asker-tool 2.1.2 → 2.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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +17 -18
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +43 -74
  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 +19 -3
  17. data/lib/asker/checker.rb +152 -53
  18. data/lib/asker/cli.rb +19 -22
  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 +58 -32
  26. data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +6 -6
  27. data/lib/asker/displayer/concept_ai_displayer.rb +132 -0
  28. data/lib/asker/displayer/concept_displayer.rb +29 -0
  29. data/lib/asker/displayer/stats_displayer.rb +14 -0
  30. data/lib/asker/exporter/code_gift_exporter.rb +10 -11
  31. data/lib/asker/exporter/concept_ai_gift_exporter.rb +23 -11
  32. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +9 -7
  33. data/lib/asker/exporter/concept_doc_exporter.rb +9 -15
  34. data/lib/asker/exporter/output_file_exporter.rb +18 -0
  35. data/lib/asker/files/config.ini +37 -0
  36. data/lib/asker/files/example-code.haml +0 -0
  37. data/lib/asker/files/example-concept.haml +29 -0
  38. data/lib/asker/files/language/du/templates.yaml +50 -0
  39. data/lib/asker/files/language/en/connectors.yaml +44 -0
  40. data/lib/asker/files/language/en/mistakes.yaml +37 -0
  41. data/lib/asker/files/language/en/templates.yaml +29 -0
  42. data/lib/asker/files/language/es/connectors.yaml +92 -0
  43. data/lib/asker/files/language/es/mistakes.yaml +82 -0
  44. data/lib/asker/files/language/es/templates.yaml +29 -0
  45. data/lib/asker/files/language/fr/connectors.yaml +92 -0
  46. data/lib/asker/files/language/fr/mistakes.yaml +82 -0
  47. data/lib/asker/files/language/fr/templates.yaml +29 -0
  48. data/lib/asker/files/language/javascript/connectors.yaml +11 -0
  49. data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
  50. data/lib/asker/files/language/javascript/templates.yaml +3 -0
  51. data/lib/asker/files/language/math/connectors.yaml +2 -0
  52. data/lib/asker/files/language/math/mistakes.yaml +2 -0
  53. data/lib/asker/files/language/math/templates.yaml +1 -0
  54. data/lib/asker/files/language/python/connectors.yaml +11 -0
  55. data/lib/asker/files/language/python/mistakes.yaml +26 -0
  56. data/lib/asker/files/language/python/templates.yaml +3 -0
  57. data/lib/asker/files/language/ruby/connectors.yaml +11 -0
  58. data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
  59. data/lib/asker/files/language/ruby/templates.yaml +3 -0
  60. data/lib/asker/files/language/sql/connectors.yaml +6 -0
  61. data/lib/asker/files/language/sql/mistakes.yaml +11 -0
  62. data/lib/asker/files/language/sql/templates.yaml +2 -0
  63. data/lib/asker/formatter/concept_string_formatter.rb +9 -8
  64. data/lib/asker/formatter/question_gift_formatter.rb +9 -1
  65. data/lib/asker/lang/lang.rb +18 -12
  66. data/lib/asker/lang/lang_factory.rb +26 -5
  67. data/lib/asker/lang/text_actions.rb +87 -69
  68. data/lib/asker/loader/code_loader.rb +3 -3
  69. data/lib/asker/loader/content_loader.rb +9 -5
  70. data/lib/asker/loader/file_loader.rb +2 -11
  71. data/lib/asker/loader/haml_loader.rb +15 -0
  72. data/lib/asker/loader/image_url_loader.rb +5 -8
  73. data/lib/asker/loader/input_loader.rb +23 -7
  74. data/lib/asker/loader/project_loader.rb +32 -29
  75. data/lib/asker/logger.rb +3 -4
  76. data/lib/asker/project.rb +28 -52
  77. data/lib/asker/skeleton.rb +73 -0
  78. metadata +62 -73
  79. data/docs/changelog/v2.1.md +0 -99
  80. data/docs/commands.md +0 -15
  81. data/docs/contributions.md +0 -18
  82. data/docs/history.md +0 -40
  83. data/docs/idea.md +0 -44
  84. data/docs/inputs/README.md +0 -39
  85. data/docs/inputs/code.md +0 -69
  86. data/docs/inputs/concepts.md +0 -142
  87. data/docs/inputs/jedi.md +0 -68
  88. data/docs/inputs/tables.md +0 -112
  89. data/docs/inputs/templates.md +0 -87
  90. data/docs/install/README.md +0 -38
  91. data/docs/install/manual.md +0 -26
  92. data/docs/install/scripts.md +0 -26
  93. data/docs/revise/asker-file.md +0 -41
  94. data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
  95. data/docs/revise/buenas-practicas/02-formulario.md +0 -35
  96. data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
  97. data/docs/revise/buenas-practicas/04-resultados.md +0 -17
  98. data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
  99. data/docs/revise/ejemplos/01/README.md +0 -27
  100. data/docs/revise/ejemplos/02/README.md +0 -31
  101. data/docs/revise/ejemplos/03/README.md +0 -31
  102. data/docs/revise/ejemplos/04/README.md +0 -37
  103. data/docs/revise/ejemplos/05/README.md +0 -25
  104. data/docs/revise/ejemplos/06/README.md +0 -43
  105. data/docs/revise/ejemplos/README.md +0 -11
  106. data/docs/revise/projects.md +0 -74
  107. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  108. data/lib/asker/code/code.rb +0 -53
  109. data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
  110. data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
  111. data/lib/asker/exporter/main.rb +0 -9
