[Tutor] First Serious Num-Python Prog.

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Sun, 29 Sep 2002 15:37:07 -0700 (PDT)


On Wed, 25 Sep 2002, Karthikesh Raju wrote:

> The following is my first serious python program. This does LS based
> estimation. i havent commented it but i was filled with enthu that i
> wanted to get the comments of people on how better i could do and the
> means and methods to imporve this. (Please leave the comments and the
> synthetic ones).

Hi Karthikesh,

Have you gotten any responses yet?  If not, this is probably because many
of us haven't had extensive experience with Numeric; you may get a better
response by posting on a forum that focuses on Numeric issues.


>From a straightforward programming standpoint, I'll try to offer some
suggestions.  Let's take a look at some of your code:


######
# generate the signal

i = indices = arange(1,162)
x = -8 + (i-1)/10.0

a0 = 0
a1 = -100
a2 = 0
a3 = 1

z = a0 + a1*x + a2*x**2 + a3*x**3
######

I'm not sure what all these variables are, but I'll assume that 'z' is the
ultimate result that we want out of these statements.  If so, perhaps we
can wrap these statements into a single function called
"generate_signal()":


###
def generate_signal():
    i = indices = arange(1,162)
    x = -8 + (i-1)/10.0
    a0 = 0
    a1 = -100
    a2 = 0
    a3 = 1
    z = a0 + a1*x + a2*x**2 + a3*x**3
    return z
###

This adds no additional functionality, but does emphasize the fact that
'i', 'x', 'a0', 'a1', 'a2', and 'a3' are just temporary "scratchpaper"
local variables that are being used to build up 'z'.  This same kind of
function wrapping can be applied to other chunks of your code.

It's not quite clear what the significance of "162" holds in this code.
Can you explain what it means?



Let's take a look at a few more chunks of code:

######
# generate Nosie

Sigma = sqrt(10)
v = normal(0,Sigma,161)

# generate Noisy Signal
y = z + v

# generate signal with outliers
replace = randint(1,161,17)

for ind in range(17):
    y[replace[ind]] = random()*400
######


If I understand this code correctly, I think we can apply a similar
function factorization to those three chunks:

###
def generate_noise():
    """Creates a new noisy signal."""
    Sigma = sqrt(10)
    v = normal(0,Sigma,161)
    return v


def generate_noisy_signal(signal):
    """Given a signal, returns a new signal with noise."""
    return signal + generate_noise()


def add_outliers(signal):
    """Modifies a preexisting signal with outliers."""
    replace = randint(1,161,17)
    for ind in range(17):
        signal[replace[ind]] = random()*400
###


Whenever you feel the need to put a comment for a block of code, that's a
prime target for this function treatment.  *grin*



With these changes, your main code will look like this:

###
z = generate_signal()
z = generate_noisy_signal(z)
add_outliers(z)
###

And in this version, the overall motion of the the program is easier to
see --- it doesn't get lost within the particular details of generating
noise or outliers.  We use functions to wrap the details of events: in a
sense, we're turning multiple, disconnected statements into compound
verbs.


I hope this helps!