What's a function?
A function is a named sequence of statements that performs some useful operation
What's a method (well… in the context of programming, of course!)?
A method is an action that an object/thing can do. It's basically a function that's attached to an object.
What's a function call?
A function call is the statement that actually executes a function. It's just the function's name followed by parentheses, with zero or more arguments within those parentheses.
What's an argument (again, in the context of functions, of course)?
An argument is a value that's passed in to a function when a function is called. It's the input!
What's None?
None is a special value in Python that represents the absence of a value.
What's the syntax for defining a function?
def <function_name>(<zero_or_more_parameters>):
<statement #1>
<statement #2>
.
.
<etc.>
# an optional return statement
return <some value>
What does return do?
What's value is given back if a function doesn't return anything?
None
Using the following function and function call, what are the values of both greeting and num within the function? What's the output?→
def greet_more_input(greeting, num):
s = greeting * num
return s
import math
print(greet_more_input("hello".upper() * 2, int(math.sqrt(4))))
Using the following function and function call, what are the values of both greeting and num within the function? What's the output?→
def greet_more_input(greeting, num):
s = greeting * num
return s
num = "yo"
greeting = 1
print(greet_more_input(num, greeting))
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
What are the values of a, b and c in the above function when called as below:→
join_three_strings('one', 'two', 'three')
join_three_strings('three', 'one', 'two')
a = 'three'
b = 'two'
c = 'one'
join_three_strings(c, b, a)
What do you think will happen here? Will something be printed out? Nothing? Or an error?
s = "hello"
def greet():
print(s)
greet()
Oddly… it's fine. Something is printed out. It seems like the function has access to s, which was declared outside of the function.
What do you think will happen here? Will something be printed out? Nothing? Or an error?
def greet():
s = "hello"
print(s)
print(s)
Uh-oh. Looks like you can't access variables that are inside a function.
What do you think will happen here? Will something be printed out? Nothing? Or an error?
def greet(s):
s = s + "!"
print(s)
greet("foo")
print(s)
This is the same as the previous slide. You can't access the parameters (by their name) that you passed in to the function from outside of the function.
What do you think will happen here? Will something be printed out? Nothing? Or an error?
s = "hello"
def greet():
s = "something else"
print(s)
greet()
print(s)
Hmmm… it looks like names created within a function are local to that function. They don't override names in the global space.
A scope holds the current set of available names (variables) and the values that they point to.
a, b = 25, "something"
def foo():
c = "bar"
print(b)
print(c)
# what will this print out?
foo()
Variables that are defined in your function (one indentation level in), however, are only available within your function. They are local to that function. The example below won't work.
def foo():
c = "bar"
return c
print(c)
Furthermore, variables that are declared within a function that have the same name as a global variable are totally different variables/values! They don't overwrite the outer, global variable (there's a way to do this, though). What will this print?
c = "on toast"
def foo():
c = "grape jelly"
print(c)
foo()
print(c)
grape jelly
on toast
What's the difference between these two definitions of our function? What gets printed out for each code sample? →
Version #1
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
print(join_three_strings('one', 'two', 'three'))
Version #2
def join_three_strings(a, b, c):
print("%s %s %s" % (a, b, c))
print(join_three_strings('one', 'two', 'three'))
The first definition (#1) returns a string, while the other (#2) doesn't return a value. Here are the values that are returned from functions #1 and #2:
Note however, that the actual output is:
# version 1
one two three
# version 2 (the print within the function gets executed, followed by the
# print outside of the function)
one two three
None
What gets printed out for each version of code?
# version 1
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
# version 2
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
join_three_strings('one', 'two', 'three')
# version 3
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
print(join_three_strings('one', 'two', 'three'))
1: nothing, 2: nothing, 3: 'one two three'
So far, we've tested our programs by:
Some shortcomings of manual testing
What can we do to make testing less tedious and error prone? →
Let's get the computer to test it for us! Assertions are a way to systematically check the state of our program.
assert <some condition>, "a string representing a test"
Let's use assertions to test an incorrect implementation of our function - one that doesn't have spaces between the strings. →
def join_three_strings(a, b, c):
return "%s%s%s" % (a, b, c)
assert "ha ha ha" == join_three_strings("ha", "ha", "ha"), "should have spaces"
# output shows line number and error...
Traceback (most recent call last):
File "foo.py", line 4, in <module>
assert "ha ha ha" == join_three_strings("ha", "ha", "ha"), "joined string should have spaces"
AssertionError: joined string should have spaces
Let's fix the program… and see what happens. →
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
assert "ha ha ha" == join_three_strings("ha", "ha", "ha"), "should have spaces"
# results in no output
Let's use assertions to test an incorrect implementation of an absolute_value function →
def absolute_value(x):
if x >= 0:
return x
else:
return -1
assert 1 == absolute_value(-1), "absolute value of negative # is positive"
assert 1 == absolute_value(1), "absolute value of positive # is same #"
assert 0 == absolute_value(0), "absolute value of 0 is 0"
Example Usage:
>>> print(join_three_strings('one', 'two', 'three'))
one two three
>>> print(join_three_strings('1', '2', '3'))
1 2 3
>>> print(join_three_strings(1, 2, 3))
1 2 3
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
assert "one two three" == join_three_strings('one', 'two', 'three'), "three strings are joined with a space"
assert "1 2 3" === join_three_strings(1, 2, 3), "joins three ints as strings"
Using the function definition below, what is the value and type of a? →
def join_three_strings(a, b, c):
return "%s %s %s" % (a, b, c)
a = join_three_strings(4, 'five', 6)