Thursday, October 25, 2012

Abstract Base Classes in python

Python provides ABC.

References

spawn a process and get the output with python

The simplest way to spawn a process is to use os.system(COMMAND), however if you want to intercept the output, you need to python's process module.
from subprocess import *

cmd = ["ls", "-alF"]

p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)

stdout,stderr = p.communicate()
print stdout
You need PIPE assigned to stdin/stdout/stderr in order to get the result assigned to local variables.

With close_fds value as True, all the file descriptors in the process is closed. You can just remove this option. If you have a long command line string, then you can use STRING.split() method to get a list to an input to Popen method.

References

Use shutil.rmtree for deleting whole directory

Maybe, one tries to use os.remove(path) or os.removedirs(path) for deleting the whole directory.

However, they should raise an error when the directory is not empty. So, the better choice is using shutil.rmtree(path).

The name remove tree fits the idea of removing everything whereas remove and removedir delete the directory (only the directory not files in it).

Reading ini file into a dictionary in python

Configuration Reader

Python's ConfigParser lets users read configuration files.
[TestA]
package = None
class = A
method = test
We can read the items in the configuration file to be accessed as a dictionary.
a['TestA']['package']
In order to do that, we need a method to do that.
import ConfigParser

class MyParser(ConfigParser.ConfigParser):
    def as_dict(self):
        d = dict(self._sections)
        for k in d:
            d[k] = dict(self._defaults, **d[k])
            d[k].pop('__name__', None)
        return d
This is how one can use this code.
if __name__ == "__main__":
    f = MyParser()
    f.read("/DIRECTORY_TO/setup.ini")
    d = f.as_dict()
    print d
    print d['TestA']['class']
You'll get the result.
{'TestA': {'package': 'None', 'method': 'test', 'class': 'A'}}
A

Analysis of the code

If you are not familiar with python dictionary, you can check this post. When the ini file is read into ConfigParser object, all the information is already in the dictionary.
config = ConfigParser.RawConfigParser()
config.read(PATH)
In config, you have all the items in dictionary, the issue is that you can't use it as is.
print f._sections
OrderedDict( # <-- Ordered Dictionary
  [ # <-- List of tuples : string and OrderedDict 
     ('TestA', 
       OrderedDict(
         # The first item in the list is not necessary, so pop it off
         [('__name__', 'TestA'), ('package', 'None'), ('class', 'A'), ('method', 'test')]
       )
     )
  ]
)
The default data structure is OrderedDict, if you need more about OrderedDict, you can check this post. for k in d:, the k holds the section name ('TestA'), and it only iterates once as there is only one sections. When you run this code, you'll get the OrderedDictionary(), but you don't need the first element which is the name of the section.
for k in d: print d[k]
OrderedDict([('__name__', 'TestA'), ('package', 'None'), ('class', 'A'), ('method', 'test')])
The next code creates a dictionary based on _defaults OrderedDict().
d[k] = dict(self._defaults, **d[k])
print f._defaults
OrderedDict()
And for the **d[k], it means that d[k] (dictionary) is decomposed into assignments. This is necessary as the dict() method requires assignments as additional parameters to the method.
def hello(**a):
    print a
    
a = dict([['a',10],['b',20]])
print a
hello(**a)
{'a': 10, 'b': 20}
{'a': 10, 'b': 20}
You'll get d[k] as follows:
{'__name__': 'TestA', 'package': 'None', 'method': 'test', 'class': 'A'}
Finally, you should pop up the ('__name__': 'TestA')
d[k].pop('__name__', None)
This is explanation for the pop() method. Screen Shot 2012 10 25 at 4 17 02 PM

References

Displaying updated post in blogspot

This post teaches how to enlist newly generated posts.




Get this widget

The basic idea is retrieve information from blogger, and calls he callback function to enlist the result.

The summary has all the information, you can check it from http://prosseek.blogspot.com/feeds/posts/summary. Compare it to the case with only for python label with http://prosseek.blogspot.com/feeds/posts/summary/-/python. so if you want to enlist all the posts updated not for specific label, you can modify the code as follows.

OrderedDict in python

The dict type in python is not ordered, and it's been a pain, especially when you want to keep the sorted order inside a dictionary. From python 2.7, OrderedDict is supported. Screen Shot 2012 10 25 at 10 57 47 AM This quick example will show you what are the differences.
from collections import *

print 'Regular dictionary:'
d = {}
d['a'] = 'A'
d['b'] = 'B'
d['c'] = 'C'
d['d'] = 'D'
d['e'] = 'E'

for k, v in d.items():
    print k, v

print '\nOrderedDict:'
d = collections.OrderedDict()
d['a'] = 'A'
d['b'] = 'B'
d['c'] = 'C'
d['d'] = 'D'
d['e'] = 'E'

for k, v in d.items():
    print k, v
OrderedItem() keeps the input order, with this you can sort
Regular dictionary:
a A
c C
b B
e E
d D

OrderedDict:
a A
b B
c C
d D
e E
  • OrderedDict() requires import collections.
  • When printing the object, OrderedDict() doesn't show it with '{' and '}'.
You can build OrderedDict() using list (iteration), and you can keep the order now.
d = OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
for k, v in d.items():
    print k, v
apple 4
banana 3
orange 2
pear 1
Using this, you can get the sorted dictionary. Remembering dict.items() return list, you can sort regular dictionary.
# dictionary sorted by value
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
d = OrderedDict(sorted(d.items(), key=lambda t: t[0]))
for k, v in d.items():
    print k, v
d = OrderedDict(sorted(d.items(), key=lambda t: t[1]))
for k, v in d.items():
    print k, v
apple 4
banana 3
orange 2
pear 1

pear 1
orange 2
banana 3
apple 4
sort() method gets a list as an input and returns sorted list, it doesn't modify the original list.
a = [1,2,3,4,-3]
b = sorted(a)
print b
print a
[-3, 1, 2, 3, 4]
[1, 2, 3, 4, -3]
Even you can sort by the length of the index.
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}
# dictionary sorted by length of the key string
d = OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
for k, v in d.items():
    print k, v
pear 1
apple 4
orange 2
banana 3
You can get the dict from OrderedDict() as the latter is iterable.
o = OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
d = dict(o)
for k, v in d.items():
    print k, v
orange 2
pear 1
apple 4
banana 3

References