A function is a reusable block of code that is executed on command. When you instruct Python to execute a function, it is said that you are calling the function.
We have already been using several functions in this series. Namely, the print function and the input function.
A function is given a name or an identifier, just as variables are.
They may be created with parameters which allow them to receive and manipulate data. When we send a function values, such as a string to the print function, it’s said that we are passing an argument to the function. You may hear these terms used interchangeably, and they’re nearly the same thing. However, it’s technically an argument when you are calling a function and a parameter when you’re creating the function itself.
Finally, functions may return an object or a value.
If this seems a little confusing, hopefully some examples will help.
The Main Function
Python programs are executed from top to bottom. However, many other languages require you to define a “main” function or entry point to the program. This is the function that gets executed first, before anything else.
When you’re working with a file that contains multiple functions, it may make sense to define a main function. This helps better organize your code and makes it more understandable.
Depending on which IDE you’re using, a main function may have been automatically generated for you when you created your python file or python project.
Let’s examine what the main function looks like in Python.
def main(): print("Hello, World.") if __name__ == "__main__": main()
The above code contains a main function. Functions are declared or defined using the def keyword. All functions must have parenthesis following them when they’re defined or when they’re later called, even if they don’t have any arguments.
The main function of this sample code simply prints out the Hello, World message from earlier. Note that everything in the main function is indented, just as we had to indent the body of control statements, we must indent the body of a function.
At the end of the code, you’ll see a control statement which checks if __name__ equals “__main__”
This line is important. I’m going to oversimplify this slightly, but __name__ is a variable. The double underscores mean it’s a variable reserved by Python. It’s a special variable that holds some value related to the execution of the file. When this special variable __name__ is equal to __main__ it simply means the program is currently being run.
So in plain English, when the program is being run, call the main function above.
Order matters in Python. Before you can use any function in Python, you must define it first. If you attempt to call a function that’s defined further down in the file, it will throw an error message.
# this will not work if __name__ == "__main__": main() def main(): print("Hello, World.")
I would encourage you to create a main function in your python projects from now on. It’s a pretty standard practice.
Examples of Functions
We can create functions to do virtually anything. So let’s look at a few more examples.
In this first example, I am defining a method called print_stuff. All it does is print out the string “stuff”.
def print_stuff(): print("stuff") def main(): print_stuff() if __name__ == "__main__": main()
So in this example, the main function is called at the bottom. The main function then calls the print_stuff function, which prints out the word “stuff”
Note that for functions containing multiple words, like variables, the convention is to use an underscore between words.
We can call the print_stuff function as many times as we’d like, and it will continue to print out the word stuff.
def main(): print_stuff() print_stuff() print_stuff()
stuff stuff stuff
Next let’s create a slightly more complex function. This function will take two arguments (float variables) and print their sum.
def print_sum(num1, num2): sum = float(num1) + float(num2) print("the sum of",num1,"and",num2,"is",sum) def main(): print_sum(5, 25.5) if __name__ == "__main__": main()
the sum of 5 and 25.5 is 30.5
To define a function with parameters, they must be arranged into a comma separated list. In this case, my parameters are num1 and num2. The print_sum function then converts these to floats (if they’re not floats already) and prints their sum.
When I call print_sum from the main function with 5 and 25.5 as arguments, it takes them and does what it’s supposed to.
You may use however many arguments you require to get a function to work.
Now let’s create a function that returns a value. This is like before when we used float() and int() to convert strings to floats or ints. We pass the function something, and it returns something else. We can treat these functions just like variables.
The add_these function will work similarly to the previous print_sum function. But now it returns their sum as a value, rather than printing it.
def add_these(num1, num2): sum = float(num1) + float(num2) return sum def main(): added_nums = add_these(10, 10.5) print(added_nums) if __name__ == "__main__": main()
This time, the main function creates a variable called added_nums and sets it equal to add_these(10, 10.5). Since add_these returns the sum with the return keyword, added_nums becomes equal to 20.5. The main function then prints this to the screen.
Now let’s look at a slightly more useful example. The formula for the area of a circle is:\[\pi * r^2\]
Let’s create a function that returns the area of a circle given the radius.
To do this, define the function and give it a parameter “radius”
Next, we need to figure out how to get the value of pi. You could just use the number 3.14159, or however many digits of pi you know. A better option is to use the math.pi constant, which has pi to 15 decimal places.
To access the math.pi constant, we must first import the math module from the Python library. An import statement goes at the top of your python file. It includes or imports another file into your own file, so you may use its functions and constants.
import math def calc_circle_area(radius): area = math.pi * float(radius) * float(radius) return area def main(): test = calc_circle_area(5) print(test) if __name__ == "__main__": main()
Now that’s a more useful function! We can calculate the area of any circle using it, provided we know the radius. This would save you a lot of time if you needed to calculate the areas of multiple circles.
Calling A Function from Itself
There are many situations where you might want to call a function from itself.
Consider a simple program like the calculator assignment from the previous section. Suppose we want to give the user the option to “add” or “subtract” two numbers. They must type “add” or “subtract” – but what if they accidentally type the wrong thing? We don’t want the program to just end, or for them to encounter an error. We can fix this by simply placing everything inside a function, and then having it call itself if the user doesn’t type “add” or “subtract”
def main(): # have them enter two numbers a = float(input("Type a number: ")) b = float(input("Type another number: ")) # see what they want to do operation = input('Would you like to "add" or "subtract" ?') if operation == "add": print("The sum is:", a+b) elif operation == "subtract": print("The sum is:", a-b) # if neither of the above conditions were met, they must have typed something else else: print("You did not choose a valid option. Try again.") #call the main function over again main() if __name__ == "__main__": main()
Type a number: 5 Type another number: 9 Would you like to "add" or "subtract" ?ad You did not choose a valid option. Try again. Type a number:
In the above example on line 16, I call the main function again from within the main function. This allows the user to try the whole operation over again, without closing or crashing the program.
This is an example of basic input validation, which is checking for problems with user input before it is submitted. Note that I only performed basic input validation on the operation, but not the numbers. It’s still possible the user might try to add or subtract non-numbers, which may result in an error.
Consider the following code. What letter do you think will be printed?
letter = 'a' def do_something(): letter = 'c' def main(): letter = 'b' do_something() print(letter) if __name__ == "__main__": main()
Will the program print the letter a, b, or c?
If you run the code, you will find that it prints out the letter ‘b’. This is because variables defined within the scope of a function are local or specific to that function. The area a variable may be used in is its scope. Although they’re all called letter, they’re actually three different objects! Here’s what happened:
- Letter was set to ‘a’ on the first line.
- The main function was called, it created a new letter variable with a value of ‘b’
- The do_something function was called, which created a third letter value ‘c’
- Since I am printing the letter I created in the main function on line 9, it will print out ‘b’.
- The letter created in main() has absolutely nothing to do with the letter created on line 1 or line 4.
If you wanted to use the same instance of the variable letter across the different functions, you must tell python you’re using a global variable with the global keyword. Global variables are variables that may be used globally or anywhere in the code. They are usually defined at the top of the file, after any import statements.
You must remember to say the variable is global in every function where you want it to be so.
letter = 'a' def do_something(): global letter letter = 'c' def main(): global letter letter = 'b' do_something() print(letter) if __name__ == "__main__": main()
Since letter is now global, you will get an output of ‘c’ instead of b when you run the program.
Assignment: Assorted Calc
Instructions: Create a new python project based on this template. Implement all the calc functions according to the instructions in the comments.
""" Implement the three functions and test the code. Their return type should be a float. """ def calc_rectangle_area(width, height): # implement me (fix the following line) area = 0 return area def calc_circle_area(diameter): # remember, diameter is 2 radius area = 0 return area def calc_absolute_value(value): # hint use a control structure and multiply by -1 absolute = 0 return absolute def main(): # should print 1 print(calc_absolute_value(-1.0)) #should print 2 (or close to it) print(calc_circle_area(1.5958)) # should print 3 print(calc_rectangle_area(1.5, 2)) if __name__ == "__main__": main()
import math def calc_rectangle_area(width, height): area = float(width) * float(height) return area def calc_circle_area(diameter): radius = float(diameter) / 2 area = math.pi * radius * radius return area def calc_absolute_value(value): absolute = float(value) if absolute < 0: absolute = absolute * -1 return absolute def main(): # should print 1 print(calc_absolute_value(-1.0)) #should print 2 (or very close to it) print(calc_circle_area(1.5958)) # should print 3 print(calc_rectangle_area(1.5, 2)) if __name__ == "__main__": main()