Merge branch 'feature/infected_breaks' into 'master'
Added logic for precise breaks for both infected and exposed See merge request caimira/caimira!422
This commit is contained in:
commit
ca7f84e4f7
3 changed files with 53 additions and 29 deletions
|
|
@ -33,7 +33,7 @@ class FormData:
|
|||
air_changes: float
|
||||
air_supply: float
|
||||
arve_sensors_option: bool
|
||||
specific_breaks: list
|
||||
specific_breaks: dict
|
||||
precise_activity: dict
|
||||
ceiling_height: float
|
||||
exposed_coffee_break_option: str
|
||||
|
|
@ -100,7 +100,7 @@ class FormData:
|
|||
'air_changes': 0.,
|
||||
'air_supply': 0.,
|
||||
'arve_sensors_option': False,
|
||||
'specific_breaks': '[]',
|
||||
'specific_breaks': '{}',
|
||||
'precise_activity': '{}',
|
||||
'calculator_version': _NO_DEFAULT,
|
||||
'ceiling_height': 0.,
|
||||
|
|
@ -312,22 +312,33 @@ class FormData:
|
|||
raise ValueError("mechanical_ventilation_type cannot be 'not-applicable' if "
|
||||
"ventilation_type is 'mechanical_ventilation'")
|
||||
|
||||
# Validate specific inputs - breaks
|
||||
if self.specific_breaks != []:
|
||||
if type(self.specific_breaks) is not list:
|
||||
raise TypeError(f'All breaks should be in a list. Got {type(self.specific_breaks)}.')
|
||||
for input_break in self.specific_breaks:
|
||||
# Input validations.
|
||||
if type(input_break) is not dict:
|
||||
raise TypeError(f'Each break should be a dictionary. Got {type(input_break)}.')
|
||||
dict_keys = list(input_break.keys())
|
||||
if "start_time" not in input_break:
|
||||
raise TypeError(f'Unable to fetch "start_time" key. Got "{dict_keys[0]}".')
|
||||
if "finish_time" not in input_break:
|
||||
raise TypeError(f'Unable to fetch "finish_time" key. Got "{dict_keys[1]}".')
|
||||
for time in input_break.values():
|
||||
if not re.compile("^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$").match(time):
|
||||
raise TypeError(f'Wrong time format - "HH:MM". Got "{time}".')
|
||||
# Validate specific inputs - breaks (exposed and infected)
|
||||
if self.specific_breaks != {}:
|
||||
if type(self.specific_breaks) is not dict:
|
||||
raise TypeError('The specific breaks should be in a dictionary.')
|
||||
|
||||
dict_keys = list(self.specific_breaks.keys())
|
||||
if "exposed_breaks" not in dict_keys:
|
||||
raise TypeError(f'Unable to fetch "exposed_breaks" key. Got "{dict_keys[0]}".')
|
||||
if "infected_breaks" not in dict_keys:
|
||||
raise TypeError(f'Unable to fetch "infected_breaks" key. Got "{dict_keys[1]}".')
|
||||
|
||||
for population_breaks in ['exposed_breaks', 'infected_breaks']:
|
||||
if self.specific_breaks[population_breaks] != []:
|
||||
if type(self.specific_breaks[population_breaks]) is not list:
|
||||
raise TypeError(f'All breaks should be in a list. Got {type(self.specific_breaks[population_breaks])}.')
|
||||
for input_break in self.specific_breaks[population_breaks]:
|
||||
# Input validations.
|
||||
if type(input_break) is not dict:
|
||||
raise TypeError(f'Each break should be a dictionary. Got {type(input_break)}.')
|
||||
dict_keys = list(input_break.keys())
|
||||
if "start_time" not in input_break:
|
||||
raise TypeError(f'Unable to fetch "start_time" key. Got "{dict_keys[0]}".')
|
||||
if "finish_time" not in input_break:
|
||||
raise TypeError(f'Unable to fetch "finish_time" key. Got "{dict_keys[1]}".')
|
||||
for time in input_break.values():
|
||||
if not re.compile("^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$").match(time):
|
||||
raise TypeError(f'Wrong time format - "HH:MM". Got "{time}".')
|
||||
|
||||
# Validate specific inputs - precise activity
|
||||
if self.precise_activity != {}:
|
||||
|
|
@ -738,9 +749,9 @@ class FormData:
|
|||
else:
|
||||
return self.exposed_coffee_break_times()
|
||||
|
||||
def generate_specific_break_times(self) -> models.BoundarySequence_t:
|
||||
def generate_specific_break_times(self, population_breaks) -> models.BoundarySequence_t:
|
||||
break_times = []
|
||||
for n in self.specific_breaks:
|
||||
for n in population_breaks:
|
||||
# Parse break times.
|
||||
begin = time_string_to_minutes(n["start_time"])
|
||||
end = time_string_to_minutes(n["finish_time"])
|
||||
|
|
@ -845,8 +856,8 @@ class FormData:
|
|||
return models.SpecificInterval(tuple(present_intervals))
|
||||
|
||||
def infected_present_interval(self) -> models.Interval:
|
||||
if self.specific_breaks != []: # It means the breaks are specific and not predefined
|
||||
breaks = self.generate_specific_break_times()
|
||||
if self.specific_breaks != {}: # It means the breaks are specific and not predefined
|
||||
breaks = self.generate_specific_break_times(self.specific_breaks['infected_breaks'])
|
||||
else:
|
||||
breaks = self.infected_lunch_break_times() + self.infected_coffee_break_times()
|
||||
return self.present_interval(
|
||||
|
|
@ -860,8 +871,8 @@ class FormData:
|
|||
return models.SpecificInterval(present_times=((start_time/60, (start_time + duration)/60),))
|
||||
|
||||
def exposed_present_interval(self) -> models.Interval:
|
||||
if self.specific_breaks != []: # It means the breaks are specific and not predefined
|
||||
breaks = self.generate_specific_break_times()
|
||||
if self.specific_breaks != {}: # It means the breaks are specific and not predefined
|
||||
breaks = self.generate_specific_break_times(self.specific_breaks['exposed_breaks'])
|
||||
else:
|
||||
breaks = self.exposed_lunch_break_times() + self.exposed_coffee_break_times()
|
||||
return self.present_interval(
|
||||
|
|
|
|||
|
|
@ -536,7 +536,7 @@
|
|||
<div data-tooltip="Input breaks that, by default, are the same for infected/exposed person(s) unless specified otherwise.">
|
||||
<span class="tooltip_text">?</span>
|
||||
</div>
|
||||
<input type="text" class="form-control d-none" name="specific_breaks" value='[]'>
|
||||
<input type="text" class="form-control d-none" name="specific_breaks" value='{}'>
|
||||
</span><br>
|
||||
|
||||
<!-- Lunch Options -->
|
||||
|
|
|
|||
|
|
@ -7,6 +7,20 @@ from caimira.apps.calculator import model_generator
|
|||
|
||||
@pytest.mark.parametrize(
|
||||
["break_input", "error"],
|
||||
[
|
||||
[["exposed_breaks", [], "infected_breaks", []], "The specific breaks should be in a dictionary."],
|
||||
[{"eposed_breaks": [], "infected_breaks": []}, 'Unable to fetch "exposed_breaks" key. Got "eposed_breaks".'],
|
||||
[{"exposed_breaks": [], "ifected_breaks": []}, 'Unable to fetch "infected_breaks" key. Got "ifected_breaks".'],
|
||||
]
|
||||
)
|
||||
def test_specific_break_structure(break_input, error, baseline_form: model_generator.FormData):
|
||||
baseline_form.specific_breaks = break_input
|
||||
with pytest.raises(TypeError, match=error):
|
||||
baseline_form.validate()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
["population_break_input", "error"],
|
||||
[
|
||||
[{"start_time": "10:00", "finish_time": "11:00"}, "All breaks should be in a list. Got <class 'dict'>."],
|
||||
[[["start_time", "10:00", "finish_time", "11:00"]], "Each break should be a dictionary. Got <class 'list'>."],
|
||||
|
|
@ -16,8 +30,8 @@ from caimira.apps.calculator import model_generator
|
|||
[[{"start_time": "10:00", "finish_time": "11"}], 'Wrong time format - "HH:MM". Got "11".'],
|
||||
]
|
||||
)
|
||||
def test_specific_break_data_structure(break_input, error, baseline_form: model_generator.FormData):
|
||||
baseline_form.specific_breaks = break_input
|
||||
def test_specific_population_break_data_structure(population_break_input, error, baseline_form: model_generator.FormData):
|
||||
baseline_form.specific_breaks = {'exposed_breaks': population_break_input, 'infected_breaks': population_break_input}
|
||||
with pytest.raises(TypeError, match=error):
|
||||
baseline_form.validate()
|
||||
|
||||
|
|
@ -32,9 +46,8 @@ def test_specific_break_data_structure(break_input, error, baseline_form: model_
|
|||
]
|
||||
)
|
||||
def test_specific_break_time(break_input, error, baseline_form: model_generator.FormData):
|
||||
baseline_form.specific_breaks = break_input
|
||||
with pytest.raises(ValueError, match=error):
|
||||
baseline_form.generate_specific_break_times()
|
||||
baseline_form.generate_specific_break_times(break_input)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
|
|||
Loading…
Reference in a new issue