Examining program - python

At first I thought this would be an easy program where I could learn a lot. But I'm stuck.
How can I ask diffrent questions all after eachother. I have tried some things I came up with but none of those work.
This is the first one, where I use a variable x to re-generate the question. This simply doesn't work.
# Laad de database
cnx = mysql.connector.connect(user='FransSchool', password='RandomPass',host='10.0.0.25', database='Overhoor')
cursor = cnx.cursor()
# Maak een grafische interface
gui = Tk()
gui.resizable(width=FALSE, height=FALSE)
# Verklaringen
def verify():
overify = antwoord.get()
if overify == Nederlandsevertaling:
oentry.delete(0,END)
x=0
else:
oentry.delete(0,END)
x = 0
antwoord = StringVar()
willekeurig = random.randint(0,9)
# Indexeer de database
query = "SELECT FRwoord, NLwoord FROM unite8app1 WHERE id=%s"
cursor.execute(query, (willekeurig,))
while x < 1:
for (FRwoord, NLwoord) in cursor:
Fransevertaling = FRwoord
Nederlandsevertaling = NLwoord
x+=1
And this is the second one which gave me an error. It didn't really came as a surprise that this one didn't work. On button press it tries to recieve a new FR and NLwoord.
# Laad de database
cnx = mysql.connector.connect(user='FransSchool', password='RandomPass', host='10.0.0.25', database='Overhoor')
cursor = cnx.cursor()
# Maak een grafische interface
gui = Tk()
gui.resizable(width=FALSE, height=FALSE)
# Verklaringen
def verify():
overify = antwoord.get()
if overify == Nederlandsevertaling:
oentry.delete(0,END)
willekeurig = random.randint(0,9)
for (FRwoord, NLwoord) in cursor:
Fransevertaling = FRwoord
Nederlandsevertaling = NLwoord
else:
oentry.delete(0,END)
#Save the wrong answer aswell as the right answer to print out at the end
antwoord = StringVar()
willekeurig = random.randint(0,9)
# Indexeer de database
query = "SELECT FRwoord, NLwoord FROM unite8app1 WHERE id=%s"
cursor.execute(query, (willekeurig,))
for (FRwoord, NLwoord) in cursor:
Fransevertaling = FRwoord
Nederlandsevertaling = NLwoord
# Uiterlijk van het venster
gui.configure(background="white")
gui.title("Overhoorprogramma - Bryan")
# Grafische objecten
style = ttk.Style()
olabel = ttk.Label(gui,text=Fransevertaling,font=("Times", 18), background="white")
olabel.grid(row=0, column=0,padx=5, pady=5, sticky="W")
oentry = ttk.Entry(gui,textvariable=antwoord, font=("Times", 18))
oentry.grid(row=1, column=0,padx=5, pady=5)
obutton = ttk.Button(gui,text="Suivant", command = verify)
obutton.grid(row=1, column=1,padx=5, pady=5)
At the moment it just clears the entry box on button press. The goal is that everytime an answer has been typed in right it should skip that and if it is typed wrong it has to save it. Either way it has to create a new question what means a new Frword and NLword.
Ideally I am looking for a push in the right direction, the mechanism behind it or a small snippet of code.

Related

Problem printing the contents of a text box in another textbox multiline

