Section 11.2. Calling Functions


11.2. Calling Functions

11.2.1. Function Operator

Functions are called using the same pair of parentheses that you are used to. In fact, some consider ( () ) to be a two-character operator, the function operator. As you are probably aware, any input parameters or arguments must be placed between these calling parentheses. Parentheses are also used as part of function declarations to define those arguments. Although we have yet to formally study classes and object-oriented programming, you will discover that the function operator is also used in Python for class instantiation.

11.2.2. Keyword Arguments

The concept of keyword arguments applies only to function invocation. The idea here is for the caller to identify the arguments by parameter name in a function call. This specification allows for arguments to be missing or out-of-order because the interpreter is able to use the provided keywords to match values to parameters.

For a simple example, imagine a function foo(), which has the following pseudocode definition:

 def foo(x):     foo_suite # presumably does some processing with 'x' Standard calls to foo():     foo(42)    foo('bar')    foo(y) Keyword  calls to foo():      foo(x=42)   foo(x='bar') foo(x=y)


For a more realistic example, let us assume you have a function called net_conn() and you know that it takes two parameters, say, host and port:

def net_conn(host, port):          net_conn_suite


Naturally, we can call the function, giving the proper arguments in the correct positional order in which they were declared:

net_conn('kappa', 8080)


The host parameter gets the string 'kappa' and port gets integer 8080. Keyword arguments allow out-of-order parameters, but you must provide the name of the parameter as a "keyword" to have your arguments match up to their corresponding argument names, as in the following:

net_conn(port=8080, host='chino')


Keyword arguments may also be used when arguments are allowed to be "missing." These are related to functions that have default arguments, which we will introduce in the next section.

11.2.3. Default Arguments

Default arguments are those that are declared with default values. Parameters that are not passed on a function call are thus allowed and are assigned the default value. We will cover default arguments more formally in Section 11.5.2.

11.2.4. Grouped Arguments

Python also allows the programmer to execute a function without explicitly specifying individual arguments in the call as long as you have grouped the arguments in either a tuple (non-keyword arguments) or a dictionary (keyword arguments), both of which we will explore in this chapter. Basically, you can put all the arguments in either a tuple or a dictionary (or both), and just call a function with those buckets of arguments and not have to explicitly put them in the function call:

func(*tuple_grp_nonkw_args, **dict_grp_kw_args)


The tuple_grp_nonkw_args are the group of non-keyword arguments as a tuple, and the dict_grp_kw_args are a dictionary of keyword arguments. As we already mentioned, we will cover all of these in this chapter, but just be aware of this feature that allows you to stick arguments in tuples and/or dictionaries and be able to call functions without explicitly stating each one by itself in the function call.

In fact, you can give formal arguments, too! These include the standard positional parameters as well as keyword argument, so the full syntax allowed in Python for making a function call is:

func(positional_args, keyword_args, *tuple_grp_nonkw_args, **dict_grp_kw_args)


All arguments in this syntax are optionaleverything is dependent on the individual function call as far as which parameters to pass to the function. This syntax has effectively deprecated the apply() built-in function. (Prior to Python 1.6, such argument objects could only be passed to apply() with the function object for invocation.)

Example

In our math game in Example 11.1 (easyMath.py), we will use the current function calling convention to generate a two-item argument list to send to the appropriate arithmetic function. (We will also show where apply() would have come in if it had been used.)

Example 11.1. Arithmetic Game (easyMath.py)

Randomly chooses numbers and an arithmetic function, displays the question, and verifies the results. Shows answer after three wrong tries and does not continue until the user enters the correct answer.

1 #!/usr/bin/env python 2 3 from operator import add, sub 4 from random import randint, choice 5 6 ops = {'+': add, '-': sub} 7 MAXTRIES = 2 8 9 def doprob(): 10    op = choice('+-') 11    nums = [randint(1,10) for i in range(2)] 12    nums.sort(reverse=True) 13    ans = ops[op](*nums) 14    pr = '%d %s %d = ' % (nums[0], op, nums[1]) 15    oops = 0 16    while True: 17        try: 18             if int(raw_input(pr)) == ans: 19                print 'correct' 20                break 21             if oops == MAXTRIES: 22                print 'answer\n%s%d'%(pr, ans) 23             else: 24                print 'incorrect... try again' 25                oops += 1 26        except (KeyboardInterrupt,  \ 27                EOFError, ValueError): 28             print 'invalid input... try again' 29 30 def main(): 31     while True: 32          doprob() 33         try: 34             opt = raw_input('Again? [y]').lower() 35             if opt and opt[0] == 'n': 36                break 37         except (KeyboardInterrupt, EOFError): 38             break 39 40 if __name__ == '__main__': 41     main()

The easyMath.py application is basically an arithmetic math quiz game for children where an arithmetic operationaddition or subtractionis randomly chosen. We use the functional equivalents of these operators, add() and sub(), both found in the operator module. We then generate the list of arguments (two, since these are binary operators/ operations). Then random numbers are chosen as the operands. Since we do not want to support negative numbers in this more elementary edition of this application, we sort our list of two numbers in largest-to-smallest order, then call the corresponding function with this argument list and the randomly chosen arithmetic operator to obtain the correct solution to the posed problem.

Line-by-Line Explanation
Lines 14

Our code begins with the usual Unix startup line followed by various imports of the functions that we will be using from the operator and random modules.

Lines 67

The global variables we use in this application are a set of operations and their corresponding functions, and a value indicating how many times (three: 0, 1, 2) we allow the user to enter an incorrect answer before we reveal the solution. The function dictionary uses the operator's symbol to index into the dictionary, pulling out the appropriate arithmetic function.

Lines 928

The doprob() function is the core engine of the application. It randomly picks an operation and generates the two operands, sorting them from largest-to-smallest order in order to avoid negative numbers for subtraction problems. It then invokes the math function with the values, calculating the correct solution. The user is then prompted with the equation and given three opportunities to enter the correct answer.

Line 10 uses the random.choice() function. Its job is to take a sequencea string of operation symbols in our caseand randomly choose one item and return it.

Line 11 uses a list comprehension to randomly choose two numbers for our exercise. This example is simple enough such that we could have just called randint() twice to get our operands, i.e., nums = [randint (1,10), randint(1,10)], but we wanted to use a list comprehension so that you could see another example of its use as well as in case we wanted to upgrade this problem to take on more than just two numbers, similar to the reason why instead of cutting and pasting the same piece of code, we put it into a for loop.

Line 12 will only work in Python 2.4 and newer because that is when the reverse flag was added to the list.sort() method (as well as the new sorted() built-in function). If you are using an earlier Python version, you need to either:

  • Add an inverse comparison function to get a reverse sort, i.e., lambda x,y: cmp(y, x), or

  • Call nums.sort() followed by nums.reverse()

Don't be afraid of lambda if you have not seen it before. We will cover it in this chapter, but for now, you can think of it as a one-line anonymous function.

Line 13 is where apply() would have been used if you are using Python before 1.6. This call to the appropriate operation function would have been coded as apply(ops[op], nums) instead of ops[op](*nums).

Lines 16-28 represent the controlling loop handling valid and invalid user input. The while loop is "infinite," running until either the correct answer is given or the number of allowed attempts is exhausted, three in our case. It allows the program to accept erroneous input such as non-numbers, or various keyboard control characters. Once the user exceeds the maximum number of tries, the answer is presented, and the user is "forced" to enter the correct value, not proceeding until that has been done.

Lines 3041

The main driver of the application is main(), called from the top level if the script is invoked directly. If imported, the importing function either manages the execution by calling doprob(), or calls main() for program control. main() simply calls doprob() to engage the user in the main functionality of the script and prompts the user to quit or to try another problem.

Since the values and operators are chosen randomly, each execution of easyMath.py should be different. Here is what we got today (oh, and your answers may vary as well!):

$ easyMath.py 7 - 2 = 5 correct Again? [y] 7 * 6 = 42 correct Again? [y] 7 * 3 = 20 incorrect... try again 7 * 3 = 22 incorrect... try again 7 * 3 = 23 sorry... the answer is 7 * 3 = 21 7 * 3 = 21 correct Again? [y] 7 - 5 = 2 correct Again? [y] n




Core Python Programming
Core Python Programming (2nd Edition)
ISBN: 0132269937
EAN: 2147483647
Year: 2004
Pages: 334
Authors: Wesley J Chun

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net