Object Oriented Programming with python issue with the list? - python

Code is not printing the multiple elements that I add to it. Instead it is just printing out the recently added element. can anyone guide me on this?
class bikes:
def __init__(self,make,name,model):
self.make = make
self.name = name
self.model = model
self.all_bikes = []
def total_bikes(self):
self.counter = 0
dict_bikes = {"Make": self.make,
"Name": self.name,
"Model": self.model}
self.all_bikes.append({self.counter : dict_bikes})
self.counter = self.counter + 1
def show_all_bikes(self):
print(self.all_bikes)
class user(bikes):
def __init__(self):
self.user_make = make = input("Enter the Company name: ")
self.user_name = name = input("Enter the Bike name: ")
self.user_model = model = input("Enter the Model name: ")
super().__init__(make,name,model)
bikes.total_bikes(self)
while True:
menu = input("Enter Add,View to Add a new bike and View all bikes: ")
if menu.upper() == "ADD":
add_bike = user()
elif menu.upper() == "VIEW":
add_bike.show_all_bikes()
else:
print("Invalid Command")

This construct
while True:
menu = input("Enter Add,View to Add a new bike and View all bikes: ")
if menu.upper() == "ADD":
add_bike = user()
elif menu.upper() == "VIEW":
add_bike.show_all_bikes()
else:
print("Invalid Command")
if ADD is choice then new instance of user class is created, which has empty all_bikes. You need to equip your class with seperate method for adding bike and __init__ and createdinstance of user class before entering while loop.

Related

Python - How to store desired amount of objects of a class in a list?

I would like to make a list that stores all objects of the JoJo class in a list according to the desired amount of users.
Example: If I want to create two users of the JoJo class, the code will allow me to enter the name and stand of these users and print them at the end of the code. The necessary changes for this will be on the main.py page.
jojo.py
class JoJo:
# Construct
def __init__(self):
self.status_stand = False
# Destruct
def __del__(self):
print (f"The user {self.getName()} was deleted by the destruct.")
# Getter
def getName(self): return self.name
def getStand(self): return self.stand
# Setter
def setName(self, noma): self.name = name
def setStand(self, stand): self.stand = stand
# Method activeStand()
def activeStand(self):
if self.status_stand:
print(f"{self.getStand()} is already invoked.")
else:
self.status_stand = True
print(f"{self.getStand()} was invoked.")
# Méthod desactiveStand()
def desactiveStand(self):
if self.status_stand == False:
print(f"{self.getStand()} is already hidden.")
else:
self.status_stand = False
print(f"{self.getStand()} was hidden.")
# Method talk()
def talk(self):
print(f"Name: {self.getName()} | Stand: {self.getStand()}")
print ("Stand status: " + {True: "Active.", False: "Inactive."}[self.status_stand])
self.activeStand() if self.status_stand else self.desactiveStand()
main.py
from jojo import JoJo
jojo = JoJo()
while True:
name = str(input("Enter username: "))
if (len(nome.strip()) <= 0):
print("Username cannot be empty.")
else:
jojo.setNome(name.title())
break
while True:
stand = str(input(f"Enter the name of the {jojo.getName()} stand: "))
if (len(stand.strip()) <= 0):
print(f"The name of {jojo.getNome()} stand cannot be empty.")
else:
jojo.setStand(stand.title())
break
jojo.talk()
del jojo
All you need is a list object. Assuming we accept user names until a blank value tells us to stop:
jojo_list = list()
while True:
name = input("Enter username: ")
if name.strip() == '':
break
jojo = JoJo()
jojo.setName(name.strip().title())
jojo_list.append(jojo)
Now you can simply loop over your list of jojo objects and do things to them:
for jojo in jojo_list:
print(jojo.getName())
Details on list objects: https://docs.python.org/3/tutorial/datastructures.html

how to fix this error? python <__main__.Employee at 0x7f2358d89910> None

here is the output
Enter your ID: 1234
Enter your NAME: Name
Enter your AGE: 20
Enter your Birthdate: 12
EMPLOYMENT STATUS:
Enter 1 if you are employed:
Enter 2 if unemployed:
1
Enter 1 if the employment is permanent:
Enter 2 if the employment a job-order:
2
<__main__.Employee at 0x7f2358d89910>
None
the NONE keeps appearing, I want to get the information which is set by the user in display(employee_object) but I don't know hw
class Employee(object):
# initialize values
def __init__(self):
self.id = ""
self.name = ""
self.age = ""
self.birthdate = ""
self.status = ""
# setter methode for setting values to the class properties
def set_id(self, id):
self.id = id
def set_name(self, name):
self.name = name
def set_age(self, age):
self.age = age
def set_birthdate(self, birthdate):
self.birthdate = birthdate
def set_status(self, status):
self.status = status
# getter methode for getting values of the class properties
def get_id(self):
return self.id
def get_name(self):
return self.name
def get_age(self):
return self.age
def get_birthdate(self):
return self.birthdate
def get_status(self):
return self.status
# methode which takes object as an argument and display its properties
def display(employee_object):
print("ID : ", employee_object.get_id())
print("Name : ", employee_object.get_name())
print("Age : ", employee_object.get_age())
print("Birthdate : ", employee_object.get_birthdate())
print("Status : ", employee_object.get_status())
# calls class Employee
# Main methode of the program
if __name__ == "__main__":
employee_List = []
emp_1 = Employee()
# appending objects to the list
employee_List.append(emp_1)
# Initializing each objects of the list
for employee in employee_List:
emp_id = input("Enter your ID: ")
employee.set_id(emp_id)
emp_name = input("Enter your NAME: ")
employee.set_name(emp_name)
emp_age = input("Enter your AGE: ")
employee.set_age(emp_age)
emp_birthdate = input("Enter your Birthdate: ")
employee.set_birthdate(emp_birthdate)
emp_stat1 = input("EMPLOYMENT STATUS: \nEnter 1 if you are employed: \nEnter 2 if unemployed: \n")
if emp_stat1 == '1':
emp_stat2 = input("Enter 1 if the employment is permanent: \nEnter 2 if the employment a job-order: \n")
if emp_stat2 == '1':
employee.set_status = "PERMANENT"
elif emp_stat2 == '2':
employee.set_status = "JOB ORDER"
elif emp_stat1 == '2':
emp_stat2 = input("Enter 1 if you are a freelancer: \nEnter 2 if you are seeking a job: \n ")
if emp_stat2 == '1':
employee.set_status = "FREELANCER"
elif emp_stat2 == '2':
employee.set_status = "JOB SEEKER"
# Displaying each objects of the list
for employee_object in employee_List:
print(display(employee_object))
When using print, python will call the str method of your class, therefore if you want to print readable information you can do it by using
print(employee_object)
and inserting the str method to your class, which could be something like:
def __str__(self):
return f'The employee {self.name} is {self.status}'
As no return is specified in display method, the default is None , see How to prevent Python function from returning None
Your display method shows things, you don't expected it to return anything, so call it like
# Displaying each objects of the list
for employee_object in employee_List:
display(employee_object)
Then some python-coding specifics
What's the pythonic way to use getters and setters? using #property
# If you defined a self._name attribut
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name
# GET use : employee.name
# SET use : employee.name = emp_name
Use a constructor with parameters, that nicer
class Employee(object):
def __init__(self, emp_id, name, age, birthdate, status):
self._id = emp_id
self._name = name
self.age = age
self.birthdate = birthdate
self.status = status
Don't use a outer method display, there is a built-in way with __str__ (or __repr__) see Difference between __str__ and __repr__, add it to the Employee class and it'll be use then you do print(emp) where emp is an Employee instance
def __str__(self):
return "\n".join((
f"ID: {self.id}",
f"Name: {self.name}",
f"Age: {self.age}",
f"Birthdate: {self.birthdate}",
f"Status: {self.status}",
))
Then the principe you used of create a list / add one instance / iterate on the list to populate the instance isn't a good idea, because you have a fixed amount of employee which isn't dynamically given.
I'd suggest to use a while loop that will stops when you enter stop at the ID input
employee_List = []
while True:
emp_id = input("Enter your ID: ('stop' to quit)")
if emp_id == "stop":
break
emp_name = input("Enter your NAME: ")
emp_age = input("Enter your AGE: ")
emp_birthdate = input("Enter your Birthdate: ")
emp_stat1 = input("EMPLOYMENT STATUS: \nEnter 1 if you are employed: \nEnter 2 if unemployed: \n")
if emp_stat1 == '1':
emp_stat2 = input("Enter 1 if the employment is permanent: \nEnter 2 if the employment a job-order: \n")
if emp_stat2 == '1':
emp_status = "PERMANENT"
elif emp_stat2 == '2':
emp_status = "JOB ORDER"
elif emp_stat1 == '2':
emp_stat2 = input("Enter 1 if you are a freelancer: \nEnter 2 if you are seeking a job: \n ")
if emp_stat2 == '1':
emp_status = "FREELANCER"
elif emp_stat2 == '2':
emp_status = "JOB SEEKER"
emp = Employee(emp_id, emp_name, emp_age, emp_birthdate, emp_status)
employee_List.append(emp)
for employee_object in employee_List:
print(employee_object, "\n")
FULL CODE

User input not saving into inventory list

Basically I am making an app to better assist me at managing my ebay store. I am still very new to programming and OOP. After watching some tutorials I pieced together the following code. Everything so far works pretty well. What I am currently stuck on is when the user inputs an item for inventory, it is not saving it. And, when the user wants to view the inventory the item they added wont populate. Any input or suggestions would be much apprenticed.
def Inventory():
All_Inventory = {}
class Ebay_Inventory:
def __init__(self, manufacturer, object_type, price):
self.manufacturer = manufacturer
self.object_type = object_type
self.price = price
def add_item(self):
manufacturer = input("Enter Manufacturer: ")
object_type = input("Enter what the item is: ")
price = input("Enter price: ")
item_info = Ebay_Inventory(manufacturer, object_type, price)
All_Inventory = item_info
print("Item added successfully")
def delete_item(self):
delete = input("What is the item you want to delete?: ")
if delete in All_Inventory.keys():
del[delete]
print("The item entered has been deleted.")
else:
print("Item not found")
def sale_status(self):
update = input("What is the item you want to update?:")
if update in All_Inventory.keys():
pass
else:
print("Item not found")
user=True
while user:
print("\n1. Add to item inventory")
print("2. Remove item from inventory")
print("3. Update sale status")
print("4. View inventory")
print("5. Exit program")
user_wants=input("What would you like to do today?")
if user_wants=="1":
Ebay_Inventory.add_item(input)
elif user_wants=="2":
Ebay_Inventory.delete_item(input)
elif user_wants=="3":
Ebay_Inventory.sale_status(input)
elif user_wants=="4":
print(All_Inventory)
elif user_wants=="5":
print("\n Thank you for using item inventory.")
break
elif user_wants!="":
print("\n Input not understood. Please try again.")
You need to read about Scope, OOP and dicts:
You are not adding to your Inventory.All_Inventory - you create a new local with All_Inventory = item_info
https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
Short description of the scoping rules?
You mix up static class attributes and instance attributes, read:
https://docs.python.org/3/tutorial/classes.html#class-objects.
What is the difference between #staticmethod and #classmethod?
You are deleting / accessing your dictionary wrongly - see :
https://docs.python.org/3/tutorial/datastructures.html#dictionaries
Delete an element from a dictionary
Fixed:
class Ebay_Inventory:
Inventory = {} # class property
#staticmethod
def print_inventory():
for k in Ebay_Inventory.Inventory:
for i in Ebay_Inventory.Inventory[k]:
print(k,i)
class Ebay_Item:
def __init__(self, key, manufacturer, object_type, price):
self.manufacturer = manufacturer
self.object_type = object_type
self.price = price
self.key = key
def __str__(self):
return f"{self.manufacturer} {self.object_type} {self.price}"
def __repr__(self):
return str(self)
#staticmethod
def add_item(key=None, man=None, obj=None, pri=None):
# use values if given, else ask - this is for demo purposes only
key = key or input("Enter key: ")
manufacturer = man or input("Enter Manufacturer: ")
object_type = obj or input("Enter what the item is: ")
price = pri or input("Enter price: ")
# create new item
item_info = Ebay_Inventory.Ebay_Item(key, manufacturer, object_type, price)
# add to class member, create key if need be
Ebay_Inventory.Inventory.setdefault(item_info.key,[]).append(item_info)
def delete_item(key=None):
delete = key or input("What is the item you want to delete?: ")
if delete in Ebay_Inventory.Inventory:
del Ebay_Inventory.Inventory[delete]
print("The item entered has been deleted.")
else:
print("Item not found")
def __str__(self):
return Ebay_Inventory.print_inventory()
# add 2 items and print
Ebay_Inventory.add_item(1,"Me","Me",1000)
Ebay_Inventory.add_item(2,"You","You",1000)
Ebay_Inventory.print_inventory()
# remove non existent and existent item and print
Ebay_Inventory.delete_item(3)
Ebay_Inventory.delete_item(2)
Ebay_Inventory.print_inventory()
Output:
1 Me Me 1000
2 You You 1000
Item not found
The item entered has been deleted.
1 Me Me 1000
Sorry to rework your code pretty extensively, but I think this is more like what you are going for:
class EbayInventory:
def __init__(self):
self.all_inventory = []
def print_items(self):
print('Current item list by index:')
for i in range(0, len(self.all_inventory)):
print("{} -> {}".format(i+1, self.all_inventory[i]))
def add_item(self):
manufacturer = input("Enter Manufacturer: ")
object_type = input("Enter what the item is: ")
price = input("Enter price: ")
item = {'manufacturer': manufacturer, 'type': object_type, 'price': price}
self.all_inventory.append(item)
print("Item added successfully")
def delete_item(self):
self.print_items()
delete = int(input("Item id you want to delete: "))
try:
del self.all_inventory[delete - 1]
print("The item entered has been deleted.")
except Exception as e:
print("An error occurred deleting that item, details below")
print(e)
def sale_status(self):
self.print_items()
update_index = int(input("Item id you want to update: "))
if update_index > len(self.all_inventory) or update_index <= 0:
print("You're trying to change an item that doesn't exist!!")
return
print("OK. Let's get that item up to date!")
manufacturer = input("Enter Manufacturer: ")
object_type = input("Enter what the item is: ")
price = input("Enter price: ")
item = {'manufacturer': manufacturer, 'type': object_type, 'price': price}
self.all_inventory[update_index - 1] = item
print("OK. We got that update taken care of")
if __name__ == "__main__":
my_app = EbayInventory()
while True:
print("\n1. Add to item inventory")
print("2. Remove item from inventory")
print("3. Update sale status")
print("4. View inventory")
print("5. Exit program")
user_wants = input("Please enter the number corresponding to how you would like help: ")
if user_wants == "1":
my_app.add_item()
elif user_wants == "2":
my_app.delete_item()
elif user_wants == "3":
my_app.sale_status()
elif user_wants == "4":
my_app.print_items()
elif user_wants == "5":
print("Thank you for using item inventory.")
break
else:
print("Input not understood. Please try again.")
You had a variable user that did nothing. You can simply enter an infinite loop with while True:. If you wanted to loop the way you did, then instead of a break you could have put a user = False to break out of the loop. This is sometimes a nifty trick, but doesn't make sense here I think. It seemed to me the inventory was really the only thing that would benefit by being stored in your class, and the methods could then access it to adjust it via a self.all_inventory. I moved your code to ask for item inputs to the add_item() and sale_status() methods, so now the main block of code looks a lot cleaner. I also wrapped it in if __name__ == "__main__": so that you can import this class to another project without running the entire program! I threw in some basic error checking with try: and except: clauses also. I think you were misunderstanding the difference between a Class and an Instance. So in my code the Class is EbayInventory, but the Instance is my_app. You create instances of your class just like I did with my_app = EbayInventory() and then the self now refers to my_app. In this manner I can call my_app.add_item(). You can have several instances of objects though, and they each have their own space in your computers memory. So you could have said:
app1 = EbayInventory()
app2 = EbayInventory()
app1.add_item()
And only the app1 will have any items, whereas app2 is still an empty list, but still has the methods to build an inventory via app2.add_item(). To answer your main question though, you never call your function Inventory() and therefore it doesn't exist to hold your information. When you call item_info = Ebay_Inventory(manufacturer, object_type, price) in fact you are making an Instance of a class, which is really nonsensical to do here because that means on the next line you could say item_info.add_item() and this would make another instance, yet you are not saving this information anywhere so you can never retrieve it!

