Created
June 10, 2013 10:37
-
-
Save chrismcg/5747852 to your computer and use it in GitHub Desktop.
Stockholm to Dublin plane hacking with @paulca
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'csv' | |
class Restaurant | |
attr_accessor :name, :country, :scores | |
def initialize(name) | |
@scores = Array.new(11, 0) | |
@name = name | |
end | |
def all_time | |
scores.inject(&:+) | |
end | |
def average | |
all_time / appearances | |
end | |
def weighted_all_time | |
weighted = [] | |
scores.each_with_index do |score, index| | |
weighted << score * (index + 1) * (index + 1) | |
end | |
weighted.inject(&:+) | |
end | |
def appearances | |
scores.reject(&:zero?).length | |
end | |
def to_s(score_method = :all_time) | |
"#{name}, #{send(score_method)}" | |
end | |
end | |
class RestaurantList | |
attr_reader :restaurants | |
attr_accessor :top | |
def initialize | |
@restaurants = Hash.new { |h, name| h[name] = Restaurant.new(name) } | |
@top = 9 | |
load_data | |
end | |
def sort_by(&block) | |
restaurants.sort_by(&block) | |
end | |
def sort(&block) | |
restaurants.sort(&block) | |
end | |
def reject(&block) | |
restaurants.reject(&block) | |
end | |
def load_data | |
Dir['csv/*.csv'].each do |filename| | |
year = File.basename(filename, '.csv').to_i | |
CSV.foreach(filename) do |data| | |
position = data[0].to_i | |
score = 51 - position | |
name = data[1].downcase | |
country = data[3] | |
restaurants[name].scores[year - 2003] = score | |
restaurants[name].country = country | |
end | |
end | |
end | |
end | |
class CountryList | |
attr_reader :countries | |
def initialize(restaurant_list) | |
countries = Hash.new { |h, country| h[country] = [] } | |
restaurant_list.restaurants.each do |_, restaurant| | |
countries[restaurant.country] << restaurant | |
end | |
end | |
end | |
class TopOfThe | |
attr_accessor :top | |
attr_reader :data | |
def self.score_method(value = nil) | |
return @score_method if value.nil? | |
@score_method = value | |
end | |
def score_method | |
self.class.score_method | |
end | |
def initialize(data) | |
@data = data | |
@top = 9 | |
end | |
def sorted | |
data.sort_by { |_, item| -item.send(score_method) } | |
end | |
def output | |
array = [] | |
array << header | |
sorted[0..top].each_with_index do |(_, item), index| | |
array << "#{index + 1}: #{item.to_s(score_method)}" | |
end | |
array << footer | |
array.join("\n") | |
end | |
def header | |
title = self.class.name.gsub(/([A-Z])/, ' \1').strip | |
[title, "-" * title.length].join("\n") | |
end | |
def footer | |
"\n" | |
end | |
end | |
class WeightedAllTime < TopOfThe | |
score_method :weighted_all_time | |
end | |
class AllTime < TopOfThe | |
score_method :all_time | |
end | |
class Average < TopOfThe | |
score_method :average | |
end | |
class Appearances < TopOfThe | |
score_method :appearances | |
def sorted | |
data.sort do |a, b| | |
left = a[1] | |
right = b[1] | |
if left.appearances == right.appearances | |
right.all_time <=> left.all_time | |
else | |
right.appearances <=> left.appearances | |
end | |
end | |
end | |
end | |
class BestOfTheRest < TopOfThe | |
score_method :all_time | |
def data | |
super.reject { |_, i| i.scores.any? { |s| s > 40 } } | |
end | |
end | |
restaurant_list = RestaurantList.new | |
puts WeightedAllTime.new(restaurant_list).output | |
puts AllTime.new(restaurant_list).output | |
puts Average.new(restaurant_list).output | |
puts Appearances.new(restaurant_list).output | |
puts BestOfTheRest.new(restaurant_list).output | |
country_list = CountryList.new(restaurant_list) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment