How to insert data into specific row without hardcode - python

The aim of this code is to achieve the following:
-Enter username
-Check if exists on DB
-If not create new user
-Add currency & balance to new user row
The issue is with my insert statement. I'm not sure how to use the WHERE condition while inserting data using defined variables. Help would be welcomed!
Error Message: TypeError: function takes at most 2 arguments (4 given)
def add_user():strong text
print("enter new username")
UserLogin = str(input())
c.execute("SELECT username FROM FinanceDBTable")
enter code here
for row in c.fetchall():
print()
#Convers tuple to string without spaces
UserNameDB = ''.join(row)
if UserNameDB == UserLogin:
print('This username already exisits. please try again')
add_user()
else:
print("Please enter your balanace\n")
userbalance = input()
print("Please enter currency\n")
userCurrency = input()
c.execute("INSERT INTO FinanceDBTable (balance, currency) VALUES (?,?)",
(userbalance, userCurrency), "WHERE (username) VALUES (?)", (UserLogin))
conn.commit()

One way would be to do this, also does not use recursion which is seen as unpythonic and also will eventually throw errors. Plus made it a bit more pythonic.
I'm not sure if you can use WHERE in INSERT statements, you can in UPDATE maybe that where you're getting that idea from, but by also giving the username value with the other will work for what you are trying to achieve i think.
def add_user():
while True:
username = input("Username: ")
c.execute("SELECT username FROM FinanceDBTable WHERE username = ?", (username,))
results = c.fetchall()
if len(results) < 1:
# Add user as there is not user with that username.
user_balance = int(input("Please enter your balance: "))
user_currency = input("Please enter currency: ")
c.execute("INSERT INTO FinanceDBTable(username, balance, currency) VALUES (?,?,?)", (username, user_balance, user_currency))
conn.commit()
break
else:
# User already exists
print('This username already exists, please try again.')

Related

Python SQlite3 Update No Error But Does Not Updating

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))

TypeError in simple registration/login program

For practice purposes I tried coding a little registration/login system which stores the registered users' data in a list.
I tried to solve this by getting user input (name, nickname and password), then create a list with the chosen "Name" which then stores "Nickname" and "PW" . This then should be then stored in the created list "users" which is being created in the beginning.
So I would have a list with different names/persons which includes their data.
The problem is that in the else statement it won't let me create the name-variable list with (username, password) in it. "TypeError: string indices must be integers"
users = []
def register():
print("Please insert your Name")
name = input()
print("Please insert your Username")
username = input()
print("Please type your Password")
userpw = input()
if name in users:
print("Account already exist, try again")
register()
else:
users.append(name[username, userpw])
This code creates a dictionary for a user and then check if its already registrated. I recommend using some sort of database to avoid dataloss from program restarts.
users = []
def register():
print("Please insert your Name")
name = input()
print("Please insert your Username")
username = input()
print("Please type your Password")
userpw = input()
for x in users:
if x['name'] == name:
print("Account already exist, try again")
register()
return
user = {'name': name,
'username': username,
'password': userpw}
users.append(user)

How to interate over an output list from fetchone() in mysql database

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()

How do I use the text from my database to authenticate as usernames and passwords?

My userpass.txt is like this:
gabiel,bab
sabiel,pont
mabiel,blont
instead of using bonjovi as username, and isagod as password, how do I use the left column of the text file associated with the words on the right column of the text file to access? It's such basic code because I'm 15 and in school.
import time
import sqlite3
conn = sqlite3.connect("UserPass.db")
cursor = conn.cursor()
print("*"*50)
print("Authentication Database")
print("*"*50)
cursor.execute("""
CREATE TABLE tblUserPass
(
usernames TEXT,
passwords TEXT,
primary key (usernames)
)"""
)
print("tblUserPass created in UserPass.db")
def readTextFile(userFile):
numRecs = 0
userDBRec = []
userTextRec = userFile.readline()
while userTextRec != "":
numRecs += 1
field = userTextRec.split(",")
usernames = field[0]
passwords = field[1]
print(usernames, passwords)
userDBRec.append(usernames)
userDBRec.append(passwords)
cursor.execute ("insert into tblUserPass VALUES (?,?)", userDBRec)
conn.commit()
userDBRec = []
userTextRec = userFile.readline()
return numRecs
userFile = open("UserPass.txt", "r")
numRecs = readTextFile(userFile)
print("\n",numRecs, "records transferred")
userFile.close()
for rows in cursor.execute('SELECT * FROM tblUserPass'):
print(rows[1])
username=input("enter user")
password=input("enter pass")
while username!='bonjovi' or password!='isagod':
print("one of 'em incorrect")
time.sleep(1)
print("go again")
username=input("ENTER USER AGAIN")
password=input("ENTER PASS AGIAN")
print("hento and welcom")
First you should never store password as clear text in your database, hash it then store it.
This is actually a simple db query,
username=input("enter user")
password=input("enter pass")
while cursor.execute(f"SELECT * FROM tblUserPass where usernames='{username}' AND passwords='{password}'").fetchone() is None:
print("one of 'em incorrect")
time.sleep(1)
print("go again")
username=input("ENTER USER AGAIN")
password=input("ENTER PASS AGIAN")
print("hento and welcom")
the query is to search for the row which matches both username and password.
Finally, welcome to SO and bravo taking the initiative to write things from scratch.
EDIT
Prior of this, this is a small problem when you initialize your database, when you do userTextRec = userFile.readline() there is actually a newline character at the end, therefore all your password (except for the last line) is suffixed with \n. To remove it, do field = userTextRec.split('\n')[0].split(",").

Loop Dual-Conditional Input Validation (Python)

I'm trying to write a python script that achieves the following:
First, prompt a user to enter the username or press enter to exit.
Prompt a user to enter quantity.
Next, use regular expression to make sure that the username consists of 5 to 10 alphabetical characters.
Use regular expression to make sure that quantity consists of only numerical values and the quantity entered is between 0 and 100
If both the username and quantity are valid, then print the username and quantity. Otherwise print an error message.
Finally, prompt the user for username again or press enter to exit.
import re, sys
username = ""
username = input('Enter Username (Press ENTER to exit): ')
while username != "":
quantity = input('Enter Quantity: ')
if re.match("[a-zA-Z]{5,10}$", username) and re.match("[0-9]{1,2}$", quantity) and type(quantity) is int and quantity > 0:
print('Username: ', username, "\n" 'Quantity: ', quantity)
else:
print('Error: Enter a username consisting of 5-10 alphabetical letters and a valid integer between 1 and 100')
username = input('Enter Username (Press ENTER to exit): ')
How would I achieve these requirements? When I run my program I always print the error message and can't properly print the username and quantity.
Thank you for taking the time and I appreciate any help I can get.
If you are having trouble understanding a complex condition, test each component individually. In your case, type(quantity)will not be int it will be str, which also means that quantity > 0 would raise a TypeError (you are not getting there because the typetest shortcircuits the condition).
A slightly better condition would be:
if re.match("[a-zA-Z]{5,10}$", username) and re.match("[0-9]{1,2}$", quantity) and int(quantity) > 0
This is hardly pythonic, but it will get the job done.

Categories

Resources