My database SQL does not allow me to access a hint - python

It will not allow me to access my hints from my database, an error comes up.
Code:
def do_question(self):
self.func1()
#myGlobal + 1
if myGlobal >5:
import MathsvadersReal
SQL = 'SELECT * FROM tblQuestion'
cursor = Databaseconnector.SELECT(SQL)
rows = cursor.fetchall()
random_row = random.choice(rows)
print random_row.QuestionID, random_row.Question, random_row.Hint, random_row.A1, random_row.A2, random_row.A3, random_row.A4, random_row.CorrectAnswer
# create welcome label
self.label1 = Tkinter.Label(self, bg ='yellow', text = (random_row.Question))
self.label1.grid(row = 0, column = 6, columnspan = 2, sticky = 'E')
self.label111 = Tkinter.Label(self, bg ='red', text = (random_row.QuestionID, "."))
self.label111.grid(row = 0, column = 1, columnspan = 4, sticky = 'W')
Hint Code:
def homepage_link(self):
lbl = self.label111['text']
SQL = 'SELECT Hint FROM tblQuestion WHERE QuestionID = ' + lbl + ''
print SQL
cursor = Databaseconnector.SELECT(SQL)
rows = cursor.fetchall()
#row = rows
tkMessageBox.showinfo("Hint", (row.Hint))
ERROR:
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression 'QuestionID = 9 .'. (-3100) (SQLExecDirectW)")

The value you retrieve from self.label111['text'] is not a valid integer, you should remove the "." at the end of the text:
self.label111 = Tkinter.Label(self, bg ='red', text=random_row.QuestionID)
# ...
SQL = 'SELECT Hint FROM tblQuestion WHERE QuestionID = %s' % self.label111['text']

Related

Unable to insert values