@@ -1,31 +0,0 @@
1
-
2
- # Ejemplo 03
3
-
4
- Vamos a ampliar las definiciones del concepto `obiwan`.
5
-
6
- ## Input
7
-
8
- Hemos modificado el fichero [`starwars.haml`](./starwars.haml),
9
- ampliando las definiciones del concepto `obiwan`.
10
-
11
- Además hemos incluido
12
- una definición de tipo `image_url`. Esto es, un URL a una imagen, la cual
13
- identifica de forma inequívoca el conceto al cual se refiere.
14
-
15
- > Por tanto, podemos tener definiciones de texto y URL a una imagen.
16
-
17
- ## Ejecución
18
-
19
- Para ejecutar *darts* usando como entrada el fichero con los conceptos, hacemos:
20
-
21
- `./darts file docs/es/ejemplos/03/starwars.haml`
22
-
23
- Vemos que aparece en pantalla la siguiente [información](./starwars-log.txt).
24
-
25
- ## Output
26
-
27
- Se ha generado este [fichero](./starwars-gift.txt) con las preguntas en
28
- format Gift, preparadas para cargarse en Moodle.
29
-
30
- > Podemos comprobar como al aumentar las definiciones aumenta significativamente
31
- el número de preguntas que se generan.
@@ -1,37 +0,0 @@
1
-
2
- # Ejemplo 04
3
-
4
- Vamos a incluir más conceptos que tengan que ver con personajes de starwars
5
- dentro del mismo mapa.
6
-
7
- ## Input
8
-
9
- Consultar el fichero [`starwars.haml`](./starwars.haml) de entrada,
10
- con los nuevos conceptos.
11
-
12
- Hemos incluido en cada concepto una etiqueta con el nombre "tags". tags es una
13
- lista de términos que ayuda a definir el concepto. Es como una nube de palabras.
14
- Esta lista (tags) se usa para evaluar cuańto de cerca está la definición de un
15
- concepto con respecto a otro semánticamente. Bueno, es una aproximación.
16
-
17
- Esta valor de distancia semántica entre conceptos ayuda a formar preguntas
18
- más difíciles para el alumno, proponiéndole varias alternativas, no al azar, sino
19
- aquellas que tengan una "semántica" más parecida.
20
-
21
- Cuantos más conceptos tenga el mapa, más complejas serán las preguntas y más
22
- difícil responder al alumno.
23
-
24
- ## Ejecución
25
-
26
- Para ejecutar *darts* usando como entrada el fichero con los conceptos, hacemos:
27
-
28
- `./darts file docs/es/ejemplos/04/starwars.haml`
29
-
30
- Vemos que aparece en pantalla la siguiente [información](./starwars-log.txt).
31
-
32
- ## Output
33
-
34
- Se ha generado este [fichero](./starwars-gift.txt) con las preguntas en
35
- format Gift, preparadas para cargarse en Moodle.
36
-
37
- Podemos comprobar como al incluir más conceptos aumentan las preguntas.
@@ -1,25 +0,0 @@
1
-
2
- # Ejemplo 05
3
-
4
- Vamos a ampliar aún más el mapa conceptual añadiendo definiciones a todos
5
- los conceptos del mapa.
6
-
7
- ## Input
8
-
9
- Hemos modificado el fichero [`starwars.haml`](./starwars.haml),
10
- añadiendo definiciones al resto de conceptos del mapa.
11
-
12
- ## Ejecución
13
-
14
- Para ejecutar *darts* usando como entrada el fichero con los conceptos, hacemos:
15
-
16
- `./darts file docs/es/ejemplos/05/starwars.haml`
17
-
18
- Vemos que aparece en pantalla la siguiente [información](./starwars-log.txt).
19
-
20
- ## Output
21
-
22
- Se ha generado este [fichero](./starwars-gift.txt) con las preguntas en
23
- format Gift, preparadas para cargarse en Moodle.
24
-
25
- Al incluir más conceptos aumenta el número de preguntas que se generan.
@@ -1,43 +0,0 @@
1
-
2
- # Ejemplo 06
3
-
4
- Vamos a ampliar aún más el concepto `obiwan`, pero ahora vamos a incluir
5
- nueva información en forma de "tablas".
6
-
7
- ## Input
8
-
9
- Hemos modificado el fichero [`starwars.haml`](./starwars.haml),
10
- ampliando la información del concepto `obiwan` con "tablas". Éstas sirven
11
- para incluir nueva información que acompaña al concepto pero
12
- que no puede ser "definición" porque no identifica al concepto
13
- (No es un valor único de dicho concepto).
14
-
15
- > Usamos **definiciones** para representar información que sólo posee dicho concepto.
16
- Es informacion única para él.
17
- > Usamos las **tablas** para representar información asociada al concepto pero
18
- no de forma única. Estos datos se pueden repetir en otros conceptos del mapa conceptual.
19
-
20
- Por ejemplo, vamos a añadir "tabla" con información de "atributo,valor".
21
- Esto es un conjunto de atributos del personaje "obiwan" junto con el valor de
22
- cada uno.
23
-
24
- Las "tablas" pueden tener tienen uno o dos campos. Cada campo tiene que tener
25
- un nombre.
26
-
27
- > En el futuro se podrán hacer tablas con más de 2 campos. Por ahora, no.
28
-
29
- ## Ejecución
30
-
31
- Para ejecutar *darts* usando como entrada el fichero con los conceptos, hacemos:
32
-
33
- `./darts file docs/es/ejemplos/06/starwars.haml`
34
-
35
- Vemos que aparece en pantalla la siguiente [información](./starwars-log.txt).
36
-
37
- ## Output
38
-
39
- Se ha generado este [fichero](./starwars-gift.txt) con las preguntas en
40
- format Gift, preparadas para cargarse en Moodle.
41
-
42
- > Podemos comprobar como al incluir las tablas sigue aumentando
43
- el número de preguntas que se generan.
@@ -1,11 +0,0 @@
1
-
2
- # Ejemplos
3
-
4
- |Ejemplo | Descripción |
5
- |-------- |------------ |
6
- |[ejemplo 01](01/README.md) | Crear un concepto con una definición |
7
- |[ejemplo 02](02/README.md) | Cambiar XML por HAML |
8
- |[ejemplo 03](03/README.md) | Añadimos más definiciones y una imagen al concepto |
9
- |[ejemplo 04](04/README.md) | Incluimos más conceptos dentro del mismo mapa pero sin definirlos |
10
- |[ejemplo 05](05/README.md) | Añadimos definiciones a todos los conceptos del mapa |
11
- |[ejemplo 06](06/README.md) | Usamos tablas para añadir más información a un concepto |
@@ -1,74 +0,0 @@
1
-
2
- *Extra configuration params*
3
- ===========================
4
-
5
- =begin
6
- lConfig={
7
- #category => :none,
8
- #formula_weights => [1,1,1],
9
- #outputdir => 'output',
10
- #logname => 'default.log',
11
- #verbose => true,
12
- #:show_mode => :default
13
- :outputname => 'asir1-idp1314-gift.txt',
14
- :lesson_file => 'asir1-idp1314-lesson.txt',
15
- :lesson_separator => ' |',
16
- :inputdirs => 'input/idp',
17
- :process_file => 'idp-u1.xml'
18
- }
19
- =end
20
-
21
-
22
- Los parámetros más importantes son:
23
- * **:inputdirs**: Una lista de todos los directorios de entrada separados
24
- por comas. Por defecto será *input*. Se aconseja hacer subdirectorios
25
- dentro de input para organizar los ficheros XML, e incluir los subdirectorios
26
- dentro de este parámetro.
27
- * **:process_file**: Como los directorios de entrada pueden contener un número
28
- elevado de ficheros XML (Cosa además muy recomendable), este parámetro
29
- indica el nombre del fichero XML que se desea procesar en este momento.
30
-
31
- El resto no es obligatorio especificarlos, y de podrían dejar los valores por defecto.
32
-
33
- Ejemplo de script con más parámetros:
34
-
35
- require_relative 'sys/interviewer'
36
-
37
- lConfig={
38
- :category => :none,
39
- :formula_weights => [1,1,1],
40
- :outputdir => 'output',
41
- :outputname => 'default.txt',
42
- :logname => 'default.log',
43
- :verbose => true,
44
- :show_mode => :full
45
- :lesson_file => 'lesson.txt',
46
- :lesson_separator => ' |',
47
- :inputdirs => 'input/idp,input/etc',
48
- :process_file => 'commands.xml'
49
- }
50
-
51
- Interviewer.instance.run(lConfig)
52
-
53
- Pero si quieres saber más, ahí van otros parámetros que podemos configurar
54
- al ejecutar la herramienta:
55
- * **:outputdir**: Nombre del directorio de salida. Por defecto será *output*.
56
- * **:outputname**: Nombre del fichero de salida donde se guardarán las preguntas
57
- generadas.
58
- * **:lesson_file**: Cuando se indica este parámetro se crea un fichero de
59
- salida con el contenido de los conceptos en modo texto.
60
- * **:lesson_separator**: Por defecto es |. Es un caracter separador para las
61
- distintas columnas de las tablas.
62
- * **:category**: Nombre de la categoría Moodle donde se cargarán las preguntas.
63
- Por defecto no se establece ninguna categoría Moodle.
64
- * **:formula_weights**: Son pesos que se utilizarán en la fórmula que calcula
65
- la proximidad o cercanía entre dos conceptos diferentes.
66
- * **:logname**: Nombre del fichero de log. Este fichero registra las acciones
67
- realizadas por script. Por defecto toma el valor *default.log*.
68
- * **:verbose**: Si es *true* se emiten mensajes por pantalla de los pasos
69
- realizados. Por defecto toma el valor *true*.
70
- * **:show_mode**: Cuando la herramienta termina muestra por pantalla un resumen
71
- de los datos procesados. El valor por defecto es *:default*. Además acepta
72
- los valores *:none* para no mostrar salida, y *:resume* que muestra un
73
- breve resumen.
74
-
@@ -1,48 +0,0 @@
1
-
2
- require_relative '../../lang/lang_factory'
3
- require_relative '../../ai/question'
4
-
5
- class BaseCodeAI
6
- def name
7
- File.basename(@data_object.filename)
8
- end
9
-
10
- def num
11
- @num += 1
12
- end
13
-
14
- def clone_array(array)
15
- out = []
16
- array.each { |item| out << item.dup }
17
- out
18
- end
19
-
20
- def lines_to_s(lines)
21
- out = ''
22
- lines.each_with_index do |line,index|
23
- out << "%2d: #{line}\n"%(index+1)
24
- end
25
- out
26
- end
27
-
28
- def lines_to_html(lines)
29
- out = ''
30
- lines.each_with_index do |line,index|
31
- out << "%2d: #{line}</br>"%(index+1)
32
- end
33
- out
34
- end
35
-
36
- def find_make_methods
37
- list = self.public_methods.sort
38
- list.select! { |name| name.to_s.start_with? 'make_'}
39
- list.delete(:make_questions)
40
- list
41
- end
42
-
43
- def make_questions
44
- list = find_make_methods
45
- list.each { |m| @questions += self.send m }
46
- @questions
47
- end
48
- end
@@ -1,53 +0,0 @@
1
- require_relative 'ai/code_ai_factory'
2
- require_relative '../project'
3
- require_relative '../formatter/code_string_formatter'
4
-
5
- # Contains code data input
6
- class Code
7
- attr_reader :dirname, :filename, :type
8
- attr_accessor :process, :features
9
- attr_reader :lines, :questions
10
-
11
- def initialize(dirname, filename, type)
12
- @dirname = dirname
13
- @filename = filename
14
- @type = type
15
- @filepath = File.join(@dirname, @filename)
16
- @process = false
17
- @features = []
18
- @lines = load(@filepath)
19
- @questions = []
20
- @code_ai = CodeAIFactory.get(self)
21
- end
22
-
23
- def process?
24
- @process
25
- end
26
-
27
- def make_questions
28
- return unless process?
29
- @questions += @code_ai.make_questions
30
- end
31
-
32
- def lines_to_s(lines)
33
- out = ''
34
- lines.each_with_index do |line, index|
35
- out << format("%2d| #{line}\n", (index + 1))
36
- end
37
- out
38
- end
39
-
40
- def debug
41
- out = CodeStringFormatter.to_s(self)
42
- p = Project.instance
43
- p.verbose out
44
- end
45
-
46
- private
47
-
48
- def load(filepath)
49
- return if filepath.nil?
50
- content = File.read(filepath)
51
- content.split("\n")
52
- end
53
- end
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'terminal-table'
4
-
5
- # Show ConceptAI info on screen
6
- class ConceptAIScreenExporter
7
- def self.export_all(concepts_ai)
8
- @concepts_ai = concepts_ai
9
- project = Project.instance
10
- return if project.show_mode == :none
11
-
12
- # Create table HEAD
13
- screen_table = Terminal::Table.new do |st|
14
- st << ['Concept','Questions','Entries','xFactor',
15
- 'd','b','f','i','s','t']
16
- st << :separator
17
- end
18
-
19
- # Create table BODY
20
- total = {}
21
- total[:q] = total[:e] = total[:c] = 0
22
- total[:sd] = total[:sb] = total[:sf] = 0
23
- total[:si] = total[:ss] = total[:st] = 0
24
-
25
- @concepts_ai.each do |concept_ai|
26
- if concept_ai.process?
27
- e = concept_ai.texts.size
28
- concept_ai.tables.each { |t| e += t.fields.size * t.rows.size }
29
-
30
- sd = concept_ai.questions[:d].size
31
- sb = concept_ai.questions[:b].size
32
- sf = concept_ai.questions[:f].size
33
- si = concept_ai.questions[:i].size
34
- ss = concept_ai.questions[:s].size
35
- st = concept_ai.questions[:t].size
36
- t = sd + sb + sf + si + ss + st
37
-
38
- if e == 0
39
- factor = 'Unkown'
40
- else
41
- factor = (t.to_f/e.to_f).round(2).to_s
42
- end
43
- screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
44
- t, e, factor, sd, sb, sf, si, ss, st]
45
-
46
- total[:q] += t ; total[:e] += e; total[:c] += 1
47
- total[:sd] += sd; total[:sb] += sb; total[:sf] += sf
48
- total[:si] += si; total[:ss] += ss; total[:st] += st
49
- end
50
- end
51
- return if total[:c] == 0 # No concepts to be process?
52
-
53
- # Add row with excluded questions
54
- export_excluded_questions(screen_table, @concepts_ai)
55
-
56
- # Create table TAIL
57
- screen_table.add_separator
58
- screen_table.add_row [Rainbow("TOTAL = #{total[:c]}").bright,
59
- Rainbow(total[:q].to_s).bright,
60
- Rainbow(total[:e].to_s).bright,
61
- Rainbow((total[:q].to_f/total[:e].to_f).round(2)).bright,
62
- total[:sd], total[:sb], total[:sf],
63
- total[:si], total[:ss], total[:st]]
64
- export_notes
65
- project.verbose screen_table.to_s + "\n"
66
- end
67
-
68
- def self.export_excluded_questions(screen_table, concepts_ai)
69
- # Create table BODY
70
- total = {}
71
- total[:q] = total[:c] = 0
72
- total[:sd] = total[:sb] = total[:sf] = 0
73
- total[:si] = total[:ss] = total[:st] = 0
74
-
75
- concepts_ai.each do |concept_ai|
76
- if concept_ai.process?
77
- sd = concept_ai.excluded_questions[:d].size
78
- sb = concept_ai.excluded_questions[:b].size
79
- sf = concept_ai.excluded_questions[:f].size
80
- si = concept_ai.excluded_questions[:i].size
81
- ss = concept_ai.excluded_questions[:s].size
82
- st = concept_ai.excluded_questions[:t].size
83
- t = sd + sb + sf + si + ss + st
84
-
85
- total[:q] += t ; total[:c] += 1
86
- total[:sd] += sd; total[:sb] += sb; total[:sf] += sf
87
- total[:si] += si; total[:ss] += ss; total[:st] += st
88
- end
89
- end
90
- screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
91
- total[:q], '-', '-',
92
- total[:sd], total[:sb],
93
- total[:sf], total[:si],
94
- total[:ss], total[:st]]
95
- end
96
-
97
- def self.export_notes
98
- p = Project.instance
99
- p.verbose "\n[INFO] Showing CONCEPT statistics\n"
100
- p.verbose ' * Exclude questions: ' +
101
- Application.instance.config['questions']['exclude'].to_s
102
- p.verbose ' * Annotations:'
103
- p.verbose ' ├── (d) Definitions <= Concept.def'
104
- p.verbose ' ├── (b) Table Matching <= ' \
105
- 'Concept.table.rows.columns'
106
- p.verbose ' ├── (f) Tables 1 Field <= Concept.table.fields.size==1'
107
- p.verbose ' ├── (i) Images URL <= ' \
108
- "Concept.def{:type => 'image_url'}"
109
- p.verbose ' ├── (s) Sequences <= ' \
110
- "Concept.table{:sequence => '...'}"
111
- p.verbose ' └── (t) Table Rows&Cols <= ' \
112
- 'Concept.table.rows.columns'
113
- p.verbose "\n"
114
- end
115
- end