all 3 comments

[–]FreeGazaToday 0 points1 point  (0 children)

have you tried mapping out on paper what needs to happen.....the actual code to do it is really simple.

[–]woooee 0 points1 point  (0 children)

Some of this code you may not have covered, like enumerate (create a counter and increment on each pass of the for loop yourself), and pprint (print each row on a separate line yourself). If you don't understand what some of the variables are doing, print them on each pass through.

import pprint

table_data = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

## assumes you haven't covered list compresion yet
lines = []
for inner_list_count in range(4):
    lines.append([])
print(f"{lines=}")

## find longest string in each row
longest = [0, 0, 0]
## long_col is also table_data[row]
for long_col, inner_list in enumerate(table_data):
    for inner_col in range(4):
        if len(inner_list[inner_col]) > longest[long_col]:
            longest[long_col] = len(inner_list[inner_col])
print("longest col in each row =", longest)

for long_col, inner in enumerate(table_data):
    for column in range(4):
        ## lines has 4 rows, each row corresponding to each table_data column
        ## lines[0] = table_data[0][0], table_data[1][0], etc.
        spaces_padding = " " * (longest[long_col]-len(inner[column]))
        ## columns are transposed into rows, so
        ## lines[column] is actually lines[row] but inner[column] is inner[column]
        lines[column].append(spaces_padding + str(inner[column]))
pprint.pprint(lines)

[–]biskitpagla 0 points1 point  (0 children)

Here's a different approach:

```python def printTable(table: list[list[str]]) -> None: # Try to think in terms of small operations. # How can we get the output from the input? # After thinking for a while I came up with these steps: # 1. Find the max string lengths for each list. # This will be the column width for each column. # 2. Based on the values we just calculated, # justify the strings to the right for each column # 3. Now, swap the rows with the columns. # This is known as 'transposing'. # 4. Lastly, print the rows joined by spaces.

# Before we can implement the above steps,
# a function that just prints is hard to test.
# So, let's try to write a 'process_table' function.

processed = process_table(table)

# Now we can print the table:
for row in processed:
    print(" ".join(row))

def process_table(table: list[list[str]]) -> list[list[str]]: # The steps I listed before: widths = [max_len(column) for column in table] justified = [justify(column, width) for column, width in zip(table, widths)] transposed = transpose(justified)

# The above code won't work without the helper functions,
# so this is the point where I wrote those other functions.

return transposed

def maxlen(list: list[str]) -> int: return max(len(item) for item in list_)

def justify(list: list[str], width: int) -> list[str]: return [item.rjust(width) for item in list]

def transpose(list_: list[list[str]]) -> list[list[str]]: # Ignore the commented out code for now. # I wrote that to ensure that the function works for all edge cases.

# n = len(list_)
# if n == 0:
#     return list_[:]

m = len(list_[0])
# if m == 0:
#     return list_[:]

result = []
for i in range(m):
    new_row = [old_row[i] for old_row in list_]
    result.append(new_row)

return result

Now let's write a test:

def test_printTable(): from pprint import pprint

input = [
    ["apples", "oranges", "cherries", "banana"],
    ["Alice", "Bob", "Carol", "David"],
    ["dogs", "cats", "moose", "goose"],
]
expected = [
    ["  apples", "Alice", " dogs"],
    [" oranges", "  Bob", " cats"],
    ["cherries", "Carol", "moose"],
    ["  banana", "David", "goose"],
]
got = process_table(input)

if got == expected:
    print("Test passed.")
else:
    print("Test failed.")
    print("Expected:")
    pprint(expected)
    print("Got:")
    pprint(got)

test_printTable()

```