1

How do I make this graph print vertically rather than horizontally? Please try to use the same concept(loops, lists) I used in my code so I understand the changes. Thank you for your help!

Here is the code:

SIGN='x'
test_list=[500000,5000000,7000000]
test_calc_list=[]
test_sum=sum(test_list)
test_string_list=['Test1','Test2','Test3']
signs_list=[]
for x in test_list:
 test_calc=round((x/float(test_sum)*10))
 test_calc_list.append(test_calc)
for y in test_calc_list:
 y=int(y)
 signs=y*SIGN
 signs_list.append(signs)
for z in range(len(test_string_list)):
 print "%8s: %-6s %7i"% (test_string_list[z],signs_list[z],test_list[z])

This is the output I get:

Test1: 500000
Test2: xxxx 5000000
Test3: xxxxxx 7000000

This is the output I want:

 x
 x x
 x x
 x x
 x x
Test1 Test2 Test3 
500000 5000000 7000000
asked Apr 20, 2013 at 2:19
3
  • 4
    This looks like homework, you will need to go about this in a very different way. start with finding the longest row of x's so you know how many lines you need to loop over, for each line check if their should be an x in the appropriate column if so print it, the bottom two rows I am sure you can manage Commented Apr 20, 2013 at 2:29
  • I agree that this looks like homework. @Drake, can you tell us if this question is homework? We will be happy to guide you in the right direction. Commented Apr 20, 2013 at 2:34
  • @chappy, the homework part was graphing it horizontally. Since I already got that down, I tried to make a vertical graph of the same information. So the question I am asking is not for homework. Commented Apr 20, 2013 at 2:45

1 Answer 1

1

Assuming this isn't homework (you do know that there is software to detect plagiarism?) here are possible solutions.

Easiest is to assume the list is a fixed size:

for i in range(len(max(signs_list)), 0, -1):
 print ('{0:<8} {1:<8} {2}').format(
 'x' if len(signs_list[0]) >= i else '', 
 'x' if len(signs_list[1]) >= i else '', 
 'x' if len(signs_list[2]) >= i else '')
print ('{0:<8} {1:<8} {2}').format(test_string_list[0], test_string_list[1], test_string_list[2])
print ('{0:<8} {1:<8} {2}').format(test_list[0], test_list[1], test_list[2])

Trickier is dealing with lists of arbitrary size which requires eval

for i in range(len(max(signs_list)), 0, -1):
 template_string = ""
 input_string = ""
 for z in range(len(test_string_list)):
 string_part = "{" + str(z) + ":<8} "
 template_string += string_part
 input_part = "'x' if len(signs_list[" \
 + str(z) + "]) >= i else '',"
 input_string += input_part
 statement = "('" + template_string + "')"
 statement += ".format"
 statement += "(" + input_string[:-1] + ")"
 print eval(statement)
template_string = ""
input_string = ""
for z in range(len(test_string_list)):
 string_part = "{" + str(z) + ":<8} "
 template_string += string_part
 input_part = "test_list[" + str(z) + "],"
 input_string += input_part
statement = "('" + template_string + "')"
statement += ".format"
statement += "(" + input_string[:-1] + ")"
print eval(statement)
template_string = ""
input_string = ""
for z in range(len(test_string_list)):
 string_part = "{" + str(z) + ":<8} "
 template_string += string_part
 input_part = "test_string_list[" + str(z) + "],"
 input_string += input_part
statement = "('" + template_string + "')"
statement += ".format"
statement += "(" + input_string[:-1] + ")"
print eval(statement)

The above monstrosity could can be refactored to remove the statement construction:

def statement_constructor(list_type, list_size):
 template_string = ""
 input_string = ""
 for z in range(list_size):
 string_part = "{" + str(z) + ":<8} "
 template_string += string_part
 if list_type == "signs_list":
 input_part = "'x' if len(signs_list[" \
 + str(z) + "]) >= i else '',"
 else:
 input_part = list_type + "[" + str(z) + "],"
 input_string += input_part
 statement = "('" + template_string + "')"
 statement += ".format"
 statement += "(" + input_string[:-1] + ")" 
 return statement
length = len(test_string_list)
for i in range(len(max(signs_list)), 0, -1):
 print eval(statement_constructor('signs_list', length))
print eval(statement_constructor('test_list', length))
print eval(statement_constructor('test_string_list', length))

All three produce the same output:

 x 
 x 
 x x 
 x x 
 x x 
 x x 
500000 5000000 7000000 
Test1 Test2 Test3 

Although the solution using eval could handle Test4, Test5, and so on. There may be a more elegant solution, but this works.

Edit: Or the more elegant solution without eval overkill suggested in the comment by Michael0x2a.

def statement_constructor(list_type, list_size):
 template_string = ""
 input_string = ""
 array = []
 for z in range(list_size):
 string_part = "{:<8}"
 template_string += string_part
 if list_type == "signs_list":
 array.append('x' if len(signs_list[z]) >= i else '')
 elif list_type == 'test_list':
 array.append(test_list[z])
 else:
 array.append(test_string_list[z])
 print (template_string).format(*array)
length = len(test_string_list)
for i in range(len(max(signs_list)), 0, -1):
 statement_constructor('signs_list', length)
statement_constructor('test_list', length)
statement_constructor('test_string_list', length) 
answered Apr 20, 2013 at 7:23
Sign up to request clarification or add additional context in comments.

1 Comment

I think using eval is overkill here. Instead, you could iterate through the number of columns there are to create the format string (just append '{:<8}' to the format string per column (no need for the number)). Then, you iterate through the elements inside the signs_list and add the 'x' or '' strings to an array. Then, do format_string.format(*array).

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.