EINSTEIGERFRAGE: Bestimmter Error/ Syntaxproblem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
LucasTrever
User
Beiträge: 5
Registriert: Donnerstag 11. Dezember 2014, 18:12

Einleitung:

Zunächst möchte ich anmerken, dass ich ein totaler Neuling bin, ich habe praktisch erst vor 3 Tagen mit dem programmieren angefangen, auch ist dies mein erster Beitrag im Forum, auch bin ich mir nicht sicher ob ich die foreninterne Suchfunktion richtig genutzt habe also urteilt bitte nicht zu hart ^^.

Mein Problem:

Ich habe grundsätzlich zwei Probleme...

Nr. 1
Wohl das simplere, ein Syntaxproblem (ergo Syntaxerror), hier mein Code, ich versuche ein Umrechnungsprogramm für Temperaturen zu erstellen:

Code: Alles auswählen

if (v1 == v2):
        print(v3 "Grad" e1 "=" v3 "Grad" e2)
Diese Codepassage handelt ab, was passiert wenn Celsius (v1) in Celsius (e1 steht für "Celsius", v1 und v2 steht nur für den Input).

Nr. 2
Nun, ich verstehe den Errorcode leider nicht genau:

"can't multiply sequence by non-int of type 'str'"

Er wird angezeigt wenn der folgende Code ausgeführt wird, der eigentlich Celsius in Fahrenheit umrechnen sollte:

Code: Alles auswählen

if (v1 == "c" and v2 == "f"):
        v4 = v1 * "1,8" + "32"
Im Voraus danke für jede Hilfe,
Lucas
Zuletzt geändert von cofi am Sonntag 14. Dezember 2014, 18:41, insgesamt 1-mal geändert.
Grund: Code in Tags gesetzt
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Sieht ein wenig danach aus, dass du auf gut Glück programmierst.
Beim print Befehl fehlen offensichtlich die Kommata.

v1 ist ein String und keine Ganzzahl weshalb die Vervielfachung des Strings nicht funktioniert.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Nach dem obligatorischen Hinweis, unbedingt das offizielle Python Tutorial, das es auch in in deutsch gibt durchzuarbeiten, hier noch zwei allgemeine Tipps:
  1. Verwende Namen, die Deine Objekte klar bezeichnen. Damit ersparst Du Dir Erklärungen wie "...Celsius (e1 steht für "Celsius", v1 und v2 steht nur für den Input)" die letztlich ja auch wieder kaum zu verstehen sind... ;-)
  2. Setze Deinen Code hier im Forum in Codetags. Damit liest er sich sehr viel einfacher.
In Deinem ersten Beispiel fehlen die Kommata zwischen den einzelnen Objekten. Die Klammern um den Vergleich sind sinnfrei und können weggelassen werden. Es müsste also heißen

Code: Alles auswählen

if v1 == v2:
    print(v3, "Grad", e1, "=", v3, "Grad", e2)
Wobei sich mir überhaupt nicht erschließt, was da eigentlich geschehen soll?

Was möchtest Du in Deinem zweiten Beispiel eigentlich machen? Wenn Du Deine Rechnung einmal in der Pythonkonsole eingibst, kannst Du folgendes sehen:

Code: Alles auswählen

>>> v1 = 'c'
>>> v1 * '1,8'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
>>> v1 * 1.8
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'float'
>>> v1 * 2
'cc'

Code: Alles auswählen

>>> '1,8' + '32'
'1,832'
Wie Du siehst lassen sich Strings miteinander nicht multiplizieren. Was sollte ein String 'c' multipliziert mit einem anderen String '1,8' denn auch ergeben? Strings lassen sich in Python mit Ganzzahlen, allerdings nicht mit Kommazahlen (float) multiplizieren. 2 oder mehr 'c' sind jedem klar, aber was sollen 1.8 'c' denn sein?

Deine Addition '1,8' + '32' provoziert keine Fehlermeldung ist aber wohl auch nicht das Ergebnis, das Du erwartet hast, oder?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
LucasTrever
User
Beiträge: 5
Registriert: Donnerstag 11. Dezember 2014, 18:12

Also erst einmal ein herzliches Danke für den Link zum deutschen Tutorial und auch für die anderen Hinweise...

Auf jeden Fall konnte ich mein erstes Problem sofort lösen, der Fehler war dann doch sehr offensichtlich, das tut mir Leid.

Die Erklärung für mein zweites Problem habe ich leider nicht ganz verstanden, auch scheint der Fehlercode nicht ganz mit meinem einzustimmen, er tritt aber nachdem ich nun ein paar kleine Änderungen vorgenommen habe gar nicht mehr auf... Nun hier einmal den ganzen Code (der Fehlercode trat früher auf, wenn man Celsius in Fahrenheit umrechnen wollte, etwas anderes ist bisher noch nicht möglich. Auch möchte ich den Leser vorwarnen, es ist wahrscheinlich Tonnenweise unnötiger Text vorhanden, darum danke ich jedem um so mehr, der sich das nun antut :wink:):

Code: Alles auswählen

def opop():

    op()

