1
\$\begingroup\$

I have created a python program that prints a vertical bar graph made from fields and values inputted by the user. It works by first creating a horizontal bar graph and then going through each layer and determining whether to print a letter, a "|", a "_", or a space. I would appreciate any feedback on the program and things I could do to improve it.

import re

feilds = input("Input| ex: dogs,10 cats,23 birds,67\n").strip()
while not re.match("^(\w+,\d+ ?)+$", feilds):
  feilds = input("invalid input, use this format:\nfeild,value feild,value feild,value...\n").strip()
width = int(input("How wide is your output window in characters? "))
scale = float(input("Scale: "))
vals = dict([feild.split(",") for feild in feilds.split(" ")])
for k, v in vals.items():
  vals[k] = int(v)
spacing = int(width / len(vals.keys()))
horizontal = ["-" * int(v * scale) + "|" + k[::-1] for k, v in vals.items()]
vertical = []
for x in reversed(range(len(max(horizontal, key=len)))):
  layer = []
  for val in horizontal:
    try:
      if val[x] == "-":
        layer.append("|")
      elif val[x] == "|":
        layer.append("_")
      else:
        layer.append(val[x])
    except IndexError:
      layer.append(" ")
  vertical.append(layer)
print("\n")
print("\n".join((" " * (spacing - 1)).join(layer) for layer in vertical))

ex:

input:

dogs,20 cats,18 fish,25 birds,10
80
.5

output:

                                        f                    
                                        i                    
d                                       s                    
o                   c                   h                    
g                   a                   _                    
s                   t                   |                    
_                   s                   |                   b
|                   _                   |                   i
|                   |                   |                   r
|                   |                   |                   d
|                   |                   |                   s
|                   |                   |                   _
|                   |                   |                   |
|                   |                   |                   |
|                   |                   |                   |
|                   |                   |                   |
|                   |                   |                   |

NOTE: output might be messed up if the width is off by a lot. Make sure to input a width close to what it is.

\$\endgroup\$
3
\$\begingroup\$

feilds is spelled fields. IDEs like PyCharm will identify spelling mistakes in variables.

Why is there a ? after the space in your regex? Currently I believe it will pass input looking like

key,1key,2key,3

So you have to fix that edge case, probably by adding a final key-value pair with no space, and making the space in the first group mandatory.

This:

vals = dict([feild.split(",") for feild in feilds.split(" ")])
for k, v in vals.items():
    vals[k] = int(v)

should be

vals = {k: int(v)
        for field in fields.split(' ')
        for k, v in field.split(',')}

i.e. don't construct a list in memory only to throw it away.

This:

spacing = int(width / len(vals.keys()))

can be

spacing = width // len(vals)

This:

for x in reversed(range(len(max(horizontal, key=len)))):

doesn't actually need an index at all, since you don't use it. Also, lumping everything into one line is confusing. Instead:

longest_horz = max(len(h) for h in horz)
for v in val[longest_horz-1::-1]:

Then use v instead of val[x].

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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