490 likes | 501 Vues
Learn how to use functions to simplify and organize your code, and to break down big programs into manageable chunks. Examples and explanations provided.
E N D
COSC 1306COMPUTER SCIENCE AND PROGRAMMING Jehan-François Pâris jfparis@uh.edu Fall 2017
Motivation • The for loop let us identify segments of code that are used again and again • Replace them with functions • Can also use functions to break down big programs into more manageable chunks
Example Program has 260 lines # START MAIN PROGRAM readinputs() # MAIN LOOP while eventlist != [] : [time, event, pid] = eventlist.pop(0) if event == 'ARRIVAL' : arrival(pid) elif event == 'CORE' : corecompletion(pid) elif event == 'DISK' : diskcompletion(pid) elif event == 'I/O' : iocompletion(pid) else : print("PANIC" ) # PRINT SUMMARY printsummary()
Functions • Straight extension of mathematical functions • sin(…), cos(…), exp(…) • Also apply to strings, lists, … • Can be • Built-in • Imported from a Python module • import mathy = math.sqrt(x) • User defined
Writing your own functions • def function_name(argument(s)) : statements • Note • The column at the end of the first line • The indenting
An example def mysqrt(number) : root = number/2 for i in range(10) : inverse = number/root root = (root + inverse)/2 return root
A very simple function def increment(number) : return number + 1 print("increment(5)", increment(5)) • Note that the print() statement is not part of the function • Many people prefer to leave an empty line after each function declaration
Back to turtles (I) import turtle def draw_square(t, sz): """Make t draw a sz by sz square.""" for i in range(4): t.forward(sz) t.left(90)
Back to turtles (II) wn = turtle.Screen() wn.bgcolor("lightgreen") wn.title("Alex meets a function") # New alex = turtle.Turtle() draw_square(alex, 50) # Call draw_square wn.mainloop()
A more general function def draw_rectangle(t, w, h): """Get turtle t to draw a rectangle of width w and height h.""" for i in range(2) : t.forward(w) t.left(90) t.forward(h) t.left(90)
A new draw_square function def draw_square(tx, sz): draw_rectangle(tx, sz, sz) • If we have to draw rectangles and squares • Write most general of the two • Make the other a special case of the first • Avoids doing the work twice
Flow of control (I) • When Python encounters a function definition • It does not do anything with code • It just remembers that the programmer defined that function • When Python encounters a function call • It looks if the function was defined in an imported module or in the program • It then executes that function
Flow of control (II) • Think of function declarations as specifying something the program can do • Put them ahead of the first place where they will be used: • Included modules • Function declarations • "Main" program
Function parameters • Most functions have parameters • Makes them more general • mysqrt(number), draw_square(t, sz), draw_rectangle(t, w, h)
Functions returning a value • Some functions return values • mysqrt(number) • Some do not • draw_square(t, sz), • draw_rectangle(t, w, h)
What happens inside a function def mysqrt(number) : root = number/2 for i in range(10) : inverse = number/root root = (root + inverse)/2 return root i = 0 rt2 =mysqrt(2.0)
The question • Have two variables with the same name • In the main program • In the function definition • What will happen to the i variable in the main program when we call mysqrt()? • Will it be set to 9? • Will it remain equal to zero?
The answer • What happens in a function declaration • … remains in the function declaration • All variables used in a function declaration • Are newly created variables • Exist only inside the function body
What happens inside a function def mysqrt(number) : root = number/2 for i in range(10) : inverse = number/root root = (root + inverse)/2 return root i = 0 rt2 =mysqrt(2.0) ... Use the green i here Use the red i here
Main advantage • Can use any variable name inside a function declaration • No need to worry whether the name is used elsewhere
Organizing our code (I) def make_window(colr, ttle): """Set up a new window.""" w = turtle.Screen() w.bgcolor(colr) w.title(ttle) return w
Organizing our code (II) def make_turtle(colr, sz): """ Set up a new turtle.""" t = turtle.Turtle() t.color(colr) t.pensize(sz) return t
Organizing our code (III) wn = make_window("lightgreen", "Tess and Alex dancing") tess = make_turtle("hotpink", 5) alex = make_turtle("black", 1) dave = make_turtle("yellow", 2) Our main program is shorterand easier to understand
The accumulator pattern • Suppose we want to count the sum of the first n numbers • def sum_them_all(n) : running_total = 0 # before the loop for i in range(1, n + 1) : running_total += i return running_total #after it
The accumulator pattern • Suppose we want to count the sum of the first n numbers • defsum_them_all(n) :running_total= 0 # before the loop for i in range(1, n + 1) :running_total+= i return running_total#after it
Python will refuse to execute • defsum_them_all(n) : for i in range(1, n + 1) :running_total += i return running_total#last line Why?
Will return n • defsum_them_all(n) : for i in range(1, n + 1) :running_total= 0# WRONGrunning_total+= i return running_total#after it
Will return 1 • defsum_them_all(n) :running_total= 0 # before the loop for i in range(1, n + 1) :running_total+= i return running_total# WRONG
Functions can call functions • Recall • def draw_square(tx, sz): draw_rectangle(tx, sz, sz)
The main function • Unlike C and C++, Python has no notion of a specian main function • If you try • def main() : print("Hello World") nothing will happen • Python will define a main() function butnot execute it
A personal comment • You will have to learn the little peculiarities of each language • In French, I would not say • My name is Jehan-François but instead the equivalent of • *I call myself Jehan-François • Same thing with Python
Stepwise refinement • Suppose we are asked to draw the front of a house with a flat roof • How should we proceed?
Step one • draw_frame(turtle, width, height, color)draw_windows(???)position(turtle, x,y)draw_door(turtle, width, height, color, doorknob, doorknob_color, doorknob_side)
The easiest • draw_frame(trtl, w, h, clr) : draw_filled_rectangle(trtl, w, h, clr) which will use • draw_filled_rectangle(trtl, w, h, clr) : trtl.fillcolor(clr) trtl.start_fill() draw_rectangle(trtl, w, h) trtl.end_fill
The door • draw_door(trtl, w, h, clr, dk, dk_clr, dk_side) : draw_filled_rectangle(trtl, w, h, clr) // must learn to make choices: // left or right position_doorknob(???) // Does not work • OMG !!!
The door revisited • draw_door(trtl, x, y, w, h, clr, dk, dk_clr, dk_side) : position(trtl, x, y) draw_filled_rectangle(trtl, w, h, clr) // assume knob on right side dk_x =x + w*9/10 // BAD dk_y= y + h/2 position turtle(trtl, dk_x, dk_y) draw_filled_circle(trtl, dk,clr)
The windows • Replace • draw_windows(???) by • position(trtl, x1, y1)draw_window(w, h, clr)position(trtl, x2, y2)draw_window(w, h, clr)position(trtl, x3, w3)draw_window(w, h, clr) • Will have problems drawing the window frames!
The windows • Use • draw_window(trtl, w, h, clr)position(trtl, x2, y2)draw_window(w, h, clr)position(trtl, x3, w3)draw_window(w, h, clr) • Will have problems drawing the window frames!
A turtle bar chart (II) import turtle
A turtle bar chart (III) # def drawBar(t, height): """ Get t to draw one bar of height. """ t.begin_fill() # start filling t.left(90) # up t.forward(height) t.write(str(height)) # write label t.right(90) # back to horizontal t.forward(40) t.right(90) #down t.forward(height) t.left(90) t.end_fill() # stop filling
A turtle bar chart (IV) xs = [48, 117, 200, 240, 160, 260, 220] # here are the data to plot maxheight = max(xs) # max entry in list numbars = len(xs) # size of list border = 10 # extra space top and right
A turtle bar chart (V) # Set up the window and its attributes wn = turtle.Screen() wn.setworldcoordinates(0-border,0-border, 40*numbars+border, maxheight+border) # do not study this wn.bgcolor("lightgreen")
setworldcoordinates() • setworldcoordinates(llx, lly, urx, ury) • Four numbers • llx : x-coordinate of lower left corner of canvas • lly : y-coordinate of lower left corner of canvas • urx : x-coordinate of upper right corner of canvas • ury: y-coordinate of upper right corner of canvas
A turtle bar chart (VI) # Setup turtle tess tess = turtle.Turtle() tess.color("blue") tess.fillcolor("red") tess.pensize(3)
A turtle bar chart (VII) # draw the chart for a in xs: drawBar(tess, a) # works because tess is always where # it should be after having drawn # a bar wn.exitonclick()
There is more • There are many other aspects of functions that are left to be discovered later • Optional parameters • Parameters with default values • Declaring some variables to be global • … • Python is like a big city that takes time to discover