Software Design Lecture Notes Fall 2004 For Thursday you should: 1) read my Homework 7 solutions and make sure you understand this data structure design stuff. 2) work on your project The exam is Friday, either 8-10 or 11-1. Exam questions? Homework 7 Solutions -------------------- Some comments on my solutions: 1) in several cases, I demonstrate a specific version of a function (like analyze_wants) and then a more general version (like analyze_attr) generalization is great, but at some point it starts to make programs hard to read. 2) the getattr and setattr functions make it relatively clean to generalize a function to work with unspecified attributes. 3) maybe I'm just a function junky, but I think it would be good (for most of you) to write smaller, simpler functions. 4) writing function comments often leads you to improve interfaces. The output from my program is in 5 (unlabeled) columns The sequence is a string with 1s for boys and 2s for girls seq n wants% spousewnts intends 2073 people with one children 1 1036 51.44788 27.60618 23.74517 2 1037 50.72324 28.25458 24.01157 2657 people with two children 11 687 18.19505 12.37263 8.29694 12 733 17.59891 12.41473 8.73124 21 669 16.89088 10.16442 6.42750 22 568 19.71831 14.96479 10.21127 1415 people with three children 111 250 12.00000 7.20000 3.60000 112 205 12.68293 9.26829 4.87805 121 178 10.67416 6.74157 4.49438 122 179 12.84916 8.93855 4.46927 211 166 9.63855 6.02410 3.01205 212 156 8.97436 3.84615 1.92308 221 147 9.52381 8.16327 2.72109 222 134 9.70149 8.95522 4.47761 517 people with four children 1111 42 7.14286 4.76190 4.76190 2222 25 12.00000 12.00000 4.00000 By the way, if there is a bias toward having more children if there is no boy, what effect does that have on the population? Inheriting from built-in types ------------------------------ You can write classes that inherit from built-in types. In fact, we saw an example on the first day: class Hist(dict): def __init__(self, s): for c in s: self[c] = self.get(c, 0) + 1 def is_anagram(s1, s2): return Hist(s1) == Hist(s2) 1) all the dictionary methods work on Hists 2) the dictionary operators, too # a Filist is a list of strings that contains the contents of # a file. All the usual list operations can be applied to a # Filist. class Filist(list): def __init__(self, file=None, t=None): # if a file is provided, read the contents if file: self.file = file lines = [line for line in open(file)] self.extend(lines) # add any lines that are provided if t: self.extend(t) def __str__(self): return string.join(self, '') def join(self): # collapse the list of strings into a single long string self[:] = [str(self)] def prefile(self, file): # prepend the contents of the given file ft = Filist(file) self.insert(0, ft) def suffile(self, file): # append the contents of the given file ft = Filist(file) self.extend(ft) def writeto(self, file): # write the contents of the Filist to a file fp = open(file, 'w') for line in self: fp.write(line) def writeback(self): # write the contents of the Filist back to the file it came from self.writeto(self.file) Notice that in addition to being a list, the Filist has an additional attribute named file. Try this: wget http://wb/sd/code/Filist.py python from Filist import * ft = Filist('Filist.py') print ft[0] print ft.file print ft.__dict__ print ft Threading --------- Create a file named thread_example.py and type this in: import string from time import sleep from threading import * def loop(seq, delay=1): for x in seq: print x sleep(delay) loop(range(3)) thread = Thread(target=loop, args=[string.lowercase, 0.4]) thread.start() loop(string.uppercase) 1) thread diagrams 2) keyboard interrupt woes