Making diamond ASCII art with Python

这一生的挚爱 提交于 2019-12-01 07:54:16

This is python. There are a multitude of useful string functions you could use to create inventive ASCII art in a handful lines of code.

Some of the most important ones would be str.join, str.Xjust. We'll also make use of chr and ord to iterate over character ranges.

First, define a function that'll handle padding.

def pad(c1, c2, sep='.', field_width=10):
    out = sep.join(chr(x) for x in range(c2, c1, -1)).rjust(field_width, sep) # build the first part 
    return sep.join([out, chr(c1), out[::-1]])

The first line of code will build the first half of the diamond line. The second line joins the first half with the centre letter, and the reversed version of the first half.

Next, determine the range - how big your diamond is going to be.

start = 'A'
end = ...
field_width = (ord(end) - ord('A')) * 2 - 1

Now, you'll need two separate loops - one for the upper diamond and the other for the lower one. Both loops call pad at each iteration.

for e in range(ord(end), ord(start), -1):
    print(pad(e, ord(end), '.', field_width))

for e in range(ord(start), ord(end) + 1):
    print(pad(e, ord(end), '.', field_width))

end = 'E':

........E........
......E.D.E......
....E.D.C.D.E....
..E.D.C.B.C.D.E..
E.D.C.B.A.B.C.D.E
..E.D.C.B.C.D.E..
....E.D.C.D.E....
......E.D.E......
........E........

end = 'F':

..........F..........
........F.E.F........
......F.E.D.E.F......
....F.E.D.C.D.E.F....
..F.E.D.C.B.C.D.E.F..
F.E.D.C.B.A.B.C.D.E.F
..F.E.D.C.B.C.D.E.F..
....F.E.D.C.D.E.F....
......F.E.D.E.F......
........F.E.F........
..........F..........

Seth Difley's answer explores an alternative approach which involves building the first half of the diamond and reversing it to obtain the second half. Indeed, this approach can also be adopted to this solution, something along the lines of:

lines = []
for e in range(ord(end), ord(start) - 1, -1):
    lines.append(pad(e, ord(end), '.', field_width))

for x in lines + lines[-2::-1]:
    print(x)

Which also results in the same output, and is faster.

Strategy: since the top half of the diamond is rendered correctly by the existing program, generate the top half and then generate the bottom half by reversing the lines from the top half. build_diamond returns a list containing the strings for the top half. print('\n'.join(string_list)) prints the top half. bottom_of_diamond_string_list = list(reversed(string_list))[1:] reverses the strings from the top half and removes the middle string with [1:] to get the strings for the bottom half. print('\n'.join(bottom_of_diamond_string_list)) prints the bottom half. Tested and works for 5 and 6 (even and odd) chars length. A lot more code clean up can be done, if desired.

chars = 'ABCDEF'
length = len(chars)

def build_diamond(length):
    dots = (length*2 - 1)*2 - 1
    string = ''
    string_list = []
    for i in range(length):
        string1 = ''
        string += chars[i]
        length1 = len(string)
        for j in range(0, length1):
            if j % 2 != 0:
                string1 += chars[length -1 - j].center(3, '.')
            else:
                string1 += chars[length - 1 - j]
        for k in range(i - 1, -1, -1):
            if k % 2 != 0:
                string1 += chars[length - 1 - k].center(3, '.')
            else:
                string1 += chars[length - 1 - k]
        string1 = string1.center(dots, '.')
        string_list.append(string1)
    return string_list

if __name__ == '__main__':
    string_list = build_diamond(length)
    print('\n'.join(string_list))
    bottom_of_diamond_string_list = list(reversed(string_list))[1:]
    print('\n'.join(bottom_of_diamond_string_list))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!