-
-
Save kmcallister/19c9898fea0d76156fa2f1925ace2164 to your computer and use it in GitHub Desktop.
Revisions
-
kmcallister created this gist
Jul 28, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ #!/bin/sh #set -e ./ewma.py < log > smoothed echo ./progress.py "$@" < smoothed echo gnuplot < weight-graph.gpl #./maintain.py < log #echo ./rate.py < smoothed > rate gnuplot < rate-graph.gpl cp log backup/$(tail -n 1 log | awk '{print $1}') This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,48 @@ #!/usr/bin/python import sys import argparse import time import datetime argparser = argparse.ArgumentParser() argparser.add_argument('--verbose', '-v', action='store_true') argparser.add_argument('--alpha', '-a', type=float, default=0.1) args = argparser.parse_args() if args.alpha < 0.0 or args.alpha > 1.0: raise ValueError, "you suck" ewma = 0.0 def update(weight): global ewma ewma = args.alpha*weight + (1.0 - args.alpha)*ewma last_ordinal = None last_weight = None for ln in sys.stdin: date, weight = ln.split() date = datetime.datetime.strptime(date, '%Y-%m-%d') weight = float(weight) ordinal = date.toordinal() if args.verbose: print (date.toordinal(), weight) if last_ordinal is None: last_ordinal = ordinal last_weight = weight ewma = weight else: last_ordinal += 1 while last_ordinal < ordinal: if args.verbose: print 'Missing day, using', last_weight update(last_weight) last_ordinal += 1 if args.verbose: print 'Update with', weight update(weight) last_weight = weight print date.strftime('%Y-%m-%d'), ewma This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,32 @@ #!/usr/bin/env python import datetime import sys import math import argparse import numpy from scipy import stats goal = 234 window = 30 points = [] confidence = 0.05 for ln in sys.stdin: date, weight = ln.split() date = datetime.datetime.strptime(date, '%Y-%m-%d') weight = float(weight) points.append((date, weight)) points = points[-window:] weights = [p[1] for p in points] minw, maxw, avgw = (min(weights), max(weights), numpy.average(weights)) t_stat, p_value = stats.ttest_1samp(weights, goal) print 'Target: %6.2f lbs' % (goal,) print 'Range: %6.2f lbs' % (maxw-minw,) print 'Std deviation: %6.2f lbs' % (numpy.std(weights),) print 'Min/avg/max: %6.2f / %6.2f / %6.2f' % (minw, avgw, maxw) print 'Deltas: %6.2f / %6.2f / %6.2f' % (minw-goal, avgw-goal, maxw-goal) print print 'Verdict: ', 'Maintaining!' if p_value > confidence else 'Not maintaining', '(p = %.2f)' % (p_value,) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,104 @@ #!/usr/bin/env python import datetime import sys import math import argparse from scipy import stats argparser = argparse.ArgumentParser() argparser.add_argument('--reddit', '-r', action='store_true') args = argparser.parse_args() parse_date = lambda s: datetime.datetime.strptime(s, "%Y-%m-%d") goal = 225 goal_date = parse_date("2019-06-01") window = 30 height = 1.91 # meters kg_per_lb = 0.453592 points = [] def parse(ln): date, weight = ln.split() date = datetime.datetime.strptime(date, '%Y-%m-%d') weight = float(weight) return (date, weight) lines = list(sys.stdin) start_date, start = parse(lines[0]) points = map(parse, lines) num_points = len(points) num_decrease = sum(1 for p, q in zip(points, points[1:]) if p[1] > q[1]) points = points[-window:] first = points[0] last = points[-1] reg_x = [p[0].toordinal() for p in points] reg_y = [p[1] for p in points] slope, intercept, r_value, p_value, stderr = stats.linregress(reg_x, reg_y) #rate = (first[1] - last[1]) / (last[0] - first[0]).days rate = -slope if rate <= 0.0: print "Sorry, you're getting fatter at %.2f lb/wk (r^2 = %.2f)" % (-7.0*rate, r_value**2.0) sys.exit(1) def output_stat(label, value): if args.reddit: print '**' + label + '**|' + value.lstrip() else: print (label + ':').ljust(17) + value done = start - last[1] days_done = (last[0] - start_date).days remainder = last[1] - goal remaining_time = datetime.timedelta(days = remainder / rate) finish_date = last[0] + remaining_time margin = (goal_date - finish_date).days + 1 required_rate = remainder / (goal_date - last[0]).days excess_rate = rate - required_rate def project(date): projection = last[1] - (rate * (parse_date(date) - last[0]).days) print 'Weight on %s: %6.2f lbs = %6.2f lbs lost' % (date, projection, start - projection) if args.reddit: print 'Stat|Value' print ':-|:-' output_stat('Current weight', '%6.2f lbs' % (last[1],)) #output_stat('BMI', '%6.2f' % ((kg_per_lb * last[1]) / (height ** 2.0),)) output_stat('Lost so far', '%6.2f lbs = %5.2f%% of starting weight' % (done, 100.0 * done / start)) output_stat('Remaining', '%6.2f lbs = %5.2f%% of current weight' % (remainder, 100.0 * remainder / last[1])) output_stat('Progress', '%6.2f %%' % (done / (start - goal) * 100.0,)) output_stat('Required rate', '%6.2f lbs / wk' % (7.0 * required_rate,)) output_stat('Actual rate', '%6.2f lbs / wk = %.2f%% per week (r^2 = %4.2f)' % (7.0*rate, 100*7.0*rate / last[1], r_value**2.0)) #output_stat('Excess rate', '%6.2f lbs / wk' % (7.0*excess_rate,)) output_stat('Deficit', ' %4d kcal / day' % (rate*3500,)) #output_stat('Excess deficit', ' %4d kcal/day' % (excess_rate*3500,)) output_stat('All-time rate', '%6.2f lbs / wk' % (7.0 * done / days_done,)) output_stat('Average drops', '%6.2f %% of the time (%d out of %d points)' % (100.0 * num_decrease / float(num_points), num_decrease, num_points)) print print 'Goal will be reached on %s' % (finish_date.strftime('%Y-%m-%d'),), if margin > 0: print '(%d days early)' % (margin,) else: print '(%d days late)' % (-margin,) if args.reddit: print print days_done, 'days done, only', remaining_time.days, 'left to go! Keep it up, you\'re doing great!' print project('2019-06-01') with open('regression_line', 'w') as f: line_out = lambda pt: f.write(pt[0].strftime('%Y-%m-%d') + ' ' + str(intercept + slope*pt[0].toordinal()) + '\n') line_out(points[0]) line_out(points[-1]) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ set title "Weight loss rate" set ylabel "Pounds per week" #set y2label "r^2" set term png size 1400,900 set output "rate-graph.png" set timefmt "%Y-%m-%d" set xdata time set format x "%b\n%d" #set xrange ["2018-02-18":] plot "rate" using 1:2 with lines lw 3 title "Rate", \ #"rate" using 1:3 with lines lw 1 title "r^2" axes x1y2 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,26 @@ #!/usr/bin/env python import datetime import sys import math import argparse from scipy import stats window = 14 points = [] for ln in sys.stdin: date, weight = ln.split() date = datetime.datetime.strptime(date, '%Y-%m-%d') weight = float(weight) points.append((date, weight)) points = points[-window:] if len(points) < window: continue reg_x = [p[0].toordinal() for p in points] reg_y = [p[1] for p in points] slope, intercept, r_value, p_value, stderr = stats.linregress(reg_x, reg_y) print date.strftime("%Y-%m-%d"), -7.0*slope, r_value**2.0 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ set title "Weight loss progress" set ylabel "Weight (lbs)" set term png size 1400,900 set output "weight-graph.png" set timefmt "%Y-%m-%d" set xdata time set format x "%b\n%d" #set xrange ["2018-08-01":] #set yrange [240:290] plot "log" using 1:2 with linespoints pointtype 6 title "Daily weight", \ "smoothed" using 1:2 with lines lw 3 title "Moving average", \ "regression_line" using 1:2 title "Trend line" with lines lw 2 lt rgb "#c01f1f", \ # "raw_line" using 1:2 title "Raw trend line" with lines lw 2 lt rgb "blue"