```
WEEK05: functions and lists
--------------------------------------------------------
M: who,what,when,where,and why of functions...

LAB 4: due Tuesday
REVIEW QUIZ 2

WHY FUNCTIONS:

- make code easier to maintain and debug
- good for code reuse
- necessary for large/complex programs

For example: you are working on a program to draw a heart.
What would you do if you had to draw many hearts? Wouldn't
it be nice call a drawHeart function, and give it a size
and position, like this:

drawHeart(position, size, color, window)

Now you can call that function over and over, giving it
different positions and sizes!

easier to read and write if you used functions. Something
like this:

if choice == 2:
winner()
else:
death()

If they choose option 2, they win the game. All other
choices lead to the death function.

FUNCTION ANALOGY:

Imagine you are planning a party and you ask a friend to help.
You might give your friend a list of people to invite and some
money to buy food and stuff. Your friend may give you back some
receipts.

you: main()
function arguments: list of fiends, amount of money
return value: list of receipts

def main():
money = 2500.00
friends = ["Lisa", "Rich", "Andy", "Frances"]
recpts = planParty(friends, money)
print recpts

def planParty(guests, money):
#
# here in the function you would use the two variables,
# guests and money, to plan out the party, keeping a
# list of all receipts...
receipts = []
#
# at the end of the function, return any receipts
return receipts

FUNCTION DETAILS:

def name(formal parameters):
body

def functionName(param1, param2, ...):
do this
and this
return this

Terminology related to functions:
invoking or calling:
starting the function's execution
arguments:
actual values that are inputs into a function
formal parameters:
variables that stand for inputs into a function
return values:
outputs from a function
scope:
the places in a program where a given variable may be referenced

EXAMPLES:

- simple functions have no parameters and don't return anything:

def print_greeting():
print "Hello there, welcome to my program"

- other functions have parameters and return something to main:

def count_letters(string, letter):
count = 0
for ch in string:
if ch == letter:
count = count + 1

return count

in the above count_letters function, whatever string and letter
are, it will count the number of times the letter is in the string
and return that number to the caller.

calling it like this:

n = count_letters("this is fun", "i")

would count the number of i's in the string, returning a 2.

FUNCTION TERMINOLOGY:

In the above example, "this is fun" and "i" are arguments.

Inside the count_letters function, the argument "this is fun" is
assigned to the parameter string (and the argument "i"
is assigned to the parameter letter).

All of the variables in count_letters are local in scope, meaning
they only exist when the function is being executed. Once the function
is finished, count, ch, letter, and string are gone.

Functions that return something to the calling program should return
the same kind of thing every time. For example, count_letters always
returns an integer.

Python allows functions to return more that one thing, but that's
usually not a good idea (and many other languages don't allow this).
Try to make your functions do just one thing.

- given a main function like this, write the countVowels() function
needed to make the program work:

def main():
"""get string, tell how many vowels are in the string
"""

print "\nEnter a string and I'll tell you how many vowels are in it...\n"

ustr = raw_input("string: ")

numv = countVowels(ustr)

if numv == 1:
print "\nThere is %d vowel in that string.\n" % (numv)
else:
print "\nThere are %d vowels in that string.\n" % (numv)

# --------------------------------------------------------- #

def countVowels(s):
#
# write this function
#

# --------------------------------------------------------- #

main()
```