cotcube-helpers 0.1.4 → 0.1.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5e22624f57015916268dc4ca26ec98e2d759150ab9dc88dc3b5ceda93248148
4
- data.tar.gz: 73628320f993e73c83423dded2880f44412174c8d1cd4dd201ace3f2c6c6e41e
3
+ metadata.gz: 91263c1bbd453c5b1e6c8a3cfe7c0dee3542f5873e82d15caf8118b6b20ce603
4
+ data.tar.gz: f886c9fe330f439b61c0aee1f3c9cc55b3df161511968c25bb92df5cb85c2f0c
5
5
  SHA512:
6
- metadata.gz: 4b7b9051f22418e8a5a17245b1a410e284bf279787f1f9d279f58083f93a588c916926badc2b2834361241d874126a3af11c36805d20afe5b34049934c16cb6b
7
- data.tar.gz: fd0dbfb22b5b7631c5ee220de6551e1adfe9a38311afe85918598fdf86d9dd50e1028663b633c8a675853238767455504bdfa9163a466ef3e362950aa44cf064
6
+ metadata.gz: '00591395a0289380b4063ffa6766073d7619d1f7cc0576afb722854cbdc97f03d5bd651feaaf6a5f49de61770f6d16982a3ae7de26a9fd030c40efec6198e9f5'
7
+ data.tar.gz: c25f08c4677106ec7dc714653830bb6f9ef668f70df50343c443f0d0c79dccd110bf425fe7fa8cdc28b7ecf18db2d3aafd7cccd5f00b2bb5f3a8113fc17f65fa
@@ -1,3 +1,27 @@
1
+ ## 0.1.7 (January 17, 2021)
2
+ - added new method 'simple_series_stats'
3
+
4
+ ## 0.1.6 (January 15, 2021)
5
+ - removing :ranges from Range#select_within
6
+ - Added Array#select_right_by
7
+
8
+ ## 0.1.5.4 (January 02, 2021)
9
+
10
+
11
+ ## 1.5.1.3 (January 02, 2021)
12
+ - hotfixing the hotfix (hello CI tools, c ya coming)
13
+
14
+ ## 1.5.1.2 (January 02, 2021)
15
+ - hotfix problem in Range.to_time_intervals
16
+
17
+ ## 0.1.5.1 (January 02, 2021)
18
+ - Hotfixing parallelize
19
+
20
+ ## 0.1.5 (January 02, 2021)
21
+ - applied new datetime helper to Range#to_time_intervals
22
+ - added new DateTime extension, containing 'to_seconds_since_sunday_morning'
23
+ - added #select_within to array_ext
24
+
1
25
  ## 0.1.4 (December 27, 2020)
2
26
  - applied cops
3
27
  - added README for reduce; minor changes
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.4
1
+ 0.1.7
@@ -12,6 +12,7 @@ require_relative 'cotcube-helpers/enum_ext'
12
12
  require_relative 'cotcube-helpers/hash_ext'
13
13
  require_relative 'cotcube-helpers/range_ext'
14
14
  require_relative 'cotcube-helpers/string_ext'
15
+ require_relative 'cotcube-helpers/datetime_ext'
15
16
  require_relative 'cotcube-helpers/subpattern'
16
17
  require_relative 'cotcube-helpers/parallelize'
17
18
  require_relative 'cotcube-helpers/simple_output'
@@ -53,4 +53,45 @@ class Array
53
53
  block.call(self[i - 2], self[i - 1], self[i])
54
54
  end.compact
55
55
  end
56
+
57
+ # selects all elements from array that fit in given ranges.
58
+ # if :attr is given, selects all elements, where elem[:attr] fit
59
+ # raises if elem.first[attr].nil?
60
+ def select_within(ranges:, attr: nil, &block)
61
+ unless attr.nil? || first[attr]
62
+ raise ArgumentError,
63
+ "At least first element of Array '#{first}' does not contain attr '#{attr}'!"
64
+ end
65
+ raise ArgumentError, 'Ranges should be an Array or, more precisely, respond_to :map' unless ranges.respond_to? :map
66
+ raise ArgumentError, 'Each range in :ranges should respond to .include!' unless ranges.map do |x|
67
+ x.respond_to? :include?
68
+ end.reduce(:&)
69
+
70
+ select do |el|
71
+ value = attr.nil? ? el : el[attr]
72
+ ranges.map do |range|
73
+ range.include?(block.nil? ? value : block.call(value))
74
+ end.reduce(:|)
75
+ end
76
+ end
77
+
78
+ def select_right_by(inclusive: false, exclusive: false, initial: [], &block)
79
+ # unless range.is_a? Range and
80
+ # (range.begin.nil? or range.begin.is_a?(Integer)) and
81
+ # (range.end.nil? or range.end.is_a?(Integer))
82
+ # raise ArgumentError, ":range, if given, must be a range of ( nil|Integer..nil|Integer), got '#{range}'"
83
+ # end
84
+
85
+ raise ArgumentError, 'No block given.' unless block.is_a? Proc
86
+
87
+ inclusive = true unless exclusive
88
+ if inclusive && exclusive
89
+ raise ArgumentError,
90
+ "Either :inclusive or :exclusive must remain falsey, got '#{inclusive}' and '#{exclusive}'"
91
+ end
92
+
93
+ index = find_index { |obj| block.call(obj) }
94
+
95
+ self[((inclusive ? index : index + 1)..)]
96
+ end
56
97
  end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patching the Ruby class DateTime
4
+ class DateTime
5
+ # based on the fact that sunday is 'wday 0' plus that trading week starts
6
+ # sunday 0:00 (as trading starts sunday 5pm CT to fit tokyo monday morning)
7
+ def to_seconds_since_sunday_morning
8
+ wday * 86_400 + hour * 3600 + min * 60 + sec
9
+ end
10
+
11
+ alias to_sssm to_seconds_since_sunday_morning
12
+ end
@@ -7,9 +7,9 @@ module Cotcube
7
7
  def parallelize(ary, processes: 1, threads: 1, progress: '', &block)
8
8
  chunks = []
9
9
  if [0, 1].include? processes
10
- result = Parallel.map(ary, in_threads: threads) { |u, &in_thread| in_thread.call(u) }
11
- elsif [0, 1].include?(threads)
12
- result = Parallel.map(ary, in_processes: processes) { |u, &in_process| in_process.call(u) }
10
+ result = Parallel.map(ary, in_threads: threads, &block)
11
+ elsif [0, 1].include? threads
12
+ result = Parallel.map(ary, in_processes: processes, &block)
13
13
  else
14
14
  ary.each_slice(threads) { |chunk| chunks << chunk }
15
15
  result = if progress == ''
@@ -2,11 +2,17 @@
2
2
 
3
3
  # Monkey patching the Ruby Core class Range
4
4
  class Range
5
- def to_time_intervals(step:, timezone: Time.find_zone('America/Chicago'), ranges: nil)
5
+ def to_time_intervals(step:,
6
+ timezone: Time.find_zone('America/Chicago'),
7
+ # ranges: nil,
8
+ debug: false)
6
9
  unless step.is_a? ActiveSupport::Duration
7
10
  raise ArgumentError,
8
11
  ":step must be a 'ActiveSupport::Duration', like '15.minutes', but '#{step}' is a '#{step.class}'"
9
12
  end
13
+ unless [15.minutes, 60.minutes, 1.hour, 1.day].include? step
14
+ raise ArgumentError, 'Sorry, currently supporting only 15.minutes, 1.hour, 1.day as :step'
15
+ end
10
16
 
11
17
  valid_classes = [ActiveSupport::TimeWithZone, Time, Date, DateTime]
12
18
  unless timezone.is_a? ActiveSupport::TimeZone
@@ -26,64 +32,65 @@ class Range
26
32
  ":self.end seems not to be proper time value: #{ending} is a #{ending.class}"
27
33
  end
28
34
 
29
- ##### The following is the actual big magic line, as it creates the raw target array:
30
- #
31
- result = (starting.to_time.to_i..ending.to_time.to_i).step(step).to_a.map { |x| timezone.at(x) }
32
- #
33
- # ###################<3##
35
+ # here sub-day and super-day need to be distinguished, as they react differently to daylight time
36
+ # for super-day, just return an array containing all calendar days
37
+ if step.to_i >= 1.day
38
+ (starting.to_date..ending.to_date).to_a.map(&:to_datetime)
39
+ else
34
40
 
