ix-cli 0.0.10 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9356248fcc4f5fe5c83fedeb01e13166a9764bed70c39fe06132963141f394d9
4
- data.tar.gz: c7676df3c6b0e8427888882bc02fa609e6aa987816f76ef90e656ca6ce196ed7
3
+ metadata.gz: d054eabc68581f7a85447e44ce7471bd3bfd361fec428cd6f52b07bc23d99f61
4
+ data.tar.gz: ef9b8158e1a5282d68956f9188f47d2e0753a7e42606b8fd48a8e684f2379d1a
5
5
  SHA512:
6
- metadata.gz: 21233826e4b716857231aa89c0abc3263702cf0347b71a2bfc40e3502b79946b98a7b3ae5496bf1975121ef1f3c44952bedd0415d817ac7eee34246ec91007b6
7
- data.tar.gz: fbee1010c9fda5caf7144b8855c6ff8f502413ba3dbee2b81c630340d6c429299878b9b20cc34bc6d9fe2912e3b5e4cee44159f0b31fc947d0467957f7cf6802
6
+ metadata.gz: 312c40f4c85f2c8919ddaa1ea33a9306dfc2be0eecf51782d18abaaabf4a5d1cc8fd00507674081ecf5598e694d9c28f4c31783b7416afd11a6d86024b096904
7
+ data.tar.gz: 4f7d68947f74467984e028a8d66460d662b8a32d57cc2e0072bb63454b325b3ce7abaa7600ea02f7a8bf64b4e6c8355bb1a51d8b5be8c0b5bf3d095e11716cee
data/bin/ix-json-stats CHANGED
@@ -13,7 +13,12 @@ OptionParser.new do |opts|
13
13
  opts.banner = "Usage: #{$0} [OPTIONS]"
14
14
 
15
15
  opts.on('-k', '--keys [KEYS]', 'List of keys to parse from json separated by :.') do |value|
16
- options[:keys] = value
16
+ unless value
17
+ $stderr.puts "Please provide valid --keys got: #{value.inspect}"
18
+ STDIN.each_line {}
19
+ exit 1
20
+ end
21
+ options[:keys] = value.split(':')
17
22
  end
18
23
 
19
24
  opts.on('-c', '--count [NUMBER]', 'Number of top N items to show.') do |value|
@@ -26,7 +31,7 @@ OptionParser.new do |opts|
26
31
 
27
32
  end.parse!
28
33
 
29
- required_options = [:keys]
34
+ required_options = []
30
35
  required_options.each do |option|
31
36
  unless options[option]
32
37
  $stderr.puts "Can not run #{option.to_s} was not given."
@@ -35,13 +40,17 @@ required_options.each do |option|
35
40
  end
36
41
 
37
42
  map = {}
38
- keys = options[:keys].split(':')
39
43
 
40
44
  STDIN.each_line do |line|
41
45
  begin
42
46
  object = JSON.parse(line)
47
+ unless options[:keys]
48
+ options[:keys] == object.keys
49
+ end
43
50
  object.each do |k, v|
44
- next unless keys.include?(k)
51
+ if options[:keys]
52
+ next unless options[:keys].include?(k)
53
+ end
45
54
  submap = map[k] ||= {}
46
55
  submap[v] ||= 0
47
56
  submap[v] += 1
@@ -53,36 +62,56 @@ STDIN.each_line do |line|
53
62
  end
54
63
  end
55
64
 
56
- def print_map(map, sample)
57
- map.each do |category, stats|
58
- values = []
59
- total = 0
60
-
61
- counter = 0
62
- stats.values.sort.reverse.each do |value_1|
63
- stats.each do |key, value_2|
64
- if value_1 == value_2
65
- counter += 1
66
- break if counter > sample
67
- total += value_1
68
- values.push({ :value => value_1, :key => key })
69
- end
70
- end
65
+ def print_value(result, total)
66
+ percentage = "%2.2f" % (result[:incidents] / total.to_f * 100)
67
+ h_percentage = (percentage.to_s + '%').rjust(6, ' ').to_ansi.yellow.to_s
68
+ value = result[:incidents].to_s.rjust(10, ' ').to_ansi.green.to_s
69
+ key = result[:label]
70
+ puts "%s %s %s" % [value, h_percentage, key]
71
+ end
72
+
73
+ class GroupObject
74
+ attr_accessor :category
75
+ attr_accessor :results
76
+ def initialize(category)
77
+ @category = category
78
+ @results = []
79
+ end
80
+ def add_result(label, incidents)
81
+ @results.push({ :label => label, :incidents => incidents })
82
+ end
83
+ def total
84
+ results.sum do |result|
85
+ result[:incidents]
71
86
  end
