05 Functions - 04 Parameters
In Python, parameters are used to pass values into functions. A parameter can have an optional value, often represented by None
, which acts as a placeholder for an argument that may or may not be provided.
The special value None
is often used in conditional tests because it evaluates to False
. This allows us to include logic to handle missing or optional parameters.
>>> def build_person(first_n, last_n, age=None):
... """Builds a dictionary representing a person."""
... person = {"first": first_n, "last": last_n}
... if age: # If age is provided, add it to the dictionary
... person["age"] = age
... return person
...
>>> name = build_person("jimi", "hendrix", 27)
>>> print(name)
{'first': 'jimi', 'last': 'hendrix', 'age': 27}
>>> name_without_age = build_person("jimmy", "page")
>>> print(name_without_age)
{'first': 'jimmy', 'last': 'page'}
Using Functions with a While Loop
Functions and loops can work together to make your program interactive and repetitive. A while loop can be used to repeatedly ask for input, such as names, and call a function based on that input.
>>> def get_formatted_name(first_name, last_name):
... """Returns a neatly formatted full name."""
... full_name = f"{first_name} {last_name}"
... return full_name.title()
...
>>> while True:
... print("\nPlease tell me your name: ")
... print("(Enter 'q' at any time to exit)")
...
... f_name = input("First Name: ")
... if f_name == "q":
... break
...
... l_name = input("Last Name: ")
... if l_name == "q":
... break
...
... name = get_formatted_name(f_name, l_name)
... print(f"\n{name.title()}")
Passing a List to a Function
Functions can also process multiple values by accepting a list (or any other collection) as an argument. This allows the function to perform an operation on each element in the list.
>>> def greeting(names):
... """Prints a greeting for each name in the list."""
... for name in names:
... print(f"Hello, {name.title()}.")
...
>>> usernames = ['hannah', 'ty', 'margot']
>>> greeting(usernames)
Hello, Hannah.
Hello, Ty.
Hello, Margot.
- The
greeting()
function takes a list of names (usernames
) as an argument. - It then loops through the list and prints a greeting for each name.
Moving Elements to a New List and Printing Without a Function
You can perform operations like moving elements from one list to another and then printing them without using functions. This is useful for simple tasks but can become cumbersome when working with larger or more complex programs.
>>> unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron']
>>> completed_models = []
>>> while unprinted_designs:
... one = unprinted_designs.pop()
... print(f"The following model is done: {one}")
... completed_models.append(one)
...
...
>>> print("\nThese have been printed:")
>>> for model in completed_models:
... print(model)
The following model is done: dodecahedron
The following model is done: robot pendant
The following model is done: phone case
These have been printed:
dodecahedron
robot pendant
phone case
Performing the Same Action with Functions
To make the code more modular and reusable, you can refactor repetitive code into functions. This allows you to encapsulate logic, making the program more organized and easier to maintain.
>>> def making_print(unprinted_designs, completed_models):
... """Simulates printing each design until none are left."""
... while unprinted_designs:
... one = unprinted_designs.pop()
... print(f"The following model is done: {one}")
... completed_models.append(one)
...
>>> def last_check(completed_models):
... """Displays all completed models."""
... print("\nThese have been printed:")
... for model in completed_models:
... print(model)
...
>>> # Lists to store designs
>>> unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron']
>>> completed_models = []
>>> # Call functions
>>> making_print(unprinted_designs, completed_models)
>>> last_check(completed_models)
The following model is done: dodecahedron
The following model is done: robot pendant
The following model is done: phone case
These have been printed:
dodecahedron
robot pendant
phone case
- The
making_print()
function moves designs fromunprinted_designs
tocompleted_models
. - The
last_check()
function prints out the models that have been completed.
By using functions, we can clearly separate different pieces of logic, making the code easier to follow and reuse.
Using Slice Notation to Pass a Copy of a List
When you need to pass a copy of a list to a function instead of the original list, you can use slice notation ([:]
). This creates a shallow copy of the list, ensuring that any changes made to the copy inside the function do not affect the original list.
>>> def print_models(unprinted_designs, completed_models):
... """Prints each model and adds it to the completed models list."""
... while unprinted_designs:
... one = unprinted_designs.pop()
... print(f"Printing model: {one}")
... completed_models.append(one)
...
>>> # Lists
>>> unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron']
>>> completed_models = []
>>> # Call the function with a copy of the list
>>> print_models(unprinted_designs[:], completed_models)
>>>
>>> # Original list remains unchanged
>>> print("\nUnprinted designs after function call:")
>>> print(unprinted_designs)
['phone case', 'robot pendant', 'dodecahedron']
>>>
>>> print("\nCompleted models:")
>>> print(completed_models)
['dodecahedron', 'robot pendant', 'phone case']
- The
[:]
slice notation creates a copy of theunprinted_designs
list and passes it to theprint_models()
function. - The original list
unprinted_designs
remains unchanged because we passed a copy, not the original list.
This approach ensures that the original data remains intact while still allowing the function to perform operations on it.