forked from Sanyamkothari/solar
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquality_rules.py
More file actions
115 lines (101 loc) · 4.12 KB
/
Copy pathquality_rules.py
File metadata and controls
115 lines (101 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""
Quality Rules engine.
Applies Rule A, B, and C criteria on the validated matrices.
Determines final QC decision categories (APPROVED, REJECTED, etc.).
"""
from typing import List, Dict, Tuple
from config import (
BUS_BARS,
POINTS_PER_BAR,
RULE_A_THRESHOLD,
RULE_A_PERCENTAGE,
MIN_POINTS_RULE_A,
RULE_B_THRESHOLD,
MAX_RULE_B_PER_BAR,
RULE_C_THRESHOLD,
MAX_RULE_C_TOTAL,
MAX_RULE_C_PER_BAR,
CATEGORY_APPROVED,
CATEGORY_REJECTED
)
class QualityEvaluator:
@staticmethod
def evaluate_rule_a(matrix: List[List[float]]) -> Tuple[bool, int, int]:
"""
Rule A: At least 75% of total points must be > 0.8.
Scales proportionally for partial matrices.
Returns (passed, count_above_threshold, required_count).
"""
total_points = len(matrix) * POINTS_PER_BAR
required = int(total_points * RULE_A_PERCENTAGE) if len(matrix) != BUS_BARS else MIN_POINTS_RULE_A
total_greater_than_threshold = 0
for row in matrix:
total_greater_than_threshold += sum(1 for val in row if val > RULE_A_THRESHOLD)
passed = total_greater_than_threshold >= required
return passed, total_greater_than_threshold, required
@staticmethod
def evaluate_rule_b(matrix: List[List[float]]) -> Tuple[bool, Dict[int, int]]:
"""
Rule B: For each bus bar (7 points), maximum 2 points allowed <= 0.35.
If any bus bar has more than 2, reject.
"""
passed = True
failures_per_bar = {}
for bar_idx, row in enumerate(matrix):
count_b = sum(1 for val in row if val <= RULE_B_THRESHOLD)
failures_per_bar[bar_idx] = count_b
if count_b > MAX_RULE_B_PER_BAR:
passed = False
return passed, failures_per_bar
@staticmethod
def evaluate_rule_c(matrix: List[List[float]]) -> Tuple[bool, int, Dict[int, int]]:
"""
Rule C: Total points <= 0.1 allowed: maximum 8 AND Each bus bar can have maximum 1 point <= 0.1.
"""
passed = True
total_failures_c = 0
failures_per_bar = {}
for bar_idx, row in enumerate(matrix):
count_c = sum(1 for val in row if val <= RULE_C_THRESHOLD)
failures_per_bar[bar_idx] = count_c
total_failures_c += count_c
if count_c > MAX_RULE_C_PER_BAR:
passed = False
if total_failures_c > MAX_RULE_C_TOTAL:
passed = False
return passed, total_failures_c, failures_per_bar
@staticmethod
def evaluate_batch(matrix: List[List[float]]) -> Dict:
"""
Evaluates the full batch against all rules.
Returns a detailed report.
"""
rule_a_pass, count_a, required_a = QualityEvaluator.evaluate_rule_a(matrix)
rule_b_pass, dict_b = QualityEvaluator.evaluate_rule_b(matrix)
rule_c_pass, total_c, dict_c = QualityEvaluator.evaluate_rule_c(matrix)
# Scale Rule C total threshold proportionally for partial matrices
actual_bars = len(matrix)
scaled_max_c_total = MAX_RULE_C_TOTAL if actual_bars == BUS_BARS else max(1, int(MAX_RULE_C_TOTAL * actual_bars / BUS_BARS))
if total_c > scaled_max_c_total:
rule_c_pass = False
overall_pass = rule_a_pass and rule_b_pass and rule_c_pass
decision = CATEGORY_APPROVED if overall_pass else CATEGORY_REJECTED
return {
"decision": decision,
"metrics": {
"rule_A": {
"passed": rule_a_pass,
"points_gt_08": count_a,
"required": required_a
},
"rule_B": {
"passed": rule_b_pass,
"failures_per_bar": dict_b, # dict map row_index: count
},
"rule_C": {
"passed": rule_c_pass,
"total_failures": total_c,
"failures_per_bar": dict_c # dict map row_index: count
}
}
}