Im making a simple question and answer app in python , in this specific example it displays a word in simple chinese and gives two answers to pick wrong or right , i'm struggling to present a new question without restarting my code. This my go at making an app that helps me learn chinese and I wanted to use minimum help , hence the weird code.
For example :
the question is what is 1+1 and the user answered two then I want to go thourgh the code again an present the next question.
the specific section im trying the run from inside a function, so when the user answers correctly or incorrectly by pressing the button in the function I want to go through the code again and present my next question
`
# ans
def button_1(event):
if Ans_option1.text == ans_or_not["ans"]:
print('correct')
return 'correct'
else:
print("incorrect")
def button_2 (event):
if Ans_option2.text == ans_or_not["ans"]:
print('correct')
return 'correct'
else:
print("incorrect")
Ans_option1 = gp.Button(app,return_1(), button_1)
Ans_option2 = gp.Button(app,return_2(),button_2)
app.add(Ans_option1,3,2, align = 'center')
app.add(Ans_option2,3,4, align = 'center')
app.run()
`
whole code
import gooeypie as gp
import random
app = gp.GooeyPieApp ('hello')
app.set_size (1000,500)
i = 2
n =3
while True :
# use dictionary instead of lists so we c an have an answer to the questions
question_dict = {
'xihuan' : 'like',
'Wo': 'I',
'Ni': 'you'
}
# random picks a value from a list of values made here
picker = random.choice(list(question_dict.values()))
# I remake the same list here again as the indexing stays the same then find the index for the random value
ind = list(question_dict.values()).index(picker)
# I make a list of the keys and they have mathing indexes to their values and we use the index number given to us previously to find the key
final = list(question_dict.keys())[ind]
# print(final)
test = 1
def question ():
question_dict.pop(final)
print(question_dict)
# return final
return final
ans_or_not = {
# this works first before the item is popped so it can cause a they same two words to appear on the buttons
# varialbe from inside the functions arent stected outside , making this whole dictionary meaningless
'ans' : picker,
'non' : random.choice(list(question_dict.values()))
}
print(ans_or_not["non"])
print(ans_or_not["ans"])
while ans_or_not["non"] == ans_or_not["ans"]:
ans_or_not.pop('non')
print(ans_or_not)
ans_or_not['non'] = random.choice(list(question_dict.values()))
print(ans_or_not["non"])
print(ans_or_not["ans"])
nums = random.randrange(1,3)
print(nums)
def return_1():
# while anss == nons :
# anss = random.randrange(0,2)
# print(anss + ','+ nons)
if nums == 1 :
return ans_or_not["ans"]
if nums == 2:
return ans_or_not["non"]
def return_2():
# while anss == nons :
# anss = random.randrange(0,2)
# print(anss + ','+ nons)
if nums == 1 :
return ans_or_not["non"]
elif nums == 2:
return ans_or_not["ans"]
# design and layout
def menu_select (event):
pass
menu_path = ' > '.join(event.menu)
status.text = menu_path
app.add_menu_item('Menu 1', 'Item 1', menu_select)
# grid setup
app.set_grid(4,5)
question_lbl = gp.Label(app,question())
app.add(question_lbl,2,3, align = 'center')
# ans
def button_1(event):
if Ans_option1.text == ans_or_not["ans"]:
print('correct')
return 'correct'
else:
print("incorrect")
def button_2 (event):
if Ans_option2.text == ans_or_not["ans"]:
print('correct')
return 'correct'
else:
print("incorrect")
Ans_option1 = gp.Button(app,return_1(), button_1)
Ans_option2 = gp.Button(app,return_2(),button_2)
app.add(Ans_option1,3,2, align = 'center')
app.add(Ans_option2,3,4, align = 'center')
app.run()
What i've tried
i've tried using the continue function
ways to restart while loops
You have the problem wrong.
This is going to sound really complicated, but stay with me. So what app.run() does is start the program, and it displays what you have already added to it. By putting app.run() in the while loop, despite calling it multiple times, will only call once. What you need to do is draw the label and buttons, run the app, then start the while loop. In fact, I wouldn't use a while loop here at all. Instead, I would have is so you have a dictionary for the right and wrong answers, then simply modify that and the button text when you get the answer correct. I don't really understand your code, but it would look something like:
#function for choosing answer
#function for checking button one
#function for checking button two
#draw button one and two and label
app.run()
Also, you would have it so that if you got the answer right, you would choose a new one.
Related
I've got an auto completion function that listen on key. There is an edge case in which the given list to complete from is way too long. So I want to limit the output of possible options and ask the user whether he wants to see the whole amount of possibilities.
Let's say I have this completion function and my_list has about 4000 items.
import readline
my_list = [...]
def completer(text, state):
options = [x for x in my_list if x.startswith(text)]
if state < len(options):
return options[state]
else:
return None
readline.parse_and_bind("tab: complete")
readline.set_completer(completer)
while True:
ans = input("Please select one from the list above: ")
if ans == 'exit':
break
print(ans)
I tried to put the condition inside of def completer() like
def completer(text, state):
options = [x for x in my_list if x.startswith(text)]
if state < len(options):
if len(options) > 50:
question = input(f"Do you want to see all {len(options)} possibilities? ")
if question.lower(0) == "y":
return options[state]
else:
return None
else:
return options[state]
else:
return None
Unfortunately this doesn't work, because there is no way calling the input() function inside the input() function. Do you guys got an idea how to implement this?
Hello I have created a quiz using python and tkinter. After each option is pressed I wanted the correct answer to turn green and the three incorrect to turn red then revert to the default for the next question.The problem here being that running the code will take the buttons to the default before the user can see the colours. To do this I tried to use time.sleep() in the function however no matter where I use it it just seems to pause on the button being pressed down and then goes onto the next question without seeing any colour change.
Here is the relevant piece of code
def entry(num):
global score
global x
global count
count +=1
if Qa[x] == 1:
option1.config(bg = "green")
option2.config(bg = "red")
option3.config(bg="red")
option4.config(bg="red")
elif Qa[x] == 2:
option1.config(bg="red")
option2.config(bg="green")
option3.config(bg="red")
option4.config(bg="red")
elif Qa[x] == 3:
option1.config(bg="red")
option2.config(bg="red")
option3.config(bg="green")
option4.config(bg="red")
elif Qa[x] == 4:
option1.config(bg="red")
option2.config(bg="red")
option3.config(bg="red")
option4.config(bg="green")
if num == Qa[x]:
score += 1
x +=1
if count <10:
my_label.config(text = Qs[x])
option1.config(text = (question_prompts[x])[1],bg = "SystemButtonFace",command = lambda: entry(1) )
option2.config(text=(question_prompts[x])[2],bg = "SystemButtonFace",command = lambda: entry(2) )
option3.config(text=(question_prompts[x])[3],bg = "SystemButtonFace",command = lambda: entry(3) )
option4.config(text=(question_prompts[x])[4],bg = "SystemButtonFace",command = lambda: entry(4) )
else:
End_score =Label(text = "Well done you scored" +" "+ str(score)+" " +"out of 11", font = 40)
End_score.place(relx=0.5,rely =0.5,anchor = CENTER)
print(x,score, count, Qa[x])
I haven't put the time.sleep() in here because I have tried it everywhere in this section an it gives the same result
I would really appreciate some help
The PROBLEM here is that the options will not actually change color until Tk can get back to its main loop. As long as you are running your function, the main loop cannot pull new events. You need to set the colors, then use root.after to schedule a callback at some point in the future where you reset to all green.
so i have a code which loops until the user types cancel and allows the user to input things into a list and then see the list if they want to. but i have a problem wherein if i want to see the list the user has to input again and the data i typed when i added to the list is gone. here is the code pls help me im pretty new to python.
answer=""
def addlist():
list=input("what would you like to add? ")
print("added successfully")
return list
def showlist():
list=addlist()
print(list)
while answer !="cancel":
answer=input("what would you like to do?, 1 for add to list, 2 for show list, cancel to close")
if answer=="1":
addlist()
elif answer=="2":
showlist()
else:
print("wrong value")
So we've got a few problems here:
addlist doesn't actually create a list, it creates a string.
showlist depends on addlist, when really we should be looking for a common list that we toss everything into (assuming you actually want to work with a list)
Your indentation in your while loop is incorrect
def addlist():
item = input("what would you like to add?")
return item
def showlist(mylist):
print(mylist)
mylist = []
answer = ""
while answer != "cancel":
answer = input("what would you like to do?, 1 for add to list, 2 for show list, cancel to close")
if answer == "1":
add_item = addlist()
mylist.append(add_item)
print("added successfully")
elif answer == "2":
showlist(mylist)
else:
print("wrong value")
That above seems to do the trick.
You seem to have a grasp on return statements, so how about you pass each of those functions a common list as I did mylist and have them do stuff with that.
I changed addlist to actually just get the item we want to add to the list and then return that item and append it outside of the function. In showlist I pass mylist to it via: showlist(mylist) and then print the list I get in that function.
You should create a list element in order to append your items in it. You can see more here. One way to do what you want is like this:
answer = ""
temp_list = []
def addlist():
item = input("what would you like to add? ")
temp_list.append(item)
print("added successfully")
def showlist():
print(temp_list)
while answer != "cancel":
answer = input(
"what would you like to do?, 1 for add to list, 2 for show list, cancel to close")
if answer == "1":
addlist()
elif answer == "2":
showlist()
else:
print("wrong value")
So in my tkinter python program I am calling on a command when a button is clicked. When that happens it runs a function but in the function I have it set a label to something on the first time the button is clicked and after that it should only update the said label. Basically after the attempt it changes the attempt to 1 ensuring the if statement will see that and not allow it to pass. However it keeps resetting and I don't know how to stop it. When you click the button no matter first or third the button resets and proof of that occurs because the h gets printed. It's as if the function restarts but it shouldn't since it's a loop for the GUI.
def fight(): #Sees which one is stronger if user is stronger he gets win if no he gets loss also displays enemy stats and removes used characters after round is finished
try:
attempt=0
namel = ""
namer=""
left = lbox.curselection()[0]
right = rbox.curselection()[0]
totalleft = 0
totalright = 0
if left == 0:
namel = "Rash"
totalleft = Rash.total
elif left==1:
namel = "Untss"
totalleft = Untss.total
elif left==2:
namel = "Illora"
totalleft = 60+35+80
if right == 0:
namer = "Zys"
totalright = Zys.total
elif right==1:
namer = "Eentha"
totalright = Eentha.total
elif right==2:
namer = "Dant"
totalright = Dant.total
lbox.delete(lbox.curselection()[0])
rbox.delete(rbox.curselection()[0])
print(namel)
print(namer)
if attempt == 0:
wins.set("Wins")
loss.set("Loss")
print("h")
attempt=1
if (totalleft>totalright):
wins.set(wins.get()+"\n"+namel)
loss.set(loss.get()+"\n"+namer)
else:
wins.set(wins.get()+"\n"+namer)
loss.set(loss.get()+"\n"+namel)
except IndexError:
pass
Also for those of you who saw my previous question I still need help with that I just also want to fix this bug too.
At beginning of function fight you set attempt = 0 so you reset it.
Besides attempt is local variable. It is created when you execute function fight and it is deleted when you leave function fight. You have to use global variable (or global IntVar)
attempt = 0
def fight():
global attempt
BTW: of you use only values 0/1 in attempt then you can use True/False.
attempt = False
def fight():
global attempt
...
if not attempt:
attempt = True
hey im making a simple little grocery list on Python. I know it's not the most eloquent... but I am just learning the syntax right now. I want to get into learning Django.
list = []
def makeList():
listing = True
while listing:
addTo = raw_input("Add to list: ")
if addTo == 'q':
listing = False
else:
list.append(addTo)
def checkList():
if check in list:
print "Yay there is " + check + " here"
else:
print "No you have not added that..."
addAnother = raw_input("Would you like to add it? ")
if str.lower(addAnother) == "yes":
list.append(check)
elif str.lower(addAnother) == "no":
print "Okay then here is your list."
print list
else:
print check
makeList()
check = raw_input("What item: ")
checkList()
I know its pretty complex and hard to understand O_o... but you can see that the nested if statement is not registering when you run it.
What is making it do this? I think that's the best way to ask this.
I've rewritten it a bit to make it cleaner and more Pythonic;
def get_list(prompt, halt):
lst = []
while True:
item = raw_input(prompt)
if item == halt:
return lst
else:
lst.append(item)
def check_list(lst, item):
if item in lst:
print('Yay there is {} here'.format(item))
return True
else:
print('No you have not added {}'.format(item))
return False
def get_yesno(prompt):
while True:
yesno = raw_input(prompt).lower()
if yesno in {'y', 'yes'}:
return True
elif yesno in {'n', 'no'}:
return False
def main():
mylist = get_list('Add to list:', 'q')
check = raw_input('Look for item:')
if not check_list(mylist, check):
if get_yesno('Would you like to add it?'):
mylist.append(check)
print(mylist)
if __name__=="__main__":
main()
Some style tips:
Don't use list as a variable name; it's a built-in function, and you don't want to overwrite it.
Global variables are almost always a bad idea; passing data around explicitly makes it much easier to figure out where bad data is coming from, and makes functions more reusable.
camelCase is generally denigrated; use_underscores for function names instead.
You probably intended to keep going rather than break when you append the new item (or at least print something to indicate success), but the nested if statement works just fine, appends the thing to the list as specified and then the function and program terminate.