Turn in this page for your group
There are two parts to this lab:
Extending the program here that prints songs will help you practice with organizing functions into working programs. You'll also learn about abstractions which are hard to define, but whose understanding-of and practice-with are part of learning about computer science.
Cyndi Lauper narrating
the Old Lady and the Fly
There was an old woman who swallowed a fly, I don't know why she swallowed the fly, Perhaps she'll die. There was an old woman who swallowed a spider, That wriggled and jiggled and tickled inside her, She swallowed the spider to catch the fly, I don't know why she swallowed the fly, Perhaps she'll die. There was an old woman who swallowed a bird, How absurd! to swallow a bird, She swallowed the bird to catch the spider, That wriggled and jiggled and tickled inside her, She swallowed the spider to catch the fly, I don't know why she swallowed the fly, Perhaps she'll die. I know an old lady who swallowed a cat, Imagine that, to swallow a cat! She swallowed the cat to catch the bird, She swallowed the bird to catch the spider, That wriggled and jiggled and tickled inside her, She swallowed the spider to catch the fly, I don't know why she swallowed the fly, I guess she'll die.
There are more verses to the song, you can find them here: http://www.poppyfields.net/poppy/songs/oldwoman.html. The first two verses of the song are slightly different in the pattern they use, all the other verses have the same pattern.
You should snarf the code to the lab (
OldWoman.py), you can also find it in
the code directory here. The third verse of the song
is generated by the function third
and the helper
functions it calls: bird
and
birdverse
:
def bird(): a1 = swallowed("bird") a2 = "How absurd to swallow a bird" return a1+"\n"+a2 def birdverse(): a1 = catch("bird","spider") a2 = spiderverse() return a1+"\n"+a2 def third(): a1 = bird() a2 = birdverse() return a1+"\n"+a2The fourth verse isn't shown in the output above, but it is part of the program you'll run and it is generated by the three functions below:
def cat(): a1 = swallowed("cat") a2 = "Imagine that to swallow a cat" return a1+"\n"+a2 def catverse(): a1 = catch("cat","bird") a2 = birdverse() return a1+"\n"+a2 def fourth(): a1 = cat() a2 = catverse() return a1+"\n"+a2First you'll answer a few questions about the pattern in the three functions that print the third and fourth verses. Then you'll rewrite these functions to make them better/more abstract. Then you'll write a new verse, then you'll work to really rewrite the program to make it much smaller and more amenable to change and extension.
We'll work to create the least amount of tedium, you may find some in this exercise -- but it's for a greater good and understanding of the power of computational abstraction.
third
and fourth
? What are the similarities?
cat
and bird
are similar,
what are the differences in the functions?
bird
, birdverse
,
third
could be written as follows.
def birdverse(): a1 = catch("bird","spider") a2 = spiderverse() return a1+"\n"+a2 def third(): def bird(): a1 = swallowed("bird") a2 = "How absurd to swallow a bird" return a1+"\n"+a2 a1 = bird() a2 = birdverse() return a1+"\n"+a2Note that the function
bird
is now nested inside the
function
third
and called from the function
third
. Since this is the only place bird
is called, it's a good idea to nest it inside third
since there's no need to call it from anywhere else in the program.
birdverse
cannot be
moved inside the function third
. If you
cut/copy/paste it inside third
, what does Eclipse
tell you?
a1
and a2
appear
in both bird
and third
-- provide a
plausible explanation of why this is ok and doesn't cause
confusion in the Python interpreter.
fourth
using the
the nesting technique in your working version of the program. What
are the last three lines of the function you wrote?
Modify the Python code by adding appropriate functions in the same style as those you're given to print the new verse below in addition to all the verses that are already printed. What are the names of the new functions you wrote? What are the last three lines of the function you wrote that contains a nested function?
I know an old lady who swallowed a dog, My, what a hog, to swallow a dog! She swallowed the dog to catch the cat, She swallowed the cat to catch the bird, She swallowed the bird to catch the spider, That wriggled and jiggled and tickled inside her, She swallowed the spider to catch the fly, I don't know why she swallowed the fly, I guess she'll die.
The function
RandomWalk.py
shows by a sequence of printed
X's a simulation of a bug or person walking left or right with equal
probability starting roughly in the middle of the screen. Here's the
first part of one run:
X X X X X X X X X X X X(answer on handin pages)
location
is initialized
to 0 and to 80 when the program is run? Why?
visual
in the function main
. Here's the
function you should write in RandomWalk.py
-- then
call this function appropriately from main
:
def analyze(visual): steps = visual.split("\n") print "number of steps taken: ",len(steps)
split
and the
variable
steps
in the code above?
analyze
from main
?
analyze
so that it prints the
bug's location that's farthest to the right using the code
below. Then answer the questions about the code.
def analyze(visual): steps = visual.split("\n") print "number of steps taken: ",len(steps) locs = [elt.find("X") for elt in steps] print "farthest right: ",max(locs)
find
do?
locs
in the
code above?
max
do?
sum
returns the sum of all numbers in a
list. Find the average value of the bug's location during a
walk by writing Python code. What's the code? What's the
average value in a random walk of 1000 steps?
(answer on handin pages)
In Part II you nested bird
inside of third
,
nested cat
inside of fourth
, and nested
dog
inside of fifth
. The
verse-functions:
third
,
fourth
,
fifth
are very similar, but each is different because
of the function that's not nested, e.g., birdverse
and
dogverse
and because of the names and characteristics of
the animals. In this section you'll find a way to avoid the
duplication by leveraging abstraction using functions that return
functions instead of strings.
Here's the new function that will take the place of
third
,
fourth
,
fifth
and other verse-fuctions, including the helper
functions
each one calls.
Here's the code -- you'll be asked questions about it, but you'll need
to type it into Eclipse, or to use the module
MetaOldWoman.py
that was snarfed.
def make_verse(animal, characteristic, eaten, previous): def opening(): a1 = swallowed(animal) a2 = characteristic return a1 + "\n" + a2 def chorus(): a1 = catch(animal,eaten) a2 = previous() return a1 + "\n" + a2 return (opening,chorus)Here's a
main
that uses this function:
def main(): print first() print print second() print bird,birdverse = make_verse("bird","How absurd to swallow a bird","spider",spiderverse) cat,catverse = make_verse("cat","Imagine that to swallow a cat","bird",birdverse) print bird() print birdverse() print print cat() print catverse() print
make_verse
returns two things, both are
functions. What are the clues in the return statement and
in the function call that two things are returned?
main
that the return values are functions and
not strings?
make_verse
that will result in
generating the verse about the woman eating a dog? How will you
use the returned values to print the verse?
make_verse
. Here's a new version of
main
that you should try to finish and about which
you'll answer questions.
def metamain(): print first() print print second() print animals = ["spider","bird","cat","dog","goat"] exclaims = ["", "How absurd to swallow a bird", "Imagine that to swallow a cat", "What a hog to swallow a dog", "Just opened her throat and swallowed a goat"] lastverse = spiderverse for i in range(1,len(animals)): start,verse = make_verse(animals[i],... print start() print verse() print lastverse=verse
make_verse
. Add them so the program runs using
this loop. What did you add?
lastverse
? What
type of value does it hold?