Chapter 9, Lesson 1 Text

Lesson One: Writing and Calling Functions

 

Tool set with something missingfunction is a block of re-usable code that can be called (used) many times from different places in your program. Python contains many built-in functions that you already know like print(), input(), int(), str.format(), str.split(), datetime.strftime(), pdb.set_trace() and so on. But what happens if you don't have an existing function to do some task that your program needs?

In this chapter, you are going to learn how to create your own functions. Your program can rely on your own functions to produce more powerful and flexible behavior with cleaner code. Let's begin by reviewing simple function definitions and understanding where to place them in your source file.

Defining Functions

The overall format of a Python function is shown below.

def <function_name>( parameters ):
   "This optional line will explain what the function does."
   <function code statements>
   return

The function always starts with the "def" keyword (short for "definition"). This is followed by the function name, a set of parentheses and a list of optional parameters inside the parentheses. End the statement with a colon (:). We'll discuss function parameters in the next lesson, so for now we'll define simple functions with nothing inside the parentheses.

The body of the function is then indented underneath the "def" statement. As with all blocks of code in Python, this indentation sets apart the function body from the rest of the program and visually shows where the function begins and ends. The body of the function contains statements that will run each time the function is called.

The first optional line in the function body isn't really a statement at all. You can choose to add a quoted description of the function, if desired. This quoted string acts basically like a comment - it is not shown to the user or involved in the program logic. Because comments serve the same purpose, and a function description string is somewhat unique to Python, we'll mostly avoid using these optional quoted lines ourselves.

After an optional quoted description string comes the heart of your function. The remaining code statement(s) make up the body of your function and will run each time the function is called. Your function might be very simple with a single statement, or it might be very complex with dozens of statements, loops and other program logic.

A function should be ended with the "return" keyword. This keyword signals that the function is done and the program flow should return to the spot in the program from where the function was called.

Remember, all function description strings, body statements and the return keyword should be indented underneath the function "def" statement. Always use the same amount of indentation unless you are intending to start a new block of code with a new level of indentation. However, if you are continuing a long statement across multiple lines using "\" at the end of a line, you can indent the remaining parts of the statement any amount.

 

An Example Function: make_smiley()

Let's quickly define and run a small sample function. Our make_smiley() function will print out a smiley face on the screen using some character art. Run the code below to see make_smiley() in action!

Try It Now

def make_smiley():
print(" *** ")
print(" ** ** ")
print(" * * ")
print(" * * * * ")
print(" * * ")
print(" * * * ")
print(" * * * * ")
print(" * ***** * ")
print(" * * ")
print(" ** ** ")
print(" *** ")
return
# call the make_smiley() function
make_smiley()

Do you understand each part of this example? The first "def" line defines the function name. The parentheses after the function name can include a list of parameters, though make_smiley() doesn't need any parameters.

def make_smiley():

After the "def" statements comes the indented lines of code that make up the function body. We have skipped the optional function description string and began writing the body statements. In this example, we are simply using print() to create some artwork on the screen. Every time the make_smiley() function is called, a new smiley face is printed to the screen.

   print("        ***        ")
   print("      **   **      ")
   print("     *       *     ")
   print("    *  *   *  *    ")
   print("   *           *   ")
   print("   *     *     *   ")
   print("   *  *     *  *   ")
   print("    *  *****  *    ")
   print("     *       *     ")
   print("      **   **      ")
   print("        ***        ")

Finally, our function ends with the "return" keyword, which is the last indented line under the "def" statement.

   return

 

Calling Functions

Calling or using functions in Python is very simple. Just write the function name, followed by a set of parentheses, as shown below. Of course, if your function requires input values, you would place those parameters inside the parentheses.

# call the make_smiley() function
make_smiley()

Every time you call a function, all of the statements inside the function body are run. In many cases, you will define a function when you want to run the same block of code multiple times from different places in your program. Can you predict what will happen when you run the code below? We've called the make_smiley() function twice, so how many smiley faces will appear on the screen?

Try It Now

def make_smiley():
print(" *** ")
print(" ** ** ")
print(" * * ")
print(" * * * * ")
print(" * * ")
print(" * * * ")
print(" * * * * ")
print(" * ***** * ")
print(" * * ")
print(" ** ** ")
print(" *** ")
return
make_smiley() # call the make_smiley() function
print("Second time is the charm")
make_smiley() # call the make_smiley() function

Function Location within Your Code

Functions in Python must be defined before you can call them! Notice that in all of our examples so far, the function was first defined with the "def" statement, and then later (further down in the source file) we could make use of that function by calling it. This means that, generally speaking, your functions will be placed near the top of your source file. Try moving the make_smiley() function call in one of the above code boxes to the top, before the "def" statement.

make_smiley()        # ERROR - make_smiley() function not yet defined
def make_smiley():
   ...
   return
         

If you try to call a function before it has been defined, you will get a run-time error that tells you the function is not yet defined.

Traceback (most recent call last):
  File "code1.py", line 1, in 
    make_smiley()
NameError: name 'make_smiley' is not defined

If you are creating more than one function, simply place them one after another near the top of your file. You can start your main program flow after all of the functions have been defined.

def function1():
   <function statements here>
   return

def function2():
   <function statements here>
   return

def function3():
   <function statements here>
   return

print("Here we go!")         

Understanding Program Flow with Functions

You are used to programs flowing cleanly from the top of your source file all the way down to the bottom. The program flow might take some branches due to "if / else" logic, and it may even loop with "for" or "while" loops, but the overall sequence starts from line 1 and goes down from there.

