Looping through a dictionary for calculation - python

I'm brand new if you can't tell.
I want to loop through each dictionary, so that I can calculate the total worth of the 'menu' but i have no idea how to construct the loop.
Please help...
menu = ["Cappuccino", "Espresso", "Latte", "Macchiato"]
stock = {"Cappuccino": 24,
"Espresso": 18,
"Latte": 39,
"Macchiato": 43}
price = {"Cappuccino": 4.36,
"Espresso": 1.70,
"Latte": 3.25,
"Macchiato": 1.80}

You need to use the for loop for this.
I assume you want to sum the number of each element multiplied by the nummber ofelements in stock
total_price = 0
for item in menu:
total_price += price[item] * stock[item]
print(total_price)
total_price will have the total value of your stock

Related

How to find which products have the best value in Python

I am currently creating a code/application that will help shoppers determine which products to purchase, by calculating the best value. The best value of a product is calculated by finding the $/g, which is found by dividing the cost of the product by the mass of the product.
My problem is, that if there are multiple products that have the same best value, then it will only show one of the products that have the best value. Is there a way so that it will display ALL of the products with the best value? Thank you kindly in advance.
Here's my code so far:
def best_cost():
while True:
num_of_products = int(input('How many products are there? '))
if num_of_products < 1:
print(f'Enter valid number for number of products')
else:
print(f'Finding best value out of {num_of_products} products')
all_prices = []
for i in range(1, num_of_products+1):
cost = float(input(f'Enter cost of product {i} $'))
mass = float(input(f'Enter mass of product {i} in grams:'))
print(f'Product {i} at ${cost / mass} per gram')
price = cost/mass
all_prices.append(price)
for prod in all_prices:
if prod == min(all_prices):
best_prod = all_prices.index(prod)+1
return print(f'Best product is Product {best_prod}')
best_cost()
The reason is because you return from the print statement, so you only ever get one item. You can instead build a list and return a list of items. You should also use something like math.isclose for comparing floating point values. Otherwise you can get some hard to track down errors.
You will also want to track the last index that you found a value for so you can find the next available item in the list.
from math import isclose
def best_cost():
while True:
num_of_products = int(input('How many products are there? '))
if num_of_products < 1:
print(f'Enter valid number for number of products')
else:
print(f'Finding best value out of {num_of_products} products')
all_prices = []
for i in range(1, num_of_products+1):
cost = float(input(f'Enter cost of product {i} $'))
mass = float(input(f'Enter mass of product {i} in grams:'))
print(f'Product {i} at ${cost / mass} per gram')
price = cost/mass
all_prices.append(price)
min_price = min(all_prices) # You only need to do the min check once
best_prods = [] # Create a list to store the results in
for i, prod in enumerate(all_prices, 1):
if isclose(prod, min_price):
best_prods.append(i)
print(f'Best product(s) are: {best_prods}')
best_cost()
Your code works, but when you return the whole operation stops.
If you are not using the return value, you can not return and it will print all the new products
best_prod = all_prices.index(prod)+1
print(f'Best product is Product {best_prod}')
or if you want to return a list of all the best products, keep track of them with a list:
best_products = []
...
for prod in all_prices:
if prod == min(all_prices):
best_prod = all_prices.index(prod)+1
best_products.append(best_prod)
print(f'Best product is Product {best_prod}')
return best_products

what is the mistake in the while/for loop?

This is the output using the wrong for/while-loop operation:
current value is 60
current value is 120
total value is 120
This is what I would like it to be:
current value is 10
current value is 30
total value is 30
prices = [10, 20, 30]
total = 0
steps = 0
step_limit = 2
while steps < step_limit:
steps +=1
for i in prices:
total += i
print(f'current value is {total}')
print(f'total value is {total}')
If you want to add each element from the list, the problem that arises here is in the following part of your code:
for i in prices:
total += i
This means that you iterate through each element inside the list and add it to the total (10+20+30). This is done 2 times, so the total will be 120.
You have to replace that part of the code with something that accesses only one element at a time. For instance:
total += prices[steps]
If you desire to add the last element and display the total straight away with it, you can add the last price outside of the while loop right before the message display at the end:
total += prices[steps]
print(f'total value is {total}')

How to pass assertion at this stage?