35
- # with step.to_i >= 86400 we are risking stuff like 25.hours to return bogus
36
- # also notice: When using this with swaps, you will loose 1 hour (#f**k_it)
37
- #
38
- # eventually, for dailies and above, return M-F default, return S-S when forced by empty ranges
39
- if step.to_i >= 86_400
40
- return result.select do |x|
41
- (not ranges.nil?) && ranges.empty? ? true : (not [6, 0].include?(x.wday))
42
- end
43
- end
41
+ # sub-day is checked for DST
42
+ # noinspection RubyNilAnalysis
43
+ actual_starting = starting.to_time.to_i
44
+ actual_ending = ending.to_time.to_i
45
+ actual_ending -= 3600 if starting.dst? && (not ending.dst?)
46
+ actual_ending += 3600 if ending.dst? && (not starting.dst?)
44
47
 
45
- # sub-day is checked for DST and filtered along provided ranges
46
- starting_with_dst = result.first.dst?
48
+ ##### The following is the actual big magic line, as it creates the raw target array:
49
+ #
50
+ result = (actual_starting..actual_ending).step(step).to_a.map { |x| timezone.at(x) }
51
+ #
52
+ # ###################<3##
47
53
 
48
- # The following lambda is completely misplaces here.
49
- # It should probably relocated to Cotcube::Bardata
50
- # NOTE: In this current version 12 belongs to it succeeding hour
51
- # i.e. 12am is right before 1am and 12pm right before 1pm
52
- convert_to_sec_since = lambda do |clocking|
53
- from_src, to_src = clocking.split(' - ')
54
- regex = /^(?<hour>\d+):(?<minute>\d+)(?<morning>[pa]).?m.*/
54
+ # It should probably relocated to Cotcube::Bardata
55
+ # NOTE: In this current version 12 belongs to it succeeding hour
56
+ # i.e. 12am is right before 1am and 12pm right before 1pm
57
+ convert_to_sec_since = lambda do |clocking|
58
+ from_src, to_src = clocking.split(' - ')
59
+ regex = /^(?<hour>\d+):(?<minute>\d+)(?<morning>[pa]).?m.*/
55
60
 
56
- from = from_src.match(regex)
57
- to = to_src.match(regex)
61
+ from = from_src.match(regex)
62
+ to = to_src.match(regex)
58
63
 
59
- from_i = from[:hour].to_i * 3600 + from[:minute].to_i * 60 + (from[:morning] == 'a' ? 2 : 1) * 12 * 3600
60
- to_i = to[:hour].to_i * 3600 + to[:minute].to_i * 60 + (to[:morning] == 'a' ? 2 : 3) * 12 * 3600
64
+ from_i = from[:hour].to_i * 3600 + from[:minute].to_i * 60 + (from[:morning] == 'a' ? 2 : 1) * 12 * 3600
65
+ to_i = to[:hour].to_i * 3600 + to[:minute].to_i * 60 + (to[:morning] == 'a' ? 2 : 3) * 12 * 3600
61
66
 
62
- (0...5).to_a.map { |i| [from_i + i * 24 * 3600, to_i + i * 24 * 3600] }
63
- end
64
- convert_to_sec_since.call('9:00a.m - 5:00p.m.')
67
+ (0...5).to_a.map { |i| [from_i + i * 24 * 3600, to_i + i * 24 * 3600] }
68
+ end
69
+ convert_to_sec_since.call('9:00a.m - 5:00p.m.')
65
70
 
66
- seconds_since_sunday_morning = ->(x) { x.wday * 86_400 + x.hour * 3600 + x.min * 60 + x.sec }
67
- ranges ||= [
68
- 61_200...144_000, # Sun 5pm .. Mon 4pm
69
- 147_600...230_400, # Mon 5pm .. Tue 4pm
70
- 234_000...316_800, # ...
71
- 320_400...403_200,
72
- 406_800...489_600
73
- ]
71
+ # ranges ||= [
72
+ # 61_200...144_000, # Sun 5pm .. Mon 4pm
73
+ # 147_600...230_400, # Mon 5pm .. Tue 4pm
74
+ # 234_000...316_800, # ...
75
+ # 320_400...403_200,
76
+ # 406_800...489_600
77
+ # ]
74
78
 
75
- # if there was a change towards daylight saving time, subtract 1 hour, otherwise add 1 hour
76
- result.map! do |time|
77
- if (not starting_with_dst) && time.dst?
78
- time - 3600
79
- elsif starting_with_dst && (not time.dst?)
80
- time + 3600
81
- else
79
+ # if there was a change towards daylight saving time, subtract 1 hour, otherwise add 1 hour
80
+ result.map! do |time|
81
+ print "#{time}\t" if debug
82
+ if (not starting.dst?) && time.dst?
83
+ time -= 3600
84
+ print "Time reduced (not starting_DST, but current\t" if debug
85
+ elsif starting.dst? && (not time.dst?)
86
+ time += 3600
87
+ print "Time extended (starting DST, but not current\t" if debug
88
+ end
89
+ puts "#{time} " if debug
82
90
  time
