I need to make a function for client registration where the client's username must be unique. I made a dict and a list where I put everything from my txt file, and now I've been trying to set for and while loops, but it isn't going well:
client_list = []
def c_l():
with open("svi.txt","r") as f:
pieces = ["username","password","name","lastname","role"]
for r in f.readlines():
dicct = {}
bla = r.strip().split("|")
count = 0
for i in bla:
dicct[pieces[count]] = i
count += 1
client_list.append(dicct)
c_l()
def reg():
for r in client_list:
while True:
username = input("Username: ")
if (username == r["username"] ):
print("Username is already taken, please try again: ")
else:
break
password = input("Your password:")
name = input("Your name: ")
lastname = input("Your lastname: ")
client = username + "|" + password + "|" + name + "|" + lastname + "|" + "buyer"
with open("svi.txt","a") as f:
f.write(client)
reg()
When I was typing this function for the first time, I made all in one function, where I opened the file, typed code for unique username and then printed client into that txt file. In that function my while loop worked, because all I had to do is to split the parts of the file and index the right one, then make this while loop, which worked fine. But now I've been told that I have to do it by using dict and list and I tried doing this, I don't know what the problem is with my approach.
You may want to load usernames into a set which ensures uniqueness. Then, in your reg function check whether the new username is in the set, like:
if username in myset:
raise InvalidUsernameError
else:
myset.add(username)
Related
I started learning python(and coding in general) a couple of weeks ago and I am having struggle in a project I trying to make. In part of the project I am trying to make a register and login system, everything went fine expect the 'username already taken' part in the register section.
No matter what I do, the code just keep allowing registering even if the username already taken(You can register with "x" username, and right after registering again with "x" username).
I will appreciate any kind of help!(and sorry for the english :) )
import re
Users = open('Users.txt', mode = 'a')
Hquestion = input("\t\t If you already registered please press Y, if you need to register
please press N")
def register():
if Hquestion == "N" or Hquestion == "n":
with open('Logindata.txt', mode = 'a') as logindata:
firstname = input('please write your first name(only a-zA-Z allowed): ')
username = input('Enter Username : ')
with open('Users.txt', mode = 'r') as userdata:
if username in userdata:
print("username already taken!")
return register()
password = input ('Enter Password (using only a-zA-Z0-9!##$%^&*. min 8 characters) : ' )
passpattern = re.compile('[a-zA-Z0-9##$%^&*()-+=?/".,{}\;:~]{8,}')
namepattern = re.findall('[0-9!##$%^&*()-+=?/".,{}\;:~]',firstname)
while not passpattern.match(password):
print("Your password is invalid. Please make sure you password is atleast 8 characters long!\n")
return register()
if namepattern:
print("Please use only a-z A-Z characters for first and last name!\n")
return register()
Users.write(f'{username}\n')
Users.close()
logindata.write(f'{username} ')
logindata.write(f'{password} ')
logindata.write(f'{firstname}\n')
def login():
if Hquestion == "Y" or Hqeustion == "y":
loginuser = input('Write your username: ')
loginpass = input('Write your password: ')
for user_pass in open('Logindata.txt', mode = 'r').readlines():
loginsplit = user_pass.split()
if loginuser == loginsplit[0] and loginpass == loginsplit[1]:
print("You have succsesfuly loged in! Enjoy shoping in Tomer's Shop!")
return
else:
print("Your username or password wrong, please try again")
return login()
register()
login()
From Membership test operations, python will iterate containers that do not implement __contains__. The file object is one of those containers.
That means that your membership test if username in userdata: will iterate the file line by line until username is found. The thing is, that's the full line, including newline. A quick test shows that username without newline is False and reads through the entire file
>>> # create test file
>>> open("users.txt", "w").write("Alice\nBob\nChuck\n")
16
>>> username = "Bob"
>>> f = open("users.txt")
>>> username in f
False
>>> f.read()
''
But adding the newline fixes the problem
>>> f = open("users.txt")
>>> username + "\n" in f
True
>>> f.read()
'Chuck\n'
I am completely new to programming and started a few days ago with learning Python(v.3.8.8). I wanted to make a small password manager, but with a little secret function(I think that's not important and it would take too much time to describe). Anyways I converted the main.py to a .exe with auto-py-to-exe but every time I wanna execute the .exe I can only enter my Login data and the window instantly closes but in Pycharm everything works totally fine. Does anyone know why?
EDIT: It works now, there was no missing "Input()" or stuff like that, I had a spelling mistake in my code and pycharm ignored it!
from cryptography.fernet import Fernet
welcome = input("Login(1), New User (2): ")
def new_user(): # creates a new user and safe the Username and pw in a .txt
print("The login is just for the safety of your data, everything is stored on your local PC!")
username = input("Enter a username:")
password = input("Enter a password:")
password1 = input("Confirm password:")
if password == password1:
key = Fernet.generate_key()
f = Fernet(key)
f.encypt(b'password')
file = open(username + ".txt", "w")
file.write(username + ":" + password)
#file.close()
login() # go to login after everything is safed in the .txt
else:
print("Passwords do NOT match!")
def login(): # checks if the entered username and pw match with the .txt content
login1 = input("Login:")
login2 = input("Password:")
file = open(login1 + ".txt", "r")
pw = file.readline()
#file.close()
if pw == login1 + ":" + login2: # infinte trys to enter the username and pw
print("Welcome " + login1)
pwrequest()
else: # returns to login() if the pw is incorrect
print("Incorrect username or password. Please try again")
login()
def pwrequest():
q = input("safe new Password(1), show safed passwords(2)")
if q == "2":
data() # show all saved pw
if q == "1":
newdata() # go to data() if the user want to add a new pw or
# want to acces the hidden part
def data():
file = open('1.txt', 'r') # prints all saved passwords
file_pw = file.read()
print(file_pw)
file.close()
c = input("Press (1) to delete something and press (2) to log out.")
if c == '1':
delete() # delete a pw or acces to hidden part
if c == '2':
login() # simple logout system, probably have to change this to something more intermediate
def newdata(): # safes the data in variables and put it in a .txt file
company = input("Enter the companys name: ")
username = input("Enter your username: ")
password = input("Enter your password: ")
print(company + username + password + ", is everything correct?")
a = input("y/n")
if a == "y":
file = open("1.txt", "w")
file.write(
"Company: " + company + "\n" + "Username: " + username + "\n" + "Password: " + password + "\n" + "\n")
file.close()
pwrequest() # return to pwrequest()
if a == "n":
newdata() # return to newdata() if something is incorrect
secretWord = "CompanyUsernamePassword" # define the secret word to finaly acces the hidden part
if company + username + password == secretWord:
secrettest() # go to secrettest() to enter the secret word
def delete(): # just simple code that delete specific content of the pw .txt
name = input("Please enter the Company, Username and password you wanna delete: ")
with open("1.txt", "r") as f:
lines = f.readlines()
with open("1.txt", "w") as f:
for line in lines:
if line.strip("\n") != name:
f.write(line)
def secrettest():
key = Fernet.generate_key()
f = Fernet(key)
truepass = f.encrypt(b"Test1234")
trys = 3
while trys != 0: # checks if you entered the correct pw and if not count 2 times
password = input("Pls enter the password: ")
d = f.decrypt(truepass)
if password == d.decode():
print(truepass)
break
else:
print("Wrong password!")
trys -= 1
if trys == 0:
print("You entered the wrong password to many times!")
if welcome == "1": # should probably try to move that to the top
login()
if welcome == "2": # this too
new_user()
I think I know why the .exe always closes. I executed the .exe in the windows cmd, and got this error "AttributeError: 'Fernet' object has no attribute 'enrcypt'". I'm kinda sure that this is the part that caused the trouble. I'm just wondering why pycharm just ignored this error...
I'm trying to practice my python skills, I knew that I was kind of unfamiliar with how to work with files so I decided to teach my self. The code is basically making an account, signing in and checking the user and pass stored in a file. I know my user and pass is appending and reading to the file. The problem i'm getting is in my if statement. I'm using if i == user but == means literal. So i tried just using one = to check if one variable = the variable that the user has put in, when I do that, I get a syntax error. My last question is when I run the code, in they else statement where it says username incorrect, it says it 2 or 3 times in the console. This confuses me because no where outside of the else statement is their a while or for loop. If someone can just explain how to get my if statment to excutute when the user and password string are right. That would be great. Also if you know why my console is doing the else: print('username incorrect) 3 times for no reason. I'm very curious to know
I tried printing out the variables in my for loop and it indeed printed the strings in the file.
u = open('users.txt', 'a+')
p = open('pass.txt', 'a+')
does_acc = input('Do you have a account? ')
if does_acc == 'no' or does_acc == 'No':
new_user = input('Username: ')
u.write(new_user + '\n')
new_pass = input('Password: ')
p.write(new_pass + '\n')
sign_in = input('Would you like to sign in? ')
if sign_in == 'yes' or sign_in == 'Yes':
n = open('users.txt', 'r')
m = open('pass.txt', 'r')
lines = n.readlines()
line = m.readlines()
user = input('Username: ')
for i in lines:
print(i)
if i = user:
password = input('Password: ')
for x in lines:
if password == x:
print('secret file opened')
else:
print("{} is not a valid password.").format(password)
else:
print('Username incorrect.')
else:
print('Have a nice day.')
u.close()
p.close()
Do you have a account? yes
Would you like to sign in? yes
Bob
Username: Bob
Username incorrect.
Username incorrect.
This if i = user: should be replaced with this: if i == user: (double equal sign)
Once you have created a new account, you should close the files, because you're going to open them again while they are already open. This might or might not lead to a wrongfully read / written data.
The idea that once user has entered their name, the whole password file is matched against the input password does not seem right -- you only need to check the one password for every user.
for x in lines: tries to match the password against the user names. Seems strange.
print("{} is not a valid password.").format(password) has wrong parenthesis order, it should be "string".format(parm) enclosed in print( .... ), not vice versa.
All in all, I'd rather rewrite your password matching part like this:
with open( 'passwords.txt' ) as fin :
passwords = [p.strip() for p in fin.readlines()]
with open( 'users.txt' ) as fin :
users = [u.strip() for u in fin.readlines()]
user = input( 'User: ' )
password = input( 'Password: ' )
if [user, password] in zip( users, passwords ) :
print( "You're welcome!" )
else :
print( "Go away!" )
Or something along the lines.
the if i = user should be if i == user and also you are opening the same file twice, one at the beginning and the second one after if sign_in == 'yes' or sign_in == 'Yes':
I am trying to write a code which asks a user for a username and password and then stores these into a csv file in 2 seperate columns. I have tried lots of different methods but cannot seem to do it :/
username = input ("What is your first name (or username)? ")
username = (username[0:3])
birthyear = input ("What year were you born? ")
birthyear = (birthyear[2:4])
print (("Your username is ") + (username) + (birthyear))
login = (username) + (birthyear)
newpassword = input ("Please create a password ")
with open ("scores.csv", "a") as scoreFile:
scoreFileWriter = csv.writer(scoreFile)
scoreFileWriter.writerow(username + "," + newpassword+"\n")
scoreFile.close()
This is one way I've tried but it writes every single letter in a different column like this:
b o b , p a s s w o r d
Instead of this:
bob, password
Thanks in advance if you can offer any help :)
You should specify a delimiter of ','. https://docs.python.org/3/library/csv.html
scoreFileWriter = csv.writer(scoreFile, delimiter=',')
Also, storying passwords in plain-text is Very Bad Practice (TM).
It looks like in this line you're doing the comma yourself, that is what the csv writer will do for your (as #Pipupnipup said, specify a delimeter)
You should just pass writerow a list and let it handle the newline and comma:
scoreFileWriter.writerow([username, newpassword])
And to iterate: Storing passwords in plain-text is Very Bad Practice (TM).
Working code:
username = input ("What is your first name (or username)? ")
username = (username[0:3])
birthyear = input ("What year were you born? ")
birthyear = (birthyear[2:4])
print (("Your username is ") + (username) + (birthyear))
login = (username) + (birthyear)
newpassword = input ("Please create a password ")
with open ("scores.csv", "a") as scoreFile:
scoreFileWriter = csv.writer(scoreFile, delimiter=',')
scoreFileWriter.writerow([login, newpassword])
scoreFile.close()
In relation to your stated problem .writerow() requires a sequence ('', (), []).
As you were passing strings not a sequence writerow() iterates over each letter in your string and each letter is written to a separate cell in the CSV. By giving [username, newpassword] you provide a sequence.
Also, note that you are passing the original Username, as the entered string, not the concatenation of username + birthyear which you return to the user as their username.
I'm trying to build a working login function that will take me to my menu.
Here is the code I have:
def login(userlist):
verified = False
name = input('username: ')
password = input('password: ')
while not verified:
name = input('username: ')
password = input('password: ')
if [name, password] in userlist:
verified = True
print('You logged in the system!')
else:
print('invalid username\password.')
return verified
Even though I type in the correct username and password into the program, it keeps saying Invalid...
What am I missing? Also, userlist is a textfile with the usernames and passwords are separated by lines. I'm able to read the file because of my load function:
def load():
user_file = open('userdata.txt', 'r')
userlist = []
line = user_file.readline()
while line != '':
line = line.split()
userlist.append(line)
line = user_file.readline()
user_file.close()
return userlist
My text file ends up looking like this:
username #password #list
Sam #password #[1,2,...]
(the list of numbers doesn't actually spill over to the next line)
Here is my registration function, which I think is relevant.
def register(userlist):
# ASK FOR USERNAME
name = input('Choose your username: ')
while search(userlist, name):
print('The username is not available. Choose somethng else. ')
name = input('Choose your username: ')
# ASKING FOR PASSWORD
password = input('Choose your password: ')
p = input('Retype your password: ')
while p != password:
password = input('Choose your password: ')
p = input('Retype your password: ')
# SURVEY INDEX
a = list(range(26))
user = [name, p, a]
userlist.append(user)
print('Your registration is successful, your user namw ia: ', name)
user_file = open('userdata.txt', 'a')
user_file.write(str(name) + ' ' + str(p) + ' ' + str(a)+ '\n')
user_file.close()
return userlist
if userlist is file IO object:
for i in userlist.readlines():
if [name, password] in i.split() # assumes no whitespace in password is allowed
verified = True
print('You logged in the system!')
if userlist is a dict:
if (name,password) in userlist.items()
You have issues with your load function. When you checked if [name, password] were in the userlist you hadn't stored the username and password together, they were in separate lists in the userlist.
So I changed the load function to do what you wanted.
I changed the load function though assuming your text file looks like this (missing line breaks is fine as well).
EDIT: Okay so I made changes to my answer now I know what your text file looks like.
def login(userlist):
verified = False
print(userlist)
while not verified:
name = input('username: ')
password = input('password: ')
if [name, password] in userlist:
verified = True
print('You logged in the system!')
else:
print('invalid username\password.')
return verified
def load():
userlist = []
with open('test.txt', 'r') as user_file:
for line in user_file:
line = line.strip()
if not line:
continue
userlist.append(line.split()[:2]) # Gets only name and password
return userlist
if __name__ == '__main__':
user_list = load()
login(user_list)
If you would like to change to a dictionary, instead then you can do this
if [name, password] in userlist: becomes if userlist.get(name) == password:
userlist = [] becomes userlist = {}
userlist.append(line.split()[:2]) becomes
name, password = line.split()[:2]
userlist[name] = password
Side Note:
I would suggest changing your write line to something cleaner.
user_file.write("{0} {1} {2}\n".format(name, p, a))