mirror of
https://github.com/3b1b/manim.git
synced 2025-07-31 05:52:34 +08:00
691 lines
20 KiB
Python
691 lines
20 KiB
Python
from big_ol_pile_of_manim_imports import *
|
|
from active_projects.eop.reusable_imports import *
|
|
|
|
|
|
class BrickRowScene(PiCreatureScene):
|
|
|
|
|
|
def split_tallies(self, direction = DOWN):
|
|
# Split all tally symbols at once and move the copies
|
|
# either horizontally on top of the brick row
|
|
# or diagonally into the bricks
|
|
|
|
self.tallies_copy = self.tallies.copy()
|
|
self.add_foreground_mobject(self.tallies_copy)
|
|
|
|
tally_targets_left = [
|
|
rect.get_center() + 0.25 * rect.get_width() * LEFT
|
|
for rect in self.row.rects
|
|
]
|
|
|
|
tally_targets_right = [
|
|
rect.get_center() + 0.25 * rect.get_width() * RIGHT
|
|
for rect in self.row.rects
|
|
]
|
|
|
|
if np.all(direction == LEFT) or np.all(direction == RIGHT):
|
|
|
|
tally_y_pos = self.tallies[0].anchor[1]
|
|
for target in tally_targets_left:
|
|
target[1] = tally_y_pos
|
|
for target in tally_targets_right:
|
|
target[1] = tally_y_pos
|
|
|
|
for (i, tally) in enumerate(self.tallies):
|
|
|
|
target_left = tally_targets_left[i]
|
|
new_tally_left = TallyStack(tally.nb_heads + 1, tally.nb_tails)
|
|
new_tally_left.move_anchor_to(target_left)
|
|
v = target_left - tally.anchor
|
|
|
|
self.play(
|
|
tally.move_anchor_to, target_left,
|
|
)
|
|
tally.anchor = target_left
|
|
self.play(Transform(tally, new_tally_left))
|
|
|
|
tally_copy = self.tallies_copy[i]
|
|
|
|
target_right = tally_targets_right[i]
|
|
new_tally_right = TallyStack(tally.nb_heads, tally.nb_tails + 1)
|
|
new_tally_right.move_anchor_to(target_right)
|
|
v = target_right - tally_copy.anchor
|
|
|
|
self.play(tally_copy.move_anchor_to, target_right)
|
|
tally_copy.anchor = target_right
|
|
self.play(Transform(tally_copy, new_tally_right))
|
|
|
|
tally_copy.nb_heads = new_tally_right.nb_heads
|
|
tally_copy.nb_tails = new_tally_right.nb_tails
|
|
tally.nb_heads = new_tally_left.nb_heads
|
|
tally.nb_tails = new_tally_left.nb_tails
|
|
|
|
|
|
|
|
|
|
def tally_split_animations(self, direction = DOWN):
|
|
# Just creates the animations and returns them
|
|
# Execution can be timed afterwards
|
|
# Returns two lists: first all those going left, then those to the right
|
|
|
|
self.tallies_copy = self.tallies.copy()
|
|
self.add_foreground_mobject(self.tallies_copy)
|
|
|
|
tally_targets_left = [
|
|
rect.get_center() + 0.25 * rect.get_width() * LEFT
|
|
for rect in self.row.rects
|
|
]
|
|
|
|
tally_targets_right = [
|
|
rect.get_center() + 0.25 * rect.get_width() * RIGHT
|
|
for rect in self.row.rects
|
|
]
|
|
|
|
if np.all(direction == LEFT) or np.all(direction == RIGHT):
|
|
|
|
tally_y_pos = self.tallies[0].anchor[1]
|
|
for target in tally_targets_left:
|
|
target[1] = tally_y_pos
|
|
for target in tally_targets_right:
|
|
target[1] = tally_y_pos
|
|
|
|
|
|
anims1 = []
|
|
|
|
for (i, tally) in enumerate(self.tallies):
|
|
|
|
new_tally_left = TallyStack(tally.nb_heads + 1, tally.nb_tails)
|
|
target_left = tally_targets_left[i]
|
|
new_tally_left.move_anchor_to(target_left)
|
|
|
|
anims1.append(Transform(tally, new_tally_left))
|
|
|
|
tally.anchor = target_left
|
|
tally.nb_heads = new_tally_left.nb_heads
|
|
tally.nb_tails = new_tally_left.nb_tails
|
|
|
|
|
|
anims2 = []
|
|
|
|
for (i, tally) in enumerate(self.tallies_copy):
|
|
|
|
new_tally_right = TallyStack(tally.nb_heads, tally.nb_tails + 1)
|
|
target_right = tally_targets_right[i]
|
|
new_tally_right.move_anchor_to(target_right)
|
|
|
|
anims2.append(Transform(tally, new_tally_right))
|
|
|
|
tally.anchor = target_right
|
|
tally.nb_heads = new_tally_right.nb_heads
|
|
tally.nb_tails = new_tally_right.nb_tails
|
|
|
|
return anims1, anims2
|
|
|
|
|
|
def split_tallies_at_once(self, direction = DOWN):
|
|
anims1, anims2 = self.tally_split_animations(direction = direction)
|
|
self.play(*(anims1 + anims2))
|
|
|
|
def split_tallies_in_two_steps(self, direction = DOWN):
|
|
# First all those to the left, then those to the right
|
|
anims1, anims2 = self.tally_split_animations(direction = direction)
|
|
self.play(*anims1)
|
|
self.wait(0.3)
|
|
self.play(*anims2)
|
|
|
|
|
|
|
|
|
|
def merge_rects_by_subdiv(self):
|
|
|
|
half_merged_row = self.row.copy()
|
|
half_merged_row.subdiv_level += 1
|
|
half_merged_row.generate_points()
|
|
half_merged_row.move_to(self.row)
|
|
|
|
self.play(FadeIn(half_merged_row))
|
|
self.remove(self.row)
|
|
self.row = half_merged_row
|
|
|
|
def merge_tallies(self, direction = UP):
|
|
|
|
r = self.row.subdiv_level
|
|
tally_targets = [
|
|
rect.get_center()
|
|
for rect in self.row.get_rects_for_level(r)
|
|
]
|
|
|
|
if np.all(direction == LEFT) or np.all(direction == RIGHT):
|
|
y_pos = self.row.get_center()[1] + 1.2 * 0.5 * self.row.get_height()
|
|
for target in tally_targets:
|
|
target[1] = y_pos
|
|
|
|
anims = []
|
|
for (tally, target) in zip(self.tallies[1:], tally_targets[1:-1]):
|
|
anims.append(tally.move_anchor_to)
|
|
anims.append(target)
|
|
|
|
for (tally, target) in zip(self.tallies_copy[:-1], tally_targets[1:-1]):
|
|
anims.append(tally.move_anchor_to)
|
|
anims.append(target)
|
|
|
|
self.play(*anims)
|
|
# update anchors
|
|
for (tally, target) in zip(self.tallies[1:], tally_targets[1:-1]):
|
|
tally.anchor = target
|
|
for (tally, target) in zip(self.tallies_copy[:-1], tally_targets[1:-1]):
|
|
tally.anchor = target
|
|
|
|
self.remove(self.tallies_copy)
|
|
self.tallies.add(self.tallies_copy[-1])
|
|
|
|
|
|
def merge_rects_by_coloring(self):
|
|
|
|
merged_row = self.row.copy()
|
|
merged_row.coloring_level += 1
|
|
merged_row.generate_points()
|
|
merged_row.move_to(self.row)
|
|
|
|
self.play(FadeIn(merged_row))
|
|
self.remove(self.row)
|
|
self.row = merged_row
|
|
|
|
|
|
|
|
def move_tallies_on_top(self):
|
|
self.play(
|
|
self.tallies.shift, 1.2 * 0.5 * self.row.height * UP
|
|
)
|
|
for tally in self.tallies:
|
|
tally.anchor += 1.2 * 0.5 * self.row.height * UP
|
|
|
|
def create_pi_creature(self):
|
|
randy = CoinFlippingPiCreature(color = MAROON_E)
|
|
return randy
|
|
|
|
def construct(self):
|
|
|
|
randy = self.get_primary_pi_creature()
|
|
randy = randy.scale(0.5).move_to(3*DOWN + 6*LEFT)
|
|
#self.add(randy)
|
|
self.row = BrickRow(0, height = 2, width = 10)
|
|
self.wait()
|
|
|
|
self.play(FadeIn(self.row))
|
|
|
|
self.wait()
|
|
|
|
|
|
# move in all kinds of sequences
|
|
coin_seqs = VGroup()
|
|
for i in range(20):
|
|
n = np.random.randint(1,10)
|
|
seq = [np.random.choice(["H", "T"]) for j in range(n)]
|
|
coin_seq = CoinSequence(seq).scale(1.5)
|
|
loc = np.random.uniform(low = -10, high = 10) * RIGHT
|
|
loc += np.random.uniform(low = -6, high = 6) * UP
|
|
coin_seq.move_to(loc)
|
|
|
|
coin_seq.target = coin_seq.copy().scale(0.3).move_to(0.4 * loc)
|
|
coin_seq.target.fade(1)
|
|
coin_seqs.add(coin_seq)
|
|
|
|
self.play(
|
|
LaggedStart(
|
|
Succession, coin_seqs, lambda m: (FadeIn(m, run_time = 0.1), MoveToTarget(m)),
|
|
run_time = 5,
|
|
lag_ratio = 0.5
|
|
)
|
|
)
|
|
|
|
self.play(FlipCoin(randy) )
|
|
|
|
self.play(SplitRectsInBrickWall(self.row))
|
|
self.merge_rects_by_subdiv()
|
|
self.merge_rects_by_coloring()
|
|
#
|
|
# put tallies on top
|
|
|
|
single_flip_labels = VGroup(UprightHeads(), UprightTails())
|
|
for (label, rect) in zip(single_flip_labels, self.row.rects):
|
|
label.next_to(rect, UP)
|
|
self.play(FadeIn(label))
|
|
self.wait()
|
|
|
|
self.wait()
|
|
|
|
|
|
# # # # # # # #
|
|
# SECOND FLIP #
|
|
# # # # # # # #
|
|
|
|
self.play(FlipCoin(randy))
|
|
self.wait()
|
|
|
|
self.play(
|
|
SplitRectsInBrickWall(self.row)
|
|
)
|
|
self.wait()
|
|
|
|
|
|
# split sequences
|
|
single_flip_labels_copy = single_flip_labels.copy()
|
|
self.add(single_flip_labels_copy)
|
|
|
|
|
|
v = self.row.get_outcome_centers_for_level(2)[0] - single_flip_labels[0].get_center()
|
|
self.play(
|
|
single_flip_labels.shift, v
|
|
)
|
|
new_heads = VGroup(UprightHeads(), UprightHeads())
|
|
for i in range(2):
|
|
new_heads[i].move_to(single_flip_labels[i])
|
|
new_heads[i].shift(COIN_SEQUENCE_SPACING * DOWN)
|
|
self.play(FadeIn(new_heads))
|
|
|
|
v = self.row.get_outcome_centers_for_level(2)[-1] - single_flip_labels_copy[-1].get_center()
|
|
self.play(
|
|
single_flip_labels_copy.shift, v
|
|
)
|
|
new_tails = VGroup(UprightTails(), UprightTails())
|
|
for i in range(2):
|
|
new_tails[i].move_to(single_flip_labels_copy[i])
|
|
new_tails[i].shift(COIN_SEQUENCE_SPACING * DOWN)
|
|
self.play(FadeIn(new_tails))
|
|
|
|
|
|
decimal_tallies = VGroup()
|
|
# introduce notion of tallies
|
|
for (i, rect) in enumerate(self.row.get_rects_for_level(2)):
|
|
tally = DecimalTally(2-i, i)
|
|
tally.next_to(rect, UP)
|
|
decimal_tallies.add(tally)
|
|
self.play(FadeIn(tally))
|
|
self.wait()
|
|
|
|
self.add_foreground_mobject(single_flip_labels)
|
|
self.add_foreground_mobject(new_heads)
|
|
self.add_foreground_mobject(single_flip_labels_copy)
|
|
self.add_foreground_mobject(new_tails)
|
|
|
|
# show individual outcomes
|
|
outcomes = self.row.get_outcome_rects_for_level(2, with_labels = False)
|
|
|
|
|
|
self.play(
|
|
LaggedStart(FadeIn, outcomes)
|
|
)
|
|
self.wait()
|
|
self.play(
|
|
LaggedStart(FadeOut, outcomes),
|
|
)
|
|
self.wait()
|
|
self.play(
|
|
FadeOut(single_flip_labels),
|
|
FadeOut(new_heads),
|
|
FadeOut(single_flip_labels_copy),
|
|
FadeOut(new_tails)
|
|
)
|
|
self.wait()
|
|
|
|
self.tallies = VGroup()
|
|
for (i, rect) in enumerate(self.row.get_rects_for_level(2)):
|
|
tally = TallyStack(2-i, i, show_decimals = False)
|
|
tally.move_to(rect)
|
|
self.tallies.add(tally)
|
|
|
|
|
|
self.play(FadeIn(self.tallies))
|
|
self.wait()
|
|
|
|
anims = []
|
|
for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies):
|
|
anims.append(ApplyFunction(
|
|
tally_stack.position_decimal_tally, decimal_tally
|
|
))
|
|
|
|
self.play(*anims)
|
|
self.wait()
|
|
|
|
# replace the original decimal tallies with
|
|
# the ones that belong to the TallyStacks
|
|
for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies):
|
|
self.remove(decimal_tally)
|
|
tally_stack.position_decimal_tally(tally_stack.decimal_tally)
|
|
tally_stack.add(tally_stack.decimal_tally)
|
|
|
|
self.add_foreground_mobject(self.tallies)
|
|
self.merge_rects_by_subdiv()
|
|
self.wait()
|
|
self.merge_rects_by_coloring()
|
|
self.wait()
|
|
|
|
|
|
# # # # # # # # # # # # #
|
|
# CALLBACK TO SEQUENCES #
|
|
# # # # # # # # # # # # #
|
|
|
|
outcomes = self.row.get_outcome_rects_for_level(2, with_labels = True)
|
|
subdivs = self.row.get_sequence_subdivs_for_level(2)
|
|
self.play(
|
|
FadeIn(outcomes),
|
|
FadeIn(subdivs),
|
|
FadeOut(self.tallies)
|
|
)
|
|
|
|
self.wait()
|
|
|
|
rect_to_dice = outcomes[1]
|
|
N = 10
|
|
dice_width = rect_to_dice.get_width()/N
|
|
dice_height = rect_to_dice.get_height()/N
|
|
prototype_dice = Rectangle(
|
|
width = dice_width,
|
|
height = dice_height,
|
|
stroke_width = 2,
|
|
stroke_color = WHITE,
|
|
fill_color = WHITE,
|
|
fill_opacity = 0
|
|
)
|
|
prototype_dice.align_to(rect_to_dice, direction = UP)
|
|
prototype_dice.align_to(rect_to_dice, direction = LEFT)
|
|
all_dice = VGroup()
|
|
for i in range(N):
|
|
for j in range(N):
|
|
dice_copy = prototype_dice.copy()
|
|
dice_copy.shift(j * dice_width * RIGHT + i * dice_height * DOWN)
|
|
all_dice.add(dice_copy)
|
|
|
|
self.play(
|
|
LaggedStart(FadeIn, all_dice),
|
|
FadeOut(rect_to_dice.label)
|
|
)
|
|
|
|
self.wait()
|
|
|
|
table = Ellipse(width = 1.5, height = 1)
|
|
table.set_fill(color = GREEN_E, opacity = 1)
|
|
table.next_to(rect_to_dice, UP)
|
|
self.add(table)
|
|
coin1 = UprightHeads(radius = 0.1)
|
|
coin2 = UprightTails(radius = 0.1)
|
|
|
|
def get_random_point_in_ellipse(ellipse):
|
|
width = ellipse.get_width()
|
|
height = ellipse.get_height()
|
|
x = y = 1
|
|
while x**2 + y**2 > 0.9:
|
|
x = np.random.uniform(-1,1)
|
|
y = np.random.uniform(-1,1)
|
|
x *= width/2
|
|
y *= height/2
|
|
return ellipse.get_center() + x * RIGHT + y * UP
|
|
|
|
|
|
for dice in all_dice:
|
|
p1 = get_random_point_in_ellipse(table)
|
|
p2 = get_random_point_in_ellipse(table)
|
|
coin1.move_to(p1)
|
|
coin2.move_to(p2)
|
|
self.add(coin1, coin2)
|
|
self.play(
|
|
ApplyMethod(dice.set_fill, {"opacity" : 0.5},
|
|
rate_func = there_and_back,
|
|
run_time = 0.05)
|
|
)
|
|
|
|
|
|
self.wait()
|
|
|
|
self.play(
|
|
FadeOut(outcomes),
|
|
FadeOut(subdivs),
|
|
FadeOut(all_dice),
|
|
FadeOut(table),
|
|
FadeOut(coin1),
|
|
FadeOut(coin2),
|
|
FadeIn(self.tallies)
|
|
)
|
|
|
|
self.wait()
|
|
|
|
# # # # # # # #
|
|
# THIRD FLIP #
|
|
# # # # # # # #
|
|
|
|
# move row up, leace a copy without tallies below
|
|
new_row = self.row.copy()
|
|
self.clear()
|
|
self.add(randy, self.row, self.tallies)
|
|
self.bring_to_back(new_row)
|
|
self.play(
|
|
self.row.shift, 2.5 * UP,
|
|
self.tallies.shift, 2.5 * UP,
|
|
)
|
|
|
|
old_row = self.row
|
|
self.row = new_row
|
|
|
|
self.play(FlipCoin(randy))
|
|
|
|
self.wait()
|
|
|
|
self.play(
|
|
SplitRectsInBrickWall(self.row)
|
|
)
|
|
self.wait()
|
|
|
|
self.split_tallies_in_two_steps()
|
|
self.wait()
|
|
self.merge_rects_by_subdiv()
|
|
self.wait()
|
|
self.merge_tallies()
|
|
self.merge_rects_by_coloring()
|
|
self.wait()
|
|
self.move_tallies_on_top()
|
|
|
|
return
|
|
|
|
# show individual outcomes
|
|
outcomes = self.row.get_outcome_rects_for_level(3, with_labels = True)
|
|
self.play(
|
|
LaggedStart(FadeIn, outcomes)
|
|
)
|
|
self.wait()
|
|
self.play(
|
|
LaggedStart(FadeOut, outcomes)
|
|
)
|
|
|
|
|
|
# # # # # # # # # # # # # #
|
|
# # FOURTH FLIP IN DETAIL #
|
|
# # # # # # # # # # # # # #
|
|
|
|
|
|
|
|
# removing the tallies (boy are they sticky)
|
|
self.play(FadeOut(self.tallies))
|
|
self.remove(self.tallies, self.tallies_copy)
|
|
for tally in self.tallies:
|
|
self.remove_foreground_mobject(tally)
|
|
self.remove(tally)
|
|
for tally in self.tallies_copy:
|
|
self.remove_foreground_mobject(tally)
|
|
self.remove(tally)
|
|
|
|
# delete all the old crap hidden behind the row
|
|
# before we can move it
|
|
self.remove(*self.mobjects)
|
|
self.add(randy) #,self.decimals,self.decimal_copies)
|
|
|
|
|
|
previous_row = self.row.copy()
|
|
self.add(previous_row)
|
|
|
|
v = 1.25 * self.row.height * UP
|
|
self.play(
|
|
previous_row.shift, v,
|
|
#self.decimals.shift, v,
|
|
#self.decimal_copies.shift, v
|
|
)
|
|
|
|
self.add(self.row)
|
|
self.bring_to_back(self.row)
|
|
self.row.shift(v)
|
|
|
|
w = 1.5 * self.row.height * DOWN
|
|
self.play(
|
|
self.row.shift, w,
|
|
Animation(previous_row)
|
|
)
|
|
|
|
self.play(
|
|
SplitRectsInBrickWall(self.row)
|
|
)
|
|
self.wait()
|
|
|
|
self.merge_rects_by_subdiv()
|
|
|
|
self.wait()
|
|
|
|
n = 3 # level to split
|
|
k = 1 # tally to split
|
|
|
|
# show individual outcomes
|
|
outcomes = previous_row.get_outcome_rects_for_level(n, with_labels = False)
|
|
grouped_outcomes = VGroup()
|
|
index = 0
|
|
for i in range(n + 1):
|
|
size = choose(n,i)
|
|
grouped_outcomes.add(VGroup(outcomes[index:index + size]))
|
|
index += size
|
|
|
|
|
|
grouped_outcomes_copy = grouped_outcomes.copy()
|
|
|
|
original_grouped_outcomes = grouped_outcomes.copy()
|
|
# for later reference
|
|
|
|
self.play(
|
|
LaggedStart(FadeIn, grouped_outcomes),
|
|
LaggedStart(FadeIn, grouped_outcomes_copy),
|
|
)
|
|
self.wait()
|
|
|
|
# show how the outcomes in one tally split into two copies
|
|
# going into the neighboring tallies
|
|
|
|
#self.revert_to_original_skipping_status()
|
|
|
|
target_outcomes = self.row.get_outcome_rects_for_level(n + 1, with_labels = False)
|
|
grouped_target_outcomes = VGroup()
|
|
index = 0
|
|
old_tally_sizes = [choose(n,i) for i in range(n + 1)]
|
|
new_tally_sizes = [choose(n + 1,i) for i in range(n + 2)]
|
|
for i in range(n + 2):
|
|
size = new_tally_sizes[i]
|
|
grouped_target_outcomes.add(VGroup(target_outcomes[index:index + size]))
|
|
index += size
|
|
|
|
self.play(
|
|
Transform(grouped_outcomes[k][0],grouped_target_outcomes[k][0][old_tally_sizes[k - 1]:])
|
|
)
|
|
|
|
self.play(
|
|
Transform(grouped_outcomes_copy[k][0],grouped_target_outcomes[k + 1][0][:old_tally_sizes[k]])
|
|
)
|
|
|
|
old_tally_sizes.append(0) # makes the edge cases work properly
|
|
|
|
# split the other tallies
|
|
for i in range(k) + range(k + 1, n + 1):
|
|
self.play(
|
|
Transform(grouped_outcomes[i][0],
|
|
grouped_target_outcomes[i][0][old_tally_sizes[i - 1]:]
|
|
),
|
|
Transform(grouped_outcomes_copy[i][0],
|
|
grouped_target_outcomes[i + 1][0][:old_tally_sizes[i]]
|
|
)
|
|
)
|
|
|
|
|
|
self.wait()
|
|
|
|
# remove outcomes and sizes except for one tally
|
|
anims = []
|
|
for i in range(n + 1):
|
|
if i != k - 1:
|
|
anims.append(FadeOut(grouped_outcomes_copy[i]))
|
|
if i != k:
|
|
anims.append(FadeOut(grouped_outcomes[i]))
|
|
|
|
self.play(*anims)
|
|
|
|
self.wait()
|
|
|
|
self.play(
|
|
Transform(grouped_outcomes_copy[k - 1], original_grouped_outcomes[k - 1])
|
|
)
|
|
self.play(
|
|
Transform(grouped_outcomes[k], original_grouped_outcomes[k])
|
|
)
|
|
|
|
|
|
new_rects = self.row.get_rects_for_level(n + 1)
|
|
|
|
#decimals_copy = self.decimals.copy()
|
|
#decimals_copy2 = self.decimals.copy()
|
|
|
|
self.play(
|
|
Transform(grouped_outcomes[k][0],grouped_target_outcomes[k][0][old_tally_sizes[k - 1]:]),
|
|
Transform(grouped_outcomes_copy[k - 1][0],grouped_target_outcomes[k][0][:old_tally_sizes[k]]),
|
|
#decimals_copy[k - 1].move_to, new_rects[k],
|
|
#decimals_copy2[k].move_to, new_rects[k],
|
|
)
|
|
|
|
|
|
# # # # # # # #
|
|
# FIFTH FLIP #
|
|
# # # # # # # #
|
|
|
|
# self.remove(
|
|
# grouped_outcomes,
|
|
# grouped_outcomes_copy,
|
|
# grouped_target_outcomes,
|
|
# target_outcomes,
|
|
# outcomes,
|
|
# previous_row,
|
|
# original_grouped_outcomes)
|
|
self.clear()
|
|
self.add(randy, self.row)
|
|
#self.row.shift(0.5 * UP)
|
|
|
|
#return
|
|
|
|
self.merge_rects_by_coloring()
|
|
|
|
self.revert_to_original_skipping_status()
|
|
|
|
for i in range(1):
|
|
|
|
self.play(FlipCoin(randy))
|
|
|
|
self.wait()
|
|
|
|
self.play(
|
|
SplitRectsInBrickWall(self.row)
|
|
)
|
|
self.wait()
|
|
|
|
|
|
#self.split_tallies_at_once(direction = LEFT)
|
|
self.wait()
|
|
self.merge_rects_by_subdiv()
|
|
self.wait()
|
|
#self.merge_tallies(direction = LEFT)
|
|
self.merge_rects_by_coloring()
|
|
#self.merge_decimals()
|
|
self.wait()
|
|
|