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

Counter prettyprinter should sort entries by count #48

Open
anntzer opened this issue Mar 19, 2019 · 1 comment
Open

Counter prettyprinter should sort entries by count #48

anntzer opened this issue Mar 19, 2019 · 1 comment

Comments

@anntzer
Copy link
Contributor

anntzer commented Mar 19, 2019

  • PrettyPrinter version: 0.17.0
  • Python version: 3.7
  • Operating System: linux

Description

PrettyPrinter does not sort Counter()s entries by count, unlike Counter.__str__ which explicitly does so.

What I Did

In [1]: prettyprinter.pformat(collections.Counter({"a": 1, "b": 200}))
Out[1]: "collections.Counter({'a': 1, 'b': 200})"

In [2]: str(collections.Counter({"a": 1, "b": 200}))                                                                
Out[2]: "Counter({'b': 200, 'a': 1})"

I think the sorted form is clearly more useful (well, at least, it matches the intent of whoever wrote the stdlib's Counter.__str__).

On Py3.6+ I think it's just a matter of

diff --git i/prettyprinter/pretty_stdlib.py w/prettyprinter/pretty_stdlib.py
index 273ee0e..9c66171 100644
--- i/prettyprinter/pretty_stdlib.py
+++ w/prettyprinter/pretty_stdlib.py
@@ -296,7 +296,7 @@ def pretty_ordereddict(d, ctx):
 
 @register_pretty(Counter)
 def pretty_counter(counter, ctx):
-    return pretty_call_alt(ctx, type(counter), args=(dict(counter), ))
+    return pretty_call_alt(ctx, type(counter), args=(dict(counter.most_common()), ))
 
 
 @register_pretty('enum.Enum')

(well the stdlib's version has additionally some handling when most_common() fails due to unorderable values, but you get the idea) but I'm not sure how to make this work on Py3.5.

@tommikaikkonen
Copy link
Owner

tommikaikkonen commented Mar 26, 2019

I think this sounds good. I believe we'll need to extract logic from pretty_dict to a utility function that takes an iterable of key-value pairs instead of a dict, called something like pretty_dict_from_pairs so that we can use that function both here and in the implementation of pretty_dict. This will ensure Python 3.5 can correctly render the output in the most common order. Then the actual pretty printer for Counter can be implemented as

build_fncall(
    ctx,
    type(counter),
    argdocs=(
        pretty_dict_from_pairs(ctx, counter.most_common()),
    ),
    hug_sole_arg=True
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants