How to update user input result in while loop? - python

I'm trying to give the user information about the product, but how can I give it to them in case they add another product to the order?
import datetime
db = [
{
'product': 'cola',
'price': {
'USD': '2',
'GEL': '6'
},
'amount': 20,
'validity': '17/12/2019'
},
{
'product': 'cake',
'price': {
'USD': '3',
'GEL': '9'
},
'amount': 15,
'validity': '17/12/2019'
},
{
'product': 'tea',
'price': {
'USD': '1',
'GEL': '3'
},
'amount': 14,
'validity': '17/12/2019'
},
]
amount_of_product = {}
validity_of_product = {}
prices_of_product = {}
for i in db:
amount_of_product.update({i["product"]: i["amount"]})
validity_of_product.update({i["product"]: i["validity"]})
prices_of_product.update({i["product"]: i["price"]})
adLoop = True
final_price = []
while adLoop:
user_input = input("Please enter a product name: ")
if user_input in amount_of_product.keys() and validity_of_product.keys():
print(f"Currently, we have {amount_of_product[user_input]} amount of {user_input} left, "
f"which are valid through {validity_of_product[user_input]}")
user_input_two = int(input("Please enter the amount: "))
user_input_three = input("In which currency would you like to pay in?(GEL or USD: ").upper()
price = prices_of_product[user_input][user_input_three]
total = user_input_two * int(price)
if user_input_three == "GEL":
final_price.append(total)
print(f"Your order is: {user_input_two} {user_input} and total price for it is: {total}₾")
elif user_input_three == "USD":
final_price.append(total * 3)
print(f"Your order is: {user_input_two} {user_input} and total price for it is: {total}$")
stop_or_order = input("Would you like to add anything else?: ")
if stop_or_order == "yes":
adLoop = True
elif stop_or_order == "no":
adLoop = False
so if user orders cola and cake, I want the output to look like this:
Your order is 1 cola and 1 cake and total price of it is: sum(final_price)
But every time I execute the code, the older input gets removed and I get the newer input as a result. I want to save it somewhere and show the user everything he/she ordered.

You're defining user_input inside the loop, so it gets overwritten each iteration. You could define an dict
user_shopping_cart = {
'cola':0,
'cake':0,
'tea':0
}
before the while loop and update the cart as the user puts items inside,
then generate the output with data from the cart.

Related

How to put this in a loop [duplicate]

