I live in Omaha.
 
Navigation
 
Search
 
Random Image
CBSet_121953944001.jpg
 
Me. Elsewhere.
 
Archives
 
Darcy
 
Recently Read
 
Things I Like
mongodb
 
License
 

Thursday Quote: Ed Nather

“I have often felt that programming is an art form, whose real value can only be appreciated by another versed in the same arcane art;”

- Ed Nather
The Story of Mel, a Real Programmer

Posted July 22nd, 2010 - Permalink
Categories: Geek
Tags: , ,
No Comments »
 

Charting Weight Change With Google Visualizations

I started trying to lose weight a while back, since we both know I’m a bit heavy and sitting in front of a computer isn’t going to lose the weight for me.

Naturally, it’s important that I incorporate technology into my weight loss somehow, right? So I decided to give the Google Visualizations API a spin.

I worked up a quick data format and a method to pop the data out. Nothing fancy, just a fixed width flat file. This doesn’t deserve a database.

1
2
2010-06-30 235.4
2010-06-29 236.8

Easy to read, easy to edit, and easy to consume. Every morning I just hop on the server, add the day’s weight and log off.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
  // Get the max days back we want to look.
  $max_days = 7;
  if( isset( $_REQUEST['days'] ) and ! empty( $_REQUEST['days'] ) )
    $max_days = intval( $_REQUEST['days'] );
 
  $i = 0;
  $lines = array();
 
  $fh = fopen( 'data.txt', 'r' );
  while( ! feof( $fh ) and ++$i <= $max_days ) {
    $line = fgets( $fh );
    if( empty( $line ) ) { continue; }
    array_unshift( $lines, $line );
  }
  fclose( $fh );

Now I just needed to represent it. The API is very object oriented and easy to work with. I wish there was a less verbose way of presenting the data, but you can’t have everything.

Actually, there may be a better way, I just didn’t come across it while speed reading the docs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function drawChart() {
  var data = new google.visualization.DataTable();
  data.addColumn( 'string', 'Date' );
  data.addColumn( 'number', 'Weight' );
 
  data.addRows( <?php echo count( $lines ); ?> );
 
  <?php
    $i = 0;
    foreach( $lines as $line ):
  ?>
  data.setValue( 
    <?php echo $i; ?>, 
    0,
    '<?php echo substr( $line, 0, 10 ); ?>'
  );
 
  data.setValue(
    <?php echo $i; ?>,
    1,
    <?php echo floatval( substr( $line, 11 ) ); ?>
  );
  <?php
    ++$i;
    endforeach;
  ?>
 
  var chart_div = document.getElementById( 'chart_div' );
  var chart = new google.visualization.LineChart( chart_div );
  chart.draw(
    data,
    {
      width: 800,
      height: 600,
      title: 'Weight Over Time'
    }
  );
}

And there you have it, fancy charting in no time.

Example Chart

See it in action at http://static.velvetcache.org/weight.php

Get the full source at http://gist.github.com/459148.

Posted July 5th, 2010 - Permalink
Categories: Consume - Geek - Life
Tags: , , , , , , ,
No Comments »
 

Streaming Tweets With Tweepy

I’ve been meaning to check out the Tweepy for a while and got around to it today. It’s a Python library for interacting with Twitter. The feature I’m most interested in is the streaming API support, which isn’t advertised much by Tweepy but seems pretty solid.

Tweepy has pretty good documentation, and the code is terse and readable, but what I found most useful was the examples repository, which had the only example of streaming with Tweepy that I could find in the official documentation.

It’s really straightforward. Implement a tweepy.streaming.StreamListener to consume data, set up a tweepy.streaming.Stream with that listener, then pull the trigger on the streaming function you want to use.

Here’s a quick example I set up to track the filter keyword “omaha”.

# -*- coding: utf-8 -*-
 
from tweepy.streaming import StreamListener, Stream
 
class Listener ( StreamListener ):
  def on_status( self, status ):
    print '-' * 20
    print status.text
    return
 
if __name__ == "__main__":
 
  USERNAME = "YourUsernameHere"
  PASSWORD = "YourPasswordHere"
 
  listener = Listener()
  stream = Stream(
    USERNAME,
    PASSWORD,
    listener
  );
 
  stream.filter( track=( "omaha", ) )

Posted July 5th, 2010 - Permalink
Categories: Consume - Geek
Tags: , , , ,
No Comments »
 

Auto-Generated Github User Page With py-github

Update (2010-06-30)

So I got antsy about this and I upgraded to using pystache instead of my homebrew templating system. This was my first run in with mustache, and I have to say I like it, even though I used the bare minimum feature set.

New code is at http://github.com/jmhobbs/jmhobbs.github.com

