0

For some reason that I cannot figure out this will only write 11571 characters in the pi.txt file - way short of the 50 thousand there should be I've been looking up buffers to do with the disk IO, and have tried os.fsync(fo) every 10 thousand iterations, but the same thing happens, only 11571 characters actually recorded in the txt file It seems to be generating all 50 thousand chars (it counts up to 50k with the Count status: ) Is this a problem with my code, or disk buffer or something simple I am completely missing. this code was nicked from here: 1000 digits of pi in python

I've tried this solution: Python not writing full string to file

Exactly the same thing, write down to the size of the file

I've also tried calculating longer and shorter values, same issue.

import os
fo=open("pi.txt", "wb")
def make_pi():
    cnt = 1
    q, r, t, k, m, x = 1, 0, 1, 1, 3, 3
    for j in range(50000):
        if 4 * q + r - t < m * t:
            fo.write(str(m))
            yield m
            q, r, t, k, m, x = 10*q, 10*(r-m*t), t, k, (10*(3*q+r))//t - 10*m, x
        else:
            q, r, t, k, m, x = q*k, (2*q+r)*x, t*x, k+1, (q*(7*k+2)+r*x)//(t*x), x+2
        if cnt % 1000 == 0:
            print("Count status: %s" % cnt)
        elif cnt % 10002 == 0:
            fo.flush()
            os.fsync(fo)
        else:
            pass
        cnt+=1
for i in make_pi():
    pass
fo.close()

Also if it makes a difference I am using windows 7 64 bit, I haven't tried this in linux.

This is the fixed code, that is working correctly :)

fo=open("pi.txt", "wb")
def make_pi():
    cnt=0
    q, r, t, k, m, x = 1, 0, 1, 1, 3, 3
    while True:
        if 4 * q + r - t < m * t:
            if cnt % 1000 == 0:
                print("Counted %s places" % cnt)
            else:
                pass
            yield m
            fo.write(str(m))
            cnt+=1
            q, r, t, k, m, x = 10*q, 10*(r-m*t), t, k, (10*(3*q+r))//t - 10*m, x
        else:
            q, r, t, k, m, x = q*k, (2*q+r)*x, t*x, k+1, (q*(7*k+2)+r*x)//(t*x), x+2

i = 0;
for x in make_pi():
    i += 1
    if i == 10001:
        break

fo.close()

Thanks for pointing that out :)

Community
  • 1
  • 1
AB49K
  • 3,275
  • 3
  • 16
  • 15

1 Answers1

3

This is a logical issue and not a buffering/disc syncing one. The function only yields (and writes) if the condition: 4 * q + r - t < m * t is TRUE, which it is only 11571 times in the 50K loops.

Just because.. here's a slightly modified version which should achieve what you're trying to do: generate the first X digits of PI:

fo=open("pi.txt", "wb")

def make_pi(num_digits):
    q, r, t, k, m, x = 1, 0, 1, 1, 3, 3
    j = 0
    while True:
        if 4 * q + r - t < m * t:
            fo.write(str(m))
            yield m
            q, r, t, k, m, x = 10*q, 10*(r-m*t), t, k, (10*(3*q+r))//t - 10*m, x
            j += 1
            if j % 1000 == 0:
                print("Count status: %s" % j)
        else:
            q, r, t, k, m, x = q*k, (2*q+r)*x, t*x, k+1, (q*(7*k+2)+r*x)//(t*x), x+2
        if j >= num_digits:
            break

for i in make_pi(50000):
    pass

fo.close()
smassey
  • 5,875
  • 24
  • 37