7.3 Python Functions & Modules

Introduction to Functions

Functions are reusable blocks of code that perform a specific task. They help in organizing code, making it more readable and maintainable.

Why Use Functions?

  • Code reusability
  • Better organization
  • Easier debugging
  • Code abstraction

Defining and Calling Functions

Basic Function Syntax

def greet():
    """Display a simple greeting."""
    print("Hello, World!")

# Call the function
greet()  # Output: Hello, World!

Functions with Parameters

def greet_user(username):
    """Display a personalized greeting."""
    print(f"Hello, {username.title()}!")

greet_user('alice')  # Output: Hello, Alice!

Return Values

def get_formatted_name(first_name, last_name):
    """Return a full name, neatly formatted."""
    full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_formatted_name('jimi', 'hendrix')
print(musician)  # Output: Jimi Hendrix

Function Arguments

Positional Arguments

def describe_pet(animal_type, pet_name):
    """Display information about a pet."""
    print(f"\nI have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name.title()}.")

describe_pet('hamster', 'harry')
describe_pet('dog', 'willie')

Keyword Arguments

describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='harry', animal_type='hamster')  # Order doesn't matter

Default Values

def describe_pet(pet_name, animal_type='dog'):
    """Display information about a pet."""
    print(f"\nI have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name.title()}.")

describe_pet(pet_name='willie')  # Uses default animal_type 'dog'
describe_pet('harry', 'hamster')  # Overrides default

Arbitrary Arguments

def make_pizza(*toppings):
    """Print the list of toppings that have been requested."""
    print("\nMaking a pizza with the following toppings:")
    for topping in toppings:
        print(f"- {topping}")

make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

Working with Modules

Importing Modules

# Import an entire module
import math
print(math.sqrt(16))  # 4.0

# Import specific functions
from math import sqrt, pi
print(sqrt(16))  # 4.0
print(pi)        # 3.141592653589793

# Using an alias
import math as m
print(m.sqrt(16))  # 4.0

# Import all names (not recommended)
from math import *
print(sqrt(16))  # 4.0

Creating Your Own Modules

Save this as pizza.py:

def make_pizza(size, *toppings):
    """Summarize the pizza we are about to make."""
    print(f"\nMaking a {size}-inch pizza with the following toppings:")
    for topping in toppings:
        print(f"- {topping}")

Now you can import and use it:

import pizza

pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

Variable Scope

Local and Global Scope

# Global variable
title = "Python Programming"

def greet():
    # Local variable
    message = "Hello, "
    print(message + title)  # Can access global variable

greet()  # Output: Hello, Python Programming
# print(message)  # Error: message is not defined in global scope

The global Keyword

counter = 0

def increment():
    global counter
    counter += 1
    print(f"Counter: {counter}")

increment()  # Counter: 1
increment()  # Counter: 2

Practice Exercises

Exercise 1: Basic Function

Create a function called describe_city() that accepts the name of a city and its country. The function should print a simple sentence like "Reykjavik is in Iceland." Give the parameter for the country a default value. Call your function for three different cities, at least one of which is not in the default country.

def describe_city(city, country='Iceland'):
    """Describe a city and its country."""
    print(f"{city.title()} is in {country.title()}.")

# Call the function for three different cities
describe_city('reykjavik')
describe_city('akureyri')
describe_city('paris', 'france')

Exercise 2: Return a Dictionary

Write a function called make_album() that builds a dictionary describing a music album. The function should take an artist name and an album title, and it should return a dictionary containing these two pieces of information. Use the function to make three dictionaries representing different albums. Print each return value to show that the dictionaries are storing the album information correctly.

def make_album(artist, title, tracks=None):
    """Build a dictionary containing information about an album."""
    album = {'artist': artist, 'title': title}
    if tracks:
        album['tracks'] = tracks
    return album

# Create three albums
album1 = make_album('pink floyd', 'dark side of the moon')
album2 = make_album('the beatles', 'abbey road')
album3 = make_album('led zeppelin', 'iv', 8)

# Print the albums
print(album1)
print(album2)
print(album3)