Seite 1 von 1

Anfänger braucht Hilfe ( 'str' and 'int' )

Verfasst: Mittwoch 26. November 2008, 18:46
von digted
Hallo,
ich hab gestern angefangen mich mit Python zu beschäftigt. Ich bin nun auf ein Problem mit raw input und input gestoßen . Mit input läuft mein Programm, mit raw_input nicht. In eurem Wiki bin ich auch auf den Artikel gestoßen, dass input einige Schwäche hat und diese wollte ich mir nicht aneignen. So wie löse ich nun mein Problem.

Code: Alles auswählen

fahrenheit = raw_input ("Wieviel Fahrenheit?")
print "Du hast %s angegeben" %fahrenheit ## nur zum testen
ergebnis =(fahrenheit-32)*-9 
print "Die Temperatur in Celsius lautet %d" %ergebnis
Fehlermeldung lautet :
File "E:\Python\temperatur.py", line 11, in <module>
ergebnis = int(fahrenheit-32)*-9
TypeError: unsupported operand type(s) for -: 'str' and 'int'

Wenn ich das richtig verstanden habe, ist meine Variable "ergebnis" ein String? Wieso kann ich dann nicht in Zeile 4 %d durch %s ersetzen?

Verfasst: Mittwoch 26. November 2008, 18:52
von derdon
gibt zwei Möglichkeiten:
1.

Code: Alles auswählen

fahrenheit = int(raw_input ("Wieviel Fahrenheit?"))
2.

Code: Alles auswählen

ergebnis =(int(fahrenheit)-32)*-9

Re: Anfänger brauch Hilfe ( 'str' and 'int' )

Verfasst: Mittwoch 26. November 2008, 19:04
von numerix
digted hat geschrieben:Wenn ich das richtig verstanden habe, ist meine Variable "ergebnis" ein String? Wieso kann ich dann nicht in Zeile 4 %d durch %s ersetzen?
Kannst du machen - allerdings musst du Zeile 3 streichen ... :D

Im Ernst: Zeile 4 ist nicht das Problem, sondern Zeile 3, weil man eben mit Zeichenketten nicht rechnen kann. Also musst du eine Typumwandlung vornehmen und die Zeichenkette in eine Zahl umwandeln. Mögliche Lösungen wurden ja schon gepostet.

Edit: Im übrigen ist deine Umrechnungsformel falsch ... :wink:

Verfasst: Mittwoch 26. November 2008, 19:38
von digted
Hmm, ist mir auch schon aufgefallen. Ich bin einfach mal davon ausgegangn, dass man Unterlagen von Universitäten vertrauen kann :). Egal es ging ja um das Prinzip. Vielen Dank !

Verfasst: Donnerstag 27. November 2008, 15:45
von pcos
digted hat geschrieben:Ich bin einfach mal davon ausgegangn, dass man Unterlagen von Universitäten vertrauen kann :).
Falls in den Unterlagen input verwendet wird, ist das auch OK; input hat die Typumwandlung "eingebaut", genauer:

Code: Alles auswählen

>>> help(input)
Help on built-in function input in module __builtin__:

input(...)
    input([prompt]) -> value
    
    Equivalent to eval(raw_input(prompt)).
Wenn die eingeg. Zeichenkette nur Ziffern enthält, macht input mittels eval daraus einen Integer. Das Problem mit eval ist aber eben, dass beliebiger Code ausgeführt wird; gibt jemand in Deinem Beispiel keinen Fahrenheit-Wert, sondern einen Befehl zum Formatieren der Festplatte ein, dann hat man möglicherweise ein Problem. Bei der Umwandlung mit int() kann das nicht passieren.

Verfasst: Donnerstag 27. November 2008, 15:59
von DasIch
pcos hat geschrieben:Das Problem mit eval ist aber eben, dass beliebiger Code ausgeführt wird;
Ahja?

Code: Alles auswählen

In [28]: eval("import os; os.remove('/')")
------------------------------------------------------------
   File "<string>", line 1
     import os; os.remove('/')
          ^
SyntaxError: invalid syntax
Es ist schon etwas schwerer da Mist zu bauen. Allerdings hast du prinzipiell recht man ist halt nur auf expressions beschränkt.

Verfasst: Donnerstag 27. November 2008, 16:06
von digted
Vielen Dank, das werd ich doch gleich mal testen, klingt interessant. :twisted:

Verfasst: Donnerstag 27. November 2008, 16:10
von numerix
pcos hat geschrieben:
digted hat geschrieben:Ich bin einfach mal davon ausgegangn, dass man Unterlagen von Universitäten vertrauen kann :).
Falls in den Unterlagen input verwendet wird, ist das auch OK; input hat die Typumwandlung "eingebaut", genauer: [....]
Eigentlich ging es dabei nicht um (raw)input und die Typumwandlung, sondern um die (nicht gegebene) mathematische Richtigkeit der Umrechnungsformel "Fahrenheit -> Grad Celsius". :wink:

Verfasst: Donnerstag 27. November 2008, 17:45
von lunar
DasIch hat geschrieben:Es ist schon etwas schwerer da Mist zu bauen. Allerdings hast du prinzipiell recht man ist halt nur auf expressions beschränkt.
"__import__()" existiert.

