Functions II¶
more on user-defined functions
docstrings
default values
methods
string, list, & dictionary
in place vs not in place
relationship to functions
Clicker Question #1¶
What will the following code snippet print?
def my_func(my_dictionary):
output = []
for item in my_dictionary:
value = my_dictionary[item]
output.append(value) #append method adds an item to end of a list
return output
# create dictionary and execute function
dictionary = {'first' : 1, 'second' : 2, 'third' : 3}
out = my_func(dictionary)
print(out)
[1, 2, 3]
A) [‘first’, ‘second’, ‘third’]
B) {1, 2, 3}
C) [‘first’, 1, ‘second’, 2, ‘third’, 3]
D) [1, 2, 3]
E) None
Docstrings¶
When writing functions, it’s often helpful to include information about what the function does.
These are specified by text within triple quotes in the first line after your function is defined.
def list_dictionary(my_dictionary):
"""return list of dictionary values"""
## comment that is not very helpful
output = []
for item in my_dictionary:
value = my_dictionary[item]
output.append(value)
return output
list_dictionary?
Default Values¶
Default Value Functions¶
Specify a default value in a function by doing an assignment within the function definition.
# Create a function, that has a default values for a parameter
def exponentiate(number, exponent = 2):
return number ** exponent
# Use the function, using default value
exponentiate(3)
9
# Call the function, over-riding default value with something else
# python assumes values are in order of parameters specified in definition
exponentiate(2, 3)
8
# you can always state this explicitly
exponentiate(number = 2, exponent = 3)
8
Positional vs. Keyword Arguments¶
# Positional arguments use the position to infer which argument each value relates to
exponentiate(2, 3)
8
# Keyword arguments are explicitly named as to which argument each value relates to
exponentiate(number = 2, exponent = 3)
8
exponentiate(exponent = 3, number = 2)
8
# Note: once you have a keyword argument, you can't have other positional arguments afterwards
# this cell will produce an error
exponentiate(number = 2, 3)
File "<ipython-input-17-82d192fd1eb1>", line 3
exponentiate(number = 2, 3)
^
SyntaxError: positional argument follows keyword argument
Reminder, setting a default value for parameters is allowed during function definition.
(This may look like what we did above, but here we are including a default value for one parameter during function definition. During function execution, you can’t mix and match using positional vs. keywords)
def exponentiate(number, exponent = 2):
return number ** exponent
Clicker Question #2¶
What will the following code snippet print?
def exponentiate(number, exponent = 2):
return number ** exponent
exponentiate(exponent = 3, number = 2)
A) 8
B) 9
C) SyntaxError
D) None
Note: when using Keyword arguments position/order no longer matters
Methods¶
Method Examples¶
A method is a function applied directly to the object you call it on.
General form of a method:
object.method()
In other words: methods “belong to” an object.
# The `append` method, defined on lists
my_list = [1, 2, 3]
my_list.append(4)
print(my_list)
[1, 2, 3, 4]
The method append()
is called directly on the list my_list
# append is a method for lists
# this will error with a string
my_string = 'cogs18'
my_string.append('!')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-25-b99e95dcd8d7> in <module>()
2 # this will error with a string
3 my_string = 'cogs18'
----> 4 my_string.append('!')
AttributeError: 'str' object has no attribute 'append'
# The `is_integer()` method, defined on floats
my_float = 12.2
my_float.is_integer()
False
# The `is_integer()` method, attempted on an integer
# this code will produce an error
my_int = 12
my_int.is_integer()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-27-ba89eed6f102> in <module>()
2 # this code will produce an error
3 my_int = 12
----> 4 my_int.is_integer()
AttributeError: 'int' object has no attribute 'is_integer'
String Methods¶
There are a whole bunch of string methods, all described here. We’ll review a few of the most commonly used here.
# Make a string all lower case
'aBc'.lower()
'abc'
# Make a string all upper case
'aBc'.upper()
'ABC'
# Capitalize a string
'python is great'.capitalize()
'Python is great'
# Find the index of where a string starts
'Hello, my name is'.find('name')
10
Clicker Question #3¶
What will the following code snippet print out?
inputs = ['fIx', 'tYpiNg', 'lIkE', 'tHiS']
output = ''
for element in inputs:
output = output + element.lower() + ' '
output.capitalize()
'Fix Typing Like This '
A) ‘fix typing like this ‘
B) [‘fix’, ‘typing’, ‘like’, ‘this’]
C) ‘Fix typing like this ‘
D) ‘Fix typing like this’
E) ‘Fixtypinglikethis’
List Methods¶
There are also a bunch of list methods, all described here. You’ve seen some of these before, but we’ll review a few of the most commonly used here.
# sort sorts integers in numerical orders
ints = [16, 88, 33, 40]
ints.sort()
ints
[16, 33, 40, 88]
ints.sort(reverse=True)
ints
[88, 33, 16, 2]
# append adds to the end of a list
ints.append(2)
ints
[16, 33, 40, 88, 2]
# remove value from list
ints.remove(40)
ints
[16, 33, 88, 2]
list.remove?
# reverse order of list
ints.reverse()
ints
[2, 88, 33, 16]
Clicker Question #4¶
What will the following code snippet print out?
list_string = ['a', 'c', 'd', 'b']
list_string.sort()
list_string.reverse()
list_string
['d', 'c', 'b', 'a']
A) [‘a’, ‘c’, ‘d’, ‘b’]
B) [‘a’, ‘b’, ‘c’, ‘d’]
C) [‘d’, ‘c’, ‘b’, ‘a’]
D) [‘d’, ‘b’, ‘a’, ‘c’]
E) [‘d’, ‘a’, ‘b’, ‘c’]
Dictionary Methods¶
As with string and list methods, there are many described here that are helpful when working with dictionaries.
car = {
"brand": "BMW",
"model": "M5",
"year": 2019
}
# keys() returns the keys of a dictionary
car.keys()
dict_keys(['brand', 'model', 'year'])
# get returns the value of a specified key
mod = car.get('model')
# equivalent
mod2 = car['model']
print(mod)
print(mod2)
M5
M5
# previously done this by indexing
print(car['model'])
# update adds a key-value pair
car.update({"color": "Black"})
print(car)
{'brand': 'BMW', 'model': 'M5', 'year': 2019, 'color': 'Black'}
Clicker Question #5¶
Assuming dictionary
is a dictionary that exists, what would the following accomplish:
dictionary.get('letter')
A) Return the key for the value ‘letter’ from
dictionary
B) Add the key ‘letter’ to
dictionary
C) Add the value ‘letter’ to
dictionary
D) Return the value for the key ‘letter’ from
dictionary
Clicker Question #6¶
Which method would you use to add a new key-value pair to a dictionary?
A)
.append()
B)
.get()
C)
.keys()
D)
.update()
Methods: In Place vs Not In Place¶
List methods that are in place¶
# Reverse a list
my_list = ['a', 'b', 'c']
my_list.reverse()
print(my_list)
['c', 'b', 'a']
# Sort a list
my_numbers = [13, 3, -1]
my_numbers.sort()
print(my_numbers)
[-1, 3, 13]
Dictionary methods that are not in place¶
car
{'brand': 'BMW', 'model': 'M5', 'year': 2019, 'color': 'Black'}
# Return the keys in the dictionary
out = car.keys()
# print keys
print(type(out))
print(out)
<class 'dict_keys'>
dict_keys(['brand', 'model', 'year', 'color'])
# car has not changed
print(type(car))
print(car)
<class 'dict'>
{'brand': 'BMW', 'model': 'M5', 'year': 2019, 'color': 'Black'}
# Return the values in the dicionary
car.values()
dict_values(['BMW', 'M5', 2019, 'Black'])
Finding Methods¶
Typing the object/variable name you want to find methods for followed by a ‘.’ and then pressing tab will display all the methods available for that type of object.
# Define a test string
my_string = 'Python'
# See all the available methods on an object with tab complete
my_string.
Using the function dir()
returns all methods available
# For our purposes now, you can ignore any leading underscores (these are special methods)
dir(my_string)
['__add__',
'__class__',
'__contains__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__getnewargs__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mod__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__rmod__',
'__rmul__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'capitalize',
'casefold',
'center',
'count',
'encode',
'endswith',
'expandtabs',
'find',
'format',
'format_map',
'index',
'isalnum',
'isalpha',
'isascii',
'isdecimal',
'isdigit',
'isidentifier',
'islower',
'isnumeric',
'isprintable',
'isspace',
'istitle',
'isupper',
'join',
'ljust',
'lower',
'lstrip',
'maketrans',
'partition',
'replace',
'rfind',
'rindex',
'rjust',
'rpartition',
'rsplit',
'rstrip',
'split',
'splitlines',
'startswith',
'strip',
'swapcase',
'title',
'translate',
'upper',
'zfill']
Correspondance Between Functions & Methods¶
Note that:
my_variable.function_call()
acts like:
function_call(my_variable)
A function that we can call directly on a variable (a method) acts like a shortcut for passing that variable into a function.
Method / Function Comparison Example¶
my_float = 11.0
# Method call
print(my_float.is_integer())
# Function call
# Note: `is_integer` is part of the float variable type, which is why we access it from there
print(float.is_integer(my_float))
True
True
# method documentation
float.is_integer?
# function documentation
type?
is_integer
¶
You could write a function to check whether a float was an integer and use it as a function (rather than the method .is_integer()
) …and we know how to do that!
def is_integer(my_float):
if my_float % 1 == 0:
is_int = True
else:
is_int = False
return is_int
print(my_float)
is_integer(my_float)
11.0
True
A3 Q10: The instructions use the word append. They don’t tell you to use the method append()
. Remember:
append()
is a list method (not a string method)append (the word) just means add to the end
concatenation is how to add to the end of a string
Functions: Points of Clarification¶
Additional notes included here to clarify points we’ve already discussed. Not presented in class, but feel free to review and gain additional clarificaiton.
def
defines a functionfunction_name()
- parentheses are required to execute a functionfunction_name(input1)
- input parameters are specified within the function parenthesesfunction_name(input1, input2)
- functions can take multiple parameters as inputsinput1
andinput2
can then be used within your function when it executes
To store the output from a function, you’ll need a
return
statement
For example….¶
If you write a function called is_odd()
which takes an input value
,
def is_odd(value):
if value % 2 != 0:
answer = True
else:
answer = False
return answer
to use that function, you would execute is_odd(value)
….something like is_odd(value = 6)
out = is_odd(6)
out
Later on, if you wanted to use that function within another function you still have to pass an input to the function.
def new_function(my_list):
output = []
for val in my_list:
if is_odd(val):
output.append('yay!')
return output
new_function([1,2,3,4])