Thus far, our programs have consisted of short code segments or scripts. Some of these have used built-in functions to do useful work. Some of our scripts might also be useful enough to package as functions to be used in other scripts. Moreover, defining our own functions allows us to organize our code in existing scripts more effectively. This section provides a brief overview of how to do this. We’ll examine program design with functions in more detail in Chapter 6.
The Syntax of Simple Function Definitions
Most of the functions used thus far expect one or more arguments and return a value. Let’s define a function that expects a number as an argument and returns the square of that number. First, we consider how the function will be used. Its name is square, so you can call it like this:
>>> square(2) 4
>>> square(6) 36
>>> square(2.5) 6.25
The definition of this function consists of a header and a body. Here is the code:
def square(x):
"""Returns the square of x."""
return x * x
e. Add the values in the list newData to the end of data. f. Locate the index of the value 7 in data, safely.
g. Sort the values in data.
3. What is a mutator method? Explain why mutator methods usually return the value None.
4. Write a loop that accumulates the sum of the numbers in a list named data. 5. Assume that data refers to a list of numbers, and result refers to an empty list.
Write a loop that adds the nonzero values in data to the result list, keeping them in their relative positions and excluding the zeros.
6. Write a loop that replaces each number in a list named data with its absolute value.
7. Describe the costs and benefits of aliasing, and explain how it can be avoided.
8. Explain the difference between structural equivalence and object identity.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
147 Defining Simple Functions
The header includes the keyword def as well as the function name and list of parameters.
The function’s body contains one or more statements. Here is the syntax:
def <function name>(<parameter-1>, ..., <parameter-n>):
<body>
The function’s body contains the statements that execute when the function is called. Our function contains a single return statement, which simply returns the result of multiply- ing its argument, named x, by itself. Note that the argument name, also called a parameter, behaves just like a variable in the body of the function. This variable does not receive an ini- tial value until the function is called. For example, when the function square is called with the argument 6, the parameter x will have the value 6 in the function’s body.
Our function also contains a docstring. This string contains information about what the function does. It is displayed in the shell when the programmer enters help(square). A function can be defined in a Python shell, but it is more convenient to define it in an IDLE window, where it can be saved to a file. Loading the window into the shell then loads the function definition as well. Like variables, functions generally must be defined in a script before they are called in that same script.
Our next example function computes the average value in a list of numbers. The function might be used as follows:
>>> average([1, 3, 5, 7]) 4.0
Here is the code for the function’s definition:
def average(lyst):
"""Returns the average of the numbers in lyst."""
theSum = 0
for number in lyst:
theSum += number return theSum / len(lyst)
Parameters and Arguments
A parameter is the name used in the function definition for an argument that is passed to the function when it is called. For now, the number and positions of the arguments of a function call should match the number and positions of the parameters in that function’s definition. Some functions expect no arguments, so they are defined with no parameters.
The return Statement
The programmer places a return statement at each exit point of a function when that func- tion should explicitly return a value. The syntax of the return statement for these cases is the following:
return <expression>
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
148
Upon encountering a return statement, Python evaluates the expression and immediately transfers control back to the caller of the function. The value of the expression is also sent back to the caller. If a function contains no return statement, Python transfers control to the caller after the last statement in the function’s body is executed, and the special value
None is automatically returned.
Boolean Functions
A Boolean function usually tests its argument for the presence or absence of some property.
The function returns True if the property is present, or False otherwise. The next example shows the use and definition of the Boolean function odd, which tests a number to see whether it is odd.
>>> odd(5) True
>>> odd(6) False def odd(x):
"""Returns True if x is odd or False otherwise."""
if x % 2 == 1:
return True else:
return False
Note that this function has two possible exit points, in either of the alternatives within the
if/else statement.
Defining a main Function
In scripts that include the definitions of several cooperating functions, it is often useful to define a special function named main that serves as the entry point for the script. This func- tion usually expects no arguments and returns no value. Its purpose might be to take inputs, process them by calling other functions, and print the results. The definition of the main function and the other function definitions need appear in no particular order in the script, as long as main is called at the very end of the script. The next example shows a complete script that is organized in the manner just described. The main function prompts the user for a number, calls the square function to compute its square, and prints the result. You can define the main and the square functions in any order. When Python loads this module, the code for both function definitions is loaded and compiled, but not executed. Note that
main is then called within an if statement as the last step in the script. This has the effect of transferring control to the first instruction in the main function’s definition. When square is called from main, control is transferred from main to the first instruction in square. When a function completes execution, control returns to the next instruction in the caller’s code.
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
149 Defining Simple Functions
"""
File: computesquare.py
Illustrates the definition of a main function.
"""
def main():
"""The main function for this script."""
number = float(input("Enter a number: ")) result = square(number)
print("The square of", number, "is", result) def square(x):
"""Returns the square of x."""
return x * x
# The entry point for program execution if __name__ == "__main:"__
main()
Like all scripts, the preceding script can be run from IDLE, run from a terminal command prompt, or imported as a module. When the script is imported as a module, the value of the module variable __name__ will be the name of the module, "computeSquare". In that case, the
main function is not called, but the script’s functions become available to be called by other code. When the script is launched from IDLE or a terminal prompt, the value of the module variable __name __ will be "__main__". In that case, the main function is called and the script runs as a standalone program. This mechanism aids in testing, as the script can be run repeatedly in the shell by calling main(), rather than reloading it from the editor’s window.
We will start defining and using a main function in our case studies from this point forward.
exercises
1. What roles do the parameters and the return statement play in a function definition?
2. Define a function named even. This function expects a number as an argument and returns True if the number is divisible by 2, or it returns False otherwise. (Hint: A number is evenly divisible by 2 if the remainder is 0.)
3. Use the function even to simplify the definition of the function odd presented in this section.
4. Define a function named summation. This function expects two numbers, named
low and high, as arguments. The function computes and returns the sum of the numbers between low and high, inclusive.
5. What is the purpose of a main function?
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
150
CaSe StuDy: Generating Sentences
Can computers write poetry? We’ll attempt to answer that question in this case study by giving a program a few words to play with.
request
Write a program that generates sentences.
analysis
Sentences in any language have a structure defined by a grammar. They also include a set of words from the vocabulary of the language. The vocabulary of a language like English consists of many thousands of words, and the grammar rules are quite complex. For the sake of simplicity our program will generate sentences from a sim- plified subset of English. The vocabulary will consist of sample words from several parts of speech, including nouns, verbs, articles, and prepositions. From these words, you can build noun phrases, prepositional phrases, and verb phrases. From these constituent phrases, you can build sentences. For example, the sentence “The girl hit the ball with the bat” contains three noun phrases, one verb phrase, and one preposi- tional phrase. Table 5-3 summarizes the grammar rules for our subset of English.
The rule for Noun phrase says that it is an article followed by (1) a Noun. Thus, a possible noun phrase is “the bat.” Note that some of the phrases in the left column of Table 5-3 also appear in the right column as constituents of other phrases. Although this grammar is much simpler than the complete set of rules for English grammar, you should still be able to generate sentences with quite a bit of structure.
The program will prompt the user for the number of sentences to generate. The pro- posed user interface follows:
Enter the number of sentences: 3 THE BOY HIT THE BAT WITH A BOY
phrase Its Constituents
Sentence Noun phrase + Verb phrase
Noun phrase Article + Noun
Verb phrase Verb + Noun phrase + Prepositional phrase
Prepositional phrase Preposition + Noun phrase
table 5-3 The grammar rules for the sentence generator
(continues)
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
151 Defining Simple Functions
THE BOY HIT THE BALL BY A BAT THE BOY SAW THE GIRL WITH THE GIRL Enter the number of sentences: 2 A BALL HIT A GIRL WITH THE BAT A GIRL SAW THE BAT BY A BOY
Design
Of the many ways to solve the problem in this case study, perhaps the simplest is to assign the task of generating each phrase to a separate function. Each function builds and returns a string that represents its phrase. This string contains words drawn from the parts of speech and from other phrases. When a function needs an individual word, it is selected at random from the words in that part of speech. When a function needs another phrase, it calls another function to build that phrase. The results, all strings, are concatenated with spaces and returned.
The function for Sentence is the easiest. It just calls the functions for Noun phrase and Verb phrase and concatenates the results, as in the following:
def sentence():
"""Builds and returns a sentence."""
return nounPhrase() + " " + verbPhrase() + "."
The function for Noun phrase picks an article and a noun at random from the vocabulary, concatenates them, and returns the result. We assume that the variables articles and
nouns refer to collections of these parts of speech and develop these later in the design.
The function random.choice returns a random element from such a collection.
def nounPhrase() :
"""Builds and returns a noun phrase."""
return random.choice(articles) + " " + random.choice(nouns)
The design of the remaining two phrase-structure functions is similar.
The main function drives the program with a count-controlled loop:
def main():
"""Allows the user to input the number of sentences to generate."""
number = int(input("Enter the number of sentences: ")) for count in range(number):
print(sentence())
The variables articles and nouns used in the program’s functions refer to the collec- tions of actual words belonging to these two parts of speech. Two other collections, named verbs and prepositions, also will be used. The data structure used to rep- resent a collection of words should allow the program to pick one word at random.
(continues) (continued)
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
152
Because the data structure does not change during the course of the program, you can use a tuple of strings. Four tuples serve as a common pool of data for the func- tions in the program and are initialized before the functions are defined.
Implementation (Coding)
When functions use a common pool of data, you should define or initialize the data before the functions are defined. Thus, the variables for the data are initialized just below the import statement.
"""
Program: generator.py Author: Ken
Generates and displays sentences using simple grammar and vocabulary. Words are chosen at random.
"""
import random
# Vocabulary: words in 4 different parts of speech articles = ("A", "THE")
nouns = ("BOY", "GIRL", "BAT", "BALL") verbs = ("HIT", "SAW", "LIKED")
prepositions = ("WITH", "BY") def sentence():
"""Builds and returns a sentence."""
return nounPhrase() + " " + verbPhrase() def nounPhrase():
"""Builds and returns a noun phrase."""
return random.choice(articles) + " " + random.choice(nouns) def verbPhrase():
"""Builds and returns a verb phrase."""
return random.choice(verbs) + " " + nounPhrase() + " " + \ prepositionalPhrase()
def prepositionalPhrase():
"""Builds and returns a prepositional phrase."""
return random.choice(prepositions) + " " + nounPhrase() def main():
"""Allows the user to input the number of sentences to generate."""
number = int(input("Enter the number of sentences: "))
(continues) (continued)
Copyright 2019 Cengage Learning. All Rights Reserved. May not be copied, scanned, or duplicated, in whole or in part. WCN 02-200-203
153