[Python3.1]Land/Stadt Abfrage wie über dict/2 Listen

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
Benutzeravatar
katd0m
User
Beiträge: 6
Registriert: Dienstag 11. Januar 2011, 19:17
Wohnort: Hamburg

Moin und einen schönen Abend an euch alle,

habe mich hier gerade frisch registriert in der Hoffnung das ihr mir bei einem Problem helfen könnt...

Zu meinem Problem :

Ich versuche gerade ein Pythonprogramm zu realisieren um das was ich (hoffentlich) bis jetzt aus dem Buch "Python3" gelernt habe nochmal zu vertiefen. Das Programm soll aus einer Datei(txt) jeweils das Land
und die dazugehörige Stadt rauslesen und dann entweder Stadt oder Land auf die Konsole ausgeben, mit der Auforderung das jeweils andere einzutippen(also bei Land dann die Stadt oder andersrum). Das soll aber durch Zufall bestimmt werden....

Nun habe ich mal im Internet geschaut, und gelesen das es mit dict oder auch mit 2 Listen gehen soll.

Kann mir jemand anhand eines Bsp. vllt erklären wie ich die dict oder die listen so erstelle das ein Zufälliger eintrag ausgegeben wird ? Im Buch wird das leider nicht weiter erklärt =( und selber stehe ich da im Moment auf dem Schlauch...

Wäre toll wenn mir da jemand helfen würde =)

Mit freundlichen Grüßen

katd0m
Das Wissen der Menschheit gehört der Welt!
(Zitat: Teddy Chin, Hackers3-StartUp)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Um welches Buch handelt es sich denn?

Du solltest immer die offizielle Doku im Browser offen haben. Dort guck Dir mal das random-Modul an. Darin findest Du viele hilfreiche Funktionen, rund um das Thema Zufall.

Je nach dem, wie Deine Datenstruktur aussieht, könnten shuffle(), randint() oder choice() für Dich interessant sein.

Ich könnte mir das im Ansatz so vorstellen:

Code: Alles auswählen

In [2]: import random

In [9]: data = [
{"stadt": "Berlin", "land": "Deutschland"},
{"stadt": "Paris", "land": "Frankreich"}
]

In [13]: random.shuffle(data)

In [14]: data
Out[14]: 
[{'land': 'Frankreich', 'stadt': 'Paris'},
 {'land': 'Deutschland', 'stadt': 'Berlin'}]

In [17]: random.shuffle(data)

In [18]: data
Out[18]: 
[{'land': 'Deutschland', 'stadt': 'Berlin'},
 {'land': 'Frankreich', 'stadt': 'Paris'}]
Die Sequenz kannst Du nun in einer Schleife durchgehen und die entsprechenden Fragen stellen.

Für die Frage, ob nun Land oder Stadt gegeben sind, kannst Du eine Liste mit den keys erstellen und ebenfalls shuffeln:

Code: Alles auswählen

In [33]: keys = ["stadt", "land"]

In [34]: keys
Out[34]: ['stadt', 'land']

In [35]: random.shuffle(keys)

In [36]: keys
Out[36]: ['land', 'stadt']
Per Konvention kannst Du nun das erste Element als gegeben annehmen und das andere als gesucht.

Code: Alles auswählen

In [37]: given, searchfor = keys

In [38]: given
Out[38]: 'land'

In [39]: searchfor
Out[39]: 'stadt'
Geht natürlich auch über die Indizies (0 oder 1). Praktischer, falls es noch mehr als nur zwei Schlüssel gibt, so kann der Rest so bleiben.

Ich denke damit solltest Du das umsetzen können.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich denke, "random.choice" ist die gesuchte Funktion.

Code: Alles auswählen

# Dies
#with open("data.txt") as f:
#    data = [line.split(",") for line in f]
# Liefert sowas
data = [
    ["Deutschland", "Berlin"],
    ["Österreich", "Wien"],
    ["Russland", "Moskau"],
    ["England", "London"],
]
import random

