Merge pull request #230 from 3b1b/eop

Eop
This commit is contained in:
Grant Sanderson 2018-05-09 14:03:28 -07:00 committed by GitHub
commit 169f5db9bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 616 additions and 370 deletions

View file

@ -47,18 +47,19 @@ class WriteOpeningWords(Scene):
class StartingCalc101(PiCreatureScene):
CONFIG = {
# "default_pi_creature_kwargs": {
# "color": BLUE,
# "flip_at_start": False,
# },
}
def construct(self):
randy = self.pi_creature
deriv_equation = TexMobject(
"\\frac{df}{dx}(x) = \\lim(\\Delta x \\to \\infty)" +
"{f(x + \\Delta x) - f(x) \\over \\Delta x}",
tex_to_color_map={"\\Delta x": BLUE}
deriv_string = "\\frac{df}{dx}(x) = \\lim(\\delta x \\to \\infty)" + \
"{f(x + \\delta x) - f(x) \\over \\delta x}"
equations = VGroup(
TexMobject(*break_up_string_by_terms(deriv_string, "\\delta x"))
)
self.add(deriv_equation)
equations = VGroup(deriv_equation)
title = TextMobject("Calculus 101")
title.to_edge(UP)
h_line = Line(LEFT, RIGHT)

View file

@ -0,0 +1,62 @@
from big_ol_pile_of_manim_imports import *
from active_projects.eop.reusable_imports import *
class ShuffleThroughAllSequences(Scene):
CONFIG = {
"nb_coins" : 14,
"run_time" : 5,
"fps" : int(1.0/PRODUCTION_QUALITY_FRAME_DURATION),
"coin_size" : 0.5,
"coin_spacing" : 0.65
}
def construct(self):
nb_frames = self.run_time * self.fps
nb_relevant_coins = int(np.log2(nb_frames)) + 1
print "relevant coins:", nb_relevant_coins
nb_idle_coins = self.nb_coins - nb_relevant_coins
idle_heads = CoinSequence(nb_idle_coins * ["H"],
radius = self.coin_size * 0.5,
spacing = self.coin_spacing)
idle_tails = CoinSequence(nb_idle_coins * ["T"],
radius = self.coin_size * 0.5,
spacing = self.coin_spacing)
idle_tails.fade(0.5)
idle_part = VGroup(idle_heads, idle_tails)
left_idle_part = CoinSequence(6 * ["H"],
radius = self.coin_size * 0.5,
spacing = self.coin_spacing)
self.add(idle_part, left_idle_part)
last_coin_seq = VGroup()
for i in range(2**nb_relevant_coins):
binary_seq = binary(i)
# pad to the left with 0s
nb_leading_zeroes = nb_relevant_coins - len(binary_seq)
for j in range(nb_leading_zeroes):
binary_seq.insert(0, 0)
seq2 = ["H" if x == 0 else "T" for x in binary_seq]
coin_seq = CoinSequence(seq2,
radius = self.coin_size * 0.5,
spacing = self.coin_spacing)
coin_seq.next_to(idle_part, LEFT, buff = self.coin_spacing - self.coin_size)
left_idle_part.next_to(coin_seq, LEFT, buff = self.coin_spacing - self.coin_size)
all_coins = VGroup(left_idle_part, coin_seq, idle_part)
all_coins.center()
self.remove(last_coin_seq)
self.add(coin_seq)
#self.wait(1.0/self.fps)
self.update_frame()
self.add_frames(self.get_frame())
last_coin_seq = coin_seq
print float(i)/2**nb_relevant_coins

View file

@ -84,7 +84,7 @@ class IllustrateAreaModelErf(GraphScene):
equals_sign = TexMobject("=").next_to(cdf_formula, buff = MED_LARGE_BUFF)
cdf_value = DecimalNumber(0, color = graph.color, num_decimal_points = 3)
cdf_value = DecimalNumber(0, color = graph.color, num_decimal_places = 3)
cdf_value.next_to(equals_sign)
self.play(
FadeIn(equals_sign),
@ -99,13 +99,13 @@ class IllustrateAreaModelErf(GraphScene):
self.add(ContinualChangingDecimal(
decimal_number_mobject = cdf_value,
number_update_func = integral_update_func,
num_decimal_points = 3
num_decimal_places = 3
))
self.add(ContinualChangingDecimal(
decimal_number_mobject = cdf_percentage,
number_update_func = integral_update_func_percent,
num_decimal_points = 1
num_decimal_places = 1
))

View file

@ -5,7 +5,7 @@ from active_projects.eop.reusable_imports import *
class BrickRowScene(PiCreatureScene):
def split_tallies(self, direction = DOWN):
def split_tallies(self, row, 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
@ -15,12 +15,12 @@ class BrickRowScene(PiCreatureScene):
tally_targets_left = [
rect.get_center() + 0.25 * rect.get_width() * LEFT
for rect in self.row.rects
for rect in row.rects
]
tally_targets_right = [
rect.get_center() + 0.25 * rect.get_width() * RIGHT
for rect in self.row.rects
for rect in row.rects
]
if np.all(direction == LEFT) or np.all(direction == RIGHT):
@ -63,7 +63,7 @@ class BrickRowScene(PiCreatureScene):
def tally_split_animations(self, direction = DOWN):
def tally_split_animations(self, row, 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
@ -73,12 +73,12 @@ class BrickRowScene(PiCreatureScene):
tally_targets_left = [
rect.get_center() + 0.25 * rect.get_width() * LEFT
for rect in self.row.rects
for rect in row.rects
]
tally_targets_right = [
rect.get_center() + 0.25 * rect.get_width() * RIGHT
for rect in self.row.rects
for rect in row.rects
]
if np.all(direction == LEFT) or np.all(direction == RIGHT):
@ -122,13 +122,14 @@ class BrickRowScene(PiCreatureScene):
return anims1, anims2
def split_tallies_at_once(self, direction = DOWN):
anims1, anims2 = self.tally_split_animations(direction = direction)
def split_tallies_at_once(self, row, direction = DOWN):
anims1, anims2 = self.tally_split_animations(row, direction = direction)
self.play(*(anims1 + anims2))
def split_tallies_in_two_steps(self, direction = DOWN):
def split_tallies_in_two_steps(self, row, direction = DOWN):
# First all those to the left, then those to the right
anims1, anims2 = self.tally_split_animations(direction = direction)
anims1, anims2 = self.tally_split_animations(row, direction = direction)
self.play(*anims1)
self.wait(0.3)
self.play(*anims2)
@ -136,31 +137,31 @@ class BrickRowScene(PiCreatureScene):
def merge_rects_by_subdiv(self):
def merge_rects_by_subdiv(self, row):
half_merged_row = self.row.copy()
half_merged_row = row.copy()
half_merged_row.subdiv_level += 1
half_merged_row.generate_points()
half_merged_row.move_to(self.row)
half_merged_row.move_to(row)
self.play(FadeIn(half_merged_row))
self.remove(self.row)
self.row = half_merged_row
self.remove(row)
return half_merged_row
def merge_tallies(self, target_pos = UP):
def merge_tallies(self, row, target_pos = UP):
r = self.row.subdiv_level
r = row.subdiv_level
if np.all(target_pos == DOWN):
tally_targets = [
rect.get_center()
for rect in self.row.get_rects_for_level(r)
for rect in row.get_rects_for_level(r)
]
elif np.all(target_pos == UP):
y_pos = self.row.get_center()[1] + 1.2 * 0.5 * self.row.get_height()
y_pos = row.get_center()[1] + 1.2 * 0.5 * row.get_height()
for target in tally_targets:
target[1] = y_pos
else:
@ -186,25 +187,25 @@ class BrickRowScene(PiCreatureScene):
self.tallies.add(self.tallies_copy[-1])
def merge_rects_by_coloring(self):
def merge_rects_by_coloring(self, row):
merged_row = self.row.copy()
merged_row = row.copy()
merged_row.coloring_level += 1
merged_row.generate_points()
merged_row.move_to(self.row)
merged_row.move_to(row)
self.play(FadeIn(merged_row))
self.remove(self.row)
self.row = merged_row
self.remove(row)
return merged_row
def move_tallies_on_top(self):
def move_tallies_on_top(self, row):
self.play(
self.tallies.shift, 1.2 * 0.5 * self.row.height * UP
self.tallies.shift, 1.2 * 0.5 * row.height * UP
)
for tally in self.tallies:
tally.anchor += 1.2 * 0.5 * self.row.height * UP
tally.anchor += 1.2 * 0.5 * row.height * UP
def create_pi_creature(self):
randy = CoinFlippingPiCreature(color = MAROON_E)
@ -256,12 +257,11 @@ class BrickRowScene(PiCreatureScene):
# # # # # # # #
self.play(FlipCoin(randy))
self.play(SplitRectsInBrickWall(self.row))
self.merge_rects_by_subdiv()
self.merge_rects_by_coloring()
self.row = self.merge_rects_by_subdiv(self.row)
self.row = self.merge_rects_by_coloring(self.row)
#
# put tallies on top
@ -312,7 +312,6 @@ class BrickRowScene(PiCreatureScene):
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)):
@ -347,6 +346,7 @@ class BrickRowScene(PiCreatureScene):
)
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)
@ -357,6 +357,7 @@ class BrickRowScene(PiCreatureScene):
self.play(FadeIn(self.tallies))
self.wait()
anims = []
for (decimal_tally, tally_stack) in zip(decimal_tallies, self.tallies):
anims.append(ApplyFunction(
@ -366,6 +367,7 @@ class BrickRowScene(PiCreatureScene):
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):
@ -374,9 +376,9 @@ class BrickRowScene(PiCreatureScene):
tally_stack.add(tally_stack.decimal_tally)
self.add_foreground_mobject(self.tallies)
self.merge_rects_by_subdiv()
self.row = self.merge_rects_by_subdiv(self.row)
self.wait()
self.merge_rects_by_coloring()
self.row = self.merge_rects_by_coloring(self.row)
self.wait()
@ -494,7 +496,7 @@ class BrickRowScene(PiCreatureScene):
)
self.wait()
self.split_tallies_in_two_steps()
self.split_tallies_in_two_steps(self.row)
self.wait()
self.add_foreground_mobject(self.tallies)
@ -554,7 +556,7 @@ class BrickRowScene(PiCreatureScene):
# self.wait()
# self.merge_rects_by_subdiv()
# self.row = self.merge_rects_by_subdiv(self.row)
# self.wait()
# self.play(
@ -575,9 +577,9 @@ class BrickRowScene(PiCreatureScene):
# self.wait()
# self.merge_tallies(target_pos = DOWN)
# self.merge_tallies(self.row, target_pos = DOWN)
# self.add_foreground_mobject(self.tallies)
# self.merge_rects_by_coloring()
# self.row = self.merge_rects_by_coloring(self.row)
# self.wait()
@ -645,7 +647,7 @@ class BrickRowScene(PiCreatureScene):
self.wait()
self.merge_rects_by_subdiv()
self.row = self.merge_rects_by_subdiv(self.row)
self.wait()
self.play(
@ -666,9 +668,9 @@ class BrickRowScene(PiCreatureScene):
self.wait()
self.merge_tallies(target_pos = DOWN)
self.merge_tallies(self.row, target_pos = DOWN)
self.add_foreground_mobject(self.tallies)
self.merge_rects_by_coloring()
self.row = self.merge_rects_by_coloring(self.row)
self.wait()
@ -677,11 +679,18 @@ class BrickRowScene(PiCreatureScene):
with_labels = True,
inset = True)
self.play(FadeOut(self.tallies))
self.play(LaggedStart(
FadeIn, outcomes))
self.wait()
self.play(LaggedStart(
FadeOut, outcomes))
FadeIn, outcomes,
#rate_func = there_and_back_with_pause,
run_time = 5))
self.wait()
self.play(LaggedStart(
FadeOut, outcomes,
#rate_func = there_and_back_with_pause,
run_time = 5))
self.wait()
self.play(FadeIn(self.tallies))
brace1 = Brace(self.row.rects[2], UP)
@ -705,48 +714,54 @@ class BrickRowScene(PiCreatureScene):
)
self.wait()
# put visuals for other probability distribtuions here
# back to three coin flips, show all 8 outcomes
run_time = 5
self.play(
LaggedStart(FadeIn, outcomes,
#rate_func = there_and_back_with_pause,
run_time = run_time),
FadeOut(self.tallies,
run_time = run_time)
)
self.wait()
self.play(
LaggedStart(FadeOut, outcomes,
#rate_func = there_and_back_with_pause,
run_time = 5),
FadeIn(self.tallies,
run_time = run_time)
)
# # # # # # # #
# FOURTH FLIP #
# # # # # # # #
# 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)
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.tallies.shift, v,
)
self.add_foreground_mobject(self.tallies)
self.play(
SplitRectsInBrickWall(self.row)
)
self.wait()
self.merge_rects_by_subdiv()
self.row = self.merge_rects_by_subdiv(self.row)
self.wait()
@ -754,7 +769,10 @@ class BrickRowScene(PiCreatureScene):
k = 1 # tally to split
# show individual outcomes
outcomes = previous_row.get_outcome_rects_for_level(n, with_labels = False)
outcomes = previous_row.get_outcome_rects_for_level(n,
with_labels = False,
inset = True
)
grouped_outcomes = VGroup()
index = 0
for i in range(n + 1):
@ -779,7 +797,10 @@ class BrickRowScene(PiCreatureScene):
#self.revert_to_original_skipping_status()
target_outcomes = self.row.get_outcome_rects_for_level(n + 1, with_labels = False)
target_outcomes = self.row.get_outcome_rects_for_level(n + 1,
with_labels = False,
inset = True
)
grouped_target_outcomes = VGroup()
index = 0
old_tally_sizes = [choose(n,i) for i in range(n + 1)]
@ -813,6 +834,13 @@ class BrickRowScene(PiCreatureScene):
self.wait()
# fade in new tallies
new_rects = self.row.get_rects_for_level(4)
new_tallies = VGroup(*[
TallyStack(n + 1 - i, i).move_to(rect) for (i, rect) in enumerate(new_rects)
])
self.play(FadeIn(new_tallies))
self.add_foreground_mobject(new_tallies[1])
# remove outcomes and sizes except for one tally
anims = []
for i in range(n + 1):
@ -820,6 +848,11 @@ class BrickRowScene(PiCreatureScene):
anims.append(FadeOut(grouped_outcomes_copy[i]))
if i != k:
anims.append(FadeOut(grouped_outcomes[i]))
anims.append(FadeOut(new_tallies[i]))
#anims.append(FadeOut(self.tallies[0]))
#anims.append(FadeOut(self.tallies[2:]))
anims.append(FadeOut(new_tallies[-1]))
self.play(*anims)
@ -828,64 +861,69 @@ class BrickRowScene(PiCreatureScene):
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],
Transform(grouped_outcomes_copy[k - 1][0],grouped_target_outcomes[k][0][:old_tally_sizes[k - 1]]),
)
self.play(
FadeOut(previous_row),
FadeOut(self.tallies),
)
self.row = self.merge_rects_by_coloring(self.row)
self.play(
FadeIn(new_tallies[0]),
FadeIn(new_tallies[2:]),
)
# # # # # # # #
# FIFTH FLIP #
# # # # # # # #
# self.remove(
# grouped_outcomes,
# grouped_outcomes_copy,
# grouped_target_outcomes,
# target_outcomes,
# outcomes,
# previous_row,
# original_grouped_outcomes)
# # # # # # # # # #
# EVEN MORE FLIPS #
# # # # # # # # # #
self.play(FadeOut(new_tallies))
self.clear()
self.add(randy, self.row)
#self.row.shift(0.5 * UP)
self.add(randy, self.row)
#return
self.merge_rects_by_coloring()
self.revert_to_original_skipping_status()
for i in range(1):
for i in range(3):
self.play(FlipCoin(randy))
self.wait()
previous_row = self.row.copy()
self.play(previous_row.shift, 1.25 * self.row.height * UP)
self.play(
SplitRectsInBrickWall(self.row)
)
self.wait()
#self.split_tallies_at_once(direction = LEFT)
self.row = self.merge_rects_by_subdiv(self.row)
self.wait()
self.merge_rects_by_subdiv()
self.wait()
#self.merge_tallies(direction = LEFT)
self.merge_rects_by_coloring()
#self.merge_decimals()
self.row = self.merge_rects_by_coloring(self.row)
self.wait()
self.play(FadeOut(previous_row))