def op():

    print("+------------------------------------------+")
    print("|Dies ist ein Temperaturumrechner. Welche  |")
    print("|Temperaturen möchten Sie umrechnen?       |")
    print("|                                          |")
    print("|Celsius: C                                |")
    print("|Fahrenheit: F                             |")
    print("|Kelvin: K                                 |")
    print("+------------------------------------------+")

    v1 = input ("Bekannte Einheit: ")
    v2 = input ("Gesuchte Einheit: ")
    v3 = input ("Wert bekannter Einheit: ")

    if (v1 == "c"):
        e1 = "Celsius"

    if (v1 == "f"):
        e1 = "Fahrenheit"

    if (v1 == "k"):
        e1 = "Kelvin"
        
    if (v2 == "c"):
        e2 = "Celsius"

    if (v2 == "f"):
        e2 = "Fahrenheit"

    if (v2 == "k"):
        e2 = "Kelvin"

    if (v1 != "c" and v1 != "f" and v1 != "k" and v2 != "c" and v2 != "f" and v2 != "k"):
        print("")
        print("Die beiden Zeichen ", v1, " und ", v2, " sind dem Programm")
        print("nicht bekannt, bitte versuchen Sie es erneut.")
        print("")
        
    elif (v1 == v2 and (v1 != "c" and v1 != "f" and v1 != "k")):
        print("")
        print("Das Zeichen ", v1, " ist dem Programm nicht")
        print("bekannt, bitte versuchen Sie es erneut.")
        print("")
        
    elif (v1 != "c" and v1 != "f" and v1 != "k"):
        print("")
        print("Das Zeichen ", v1, " ist dem Programm nicht")
        print("bekannt, bitte versuchen Sie es erneut.")
        print("")

    elif (v2 != "c" and v2 != "f" and v2 != "k"):
        print("")
        print("Das Zeichen ", v2, " ist dem Programm nicht")
        print("bekannt, bitte versuchen Sie es erneut.")
        print("")
        
    elif (v1 == v2):
        print("")
        print(v3, "Grad", e1, "=", v3, "Grad", e2)
        print("")
        
    v1 = 1

    if (v1 == "c" and v2 == "f"):
        v4 = 1 * "1,8" + "32"
        print("")
        print(v3, "Grad", e1, "=", v4, "Grad", e2)
        print("")
        
    opop()

opop()
BlackJack

@LucasTrever: Das mit den Namen ist *wichtig*. Die sollten so gewählt sein das der Leser die Bedeutung des Wertes dahinter versteht, was bei `op()`, `opop()`, `v1`, `v2`, `v3`, `v4`, `e1`, `e2` & Co nicht der Fall ist.

Die Klammern um die Bedingungen sind wirklich komplett unnötig. Die gehören da nicht hin. Du klammerst ja an anderen Stellen nicht unnötig herum, warum ausgerechnet dort?

In der Praxis würde man das nicht mit so vielen ``if``-Abfragen lösen sondern Wörterbücher (Datentyp `dict`) verwenden um Kürzel auf ausgeschriebene Einheit und Paar von Kürzeln auf Umrechnungsfaktoren abzubilden.

Der rekursive Aufruf der Funktion um eine Wiederholung zu erreichen ist in Python, wie in allen Sprachen die Endrekursion nicht erkennen und wegoptimieren, keine gute Idee. Das Programm wird damit irgendwann das Rekursionslimit erreichen und mit einer Ausnahme abbrechen. Das würde ich als fehlerhaft bezeichnen. Schreibe Funktionen immer so das die etwas tun und dann zum Aufrufer *zurückkehren*. Rekursion sollte man nur für tatsächlich rekursive Probleme vorbehalten und nicht als Ersatz für einfache Schleifen.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@LucasTrever: Schau Dir dringend Datentypen an. Ein String ist keine Zahl. Damit kann man nicht rechnen. Das wollte Dir auch schon mutetella zeigen. Dass es keinen "Fehler" mehr gibt, liegt nur daran, dass Du v1 durch 1 ersetzt hast.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du solltest in Deinen Programmen immer darauf achten, Dich nicht zu wiederholen. Dies ist das erste Prinzip der Programmierung, welches Du zur Kenntniss nehmen solltest: DRY :!:

Wann immer Du über eine Stelle stoplerst, an der Du Quellcode kopierst, nur wenige Dinge daran änderst (wie z.B. Text eines String-Literals oder eine Variable gegen eine andere tauschst), solltest Du prüfen, ob man den Code nicht *allgemein* in einer Funktion (ggf. später auch Klasse o.ä.) vereinheitlichen kann.

Code: Alles auswählen

     print("")
        print("Das Zeichen ", v1, " ist dem Programm nicht")
        print("bekannt, bitte versuchen Sie es erneut.")
        print("")
Das steht so oder so ähnlich drei bis viermal in Deinem Programm. Stell Dir vor, Du willst den Text ein wenig ändern: An wievielen Stellen müsstest Du das tun? ;-)

Von solchen Prinzipien gibt es übrigens jede Menge... manche sind für alle Sprachen allgemein gültig, andere betreffen nur ausgewählte Sprachen und wieder manche gelten nur in einer speziellen Sprache. Im Laufe der Zeit werden Dir noch viele weitere begegnen, aber DRY sollte man von Anfang an beachten und danach streben, es einzuhalten. (Eigentlich immer wenn man Code kopiert oder ähnlichen Code immer und immer wieder schreibt, gibt es eine mehr oder weniger offensichtliche Art und Weise, diesen zusammenzufassen. Die Kunst ist es, diese zu erkennen :mrgreen: )

Obige Stelle ist nur ein Fragment in Deinem Programm, welches DRY verletzt. Ich habe diese nur herausgepickt, weil die vermutlich am einfachsten zu lösen ist! Also, ran an die Tasten ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten