Gewinnspiel

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.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Du kannst doch mittels eines prints ganz einfach sehen, welche Werte an i und k gebunden sind. Dann hättest du von selbst bemerkt, dass es Tuple-Unpacking ist ;-) Hier sieht man auch mal wieder, wie gut passende Namen sind, bzw. was passiert, wenn die Namen schlecht gewählt sind.

Deine Datenstruktur ist an sich in Ordnung. Allerdings solltest du die Listen noch in Tupel ändern. Das bietet sich immer dann an, wenn man auf Unveränderlichkeit der Daten und eine feste Anzahl an Elementen hinweisen möchte. Beides ist hier der Fall.
Das Leben ist wie ein Tennisball.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Wenn ich die Listen in Tupeln umwandle, klappt das random.shuffle nicht mehr. Würde daher gerne doch weiter Listen verwenden. :)

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-
import easygui, random

frage_antwort = (("Was ist Fifa13?",["Ein Computerspiel", "Ein Monster", "Eine Uhrzeit"]), ("Was ist eine Computermaus?", ["Ein Steuerungsgeraet", "Eine Tastatur", "Ein Bildschirm"]), ("Test1", ["Test2", "Test3", "Test4"]))


for frage, antwort in frage_antwort:
	random.shuffle(antwort)
	fragen_gui = easygui.buttonbox(frage, choices = antwort)
Ich denke von der Namensgebung ist das jetzt so in Ordnung. Bin jetzt mega froh, dass ich es hab. Denncoh weiss ich nicht, ob ich das später wieder alleine schaffe. Ich bin ehrlichgesagt eher durch Glück auf diese Lösung gekommen, aber was solls :)

Ich schau jetzt weiter, wie ich das noch besser machen könnte ;)
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Ui,

habe den Code erweitert und funkt auch alles wie es soll, aber kann man diesen Code vereinfachen:

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-
import easygui, random, sys

frage_antwort = (("Was ist Fifa13?",["Ein Computerspiel", "Ein Monster", "Eine Uhrzeit"]), ("Was ist eine Computermaus?", ["Ein Steuerungsgeraet", "Eine Tastatur", "Ein Bildschirm"]), ("Test1", ["Test2", "Test3", "Test4"]))
richtig = ["Ein Computerspiel", "Ein Steuerungsgeraet", "Test2"]

punkte = 0
versuche = 2

for frage, antwort in frage_antwort:
	random.shuffle(antwort)
	frage_gui = easygui.buttonbox(frage, choices = antwort)
	
	for i in richtig:
		if frage_gui == i:
			print "richtig"
			punkte += 100
		else:
			punkte -= 100
			versuche -= 1

		if versuche == 0:
			print "Looser"
			# danach Exit

Bin jetzt mal ca 30min weg. Evtl auch noch viel länger.

PS: Ja, ich habe überlegt, wie es geht, aber diese Methode scheint mir die übersichtlichste zu sein ;)
BlackJack

@Gary123456: Die zweite Liste mit den richtigen Antworten ist nicht gut. Damit hast Du wieder zusammengehörige Daten auf zwei verschiedene Datenstrukturen verteilt. Ausserdem sind redundante Daten vorhanden, denn die richtigen Antworten sind jetzt alle zweimal in den Daten. Die Lösung wurde doch schon mal angegeben: Nicht die Antworten mischen, sondern eine Kopie davon. Dann kann man weiterhin auf die erste Antwort zugreifen um sie mit der richtigen zu vergleichen.

So wie Du es jetzt machst, hast Du ausserdem das Problem das keine der richtigen Antworten als falsche in anderen Fragen vorkommen darf, sonst wird die Antwort als richtig gezählt.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

`frage_antwort` an sich sollte eine Liste sein. Also eckige Klammern außen herum, anstatt runde. Es geht dabei ja um eine Auflistung einer beliebigen Anzahl von Fragen, vielleicht möchte man Fragen zur Liste hinzufügen (`.append()`), etc.

Um die richtige Antwort zu markieren, könntest du ein drittes Element zu deinen Tupeln hinzufügen: Eine Zahl, die auf den Index des Antwort-Elements hinweist (z.B. `0`).
JonnyDamnnox
User
Beiträge: 68
Registriert: Sonntag 10. März 2013, 21:14

@Gary:Achso, ja ich verstehe ;) dann noch Viel Erfolg !

Gruß
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Hallo,

@BlackJack)

Ist das nicht eine elegantere Lösung:

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-
import easygui, random, sys

frage_antwort = [("Was ist Fifa13?",["Ein Computerspiel", "Ein Monster", "Eine Uhrzeit"], ["Ein Computerspiel"]), ("Was ist eine Computermaus?", ["Ein Steuerungsgeraet", "Eine Tastatur", "Ein Bildschirm"], ["Ein Steuerungsgeraet"]), \
	("Test1", ["Test2", "Test3", "Test4"], ["Test2"])]
	


punkte = 0
versuche = 2