while True:
    d = random.choice(data)
    i = random.randrange(2)
    print(["Hauptstadt von Land", "Land von Hauptstadt"][i], d[i])
    a = input()
    print("Richtig" if a == d[1 - i] else "Falsch")
Stefan
Benutzeravatar
katd0m
User
Beiträge: 6
Registriert: Dienstag 11. Januar 2011, 19:17
Wohnort: Hamburg

Abend melde mich auch mal wieder ;), sry im moment ist Schule sehr anstregend....

erstmal danke an euch, für die Tipps ;)!
also habe das jetzt alles hingebogen bekommen mit random....
Der Code sieht jetzt so aus :

Code: Alles auswählen

      
while True:
		eingabe=int(input("\n\t\tGeben sie ihre Auswahl an: "))
		if eingabe == 1:
			        e=open("land.txt", "a+")
			d=open("stadt.txt", "a+")
			while True:
				print("\t\tGeben sie die Stadt ein: ")
				d_stadt=str(input("\t\t>"))
				
				if d_stadt =="0":
					e.close()
					d.close()
					break
				else:
					print("\t\tGeben sie das Land ein: ")
					e_land=str(input("\t\t>"))
					d.write(d_stadt+"\n")
					e.write(e_land+"\n")
                  elif eingabe == 2:
                  e=open("land.txt", "r")
			d=open("stadt.txt", "r")
			land=e.readlines()
			stadt=d.readlines()
			print("\n\t\tGeben sie die Stadt ein\n")

			while True:
				r=random.randint(0,8)
				print("\t\t\t "+land[r])
				loesung=str(input("\t\t\t>"))
				if loesung=="Ende":
					break
				elif loesung+"\n" == stadt[r]:
					print("\t\t\tRichtig\n")
Nun ist es leider blöd das ich r=random.randint immer selber anpassen muss, gibt es nicht vlt. eine möglichkeit das es das selber macht ?
Hatt vlt. gedacht das es eine Funktion gibt die vlt. die Zeilenanzahl in einer Datei ausliest, dann könnte man ja die Zeilenanzahl von land.txt auslesen und minus 1 nehmen um auf max randint zu kommen....

Gibt es sowas ?

MfG
katd0m
Das Wissen der Menschheit gehört der Welt!
(Zitat: Teddy Chin, Hackers3-StartUp)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

katd0m hat geschrieben:Hatt vlt. gedacht das es eine Funktion gibt die vlt. die Zeilenanzahl in einer Datei ausliest, dann könnte man ja die Zeilenanzahl von land.txt auslesen und minus 1 nehmen um auf max randint zu kommen....
Alter Schwede, das sieht aber merkwürdig aus. Alleine die Einrückungen sind so etwas von verhunzt, dass dir das Programm mit einem Fehler aussteigen muss.

Dann halte ich es für arg gewagt, die Daten in zwei Dateien zu halten die immer synchronisiert sein müssen. Zudem stellt sich dann noch die Frage, warum du diese Dateien in der Schleife wieder und wieder ausliest statt das einmal vorher zu machen.

Der Einsatz von with, ordentliche Fehlerbehandlung und die Wahl von sinnvollen Bezeichnern kommt dann in der nächsten Lektion.

Ach ja, du brauchst natürlich nicht die Zeilen einer Datei extra zu zählen wenn du sie ohnehin schon als Liste vorliegen hast. Die Länge einer Liste ermittelt man mit len(). Das ist ziemlich weit vorne im Tutorial.
Benutzeravatar
katd0m
User
Beiträge: 6
Registriert: Dienstag 11. Januar 2011, 19:17
Wohnort: Hamburg

Abend,

also die EInrückung ist in beim Übertragen flöten gegangen....Habe leider nicht via Vorschau nochmal nachgesehen.

Was die Variablen bezeichnung angeht, so ist diese immer Subjektiv....ich finde die jetzt nicht so schlimm und da das Programm auch definitiv eine Übung für mich ist, finde ich das jetzt nicht so schlimm, wenn die Variablenamen nicht 100% passen!

Die Methode mit den 2 Listen habe ich auch nur gewählt weil ich im moment noch nicht mit dict klarkomme, muss ich mir bei nächster gelegenheit mal genauer anschauen.

Welches while meinst du ?

Und danke für die len() funktion, bei mir im Buch wurde die nicht weiter behandelt(jedenfalls bis da wo ich gerade bin :P)

MfG
katd0m

PS:
@/me : Ich bin wiegesagt neu im Python....und das Buch habe ich auch noch nicht durchgelesen, ich versuche mit diesem Programm, alles nochmal zu wiederholen, und das ein ANfänger nicht alles 100% richtig und elegant gelöst hat, sollte man doch verstehen oder ? ;)
Das Wissen der Menschheit gehört der Welt!
(Zitat: Teddy Chin, Hackers3-StartUp)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich wiederhole noch mal meine Frage: Welches Buch liest Du denn?

Der Quellcode sieht wirklich "abenteuerlich" aus.

Dateien öffnet man mit dem

Code: Alles auswählen

with open() as handler:
    # handler ist hier file object
Idiom. Dabei wird die Datei auf jeden Fall (also auch beim Auftreten von Excpetions) geschlossen.

Du willst Dich auf jeden Fall schnell mit Funktionen befassen. Du packst hier zu viel Code in eine Funktion (bzw. direkt in das Modul?), der auch noch unterschiedlichste Funktionalität beinhaltet (Menüabfrage, Daten eingeben, Quiz durchführen). Das kann man viel schöner aufteilen, was leichter zu testen und überblicken ist.

Zudem ist Deine Datenstruktur unschön; wieso hältst Du Länder und (zugehörige) Städte in zwei getrennten Listen? Sowohl sma als auch ich haben doch dazu bessere Vorschläge gemacht! Solche Strukturfragen bestimmen viel von der späteren Komplexität bzw. Eleganz des Codes (und sind zugegebener Maßen mit das schwierigste am Coden). Im Moment stellst Du implizit durch Deinen Code eine Beziehung zwischen den beiden Listen über den Index her. Stellt sich die Frage: Wozu? Wieso nicht zusammengehörige Daten in eine Struktur packen, so dass die Information dieser Daten darin implizit enthalten ist (nämlich dass eine Stadt in dem zugehörigen Land liegt)?

Du könntest Dir auch die beiden Dateien sparen und die zusammengehörige Struktur in einem etablierten Format, wie etwa JSON, CSV oder auch YAML oder XML speichern. Willst Du die Daten tatsächlich nur über das Programm eingeben, wäre auch pickle noch etwas für Dich. Auf jeden Fall gibt es für alle die Formate Module in der StandardLib, die man leicht dazu verwenden kann.

Du solltest zudem sicherstellen, dass Dein Editor 4 Spaces für einen Tabulator in den Quellcode einfügt. Dann geht auch keine Formatierung flöten und Du hältst Dich an den Standard PEP8.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
katd0m
User
Beiträge: 6
Registriert: Dienstag 11. Januar 2011, 19:17
Wohnort: Hamburg

moin =),

als Buch benutze ich "Python 3 Das umfassende Handbuch" von Johannes Ernesti und Peter Kaiser.

Die Funktionen habe ich schon angefangen, da ich strukturierten Code auch besser finde.

Warum ich nicht gleich eure Ideen genommen habe? Weis ich ehrlichgesagt nicht so wirklich, vermutlich weil ich es schaffen wollte
mit den mir bis dahin vorhandenen Wissen das Programm erstmal fertigzustellen ;), vermutlich einfach unter dem Motto-->schaffst du Programmieren überhaubt?Da zum
programmieren ja auch Lösungsansätze gehören....

Aber vllt. auch weil ich zum Beispiel mit den dict überfordert war.... Die werden im besagten Buch nur kurz angeschnitten, aber noch ein Python Buch zu kaufen...
weis nicht warte damit noch lieber, und Python 3 Tutorial im Internet ist ja auch immer so eine Sache(eigentlich egal mit welche Sprache) kann man vllt. einfach dazu ein Python 2.7 Tutorial nehmen ? Hat sich da was bei den dict geändert ?

