diff --git a/args.py b/args.py new file mode 100644 index 0000000..1f80b2e --- /dev/null +++ b/args.py @@ -0,0 +1,30 @@ +""" +Parse commandline arguments and provide global variables for settings. +""" + +import argparse + + +class Settings(): + file = None + sort = "time" + debug = False + + def __init__(self): + parser = argparse.ArgumentParser(description='IHK Dijkstra Projekt.') + parser.add_argument('file', help='The input file.') + parser.add_argument( + '-sort', + default='time', + help='Whether to sort after "time" or "co2"') + parser.add_argument( + '-debug', + action='store_true', + help='Show debug output.') + args = parser.parse_args() + assert(args.sort == "time" or args.sort == "co2") + + # update default values + self.file = args.file + self.debug = args.debug + self.sort = args.sort diff --git a/dijsktra.py b/dijsktra.py index 206d6ad..7b264b5 100644 --- a/dijsktra.py +++ b/dijsktra.py @@ -2,6 +2,9 @@ This module holds the logic for the solving """ +from args import Settings +from parser import DataSet + class Dijkstra(): def __init__(self, graph: dict, connection: tuple): @@ -17,13 +20,13 @@ class Dijkstra(): "prev": None}}) self.table[connection[0]]["distance"] = (0, 0) - def algorithm(self, switch: str): - assert(switch == "time" or switch == "co2") - - print("Performing Dijkstra on the following graph...") + def algorithm(self, settings: Settings): + if settings.debug: + print("Performing Dijkstra on the following graph...") for vertex in self.graph: - print(f"{vertex}: {self.graph[vertex]}") - print("") + if settings.debug: + print(f"{vertex}: {self.graph[vertex]}") + print("") for v1 in self.graph.keys(): neighbors = self.graph[v1] @@ -35,18 +38,19 @@ class Dijkstra(): time = self.table[v1]["distance"][0] + edge[0] co2 = self.table[v1]["distance"][1] + edge[1] # but only eval the one we want - if switch == "time": + if settings.sort == "time": if time < self.table[key]["distance"][0]: self.table[key]["distance"] = (time, co2) self.table[key]["prev"] = v1 - elif switch == "co2": + elif settings.sort == "co2": if co2 < self.table[key]["distance"][1]: self.table[key]["distance"] = (time, co2) self.table[key]["prev"] = v1 - print("Final Dijkstra table:", self.table) + if settings.debug: + print("Final Dijkstra table:", self.table) - def print_result(self, connection: tuple): + def print_result(self, connection: tuple, dataset: DataSet): sequence = [] (start, dest) = connection # start at destination @@ -57,8 +61,19 @@ class Dijkstra(): current = self.table[sequence[-1]] # last element of list prev = current["prev"] sequence.append(prev) - sequence.reverse() - print(sequence) + + connection = dataset.connection + frm = dataset.locations[connection[0]] + to = dataset.locations[connection[1]] + print(f"{frm.name}-->{to.name}") + print("----") + print(f"Lufstrecke: {frm.distance(to)}") + total = "" + for loc in sequence: + total += f"{dataset.locations[loc].name}-->" + # remove last arrow again + total = total[0:-3] + print(total) print("Total Time:", self.table[dest]["distance"][0]) print("Total CO2:", self.table[dest]["distance"][1]) diff --git a/graph.py b/graph.py index 2577574..fc03c4c 100644 --- a/graph.py +++ b/graph.py @@ -3,6 +3,7 @@ Module, which creates a graph """ from classes import DataSet, LocationType, TransportMethod, TransportKind +from args import Settings def calc_co2(distance: float, kind: TransportKind) -> float: @@ -68,14 +69,15 @@ def calc_time( return waittime + (distance / TransportMethod.AIRPLANE.value.speed) -def create_graph(dataset: DataSet) -> dict: +def create_graph(dataset: DataSet, settings: Settings) -> dict: """ Creates the initial graph, with all edges """ locations = dataset.locations graph: dict = {} - print("Creating graph...") + if settings.debug: + print("Creating graph...") # add nodes with no edges for start in locations: @@ -87,7 +89,8 @@ def create_graph(dataset: DataSet) -> dict: # skip, if we wouldnt go anywhere if start == dest: continue - print(f"Searching for nodes from {start} to {dest}...") + if settings.debug: + print(f"Searching for nodes from {start} to {dest}...") distance = locations[start].distance(locations[dest]) # Individualtransport @@ -100,7 +103,8 @@ def create_graph(dataset: DataSet) -> dict: "co2": co2, "time": time}} graph[start].append(new_connection) - print(f"Added new INDIVIDUAL connection from {start} to {dest}") + if settings.debug: + print(f"Added new INDIVIDUAL connection from {start} to {dest}") # Train is_haltestelle = locations[start].type == LocationType.HALTESTELLE @@ -121,10 +125,12 @@ def create_graph(dataset: DataSet) -> dict: "co2": co2, "time": time}} graph[start].append(new_connection) - print(f"Added new TRAIN connection from {start} to {dest}") + if settings.debug: + print(f"Added new TRAIN connection from {start} to {dest}") # Flying - print("Adding flights...") + if settings.debug: + print("Adding flights...") flights = dataset.flights for flight in flights: start = flight @@ -138,6 +144,7 @@ def create_graph(dataset: DataSet) -> dict: "co2": co2, "time": time}} graph[start].append(new_connection) - print(f"Added new FLYING connection from {start} to {dest}") + if settings.debug: + print(f"Added new FLYING connection from {start} to {dest}") return graph diff --git a/main.py b/main.py index 1a2446a..714533c 100644 --- a/main.py +++ b/main.py @@ -6,20 +6,20 @@ Requires: python > 3.10.x from parser import parse from graph import create_graph from dijsktra import Dijkstra - - -INPUTFILE = "file.txt" +from args import Settings def main(): + # parse args + settings = Settings() # parse inputfile - dataset: dict = parse(INPUTFILE) + dataset: dict = parse(settings) # create graph - graph: dict = create_graph(dataset) + graph: dict = create_graph(dataset, settings) # solve - dijkstra = Dijkstra(graph, dataset.connection) - dijkstra.algorithm("co2") - dijkstra.print_result(dataset.connection) + dijkstra: Dijkstra = Dijkstra(graph, dataset.connection) + dijkstra.algorithm(settings) + dijkstra.print_result(dataset.connection, dataset) if __name__ == "__main__": diff --git a/parser.py b/parser.py index b75c72c..c3e4d6e 100644 --- a/parser.py +++ b/parser.py @@ -3,9 +3,10 @@ Parse the input file """ from classes import ParsingMode, Coordinate, LocationType, Location, DataSet +from args import Settings -def parse(filename: str) -> DataSet: +def parse(settings: Settings) -> DataSet: """ Parse a given file with given format and return a DataSet containing the parsed locations, flightschedules and wanted connection @@ -13,7 +14,7 @@ def parse(filename: str) -> DataSet: locations: dict = {} flights: dict = {} connection: tuple = () - with open(filename, "r") as file: + with open(settings.file, "r") as file: for line in file.readlines(): line = line.replace("\n", "") # strip newline line = line.replace(" ", "") # strip whitespaces @@ -25,21 +26,25 @@ def parse(filename: str) -> DataSet: # meta parsing match line: case "Locations:": - print("Parsing `Locations`...") + if settings.debug: + print("Parsing `Locations`...") current_parsing = ParsingMode.LOCATIONS continue case "FlightSchedule:": - print("Parsing `FlightSchedule`...") + if settings.debug: + print("Parsing `FlightSchedule`...") current_parsing = ParsingMode.FLIGHTSCHEDULE continue case "FindBestConnections:": - print("Parsing `FindBestConnections`...") + if settings.debug: + print("Parsing `FindBestConnections`...") current_parsing = ParsingMode.FINDCONNECTION continue match current_parsing: case ParsingMode.LOCATIONS: - print("Parsing location...") + if settings.debug: + print("Parsing location...") splitted = line.split(";") assert(len(splitted) == 6) # make sure we have a location id = splitted[0] @@ -59,7 +64,8 @@ def parse(filename: str) -> DataSet: location = Location(coord, continent, name, type) locations.update({id: location}) case ParsingMode.FLIGHTSCHEDULE: - print("Parsing flight schedule...") + if settings.debug: + print("Parsing flight schedule...") splitted = line.split(";") assert(len(splitted) >= 2) id1 = splitted[0] @@ -78,7 +84,8 @@ def parse(filename: str) -> DataSet: "domestic": domestic}}) continue case ParsingMode.FINDCONNECTION: - print("Parsing connection...") + if settings.debug: + print("Parsing connection...") splitted = line.split(";") assert(len(splitted) == 2) connection = (splitted[0], splitted[1])