Software Design Spring 2007 For today, you should have: 1) read Chapter 5 of How to think 2) read Chapter 3 of the Olinux manual 3) worked on Homework 2 For lab: 1) read Chapter 6 of "How to think..." 2) finish on Homework 2 For Thursday: 1) read Chapter 7 of "How to think" 2) prepare for a quiz Homework 1 Discussion --------------------- Important ideas: 1) using parameters to make code general and reusable 2) designing functions by looking for repetitive code 3) designing functions by identifying primitives 4) multi-level library design 5) library as an abstraction (and accompanying language) 6) preconditions and postconditions Parameters ---------- One way to make a function more general is to replace specific values with parameters. This function draws an O, but only for the turtle named bob: def draw_o(): fd(bob, 30) lt(bob) fd(bob, 60) lt(bob) fd(bob, 30) lt(bob) fd(bob, 60) draw_o() This function works for any turtle, but it's always the same size: def draw_o(t): fd(t, 30) lt(t) fd(t, 60) lt(t) fd(t, 30) lt(t) fd(t, 60) draw_o(bob) draw_o(yertle) This function can make the letter any size: def draw_o(t, n): fd(t, n) lt(t) fd(t, 2*n) lt(t) fd(t, n) lt(t) fd(t, 2*n) draw_o(bob, 30) draw_o(yertle, 100) What other values might we think about replacing with parameters? Refactoring ----------- Now that draw_o is appropriately general, we can look for places where a well-defined subfunction can improve the code. def half_o(t, n): fd(t, n) lt(t) fd(t, 2*n) lt(t) def draw_o(t, n): half_o(t, n) half_o(t, n) draw_o(bob, 30) Repetitive code is hard to read and hard to maintain, but more importantly, the repetition is a clue that there is an abstraction waiting to be discovered. Good abstractions don't just make the same program better, they make a better program possible. Preconditions and postconditions -------------------------------- precondition: a conditions that must be true at the beginning of a function; otherwise, the function might fail postcondition: a condition that is guaranteed to be true at the end of the function (provided that the preconditions were true at the beginning) Example: What are the preconditions of draw_o, above? What are the postconditions of draw_o, above? A complete specification of a function interface includes: 1) what are the parameters and preconditions? 2) what effect does the function have? 3) what are the postconditions and return value? UML State Diagrams ------------------ When you call a function, Python creates a frame (or scope) that contains 1) the parameters and their values 2) local variables and their values In a UML state diagram, a frame is a box with the name of the function outside and the parameters/local variables inside. Draw a state diagram for this program def half_o(t, n): fd(t, n) lt(t) fd(t, 2*n) # while it is executing this line lt(t) def draw_o(t, n): half_o(t, n) half_o(t, n) bob = Turtle(world) draw_o(bob, 30) Then download and run wb/sd/code/lumpy_turtle.py