rsalmei / alive-progress

A new kind of Progress Bar, with real-time throughput, ETA, and very cool animations!
MIT License
5.53k stars 206 forks source link

method to set progress to a percentage #4

Closed jonturneratduke closed 5 years ago

jonturneratduke commented 5 years ago

It would be very useful to be able to set the progress of the bar to some percentage, rather than needing to call the update method (alive_bar()) X number of times which is based on the initialization value. Similarly, if the update method is not called the same # of times, when the progressbar is released, it indicates a warning. This causes difficulty for instances where the progress duration may not be known beforehand (such as uploading a large file), and callbacks are inconsistent. What if we could pass in a float (percentage completion)? bar(50.25) or even bar(100.00) Rather than display a progress message, it would set the bar to that % completion. Alternatively, a way to declare "successful completion" which would set the bar to 100% without error/warning indicators would be helpful.

rsalmei commented 5 years ago

Hello @jonturneratduke! Yeah, I can do that, shouldn't be a problem to set a percentage, since internally I calculate one.

Only the bar() call gets the first positional argument as the message text. So I could do one of:

  1. add a keyword argument to the bar() call;
  2. add a sub-method to bar, like bar.set(50.25) for this use-case.

I'm tending to the second one, what do you think?

rsalmei commented 5 years ago

Actually, it's not that easy. I also display in the alive-bar the observed throughput, it does not make much sense to know it's processing 18% per second. What does that represent? One needs to know how much actual elements or transactions or bytes are being processed per second.

If the total is adequately declared, I think I could calculate that actual number too, but the two modes could not be mixed, which would need validations and so a little overhead.

jonturneratduke commented 5 years ago

Understood. I don't want to break (or clutter) your usage model -- you have a nice clean (and refreshingly simple!) interface for a priori well-bounded tasks, and I have a what may be an edge case.

rsalmei commented 5 years ago

Hey @jonturneratduke I'm still thinking about how to implement this, let's keep it open for a while. I think, regardless of the overhead, it might be a good addition of functionality.

rsalmei commented 5 years ago

Hello again @jonturneratduke, great news! I've finally found a solution for this, after studying it for this whole week!

I had to refactor almost all of the main code! 😅 But I think I came up with a very neat implementation, it is almost ready in #6.

I only need to write the instructions in readme, bump version and release it!

jonturneratduke commented 5 years ago

That's great! Sorry for the extra work I've created for you, but it's exciting to hear you've found a solution. Looking forward to what you've cooked up. :)

rsalmei commented 5 years ago

No problem at all, you're welcome. It's released! Version 1.1.0

Please give a look at the new readme and try it, let me know what you think!

jonturneratduke commented 5 years ago

Nicely done! It's very useful now, even if the progress intervals are inconsistent as in my use case -- getting callbacks from some remote service (Azure blob storage, or Amazon AWS S3, etc.).

There's a little bit of weirdness in calculating progress %, but overall that's exactly what I was hoping for.

Here's a simple sample to count the progress from 0 to 100%.

    with alive_bar(100, manual=True) as bar:   # 100% = finished
        total = 0
        while total != 100:
            total += 1
            time.sleep(0.02)
            bar(total)
        return

Assuming I'm calling it correctly, I expected to see 100/100 [100%] but instead I see this output like so: |████████████████████████████████████████✗ (!) 10000/100 [10000%] in 2.3s (4308.81/s) It seems like it's multiplying the progress ( numerator ) by 100.

edit: yep, that's it. This works as expected:

        total = 0.0
        while total < 1.00:
            total += .01
            time.sleep(0.02)
            bar(total)
        bar(1.00)
        return

|████████████████████████████████████████| 100/100 [100%] in 2.3s (43.30/s) So I think just one bug in the progress % calculation and it'll be ready. Thank you again for having a look at this.

rogerio-geru commented 5 years ago

Thank you @jonturneratduke ! Glad you liked!

Actually, you do not need to simulate the percentage, I already did it internally! Did you happen to read the new readme? It's in https://github.com/rsalmei/alive-progress#alive-bar-modes, if not I invite you to take a look :wink: Please, try without declaring the total, I'm gonna calculate for you both the throughput and the ETA! Let me know the result :+1:

jonturneratduke commented 5 years ago

Yes, it works perfectly if I just read & follow the instructions. 😃 ETA and throughput are super! Some of our processes may take 5 minutes or more so that really helps set user expectations. Plus, no more crashes if I try to print() while the status bar is active. I suspect there was a lot of work internally to make all this possible, but you've implemented it in a really tidy way that hides all that complexity.