qti 2.20.1 → 2.21.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86c46f8f8cc44f5462d95d93455aefd56aae83e8f6291a492459ba9da425c510
4
- data.tar.gz: 63429e02991279043a3a0380e720fee6bb27b36132cfcb97837a68ddec0dd0cc
3
+ metadata.gz: e16530dedba8c33540a05d73d7c497eb3d3d84a75891fe080443187c85a68eff
4
+ data.tar.gz: 5e83f70021c905abba7bafb12cbad27532868f972d423f21c5ca4209a00af5c8
5
5
  SHA512:
6
- metadata.gz: 2f628da6521093b39fa707d8305431e5282f4a5c9bae5f386f8e91b59d56be873f3705844b146a220a97e6ca1d8eb7f7b822e22d37c162499b4e418b2aebe5e3
7
- data.tar.gz: 232035507f0adfe737d0271c9e2d4200330e0921205c4ae2f5800564d755ed82630ad58955615102e6e3c40392f4270fb0a9167e70f769c29e701b96eb6acf40
6
+ metadata.gz: 61b96b3a9dd2096b2b15766d2e577a90f225181de62ddd9f2304e2163e84e08011b31b5395157a81ce131eb3b160a94e9455de8faf1c2888488edf7168bafb03
7
+ data.tar.gz: 812ef9edf33a9b3fd1f1712767b14ab63a21f845a02df89affc98feebff7698cca561c3945eb2988e5b41ed23bdb736e697024421d20d247dc5bcdb684a5d381
@@ -58,12 +58,25 @@ module Qti
58
58
  end
59
59
  end
60
60
 
61
+ # rubocop:disable Metrics/AbcSize
61
62
  def scoring_data(choice_nodes)
62
- set_var_nodes = choice_nodes.select do |choice_node|
63
- choice_node.at_xpath('.//xmlns:setvar')&.content&.to_f&.positive?
63
+ setvar_nodes(choice_nodes).map do |value_node|
64
+ scoring_options = {}
65
+ scoring_options['points'] = value_node.at_xpath('.//xmlns:setvar')&.content&.to_f
66
+
67
+ if value_node.attributes['correctanswer']&.value&.downcase == 'yes'
68
+ scoring_options['correct_answer'] = true
69
+ end
70
+
71
+ ScoringData.new(value_node.at_xpath('.//xmlns:varequal').content, rcardinality,
72
+ scoring_options: scoring_options)
64
73
  end
65
- set_var_nodes.map do |value_node|
66
- ScoringData.new(value_node.at_xpath('.//xmlns:varequal').content, rcardinality)
74
+ end
75
+ # rubocop:enable Metrics/AbcSize
76
+
77
+ def setvar_nodes(choice_nodes)
78
+ choice_nodes.select do |choice_node|
79
+ choice_node.at_xpath('.//xmlns:setvar')&.content&.to_f&.positive?
67
80
  end
68
81
  end
69
82
  end
@@ -22,9 +22,11 @@ module Qti
22
22
 
23
23
  def solutions
24
24
  node.xpath('.//xmlns:var_set').map do |anode|
25
+ output = anode.at_xpath('.//xmlns:answer')&.text
26
+
25
27
  {
26
28
  inputs: vars_at_node(anode),
27
- output: anode.at_xpath('.//xmlns:answer')&.text&.to_f
29
+ output: formula_scientific_notation ? output : output&.to_f
28
30
  }
29
31
  end
30
32
  end
@@ -49,6 +51,10 @@ module Qti
49
51
  @node.at_xpath('.//xmlns:formulas/@decimal_places')&.value
50
52
  end
51
53
 
54
+ def formula_scientific_notation
55
+ @node.at_xpath('.//xmlns:formulas/@scientific_notation')&.value == 'true'
56
+ end
57
+
52
58
  def formulas
53
59
  node.xpath('.//xmlns:formula').map(&:text)
54
60
  end
data/lib/qti/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Qti
2
- VERSION = '2.20.1'.freeze
2
+ VERSION = '2.21.0'.freeze
3
3
  end
