Source code for eppy3000.epj_mmapping

# Copyright (c) 2022 Santosh Philip
# =======================================================================
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# =======================================================================

"""
Subclass from collections.abc.MutableMapping to get finer control over a dict like
object.

epj.epobjects is a dict and is not connected to epj.epj

There are 2 dicts:

- epj.epj is the real dict where the epJSON data is held as a dict
- in eppy3000 one does not work directly on epj.epj
- one works on epj.epobjects that holds the same data as epj.epj
- this means that any operations done on epj.epobjects should make
- equivalent changes in epj.epj

This can be done thru subclassing collections.abc.MutableMapping, rather than subclassing dict

https://stackoverflow.com/questions/3387691/how-to-perfectly-override-a-dict

# Alex Martelli describes how to use collections.MutableSequence in
# <http://stackoverflow.com/questions/3487434/overriding-append-method-after-inheriting-from-a-python-list>
"""
# from the link
# https://stackoverflow.com/questions/3387691/how-to-perfectly-override-a-dict
# loolks like we can have a case insensitive keys
# and still retain the original case of the key


# Note:
# The values of the dict are lists
# the list does not have to be subclasses from collections.abc.MutableSequence
# as eppy does
# since bothe the dicts will point to the same list

# how do we incrementally implement this ??
# start by implementing epj.popepobject, epj.removeepobject & epj.removeallepobjects

from collections.abc import MutableMapping
from collections.abc import MutableSequence

# TODO - unit tests. use samples from main() and commented out code at the end of file
# TODO


[docs]def epjsequence2dict(epjs): """convert the epjsequence to a dict to compare to epj[key]""" return {item["eppyname"]: {key: item[key] for key in item} for item in epjs}
[docs]class EpjSequence(MutableSequence): """simple Mutable Sequence to stes to ut some stuff""" def __init__(self, adict, theepj=None): super(EpjSequence, self).__init__() self.theepj = theepj self.list1 = [adict[key] for key in adict] def __getitem__(self, i): return self.list1[i] def __setitem__(self, i, v): oldv = self.list1[i] self.theepj[oldv["eppykey"]].pop(oldv["eppyname"]) self.theepj[v["eppykey"]][v["eppyname"]] = v self.list1[i] = v def __delitem__(self, i): val = self.list1[i] del self.list1[i] self.theepj[val["eppykey"]].pop(val["eppyname"]) def __len__(self): return len(self.list1) # __setitem__ should take care of this.
[docs] def insert(self, i, v): self.theepj[v["eppykey"]][v["eppyname"]] = v self.list1.insert(i, v)
def __str__(self): return self.list1.__str__() def __repr__(self): return self.list1.__repr__()
# # TODO - not sure # def __eq__(self, other): # """Test for equality uses the IDF.model.dt list, list2.""" # return self.list1 == other.list1
[docs]class EpjMapping(MutableMapping): """simple Mutable mapping to test out some stuff""" def __init__(self, theepj): super(EpjMapping, self).__init__() self.theepj = theepj self.store = { key: EpjSequence(self.theepj[key], self.theepj) for key in self.theepj } def __getitem__(self, key): return self.store[self._keytransform(key)] def __setitem__(self, key, value): self.store[self._keytransform(key)] = value self.theepj[key] = epjsequence2dict(value) def __delitem__(self, key): del self.store[self._keytransform(key)] del self.theepj[key] def __iter__(self): return iter(self.store) def __len__(self): return len(self.store) def _keytransform(self, key): return key # --- not needed, but coded for readability during usage ---- def __str__(self): return self.store.__str__() def __repr__(self): return self.store.__repr__()
[docs] def keys(self): return self.store.keys()
[docs]def eppyfields(epj): """put eppy fields into epj""" for key in epj: for kkey in epj[key]: epj[key][kkey]["eppykey"] = key epj[key][kkey]["eppyname"] = kkey return epj
[docs]def main(): # print("Main") # manufactur an epj epj = dict( Zone=dict(zone1=dict(area=15, type="conditioned")), Wall=dict(wall1=dict(area=23, ZoneName="zone1")), ) epj = eppyfields(epj) epjmm = EpjMapping(epj)
# print(epjmm.keys()) # print(epjmm) if __name__ == "__main__": main() # print("Main") # # manufacture an epj # epj = dict(Zone=dict(zone1=dict(area=15, type="conditioned")), Wall=dict(wall1=dict(area=23, ZoneName="zone1"))) # # for key in epj: # # EpjSequence(epj[key]) # # {key:EpjSequence(theepj[key]) for key in theepj} # epj = eppyfields(epj) # mm = EpjMapping(epj) # zones = mm['Zone'] # newzone = dict(eppykey='Zone', eppyname='new zone', area=16, type='unconditioned') # zones[0] = newzone # print(mm) # print(epj) # mm.pop('Zone') # print(mm) # print(epj)