import os from datetime import date,timedelta,datetime class superdate(date): pass # This becomes magix tracing=False def trace(msg,*args,**kwargs): if not tracing: return print(datetime.now(),msg,*args,**kwargs) def loadcsv(file): with open(file) as a: out=parsecsv(a.read()) if out: y,m=file[:-4].split('-') for n in out: if n[0]==0: n[0]=superdate(int(y),int(m),1) else: n[0]=date(int(y),int(m),n[0]) return out def guesssplit(rows,splitter): counts={} for i in rows: c=i.count(splitter) try: counts[c]+=1 except KeyError: counts[c]=1 return sorted(counts.items(),key=lambda x:x[1])[-1][0] def parsecsv(data): if data: dat=data.split('\n') c=guesssplit(dat,',') out=[n.split(',',c) for n in dat if n.strip(',')] for n in out: n[0],n[1]=int(n[0]),int(n[1]) return out def putcsv(data): return '\n'.join([','.join([str(m) for m in n]) for n in data]) def savecsv(data): filename=f'{data[0][0].year}-{data[0][0].month}.csv' out=[] for n in data: out.append(n.copy()); n=out[-1] if isinstance(n[0],superdate): n[0]=0 else: n[0]=n[0].day with open(filename,'w') as a: return a.write(putcsv(out)) def loadbudget(): out=list(filter(None,map(loadcsv,[n for n in os.listdir('.') if n[-4:]=='.csv']))) # filter(None) actually works wtf global budget budget=[] for n in out: budget.extend(n) global _budget _budget=budget.copy() def savebudget(alll=False): global _budget grps=set(map(lambda x:(x[0].year,x[0].month),budget)) for mo in grps: stuff=list(filter(lambda x:x[0].year==mo[0] and x[0].month==mo[1], budget)) stuff2=list(filter(lambda x:x[0].year==mo[0] and x[0].month==mo[1], _budget)) if stuff!=stuff2 or alll: savecsv(stuff) _budget=budget.copy() def current(combined=False,display=True,start=None,end=None,accs=None): start=start or min(map(lambda x:x[0],budget)) end=end or max(map(lambda x:x[0],budget)) reng=list(filter(lambda x:start<=x[0]<=end,budget)) wals=accs or set(map(lambda x:x[2],reng)) wallets={} for wallet in wals: labels=set(map(lambda x:x[3],filter(lambda x:x[2]==wallet,reng))) wallets[wallet]={label:sum(n[1] for n in filter(lambda x:x[2]==wallet and x[3]==label,reng)) for label in labels} if combined: total=sum([sum(n.values()) for n in wallets.values()]) return total/100 if display else total # I want to do (1+99*display) but that guarantees a float, and floats are gay if display: for w in wallets: wallets[w]={k:(v/100) for k,v in wallets[w].items()} return wallets def history(pool,start=date.today()-timedelta(days=7)): return list(filter(lambda x:x[0]>start and x[2]==pool,budget)) def monthstart(acc=None): start=date.today().replace(day=1) if not acc: return sum(n[1] for n in budget if n[0]