Update: Apparently, I noticed that in my main code, when I extract the values from the list of dictionaries that I get from readExpenses.py, I store it as a set, not as a list of dictionaries.
Now, I know that I store each dictionary in the 'exp' list with these lines of code:
for e in expenses:
exp.append(e)
However, I only want the Keys Amount, and Type from those dictionaries, and not the other entries.
For reference, here is the list of keys in an expense dictionary:
"Date","Description","Type","Check Number","Amount","Balance"
As mentioned before, I only need Type and Amount.
I am trying to make a budget program, So I have this list of dictionaries:
[{'Bills': 30.0}, {'Bills': 101.53}, {'Bills': 60.0}, {'Bills': 52.45}, {'Gas': 51.17}, {500.0: 'Mortgage'}, {'Food': 5.1}]
And I'm trying to compare it to this list of dictionaries:
[{400.0: 'Bills'}, {'Gas': 100.0}, {500.0: 'Mortgage'}, {'Food': 45.0}]
The first list is how much money I spent on different services in a given month, and what category it was in, and the second dictionary is the max amount that the budget allows me to spend on said category.
The goal is, in the first dictionary, to combine all the values of the same key into one key:value pair, then compare it to the second dictionary.
So I should get this list of dictionaries out of the first one:
[{'Bills': 295.15), {'Gas': 51.17}, {500.0: 'Mortgage'}, {'Food': 5.1}]
I tried looking at this example and this one, but they are just about merging the dictionaries lists together, and not summing the values of the same key. I did try the code in the latter, but it only joined the dictionaries together. I noticed that sum only seems to work with "raw" dictionaries, and not with lists of dictionaries.
I did try this as a thought experiment:
print(sum(item['amount'] for item in exp))
I know that would sum up all the numbers under amount, rather than return a number for each category, but I wanted to try out it for the heck of it, to see if it would lead to a solution, but I got this error in return:
TypeError: 'set' object is not subscriptable
The Counter function seemed to show promise as a solution as well when I was messing around, however, it seems to only work with dictionaries that are on their own, and not with list of dictionaries.
#where exp is the first dictionary that I mentioned
a = Counter(exp)
b = Counter(exp)
c = a + b #I'm aware the math would have be faulty on this, but this was a test run
print (c)
This attempt returned this error:
TypeError: unhashable type: 'set'
Also, is there a way to do it without importing the collections module and using what comes with python as well?
My code:
from readExpense import *
from budget import *
from collections import *
#Returns the expenses by expenses type
def expensesByType(expenses, budget):
exp = []
expByType = []
bud = []
for e in expenses:
entry = {e['exptype'], e['amount']}
exp.append(entry)
for b in budget:
entry = {b['exptype'], b['maxamnt']}
bud.append(entry)
return expByType;
def Main():
budget = readBudget("budget.txt")
#printBudget(budget)
expenses = readExpenses("expenses.txt")
#printExpenses(expenses)
expByType = expensesByType(expenses, budget)
if __name__ == '__main__':
Main()
And for reference, the code from budget and readexpense respectively.
budget.py
def readBudget(budgetFile):
# Read the file into list lines
f = open(budgetFile)
lines = f.readlines()
f.close()
budget = []
# Parse the lines
for i in range(len(lines)):
list = lines[i].split(",")
exptype = list[0].strip('" \n')
if exptype == "Type":
continue
maxamount = list[1].strip('$" \n\r')
entry = {'exptype':exptype, 'maxamnt':float(maxamount)}
budget.append(entry)
return budget
def printBudget(budget):
print()
print("================= BUDGET ==================")
print("Type".ljust(12), "Max Amount".ljust(12))
total = 0
for b in budget:
print(b['exptype'].ljust(12), str("$%0.2f" %b['maxamnt']).ljust(50))
total = total + b['maxamnt']
print("Total: ", "$%0.2f" % total)
def Main():
budget = readBudget("budget.txt")
printBudget(budget)
if __name__ == '__main__':
Main()
readExpense.py
def readExpenses(file):
#read file into list of lines
#split lines into fields
# for each list create a dictionary
# add dictionary to expense list
#return expenses in a list of dictionary with fields
# date desc, exptype checknm, amnt
f = open(file)
lines=f.readlines()
f.close()
expenses = []
for i in range(len(lines)):
list = lines[i].split(",")
date = list[0].strip('" \n')
if date == "Date":
continue
description = list[1].strip('" \n\r')
exptype= list[2].strip('" \n\r')
checkNum = list[3].strip('" \n\r')
amount = list[4].strip('($)" \n\r')
balance = list[5].strip('" \n\r')
entry ={'date':date, 'description': description, 'exptype':exptype, 'checkNum':checkNum, 'amount':float(amount), 'balance': balance}
expenses.append(entry)
return expenses
def printExpenses(expenses):
#print expenses
print()
print("================= Expenses ==================")
print("Date".ljust(12), "Description".ljust(12), "Type".ljust(12),"Check Number".ljust(12), "Amount".ljust(12), "Balance".ljust(12))
total = 0
for e in expenses:
print(str(e['date']).ljust(12), str(e['description']).ljust(12), str(e['exptype']).ljust(12), str(e['checkNum']).ljust(12), str(e['amount']).ljust(12))
total = total + e['amount']
print()
print("Total: ", "$%0.2f" % total)
def Main():
expenses = readExpenses("expenses.txt")
printExpenses(expenses)
if __name__ == '__main__':
Main()