Skip to content

Commit d063a89

Browse files
author
gangs2314
committed
fix: resolve ruff linting, naming, and type hint issues
1 parent cee0636 commit d063a89

18 files changed

Lines changed: 283 additions & 137 deletions

fix_ruff_errors.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Auto-fix script for TheAlgorithms/Python PR ruff errors.
4+
Run from repo root: python fix_ruff_errors.py
5+
"""
6+
7+
from pathlib import Path
8+
9+
10+
def fix_floyd_warshall():
11+
p = Path("graphs/floyd_warshall.py")
12+
text = p.read_text()
13+
text = text.replace(
14+
'current = next_node[current][end] # type: ignore',
15+
'current = next_node[current][end] # type: ignore[assignment]'
16+
)
17+
p.write_text(text)
18+
print("fixed graphs/floyd_warshall.py")
19+
20+
21+
def fix_ford_fulkerson():
22+
p = Path("graphs/ford_fulkerson.py")
23+
text = p.read_text()
24+
text = text.replace(
25+
'u = parent[s] # type: ignore',
26+
'u = parent[s] # type: ignore[assignment]'
27+
)
28+
p.write_text(text)
29+
print("fixed graphs/ford_fulkerson.py")
30+
31+
32+
def fix_heavy_light_decomposition():
33+
p = Path("graphs/heavy_light_decomposition.py")
34+
text = p.read_text()
35+
old = """ # Same chain now
36+
l, r = self.pos[u], self.pos[v]
37+
if l > r:
38+
l, r = r, l
39+
segment = self.base_array[l : r + 1]"""
40+
new = """ # Same chain now
41+
left_idx, right_idx = self.pos[u], self.pos[v]
42+
if left_idx > right_idx:
43+
left_idx, right_idx = right_idx, left_idx
44+
segment = self.base_array[left_idx : right_idx + 1]"""
45+
text = text.replace(old, new)
46+
p.write_text(text)
47+
print("fixed graphs/heavy_light_decomposition.py")
48+
49+
50+
def fix_hopcroft_karp():
51+
p = Path("graphs/hopcroft_karp.py")
52+
text = p.read_text()
53+
54+
text = text.replace(
55+
'self.dist[u] = float("inf") # type: ignore',
56+
'self.dist[u] = float("inf") # type: ignore[assignment]',
57+
1
58+
)
59+
text = text.replace(
60+
'if pair_v is not None and self.dist[pair_v] == float("inf"): # type: ignore',
61+
'if pair_v is not None and self.dist[pair_v] == float("inf"): # type: ignore[operator]'
62+
)
63+
text = text.replace(
64+
'self.dist[u] = float("inf") # type: ignore',
65+
'self.dist[u] = float("inf") # type: ignore[assignment]'
66+
)
67+
68+
old = """ if self.pair_u[u] is None:
69+
if self.dfs(u):
70+
matching += 1"""
71+
new = """ if self.pair_u[u] is None and self.dfs(u):
72+
matching += 1"""
73+
text = text.replace(old, new)
74+
75+
old = """ print(
76+
f"Hopcroft-Karp: {n}x{m}, {edges} edges, matching={result}, time={elapsed:.3f}s"
77+
)"""
78+
new = """ print(
79+
f"Hopcroft-Karp: {n}x{m}, {edges} edges, "
80+
f"matching={result}, time={elapsed:.3f}s"
81+
)"""
82+
text = text.replace(old, new)
83+
84+
p.write_text(text)
85+
print("fixed graphs/hopcroft_karp.py")
86+
87+
88+
def fix_max_bipartite_independent_set():
89+
p = Path("graphs/max_bipartite_independent_set.py")
90+
text = p.read_text()
91+
92+
text = text.replace(
93+
'# Minimum vertex cover = (U - Z) \u222a (V \u2229 Z)',
94+
'# Minimum vertex cover = (U - Z) union (V intersect Z)'
95+
)
96+
text = text.replace(
97+
'# Maximum independent set = Z \u222a (V - Z) = complement of min vertex cover',
98+
'# Maximum independent set = Z union (V - Z) = complement of min vertex cover'
99+
)
100+
text = text.replace(
101+
'dist[u] = float("inf") # type: ignore',
102+
'dist[u] = float("inf") # type: ignore[assignment]',
103+
1
104+
)
105+
text = text.replace(
106+
'if pu is not None and dist[pu] == float("inf"): # type: ignore',
107+
'if pu is not None and dist[pu] == float("inf"): # type: ignore[operator]'
108+
)
109+
text = text.replace(
110+
'dist[u] = float("inf") # type: ignore',
111+
'dist[u] = float("inf") # type: ignore[assignment]'
112+
)
113+
114+
p.write_text(text)
115+
print("fixed graphs/max_bipartite_independent_set.py")
116+
117+
118+
def fix_push_relabel():
119+
p = Path("graphs/push_relabel.py")
120+
text = p.read_text()
121+
122+
old = 'v for v in range(n) if v != source and v != sink and self.excess[v] > 0'
123+
new = 'v for v in range(n) if v not in (source, sink) and self.excess[v] > 0'
124+
text = text.replace(old, new)
125+
126+
old = """ if (
127+
v != source
128+
and v != sink
129+
and self.excess[v] == self.excess[u] + 1
130+
):"""
131+
new = """ if (
132+
v not in (source, sink)
133+
and self.excess[v] == self.excess[u] + 1
134+
):"""
135+
text = text.replace(old, new)
136+
137+
p.write_text(text)
138+
print("fixed graphs/push_relabel.py")
139+
140+
141+
def fix_test_graph_algorithms():
142+
p = Path("graphs/tests/test_graph_algorithms.py")
143+
text = p.read_text()
144+
145+
text = text.replace(
146+
'dist, next_node = floyd_warshall(graph)',
147+
'_dist, next_node = floyd_warshall(graph)'
148+
)
149+
text = text.replace(
150+
'result = hk.max_matching()',
151+
'hk.max_matching()'
152+
)
153+
154+
p.write_text(text)
155+
print("fixed graphs/tests/test_graph_algorithms.py")
156+
157+
158+
if __name__ == "__main__":
159+
print("Applying auto-fixes for ruff errors...\n")
160+
fix_floyd_warshall()
161+
fix_ford_fulkerson()
162+
fix_heavy_light_decomposition()
163+
fix_hopcroft_karp()
164+
fix_max_bipartite_independent_set()
165+
fix_push_relabel()
166+
fix_test_graph_algorithms()
167+
print("\nAll fixes applied! Run 'ruff check graphs/' to verify.")

graphs/basic_graphs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ def adjm():
257257

258258

259259
def floy(a_and_n):
260-
(a, n) = a_and_n
260+
a, n = a_and_n
261261
dist = list(a)
262262
path = [[0] * n for i in range(n)]
263263
for k in range(n):
@@ -351,7 +351,7 @@ def krusk(e_and_n):
351351
"""
352352
Sort edges on the basis of distance
353353
"""
354-
(e, n) = e_and_n
354+
e, n = e_and_n
355355
e.sort(reverse=True, key=lambda x: x[2])
356356
s = [{i} for i in range(1, n + 1)]
357357
while True:

graphs/chinese_postman.py

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
Space Complexity: O(V²)
1010
"""
1111

