installed_progs.t: Python checks stdout too, 150 ok
[sunny256-utils.git] / geohashing
blob7bd512d478f8f528a80bc2de91bc5f38f8c75bd0
1 #!/usr/bin/env perl
3 # Reference implementation for the geohashing algorithm described in xkcd #426
4 # See http://wiki.xkcd.com/ProjectRainbow/Main_Page
6 # Dan Boger (zigdon@gmail.com)
7 # 2008-05-21
9 use strict;
10 use warnings;
11 use Digest::MD5 qw/md5_hex/;
12 use Date::Manip;
13 use Getopt::Std;
15 my %opts;
16 getopts('e', \%opts);
18 # get the date from the commandline, or assume it's today's date
19 my $date = shift || "";
20 $date ||= 'today';
21 my $datestring = UnixDate( ParseDate($date), "%Y-%m-%d" );
23 die "Usage: $0 [-e] <date> [DJI opening]"
24 unless $datestring and $datestring =~ /^\d\d\d\d-\d\d-\d\d$/;
26 # get the DJIA from the commandline, or try to retrieve it from google
27 my $djia = shift;
28 unless ($djia) {
29 $djia = &download_djia($date, $opts{e});
32 print "Date: $datestring, DJIA: $djia\n";
34 # calculate the MD5 of the combined date and DJIA
35 my $md5 = md5_hex("$datestring-$djia");
36 print "MD5($datestring-$djia): $md5\n";
38 # split into two
39 my ( $md5x, $md5y ) = ( substr( $md5, 0, 16 ), substr( $md5, 16, 16 ) );
40 print "Split: $md5x, $md5y\n";
42 # transform into a fraction
43 my ( $fx, $fy ) = ( 0, 0 );
44 while ( length $md5x or length $md5y ) {
45 my $d = substr( $md5x, -1, 1, "" );
46 $fx += hex $d;
47 $fx /= 16;
49 $d = substr( $md5y, -1, 1, "" );
50 $fy += hex $d;
51 $fy /= 16;
53 printf "Fractions: %0.16f, %0.16f\n", $fx, $fy;
55 sub download_djia {
56 my $date = shift;
57 my $use_30w_rule = shift;
59 if ($use_30w_rule) {
60 print "Adjusting for 30W\n";
61 $date = DateCalc(ParseDate($datestring), "-1 day");
64 my $datestring = UnixDate( ParseDate($date), "%Y-%m-%d" );
65 my $djia;
67 require LWP::Simple;
68 import LWP::Simple 'get';
69 require HTML::TreeBuilder;
71 my $URL =
72 'http://finance.google.com/finance/historical?cid=983582&startdate=%s&enddate=%s';
73 $URL = sprintf( $URL,
74 UnixDate( DateCalc( $date, "- 7 days" ), "%b+%d,+%Y" ),
75 UnixDate( $date, "%b+%d,+%Y" ) );
76 print "Downloading DJIA from google: $URL\n";
77 my $page = get($URL);
78 die "Failed to get DJIA from google!" unless $page;
79 my $tree = HTML::TreeBuilder->new_from_content($page)
80 or die "Failed to parse google DJIA page!";
82 my $data = $tree->look_down( id => "prices" ) or die "No data div: $!";
83 foreach my $td ( $data->look_down( class => "firstcol" ) ) {
84 next if $td->as_text eq 'Date';
85 my @date = localtime;
86 $djia = $td->right->as_text;
87 $djia =~ s/,//g;
88 print "DJIA opening for $datestring is $djia\n";
89 last;
92 $tree->delete;
94 die "Failed to retrieve DJIA from google!" unless $djia;
96 return $djia;