How do I add an inventory remaining counter? [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Previously, I have asked for help in my attempt to add an inventory counter that has not worked. This is the original program I made. Everything works properly. How do I set each item (Pants, Shirt, Dress, Socks, and Sweater) to have a qty of 100 then take the input of qty and subtract that number. Lastly, printing what is left of the 100 after your bill is printed in Option 2 of the menu. Please edit the code to help me solve this issue. I really want to be done with this program. Thank you for your time.
#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 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()
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 never define item_type_qty. All you ever do with it in your class is this:
self.item_type_qty[["Pants",20],["Dress",20]]
Which has no effect, since it looks like you're trying to get a value out using weird indexes. If you meant to assign it, do it like this:
self.item_type_qty = [["Pants",20],["Dress",20]]
However, you'll run into another problem with this line:
for x in c.item_type_qty:
That line is run before you call inhand, meaning item_type_qty will be still undefined when that line is reached, throwing that error anyway. You kind of have a circular dependency going on, where you try to loop through item_type_qty, which is set by inhand(), but then in your loop you call inhand() with x[0] and x[1], but x is an item from item_type_qty, which is defined in inhand. Just kind of a messy situation that doesn't make sense.

Related

Variables and Functions explanation for a beginner [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 months ago.
Improve this question
I don't know how functions work and would like help making sure that I can have the variable change depending on which 'person' is running the account. Can someone explain how to change the 'bad' variable so that it goes to a 'person 1' 'person 2' or 'person 3' depending on which the user chooses to enter?:
bal=500
lock=0
end=False
def atm():
while end==False:
if lock>=4:
while lockloop==True:
try:
print("Your balance is $",bal, sep='')
lk=int(input("Error, you have locked your account. Please enter funds until balance becomes positive: \n$"))
if lk<=0:
print("Please input a positive amount")
continue
bal=bal+lk
if bal<0:
continue
except ValueError:
print("Try again")
continue
else:
lockloop=False
lk=0
lock=0
print("Your balance is now: $", bal, sep='')
des=input("Would you like to (d)eposit, (w)ithdraw, (b)alance, or (e)nd? ")
witloop=True
deploop=True
lockloop=True
if lock>1 and bal>=0:
lock=1
if des=="deposit" or des=="d" and lock<4:
while deploop==True:
try:
dep=int(input("How much would you like to deposit? "))
if dep<=0:
print("Please input a positive amount")
continue
except ValueError:
print("Try again")
continue
else:
deploop=False
bal=dep+bal
dep=0
if bal<0 and lock==0:
bal=bal-50
lock=lock+1
print("You have incured an overdraft fee of $50. It will be removed from your account.")
if bal<0 and lock!=0:
lock=lock+1
print("Your account is still overdrawn. Please deposit funds.")
print("You now have: $", bal, sep='')
continue
elif des=="withdraw" or des=="w" and lock<4:
if bal<=0:
print("Cannot withdraw funds at this time.")
continue
while witloop==True:
try:
wit=int(input("How much would you like to withdraw? "))
if wit<=0:
print("Please input a positive amount")
continue
except ValueError:
print("Try again")
continue
else:
witloop=False
bal=bal-wit
wit=0
if bal<0 and lock==0:
bal=bal-50
lock=lock+1
print("You have incured an overdraft fee of $50. It will be removed from your account.")
if bal<0 and lock!=0:
lock=lock+1
print("Your account is still overdrawn. Please deposit funds.")
print("You now have: $", bal, sep='')
continue
elif des=="balance" or des=="b":
print("You have: $", bal, sep='')
continue
elif des=="end" or des=="e" and lock==0:
end=True
print("Thank you for banking with Nolan's Banking Services today! Have a great day! :)")
else:
print("You must enter one of the four options, try again")
continue
atm()
Running your code as-is is returning this error:
UnboundLocalError: local variable 'end' referenced before assignment
The reason here is to do with the scope of your variables. You are declaring the bal, lock and end variables outside of your function, therefore making them global variables. But you are also then declaring those variables inside the function, making them local variables. The interpreter is getting confused and the error is telling you the the local variable end is being used before it is being assigned.
Don't mix and match variables inside and outside a function like this. You should try to avoid global variables in your functions as much as possible as a good rule of thumb when programming.
You could read some more here as a starting point:
https://www.w3schools.com/python/python_variables_global.asp
https://bobbyhadz.com/blog/python-unboundlocalerror-local-variable-name-referenced-before-assignment
I don't know how to have the function use a different variable for each person
You can pass arguments into your function like this. In this case, when we define the function, we tell it to expect an argument called user that you can then use inside your function.
def atm(user):
if user == 'Nolan':
print('Hi Nolan')
elif user == 'Lummers':
print('Hi Lummers')
else:
print("I don't talk to strangers")
atm('Nolan')
atm('Lummers')
atm('John Doe')
To provide a different variable for each person I suggest you look into classes. Something like ...
class Person:
def __init__(self, name: str, balance: float = 0):
"""Create a new person each time."""
self.name = name
self.balance = balance
def action(self, action: str, amount: float):
if action == 'deposit':
self.balance += amount
elif action == 'withdraw':
self.balance -= amount
def __repr__(self):
return f"{self.name} {self.balance}"
def main():
customers = {}
customers['Fred'] = Person('Fred', 500)
customers['Jane'] = Person('Jane')
"""Preload some actions for example."""
actions = [
['Fred', 'withdraw', 123],
['Jane', 'deposit', 789]
]
"""Process the actions. Could run forever."""
for person, action, value in actions:
if person in customers:
customers[person].action(action, value)
print(customers)
if __name__ == '__main__':
main()

How do I subtract items that are in my inventory and print them later in my program?

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)

Python dictionary becomes empty as soon as the function, which added items to it, finishes execution

I am trying to write a menu in which option 1 would add a key:value pair to a dictionary and option 2 would run a threading module using the items from the dictionary. Key is a message from the user input and Value is a number of seconds, from the user input, that a thread should pause for, before displaying the message.
Threading itself is irrelevant right now though. What I'm struggling with is the fact that when I use the function for option 1, it adds the key:value pairs to the dictionary (called messages_and_times) successfully. But as soon as the function is finished the dictionary becomes empty again, as can be seen from the function for option 2, which accesses it.
At the bottom you can see my code. I've added the following lines in order to check what's in the dictionary at each step:
print(dict(messages_and_times))
if not messages_and_times:
print("This dictionary is empty.")
else:
print("This dictionary contains items.")
It doesn't seem to work correctly either however. First of all it prints "This dictionary contains items." whether the printed dictionary looks empty or not. Second of all the following part of my code (clear() is used for clearing the terminal display):
def create_dictionary():
clear()
answer = input(
"Would you like to add another message? (yes/no)").lower()
if answer == "yes":
option_1()
elif answer == "no":
clear()
print("You will now be returned to the main menu.")
print(dict(messages_and_times))
does print a dictionary containing items if I chose to add them. But if I add the line
print(dict(messages_and_times))
to the main_menu() itself, the above mentioned create_dictionary() function prints an empty dictionary instead. Just this one print() statement in the main_menu() affects whether create_dictionary() shows a dictionary with items in it or not.
Could someone please help me understand how to design a code in which the dictionary retains the items created by one function, so that they can be accessed by other functions?
Thank you in advance for your time and assistance,
import os
clear = lambda: os.system('cls')
def main_menu():
list_of_messages = []
list_of_times = []
messages_and_times = zip(list_of_messages, list_of_times)
def option_1():
clear()
list_of_messages.append(
input("Please type in a message you would like to add to the list:"))
clear()
list_of_times.append(
input("Please type in the time of delay for this message:"))
def create_dictionary():
clear()
answer = input(
"Would you like to add another message? (yes/no)").lower()
if answer == "yes":
option_1()
elif answer == "no":
clear()
print("You will now be returned to the main menu.")
print(dict(messages_and_times))
if not messages_and_times:
print("This dictionary is empty.")
else:
print("This dictionary contains items.")
time.sleep(1.5)
main_menu()
else:
clear()
print("Please answer yes or no.")
time.sleep(1.5)
create_dictionary()
create_dictionary()
def option_2():
clear()
print(dict(messages_and_times))
if not messages_and_times:
print("This dictionary is empty.")
else:
print("This dictionary contains items.")
time.sleep(5)
main_menu()
clear()
selection = 0
while selection == 0:
print(("-" * 15) + "MAIN MENU" + ("-" * 15) + "\n")
print("1: Input a message and a corresponding time of delay before its display.")
print("2: Print your customized list of messages.")
print("3: Generate a list of random messages with random delays.\n")
selection = int(input(
"Please select one of the options, by typing in the corresponding number:"))
if selection == 1:
option_1()
elif selection == 2:
option_2()
elif selection == 3:
clear()
print("You've selected the third option.")
else:
clear()
print("Please select from options 1 - 3.\n")
time.sleep(1.5)
main_menu()

Python not importing data structure [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm trying to create a text-based game. I've made a basic/generic intro and now it's getting long so I want to create a new file so that I can add things like armor and weapons. When I went to try to import 'my_character' it gave me an error so I went to research this problem and I found this, so I tried it. I just got an error message saying it wasn't define (similar to the error below). This is the intro part named intro:
# Date started: 3/13/2018
# Description: text based adventure game
import time
def display_intro():
print('It is the end of a 100 year war between good and evil that had\n' +
'killed more than 80% of the total human population. \n')
time.sleep(3)
print('The man who will soon be your father was a brave adventurer who \n'
+ 'fought for the good and was made famous for his heroism. \n')
time.sleep(3)
print('One day that brave adventurer meet a beautiful woman who he later \n'
+ 'wed and had you. \n')
time.sleep(3)
def main():
display_intro()
main()
gen = input('\nYour mother had a [Boy or Girl]: ')
name = input("\nAnd they named you: ")
print("You are a {} named {}".format(gen, name))
chara_class = None
# Assigning points Main
my_character = {
'name': name,
'gender': gen,
'class': chara_class,
'strength': 0,
'health': 0,
'wisdom': 0,
'dexterity': 0,
'points': 20
}
# This is a sequence establishes base stats.
def start_stat():
print("\nThis is the most important part of the intro")
time.sleep(3)
print("\nThis decides your future stats and potentially future gameplay.")
time.sleep(4)
print("\nYou have 20 points to put in any of the following category: Strength, Health, Wisdom, or Dexterity.\n"
)
def add_character_points(): # This adds player points in the beginnning
attribute = input("\nWhich attribute do you want to assign it to? ")
if attribute in my_character.keys():
amount = int(input("By how much? "))
if (amount > my_character['points']) or (my_character['points'] <= 0):
print("Not enough points!!! ")
else:
my_character[attribute] += amount
my_character['points'] -= amount
else:
print("That attribute doesn't exist! \nYou might have to type it in all lowercase letters!!!")
def remove_character_points():
attribute = input("\nWhich of the catagories do you want to remove from? ")
if attribute in my_character.keys():
amount = int(input("How many points do you want to remove? "))
if amount > my_character[attribute]:
print("\nYou are taking away too many points!")
else:
my_character[attribute] -= amount
my_character['points'] += amount
else:
print(
"That attribute doesn't exist! \nYou might have to type it in all lowercase letters!!!")
def print_character():
for attribute in my_character.keys():
print("{} : {}".format(attribute, my_character[attribute]))
playContinue = "no"
while playContinue == "no":
Continue = input("Are you sure you want to continue?\n")
if Continue == "yes" or "Yes" or "y":
playContinue = "yes"
start_stat()
add_character_points()
elif Continue == "n" or "No" or "no":
main()
running = True
while running:
print("\nYou have {} points left\n".format(my_character['points']))
print("1. Add points\n2. Remove points. \n3. See current attributes. \n4. Exit\n")
choice = input("Choice: ")
if choice == "1":
add_character_points()
elif choice == "2":
remove_character_points()
elif choice == "3":
print_character()
elif choice == "4":
running = False
else:
pass
def story_str():
print(
"\nYou were always a strong child who easily do physical labor and gain lots of muscle."
)
time.sleep(3)
print("\nYou regularly trained with your dad who was also a skilled swordsman.")
time.sleep(3)
print("\nAs you grew into an adult, you're swordsmanship improved drastically.")
time.sleep(3)
print("\nOnce old enough, you joined the local guild as a warrior.")
time.sleep(3)
def story_dex():
print("\nYou were a sly child. You would always be stealing from other people and with"
+ "\nconstant practice you became proficient at thieving.")
time.sleep(3)
print("\nCombined with the skill of knives and short-blades, you became an extremely deadly assassin."
)
time.sleep(3)
print("\nOnce old enough, you joined the local guild as an assassin.")
time.sleep(3)
def story_wis():
print("\nYou grew up as a very intellegent child. You read books everyday and realized that magic"
+ "is the best offensively and defensively.")
print("\nYou grew up and attended the best magic school avalible and graduated."
)
print("\nYou soon went to the local guild and joined as a wizard.")
run_story = False
while run_story:
if my_character['strength'] >= 13:
story_str()
chara_class = 'Warrior'
run_story = True
else:
continue
if my_character['dexterity'] >= 13:
story_dex()
chara_class = 'Assassin'
run_story = True
else:
continue
if my_character["wisdom"] >= 13:
story_wis()
chara_class = 'Mage'
run_story = True
else:
continue
The command I have typed on part1 is to try to import my_character is:
from intro import my_character
print(my_character)
I have been trying to import my_character but it comes up as:
Traceback (most recent call last):
File "C:/Users/user/Desktop/part1.py", line 5, in <module>
my_character
NameError: name 'my_character' is not defined
The original file was named "intro" and the new one is named "part1". Do I need to do the 'if name == "__main"' thing? If so, what does that do?
Check for:
1) is the file name my_character.py
2) you have imported it as my_character
3) my_character is in the main python directory (if you are importing in interpreter)

