Search code examples
pythonprogress-bar

Progress bar is not working good in python


I'm trying to make a progress bar when deleting files in python. This python script print the count of the files in a directory and then it will delete them while showing a progress bar. When deleting 10 or 11 files it is working good. But when the file count is larger like 20, It is showing this mess,

Found 20 files.
Deleting[########################################################################################################
.........Deleting[###############################################################################################
##################Deleting[######################################################################################
###########################Deleting[#############################################################################
####################################Deleting[####################################################################
#############################################Deleting[###########################################################
######################################################Deleting[##################################################
#################################################################################################################
###############################################]100.0%

But I want to print it like this,

Found 20 files.
Deleting[####################.............]75%

Here is my code ,

import os
import sys
import time

out = sys.stdout

path_ = input("Enter the path: ")
count_ = 0
files = []
for path in os.listdir(path_):
    if os.path.isfile(os.path.join(path_, path)):
        count_ += 1
        files.append(path)

print(f"Found {count_} files.")
hashes = ""
count = 0
hash = 0
spaces = ".." * 20
for item in files:
    item = path_ + "\\" + item
    os.remove(item)
    count += 1
    per = count/count_ * 100
    for i in range(int(per)):
        hash += 1
        if hash == 10:
            hash = 0
            spaces = ".." * (count_ - count)
            hashes += "##"
    print("{}[{}{}]{}{}".format("Deleting", hashes, spaces, per, "%"), end='\r', file=out, flush=True)
    time.sleep(1)

print("\n")

What am I doing wrong here? please help.


Solution

  • I found something that works for me , hope the comments make it understandable. This solution doesn't use os.system to clear the printed lines so it should work in your IDE.

    Still, I strongly suggest looking into tqdm as it's very easy to use and optimized. for this kind of things.

    Feel free to ask further questions if needed. Don't forget to accept an answer if it solved your issue !

    import os
    import sys
    import time
    
    out = sys.stdout
    
    path_ = input("Enter the path: ")
    count_ = 0
    files = []
    for path in os.listdir(path_):
        if os.path.isfile(os.path.join(path_, path)):
            count_ += 1
            files.append(path)
    
    print(f"Found {count_} files.")
    count = 0
    hash_counter = 0
        #avoid creating a variable named 'hash', as it is a method name.
    spaces = ".." * 20
    for item in files:
        item = path_ + "\\" + item
        os.remove(item)
        count += 1
        per = count/count_ * 100
        is_last_file = (count==count_)
            #this variable checks if the number of deleted files (count) si equal to the total number of files (count_),
            #so it will return True only when we're deleting the last file of the directory.
        for i in range(int(per)):
            hash += 1
            if hash == 10:
                hash = 0
                number_of_hashes = int(round(per/5, 0))
                    #first we calculate the number of hashes ("##") in our progress bar.
                    #we divide the percentage by five because we have a percentage x/100 but we want to display it on a divider of 20 (x/20),
                    #so we divide your percentage by 5 (e.g 40% of 20 = 5 hashes)
                hashes = "##" * number_of_hashes
                spaces = ".." * (20-number_of_hashes)
                    #we calculate easily the number of spaces : it's 20 (the size of our progress bar) minus the number of hashes.
        print(f"{'Deleting' if not is_last_file else 'Deleted'} [{hashes}{spaces}] {per:.1f}%", end=('\r' if not is_last_file else '\n'), file=out, flush=True)
            #using f-strings here is more pythonic ! ;)
            #Also as you can see i used ":.1f" after the percentage. this way we have only one decimal after our float.
        time.sleep(1)
            #you can remove this from your code afterwards.
    
    print("\n")