I created this function that iterates through dictionaries. I have a price dict, with each price of an item is stored. then customer order dictionary, where every order per customer is stored.
for every item in a customer order, I multiplied the item to the price,
for example...
order 1: 10 books * $10.0
in the end of this function, if the total order is above $100 I will give 10% discount. 5% for above $50 and no discount if lesser than $50.
Now, for some reasons, I cannot alter assertion syntax below..Have to stick with the format and codes in there, the problem is I'm getting an assertion error. which supposed to be, the final output is "DONE"
How can I avoid catching assertions at this stage?
In particular im getting assertion error in order1
here's what I've done...
def calculate_price(price, order):
final_list = []
# Iterating through each dictionary key.
for key, order_value in order.items():
# Splitting on whitespace, taking the first result.
first_word = key.split()[0]
# Initiating condition to compare key similarities.
if first_word in price:
# Matching dict keys successful.
price_value = price[first_word]
# Multiplying key-pair values of two matched keys.
individual_price = (order_value*price_value)
final_list.append(individual_price)
new = sum(final_list)
if new >= 101:
order3 = new - (new*0.10)
elif new >= 51:
order1 = new - (new*0.05)
order1 = int(order1)
else:
order2 = new
price = {'book': 10.0, 'magazine': 5.5, 'newspaper': 2.0}
order1 = {'book': 10}
order2 = {'book': 1, 'magazine': 3}
order3 = {'magazine': 5, 'book': 10}
assert(95 == calculate_price(price, order1))
assert(26.5 == calculate_price(price, order2))
assert(114.75 == calculate_price(price, order3))
print("Done")
your suggestions and help are very much appreaciated. thank you
https://www.tutorialspoint.com/python/assertions_in_python.htm
When it encounters an assert statement, Python evaluates the accompanying expression, which is hopefully true. If the expression is false, Python raises an AssertionError exception.
In your code, the function evaluated to false because your calculate_price function returns a None value.
The contract implied in the assert statement is that the function will return an int or float, that is the cost value calculated for a single order from the inputs to the function.
Try this :
Also added code for raising keyerror in case item in order does not exist in price dictionary.
def calculate_price(price, order):
count = 0
for i in order:
if i in price:
count += (price[i] * order[i])
else :
raise KeyError('Key not found')
if 50 <= count <= 100:
count *= 0.95
elif count > 100:
count *= 0.90
return count
price = {'book': 10.0, 'magazine': 5.5, 'newspaper': 2.0}
order1 = {'book': 10}
order2 = {'book': 1, 'magazine': 3}
order3 = {'magazine': 5, 'book': 10}
assert(95 == calculate_price(price, order1))
assert(26.5 == calculate_price(price, order2))
assert(114.75 == calculate_price(price, order3))
print("Done")

Product Process Order

I want to make a simple process order like :
You filled an order for 1 antacid for a total of $5.33
You filled an order for 3 sour bites for a total of $6.99
My code is:
total = 0
def process_order(x_list):
for x in len(x_list):
print(f"You filled an order for{x[1]} {x[0]} for a total of {x[1]* x[2]}")
x = [("oranges", 4, 3.22),("gummy bears",1,1.99),("sour bites", 3, 2.33), ("antacid", 1, 5.33)]
while(len(x)>0):
process_order(x)
print("Total price: ${:.2f}".format(total))
But I got error
TypeError: 'int' object is not iterable
As far as I understood, this seems like the code you want:
total = 0
def process_order(x_list):
global total
for x in x_list:
print(f"You filled an order for {x[1]} {x[0]} for a total of {x[1]* x[2]}")
total = total + x[1] * x[2]
return
x = [("oranges", 4, 3.22),("gummy bears",1,1.99),("sour bites", 3, 2.33), ("antacid", 1, 5.33)]
process_order(x)
print("Total price: ${:.2f}".format(total))
Output:
You filled an order for 4 oranges for a total of 12.88
You filled an order for 1 gummy bears for a total of 1.99
You filled an order for 3 sour bites for a total of 6.99
You filled an order for 1 antacid for a total of 5.33
Total price: $27.19
You need to define total as a global variable to get a overall total of the prices. Also, you can iterate through the list in python, as for list_element in list. If you want to make a function, it needs return statement at the end. In this case, what you have to do is to add each prices to global variable, and print out the process for each items, there's no need to return something.
You code is can be simplified with the same concepts minus the use of a defined function. First thing to address, is your while len(x) > 0 needs something to decrease the len(x) to end the loop. For this we can use .pop(). This will remove the item at index , we will use 0, and assign that to a variable z. From here we can use your print statement unchanged, I used other formatting for preference. And then we can add the total of each person to our running total.
x = [("oranges", 4, 3.22),("gummy bears",1,1.99),("sour bites", 3, 2.33), ("antacid", 1, 5.33)]
total = 0
while len(x) > 0:
z = x.pop(0)
print('You filled and order for {} {} for a total of {}'.format(z[1], z[0], z[1] * z[2]))
total += z[1] * z[2]
print("Total price: {:.2f}".format(total))
You filled and order for 4 oranges for a total of 12.88
You filled and order for 1 gummy bears for a total of 1.99
You filled and order for 3 sour bites for a total of 6.99
You filled and order for 1 antacid for a total of 5.33
Total price: 27.19
Function name process_order gives an idea, that only one order has been processed. so it's not a good idea to process many orders there at once. Moreso, if you return an order total from this function, you can sum over it afterwards to have total: total = sum(map(process_order, orders)). This will save you a lot of time to improve your functions while line with counting total still be the same.
The sample code below:
def process_order(order):
"""Process an order.
Order is a tuple and contains 3 fields: name, quantity and price.
"""
name, quantity, price = order
total_price = price * quantity
print(f"You filled an order for {]} {} for a total of {.2f}".format(
quantity, name, total_price))
return total_price
orders = [
("oranges", 4, 3.22), ("gummy bears", 1, 1.99),
("sour bites", 3, 2.33), ("antacid", 1, 5.33)]
total = sum(map(process_order, orders)) # can be rewritten with for loop
print("Total price: ${:.2f}".format(total))

