Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oop task done #1

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true
source 'https://rubygems.org'

gem 'activesupport'
23 changes: 23 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (5.0.0.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
minitest (~> 5.1)
tzinfo (~> 1.1)
concurrent-ruby (1.0.2)
i18n (0.7.0)
minitest (5.9.1)
thread_safe (0.3.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)

PLATFORMS
ruby

DEPENDENCIES
activesupport

BUNDLED WITH
1.13.5
1 change: 1 addition & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Run init.rb to fill storage with data
10 changes: 10 additions & 0 deletions entities/author.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# class author described
class Author
attr_accessor :id, :name, :biography

def initialize(name, biography)
@id = SecureRandom.uuid
@name = name
@biography = biography
end
end
10 changes: 10 additions & 0 deletions entities/book.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# class book described
class Book
attr_accessor :id, :title, :author

def initialize(title, author)
@id = SecureRandom.uuid
@title = title
@author = author
end
end
38 changes: 38 additions & 0 deletions entities/library.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# described library class - get output information
class Library
attr_accessor :data_module
def initialize(data_module)
@data_module = data_module
end

def most_active_reader
data_module.fetch_orders.group_by { |order| order.reader }.sort_by { |_, value| value.length }.to_a.last.first
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group_by(&:reader)

end

def most_popular_book
group_orders_by_books.last.first
end

def three_popular_books_orders
books = group_orders_by_books.last(3).map { |item| item.first }
book_ids = books.map { |book| book.id }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map(&:first).map(&:id)


readers = data_module.fetch_orders.map do |order|
if book_ids.include? order.book.id
order.reader
else
nil
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now method is very long and are several extra actions
There are several possibilities here:

  1. data_module.fetch_orders.select { |order| book_ids.include? order.book.id }.map(&:reader)
  2. data_module.fetch_orders.map { |order| order.reader if book_ids.include? order.book.id }.compact

According to task you should return count of uniq readers who takes at least one of 3 most popular books. Are you sure that you need to return books and readers.

Also you don't need to use return in the line 30


readers = readers.uniq.compact

return books, readers
end

private

def group_orders_by_books
data_module.fetch_orders.group_by { |order| order.book }.sort_by { |_, value| value.length }.to_a
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group_by(&:book)

end
end
12 changes: 12 additions & 0 deletions entities/order.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# class order described
class Order
attr_accessor :id, :book, :reader, :date
include Common

def initialize(book, reader)
@id = SecureRandom.uuid
@book = book
@reader = reader
@date = Common.format_time
end
end
13 changes: 13 additions & 0 deletions entities/reader.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# class reader described
class Reader
attr_accessor :id, :name, :email, :city, :street, :house

def initialize(name, email, city, street, house)
@id = SecureRandom.uuid
@name = name
@email = email
@city = city
@street = street
@house = house
end
end
40 changes: 40 additions & 0 deletions index.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require './require'
require './entities/library'

library = Library.new DataManipulation

reader = library.most_active_reader
puts 'Often takes books:'
puts '-- Name: ' + reader.name
puts '-- E-mail: ' + reader.email
puts '-- City: ' + reader.city
puts '-- Street: ' + reader.street
puts '-- House: ' + reader.house.to_s

book = library.most_popular_book
puts '**********************'
puts 'Most popular book:'
puts '-- Title: ' + book.title
puts '-- Author:'
puts '---- name: ' + book.author.name
puts '---- biography: ' + book.author.biography

books, readers = library.three_popular_books_orders

puts '**********************'
puts 'Three most popular books:'
books.each do |popular_book|
puts '-- Title: ' + popular_book.title
puts '-- Author: ' + popular_book.author.name
puts ''
end
puts '**********************'
puts 'People, who ordered al least one of these books:'
readers.each do |book_reader|
puts '-- Name: ' + book_reader.name
puts '-- E-mail: ' + book_reader.email
puts '-- City: ' + book_reader.city
puts '-- Street: ' + book_reader.street
puts '-- House: ' + book_reader.house.to_s
puts ''
end
73 changes: 73 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require './require'

File.delete DataManipulation::STORAGE if File.exist? DataManipulation::STORAGE

authors_hash = {
'Alexander Block': 'Russian writer',
'Jack London': 'Cool writer',
'Taras Shevchecnko': 'Our writer',
'Alexandre Dumas': 'Author of The Count of Monte Cristo',
'Herman Melville': 'Wrote Moby-Dick'
}
authors = []
authors_hash.each do |key, value|
authors << Author.new(key.to_s, value)
end

DataManipulation.add_authors authors

books_hash = {
'Alexander Block': ['Stranger'],
'Jack London': ['Martin Eden', 'The Iron Heel', 'The Call of the Wild'],
'Taras Shevchecnko': ['Kobzar'],
'Alexandre Dumas': ['The Count of Monte Cristo', 'The Three Musketeers'],
'Herman Melville': ['Moby-Dick']
}

authors = DataManipulation.fetch_authors

books = []
authors.each do |author|
next unless books_hash.key? author.name.to_sym
books_hash[author.name.to_sym].each do |book_name|
books << Book.new(book_name, author)
end
end
DataManipulation.add_books books

readers = []
readers_arr = [
['Fedor', '[email protected]', 'Kyiv', 'Bazhana', 115],
['Petro', '[email protected]', 'Kharkiv', 'Shevchenka', 34],
['Semen', '[email protected]', 'Kyiv', 'Obolonska', 56],
['Olga', '[email protected]', 'Dnipro', 'Korolenko', 15],
['Maksim', '[email protected]', 'Dnipro', 'Fabra', 4],
['Svitlana', '[email protected]', 'Lviv', 'Bandery', 39]
]
readers_arr.each do |reader|
readers << Reader.new(reader[0], reader[1], reader[2], reader[3], reader[4])
end
DataManipulation.add_readers readers

orders = []
orders_arr = [
{ book: 'Martin Eden', reader: 'Olga' },
{ book: 'The Count of Monte Cristo', reader: 'Olga' },
{ book: 'Moby-Dick', reader: 'Semen' },
{ book: 'Kobzar', reader: 'Maksim' },
{ book: 'The Three Musketeers', reader: 'Olga' },
{ book: 'Kobzar', reader: 'Petro' },
{ book: 'Moby-Dick', reader: 'Olga' },
{ book: 'Kobzar', reader: 'Fedor' },
{ book: 'Stranger', reader: 'Svitlana' },
{ book: 'Martin Eden', reader: 'Svitlana' },
{ book: 'Kobzar', reader: 'Svitlana' }
]

orders_arr.each do |item|
orders << Order.new(
DataManipulation.fetch_book_by_name(item[:book]),
DataManipulation.fetch_reader_by_name(item[:reader])
)
end
DataManipulation.add_orders orders
6 changes: 6 additions & 0 deletions modules/common.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# common functions
module Common
def format_time(time = Time.current)
time.strftime('%d/%m/%Y %H:%M:%S')
end
end
54 changes: 54 additions & 0 deletions modules/data_manipulation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# functions for reading/saving library data
module DataManipulation
STORAGE = 'library.yml'.freeze

def method_missing(method_name, *args, &block)
match = method_name.to_s.match(/^((add|fetch)_(authors|books|orders|readers)|(fetch)_(book|reader)_by_name)$/)

if match
case match[2]
when 'add'
__send__("#{match[2]}_data".to_sym, args[0], match[3].to_sym)
when 'fetch'
__send__("#{match[2]}_data".to_sym, match[3].to_sym)
when nil && !match[5].nil?
compare_field_map = { book: 'title', reader: 'name' }
__send__(:fetch_item_by_name, args[0], compare_field_map[match[5].to_sym], "#{match[5]}s".to_sym)
else
super
end
else
super
end
end

private

def add_data(data, key)
data = [data] unless data.is_a? Array
load_data unless defined? @storage_data
@storage_data[key] = @storage_data[key].concat data
write_data(@storage_data)
end

def load_data
no_data = { authors: [], books: [], orders: [], readers: [] }
@storage_data = File.file?(STORAGE) ? (YAML.load_file(STORAGE) || no_data) : no_data
end

def fetch_data(key)
load_data unless defined? @storage_data
@storage_data[key]
end

def fetch_item_by_name(value, compare_field, key)
@storage_data[key].each do |item|
return item if item.public_send(compare_field) == value
end
raise "Couldn't find #{key} with #{compare_field} == #{value}"
end

def write_data(data)
File.open(STORAGE, 'w') { |f| f.write(data.to_yaml) }
end
end
15 changes: 15 additions & 0 deletions require.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'active_support/time'

require 'yaml'
require 'securerandom'

require './modules/common'
require './modules/data_manipulation'

include Common
include DataManipulation

require './entities/book'
require './entities/order'
require './entities/author'
require './entities/reader'