A Large Program Must Be Divided Into to Make the Program Easy to Debug
03 Prepare: Writing Functions
Because most useful computer programs are very large, programmers divide their programs into parts. Dividing a program into parts makes it easier to write, debug, and understand the program. A programmer can divide a Python program into modules, classes, and functions. In this lesson and the next, you will learn how to write your own functions.
Videos
Watch the following four videos from Microsoft about writing functions:
Concepts
Here are the Python programming concepts and topics that you should learn during this lesson.
What Is a Function?
A function is a group of statements that together perform one task. Broadly speaking, there are four types of functions in Python which are:
-
Built-in functions
-
Standard library functions
-
Third-party functions
-
User-defined functions
In the previous lesson, you learned how to call the first two types of functions. In lesson 5, you will learn how to install third-party modules and call third-party functions. In this lesson, you will learn how to write and call user-defined functions.
What Is a User-Defined Function?
A user-defined function is a function that is not a built-in function, a standard function, or a third-party function. A user-defined function is written by a programmer like yourself as part of a program. For some students the term "user-defined function" is confusing because the user of a program doesn't define the function. Instead, the programmer (you) define user-defined functions. Perhaps a more correct term is programmer-defined function. Writing user-defined functions has several advantages, including:
-
making your code more reusable
-
making your code easier to understand and debug
-
making your code easier to change and add capabilities
How to Write a User-Defined Function
To write a user-defined function in Python, simply type code that matches this template:
def function_name(param1, param2, … paramN): """documentation string""" statement1 statement2 ⋮ statementN return value
The first line of a function is called the header or signature, and it includes the following:
-
the keyword
def
(which is an abbreviation for "define") -
the function name
-
the parameter list (with the parameters separated by commas)
Here is the header for a function named draw_circle
that takes three parameters named x
, y
, and radius
:
def draw_circle(x, y, radius):
You could read the previous line of code as, "Define a function named draw_circle
that takes three parameters named x, y, and radius."
The function name must start with a letter or the underscore (_). The rest of the name must be made of letters, digits (0–9), or the underscore. A function name cannot include spaces or other punctuation. A function name should be meaningful and should describe briefly what the function does. Well-named functions often start with a verb.
The statements inside a function are called the body of the function. Just like other block statements in Python, such as if
, else
, while
, and for
, all of which end with a colon (:), you must indent the statements inside the body of a function. The body of a function should begin with a documentation string which is a triple quoted string that describes the function's purpose, parameters and return value. The body of a function may contain as many statements as you wish to write inside of it. However, it is a good idea to limit functions to less than 20 lines of code.
Example 1 contains a function named print_cylinder_volume()
with no parameters that gets two numbers from the user: radius and height and uses those numbers to compute the volume of a right circular cylinder and then prints the volume for the user to see.
# Example 1 import math # Define a function named print_cylinder_volume. def print_cylinder_volume(): """Compute and print the volume of a cylinder. Parameters: none Return: nothing """ # Get the radius and height from the user. radius = float(input("Enter the radius of a cylinder: ")) height = float(input("Enter the height of a cylinder: ")) # Compute the volume of the cylinder. volume = math.pi * radius**2 * height # Print the volume of the cylinder. print(f"Volume: {volume:.2f}")
Because the print_cylinder_volume
function in example 1 doesn't accept parameters, it must be called without any arguments like this:
How to Make a User-Defined Function Reusable
Because the print_cylinder_volume
function in example 1 gets input from a user and prints its results to a terminal window, it can be used only in a program that runs when a user is present. It cannot be used in a program that runs automatically and gets input from a file or the network or a sensor. In other words, the print_cylinder_volume
function in example 1 is not reusable in other programs. The most reusable functions are ones that take parameters, perform calculations, and return a result but do not perform user input and output.
The parameter list in a function's header contains data stored in variables that the function needs to complete its task. A parameter is a variable whose value comes from outside the function. One way to get input into a function is to ask the user for input by calling the built-in Python input
function. Another way to get input into a function is through the function's parameters. Getting input through parameters is much more flexible than asking the user for input because the input through parameters can come from the user or a file on a hard drive or the network or a sensor or even another function.
Example 2 contains another version of the print_cylinder_volume
function. This second version doesn't get the radius and height from the user. Instead, it gets input through its two parameters named radius and height.
# Example 2 import math # Define a function named print_cylinder_volume. def print_cylinder_volume(radius, height): """Compute and print the volume of a cylinder. Parameters radius: the radius of the cylinder height: the height of the cylinder Return: nothing """ # Compute the volume of the cylinder. volume = math.pi * radius**2 * height # Print the volume of the cylinder. print(volume)
Because the second version of the print_cylinder_volume
function accepts two parameters, it must be called with two arguments like this:
print_cylinder_volume(2.5, 4.1)
To return a result from a function, simply type the keyword return
followed by whatever result you want returned to the calling function. Example 3 contains a third version of the cylinder volume function. Notice that the version in example 3 returns the volume instead of printing it, which makes the function more reusable. Notice also in example 3 that we changed the name of the function from print_cylinder_volume
to compute_cylinder_volume
because this version doesn't print the volume but instead returns it.
# Example 3 import math # Define a function named computer_cylinder_volume. def compute_cylinder_volume(radius, height): """Compute and return the volume of a cylinder. Parameters radius: the radius of the cylinder height: the height of the cylinder Return: the volume of the cylinder """ # Compute the volume of the cylinder. volume = math.pi * radius**2 * height # Return the volume of the cylinder so that the # volume can be used somewhere else in the program. return volume
Many functions that you've used in the past such as input
, float
, and round
, return a result. When a function returns a result, we usually write code to store that returned result in a variable to use later in the program like this:
text = input("Please enter your name: ")
Because the compute_cylinder_volume
function in example 3 accepts two parameters and returns a result, it could be called like this:
volume = compute_cylinder_volume(2.5, 4.1)
The main
User-Defined Function
In all previous Python programs that you wrote in CSE 110 and 111, you wrote statements that were not in a function like the simple program in example 4.
# Example 4 import math # Get the radius and height from the user. radius = float(input("Enter the radius of a cylinder: ")) height = float(input("Enter the height of a cylinder: ")) # Compute the volume of the cylinder. volume = math.pi * radius**2 * height # Print the volume of the cylinder. print(f"Volume: {volume:.2f}")
> python example_4.py Enter the radius in centimeters: 3 Enter the height in centimeters: 8 Volume: 226.19
Writing statements outside a function can lead to poor organization within a large program. Professional software developers write statements inside a function whenever possible. Beginning with this lesson, you will write nearly all statements inside a user-defined function. Also, in each program, you will write a user-defined function named main
, which will contain the beginning statements of the program. In addition, in each program you will write one or more user-defined functions that have parameteters, perform calculations and other useful work, and return a result to the call point. Example 5 contains the same Python program as example 4 except most of the statements are inside a user-defined function named main
.
# Example 5 import math # Define a function named main. def main(): # Get the radius and height from the user. radius = float(input("Enter the radius of a cylinder: ")) height = float(input("Enter the height of a cylinder: ")) # Compute the volume of the cylinder. volume = math.pi * radius**2 * height # Print the volume of the cylinder. print(f"Volume: {volume:.2f}") # Start this program by # calling the main function. main()
> python example_5.py Enter the radius in centimeters: 3 Enter the height in centimeters: 8 Volume: 226.19
Notice the call to the main
function at line 19 in example 5. Without that call to the main
function, when we run the program, the program will do nothing. In all of your future programs in CSE 111 you will write a user-defined function named main
and will have a call to main
at the bottom of the program.
A Complete Program with User-Defined Functions
If you look closely at the code in examples 1 and 5, you will realize that both programs have the same problem, namely both the print_cylinder_volume
function in example 1 and the main
function in example 5 are not reusable because both of them get input from a user and print to a terminal window. A better way to write the program in examples 1 and 5 is to separate the program into two functions, one named main
and one named compute_cylinder_volume
as shown in example 6.
Example 6 contains a complete program with two functions, the first named main
at line 6 and the second named compute_cylinder_volume
at line 20. At line 13, the main
function calls the compute_cylinder_volume
function. Notice that the compute_cylinder_volume
function gets its input through parameters and returns a result which makes this function reusable in other programs, including programs that run automatically without a user.
# Example 6 import math # Define the main function. def main(): # Get a radius and a height from the user. radius = float(input("Enter the radius of a cylinder: ")) height = float(input("Enter the height of a cylinder: ")) # Call the compute_cylinder_volume function and store # its return value in a variable to use later. volume = compute_cylinder_volume(radius, height) # Print the volume of the cylinder. print(f"Volume: {volume:.2f}") # Define a function that accepts two parameters. def compute_cylinder_volume(radius, height): """Compute and print the volume of a cylinder. Parameters radius: the radius of the cylinder height: the height of the cylinder Return: the volume of the cylinder """ # Compute the volume of the cylinder. volume = math.pi * radius**2 * height # Return the volume of the cylinder so that the # volume can be used somewhere else in the program. # The returned result will be available wherever # this function was called. return volume # Start this program by # calling the main function. main()
> python example_6.py Enter the radius in centimeters: 3 Enter the height in centimeters: 8 Volume: 226.19
The most reusable functions are ones that have parameters, perform calculations, and return a result but do not perform user input and output. In the previous code example, there are two functions named main
and compute_cylinder_volume
. The main
function is certainly useful in the program, but it is not reusable in other programs because it gets user input and prints the result for the user to see. The compute_cylinder_volume
function is very reusable in another program because it doesn't get user input or print output. Instead, it takes two parameters, performs a calculation, and returns a result to the calling function. The compute_cylinder_volume
function is so reusable that it could be included in a library of functions that compute the area and volume of 2-D and 3-D geometric shapes.
What Happens When the Computer Calls a Function?
Some students have trouble visualizing what happens when the computer calls (executes) a function. The following diagram contains the same program as example 6. The circled numbers show the order in which the events happen in the computer. The green numbers and arrows in the diagram show the order in which the computer executes statements in the program. The blue numbers and arrows show how data flows from arguments into parameters and from a returned result to a variable.
A computer will execute the statements in the previous diagram in the following order:
-
The statement at (1) is not inside a function, so the computer executes it when the program begins. The statement at (1) is a call to the
main
function which causes the computer to begin executing the statements insidemain
at (2). -
At (2), the computer gets two numbers from the user.
-
The statement at (3) is a call to the
compute_cylinder_volume
function which causes the computer to copy the values in the arguments r and h into the parameters radius and height respectively and then begin executing the statements inside thecompute_cylinder_volume
function at (5). -
At (5), the computer computes the volume of a cylinder.
-
The statement at (6) is a return statement which causes the computer to stop executing the
compute_cylinder_volume
function, to return the computed volume to the call point at (3), and to resume executing statements at the call point. -
At the call point (3), the computer stores the returned value in the variable named v.
-
At (8), the computer prints the value that is in the volume variable for the user to see. This is the last statement in the
main
function, so after executing it, the computer resumes executing the statements after the call point (1) tomain
. -
At (9), there are no more statements after the call to
main
, so the computer terminates the program.
Call Graphs
A call graph is a diagram that shows function calls and returns within a program. A call graph can help you visualize how a program is divided into functions. Within a call graph, the unfilled circle shows where the computer begins executing a program. A rounded rectangle represents a function. A solid arrow represents a call from one function to another function. A dashed arrow represents a value returned from a called function to the calling function.
The call graph below shows the function calls and returns for the program in example 6. From the call graph, we see that the computer begins executing the program by calling the main
function. While executing the main
function, the computer calls the input
and float
functions. Then the computer calls the compute_cylinder_volume
function. Finally the computer calls the print
function. In the call graph we can see that the main
and print
functions don't return a value. The print
function prints results for the user to see, but it doesn't return anything.
Summary
A function is a group of statements that together perform one task. A user-defined function is a function written by a programmer like you. To write a user-defined function, write code that follows this template:
def function_name(param1, param2, … paramN): """documentation string""" statement1 statement2 ⋮ statementN return value
To call a user-defined function, write code that follows this template:
variable_name = function_name(arg1, arg2, … argN)
The most reusable functions are ones that take parameters, perform calculations, and return a result but do not perform user input and output. All of your future programs in CSE 111 will have a user-defined function named main
and will have a call to main
at the bottom of the program.
It is extremely important that you can write and call functions. After watching the videos and reading this prepare content, if the concepts still seem confusing or vague to you, pray and ask Heavenly Father to help you understand the concepts. Then watch the videos and read the concepts again.
Source: https://byui-cse.github.io/cse111-course/lesson03/prepare.html
0 Response to "A Large Program Must Be Divided Into to Make the Program Easy to Debug"
Post a Comment