This question already has an answer here:
How to create a counter that counts unrighteous inputs
(1 answer)
Closed 2 months ago.
I need to put this code in a loop so that you can choose whichever number first and go back to the start after whichever one you choose, but everything I've tried hasn't worked and need help.
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
option = int(input("Enter an option: "))
if option == 1:
people = input("Who are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"]
[item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
option = int(input("\nEnter an option: "))
if option == 2:
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
answer = input("Do you want to complete their shopping list (Y/N)? ")
if answer.upper() == "Y":
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
option = int(input("\nEnter an option: "))
if option == 3:
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
option = int(input("\nEnter an option: "))
if option == 4:
print("Thank You For Shopping With Us!")
I've tried putting in different versions of loop, but it always either results in the program ignoring it and not going back to the start, or breaking when I choose something else then 1 at the start.
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
With the same list above, After adding in my information to the set example given, I would get the error below.
error with pic: https://i.stack.imgur.com/BrqBB.png
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
while True:
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
It now looks exactly like this, and it still gives back a syntax error on the first elif statement. I don't understand what the problem is if it's properly indented and should follow the correct rules to use it.
edited with error: https://i.stack.imgur.com/rTW6k.png
The syntax error is finally gone, but now lies the problem where the code just repeats itself on the menu screen without going anywhere, like this:
repeating: https://i.stack.imgur.com/YNPdF.png
I would do something like this:
while True:
print(<instructions>)
option = input("Enter an option: ")
if option == "1":
do stuff...
elif option == "2":
do number two stuff..
elif option == "3":
do that third stuff..
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
This will keep the menu in a loop and if option 4 is selected, it will break from the loop and continue on.
The issue now is with your indentation. You must indent your code properly for python to be able to understand what you want it to do, for instance:
x= "3"
if x == "2":
print("hello world")
print("outside the indent")
you console output would be:
>>outside the indent
but if your code looks like this:
x= "3"
if x == "2":
print("hello world")
print("outside the indent")
you would get no output from the console, everything is within the "if" code block. Indentation is crucial for python to exhibit the expected behavior. you need to make sure that all your code for each condition is indented properly inside the if blocks, like the example I gave above. Also, if you want this in a loop, you need to put it in a loop with the while True: statement, and indent everything inside it.
Your final result should look something like this:
peoples = {
"Mary": {
"name": "Mary",
"budget": 100,
"items": {
"Game": 0,
"Book": 0,
"Kindle": 0
},
"status": "incomplete"
},
"Steve": {
"name": "Steve",
"budget": 100,
"items": {
"Tie": 0,
"Scarf": 0,
"Amazon Echo": 0
},
"status": "incomplete"
},
"Kevin": {
"name": "Kevin",
"budget": 65,
"items": {
"Mario Kart": 0
},
"status": "incomplete"
},
"Jane": {
"name": "Jane",
"budget": 50,
"items": {
"Gift Card": 0,
"Gloves": 0
},
"status": "incomplete"
},
"Chris": {
"name": "Chris",
"budget": 100,
"items": {
"Chocolates": 0,
"Galaxy Tab": 0
},
"status": "incomplete"
}
}
print("""
Menu
--------------------
1. Update Shopping List
2. Complete Shopping List
3. Display Shopping List
4. Exit Application
--------------------
Make your selection
""")
while True:
option = input("Enter an option: ")
if option == "1":
people = input("\nWho are you updating?: ")
print("\nCurrent values of people",people)
print(peoples[people])
print("\nAvailable items and their prices are:")
for item in peoples[people]["items"]:
print(item, peoples[people]["items"][item])
item_to_update = input("Enter an item to update: ")
price = int(input("Enter updated price: "))
budget = peoples[people]["budget"] - peoples[people]["items"][item_to_update] - price
peoples[people]["items"][item_to_update] = price
peoples[people]["budget"] = budget
print("\nUpdated values of people",people)
print(peoples[people])
elif option == "2":
update = input("Choose one of the 5 people to complete their shopping list: ")
if update in peoples:
print("You have chosen",update)
peoples[people]['status'] = 'complete'
print("Shopping list has been completed!")
elif option == "3":
display = input("Who's do you want to look at?: ")
print("\nShopping List Of",display)
print(peoples[display])
elif option == "4":
print("Thank You For Shopping With Us!")
break
else:
print("That's not a valid answer! Try again!")
Also, please review this link as it is crucial you understand how to properly indent your code when writing python.
https://www.geeksforgeeks.org/indentation-in-python/

Removing a key from a dictionary using the value

Can I somehow delete a value from a dictionary using its key?
The function del_contact is supposed to delete a contact using only the name of the contact, but unfortunately I have the dictionary and the value, but not the key. How can this be solved?
my_contacts = {
1: {
"Name": "Tom Jones",
"Number": "911",
"Birthday": "22.10.1995",
"Address": "212 street"
},
2: {
"Name": "Bob Marley",
"Number": "0800838383",
"Birthday": "22.10.1991",
"Address": "31 street"
}
}
def add_contact():
user_input = int(input("please enter how many contacts you wanna add: "))
index = len(my_contacts) + 1
for _ in range(user_input):
details = {}
name = input("Enter the name: ")
number = input("Enter the number: ")
birthday = input("Enter the birthday")
address = input("Enter the address")
details["Name"] = name
details["Number"] = number
details["Birthday"] = birthday
details["Address"] = address
my_contacts[index] = details
index += 1
print(my_contacts)
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
my_contacts.pop(user_input)
add_contact()
print(my_contacts)
The problem is that my key of the dictionary is 1 or Name, and I want to be able to remove the contact using only the value of Name.
Basically what you can do is iterate of the dict and save only the keys without that user's name.
This code will do the trick:
my_contacts = {1: {"Name": "Tom Jones",
"Number": "911",
"Birthday": "22.10.1995",
"Address": "212 street"},
2: {"Name": "Bob Marley",
"Number": "0800838383",
"Birthday": "22.10.1991",
"Address": "31 street"}
}
user_input = "Tom Jones"
my_contacts = {key: value for key, value in my_contacts.items() if value["Name"] != user_input}
There's two steps here:
Finding the key/value pair(s) that match
Deleting the keys you found
If you're only deleting a single item (even with multiple matches), always, these can be combined:
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
for k, v in my_contacts.items(): # Need both key and value, we test key, delete by value
if v["Name"] == user_input:
del my_contacts[k]
break # Deleted one item, stop now (we'd RuntimeError if iteration continued)
else:
# Optionally raise exception or print error indicating name wasn't found
If you might delete multiple entries, and must operate in place, you'd split the steps (because it's illegal to continue iterating a dict while mutating the set of keys):
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
to_delete = [k for k, v in my_contacts.items() if v["Name"] == user_input]
if not to_delete:
# Optionally raise exception or print error indicating name wasn't found
for k in to_delete:
del my_contacts[k]
Or if you're okay with replacing the original dict, rather than mutating it in place, you can one-line the multi-deletion case as:
def del_contact():
global my_contacts # Assignment requires explicitly declared use of global
user_input = input("Please enter the name of the contact you want to delete: ")
my_contacts = {k: v for k, v in my_contacts.items() if v["Name"] != user_input} # Flip test, build new dict
# Detecting no matches is more annoying here (it's basically comparing
# length before and after), so I'm omitting it
I think thats what you need, hope that helps:
Code:
my_contacts = {1: {"Name": "Tom Jones",
"Number": "911",
"Birthday": "22.10.1995",
"Address": "212 street"},
2: {"Name": "Bob Marley",
"Number": "0800838383",
"Birthday": "22.10.1991",
"Address": "31 street"}
}
def add_contact():
user_input = int(input("please enter how many contacts you wanna add: "))
index = len(my_contacts) + 1
for _ in range(user_input):
details = {}
name = input("Enter the name: ")
number = input("Enter the number: ")
birthday = input("Enter the birthday")
address = input("Enter the address")
details["Name"] = name
details["Number"] = number
details["Birthday"] = birthday
details["Address"] = address
my_contacts[index] = details
index += 1
print(my_contacts)
add_contact()
print(my_contacts)
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
values = [key for key in my_contacts.keys() if user_input in my_contacts[key].values()]
for value in values:
my_contacts.pop(value)
del_contact()
print(my_contacts)
Input:
{1: {'Name': 'Tom Jones', 'Number': '911', 'Birthday': '22.10.1995', 'Address': '212 street'}, 2: {'Name': 'Bob Marley', 'Number': '0800838383', 'Birthday': '22.10.1991', 'Address': '31 street'}, 3: {'Name': 'myname', 'Number': '1233455', 'Birthday': '12-12-22', 'Address': 'blabla street'}}
Please enter the name of the contact you want to delete: Bob Marley
Output:
{1: {'Name': 'Tom Jones', 'Number': '911', 'Birthday': '22.10.1995', 'Address': '212 street'}, 3: {'Name': 'myname', 'Number': '1233455', 'Birthday': '12-12-22', 'Address': 'blabla street'}}
Being that the index are used as keys for the dictionary, the range function can be used as follows:
def del_contact():
user_input = input("Please enter the name of the contact you want to delete: ")
for i in range(1,len(my_contacts)+1):
if my_contacts[i]['Name'] == user_input:
del my_contacts[i]
break
If there can be multiple contacts with the same name that need to be deleted, remove the break statement.
But as mentioned in the comments, there is no need to use an index as a key for the dictionaries. A potential bug you'll encounter with that, is if the first entry is deleted whose name is Tom Jones the dict will have a length of 1 with only one key - 2. Then when you try to add more contacts, when you check the length of the dictionary index = len(my_contacts) + 1, since length is 1, index will be 2. Hence my_contacts[index] = details will update the contact with a key of 2 or "Name": "Bob Marley" instead of adding a new contact.

How do I compare user integer input to values in dictionary? (Python)

I'm working on a vending machine program and my code skips straight to the else statement instead of taking the user input and comparing it to the ID number in the list.
Here's the list and code:
`
itemstock = [
{
"idnum": 0,
"name": 'Water',
"price": 12,
},
{
"idnum": 1,
"name": 'Soda',
"price": 14,
},
{
"idnum": 2,
"name": 'Juice',
"price": 13,
},
]
choice = int(input("Now, choose an item ID from the Menu and enter the ID: "))
for i in itemstock:
if choice in ["idnum"]:
print("You have chosen item", choice)
else:
print("This is not a valid ID.")
break
`
I had hoped for if I had input the number 2, it would display what the user chose along with some text but it skips straight to the else statement. I've tried looking online but I may be doing something wrong here.
if choice in ["idnum"]
That is just a list containing the text "idnum". You want i["idnum"] instead:
for i in itemstock:
if i["idnum"] == choice:
print("You have chosen item", choice)
break
else:
print("This is not a valid ID.")
I also moved the else block out one level, so it is paired with the for loop, not the if statement. When a for loop iterates all the way to the end, the else block is executed (if it has one).

Get max value from nested dictionary return both keys if equal

I have following dictionary
{
"match_1":{
"home_team":2,
"away_team":1
},
"match_2":{
"home_team":1,
"away_team":2
},
"match_3":{
"home_team":1,
"away_team":4}
}
I want to sum home team and away team goals and find which team won in aggregate
if both have same score result is draw.
I tried converting to tuple and used max with lambda but it fails when result score is same.
required output for current question: winner! away team
if same goals in all matches in aggregate: Draw
Use this tricky way
d={
"match_1":{
"home_team":2,
"away_team":1
},
"match_2":{
"home_team":1,
"away_team":2
},
"match_3":{
"home_team":1,
"away_team":4}
}
score = ((i["home_team"], i["away_team"]) for i in d.values())
t1,t2 = map(sum,zip(*score))
[["Away team","Home team"][t1>t2], "Draw"][t1==t2]
Try the below approach
table = {
"match_1":{
"home_team":2,
"away_team":1
},
"match_2":{
"home_team":1,
"away_team":2
},
"match_3":{
"home_team":1,
"away_team":4}
}
score = {}
for match in table.keys():
for team in table[match].keys():
if team in score.keys():
score[team]+=table[match][team]
else:
score[team]=table[match][team]
if score["home_team"]==score["away_team"]:
print("Draw")
elif score["home_team"]>score["away_team"]:
print("Winner! Home team")
else:
print("Winner! Away team")
Output
> python -u "run.py"
Winner! Away team
>
There are many options to do this, and one of the ways is to use reduce function
import functools
d = {
"match_1": {"home_team": 2, "away_team": 1},
"match_2": {"home_team": 1, "away_team": 2},
"match_3": {"home_team": 1, "away_team": 4},
}
result = functools.reduce(
lambda a, b: {
"home_team": a["home_team"] + b["home_team"],
"away_team": a["away_team"] + b["away_team"],
},
d.values(),
)
if result["home_team"] > result["away_team"]:
print("winner! home_team")
elif result["away_team"] > result["home_team"]:
print("winner! away_team")
else:
print("Draw")
I provide an intuition way to deal this problem. You can try the following code snippet:
match = {
"match_1":{
"home_team":2,
"away_team":1
},
"match_2":{
"home_team":1,
"away_team":2
},
"match_3":{
"home_team":1,
"away_team":4}
}
home_team_score = 0
away_team_score = 0
for m in match:
home_team_score += match[m]['home_team']
away_team_score += match[m]['away_team']
if home_team_score > away_team_score:
print("winner! home team")
elif home_team_score < away_team_score:
print("winner! away team")
else:
print("Draw")

