elevatore 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c87727f4f5846a3ae7f62a2ebd65b8f86a9f0c6f
4
+ data.tar.gz: c99a3bbb2283f256d99fc4e4754326f5798cc4fd
5
+ SHA512:
6
+ metadata.gz: 927f8c331327bde592588df1dfb9c1319b5887ac9529238831b49ce6a2c62f0f2d53a354649377d35596e639cbf749d80a49d6744babf69486a689b80eb493b7
7
+ data.tar.gz: 27c667e23ebdd1ca33b36b3ec56d6761b14d6151d02567223ee6ae2269815c574d2039d8cb91445bca80de5ab578fe714132472af5f5b8c657f6346cfc487646
@@ -0,0 +1,50 @@
1
+ continue
2
+ exit
3
+ continue
4
+ ARGV.include?('-v')
5
+ continue
6
+ opts
7
+ exit
8
+ opts.first
9
+ opts
10
+ exit
11
+ opts.class
12
+ opts
13
+ opst
14
+ exit
15
+ line
16
+ person
17
+ exit
18
+ opts = JSON.parse(opts).map(&:symbolize_keys)
19
+ exit
20
+ opts
21
+ exit
22
+ person
23
+ peson
24
+ exit
25
+ opts.class
26
+ opts
27
+ opst
28
+ exit
29
+ opts
30
+ continue
31
+ person == "exit\n"
32
+ person
33
+ perosn
34
+ continue
35
+ person
36
+ exit
37
+ gets
38
+ exit
39
+ continue
40
+ exit
41
+ ARGV
42
+ exit
43
+ ARGV.size
44
+ ARGV
45
+ exit
46
+ ARGV
47
+ exit
48
+ opts
49
+ exit
50
+ opts
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.15.2
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at ervalhous@hotmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in elevatore.gemspec
6
+ gemspec
7
+ gem 'activesupport'
8
+ gem 'byebug', :groups => [:development, :test]
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Fernando Bellincanta
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,58 @@
1
+ # Elevatore
2
+
3
+ Welcome to Elevatore. I am an intelligent elevator, programmed to get a bunch of people that schedule their trips inside of me through STDIN or file input. I am written in Ruby, so you have to [get it somehow](https://rvm.io/rvm/install) to execute me.
4
+
5
+ ## Installation
6
+
7
+ With Ruby installed in you machine, clone this repository, navigate to it's folder and then execute:
8
+
9
+ $ bundle
10
+ $ bundle exec rake install
11
+
12
+ ## Usage
13
+
14
+ $ bundle exec elevatore
15
+
16
+ `-q` - Output to STDOUT only the travel times.
17
+ `-v` - Check my version out.
18
+ `-h` - Take a look at my help menu.
19
+
20
+ You have 4 options to make people travel with me.
21
+
22
+ *Executing command without arguments:*
23
+ - This way you will use STDIN to input people until you type 'exit' or interrupt execution(CTRL-C), so that I can finally take them home.
24
+
25
+ *Executing command with arguments:*
26
+ - You can pass file paths with one person per line
27
+ - You can pass people as a formatted string argument
28
+ - You can pass people as a JSON array with people objects inside
29
+
30
+ To make it easier for me to understand you please catalog yourselves with the following information:
31
+ `attribute_1` - Time in minutes that you plan to begin your travel
32
+ `attribute_2` - A numeric identification, to make it easier for me to know who you are
33
+ `attribute_3` - From which floor I should pick you up
34
+ `attribute_4` - Which floor do you want to go?
35
+
36
+ When using STDIN or strings in files or arguments, each person should be formatted as follows(without curly brackets):
37
+ '`attribute_1`m P`attribute_2` `attribute_3` `attribute_4`'
38
+
39
+ When using JSON formatting follow a schema like:
40
+ [{enter_at: `attribute_1`, id: `attribute_2`, from: `attribute_3`, to: `attribute_4`}]
41
+
42
+ ## Development
43
+
44
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
45
+
46
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
47
+
48
+ ## Contributing
49
+
50
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/elevatore. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
51
+
52
+ ## License
53
+
54
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
55
+
56
+ ## Code of Conduct
57
+
58
+ Everyone interacting in the Elevatore project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/elevatore/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "elevatore"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,39 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "elevatore/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "elevatore"
8
+ spec.version = Elevatore::VERSION
9
+ spec.authors = ["Fernando Bellincanta"]
10
+ spec.email = ["ervalhous@hotmail.com"]
11
+
12
+ spec.summary = %q{Elevatore it is an exercise at elevator's behavior.}
13
+ spec.description = %q{Elevatore assumes you have an elevator in a 10 level
14
+ building, and the time between levels is 0.1 minutes.
15
+ The time it takes to a person to enter the elevator is
16
+ considered 0.}
17
+ spec.homepage = "https://github.com/ErvalhouS/fernando-bellincanta"
18
+ spec.license = "MIT"
19
+
20
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
21
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
22
+ if spec.respond_to?(:metadata)
23
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
24
+ else
25
+ raise "RubyGems 2.0 or newer is required to protect against " \
26
+ "public gem pushes."
27
+ end
28
+
29
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
30
+ f.match(%r{^(test|spec|features)/})
31
+ end
32
+ spec.bindir = "exe"
33
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
+ spec.require_paths = ["lib"]
35
+
36
+ spec.add_development_dependency "bundler", "~> 1.15"
37
+ spec.add_development_dependency "rake", "~> 10.0"
38
+ spec.add_development_dependency "rspec", "~> 3.0"
39
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/elevatore/cli"
4
+ Elevatore::CLI.run!
@@ -0,0 +1,75 @@
1
+ require_relative "elevatore/version"
2
+ require_relative "elevatore/person"
3
+ require_relative "elevatore/elevator"
4
+ require "active_support/core_ext/hash/except"
5
+ require "byebug"
6
+ require "json"
7
+
8
+ module Elevatore
9
+ LOWER_LEVEL=0
10
+ TOP_LEVEL=10
11
+ SPEED=0.1
12
+ DIRECTION_UP=1.freeze
13
+ DIRECTION_DOWN=-1.freeze
14
+
15
+ def self.calling opts=[]
16
+ return nil if opts == []
17
+ @opts = opts
18
+ enforce_rules! @opts
19
+ @elevator = Elevatore::Elevator.new(people: build_people(@opts))
20
+ @elevator.print_exit_times
21
+ end
22
+
23
+ private
24
+ def self.build_people opts
25
+ (opts.class==String ? parse_string(opts) : parse_array(opts))
26
+ end
27
+
28
+ def self.parse_array opts
29
+ people=[]
30
+ opts.map.each do |person|
31
+ people << Elevatore::Person.new(person)
32
+ end
33
+ people
34
+ end
35
+
36
+ def self.parse_string opts
37
+ people=[]
38
+ opts.split("\n".freeze).each do |line|
39
+ person = line.split(" ")
40
+ people << Elevatore::Person.new(enter_at: person[0].chomp("m").to_f,
41
+ id: person[1][1..-1].to_i,
42
+ from: person[2].to_i,
43
+ to: person[3].to_i)
44
+ end
45
+ people
46
+ end
47
+
48
+ def self.enforce_rules! opts
49
+ begin
50
+ @opts = JSON.parse(opts)
51
+ ensure
52
+ unless @opts.class==String || (@opts.class==Array && !@opts.any?{|hash| hash.class!=Hash })
53
+ raise ArgumentError.new('Input should be either a String or a Array with Hashes of attributes')
54
+ end
55
+ if @opts.class==String
56
+ person_id = @opts.split(" ".freeze)[1].chomp("P")
57
+ person_from = @opts.split(" ".freeze)[1].chomp("P")
58
+ person_to = @opts.split(" ".freeze)[2]
59
+ person_enter_at = @opts.split(" ".freeze)[3]
60
+ if !@opts.match?(/^(([0-9]+(\.[0-9]+)?m\ +P[0-9]+\ [0-9]+\ [0-9]+)\s?)+/)
61
+ raise ArgumentError.new("Error on P#{person_id}: Text lines input should follow the structure: '<MINUTE>m P<ID> <FROM> <TO>'")
62
+ end
63
+ else @opts.class==Array
64
+ @opts.each do |person|
65
+ if person.keys.sort != ["id", "from", "to", "enter_at"].sort
66
+ raise ArgumentError.new('Error on P#{person[:id]}: All hashes should contain [:id, :from, :to, :enter_at] as keys')
67
+ end
68
+ if !person.values.map(&:class).any?{|klass| klass <= Numeric }
69
+ raise ArgumentError.new("#{"Error on P"+person[:id]+": " unless person[:id].nil?}All hashes should contain numbers as values")
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,102 @@
1
+ require_relative '../elevatore'
2
+
3
+ module Elevatore
4
+ module CLI
5
+ def self.run!
6
+ welcome!
7
+ real_arguments = ARGV-['-v', '-q' , '-h']
8
+ if real_arguments.size == 0
9
+ @people = ""
10
+ stdin_welcome
11
+ get_stdin
12
+ else
13
+ real_arguments.each do |argument|
14
+ parse! argument
15
+ end
16
+ end
17
+ end
18
+
19
+ private
20
+ def self.welcome!
21
+ unless ARGV.include?('-q')
22
+ puts "\nWelcome to the Elevatore...\n\n"
23
+ if ARGV.include?('-h')
24
+ lettering
25
+ instructions
26
+ exit
27
+ elsif ARGV.include?('-v')
28
+ print "Elevatore v" + Elevatore::VERSION
29
+ exit
30
+ end
31
+ puts "Execute with -h to get help\n\n"
32
+ end
33
+ end
34
+
35
+ def self.stdin_welcome
36
+ unless ARGV.include?('-q')
37
+ puts "Input people that wants to get in through STDOIN"
38
+ puts "Press ctrl-C when you are finished, or `echo 'exit'` into STDIN."
39
+ puts "Pay attention to formatting: <Minute>m P<Person ID> <From Floor> <To Floor>"
40
+ end
41
+ end
42
+
43
+ def self.get_stdin
44
+ begin
45
+ loop do
46
+ print "> " unless ARGV.include?('-q')
47
+ person = gets
48
+ break if person == "exit\n"
49
+ @people << person
50
+ end
51
+ ensure
52
+ begin
53
+ Elevatore.calling @people
54
+ rescue ArgumentError => e
55
+ puts e.message
56
+ end
57
+ end
58
+ end
59
+
60
+ def self.parse! argument
61
+ if File.file?(argument)
62
+ Elevatore.calling open(argument).read
63
+ else
64
+ Elevatore.calling argument
65
+ end
66
+ end
67
+
68
+ def self.lettering
69
+ puts "This is a scheduling program to organize you humans to travel with me efficiently\n\n"
70
+ puts "+-+------+ +-+ +-+------+ \\-\\ /-/ /-->\\ ^-----------+ +-------+-+ +------v-¬ +--+------+"
71
+ puts "|-|------+ | | |-|------+ \\ \\ / / / /-> \\ |----+ +----v +-------|-| + ----¬ | |--|------+"
72
+ puts "| | | | | | | | | | / / \\ \\ | | | | | | | | / / | | "
73
+ puts "| +---+ | | | +---+ || || | / \\ | | | | | | | | --- / | +--+ "
74
+ puts "| +---+ | | | +---+ \\\\ // / /<------\\ \\ | | | | | | | +- < | +--+ "
75
+ puts "| | | | | | \\\\ // / /<--------\\ \\ | | | | | | | | \\ \\ | | "
76
+ puts "+--------+ +--------+ +--------+ \\v/ / / \\ \\ | | +-------|-| | | \\ \\ +---------+"
77
+ puts "+--------+ +--------+ +--------+ --> vv vv vvv +-------+-+ +--+ --> +---------+"
78
+ end
79
+
80
+ def self.instructions
81
+ puts "\n\n`-q` - Output to STDOUT only the travel times."
82
+ puts "`-v` - Check my version out."
83
+ puts "`-h` - Take a look at my help menu.\n\n"
84
+ puts "You have 4 options to make people travel with me.\n\n"
85
+ puts "*Executing command without arguments:*"
86
+ puts " - This way you will use STDIN to input people until you type 'exit' or interrupt execution(CTRL-C), so that I can finally take them home.\n\n"
87
+ puts "*Executing command with arguments:*"
88
+ puts " - You can pass file paths with one person per line"
89
+ puts " - You can pass people as a formatted string argument"
90
+ puts " - You can pass people as a JSON array with people objects inside\n\n"
91
+ puts "To make it easier for me to understand you please catalog yourselves with the following information:\n\n"
92
+ puts "attribute_1 - Time in minutes that you plan to begin your travel"
93
+ puts "attribute_2 - A numeric identification, to make it easier for me to know who you are"
94
+ puts "attribute_3 - From which floor I should pick you up"
95
+ puts "attribute_4 - Which floor do you want to go?\n\n\n"
96
+ puts "When using STDIN or strings in files or arguments, each person should be formatted as follows(without curly brackets):"
97
+ puts "'{attribute_1}m P{attribute_2} {attribute_3} {attribute_4}'\n\n"
98
+ puts "When using JSON formatting follow a schema like:"
99
+ puts "[{enter_at: attribute_1, id: attribute_2, from: attribute_3, to: attribute_4}]\n\n"
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,107 @@
1
+ module Elevatore
2
+ class Elevator
3
+ attr_reader :current_time, :current_floor, :people, :direction
4
+ def initialize opts={}
5
+ @current_floor = opts[:current_floor] || 0
6
+ @people = opts[:people]
7
+ @current_time = 0
8
+ @direction = opts[:direction] || Elevatore::DIRECTION_UP
9
+ if @direction != Elevatore::DIRECTION_UP && @direction != Elevatore::DIRECTION_DOWN
10
+ raise ArgumentError.new("Your direction is misleading the elevator")
11
+ end
12
+ end
13
+
14
+ def print_exit_times
15
+ clear_building!
16
+ output_people!
17
+ end
18
+
19
+ private
20
+ def clear_building!
21
+ while @people.any?{|person| has_inside?(person) || is_being_called?(person)}
22
+ people_exit!
23
+ people_enter!
24
+ set_direction!
25
+ travel!
26
+ end
27
+ end
28
+
29
+ def travel!
30
+ @current_time += Elevatore::SPEED
31
+ @current_floor += @direction if needs_to_roll?
32
+ end
33
+
34
+ def people_exit!
35
+ people_inside.each do |person|
36
+ person.exit_at = @current_time.round(1) if @current_floor == person.to
37
+ end
38
+ end
39
+
40
+ def people_enter!
41
+ people_to_enter.each do |person|
42
+ if @current_floor == person.from && person.pickup_at.nil? && person.enter_at == @current_time.round(1)
43
+ person.pickup_at = @current_time.round(1)
44
+ end
45
+ end
46
+ end
47
+
48
+ def output_people!
49
+ people.sort_by(&:exit_at).each do |person|
50
+ puts "#{person.exit_at}m P#{person.id}"
51
+ end
52
+ end
53
+
54
+ def needs_to_roll?
55
+ ((Elevatore::TOP_LEVEL >= @current_floor+1 && @direction == Elevatore::DIRECTION_UP) || (Elevatore::LOWER_LEVEL <= @current_floor-1 && @direction == Elevatore::DIRECTION_DOWN)) && ((!next_pickup.nil? && people_inside.size != 0) || next_pickup != @current_floor)
56
+ end
57
+
58
+ def is_being_called? person
59
+ !has_picked_up?(person) && !has_delivered?(person)
60
+ end
61
+
62
+ def has_inside? person
63
+ has_picked_up?(person) && !has_delivered?(person)
64
+ end
65
+
66
+ def has_picked_up? person
67
+ !person.pickup_at.nil?
68
+ end
69
+
70
+ def has_delivered? person
71
+ has_picked_up?(person) && !person.exit_at.nil?
72
+ end
73
+
74
+ def people_inside
75
+ @people.select{|person| has_inside?(person) }
76
+ end
77
+
78
+ def people_to_enter
79
+ @people.select{|person| is_being_called?(person) }
80
+ end
81
+
82
+ def next_pickup
83
+ people_to_enter.min_by{|person| person.enter_at }&.from
84
+ end
85
+
86
+ def next_drop
87
+ if @direction==Elevatore::DIRECTION_UP
88
+ people_inside.max_by{|person| person.to }&.to
89
+ else
90
+ people_inside.min_by{|person| person.to }&.to
91
+ end
92
+ end
93
+
94
+ def set_direction!
95
+ return if (next_pickup.nil? && people_inside.size == 0) || (next_drop.nil? && people_to_enter.size == 0)
96
+ if @direction==Elevatore::DIRECTION_UP
97
+ unless (next_pickup.to_i > @current_floor && people_inside.size == 0) || (next_drop.to_i > @current_floor)
98
+ @direction=Elevatore::DIRECTION_DOWN
99
+ end
100
+ else
101
+ unless (next_pickup.to_i < @current_floor && people_inside.size == 0) || (next_drop.to_i < @current_floor)
102
+ @direction=Elevatore::DIRECTION_UP
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,31 @@
1
+ module Elevatore
2
+ class Person
3
+ attr_reader :id, :from, :to, :enter_at
4
+ attr_accessor :exit_at, :pickup_at
5
+ def initialize opts={}
6
+ enforce_rules! opts
7
+ @id = opts["id"]
8
+ @from = opts["from"]
9
+ @to = opts["to"]
10
+ @enter_at = opts["enter_at"]
11
+ end
12
+
13
+ private
14
+ def enforce_rules! opts
15
+ if (opts["enter_at"].to_f%Elevatore::SPEED).round != 0
16
+ raise ArgumentError.new("Error on P#{opts["id"]}: Time should grow in multiples of #{Elevatore::SPEED}")
17
+ end
18
+ if opts["enter_at"].to_f < 0
19
+ raise ArgumentError.new("Error on P#{opts["id"]}: Time starts at 0")
20
+ end
21
+ round_numbers=[opts["id"], opts["from"], opts["to"]]
22
+ if round_numbers.any?{|int| int.class <= Float }
23
+ raise ArgumentError.new("Error on P#{opts["id"]}: Only time can be fractioned")
24
+ end
25
+ route=[opts["from"], opts["to"]]
26
+ if route.max > Elevatore::TOP_LEVEL || route.min < Elevatore::LOWER_LEVEL
27
+ raise ArgumentError.new("Error on P#{opts["id"]}: Floors should be between #{Elevatore::LOWER_LEVEL} and #{Elevatore::TOP_LEVEL}")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Elevatore
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elevatore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Fernando Bellincanta
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-04-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: |-
56
+ Elevatore assumes you have an elevator in a 10 level
57
+ building, and the time between levels is 0.1 minutes.
58
+ The time it takes to a person to enter the elevator is
59
+ considered 0.
60
+ email:
61
+ - ervalhous@hotmail.com
62
+ executables:
63
+ - elevatore
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - ".byebug_history"
68
+ - ".gitignore"
69
+ - ".rspec"
70
+ - ".travis.yml"
71
+ - CODE_OF_CONDUCT.md
72
+ - Gemfile
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - bin/console
77
+ - bin/setup
78
+ - elevatore.gemspec
79
+ - exe/elevatore
80
+ - lib/elevatore.rb
81
+ - lib/elevatore/cli.rb
82
+ - lib/elevatore/elevator.rb
83
+ - lib/elevatore/person.rb
84
+ - lib/elevatore/version.rb
85
+ homepage: https://github.com/ErvalhouS/fernando-bellincanta
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.6.14
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: Elevatore it is an exercise at elevator's behavior.
109
+ test_files: []