Automate the Boring Stuff Chapter 6 Table Printer Almost Done

18,976

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))
Share:
18,976
Stanley Wilkins
Author by

Stanley Wilkins

Updated on June 17, 2022

Comments

  • Stanley Wilkins
    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
    vesche over 8 years
    You have a slight syntax error friend, should be print (' ' * (maxlen - length) + fruit, name, animal).
  • Stanley Wilkins
    Stanley Wilkins over 8 years
    Can 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
    Stanley Wilkins over 8 years
    It 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
    vesche over 8 years
    I simplified the code, and added comments so you can follow along. Hope this helps!
  • Stanley Wilkins
    Stanley Wilkins over 8 years
    Thanks 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
    vesche over 8 years
    I 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
    Stanley Wilkins over 8 years
    No, 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
    Arthur Hv over 8 years
    Sorry 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
    J. Chomel almost 8 years
    Hi test, could you develop what you're doing here to answer the question? It's absolutely not clear.
  • onetwo12
    onetwo12 almost 6 years
    Explaining your solution can be really helpful.
  • Nilay Vishwakarma
    Nilay Vishwakarma almost 6 years
    Welcome to SO. I am sure you can add some descriptions and gotchas in the code, to make a better answer.
  • colidyre
    colidyre over 5 years
    there is already an answer using enumeration: stackoverflow.com/a/38292570/2648551
  • Frieder
    Frieder over 5 years
    Nice, short and clean answer!
  • kfrncs
    kfrncs over 5 years
    thanks for this! my solution had me scratching my head. as far as I can tell, the 'x += 1' is unnecessary
  • Sashi
    Sashi over 5 years
    Welcome to stack overflow. Please also add a description on what the code does instead of just providing the code.
  • Akaisteph7
    Akaisteph7 almost 5 years
    Please explain how this is different from the other provided answers.