argparser: add argparser and nice print

This commit is contained in:
Marco Thomas
2022-07-28 11:10:37 +02:00
parent d29c08a411
commit 15b156a7c6
5 changed files with 94 additions and 35 deletions

30
args.py Normal file
View File

@@ -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

View File

@@ -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])

View File

@@ -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

16
main.py
View File

@@ -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__":

View File

@@ -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])