errors with Elif expected indented block

I'm trying to create a menu for my application, the menu has 4 options and each of these options should return with the correct information when the user has entered the chosen value. i keep getting an error with the Elif statements.
I am a newbie so please understand where am coming from.
much appreciation.
when i indent the while ans: i will receive an error says invalid syntax after indenting the elif ans==2.
elif ans==2 <--- this error keeps saying indention block error or syntex invalid when i indent it.
def print_menu(self,car):
print ("1.Search by platenumber")
print ("2.Search by price ")
print ("3.Delete 3")
print ("4.Exit 4")
loop=True
while loop:
print_menu()
ans==input("Please choose from the list")
if ans==1:
print("These are the cars within this platenumber")
return platenumber_
while ans:
if ans==2:
elif ans==2:
print("These are the prices of the cars")
return price_
elif ans==3:
print("Delete the cars ")
return delete_
elif ans==4:
return Exit_
loop=False
else:
raw_input("please choose a correct option")
You have a while loop without a body. Generally speaking, if there is an indentation error message and the error is not on the line mentioned, it's something closely above it.
loop=True
while loop:
print_menu()
ans = int(input("Please choose from the list"))
if ans==1:
print("These are the cars within this platenumber")
# return some valid information about plate numbers
elif ans==2:
print("These are the prices of the cars")
# return some valid information about pricing
elif ans==3:
print("Delete the cars ")
# Perform car deletion action and return
elif ans==4:
# I am assuming this is the exit option? in which case
# return without doing anything
else:
# In this case they have not chosen a valid option. Send
# A message to the user, and do nothing. The while loop will run again.
print("please choose a correct option")
Also, your code is a bit confusing to me. It looks like you're going to return car_ no matter what, which means your loop will only execute once. Also, = is assignment and == is equality. Be careful.

Categories

Resources