Frage zu einem einfachen Programm / input-Funktion

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
cYtec777
User
Beiträge: 2
Registriert: Sonntag 23. November 2014, 12:08

Hallo Gemeinde,
dies ist mein erster Post in diesem Forum. Ich arbeite gerade ein Beispiel aus einem Python Buch durch, welches ich mir neulich gekauft habe.
Leider scheitere ich gerade an dem folgenden Programm. Beim kompilieren erscheint der folgende Fehler:
Traceback (most recent call last):
File "/Users/Andi/Documents/Programmieren/ZahlenRaten.py", line 12, in <module>
if tipp < geheimnis:
TypeError: unorderable types: str() < int()
Warum ist dies der Fall? Erkennt input denn nicht, das hier eine Zahl eingelesen wird?

Vielen Dank für eure Hilfe.

Code: Alles auswählen

geheimnis = random.randint(1, 99)
tipp = 0
versuche = 0

while tipp != geheimnis and versuche < 6:
      tipp = input("Was rätst du? ")
      if tipp < geheimnis:
            print("Zu niedrig, du Landratte")
      elif tipp > geheimnis:
            print("Zu hoch, du Leichtmatrose")

      versuche = versuche + 1

if tipp == geheimnis:
      print("Ha! Du hast es! Hast mein Geheimnis erraten!")
else:
      print ("Alle Versuche verbraucht! Mehr Gück beim nächsten Mal!")
      print ("Die Geheimzahl war ", geheimnis)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Für ``input()`` (unter Python 3.x) ist jede Eingabe ein String. Da wird nichts von selbst interpretiert. Das muss man schon explizit in seinem Programmcode machen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

cYtec777 hat geschrieben:Ich arbeite gerade ein Beispiel aus einem Python Buch durch, welches ich mir neulich gekauft habe.
Ein Buch das auf Python 2 aufbaut und trotzdem input() statt raw_input() für die Eingabe verwendet ist einfach kaputt.
CasualCoding.org

/me hat geschrieben:Ein Buch das auf Python 2 aufbaut und trotzdem input() statt raw_input() für die Eingabe verwendet ist einfach kaputt.
Ich sehe hier nichts, was auf Python 2 hinweist...?
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

Hallo cYtec777,

dein Problem ist, dass input() eine Variable vom Typ Zeichenkette(String) ausgibt. Diesen vergleichst du dann mit einer Ganzzahl(Integer). Ist zwar in der Ausgabe für das menschliche Auge die gleiche Zahl, allerdings für den Computer zwei verschiedene Werte die er nicht vergleichen kann.

Du musst also deine Variable tipp in eine Ganzzahl(Integer) umwandeln. Dann sollte dein Beispiel funktionieren.

Code: Alles auswählen

tipp = int(input("Was rätst du? "))
Das Buch sollte "Hello World!: Programmieren für Kids und andere Anfänger" heißen und basiert auf Python 2.7.3.
Link zur Vorschau
Der Fehler passiert dem Author bevor er überhaupt die Datentypen erklärt, dass ist natürlich "etwas" unschön.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

CasualCoding.org hat geschrieben:Ich sehe hier nichts, was auf Python 2 hinweist...?
Wenn der gepostete Code derjenige ist, der angeblich laufen soll, dann kann er mit dieser Verwendung von input() nur unter Python 2 überhaupt jemals gelaufen sein.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Der Unterschied bei Python 2 und Python 3 bezüglich input() ist die Art und Weise, wie die Eingabe interpretiert wird. Bei Python 3 erhältst du immer einen String. Bei Python 2 heißt die Funktion mit der identischen Funktionalität noch raw_input. input bei Python 2 hat ein implizites eval eingebaut und wertet somit den eingegebenen Ausdruck aus. Dort wird 3 dann direkt ein Integer-Wert. Strings bekommst du dort nur, wenn du explizit Anführungszeichen mit angibst ("Monty").

Das Problem bei Python 2 ist, dass du via input fast beliebigen Code in die Anwendung schleusen kannst. Das ist eine riesige Sicherheitslücke und die möchte man nicht haben (siehe auch Eval really is dangerous). Diese Gefährlichkeit war auch der Grund dafür, dass man input in der bisherigen Form in Python 3 entfernt hat.

