asker-tool 2.1.5 → 2.1.6

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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +2 -3
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +10 -6
  6. data/lib/asker/ai/ai.rb +4 -0
  7. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  8. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  9. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  10. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  11. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  12. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  13. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  14. data/lib/asker/ai/concept_ai.rb +1 -0
  15. data/lib/asker/ai/stages/stage_t.rb +76 -76
  16. data/lib/asker/application.rb +18 -2
  17. data/lib/asker/checker.rb +112 -30
  18. data/lib/asker/cli.rb +12 -25
  19. data/lib/asker/data/code.rb +73 -0
  20. data/lib/asker/data/column.rb +31 -21
  21. data/lib/asker/data/concept.rb +42 -45
  22. data/lib/asker/data/data_field.rb +14 -0
  23. data/lib/asker/data/row.rb +75 -52
  24. data/lib/asker/data/table.rb +89 -42
  25. data/lib/asker/data/world.rb +57 -33
  26. data/lib/asker/displayer/concept_ai_displayer.rb +56 -37
  27. data/lib/asker/displayer/concept_displayer.rb +7 -5
  28. data/lib/asker/displayer/stats_displayer.rb +4 -3
  29. data/lib/asker/exporter/concept_ai_gift_exporter.rb +5 -3
  30. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -3
  31. data/lib/asker/exporter/output_file_exporter.rb +1 -1
  32. data/lib/asker/files/config.ini +37 -0
  33. data/lib/asker/files/example-concept.haml +0 -1
  34. data/lib/asker/{lang/locales → files/language}/du/templates.yaml +0 -0
  35. data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
  36. data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
  37. data/lib/asker/{lang/locales → files/language}/en/templates.yaml +0 -0
  38. data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
  39. data/lib/asker/{lang/locales → files/language}/es/mistakes.yaml +0 -0
  40. data/lib/asker/{lang/locales → files/language}/es/templates.yaml +0 -0
  41. data/lib/asker/{lang/locales → files/language}/fr/connectors.yaml +0 -0
  42. data/lib/asker/{lang/locales → files/language}/fr/mistakes.yaml +0 -0
  43. data/lib/asker/{lang/locales → files/language}/fr/templates.yaml +0 -0
  44. data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
  45. data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
  46. data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
  47. data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
  48. data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
  49. data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
  50. data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
  51. data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
  52. data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
  53. data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
  54. data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
  55. data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
  56. data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
  57. data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
  58. data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
  59. data/lib/asker/lang/lang.rb +17 -10
  60. data/lib/asker/lang/lang_factory.rb +26 -5
  61. data/lib/asker/lang/text_actions.rb +87 -69
  62. data/lib/asker/loader/code_loader.rb +3 -3
  63. data/lib/asker/loader/content_loader.rb +9 -5
  64. data/lib/asker/loader/file_loader.rb +2 -11
  65. data/lib/asker/loader/haml_loader.rb +15 -0
  66. data/lib/asker/loader/image_url_loader.rb +5 -8
  67. data/lib/asker/loader/input_loader.rb +8 -9
  68. data/lib/asker/loader/project_loader.rb +10 -8
  69. data/lib/asker/logger.rb +3 -3
  70. data/lib/asker/project.rb +24 -50
  71. data/lib/asker/skeleton.rb +22 -13
  72. metadata +39 -37
  73. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  74. data/lib/asker/code/code.rb +0 -53
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'terminal-table'
4
+ require_relative '../application'
4
5
  require_relative '../logger'
5
6
 
6
7
  # Display ConceptAI stat on screen
@@ -9,10 +10,18 @@ class ConceptAIDisplayer
9
10
  # Display ConceptAI stat on screen
10
11
  # @param concepts_ai (Array)
11
12
  def self.show(concepts_ai)
13
+ stages = Application.instance.config['questions']['stages']
12
14
  # Create table HEAD
13
15
  screen_table = Terminal::Table.new do |st|
14
- st << ['Concept','Questions','Entries','xFactor',
15
- 'd','b','f','i','s','t']
16
+ title = ['Concept', 'Questions', 'Entries', 'xFactor']
17
+ %w[d b f i s t].each do |i|
18
+ if stages.include? i.to_sym
19
+ title << i
20
+ next
21
+ end
22
+ title << Rainbow(i).yellow.bright
23
+ end
24
+ st << title
16
25
  st << :separator
17
26
  end
18
27
  # Create table BODY
@@ -22,32 +31,37 @@ class ConceptAIDisplayer
22
31
  total[:si] = total[:ss] = total[:st] = 0
