Module und Pakete werden wie Variablennamen oder Funktionen komplett klein geschrieben. Du scheinst eine Klasse pro Modul zu haben. Das macht man in Python nicht, denn so ist der Namespace "Modul" total nutzlos. Die Klassen sind meist so kurz, dass man die meisten davon in ein Modul packen kann.
Nach einem Komma kommt immer ein Leerzeichen, das macht den Code deutlich lesbarer. Benutze keine Abkürzungen, Cmd, Ctrl? Vokale kosten nichts.
Einige Typannotationen sind absolut unsinnig. In Keyspeed z.B. sieht man ja schon am Defaultvalue, oder dass self.speed ein String ist, dass das Strings sein müssen.
Statt langer if-Ketten benutzt man Wörterbücher:
Code: Alles auswählen
import random
SPEED_TYPES = {
'FAST': lambda: 0.01,
'SLOW': lambda: 1,
'MEDIUM': lambda: 0.2,
'HUMAN': 0.15 + random.uniform(-0.15, 0),
}
class Keyspeed:
def __init__(self, speed='FAST'):
self.speed = speed
def get_speed(self):
try:
return SPEED_TYPES[self.speed.upper()]()
except KeyError:
return Time(self.speed).get_time_in_seconds()
eigentlich ist die Klasse gar nicht nötig, weil get_speed auch einfach eine Funktion sein könnte.
Genauso ist Time keine Klasse:
Code: Alles auswählen
import random
SPEED_TYPES = {
'FAST': lambda: 0.01,
'SLOW': lambda: 1,
'MEDIUM': lambda: 0.2,
'HUMAN': 0.15 + random.uniform(-0.15, 0),
}
TIME_UNITS = {
'ms': 0.001,
's': 1,
'm': 60,
'min': 60,
'h': 3600,
}
def str_to_seconds(value):
try:
for unit, scale in TIME_UNITS.items():
if value.endswith(unit):
return int(value[:-len(unit)]) * scale
raise ValueError()
except ValueError:
print(f"Not valid time format {value}! Fallback to notime")
return 0
def get_speed(speed='FAST'):
try:
return SPEED_TYPES[speed.upper()]()
except KeyError:
return str_to_seconds(speed)
In Program: Weder _thread noch os.system sollte man verwenden. Unabhängig vom System solltest Du subprocess.run verwenden und Threads baut man mit threading.
Mit subprocess.Popen brauchst Du gar keinen Thread, weil das externe Programm eh parallel läuft.
In StoryScript hast Du ein Problem mit zu restriktiven Typannotations. filename sollte ein pathlib.Path sein dürfen, was ja im Code kein Problem ist, aber mit Deiner Annotation. sys.exit darf nur im Hauptprogramm vorkommen. Wenn Du an der Stelle keine sinnvolle Fehlerbehandlung durchführen kannst, dann mußt Du die Exception nach oben fallen lassen. script_file darf kein Attribut sein und Dateien öffnet man am besten innerhalb von with, damit sie auch wieder geschlossen werden. YAML-Dateien haben normalerweise UTF8-Encoding, das Du beim öffnen angeben mußt. Da eine Instanz der Klasse ohne parse -Aufruf nicht vollständig ist, sollte parse gleich in __init__ aufgerufen werden. `l` ist der schlechteste Variablennamen, den es gibt, weil man ihn leicht mit 1 verwechseln kann. Benutze aussagekräftige Namen.
Das mit dem Keyspeed verstehe ich nicht. Warum bilden die einen Stack?
In __init__ gibst Du zwar bei weniger als einem Argument eine Fehlermeldung aus, bei mehr als einem werden aber die restlichen Argumente kommentarlos ignoriert. `x` ist ein schlechter Name für eine `section`.