for frage, antwort, loesung in frage_antwort:
	random.shuffle(antwort)
	frage_gui = easygui.buttonbox(frage, choices = antwort)
	if frage_gui == loesung[0]:
		print "Richtig"
		punkte += 100
	else:
		print "You failed"
		versuche -= 1
	

@snafu)

OK :)
BlackJack

@Gary123456: Nein, die richtige Antwort zweimal schreiben zu müssen ist nicht elegant.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Du sagtest ich soll von der Liste eine Kopie erstellen und diese dann in eine Variable legen. Danach muss ich diese nur noch abfragen. natürlich erspart mir dies etwas Tipparbeit, jedoch kann es auch wieder unübersichtlicher sein. Darüber lässt sich aber wieder streiten.

Mein letzter Code für heute:

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-
import easygui, random, sys

frage_antwort = (("Was ist Fifa13?",["Ein Computerspiel", "Ein Monster", "Eine Uhrzeit"]), ("Was ist eine Computermaus?", ["Ein Steuerungsgeraet", "Eine Tastatur", "Ein Bildschirm"]), ("Test1", ["Test2", "Test3", "Test4"]))


kopie = frage_antwort[:]
	

punkte = 0
versuche = 2

k = 0

for frage, antwort in frage_antwort:
	random.shuffle(antwort)
	frage_gui = easygui.buttonbox(frage, choices = antwort)
	if frage_gui == kopie[k][1][0]:
		print "richtig"
	print k
	k += 1
Ich habe jetzt den Wert 0 des Typ integers dem Etikett k zugewiesen. Bei jeder Iteration soll sich diese Variable um 1 erhöhen. Nun verstehe ich garnicht, was da schiefläuft. Um den Fehler zu suchen habe ich mal den Code ausgedruckt und die verschiedenen Indizes gekennzeichnet. Nach längerem Hinschauen konnte ich keinen Fehler entdecken. Ich habe mir den Quelltext genau angeschaut, aber wirklich , ich finde nichts. Könnte jemand mir einen kleinen Tipp geben, was da schief läuft?

Aber dennoch - Schluss für heute. Hab genug geschafft.
Habe folgendes geschafft:
- for schleife korrekt anwenden
- tuple unpacking
- richtige Datenstruktur

Jetzt stimmts auch großteils Praktisch und in der Theorie ist mir eh alles klar! 8)

Gute Nacht euch allen!
BlackJack

@Gary123456: Du machst die Kopie an der falschen Stelle und vom falschen Objekt. Es macht doch gar keinen Sinn eine Kopie von der gesamten Datenstruktur zu machen. Zumal das auch noch eine flache Kopie ist, das also so gar nicht funktioniert. Es wird nur eine Kopie von den Antworten benötigt um die mischen und anzeigen zu können. Und das macht man genau an der Stelle wo man die Liste mit den Antworten hat, die man gemischt anzeigen möchte. Ich würde in Anlehnung an `sorted()` wahrscheinlich eine `shuffled()`-Funktion dafür schreiben.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier mal mein Vorschlag (unter Beachtung deiner bisherigen Kenntnisse):

Code: Alles auswählen

import random
import easygui

fragen = [
    (
        "Was ist Fifa13?", 
        ["Ein Monster", "Ein Computerspiel", "Eine Uhrzeit"], 
        1
    ),
    (
        "Was ist eine Computermaus?", 
        ["Eine Tastatur", "Ein Bildschirm", "Ein Steuerungsgeraet"], 
        2
    ), 
    (
        "Was ist ein Laptop?", 
        ["Ein tragbarer Computer", "Ein Telefon", "Eine Musikrichtung"], 
        0
    )
]


for fragetext, moegliche_antworten, index_richtige_antwort in fragen:
    antworten = random.sample(moegliche_antworten, len(moegliche_antworten))
    antwort_benutzer = easygui.buttonbox(fragetext, choices=antworten)
    if antwort_benutzer == moegliche_antworten[index_richtige_antwort]:
        print "Das war richtig."
    else:
        print "Leider falsch."
Ich habe jetzt einfach mal `random.sample` verwendet, anstatt eine Kopie der Liste anzulegen und diese dann mit `random.shuffle` inplace sortieren zu lassen. Im Ergebnis ist es ja das gleiche.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Irgendwie gefällt mir die Annahme, dass das erste Anwortelement die richtige Lösung ist, nicht. Das ist Datenstruktur-"Magie". Solange Du nicht Bytes auf der Zielplattform sparen musst, würde ich sowas explizit angeben. Dadurch wird die Datenstruktur auch generischer, falls z.B. mal keine oder mehrere Antworten richtig sein sollen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jerch hat geschrieben:Irgendwie gefällt mir die Annahme, dass das erste Anwortelement die richtige Lösung ist, nicht. Das ist Datenstruktur-"Magie". Solange Du nicht Bytes auf der Zielplattform sparen musst, würde ich sowas explizit angeben. Dadurch wird die Datenstruktur auch generischer, falls z.B. mal keine oder mehrere Antworten richtig sein sollen.
Ich muss sagen, ich hätte das auch mit "richtige Antwort" == "erster Eintrag der Liste" gemacht und obwohl mir keiner glauben wird, bin ich unabhängig von BlackJack drauf gekommen. Warum: weil es simpel und leicht verständlich ist. Denn es gibt n>0 Antworten und davon ist eben eine richtig. Da die erste als richtig zu deklarieren ist naheliegend.