Entering a Changing Class Object into a List for Python

I'm trying to make a program that creates objects from another class I made and calls the class methods based on user input. The problem I'm having is that once a object is created I'm trying to enter that object into a dictionary, so I can compress it with pickle for later use. I'm having trouble trying to find the best way to append these class objects into a list when the name for the created objects are the same as the name variable I prompt from the user. The lines I am talking about are lines 34 to 41. I have so far change it to set the object named personObject to create a object and repeat if another user is created. It seems to work, I just feel there is a better way.
from budgetaccount import *
import pickle
import sys
class mainprogram:
def __init__(self):
self.account_list = {}
self.name = ""
def main(self):
grab_user()
endProgram = 0
while endProgram != 6:
print('Welcome to our monthly budget program\n')
print('1-Create a new account')
print('2-Exit')
selection = input("Enter your Selection: ")
if selection != "":
choice = int(selection)
if choice == 1:
self.create_user()
if choice == 2:
break
continue
name = self.account_list[0]
name.showSetBudgetLimits()
def create_user(self):
cancel = False
while (True):
self.name = input("Type your username: ")
name = self.name
income = float(input("Enter your income: "))
personObject = BudgetAccount(name, income)
personObject.setUserExspenseLimit()
self.account_list.append({
"%s"% (name) : personObject
})
cont = input("Want to add another? (Y/N)")
if cont == "N":
break
continue
print(self.account_list)
self.pickle_data1()
def pickle_data1(self): ###Pickle writes to userdata1.pickle from account_list###
pickle_out = open("userdata1.pickle", "wb")
pickle.dump(self.account_list, pickle_out)
pickle_out.close()
def grab_user():
pickle_in = open("E:/Python/Lib/idlelib/userdata1.pickle","rb")
account_list = pickle.load(pickle_in)
print(account_list)
print(account_list)
test = ihateThis()
test.main()

