I am trying to make a login system that is looped basically and whenever I try to enter the correct details that are even stored in the .csv file, it outputs as incorrect username/password no matter what I put. This code works for python 3.6 but I need it to work for python 3.2.3.
loop1 = False #for this bit of code (logging in)
loop2 = False #for next bit of code
while loop1 == False:
choice = input("Login/SignUp [TYPE 'L' OR 'S']: ").lower()
if choice == "l":
username = input("Username: ")
password = input("Password: ")
f = open("usernamepassword.csv","r")
for line in f:
details = line.split(",")
if username == details[0] and password == details[1]:
print("Welcome")
break
#this whole bit of code is meant to read from the csv and check if the login details are correct
else:
print("Username/Password [INCORRECT]")
Allow me to refactor your code:
def login(username, password):
with open("usernamepassword.csv", "r") as csv:
all_details =
[[attr.strip() for attr in line.split(",")]
for line in csv]
return any(
username == details[0]
and password == details[1]
for details in all_details)
def login_action():
username = input("Username: ")
password = input("Password: ")
if not login(username, password):
raise ValueError("Username/Password [INCORRECT]")
return True
_USER_ACTIONS = {
'l': login_action
}
def main():
while True:
choice = input("Login/SignUp [TYPE 'L' or 'S']: ").lower()
action = _USER_ACTIONS[choice]
try:
if action():
break
except Exception as err:
print(err.message)
I think your unexpected behavior comes from not stripping the values you get after splitting by ,
Solved by replacing:
if username == details[0] and password == details[1]:
With:
if username == details[0] and (password+"\n") == details[1]:
You may have a bug in line.split(','), try line.strip().split(',')
TL; DR: posted a proper solution there : https://github.com/cgte/stackoverflow-issues/tree/master/47207293-csv-dict
I'll stuff up my answer later if needed.
Furthermore you have a poor code design here, and find yourself debugging in the middle of a loop.
So first of all : load the data file, store content to a dict.
f = open("usernamepassword.csv","r")
for line in f:
details = line.split(",")
if username == details[0] and password == details[1]:
print("Welcome")
break
Should become
user_pass = {}
f = open("usernamepassword.csv","r")
for line in f:
user, password = line.strip().split(",")
user_pass[user] = password
f.close()
or better
with open("usernamepassword.csv","r") as f:
for line in f.readlines():
user, password = line.split().split(",")
user_pass[user] = password
eventually run python -i yourfile.py and type "user_pass" to see what is actually stored when correct go on further code.
Think of using the csv module : https://docs.python.org/3/library/csv.html
Then get username and password from input and check:
if login in user_pass and user_pass[login] = password:
# or better `if user_pass.get(login, None) == password:`
do_stuff()
Related
import json
def write_json(data, file='users.json'):
with open(file, 'w') as f:
json.dump(data, f, indent=4)
while True:
user = {'name':[], 'password':[]}
choice = int(input('1) Register, 2) Login\n>> '))
if choice == 1:
username = input('Enter username: ')
password = input('Enter password: ')
user['name'] = username
user['password'] = password
print('Registered successfully')
with open('users.json') as json_file:
data = json.load(json_file)
users = data['users']
for user in users:
if user['name'] == username:
print(f'User "{username}" already exists')
break
new_user = user
users.append(new_user)
write_json(data)
if choice == 2:
username = input('Enter username: ')
password = input('Enter password: ')
with open('users.json', 'r') as f:
data = json.load(f)
for user in data['users']:
if user['name'] == username and user['password'] == password:
print('Logged in succesfully')
I am trying to make a simple login/register system, but when the user registers for the 2nd time, its gets overridden by the 1st key/value every time, I tried user.clear() but it doesnt seem to have an effect
The issue is that you are using a single dict item for all your users. The way you've set it up only allows for one user to exist.
You need to restructure your dict. You could do a list of dict items, but I would suggest using the username as the key in your dict. Since usernames are supposed to be unique, this makes sense IMHO.
In case you want to use the simpler list of dict items metioned above, you would structure it as follows:
[
{'Edo': 'mypassword'},
{'Iso': 'yourpassword'}
]
I've added some comments on the adjusted code below...
import json
def write_json(data, file="users.json"):
with open(file, "w") as outfile:
json.dump(data, outfile, indent=4)
def load_json(file="users.json"):
# try block in case file doesn't exist
try:
with open(file) as infile:
result = json.load(infile)
return result
except Exception as e:
# just printing out the error
print(e)
# should only be file not found error
# returning an empty dict
return {}
while True:
# you need to load before actually doing anything.
# if you don't you might overwrite the file
userlist = load_json()
# newlines for each option
choice = int(input("1) Register\n2) Login\n>> "))
if choice == 1:
username = input("Enter username: ")
# check if user already exists before requesting password
# since usernames are supposed to be unique, you can just
# create a dict with the key being username.
# you could use the value directly for password, but
# if you need to store more values for a user, I advice
# you use another dict as the value.
if username in userlist:
print(f"User {username} already exists")
# do some other magic here to handle this scenario
# continue makes the while loop go to the next iteration
continue
password = input("Enter password: ")
userlist[username] = {"password": password, "someotheruserdate": "dunno?"}
write_json(userlist)
# only print the success **after** you've actually
# completed all relevant logic.
print("Registered successfully")
# change this to elif instead of a second if statement
elif choice == 2:
username = input("Enter username: ")
password = input("Enter password: ")
if username in userlist and userlist[username]["password"] == password:
print("Logged in succesfully")
else:
# handle wrong username/password
# here you need to check after getting both username&password
print("Incorrect username/password combination")
So I'm making a program where I need a user to log in or register. The registered account goes to a .txt file from which I'm supposed to read the data to log in again.
I managed to get the basics working. I can register a new account to the file and I can log in with every account I've created, but I can't seem to get 2 important elements working. The first one is for when the user inserts an inexistent username/ password (in this case the program just does nothing as I can't figure out a condition to make it go back to asking the username and password), and the second one is for when I insert a username and password that don't match. Here the program goes back and asks for them again but then keeps asking, even if I put them correctly.
Here's my function if anyone's interested in having a look at it:
def ent():
util = False
ppass = False
login = False
while not login:
n_util = input("Introduce your username: ")
password = input("Introduce your password: ")
with open("dadoscontas.txt", "r") as f:
while not util:
vski = 0
for line in f:
vski += 1
if vski == 1:
if line.strip() == n_util:
util = True
else:
break
if vski == 2:
if line.strip() == password and user:
ppass = True
if user and ppass:
login = True
print("Logged in")
I've spent my whole afternoon trying different things to see if I can get these 2 things to work, but I can't. As I said, the function above is the part that kinda works, and if anyone could give any suggestions / point me in the right direction it would be really helpful. Thank you in advance.
Does this code cover your needs?
def ent():
util = False
login = False
while not login:
n_util = input("Introduce your username: ")
password = input("Introduce your password: ")
with open("some_test.txt", "r") as f:
vski = 0
for line in f:
vski += 1
if vski%2:
if line.strip() == n_util:
util = True
elif util:
if line.strip() == password:
login = True
else:
util = False
print("Logged in")
Or you even could exit the function with return in if line.strip() == password: block.
But i would recommend you to store the file content to dictionaries (user_name:passwor),
because you are parsing the whole file again and again while login=False:
def ent():
login = False
name=""
my_data = {}
with open("some_test.txt", "r") as f:
index = 0
for line in f:
index += 1
if index%2:
name = line.strip()
else:
my_data[name] = line.strip()
while not login:
n_util = input("Introduce your username: ")
password = input("Introduce your password: ")
if n_util in my_data and my_data[n_util] == password:
login = True
print("Logged in")
If you use python2 you can use .get() or try instead of n_util in my_data for better performance.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have this very simple sign up/log in program for learning purpose, and it works. But it feels like I have code that repeats itself. The must obvious is the check functions.
My question is, should I refactor those two so they become one or is it better to keep them seperate?
def signUp():
username = input("Give me a username: ")
if checkUser(username) == True:
print("You are already registrered, please log in with your password.")
else:
password = input("Also give me a password: ")
with open("sign-up.csv", "a", newline="") as file:
writer = csv.writer(
file, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL
)
writer.writerow([username, password])
print("You are now signed up. Please log in with your credentials.")
def logIn():
username = input("Give me your username: ")
password = input("Also give me your password: ")
if checkPassword(username, password) == True:
print("Welcome, you are now logged in.")
else:
print("Username or password is incorrect please try again.")
def checkUser(username):
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList:
return True
else:
return False
def checkPassword(username, password):
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList and password == myList[username]:
return True
else:
return False
def get_user_choice():
print("\n[1] Sign up")
print("[2] Log in")
print("[q] Quit")
return input("What would you like to do? ")
choice = ""
while choice != "q":
choice = get_user_choice()
if choice == "1":
signUp()
elif choice == "2":
logIn()
elif choice == "q":
print("Welcome back some other day")
else:
print("That choice doesn't exists")
Function checkUser is checking if a username is already present in the csv file. This would happen at signup. The function checkPassword is used when the user is signing in. These functions should stay seperate since they do dramaticly different things with different levels of security concerns. They also expect input based on where the user is in the procces of signup/login. Meaning when you write a function that does both like doBoth(username, password) you have to call this function with a null when you wanna use it at the signup fase in the application doBoth(username, null) since password is never known at signup.
The first obvious factorisation is the common part of both functions - the part tha reads the csv file into a dict:
def read_users():
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
return dict(reader)
Then you can rewrite check_user and check_password with this function:
def check_user(username):
users = read_users()
return username in users
def check_password(username, password):
users = read_users()
# make sure we work correctly even if
# someone passes `None` as password
_notfound = object()
return users.get(username, _notfound) == password
FWIW, those functions would be better named as (resp.) 'user_exists' and 'authenticate'
Also, you may want to factor out the part that's writing to the csv file - not to reduce code duplication, but to better separate the UI / domain / persistance layers.
def add_user(username, password):
with open("sign-up.csv", "a", newline="") as file:
writer = csv.writer(
file, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL
writer.writerow([username, password])
def sign_up():
username = input("Give me a username: ")
# note how good naming makes code much more explicit
if user_exists(username):
print("You are already registrered, please log in with your password.")
return # no need to go further
password = input("Also give me a password: ")
add_user(username, password)
def log_in():
username = input("Give me your username: ")
password = input("Also give me your password: ")
if authenticate(username, password):
print("Welcome, you are now logged in.")
return
# oops...
print("Username or password is incorrect please try again.")
Next step would be to replace the input() calls by dedicated ask_username() and ask_password() functions that will validate the user's input. First write them as simply as possible, then find out the common part(s) and see if you can factor them out.
Note that I renamed your functions in all_lower - this is the official coding convention, and Python users tend to strongly adhere to the official coding conventions.
Also note that I removed the useless == True tests. In Python, any expression resolves to an object (in the case of a function call, to the object returned by the function), and every object has a boolean value, so if someexpression == True: is redundant at best. FWIW this is also part of pep8 (official coding conventions). And finally, when you find yourself writing something like:
if someexperession:
return True
else:
return False
You can just simplify it to
return someexpression
Try this:
def checkBoth(username, password):
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList:
u = True
if password == myList[username]:
p = True
else:
p = False
else:
u = False
p = False
return (u,p)
def checkPassword(username, password):
out = [False, False]
with open("sign-up.csv", "r") as file:
reader = csv.reader(file)
myList = dict(reader)
if username in myList:
out[0] = True
if password == myList[username]:
out[1] = True
return out
and then having a check what is true on the out.
I have some code that makes a login system that retrieves the accounts from a text file. The account format goes like this: Username:Password:ID, (1 is admin anything else is guest)
my current list:
Admin:Admin!:1
Guest:Password:0
test:test:0
but for some strange reason if I write in the admin credentials it lets me in but anything else fails here is my code:
import sys
username = raw_input("Username: ")
password = raw_input("Password: ")
createLogin = file("login.txt", "a")
with open("login.txt", "r") as login:
lines = login.readlines()
while True:
for line in lines:
if line.split(":")[0] == username and line.split(":")[1] == password:
print("Welcome back %s" % (username))
while True:
message = raw_input("")
else:
sys.exit()
I would appreciate it if someone could modify or tell me what to add to the code. Thanks.
So your issue is that you check the first line of the 'login.txt' file, and exit if it doesn't match. You could do something like this:
for line in lines:
if line.split(":")[0] == username and line.split(":")[1] == password:
print("Welcome back %s" % (username))
while True:
message = raw_input("")
else:
sys.exit()
By moving the else one indent back, you create a for/else loop, which will run the else code if no lines in the file matched.
I'm using python 2.7.5 and i'm trying to make a simple program that has a username, password, and checks if it exists in a dictionary. If true, it prints welcome + username, and ignores if false.
First: code.
#!/usr/bin/python
import csv
users = {}
with open('C:\\Users\\chef\\Python\\fn.csv', 'wb') as f: # Just use 'w' mode in 3.x
w = csv.DictWriter(f, users.keys())
w.writeheader()
w.writerow(users)
def new_user():
uname = raw_input("Choose a username: ")
while 1:
pwd = raw_input("Choose a password: ")
check = raw_input("Retype password: ")
if pwd == check:
print "Saved."
users[uname] = pwd
break
if uname in users.keys():
pass
def show_users():
for unames in users.keys():
print unames
def login():
uname = raw_input("Username: ")
pwd = raw_input("Password: ")
if uname in users and pwd in users.values():
print "Welcome, " + uname + "! "
def save():
f=open('C:\\Users\\chef\\Python\\fn.csv', "wb")
w = csv.writer(f)
for key, val in users.items():
w.writerow([key, val])
f.close()
def read():
with open('C:\\Users\\chef\\Python\\fn.csv', 'wb') as f: # Just use 'w' mode in 3.x
w = csv.DictWriter(f, users.keys())
w.writeheader()
w.writerow(users)
print "Welcome to Yubin's 'fake' Email server."
while 1:
read()
choice = raw_input("What would you like to do? ")
if choice == "signup":
new_user()
if choice == "login":
login()
if choice == "showusers":
show_users()
if choice == "logout":
print "You have successfully logged out."
if choice == "quit":
x = raw_input("Are you sure? (y/n) ")
if x == "y":
save()
break
else:
pass
else:
print "Please sign up, log in or see who have signed up."
Problems:
When I first "sign up", i can log in perfectly fine. But, after closing the program and running it again, i can't log in. i assume it's because i set the dictionary empty every time i start, but it's supposed to rewrite the contents into the dictionary. i use windows 7 and in the preview, when i rerun the program, the file becomes empty.
After i write either login, signup or showusers, it prints the last line,
"Please sign up, log in or see who have signed up. "
Please i ask for solutions, and thank you in advance.
EDIT: I solved problem #2, but #1 still is there.
The problem is, as hyades stated, that your read-method overwrites the csv-file instead of reading it. The csv-module offers a reader for this purpose. I have changed your read-method like this to make it work:
def read():
with open('C:\\Users\\chef\\Python\\fn.csv', 'r') as f:
usersReader = csv.reader(f)
for row in usersReader:
if row == []:
pass
else:
users[row[0]] = row[1]
f.close();
You can also remove the "with open..."-code block at the begining of the file (after import and users-declaration).
For Problem 1, might be an issue with the mode of the file. Change it to wb+
Opens a file for both writing and reading in binary format. Overwrites
the existing file if the file exists. If the file does not exist,
creates a new file for reading and writing.
Problem 2 will be solved if you use if..elif instead of if
Check this code above. I use only save and read function. I used read function only once, outside while loop (used 'rb' mode istaed 'wb' mode). I used csv.WriteDict and csv.ReadDict classes enter link description here. to read and save data from users dict. I think You can use shelve or json instead csv, propobly these way will by faster and simply ;)
#!/usr/bin/python
import csv
users = {}
'''def write():
with open('/home/marcin/fn.csv', 'wb+') as f: # Just use 'w' mode in 3.x
w = csv.DictWriter(f, users.keys())
w.writeheader()
w.writerow(users)'''
def new_user():
uname = raw_input("Choose a username: ")
while 1:
pwd = raw_input("Choose a password: ")
check = raw_input("Retype password: ")
if pwd == check:
print "Saved."
users[uname] = pwd
break
if uname in users.keys():
pass
def show_users():
for unames in users.keys():
print unames
def login():
uname = raw_input("Username: ")
pwd = raw_input("Password: ")
if uname in users and pwd in users.values():
print "Welcome, " + uname + "! "
def save():
with open('/home/marcin/fn.csv', "wb+") as f:
fieldnames=['user','pwd']
writer = csv.DictWriter(f,fieldnames=fieldnames)
writer.writeheader()
for key, val in users.items():
writer.writerow({'user' : key, 'pwd' : val})
def read():
with open('/home/marcin/fn.csv','rb') as f: # Just use 'w' mode in 3.x
w = csv.DictReader(f)
for row in w:
print row
users[row['user']]=row['pwd']
def main():
print "Welcome to Yubin's 'fake' Email server."
try:
read()
except IOError:
pass
while 1:
choice = raw_input("What would you like to do? ")
if choice == "signup":
new_user()
save()
if choice == "login":
login()
if choice == "showusers":
show_users()
if choice == "logout":
print "You have successfully logged out."
if choice == "quit":
x = raw_input("Are you sure? (y/n) ")
if x == "y":
save()
break
else:
pass
else:
print "Please sign up, log in or see who have signed up."
if __name__ == "__main__":
main()