I have taken what was once a class project and turned it into something more usable for work. My program is designed as an inventory system. I have currently ensured that my program can export data to a text file, and import that data at request if the program is ever closed. I cannot edit the data after import unless I add new data to the list first, or add new data to the list then import.
I think the reason why it isn't working is because the data imported from the list doesn't have a logical position yet until new data is added.
class Inventory:
def __init__(self):
self.item = ""
self.amount = 0
self.asset_tag = 0
self.notes = ""
def add_inventory(self):
self.item = input("Enter item: ")
self.amount = int(input("How many? "))
self.asset_tag = int(input("Enter Asset Tag if available. Enter 0 if not tagged. "))
self.notes = input("Please add any additional information: ")
def __str__(self):
return('Item: %s Amount: %d Asset Tag: %d Notes: %s' %
(self.item, self.amount, self.asset_tag, self.notes))
inventory_list = []
def edit(inventory_list):
pos = int(input('Enter the position of the item you would like to edit: '))
new_inventory = item.add_inventory()
new_inventory = item.__str__()
inventory_list[pos-1] = new_inventory
print('Inventory has been updated. If the amount is now 0 please notify.')
while True:
print("""
1. Add new inventory.
2. Remove item from inventory.
3. View inventory.
4. Update current inventory.
5. Export inventory to file.
6. Import Inventory file
7. Quit
""")
ans = input('What would you like to do? ')
if ans == "1":
item = Inventory()
item.add_inventory()
inventory_list.append(item.__str__())
elif ans == "2":
for i in inventory_list:
inventory_list.pop(int(input('Enter position of item to remove: ')))
print('Inventory item removed successfully!')
elif ans == "3":
print('\n'.join(map(str, inventory_list)))
elif ans == "4":
edit(inventory_list)
elif ans == "5":
f = open('Inventory_List.txt', 'w')
for ele in inventory_list:
f.write(ele+'\n')
f.close()
elif ans == "6":
with open('Inventory_List.txt') as f:
data = f.read().splitlines()
print(data)
inventory_list.extend(data)
elif ans == "7":
break
else:
print('Invalid entry, try again.')```
item is not defined in the function edit before it gets utilized.
Related
I need to be able to add, delete, edit, and recall transactions in a list.
I opened a while loop, set the constants and defined an empty list. I then proceeded to create the menuing through if statements. Everything seems to work except I am unable to add to the list and then recall all added values.
This is what I have so far:
while True:
addTransaction = "1"
deleteTransaction = "2"
editTransaction = "3"
displayTransactions = "4"
exit = "5"
transactions = []
menu = input("**********Main Menu***********\n1. Add Transaction\n2. Delete Transaction\n3. Edit Transaction\n4. Display Transactions\n5. Exit the Program\n\nChoose a menu option from 1-4 or 5 to exit the program: ")
if menu != "5":
if menu == "1":
newTransaction = (input("Enter new transaction: "))
transactions.append(newTransaction)
print("Added")
elif menu == "2":
target = input("Edit transaction: ")
if target in transactions:
transactions.pop(transactions.index(target))
print("Removed")
else:
print("Transaction not found.")
elif menu == "3":
transactions[input("Enter the transaction key to edit: ")] = input("Enter the new transaction key: ")
elif menu == "4":
print("******************\n** Transactions **\n" + str(transactions) + "\n******************")
else:
print("Invalid input.")
else:
break
I am brand new to Python, trying to figure out how to use all of these functions
You just need to make sure transactions is not in the while loop. Because it was being reset to [] every iteration.
addTransaction = "1"
deleteTransaction = "2"
editTransaction = "3"
displayTransactions = "4"
exit = "5"
transactions = []
while True:
menu = input("**********Main Menu***********\n1. Add Transaction\n2. Delete Transaction\n3. Edit Transaction\n4. Display Transactions\n5. Exit the Program\n\nChoose a menu option from 1-4 or 5 to exit the program: ")
if menu != "5":
if menu == "1":
newTransaction = input("Enter new transaction: ")
transactions.append(newTransaction)
print("Added")
elif menu == "2":
target = input("Remove transaction: ")
if target in transactions:
# Use remove to remeve the first occurance of a value
transactions.remove(target)
print("Removed")
else:
print("Transaction not found.")
elif menu == "3":
transactions[input("Enter the transaction key to edit: ")] = input(
"Enter the new transaction key: ")
elif menu == "4":
# Use join to join elements in a list
print("******************\n** Transactions **\n" +
", ".join(transactions) + "\n******************")
else:
print("Invalid input.")
else:
break
You may also want to experiment with match. Which is a Python switch case basically
menu = "1"
match menu:
case "1":
# Code here for when menu = 1
case "2":
# Code here for when menu = 2
case _:
# Code here for when menu != 1 or 2
print("Error")
New to programming and trying to learn how to store data using pickle. Essentially, what I'm trying to do is create an address book using classes stored in a dictionary. I define the class (Contact). It all worked, but when I tried to introduce pickling to store data from a previous session, I've created 2 errors that I've found so far.
1: If I select to load a previous address book, I cant update or view the class variables. It's almost like there are two different dictionaries.
2: I select not to load a previous address book and add a contact. When I add the contact and try to view the contacts, I'll get an "Unbound Error: local variable 'address book' referenced before assignment"
What am I doing wrong with pickling?
address_book= {}
class Contact:
def __init__(self,first_name,last_name, phone,company):
self.first_name = first_name
self.last_name = last_name
self.phone = phone
self.company = company
def __call__(self):
print("Contact: %s \nPhone #: %s \nCompany: %s" %(self.name,self.phone,self.company))
def erase(entry):
del address_book[entry] # delete address book entry
del entry #delete class instance
def save():
new_file = open("addressBook.pkl", "wb")
saved_address = pickle.dump(address_book, new_file)
new_file.close()
def load():
open_file = open("addressBook.pkl", "rb")
address_book = pickle.load(open_file)
open_file.close()
print(address_book)
return address_book
def add_contact():
first_name = input("Please type the first name of the contact. ")
last_name = input("Please type in the last name of the contact. ")
if " " in first_name or " " in last_name:
print("Please do not add spaces to your first or last name.")
else:
phone = input("Please type the user phone number without hyphens. ")
if not phone.isnumeric():
print("That isn't a valid phone number.")
else:
company = input("Please type the company they work for. ")
contact = Contact(first_name,last_name,phone,company)
address_book[first_name + " " +last_name] = contact #assign key[first and last name] to value[the class instance] in dictionary
def view_contact(entry):
if entry in address_book:
print("First Name: %s" %(address_book[entry].first_name)) #get class variables
print("Last Name: %s" %(address_book[entry].last_name))
print("Phone Number: %s" %(address_book[entry].phone))
print("Company: %s" %(address_book[entry].company))
else:
print("That person isn't in your address book")
def update(entry):
if entry in address_book:
update_choice = input("Would you like to update the first name (f), last name (l), phone (p), or company (c)? ").lower()
if update_choice == "f":
address_book[entry].first_name = input("Please type the updated first name of this contact. ")
updated_key = address_book[entry].first_name + " " + address_book[entry].last_name
address_book[updated_key] = address_book[entry]
del address_book[entry] #delete old key
elif update_choice == "l": #update last name
address_book[entry].last_name = input("Please type the updated last name of this contact. ")
updated_key = address_book[entry].first_name + " " + address_book[entry].last_name
address_book[updated_key] = address_book[entry]
del address_book[entry]
elif update_choice == "p":
address_book[entry].phone = input("Please type the updated phone number of this contact. ")
elif update_choice == "c":
address_book[entry].company = input("Please type the updated company of this contact. ")
else:
print("That was not valid. Please try again.")
def main():
print("Welcome to your address book!!")
returning_user = input("Would you like to load a previous address book? Y or N ").lower()
if returning_user == "y":
address_book = load()
while True:
choice = input("Please type A:Add, B:View All Contacts, V:View a Contact, D:Delete, U:Update, or X:Exit ").lower()
if choice == "x":
break
elif choice == "a":
add_contact()
elif choice == "b":
if len(address_book) == 0: #error check if no contacts
print("You don't have any friends. PLease go make some and try again later. :(")
else:
for i in address_book:
print(i)
elif choice == "v":
if len(address_book) == 0:
print("You don't have any friends. PLease go make some and try again later. :(")
else:
view = input("Who do you want to view? Please type in their first and last name. ")
view_contact(view)
elif choice == "d":
if len(address_book) == 0:
print("You don't have any friends. PLease go make some and try again later. :(")
else:
contact = input("Please type the first and last name of the person you want to delete ")
if contact in address_book:
erase(contact)
elif choice == "u":
if len(address_book) == 0:
print ("C'mon, you don't know anyone yet. How about you make some friends first?")
else:
choice = input("What is the first and last name of the person you'd like to update? ")
update(choice)
else:
print("That was not valid. Please try again.")
print()
save_book = input("Would you like to save your book? Y or N ").lower()
if save_book == "y":
save()
print("Thanks for using the address book!")
main()
In this program I am trying to make an inventory program. Under option (3) titled "Update Inventory" you type in an item for the list name, then you are prompted to either add to the existing quantity in the list qty or subtract from it.
For example if I have five items in name and the corresponding quantity in qty. How do I find item 3, and update the quantity by adding to or subtracting from the current amount.
Full program code (only looking for help on how to write option 3):
name = []
qty = []
class Foo():
def __init__(self, name, qty):
self.name = name
self.qty = qty
def menuDisplay():
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')
CHOICE = int(input("Enter choice: "))
menuSelection(CHOICE)
def menuSelection(CHOICE):
if CHOICE == 1:
print('Adding Inventory')
print('================')
new_name = input('Enter the name of the item: ')
name.append(new_name)
new_qty = int(input("Enter the quantity of the item: "))
qty.append(new_qty)
CHOICE = int(input('Enter 98 to continue or 99 to exit: '))
if CHOICE == 98:
menuDisplay()
elif CHOICE == 99:
exit()
elif CHOICE == 2:
print('Removing Inventory')
print('==================')
removing = input('Enter the item name to remove from inventory: ')
indexdel = name.index(removing)
name.pop(indexdel)
qty.pop(indexdel)
CHOICE = int(input('Enter 98 to continue or 99 to exit: '))
if CHOICE == 98:
menuDisplay()
elif CHOICE == 99:
exit()
elif CHOICE == 3:
print('Updating Inventory')
print('==================')
item = input('Enter the item to update: ')
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
if update >= 0:
print()
elif update <= -1:
print()
CHOICE = int(input('Enter 98 to continue or 99 to exit: '))
if CHOICE == 98:
menuDisplay()
elif CHOICE == 99:
exit()
I have shortened the code as I believe this is the minimum code as possible to duplicate my issue.
I would not suggest using multiple lists to store related items. A dictionary is probably your best bet, especially when working with an inventory system - in an inventory, every item has a unique attribute. Dictionaries store key/value pairs, which is perfect for something like this. Using two lists can be detrimental; one small bug could derail the entire system. Something like this will illustrate the simplicity of using a dictionary over multiple lists:
inventory = {'apples':0, 'bananas':0, 'oranges':0}
item = input("Enter the item to update: ")
qty = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
inventory[item] += qty
However, if you are set on using two lists, this will serve your purpose:
name = ['apples', 'bananas', 'oranges']
qty = [0,0,0]
item = input("Enter the item to update: ")
update = int(input("Enter the updated quantity. Enter 5 for additional or -5 for less: "))
qty[name.index(item)] += update
Assuming your lists are associated 100% with each other, the above will use the index position of the item and update that quantity in the other list.
I want to user to input information and print out the total list. However, when the user input another list it only prints out the first list. How can I make the program print the users total input. Here's my code.
listing = []
class Car:
def __init__(self, ownerName=None, model=None, make=None, price=None):
self.ownerName = ownerName
self.model = model
self.make = make
self.price = price
def input(self):
print "Please update car info \n"
while True:
i = 0
listing.append(Car(raw_input("Owner Name"), raw_input("Model?"), raw_input("Make?"), raw_input("Price?")))
print "Updated"
print listing[i].ownerName, listing[i].model, listing[i].make, listing[i].price
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() == "y":
i += 1
continue
else:
break
# search a car and print its information. Exit when user input is 'exit'
def menu():
x = Car()
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) search a car and print info\n" \
"\"exit\" Exit")
if choice == "1":
x.input()
elif choice == "2":
print "Price"
elif choice == "3":
print "Search and Print info"
menu()
#mhawke's answer should fix your problem. However, I do not like the idea of creating objects of a class from one of its functions. Check the edited code below.
listing = []
class Car:
def __init__(self, ownerName=None, model=None, make=None, price=None):
self.ownerName = ownerName
self.model = model
self.make = make
self.price = price
def input_car():
print "Please update car info \n"
i = 0
while True:
listing.append(Car(raw_input("Owner Name"), raw_input("Model?"), raw_input("Make?"), raw_input("Price?")))
print "Updated"
print listing[i].ownerName, listing[i].model, listing[i].make, listing[i].price
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() == "y":
i += 1
continue
else:
break
# search a car and print its information. Exit when user input is 'exit'
def menu():
#x = Car()
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) search a car and print info\n" \
"\"exit\" Exit")
if choice == "1":
input_car()
elif choice == "2":
print "Price"
elif choice == "3":
print "Search and Print info"
menu()
I cleaned up the code a little bit. I should work now. Option 3 gives you a complete listing of all cars so far, so youhave an example to build on.
listing = []
class Car:
def __init__(self, ownerName=None, model=None, make=None, price=None):
self.ownerName = ownerName
self.model = model
self.make = make
self.price = price
#to have a useful method for our example I overwrite the __str__ method from object
def __str__(self):
return ",".join([self.ownerName, self.model, self.make, self.price])
#input does not handle aspects of car, therefore it should be not a method of car
def input():
print "Please update car info \n"
while True:
# there is no need for 'i' so I removed it
car = Car(raw_input("Owner Name"),
raw_input("Model?"),
raw_input("Make?"),
raw_input("Price?"))
listing.append(car)
print "Updated"
print car #possible since __str__ is overwritten
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() == "n":
break
def menu():
keep_running = True
#added a while loop so the user stays in the program until he types 'exit'
#changed option '3' to have a working example to build on
while keep_running:
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) list all cars\n" \
"\"exit\" Exit")
if choice == "1":
input()
elif choice == "2":
print "Price"
elif choice == "3":
print "\n".join(map(str, listing))
elif choice == "exit":
keep_running = False
menu()
That's because you reset i on each iteration of your while loop.
Move the line:
i = 0
to the line before the while True:
That should fix the immediate problem, however, your code uses an unusual design. You should not create a Car object in order to create further instances of Cars which are then inserted into a global list.
At a minimum you could make input() a static method and have it return a list of Car instances to the caller. Then you can do away with the global listing variable. Also, you don't actually need to keep a counter in i you can just use -1 as the subscript to access the last item in the list:
#staticmethod
def input(listing=None):
if listing is None:
listing = []
print "Please update car info \n"
while True:
listing.append(Car(raw_input("Owner Name"), raw_input("Model?"), raw_input("Make?"), raw_input("Price?")))
print "Updated"
print('{0.ownerName} {0.model} {0.make} {0.price}'.format(listing[-1]))
addOn = raw_input("Continue? (Y/N)")
if addOn.lower() != "y":
break
return listing
Using a static method is good here because input() is related to Car objects so it makes sense to package that function with the class.
Now you can call input() without creating an instance of a Car. In your menu() function remove the x = Car() and change x.input() to listing = Car.input(). Or, if you want to append to an existing "listing" list, call Car.input(listing) which will append new input to listing. You can then print the returned list to see all user input:
def menu():
print "PLease choose an option (1-4):\n"
choice = raw_input("1) input\n" \
"2) change price and owner\n" \
"3) search a car and print info\n" \
"\"exit\" Exit")
if choice == "1":
listing = Car.input()
# print out all user entered cars
for car in listing:
print('{0.ownerName} {0.model} {0.make} {0.price}'.format(car))
elif choice == "2":
print "Price"
elif choice == "3":
print "Search and Print info"
I currently have this code which works fine, but I need to be able to delete data on command from the data file.
This is what the inside of the file looks like:
[[15, "TomBy012"], [10, "Badrob135"]]
And this is what my code looks like:
import json
def load_scores():
with open("scores.json") as infile:
return json.load(infile)
def save_scores(scores):
with open("scores.json", "w") as outfile:
json.dump(scores, outfile)
print("Scores Saved")
def scoresMenu():
print ("""Please pick a valid option from the list below
1 » Load existing scores from the database
2 » Save the scores from this session
3 » Create a new score for the database
4 » Delete specific scores from the database
""")
menuInput = input(" Option » ")
if menuInput == "3":
global scores
name = input(" Input Your Username » ")
score = int(input("Input Your Score » "))
entry = [score, name]
scores.append(entry)
scores.sort(reverse=True)
scores = scores[:10]
elif menuInput == "1":
print(scores)
elif menuInput == "2":
save_scores(scores)
elif menuInput == "4":
print("Work In Progress!")
else:
print("GoodBye! Thanks for trying our program.")
exit
scores = load_scores()
while True:
print(" ")
scoresMenu()
To sum up, what I want to achieve is if a user inputs, for example, 'Tomby' it would delete the score assosiacted and the name from the file so [15, "TomBy"] would be removed. How would I implement this?
Ask the user for the name to delete
Iterate the list
Delete the item that matches the name
It might look like like this:
#UNTESTED
name = input(" Input Your Username » ")
for index, item in enumerate(scores):
if item[1] == name:
del scores[index]
break