View file

@ -1,29 +1,31 @@
from big_ol_pile_of_manim_imports import *
from active_projects.eop.reusable_imports import *
from active_projects.eop.chapter1.brick_row_scene import BrickRowScene
class EntireBrickWall(Scene):
class EntireBrickWall(BrickRowScene):
def construct(self):
self.remove(self.get_primary_pi_creature())
row_height = 0.3
nb_rows = 20
start_point = 3 * UP + 1 * LEFT
rows = VMobject()
rows.add(BrickRow(0, height = row_height))
rows[0].move_to(start_point)
rows.move_to(start_point)
self.add(rows)
zero_counter = Integer(0).next_to(start_point + 0.5 * rows[0].width * RIGHT)
nb_flips_text = TextMobject("\# of flips")
nb_flips_text.next_to(zero_counter, RIGHT, buff = LARGE_BUFF)
self.add(zero_counter, nb_flips_text)
flip_counters = VGroup(zero_counter)
for i in range(1,nb_rows + 1):
rows.add(BrickRow(i, height = row_height))
rows[-1].move_to(start_point + (i - 1) * row_height * DOWN)
for i in range(1, nb_rows + 1):
rows.add(rows[-1].copy())
self.bring_to_back(rows[-1])
anims = [
rows[-1].shift, row_height * DOWN,
@ -33,10 +35,17 @@ class EntireBrickWall(Scene):
if i % 5 == 0:
counter = Integer(i)
counter.next_to(rows[-1].get_right() + row_height * DOWN, RIGHT)
flip_counters.add(counter)
anims.append(FadeIn(counter))
self.play(*anims)
self.play(SplitRectsInBrickWall(rows[-1]))
rows.submobjects[-1] = self.merge_rects_by_subdiv(rows[-1])
rows.submobjects[-1] = self.merge_rects_by_coloring(rows[-1])
# draw indices under the last row for the number of tails
tails_counters = VGroup()
for (i, rect) in enumerate(rows[-1].rects):
@ -62,10 +71,73 @@ class EntireBrickWall(Scene):
FadeIn(nb_tails_text)
)
special_brick_copy = rows[-1].rects[13].copy()
# remove any hidden brick rows
self.clear()
self.add(nb_flips_text)
mobs_to_shift = VGroup(
rows, flip_counters, tails_counters, nb_tails_text,
)
self.play(mobs_to_shift.shift, 3 * UP)
last_row_rect = SurroundingRectangle(rows[-1], buff = 0)
last_row_rect.set_stroke(color = YELLOW, width = 6)
self.play(
rows.fade, 0.9,
FadeIn(special_brick_copy)
ShowCreation(last_row_rect)
)
def highlighted_brick(row = 20, nb_tails = 10):
brick_copy = rows[row].rects[nb_tails].copy()
brick_copy.set_fill(color = YELLOW, opacity = 0.8)
prob_percentage = float(choose(row, nb_tails)) / 2**row * 100
brick_label = DecimalNumber(prob_percentage,
unit = "\%", num_decimal_places = 1, color = BLACK)
brick_label.move_to(brick_copy)
brick_label.scale_to_fit_height(0.8 * brick_copy.get_height())
return VGroup(brick_copy, brick_label)
highlighted_bricks = [
highlighted_brick(row = 20, nb_tails = i)
for i in range(20)
]
self.play(
FadeIn(highlighted_bricks[10])
)
self.play(
FadeOut(highlighted_bricks[10]),
FadeIn(highlighted_bricks[9]),
FadeIn(highlighted_bricks[11]),
)
self.play(
FadeOut(highlighted_bricks[9]),
FadeOut(highlighted_bricks[11]),
FadeIn(highlighted_bricks[8]),
FadeIn(highlighted_bricks[12]),
)

