function not working using sql and tkinter (quiz) - python

On the function, confirmAnswer, it updates the question but doesn't display to the user whether their answer is correct or inccorrect which makes me think it is skipping straight to this line, if self.Qn < self.recordNum['text']: on the same function.
I only have two questions in the database at the moment allowing testing to be easier and when the question updates, the submit button doesnt work when an answer is inputted when really the quiz should end and display the score which is in the same function.
I included this much code as I thought it would make more sense to understand the code so sorry if it is too much and sorry if it comes across confusing. Thank you for your help!
def quiz(self):
self.newf.pack_forget()
self.head['text'] = 'Welcome to the psychology revision quiz'
self.quizf.pack()
self.quizScore = 0
self.correctAnswer = '' # <-- create it at start (and use better name)
self.Qn = 1
self.update_question()# <-- get new question
self.update_question_number()
def update_question_number(self):
# Get question's number
query = "SELECT MAX(qnumber) FROM questions"
c.execute(query)
row = c.fetchone()
self.recordNum['text'] = row[0]
def update_question(self):
# Get new question
query = "SELECT * FROM questions WHERE qnumber=?"
c.execute(query, (self.Qn,))
row = c.fetchone()
self.question['text'] = row[1]
self.answer1['text'] = row[2]
self.answer2['text'] = row[3]
self.answer3['text'] = row[4]
self.answer4['text'] = row[5]
self.correctAnswer = row[6]
def confirmAnswer(self):
self.rightOrWrong = self.enterAnswer
if self.enterAnswer == self.correctAnswer:
self.rightOrWrong['text'] = "Correct"
self.quizScore += 1
self.update_question()
else:
self.rightOrWrong['text'] = "Incorrect"
if self.Qn < self.recordNum['text']:
self.Qn += 1 # <-- get new question
self.update_question() # <-- get new question
else:
self.rightOrWrong['text'] = "Quiz Complete! Your score was: {}".format(self.quizScore)

Related

Label not changing in window - tkinter

