Skip to content

Instantly share code, notes, and snippets.

@koehlma
Last active August 29, 2015 14:05
Show Gist options
  • Save koehlma/f4d309ccbebe3eb105fe to your computer and use it in GitHub Desktop.
Save koehlma/f4d309ccbebe3eb105fe to your computer and use it in GitHub Desktop.
MoneyManager
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import argparse
import collections
import csv
import datetime
import os
import os.path
import subprocess
from decimal import Decimal
from pathlib import Path
GREEN = '\033[0;32m'
RED = '\033[0;31m'
NORMAL = '\033[0m'
color = lambda value: RED if value < 0 else GREEN
today = datetime.date.today()
default_month = today.month
default_year = today.year
default_directory = (os.environ.get('MONEYMGR_DIR') or
Path(os.path.expanduser('~/.moneymgr')))
Transaction = collections.namedtuple('Transaction', ['value', 'subject'])
size = subprocess.check_output(['stty', 'size']).decode('ascii').split()
height, width= map(int, size)
class Database():
def __init__(self, path):
self.path = path
self.transactions = []
if self.path.exists():
with self.path.open('r', encoding='utf-8') as csvfile:
for value, subject in csv.reader(csvfile):
transaction = Transaction(Decimal(value), subject)
self.transactions.append(transaction)
def __iter__(self):
return iter(self.transactions)
def add(self, value, subject):
self.transactions.append(Transaction(value, subject))
def remove(self, number):
del self.transactions[number - 1]
def pprint(self):
print(' | Value | Subject')
print('---+-------------+--------' + '-' * (width - 26))
for number, (value, subject) in enumerate(self.transactions, 1):
print(('{:>2} | {}{:>+10.2f}€{} | {}'
).format(number, color(value), value, NORMAL, subject))
print('---+=============+--------' + '-' * (width - 26))
total = sum(t.value for t in self.transactions)
print(' | {}{:>+10.2f}€{} |'.format(color(total), total, NORMAL))
def write(self):
with self.path.open('w', encoding='utf-8') as csvfile:
csv.writer(csvfile).writerows(self.transactions)
def get_path(year, month, directory=default_directory):
return directory / '{:0>4}-{:0>2}.csv'.format(year, month)
def cmd_list(database, arguments):
database.pprint()
def cmd_add(database, arguments):
if arguments.value.startswith('-') or arguments.value.startswith('+'):
value = arguments.value
else:
value = '-' + arguments.value
database.add(Decimal(value), arguments.subject)
database.write()
database.pprint()
def cmd_remove(database, arguments):
database.remove(arguments.number)
database.write()
database.pprint()
commands = {'list' : cmd_list, 'add': cmd_add, 'remove' : cmd_remove}
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-d', metavar='DIRECTORY', default=default_directory)
parser.add_argument('-y', metavar='YEAR', type=int, default=default_year)
parser.add_argument('-m', metavar='MONTH', type=int, default=default_month)
subparsers = parser.add_subparsers(dest='command')
parser_list = subparsers.add_parser('list')
parser_add = subparsers.add_parser('add')
parser_add.add_argument('value')
parser_add.add_argument('subject')
parser_remove = subparsers.add_parser('remove')
parser_remove.add_argument('number', type=int)
arguments = parser.parse_args()
command = arguments.command or 'list'
database = Database(get_path(arguments.y, arguments.m, arguments.d))
commands[command](database, arguments)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment