Here is my code -
#Using pickle
#using pickle with dictionaries
import pickle
checkDeets = True
passWrong = "You have entered incorrect details, please try again"
x = input("want to enter data? - ")
if x == "yes":
file = open("data.pickle" , "wb")
signUpU = input("enter user - ") #Later used as sign in details
signUpP = input("enter pass - ") # as above
ID_in = {signUpU : signUpP} #Is meant to store the two user details
pickle.dump(ID_in, file)
file.close()
y = input("want to log in? ")
if y == "yes":
file = open("data.pickle" , "rb")
ID_out = pickle.load(file)
while checkDeets == True:
signInU = input("enter username - ")
signInP = input("enter pass - ")
if signInU in ID_out:
if signInP == ID_out[signInU][0]:
print("Login accepted")
checkDeets = False
else:
print("1")
print(passWrong)
else:
print("2")
print(passWrong)
Here is my inputs -
want to enter data? - yes
enter user - user123
enter pass - pass123
want to log in? no
>>> x = open("data.pickle" , "rb")
>>> x
<_io.BufferedReader name='data.pickle'>
this last part is where i get confused, as it seems that my dictionary data is not being saved. And this is causing my to have other errors in my log in part of my code, where the user details are not recognized.
New to pickling, sorry if there are any obvious mistakes. Using python 3
open() returns a file object, your repl output is expected. If you want to see what the data inside of it contains pass it to pickle.load() like so:
want to enter data? - yes
enter user - foo
enter pass - bar
want to log in? no
>>> import pickle
>>> pickle.load(open("data.pickle" , "rb"))
{'foo': 'bar'}
>>>
And you can see your data is being saved and loaded without issue. The second part of your code doesn't work because of this:
if signInP == ID_out[signInU][0]:
ID_out[signInU] is a string, the password, so ID_out[signInU][0] is the first character of that password. If the password is "bar" this line compares "bar" (the string we're checking against the stored password) to "b" (the first letter of the stored password) and obviously these are not the same string. Just drop the [0] and this code should do want you're going for.
Related
I'm trying to get my code to check if a word is already in the document. However when choosing a variable (username) that happens to share the same letters going to the right as the preexisting one in the file, it thinks that the name is taken. For example, if abcdefg was in the file, if I was to right defg or fg or g, it would think the username was taken.
def register():
print("━━━━ACCOUNT CREATION━━━━")
username = input("Create Username: ")
with open("Login.txt", "r") as loginfile:
if (username+",") in loginfile.read():
print("Sorry, but that username is taken.")
choice = input("Try again with a new name? (Y/N)")
choice = choice.upper()
My case:
Say I had the name, Joe which is already in the file. If I tried to make a username that is just e, then it would think it is Joe, as it is looking for the e, next to a comma.
Anyway to fix this? Thanks!
This should work
with open('login.txt', 'r') as LoginFile:
# the split function splits a string to a list on mark
Data = LoginFile.read().split(" ,")
if username in Data:
# .....
if this isn't what you want try this built-in module :
https://docs.python.org/3/library/re.html
def register():
print("━━━━ACCOUNT CREATION━━━━")
# read the names from the file
with open('Login.txt', 'r') as f:
names = f.read().split(',')
username = input("Create Username: ")
for name in names:
# check if any names end with this name have been created
if name.endswith(username):
# found
print("Sorry, but that username is taken.")
# we want to keep ask the user to select if
# they enter something other than Y/N
while True:
# ask for the option
option = input("Try again with a new name? (Y/N) ")
# try again, we just rerun this function
if option == 'Y':
register()
# don't ask any more
break
elif option == 'N':
# exit if user chooses N
break
# if the user chooses something else, continue
# the loop and keep asking
# if no names end with username, goto else
break
else:
# name available, save it to the file
print("Name created successfully:", username)
new_names = names + [username]
with open('Login.txt', 'w') as f:
f.write(','.join(new_names))
I have tested it, please try and see if it works for you.
There's one last feature I want for my bank account system.
I want it to check if a username has already been saved to the text file database. If the username already exists, then it should tell the user that they can't have that name option. If not, then they would be able to use it.
The rest of my code works as it should, it's just the fcat that I can't append/update my text file properly and see if usernames already exist in the text file database.
import sys
users = {}
status = ""
# Functions ---------------------------------------------------------------------------------------------------------
# Select either account creation or login
def displayMenu():
global status
status = input("Are you a registered user? \n1 - Yes \n2 - No \nQ - Quit \n")
if status == '1':
oldUser()
elif status == '2':
newUser()
else:
print("Unknown input error, exiting . . . .")
sys.exit(0)
return status
# Account creation
def newUser():
global createLogin
createLogin = input("Create login name: ")
if createLogin in users: # check if login name exists
print ("\nLogin name already exists!\n")
else:
createPassw = input("Create password: ")
users[createLogin] = createPassw # add login and password
print("\nAccount created!\n")
#---- Storing the username in a txt file
file = open("accountfile.txt", "a")
file.write(createLogin)
file.write("\n")
file.close()
oldUser()
# Account login
def oldUser():
global login
login = input("Enter login name: ")
passw = input("Enter password: ")
# check if user exists and login matches password
if login in users and users[login] == passw:
file = open("accountfile.txt", "r")
for text in file: ######## This is where I'm trying to compare username duplicates
if text in file == createLogin:
print("Username already exists!")
print("\nLogin successful!\n")
Bank_Account()
else:
print("\nUser doesn't exist or wrong password!\n")
print("Restarting. Please enter details correctly . . . . .")
sys.exit(0)
class Bank_Account:
def __init__(self):
self.balance=0
response = ''
def deposit(self):
try:
amount=float(input("Enter amount to be Deposited: "))
except ValueError:
print("Enter digits only")
else:
self.balance += amount
print("\n Amount Deposited:",amount)
def withdraw(self):
try:
amount = float(input("Enter amount to be Withdrawn: "))
if self.balance>=amount:
self.balance-=amount
print("\n You Withdrew:", amount)
except ValueError:
print("Enter digits only")
s.withdraw()
else:
print("\n ")
def display(self):
print("\n Remaining Balance=",self.balance)
displayMenu()
s = Bank_Account()
# Calling functions with that class object
s.deposit()
s.withdraw()
s.display()
So it looks you are are writing the user input in the file accountfile.txt. So after a few users log in it might look something like:
$ cat accountfile.txt
mike
sarah
morgan
lee
The section of your code in question is here:
file = open("accountfile.txt", "r")
for text in file:
if text in file == createLogin:
print("Username already exists!")
This particular part is probably not doing what you think it's doing:
if text in file == createLogin
...
if text in file is returning either True or False.
...
So the line above is essentially saying
if False == createLogin
or
if True == createLogin
I believe what you want to do is check if a name is in accountfile.txt. The smallest change you could make to your code in order to achieve that would be
file = open("accountfile.txt", "r")
for text in file:
if text.strip() == createLogin: # .strip() will clean up the \n
print("Username already exists!")
This line:
if text in file == createLogin: is where you are making a mistake. The line is essentially saying:
"(if the text is in the file) compare the result of that check with the string createLogin".
i.e. if (True/False) == createLogin, which is always false because the True/False boolean primitives are never equal to any string (if it actually runs, i have not tested to see if an exception will be thrown).
what you should do is this
for text in file: # get one line of text
if createLogin == text.strip(): # compare the line with the user input string
print("Username already exists!")
break
.strip() removes any leading or trailing spaces in the database stored name (in this case the line break character \n used to denote the end of a line in the file. break ends the loop prematurely cos your lookup is complete since you found what you were looking for, and it would be an unnecessary to continue comparing the user input with other strings, imagine the txt had 1000 names and the 1st name was a match, the user would see the error printed but the program would continue running for the rest of the 999 tries, making it seem sluggish and waste unnecessary CPU cycles.
The database is still case sensitive however which may or may not be desired depending on your requirements. For case insensitivity you could do the following:
for text in file: # get one line of text
if createLogin.lower() == text.strip().lower(): # compare the line with the user input string
print("Username already exists!")
break
.lower() makes both strings into lower case strings and then checks if they are the same, eliminating the case sensitivity.
Instead of writing to the text file, try pickling the database.
This will save a representation of the object that you can easily load back into your program.
import pickle
users = {}
users["Ash"] = "password"
pickle.dump(users, open("users.p", "wb"))
loaded_users = pickle.load(open("users.p", "rb"))
print(loaded_users)
A more advanced solution may also be to check out a relational database, such as [sqlite3][1]
I've been trying to create a really simple login screen on python for fun. Somewhere else in the program I have it save the entered username and password as a str (in dict format) on an external file. I can get it to check if the key-username- is correct but i cant find a way to make it check if the password entered is the password linked with the key -the value- I might of worded this weirdly but does any one have any idea how?
def login():
clear()
gap()
loginu = input("ENTER YOUR USERNAME:")
gap()
file = open("usernamesf.txt","r")
usernra = file.read()
usernr = usernra.replace("'","")
usernw = '"{' + usernr + '}"'
print (usernw)
usernwl = ast.literal_eval(usernw)
print (usernwl)
if loginu in usernwl:
gap()
loginp = input("ENTER YOUR PASSWORD:")
loginpc = usernw[loginu]
if loginp in loginpc:
print ("yay")
else:
gap()
print ("NO USERNAME FOUND...")
time.sleep(0.5)
gap()
signu = input("Would you like to sign up?")
if signu in ['yes','y','Y','Yes',' yes',' Yes',' y',' Y']:
sign()
else:
menu()
I would first recommend that you use the json library to parse your file - it is able to convert python dictionaries to string and vice versa, which is really useful.
To convert dict to str:
json.dumps(dictionary)
To convert str to dict: json.loads(string)
With this, to read the dictionary from the file, it is simply:
import json
with open("usernamesf.txt") as f:
user_dictionary = json.loads(f.read())
if loginu in user_dictionary:
password = input("ENTER YOUR PASSWORD")
if user_dictionary[username] == password:
# success
Notice how i used the with statement here for the file - this ensures that the file is properly closed by python after you are done with it - that is, after you exit the with block. You can read more about this in the official python documentation on file I/O here: https://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects
I am trying to create a registrar system through Python with pickles. I have gotten the system to record user input, but it does not save it for future implementations of the program.
Here is the code that will start the program:
import datetime
import pandas as pd
import pickle as pck
import pathlib
from pathlib import *
from registrar import *
prompt = "Please select an option: \n 1 Create a new course \n 2 Schedule a new course offering \n 3 List this school's course catalogue \n 4 List this school's course schedule \n 5 Hire an instructor \n 6 Assign an instructor to a course \n 7 Enroll a student \n 8 Register a student for a course \n 9 List this school's enrolled students \n 10 List the students that are registered for a course \n 11 Submit a student's grade \n 12 Get student records \n 13 Exit"
farewell = "Thank you for using the Universal University Registrar System. Goodbye!"
print ("Welcome to the Universal University Registration System.")
print ("\n")
try: #As long as CTRL-C has not been pressed, or 13 not been input by user.
input_invalid = True
while input_invalid:
inst = input("Please enter the name of your institution. ").strip()
domain = input("Please enter the domain. ").strip().lower()
if inst == "" or domain == "":
print("Your entry is invalid. Try again.")
else:
input_invalid = False
schoolie = Institution(inst, domain)
if Path(inst + '.pkl').exists() == False:
with open(inst + '.pkl', 'r+b') as iptschool:
schoolie = pck.load(iptschool)
while True:
print (prompt)
user_input = input("Please enter your choice: ")
try:
user_input = int(user_input)
if user_input < 1 or user_input > 14: #UserInput 14: on prompt.
raise ValueError("Please enter a number between 1 and 13, as indicated in the menu.")
except ValueError:
print("Not a valid number. Please try again.")
if user_input == 1: #Create a new course
input_invalid2 = True #Ensure that the user actually provides the input.
while input_invalid2:
input_name = input("Please enter a course name: ").strip()
input_department = input("Please enter the course's department: ").strip()
input_number = input("Please enter the course's number (just the number, not the departmental prefix): ").strip()
try:
input_number = int(input_number)
except ValueError:
print ("Please print an integer. Try again.")
input_credits = input("Please enter the number of credits awarded for passing this course. Please use an integer: ").strip()
try:
input_credits = int(input_credits)
except ValueError:
print ("Please print an integer. Try again.")
if input_name != "" and input_department != "" and input_number and input_credits:
input_invalid2 = False #Valid input
else:
print("One or more of your entries is invalid. Try again.")
added_course = Course(input_name, input_department, input_number, input_credits)
for course in schoolie.course_catalog:
if course.department == input_department and course.number == input_number and course.name == input_name:
print("That course is already in the system. Try again.")
input_invalid2 == True
if input_invalid2 == False:
schoolie.add_course(added_course)
print ("You have added course %s %s: %s, worth %d credits."%(input_department,input_number,input_name, input_credits))
And here is the second option, which SHOULD reveal that it is stored, but it does not.
elif user_input == 2: #Schedule a course offering
input_invalid2 = True #Ensure that the user actually provides the input.
while input_invalid2:
input_department = input("Please input the course's department: ").strip()
input_number = input("Please input the course's number: ").strip()
course = None
courseFound = False
for c in schoolie.course_catalog:
if c.department == input_department and c.number == input_number: #Course found in records
courseFound = True
course = c
input_section_number = input("Please enter a section number for this course offering: ").strip()
input_instructor = input("If you would like, please enter an instructor for this course offering: ").strip()
input_year = input("Please enter a year for this course offering: ").strip()
input_quarter = input("Please enter the quarter in which this course offering will be held - either SPRING, SUMMER, FALL, or WINTER: ").strip().upper()
if input_course != "" and input_course in schoolie.course_catalog and input_section_number.isdigit() and input_year.isdigit() and input_quarter in ['SPRING', 'SUMMER', 'FALL', 'WINTER'] and input_credits.isdigit():
if input_instructor != "": #Instructor to be added later, if user chooses option 6.
added_course_offering = CourseOffering(c, input_section_number, None, input_year, input_quarter)
else:
added_course_offering = CourseOffering(c, input_section_number, input_instructor, input_year, input_quarter)
schoolie.add_course_offering(added_course_offering)
input_invalid2 = False #Valid input
print ("You have added course %s, Section %d: %s, worth %d credits."%(input_course,input_section_number,input_name, input_credits))
else:
print("One or more of your entries is invalid. Try again.")
if courseFound == False: #If course has not been found at the end of the loop:
print("The course is not in our system. Please create it before you add an offering.")
break
By the way, I think I have the system closing properly. Correct me if I'm wrong:
elif user_input == 13: #Exit
with open(inst + '.pkl', 'wb') as output:
pck.dump(schoolie, output, pck.HIGHEST_PROTOCOL)
del schoolie
print (farewell)
sys.exit()
except KeyboardInterrupt: #user pushes Ctrl-C to end the program
print(farewell)
I believe that there is something wrong with the way that I am setting up the pickles files. I'm creating them, but I seem not to be putting data into them.
I apologize for the long-winded nature of this question, but I hope that the details will help you understand the problems that I've been having. Thanks in advance for the help!
it seems you may have dump and load reversed: (from the docs)
Signature: pck.load(file, *, fix_imports=True, encoding='ASCII', errors='strict')
Docstring:
Read and return an object from the pickle data stored in a file.
Signature: pck.dump(obj, file, protocol=None, *, fix_imports=True)
Docstring:
Write a pickled representation of obj to the open file object file.
With all those lines of code, it does get a little confusing, but I don't see any code that is pickling and writing the objects to a file.
Before anything else, you should assign the file to a variable so you can reference it. To do this, you'll have code similar to this:MyFile = open("FileName.extension","wb"). MyFile can be any name you want, it will be what you use later to reference the file. FileName is the name of the file itself. This is the name it will have in File Explorer. .extension is the file's extension, specifying the type of file. You should use .dat for this. wb is the file access mode. "w" means write, and "b" means binary. (Pickled objects can only be stored in a binary file.)
To write the pickled objects, you'll need this code:pck.dump(object,MyFile). (Usually, you would use pickle.dump(object,MyFile), but you imported pickle as pck.)
After writing the data to the file, you'll want to retrieve it. To do this, the "wb" instance of MyFile needs to be closed like this:MyFile.close(). Then you'll need to re-open the file in read mode using the following code:MyFile = open("FileName.extension","rb") Then you would use this:object = pickle.load(MyFile) to read the data. In the preceding example, (the load function), your object must have the same name as when you pickled it using the dump function. (pck.dump(object,MyFile))
In the end, you'll end up with something similar to this:
if writing conditions are true:
MyFile = open("FileName.dat","wb")
pickle.dump(object,MyFile) # This will be repeated for each object.
MyFile.close()
if reading conditions are true:
MyFile = open("FileName.dat","rb")
object = pickle.load(MyFile) # This will be repeated for each object.
MyFile.close()
I'm sorry if this wasn't the answer you wanted. Because of all those lines of code, it is somewhat hard to understand. I need clarification to give a better answer.
I have made a program on python 3.5 which you can find out the password linked to a username, make a new password for an existing user and add a new user and password to the dictionary then pickles it so every time I load the program all the usernames and passwords will be there.
The error that comes up is after you create the pickle file(after running it for the first time) then on line 6 the error
AttributeError: Can't get attribute 'NewPass' on <module '__main__' (built-in)>
occurs.
Here is my script:
import sys
import pickle
import os
if os.path.exists("branston.p"):
LOGG = pickle.load(open('branston.p', 'rb'))
else:
LOGG = {'Sam': ('CHRIST')}
def Find():
Username = input("Say a Username.")
print (LOGG[Username])
def NewPass():
Username = Input("Enter your username.")
Newpass = input("Enter your new password")
if NewPass == input("Confirm password"):
LOGG[Username] = (NewPass)
def NewEntry():
NewUser = input("Enter your new username.")
Newpass = input("Enter your new password.")
LOGG[NewUser] = (NewPass)
loop = True
while loop == True:
function = input("Say what you want me to do.'Find', 'NewPass', 'NewEntry', 'Stop'.")
if function == ("Find"):
Find()
elif function == ("NewPass"):
NewPass()
elif function == ("NewEntry"):
NewEntry()
elif function == ("Stop"):
f = open('branston.p', 'wb')
pickle.dump(LOGG, f)
f.close()
sys.exit()
Any help would be appreciated. Thanks!
When you do this
LOGG[NewUser] = (NewPass)
You are assigning the function NewPass to your dict entry. You are probably intending to assign the password string and therefore it should be.
LOGG[NewUser] = Newpass
Note: Parenthesis are superfluous. I'd also suggest avoiding using upper case letters as the first character of your variable names, as otherwise it is easy to confuse variable and function names.