Skip to content

Commit f3cb719

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent a84ebb3 commit f3cb719

9 files changed

Lines changed: 132 additions & 42 deletions

File tree

data_structures/simple/run_ds_tests.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def run() -> None:
2626
assert ll.to_list() == [0, 2]
2727
print("LinkedList: OK")
2828
except Exception as e:
29-
failures.append(('LinkedList', e))
29+
failures.append(("LinkedList", e))
3030

3131
try:
3232
s = ListStack()
@@ -36,13 +36,13 @@ def run() -> None:
3636
assert s.pop() == 2
3737

3838
ls = LinkedStack()
39-
ls.push('a')
40-
ls.push('b')
41-
assert ls.peek() == 'b'
42-
assert ls.pop() == 'b'
39+
ls.push("a")
40+
ls.push("b")
41+
assert ls.peek() == "b"
42+
assert ls.pop() == "b"
4343
print("Stacks: OK")
4444
except Exception as e:
45-
failures.append(('Stacks', e))
45+
failures.append(("Stacks", e))
4646

4747
try:
4848
q = Queue()
@@ -52,7 +52,7 @@ def run() -> None:
5252
assert q.dequeue() == 1
5353
print("Queue: OK")
5454
except Exception as e:
55-
failures.append(('Queue', e))
55+
failures.append(("Queue", e))
5656

5757
try:
5858
bst = BinarySearchTree()
@@ -62,7 +62,7 @@ def run() -> None:
6262
assert bst.inorder() == [1, 2, 3, 4]
6363
print("BST: OK")
6464
except Exception as e:
65-
failures.append(('BST', e))
65+
failures.append(("BST", e))
6666

6767
try:
6868
g = Graph()
@@ -74,16 +74,16 @@ def run() -> None:
7474
assert 1 in order_dfs
7575
print("Graph: OK")
7676
except Exception as e:
77-
failures.append(('Graph', e))
77+
failures.append(("Graph", e))
7878

7979
try:
8080
t = Trie()
81-
t.insert('hello')
82-
assert t.search('hello')
83-
assert t.starts_with('hel')
81+
t.insert("hello")
82+
assert t.search("hello")
83+
assert t.starts_with("hel")
8484
print("Trie: OK")
8585
except Exception as e:
86-
failures.append(('Trie', e))
86+
failures.append(("Trie", e))
8787

8888
try:
8989
uf = UnionFind()
@@ -93,7 +93,7 @@ def run() -> None:
9393
assert uf.find(1) == uf.find(2)
9494
print("UnionFind: OK")
9595
except Exception as e:
96-
failures.append(('UnionFind', e))
96+
failures.append(("UnionFind", e))
9797

9898
try:
9999
h = MinHeap()
@@ -104,16 +104,16 @@ def run() -> None:
104104
assert h.pop() == 1
105105
print("MinHeap: OK")
106106
except Exception as e:
107-
failures.append(('MinHeap', e))
107+
failures.append(("MinHeap", e))
108108

109109
if failures:
110-
print('\nFAILURES:')
110+
print("\nFAILURES:")
111111
for name, exc in failures:
112112
print(f"- {name}: {exc}")
113113
sys.exit(2)
114114
else:
115-
print('\nAll data_structures.simple smoke tests passed.')
115+
print("\nAll data_structures.simple smoke tests passed.")
116116

117117

118-
if __name__ == '__main__':
118+
if __name__ == "__main__":
119119
run()

data_structures/stacks/balanced_parentheses.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
from pathlib import Path
1111

1212
stack_path = Path(__file__).with_name("stack.py")
13-
spec = importlib.util.spec_from_file_location("data_structures.stacks.stack", str(stack_path))
13+
spec = importlib.util.spec_from_file_location(
14+
"data_structures.stacks.stack", str(stack_path)
15+
)
1416
_stack = importlib.util.module_from_spec(spec)
1517
sys.modules[spec.name] = _stack
1618
spec.loader.exec_module(_stack) # type: ignore[attr-defined]

scripts/run_doctests.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import traceback
2020
from pathlib import Path
2121

22-
ROOT = Path(__file__).resolve().parents[1] # Python/ (project root where data_structures lives)
22+
ROOT = (
23+
Path(__file__).resolve().parents[1]
24+
) # Python/ (project root where data_structures lives)
2325
DATA_DIR = ROOT / "data_structures"
2426

2527

@@ -69,7 +71,9 @@ def main() -> int:
6971
except Exception as ex2:
7072
print(f"Fallback testfile raised {ex2.__class__.__name__}: {ex2}")
7173
traceback.print_exc()
72-
results.append((str(rel), "error", f"import error: {e}; fallback error: {ex2}"))
74+
results.append(
75+
(str(rel), "error", f"import error: {e}; fallback error: {ex2}")
76+
)
7377

7478
# Summary
7579
print("\n=== Summary ===")

simulated_annealing/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- SimulatedAnnealing: core optimizer class
55
- example_functions: a small collection of test functions
66
"""
7+
78
from .simulated_annealing import SimulatedAnnealing
89
from .example import example_functions
910

simulated_annealing/example.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ def sphere(x: Sequence[float]) -> float:
88
def rastrigin(x: Sequence[float]) -> float:
99
# Rastrigin function (common test function)
1010
A = 10
11-
return A * len(x) + sum((v * v - A * __import__("math").cos(2 * __import__("math").pi * v)) for v in x)
11+
return A * len(x) + sum(
12+
(v * v - A * __import__("math").cos(2 * __import__("math").pi * v)) for v in x
13+
)
1214

1315

1416
example_functions: Dict[str, Callable[[Sequence[float]], float]] = {
@@ -20,10 +22,18 @@ def rastrigin(x: Sequence[float]) -> float:
2022
def cli_example():
2123
# CLI demo minimizing 2D sphere
2224
from .simulated_annealing import SimulatedAnnealing
25+
2326
func = sphere
2427
initial = [5.0, -3.0]
2528
bounds = [(-10, 10), (-10, 10)]
26-
sa = SimulatedAnnealing(func, initial, bounds=bounds, temperature=50, cooling_rate=0.95, iterations_per_temp=200)
29+
sa = SimulatedAnnealing(
30+
func,
31+
initial,
32+
bounds=bounds,
33+
temperature=50,
34+
cooling_rate=0.95,
35+
iterations_per_temp=200,
36+
)
2737
best, cost, history = sa.optimize()
2838
print("Best:", best)
2939
print("Cost:", cost)
@@ -41,7 +51,9 @@ def tsp_example():
4151
initial = [float(i) for i in init_tour]
4252
cost_fn = make_tsp_cost(coords)
4353

44-
sa = SimulatedAnnealing(cost_fn, initial, temperature=100.0, cooling_rate=0.995, iterations_per_temp=500)
54+
sa = SimulatedAnnealing(
55+
cost_fn, initial, temperature=100.0, cooling_rate=0.995, iterations_per_temp=500
56+
)
4557
best, cost, history = sa.optimize()
4658
best_tour = vector_to_tour(best)
4759
print("Best tour:", best_tour)

simulated_annealing/gui.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Optional
55

66
import matplotlib
7+
78
matplotlib.use("TkAgg")
89
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
910
import matplotlib.pyplot as plt
@@ -24,15 +25,22 @@ def __init__(self):
2425

2526
ttk.Label(ctrl, text="Function:").pack(anchor=tk.W)
2627
self.func_var = tk.StringVar(value="sphere")
27-
func_menu = ttk.Combobox(ctrl, textvariable=self.func_var, values=list(example_functions.keys()), state="readonly")
28+
func_menu = ttk.Combobox(
29+
ctrl,
30+
textvariable=self.func_var,
31+
values=list(example_functions.keys()),
32+
state="readonly",
33+
)
2834
func_menu.pack(fill=tk.X)
2935

3036
ttk.Label(ctrl, text="Initial (comma-separated)").pack(anchor=tk.W, pady=(8, 0))
3137
self.init_entry = ttk.Entry(ctrl)
3238
self.init_entry.insert(0, "5, -3")
3339
self.init_entry.pack(fill=tk.X)
3440

35-
ttk.Label(ctrl, text="Bounds (lo:hi comma-separated for each)").pack(anchor=tk.W, pady=(8, 0))
41+
ttk.Label(ctrl, text="Bounds (lo:hi comma-separated for each)").pack(
42+
anchor=tk.W, pady=(8, 0)
43+
)
3644
self.bounds_entry = ttk.Entry(ctrl)
3745
self.bounds_entry.insert(0, "-10:10, -10:10")
3846
self.bounds_entry.pack(fill=tk.X)
@@ -56,7 +64,9 @@ def __init__(self):
5664
self.run_btn.pack(fill=tk.X, pady=(12, 0))
5765

5866
self.stop_flag = threading.Event()
59-
self.stop_btn = ttk.Button(ctrl, text="Stop", command=self._on_stop, state=tk.DISABLED)
67+
self.stop_btn = ttk.Button(
68+
ctrl, text="Stop", command=self._on_stop, state=tk.DISABLED
69+
)
6070
self.stop_btn.pack(fill=tk.X, pady=(6, 0))
6171

6272
# Right: plot
@@ -65,7 +75,7 @@ def __init__(self):
6575
self.canvas = FigureCanvasTkAgg(fig, master=self)
6676
self.canvas.get_tk_widget().pack(side=tk.RIGHT, fill=tk.BOTH, expand=1)
6777

68-
self._plot_line, = self.ax.plot([], [], label="best_cost")
78+
(self._plot_line,) = self.ax.plot([], [], label="best_cost")
6979
self.ax.set_xlabel("Iterations")
7080
self.ax.set_ylabel("Best cost")
7181
self.ax.grid(True)
@@ -120,13 +130,22 @@ def _on_run(self):
120130
self.stop_flag.clear()
121131

122132
def worker():
123-
sa = SimulatedAnnealing(func, initial, bounds=bounds, temperature=temp, cooling_rate=cooling, iterations_per_temp=iterations)
133+
sa = SimulatedAnnealing(
134+
func,
135+
initial,
136+
bounds=bounds,
137+
temperature=temp,
138+
cooling_rate=cooling,
139+
iterations_per_temp=iterations,
140+
)
124141

125142
def progress_cb(step, best_cost, current_cost):
126143
# schedule a plot update on the main thread
127144
self.after(0, lambda: self._update_plot_partial(step, best_cost))
128145

129-
best, cost, history = sa.optimize(stop_event=self.stop_flag, progress_callback=progress_cb)
146+
best, cost, history = sa.optimize(
147+
stop_event=self.stop_flag, progress_callback=progress_cb
148+
)
130149
# update final plot on main thread
131150
self.after(0, lambda: self._on_complete(best, cost, history))
132151

@@ -158,7 +177,11 @@ def _on_complete(self, best, cost, history):
158177
def _update_plot_partial(self, step: int, best_cost: float):
159178
# Append a new point to plot (x=step, y=best_cost)
160179
# We'll redraw full plot for simplicity
161-
line_x = list(range(len(self.ax.lines[0].get_xdata()) + 1)) if self.ax.lines else [step]
180+
line_x = (
181+
list(range(len(self.ax.lines[0].get_xdata()) + 1))
182+
if self.ax.lines
183+
else [step]
184+
)
162185
if self.ax.lines:
163186
ydata = list(self.ax.lines[0].get_ydata())
164187
ydata.append(best_cost)

simulated_annealing/simulated_annealing.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,17 @@ def __init__(
2121
min_temperature: float = 1e-3,
2222
iterations_per_temp: int = 100,
2323
neighbor_scale: float = 0.1,
24-
local_search: Optional[Callable[[Sequence[float], Callable[[Sequence[float]], float], Callable[[Sequence[float]], Sequence[float]], int], Tuple[Sequence[float], float]]] = None,
24+
local_search: Optional[
25+
Callable[
26+
[
27+
Sequence[float],
28+
Callable[[Sequence[float]], float],
29+
Callable[[Sequence[float]], Sequence[float]],
30+
int,
31+
],
32+
Tuple[Sequence[float], float],
33+
]
34+
] = None,
2535
local_search_iters: int = 10,
2636
seed: Optional[int] = None,
2737
):
@@ -70,7 +80,12 @@ def _accept(self, delta: float, temp: float) -> bool:
7080
prob = 0.0
7181
return random.random() < prob
7282

73-
def optimize(self, max_steps: Optional[int] = None, stop_event: Optional[object] = None, progress_callback: Optional[Callable[[int, float, float], None]] = None) -> Tuple[List[float], float, dict]:
83+
def optimize(
84+
self,
85+
max_steps: Optional[int] = None,
86+
stop_event: Optional[object] = None,
87+
progress_callback: Optional[Callable[[int, float, float], None]] = None,
88+
) -> Tuple[List[float], float, dict]:
7489
"""Run optimization and return best solution, cost, and history.
7590
7691
New optional args:
@@ -91,15 +106,23 @@ def optimize(self, max_steps: Optional[int] = None, stop_event: Optional[object]
91106
while temp > self.min_temperature:
92107
for _ in range(self.iterations_per_temp):
93108
# Check stop event
94-
if stop_event is not None and getattr(stop_event, "is_set", lambda: False)():
109+
if (
110+
stop_event is not None
111+
and getattr(stop_event, "is_set", lambda: False)()
112+
):
95113
self.current = current
96114
return best, best_cost, history
97115

98116
candidate = self._neighbor(current)
99117
# Optionally refine candidate with local search before evaluating/accepting
100118
if self.local_search is not None:
101119
try:
102-
improved, improved_cost = self.local_search(candidate, self.func, self._neighbor, self.local_search_iters)
120+
improved, improved_cost = self.local_search(
121+
candidate,
122+
self.func,
123+
self._neighbor,
124+
self.local_search_iters,
125+
)
103126
candidate = list(improved)
104127
candidate_cost = float(improved_cost)
105128
except Exception:
@@ -120,7 +143,10 @@ def optimize(self, max_steps: Optional[int] = None, stop_event: Optional[object]
120143
history["current_costs"].append(current_cost)
121144

122145
steps += 1
123-
if progress_callback is not None and steps % max(1, self.iterations_per_temp // 10) == 0:
146+
if (
147+
progress_callback is not None
148+
and steps % max(1, self.iterations_per_temp // 10) == 0
149+
):
124150
try:
125151
progress_callback(steps, best_cost, current_cost)
126152
except Exception:
@@ -141,12 +167,19 @@ def optimize(self, max_steps: Optional[int] = None, stop_event: Optional[object]
141167
def _test_quadratic():
142168
# Simple test: minimize f(x) = (x-3)^2
143169
func = lambda x: (x[0] - 3) ** 2
144-
sa = SimulatedAnnealing(func, [0.0], bounds=[(-10, 10)], temperature=10, iterations_per_temp=50)
170+
sa = SimulatedAnnealing(
171+
func, [0.0], bounds=[(-10, 10)], temperature=10, iterations_per_temp=50
172+
)
145173
best, cost, hist = sa.optimize()
146174
print("best:", best, "cost:", cost)
147175

148176

149-
def simple_local_search(solution: Sequence[float], func: Callable[[Sequence[float]], float], neighbor_fn: Callable[[Sequence[float]], Sequence[float]], iterations: int = 10) -> Tuple[Sequence[float], float]:
177+
def simple_local_search(
178+
solution: Sequence[float],
179+
func: Callable[[Sequence[float]], float],
180+
neighbor_fn: Callable[[Sequence[float]], Sequence[float]],
181+
iterations: int = 10,
182+
) -> Tuple[Sequence[float], float]:
150183
"""A tiny hill-climbing local search that repeatedly accepts improving neighbors.
151184
152185
Parameters

0 commit comments

Comments
 (0)