How to properly use __repr__ when two classes are involved

I am working on some Python code where I create a basic ATM. The issue I am having is I am not able to get the result that I want its printing "<'function Account.balance at 0x012CBC90>" Instead of the actual balance number. So far I have only tested using jsmith. Feel free to call out any other issues that may cause a problem later.
class Account:
def __init__(self,user,pin,balance):
self.user = user
self.pin = pin
self.balance = int(balance)
def get_user(self):
return self.user
def get_pin(self):
return self.pin
def balance(self):
return int(self.balance)
def setBalance(self,newBalance):
self.balance = newBalance
def __repr__(self):
return str(self.user) + " " + str(self.pin) + " " + str(self.balance)
class ATM:
def withdraw(self,Person,amount):
result = Person - amount
return result
def check(self,Person):
Person = Account.balance
return str(Person)
def transfer(self,id1,id2):
pass
def __str__(self):
return self
def main():
Chase = ATM()
Database = []
Teron_Russell = Account("trussell",1738,0)
Joe_Smith = Account("jsmith",1010,1350)
print(Teron_Russell)
Database.append(Teron_Russell)
Database.append(Joe_Smith)
print("Welcome to the ATM")
id = input("Please enter your user ID: ")
pin = input("Enter your pin: ")
chosen = ""
for i in Database:
print("Test1")
name = Account.get_user(i)
print(name)
checkPin = Account.get_pin(i)
print(checkPin)
if id == name and pin == checkPin:
chosen = i
choice = input("What would you like to do. (Type 'Check','Withdraw','Transfer': ")
if(choice == "Check" or "check"):
print(Chase.check(chosen))
# if(choice == "Withdraw" or "withdraw"):
# wAmount = eval(input("How much would you like to Withdraw: "))
# # Chase.withdraw(Account.balance,)
# elif(choice == "Check" or "check"):
# Chase.check()
# else:
# print("Invalid Choice!")
if __name__ == "__main__":
main()
You named a variable and a method the same name, so the interpreter is confused on which one to use. Change the name of either the method or variable balance and you won't have this problem. Additionally, this isn't java, and you shouldn't use classes for no reason. Since you aren't using any instance variables, it is pointless to have all of those methods inside that class.

Categories