Skip to content

Instantly share code, notes, and snippets.

@akdh
Created April 20, 2012 20:42
Show Gist options
  • Save akdh/2431767 to your computer and use it in GitHub Desktop.
Save akdh/2431767 to your computer and use it in GitHub Desktop.
Generates contexts
require 'iconv'
def content_to_xml(context)
"<context number=\"#{context[:number]}\">
<city>#{context[:city]}</city>
<state>#{context[:state]}</state>
<lat>#{context[:lat]}</lat>
<long>#{context[:long]}</long>
<day>#{context[:day]}</day>
<time>#{context[:time]}</time>
<season>#{context[:season]}</season>
</context>"
end
def weighted_sample(lst)
w = Random.new.rand(1..lst.last[:pop_acc])
lst.find do |item|
w <= item[:pop_acc] && item[:population] != 0
end
end
if ARGV.length < 1
puts "usage: FILE [count] [population_min]"
exit
end
# file comes from http://download.geonames.org/export/dump/
filename = ARGV[0]
count = [ARGV[1].to_i, 1].max
pop_min = ARGV[2] || 100000
content = IO.read(filename)
contnet = Iconv.conv('UTF8//UNKNOWN', 'UTF-8', content)
content = content.lines.map { |line| line.split("\t") }
content = content.each { |cols| cols[14] = cols[14].to_i }
content = content.find_all { |cols| cols[6] == 'P' && cols[14] > pop_min }
cities = content.map do |cols|
{
:city => cols[1],
:state => cols[10],
:population => cols[14],
:lat => cols[4],
:long => cols[5],
:contexts => []
}
end
days = %w(weekday weekend)
seasons = %w(spring summer fall winter)
times = %w(morning afternoon evening)
contexts = days.map do |day|
seasons.map do |season|
times.map do |time|
{ :day => day, :season => season, :time => time }
end
end
end.flatten
cities.inject(0) do |pop_sum, city|
result = pop_sum + city[:population] * contexts.length
city[:pop_acc] = result
result
end
(1..count).each do |number|
city = weighted_sample(cities)
city[:contexts] << (contexts - city[:contexts]).sample
if (contexts - city[:contexts]).empty?
index = cities.index(city)
cities[index..-1].each do |item|
item[:pop_acc] -= city[:population]
end
city[:population] = 0
end
end
contexts = cities.map do |city|
city[:contexts].map do |context|
puts context
{
:city => city[:city],
:state => city[:state],
:lat => city[:lat],
:long => city[:long],
:day => context[:day],
:time => context[:time],
:season => context[:season]
}
end
end
contexts = contexts.flatten.shuffle
contexts.each_with_index do |context, number|
context[:number] = number + 1
end
contexts.each do |context|
puts content_to_xml(context)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment