Calculating sum of ordered list of dictionaries - python

I am trying to find out how to return a sum of several values given in a order list of dictionaries
menu = {
1: {"name": 'espresso',
"price": 1.99},
2: {"name": 'coffee',
"price": 2.50},
3: {"name": 'cake',
"price": 2.79},
4: {"name": 'soup',
"price": 4.50},
5: {"name": 'sandwich',
"price": 4.99}
}
def calculate_subtotal(order):
return subtotal
def take_order():
display_menu()
order = []
count = 1
for i in range(3):
item = input('Select menu item number ' + str(count) + ' (from 1 to 5): ')
count += 1
order.append(menu[int(item)])
return order
def calculate_subtotal(order) should accept one argument which is the order list and return the sum
of the prices of the items in the order list.
Do I have to use a for loop to iterate through the values and sum each value?
How do I access the dictionaries inside the list?

Let's say a person orders the following:
orders = [
{"name": "espresso", "price": 1.99},
{"name": "espresso", "price": 1.99},
{"name": "soup", "price": 4.99},
]
You now have a list of dict. Indexing into the list returns a reference to a dictionary. For example:
first_order = orders[0]
print(first_order)
Would print:
{'name': 'espresso', 'price': 1.99}
Using that knowledge, you can loop through the orders like so:
total = 0.0
for order in orders:
total += order["price"]
Each order will be a dict like you saw above.
You can also use a comprehension if you're comfortable with them.
total = sum(order["price"] for order in orders)

Related

How can I get "price"s value in this dict list?

products = [
{"name": "samsung s6", "price": 3000},
{"name": "samsung s7", "price": 4000},
{"name": "samsung s8", "price": 5000},
{"name": "samsung s9", "price": 6000},
{"name": "samsung s10", "price": 7000}
]
for product in products:
for a, b in product.items():
print(b)
hey guys. i want to get price key's value and calculate total price all of items i have. what's the best way to get it?
To get the value of each dict's price key, simply access it using the my_dict["key"] syntax. Here is a basic way to sum the prices using a for loop:
total = 0
for product in products:
total += product["price"]
print(total)
The slightly more advanced method is to create a sequence of prices using a list comprehension or generator expression, and pass it to the built-in sum function, like this:
total = sum(product["price"] for product in products)
The short version:
print( sum( x['price'] for x in products ) )
This is the same as:
newList = []
for x in products:
newList.append( x['price'] )
out = sum( newList )
print( out )

How Can I Find the Minimum number of stores?

so I have a list of stores and their inventory and a shopping list. I need to find the minimum number of stores to satisfy the shopping list. I currently have separated the store name to create all permutations of the stores. I am not sure how to actually make the comparison of stores inventory to the shopping list I have. Any help would be greatly appreciated.
def satisfy_shopping_list(shopping_list_json, inventory_json):
# find out minimum combination of stores that would satisfy shopping list
shops = []
print(inventory_json['stores'])
for item in inventory_json['stores']:
shops.append(item.get("name"))
routes = list(itertools.permutations(shops))
print(routes)
# if shopping list is impossible to satisfy
shopping_list_satisfiable = True
if shopping_list_satisfiable:
# print out number of stores and corresponding combinations
# num_stores = 0
# print "The shopping list can be satisfied by visiting {} store(s):".format(num_stores)
# for each valid store_combination:
# print_store_list(store_combination)
pass
else:
print("No combination of given stores can satisfy this shopping list :(")
pass
def print_store_combination(store_combination):
store_combination_copy = copy.deepcopy(store_combination)
store_combination_copy.sort()
print(', '.join(store_combination_copy))
def main():
args = parse_args()
with open(args.shopping_list_json_path) as shopping_list_json_file, open(args.inventory_json_path) as inventory_json_file:
shopping_list_json = json.load(shopping_list_json_file)
inventory_json = json.load(inventory_json_file)
satisfy_shopping_list(shopping_list_json, inventory_json)
def parse_args():
p = argparse.ArgumentParser()
p.add_argument('shopping_list_json_path')
p.add_argument('inventory_json_path')
args = p.parse_args()
return args
if __name__ == '__main__':
main()
Example Shopping List
{
"apples": 10,
"oranges": 10,
"pineapples": 10,
"coconuts": 10,
"strawberries": 10,
"peaches": 1
}
Inventory Example
{
"stores": [
{
"name":"Kroger",
"inventory": {
"oranges": 10,
"coconuts": 10,
"strawberries": 10
}
},
{
"name":"Meijer",
"inventory": {
"oranges": 10,
"grapes": 10,
"pineapples": 10,
"strawberries": 10
}
},
{
"name":"Store 3",
"inventory": {
"apples": 1,
"oranges": 10,
"bananas": 10,
"grapes": 10,
"chickens": 10
}
},
{
"name":"Whole Foods",
"inventory": {
"grapes": 10,
"pineapples": 10,
"organic apples": 10,
"coconuts": 10,
"strawberries": 10
}
},
{
"name":"Kroger 2",
"inventory": {
"apples": 8
}
},
{
"name":"peach store",
"inventory": {
"peaches": 1
}
},
{
"name":"CVS",
"inventory": {}
},
{
"name":"apples r us",
"inventory": {
"apples": 10000000000000
}
}
]
}
Here's a rough solution from me - just by prioritizing shops that are able to satisfy your shopping list most. Then you just iterate and trim the shopping list from there. I'm leaving the satisfiability check of the shopping list to you. You should do the check before jumping into the iteration I believe, by comparing the aggregate of the inventory against the numbers required in the shopping list.
def satisfy_shopping_list(shopping_list_json, inventory_json):
# find out minimum combination of stores that would satisfy shopping list
shops = []
inventory = [] # De-nesting the shops and their inventories. Matched by index
for item in inventory_json['stores']:
shops.append(item.get("name"))
inventory.append(item.get("inventory"))
# if shopping list is impossible to satisfy
shopping_list_satisfiable = True # You need to do this check yourself
shop_seq = []
if shopping_list_satisfiable:
while len(shopping_list_json) > 0:
# Compute satisfiability score for all shops
# We assign a score of 1 for each item that the shop is able to satisfy fully
# Else, we give it a pro-rated score if the shop has the supplies
scorelist = []
for i, ivt in enumerate(inventory):
score= 0
for k, v in shopping_list_json.items():
if k in ivt.keys():
if ivt[k] >= v:
score += 1
else:
score += (ivt[k]/v)
scorelist.append((score, i))
# Go to the shop with the highest score first
scorelist.sort(key=itemgetter(0), reverse=True)
shop_seq.append(shops[scorelist[0][1]])
# Update shopping list
shop_idx = scorelist[0][1]
to_remove = []
for k, v in shopping_list_json.items():
if k in inventory[shop_idx].keys():
if v - inventory[shop_idx][k] <= 0:
to_remove.append(k)
else:
shopping_list_json[k] = v - inventory[shop_idx][k]
for rem in to_remove:
shopping_list_json.pop(rem)
print(shop_seq)
else:
print("No combination of given stores can satisfy this shopping list :(")
pass

