Cookie Notice

As far as I know, and as far as I remember, nothing in this page does anything with Cookies.

2013/08/21

Caller ID, Time and Temp with Twilio

The other day, my wife got a new phone, replacing her shattered iPhone 4 with a new LG Optimus. The problem is, by rotation, the upgrade was for me, so the new phone was to have my phone number. They moved it to her phone number, but that left me disconnected from the cell network. At least, I knew at the time I was disconnected, but I was less than sure that her phone was using her number.

My thought was, "It would be nice to be able to call someplace and have it tell you what number your phone is, so we could be sure." So, I wrote something.


This uses Twilio, which is essentially an API into IP telephony. I've used Twilio before, and have two projects on GitHub, Call_Me and SMS_Me, that are generally unidirectional messaging tools, but I haven't done much interactivity with the tool.

It gives the following output, which Twilio then runs through text-to-speech.


The time is currently 4 37 pm

The temperature in West Lafayette is 83 degrees Fahrenheit.

Your phone number is 1 2 3. 4 5 6. 7 8 9 0.

A few notes on the formatting first. I separate the numbers of the phone number (and that is not a real number) so that it says the number with an expected cadence. If I just put 1234567890, it'd say one billion, two hundred twenty three million, five hundred sixty-seven thousand, eight hundred and ninety. If I just broke it up to 123 456 7890, it'd say one hundred twenty three, four hundred fifty six, seven thousand eight hundred ninety. To break up the numbers so it just says the digits, you need to put the spaces. To break it up so the area code and exchange and line numbers are distinct, you need the punctuation.

Times are weird, too. If the time is 4:37, just having the time as 4 37 works, but if the time is 4:05 and broken into 4 05 instead, it'd read it as four five. This is why I use digit letter-"o" digit for the time.

I say lots of bad things about XML and prefer to avoid it when possible, but sometimes, like here, it's just that easy to handle. Kudos to XML::LibXML and NOAA for making that part reasonable and good.

Now that I have this working, I'm curious about doing other things. I can see myself adding to this, checking to see if From is my number, and if so, opening up choices like my whole Quantified Self stuff, the home automation I want to do more of, etc. I'm not sure I like the TwiML module, and might move that over to Template Toolkit, but that remains to be seen.

2013/08/12

Coding Yourself Into Shape

Today, I've hit a new low.

224 lbs. This is as low as I've been in a great long while.

I've been looking and thinking about this graph for a while and have come to some conclusions.

I ran some last year and it didn't help much. 

The first day I was under 240 (the orange line, separating overweight and obese for my height on the BMI index) was October 7, 2012. (I get that it's problematic because Fat Albert and in-his-prime Mike Tyson were about the same height and weight, but there's a huge difference, pun intended, between their body composition. When people start mistaking me for a heavyweight champion, I'll start worrying about being placed wrong on the BMI chart.) I started running at some point in the summer and mostly ended after a 5K I participated in on August 25. The trend line for weight doesn't change significantly, sticking with the ~1lb/week during that time.

Be aware that this is self-tracked, and there are some days where I forgot to weigh and some weeks when I was unable to check against my scale, and this version of the graph does not show the gaps.

So, what did help?

The majority of my weight loss during that time is probably attributable to drinking more water and less caffeine.


There were certainly times when I lived off the stuff.
In April 2009, I started to think about all the bad things they say about caffeine, as well as all the good things, and decided that I'd go cold turkey, test it out on myself and see for myself.

The first day, I took my boys to a pizza place with a soda fountain, and I had two cups of Diet Coke before I thought about it. The second day, I did much the same. This is why we call it a habit, because we start continuing behaviors because that's what we do.

The third day, I remembered and went without anything.

The fourth day, my co-worker looked over at me, with my area's lights off, hunched over, nauseous and with a head that felt like it was exploding, and told me "If you have the flu, you should just go home." I gave up. But I started cutting back. Way back.

Right now, I tend to drink two cups of coffee a day, only on work days, and never on work days. Sometimes maybe a cup on Sundays, but rarely.

The way I think of the problem with cola, even diet is:
  • As I got from Tim Ferriss' Four Hour Body, Never Drink Calories
  • We put artificial sweetener into our drinks in order to trick our tongues into thinking the drink is sugary and therefore tasty. Current thought is that our pancreas is similarly tricked, thus creating large amounts of Insulin and storing our calories as fat. 
  • The body works better with sleep. When you caffeinate, you mess up your sleep. When you don't get good sleep, you get fat.
  • If you don't drink it all the time, there's withdrawal, which give the flu-like symptoms I describe above. I heard a story about how a person's mom tried to get his dad to switch to decaf on weekends, and the illness and headaches almost led to them getting a divorce. Part of what I began to realize was that I was having the same effects, and sometimes still do. 
I have never really trusted the bad things said about Aspartame, but there's enough here to make me choose water over cola every time.

You should never be hungry.

Time was, I would only eat dinner most days. Beyond what it might've done to slow my metabolism, it made me famished by the end of the day, and, as I was either a CS student or a developer for those days, and willpower and cognitive processing draw from the same pool, by the end of the day, as I was exhausted, I made stupid decisions, ate as much as I could, then fell asleep.

Right now, I eat cheaply and probably not right — generally a packet of oatmeal for breakfast and a $1 TV dinner for lunch — I always eat, so I'm never so famished that I couldn't say "no" to the promise of a snack, or to thirds. I don't always do so, as I'm a weak, weak man, but I'm better than I was.

Eventually, you get all the benefits you're going to get for one change.

The story from October to the middle of summer is pretty much +/- 5lbs from 235 lbs, which is pretty much stasis. (Reading Back, that doesn't make sense. Trying to rewrite) The sudden drop at about 375 on the graph above (I really need to put dates into the graph!) occurred over Christmas/New Years', when I was away, visiting with family. Days out and about with my family in Nevada are different than snowy days in Indiana, so that shows that other changes in diet and exercise made more difference at 235lbs than they did before.

My newest changes are more exercise — I try to make it to the gym three times a week but usually more hist twice — and less carbs — as suggested by Randal Schwartz, I tend to eat the toppings off pizzas but leave the bread alone, and not just the crust — and those are leading to the current drop. We'll see how far these take me.

Your body is hackable.

The graph above and the data it shows exist because I read Tim Ferriss' book, The 4-Hour Body. I'm not doing everything in it — it's probably accurate to say I'm not doing anything in it — but most everything in this post started with me trying to affect the inputs to the black box that is my body and trying to get different outputs.

The graphs and the core of my first approach has been mostly inspired by John Walker's Hacker's Diet. My graph shows a several-day rolling average, but not a weighted average like Walker suggests, because that was the limit to the amount of SQL I knew.

My goal right now is to get to and stay at about +/-5lbs from 200, and I think I can do that. My other goal is to not be able to pinch an inch on my belly. I've been able to do that ever since Special K started showing that ad.

There's more things to change than weight.

In many ways, I enjoyed my time trying to build up to a 5K last year. I didn't enjoy all of it. There was intense pain, mostly in my right foot, and running on feet that hurt you is not fun. So, I went to see a podiatrist, who said that my left ankle is pronated and my right was even more so, so much that my right achilles tendon is in the wrong place. She made me orthotics. I personally don't think they did much good, and I stopped wearing them earlier this summer. Over the last few weeks, I've been using a home-made standing desk, basically monitors on top of the hutch and a box holding my keyboard up. I might get a purpose-built desk to replace this in the fullness of time, but this was mostly to prove the concept.

I have to say that, for the first two weeks, my feet were always sore. The problem wasn't the sole of the foot, but rather the arches going into the ankle. The interesting thing has happened in the last week: I've felt something happen with my heel which might be my tendon going back into position, and I'm pretty sure my ankle looks better and has better range of motion than it has in quite some time. So, for that change alone, I don't think I'll go back to a standard desk any time soon.

Making it a more public process helps with motivation.

When I make new milestones with my weight loss, I tweet my weight, linking to a JavaScript graph of my recent progress. I wear a FitBit most every day, and have code that connects to the FitBit API and also tweets my steps and floors each day. You can even follow me directly on FitBit. I even have my running tracker, Endomondo, post to Twitter and Facebook, even if I wish it wouldn't post the map.

I don't feel like running every day. I don't feel motivated to just eat the toppings off pizza every day. That people I know can know what I'm doing and give me encouragement is a major part of what I'm doing. (Learning how to make the graphs and sparklines and such is another big part.)

If you have something you want to change about yourself, the thing I would suggest is to break it into things you can keep track of, then go for it!

2013/08/07

Enemy of the State?

I've been glad for all the new life breathed into the Perl community starting with 5.10, but, honestly, there has been only one thing I consistently used in the raft of new stuff added: say. I disliked having to write print "$var\n" each time I wanted to print a line with a newline, and say allowed me an easy way to do that without changing the behavior of print.

But I've been trying out state.
state declares a lexically scoped variable, just like my. However, those variables will never be reinitialized, contrary to lexical variables that are reinitialized each time their enclosing block is entered.
That sounds like a winner, doesn't it? But it left me some questions.

I deal with SQL a lot, and so I have queries in my code. Sometimes, big queries. I'm wondering if assigning the SQL query each time is more costly, CPU-wise, than declaring it as a state variable and just holding it in memory.

#!/usr/bin/perl

use feature qw{ say state } ;
use strict ;
use warnings ;
use Benchmark qw{:all} ;
use Carp ;

use lib '/home/jacoby/lib' ;
use DB ;

my $sql = <<SQL;
        SHOW TABLES
SQL

sub outside {
    my $arrayref = db_arrayref( $sql ) ;
    }

sub use_my {
    my $sql = <<SQL;
        SHOW TABLES
SQL
    my $arrayref = db_arrayref( $sql ) ;
    }

sub use_state {
    state $sql = <<SQL;
        SHOW TABLES
SQL
    my $arrayref = db_arrayref( $sql ) ;
    }

timethese(
    10_000 , {
    'outside'   => sub { outside( ) ; } ,
    'use my'    => sub { use_my( ) ; } ,
    'use state' => sub { use_state( ) ; } ,
    } ) ;

DB.pm is my wrapper for the very complex DBI module, which gives me just three functions: db_do, db_hashref and db_arrayref. DB has %prepared, such that $prepared{ $sql } = $dbh->prepare( $sql ), so that, when using a query over and over again, a pre-prepared statement handle object is passed out.
Benchmark: timing 10000 iterations of outside, use my, use state...
   outside: 476 wallclock secs (14.66 usr +  8.21 sys = 22.87 CPU) @ 437.25/s (n=10000)
    use my: 475 wallclock secs (14.87 usr +  8.01 sys = 22.88 CPU) @ 437.06/s (n=10000)
 use state: 469 wallclock secs (14.68 usr +  8.14 sys = 22.82 CPU) @ 438.21/s (n=10000)
Looks like, in this case, it doesn't make a whole lot of difference. Still, good to know, right?