Verfasst: Donnerstag 27. November 2008, 18:16
von numerix
lunar hat geschrieben:
DasIch hat geschrieben:Es ist schon etwas schwerer da Mist zu bauen. Allerdings hast du prinzipiell recht man ist halt nur auf expressions beschränkt.
"__import__()" existiert.
Sicher. Ich denke, DasIch wollte damit auch nicht sagen, dass es kompliziert oder aufwändig ist, so etwas zu realisieren, sondern dass es - gerade für Anfänger - nicht mal so einfach gemacht ist.

Man findet in diesem Forum schon den ein oder anderen Thread zum Thema "böses input()", wo gerne die Gefährlichkeit mit Beispielen belegt wird, die gar nicht funktionieren (weil es keine Ausdrücke sind). Das zeigt zumindest, dass es schwieriger ist, ein "funktionierendes" Beispiel anzugeben als auf die Gefährlichkeit von input() hinzuweisen ... :wink:

Verfasst: Donnerstag 27. November 2008, 18:27
von Leonidas
numerix hat geschrieben:Man findet in diesem Forum schon den ein oder anderen Thread zum Thema "böses input()", wo gerne die Gefährlichkeit mit Beispielen belegt wird, die gar nicht funktionieren (weil es keine Ausdrücke sind). Das zeigt zumindest, dass es schwieriger ist, ein "funktionierendes" Beispiel anzugeben als auf die Gefährlichkeit von input() hinzuweisen ... :wink:
Schwieriger ja, marginal. Weiterhin bleibt aber das Problem dass bei ``input()`` wild Strings oder Integer herauskommen, je nachdem was der User eintippt und das zwar akteptiert wird, aber oft an einer anderen Stelle im Programm dann auf die Nase fliegt ohne das man so einfach weiß warum. Ein Programm sollte bei Problemen so früh wie möglich scheitern und dann gegenmaßnahmen ergreifen, statt mit inkorrekten Daten dann irgendwielang weiterrechnen. Sonst hat man die Situation Garbage in -> Garbage out und das ist dann blöd wenn man erwartet dass der Output korrekt ist und nicht gegenprüft.

Verfasst: Donnerstag 27. November 2008, 18:34
von lunar
Man muss ja nicht alle Feinheiten kennen, um davor warnen zu dürfen. Die Sicherheit ist doch bei den meisten hier geposteten Programmen eh nachrangig, weil sie meist Works-for-me-and-friends-only-Lösungen sind, die kaum je ein anderer sieht.

Schwerwiegender sind doch logische Fehler oder seltsame Ausnahmen wegen Tippfehlern in der Eingabe, da die jedes Programm betreffen.

Im Übrigen funktioniert ja auch "os.remove('/')" nicht, weil diese Funktion nur auf Dateien operiert.

Verfasst: Donnerstag 27. November 2008, 18:34
von pcos
DasIch hat geschrieben: Ahja?

Code: Alles auswählen

In [28]: eval("import os; os.remove('/')")
------------------------------------------------------------
   File "<string>", line 1
     import os; os.remove('/')
          ^
SyntaxError: invalid syntax
Es ist schon etwas schwerer da Mist zu bauen. Allerdings hast du prinzipiell recht man ist halt nur auf expressions beschränkt.
Natürlich kann man mit eval auch Statements ausführen, auch wenn nichts vorher importiert wurde:

Code: Alles auswählen

>eval("""file('D://foo.py','w').write('print "Ich bin ein print-Statement."\\nimport os\\nprint "Gerade hat jemand",os,"importiert."') or execfile('D://foo.py')""")
liefert

Code: Alles auswählen

Ich bin ein print-Statement.
Gerade hat jemand <module 'os' from 'D:\Python25\lib\os.pyc'> importiert.
:wink:

Liebe Kinder, macht das bitte nicht zu Hause nach.

Verfasst: Donnerstag 27. November 2008, 19:11
von numerix
lunar hat geschrieben:Die Sicherheit ist doch bei den meisten hier geposteten Programmen eh nachrangig, weil sie meist Works-for-me-and-friends-only-Lösungen sind, die kaum je ein anderer sieht.
Das ist wohl war und wird bei den leidigen "böses input()"-Diskussionen viel zu wenig bedacht.

Verfasst: Donnerstag 27. November 2008, 19:20
von lunar
Ob es aber nun Sicherheitslücken sind oder "nur" logische Fehler: input() ist und bleibt (zumindest bist P3k) ein ungeeignetes Werkzeug für die Eingabe.

os.remove vs. shutil.rmtree

Verfasst: Freitag 28. November 2008, 10:34
von farid
lunar hat geschrieben:Im Übrigen funktioniert ja auch "os.remove('/')" nicht, weil diese Funktion nur auf Dateien operiert.
Gut beobachtet. Aber kein echtes Hindernis: es gibt ja shutil.rmtree... :?

Wie heißt es so schön? input is eval, just one letter away from evil.

Verfasst: Freitag 28. November 2008, 11:46
von lunar
Schöner Spruch ;)