Franck Pommereau

added Box for easy layout

...@@ -28,6 +28,7 @@ class TikZ (object) : ...@@ -28,6 +28,7 @@ class TikZ (object) :
28 "arrayscope": {}, 28 "arrayscope": {},
29 "structscope": {}, 29 "structscope": {},
30 "heapscope": {}, 30 "heapscope": {},
31 + "boxscope": {},
31 "valueread" : {"very thick": None, 32 "valueread" : {"very thick": None,
32 "draw": "blue!50!black", 33 "draw": "blue!50!black",
33 "fill": "blue!20"}, 34 "fill": "blue!20"},
...@@ -44,6 +45,7 @@ class TikZ (object) : ...@@ -44,6 +45,7 @@ class TikZ (object) :
44 "heap": {"grow": "left", 45 "heap": {"grow": "left",
45 "distance": "15mm"}, 46 "distance": "15mm"},
46 "group": {"opacity": 0, 47 "group": {"opacity": 0,
48 + "draw": "yellow",
47 "very thick": None, 49 "very thick": None,
48 "inner sep": "0pt", 50 "inner sep": "0pt",
49 "outer sep": "0pt"}, 51 "outer sep": "0pt"},
...@@ -93,8 +95,8 @@ class CAniTikZ (CAni) : ...@@ -93,8 +95,8 @@ class CAniTikZ (CAni) :
93 {head}{code}{tail} 95 {head}{code}{tail}
94 \end{{tikzpicture}} 96 \end{{tikzpicture}}
95 """).format(opt=opt, 97 """).format(opt=opt,
96 - head=(head + "\n") if head else "", 98 + head=(head.strip("\n") + "\n") if head else "",
97 - tail=("\n" + tail) if tail else "", 99 + tail=("\n" + tail.strip("\n")) if tail else "",
98 code="\n ".join(self.tikz(**tikz).splitlines())) 100 code="\n ".join(self.tikz(**tikz).splitlines()))
99 101
100 class Pointer (CAniTikZ) : 102 class Pointer (CAniTikZ) :
...@@ -379,8 +381,7 @@ class Struct (Aggregate) : ...@@ -379,8 +381,7 @@ class Struct (Aggregate) :
379 self.__dict__[name] = value 381 self.__dict__[name] = value
380 382
381 class Heap (CAniTikZ) : 383 class Heap (CAniTikZ) :
382 - _defaults = {"group": {"opacity": 0, 384 + _defaults = {"group": {"inner sep": "5mm"}}
383 - "inner sep": "5mm"}}
384 def __init__ (self, **tikz) : 385 def __init__ (self, **tikz) :
385 super().__init__(tikz) 386 super().__init__(tikz)
386 self._alloc = {} 387 self._alloc = {}
...@@ -418,3 +419,51 @@ class Heap (CAniTikZ) : ...@@ -418,3 +419,51 @@ class Heap (CAniTikZ) :
418 children = " ".join(f"({nid})" for nid in fit) 419 children = " ".join(f"({nid})" for nid in fit)
419 yield fr" \node[{opt.group},fit={children}] ({self.nodeid}) {{}};" 420 yield fr" \node[{opt.group},fit={children}] ({self.nodeid}) {{}};"
420 yield r"\end{scope}" 421 yield r"\end{scope}"
422 +
423 +_flip = {"right": "below",
424 + "below": "right",
425 + "left": "above",
426 + "above": "left"}
427 +
428 +class Box (CAniTikZ) :
429 + def __init__ (self, *content, grow="right", distance="15mm", parent=None, **tikz) :
430 + super().__init__(tikz)
431 + self._grow = grow
432 + self._dist = distance
433 + self._parent = parent
434 + self._data = tuple(self._init(content))
435 + def _init (self, content) :
436 + for obj in content :
437 + if isinstance(obj, CAniTikZ) :
438 + yield obj
439 + elif isinstance(obj, list) :
440 + yield self.__class__(*obj,
441 + grow=(_flip.get(self._grow) if self._parent is None
442 + else self._parent._grow),
443 + distance=self._dist,
444 + parent=self,
445 + **self._o.dict())
446 + else :
447 + raise ValueError("invalid %s content: %r"
448 + % (self.__class__.__name__, obj))
449 + def tikz (self, **tikz) :
450 + opt = TikZ(tikz) + self._o
451 + classname = self.__class__.__name__
452 + nodeid = self.nodeid
453 + return (f"%% {classname} {nodeid} ({self._grow})\n"
454 + + "\n".join(self._tikz(opt))
455 + + f"\n%% /{classname} {nodeid}")
456 + def _tikz (self, opt) :
457 + fit = []
458 + yield fr"\begin{{scope}}[{opt.boxscope}]"
459 + for data in self._data :
460 + fit.append(data.nodeid)
461 + yield fr" %% box {self.nodeid} content"
462 + for line in data.tikz(**opt.dict()).splitlines() :
463 + yield " " + line
464 + opt = opt + {"pos": {self._grow:
465 + "{dist} of {prev}".format(dist=self._dist,
466 + prev=(data@None).nodeid)}}
467 + children = " ".join(f"({nid})" for nid in fit)
468 + yield fr" \node[{opt.group},fit={children}] ({self.nodeid}) {{}};"
469 + yield r"\end{scope}"
......
...@@ -6,11 +6,10 @@ mp4: qs-partition.mp4 qs-main.mp4 stack-push.mp4 ...@@ -6,11 +6,10 @@ mp4: qs-partition.mp4 qs-main.mp4 stack-push.mp4
6 rm -f out.* 6 rm -f out.*
7 PYTHONPATH=..:$$PYTHONPATH python3 $< 7 PYTHONPATH=..:$$PYTHONPATH python3 $<
8 pdflatex tpl 8 pdflatex tpl
9 - pdflatex tpl
10 mv -f tpl.pdf $@ 9 mv -f tpl.pdf $@
11 10
12 %.gif: %.pdf 11 %.gif: %.pdf
13 - rm -rf _gif 12 + rm -rf _gif $@
14 mkdir _gif 13 mkdir _gif
15 gs -dSAFER -DBATCH -dNOPAUSE -sDEVICE=png16m -r400 -sOutputFile=_gif/%03d.png $< 14 gs -dSAFER -DBATCH -dNOPAUSE -sDEVICE=png16m -r400 -sOutputFile=_gif/%03d.png $<
16 mogrify -resize 800x600 -format gif _gif/*.png 15 mogrify -resize 800x600 -format gif _gif/*.png
...@@ -18,7 +17,7 @@ mp4: qs-partition.mp4 qs-main.mp4 stack-push.mp4 ...@@ -18,7 +17,7 @@ mp4: qs-partition.mp4 qs-main.mp4 stack-push.mp4
18 rm -rf _gif 17 rm -rf _gif
19 18
20 %.mp4: %.pdf 19 %.mp4: %.pdf
21 - rm -rf _mp4 20 + rm -rf _mp4 $@
22 mkdir _mp4 21 mkdir _mp4
23 gs -dSAFER -DBATCH -dNOPAUSE -sDEVICE=png16m -r400 -sOutputFile=_mp4/%03d.png $< 22 gs -dSAFER -DBATCH -dNOPAUSE -sDEVICE=png16m -r400 -sOutputFile=_mp4/%03d.png $<
24 ffmpeg -r 1 -s 1024x768 -i _mp4/%03d.png -vcodec libx264 -crf 25 -pix_fmt yuv420p $@ 23 ffmpeg -r 1 -s 1024x768 -i _mp4/%03d.png -vcodec libx264 -crf 25 -pix_fmt yuv420p $@
......
No preview for this file type

5.08 MB | W: | H:

5 MB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
No preview for this file type
No preview for this file type
1 -from codanim.data import Array, Heap 1 +from codanim.data import Array, Box
2 from codanim.flow import FUNC, BLOCK, ENV, WS, XDECL, DECL, PY, EXPR, STMT, WHILE, IF 2 from codanim.flow import FUNC, BLOCK, ENV, WS, XDECL, DECL, PY, EXPR, STMT, WHILE, IF
3 3
4 ## 4 ##
...@@ -87,19 +87,6 @@ sort = FUNC(BLOCK(ENV("t", array), ...@@ -87,19 +87,6 @@ sort = FUNC(BLOCK(ENV("t", array),
87 src="while ({cond}) {{\n{body} }}\n")), 87 src="while ({cond}) {{\n{body} }}\n")),
88 src="void sort (Tab t) {{{body}}}") 88 src="void sort (Tab t) {{{body}}}")
89 89
90 -# let's play with Heap to layout the various data blocks
91 -# /!\ we must do this before simulating the code
92 -ha = Heap()
93 -ha.new(array)
94 -hs = Heap(heap={"grow": "right",
95 - "distance": "0pt"})
96 -hs.new(first)
97 -hs.new(last)
98 -h = Heap(heap={"grow": "right",
99 - "distance": "5mm"})
100 -h.new(ha)
101 -h.new(hs)
102 -
103 # run code and save its animation 90 # run code and save its animation
104 sort.IP += 1 91 sort.IP += 1
105 sort() 92 sort()
...@@ -107,5 +94,7 @@ with open("out.code", "w") as out : ...@@ -107,5 +94,7 @@ with open("out.code", "w") as out :
107 out.write(sort.tex()) 94 out.write(sort.tex())
108 95
109 # save data animation 96 # save data animation
97 +b = Box(Box(array), Box(first, last, distance="0pt"))
110 with open("out.tikz", "w") as out : 98 with open("out.tikz", "w") as out :
111 - out.write(h.tex(tikzpicture={"scale": .55})) 99 + out.write(b.tex(tikzpicture={"scale": .55},
100 + tail=r"\node at (-2,1) {};"))
......

841 KB | W: | H:

807 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
No preview for this file type
No preview for this file type
1 -from codanim.data import Array, Struct, Value, Heap 1 +from codanim.data import Array, Struct, Value, Box
2 from codanim.flow import FUNC, BLOCK, ENV, WS, DECL, WHILE, EXPR, DO, STMT, RETURN, IF 2 from codanim.flow import FUNC, BLOCK, ENV, WS, DECL, WHILE, EXPR, DO, STMT, RETURN, IF
3 3
4 a = Array([3, 13, 5, 0, 7, 11, 4, 9, 14, 2, 10, 1, 12, 8, 6], 4 a = Array([3, 13, 5, 0, 7, 11, 4, 9, 14, 2, 10, 1, 12, 8, 6],
5 index=["a", "b"]) 5 index=["a", "b"])
6 t = Struct({"len": Value(15), "val": a.ptr()}) 6 t = Struct({"len": Value(15), "val": a.ptr()})
7 7
8 -h = Heap()
9 -h.new(a)
10 -h.new(t)
11 -
12 partition = FUNC(BLOCK(ENV("t", t), 8 partition = FUNC(BLOCK(ENV("t", t),
13 WS(" "), 9 WS(" "),
14 DECL("pivot", EXPR("t.val[(t.len-1)//2]", 10 DECL("pivot", EXPR("t.val[(t.len-1)//2]",
...@@ -55,5 +51,7 @@ with open("out.code", "w") as out : ...@@ -55,5 +51,7 @@ with open("out.code", "w") as out :
55 out.write(partition.tex()) 51 out.write(partition.tex())
56 52
57 # save data animation 53 # save data animation
54 +b = Box(a, t, grow="left")
58 with open("out.tikz", "w") as out : 55 with open("out.tikz", "w") as out :
59 - out.write(h.tex(tikzpicture={"scale": .6})) 56 + out.write(b.tex(tikzpicture={"scale": .6},
57 + tail=r"\node at (0,-2) {};"))
......

87.2 KB | W: | H:

83.3 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
No preview for this file type
No preview for this file type
1 -from codanim.data import Heap, Struct, Value 1 +from codanim.data import Heap, Struct, Value, Box
2 from codanim.flow import FUNC, BLOCK, ENV, WS, DECL, EXPR, STMT 2 from codanim.flow import FUNC, BLOCK, ENV, WS, DECL, EXPR, STMT
3 3
4 heap = Heap() 4 heap = Heap()
...@@ -8,15 +8,6 @@ stack = heap.new(Struct({"val": Value(2), "next": stack})) ...@@ -8,15 +8,6 @@ stack = heap.new(Struct({"val": Value(2), "next": stack}))
8 s = Value(stack, nodeid="s") 8 s = Value(stack, nodeid="s")
9 t = Value(None, nodeid="t", value={"xshift": "-25mm"}) 9 t = Value(None, nodeid="t", value={"xshift": "-25mm"})
10 10
11 -v = Heap(heap={"grow": "above",
12 - "separation": "0pt"})
13 -h = Heap(heap={"grow": "right"},
14 - )
15 -h.new(t)
16 -h.new(s)
17 -v.new(heap)
18 -v.new(h)
19 -
20 push = FUNC(BLOCK(ENV("s", s), 11 push = FUNC(BLOCK(ENV("s", s),
21 ENV("u", Value(3)), 12 ENV("u", Value(3)),
22 ENV("top", t), 13 ENV("top", t),
...@@ -43,8 +34,9 @@ with open("out.code", "w") as out : ...@@ -43,8 +34,9 @@ with open("out.code", "w") as out :
43 out.write(push.tex()) 34 out.write(push.tex())
44 35
45 # save data and animation 36 # save data and animation
37 +b = Box(heap, Box(t, s, grow="right"), grow="above")
46 with open("out.tikz", "w") as out : 38 with open("out.tikz", "w") as out :
47 - out.write(v.tex(tail=r""" 39 + out.write(b.tex(tail=r"""
48 \node[above] at (s.north) {\texttt{s}}; 40 \node[above] at (s.north) {\texttt{s}};
49 \node[above] at (t.north) {\texttt{top}}; 41 \node[above] at (t.north) {\texttt{top}};
50 """)) 42 """))
......