Software Design Spring 2008 For today, you should have: 1) read Chapter 8 2) started Homework 3 For next time: 1) don't read Chapter 9 yet 2) read Chapter 10 3) work on hw03 4) prepare for a quiz Homework 2 ---------- Download: http://wb/sd/code/polygon.py http://wb/sd/code/Wanderer_soln.py 1) overgeneralization: writing a function that is so general it is seldom used directly, and helper functions (veneer) that provide multiple interfaces to the uberfunction. Pros: a) the kernel of the problem is solved once and for all; easy to maintain, and improvements propagate. b) the helper functions tailor the interface: kernel is usually based on the implementation; helpers on the user's model. Cons: a) performance penalty (small). b) if requirements change, you might have to "unfactor". 2) Incremental development by encapsulation and generalization a) good for exploring a problem you don't understand yet b) good for avoiding debugging heck c) you can paint yourself into a corner 3) Programming is not just translating a well-understood solution into code, the act of programming is a way of exploring a problem. 4) Preview of event-driven programming. Don't call us; we'll call you. Giving up control of the flow of execution can be unnerving. Sometimes you have to design algorithms that do a little bit of work each time, gently nudging the system toward a good state. 5) Work with the interface, at least until there is a good reason to break it. Absolute vs. relative coordinates: the power of not knowing. Here is a way to keep the turtles in bounds. def step(self): d = self.distance() dir = randint(0,self.clumsiness) - randint(0,self.clumsiness) self.rt(dir) self.fd(self.speed) if self.distance() > self.boundary: d2 = self.distance() if d2 > d: self.bk(self.speed) There are lots of good answers to this one; I'm not trying to say mine is the best, but a) it's simple and b) it respects the interface. Comments -------- Where, what and why? def arc(t, r, theta=360.0): """draw part of a circle with radius r and angle theta (in degrees). using segments with the given length""" # compute circumference circum = 2 * pi * r * theta / 360.0 # n is the number of steps n = int(ceil(circum / length)) # round up length = circum / n angle = 1.0 * theta / n polyline(t, n, length, angle) 1) first thing in a function should be a triple-quoted string that describes the interface... and you remember what information should be included, right? 2) if you have a very short comment, you can tack it to the end of a line, but you must fit your code into 80 columns! Google "programming style 80 columns" And read http://ask.slashdot.org/article.pl?sid=07/07/07/1931246 3) anything else should precede the code it describes 4) all comments should emphasize HOW and WHY, not WHAT the code is doing. 5) comments should not be redundant with code Methods ------- A method is very similar to a function, except that when you invoke it, you specify the object that should carry out the action. For example, fd is a function, but it is also a Turtle method. So you can call fd(bob, 90) which means "Move bob forward 90 units." Or bob.fd(90) which means, "Bob, move forward 90 units." The effect is exactly the same; it's just a difference in how you think about it. Methods are part of an "object-oriented" world view in which the objects are considered active. The turtle interface, which provides both functions and methods, is non-standard. Usually it's one or the other. Many string operations are available as both functions and methods, but the functions are on their way out. See: http://docs.python.org/lib/module-string.html http://docs.python.org/lib/string-methods.html (read these docs!) Encapsulation ------------- The following program draws a Koch curve. from World import * world = TurtleWorld() bob = Turtle(world) bob.delay = 0.001 bob.x = -150 bob.y = 90 bob.redraw() def koch(t, n): if n<5: fd(t, n) return n = n/3.0 koch(t, n) lt(t, 60) koch(t, n) rt(t, 120) koch(t, n) lt(t, 60) koch(t, n) for i in range(3): koch(bob, 300) rt(bob, 120) world.mainloop() You can download and run it by typing: wget http://wb/sd/code/koch.py python koch.py Let's improve it by: 1) encapsulating the for loop in a function 2) refactoring koch For more information, Google "koch curve", or check out http://www.jimloy.com/fractals/koch.htm