Python: How to print a 5×5 grid on the same line as another

Question:

I’m trying to build a function that prints a given string in large text through command line. Each letter is a 5×5 grid of *’s and spaces. How would I print the next 5×5 character on the same line as the previous to print out the given string?

Code:

    options = {
    'a': '  *  n * * n*****n*   *n*   *', 
    'b': '**** n*   *n*****n*   *n**** ',
    'c': ' ****n*    n*    n*    n ****',
    'd': '**** n*   *n*   *n*   *n**** ',
    'e': '*****n*    n*****n*    n*****',
    'f': '*****n*    n*****n*    n*    ',
    'g': '*****n*    n* ***n*   *n*****',
    'h': '*   *n*   *n*****n*   *n*   *',
    'i': '*****n  *  n  *  n  *  n*****',
    'j': '***  n  *  n  *  n  *  n***  ',
    'k': '*   *n* *  n*    n* *  n*   *',
    'l': '*    n*    n*    n*    n*****',
    'm': '*   *n** **n* * *n*   *n*   *',
    'n': '*   *n**  *n* * *n*  **n*   *',
    'o': ' *** n*   *n*   *n*   *n *** ',
    'p': '**** n*   *n**** n*    n*    ',
    'q': ' *** n*   *n* * *n*  * n ** *',
    'r': '**** n*   *n**** n* *  n*  **',
    's': ' ****n*    n *** n    *n**** ',
    't': '*****n  *  n  *  n  *  n  *  ',
    'u': '*   *n*   *n*   *n*   *n *** ',
    'v': '*   *n*   *n * * n * * n  *  ',
    'w': '*   *n*   *n* * *n* * *n * * ',
    'x': '*   *n * * n  *  n * * n*   *',
    'y': '*   *n * * n  *  n  *  n  *  ',
    'z': '*****n   * n  *  n *   n*****',
    ',': '     n     n   **n   **n  *  ',
    ':': '     n  *  n     n  *  n     '

    }

    def Print_Big(inputString):
        lst = list(inputString)
        for i in lst:
            print(options[i], end = "")

    while True:
        userIn = input('Please enter a letter to big-ify: ').lower()
if userIn == "exit":
    break
elif userIn != "" and len(userIn) >= 1:
    Print_Big(userIn)
else:
    print('Please enter a valid string')
Asked By: Jake Doe

||

Answers:

You can’t print different letters side by side because you have n (new line character) in every letters you made.
So by default every next element will be printed in the next line.
Now to overcome this issue,I made some changes in your code.
Make a dictionary of lists in your code for each letters as follows.

options = {
        'a':['  *  ',' * * ','*****','*   *','*   *'],
        'b':['**** ','*   *','*****','*   *','**** '],
        'c':[' ****','*    ','*    ','*    ',' ****'],
         ........
        }

Why dictionary of lists? because I can access each lines of a letter one by one now.
I have given the code sample here. its working fine for 3 characters a,b,c as I added only 3 letters into dict for the purpose of demonstration.

options = {         
        'a':['  *  ',' * * ','*****','*   *','*   *'],
        'b':['**** ','*   *','*****','*   *','**** '],
        'c':[' ****','*    ','*    ','*    ',' ****']
        }   # I added only 3 letters, so It will work for only(a,b,c)

def Print_Big(newList):
    for i in range(len(options['a'])):  
        for j in range(len(newList)):       
            print(options[newList[j]][i]+"   ",end = " ")
        print()

output:

Please enter a letter to big-ify: abc
    *      ****      ****
   * *     *   *    *
  *****    *****    *
  *   *    *   *    *
  *   *    ****      ****
Answered By: Mufeed

@Mufeed’s answer is excellent, and well suited for beginners. This answer is a bit more complex.

One thing I would suggest is to write your letters using Python’s multi-line strings. It makes them much easier to edit. My letters are a bit bigger and I’ve only defined the three letters b, g, and i (using artist mode in emacs..):

letter_definitions = {
    'b': Letter("""
      ****************
      ******************
      *****          *****
      ***              ***
      ***              ****
      ***              ****
      ***            ******
      ******************
      *********************
      ***             * *****
      ***               ******
      ***                 *****
      ***                  ****
      ***                  ****
      ***                  ****
      ***                ****
      ***          **********
      *********************
      *****************
        """),
    'g': Letter("""
               ****************
             *** *        **** **
            ***              *****
         ****
        ****
       *****
       ****
       ****
       ****            ************
       ****            *************
       *****                       *
       *****                       *
        *****                     **
         ******                   *
           *******               **
             *********       *****
                   *************
         """),
    'i': Letter("""
        +---+
        |***|
        +---+

         +-+
         |*|
         |*|
         |*|
         |*|
         |*|
         |*|
         +-+
    """),
}

The Letter class stores the shape, and records height/width/baseline (__init__ method), and can write itself to a 2-dimensional buffer (the add_to_buffer() method):