View file

@ -9,6 +9,7 @@ class GenericMorphBrickRowIntoHistogram(Scene):
"bar_width" : 2.0,
"bar_anchor_height" : -3.0,
"show_tallies" : False,
"show_nb_flips" : True
}
def construct(self):
@ -25,13 +26,23 @@ class GenericMorphBrickRowIntoHistogram(Scene):
for (i,brick) in enumerate(self.row.rects):
tally = TallyStack(self.level - i, i)
tally.next_to(brick, UP)
tally.move_to(brick)
self.add(tally)
tallies.add(tally)
brick.set_stroke(width = 3)
if self.show_nb_flips:
nb_flips_text = TextMobject("\# of flips: " + str(self.level))
nb_flips_text.to_corner(UR)
self.add(nb_flips_text)
self.remove(self.row.subdivs, self.row.border)
for rect in self.row.rects:
rect.set_stroke(color = WHITE, width = 3)
self.play(self.row.rects.space_out_submobjects, {"factor" : 1.3})
anims = []
for brick in self.row.rects:
anims.append(brick.rotate)
@ -41,7 +52,7 @@ class GenericMorphBrickRowIntoHistogram(Scene):
anims.append(FadeOut(tallies))
self.play(*anims)
anims = []
for (i,brick) in enumerate(self.row.rects):
anims.append(brick.next_to)
@ -50,11 +61,10 @@ class GenericMorphBrickRowIntoHistogram(Scene):
self.play(*anims)
self.bars.create_outline()
anims = []
for bar in self.bars.submobjects:
anims.append(bar.set_stroke)
anims.append({"width" : 0})
anims = [
ApplyMethod(rect.set_stroke, {"width" : 0})
for rect in self.bars
]
anims.append(FadeIn(self.bars.outline))
self.play(*anims)
@ -67,7 +77,8 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram):
"prob_denominator" : 8,
"bar_width" : 2.0,
"bar_anchor_height" : -3.0,
"show_tallies" : True
"show_tallies" : True,
"show_nb_flips" : False
}
def construct(self):
@ -89,56 +100,72 @@ class MorphBrickRowIntoHistogram3(GenericMorphBrickRowIntoHistogram):
nb_tails_label = TextMobject("\# of tails")
nb_tails_label.next_to(x_labels[-1], RIGHT, MED_LARGE_BUFF)
self.play(
FadeIn(x_axis),
FadeIn(x_labels),
FadeIn(nb_tails_label)
)
# draw y-guides
y_guides = VMobject()
for i in range(1,self.prob_denominator + 1):
for i in range(0,self.prob_denominator + 1):
y_guide = Line(5 * LEFT, 5 * RIGHT, stroke_color = GRAY)
y_guide.move_to(self.bar_anchor_height * UP + i * float(self.row.width) / self.prob_denominator * UP)
y_guide_label = TexMobject("{" + str(i) + "\over " + str(self.prob_denominator) + "}", color = GRAY)
y_guide_label.scale(0.7)
y_guide_label.next_to(y_guide, LEFT)
y_guide.add(y_guide_label)
if i != 0:
y_guide.add(y_guide_label)
y_guides.add(y_guide)
self.bring_to_back(y_guides)
self.play(FadeIn(y_guides), Animation(self.bars))
total_area_text = TextMobject("total area = 1", color = YELLOW)
total_area_rect = SurroundingRectangle(total_area_text,
buff = MED_SMALL_BUFF,
fill_opacity = 0.5,
fill_color = BLACK,
stroke_color = YELLOW
self.play(
FadeIn(y_guides),
Animation(self.bars.outline),
Animation(self.bars)
)
self.play(
Write(total_area_text),
FadeIn(x_axis),
FadeIn(x_labels),
FadeIn(nb_tails_label)
)
self.add_foreground_mobject(nb_tails_label)
area_color = YELLOW
total_area_text = TextMobject("total area =", color = area_color)
area_decimal = DecimalNumber(0, color = area_color, num_decimal_places = 3)
area_decimal.next_to(total_area_text, RIGHT)
total_area_group = VGroup(total_area_text, area_decimal)
total_area_group.move_to(2.7 * UP)
self.play(
FadeIn(total_area_text),
)
cumulative_areas = [0.125, 0.5, 0.875, 1]
covering_rects = self.bars.copy()
for (i,rect) in enumerate(covering_rects):
rect.set_fill(color = area_color, opacity = 0.5)
self.play(
FadeIn(rect, rate_func = linear),
ChangeDecimalToValue(area_decimal, cumulative_areas[i],
rate_func = linear)
)
self.wait(0.2)
self.wait()
total_area_rect = SurroundingRectangle(
total_area_group,
buff = MED_SMALL_BUFF,
stroke_color = area_color
)
self.play(
FadeOut(covering_rects),
ShowCreation(total_area_rect)
)
prob_dist_text = TextMobject("probability distribution", color = YELLOW)
prob_dist_text.to_corner(UP, buff = LARGE_BUFF)
prob_dist_rect = SurroundingRectangle(prob_dist_text,
buff = MED_SMALL_BUFF,
stroke_color = YELLOW
)
self.play(
Write(prob_dist_text),
ShowCreation(prob_dist_rect)
)
class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
@ -165,9 +192,9 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
label.next_to(self.bar_anchors[i], DOWN)
x_labels.add(label)
nb_tails_label = TextMobject("\# of heads")
nb_tails_label.next_to(x_labels[-1], RIGHT, MED_LARGE_BUFF)
nb_tails_label = TextMobject("\# of tails")
nb_tails_label.move_to(5 * RIGHT + 2.5 * DOWN)
self.play(
FadeIn(x_axis),
FadeIn(x_labels),
@ -186,7 +213,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
y_guide_height = self.bar_anchor_height + i * float(self.row.width)
y_guide_heights.append(y_guide_height)
y_guide.move_to(y_guide_height * UP)
y_guide_label = DecimalNumber(i, num_decimal_points = 2, color = GRAY)
y_guide_label = DecimalNumber(i, num_decimal_places = 2, color = GRAY)
y_guide_label.scale(0.7)
y_guide_label.next_to(y_guide, LEFT)
y_guide.add(y_guide_label)
@ -199,7 +226,7 @@ class MorphBrickRowIntoHistogram20(GenericMorphBrickRowIntoHistogram):
histogram_height = self.bars.get_height()
# scale to fit screen
self.scale_x = 10.0/(len(self.bars) * self.bar_width)
self.scale_x = 10.0/((len(self.bars) - 1) * self.bar_width)
self.scale_y = 6.0/histogram_height

View file

@ -14,15 +14,25 @@ class ProbabilityDistributions(PiCreatureScene):
def construct(self):
lag_ratio = 0.2
run_time = 5
run_time = 3
text = TextMobject("Probability distributions", color = YELLOW)
text.to_edge(UP)
text_rect = SurroundingRectangle(text, buff = MED_SMALL_BUFF)
self.play(
FadeIn(text),
ShowCreation(text_rect)
)
# WEATHER FORECAST
unit_rect = Rectangle(
height = 4, width = 4
)
height = 3, width = 3
).shift(DOWN)
p_rain = 0.23
p_sun = 1 - p_rain
@ -38,7 +48,7 @@ class ProbabilityDistributions(PiCreatureScene):
sun_rect.set_fill(color = YELLOW, opacity = opacity)
sun_rect.set_stroke(width = 0)
self.add(unit_rect, rain_rect, sun_rect)
self.play(FadeIn(VGroup(unit_rect, rain_rect, sun_rect)))
rain = SVGMobject(file_name = "rain").scale(0.35)
sun = SVGMobject(file_name = "sun").scale(0.35)
@ -189,7 +199,8 @@ class ProbabilityDistributions(PiCreatureScene):
coin_flip_rect.add(braces, labels)
coin_flip_rect.target = coin_flip_rect.copy().scale(0.6)
coin_flip_rect.target.to_corner(UR, buff = LARGE_BUFF)
coin_flip_rect.target.to_corner(UR, buff = MED_LARGE_BUFF)
coin_flip_rect.target.shift(DOWN)
self.play(
MoveToTarget(coin_flip_rect)
@ -255,25 +266,3 @@ class ProbabilityDistributions(PiCreatureScene):
rate_func=there_and_back_with_pause,
run_time=run_time
)

View file

@ -1,12 +1,14 @@
from big_ol_pile_of_manim_imports import *
from active_projects.eop.reusable_imports import *
from active_projects.eop.independence import *
from for_3b1b_videos.pi_class import PiCreatureClass
class QuizResult(Scene):
class QuizResult(PiCreatureScene):
CONFIG = {
"pi_creatures_start_on_screen" : False,
"random_seed" : 6
}
def construct(self):
@ -23,14 +25,15 @@ class QuizResult(Scene):
return quiz
highlight_color = YELLOW
highlight_color = WHITE
nb_students_x = 5
nb_students_y = 3
spacing_students_x = 2.0
spacing_students_y = 2.2
all_students = VGroup()
all_students = PiCreatureClass(
width = nb_students_x, height = nb_students_y)# VGroup()
student_points = []
grades = []
grades_count = []
@ -39,9 +42,10 @@ class QuizResult(Scene):
for j in range(nb_students_y):
x = i * spacing_students_x
y = j * spacing_students_y
pi = PiCreature().scale(0.3)
pi.move_to([x,y,0])
all_students.add(pi)
#pi = PiCreature().scale(0.3)
#pi.move_to([x,y,0])
#all_students.add(pi)
all_students[i*nb_students_y + j].move_to([x,y,0])
q1 = np.random.choice([True, False])
q2 = np.random.choice([True, False])
q3 = np.random.choice([True, False])
@ -55,7 +59,8 @@ class QuizResult(Scene):
all_students.move_to(ORIGIN)
self.add(all_students)
self.pi_creatures = all_students
self.play(FadeIn(all_students))
all_quizzes = VGroup()
@ -133,17 +138,20 @@ class QuizResult(Scene):
)
grade_hist.move_to(all_students)
self.play(FadeIn(grade_hist))
self.play(
FadeIn(grade_hist),
FadeOut(all_students)
)
nb_students_label = TextMobject("\# of students", color = highlight_color)
nb_students_label.move_to(3 * LEFT + 2 * UP)
nb_students_label.move_to(5 * LEFT + 2 * UP)
arrows = VGroup(*[
Arrow(nb_students_label, grade_hist.bars[i].get_center(),
Arrow(nb_students_label.get_right(), grade_hist.bars[i].get_center(),
color = highlight_color)
for i in range(4)
])
self.play(Write(nb_students_label), LaggedStart(ShowCreation,arrows))
self.play(Write(nb_students_label), LaggedStart(GrowArrow,arrows))
percentage_label = TextMobject("\% of students", color = highlight_color)
percentage_label.move_to(nb_students_label)
@ -151,10 +159,11 @@ class QuizResult(Scene):
anims = []
for (label, percentage) in zip(grade_hist.y_labels_group, percentages):
new_label = DecimalNumber(percentage,
num_decimal_points = 1,
num_decimal_places = 1,
unit = "\%",
color = highlight_color
)
new_label.scale(0.7)
new_label.move_to(label)
anims.append(Transform(label, new_label))
anims.append(ReplacementTransform(nb_students_label, percentage_label))
@ -174,8 +183,8 @@ class QuizResult(Scene):
prob_label.move_to(percentage_label)
self.play(
all_students[8].set_color, MAROON_E,
all_students[:8].fade, 0.6,
all_students[9:].fade, 0.6,
#all_students[:8].fade, 0.6,
#all_students[9:].fade, 0.6,
ReplacementTransform(percentage_label, prob_label)
)
@ -184,12 +193,32 @@ class QuizResult(Scene):
FadeOut(arrows)
)
for i in range(1):
self.play(
FlashThroughHistogram(
flash_hist = FlashThroughHistogram(
grade_hist,
direction = "vertical",
mode = "random",
run_time = 5
cell_opacity = 0.5,
run_time = 5,
rate_func = linear
)
)
flash_class = FlashThroughClass(
all_students,
mode = "random",
highlight_color = MAROON_E,
run_time = 5,
rate_func = linear
)
for i in range(3):
self.play(flash_hist, flash_class)
self.remove(flash_hist.prototype_cell)

View file

@ -11,7 +11,7 @@ class BrickRow(VMobject):
"height" : 1.0,
"width" : 8.0,
"outcome_shrinkage_factor_x" : 0.95,
"outcome_shrinkage_factor_y" : 0.95
"outcome_shrinkage_factor_y" : 0.94
}
def __init__(self, n, **kwargs):
@ -104,12 +104,12 @@ class BrickRow(VMobject):
outcome_width = float(self.width) / (2 ** r)
outcome_height = self.height
corner_radius = 0 # min(0.1, 0.3 * min(outcome_width, outcome_height))
corner_radius = min(0.1, 0.3 * min(outcome_width, outcome_height))
# this scales down the corner radius for very narrow rects
rect = Rectangle( # RoundedRectangle(
rect = RoundedRectangle(
width = outcome_width,
height = outcome_height,
#corner_radius = corner_radius,
corner_radius = corner_radius,
fill_color = WHITE,
fill_opacity = 0.2,
stroke_width = 0
@ -205,13 +205,3 @@ class SplitRectsInBrickWall(AnimationGroup):
# def update_mobject(self, alpha):
# for subdiv in self.subdivs:
# x = subdiv.get_start()[0]
# start = self.mobject.get_center()
# start += x * RIGHT + 0.5 * self.mobject.get_height() * UP
# end = start + alpha * self.mobject.get_height() * DOWN
# subdiv.put_start_and_end_on(start,end)

View file

@ -201,7 +201,10 @@ class FlashThroughHistogram(Animation):
"hist_opacity" : 0.2
}
def __init__(self, mobject, direction = "horizontal", mode = "random", **kwargs):
def __init__(self, mobject,
direction = "horizontal",
mode = "random",
**kwargs):
digest_config(self, kwargs)
@ -277,6 +280,15 @@ class FlashThroughHistogram(Animation):
self.mobject.remove(self.prototype_cell)
def clean_up(self, surrounding_scene = None):
Animation.clean_up(self, surrounding_scene)
self.update(1)
if surrounding_scene is not None:
if self.is_remover():
surrounding_scene.remove(self.prototype_cell)
else:
surrounding_scene.add(self.prototype_cell)
return self
@ -290,7 +302,7 @@ class OutlineableBars(VGroup):
# We use this to morph a row of bricks into a histogram.
CONFIG = {
"outline_stroke_width" : 5,
"outline_stroke_width" : 3,
"stroke_color" : WHITE
}
def create_outline(self, animated = False, **kwargs):

View file

@ -37,6 +37,7 @@ class UprightTails(UprightCoin):
class CoinSequence(VGroup):
CONFIG = {
"sequence": [],
"radius" : COIN_RADIUS,
"spacing": COIN_SEQUENCE_SPACING,
"direction": RIGHT
}
@ -47,11 +48,11 @@ class CoinSequence(VGroup):
offset = 0
for symbol in self.sequence:
if symbol == "H":
new_coin = UprightHeads()
new_coin = UprightHeads(radius = self.radius)
elif symbol == "T":
new_coin = UprightTails()
new_coin = UprightTails(radius = self.radius)
else:
new_coin = UprightCoin(symbol = symbol)
new_coin = UprightCoin(symbol = symbol, radius = self.radius)
new_coin.shift(offset * self.direction)
self.add(new_coin)
offset += self.spacing

View file

@ -10,7 +10,7 @@ from utils.config_ops import digest_config
class ChangingDecimal(Animation):
CONFIG = {
"num_decimal_points": None,
"num_decimal_places": None,
"show_ellipsis": None,
"position_update_func": None,
"tracked_mobject": None,
@ -21,7 +21,7 @@ class ChangingDecimal(Animation):
self.decimal_number_config = dict(
decimal_number_mobject.initial_config
)
for attr in "num_decimal_points", "show_ellipsis":
for attr in "num_decimal_places", "show_ellipsis":
value = getattr(self, attr)
if value is not None:
self.decimal_number_config[attr] = value

View file

@ -151,11 +151,12 @@ def handle_scene(scene, **config):
if config["show_file_in_finder"]:
commands.append("-R")
#
if config["show_last_frame"]:
commands.append(scene.get_image_file_path())
else:
commands.append(scene.get_movie_file_path())
#commands.append("-g")
FNULL = open(os.devnull, 'w')
sp.call(commands, stdout=FNULL, stderr=sp.STDOUT)
FNULL.close()
@ -223,8 +224,11 @@ def get_module_posix(file_name):
module_name = file_name.replace(".py", "")
last_module = imp.load_module(".", *imp.find_module("."))
for part in module_name.split(os.sep):
load_args = imp.find_module(part, last_module.__path__)
last_module = imp.load_module(part, *load_args)
try:
load_args = imp.find_module(part, last_module.__path__)
last_module = imp.load_module(part, *load_args)
except ImportError:
continue
return last_module

View file

@ -0,0 +1,23 @@
import numpy as np
import warnings
from constants import *
from mobject.types.vectorized_mobject import VGroup
from for_3b1b_videos.pi_creature import PiCreature
class PiCreatureClass(VGroup):
CONFIG = {
"width" : 3,
"height" : 2
}
def __init__(self, **kwargs):
VGroup.__init__(self, **kwargs)
for i in range(self.width):
for j in range(self.height):
pi = PiCreature().scale(0.3)
pi.move_to(i*DOWN + j* RIGHT)
self.add(pi)

View file

@ -6,6 +6,7 @@ from mobject.mobject import Group
from mobject.svg.drawings import SpeechBubble
from animation.animation import Animation
from animation.creation import ShowCreation
from animation.creation import Write
from animation.composition import AnimationGroup
@ -16,6 +17,8 @@ from utils.config_ops import digest_config
from utils.rate_functions import squish_rate_func
from utils.rate_functions import there_and_back
from for_3b1b_videos.pi_class import PiCreatureClass
class Blink(ApplyMethod):
CONFIG = {
@ -101,3 +104,46 @@ class RemovePiCreatureBubble(AnimationGroup):
self.pi_creature.bubble = None
if surrounding_scene is not None:
surrounding_scene.add(self.pi_creature)
class FlashThroughClass(Animation):
CONFIG = {
"highlight_color" : GREEN,
}
def __init__(self, mobject, mode = "linear", **kwargs):
if not isinstance(mobject, PiCreatureClass):
raise Exception("FlashThroughClass mobject must be a PiCreatureClass")
digest_config(self, kwargs)
self.indices = range(mobject.height * mobject.width)
if mode == "random":
np.random.shuffle(self.indices)
Animation.__init__(self, mobject, **kwargs)
def update_mobject(self, alpha):
index = int(np.floor(alpha * self.mobject.height * self.mobject.width))
for pi in self.mobject:
pi.set_color(BLUE_E)
if index < self.mobject.height * self.mobject.width:
self.mobject[self.indices[index]].set_color(self.highlight_color)

View file

@ -139,7 +139,7 @@ class Matrix(VMobject):
class DecimalMatrix(Matrix):
CONFIG = {
"element_to_mobject": DecimalNumber,
"element_to_mobject_config": {"num_decimal_points": 1}
"element_to_mobject_config": {"num_decimal_places": 1}
}

View file

@ -623,13 +623,17 @@ class Mobject(Container):
values = []
values += [
mob.reduce_across_dimension(points_func, reduce_func, dim)
for mob in self.submobjects
for mob in self.nonempty_submobjects()
]
try:
return reduce_func(values)
except:
return 0
def nonempty_submobjects(self):
return [submob for submob in self.submobjects
if len(submob.submobjects) != 0 or len(submob.points) != 0]
def get_merged_array(self, array_attr):
result = None
for mob in self.family_members_with_points():
@ -745,6 +749,7 @@ class Mobject(Container):
def submobject_family(self):
sub_families = map(Mobject.submobject_family, self.submobjects)
all_mobjects = [self] + list(it.chain(*sub_families))
#all_mobjects = list(it.chain(*sub_families)) + [self]
return remove_list_redundancies(all_mobjects)
def family_members_with_points(self):

View file

@ -8,7 +8,7 @@ from mobject.types.vectorized_mobject import VMobject
class DecimalNumber(VMobject):
CONFIG = {
"num_decimal_points": 2,
"num_decimal_places": 2,
"digit_to_digit_buff": 0.05,
"show_ellipsis": False,
"unit": None, # Aligned to bottom unless it starts with "^"
@ -18,7 +18,7 @@ class DecimalNumber(VMobject):
def __init__(self, number, **kwargs):
VMobject.__init__(self, **kwargs)
self.number = number
ndp = self.num_decimal_points
ndp = self.num_decimal_places
# Build number string
if isinstance(number, complex):
@ -71,5 +71,5 @@ class DecimalNumber(VMobject):
class Integer(DecimalNumber):
CONFIG = {
"num_decimal_points": 0,
"num_decimal_places": 0,
}

View file

@ -5,6 +5,7 @@ from svg_mobject import VMobjectFromSVGPathstring
from utils.config_ops import digest_config
from utils.strings import split_string_list_to_isolate_substring
from utils.tex_file_writing import tex_to_svg_file
from mobject.geometry import Line
from mobject.types.vectorized_mobject import VGroup
from mobject.types.vectorized_mobject import VectorizedPoint
@ -290,3 +291,27 @@ class TexMobjectFromPresetString(TexMobject):
TexMobject.__init__(self, self.tex, **kwargs)
self.set_color(self.color)
class Title(TextMobject):
CONFIG = {
"scale_factor": 1,
"include_underline": True,
"underline_width": FRAME_WIDTH - 2,
# This will override underline_width
"match_underline_width_to_text": False,
"underline_buff": MED_SMALL_BUFF,
}
def __init__(self, text, **kwargs):
TextMobject.__init__(self, text, **kwargs)
self.scale(self.scale_factor)
self.to_edge(UP)
if self.include_underline:
underline = Line(LEFT, RIGHT)
underline.next_to(self, DOWN, buff=self.underline_buff)
if self.match_underline_width_to_text:
underline.match_width(self)
else:
underline.scale_to_fit_width(self.underline_width)
self.add(underline)
self.underline = underline

View file

@ -565,7 +565,7 @@ def walker_animation_with_display(
number_update_func = None,
show_arrows = True,
scale_arrows = False,
num_decimal_points = 1,
num_decimal_places = 1,
include_background_rectangle = True,
**kwargs
):
@ -581,7 +581,7 @@ def walker_animation_with_display(
if number_update_func != None:
display = DecimalNumber(0,
num_decimal_points = num_decimal_points,
num_decimal_places = num_decimal_places,
fill_color = WHITE if include_background_rectangle else BLACK,
include_background_rectangle = include_background_rectangle)
if include_background_rectangle:
@ -732,7 +732,7 @@ class PiWalker(ColorMappedByFuncScene):
"show_num_plane" : False,
"draw_lines" : True,
"num_checkpoints" : 10,
"num_decimal_points" : 1,
"num_decimal_places" : 1,
"include_background_rectangle" : False,
}
@ -788,7 +788,7 @@ class PiWalker(ColorMappedByFuncScene):
number_update_func = number_update_func,
run_time = self.step_run_time,
walker_stroke_color = WALKER_LIGHT_COLOR if self.color_foreground_not_background else BLACK,
num_decimal_points = self.num_decimal_points,
num_decimal_places = self.num_decimal_places,
include_background_rectangle = self.include_background_rectangle,
)
@ -2751,7 +2751,7 @@ class OneFifthTwoFifthWinder(SpecifiedWinder):
"step_size" : 0.01,
"show_num_plane" : False,
"step_run_time" : 6,
"num_decimal_points" : 2,
"num_decimal_places" : 2,
}
class OneFifthOneFifthWinderWithReset(OneFifthTwoFifthWinder):

View file

@ -386,7 +386,7 @@ class Introduce1DFunctionCase(Scene):
)
decimal = DecimalNumber(
0,
num_decimal_points = 3,
num_decimal_places = 3,
show_ellipsis = True,
)
decimal.scale(0.7)
@ -484,7 +484,7 @@ class Introduce1DFunctionCase(Scene):
if show_decimal:
decimal = DecimalNumber(
axes.x_axis.point_to_number(arrow.get_start()),
num_decimal_points = 3,
num_decimal_places = 3,
# show_ellipsis = True,
)
height = self.rect.get_height()
@ -2310,7 +2310,7 @@ class TransitionFromPathsToBoundaries(ColorMappedObjectsScene):
)
)
label = DecimalNumber(0, num_decimal_points = 1)
label = DecimalNumber(0, num_decimal_places = 1)
label_upadte = ContinualChangingDecimal(
label, get_total_winding,
position_update_func = lambda l : l.next_to(dot, UP+LEFT, SMALL_BUFF)

View file

@ -119,7 +119,7 @@ class LightIndicator(VMobject):
self.foreground.set_stroke(color=INDICATOR_STROKE_COLOR,width=INDICATOR_STROKE_WIDTH)
self.add(self.background, self.foreground)
self.reading = DecimalNumber(self.intensity,num_decimal_points = self.precision)
self.reading = DecimalNumber(self.intensity,num_decimal_places = self.precision)
self.reading.set_fill(color=INDICATOR_TEXT_COLOR)
self.reading.move_to(self.get_center())
if self.show_reading:
@ -287,7 +287,7 @@ class IntroScene(PiCreatureScene):
equals_sign = self.euler_sum.get_part_by_tex("=")
self.partial_sum_decimal = DecimalNumber(partial_results_values[1],
num_decimal_points = 2)
num_decimal_places = 2)
self.partial_sum_decimal.next_to(equals_sign, RIGHT)
@ -313,7 +313,7 @@ class IntroScene(PiCreatureScene):
self.partial_sum_decimal,
partial_results_values[i+1],
run_time = self.duration,
num_decimal_points = 6,
num_decimal_places = 6,
show_ellipsis = True,
position_update_func = lambda m: m.next_to(equals_sign, RIGHT)
)
@ -863,7 +863,7 @@ class SingleLighthouseScene(PiCreatureScene):
# angle msmt (decimal number)
self.angle_indicator = DecimalNumber(arc_angle / DEGREES,
num_decimal_points = 0,
num_decimal_places = 0,
unit = "^\\circ",
fill_opacity = 1.0,
fill_color = WHITE)
@ -4262,7 +4262,7 @@ class LabeledArc(Arc):
Arc.__init__(self,angle,**kwargs)
label = DecimalNumber(self.length, num_decimal_points = 0)
label = DecimalNumber(self.length, num_decimal_places = 0)
r = BUFFER * self.radius
theta = self.start_angle + self.angle/2
label_pos = r * np.array([np.cos(theta), np.sin(theta), 0])

