Skip to content

Commit 1067ac0

Browse files
lint fix
1 parent 26c9e75 commit 1067ac0

1 file changed

Lines changed: 103 additions & 36 deletions

File tree

src/eligibility_signposting_api/services/calculators/eligibility_calculator.py

Lines changed: 103 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,22 @@
2222
IterationResult,
2323
Status,
2424
)
25-
from eligibility_signposting_api.services.calculators.rule_calculator import RuleCalculator
25+
from eligibility_signposting_api.services.calculators.rule_calculator import (
26+
RuleCalculator,
27+
)
2628

2729
Row = Collection[Mapping[str, Any]]
2830

2931

3032
@service
3133
class EligibilityCalculatorFactory:
3234
@staticmethod
33-
def get(person_data: Row, campaign_configs: Collection[rules.CampaignConfig]) -> EligibilityCalculator:
34-
return EligibilityCalculator(person_data=person_data, campaign_configs=campaign_configs)
35+
def get(
36+
person_data: Row, campaign_configs: Collection[rules.CampaignConfig]
37+
) -> EligibilityCalculator:
38+
return EligibilityCalculator(
39+
person_data=person_data, campaign_configs=campaign_configs
40+
)
3541

3642

3743
@dataclass
@@ -51,34 +57,51 @@ def campaigns_grouped_by_condition_name(
5157
) -> Iterator[tuple[eligibility.ConditionName, list[rules.CampaignConfig]]]:
5258
"""Generator function to iterate over campaign groups by condition name."""
5359
for condition_name, campaign_group in groupby(
54-
sorted(self.active_campaigns, key=attrgetter("target")), key=attrgetter("target")
60+
sorted(self.active_campaigns, key=attrgetter("target")),
61+
key=attrgetter("target"),
5562
):
5663
yield condition_name, list(campaign_group)
5764

5865
@property
5966
def person_cohorts(self) -> set[str]:
6067
cohorts_row: Mapping[str, dict[str, dict[str, dict[str, Any]]]] = next(
61-
(row for row in self.person_data if row.get("ATTRIBUTE_TYPE") == "COHORTS"), {}
68+
(row for row in self.person_data if row.get("ATTRIBUTE_TYPE") == "COHORTS"),
69+
{},
70+
)
71+
return set(
72+
cohorts_row.get("COHORT_MAP", {}).get("cohorts", {}).get("M", {}).keys()
6273
)
63-
return set(cohorts_row.get("COHORT_MAP", {}).get("cohorts", {}).get("M", {}).keys())
6474