87
+ end
88
+ end
72
89
 
73
- puts ""
74
- puts "#{category.to_s.to_ansi.cyan.to_s} (#{total})"
90
+ def get_group_objects(map)
91
+ group_objects = []
75
92
 
76
- values.each do |object|
77
- percentage = "%2.2f" % (object[:value] / total.to_f * 100)
78
- h_percentage = (percentage.to_s + '%').rjust(6, ' ').to_ansi.yellow.to_s
79
- value = object[:value].to_s.rjust(10, ' ').to_ansi.green.to_s
80
- key = object[:key]
81
- puts "%s %s %s" % [value, h_percentage, key]
93
+ map.each do |category, hash|
94
+ group_object = GroupObject.new(category)
95
+ hash.each do |k, v|
96
+ group_object.add_result(k, v)
82
97
  end
98
+ group_objects.push(group_object)
99
+ end
83
100
 
101
+ group_objects.sort do |a, b|
102
+ a.category <=> b.category
84
103
  end
85
104
  end
86
105
 
87
- print_map(map, options[:count])
106
+ def print_map(map, sample)
107
+ get_group_objects(map).each do |group_object|
108
+ puts "\n#{group_object.category.to_s.to_ansi.cyan.to_s} (#{group_object.total})"
109
+ group_object.results.sort do |a, b|
110
+ a[:incidents] <=> b[:incidents]
111
+ end.reverse.first(sample).each do |result|
112
+ print_value(result, group_object.total)
113
+ end
114
+ end
115
+ end
88
116
 
117
+ print_map(map, options[:count])
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'json'
5
+
6
+ def tag(name, content)
7
+ "<#{name}>#{content}</#{name}>"
8
+ end
9
+
10
+ def row(name, array)
11
+ array.map do |value|
12
+ tag(name, value)
13
+ end * ' '
14
+ end
15
+
16
+ table_header = false
17
+
18
+ puts '
19
+ <style>
20
+ tr:nth-child(even) {
21
+ background-color: whitesmoke;
22
+ }
23
+ th {
24
+ background: darkgray;
25
+ font-color: white;
26
+ padding: 1mm;
27
+ }
28
+ td {
29
+ padding: 1mm;
30
+ }
31
+ </style>
32
+ '
33
+
34
+ STDIN.each_line do |line|
35
+ begin
36
+ object = JSON.parse(line)
37
+ unless table_header
38
+ puts '<table>'
39
+ table_header_row = row('th', object.keys.sort)
40
+ puts tag('tr', table_header_row)
41
+ table_header = true
42
+ end
43
+ copy = object.keys.sort.map do |key|
44
+ object[key]
45
+ end
46
+ table_body_row = row('td', copy)
47
+ puts tag('tr', table_body_row)
48
+ rescue => error
49
+ end
50
+ end
51
+
52
+ puts '</table>'
data/bin/ix-prepend CHANGED
File without changes
@@ -1,152 +1,222 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'optparse'
4
- require 'ostruct'
3
+ class Chunk
4
+ attr_accessor :char_1
5
+ attr_accessor :char_2
6
+ attr_accessor :index_1
7
+ attr_accessor :index_2
8
+
9
+ def initialize(c1, c2, i1, i2)
10
+ @char_1 = c1
11
+ @char_2 = c2
12
+ @index_1 = i1
13
+ @index_2 = i2
14
+ end
5
15
 
6
- configuration = OpenStruct.new
16
+ def to_s
17
+ "#{char_1} #{char_2} #{index_1} #{index_2}"
18
+ end
19
+ end
7
20
 
8
- OptionParser.new do |opts|
21
+ class Similarity
22
+ CHAR_REGEX = /./
9
23
 
10
- opts.banner = "Find similarity in a set of strings."
11
- opts.separator ''
12
- opts.separator "Usage: #{File.basename($0)} [OPTIONS]"
13
- opts.separator ''
24
+ attr_accessor :string_1
25
+ attr_accessor :string_2
14
26
 
15
- configuration.group = false
16
- configuration.threshold = 50
17
- configuration.summary = false
27
+ def initialize(string_1, string_2)
28
+ @string_1 = string_1
29
+ @string_2 = string_2
30
+ end
18
31
 
19
- description = "Group input in batches and process each individually (faster)"
20
- opts.on("-g", "--group", description) do |v|
21
- configuration.group = v
32
+ def tokens
33
+ chunks = []
34
+ string_1.scan(CHAR_REGEX).each_with_index do |char_1, index_1|
35
+ string_2.scan(CHAR_REGEX).each_with_index do |char_2, index_2|
36
+ next if char_1 != char_2
37
+ chunks.push(Chunk.new(char_1, char_2, index_1, index_2))
38
+ end
39
+ end
40
+ chunks
22
41
  end
23
42
 
24
- description = "Limit the number of results by threshold, default is 50"
25
- opts.on("-t", "--threshhold [NUMBER]", OptionParser::DecimalNumeric, description) do |v|
26
- configuration.threshold = v
43
+ def count
44
+ counter = 0
45
+ prev = false
46
+ tokens.each_with_index do |chunk, index|
47
+
48
+ unless prev
49
+ prev = chunk.index_1
50
+ next
51
+ end
52
+
53
+ if prev == (chunk.index_1 - 1)
54
+ counter += 1
55
+ end
56
+
57
+ prev = chunk.index_1
58
+ end
59
+
60
+ counter
27
61
  end
28
62
 
29
- description = "Print a Summary of the groups found"
30
- opts.on("-s", "--summary", description) do |v|
31
- configuration.summary = v
63
+ def score
64
+ desired = (string_1.size + string_2.size) / 2
65
+ size_thresh = ([string_1.size, string_2.size].sort.first.to_f / desired)
66
+ compatibility_thresh = (count.to_f + 1) / string_1.size
67
+ (size_thresh + compatibility_thresh).to_f / 2
32
68
  end
69
+ end
70
+
71
+ require 'optparse'
72
+
73
+ options = {}
74
+ options[:threshold] = 0.8
33
75
 
76
+ OptionParser.new do |opts|
34
77
 
35
- opts.separator ''
78
+ opts.banner = "Usage: #{$0} [OPTIONS]"
79
+
80
+ opts.on('-t', '--threshold [NUMBER]', 'Threshold default value is 0.8.') do |value|
81
+ options[:threshold] = value.to_f
82
+ end
83
+
84
+ opts.on('-s', '--summary', 'Print Summarized version.') do |value|
85
+ options[:summary] = value
86
+ end
36
87
 
37
88
  end.parse!
38
89
 
39
- # puts configuration.inspect
90
+ required_options = [:threshold]
91
+ required_options.each do |option|
92
+ unless options[option]
93
+ $stderr.puts "Can not run #{option.to_s} was not given."
94
+ exit 1
95
+ end
96
+ end
97
+
98
+ # hash = {
99
+ # 'line' => [
100
+ # { :line => 'line', :score => 1 },
101
+ # ]
102
+ # }
103
+
104
+ hash = {}
105
+ lines = 0
40
106
 
41
- class Array
42
- def product
43
- inject do |cumulative, value|
44
- cumulative += value
107
+ STDIN.each_line do |line|
108
+ line.chomp!
109
+ next if line == ''
110
+ lines += 1
111
+ resolved = false
112
+ hash.keys.each do |registered_line|
113
+ score = Similarity.new(line, registered_line).score
114
+ if score > options[:threshold]
115
+ hash[registered_line].push({
116
+ :line => line,
117
+ :score => score
118
+ })
119
+ resolved = true
45
120
  end
