from typing import Dict, List, Tuple, Union import matplotlib.pyplot as plt import numpy as np import numpy.typing as npt # Data given by the assignment city_coords: Dict = { "Barcelona": [2.154007, 41.390205], "Belgrade": [20.46, 44.79], "Berlin": [13.40, 52.52], "Brussels": [4.35, 50.85], "Bucharest": [26.10, 44.44], "Budapest": [19.04, 47.50], "Copenhagen": [12.57, 55.68], "Dublin": [-6.27, 53.35], "Hamburg": [9.99, 53.55], "Istanbul": [28.98, 41.02], "Kyiv": [30.52, 50.45], "London": [-0.12, 51.51], "Madrid": [-3.70, 40.42], "Milan": [9.19, 45.46], "Moscow": [37.62, 55.75], "Munich": [11.58, 48.14], "Paris": [2.35, 48.86], "Prague": [14.42, 50.07], "Rome": [12.50, 41.90], "Saint Petersburg": [30.31, 59.94], "Sofia": [23.32, 42.70], "Stockholm": [18.06, 60.33], "Vienna": [16.36, 48.21], "Warsaw": [21.02, 52.24], } def plot_plan(city_order: Union[List[str], npt.NDArray]) -> None: """A function that plots the circuit given by city_order. This function was given in the assignment from 2024. Args: city_order (List[str]): A list of cities in the order to be plotted. Returns: None """ europe_map = plt.imread("map.png") _, ax = plt.subplots(figsize=(10, 10)) ax.imshow( europe_map, extent=[-14.56, 38.43, 37.697 + 0.3, 64.344 + 2.0], aspect="auto" ) # Map (long, lat) to (x, y) for plotting for index in range(len(city_order) - 1): current_city_coords = city_coords[city_order[index]] next_city_coords = city_coords[city_order[index + 1]] x, y = current_city_coords[0], current_city_coords[1] # Plotting a line to the next city next_x, next_y = next_city_coords[0], next_city_coords[1] plt.plot([x, next_x], [y, next_y]) plt.plot(x, y, "ok", markersize=5) plt.text(x, y, str(index), fontsize=12) # Finally, plotting from last to first city first_city_coords = city_coords[city_order[0]] first_x, first_y = first_city_coords[0], first_city_coords[1] plt.plot([next_x, first_x], [next_y, first_y]) # Plotting a marker and index for the final city plt.plot(next_x, next_y, "ok", markersize=5) plt.text(next_x, next_y, str(index + 1), fontsize=12) plt.show() def indexes_to_cities(indexes: npt.NDArray, cities: npt.NDArray) -> npt.NDArray: """Create an array of cities from indeces in a specific order. Args: indexes (npt.NDArray): An array of city indexes. cities (npt.NDArray): An array of cities. Returns: npt.NDArray An array of cities in the same order as given in indexes. """ return np.array([cities[i] for i in indexes]) def read_data(file_path: str) -> Tuple[npt.NDArray, npt.NDArray]: """Read the city data from a file given and return 2 arrays. The data being read should be separated by semicolons, and the first line should be a list of cities while the rest of the file should contain the data. The resulting array for the data should be an NxN matrix. Args: file_path (str): The file path for the file containing the city data. Returns: Tuple[npt.NDArray, npt.NDArray] A tuple containing the list of cities and the data associated with it. """ cities = None data = [] with open(file_path, "r") as f: cities = f.readline().strip().split(";") lines = f.readlines() for line in lines: data.append(list(map(float, line.strip().split(";")))) return (np.array(cities), np.array(data)) if __name__ == "__main__": # A test program to see that the file is read correctly. cities, data = read_data("./european_cities.csv") print(cities) print(data)