@@ -0,0 +1,69 @@
1
+ <?xml version="1.0"encoding="UTF-8"?>
2
+ <questestinterop xmlns="http://www.imsglobal.org/xsd/ims_qtiasiv1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd">
3
+ <assessment title="1.2 Import Quiz" ident="A1001">
4
+ <section title="Main" ident="S1002">
5
+ <item ident="d74b47a4abeeed159e030bfecbcecea2" title="My question title">
6
+ <itemmetadata>
7
+ <qtimetadata>
8
+ <qtimetadatafield>
9
+ <fieldlabel>question_type</fieldlabel>
10
+ <fieldentry>multiple_choice_question</fieldentry>
11
+ </qtimetadatafield>
12
+ <qtimetadatafield>
13
+ <fieldlabel>points_possible</fieldlabel>
14
+ <fieldentry>10.0</fieldentry>
15
+ </qtimetadatafield>
16
+ <qtimetadatafield>
17
+ <fieldlabel>original_answer_ids</fieldlabel>
18
+ <fieldentry>93bbcb84-3281-4d99-b243-79ba4051e654,3cd6d311-07cd-4ec0-b2db-3048e6cf1128</fieldentry>
19
+ </qtimetadatafield>
20
+ <qtimetadatafield>
21
+ <fieldlabel>assessment_question_identifierref</fieldlabel>
22
+ <fieldentry>9f47365e112840d80a79a960b1b0b6a7</fieldentry>
23
+ </qtimetadatafield>
24
+ <qtimetadatafield>
25
+ <fieldlabel>calculator_type</fieldlabel>
26
+ <fieldentry>none</fieldentry>
27
+ </qtimetadatafield>
28
+ </qtimetadata>
29
+ </itemmetadata>
30
+ <presentation>
31
+ <material>
32
+ <mattext texttype="text/html">&lt;p&gt;the correct answer is letter A&lt;/p&gt;</mattext>
33
+ </material>
34
+ <response_lid ident="response1" rcardinality="Single">
35
+ <render_choice>
36
+ <response_label ident="93bbcb84-3281-4d99-b243-79ba4051e654">
37
+ <material>
38
+ <mattext texttype="text/html">A</mattext>
39
+ </material>
40
+ </response_label>
41
+ <response_label ident="3cd6d311-07cd-4ec0-b2db-3048e6cf1128">
42
+ <material>
43
+ <mattext texttype="text/html">B</mattext>
44
+ </material>
45
+ </response_label>
46
+ </render_choice>
47
+ </response_lid>
48
+ </presentation>
49
+ <resprocessing>
50
+ <outcomes>
51
+ <decvar maxvalue="100" minvalue="0" varname="SCORE" vartype="Decimal"/>
52
+ </outcomes>
53
+ <respcondition>
54
+ <conditionvar>
55
+ <varequal respident="response1">93bbcb84-3281-4d99-b243-79ba4051e654</varequal>
56
+ </conditionvar>
57
+ <setvar action="Set" varname="SCORE">10.0</setvar>
58
+ </respcondition>
59
+ <respcondition correctanswer="Yes">
60
+ <conditionvar>
61
+ <varequal respident="response1">3cd6d311-07cd-4ec0-b2db-3048e6cf1128</varequal>
62
+ </conditionvar>
63
+ <setvar action="Set" varname="SCORE">5.0</setvar>
64
+ </respcondition>
65
+ </resprocessing>
66
+ </item>
67
+ </section>
68
+ </assessment>
69
+ </questestinterop>
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <questestinterop xmlns="http://www.imsglobal.org/xsd/ims_qtiasiv1p2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2p1.xsd">
3
+ <item ident="id39adb107fd2d03971a2d4206c6550dc" title="Formula">
4
+ <itemmetadata>
5
+ <qtimetadata>
6
+ <qtimetadatafield>
7
+ <fieldlabel>question_type</fieldlabel>
8
+ <fieldentry>calculated_question</fieldentry>
9
+ </qtimetadatafield>
10
+ <qtimetadatafield>
11
+ <fieldlabel>points_possible</fieldlabel>
12
+ <fieldentry>1.0</fieldentry>
13
+ </qtimetadatafield>
14
+ <qtimetadatafield>
15
+ <fieldlabel>assessment_question_identifierref</fieldlabel>
16
+ <fieldentry>i2c64259a331bc821bdcb2f326cf36631</fieldentry>
17
+ </qtimetadatafield>
18
+ </qtimetadata>
19
+ </itemmetadata>
20
+ <presentation>
21
+ <material>
22
+ <mattext texttype="text/html">&lt;div&gt;&lt;p&gt;What number is [x]&lt;/p&gt;&lt;/div&gt;</mattext>
23
+ </material>
24
+ <response_str ident="response1" rcardinality="Single">
25
+ <render_fib fibtype="Decimal">
26
+ <response_label ident="answer1"/>
27
+ </render_fib>
28
+ </response_str>
29
+ </presentation>
30
+ <resprocessing>
31
+ <outcomes>
32
+ <decvar maxvalue="100" minvalue="0" varname="SCORE" vartype="Decimal"/>
33
+ </outcomes>
34
+ <respcondition title="correct">
35
+ <conditionvar>
36
+ <other/>
37
+ </conditionvar>
38
+ <setvar varname="SCORE" action="Set">100</setvar>
39
+ </respcondition>
40
+ <respcondition title="incorrect">
41
+ <conditionvar>
42
+ <not>
43
+ <other/>
44
+ </not>
45
+ </conditionvar>
46
+ <setvar varname="SCORE" action="Set">0</setvar>
47
+ </respcondition>
48
+ </resprocessing>
49
+ <itemproc_extension>
50
+ <calculated>
51
+ <answer_tolerance margin_type="">0</answer_tolerance>
52
+ <formulas decimal_places="0" scientific_notation="true">
53
+ <formula>5+x</formula>
54
+ </formulas>
55
+ <vars>
56
+ <var name="x" scale="0">
57
+ <min>0</min>
58
+ <max>10</max>
59
+ </var>
60
+ </vars>
61
+ <var_sets>
62
+ <var_set ident="7d5006729d5dbc489c374a2cd5f41352">
63
+ <var name="x">9</var>
64
+ <answer>1*10^1</answer>
65
+ </var_set>
66
+ <var_set ident="15f629c4045e838e172b04824caa3893">
67
+ <var name="x">2</var>
68
+ <answer>7*10^0</answer>
69
+ </var_set>
70
+ </var_sets>
71
+ </calculated>
72
+ </itemproc_extension>
73
+ </item>
74
+ </questestinterop>
@@ -244,4 +244,26 @@ describe Qti::V1::Models::AssessmentItem do
244
244
  end
