I have an inventory program that stores the ID number, item name, and the quantity in three different lists. These three lists are combined in an inventory list but, when the data is saves to a TextEdit document it stores the data in three different lists. How do I save this data in one dictionary. First ID number, item name, then qty.
Here is the full program code:
import os
class Inventory:
def __init__(self):
#AT LAUNCH GROUPS AND LOADING FUNCTION
self.ID = []
self.item = []
self.qty = []
self.load()
def remove(self, ID):
#REMOVING ITEMS FOR LISTS AND OUTPUT DOCUMENT
ix = self.ID.index(ID)
self.ID.pop(ix)
self.item.pop(ix)
self.qty.pop(ix)
self.save()
def add(self, ID, name, qty):
#ADDING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.ID.append(ID)
self.item.append(name)
self.qty.append(qty)
self.save()
def update(self, ID, update):
#UPDATING ITEMS FOR LISTS AND OUTPUT DOCUMENT
if update >= 0:
self.qty[self.ID.index(ID)] += update
elif update <= -1:
self.qty[self.ID.index(ID)] += update
self.save()
def search(self, ID):
#SEARCHING ITEMS FOR LISTS
pos = self.ID.index(ID) if ID in self.ID else -1
if pos >= 0:
return self.ID[pos], self.item[pos], self.qty[pos]
else:
return None
def __str__(self):
#FORMATTING
out = ""
zipo = list(zip(self.ID, self.item, self.qty))
for foobar in zipo:
out += f"ID Number : {foobar[0]} \nItem Name : {foobar[1]}\nQuantity : {foobar[2]}\n"
out += "----------\n"
return out
def save(self):
#WHERE TO SAVE TO
with open('inventory.dat','w') as f:
f.write(str(self.ID) + '\n' + str(self.item) + '\n' + str(self.qty))
def load(self):
#WHERE TO PUT DATA FROM WHEN RELAUNCHING PROGRAM
from os import path
if path.exists('inventory.dat'):
with open('inventory.dat','r') as f:
lns = f.readlines()
self.ID = eval(lns[0])
self.item = eval(lns[1])
self.qty = eval(lns[2])
def menuDisplay():
#MENU FOR PROGRAM
"""Display the menu"""
print('=============================')
print('= Inventory Management Menu =')
print('=============================')
print('(1) Add New Item to Inventory')
print('(2) Remove Item from Inventory')
print('(3) Update Inventory')
print('(4) Search Item in Inventory')
print('(5) Print Inventory Report')
print('(99) Quit')
def add_one_item(inventory):
#ADDING PROMPT AND ERROR CHECKING
print('Adding Inventory')
print('================')
while True:
try:
new_ID = int(input("Enter an ID number for the item: "))
if new_ID in inventory.ID:
print("ID number is taken, please enter a different ID number")
continue
new_name = input('Enter the name of the item: ').lower()
assert new_name.isalpha(), "Only letters are allowed!"
new_qty = int(input("Enter the quantity of the item: "))
inventory.add(new_ID, new_name, new_qty)
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def remove_one_item(inventory):
#REMOVING PROMPT AND ERROR CHECKING
print('Removing Inventory')
print('==================')
removing = int(input("Enter the item's ID number to remove from inventory: "))
inventory.remove(removing)
def ask_exit_or_continue():
#OPTION TO CONTINUE OR QUITE PROGRAM
return int(input('Enter 98 to continue or 99 to exit: '))
def update_inventory(inventory):
#UPDATING PROMPT AND ERROR CHECKING
print('Updating Inventory')
print('==================')
ID = int(input("Enter the item's ID number to update: "))
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
inventory.update(ID, update)
def search_inventory(inventory):
#SEARCHING PROMPT AND ERROR CHECKING
print('Searching Inventory')
print('===================')
search = int(input("Enter the ID number of the item: "))
result = inventory.search(search)
if result is None:
print("Item not in inventory")
else:
ID, name, qty = result
print('ID Number: ', ID)
print('Item: ', name)
print('Quantity: ', qty)
print('----------')
def print_inventory(inventory):
#PRINT CURRENT LIST OF ITEMS IN INVENTORY
print('Current Inventory')
print('=================')
print(inventory)
def main():
#PROGRAM RUNNING COMMAND AND ERROR CHECKING
inventory = Inventory()
while True:
try:
menuDisplay()
CHOICE = int(input("Enter choice: "))
if CHOICE in [1, 2, 3, 4, 5]:
if CHOICE == 1:
add_one_item(inventory)
elif CHOICE == 2:
remove_one_item(inventory)
elif CHOICE == 3:
update_inventory(inventory)
elif CHOICE == 4:
search_inventory(inventory)
elif CHOICE == 5:
print_inventory(inventory)
exit_choice = ask_exit_or_continue()
if exit_choice == 99:
exit()
elif CHOICE == 99:
exit()
except Exception as e:
print("Invalid choice! try again!"+str(e))
print()
# If the user pick an invalid choice,
# the program will come to here and
# then loop back.
main()
Thank you in advance.
Don't use 3 lists, use a dictionary containing dictionaries. The keys of the main dictionary will be the IDs, and the values will be dictionaries containing the name and quantity.
You can use JSON or pickle to save and load the data.
import os
import json
class Inventory:
def __init__(self):
#AT LAUNCH GROUPS AND LOADING FUNCTION
self.items = {}
self.load()
def remove(self, ID):
#REMOVING ITEMS FOR LISTS AND OUTPUT DOCUMENT
del self.items[ID]
self.save()
def add(self, ID, name, qty):
#ADDING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[ID] = {"name": name, "qty": qty}
self.save()
def update(self, ID, update):
#UPDATING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[ID]["qty"] += update
self.save()
def search(self, ID):
#SEARCHING ITEMS FOR LISTS
item = self.items.get(ID, None)
if item:
return ID, item['name'], item['qty']
else:
return None
def __str__(self):
#FORMATTING
out = ""
for id, d in self.items.items():
out += f"ID Number : {id} \nItem Name : {d['name']}\nQuantity : {d['qty']}\n"
out += "----------\n"
return out
def save(self):
#WHERE TO SAVE TO
with open('inventory.dat','w') as f:
json.dump(self.items, f)
def load(self):
#WHERE TO PUT DATA FROM WHEN RELAUNCHING PROGRAM
try:
with open('inventory.dat','r') as f:
self.items = json.load(f)
except:
print("Can't load old inventory, starting fresh")
self.items = {}
You should avoid accessing attributes directly outside the class, as it makes it difficult to reimplement the class so
if new_ID in inventory.ID:
should be
if inventory.search(new_ID):
Related
I have an inventory program that you can keep adding items into. But how/where do I put the .sort or .sort() for when I hit Option 5 (Print inventory report) it displays the information by ID number.
For example is I have ID numbers: 1, 4, 2, 3, 10 . When it print the report its 1,2,3,4,10.
I will attach the full program as I don't know when sorting should occur.
Full code:
import os
import json
class Inventory:
def __init__(self):
#AT LAUNCH GROUPS AND LOADING FUNCTION
self.items = {}
self.load()
def remove(self, ID):
#REMOVING ITEMS FOR LISTS AND OUTPUT DOCUMENT
del self.items[str(ID)]
self.save()
def add(self, ID, name, qty):
#ADDING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)] = {"name": name, "qty": qty}
self.save()
def update(self, ID, update):
#UPDATING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)]["qty"] += update
self.save()
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
return id, self.items[id]['name'], self.items[id]['qty']
return None
def __str__(self):
#FORMATTING
out = ""
for id, d in self.items.items():
out += f"ID Number : {id} \nItem Name : {d['name']}\nQuantity : {d['qty']}\n"
out += "----------\n"
return out
def save(self):
#WHERE TO SAVE TO
with open('data.txt','w') as outfile:
json.dump(self.items, outfile)
def load(self):
#WHERE TO PUT DATA FROM WHEN RELAUNCHING PROGRAM
try:
with open('data.txt','r') as json_file:
self.items = json.load(json_file)
except:
print("Can't load old inventory, starting fresh")
self.items = {}
def menuDisplay():
#MENU FOR PROGRAM
"""Display the menu"""
print('=============================')
print('= Inventory Management Menu =')
print('=============================')
print('(1) Add New Item to Inventory')
print('(2) Remove Item from Inventory')
print('(3) Update Inventory')
print('(4) Search Item in Inventory')
print('(5) Print Inventory Report')
print('(99) Quit')
def add_one_item(inventory):
#ADDING PROMPT AND ERROR CHECKING
print('Adding Inventory')
print('================')
while True:
try:
new_ID = int(input("Enter an ID number for the item: "))
if inventory.search(new_ID):
print("ID number is taken, please enter a different ID number")
continue
new_name = input('Enter the name of the item: ')
new_qty = int(input("Enter the quantity of the item: "))
inventory.add(new_ID, new_name, new_qty)
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def remove_one_item(inventory):
#REMOVING PROMPT AND ERROR CHECKING
print('Removing Inventory')
print('==================')
while True:
try:
removing = int(input("Enter the item's ID number to remove from inventory: "))
if inventory.search(removing):
inventory.remove(removing)
else:
print("Item not in inventory")
continue
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def ask_exit_or_continue():
#OPTION TO CONTINUE OR QUITE PROGRAM
return int(input('Enter 98 to continue or 99 to exit: '))
def update_inventory(inventory):
#UPDATING PROMPT AND ERROR CHECKING
print('Updating Inventory')
print('==================')
while True:
try:
ID = int(input("Enter the item's ID number to update: "))
if inventory.search(ID):
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
inventory.update(ID, update)
else:
print("ID number is not in the system, please enter a different ID number")
continue
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def search_inventory(inventory):
#SEARCHING PROMPT AND ERROR CHECKING
print('Searching Inventory')
print('===================')
while True:
try:
search = input("Enter the name of the item: ")
result = inventory.search(search)
if result is None:
print("Item not in inventory")
continue
else:
ID, name, qty = result
print('ID Number: ', ID)
print('Item: ', name)
print('Quantity: ', qty)
print('----------')
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def print_inventory(inventory):
#PRINT CURRENT LIST OF ITEMS IN INVENTORY
print('Current Inventory')
print('=================')
print(inventory)
def main():
#PROGRAM RUNNING COMMAND AND ERROR CHECKING
inventory = Inventory()
while True:
try:
menuDisplay()
CHOICE = int(input("Enter choice: "))
if CHOICE in [1, 2, 3, 4, 5]:
if CHOICE == 1:
add_one_item(inventory)
elif CHOICE == 2:
remove_one_item(inventory)
elif CHOICE == 3:
update_inventory(inventory)
elif CHOICE == 4:
search_inventory(inventory)
elif CHOICE == 5:
print_inventory(inventory)
exit_choice = ask_exit_or_continue()
if exit_choice == 99:
exit()
elif CHOICE == 99:
exit()
except Exception as e:
print("Invalid choice! try again!"+str(e))
print()
# If the user pick an invalid choice,
# the program will come to here and
# then loop back.
main()
Try this code as a a hot fix But should consider changing your data structure from dict which is unordered to something like a 2D array which can be sorted easily the below code take advantage of __str__ method and use it's fixed output and fact that different items will first differ in their ID number to sort it. To see difference in code look at __str__ (notice /n/r delimiter at end) then look at print_inventory function to see how I took advantage of this fact.
import os
import json
class Inventory:
def __init__(self):
# AT LAUNCH GROUPS AND LOADING FUNCTION
self.items = {}
self.load()
def remove(self, ID):
# REMOVING ITEMS FOR LISTS AND OUTPUT DOCUMENT
del self.items[str(ID)]
self.save()
def add(self, ID, name, qty):
# ADDING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)] = {"name": name, "qty": qty}
self.save()
def update(self, ID, update):
# UPDATING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)]["qty"] += update
self.save()
def search(self, query):
# SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
return id, self.items[id]['name'], self.items[id]['qty']
return None
def __str__(self):
# FORMATTING
out = ""
for id, d in self.items.items():
out += f"\nID Number : {id} \nItem Name : {d['name']}\nQuantity : {d['qty']}\n"
out += "----------\n\r"
return out
def save(self):
# WHERE TO SAVE TO
with open('data.txt', 'w') as outfile:
json.dump(self.items, outfile)
def load(self):
# WHERE TO PUT DATA FROM WHEN RELAUNCHING PROGRAM
try:
with open('data.txt', 'r') as json_file:
self.items = json.load(json_file)
except:
print("Can't load old inventory, starting fresh")
self.items = {}
def menuDisplay():
# MENU FOR PROGRAM
"""Display the menu"""
print('=============================')
print('= Inventory Management Menu =')
print('=============================')
print('(1) Add New Item to Inventory')
print('(2) Remove Item from Inventory')
print('(3) Update Inventory')
print('(4) Search Item in Inventory')
print('(5) Print Inventory Report')
print('(99) Quit')
def add_one_item(inventory):
# ADDING PROMPT AND ERROR CHECKING
print('Adding Inventory')
print('================')
while True:
try:
new_ID = int(input("Enter an ID number for the item: "))
if inventory.search(new_ID):
print("ID number is taken, please enter a different ID number")
continue
new_name = input('Enter the name of the item: ')
new_qty = int(input("Enter the quantity of the item: "))
inventory.add(new_ID, new_name, new_qty)
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def remove_one_item(inventory):
# REMOVING PROMPT AND ERROR CHECKING
print('Removing Inventory')
print('==================')
while True:
try:
removing = int(input("Enter the item's ID number to remove from inventory: "))
if inventory.search(removing):
inventory.remove(removing)
else:
print("Item not in inventory")
continue
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def ask_exit_or_continue():
# OPTION TO CONTINUE OR QUITE PROGRAM
return int(input('Enter 98 to continue or 99 to exit: '))
def update_inventory(inventory):
# UPDATING PROMPT AND ERROR CHECKING
print('Updating Inventory')
print('==================')
while True:
try:
ID = int(input("Enter the item's ID number to update: "))
if inventory.search(ID):
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
inventory.update(ID, update)
else:
print("ID number is not in the system, please enter a different ID number")
continue
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def search_inventory(inventory):
# def select(obj: object):
# return o
# SEARCHING PROMPT AND ERROR CHECKING
print('Searching Inventory')
print('===================')
while True:
try:
search = input("Enter the name of the item: ")
result = inventory.search(search)
if result is None:
print("Item not in inventory")
continue
else:
ID, name, qty = result
print('ID Number: ', ID)
print('Item: ', name)
print('Quantity: ', qty)
print('----------')
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def print_inventory(inventory: object):
# PRINT CURRENT LIST OF ITEMS IN INVENTORY
print('Current Inventory')
print('=================')
string = inventory.__str__()
lis = string.split("\n\r")
lis.sort()
print("".join(lis))
def main():
# PROGRAM RUNNING COMMAND AND ERROR CHECKING
inventory = Inventory()
while True:
try:
menuDisplay()
CHOICE = int(input("Enter choice: "))
if CHOICE in [1, 2, 3, 4, 5]:
if CHOICE == 1:
add_one_item(inventory)
elif CHOICE == 2:
remove_one_item(inventory)
elif CHOICE == 3:
update_inventory(inventory)
elif CHOICE == 4:
search_inventory(inventory)
elif CHOICE == 5:
print_inventory(inventory)
exit_choice = ask_exit_or_continue()
if exit_choice == 99:
exit()
elif CHOICE == 99:
exit()
except Exception as e:
print("Invalid choice! try again!" + str(e))
print()
# If the user pick an invalid choice,
# the program will come to here and
# then loop back.
main()
You have left a comment with a question that I believe will answer also your main question.
I don't know if sort should go on the add item function or on the dictionary, or before printing the data
Answer:
You should create a sorting function and use it on your dictionary right before printing.
What not to do:
Don't sort your array on every added element. It's not efficient and in bigger projects it would cause time loss.
Disclaimer:
Sometimes you have to code a program in a way it sorts array on every added element - if you have to do it, then it's fine - but don't do it when it's not needed as sorting is a resource consuming operation
I have a program that has a search option that if chicken or Chicken is in inventory it will pull up the item by just typing chi (not case-sensitive). The issue is how do I make the function return all items that contain chi?
For example if I have Chickens, chicken, chickens, and Chicken in inventory I should be able to type in chi and it should print out all the information about each item.
Affected Code (not full program):
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
return id, self.items[id]['name'], self.items[id]['qty']
return None
How do I fix this?
Full program code for testing:
import os
import json
class Inventory:
def __init__(self):
#AT LAUNCH GROUPS AND LOADING FUNCTION
self.items = {}
self.load()
def remove(self, ID):
#REMOVING ITEMS FOR LISTS AND OUTPUT DOCUMENT
del self.items[str(ID)]
self.save()
def add(self, ID, name, qty):
#ADDING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)] = {"name": name, "qty": qty}
self.save()
def update(self, ID, update):
#UPDATING ITEMS FOR LISTS AND OUTPUT DOCUMENT
self.items[str(ID)]["qty"] += update
self.save()
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
output = []
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
output.append((id, self.items[id]['name'], self.items[id]['qty']))
if output: return output
else: return None
def __str__(self):
#FORMATTING
out = ""
for id, d in self.items.items():
out += f"ID Number : {id} \nItem Name : {d['name']}\nQuantity : {d['qty']}\n"
out += "----------\n"
return out
def save(self):
#WHERE TO SAVE TO
with open('data.txt','w') as outfile:
json.dump(self.items, outfile)
def load(self):
#WHERE TO PUT DATA FROM WHEN RELAUNCHING PROGRAM
try:
with open('data.txt','r') as json_file:
self.items = json.load(json_file)
except:
print("Can't load old inventory, starting fresh")
self.items = {}
def menuDisplay():
#MENU FOR PROGRAM
"""Display the menu"""
print('=============================')
print('= Inventory Management Menu =')
print('=============================')
print('(1) Add New Item to Inventory')
print('(2) Remove Item from Inventory')
print('(3) Update Inventory')
print('(4) Search Item in Inventory')
print('(5) Print Inventory Report')
print('(99) Quit')
def add_one_item(inventory):
#ADDING PROMPT AND ERROR CHECKING
print('Adding Inventory')
print('================')
while True:
try:
new_ID = int(input("Enter an ID number for the item: "))
if inventory.search(new_ID):
print("ID number is taken, please enter a different ID number")
continue
new_name = input('Enter the name of the item: ')
new_qty = int(input("Enter the quantity of the item: "))
inventory.add(new_ID, new_name, new_qty)
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def remove_one_item(inventory):
#REMOVING PROMPT AND ERROR CHECKING
print('Removing Inventory')
print('==================')
while True:
try:
removing = int(input("Enter the item's ID number to remove from inventory: "))
if inventory.search(removing):
inventory.remove(removing)
else:
print("Item not in inventory")
continue
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def ask_exit_or_continue():
#OPTION TO CONTINUE OR QUITE PROGRAM
return int(input('Enter 98 to continue or 99 to exit: '))
def update_inventory(inventory):
#UPDATING PROMPT AND ERROR CHECKING
print('Updating Inventory')
print('==================')
while True:
try:
ID = int(input("Enter the item's ID number to update: "))
if inventory.search(ID):
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
inventory.update(ID, update)
else:
print("ID number is not in the system, please enter a different ID number")
continue
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def search_inventory(inventory):
#SEARCHING PROMPT AND ERROR CHECKING
print('Searching Inventory')
print('===================')
while True:
try:
search = input("Enter the name of the item: ")
result = inventory.search(search)
if result is None:
print("Item not in inventory")
continue
else:
for found in result:
ID, name, qty = found
print('ID Number: ', ID)
print('Item: ', name)
print('Quantity: ', qty)
print('----------')
break
except Exception as e:
print("Invalid choice! try again! " + str(e))
print()
def print_inventory(inventory):
#PRINT CURRENT LIST OF ITEMS IN INVENTORY
print('Current Inventory')
print('=================')
print(inventory)
def main():
#PROGRAM RUNNING COMMAND AND ERROR CHECKING
inventory = Inventory()
while True:
try:
menuDisplay()
CHOICE = int(input("Enter choice: "))
if CHOICE in [1, 2, 3, 4, 5]:
if CHOICE == 1:
add_one_item(inventory)
elif CHOICE == 2:
remove_one_item(inventory)
elif CHOICE == 3:
update_inventory(inventory)
elif CHOICE == 4:
search_inventory(inventory)
elif CHOICE == 5:
print_inventory(inventory)
exit_choice = ask_exit_or_continue()
if exit_choice == 99:
exit()
elif CHOICE == 99:
exit()
except Exception as e:
print("Invalid choice! try again!"+str(e))
print()
# If the user pick an invalid choice,
# the program will come to here and
# then loop back.
main()
def search(self, query):
#SEARCHING DATA BASED ON CLOSEST CHARACTER MATCH - NOT CASE SENSITIVE
output = []
for id in self.items:
if str(query) == id or self.items[id]['name'].lower().startswith(str(query).lower()):
output.append((id, self.items[id]['name'], self.items[id]['qty']))
if output:
return output
else:
return None
If you find this unexplainable, maybe I got the question wrong. You should try and explain better more.
The code returns the first match. This search returns all matches.
def search(self, query):
""" Search items for all matching id's in query.
"""
output = [id for id in self.items if str(query).upper() in id.upper()]
return output if output != [] else None
As a stand-alone demo I constructed a Class having a database of 3 items and a search method.
For the search method I use 'if str(query).upper() in id.upper()' in a list comprehension.
class Db:
def __init__(self):
self.items = {
'Picture1': {'name': 'name1', 'qty': 1},
'Picture2': {'name': 'name2', 'qty': 2},
'Picture3': {'name': 'name3', 'qty': 3}}
def search(self, query):
return [(id, self.items[id]['name'], self.items[id]['qty'])
for id in self.items if str(query).upper() in id.upper()]
db = Db()
db.search('pic')
db.search('ure2')
I've been struggling with my code for a class project and am in need of some help. I am not sure if I need to have a nested dictionary or list of dict or just use class in a list or dict. I've struggled to find the answers and could use some help with my code.
Should I just use list instead or am I thinking of this the right way, having the values stored in a dictionary or nested dict of some kind.
I'm especially at a loss for menu==3 #delete an item because as it is now I can only delete one attribute but what I need is to delete a whole property by property ID if possible
As you can probably tell I'm quite confused by now and would really appreciate any help from more experienced programmers.
inventory = {}
#class & constructor
class Property:
def __init__(self, propertyID, address, city, state, zipcode, squarefeet, modelname, salestatus):
self.propertyID = propertyID
self.address = address
self.city = city
self.state = state
self.zipcode = zipcode
self.modelname = modelname
self.squarefeet = squarefeet + 'Square Feet'
self.salestatus = salestatus
def print_Property(o):
if not isinstance(o, Property):
raise TypeError('print_Property(): requires a Property')
print('The property selected is Property ID: {} located at {} {} {} The Sqare footage is {}, {} model, Current status: {}'. format(o.propertyID,o.addresss, o.city, o.state, o.zipcode, o.squarefeet, o.modelname, o.salestatus))
def main():
print('What would you like to do today?')
print('----------------------------------------')
print('1. Add a new item to the Inventory')
print('2. Update an Existing item in the Inventory')
print('3. Delete an existing item from the Inventory')
print('4. View the current item inventory')
print('5. Print the Inventory to a text file')
print('------------------------------')
while True:
try:
menu = int(input('Type a number 1-5'))
if menu == 1: #Add data
print('Add a new property to the inventory...')
propertyID = input('Enter the property Listing ID:') #User inputting a property ID
inventory['Property ID']= propertyID
address = input('Enter the property address:') #User inputting an address
inventory['Address']= address
city = input('Enter property city:') #User inputting a city
inventory['City']= city
state = input('Enter property state:') #User inputting a state
inventory['State']= state
zipcode = int(input('Enter the property zipcode:')) #User inputting a zipcode
inventory['Zipcode']= zipcode
modelname = input('Enter property model name:') #User inputting a property model name
inventory['Model Name']= modelname
squarefeet = int(input('Enter the sqaure footage of the property:')) #User inputting the sqaure footage for the property
inventory['Square Footage']= squarefeet
salestatus = input('Enter the property status:(Is the home sold, available, or under contract?):') #User inputting the property status
inventory['Current Staus']= salestatus
print('The following properties are in the inventory now:')
print(inventory)
#break
elif menu == 2: #Update data
print('Update an item from the inventory...')
print (inventory)
itemreplace = input("Enter the name of the attribute you wish to replace:")
itemupdate = input("Enter the new information for that attribute now:")
inventory[itemreplace]= itemupdate
print(inventory)
elif menu == 3: #Delete data
print("Which property do you want to delete?")
print(inventory)
itemdel = input("Enter the Property ID of the property to delete.")
if itemdel in inventory:
del inventory[itemdel]
print(inventory)
elif menu == 4: #View data
print(inventory)
elif menu == 5: #Print data
output = open("PropertyData.txt", "w")
for item in inventory:
output.write("%s\n" % item)
print('Text file \'PropertyData.txt\' has been created.')
else:
print('That number is not valid. Please try 1-5.')
except ValueError: #throw an error for anything that is not a number
print('You may only select values 1-5. (ex.: 2)')
if __name__ == '__main__': main()
#Lucas is right. Here is a fully working ( I think :) ) system:
import json
class Property:
def __init__(self, propertyID, address, city, state, zipcode, squarefeet, modelname, salestatus):
self.propertyID = propertyID
self.address = address
self.city = city
self.state = state
self.zipcode = zipcode
self.modelname = modelname
self.squarefeet = squarefeet
self._sqfeet_description = str(squarefeet) + ' Square Feet'
self.salestatus = salestatus
def __str__(self):
o = self
return 'Property ID: {}. Address: {}, {}, {}, {}. Size: {} sq feet, {} model. Status: {}.'.format(o.propertyID,o.address, o.city, o.state, o.zipcode, o.squarefeet, o.modelname, o.salestatus)
def as_json(self):
return {x:y for x,y in self.__dict__.items() if not x.startswith("_")}
def int_input(prompt, range=None):
while True:
ans = input(prompt)
if not ans.isnumeric():
print("Please enter a valid number")
continue
ans = int(ans)
if range == None:
return ans
if ans not in range:
print(f"Please enter a number between {min(range)} and {max(range)}")
continue
return ans
inventory = []
def main():
print('What would you like to do today?')
print('----------------------------------------')
print('1. Add a new item to the Inventory')
print('2. Update an Existing item in the Inventory')
print('3. Delete an existing item from the Inventory')
print('4. View the current item inventory')
print('5. Print the Inventory to a text file')
print('------------------------------')
while True:
menu = int_input("Choose an option 1-5", range(1,6))
if menu == 1:
# add data
propertyID = input('Enter the property Listing ID:') #User inputting a property ID
address = input('Enter the property address:') #User inputting an address
city = input('Enter property city:') #User inputting a city
state = input('Enter property state:') #User inputting a state
zipcode = int_input('Enter the property zipcode:') #User inputting a zipcode
modelname = input('Enter property model name:') #User inputting a property model name
squarefeet = int_input('Enter the sqaure footage of the property:') #User inputting the sqaure footage for the property
salestatus = input('Enter the property status:(Is the home sold, available, or under contract?):') #User inputting the property status
this_property = Property(
propertyID,
address,
city,
state,
zipcode,
squarefeet,
modelname,
salestatus)
inventory.append(this_property)
print('The following properties are in the inventory now:')
print(*("\t" + str(i) for i in inventory), sep="\n")
print()
elif menu == 2:
# update data
while True:
propertyID = input("Enter the property id: ")
this_property = [x for x in inventory if x.propertyID == propertyID]
if not this_property:
print("That property doesn't exist")
continue
this_property = this_property[0]
break
lookup = {
"propertyID": str,
"address":str,
"city":str,
"state":str,
"zipcode":int,
"modelname":str,
"squarefeet":int,
"salestatus":str
}
while True:
detail_name = input("Enter the detail you wish to change")
if detail_name not in lookup:
print("That detail does not exist")
continue
break
if lookup[detail_name] == int:
new = int_input("Enter the new value:")
else:
new = input("Enter the new value:")
setattr(this_property, detail_name, new)
elif menu == 3:
# delete
while True:
propertyID = input("Enter the property id: ")
this_property = [i for i, x in enumerate(inventory) if x.propertyID == propertyID]
if not this_property:
print("That property doesn't exist")
continue
this_property = this_property[0]
break
del inventory[this_property]
elif menu == 4:
# print inventory
print('The following properties are in the inventory now:')
print(*("\t" + str(i) for i in inventory), sep="\n")
print()
elif menu == 5:
# save
new_inv = [x.as_json() for x in inventory]
with open("output.txt", "w") as f:
json.dump(new_inv, f)
if __name__ == '__main__':
main()
If you want to save your properties and be able to load them again, add this method to Property:
class Property:
...
#classmethod
def from_json(cls, json_code):
c = cls(*(None for _ in range(8)))
for x,y in json_code.items():
setattr(c, x, y)
return c
and this function to the body of your program:
def load_from_file():
with open("output.txt") as f:
for item in json.load(f):
inventory.append(Property.from_json(item))
and then call the function at the start:
if __name__ == '__main__':
load_from_file()
main()
(obviously make sure the file exists before that though - just save [] to output.txt before running the program for the first time)
The easiest solution is to use a list of Property objects, where each element in a list is an individual property. Adding properties to the inventory means creating a new object, filling in all the fields and appending it to the inventory list.
sorry if this is not presented well. This is my first time ever using StackOverflow. I'm trying to create this to keep track of inventory. I do not know how to utilize try-excepts. Additionally, I don't know what else is going wrong. Thanks for any and all help !
data handler:
import os
class DataHandler():
def __init__(self, filename, datadict = {}):
self.filename = filename
self.datadict = datadict
def readData(self): # returns dictionary
try:
fileobj = open(self.filename,'r')
datastr = fileobj.read()
fileobj.close()
# return dictionary read from file or null dictionary
if datastr != '':
return eval(datastr)
else:
return self.datadict
except FileNotFoundError:
return self.datadict # null dictionary
def writeData(self, datadict): # must pass dictionary
fileobj = open(self.filename,'w')
fileobj.write(str(datadict))
fileobj.close()
separate file:
import DataHandler as DH
def menuDisplay():
print("="*40)
print("1 - Add inventory item")
print("2 - Modify inventory item")
print("3 - Delete inventory item")
print("4 - Print inventory list")
print("5 - Exit program")
print("="*40)
selection = input("\nPlease enter menu choice: ")
if selection < "1" and selection > "5":
input("Invalid selection, please enter 1 - 5")
menuDisplay()
else:
return int(selection)
def addItem(invDict,dh):
itemdesc = input("Item Description: ")
itemqty = int(input("Qty: "))
if len(invDict) > 0:
nextKey = sorted(invDict.keys())[-1]+1
else:
nextKey = 1
invDict[nextKey]=[itemdesc,itemqty]
dh.writeData(invDict)
def printInv(invDict):
print("{:<10}{:20}{:6}".format("Item #", "Description", "Qty",))
for dkey, lvalue in invDict.items():
print("{:<10}{:20}{:6d}".format(str(dkey), lvalue[0],lvalue[1], lvalue[2]))
def delItem(invDict,dh):
itemnum = input("Please enter item to delete: ")
del invDict[int(itemnum)]
dh.writeData(invDict)
# complete error checking
def modItem(invDict,dh):
itemnum = input("Please enter item to modify: ")
newqty = input("Please enter the new quantity: ")
invDict[int(itemnum)][1] = int(newqty)
dh = DH.DataHandler("inventory.txt")
invDict = dh.readData()
selection = 0
while selection != 5:
selection = menuDisplay()
if selection == 1:
addItem(invDict,dh)
elif selection == 2:
modItem(invDict,dh)
elif selection == 3:
delItem(invDict,dh)
elif selection == 4:
printInv(invDict)
This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 3 years ago.
I'm running this code and when i add an item to the inventory,the item appears in all the Inventory Classes, Where am I going wrong here?
Once i run Browse(),add new inventory,add items to it,
and when i make a new inventory, items from the first inventory appear in the new one by default.
how can i fix this problem boys and girls?
inventories = {}
class Inventory: ##Class for new inventory
inventory = {}
items = {}
def __init__(self,name):
self.name = name
def add_item(self,item,price,amount):
if item in self.items:
return False
else:
self.items[item] = int(price)
self.inventory[item] = int(amount)
return True
def add_amount(self,item,amount):
self.inventory[item] += amount
def update_amount(self,item,amount):
self.inventory[item] = amount
def remove_amount(self,item,amount):
self.inventory[item] -= amount
def update_item_price(self,item,price):
self.items[item] = price
def inv_list(self): ##Print the class
print(self.name)
print("\nItem: Price: Amount:\n")
for item in self.inventory:
print(f"{item}\t\t{self.items[item]}\t\t{self.inventory[item]}")
def new_inventory(): ##MAkes a new inventory class and stores in inventories{}
global inventories
while True:
answer = input("What would you like to call your new Inventory?")
if answer in inventories:
print("Name already taken")
continue
inventories[answer] = Inventory(answer)
print("Inventory created")
update(answer)
break
def update(inv): ##Updates an excisting Inventory
global inventories
while True:
inventories[inv].inv_list()
answer = int(input("1.Add item to inventory\n2.Update items price\n3.Update items amount\n4.Exit"))
if answer == 1:
while True:
name = input("Name of item")
price = int(input("Price"))
amount = int(input("Amount"))
answer = inventories[inv].add_item(name,price,amount)
if answer == False:
print("Item already in inventory")
continue
break
if answer == 2:
while True:
print(inventories[inv].inv_list())
name = input("item")
price = int(input("Price"))
if name in inventories[inv].items:
inventories[inv].update_item_price(name,price)
break
print("No such item")
continue
if answer == 3:
while True:
print(inventories[inv].inv_list())
name = input("item")
amount = int(input("Amount"))
if name in inventories[inv].items:
inventories[inv].update_amount(name,amount)
break
print("No such item")
continue
if answer == 4:
break
def browse(): ##Runs the prigram Function
global inventories
while True:
print("Welcome to your inventory collection\nWhat action would you like to take?")
print("1.Add a new inventory list\n2.Update excisting inventory\n3.Exit")
answer = int(input())
if answer == 1:
new_inventory()
if answer == 2:
for x in inventories:
print(x)
while True:
answer = input("Which inv?")
if answer in inventories:
update(answer)
break
if answer == "exit":
break
continue
if answer == 3:
print("Goodbye")
break
else:
continue
browse()
inventory = {}
items = {}
is creating shared attributes for all class instances. You should initialize the attributes in the __init__ method.
class inventory:
def __init__(self, name):
self.name = name
self.inventory = {}
self.items = {}