23
32
 
24
33
  concepts_ai.each do |concept_ai|
25
- if concept_ai.process?
26
- e = concept_ai.texts.size
27
- concept_ai.tables.each { |t| e += t.fields.size * t.rows.size }
34
+ next unless concept_ai.process?
28
35
 
29
- sd = concept_ai.questions[:d].size
30
- sb = concept_ai.questions[:b].size
31
- sf = concept_ai.questions[:f].size
32
- si = concept_ai.questions[:i].size
33
- ss = concept_ai.questions[:s].size
34
- st = concept_ai.questions[:t].size
35
- t = sd + sb + sf + si + ss + st
36
+ e = concept_ai.texts.size
37
+ concept_ai.tables.each { |t| e += t.fields.size * t.rows.size }
36
38
 
37
- if e == 0
38
- factor = 'Unkown'
39
- else
40
- factor = (t.to_f/e.to_f).round(2).to_s
41
- end
42
- screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
43
- t, e, factor, sd, sb, sf, si, ss, st]
39
+ sd = sb = sf = 0
40
+ si = ss = st = 0
41
+ sd = concept_ai.questions[:d].size if stages.include? :d
42
+ sb = concept_ai.questions[:b].size if stages.include? :b
43
+ sf = concept_ai.questions[:f].size if stages.include? :f
44
+ si = concept_ai.questions[:i].size if stages.include? :i
45
+ ss = concept_ai.questions[:s].size if stages.include? :s
46
+ st = concept_ai.questions[:t].size if stages.include? :t
47
+ t = sd + sb + sf + si + ss + st
44
48
 
45
- total[:q] += t ; total[:e] += e; total[:c] += 1
46
- total[:sd] += sd; total[:sb] += sb; total[:sf] += sf
47
- total[:si] += si; total[:ss] += ss; total[:st] += st
48
- end
49
+ factor = 'Unkown'
50
+ factor = (t.to_f / e).round(2).to_s unless e.zero?
51
+ screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
52
+ t, e, factor, sd, sb, sf, si, ss, st]
53
+
54
+ total[:q] += t
55
+ total[:e] += e
56
+ total[:c] += 1
57
+ total[:sd] += sd
58
+ total[:sb] += sb
59
+ total[:sf] += sf
60
+ total[:si] += si
61
+ total[:ss] += ss
62
+ total[:st] += st
49
63
  end
50
- return if total[:c] == 0 # No concepts to be process?
64
+ return if total[:c].zero? # No concepts to be process?
51
65
 
52
66
  # Add row with excluded questions
53
67
  export_excluded_questions(screen_table, concepts_ai)
@@ -57,7 +71,7 @@ class ConceptAIDisplayer
57
71
  screen_table.add_row [Rainbow("TOTAL = #{total[:c]}").bright,
58
72
  Rainbow(total[:q].to_s).bright,
59
73
  Rainbow(total[:e].to_s).bright,
60
- Rainbow((total[:q].to_f/total[:e].to_f).round(2)).bright,
74
+ Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
61
75
  total[:sd], total[:sb], total[:sf],
62
76
  total[:si], total[:ss], total[:st]]
63
77
  export_notes
@@ -72,19 +86,24 @@ class ConceptAIDisplayer
72
86
  total[:si] = total[:ss] = total[:st] = 0
73
87
 
74
88
  concepts_ai.each do |concept_ai|
75
- if concept_ai.process?
76
- sd = concept_ai.excluded_questions[:d].size
77
- sb = concept_ai.excluded_questions[:b].size
78
- sf = concept_ai.excluded_questions[:f].size
79
- si = concept_ai.excluded_questions[:i].size
80
- ss = concept_ai.excluded_questions[:s].size
81
- st = concept_ai.excluded_questions[:t].size
82
- t = sd + sb + sf + si + ss + st
89
+ next unless concept_ai.process?
83
90
 
84
- total[:q] += t ; total[:c] += 1
85
- total[:sd] += sd; total[:sb] += sb; total[:sf] += sf
86
- total[:si] += si; total[:ss] += ss; total[:st] += st
87
- end
91
+ sd = concept_ai.excluded_questions[:d].size
92
+ sb = concept_ai.excluded_questions[:b].size
93
+ sf = concept_ai.excluded_questions[:f].size
94
+ si = concept_ai.excluded_questions[:i].size
95
+ ss = concept_ai.excluded_questions[:s].size
96
+ st = concept_ai.excluded_questions[:t].size
97
+ t = sd + sb + sf + si + ss + st
98
+
99
+ total[:q] += t
100
+ total[:c] += 1
101
+ total[:sd] += sd
102
+ total[:sb] += sb
103
+ total[:sf] += sf
104
+ total[:si] += si
105
+ total[:ss] += ss
106
+ total[:st] += st
88
107
  end
