searching if an item is in a list of objects - python

I am trying to ask a user for a username and password and check a file with user name and passwords to see if it exists if it does it just says welcome if it doesnt tells the user he put in the wrong info. The file is just a simple text file with format "username,password" as shown below
SSD,adgEgd
aegag,asdhasdh
here is my code
class Account():
def __init__(self, name, password):
self.name = name
self.password = password
username_input = input("Enter the name: ")
userpassword_input = input("Enter password: ")
file = open('account information.txt', 'r')
data = []
for lines in file:
temp = lines.split(',')
data.append(Account(temp[0], temp[1]))
file.close()
isExsits = ' '
for d in data:
if username_input == d.name and userpassword_input == d.password:
isExsits = 'huzzah'
print(isExsits)
It identifies the username but not the password

There is a newline character in the password and it looks like adgEgd\n after reading from file.
You can get rid from it by using rstrip
data.append(Account(temp[0], temp[1].rstrip()))

This works as you intended, it iterates over all accounts in the account_information.txt file and creates an Account object for each of them which is added to the data list.
Afterwards, we iterate through every account and check to see if the credentials provided by the user match any within the list.
class Account():
def __init__(self, name, password):
self.name = name
self.password = password
username_input = input("Enter the name: ")
userpassword_input = input("Enter password: ")
data = []
with open("account_information.txt") as file:
for line in file.readlines():
credentials = line.rstrip().split(",")
data.append(Account(credentials[0], credentials[1]))
accountExists = False
for account in data:
if (account.name == username_input) and (account.password == userpassword_input):
accountExists = True
print(accountExists)

It seems to working fine like this, so I would likewise say it's probably the newlines or other extraneous characters at the end of the lines that are throwing off the calculation.
user_pass_list = [
('SSD', 'adgEgd'),
('aegag', 'asdhasdh')
]
username = 'SSD'
password = 'adgEgd'
exists = False
for d in user_pass_list:
if username == d[0] and password == d[1]:
exists = True
print(exists) # True
Another approach can be to just do an in check, so that we don't need to iterate over user_pass_list for example:
user_pass_list = [
('SSD', 'adgEgd'),
('aegag', 'asdhasdh')
]
username = 'SSD'
password = 'adgegd' # casing is different
exists = (username, password) in user_pass_list
assert exists is False # True
With the Account class example from the original question, reformatted as a dataclass for slightly cleaner code:
from dataclasses import dataclass
# same as `#dataclass(eq=True)`, so an equals (__eq__) method
# is automatically generated for the class.
#dataclass
class Account:
name: str
password: str
user_pass_list = [
Account('SSD', 'adgEgd'),
Account('aegag', 'asdhasdh')
]
username = 'SSD'
password = 'adgEgd'
exists = Account(username, password) in user_pass_list
assert exists is True # True

Related

How do I store an object in a dictionary in Python?

In my password manager prroject, I am trying to code a login function.
In this functtion, if the user's username and password match an account stored in this dictionary, it allows access to their object which has the following attributes: username, password, password_coll.
(The password_coll is a dictionary/collection of the users passwords as values to the website of use as keys).
So as a little stem from my original question, how would I also reference my
This is my first time using OOP approach and it is really frying my brain hahaha.
So I thought of using usernames as keys and the object as the value. But how do I structure this in code?
Any examples would be greatly appreciated.
I did try checking existing questions but they didn't answer my question closely enough. So here we are haha:)
The code block at the bottom is my attempt at testing the output of those methods to see if they return the data in the object. But the result was this message:
"<bound method User.return_pass of <main.User object at 0x0000023419597940>>"
import random
import secrets
import string
class User:
def __init__(self, username, password, password_dict=None) -> None:
self.username = username
self.password = password
self.password_dict = {}
def return_pass(self, password):
return self.password
def __str__(self, password) -> str:
return self.password
def get_creds(self, username, password):
usern = input('Enter username: ')
pwd = input('Enter password: ')
self.username = usern
self.password = pwd
def passGen(self, password_dict): # random password generator
n = int(input('Define password length. Longer passwords are safer.'))
source = string.ascii_letters + string.digits
password = ''.join((secrets.choice(source)) for i in range(n))
print('Password has been generated!')
print('Would you like to save this password? Type y or n: ')
yon = input()
if yon == 'y':
site = input('Please enter the site password is to be used:')
self.password_dict[site] = password
return self.password_dict
u1 = User('dave', 'pass', {})
user_logins = {'dave': u1}
print(user_logins['dave'].return_pass)
User.return_pass is a function, it has to be called:
print(user_logins['dave'].return_pass("password")) where the text "password" is the arg required in the function.
Hope this helps
def login(username, password, user_logins):
if username in user_logins:
user = user_logins[username]
if user.password == password:
return user.password_dict
else:
return "Incorrect password"
else:
return "Username not found"
print(login('dave', 'pass', user_logins))
In your code, you're trying to print the output of a function, but you forgot to actually run the function by adding parentheses at the end. So instead of just printing the function, you need to run it by adding () at the end. Also, the str method in the User class should not take any input, and it should return the value of self.password instead of just 'password'
print(user_logins['dave'].return_pass())

Can't append to txt file with a comma separator and linebreak

I am a function (logger) that expects two arguments from another python file. one of the arguments is a user input: firstname, lastname, email and phone number. the logger function should write the user input into txt file with comma operator between all elements. Then the next time the user executes the code, it should append the new data to a newline, but does not do that. It continues with the same line. Can someone please take a look of what I am getting wrong. code is attached below:
import re
def firstnamechecker(firstname):
firstEx = re.compile('[a-zA-Z]+$')
if firstEx.match(firstname):
return True
else:
return False
def lastnamechecker(lastname):
lastnameEx = re.compile('[a-zA-Z]+$')
if lastnameEx.match(lastname):
return True
else:
return False
def emailchecker(email):
emailEx = re.compile('[a-zA-Z0-9]+#[a-zA-Z]+\.[a-zA-Z]+$')
if emailEx.match(email):
return True
else:
return False
def phonenumberchecker(phonenumber):
numEx = re.compile('\d{3}-\d{3}-\d{4}$')
if numEx.match(phonenumber):
return True
else:
return False
def logger(logfile, data):
filewrite = open(logfile, "a")
data = data.splitlines()
data[:-1:] = [x+',' for x in data[:-1:]]
for item in data:
filewrite.write(item)
filewrite.close()
The code where the above code gets the information from is posted below:
import re
from checker import firstnamechecker, lastnamechecker, emailchecker,phonenumberchecker,logger
#lettersreg = re.compile('[a-zA-Z]+$')
#phonereg = re.compile('\d{3}-\d{3}-\d{4}$')
#emailreg = re.compile('[a-zA-Z0-9]+#[a-zA-Z]+\.[a-zA-Z]+$')
ADDBOOKPATH = "addbookFinal.txt"
ADDBOOKDATA = "addbook.txt"
LOGGING = True
def firstname():
firstname = input("put in your first name: ")
if LOGGING:
logger(ADDBOOKDATA, firstname)
while not firstnamechecker(firstname):
firstname = input("put in your first name: ")
if LOGGING:
logger(ADDBOOKDATA, firstname)
return firstname
#lastname
def lastname():
lastname = input("put in your last name: ")
if LOGGING:
logger(ADDBOOKDATA, lastname)
while not lastnamechecker(lastname):
lastname = input("put in your last name: ")
if LOGGING:
logger(ADDBOOKDATA, lastname)
return lastname
#email
def email():
email = input("put in your email: ")
if LOGGING:
logger(ADDBOOKDATA, email)
while not emailchecker(email):
email = input("put in your email: ")
if LOGGING:
logger(ADDBOOKDATA, email)
return email
#phonenumber
def phonenumber():
phonenumber = input("put in your phone number: ")
if LOGGING:
logger(ADDBOOKDATA, phonenumber)
while not phonenumberchecker(phonenumber):
phonenumber = input("put in your phone number: ")
if LOGGING:
logger(ADDBOOKDATA, phonenumber)
return phonenumber
def main():
firstname()
lastname()
email()
phonenumber()
main()
I updated the question and posted the code where the logger gets the information from. so basically, it should append like: firstname, lastname, email, phonenumber in one line and the next time the code is executed. it should write the new info into a newline in the same txt file.

Storing items in a module-level list