How to extract corresponding value from python dictionary?

I wrote simple python which gives idea how the system performs but the total is not calculated. Now what I want is get the corresponding value (i.e. cone type, Scoop flavor for each scoop, and Topping flavor for each topping) and calculate total cost and finally displaying the items chosen in details (item-->price and quantity) and the total sum.
customername = input("Enter the customer's name....")
ic_no = int(input("Enter the number of ice-creams you want to buy"))
total = {}
for i in range(1, ic_no + 1):
print("For item ", i)
cone = int(input("Enter the cone type: "))
scoop = int(input("Enter the scoop amount: "))
for j in range(1, scoop+1):
#select flavor type for each scoop
flavor = int(input("Entr No."+ str(j) +" flavor"))
topping = int(input("Entr the toppings amount: "))
for k in range(1, topping+1):
#select flavor type for each topping
top_flavor = int(input("Entr No." + str(k) +" topping flavor"))
print("Total price is ", total)
I want to get the selected items simply by passing number. For eg: 1 for 'plain' cone type.
cone_type = (
{"name": "Plain", "price": 2},
{"name": "Wafle", "price": 3},
)
scoop_flavor = (
{"name": "Mint", "price": 1},
{"name": "Caramel", "price": 1},
{"name": "Chocolate", "price": 1},
{"name": "Apple", "price": 1},
)
topping_flavor = (
{"name": "Chocolate", "price": 1},
{"name": "Caramel", "price": 0.5},
{"name": "Peanut", "price": 0.5},
{"name": "Coconut Sprinkle", "price": 0.25},
)
I would like to add to blue_note answer and would suggest to use Enum to get the cone_type as below:
class ConeType (enum.Enum):
PLAIN = 1
WAFLE = 2
print(ConeType(1).name);
Just filter the tuple to get the (only) valid entry, and get its price
def get_price(cone_types, cone_name):
return [cone['price'] for cone in cone_types if cone['name']==cone_name][0]
However, if you only have name & price, it would probably be better to directly form you dictionary as
cone_types {'plain': 2, 'wafle': 3}
and similarly for other dicts. That's how dictionaries are meant to be used, the key should have discriminative value.
You could change your inventory data-structures to be a dictionaries of int:list-of-details, instead of your current lists of dictionaries.
For example:
cone_type = {1:["Plain", 2], 2:["Waffle", 3]}
For the plain cone, the name is accessed with cone_type[1][0], and the price with cone_type[1][1].
You might also consider creating a class each for cones, flavors and toppings. Then, you can use these as values for the dictionaries, in place of lists. Doing so would allow you to access product information as cone_type[1].getName() and cone_type[1].getPrice(), which is a lot easier to read!

Dynamic approach to iterate nested dict and list of dict in Python

