Python development is largely an exercise in rapid, incremental, and interactive programming, which is well suited to the shifting needs of real-world projects.
_ Mark Lutz, "Programming Python"
Recent Code
Design patterns in Python [top]
I have been obsessed with design patterns lately. Design patterns are solution to frequently encountered problems or challenge when dealing with object oriented software. Here is a modified version of a cookbook snippet to explain the Observer Pattern that perhaps is easier to understand.You can find the original by Jorgen Cederberg here
I also contributed to a revised version of the observer pattern on wikipedia
#
# -*- coding: utf-8 -*-
"""
"""
class Publisher:
def __init__(self):
pass
def attach(self, observer):
raise NotImplementedError, "you Must subclass me"
def detach(self, observer):
raise NotImplementedError, "you Must subclass me"
def notify(self):
raise NotImplementedError, "you Must subclass me"
class Subject(Publisher):
def __init__(self):
self._observers = []
def attach(self, observer):
if not observer in self._observers:
self._observers.append(observer)
def detach(self, observer):
try:
self._observers.remove(observer)
except ValueError:
pass
def notify(self):
for observer in self._observers:
observer.update(self)
class Observer:
def update(self, subject):
raise NotImplementedError, "Must subclass me"
# Example usage
#--- The model
class Data(Subject):
def __init__(self, name=''):
Subject.__init__(self)
self.name = name
self.data = None
def setData(self, data):
self.data = data
self.notify()
def getData(self):
return self.data
#--- The views
class UpperViewer(Observer):
def update(self, subject):
print '\nUpperViewer: Been told that Subject %s now has data %s' % (subject.name, subject.getData())
self.doSomethingWithData(subject.getData())
def doSomethingWithData(self, data):
print 'Applying Upper(): %s '%data.upper()
class ReverseViewer(Observer):
def update(self, subject):
print '\nReverseViewer: Been told that Subject %s now has data %s' % (subject.name, subject.getData())
self.doSomethingWithData(subject.getData())
def doSomethingWithData(self, data):
print 'Reversing it: %s '%data[::-1]
# Example usage...
#--- the Controller
def main():
data1 = Data('Data 1')
data2 = Data('Data 2')
view1 = UpperViewer()
view2 = ReverseViewer()
data1.attach(view1)
data1.attach(view2)
data2.attach(view2)
data2.attach(view1)
print "\nSetting Data 1 = hello"
data1.setData('hello')
print "\nSetting Data 2 = 15"
data2.setData('15')
print "\nSetting Data 1 = 1253"
data1.setData('1253')
print "\nSetting Data 2 = adios"
data2.setData('adios')
print "\n----\nDetach ReverseViewer from data1 and data2."
data1.detach(view2)
data2.detach(view2)
print "\nSetting Data 1 = python"
data1.setData('python')
print "\nSetting Data 2 = is great"
data2.setData('is great')
if __name__ == '__main__':
main()
Test Driven Development with Python [top]
"Agile Java: Crafting Code with Test-Driven Development" by Jeff Langr and "Test-Driven Development by example" by Kent Beck
are two books that frankly I believe are "must read" items. The following are some insight into what I have incorporated in my programming practice.
The TDD coder pledge.
TDD means that for each class you code, you will have a corresponding test class.
- You will write the Tests FIRST!
- The test are a means of specifying what the code needs to do.
After writing the corresponding code, the tests are run to ensure that the code does indeed what the tests specify. - The production classes you build should know nothing about the tests written for them.
The TDD Process
This cycle will quickly become an ingrained, natural flow of development
_ Jeff Langr, "Agile Java: Crafting Code with Test-Driven Development"
- Write a small test to assert some piece of funcionality
- Demonstrate that the test fails (compiler/interpreter complains)
- Write a small bit of code to make this test pass (satisfy compiler/interpreter demand)
- Refactor both the test and the code:
- Eliminate duplicate concepts
- Ensure code expressiveness