Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial![](https://ecs-static.teamtreehouse.com/assets/views/marketing/shared/community-banner-white-47072046c51352fe6a69f5e691ff5700b28bb11d45197d7bdf066d9ea3f72d0c.webp)
![Miguel de Luis Espinosa](https://secure.gravatar.com/avatar/8de13e44d51d77191761bdeb5f5c9524?s=96&d=https%3A%2F%2Fecs-static.teamtreehouse.com%2Fassets%2Fcontent%2Fdefault_avatar-445fbbabfc8dc9188fb5967fe43322ee0c3e0dd1e10f378bf8343784af5a13eb.webp&r=pg)
Miguel de Luis Espinosa
41,279 PointsChurch Account Project: Asking for Comments
Hi Kenneth Love
Just wanted to share what I'm working in. I'm, for my many sins, the treasurer of a small church and I thought of making a python app to gather the accounts and do the maths so it can be presented to the council, and so on.
The thing is that an excell sheet is a pain to work with, and dedicated apps are often an overkill for our needs, so I'm writing my own app. Right now, I have something that is barely functional. I mean, it kinda works, but I'm sure I will have to do a few iterations of refactoring.
First Attempt, has issues, see below
# This bit adds a new entry into the Church Accounts Book (a csv file)
import os
import csv
entries = []
def choose_a_category(categories): # A helper function
for key in sorted(categories):
print("Enter {} for {}".format(key,categories[key]))
menu = input("\n Choose a category:\t")
try:
return categories[menu]
except KeyError:
print("Try again")
choose_a_category(categories)
def add_entry(): # Main function
goOn = True # seguir = "go on in Spanish"
entries = []
while goOn:
entry = ["","","","","",""] # Entry - In/Out Date Amount Category Source/Payee Notes
in_categories = {"1":"Collections","2":"Donations","3":"Events"}
out_categories = {"1":"Stipend","2":"Electricity Church"}
# In/Out
InOut = "X"
while InOut != "i" and InOut != "o":
InOut = input("\n In or Out: i for In, o for Out \t").lower()
if InOut == "i":
entry[0] = "In"
else:
entry[0] = "Out"
if entry[0] == "In": #In
categories = in_categories
payee_or_source_enter_text = "Source"
else: #Out
categories = out_categories
payee_or_source_enter_text = "Payed by"
#Date
entry[1] = input("\n Date in dd/mm: \t")
#Amount
entry[2] = input("\n Amount, no + or - \t")
# Category
entry[3] = choose_a_category(categories)
# Subject
entry[4] = input("\n {}: \n".format(payee_or_source_enter_text))
# Notes
entry[5] = input("\n Write a note if needed: \n")
# Append entry to entries
entries.append(entry)
goOnText = input("\n Another entry? (n for no)\t").lower()
if goOnText == "n":
goOn = False
# add entries to file
with open('ca.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerows(entries)
return entries
add_entry()
# this bit gathers totals and subtotals by category of income, expense and source
import os
import csv
def open_book():
with open('ca.csv', newline='') as f:
book = []
reader = csv.reader(f)
for row in reader:
book.append(row)
return book
def gather_categories(book):
category_list = []
for x in range(0,len(book)):
if book[x][3] not in category_list:
category_list.append(book[x][3])
return category_list
def gather_sources(book):
sources_list = []
for x in range(0,len(book)):
if book[x][4] not in sources_list:
sources_list.append(book[x][4])
return sources_list
def add_income_expense():
total_income = 0.00
total_expense =0.00
book = open_book()
for x in range(0,len(book)):
this_quantity = float(book[x][2])
if book[x][0]=='In':
total_income += this_quantity
else:
total_expense += this_quantity
total_income = round(total_income,2)
total_expense = round(total_expense,2)
print("Total Income: {} \t Total Expense {}".format((total_income),total_expense))
print("="*80)
def add_categories():
total_categories = []
book = open_book()
categories = gather_categories(book)
print("\n Categories")
print(" ==========")
for x in range(0,len(categories)):
total_categories.append(0)
for y in range(0,len(book)):
if book[y][3]==categories[x]:
total_categories[x] += float(book[y][2])
print("\n {}\t {}".format(categories[x],round(total_categories[x],2)))
print("-"*80)
def add_sources():
total_sources = [[0.0,0.0]]
book = open_book()
sources = gather_sources(book)
print("\n Sources")
print(" =======")
for x in range(0,len(sources)):
total_sources.append([0.0,0.0])
for y in range(0,len(book)):
if book[y][4]==sources[x]:
if book[y][0]=="In":
total_sources[x][0] += float(book[y][2])
else:
total_sources[x][1] += float(book[y][2])
total_sources[x][0] = round(total_sources[x][0],2)
total_sources[x][1] = round(total_sources[x][1],2)
subtotal = round(total_sources[x][0]-total_sources[x][1])
print("\n {}\tIn: {}\t Out: {} \t Total: {}".format(sources[x], total_sources[x][0],total_sources[x][1], subtotal) )
print("-"*80)
add_categories()
add_sources()
add_income_expense()
3 Answers
![Kenneth Love](https://uploads.teamtreehouse.com/production/profile-photos/710512/micro_TeacherShoot-Kenneth.jpg)
Kenneth Love
Treehouse Guest TeacherLooks like a pretty thorough app, Miguel de Luis Espinosa. If you have any specific questions, be sure to ping me.
![Miguel de Luis Espinosa](https://secure.gravatar.com/avatar/8de13e44d51d77191761bdeb5f5c9524?s=96&d=https%3A%2F%2Fecs-static.teamtreehouse.com%2Fassets%2Fcontent%2Fdefault_avatar-445fbbabfc8dc9188fb5967fe43322ee0c3e0dd1e10f378bf8343784af5a13eb.webp&r=pg)
Miguel de Luis Espinosa
41,279 PointsOK, I ran into problems. The most serious was that I was using floats for currency. Floats do not work at all for currency, as I got rounding errors just for adding 4 numbers. So go figure what mess I could have run into in the long run. It made remember Superman III.
you want Decimal type, available as a module
from decimal import Decimal
# and then replace float(your_saved_string_with_money) with
Decimal(your_saved_string_with_money) #notice capital D
![Miguel de Luis Espinosa](https://secure.gravatar.com/avatar/8de13e44d51d77191761bdeb5f5c9524?s=96&d=https%3A%2F%2Fecs-static.teamtreehouse.com%2Fassets%2Fcontent%2Fdefault_avatar-445fbbabfc8dc9188fb5967fe43322ee0c3e0dd1e10f378bf8343784af5a13eb.webp&r=pg)
Miguel de Luis Espinosa
41,279 Points# I use this bit to enter data on the console
import os
import csv
entries = []
def choose_a_category(categories):
# generates a menu and check if your category is within the menu
for key in sorted(categories):
print("Enter {} for {}".format(key,categories[key]))
menu = input("\n Choose a category:\t")
try:
return categories[menu]
except KeyError:
print("Try again")
choose_a_category(categories)
def add_entry():
# add an entry or entries to the account book
seguir = True
entries = []
while seguir:
entry = ["","","","","",""] # Entry - In/Out Date Amount Category Source/Payee Notes
in_categories = {"1":"Collections","2":"Events","3":"Interest","4":"Fees"}
out_categories = {"1":"Stipend","2":"Chaplain Accomodation",
"3":"Chaplain Expenses", "4":"Services & Administration",
"5":"Church Fabric", "6":"Diocesan Quotas", "7":"Charity", "8":"Exceptional"}
# In/Out
InOut = "X"
while InOut != "i" and InOut != "o":
InOut = input("\n In or Out: i for In, o for Out \t").lower()
if InOut == "i":
entry[0] = "In"
else:
entry[0] = "Out"
if entry[0] == "In": #In
categories = in_categories
payee_or_source_enter_text = "Source"
else: #Out
categories = out_categories
payee_or_source_enter_text = "Assigned to"
#Date
day = ""
month = ""
day = input("\n Day (dd): \t")
month = input("\n Month (mm): \t")
entry[1] = day + "/" + month
#Amount
entry[2] = input("\n Amount").strip('+- ')
# Category
entry[3] = choose_a_category(categories)
# Subject
entry[4] = input("\n {}: \n".format(payee_or_source_enter_text))
# Notes
entry[5] = input("\n Write a note if needed: \n")
# Append entry to entries
entries.append(entry)
seguimos = input("\n Another entry? (n for no)\t")
if seguimos.lower() == "n":
seguir = False
# append entries to file
with open('ca.csv', 'a', newline='') as f:
writer = csv.writer(f)
writer.writerows(entries)
return entries
add_entry()
# This bit does the maths
import os
import csv
from decimal import Decimal
opening_balance = round(Decimal(1.01),2) #1.01 is just a fake ammount
def open_book():
with open('ca.csv', newline='') as f:
book = []
reader = csv.reader(f)
for row in reader:
book.append(row)
return book
def gather_categories(book):
category_list = []
for x in range(0,len(book)):
if book[x][3] not in category_list:
category_list.append(book[x][3])
return category_list
def gather_sources(book):
sources_list = []
for x in range(0,len(book)):
if book[x][4] not in sources_list:
sources_list.append(book[x][4])
return sources_list
def add_income_expense():
total_income = Decimal(0)
total_expense = Decimal(0)
book = open_book()
for x in range(0,len(book)):
this_quantity = Decimal(book[x][2])
if book[x][0]=='In':
total_income += this_quantity
else:
total_expense += this_quantity
total_income = round(total_income,2)
total_expense = round(total_expense,2)
balance = total_income-total_expense
historic_balance = opening_balance + balance
print("\nTotal Income: {:8,} \tTotal Expense: {:8,}\t Balance: {:8,}".format(total_income,total_expense,balance))
print("\nOpening Balance: {:8,}\tHistoric Balance: {:8,}".format(opening_balance,historic_balance))
print("="*80)
def add_categories():
total_categories = []
book = open_book()
categories = gather_categories(book)
print("\n Categories")
print(" ==========")
for x in range(0,len(categories)):
total_categories.append(Decimal(0))
for y in range(0,len(book)):
if book[y][3]==categories[x]:
total_categories[x] += Decimal(book[y][2])
print("\n {:<20}\t {:^8,}".format(categories[x],total_categories[x]))
print("-"*80)
def add_sources():
total_sources = [[Decimal(0),Decimal(0)]]
book = open_book()
sources = gather_sources(book)
print("\n Sources")
print(" =======")
for x in range(0,len(sources)):
total_sources.append([Decimal(0),Decimal(0)])
for y in range(0,len(book)):
if book[y][4]==sources[x]:
if book[y][0]=="In":
total_sources[x][0] += Decimal(book[y][2])
else:
total_sources[x][1] += Decimal(book[y][2])
subtotal = total_sources[x][0]-total_sources[x][1]
print("\n {:<20} In: {:^8,} Out: {:^8,} Total: {:^8,}".format(sources[x], total_sources[x][0], total_sources[x][1], subtotal))
print("-"*80)
add_categories()
add_sources()
add_income_expense()