I am making a small app with Tkinter, for educational purposes, which consists of pressing a button and displaying the contents of a textobox ... in another multiline textbox.
The problem is that you see this:
<bound method Text.get of <tkinter.Text object.! Text2 >>
and not the content that I manually write of the textobox. The textbox that I would like to print in the multiline textobox (called text) is called textbox_test. Textbox_test is called
A = f "{test_textbox.get} {'' .join (word2)} {abitanti} abitanti su un'area di {superficie}".
Questo è il textobox
test_textbox = Text(window,width=10,height=1)
test_textbox.pack()
test_textbox.place(x=5, y=100)
How can I remove the error above and correctly display the text of a textbox? I attach complete code. Thank you
from tkinter import *
from tkinter import ttk
import tkinter as tk
import sqlite3
import random
window=Tk()
window.title("xxxxxxxx")
window.geometry("750x750")
window.configure(bg='#78c030')
con = sqlite3.connect('/home/xxxxxxxxxxx/Database.db')
cursor = con.cursor()
# Search Data
def city(name_city):
name_city = city.get()
cursor.execute('SELECT * FROM Info WHERE City =?',(name_city,))
results = cursor.fetchone()
return results
# Print Data in textbox multiline
def write():
name_city = city.get
results = city(name_city)
inhabitants = results[2]
surface = results[3]
if categoria.get() == "Test 1" and sottocategoria.get() == "Test 1.1":
cursor.execute('SELECT xxxxxxxx FROM TableExample ORDER BY RANDOM() LIMIT 1')
word2 = cursor.fetchone()
text.delete(1.0,END)
A= f"{test_textbox.get} {''.join(word2)} {inhabitants} inhabitants on an area of {surface}"
B= f"Che sale a"
text.insert(tk.END, random.choice([A, B]))
button2 = Button(window, text="Button2", bg='white', command = write)
button2.pack()
button2.place(x=5, y=330)
### TEXTBOX MULTILINE ###
text = Text(window,width=63,height=38)
text.pack()
text.place(x=180, y=24)
### TEXTBOX ###
test_textbox = Text(window,width=10,height=1)
test_textbox.pack()
test_textbox.place(x=5, y=100)
### CATEGORIA E SOTTO CATEGORIA ###
cat=StringVar()
sub_cat=StringVar()
def change_val(*args):
if cat.get() == "Test 1":
sottocategorias = ["Test 1.1", "Test 1.2", "Test 1.3"]
sottocategoria.config(values=sottocategorias)
else:
sottocategorias = ["aaaa"]
sottocategoria.config(values=sottocategorias)
categorias=["Test 1", "Test 2", "Test 3"]
categoria=ttk.Combobox(window,value=categorias,textvariable=cat,width=16)
categoria.place(x=5, y=25)
cat.set("Scegliere categoria")
sottocategorias=["aaaa"]
sottocategoria=ttk.Combobox(window,textvariable=sub_cat,value=sottocategorias,
width=16)
sottocategoria.place(x=5, y=55)
cat.trace("w",change_val)
### COMBOBOX ###
def combo_nation():
cursor.execute('SELECT DISTINCT Nation FROM Info')
result=[row[0] for row in cursor]
return result
def combo_city(event=None):
val = city.get()
cursor.execute('SELECT City FROM Info WHERE Nation = ?', (val,))
result = [row[0] for row in cursor]
city['value'] = result
city.current(0)
return result
nation=ttk.Combobox(window,state="readonly")
nation['value'] = combo_nation()
nation.bind('<<ComboboxSelected>>', combo_city)
nation.place(x=5, y=150,height = 25, width = 180)
city=ttk.Combobox(window,state="readonly")
city.place(x=5, y=180, height = 25, width = 180)
window.mainloop()
IMPORTANT: If you try to change to A = f "{test_textbox.get (" 1.0 "," end-1c ")} {'' .join (word2)}, that's not good. The app won't open. Without this code instead opens
As #BryanOakley said in comment you need get with () to run it and widget Text needs it with arguments like
A = f"{test_textbox.get('1.0','end-1c')} ...
It didn't work because it was only part which you would have to replace in full text, but it seems you replaced all text. Because you didn't run code in console so you couldn't see error message which could explain problem
Full line should be
A = f"{test_textbox.get('1.0','end-1c')} {''.join(word2)} {inhabitants} inhabitants on an area of {surface}"

Why do i need to use this user = dict()

from tkinter import *
main_window = Tk()
main_window.title("Register now")
frame = Frame(main_window)
frame.pack()
l_name = Label (frame, text = "Name:")
#metodo entende que é a mesma coisa que l_name.grid(row = 0, column = 0)
l_name.grid()
e_name = Entry(frame)
e_name.grid(row = 0, column =1)
l_lastname = Label(frame, text = "Last name:")
#metodo entende que é a mesma coisa que l_name.grid(row = 1, column = 0)
l_lastname.grid(row = 1)
e_lastname = Entry(frame)
e_lastname.grid(row = 1, column =1)
l_email = Label (frame, text = "E-mail:")
l_email.grid(row = 2)
e_email = Entry(frame)
e_email.grid(row = 2, column =1)
def convert_to_dict():
user = dict()
user['name'], user['last_name'], user['e-mail'] = e_name.get(), e_lastname.get(), e_email.get()
print(user)
Button(frame, text = "Send", command = convert_to_dict).grid(row=3,column =1)
Why i need this comanda user = dict()? I am telling the programn that the variable user is a dict() and thats ok, but i want to know if put user = {} would do same harm to the code
The statement user = dict() creates a new and empty python dictionary which you then fill with content on the subsequent line.
The approach looks rather non-pythonic to me. I would rather initialize and fill the dictionary in one go as TheLizzard suggested:
user = {"name": e_name.get(), "last__name": e_lastname.get(), ...}
You can achieve the same thing with the dict() method but it may result in more visual clutter in this case. However, the dict() method comes with a bunch of other handy ways to create and fill dictionaries in programmatic ways. e.g. this resource gives a nice overview: https://www.programiz.com/python-programming/dictionary

