@noisefloor: Bei den Ausnahmen hätte ich eine Klassenhierarchie erstellt. Mindestens mal eine Basisklasse von der alle anderen abgleitet werden, damit man nicht gezwungen ist wirklich alle in einem ``except`` aufzuführen wenn man nur daran interessiert ist grundsätzlich zu wissen ob es fehlgeschlagen ist.
Du machst alles möglich an Zeichen konfigurierbar, nur nicht den kurzen und den langen Pieps selbst.
Die Schleife am Ende der `__init__()` würde auf Klassenebene nur einmal ausgeführt werden und nicht bei jedem Erstellen eines `Morse`-Exemplars.
Die ``print``\s hätte ich in der Tat über Logging gelöst, dann kann man sie abschalten.
``else: pass``?
Wenn man bei verknüpften Bedingungen ein bisschen auf die Reihenfolge achtet kann man ab und zu Rechenzeit sparen. Also zum Beispiel erst prüfen ob man im `strict_mode` ist und dann erst die Daten untersuchen. Und das ganze auch so anordnen, dass man nicht mehrfach das gleiche ausrechnen muss und/oder in ``elif``-Zweigen teilweise die gleiche Bedingung stehen hat wie im Test für den Zweig davor. Beispiel:
Code: Alles auswählen
if not test(data) and strict_mode:
error()
elif not test(data) and not strict_mode:
warning()
#
# Besser:
#
if not test(data):
if strict_mode:
error()
else:
warning()
Ist von den Bedingungen her IMHO auch einfacher verständlich ausgedrückt.
Statt den `KeyError` abzufangen hätte man anstelle des []-Zugriffs auch die `get()`-Methode verwenden können.
In `is_valid_morse_code()` könnte man `all()` und einen Generatorausdruck verwenden.
Der Rückgabewert von `is_valid_input_text()` ist unnötig kompliziert. Es würde reichen einfach die gefundenen ungültigen Zeichen zurück zu geben. Der Wahrheitswert ergibt sich daraus ja automatisch ist also redundant. Ein `set()` wäre hier vielleicht besser als eine Liste.