245
245
  end
246
246
  end
247
+
248
+ context 'multiple choice with "vary points by answer"' do
249
+ let(:file_path) { File.join('spec', 'fixtures', 'items_1.2', 'choice_vary_points_by_answer.xml') }
250
+ let(:test_object) { Qti::V1::Models::Assessment.from_path!(file_path) }
251
+ let(:assessment_item_refs) { test_object.assessment_items }
252
+ let(:loaded_class) { described_class.new(assessment_item_refs.first) }
253
+
254
+ describe '#scoring_data_structs' do
255
+ it 'collects all the correct answers' do
256
+ struct = loaded_class.scoring_data_structs
257
+ expect(struct.size).to eq 2
258
+ expect(struct.map(&:values)).to eq %w[93bbcb84-3281-4d99-b243-79ba4051e654 3cd6d311-07cd-4ec0-b2db-3048e6cf1128]
259
+ end
260
+
261
+ it 'collect all the points answer points' do
262
+ struct = loaded_class.scoring_data_structs
263
+ expect(struct.size).to eq 2
264
+ expect(struct.map(&:scoring_options)).to eq([{ 'points' => 10.0 },
265
+ { 'points' => 5.0, 'correct_answer' => true }])
266
+ end
267
+ end
268
+ end
247
269
  end
@@ -13,6 +13,7 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
13
13
  shared_examples_for 'reading_formulas' do
14
14
  it 'reads formulas correctly' do
15
15
  expect(loaded_class.formula_decimal_places).to eq(formula_decimal_places)
16
+ expect(loaded_class.formula_scientific_notation).to eq(formula_scientific_notation)
16
17
  expect(loaded_class.formulas).to eq(formula_formulas)
17
18
  end
18
19
  end
@@ -41,6 +42,7 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
41
42
  let(:answer_tolerance) { '0' }
42
43
  let(:margin_of_error) { { margin: '0', margin_type: 'absolute' } }
43
44
  let(:formula_decimal_places) { '0' }
45
+ let(:formula_scientific_notation) { false }
44
46
  let(:formula_formulas) { ['x'] }
45
47
 
46
48
  let(:item_title) { '<div><p>What number is [x]</p></div>' }
@@ -61,6 +63,7 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
61
63
  let(:answer_tolerance) { '0' }
62
64
  let(:margin_of_error) { { margin: '0', margin_type: 'absolute' } }
63
65
  let(:formula_decimal_places) { '0' }
