0

I have made a python program to calculate e and it worked up until a while ago but now all of the sudden it doesn't work anymore and is behaving very oddly. Here is the source code:

from decimal import *
import time
dig = int(input('Enter number of digits: '))
getcontext().prec = dig +5
def factorial(n):
    num = Decimal(1)
    while Decimal(n) >= Decimal(1):
        num = Decimal(num)*Decimal(n)
        n = Decimal(n)-Decimal(1)
    return Decimal(num)
def calce(n):
    def calce(n):
        e = 0
        for i in range(0, n+1):
            e = e + Decimal((Decimal(2)*Decimal(i)+Decimal(2)))/Decimal(factorial(Decimal(2)*Decimal(i)+1))
        return Decimal(e)
n = int(input('How many iterations for e?: '))
t0= time.clock()
numb = str(calce(n))
numb = numb[:-4]
f = open("edigits.txt", 'w')
f.write(str(dig))
f.write(" digits.")
f.write("\n")
f.write(str(n))
f.write("!\n\n")
f.write(numb)
t= str(time.clock() - t0)
f.seek(0, 0)
f.write(t)
f.write(" seconds.\n\n")
f.close()

It even works when I don't write it to a file but when I do this it only gives the time elapsed and doesn't give anything else and sometimes it might give this random number too but that is it... Any help?

Paul
  • 26,170
  • 12
  • 85
  • 119
  • 4
    What does "doesn't work" mean, or "behaving oddly"? Also, surely you can reduce this to a [minimal example](http://stackoverflow.com/help/mcve); unless all that code at the end for formatting the results and timing how long the write takes and so on is relevant to your problem, it shouldn't be in your question. – abarnert Oct 27 '14 at 20:43
  • 3
    If it was working before and now it isn't, what did you change, either in the code or on the machine where it is running? Are you using a version control system of some sort? If not, now you know one more reason why people recommend using them -- when something goes wrong, you can go back to a previous version that worked. – Jonathan Leffler Oct 27 '14 at 20:43
  • Does it work if you just print your e to standard output? – Linuxios Oct 27 '14 at 20:45
  • [root@matthewharris cpanel]# python thing.py Enter number of digits: 5 How many iterations for e?: 10 [root@matthewharris cpanel]# cat edigits.txt 0.0 seconds. – morissette Oct 27 '14 at 20:45
  • 2
    For one thing, your `cacle` function defines a local function named `calce` and does nothing else (including calling or returning that local function), so it can't be doing anything useful. So `numb = str(calce(n))` is guaranteed to just give you the string `'None'`. – abarnert Oct 27 '14 at 20:45
  • 1
    Also not clear why `f.seek(0, 0)` would be needed, since that's guaranteed to overwrite what's already been written to that file... – khampson Oct 27 '14 at 20:48
  • 4
    For the love of God don't experiment around with buggy code using the root account on your server! – Burhan Khalid Oct 27 '14 at 20:50

2 Answers2

2

The problem is here:

def calce(n):
    def calce(n):
        e = 0
        for i in range(0, n+1):
            e = e + Decimal((Decimal(2)*Decimal(i)+Decimal(2)))/Decimal(factorial(Decimal(2)*Decimal(i)+1))
        return Decimal(e)

Your calce function defines a local function, also named calce, does nothing with it, does nothing else, and just falls off the end, returning None. So, when you run your program, numb ends up always being the string 'None' and nothing else happens.

If you fix this, whether by removing the extra def line, or by calling the local function (like return calce(n) after the local definition), you get reasonable results (e.g., 2.71828 when given 5 and 10 as inputs), so I'm pretty sure this is your problem.

However, the f.seek(0, 0) does mean that you overwrite the start of your output with the timing information, which you almost certainly didn't want.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • Thanks I should've saw that –  Oct 27 '14 at 20:52
  • how would I move to the beginning of the file without overwriting? –  Oct 27 '14 at 20:59
  • 1
    @caleb64804 why do you want to move to the beginning of the file? If you do and then write something, you'll overwrite whatever is there. It's that simple. – MattDMo Oct 27 '14 at 21:04
2
def calce(n):
    def calce(n):
        e = 0
        for i in range(0, n+1):
            e = e + Decimal((Decimal(2)*Decimal(i)+Decimal(2)))/Decimal(factorial(Decimal(2)*Decimal(i)+1))
        return Decimal(e)

the definition of calce(n) returns None because you have defined an inner function with the same name. the outer calce(n) returns None by default and the statement numb = numb[:-4] strips off all the values ('None') of num

remove the inner function and define calce(n) as

def calce(n):
            e = 0
            for i in range(0, n+1):
                e = e + Decimal((Decimal(2)*Decimal(i)+Decimal(2)))/Decimal(factorial(Decimal(2)*Decimal(i)+1))
            return Decimal(e)

it will work.

srj
  • 9,591
  • 2
  • 23
  • 27