Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lengthen bars unless nested/threaded #2857

Merged
merged 3 commits into from
Dec 3, 2019

Conversation

casperdcl
Copy link
Contributor

@casperdcl casperdcl commented Nov 26, 2019

issue:
asciicast
asciicast
fix:
asciicast

@casperdcl casperdcl added enhancement Enhances DVC c1-quick-fix ui user interface / interaction discussion requires active participation to reach a conclusion labels Nov 26, 2019
@casperdcl casperdcl self-assigned this Nov 26, 2019
@casperdcl casperdcl requested a review from efiop November 26, 2019 21:37
Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me 🙂

Copy link
Contributor

@Suor Suor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They should be long for nested and threaded bars too.

@casperdcl
Copy link
Contributor Author

They should be long for nested and threaded bars too.

@Suor
Copy link
Contributor

Suor commented Nov 27, 2019

Combining threaded actions into one would be even better for sure. This will be really big. Will make uploading and downloading dirs predictable.

But what's the point aligning nested bars? These perform independent actions and don't need to be aligned.

@casperdcl
Copy link
Contributor Author

casperdcl commented Nov 27, 2019

8 threads downloading independent files with progress bars on top of each other imho look bad when unaligned

 90%|█████████ |fffffffffffffffffffffffffffffffffffffffffffffffff   9/10 [00:00<00:00, 47904.49it/s]
 30%|███       |fffffffffffffffffffffffffffffffff                   3/10 [00:00<00:00, 12722.86it/s]
 70%|███████   |fffffffffffffffffffffffffffffff                     7/10 [00:00<00:00, 32768.00it/s]
 60%|██████    |ffffffffffffffffffffffffffffffffffffffffffffffffff  6/10 [00:00<00:00, 33644.15it/s]
 70%|███████   |fffffffffffffffffffffffffffff                       7/10 [00:00<00:00, 36024.70it/s]
 60%|██████    |fffffffffffffffffffffff                             6/10 [00:00<00:00, 45019.36it/s]
 70%|███████   |ffffffffffffffff                                    7/10 [00:00<00:00, 56245.46it/s]
 70%|███████   |ffffffffffffffffffffffffffffffffffffffffffffffffff  7/10 [00:00<00:00, 49427.82it/s]

looks better than

 90%|██████████▊ |fffffffffffffffffffffffffffffffffffffffffffffffff 9/10 [00:00<00:00, 32824.99it/s]
 30%|████████▍                   |fffffffffffffffffffffffffffffffff 3/10 [00:00<00:00, 11618.57it/s]
 70%|█████████████████████         |fffffffffffffffffffffffffffffff 7/10 [00:00<00:00, 26450.57it/s]
 60%|██████▌    |ffffffffffffffffffffffffffffffffffffffffffffffffff 6/10 [00:00<00:00, 27443.65it/s]
 70%|██████████████████████▍         |fffffffffffffffffffffffffffff 7/10 [00:00<00:00, 33063.21it/s]
 60%|██████████████████████▊               |fffffffffffffffffffffff 6/10 [00:00<00:00, 31655.12it/s]
 70%|███████████████████████████████▍             |ffffffffffffffff 7/10 [00:00<00:00, 68120.95it/s]
 70%|███████▋   |ffffffffffffffffffffffffffffffffffffffffffffffffff 7/10 [00:00<00:00, 50884.10it/s]
from random import randint, seed
from dvc.progress import Tqdm

seed(1337)
bars = []
fmt = (
    "{percentage:3.0f}%|{bar}|"
    "{desc} {n_fmt}/{total_fmt}"
    " [{elapsed}<{remaining}, {rate_fmt:>11}{postfix}]"
)
#fmt = None
for i in range(8):
    filename = "f" * randint(10, 50)
    bars.append(Tqdm(desc=filename, total=10, leave=True, ncols=100, bar_format=fmt))
    bars[-1].update(randint(1, 9))
    bars[-1].refresh()

input()

@efiop
Copy link
Member

efiop commented Nov 27, 2019

@casperdcl I think @Suor is bring up a good point. We've also discussed not using 1 progress bars for each file we are downloading, but instead using 1 progress bar for all of them, right?

@casperdcl
Copy link
Contributor Author

yes but that's a next step. for now (with the top-level bar for file count and then nested bars for bytes) I feel the nested ones should be aligned.

@efiop
Copy link
Member

efiop commented Nov 27, 2019

@casperdcl E.g. showing the amount of data being downloaded instead of showing individual files.

@efiop
Copy link
Member

efiop commented Nov 27, 2019

@casperdcl But we are going to remove those, why try to align them?

@casperdcl
Copy link
Contributor Author

Well they were already aligned, I'm just leaving them that way. This PR removes the 10-bar width on all top-level bars only. Making the nested bars look bad with the explanation that "we will one day soon remove them" doesn't sound like something which would make users happy. Would make devs happy. Would make my life easier. But not users.

@efiop
Copy link
Member

efiop commented Nov 27, 2019