12-
from typing import List, Tuple, Dict, Set
13-
import itertools
14-
1512

1613
class ChinesePostman:
1714
"""
@@ -20,7 +17,7 @@ class ChinesePostman:
2017

2118
def __init__(self, n: int):
2219
self.n = n
23-
self.adj: List[List[Tuple[int, int]]] = [[] for _ in range(n)]
20+
self.adj: list[list[tuple[int, int]]] = [[] for _ in range(n)]
2421
self.total_weight = 0
2522

2623
def add_edge(self, u: int, v: int, w: int) -> None:
@@ -29,7 +26,7 @@ def add_edge(self, u: int, v: int, w: int) -> None:
2926
self.adj[v].append((u, w))
3027
self.total_weight += w
3128

32-
def _floyd_warshall(self) -> List[List[float]]:
29+
def _floyd_warshall(self) -> list[list[float]]:
3330
"""All-pairs shortest paths."""
3431
n = self.n
3532
dist = [[float("inf")] * n for _ in range(n)]
@@ -44,12 +41,11 @@ def _floyd_warshall(self) -> List[List[float]]:
4441
for k in range(n):
4542
for i in range(n):
4643
for j in range(n):
47-
if dist[i][k] + dist[k][j] < dist[i][j]:
48-
dist[i][j] = dist[i][k] + dist[k][j]
44+
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
4945

5046
return dist
5147

52-
def _find_odd_degree_vertices(self) -> List[int]:
48+
def _find_odd_degree_vertices(self) -> list[int]:
5349
"""Find vertices with odd degree."""
5450
odd = []
5551
for u in range(self.n):
@@ -58,7 +54,7 @@ def _find_odd_degree_vertices(self) -> List[int]:
5854
return odd
5955

6056
def _min_weight_perfect_matching(
61-
self, odd_vertices: List[int], dist: List[List[float]]
57+
self, odd_vertices: list[int], dist: list[list[float]]
6258
) -> float:
6359
"""
6460
Find minimum weight perfect matching on odd degree vertices.
@@ -69,7 +65,7 @@ def _min_weight_perfect_matching(
6965
return 0
7066

7167
# Dynamic programming: dp[mask] = min cost to match vertices in mask
72-
dp: Dict[int, float] = {0: 0}
68+
dp: dict[int, float] = {0: 0}
7369

7470
for mask in range(1 << k):
7571
if bin(mask).count("1") % 2 == 1:
@@ -97,7 +93,7 @@ def _min_weight_perfect_matching(
9793
full_mask = (1 << k) - 1
9894
return dp.get(full_mask, 0)
9995

100-
def solve(self) -> Tuple[float, List[int]]:
96+
def solve(self) -> tuple[float, list[int]]:
10197
"""
10298
Solve Chinese Postman Problem.
10399
@@ -137,16 +133,14 @@ def solve(self) -> Tuple[float, List[int]]:
137133
return float(self.total_weight + matching_cost), circuit
138134

139135
def _add_matching_edges(
140-
self, odd_vertices: List[int], dist: List[List[float]]
136+
self, odd_vertices: list[int], dist: list[list[float]]
141137
) -> None:
142138
"""Duplicate edges based on minimum matching (simplified)."""
143139
# In practice, reconstruct path and add edges
144140
# For this implementation, we assume edges can be duplicated
145-
pass
146141

147-
def _find_eulerian_circuit(self) -> List[int]:
142+
def _find_eulerian_circuit(self) -> list[int]:
148143
"""Find Eulerian circuit using Hierholzer's algorithm."""
149-
n = self.n
150144
adj_copy = [list(neighbors) for neighbors in self.adj]
151145
circuit = []
152146
stack = [0]
@@ -168,8 +162,8 @@ def _find_eulerian_circuit(self) -> List[int]:
168162

169163

170164
def chinese_postman(
171-
n: int, edges: List[Tuple[int, int, int]]
172-
) -> Tuple[float, List[int]]:
165+
n: int, edges: list[tuple[int, int, int]]
166+
) -> tuple[float, list[int]]:
173167
"""
174168
Convenience function for Chinese Postman.
175169

graphs/dijkstra.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def dijkstra(graph, start, end):
4848
heap = [(0, start)] # cost from start node,end node
4949
visited = set()
5050
while heap:
51-
(cost, u) = heapq.heappop(heap)
51+
cost, u = heapq.heappop(heap)
5252
if u in visited:
5353
continue
5454
visited.add(u)

graphs/dijkstra_binary_grid.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def dijkstra(
5757
predecessors[source] = None
5858

5959
while queue:
60-
(dist, (x, y)) = heappop(queue)
60+
dist, (x, y) = heappop(queue)
6161
if (x, y) in visited:
6262
continue
6363
visited.add((x, y))

graphs/floyd_warshall.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@
88
Space Complexity: O(V²)
99
"""
1010

11-
from typing import List, Tuple, Optional
12-
1311

1412
def floyd_warshall(
15-
graph: List[List[float]],
16-
) -> Tuple[List[List[float]], List[List[Optional[int]]]]:
13+
graph: list[list[float]],
14+
) -> tuple[list[list[float]], list[list[int | None]]]:
1715
"""
1816
Compute all-pairs shortest paths using Floyd-Warshall algorithm.
1917
@@ -61,8 +59,8 @@ def floyd_warshall(
6159

6260

6361
def reconstruct_path(
64-
next_node: List[List[Optional[int]]], start: int, end: int
65-
) -> Optional[List[int]]:
62+
next_node: list[list[int | None]], start: int, end: int
63+
) -> list[int] | None:
6664
"""
6765
Reconstruct shortest path from start to end using next_node matrix.
6866
@@ -75,13 +73,13 @@ def reconstruct_path(
7573
current = start
7674

7775
while current != end:
78-
current = next_node[current][end] # type: ignore
76+
current = next_node[current][end]
7977
path.append(current)
8078

8179
return path
8280

8381

84-
def floyd_warshall_optimized(graph: List[List[float]]) -> List[List[float]]:
82+
def floyd_warshall_optimized(graph: list[list[float]]) -> list[list[float]]:
8583
"""
8684
Space-optimized version using only distance matrix.
8785
Use when path reconstruction is not needed.
@@ -100,8 +98,7 @@ def floyd_warshall_optimized(graph: List[List[float]]) -> List[List[float]]:
10098
if dist[k][j] == float("inf"):
10199
continue
102100
new_dist = dist[i][k] + dist[k][j]
103-
if new_dist < dist[i][j]:
104-
dist[i][j] = new_dist
101+
dist[i][j] = min(dist[i][j], new_dist)
105102

106103
return dist
107104

0 commit comments

Comments
 (0)