runby_pace 0.2.50.111 → 0.2.55

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.
Files changed (43) hide show
  1. checksums.yaml +13 -5
  2. data/.travis.yml +1 -5
  3. data/Gemfile +0 -4
  4. data/README.md +5 -16
  5. data/Rakefile +6 -40
  6. data/bin/_guard-core +16 -17
  7. data/bin/guard +16 -17
  8. data/lib/runby_pace.rb +1 -4
  9. data/lib/runby_pace/{pace_calculator.rb → pace_data.rb} +13 -29
  10. data/lib/runby_pace/pace_range.rb +9 -27
  11. data/lib/runby_pace/pace_time.rb +110 -0
  12. data/lib/runby_pace/run_type.rb +4 -12
  13. data/lib/runby_pace/run_types/all_run_types.template +4 -6
  14. data/lib/runby_pace/run_types/easy_run.rb +10 -31
  15. data/lib/runby_pace/run_types/find_divisor.rb +17 -13
  16. data/lib/runby_pace/run_types/long_run.rb +10 -32
  17. data/lib/runby_pace/version.rb +2 -17
  18. data/runby_pace.gemspec +5 -4
  19. metadata +18 -41
  20. data/.rubocop.yml +0 -10
  21. data/bin/runbypace +0 -15
  22. data/lib/runby_pace/cli/cli.rb +0 -127
  23. data/lib/runby_pace/cli/config.rb +0 -82
  24. data/lib/runby_pace/distance.rb +0 -135
  25. data/lib/runby_pace/distance_unit.rb +0 -89
  26. data/lib/runby_pace/golden_pace_set.rb +0 -50
  27. data/lib/runby_pace/pace.rb +0 -152
  28. data/lib/runby_pace/run_math.rb +0 -14
  29. data/lib/runby_pace/run_types/distance_run.rb +0 -55
  30. data/lib/runby_pace/run_types/fast_tempo_run.rb +0 -23
  31. data/lib/runby_pace/run_types/five_kilometer_race_run.rb +0 -22
  32. data/lib/runby_pace/run_types/mile_race_run.rb +0 -24
  33. data/lib/runby_pace/run_types/slow_tempo_run.rb +0 -22
  34. data/lib/runby_pace/run_types/tempo_run.rb +0 -54
  35. data/lib/runby_pace/run_types/ten_kilometer_race_run.rb +0 -23
  36. data/lib/runby_pace/runby_range.rb +0 -22
  37. data/lib/runby_pace/runby_time.rb +0 -138
  38. data/lib/runby_pace/runby_time_parser.rb +0 -80
  39. data/lib/runby_pace/speed.rb +0 -97
  40. data/lib/runby_pace/speed_range.rb +0 -30
  41. data/lib/runby_pace/utility/parameter_sanitizer.rb +0 -29
  42. data/lib/runby_pace/version.seed +0 -5
  43. data/misc/runbypace_logo.png +0 -0
