fuelator 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -2
- data/README.md +12 -0
- data/bin/fuelator +72 -30
- data/bin/setup +0 -0
- data/lib/fuelator.rb +3 -51
- data/lib/fuelator/calc.rb +46 -0
- data/lib/fuelator/parameters.rb +28 -21
- data/lib/fuelator/parameters/pair.rb +25 -0
- data/lib/fuelator/parameters/validator.rb +15 -0
- data/lib/fuelator/version.rb +1 -1
- metadata +5 -3
- data/lib/fuelator/parameters/error.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52e3da363267f184f76cf719b684b5422d3dcfca
|
4
|
+
data.tar.gz: 270e68d051d6a2a98023c091dbc78d72d082ac95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e47ac42223a6c2d6b2990f0259b93dcd637f60369e655511f85a85fb58de3b2e24d98139cf078ed268813c1c94cb147ed166497004c2c63af667ddcee0a1d72
|
7
|
+
data.tar.gz: cfe0164fce7608eab69c010312e16bfeb308aa7870eb031060c5bc1b71e2e5968b0c6c87d981a9d9c49162b0da0fe236bc4646c51afaea454458d4c40d8f76d8
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -24,6 +24,18 @@ If you plan a trip to Moon, once you are at fuel station, run:
|
|
24
24
|
|
25
25
|
$ fuelator 28801, [[:launch, 9.807], [:land, 1.62], [:launch, 1.62], [:land, 9.807]]
|
26
26
|
|
27
|
+
Or use API provided:
|
28
|
+
```ruby
|
29
|
+
require 'fuelator'
|
30
|
+
|
31
|
+
Fuelator.calculate(28801, [[:launch, 9.807], [:land, 1.62], [:launch, 1.62], [:land, 9.807]])
|
32
|
+
# => 51898
|
33
|
+
```
|
34
|
+
Be ready do handle errors:
|
35
|
+
```ruby
|
36
|
+
Fuelator::Parameters::Error
|
37
|
+
```
|
38
|
+
|
27
39
|
## Development
|
28
40
|
|
29
41
|
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.
|
data/bin/fuelator
CHANGED
@@ -1,43 +1,85 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "fuelator"
|
4
|
-
require '
|
4
|
+
require 'optparse'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class OptsParser
|
7
|
+
Version = Fuelator::VERSION
|
8
|
+
|
9
|
+
class Options
|
10
|
+
attr_accessor :verbose, :mass, :pairs
|
9
11
|
|
10
|
-
|
12
|
+
def initialize
|
13
|
+
@verbose = false
|
14
|
+
@mass = 0
|
15
|
+
@pairs = []
|
16
|
+
end
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
19
|
+
def self.parse
|
20
|
+
@options = Options.new
|
21
|
+
parser.parse!
|
22
|
+
@options
|
23
|
+
end
|
14
24
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
opts.separator "Add as many directive/gravity pairs as you wish. Note, you can not pass 2 same directives in a sequence."
|
25
|
+
def self.parser
|
26
|
+
@parser ||= OptionParser.new do |parser|
|
27
|
+
parser.banner = "Usage: fuelator [options]"
|
28
|
+
parser.separator ""
|
29
|
+
parser.separator "Specific options:"
|
21
30
|
|
22
|
-
|
23
|
-
|
31
|
+
boolean_verbose_option parser
|
32
|
+
float_mass_option(parser)
|
33
|
+
list_pairs_option(parser)
|
34
|
+
|
35
|
+
parser.separator ""
|
36
|
+
parser.separator "Common options:"
|
37
|
+
# No argument, shows at tail. This will print an options summary.
|
38
|
+
# Try it and see!
|
39
|
+
parser.on_tail("-h", "--help", "Show this message") do
|
40
|
+
puts parser
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
# Another typical switch to print the version.
|
44
|
+
parser.on_tail("--version", "Show version") do
|
45
|
+
puts Version
|
46
|
+
exit
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.boolean_verbose_option(parser)
|
52
|
+
# Boolean switch.
|
53
|
+
parser.on("-v", "--[no-]verbose", "Show error backtrace") do |v|
|
54
|
+
@options.verbose = v
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.float_mass_option(parser)
|
59
|
+
# Mass required float option.
|
60
|
+
parser.on("-m", "--mass MASS", Float, "Space ship mass") do |v|
|
61
|
+
@options.mass = v
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.list_pairs_option(parser)
|
66
|
+
# List of arguments.
|
67
|
+
parser.on("-p", "--pair PAIRS", Array, "Directive/gravity comma separated pairs: -p launch,9.2 -p land,2.2") do |list|
|
68
|
+
list = list.map { |v| (!!Float(v) rescue false) ? v.to_f : v.to_sym }
|
69
|
+
@options.pairs << list
|
70
|
+
end
|
24
71
|
end
|
25
|
-
end
|
26
|
-
optparse.parse!
|
27
|
-
|
28
|
-
def run(params, verbose)
|
29
|
-
result = Fuelator.calculate(params)
|
30
|
-
log "#{result.to_i} kg"
|
31
|
-
rescue Fuelator::Error, Fuelator::Parameters::Error => e
|
32
|
-
log_error(e, verbose)
|
33
|
-
rescue StandardError => e
|
34
|
-
log_error(e, verbose)
|
35
72
|
end
|
36
73
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
74
|
+
def run_script
|
75
|
+
options = OptsParser.parse
|
76
|
+
begin
|
77
|
+
puts "#{Fuelator::Calc.new(options.mass, options.pairs).run} kg"
|
78
|
+
rescue Fuelator::Parameters::Error, StandardError => e
|
79
|
+
puts e
|
80
|
+
puts e.backtrace if options.verbose
|
81
|
+
end
|
41
82
|
end
|
42
83
|
|
43
|
-
|
84
|
+
ARGV << '-h' if ARGV.empty?
|
85
|
+
run_script
|
data/bin/setup
CHANGED
File without changes
|
data/lib/fuelator.rb
CHANGED
@@ -1,56 +1,8 @@
|
|
1
1
|
require "fuelator/version"
|
2
|
+
require 'fuelator/parameters/validator'
|
3
|
+
require 'fuelator/parameters/pair'
|
2
4
|
require "fuelator/parameters"
|
3
|
-
|
5
|
+
require "fuelator/calc"
|
4
6
|
|
5
7
|
module Fuelator
|
6
|
-
# Calculate fuel for a flight
|
7
|
-
#
|
8
|
-
# Example:
|
9
|
-
# >> Fuelator.calculate(28801, [[:launch, 9.807], [:land, 1.62], [:launch, 1.62], [:land, 9.807]])
|
10
|
-
# => 51898
|
11
|
-
|
12
|
-
class Error < StandardError; end
|
13
|
-
|
14
|
-
FLIGHT_CONSTANTS = {
|
15
|
-
launch: {
|
16
|
-
theta: 0.042,
|
17
|
-
bias: 33,
|
18
|
-
},
|
19
|
-
land: {
|
20
|
-
theta: 0.033,
|
21
|
-
bias: 42,
|
22
|
-
},
|
23
|
-
}
|
24
|
-
|
25
|
-
# @param [Array] params
|
26
|
-
# [123, [[:launch, 123]]] or flatten [123, :launch, 123]
|
27
|
-
# params are validated and validation error may be raised
|
28
|
-
# @return Float - fuel for a flight
|
29
|
-
def self.calculate(*params)
|
30
|
-
parameters = Parameters.new(params)
|
31
|
-
|
32
|
-
full_mass = parameters.mass
|
33
|
-
|
34
|
-
parameters.dir_grav_pairs.reverse.map do |val|
|
35
|
-
full_mass += recursive_calculate(full_mass, val)
|
36
|
-
end.last - parameters.mass
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def self.recursive_calculate(mass, params)
|
42
|
-
directive = params[0]
|
43
|
-
gravity = params[1]
|
44
|
-
constants = FLIGHT_CONSTANTS[directive]
|
45
|
-
|
46
|
-
begin
|
47
|
-
fuel_mass = (mass * gravity * constants[:theta] - constants[:bias]).to_i # rounded down
|
48
|
-
rescue StandardError => e
|
49
|
-
raise Error.new(e.message)
|
50
|
-
end
|
51
|
-
|
52
|
-
return 0 if fuel_mass <= 0
|
53
|
-
result = recursive_calculate(fuel_mass, params)
|
54
|
-
fuel_mass + result
|
55
|
-
end
|
56
8
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Calculation of fuel required for flight based on input params
|
2
|
+
|
3
|
+
module Fuelator
|
4
|
+
# Calculate fuel for a flight
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# >> Fuelator.Calc.new(28801, [[:launch, 9.807], [:land, 1.62], [:launch, 1.62], [:land, 9.807]]).run
|
8
|
+
# => 51898
|
9
|
+
class Calc
|
10
|
+
attr_reader :parameters
|
11
|
+
|
12
|
+
FLIGHT_CONSTANTS = {
|
13
|
+
launch: {
|
14
|
+
theta: 0.042,
|
15
|
+
bias: 33,
|
16
|
+
},
|
17
|
+
land: {
|
18
|
+
theta: 0.033,
|
19
|
+
bias: 42,
|
20
|
+
},
|
21
|
+
}
|
22
|
+
|
23
|
+
def initialize(mass, pairs)
|
24
|
+
@parameters = Parameters.new(mass, pairs)
|
25
|
+
end
|
26
|
+
|
27
|
+
def run
|
28
|
+
full_mass = parameters.mass
|
29
|
+
|
30
|
+
parameters.reversed.map do |val|
|
31
|
+
full_mass += recursive_calculate(full_mass, val)
|
32
|
+
end.last - parameters.mass
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def recursive_calculate(mass, pair)
|
38
|
+
constants = FLIGHT_CONSTANTS[pair.directive]
|
39
|
+
fuel_mass = (mass * pair.gravity * constants[:theta] - constants[:bias]).to_i # rounded down
|
40
|
+
|
41
|
+
return 0 if fuel_mass <= 0
|
42
|
+
result = recursive_calculate(fuel_mass, pair)
|
43
|
+
fuel_mass + result
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/fuelator/parameters.rb
CHANGED
@@ -1,41 +1,48 @@
|
|
1
|
-
require 'fuelator/parameters/error'
|
2
1
|
# For flight parameters validation purposes
|
3
2
|
|
4
3
|
module Fuelator
|
5
4
|
class Parameters
|
6
|
-
|
5
|
+
include Validator
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
class Error < StandardError; end
|
8
|
+
|
9
|
+
attr_reader :mass, :pairs, :order
|
10
|
+
|
11
|
+
def initialize(mass, pairs)
|
12
|
+
@mass = mass
|
13
|
+
@pairs = pairs.map { |pair| Pair.new(pair) }
|
14
|
+
@order = define_order
|
12
15
|
|
13
16
|
validate!
|
14
17
|
end
|
15
18
|
|
19
|
+
def reversed
|
20
|
+
pairs.reverse
|
21
|
+
end
|
22
|
+
|
16
23
|
private
|
17
24
|
|
18
|
-
def
|
19
|
-
|
25
|
+
def valid_mass?
|
26
|
+
!mass.nil? && mass.is_a?(Numeric)
|
20
27
|
end
|
21
28
|
|
22
|
-
def
|
23
|
-
|
24
|
-
validate_pairs!
|
29
|
+
def valid_pairs?
|
30
|
+
!pairs.empty?
|
25
31
|
end
|
26
32
|
|
27
|
-
def
|
28
|
-
|
29
|
-
dir_grav_pairs.each do |pair|
|
30
|
-
error(:pairs, pair.count) if (pair.count % 2) != 0
|
31
|
-
error(:format, pair[0], pair[1]) unless pair[0].is_a?(Symbol) && pair[1].is_a?(Float)
|
32
|
-
error(:sequence, dir, pair[0]) if dir == pair[0] # no same directives allowed in a sequence
|
33
|
-
dir = pair[0]
|
34
|
-
end
|
33
|
+
def valid_order?
|
34
|
+
!order
|
35
35
|
end
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
# you can only calculate if directives passed in right order - :launch->:land
|
38
|
+
def define_order
|
39
|
+
dir = nil
|
40
|
+
pairs.map do |pair|
|
41
|
+
return true if dir == pair.directive
|
42
|
+
|
43
|
+
dir = pair.directive
|
44
|
+
end
|
45
|
+
false
|
39
46
|
end
|
40
47
|
end
|
41
48
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fuelator
|
2
|
+
class Parameters
|
3
|
+
class Pair
|
4
|
+
include Validator
|
5
|
+
DIRECTIVES = [:launch, :land]
|
6
|
+
|
7
|
+
attr_reader :directive, :gravity
|
8
|
+
|
9
|
+
def initialize(pair)
|
10
|
+
@directive = pair[0]
|
11
|
+
@gravity = pair[1]
|
12
|
+
|
13
|
+
validate!
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid_directive?
|
17
|
+
DIRECTIVES.include?(directive) && directive.is_a?(Symbol)
|
18
|
+
end
|
19
|
+
|
20
|
+
def valid_gravity?
|
21
|
+
!gravity.nil? && gravity.is_a?(Numeric)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Fuelator
|
2
|
+
class Parameters
|
3
|
+
module Validator
|
4
|
+
|
5
|
+
# runs #valid_[variable]? method for every instance variable
|
6
|
+
# raises Error defined in parent namespace
|
7
|
+
def validate!
|
8
|
+
instance_variables.each do |v|
|
9
|
+
v_name = v.to_s.gsub(/^@/, '')
|
10
|
+
raise Error.new("value for #{v_name} is invalid") unless send("valid_#{v_name}?")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/fuelator/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fuelator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergii Brytiuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-07-
|
11
|
+
date: 2020-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |-
|
14
14
|
The goal of this application is to calculate fuel
|
@@ -37,8 +37,10 @@ files:
|
|
37
37
|
- bin/setup
|
38
38
|
- fuelator.gemspec
|
39
39
|
- lib/fuelator.rb
|
40
|
+
- lib/fuelator/calc.rb
|
40
41
|
- lib/fuelator/parameters.rb
|
41
|
-
- lib/fuelator/parameters/
|
42
|
+
- lib/fuelator/parameters/pair.rb
|
43
|
+
- lib/fuelator/parameters/validator.rb
|
42
44
|
- lib/fuelator/version.rb
|
43
45
|
homepage: https://github.com/645383/fuelator
|
44
46
|
licenses:
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# Flight parameters validation error,
|
2
|
-
# Add error descriptive message to map of messages when new validation case added
|
3
|
-
|
4
|
-
module Fuelator
|
5
|
-
class Parameters
|
6
|
-
class Error < StandardError
|
7
|
-
MESSAGES = {
|
8
|
-
format: "directive/gravity pairs should be in format string/float: directive: %s, gravity: %s",
|
9
|
-
sequence: "you can not pass 2 same directives in a sequence: %s => %s",
|
10
|
-
mass: "mass should be float: %s",
|
11
|
-
pairs: "provide pairs for directive/gravity: %s elements"
|
12
|
-
}
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|