def test_overriden_refs(): m = mx.new_model() base = mx.new_space("base") sub = mx.new_space("sub", bases=base) def foo(x): return bar base.new_cells(formula=foo) m.bar = 2 # Add global ref base.bar = 3 # Add base ref assert sub.foo(1) == 3 # Base ref base.bar = 4 # Change base ref assert sub.foo(1) == 4 # Updated base ref sub.bar = 5 # Add self ref assert sub.foo(1) == 5 # self ref del sub.bar # Del self ref assert sub.foo(1) == 4 # Base ref del base.bar # Del base ref assert sub.foo(1) == 2 # Global ref
def dyntotal(): """ Model-----s_base[id]-----a(i) | +--b(i, j) +--s[id] | +--Tot_func | +--m """ m = mx.new_model() s_base = mx.new_space('s_base', formula=lambda id: None) @mx.defcells def a(i): return i @mx.defcells def b(i, j): return i * j m.Tot_func = Tot_func m.m = m s = mx.new_space('s', formula=s_arg) return m
def test_serialize_refmode(tmp_path): """ m---A---RefDynCells --(abs)-->B[1, 2].foo | +-RefSpace --(rel)-->B | +-RefCells --(auto)-->B.foo | +-B[x, y]---foo """ m = mx.new_model() A = mx.new_space('A') B = mx.new_space('B') B.parameters = ('x', 'y') @mx.defcells def foo(x): return x A.absref(RefDynCells=B[1, 2].foo) A.relref(RefSpace=B) A.RefCells = B.foo m.write(tmp_path / 'refpickle') m2 = mx.read_model(tmp_path / 'refpickle') assert m2.A.RefSpace is m2.B assert m2.A.RefDynCells is m2.B[1, 2].foo assert m2.A.RefCells is m2.B.foo assert m2.A._get_object('RefSpace', as_proxy=True).refmode == "relative" assert m2.A._get_object('RefDynCells', as_proxy=True).refmode == "absolute" assert m2.A._get_object('RefCells', as_proxy=True).refmode == "auto"
def test_copy_error_name_conflict(): """ Base<------Sub Source | | | SpaceA SpaceA* foo """ m, base = mx.new_model(), mx.new_space("Base") sub = m.new_space(bases=base) base.new_space("SpaceA") source = mx.new_space("Source") source.new_cells("foo") with pytest.raises(ValueError): source.copy(base, "SpaceA")
def test_log_input(tmp_path, func_or_meth, write_or_zip): import pandas as pd m, s = mx.new_model(), mx.new_space('SpaceA') ns = s.new_space('SpaceB') @mx.defcells def foo(x): return x foo[0] = pd.DataFrame() foo[2] = 1 ns.parameters = ("x", ) ns[3].foo[3] = 1 s.parameters = ("a", ) s["abc"].SpaceB.foo[3] = "defg" if func_or_meth == "func": getattr(mx, write_or_zip + "_model")(m, tmp_path / "model", log_input=True) else: getattr(m, write_or_zip)(tmp_path / "model", log_input=True) s = ziputil.read_str(tmp_path / "model/_input_log.txt") assert s == sample_log
def test_false_value(tmp_path, write_method): # https://github.com/fumitoh/modelx/issues/39 m = mx.new_model() s = mx.new_space() s.a = False getattr(mx, write_method)(m, tmp_path / "model") m2 = mx.read_model(tmp_path / "model")
def test_multiple_params(tmp_path, write_method): m, s = mx.new_model(), mx.new_space() s.new_cells_from_csv(filepath=CSV_MULTI_PARAMS, cells=None, param=None, index_col=[0, 1]) modelpath = tmp_path / "csv_mult_params" getattr(mx, write_method)(m, modelpath) assert ziputil.exists(modelpath / s.name / CSV_MULTI_PARAMS.name) m2 = mx.read_model(modelpath) # Write twice to check copy from renamed backup. getattr(mx, write_method)(m2, modelpath) m2 = mx.read_model(modelpath) # Compare components compare_model(m, m2) # Compare values trg = m2.spaces[s.name] for cells, offset in zip(["Cells1", "Cells2"], [1000, 2000]): assert trg.cells[cells].parameters == ("Param1", "Param2") for param in range(16): assert trg.cells[cells](param, param + 100) == offset + param
def test_dynamic_space_created_before_base_ref_assignment(): # https://github.com/fumitoh/modelx/issues/25 m, s1 = mx.new_model(), mx.new_space('s1') s2 = m.new_space(name='s2', formula=lambda t: None) s2(0) # Create dynamic space before ref assignment s2.a = 1 assert s2(0).a == 1
def test_copy_defined(parent): """ Base----Child---foo | Sub(Base)----bar """ m, b = mx.new_model(), mx.new_space("Base") b.new_space("Child") @mx.defcells def foo(x): return x s = m.new_space("Sub", bases=b) @mx.defcells def bar(y): return y if parent == "model": parent = m else: parent = m.new_space() bc = b.copy(parent, "BaseCopy", True) assert "foo" in bc.Child.cells sc = s.copy(parent, "SubCopy", True) assert "Child" not in sc.spaces assert "bar" in sc.cells
def test_single_param(tmp_path): m, s = mx.new_model(), mx.new_space() s.new_cells_from_csv(filepath=CSV_SINGLE_PARAM, cells=None, param=None, index_col=0) modelpath = tmp_path / "csv_single_param" mx.write_model(m, modelpath) assert modelpath.joinpath(CSV_SINGLE_PARAM.name).exists() m2 = mx.read_model(modelpath) # Write twice to check copy from renamed backup. mx.write_model(m2, modelpath) m2 = mx.read_model(modelpath) # Compare components compare_model(m, m2) # Compare values trg = m2.spaces[s.name] for cells, offset in zip(["Cells1", "Cells2"], [1000, 2000]): assert trg.cells[cells].parameters == ("Param", ) for param in range(16): assert trg.cells[cells](param) == offset + param
def test_change_attrref(): """ m---s---bar<-m.bar | +--bar[a]---x """ m = mx.new_model() s = m.new_space() @mx.defcells def foo(x): return bar.x @mx.defcells def qux(y): return bar[1].x s2 = mx.new_space("bar", formula=lambda a: None) s.bar = s2 s2.x = "bar" assert foo(3) == qux(3) == "bar" s2.x = "baz" assert foo(3) == qux(3) == "baz"
def test_set_parameters(): s = mx.new_space() s.parameters = ('x', 'y=1') assert s[1].x == 1 assert s[2].y == 1 assert s[2, 3].x == 2 assert s[2, 3].y == 3
def test_delattr_space(testmodel): """ A---Child """ space = new_space("A") child = space.new_space("Child") del space.Child assert space.named_spaces == {} assert not child._is_valid()
def test_baseattrs(): s = mx.new_space() s.bar = 1 attrs = mx.get_object(s.fullname + "." + "bar", as_proxy=True)._baseattrs assert attrs["name"] == "bar" assert attrs["fullname"] == s.fullname + "." + "bar" assert attrs["repr"] == "bar" assert attrs["namedid"] == s.name + ".bar"
def testspace(): m, s = mx.new_model(), mx.new_space() s.new_cells(name="func1_code", formula=func1) s.new_cells(name="func1_src", formula=src_func1) s.new_cells(name="lambda1_code", formula=lambda x: 3 * x) s.new_cells(name="lambda1_src", formula="lambda x: 3 * x") return s
def test_multinherit_change_baseref(): """ base1.x base2.x +-----+---+ | sub.x """ m, base1 = mx.new_model(), mx.new_space("base1") base2 = mx.new_space("base2") base1.x = 1 base2.x = 2 sub = mx.new_space(bases=[base1, base2]) assert sub.x == 1 base2.x = 3 assert sub.x == 1 del base1.x assert sub.x == 3
def derived_sample(): model, root = mx.new_model(), mx.new_space(name="root") A = root.new_space(name="A") B = A.new_space("B") C = root.new_space(name="C", bases=A) D = C.B.new_space(name="D") E = root.new_space(name="E", bases=C) return model
def testmodel(): """ TestModel-----TestSpace[a]-----foo | +--m = 1 +--n = "abc" +--t = nested sequences +--u = dict +--v = TestModel +--w = foo | +--Another +s = Another """ m, s = mx.new_model("TestModel"), mx.new_space(name='TestSpace') m.doc = textwrap.dedent("""\ This is a model docstring 3rd line 4th line """) s.doc = textwrap.dedent("""\ This is a space docstring 3rd line 4th line """) @mx.defcells def foo(x): # Comment return x # Comment bar = s.new_cells(name='bar', formula=lambda x: x) bar.doc = "doc of lambda" s.formula = lambda a: None s.m = 1 s.n = "abc" s.o = [1, "2"] s.t = (1, 2, "藍上夫", (3, 4.33), [5, None, (7, 8, [9, 10], "ABC")]) s.u = {3: '4', '5': ['6', 7]} # modelx objects as refs s.v = m s.w = foo an = m.new_space(name="Another") s.s = an return m
def test_duplicate_model_ref(): m, s = mx.new_model(), mx.new_space() m.x = "model x" assert s.x == "model x" s.x = "space x" assert s.x == "space x" del s.x assert s.x == "model x" del m.x with pytest.raises(AttributeError): s.x
def testmodel(): model, space = ( mx.new_model(name="testmodel"), mx.new_space(name="testspace"), ) space.new_cells(formula=foo) space.bar = 3 space.new_cells(formula=baz) return model
def test_save_again(tmpdir_factory): m, s = mx.new_model(), mx.new_space() @mx.defcells def a(): return 1 file = str(tmpdir_factory.mktemp("data").join("test_save_again.mx")) m.save(file) m2 = mx.restore_model(file) m2.save(file)
def test_del_base_in_model(): m, base = mx.new_model(), mx.new_space("Base") child = base.new_space("BaseChild") cells = base.new_cells("BaseCells") child.new_cells("BaseChildCells") m.new_space("Sub", bases=base) del m.Base assert not m.Sub.cells assert not m.Sub.spaces
def samplecells(request): m, s = mx.new_model(), mx.new_space("Source") @mx.defcells def foo(x): return x foo[0] = 1 s.new_cells("bar", lambda x: 2 * x) s.bar[0] = 1 return s.cells[request.param]
def test_absolute_reference(basic_relref): """Sub->Base.ChildB""" Base = basic_relref.Base Sub = mx.new_space("Sub", bases=Base.ChildB) assert Sub.A is Base.ChildA assert Sub.f is Base.ChildA.foo Base.ChildA.c = 3 assert Sub.f() == 3
def test_max_recursion(): m, s = mx.new_model(), mx.new_space() @mx.defcells def foo(x): if x == 0: return 0 else: return foo(x-1) + 1 assert foo(maxdepth) == maxdepth
def testspace(): s = mx.new_space() def foo(x): return foo(x - 1) + 1 if x > 0 else 0 foo = s.new_cells(formula=foo) foo[10] return s
def constcells(): model, space = new_model(), new_space() @defcells def bar(): return 3 @defcells def baz(): return 4 return space
def test_write_cells_from_pandas(tmp_path, write_method): m, space = mx.new_model(), mx.new_space() space.new_cells_from_pandas(testdf) modelpath = tmp_path / "write_cells_from_pandas" getattr(mx, write_method)(m, modelpath) m2 = mx.read_model(modelpath) compare_model(m, m2) assert space.frame.equals(m2.spaces[space.name].frame)
def str_values(): m, s = mx.new_model('Model2'), mx.new_space('Space2') @defcells def a(name): return 'Hello ' + name @defcells def b(name): return a(name) return m
def test_del_global_attrref(): """ m-----SpaceA-----foo +--SpaceB +--s2 +--x """ m = mx.new_model() s = mx.new_space("SpaceA") @mx.defcells def foo(i): return s2.x s2 = mx.new_space(name="SpaceB", formula=lambda a: None) s.s2 = s2 m.x = 3 assert foo(3) == 3 del m.x with SuppressFormulaError(): with pytest.raises(AttributeError): foo(3)