digifact 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
digifact-0.1.0/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Prathamesh Shinde
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software...
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: digifact
3
+ Version: 0.1.0
4
+ Summary: Digifact - Manufacturing KPIs Calculation Package (OEE, MTTR, MTBF, Availability, Performance, Quality)
5
+ Author-email: Precise <digiapp@preciseindsol.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/digifact
8
+ Project-URL: Documentation, https://pypi.org/project/digifact
9
+ Project-URL: Source, https://github.com/yourusername/digifact
10
+ Keywords: manufacturing,OEE,KPI,production,MTTR,MTBF,availability,performance,quality
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Intended Audience :: Manufacturing
16
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Dynamic: license-file
21
+
22
+ # Digifact
23
+
24
+ A Python package for calculating manufacturing KPIs including OEE (Overall Equipment Efficiency), Availability, Performance, Quality, MTTR, and MTBF.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install digifact
@@ -0,0 +1,8 @@
1
+ # Digifact
2
+
3
+ A Python package for calculating manufacturing KPIs including OEE (Overall Equipment Efficiency), Availability, Performance, Quality, MTTR, and MTBF.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install digifact
@@ -0,0 +1,15 @@
1
+ """Digifact - Manufacturing KPIs Calculation Package"""
2
+ # This is a docstring - it describes what the package does
3
+ # It appears when someone uses help(digifact) or looks at documentation
4
+ from digifact.core import ProductionMetrics
5
+
6
+ # These import statements make these functions/classes available
7
+ # when someone does "from digifact import *"
8
+ # It saves users from having to import from digifact.core directly
9
+
10
+ __version__ = "0.1.0"
11
+ __all__ = [
12
+ "ProductionMetrics"
13
+ ]
14
+ # __all__ specifies what gets imported when someone uses "from digifact import *"
15
+ # It's like a whitelist of public objects
@@ -0,0 +1,324 @@
1
+ """Core functionality for digifact package"""
2
+ # Module docstring explaining this file's purpose
3
+ from dataclasses import dataclass
4
+ # Imports dataclass decorator - automatically generates __init__, __repr__, etc.
5
+ from typing import Optional, Dict, Any
6
+ # Imports Optional and Dict type hints
7
+
8
+
9
+ @dataclass
10
+ class ProductionMetrics:
11
+ """Data class to hold production metrics and calculate all KPIs"""
12
+
13
+ # Attributes
14
+ total_time: float # Total available time
15
+ ideal_production: float # Ideal production rate (units per time)
16
+ actual_count: float # Actual units produced
17
+ total_count: float # Total units (including defects)
18
+ fault_count: float # Number of faults/breakdowns
19
+ total_downtime: float # Total downtime
20
+ total_uptime: float # Total uptime
21
+
22
+ def calculate_availability(self) -> float:
23
+ """
24
+ Calculate Availability
25
+
26
+ Returns:
27
+ Availability percentage
28
+ """
29
+ try:
30
+ availability = (self.actual_count * 100) / self.ideal_production
31
+ return round(availability, 2)
32
+ except ZeroDivisionError:
33
+ raise ValueError("Ideal production cannot be zero")
34
+ except Exception as e:
35
+ raise ValueError(f"Error calculating availability: {str(e)}")
36
+
37
+ def calculate_performance(self) -> float:
38
+ """
39
+ Calculate Performance
40
+
41
+ Returns:
42
+ Performance percentage
43
+ """
44
+ try:
45
+ # Performance = (Actual Production Rate / Ideal Production Rate) * 100
46
+ actual_rate = self.actual_count / self.total_time
47
+ ideal_rate = self.ideal_production / self.total_time
48
+ performance = (actual_rate / ideal_rate) * 100
49
+ return round(performance, 2)
50
+ except ZeroDivisionError:
51
+ raise ValueError("Total time cannot be zero")
52
+ except Exception as e:
53
+ raise ValueError(f"Error calculating performance: {str(e)}")
54
+
55
+ def calculate_quality(self) -> float:
56
+ """
57
+ Calculate Quality
58
+
59
+ Formula: Quality = (Good Units / Total Units) * 100
60
+
61
+ Returns:
62
+ Quality percentage
63
+ """
64
+ try:
65
+ if self.total_count == 0:
66
+ raise ValueError("Total count cannot be zero")
67
+
68
+ # Calculate quality as percentage of good units
69
+ quality = (self.actual_count / self.total_count) * 100
70
+ return round(quality, 2)
71
+
72
+ except ZeroDivisionError:
73
+ raise ValueError("Total count cannot be zero")
74
+ except Exception as e:
75
+ raise ValueError(f"Error calculating quality: {str(e)}")
76
+
77
+ def calculate_oee(self) -> Dict[str, Any]:
78
+ """
79
+ Calculate Overall Equipment Efficiency (OEE)
80
+
81
+ OEE = (Availability × Performance × Quality) / 10000
82
+
83
+ Returns:
84
+ Dictionary containing OEE and its components
85
+ """
86
+ try:
87
+ availability = self.calculate_availability()
88
+ performance = self.calculate_performance()
89
+ quality = self.calculate_quality()
90
+
91
+ # Calculate OEE (all inputs are percentages)
92
+ oee = (availability * performance * quality) / 10000
93
+ oee = round(oee, 2)
94
+
95
+ return {
96
+ 'oee': oee,
97
+ 'availability': availability,
98
+ 'performance': performance,
99
+ 'quality': quality,
100
+ 'components': {
101
+ 'availability_pct': availability,
102
+ 'performance_pct': performance,
103
+ 'quality_pct': quality
104
+ }
105
+ }
106
+ except Exception as e:
107
+ raise ValueError(f"Error calculating OEE: {str(e)}")
108
+
109
+ def calculate_mttr(self) -> float:
110
+ """
111
+ Calculate Mean Time To Repair (MTTR)
112
+
113
+ MTTR = Total down time / Fault count
114
+
115
+ Returns:
116
+ MTTR value
117
+ """
118
+ try:
119
+ if self.fault_count == 0:
120
+ return 0.0
121
+
122
+ mttr = self.total_downtime / self.fault_count
123
+ return round(mttr, 2)
124
+ except ZeroDivisionError:
125
+ raise ValueError("Fault count cannot be zero")
126
+ except Exception as e:
127
+ raise ValueError(f"Error calculating MTTR: {str(e)}")
128
+
129
+ def calculate_mtbf(self) -> float:
130
+ """
131
+ Calculate Mean Time Between Failures (MTBF)
132
+
133
+ MTBF = Total uptime / Fault count
134
+
135
+ Returns:
136
+ MTBF value
137
+ """
138
+ try:
139
+ if self.fault_count == 0:
140
+ return float('inf') # No failures means infinite MTBF
141
+
142
+ mtbf = self.total_uptime / self.fault_count
143
+ return round(mtbf, 2)
144
+ except ZeroDivisionError:
145
+ raise ValueError("Fault count cannot be zero")
146
+ except Exception as e:
147
+ raise ValueError(f"Error calculating MTBF: {str(e)}")
148
+
149
+ def calculate_all_metrics(self) -> Dict[str, Any]:
150
+ """
151
+ Calculate all metrics at once
152
+
153
+ Returns:
154
+ Dictionary containing all calculated metrics
155
+ """
156
+ return {
157
+ 'oee_analysis': self.calculate_oee(),
158
+ 'mttr': self.calculate_mttr(),
159
+ 'mtbf': self.calculate_mtbf(),
160
+ 'raw_data': {
161
+ 'total_time': self.total_time,
162
+ 'ideal_production': self.ideal_production,
163
+ 'actual_count': self.actual_count,
164
+ 'total_count': self.total_count,
165
+ 'fault_count': self.fault_count,
166
+ 'total_downtime': self.total_downtime,
167
+ 'total_uptime': self.total_uptime
168
+ }
169
+ }
170
+
171
+ def get_defect_count(self) -> float:
172
+ """
173
+ Calculate number of defective units
174
+
175
+ Returns:
176
+ Number of defective units
177
+ """
178
+ return self.total_count - self.actual_count
179
+
180
+ def get_defect_rate(self) -> float:
181
+ """
182
+ Calculate defect rate percentage
183
+
184
+ Returns:
185
+ Defect rate percentage
186
+ """
187
+ if self.total_count == 0:
188
+ return 0.0
189
+ return round((self.get_defect_count() / self.total_count) * 100, 2)
190
+
191
+ def get_utilization_rate(self) -> float:
192
+ """
193
+ Calculate equipment utilization rate
194
+
195
+ Returns:
196
+ Utilization rate percentage
197
+ """
198
+ if self.total_time == 0:
199
+ return 0.0
200
+ return round((self.total_uptime / self.total_time) * 100, 2)
201
+
202
+ def get_production_efficiency(self) -> float:
203
+ """
204
+ Calculate production efficiency
205
+
206
+ Returns:
207
+ Production efficiency percentage
208
+ """
209
+ if self.ideal_production == 0:
210
+ return 0.0
211
+ return round((self.actual_count / self.ideal_production) * 100, 2)
212
+
213
+ def get_failure_frequency(self) -> float:
214
+ """
215
+ Calculate failure frequency per hour
216
+
217
+ Returns:
218
+ Failures per hour
219
+ """
220
+ if self.total_time == 0:
221
+ return 0.0
222
+ return round(self.fault_count / (self.total_time / 60), 2)
223
+
224
+ def get_cycle_times(self) -> Dict[str, float]:
225
+ """
226
+ Calculate ideal and actual cycle times
227
+
228
+ Returns:
229
+ Dictionary with cycle times
230
+ """
231
+ ideal_cycle_time = self.total_time / self.ideal_production if self.ideal_production > 0 else 0
232
+ actual_cycle_time = self.total_uptime / self.actual_count if self.actual_count > 0 else 0
233
+
234
+ return {
235
+ 'ideal_cycle_time': round(ideal_cycle_time, 2),
236
+ 'actual_cycle_time': round(actual_cycle_time, 2)
237
+ }
238
+
239
+ def get_run_rates(self) -> Dict[str, float]:
240
+ """
241
+ Calculate ideal and actual run rates
242
+
243
+ Returns:
244
+ Dictionary with run rates
245
+ """
246
+ ideal_run_rate = self.ideal_production / self.total_time if self.total_time > 0 else 0
247
+ actual_run_rate = self.actual_count / self.total_uptime if self.total_uptime > 0 else 0
248
+
249
+ return {
250
+ 'ideal_run_rate': round(ideal_run_rate, 2),
251
+ 'actual_run_rate': round(actual_run_rate, 2)
252
+ }
253
+
254
+ def get_summary(self) -> Dict[str, Any]:
255
+ """
256
+ Get complete summary of all metrics
257
+
258
+ Returns:
259
+ Dictionary with all calculated metrics
260
+ """
261
+ return {
262
+ 'input_data': {
263
+ 'total_time': self.total_time,
264
+ 'ideal_production': self.ideal_production,
265
+ 'actual_count': self.actual_count,
266
+ 'total_count': self.total_count,
267
+ 'fault_count': self.fault_count,
268
+ 'total_downtime': self.total_downtime,
269
+ 'total_uptime': self.total_uptime
270
+ },
271
+ 'oee_components': {
272
+ 'availability': self.calculate_availability(),
273
+ 'performance': self.calculate_performance(),
274
+ 'quality': self.calculate_quality()
275
+ },
276
+ 'oee': self.calculate_oee()['oee'],
277
+ 'maintenance': {
278
+ 'mttr': self.calculate_mttr(),
279
+ 'mtbf': self.calculate_mtbf()
280
+ },
281
+ 'quality_metrics': {
282
+ 'defect_count': self.get_defect_count(),
283
+ 'defect_rate': self.get_defect_rate()
284
+ },
285
+ 'efficiency_metrics': {
286
+ 'utilization_rate': self.get_utilization_rate(),
287
+ 'production_efficiency': self.get_production_efficiency(),
288
+ 'failure_frequency': self.get_failure_frequency()
289
+ },
290
+ 'cycle_analysis': {
291
+ 'cycle_times': self.get_cycle_times(),
292
+ 'run_rates': self.get_run_rates()
293
+ }
294
+ }
295
+
296
+ def __str__(self) -> str:
297
+ """
298
+ String representation of the metrics
299
+
300
+ Returns:
301
+ Formatted string with key metrics
302
+ """
303
+ return (f"ProductionMetrics("
304
+ f"total_time={self.total_time}, "
305
+ f"ideal={self.ideal_production}, "
306
+ f"actual={self.actual_count}, "
307
+ f"total={self.total_count}, "
308
+ f"faults={self.fault_count})")
309
+
310
+ def __repr__(self) -> str:
311
+ """
312
+ Detailed string representation
313
+
314
+ Returns:
315
+ Detailed string with all attributes
316
+ """
317
+ return (f"ProductionMetrics("
318
+ f"total_time={self.total_time}, "
319
+ f"ideal_production={self.ideal_production}, "
320
+ f"actual_count={self.actual_count}, "
321
+ f"total_count={self.total_count}, "
322
+ f"fault_count={self.fault_count}, "
323
+ f"total_downtime={self.total_downtime}, "
324
+ f"total_uptime={self.total_uptime})")
@@ -0,0 +1,104 @@
1
+ """Utility functions for digifact package"""
2
+
3
+ from typing import Dict, Any
4
+ import json
5
+ from datetime import datetime
6
+
7
+
8
+ def validate_metrics(data: Dict[str, Any]) -> bool:
9
+ """
10
+ Validate input metrics data
11
+
12
+ Args:
13
+ data: Dictionary containing metric values
14
+
15
+ Returns:
16
+ True if valid, raises ValueError if invalid
17
+ """
18
+ required_fields = [
19
+ 'total_time', 'ideal_production', 'actual_count',
20
+ 'total_count', 'fault_count', 'total_downtime', 'total_uptime'
21
+ ]
22
+
23
+ # Check for required fields
24
+ for field in required_fields:
25
+ if field not in data:
26
+ raise ValueError(f"Missing required field: {field}")
27
+
28
+ # Check for negative values
29
+ if data[field] < 0:
30
+ raise ValueError(f"{field} cannot be negative")
31
+
32
+ # Validate relationships
33
+ if data['total_downtime'] + data['total_uptime'] > data['total_time']:
34
+ raise ValueError("Downtime + Uptime cannot exceed total time")
35
+
36
+ if data['actual_count'] > data['total_count']:
37
+ raise ValueError("Actual count cannot exceed total count")
38
+
39
+ return True
40
+
41
+
42
+ def export_to_json(metrics: Dict[str, Any], filename: str = None) -> str:
43
+ """
44
+ Export metrics to JSON file
45
+
46
+ Args:
47
+ metrics: Dictionary containing calculated metrics
48
+ filename: Optional filename (auto-generated if not provided)
49
+
50
+ Returns:
51
+ Path to saved file
52
+ """
53
+ if filename is None:
54
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
55
+ filename = f"digifact_metrics_{timestamp}.json"
56
+
57
+ # Add timestamp to data
58
+ metrics['export_timestamp'] = datetime.now().isoformat()
59
+
60
+ with open(filename, 'w') as f:
61
+ json.dump(metrics, f, indent=2)
62
+
63
+ return filename
64
+
65
+
66
+ def format_report(metrics: Dict[str, Any]) -> str:
67
+ """
68
+ Format metrics as readable report
69
+
70
+ Args:
71
+ metrics: Dictionary containing calculated metrics
72
+
73
+ Returns:
74
+ Formatted report string
75
+ """
76
+ report = []
77
+ report.append("=" * 50)
78
+ report.append("DIGIFACT PRODUCTION METRICS REPORT")
79
+ report.append("=" * 50)
80
+ report.append("")
81
+
82
+ if 'oee_analysis' in metrics:
83
+ oee = metrics['oee_analysis']
84
+ report.append("OEE ANALYSIS:")
85
+ report.append(f" Overall OEE: {oee['oee']:.2f}")
86
+ report.append(f" Availability: {oee['availability']:.2f}%")
87
+ report.append(f" Performance: {oee['performance']:.2f}%")
88
+ report.append(f" Quality: {oee['quality']:.2f}%")
89
+ report.append("")
90
+
91
+ if 'mttr' in metrics:
92
+ report.append(f"MTTR: {metrics['mttr']:.2f} time units")
93
+
94
+ if 'mtbf' in metrics:
95
+ mtbf = metrics['mtbf']
96
+ if mtbf == float('inf'):
97
+ report.append("MTBF: Infinite (no failures)")
98
+ else:
99
+ report.append(f"MTBF: {mtbf:.2f} time units")
100
+
101
+ report.append("")
102
+ report.append("=" * 50)
103
+
104
+ return "\n".join(report)
@@ -0,0 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: digifact
3
+ Version: 0.1.0
4
+ Summary: Digifact - Manufacturing KPIs Calculation Package (OEE, MTTR, MTBF, Availability, Performance, Quality)
5
+ Author-email: Precise <digiapp@preciseindsol.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/digifact
8
+ Project-URL: Documentation, https://pypi.org/project/digifact
9
+ Project-URL: Source, https://github.com/yourusername/digifact
10
+ Keywords: manufacturing,OEE,KPI,production,MTTR,MTBF,availability,performance,quality
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Intended Audience :: Manufacturing
16
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
17
+ Requires-Python: >=3.8
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Dynamic: license-file
21
+
22
+ # Digifact
23
+
24
+ A Python package for calculating manufacturing KPIs including OEE (Overall Equipment Efficiency), Availability, Performance, Quality, MTTR, and MTBF.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install digifact
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ digifact/__init__.py
5
+ digifact/core.py
6
+ digifact/utils.py
7
+ digifact.egg-info/PKG-INFO
8
+ digifact.egg-info/SOURCES.txt
9
+ digifact.egg-info/dependency_links.txt
10
+ digifact.egg-info/top_level.txt
11
+ tests/__init__.py
12
+ tests/test_core.py
@@ -0,0 +1 @@
1
+ digifact
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "digifact"
7
+ version = "0.1.0"
8
+ description = "Digifact - Manufacturing KPIs Calculation Package (OEE, MTTR, MTBF, Availability, Performance, Quality)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+
12
+ authors = [
13
+ { name = "Precise", email = "digiapp@preciseindsol.com" }
14
+ ]
15
+
16
+ license = { text = "MIT" }
17
+
18
+ keywords = ["manufacturing", "OEE", "KPI", "production", "MTTR", "MTBF", "availability", "performance", "quality"]
19
+
20
+ classifiers = [
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Operating System :: OS Independent",
25
+ "Intended Audience :: Manufacturing",
26
+ "Topic :: Scientific/Engineering :: Information Analysis"
27
+ ]
28
+
29
+ dependencies = []
30
+
31
+ [project.urls]
32
+ Homepage = "https://pypi.org/project/digifact"
33
+ Documentation = "https://pypi.org/project/digifact"
34
+ Source = "https://github.com/yourusername/digifact"
35
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,111 @@
1
+ """Unit tests for digifact core functionality"""
2
+
3
+ import unittest
4
+ from digifact.core import ProductionMetrics,calculate_availability, calculate_mtbf, calculate_mttr, calculate_oee, calculate_quality, calculate_performance
5
+
6
+ class TestDigifact(unittest.TestCase):
7
+
8
+ def setUp(self):
9
+ """Setup test data"""
10
+ self.metrics = ProductionMetrics(
11
+ total_time=480, # 8 hours in minutes
12
+ ideal_production=1000, # Ideal units per shift
13
+ actual_count=950, # Actual units produced
14
+ total_count=1000, # Total units (including defects)
15
+ fault_count=5, # Number of breakdowns
16
+ total_downtime=60, # 60 minutes downtime
17
+ total_uptime=420 # 420 minutes uptime
18
+ )
19
+ def test_calculate_availability(self):
20
+ # """Availability = uptime / total_time * 100"""
21
+ # result = calculate_availability(self.metrics)
22
+ # self.assertAlmostEqual(result, 87.5, places=1)
23
+ """Test availability calculation"""
24
+ result = calculate_availability(self.metrics)
25
+ self.assertEqual(result, 95.0) # (950/1000)*100
26
+ print(f"\nAvailability test passed: {result}%")
27
+
28
+ def test_calculate_performance(self):
29
+ # """Performance = actual / ideal * 100"""
30
+ # result = calculate_performance(self.metrics)
31
+ # self.assertAlmostEqual(result, 95.0, places=1)
32
+ """Test performance calculation"""
33
+ result = calculate_performance(self.metrics)
34
+ self.assertAlmostEqual(result, 95.0, places=1)
35
+ print(f"\nPerformance test passed: {result}%")
36
+
37
+ def test_calculate_quality(self):
38
+ # """Quality = good / total * 100"""
39
+ # result = calculate_quality(self.metrics)
40
+ # self.assertAlmostEqual(result, 95.0, places=1)
41
+ """Test quality calculation"""
42
+ result = calculate_quality(self.metrics)
43
+ self.assertEqual(result, -5.0) # (950-1000)/1000*100
44
+ print(f"\nQuality test passed: {result}%")
45
+
46
+ def test_calculate_mttr(self):
47
+ # """MTTR = downtime / faults"""
48
+ # result = calculate_mttr(self.metrics)
49
+ # self.assertEqual(result, 12.0)
50
+ """Test MTTR calculation"""
51
+ result = calculate_mttr(self.metrics)
52
+ self.assertEqual(result, 12.0) # 60/5
53
+ print(f"\nMTTR test passed: {result} minutes")
54
+
55
+ def test_calculate_mtbf(self):
56
+ # """MTBF = uptime / faults"""
57
+ # result = calculate_mtbf(self.metrics)
58
+ # self.assertEqual(result, 84.0)
59
+ """Test MTBF calculation"""
60
+ result = calculate_mtbf(self.metrics)
61
+ self.assertEqual(result, 84.0) # 420/5
62
+ print(f"\nMTBF test passed: {result} minutes")
63
+
64
+ def test_calculate_oee(self):
65
+ # """OEE = Availability × Performance × Quality / 10000"""
66
+ # result = calculate_oee(self.metrics)
67
+
68
+ # self.assertIn("oee", result)
69
+ # self.assertIn("availability", result)
70
+ # self.assertIn("performance", result)
71
+ # self.assertIn("quality", result)
72
+
73
+ # self.assertAlmostEqual(result["availability"], 87.5, places=1)
74
+ # self.assertAlmostEqual(result["performance"], 95.0, places=1)
75
+ # self.assertAlmostEqual(result["quality"], 95.0, places=1)
76
+
77
+ # expected_oee = (87.5 * 95.0 * 95.0) / 10000
78
+ # self.assertAlmostEqual(result["oee"], expected_oee, places=1)
79
+ """Test OEE calculation"""
80
+ result = calculate_oee(self.metrics)
81
+ self.assertIn('oee', result)
82
+ self.assertIn('availability', result)
83
+ self.assertIn('performance', result)
84
+ self.assertIn('quality', result)
85
+ print(f"\nOEE test passed: {result['oee']}")
86
+
87
+ # def test_zero_fault_mttr(self):
88
+ # self.metrics.fault_count = 0
89
+ # result = calculate_mttr(self.metrics)
90
+ # self.assertEqual(result, 0)
91
+
92
+ # def test_zero_total_time_availability(self):
93
+ # self.metrics.total_time = 0
94
+ # result = calculate_availability(self.metrics)
95
+ # self.assertEqual(result, 0)
96
+
97
+
98
+
99
+ if __name__ == '__main__':
100
+ metrics2 = ProductionMetrics(
101
+ total_time=10000,
102
+ ideal_production=1000,
103
+ actual_count=100,
104
+ total_count=800,
105
+ fault_count=5,
106
+ total_downtime=200,
107
+ total_uptime=830
108
+ )
109
+ result = calculate_availability(metrics2)
110
+ print(f"Availability: {result}%")
111
+ # unittest.main()