[Tutor] (No Subject)

Daniel Yoo dyoo@hkn.eecs.berkeley.edu
Sat, 30 Dec 2000 20:37:12 -0800 (PST)


On Wed, 27 Dec 2000, kevin parks wrote:

> 1. find the frequnce in the list below that is closest. 
> 2. return that frequency and the name of the associated sample. 
> e.g.: if i arrive at a frequency of  31.001 Hz, the code should look up and see that 32.703 is my closest available sample base frequency. It should return that number along with the name of the sample 'sh.forte C_1' so that i now have the desired frequency (31.001), the base frequency (32.703) and the sample name ('sh.forte C_1') which i can then use to calulate a transposition factor (31.001/32.703).
> 
> What is the best way to do this? In my old language i would use a
> look-up table to choose the base freq. and then a table with a step
> function to choose the sample. so that all frequncies from 0-27.500

Hmmm...  You can use a stepping function.  You might have run into the
problem of looking up a nonexisting dictionary value:

>>> dict = {3 : 'foo', 5: 'bar'}
>>> dict[1]
Traceback (innermost last):
  File "<stdin>", line 1, in ?
KeyError: 1

This occurs because Python assumes that a mistake has been made ---
usually, keys should match exactly.  If a key is invalid, Python will
raise KeyError.  What we can do to avoid KeyError is to first check if
your dictionary has a key using the dict's has_key() method:

if dict.has_key(something):
    # then doing dict[something] is safe

So your function could look like this:

###
def selectSample(dict, frequency, step_size):
    while not dict.has_key(frequency):
        frequency = frequency + step_size
    return dict[frequency]
###

So the above function will use the step_size to find the "ceil" of the
frequency you pass it.

However, you might also consider filling in the gaps of your lookup table
itself --- if you do that in your initialization, then you won't need to
do so much work throughout the rest of your program.  Your table will be
much larger, true, but it might save some time.  There are proabbly many
solutions to your problem.  Using dictionaries will speed things along.



> { 'sh.forte A_0' : 27.500 , 'sh.forte C_1' : 32.703 , 'sh.forte D#1' :
> 38.891 , 'sh.forte F#1' : 46.249 , 'sh.forte A_1' : 55.000 , 'sh.forte

[lots of stuff cut]

This looks almost ok, but may work better if the frequencies are keys, and
the samples are values.  So, it might be something like:

    { 27.500 : 'sh.forte A_0',
      32.703 : 'sh.forte C_1', ... }

Otherwise, you'll lose the advantages of the dictionary --- dictionaries
make it very easy to find a value if we know the key.  However, going the
other way around is a bit expensive.

Good luck!