Folgende Vorgehensweise ist daher bei der Umstellung von Python 2 auf Python 3 in diesem Kontext angeraten:
  1. Python 2 verwendet raw_input -> bei Python 3 auf input ändern
  2. Python 2 verwendet input -> Entsetzt die Hände über dem Kopf zusammenschlagen und bei Python 3 eine explizite Typkonvertierung vornehmen.
CasualCoding.org

/me hat geschrieben:Wenn der gepostete Code derjenige ist, der angeblich laufen soll, dann kann er mit dieser Verwendung von input() nur unter Python 2 überhaupt jemals gelaufen sein.
Das tut er aber doch gerade eben nicht. Python beschwert sich, dass der Inhalt der Variablen ein String ist. Ganz normales Python-3-Verhalten.
garreth
User
Beiträge: 41
Registriert: Donnerstag 23. Oktober 2014, 12:04

Na dann sollte man ihm vielleicht sagen, dass er versucht ein für Python 2 geschriebenes Programm auf einem Python 3 Interpreter laufen zu lassen und dass dieser nicht abwärtskompatibel ist.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn das Python 2 sein soll, was sollen dann die Klammern um "print"?
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Selbst das Deppenleerzeichen ist vorhanden.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

CasualCoding.org hat geschrieben:Das tut er aber doch gerade eben nicht. Python beschwert sich, dass der Inhalt der Variablen ein String ist. Ganz normales Python-3-Verhalten.
Exakt. Unter Python 2 läuft es (auch wenn die Klammern beim print zu viel sind) und unter Python 3 eben nicht.
Ene Uran
User
Beiträge: 125
Registriert: Sonntag 17. September 2006, 20:14
Wohnort: Hollywood

Oder Du kannst auch sowas tun:

Code: Alles auswählen

import random

# damit klappt string input() mit Python2 und Python3
try:  input = raw_input
except NameError:  pass

geheimnis = random.randint(1, 99)
tipp = 0
versuche = 0
 
while tipp != geheimnis and versuche < 6:
      tipp = int(input("Was rätst du? "))  # gebrauche int()
      if tipp < geheimnis:
            print("Zu niedrig, du Landratte")
      elif tipp > geheimnis:
            print("Zu hoch, du Leichtmatrose")
 
      versuche = versuche + 1
 
if tipp == geheimnis:
      print("Ha! Du hast es! Hast mein Geheimnis erraten!")
else:
      print ("Alle Versuche verbraucht! Mehr Glück beim nächsten Mal!")
      print ("Die Geheimzahl war ", geheimnis)
 
Python2 hatte ein paar Warzen und Python3 hat die weg gemacht.
Atomkraftwerkaktienbesitzer
BlackJack

Bleibt noch das Problem mit dem ``print`` — insbesondere das Letzte im Skript gibt unter Python 2 nicht das aus was man sich hier gewünscht oder erwartet hätte. Da fehlt also vielleicht noch ein ``from __future__ import print_function`` am Anfang des Moduls.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Explizites int() verwenden benötigt dann aber noch ein try...except für den Fall das keine Zahl eingegeben wurde...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CasualCoding.org

jens hat geschrieben:Explizites int() verwenden benötigt dann aber noch ein try...except für den Fall das keine Zahl eingegeben wurde...
Das finde ich aber gerade schön, dass Python eine so einfache Mögllichkeit bietet. Versuch' mal, unter C++ (ohne Drittanbieter-Bibliotheken) eine robuste Eingabeüberprüfung für die Konsole zu basteln... :K
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

CasualCoding.org hat geschrieben:...
Das finde ich aber gerade schön, dass Python eine so einfache Mögllichkeit bietet. Versuch' mal, unter C++ (ohne Drittanbieter-Bibliotheken) eine robuste Eingabeüberprüfung für die Konsole zu basteln... :K
Für Integers geht das aber noch mit recht überschaubarem Aufwand, solange die Zahlen in die Typen passen. Für größere brauchts dann eine BigNum-Lib, bei Floats würde ich auf Regex + Bereichsprüfung gehen. Das batteries included-Konzept bei Python bringt halt die Konvertierfunktionen und den BigNum-Support gleich mit.
Antworten