2018年10月27日 星期六

[ Python 常見問題 ] Display number with leading zeros

Source From Here 
Question 
Given: 
  1. a = 1  
  2. b = 10  
  3. c = 100  
How do I display a leading zero for all numbers with less than two digits? That is, 
01 
10 
100

How-To 
One approach is to use Format feature from string class: 
>>> print("{:02d}".format(1)) # Filler as '0'; width=2 
01 
>>> print("{:03d}".format(1)) 
001 
>>> print("{:03d}".format(123)) 
123
Or you can use str.zfill: 
>>> print("1".zfill(3)) # Return the numeric string left filled with zeros in a string of length 3 
001 
>>> print("12".zfill(3)) 
012 
>>> print("123".zfill(3)) 
123


[ Python 常見問題 ] How do I correctly clean up a Python object?

Source From Here 
Question 
Check sample code below: 
  1. class Package:  
  2.     def __init__(self):  
  3.         self.files = []  
  4.   
  5.     # ...  
  6.   
  7.     def __del__(self):  
  8.         for file in self.files:  
  9.             os.unlink(file)  
__del__(self) above fails with an AttributeError exception. I understand Python doesn't guarantee the existence of "global variables" (member data in this context?) when __del__() is invoked. If that is the case and this is the reason for the exception, how do I make sure the object destructs properly? 

How-To 
I'd recommend using Python's with statement for managing resources that need to be cleaned up. The problem with using an explicit close() statement is that you have to worry about people forgetting to call it at all or forgetting to place it in a finally block to prevent a resource leak when an exception occurs. To use the with statement, create a class with the following methods: 
  1. def __enter__(self)  
  2. def __exit__(self, exc_type, exc_value, traceback)  
In your example above, you'd use: 
  1. class Package:  
  2.     def __init__(self):  
  3.         self.files = []  
  4.   
  5.     def __enter__(self):  
  6.         return self  
  7.   
  8.     # ...  
  9.   
  10.     def __exit__(self, exc_type, exc_value, traceback):  
  11.         for file in self.files:  
  12.             os.unlink(file)  
Then, when someone wanted to use your class, they'd do the following: 
  1. with Package() as package_obj:  
  2.     # use package_obj  
The variable package_obj will be an instance of type Package (it's the value returned by the __enter__ method). Its __exit__ method will automatically be called, regardless of whether or not an exception occurs. 

Another approach is to use atexit.register. For example: 
  1. # package.py  
  2. import atexit  
  3. import os  
  4.   
  5. class Package:  
  6.     def __init__(self):  
  7.         self.files = []  
  8.         atexit.register(self.cleanup)  
  9.   
  10.     def cleanup(self):  
  11.         print("Running cleanup...")  
  12.         for file in self.files:  
  13.             print("Unlinking file: {}".format(file))  
  14.             # os.unlink(file)  
But you should keep in mind that this will persist all created instances of Package until Python is terminated. Demo using the code above saved as package.py: 
  1. >>> from package import *  
  2. >>> p = Package()  
  3. >>> q = Package()  
  4. >>> q.files = ['a', 'b', 'c']  
  5. >>> quit()  
  6. Running cleanup...  
  7. Unlinking file: a  
  8. Unlinking file: b  
  9. Unlinking file: c  
  10. Running cleanup...  
Supplement 
* Python 建構、初始與消滅 
如果要定義物件被垃圾收集(Garbage collection)時,所要進行的資源清除動作,則可以定義__del__()方法,物件會被資源回收的資格,基本上就是參考至物件的變數計數為0的時候...


[ Python 常見問題 ] How to format print output or string into fixed width?

Source From Here 
Question 
I have this code (printing the occurrence of the all permutations in a string): 
  1. def splitter(str):  
  2.     for i in range(1, len(str)):  
  3.         start = str[0:i]  
  4.         end = str[i:]  
  5.         yield (start, end)  
  6.         for split in splitter(end):  
  7.             result = [start]  
  8.             result.extend(split)  
  9.             yield result      
  10.   
  11. el =[];  
  12.   
  13. string = "abcd"  
  14. for b in splitter("abcd"):  
  15.     el.extend(b);  
  16.   
  17. unique =  sorted(set(el));  
  18.   
  19. for prefix in unique:  
  20.     if prefix != "":  
  21.         print "value  " , prefix  , "- num of occurrences =   " , string.count(str(prefix));  
I want to print all the permutation occurrence there is in string varaible. since the permutation aren't in the same length i want to fix the width and print it in a nice not like this one: 
  1. value   a - num of occurrences =    1  
  2. value   ab - num of occurrences =    1  
  3. value   abc - num of occurrences =    1  
  4. value   b - num of occurrences =    1  
  5. value   bc - num of occurrences =    1  
  6. value   bcd - num of occurrences =    1  
  7. value   c - num of occurrences =    1  
  8. value   cd - num of occurrences =    1  
  9. value   d - num of occurrences =    1  
How can I use format to do it? 

How-To 
This answer is very old. It is still valid and correct, but people looking at this should prefer the new format syntax. You can use string formatting like this: 
  1. >>> print("|%5s" % 'aa')  
  2. |   aa  
  3. >>> print("%5s" % 'aaa')  
  4. |  aaa  
  5. >>> print("%5s" % 'aaaa')  
  6. | aaaa  
  7. >>> print("%5s" % 'aaaaa')  
  8. |aaaaa  
Basically: 
* the % character informs python it will have to substitute something to a token 
* the s character informs python the token will be a string 
* the 5 (or whatever number you wish) informs python to pad the string with spaces up to 5 characters.

If you are using format function from string class: 
  1. >>> print("{:^>5s}".format('a'))  # '^ 'as filler; '>' as align policy; '5' as width  
  2. ^^^^a  
  3. >>> print("{:^>5s}".format('aa'))  
  4. ^^^aa  
  5. >>> print("{:^>5s}".format('aaa'))  
  6. ^^aaa  
  7. >>> print("{:^>5s}".format('aaaa'))  
  8. ^aaaa  
  9. >>> print("{:^>5s}".format('aaaaa'))  
  10. aaaaa  
In your specific case a possible implementation could look like: 
  1. >>> dict_ = {'a': 1, 'ab': 1, 'abc': 1}  
  2. >>> for item in dict_.items():  
  3. ...     print 'value %3s - num of occurances = %d' % item # %d is the token of integers  
  4. ...   
  5. value   a - num of occurances = 1  
  6. value  ab - num of occurances = 1  
  7. value abc - num of occurances = 1  
SIDE NOTE: Just wondered if you are aware of the existence of the itertools module. For example you could obtain a list of all your combinations in one line with: 
  1. >>> import itertools as it  
  2. >>> it.permutations(['a', 'b'], 1)  
  3.  0x7f8994e3e470>  
  • >>> list(it.permutations(['a', 'b'], 1))  
  • [('a',), ('b',)]  
  • >>> list(it.permutations(['a', 'b'], 2))  
  • [('a', 'b'), ('b', 'a')]  
  • >>> [''.join(perm) for i in range(1, len(s)) for perm in it.permutations(s, i)]  
  • ['a', 'b', 'c', 'd', 'ab', 'ac', 'ad', 'ba', 'bc', 'bd', 'ca', 'cb', 'cd', 'da', 'db', 'dc', 'abc', ...]  


  • [ Python 常見問題 ] How to shift a datetime object by 12 hours in python

    Source From   Here   Question   Datetime   objects hurt my head for some reason. I am writing to figure out   how to shift a date time obje...