Functions interrupt that normal program flow in two ways. First, when a function is defined with "def", program flow will initially skip that entire block of code. The function body statements will never run unless the function is specifically called somewhere later in the code. So, instead of starting at line 1, your program flow will actually start on the first line of code that is not inside a function definition! The illustration below shows the different starting points with and without a function defined at the top of the source file.

Starting point without and with function defs

Second, when you actually call a function, the program flow is transferred to the first statement inside that function. After the function completes with the return keyword, the program flow will go back to the first statement after the one that called the function. This transfer of program flow into a function and then back out happens each time you call the function.

Illustration of program flow into function calls

The diagram above shows how the program flow (in green) starts at the first line outside of a function and - overall - still flows from top to bottom in normal order. However, each time a function is called, the program flow moves inside that function until the return keyword is found. The flow from the first function call is shown in orange and the second function call in blue. Notice that each time the function returns, the flow continues with the next statement after the one that made the function call.

Can you you follow the arrows to trace the expected program flow in the above example? You should predict that the illustrated code produces messages in the following order.

The Beginning
Doing useful work
Doing useful work
The End          

Note that it is perfectly fine to call other functions from within a function body. So, if you are writing a function and want to make use of any other function - yours or defined by Python - from within your function body, go ahead! When the other function completes, the program flow will always return to the next statement after the one that called it.

Function Naming Rules

You have plenty of flexibility when choosing your variable names, and the same is true when defining function names. Your function names must follow these rules:

  1. The function’s name must consist only of lowercase or capital lettersnumbers and underscores (_). Spaces and other special characters are not allowed.
  2. The first symbol in your function name must always be either a letter or an underscore; you can't start with a number.
  3. Function names are case-sensitive. Therefore, functions named make_smiley(), Make_Smiley() and MAKE_SMILEY() are all different functions. When calling functions, you must write the function name exactly as it is defined, matching the case of all letters.

Here are some examples of valid and invalid function names.

def make_smiley():
def makeSmiley():
def MakeSmiley():
def _makeSmiley():
def make_smiley1000():
def 1MakeSmiley():     # ERROR - numbers cannot be first 
def make smiley():     # ERROR - spaces not allowed

It is best practice to pick one naming style and stick with it throughout your program. If you decide to capitalize the first letter of every word in your function name (MakeSmiley), do this for all your functions. If you decide to capitalize the first letter of every word except the first (makeSmiley), do this for all your functions. You could also decide to use all lowercase letters and separate any words with underscores (make_smiley). If you are consistent, other programmers who have to look at your code later will thank you!

Python's general style recommendations suggest using all lower case letters and underscores for function names, as in "make_smiley". You can see this style yourself in some built-in library functions like pdb.set_trace(). However, Python itself is not consistent - think about datetime.strftime().

Many programmers have a strong preference for their own personal styles. We will tend to use the Python recommendations like "make_smiley" or mixed case like "makeSmiley". The mixed case styles (also called "Camel Case") are popular across many programming languages.

 

Work with Me: Quotable Quotes

 

In this exercise, you are going to write a function the selects a random quote and prints it to the screen. The function will internally define a tuple that contains a list of available quotes. It then generates a random number as an index into that tuple, and prints the selected tuple value. Your main program flow will call this function twice to generate two quotes.

Follow the steps below to complete this exercise.

  1. Import the random library - you will need it to produce a random number!
  2. Define a function called "select_quote()". Inside the function, write indented statements for the function body as follows:
    1. Declare a tuple named quotes and initialize it with several quote strings. You can select your own quotes or, for simplicity, copy the following code into your function.
    2.   # set up a tuple of available quotes
        quotes = ("My fake plants died because I did not pretend to water them - Mitch Hedberg", \
                  "There cannot be a crisis next week.  My schedule is already full. - Henry Kissinger", \
                  "Weather forecast for tonight: dark. - George Carlin", \
                  "All generalizations are false, including this one. - Mark Twain", \
                  "Why do they call it rush hour when nothing moves? - Robin Williams")
    3. Create a variable named numQuotes and set it equal to the number of quotes in the tuple. Hint: review the len() function if needed.
    4. Create a variable named index and set it equal to a random number between 0 and the number of quotes (not including numQuotes itself). Hint: review the random.randrange() function if needed.
    5. Print the value of the quotes tuple found at the random index. Hint: access tuple elements with square brackets and the index number you have generated.
    6. Add a "return "statement to mark the end of the function.
  3. After the function is complete, main program should call select_quote() twice. These calls should each produce one random quote on the screen. Remember, your main program statements should not be indented.

The code below has some comments to help you get started.

Try It Now

# define a function that returns a random quote
# set up a tuple of available quotes
# get the number of available quotes
# get a random number between 0 and numQuotes - 1 (the last valid tuple index)
# print the selected quote
# function is complete
# main program will call select_quote() twice
  

Console

When you run your program, you should see two random quotes displayed on the screen. The example runs below demonstrate some possible output. Note that the same quote might be randomly selected within one run!

Weather forecast for tonight: dark. - George Carlin
Why do they call it rush hour when nothing moves? - Robin Williams
My fake plants died because I did not pretend to water them - Mitch Hedberg
There cannot be a crisis next week. My schedule is already full. - Henry Kissinger
All generalizations are false, including this one. - Mark Twain
All generalizations are false, including this one. - Mark Twain

Last modified: Sunday, 18 August 2019, 9:59 PM