json udc working - meets spec
This commit is contained in:
parent
a57e9d5ea3
commit
875f370c5e
|
|
@ -1,11 +1,10 @@
|
||||||
from collections import namedtuple
|
|
||||||
from typing import Any, Callable, Dict, List, Tuple
|
from typing import Any, Callable, Dict, List, Tuple
|
||||||
from pathos.pools import ThreadPool as TPool
|
from pathos.pools import ThreadPool as TPool
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from fn.op import foldr, call
|
from fn.op import foldr, call
|
||||||
|
|
||||||
from cadCAD.engine.utils import engine_exception
|
from cadCAD.engine.utils import engine_exception
|
||||||
from cadCAD.utils import flatten, UDC_Wrapper, objectview
|
from cadCAD.utils import flatten
|
||||||
|
|
||||||
id_exception: Callable = engine_exception(KeyError, KeyError, None)
|
id_exception: Callable = engine_exception(KeyError, KeyError, None)
|
||||||
|
|
||||||
|
|
@ -69,34 +68,16 @@ class Executor:
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
|
|
||||||
last_in_obj: Dict[str, Any] = deepcopy(sL[-1])
|
last_in_obj: Dict[str, Any] = deepcopy(sL[-1])
|
||||||
udc = var_dict[0]['udc']
|
|
||||||
|
|
||||||
_input: Dict[str, Any] = self.policy_update_exception(self.get_policy_input(var_dict, sub_step, sL, last_in_obj, policy_funcs))
|
_input: Dict[str, Any] = self.policy_update_exception(self.get_policy_input(var_dict, sub_step, sL, last_in_obj, policy_funcs))
|
||||||
|
|
||||||
# ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function
|
# ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function
|
||||||
# ToDo: Can be multithreaded ??
|
# ToDo: Can be multithreaded ??
|
||||||
|
def generate_record(state_funcs):
|
||||||
def generate_record(state_funcs, alt_udc_dict):
|
|
||||||
for k, v in last_in_obj.items():
|
|
||||||
if isinstance(v, dict) and hasattr(v, 'class_id'):
|
|
||||||
del last_in_obj[k]
|
|
||||||
|
|
||||||
new_last_in_obj = dict(list(last_in_obj.items()) + list(alt_udc_dict.items()))
|
|
||||||
for f in state_funcs:
|
for f in state_funcs:
|
||||||
# ToDo: Create Named Tuple Here
|
yield self.state_update_exception(f(var_dict, sub_step, sL, last_in_obj, _input))
|
||||||
yield self.state_update_exception(f(var_dict, sub_step, sL, new_last_in_obj, _input))
|
|
||||||
|
|
||||||
|
last_in_copy: Dict[str, Any] = dict(generate_record(state_funcs))
|
||||||
udc_dict = {
|
|
||||||
k: UDC_Wrapper(
|
|
||||||
v['current'],
|
|
||||||
udc(**v['current'].__dict__),
|
|
||||||
current_functions=['update']
|
|
||||||
).get_hybrid_members()
|
|
||||||
for k, v in last_in_obj.items() if isinstance(v, dict) and 'current' in v.keys()
|
|
||||||
}
|
|
||||||
last_in_copy: Dict[str, Any] = dict(generate_record(state_funcs, udc_dict))
|
|
||||||
del udc_dict
|
|
||||||
|
|
||||||
for k in last_in_obj:
|
for k in last_in_obj:
|
||||||
if k not in last_in_copy:
|
if k not in last_in_copy:
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ from typing import Dict, List
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from itertools import product
|
from itertools import product
|
||||||
import warnings
|
import warnings
|
||||||
from inspect import getmembers, ismethod
|
|
||||||
from copy import deepcopy, copy
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,25 +9,35 @@ class objectview(object):
|
||||||
def __init__(self, d):
|
def __init__(self, d):
|
||||||
self.__dict__ = d
|
self.__dict__ = d
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
filtered_members = {k: v for k, v in self.__dict__.items() if k != 'obj'}
|
||||||
|
return f"{filtered_members}"
|
||||||
|
|
||||||
class UDC_Wrapper(object):
|
|
||||||
def __init__(self, current, past, current_functions, past_functions=[]):
|
|
||||||
current_funcs = dict(getmembers(current, ismethod))
|
|
||||||
|
|
||||||
filtered_current_funcs = {k: v for k, v in current_funcs.items() if k in current_functions}
|
class UDC(object):
|
||||||
|
def __init__(self, obj):
|
||||||
|
d = vars(obj) # somehow is enough
|
||||||
|
d['obj'] = obj
|
||||||
|
|
||||||
filtered_current_funcs.update(vars(past))
|
self.members_dict = d
|
||||||
filtered_current_funcs['hydra_type'] = Dict
|
|
||||||
filtered_current_funcs['current'] = current
|
|
||||||
filtered_current_funcs['past'] = past
|
|
||||||
|
|
||||||
self.hybrid_members = filtered_current_funcs
|
def get_members(self):
|
||||||
|
return self.members_dict
|
||||||
|
|
||||||
def get_hybrid_members(self):
|
def get_object(self):
|
||||||
return self.hybrid_members
|
return objectview(self.members_dict)
|
||||||
|
|
||||||
def get_namedtuple(self):
|
def get_namedtuple(self):
|
||||||
return namedtuple("Hydra", self.hybrid_members.keys())(*self.hybrid_members.values())
|
return namedtuple("Hydra", self.members_dict.keys())(*self.members_dict.values())
|
||||||
|
|
||||||
|
|
||||||
|
# class UDC_Wrapper2(object):
|
||||||
|
# def __init__(self, obj, functions):
|
||||||
|
#
|
||||||
|
# self.obj = obj
|
||||||
|
#
|
||||||
|
# def get_object(self):
|
||||||
|
# return objectview(self.obj.__dict__)
|
||||||
|
|
||||||
|
|
||||||
def pipe(x):
|
def pipe(x):
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import pandas as pd
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
# The following imports NEED to be in the exact order
|
# The following imports NEED to be in the exact order
|
||||||
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
from cadCAD.engine import ExecutionMode, ExecutionContext, Executor
|
||||||
from simulations.validation import config_udc_json2
|
from simulations.validation import config_udc_json3
|
||||||
from cadCAD import configs
|
from cadCAD import configs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class MyClassA(object):
|
||||||
# self.past = copy(self)
|
# self.past = copy(self)
|
||||||
self.x += 1
|
self.x += 1
|
||||||
print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}")
|
print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}")
|
||||||
return self.x #self #old_self #self.x
|
return self #.x #self #old_self #self.x
|
||||||
|
|
||||||
def getMemID(self):
|
def getMemID(self):
|
||||||
return str(hex(id(self)))
|
return str(hex(id(self)))
|
||||||
|
|
@ -75,7 +75,7 @@ g: Dict[str, List[MyClassA]] = {'udc': [MyClassA]}
|
||||||
# genesis state
|
# genesis state
|
||||||
udc = MyClassA(0)
|
udc = MyClassA(0)
|
||||||
# namedtuple("Hydra", self.hybrid_members.keys())(*self.hybrid_members.values())
|
# namedtuple("Hydra", self.hybrid_members.keys())(*self.hybrid_members.values())
|
||||||
# udc_json = {'current': udc, 'past': udc}
|
udc_json = {'current': udc, 'past': udc}
|
||||||
hydra = UDC_Wrapper(udc, udc, current_functions=['update'])
|
hydra = UDC_Wrapper(udc, udc, current_functions=['update'])
|
||||||
hydra_members = hydra.get_hybrid_members()
|
hydra_members = hydra.get_hybrid_members()
|
||||||
# hydra_obj = namedtuple("Hydra", hydra_members.keys())(*hydra_members.values())
|
# hydra_obj = namedtuple("Hydra", hydra_members.keys())(*hydra_members.values())
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,157 @@
|
||||||
|
from datetime import timedelta
|
||||||
|
from cadCAD.utils import UDC
|
||||||
|
from cadCAD.configuration import append_configs
|
||||||
|
from cadCAD.configuration.utils import ep_time_step, config_sim
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
|
||||||
|
# ToDo: Create member for past value
|
||||||
|
class MyClassA(object):
|
||||||
|
def __init__(self, x):
|
||||||
|
self.x = x
|
||||||
|
print(f"Instance of MyClass (mem_id {hex(id(self))}) created with value {self.x}")
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.x += 1
|
||||||
|
print(f"Instance of MyClass (mem_id {hex(id(self))}) has been updated, has now value {self.x}")
|
||||||
|
# return self.x
|
||||||
|
return self
|
||||||
|
|
||||||
|
def getMemID(self):
|
||||||
|
return str(hex(id(self)))
|
||||||
|
|
||||||
|
# can be accessed after an update within the same substep and timestep
|
||||||
|
# ToDo: id sensitive to lineage, rerepresent
|
||||||
|
def __str__(self):
|
||||||
|
# return f"{self.__class__.__name__} - {hex(id(self))} - {self.__dict__}"
|
||||||
|
return f"{self.__dict__}"
|
||||||
|
|
||||||
|
|
||||||
|
# a is Correct, and classX's value is Incorrect
|
||||||
|
# Expected: a == classX's value
|
||||||
|
# b should be tracking classX's value and a:
|
||||||
|
# b should be the same value as the previous classX value and the previous a value
|
||||||
|
# https://pymotw.com/2/multiprocessing/communication.html
|
||||||
|
# ccc = MyClassA
|
||||||
|
# udc = ccc(0)
|
||||||
|
# print(MyClassA(**udc.__dict__).__dict__)
|
||||||
|
|
||||||
|
g: Dict[str, List[MyClassA]] = {'udc': [MyClassA]}
|
||||||
|
|
||||||
|
# udcB = MyClassB()
|
||||||
|
|
||||||
|
# z = MyClass()
|
||||||
|
# pointer(z)
|
||||||
|
# separate thread/process for UCD with async calls to this thread/process
|
||||||
|
|
||||||
|
# genesis state
|
||||||
|
# udc_obj = MyClassA(0)
|
||||||
|
# hydra = UDC_Wrapper(udc, udc, current_functions=['update'])
|
||||||
|
# hydra = UDC_Wrapper(udc_obj, functions=['update'])
|
||||||
|
hydra = UDC(MyClassA(0))
|
||||||
|
hydra_members = hydra.get_object()
|
||||||
|
|
||||||
|
state_dict = {
|
||||||
|
'a': 0,
|
||||||
|
'b': 0,
|
||||||
|
'j': 0,
|
||||||
|
"hydra_members": hydra_members,
|
||||||
|
'timestamp': '2019-01-01 00:00:00'
|
||||||
|
}
|
||||||
|
|
||||||
|
timestep_duration = timedelta(minutes=1) # In this example, a timestep has a duration of 1 minute.
|
||||||
|
ts_format = '%Y-%m-%d %H:%M:%S'
|
||||||
|
def time_model(_g, step, sL, s, _input):
|
||||||
|
y = 'timestamp'
|
||||||
|
x = ep_time_step(s, dt_str=s['timestamp'], fromat_str=ts_format, _timedelta=timestep_duration)
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
|
||||||
|
def HydraMembers(_g, step, sL, s, _input):
|
||||||
|
y = 'hydra_members'
|
||||||
|
obj = s['hydra_members'].obj
|
||||||
|
obj.update()
|
||||||
|
x = UDC(obj).get_object()
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
|
||||||
|
def A(_g, step, sL, s, _input):
|
||||||
|
y = 'a'
|
||||||
|
x = s['a'] + 1
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
def B(_g, step, sL, s, _input):
|
||||||
|
y = 'b'
|
||||||
|
# x = s['hydra_members']['x']
|
||||||
|
x = s['hydra_members'].x
|
||||||
|
# x = s['hydra_obj'].x
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
|
||||||
|
def J(_g, step, sL, s, _input):
|
||||||
|
y = 'j'
|
||||||
|
# x = s['hydra_members']['x']
|
||||||
|
x = s['hydra_members'].x
|
||||||
|
# x = s['hydra_obj'].x
|
||||||
|
# x = s['hydra_view'].x
|
||||||
|
return (y, x)
|
||||||
|
|
||||||
|
|
||||||
|
partial_state_update_blocks = {
|
||||||
|
'PSUB1': {
|
||||||
|
'behaviors': {
|
||||||
|
},
|
||||||
|
'states': {
|
||||||
|
# 'ca': CA,
|
||||||
|
'a': A,
|
||||||
|
'b': B,
|
||||||
|
# 'hydra': Hydra,
|
||||||
|
'hydra_members': HydraMembers,
|
||||||
|
# 'hydra_obj': HydraObj,
|
||||||
|
# 'hydra_view': HydraView,
|
||||||
|
# 'i': I,
|
||||||
|
'j': J,
|
||||||
|
# 'k': K,
|
||||||
|
'timestamp': time_model,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'PSUB2': {
|
||||||
|
'behaviors': {
|
||||||
|
},
|
||||||
|
'states': {
|
||||||
|
# 'ca': CA,
|
||||||
|
'a': A,
|
||||||
|
'b': B,
|
||||||
|
# 'hydra': Hydra,
|
||||||
|
'hydra_members': HydraMembers,
|
||||||
|
# 'hydra_obj': HydraObj,
|
||||||
|
# 'hydra_view': HydraView,
|
||||||
|
# 'i': I,
|
||||||
|
'j': J,
|
||||||
|
# 'k': K,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'PSUB3': {
|
||||||
|
'behaviors': {
|
||||||
|
},
|
||||||
|
'states': {
|
||||||
|
'a': A,
|
||||||
|
'b': B,
|
||||||
|
# 'hydra': Hydra,
|
||||||
|
'hydra_members': HydraMembers,
|
||||||
|
# 'hydra_obj': HydraObj,
|
||||||
|
# 'hydra_view': HydraView,
|
||||||
|
# 'i': I,
|
||||||
|
'j': J,
|
||||||
|
# 'k': K,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sim_config = config_sim({
|
||||||
|
"N": 2,
|
||||||
|
"T": range(4),
|
||||||
|
"M": g
|
||||||
|
})
|
||||||
|
|
||||||
|
append_configs(sim_config, state_dict, {}, {}, {}, partial_state_update_blocks)
|
||||||
Loading…
Reference in New Issue