89
108
  screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
90
109
  total[:q], '-', '-',
@@ -1,4 +1,5 @@
1
1
 
2
+ require_relative '../application'
2
3
  require_relative '../formatter/concept_string_formatter'
3
4
  require_relative '../logger'
4
5
 
@@ -7,17 +8,18 @@ module ConceptDisplayer
7
8
  ##
8
9
  # Show concepts on screen
9
10
  # @param concepts (Array)
10
- # @param show_mode (Symbol)
11
- def self.show(concepts, show_mode = :default)
12
- return if show_mode == :none
11
+ def self.show(concepts)
12
+ show_mode = Application.instance.config['global']['show_mode']
13
+ return unless show_mode
14
+
13
15
  msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
14
16
  Logger.verbose msg
15
17
  case show_mode
16
- when :resume
18
+ when 'resume'
17
19
  s = "* Concepts (#{concepts.count}): "
18
20
  concepts.each { |c| s += c.name + ', ' }
19
21
  Logger.verbose s
20
- when :default
22
+ when 'default'
21
23
  # Only show Concepts with process attr true
22
24
  concepts.each do |c|
23
25
  Logger.verbose ConceptStringFormatter.to_s(c) if c.process?
@@ -1,13 +1,14 @@
1
+ require_relative '../application'
1
2
  require_relative 'concept_ai_displayer'
2
3
  require_relative 'code_displayer'
3
4
 
4
5
  # Display Stats on screen.
5
6
  module StatsDisplayer
6
- def self.show(data, show_mode)
7
- return if show_mode == :none
7
+ def self.show(data)
8
+ return unless Application.instance.config['global']['show_mode']
8
9
 
9
10
  # show_final_results
10
11
  ConceptAIDisplayer.show(data[:concepts_ai])
11
- CodeDisplayer.show(data[:codes])
12
+ CodeDisplayer.show(data[:codes_ai])
12
13
  end
13
14
  end
@@ -6,17 +6,19 @@ require_relative '../formatter/question_gift_formatter'
6
6
  # Export ConceptIA data to gift to outputfile
7
7
  module ConceptAIGiftExporter
8
8
  ##
9
- # Export list of ConceptAI into outpufile
9
+ # Export an array of ConceptAI objects from Project into GIFT outpufile
10
+ # @param concepts_ai (Array)
11
+ # @param project (Project)
10
12
  def self.export_all(concepts_ai, project)
11
13
  concepts_ai.each { |concept_ai| export(concept_ai, project) }
12
14
  end
13
15
 
14
- def self.export(concept_ai, project)
16
+ private_class_method def self.export(concept_ai, project)
15
17
  return unless concept_ai.process?
16
18
 
17
19
  file = project.get(:outputfile)
18
20
  file.write head(concept_ai.name)
19
- project.stages.each_key do |stage|
21
+ Application.instance.config['questions']['stages'].each do |stage|
20
22
  concept_ai.questions[stage].each do |question|
21
23
  file.write(QuestionGiftFormatter.to_s(question))
22
24
  end
@@ -5,6 +5,10 @@ require_relative '../formatter/question_hash_formatter'
5
5
 
6
6
  # Use to export data from ConceptIA to YAML format
7
7
  module ConceptAIYAMLExporter
8
+ ##
9
+ # Export array of ConceptAI objects from Project to YAML output file
10
+ # @param concepts_ai (Array)
11
+ # @param project (Project)
8
12
  def self.export_all(concepts_ai, project)
9
13
  questions = []
10
14
  concepts_ai.each do |concept_ai|
@@ -16,11 +20,11 @@ module ConceptAIYAMLExporter
16
20
  project.get(:yamlfile).write(output.to_yaml)
17
21
  end
18
22
 
19
- def self.get_questions_from(concept_ai)
23
+ private_class_method def self.get_questions_from(concept_ai)
20
24
  data = []
21
25
  return data unless concept_ai.process?
22
- stages = Project.instance.stages
23
- stages.each_key do |stage|
26
+
27
+ Application.instance.config['questions']['stages'].each do |stage|
24
28
  concept_ai.questions[stage].each do |question|
