Functions are blocks of code that you give a name to that can then be easily run as a whole whenever you need that task performed. They can receive additional information to help with their task, and can return a result containing the information they generate. Writing functions lets us effectivly create our own Python commands that we can then use else where in our programs.
The easiest way to get an idea of functions is through a couple of simple examples. You are probably familiar with the concept of functions in math, so lets return to how we started this entire handbook by doing a little math (only a little I promise).
Hopefully you are comfortable with the following two math formulas:
- Area of a circle:
A = π r^2
- Circumference of a circle:
C = 2 π r
Obviously these are fairly simple formula such that you may not bother making functions for them, but it will allow the point to be demonstrated nicely.
def area(radius): PI = 3.1415 area = 2 * PI * radius ** 2 return area def circumference(radius): PI = 3.1415 circ = 2 * PI * radius return circ r = int(input("What is the radius of your circle?")) answer = area(r) print("The area of your circle is: ",answer) answer = circumference(r) print("The circumference of your circle is: ",answer)
A few things to point out:
- Functions declarations start with the key word
def. You then give your function a name, followed by any inputs it requires in parenthesis, followed by a colon.
- You must have the parenthesis after the function name. If no inputs are required, just leave it empty.
- Just like “if”, “while” and “for” you use indenting to show which code belongs to the function.
- The return at the end of the function is optional. If there is no result to pass back to the code that called it, you can skip it.
Functions are very useful for separating common tasks out from your main code. It allows you to avoid repeating yourself all the time which makes your code easier to maintain. Tasks like reading from a file, saving to a file, etc are all ideally suited to being chopped off into a separate function. If you’ve worked through the PyGame lessons, you’ve used some functions I’ve created before without fully appreciating what was going on, for instance in the lesson on sprite maps.
Putting functions in separate files
To further help make your code easier to maintain, you can even move all your functions into separate files so they don’t clutter up your main project file (like I used with the sprite map). To do this, you add either a
from ... import ... or an
import ... at the top of your main project file. Using the previous example, if the circle functions were saved in a file circles.py, it would work like this:
#### File: circles.py def area(radius): PI = 3.1415 area = 2 * PI * radius ** 2 return area def circumference(radius): PI = 3.1415 circ = 2 * PI * radius return circ
#### File: main.py from circles import * # From the circles file, import everything r = int(input("What is the radius of your circle?")) answer = area(r) print("The area of your circle is: ",answer) answer = circumference(r) print("The circumference of your circle is: ",answer)
The second method is generally considered better by programmers as it ensures the names of your functions won’t clash with anything in your “main” program. To illustrate the problem with the first method, what would happen if you had a
squares.py and a
triangles.py file you were also importing which also had functions called
area()? Python wouldn’t know which one to use. Method 2 solves that problem.
#### File: main.py import circles # Import the circles file, requiring the use of "circles." to access its content r = int(input("What is the radius of your circle?")) answer = circles.area(r) print("The area of your circle is: ",answer) answer = circles.circumference(r) print("The circumference of your circle is: ",answer)
A parameter is the name given to the values we put into the function when we run it. Our previous exercises just had one parameter, radius. What happens if we need more than one? Easy, we just comma separate them.
#### File: cylinders.py PI = 3.1415 def surface_area(radius, height): sa = 2 * PI * radius**2 + 2 * PI * radius * height return sa def volume(radius, height): v = PI * radius ** 2 * height return v
#### File: main.py import cylinders print("Cylinders calculator") r = int(input("Radius? ")) h = int(input("Height? ")) answer = cylinders.surface_area(r,h) print("Surface area: "+str(answer)) answer = cylinders.volume(r,h) print("Volume: "+str(answer))
What happens if we have so many parameters or functions we can’t remember the order in which they are required? For instance “Was it radius first then height, or height first then radius?”. Putting aside the fact that it’s easy to check and you should have good documentation to refer to… there is also another way: you can name your parameters when passing them in from main. Using the above example, we could change the file
main.py to the following.
import cylinders print("Cylinders calculator") r = int(input("Radius? ")) h = int(input("Height? ")) answer = cylinders.surface_area(height=h, radius=r) print("Surface area: "+str(answer)) answer = cylinders.volume(radius=r, height=h) print("Volume: "+str(answer))
Default and optional parameters
The final important thing to appreciate with functions is that you can decide that some parameters are optional, and work with a default value for them if they aren’t provided. The following example will make family_name an optional parameter.
# Providing a family_name is optional in this example def greetings( given_name, family_name=None ): if family_name: print("Hello "+given_name+" "+family_name) else: print("Hello "+given_name)
# In this example, if family_name is not provided, it will assume you are "Smith" def greetings( given_name, family_name="Smith" ): print("Hello "+given_name+" "+family_name)
In both cases, the following are all valid ways of calling the function from your main file:
greetings("Jane", "Doe") greetings("Jane") greetings( given_name="Jane" ) greetings( given_name="Jane", family_name="Doe" )