Skip to content

Commit 04aea8e

Browse files
committed
fix: fix lint
1 parent a698cb0 commit 04aea8e

File tree

14 files changed

+478
-440
lines changed

14 files changed

+478
-440
lines changed

.github/workflows/security.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v4
14-
14+
1515
- name: Run Bandit security scan
1616
run: |
1717
pip install bandit
1818
bandit -r min_ratio_cycle/
19-
19+
2020
- name: Run Safety check
2121
run: |
2222
pip install safety
2323
safety check
24-
24+
2525
- name: Dependency vulnerability scan
2626
uses: pypa/[email protected]

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ import subprocess
141141
import sys
142142

143143
try:
144-
result = subprocess.run(['pytest', '--collect-only', '-q'],
144+
result = subprocess.run(['pytest', '--collect-only', '-q'],
145145
capture_output=True, text=True)
146146
lines = result.stdout.strip().split('\n')
147147
for line in lines[-5:]:
@@ -165,7 +165,7 @@ print(f' Memory: {psutil.virtual_memory().total // (1024**3)}GB')
165165
print()
166166

167167
start_time = time.time()
168-
result = subprocess.run(['python', 'run_tests.py', '--quick'],
168+
result = subprocess.run(['python', 'run_tests.py', '--quick'],
169169
capture_output=True)
170170
elapsed = time.time() - start_time
171171

docs/conf.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import os
22
import sys
3-
sys.path.insert(0, os.path.abspath('..'))
43

5-
project = 'Min Ratio Cycle'
6-
author = 'Diogo Ribeiro'
7-
release = '0.1.0'
4+
sys.path.insert(0, os.path.abspath(".."))
5+
6+
project = "Min Ratio Cycle"
7+
author = "Diogo Ribeiro"
8+
release = "0.1.0"
89

910
extensions = [
10-
'sphinx.ext.autodoc',
11-
'sphinx.ext.napoleon',
12-
'sphinx.ext.viewcode',
11+
"sphinx.ext.autodoc",
12+
"sphinx.ext.napoleon",
13+
"sphinx.ext.viewcode",
1314
]
1415

15-
templates_path = ['_templates']
16+
templates_path = ["_templates"]
1617
exclude_patterns = []
1718

18-
html_theme = 'alabaster'
19+
html_theme = "alabaster"

min_ratio_cycle/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
__version__ = "0.1.0"
55
__author__ = "Diogo Ribeiro"
66

7-
from .solver import MinRatioCycleSolver, Edge
7+
from .solver import Edge, MinRatioCycleSolver
88

99
__all__ = ["MinRatioCycleSolver", "Edge"]

min_ratio_cycle/monitoring/__init__.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,27 @@
1616
- progress_tracker: Progress tracking context manager
1717
"""
1818

19-
from .metrics import SolverMetrics, MetricsCollector, PerformanceAnalyzer
19+
from .health import SolverHealthCheck, run_health_check
2020
from .logging import SolverLogger, setup_logging
21+
from .metrics import MetricsCollector, PerformanceAnalyzer, SolverMetrics
2122
from .profiler import SolverProfiler, profile_operation
22-
from .health import SolverHealthCheck, run_health_check
23-
from .progress import progress_tracker, ProgressTracker
23+
from .progress import ProgressTracker, progress_tracker
2424

2525
__all__ = [
2626
# Core monitoring classes
27-
'SolverMetrics',
28-
'SolverLogger',
29-
'SolverProfiler',
30-
'SolverHealthCheck',
31-
27+
"SolverMetrics",
28+
"SolverLogger",
29+
"SolverProfiler",
30+
"SolverHealthCheck",
3231
# Utility classes
33-
'MetricsCollector',
34-
'PerformanceAnalyzer',
35-
'ProgressTracker',
36-
32+
"MetricsCollector",
33+
"PerformanceAnalyzer",
34+
"ProgressTracker",
3735
# Convenience functions
38-
'setup_logging',
39-
'profile_operation',
40-
'run_health_check',
41-
'progress_tracker',
36+
"setup_logging",
37+
"profile_operation",
38+
"run_health_check",
39+
"progress_tracker",
4240
]
4341

4442
# Version info
Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,179 @@
1+
import json
12
import logging
23
import time
3-
import json
4+
45

56
# Missing: Health check and diagnostics
67
class SolverHealthCheck:
78
"""System health checks and diagnostics."""
8-
9+
910
def __init__(self):
1011
self.checks = []
11-
12+
1213
def check_numpy_version(self):
1314
"""Check NumPy version compatibility."""
1415
import numpy as np
16+
1517
min_version = "1.20.0"
1618
current = np.__version__
17-
19+
1820
try:
1921
from packaging import version
22+
2023
is_compatible = version.parse(current) >= version.parse(min_version)
2124
except ImportError:
2225
# Fallback comparison
2326
is_compatible = current >= min_version
24-
27+
2528
return {
26-
'check': 'numpy_version',
27-
'status': 'PASS' if is_compatible else 'FAIL',
28-
'details': f'NumPy {current} (min required: {min_version})',
29-
'recommendation': 'Update NumPy' if not is_compatible else None
29+
"check": "numpy_version",
30+
"status": "PASS" if is_compatible else "FAIL",
31+
"details": f"NumPy {current} (min required: {min_version})",
32+
"recommendation": "Update NumPy" if not is_compatible else None,
3033
}
31-
34+
3235
def check_memory_available(self, min_memory_gb=1.0):
3336
"""Check available system memory."""
3437
try:
3538
import psutil
39+
3640
available_gb = psutil.virtual_memory().available / (1024**3)
3741
is_sufficient = available_gb >= min_memory_gb
38-
42+
3943
return {
40-
'check': 'memory_available',
41-
'status': 'PASS' if is_sufficient else 'WARN',
42-
'details': f'{available_gb:.1f}GB available (min: {min_memory_gb}GB)',
43-
'recommendation': 'Consider smaller graphs or more memory' if not is_sufficient else None
44+
"check": "memory_available",
45+
"status": "PASS" if is_sufficient else "WARN",
46+
"details": f"{available_gb:.1f}GB available (min: {min_memory_gb}GB)",
47+
"recommendation": "Consider smaller graphs or more memory"
48+
if not is_sufficient
49+
else None,
4450
}
4551
except ImportError:
4652
return {
47-
'check': 'memory_available',
48-
'status': 'SKIP',
49-
'details': 'psutil not available',
50-
'recommendation': 'Install psutil for memory monitoring'
53+
"check": "memory_available",
54+
"status": "SKIP",
55+
"details": "psutil not available",
56+
"recommendation": "Install psutil for memory monitoring",
5157
}
52-
58+
5359
def check_numerical_precision(self):
5460
"""Check floating-point precision issues."""
5561
import numpy as np
56-
62+
5763
# Test for common precision issues
5864
test_cases = [
5965
(0.1 + 0.2, 0.3), # Classic floating-point issue
6066
(1e16 + 1.0 - 1e16, 1.0), # Large number precision
6167
]
62-
68+
6369
issues = []
6470
for computed, expected in test_cases:
6571
if abs(computed - expected) > 1e-15:
6672
issues.append(f"{computed} != {expected}")
67-
73+
6874
return {
69-
'check': 'numerical_precision',
70-
'status': 'WARN' if issues else 'PASS',
71-
'details': f'Found {len(issues)} precision issues' if issues else 'No precision issues detected',
72-
'recommendation': 'Use exact mode when possible' if issues else None
75+
"check": "numerical_precision",
76+
"status": "WARN" if issues else "PASS",
77+
"details": f"Found {len(issues)} precision issues"
78+
if issues
79+
else "No precision issues detected",
80+
"recommendation": "Use exact mode when possible" if issues else None,
7381
}
74-
82+
7583
def run_all_checks(self):
7684
"""Run all health checks."""
7785
checks = [
7886
self.check_numpy_version(),
7987
self.check_memory_available(),
8088
self.check_numerical_precision(),
8189
]
82-
90+
8391
return {
84-
'timestamp': time.time(),
85-
'checks': checks,
86-
'summary': {
87-
'total': len(checks),
88-
'passed': sum(1 for c in checks if c['status'] == 'PASS'),
89-
'warnings': sum(1 for c in checks if c['status'] == 'WARN'),
90-
'failures': sum(1 for c in checks if c['status'] == 'FAIL'),
91-
}
92+
"timestamp": time.time(),
93+
"checks": checks,
94+
"summary": {
95+
"total": len(checks),
96+
"passed": sum(1 for c in checks if c["status"] == "PASS"),
97+
"warnings": sum(1 for c in checks if c["status"] == "WARN"),
98+
"failures": sum(1 for c in checks if c["status"] == "FAIL"),
99+
},
92100
}
93101

102+
94103
# Missing: Configuration management
95104
class SolverConfig:
96105
"""Configuration management for solver parameters."""
97-
106+
98107
DEFAULT_CONFIG = {
99-
'numeric_mode': {
100-
'max_iter': 60,
101-
'tol': 1e-12,
102-
'detect_cycle_slack': 1e-15,
108+
"numeric_mode": {
109+
"max_iter": 60,
110+
"tol": 1e-12,
111+
"detect_cycle_slack": 1e-15,
103112
},
104-
'exact_mode': {
105-
'max_den': None, # Auto-determine
106-
'max_steps': None, # Auto-determine
113+
"exact_mode": {
114+
"max_den": None, # Auto-determine
115+
"max_steps": None, # Auto-determine
107116
},
108-
'performance': {
109-
'enable_logging': True,
110-
'enable_metrics': True,
111-
'enable_profiling': False,
117+
"performance": {
118+
"enable_logging": True,
119+
"enable_metrics": True,
120+
"enable_profiling": False,
121+
},
122+
"validation": {
123+
"validate_cycles": True,
124+
"check_consistency": True,
112125
},
113-
'validation': {
114-
'validate_cycles': True,
115-
'check_consistency': True,
116-
}
117126
}
118-
127+
119128
def __init__(self, config_dict=None, config_file=None):
120129
self.config = self.DEFAULT_CONFIG.copy()
121-
130+
122131
if config_file:
123132
self.load_from_file(config_file)
124-
133+
125134
if config_dict:
126135
self._update_config(config_dict)
127-
136+
128137
def load_from_file(self, filename):
129138
"""Load configuration from JSON file."""
130139
try:
131-
with open(filename, 'r') as f:
140+
with open(filename, "r") as f:
132141
file_config = json.load(f)
133142
self._update_config(file_config)
134143
except FileNotFoundError:
135144
logging.warning(f"Config file {filename} not found, using defaults")
136145
except json.JSONDecodeError as e:
137146
logging.error(f"Invalid JSON in config file: {e}")
138-
147+
139148
def _update_config(self, new_config):
140149
"""Recursively update configuration."""
150+
141151
def deep_update(base, update):
142152
for key, value in update.items():
143-
if key in base and isinstance(base[key], dict) and isinstance(value, dict):
153+
if (
154+
key in base
155+
and isinstance(base[key], dict)
156+
and isinstance(value, dict)
157+
):
144158
deep_update(base[key], value)
145159
else:
146160
base[key] = value
147-
161+
148162
deep_update(self.config, new_config)
149-
163+
150164
def get(self, path, default=None):
151165
"""Get configuration value using dot notation."""
152-
keys = path.split('.')
166+
keys = path.split(".")
153167
value = self.config
154-
168+
155169
try:
156170
for key in keys:
157171
value = value[key]
158172
return value
159173
except (KeyError, TypeError):
160174
return default
161-
175+
162176
def save_to_file(self, filename):
163177
"""Save current configuration to file."""
164-
with open(filename, 'w') as f:
178+
with open(filename, "w") as f:
165179
json.dump(self.config, f, indent=2)

0 commit comments

Comments
 (0)