From 3f7c761925a15913549eff39029b8c6cb883847b Mon Sep 17 00:00:00 2001 From: markus Date: Thu, 5 Nov 2020 15:42:40 +0100 Subject: [PATCH 1/6] move interval-calculation into separate function --- cara/apps/calculator/model_generator.py | 89 +++++++++++++------------ 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index 6ed8a779..4510a46c 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -87,8 +87,50 @@ class FormData: pass def present_interval(self) -> models.Interval: - # TODO - pass + coffee_period = (self.activity_finish - self.activity_start) // self.coffee_breaks + leave_times = [self.lunch_start] + enter_times = [self.lunch_finish] + for minute in range(self.lunch_start, self.activity_finish, coffee_period): + leave_times.append(minute + coffee_period // 2) + enter_times.append(minute + coffee_period // 2 + self.coffee_duration) + + # These lists represent the times where the infected person leaves or enters the room, respectively, sorted in + # reverse order. Note that these lists allows the person to "leave" when they should not even be present in the room + # The following loop handles this. + leave_times.sort(reverse=True) + enter_times.sort(reverse=True) + + # This loop iterates through the lists above, populating present_intervals with (enter, leave) intervals + # representing the infected person entering and leaving the room. Note that if one of the evenly spaced coffee- + # breaks happens to coincide with the lunch-break, it is simply ignored. + is_present = True + present_intervals = [] + time = self.activity_start + while time < self.activity_finish: + if is_present: + if not leave_times: + present_intervals.append((time / 60, self.activity_finish / 60)) + break + + if leave_times[-1] < time: + leave_times.pop() + else: + new_time = leave_times.pop() + present_intervals.append((time / 60, min(new_time, self.activity_finish) / 60)) + is_present = False + time = new_time + + else: + if not enter_times: + break + + if enter_times[-1] < time: + enter_times.pop() + else: + is_present = True + time = enter_times.pop() + + return models.SpecificInterval(tuple(present_intervals)) def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model: @@ -135,47 +177,6 @@ def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model: coffee_duration = int(d['coffee_duration']) coffee_breaks = int(d['coffee_breaks']) coffee_period = (activity_finish - activity_start) // coffee_breaks + 1 - leave_times = [lunch_start] - enter_times = [lunch_finish] - for minute in range(activity_start, activity_finish, coffee_period): - leave_times.append(minute) - enter_times.append(minute + coffee_duration) - - # These lists represent the times where the infected person leaves or enters the room, respectively, sorted in - # reverse order. Note that these lists allows the person to "leave" when they should not even be present in the room - # The following loop handles this. - leave_times.sort(reverse=True) - enter_times.sort(reverse=True) - - # This loop iterates through the lists above, populating present_intervals with (enter, leave) intervals - # representing the infected person entering and leaving the room. Note that if one of the evenly spaced coffee- - # breaks happens to coincide with the lunch-break, it is simply ignored. - is_present = True - present_intervals = [] - time = activity_start - while time < activity_finish: - if is_present: - if not leave_times: - present_intervals.append((time / 60, activity_finish / 60)) - break - - if leave_times[-1] < time: - leave_times.pop() - else: - new_time = leave_times.pop() - present_intervals.append((time / 60, min(new_time, activity_finish) / 60)) - is_present = False - time = new_time - - else: - if not enter_times: - break - - if enter_times[-1] < time: - enter_times.pop() - else: - is_present = True - time = enter_times.pop() # Initializes a mask of type 1 if mask wearing is "continuous", otherwise instantiates the mask attribute as # the "No mask"-mask @@ -204,7 +205,7 @@ def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model: ventilation=ventilation, infected=models.InfectedPerson( virus=virus, - presence=models.SpecificInterval(tuple(present_intervals)), + presence=form.present_interval(), mask=mask, activity=infected_activity, expiration=infected_expiration From 9190a33634894cfeab030778b387180074e85825 Mon Sep 17 00:00:00 2001 From: markus Date: Thu, 5 Nov 2020 15:43:27 +0100 Subject: [PATCH 2/6] change baseline_raw_form_data --- cara/apps/calculator/model_generator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index 4510a46c..1a8a3633 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -225,9 +225,9 @@ def baseline_raw_form_data(): 'air_changes': '', 'air_supply': '', 'ceiling_height': '', - 'coffee_breaks': '', - 'coffee_duration': '1', - 'coffee_option': '0', + 'coffee_breaks': '5', + 'coffee_duration': '10', + 'coffee_option': '1', 'event_type': 'single_event', 'floor_area': '', 'infected_people': '1', From 97c667911f62a617f2013554754d35a63ccba69f Mon Sep 17 00:00:00 2001 From: markus Date: Thu, 5 Nov 2020 16:01:08 +0100 Subject: [PATCH 3/6] split long line --- cara/apps/calculator/model_generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index 1a8a3633..c02bdff5 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -95,8 +95,8 @@ class FormData: enter_times.append(minute + coffee_period // 2 + self.coffee_duration) # These lists represent the times where the infected person leaves or enters the room, respectively, sorted in - # reverse order. Note that these lists allows the person to "leave" when they should not even be present in the room - # The following loop handles this. + # reverse order. Note that these lists allows the person to "leave" when they should not even be present in the + # room. The following loop handles this. leave_times.sort(reverse=True) enter_times.sort(reverse=True) From a28227e7acd83282fc570b3de2f2d1ab6cc7e799 Mon Sep 17 00:00:00 2001 From: markus Date: Thu, 5 Nov 2020 16:10:28 +0100 Subject: [PATCH 4/6] fix typo --- cara/apps/calculator/model_generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index c02bdff5..6cc02118 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -90,7 +90,7 @@ class FormData: coffee_period = (self.activity_finish - self.activity_start) // self.coffee_breaks leave_times = [self.lunch_start] enter_times = [self.lunch_finish] - for minute in range(self.lunch_start, self.activity_finish, coffee_period): + for minute in range(self.activity_start, self.activity_finish, coffee_period): leave_times.append(minute + coffee_period // 2) enter_times.append(minute + coffee_period // 2 + self.coffee_duration) From f896cbf09488966a01ef0b95ca68b54bd1041fd7 Mon Sep 17 00:00:00 2001 From: markus Date: Thu, 5 Nov 2020 16:17:52 +0100 Subject: [PATCH 5/6] add test for present_intervals --- cara/tests/apps/calculator/test_model_generator.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cara/tests/apps/calculator/test_model_generator.py b/cara/tests/apps/calculator/test_model_generator.py index 05203273..a13018cc 100644 --- a/cara/tests/apps/calculator/test_model_generator.py +++ b/cara/tests/apps/calculator/test_model_generator.py @@ -23,3 +23,15 @@ def test_ventilation(baseline_form): ventilation = baseline_form.ventilation() # TODO: # assert ventilation == cara.models.Ventilation() + + +def test_present_intervals(baseline_form): + baseline_form.coffee_duration = 15 + baseline_form.coffee_option = True + baseline_form.coffee_breaks = 4 + baseline_form.activity_start = 9 * 60 + baseline_form.activity_finish = 17 * 60 + baseline_form.lunch_start = 12 * 60 + 30 + baseline_form.lunch_finish = 13 * 60 + 30 + correct = ((9, 10), (10.25, 12), (12.25, 12.5), (13.5, 14), (14.25, 16), (16.25, 17)) + assert baseline_form.present_interval().present_times == correct From f04f813e25b3b8c250ad99d5383afc4c32d98c9f Mon Sep 17 00:00:00 2001 From: markus Date: Thu, 5 Nov 2020 16:22:20 +0100 Subject: [PATCH 6/6] remove unnecessary leftovers from model_from_form --- cara/apps/calculator/model_generator.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py index 6cc02118..9ae8cb97 100644 --- a/cara/apps/calculator/model_generator.py +++ b/cara/apps/calculator/model_generator.py @@ -168,16 +168,6 @@ def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model: # Initializes the virus as SARS_Cov_2 virus = models.Virus.types['SARS_CoV_2'] - # Defines all of the parameters required to construct a list of intervals where the infected person is present in - # the room - activity_start = int(d['activity_start'][:2]) * 60 + int(d['activity_start'][3:]) - activity_finish = int(d['activity_finish'][:2]) * 60 + int(d['activity_finish'][3:]) - lunch_start = int(d['lunch_start'][:2]) * 60 + int(d['lunch_start'][3:]) - lunch_finish = int(d['lunch_finish'][:2]) * 60 + int(d['lunch_finish'][3:]) - coffee_duration = int(d['coffee_duration']) - coffee_breaks = int(d['coffee_breaks']) - coffee_period = (activity_finish - activity_start) // coffee_breaks + 1 - # Initializes a mask of type 1 if mask wearing is "continuous", otherwise instantiates the mask attribute as # the "No mask"-mask mask = models.Mask.types['Type I' if d['mask_wearing'] == "Continuous" else 'No mask']