json udc working - meets spec

This commit is contained in:
Joshua E. Jodesty 2019-04-03 15:33:38 -04:00
parent a57e9d5ea3
commit 875f370c5e
5 changed files with 186 additions and 40 deletions

View File

@ -1,11 +1,10 @@
from collections import namedtuple
from typing import Any, Callable, Dict, List, Tuple
from pathos.pools import ThreadPool as TPool
from copy import deepcopy
from fn.op import foldr, call
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)
@ -69,34 +68,16 @@ class Executor:
) -> List[Dict[str, Any]]:
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))
# ToDo: add env_proc generator to `last_in_copy` iterator as wrapper function
# ToDo: Can be multithreaded ??
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()))
def generate_record(state_funcs):
for f in state_funcs:
# ToDo: Create Named Tuple Here
yield self.state_update_exception(f(var_dict, sub_step, sL, new_last_in_obj, _input))
yield self.state_update_exception(f(var_dict, sub_step, sL, last_in_obj, _input))
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
last_in_copy: Dict[str, Any] = dict(generate_record(state_funcs))
for k in last_in_obj:
if k not in last_in_copy:

View File

@ -2,8 +2,6 @@ from typing import Dict, List
from collections import defaultdict
from itertools import product
import warnings
from inspect import getmembers, ismethod
from copy import deepcopy, copy
from collections import namedtuple
@ -11,25 +9,35 @@ class objectview(object):
def __init__(self, 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))
filtered_current_funcs['hydra_type'] = Dict
filtered_current_funcs['current'] = current
filtered_current_funcs['past'] = past
self.members_dict = d
self.hybrid_members = filtered_current_funcs
def get_members(self):
return self.members_dict
def get_hybrid_members(self):
return self.hybrid_members
def get_object(self):
return objectview(self.members_dict)
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):

View File

@ -2,7 +2,7 @@ import pandas as pd
from tabulate import tabulate
# The following imports NEED to be in the exact order
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

View File

@ -19,7 +19,7 @@ class MyClassA(object):
# self.past = copy(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 #self #old_self #self.x
return self #.x #self #old_self #self.x
def getMemID(self):
return str(hex(id(self)))
@ -75,7 +75,7 @@ g: Dict[str, List[MyClassA]] = {'udc': [MyClassA]}
# genesis state
udc = MyClassA(0)
# 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_members = hydra.get_hybrid_members()
# hydra_obj = namedtuple("Hydra", hydra_members.keys())(*hydra_members.values())

View File

@ -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)