• No results found

1. Word Frequencies. Update the exercise inAccumulating Unique Valuesto count each occurance of the values in aSequence. Change the result from a simple sequence to adict. Thedict key is the value fromaSequence. Thedict value is the count of the number of occurances.

If this is done correctly, the input sequence can be words, numbers or any other immutable Python object, suitable for adict key.

For example, the program could accept a line of input, discarding punctuation and breaking them into words in space boundaries. The basic string operations should make it possible to create a simple sequence of words.

Iterate through this sequence, placing the words into a dict. The first time a word is seen, the frequency is 1. Each time the word is seen again, increment the frequency. Produce a frequency table. To alphabetize the frequency table, extract just the keys. A sequence can be sorted (see section 6.2). This sorted sequence of keys can be used to extract the counts from thedict.

2. Stock Reports. A block of publicly traded stock has a variety of attributes, we’ll look at a few of them. A stock has a ticker symbol and a company name. Create a simple dict with ticker symbols

For example:

stockDict = { 'GM': 'General Motors', 'CAT':'Caterpillar', 'EK':"Eastman Kodak" }

Create a simplelistof blocks of stock. These could betuples with ticker symbols, prices, dates and number of shares. For example:

purchases = [ ( 'GE', 100, '10-sep-2001', 48 ), ( 'CAT', 100, '1-apr-1999', 24 ),

( 'GE', 200, '1-jul-1999', 56 ) ]

Create a purchase history report that computes the full purchase price (shares times dollars) for each block of stock and uses the stockDict to look up the full company name. This is the basic relational database join algorithm between two tables.

Create a second purchase summary that which accumulates total investment by ticker symbol. In the above sample data, there are two blocks of GE. These can easily be combined by creating adictwhere the key is the ticker and the value is the list of blocks purchased. The program makes one pass through the data to create thedict. A pass through thedict can then create a report showing each ticker symbol and all blocks of stock.

3. Date Decoder. A date of the form ‘8-MAR-85’ includes the name of the month, which must be translated to a number. Create a dict suitable for decoding month names to numbers. Create a function which usesstringoperations to split the date into 3 items using the “-” character. Translate the month, correct the year to include all of the digits.

The function will accept a date in the “dd-MMM-yy” format and respond with atupleof (y,m,d). 4. Dice Odds. There are 36 possible combinations of two dice. A simple pair of loops over range(6)+1 will enumerate all combinations. The sum of the two dice is more interesting than the actual combination. Create adictof all combinations, using the sum of the two dice as the key.

Each value in thedictshould be alistoftuples; eachtuplehas the value of two dice. The general outline is something like the following:

Enumerate Dice Combinations

Initialize. combos←dict()

For all d1. Iterate with1≤d1<7. For all d2. Iterate with1≤d2<7.

Create a Tuple. t←(d1, d2).

In the Dictionary. Is d1+d2 a key incombos?

Append. Append the tuple,t to the value for itemd1+d2 incombos.

Not In the Dictionary. Ifd1+d2 is not a key incombos, then

Insert. Add a new elementd1+d2 to thecombos; the value is a 1-element list of the tuple,t.

Report. Display the resulting dictionary.

16.10 Advanced Parameter Handling For Functions

In More Function Definition Features we hinted that Python functions can handle a variable number of argument values in addition to supporting optional argument values.

When we define a function, we can have optional parameters. We define a fixed number of parameters, but some (or all) can be omitted because we provided default values for them. This allows us to provide too few positional argument values.

If we provide too many positional argument values to a function, however, Python raises an exception. It turns out that we can also handle this.

Consider the following example. We defined a function of three positional parameters, and then evaluated it with more than three argument values.

>>> def avg(a,b,c): return (a+b+c)/3.0

...

>>> avg(10,11,12) 11.0

>>> avg(10,11,12,13)

Traceback (most recent call last): File "<stdin>", line 1, in <module>

TypeError: avg() takes exactly 3 arguments (4 given)