@casperdcl Thanks for clarifying! Looks like we won't get rid of all nested progress bars anyway, so this PR will still be useful later when we optimize most of the stuff. 👍

Copy link
Member

@efiop efiop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 🙏

@Suor
Copy link
Contributor

Suor commented Nov 27, 2019

Waiting for bars to be combined is ok.

What are other situations we have several pbars? Like add several things and calc checksums maybe. This looks ugly now anyway - misaligned and labels on different sides.

@casperdcl
Copy link
Contributor Author

casperdcl commented Nov 27, 2019

This looks ugly now anyway - misaligned and labels on different sides.

Yes @Suor I agree. I'm still not happy about it either (even tried with 78c9e32) but couldn't come up with a nice solution.

  • If we care about alignment for nested bars then {percentage:3.0f}%|{bar:10}| have to appear together because they're fixed-width; but for the top-level bar {percentage:3.0f}% {desc}|{bar}| makes more sense to keep the all-important description near where the user would look for it
  • Since the nested bars always get cleared away it's not too bad that they're formatted differently from the top-level bar

@Suor
Copy link
Contributor

Suor commented Nov 27, 2019

One solution is to dynamically align them. You get the shortest pbar and redraw all the earlier ones to fit it, then go from where.

a non-related thing, we obviously need to cap it, because text might be however long. Can we just cap it so that we don't get 10 char pbars at all? Or maybe we can set that minimum pbar dependent on overall width, like max(10, width * 0.5),

@casperdcl
Copy link
Contributor Author

we obviously need to cap it, because text might be however long. Can we just cap it so that we don't get 10 char pbars at all?

not sure I follow. Right now I cap the desc text to make sure the whole thing doesn't flow over the terminal width.

@Suor
Copy link
Contributor

Suor commented Nov 27, 2019

@casperdcl the formula might be more complex:

  • we have some fixed stuff, like percent, borders, some spaces
  • numbers, that are log(total) * 2 + 1 + spaces
  • label
  • bar

We may distribute the rest of the width between text and bar however we like, e.g.:

free_width = width - fixed_stuff - numbers 
# If free_width < 0 then we can't do much, 
# let's suppose we always have free_width >= 30
# then we can use:
text_width = max(20, free_width * 0.3)
pbar_width = free_width - text_width  # pbar is 10+, but generally 70% of free space.

We can even have separate formula for damage control, e.g free_width < 30:

if free_width <= 15:  # the very low limit for text
    text_width = free_width
    pbar_width = 0   # hide pbar, rely on %
elif free_width < 30:
    text_width = ...
    ...
else:
    # normal scenario

@casperdcl
Copy link
Contributor Author

@Suor I'm not sure it's wise to share space between {bar} and {desc}.

Surely {desc} is always far more important, while {bar} is the least important thing on the screen.

I'd prefer

# truncate bar down to 10 min
bar_width = max(10, free_width - desc_width)
# truncate desc down to 0 min
desc_width = max(0, free_width - bar_width)
# truncate bar down to 0 min
bar_width = max(0, free_width - desc_width)

@Suor
Copy link
Contributor

Suor commented Nov 29, 2019

Surely {desc} is always far more important, while {bar} is the least important thing on the screen.

I disagree. After say 40-50 chars desc is not that helpful. And bar is very important, it makes waiting less annoying. The very point of progress bar is bar, we don't call it progress description after all.

@casperdcl
Copy link
Contributor Author

casperdcl commented Nov 29, 2019

Hmm I think we need more opinions on this one and then go with the majority... @efiop @shcheklein @MrOutis? Also regarding truncating {desc} - best to strip the front (removing prefix of long paths, more fine grained filename path info displayed) or back (removing files from long paths, less flickering for large directories)?

@shcheklein
Copy link
Member

Agreed with @casperdcl on this (though would love to see a GIF with it). It went into matter of personal preferences it looks like. I think the most important part is to show that something is happening + explain what exactly is happening. There a lot of ways to do the first part, and I'm not very opinionated unless it looks really bad. For example, I've shared recently https://asciinema.org/a/rUwhTMR06Rz7MIFEeFxFsjrHd which does not use classical progress bar at the last stage (multithreaded) at all.

So, I'm fine with a (reasonable) number of progress bars and even if we sacrifice some width for now. Especially considering that we are going to think how to make one shared bar or something else as the next step, right?

@efiop
Copy link
Member

efiop commented Nov 30, 2019

I agree with @casperdcl and @shcheklein 🙂

@Suor
Copy link
Contributor

Suor commented Nov 30, 2019

Combining threads into single bar is more important I agree on that.

On bar and text, having 140 chars in a screen and only 10 chars for bar doesn't make sense to me at all.

@efiop
Copy link
Member

efiop commented Nov 30, 2019

@Suor We have percentage, data and time counts, so having a high def progress bar is not vital there.

@Suor
Copy link
Contributor

Suor commented Nov 30, 2019

@efiop This is not about vital, it's about ugly. If we can't make it > 10 chars then let's remove it.

@Suor
Copy link
Contributor

Suor commented Nov 30, 2019