Github has a cool feature called “Github Pages” that let you host static content on a subdomain of github, e.g. http://jmhobbs.github.com/.

They also provide an auto-generator for project pages that has a nice clean format which I really like. So I decided to make my user page match the look and feel of the project pages. And to boot I wanted to be able have it auto-generate since I want it to be “hands free”, otherwise I’ll forget to update it.

To make this happen I whipped up my template and then grabbed the excellent py-github from Dustin Sallings, which I have used before.

Without furthur ado I’ll just show you the source. It’s not complicated, just some API calls then search replace on a template file. If you want to use it, be sure to get the most recent version from http://github.com/jmhobbs/jmhobbs.github.com.

Throw in a cron job and you are set. Beware of lot’s of “page build” notices from Github though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# -*- coding: utf-8 -*-
 
import github.github as github
import yaml
import time
from datetime import datetime
 
def repo_date_to_epoch ( date ):
  epoch = time.mktime(
    time.strptime(
      date[0:-6],
      "%Y-%m-%dT%H:%M:%S"
    )
  )
  return int( epoch )
 
def main ():
 
  print "Loading settings...."
  f = open( 'settings.yaml' )
  settings = yaml.load( f )
  f.close()
 
  gh = github.GitHub()
 
  print "Fetching user information..."
  user = gh.users.show( settings['username'] )
 
  print "Fetching repository information..."
  repos = gh.repos.forUser( settings['username'] )
 
  print "Sorting repositories..."
  repos = sorted( repos, cmp=lambda a, b: repo_date_to_epoch( b.pushed_at ) - repo_date_to_epoch( a.pushed_at ) )
 
  print "Loading template..."
  f = open( 'index.html.tpl' )
  template = f.read()
  f.close()
 
  print "Mangling template..."
  template = template.replace( '<% username %>', settings['username'] )
  template = template.replace( '<% fullname %>', user.name )
  template = template.replace( '<% email %>', user.email )
  template = template.replace( '<% following %>', str( user.following_count ) )
  template = template.replace( '<% followers %>', str( user.followers_count ) )
  template = template.replace( '<% publicrepos %>', str( user.public_repo_count ) )
 
  repo_string = ''
 
  for repo in repos:
    if repo.private:
      continue
 
    repo_string = repo_string + '<div class="repo"><h3><a href="' + repo.url + '">' + repo.name + '</a>'
 
    try:
      repo_string = repo_string + ' - <span class="small"><a href="' + repo.homepage + '">' + repo.homepage + '</a></span>'
    except AttributeError:
      pass
 
    repo_string = repo_string + '</h3>'
 
    repo_string = repo_string + "Forks: " + str( repo.forks ) + " - Watchers: " + str( repo.watchers ) + ' | '
 
    if repo.has_issues:
      repo_string = repo_string + ' <a href="' + repo.url + '/issues">Issues</a> |'
 
    if repo.has_wiki:
      repo_string = repo_string + ' <a href="http://wiki.github.com/' + settings['username'] + '/' + repo.name + '">Wiki</a> |'
 
    if repo.has_downloads:
      repo_string = repo_string + ' <a href="' + repo.url + '/downloads">Downloads</a> |'
 
    repo_string = repo_string + '<br/>Last Push: ' + datetime.fromtimestamp( repo_date_to_epoch( repo.pushed_at ) ).ctime()
 
    try:
      repo_string = repo_string + '<pre>' + repo.description + '< /pre>'
    except AttributeError:
      repo_string = repo_string + '<br/><br/>'
      pass
 
    repo_string = repo_string + "</div><!--// .repo //-->\n"
 
  template = template.replace( '<% repos %>', repo_string )
 
  ga = """
    <script type="text/javascript">
      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', '<% ga_code %>']);
      _gaq.push(['_trackPageview']);
      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();
    </script>
  """
 
  if False != settings['google_analytics']:
    template = template.replace( '<% google_analytics %>', ga )
    template = template.replace( '<% ga_code %>', settings['google_analytics'] )
  else:
    template = template.replace( '<% google_analytics %>', '' )
 
  print "Writing file..."
  f = open( 'index.html', 'w' )
  f.write( template )
  f.close()
 
  print "Done!"
 
if __name__ == "__main__":
  main()

Wow. You actually scrolled through all of that. Amazing.

Posted June 29th, 2010 - Permalink
Categories: Geek
Tags: , , , ,
3 Comments »
 

Thursday Quote: Harold Ableson

“Computer Science is a terrible name for this business. First of all it’s not a science. It might be engineering or it might be art.”

- Harold Ableson
EE & CS Professor at MIT
Overview and Introduction to Lisp

Posted June 24th, 2010 - Permalink
Categories: Geek
Tags: , ,
2 Comments »
 
More Posts
 
Copyright © 2006 - 2010 John Hobbs
get userping