Change "print " lines to "print(" lines

This commit is contained in:
ddxtanx 2017-10-05 21:03:30 -05:00
parent 5c1a8f9a32
commit 384915d5a7
9 changed files with 188 additions and 305 deletions

View file

@ -14,7 +14,7 @@ from scene import Scene
from camera import Camera
HELP_MESSAGE = """
Usage:
Usage:
python extract_scene.py <module> [<scene name>]
-p preview in low quality
@ -44,7 +44,7 @@ def get_configuration(sys_argv):
try:
opts, args = getopt.getopt(sys_argv[1:], 'hlmpwstqao:')
except getopt.GetoptError as err:
print str(err)
print(str(err))
sys.exit(2)
config = {
"file" : None,
@ -63,7 +63,7 @@ def get_configuration(sys_argv):
}
for opt, arg in opts:
if opt == '-h':
print HELP_MESSAGE
print(HELP_MESSAGE)
return
if opt in ['-l', '-p']:
config["camera_config"] = LOW_QUALITY_CAMERA_CONFIG
@ -89,11 +89,11 @@ def get_configuration(sys_argv):
#By default, write to file
actions = ["write_to_movie", "preview", "save_image"]
if not any([config[key] for key in actions]):
config["write_to_movie"] = True
config["write_to_movie"] = True
config["skip_animations"] = config["save_image"] and not config["write_to_movie"]
if len(args) == 0:
print HELP_MESSAGE
print(HELP_MESSAGE)
sys.exit()
config["file"] = args[0]
if len(args) > 1:
@ -104,7 +104,7 @@ def handle_scene(scene, **config):
if config["quiet"]:
curr_stdout = sys.stdout
sys.stdout = open(os.devnull, "w")
if config["preview"]:
scene.preview()
if config["save_image"]:
@ -129,7 +129,7 @@ def prompt_user_for_choice(name_to_obj):
num_to_name = {}
names = sorted(name_to_obj.keys())
for count, name in zip(it.count(1), names):
print "%d: %s"%(count, name)
print("%d: %s"%(count, name))
num_to_name[count] = name
try:
user_input = raw_input(CHOOSE_NUMBER_MESSAGE)
@ -138,19 +138,19 @@ def prompt_user_for_choice(name_to_obj):
for num_str in user_input.split(",")
]
except:
print INVALID_NUMBER_MESSAGE
print(INVALID_NUMBER_MESSAGE)
sys.exit()
def get_scene_classes(scene_names_to_classes, config):
if len(scene_names_to_classes) == 0:
print NO_SCENE_MESSAGE
print(NO_SCENE_MESSAGE)
return []
if len(scene_names_to_classes) == 1:
return scene_names_to_classes.values()
if config["scene_name"] in scene_names_to_classes:
return [scene_names_to_classes[config["scene_name"]] ]
if config["scene_name"] != "":
print SCENE_NOT_FOUND_MESSAGE
print(SCENE_NOT_FOUND_MESSAGE)
return []
if config["write_all"]:
return scene_names_to_classes.values()
@ -171,7 +171,7 @@ def get_module_posix(file_name):
load_args = imp.find_module(part, last_module.__path__)
last_module = imp.load_module(part, *load_args)
return last_module
def get_module(file_name):
if os.name == 'nt':
return get_module_windows(file_name)
@ -185,7 +185,7 @@ def main():
inspect.getmembers(module, is_scene)
)
config["output_directory"] = os.path.join(
MOVIE_DIR,
MOVIE_DIR,
config["file"].replace(".py", "")
)
@ -206,15 +206,11 @@ def main():
handle_scene(SceneClass(**scene_kwargs), **config)
play_finish_sound()
except:
print "\n\n"
print("\n\n")
traceback.print_exc()
print "\n\n"
print("\n\n")
play_error_sound()
if __name__ == "__main__":
main()

View file

@ -13,7 +13,7 @@ class TexSymbol(VMobjectFromSVGPathstring):
def pointwise_become_partial(self, mobject, a, b):
#TODO, this assumes a = 0
if b < 0.5:
b = 2*b
b = 2*b
added_width = 1
opacity = 0
else:
@ -116,7 +116,7 @@ class TexMobject(SVGMobject):
def handle_multiple_args(self):
"""
Reorganize existing submojects one layer
Reorganize existing submojects one layer
deeper based on the structure of args (as a list of strings)
"""
new_submobjects = []
@ -189,7 +189,7 @@ class TexMobject(SVGMobject):
def add_background_rectangle(self, color = BLACK, opacity = 0.75):
self.background_rectangle = BackgroundRectangle(
self, color = color,
self, color = color,
fill_opacity = opacity
)
letters = VMobject(*self.submobjects)
@ -233,8 +233,8 @@ class Brace(TexMobject):
def put_at_tip(self, mob, use_next_to = True, **kwargs):
if use_next_to:
mob.next_to(
self.get_tip(),
np.round(self.get_direction()),
self.get_tip(),
np.round(self.get_direction()),
**kwargs
)
else:
@ -269,7 +269,7 @@ def tex_hash(expression, template_tex_file):
def tex_to_svg_file(expression, template_tex_file):
image_dir = os.path.join(
TEX_IMAGE_DIR,
TEX_IMAGE_DIR,
tex_hash(expression, template_tex_file)
)
if os.path.exists(image_dir):
@ -280,13 +280,13 @@ def tex_to_svg_file(expression, template_tex_file):
def generate_tex_file(expression, template_tex_file):
result = os.path.join(
TEX_DIR,
TEX_DIR,
tex_hash(expression, template_tex_file)
) + ".tex"
if not os.path.exists(result):
print "Writing \"%s\" to %s"%(
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)
@ -303,8 +303,8 @@ def tex_to_dvi(tex_file):
result = tex_file.replace(".tex", ".dvi")
if not os.path.exists(result):
commands = [
"latex",
"-interaction=batchmode",
"latex",
"-interaction=batchmode",
"-halt-on-error",
"-output-directory=" + TEX_DIR,
tex_file,
@ -325,7 +325,7 @@ def tex_to_dvi(tex_file):
def dvi_to_svg(dvi_file, regen_if_exists = False):
"""
Converts a dvi, which potentially has multiple slides, into a
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
@ -345,17 +345,3 @@ def dvi_to_svg(dvi_file, regen_if_exists = False):
]
os.system(" ".join(commands))
return result

View file

@ -92,10 +92,10 @@ class Network(object):
for mini_batch in mini_batches:
self.update_mini_batch(mini_batch, eta)
if test_data:
print "Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test)
print("Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test))
else:
print "Epoch {0} complete".format(j)
print("Epoch {0} complete".format(j))
def update_mini_batch(self, mini_batch, eta):
"""Update the network's weights and biases by applying
@ -207,7 +207,7 @@ def save_pretrained_network(epochs = 30, mini_batch_size = 10, eta = 3.0):
data_file.close()
def test_network():
network = get_pretrained_network()
network = get_pretrained_network()
training_data, validation_data, test_data = load_data_wrapper()
n_right, n_wrong = 0, 0
for test_in, test_out in test_data:
@ -215,7 +215,7 @@ def test_network():
n_right += 1
else:
n_wrong += 1
print n_right, n_wrong, float(n_right)/(n_right + n_wrong)
print(n_right, n_wrong, float(n_right)/(n_right + n_wrong))
def layer_to_image_array(layer):
w = int(np.ceil(np.sqrt(len(layer))))
@ -254,8 +254,8 @@ def maximizing_input(network, layer_index, layer_vect, n_steps = 100, seed_guess
norms.append(norm)
old_pre_sig_guess = np.array(pre_sig_guess)
pre_sig_guess += 0.1*gradient
print np.linalg.norm(old_pre_sig_guess - pre_sig_guess)
print ""
print(np.linalg.norm(old_pre_sig_guess - pre_sig_guess))
print("")
return sigmoid(pre_sig_guess)
def save_organized_images(n_images_per_number = 10):
@ -299,41 +299,3 @@ def get_organized_images():
# prev_vect /= np.max(np.abs(prev_vect))
# # prev_vect /= 1.1
# return maximizing_input(network, layer_index - 1, prev_vect)

View file

@ -82,7 +82,7 @@ COUNT_TO_TIP_POS = {
def finger_tip_power_of_2(finger_no):
return TexMobject(str(2**finger_no)).shift(COUNT_TO_TIP_POS[finger_no])
class Hand(ImageMobject):
STARTING_BOTTOM_RIGHT = [4.61111111e+00, -3.98888889e+00, 9.80454690e-16]
def __init__(self, num, small = False, **kwargs):
@ -115,7 +115,7 @@ class Hand(ImageMobject):
def get_algorithm():
return TextMobject(ALGORITHM_TEXT)
def get_finger_colors():
return list(Color("yellow").range_to("red", 5))
@ -133,7 +133,7 @@ class LeftHand(Hand):
def __init__(self, num, **kwargs):
Hand.__init__(
self,
read_reversed_binary(five_char_binary(num)),
read_reversed_binary(five_char_binary(num)),
**kwargs
)
self.rotate(np.pi, UP)
@ -145,7 +145,7 @@ def get_hand_map(which_hand = "right"):
elif which_hand == "left":
Class = LeftHand
else:
print "Bad arg, bro"
print("Bad arg, bro")
return
return dict([
(num, Class(num, small=True))
@ -164,13 +164,13 @@ class SaveEachNumber(OverHand):
OverHand.construct(self)
for count in COUNT_TO_FRAME_NUM:
path = os.path.join(
MOVIE_DIR, MOVIE_PREFIX, "images",
MOVIE_DIR, MOVIE_PREFIX, "images",
"Hand%d.png"%count
)
Image.fromarray(self.frames[COUNT_TO_FRAME_NUM[count]]).save(path)
def write_to_movie(self, name = None):
print "Why bother writing to movie..."
print("Why bother writing to movie...")
class ShowCounting(OverHand):
def construct(self):
@ -197,7 +197,7 @@ class ShowFrameNum(OverHand):
def construct(self):
OverHand.construct(self)
for frame, count in zip(self.frames, it.count()):
print count, "of", len(self.frames)
print(count + "of" + len(self.frames))
mob = Mobject(*[
TexMobject(char).shift(0.3*x*RIGHT)
for char, x, in zip(str(count), it.count())
@ -241,7 +241,7 @@ class Introduction(Scene):
class ShowReadingRule(Scene):
def construct(self):
sample_counts = [6, 17, 27, 31]
sample_counts = [6, 17, 27, 31]
question = TextMobject("""
How do you recognize what number a given configuration represents?
""", size = "\\Huge").scale(0.75).to_corner(UP+LEFT)
@ -284,7 +284,7 @@ class ShowReadingRule(Scene):
self.add(hand, *count_mobs)
self.dither()
self.play(*[
Transform(count_mobs[n/2], sum_mobs[n])
Transform(count_mobs[n/2], sum_mobs[n])
if n%2 == 0 and n/2 < len(counts)
else FadeIn(sum_mobs[n])
for n in range(len(sum_mobs))
@ -380,13 +380,13 @@ class MindFindsShortcuts(Scene):
sum421 = TexMobject("4+2+1").shift(DOWN+2*RIGHT)
seven = TexMobject("7").shift(DOWN+6*RIGHT)
compound = Mobject(
Arrow(hand, sum421),
Arrow(hand, sum421),
sum421,
Arrow(sum421, seven)
)
self.add(
words1,
hand,
hand,
compound,
seven
)
@ -415,11 +415,11 @@ class MindFindsShortcuts(Scene):
self.dither()
self.play(
Transform(
deepcopy(hands[16]).highlight("black").center().shift(hands[23].get_center()),
deepcopy(hands[16]).highlight("black").center().shift(hands[23].get_center()),
hands[16]
),
Transform(
deepcopy(hands[7]).highlight("black").center().shift(hands[23].get_center()),
deepcopy(hands[7]).highlight("black").center().shift(hands[23].get_center()),
hands[7]
),
Animation(hands[23]),
@ -480,14 +480,3 @@ class WithToes(Scene):
if __name__ == "__main__":
command_line_create_scene(MOVIE_PREFIX)

View file

@ -74,7 +74,7 @@ class SierpinskiTest(Scene):
)
self.play(FadeIn(
sierp,
sierp,
run_time = 5,
submobject_mode = "lagged_start",
))
@ -146,7 +146,7 @@ class ZoomInOnFractal(PiCreatureScene):
run_time = 2
)
self.dither()
grower_target = grower.copy()
grower_target = grower.copy()
grower = grower[self.index_to_replace]
@ -198,7 +198,7 @@ class IntroduceVonKochCurve(Scene):
self.play(Write(name, run_time = 2))
curve = self.isolate_one_curve(snowflake)
self.dither()
self.zoom_in_on(curve)
self.zoom_in_on(curve)
self.zoom_in_on(curve)
@ -266,9 +266,9 @@ class IntroduceSierpinskiTriangle(PiCreatureScene):
sierp.save_state()
self.play(FadeIn(
sierp,
sierp,
run_time = 2,
submobject_mode = "lagged_start"
submobject_mode = "lagged_start"
))
self.dither()
self.play(
@ -285,7 +285,7 @@ class IntroduceSierpinskiTriangle(PiCreatureScene):
self.play(sierp.restore)
self.change_mode("happy")
self.dither()
class SelfSimilarFractalsAsSubset(Scene):
CONFIG = {
"fractal_width" : 1.5
@ -349,7 +349,7 @@ class SelfSimilarFractalsAsSubset(Scene):
fractalify(randy.target, order = 2)
self.play(
ShowCreation(big_rectangle),
ShowCreation(big_rectangle),
Write(title),
)
self.play(ShowCreation(britain), run_time = 5)
@ -404,8 +404,8 @@ class ConstrastSmoothAndFractal(Scene):
self.britain_zoom_point_proportion
)
fractalify(
britain,
order = self.fractalification_order,
britain,
order = self.fractalification_order,
dimension = self.fractal_dimension,
)
@ -421,15 +421,15 @@ class ConstrastSmoothAndFractal(Scene):
self.dither()
self.play(
ApplyMethod(
smooth_britain.scale,
self.scale_factor,
smooth_britain.scale,
self.scale_factor,
smooth_britain.zoom_point
),
Animation(v_line),
Animation(background_rectangle),
ApplyMethod(
britain.scale,
self.scale_factor,
britain.scale,
self.scale_factor,
britain.zoom_point
),
Animation(smooth),
@ -454,7 +454,7 @@ class InfiniteKochZoom(Scene):
def get_curve(self, order):
koch_curve = KochCurve(
monochromatic = True,
monochromatic = True,
order = order,
color = BLUE,
stroke_width = 2,
@ -464,7 +464,7 @@ class InfiniteKochZoom(Scene):
self.left_point - koch_curve.points[0]
)
return koch_curve
class ShowIdealizations(Scene):
def construct(self):
arrow = DoubleArrow(SPACE_WIDTH*LEFT, SPACE_WIDTH*RIGHT)
@ -472,8 +472,8 @@ class ShowIdealizations(Scene):
left_words = TextMobject("Idealization \\\\ as smooth")
middle_words = TextMobject("Nature")
right_words = TextMobject("""
Idealization
as perfectly
Idealization
as perfectly
self-similar
""")
for words in left_words, middle_words, right_words:
@ -695,11 +695,11 @@ class FourSelfSimilarShapes(Scene):
self.play(line.shift, 3*DOWN)
self.play(ApplyFunction(break_up, line))
self.dither()
self.dither()
brace = Brace(line[0], DOWN)
brace_text = brace.get_text("1/2")
self.play(
GrowFromCenter(brace),
GrowFromCenter(brace),
Write(brace_text)
)
brace.add(brace_text)
@ -728,8 +728,8 @@ class FourSelfSimilarShapes(Scene):
line, square, cube, sierpinski = self.shapes_copy
labels = map(TextMobject, [
"$1/2$ length",
"$1/4$ area",
"$1/2$ length",
"$1/4$ area",
"$1/8$ volume",
"You'll see...",
])
@ -770,7 +770,7 @@ class GeneralWordForMeasurement(Scene):
word.highlight(color)
lines = VGroup(*[
Line(
measure.get_bottom(), word.get_top(),
measure.get_bottom(), word.get_top(),
color = word.get_color(),
buff = MED_SMALL_BUFF
)
@ -794,8 +794,8 @@ class ImagineShapesAsMetal(FourSelfSimilarShapes):
descriptions = VGroup(*[
TextMobject(*words, arg_separator = "\\\\")
for shape, words in zip(shapes, [
["Thin", "wire"],
["Flat", "sheet"],
["Thin", "wire"],
["Flat", "sheet"],
["Solid", "cube"],
["Sierpinski", "mesh"]
])
@ -848,7 +848,7 @@ class ScaledLineMass(Scene):
)
mass_scaling_label[1].highlight(GREEN)
mass_scaling_label.next_to(
scaling_factor_label, DOWN,
scaling_factor_label, DOWN,
aligned_edge = LEFT,
buff = LARGE_BUFF
)
@ -916,7 +916,7 @@ class ScaledSquareMass(ScaledLineMass):
def get_shape(self):
return VGroup(*[
Square(
stroke_width = 0,
stroke_width = 0,
fill_color = BLUE,
fill_opacity = 0.7
).shift(vect)
@ -995,13 +995,13 @@ class DefineTwoDimensional(PiCreatureScene):
top_length = TextMobject("Length:", "$L$")
top_mass = TextMobject("Mass:", "$M$")
bottom_length = TextMobject(
"Length: ", "$%s$"%self.scalar, "$L$",
"Length: ", "$%s$"%self.scalar, "$L$",
arg_separator = ""
)
bottom_mass = TextMobject(
"Mass: ",
"$%s^%s$"%(self.scalar, self.dimension),
"$M$",
"Mass: ",
"$%s^%s$"%(self.scalar, self.dimension),
"$M$",
arg_separator = ""
)
self.dimension_in_exp = VGroup(
@ -1013,7 +1013,7 @@ class DefineTwoDimensional(PiCreatureScene):
bottom_group = VGroup(bottom_length, bottom_mass)
for group in top_group, bottom_group:
group.arrange_submobjects(
DOWN,
DOWN,
buff = MED_LARGE_BUFF,
aligned_edge = LEFT
)
@ -1044,15 +1044,15 @@ class DefineTwoDimensional(PiCreatureScene):
def perform_scaling(self):
group = VGroup(self.shape, self.brace).copy()
self.play(
group.shift,
group.shift,
(group.get_top()[1]+self.bottom_shape_buff)*DOWN
)
shape, brace = group
bottom_L = self.bottom_L.copy()
bottom_L = self.bottom_L.copy()
shape.generate_target()
shape.target.scale_in_place(
self.scale_factor,
self.scale_factor,
)
brace.target = Brace(shape.target, LEFT)
self.play(*map(MoveToTarget, group))
@ -1063,7 +1063,7 @@ class DefineTwoDimensional(PiCreatureScene):
top_dimension = self.dimension_in_title.copy()
self.play(self.pi_creature.look_at, top_dimension)
self.play(Transform(
top_dimension,
top_dimension,
self.dimension_in_exp,
run_time = 2,
))
@ -1136,7 +1136,7 @@ class DefineSierpinskiDimension(DefineTwoDimensional):
self.remove(*keepers_copies)
for mob in keepers:
ApplyMethod(mob.restore).update(1)
self.add(*keepers)
self.add(*keepers)
self.play(
self.pi_creature.change_mode, "confused",
self.pi_creature.look_at, self.equation
@ -1255,7 +1255,7 @@ class FractionalAnalogOfLengthAndArea(Scene):
morty.to_corner(DOWN+RIGHT)
self.play(FadeIn(morty))
self.play(PiCreatureSays(
morty,
morty,
"""
Better described with a
1.585-dimensional measure.
@ -1288,7 +1288,7 @@ class DimensionOfKoch(Scene):
def add_labels(self):
scaling_factor = TextMobject(
"Scaling factor:",
"Scaling factor:",
"$\\frac{1}{%d}$"%self.scaling_factor,
)
scaling_factor.next_to(ORIGIN, UP)
@ -1297,7 +1297,7 @@ class DimensionOfKoch(Scene):
self.add(scaling_factor[0])
mass_scaling = TextMobject(
"Mass scaling factor:",
"Mass scaling factor:",
"$\\frac{1}{%d}$"%self.mass_scaling_factor
)
mass_scaling.next_to(ORIGIN, DOWN)
@ -1371,7 +1371,7 @@ class DimensionOfKoch(Scene):
simpler_formula = TexMobject(
str(self.scaling_factor),
"^D", "=",
"^D", "=",
str(self.mass_scaling_factor)
)
simpler_formula.move_to(formula, UP)
@ -1393,7 +1393,7 @@ class DimensionOfKoch(Scene):
log_expression[7].highlight(self.mass_scaling_color)
log_expression.next_to(
simpler_formula, DOWN,
aligned_edge = LEFT,
aligned_edge = LEFT,
buff = MED_LARGE_BUFF
)
@ -1438,7 +1438,7 @@ class DimensionOfQuadraticKoch(DimensionOfKoch):
def get_curve(self, order):
curve = self.curve_class(
order = order,
order = order,
monochromatic = True
)
curve.scale_to_fit_width(self.koch_curve_width)
@ -1520,7 +1520,7 @@ class ShowSeveralSelfSimilarityDimensions(Scene):
def construct(self):
vects = [
4*LEFT,
ORIGIN,
ORIGIN,
4*RIGHT,
]
fractal_classes = [
@ -1529,8 +1529,8 @@ class ShowSeveralSelfSimilarityDimensions(Scene):
DiamondFractal,
]
max_orders = [
4,
4,
4,
4,
5,
]
dimensions = [
@ -1591,7 +1591,7 @@ class SeparateFractals(Scene):
curves.save_state()
self.play(*[
ApplyFunction(
lambda m : break_up(m, 2),
lambda m : break_up(m, 2),
curve
)
for curve in curves
@ -1641,7 +1641,7 @@ class ShowDiskScaling(Scene):
def isolate_disk(self):
disk = self.disk
self.play(
FadeOut(self.to_fade),
FadeOut(self.to_fade),
disk.scale_to_fit_width, 2,
disk.next_to, ORIGIN, LEFT, 2,
disk.set_fill, BLUE_D, 0.7
@ -1794,7 +1794,7 @@ class BoxCountingScene(Scene):
points = np.array(points)
rounded_points = np.floor(points/self.box_width)*self.box_width
unique_rounded_points = np.vstack({
tuple(row) for
tuple(row) for
row in rounded_points
})
@ -1810,7 +1810,7 @@ class BoxCountingScene(Scene):
def get_corner_rect(self):
rect = Rectangle(
height = SPACE_HEIGHT/2,
height = SPACE_HEIGHT/2,
width = SPACE_WIDTH+self.corner_rect_left_extension,
stroke_width = 0,
fill_color = BLACK,
@ -1824,7 +1824,7 @@ class BoxCountingScene(Scene):
label.next_to(ORIGIN, RIGHT)
label.to_edge(UP)
label.shift(self.corner_rect_left_extension*LEFT)
self.counting_num_reference = label[-1]
self.counting_num_reference = label[-1]
rect = BackgroundRectangle(label)
rect.stretch(1.3, 0)
rect.move_to(label, LEFT)
@ -1875,7 +1875,7 @@ class BoxCountingWithDisk(BoxCountingScene):
self.add(disk, one)
self.play(
ShowCreation(grid),
ShowCreation(grid),
Animation(disk),
)
self.dither()
@ -1933,7 +1933,7 @@ class FinerBoxCountingWithDisk(BoxCountingWithDisk):
"num_boundary_check_points" : 1000,
"disk_stroke_width" : 0.5,
"decimal_string" : "= %.2f",
}
}
class PlotDiskBoxCounting(GraphScene):
CONFIG = {
@ -1969,7 +1969,7 @@ class PlotDiskBoxCounting(GraphScene):
self.dither()
self.play(ShowCreation(self.graph))
self.label_graph(
self.graph,
self.graph,
self.func_label,
direction = RIGHT+DOWN,
buff = SMALL_BUFF,
@ -2104,11 +2104,11 @@ class BoxCountingWithBritain(BoxCountingScene):
def show_formula(self):
corner_rect = self.get_corner_rect()
equation = TextMobject("""
Number of boxes $\\approx$
Number of boxes $\\approx$
\\quad $c(\\text{scaling factor})^{1.21}$
""")
equation.next_to(
corner_rect.get_corner(UP+LEFT), DOWN+RIGHT
corner_rect.get_corner(UP+LEFT), DOWN+RIGHT
)
N = equation[0].copy()
@ -2128,7 +2128,7 @@ class BoxCountingWithBritain(BoxCountingScene):
simpler_eq.target.move_to(N, LEFT)
simpler_eq.target[-1].next_to(
simpler_eq.target[-2].get_corner(UP+RIGHT),
RIGHT,
RIGHT,
buff = SMALL_BUFF
)
@ -2151,7 +2151,7 @@ class BoxCountingWithBritain(BoxCountingScene):
"\\log(", "c", "s", "^{1.21}", ")"
)
log_expression2 = TexMobject(
"\\log(", "N", ")", "=",
"\\log(", "N", ")", "=",
"\\log(", "c", ")", "+",
"1.21", "\\log(", "s", ")"
)
@ -2397,7 +2397,7 @@ class DifferentSlopesAtDifferentScales(IntroduceLogLogPlot):
self.y_axis_label_mob[-2].highlight(YELLOW)
self.graph_function(
lambda x : 0.01*(x-5)**3 + 0.3*x + 3
)
)
self.remove(self.graph)
words = TextMobject("""
@ -2451,12 +2451,12 @@ class HoldUpCoilExample(TeacherStudentsScene):
class SmoothHilbertZoom(Scene):
def construct(self):
hilbert = HilbertCurve(
order = 7,
order = 7,
color = MAROON_B,
monochromatic = True
)
hilbert.make_smooth()
self.add(hilbert)
self.add(hilbert)
two_d_title = TextMobject("2D at a distance...")
one_d_title = TextMobject("1D up close")
@ -2467,7 +2467,7 @@ class SmoothHilbertZoom(Scene):
self.dither()
self.play(
ApplyMethod(
hilbert.scale, 100,
hilbert.scale, 100,
hilbert.point_from_proportion(0.3),
),
Transform(
@ -2507,12 +2507,12 @@ class ZoomInOnBritain(Scene):
anchors = britain.get_anchors()
key_value = int(0.3*len(anchors))
point = anchors[key_value]
point = anchors[key_value]
thinning_factor = 100
num_neighbors_kept = 1000
britain.set_points_as_corners(reduce(
lambda a1, a2 : np.append(a1, a2, axis = 0),
lambda a1, a2 : np.append(a1, a2, axis = 0),
[
anchors[:key_value-num_neighbors_kept:thinning_factor,:],
anchors[key_value-num_neighbors_kept:key_value+num_neighbors_kept,:],
@ -2639,7 +2639,7 @@ class BritainBoxCountHighZoom(BoxCountingWithBritain):
self.play(ShowCreation(boxes))
self.dither()
self.play(FadeOut(boxes))
class IfBritainWasEventuallySmooth(Scene):
def construct(self):
britain = Britain()
@ -2671,7 +2671,7 @@ class SmoothBritainLogLogPlot(IntroduceLogLogPlot):
interim_point1 = p2[0]*RIGHT + p1[1]*UP
interim_point2 = p4[0]*RIGHT + p3[1]*UP
print self.func(2)
print(self.func(2))
slope_lines1, slope_lines2 = VMobject(), VMobject()
slope_lines1.set_points_as_corners(
@ -2736,7 +2736,7 @@ class CompareBritainAndNorway(Scene):
fractalify(norway, order = 1, dimension = 1.5)
anchors = list(norway.get_anchors())
anchors.append(SPACE_WIDTH*RIGHT+SPACE_HEIGHT*UP)
norway.set_points_as_corners(anchors)
norway.set_points_as_corners(anchors)
britain = Britain(
fill_opacity = 0,
@ -2751,7 +2751,7 @@ class CompareBritainAndNorway(Scene):
1.21-dimensional
""")
norway_label = TextMobject("""
Norway coast:
Norway coast:
1.52-dimensional
""")
britain_label.next_to(britain, DOWN)
@ -2766,7 +2766,7 @@ class CompareBritainAndNorway(Scene):
self.dither()
self.play(*it.chain(*[
[
mob.set_stroke, None, 0,
mob.set_stroke, None, 0,
mob.set_fill, BLUE, 1
]
for mob in britain, norway
@ -2945,7 +2945,7 @@ class MortyLookingAtRectangle(Scene):
class Thumbnail(Scene):
def construct(self):
title = TextMobject("1.5-dimensional")
title.scale(2)
title.scale(2)
title.to_edge(UP)
@ -2956,19 +2956,3 @@ class Thumbnail(Scene):
koch_curve.to_edge(DOWN, buff = SMALL_BUFF)
self.add(koch_curve, title)

View file

@ -50,7 +50,7 @@ COUNT_TO_FRAME_NUM = {
31 : 1224,
32 : 1239,
}
class Hand(ImageMobject):
def __init__(self, num, **kwargs):
Mobject2D.__init__(self, **kwargs)
@ -101,11 +101,11 @@ class BufferedCounting(SceneFromVideo):
threshold2 = 70
matrices = [
thick_diagonal(dim, spread)
thick_diagonal(dim, spread)
for dim, spread in zip(self.shape, spreads)
]
for frame, index in zip(self.frames, it.count()):
print index, "of", len(self.frames)
print(index + "of" + len(self.frames))
blurred = cv2.GaussianBlur(frame, ksize, sigmaX)
edged = cv2.Canny(blurred, threshold1, threshold2)
buffed = reduce(np.dot, [matrices[0], edged, matrices[1]])
@ -133,7 +133,7 @@ class ClearLeftSide(SceneFromVideo):
self.highlight_region_over_time_range(
Region(lambda x, y : x < -1, shape = self.shape)
)
class DraggedPixels(SceneFromVideo):
@ -159,7 +159,7 @@ class DraggedPixels(SceneFromVideo):
index
)
], axis = 0)
class SaveEachNumber(SceneFromVideo):
def construct(self):
@ -167,7 +167,7 @@ class SaveEachNumber(SceneFromVideo):
SceneFromVideo.construct(self, path)
for count in COUNT_TO_FRAME_NUM:
path = os.path.join(
MOVIE_DIR, MOVIE_PREFIX, "images",
MOVIE_DIR, MOVIE_PREFIX, "images",
"Hand%d.png"%count
)
Image.fromarray(self.frames[COUNT_TO_FRAME_NUM[count]]).save(path)
@ -186,13 +186,13 @@ class ShowCounting(SceneFromVideo):
SceneFromVideo.construct(self, path)
total_time = len(self.frames)*self.frame_duration
for count in range(32):
print count
print(count)
mob = TexMobject(str(count)).scale(1.5)
mob.shift(0.3*LEFT).to_edge(UP, buff = 0.1)
index_range = range(
max(COUNT_TO_FRAME_NUM[count]-10, 0),
COUNT_TO_FRAME_NUM[count+1]-10
)
)
for index in index_range:
self.frames[index] = disp.paint_mobject(
mob, self.frames[index]
@ -210,7 +210,7 @@ class ShowFrameNum(SceneFromVideo):
path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, filename+".mp4")
SceneFromVideo.construct(self, path)
for frame, count in zip(self.frames, it.count()):
print count, "of", len(self.frames)
print(count + "of" + len(self.frames))
mob = Mobject(*[
TexMobject(char).shift(0.3*x*RIGHT)
for char, x, in zip(str(count), it.count())
@ -225,4 +225,4 @@ class ShowFrameNum(SceneFromVideo):
if __name__ == "__main__":
command_line_create_scene(MOVIE_PREFIX)
command_line_create_scene(MOVIE_PREFIX)

View file

@ -71,7 +71,7 @@ class ZetaTransformationScene(ComplexTransformationScene):
#See how big this line will become
diameter = abs(zeta(complex(*closest_to_one[:2])))
target_num_anchors = np.clip(
int(self.anchor_density*np.pi*diameter),
int(self.anchor_density*np.pi*diameter),
self.min_added_anchors,
self.max_added_anchors,
)
@ -91,12 +91,12 @@ class ZetaTransformationScene(ComplexTransformationScene):
epsilon = 0.1
x_range = np.arange(
max(self.x_min, self.extra_lines_x_min),
min(self.x_max, self.extra_lines_x_max),
min(self.x_max, self.extra_lines_x_max),
step_size
)
y_range = np.arange(
max(self.y_min, self.extra_lines_y_min),
min(self.y_max, self.extra_lines_y_max),
min(self.y_max, self.extra_lines_y_max),
step_size
)
vert_lines = VGroup(*[
@ -158,11 +158,11 @@ class TestZetaOnHalfPlane(ZetaTransformationScene):
self.add_transformable_plane()
self.add_extra_plane_lines_for_zeta()
self.prepare_for_transformation(self.plane)
print sum([
print(sum([
mob.get_num_points()
for mob in self.plane.family_members_with_points()
])
print len(self.plane.family_members_with_points())
]))
print(len(self.plane.family_members_with_points()))
self.apply_zeta_function()
self.dither()
@ -347,7 +347,7 @@ class PreviewZetaAndContinuation(ZetaTransformationScene):
alignment = "",
)
for s in [
"$\\displaystyle \\sum_{n=1}^\\infty \\frac{1}{n^s}$",
"$\\displaystyle \\sum_{n=1}^\\infty \\frac{1}{n^s}$",
"analytic continuation"
]
]
@ -409,7 +409,7 @@ class AssumeKnowledgeOfComplexNumbers(ComplexTransformationScene):
ShowCreation(x_line),
ShowCreation(y_line),
ShowCreation(VGroup(line, dot)),
Write(complex_number_label),
Write(complex_number_label),
)
self.play(Write(text[2]))
self.dither(2)
@ -457,7 +457,7 @@ class DefineForRealS(PiCreatureScene):
def plug_in_two(self, zeta_def):
two_def = self.get_definition("2")[0]
number_line = NumberLine(
x_min = 0,
x_min = 0,
x_max = 3,
tick_frequency = 0.25,
numbers_with_elongated_ticks = range(4),
@ -480,7 +480,7 @@ class DefineForRealS(PiCreatureScene):
frac.shift(0.5*RIGHT + 0.2*UP)
arrow = Arrow(
frac.get_bottom(), brace.get_top(),
tip_length = 0.1,
tip_length = 0.1,
buff = 0.1
)
arrow.highlight(line.get_color())
@ -489,7 +489,7 @@ class DefineForRealS(PiCreatureScene):
pi_term = TexMobject("= \\frac{\\pi^2}{6}")
pi_term.next_to(zeta_def[1], RIGHT)
pi_arrow = Arrow(
pi_term[-1].get_bottom(), pi_dot,
pi_term[-1].get_bottom(), pi_dot,
color = pi_dot.get_color()
)
approx = TexMobject("\\approx 1.645")
@ -762,7 +762,7 @@ class IgnoreNegatives(TeacherStudentsScene):
self.add(definition)
brace = Brace(definition, DOWN)
only_s_gt_1 = brace.get_text("""
Only defined
Only defined
for $s > 1$
""")
only_s_gt_1[-3].highlight(YELLOW)
@ -795,7 +795,7 @@ class RiemannFatherOfComplex(ComplexTransformationScene):
)
name.to_corner(UP+LEFT)
name.shift(0.25*DOWN)
name.add_background_rectangle()
name.add_background_rectangle()
# photo = Square()
photo = ImageMobject("Riemann", invert = False)
photo.scale_to_fit_width(5)
@ -862,7 +862,7 @@ class FromRealToComplex(ComplexTransformationScene):
def show_real_to_real(self):
zeta = self.get_zeta_definition("2", "\\frac{\\pi^2}{6}")
number_line = NumberLine(
unit_size = 2,
unit_size = 2,
tick_frequency = 0.5,
numbers_with_elongated_ticks = range(-2, 3)
)
@ -1093,7 +1093,7 @@ class FromRealToComplex(ComplexTransformationScene):
domain_words = TextMobject("""
$\\zeta(s)$ happily
converges and
converges and
makes sense
""")
domain_words.to_corner(UP+RIGHT, buff = MED_LARGE_BUFF)
@ -1164,7 +1164,7 @@ class FromRealToComplex(ComplexTransformationScene):
])
sum_terms = VGroup(*it.chain(*[
[
VGroup(*term[:3]),
VGroup(*term[:3]),
VGroup(*term[3:-1]),
term[-1],
]
@ -1187,7 +1187,7 @@ class FromRealToComplex(ComplexTransformationScene):
def get_sum_lines(self, exponent, line_thickness = 6):
powers = [0] + [
x**(-exponent)
x**(-exponent)
for x in range(1, self.num_lines_in_spiril_sum)
]
power_sums = np.cumsum(powers)
@ -1411,7 +1411,7 @@ class ComplexExponentiation(Scene):
self.dither()
walk_up_and_down()
self.dither()
curr_base = 1./9
curr_base = 1./9
self.play(Transform(denom, nine))
walk_up_and_down()
self.dither()
@ -1576,8 +1576,8 @@ class ComplexFunctionsAsTransformations(ComplexTransformationScene):
input_dots, output_dots, arrows = self.get_dots()
self.play(FadeIn(
input_dots,
run_time = 2,
input_dots,
run_time = 2,
submobject_mode = "lagged_start"
))
for in_dot, out_dot, arrow in zip(input_dots, output_dots, arrows):
@ -1847,7 +1847,7 @@ class ShowZetaOnHalfPlane(ZetaTransformationScene):
right_i_lines, left_i_lines = [
VGroup(*[
Line(
vert_vect+RIGHT,
vert_vect+RIGHT,
vert_vect+(SPACE_WIDTH+1)*horiz_vect
)
for vert_vect in UP, DOWN
@ -2060,9 +2060,9 @@ class SquiggleOnExtensions(ZetaTransformationScene):
0
])
funcs = [
shear,
mixed_scalar_func,
alt_mixed_scalar_func,
shear,
mixed_scalar_func,
alt_mixed_scalar_func,
sinusoidal_func,
]
for mob in self.left_plane.family_members_with_points():
@ -2080,7 +2080,7 @@ class SquiggleOnExtensions(ZetaTransformationScene):
self.left_plane.save_state()
for plane, dot in zip(new_left_planes, new_dots):
self.play(
Transform(self.left_plane, plane),
Transform(self.left_plane, plane),
Transform(self.dot, dot),
run_time = 3
)
@ -2100,9 +2100,9 @@ class SquiggleOnExtensions(ZetaTransformationScene):
def lock_into_place(self):
words = TextMobject(
"""Only one extension
has a """,
has a """,
"\\emph{derivative}",
"everywhere",
"everywhere",
alignment = ""
)
words.to_corner(UP+LEFT)
@ -2126,7 +2126,7 @@ class DontKnowDerivatives(TeacherStudentsScene):
self.random_blink(2)
self.student_says(
"""
I get $\\frac{df}{dx}$, just not
I get $\\frac{df}{dx}$, just not
for complex functions
""",
target_mode = "confused",
@ -2206,8 +2206,8 @@ class IntroduceAnglePreservation(VisualizingSSquared):
self.play(Blink(randy))
self.dither()
self.play(*map(FadeOut, [
randy, morty,
randy.bubble, randy.bubble.content,
randy, morty,
randy.bubble, randy.bubble.content,
morty.bubble, morty.bubble.content,
]))
@ -2253,7 +2253,7 @@ class IntroduceAnglePreservation(VisualizingSSquared):
def name_analytic(self):
equiv = TextMobject("``Analytic'' $\\Leftrightarrow$ Angle-preserving")
kind_of = TextMobject("...kind of")
for text in equiv, kind_of:
for text in equiv, kind_of:
text.scale(1.2)
text.add_background_rectangle()
equiv.highlight(YELLOW)
@ -2316,7 +2316,7 @@ class IntroduceAnglePreservation(VisualizingSSquared):
angle_tex.add_background_rectangle()
self.put_angle_tex_next_to_arc(angle_tex, arc)
angle_arrow = Arrow(
angle_tex, arc,
angle_tex, arc,
color = arc.get_color(),
buff = 0.1,
)
@ -2577,7 +2577,7 @@ class ThatsHowZetaIsDefined(TeacherStudentsScene):
def construct(self):
self.add_zeta_definition()
self.teacher_says("""
So that's how
So that's how
$\\zeta(s)$ is defined
""")
self.change_student_modes(*["hooray"]*3)
@ -2647,11 +2647,11 @@ class ManyIntersectingLinesPreZeta(ZetaTransformationScene):
class ManyIntersectingLinesPostZeta(ManyIntersectingLinesPreZeta):
CONFIG = {
"apply_zeta" : True,
"apply_zeta" : True,
# "anchor_density" : 5
}
def get_modified_line_anims(self, lines):
n_inserted_points = 30
n_inserted_points = 30
new_lines = lines.copy()
new_lines.set_stroke(width = 5)
def update_new_lines(lines_to_update):
@ -2686,7 +2686,7 @@ class ManyIntersectingLinesPostSSquared(ManyIntersectingLinesPreSSquared):
"apply_zeta" : True,
}
def get_modified_line_anims(self, lines):
n_inserted_points = 30
n_inserted_points = 30
new_lines = lines.copy()
new_lines.set_stroke(width = 5)
def update_new_lines(lines_to_update):
@ -2699,7 +2699,7 @@ class ManyIntersectingLinesPostSSquared(ManyIntersectingLinesPreSSquared):
if start.get_num_points() > 0:
start.points = np.array(end.points)
return [UpdateFromFunc(new_lines, update_new_lines)]
class ButWhatIsTheExensions(TeacherStudentsScene):
def construct(self):
self.student_says(
@ -2725,7 +2725,7 @@ class MathematiciansLookingAtFunctionEquation(Scene):
"\\zeta(s)",
"= 2^s \\pi ^{s-1}",
"\\sin\\left(\\frac{\\pi s}{2}\\right)",
"\\Gamma(1-s)",
"\\Gamma(1-s)",
"\\zeta(1-s)",
)
equation.shift(UP)
@ -2789,7 +2789,7 @@ class DiscussZeros(ZetaTransformationScene):
for mob in dots, arrows, q_marks:
self.play(ShowCreation(mob))
self.play(Write(question))
self.play(Write(question))
self.dither(2)
dots.generate_target()
for i, dot in enumerate(dots.target):
@ -2865,7 +2865,7 @@ class DiscussZeros(ZetaTransformationScene):
name.to_edge(UP)
arrow = Arrow(name.get_bottom(), 0.5*RIGHT+UP)
primes = TexMobject("2, 3, 5, 7, 11, 13, 17, \\dots")
primes.to_corner(UP+RIGHT)
primes.to_corner(UP+RIGHT)
# photo = Square()
photo = ImageMobject("Riemann", invert = False)
photo.scale_to_fit_width(5)
@ -2885,7 +2885,7 @@ class DiscussZeros(ZetaTransformationScene):
self.play(FadeIn(strip), *self.get_dot_wandering_anims())
self.play(
Write(name, run_time = 1),
Write(name, run_time = 1),
ShowCreation(arrow),
*self.get_dot_wandering_anims()
)
@ -2919,7 +2919,7 @@ class DiscussZeros(ZetaTransformationScene):
result = (np.sin(6*2*np.pi*t) + 1)*RIGHT/2
result += 3*np.cos(2*2*np.pi*t)*UP
return result
self.wandering_path = ParametricFunction(func)
for i, dot in enumerate(self.dots):
dot.target = dot.copy()
@ -2940,7 +2940,7 @@ class DiscussZeros(ZetaTransformationScene):
return lambda t : (float(self.dot_anim_count + 2*index + t)/denom)%1
return [
MoveAlongPath(
dot, self.wandering_path,
dot, self.wandering_path,
rate_func = get_rate_func(i)
)
for i, dot in enumerate(self.dots)
@ -2988,7 +2988,7 @@ class AskAboutRelationToPrimes(TeacherStudentsScene):
""", target_mode = "confused")
self.random_blink(3)
self.teacher_says("""
Perhaps in a
Perhaps in a
different video.
""", target_mode = "hesitant")
self.random_blink(3)
@ -3056,7 +3056,7 @@ class DiscussSumOfNaturals(Scene):
neg_twelfth, eq, zeta_neg_1, sum_naturals = equation = TexMobject(
"-\\frac{1}{12}",
"=",
"\\zeta(-1)",
"\\zeta(-1)",
"= 1 + 2 + 3 + 4 + \\cdots"
)
neg_twelfth.highlight(GREEN_B)
@ -3141,7 +3141,7 @@ class FinalAnimationTease(Scene):
morty = Mortimer().shift(2*(DOWN+RIGHT))
bubble = morty.get_bubble(SpeechBubble)
bubble.write("""
Want to know what
Want to know what
$\\zeta'(s)$ looks like?
""")
@ -3188,10 +3188,10 @@ class PatreonThanks(Scene):
patreon_logo.scale_to_fit_height(1.5)
patreon_logo.next_to(special_thanks, DOWN)
left_patrons = VGroup(*map(TextMobject,
left_patrons = VGroup(*map(TextMobject,
self.specific_patrons[:n_patrons/2]
))
right_patrons = VGroup(*map(TextMobject,
right_patrons = VGroup(*map(TextMobject,
self.specific_patrons[n_patrons/2:]
))
for patrons, vect in (left_patrons, LEFT), (right_patrons, RIGHT):
@ -3225,7 +3225,7 @@ class CreditTwo(Scene):
brother = PiCreature(color = GOLD_E)
brother.next_to(morty, LEFT)
brother.look_at(morty.eyes)
headphones = Headphones(height = 1)
headphones.move_to(morty.eyes, aligned_edge = DOWN)
headphones.shift(0.1*DOWN)
@ -3236,7 +3236,7 @@ class CreditTwo(Scene):
self.add(morty)
self.play(Blink(morty))
self.play(
FadeIn(headphones),
FadeIn(headphones),
Write(url),
Animation(morty)
)
@ -3359,8 +3359,3 @@ class ZetaPartialSums(ZetaTransformationScene):
Transform(symbol, sigma)
)
self.dither()

View file

@ -168,12 +168,12 @@ class Scene(object):
families = [m.submobject_family() for m in mobjects]
def is_top_level(mobject):
num_families = sum([
(mobject in family)
(mobject in family)
for family in families
])
return num_families == 1
return filter(is_top_level, mobjects)
def separate_mobjects_and_continual_animations(self, mobjects_or_continual_animations):
mobjects = []
continual_animations = []
@ -185,7 +185,7 @@ class Scene(object):
continual_animations.append(item)
else:
raise Exception("""
Adding/Removing something which is
Adding/Removing something which is
not a Mobject or a ContinualAnimation
""")
return mobjects, continual_animations
@ -249,7 +249,7 @@ class Scene(object):
def add_foreground_mobjects(self, *mobjects):
self.foreground_mobjects = list_update(
self.foreground_mobjects,
self.foreground_mobjects,
mobjects
)
self.add(*mobjects)
@ -319,12 +319,12 @@ class Scene(object):
def compile_play_args_to_animation_list(self, *args):
"""
Eacn arg can either be an animation, or a mobject method
followed by that methods arguments.
followed by that methods arguments.
This animation list is built by going through the args list,
and each animation is simply added, but when a mobject method
s hit, a MoveToTarget animation is built using the args that
follow up until either another animation is hit, another method
This animation list is built by going through the args list,
and each animation is simply added, but when a mobject method
s hit, a MoveToTarget animation is built using the args that
follow up until either another animation is hit, another method
is hit, or the args list runs out.
"""
animations = []
@ -361,7 +361,7 @@ class Scene(object):
state["method_args"].append(arg)
elif isinstance(arg, Mobject):
raise Exception("""
I think you may have invoked a method
I think you may have invoked a method
you meant to pass in as a Scene.play argument
""")
else:
@ -471,7 +471,7 @@ class Scene(object):
name = str(self)
file_path = self.get_movie_file_path(name, ".mp4")
temp_file_path = file_path.replace(".mp4", "Temp.mp4")
print "Writing to %s"%temp_file_path
print("Writing to %s"%temp_file_path)
self.args_to_rename_file = (temp_file_path, file_path)
fps = int(1/self.frame_duration)
@ -502,29 +502,3 @@ class Scene(object):
shutil.move(*self.args_to_rename_file)
else:
os.rename(*self.args_to_rename_file)

View file

@ -7,7 +7,7 @@ from scene import Scene
class SceneFromVideo(Scene):
def construct(self, file_name,
def construct(self, file_name,
freeze_last_frame = True,
time_range = None):
cap = cv2.VideoCapture(file_name)
@ -25,7 +25,7 @@ class SceneFromVideo(Scene):
start_frame, end_frame = map(lambda t : fps*t, time_range)
frame_count = end_frame - start_frame
print "Reading in " + file_name + "..."
print("Reading in " + file_name + "...")
for count in show_progress(range(start_frame, end_frame+1)):
returned, frame = cap.read()
if not returned
@ -52,6 +52,3 @@ class SceneFromVideo(Scene):
for index in range(len(self.frames)):
for i in range(3):
self.frames[index][:,:,i] = edged_frames[index]