Week 5: more functions, scope, stack diagrams
Quiz 2 on Friday
Lab 4 due Saturday
lab 4 is functions and while loops, but we tell you exactly how to write the functions (what the params are, what it does, what it returns)
lab 5 will be more functions, but not as much guidance on each function
lab 7 will be yours to write (you design the functions and the whole program)
We started by looking at the
countletter.py program from last time:
def main(): phrase = "we love computer science" letter = "e" result = countletter(letter,phrase) print("Number of %s's: %d" % (letter, result)) def countletter(ch,txt): """return number of ch in txt""" count = 0 for char in txt: if char == ch: count += 1 return count main()
Some questions students had from last time:
- how do
phrase get transfered to the
- how does the result (the
count variable) get back to
- should I name the arguments the same as the parameters?
- can I use
phrase in the
stack diagrams and scope
All good questions! And we’ll use stack diagrams to understand what’s going on and answer these questions.
Understanding stack diagrams helps you see how the computer works, and why python does what it does. It will also be very valuable in week 11 when we learn recursion (functions calling multiple copies of themselves).
A "stack" is just a data structure used by many programs. A stack is useful because it keeps track of where we are, and allows backtracking (e.g., hitting "undo" in your editor, or hitting the "back" button on your browser).
If you think of a stack of books or a stack of trays, you generally add items to the stack and remove items from the stack at the top end. This is different from a queue data structure (like a line at the bank or the grocery store) where items (people) are added at the back of the queue and removed (they checkout or are served) from the front of the queue.
So for your browser, say you visit espn.com, then swarthmore.edu, then cnn.com, and finally google.com. At this point, the broswer stack would look like this, with the current site on the top of the stack, and your history recorded in the rest of the stack:
google.com cnn.com swarthmore.edu espn.com
If you now hit the "back" button, the browser would "pop" the stack and remove the top item (google.com) and go to whatever is next on the stack (cnn.com).
As functions are executed in our program, they are placed on the top of the stack. When the function executing is done, it is removed from the top of the stack and the function below resumes execution. This is how the computer keeps track of the program flow.
For example, if you have a
main() function called first, and then
main() calls another function, say
func1(), and before
returns it calls another function, say
func2(), then at this point
"the stack" would look like this:
func2 func1 main
In addition to just showing what functions are on the stack, we will also include their variables and what data they refer to.
Here is a stack diagram for the
countletter.py program above,
where I have stopped at the end of the
count() function, just before
it returns to
In the above diagram, the "stack" is on the left, with two functions
currently on the stack, and the one on top is the function currently
main() has paused, and is waiting for
to finish and return).
In each stack frame, for each function, we list the variables that are active, with arrows that point to the data they refer to. This data, shown off to the right, is technically stored in a different area of the computer’s memory (this whole diagram is a simplified view of the memory of the computer, as the program is executing).
main() has just two variables:
letter. The arrows
show what values are currently stored in these variables.
countletter() function has three variables:
ch points to the same data as
letter. This is
how arguments and parameters pass data from
main() to a function.
txt points to the same string as
count variable initially stores a zero, but as the computer works
through the function, step by step, it is updated each time another "e"
is found in the
txt string. This is shown by the crossed-out values,
with the final value being 5. So at the end of the
function, the value that will be returned back to main (
count) is 5.
So the rules for drawing the stack are as follows:
put the first function called (usually
main()) on the stack
inside the stack frame, show any variables that are assigned, with arrows pointing to their values (off to the right)
if another function is called, make a new stack frame for that function on top of the stack
again, inside that frame, show any parameters and local variables, with arrows pointing to their initial values
work through each function, step-by-step, updating any variables and their data
Usually, on quizzes, we will ask you to stop updating the stack diagram
before any functions finish and return. For completeness, if a function
did finish and return, we would remove it (and all it’s variables) from
the top of the stack. Any return value would usually be assigned back
to a variable in the calling function. For example, in the above
program, back in
result variable would be assigned the
value 5, since
count is returned from the
mutable objects in function
What about this program? Can you draw the stack for this one?
And what does the
print(data) line show, after the call to
def main(): data = [2,37,300,127,-1] print(data) changed = bounds(data,0,255) print(data) print("Number changed: %d" % (changed)) def bounds(L,min,max): """check that all items in list are within min/max""" numchanged = 0 for i in range(len(L)): if L[i] < min: L[i] = min numchanged += 1 elif L[i] > max: L[i] = max numchanged += 1 # after loop, return how many were changed return numchanged main()
review function worksheet
functionWorksheet.py program that we started as a worksheet
on Monday. Can you predict the output of the whole program? Can you draw
the stack up to where
function2() is about to return?
# ------------------------------------------------------ # def function1(L, X, S): X = 100 L = list("WXYZ") S = "pony" # draw what stack looks like at this point, before function ends # ------------------------------------------------------ # def printline(ch): print(50*ch) # ------------------------------------------------------ # def function2(L, X, S): X = X + 1 L = "hello" L = "goodbye" L = "lists are mutable!" S = S + "pony" # draw what stack looks like at this point, before function ends # ------------------------------------------------------ # def function3(mystring): newstr = "**" + mystring + "**" return newstr # ------------------------------------------------------ # def main(): L = list("ABCDE") X = 42 S = "Swarthmore" function1(L, X, S) print("L: %s" % (L)) print("X: %d" % (X)) print("S: %s" % (S)) result = printline("!") print(result) printline("!") function2(L, X, S) print("L: %s" % (L)) print("X: %d" % (X)) print("S: %s" % (S)) printline("#") S = function3(S) print("S: %s" % (S)) # ------------------------------------------------------ # main()
After you have studied the program, run it and make sure you understand the output!
Here are the main points from the above program:
in python, lists are mutable. This is why
function2()is able to change some of the items in
L, and those changes are seen back in
scope refers to where in a program a variable is active or accessible. Variables (and the data they reference) in one function are local (ie, not global) to that function. If you need the data from one function in another function, you should pass the data from function to function using arguments and parameters, or return the data from the called function back to the calling function
in python, a function returns
Noneif you don’t explicitly return something (which is why you see
Let’s write a program to present the user with a simple math quiz, testing their multiplication knowledge. Here’s a quick example:
$ python3 mathquiz.py Welcome to MathQuiz v0.1! What factor would you like to work on? 4 - - - - - - - - - - - - - - 4 x 6? 35 ....Nope. 4 x 6 = 24 - - - - - - - - - - - - - - 4 x 4? 16 ....Correct! - - - - - - - - - - - - - - 4 x 10? 40 ....Correct! - - - - - - - - - - - - - - 4 x 2? 8 ....Correct! - - - - - - - - - - - - - - You got 3 out of 4 correct. Good work!
Start with just these requirements:
ask for a factor
keep asking simple multiplication questions (factor times a random number from 1-12) until they get 3 in a row correct
If you have time: add a
results(numprob, numcorrect) function
that takes two arguments/parameters: the total number of problems
asked and the total number they got correct. This function should
output a status message based on the percent correct:
All correct: Super!
greater than 80% correct: Good work!
greater than 50% correct: Not bad…
less that 50% correct: Keep trying…
This function should also print the "You got X out of Y correct" message.
Quiz 2 for the first half of class
intro to objects: strings and lists
objects and methods
Both python strings and python lists are examples of objects. An object is just some data plus some methods (similar to functions) wrapped up together into one thing. We’ll learn more about objects as we go. For now we just want to learn the syntax of using them: object.method()
>>> course = "Introduction to Computer Science" >>> course.count("o") 4 >>> course.count("z") 0 >>> course.isalpha() False >>> course.upper() 'INTRODUCTION TO COMPUTER SCIENCE'
>>> grades = [88,90,78,99,93] >>> grades.sort() >>> print(grades) [78, 88, 90, 93, 99] >>> grades.append(75) >>> print(grades) [78, 88, 90, 93, 99, 75]
The string methods used above are:
count()— returns the number of occurrences of the given substring
isalpha()— returns True if all characters in the string are letters
upper()— returns an uppercase version of the string
There are many other str methods. In string objects, the data are the characters in the string.
The list methods used above are:
sort()— sorts the list in place
append()— adds the given argument to the end of the list
In list objects, the data are the items in the list.
Methods are always called with the dot syntax:
Again, methods are similar to functions, except they are tied to the type of object, and are called with this special syntax.
common string methods
Strings are objects in Python, and thus have methods that
we can invoke on them.
There are a lot of methods in the
str library for creating new
string objects from existing string objects and for testing properties
of strings. Keep in mind that strings are immutable!
Here are a few
str methods that may be particularly useful (run
in the python interpreter to see the full set):
return copy of str converted to uppercase
return copy of str converted to lowercase
return True if string is all alphabetic characters
return True if string is all digits
return number of occurrences of sub
return index of first occurrence of sub
strip off leading and trailing whitespace
split into list of "words" (see below)
>>> S = "we LOVE cs" >>> S.upper() 'WE LOVE CS' >>> S.lower() 'we love cs' >>> S.isalpha() False >>> S.isdigit() False >>> S.count(" ") 2 >>> S.index("L") 3 >>> S.split() ['we', 'LOVE', 'cs'] >>> S = " we love cs " >>> len(S) 17 >>> S = S.strip() >>> len(S) 10 >>> print(S) we love cs
common list methods
Lists are also objects in Python, and thus have methods that
we can invoke on them. Here are a few that may be particularly useful
help(list) in the python interpreter to see the full set):
add item to end of list
insert item at index
add list L1 to original list
sort the list
reverse the list
return number of occurrences of item in list
return index of first occurrence of item
remove and return item at index
>>> L = list("ABCDEFG") >>> print(L) ['A', 'B', 'C', 'D', 'E', 'F', 'G'] >>> L.append("X") >>> print(L) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'X'] >>> L.extend(["Y","Z"]) >>> print(L) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'X', 'Y', 'Z'] >>> L.reverse() >>> print(L) ['Z', 'Y', 'X', 'G', 'F', 'E', 'D', 'C', 'B', 'A'] >>> L.sort() >>> print(L) ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'X', 'Y', 'Z'] >>> L.count("E") 1 >>> L.index("E") 4 >>> L.pop(4) 'E' >>> print(L) ['A', 'B', 'C', 'D', 'F', 'G', 'X', 'Y', 'Z'] >>> L.insert(1,"hello") >>> print(L) ['A', 'hello', 'B', 'C', 'D', 'F', 'G', 'X', 'Y', 'Z']
To see the full documentation for both the
$ python3 >>> help(str) >>> help(list)