showing data from database into tkinter not working

I have defined a function here and it is supposed to work correctly because im using a similar function somewhere else but without giving any conditions(where.. like or regexp) and it works fine there, when i use regexp and all it does not give an output. Why is that? Thanks in advance :)
Code:
def search():
log = Toplevel(root)
log.title('View all customers')
def db():
selected = drop.get()
result_win = Toplevel(log)
result_win.title('Search result')
con = mysql.connect(host='localhost', user='root',
password='*****', database='BOOK')
c = con.cursor()
c.execute(f"SELECT * from books where '{selected}' regexp
'{e_sch.get()}';")
result = c.fetchall()
index=0
for index, x in enumerate(result):
num = 0
for y in x:
lookup_label = Label(result_win, text=y)
lookup_label.grid(row=index+1, column=num)
num +=1
con.close()
l1 = Label(result_win,text='Sl.No',font=font_text)
l2 = Label(result_win,text='Title',font=font_text)
l3 = Label(result_win,text='Authors',font=font_text)
l4 = Label(result_win,text='Subject',font=font_text)
l5 = Label(result_win,text='Availablity',font=font_text)
btn_ext = Button(result_win,text='Exit',font=font_text,command=result_win.destroy,borderwidth=2,fg='#eb4d4b')
l1.grid(row=0,column=0,padx=20)
l2.grid(row=0,column=1,padx=20)
l3.grid(row=0,column=2,padx=20)
l4.grid(row=0,column=3,padx=20)
l5.grid(row=0,column=4,padx=20)
btn_ext.grid(row=index+2,columnspan=7,ipadx=540)
global a
l = Label(log,text='Search',font=Font(family='helvetica', size='20'))
drop = ttk.Combobox(log,value=['Search by....','Sl.no','Title','Authors','Subject','Availablity'])
drop.current(0)
l2 = Label(log,text='Enter',font=font_text)
e_sch = Entry(log)
b_sch = Button(log, text='Search book', command=db, font=font_text)
b_ext = Button(log, text='Exit', command=log.destroy, font=font_text)
a = drop.get()
l.grid(row=0,columnspan=3,pady=20)
drop.grid(row=1,column=0,columnspan=3)
l2.grid(row=2,column=0,padx=(20,0))
e_sch.grid(row=2,column=1, padx=30, ipady=5,pady=20)
b_sch.grid(row=3,column=0,columnspan=3,ipadx=200)
b_ext.grid(row=4,column=0,columnspan=3,ipadx=237)
Sometimes i get this error too UnboundLocalError: local variable 'index' referenced before assignment
The syntax of the SELECT statement is incorrect:
SELECT * from books where '{selected}' regexp '{e_sch.get()}';
should be:
SELECT * from books where `{selected}` regexp '{e_sch.get()}';
Field name should be surrounded by ``, not ''.

Name 'NewPage' is not defined in object oriented programming

#imports
from tkinter import *
from tkinter import messagebox as ms
import sqlite3
# make database and users (if not exists already) table at programme start up
with sqlite3.connect('quit.db') as db:
c = db.cursor()
c.execute('CREATE TABLE IF NOT EXISTS user (username TEXT NOT NULL ,password TEX NOT NULL);')
db.commit()
db.close()
#main Class
class main:
def __init__(self,master):
# Window
self.master = master
# Some Usefull variables
self.username = StringVar()
self.password = StringVar()
self.n_username = StringVar()
self.n_password = StringVar()
#Create Widgets
self.widgets()
def NewPage():
global NewRoot
root.withdraw() # hide (close) the root/Tk window
NewRoot = tk.Toplevel(root)
# use the NewRoot as the root now
#Login Function
def login(self):
with sqlite3.connect('quit.db') as db:
c = db.cursor()
#Find user If there is any take proper action
find_user = ('SELECT * FROM user WHERE username = ? and password = ?')
c.execute(find_user,[(self.username.get()),(self.password.get())])
result = c.fetchall()
if result:
self.logf.pack_forget()
self.head['text'] = self.username.get() + '\n Logged In'
self.head['pady'] = 150
root.after(2000, NewPage)
else:
ms.showerror('Oops!','Username Not Found.')
def new_user(self):
#Establish Connection
with sqlite3.connect('quit.db') as db:
c = db.cursor()
#Find Existing username if any take proper action
find_user = ('SELECT * FROM user WHERE username = ?')
c.execute(find_user,[(self.username.get())])
if c.fetchall():
ms.showerror('Error!','Username Taken Try a Diffrent One.')
else:
ms.showinfo('Success!','Account Created!')
self.log()
#Create New Account
insert = 'INSERT INTO user(username,password) VALUES(?,?)'
c.execute(insert,[(self.n_username.get()),(self.n_password.get())])
db.commit()
#Frame Packing Methords
def log(self):
self.username.set('')
self.password.set('')
self.crf.pack_forget()
self.head['text'] = 'LOGIN'
self.logf.pack()
def cr(self):
self.n_username.set('')
self.n_password.set('')
self.logf.pack_forget()
self.head['text'] = 'Create Account'
self.crf.pack()
#Draw Widgets
def widgets(self):
self.head = Label(self.master,text = 'LOGIN',font = ('',35),pady = 10)
self.head.pack()
self.logf = Frame(self.master,padx =10,pady = 10)
Label(self.logf,text = 'Username: ',font = ('',20),pady=5,padx=5).grid(sticky = W)
Entry(self.logf,textvariable = self.username,bd = 5,font = ('',15)).grid(row=0,column=1)
Label(self.logf,text = 'Password: ',font = ('',20),pady=5,padx=5).grid(sticky = W)
Entry(self.logf,textvariable = self.password,bd = 5,font = ('',15),show = '*').grid(row=1,column=1)
Button(self.logf,text = ' Login ',bd = 3 ,font = ('',15),padx=5,pady=5,command=self.login).grid()
Button(self.logf,text = ' Create Account ',bd = 3 ,font = ('',15),padx=5,pady=5,command=self.cr).grid(row=2,column=1)
self.logf.pack()
self.crf = Frame(self.master,padx =10,pady = 10)
Label(self.crf,text = 'Username: ',font = ('',20),pady=5,padx=5).grid(sticky = W)
Entry(self.crf,textvariable = self.n_username,bd = 5,font = ('',15)).grid(row=0,column=1)
Label(self.crf,text = 'Password: ',font = ('',20),pady=5,padx=5).grid(sticky = W)
Entry(self.crf,textvariable = self.n_password,bd = 5,font = ('',15),show = '*').grid(row=1,column=1)
Button(self.crf,text = 'Create Account',bd = 3 ,font = ('',15),padx=5,pady=5,command=self.new_user).grid()
Button(self.crf,text = 'Go to Login',bd = 3 ,font = ('',15),padx=5,pady=5,command=self.log).grid(row=2,column=1)
if __name__ == '__main__':
#Create Object
#and setup window
root = Tk()
root.title('Login Form')
#root.geometry('400x350+300+300')
main(root)
root.mainloop()
On line 37 it says NewPage is not defined but I defined it on line 24, please help. this program is object oriented and im a student trying to complete this for my A-Level project. I dont understand alot of this code but any help would be much appreciated. Im a amateur when it comes to python/tkinter/sqlite but need this help otherwise I will fail my course because my teacher is not much help when it comes to programming
You are missing self in your function def NewPage(self): and go to the line which you have root.after(2000, NewPage) and replace it with root.after(2000, self.NewPage)

Unable to increment questions from sqlite database in quiz using tkinter

I'm still working on my quiz program but I'm currently having an issue with getting the program to increment the questions which are retrieved from a database that I also have. When I try to move to the next record in my database I haven't been able to actually change the contents of the page, everything stays as it is and I have to this point not been able to rectify the issue. I feel as though it's an issue with my use of variable but I cant think of any way around this. Here's the section of my code where I'm having this issue:
class ques(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
fetchrecNum = "SELECT MAX(qnumber) FROM questions"
cursor.execute(fetchrecNum)
self.recNum=str(cursor.fetchall())
self.recNum=self.recNum.strip("[('")
self.recNum=self.recNum.strip("',)]")
self.recNum=int(self.recNum)
recordNum = tk.Label(self, text = self.recNum)
recordNum.pack()
self.Qn = 1
self.quizScore = 0
fetchQ = "SELECT questioncontent FROM questions WHERE qnumber=?"
cursor.execute(fetchQ, [self.Qn])
Q=str(cursor.fetchall())
Q=Q.strip("[('")
Q=Q.strip("',)]")
question = tk.Label(self, text = Q)
question.pack()
fetchA1 = "SELECT qanswer1 FROM questions WHERE qnumber=?"
cursor.execute(fetchA1, [self.Qn])
A1=str(cursor.fetchall())
A1=A1.strip("[('")
A1=A1.strip("',)]")
answer1 = tk.Label(self, text = A1)
answer1.pack()
fetchA2 = "SELECT qanswer2 FROM questions WHERE qnumber=?"
cursor.execute(fetchA2, [self.Qn])
A2=str(cursor.fetchall())
A2=A2.strip("[('")
A2=A2.strip("',)]")
answer2 = tk.Label(self, text = A2)
answer2.pack()
fetchA3 = "SELECT qanswer3 FROM questions WHERE qnumber=?"
cursor.execute(fetchA3, [self.Qn])
A3=str(cursor.fetchall())
A3=A3.strip("[('")
A3=A3.strip("',)]")
answer3 = tk.Label(self, text = A3)
answer3.pack()
fetchA4 ="SELECT qanswer4 FROM questions WHERE qnumber=?"
cursor.execute(fetchA4, [self.Qn])
A4=str(cursor.fetchall())
A4=A4.strip("[('")
A4=A4.strip("',)]")
answer4 = tk.Label(self, text = A4)
answer4.pack()
fetchcA ="SELECT correctans FROM questions WHERE qnumber=?"
cursor.execute(fetchcA, [self.Qn])
self.cA=str(cursor.fetchall())
self.cA=self.cA.strip("[('")
self.cA=self.cA.strip("',)]")
def confirmAnswer(self):
answerGiven = self.enterAnswer
correctAnswer = self.cA
if answerGiven == correctAnswer:
self.rightOrWrong.configure(text ="Correct")
self.quizScore = (self.quizScore + 1)
else:
self.rightOrWrong.configure(text="Incorrect")
if self.Qn < self.recNum:
self.Qn = (self.Qn+1)
lambda: controller.show_frame(ques)
else:
self.rightOrWrong.configure(text="Quiz Complete! Your score was: " + str(self.quizScore))
I'm not sure how else i could go about trying to get the contents of the page to change but i hope i can learn from someone else here as nobody around me is very helpful at all (including teachers) and this is the best option I have. Thanks in advance for any help.
I can't test it but I would do something like in code.
In __init__ I create empty labels and execute separated method which reads data from database and puts them in labels. later I can use this method to get next question.
To get one row from database you can use fetchone(). To get data from row you don't have to use str() and strip() but index row[0], row[1], etc. You may have to change indexes if you have columns in different order in database.
class ques(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.Qn = 1
self.quizScore = 0
self.correctAnswer = '' # <-- create it at start (and use better name)
# v-- create empty labels
self.recordNum = tk.Label(self, text='')
self.recordNum.pack()
self.question = tk.Label(self, text='')
self.question.pack()
self.answer1 = tk.Label(self, text='')
self.answer1.pack()
self.answer2 = tk.Label(self, text='')
self.answer2.pack()
self.answer3 = tk.Label(self, text='')
self.answer3.pack()
self.answer4 = tk.Label(self, text='')
self.answer4.pack()
self.update_question_number() # <-- get question number
self.update_question() # <-- get new question
def update_question_number(self)
# Get question's number
query = "SELECT MAX(qnumber) FROM questions"
cursor.execute(query)
row = cursor.fetchone()
self.recordNum['text'] = row[0]
def update_question(self):
# Get new question
query = "SELECT * FROM questions WHERE qnumber=?"
cursor.execute(query, (self.Qn,))
row = cursor.fetchone()
self.question['text'] = row[0]
self.answer1['text'] = row[1]
self.answer2['text'] = row[2]
self.answer3['text'] = row[3]
self.answer4['text'] = row[4]
self.correctAnswer = row[5]
def confirmAnswer(self):
if self.enterAnswer == self.correctAnswer:
self.rightOrWrong['text'] = "Correct"
self.quizScore += 1
else:
self.rightOrWrong['text'] = "Incorrect"
if self.Qn < self.recNum:
self.Qn += 1 # <-- get new question
self.update_question() # <-- get new question
#lambda: controller.show_frame(ques) # ??? do you have to change frame ???
else:
self.rightOrWrong.['text'] = "Quiz Complete! Your score was: {}".format(self.quizScore)

Categories