Den Einwand mit der Magie kann ich verstehen, würde dem auch prinzipiell zustimmen, aber im aktuellen Fall ist das eher overkill und würde das alles meiner Meinung nach unnötig komplizierter machen, wenn man die richtige Antwort einzeln auszeichnet. Aber als Übungsaufgabe für Gary123456, warum nicht:

Code: Alles auswählen

[("Frage", "Richtige Antwort", ["Falsche Antwort 1", "Falsche Antwort 2", "Falsche Antwort 3"]), …]
Oder um das als Typsignatur anzugeben, was eventuell hilfreich sein könnte, damit Gary123456 sich verinnerlichen kann welche "Form" sowas annehmen kann:

Code: Alles auswählen

(string * string * string list) list
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-
import easygui, random, sys

frage_antwort = [("Was ist Fifa13?",["Ein Computerspiel", "Ein Monster", "Eine Uhrzeit"], 0), ("Was ist eine Computermaus?", ["Ein Steuerungsgeraet", "Eine Tastatur", "Ein Bildschirm"], 0), ("Test1", ["Test2", "Test3", "Test4"], 0)]

	

punkte = 0
versuche = 2

k = 0

for frage, antwort, index in frage_antwort:
	random.sample(antwort, len(antwort))
	frage_gui = easygui.buttonbox(frage, choices = antwort)
	if frage_gui == antwort[index]:
		print "richtig"
	k += 1
Für mich das leichteste und Beste. Eine Kopie von der Liste zu erstellen finde ich etwas kompliziert. Darüberhinaus ist dies wohl etwas übersichtlicher.
Ich will jetzt gar nicht Tipps ablehnen, sondern will einfach für mich die leichteste Methode finden. Und ja, wie man eine Liste kopiert weiß ich (ich weiss praktisch alles über slicing)

Ich werde nun das große Thema Funktionen betrachten ;)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Mit den Indizes machst du den selbern Fehler wie vorher: du zerlegst zusammengehörige Daten wieder in zwei unerschiedliche Datenstrukturen. Es kommt leicht vor, dass man an den Daten mal etwas ändert, so einen Index überseht man dann schnell. Bei dem von Leonidas gezeigten Ansatz kann genau dies nicht passieren. Daher ist er auch zu bevorzugen.

Hast du deinen Code eigentlich getestet? Dann wäre dir aufgefallen, dass deine Antwortmöglichkeiten nie gemischt werden. 'random.sample' liefert eine neue Liste zurück und verändert nicht die übergebene.

Und was ist dieses ominöse k?
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Gary123456 hat geschrieben:ich weiss praktisch alles über slicing
Ok, dann suche jetzt 5 ganz bestimmte Buchstaben aus dem Alphabet heraus: Du musst bei Y beginnen und von da aus in Richtung A gehen. Zwischen den Buchstaben müssen jeweils 2 Buchstaben übersprungen werden. Das alles muss innerhalb einer einzigen Slicing-Operation erfolgen. Los, mach! :twisted:

Tipp: Erster Buchstabe der Lösung ist Y, danach kommt das W, usw.

EDIT: Ich glaube, in einer einzigen Operation (also *einer* Verwendung von eckigen Klammern) geht es nicht wirklich elegant. War ja auch eigentlich eh nur Getrolle...
Zuletzt geändert von snafu am Dienstag 9. April 2013, 15:57, insgesamt 1-mal geändert.
BlackJack

@Gary123456: Den `random.sample()`-Aufruf musst Du noch entfernen. Der hat so ja auch gar keinen Effekt.
Gary123456
User
Beiträge: 318
Registriert: Dienstag 26. Februar 2013, 18:39

Stop oO Da habe ich wohl den falschen COde gespeichert oO Muss mal wieder nachsehen.

EDIT: Es hat den Code nicht gespeichert :( Daher Fehler im Code. Werde mal schauen wie's ich noich besser mache. Aber der ursprüngliche Code war ähnlich, nur es hat die antworten vermischt oO
Zuletzt geändert von Gary123456 am Dienstag 9. April 2013, 16:01, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dann kannst du bei der Gelegenheit gleich mal lernen was eine Versionsverwaltung ist ;-)
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das mit den Indizes stimmt schon. Beim Abwägen der Vor- und Nachteile würde ich letztlich wohl auch eher dazu tendieren, mit der Regel zu arbeiten, dass die erste Antwortmöglichkeit stets die korrekte Antwort ist. Man kann - die richtige Anwendung der `random`-API vorausgesetzt - ja immer noch die Antwortmöglichkeiten zufällig durchmischen lassen und mit dem Ergebnis als Ausgabe arbeiten.

Falls aber irgendwann mal mehrere Antwortmöglichkeiten korrekt sein können, muss man sich natürlich wieder etwas anderes ausdenken, um dies einigermaßen benutbar in Code zu bringen...
Antworten