From e3ee258d91fe7269561026601105ab57d12d4bcb Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Wed, 6 Feb 2019 21:32:42 -0800 Subject: [PATCH] Replaced merge_config with merge_dicts_recursively --- manimlib/mobject/coordinate_systems.py | 16 +++++++-------- manimlib/mobject/number_line.py | 8 ++++---- manimlib/scene/three_d_scene.py | 7 ++++--- manimlib/utils/config_ops.py | 28 ++++++++++---------------- old_projects/sphere_area.py | 2 +- 5 files changed, 28 insertions(+), 33 deletions(-) diff --git a/manimlib/mobject/coordinate_systems.py b/manimlib/mobject/coordinate_systems.py index eb325c1e..4c77c1c2 100644 --- a/manimlib/mobject/coordinate_systems.py +++ b/manimlib/mobject/coordinate_systems.py @@ -9,7 +9,7 @@ from manimlib.mobject.number_line import NumberLine from manimlib.mobject.svg.tex_mobject import TexMobject from manimlib.mobject.types.vectorized_mobject import VGroup from manimlib.utils.config_ops import digest_config -from manimlib.utils.config_ops import merge_config +from manimlib.utils.config_ops import merge_dicts_recursively from manimlib.utils.simple_functions import binary_search from manimlib.utils.space_ops import angle_of_vector @@ -120,11 +120,11 @@ class Axes(VGroup, CoordinateSystem): self.shift(self.center_point) def create_axis(self, min_val, max_val, axis_config): - new_config = merge_config([ - axis_config, - {"x_min": min_val, "x_max": max_val}, + new_config = merge_dicts_recursively( self.number_line_config, - ]) + {"x_min": min_val, "x_max": max_val}, + axis_config, + ) return NumberLine(**new_config) def coords_to_point(self, *coords): @@ -398,10 +398,10 @@ class ComplexPlane(NumberPlane): if abs(z.imag) > abs(z.real): axis = self.get_y_axis() value = z.imag - kwargs = merge_config([ - {"number_config": {"unit": "i"}}, + kwargs = merge_dicts_recursively( kwargs, - ]) + {"number_config": {"unit": "i"}}, + ) else: axis = self.get_x_axis() value = z.real diff --git a/manimlib/mobject/number_line.py b/manimlib/mobject/number_line.py index 8b65feab..4d014d41 100644 --- a/manimlib/mobject/number_line.py +++ b/manimlib/mobject/number_line.py @@ -7,7 +7,7 @@ from manimlib.mobject.numbers import DecimalNumber from manimlib.mobject.types.vectorized_mobject import VGroup from manimlib.utils.bezier import interpolate from manimlib.utils.config_ops import digest_config -from manimlib.utils.config_ops import merge_config +from manimlib.utils.config_ops import merge_dicts_recursively from manimlib.utils.simple_functions import fdiv from manimlib.utils.space_ops import normalize @@ -134,10 +134,10 @@ class NumberLine(Line): scale_val=None, direction=None, buff=None): - number_config = merge_config([ + number_config = merge_dicts_recursively( + self.decimal_number_config, number_config or {}, - self.decimal_number_config - ]) + ) scale_val = scale_val or self.number_scale_val direction = direction or self.label_direction buff = buff or self.line_to_number_buff diff --git a/manimlib/scene/three_d_scene.py b/manimlib/scene/three_d_scene.py index 8396a2a9..8cff6fb6 100644 --- a/manimlib/scene/three_d_scene.py +++ b/manimlib/scene/three_d_scene.py @@ -10,7 +10,7 @@ from manimlib.mobject.types.vectorized_mobject import VGroup from manimlib.mobject.types.vectorized_mobject import VectorizedPoint from manimlib.scene.scene import Scene from manimlib.utils.config_ops import digest_config -from manimlib.utils.config_ops import merge_config +from manimlib.utils.config_ops import merge_dicts_recursively class ThreeDScene(Scene): @@ -150,7 +150,8 @@ class SpecialThreeDScene(ThreeDScene): config = {} else: config = self.low_quality_config - ThreeDScene.__init__(self, **merge_config([kwargs, config])) + config = merge_dicts_recursively(config, kwargs) + ThreeDScene.__init__(self, **config) def get_axes(self): axes = ThreeDAxes(**self.three_d_axes_config) @@ -174,7 +175,7 @@ class SpecialThreeDScene(ThreeDScene): return axes def get_sphere(self, **kwargs): - config = merge_config([kwargs, self.sphere_config]) + config = merge_dicts_recursively(self.sphere_config, kwargs) return Sphere(**config) def get_default_camera_position(self): diff --git a/manimlib/utils/config_ops.py b/manimlib/utils/config_ops.py index 37be72a7..3c18740a 100644 --- a/manimlib/utils/config_ops.py +++ b/manimlib/utils/config_ops.py @@ -1,6 +1,5 @@ -from functools import reduce import inspect -import operator as op +import itertools as it def instantiate(obj): @@ -53,32 +52,27 @@ def digest_config(obj, kwargs, caller_locals={}): caller_locals = filtered_locals(caller_locals) all_dicts = [kwargs, caller_locals, obj.__dict__] all_dicts += static_configs - obj.__dict__ = merge_config(all_dicts) + obj.__dict__ = merge_dicts_recursively(*reversed(all_dicts)) -# TODO, priority here is backwards from dict.update. -# Should I change the convention? -def merge_config(all_dicts): +def merge_dicts_recursively(*dicts): """ Creates a dict whose keyset is the union of all the input dictionaries. The value for each key is based on the first dict in the list with that key. - First dicts have higher priority + dicts later in the list have higher priority When values are dictionaries, it is applied recursively """ - all_config = reduce(op.add, [list(d.items()) for d in all_dicts]) - config = dict() - for c in all_config: - key, value = c - if key not in config: - config[key] = value + result = dict() + all_items = it.chain(*[d.items() for d in dicts]) + for key, value in all_items: + if key in result and isinstance(result[key], dict) and isinstance(value, dict): + result[key] = merge_dicts_recursively(result[key], value) else: - # When two dictionaries have the same key, they are merged. - if isinstance(value, dict) and isinstance(config[key], dict): - config[key] = merge_config([config[key], value]) - return config + result[key] = value + return result def soft_dict_update(d1, d2): diff --git a/old_projects/sphere_area.py b/old_projects/sphere_area.py index 9dbb6558..28f69181 100644 --- a/old_projects/sphere_area.py +++ b/old_projects/sphere_area.py @@ -54,7 +54,7 @@ class SphereCylinderScene(SpecialThreeDScene): } def get_cylinder(self, **kwargs): - config = merge_config([kwargs, self.sphere_config]) + config = merge_dicts_recursively(self.sphere_config, kwargs) return Cylinder(**config) def get_cylinder_caps(self):