-
Notifications
You must be signed in to change notification settings - Fork 1
/
generate.py
executable file
·102 lines (74 loc) · 2.52 KB
/
generate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python3
def join(*args):
"Simply join strings together"
return "".join(args)
def escape(*args):
"Replace new-line and quote characters"
return join(*args).replace("\n", r"\n").replace("\"", r"\"")
def quote(*args):
"Single quote a string, escaping it"
return join("'", escape(*args), "'")
def triple_quote(*args):
"Triple quote a string, without escaping, allow new-lines"
return join("r\"\"\"", join(*args), "\"\"\"")
def expand(n, s):
"""For each line of a string, if shorter then n, take the first space (if
any) and fil it with other spaces"""
rows = s.split("\n")
for i, r in enumerate(rows):
space_i = r.find(" ")
if space_i != -1:
if len(r) < n:
r = join(r[:space_i],
" " * int(n - len(r)),
r[space_i:])
rows[i] = r
return "\n".join(rows)
def indent(n, *rows):
"Indent rows by n spaces"
return "\n".join(["''" + (n-2)*" " + row for row in rows])
def spaces(n):
"Multiple spaces"
return " " * int(n)
def genera():
"Generate the quine code"
printing = join(";",
# "\n",
# r"print" + (indenting + 13)*" " + "(", "\n",
# r"_=(" + spaces(indenting + 14), "''", "\n",
r"_=(", " ''", "\n",
indent(8,
# r"'' ''",
r"'_=r\"\"\"%s\"\"\"'",
r"%_+_[::-1]) ",
r" ''",
r" ''",
r"# codiceinutile.org"),
"\n",
"print(_)" + spaces(13),
# "\n"
).replace("'", '"')
code = join("_=",
triple_quote(printing[::-1]),
printing, "\n")
return code
def test(code, file_name):
"Test the generated script"
# can it be done with an eval?
from subprocess import check_output
with open(file_name, "w") as f:
f.write(code)
output = check_output(["python3", file_name]).decode()
if code != output:
print(output)
raise AssertionError
def main():
"Main function"
from sys import argv
code = genera()
print(code)
if "--render" in argv:
print("".join([c if c in [" ", "\n"] else u"\u25AE" for c in code]))
test(code, "logo.py")
if __name__ == "__main__":
main()