# project - trivia game

Discussion in 'Python' started by Shawn Minisall, Dec 5, 2007.

1. ### Shawn MinisallGuest

For my final project, I'm trying to do a GUI based game similar to are
you smarter then a 5th grader. I've been working on it and am stuck
with some code someone helped me with to randomize the A,B,C,D letters
that the correct answer is assigned too. The code that does this is
highlighted in bold and the code that assigns it to a variable is also
in bold so I can test it in the console window. Problem is, it's always
stuck at letter A and doesn't always give the correct answer. The
correct answer is always position 1 in my make math question list.

thanks

BTW, to whoever asked me why I don't use functions b4, I'm using them
now that I've learned how to...

from graphics import *
from random import *

#define and draw the buttons

#define and draw the main menu
"normal", "red",win))
below: ","times roman", 14, "normal", "purple",win))
"italic", "blue",win))
"italic", "yellow",win))
"italic", "pink",win))
"italic", "green",win))
"italic", "black",win))

def CreateText(x,y,myString,myFace,mySize, myStyle, myColor,win):
myText = Text(Point(x,y), myString)
myText.setFace(myFace)
myText.setSize(mySize)
myText.setStyle(myStyle)
myText.setTextColor(myColor)
myText.draw(win)
return myText

def CreateRect(x1,x2,y1,y2,myFill,win):
myRect = Rectangle(Point(x1,y1,), Point(x2,y2))
myRect.setFill(myFill)
myRect.draw(win)
return myRect

def isValidClick(x1,x2, y1, y2, p1, win):
if p1.getX()>=x1 and p1.getY()>=y1 and p1.getX()<=x2 and p1.getY()<=y2:
return True
else:
return False

def drawQuestion (subject, question, answers, win):

#define and draw the entry boxes
entchoice = Entry(Point(6.4,6.5), 1)
entchoice.setText("A")
entchoice.setTextColor ("blue")
entchoice.draw(win)

"normal", "red",win))
16, "normal", "purple",win))
16, "normal", "purple",win))
16, "normal", "purple",win))
16, "normal", "purple",win))
choice:","times roman", 16, "normal", "purple",win))

def main():

#Declare and initialize variables

