CS 1110 - Introduction to Programming
Starting Out with Python
Chapter 5, Functions, part 2
Objectives:
This lesson covers the rest of chapter 5, which
deals with saving function files. Objectives important to this lesson:
- Writing value-returning functions
- math module
- Storing functions in files (modules)
Concepts:
Chapter 5, part 2
Value-returning Functions
When we left off last week, we had looked at modularized programming, writing a
program with a main() function
that controls what the program does, specifically by calling other
functions as they are needed. We talked about passing arguments to functions, and writing
functions that can receive
arguments by placing parameter
variables in that function's parentheses. The parameter
variables are meant to catch the values of the arguments passed to the
function, and they must be declared in the function's definition.
Some functions are void
functions. This does not mean that the don't work, it means that
they do not return a value to
the command line that calls them. We also talked about return-value
functions, which have one command that the bottom of their code block
that enables them to return a value, typically the result of their
processing.
def function_name():
statement
statement
statement
return expression
We also talked about including a command to load a module of functions.
For example, there is a module included with Python that contains
advance math functions. If we want to use the functions stored in this
module, we first have to import the module into our program. The
command to do so would be at the top of the program. It would look like
this:
import math
We also talked about using dot
notation when calling a function that exists in an imported
module. We discussed calling the randint() function that is part of the
random module like this:
number = random.randint(1, 100)
Reading from left to right:
- the first thing we
see is a variable that will
catch/hold/remember the result of the function we are about to call.
the variable is called number
- the second thing
we see is an equal sign, which
is just an assignment operator
- the third thing we
see is the name of the loaded module
that contains the function we are going to call
- the name of the module
is immediately followed by a dot,
which is followed by the name of the function. the text calls this dot
notation. the simple version of this is that the function is a member
of, a part of the module, so the dot notation tells the interpreter
where to look, and what to look for
- finally, we see a set of parentheses, containing the arguments we are passing to the
randint() function. in this case, the arguments are 1 and 100, meaning
that we want the function to pick a number at random from the range 1
through 100
We should be up to date now. Let's look at a modification the
text suggests. The code the author used in a sample program said:
def sum(num1, num2)
result = num1 + num2
return result
The author points out that we can shorten this by one line. Since the
local variable result is only used for one purpose, we can do this,
making it unnecessary:
def sum(num1, num2)
return num1 + num2
Remember that a return
command can return the result of an
operation, or the value
of any valid expression.
Usually, you want to assign that value to a local variable in the
calling function (usually main()) so you can use it as needed. Program 5-22 illustrates most of the
concepts in the chapter so far. We will walk through it in class.
The spotlight feature on Modularizing with Functions shows how
you might develop a program while handling it as a series of function
calls. Consider what the programmer does in this case:
- Collect information about how commission is calculated for
sales people. This includes walking through the process with examples,
to make sure the program requirements are understood.
- The programmer writes pseudocode for the program, laying
out six functions this program must perform. This means that the main()
function will call six other functions.
- Rough out the code for the main function, naming the other
functions and deciding on their natures: will we pass arguments to
them, receive return values from them, or do both? You can decide this
based on what you need from each function, and what that function needs
to do its job. Note that you should design your functions so they only
need to return one value. You don't know how to collect more than one
value from a function yet. Hang on for a few minutes.
- Write the code for each function. Test the code, and
determine that they work properly.
We can walk through this lesson in class as well.
The text remarks that we can have a function return a string
as easily as having it return a number. It is done exactly the same way.
The example in the text about returning Boolean values is
pretty simple, up to the final code that is a bit more elegant than
most. In this example, the author is testing a number to find out
whether it is even or odd. Most integers can be said to be even or odd,
right? We see a very logical bit of code:
number = int(input("Enter a number: "))
if number % 2 == 0:
print( 'The number is even.')
else:
print( 'The number is odd.')
Before we go any farther, do you agree that there was no need
for a second conditional test? If the number is not even, can we assume
it is odd? Because, what else could it be? When there are only two
alternatives, and the test for the first one failed, there is only one
thing left that the answer could be. As long as your test is valid.
The text changes the output of the program to setting a
Boolean value for each outcome, True matching even numbers, and False
matching odd numbers. To make this more agreeable, the author calls
this bit of code a function, and names it is_even().
def is_even(number):
if number % 2 == 0:
status = True
else:
status = False
return status
So, if the function above exists, we can call it from a main()
function with a little more elegance"
number = int(input("Enter a number: "))
if is_even(number):
print( 'The number is even.')
else:
print( 'The number is odd.')
Why is that elegant? We are testing whether a number is even by passing its value to a
function that returns True
when the value is even, and False
when it is odd. We simply run the function, and the return value
determines which of two print() functions run.
Let's move on to learn how to return and receive two values
from a function. It is not hard, once you accept that the notation is
valid. It just looks weird. The text provides an example:
def main()
first_name, last_name = get_name()
def get_name():
first = input( 'Enter your
first
name:' )
last = input( 'Enter your
last name:' )
return first, last
The text warns us that the number of values returned must match the number of variables set to receive them.
When you write a program that requires more math than the
standard operators we have seen so far, you will probably need to
import the math module. A list of functions that can deal with
trigonometry are shown in table 5-2.
For a rather different lesson to end the chapter, turn to
section 5.10, where we learn that we can store collections of functions
we write in files, which should be no surprise. What may be a surprise
is that the files must be text files, and they must have .py
extensions, just like regular Python program files. Such a file that
has no programs in it, but has a collection of function definitions, is
a module, just like the modules we have been importing to use the
special functions that they contain. It would be confusing to the
interpreter to import two modules, each of which had a different
function with the same name. It would be a good idea to review the
functions that we already have in modules before accidentally creating
a separate function that either duplicates or breaks the work that is
already done for us.
As the lesson in the chapter ends, the author walks us through
saving to different modules, each holding only two function
definitions. He then imports both of those modules into program 5-28,
which presents a menu to the user, who can select which calcuation to
run from that menu.
|