6
\$\begingroup\$

I'm currently learning Python for a masters and am trying to improve the best I can, as I'll need to know how to code in my future career.

I currently have a function that builds a table from a dictionary, no matter how long the characters of either the keys or values are.

However, I'm trying to get better and I'm sure there's a more "Pythonic" way to write this (i.e. a more simple way). This is just what I was able to come to with my limited knowledge.

def salaryTable(itemsDict):
    
    lengthRight=max( [ len(k) for k,v in itemsDict.items() ] )
    lengthLeft=max( [ len(str(v)) for k,v in itemsDict.items() ] )
    
    print( "Major".ljust(lengthRight+7) + "Salary".rjust(lengthLeft+7) )
    print( '-' * (lengthRight+lengthLeft+14) )
    
    for k,v in itemsDict.items():
        print( k.ljust(lengthRight+7,'.') + str(v).rjust(lengthLeft+7) )

And here's the two dictionaries I used to test both left and right:

# what it produces when keys or values in the dictionary are longer than the parameter's # leftWidth and rightWidth

majors={'English Composition':45000,
        'Mechanical Engineering with a concentration in Maritime Mechanics':75000,
        'Applied Math with a concentration in Computer Science':80000}



# testing on a dictionary with a long value

majors2={'English Composition':45000,
        'Mechanical Engineering':75000,
        'Applied Math':"$100,000 thousand dollars per year USD"}
```
\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

Identifiers

PEP8 recommends using snake_case for variables and functions, not camelCase.

It should be salary_table, length_right and items_dict. Besides, do you really need _dict in items_dict?

Are you sure lengthLeft and lengthRight are proper names?

It looks strange that lengthRight is the width of the left column; maybe it has something with the content of the column, but width_left looks better to me.

Max works with any iterator, not only list

width_left = max( len(k) for k,v in items_dict.items() )

works as well, and doesn't create a list.

You can iterate over keys of dict without items()

width_left = max( len(k) for k in items_dict )

You can go further and use max(map(len, itemsDict)), but this is pythonic enough for me.

If the variable is not used, point this out with _

width_right = max( len(str(v)) for _, v in items_dict.items() )

But it is better to

Use .values(), if you don't need keys

width_right = max( len(str(v)) for v in items_dict.values() )

Avoid "magic numbers" (constants without explanation)

Both lengths are added with 7; maybe it is better to add it at once and name it?

MINIMAL_WIDTH = 7
width_left = max( len(k) for k in items_dict ) + MINIMAL_WIDTH
width_right = max( len(str(v)) for v in items_dict.values() ) + MINIMAL_WIDTH

F-strings are usually more readable

print(f"{k:.<{length_right}}{v:>{length_right}}")

All together

def salary_table(items):
    MINIMAL_WIDTH = 7
    width_left  = MINIMAL_WIDTH + max( len(k) for k in items )
    width_right = MINIMAL_WIDTH + max( len(str(v)) for v in items.values() )

    print( f"{'Major':<{width_left}}{'Salary':>{width_right}}" )
    print( '-' * (width_left + width_right) )

    for k, v in items.items():
        print( f"{k:.<{width_left}}{v:>{width_right}}" )

I don't know anything about the nature of keys and values; according to values given it can be better to rename k and v into name and price, and items into books.

Alternatives

Pay attention to tabulate. Maybe you better use it instead of inventing the wheel? There are also PrettyTable and texttable.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ You could make MINIMAL_WIDTH a defaulted kwarg of salary_table(). \$\endgroup\$ Jul 16, 2021 at 14:28
  • \$\begingroup\$ Yes. Also the dot - it could be optionated, right? And the max width. And justification. I've thought about it - and the best choice would be to take one of the libraries in the Alternatives section. \$\endgroup\$ Jul 16, 2021 at 16:11
  • \$\begingroup\$ Thank you so much! Especially for taking the time to explain each step and directing me to those useful cites. I'm assuming there are pretty useful codes/mods (whatever you call them) there and that's why I can just search there and not have to "inventing the wheel"? \$\endgroup\$ Jul 16, 2021 at 19:25
  • \$\begingroup\$ This was so helpful because I learned how these little improvements can help in a big, besides I'm trying to become a good programmer myself so knowing these things are important. \$\endgroup\$ Jul 16, 2021 at 19:27
  • \$\begingroup\$ Steve McConnel's "Code Complete" is still the best. Also Robert Martin's "Clean Code". \$\endgroup\$ Jul 17, 2021 at 5:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.