Module: Misc
- Defined in:
- lib/scout/misc.rb,
lib/scout/misc/math.rb,
lib/scout/misc/digest.rb,
lib/scout/misc/format.rb,
lib/scout/misc/helper.rb,
lib/scout/misc/insist.rb,
lib/scout/misc/system.rb,
lib/scout/misc/monitor.rb,
lib/scout/misc/filesystem.rb
Constant Summary collapse
- Log2Multiplier =
1.0 / Math.log(2.0)
- Log10Multiplier =
1.0 / Math.log(10.0)
- MAX_ARRAY_DIGEST_LENGTH =
100_000
- COLOR_LIST =
%w(#BC80BD #CCEBC5 #FFED6F #8DD3C7 #FFFFB3 #BEBADA #FB8072 #80B1D3 #FDB462 #B3DE69 #FCCDE5 #D9D9D9)
- CHAR_SENCONDS =
ENV["SCOUT_NOCOLOR"] == "true" ? "sec" : "″"
- MAX_TTY_LINE_WIDTH =
160
Class Method Summary collapse
- .abort_child(pid, wait = true) ⇒ Object
- .benchmark(repeats = 1, message = nil) ⇒ Object
- .camel_case(string) ⇒ Object
- .camel_case_lower(string) ⇒ Object
- .children(ppid = nil) ⇒ Object
-
.chunk(array, size) ⇒ Object
Divides the array into chunks of size
size
by taking consecutive elements. - .colors_for(list) ⇒ Object
- .counts(array) ⇒ Object
- .digest(obj) ⇒ Object
- .digest_file(file) ⇒ Object
- .digest_str(obj) ⇒ Object
-
.divide(array, num) ⇒ Object
Divides the array into
num
chunks of the same size by placing one element in each chunk iteratively. - .env_add(var, value, sep = ":", prepend = true) ⇒ Object
- .exec_time(&block) ⇒ Object
- .fast_file_md5(file, sample = 3_000_000) ⇒ Object
- .file_md5(file) ⇒ Object
- .fixascii(string) ⇒ Object
- .fixutf8(string) ⇒ Object
- .format_definition_list(defs, indent = nil, size = nil, color = :yellow, sep = "\n\n") ⇒ Object
- .format_definition_list_item(dt, dd, indent = nil, size = nil, color = :yellow) ⇒ Object
- .format_paragraph(text, size = nil, indent = nil, offset = nil) ⇒ Object
- .format_seconds(time, extended = false) ⇒ Object
- .format_seconds_short(time) ⇒ Object
- .hostname ⇒ Object
-
.humanize(value, options = {}) ⇒ Object
source: gist.github.com/ekdevdes/2450285 author: Ethan Kramer (github.com/ekdevdes).
- .humanize_list(list) ⇒ Object
- .in_dir(dir) ⇒ Object
- .insist(times = 4, sleep = nil, msg = nil) ⇒ Object
- .intersect_sorted_arrays(a1, a2) ⇒ Object
- .log10(x) ⇒ Object
- .log2(x) ⇒ Object
- .max(list) ⇒ Object
- .mean(list) ⇒ Object
- .median(array) ⇒ Object
- .min(list) ⇒ Object
-
.ordered_divide(array, num) ⇒ Object
Divides the array into chunks of
num
same size by placing one element in each chunk iteratively. - .parse_sql_values(txt) ⇒ Object
- .path_relative_to(basedir, path) ⇒ Object
- .pid_alive?(pid) ⇒ Boolean
- .processors ⇒ Object
- .profile(options = {}) ⇒ Object
- .proportions(array) ⇒ Object
- .sd(list) ⇒ Object
- .snake_case(string) ⇒ Object
- .softmax(array) ⇒ Object
- .std_num_vector(v, min, max) ⇒ Object
- .sum(list) ⇒ Object
- .tarize(path, dest = nil) ⇒ Object
- .timespan(str, default = "s") ⇒ Object
- .to_utf8(string) ⇒ Object
- .untar(file, target = '.') ⇒ Object
- .update_git(gem_name = 'scout-essentials') ⇒ Object
- .variance(list) ⇒ Object
- .wait_child(pid) ⇒ Object
- .wait_for_interrupt ⇒ Object
- .with_env(var, value, &block) ⇒ Object
- .zscore(e, list) ⇒ Object
Class Method Details
.abort_child(pid, wait = true) ⇒ Object
23 24 25 26 27 28 29 30 |
# File 'lib/scout/misc/system.rb', line 23 def self.abort_child(pid, wait = true) begin Process.kill("TERM", pid.to_i) wait_child(pid) if wait rescue Log.debug("Process #{pid} was not killed: #{$!.}") end end |
.benchmark(repeats = 1, message = nil) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/scout/misc/monitor.rb', line 7 def self.benchmark(repeats = 1, = nil) require 'benchmark' res = nil begin measure = Benchmark.measure do repeats.times do |i| res = yield i end end if puts "#{ }: #{ repeats } repeats" else puts "Benchmark for #{ repeats } repeats (#{caller.first})" end puts measure rescue Exception puts "Benchmark aborted" raise $! end res end |
.camel_case(string) ⇒ Object
112 113 114 115 116 117 |
# File 'lib/scout/misc/format.rb', line 112 def self.camel_case(string) return string if string !~ /_/ && string =~ /[A-Z]+.*/ string.split(/_|(\d+)/).map{|e| (e =~ /^[A-Z]{2,}$/ ? e : e.capitalize) }.join end |
.camel_case_lower(string) ⇒ Object
119 120 121 122 123 |
# File 'lib/scout/misc/format.rb', line 119 def self.camel_case_lower(string) string.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e.downcase : (e =~ /^[A-Z]{2,}$/ ? e : e.capitalize)) }.join end |
.children(ppid = nil) ⇒ Object
9 10 11 12 13 14 |
# File 'lib/scout/misc/system.rb', line 9 def self.children(ppid = nil) require 'sys/proctable' ppid ||= Process.pid Sys::ProcTable.ps.select{ |pe| pe.ppid == ppid } end |
.chunk(array, size) ⇒ Object
Divides the array into chunks of size size
by taking consecutive elements. If a block is given it runs it instead of returning the chunks
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/scout/misc/helper.rb', line 34 def self.chunk(array, size) total = array.length current = 0 res = [] unless block_given? while current < total last = current + size - 1 if block_given? yield array[current..last] else res << array[current..last] end current = last + 1 end block_given? ? nil : res end |
.colors_for(list) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/scout/misc/format.rb', line 4 def self.colors_for(list) unused = COLOR_LIST.dup used = {} colors = list.collect do |elem| if used.include? elem used[elem] else color = unused.shift used[elem]=color color end end [colors, used] end |
.counts(array) ⇒ Object
76 77 78 79 80 81 82 83 84 |
# File 'lib/scout/misc/math.rb', line 76 def self.counts(array) counts = {} array.each do |e| counts[e] ||= 0 counts[e] += 1 end counts end |
.digest(obj) ⇒ Object
54 55 56 57 |
# File 'lib/scout/misc/digest.rb', line 54 def self.digest(obj) str = String === obj ? obj : Misc.digest_str(obj) Digest::MD5.hexdigest(str) end |
.digest_file(file) ⇒ Object
78 79 80 81 82 83 84 85 86 |
# File 'lib/scout/misc/digest.rb', line 78 def self.digest_file(file) file = file.find if Path === file file = File.(file) if File.size(file) > 10_000_000 fast_file_md5(file) else file_md5(file) end end |
.digest_str(obj) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/scout/misc/digest.rb', line 4 def self.digest_str(obj) if obj.respond_to?(:digest_str) obj.digest_str else case obj when String if Path.is_filename?(obj) && Open.exists?(obj) if File.directory?(obj) "Directory MD5: #{digest_str(Dir.glob(File.join(obj, "*")))}" else "File MD5: #{Misc.digest_file(obj)}" end else obj.dup end when Integer, Symbol obj.to_s when Array if obj.length > MAX_ARRAY_DIGEST_LENGTH length = obj.length mid = length/2 sample_pos = [1, 2, mid, length-2, length-1] "[#{length}:" << obj.values_at(*sample_pos).inject(""){|acc,o| acc.empty? ? Misc.digest_str(o) : acc << ', ' << Misc.digest_str(o) } << ']' else '[' << obj.inject(""){|acc,o| acc.empty? ? Misc.digest_str(o) : acc << ', ' << Misc.digest_str(o) } << ']' end when Hash '{' << obj.inject(""){|acc,p| s = Misc.digest_str(p.first) << "=" << Misc.digest_str(p.last); acc.empty? ? s : acc << ', ' << s } << '}' when Integer obj.to_s when Float if obj % 1 == 0 obj.to_i.to_s elsif obj.abs > 10 "%.1f" % obj elsif obj.abs > 1 "%.3f" % obj else "%.6f" % obj end when TrueClass "true" when FalseClass "false" else obj.inspect end end end |
.divide(array, num) ⇒ Object
Divides the array into num
chunks of the same size by placing one element in each chunk iteratively.
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/scout/misc/helper.rb', line 52 def self.divide(array, num) num = 1 if num == 0 chunks = [] num.to_i.times do chunks << [] end array.each_with_index{|e, i| c = i % num chunks[c] << e } chunks end |
.env_add(var, value, sep = ":", prepend = true) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/scout/misc/system.rb', line 32 def self.env_add(var, value, sep = ":", prepend = true) if ENV[var].nil? ENV[var] = value elsif ENV[var] =~ /(#{sep}|^)#{Regexp.quote value}(#{sep}|$)/ return else if prepend ENV[var] = value + sep + ENV[var] else ENV[var] += sep + value end end end |
.exec_time(&block) ⇒ Object
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/scout/misc/monitor.rb', line 47 def self.exec_time(&block) start = Time.now eend = nil begin yield ensure eend = Time.now end eend - start end |
.fast_file_md5(file, sample = 3_000_000) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/scout/misc/digest.rb', line 65 def self.fast_file_md5(file, sample = 3_000_000) size = File.size(file) sample_txt = size.to_s << ":" File.open(file) do |f| sample_txt << f.read(sample) f.seek(size/2) sample_txt << f.read(sample) f.seek(size - sample - 1) sample_txt << f.read(sample) end Digest::MD5.hexdigest(sample_txt) end |
.file_md5(file) ⇒ Object
59 60 61 62 63 |
# File 'lib/scout/misc/digest.rb', line 59 def self.file_md5(file) file = file.find if Path === file file = File.(file) Digest::MD5.file(file).hexdigest end |
.fixascii(string) ⇒ Object
179 180 181 182 183 184 185 |
# File 'lib/scout/misc/format.rb', line 179 def self.fixascii(string) if string.respond_to?(:encode) self.fixutf8(string).encode("ASCII-8BIT") else string end end |
.fixutf8(string) ⇒ Object
191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/scout/misc/format.rb', line 191 def self.fixutf8(string) return nil if string.nil? return string if string.respond_to?(:encoding) && string.encoding.to_s == "UTF-8" && (string.respond_to?(:valid_encoding?) && string.valid_encoding?) || (string.respond_to?(:valid_encoding) && string.valid_encoding) if string.respond_to?(:encode) string.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '') else require 'iconv' @@ic ||= Iconv.new('UTF-8//IGNORE', 'UTF-8') @@ic.iconv(string) end end |
.format_definition_list(defs, indent = nil, size = nil, color = :yellow, sep = "\n\n") ⇒ Object
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/scout/misc/format.rb', line 101 def self.format_definition_list(defs, indent = nil, size = nil, color = :yellow, sep = "\n\n") indent ||= 30 size ||= (Log.tty_size || MAX_TTY_LINE_WIDTH) - indent entries = [] defs.each do |dt,dd| text = format_definition_list_item(dt,dd,indent, size,color) entries << text end entries * sep end |
.format_definition_list_item(dt, dd, indent = nil, size = nil, color = :yellow) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/scout/misc/format.rb', line 75 def self.format_definition_list_item(dt, dd, indent = nil, size = nil, color = :yellow) if size.nil? base_size = MAX_TTY_LINE_WIDTH base_indent = indent || (base_size / 3) size = base_size - base_indent end indent ||= base_indent || size / 3 dd = "" if dd.nil? dt = Log.color color, dt if color dt = dt.to_s unless dd.empty? len = Log.uncolor(dt).length if indent < 0 text = format_paragraph(dd, size, indent.abs-1, 0) text = dt << "\n" << text else offset = len - indent offset = 0 if offset < 0 text = format_paragraph(dd, size, indent.abs+1, offset) text[0..len-1] = dt end text end |
.format_paragraph(text, size = nil, indent = nil, offset = nil) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/scout/misc/format.rb', line 40 def self.format_paragraph(text, size = nil, indent = nil, offset = nil) size ||= Log.tty_size || MAX_TTY_LINE_WIDTH size = MAX_TTY_LINE_WIDTH if size > MAX_TTY_LINE_WIDTH indent ||= 0 offset ||= 0 i = 0 size = size + offset + indent re = /((?:\n\s*\n\s*)|(?:\n\s*(?=\*)))/ text.split(re).collect do |paragraph| i += 1 str = if i % 2 == 1 words = paragraph.gsub(/\s+/, "\s").split(" ") lines = [] line = " "*offset word = words.shift while word word = word[0..size-indent-offset-4] + '...' if word.length >= size - indent - offset while word and Log.uncolor(line).length + Log.uncolor(word).length <= size - indent line << word << " " word = words.shift end offset = 0 lines << ((" " * indent) << line[0..-2]) line = "" end (lines * "\n") else paragraph end offset = 0 str end*"" end |
.format_seconds(time, extended = false) ⇒ Object
21 22 23 24 25 26 |
# File 'lib/scout/misc/format.rb', line 21 def self.format_seconds(time, extended = false) seconds = time.to_i str = [seconds/3600, seconds/60 % 60, seconds % 60].map{|t| "%02i" % t }.join(':') str << ".%02i" % ((time - seconds) * 100) if extended str end |
.format_seconds_short(time) ⇒ Object
29 30 31 32 33 34 35 36 37 |
# File 'lib/scout/misc/format.rb', line 29 def self.format_seconds_short(time) if time < 0.0001 "%.5g" % time + CHAR_SENCONDS elsif time < 60 "%.2g" % time + CHAR_SENCONDS else format_seconds(time) end end |
.hostname ⇒ Object
3 4 5 6 7 |
# File 'lib/scout/misc/system.rb', line 3 def self.hostname @@hostname ||= begin `hostname`.strip end end |
.humanize(value, options = {}) ⇒ Object
source: gist.github.com/ekdevdes/2450285 author: Ethan Kramer (github.com/ekdevdes)
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/scout/misc/format.rb', line 137 def self.humanize(value, = {}) if .empty? [:format] = :sentence end values = value.to_s.split('_') values.each_index do |index| # lower case each item in array # Miguel Vazquez edit: Except for acronyms values[index].downcase! unless values[index].match(/[a-zA-Z][A-Z]/) end if [:format] == :allcaps values.each do |value| value.capitalize! end if .empty? [:seperator] = " " end return values.join " " end if [:format] == :class values.each do |value| value.capitalize! end return values.join "" end if [:format] == :sentence values[0].capitalize! unless values[0].match(/[a-zA-Z][A-Z]/) return values.join " " end if [:format] == :nocaps return values.join " " end end |
.humanize_list(list) ⇒ Object
205 206 207 208 209 210 211 212 |
# File 'lib/scout/misc/format.rb', line 205 def self.humanize_list(list) return "" if list.empty? if list.length == 1 list.first else list[0..-2].collect{|e| e.to_s} * ", " << " and " << list[-1].to_s end end |
.in_dir(dir) ⇒ Object
2 3 4 5 6 7 8 9 10 11 |
# File 'lib/scout/misc/filesystem.rb', line 2 def self.in_dir(dir) old_pwd = FileUtils.pwd begin FileUtils.mkdir_p dir unless File.exist?(dir) FileUtils.cd dir yield ensure FileUtils.cd old_pwd end end |
.insist(times = 4, sleep = nil, msg = nil) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/scout/misc/insist.rb', line 2 def self.insist(times = 4, sleep = nil, msg = nil) sleep_array = nil try = 0 begin begin yield rescue Exception if Array === times sleep_array = times times = sleep_array.length sleep = sleep_array.shift end if sleep.nil? sleep_array = ([0] + [0.001, 0.01, 0.1, 0.5] * (times / 3)).sort[0..times-1] sleep = sleep_array.shift end raise $! end rescue TryAgain sleep sleep retry rescue StopInsist raise $!.exception rescue Aborted, Interrupt if msg Log.warn("Not Insisting after Aborted: #{$!.} -- #{msg}") else Log.warn("Not Insisting after Aborted: #{$!.}") end raise $! rescue Exception Log.exception $! if ENV["SCOUT_LOG_INSIST"] == 'true' if msg Log.warn("Insisting after exception: #{$!.class} #{$!.} -- #{msg}") elsif FalseClass === msg nil else Log.warn("Insisting after exception: #{$!.class} #{$!.}") end if sleep and try > 0 sleep sleep sleep = sleep_array.shift || sleep if sleep_array else Thread.pass end try += 1 retry if try < times raise $! end end |
.intersect_sorted_arrays(a1, a2) ⇒ Object
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/scout/misc/helper.rb', line 2 def self.intersect_sorted_arrays(a1, a2) e1, e2 = a1.shift, a2.shift intersect = [] while true break if e1.nil? or e2.nil? case e1 <=> e2 when 0 intersect << e1 e1, e2 = a1.shift, a2.shift when -1 e1 = a1.shift while not e1.nil? and e1 < e2 when 1 e2 = a2.shift e2 = a2.shift while not e2.nil? and e2 < e1 end end intersect end |
.log10(x) ⇒ Object
9 10 11 |
# File 'lib/scout/misc/math.rb', line 9 def self.log10(x) Math.log(x) * Log10Multiplier end |
.log2(x) ⇒ Object
5 6 7 |
# File 'lib/scout/misc/math.rb', line 5 def self.log2(x) Math.log(x) * Log2Multiplier end |
.max(list) ⇒ Object
13 14 15 16 17 18 19 20 |
# File 'lib/scout/misc/math.rb', line 13 def self.max(list) max = nil list.each do |v| next if v.nil? max = v if max.nil? or v > max end max end |
.mean(list) ⇒ Object
44 45 46 |
# File 'lib/scout/misc/math.rb', line 44 def self.mean(list) sum(list.compact.collect{|v| v.to_f } ) / list.compact.length end |
.median(array) ⇒ Object
48 49 50 51 52 |
# File 'lib/scout/misc/math.rb', line 48 def self.median(array) sorted = array.sort len = sorted.length (sorted[(len - 1) / 2] + sorted[len / 2]).to_f / 2 end |
.min(list) ⇒ Object
22 23 24 25 26 27 28 29 |
# File 'lib/scout/misc/math.rb', line 22 def self.min(list) min = nil list.each do |v| next if v.nil? min = v if min.nil? or v < min end min end |
.ordered_divide(array, num) ⇒ Object
Divides the array into chunks of num
same size by placing one element in each chunk iteratively.
65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/scout/misc/helper.rb', line 65 def self.ordered_divide(array, num) last = array.length - 1 chunks = [] current = 0 while current <= last next_current = [last, current + num - 1].min chunks << array[current..next_current] current = next_current + 1 end chunks end |
.parse_sql_values(txt) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/scout/misc/format.rb', line 214 def self.parse_sql_values(txt) io = StringIO.new txt.strip values = [] fields = [] current = nil quoted = false while c = io.getc if quoted if c == "'" quoted = false else current << c end else case c when "(" current = "" when ")" fields << current values << fields fields = [] current = nil when ',' if not current.nil? fields << current current = "" end when "'" quoted = true when ";" break else current << c end end end values end |
.path_relative_to(basedir, path) ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/scout/misc/filesystem.rb', line 13 def self.path_relative_to(basedir, path) path = File.(path) unless path.slice(0,1) == "/" basedir = File.(basedir) unless basedir.slice(0,1) == "/" basedir += "/" unless basedir.slice(-2,-1) == "/" if path.start_with?(basedir) return path.slice(basedir.length, basedir.length) else return nil end end |
.pid_alive?(pid) ⇒ Boolean
2 3 4 5 |
# File 'lib/scout/misc/monitor.rb', line 2 def self.pid_alive?(pid) return true if Process.pid == pid !! Process.kill(0, pid) rescue false end |
.processors ⇒ Object
86 87 88 |
# File 'lib/scout/misc/system.rb', line 86 def self.processors Etc.nprocessors end |
.profile(options = {}) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/scout/misc/monitor.rb', line 29 def self.profile( = {}) require 'ruby-prof' profiler = RubyProf::Profile.new profiler.start begin res = yield rescue Exception puts "Profiling aborted" raise $! ensure result = profiler.stop printer = RubyProf::FlatPrinter.new(result) printer.print(STDOUT, ) end res end |
.proportions(array) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/scout/misc/math.rb', line 86 def self.proportions(array) total = array.length proportions = Hash.new 0 array.each do |e| proportions[e] += 1.0 / total end class << proportions; self; end.class_eval do def to_s sort{|a,b| a[1] == b[1] ? a[0] <=> b[0] : a[1] <=> b[1]}.collect{|k,c| "%3d\t%s" % [c, k]} * "\n" end end proportions end |
.sd(list) ⇒ Object
70 71 72 73 74 |
# File 'lib/scout/misc/math.rb', line 70 def self.sd(list) return nil if list.length < 3 variance = self.variance(list) Math.sqrt(variance) end |
.snake_case(string) ⇒ Object
125 126 127 128 129 130 131 132 133 |
# File 'lib/scout/misc/format.rb', line 125 def self.snake_case(string) return nil if string.nil? string = string.to_s if Symbol === string string. gsub(/([A-Z]{2,})([A-Z][a-z])/,'\1_\2'). gsub(/([a-z])([A-Z])/,'\1_\2'). gsub(/\s/,'_').gsub(/[^\w]/, ''). split("_").collect{|p| p.match(/[A-Z]{2,}/) ? p : p.downcase } * "_" end |
.softmax(array) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/scout/misc/math.rb', line 110 def self.softmax(array) # Compute the exponentials of the input array elements exp_array = array.map { |x| Math.exp(x) } # Sum of all exponentials sum_exp = exp_array.sum # Compute the softmax values by dividing each exponential by the sum of exponentials softmax_array = exp_array.map { |x| x / sum_exp } return softmax_array end |
.std_num_vector(v, min, max) ⇒ Object
31 32 33 34 35 36 37 38 |
# File 'lib/scout/misc/math.rb', line 31 def self.std_num_vector(v, min, max) v_min = Misc.min(v) v_max = Misc.max(v) v_range = v_max - v_min range = max.to_f - min.to_f v.collect{|e| (e.nil? || e.nan?) ? e : min + range * (e.to_f - v_min) / v_range } end |
.sum(list) ⇒ Object
40 41 42 |
# File 'lib/scout/misc/math.rb', line 40 def self.sum(list) list.compact.inject(0.0){|acc,e| acc += e } end |
.tarize(path, dest = nil) ⇒ Object
26 27 28 29 30 31 32 33 34 |
# File 'lib/scout/misc/filesystem.rb', line 26 def self.tarize(path, dest = nil) Misc.in_dir(path) do if dest CMD.cmd("tar cvfz '#{dest}' '.'") else CMD.cmd("tar cvfz - '.'", :pipe => true) end end end |
.timespan(str, default = "s") ⇒ Object
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/scout/misc/format.rb', line 254 def self.timespan(str, default = "s") return - timespan(str[1..-1], default) if str[0] == "-" if str.include?(":") seconds, minutes, hours = str.split(":").reverse return seconds.to_i + minutes.to_i * 60 + hours.to_i * 60 * 60 end tokens = { "s" => (1), "sec" => (1), "m" => (60), "min" => (60), "''" => (1), "'" => (60), "h" => (60 * 60), "d" => (60 * 60 * 24), "w" => (60 * 60 * 24 * 7), "mo" => (60 * 60 * 24 * 31), "y" => (60 * 60 * 24 * 365), } tokens[nil] = tokens[default] tokens[""] = tokens[default] time = 0 str.scan(/(\d+)(\w*)/).each do |amount, measure| time += amount.to_i * tokens[measure] end time end |
.to_utf8(string) ⇒ Object
187 188 189 |
# File 'lib/scout/misc/format.rb', line 187 def self.to_utf8(string) string.encode("UTF-16BE", :invalid => :replace, :undef => :replace, :replace => "?").encode('UTF-8') end |
.untar(file, target = '.') ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/scout/misc/filesystem.rb', line 36 def self.untar(file, target = '.') target = target.find if Path === target file = file.find if Path === file Misc.in_dir target do if IO === file CMD.cmd("tar xvfz -", in: file) else CMD.cmd("tar xvfz '#{file}'") end end end |
.update_git(gem_name = 'scout-essentials') ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/scout/misc/system.rb', line 56 def self.update_git(gem_name = 'scout-essentials') gem_name = 'scout-essentials' if gem_name.nil? dir = File.join(__dir__, '../../../../', gem_name) return unless Open.exist?(dir) Misc.in_dir dir do begin begin CMD.cmd_log('git pull') rescue raise "Could not update #{gem_name}" end begin CMD.cmd_log('git submodule update') rescue raise "Could not update #{gem_name} submodules" end begin CMD.cmd_log('rake install') rescue raise "Could not install updated #{gem_name}" end rescue Log.warn $!. end end end |
.variance(list) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/scout/misc/math.rb', line 54 def self.variance(list) return nil if list.length < 3 mean = mean(list) list = list.compact list_length = list.length total_square_distance = 0.0 list.each do |value| distance = value.to_f - mean total_square_distance += distance * distance end total_square_distance / (list_length - 1) end |
.wait_child(pid) ⇒ Object
16 17 18 19 20 21 |
# File 'lib/scout/misc/system.rb', line 16 def self.wait_child(pid) begin Process.waitpid2 pid.to_i rescue Errno::ECHILD end end |
.wait_for_interrupt ⇒ Object
58 59 60 61 62 63 64 65 66 |
# File 'lib/scout/misc/monitor.rb', line 58 def self.wait_for_interrupt while true begin sleep 1 rescue Interrupt break end end end |
.with_env(var, value, &block) ⇒ Object
46 47 48 49 50 51 52 53 54 |
# File 'lib/scout/misc/system.rb', line 46 def self.with_env(var, value, &block) old_value = ENV[var] begin ENV[var] = value yield ensure ENV[var] = old_value end end |