Created
May 20, 2021 02:26
-
-
Save 3zcurdia/61c7390fbb14550cab52e5a10629ff66 to your computer and use it in GitHub Desktop.
Rick And Morty death toll
This file contains 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
# frozen_string_literal: true | |
require 'json' | |
require 'net/http' | |
require 'concurrent' | |
class RickAndMorty | |
def character(id) | |
response = get_response("https://rickandmortyapi.com/api/character/#{id}") | |
return {} unless response.is_a?(Net::HTTPSuccess) | |
safe_parse(response.body) | |
end | |
private | |
def get_response(uri) | |
uri = URI(uri) | |
Net::HTTP.get_response(uri) | |
rescue SocketError | |
sleep(0.1) | |
retry | |
end | |
def safe_parse(content) | |
JSON.parse(content, symbolize_names: true) | |
rescue JSON::ParserError | |
{} | |
end | |
end | |
class DeathToll | |
def initialize(max = 671) | |
@max = max | |
end | |
def call | |
hist.each do |species, count| | |
puts "#{species}: #{'💀' * count}" | |
end | |
puts "Total deaths: #{hist.values.sum}" | |
puts "Total characters: #{all.count}" | |
puts "%.2f %% has died" % ((hist.values.sum/all.count.to_f) * 100.0) | |
end | |
def all | |
@all ||= fetch_all_thread | |
end | |
def hist | |
@hist ||= calc_hist | |
end | |
private | |
def fetch_all | |
(1..@max).map do |idx| | |
RickAndMorty.new.character(idx) | |
end | |
end | |
def fetch_all_fiber | |
(1..@max).map do |idx| | |
Fiber.new { RickAndMorty.new.character(idx) } | |
end.map(&:resume) | |
end | |
def fetch_all_thread | |
(1..@max).map do |idx| | |
Thread.new { RickAndMorty.new.character(idx) } | |
end.map(&:value) | |
end | |
def fetch_all_thread_pool | |
pool = Concurrent::FixedThreadPool.new(100) | |
characters = [] | |
(1..@max).each do |idx| | |
pool.post do | |
characters << RickAndMorty.new.character(idx) | |
end | |
end | |
pool.shutdown | |
pool.wait_for_termination | |
characters | |
end | |
def calc_hist | |
all.each_with_object(Hash.new { 0 }) do |character, hist| | |
hist[character[:species]] += 1 if character[:status] == 'Dead' | |
end | |
end | |
end | |
DeathToll.new.call |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment