Hilfe bei kleinem Einheitenumrechenprogramm

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
Argoth
User
Beiträge: 8
Registriert: Freitag 20. Februar 2009, 21:21

Hallo liebe Leute!
Ich bin blutiger Pythonanfänger und wollte übungshalber einen extrem primitiven Einheitenumrechner schreiben. Erst mal soll es nur um die Berechnung einer Wellenlänge in Nanometer aus Elektronenvolt und umgekehrt gehen.
leider hab ich beim coden wohl nen Denkfehler, denn ich bekomme das Programm einfach nicht zum laufen. Die erste Abfrage klappt und danach wars das, das Programm hängt in der Schleife. Ich hab den ausführlich kommentierten Quelltext mal bei nopaste hinterlegt: http://nopaste.info/c921e51fff.html


Hat jemand ne Anregung wo ich den Fehler suchen muss?
Vielen Dank!
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Ueberlege dir mal, von welchem Datentyp choice in jeder Zeile ist, und womit du es in der while-Bedingung vergleichst!

Tipp:

Code: Alles auswählen

>>> 1 == "1"
False
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
BlackJack

@Argoth: Die Schleife wird *immer* betreten weil `choice` an der Stelle nie 1 oder 2 sein kann und "hängt" halt solange bis man 1 oder 2 eingibt. Was bei Python 2.x geht, bei Python 3.x aber auch wieder nie der Fall sein wird. Kleiner Tipp:

Code: Alles auswählen

In [126]: 1 == '1'
Out[126]: False

In [127]: 2 == '2'
Out[127]: False
Ansonsten solltest Du Funktionen auch wirklich wie Funktionen benutzen und nicht nur als Namen für Code der "angesprungen" werden soll. Funktionen bekommen Werte als Argumente übergeben und sollten sie sich nicht einfach so aus dem umgebenden Modulnamensraum holen. Das ist für Konstanten okay, aber nicht für Benutzereingaben.

Und dann musst Du mit den Rückgabewerten natürlich auch etwas machen.
Argoth
User
Beiträge: 8
Registriert: Freitag 20. Februar 2009, 21:21

BlackJack hat geschrieben:@Argoth: Die Schleife wird *immer* betreten weil `choice` an der Stelle nie 1 oder 2 sein kann und "hängt" halt solange bis man 1 oder 2 eingibt. Was bei Python 2.x geht, bei Python 3.x aber auch wieder nie der Fall sein wird. Kleiner Tipp:

Code: Alles auswählen

In [126]: 1 == '1'
Out[126]: False

In [127]: 2 == '2'
Out[127]: False
Ansonsten solltest Du Funktionen auch wirklich wie Funktionen benutzen und nicht nur als Namen für Code der "angesprungen" werden soll. Funktionen bekommen Werte als Argumente übergeben und sollten sie sich nicht einfach so aus dem umgebenden Modulnamensraum holen. Das ist für Konstanten okay, aber nicht für Benutzereingaben.

Und dann musst Du mit den Rückgabewerten natürlich auch etwas machen.
Vielen Dank, das waren echt paar dämliche Sachen. Die integer/string Geschichte dummerweise ein Tipfehler. Es läuft jetzt und gibt auch richtige Werte aus. Die Funktionen hab ich jetzt hoffentlich auch mehr in dem Sinne wofür sie gedacht sind benutzt, aber ich geh mal stark davon aus, dass das noch viel besser und eleganter geht. Hab halt das Gefühl, dass mein weg ziemlich umständlich und für nen richtigen Programmierer zum Haare raufen ist :roll:
Naja, falls es euch interessiert, wie das jetzt aussieht : http://nopaste.info/b20731097e.html
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

So schlimm sieht es doch gar nicht aus. :)

Zeile 20-23 kannst du dir sparen und durch "choice = None" ersetzen, so gehst du beim ersten Durchlauf auf jeden Fall in die Schleife.

Zeile 33 und 37 sind ueberfluessig.

Variablennamen waehlt man normalerweise klein_mit_unterstrichen, und nicht mit binnenGrossSchreibung: Pep 008.

Die Dokumentation der Funktionen kannst du gleich als richtige Docstrings machen statt als Inline-Kommentare:

Code: Alles auswählen

def bla():
    """gibt bla aus"""
    print("bla")
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Argoth
User
Beiträge: 8
Registriert: Freitag 20. Februar 2009, 21:21

Rebecca hat geschrieben:So schlimm sieht es doch gar nicht aus. :)

Zeile 20-23 kannst du dir sparen und durch "choice = None" ersetzen, so gehst du beim ersten Durchlauf auf jeden Fall in die Schleife.

Zeile 33 und 37 sind ueberfluessig.

