Day-06 More Functions
Day-06 More Functions
---------------------------------------------------------------------------
When we first introduced functions, we started with this example: TypeError Traceback (most recent call last)
<ipython-input-1-8d6428a8085c> in <module>()
6 thank_you('Billy')
7 thank_you('Caroline')
----> 8 thank_you()
That makes sense; the function needs to have a name in order to do its work, so without a name it is stuck.
If you want your function to do something by default, even if no information is passed to it, you can do so by
giving your arguments default values. You do this by specifying the default values when you define the function:
This is particularly useful when you have a number of arguments in your function, and some of those arguments
Here is a simple implementation of this function:
almost always have the same value. This allows people who use the function to only specify the values that are
unique to their use of the function.
In [22]: def describe_person(first_name, last_name, age):
# This function takes in a person's first and last name,
# and their age.
top
# It then prints this information out in a simple format.
print("First name: %s" % first_name.title())
print("Last name: %s" % last_name.title())
print("Age: %d\n" % age)
Exercises
describe_person('brian', 'kernighan', 71)
describe_person('ken', 'thompson', 70)
Games
describe_person('adele', 'goldberg', 68)
Write a function that accepts the name of a game and prints a statement such as, "I like playing chess!"
First name: Brian
Give the argument a default value, such as chess . Last name: Kernighan
Call your function at least three times. Make sure at least one of the calls includes an argument, and at least Age: 71
one call includes no arguments.
First name: Ken
Last name: Thompson
Favorite Movie Age: 70
Write a function that accepts the name of a movie, and prints a statement such as, "My favorite movie is The
First name: Adele
Princess Bride." Last name: Goldberg
Give the argument a default value, such as The Princess Bride . Age: 68
Call your function at least three times. Make sure at least one of the calls includes an argument, and at least
one call includes no arguments.
In [ ]: # Ex 8.1 : Games
The arguments in this function are first_name , last_name , and age . These are called positional top
arguments because Python knows which value to assign to each by the order in which you give the function
values. In the calling line
Favorite Colors
we send the values brian, kernighan, and 71 to the function. Python matches the first value brian with the first
argument first_name . It matches the second value kernighan with the second argument last_name . Finally Write a function that takes two arguments, a person's name and their favorite color. The function should print
it matches the third value 71 with the third argument age . out a statement such as "Hillary's favorite color is blue."
Call your function three times, with a different person and color each time.
This is pretty straightforward, but it means we have to make sure to get the arguments in the right order.
Phones
Write a function that takes two arguments, a brand of phone and a model name. The function should print
If we mess up the order, we get nonsense results or an error: out a phrase such as "iPhone 6 Plus".
Call your function three times, with a different combination of brand and model each time.
In [23]: def describe_person(first_name, last_name, age):
# This function takes in a person's first and last name,
# and their age. In [1]: # Ex 8.3 : Favorite Colors
# It then prints this information out in a simple format.
print("First name: %s" % first_name.title()) # put your code here
print("Last name: %s" % last_name.title())
print("Age: %d\n" % age) In [ ]: # Ex 8.4 : Phones
--------------------------------------------------------------------------- top
AttributeError Traceback (most recent call last)
<ipython-input-23-59fb6d0341c1> in <module>()
7 print("Age: %d\n" % age)
8
----> 9 describe_person(71, 'brian', 'kernighan')
Keyword arguments
10 describe_person(70, 'ken', 'thompson') Python allows us to use a syntax called keyword arguments. In this case, we can give the arguments in any
11 describe_person(68, 'adele', 'goldberg')
order when we call the function, as long as we use the name of the arguments in our calling statement. Here is
<ipython-input-23-59fb6d0341c1> in describe_person(first_name, last_name, ag how the previous code can be made to work using keyword arguments:
e)
3 # and their age.
4 # It then prints this information out in a simple format.
----> 5 print("First name: %s" % first_name.title())
6 print("Last name: %s" % last_name.title())
7 print("Age: %d\n" % age)
This fails because Python tries to match the value 71 with the argument first_name , the value brian with the
argument last_name , and the value kernighan with the argument age . Then when it tries to print the value
first_name.title() , it realizes it can't use the title() method on an integer.
In [3]: def describe_person(first_name, last_name, age): In [25]: def describe_person(first_name, last_name, age, favorite_language):
# This function takes in a person's first and last name, # This function takes in a person's first and last name,
# and their age. # their age, and their favorite language.
# It then prints this information out in a simple format. # It then prints this information out in a simple format.
print("First name: %s" % first_name.title()) print("First name: %s" % first_name.title())
print("Last name: %s" % last_name.title()) print("Last name: %s" % last_name.title())
print("Age: %d\n" % age) print("Age: %d" % age)
print("Favorite language: %s\n" % favorite_language)
describe_person(age=71, first_name='brian', last_name='kernighan')
describe_person(age=70, first_name='ken', last_name='thompson') describe_person('brian', 'kernighan', 71, 'C')
describe_person(age=68, first_name='adele', last_name='goldberg') describe_person('ken', 'thompson', 70, 'Go')
describe_person('adele', 'goldberg', 68, 'Smalltalk')
First name: Brian
Last name: Kernighan First name: Brian
Age: 71 Last name: Kernighan
Age: 71
First name: Ken Favorite language: C
Last name: Thompson
Age: 70 First name: Ken
Last name: Thompson
First name: Adele Age: 70
Last name: Goldberg Favorite language: Go
Age: 68
First name: Adele
Last name: Goldberg
Age: 68
This works, because Python does not have to match values to arguments by position. It matches the value 71 Favorite language: Smalltalk
with the argument age , because the value 71 is clearly marked to go with that argument. This syntax is a little
more typing, but it makes for very readable code.
We can expect anyone who uses this function to supply a first name and a last name, in that order. But now we
are starting to include some information that might not apply to everyone. We can address this by keeping
positional arguments for the first name and last name, but expect keyword arguments for everything else. We
Mixing positional and keyword arguments
can show this works by adding a few more people, and having different information about each person:
It can make good sense sometimes to mix positional and keyword arguments. In our previous example, we can
expect this function to always take in a first name and a last name. Before we start mixing positional and
keyword arguments, let's add another piece of information to our description of a person. Let's also go back to
using just positional arguments for a moment:
Everyone needs a first and last name, but everthing else is optional. This code takes advantage of the Python
keyword None , which acts as an empty value for a variable. This way, the user is free to supply any of the
'extra' values they care to. Any arguments that don't receive a value are not displayed. Python matches these
extra values by name, rather than by position. This is a very common and useful way to define functions.
This function appears to work well. But what if we pass it three numbers, which is a perfectly reasonable thing to arg_1: 1
arg_2: 2
do mathematically?
arg_3: (3,)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last) You can use a for loop to process these other arguments:
<ipython-input-40-9939998d2a01> in <module>()
5
6 # Let's add some numbers.
----> 7 adder(1, 2, 3)
This function fails, because no matter what mix of positional and keyword arguments we use, the function is only
written two accept two arguments. In fact, a function written in this way will only work with exactly two arguments.
arg_1: 1
arg_2: 2 We can then "unpack" these values, using a for loop. We can demonstrate how flexible this function is by calling
arg_3 value: 3 it a number of times, with a different number of arguments each time.
arg_3 value: 4
In [28]: def adder(num_1, num_2, *nums):
arg_1: 1
# This function adds the given numbers together,
arg_2: 2
# and prints the sum.
arg_3 value: 3
arg_3 value: 4
# Start by adding the first two numbers, which
arg_3 value: 5
# will always be present.
sum = num_1 + num_2
We can now rewrite the adder() function to accept two or more arguments, and print the sum of those numbers: # Then add any other numbers that were sent.
for num in nums:
In [7]: def adder(*nums): sum = sum + num
"""This function adds the given numbers together and prints the sum."""
# Print the results.
s = 0 print("The sum of your numbers is %d." % sum)
for num in nums:
s = s + num
# Print the results. # Let's add some numbers.
print("The sum of your numbers is %d." % s) adder(1, 2)
adder(1, 2, 3)
# Let's add some numbers. adder(1, 2, 3, 4)
adder(1, 2, 3) adder(1, 2, 3, 4, 5)
top
The third argument has two asterisks in front of it, which tells Python to collect all remaining key-value arguments
Accepting an arbitrary number of keyword arguments in the calling statement. This argument is commonly named kwargs. We see in the output that these key-values
are stored in a dictionary. We can loop through this dictionary to work with all of the values that are passed into
Python also provides a syntax for accepting an arbitrary number of keyword arguments. The syntax looks like
the function:
this:
arg_1: a
arg_2: b
arg_3: {'value_3': 'c'}
arg_1: a
arg_2: b
arg_3: {'value_4': 'd', 'value_3': 'c'}
arg_1: a
arg_2: b
arg_3: {'value_5': 'e', 'value_4': 'd', 'value_3': 'c'}
We can make this function much more flexible by accepting any number of keyword arguments. Here is what the This is pretty neat. We get the same output, and we don't have to include a bunch of if tests to see what kind of
function looks like, using the syntax for accepting as many keyword arguments as the caller wants to provide: information was passed into the function. We always require a first name and a last name, but beyond that the
caller is free to provide any keyword-value pair to describe a person. Let's show that any kind of information can
be provided to this function. We also clean up the output by replacing any underscores in the keys with a space.
In [4]: def describe_person(first_name, last_name, **kwargs):
# This function takes in a person's first and last name,
# and then an arbitrary number of keyword arguments.
# Required information:
print("First name: %s" % first_name.title())
print("Last name: %s" % last_name.title())
# Optional information:
for key in kwargs:
print("%s: %s" % (key.title(), kwargs[key]))