Skip to content

Commit 0502b30

Browse files
committed
Optimized animations.
Let characters that have been read continue highlighting. Lower the frame rate inb notebook to fasten animation generation.
1 parent cef9444 commit 0502b30

File tree

4 files changed

+37
-38
lines changed

4 files changed

+37
-38
lines changed

automata/base/animation.py

-18
Original file line numberDiff line numberDiff line change
@@ -227,24 +227,6 @@ def change_symbol(self, current_index: int) -> Iterable[manim.ApplyMethod]:
227227
"""
228228
if current_index >= 0:
229229
yield Animate.highlight(self[current_index])
230-
if current_index >= 1:
231-
yield Animate.to_default_color(self[current_index - 1])
232-
233-
def clean(self, current_index: int) -> Iterable[manim.ApplyMethod]:
234-
"""
235-
Cancel all the highlighted elements.
236-
237-
Parameters
238-
----------
239-
current_index : int
240-
The highlighted symbol to cancel highlight.
241-
242-
Returns
243-
-------
244-
The animations (maybe none) for `Scene` object to `play`.
245-
"""
246-
if 0 <= current_index < len(self):
247-
yield Animate.to_default_color(self[current_index])
248230

249231
def show_result(self, accept: bool) -> manim.Write:
250232
"""

automata/fa/animation.py

+9-15
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717

1818
class _FAGraph(manim.VDict):
1919
"""
20-
The `FAGraph` class is the common class for FA to draw a picture of a `FA`
21-
object by representing the `AGraph` object generated by `fa.show_diagram()` with
22-
manim.
20+
The `FAGraph` class is the common class for FA to draw a picture of a `FA` object by
21+
representing the `AGraph` object generated by `fa.diagram` with manim.
2322
2423
The `FAGraph` class is a `VDict`. The keys are the states (with type `FAStateT`)
2524
and the transitions (with type `tuple[FAStateT, FAStateT]`, which is their start
@@ -37,17 +36,17 @@ def __init__(self, fa: FA) -> None:
3736
fa : FA
3837
The FA object based to create the graph.
3938
40-
Note that states are discriminated by `FA._get_state_name`, so states
41-
are not allowed to have same names. Plus, states are not allowed to be
42-
named 'None'.
39+
Note
40+
----
41+
As states are discriminated by `FA._get_state_name`, they are not allowed to
42+
have same names, nor named as 'None'.
4343
"""
4444
name_state = {FA._get_state_name(state): state for state in fa.states}
45-
fa_diagram = fa.show_diagram()
4645
super().__init__(
47-
{name_state.get(node): _ManimNode(node) for node in fa_diagram.nodes_iter()}
46+
{name_state.get(node): _ManimNode(node) for node in fa.diagram.nodes_iter()}
4847
| {
4948
tuple(map(name_state.get, edge)): _ManimEdge(edge)
50-
for edge in fa_diagram.edges_iter()
49+
for edge in fa.diagram.edges_iter()
5150
}
5251
)
5352
self.scale_to_fit_width(manim.config.frame_width)
@@ -235,7 +234,6 @@ def construct(self) -> None:
235234
accepts_input = False
236235
self.play(
237236
*self.dfa_graph.clean(((states_queue[-2], states_queue[-1]),)),
238-
*self.input_symbols.clean(symbol_index),
239237
self.input_symbols.show_result(accepts_input),
240238
)
241239

@@ -370,11 +368,7 @@ def add_lambda_transitions() -> Iterable[tuple["NFAStateT", "NFAStateT"]]:
370368
current_transitions = lambda_transitions
371369
self.play(
372370
*self.nfa_graph.clean(current_transitions),
373-
*self.input_symbols.clean(input_index),
374371
self.input_symbols.show_result(
375-
any(
376-
current_state in self.nfa.final_states
377-
for current_state in current_states
378-
)
372+
not current_states.isdisjoint(self.nfa.final_states)
379373
),
380374
)

automata/fa/fa.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import abc
66
import os
77
from collections import defaultdict
8+
from functools import cached_property
89
from typing import Any, Dict, Generator, List, Optional, Set, Tuple, Union
910

1011
from automata.base.automaton import Automaton, AutomatonStateT
@@ -28,7 +29,7 @@ class FA(Automaton, metaclass=abc.ABCMeta):
2829
"""
2930
The `FA` class is an abstract base class from which all finite automata inherit.
3031
Every subclass of FA can be rendered natively inside of a Jupyter notebook
31-
(automatically calling `show_diagram` without any arguments) if installed with
32+
(automatically calling `diagram` property) if installed with
3233
the `visual` optional dependency.
3334
"""
3435

@@ -183,6 +184,16 @@ def show_diagram(
183184

184185
return graph
185186

187+
@cached_property
188+
def diagram(self) -> pgv.AGraph:
189+
"""
190+
Returns
191+
-------
192+
AGraph
193+
A diagram of this automaton.
194+
"""
195+
return self.show_diagram()
196+
186197
@abc.abstractmethod
187198
def _get_input_path(
188199
self, input_str: str
@@ -196,7 +207,7 @@ def _get_input_path(
196207
def _repr_mimebundle_(
197208
self, *args: Any, **kwargs: Any
198209
) -> Dict[str, Union[bytes, str]]:
199-
return self.show_diagram()._repr_mimebundle_(*args, **kwargs)
210+
return self.diagram._repr_mimebundle_(*args, **kwargs)
200211

201212
@staticmethod
202213
def _add_new_state(state_set: Set[FAStateT], start: int = 0) -> int:

example_notebooks/fa_animation.ipynb

+15-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
"from automata.fa.nfa import NFA"
1919
]
2020
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"metadata": {},
25+
"outputs": [],
26+
"source": [
27+
"import manim\n",
28+
"\n",
29+
"# By default, the frame rate is 60 fps. So it takes a while to generates the animation.\n",
30+
"# This notebook set the frame rate lower to fasten the animation generation.\n",
31+
"manim.config.frame_rate = 12"
32+
]
33+
},
2134
{
2235
"cell_type": "markdown",
2336
"metadata": {},
@@ -51,7 +64,7 @@
5164
"cell_type": "markdown",
5265
"metadata": {},
5366
"source": [
54-
"The animation genereated will be in the `media/videos/1080p60` folder by default. When set `preview=True`, the video will show as soon as it's generated."
67+
"The animation genereated will be in the `media/videos/{pixel height}p{frame rate}` folder by default. When set `preview=True`, the video will show as soon as it's generated."
5568
]
5669
},
5770
{
@@ -176,7 +189,6 @@
176189
"outputs": [],
177190
"source": [
178191
"from automata.base.animation import Animate\n",
179-
"import manim\n",
180192
"\n",
181193
"Animate.HIGHLIGHT_COLOR = manim.XKCD.AVOCADO\n",
182194
"regex_nfa.animate_reading_input(\"0101000\", preview=True)"
@@ -225,7 +237,7 @@
225237
"name": "python",
226238
"nbconvert_exporter": "python",
227239
"pygments_lexer": "ipython3",
228-
"version": "3.12.9"
240+
"version": "3.12.10"
229241
}
230242
},
231243
"nbformat": 4,

0 commit comments

Comments
 (0)