Skip to content

Instantly share code, notes, and snippets.

@samnissen
Last active January 29, 2021 20:23
Show Gist options
  • Save samnissen/ad25d4fdadb29d9dc9673ab1ec3f069f to your computer and use it in GitHub Desktop.
Save samnissen/ad25d4fdadb29d9dc9673ab1ec3f069f to your computer and use it in GitHub Desktop.
Get a daily countdown to Vaccine Day UK
require 'active_support/all'
require 'HTTParty'
require 'json'
UK_CHILD_DECIMAL = 0.189
UK_ADULT_DECIMAL = 1.0 - UK_CHILD_DECIMAL
UK_POPULATION = 67_886_004.0
UK_ADULT_POPULATION = UK_POPULATION * UK_ADULT_DECIMAL
DOWNLOAD_URL = 'https://api.coronavirus.data.gov.uk/v1/data?filters=areaType=nation&structure={"date":"date","total":"cumPeopleVaccinatedFirstDoseByPublishDate","new":"newPeopleVaccinatedFirstDoseByPublishDate"}'
# v2 is not working today (Jan. 26), and instead respondes with a
# "412 Precondition Failed" ...
# "https://api.coronavirus.data.gov.uk/v2/data?areaType=overview&metric=cumPeopleVaccinatedFirstDoseByPublishDate&metric=newPeopleVaccinatedFirstDoseByPublishDate&format=json"
# ^ from https://coronavirus.data.gov.uk/details/download
# TOTALDELTA = (6853327-5962544)
# TOTALDELTA = (7164387-6221850)
# TOTALDELTA = (7447199-6473752)
# TOTALDELTA = (7891184-6816945)
# FUN: API v1 doesn't appear to have correct info for
# cumPeopleVaccinatedFirstDoseByPublishDate
# We get a number, but it is always underreported.
# This delta as an integer does not hold every day.
# (Thus far it is growing, but I have few data points as of yet.)
# So, I've averaged the percent they are underreported
# which is AVERAGE_MISS
AVERAGE_MISS = 0.1522091537079264
class VaccineDay
class << self
def predict
data = get_data
parsed_data = parse(data)
throughput = calculate_throughput(parsed_data)
dates = calulate_dates(throughput)
report(dates, throughput)
end
def get_data
HTTParty.get(DOWNLOAD_URL)
end
def parse(raw)
puts raw.code
puts raw.body[0..100]
JSON.parse(raw.body, symbolize_names: true)[:data]
end
def calculate_throughput(results)
upto_date = results.first[:date]
vaccinated = results.first[:total] * (1+AVERAGE_MISS)
last_seven_daily = results[0..6].map do |result|
result[:new]
end
{
vaccinated: vaccinated,
upto_date: upto_date,
last_seven_average: ((last_seven_daily.inject(:+))/7.0),
percent_vaccinated: (vaccinated/UK_ADULT_POPULATION)
}
end
def calulate_dates(throughput)
days_to_fifty = days_to(0.5, throughput)
days_to_total = days_to(1.0, throughput)
{
days_to_fifty: days_to_fifty,
days_to_total: days_to_total,
fifty_day: (Date.today + days_to_fifty),
total_day: (Date.today + days_to_total)
}
end
def days_to(percentage, throughput)
(((percentage - throughput[:percent_vaccinated]) * UK_ADULT_POPULATION)/throughput[:last_seven_average])
end
def report(dates, throughput)
puts "* #{(throughput[:percent_vaccinated] * 100.0).round(2)}% of UK adults (#{throughput[:vaccinated].to_i.to_s(:delimited)}) have received their first vaccine dose as of #{throughput[:upto_date].to_s}"; sleep(0.2)
puts "* #{dates[:days_to_fifty].round(0)} days (#{dates[:fifty_day].to_s}) before 50% of UK adults receive first vaccine dose"; sleep(0.2)
puts "* #{dates[:days_to_total].round(0)} days (#{dates[:total_day].to_s}) before all UK adults receive single day vaccine"; sleep(0.2)
puts "(throughput based on a rolling 7 day average)"; sleep(0.05)
end
end
end
VaccineDay.predict
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment