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
Related
I had a basic phone book application that adds, lookup, updates, and deletes a record and it works fine. I wanted to add functionality to it in which when I close and restart the program the previously added records are still there saved in a file. And when I want to add more records to the dictionary file it will also be appended to the file but I am running into 2 issues the first one is when I try to integrate my saved file with my dictionary I get error dictionary update sequence element #0 has length 1; 2 is required so I for some reason can't read the file to check if I have a record in the file with the same name for example. The second issue is when I Quit the program I added a save Record function which when run adds the newly added records onto the file to save it before it quits but when I print it, it only shows the first string printed the other is not shown I don't know what is causing this. Any help is appreciated thanks in advance.
#!/usr/bin/python3
import os.path
from os import path
phones = {}
if path.exists('phones.txt'):
with open("phones.txt") as f:
phones = dict(x.rstrip().split(None, 1) for x in f)
else:
phoneFile = open("phones.txt", "w")
print("File Created")
phoneFile.close()
with open("phones.txt") as f:
phones = dict(x.rstrip().split(None, 1) for x in f)
def menu():
print("1. Add a record")
print("2. Lookup a record")
print("3. Update a record")
print("4. Remove a record")
print("5. List all records")
print("6. Quit")
selection = input("Please make your selection from the options above: ")
if(selection == '1'):
addRecord()
menu()
elif(selection == '2'):
lookupRecord()
menu()
elif(selection == '3'):
updateRecord()
menu()
elif(selection == '4'):
removeRecord()
menu()
elif(selection == '5'):
listRecords()
menu()
elif(selection == '6'):
saveRecords()
print("Goodbye")
#exit(0)
else:
print("Sorry, invalid input, try again.")
menu()
def addRecord():
a = str(input("Person's name to add to record: "))
b = int(input("Number to add to record: "))
if a in phones:
print("Name already in records, Please choose another name")
else:
phones[a] = b
print(phones)
def lookupRecord():
a = str(input("Person's name to look: "))
if a in phones:
print(a + "'s number is " + str(phones.get(a)))
else:
print("Person not found")
def updateRecord():
a = str(input("Person's name to update: "))
if a in phones:
b = int(input("New phone number to update: "))
phones[a] = b
print(phones)
else:
print(a + " is not in your phone book")
def removeRecord():
a = str(input("Person's name to remove: "))
if a in phones:
del phones[a]
print(a + " removed from phone book")
else:
print("Name not found")
def listRecords():
for i in phones.items():
print(i)
def saveRecords():
for i in phones.items():
writePhoneFile = open("phones.txt", "w")
finalRecord = ':'.join('%s' %id for id in i)
writePhoneFile.write(finalRecord)
readPhoneFile = open("phones.txt", "r+")
print(readPhoneFile.read())
def main():
print("== Welcome to the Phonebook App ==")
menu()
if __name__ == "__main__":
main()
use below because phone number in integer :
phones = dict( (x.rstrip().split(':')[0] , int(x.rstrip().split(':')[1])) for x in f)
in addition, open the file outside for loop in saverecords:
writePhoneFile = open("phones.txt", "w")
for i in phones.items():
print(i)
finalRecord = ':'.join('%s' %id for id in i)+'\n'
writePhoneFile.write(finalRecord)
writePhoneFile.close()
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):
I have a program that totally works except I have to have it report how many item are left in inventory after the user "checkout" (option 2). I have created a function called inhand. In this function I assigned each item in inventory with the qty of 100. The following line is suppose to take the item the user selected and subtract the qty they entered. After the user chooses option 2 "checkout". It prints a "bill". I want it to print how many of each item is left in inventory. Instead it currently errors. How do I fix this?
Full Code:
#DEFINING EACH RETAIL ITEM TEMPLATE
class RetailItem:
def __init__(self,desc,unit,price):
self.description = desc
self.units = unit
self.price = price
#CREATING WHERE SELECTED ITEMS WITH RESIDE
class CashRegister:
def __init__(self):
self.shopping_list=[]
def purchase_item(self,retail):
#adding item to list
self.shopping_list.append(retail)
#CREATING PRICING / COST
def get_total(self):
total = 0
for i in self.shopping_list:
total+=(i.units*i.price)
return total
#HOW THE CHECKOUT WILL FORMAT/LOOK IN AFFECT ON OPTION 2 (CHECKOUT)
def show_items(self):
if not self.shopping_list:
return
print("{:<15}{:<25}{:<25}{:<10}".format(" "*9,"Description","Units","Price"))
print("-"*75)
for c,i in enumerate(self.shopping_list,1):
print("{:<15}{:<25}{:<25}{:<10}".format("Item #"+str(c),i.description,i.units,i.price))
print("-"*75)
def inhand():
inventory = { "Pants":100, "Shirt":100, "Dress":100, "Socks":100, "Sweater":100 }
inventory[item_type] -= qty_purchased
def main():
#ADDING TO CART
c=CashRegister()
#MENU
while 1:
try:
print("1. Purchase\n2. Checkout\n3. Clear\n4. Exit")
print()
choice = int(input("Enter your choice: "))
print()
if choice == 1:
while 1:
print()
print("Menu\n-----------------------\n1. Pants\n2. Shirt\n3. Dress\n4. Socks\n5. Sweater")
item_type = int(input("Select item: "))
print()
qty=int(input("Enter quantity: "))
#ITEMS TO CHOOSE FROM AND ADD TO CART
if item_type == 1:
c.purchase_item(RetailItem("Pants",qty,44.95))
elif item_type == 2:
c.purchase_item(RetailItem("Shirt",qty,34.95))
elif item_type == 3:
c.purchase_item(RetailItem("Dress",qty,79.95))
elif item_type == 4:
c.purchase_item(RetailItem("Socks",qty,6.95))
elif item_type == 5:
c.purchase_item(RetailItem("Sweater",qty,24.95))
else:
#ERROR MESSAGE
print("Invalid item! try again")
print()
continue
print("Item added to list")
print()
break
elif choice == 2:
if not c.shopping_list:
#ERROR MESSAGE
print("Nothing to checkout!")
print()
continue
#DISPLAYING BILL
c.show_items()
print(" "*60+"Total: ${}".format(round(c.get_total(),2)))
print()
print(inhand)
elif choice == 3:
#CLEARING
c.shopping_list=[]
elif choice == 4:
#EXIT
exit()
else:
#ERROR MESSAGE
print("Invalid choice! try again!")
print()
#ERROR MESSAGE
except Exception as e:
print("Invalid choice! try again!"+str(e))
print()
#RUN PROGRAM
if __name__ == "__main__":
main()
you must declare that inhand function scope variable first as well making the function accessible throughout the class, then assign inventory to your class variable otherwise it wont get stored globally in your class (only inside of your function) for example:
def inhand(self,item_type,qty_purchased):
self.inventory = { "Pants":100, "Shirt":100, "Dress":100, "Socks":100, "Sweater":100 }
self.inventory[item_type] -= qty_purchased
so then you can use it repetitively using for loop
self.item_type_qty[["Pants",20],["Dress",20]] #for example, this variable store user picked item
for x in self.item_type_qty:
self.inhand(x[0],x[1]) #calling inhand function repetitively
you will also need to validate if in case those inventory get valued below zero. which at this point you can figure it out on your own. good luck
Initialize the inventory in the constructor. Let the inhand function check the inventory and return True\False if the purchase can be made.
Try this code:
#CREATING WHERE SELECTED ITEMS WITH RESIDE
class CashRegister:
def __init__(self):
self.shopping_list=[]
self.inventory = { "Pants":100, "Shirt":100, "Dress":100, "Socks":100, "Sweater":100 }
def purchase_item(self,retail):
#adding item to list
if self.inhand(retail.description, retail.units):
self.shopping_list.append(retail)
#CREATING PRICING / COST
def get_total(self):
total = 0
for i in self.shopping_list:
total+=(i.units*i.price)
return total
#HOW THE CHECKOUT WILL FORMAT/LOOK IN AFFECT ON OPTION 2 (CHECKOUT)
def show_items(self):
if not self.shopping_list:
return
print("{:<15}{:<25}{:<25}{:<10}".format(" "*9,"Description","Units","Price"))
print("-"*75)
for c,i in enumerate(self.shopping_list,1):
print("{:<15}{:<25}{:<25}{:<10}".format("Item #"+str(c),i.description,i.units,i.price))
print("-"*75)
def inhand(self,item_type,qty_purchased):
if self.inventory[item_type] < qty_purchased:
print(f"Cannot purchase {qty_purchased} {item_type}. Only {self.inventory[item_type]} left in stock.")
return False
self.inventory[item_type] -= qty_purchased
return True
You can print the inventory after printing the cart:
#DISPLAYING BILL
c.show_items()
print(" "*60+"Total: ${}".format(round(c.get_total(),2)))
print()
print(">> Inventory:", c.inventory)
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')
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)