Automate the Boring Stuff Chapter 6 Table Printer Almost Done
Solution 1
Here's an alternate method that perhaps you could apply to your own code. I first took tableData
and sorted it out into a dictionary so it's easier to work with. After that I found the longest list in terms of characters. This allows us to know how far over the shorter lists should go. Finally, I printed out each lists adding spaces in front of the shorter ones based on the difference from the longest.
# orginal data
tableData=[['apples', 'oranges', 'cherries', 'banana'],
['Alice', 'Bob', 'Carol', 'David'],
['dogs', 'cats', 'moose', 'goose']]
# empty dictonary for sorting the data
newTable = {0:[], 1:[], 2:[], 3:[]}
# iterate through each list in tableData
for li in tableData:
for i in range(len(li)):
# put each item of tableData into newTable by index
newTable[i].append(li[i])
# determine the longest list by number of total characters
# for instance ['apples', 'Alice', 'dogs'] would be 15 characters
# we will start with longest being zero at the start
longest = 0
# iterate through newTable
# for example the first key:value will be 0:['apples', 'Alice', 'dogs']
# we only really care about the value (the list) in this case
for key, value in newTable.items():
# determine the total characters in each list
# so effectively len('applesAlicedogs') for the first list
length = len(''.join(value))
# if the length is the longest length so far,
# make that equal longest
if length > longest:
longest = length
# we will loop through the newTable one last time
# printing spaces infront of each list equal to the difference
# between the length of the longest list and length of the current list
# this way it's all nice and tidy to the right
for key, value in newTable.items():
print(' ' * (longest - len(''.join(value))) + ' '.join(value))
Solution 2
This is how I did.
For the first part of the code I just used the hint they give to us.
In Chapter 4 / Practice Project / Character Picture Grid we've learned how to "rotate" and then print a list of lists. It was useful for the second part of my code.
#!/usr/bin/python3
# you can think of x and y as coordinates
tableData = [['apples', 'oranges', 'cherries', 'banana'],
['Alice', 'Bob', 'Carol', 'David'],
['dogs', 'cats', 'moose', 'goose']]
def printTable(table):
# create a new list of 3 "0" values: one for each list in tableData
colWidths = [0] * len(table)
# search for the longest string in each list of tableData
# and put the numbers of characters in the new list
for y in range(len(table)):
for x in table[y]:
if colWidths[y] < len(x):
colWidths[y] = len(x)
# "rotate" and print the list of lists
for x in range(len(table[0])) :
for y in range(len(table)) :
print(table[y][x].rjust(colWidths[y]), end = ' ')
print()
x += 1
printTable(tableData)
Solution 3
that's my method to solve this problem.
tableData = [['apples', 'oranges', 'cherries', 'banana'],
['Alice', 'Bob', 'Carol', 'David'],
['dogs', 'cats', 'moose', 'goose']]
def printTable(mylist):
#getting the item who has the max length in the inner tables
maxLength = 0
for item in mylist:
for i in item:
if len(i) > maxLength:
maxLength = len(i)
else:
maxLength = maxLength
# make a seperated rjust for every item in the inner lists
for item in mylist:
for i in range(len(item)):
item[i] = (item[i].rjust(maxLength))
# convert list to dictionary data type it's more easier to deal with.
myNewlist = {0: [], 1: [], 2: [], 3: []}
for i in range(len(item)):
for u in tableData:
myNewlist[i].append(u[i])
# print the out put :)
for key, value in myNewlist.items():
print(''.join(value))
(printTable(tableData))
Solution 4
Here you go young padawan:
tableData=[['apples', 'oranges', 'cherries', 'banana'],
['Alice', 'Bob', 'Carol', 'David'],
['dogs', 'cats', 'moose', 'goose']]
maxlen = 0
for fruit,name,animal in zip(tableData[0], tableData[1], tableData[2]):
maxlen = max(len(fruit) + len (name) + len (animal), maxlen)
for fruit,name,animal in zip(tableData[0], tableData[1], tableData[2]):
length = len(fruit) + len (name) + len (animal)
print ((' ' * (maxlen - length)) + fruit, name, animal)
Looping to determine maxlen is probably not optimal, copypasting was just the quickest thing that came to my mind.
Solution 5
First join elements, then find the longest one and then you can use %*s
to write lines. More in comments in code.
tableData=[['apples', 'oranges', 'cherries', 'banana'],
['Alice', 'Bob', 'Carol', 'David'],
['dogs', 'cats', 'moose', 'goose']]
longest = 0 # to find the longest line
lines = [] # to keep lines
for elements in zip(tableData[0], tableData[1], tableData[2]):
# join elements in line - like 'apples' + ' ' + 'Alice' + ' ' + 'dogs'
line = ' '.join(elements)
# add line to the list
lines.append(line)
#print(line) # you can print it to see what you get
# find the longest line
length = len(line)
if length > longest:
longest = length
#print('the longest:', longest)
longest += 1 # to get one space more at left side
# print lines using `%*s`
# if `longest` is 21 then it will works as `%21s`
for line in lines:
print('%*s' % (longest, line))
Stanley Wilkins
Updated on June 17, 2022Comments
-
Stanley Wilkins almost 2 years
In this section, they want us to create this table:
apples Alice dogs oranges Bob cats cherries Carol moose banana David goose
It must be justified to the right, and the input is tableData. Here's my code:
tableData=[['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']] listlens=[] tour=0 lists={} for m in tableData: total=0 tour+=1 for n in m: total+=len(n) lists["list:",tour]=total print("list",tour,total) itemcount=list(lists.values()) sortedlen=(sorted(itemcount,reverse=True)) longest=sortedlen[0] #print (lists['list:', 1]) #print (longest) for m in range(len(tableData[0])): for n in range(len(tableData)): print (tableData[n][m],end=" ") n+=1 print ("".rjust(lists['list:', 1],"-")) m+=1
I'm almost done except for one thing, I can't make it right-justified. This output is the closest I came so far.
apples Alice dogs --------------------------- oranges Bob cats --------------------------- cherries Carol moose --------------------------- banana David goose ---------------------------
If I put rjust inside the inner for-loop the output is much different:
apples-------------------------- Alice-------------------------- dogs-------------------------- oranges-------------------------- Bob-------------------------- cats-------------------------- cherries-------------------------- Carol-------------------------- moose-------------------------- banana-------------------------- David-------------------------- goose--------------------------
-
vesche over 8 yearsYou have a slight syntax error friend, should be
print (' ' * (maxlen - length) + fruit, name, animal)
. -
Stanley Wilkins over 8 yearsCan we simplify _,li part somehow? I googled it and it looks very difficult, maybe even more than my question. Your approach is way more advanced than I could figure out by myself but if you would explain a little more it would help.
-
Stanley Wilkins over 8 yearsIt works with vesche's correction to the last line, but about the fruit, name and animal, are they considered lists? It's my first time seeing built-in zip function, but I've done a little research about it now. Can we think it as a shortcut to make iterated lists from other lists?
-
vesche over 8 yearsI simplified the code, and added comments so you can follow along. Hope this helps!
-
Stanley Wilkins over 8 yearsThanks for making it easier, I love learning new ways to solve problems but since I'm at the very beginning, using zip() function and other built-in functions or methods to solve them would defeat the purpose of practicing the basics.
-
vesche over 8 yearsI didn't use
zip
. What built-in function are you having trouble understanding? I could rewrite something an easier way if you let me know what you're not getting. -
Stanley Wilkins over 8 yearsNo, I meant zip for the other answers. Your first code had some other advanced features but as for now it's very easy to understand.
-
Arthur Hv over 8 yearsSorry for the error, very obviously i have my head still wrapped in python 2. @StanleyWilkins zip transforms multiple lists in a single list of tuples, which is indeed handy for some iterations. Fruit name and animal are the loop iterators, they are single values; the lists they are iterating are tableData[n].
-
J. Chomel almost 8 yearsHi test, could you develop what you're doing here to answer the question? It's absolutely not clear.
-
onetwo12 almost 6 yearsExplaining your solution can be really helpful.
-
Nilay Vishwakarma almost 6 yearsWelcome to SO. I am sure you can add some descriptions and gotchas in the code, to make a better answer.
-
colidyre over 5 yearsthere is already an answer using enumeration: stackoverflow.com/a/38292570/2648551
-
Frieder over 5 yearsNice, short and clean answer!
-
kfrncs over 5 yearsthanks for this! my solution had me scratching my head. as far as I can tell, the 'x += 1' is unnecessary
-
Sashi over 5 yearsWelcome to stack overflow. Please also add a description on what the code does instead of just providing the code.
-
Akaisteph7 almost 5 yearsPlease explain how this is different from the other provided answers.