83
91
  end
84
- end
85
- return result if ranges.empty?
86
92
 
87
- result.select { |x| ranges.map { |r| r.include? seconds_since_sunday_morning.call(x) }.reduce(:|) }
93
+ result # .select_within(ranges: ranges) { |x| x.to_datetime.to_seconds_since_sunday_morning }
94
+ end
88
95
  end
89
96
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cotcube
4
+ # Missing top level documentation
5
+ module Helpers
6
+ # if given a block, :ind of base is set by block.call()
7
+ # dim reduces the sample size by top n% and least n%, so dim of 0.5 would remove 100% of the sample
8
+ def simple_series_stats(base:, ind: nil, dim: 0, format: '%5.2f', print: true, &block)
9
+ raise ArgumentError, 'Need :ind of type integer' if base.first.is_a?(Array) and not ind.is_a?(Integer)
10
+ raise ArgumentError, 'Need :ind to evaluate base' if base.first.is_a?(Hash) and ind.nil?
11
+
12
+ dim = dim.to_f if dim.is_a? Numeric
13
+ dim = 0 if dim==false
14
+
15
+ raise ArgumentError, 'Expecting 0 <= :dim < 0.5' unless dim.is_a?(Float) and dim >= 0 and dim < 0.5
16
+ raise ArgumentError, 'Expecting arity of one if block given' if block_given? and not block.arity==1
17
+
18
+ precision = format[-1] == 'f' ? format[..-2].split('.').last.to_i : 0
19
+ worker = base.
20
+ tap {|b| b.map{|x| x[ind] = block.call(x) } if block.is_a? Proc }.
21
+ map {|x| ind.nil? ? x : x[ind] }.
22
+ compact.
23
+ sort
24
+ unless dim.zero?
25
+ reductor = (base.size * dim).round
26
+ puts reductor
27
+ worker = worker[reductor..base.size - reductor]
28
+ puts worker.size
29
+ end
30
+ result = {}
31
+
32
+ result[:size] = worker.size
33
+ result[:min] = worker.first
34
+ result[:avg] = (worker.reduce(:+) / result[:size]).round(precision+1)
35
+ result[:lower] = worker[ (result[:size] * 1 / 4).round ]
36
+ result[:median] = worker[ (result[:size] * 2 / 4).round ]
37
+ result[:upper] = worker[ (result[:size] * 3 / 4).round ]
38
+ result[:max] = worker.last
39
+
40
+ result[:output] = result.
41
+ reject{|k,_| k == :size}.
42
+ map{|k,v| { type: k, value: v, output: "#{k}: #{format(format, v)}".colorize(k==:avg ? :light_yellow : :white) } }.
43
+ sort_by{|x| x[:value]}.
44
+ map{|x| x[:output]}
45
+ output = "[" +
46
+ " size: #{format '%6d', result[:size]} | ".light_white +
47
+ output.join(' | ') +
48
+ " ]"
49
+
50
+ puts result[:output] if print
51
+ result
52
+ end
53
+ end
54
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cotcube-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin L. Tischendorf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-27 00:00:00.000000000 Z
11
+ date: 2021-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -82,6 +82,7 @@ files:
82
82
  - cotcube-helpers.gemspec
83
83
  - lib/cotcube-helpers.rb
84
84
  - lib/cotcube-helpers/array_ext.rb
85
+ - lib/cotcube-helpers/datetime_ext.rb
85
86
  - lib/cotcube-helpers/enum_ext.rb
86
87
  - lib/cotcube-helpers/hash_ext.rb
87
88
  - lib/cotcube-helpers/input.rb
@@ -89,6 +90,7 @@ files:
89
90
  - lib/cotcube-helpers/range_ext.rb
90
91
  - lib/cotcube-helpers/reduce.rb
91
92
  - lib/cotcube-helpers/simple_output.rb
93
+ - lib/cotcube-helpers/simple_series_stats.rb
92
94
  - lib/cotcube-helpers/string_ext.rb
93
95
  - lib/cotcube-helpers/subpattern.rb
94
96
  - lib/cotcube-helpers/swig/date.rb