From 2b2fecf94d3681cef1570698f10a48b9b6d8b31e Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Wed, 30 May 2018 22:54:50 -0700 Subject: [PATCH] Edits for eop1 finalization --- active_projects/eop/chapter1/million_flips.py | 118 ++++++++++++++++++ .../eop/chapter1/prob_dist_visuals.py | 47 +++---- active_projects/eop/chapter1/quiz_result.py | 12 +- .../chapter1/what_does_probability_mean.py | 55 ++++---- 4 files changed, 176 insertions(+), 56 deletions(-) create mode 100644 active_projects/eop/chapter1/million_flips.py diff --git a/active_projects/eop/chapter1/million_flips.py b/active_projects/eop/chapter1/million_flips.py new file mode 100644 index 00000000..5f270062 --- /dev/null +++ b/active_projects/eop/chapter1/million_flips.py @@ -0,0 +1,118 @@ +from big_ol_pile_of_manim_imports import * +from active_projects.eop.reusable_imports import * + + +class MillionFlips(Scene): + def construct(self): + title = TextMobject("1{,}000{,}000 flips") + title.to_edge(UP) + self.add(title) + + small_wait_time = 1.0 / 15 # Um... + + n_flips_label = TextMobject("\\# Flips: ") + n_heads_label = TextMobject("\\# Heads: ") + n_flips_count = Integer(0) + n_heads_count = Integer(0) + n_heads_label.to_edge(RIGHT, buff=2 * LARGE_BUFF) + n_flips_label.next_to(n_heads_label, DOWN, aligned_edge=LEFT) + n_flips_count.next_to(n_flips_label[-1], RIGHT) + n_heads_count.next_to(n_heads_label[-1], RIGHT) + VGroup(n_flips_count, n_heads_count).shift(0.5 * SMALL_BUFF * UP) + self.add(n_flips_label, n_heads_label, n_flips_count, n_heads_count) + + coins = VGroup(*[ + FlatHeads() if random.random() < 0.5 else FlatTails() + for x in range(100) + ]) + self.organize_group(coins) + + proportions = np.random.normal(0.5, 0.5 * 0.1, 100) + hundred_boxes = VGroup(*[ + Square( + stroke_width=1, + stroke_color=WHITE, + fill_opacity=1, + fill_color=interpolate_color(COLOR_HEADS, COLOR_TAILS, prop) + ) + for prop in proportions + ]) + self.organize_group(hundred_boxes) + + ten_k_proportions = np.random.normal(0.5, 0.5 * 0.01, 100) + ten_k_boxes = VGroup(*[ + Square( + stroke_width=1, + stroke_color=WHITE, + fill_opacity=1, + fill_color=interpolate_color(COLOR_HEADS, COLOR_TAILS, prop) + ) + for prop in ten_k_proportions + ]) + self.organize_group(ten_k_boxes) + + # Animations + for coin in coins: + self.add(coin) + self.increment(n_flips_count) + if isinstance(coin, FlatHeads): + self.increment(n_heads_count) + self.wait(small_wait_time) + + self.play( + FadeIn(hundred_boxes[0]), + coins.set_stroke, {"width": 0}, + coins.replace, hundred_boxes[0] + ) + hundred_boxes[0].add(coins) + for box, prop in zip(hundred_boxes, proportions)[1:]: + self.add(box) + self.increment(n_flips_count, 100) + self.increment(n_heads_count, int(np.round(prop * 100))) + self.wait(small_wait_time) + + self.play( + FadeIn(ten_k_boxes[0]), + hundred_boxes.set_stroke, {"width": 0}, + hundred_boxes.replace, ten_k_boxes[0] + ) + ten_k_boxes[0].add(hundred_boxes) + for box, prop in zip(ten_k_boxes, ten_k_proportions)[1:]: + self.add(box) + self.increment(n_flips_count, 10000) + self.increment(n_heads_count, int(np.round(prop * 10000))) + self.wait(small_wait_time) + self.wait() + + def organize_group(self, group): + group.arrange_submobjects_in_grid(10) + group.scale_to_fit_height(5) + group.shift(DOWN + 2 * LEFT) + + def increment(self, integer_mob, value=1): + new_int = Integer(integer_mob.number + value) + new_int.move_to(integer_mob, DL) + integer_mob.number += value + integer_mob.submobjects = new_int.submobjects + + +class PropHeadsWithinThousandth(Scene): + def construct(self): + prob = TexMobject( + "P(499{,}000 \\le", "\\# \\text{H}", "\\le 501{,}000)", + "\\approx", "0.9545", + ) + prob[1].set_color(RED) + prob[-1].set_color(YELLOW) + self.add(prob) + + +class PropHeadsWithinHundredth(Scene): + def construct(self): + prob = TexMobject( + "P(490{,}000 \\le", "\\# \\text{H}", "\\le 510{,}000)", + "\\approx", "0.99999999\\dots", + ) + prob[1].set_color(RED) + prob[-1].set_color(YELLOW) + self.add(prob) diff --git a/active_projects/eop/chapter1/prob_dist_visuals.py b/active_projects/eop/chapter1/prob_dist_visuals.py index 513c94c2..6722e39a 100644 --- a/active_projects/eop/chapter1/prob_dist_visuals.py +++ b/active_projects/eop/chapter1/prob_dist_visuals.py @@ -164,28 +164,28 @@ class ProbabilityDistributions(PiCreatureScene): cell_size = 0.5 dice_table = TwoDiceTable(cell_size = cell_size, label_scale = 0.7) dice_table.shift(0.8 * DOWN) - dice_unit_rect = SurroundingRectangle(dice_table.cells, buff = 0, - stroke_color = WHITE) + dice_unit_rect = SurroundingRectangle( + dice_table.cells, buff = 0, + stroke_color=WHITE + ) dice_table_grouped_cells = VGroup() for i in range(6): - cell = dice_table.cells[6 * i] - start = cell.get_center() - stop = start + cell_size * LEFT + cell_size * DOWN - dice_table_grouped_cells.add(VGroup(*[ - dice_table.cells[6 * i - 5 * k] + VGroup( + dice_table.cells[6 * i - 5 * k], + dice_table.labels[6 * i - 5 * k], + ) for k in range(i + 1) ])) for i in range(5): - cell = dice_table.cells[31 + i] - start = cell.get_center() - stop = start + cell_size * LEFT + cell_size * DOWN - dice_table_grouped_cells.add(VGroup(*[ - dice_table.cells[31 + i - 5 * k] + VGroup( + dice_table.cells[31 + i - 5 * k], + dice_table.labels[31 + i - 5 * k], + ) for k in range(5 - i) ])) @@ -194,8 +194,8 @@ class ProbabilityDistributions(PiCreatureScene): # FadeIn(dice_table.rows) # ) - for (cell, label) in zip(dice_table.cells, dice_table.labels): - cell.add(label) + # for (cell, label) in zip(dice_table.cells, dice_table.labels): + # cell.add(label) # self.play( # LaggedStart(FadeIn, dice_table_grouped_cells, @@ -211,14 +211,16 @@ class ProbabilityDistributions(PiCreatureScene): self.play( - dice_table_grouped_cells.space_out_submobjects, {"factor" : 1.9}, + dice_table_grouped_cells.space_out_submobjects, {"factor" : 1.5}, rate_func=there_and_back_with_pause, run_time=run_time ) + dice_table.add(dice_unit_rect) - dice_table_target = dice_table.copy() - dice_table_target.scale(0.5).to_corner(UR, buff = LARGE_BUFF) - dice_table_target.shift(0.4*UP) + dice_table_target = dice_table.deepcopy() + dice_table_target.scale(0.5) + dice_table_target.to_corner(UR, buff=LARGE_BUFF) + dice_table_target.shift(0.4 * UP) self.play(Transform(dice_table, dice_table_target)) @@ -231,9 +233,10 @@ class ProbabilityDistributions(PiCreatureScene): # TITLE - text = TextMobject("Probability distributions", color = YELLOW) + text = TextMobject("Probability distributions") text.to_edge(UP) - text_rect = SurroundingRectangle(text, buff = MED_SMALL_BUFF) + text_rect = SurroundingRectangle(text, buff=MED_SMALL_BUFF) + text_rect.match_color(text) self.play( FadeIn(text), @@ -263,7 +266,7 @@ class ProbabilityDistributions(PiCreatureScene): braces = VGroup() labels = VGroup() for (rect, count) in zip(brick_row.rects, counts): - label = TexMobject("{" + str(count) + "\over 8}").scale(0.5) + label = TexMobject("{" + str(count) + "\\over 8}").scale(0.5) brace = Brace(rect, DOWN) label.next_to(brace, DOWN) braces.add(brace) @@ -286,7 +289,7 @@ class ProbabilityDistributions(PiCreatureScene): outcome_braces = VGroup(*[ Brace(outcome, DOWN) for outcome in outcomes ]) - outcome_labels = VGroup(*[ + outcome_labels = VGroup(*[i TexMobject("{1\over 8}").scale(0.5).next_to(brace, DOWN) for brace in outcome_braces ]) diff --git a/active_projects/eop/chapter1/quiz_result.py b/active_projects/eop/chapter1/quiz_result.py index c6a85b30..c8bec9d9 100644 --- a/active_projects/eop/chapter1/quiz_result.py +++ b/active_projects/eop/chapter1/quiz_result.py @@ -71,12 +71,14 @@ class QuizResult(PiCreatureScene): all_quizzes.add(quiz_copy) master_quiz = get_example_quiz() - self.play(ShowCreation(master_quiz), run_time = 2) + self.play(Write(master_quiz), run_time = 2) self.wait() - self.play(Transform(master_quiz, all_quizzes[0])) - self.wait() - - self.play(LaggedStart(FadeIn,all_quizzes)) + self.play(ReplacementTransform( + VGroup(master_quiz), all_quizzes, + run_time=2, + submobject_mode="lagged_start" + )) + self.wait(2) grades_mob = VGroup() for (pi, quiz, grade) in zip(all_students, all_quizzes, grades): diff --git a/active_projects/eop/chapter1/what_does_probability_mean.py b/active_projects/eop/chapter1/what_does_probability_mean.py index 99fc1413..f2b3ff8b 100644 --- a/active_projects/eop/chapter1/what_does_probability_mean.py +++ b/active_projects/eop/chapter1/what_does_probability_mean.py @@ -1,8 +1,7 @@ - from big_ol_pile_of_manim_imports import * -class WhatDoesItReallyMean(TeacherStudentsScene): +class WhatDoesItReallyMean(TeacherStudentsScene): CONFIG = { "default_pi_creature_kwargs": { "color": MAROON_E, @@ -11,36 +10,34 @@ class WhatDoesItReallyMean(TeacherStudentsScene): } def construct(self): - - student_q = TextMobject("What does", "``probability''", "\emph{actually}", "mean?") + student_q = TextMobject( + "What does", "``probability''\\\\", + "\\emph{actually}", "mean?" + ) student_q.set_color_by_tex("probability", YELLOW) - self.student_says(student_q, target_mode = "sassy") + self.student_says(student_q, target_mode="sassy") self.wait() self.play( - self.students[1].change_mode, "plain" + self.students[1].change_mode, "confused" ) - self.wait() - self.play(RemovePiCreatureBubble(self.students[1])) - - self.wait() - - self.teacher_says("Don't worry -- philosophy can come later!") - self.wait() - - - -class EmptyTSScene(TeacherStudentsScene): - CONFIG = { - "default_pi_creature_kwargs": { - "color": MAROON_E, - "flip_at_start": True, - }, - } - - def construct(self): - - self.wait() + self.wait(2) + student_bubble = self.students[1].bubble + self.students[1].bubble = None + student_bubble.add(student_bubble.content) + self.play( + student_bubble.scale, 0.5, + student_bubble.to_corner, UL, + ) + self.teacher_says( + "Don't worry -- philosophy\\\\ can come later!", + added_anims=[self.get_student_changes(*3 * ["happy"])], + ) + self.wait(2) + self.play(RemovePiCreatureBubble(self.teacher)) self.play(*[ - ApplyMethod(pi.look_at,ORIGIN) for pi in self.get_pi_creatures() + ApplyMethod(pi.look_at, ORIGIN) for pi in self.get_pi_creatures() ]) - self.wait(8) \ No newline at end of file + self.change_all_student_modes("pondering", look_at_arg=UP) + self.wait(3) + self.change_student_modes("confused", look_at_arg=UP) + self.wait(3)