25
29
  question.lang = concept_ai.lang
26
30
  data << QuestionHashFormatter.to_hash(question)
@@ -11,7 +11,7 @@ module OutputFileExporter
11
11
  def self.export(data, project)
12
12
  ConceptAIGiftExporter.export_all(data[:concepts_ai], project)
13
13
  # UNDER DEVELOPMENT
14
- CodeGiftExporter.export_all(data[:codes], project.get(:outputfile))
14
+ CodeGiftExporter.export_all(data[:codes_ai], project.get(:outputfile))
15
15
  ConceptAIYAMLExporter.export_all(data[:concepts_ai], project)
16
16
  ConceptDocExporter.export_all(data[:concepts], project.get(:lessonfile))
17
17
  end
@@ -3,7 +3,44 @@
3
3
  ; Accept yes|no
4
4
  internet = no
5
5
 
6
+ ; Output files will be save into output folder.
7
+ outputdir = output
8
+
9
+ ; Display on screen messages about program progress
10
+ ; Accept yes|no
11
+ verbose = yes
12
+ color = yes
13
+
14
+ ; Accept resume|default
15
+ show_mode = default
16
+
17
+ [languages]
18
+ ; Default code language
19
+ default = en
20
+
21
+ ; List of code languages to be loaded
22
+ ; Accept yes|no
23
+ en = yes
24
+ es = yes
25
+ javascript = yes
26
+ math = no
27
+ python = yes
28
+ ruby = yes
29
+ sql = yes
30
+
31
+ [ai]
32
+
33
+ ; Concept formula weights to find neighbors: context, tags, tables
34
+ formula_weights = 1, 1, 1
35
+
6
36
  [questions]
37
+
38
+ ; List of values d,b,f,i,s,t
39
+ stages = d,b,f,i,s,t
40
+
41
+ ; Questions category
42
+ category =
43
+
7
44
  ; Exclude questions with this texts into their names.
8
45
  ; Accept Comma separated strings.
9
46
  exclude =
@@ -2,7 +2,6 @@
2
2
 
3
3
  %concept
4
4
  %names AC/DC, ACDC
5
- %tags single, seat, leg, backrest
6
5
  %tags rock, band, australia
7
6
  %def Australian rock band formed by Scottish-born brothers Malcolm and Angus Young
8
7
  %table{ :fields => 'members'}
@@ -23,19 +23,26 @@ class Lang
23
23
  private
24
24
 
25
25
  def load_files
26
- dirbase = File.dirname(__FILE__)
27
- filename = File.join(dirbase, 'locales', @code, 'templates.yaml')
26
+ dirbase = File.join(File.dirname(__FILE__), '..', 'files', 'language')
27
+ filepath = File.join(dirbase, @code, 'templates.yaml')
28
+ @templates = load_yaml_file(filepath)
29
+ filepath = File.join(dirbase, @code, 'connectors.yaml')
30
+ @connectors = load_yaml_file(filepath)
31
+ filepath = File.join(dirbase, @code, 'mistakes.yaml')
32
+ @mistakes = load_yaml_file(filepath)
33
+ end
34
+
35
+ # rubocop:disable Security/YAMLLoad
36
+ def load_yaml_file(filepath)
28
37
  begin
29
- @templates = YAML.load(File.new(filename))
38
+ content = YAML.load(File.new(filepath))
30
39
  rescue StandardError => e
31
- Logger.verboseln "[ERROR] lang.initialize(): Reading YAML file <#{filename}>"
32
- Logger.verboseln "[ADVISE] Revise apostrophe into string without \\ char\n"
40
+ Logger.verboseln '[ERROR] Lang.initialize():' \
41
+ " Reading YAML file <#{filepath}>"
42
+ Logger.verboseln '[ADVISE] Revise apostrophe into string without \ symbol'
33
43
  raise e
34
44
  end
35
- filename = File.join(dirbase, 'locales', @code, 'connectors.yaml')
36
- @connectors = YAML.load(File.new(filename))
37
-
38
- filename = File.join(dirbase, 'locales', @code, 'mistakes.yaml')
39
- @mistakes = YAML.load(File.new(filename))
45
+ content
40
46
  end
47
+ # rubocop:enable Security/YAMLLoad
41
48
  end
@@ -2,18 +2,39 @@
2
2
 
3
3
  require 'singleton'
4
4
  require_relative 'lang'
5
- require_relative '../project'
5
+ require_relative '../application'
6
6
 
7
- # LangFactory#get
7
+ ##
8
+ # LangFactory singleton class.
9
+ # * Read all language codes defined into configuration file
10
+ # * and load every language
11
+ # Lang objects are reused
8
12
  class LangFactory
9
13
  include Singleton
10
14
 
15
+ ##
16
+ # Read all language codes from configuration file and load every language
11
17
  def initialize
18
+ @default = Application.instance.config['languages']['default'].downcase
12
19
  @langs = {}
13
- Project.instance.locales.each { |i| @langs[i] = Lang.new(i) }
20
+ Application.instance.config['languages'].each_pair do |key, value|
21
+ code = key.downcase
22
+ next if code == 'default'
23
+
24
+ @langs[code] = Lang.new(code) if value.downcase == 'yes'
25
+ end
26
+ end
27
+
28
+ ##
29
+ # Return Lang object associated to code
30
+ # @param code (String)
31
+ def get(code)
32
+ @langs[code]
14
33
  end
15
34
 
16
- def get(locale)
17
- @langs[locale]
35
+ ##
36
+ # Return default Lang object
37
+ def default
38
+ get(@default)
18
39
  end
19
40
  end
@@ -1,134 +1,152 @@
1
1
  # encoding: utf-8
2
2
 
3
+ ##
4
+ # Set of functions used by Lang class
3
5
  module TextActions
4
-
5
- def text_for(pOption, pText1="",pText2="",pText3="",pText4="",pText5="",pText6="",pText7="")
6
- text1=pText1
7
- text2=pText2
8
- text3=pText3
9
- text4=pText4
10
- text5=pText5
11
- text6=pText6
12
- text7=pText7
13
-
14
- # TODO: check if exists pOption before use it
15
- renderer = ERB.new(@templates[pOption])
16
- output = renderer.result(binding)
17
- return output
6
+ ##
7
+ # Return text indicated by lang code...
8
+ def text_for(option, *input)
9
+ text1 = input[0]
10
+ text2 = input[1]
11
+ text3 = input[2]
12
+ text4 = input[3]
13
+ text5 = input[4]
14
+ text6 = input[5]
15
+ text7 = input[6]
16
+
17
+ # Check if exists option before use it
18
+ raise "[ERROR] Unkown template #{option}" if @templates[option].nil?
19
+
20
+ renderer = ERB.new(@templates[option])
21
+ renderer.result(binding)
18
22
  end
19
23
 
20
- def text_filter_connectors(pText, pFilter)
21
- input_lines = pText.split(".")
24
+ ##
25
+ # Convert input text into output text struct
26
+ # @param input (String) Input text
27
+ # @param filter (Boolean) true => apply filter, false => dont filter
28
+ # @return Array
29
+ def text_filter_connectors(input, filter)
30
+ input_lines = input.split('.')
22
31
  output_lines = []
23
32
  output_words = []
24
33
  input_lines.each_with_index do |line, rowindex|
25
- row=[]
34
+ row = []
26
35
  line.split(' ').each_with_index do |word, colindex|
27
36
  flag = @connectors.include? word.downcase
28
37
 
29
38
  # if <word> is a conector and <pFilter>==true Then Choose this <word>
30
39
  # if <word> isn't a conector and <pFilter>==true and <word>.length>1 Then Choose this <word>
31
- if (flag and pFilter) || (!flag and !pFilter and word.length>1)
32
- output_words << {:word => word,
33
- :row => rowindex,
34
- :col => colindex }
40
+ if (flag and filter) || (!flag and !filter and word.length > 1)
41
+ output_words << {:word => word, :row => rowindex, :col => colindex }
35
42
  row << (output_words.size-1)
36
43
  else
37
44
  row << word
38
- end
45
+ end
39
46
  end
40
47
  row << '.'
41
48
  output_lines << row
42
- end
49
+ end
43
50
 
44
51
  indexes = []
45
- exclude = ['[', ']', '(', ')', "\"" ]
52
+ exclude = ['[', ']', '(', ')', '"']
46
53
  output_words.each_with_index do |item, index|
47
54
  flag = true
48
- exclude.each { |e| flag = false if (item[:word].include?(e)) }
55
+ exclude.each { |e| flag = false if item[:word].include? e }
49
56
  indexes << index if flag
50
57
  end
51
58
 
52
- result={ :lines => output_lines, :words => output_words, :indexes => indexes }
53
- return result
59
+ { lines: output_lines, words: output_words, indexes: indexes }
54
60
  end
55
61
 
62
+ ##
63
+ # Return text with connectors
56
64
  def text_with_connectors(text)
57
65
  text_filter_connectors(text, false)
58
66
  end
59
67
 
68
+ ##
69
+ # Return text without connectors
60
70
  def text_without_connectors(text)
61
- text_filter_connectors(text, true)
71
+ text_filter_connectors(text, true)
62
72
  end
63
73
 
64
- def build_text_from_filtered(pStruct, pIndexes)
65
- lines = pStruct[:lines]
66
- lIndexes = pIndexes.sort
67
- counter = 1
68
- lText = ''
74
+ def build_text_from_filtered(input_struct, input_indexes)
75
+ lines = input_struct[:lines]
76
+ indexes = input_indexes.sort
77
+ counter = 1
78
+ text = ''
69
79
 
70
80
  lines.each do |line|
71
81
  line.each do |value|
72
82
  if value.class == String
73
- lText += (' ' + value)
83
+ text += (' ' + value)
74
84
  elsif value == value.to_i
75
85
  # INFO: ruby 2.4 unifies Fixnum and Bignum into Integer
76
86
  # Avoid using deprecated classes.
77
- if lIndexes.include? value
78
- lText += " [#{counter.to_s}]"
87
+ if indexes.include? value
88
+ text += " [#{counter}]"
79
89
  counter += 1
80
90
  else
81
- lword = pStruct[:words][value][:word]
82
- lText += (' ' + lword)
91
+ word = input_struct[:words][value][:word]
92
+ text += (' ' + word)
83
93
  end
84
94
  end
85
95
  end
86
96
  end
87
- lText.gsub!(' .', '.')
88
- lText.gsub!(' ,', ',')
89
- lText = lText[1, lText.size] if lText[0] == ' '
90
- lText
97
+ text.gsub!(' .', '.')
98
+ text.gsub!(' ,', ',')
99
+ text = text[1, text.size] if text[0] == ' '
100
+ text
91
101
  end
92
102
 
93
- def count_words(pInputText)
94
- return 0 if pInputText.nil?
95
-
96
- t = pInputText.clone
97
- t.gsub!("\n"," ")
98
- t.gsub!("/"," ")
99
- #t.gsub!("-"," ")
100
- t.gsub!("."," ")
101
- t.gsub!(","," ")
102
- t.gsub!(" "," ")
103
- t.gsub!(" "," ")
104
- t.split(" ").count
103
+ ##
104
+ # Count words
105
+ # @param input (String)
106
+ # @return Integer
107
+ def count_words(input)
108
+ return 0 if input.nil?
109
+
110
+ t = input.clone
111
+ t.gsub!("\n", ' ')
112
+ t.gsub!('/', ' ')
113
+ # t.gsub!("-"," ")
114
+ t.gsub!('.', ' ')
115
+ t.gsub!(',', ' ')
116
+ t.gsub!(' ', ' ')
117
+ t.gsub!(' ', ' ')
118
+ t.split(' ').count
105
119
  end
106
120
 
107
- def do_mistake_to(pText = '')
108
- lText = pText.dup
121
+ ##
122
+ # Do mistake to input
123
+ # @param input (String)
124
+ # @return String
125
+ def do_mistake_to(input = '')
126
+ text = input.dup
109
127
  keys = @mistakes.keys
110
128
 
111
129
  # Try to do mistake with one item from the key list
112
130
  keys.shuffle!
113
131
  keys.each do |key|
114
- if lText.include? key.to_s
115
- values = @mistakes[key].split(',')
116
- values.shuffle!
117
- lText = lText.sub(key.to_s,values[0].to_s)
118
- return lText
119
- end
132
+ next unless text.include? key.to_s
133
+
134
+ values = @mistakes[key].split(',')
135
+ values.shuffle!
136
+ text = text.sub(key.to_s, values[0].to_s)
137
+ return text
120
138
  end
121
139
 
122
140
  # Force mistake by swapping letters
123
- if lText.size > 1
124
- i = rand(lText.size - 2)
125
- aux = lText[i]
126
- lText[i] = lText[i + 1]
127
- lText[i + 1] = aux
141
+ if text.size > 1
142
+ i = rand(text.size - 2)
143
+ aux = text[i]
144
+ text[i] = text[i + 1]
145
+ text[i + 1] = aux
128
146
  end
129
- return lText if lText != pText
147
+ return text if text != input
130
148
 
131
- lText + 's'
149
+ text + 's'
132
150
  end
133
151
 
134
152
  def hide_text(input_text)