'AttributeError:' when I try to unpickle dictionary - python

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.

Related

register system in python 3 cant identify already taken usernames

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'

ValueError: I/O operation on closed file inside an if statement

I made a login/signup program where the user must type in credentials in order to make an account or enter.
But I have two problems though, one is inside the function 'sign_up()' if the user is attempting to make a pre-existing account it should print the 'This username is taken' statement, but that's not the case. It prints a Value Error called 'I/O operation on closed file' instead.
Then the second problem is, it doesn't print the credentials in a designated file called 'LOG-IN_DATA', it's basically where you store it.
Anyway here is the code:
from class1 import Credentials
def sign_up():
choose_username_data = input("Choose a UserName: ")
choose_password_data = input("Choose your password: ")
Credentials(choose_username_data, choose_password_data)
data = open('LOG-IN_DATA', 'a+')
if choose_username_data not in data:
data.write(str(Credentials))
data.write('\n')
welcome()
data.close()
if choose_username_data in data:
print("This username is taken!")
sign_up()
data.close()
def log_in():
username_data = input("Enter your username: ")
password_data = input("Enter your password: ")
data = open('LOG-IN_DATA', 'r')
data.read()
data.close()
if username_data and password_data in data:
welcome()
elif username_data and password_data not in data:
print("Username or Password does not match or not recognized.")
log_in()
def welcome():
print("Welcome! You made it in!")
def login_or_signup():
signup_var = ('Signup', 'SignUp', 'signup')
login_var = ('Login', 'LogIn', 'login')
prompt_user = input("Welcome! Would you like to Login or Signup?: ")
if prompt_user in login_var:
log_in()
elif prompt_user in signup_var:
sign_up()
else:
print("\nChoose 'Login' or 'Signup'")
login_or_signup()
login_or_signup()
Sorry if the code is too long. I just want problems and potential ones to be eliminated as far as I am concerned.
Anyways thank you in advance!
Try using with statements when manipulating files. It handles flush and close automatically even when errors occur.
For example:
with open("path", 'r') as f:
content = f.read()
instead of:
f = open("path", 'r')
content = f.read()
f.close()
The problem with this line if choose_username_data in data: is that before, you also used data. The cursor in the file is at the end of this file. So when you ask a second time without setting the cursor back to the start of the file, it read nothing. That's why the 2nd statement never evaluates true.
With everything I told you, the sign_up function can be written:
def sign_up():
loop = True
while loop:
choose_username_data = input("Choose a username: ")
choose_password_data = input("Choose your password: ")
creds = Credentials(choose_username_data, choose_password_data)
with open('LOG-IN_DATA', 'a+') as data:
content = data.read()
if choose_username_data not in content:
data.write(str(creds)+'\n')
welcome()
loop = False
# if choose_username_data in content:
else:
print("This username is taken!")

How to check if only a part of a variable is next to a string in Python?

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.

How to check if the entered value is in a key - Python

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

pickle not saving dictionary properly

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.

Categories

Resources