Verify the date of birth taken as user input with the value stored in nested dictionary in a list in python

I am trying to verify date of birth taken from user and comparing it with the value stored in dictionary database. But it is not verifying the value even if I have entered the right value of date of birth. Here is my code:
from collections import defaultdict
accountDetails = [
{"FirtsName": "JOHN", "LastName": "DENIS","date of Birth": "01-06-1992", "Account Number": "432524352345234", "Account Balance": "50000"},
{"FirtsName": "AKASH", "LastName": "MAHAJAN", "date of Birth": "04-02-1995","Account Number": "432524352345234", "Account Balance": "50000"},
{"FirtsName": "AMAN", "LastName": "RANA","date of Birth": "11-04-1996", "Account Number": "432524352345234", "Account Balance": "50000"},
{"FirtsName": "ANKUR", "LastName": "JAIN","date of Birth": "21-05-1990", "Account Number": "432524352345234", "Account Balance": "50000"},
]
d = defaultdict(lambda: defaultdict(dict))
for item in accountDetails:
d[item['FirtsName']][item['LastName']][item['date of Birth']] = item
# get valid first name
while True:
first_name_input = input('Enter First Name:\n').upper()
if first_name_input in d:
break
else:
print('Enter valid First Name')
# get valid last name
while True:
last_name_input = input('Enter Last Name:\n').upper()
if last_name_input in d[first_name_input]:
break
else:
print('Enter valid Last Name')
# get valid last name
while True:
dob_input = input('Enter dob:\n')
if dob_input in d[first_name_input]:
break
else:
print('Enter valid dob')
print(d[first_name_input][last_name_input])
The user has put the value as-04-02-1995
You need to test versus keys in the second level of your nested dictionary:
while True:
dob_input = input('Enter dob:\n')
if dob_input in d[first_name_input][last_name_input]:
break
else:
print('Enter valid dob')
This becomes clear when you print the structure of the nested dictionary you have created:
print(d)
defaultdict(<function __main__.<lambda>>,
{'AKASH': defaultdict(dict,
{'MAHAJAN': {'04-02-1995': {'Account Balance': '50000',
'Account Number': '432524352345234',
'FirtsName': 'AKASH',
'LastName': 'MAHAJAN',
'date of Birth': '04-02-1995'}}}),
...
'JOHN': defaultdict(dict,
{'DENIS': {'01-06-1992': {'Account Balance': '50000',
'Account Number': '432524352345234',
'FirtsName': 'JOHN',
'LastName': 'DENIS',
'date of Birth': '01-06-1992'}}})})

Categories