@Pandorarain: Das ist reichlich unübersichtlich und schwer zu erweitern. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Keine Variablen und dann auch noch Code des Hauptprogramms und Funktionsdefinitionen vermischt. Du bist da selbst schon ein bisschen durcheinander gekommen, denn wenn man das Hauptprogramm und die Funktionsdefinitionen trennt, sieht man das zwei Trennlinien direkt hintereinander ausgegeben werden, was man leichter sieht wenn dazwischen keine Funktionsdefinition steht, die ja keine Ausgabe zwischen den Trennlinien erzeugt. Warum die Ergebnisse der Funktionen jeweils zweimal direkt hintereinander ausgegeben werden, verstehe ich auch nicht‽
Die Funktionen sollten echte Funktionen sein, das heisst alle Werte (ausser Konstanten) die in Funktionen und Methoden verwendet werden, sollten als Argumente übergeben werden und nicht auf magische Weise irgendwo in der Umgebung existieren. Da verliert man ganz schnell den Überblick von wo auf diese Werte überall zugegriffen wird, also auch was alles betroffen ist wenn man den Wert ändert und welche Funktionen den Wert verändern (könnten).
Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Wenn man das in eine Funktion verschiebt, sieht man auch ganz gut das die Funktionen auf Werte zugreifen auf die sich nicht zugreifen sollten, beziehungsweise muss man sich dann überlegen ob `code_1` und `code_2` Variablen oder Konstanten sein sollen. `input_1` und `res` sind jedenfalls keine Konstanten, die müssen also auf jeden Fall zu Argumenten für die Funktionen werden.
Dann wären wir bei diesen Nummern an den Namen: Gewöhn Dir diesen Unsinn ganz schnell wieder ab. Wenn man Namen nummeriert, macht man in der Regel etwas falsch. Entweder es ist unnötig, oder man hat sich nicht genug Gedanken über einen passenden Namen gemacht, oder man will gar keine einzelnen Namen für die Werte, sondern die Werte in eine Datenstruktur stecken. Oft eine Liste.
Fangen wir mit den Funktionsnamen an: `binarycode_1()` und `colorcode_1()` haben eine überflüssige Nummer und die Namen verraten dem Leser nicht was die Funktionen eigentlich *tun*. Deswegen benennt man Funktionen und Methoden nach ihrer Tätigkeit. Zum Beispiel `convert_binary2color()` und `convert_color2binary()`. Und die bekommen dann jeweils ein Argument, nämlich das was umgewandelt werden soll.
Bei `code_1` und `code_2` möchte man gar keine einzelnen Namen, sondern eine Liste. Dann werden die beiden Funktionen einfacher, und vor allem auch einfacher erweiterbar, denn wenn man dann einen weiteren Code hinzufügen möchte, dann macht man das einfach bei dieser Liste. Man muss dann nicht mehr in jeder Funktion noch einen ``if``-Zweig hinzufügen der fast das gleiche macht wie die anderen.
``return`` ist übrigens keine Funktion und sollte deshalb auch nicht so geschrieben werden als wäre es eine. Um den Wert gehören keine unnötigen Klammern und nach dem Schlüsselwort sollte ein Leerzeichen stehen.
Die Funktionen haben eine leicht komische API. Die geben entweder explizit einen Wert an den Aufrufer zurück, oder sie geben eine Fehlermeldung aus, und nicht explizit etwas zurück. Die Fehlerausgabe gehört dort nicht rein, denn es kann ja sein, dass der aufrufende Code mit dem Fehler umgehen kann und etwas tun kann um das Problem zu lösen — eine andere Umwandlungsfunkion versuchen, einen Defaultwert verwenden, … — und selbst wenn man am Ende `None` zurückgeben möchte, sollte man das in dem Fall *explizit* tun, damit der Leser weiss, dass man an diesen Fall gedacht hat, und nicht davon ausgeht, dass der Code davor 100% irgendwo bei einem ``return`` landet.
Dein Code behandelt den Fehler/die Fehleingabe auch gar nicht. Wenn bei der ersten Funktion nichts gefunden wird, dann braucht man die zweite doch eigentlich gar nicht erst aufrufen, denn da ist dann ja schon klar, dass es auch dort zu einem Fehler kommen wird.
Man kann statt eines speziellen Fehlerwertes auch überlegen eine Ausnahme auszulösen.
Jetzt brauche `input_1`, `res`, und `res_2` noch Namen an denen man ablesen kann was die Bedeutung dieser Werte ist. Dann lande ich ungefähr bei dem hier:
Code: Alles auswählen
CODES = [['000000', 'gggb', '0001'], ['000001', 'gggr', '0002']]
def print_line():
print('=' * 44)
def convert_binary2color(value):
for binary, color, _ in CODES:
if value == binary:
return color
return None # TODO Maybe use an exception instead of an error value.
def convert_color2binary(value):
for binary, color, _ in CODES:
if value == color:
return binary
return None # TODO Maybe use an exception instead of an error value.
def main():
binary_code_from_user = input(
'Hier einen 6-stelligen Binaercode eingeben:\n'
'(000000 oder 000001):\n'
)
print_line()
color_value = convert_binary2color(binary_code_from_user)
if color_value is None:
print('Fehler_1')
else:
print(color_value)
print_line()
binary_code = convert_color2binary(color_value)
print('Fehler_2' if binary_code is None else binary_code)
assert binary_code == binary_code_from_user
print_line()
print('END')
print_line()
if __name__ == '__main__':
main()
Zur Modulfrage: Das geht mit dem `x` genau so wie mit `say_hello`. Beides sind Werte in dem Modul die man importieren kann, oder man importiert das Modul und greift auf die Werte als Attribute auf dem Modulobjekt zu.
Der erste ``import modul`` ist überflüssig.