ix-cli 0.0.7 → 0.0.13

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: 43ba4c089dae9199af259e9f02a035744e7420962a118d853e0e676d2a5dd599
4
- data.tar.gz: 17d6460e0f39932ec59f1011638deb3df787239106bfac6616ab7355af18f9f7
3
+ metadata.gz: 943f1cbefd1b38913bd4291a440291b6997b9dce730e9990aacd8743f49ca24e
4
+ data.tar.gz: dff95cf081a6d4b9f319fa5b86e97f3265cd115f72137dd6bef6b3ca1167da24
5
5
  SHA512:
6
- metadata.gz: 57bc28846bb606f482574a62e5a6b338b1f988ca9b6350929b71849732dec880e9a57f1d1649189cd802a9359a5a8ebe9ac27f080aef42fe62ceb3b448cfe679
7
- data.tar.gz: 47f05a70186b648cff3277a8cfb2a6df62e5949fe2053d0108ec8d2555e57576d55e1c5fa802236273daeb6093752e8be12c872d3ffcc7d3c36de9e42aaaacca
6
+ metadata.gz: 523fa547597c6c94e3ba4b6b36dbb076ee5e199818ac72eb97d599c5a1043a0cad0bccd089b55457db447860cc476cb04e380d43d4e9b3fd88b3050ac428a583
7
+ data.tar.gz: 93600db984ace082d9ba956228e7b543dd5766ac7da5cd4e66183009535a6000613399c1cb9bf082b7a4d34002dedbdcc0ef6b73bcd9d3c3e444d2a818dbbe22
@@ -175,10 +175,42 @@ class Bcat
175
175
  end
176
176
  end
177
177
 
178
+ require 'optparse'
179
+
180
+ options = {}
181
+
182
+ OptionParser.new do |opts|
183
+
184
+ opts.banner = "Usage: #{$0} [OPTIONS]"
185
+
186
+ opts.on('-p', '--pre', 'Pre.') do |value|
187
+ options[:pre] = value
188
+ end
189
+
190
+
191
+ end.parse!
192
+
193
+ required_options = []
194
+ required_options.each do |option|
195
+ unless options[option]
196
+ $stderr.puts "Can not run #{option.to_s} was not given."
197
+ exit 1
198
+ end
199
+ end
200
+
178
201
  data = []
179
202
 
180
203
  STDIN.each_line do |line|
181
204
  data.push(line)
182
205
  end
183
206
 
207
+ if options[:pre]
208
+ puts '<pre>'
209
+ end
210
+
184
211
  puts Bcat::ANSI.new(data).to_html
212
+
213
+ if options[:pre]
214
+ puts '</pre>'
215
+ end
216
+
data/bin/ix-cat CHANGED
File without changes
@@ -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,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ print ARGV[0]
4
+
5
+ STDIN.each_line do |line|
6
+ puts line.chomp
7
+ end
8
+
@@ -3,7 +3,12 @@
3
3
  normal = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
4
4
  rot13 = "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM"
5
5
 
6
- STDIN.each_line do |line|
7
- puts line.tr!(normal, rot13)
6
+ STDIN.each_char do |char|
7
+ candidate = char.tr!(normal, rot13)
8
+ if candidate
9
+ print candidate
10
+ else
11
+ print char
12
+ end
8
13
  end
9
14
 
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'isna'
4
+
5
+ UNIVERSE = (0..9).to_a
6
+ ROT = 5
7
+ DIGIT_REGEX = /^\d$/
8
+
9
+ def resolve(set, candidate)
10
+ needle = set.index(candidate)
11
+ if (needle + ROT) > set.size
12
+ return (needle - set.size + ROT)
13
+ end
14
+ if (needle + ROT) < set.size
15
+ return needle + ROT
16
+ end
17
+ if (needle == 5)
18
+ return 0
19
+ end
20
+ end
21
+
22
+ STDIN.each_char do |char|
23
+ next if char.chomp == ''
24
+ unless char =~ DIGIT_REGEX
25
+ print char
26
+ next
27
+ end
28
+ rotation = resolve(UNIVERSE, char.to_i)
29
+ m = (0..9).to_a.map do |n|
30
+ if n.to_s == char
31
+ char.to_ansi.green.to_s
32
+ else
33
+ n.to_s
34
+ end
35
+ end
36
+ # puts "#{rotation.to_s.to_ansi.red.to_s} = [" + (m * ', ') + "]"
37
+ print rotation
38
+ end
39
+
@@ -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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ix-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kazuyoshi Tlacaelel
@@ -199,6 +199,7 @@ executables:
199
199
  - ix-pick
200
200
  - ix-planning-tickets
201
201
  - ix-prefix
202
+ - ix-prepend
202
203
  - ix-pretty
203
204
  - ix-print-and-run
204
205
  - ix-psd-to-json
@@ -217,6 +218,7 @@ executables:
217
218
  - ix-reverse
218
219
  - ix-right
219
220
  - ix-rm
221
+ - ix-rot5
220
222
  - ix-rot13
221
223
  - ix-rot3
222
224
  - ix-rps
@@ -477,6 +479,7 @@ files:
477
479
  - bin/ix-pick
478
480
  - bin/ix-planning-tickets
479
481
  - bin/ix-prefix
482
+ - bin/ix-prepend
480
483
  - bin/ix-pretty
481
484
  - bin/ix-print-and-run
482
485
  - bin/ix-psd-to-json
@@ -497,6 +500,7 @@ files:
497
500
  - bin/ix-rm
498
501
  - bin/ix-rot13
499
502
  - bin/ix-rot3
503
+ - bin/ix-rot5
500
504
  - bin/ix-rps
501
505
  - bin/ix-ruby-constructor-arguments
502
506
  - bin/ix-ruby-methods