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.

alecxe
17.5k8 gold badges52 silver badges93 bronze badges
asked Dec 27, 2018 at 18:52
\$\endgroup\$

1 Answer 1

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].

answered Dec 27, 2018 at 19:58
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.