8. Funktionen erstellen¶
In the last chapter we learned how to create variables and use
them in expressions. In this chapter we are going to build on
that knowledge to create functions. Functions are groups of commands we
give to the computer.
We’ve already used functions, for example the print
function and the draw_line
function. Now we are going to learn to make our own functions.
Functions help us by:
Making our code easier to read. By writing our own functions we can have functions to
draw_tree
anddraw_horse
which is a lot easier to read than long blocks of code that just draw lines and rectangles.Abstracting our code. By using variables, we can abstract our code and tell a function where to draw a tree, how big to draw it, and what color to draw it. This is a lot more flexible than one set of code that can only draw a tree in one exact place and one exact size.
Re-using our code. By calling a function, I can re-use code over and over. If it takes ten lines of code to draw a horse, I can put that in a function. Then if I want to draw three horses, I don’t need thirty lines of code to do it.
Dividing a complex problem into simpler ones. The key to programming, and a lot of things in life, is to learn how to take a large, overwhelmingly complex problem, and divide it into small problems. For example, we have functions that can display dots on the screen. Then there functions that can draw a line using those dots. Then functions that can draw triangles using those lines. Then functions that can draw trees using those triangles. Then finally a forest function that uses the trees function. Drawing a complex forest is broken down into simple functions that build off each other.
Making code easier to maintain. If there is a problem in your program, it is easier to find when your program is divided into parts. If your car isn’t moving correctly, and there is a
move_car
function, that’s easy to find. Plus, if all cars move using that function, I can fix a problem for every car in my game in one spot.
8.1. Einfache Funktionen erstellen¶
Defining a function in Python is easy. Here’s an example:
1 2 3 | def print_hello():
""" This is a comment that describes the function. """
print("Hello!")
|
To write a function:
Fange mit dem Schlüsselwort
def
, kurz für define, an.Next, give the function a name. Function names follow the same rules that variable names follow. They must:
Start with a lower case letter. (Or in special cases, an underscore.)
Nach dem ersten Buchstaben dürfen nur weitere Buchstaben, Ziffern und der Unterstrich folgen.
Leerzeichen sind nicht erlaubt. Verwende stattdessen Unterstriche.
Obwohl Großbuchstaben erlaubt sind, bestehen Funktionsnamen normalerweise nur aus Kleinbuchstaben.
Danach folgt ein Klammernpaar. In das Klammernpaar kommen die Parameter. Wir erklären das in Kürze.
Danach ein Doppelpunkt.
All the code that goes in the function will be on the following lines. That code must be indented four spaces. The first line that is not indented, signifies the function is done.
Üblicherweise starten wir eine Funktion mit einem mehrzeiligen Kommentar, der erklärt, was die Funktion tut.
Bemerkung
Funktionsdefinition gehören hinter die import
-Anweisungen und vor den Rest des Programms. Du könntest sie auch woanders hinschreiben, aber das solltest du nicht tun.
Defining a function doesn’t cause the computer to do anything. It is like giving a recipe to the computer. Give someone a recipe for banana bread and they know how to make it. They haven’t actually made it yet, they just know how. You have to tell them to make banana bread. That is, after we define the function we must call the function before the code in it runs.
To call a function, type the function name and follow it by parenthesis.
Do not use def
, that is only used when we define what the function does,
not when we tell the computer to run it.
Below is a program that defines print_hello
, then
calls it twice.
1 2 3 4 5 6 7 | def print_hello():
""" This is a comment that describes the function. """
print("Hello!")
# This calls our function twice.
print_hello()
print_hello()
|
You can define and use multiple functions. But all function definitions should go before the main code. In this example, see how we’ve defined two functions and then we call them in our main code.
1 2 3 4 5 6 7 8 9 10 11 | def print_hello():
print("Hello!")
def print_goodbye():
print("Bye!")
# Here is the main code, after all the function
# definitions.
print_hello()
print_goodbye()
|
8.2. Creating a Main Function¶
Es sollte sogar fast der gesamte Programmcode in Funktionen stehen. Es gehört zu einer vorbildlichen Vorgehensweise, den Startpunkt deines Programms in eine Funktion namens main
zu packen und aufzurufen,
In this next example, we do just that. See how we took the two function
calls and put them in a main
function. Also, note that we call main
at the end. Without that, our program won’t do anything at all.
main
function.¶1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def print_hello():
print("Hello!")
def print_goodbye():
print("Bye!")
def main():
""" This is my main program function """
print_hello()
print_goodbye()
# Call (run) the main function
main()
|
Remember how our drawing code always starts with import arcade
? That
just imports a lot of functions that are defined in the Arcade library
so we can use those functions ourselves. It doesn’t run anything, just
imports functions.
Eventually we’ll learn to write our own modules we import. Right now, we couldn’t do that with our code because attempting to import the code would actually run it. What we want is simply to make the functions available for us to use.
With that in mind, a better habit to get into is to check if we are
trying to import
the file before calling the main
function.
The statement, in this next example, looks a little weird.
In fact, it is weird enough I just look it up and copy/paste it any
time I want to use it. Don’t worry about understanding how it works yet,
just realize it is a good practice and why.
main
.¶1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def print_hello():
print("Hello!")
def print_goodbye():
print("Bye!")
def main():
print_hello()
print_goodbye()
# Only run the main function if we are running this file. Don't run it
# if we are importing this file.
if __name__ == "__main__":
main()
|
If this is too confusing, just call the main()
method instead. Eventually
we’ll learn about imports and if
statements. Then it will make more sense.
8.3. Take in Data with Parameters¶
Functions are even more powerful if we can feed data into them to process.
Here is a simple example that will take in a number and print it. Notice how
I’ve created a new variable my_number
in between the parenthesis.
This is called a function parameter. It is just a variable that
is given a value equal to what is passed in when called.
In the example below, it
is given first a 55
, then 25
, and finally an 8
.
1 2 3 4 5 6 7 | def print_number(my_number):
print(my_number)
print_number(55)
print_number(25)
print_number(8)
|
You can pass in multiple numbers, just separate them with a comma. In
this case a
will be 11 and b
will be 7.
1 2 3 4 5 | def add_numbers(a, b):
print(a + b)
add_numbers(11, 7)
|
Occasionally, new programmers want to set the parameter values inside the function. This is wrong. If you do this, the function would only work for those values. The power is in specifying the numbers outside the function. We don’t want the function to be limited to only certain data values.
This example works, but it is wrong. Because if we ever changed line 8 to pass in different values, the program would ignore those values because on lines 3 and 4 they are always over written with 11 and 7.
1 2 3 4 5 6 7 8 | # This is wrong
def add_numbers(a, b):
a = 11
b = 7
print(a + b)
add_numbers(11, 7)
|
8.4. Werte zurückgeben und weiterverarbeiten¶
Functions can not only take in values, functions can return values.
8.4.1. Werte zurückgeben¶
For example, here is a function that returns two numbers added together.
See how it uses a return
statement on line four to return the result out of the
function.
1 2 3 4 | # Add two numbers and return the results
def sum_two_numbers(a, b):
result = a + b
return result
|
Bemerkung
Return is not a function, and does not use parentheses. Don’t do
return(result)
.
This only gets us half-way there. Because if we call the function now, not much happens. Take a look at this example:
# This doesn't do much, because we don't capture the result
sum_two_numbers(22, 15)
The numbers get added. They get returned to us. But we do nothing with the result. So if you run this program, nothing prints to the screen and we can’t tell that anything happened.
8.4.2. Zurückgegeben Wert weiterverarbeiten¶
We need to capture the result. We do that by setting a variable equal to
the value the function returned. In this next code example we capture the result by
putting a variable to the left of the function call and using the =
(assignment)
operator. Later the code prints the value, but that’s not capturing! That is
just using the result we captured and printing it.
# Capture the function's result into a variable
# by putting "my_result =" in front of it.
# (Use whatever variable name best describes the data,
# don't blindly use 'my_result' for everything.)
my_result = sum_two_numbers(22, 15) # <--- This line CAPTURES the return value
# Now that I captured the result, print it.
print(my_result) # <--- This is printing, NOT capturing.
Now the result isn’t lost. It is stored in the my_result
variable
which we can print or use some other way.
We will do this a lot, so pause for a second and set it sit in your mind. I’ll wait.
Great, now imagine you have an instructor or co-worker watching over your shoulder. You have a function. It returns a value. The person over your shoulder says, „Ok, now you just have to capture the value.“ The pressure is on.
Don’t panic! Remember to capture
the value returned from a function, put a variable to the left of it and
use an =
operator.
8.4.3. Beispiel Zylindervolumen¶
Let’s use what we learned for something more practical. Here is a function that returns the volume of a cylinder. Notice how we take in two parameters and return the result of the calculation.
1 2 3 4 | def volume_cylinder(radius, height):
pi = 3.141592653589
volume = pi * radius ** 2 * height
return volume
|
Because of the return
, this function could be used later on as part of an
equation to calculate the volume of a six-pack like this:
six_pack_volume = volume_cylinder(2.5, 5) * 6
See how the value returned from volume_cylinder
goes into the equation and is
multiplied by six. We would not be able to chain together calculations like
that if all we could do was print
, instead of return
.
There is a big difference between a function that prints a value and a function that returns a value. Look at the code below. Pause for a bit and make sure you can follow how it works. Read the comments. This is a common source of confusion for new programmers, so spend a bit of time studying it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # This function will print the result
def sum_print(a, b):
result = a + b
print(result)
# This function will return the result
def sum_return(a, b):
result = a + b
return result
# This code prints the sum of 4+4, because the function has a print
sum_print(4, 4)
# This code prints nothing, because the function returns, and doesn't print
sum_return(4, 4)
# This code will not set x1 to the sum.
# The sum_print function does not have a return statement, so it returns
# nothing!
# x1 actually gets a value of 'None' because nothing was returned
x1 = sum_print(4, 4)
print("x1 =", x1)
# This will set x2 to the sum and print it properly.
x2 = sum_return(4, 4)
print("x2 =", x2)
|
This next code example has a very common issue new programmers face. It is not unusual to get stuck looking at code like this example below. Your task: how would you print the result of the function? See if you can figure it out without looking ahead.
def calculate_average(a, b):
""" Calculate an average of two numbers """
result = (a + b) / 2
return result
# Pretend you have some code here
x = 45
y = 56
# Wait, how do I print the result of this?
calculate_average(x, y)
What’s the answer?
How do we print the result of calculate_average
?
In the code above, the program can’t print
the result because the result
variable only exists inside the function.
Instead, use
a new variable outside the function, and the =
operator
to capture the result:
def calculate_average(a, b):
""" Calculate an average of two numbers """
result = (a + b) / 2
return result
# Pretend you have some code here
x = 45
y = 56
average = calculate_average(x, y)
print(average)
8.5. Funktionen dokumentieren¶
Functions in Python typically have a comment as the first statement of the function. This comment is delimited using three double quotes, and is called a docstring. In this case, the docstring is on line 2:
1 2 3 4 5 | def volume_cylinder(radius, height):
"""Returns volume of a cylinder given radius, height."""
pi = 3.141592653589
volume = pi * radius ** 2 * height
return volume
|
The great thing about using docstrings in functions is that the comment can be pulled out and put into a website. That can be part of a larger website that documents your code. For example, here is the documentation for drawing a circle, generated automatically from the function comment. In fact, everything on that page is automatically generated. Most languages have similar tools that can help make documenting a breeze. This can save a lot of time as you start working on larger programs.
8.6. Gültigkeitsbereich von Variablen¶
The use of functions introduces the concept of scope. Scope is where in the code a variable is „alive“ and can be accessed. For example, look at the code below:
# Define a simple function that sets
# x equal to 22
def f():
x = 22
# Call the function
f()
# This fails, x only exists in f()
print(x)
The last line will generate an error because x
only exists inside of the f()
function. Every heard the phrase „What happens in Vegas, stays in Vegas?“
Well, variables created in a function stay in the function.
The variable is created when f()
is called and the memory it uses is
freed as soon as f()
finishes.
Here’s where it gets complicated.
A more confusing rule is how to access variables created outside of the f()
function. In the following code, x
is created before the f()
function, and
thus can be read from inside the f()
function.
# Create the x variable and set to 44
x = 44
# Define a simple function that prints x
def f():
print(x)
# Call the function
f()
Variables created ahead of a function may be read inside of the function only
if the function does not change the value. This code, very similar to the code
above, will fail. The computer will claim it doesn’t know what x
is.
# Create the x variable and set to 44
x = 44
# Define a simple function that prints x
def f():
x += 1
print(x)
# Call the function
f()
8.7. Als Kopie übergeben¶
When you call a function and set a value to a function parameter, that value is a copy of the original. For example take a look at this code:
# Define a simple function that prints x
def f(x):
x += 1
print(x)
# Set y
y = 10
# Call the function
f(y)
# Print y to see if it changed
print(y)
The value of y
does not change, even though the f()
function increases the
value passed to it. Each of the variables listed as a parameter in a function
is a brand new variable. The value of that variable is copied from where it is
called.
This is reasonably straight forward in the prior example. Where it gets
confusing is if both the code that calls the function and the function itself
have variables named the same. The code below is identical to the prior listing,
but rather than use y
it uses x
.
# Define a simple function that prints x
def f(x):
x += 1
print(x)
# Set x
x = 10
# Call the function
f(x)
# Print x to see if it changed
print(x)
Die Ausgabe ist die gleiche wie vorher. Obwohl die Funktion und der umgebende Code x
als Variablennamen verwenden, sind es doch tatsächlich zwei verschiedene Variablen. Die eine Variable x
existiert innerhalb der Funktion. Die andere Variable x
existiert außerhalb der Funktion.
8.8. Funktionen rufen Funktionen auf¶
Überlege dir bei jedem der Beispiele unten, was es ausgeben wird. Überprüfe, ob du recht hattest. Wenn du falsch lagst, verwende Zeit darauf zu verstehen warum.
8.8.1. Beispiel 1¶
Beachte in diesem Beispiel, dass eine Funktion nur ausgeführt wird, wenn sie auch aufgerufen wird.
# Example 1
def a():
print("A")
def b():
print("B")
def c():
print("C")
a()
8.8.2. Beispiel 2¶
# Example 2
def a():
b()
print("A")
def b():
c()
print("B")
def c():
print("C")
a()
8.8.3. Beispiel 3¶
# Example 3
def a():
print("A")
b()
def b():
print("B")
c()
def c():
print("C")
a()
8.8.4. Beispiel 4¶
# Example 4
def a():
print("A start")
b()
print("A end")
def b():
print("B start")
c()
print("B end")
def c():
print("C start and end")
a()
8.8.5. Beispiel 5¶
# Example 5
def a(x):
print("A start, x =", x)
b(x + 1)
print("A end, x =", x)
def b(x):
print("B start, x =", x)
c(x + 1)
print("B end, x =", x)
def c(x):
print("C start and end, x =", x)
a(5)
8.8.6. Beispiel 6¶
In Zeile 3 dieses Beispiel wird der Wert von x
inkrementiert. Da aber die Variable x
in der Funktion eine andere Variable ist, als x
im Rest des Programms, ändert sich der angezeigte Wert nicht.
# Example 6
def a(x):
x = x + 1
x = 3
a(x)
print(x)
8.8.7. Beispiel 7¶
In diesem Beispiel, das dem vorherigen ähnelt, geben wir x
zurück. Es zeigt sich, dass das keinen Unterschied macht, da wir mit dem Rückgabewert nichts machen. Die globale Variable x
erhöht sich immer noch nicht. Sieh dir das nächste Beispiel an.
# Example 7
def a(x):
x = x + 1
return x
x = 3
a(x)
print(x)
8.8.8. Beispiel 8¶
In diesem Beispiel nehmen wir den von a()
zurückgegebenen Wert und speichern ihn in der Variablen x
. Wie? Durch Schreiben von x = a(x)
statt nur a(x)
.
# Example 8
def a(x):
x = x + 1
return x
x = 3
x = a(x)
print(x)
8.8.9. Beispiel 9¶
# Example 9
def a(x, y):
x = x + 1
y = y + 1
print(x, y)
x = 10
y = 20
a(y, x)
8.8.10. Beispiel 10¶
Obwohl man mehrere return
-Anweisungen in einer Funktion haben kann, endet die Funktion mit dem ersten return
. In diesem Beispiel wird return y
niemals ausgeführt, wir von der Funktion schon in der Zeile davor zurückgekehrt sind.
# Example 10
def a(x, y):
x = x + 1
y = y + 1
return x
return y
x = 10
y = 20
z = a(x, y)
print(z)
8.8.11. Beispiel 11¶
Dies ist etwas, das man nicht in jeder Programmiersprache machen kann. Du kannst zwei Werte auf einmal zurückgeben, indem du sie mit einem Komma getrennt angibst.
# Example 11
def a(x, y):
x = x + 1
y = y + 1
return x, y
x = 10
y = 20
z = a(x, y)
print(z)
8.8.12. Beispiel 12¶
Wenn du zwei Werte aus einer Funktion zurück gibst, kannst du sie in dieser vor weiterverarbeiten.
# Example 12
def a(x, y):
x = x + 1
y = y + 1
return x, y
x = 10
y = 20
x2, y2 = a(x, y) # Most computer languages don't support this
print(x2)
print(y2)
8.8.13. Beispiel 13¶
# Example 13
def a(my_data):
print("function a, my_data = ", my_data)
my_data = 20
print("function a, my_data = ", my_data)
my_data = 10
print("global scope, my_data =", my_data)
a(my_data)
print("global scope, my_data =", my_data)
8.8.14. Beispiel 14¶
Wir werden mehr über die nächsten beiden Beispiele reden, wenn wir „Listen“ und „Klassen“ behandeln. Diese Beispiele funktionieren nicht so, wie du das vielleicht zuerst erwartest. Sieh dir an, was unterschiedlich ist. Wir werden später erklären, warum dies anders funktioniert.
# Example 14
def a(my_list):
print("function a, list = ", my_list)
my_list = [10, 20, 30]
print("function a, list = ", my_list)
my_list = [5, 2, 4]
print("global scope, list =", my_list)
a(my_list)
print("global scope, list =", my_list)
8.8.15. Beispiel 15¶
# Example 15
# New concept!
# Covered in more detail in a later chapter
def a(my_list):
print("function a, list = ", my_list)
my_list[0] = 1000
print("function a, list = ", my_list)
my_list = [5, 2, 4]
print("global scope, list =", my_list)
a(my_list)
print("global scope, list =", my_list)
8.9. Review¶
This chapter was all about functions.
We learned how to define functions using the def
keyword.
We can call functions just by using the function name followed by parenthesis.
Functions can take in data by using parameters.
Functions return data using the return
statement.
We can capture that data by setting a variable equal to the function call.
Functions can be documented with comments.
Variables created inside a function cannot be accessed outside the function.
Parameter variables contain copies of the original data and can be modified without
changing the original.
Functions can call other functions, which can call yet more functions.
8.9.1. Online Coding Problems¶
Practice on-line by completing the first set of coding problems available here:
https://repl.it/community/classrooms/174286
All problems beginning with 02
can be done with the knowledge from this
chapter.