-
Notifications
You must be signed in to change notification settings - Fork 0
/
genQuine.py
177 lines (161 loc) · 3.94 KB
/
genQuine.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import random as rnd
import sys,os
#===========DEFINE ALL THE NECCESARY COMMANDS============
#these must appear in this order
order = [
r"I='import';",
r"M='from math ';",
r"exec(I+' os');",
r"exec(M+I+' sqrt');",
r"x='M=os.path.realp';",
r"y='ath(__file__)';",
r"exec(x+y);",
r"f=open(M);",
r"s=f.read();"]
#these can be interspersed in 'order' in any order
anys = [\
r'S=-1.;',
r'F=2;',
r"o='%f';",
r"a='for i in s:\n ';",
r"N='\n';",
"b='if(i==\\'\"\\' ';",
r"c='or i==N):pass\n ';",
r"e='elif(i==\'|\'):';",
r"f='S+=1\n else:F+=1';"
]
#these must appear in this order, after everything above
lasts = [\
"m=a+b+c+e+f;",
"exec(m);",
"Q=S+F;",
"H=.5;",
"r=sqrt(Q/4)-H;",
"p=F/r**2;",
"r=o%p;",
"print r;"]
#==========PROGRAM WRITER HELPERS======================
def nl(f):
f.write("\n")
#=========GENERATE TEST PROGRAM========================
def writeTestProgram():
f=open("test.py","w")
for line in inits:
f.write(line)
nl(f)
for line in anys:
f.write(line)
nl(f)
for line in finals:
f.write(line)
nl(f)
#=======FORMAT THE GENERATION OF PROGRAM LINES=========
def addTo(line,string):
if line == "":
line += ";"+string
else:
line += string
return line
#=======RETRIEVE PROGRAM COMMANDS AS PER RULES========
def getLine(length):
global order
global anys
global lasts
#print order;print anys;print lasts
line = ""
if len(anys)>0:
#no spaces for initializations
if len(order)==0 or length < len(order[0]):
i = 0
#fill with anys
while len(line)<length and i<len(anys):
if len(line)+len(anys[i])+1<=length:
line = addTo(line,anys[i])
anys.remove(anys[i])
i=-1
i+=1
#just space for one initialization
elif length-1 == len(order[0]):
line = addTo(line,order[0])
order = order[1:]
#space for initializations + anys
else:
#fill with as many inits as possible
while len(line)<length and len(order)>0:
if len(line)+len(order[0])+1<=length:
line = addTo(line,order[0])
order = order[1:]
else:
break
#fill the rest with anys
i = 0
while len(line)<=length and i<len(anys):
if len(line)+len(anys[i])+1<=length:
line = addTo(line,anys[i])
anys.remove(anys[i])
i+=1
#no anys or inits left
if len(order)==0 and len(anys)==0:
#no space for lasts
if len(lasts)==0 or length < len(lasts[0]):
pass
else:
#fill line with lasts
while len(line)<=length and len(lasts)>0:
if len(line)+len(lasts[0])+1<=length:
line = addTo(line,lasts[0])
lasts = lasts[1:]
else:
break
#find out the leftover space
toFill = length - len(line)
if toFill > 0:
#fill leftover space with valid,pythonic gibberish
filler = "#"
for iterator in range(0,toFill - 1):
filler += "{}".format(rnd.randint(0,9))
else:
filler = ""
return line + filler
#======GENERATE QUINE CIRCLE PROGRAM FROM ABOVE LINES====
def makeCircle(radius,verbose):
f=open("quinePi.py","w")
#iterate through circle
for y_pos in range(-radius,radius+1):
content,empties = 0,0
for x_pos in range(-radius,radius+1):
#if coordinate in circle, allocate line space
if x_pos**2+y_pos**2 <= radius**2:
content += 1
else:
empties += 1
#get the Python contents of line
program = getLine(content)
#generate the beginning and ending separator strings
numSeps = empties/2
seps = "|"*numSeps
seps = '"""'+seps+'"""'
#format and write program line
toWrite = "{}{}{}".format(seps,program,seps)
if verbose:
print toWrite
f.write(toWrite)
if y_pos!=radius+1:
f.write("\n")
f.close()
#=======PROGRAM MAIN FUNCTION=============================
def estimate(radius,verbose):
makeCircle(radius,verbose)
os.system("python quinePi.py")
#======INTERPRET COMMAND LINE ARGS========================
if __name__ == '__main__':
desiredRad = int(sys.argv[2])
verbose = sys.argv[1]
if verbose=="-v":
verbose = True
else:
verbose = False
if desiredRad < 12:
print "Sorry! I haven't been able to make them that small yet!"
sys.exit()
estimate(desiredRad,verbose)