diff --git a/statistikk.py b/statistikk.py new file mode 100755 index 0000000..61f18dc --- /dev/null +++ b/statistikk.py @@ -0,0 +1,197 @@ +#! /usr/bin/env python +# -*- coding: UTF-8 -*- +import matplotlib.pyplot as plt +from statistikkHelpers import * +import matplotlib.dates as mdates + +def getInputType(): + inp = 0 + while not (inp == '1' or inp == '2' or inp == '3' or inp == '4'): + print 'type 1 for user-statistics' + print 'type 2 for product-statistics' + print 'type 3 for global-statistics' + print 'type 4 to enter loop-mode' + inp = raw_input('') + return int(inp) + +def getDateFile(date, n): + try: + if n==0: + inp = raw_input('start date? (yyyy-mm-dd) ') + elif n==-1: + inp = raw_input('end date? (yyyy-mm-dd) ') + year = inp.partition('-') + month = year[2].partition('-') + return datetime.date(int(year[0]), int(month[0]), int(month[2])) + except: + print 'invalid date, setting start start date' + if n==0: + print 'to date found on first line' + elif n==-1: + print 'to date found on last line' + print date + return datetime.date(int(date.partition('-')[0]), int(date.partition('-')[2].partition('-')[0]), int(date.partition('-')[2].partition('-')[2])) + +def dateToDateNumFile(date, startDate): + year = date.partition('-') + month = year[2].partition('-') + day = datetime.date(int(year[0]), int(month[0]), int(month[2])) + deltaDays = day-startDate + return int(deltaDays.days), day.weekday() + +def getProducts(products): + product = [] + products = products.partition('¤') + product.append(products[0]) + while (products[1]=='¤'): + products = products[2].partition('¤') + product.append(products[0]) + return product + + +def piePlot(dictionary, n): + keys = [] + values = [] + i=0 + for key in sorted(dictionary, key=dictionary.get, reverse=True): + values.append(dictionary[key]) + if i10: + continue + for u in user: + print i, u.name + i += 1 + try: + n = int(raw_input ('enter number:')) + except: + print 'invalid input, restarting' + continue + if (n>-1) and (n10: + continue + for u in product: + print i, u.name + i += 1 + try: + n = int(raw_input ('enter number:')) + except: + print 'invalid input, restarting' + continue + if (n>-1) and (narray + vareUkedagAntall = defaultdict(list) + #for personer + personVareAntall = defaultdict(dict) #personVareAntall[trygvrad][Oreo] == 3 + personVareVerdi = defaultdict(dict) #personVareVerdi[trygvrad][Oreo] == 30 #[kr] + personDatoVerdi = defaultdict(list) #dict->array + personUkedagVerdi = defaultdict(list) + #for global + personPosTransactions = {} # personPosTransactions[trygvrad] == 100 #trygvrad har lagt 100kr i boksen + personNegTransactions = {} # personNegTransactions[trygvrad» == 70 #trygvrad har tatt 70kr fra boksen + globalVareAntall = {}#globalVareAntall[Oreo] == 3 + globalVareVerdi = {}#globalVareVerdi[Oreo] == 30 #[kr] + globalPersonAntall = {}#globalPersonAntall[trygvrad] == 3 + globalPersonForbruk = {}#globalPersonVerdi == 30 #[kr] + globalUkedagForbruk = [] + globalDatoVarer = [] + globalDatoForbruk = [] + pengebeholdning = [] + +class InputLine: + def __init__(self, u, p, t): + self.inputUser = u + self.inputProduct = p + self.inputType = t + +def getDateDb(date, inp): + try: + year = inp.partition('-') + month = year[2].partition('-') + return datetime.datetime(int(year[0]), int(month[0]), int(month[2])) + except: + print 'invalid date, setting date to date found in db' + print date + return date + +def dateToDateNumDb(date, startDate): + deltaDays = date-startDate + return int(deltaDays.days), date.weekday() + +def getInputType(): + inp = 0 + while not (inp == '1' or inp == '2' or inp == '3' or inp == '4'): + print 'type 1 for user-statistics' + print 'type 2 for product-statistics' + print 'type 3 for global-statistics' + print 'type 4 to enter loop-mode' + inp = raw_input('') + return int(inp) + +def getProducts(products): + product = [] + products = products.partition('¤') + product.append(products[0]) + while (products[1]=='¤'): + products = products[2].partition('¤') + product.append(products[0]) + return product + +def getDateFile(date, inp): + try: + year = inp.partition('-') + month = year[2].partition('-') + return datetime.date(int(year[0]), int(month[0]), int(month[2])) + except: + print 'invalid date, setting date to date found on file file' + print date + return datetime.date(int(date.partition('-')[0]), int(date.partition('-')[2].partition('-')[0]), int(date.partition('-')[2].partition('-')[2])) + +def dateToDateNumFile(date, startDate): + year = date.partition('-') + month = year[2].partition('-') + day = datetime.date(int(year[0]), int(month[0]), int(month[2])) + deltaDays = day-startDate + return int(deltaDays.days), day.weekday() + +def clearDatabase(database): + database.varePersonAntall.clear() + database.vareDatoAntall.clear() + database.vareUkedagAntall.clear() + database.personVareAntall.clear() + database.personVareVerdi.clear() + database.personDatoVerdi.clear() + database.personUkedagVerdi.clear() + database.personPosTransactions.clear() + database.personNegTransactions.clear() + database.globalVareAntall.clear() + database.globalVareVerdi.clear() + database.globalPersonAntall.clear() + database.globalPersonForbruk.clear() + return(database) + +def addLineToDatabase(database, inputLine): + if abs(inputLine.price)>90000: + return database + #fyller inn for varer + if (not inputLine.product=='') and ((inputLine.inputProduct=='') or (inputLine.inputProduct==inputLine.product)): + database.varePersonAntall[inputLine.product][inputLine.user] = database.varePersonAntall[inputLine.product].setdefault(inputLine.user,0) + 1 + if inputLine.product not in database.vareDatoAntall: + database.vareDatoAntall[inputLine.product] = [0]*(inputLine.numberOfDays+1) + database.vareDatoAntall[inputLine.product][inputLine.dateNum] += 1 + if inputLine.product not in database.vareUkedagAntall: + database.vareUkedagAntall[inputLine.product] = [0]*7 + database.vareUkedagAntall[inputLine.product][inputLine.weekday] += 1 + #fyller inn for personer + if (inputLine.inputUser=='') or (inputLine.inputUser==inputLine.user): + if not inputLine.product == '': + database.personVareAntall[inputLine.user][inputLine.product] = database.personVareAntall[inputLine.user].setdefault(inputLine.product,0) + 1 + database.personVareVerdi[inputLine.user][inputLine.product] = database.personVareVerdi[inputLine.user].setdefault(inputLine.product,0) + inputLine.price + if inputLine.user not in database.personDatoVerdi: + database.personDatoVerdi[inputLine.user] = [0]*(inputLine.numberOfDays+1) + database.personDatoVerdi[inputLine.user][inputLine.dateNum] += inputLine.price + if inputLine.user not in database.personUkedagVerdi: + database.personUkedagVerdi[inputLine.user] = [0]*7 + database.personUkedagVerdi[inputLine.user][inputLine.weekday] += inputLine.price + #fyller inn delt statistikk (genereres uansett) + if (inputLine.product==''): + if (inputLine.price>0): + database.personPosTransactions[inputLine.user] = database.personPosTransactions.setdefault(inputLine.user,0) + inputLine.price + else: + database.personNegTransactions[inputLine.user] = database.personNegTransactions.setdefault(inputLine.user,0) + inputLine.price + elif not (inputLine.inputType==1): + database.globalVareAntall[inputLine.product] = database.globalVareAntall.setdefault(inputLine.product,0) + 1 + database.globalVareVerdi[inputLine.product] = database.globalVareVerdi.setdefault(inputLine.product,0) + inputLine.price + + #fyller inn for global statistikk + if (inputLine.inputType==3) or (inputLine.inputType==4): + database.pengebeholdning[inputLine.dateNum] += inputLine.price + if not (inputLine.product==''): + database.globalPersonAntall[inputLine.user] = database.globalPersonAntall.setdefault(inputLine.user,0) + 1 + database.globalPersonForbruk[inputLine.user] = database.globalPersonForbruk.setdefault(inputLine.user,0) + inputLine.price + database.globalDatoVarer[inputLine.dateNum] += 1 + database.globalDatoForbruk[inputLine.dateNum] += inputLine.price + database.globalUkedagForbruk[inputLine.weekday] += inputLine.price + return database + +def buildDatabaseFromDb(inputType, inputProduct, inputUser): + sdate = raw_input('enter start date (yyyy-mm-dd)? ') + edate = raw_input('enter end date (yyyy-mm-dd)? ') + print 'building database...' + session = Session() + transaction_list = session.query(Transaction).all() + inputLine = InputLine(inputUser, inputProduct, inputType) + startDate = getDateDb(transaction_list[0].time, sdate) + endDate = getDateDb(transaction_list[-1].time, edate) + inputLine.numberOfDays = (endDate-startDate).days + database = Database() + database = clearDatabase(database) + + if (inputType==3) or (inputType==4): + database.globalDatoVarer = [0]*(inputLine.numberOfDays+1) + database.globalDatoForbruk = [0]*(inputLine.numberOfDays+1) + database.globalUkedagForbruk = [0]*7 + database.pengebeholdning = [0]*(inputLine.numberOfDays+1) + print 'wait for it.... ' + for transaction in transaction_list: + if transaction.purchase: + products = map(lambda ent: ent.product.name, transaction.purchase.entries) + else: + products = [] + products.append('') + inputLine.dateNum, inputLine.weekday = dateToDateNumDb(transaction.time, startDate) + if inputLine.dateNum<0 or inputLine.dateNum>(inputLine.numberOfDays): + continue + inputLine.user=transaction.user.name + inputLine.price=transaction.amount + for inputLine.product in products: + database=addLineToDatabase(database, inputLine ) + inputLine.price = 0; + + print 'saving as default.dibblerlog...', + f=open('default.dibblerlog','w') + line_format = '%s|%s|%s|%s|%s|%s\n' + transaction_list = session.query(Transaction).all() + for transaction in transaction_list: + if transaction.purchase: + products = u'¤'.join(map(lambda ent: ent.product.name, transaction.purchase.entries)) + description = '' + else: + products = '' + description = transaction.description + line = line_format % ('purchase', transaction.time, products, transaction.user.name, transaction.amount, transaction.description) + f.write(line.encode('utf8')) + session.close() + f.close + #bygg database.pengebeholdning + if (inputType==3) or (inputType==4): + for i in range(inputLine.numberOfDays+1): + if i > 0: + database.pengebeholdning[i] +=database.pengebeholdning[i-1] + #bygg dateLine + day=datetime.timedelta(days=1) + dateLine=[] + dateLine.append(startDate) + for n in range(inputLine.numberOfDays): + dateLine.append(startDate+n*day) + print 'done' + return database, dateLine + +def buildDatabaseFromFile(inputFile, inputType, inputProduct, inputUser): + sdate = raw_input('enter start date (yyyy-mm-dd)? ') + edate = raw_input('enter end date (yyyy-mm-dd)? ') + + f=open(inputFile) + try: + fileLines=f.readlines() + finally: + f.close() + inputLine = InputLine(inputUser, inputProduct, inputType) + startDate = getDateFile(fileLines[0].partition('|')[2].partition(' ')[0], sdate) + endDate = getDateFile(fileLines[-1].partition('|')[2].partition(' ')[0], edate) + inputLine.numberOfDays = (endDate-startDate).days + database = Database() + database = clearDatabase(database) + + if (inputType==3) or (inputType==4): + database.globalDatoVarer = [0]*(inputLine.numberOfDays+1) + database.globalDatoForbruk = [0]*(inputLine.numberOfDays+1) + database.globalUkedagForbruk = [0]*7 + database.pengebeholdning = [0]*(inputLine.numberOfDays+1) + for linje in fileLines: + if not (linje[0]=='#') and not (linje=='\n') : + #henter dateNum, products, user, price + restDel = linje.partition('|') + restDel = restDel[2].partition(' ') + inputLine.dateNum, inputLine.weekday = dateToDateNumFile(restDel[0], startDate) + if inputLine.dateNum<0 or inputLine.dateNum>(inputLine.numberOfDays): + continue + restDel=restDel[2].partition('|') + restDel=restDel[2].partition('|') + products = restDel[0] + restDel=restDel[2].partition('|') + inputLine.user=restDel[0] + inputLine.price=int(restDel[2].partition('|')[0]) + for inputLine.product in getProducts(products): + database=addLineToDatabase(database, inputLine ) + inputLine.price = 0; + #bygg database.pengebeholdning + if (inputType==3) or (inputType==4): + for i in range(inputLine.numberOfDays+1): + if i > 0: + database.pengebeholdning[i] +=database.pengebeholdning[i-1] + #bygg dateLine + day=datetime.timedelta(days=1) + dateLine=[] + dateLine.append(startDate) + for n in range(inputLine.numberOfDays): + dateLine.append(startDate+n*day) + return database, dateLine + +def printTopDict(dictionary, n, k): + i=0 + for key in sorted(dictionary, key=dictionary.get, reverse=k): + print key, ': ',dictionary[key] + if i