Sum of values in a multiple lists of a dict
Question:
I am new to python and have been trying to add values that I get from iterating over a list of dictionaries.
I keep running into ‘builtin_function_or_method’ object is not iterable’ error message or unsupported type. Any help would be much appreciated.
here is my code:
def inventory(acct_info, months_subscribed, add_free_months, video_on_demand):
print(acct_info)
for info in acct_info:
print('-')
if info.get('months_subscribed') == 3:
months_subscribed_total = info.get('months_subscribed') * 18
elif info.get('months_subscribed') < 3:
months_subscribed_total = info['months_subscribed'] * 7
elif info.get('months_subscribed') > 3:
months_subscribed_total = info['months_subscribed'] - 3 * 7 + 18
print(f"User {info.get('name')} has months subscribed total of : $ {months_subscribed_total} ")
if info['ad_free_months'] > 0:
ad_free_total = info.get('ad_free_months') * 2
print(f" User {info.get('name')} total ad free is : {ad_free_total} ")
if info['video_on_demand'] > 0:
video_on_demand_total = info.get('video_on_demand') * 27.99
print(f" User {info.get('name')} total video on demand is : {video_on_demand_total} ")
acct_all_total = int(months_subscribed_total + ad_free_total + video_on_demand_total)
acct_all_total = [int(acct_all_total)]
print(f"Total for {info.get('name')} is: {acct_all_total} ")
acct_info = [{'name': 'acct_1', 'months_subscribed' : 2 , 'ad_free_months' : 3 , 'video_on_demand' : 1} ,
{'name': 'acct_2', 'months_subscribed' : 1 , 'ad_free_months' : 2 , 'video_on_demand' : 2},
{'name': 'acct_3', 'months_subscribed' : 2 , 'ad_free_months' : 1 , 'video_on_demand' : 3}]
combined_total = 0
months_subscribed = 0
ad_free_months = 0
video_on_demand = 0
months_subscribed_total = 0
ad_free_total = 0
video_on_demand_total = 0
inventory(acct_info, months_subscribed, ad_free_months, video_on_demand)
acct_all_total = 0
main()
Output so far is :
User acct_1 has months subscribed total of : $ 14
User acct_1 total ad free is : 6
User acct_1 total video on demand is : 27.99
Total for acct_1 is: [47]
-
User acct_2 has months subscribed total of : $ 7
User acct_2 total ad free is : 4
User acct_2 total video on demand is : 55.98
Total for acct_2 is: [66]
-
User acct_3 has months subscribed total of : $ 14
User acct_3 total ad free is : 2
User acct_3 total video on demand is : 83.97
Total for acct_3 is: [99]
What i am trying to sum up is the total for all of the users. I manage to get a total for each user, but i then want add the totals of that. Thank you.
Answers:
I modified your inventory function, now it contains a list before the loop start and it holds all the totals of the users that you are printing at the bottom of the loop, at the end using the sum
function the grand total of all users can be calculated
def inventory(acct_info, months_subscribed, add_free_months, video_on_demand):
print(acct_info)
all_users_collection = []
for info in acct_info:
print('-')
if info.get('months_subscribed') == 3:
months_subscribed_total = info.get('months_subscribed') * 18
elif info.get('months_subscribed') < 3:
months_subscribed_total = info['months_subscribed'] * 7
elif info.get('months_subscribed') > 3:
months_subscribed_total = info['months_subscribed'] - 3 * 7 + 18
print(f"User {info.get('name')} has months subscribed total of : $ {months_subscribed_total} ")
if info['ad_free_months'] > 0:
ad_free_total = info.get('ad_free_months') * 2
print(f" User {info.get('name')} total ad free is : {ad_free_total} ")
if info['video_on_demand'] > 0:
video_on_demand_total = info.get('video_on_demand') * 27.99
print(f" User {info.get('name')} total video on demand is : {video_on_demand_total} ")
acct_all_total = int(months_subscribed_total + ad_free_total + video_on_demand_total)
acct_all_total = [int(acct_all_total)]
all_users_collection.append(int(acct_all_total))
print(f"Total for {info.get('name')} is: {acct_all_total} ")
acct_info = [{'name': 'acct_1', 'months_subscribed' : 2 , 'ad_free_months' : 3 , 'video_on_demand' : 1} ,
{'name': 'acct_2', 'months_subscribed' : 1 , 'ad_free_months' : 2 , 'video_on_demand' : 2},
{'name': 'acct_3', 'months_subscribed' : 2 , 'ad_free_months' : 1 , 'video_on_demand' : 3}]
combined_total = 0
months_subscribed = 0
ad_free_months = 0
video_on_demand = 0
months_subscribed_total = 0
ad_free_total = 0
video_on_demand_total = 0
inventory(acct_info, months_subscribed, ad_free_months, video_on_demand)
acct_all_total = 0
print('Total for all users is', sum(all_users_collection))
The other approach can be to use a single variable and increment for every total of a user at the end you will get total of all users
You can take into consideration modifying your code a little bit your code.
I would move out the for loop
from your function to make it do just one thing: do the inventory for a given account.
The following code is just an example, but it provides an alternative solution for your question.
def inventory(info, months_subscribed, add_free_months, video_on_demand):
acct_all_total = 0 # here you init the total value to 0
if info.get('months_subscribed') == 3:
months_subscribed_total = info.get('months_subscribed') * 18
elif info.get('months_subscribed') < 3:
months_subscribed_total = info['months_subscribed'] * 7
elif info.get('months_subscribed') > 3:
months_subscribed_total = info['months_subscribed'] - 3 * 7 + 18
print(f"User {info.get('name')} has months subscribed total of : $ {months_subscribed_total} ")
if info['ad_free_months'] > 0:
ad_free_total = info.get('ad_free_months') * 2
print(f" User {info.get('name')} total ad free is : {ad_free_total} ")
if info['video_on_demand'] > 0:
video_on_demand_total = info.get('video_on_demand') * 27.99
print(f" User {info.get('name')} total video on demand is : {video_on_demand_total} ")
acct_all_total = int(months_subscribed_total + ad_free_total + video_on_demand_total)
# acct_all_total = [int(acct_all_total)]
print(f"Total for {info.get('name')} is: {acct_all_total} ")
return acct_all_total
Please note I also commented the # acct_all_total = [int(acct_all_total)]
Then you can call it
acct_info = [{'name': 'acct_1', 'months_subscribed': 2, 'ad_free_months': 3, 'video_on_demand': 1},
{'name': 'acct_2', 'months_subscribed': 1, 'ad_free_months': 2, 'video_on_demand': 2},
{'name': 'acct_3', 'months_subscribed': 2, 'ad_free_months': 1, 'video_on_demand': 3}]
combined_total = 0
months_subscribed = 0
ad_free_months = 0
video_on_demand = 0
months_subscribed_total = 0
ad_free_total = 0
video_on_demand_total = 0
acct_all_total = 0
for acct in acct_info:
acct_all_total+=inventory(acct, months_subscribed, ad_free_months, video_on_demand)
print("Tot:",acct_all_total)
Output:
User acct_1 has months subscribed total of : $ 14
User acct_1 total ad free is : 6
User acct_1 total video on demand is : 27.99
Total for acct_1 is: 47
User acct_2 has months subscribed total of : $ 7
User acct_2 total ad free is : 4
User acct_2 total video on demand is : 55.98
Total for acct_2 is: 66
User acct_3 has months subscribed total of : $ 14
User acct_3 total ad free is : 2
User acct_3 total video on demand is : 83.97
Total for acct_3 is: 99
Tot: 212
Edited to reflect comments.
If you want to get the largest of your total, you have to change the code a bit. Consider to use the built-in function max()
https://docs.python.org/3.8/library/functions.html#max and sum()
https://docs.python.org/3.8/library/functions.html#sum.
max()
returns the largest item in an iterable or the largest of two or more arguments. sum()
sums all the element in an iterable. So, let’s use an iterable in our code
tot = list()
for acct in acct_info:
# here, we gonna append each total
tot.append(inventory(acct, months_subscribed, ad_free_months, video_on_demand))
print("all the values:",tot)
print("the largest is:",max(tot)) # here we extract the largest item of the list
print("Total:",sum(tot)) # here we sum all the element of the list tot
Output:
all the values: [47, 66, 99]
the largest is: 99
Total: 212
I am new to python and have been trying to add values that I get from iterating over a list of dictionaries.
I keep running into ‘builtin_function_or_method’ object is not iterable’ error message or unsupported type. Any help would be much appreciated.
here is my code:
def inventory(acct_info, months_subscribed, add_free_months, video_on_demand):
print(acct_info)
for info in acct_info:
print('-')
if info.get('months_subscribed') == 3:
months_subscribed_total = info.get('months_subscribed') * 18
elif info.get('months_subscribed') < 3:
months_subscribed_total = info['months_subscribed'] * 7
elif info.get('months_subscribed') > 3:
months_subscribed_total = info['months_subscribed'] - 3 * 7 + 18
print(f"User {info.get('name')} has months subscribed total of : $ {months_subscribed_total} ")
if info['ad_free_months'] > 0:
ad_free_total = info.get('ad_free_months') * 2
print(f" User {info.get('name')} total ad free is : {ad_free_total} ")
if info['video_on_demand'] > 0:
video_on_demand_total = info.get('video_on_demand') * 27.99
print(f" User {info.get('name')} total video on demand is : {video_on_demand_total} ")
acct_all_total = int(months_subscribed_total + ad_free_total + video_on_demand_total)
acct_all_total = [int(acct_all_total)]
print(f"Total for {info.get('name')} is: {acct_all_total} ")
acct_info = [{'name': 'acct_1', 'months_subscribed' : 2 , 'ad_free_months' : 3 , 'video_on_demand' : 1} ,
{'name': 'acct_2', 'months_subscribed' : 1 , 'ad_free_months' : 2 , 'video_on_demand' : 2},
{'name': 'acct_3', 'months_subscribed' : 2 , 'ad_free_months' : 1 , 'video_on_demand' : 3}]
combined_total = 0
months_subscribed = 0
ad_free_months = 0
video_on_demand = 0
months_subscribed_total = 0
ad_free_total = 0
video_on_demand_total = 0
inventory(acct_info, months_subscribed, ad_free_months, video_on_demand)
acct_all_total = 0
main()
Output so far is :
User acct_1 has months subscribed total of : $ 14
User acct_1 total ad free is : 6
User acct_1 total video on demand is : 27.99
Total for acct_1 is: [47]
-
User acct_2 has months subscribed total of : $ 7
User acct_2 total ad free is : 4
User acct_2 total video on demand is : 55.98
Total for acct_2 is: [66]
-
User acct_3 has months subscribed total of : $ 14
User acct_3 total ad free is : 2
User acct_3 total video on demand is : 83.97
Total for acct_3 is: [99]
What i am trying to sum up is the total for all of the users. I manage to get a total for each user, but i then want add the totals of that. Thank you.
I modified your inventory function, now it contains a list before the loop start and it holds all the totals of the users that you are printing at the bottom of the loop, at the end using the sum
function the grand total of all users can be calculated
def inventory(acct_info, months_subscribed, add_free_months, video_on_demand):
print(acct_info)
all_users_collection = []
for info in acct_info:
print('-')
if info.get('months_subscribed') == 3:
months_subscribed_total = info.get('months_subscribed') * 18
elif info.get('months_subscribed') < 3:
months_subscribed_total = info['months_subscribed'] * 7
elif info.get('months_subscribed') > 3:
months_subscribed_total = info['months_subscribed'] - 3 * 7 + 18
print(f"User {info.get('name')} has months subscribed total of : $ {months_subscribed_total} ")
if info['ad_free_months'] > 0:
ad_free_total = info.get('ad_free_months') * 2
print(f" User {info.get('name')} total ad free is : {ad_free_total} ")
if info['video_on_demand'] > 0:
video_on_demand_total = info.get('video_on_demand') * 27.99
print(f" User {info.get('name')} total video on demand is : {video_on_demand_total} ")
acct_all_total = int(months_subscribed_total + ad_free_total + video_on_demand_total)
acct_all_total = [int(acct_all_total)]
all_users_collection.append(int(acct_all_total))
print(f"Total for {info.get('name')} is: {acct_all_total} ")
acct_info = [{'name': 'acct_1', 'months_subscribed' : 2 , 'ad_free_months' : 3 , 'video_on_demand' : 1} ,
{'name': 'acct_2', 'months_subscribed' : 1 , 'ad_free_months' : 2 , 'video_on_demand' : 2},
{'name': 'acct_3', 'months_subscribed' : 2 , 'ad_free_months' : 1 , 'video_on_demand' : 3}]
combined_total = 0
months_subscribed = 0
ad_free_months = 0
video_on_demand = 0
months_subscribed_total = 0
ad_free_total = 0
video_on_demand_total = 0
inventory(acct_info, months_subscribed, ad_free_months, video_on_demand)
acct_all_total = 0
print('Total for all users is', sum(all_users_collection))
The other approach can be to use a single variable and increment for every total of a user at the end you will get total of all users
You can take into consideration modifying your code a little bit your code.
I would move out the for loop
from your function to make it do just one thing: do the inventory for a given account.
The following code is just an example, but it provides an alternative solution for your question.
def inventory(info, months_subscribed, add_free_months, video_on_demand):
acct_all_total = 0 # here you init the total value to 0
if info.get('months_subscribed') == 3:
months_subscribed_total = info.get('months_subscribed') * 18
elif info.get('months_subscribed') < 3:
months_subscribed_total = info['months_subscribed'] * 7
elif info.get('months_subscribed') > 3:
months_subscribed_total = info['months_subscribed'] - 3 * 7 + 18
print(f"User {info.get('name')} has months subscribed total of : $ {months_subscribed_total} ")
if info['ad_free_months'] > 0:
ad_free_total = info.get('ad_free_months') * 2
print(f" User {info.get('name')} total ad free is : {ad_free_total} ")
if info['video_on_demand'] > 0:
video_on_demand_total = info.get('video_on_demand') * 27.99
print(f" User {info.get('name')} total video on demand is : {video_on_demand_total} ")
acct_all_total = int(months_subscribed_total + ad_free_total + video_on_demand_total)
# acct_all_total = [int(acct_all_total)]
print(f"Total for {info.get('name')} is: {acct_all_total} ")
return acct_all_total
Please note I also commented the # acct_all_total = [int(acct_all_total)]
Then you can call it
acct_info = [{'name': 'acct_1', 'months_subscribed': 2, 'ad_free_months': 3, 'video_on_demand': 1},
{'name': 'acct_2', 'months_subscribed': 1, 'ad_free_months': 2, 'video_on_demand': 2},
{'name': 'acct_3', 'months_subscribed': 2, 'ad_free_months': 1, 'video_on_demand': 3}]
combined_total = 0
months_subscribed = 0
ad_free_months = 0
video_on_demand = 0
months_subscribed_total = 0
ad_free_total = 0
video_on_demand_total = 0
acct_all_total = 0
for acct in acct_info:
acct_all_total+=inventory(acct, months_subscribed, ad_free_months, video_on_demand)
print("Tot:",acct_all_total)
Output:
User acct_1 has months subscribed total of : $ 14
User acct_1 total ad free is : 6
User acct_1 total video on demand is : 27.99
Total for acct_1 is: 47
User acct_2 has months subscribed total of : $ 7
User acct_2 total ad free is : 4
User acct_2 total video on demand is : 55.98
Total for acct_2 is: 66
User acct_3 has months subscribed total of : $ 14
User acct_3 total ad free is : 2
User acct_3 total video on demand is : 83.97
Total for acct_3 is: 99
Tot: 212
Edited to reflect comments.
If you want to get the largest of your total, you have to change the code a bit. Consider to use the built-in function max()
https://docs.python.org/3.8/library/functions.html#max and sum()
https://docs.python.org/3.8/library/functions.html#sum.
max()
returns the largest item in an iterable or the largest of two or more arguments. sum()
sums all the element in an iterable. So, let’s use an iterable in our code
tot = list()
for acct in acct_info:
# here, we gonna append each total
tot.append(inventory(acct, months_subscribed, ad_free_months, video_on_demand))
print("all the values:",tot)
print("the largest is:",max(tot)) # here we extract the largest item of the list
print("Total:",sum(tot)) # here we sum all the element of the list tot
Output:
all the values: [47, 66, 99]
the largest is: 99
Total: 212