Skip to content

Commit e3690e2

Browse files
committed
v2
1 parent 121a784 commit e3690e2

10 files changed

Lines changed: 53 additions & 18 deletions

File tree

‎Heuristics/Makefile‎

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,37 @@
1-
.PHONY: install test format lint refactor all clean help
1+
.PHONY: install test format format-check lint refactor all clean help
22

3+
# Install all dependencies
34
install:
45
@pip install --upgrade pip
56
@pip install -r requirements.txt
67

8+
# Run tests with coverage
79
test:
810
@pytest -vv --cov=TSP --cov-report=term-missing --cov-report=html tests/
911

12+
# Autoformat code
1013
format:
1114
@black TSP/ tests/
1215

16+
# Check code formatting (non-destructive)
17+
format-check:
18+
@black --check TSP/ tests/
19+
20+
# Lint Python code
1321
lint:
1422
@pylint --disable=R,C --ignore-patterns='test_.*\.py' TSP tests
1523

24+
# Format + lint
1625
refactor: format lint
1726

18-
all: install lint test
27+
# Full pipeline: install, format, check, lint, test, clean
28+
all: install format format-check lint test clean
1929

30+
# Remove caches and coverage reports
2031
clean:
2132
@rm -rf __pycache__ *.pyc *.pyo .pytest_cache htmlcov coverage.xml .coverage
2233

34+
# Show help for each target
2335
help:
24-
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
36+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | \
37+
awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

‎Heuristics/TSP/__init__.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
my_cities,
2424
create_cities_dataframe,
2525
main,
26-
2726
)
2827

2928
# CLI entry
@@ -39,5 +38,5 @@
3938
"my_cities",
4039
"create_cities_dataframe",
4140
"cli",
42-
"main"
41+
"main",
4342
]

‎Heuristics/TSP/cli.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import click
66
import warnings
7+
78
warnings.filterwarnings("ignore", category=RuntimeWarning)
89
from .tsp_pandas import create_cities, tsp_pandas
910
from .visualization import plot_path
@@ -13,6 +14,7 @@
1314
def cli():
1415
"""TSP command-line tool."""
1516

17+
1618
@cli.command()
1719
@click.option("--count", default=1, type=int, help="Number of simulations to run")
1820
@click.option("--plot", is_flag=True, help="Plot the best route")
@@ -34,7 +36,6 @@ def simulate(count, plot):
3436
plot_path(best_route_order)
3537

3638

37-
3839
@cli.command()
3940
@click.option(
4041
"--city",

‎Heuristics/TSP/tsp_pandas.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def create_cities():
4848

4949
def euclidean_distance(lat1, lon1, lat2, lon2):
5050
return np.sqrt((lat1 - lat2) ** 2 + (lon1 - lon2) ** 2)
51+
52+
5153
#
5254
#
5355
# def tsp_pandas(df: pd.DataFrame):
@@ -83,6 +85,7 @@ def euclidean_distance(lat1, lon1, lat2, lon2):
8385
# # ✅ Return distance first, then route list
8486
# return float(total_distance), route_list
8587

88+
8689
def tsp_pandas(df: pd.DataFrame):
8790
df = df.copy()
8891
random.seed(42) # deterministic for testing

‎Heuristics/TSP/visualization.py‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1+
import os
2+
import matplotlib
13
import matplotlib.pyplot as plt
24
from .tsp_pandas import create_cities
35

4-
def plot_path(route):
6+
# Use non-interactive backend in CI / headless environments
7+
if os.environ.get("CI"):
8+
matplotlib.use("Agg")
9+
10+
11+
def plot_path(route, save_path="tsp_route.png"):
512
"""
6-
route: list of city names in order
13+
Plots the TSP route.
14+
15+
Parameters:
16+
- route: list of city names in order
17+
- save_path: file path to save the plot (default: tsp_route.png)
18+
19+
Behavior:
20+
- In CI (headless), the plot is saved automatically.
21+
- Locally, the plot window is displayed for interactive viewing.
722
"""
823
df = create_cities()
924
df = df.set_index("city").loc[route] # order cities
@@ -12,10 +27,20 @@ def plot_path(route):
1227
plt.plot(df["longitude"], df["latitude"], marker="o", linestyle="-", color="blue")
1328

1429
for i, city in enumerate(df.index):
15-
plt.text(df.loc[city, "longitude"], df.loc[city, "latitude"], f"{i+1}. {city}")
30+
plt.text(
31+
df.loc[city, "longitude"], df.loc[city, "latitude"], f"{i + 1}. {city}"
32+
)
1633

1734
plt.xlabel("Longitude")
1835
plt.ylabel("Latitude")
1936
plt.title("TSP Route")
2037
plt.grid(True)
21-
plt.show()
38+
39+
# Save the plot to file
40+
plt.savefig(save_path)
41+
42+
# Only show the plot locally (not in CI)
43+
if not os.environ.get("CI"):
44+
plt.show()
45+
46+
plt.close()

‎Heuristics/tests/test_cli.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
from click.testing import CliRunner
44
from TSP import cli
55

6+
67
def test_simulate_command():
78
runner = CliRunner()
89
# Only use existing --plot option
910
result = runner.invoke(cli, ["simulate", "--plot"])
1011
assert result.exit_code == 0
11-
12-

‎Heuristics/tests/test_coin.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from TSP import greedy_coin_change
22

3+
34
def test_coin_change():
45
assert greedy_coin_change(0.41) == 4

‎Heuristics/tests/test_tsp_dict.py‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ def cities():
3434
}
3535

3636

37-
38-
39-
4037
def test_tsp_dict():
4138
cities = {
4239
"A": {"A": 0, "B": 1, "C": 2},

‎Heuristics/tests/test_tsp_pandas.py‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,3 @@ def test_tsp_pandas(cities):
1616
assert distance > 0
1717
assert isinstance(route, list)
1818
assert len(route) == len(cities)
19-
20-
21-

‎Heuristics/tsp_route.png‎

44.5 KB
Loading

0 commit comments

Comments
 (0)