gipper 0.0.1
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.
- data/.gitignore +7 -0
- data/PostInstall.txt +5 -0
- data/README.rdoc +49 -0
- data/Rakefile +69 -0
- data/VERSION.yml +4 -0
- data/docs/gift_reference.pdf +0 -0
- data/features/fixtures/matching.gift +9 -0
- data/features/fixtures/missing_word.gift +8 -0
- data/features/fixtures/multiple_choice.gift +41 -0
- data/features/fixtures/numerical.gift +10 -0
- data/features/fixtures/short_answer.gift +10 -0
- data/features/fixtures/super_gift.txt +169 -0
- data/features/fixtures/true_or_false.gift +19 -0
- data/features/gift_parsing.feature +10 -0
- data/features/parse_matching_questions.feature +10 -0
- data/features/parse_missing_word.feature +10 -0
- data/features/parse_multiple_choice_questions.feature +10 -0
- data/features/parse_numerical_questions.feature +10 -0
- data/features/parse_short_answer_questions.feature +10 -0
- data/features/parse_true_or_false_questions.feature +10 -0
- data/features/steps/gift_parsing_steps.rb +546 -0
- data/features/steps/parse_matching_steps.rb +30 -0
- data/features/steps/parse_missing_word_steps.rb +58 -0
- data/features/steps/parse_multiple_choice_steps.rb +107 -0
- data/features/steps/parse_numerical_steps.rb +35 -0
- data/features/steps/parse_short_answer_steps.rb +42 -0
- data/features/steps/parse_steps.rb +7 -0
- data/features/steps/parse_true_or_false_steps.rb +61 -0
- data/features/support/env.rb +10 -0
- data/lib/answer.rb +165 -0
- data/lib/answers.rb +99 -0
- data/lib/gipper.rb +15 -0
- data/lib/question.rb +53 -0
- data/lib/quiz.rb +31 -0
- data/lib/special_charater_handler.rb +8 -0
- data/script/txt2html +71 -0
- data/script/txt2html.cmd +1 -0
- data/tasks/rspec.rake +21 -0
- data/test/answer_test.rb +152 -0
- data/test/answers_test.rb +126 -0
- data/test/custom_assertions.rb +68 -0
- data/test/fixtures/begins_with_comment.txt +6 -0
- data/test/question_test.rb +86 -0
- data/test/quiz_test.rb +65 -0
- data/test/special_character_handler_test.rb +43 -0
- data/test/test_helper.rb +19 -0
- metadata +125 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
Given /^a GIFT file of matching questions$/ do
|
3
|
+
file = File.open(File.join(File.dirname(__FILE__), *%w[.. fixtures matching.gift]))
|
4
|
+
@data = file.read
|
5
|
+
assert @data.length > 0
|
6
|
+
end
|
7
|
+
|
8
|
+
Then /^contains the correct matching questions$/ do
|
9
|
+
#//My file of matching questions about emoticons
|
10
|
+
#::Intro to matching questions
|
11
|
+
#::Match the emoticon to the correct emotion:{
|
12
|
+
#=:) -> smiling
|
13
|
+
#=:D -> crazy happy
|
14
|
+
#=\(^_^)/ -> yay!
|
15
|
+
#=:( -> sad
|
16
|
+
#}
|
17
|
+
assert_equal 1, @questions.length
|
18
|
+
|
19
|
+
question = @questions[0]
|
20
|
+
assert_equal 4, question.answer.length
|
21
|
+
assert_question question, :style => :matching,
|
22
|
+
:text => "Match the emoticon to the correct emotion:",
|
23
|
+
:title => "Intro to matching questions"
|
24
|
+
|
25
|
+
assert_answer question.answer[0], :correct => "smiling", :text => ":)"
|
26
|
+
assert_answer question.answer[1], :correct => "crazy happy", :text => ":D"
|
27
|
+
assert_answer question.answer[2], :correct => "yay!", :text => '\\(^_^)/'
|
28
|
+
assert_answer question.answer[3], :correct => "sad", :text => ":("
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
Given /^a GIFT file of missing word questions$/ do
|
2
|
+
file = File.open(File.join(File.dirname(__FILE__), *%w[.. fixtures missing_word.gift]))
|
3
|
+
@data = file.read
|
4
|
+
@data.length.should be > 0
|
5
|
+
end
|
6
|
+
|
7
|
+
Then /^contains the correct missing word questions$/ do
|
8
|
+
@questions.length.should be(4)
|
9
|
+
|
10
|
+
#Sally sells { =seashells ~snails} by the seashore.
|
11
|
+
question = @questions[0]
|
12
|
+
assert_equal 2, question.answer.length
|
13
|
+
assert_question question, :style => :missing_word,
|
14
|
+
:text => "Sally sells",
|
15
|
+
:title => nil,
|
16
|
+
:text_post => "by the seashore."
|
17
|
+
|
18
|
+
assert_answer question.answer[0], :correct => true, :text => "seashells"
|
19
|
+
assert_answer question.answer[1], :correct => false, :text => "snails"
|
20
|
+
|
21
|
+
|
22
|
+
#::Hamster Tree::
|
23
|
+
#Oh woe is me, {~oh =doh!} woe is me!
|
24
|
+
question = @questions[1]
|
25
|
+
assert_equal 2, question.answer.length
|
26
|
+
assert_question question, :style => :missing_word,
|
27
|
+
:text => "Oh woe is me,",
|
28
|
+
:title => "Hamster Tree",
|
29
|
+
:text_post => "woe is me!"
|
30
|
+
|
31
|
+
assert_answer question.answer[0], :correct => false, :text => "oh"
|
32
|
+
assert_answer question.answer[1], :correct => true, :text => "doh!"
|
33
|
+
|
34
|
+
#You say that, "money is the root of all evil", I ask you "what is the root of all {~honey ~bunnies =money}?"
|
35
|
+
question = @questions[2]
|
36
|
+
assert_equal 3, question.answer.length
|
37
|
+
assert_question question, :style => :missing_word,
|
38
|
+
:text => 'You say that, "money is the root of all evil", I ask you "what is the root of all',
|
39
|
+
:title => nil,
|
40
|
+
:text_post => '?"'
|
41
|
+
|
42
|
+
assert_answer question.answer[0], :correct => false, :text => "honey"
|
43
|
+
assert_answer question.answer[1], :correct => false, :text => "bunnies"
|
44
|
+
assert_answer question.answer[2], :correct => true, :text => "money"
|
45
|
+
|
46
|
+
#Ooh Eee \{Uh\} Ooh Ah Ah {=Ting Tang ~Tung Ting ~Wing Wang} Walla Walla Bing Bang!
|
47
|
+
question = @questions[3]
|
48
|
+
assert_equal 3, question.answer.length
|
49
|
+
assert_question question, :style => :missing_word,
|
50
|
+
:text => 'Ooh Eee {Uh} Ooh Ah Ah',
|
51
|
+
:title => nil,
|
52
|
+
:text_post => "Walla Walla Bing Bang!"
|
53
|
+
|
54
|
+
assert_answer question.answer[0], :correct => true, :text => "Ting Tang"
|
55
|
+
assert_answer question.answer[1], :correct => false, :text => "Tung Ting"
|
56
|
+
assert_answer question.answer[2], :correct => false, :text => "Wing Wang"
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,107 @@
|
|
1
|
+
|
2
|
+
Given /^a GIFT file of multiple choice questions$/ do
|
3
|
+
file = File.open(File.join(File.dirname(__FILE__), *%w[.. fixtures multiple_choice.gift]))
|
4
|
+
@data = file.read
|
5
|
+
@data.length.should be > 0
|
6
|
+
end
|
7
|
+
|
8
|
+
Then /^contains the correct multiple choice questions$/ do
|
9
|
+
@questions.length.should be(6)
|
10
|
+
|
11
|
+
|
12
|
+
#::Ninjas and the future::In the future, ninjas will be able to{= Travel to the moon ~play tennis ~eat apples ~play fable 2 ~code in Assembly }
|
13
|
+
question = @questions[0]
|
14
|
+
assert_equal 5, question.answer.length
|
15
|
+
assert_question question, :style => :multiple_choice,
|
16
|
+
:text => "In the future, ninjas will be able to",
|
17
|
+
:title => "Ninjas and the future"
|
18
|
+
|
19
|
+
assert_answer question.answer[0], :correct => true, :text => "Travel to the moon"
|
20
|
+
assert_answer question.answer[1], :correct => false, :text => "play tennis"
|
21
|
+
assert_answer question.answer[2], :correct => false, :text => "eat apples"
|
22
|
+
assert_answer question.answer[3], :correct => false, :text => "play fable 2"
|
23
|
+
assert_answer question.answer[4], :correct => false, :text => "code in Assembly"
|
24
|
+
|
25
|
+
#// question: 2 name: Ninjas and you
|
26
|
+
#::Ninjas and you::
|
27
|
+
# If you see a ninja you should: {~offer them a crunchy frog =run ~attack them }
|
28
|
+
question = @questions[1]
|
29
|
+
assert_equal 3, question.answer.length
|
30
|
+
assert_question question, :style => :multiple_choice,
|
31
|
+
:text => "If you see a ninja you should:",
|
32
|
+
:title => "Ninjas and you"
|
33
|
+
|
34
|
+
assert_answer question.answer[0], :correct => false, :text => "offer them a crunchy frog"
|
35
|
+
assert_answer question.answer[1], :correct => true, :text => "run"
|
36
|
+
assert_answer question.answer[2], :correct => false, :text => "attack them"
|
37
|
+
|
38
|
+
#Ninjas will only attack when {~provoked ~ upset ~off duty =none of the above}
|
39
|
+
question = @questions[2]
|
40
|
+
assert_equal 4, question.answer.length
|
41
|
+
assert_question question, :style => :multiple_choice,
|
42
|
+
:text => "Ninjas will only attack when",
|
43
|
+
:title => nil
|
44
|
+
|
45
|
+
assert_answer question.answer[0], :correct => false, :text => "provoked"
|
46
|
+
assert_answer question.answer[1], :correct => false, :text => "upset"
|
47
|
+
assert_answer question.answer[2], :correct => false, :text => "off duty"
|
48
|
+
assert_answer question.answer[3], :correct => true, :text => "none of the above"
|
49
|
+
|
50
|
+
#One way ninjas are like a snake is: {~Ninjas have scales ~Ninjas eat rodents =Ninjas can spit venom}
|
51
|
+
question = @questions[3]
|
52
|
+
assert_equal 3, question.answer.length
|
53
|
+
assert_question question, :style => :multiple_choice,
|
54
|
+
:text => "One way ninjas are like a snake is:",
|
55
|
+
:title => nil
|
56
|
+
|
57
|
+
assert_answer question.answer[0], :correct => false, :text => "Ninjas have scales"
|
58
|
+
assert_answer question.answer[1], :correct => false, :text => "Ninjas eat rodents"
|
59
|
+
assert_answer question.answer[2], :correct => true, :text => "Ninjas can spit venom"
|
60
|
+
|
61
|
+
#::Supercomputing Ninjas
|
62
|
+
#::Ninjas can recite the value of pi to how many digits?{
|
63
|
+
#~10
|
64
|
+
## do you even know what a ninja is?
|
65
|
+
#~100
|
66
|
+
## are you crazy?
|
67
|
+
#~100,000
|
68
|
+
## that is pitiful
|
69
|
+
#=twice the US national debt
|
70
|
+
## if not more!
|
71
|
+
#}
|
72
|
+
question = @questions[4]
|
73
|
+
assert_equal 4, question.answer.length
|
74
|
+
assert_question question, :style => :multiple_choice,
|
75
|
+
:text => "Ninjas can recite the value of pi to how many digits?",
|
76
|
+
:title => "Supercomputing Ninjas"
|
77
|
+
|
78
|
+
assert_answer question.answer[0], :correct => false, :text => "10", :comment => "do you even know what a ninja is?"
|
79
|
+
assert_answer question.answer[1], :correct => false, :text => "100", :comment => "are you crazy?"
|
80
|
+
assert_answer question.answer[2], :correct => false, :text => "100,000", :comment => "that is pitiful"
|
81
|
+
assert_answer question.answer[3], :correct => true, :text => "twice the US national debt", :comment => "if not more!"
|
82
|
+
|
83
|
+
#// Ninjas can be commented on
|
84
|
+
#::Are you a Ninja?::
|
85
|
+
#When confronted by a zombie army of terracotta kung-fu masters, you would: {
|
86
|
+
#~ cry
|
87
|
+
## not even baby ninjas would do that
|
88
|
+
#~ try to fight
|
89
|
+
## fight or fight not, there is no try.
|
90
|
+
#= slay them all with a single strike before they even saw you.
|
91
|
+
## You are Ninja!
|
92
|
+
#~ run away
|
93
|
+
## You would make a poor ninja.
|
94
|
+
#}
|
95
|
+
question = @questions[5]
|
96
|
+
assert_equal 4, question.answer.length
|
97
|
+
assert_question question, :style => :multiple_choice,
|
98
|
+
:text => "When confronted by a zombie army of terracotta kung-fu masters, you would:",
|
99
|
+
:title => "Are you a Ninja?"
|
100
|
+
|
101
|
+
assert_answer question.answer[0], :correct => false, :text => "cry", :comment => "not even baby ninjas would do that"
|
102
|
+
assert_answer question.answer[1], :correct => false, :text => "try to fight", :comment => "fight or fight not, there is no try."
|
103
|
+
assert_answer question.answer[2], :correct => true, :text => "slay them all with a single strike before they even saw you.", :comment => "You are Ninja!"
|
104
|
+
assert_answer question.answer[3], :correct => false, :text => "run away", :comment => "You would make a poor ninja."
|
105
|
+
|
106
|
+
end
|
107
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Given /^a GIFT file of numerical questions$/ do
|
2
|
+
file = File.open(File.join(File.dirname(__FILE__), *%w[.. fixtures numerical.gift]))
|
3
|
+
@data = file.read
|
4
|
+
@data.length.should be > 0
|
5
|
+
end
|
6
|
+
|
7
|
+
Then /^contains the correct numerical questions$/ do
|
8
|
+
@questions.length.should be(2)
|
9
|
+
|
10
|
+
#When was Harvey D. Smith born?{#1945:5}
|
11
|
+
question = @questions[0]
|
12
|
+
assert_equal 1, question.answer.length
|
13
|
+
assert_question question, :style => :numerical,
|
14
|
+
:text => "When was Harvey D. Smith born?",
|
15
|
+
:title => nil
|
16
|
+
|
17
|
+
assert_answer question.answer[0], :correct => 1945, :range => 5, :weight => nil
|
18
|
+
|
19
|
+
#//this comment will be ignored in the import process
|
20
|
+
#::Numerical example::
|
21
|
+
#When was Elizabeth M. Danson born? {#
|
22
|
+
# =1993:0 #Correct! you will get full credit for this answer
|
23
|
+
# =%50%1993:2 #She was born in 1993.
|
24
|
+
# You get 50% credit for being close.
|
25
|
+
#}
|
26
|
+
question = @questions[1]
|
27
|
+
assert_equal 2, question.answer.length
|
28
|
+
assert_question question, :style => :numerical,
|
29
|
+
:text => "When was Elizabeth M. Danson born?",
|
30
|
+
:title => "Numerical example"
|
31
|
+
|
32
|
+
assert_answer question.answer[0], :correct => 1993, :range => 0, :weight => nil, :comment => "Correct! you will get full credit for this answer"
|
33
|
+
assert_answer question.answer[1], :correct => 1993, :range => 2, :weight => 50, :comment => "She was born in 1993.\n You get 50% credit for being close."
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
|
2
|
+
Given(/^a GIFT file of short answer questions$/) do
|
3
|
+
file = File.open(File.join(File.dirname(__FILE__), *%w[.. fixtures short_answer.gift]))
|
4
|
+
@data = file.read
|
5
|
+
@data.length.should be > 0
|
6
|
+
end
|
7
|
+
|
8
|
+
Then(/^contains the correct short answer questions$/) do
|
9
|
+
@questions.length.should be(3)
|
10
|
+
|
11
|
+
#//File of short answer questions
|
12
|
+
#::Intro question about coffee::
|
13
|
+
#Coffee is made from {=ground coffee beans and water =burnt beans = the nectar of the gods}
|
14
|
+
question = @questions[0]
|
15
|
+
assert_equal 3, question.answer.length
|
16
|
+
assert_question question, :style => :short_answer,
|
17
|
+
:text => "Coffee is made from",
|
18
|
+
:title => "Intro question about coffee"
|
19
|
+
|
20
|
+
assert_answer question.answer[0], :correct => true, :text => "ground coffee beans and water"
|
21
|
+
assert_answer question.answer[1], :correct => true, :text => "burnt beans"
|
22
|
+
assert_answer question.answer[2], :correct => true, :text => "the nectar of the gods"
|
23
|
+
|
24
|
+
#Coffee is best when{ = hot = cold}
|
25
|
+
question = @questions[1]
|
26
|
+
assert_equal 2, question.answer.length
|
27
|
+
assert_question question, :style => :short_answer,
|
28
|
+
:text => "Coffee is best when",
|
29
|
+
:title => nil
|
30
|
+
|
31
|
+
assert_answer question.answer[0], :correct => true, :text => "hot"
|
32
|
+
assert_answer question.answer[1], :correct => true, :text => "cold"
|
33
|
+
|
34
|
+
#The only way to spell coffee is:{=coffee}
|
35
|
+
question = @questions[2]
|
36
|
+
assert_equal 1, question.answer.length
|
37
|
+
assert_question question, :style => :short_answer,
|
38
|
+
:text => "The only way to spell coffee is:",
|
39
|
+
:title => nil
|
40
|
+
|
41
|
+
assert_answer question.answer[0], :correct => true, :text => "coffee"
|
42
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
Given(/^a GIFT file of true or false questions$/) do
|
2
|
+
file = File.open(File.join(File.dirname(__FILE__), *%w[.. fixtures true_or_false.gift]))
|
3
|
+
@data = file.read
|
4
|
+
@data.length.should be > 0
|
5
|
+
end
|
6
|
+
|
7
|
+
Then(/^contains the correct true or false questions$/)do
|
8
|
+
@questions.length.should be(6)
|
9
|
+
|
10
|
+
#:trueStatement about monkeys::Monkeys like to fly like ninjas.{T}
|
11
|
+
question = @questions[0]
|
12
|
+
assert_question question, :style => :true_false,
|
13
|
+
:text => "Monkeys like to fly like ninjas.",
|
14
|
+
:title => "TrueStatement about monkeys"
|
15
|
+
|
16
|
+
assert_answer question.answer[0], :correct => true
|
17
|
+
|
18
|
+
#// question: 0 name: TrueStatement
|
19
|
+
#::A Second TrueStatement about monkeys::
|
20
|
+
#Monkeys roam in packs with swords.{True}
|
21
|
+
question = @questions[1]
|
22
|
+
assert_question question, :style => :true_false,
|
23
|
+
:text => "Monkeys roam in packs with swords.",
|
24
|
+
:title => "A Second TrueStatement about monkeys"
|
25
|
+
|
26
|
+
assert_answer question.answer[0], :correct => true
|
27
|
+
|
28
|
+
#Monkeys will jump from buildings without fear. {T}
|
29
|
+
question = @questions[2]
|
30
|
+
assert_question question, :style => :true_false,
|
31
|
+
:text => "Monkeys will jump from buildings without fear.",
|
32
|
+
:title => nil
|
33
|
+
|
34
|
+
assert_answer question.answer[0], :correct => true
|
35
|
+
|
36
|
+
#Monkeys have a formal system of government{False}
|
37
|
+
question = @questions[3]
|
38
|
+
assert_question question, :style => :true_false,
|
39
|
+
:text => "Monkeys have a formal system of government",
|
40
|
+
:title => nil
|
41
|
+
|
42
|
+
assert_answer question.answer[0], :correct => false
|
43
|
+
|
44
|
+
#::A Second FalseStatement about monkeys
|
45
|
+
#::Monkeys wear suits and sit around in corporate offices.{False}
|
46
|
+
question = @questions[4]
|
47
|
+
assert_question question, :style => :true_false,
|
48
|
+
:text => "Monkeys wear suits and sit around in corporate offices.",
|
49
|
+
:title => "A Second FalseStatement about monkeys"
|
50
|
+
|
51
|
+
assert_answer question.answer[0], :correct => false
|
52
|
+
|
53
|
+
#// question: 6 name: FalseStatement
|
54
|
+
#::A Third FalseStatement about monkeys:: Monkeys can operate heavy machinery.{F}
|
55
|
+
question = @questions[5]
|
56
|
+
assert_question question, :style => :true_false,
|
57
|
+
:text => "Monkeys can operate heavy machinery.",
|
58
|
+
:title => "A Third FalseStatement about monkeys"
|
59
|
+
|
60
|
+
assert_answer question.answer[0], :correct => false
|
61
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join [File.dirname(__FILE__), "..", "..", "lib"])
|
2
|
+
require 'gipper'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.join [File.dirname(__FILE__), "..", "..", "test"])
|
5
|
+
require 'custom_assertions'
|
6
|
+
include CustomAssertions
|
7
|
+
|
8
|
+
require 'test/unit/assertions'
|
9
|
+
|
10
|
+
World(Test::Unit::Assertions)
|
data/lib/answer.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'special_charater_handler'
|
2
|
+
|
3
|
+
module Gipper
|
4
|
+
# == Gipper::Answer
|
5
|
+
#
|
6
|
+
# Represents the single correct answer if there is only one answer,
|
7
|
+
# or one of the answer choices if multiple are provided for a question.
|
8
|
+
#
|
9
|
+
# To populate the answer from a string use the parse method
|
10
|
+
#
|
11
|
+
# answer = Gipper::Answer.new
|
12
|
+
# answer.parse "= foo #bar"
|
13
|
+
#
|
14
|
+
# answer.correct
|
15
|
+
# >> true
|
16
|
+
#
|
17
|
+
# answer.text
|
18
|
+
# >> foo
|
19
|
+
#
|
20
|
+
# answer.comment
|
21
|
+
# >> bar
|
22
|
+
#
|
23
|
+
# or
|
24
|
+
#
|
25
|
+
# answer.parse "F"
|
26
|
+
#
|
27
|
+
# answer.correct
|
28
|
+
# >> false
|
29
|
+
#
|
30
|
+
class Answer
|
31
|
+
include Oniguruma
|
32
|
+
include Gipper::SpecialCharacterHandler
|
33
|
+
attr_reader :weight, :correct, :comment, :range, :text
|
34
|
+
|
35
|
+
# Will parse a single answer into it's parts.
|
36
|
+
# If the answer type is numerical, pass :numerical as the optional second parameter.
|
37
|
+
def parse answer, style_hint = nil
|
38
|
+
if style_hint == :numerical
|
39
|
+
parse_as_numerical answer
|
40
|
+
else
|
41
|
+
parse_standard answer
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def can_parse_as_true_false? answer
|
47
|
+
return false if answer.nil?
|
48
|
+
answer.downcase.strip =~ /^(t|f|true|false)$/
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_standard answer
|
52
|
+
correct, text = split_correct answer
|
53
|
+
|
54
|
+
split_matching(text) do |t, c|
|
55
|
+
text, correct = t, c
|
56
|
+
end
|
57
|
+
|
58
|
+
text, weight = split_weight(text)
|
59
|
+
@weight = weight.to_i if weight
|
60
|
+
@text, @comment = split_comment(text).map { |item| unescape item }
|
61
|
+
|
62
|
+
@correct = correct
|
63
|
+
|
64
|
+
# handle true false
|
65
|
+
if can_parse_as_true_false?(@text)
|
66
|
+
convert_to_true_false!
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_as_numerical answer
|
71
|
+
correct, range = answer.split(":", 2)
|
72
|
+
range, comment = split_comment range
|
73
|
+
correct.gsub!("=", "")
|
74
|
+
weight = 100
|
75
|
+
|
76
|
+
correct, weight = split_weight(correct)
|
77
|
+
@weight = weight.to_i if weight
|
78
|
+
|
79
|
+
@comment = comment
|
80
|
+
parts = correct.split(/\.\./)
|
81
|
+
if parts.length == 2
|
82
|
+
parts.map! { |s| to_num(s) }
|
83
|
+
@correct = ((parts[0] + parts[1]) /2)
|
84
|
+
@range = ((parts[1] - parts[0]) /2)
|
85
|
+
else
|
86
|
+
@correct = to_num(correct)
|
87
|
+
@range = to_num(range)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def convert_to_true_false!
|
92
|
+
@correct = is_true(@text)
|
93
|
+
@text = nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def to_num(val)
|
97
|
+
if val && val.include?(".")
|
98
|
+
val.to_f
|
99
|
+
else
|
100
|
+
val.to_i
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def is_true answer
|
105
|
+
!(answer.downcase.strip =~ /^(t|true)$/).nil?
|
106
|
+
end
|
107
|
+
|
108
|
+
def split_correct clause
|
109
|
+
correct = []
|
110
|
+
|
111
|
+
if clause =~ /^[~=]/
|
112
|
+
correct[0] = eval_correctness(clause[0])
|
113
|
+
correct[1] = clause[1..clause.length].strip
|
114
|
+
else
|
115
|
+
correct[0] = true
|
116
|
+
correct[1] = clause
|
117
|
+
end
|
118
|
+
|
119
|
+
return correct
|
120
|
+
end
|
121
|
+
|
122
|
+
def split_matching answers
|
123
|
+
reg = Regexp.new('(.*)\-\>(.*)', Regexp::MULTILINE)
|
124
|
+
matches = reg.match answers
|
125
|
+
|
126
|
+
if matches
|
127
|
+
yield matches.captures.map {|s| s.strip}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def split_weight answer
|
132
|
+
return [answer, nil] unless answer.class == String
|
133
|
+
matches = answer.match(/%(-?\d+)%(.+)/)
|
134
|
+
if matches
|
135
|
+
weight = matches.captures[0]
|
136
|
+
correct = matches.captures[1]
|
137
|
+
return [correct, weight]
|
138
|
+
end
|
139
|
+
|
140
|
+
return [answer, nil]
|
141
|
+
end
|
142
|
+
|
143
|
+
def eval_correctness indicator
|
144
|
+
{ 61 => true, 126 => false}[indicator]
|
145
|
+
end
|
146
|
+
|
147
|
+
def split_comment answer_text
|
148
|
+
return [nil, nil] if blank?(answer_text)
|
149
|
+
|
150
|
+
answer_text.strip!
|
151
|
+
reg = ORegexp.new('(?<before>.*)(?<!\\\\)#(?<after>.*)', :options => OPTION_MULTILINE)
|
152
|
+
match = reg.match(answer_text)
|
153
|
+
return [answer_text, nil] unless match
|
154
|
+
|
155
|
+
text = match[:before].strip
|
156
|
+
feedback_comment = match[:after].strip
|
157
|
+
[text, feedback_comment]
|
158
|
+
end
|
159
|
+
|
160
|
+
def blank? text
|
161
|
+
text.nil? || text == ""
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|