I have this code that I'm following from a video. This is a function that gets activated when a button is pressed. In some parts I want to erase the previous output in a label every time the button is pressed:
# Search customers
def search_customers():
search_customers = Tk()
search_customers.title("Search Customers")
search_customers.geometry("1300x600")
searched_label = Label(search_customers)
searched_label.grid(row=2, column=0)
test = Label(search_customers)
test.grid(row=3, column=0)
def search_now():
# searched_label = Label(search_customers)
# searched_label.grid(row=2, column=0)
selected = drop.get() # This is a Combobox
if selected == 'Search By...':
sql = ""
test['text'] = 'You forgot to pick an option'
elif selected == 'Last Name':
sql = "SELECT * FROM customers WHERE last_name = %s"
elif selected == 'Email Address':
sql = "SELECT * FROM customers WHERE email = %s"
elif selected == 'Customer ID':
sql = "SELECT * FROM customers WHERE user_id = %s"
searched = search_box.get()
name = (searched, )
result = my_cursor.execute(sql, name)
if selected == "Search By...":
result = ''
else:
result = my_cursor.fetchall()
if not result:
result = "Record Not Found"
test['text'] = ''
searched_label['text'] = result
elif result:
test['text'] = ''
searched_label['text] = ''
searched_label = Label(search_customers)
for index, x in enumerate(result):
num = 0
index += 2
for y in x:
searched_label = Label(search_customers, text=y)
searched_label.grid(row=index, column=num)
num += 1
The thing is, every time the code reaches this statement: searched_label['text'] = '', it says: variable referenced before the assignment but that doesn't happen with test['text'] = '' even though both labels are created in the same scope.
The only way it worked was to create searched_label inside the search_now() (see the commented lines and let's pretend to uncomment them and comment the ones above).
With the lines uncommented inside search_now(), when it reaches this statement: if not result, it sets searched_label['text'] = result without a problem, but when it reaches the last elif, it doesn't set searched_label['text'] = '', actually, let's say the code was run and it first reached the if not result: statement so when the button is press again and it reaches the last elif it doesn't erase the previous output with searched_label['text] = ''.
In this last elif, I tried reached_label.grid_remove() and creating the label again but the previous output still remains so it mixes with the new output.
Thanks in advance, I'm still learning and I hope my question is clear enough
If you want to change the texts of Label widgets regularily, it pays to use the parameter textvariable. It takes a StringVar() object that can be changed by any function. As soon as the StringVar gets a new value, the label changes.
I do not see the whole of your program, but this is how it works in general:
def search_customers():
search_customers = Tk()
search_customers.title("Search Customers")
search_customers.geometry("1300x600")
global labeltext
labeltext = StringVar() ## Initiate a string variable
labeltext.set("This is the mutable text")
searched_label = Label(search_customers,textvariable=labeltext)
searched_label.grid(row=2, column=0)
test = Button(search_customers,text="Change it",command=change)
test.grid(row=3, column=0)
def change():
labeltext.set("This is a new text")
If the program gets more complicated, you might also consider defining the dialog box as a new class, iheriting from Frame. There, you can define methods that have access to all widgets and variables without the need of global variables.
I can't help you. Actually, need more information. I am using match case statements instead of if/else.
Code:
def search_now():
searched_label = Label(search_customers)
searched_label.grid(row=2, column=0)
selected = drop.get() # This is a Combobox
match selected:
case 'Search By...':
sql = ""
test['text'] = 'You forgot to pick an option'
case 'Last Name':
sql = "SELECT * FROM customers WHERE last_name = %s"
case 'Email Address':
sql = "SELECT * FROM customers WHERE email = %s"
case 'Customer ID':
sql = "SELECT * FROM customers WHERE user_id = %s"
searched = search_box.get()
name = (searched, )
result = my_cursor.execute(sql, name)
if selected == "Search By...":
result = ''
else:
result = my_cursor.fetchall()
if not result:
result = "Record Not Found"
#test['text'] = ''
searched_label.config{text=result)
elif result:
#test['text'] = ''
searched_label.config(text='')
#searched_label = Label(text=search_customers)
for index, x in enumerate(result):
num = 0
index += 2
for y in x:
#searched_label = Label(search_customers, text=y)
searched_label.config(text=y)
Let me know if this work.

Flask-sqlalchemy add numbers on button click

Hai so i am trying to increase a number ( +1 ) in my join column on button click on flask so far i done up to this
#app.route("/joins/<name>", methods=["POST"])
def joins(name):
namess = name
owner = users.query.filter_by(name=namess).first()
if owner is not None:
#making the joins +1 if the value is already 1
owner.joins = + 1
db.session.commit()
return redirect("/")
else:
return "You are not the owner of this url"
but it is not increasing the number how can i fix this happy coding!
The line
owner.joins = + 1
is valid python but I don't think it's what you want. It just assigns 1 to owner.joins. If you want to increment you need to do it like this:
owner.joins = owner.joins + 1

How can I delete a row from .csv file

I am a new learner in python trying to understand the logic and the solution of this problem.Exercise says to create an order app for a coffee shop .
import uuid # GET A RANDOM ID FOR THE CUSTOMER
from datetime import date # GET CURRENT DATE
from csv import DictWriter
inlist = -1
length = 0
Total_Amount = 0.0
CustomerList = []
AddressList = []
Today_Key = date.toordinal(date.today())
Today_Date = date.today()
Print_Today = Today_Date
Customers = {}
Dates = {}
FirstEmployeeAccountUsername = "coffee1"
FirstEmployeeAccountPassword = "coffeeshop1"
SecondEmployeeAccountUsername = "coffee2"
SecondEmployeeAccountPassword = "coffeeshop2"
ThirdEmployeeAccountUsername = "coffee3"
ThirdEmployeeAccountPassword = "coffeeshop3"
print("Welcome to our coffee shop!")
print("Login")
# EMPLOYEE LOGIN PROCESS STARTS
LoginEnter = True
while LoginEnter:
username = input("Username: ")
password = input("Password: ")
if username == FirstEmployeeAccountUsername and password == FirstEmployeeAccountPassword or username == SecondEmployeeAccountUsername and password == SecondEmployeeAccountPassword or username == ThirdEmployeeAccountUsername and password == ThirdEmployeeAccountPassword:
print("Login Successful")
LoginEnter = False
else:
print("Invalid Login. Try again")
# EMPLOYEE LOGIN PROCESS ENDS
# PROCESS AFTER ORDER PLACEMENT STARTS
process1 = True
process2 = True
while process1:
while process2:
Customer_Name = input("Customer's Name:")
CustomerList.append(Customer_Name)
Customers_Address = input("Customer's Address:")
AddressList.append(Customers_Address)
if Today_Key not in Dates:
Dates[Today_Key] = {}
if Customer_Name not in Dates[Today_Key]:
Dates[Today_Key][Customer_Name] = 1
else:
Dates[Today_Key][Customer_Name] += 1
if Customer_Name in Customers:
Customers[Customer_Name]['Orders'] += 1
Customers[Customer_Name]['TotalAmount'] = Total_Amount
else:
Customers[Customer_Name] = {}
Customers[Customer_Name]['Address'] = Customers_Address
Customers[Customer_Name]['ID'] = uuid.uuid1()
Customers[Customer_Name]['Orders'] = 1
Customers[Customer_Name]['TotalAmount'] = 0
print(Customer_Name, "has ordered {} time(s)".format(Customers[Customer_Name]['Orders']))
if Customers[Customer_Name]['TotalAmount'] == 0:
print("This is the first time", Customer_Name, "orders")
else:
print(Customer_Name, "has spent", Customers[Customer_Name]['TotalAmount'], "in total")
print("Current Date is: {}".format(Today_Date))
Order_Price = float(input("Total amount of order:"))
Total_Amount = Order_Price + Total_Amount
if Print_Today != Today_Date:
print("Total amount of orders today is: ", float(Total_Amount))
answer1 = input("Send another order? (Y/N)").lower()
if answer1 == "y":
process2 = True
else:
process2 = False
LengthCustomersList = len(CustomerList)
length += 1
inlist += 1
file = open('CustomerNames.txt', 'w')
file.write(str(CustomerList[0:]) + '\n') # TAKE CARE FOR DUPLICATE NAMES FROM SAME ADDRESS
file.close()
file1 = open('Orders_Per_Users.txt', 'a')
file1.write(Customer_Name + " has ordered " + str(
Customers[Customer_Name]['Orders']) + " times in total\n") # FIX DUPLICATES SAME NAME SAME ADDRESS
file1.close()
with open('data_entered.csv', 'a') as f:
csv_writer = DictWriter(f, fieldnames=['Customer Name', 'Customer Address', 'Customer ID', 'Total Orders',
'Total Amount'])
csv_writer.writeheader()
csv_writer.writerows([{'Customer Name': CustomerList[inlist], 'Customer Address': AddressList[inlist],
'Customer ID': Customers[Customer_Name]['ID'],
'Total Orders': Customers[Customer_Name]['Orders'],
'Total Amount': Customers[Customer_Name]['TotalAmount']}])
if int(length) == int(LengthCustomersList):
process1 = False
My idea is to do something like an if statement so when the same Customer ID and the same CustomerName show up in the .csv file , one of them gets deleted, so the file does not contain any duplicates like those in the screenshot above.
I am not sure we are going to eventually solve your question but I wanted to give you some inputs that you can use to fix your code.
Use of variable Today_Date and Print_Today in your code
Today_Date = date.today()
Print_Today = Today_Date
if Print_Today != Today_Date:
These two lines are set to the same value. Later on in the code, you are checking if the are not equal. I checked Print_Today and Today_Date for reassignment. None occurs. So how do you expect these two variables to have different values?
If this program runs for infinite number of days, it will still NOT change the value of these two variables. The reason is they were defined at the beginning of the program and never changed. You may want to look into it.
The use of Today_Key in Dates dictionary in your code.
Today_Key = date.toordinal(date.today())
Dates = {}
You are using Today_Key to count the number of times a customer name was entered. I don't see a point in having Today_Key as the key unless you plan to have more than one key in the dictionary. This was set at the beginning of the program and never changed. So what do you intend to do with this key? I don't think you should have that as key. Instead you should just keep track of the customer names. Also, you are not printing or writing this information into a file. Are you intending to use this later in the program? I dont see the value and it may just be using up memory space and processing time.
Use of multiple names for Username & Password.
You have created 6 variables to store username & password. In other places, you are using dictionary. So why are you not taking advantage of the dictionary here?
FirstEmployeeAccountUsername = "coffee1"
FirstEmployeeAccountPassword = "coffeeshop1"
SecondEmployeeAccountUsername = "coffee2"
SecondEmployeeAccountPassword = "coffeeshop2"
ThirdEmployeeAccountUsername = "coffee3"
ThirdEmployeeAccountPassword = "coffeeshop3"
Instead of these, can't you just define a dict variable and check for the value as shown below?
UserLogin = {"coffee1":"coffeeshop1", "coffee2": "coffeeshop2", "coffee3": "coffeeshop3"}
username = password = ''
while True:
username = input("Username: ")
password = input("Password: ")
if (username in UserLogin) and (UserLogin[username] == password):
print("Login Successful")
break
else:
print("Invalid Login. Try again")
For your customer name counter portion, try this. I dont think you are actually doing anything with the counter. If you are, this code is much simpler.
CustomerCounts = defaultdict(int)
while True:
Customer_Name = input("Customer's Name:")
CustomerList.append(Customer_Name)
Customers_Address = input("Customer's Address:")
AddressList.append(Customers_Address)
CustomerCounts[Customer_Name] += 1
similarly, try using defaultdict and reduce a lot of code you have written. In the end, there is lot of code optimization and logic corrections you can do. However, it does not solve the infinite loop situation.

python: comparing equivalent coordinates

I am doing a maths quiz for my coursework based around differentiation and integration using python 3. I'm finding it difficult to check if the answer, typed in by the user, is correct. I'm currently using the code below. However, if the user types in answer but in a different order it is treated as incorrect. for example if the answer was (2,4) but I typed in (4/2,4) it would be treated as incorrect despite both answers being correct. I've tried using sympify but it isnt working. How would I overcome this issue?
def Question4(self):
QID = 109
conn = mysql.connector.connect(user="root", password = "", host = "")
mycursor = conn.cursor()
#mysql query
query = """
SELECT
QText, QAnswer, Marks
FROM
QuestionInfo.Question
WHERE
QID = %s
"""
mycursor.execute(query, (QID, ))
Question4, Answer4, Mark4 = mycursor.fetchone()
self.Answer4 = str(Answer4)
self.Mark4 = Mark4
self.next_question.clicked.connect(self.HandleQuestion4)
def HandleQuestion4(self):
#for validation
reply = QtGui.QMessageBox.question(self, 'Message',
"Are you sure this is your final answer?", QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No, QtGui.QMessageBox.Yes)
#get users answer in a sympy state
self.UAnswer4 = self.Answer.text().replace("^", "**")
if reply == QtGui.QMessageBox.Yes:
if sympify(self.UAnswer4) == sympify(self.Answer4):
self.score = self.score + self.Mark4
else:
self.score = self.score + 0
self.Question5()
If you are expecting only numbers then you can use S (short for sympify) on the string. Otherwise you might need parse_expr and/or other string processing to to handle additional syntax like implied multiplication and "^" for exponentiation (see sympy.parsing.sympy_parser):
>>> S('4/2,2')
(2, 2)

Why is this code returning an entity when the datastore viewer shows that NO entities of that kind exist?

I want to display a cart page that shows the items the user wants to buy. Before adding an item to the cart, I want to make sure that item has not been already added (as each item is singular and unique).
The way each item is modeled:
class SellModel(db.Model):
user = db.ReferenceProperty(UserModel)
amount = db.StringProperty(required = True)
price = db.StringProperty(required = True)
num = db.IntegerProperty(required = True)
def render(self):
return render_str("sellmodel.html", s = self)
The way each item displayed in the cart is modeled:
class CartModel(db.Model):
user = db.ReferenceProperty(UserModel)
num = db.IntegerProperty(required = True)
def render(self):
return render_str("cartmodel.html", c = self)
the code in the post method of the buy page where i check for item duplication includes
sells = SellModel.all().ancestor(sell_key()).order('price')
and
#did user already put the same item (num) in cart?
item_check = CartModel.all().filter("email = ", email)
item_check = item_check.filter("num = ", num)
item_count = 0
if item_check: #order already added to cart!
self.write("ELLOHAY")
item_count = 1
if item_count == 0:
cart = CartModel(parent = cart_key(), user = user, num = num)
cart.put()
numkey = SellModel.gql('where num = :num', num = num)
derp = numkey.get()
amount = derp.amount
price = derp.price
self.render('newbuy.html', first_name = first_name, amount = amount, price = price)
else:
cart_error = "this order is already in your cart"
self.render("buy.html", cart_error = cart_error, sells = sells)
The problem: no CartModel entities exist yet. Zero. The datastore viewer doesn't even show the CartModel entity kind. Yet when I run this code, sure enough, "ELLOHAY" prints and the buy page is rendered with the error message that the user has already added the order to the cart? Why is item_check returning an entity when it shouldn't?
This line of code is incorrect
if item_check: #
item_check is defined as
item_check = CartModel.all().filter("email = ", email)
item_check = item_check.filter("num = ", num)
At no point do you do a run(), fetch() or get()
At the time of the comparison if item_check item_check is a Query object and will evaluate to true. You need to actually run the query and examine the results - get() is probably a good start.
Also I see a number of other potential issues you will face with eventual consistancy but that isn't what you question is about.
you can do like this -
if item_check.exists():
self.write("ELLOHAY")
item_count = 1
This will not go inside the loop if item_check has no records.

Categories