ruql 0.1.5 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,6 +10,40 @@ class JSONRenderer
10
10
  end
11
11
 
12
12
  def render_quiz
13
- @output = @quiz.questions.map {|question| JSON.pretty_generate(question.to_JSON)}
13
+ @quiz.questions.each do |question|
14
+ case question
15
+ when MultipleChoice, SelectMultiple, TrueFalse then render_multiple_choice(question)
16
+ when FillIn then render_fill_in(question) # not currently supported
17
+ else
18
+ raise "Unknown question type: #{question}"
19
+ end
20
+ end
21
+ @output = JSON.pretty_generate(@json_array)
14
22
  end
23
+
24
+ def render_multiple_choice(question)
25
+ question_hash = {
26
+ "text" => question.question_text,
27
+ "answers" => answers_to_json_array(question.answers)
28
+ }
29
+ @json_array.push(question_hash)
30
+ end
31
+
32
+ def answers_to_json_array(answers)
33
+ answers_array = []
34
+ answers.each do |answer|
35
+ answer_json = {
36
+ "text" => answer.answer_text,
37
+ "explanation" => answer.explanation,
38
+ "correct" => answer.correct
39
+ }
40
+ answers_array.push(answer_json)
41
+ end
42
+ answers_array
43
+ end
44
+
45
+ def render_fill_in(q)
46
+ # fill-in-the-blank questions not currently supported
47
+ end
48
+
15
49
  end
@@ -0,0 +1,148 @@
1
+ class XMLRenderer
2
+ require 'builder'
3
+
4
+ attr_reader :output
5
+ def initialize(quiz,options={})
6
+ @output = ''
7
+ @b = Builder::XmlMarkup.new(:target => @output, :indent => 2)
8
+ @quiz = quiz
9
+ end
10
+
11
+ def render(thing)
12
+ case thing
13
+ when MultipleChoice,SelectMultiple,TrueFalse then render_multiple_choice(thing)
14
+ when FillIn then render_fill_in(thing)
15
+ else
16
+ raise "Unknown question type: #{thing}"
17
+ end
18
+ end
19
+
20
+ def render_quiz
21
+ # entire quiz can be in one question group, as long as we specify
22
+ # that ALL question from the group must be used to make the quiz.
23
+ xml_quiz do
24
+ # after preamble...
25
+ @b.question_groups do
26
+ @b.question_group(:select => @quiz.questions.length) do
27
+ @quiz.questions.each do |question|
28
+ self.render(question)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ @output
34
+ end
35
+
36
+ def render_fill_in(question)
37
+ @b.question :type => 'GS_Short_Answer_Question_Simple', :id => question.object_id.to_s(16) do
38
+ @b.metadata {
39
+ @b.parameters {
40
+ @b.rescale_score question.points
41
+ @b.type 'regexp'
42
+ }
43
+ }
44
+ # since we want all the options to appear, we create N option
45
+ # groups each containig 1 option, and specify that option to
46
+ # always be selected for inclusion in the quiz. If the original
47
+ # question specified 'random', use the 'randomize' attribute on
48
+ # option_groups to scramble the order in which displayed;
49
+ # otherwise, display in same order as answers appear in source.
50
+ @b.data {
51
+ @b.text { @b.cdata!(question.question_text) }
52
+ @b.option_groups(:randomize => !!question.randomize) {
53
+ @b.option_group(:select => 'all') {
54
+ question.answers.each do |answer|
55
+ option_args = {}
56
+ option_args['selected_score'] = answer.correct? ? 1 : 0
57
+ option_args['unselected_score'] =
58
+ question.multiple ? 1 - option_args['selected_score'] : 0
59
+ option_args['id'] = answer.object_id.to_s(16)
60
+ @b.option(option_args) do
61
+ answer_text = answer.answer_text
62
+ if answer_text.kind_of?(Regexp)
63
+ answer_text = answer_text.inspect
64
+ if !question.case_sensitive
65
+ answer_text += 'i'
66
+ end
67
+ end
68
+ @b.text { @b.cdata!(answer_text) }
69
+ @b.explanation { @b.cdata!(answer.explanation) } if answer.has_explanation?
70
+ end
71
+ end
72
+ }
73
+ }
74
+ }
75
+ end
76
+ end
77
+
78
+ def render_multiple_choice(question)
79
+ @b.question :type => 'GS_Choice_Answer_Question', :id => question.object_id.to_s(16) do
80
+ @b.metadata {
81
+ @b.parameters {
82
+ @b.rescale_score question.points
83
+ @b.choice_type (question.multiple ? 'checkbox' : 'radio')
84
+ }
85
+ }
86
+ # since we want all the options to appear, we create N option
87
+ # groups each containig 1 option, and specify that option to
88
+ # always be selected for inclusion in the quiz. If the original
89
+ # question specified 'random', use the 'randomize' attribute on
90
+ # option_groups to scramble the order in which displayed;
91
+ # otherwise, display in same order as answers appear in source.
92
+ @b.data {
93
+ @b.text { @b.cdata!(question.question_text) }
94
+ @b.option_groups(:randomize => !!question.randomize) {
95
+ question.answers.each do |a|
96
+ @b.option_group(:select => 'all') {
97
+ self.render_multiple_choice_answer a, question.multiple
98
+ }
99
+ end
100
+ }
101
+ }
102
+ end
103
+ end
104
+ alias :render_true_false :render_multiple_choice
105
+
106
+ def render_multiple_choice_answer(answer, multiple_allowed)
107
+ option_args = {}
108
+ option_args['selected_score'] = answer.correct? ? 1 : 0
109
+ option_args['unselected_score'] =
110
+ multiple_allowed ? 1 - option_args['selected_score'] : 0
111
+ option_args['id'] = answer.object_id.to_s(16)
112
+ @b.option(option_args) do
113
+ @b.text { @b.cdata!(answer.answer_text) }
114
+ @b.explanation { @b.cdata!(answer.explanation) } if answer.has_explanation?
115
+ end
116
+ end
117
+
118
+ private
119
+
120
+ def options_to_xml(h)
121
+ h.each_pair do |k,v|
122
+ if v.is_a?(Hash)
123
+ @b.__send__(k.to_sym) do
124
+ options_to_xml v
125
+ end
126
+ else
127
+ @b.__send__(k.to_sym, v)
128
+ end
129
+ end
130
+ end
131
+
132
+
133
+ def xml_quiz
134
+ @b.quiz do
135
+ @b.metadata do
136
+ @b.type 'quiz'
137
+ @b.title @quiz.title
138
+ options_to_xml @quiz.options
139
+ end
140
+ @b.preamble
141
+ @b.data do
142
+ yield
143
+ end
144
+ end
145
+ end
146
+
147
+ end
148
+
@@ -1,6 +1,10 @@
1
- class SelectMultiple < MultipleChoice
1
+ class SelectMultiple < Question
2
+
3
+ attr_accessor :multiple
4
+
2
5
  def initialize(text='', opts={})
3
6
  super
7
+ self.question_text = text
4
8
  self.multiple = true
5
9
  end
6
10
 
@@ -0,0 +1,18 @@
1
+ module Ruql
2
+ class Stats
3
+ attr_reader :output, :quiz
4
+ # a pseudo-renderer that just prints stats about the quiz
5
+ def initialize(quiz, options={})
6
+ @quiz = quiz
7
+ @output = []
8
+ end
9
+ def render_quiz
10
+ @output << "%3d questions" % quiz.questions.length
11
+ @output << " %3d (%d points) in no group" % [quiz.ungrouped_questions.length, quiz.ungrouped_points]
12
+ @output << " %3d (%d points) in %d groups" % [quiz.grouped_questions.length, quiz.grouped_points, quiz.groups.length]
13
+ @output << "%3d effective questions on quiz" % quiz.num_questions
14
+ @output << "%3d max points possible" % quiz.points
15
+ @output.join("\n")
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,6 @@
1
1
  class TrueFalse < Question
2
2
 
3
- def initialize(text='', correct_answer=false, opts=nil)
3
+ def initialize(text, correct_answer, opts=nil)
4
4
  super
5
5
  opts ||= {}
6
6
  opts[:explanation] ||= ''
@@ -0,0 +1,3 @@
1
+ module Ruql
2
+ VERSION = '1.0.5'
3
+ end
@@ -0,0 +1,43 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'ruql/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'ruql'
8
+ s.version = Ruql::VERSION
9
+ s.summary = "Ruby question language"
10
+ s.description = "Ruby-embedded DSL for creating short-answer quiz questions"
11
+ s.authors = ["Armando Fox"]
12
+ s.email = 'fox@berkeley.edu'
13
+ s.homepage = 'http://github.com/saasbook/ruql'
14
+ s.license = 'CC By-SA'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if s.respond_to?(:metadata)
19
+ s.metadata["allowed_push_host"] = "https://rubygems.org"
20
+
21
+ s.metadata["homepage_uri"] = s.homepage
22
+ s.metadata["source_code_uri"] = s.homepage
23
+ #s.metadata["changelog_uri"] = ''
24
+ else
25
+ raise "RubyGems 2.0 or newer is required to protect against " \
26
+ "public gem pushes."
27
+ end
28
+
29
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
+ s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
32
+ end
33
+
34
+ s.executables << 'ruql'
35
+
36
+ s.require_paths= ['lib']
37
+
38
+ s.add_development_dependency "bundler", "~> 1.17"
39
+ s.add_development_dependency "rake", "~> 10.0"
40
+ s.add_development_dependency "byebug"
41
+ s.add_development_dependency "rspec", "~> 3.0"
42
+ s.add_development_dependency "rspec_its"
43
+ end
metadata CHANGED
@@ -1,83 +1,113 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Armando Fox
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-08 00:00:00.000000000 Z
11
+ date: 2020-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: bundler
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
- - - '>='
17
+ - - "~>"
17
18
  - !ruby/object:Gem::Version