Variablennamen waehlt man normalerweise klein_mit_unterstrichen, und nicht mit binnenGrossSchreibung: Pep 008.

Die Dokumentation der Funktionen kannst du gleich als richtige Docstrings machen statt als Inline-Kommentare:

Code: Alles auswählen

def bla():
    """gibt bla aus"""
    print("bla")
Vielen Dank für die Tips. Hab den code nach deiner Anleitung bisschen aufgeräumt, sieht doch sehr viel übersichtlicher und strukturierter aus (und nen bug hats auch noch behoben :) ). Auch sehr hilfreich der Artikel mit den Konventionen, werd ich mir mal zu Gemüte führen und beherzigen!
Bessere Fassung zur Ansicht: http://nopaste.info/416b8277bf.html

PS: super Forum, schnelle, kompetente Antwort und freundliche Leute. Find auch den didaktischen Ansatz die Leute selber drauf kommen zu lassen gut!

Edit: Hab noch nen Check eingebaut, ob die Eingabe überhaupt ein Integer ist. Kann man das so machen?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo!

Deine Prüfung kann man noch besser zusammenfassen. Mache bei deinem Code mal zwei fehlerhafte Eingaben hintereinander.

Code: Alles auswählen

while True:
    choice = input('Please enter 1 for eV to nanometers and 2 for nanometers to eV:')
    try:
        choice = int(source)

        if choice in (1, 2):
            break
    except ValueError:
        pass
Wichtig ist außerdem, dass du kein leeres except verwendest, sondern immer angibst, welche Fehler abgefangen werden sollen. Sonst werden wirklich alle Fehler ignoriert, was sehr leicht zu sehr schwer lösbaren Problemen führt. Du bekommst zum Beispiel keine Fehlermeldungen mehr und wunderst dich nur über seltsame Ergebnisse oder Fehler treten auf einmal an ganz anderen Stellen auf.

Wenn du dir die Zeilen 32 bis 38 anschaust, solltest du noch die ein oder andere Ähnlichkeit entdecken, hier könnte man auch noch zusammenfassen, auch wenn sich das nicht unbedingt lohnt. Vielleicht als Tip: Du kannst auch Funktionen an Namen binden. Außerdem sind Tupel noch ganz hilfreich.

Sebastian
Das Leben ist wie ein Tennisball.
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

die letzte Version hast du wahrscheinlich nicht getestet:

Code: Alles auswählen

Please enter 1 for eV to nanometers and 2 for nanometers to eV:
1
Please enter 1 for eV to nanometers and 2 for nanometers to eV:
1
Please enter your value as x.x:
44.2
Traceback (most recent call last):
  File "unit_umrechner.py", line 34, in <module>
    print(ev_input + ' eV equals ' + str(evtonm(ev_input)) + ' nm\n') 
TypeError: unsupported operand type(s) for +: 'float' and 'str'
die while Schleife musst du noch einmal anschauen. Das try except ist zwar gut für die Umwandlung, aber verwende den spezifischen 'ValueError' statt nur 'except' und gib nur eine Fehlermeldung aus, die 2. Abfrage wird ja durch die while Schlaufe durchgeführt.

Für die Stringformatierung verwende:

Code: Alles auswählen

"{0} nm equals {1} eV".format(nm_input, nmtoev(nm_input))
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Alles ab Zeile 21 kannst du dann noch hinter "if __name__ == '__main__':" verschwinden lassen. Dann wird der Code nur ausgeführt wenn das Skript direkt gestartet wird, aber nicht wenn du es importierst um z.B. die Funktionen in einem anderen Skript zu benutzen.

Grüße
Gerrit
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Man sollte diesen Thread imho ins Allgemeine Forum verschieben - oder habe ich hier die "Idee" überlesen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:oder habe ich hier die "Idee" überlesen?
Na offenbar war die Idee, einen Thread zu starten :) Habs mal verschoben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Leonidas hat geschrieben:
Hyperion hat geschrieben:oder habe ich hier die "Idee" überlesen?
Na offenbar war die Idee, einen Thread zu starten :)
:mrgreen: YMMD!

Dann gehören Antworten wohl ins "Showcase Forum" :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Argoth
User
Beiträge: 8
Registriert: Freitag 20. Februar 2009, 21:21

Nochmal danke für die vielen hilfreichen Ratschläge, hab wieder einiges lernen können :) Hab mir die Dinge mal zu Herzen genommen und das dann auch entsprechend umgesetzt. Ist alles logisch und einleuchtend wenn mans so sieht, aber selber draufkommen ist nochmal ne andere Sache :D. Und Sorry wenn das das falsche Forum war ;)
Antworten