# -*- Mode: Python; tab-width: 4 -*- # python weight_chart.py [-o {png|ps}] mm/dd import os import string import sys import time if '-o' in sys.argv: i = sys.argv.index ('-o') oo = sys.argv[i+1] if oo not in ('ps','png'): raise ValueError, "supported output is or " fileout = 1 del sys.argv[i:i+2] else: fileout = 0 # get the start date now = list(time.localtime (time.time())) [m,d] = map (int, string.split (sys.argv[1], '/')) now[1] = m now[2] = d secs = time.mktime (now) data = [] # first, read the data f = open (sys.argv[2]) while 1: line = f.readline() if not line: break if line[0] == '#': continue else: w = string.atof (line) data.append (w) f.close() if not fileout: sys.stderr.write ('%d data points\n' % (len(data))) # exponentially-weighted moving average, # recreating/checking the pencil-and-paper 1/10 algorithm. def ewma (values, trend=None, f=10): trends = [] if trend is None: trend = values[0] for v in values: delta = trend - v delta = delta/f delta = round (delta, 1) trend = trend - delta trends.append (trend) return trends trends = ewma (data, f=10) # write the data to a tempfile import tempfile fn = tempfile.mktemp() f = open (fn, 'w') w0 = trends[0] w1 = trends[-1] tw0 = data[0] tw1 = data[-1] for i in range(len(data)): w = data[i] t = trends[i] # convert secs to mm/dd [mm, dd] = time.localtime (secs)[1:3] f.write ('%d/%d %f %f\n' % (mm,dd,w,t)) secs = secs + 86400 f.close() loss = (w0-w1) tloss = (tw0-tw1) deficit = (loss/len(data)) * 3500 tdeficit = (tloss/len(data)) * 3500 # get a pipe to gnuplot p = os.popen ('/usr/local/bin/gnuplot', 'w') commands = """ set ytics 1 set title "Loss: %.1f/%.1f pounds. \\nDaily Deficit: %d/%d kCal" set grid set timefmt "%%m/%%d" set xdata time set format x "%%m/%%d" plot '%s' using 1:2:2:3 notitle with yerrorbars,\ '%s' using 1:3 title "Trend" with lines, \ '%s' using 1:2 title "Weight" with lines """ if fileout: if oo == 'ps': p.write ('set terminal postscript landscape color\n') elif oo == 'png': p.write ('set size 1.25, 1.25\n') p.write ('set terminal png color\n') p.write (commands % (tloss,loss,int(tdeficit),int(deficit),fn,fn,fn)) if not fileout: p.write ('pause -1 "[hit return]"\n') p.flush() raw_input() p.write ('\n') p.close() os.unlink (fn)