Writing a python script that prompts the user by asking if they are are new or an existing user. If new, they will create a username, password, age. A User class instance should be created with that information along with adding the new username and password to the security dictionary. Once registered, or an existing user, it will be prompted to enter the username and password.
The username and password will be checked in the security dictionary (key is username, value is password). If in the dictionary, then the user can run a couple commands that affect the user class instance. For example, a function to increase the age by 1 (for birthdays).
Question: How do I load and save the security dictionary (username and password) and the user class instances (database for the user data: username, password, age, and height) so that a user can login in and out?
Here is my code:
class users:
def __init__(self, username, password, age):
self.username = username
self.password = password
self.age = age
#classmethod
def register(cls):
return cls(
str(input("Email: ")),
int(input("ID Pin Number XXXX: ")),
int(input("Age: "))
)
def load_func(file):
#Open the security file if present
if file == "security":
try:
with open("security.txt", "rb") as sct:
return pickle.load(sct)
except IOError:
with open("security.txt", "w+") as sct:
pickle.dump(dict(), sct)
return dict()
elif file == "userDatabase":
try:
with open("userDatabase.txt", "rb") as dat:
return pickle.load(dat)
except IOError:
with open("userDatabase.txt", "w+") as dat:
pickle.dump(dict(), dat)
return dict()
def saveData(file, data):
if file == "security":
with open("security.txt", "wb") as sct:
pickle.dump(data, sct)
elif file == "userDatabase":
with open("userDatabase.txt", "wb") as dat:
pickle.dump(data, dat)
else:
print("Error with saving file")
First of all: If you ever save passwords from users other than fictive testing users, be sure to hash the passwords using hashlib.
Now to your problem: Your users class is meant to represent one single user and should be renamed to User, in order to match PEP8 code standard (classes are CapitalLetters) and because it's more intuitive that a class named User represents one user.
You could then save the username and password combination using dill. Later on, you could load the dill string to re-create the exact object that it was before saving:
import dill
class User:
def __init__(self, username, password, age):
self.username = username
self.password = password
self.age = age
#classmethod
def register(cls):
return cls(
str(input("Email: ")),
int(input("ID Pin Number XXXX: ")),
int(input("Age: "))
)
#classmethod
def load(cls, file: str):
with open(file, "rb") as f:
return dill.load(f)
def save(self):
with open(self.username, "wb") as f:
dill.dump(self, f)
Max = User("Max", "SecUrEP4$$W0rD", 42)
Max.save()
Max2 = User.load("Max")
print(Max2.username)
If you found this helpful, please leave an UP,
if you have any further questions, leave a comment! :)
Related
I want to create some users just to populate my database, so using decorators I created a method inside a class for it. I returned the results into a list and used the information without a problem. But after a while I thought that once I was working with classes wouldn't be dumb to use lists? I feel that I am kind of moving backwards since, at least in my understanding, it might be possible to access those values directly.. But the truth is I struggled on attempting to instantiate dynamically and access those instances. So, how could I do that properly? Here is the code I wrote in the first attempt:
class User:
def __init__(self, user_name, password, email, i=0):
self.user_name = user_name
self.password = password
self.email = email
#classmethod
def from_generate(cls, amount):
user_name = 'user' + str(amount)
password = 'password000.' + str(amount)
email = 'user' + str(amount) + "#whatever.com"
return cls(user_name, password, email)
in another file:
def user_generator(user_qty=0):
user_list = []
for i in range(1, user_qty + 1):
# call the class method to generate users
instance = User.from_generate(i)
user_list.append(instance)
return(user_list)
users = user_generator(5)
if __name__ == "__user_generator__":
user_generator()
I am trying to simulate a system access portal using classes and methods. I want to be able to ask the user for their username using input(), check if that input is an object of class User and if so, check if the password is correct for the username. When I use instance of it is returning false. How can I modify this to work?
class User():
def __init__(self, username, password):
self.username = username
self.password = password
def change_pw(self, new_password):
self.password = new_password
jshannon = User("jshannon","AbC!23")
print(jshannon.username)
print(jshannon.password)
jshannon.change_pw("(i*u&y1")
print(jshannon.password)
input_user = input("What is your username? ")
print(isinstance(input_user, User))
User inputs are strings. Always. Period. So you can not "check if that input is an object of class User" - it will never be.
The solution here is to maintain a collection of User instances, and use the input string to search for a matching user.
class UsersCollection(object):
def __init__(self):
# we store users in a dict, with user.usernale as key
self._users = {}
def add(self, user):
if user.username in self._users:
raise ValueError("username '{}' already in used".format(user.username))
self._users[user.username] = user
def get(self, username):
return self._users.get(username)
users = UsersCollection()
users.add(User("jshannon","AbC!23"))
input_user = input("What is your username? ").strip()
userfound = users.get(input_user)
if userfound:
# you can do something with your user
else:
print("sorry, we don't know you")
Note that this is only suitable as a toy project of course.
If you are using Python 3.x (which I'm going to assume), input returns a string so isinstance(input_user, User) will always be False.
You will need to keep track of all User objects created and search for the object with the inputted name.
There are several different ways to do that. I'm going to assume that usernames are unique so I will use them in a shared set:
class User:
users = set()
def __init__(self, username, password):
self.username = username
self.password = password
self.users.add(username)
def change_pw(self, new_password):
self.password = new_password
jshannon = User("jshannon", "AbC!23")
print(jshannon.username)
print(jshannon.password)
jshannon.change_pw("(i*u&y1")
print(jshannon.password)
input_user = input("What is your username? ")
print(input_user in User.users)
# will output True if input_user is jshannon, otherwise False
Note that this is just an example, and it is not bullet-proof nor the best design (one may argue if the users set even belongs to the User class Hint: probably not). If an object's username changes after the initialization the set will not be updated and you may get wrong results. This particular problem can be solved by changing self.username to a property but I suppose that is out of scope of this Q&A.
I am not sure if this is what you want to do but you cant try this
add a list to your class list_of_usernames = []
and then in __init__() append username to the list_of_usernames and at the end
print(input_user in User.list_of_usernames)
so your code will look like this
class User():
list_of_usernames = []
def __init__(self, username, password):
self.username = username
self.password = password
self.list_of_usernames.append(username)
def change_pw(self, new_password):
self.password = new_password
jshannon = User("jshannon","AbC!23")
print(jshannon.username)
print(jshannon.password)
jshannon.change_pw("(i*u&y1")
print(jshannon.password)
input_user = input("What is your username? ")
print(input_user in User.list_of_usernames)
I'm not sure how to describe the issue but I'll try it.
Background info
I have in my Django web application a function where the user can import other users. The user can via drag and drop import a .csv file which gets converted to a JSON 2D Array (with Papaparse JS)
In the view, I loop through the elements in the 2D array and create an "Importuser" which contains some properties like "firstname", "lastname", email and so on.
class Importuser:
firstname = None
lastname = None
email = None
import_errors = []
def __init__(self, fn, ln, e):
self.firstname = fn
self.lastname = ln
self.email = e
class Importerror:
message = None
type = None
def __init__(self, m, t):
self.message = m
self.type = t
In the for-loop, I also validate the email-address, so that there are no doubled users.
data = jsonpickle.decode(method.POST["users"])
users = []
for tempuser in data:
u = validate(Importuser(tempuser[0], tempuser[1], tempuser[2])
users.append(u)
In the validate function I check if there any user with the same email
def validate(user : Importuser):
user_from_db = User.objects.filter(email=user.email)
if user_from_db:
user.import_errors.append(Importerror("The user exists already!", "doubleuser"))
return user
Issue
After the for-loop finished all user have the same error but not when I print each user while doing the for-loop. The Importerror-Object in each user refers to the same memory location but in my test import should only have one user an error.
test.csv:
Dave,Somename,dave#example.com
Joe,Somename2,joe#example.com
Yannik,Somename3,yannik#example.com <<That's me (exsiting user)
What I'm doing wrong? can someone help me to understand why this happens?
You've defined import_errors as a class-level static, so it's shared between all instances of Importuser.
See: Static class variables in Python
For your particular problem, rewrite your classes as
class Importuser:
def __init__(self, firstname, lastname, email):
self.firstname = firstname
self.lastname = lastname
self.email = email
self.import_errors = []
class Importerror:
def __init__(self, message, type):
self.message = message
self.type = type
import_errors is a class-attribute of ImportUser. It should be a instance-attribute:
class Importuser:
def __init__(self, fn, ln, e):
self.firstname = fn
self.lastname = ln
self.email = e
self.import_errors = []
Newbie..
code:
class User:
def __init__(self, emailAddress, fName):
parts = emailAddress.split('#')
if len(parts) != 2:
raise Exception("Invalid email address: %s" % emailAddress)
self.emailAddress = emailAddress
self.emailMd5 = hashlib.md5(emailAddress).hexdigest()
self.domain = parts[1]
self.fName = fName
I want to be able to access 'fName', and return the value thats stored in it. Obviously this is not the way to do it! Working with example API code, and trying to extend it. I pass into user(emailAddress, fName) (First Name).
There code later goes on to use:
emailData['recipient'] = users[emailData['recipientMd5']].emailAddress
Which works, so I figured what I would do would also?
I know this should be a simple fix. Not sure what to google though, and example class tutorials I've read haven't covered what I'm trying to do.
import hashlib
class User:
def __init__(self, emailAddress, fName):
parts = emailAddress.split('#')
if len(parts) != 2:
raise Exception("Invalid email address: %s" % emailAddress)
self.emailAddress = emailAddress
self.emailMd5 = hashlib.md5(emailAddress).hexdigest()
self.domain = parts[1]
self.fName = fName
u = User("me#you.com","uname") # create instance
print u.fName # print instance attribute
You can access attributes directly from each instance.
I'm trying to make a function that checks if the user is logged in. I've placed the function outside of the mainpage class and it gives no errors until I try to use it insie the def get(self) within the MainPage class. The function looks like this:
def LoginCheck():
username = self.request.cookies.get('username')
password = self.request.cookies.get('password')
if username and password:
checkq = db.GqlQuery("SELECT * FROM Users WHERE username = :1 AND password = :2", username, password)
checkresult = checkq.get()
if checkresult is None:
self.redirect("/wrong")
else:
self.redirect("/wrong2")
and When I try to use it it returns:
line 14, in LoginCheck
username = self.request.cookies.get('username')
NameError: global name 'self' is not defined
What am I doing wrong?
You'll have to add "self" to your function definition. See section 9.3.2 of python's tutorial.
def LoginCheck(self):
username = self.request.cookies.get('username')
password = self.request.cookies.get('password')
if username and password:
checkq = db.GqlQuery("SELECT * FROM Users WHERE username = :1 AND password = :2", username, password)
checkresult = checkq.get()
if checkresult is None:
self.redirect("/wrong")
else:
self.redirect("/wrong2")