Habe aber mittlerweile euren Code durchgearbeitet und (hoffe ich) verstanden ;). Zur übung habe ich einfach jetzt noch ein Vokabelprogramm gemacht :D.

pickel werde ich mir dann auch einmal ansehen.

Noch eine Frage, kann ich mit "with open" auch einfach diese Dateien öffnen ? also CSV, XML ect. meine gelesen zu haben das nur .txt dateien gehen sollen.

Zu dem Editor stelle ich auch gleich eine Frage, das erspart einen neuen Thread :), ich arbeite unter linux, habe aber große Probleme eine guten IDE zu finden
die Python3 unterstüzt, im Moment arbeite ich mit gedit(sowas wie Notepad bei Wind.) doch würde ich auch den Umgang mit IDEs gerne lernen, kennt da jemand zufälllig eine ?(Bitte kein Eric, die Installation unter Linux ist schlimm =( )

So hoffe habe alles diesmal besser erklärt =), falls nicht.... :cry: weis ich auch nicht weiter xD :K

MfG
katd0m :mrgreen:
Das Wissen der Menschheit gehört der Welt!
(Zitat: Teddy Chin, Hackers3-StartUp)
BlackJack

@katd0m: Das Buch hat einen schlechten Ruf -- zumindest was die Ausgabe für Python 2.x angeht. Wenn die das also nur an Python 3.x-Syntax angepasst und nicht deutlich überarbeitet haben, sollte man daraus besser kein Python lernen. Das Buch machte nämlich den Eindruck als wenn die Autoren selber nicht viel Ahnung von Python hatten und einfach ihr Wissen von anderen Programmiersprachen 1:1 auf Python übertragen haben. Was teilweise ziemlich daneben gegangen ist.

Sowohl ``with`` als auch `open()` ist der Inhalt der Dateien ziemlich egal. Bei `open()` muss man nur darauf achten, dass man zwischen Text und Binärdateien unterscheiden muss, und das XML und CSV zum Beispiel *Binärdateien* sind! XML wird man in der Regel aber sowieso mit einer passenden Bibliothek verarbeiten und `ElementTree.parse()` kann man auch gleich einen Dateinamen übergeben. Das öffnen, einlesen und parsen, und schliessen der Datei übernimmt dann die Bibliothek komplett.

IDEs sind bei Python-Programmierern nicht so verbreitet wie bei anderen Sprachen. Viele nehmen einfach ihren Lieblingstexteditor und vielen reicht da auch ein einfacher Editor mit Syntaxhighlighting und einfacher, textbasierter Autovervollständigung.
Benutzeravatar
katd0m
User
Beiträge: 6
Registriert: Dienstag 11. Januar 2011, 19:17
Wohnort: Hamburg

moin :),

ok das ist ja blöd....kannst du mir denn ein gutes Buch oder Online Tutorial für Python3 empfehlen?

Ok mit open ist gut zu wissen....=)

Dann werde ich mit gedit weiter schreiben ;).

Danke für die Antwort!

MfG
Dominic
Das Wissen der Menschheit gehört der Welt!
(Zitat: Teddy Chin, Hackers3-StartUp)
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Wenn du bei gedit bleibst solltest du mal hier vorbei schauen: http://live.gnome.org/Gedit/Plugins
Dort gibt es ein paar sehr nützliche Plugins für ihn, unteranderem "Word Completion for python" und einen "Class Browser"
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
katd0m
User
Beiträge: 6
Registriert: Dienstag 11. Januar 2011, 19:17
Wohnort: Hamburg

wäre

http://tutorial.pocoo.org/

ein gutes Python 3 tut ?

MfG
Dominic
Das Wissen der Menschheit gehört der Welt!
(Zitat: Teddy Chin, Hackers3-StartUp)
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Ja.
Antworten