How do I print separate multi-line ascii symbols side by side in output window

Viewed 265

Disclaimer: I'm a relatively new python user and programmer in general.

I am building a class for a deck of cards, and for the __str__ method I want to return the ascii symbols for cards currently in the deck as thirteen rows of four columns. Later, I will need similar logic when displaying players' hands when I actually use this class for a game. I'm hoping to find a way to do this where the number of columns is variable, and the number of rows is dependent upon the number of columns and the length of the list (or put plainly, just stops when out of cards). This way it will work for my __str__ return with 4 columns, and with a player's hand at a variable number of columns.

Since I'm only wanting to understand the logic to do this, I've simplified the issue down to the code below. I've done quite a bit of research, but I haven't found an example of this that I can understand or that doesn't use imported libraries. I've learned to use a comma after a print statement to prevent forcing a new line, but even with that tool I cannot find a way to make this work using for and while loops. I will also paste some code from my final use case. It is only an example of many that haven't worked, and it's probably hideous, but it's where I'm at.

Simplified use case:

# Each string in each list below would actually be one line of ascii art for
# the whole card, an example would be '|{v}   {s}   |'

deck = [['1','2','3','4'],
    ['5','6','7','8'],
    ['9','10','11','12'],
    ['a','b','c','d'],
    ['e','f','g','h'],
    ['i','j','k','l']]

# expected output in 3 columns:
#
#   1   5   9
#   2   6   10
#   3   7   11
#   4   8   12
#
#   a   e   i
#   b   f   j
#   c   g   k
#   d   h   l
#
# expected output in 4 columns:
#
#   1   5   9   a
#   2   6   10  b
#   3   7   11  c
#   4   8   12  d
#
#   e   i
#   f   j
#   g   k
#   h   l

End use case:

def __str__(self):

    # WORKS empty list to hold ascii strings
    built_deck = []

    # WORKS fill the list with ascii strings [card1,card2,card3,card4...]
    for card in self.deck:
        built_deck.append(self.build_card(str(card[0]),str(card[1:])))

    # WORKS transform the list to [allCardsRow1,allCardsRow2,allCardsRow3,allCardsRow4...]
    built_deck = list(zip(*built_deck))

    # mark first column as position
    position = 1

    # initialize position to beginning of deck
    card = 0

    # Try to print the table of cards ***FAILURE***
    for item in built_deck:
        while position <= 4:
            print(f'{item[card]}\t',)
            card += 1
            continue
        position = 1
        print(f'{item[card]}')
        card += 1
    #return built_deck
1 Answers

The trick is here to realize that what you are doing it taking successive transposes of the matrix of your cards and printing them where the size of the matrix you preform the operation on is the number of items you want to be displayed. We can get a transpose using zip in python.

def display(deck, number_of_columns):
    col = 0
    while col < len(deck):
        temp = deck[col:col+number_of_columns]
        temp = zip(*temp)
        for x in temp:
            for y in x:
                print(y, end=" ")
            print()
        col += number_of_columns
display(deck, 3)
print()
display(deck, 4)

Output

1 5 9 
2 6 10 
3 7 11 
4 8 12 
a e i 
b f j 
c g k 
d h l 

1 5 9 a 
2 6 10 b 
3 7 11 c 
4 8 12 d 
e i 
f j 
g k 
h l 
Related