Blutiger Anfänger braucht Hilfe.

Code-Stücke können hier veröffentlicht werden.
Antworten
Pandorarain
User
Beiträge: 5
Registriert: Freitag 24. Februar 2017, 16:53

Hallo liebe Python-Freunde

Zu meinem ersten Beitrag habe ich eigentlich nicht viel zu sagen. Ich habe etwa vor einer Woche begonnen mich mit Python zu befassen und auch allgemein mit dem Programmieren. Leider komme ich nur in kleinen Schritten voran und benötige aus diesem Grund Hilfe von den Leuten die etwas Zeit für mich aufbringen können.

Der unten angefügte Code ist nur ein kleines Beispiel aus dem eigentlichen Skript. Ich versuche hier lediglich eine 6-stellige Binärzahl in einen Farb-Code umzuwandeln und dann wieder in eine Binärzahl.

Leider musste ich aber feststellen, dass etwas nicht richtig funktionier.

Wie kann der ausgegebene Wert aus der ersten Funktion in der zweiten Funktion weiterverwendet werden?

Ich hoffe Ihr könnt mir weiterhelfen und evtl. Optimierungsvorschläge unterbreiten.

Zur Darstellung hoffe ich auch auf Kritik. Ich bin Anfänger und lerne noch… :)

Vielen Dank im Voraus.

PS:Leider weiss ich nicht wie ich den Code anständig einfügen kann. Wie geht das genau?
CODE_1 = ["000000", "GGGB", "0002"]

INPUT = input("Hier einen Binaercode eingeben: ")
def COLORCODE():
if INPUT == (CODE_1[0]):
print(CODE_1[1])
else:
print("Fehler_1")

COLORCODE()
#COLORCODE = "GGGB"

def BINARYCODE():
if COLORCODE == (CODE_1[1]):
print(CODE_1[0])
else:
print("Fehler_2")

BINARYCODE()
#BINARYCODE = "000000"
print("END")
Sirius3
User
Beiträge: 17703
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pandorarain: Werte betreten eine Funktion über ihre Argumente, und verlassen sie als Rückgabewerte per ›return‹. Variablennamen werden komplett klein geschrieben. Eingerückt wird immer mit 4 Leerzeichen pro Ebene und Code kann man hier im Forum einfügen, indem man oberhalb des Editierfensters bei »Code auswählen« »Python« auswählt. So ganz wird mit aus dem Code nicht klar, was Du eigentlich erreichen willst.
Pandorarain
User
Beiträge: 5
Registriert: Freitag 24. Februar 2017, 16:53

@Sirius3: Vielen Dank für die schnelle Antwort. Ich werde das Grundkonstrukt nochmals überdenken. Kann es sein dass ich für diese Aufgabe die falsche Funktion gewählt habe? Es soll lediglich eine Binärzahl in eine Farbabfolge umgewandelt werden und wieder zurück. Eigentlich keine Grosse Sache.
Ich versuch es weiter.... :wink:

Hier nochmals der Code im Ursprungszustand.

Ich werde die von dir vorgeschlagenen Änderungen vornehmen.

Vielen Dank nochmals.

Code: Alles auswählen

CODE_1 = ["000000", "GGGB", "0002"]

INPUT = input("Hier einen Binaercode eingeben: ")
def COLORCODE():
	if INPUT == (CODE_1[0]):
		print(CODE_1[1])
	else:
		print("Fehler_1")

COLORCODE()		
#COLORCODE = "GGGB"

def BINARYCODE():
	if COLORCODE == (CODE_1[1]):
		print(CODE_1[0])	
	else:
		print("Fehler_2")
		
BINARYCODE()
#BINARYCODE = "000000"
print("END")
Pandorarain
User
Beiträge: 5
Registriert: Freitag 24. Februar 2017, 16:53

@Sirius3: Vielen Dank für die Hilfe.

Der Programmteil funktioniert soweit ganz gut:

Code:

Code: Alles auswählen

def newLine():
	print("========================================")

code_1 = ["000000", "gggb", "0001"]
code_2 = ["000001", "gggr", "0002"]

input_1 = input("Hier einen 6-stelligen Binaercode eingeben:\n(000000 oder 000001): \n")

def colorcode_1():
	if input_1 == (code_1[0]):
		return(code_1[1])
	elif input_1 == (code_2[0]):
		return(code_2[1])
	else:
		print("Fehler_1")

newLine()		
	
res = colorcode_1()
print(res)
print(res)

newLine()

#colorcode_1 = "gggb"
#colorcode_1 = "gggr"

def binarycode_1():
	if res == (code_1[1]):
		return(code_1[0])
	if res == (code_2[1]):
		return(code_2[0])
	else:
		print("Fehler_2")
		
newLine()

res_2 = binarycode_1()
print(res_2)
print(res_2)


#binarycode_1 = "000000"
#binarycode_1 = "000001"
newLine()
print("END")
newLine()
Hab noch eine Frage, zu Modulen:

Aus einem Modul möchte ich eine Liste importieren und diese als Variable x weiterverwenden.
Jedoch bin ich mir nicht sicher was ich falsch mache oder vergessen habe.
Evtl. kann mich jemand aufklären was ich falsch mache. Ich möchte lediglich x im main ausgeben oder weiterverwenden.
Funktionen importieren und diese weiterverwenden funktioniert einwandfrei.

main:

Code: Alles auswählen

import modul
from modul import say_hallo

z = open("modul.py", "r")
print(z.read())

say_hallo("XXX")

print(x)

modul:

Code: Alles auswählen

x = [1, 2, 3]

def say_hallo(name):
	print("Hallo {}!".format(name))
Vielen Dank im Voraus.

Lg Pandorarain

PS: Bin wiederum offen für Kritik. :)
BlackJack

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