I am getting not all arguments converted during string formatting, but my code is actually working. Can someone tell me what is wrong with my code?
When I run this, it returns the error, but whenI look at the list wo workes by calling Query_Workers(), it appears that the person I chose had been removed successfully.
def Remove_Directors(id, name):
conn = None
try:
# read the connection parameters
params = config()
# connect to the PostgreSQL server
conn = psycopg2.connect(**params)
cur = conn.cursor()
# create table one by one
#for command in commands:
# cur.execute(command)
SQL = "DELETE FROM directors WHERE id = (%s);"
#cur.execute("DELETE FROM directors WHERE id = (%s)", (id))
id = (id, )
cur.execute(SQL, id)
# close communication with the PostgreSQL database server
cur.close()
# commit the changes
conn.commit()
print ("%s has been removed from Directors.") % (name)
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
def Modify():
print "Choose Options"
option = raw_input("Press A for adding a member, R for removing a member, or V for Viewing members: ")
if option.upper() == "A":
print "Adding a member."
Director_or_EventManager = raw_input("Is the new member a director or an event manager?\nPress D for Director or E for Event Manager:")
if Director_or_EventManager.upper() == "D":
ID_Entered_Correctly = False
while ID_Entered_Correctly == False:
id = raw_input("Enter 10 digit ID: ")
if len(id) == 10:
ID_Entered_Correctly = True
else:
print "Invalid ID"
name = raw_input("Enter Name: ")
Add_Directors(id, name)
if Director_or_EventManager.upper() == "E":
ID_Entered_Correctly = False
while ID_Entered_Correctly == False:
id = raw_input("Enter 10 digit ID: ")
if len(id) == 10:
ID_Entered_Correctly = True
else:
print "Invalid ID"
name = raw_input("Enter Name: ")
Add_Event_Managerss(id, name)
elif option.upper() == "R":
print "Removing a member."
Director_or_EventManager = raw_input("Is the member a director or an event manager?\nPress D for Director or E for Event Manager:")
if Director_or_EventManager.upper() == "D":
conn = None
try:
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
cur.execute("SELECT id, name FROM directors ORDER BY name")
directors = cur.fetchall()
print ("\tNumber\tID\t\tName")
ids = []
names = []
count = 1
for director in directors:
print ("\t%s\t%s\t%s") % (count, director[0], director[1])
ids.append(director[0])
names.append(directors[1])
count += 1
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
count -= 1
num_director = int(raw_input("Enter the number of director to remove: "))
if num_director <= 0 or num_director > count:
print "Invalid entry"
else:
id = ids[num_director - 1]
name = names[ids.index(id)]
print id
print name
Remove_Directors(id, name)
elif option.upper() == "V":
Query_Workers()
else:
print "Invalid option"
The error seems to occur after the query, so it doesn't impact the data change, only the output debugging.
You just need to change those lines :
print ("%s has been removed from Directors.") % (name)
to
print ("%s has been removed from Directors." % name)
and also :
print ("\t%s\t%s\t%s") % (count, director[0], director[1])
to
print ("\t%s\t%s\t%s" % (count, director[0], director[1]))
I am creating an ATM program that stores all registered users in a database and starts them with $500 in cheqings. I have created a function to deposit money but when I run it I get this error
InterfaceError: Error binding parameter 0 - probably unsupported type.
def depositCheq(userID):
while True:
cheqDeposit = input("How much would you like to deposit?: $")
"""try:
c.execute('UPDATE userAccounts SET cheqBal += ? WHERE id = ?',(int(cheqDeposit)), (userID,))
print("Deposit Complete.\n")
break
except:
print("Could not deposit, error!")"""
c.execute('SELECT cheqBal FROM userAccounts WHERE id = ?', (userID,))
cheqBal = (c.fetchone()) + (cheqDeposit,)
c.execute('UPDATE userAccounts SET cheqBal = ? WHERE id = ?', ([cheqBal], [userID]))
conn.commit()
print("Deposit Complete!\n")
def userMenu():
var = input("1: Deposit\n2: Withdrawl\n3: Check Balance\n4: Log Out\n")
if(int(var) == 1):
userIn = input("1: Cheqings\n2: Savings\n")
userName = input("Enter your username: ")
if(int(userIn) == 1):
database.depositCheq(userName)
elif(int(userIn) == 2):
database.depositSav(userName)
When I run the code, the program runs with no errors but leaves a blank space after the asking the 'class number'. I can't tell what's wrong. I've not yet finished with the code so just want to see if it works as it's supposed to but haven't been able to get that far yet.
user_name = input('Enter a name: ')
total_score = 0
x=0
while x<10:
import random
signs = ['+', '-', '*']
sign = random.choice(signs)
num1 = random.randint(1, 10)
num2 = random.randint(1, 10)
print(num1, sign, num2)
answer = int(eval(str(num1) + sign + str(num2)))
userAnswer= int(input("= "))
if userAnswer != answer:
print ("Incorrect. The right answer is {}.".format(answer))
else:
print('Correct')
total_score = total_score +1
x=x+1
if total_score == 10:
print('Wow',user_name,'!','All 10 of your answers were correct!')
else:
print (total_score, 'out of 10 were correct!')
from datetime import datetime
now = datetime.now().strftime('%Y-%m-%d %H:%M')
class_number = int(input('Please enter your class number: '))
import sqlite3
if class_number in ['1','2','3']:
conn = sqlite3.connect('class{}.db')
c = conn.cursor()
c.execute('''CREATE TABLE CLS1
(Username, Score, Date)''')
c.execute("INSERT INTO CLS1 VALUES (user_name, total_score, now)")
conn.commit()
import sqlite3
if class_number in ['1','2','3']:
conn = sqlite3.connect('class{}.db')
print ("Opened database successfully");
cursor = conn.execute("SELECT user_name,total_score, now from CLS1 ")
for row in cursor:
print ("user_name = ", row[0])
print ("total_score = ", row[1])
print ("date text = ", row[2], "\n")
print ("Operation done successfully");
conn.close()
You cast to int then compare to strings inside the list so the if could never evaluate to True
class_number = int(input('Please enter your class number: '))
if class_number in ['1','2','3']:
remove the int:
class_number = input('Please enter your class number: ')
if class_number in ['1','2','3']:
You should also use range instead of your while loop:
import random
for _ in range(10)
The logic for you sqlite also seems a bit off:
import sqlite3
import os
if class_number in ['1', '2', '3']:
db = 'class{}.db'.format(class_number)
query = """
INSERT INTO ClS1 VALUES
(?, ?, ?)
"""
if not os.path.isfile(db):
conn = sqlite3.connect(db)
c = conn.cursor()
c.execute('''CREATE TABLE CLS1 (USERNAME TEXT, SCORE INT, DATE TEXT);''')
conn.execute(query, (user_name, total_score, now))
conn.commit()
else:
conn = sqlite3.connect(db)
print("Opened database successfully")
conn.execute(query, (user_name, total_score, now))
conn.commit()
cursor = conn.execute("SELECT USERNAME, SCORE, DATE FROM CLS1 ")
for row in cursor:
print("user_name = ", row[0])
print("total_score = ", row[1])
print("date text = ", row[2], "\n")
print("Operation done successfully")
conn.close()
My problem is that i have created a maths quiz that will ask the user 10 random questions and then it will output their score out of 10 at the end.I have done this art of the task but i struggle with the last part.The last part is that i need to create something that will store the last 3 scores for each user.I decided to use mysql but my code will only let me store 1 score for each user.I use python 3.4.Here is the code.
import random
import operator
import mysql.connector
cnx = mysql.connector.connect(user='root', password='password',
host='localhost',
database='mydb')
cursor = cnx.cursor()
ID = input("what is your ID?")
OPERATIONS = [
(operator.add, "+"),
(operator.mul, "x"),
(operator.sub, "-")
]
NB_QUESTIONS = 10
def get_int_input(prompt=''):
while True:
try:
return int(input(prompt))
except ValueError:
print("Sorry,but we need a number")
if __name__ == '__main__':
name = input("What is your name?").title()
Class=input("Which class do you wish to input results for 1,2 or 3?")
print(name, ", Welcome to the Maths Test")
score = 0
for _ in range(NB_QUESTIONS):
num1 = random.randint(1,10)
num2 = random.randint(1,10)
op, symbol = random.choice(OPERATIONS)
print("What is", num1, symbol, num2)
if get_int_input() == op(num1, num2):
print("Correct")
score += 1
else:
print("Incorrect")
print("Well done", name, "you scored", score, "/", NB_QUESTIONS)
print ("Thank you for doing this mathamatical quiz , goodbye ")
if "ID" in "Class1":
if "score" in "Score1":
add_record = ("INSERT INTO Class1"
"(Score2)"
"VALUES(%s)")
data_record = (score)
if "score" in "Score2":
add_record = ("INSERT INTO Class1"
"(Score3)"
"VALUES(%s)")
data_record = (score)
else:
add_record = ("INSERT INTO Class1"
"(ID, Name, Score1) "
"VALUES (%s, %s, %s)")
data_record = (ID, name, score)
cursor.execute(add_record, data_record)
cnx.commit()
cursor.close()
cnx.close()
In my databse i have the columns ID,name,score1,score2,score3
when i complete the quiz the score,name and ID will be input into the table.But once the user with the same ID does the quiz there is a error.I want the code to store 3 scores for each user but there is a error.The error is:
cursor.execute(add_record, data_record)
NameError: name 'add_record' is not defined
Thank you for reading this and thank you also for the help.I look forward to hearing the replies.
if "ID" in "Class1":
if "score" in "Score1":
add_record = ("INSERT INTO Class1"
"(Score2)"
"VALUES(%s)")
data_record = (score)
if "score" in "Score2":
add_record = ("INSERT INTO Class1"
"(Score3)"
"VALUES(%s)")
data_record = (score)
else:
add_record = ("INSERT INTO Class1"
"(ID, Name, Score1) "
"VALUES (%s, %s, %s)")
data_record = (ID, name, score)
cursor.execute(add_record, data_record)
cnx.commit()
cursor.close()
cnx.close()
Alright, we are going to step through my solution in the smallest steps possible to reach your solution. Note: All this code in a single file works for me.
First I create a table in the database from Python. I'm not sure why your Average column is an INT type, so I changed that. Also, my ID is an INT just for simplicity.
import mysql.connector
cnx = mysql.connector.connect(user='root', password='password',
host='localhost',
database='mydb')
cursor = cnx.cursor()
# cursor.execute("DROP TABLE IF EXISTS Class1")
cursor.execute('''
CREATE TABLE IF NOT EXISTS Class1
( ID INT PRIMARY KEY
, Name VARCHAR(10) NOT NULL
, Score1 INT
, Score2 INT
, Score3 INT
, Average DECIMAL(9, 5)
);
''')
cnx.commit()
Next, I create a User class in order to hold all the important information and contain the logic to go to & from the database. This way, you only require a single User object and a single method to go each way. This approach is preferred over your multiple INSERT queries.
class User:
def __init__(self, _id, name, score1=None, score2=None, score3=None):
self._id = _id
self.name = name
self.score1 = score1
self.score2 = score2
self.score3 = score3
''' set the score of the given or next available class '''
def add_score(self, score, Class=None):
if not Class or (Class < 0 or Class > 3):
if all((self.score1, self.score2, self.score3)):
return # can't update
elif all((self.score1, self.score2)):
Class = 3
elif self.score1:
Class = 2
else:
Class = 1
if Class and 0 < Class <= 3: # if a position is given and valid
setattr(self, 'score' + str(Class), score)
def to_tuple(self):
return (self._id, self.name, self.score1, self.score2, self.score3)
''' make it possible to see this object when printed '''
def __repr__(self):
return self.__class__.__name__+ str(self.to_tuple())
''' insert or update this user object in the database '''
def insert_to_db(self, db):
crsr = db.cursor()
data = list(self.to_tuple())
data.append(self.get_average_score())
if User.get_by_id(self._id):
data = data[1:]
data.append(self._id)
crsr.execute('''
UPDATE Class1 SET
Name = %s,
Score1 = %s,
Score2 = %s,
Score3 = %s,
Average = %s
WHERE ID = %s;
''', data)
else:
crsr.execute("INSERT INTO Class1 VALUES (%s,%s,%s,%s,%s,%s)", data)
db.commit()
crsr.close()
#staticmethod
def get_by_id(_id):
cursor.execute("SELECT * FROM Class1 WHERE ID = %s", [_id])
row = cursor.fetchone()
return User.from_tuple(row)
#staticmethod
def get_by_name(name):
cursor.execute("SELECT * FROM Class1 WHERE Name = %s", [name])
row = cursor.fetchone()
return User.from_tuple(row)
''' Get the average score from the object. No need to query the database '''
def get_average_score(self):
from statistics import mean
scores = list(self.to_tuple())[2:4]
scores = list(filter(None.__ne__, scores))
return mean(scores) if len(scores) > 0 else 0
#staticmethod
def from_tuple(tup, min_elems=2, max_elems=6):
user = None
if tup:
num_elems = len(tup)
if num_elems < min_elems or num_elems > max_elems:
raise Exception('invalid tuple given', tup)
# know there is at least 2 elements here
user = User(tup[0], tup[1])
if num_elems >= 3:
user.score1 = tup[2]
if num_elems >= 4:
user.score2 = tup[3]
if num_elems >= 5:
user.score3 = tup[4]
return user
#staticmethod
def from_cursor(cursor):
if cursor:
return (User.from_tuple(row) for row in cursor.fetchall())
return iter(()) # Return empty generator if cursor == None
Next, a quiz method is defined that returns the score and name of the person taking the quiz. The parameters are optional and have default values. It is a good habit to define many small methods in order to test your code and logic.
def quiz(num_questions=10, name=None):
if not name:
name = input("Enter your name: ").title()
print(name, ", Welcome to the Maths Test")
score = 0
for _ in range(num_questions):
num1 = random.randint(1,10)
num2 = random.randint(1,10)
op, symbol = random.choice(OPERATIONS)
print("What is", num1, symbol, num2)
if get_int_input() == op(num1, num2):
print("Correct")
score += 1
else:
print("Incorrect")
return name, score
And finally (along with your other methods), this is the main method that will run with the program. This prompts for an ID, tries to find it in the database, then quizzes either an existing user and updates their score, or creates a new user, then inserts the user into the database.
def main():
user_id = get_int_input("Enter your ID: ")
Class = get_int_input("Which class do you wish to input results for 1, 2, or 3? ")
user = User.get_by_id(user_id)
if not user:
print("User with id %d not found" % user_id)
print("Creating new user")
name, score = quiz(NB_QUESTIONS)
user = User(user_id, name)
else:
print("Found user %s" % user.name)
_, score = quiz(NB_QUESTIONS, user)
user.add_score(score, Class)
print("\nWell done", user.name, "you scored", score, "/", NB_QUESTIONS)
print("Thank you for doing this mathamatical quiz , goodbye ")
user.insert_to_db(cnx) # Remember to update the user in the database
cnx.close()
if __name__ == '__main__':
main()
I have a function within my "students' test" program.
This function reads out either the "highest score", "lowest score" or "average score" when you enter the student's name and class number.
The first two parts work but i can't seem to get the average working, when i read a value from a database it never returns like i would prefer it to, it returns it like: [(6,) , (3,)].
This is the function below:
def readScore():
selection = input("What score would you like the read ? \n 1 - Lowest score \n 2 - Highest score \n 3 - Average score... ")
name = input("Please enter the name of the pupil...")
classNo = input("Please enter the class of the pupil...")
myFile = sqlite3.connect("scores.db")
c = myFile.cursor()
c.execute('SELECT score FROM scores WHERE name = (?) AND classNo = (?)', (name, classNo,))
row = c.fetchall()
print(row)
try:
if selection == "1":
print (min(row))
if selection == "2":
print (max(row))
if selection == "3":
print (sum(row) /len(row))
except:
print("No scores for that student")
myFile.commit()
myFile.close()
You could compute the average in your program, but it would be a better idea to avoid fetching all rows, and to let the database compute these values:
c.execute('SELECT MIN(score) FROM ...') # or
c.execute('SELECT MAX(score) FROM ...') # or
c.execute('SELECT AVG(score) FROM ...')
row = c.fetchone()
print(row[0])