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)
Related
I'm trying to create a bank account management system where the user can create an account, log in, and withdraw/deposit money from that account.
# PHASE 1 (FILE I/O and Logic of System)
# Initialization of Current Balance ** Current Balance is the same for all users for the sake of simplicity **
myMoney = open("current_balance.txt")
currentBalance = int(myMoney.readline())
# Imports
import sqlite3
# Creation of Bank Account and Notifying User(s) of Current Balance
class Bank_Account:
def __init__(self):
self.balance= currentBalance
print("Welcome to Your Bank Account System!")
# If statements for first screen
def options_1(self):
ch = int(input("1. Create an Account\n2. Log into Your Account\nEnter a Choice: "))
if ch == 1:
self.create()
if ch == 2:
self.Log_in()
def options_2(self):
ch= int(input("1. Withdraw Money from Your Account\n2. Deposit Money to Your Account\nEnter a Choice: "))
if ch == 1:
self.withdraw()
if ch == 2:
self.deposit()
# Function to Create an Account
def create(self):
user_create_input = str(input("Enter a Username:"))
pin_create_input = int(input("Enter a Pin Number:" ))
print("Account successfully created!")
# Function to Log into Account
def Log_in(self):
user_input = str(input("Enter your Username:"))
pin_input = int(input("Enter your Pin Number:"))
print("Welcome", user_input, "!")
# Function to Deposit Money
def deposit(self):
amount=float(input("Enter the amount you want to deposit: "))
self.balance += amount
print("Amount Deposited: ",amount)
# Function to Withdraw Money
def withdraw(self):
amount = float(input("Enter the amount you want to withdraw: "))
if self.balance>=amount:
self.balance-=amount
print("You withdrew: ",amount)
else:
print("Insufficient balance ")
def display(self):
print("Net Available Balance=",self.balance)
# PHASE 2 (With Database) SQLite 3
# Define Connection and Cursor
connection = sqlite3.connect('Bank_Users.db')
cursor = connection.cursor()
# Create Users Table
command1 = """ CREATE TABLE IF NOT EXISTS
bank(pin INTEGER PRIMARY KEY, username text )"""
cursor.execute(command1)
# Add to Users/Bank
cursor.execute("INSERT INTO bank VALUES (7620, 'Kailas Kurup')")
cursor.execute("INSERT INTO bank VALUES (4638, 'Bethany Watkins')")
cursor.execute("INSERT INTO bank VALUES (3482, 'John Hammond')")
cursor.execute("INSERT INTO bank VALUES (3493, 'Melissa Rodriguez')")
cursor.execute("INSERT INTO bank VALUES (9891, 'Kevin Le')")
# Get Results / Querying Database
cursor.execute("SELECT username, pin FROM bank")
results = cursor.fetchall()
print(results)
connection.commit()
# Check Database User Info
def Log_in2():
user_input = str(input("Enter your Username:"))
pin_input = int(input("Enter your Pin Number:"))
for row in cursor.fetchall():
if user_input and pin_input in row:
print ("Welcome", user_input, "!")
else:
print("Invalid Login Credentials")
Log_in2()
# Phase 3 (With GUI) Tkinter
# Creating an object of class
self = Bank_Account()
# Calling functions with that class
self.options_1()
self.options_2()
self.display()
QUESTIONS:
The code I wrote underneath the "# Check Database User Info" isn't checking the user input. When a pin or username that is entered which is not in the database should return "Invalid Credentials" How do I fix this?
Why is this UNIQUE Constraint error happening and what do I do to fix it?
if user_input and pin_input in row:
is not the correct way to test of the two inputs are both in row. It's parsed as:
if user_input and (pin_input in row):
Also, you can't call cursor.fetchall() twice for the same query. cursor.fetchall() only fetches the rows that haven't been fetched yet. Once you call it, all rows have been fetched, so there's nothing left to fetch. If you want to loop over the query results multiple times, you should save the result of fetchall() in a list and use that.
But there's no need to loop over all the rows to tell if the user input is in the table. Get the user input first, and use it in the WHERE clause of the query.
def Log_in2():
user_input = str(input("Enter your Username:"))
pin_input = int(input("Enter your Pin Number:"))
cursor.execute("SELECT COUNT(*) FROM bank WHERE username = ? AND pin = ?", (user_input, pin_input))
(count,) = cursor.fetchone()
if count == 1:
print ("Welcome", user_input, "!")
else:
print("Invalid Login Credentials")
It shows no error and is able to run, but the data in the SQLite table doesn't update. However other update function similar to this work
def seller_edit():
while True:
sellername = str(input("Enter your username: "))
with sqlite3.connect(r"C:\Users\User\Desktop\HFSystem\Assginment\HFuserinfo.db") as connect:
cursor = connect.cursor()
check = "SELECT * FROM sellerinfo WHERE Username = ?"
cursor.execute(check,[sellername])
results = cursor.fetchall()
if results:
Phone = int(input("Enter New Phone No.: "))
Email = str(input("Enter New Email: "))
Address = str(input("Enter New Address: "))
updateseller ="""UPDATE sellerinfo SET Phone = ?, Email=?,Address=? WHERE Username=?"""
cursor.execute(updateseller,[sellername,Phone,Email,Address])
connect.commit()
print("Seller Info Edited!")
connect.close()
seller_info_menu()
break
else:
print("ProductID does not recognised")
option = input("Do you want to try again (y/n): ")
if option.lower() == "n":
seller_info_menu()
break
The order of the parameters inside the tuple of the 2nd argument of cursor.execute() must be the same as the order of the ? paceholders:
cursor.execute(updateseller, (Phone, Email, Address, sellername))
I am currently creating a main menu that acts like a bank account.
def main_menu():
print("Main Menu")
print("0 - Quit")
print("1 - Open Account")
print("2 - Check Balance")
print("3 - Close Account")
loop = True
while loop:
main_menu()
choice = input("Enter your choice: ")
choice = int(choice)
if choice == 0:
exit(loop)
elif choice == 1:
name_on_account = input("Name on account: ")
balance = float(input("Enter Initial Balance: "))
print("---Account successfully created---")
print("Account number:", account_no())
print("Name on account:", name_on_account)
print("Balance:", balance)
print("Account opened on:", now)
cur.execute("""
INSERT INTO account(name_on_account, balance) VALUES
("%s", "%s");""", (name_on_account, balance))
connection.commit()
elif choice == 2:
print("Checking account balance")
account_number = input("Enter account number: ")
print("---Checking account balance---")
print("Account number:", account_number)
cur.execute("""SELECT * from account;
""")
account_no1 = cur.fetchone()
for i in account_no1[0]:
if account_number == i:
cur.execute("""select name_on_account from account where account_no = "%s";
""", (account_number,))
name1 = cur.fetchone()
print(name1)
name2 = ''.join(map(str,name1))
name3 = int(name2)
print("Name on account:", name3)
cur.execute("""select balance from account where account_no = "%s";
""", account_number)
balance1 = cur.fetchone()
balance2 = ''.join(map(str,balance1))
balance3 = int(balance2)
print("Balance:", balance3)
cur.expecute("""select account_open_date from account where account no = "%s";
""", account_number)
date1 = cur.fetchone()
date2 = ''.join(map(str, date1))
date3 = int(date2)
print("Account opened on:", date3)
connection.commit()
else:
print("Error: Invalid account number")
I'm not worried about option 3 as of right now, but I am having trouble with option 2.
When a person pick option 1, they will input their name and the amount of money deposited in their bank account.
This information will be stored in the mysql table account(account_no, name_on_account, balance, account_open_date, account_status).
This means that account_no is auto-incremented, account_open_date is default as curdate(), and account_status is default to be "open").
In option 2 however, when a person input their account number; it should return back all of their information how it is displayed in the option 1.
What I am having trouble with is, how do you efficiently iterate over the person's information using fetchone() and be able to get the specific column information with (account_no = account_number) (if you do have a better suggestion on a better way to implement this, please comment below)
This is the error message that I get:
Traceback (most recent call last):
File "(deleted for privacy purposes)"
for i in account_no1[0]:
TypeError: 'int' object is not iterable
Thank you for the help!
pymysql (and most other python mysql clients) is returning a tuple when you invoke fetchone(), and each entry in the tuple matches up to the datatypes defined in the table that you're querying. So let's look at your code:
elif choice == 2:
print("Checking account balance")
account_number = input("Enter account number: ")
print("---Checking account balance---")
print("Account number:", account_number)
cur.execute("""SELECT * from account""")
account_no1 = cur.fetchone()
for i in account_no1[0]:
Here you're querying all columns and all rows from the account table, reading the first row, and then iterating over whatever is in the first column of that row. But that's probably just an id column, which is probably why you're getting the error that you're getting: integers are not iterable. That'd be like writing for i in 10, Python doesn't understand what that means
If you want to iterate over all of the returned rows, you can do that like this:
cur.execute("""SELECT * from account;
""")
for row i in cur.fetchall():
# Each iteration "row" is a tuple of values corresponding to the table's columns
That's kind of silly though. You'd returning all of the rows from the database and then iterating over them and looking for a specific account number. Why not just do that as part of your query?
nrows = cur.execute("SELECT * from account where account_no=%s", (account_number,))
if nrows == 0:
# Account number not found, do something
else:
row = curs.fetchone()
# row now contains all of the values from the discovered
Note that you don't need to put quotation marks around %s placeholders, and you don't need semicolons. The client does all of this conversion for you.
Also note that you should not select * from tables. What if the table definition changes to include more columns? Just select the handful of columns that you actually need, then if more columns are added to the table later your code won't need to be changed at all and you won't be requesting more data than you need. So more like:
nrows = cur.execute("SELECT name, balance, date_opened from account where account_no=%s", (account_number,))
if nrows > 0:
name, balance, date_opened = curs.fetchone()
The last stretch of my banking project I've been working on is the deposit/withdraw function. I've gotten most of the other bits working (outside of cleaning up the code) I'm not fully understanding how one adds and subtracts a number from a sql statement inside of python...so here's the part of the code I'm struggling with:
here are my tables:
sqlite_file = 'banking2_db.sqlite'
table_1 = 'Bartertown'
table_2 = 'PINs'
id_column = 'Card_Numbers'
column_1 = 'Character_PINs'
column_2 = 'Balances'
column_3 = 'Card_Numbers'
column_4 = 'Characters'
class LoginPrompt:
def Login(self):
while True:
print(menu[1])
self.Card_number=str(input('>> '))
print(menu[2])
while True:
try:
self.Character_PINs = getpass.getpass('>> ')
self.one_row = c.execute('SELECT * FROM {tn} WHERE {cn}=? and {cnn}=?'.\
format(tn=table_1, cn=column_1, cnn=column_3), (self.Character_PINs, self.Card_number,))
for row in self.one_row.fetchone():
print('Welcome: ', row)
input('Press any key to continue... ')
return
except:
print('PIN incorrect; try again')
break
#MINOR ISSUE, ONLY QUERIES CHAR COLUMN
def loginMenu(self):
while True:
print(menu[5])
print("\n1 - Deposit funds")
print("2 - Withdraw funds")
print("3 - Check balance")
print("4 - Reset Pin")
print("5 - Exit")
while True:
try:
choice = int(input("Please enter a number: "))
except ValueError:
print("Please choose a valid entry")
if choice >= 1 and choice <=5:
choice == 1:
amount = input("\nPlease enter the deposit amount: ")
if amount != '' and amount.isdigit():
int(amount)
balance = c.execute('UPDATE {tn} SET {cn} = Balances +:amount WHERE Card_Numbers =:self.Card_number' .\
format(tn=table_1, cn=column_2,))
new_bal = balance + (int(amount))
print('${} has been deposited to account {} and the new balance is ${}'.\
format(amount, self.Card_number, balance + (int(amount))))
for row in self.Balances.fetchone():
print('Your new balance is: ', new_bal)
return self.loginMenu()
basically, I'm trying to make sure the program can only pull the balance where the PIN and the Card Number are specified. It selects the balance (This part is working, it is another option in the menu) however, the UPDATE function is still a mystery to me. I understand how to update both the ENTIRE column...on accident, and also how to change the value presented in the Balance field to the value the user submitted ie: the user selects to deposit 100 caps, and then their balance becomes 100 caps. The column I'm trying to update is called Balances, Card_Numbers is the column containing the users "credit card" and amount is the value the user just entered.
Thank you for your help.
edit: added tables, and initial input of the data.
If you want to update the column Balances then your statement should be:
...SET Balances = Balances + :amount...
so do it like this:
c.execute("UPDATE " + table_1 + " SET Balances = Balances + ? WHERE Card_Numbers = ?", (amount, self.Card_number,))
Finally figured it out, silly me.
choice == 1:
amount = input("\nPlease enter the deposit amount: ")
if amount != '' and amount.isdigit():
int(amount)
balance = c.execute('UPDATE {tn} SET {cn} = Balances +:amount WHERE Card_Numbers =:self.Card_number' .\
format(tn=table_1, cn=column_2,))
new_bal = balance + (int(amount))
I was trying to reference it by printing the output of the of the db while it hadn't been committed yet, :eyeroll:
Thank you for the help forpas, it worked like a charm.
when I run this program, it doesn't change the value in my database. Is it because something is wrong with the options section or is there the other problem? I don"t know what it is, I hope someone can help me with this.
import sqlite3
def product_kopen(crsr):
print ("Which product would you like to buy?")
product = str(input(""))
print ("And how many?")
wanted_amount = int(input(""))
crsr.execute("SELECT * FROM emp")
rows = crsr.fetchall()
for row in rows:
if row[0] == product:
actual_amount = int(row[1])
fetched_amount = actual_amount - wanted_amount
kopen = "UPDATE emp SET Amount = {amount} WHERE Product = '{name}' ".format(name=product,
amount=fetched_amount)
crsr.execute(kopen)
print("You have succesfully bought your product!", "\n")
def product_verkopen(crsr):
print ("Which product would you like to sell?")
sold_product = str(input(""))
print("And how many?")
wanted_sold_amount = int(input(""))
crsr.execute("SELECT * FROM emp")
rows = crsr.fetchall()
for row in rows:
if row[0] == sold_product:
actual_amount = int(row[1])
fetched_amount = actual_amount + wanted_sold_amount
kopen = "UPDATE emp SET Amount = {amount} WHERE Product = '{name}' ".format(name=sold_product,
amount=fetched_amount)
crsr.execute(kopen)
print("You have succesfully sold your product")
connection = sqlite3.connect("Stock.db", timeout=10)
crsr = connection.cursor()
connection.commit()
while True:
print("Welcome to this shop! choose your option", "\n",
"1. Buy a product.", "\n", "2. Sell a product")
option = int(input(""))
if option == 1:
product_kopen(crsr)
elif option == 2:
product_verkopen(crsr)
else:
print("This isn't a valid option", "\n")
continue
connection.close()
After you make changes to the database, you must commit them. sqlite3 does not commit changes by default. Every time you do cursor.execute(...), follow it up with a cursor.commit()
crsr.execute(kopen)
crsr.commit()
See here for more information https://docs.python.org/3/library/sqlite3.html