6575
@staticmethod
66-
def get_the_best_cohort_memberships(cohort_results: dict[str, CohortResult]) -> tuple[Status, list[CohortResult]]:
76+
def get_the_best_cohort_memberships(
77+
cohort_results: dict[str, CohortResult],
78+
) -> tuple[Status, list[CohortResult]]:
6779
"""
6880
1. Get all the cohorts with the best status
6981
2. Case 1: Ignore magic cohort if other cohorts have better status
70-
Case 2: If no cohorts have the better status than magic cohort,
71-
then response excludes cohort memberships but will have actions/suitability rules
72-
also, excludes the cohorts with no positive or negative description
82+
Case 2: If no cohorts have the better status than magic cohort, then response excludes cohort memberships but
83+
will have actions/suitability rules also excludes the cohorts with no positive or negative description
7384
"""
7485
if not cohort_results:
7586
return eligibility.Status.not_eligible, []
76-
best_status = eligibility.Status.best(*[result.status for result in cohort_results.values()])
77-
best_cohorts = [result for result in cohort_results.values() if result.status == best_status]
78-
if all(cc.cohort_code and str(cc.cohort_code.upper()) == MAGIC_COHORT_LABEL.upper() for cc in best_cohorts):
87+
best_status = eligibility.Status.best(
88+
*[result.status for result in cohort_results.values()]
89+
)
90+
best_cohorts = [
91+
result for result in cohort_results.values() if result.status == best_status
92+
]
93+
if all(
94+
cc.cohort_code and str(cc.cohort_code.upper()) == MAGIC_COHORT_LABEL.upper()
95+
for cc in best_cohorts
96+
):
7997
# Update the magic cohort to have no cohort membership information
8098
best_cohorts = [
81-
CohortResult(cohort_code="", status=best_status, reasons=best_cohorts[0].reasons, description="")
99+
CohortResult(
100+
cohort_code="",
101+
status=best_status,
102+
reasons=best_cohorts[0].reasons,
103+
description="",
104+
)
82105
]
83106
else:
84107
best_cohorts = [
@@ -99,15 +122,22 @@ def get_exclusion_rules(
99122
for ir in filter_rules
100123
if ir.cohort_label is None
101124
or cohort.cohort_label == ir.cohort_label
102-
or (isinstance(ir.cohort_label, (list, set, tuple)) and cohort.cohort_label in ir.cohort_label)
125+
or (
126+
isinstance(ir.cohort_label, (list, set, tuple))
127+
and cohort.cohort_label in ir.cohort_label
128+
)
103129
)
104130

105131
@staticmethod
106132
def get_rules_by_type(
107133
active_iteration: Iteration,
108134
) -> tuple[tuple[rules.IterationRule, ...], tuple[rules.IterationRule, ...]]:
109135
filter_rules, suppression_rules = (
110-
tuple(rule for rule in active_iteration.iteration_rules if attrgetter("type")(rule) == rule_type)
136+
tuple(
137+
rule
138+
for rule in active_iteration.iteration_rules
139+
if attrgetter("type")(rule) == rule_type
140+
)
111141
for rule_type in (rules.RuleType.filter, rules.RuleType.suppression)
112142
)
113143
return filter_rules, suppression_rules
@@ -122,33 +152,54 @@ def evaluate_eligibility(self) -> eligibility.EligibilityStatus:
122152
for active_iteration in [cc.current_iteration for cc in campaign_group]:
123153
cohort_results: dict[str, CohortResult] = {}
124154

125-
filter_rules, suppression_rules = self.get_rules_by_type(active_iteration)
155+
filter_rules, suppression_rules = self.get_rules_by_type(
156+
active_iteration
157+
)
126158

127-
for cohort in sorted(active_iteration.iteration_cohorts, key=attrgetter("priority")):
159+
for cohort in sorted(
160+
active_iteration.iteration_cohorts, key=attrgetter("priority")
161+
):
128162
# Base Eligibility - check
129-
if cohort.cohort_label in self.person_cohorts or active_iteration.has_magic_cohort:
163+
if (
164+
cohort.cohort_label in self.person_cohorts
165+
or active_iteration.has_magic_cohort
166+
):
130167
# Eligibility - check
131-
if self.is_eligible_by_filter_rules(cohort, cohort_results, filter_rules):
168+
if self.is_eligible_by_filter_rules(
169+
cohort, cohort_results, filter_rules
170+
):
132171
# Actionability - evaluation
133-
self.evaluate_suppression_rules(cohort, cohort_results, suppression_rules)
172+
self.evaluate_suppression_rules(
173+
cohort, cohort_results, suppression_rules
174+
)
134175

135176
# Not base eligible
136177
elif cohort.cohort_label is not None:
137178
cohort_results[cohort.cohort_label] = CohortResult(
138-
cohort.cohort_group if cohort.cohort_group else cohort.cohort_label,
179+
(
180+
cohort.cohort_group
181+
if cohort.cohort_group
182+
else cohort.cohort_label
183+
),
139184
Status.not_eligible,
140185
[],
141186
str(cohort.negative_description),
142187
)
143188

144189
# Determine Result between cohorts - get the best
145-
status, best_cohorts = self.get_the_best_cohort_memberships(cohort_results)
190+
status, best_cohorts = self.get_the_best_cohort_memberships(
191+
cohort_results
192+
)
146193

147-
iteration_results[active_iteration.name] = IterationResult(status, best_cohorts)
194+
iteration_results[active_iteration.name] = IterationResult(
195+
status, best_cohorts
196+
)
148197

149198
# Determine results between iterations - get the best
150199
if iteration_results:
151-
best_candidate = max(iteration_results.values(), key=lambda r: r.status.value)
200+
best_candidate = max(
201+
iteration_results.values(), key=lambda r: r.status.value
202+
)
152203
else:
153204
best_candidate = IterationResult(eligibility.Status.not_eligible, [])
154205
condition_results[condition_name] = best_candidate
@@ -158,19 +209,25 @@ def evaluate_eligibility(self) -> eligibility.EligibilityStatus:
158209
return eligibility.EligibilityStatus(conditions=final_result)
159210

160211
@staticmethod
161-
def build_condition_results(condition_results: dict[ConditionName, IterationResult]) -> list[Condition]:
212+
def build_condition_results(
213+
condition_results: dict[ConditionName, IterationResult],
214+
) -> list[Condition]:
162215
conditions: list[Condition] = []
163216
# iterate over conditions
164217
for condition_name, active_iteration_result in condition_results.items():
165218
grouped_cohort_results = defaultdict(list)
166219
# iterate over cohorts and group them by status and cohort_group
167220
for cohort_result in active_iteration_result.cohort_results:
168221
if active_iteration_result.status == cohort_result.status:
169-
grouped_cohort_results[cohort_result.cohort_code].append(cohort_result)
222+
grouped_cohort_results[cohort_result.cohort_code].append(
223+
cohort_result
224+
)
170225

171226
# deduplicate grouped cohort results by cohort_code
172227
deduplicated_cohort_results = {
173-
cohort_code: results[0] for cohort_code, results in grouped_cohort_results.items() if results
228+
cohort_code: results[0]
229+
for cohort_code, results in grouped_cohort_results.items()
230+
if results
174231
}
175232

176233
# return condition with cohort results
@@ -191,16 +248,22 @@ def is_eligible_by_filter_rules(
191248
) -> bool:
192249
is_eligible = True
193250
priority_getter = attrgetter("priority")
194-
sorted_rules_by_priority = sorted(self.get_exclusion_rules(cohort, filter_rules), key=priority_getter)
251+
sorted_rules_by_priority = sorted(
252+
self.get_exclusion_rules(cohort, filter_rules), key=priority_getter
253+
)
195254

196255
for _, rule_group in groupby(sorted_rules_by_priority, key=priority_getter):
197-
status, group_inclusion_reasons, group_exclusion_reasons, rule_stop = self.evaluate_rules_priority_group(
198-
rule_group
256+
status, group_inclusion_reasons, group_exclusion_reasons, rule_stop = (
257+
self.evaluate_rules_priority_group(rule_group)
199258
)
200259
if status.is_exclusion:
201260
if cohort.cohort_label is not None:
202261
cohort_results[str(cohort.cohort_label)] = CohortResult(
203-
cohort.cohort_group if cohort.cohort_group else cohort.cohort_label,
262+
(
263+
cohort.cohort_group
264+
if cohort.cohort_group
265+
else cohort.cohort_label
266+
),
204267
Status.not_eligible,
205268
[],
206269
str(cohort.negative_description),
@@ -219,11 +282,13 @@ def evaluate_suppression_rules(
219282
priority_getter = attrgetter("priority")
220283
suppression_reasons = []
221284

222-
sorted_rules_by_priority = sorted(self.get_exclusion_rules(cohort, suppression_rules), key=priority_getter)
285+
sorted_rules_by_priority = sorted(
286+
self.get_exclusion_rules(cohort, suppression_rules), key=priority_getter
287+
)
223288

224289
for _, rule_group in groupby(sorted_rules_by_priority, key=priority_getter):
225-
status, group_inclusion_reasons, group_exclusion_reasons, rule_stop = self.evaluate_rules_priority_group(
226-
rule_group
290+
status, group_inclusion_reasons, group_exclusion_reasons, rule_stop = (
291+
self.evaluate_rules_priority_group(rule_group)
227292
)
228293
if status.is_exclusion:
229294
is_actionable = False
@@ -250,7 +315,9 @@ def evaluate_suppression_rules(
250315

251316
def evaluate_rules_priority_group(
252317
self, rules_group: Iterator[rules.IterationRule]
253-
) -> tuple[eligibility.Status, list[eligibility.Reason], list[eligibility.Reason], bool]:
318+
) -> tuple[
319+
eligibility.Status, list[eligibility.Reason], list[eligibility.Reason], bool
320+
]:
254321
is_rule_stop = False
255322
inclusion_reasons, exclusion_reasons = [], []
256323
best_status = eligibility.Status.not_eligible

0 commit comments

Comments
 (0)