Removing files from data analysis directory
[ou-summer-of-code-2017.git] / 05-display-board / display-board-animation.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 27,
6 "metadata": {
7 "collapsed": true
8 },
9 "outputs": [],
10 "source": [
11 "import time\n",
12 "import re\n",
13 "from IPython.display import clear_output\n",
14 "from PIL import Image, ImageDraw, ImageColor, ImageFont"
15 ]
16 },
17 {
18 "cell_type": "code",
19 "execution_count": 3,
20 "metadata": {
21 "collapsed": true
22 },
23 "outputs": [],
24 "source": [
25 "WIDTH = 80\n",
26 "HEIGHT = 8"
27 ]
28 },
29 {
30 "cell_type": "code",
31 "execution_count": 4,
32 "metadata": {
33 "collapsed": true
34 },
35 "outputs": [],
36 "source": [
37 "def new_grid(w=WIDTH, h=HEIGHT):\n",
38 " return ['.' * w for r in range(1, h+1)]"
39 ]
40 },
41 {
42 "cell_type": "code",
43 "execution_count": 5,
44 "metadata": {
45 "collapsed": true
46 },
47 "outputs": [],
48 "source": [
49 "def print_grid(grid, md=False, suppress_dots=False):\n",
50 " if md:\n",
51 " print('```')\n",
52 " for row in grid:\n",
53 " if suppress_dots:\n",
54 " print(re.sub(r'\\.', ' ', row))\n",
55 " else:\n",
56 " print(row)\n",
57 " if md:\n",
58 " print('```')"
59 ]
60 },
61 {
62 "cell_type": "code",
63 "execution_count": 6,
64 "metadata": {
65 "collapsed": true
66 },
67 "outputs": [],
68 "source": [
69 "def top(grid, l, r):\n",
70 " new_segment = ''\n",
71 " for i in range(l-1, r):\n",
72 " if grid[0][i] == '.':\n",
73 " new_segment += '*'\n",
74 " else:\n",
75 " new_segment += '.'\n",
76 " grid[0] = grid[0][:l-1] + new_segment + grid[0][r:]\n",
77 " return grid"
78 ]
79 },
80 {
81 "cell_type": "code",
82 "execution_count": 7,
83 "metadata": {
84 "collapsed": true
85 },
86 "outputs": [],
87 "source": [
88 "def left(grid, t, b):\n",
89 " for i in range(t-1, b):\n",
90 " if grid[i][0] == '.':\n",
91 " grid[i] = '*' + grid[i][1:]\n",
92 " else:\n",
93 " grid[i] = '.' + grid[i][1:]\n",
94 " return grid"
95 ]
96 },
97 {
98 "cell_type": "code",
99 "execution_count": 8,
100 "metadata": {
101 "collapsed": true
102 },
103 "outputs": [],
104 "source": [
105 "def rotate_column(grid, c, raw_n):\n",
106 " n = raw_n % len(grid)\n",
107 " col = [row[c-1] for row in grid]\n",
108 " new_col = col[-n:] + col[:-n]\n",
109 " for i in range(len(grid)):\n",
110 " grid[i] = grid[i][:c-1] + new_col[i] + grid[i][c:]\n",
111 " return grid"
112 ]
113 },
114 {
115 "cell_type": "code",
116 "execution_count": 9,
117 "metadata": {
118 "collapsed": true
119 },
120 "outputs": [],
121 "source": [
122 "def rotate_row(grid, r, raw_n):\n",
123 " n = raw_n % len(grid[0])\n",
124 " grid[r-1] = grid[r-1][-n:] + grid[r-1][:-n]\n",
125 " return grid"
126 ]
127 },
128 {
129 "cell_type": "code",
130 "execution_count": 10,
131 "metadata": {
132 "collapsed": true
133 },
134 "outputs": [],
135 "source": [
136 "command_dispatch = {'left': left, 'top': top,\n",
137 " 'rotate row': rotate_row,\n",
138 " 'rotate column': rotate_column}"
139 ]
140 },
141 {
142 "cell_type": "code",
143 "execution_count": 11,
144 "metadata": {
145 "collapsed": true
146 },
147 "outputs": [],
148 "source": [
149 "def parse(command):\n",
150 " cmd, a, b = command.rsplit(maxsplit=2)\n",
151 " return cmd, int(a), int(b) "
152 ]
153 },
154 {
155 "cell_type": "code",
156 "execution_count": 63,
157 "metadata": {
158 "collapsed": true
159 },
160 "outputs": [],
161 "source": [
162 "def interpret(commands, grid=None, w=WIDTH, h=HEIGHT, \n",
163 " show_each_step=False, md=False, overprint=False):\n",
164 " if grid is None:\n",
165 " grid = new_grid(w, h)\n",
166 " frames = []\n",
167 " for cn, c in enumerate(commands):\n",
168 " cmd, a, b = parse(c)\n",
169 " if cmd in command_dispatch:\n",
170 " command_dispatch[cmd](grid, a, b)\n",
171 " else:\n",
172 " raise ValueError('Unknown command')\n",
173 " if show_each_step:\n",
174 " frames += [draw_frame(grid, c, cn)]\n",
175 " if show_each_step: \n",
176 " print('Final')\n",
177 " print_grid(grid, md=md)\n",
178 " frames[0].save('frames.gif', save_all=True, append_images=frames[1:], duration=200)\n",
179 " return grid"
180 ]
181 },
182 {
183 "cell_type": "code",
184 "execution_count": 44,
185 "metadata": {},
186 "outputs": [
187 {
188 "name": "stdout",
189 "output_type": "stream",
190 "text": [
191 "...****..............*...................*.....*..............*.................\n",
192 "......*..............*...................***..**..............*.................\n",
193 "......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...\n",
194 "......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......\n",
195 "......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......\n",
196 "......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......\n",
197 "...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......\n",
198 "....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......\n"
199 ]
200 }
201 ],
202 "source": [
203 "cmds = [c.strip() for c in open('05-pixels.txt').readlines()]\n",
204 "g = interpret(cmds)\n",
205 "print_grid(g)"
206 ]
207 },
208 {
209 "cell_type": "code",
210 "execution_count": 60,
211 "metadata": {},
212 "outputs": [
213 {
214 "name": "stdout",
215 "output_type": "stream",
216 "text": [
217 "(209, 17)\n"
218 ]
219 }
220 ],
221 "source": [
222 "im = Image.new('RGBA', (WIDTH * 10, HEIGHT * 10 + 21))\n",
223 "\n",
224 "# make a blank image for the text, initialized to transparent text color\n",
225 "# txt = Image.new('RGBA', im.size, (255,255,255,0))\n",
226 "txt = Image.new('RGBA', im.size, (0, 0, 0, 0))\n",
227 "\n",
228 "# get a font\n",
229 "fnt = ImageFont.truetype('Pillow/Tests/fonts/FreeMono.ttf', 18)\n",
230 "# get a drawing context\n",
231 "d = ImageDraw.Draw(txt)\n",
232 "\n",
233 "# draw text, full opacity\n",
234 "d.text((1,1), \"Command description\", font=fnt, fill='black')\n",
235 "\n",
236 "print(d.textsize(\"Command description\", fnt))\n",
237 "\n",
238 "\n",
239 "draw = ImageDraw.Draw(im)\n",
240 "for (r, row) in enumerate(g):\n",
241 " for (c, cell) in enumerate(row):\n",
242 " rx = c * 10\n",
243 " ry = r * 10 + 20\n",
244 " if cell == '*':\n",
245 " fill_colour = 'lime'\n",
246 " else:\n",
247 " fill_colour = 'black'\n",
248 " draw.rectangle([rx, ry, rx + 10, ry + 10], fill=fill_colour, outline='orange')\n",
249 " \n",
250 "# draw.line((0, 0) + im.size, fill=128)\n",
251 "# draw.line((0, im.size[1], im.size[0], 0), fill=128)\n",
252 "\n",
253 "out = Image.alpha_composite(im, txt)\n",
254 "out.save('test.png', 'PNG')\n",
255 "\n",
256 "del draw\n",
257 "\n"
258 ]
259 },
260 {
261 "cell_type": "code",
262 "execution_count": 76,
263 "metadata": {
264 "collapsed": true
265 },
266 "outputs": [],
267 "source": [
268 "def draw_frame(grid, command, frame_number, gif=True):\n",
269 " im = Image.new('RGBA', (WIDTH * 10, HEIGHT * 10 + 21))\n",
270 "\n",
271 " # make a blank image for the text, initialized to transparent text color\n",
272 " if gif:\n",
273 " txt = Image.new('RGBA', im.size, (255,255,255,0))\n",
274 " else:\n",
275 " txt = Image.new('RGBA', im.size, (0, 0, 0, 0)) # use this line rather than line above for animated png\n",
276 "\n",
277 " # get a font\n",
278 " fnt = ImageFont.truetype('Pillow/Tests/fonts/FreeMono.ttf', 18)\n",
279 " # get a drawing context\n",
280 " d = ImageDraw.Draw(txt)\n",
281 "\n",
282 " # draw text, full opacity\n",
283 " if gif:\n",
284 " d.text((1,1), command, font=fnt, fill='white')\n",
285 " else:\n",
286 " d.text((1,1), command, font=fnt, fill='black') # use this line rather than line above for animated png\n",
287 "\n",
288 " draw = ImageDraw.Draw(im)\n",
289 " for (r, row) in enumerate(grid):\n",
290 " for (c, cell) in enumerate(row):\n",
291 " rx = c * 10\n",
292 " ry = r * 10 + 20\n",
293 " if cell == '*':\n",
294 " fill_colour = 'lime'\n",
295 " else:\n",
296 " fill_colour = 'black'\n",
297 " draw.rectangle([rx, ry, rx + 10, ry + 10], fill=fill_colour, outline=128)\n",
298 "\n",
299 " # draw.line((0, 0) + im.size, fill=128)\n",
300 " # draw.line((0, im.size[1], im.size[0], 0), fill=128)\n",
301 "\n",
302 " out = Image.alpha_composite(im, txt)\n",
303 " if not gif:\n",
304 " out.save('frame{:04}.png'.format(frame_number), 'PNG') # uncomment here to save animated png frames\n",
305 "\n",
306 " del draw\n",
307 " \n",
308 " return out"
309 ]
310 },
311 {
312 "cell_type": "code",
313 "execution_count": 24,
314 "metadata": {},
315 "outputs": [
316 {
317 "data": {
318 "text/plain": [
319 "['...****..............*...................*.....*..............*.................',\n",
320 " '......*..............*...................***..**..............*.................',\n",
321 " '......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...',\n",
322 " '......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......',\n",
323 " '......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......',\n",
324 " '......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......',\n",
325 " '...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......',\n",
326 " '....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......']"
327 ]
328 },
329 "execution_count": 24,
330 "metadata": {},
331 "output_type": "execute_result"
332 }
333 ],
334 "source": [
335 "g"
336 ]
337 },
338 {
339 "cell_type": "code",
340 "execution_count": 77,
341 "metadata": {},
342 "outputs": [
343 {
344 "name": "stdout",
345 "output_type": "stream",
346 "text": [
347 "Final\n",
348 "...****..............*...................*.....*..............*.................\n",
349 "......*..............*...................***..**..............*.................\n",
350 "......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...\n",
351 "......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......\n",
352 "......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......\n",
353 "......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......\n",
354 "...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......\n",
355 "....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......\n",
356 "...****..............*...................*.....*..............*.................\n",
357 "......*..............*...................***..**..............*.................\n",
358 "......*.*****.*****.****.*****..****.....*.*.***.*****.*****.****.*****..****...\n",
359 "......*.....*.*...*..*.......*..*........*..**.*.....*.*...*..*.......*..*......\n",
360 "......*.*****.*...*..*...*****..*........*..*..*.*****.*...*..*...*****..*......\n",
361 "......*.*...*.*...*..*...*...*..*........*.....*.*...*.*...*..*...*...*..*......\n",
362 "...*..*.*..**.*...*..**..*..**..*........*.....*.*..**.*...*..**..*..**..*......\n",
363 "....**...**.*.*...*...**..**.*..*........*.....*..**.*.*...*...**..**.*..*......\n"
364 ]
365 }
366 ],
367 "source": [
368 "cmds = [c.strip() for c in open('05-pixels.txt').readlines()]\n",
369 "g = interpret(cmds, show_each_step=True)\n",
370 "print_grid(g)"
371 ]
372 },
373 {
374 "cell_type": "markdown",
375 "metadata": {},
376 "source": [
377 "Create animated png."
378 ]
379 },
380 {
381 "cell_type": "code",
382 "execution_count": null,
383 "metadata": {
384 "collapsed": true
385 },
386 "outputs": [],
387 "source": [
388 "! apngasm frames.png frame0*png 1 5"
389 ]
390 }
391 ],
392 "metadata": {
393 "kernelspec": {
394 "display_name": "Python 3",
395 "language": "python",
396 "name": "python3"
397 },
398 "language_info": {
399 "codemirror_mode": {
400 "name": "ipython",
401 "version": 3
402 },
403 "file_extension": ".py",
404 "mimetype": "text/x-python",
405 "name": "python",
406 "nbconvert_exporter": "python",
407 "pygments_lexer": "ipython3",
408 "version": "3.5.2+"
409 }
410 },
411 "nbformat": 4,
412 "nbformat_minor": 2
413 }