繁体   English   中英

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

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

我正在尝试构建一个 function 通过命令行以大文本打印给定的字符串。 每个字母都是由 * 和空格组成的 5x5 网格。 我将如何在与前一行相同的行上打印下一个 5x5 字符以打印出给定的字符串?

代码:

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

您不能并排打印不同的字母,因为您在每个字母中都有\\ n(换行符)。 因此,默认情况下,每个下一个元素都将打印在下一行中。 现在要解决这个问题,我在代码中做了一些更改。 在代码中为每个字母创建一个列表字典,如下所示。

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

为什么列表的字典? 因为我现在可以逐个访问每一行字母。 我在这里给出了代码示例。 它的工作正常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()

输出:

Please enter a letter to big-ify: abc
    *      ****      ****
   * *     *   *    *
  *****    *****    *
  *   *    *   *    *
  *   *    ****      ****

@Mufeed的答案非常好,非常适合初学者。 这个答案有点复杂。

我建议的一件事是使用Python的多行字符串来编写你的字母。 它使编辑更容易。 我的字母有点大,我只定义了三个字母b,g和i(在emacs中使用艺术家模式..):

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

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

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

缓冲区在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)

最后我将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)

通常你需要重复使用这些函数,如果它们返回字符串而不是打印它,它就更容易重用它们,并且你可以像打印一样方便地使用它:

print big_text('big')

结果:

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

这是我为字母 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)

测试和输出:

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