Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将三引号文本格式化为三引号打印语句_Python_Python 3.x_Formatting - Fatal编程技术网

Python 如何将三引号文本格式化为三引号打印语句

Python 如何将三引号文本格式化为三引号打印语句,python,python-3.x,formatting,Python,Python 3.x,Formatting,所以目前我正在做一个基于文本的项目,包括一个乐透。问题是我想在已经有三重引号的print语句中使用三重引号的文本编号。基本上我想做这样的事情: num1 = """ ______ / ___ \ \/ \ \ ___) / (___ ( ) \ /\___/ / \______/ """ print(""" ______________ | | | | |

所以目前我正在做一个基于文本的项目,包括一个乐透。问题是我想在已经有三重引号的print语句中使用三重引号的文本编号。基本上我想做这样的事情:

num1  = """
 ______   
/ ___  \  
\/   \  \ 
   ___) / 
  (___ (  
      ) \ 
/\___/  / 
\______/   

"""
print("""
 ______________
|             |
|             |
|             |
|     {a}     |
|             |
|             |
|             |
""".format(a=num1))
这只是一个概念,我知道这实际上不起作用。如果我尝试这样做,它只会将未格式化的文本推到下一行。我应该逐行打印吗?我是否需要使用
%s
而不是
.format()
?无论如何,我希望我能清楚地表达我的问题


-宙斯

我认为没有任何python内置程序可以帮你解决这个问题。我建议您只需寻找一个合适的ascii文本库就可以轻松地构建这种类型的ascii文本脚本,它是数百种可用脚本之一

如果你想自己编写代码,我只需要安装
pillow
,然后用它来填充自定义缓冲区中我想要的形状,下面是一个5分钟的示例,它将文本和矩形“渲染”到这样的缓冲区中。请注意,它没有进行越界检查,并且可能非常缓慢。。。但我想你可以在这上面开始工作:

from PIL import Image, ImageFont, ImageDraw


class AsciiBuffer():

    def __init__(self, width, height):
        self.font_size = 15
        self.font = ImageFont.truetype('arialbd.ttf', self.font_size)
        self.width = width
        self.height = height
        self.clear()

    def clear(self):
        self.buffer = [['*' for x in range(self.width)]
                       for y in range(self.height)]

    def draw_text(self, x0, y0, text):
        size = self.font.getsize(text)
        image = Image.new('1', size, 1)
        draw = ImageDraw.Draw(image)
        draw.text((0, 0), text, font=self.font)

        for y in range(size[1]):
            line = []
            for x in range(size[0]):
                if image.getpixel((x, y)):
                    self.buffer[y0 + y][x0 + x] = ' '
                else:
                    self.buffer[y0 + y][x0 + x] = '#'

    def draw_rectangle(self, x0, y0, w, h, fill=' '):
        for y in range(h):
            for x in range(w):
                self.buffer[y0 + y][x0 + x] = fill

    def render(self):
        for y in range(self.height):
            print(''.join(self.buffer[y]))

if __name__ == "__main__":
    k = 20
    ab = AsciiBuffer(k * 3 + 4, k * 3 + 4)
    n = 1
    for i in range(3):
        for j in range(3):
            x = 1 + (k + 1) * i
            y = 1 + (k + 1) * j
            ab.draw_rectangle(x, y, k, k)
            ab.draw_text(x + int(k / 4), y, str(n))
            n += 1
    ab.render()
输出:

重构:

在任何情况下,上面的代码都有多个问题,其中一个问题是类AsciiBuffer与PIL耦合,而这个类应该尽可能地虚拟,例如,只绘制“文本精灵”就可以了,所以这里有一个小重构,我将向您展示如何从多行字符串生成“文本精灵”(如您在问题中发布的内容)或PIL提供的某些系统字体:

import sys
from PIL import Image, ImageFont, ImageDraw


class SpriteGenerator():

    def __init__(self):
        pass

    def from_multiline_string(self, text, length):
        buf = []

        for l in text.splitlines():
            buf.append(list(l) + [' '] * (length - len(l)))

        return buf

    def from_pil(self, text, font_name='arialbd.ttf', font_size=15):
        font = ImageFont.truetype(font_name, font_size)
        size = font.getsize(text)
        image = Image.new('1', size, 1)
        draw = ImageDraw.Draw(image)
        draw.text((0, 0), text, font=font)
        buf = []

        for y in range(size[1]):
            line = []
            for x in range(size[0]):
                if image.getpixel((x, y)):
                    line.append(' ')
                else:
                    line.append('#')
            buf.append(line)

        return buf


class AsciiBuffer():

    def __init__(self, width, height):
        self.width = width
        self.height = height
        self.clear()

    def clear(self):
        self.buffer = [['*' for x in range(self.width)]
                       for y in range(self.height)]

    def draw_sprite(self, x0, y0, sprite):
        for y, row in enumerate((sprite)):
            for x, pixel in enumerate(row):
                self.buffer[y0 + y][x0 + x] = pixel

    def draw_rectangle(self, x0, y0, w, h, fill=' '):
        for y in range(h):
            for x in range(w):
                self.buffer[y0 + y][x0 + x] = fill

    def render(self):
        for y in range(self.height):
            print(''.join(self.buffer[y]))

if __name__ == "__main__":
    num  = """


 ______
/ ___  \\
\\/   \\  \\
   ___) /
  (___ (
      ) \\
/\\___/  /
\\______/
"""

    k = 15
    ab = AsciiBuffer(k * 3 + 4, k * 3 + 4)
    sg = SpriteGenerator()
    n = 1

    for i in range(3):
        for j in range(3):
            x = 1 + (k + 1) * i
            y = 1 + (k + 1) * j
            ab.draw_rectangle(x, y, k, k)
            if n == 3:
                ab.draw_sprite(
                    x + int(k / 4), y, sg.from_multiline_string(num, 11))
            else:
                ab.draw_sprite(
                    x + int(k / 4), y, sg.from_pil(str(n), font_size=k))
            n += 1

    ab.render()
输出:

通用解决方案: 下面的
函数应该可以满足您的需要。它接受
变量
带有
*arg的参数数量
,并
打印出
格式,并排打印在方框中。它的工作方式是将传入的数字压缩在一起,然后为每个变量打印它们之间的行。它还打印数字上方和下方的行,以完成方框

def printNums(*arg):
   nums = [n.split("\n")[1:-1] for n in arg]
   print("_" * (sum([len(n[0]) for n in nums]) + len(nums) + 1))
   rows = zip(*nums)
   for r in rows:
      for n in r:
         print("|", end='')
         print(n, end='')
      print("|")
   print("_" * (sum([len(n[0]) for n in nums]) + len(nums) + 1))
使用您的号码:

num1  = """
 ______   
/ ___  \  
\/   \  \ 
   ___) / 
  (___ (  
      ) \ 
/\___/  / 
\______/  
"""
我们可以使用其中的
4
调用
函数,例如:

printNums(num1, num1, num1, num1)
哪些产出:

_____________________________________________
| ______   | ______   | ______   | ______   |
|/ ___  \  |/ ___  \  |/ ___  \  |/ ___  \  |
|\/   \  \ |\/   \  \ |\/   \  \ |\/   \  \ |
|   ___) / |   ___) / |   ___) / |   ___) / |
|  (___ (  |  (___ (  |  (___ (  |  (___ (  |
|      ) \ |      ) \ |      ) \ |      ) \ |
|/\___/  / |/\___/  / |/\___/  / |/\___/  / |
|\______/  |\______/  |\______/  |\______/  |
_____________________________________________
我希望这就是您想要的!当然,这里我们对
3
数字使用重复的ASCII艺术,您可以制作其他数字,并适当地调用它们,如果这是您的应用程序所需要的。:)


希望这有帮助

您是否希望它在
num1
的每一行周围添加左右边框?格式化只是将一个字符串替换为另一个字符串,它不会试图理解布局并复制它。是的,我希望在三个不同的框中有三个数字。您需要编写自己的函数,将
num1
拆分为行,并在
中打印每一行|字符串。你必须调整它周围的空格数量,以便所有的边框都对齐。我不认为有任何内置的东西可以自动做到这一点。@Mr.Zeus谢谢:)这是一个非常酷的模块,感谢你花时间编写这么多代码,但我正在进行的项目将没有任何第三方模块。我希望这个答案能帮助很多人(我相信会的)。再次感谢!