Python中的ASCII艺术
我对python非常陌生,把它作为一种爱好来学习,通过一些搜索,我发现自己有一大堆来自“计算实践”的练习,其中一个要求写一个ASCII数字,如下面所示 这似乎是一个足够简单的练习,但我似乎不能用数字来画这个,练习表明上面的画是用数字“1”画的 它还规定,0以下或100以上的数字不能或不应用于创建ASCII图形 下面是另一个例子: 这里的输入是数字“2” 我已经找到了一种方法来显示第一张图像,但不是以任何方式使用给定的数字,只是在while循环中使用一个简单的“else”,这样我就可以过滤掉低于或等于0、高于或等于100的数字 我已经完全停下来了 我的代码如上所述,不使用变量编号创建第一个图形:Python中的ASCII艺术,python,ascii,Python,Ascii,我对python非常陌生,把它作为一种爱好来学习,通过一些搜索,我发现自己有一大堆来自“计算实践”的练习,其中一个要求写一个ASCII数字,如下面所示 这似乎是一个足够简单的练习,但我似乎不能用数字来画这个,练习表明上面的画是用数字“1”画的 它还规定,0以下或100以上的数字不能或不应用于创建ASCII图形 下面是另一个例子: 这里的输入是数字“2” 我已经找到了一种方法来显示第一张图像,但不是以任何方式使用给定的数字,只是在while循环中使用一个简单的“else”,这样我就可以过滤掉低
while True:
s = input("Give me a number to make a drawing with that is between 0 and 100: ")
if not s.isdigit():
print ("Error, only numbers will make this program run.")
continue #Try Again but with a number this time
if int(s) >= 100:
print ("The number is bigger than or equal to 100 and won't work. \nDo try again.")
continue #try again
if int(s) <= 0:
print ("The number is smaller than or equal to 0 and won't work. \nDo try again.")
continue #try again
else:
print ("%5s" %("*" *3),"\n"'%5s' %("* *"),"\n" '%7s' %("*** ***"),"\n" '%7s' %("* *"),"\n" '%7s' %("*** ***"),"\n" '%5s' %("* *"),"\n" '%5s' %("*" *3))
print ('Want to make another drawing ?')
continue #make another drawing
为True时:
s=输入(“给我一个数字,让我画一个介于0和100之间的图形:”)
如果不是s.isdigit():
打印(“错误,只有数字才能运行此程序。”)
继续#再试一次,但这次使用数字
如果整数>=100:
打印(“数字大于或等于100,无法使用。\n请重试。”)
继续#再试一次
如果int(s)请考虑1和2之间的差异。试着用手画出3和4应该是什么样子,以使序列正常工作。把它想象成一个问题,在这个问题中,你被赋予了一个序列的开始,而你必须完成剩下的工作
比如:
011235813
如果你不马上认出它,那就是斐波那契序列。一旦找出模式,就可以编写任意长的值序列
想想这个简单的ascii序列:
(一)
(二)
(三)
什么样子
或其他ascii序列:
(一)
(二)
(三)
什么是(4)
如果它仍然没有意义,请尝试设计一些您自己的递归形状,这些形状与您试图找出的形状有点类似(可能与我的第二个示例类似)。现在不必担心如何编码,只需担心输出应该是什么。然后查看这些模式并给出一个算法。首先,逐行分析图形以识别不同类型的模式
def cap(spacesBefore):
print " " * spacesBefore + "***"
def wall(spacesBefore, spacesBetween):
print " " * spacesBefore + "*" + " " * spacesBetween + "*"
def floor(spacesBefore, spacesBetween):
print " " * spacesBefore + "***" + " " * spacesBetween + "***"
- 封口,仅显示在顶行和底行上。它是任意数量的空间,后跟三星
- 墙,形成图形的垂直部分。它是任意数量的空间,后跟一颗星,后跟任意数量的空间,后跟一颗星
- 构成图形水平部分的地板。它是任意数量的空间,后跟三星,后跟任意数量的空间,后跟三星
我们可以编写一个函数来打印每个模式
def cap(spacesBefore):
print " " * spacesBefore + "***"
def wall(spacesBefore, spacesBetween):
print " " * spacesBefore + "*" + " " * spacesBetween + "*"
def floor(spacesBefore, spacesBetween):
print " " * spacesBefore + "***" + " " * spacesBetween + "***"
接下来,编写将显示大小为0、1和2的图形的代码。这将使您了解如何显示任意大小的图形
#size 0
cap(0)
wall(0,1)
cap(0)
print "\n"
#size 1
cap(2)
wall(2, 1)
floor(0, 1)
wall(0, 5)
floor(0, 1)
wall(2, 1)
cap(2)
print "\n"
#size 2
cap(4)
wall(4, 1)
floor(2, 1)
wall(2, 5)
floor(0, 5)
wall(0, 9)
floor(0, 5)
wall(2, 5)
floor(2, 1)
wall(4, 1)
cap(4)
输出:
***
* *
***
***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
通过分析用于生成这些图形的代码,可以看出一些模式。对于尺寸为N的图形:
- 两个端盖前面都有N*2个空格
- 有2*N+1条墙线
- 有2*N个楼层线
- 图的前半部分和后半部分是镜像
- 每条墙线前面的空间数从N*2开始,然后收缩2,直到达到零;然后它再增长两倍,直到再次达到N*2
- 墙之间的间距数从1开始,增加4,直到达到4*N+1;然后它再次收缩4,直到再次达到1
- 每个楼层的前一个空间的数量从2N-2开始,然后收缩2,直到达到零;然后它再次增长两倍,直到再次达到2N-2
- 楼层之间的空间数从1开始,增加4,直到达到4*N-3;然后它再次收缩4,直到再次达到1
图案都以线性速率增长和收缩,然后以线性速率收缩和增长。这意味着我们应该对条件相反的
环使用两个,对帽和中心墙使用一点额外的代码
def draw(N):
cap(2*N)
for i in range(N): #loop from 0 to N-1
wall(2*(N-i), 1+(4*i))
floor(2*(N-i-1), 1+(4*i))
wall(0, 4*N+1)
for i in range(N-1, -1, -1): #loop from N-1 to 0
floor(2*(N-i-1), 1+(4*i))
wall(2*(N-i), 1+(4*i))
cap(2*N)
现在测试代码
for i in range(7,10):
draw(i)
print "\n"
输出:
***
* *
***
***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
要找到图案,你可以想象如何绘制它。例如,要绘制:
***
* *
***
海龟可以按照以下说明操作:
- 右转,向前走
- 右转,向前走
- 右转,向前走
- 右转,向前走
import turtle
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.exitonclick() # leave GUI open until a click
from turtle import Turtle
def get_romb_program(n):
assert n >= 0
side = "rf" + "lfrf" * n
program = side * 4 # romb has 4 sides
return program
def draw(turtle, n):
assert 0 <= n < 101
commands = {'r': lambda t: t.right(90), # turn right
'l': lambda t: t.left(90), # turn left
'f': lambda t: t.forward(2)
}
run(get_romb_program(n), turtle, commands)
def run(program, t, commands):
for c in program:
commands[c](t)
n = 2
t = Turtle()
scr = t.getscreen()
scr.xscale, scr.yscale = [101 // (n + 1)] * 2
draw(t, n)
scr.exitonclick()
如果我们将“右转”缩写为'r'
,将“前进”缩写为“f”
,则说明如下:
'rfrfrfrf'
很容易看出它是'rf'*4
。以下步骤适用于:
***
* *
*** ***
* *
*** ***
* *
***
说明是'rflfrfrfrfrfrfrfrfrfrfrfrf'
或'rflfrf'*4
,其中'l'
代表“左转”
描述n
等于0
和1
的两种情况的规则是:
("rf" + "lfrf" * n) * 4
i、 例如,如果n=0
则为'rf'*4
,如果n=1
则为('rf'+'lfrf')*4
。要检查公式,您可以将其绘制为n=2
,并将其与已知答案进行比较:
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
作为Python程序:
import turtle
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.exitonclick() # leave GUI open until a click
from turtle import Turtle
def get_romb_program(n):
assert n >= 0
side = "rf" + "lfrf" * n
program = side * 4 # romb has 4 sides
return program
def draw(turtle, n):
assert 0 <= n < 101
commands = {'r': lambda t: t.right(90), # turn right
'l': lambda t: t.left(90), # turn left
'f': lambda t: t.forward(2)
}
run(get_romb_program(n), turtle, commands)
def run(program, t, commands):
for c in program:
commands[c](t)
n = 2
t = Turtle()
scr = t.getscreen()
scr.xscale, scr.yscale = [101 // (n + 1)] * 2
draw(t, n)
scr.exitonclick()
例子
输出
我认为如果我们得到整个练习会有所帮助。练习说明如下:大小为$n$的ASCII数字由一行或几行组成。每行上只允许空格和星号(*),每行上的星号之后不允许有空格,因此应以“\n”或换行结束。然后是上面提到的例子。我找到了横幅。另外,@fp:有关横幅,请参阅。但这与当前的情况无关question@fp耶
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***
from turtle import Turtle
def get_romb_program(n):
assert n >= 0
side = "rf" + "lfrf" * n
program = side * 4 # romb has 4 sides
return program
def draw(turtle, n):
assert 0 <= n < 101
commands = {'r': lambda t: t.right(90), # turn right
'l': lambda t: t.left(90), # turn left
'f': lambda t: t.forward(2)
}
run(get_romb_program(n), turtle, commands)
def run(program, t, commands):
for c in program:
commands[c](t)
n = 2
t = Turtle()
scr = t.getscreen()
scr.xscale, scr.yscale = [101 // (n + 1)] * 2
draw(t, n)
scr.exitonclick()
class AsciiTurtle(object):
def __init__(self):
self.path = [(0, 0)]
self.direction = (1, 0)
def forward(self, distance):
x, y = self.path[-1]
for i in range(1, distance + 1):
self.path.append((x + self.direction[0] * i,
y + self.direction[1] * i))
def right(self, angle_ignored): # 90 degree turn right
self.direction = self.direction[1], -self.direction[0]
def left(self, angle_ignored): # 90 degree turn left
self.direction = -self.direction[1], self.direction[0]
def show(self):
minx, maxx, maxy, miny = [f(xy[i] for xy in self.path)
for i in [0, 1] for f in [min, max]]
miny, maxy = -miny, -maxy # upside-down
board = [[' '] * (maxx - minx + 1) for _ in range(maxy - miny + 1)]
for x, y in self.path:
board[-y - miny][x - minx] = '*'
print('\n'.join(''.join(row) for row in board))
n = 5
t = AsciiTurtle()
draw(t, n) # defined above
t.show()
***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
*** ***
* *
***