Module 10: Functions: a first look | CMSC 105 Elementary Programming - Fall 2024

Module 10: Functions: a first look

Note: Create a text file called module10.txt where you will store you answers to exercise questions. The questions that are not related to changing code. You will submit this file on Blackboard along with your code.

Objectives

By the end of this module you will be able to:

An example with function calls

Consider the following program:

# define a function we'll use later
def print_big_M():    
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *')

# define another one we'll use later
def print_big_O():    
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****')

# Print MOO using the above defined functions
print_big_M()
print_big_O()
print_big_O()

Exercise 1: Type up the above in animal_sounds.py and run it.


Let’s point out a few things:

# The "def" keyword tells Python we are defining a function
# print_big_M is the name we have given to this function
# The parens () in this case don't have anything between them
# The line that defines a function must end with a colon
def print_big_M():
    # These 5 indented prints form the "body" of the function    
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *')

def print_big_O():    
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****')

# Here, we invoke (or call) the function print_big_M
print_big_M()

# The function print_big_O is invoked twice
print_big_O() 
print_big_O()

Exercise 2: Write your own animal sound that uses one function at least thrice with an exclamation mark at the end, e.g. print the big version of BAAA!. Write your code in my_pet_sound.py.


Next, let’s see how functions “work” by making a small change to the program:

def print_big_M():
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *')

def print_big_O():
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****')

print('Step 1')
print_big_M()
print('Step 8')
print_big_O()
print('Step x')
print_big_O()
print('Step y')

Exercise 3: Type up the above in animal_sounds2.py and run it.


Let’s explain using an analogy:

# The print_big_M room	
def print_big_M():
    # After getting into this room
    # this gets executed next
    print('*   *') 
    print('** **') # Then this
    print('* * *') # Then this
    print('*   *') # Then this
    print('*   *') # Then this
    # After this last line
    # we return to after the instruction
    # to come into this room

def print_big_O():
    # Notice the 4-space indentation (tab)
    # This tells us that this group of 5 indented 
    # prints are all inside the print_big_O() function
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****')

# This is the main lobby
# Execution starts here
print('Step 1')
# This says "go to the print_big_M room"
print_big_M()
# Execution reaches here after returning from the print_big_M room 
print('Step 8') 
print_big_O()
print('Step x')
print_big_O()
print('Step y')

Exercise 4: At which step (which step number) do we execute the last line in print_big_O? And then, at which step do we enter print_big_O the second time and print its first line? In animal_sounds2.py replace x and y with the correct step number. Don’t forget: non-coding responses to exercises go into module10.txt.


Calling functions from other functions

Consider this program:

def print_big_M():
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *\n')

def print_big_O():
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****\n')

def print_two_big_Os():
    print_big_O()
    print_big_O()

print_big_M()
print_two_big_Os()

Exercise 5: Use this idea to rewrite your own animal sound in a file called my_pet_sound2.py. That is, add an additional function to your earlier program my_pet_sound.py that is analogous to print_two_big_Os() above.


Once again, let’s trace through some steps:

def print_big_M():
    print('*   *')     # 2
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *\n')   # 6

def print_big_O():
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****\n')

def print_two_big_Os():
    print_big_O()      # 8
    print_big_O()      # ?

print_big_M()          # 1
print_two_big_Os()     # 7

Exercise 6: Look at the example above. What step number is represented by the question mark (?) next to the second print_big_O() inside the print_two_big_Os() function? What line in the program represents step 15? Write your answer in module10.txt.


Mental execution:

More about functions

About function names:

Beware of name clashes:


Exercise 7: Implement the above in name_clash.py and describe what happens in module10.txt


The order of function invocation matters. For example, consider:

def print_big_M():
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *\n')

def print_big_O():
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****\n')

def print_two_big_Os():
    print_big_O()
    print_big_O()

# We've changed the order here:
print_two_big_Os()
print_big_M()

Exercise 8: Describe in your module10.txt how the output would be different, first without typing up the program, and then typing it up in animal_sounds3.py.


And now for something strange

Consider the following program:

def print_big_M():   
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *\n')

def print_big_O():   
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****\n')
    print_big_O()    # We're invoking the function from within

print_big_M()
print_big_O()

Exercise 9: Mentally execute the above program. That is, without typing it up, try to follow how the program executes, step by step. Which statement gets executed in the 10-th step of execution? Do you notice anything unusual at step 13? As a result, what line is executed in step 15? Write your answer in your module10.txt file.


Exercise 10: Before doing this exercise, remember in Thonny you can click the “STOP” button to stop endlessly running programs. Now, type up and execute the above program in my_strange_example.py. What do you notice? (Or you might get an “recursion depth exceeded” error.)


The term recursion is used when function calls itself:

Functions with for-loops

Consider the following program:

def print_big_M():  
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *\n')

def print_big_O():  
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****\n')

print_big_M()
print_big_O()  
print_big_O()  # 1st repetition
print_big_O()  # 2nd repetition
print_big_O()
print_big_O()
print_big_O()  # 5th repetition - 6 O's in all

What we would like is a way to organize repetition.

We will do this using one version (there are many) of the for-loop, one of the most important programming constructs:

def print_big_M():  
    print('*   *')
    print('** **')
    print('* * *')
    print('*   *')
    print('*   *\n')

def print_big_O():  
    print('*****')
    print('*   *')
    print('*   *')
    print('*   *')
    print('*****\n')


print_big_M()
for i in range(6):
    print_big_O()

Exercise 11: Type up the above in animal_sounds_loop.py and run it.


Exercise 12: Using the example above as a point of reference, print out your own animal sound. Be sure to use a for loop to repeatedly print one letter in the sound. Write your code in my_pet_sound_loop.py.