How can I save the items in lists because when using Sign_in function, it prints "invalid" not "success"?
import lists_module
def Sign_in():
email = input("Enter Your Email").strip()
password = input("Enter your password").strip()
if email in lists_module.emails and int(password) in lists_module.passwords:
print("success")
else : print("invalid")
def Sign_up():
first_name = input("Enter Your First Name").strip().capitalize()
last_name = input("Enter Your Last Name").strip().capitalize()
new_email = input("Enter Your Email").strip().capitalize()
new_password = input("Enetr New Password").strip().capitalize()
lists_module.Fname.append(first_name)
lists_module.Lname.append(last_name)
lists_module.emails.append(new_email)
lists_module.passwords.append(new_password)
print("Sign-In Page")
Sign_in()
Note: Fname and Lname and email are empty lists in another module.
The appended values are just temporary. Use file I/O for permanent changes. I.e.:
def Sign_in():
email = input("Enter Your Email").strip()
password = input("Enter your password").strip()
emails = open('emails.txt','r').readlines()
passwords = open('passwords.txt','r').readlines()
if email in emails and password in passwords:
print("success")
else : print("invalid")
def Sign_up():
first_name = input("Enter Your First Name").strip().capitalize()
last_name = input("Enter Your Last Name").strip().capitalize()
new_email = input("Enter Your Email").strip()
new_password = input("Enetr New Password").strip()
open('fnames.txt','a+').write(first_name+'\n')
open('lnames.txt','a+').write(first_name+'\n')
open('emails.txt','a+').write(new_email+'\n')
open('passwords.txt','a+').write(new_password+'\n')
print("Sign-In Page")
Sign_in()
This will write the values to files on your computer, then read them from those files, that way, when you run the prorgam a second time, the changes are permanent.
The reason you keep getting "invalid" is because you don't process the user's input consistently in the Sign_up() and Sign_in() functions. One way to update the lists in the lists_module is by using the atexit module to register a function that will be executed when the script ends.
import atexit
import lists_module
def Sign_in():
email = input("Enter Your Email ").strip().capitalize()
password = input("Enter your password ").strip().capitalize()
if email in lists_module.emails and password in lists_module.passwords:
print("success")
else:
print("invalid")
def Sign_up():
first_name = input("Enter Your First Name ").strip().capitalize()
last_name = input("Enter Your Last Name ").strip().capitalize()
new_email = input("Enter Your Email ").strip().capitalize()
new_password = input("Enetr New Password ").strip().capitalize()
lists_module.Fname.append(first_name)
lists_module.Lname.append(last_name)
lists_module.emails.append(new_email)
lists_module.passwords.append(new_password)
print("Sign-In Page")
Sign_in()
def update_lists_module():
with open('lists_module.py', 'w') as outp:
for name in dir(lists_module):
if not name.startswith('_'):
value = getattr(lists_module, name)
outp.write(f'{name} = {value!r}\n')
atexit.register(update_lists_module)
Sign_up()

python json keeps appending same key and value

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

Python - how to read through text file for keyword

**This is a practice application
I have a text file containing a id & a password. Each pair is on separate lines like so:
P1 dogs
P2 tree
I then have 2 functions to allow the user the add another id/password or update the password by selecting an ID then the new password. (I have removed the save functionality so I don't create loads of pairs when testing)
The question is how would I write a check function so that when the user is creating a new pair.. it checks if the id/password already exists. Then on the update password function, it only checks if the password exists?
My code so far:
#Keyword check
def used_before_check(keyword, fname):
for line in open(fname, 'r'):
login_info = line.split()
username_found = False
for line in login_info:
if keyword in line:
username_found == True
if username_found == True:
return True
else:
return False
# New password function
def new_password():
print("\nCreate a new password")
new_id_input = input("Please give your new password an ID: ")
new_password_input = input("Please enter your new password: ")
print("ID in use?", used_before_check(new_id_input, txt_file))
print("Password in use?", used_before_check(new_password_input, txt_file))
#Change password function
def change_password():
print("\nChange password")
id_input = input("Enter the ID of the password you'd like to change: ")
password_input = input("Now enter the new password: ")
print("password_input",used_before_check(password_input, txt_file))
The easiest way would be to use JSON:
import json
import os
def new_password(user, password, password_dict={}):
if user in password_dict:
password_dict[user] = password # change password
else:
password_dict[user] = password # new password
return password_dict
def read_passwords(filename):
if not os._exists(filename):
return {}
with open(filename, 'r') as f:
s = f.read()
return json.loads(s)
password_filename = 'my_passwords.json'
password_dict = read_passwords(password_filename)
user = ''
while not user == 'q':
user = input('user:')
password = input('new password:')
if user != 'q':
password_dict = new_password(user, password, password_dict)
s = json.dumps(password_dict)
with open(password_filename, 'w') as f:
f.write(s)
Not that I have included a seemingly unnecessary if clause in new_password. This is just for you that you can easily enter your own code what you want to do (maybe different) in each case.
Create a function to store your usernames/passwords in a dictionary, then you can easily check it for existing usernames/passwords
To store in dictionary:
def process_file(fname):
username_pw_dict = {}
for line in open(fname, 'r'):
login_info = line.rstrip().split()
username = login_info[0]
pw = login_info[1]
username_pw_dict[username] = pw
return username_pw_dict
username_pw_dict = process_file(fname)
Then you can check for existing usernames or passwords like this:
if new_username in username_pw_dict:
print("username already exists")
if new_pw in username_pw_dict.values():
print("password already exists")
When you are reading the file, make a dictionary with all the IDs as its keys.
In next step, reverse the dictionary key-value pair so all its values (i.e all passwords) become its keys.
Finally, when you enter a new ID and password, just check those dictionaries to know if they already exist. You may refer to this below code:
dict_ids = {1 : "one", 2:"two", 3:"three"};
dict_pwds = {}
for key, value in dict_ids.items():
for string in value:
dict_pwds[value] = key;
print "dict_ids ", dict_ids;
print "dict_pwds ", dict_pwds;
if 'myid' in dict_ids.keys():
print "ID exist! "
else:
print "New ID"
if 'mypwd' in dict_pwds.keys():
print "Password exist! "
else:
print "New Password"

Categories