First, we’ll look at handling an unlimited number of positional values. Then we’ll look at handling an unlimited number of keyword values.

16.10.1 Unlimited Number of Positional Argument Values

Python lets us define a function that handles an unknown and unlimited number of argument values. Ex- amples of built-in functions with a unlimited number of argument values aremax()andmin().

Rather than have Python raise an exception for extra argument values, we can request the additional positional argument values be collected into atuple. To do this, we provide a final parameter definition of the form *extras. The *indicates that this parameter variable is the place to capture the extra argument values. The variable, here called extras, will receive a sequence with all of the extra positional argument values.

You can only provide one such variable (if you provided two, how could Python decide which of these two got the extra argument values?) You must provide this variable after the ordinary positional parameters in the function definition.

The following function accepts an unlimited number of positional arguments; it collects these in a single

tupleparameter,args.

def myMax( *args ): max= args[0] for a in args[1:]:

if a > max: max= a return max

Here’s another example. In this case we have a fixed parameter in the first position and all the extra parameters collected into atuplecalledvals.

This should look familiar to C programmers. Now we can write the following, which may help ease the transition from C to Python.

printf( "%s = %d", "some string", 2 )

printf( "%s, %s, %d %d", "thing1", "thing2", 3, 22 )

16.10.2 Unlimited Number of Keyword Argument Values

In addition to collecting extra positional argument values into a single parameter, Python can also collect extra keyword argument values into adict.

If you want a container of keyword arguments, you provide a parameter of the form**extras. Your variable, here calledextras, will receive adictwith all of the keyword parameters.

The following function accepts any number of keyword arguments; they are collected into a single parameter. def rtd( **args ):

if "rate" in args and "time" in args:

args['distance'] = args['rate']*args['time'] elif "rate" in args and "distance" in args:

args['time']= args['distance']/args['rate'] elif "time" in args and "distance" in args:

args['rate']= args['distance']/args['time'] else:

raise Exception( "%r does not compute" % ( args, ) ) return args

Here’s two examples of using thisrtd()function.

>>> rtd( rate=60.0, time= .75 )

{'distance': 45.0, 'rate': 60.0, 'time': 0.75}

>>> rtd( distance=173, time=2+50/60.0 )

{'distance': 173, 'rate': 61.058823529411761, 'time': 2.8333333333333335}

The keyword arguments are collected into adict, namedargs. We check for combinations of “rate”, “time” and “distance” in the args dictionary. For each combination, we can solve for the remaining value and update thedictby insert the additional key and value into the dict.

16.10.3 Evaluation with a Container Instead of Individual Argument Values

When evaluating a function, we can provide a sequence instead of providing individual positional parameters. We do this with a special version of the*operator when evaluating a function. Here’s an example of forcing

a 3-tupleto be assigned to three positional parameters.

>>> def avg3( a, b, c ): ... return (a+b+c)/3.0 ... >>> data= ( 4, 3, 2 ) >>> avg3( *data ) 3.0

In this example, we told Python to assign each element of our 3-tuple nameddata, to a separate parameter variables of the functionavg3().

As with the*operator, we can use**to make adictbecome a series of keyword parameters to a function.

>>> d={ 'a':5, 'b':6, 'c':9 }

>>> avg3( **d ) 6.666666666666667

In this example, we told Python to assign each element of the dict, d, to specific keyword parameters of our function.

We can mix and match this with ordinary parameter assignment, also. Here’s an example.

>>> avg3( 2, b=3, **{'c':4} ) 3.0

Here we’ve called our function with three argument values. The parameterawill get its value from a simple positional parameter. The parameterb will get its value from a keyword argument. The parameterc will get its value from having thedict{'c':4}turned into keyword parameter assignment.

SEVENTEEN

SETS

Many algorithms need to work with simple containers of data values, irrespective of order or any key. This is a simple set of objects, which is supported by the Python set container. We’ll look at Sets from a number of viewpoints: semantics, literal values, operations, comparison operators, statements, built-in functions and methods.