I create a table but I'm not able to insert values. Database class:
import sqlite3
class Database:
word_list = ["RAFAY", "LION", "PANDA", "TIGER", "DOG", "CAT", "RABBIT", "MOUSE", "PENGUIN"]
def __init__(self, db):
self.con = sqlite3.connect(db)
self.cur = self.con.cursor()
self.cur.execute("CREATE TABLE IF NOT EXISTS DICTIONARY (ID INTEGER PRIMARY KEY, WORD TEXT NOT NULL)")
self.con.commit()
def add_valid_guessing_word(self):
for word in self.word_list:
self.insert_valid_guessing_word(word)
# Insert Function
def insert_valid_guessing_word(self, guessing_word):
cursor = self.con.cursor()
cursor.execute("INSERT INTO DICTIONARY VALUES (NULL,?)", (guessing_word,))
print("Inserted Data")
self.con.commit()
# Get a Record in DB
def get_valid_guessing_word(self, id):
cursor = self.con.cursor()
cursor.execute("SELECT * FROM DICTIONARY WHERE id=?", (id,))
valid_word = self.cur.fetchone()
print(valid_word)
return valid_word
Main code:
from tkinter import *
from tkinter import messagebox
from string import ascii_uppercase
import random
import sqlite3
from sqdb import Database
window = Tk()
window.title("Hangman")
db = Database("Goiyala.db")
photos = [PhotoImage(file="images/hang0.png"), PhotoImage(file="images/hang1.png"), PhotoImage(file="images/hang2.png"),
PhotoImage(file="images/hang3.png"),
PhotoImage(file="images/hang4.png"), PhotoImage(file="images/hang5.png"), PhotoImage(file="images/hang6.png"),
PhotoImage(file="images/hang7.png"),
PhotoImage(file="images/hang8.png"), PhotoImage(file="images/hang9.png"),
PhotoImage(file="images/hang10.png"), PhotoImage(file="images/hang11.png")]
def newGame():
messagebox.showinfo("Welcome to Hangman","By Roman & Ricario")
global the_word_withSpaces
global numberOfGuesses
global the_word
numberOfGuesses = 0
imgLabel.config(image=photos[0])
value = db.get_valid_guessing_word(random.randint(1, 7))
the_word = str(value[-1])
print(the_word)
the_word_withSpaces = " ".join(the_word)
lblWord.set(" ".join("_" * len(the_word)))
def guess(letter):
global numberOfGuesses
if numberOfGuesses < 11:
txt = list(the_word_withSpaces)
guessed = list(lblWord.get())
if the_word_withSpaces.count(letter) > 0:
for c in range(len(txt)):
if txt[c] == letter:
guessed[c] = letter
lblWord.set("".join(guessed))
if lblWord.get() == the_word_withSpaces:
messagebox.showinfo("Hangman", "You Guessed it")
newGame()
else:
numberOfGuesses += 1
imgLabel.config(image=photos[numberOfGuesses])
if numberOfGuesses == 11:
toast_message = "Game Over! " \
"The Correct answer is {}".format(the_word)
messagebox.showwarning("Hangman", toast_message)
imgLabel = Label(window)
imgLabel.grid(row=0, column=0, columnspan=3, padx=10, pady=40)
imgLabel.config(image=photos[0])
lblWord = StringVar()
Label(window, textvariable=lblWord, font="Consolas 24 bold").grid(row=0, column=3, columnspan=6, padx=10)
n = 0
for c in ascii_uppercase:
Button(window, text=c, command=lambda c=c: guess(c), font="Helvetica 18", width=4).grid(row=1 + n // 9, column=n % 9)
n += 1
Button(window, text="new\nGame", command=lambda: newGame(), font="Helvetica 10 bold").grid(row=3, column=8,
sticky="NSWE")
newGame()
window.mainloop()
Error :
Traceback (most recent call last):
File "C:\Users\Rufez\PycharmProjects\HangmanRicarioRoman2\game.py", line 128, in <module>
hangman = Game(touch.get_valid_word_to_be_execute())
File "C:\Users\Rufez\PycharmProjects\HangmanRicarioRoman2\game.py", line 41, in get_valid_word_to_be_execute
the_word = str(value[-1])
TypeError: 'NoneType' object is not subscriptable
You can't re-use the cursor.
Declare a local cursor each time:
# Get a Record in DB
def get_valid_guessing_word(self, id):
cursor = self.con.cursor() # <<-- HERE new cursor
cursor.execute("SELECT * FROM DICTIONARY WHERE id=?", (id,))
valid_word = cursor.fetchone()
print(valid_word)
return valid_word
As #kuro has pointed out in multiple comments, at no time does the Database.add_valid_guessing_word() function get called in the code. So the table is empty, so the call to db.get_valid_guessing_word(random.randint(1, 7)) returns None. This is not a list-type, hence the error.
Modify your code to put the Animals into the database:
window.title("Hangman")
db = Database("Goiyala.db")
db.add_valid_guessing_word() # <<-- HERE Populate the database
But this will continually add the words, so perhaps check to see if it's not empty first, something like:
window.title("Hangman")
db = Database("Goiyala.db")
if ( db.get_valid_guessing_word( 0 ) == None ):
db.add_valid_guessing_word() # <<-- HERE Populate IFF empty
Then you can also do a debug-dump of the database:
class Database:
# ...
def dumpAnimals( self ):
""" Debug function to dump the Animal Dictionary Table """
cursor = self.con.cursor()
cursor.execute( "SELECT id, word FROM Dictionary ORDER BY word" )
for row in cursor.fetchall():
if ( row == None ):
print( "Dictionary Table is empty" )
break
else:
id_num, word = row
print( "id=%3d, word=[%s]" % ( id_num, word ) )
Using this like:
window.title("Hangman")
db = Database("Goiyala.db")
if ( db.get_valid_guessing_word( 0 ) == None ):
db.add_valid_guessing_word() # <<-- HERE Populate IFF empty
db.dumpAnimals() # <<-- HERE Check we have data

how can I find out what button has been selected

I have a piece of code in python which generates buttons dependant on the rooms in a list in my database. I would like the code to return the room name on the button that I have selected and use it to store data in my database for that button
class buttongen():
def __init__(self,i,row):
self.i = i
self.row = row
self.roomname = self.row[0]
roomclicked = self.roomname
self.btn = Button(screen13, text=self.roomname, command=lambda :print("self.roomname"))
self.btn.grid(row=i, column=0)
Here is the class for each button and below is the code which gets the list of room names and prints them out as buttons. Is there a way I can store the text and use either .cget() or get() to return the name of the room
def search():
global screen13
global btn
global roomclicked
screen13 = Tk()
screen13.geometry("300x250")
screen13.title("Rooms")
sitename3_info = sitename.get().strip()
if sitename3_info:
cursor = cnn.cursor()
# combine the two SQL statements into one
sql = ("SELECT roomname FROM rooms, Sites "
"WHERE rooms.siteID_fk2 = Sites.siteID AND siteName = %s")
cursor.execute(sql, [sitename3_info])
rooms = cursor.fetchall()
# remove previous result (assume screen13 contains only result)
for w in screen13.winfo_children():
w.destroy()
if rooms:
for i, row in enumerate(rooms):
buttongen(i, row)
roomname = row[0]
roomclicked = roomname
btn = Button(screen13, text=roomname, command=lambda room=roomname: action(room))
btn.grid(row=i, column=0)
else:
Label(screen13, text="No room found").grid()
EDIT
this is the block to create the audit
def createaudit():
sitename2_info = sitename.get()
print(sitename2_info)
name2_info = name2.get()
print(name2_info)
name3_info = name3.get()
print(name3_info)
# Sql code for writing the data that was written in the regsitering page.
cursor = cnn.cursor()
# the site query matches the inputted username with the corresponding userID and inserts the userID into userID_fk
siteIDQuery = "SELECT siteID FROM Sites WHERE siteName = %s"
cursor.execute(siteIDQuery, [sitename2_info])
siteID_fetch = cursor.fetchall()
print(siteID_fetch[0][0])
sitequery = "INSERT INTO `audit`(`siteID_fk`, `auditor1`, `auditor2`) VALUES (%s, %s, %s)"
sitequery_vals = (siteID_fetch[0][0], name2_info, name3_info)
cursor.execute(sitequery, sitequery_vals)
# prints how many rows were inserted to make sure values are put into the database
print(cursor.rowcount)
cnn.commit()
if siteID_fetch:
for i in siteID_fetch:
search()
break
else:
failed2()
this is the block to print out the rooms within the site that's going to be audited
def search():
screen13 = Tk()
screen13.geometry("300x250")
screen13.title("Rooms")
sitename3_info = sitename.get().strip()
if sitename3_info:
cursor = cnn.cursor()
# combine the two SQL statements into one
sql = ("SELECT roomname FROM rooms, Sites "
"WHERE rooms.siteID_fk2 = Sites.siteID AND siteName = %s")
cursor.execute(sql, [sitename3_info])
rooms = cursor.fetchall()
# remove previous result (assume screen13 contains only result)
for w in screen13.winfo_children():
w.destroy()
if rooms:
for i, row in enumerate(rooms):
roomname = row[0]
btn = Button(screen13, text=roomname, command=lambda room=roomname: action(room))
btn.grid(row=i, column=0)
else:
Label(screen13, text="No room found").grid()
This is the block of code where I wish to answer questions for the room and store the answers in my database for it
def action(roomname):
global screen15
screen15 = Tk()
screen15.geometry("300x250")
screen15.title("Rooms")
global q1
global q2
global q3
q1 = StringVar()
q2 = StringVar()
q3 = StringVar()
Label(screen15, text = "Please enter details below", bg = "LightSkyBlue1", width = "300", height = "2").pack()
Label(screen15, text = "").pack()
Label(screen15, text = "01. Commodes CLEANING").pack()
q1_entry = Entry(screen15, textvariable = q1)
q1_entry.pack()
Label(screen15, text = "02. commodes NURSING").pack()
q2_entry = Entry(screen15, textvariable = q2)
q2_entry.pack()
Label(screen15, text = "03. Bathroom Hoists CLEANING").pack()
q3_entry = Entry(screen15, textvariable = q3)
q3_entry.pack()
Button(screen15, text = "Create an Audit", width = "12", height = "1", command = storescore).pack()
def storescore():
roomname2_info = buttongen(self.roomname).cget()
print(roomname2_info)
sitenameInfo = sitename.get()
# sql to store answer values
cursor = cnn.cursor()
siteID_fetch4 = "SELECT siteID FROM Sites WHERE siteName = %s"
cursor.execute(siteID_fetch4, [sitenameInfo])
siteID_fetch4 = cursor.fetchall()
print(siteID_fetch4[0][0])
roomsFID = "SELECT roomID FROM rooms WHERE siteID_fk2 = %s AND roomname = %s"
cursor.execute(roomsFID, [(siteID_fetch4[0][0]), (roomname2_info)])
roomsFID = cursor.fetchall()
print(roomsFID[0][0])
Code below will do the trick perfectly (just adjust it to your needs):
import tkinter as tk
def safe_to_sql(number):
print("Saving room {} into SQL ...".format(number))
#Save whatever you want
def addButton(window, buttons, room):
new_button = tk.Button(window, text = "Room:" + room, command = lambda: safe_to_sql(room))
new_button.pack()
buttons.append(new_button)
my_buttons = []
rooms = ["Room 1", "Super room 2", "Ever better one"]
window = tk.Tk()
for room in rooms:
addButton(window, my_buttons, room)
window.mainloop()
We are creating dynamical buttons.
To each button we connect this lambda function: command = lambda: safe_to_sql(room).

Error with parameters in Python with SQLite3 TypeError: unsupported operand type(s) for +: 'sqlite3.Cursor' and 'str'

I am a beginner in coding and this new community.I need your help to understand why it is not possible to get this solution. I would like to get a number from an entry and then sum up with the last record of the same item, so I can aggregate it.
Here is my code:
def add_stock(self):
time = datetime.now().strftime("%B %d, %Y")
hour = datetime.now().strftime("%I:%M%p")
query = 'SELECT totalstock FROM stocks WHERE name = ? AND MovementID = ( SELECT max( MovementID ) FROM stocks)'
parameters = (self.name.get(),)
lastrecord = self.run_query(query, parameters)
total = lastrecord + self.quantity.get()
if self.validation():
query = 'INSERT INTO stocks VALUES(NULL, ?, ?, ?, ?, ?)'
parameters = (self.name.get(), self.quantity.get(), total, time, hour)
self.run_query(query, parameters)
self.message['text'] = 'Movement {} added succesfully'.format(self.name.get())
self.name.delete(0, END)
self.quantity.delete(0, END)
else:
self.message['text'] = 'Name and Quantity required'
self.get_product()
But there is something wrong with it, can anybody help me out?
This is the entire code:
from tkinter import *
from tkinter import ttk
from datetime import datetime
import sqlite3
class Main:
db_name = 'materiales.db'
def __init__(self,window):
self.wind = window
self.wind.title('Stock App')
#create frame
frame = LabelFrame(self.wind, text = 'Add stock')
frame.grid(row = 0, column = 0, columnspan = 3, pady = 20)
# Name Input
Label(frame, text = 'Name: ').grid(row = 1, column = 0)
self.name = Entry(frame)
self.name.focus()
self.name.grid(row = 1, column = 1)
# Quantity Input
Label(frame, text = 'Quantity: ').grid(row = 2, column = 0)
self.quantity = Entry(frame)
self.quantity.grid(row = 2, column = 1)
# Button Add Stock
ttk.Button(frame, text = 'Add Stock', command = self.add_stock).grid(row = 3, columnspan = 2, sticky = W + E)
#Log Message
self.message = Label(text = '', fg = 'red')
self.message.grid(row = 3, column = 0, columnspan = 2, sticky = W + E)
# Table
self.tree = ttk.Treeview(height = 10, columns = 2)
self.tree.grid(row = 4, column = 0, columnspan = 2)
self.tree.heading('#0', text = 'Name', anchor = CENTER)
self.tree.heading('#1', text = 'Stock', anchor = CENTER)
#Buttons
ttk.Button(text = 'DELETE', command = self.delete_product).grid(row = 5, column = 0, sticky = W + E)
ttk.Button(text = 'MODIFY', command = self.modify_product).grid(row = 5, column = 1, sticky = W + E)
self.get_product()
def run_query(self, query, parameters = ()):
with sqlite3.connect(self.db_name) as conn:
cursor = conn.cursor()
result = cursor.execute(query, parameters)
conn.commit()
return result
def get_product(self):
records = self.tree.get_children()
for element in records:
self.tree.delete(element)
query = 'SELECT * FROM product ORDER BY name DESC'
db_rows = self.run_query(query)
for row in db_rows:
self.tree.insert('', 0, text = row[1], values = row[2])
def validation(self):
return len(self.name.get()) != 0 and len(self.quantity.get()) !=0
def add_stock(self):
time = datetime.now().strftime("%B %d, %Y")
hour = datetime.now().strftime("%I:%M%p")
query = 'SELECT totalstock FROM stocks WHERE name = ? AND MovementID = ( SELECT max( MovementID ) FROM stocks)'
parameters = (self.name.get(),)
lastrecord = self.run_query(query, parameters)
total = lastrecord + self.quantity.get()
if self.validation():
query = 'INSERT INTO stocks VALUES(NULL, ?, ?, ?, ?, ?)'
parameters = (self.name.get(), self.quantity.get(), total, time, hour)
self.run_query(query, parameters)
self.message['text'] = 'Movement {} added succesfully'.format(self.name.get())
self.name.delete(0, END)
self.quantity.delete(0, END)
else:
self.message['text'] = 'Name and Quantity required'
self.get_product()
def delete_product(self):
try:
self.tree.item(self.tree.selection())['text'][0]
except IndexError as e:
self.message['text'] = 'Please Select a Record'
return
name = self.tree.item(self.tree.selection())['text']
query = 'DELETE FROM product WHERE name = ?'
self.run_query(query,(name,))
self.message['text'] = 'Product {} deleted succesfully'.format(name)
self.get_product()
def modify_product(self):
try:
self.tree.item(self.tree.selection())['text'][0]
except IndexError as e:
self.message['text'] = 'Please Select a Record'
return
name = self.tree.item(self.tree.selection())['text']
old_price = self.tree.item(self.tree.selection())['values'][0]
self.edit_wind = Toplevel()
self.edit_wind.title = 'Edit Product'
#Old Name
Label(self.edit_wind, text = 'Old Name: ').grid(row = 0, column = 1)
Entry(self.edit_wind, textvariable = StringVar(self.edit_wind, value = name), state = 'readonly').grid(row = 0, column = 2)
#New Name
Label(self.edit_wind, text = 'New Name: ').grid(row = 1, column = 1)
new_name = Entry(self.edit_wind)
new_name.grid(row = 1, column = 2)
#Old Price
Label(self.edit_wind, text = 'Old Price: ').grid(row = 2, column = 1)
Entry(self.edit_wind, textvariable = StringVar(self.edit_wind, value = old_price), state = 'readonly').grid(row = 2, column = 2)
#New Price
Label(self.edit_wind, text = 'New Price: ').grid(row = 3, column = 1)
new_price = Entry(self.edit_wind)
new_price.grid(row = 3, column = 2)
Button(self.edit_wind, text = 'Update', command = lambda: self.edit_records(new_name.get(), name, new_price.get(), old_price)).grid(row = 4, column = 2, sticky = W)
def edit_records(self, new_name, name, new_price, old_price):
query = 'UPDATE product SET name = ?, precio = ? WHERE name = ? AND precio = ?'
parameters = (new_name, new_price, name, old_price)
self.run_query(query, parameters)
self.edit_wind.destroy()
self.message['text'] = 'Record {} updated successfully'.format(name)
self.get_product()
if __name__ == '__main__':
window = Tk()
application = Main(window)
window.mainloop()
Thanks in advance and kind regards.
The exception is raised on line 72 of your code. The code attempts to add a string object to a sqlite.Cursor object, which fails because these types are incompatible for that operation.
Instead you need to extract the data held in the returned Cursor object which can be done like this:
total = lastrecord.fetchone()[0]
fetchone() returns the first row of the data which is of type tuple. The first item in the tuple is the queried value, which is assumed to be an integer in this case. You can't add the string returned by self.quantity.get(), so you need to convert that to an integer (assuming that it is an integer.. it could be another numeric type) to calculate the new total:
total += int(self.quantity.get())

I get an error when changing data in SQlite; Python

I'm trying to save new data in sqlite and get an error.
Code:
def saveChanges(player_to_save, player_id):
db = sqlite3.connect('db_player.db')
sql = db.cursor()
sql.execute(f"""UPDATE users SET (lvl = {player_to_save.lvl}, exp = {player_to_save.exp}, hp = {player_to_save.hp}, items = {converToJson_items(player_to_save)}, weapon = {convertToJson_weapon(player_to_save)}, armour = {convertToJson_armour(player_to_save)}, bounus = {convertToJson_bounus(player_to_save)}, bonuses_award = {convertToJson_bonuses_award(player_to_save)}, stats = {converToJson_stats(player_to_save)} ) WHERE login = '{player_id}'""")
Error:
line 384, in saveChanges
sql.execute(f"""UPDATE users SET (lvl = {player_to_save.lvl}, exp = {player_to_save.exp}, hp = {player_to_save.hp}, items = {converToJson_items(player_to_save)}, weapon = {convertToJson_weapon(player_to_save)}, armour = {convertToJson_armour(player_to_save)}, bounus = {convertToJson_bounus(player_to_save)}, bonuses_award = {convertToJson_bonuses_award(player_to_save)}, stats = {converToJson_stats(player_to_save)} ) WHERE login = '{player_id}'""")
sqlite3.OperationalError: near "=": syntax error
How can i fix it?
Use this syntax-
sql.execute('''UPDATE tablename SET v1 = ?, v2 = ? where c1 = ?;''', (new_val1, new_val2, condition))

How to select a data like 100 without [(100),] from postgresql using python?

I have a table that has only 1 row, I only need to update the data in the first row. I need to preview the data at the startup like Total Wealth :- 2000 Cash :- 0 Savings :- 2000. But it previews like shown below. enter image description here So please give me a solution for this.
from tkinter import *
import psycopg2
try:
connection = psycopg2.connect(user="postgres",
password="postgres",
host="localhost",
port="5432",
database="money_db")
cursor = connection.cursor()
query_cash = "select cash from main where index = 1;"
query_savings = "select savings from main where index = 1;"
cursor.execute(query_cash)
cash = cursor.fetchall()
cursor.execute(query_savings)
savings = cursor.fetchall()
t_w = (cash + savings)
cursor.execute("commit;")
if (connection):
cursor.close()
connection.close()
print("PostgreSQL connection is closed")
except (Exception, psycopg2.Error) as error:
print("Error while fetching data from PostgreSQL", error)
root = Tk()
root.geometry("900x500")
root.resizable(width=False, height=False)
t_w_lbl = Label(text="Total Wealth = " + str(t_w), font=("Calibry", 14), bg="white")
t_w_lbl.place(rely=0.04, relx=0.1)
cash_lbl = Label(text="Cash = " + str(cash), font=("Calibry", 14), bg="white")
cash_lbl.place(rely=0.04, relx=0.45)
photo = PhotoImage(file = "exchange.png")
exchange_btn = Button(image = photo, command = lambda: exchange())
exchange_btn.place(relx = 0.64, rely = 0.03, height = 35, width = 50)
savings_lbl = Label(text="Savings = " + str(savings), font=("Calibry", 14), bg="white")
savings_lbl.place(rely=0.04, relx=0.8)`
You should use the fetchone method instead and unpack the returning tuple (note the added comma).
Change:
cash = cursor.fetchall()
...
savings = cursor.fetchall()
to:
cash, = cursor.fetchone()
...
savings, = cursor.fetchone()

Categories

Resources