├── .github └── workflows │ ├── linters.yml │ └── test.yml ├── .rubocop.yml ├── Gemfile ├── Gemfile.lock ├── MIT.md ├── README.md ├── book.rb ├── books.json ├── capitalize_decorator.rb ├── classroom.rb ├── decorator.rb ├── input.rb ├── main.rb ├── main_menu.rb ├── manage_books.rb ├── manage_persons.rb ├── manage_rentals.rb ├── nameable.rb ├── obtain_data.rb ├── options.rb ├── person.rb ├── persons.json ├── rental.rb ├── rentals.json ├── save_data.rb ├── solver.rb ├── spec ├── book_spec.rb ├── classroom_spec.rb ├── corrector_spec.rb ├── person_spec.rb ├── rentals_spec.rb ├── solver_spec.rb ├── student_spec.rb └── teacher_spec.rb ├── student.rb ├── teacher.rb ├── trimmer_decorator.rb └── user_input.rb /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | rubocop: 7 | name: Rubocop 8 | runs-on: ubuntu-18.04 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-ruby@v1 13 | with: 14 | ruby-version: ">=3.0.x" 15 | - name: Setup Rubocop 16 | run: | 17 | gem install --no-document rubocop -v '>= 1.0, < 2.0' # https://docs.rubocop.org/en/stable/installation/ 18 | [ -f .rubocop.yml ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/ruby/.rubocop.yml 19 | - name: Rubocop Report 20 | run: rubocop --color 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: pull_request 4 | 5 | jobs: 6 | rspec: 7 | name: RSpec 8 | runs-on: ubuntu-18.04 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: actions/setup-ruby@v1 12 | with: 13 | ruby-version: 3.0.x 14 | - name: Setup RSpec 15 | run: | 16 | [ -f Gemfile ] && bundle 17 | gem install --no-document rspec -v '>=3.0, < 4.0' 18 | - name: RSpec Report 19 | run: rspec --force-color --format documentation 20 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | NewCops: enable 3 | Exclude: 4 | - "Guardfile" 5 | - "Rakefile" 6 | - "node_modules/**/*" 7 | 8 | DisplayCopNames: true 9 | 10 | Layout/LineLength: 11 | Max: 120 12 | Metrics/MethodLength: 13 | Max: 20 14 | Metrics/AbcSize: 15 | Max: 50 16 | Metrics/ClassLength: 17 | Max: 150 18 | Metrics/BlockLength: 19 | IgnoredMethods: ['describe'] 20 | Max: 30 21 | 22 | 23 | Style/Documentation: 24 | Enabled: false 25 | Style/ClassAndModuleChildren: 26 | Enabled: false 27 | Style/EachForSimpleLoop: 28 | Enabled: false 29 | Style/AndOr: 30 | Enabled: false 31 | Style/DefWithParentheses: 32 | Enabled: false 33 | Style/FrozenStringLiteralComment: 34 | EnforcedStyle: never 35 | 36 | Layout/HashAlignment: 37 | EnforcedColonStyle: key 38 | Layout/ExtraSpacing: 39 | AllowForAlignment: false 40 | Layout/MultilineMethodCallIndentation: 41 | Enabled: true 42 | EnforcedStyle: indented 43 | Lint/RaiseException: 44 | Enabled: false 45 | Lint/StructNewOverride: 46 | Enabled: false 47 | Style/HashEachMethods: 48 | Enabled: false 49 | Style/HashTransformKeys: 50 | Enabled: false 51 | Style/HashTransformValues: 52 | Enabled: false 53 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rubocop', '>= 1.0', '< 2.0' 4 | # gem "rails" 5 | gem 'pry', '~> 0.13.1' 6 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | ast (2.4.2) 5 | coderay (1.1.3) 6 | method_source (1.0.0) 7 | parallel (1.22.1) 8 | parser (3.1.1.0) 9 | ast (~> 2.4.1) 10 | pry (0.13.1) 11 | coderay (~> 1.1) 12 | method_source (~> 1.0) 13 | rainbow (3.1.1) 14 | regexp_parser (2.2.1) 15 | rexml (3.2.5) 16 | rubocop (1.26.1) 17 | parallel (~> 1.10) 18 | parser (>= 3.1.0.0) 19 | rainbow (>= 2.2.2, < 4.0) 20 | regexp_parser (>= 1.8, < 3.0) 21 | rexml 22 | rubocop-ast (>= 1.16.0, < 2.0) 23 | ruby-progressbar (~> 1.7) 24 | unicode-display_width (>= 1.4.0, < 3.0) 25 | rubocop-ast (1.16.0) 26 | parser (>= 3.1.1.0) 27 | ruby-progressbar (1.11.0) 28 | unicode-display_width (2.1.0) 29 | 30 | PLATFORMS 31 | x86_64-darwin-21 32 | x86_64-linux 33 | 34 | DEPENDENCIES 35 | pry (~> 0.13.1) 36 | rubocop (>= 1.0, < 2.0) 37 | 38 | BUNDLED WITH 39 | 2.3.7 40 | -------------------------------------------------------------------------------- /MIT.md: -------------------------------------------------------------------------------- 1 | ## Copyright 2021, [DAVID VERGARAY] 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this [OOP SCHOOL LIBRARY] and associated documentation files, to deal in the [OOP SCHOOL LIBRARY] without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the [OOP SCHOOL LIBRARY], and to permit persons to whom the [OOP SCHOOL LIBRARY] is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the [OOP SCHOOL LIBRARY]. 6 | 7 | THE [OOP SCHOOL LIBRARY] IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE [OOP SCHOOL LIBRARY] OR THE USE OR OTHER DEALINGS IN THE [OOP SCHOOL LIBRARY]. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://img.shields.io/badge/Microverse-blueviolet) 2 | 3 | # OOP SCHOOL LIBRARY 4 | 5 | > This project is about learning how to handle Classes and Objects in Ruby. 6 | 7 | ## Built With 8 | 9 | - Ruby 10 | 11 | ## Getting Started 12 | 13 | Check the following instructions to install and use the project in you local machine! 14 | ### Prerequisites 15 | 16 | To begin with, you need to be able to use the **ruby** command, if you don't have it you can install it using any of these commands: 17 | 18 | **MacOS** 19 | 20 | ``` 21 | brew install rbenv ruby-build 22 | # Add rbenv to bash so that it loads every time you open a terminal 23 | echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile 24 | source ~/.bash_profile 25 | 26 | # Install Ruby 27 | rbenv install 3.0.1 28 | rbenv global 3.0.1 29 | ruby -v 30 | ``` 31 | 32 | **Ubuntu** 33 | 34 | ``` 35 | git clone https://github.com/rbenv/rbenv.git ~/.rbenv 36 | echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc 37 | echo 'eval "$(rbenv init -)"' >> ~/.bashrc 38 | exec $SHELL 39 | 40 | git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build 41 | echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc 42 | exec $SHELL 43 | 44 | rbenv install 3.0.1 45 | rbenv global 3.0.1 46 | ruby -v 47 | ``` 48 | 49 | **Windows** 50 | 51 | Use **[WSL](https://docs.microsoft.com/en-us/windows/wsl/about)** 52 | 53 | ### Setup 54 | 55 | Once you have installed **ruby** you need to clone this project's repository, use this command in your terminal: 56 | 57 | 58 | ``` 59 | git clone https://github.com/Yothu/oop-school-library.git 60 | cd /oop-school-library 61 | ``` 62 | ### Usage 63 | 64 | To use run the decode method use this command: 65 | 66 | ``` 67 | ruby ./main.rb 68 | ``` 69 | ## Author 70 | 71 | 👤 David Vergaray 72 | 73 | - GitHub: [@Yothu](https://github.com/Yothu) 74 | - Twiter: [@Daivhy](https://twitter.com/Daivhy) 75 | - LinkedIn: [David Vergaray](https://www.linkedin.com/in/david-vergaray-almontes-051a11127/) 76 | 77 | ## Colaborators 78 | 79 | 👤 **Aime Malaika** 80 | - GitHub: [@aimemalaika](https://github.com/aimemalaika) 81 | - Twitter: [@aimemalaika](https://twitter.com/Aime_Malaika) 82 | - LinkedIn: [aimemalaika](https://linkedin.com/in/aimemalaika) 83 | 84 | ## Show your support 85 | 86 | Give a ⭐️ if you like this project! 87 | 88 | ## 📝 License 89 | 90 | This project is [MIT](./MIT.md) licensed. 91 | -------------------------------------------------------------------------------- /book.rb: -------------------------------------------------------------------------------- 1 | # Book class 2 | class Book 3 | attr_accessor :title, :author, :rentals, :id 4 | 5 | def initialize(title, author, id = Time.now.to_f.to_s) 6 | @id = id 7 | @title = title 8 | @author = author 9 | @rentals = [] 10 | end 11 | 12 | def add_rental(date, person) 13 | Rental.new(date, person, self) 14 | end 15 | 16 | def return_rentals_ids 17 | ids = [] 18 | rentals.each { |rental| ids << rental.id } 19 | ids 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /books.json: -------------------------------------------------------------------------------- 1 | {"id":"1649871817.3842483","title":"the fall","author":"robat","rentals":["1649882928.5868337","1649882937.4723427"]} 2 | -------------------------------------------------------------------------------- /capitalize_decorator.rb: -------------------------------------------------------------------------------- 1 | require './decorator' 2 | 3 | # CapitalizeDecorator class 4 | class CapitalizeDecorator < Decorator 5 | def correct_name 6 | @nameable.correct_name.capitalize 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /classroom.rb: -------------------------------------------------------------------------------- 1 | # Classroom class 2 | class Classroom 3 | attr_accessor :label, :students 4 | 5 | def initialize(label) 6 | @label = label 7 | @students = [] 8 | end 9 | 10 | def add_student(student) 11 | @students << student unless @students.include?(student) 12 | student.classroom = self 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /decorator.rb: -------------------------------------------------------------------------------- 1 | require './nameable' 2 | 3 | # Decorator class 4 | class Decorator < Nameable 5 | def initialize(nameable) 6 | super() 7 | @nameable = nameable 8 | end 9 | 10 | def correct_name 11 | @nameable.correct_name 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /input.rb: -------------------------------------------------------------------------------- 1 | class Input 2 | def user_input 3 | gets.chomp 4 | end 5 | 6 | def index(array) 7 | num = 0 8 | loop do 9 | num = user_input.to_i 10 | break if num.instance_of?(Integer) && num >= 0 && num < array.length 11 | end 12 | num 13 | end 14 | 15 | def natural_int 16 | num = 0 17 | loop do 18 | print yield 19 | num = user_input.to_i 20 | break if num.instance_of?(Integer) && num.positive? 21 | end 22 | num 23 | end 24 | 25 | def text 26 | print yield 27 | user_input 28 | end 29 | 30 | def y_n 31 | response = '' 32 | loop do 33 | print yield 34 | response = user_input 35 | break if response.upcase == 'Y' || response.upcase == 'N' 36 | end 37 | return true if response.upcase == 'Y' 38 | return false if response.upcase == 'N' 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /main.rb: -------------------------------------------------------------------------------- 1 | require './input' 2 | require './options' 3 | require './main_menu' 4 | 5 | # App class 6 | class App 7 | attr_accessor :input, :options 8 | 9 | def initialize 10 | @input = Input.new 11 | @options = Options.new 12 | end 13 | 14 | def run 15 | puts 'Welcome to School Library App!' 16 | options.obtain_data 17 | loop do 18 | main_menu 19 | menu_option = input.user_input.to_i 20 | running = options.category_menu(menu_option) 21 | 22 | break unless running 23 | end 24 | options.save_data 25 | end 26 | end 27 | 28 | def main 29 | app = App.new 30 | app.run 31 | end 32 | 33 | main 34 | -------------------------------------------------------------------------------- /main_menu.rb: -------------------------------------------------------------------------------- 1 | def main_menu 2 | puts 'Please choose an option by entering a number:' 3 | puts '1 - List all books' 4 | puts '2 - List all people' 5 | puts '3 - Create a person' 6 | puts '4 - Create a book' 7 | puts '5 - Create a rental' 8 | puts '6 - List all rentals for a given person id' 9 | puts '7 - Exit' 10 | end 11 | -------------------------------------------------------------------------------- /manage_books.rb: -------------------------------------------------------------------------------- 1 | require_relative 'book' 2 | require_relative 'input' 3 | 4 | class BookList 5 | attr_accessor :books, :input 6 | 7 | def initialize 8 | @books = [] 9 | @input = Input.new 10 | end 11 | 12 | def return_books_array 13 | books 14 | end 15 | 16 | def create_book 17 | title = input.text { 'Title: ' } 18 | author = input.text { 'Author: ' } 19 | 20 | new_book = Book.new(title, author) 21 | 22 | puts 'Book created successfully' if new_book.instance_of?(Book) 23 | 24 | add_book(new_book) 25 | end 26 | 27 | def add_book(book) 28 | books << book unless books.include?(book) 29 | end 30 | 31 | def print_books 32 | books.each { |book| puts "Title: \"#{book.title}\", Author: \"#{book.author}\"" } 33 | puts 34 | end 35 | 36 | def return_by_id(id) 37 | books.each { |book| return book if book.id.to_s == id.to_s } 38 | end 39 | 40 | def list_books_indexes 41 | puts 'Select a book from the following list by number' 42 | index = 0 43 | books.each do |book| 44 | puts "#{index}) Title: \"#{book.title}\", Author: #{book.author}" 45 | index += 1 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /manage_persons.rb: -------------------------------------------------------------------------------- 1 | require './person' 2 | require './student' 3 | require './teacher' 4 | require './input' 5 | 6 | class ManagePerson 7 | attr_accessor :persons, :input 8 | 9 | def initialize 10 | @persons = [] 11 | @input = Input.new 12 | end 13 | 14 | def return_persons_array 15 | persons 16 | end 17 | 18 | def list_persons 19 | persons.each { |person| puts "[#{person.class}] Name: #{person.name}, ID: #{person.id}, Age: #{person.age}" } 20 | puts 21 | end 22 | 23 | def create_teacher 24 | age = input.natural_int { 'Age: ' } 25 | name = input.text { 'Name: ' } 26 | specialization = input.text { 'Specialization: ' } 27 | 28 | new_teacher = Teacher.new(specialization, age, name) 29 | puts 'Person created successfully' if new_teacher.instance_of?(Teacher) 30 | persons << new_teacher 31 | end 32 | 33 | def create_student 34 | age = input.natural_int { 'Age: ' } 35 | name = input.text { 'Name: ' } 36 | permission = input.y_n { 'Has parent permission? [Y/N]: ' } 37 | 38 | new_student = Student.new(age, name, permission) 39 | puts 'Person created successfully' if new_student.instance_of?(Student) 40 | persons << new_student 41 | end 42 | 43 | def create_person 44 | print 'Do you want to create a student (1) or a teacher (2)? [Input the number]:' 45 | add_person_option = input.user_input 46 | case add_person_option 47 | when '1' # Student 48 | create_student 49 | when '2' # Teacher 50 | create_teacher 51 | end 52 | end 53 | 54 | def add_person(person) 55 | persons << person 56 | end 57 | 58 | def person_by_id 59 | print 'ID of person: ' 60 | id = input.user_input 61 | persons.each { |person| return person if person.id.to_s == id.to_s } 62 | end 63 | 64 | def return_by_id(id) 65 | persons.each { |person| return person if person.id.to_s == id.to_s } 66 | end 67 | 68 | def list_persons_indexes 69 | puts 'Select a person from the following list by number (not id)' 70 | index = 0 71 | persons.each do |person| 72 | puts "#{index}) [#{person.class}] Name: #{person.name}, ID: #{person.id}, Age: #{person.age}" 73 | index += 1 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /manage_rentals.rb: -------------------------------------------------------------------------------- 1 | require './rental' 2 | require './input' 3 | 4 | class ManageRentals 5 | attr_accessor :rentals, :input 6 | 7 | def initialize 8 | @rentals = [] 9 | @input = Input.new 10 | end 11 | 12 | def create_rental(book_list, person_list) 13 | book_list.list_books_indexes 14 | book = book_list.return_books_array[input.index(book_list.return_books_array)] 15 | 16 | person_list.list_persons_indexes 17 | person = person_list.return_persons_array[input.index(person_list.return_persons_array)] 18 | 19 | date = input.text { 'Date: ' } 20 | 21 | new_rental = Rental.new(date, person, book) 22 | puts 'Rental created successfully' if new_rental.instance_of?(Rental) 23 | 24 | rentals << new_rental 25 | end 26 | 27 | def add_rental(rental) 28 | rentals << rental 29 | end 30 | 31 | def list_rentals_by_person_id(person_list) 32 | person = person_list.person_by_id 33 | 34 | return unless person.instance_of?(Student) || person.instance_of?(Teacher) 35 | 36 | puts 'Rentals:' 37 | person.rentals.each do |rental| 38 | puts "Date: #{rental.date}, Book: \"#{rental.book.title}\" by #{rental.book.author}" 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /nameable.rb: -------------------------------------------------------------------------------- 1 | # Nameable class 2 | class Nameable 3 | def correct_name 4 | raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /obtain_data.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | require './book' 3 | require './teacher' 4 | require './student' 5 | 6 | module ObtainData 7 | def create_nonexistent_files 8 | files_names = ['persons.json', 'books.json', 'rentals.json'] 9 | files_names.each do |file_name| 10 | File.new(file_name, 'w') unless File.exist?(file_name) 11 | end 12 | end 13 | 14 | def from_json_to_obj(line) 15 | JSON.parse(line) 16 | end 17 | 18 | def obtain_books 19 | file_path = 'books.json' 20 | if File.exist?(file_path) 21 | File.readlines(file_path).each do |line| 22 | book_data = from_json_to_obj(line) 23 | new_book = Book.new(book_data['title'], book_data['author'], book_data['id']) 24 | book_list.add_book(new_book) 25 | end 26 | else 27 | File.new('books.json', 'w') 28 | end 29 | end 30 | 31 | def obtain_persons 32 | file_path = 'persons.json' 33 | if File.exist?(file_path) 34 | File.readlines(file_path).each do |line| 35 | person_data = from_json_to_obj(line) 36 | case person_data['type'] 37 | when 'Student' 38 | new_person = Student.new(person_data['age'], person_data['name'], person_data['parent_permission'], 39 | person_data['id']) 40 | when 'Teacher' 41 | new_person = Teacher.new(person_data['specialization'], person_data['age'], person_data['name'], true, 42 | person_data['id']) 43 | end 44 | person_list.add_person(new_person) 45 | end 46 | else 47 | File.new('persons.json', 'w') 48 | end 49 | end 50 | 51 | def obtain_rentals 52 | file_path = 'rentals.json' 53 | if File.exist?(file_path) 54 | File.readlines(file_path).each do |line| 55 | rentals_data = from_json_to_obj(line) 56 | book = book_list.return_by_id(rentals_data['book']) 57 | person = person_list.return_by_id(rentals_data['person']) 58 | new_rental = Rental.new(rentals_data['date'], person, book, rentals_data['id']) 59 | rental_list.add_rental(new_rental) 60 | end 61 | else 62 | File.new('rentals.json', 'w') 63 | end 64 | end 65 | 66 | def obtain_data 67 | create_nonexistent_files 68 | obtain_books 69 | obtain_persons 70 | obtain_rentals 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /options.rb: -------------------------------------------------------------------------------- 1 | require './manage_books' 2 | require './manage_persons' 3 | require './manage_rentals' 4 | require './save_data' 5 | require './obtain_data' 6 | 7 | class Options 8 | include SaveData 9 | include ObtainData 10 | 11 | attr_accessor :book_list, :rental_list, :person_list 12 | 13 | def initialize 14 | @book_list = BookList.new 15 | @rental_list = ManageRentals.new 16 | @person_list = ManagePerson.new 17 | end 18 | 19 | def books_and_persons_menus(option) 20 | book_list.print_books if option == 1 21 | person_list.list_persons if option == 2 22 | person_list.create_person if option == 3 23 | book_list.create_book if option == 4 24 | end 25 | 26 | def rentals_menus(option) 27 | rental_list.create_rental(book_list, person_list) if option == 5 28 | rental_list.list_rentals_by_person_id(person_list) if option == 6 29 | end 30 | 31 | def category_menu(menu_option) 32 | running = true 33 | if menu_option.positive? && menu_option <= 4 34 | books_and_persons_menus(menu_option) 35 | elsif menu_option >= 5 && menu_option <= 6 36 | rentals_menus(menu_option) 37 | elsif menu_option == 7 38 | running = false 39 | puts 'Thank you for using this app!' 40 | end 41 | running 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /person.rb: -------------------------------------------------------------------------------- 1 | require './nameable' 2 | require './rental' 3 | 4 | # Person Class 5 | class Person < Nameable 6 | attr_reader :id 7 | attr_accessor :name, :age, :parent_permission, :rentals 8 | 9 | def initialize(age, name = 'Unknown', parent_permission = 'true', id = Time.now.to_f.to_s) 10 | super() 11 | @id = id 12 | @name = name 13 | @age = age 14 | @parent_permission = parent_permission 15 | @rentals = [] 16 | end 17 | 18 | def of_age? 19 | return true if @age >= 18 20 | 21 | false 22 | end 23 | 24 | def can_use_services? 25 | return true if of_age? || @parent_permission == 'true' 26 | 27 | false 28 | end 29 | 30 | def correct_name 31 | @name 32 | end 33 | 34 | def add_rental(date, book) 35 | Rental.new(date, self, book) 36 | end 37 | 38 | def return_rentals_ids 39 | ids = [] 40 | rentals.each { |rental| ids << rental.id } 41 | ids 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /persons.json: -------------------------------------------------------------------------------- 1 | {"id":"1649871772.7865512","type":"Student","name":"s1","age":15,"parent_permission":true} 2 | {"id":"1649871783.9507306","type":"Teacher","name":"t2","age":45,"specialization":"sleep"} 3 | {"id":"1649872411.319786","type":"Teacher","name":"das","age":43,"specialization":"zxc"} 4 | -------------------------------------------------------------------------------- /rental.rb: -------------------------------------------------------------------------------- 1 | # Rental class 2 | class Rental 3 | attr_accessor :date, :person, :book, :id 4 | 5 | def initialize(date, person, book, id = Time.now.to_f.to_s) 6 | @id = id 7 | @date = date 8 | 9 | @person = person 10 | person.rentals << self unless person.rentals.include?(self) 11 | 12 | @book = book 13 | book.rentals << self unless book.rentals.include?(self) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /rentals.json: -------------------------------------------------------------------------------- 1 | {"id":"1649882928.5868337","date":"12","person":"1649871772.7865512","book":"1649871817.3842483"} 2 | {"id":"1649882937.4723427","date":"2","person":"1649872411.319786","book":"1649871817.3842483"} 3 | -------------------------------------------------------------------------------- /save_data.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | module SaveData 4 | def transform_to_json(line) 5 | JSON.generate(line) 6 | end 7 | 8 | def preapare_person_line(person) 9 | line = { id: person.id, 10 | type: person.class, 11 | name: person.name, 12 | age: person.age } 13 | line['parent_permission'] = person.parent_permission if person.instance_of?(Student) 14 | line['specialization'] = person.specialization if person.instance_of?(Teacher) 15 | line 16 | end 17 | 18 | def save_persons 19 | File.truncate('persons.json', 0) 20 | person_list.persons.each do |person| 21 | line = preapare_person_line(person) 22 | json_line = transform_to_json(line) 23 | File.write('persons.json', "#{json_line}\n", mode: 'a') 24 | end 25 | end 26 | 27 | def save_books 28 | File.truncate('books.json', 0) 29 | book_list.books.each do |book| 30 | line = { id: book.id, 31 | title: book.title, 32 | author: book.author, 33 | rentals: book.return_rentals_ids } 34 | 35 | json_line = transform_to_json(line) 36 | File.write('books.json', "#{json_line}\n", mode: 'a') 37 | end 38 | end 39 | 40 | def save_rentals 41 | File.truncate('rentals.json', 0) 42 | rental_list.rentals.each do |rental| 43 | line = { id: rental.id, 44 | date: rental.date, 45 | person: rental.person.id, 46 | book: rental.book.id } 47 | json_line = transform_to_json(line) 48 | File.write('rentals.json', "#{json_line}\n", mode: 'a') 49 | end 50 | end 51 | 52 | def save_data 53 | save_persons 54 | save_books 55 | save_rentals 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /solver.rb: -------------------------------------------------------------------------------- 1 | class Solver 2 | def factorial(num) 3 | raise StandardError if num.negative? 4 | return 1 if num.zero? 5 | 6 | i = num - 1 7 | while i.positive? 8 | num *= i 9 | i -= 1 10 | end 11 | num 12 | end 13 | 14 | def reverse(str) 15 | str.reverse 16 | end 17 | 18 | def fizzbuzz(num) 19 | return 'fizzbuzz' if (num % 3).zero? && (num % 5).zero? 20 | return 'fizz' if (num % 3).zero? 21 | return 'buzz' if (num % 5).zero? 22 | 23 | num.to_s 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/book_spec.rb: -------------------------------------------------------------------------------- 1 | require './book' 2 | require './person' 3 | require './rental' 4 | 5 | describe Book do 6 | describe '#initialize' do 7 | it 'should create initialize a new book' do 8 | book = Book.new('The Fall', 'Marc Laid') 9 | 10 | expect(book).to be_a Book 11 | end 12 | 13 | it 'should have a title and author' do 14 | book = Book.new('A white road', 'Fer Von Amer') 15 | 16 | expect(book.title).to eq 'A white road' 17 | expect(book.author).to eq 'Fer Von Amer' 18 | end 19 | end 20 | 21 | describe '#add_rental' do 22 | it 'should add a rental to the rentals array' do 23 | book = Book.new('The Universe', 'Isaac Asimov') 24 | person = Person.new(47, 'Miluzaus') 25 | 26 | book.add_rental('29/02/2001', person) 27 | 28 | expect(book.rentals.length).to eq 1 29 | end 30 | end 31 | 32 | describe '#return_rentals_ids' do 33 | it 'should return an array of rental ids' do 34 | book = Book.new('Advanced Javascript', 'Me') 35 | person = Person.new(12, 'Me') 36 | 37 | book.add_rental('01/12/2010', person) 38 | 39 | expect(book.return_rentals_ids).to be_a Array 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /spec/classroom_spec.rb: -------------------------------------------------------------------------------- 1 | require './classroom' 2 | 3 | describe Classroom do 4 | describe '#initialize' do 5 | it 'should be a Classroom object' do 6 | classroom = Classroom.new('English') 7 | expect(classroom).to be_a(Classroom) 8 | end 9 | it 'should have a label' do 10 | classroom = Classroom.new('English') 11 | expect(classroom.label).to eq('English') 12 | end 13 | end 14 | 15 | describe '#add_student' do 16 | it 'should add a student to the classroom' do 17 | classroom = Classroom.new('History') 18 | student = Student.new('Rort', 32) 19 | classroom.add_student(student) 20 | expect(classroom.students).to include(student) 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/corrector_spec.rb: -------------------------------------------------------------------------------- 1 | require './capitalize_decorator' 2 | require './person' 3 | 4 | describe CapitalizeDecorator do 5 | describe '#correct_name' do 6 | it 'should capitalize the name' do 7 | person = Person.new(54, 'brian') 8 | decorator = CapitalizeDecorator.new(person) 9 | 10 | expect(decorator.correct_name).to eq('Brian') 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/person_spec.rb: -------------------------------------------------------------------------------- 1 | require './person' 2 | require './book' 3 | 4 | describe Person do 5 | describe '#initialize' do 6 | it 'should initialize a new person' do 7 | person = Person.new(12, 'Johnny') 8 | expect(person).to be_a Person 9 | end 10 | 11 | it 'should have a name' do 12 | person = Person.new(32, 'Johnny') 13 | expect(person.name).to be_a String 14 | end 15 | 16 | it 'should have an age' do 17 | person = Person.new(20, 'Johnny') 18 | expect(person.age).to be_a Integer 19 | end 20 | end 21 | 22 | describe '#of_age?' do 23 | it 'should return true if the person is of age' do 24 | person = Person.new(18, 'Johnny') 25 | expect(person.of_age?).to be true 26 | end 27 | 28 | it 'should return false if the person is not of age' do 29 | person = Person.new(17, 'Johnny') 30 | expect(person.of_age?).to be false 31 | end 32 | end 33 | 34 | describe '#can_use_services?' do 35 | it 'should return true if the person is of age or has a parent permission' do 36 | person = Person.new(16, 'Johnny') 37 | expect(person.can_use_services?).to be true 38 | end 39 | 40 | it 'should return false if the person is not of age and does not have a parent permission' do 41 | person = Person.new(16, 'Johnny', 'false') 42 | expect(person.can_use_services?).to be false 43 | end 44 | end 45 | 46 | describe '#add_rental' do 47 | it 'should add a rental to the rentals array' do 48 | person = Person.new(17, 'Johnny') 49 | book = Book.new('The Hobbit', 'Tolkien') 50 | person.add_rental('01/01/2017', book) 51 | expect(person.rentals.length).to eq 1 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /spec/rentals_spec.rb: -------------------------------------------------------------------------------- 1 | describe Rental do 2 | describe '#initialize' do 3 | it 'should be a Rental object' do 4 | person = Person.new(32, 'Brian') 5 | book = Book.new('Java', 'Marion') 6 | rental = Rental.new('13/04/2022', person, book) 7 | expect(rental).to be_a(Rental) 8 | end 9 | it 'should have a date' do 10 | person = Person.new(32, 'Lisa') 11 | book = Book.new('The Hobbit', 'Miguel') 12 | rental = Rental.new('12/5/2022', person, book) 13 | expect(rental.date).to eq('12/5/2022') 14 | end 15 | it 'should have a person' do 16 | person = Person.new(32, 'Barbara') 17 | book = Book.new('The Hobbit', 'James') 18 | rental = Rental.new('01/01/2022', person, book) 19 | expect(rental.person.name).to eq('Barbara') 20 | end 21 | it 'should have a book' do 22 | person = Person.new(32, 'Julia') 23 | book = Book.new('The white rose', 'Claudia') 24 | rental = Rental.new('12/12/2022', person, book) 25 | expect(rental.book.title).to eq('The white rose') 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /spec/solver_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../solver' 2 | 3 | describe Solver do 4 | describe '#factorial' do 5 | it 'the factorial of 3 should be 6' do 6 | solver = Solver.new 7 | result = solver.factorial(3) 8 | 9 | expect(result).to eq(6) 10 | end 11 | 12 | it 'the factorial of 2 should be 2' do 13 | solver = Solver.new 14 | result = solver.factorial(2) 15 | 16 | expect(result).to eq(2) 17 | end 18 | 19 | it 'the factorial of 1 should be 1' do 20 | solver = Solver.new 21 | result = solver.factorial(1) 22 | 23 | expect(result).to eq(1) 24 | end 25 | 26 | it 'the factorial of 0 should be 1' do 27 | solver = Solver.new 28 | result = solver.factorial(0) 29 | 30 | expect(result).to eq(1) 31 | end 32 | 33 | it 'A negative factorial should raise an execption' do 34 | subject = Solver.new 35 | expect { subject.factorial(-1) }.to raise_error(StandardError) 36 | end 37 | end 38 | 39 | describe '#reverse' do 40 | it 'Should return the reverse of Hello, olleh' do 41 | solver = Solver.new 42 | result = solver.reverse('hello') 43 | expect(result).to eq('olleh') 44 | end 45 | 46 | it 'should return the reverse of Aime' do 47 | solver = Solver.new 48 | result = solver.reverse('Aime') 49 | expect(result).to eq('emiA') 50 | end 51 | 52 | it 'should return the reverse of "Node.js is different from Ruby on Rails"' do 53 | solver = Solver.new 54 | result = solver.reverse('Node.js is different from Ruby on Rails') 55 | expect(result).to eq('sliaR no ybuR morf tnereffid si sj.edoN') 56 | end 57 | end 58 | 59 | describe '#fizzbuzz' do 60 | it 'should return fizz when gets a 3' do 61 | solver = Solver.new 62 | result = solver.fizzbuzz(3) 63 | 64 | expect(result).to eql('fizz') 65 | end 66 | 67 | it 'should return buzz when gets a 5' do 68 | solver = Solver.new 69 | result = solver.fizzbuzz(5) 70 | 71 | expect(result).to eql('buzz') 72 | end 73 | 74 | it 'should return fizzbuzz when gets a 15' do 75 | solver = Solver.new 76 | result = solver.fizzbuzz(15) 77 | 78 | expect(result).to eql('fizzbuzz') 79 | end 80 | 81 | it 'should return fizz when gets a 6' do 82 | solver = Solver.new 83 | result = solver.fizzbuzz(6) 84 | 85 | expect(result).to eql('fizz') 86 | end 87 | 88 | it 'should return buzz when gets a 10' do 89 | solver = Solver.new 90 | result = solver.fizzbuzz(10) 91 | 92 | expect(result).to eql('buzz') 93 | end 94 | 95 | it 'should return "7" when gets a 7' do 96 | solver = Solver.new 97 | result = solver.fizzbuzz(7) 98 | 99 | expect(result).to eql('7') 100 | end 101 | 102 | it 'should return fizzbuzz when gets a 30' do 103 | solver = Solver.new 104 | result = solver.fizzbuzz(30) 105 | 106 | expect(result).to eql('fizzbuzz') 107 | end 108 | 109 | it 'should return fizzbuzz when gets a 0' do 110 | solver = Solver.new 111 | result = solver.fizzbuzz(0) 112 | 113 | expect(result).to eql('fizzbuzz') 114 | end 115 | 116 | it 'should return "-1" when gets a -1' do 117 | solver = Solver.new 118 | result = solver.fizzbuzz(-1) 119 | 120 | expect(result).to eql('-1') 121 | end 122 | end 123 | end 124 | -------------------------------------------------------------------------------- /spec/student_spec.rb: -------------------------------------------------------------------------------- 1 | require './student' 2 | require './classroom' 3 | 4 | describe Student do 5 | describe '#add_classroom' do 6 | it 'should add a classroom to the students array' do 7 | student = Student.new(15, 'John') 8 | classroom = Classroom.new('Math') 9 | student.add_classroom(classroom) 10 | expect(student.classroom).to eq classroom 11 | end 12 | end 13 | 14 | describe '#play_hooky' do 15 | it 'should return "¯\(ツ)/¯"' do 16 | student = Student.new(12, 'Paul') 17 | expect(student.play_hooky).to eq '¯\(ツ)/¯' 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/teacher_spec.rb: -------------------------------------------------------------------------------- 1 | require './teacher' 2 | 3 | describe Teacher do 4 | describe '#initialize' do 5 | it 'should create a new teacher' do 6 | teacher = Teacher.new('History', 45, 'Leslie') 7 | 8 | expect(teacher).to be_a Teacher 9 | end 10 | 11 | it 'should have a name and age' do 12 | teacher = Teacher.new('Physics', 32, 'Rort') 13 | 14 | expect(teacher.age).to eq 32 15 | expect(teacher.name).to eq 'Rort' 16 | end 17 | 18 | it 'should have a specialization' do 19 | teacher = Teacher.new('Math', 32, 'Mira') 20 | 21 | expect(teacher.specialization).to eq 'Math' 22 | end 23 | end 24 | 25 | describe '#can_use_services?' do 26 | it 'should always return true' do 27 | teacher = Teacher.new(16, 'Mickey', 'false') 28 | 29 | expect(teacher.can_use_services?).to be true 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /student.rb: -------------------------------------------------------------------------------- 1 | require './person' 2 | 3 | # Student Class 4 | class Student < Person 5 | attr_accessor :classroom 6 | 7 | def initialize(age, name = 'Unknown', parent_permission = 'true', id = Time.now.to_f.to_s) 8 | super(age, name, parent_permission, id) 9 | end 10 | 11 | def add_classroom(classroom) 12 | @classroom = classroom 13 | classroom.students << self unless classroom.students.include?(self) 14 | end 15 | 16 | def play_hooky 17 | '¯\(ツ)/¯' 18 | end 19 | 20 | public :play_hooky 21 | end 22 | -------------------------------------------------------------------------------- /teacher.rb: -------------------------------------------------------------------------------- 1 | require './person' 2 | 3 | # Teacher Class 4 | class Teacher < Person 5 | attr_accessor :specialization 6 | 7 | def initialize(specialization, age, name = 'Unknown', parent_permission = 'true', id = Time.now.to_f.to_s) 8 | super(age, name, parent_permission, id) 9 | @specialization = specialization 10 | end 11 | 12 | def can_use_services? 13 | true 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /trimmer_decorator.rb: -------------------------------------------------------------------------------- 1 | require './decorator' 2 | 3 | # TrimmerDecorator class 4 | class TrimmerDecorator < Decorator 5 | def correct_name 6 | @nameable.correct_name.slice(0, 10) if @nameable.correct_name.length > 10 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /user_input.rb: -------------------------------------------------------------------------------- 1 | def user_input 2 | gets.chomp 3 | end 4 | --------------------------------------------------------------------------------