import getpass
import json
class LogInNow(object):
def __init__(self, file):
self.file = json.load(open("password.txt"))
def authenticate(self):
self.username = raw_input("Enter Username> ")
self.password = getpass.getpass("Enter Password> ")
for k, v in self.file:
if k == self.username and v == self.password:
print "It worked"
else:
print "Fail"
go = LogInNow("password.txt")
go.authenticate()
A separate module uses json.dump to write both inputs into password.txt
When I:
>>> import login
I get:
{u'go': u'go'}
I read the 'u' is for unicode, is good, and must be kept.
I could concatenate the u before self.username and split the values to add the quotes, but that defeats the purpose.
Any ideas?
The u
is not part of the string, any more than the quotes are. The u'go'
is just how Python represents a Unicode string whose value is go
. You do not need to "concatenate the u" or anything like that.
The raw_input
will return 'go'
, rather than u'go'
, because it's reading in an encoded byte string. But in Python 2.x, if you compare those two strings, they're still equal. Try it:
>>> 'go' == u'go'
True
So, there is no problem here.
However, as soon as you start dealing with non-ASCII usernames or passwords, then you are going to have a problem. You will need to call decode
on the values you got from the user, using the input's encoding, like this:
>>> self.username = raw_input("Enter Username> ").decode(sys.stdin.encoding)
This is a bit clumsy, but hey, Unicode is clumsy in Python 2.x, that's why Python 3.x was invented.
There is, however, a bug in your code that may be causing whatever problem you're seeing:
for k, v in self.file:
When you loop over a dictionary, you loop over its keys, not its key-value pairs. So, each username will be unpacked into k
and v
. If you have any username that aren't exactly 2 characters long, you will get ValueError: too many values to unpack
. But because you happen to have only one username, and it happens to be exactly 2 characters long, that u'go'
gets unpacked into u'g'
and u'o'
. So, instead of comparing the username to go
and the password to go
, you end up comparing the username to g
and the password to o
, which doesn't match.
If you want to iterate over key-value pairs, use for k, v in self.file.items():
.
But you usually don't want to iterate through a dict's items
to search it either. The whole point of a dict is that you can look things up instantly. Instead of this:
for k, v in self.file:
if k == self.username and v == self.password:
print "It worked"
else:
print "Fail"
… just do this:
if self.password == self.file.get(self.username):
print "It worked"
else:
print "Fail"
Or, if you want to distinguish "wrong password" from "unknown user":
try:
if self.password == self.file[self.username]:
print "It worked"
else:
print "That's the wrong password, you evil hacker"
except KeyError:
print "I've never heard of you"