-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_efficiency.py
More file actions
107 lines (89 loc) · 4.46 KB
/
Copy pathtest_efficiency.py
File metadata and controls
107 lines (89 loc) · 4.46 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
"""
Verification tests for garment-line-efficiency (Python).
Cross-verified against standard industry references:
25 workers × 8 hours × 60 min = 12,000 min available
At SAM 15, output 200 → 200×15 = 3,000 min produced → 25% efficiency
Run: python test_efficiency.py
"""
import math
import sys
sys.path.insert(0, "src")
from garment_line_efficiency import (
calculate_efficiency,
calculate_target_output,
calculate_required_workers,
calculate_line_balance,
classify_efficiency,
)
passed = 0
failed = 0
def assert_close(actual, expected, label, tolerance=0.01):
global passed, failed
if math.isclose(actual, expected, abs_tol=tolerance):
print(f" ✓ {label}")
passed += 1
else:
print(f" ✗ {label}\n expected: ~{expected}\n actual: {actual}")
failed += 1
def assert_equal(actual, expected, label):
global passed, failed
if actual == expected:
print(f" ✓ {label}")
passed += 1
else:
print(f" ✗ {label}\n expected: {expected}\n actual: {actual}")
failed += 1
def assert_throws(fn, label):
global passed, failed
try:
fn()
print(f" ✗ {label} (expected exception, did not throw)")
failed += 1
except Exception:
print(f" ✓ {label}")
passed += 1
print("\n=== calculate_efficiency ===")
assert_close(calculate_efficiency(200, 15, 25, 8), 25, "Standard: 200 pcs × 15 SAM / 12000 min = 25%")
assert_close(calculate_efficiency(400, 15, 25, 8), 50, "Double output = 50% efficiency")
assert_close(calculate_efficiency(600, 15, 25, 8), 75, "Triple output = 75% (world-class)")
assert_close(calculate_efficiency(0, 15, 25, 8), 0, "0 output = 0% efficiency")
assert_close(calculate_efficiency(600, 12, 20, 8), 75, "600 pcs × 12 SAM / 9600 min = 75%")
print("\n=== calculate_target_output ===")
assert_close(calculate_target_output(50, 15, 25, 8), 400, "50% on 25w×8h SAM15 → 400 pcs")
assert_close(calculate_target_output(100, 15, 25, 8), 800, "100% target → 800 pcs")
assert_close(calculate_target_output(25, 15, 25, 8), 200, "25% target → 200 pcs")
print("\n=== calculate_required_workers ===")
assert_close(calculate_required_workers(500, 15, 60, 8), 26.0417, "Need 26.04 workers for 500 pcs @ 60% eff")
assert_close(calculate_required_workers(400, 15, 50, 8), 25, "Need 25 workers for 400 pcs @ 50% eff")
print("\n=== calculate_line_balance ===")
balance = calculate_line_balance([
{"operation": "Shoulder join", "sam": 0.5},
{"operation": "Sleeve attach", "sam": 0.8},
{"operation": "Side seam", "sam": 0.6},
{"operation": "Hem", "sam": 0.4},
])
assert_equal(balance["bottleneck"], "Sleeve attach", "Bottleneck = Sleeve attach (0.8 SAM)")
assert_close(balance["max_sam"], 0.8, "Max SAM = 0.8")
assert_close(balance["avg_sam"], 0.575, "Avg SAM = 0.575")
assert_close(balance["balance_ratio"], 71.875, "Balance ratio = (0.575/0.8)×100 = 71.875%")
assert_close(balance["total_sam"], 2.3, "Total SAM = 2.3")
assert_equal(balance["operation_count"], 4, "Operation count = 4")
print("\n=== classify_efficiency (industry benchmarks) ===")
assert_equal(classify_efficiency(25), "BELOW_STANDARD", "25% → BELOW_STANDARD")
assert_equal(classify_efficiency(34.9), "BELOW_STANDARD", "34.9% → BELOW_STANDARD")
assert_equal(classify_efficiency(35), "AVERAGE", "35% → AVERAGE (boundary)")
assert_equal(classify_efficiency(50), "AVERAGE", "50% → AVERAGE (Bangladesh/India avg)")
assert_equal(classify_efficiency(60), "GOOD", "60% → GOOD")
assert_equal(classify_efficiency(70), "EXCELLENT", "70% → EXCELLENT")
assert_equal(classify_efficiency(80), "WORLD_CLASS", "80% → WORLD_CLASS")
print("\n=== Input validation ===")
assert_throws(lambda: calculate_efficiency(-1, 15, 25, 8), "Throws on negative output")
assert_throws(lambda: calculate_efficiency(100, 0, 25, 8), "Throws on zero SAM")
assert_throws(lambda: calculate_efficiency(100, 15, 0, 8), "Throws on zero workers")
assert_throws(lambda: calculate_efficiency(100, 15, 25, 0), "Throws on zero hours")
assert_throws(lambda: calculate_target_output(150, 15, 25, 8), "Throws on efficiency > 100")
assert_throws(lambda: calculate_target_output(0, 15, 25, 8), "Throws on efficiency 0")
assert_throws(lambda: calculate_line_balance([]), "Throws on empty operations")
assert_throws(lambda: classify_efficiency(-5), "Throws on negative efficiency")
print(f"\n{passed}/{passed + failed} tests passed." + (f" {failed} FAILED." if failed > 0 else ""))
sys.exit(1 if failed > 0 else 0)