66
+ let(:formula_scientific_notation) { false }
64
67
  let(:formula_formulas) { ['x+y'] }
65
68
 
66
69
  let(:item_title) { '<div><p>[x] + [y]</p></div>' }
@@ -84,6 +87,7 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
84
87
  let(:answer_tolerance) { '10%' }
85
88
  let(:margin_of_error) { { margin: '10', margin_type: 'percent' } }
86
89
  let(:formula_decimal_places) { '2' }
90
+ let(:formula_scientific_notation) { false }
87
91
  let(:formula_formulas) { ['x=n*x', 'y=m*y', 'x+y'] }
88
92
 
89
93
  let(:item_title) { '<div><p>[n][x] + [m][y]</p></div>' }
@@ -100,4 +104,26 @@ describe Qti::V1::Models::Interactions::FormulaInteraction do
100
104
  include_examples 'reading_formulas'
101
105
  include_examples 'variables'
102
106
  end
107
+
108
+ context 'Formula with scientific notation' do
109
+ let(:file_path) { File.join(fixtures_path, 'formula_scientific.xml') }
110
+
111
+ let(:scoring_data_values) { ['1*10^1', '7*10^0'] }
112
+
113
+ let(:answer_tolerance) { '0' }
114
+ let(:formula_decimal_places) { '0' }
115
+ let(:formula_scientific_notation) { true }
116
+ let(:formula_formulas) { ['x'] }
117
+ let(:margin_of_error) { { margin: '0', margin_type: 'absolute' } }
118
+ let(:formula_formulas) { ['5+x'] }
119
+
120
+ let(:item_title) { '<div><p>What number is [x]</p></div>' }
121
+
122
+ let(:variables) { [{ max: 10.0, min: 0.0, name: 'x', precision: 0 }] }
123
+
124
+ include_examples 'scoring_data_structs'
125
+ include_examples 'reading_formulas'
126
+ include_examples 'answer_tolerance'
127
+ include_examples 'variables'
128
+ end
103
129
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qti
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.20.1
4
+ version: 2.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Diaz
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2023-08-11 00:00:00.000000000 Z
15
+ date: 2023-08-15 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: actionview
@@ -402,6 +402,7 @@ files:
402
402
  - spec/fixtures/items_1.2/canvas_multiple_fib_extra_brackets.xml
403
403
  - spec/fixtures/items_1.2/categorization.xml
404
404
  - spec/fixtures/items_1.2/choice.xml
405
+ - spec/fixtures/items_1.2/choice_vary_points_by_answer.xml
405
406
  - spec/fixtures/items_1.2/essay.xml
406
407
  - spec/fixtures/items_1.2/fib.xml
407
408
  - spec/fixtures/items_1.2/fib_feedback.xml
@@ -409,6 +410,7 @@ files:
409
410
  - spec/fixtures/items_1.2/formula.xml
410
411
  - spec/fixtures/items_1.2/formula_mform.xml
411
412
  - spec/fixtures/items_1.2/formula_mvar.xml
413
+ - spec/fixtures/items_1.2/formula_scientific.xml
412
414
  - spec/fixtures/items_1.2/hot_spot.xml
413
415
  - spec/fixtures/items_1.2/item_no_title.xml
414
416
  - spec/fixtures/items_1.2/matching.xml
@@ -776,6 +778,7 @@ test_files:
776
778
  - spec/fixtures/items_1.2/canvas_multiple_fib_extra_brackets.xml
777
779
  - spec/fixtures/items_1.2/categorization.xml
778
780
  - spec/fixtures/items_1.2/choice.xml
781
+ - spec/fixtures/items_1.2/choice_vary_points_by_answer.xml
779
782
  - spec/fixtures/items_1.2/essay.xml
780
783
  - spec/fixtures/items_1.2/fib.xml
781
784
  - spec/fixtures/items_1.2/fib_feedback.xml
@@ -783,6 +786,7 @@ test_files:
783
786
  - spec/fixtures/items_1.2/formula.xml
784
787
  - spec/fixtures/items_1.2/formula_mform.xml
785
788
  - spec/fixtures/items_1.2/formula_mvar.xml
789
+ - spec/fixtures/items_1.2/formula_scientific.xml
786
790
  - spec/fixtures/items_1.2/hot_spot.xml
787
791
  - spec/fixtures/items_1.2/item_no_title.xml
788
792
  - spec/fixtures/items_1.2/matching.xml