View file

@ -94,7 +94,7 @@ class LightIndicator(Mobject):
self.foreground.set_fill(color = self.fill_color)
self.add(self.background, self.foreground)
self.reading = DecimalNumber(self.intensity,num_decimal_points = self.precision)
self.reading = DecimalNumber(self.intensity,num_decimal_places = self.precision)
self.reading.set_fill(color=INDICATOR_TEXT_COLOR)
self.reading.scale_to_fit_height(self.reading_height)
self.reading.move_to(self.get_center())
@ -317,7 +317,7 @@ class IntroScene(PiCreatureScene):
partial_sum_decimal = self.partial_sum_decimal = DecimalNumber(
series_terms[1],
num_decimal_points = 2
num_decimal_places = 2
)
partial_sum_decimal.next_to(equals_sign, RIGHT)
@ -418,7 +418,7 @@ class IntroScene(PiCreatureScene):
partial_sum_decimal,
series_terms[i+1],
run_time = 1,
num_decimal_points = 6,
num_decimal_places = 6,
position_update_func = lambda m: m.next_to(equals_sign, RIGHT)
)
]
@ -430,7 +430,7 @@ class IntroScene(PiCreatureScene):
ChangeDecimalToValue(
partial_sum_decimal,
series_terms[i+1],
num_decimal_points = 6,
num_decimal_places = 6,
),
]
if i == 5:
@ -451,7 +451,7 @@ class IntroScene(PiCreatureScene):
ChangeDecimalToValue(
partial_sum_decimal,
series_terms[-1],
num_decimal_points = 6,
num_decimal_places = 6,
),
morty.change, "confused",
)
@ -1295,7 +1295,7 @@ class IntroduceScreen(Scene):
self.angle_indicator = DecimalNumber(
arc_angle / DEGREES,
num_decimal_points = 0,
num_decimal_places = 0,
unit = "^\\circ"
)
self.angle_indicator.next_to(self.angle_arc, RIGHT)
@ -3818,7 +3818,7 @@ class ThinkBackToHowAmazingThisIs(ThreeDScene):
dot_pairs = it.starmap(VGroup, zip(positive_dots, negative_dots))
# Decimal
decimal = DecimalNumber(0, num_decimal_points = 6)
decimal = DecimalNumber(0, num_decimal_places = 6)
decimal.to_edge(UP)
terms = [2./(n**2) for n in range(1, 100, 2)]
partial_sums = np.cumsum(terms)
@ -4250,7 +4250,7 @@ class LabeledArc(Arc):
Arc.__init__(self,angle,**kwargs)
label = DecimalNumber(self.length, num_decimal_points = 0)
label = DecimalNumber(self.length, num_decimal_places = 0)
r = BUFFER * self.radius
theta = self.start_angle + self.angle/2
label_pos = r * np.array([np.cos(theta), np.sin(theta), 0])

