Python OOP Factory Pattern - python

I am still learning OOP Design Pattern and everything I have read so far says that Factory Patterns are commonly used. I am still trying to learn this pattern. For my program I am creating an Abstract Factory called "person" and my factory called "personFactory" should let you create different types of people (Users, Customers, Plumbers, etc...). With my current code I am getting this error:
AttributeError: 'NoneType' object has no attribute 'fName'
This is my code:
person.py
import abc
class person:
__metaclass__ = abc.ABCMeta
fName = ""
mName = ""
lName = ""
address = ""
city = ""
state = ""
zipcode = ""
email = ""
phone = ""
dob = None
personFactory.py
from person import person
class personFactory(person):
def createUser(self):
uName = ""
password = ""
role = ""
def __init__(self,uName,password,role):
self.uName = uName
self.password = password
self.role = role
def login(uName,password):
if(uName == self.uName and password == self.password):
return "Logged In"
else:
return "Did not log in"
def logout():
return "Logout"
def createCustomer(self):
items = []
balace = 0
def __init__(self,balance):
self.balance = balance
def AddToCart(item):
self.items.append(item)
print("Item added")
def Order(items):
totalprice = 0
for item in items:
totalprice =+ item.price
return totalprice
def Pay(payment):
self.balance =- payment
return self.balance
main.py
import personFactory
class main():
pf = personFactory.personFactory()
user1 = pf.createUser()
user1.fName = "John"
user1.lName = "Smith"
user1.uName = "jSmith"
user1.password = "Jamestown"
customer1 = pf.createCustomer()
customer1.fName = "George"
customer1.lName = "Washington"
customer1.balance = 100
main()
I'm not sure why fName is a NoneType. What am I doing wrong? Any help would be greatly appreciated!

You have the constructor inside the create_user method. As Ignacio was saying the init function must be outside of the create_user function, in order for you to pass the name, pass and role to the person_factory object at creation.
Or alternatively you could pass all those value to the create_user method as arguments and leave the class constructor out of the work.
Could be something like this...
class personFactory(person):
def __init__(self,uName,password,role):
self.uName = uName
self.password = password
self.role = role
def createUser(self):
user = Person()
user.type = "user"
user.uName = self.uName
user.password = self.password
user.role = role
return user
Or...
class personFactory(person):
def createUser(self, uName, password, role):
user = Person()
user.type = "user"
user.uName = uName
user.password = password
user.role = role
return user
I would also suggest that you made use of inheritance and made concrete classes based on your abstract classes that represent each of your objects.
Like...
class User(Person):
def __init__(name, password, role):
self.name = name
self.type = "User"
self.password = password
So you can have a User class, and a Customer class, and each method of your factory can create the corresponding object, instead of a regular Person.

Related

how can i make a substancial image from the code

python doesn't work, it should return "new user being created", but nothing works is it a bug?
class User:
def __int__(self):
print("new user being created...")
user_1 = User()
user_1.id = "001"
user_1.username = "angela"
print(user_1.username)
user_2 = User()
user_2.id = "002"
user_2.username = "jack"
i already tryed everything, why doesn't it print anything? in def int(self):

How can I get data for a class object, taking input from user of which object he would like to view?

First i created a class named 'employed' which looks like this-
class employed:
def __init__(self,name, age, salary, role):
self.name = name ; self.age = age
self.salary = salary ; self.role = role
def givedata(self):
return(f"name : {self.name}\nage : {self.age}\nsalary : {self.salary}\nrole : {self.role}")
Then, i created two class objects for this class-
saksham = employed("Saksham", 13, 10000, "developer")
rohan = employed("Rohan", 15, 12000, "team leader")
Now i want to take input from the user of which object's data he like to view. How can i do that?
First, we defined a function which returns the user who matches the name
if the function returns none means there is no user that name otherwise it will return user.
Before that, I've added all users into list for convineince
saksham = employed("Saksham", 13, 10000, "developer")
rohan = employed("Rohan", 15, 12000, "team leader")
objects = []
objects.append(saksham)
objects.append(rohan)
def view_object(name):
for user in objects:
if user.name == name:
return user;
name = input("Hey User... Who do you want to view: "
user = view_object(name)
if user is None:
print("Sorry there is no user with this name")
else:
print(str(user))
There is no switch case in python but you can implement it as follows
define these functions in class
def get_name(self):
return self.name
def get_salary(self):
return self.salary
then use the following method
def numbers_to_months(argument):
switcher = {
1: object.get_salary(),
2: object.get_name(),
}
# Get the function from switcher dictionary
func = switcher.get(argument, lambda: "Invalid month")
# Execute the function
print get_salary()

attributeError: 'list' object has no attribute.....

I am getting attributeError, but I don't understand....
class User():
def __init__(self, first, last, age):
self.first = first
self.last = last
self.age = age
self.login_attempt = 0
class Admin(User):
def __init__(self, first, last, age):
super().__init__(first, last, age)
self.privilages = Privilages()
class Privilages():
def __init__(self, privilages = ''):
self.privilages = []
def show_privilages(self):
print("There are the privilages... : ")
if self.privilages:
for privilage in self.privilages:
print("- " + privilage)
else:
print("The user has no privilages. ")
sarah.privilages = ['can add post', 'can delete post']
sarah.privilages.show_privilages()
I am not sure what I am missing here, I used for loops to go over the list and print it out, however I keep getting error of "'list' object has no attribute 'show_privileges'"
You're assigning a list to sarah.privilages, so it surely does not have a show_privilages method. You should make the __init__ method of Admin take a list of privileges as a parameter, so it can pass on to the __init__ method of Privilages to initialize its privilages attribute:
class Admin(User):
def __init__(self, first, last, age, privilages):
super().__init__(first, last, age)
self.privilages = Privilages(privilages)
class Privilages():
def __init__(self, privilages):
self.privilages = privilages
def show_privilages(self):
print("There are the privilages... : ")
if self.privilages:
for privilage in self.privilages:
print("- " + privilage)
else:
print("The user has no privilages. ")
sarah = Admin('sarah','mary','smith', ['can add post', 'can delete post'])
sarah.privilages.show_privilages()
This outputs:
There are the privilages... :
- can add post
- can delete post
Write a separate Privileges class. The class should have one
attribute, privileges, that stores a list of strings.
Move the show_privileges() method to this class. Make a Privileges instance
as an attribute in the Admin class. Create a new instance of Admin and use your
method to show its privileges
class User():
"""Represent a simple user profile."""
def __init__(self, first_name, last_name, username, email, location):
"""Initialize the user."""
self.first_name = first_name.title()
self.last_name = last_name.title()
self.username = username
self.email = email
self.location = location.title()
class Admin(User):
def __init__(self, first_name, last_name, username, email, location):
super().__init__(first_name, last_name, username, email, location)
#Initialize an empty set of privileges.
self.privileges= Privileges()
class Privileges():
def __init__(self,privileges =[]):
self.privileges = privileges
def Show_privileges(self):
print("\nPrivileges: ")
if self.privileges:
for privilege in self.privileges:
print("- " + str(privilege))
else:
print("- this user has no privileges.")
eric = Admin('suraj', 'boi', 'e_mater', 'e_matthes100#example.com', 'alaska')
eric.describe_user()
eric.privileges.Show_privileges()
print("\nAdding privileges...")
eric_privileges = [
'can reset passwords',
'can moderate discussions',
'can suspend accounts',
]
eric.privileges.privileges = eric_privileges
eric.privileges.Show_privileges()

AttributeError when calling instance method I defined

I coded this in python 3 and it is showing an attribute error.code is
as following:
import datetime
class MessageUser():
User_Details = []
Messages = []
base_message = """Hi {name}!
Thank you for the purchase on {date}.
We hope you are exicted about using it. Just as a
reminder the purcase total was ${total}.
Have a great time!
from Pritom_Mazhi
"""
def add_user(self, name, amount, email=None):
name = name[0].upper() + name[1:].lower() #Capitalizing the first letter of all names - formatted name
amount = "%.2f" %(amount) #formatted amount
detail = {
"name" : name,
"amount" : amount,
}
today = datetime.date.today()
date_text = '{tday.day}/{tday.month}/{tday.year}'.format(tday=today) #formatted date
detail["date"] = date_text
if email is not None:
detail["email"] = email
self.User_Details.append(detail)
def get_details(self):
return self.User_Details
def make_message(self):
if len(self.User_Details) > 0:
for detail in self.get_details(): #for detail in self.User_Details
name = detail["name"]
amount = detail["amount"]
date = detail["date"]
email = detail["email"]
message = self.base_message
formatted_message = message.format(
name = name,
total = amount,
date = date,
)
self.Messages.append(formatted_message)
return self.Messages
else:
return []
obj = MessageUser()
obj.add_user("Pritom", 123.32, email='hello#teamcfe.com')
obj.add_user("jon Snow", 94.23)
obj.add_user("Sean", 93.23)
obj.add_user("Emilee", 193.23)
obj.add_user("Marie", 13.23)
obj.get_details()
obj.make_message()
when i run it i get this error:
File "Class_StringFormat.py", line 57, in <module>
obj.get_details()
AttributeError: 'MessageUser' object has no attribute 'get_details'
i simply can't find what wrong i did there and so can't manage to fix it.
If your indentation is reproduced correctly in the question, get_details is defined inside add_user and is not visible from outside.
You should unindent the definition of get_details and make_message to be on the same level as add_user:
def add_user(self, name, amount, email=None):
# method body...
def get_details(self):
return self.User_Details
def make_message(self):
# method body

Saving from dictionary to file (error)

I'm taking my first Python class so please bear with me, I have ZERO experience in programming but I'm very eager to learn. If you could steer me in the right direction I'd really appreciate it. Thank you in advance.
I've looked through previous questions but I wasn't able to find one that fully helped/explained where I'm getting stuck. I have a dictionary that stores team members(names, phone, jersey) and need to be able to write this to a file. Below is what I currently have, when I run this I get the error AttributeError:'dict' object has no attribute 'getname'.
class Member:
def get name(self):
return self.name
def get phone(self):
return self.phone
def get jersey(self):
return self.jersey
members={}
def saveData(members, filename):
filename=input("Filename to save:")
outFile=open(filename,"wt")
for x in members.keys():
name=members[x].getname
phone=members[x].getphone
jersey=members[x].getjersey
outFile.write(name+","+phone","+jersey+"\n")
print("Data Saved")
outFile.close()
Member class
You've put a space in the function name, so it won't work.
Too, you don't seem to have an __init__ function.
class Member:
def __init__(self, name, phone, jersey):
self.name = name
self.phone = phone
self.jersey = jersey
def get_name(self):
return self.name
def get_phone(self):
return self.phone
def get_jersey(self):
return self.jersey
Anyway, it's a lot easier that just don't make these get functions; the user can get the variables of a class using the dot syntax.
class Member:
def __init__(self, name, phone, jersey):
self.name = name
self.phone = phone
self.jersey = jersey
shell:
>>> member1 = Member("Dave", "123456789", "red")
>>> member.name
'Dave'
>>> member.phone
'123456789'
>>> member.jersey
'red'
saveData function
It won't work, you should do this:
def saveData(members): # don't include filename, it's going to be redefined later
filename = input("Filename to save: ") # space at the end
with open(filename, 'wt') as outFile: # using with for files is recommended
# then you don't need to close the file
for x in members: # you can directly iterate from a dict
name = x.get_name() # you didn't call the function at all
phone = x.get_phone() # members[x] not necessary
jersey = x.get_jersey()
outFile.write(name+", "+phone+", "+jersey+"\n") #missing + sign
print("Data Saved")
Working example
__init__.py
class Member:
def __init__(self, name, phone, jersey):
self.name = name
self.phone = phone
self.jersey = jersey
def get_name(self):
return self.name
def get_phone(self):
return self.phone
def get_jersey(self):
return self.jersey
def saveData(members):
filename = input("Filename to save: ")
with open(filename, 'wt') as outFile:
for x in members:
name = x.get_name()
phone = x.get_phone()
jersey = x.get_jersey()
outFile.write(name+", "+phone+", "+jersey+"\n")
print("Data Saved")
IDLE shell
>>> members = [Member("Dave", "123456789", "red"),
Member("Tom", "133742097", "yellow"),
Member("Elisa", "122333444", "blue"),
Member("John", "987654321", "blue")
]
>>> saveData(members)
Filename to save: output.txt
Data Saved
output.txt
Dave, 123456789, red
Tom, 133742097, yellow
Elisa, 122333444, blue
John, 987654321, blue
You can define getname, getphone in your Member class as follows:
class Member:
def getname(self):
return self.name
def getphone(self):
return self.phone
def getjersey(self):
return self.jersey
Then you can get values from getters in your saveData function :
name=members[x].getname()
phone=members[x].getphone()
jersey=members[x].getjersey()

Categories

Resources