Chapter 3

Functions

Functions in Python allow you to break a task down into appropriate subtasks. They are one of the powerful tools of abstraction that higher-level programming languages provide. Ideally, every function has a single, well-defined purpose.

Consider this example, which uses the sqrt() function from the math module to implement hypot(), also in the math module.

Listing 3.1: Hypotenuse

 1 # hypot.py
 2
 3 from math import sqrt
 4
 5 def myhypot(x, y):
 6 return sqrt(x ** 2 + y ** 2)
 7
 8 def main():
 9 a = float(input("a: "))
10 b = float(input("b: "))
11 print("Hypotenuse:", myhypot(a, b))
12
13 main()

Each chapter, as we begin with a new example, type the program in to your programming environment (such as IDLE), save it with the indicated name, and run it a few times before you continue. Try to determine how the program works, even though it may use new features that you have not seen before.

For our purposes, a Python program can be thought of as a collection of function definitions with one main function call. Listing 3.1 defines and calls two functions: myhypot() and main(). A function cannot be called unless it has been defined. The function myhypot() is defined in lines 5–6 and called in line 11. The function main() is defined in lines 8–11 and called in line 13. The order of function definitions is not important: as long as myhypot() is defined somewhere in this file, the definition of main() could have come first.

Code that is outside all function definitions (like all of Listings 1.1 and 2.1) is directly executed when the program is run. In Listing 3.1, only the function call in line 13 is outside all function definitions, and so it will be executed when the program is run. In a sense, it “drives” execution of the whole program. Because of this, the main() function is known as the driver. Usually, the driver definition and call are put at the end of a Python program.

Defining a Function

A function definition specifies the code that will be executed when the function is called. The syntax of a function definition looks like this:

def <function>(<parameters>):
 <body>

The def line must end with a colon. The colon signals the beginning of an indented block of code, in this case called the body of the function. The body is the code that will be executed when the function is called and may consist of any number of lines. In Listing 3.1, line 6 is the entire body of the myhypot() function.

Parameters are used to send additional information to a function so that it can do its job. The <parameters> in a function definition are optional. In Listing 3.1, the myhypot() function has two parameters named x and y.

Usually, function definitions appear near the top of Python programs, after any import statements, but before any directly executable code.

Calling a Function

Once a function has been defined, it may be called, meaning that it will be executed with particular arguments passed as the values for its parameters. The syntax for a function call is:

<function>(<arguments>)

When this expression appears in a program statement that is being executed, the function body executes, using the argument values as the values of the parameters.

In Listing 3.1, the function myhypot() is called in line 11. The arguments being passed or sent to myhypot() are the values of a and b at the time the program runs, after the input() expressions. The value of a will be used as the value of x in myhypot(), and the value of b will be used as y. For example, if you enter 4 and 7 in response to the input() expressions, then x will get the value 4 (the value of a) and y will get 7 (the value of b) when myhypot() is called on line 11.

Note: the name of an argument does not have to be the same as its corresponding parameter.

Function calls may be nested as in lines 9 and 10 of Listing 3.1. The inner function (in these cases, input()) runs first, and then the output of that function is immediately sent as the argument to the outer function (float()).

Return Statements

A return statement may optionally appear anywhere in the body of a function, and looks like this:

return <expression>

When this statement is executed inside of a function, it immediately terminates the function and returns the value of its <expression> as the value of the function call. In fact, the <expression> is also optional: if no expression is given, the value returned is the special value None.

In Listing 3.1, the return statement in line 6 computes and returns the length of the hypotenuse. The two steps of computing and returning could be separated:

 def myhypot(x, y):
  hyp = sqrt(x ** 2 + y ** 2)
  return hyp

This version will work exactly the same as the original.

If a function does not contain a return statement, the function returns the value None when the last executable statement of its body finishes.

Local Variables

Variables used for the first time inside of a function definition are called local because their use is limited to within the definition of that function. In other words, attempts to access that variable from outside the function definition will fail. The scope of a variable is the part of the program in which the variable may be accessed, so the scope of a local variable in Python is the function definition in which it is used. Variables defined outside of all function definitions are called global; we will rarely use global variables in this text.

Parameters in a function definition have the same scope as local variables: they may not be accessed outside of the function definition.

In Listing 3.1, a and b are local variables in the main() function, whereas myhypot() does not have any local variables.

Type Conversions

The input() function always returns user input as a string. In order to process numeric input, we need to convert the string to either an integer or float. Python has the following built-in functions to convert the types we have seen so far:

int(x)

Convert x to an integer, truncating floats towards 0.

int(x, b)

Convert x given in base b to an integer.

float(x)

Convert x to a floating-point value.

str(x)

Convert x to a string.

For the input of numeric data, choose between int() and float() depending on the context. Truncation means that any non-integer fraction is dropped, so, for example, int(3.975) returns 3, and int(−3.975) is −3.