View file

@ -728,7 +728,7 @@ class UnmixMixedPaint(Scene):
class MachineThatTreatsOneFrequencyDifferently(Scene):
def construct(self):
graph = self.get_cosine_graph(0.5)
frequency_mob = DecimalNumber(220, num_decimal_points = 0)
frequency_mob = DecimalNumber(220, num_decimal_places = 0)
frequency_mob.next_to(graph, UP, buff = MED_LARGE_BUFF)
self.graph = graph
@ -1273,7 +1273,7 @@ class WrapCosineGraphAroundCircle(FourierMachineScene):
def get_winding_frequency_label(self):
freq = self.initial_winding_frequency
winding_freq_label = VGroup(
DecimalNumber(freq, num_decimal_points = 2),
DecimalNumber(freq, num_decimal_places = 2),
TextMobject("cycles/second")
)
winding_freq_label.arrange_submobjects(RIGHT)

View file

@ -1805,7 +1805,7 @@ class BoxCountingScene(Scene):
return label
def count_boxes(self, boxes):
num = DecimalNumber(len(boxes), num_decimal_points = 0)
num = DecimalNumber(len(boxes), num_decimal_places = 0)
num.next_to(boxes, RIGHT)
num.add_to_back(BackgroundRectangle(num))

View file

@ -559,7 +559,7 @@ class WriteAProgram(Scene):
rgb = square.fill_rgb
num = DecimalNumber(
square.fill_rgb[0],
num_decimal_points = 1
num_decimal_places = 1
)
num.set_stroke(width = 1)
color = rgba_to_color(1 - (rgb + 0.2)/1.2)
@ -1113,7 +1113,7 @@ class IntroduceEachLayer(PreviewMNistNetwork):
example_num = None
for neuron in neurons:
o = neuron.get_fill_opacity()
num = DecimalNumber(o, num_decimal_points = 1)
num = DecimalNumber(o, num_decimal_places = 1)
num.scale_to_fit_width(0.7*neuron.get_width())
num.move_to(neuron)
if o > 0.8:

