[Tutor] Calculating a math formula and finding errors

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Mon Jan 13 06:23:03 2003


On Mon, 13 Jan 2003, Jens Kubieziel wrote:

> I have to think about the factorial function. Because it seems that the
> recursion doesn't work with the correction in MBleft.

Hi Jens,

Let us take a look at factorial() for another moment:

> def factorial(z):
>   if z == 1 or z == 0:
>     return 1
>   else:
>     return z*factorial(z-1)

This has the potential of looping forever if we ever give invalid input
into factorial.  For example: what happens if we feed a negative number as
'z'?


This is not to say that factorial() is "broken", only that we have to be
careful to give it nonnegative numbers for input.  If we want to be
careful, we should add an assertion check to make sure that the system
will catch this invalid input as soon as possible.

###
def factorial(z):
    assert z >= 0, "Invalid input: z must be nonnegative."
    if z == 1 or z == 0:
        return 1
    else:
        return z*factorial(z-1)
###

Invalid input to factorial() is probably where we are going astray.  The
definition of binomial():

> def binomial(x,y):
>   w = 1
>   for i in range(y+1,x+1):
>       w = w * i
>   return w/factorial(x-y)


will give factorial() a negative input if 'x < y'.  But binomial() should
instead return 0 instead from a combinatorial interpretation.

###
def binomial(x,y):
    if x < y:
        return 0
    w = 1
    for i in range(y+1,x+1):
        w = w * i
    return w/factorial(x-y)
###

I believe these two corrections should help trap the infinite loop bugs in
the code, so that you can concentrate on the correctness of your code more
easily.


Have you revised the printed equation on the PDF page, or do you have a
revised version of the LaTeX source?  I am curious, and would like to
double check to see if everything else is ok between the mathematics and
the Python program.


Best of wishes to you!