ruql 0.0.8 → 1.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.
- checksums.yaml +5 -5
- data/.gitignore +14 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/LICENSE +6 -0
- data/README.md +308 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/ruql +86 -94
- data/bin/setup +8 -0
- data/examples/estilo.css +1 -0
- data/examples/example.rb +37 -0
- data/examples/file.html +94 -0
- data/examples/help.txt +55 -0
- data/examples/preguntas-TFG-20140224-0050.txt +32 -0
- data/examples/preguntas-TFG-20140224-0050.xml +168 -0
- data/examples/prueba.js +3 -0
- data/lib/ruql.rb +7 -9
- data/lib/ruql/question.rb +8 -1
- data/lib/ruql/quiz.rb +37 -33
- data/lib/ruql/renderers/html5_renderer.rb +39 -1
- data/lib/ruql/stats.rb +18 -0
- data/lib/ruql/version.rb +3 -0
- data/ruql.gemspec +43 -0
- metadata +80 -21
- data/templates/autoqcm.tex.erb +0 -1
- data/templates/html5.html.erb +0 -42
- data/templates/htmlform.html.erb +0 -44
data/lib/ruql/quiz.rb
CHANGED
@@ -2,24 +2,8 @@ class Quiz
|
|
2
2
|
@@quizzes = []
|
3
3
|
@@yaml_file = nil
|
4
4
|
@quiz_yaml = {}
|
5
|
+
@@options = {}
|
5
6
|
def self.quizzes ; @@quizzes ; end
|
6
|
-
@@default_options =
|
7
|
-
{
|
8
|
-
:open_time => Time.now,
|
9
|
-
:soft_close_time => Time.now + 24*60*60,
|
10
|
-
:hard_close_time => Time.now + 24*60*60,
|
11
|
-
:maximum_submissions => 1,
|
12
|
-
:duration => 3600,
|
13
|
-
:retry_delay => 600,
|
14
|
-
:parameters => {
|
15
|
-
:show_explanations => {
|
16
|
-
:question => 'before_soft_close_time',
|
17
|
-
:option => 'before_soft_close_time',
|
18
|
-
:score => 'before_soft_close_time',
|
19
|
-
}
|
20
|
-
},
|
21
|
-
:maximum_score => 1,
|
22
|
-
}
|
23
7
|
|
24
8
|
attr_reader :renderer
|
25
9
|
attr_reader :questions
|
@@ -29,36 +13,56 @@ class Quiz
|
|
29
13
|
attr_reader :logger
|
30
14
|
attr_accessor :title
|
31
15
|
|
32
|
-
def initialize(title,
|
16
|
+
def initialize(title, options={})
|
33
17
|
@output = ''
|
34
18
|
@questions = options[:questions] || []
|
35
19
|
@title = title
|
36
|
-
@options = @@
|
20
|
+
@options = @@options.merge(options)
|
37
21
|
@seed = srand
|
38
22
|
@logger = Logger.new(STDERR)
|
39
|
-
@logger.level =
|
40
|
-
|
41
|
-
@quiz_yaml = yaml
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.get_renderer(renderer)
|
45
|
-
Object.const_get(renderer.to_s + 'Renderer') rescue nil
|
23
|
+
@logger.level = (@options['-V'] || @options['--verbose']) ? Logger::INFO : Logger::WARN
|
24
|
+
#@quiz_yaml = yaml
|
46
25
|
end
|
47
26
|
|
48
27
|
def render_with(renderer,options={})
|
49
28
|
srand @seed
|
50
|
-
@renderer =
|
29
|
+
@renderer = renderer.send(:new,self,options)
|
51
30
|
@renderer.render_quiz
|
52
31
|
@output = @renderer.output
|
53
32
|
end
|
54
33
|
|
55
|
-
def self.
|
56
|
-
@@
|
34
|
+
def self.set_options(options)
|
35
|
+
@@options = options
|
36
|
+
end
|
37
|
+
|
38
|
+
def ungrouped_questions
|
39
|
+
questions.filter { |q| q.question_group.to_s == '' }
|
40
|
+
end
|
41
|
+
|
42
|
+
def grouped_questions
|
43
|
+
questions.filter { |q| q.question_group.to_s != '' }.sort_by(&:question_group)
|
44
|
+
end
|
45
|
+
|
46
|
+
def groups ; questions.map(&:question_group).uniq.reject { |g| g.to_s == '' } ; end
|
47
|
+
|
48
|
+
def ungrouped_points
|
49
|
+
ungrouped_questions.map(&:points).sum
|
57
50
|
end
|
58
51
|
|
59
|
-
def
|
52
|
+
def grouped_points
|
53
|
+
gq = grouped_questions
|
54
|
+
groups.sum do |g|
|
55
|
+
gq.detect { |q| q.question_group == g }.points
|
56
|
+
end
|
57
|
+
end
|
60
58
|
|
61
|
-
def
|
59
|
+
def points
|
60
|
+
ungrouped_points + grouped_points
|
61
|
+
end
|
62
|
+
|
63
|
+
def num_questions
|
64
|
+
groups.length + ungrouped_questions.length
|
65
|
+
end
|
62
66
|
|
63
67
|
def random_seed(num)
|
64
68
|
@seed = num.to_i
|
@@ -129,8 +133,8 @@ class Quiz
|
|
129
133
|
@questions << q
|
130
134
|
end
|
131
135
|
|
132
|
-
def self.quiz(
|
133
|
-
quiz = Quiz.new(
|
136
|
+
def self.quiz(title, args={}, &block)
|
137
|
+
quiz = Quiz.new(title, args)
|
134
138
|
quiz.instance_eval(&block)
|
135
139
|
@@quizzes << quiz
|
136
140
|
end
|
@@ -7,14 +7,47 @@ class Html5Renderer
|
|
7
7
|
def initialize(quiz,options={})
|
8
8
|
@css = options.delete('c') || options.delete('css')
|
9
9
|
@show_solutions = options.delete('s') || options.delete('solutions')
|
10
|
+
@show_tags = options.delete('T') || options.delete('show-tags')
|
10
11
|
@template = options.delete('t') ||
|
11
12
|
options.delete('template') ||
|
12
|
-
File.join(Gem.loaded_specs['ruql'].full_gem_path, 'templates/html5.html.erb')
|
13
|
+
File.join((Gem.loaded_specs['ruql'].full_gem_path rescue '.'), 'templates/html5.html.erb')
|
13
14
|
@output = ''
|
14
15
|
@quiz = quiz
|
15
16
|
@h = Builder::XmlMarkup.new(:target => @output, :indent => 2)
|
16
17
|
end
|
17
18
|
|
19
|
+
def allowed_options
|
20
|
+
opts = [
|
21
|
+
['-c', '--css', Getopt::REQUIRED],
|
22
|
+
['-t', '--template', Getopt::REQUIRED],
|
23
|
+
['-s', '--solutions', Getopt::BOOLEAN],
|
24
|
+
['-T', '--show-tags', Getopt::BOOLEAN]
|
25
|
+
]
|
26
|
+
help = <<eos
|
27
|
+
The HTML5 and HTML Forms renderers supports these options:
|
28
|
+
-c <href>, --css=<href>
|
29
|
+
embed <href> for stylesheet into generated HTML5
|
30
|
+
-j <src>, --js=<src>
|
31
|
+
embed <src> for JavaScrips
|
32
|
+
-t <file.html.erb>, --template=<file.html.erb>
|
33
|
+
Use file.html.erb as HTML template rather than generating our own file.
|
34
|
+
file.html.erb should have <%= yield %> where questions should go.
|
35
|
+
An example is in the templates/ directory of RuQL.
|
36
|
+
The following local variables will be replaced with their values in
|
37
|
+
the template:
|
38
|
+
<%= quiz.title %> - the quiz title
|
39
|
+
<%= quiz.num_questions %> - total number of questions
|
40
|
+
<%= quiz.points %> - total number of points for whole quiz
|
41
|
+
-T, --show-tags
|
42
|
+
Show the tag(s) associated with a question within an element <div class="tags">.
|
43
|
+
-s, --solutions
|
44
|
+
generate solutions (showing correct answers and explanations)
|
45
|
+
NOTE: If there is more than one quiz (collection of questions) in the file,
|
46
|
+
a complete <html>...</html> block is produced in the output for EACH quiz.
|
47
|
+
eos
|
48
|
+
return(
|
49
|
+
|
50
|
+
|
18
51
|
def render_quiz
|
19
52
|
if @template
|
20
53
|
render_with_template do
|
@@ -132,6 +165,11 @@ class Html5Renderer
|
|
132
165
|
if question.class == FillIn then question.question_text.gsub(/\-+/, '_____________________________')
|
133
166
|
else question.question_text
|
134
167
|
end
|
168
|
+
if @show_tags
|
169
|
+
@h.div(:class => 'text') do
|
170
|
+
question.tags.join(',')
|
171
|
+
end
|
172
|
+
end
|
135
173
|
if question.raw?
|
136
174
|
@h.p { |p| p << qtext }
|
137
175
|
else
|
data/lib/ruql/stats.rb
ADDED
@@ -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
|
data/lib/ruql/version.rb
ADDED
data/ruql.gemspec
ADDED
@@ -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,51 +1,108 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Armando Fox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-03 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
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
17
60
|
- !ruby/object:Gem::Version
|
18
61
|
version: '3.0'
|
62
|
+
type: :development
|
19
63
|
prerelease: false
|
20
|
-
name: builder
|
21
64
|
version_requirements: !ruby/object:Gem::Requirement
|
22
65
|
requirements:
|
23
|
-
- - ~>
|
66
|
+
- - "~>"
|
24
67
|
- !ruby/object:Gem::Version
|
25
68
|
version: '3.0'
|
26
|
-
type: :runtime
|
27
69
|
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec_its
|
28
71
|
requirement: !ruby/object:Gem::Requirement
|
29
72
|
requirements:
|
30
|
-
- -
|
73
|
+
- - ">="
|
31
74
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
33
77
|
prerelease: false
|
34
|
-
name: getopt
|
35
78
|
version_requirements: !ruby/object:Gem::Requirement
|
36
79
|
requirements:
|
37
|
-
- -
|
80
|
+
- - ">="
|
38
81
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
40
|
-
type: :runtime
|
82
|
+
version: '0'
|
41
83
|
description: Ruby-embedded DSL for creating short-answer quiz questions
|
42
|
-
email: fox@
|
84
|
+
email: fox@berkeley.edu
|
43
85
|
executables:
|
44
86
|
- ruql
|
45
87
|
extensions: []
|
46
88
|
extra_rdoc_files: []
|
47
89
|
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".travis.yml"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/console
|
48
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
|
49
106
|
- lib/ruql.rb
|
50
107
|
- lib/ruql/answer.rb
|
51
108
|
- lib/ruql/dropdown.rb
|
@@ -67,32 +124,34 @@ files:
|
|
67
124
|
- lib/ruql/renderers/qualtrics_renderer.rb
|
68
125
|
- lib/ruql/renderers/xml_renderer.rb
|
69
126
|
- lib/ruql/select_multiple.rb
|
127
|
+
- lib/ruql/stats.rb
|
70
128
|
- lib/ruql/tex_output.rb
|
71
129
|
- lib/ruql/true_false.rb
|
72
|
-
-
|
73
|
-
-
|
74
|
-
- templates/htmlform.html.erb
|
130
|
+
- lib/ruql/version.rb
|
131
|
+
- ruql.gemspec
|
75
132
|
homepage: http://github.com/saasbook/ruql
|
76
133
|
licenses:
|
77
134
|
- CC By-SA
|
78
|
-
metadata:
|
135
|
+
metadata:
|
136
|
+
allowed_push_host: https://rubygems.org
|
137
|
+
homepage_uri: http://github.com/saasbook/ruql
|
138
|
+
source_code_uri: http://github.com/saasbook/ruql
|
79
139
|
post_install_message:
|
80
140
|
rdoc_options: []
|
81
141
|
require_paths:
|
82
142
|
- lib
|
83
143
|
required_ruby_version: !ruby/object:Gem::Requirement
|
84
144
|
requirements:
|
85
|
-
- -
|
145
|
+
- - ">="
|
86
146
|
- !ruby/object:Gem::Version
|
87
147
|
version: '0'
|
88
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
149
|
requirements:
|
90
|
-
- -
|
150
|
+
- - ">="
|
91
151
|
- !ruby/object:Gem::Version
|
92
152
|
version: '0'
|
93
153
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 2.2.5
|
154
|
+
rubygems_version: 3.0.8
|
96
155
|
signing_key:
|
97
156
|
specification_version: 4
|
98
157
|
summary: Ruby question language
|
data/templates/autoqcm.tex.erb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
<%= yield %>
|
data/templates/html5.html.erb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title><%= quiz.title %></title>
|
4
|
-
<style type="text/css" media="all">
|
5
|
-
body { font-family: Times, serif; }
|
6
|
-
.header { text-align: right; font-weight: bold; padding-right: 30%; line-height: 300%; }
|
7
|
-
h1 { text-align: center; }
|
8
|
-
ol.questions { list-style-type: number; }
|
9
|
-
li.question { page-break-inside: avoid; border-bottom: 1px solid grey; }
|
10
|
-
li.multiplechoice ol.answers { list-style-type: lower-alpha; }
|
11
|
-
li.selectmultiple ol.answers { vertical-align: center; list-style-type: none; list-style-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUAQMAAAC3R49OAAAABlBMVEUAAAD///+l2Z/dAAAAEklEQVQImWNgAIL6/w+ogoEAAKI4Kp2NVIeDAAAAAElFTkSuQmCC'); }
|
12
|
-
li.truefalse ol.answers { list-style-type: none; }
|
13
|
-
.correct { color: green; font-weight: bold; border: 1px solid black; padding: 0.2ex; }
|
14
|
-
.incorrect { color: red }
|
15
|
-
.explanation { font-style: italic }
|
16
|
-
.instructions { clear: both; border: 1px solid black; align: center; padding: 2ex; margin: 2ex; }
|
17
|
-
</style>
|
18
|
-
</head>
|
19
|
-
<body>
|
20
|
-
<div class="header">
|
21
|
-
<div id="name">Name:</div>
|
22
|
-
<div id="sid">SID:</div>
|
23
|
-
</div>
|
24
|
-
<h1><%= quiz.title %></h1>
|
25
|
-
<div class="instructions">
|
26
|
-
<ul>
|
27
|
-
<li>No books, notes, or electronic devices allowed. </li>
|
28
|
-
<li>Time limit is 30 minutes.</li>
|
29
|
-
<li><%= quiz.num_questions %> multiple-choice questions, points indicated per question,
|
30
|
-
<%= quiz.points %> points total. Points per question are intended
|
31
|
-
to reflect approximate times they should take, at about 1 point per minute.</li>
|
32
|
-
<li>For 'select all that apply' questions worth N points,
|
33
|
-
you get 1/N of the points for each RIGHT answer that you check, plus
|
34
|
-
1/N of the points for each WRONG answer that you correctly
|
35
|
-
leave unchecked. That is, equal weight is given to deciding
|
36
|
-
whether each choice is part of the right answer or not.</li>
|
37
|
-
</ul>
|
38
|
-
<b>Good skill!</b>
|
39
|
-
</div>
|
40
|
-
<%= yield %>
|
41
|
-
</body>
|
42
|
-
</html>
|
data/templates/htmlform.html.erb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title><%= quiz.title %></title>
|
4
|
-
<style type="text/css" media="all">
|
5
|
-
body { font-family: Times, serif; }
|
6
|
-
.header { text-align: right; font-weight: bold; padding-right: 30%; line-height: 300%; }
|
7
|
-
h1 { text-align: center; }
|
8
|
-
ol.questions { list-style-type: number; }
|
9
|
-
li.question { page-break-inside: avoid; border-bottom: 1px solid grey; padding-bottom: 2ex; }
|
10
|
-
li.multiplechoice ol.answers { list-style-type: lower-alpha; }
|
11
|
-
li.multiplechoice ol.answers li { padding-bottom: 0.5ex; }
|
12
|
-
li.selectmultiple ol.answers { vertical-align: center; list-style-type: none; list-style-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUAQMAAAC3R49OAAAABlBMVEUAAAD///+l2Z/dAAAAEklEQVQImWNgAIL6/w+ogoEAAKI4Kp2NVIeDAAAAAElFTkSuQmCC'); }
|
13
|
-
li.truefalse ol.answers { list-style-type: none; }
|
14
|
-
li.truefalse ol.answers li { width: 15%; display: inline-block; }
|
15
|
-
.correct { color: green }
|
16
|
-
.incorrect { color: red }
|
17
|
-
.explanation { font-style: italic }
|
18
|
-
.instructions { clear: both; border: 1px solid black; align: center; padding: 2ex; margin: 2ex; }
|
19
|
-
</style>
|
20
|
-
</head>
|
21
|
-
<body>
|
22
|
-
<div class="header">
|
23
|
-
<div id="name">Name:</div>
|
24
|
-
<div id="sid">SID:</div>
|
25
|
-
</div>
|
26
|
-
<h1><%= quiz.title %></h1>
|
27
|
-
<div class="instructions">
|
28
|
-
<ul>
|
29
|
-
<li>No books, notes, or electronic devices allowed. </li>
|
30
|
-
<li>Time limit is 30 minutes.</li>
|
31
|
-
<li><%= quiz.num_questions %> multiple-choice questions, points indicated per question,
|
32
|
-
<%= quiz.points %> points total. Points per question are intended
|
33
|
-
to reflect approximate times they should take, at about 1 point per minute.</li>
|
34
|
-
<li>For 'select all that apply' questions worth N points,
|
35
|
-
you get 1/N of the points for each RIGHT answer that you check, plus
|
36
|
-
1/N of the points for each WRONG answer that you correctly
|
37
|
-
leave unchecked. That is, equal weight is given to deciding
|
38
|
-
whether each choice is part of the right answer or not.</li>
|
39
|
-
</ul>
|
40
|
-
<b>Good skill!</b>
|
41
|
-
</div>
|
42
|
-
<%= yield %>
|
43
|
-
</body>
|
44
|
-
</html>
|