简体   繁体   English

Python:如何在与另一行相同的行上打印 5x5 网格

[英]Python: How to print a 5x5 grid on the same line as another

I'm trying to build a function that prints a given string in large text through command line.我正在尝试构建一个 function 通过命令行以大文本打印给定的字符串。 Each letter is a 5x5 grid of *'s and spaces.每个字母都是由 * 和空格组成的 5x5 网格。 How would I print the next 5x5 character on the same line as the previous to print out the given string?我将如何在与前一行相同的行上打印下一个 5x5 字符以打印出给定的字符串?

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')

You can't print different letters side by side because you have \\n (new line character) in every letters you made. 您不能并排打印不同的字母,因为您在每个字母中都有\\ n(换行符)。 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. 它的工作正常3个字符a,b,c,因为为了演示,我只在dict中添加了3个字母。

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
    *      ****      ****
   * *     *   *    *
  *****    *****    *
  *   *    *   *    *
  *   *    ****      ****

@Mufeed's answer is excellent, and well suited for beginners. @Mufeed的答案非常好,非常适合初学者。 This answer is a bit more complex. 这个答案有点复杂。

One thing I would suggest is to write your letters using Python's multi-line strings. 我建议的一件事是使用Python的多行字符串来编写你的字母。 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..): 我的字母有点大,我只定义了三个字母b,g和i(在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): Letter类存储形状,并记录高度/宽度/基线( __init__方法),并可将自身写入二维缓冲区( add_to_buffer()方法):

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: 缓冲区在TextLine类中实现,它创建一个足够大小的(模拟)2维缓冲区,通过询问每个字母的高/宽来保存所有字母形状:

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: 最后我将print_big()函数重命名为big_text()并返回要打印的字符串:

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 '\n\n'.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: 结果:

****************                                             
******************                                           
*****          *****                    ****************     
***              ***                  *** *        **** **   
***              ****                ***              *****  
***              ****             ****                       
***            ******            ****                        
******************        +---+ *****                        
*********************     |***| ****                         
***             * *****   +---+ ****                         
***               ******        ****            ************ 
***                 *****  +-+  ****            *************
***                  ****  |*|  *****                       *
***                  ****  |*|  *****                       *
***                  ****  |*|   *****                     **
***                ****    |*|    ******                   * 
***          **********    |*|      *******               ** 
*********************      |*|        *********       *****  
*****************          +-+              *************    

Here an example I did to return 5x5 patterns for letters ae:这是我为字母 ae 返回 5x5 模式的示例:

    def print_big(letter):
    abcde ={ 
        'a':[
        '  a  \n',
        ' a a \n',
        'aaaaa\n',
        'a   a\n',
        'a   a'],
        'b':[
        'bbbb \n',
        'b   b\n',
        'bbbb \n',
        'b   b\n',
        'bbbb \n'],
        'c':[
        ' cccc\n',
        'c    \n',
        'c    \n',
        'c    \n',
        ' cccc'],
        'd':[
        'dddd \n',
        'd   d\n',
        'd   d\n',
        'd   d\n',
        'dddd '],
        'e':[
        'eeeee\n',
        'e    \n',
        'eeeee\n',
        '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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM