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 list(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 list(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_in_grid(10) group.set_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)