Python - Retrieving an element from a tuple from a list

I am a beginner in Python and am struggling on retrieving an element out of a tuple from a list. What I am trying to do is to get the value of a fruit and multiply it by the quantity needed. An example below will show you what I mean. I can not figure out how to get the second element in the tuple.
##Cost of [('apples', 2.0), ('pears', 3.0), ('limes', 4.0)] is 12.25
fruitPrices = {'apples':2.00, 'oranges': 1.50, 'pears': 1.75,'limes':0.75,
'strawberries':1.00}
def buyLotsOfFruit(orderList):
## orderList: List of (fruit, numPounds) tuples
## Returns cost of order
totalCost = 0.0
for fruit,price in fruitPrices.items():
if fruit not in fruitPrices:
print 'not here!'
else:
totalCost = totalCost +fruitPrices[fruitPrices.index(fruit)].key() * price
return totalCost
It is mostly in my else statement that I can not get it working. All help is greatly appreciated!
Why are you looping over the dictionary? Loop over your list instead, and add to totalCost accordingly.
for fruit, n in orderList:
if fruit in fruitPrices:
totalCost += fruitPrices[fruit] * n
else:
print fruit, 'not here!'
You can simplify all this and do something like
sum(fruitPrices.get(fruit, 0) * n for fruit, n in orderList)
Note that fruitPrices.get(fruit, 0) will return fruitPrices[fruit] if fruit is in fruitPrices and 0 otherwise.
fruitPrices = {'apples':2.00, 'oranges': 1.50, 'pears': 1.75,'limes':0.75,
'strawberries':1.00}
def buyLotsOfFruit(orderList):
## orderList: List of (fruit, numPounds) tuples
## Returns cost of order
totalCost = 0.0
for fruit,price in fruitPrices.items():
if fruit not in fruitPrices:
print 'not here!'
else:
#totalCost = totalCost +fruitPrices[fruitPrices.index(fruit)].key() * price
totalCost = totalCost +fruitPrices[fruit] * price
return totalCost
Could get this down to one line, but I dont think it will help. You are looping over the prices dictionary, but should be looping over the orderList, and then looking up the fruit in the dictionary.
def buyLotsOfFruit(orderList):
totalCost = 0.0
for fruit, quantity in orderList:
if fruit not in fruitPrices:
print 'not here!'
else:
totalCost = totalCost +fruitPrices[fruit]* quantiy
return totalCost
NOTE:
You can put this entire function into a one-liner like this:
buyLotsOfFruit = lambda ol: sum(fruitPrices[f] * p for f, p in ol if f in fruitPrices)
Or this other way:
def buyLotsOfFruit(orderList):
## orderList: List of (fruit, numPounds) tuples
## Returns cost of order
totalCost = 0.0
for fruit, pounds in orderList:
if fruit not in fruitPrices:
print 'not here!'
else:
totalCost += fruitPrices[fruit] * pounds
return totalCost
To retrieve a key from a dictionary all you need is this: dictionary[key]
and it returns the value

Categories

Resources