#make math question list
mathlist = []
question = ["An equilateral triangle has how many sides?", "3", "4"
, "1", "5"]
mathlist.append(question)
question = ["How many inches are in a foot?", "12", "6", "3", "9"]
mathlist.append(question)
question = ["One Kilogram equals how many grams?", "1000", "230",
"450", "100"]
mathlist.append(question)
question = ["Which means nine hundred sixty three thousandths?",
".963", ".0963", ".0.0963", "9.63"]
mathlist.append(question)
question = ["A fathom is a unit of measurement for which of the
following?", "depth", "space", "time", "distance"]
mathlist.append(question)
question = ["What is 111, plus 112, plus 113?", "336", "332", "331",
"333"]
mathlist.append(question)

#show the rules of the game window
win = GraphWin("RULES OF THE GAME",600,600)
win.setBackground("orange")
win.setCoords(0.0,0.0,10.0,10.0)

txtrules1 = CreateText(5,9.5,"The rules of the game are as
follows:","times roman", 16, "normal", "red",win)
txtrules2 = CreateText(5,8.5,"The game will be made up of 10
questions, 2 from each grade 1-5.","times roman", 12, "normal", "black",win)
txtrules3 = CreateText(5,7.5,"You will be able to pick 2 subjects
"black",win)
txtrules4 = CreateText(5,6.5,"The subjects you can pick from are
Math, Science, History and Geography.","times roman", 12, "normal",
"black",win)
txtrules5 = CreateText(5,5.5,"No more then 3 questions can be
answered from each subject.","times roman", 12, "normal", "black",win)
txtrules6 = CreateText(5,2.5,"HAVE FUN AND GOOD LUCK!","times
roman", 26, "normal", "yellow",win)

#define window and set coords
win =GraphWin("Are You Smarter Then a Fifth Grader???",800,800)
win.setBackground("orange")
win.setCoords(0.0,0.0,10.0,10.0)

#getMouse
p1 = win.getMouse()
while(isValidClick(8,10,0,1,p1,win)==False):
if (isValidClick(4,6,7,8,p1,win)==True):
currentList = mathlist
subject = "Math"

elif (isValidClick(3.5,6.5,5,6,p1,win)==True):

elif (isValidClick(3.5,6.5,3,4,p1,win)==True):

elif (isValidClick(3.1,7,1,2,p1,win)==True):

* #Picks random question
qNum = randrange(0, len(currentList))
qList = currentList[qNum]

aList = []
tmpList = qList[1:5]

while(len(tmpList) > 0):
rNum = randrange(0, len(tmpList))
aList.append(tmpList[rNum])
tmpList.pop(rNum)*

currentScreen = drawQuestion(subject, qList[0], aList, win)
currentList.pop(qNum)

#getMouse
p1 = win.getMouse()
while(isValidClick(7,3,5.5,4,p1,win)==True):
print "hello"

*
pResult = (currentScreen[0].getText())
print pResult

cResult = (currentScreen[2].getText())
print cResult*

#if correct/incorrect do a print statement

#Quit
win.close()

Shawn Minisall, Dec 5, 2007

2. ### Dennis Lee BieberGuest

On Tue, 04 Dec 2007 19:43:32 -0500, Shawn Minisall
<> declaimed the following in comp.lang.python:

> For my final project, I'm trying to do a GUI based game similar to are
> you smarter then a 5th grader. I've been working on it and am stuck
> with some code someone helped me with to randomize the A,B,C,D letters
> that the correct answer is assigned too. The code that does this is
> highlighted in bold and the code that assigns it to a variable is also
> in bold so I can test it in the console window. Problem is, it's always
> stuck at letter A and doesn't always give the correct answer. The
> correct answer is always position 1 in my make math question list.
>

Not having a copy of your graphics library, I restricted myself to
just the mechanics of randomizing the questions and responses (and since
there is only one "category" at present, I run through it completely --
see below for commentary on multiple categories). Getting the mechanics
working with a text-based prototype probably should have been done first
-- it can often be easier to map a text interface into a GUI than
starting with a GUI with no working behavior...

-=-=-=-=-=- Beware line wrapping
import time
import random

# q -> question;
# c -> choices (a four element list in any order)
# a -> answer (correct answer -- must match the entry in "c"
exactly)
mathlist = [ {"q" : "An equilateral triangle has how many sides?",
"c" : [ "1", "3", "4", "5"],
"a" : "3"},
{"q" : "How many inches are in a foot?",
"c" : [ "3", "6", "9", "12"],
"a" : "12"},
{"q" : "One Kilogram equals how many grams?",
"a" : "1000",
"c" : [ "100", "230", "450", "1000"]},
{"a" : "0.963",
"c" : [ "0.0963", "0.963", "9.63", "963000.0" ],
"q" : "Which means nine hundred sixty three
thousands?"},
{"q" : "A fathom is a unit of measurement for which of
the following?",
"a" : "depth",
"c" : [ "distance", "time", "space", "depth"]},
{"q" : "What is 111, plus 112, plus 113?",
"c" : [ "331", "332", "333", "336"],
"a" : "336"} ]

MAXSCORE = len(mathlist)
score = 0

#shuffle the questions
random.shuffle(mathlist)
for qca in mathlist:
question = qca["q"]
choices = qca["c"]
random.shuffle(choices) #shuffle the choices

print "\n\n\n\t\tScore: %s correct out of %s" % (score, MAXSCORE)
print "\n\nThe question is:\n\n\t%s\n" % question
# you'd normally assign the four choices as the text labels of the
four
# gui buttons, and wouldn't need a loop for invalid user input --
the
# only valid input IS one of the four buttons.
print "\n\nYour choices are:\n\n\tA: %s\tB: %s\n\tC: %s\tD: %s\n" %
tuple(choices)
while True:
pick = raw_input("\nEnter the letter of your choice: ")
letter = pick.upper()[0] #only want the one CAPITAL letter
if letter in "ABCD": break
print "\n*****\t'%s' is not a valid choice, try again" % letter

#determine if correct result picked
# in a GUI situation, I'd expect the buttons to be filled with the
text
# of the choices, so no trick with indexing into the choices list
is needed.
# just compare the button label text directly against the correct
ix = "ABCD".find(letter)
print "Congratulations, you picked the correct answer"
score += 1
else:
time.sleep(2.5)

print "Your FINAL score was: %s out of %s, or %s%%" % (score, MAXSCORE,
(100.0 * score /
MAXSCORE))
-=-=-=-=-=-=-

Given a system with multiple categories, you probably need to either
add a flag "used" initialized to False, and set it to True if a question
has been shown, then when the category is chosen again, loop until the
selected question was "not used" (you'd use random.choice() to get a
candidate)

while True
qca = random.choice(category_list)
if not qca["used"]: break

OR you initialize each category list using random.shuffle, as above code
does, then when the category is picked you retrieve the last item from
the list and remove it from the list.

#initialization
random.shuffle(cat1_list)
random.shuffle(cat2_list)
....etc.

#during game
if len(category_list): #still has questions
qca = category_list.pop()
else:
# the category is empty

--
Wulfraed Dennis Lee Bieber KD6MOG

HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: )
HTTP://www.bestiaria.com/

Dennis Lee Bieber, Dec 5, 2007

3. ### Dennis Lee BieberGuest

On Wed, 05 Dec 2007 10:21:57 -0800, Dennis Lee Bieber
<> declaimed the following in comp.lang.python:

Talking to myself, it would seem <G>

I went into a bought of OO'ing today and came up with this -- still
text based...

-=-=-=-=-=-=-=-
import random
import time

# define classes for "QCA" (Question, Choices, Answer);
# question Category; and overall Game data control
class QCA(object):
"""
choices is a string with each choice separated by a tilde ~
character
answer is a string that must be in choices after splitting on ~
"""
self.question = question
self.choices = choices.split("~")
random.shuffle(self.choices)
def reset(self):
random.shuffle(self.choices)

class Category(object):
def __init__(self, name):
self.name = name
self.available = []
self.used = []
def reset(self):
self.available.extend(self.used)
self.used = []
for qca in self.available:
qca.reset()
random.shuffle(self.available)
def isActive(self):
return len(self.available)
self.available.append(qca)
def getQuestion(self):
qca = self.available.pop()
self.used.append(qca)
return qca

class Game(object):
def __init__(self):
self.categories = []
self.reset()
def reset(self):
self.tried = 0
self.activeQuestion = None
self.categories.append(category)
def getCategories(self):
return [(c.name, c.isActive()) for c in self.categories]
def getQuestion(self, catName):
for c in self.categories:
if c.name == catName:
self.activeQuestion = c.getQuestion()
return self.activeQuestion
self.tried += 1
return True
return False
def getScore(self):
#
# populate the game data
game = Game()
qpool = Category("Mathematics")
qpool.addQuestion(QCA("An equilateral triangle has how many sides?",
"1~3~4~5",
"3"))
qpool.addQuestion(QCA("How many inches are in a foot?",
"3~6~9~12",
"12"))
qpool.addQuestion(QCA("One Kilogram equals how many grams?",
"100~250~1000~2000",
"1000"))
qpool.addQuestion(QCA("Which means nine hundred sixty three thousands?",
"0.0963~0.963~9,630.0~963,000.0",
"0.963"))
qpool.addQuestion(QCA("A fathom is a unit of measurement for which of
the following?",
"distance~time~space~depth",
"depth"))
qpool.addQuestion(QCA("What is 111, plus 112, plus 113?",
"331~332~334~336",
"336"))

#repeat from qpool = Category(???) for each final category

# now that the game data is populated, add the display/control
functionality
def displayScore(correct, total):
print "\n\n\n\tYour Score: %s out of %s (%s%%)" % (correct,
total,
(100.0 * correct
/ total))

def handleQuestion(qca):
print "\n\n\nThe question is:\n\n\t%s" % qca.question
print "\n"
for i, choice in enumerate(qca.choices):
print "\t%s\t%s" % (i+1, choice)
print
while True:
itm = int(raw_input("Enter your choice (1..%s): " %
len(qca.choices)))
if 0 < itm < len(qca.choices) + 1:
return qca.choices[itm - 1]
else:
print "*****\t%s is not a valid choice, try again" % itm

def selectCategory(categories):
"""
categories is a list of (name, boolean) tuples; if the boolean is
false,
this category has no more questions available and should not be
enabled
(in a GUI static button layout, disable the button; in text, remove
it from
the menu of choices presented to the player)
"""
print "\n\n\nSelect from the following categories\n\n"
select = []
selected = None
for i, (name, active) in enumerate(categories):
if active:
print "\t%s\t%s" % (i+1, name)
select.append(name)
if select:
print
while True:
itm = int(raw_input("Enter your choice (1..%s): " %
len(select)))
if 0 < itm <= len(select):
selected = select[itm - 1]
break
else:
print "*****\t%s is not a valid choice, try again" % itm
else:
print "\n\tAll questions have been attempted -- game is over"
return selected

def playGame(g):
g.reset() #ensure game data has been reset
while True:
category = selectCategory(g.getCategories())
if not category: break #no categories left to select from
qca = g.getQuestion(category)
if result:
print "That is CORRECT!"
else:
print "I'm sorry, that is incorrect."
displayScore(*g.getScore())
time.sleep(2.5)

if __name__ == "__main__":
playGame(game)
-=-=-=-=-=-=-=-
--
Wulfraed Dennis Lee Bieber KD6MOG

HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: )
HTTP://www.bestiaria.com/

Dennis Lee Bieber, Dec 6, 2007