Then again, if we solve threading - by combining them into single pbar - then we should simply use default non-fixed tqdm pbars after that. Do you guys agree with that?

@efiop
Copy link
Member

efiop commented Nov 30, 2019

@efiop This is not about vital, it's about ugly. If we can't make it > 10 chars then let's remove it.

Yeah, functionally it becomes pretty close to a spinner :) Though, small pbar is still more visually pleasant 🙂

Then again, if we solve threading - by combining them into single pbar - then we should simply use default non-fixed tqdm pbars after that. Do you guys agree with that?

I am not sure we will get rid of all pbars in favor of one, that is why this might still be useful later. But this optimization indeed feels a bit premature, even though it improves the look, but it is definitely not a game-changer. Maybe we could wait with it until we are done with combining progress bars and stuff.

@Suor
Copy link
Contributor

Suor commented Nov 30, 2019

I am not sure we will get rid of all pbars in favor of one, that is why this might still be useful later. But this optimization indeed feels a bit premature, even though it improves the look, but it is definitely not a game-changer. Maybe we could wait with it until we are done with combining progress bars and stuff.

After that those will be some nested or unrelated pbars, which I think should not be aligned. Anyway, we may postpone this decision until after that.

The one option is still to dynamically align them, just mentioning it to not get it lost.

@casperdcl
Copy link
Contributor Author

casperdcl commented Nov 30, 2019

@Suor I don't see this PR as a final solution, it's just a patch for now that I think is better in all ways than the current version. I'm hesitant to try to fix the remaining issues until we see about combining bars later; as @efiop says it seems premature.

I also don't see a bar of width 10 on a 300 character screen as ugly in the same way as people who have wide screens get used to 80 char code line lengths. I actually like the "simple important info" on the left and then the "advanced stats" on the right.

For future maybe as you say a more fine grained approach is needed. In which case I'd suggest maybe:

if wide_screen:
  # truncate or pad to ensure desc is exactly 50
  desc = "%50s" % (desc[:50])
  # rest is bar (which will be the same fixed length for all bars)
  bar_width = free_space - 50
elif narrow_screen:
  bar_width = 0
  desc_width = max(0, free_width)
else:
  # truncate bar down to 10 min
  bar_width = max(10, free_width - desc_width)
  # truncate desc down to 0 min
  desc_width = max(0, free_width - bar_width)
  # truncate bar down to 0 min
  bar_width = max(0, free_width - desc_width)

But I feel that should be debated and implemented in a different PR - especially if we opt for an alternative as major as dynamic alignment.

@efiop
Copy link
Member

efiop commented Nov 30, 2019

Btw, why are we only changing the proportions of the nested bars? Seems a bit odd looking to have some bars aligned and some not.

@efiop
Copy link
Member

efiop commented Nov 30, 2019

Btw, talking about conda: (the image is taken from the google search, sorry)
image
It seems to have fixed-length progress part, which is nice, though might be too long for our application, as we don't have the luxury of short text like in package names, where it is short and sweet and you can easilly cut-off version numbers from the end.

@casperdcl
Copy link
Contributor Author

casperdcl commented Nov 30, 2019

@efiop now they have https://github.com/conda/conda/blob/89ff48c2d20dad390ff9fa46b8e20aaff0d53d72/conda/common/io.py#L465:

bar_format = "{desc}{bar} | {percentage:3.0f}% "

producing:

Downloading and Extracting Packages
certifi-2019.11.28   | 149 KB    | ##################################### | 100% 
pygments-2.5.2       | 669 KB    | ##################################### | 100% 
ca-certificates-2019 | 145 KB    | ##################################### | 100% 
pyrsistent-0.15.6    | 87 KB     | ##################################### | 100% 
yarn-1.19.2          | 1020 KB   | ##################################### | 100% 
importlib_metadata-1 | 39 KB     | ##################################### | 100% 
setuptools-42.0.1    | 648 KB    | ##################################### | 100% 
libstdcxx-ng-9.2.0   | 4.5 MB    | ##################################### | 100% 
pyyaml-5.1.2         | 172 KB    | ##################################### | 100% 
argcomplete-1.10.3   | 32 KB     | ##################################### | 100% 
ruamel_yaml-0.15.80  | 251 KB    | ##################################### | 100% 
libgcc-ng-9.2.0      | 8.6 MB    | ##################################### | 100% 
yaml-0.2.2           | 64 KB     | ##################################### | 100% 
Preparing transaction: done
Verifying transaction: done
Executing transaction: done

I guess they pre-compute the size in the {desc} part to ensure a certain width (still think they could use {total_fmt:7} or similar instead).

Elsewhere they use the default format.

@efiop
Copy link
Member

efiop commented Dec 1, 2019

@casperdcl Got it. @Suor I suggest we move on with this implementation and merge this PR, see how we feel about it and how it looks in further UI improvements. I think it looks nice enough to give it a try and the potential harm is very minor, so I don't see a point in fighting over it here. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion requires active participation to reach a conclusion enhancement Enhances DVC ui user interface / interaction
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ui: very short progress bar
4 participants