python classes dynamic object instantiation/creation - python

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

Related

Why my add_pass function does not work? I am a newbie programmer so please don't judge

I need help, I really dont see a problem here why my add_pass method does not add the arguments to the dictionary.
class Password:
def __init__(self,media,password):
self.password = password
self.media = media
self.all_passwords = {}
self.all_passwords.setdefault(self.media,self.password)
def add_pass(self,media,password):
self.all_passwords[self.media] = self.password
b = Password('instagram','pass123')
b.add_pass('fb', 'pass12345')
In your add_pass function, remove self. from self.media and self.password. Those refer to the class attributes rather than the arguments:
def add_pass(self,media,password):
self.all_passwords[media] = password

Instanceof - using classes to simulate system access

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)

How to create and print the contents of a class?

I am creating a class structure in python for a city, that stores the name, country, population and language for a city, all of which are input by the user. The information shall then be printed.
I think that I may be successful in storing the information within the class structure (although this may be wrong as well), but I am unsuccessful in printing the information. Currently, I am receiving the error that int object is not subscriptable.
class User():
def _init_(self, username, password, email, numOfLogins):
User.username = username
User.password = password
User.email = email
User.numOfLogins = numOfLogins
#User Record Array Creation
def createUserArray(num , User):
UserArray = []
for x in range(num):
UserArray.append(User)
return UserArray
#User Record Array Population
def populateUserArray(num, UserArray):
for x in range(len(userArray)):
UserArray[x].username = str(input("Enter username."))
UserArray[x].password = str(input("Enter password."))
UserArray[x].email = str(input("Enter email address."))
UserArray[x].numOfLogins = int(input("Enter number of logins."))
return UserArray
#User Record Array Display
def displayUserArray(UserArray, num):
for x in range(len(userArray)):
print(UserArray[x].username, UserArray[x].password, UserArray[x].email, str(UserArray[x].numOfLogins))
#Top Level Program
numOfUsers = 3
userArray = createUserArray(numOfUsers, User)
userArray = populateUserArray(numOfUsers, userArray)
displayUserArray(numOfUsers, userArray)
The contents of the class should all be displayed at the end of the program, but at the minute my program crashes due to the error - int object is not subscriptable.
you can always implement the method : __str__(self) of an object , and then when you just print it with :
your_obj = User(...)
print your_obj
your __str__(self) will be called and you can return from it whatever you want to print.
for example:
def __self__(self):
return `this class has the following attributes: %s %s %s %s` % (self.username,self.password,self.email ,self.numOfLogins )
and this what will get print, i think it is more efficient and well coded to work like that and not creating a function that print each class attribute separately.
The cause of your error is quite simple and obvious: you defined the function as displayUserArray(UserArray, num) but call it with displayUserArray(numOfUsers, userArray) - IOW you pass the arguments in the wrong order.
This being said, almost all your code is wrong, you obviously don't get the difference between a class and instance and how to use a class to create instances. I strongly suggest you read at least the official tutorial, and check a couple other tutorial and/or example code on the topic of classes and instances.

Python List Bug in a for loop

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 = []

How to create a unique random username for django?

I want visitors of my page to be able to create entries without registering first. When they register later I want everything they have created within that session to belong to their user account.
To achieve that I just want to create blank users with random usernames when entries from non users are made.
What is the most elegant way to create a unique username randomly avoiding any collision?
Should I just make a while loop that generates usernames and tries to save them to the db with a break upon success or is there a better way?
Most scripts I've seen just create a random string, but that has the danger of a collision. Is there any Django function that creates random usernames based on which usernames are already taken?
No, django doesn't have such function. So you have to check for the existence of the generated username in the loop.
I created a mixin that creates a random username based on firstname, lastname and makes sure this username doesnt already exist in db User model:
random_username_mixin.py
import random
import string
from core.models import CustomUser
class RandomUsernameMixin:
"""
using firstname & lastname
create a random username (all lower case)
that doesnt already exist in db
"""
num_of_random_letters = 3
num_of_random_numbers = 2
user_model = CustomUser
def get_username(self, firstname=None, lastname=None):
username = ''
if firstname and lastname \
and firstname != '' and lastname != '':
username = firstname[0] + lastname[0]
while True:
random_letters = string.ascii_lowercase
random_numbers = string.digits
username += self.get_random_char(
random_letters, self.num_of_random_letters
)
username += self.get_random_char(
random_numbers, self.num_of_random_numbers
)
if self.username_exist_in_db(username) is False:
return username
def username_exist_in_db(self, username):
"""
:return: True if username already exist in db
else False
"""
q = self.user_model.objects.filter(username=username)
return q.exists()
def get_random_char(self, ip_str, n):
return (''.join(
random.choice(ip_str)
for i in range(n)
))
Following is the testing code. It tests the above code:
test_random_username_mixin.py
from django.test import TestCase
from miscellaneous.mixins.random_username_mixin import RandomUsernameMixin
class TestRandomUsernameMixin(RandomUsernameMixin,
TestCase):
def test_username_with_fn_ln(self):
fn = 'aseem'
ln = 'hegshetye'
username = self.get_username(
firstname=fn, lastname=ln
)
len_of_initials = 2
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)
def test_username_without_fn_ln(self):
username = self.get_username()
len_of_initials = 0
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)

Categories