Testing

An important part of writing functions (and programs in general) is testing them to make sure that they compute exactly what you intend. Some basic principles of testing are:

Test all important families of inputs. For example, include both positive and negative input values if they are appropriate. Test with both integers and floating point values.

Test known cases. Use input values that give outputs you can predict.

Test boundaries. For example, be sure your function behaves correctly at minimum and maximum input values (when appropriate).

Testing is probably the most important tool we have to improve software quality.

Exercises

  1. 3.1 Use Listing 3.1 to answer these questions:
    1. (a) Describe in your own words the subtask that the myhypot() function is designed to accomplish.
    2. (b) Which line or lines of code define the body of the main() function?
    3. (c) Is there a return statement inside main()? If not, when does main() return, and what value does it return?
    4. (d) Which line of code contains a call to the main() function? What happens if you try to run the program with that line of code deleted? Explain the result.
  2. 3.2 Describe the result if line 6 of Listing 3.1 is replaced with the single line:

    hyp = sqrt(x ** 2 + y ** 2)

    Explain the behavior you observe.

  3. 3.3 Does the alternate version of the myhypot() function on page 15 contain any local variables? If so, identify them; if not, explain why not.
  4. 3.4 Use Listing 3.1 to answer these questions:
    1. (a) List important families of inputs to test the myhypot() function. Test the program on values from each family and report the results.
    2. (b) List two sets of test values for the myhypot() function that fall in the category of known cases, where you know ahead of time what the results should be. Test the program on those values and report the results.
    3. (c) Does myhypot() have boundary cases to test? If it does, give them; if not, explain why not.
  5. 3.5 Modify Listing 3.1 to call myhypot(a, b) before the print() statement, storing the result in a new local variable, and then use the local variable in the print(). Discuss the tradeoffs.
  6. 3.6 Consider Listing 1.1 and its extension to include circumference in Exercise 1.2. Rewrite that version of circle.py to ask the user for the radius and use three functions for the area, circumference, and main program.
  7. 3.7 Rewrite Exercise 2.9 to ask the user for input and use two functions: one for computing the average and one for the main program.
  8. 3.8 Rewrite Exercise 2.10 to ask the user for input and use three functions for the area, perimeter, and main program. How many parameters will the area() and perimeter() functions need?
  9. 3.9 Rewrite Exercise 2.11 to ask the user for input and use three functions for the volume, surface area, and main program.
  10. 3.10 Rewrite Exercise 2.12 to ask the user for input and use three functions for the volume, surface area, and main program.
  11. 3.11 Write a program annulus.py that asks the user for an inner and outer radius, and then calculates and prints the area of an annulus with those dimensions. (Look up annulus if you do not know what one is.) Use a function to calculate the area of an annulus that itself calls a function that computes the area of a circle.
  12. 3.12 Write a program shell.py that calculates and prints the volume of a spherical shell, given its inner and outer radii. Use a function to calculate the voume of a shell that itself calls a function that computes the volume of a sphere.
  13. 3.13 Write a program temp.py that asks the user for a temperature in degrees Fahrenheit, and then calculates and prints the corresponding temperature in degrees Celsius. Use a function to perform the conversion.
  14. 3.14 Modify the previous exercise to also compute and display the equivalent temperature in degrees Kelvin. Use a separate conversion function (or two).
  15. 3.15 Write a program heart.py that asks for a person’s age in years y and then estimates his or her maximum heart rate in beats per minute using the formula 208 − 0.7y. Use appropriate functions.
  16. 3.16 Write a program heron.py that asks the user for the lengths of the sides of a triangle (a, b, and c) and then computes the area of the triangle using Heron’s formula. (Look up Heron’s formula if you do not remember it.) Use appropriate functions.
  17. 3.17 Write a program interest.py to calculate the new balance of a savings account if interest is compounded yearly. Ask the user for the principal, interest rate, and number of years, and then display the new balance. Use the formula P(1+r)t and appropriate functions.

    Enter interest rates as decimals: for example, a rate of 4% should be entered as 0.04. Use your program to determine the number of years it takes a principal to double with interest rate 1.5%.

  18. 3.18 Write a program compound.py to calculate the new balance of a savings account if interest is compounded n times per year. Ask the user for the principal, interest rate, number of years, and number of compounding periods per year, and display the new balance. Use the formula P(1+rn)nt and appropriate functions.

    Use your program to determine the difference over 20 years on a $1000 balance between compounding yearly and compounding monthly at 8% interest.

  19. 3.19 Write a program vp.py that asks the user for the temperature t in degrees Celsius and then displays the estimated vapor pressure of water vapor in millibars at that temperature using the approximation

    6.112e17.67tt+243.5

    Use appropriate functions. Use your program to estimate the temperature at which the vapor pressure is approximately 10 mb.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.137.108