46
121
  end
122
+ next if resolved
123
+ hash[line] ||= []
47
124
  end
48
125
 
49
- class String
50
- def to_a
51
- array = []
52
- size.times do |n|
53
- array << self[n]
126
+ module Template
127
+
128
+ class Banner < Struct.new(:lines, :groups, :threshold, :datetime)
129
+ def to_s
130
+ format(template, to_h)
131
+ end
132
+ def template
133
+ '
134
+ Total Lines Parsed: %<lines>s
135
+ Total Groups Generated: %<groups>s
136
+ Similarity Theshold at: %<threshold>s
137
+ Generated on: %<datetime>s
138
+ '
54
139
  end
55
- array
56
140
  end
57
141
 
58
- def scores(other_string)
59
- longest_string = nil
60
- if other_string.size > self.size
61
- longest_string = other_string
62
- shortest_string = self
63
- else
64
- longest_string = self
65
- shortest_string = other_string
66
- end
67
- scores = longest_string.to_a.map do |char|
68
- 0
142
+ class Group < Struct.new(:number, :percent, :items, :line)
143
+ def to_s
144
+ format(template, to_h)
69
145
  end
70
- shortest_string.size.times do |index|
71
- if shortest_string[index] == longest_string[index]
72
- scores[index] = 1
73
- end
146
+ def template
147
+ 'Group %<number>s represents %<percent>s and has %<items>s items similar to: %<line>s'
74
148
  end
75
- scores
76
149
  end
77
150
 
78
- def similarity(other_string)
79
- scores(other_string).product * 100.0 / size
151
+ class Item < Struct.new(:count, :total, :score, :line)
152
+ def to_s
153
+ format(template, to_h)
154
+ end
155
+ def template
156
+ ' %<count>s/%<total>s %<score>s %<line>s'
157
+ end
80
158
  end
81
- end
82
159
 
83
- class TargetString
84
- attr_accessor :evaluated
85
- attr_accessor :data
86
- def to_s
87
- data
88
- end
89
160
  end
90
161
 
91
- # client
162
+ require 'isna'
92
163
 
93
- strings = []
164
+ summary_output = []
165
+ detailed_output = []
94
166
 
95
- STDIN.each_line do |line|
96
- next if line.chomp == ''
97
- strings << line.chomp
98
- end
167
+ banner = Template::Banner.new
168
+ banner.lines = lines.to_s.to_ansi.yellow.to_s
169
+ banner.groups = hash.keys.size.to_s.to_ansi.yellow.to_s
170
+ banner.threshold = options[:threshold].to_s.to_ansi.yellow.to_s
171
+ banner.datetime = Time.now.to_s.to_ansi.yellow.to_s
172
+ summary_output.push(banner.to_s)
99
173
 
100
- strings.sort! do |n1, n2|
101
- n1.size <=> n2.size
174
+ groups = []
175
+
176
+ hash.each do |category_name, records|
177
+ groups.push([category_name, records.size])
102
178
  end
103
-
104
- strings.reverse!
105
-
106
- strings.map! do |string|
107
- target_string = TargetString.new
108
- target_string.evaluated = false
109
- target_string.data = string
110
- target_string
179
+
180
+ sorted_groups_by_n_records_asc = groups.sort do |array_a, array_b|
181
+ number_of_records_in_a = array_a[1]
182
+ number_of_records_in_b = array_b[1]
183
+ number_of_records_in_a <=> number_of_records_in_b
111
184
  end
112
185
 
113
- if configuration.group
114
- groups = strings.group_by do |string|
115
- string.data.size
186
+ sorted_groups_by_n_records_asc.reverse.each_with_index do |key, index|
187
+ line, records = key[0], hash[key[0]]
188
+
189
+ detailed_output.push('')
190
+
191
+ group = Template::Group.new
192
+ group.percent = ('%2.2f%%' % ((records.size.to_f / lines) * 100)).to_s.to_ansi.red.to_s
193
+ group.number = (index + 1).to_s.to_ansi.red.to_s
194
+ group.items = records.size.to_s.to_ansi.cyan.to_s
195
+ group.line = line.chomp.to_ansi.green.to_s
196
+ summary_output.push(group.to_s)
197
+ detailed_output.push(group.to_s)
198
+
199
+ sorted_items_in_group = records.sort do |a, b|
200
+ a[:score] <=> b[:score]
116
201
  end