import textwrap

class Letter(object):
    def __init__(self, shape):
        # remove space to the left (textwrap.dedent)
        # and split the shape string into lines (self.shape is a list of strings)
        self.shape = textwrap.dedent(shape).split('n')

        # remove any initial empty lines
        while self.shape[0] == '':
            self.shape = self.shape[1:]

        # remove any trailing empty lines
        while self.shape[-1] == '':
            self.shape = self.shape[:-1]

        self.height = len(self.shape)
        self.width = max(len(line) for line in self.shape)

        # we're doing the easy case where all letters are capitals
        # and the baseline is at the bottom
        self.baseline = self.height

    def add_to_buffer(self, buffer, x, y):
        "Write this letter shape to a 2-dimensional buffer at position x, y."

        # justify our baseline with the buffer's baseline
        y += buffer.baseline - self.baseline  

        # keeping track of which line and character we're at,
        # we go through each line in the shape
        for lineno, line in enumerate(self.shape):
            # .. and each character in the line
            for charpos, ch in enumerate(line):
                # and put the character into the buffer
                buffer[x + charpos, y + lineno] = ch

The buffer is implemented in the TextLine class, which creates a (simulated) 2 dimensional buffer of sufficient size to hold all the letter shapes by asking each letter how tall/wide it is:

class TextLine(object):
    def __init__(self, letters):
        self.letters = letters
        self.width = sum(letter.width for letter in self.letters)
        # one space between each letter, except the last one
        self.width += len(self.letters) - 1
        self.height = max(letter.height for letter in self.letters)
        self.baseline = self.height

        # add letters to buffer
        self.buffer = [' '] * (self.width * self.height)  # should probably use a buffer.buffer here..
        x = 0
        for letter in self.letters:
            letter.add_to_buffer(self, x, 0)
            x += letter.width + 1

    def __setitem__(self, (x, y), ch):
        # calculate the position and assign the character
        self.buffer[y * self.width + x] = ch

    def __str__(self):
        chunks = []
        # divide the buffer into pieces/chunks of length self.width..
        # (see https://stackoverflow.com/a/312464/75103 for how this works)
        for i in range(0, len(self.buffer), self.width):
            chunk = self.buffer[i:i + self.width]
            chunks.append(''.join(chunk))
        # .. and start each chunk on a new line
        return 'n'.join(chunks)

Finally I’ve renamed the print_big() function to big_text() and it returns the string to print:

def big_text(text):
    lines = text.splitlines(False)  # don't keep newlines
    res = []
    for line in lines:
        # convert each character to the corresponding Letter
        letters = [letter_definitions[ch] for ch in line]
        # put the letters into a TextLine
        text_line = TextLine(letters)
        # and append the buffer to the result
        res.append(str(text_line))
    return 'nn'.join(res)

quite often you’ll need to re-use functions like these, and it’s easier to reuse them if they return the string rather than print it, and you can use it just as easy for printing:

print big_text('big')

The result:

****************                                             
******************                                           
*****          *****                    ****************     
***              ***                  *** *        **** **   
***              ****                ***              *****  
***              ****             ****                       
***            ******            ****                        
******************        +---+ *****                        
*********************     |***| ****                         
***             * *****   +---+ ****                         
***               ******        ****            ************ 
***                 *****  +-+  ****            *************
***                  ****  |*|  *****                       *
***                  ****  |*|  *****                       *
***                  ****  |*|   *****                     **
***                ****    |*|    ******                   * 
***          **********    |*|      *******               ** 
*********************      |*|        *********       *****  
*****************          +-+              *************    
Answered By: thebjorn

Here an example I did to return 5×5 patterns for letters a-e:

    def print_big(letter):
    abcde ={ 
        'a':[
        '  a  n',
        ' a a n',
        'aaaaan',
        'a   an',
        'a   a'],
        'b':[
        'bbbb n',
        'b   bn',
        'bbbb n',
        'b   bn',
        'bbbb n'],
        'c':[
        ' ccccn',
        'c    n',
        'c    n',
        'c    n',
        ' cccc'],
        'd':[
        'dddd n',
        'd   dn',
        'd   dn',
        'd   dn',
        'dddd '],
        'e':[
        'eeeeen',
        'e    n',
        'eeeeen',
        'e    n',
        'eeeee']}
    
    finalString = ''
    
    for lines in abcde[letter]:
        finalString+=lines
    
    return print(finalString)

Tests & Outputs:

print_patterns('a')

  a  
 a a 
aaaaa
a   a
a   a

print_patterns('b')

bbbb 
b   b
bbbb 
b   b
bbbb 

print_patterns('c')

 cccc
c    
c    
c    
 cccc

print_patterns('d')

dddd 
d   d
d   d
d   d
dddd 

print_patterns('e')

eeeee
e    
eeeee
e    
eeeee
Answered By: Eduardo Cespedes
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.