View file

@ -962,14 +962,14 @@ class IntroduceCostFunction(PreviewLearning):
terms = VGroup()
term_updates = []
for arrow, d1, d2 in zip(arrows, *self.decimal_groups):
term = DecimalNumber(0, num_decimal_points = 4)
term = DecimalNumber(0, num_decimal_places = 4)
term.scale_to_fit_height(d1.get_height())
term.next_to(arrow, LEFT)
term.num_update_func = generate_term_update_func(d1, d2)
terms.add(term)
term_updates.append(ChangingDecimalWithColor(
term, term.num_update_func,
num_decimal_points = 4
num_decimal_places = 4
))
brace.target.next_to(terms, LEFT)
@ -2780,7 +2780,7 @@ class TestPerformance(PreviewLearning):
"wrong_wait_time" : 0.5,
"stroke_width_exp" : 2,
"decimal_kwargs" : {
"num_decimal_points" : 3,
"num_decimal_places" : 3,
}
}
def construct(self):

View file

@ -671,7 +671,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
decimals = VGroup()
for neuron in neurons:
activation = neuron.get_fill_opacity()
decimal = DecimalNumber(activation, num_decimal_points = 1)
decimal = DecimalNumber(activation, num_decimal_places = 1)
decimal.scale_to_fit_width(0.7*neuron.get_width())
decimal.move_to(neuron)
if activation > 0.8:
@ -748,7 +748,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
anims.append(ChangingDecimal(
decimal,
get_decimal_update(decimal.number, target),
num_decimal_points = 1
num_decimal_places = 1
))
anims.append(UpdateFromFunc(
self.decimals[i],
@ -1076,7 +1076,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
ChangingDecimal(
two_decimal,
lambda a : interpolate(two_activation, 1, a),
num_decimal_points = 1,
num_decimal_places = 1,
),
UpdateFromFunc(
two_decimal,
@ -1110,7 +1110,7 @@ class WalkThroughTwoExample(ShowAveragingCost):
ChangingDecimal(
two_decimal,
lambda a : interpolate(1, two_activation, a),
num_decimal_points = 1,
num_decimal_places = 1,
),
UpdateFromFunc(
two_decimal,
@ -3613,7 +3613,7 @@ class SimplestNetworkExample(PreviewLearning):
def get_neuron_activation_decimal(self, neuron):
opacity = neuron.get_fill_opacity()
decimal = DecimalNumber(opacity, num_decimal_points = 2)
decimal = DecimalNumber(opacity, num_decimal_places = 2)
decimal.scale_to_fit_width(0.85*neuron.get_width())
if decimal.number > 0.8:
decimal.set_fill(BLACK)

View file

@ -226,7 +226,7 @@ def get_circle_drawing_terms(radius = 1, positioning_func = lambda m : m.center(
0.25*rotate_vector(radius.get_vector(), TAU/4)
),
)
decimal = DecimalNumber(0, num_decimal_points = 4, show_ellipsis = True)
decimal = DecimalNumber(0, num_decimal_places = 4, show_ellipsis = True)
decimal.scale(0.75)
def reposition_decimal(decimal):
vect = radius.get_vector()
@ -318,7 +318,7 @@ class PiTauDebate(PiCreatureScene):
circum_line.next_to(circle, DOWN, buff = MED_LARGE_BUFF)
# circum_line.to_edge(LEFT)
brace = Brace(circum_line, DOWN, buff = SMALL_BUFF)
decimal = DecimalNumber(np.pi, num_decimal_points = 4, show_ellipsis = True)
decimal = DecimalNumber(np.pi, num_decimal_places = 4, show_ellipsis = True)
decimal.scale(0.75)
decimal.next_to(brace, DOWN, SMALL_BUFF)

View file

@ -112,7 +112,7 @@ class Introduction(Scene):
)
get_arrow_update().update(1)
decimal = DecimalNumber(
curr_product, num_decimal_points=5, show_ellipsis=True)
curr_product, num_decimal_places=5, show_ellipsis=True)
decimal.next_to(arrow, UP, SMALL_BUFF, submobject_to_align=decimal[:5])
decimal_anim = ChangingDecimal(
decimal,
@ -512,7 +512,7 @@ class ShowProduct(Scene):
])
brace = braces[0].copy()
decimal = DecimalNumber(partial_products[0], num_decimal_points=4)
decimal = DecimalNumber(partial_products[0], num_decimal_places=4)
decimal.next_to(brace, DOWN)
self.add(brace, decimal, dots[0], parts[0])
@ -677,7 +677,7 @@ class ShowProduct(Scene):
])
brace = braces[0].copy()
decimal = DecimalNumber(partial_products_iter.next(), num_decimal_points=4)
decimal = DecimalNumber(partial_products_iter.next(), num_decimal_places=4)
decimal.next_to(brace, DOWN)
self.play(*map(FadeIn, [brace, decimal, dots[0]]))
@ -894,7 +894,7 @@ class DistanceProductScene(MovingCameraScene):
self.d_labels.add(d_label)
return self.d_labels
def get_numeric_distance_labels(self, lines=None, num_decimal_points=3, show_ellipsis=True):
def get_numeric_distance_labels(self, lines=None, num_decimal_places=3, show_ellipsis=True):
radius = self.circle.get_width() / 2
if lines is None:
if not hasattr(self, "distance_lines"):
@ -904,7 +904,7 @@ class DistanceProductScene(MovingCameraScene):
for line in lines:
label = DecimalNumber(
line.get_length() / radius,
num_decimal_points=num_decimal_points,
num_decimal_places=num_decimal_places,
show_ellipsis=show_ellipsis,
include_background_rectangle=self.include_distance_labels_background_rectangle,
)
@ -943,7 +943,7 @@ class DistanceProductScene(MovingCameraScene):
product_decimal = DecimalNumber(
self.get_distance_product(fraction),
num_decimal_points=3,
num_decimal_places=3,
show_ellipsis=True,
include_background_rectangle=self.include_distance_labels_background_rectangle,
)
@ -1632,7 +1632,7 @@ class FromGeometryToAlgebra(DistanceProductScene):
values = map(plane.point_to_number, self.get_lh_points())
complex_decimal = self.complex_decimal = DecimalNumber(
values[3],
num_decimal_points=3,
num_decimal_places=3,
include_background_rectangle=True
)
complex_decimal.next_to(outer_arrow.get_start(), LEFT, SMALL_BUFF)
@ -2190,7 +2190,7 @@ class PlugObserverIntoPolynomial(DistanceProductScene):
numeric_chord_label = DecimalNumber(
np.sqrt(3),
num_decimal_points=4,
num_decimal_places=4,
include_background_rectangle=True,
show_ellipsis=True,
)
@ -2907,7 +2907,7 @@ class ProveLemma2(PlugObserverIntoPolynomial):
product = DecimalNumber(
self.num_lighthouses,
num_decimal_points=3,
num_decimal_places=3,
show_ellipsis=True
)
product.move_to(self.q_marks, LEFT)
@ -3235,7 +3235,7 @@ class KeeperAndSailor(DistanceProductScene, PiCreatureScene):
new_keeper_dp_decimal = DecimalNumber(
self.num_lighthouses,
num_decimal_points=3,
num_decimal_places=3,
)
new_keeper_dp_decimal.replace(keeper_dp_decimal, dim_to_match=1)
new_keeper_dp_decimal.set_color(YELLOW)