I am looking for a dynamic approach to solve my issue. I have a very complex structure, but for simplicity,
I have a dictionary structure like this:
dict1={
"outer_key1" : {
"total" : 5 #1.I want the value of "total"
},
"outer_key2" :
[{
"type": "ABC", #2. I want to count whole structure where type="ABC"
"comments": {
"nested_comment":[
{
"key":"value",
"id": 1
},
{
"key":"value",
"id": 2
}
] # 3. Count Dict inside this list.
}}]}
I want to this iterate dictionary and solve #1, #2 and #3.
My attempt to solve #1 and #3:
def getTotal(dict1):
#for solving #1
for key,val in dict1.iteritems():
val = dict1[key]
if isinstance(val, dict):
for k1 in val:
if k1=='total':
total=val[k1]
print total #gives output 5
#for solving #3
if isinstance(val,list):
print len(val[0]['comment']['nested_comment']) #gives output 2
#How can i get this dynamicallty?
Output:
total=5
2
Que 1 :What is a pythonic way to get the total number of dictionaries under "nested_comment" list ?
Que 2 :How can i get total count of type where type="ABC". (Note: type is a nested key under "outer_key2")
Que 1 :What is a pythonic way to get the total number of dictionaries under "nested_comment" list ?
User Counter from the standard library.
from collections import Counter
my_list = [{'hello': 'world'}, {'foo': 'bar'}, 1, 2, 'hello']
dict_count = Counter([x for x in my_list if type(x) is dict])
Que 2 :How can i get total count of type where type="ABC". (Note: type is a nested key under "outer_key2")
It's not clear what you're asking for here. If by "total count", you are referring to the total number of comments in all dicts where "type" equals "ABC":
abcs = [x for x in dict1['outer_key2'] if x['type'] == 'ABC']
comment_count = sum([len(x['comments']['nested_comment']) for x in abcs])
But I've gotta say, that is some weird data you're dealing with.
You got answers for #1 and #3, check this too
from collections import Counter
dict1={
"outer_key1" : {
"total" : 5 #1.I want the value of "total"
},
"outer_key2" :
[{
"type": "ABC", #2. I want to count whole structure where type="ABC"
"comments": {
"nested_comment":[
{
"key":"value",
"key": "value"
},
{
"key":"value",
"id": 2
}
] # 3. Count Dict inside this list.
}}]}
print "total: ",dict1['outer_key1']['total']
print "No of nested comments: ", len(dict1['outer_key2'][0]['comments'] ['nested_comment']),
Assuming that below is the data structure for outer_key2 this is how you get total number of comments of type='ABC'
dict2={
"outer_key1" : {
"total" : 5
},
"outer_key2" :
[{
"type": "ABC",
"comments": {'...'}
},
{
"type": "ABC",
"comments": {'...'}
},
{
"type": "ABC",
"comments": {'...'}
}]}
i=0
k=0
while k < len(dict2['outer_key2']):
#print k
if dict2['outer_key2'][k]['type'] == 'ABC':
i+=int(1)
else:
pass
k+=1
print ("\r\nNo of dictionaries with type = 'ABC' : "), i

Get all keys from a list of dictionaries

If I have a dictionary containing a list, like this:
{"items": [{"name": "Orange", "cost": 5}, {"name": "Apple", "cost": 10}]}
Would it be possible to get the keys "name" and "cost" from both lists in some way?
It's just for the reason that I don't want to add another line every time I add something new to the dictionary in the same list.
I am assuming that, by getting the keys you meant the values associated with those keys.
a['items'] is a list. Just iterate through it and access the name and cost values as you would access any dictionary.
>>> a_dict = {"items": [{"name": "Orange", "cost": 5}, {"name": "Apple", "cost": 10}]}
>>> for a_d in a_dict['items']:
print 'Name: {} Cost: {}'.format(a_d['name'], a_d['cost'])
This gives:
Name: Orange Cost: 5
Name: Apple Cost: 10
If infact you wanted the key names of the dictionaries in the list a['items'] you can get them using .keys():
>>> for a_d in a_dict['items']:
print a_d.keys()
This gives:
['cost', 'name']
['cost', 'name']
The best way to avoid code duplication is to use a function.
def get_name_and_cost(d):
return d['name'], d['cost']
for d in lst['items']:
name, cost = get_name_and_cost(d)
print(name, cost)
If you have more than one group of 'items', this will go through each group in your dictionary.
d = {"fruit": [{"name": "Orange", "cost": 5}, {"name": "Apple", "cost": 10}],
"vegetables": [{"name": "carrot", "cost": 5}, {"name": "eggplant", "cost": 10}]}
for group, items in d.items():
for item in items:
print item['name']
>>>
carrot
eggplant
Orange
Apple
I think a more dynamic, reusable approach would be to make a function.
def get_values(d, *keys):
t = []
for k in keys:
if k in d.keys():
t.append(d[k])
else:
t.append(None)
return t
or
def get_values(d, *keys):
return [ d[k] if k in d.keys() else none for k in keys]
then you can do stuff like this!
>>> d = {"items": [{"name": "Orange", "cost": 5}, {"name": "Apple", "cost": 10}]}
>>> for item in d["items"]:
... print "Name {}, Cost {}".format(*get_values(item, "name", "cost"))
...
Name Orange, Cost 5
Name Apple, Cost 10

Categories

Resources