NEM 2008-11-05: Flagging a little watching the results from the 2008 US Presidential election trickle in, when I stumbled upon this article [L1 ] at Ars Technica describing how to grab a live JSON feed of the results from Google/Amazon. So, here's code to periodically poll the feed and show the overall candidate votes and electoral college votes in a little table. Would love someone to combine this with TkWorld or something similar to show the results graphically on a map of the US, but must sleep soon... :-)
package require http package require json variable DATA_URL http://election2008.s3.amazonaws.com/votes/us-pres.json # Main routine - fetches data, decodes it, then displays it :-)[NEM] 2008-11-05: Flagging a little watching the results from the 2008 US Presidential election trickle in, when I stumbled upon this article [http://arstechnica.com/journals/linux.ars/2008/11/04/code-your-own-election-mashup-with-googles-json-data] at Ars Technica describing how to grab a live [JSON] feed of the results from Google/Amazon. So, here's code to periodically poll the feed and show the overall candidate votes and electoral college votes in a little table. Would love someone to combine this with [TkWorld] or something similar to show the results graphically on a map of the US, but must sleep soon... :-)
package require http package require json
variable DATA_URL http://election2008.s3.amazonaws.com/votes/us-pres.json
# Main routine - fetches data, decodes it, then displays it :-) proc refresh url { display [decode [fetch $url] }
# Fetch the data proc fetch url {
set t [http::geturl $url] if {[http::ncode $t] == 200} { set data [http::data $t] } else { set data {} } http::cleanup $t return $data
}
# Decode the JSON data and extract some summary information proc decode data {
set data [json::json2dict $data] set ret [list] foreach candidate [dict get $data totals races President "" votes] { set name [dict get $data candidates [dict get $candidate id]] set name [lindex [split $name "|"] 2] set vote [dict get $candidate votes] set electoral [dict get $candidate electoral] lappend ret $name $vote $electoral } return $ret
}
# Display the data in a neat table proc display data {
puts "Time: [clock format [clock seconds]]" puts [string repeat "-" 60] puts [format "%-30s | %10s | %10s" "Candidate" "Votes" "Electoral"] puts [string repeat "-" 60] foreach {name votes electoral} $data { puts [format "%-30s | %10d | %10d" $name $votes $electoral] } puts [string repeat "-" 60] puts ""
}
# Set up a repeating event proc every {interval units action} {
uplevel #0 $action after [$units $interval] [namespace code [info level 0]]
}
# Convert times from various units to milliseconds proc seconds t { expr {$t * 1000} } proc minutes t { expr {seconds $t * 60} } proc hours t { expr {minutes $t * 60} }
# Main routine - parse arguments and start everything running proc election {interval units} {
variable DATA_URL every $interval $units [list refresh $DATA_URL] vwait forever
}
election {*}$argv
To use just run the script like: tclsh election.tcl 5 minutes <<categories>> Toys proc refresh url { display [decode [fetch $url]] } # Fetch the data proc fetch url { set t [http::geturl $url] if {[http::ncode $t] == 200} { set data [http::data $t] } else { set data {} } http::cleanup $t return $data } # Decode the JSON data and extract some summary information proc decode data { set data [json::json2dict $data] set ret [list] foreach candidate [dict get $data totals races President "" votes] { set name [dict get $data candidates [dict get $candidate id]] set name [lindex [split $name "|"] 2] set vote [dict get $candidate votes] set electoral [dict get $candidate electoral] lappend ret $name $vote $electoral } return $ret } # Display the data in a neat table proc display data { puts "Time: [clock format [clock seconds]]" puts [string repeat "-" 60] puts [format "%-30s | %10s | %10s" "Candidate" "Votes" "Electoral"] puts [string repeat "-" 60] foreach {name votes electoral} $data { puts [format "%-30s | %10d | %10d" $name $votes $electoral] } puts [string repeat "-" 60] puts "" } # Set up a repeating event proc every {interval units action} { uplevel #0 $action after [$units $interval] [info level 0] } # Convert times from various units to milliseconds proc seconds t { expr {$t * 1000} } proc minutes t { expr {[seconds $t] * 60} } proc hours t { expr {[minutes $t] * 60} } # Main routine - parse arguments and start everything running proc election {interval units} { variable DATA_URL every $interval $units [list refresh $DATA_URL] vwait forever } election {*}$argv
To use just run the script like: tclsh election.tcl 5 minutes