View file

@ -4,6 +4,9 @@ from utils.bezier import bezier
from utils.simple_functions import sigmoid
def linear(t):
return t
def smooth(t, inflection=10.0):
error = sigmoid(-inflection / 2)
return (sigmoid(inflection * (t - 0.5)) - error) / (1 - 2 * error)

View file

@ -1,81 +0,0 @@
import os
from constants import TEX_DIR
from constants import TEX_TEXT_TO_REPLACE
def tex_hash(expression, template_tex_file):
return str(hash(expression + template_tex_file))
def tex_to_svg_file(expression, template_tex_file):
tex_file = generate_tex_file(expression, template_tex_file)
dvi_file = tex_to_dvi(tex_file)
return dvi_to_svg(dvi_file)
def generate_tex_file(expression, template_tex_file):
result = os.path.join(
TEX_DIR,
tex_hash(expression, template_tex_file)
) + ".tex"
if not os.path.exists(result):
print("Writing \"%s\" to %s" % (
"".join(expression), result
))
with open(template_tex_file, "r") as infile:
body = infile.read()
body = body.replace(TEX_TEXT_TO_REPLACE, expression)
with open(result, "w") as outfile:
outfile.write(body)
return result
def get_null():
if os.name == "nt":
return "NUL"
return "/dev/null"
def tex_to_dvi(tex_file):
result = tex_file.replace(".tex", ".dvi")
if not os.path.exists(result):
commands = [
"latex",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=" + TEX_DIR,
tex_file,
">",
get_null()
]
exit_code = os.system(" ".join(commands))
if exit_code != 0:
log_file = tex_file.replace(".tex", ".log")
raise Exception(
"Latex error converting to dvi. "
"See log output above or the log file: %s" % log_file)
return result
def dvi_to_svg(dvi_file, regen_if_exists=False):
"""
Converts a dvi, which potentially has multiple slides, into a
directory full of enumerated pngs corresponding with these slides.
Returns a list of PIL Image objects for these images sorted as they
where in the dvi
"""
result = dvi_file.replace(".dvi", ".svg")
if not os.path.exists(result):
commands = [
"dvisvgm",
dvi_file,
"-n",
"-v",
"0",
"-o",
result,
">",
get_null()
]
os.system(" ".join(commands))
return result