|I l@ve RuBoard|
We're going to start coding more sophisticated programs in this session. Be sure to check Appendix C if you get stuck, and be sure to start writing your code in module files. You won't want to retype some of these exercises from scratch if you make a mistake.
Basics. At the Python interactive prompt, write a function that prints its single argument to the screen and call it interactively, passing a variety of object types: string, integer, list, dictionary. Then try calling it without passing any argument: what happens? What happens when you pass two arguments?
Arguments. Write a function called adder in a Python module file. adder should accept two arguments and return the sum (or concatenation) of its two arguments. Then add code at the bottom of the file to call the function with a variety of object types (two strings, two lists, two floating points), and run this file as a script from the system command line. Do you have to print the call statement results to see results on the screen?
varargs. Generalize the adder function you wrote in the last exercise to compute the sum of an arbitrary number of arguments, and change the calls to pass more or less than two. What type is the return value sum? (Hints: a slice such as S[:0] returns an empty sequence of the same type as S, and the type built-in function can test types.) What happens if you pass in arguments of different types? What about passing in dictionaries?
Keywords. Change the adder function from Exercise 2 to accept and add three arguments: def adder(good, bad, ugly). Now, provide default values for each argument and experiment with calling the function interactively. Try passing one, two, three, and four arguments. Then, try passing keyword arguments. Does the call adder(ugly=1, good=2) work? Why? Finally, generalize the new adder to accept and add an arbitrary number of keyword arguments, much like Exercise 3, but you'll need to iterate over a dictionary, not a tuple. (Hint: the dictionary.keys() method returns a list you can step through with a for or while.)
Write a function called copyDict(dict) that copies its dictionary argument. It should return a new dictionary with all the items in its argument. Use the dictionary keys method to iterate. Copying sequences is easy (X[:] makes a top-level copy); does this work for dictionaries too?
Write a function called addDict(dict1, dict2) that computes the union of two dictionaries. It should return a new dictionary, with all the items in both its arguments (assumed to be dictionaries). If the same key appears in both arguments, feel free to pick a value from either. Test your function by writing it in a file and running the file as a script. What happens if you pass lists instead of dictionaries? How could you generalize your function to handle this case too? (Hint: see the type built-in function used earlier.) Does the order of arguments passed matter?
More argument matching examples. First, define the following six functions (either interactively, or in an importable module file):
def f1(a, b): print a, b # normal args def f2(a, *b): print a, b # positional varargs def f3(a, **b): print a, b # keyword varargs def f4(a, *b, **c): print a, b, c # mixed modes def f5(a, b=2, c=3): print a, b, c # defaults def f6(a, b=2, *c): print a, b, c # defaults + positional varargs
Now, test the following calls interactively and try to explain each result; in some cases, you'll probably need to fall back on the matching algorithm shown earlier in this chapter. Do you think mixing matching modes is a good idea in general? Can you think of cases where it would be useful anyhow?
>>> f1(1, 2) >>> f1(b=2, a=1) >>> f2(1, 2, 3) >>> f3(1, x=2, y=3) >>> f4(1, 2, 3, x=2, y=3) >>> f5(1) >>> f5(1, 4) >>> f6(1) >>> f6(1, 3, 4)
|I l@ve RuBoard|