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 {*}$argvTo use just run the script like: tclsh election.tcl 5 minutes