Skip to content

Commit

Permalink
Remove Tag attribute from MeasureSet (#754)
Browse files Browse the repository at this point in the history
* climada.entity.measure: remove Tag from MeasureSet
* test_entity: reestablish miinimal test for read_mat
* climada.entity.measures.test: adapt to removed tag
* remove tag from tutorial, simplify pydoc
* Fix Entity.__str__ and add test

---------

Co-authored-by: Lukas Riedel <[email protected]>
  • Loading branch information
emanuel-schmid and peanutfun authored Jul 13, 2023
1 parent 4e01450 commit c9e9b58
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 287 deletions.
20 changes: 7 additions & 13 deletions climada/entity/entity_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,14 @@ def __init__(
self.measures = MeasureSet() if measure_set is None else measure_set

@classmethod
def from_mat(cls, file_name, description=''):
def from_mat(cls, file_name):
"""Read MATLAB file of climada.
Parameters
----------
file_name : str, optional
file name(s) or folder name
containing the files to read
description : str or list(str), optional
one description of the
data or a description of each data file
Returns
-------
Expand All @@ -99,8 +96,8 @@ def from_mat(cls, file_name, description=''):
exposures=Exposures.from_mat(file_name),
disc_rates=DiscRates.from_mat(file_name),
impact_func_set=ImpactFuncSet.from_mat(file_name),
measure_set=MeasureSet.from_mat(file_name, description)
)
measure_set=MeasureSet.from_mat(file_name),
)

def read_mat(self, *args, **kwargs):
"""This function is deprecated, use Entity.from_mat instead."""
Expand Down Expand Up @@ -132,14 +129,14 @@ def from_excel(cls, file_name, description=''):

dr = DiscRates.from_excel(file_name)
impf_set = ImpactFuncSet.from_excel(file_name)
meas_set = MeasureSet.from_excel(file_name, description)
meas_set = MeasureSet.from_excel(file_name)

return cls(
exposures=exp,
disc_rates=dr,
impact_func_set=impf_set,
measure_set=meas_set
)
measure_set=meas_set,
)

def read_excel(self, *args, **kwargs):
"""This function is deprecated, use Entity.from_excel instead."""
Expand Down Expand Up @@ -183,9 +180,6 @@ def __setattr__(self, name, value):
super().__setattr__(name, value)

def __str__(self):
return 'Exposures: \n' + self.exposures.tag.__str__() + \
'\nDiscRates: \n' + self.disc_rates.tag.__str__() + \
'\nImpactFuncSet: \n' + self.impact_funcs.tag.__str__() + \
'\nMeasureSet: \n' + self.measures.tag.__str__()
return 'Exposures: \n' + self.exposures.tag.__str__()

__repr__ = __str__
28 changes: 6 additions & 22 deletions climada/entity/measures/measure_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import xlsxwriter

from climada.entity.measures.base import Measure
from climada.util.tag import Tag
import climada.util.hdf5_handler as u_hdf5

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -89,26 +88,21 @@ class MeasureSet():
Attributes
----------
tag : climada.util.tag.Tag
information about the source data
_data : dict
Contains Measure objects. This attribute is not suppossed to be accessed directly.
Use the available methods instead.
"""

def __init__(
self,
measure_list: Optional[List[Measure]] = None,
tag: Optional[Tag] = None,
measure_list: Optional[List[Measure]] = None
):
"""Initialize a new MeasureSet object with specified data.
Parameters
----------
measure_list : list of Measure objects, optional
The measures to include in the MeasureSet
tag : Tag, optional
Information about the source data
Examples
--------
Expand All @@ -121,33 +115,27 @@ def __init__(
... mdd_impact=(1, 0),
... paa_impact=(1, 0),
... )
>>> meas = MeasureSet(
... measure_list=[act_1],
... tag=Tag(description="my dummy MeasureSet.")
... )
>>> meas = MeasureSet([act_1])
>>> meas.check()
Read measures from file and checks consistency data:
>>> meas = MeasureSet.from_excel(ENT_TEMPLATE_XLS)
"""
self.clear(tag=tag)
self.clear()
if measure_list is not None:
for meas in measure_list:
self.append(meas)

def clear(self, tag: Optional[Tag] = None, _data: Optional[dict] = None):
def clear(self, _data: Optional[dict] = None):
"""Reinitialize attributes.
Parameters
----------
tag : Tag, optional
Information about the source data. If not given, an empty Tag object is used.
_data : dict, optional
A dict containing the Measure objects. For internal use only: It's not suppossed to be
set directly. Use the class methods instead.
"""
self.tag = tag if tag is not None else Tag()
self._data = _data if _data is not None else dict() # {hazard_type : {name: Measure()}}

def append(self, meas):
Expand Down Expand Up @@ -353,15 +341,13 @@ def extend(self, meas_set):
self.__dict__ = copy.deepcopy(meas_set.__dict__)
return

self.tag.append(meas_set.tag)

new_func = meas_set.get_measure()
for _, meas_dict in new_func.items():
for _, meas in meas_dict.items():
self.append(meas)

@classmethod
def from_mat(cls, file_name, description='', var_names=None):
def from_mat(cls, file_name, var_names=None):
"""Read MATLAB file generated with previous MATLAB CLIMADA version.
Parameters
Expand Down Expand Up @@ -427,7 +413,6 @@ def read_att_mat(measures, data, file_name, var_names):

data = u_hdf5.read(file_name)
meas_set = cls()
meas_set.tag = Tag(file_name=file_name, description=description)
try:
data = data[var_names['sup_field_name']]
except KeyError:
Expand All @@ -448,7 +433,7 @@ def read_mat(self, *args, **kwargs):
self.__dict__ = MeasureSet.from_mat(*args, **kwargs).__dict__

@classmethod
def from_excel(cls, file_name, description='', var_names=None):
def from_excel(cls, file_name, var_names=None):
"""Read excel file following template and store variables.
Parameters
Expand Down Expand Up @@ -525,7 +510,6 @@ def read_att_excel(measures, dfr, var_names):
dfr = pd.read_excel(file_name, var_names['sheet_name'])
dfr = dfr.fillna('')
meas_set = cls()
meas_set.tag = Tag(file_name=file_name, description=description)
try:
read_att_excel(meas_set, dfr, var_names)
except KeyError as var_err:
Expand Down
19 changes: 3 additions & 16 deletions climada/entity/measures/test/test_meas_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ def test_attributes_all(self):
"""All attributes are defined"""
meas = MeasureSet()
act_1 = Measure(name='Seawall')
self.assertTrue(hasattr(meas, 'tag'))
self.assertTrue(hasattr(meas, '_data'))
self.assertTrue(hasattr(act_1, 'name'))
self.assertTrue(hasattr(act_1, 'color_rgb'))
Expand Down Expand Up @@ -311,8 +310,7 @@ class TestReaderExcel(unittest.TestCase):

def test_demo_file(self):
"""Read demo excel file"""
description = 'One single file.'
meas = MeasureSet.from_excel(ENT_DEMO_TODAY, description)
meas = MeasureSet.from_excel(ENT_DEMO_TODAY)

# Check results
n_meas = 4
Expand Down Expand Up @@ -349,9 +347,6 @@ def test_demo_file(self):
self.assertEqual(act_buil.risk_transf_attach, 0)
self.assertEqual(act_buil.risk_transf_cover, 0)

self.assertEqual(meas.tag.file_name, [str(ENT_DEMO_TODAY)])
self.assertEqual(meas.tag.description, [description])

def test_template_file_pass(self):
"""Read template excel file"""
meas = MeasureSet.from_excel(ENT_TEMPLATE_XLS)
Expand Down Expand Up @@ -426,16 +421,13 @@ def test_template_file_pass(self):
self.assertEqual(act_buil.risk_transf_cover, 1000000000)
self.assertEqual(act_buil.risk_transf_cost_factor, 2)

self.assertEqual(meas.tag.file_name, [str(ENT_TEMPLATE_XLS)])
self.assertEqual(meas.tag.description, [])

class TestReaderMat(unittest.TestCase):
"""Test reader functionality of the MeasuresMat class"""

def test_demo_file(self):
# Read demo excel file
description = 'One single file.'
meas = MeasureSet.from_mat(ENT_TEST_MAT, description)
meas = MeasureSet.from_mat(ENT_TEST_MAT)

# Check results
n_meas = 4
Expand Down Expand Up @@ -491,8 +483,6 @@ def test_demo_file(self):
self.assertEqual(act_buil.risk_transf_attach, 0)
self.assertEqual(act_buil.risk_transf_cover, 0)

self.assertEqual(meas.tag.file_name, [str(ENT_TEST_MAT)])
self.assertEqual(meas.tag.description, [description])

class TestWriter(unittest.TestCase):
"""Test reader functionality of the MeasuresExcel class"""
Expand Down Expand Up @@ -537,10 +527,7 @@ def test_write_read_file(self):
file_name = DATA_DIR.joinpath('test_meas.xlsx')
meas_set.write_excel(file_name)

meas_read = MeasureSet.from_excel(file_name, 'test')

self.assertEqual(meas_read.tag.file_name, [str(file_name)])
self.assertEqual(meas_read.tag.description, ['test'])
meas_read = MeasureSet.from_excel(file_name)

meas_list = meas_read.get_measure('TC')
meas_list.extend(meas_read.get_measure('FL'))
Expand Down
24 changes: 22 additions & 2 deletions climada/entity/test/test_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ def test_from_mat(self):
entity_mat = Entity.from_mat(ENT_TEST_MAT)
self.assertEqual(entity_mat.exposures.tag.file_name, [str(ENT_TEST_MAT)])
self.assertIsInstance(entity_mat.disc_rates, DiscRates)
self.assertEqual(entity_mat.measures.tag.file_name, [str(ENT_TEST_MAT)])
self.assertIsInstance(entity_mat.measures, MeasureSet)
self.assertTrue(isinstance(entity_mat.impact_funcs, ImpactFuncSet))

def test_from_excel(self):
"""Read entity from an xls file following the template."""
entity_xls = Entity.from_excel(ENT_TEMPLATE_XLS)
self.assertEqual(entity_xls.exposures.tag.file_name, [str(ENT_TEMPLATE_XLS)])
self.assertEqual(entity_xls.measures.tag.file_name, [str(ENT_TEMPLATE_XLS)])


class TestCheck(unittest.TestCase):
"""Test entity checker."""
Expand Down Expand Up @@ -109,8 +109,28 @@ def test_wrongDisc_fail(self):
ent.disc_rates = Exposures()
self.assertIn('DiscRates', str(cm.exception))


class TestStringRepr(unittest.TestCase):
"""Test the representation dunder methods of Entity"""
def setUp(self):
self.entity = Entity()
self.entity.exposures.tag.description = ["foo", "bar"]

def test_str(self):
"""Test Entity.__str__"""
out = str(self.entity)
self.assertIn("Exposures", out)
self.assertIn("Description: foo + bar", out)

def test_repr(self):
"""Test Entity.__repr__"""
out = repr(self.entity)
self.assertIn("Exposures", out)
self.assertIn("Description: foo + bar", out)

# Execute Tests
if __name__ == "__main__":
TESTS = unittest.TestLoader().loadTestsFromTestCase(TestReader)
TESTS.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCheck))
TESTS.addTests(unittest.TestLoader().loadTestsFromTestCase(TestStringRepr))
unittest.TextTestRunner(verbosity=2).run(TESTS)
Loading

0 comments on commit c9e9b58

Please sign in to comment.