CS21 Week 8: Top-Down-Design, String and List Objects
Week 8 Topics
-
Review some Graphics Library features
-
Nested Loops Review
-
More List and String class methods
-
Top-Down Design
Monday
Today, we are going to quickly revisit some of the content we quickly went over in class on Friday before break, and learn some new List and String methods, and start talking about one of the main course topics: Top Down Design.
The Stack
In functionsWS.py
is a program that you should not run yet,
Instead, first open it in vim
, and trace through its execution:
(1) draw the stack at the point shown, and (2) list program output.
After you do this, you can try running the program to see if your output is correct.
You could also print out this file if you’d like to trace through on
a printout: lpr functionsWS.py
Setting Coordinates
In your cs21/inclass/week07-oop
subdirectory are two programs that use
the Graphics Library’s setCoords
method of the GraphWin
class to
re-define the x-y coordinate system in the way that we would like (by
default, it is specified in pixel width, with point (0,0) in the top
upper-left).
In setcoords.py
is a program that calls win.setCoords(-pi, -1.5, pi, 1.5)
(lower left (-pi, -1.5), upper right (pi, 1.5)) and generates a plot for
the sin function using the math library.
In setcoords_try.py
is another example program that calls
win.setCoords(0,0,10,10)
to set the window coordinates to (0,0) in the
lower left at (10,10) in the upper right. Let’s open this one up
and try drawing a circle somewhere in the lower right quadrant of
the graphics window using this new coordinate mapping.
There are also some TODO
comments in this file for some other things to
try out. You can see our solution in setcoords_try_soln.py
, but try
them out first on your own.
Nested Loops
We’ve seen the classic for
loop many times now:
for i in range(10):
<LOOP BODY>
We know that the LOOP BODY
can contain anything: print statements, calls to
input()
, if
/ else
conditionals, and many other things. But what if we
put another for loop inside the body of a loop?
Putting one loop in the body of another is called a nested loop, and it’s a
common (and very helpful!) repetition pattern. Let’s look at some examples in
nested.py
.
In your cs21/inclass/week07-oop
subdirectory is a program nested.py
with
some example nested loops. Let’s take a few minutes to review some of these.
String and List Objects
As we discussed last week, strings and lists are objects in Python, and
thus we can invoke methods on string and list objects using dot notation
(e.g., lst.append(6)
).
We have also seen how we can write programs that modify the elements stored in
a list (e.g., lst[i] = 13
). A Python string is similar to a Python list in
that they are both a sequence of values, and it would be nice if we could also
modify individual elements (characters) in a string like we can modify elements
in a list. However, unlike lists, strings are immutable, meaning that
we cannot modify their elements.
Instead, in order to "modify" a string, we need to do the following:
-
Create a list from the string using either the
list
constructor passing it the string, or using thesplit
string method that returns a newly created list of single character strings, one from each character in the string (note: we will see thatlist
andsplit
do slightly different things in creating a new list from a string). -
Modify the elements in the list, changing one or more to point to new strings
-
Create a new string from this list, using the
join
string method.
In cs21/inclass/w08-TDD
is a file named list_n_string.py
that contains
some examples of invoking methods on string and list objects, and of
converting strings to lists and lists to strings. Let’s take a look at
this and see what it does.
Listed off this page are some other common string methods and other common list methods
Top Down Design
One of the primary topics in this class is Top Down Design (TDD), a problem solving technique that computer scientists use to solve larger problems. It is a technique that is done before coding where we:
-
Start with general description of problem
-
Break it into several high-level steps
-
Iteratively break the steps into smaller steps until you have steps that are easier to solve
Top-down design is a lot like creating a paper outline for a large paper where you start with the main sections, and iteratively refine each part with more and more detail until you are ready to start writing the paper.
When you use top-down design, your resulting program’s structure will match the above idea of an outline: the main function should have calls to a few high-level functions, one for each high-level step; high-level functions have calls to medium-level functions that implement sub-steps of the high-level steps; and so on.
After TDD, implementing the program involves:
-
writing program stubs for the functions in your program
-
iterative implementation and testing of functions, often in a bottom-up order (functions representing the lowest-level steps of the TDD first)
-
often, applying more TDD to refine parts further as we need to
In Labs 5 and 6 we did the TDD part for you, specifying the functions you should write and stepping you through the iterative implementation and testing of these functions to ultimately implement a larger program. In Lab 8, you are going to do the TDD part of implementing a larger program.
This week we will step through applying TDD and iterative implementation and testing to a problem together in class.
Wednesday
Top Down Design
One of the primary topics in this class is Top Down Design (TDD), a problem solving technique that computer scientists use to solve larger problems. It is a technique that is done before coding where we:
-
Start with general description of problem
-
Break it into several high-level steps
-
Iteratively break the steps into smaller steps until you have steps that are easier to solve
Top-down design is a lot like creating a paper outline for a large paper where you start with the main sections, and iteratively refine each part with more and more detail until you are ready to start writing the paper.
When you use top-down design, your resulting program’s structure will match the above idea of an outline: the main function should have calls to a few high-level functions, one for each high-level step; high-level functions have calls to medium-level functions that implement sub-steps of the high-level steps; and so on.
Iterative Refinement
When writing a large program, programmers use iterative refinement: do some top-down design, write function stubs for this part of code and maybe some implementation, then test. Iteratively, add more functions to accomplish subproblems, and perhaps refine some of the steps using top-down design, and test, and so on. The idea is to write some code, test it, then write a little more code, and test it before writing even more. Usually, I write a function, then test it, write another function, test it, … This way if I’m careful about testing, I know that if there is a bug in my program it is with the new code I’ve just added.
Function Prototyping
We often use prototyping to just put in function stubs so we can test the whole program’s flow of control without having to have a full implementation. For example, here is a stub for a function to compute square root (it doesn’t actually do anything related to the task, but we can call it from other parts of our program to see if the program’s flow matches the design):
def main():
# a sample call to our function to see if it works
test = squareRoot(16)
# for now, the program doesn't crash, but returns an incorrect result
# of the correct type. We can now go back an refine our function
print("Answer is: %.2f " % (test))
def squareRoot(num):
"""
This function computes the square root of a number.
num: the number
returns: the square root of num
"""
print("inside squareRoot")
# TODO: implement this function
return 1 # a bogus return value, but it lets me run the program
# and make calls to this function stub to "see" program flow
main()
Let’s try it out…
We are going to walk through the process of designing a computer game to simulate the dice game Craps. The rules for a single game are as follows:
-
A player rolls a pair of six-sided dice.
-
If the initial roll in step 1 is a 2, 3, or 12, the player loses.
-
If the initial roll in step 1 is a 7 or an 11, the player wins.
-
Otherwise, the player must roll for point. In this case, the player keeps rolling until she re-rolls the initial roll in step 1. (a winning game), or rolls a 7 (a losing game).
What are the chances of winning a single game of craps? Instead of heading to the casino, let’s use our Computer Science top down design skills to see if this is a good game to play.
We are going to design a program that asks the user for the number of craps games to simulate, and then output the percentage of games won.
Friday
We are going to continue with TDD today.