117
- else
118
- groups = { 0 => strings }
119
- end
120
202
 
121
- counter = 0
122
- groups.each do |key, group|
123
- group.each do |string_1|
124
- counter = 0
125
- unless string_1.evaluated
126
- if configuration.summary
127
- summary_string = string_1.to_s
128
- else
129
- puts "****>>" + string_1.to_s
130
- end
131
- end
132
- string_1.evaluated = true
133
- group.each do |string_2|
134
- next if string_2.evaluated
135
- similarity = string_1.to_s.similarity(string_2.to_s)
136
- scores = string_1.to_s.scores(string_2.to_s).inspect
137
- template = "%5.f %s"
138
- bindings = [similarity, string_2, scores]
139
- if similarity >= configuration.threshold
140
- string_2.evaluated = true
141
- counter += 1
142
- unless configuration.summary
143
- puts template % bindings
144
- end
145
- end
146
- end
147
- if counter > 0
148
- puts "#{counter} #{summary_string}"
149
- end
203
+ sorted_items_in_group.reverse.each_with_index do |record, index|
204
+ item = Template::Item.new
205
+ item.count = (index + 1).to_s.rjust(4, ' ').to_ansi.cyan.to_s
206
+ item.total = records.size.to_s.ljust(4, ' ').to_ansi.cyan.to_s
207
+ item.score = ('%4.2f%%' % (record[:score] * 100)).rjust(7, ' ').to_ansi.green.to_s
208
+ item.line = record[:line]
209
+ detailed_output.push(item.to_s)
150
210
  end
211
+
151
212
  end
152
213
 
214
+ summary_output.each do |output_line|
215
+ puts output_line
216
+ end
217
+
218
+ unless options[:summary]
219
+ detailed_output.each do |output_line|
220
+ puts output_line
221
+ end
222
+ end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ix-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuyoshi Tlacaelel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2020-02-05 00:00:00.000000000 Z
@@ -24,8 +24,8 @@ dependencies:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.0.4
27
- description:
28
- email:
27
+ description:
28
+ email:
29
29
  executables:
30
30
  - ix
31
31
  - ix-acronym
@@ -151,6 +151,7 @@ executables:
151
151
  - ix-json-to-csv
152
152
  - ix-json-to-dot
153
153
  - ix-json-to-html-table
154
+ - ix-json-to-html-table-2
154
155
  - ix-json-to-ruby-hash
155
156
  - ix-json-to-table
156
157
  - ix-json-to-table-2
@@ -431,6 +432,7 @@ files:
431
432
  - bin/ix-json-to-csv
432
433
  - bin/ix-json-to-dot
433
434
  - bin/ix-json-to-html-table
435
+ - bin/ix-json-to-html-table-2
434
436
  - bin/ix-json-to-ruby-hash
435
437
  - bin/ix-json-to-table
436
438
  - bin/ix-json-to-table-2
@@ -582,10 +584,10 @@ files:
582
584
  - bin/ix-wrap
583
585
  - bin/ix-xy
584
586
  - bin/ix-zebra
585
- homepage:
587
+ homepage:
586
588
  licenses: []
587
589
  metadata: {}
588
- post_install_message:
590
+ post_install_message:
589
591
  rdoc_options: []
590
592
  require_paths:
591
593
  - lib
@@ -600,8 +602,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
600
602
  - !ruby/object:Gem::Version
601
603
  version: '0'
602
604
  requirements: []
603
- rubygems_version: 3.1.2
604
- signing_key:
605
+ rubygems_version: 3.0.3
606
+ signing_key:
605
607
  specification_version: 4
606
608
  summary: ix - string manipulation tools
607
609
  test_files: []