data/bin/runbypace DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- begin
4
- require "bundler/setup"
5
- rescue LoadError
6
- end
7
-
8
- begin
9
- require 'runby_pace'
10
- rescue LoadError
11
- require_relative '../lib/runby_pace'
12
- end
13
-
14
- cli = Runby::Cli::Cli.new(ARGV)
15
- cli.run
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'readline'
4
- require 'optparse'
5
- require_relative 'config'
6
-
7
- module Runby
8
- module Cli
9
- # Command line interface and REPL for RunbyPace
10
- class Cli
11
- def initialize(args = ARGV)
12
- @args = args
13
- @config = Config.new
14
- @options = parse_options args
15
- end
16
-
17
- def run
18
- puts 'Runby Pace REPL!'
19
- bnd = binding
20
- while (input = Readline.readline('🏃 ', true))
21
- begin
22
- result = bnd.eval input
23
- rescue StandardError => e
24
- puts "#{e.class}: #{e.message}"
25
- else
26
- puts result
27
- end
28
- end
29
- end
30
-
31
- def print_targets(five_k_time, distance_units = :mi)
32
- five_k_time = @config['five_k_time'] if five_k_time.nil?
33
-
34
- five_k_time = Runby.sanitize(five_k_time).as(RunbyTime)
35
- puts "\nIf you can run a 5K in #{five_k_time}, your training paces should be:"
36
- paces = []
37
- RunTypes.all_classes.each do |run_type|
38
- run = run_type.new
39
- paces.push(description: run.description, pace: run.lookup_pace(five_k_time, distance_units))
40
- end
41
- paces.sort_by { |p| p[:pace].fast }.reverse_each { |p| puts " #{p[:description]}: #{p[:pace]}" }
42
- nil
43
- end
44
-
45
- # -- Shortcuts for the REPL
46
- def di(*args)
47
- Distance.new(*args)
48
- end
49
-
50
- def du(*args)
51
- DistanceUnit.new(*args)
52
- end
53
-
54
- def pc(*args)
55
- Pace.new(*args)
56
- end
57
-
58
- def sp(*args)
59
- Speed.new(*args)
60
- end
61
-
62
- def tm(*args)
63
- RunbyTime.new(*args)
64
- end
65
-
66
- private
67
-
68
- def parse_options(options)
69
- args = { targets: nil }
70
-
71
- OptionParser.new do |opts|
72
- opts.banner = 'Usage: runbypace.rb [options]'
73
-
74
- opts.on('-h', '--help', 'Display this help message') do
75
- puts opts
76
- exit
77
- end
78
-
79
- opts.on('-c', '--config [SETTING][=NEW_VALUE]', 'Get or set a configuration value') do |config|
80
- manage_config config
81
- exit
82
- end
83
-
84
- opts.on('-t', '--targets [5K race time]', 'Show target paces') do |targets|
85
- args[:targets] = targets
86
- print_targets targets
87
- exit
88
- end
89
- end.parse!(options)
90
- args
91
- end
92
-
93
- def manage_config(config)
94
- c = parse_config_setting config
95
- unless c.key
96
- # No key specified. Print all settings.
97
- @config.pretty_print
98
- return
99
- end
100
- if c.value
101
- # Set setting "key" to new "value"
102
- @config[c.key] = c.value
103
- return
104
- end
105
- if c.clear_setting
106
- @config[c.key] = nil
107
- else
108
- # Print the value of setting "key"
109
- p @config[c.key]
110
- end
111
- end
112
-
113
- def parse_config_setting(setting)
114
- setting = '' if setting.nil?
115
- Class.new do
116
- attr_reader :key, :value, :clear_setting
117
- def initialize(setting)
118
- tokens = setting.split('=')
119
- @key = tokens[0]
120
- @value = tokens[1]
121
- @clear_setting = (@value.nil? && setting.include?('='))
122
- end
123
- end.new(setting)
124
- end
125
- end
126
- end
127
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'yaml'
4
- require 'pp'
5
-
6
- module Runby
7
- #
8
- module Cli
9
- class Config
10
- USER_CONFIG_PATH = File.expand_path('~/.runbypace').freeze
11
-
12
- VALID_OPTIONS = {
13
- five_k_time: { validate_as: RunbyTime }
14
- }.freeze
15
-
16
- def initialize
17
- @settings = load_user_settings
18
- end
19
-
20
- def load_user_settings
21
- if File.exist? USER_CONFIG_PATH
22
- YAML.load_file USER_CONFIG_PATH
23
- else
24
- {}
25
- end
26
- end
27
-
28
- def store_user_settings
29
- File.open(USER_CONFIG_PATH, 'w') { |file| file.write @settings.to_yaml }
30
- end
31
-
32
- def [](key)
33
- return unless known_setting?(key)
34
- return unless option_configured?(key)
35
- "#{key} => #{@settings[key]}"
36
- end
37
-
38
- def []=(key, value)
39
- return unless known_setting?(key)
40
- if value
41
- value = sanitize_value key, value
42
- return unless value
43
- @settings[key] = value.to_s
44
- else
45
- @settings.delete(key)
46
- end
47
- store_user_settings
48
- end
49
-
50
- def pretty_print
51
- pp @settings
52
- end
53
-
54
- def known_setting?(key)
55
- unless VALID_OPTIONS.key?(key.to_sym)
56
- puts "Unknown setting #{key}"
57
- return false
58
- end
59
- true
60
- end
61
-
62
- def sanitize_value(key, value)
63
- cls = VALID_OPTIONS[key.to_sym][:validate_as]
64
- begin
65
- value = Runby.sanitize(value).as(cls)
66
- rescue StandardError => ex
67
- value = nil
68
- p ex.message
69
- end
70
- value
71
- end
72
-
73
- def option_configured?(key)
74
- unless @settings.key? key
75
- puts "#{key} not configured. Set with:\n\trunbypace --config #{key} VALUE"
76
- false
77
- end
78
- true
79
- end
80
- end
81
- end
82
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Runby
4
- # Represents a distance (distance UOM and multiplier)
5
- class Distance
6
- include Comparable
7
-
8
- attr_reader :uom, :multiplier
9
-
10
- def self.new(uom = :km, multiplier = 1)
11
- return uom if uom.is_a? Distance
12
- return Distance.parse uom if uom.is_a? String
13
- super
14
- end
15
-
16
- def initialize(uom = :km, multiplier = 1)
17
- case uom
18
- when DistanceUnit
19
- init_from_distance_unit uom, multiplier
20
- when Symbol
21
- init_from_symbol uom, multiplier
22
- else
23
- raise 'Invalid distance unit of measure'
24
- end
25
- freeze
26
- end
27
-
28
- def convert_to(target_uom)
29
- target_uom = DistanceUnit.new target_uom unless target_uom.is_a?(DistanceUnit)
30
- return self if @uom == target_uom
31
- target_multiplier = kilometers / (target_uom.conversion_factor * 1.0)
32
- Distance.new target_uom, target_multiplier
33
- end
34
-
35
- def meters
36
- kilometers * 1000.0
37
- end
38
-
39
- def kilometers
40
- @multiplier * @uom.conversion_factor
41
- end
42
-
43
- def self.parse(str)
44
- str = str.strip.chomp.downcase
45
- multiplier = str.scan(/[\d,.]+/).first
46
- multiplier = multiplier.nil? ? 1 : multiplier.to_f
47
- uom = str.scan(/[-_a-z ]+$/).first
48
- raise "Unable to find distance unit in '#{str}'" if uom.nil?
49
-
50
- parsed_uom = Runby::DistanceUnit.parse uom
51
- raise "'#{uom.strip}' is not recognized as a distance unit" if parsed_uom.nil?
52
-
53
- new parsed_uom, multiplier
54
- end
55
-
56
- def self.try_parse(str)
57
- distance, error_message = nil
58
- begin
59
- distance = parse str
60
- rescue StandardError => ex
61
- error_message = ex.message.to_s
62
- end
63
- { distance: distance, error: error_message }
64
- end
65
-
66
- def to_s(format: :short)
67
- formatted_multiplier = format('%g', @multiplier.round(2))
68
- case format
69
- when :short then "#{formatted_multiplier} #{@uom.to_s(format: format)}"
70
- when :long then "#{formatted_multiplier} #{@uom.to_s(format: format, pluralize: (@multiplier > 1))}"
71
- else raise "Invalid string format #{format}"
72
- end
73
- end
74
-
75
- # @param [Distance, String] other
76
- def <=>(other)
77
- raise "Unable to compare Runby::Distance to #{other.class}(#{other})" unless [Distance, String].include? other.class
78
- if other.is_a?(String)
79
- return 0 if to_s == other || to_s(format: :long) == other
80
- return self <=> Distance.try_parse(other)[:distance]
81
- end
82
- kilometers <=> other.kilometers
83
- end
84
-
85
- # @param [Distance] other
86
- # @return [Distance]
87
- def +(other)
88
- raise "Cannot add Runby::Distance to #{other.class}" unless other.is_a?(Distance)
89
- sum_in_km = Distance.new(:km, kilometers + other.kilometers)
90
- sum_in_km.convert_to(@uom)
91
- end
92
-
93
- # @param [Distance] other
94
- # @return [Distance]
95
- def -(other)
96
- raise "Cannot add Runby::Distance to #{other.class}" unless other.is_a?(Distance)
97
- sum_in_km = Distance.new(:km, kilometers - other.kilometers)
98
- sum_in_km.convert_to(@uom)
99
- end
100
-
101
- # @param [Numeric] other
102
- # @return [Distance]
103
- def *(other)
104
- raise "Cannot multiply Runby::Distance by #{other.class}" unless other.is_a?(Numeric)
105
- product_in_km = Distance.new(:km, kilometers * other)
106
- product_in_km.convert_to(@uom)
107
- end
108
-
109
- # @param [Numeric, Distance] other
110
- # @return [Distance, Numeric]
111
- def /(other)
112
- raise "Cannot divide Runby::Distance by #{other.class}" unless other.is_a?(Numeric) || other.is_a?(Distance)
113
- if other.is_a?(Numeric)
114
- quotient_in_km = Distance.new(:km, kilometers / other)
115
- return quotient_in_km.convert_to(@uom)
116
- elsif other.is_a?(Distance)
117
- return kilometers / other.kilometers
118
- end
119
- end
120
-
121
- private
122
-
123
- def init_from_distance_unit(uom, multiplier)
124
- @uom = uom
125
- @multiplier = multiplier
126
- end
127
-
128
- def init_from_symbol(distance_uom_symbol, multiplier)
129
- raise "Unknown unit of measure #{distance_uom_symbol}" unless Runby::DistanceUnit.known_uom? distance_uom_symbol
130
- raise 'Invalid multiplier' unless multiplier.is_a?(Numeric)
131
- @uom = DistanceUnit.new distance_uom_symbol
132
- @multiplier = multiplier * 1.0
133
- end
134
- end
135
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Runby
4
- # Represents the distance units (e.g. kilometers, miles) used in paces
5
- # including the human-readable description of each unit
6
- # and the factor used to convert it to kilometers.
7
- class DistanceUnit
8
- attr_reader :symbol, :description, :conversion_factor
9
-
10
- def self.new(unit_of_measure)
11
- return unit_of_measure if unit_of_measure.is_a? DistanceUnit
12
- return DistanceUnit.parse(unit_of_measure) if unit_of_measure.is_a? String
13
- super
14
- end
15
-
16
- def initialize(unit_of_measure)
17
- raise "':#{unit_of_measure}' is an unknown unit of measure" unless DistanceUnit.known_uom? unit_of_measure
18
- @symbol = unit_of_measure
19
- @conversion_factor = UOM_DEFINITIONS[@symbol][:conversion_factor]
20
- @description = UOM_DEFINITIONS[@symbol][:description]
21
- freeze
22
- end
23
-
24
- def to_s(format: :long, pluralize: false)
25
- case format
26
- when :short then @symbol.to_s
27
- when :long then pluralize ? description_plural : @description
28
- else raise "Invalid string format #{format}"
29
- end
30
- end
31
-
32
- def description_plural
33
- UOM_DEFINITIONS[@symbol][:description_plural]
34
- end
35
-
36
- def self.parse(description)
37
- return new description if description.is_a? Symbol
38
- description = description.strip.chomp.downcase
39
- found_uom = nil
40
- UOM_DEFINITIONS.each do |uom, details|
41
- if details[:synonyms].include? description
42
- found_uom = uom
43
- break
44
- end
45
- end
46
- raise "Error parsing distance unit '#{description}'" unless found_uom
47
- DistanceUnit.new found_uom
48
- end
49
-
50
- def self.try_parse(str)
51
- uom, error_message = nil
52
- begin
53
- uom = parse str
54
- rescue StandardError => ex
55
- error_message = ex.message
56
- end
57
- { uom: uom, error: error_message }
58
- end
59
-
60
- def self.known_uom?(symbol)
61
- UOM_DEFINITIONS.key?(symbol)
62
- end
63
-
64
- def ==(other)
65
- if other.is_a? DistanceUnit
66
- @symbol == other.symbol
67
- elsif other.is_a? String
68
- self == DistanceUnit.parse(other)
69
- else
70
- raise "Unable to compare DistanceUnit to #{other.class}(#{other})"
71
- end
72
- end
73
-
74
- UOM_DEFINITIONS =
75
- { km: { description: 'kilometer', description_plural: 'kilometers', conversion_factor: 1.0,
76
- synonyms: %w[k km kms kilometer kilometers] },
77
- m: { description: 'meter', description_plural: 'meters', conversion_factor: 0.001,
78
- synonyms: %w[m meter meters] },
79
- mi: { description: 'mile', description_plural: 'miles', conversion_factor: 1.609344,
80
- synonyms: %w[mi mile miles] },
81
- ft: { description: 'foot', description_plural: 'feet', conversion_factor: 0.0003048,
82
- synonyms: %w[ft foot feet] },
83
- yd: { description: 'yard', description_plural: 'yards', conversion_factor: 1093.61,
84
- synonyms: %w[y yd yds yard yards] },
85
- # Fun distance unit of measures
86
- marathon: { description: 'marathon', description_plural: 'marathons', conversion_factor: 42.1648128,
87
- synonyms: %w[marathon] } }.freeze
88
- end
89
- end