18
- version: '3.0'
19
+ version: '1.17'
20
+ type: :development
19
21
  prerelease: false
20
- name: builder
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
- - - '>='
24
+ - - "~>"
24
25
  - !ruby/object:Gem::Version
25
- version: '3.0'
26
- type: :runtime
26
+ version: '1.17'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: rake
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - '>='
31
+ - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: '1.0'
33
+ version: '10.0'
34
+ type: :development
33
35
  prerelease: false
34
- name: getopt
35
36
  version_requirements: !ruby/object:Gem::Requirement
36
37
  requirements:
37
- - - '>='
38
+ - - "~>"
38
39
  - !ruby/object:Gem::Version
39
- version: '1.0'
40
- type: :runtime
40
+ version: '10.0'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: byebug
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
- - - '>='
45
+ - - ">="
45
46
  - !ruby/object:Gem::Version
46
- version: '2.0'
47
+ version: '0'
48
+ type: :development
47
49
  prerelease: false
48
- name: rspec
49
50
  version_requirements: !ruby/object:Gem::Requirement
50
51
  requirements:
51
- - - '>='
52
+ - - ">="
52
53
  - !ruby/object:Gem::Version
53
- version: '2.0'
54
- type: :development
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: rspec
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
- - - ~>
59
+ - - "~>"
59
60
  - !ruby/object:Gem::Version
60
- version: '4.0'
61
+ version: '3.0'
62
+ type: :development
61
63
  prerelease: false
62
- name: activesupport
63
64
  version_requirements: !ruby/object:Gem::Requirement
64
65
  requirements:
65
- - - ~>
66
+ - - "~>"
66
67
  - !ruby/object:Gem::Version
67
- version: '4.0'
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec_its
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
68
76
  type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description: Ruby-embedded DSL for creating short-answer quiz questions
70
- email: fox@cs.berkeley.edu
84
+ email: fox@berkeley.edu
71
85
  executables:
72
86
  - ruql
73
87
  extensions: []
74
88
  extra_rdoc_files: []
75
89
  files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
76
97
  - bin/ruql
98
+ - bin/setup
99
+ - examples/estilo.css
100
+ - examples/example.rb
101
+ - examples/file.html
102
+ - examples/help.txt
103
+ - examples/preguntas-TFG-20140224-0050.txt
104
+ - examples/preguntas-TFG-20140224-0050.xml
105
+ - examples/prueba.js
77
106
  - lib/ruql.rb
78
107
  - lib/ruql/answer.rb
79
108
  - lib/ruql/dropdown.rb
80
109
  - lib/ruql/fill_in.rb
110
+ - lib/ruql/json.rb
81
111
  - lib/ruql/multiple_choice.rb
82
112
  - lib/ruql/open_assessment/criterion.rb
83
113
  - lib/ruql/open_assessment/open_assessment.rb
@@ -93,34 +123,37 @@ files:
93
123
  - lib/ruql/renderers/html_form_renderer.rb
94
124
  - lib/ruql/renderers/json_renderer.rb
95
125
  - lib/ruql/renderers/qualtrics_renderer.rb
126
+ - lib/ruql/renderers/xml_renderer.rb
96
127
  - lib/ruql/select_multiple.rb
128
+ - lib/ruql/stats.rb
97
129
  - lib/ruql/tex_output.rb
98
130
  - lib/ruql/true_false.rb
99
- - templates/autoqcm.tex.erb
100
- - templates/html5.html.erb
101
- - templates/htmlform.html.erb
131
+ - lib/ruql/version.rb
132
+ - ruql.gemspec
102
133
  homepage: http://github.com/saasbook/ruql
103
134
  licenses:
104
- - MIT
105
- metadata: {}
106
- post_install_message:
135
+ - CC By-SA
136
+ metadata:
137
+ allowed_push_host: https://rubygems.org
138
+ homepage_uri: http://github.com/saasbook/ruql
139
+ source_code_uri: http://github.com/saasbook/ruql
140
+ post_install_message:
107
141
  rdoc_options: []
108
142
  require_paths:
109
143
  - lib
110
144
  required_ruby_version: !ruby/object:Gem::Requirement
111
145
  requirements:
112
- - - '>='
146
+ - - ">="
113
147
  - !ruby/object:Gem::Version
114
148
  version: '0'
115
149
  required_rubygems_version: !ruby/object:Gem::Requirement
116
150
  requirements:
117
- - - '>='
151
+ - - ">="
118
152
  - !ruby/object:Gem::Version
119
153
  version: '0'
120
154
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 2.2.5
123
- signing_key:
155
+ rubygems_version: 3.0.8
156
+ signing_key:
124
157
  specification_version: 4
125
158
  summary: Ruby question language
126
159
  test_files: []