I
I
Ivan Suroegin2015-03-31 19:49:34
Python
Ivan Suroegin, 2015-03-31 19:49:34

Proper display of the progressbar in Python - what's wrong?

Good evening!
Tell me, please, I can not understand why the progressbar is displayed incorrectly?
I would like to get it so that the speed of increasing the percentage value and filling the progress bar corresponds to the number of lines in the li list.
I would love your explanations!
Thank you, regards,
Ivan.

import requests
import time
import random
import sys

li = ["25min", "tester", "testsetset"]

status404 = []
status200 = []
lenLi = len(li) + 1
def wait():
    time.sleep(random.randint(2,3))

for x in li:
  
  link = "https://vk.com" + x
  q = requests.get(link)
  stat = q.status_code
  if 200 != stat:
    status404.append(x.rstrip())
    wait()
  else:
    status200.append(x.rstrip())
    wait()
  for i in range(lenLi):
    sys.stdout.write('\r')
    sys.stdout.write("[%-30s] %d%%" % ('='*i, i))
    sys.stdout.flush()

print("404 status")
for i in status404:
  print(i)
print("\n- - - - -\n200 status:")
for i in status200:
        print(i)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Pavel, 2015-03-31
@ivan_suroegin

Let's go in order.
Here is the section of code responsible for the progress bar:

for i in range(lenLi):
    sys.stdout.write('\r')
    sys.stdout.write("[%-30s] %d%%" % ('='*i, i))
    sys.stdout.flush()

First, your console output is wrong. Your progress bar is 30 characters long. This means that at each iteration, you need to display the number of characters corresponding to the iteration, not forgetting that you cannot display a fractional number of characters. For example, if you have a list length of 5, then 30/5=6 characters are added by each iteration of the loop. But you're rewriting the entire progress bar, so you can calculate a "part" of the entire length (30 characters) for this step. For example, for length 5, step 1 is 1/5 of the length, step 2 is 2/5 of the length, and so on. Then the number of characters is the number of characters for the "full" length multiplied by the resulting part.
part = float(i)/(lenLi-1)
symbols_num = int(30 * part)

lenLi -1 , since you increased the length by one above (apparently for range), then range should start from 1, not from zero. And percentages can be easily obtained by multiplying part by 100, remembering to change the output formatting from ' %s%%' to, say, ' %3.2f%% ', since the output is a fractional number and it looks very bad if %s.
Now the progress bar will be displayed correctly:
for i in range(1, lenLi):
    sys.stdout.write('\r')
    part = float(i)/(lenLi-1)
    symbols_num = int(30 * part)
    sys.stdout.write("[%-30s] %3.2f%%" % ('='*symbols_num, part*100))
    sys.stdout.flush()

True, in order to have time to see the changes, add wait () to the loop, otherwise all 100% will be filled in a split second.
Yes, for each link you fill in the progress bar from zero to 100 percent. You don't need a loop within a loop. The progress bar must be part of the for x in li:. But, for the correct display of the progress bar, you need to read the step number. To do this, you can either create a variable that will count the steps, or use the enumerate function :
Considering that it is more convenient for you to number steps from one, it would be more correct to use
In general, if you want to use the progress bar in other places of the code, then it would be worthwhile to create a separate function for printing progress, which takes a fractional number from 0 to 1 or a percentage as an argument and prints the corresponding progress bar to the console, returning the caret to the beginning of the line.
I think these hints are more than enough. Then try it yourself.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question