Lecture Date: Monday, October 10

We will continue talking about functions today. We will write a few new functions and cover some specific nuances of function usage:

  • calling a function from another function
  • local and global variables
  • variable name collision
  • keyword parameters
  • global variables vs. global constants
  • how to test a function
  • returning multiple values

Let's consider some different types of functions:

  • Functions might or might not return a value: All functions return - that's what happens when they reach the end or finish by using the keyword return. The difference is some bring back to the place where they were called some value of something. Others don't - we call these void functions.
  • Some functions have effects, even if they are void: Consider print(text). This function is technically void - it does not return anything. However, it does print stuff to the screen. A function can have an effect on the system even if it does not return a value. We will see this more when we consider how parameters are passed by value or passed by reference.
  • You can call functions from other files: The point of a library is to provide a set of functionality with functions that you can use in your program. You can then import that library in to a bunch of different programs. It's completely reusable.

When you invoke a function, the following happens in order:

  1. A new piece of memory (called a "stack frame" or "activation record") is created.
  2. The parameters of the function are created in that new memory.
  3. The parameters you pass in to the function invocation get copied into the new memory's parameters in order.
  4. We note where we left off running the old function
  5. We stack the new memory on top of the old memory, covering up the old memory completely
  6. We start running the code in the new function's body

When you return from a function, either with the return keyword or by reaching the end of the body, the new memory is removed ("popped") from the stack, leaving us with the calling function's memory.

Let's watch and see what happens at the Python Tutor Visualizer! -

Some example code for today:

import random

def who_wins(team_1, team_2):
    winner_choice = random.randint(0,1)
    if winner_choice == 0:
        return team_1
        return team_2

team_1 = input("Please enter Team 1: ")
team_2 = input("Please enter Team 2: ")

team_1_wins = 0
team_2_wins = 0

for i in range(10000):
    winner = who_wins(team_1, team_2)
    if winner == team_1:
        team_1_wins += 1
        team_2_wins += 1

if team_1_wins > team_2_wins:
    print(team_1 + " is the overall winner!  (" + str(team_1_wins) + " to " + str(team_2_wins) + ")")
elif team_2_wins > team_1_wins:
    print(team_2 + " is the overall winner!  (" + str(team_2_wins) + " to " + str(team_1_wins) + ")")
    print("It's a tie!  (" + str(team_2_wins) + " to " + str(team_1_wins) + ")")

Example code with optional/named parameters:

def my_function(name="Mark", school="UVa"):
    print(name + " goes to " + school)

my_function("Ann", "GMU")
my_function(school="GMU", name="Ann")