Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to calculate percentage of an iterating operation?

I've written a function that saves all numbers between two digit groups to a text file, with a step option to save some space and time, and I couldn't figure out how to show a percentage value, so I tried this.

for length in range(int(limit_min), int(limit_max) + 1):

    percent_quotient = 0
    j=0
    while j <= (int(length * "9")):
        while len(str(j)) < length:
            j = "0" + str(j)  

        percent_quotient+=1
        j = int(j) + int(step)  # increasing dummy variable

for length in range(int(limit_min), int(limit_max) + 1):
    counter=1
    i = 0
    while i <= (int(length * "9")):
        while len(str(i)) < length:
            i = "0" + str(i)  #

        print "Writing %s to file. Progress: %.2f percent." % (str(i),(float(counter)/percent_quotient)*100)
        a.write(str(i) + "\n")  # this is where everything actually gets written
        i = int(i) + int(step)  # increasing i
        counter+=1
    if length != int(limit_max):
        print "Length %i done. Moving on to length of %i." % (length, length + 1)
    else:
        print "Length %i done." % (length)
a.close()  # closing file stream
print "All done. Closed file stream. New file size: %.2f megabytes." % (os.path.getsize(path) / float((1024 ** 2)))
print "Returning to main..."

What I tried to do here was make the program do an iteration as many times as it would usually do it, but instead of writing to a file, I just made percent_quotient variable count how many times iteration is actually going to be repeated. (I called j dummy variable since it's there only to break the loop; I'm sorry if there is another expression for this.) The second part is the actual work and I put counter variable, and I divide it with percent_quotient and multiply with 100 to get a percentage.

The problem is, when I tried to make a dictionary from length of 1 to length of 8, it actually took a minute to count everything. I imagine it would take much longer if I wanted to make even bigger dictionary.

My question is, is there a better/faster way of doing this?

like image 236
Meaty Avatar asked Oct 20 '22 08:10

Meaty


1 Answers

I can't really work out what this is doing. But it looks like it's doing roughly this:

a = file('d:/whatever.txt', 'wb')
limit_min = 1
limit_max = 5
step = 2

percent_quotient = (10 ** (limit_max - limit_min)) / step

for i in range(limit_min, 10**limit_max, step):
    output = str(i).zfill(limit_max) + '\r\n'
    a.write(output)

    if i % 100 < 2:
        print "Writing %s to file. Progress: %.2f percent." % (str(i),(float(i)/percent_quotient)*100)

a.close()

If that's right, then I suggest:

  • Do less code looping and more math
  • Use string.zfill() instead of while len(str(num)) < length: "0" + str(num)
  • Don't overwhelm the console with output every single number, only print a status update every hundred numbers, or every thousand numbers, or so.
  • Do less str(int(str(int(str(int(str(int(...
  • Avoid "" + blah inside tight loops, if possible, it causes strings to be rebuilt every time and it's particularly slow.
like image 78
TessellatingHeckler Avatar answered Oct 23 '22 09:10

TessellatingHeckler