yorkcmarker 2.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/LICENCE +7 -0
- data/README.markdown +56 -0
- data/assets/assignment-mark-form.pdf +0 -0
- data/assets/summary-mark-form.pdf +0 -0
- data/bin/DataFiles.rb +47 -0
- data/bin/Generator.rb +43 -0
- data/bin/ReportMarker.rb +442 -0
- data/bin/ReportMarkerGUI.rb +294 -0
- data/bin/glade/ReportMarkerGUI.glade +2609 -0
- data/cmarking2.gemspec +21 -0
- data/spec/ReportMarkerGUI_spec.rb +314 -0
- data/spec/spec_helper.rb +7 -0
- data/yorkcmarker +16 -0
- metadata +143 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/LICENCE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) <2012> <Mathew Alan Gilbert>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
<h1>Installation</h1>
|
2
|
+
This application has been packaged as a [ruby gem](http://en.wikipedia.org/wiki/RubyGems#Gems): to install, simply type:
|
3
|
+
```ruby
|
4
|
+
gem install yorkcmarker
|
5
|
+
```
|
6
|
+
Then, to run the application, simply type
|
7
|
+
```ruby
|
8
|
+
yorkcmarker
|
9
|
+
```
|
10
|
+
at the command prompt.
|
11
|
+
|
12
|
+
<h2>Prerequisites</h2>
|
13
|
+
|
14
|
+
You will need a Ruby Interpreter installed. Ruby installers are available for Windows, Linux and Mac. Follow the instructions here: http://www.ruby-lang.org/en/downloads/ to install Ruby.
|
15
|
+
|
16
|
+
The gem has been developed and tested against _ruby 1.9.3p194_. It should work with earlier versions, but it's recommended you use the same version (at the time of writing it's the latest).
|
17
|
+
|
18
|
+
<h3>Ubuntu Distros</h3>
|
19
|
+
You need to have the libgtk2.0-dev package installed - you can do this using:
|
20
|
+
```bash
|
21
|
+
sudo apt-get install libgtk2.0-dev
|
22
|
+
```
|
23
|
+
Thanks to Yuan for catching this!
|
24
|
+
|
25
|
+
<h1>Usage</h1>
|
26
|
+
Simply fill in your name, and the student number, and then check the boxes the students have marks for. Multiple marks are awarded by checking multiple boxes for the appropriate statement.
|
27
|
+
|
28
|
+
Pressing the <b>Save</b> button will save the details of the _Part_ you are currently editing. Partial files are created in subdirectories (_part_1_ and _part_2_) of the output directory you select when asked. When both Parts have been completed for a student, full and summary marksheets are created in the output directory.
|
29
|
+
|
30
|
+
Each part can be marked individually - for example, you can mark Part 1, close the program, come back and mark Part 2 another time, and the program will then generate the completed marksheets. The data is sort in JSON form, in _output directory/data_.
|
31
|
+
|
32
|
+
<h2>Currently tested on:</h2>
|
33
|
+
<h4>Ruby versions</h4>
|
34
|
+
Check with:
|
35
|
+
```ruby
|
36
|
+
ruby -v
|
37
|
+
```
|
38
|
+
* ruby 1.9.3p194
|
39
|
+
* ruby 1.9.2-p290
|
40
|
+
* ruby 1.8.7
|
41
|
+
|
42
|
+
<h4>Operating Systems:</h4>
|
43
|
+
* Linux Mint 12 (see [_libgtk2.0-dev_](https://github.com/freefallertam/york-c-marking-assistant/edit/master/README.markdown#ubuntu-distros) requirement above)
|
44
|
+
* Ubuntu (see [_libgtk2.0-dev_](https://github.com/freefallertam/york-c-marking-assistant/edit/master/README.markdown#ubuntu-distros) requirement above)
|
45
|
+
* Microsoft Windows XP
|
46
|
+
* Microsoft Window Vista
|
47
|
+
|
48
|
+
If you install and run the gem on any other setups, let me know and I'll add to the above list.
|
49
|
+
|
50
|
+
<h1>Questions, Issues, Bug Reports</h1>
|
51
|
+
Either raise issues directly via GitHub, or direct all questions, issues and bug reports to Mat Alan Gilbert: mag501@york.ac.uk
|
52
|
+
|
53
|
+
<h3>Developer notes - the current code..</h3>
|
54
|
+
This code has just been thrown together - it grew from a CLI script written to save marking time. It's not clean, and it's not pretty, but is stable as far as it's been tested, and does the job. It does need a lot of refactoring and tidying up (this is on the TODO list!)!
|
55
|
+
|
56
|
+
_more information for developers coming soon.._
|
Binary file
|
Binary file
|
data/bin/DataFiles.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
class DataFiles
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
def initialize(data_directory)
|
5
|
+
@data_directory = data_directory
|
6
|
+
Dir.chdir(@data_directory)
|
7
|
+
end
|
8
|
+
|
9
|
+
def student_numbers
|
10
|
+
numbers = Array.new
|
11
|
+
Dir.glob("*.json").each do |file|
|
12
|
+
numbers << file.split("_")[0]
|
13
|
+
end
|
14
|
+
numbers.uniq
|
15
|
+
end
|
16
|
+
|
17
|
+
def part_one_details(student_number)
|
18
|
+
details = Hash.new
|
19
|
+
if File.exists? "#{student_number}_part1.json"
|
20
|
+
File.open("#{student_number}_part1.json", 'r') do |f|
|
21
|
+
details = JSON.parse(f.read, :symbolize_names => true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
details
|
25
|
+
end
|
26
|
+
|
27
|
+
def part_two_details(student_number)
|
28
|
+
details = Hash.new
|
29
|
+
if File.exists? "#{student_number}_part2.json"
|
30
|
+
File.open("#{student_number}_part2.json", 'r') do |f|
|
31
|
+
details = JSON.parse(f.read, :symbolize_names => true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
details
|
35
|
+
end
|
36
|
+
|
37
|
+
def demonstration_details(student_number)
|
38
|
+
details = Hash.new
|
39
|
+
if File.exists? "#{student_number}_demonstration.json"
|
40
|
+
File.open("#{student_number}_demonstration.json", 'r') do |f|
|
41
|
+
details = JSON.parse(f.read, :symbolize_names => true)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
details
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/bin/Generator.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
class Generator
|
2
|
+
require_relative 'DataFiles'
|
3
|
+
require_relative 'ReportMarker'
|
4
|
+
|
5
|
+
def initialize(data_directory)
|
6
|
+
@data_directory = data_directory
|
7
|
+
|
8
|
+
@data = DataFiles.new(@data_directory)
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate
|
12
|
+
all_student_data(@data_directory).each do |student_data|
|
13
|
+
|
14
|
+
ReportMarker.output_directory = "/home/mat/Documents/C Marking"
|
15
|
+
ReportMarker.generate_marksheet(student_data)
|
16
|
+
ReportMarker.generate_summary(student_data)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def all_student_data(data_directory)
|
21
|
+
Dir.chdir data_directory
|
22
|
+
students_data = Array.new
|
23
|
+
@data.student_numbers.each do |student|
|
24
|
+
students_data << load_student_data(student)
|
25
|
+
end
|
26
|
+
students_data
|
27
|
+
end
|
28
|
+
|
29
|
+
def load_student_data(student_number)
|
30
|
+
details = Hash.new
|
31
|
+
|
32
|
+
unless @data.part_one_details(student_number).nil?
|
33
|
+
details.merge!(@data.part_one_details(student_number))
|
34
|
+
end
|
35
|
+
unless @data.part_two_details(student_number).nil?
|
36
|
+
details.merge!(@data.part_two_details(student_number))
|
37
|
+
end
|
38
|
+
unless @data.demonstration_details(student_number).nil?
|
39
|
+
details.merge!(@data.demonstration_details(student_number))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/bin/ReportMarker.rb
ADDED
@@ -0,0 +1,442 @@
|
|
1
|
+
class ReportMarker
|
2
|
+
require 'prawn'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
def self.marking_form_input_filename
|
6
|
+
"#{assets_dir}/assignment-mark-form.pdf"
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.summary_input_filename
|
10
|
+
"#{assets_dir}/summary-mark-form.pdf"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.output_directory
|
14
|
+
@output_directory
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.output_directory=(value)
|
18
|
+
@output_directory = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.assets_dir
|
22
|
+
assets_root = nil
|
23
|
+
|
24
|
+
# if running as a gem
|
25
|
+
Gem::Specification.each do |installed_gem|
|
26
|
+
if installed_gem.name == 'yorkcmarker'
|
27
|
+
spec = Gem::Specification.find_by_name('yorkcmarker')
|
28
|
+
assets_root = spec.gem_dir + "/assets"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
# if running as a script
|
32
|
+
if assets_root.nil?
|
33
|
+
assets_root = File.dirname(File.dirname(__FILE__)) + "/assets"
|
34
|
+
end
|
35
|
+
assets_root
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.marking_form_output_filename(student_number)
|
39
|
+
"#{output_directory}/#{student_number}_assignment-mark-form.pdf"
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.summary_out_output_filename(student_number)
|
43
|
+
"#{output_directory}/#{student_number}_summary.pdf"
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.data_directory
|
47
|
+
unless File.directory?("#{output_directory}/data")
|
48
|
+
Dir.mkdir("#{output_directory}/data")
|
49
|
+
end
|
50
|
+
"#{output_directory}/data"
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.check_details(details)
|
54
|
+
# check for required information
|
55
|
+
if details[:marker_name].nil? || details[:marker_name].empty?
|
56
|
+
raise Exception.new "marker name cannot be nil or empty"
|
57
|
+
end
|
58
|
+
|
59
|
+
if details[:student_number].nil? || details[:student_number].length < 2
|
60
|
+
raise Exception.new "student number cannot be nil or less than 2 characters long"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.generate_marksheet(details)
|
65
|
+
x = 385
|
66
|
+
total_mark_position = {:y => 660}
|
67
|
+
requirements_position = {:y => 582}
|
68
|
+
analysis_position = {:y => 522}
|
69
|
+
specification_position = {:y => 411}
|
70
|
+
design_position = {:y => 342}
|
71
|
+
|
72
|
+
Prawn::Document.generate(self.marking_form_output_filename(details[:student_number]), :template => self.marking_form_input_filename) do
|
73
|
+
|
74
|
+
create_stamp("marker_name") do
|
75
|
+
draw_text details[:marker_name], :at => [0, 0]
|
76
|
+
end
|
77
|
+
|
78
|
+
create_stamp("student_number") do
|
79
|
+
draw_text details[:student_number], :at => [0, 0]
|
80
|
+
end
|
81
|
+
|
82
|
+
create_stamp("date") do
|
83
|
+
draw_text Time.new.strftime("%d/%m/%y"), :at => [0, 0]
|
84
|
+
end
|
85
|
+
|
86
|
+
create_stamp("minus") do
|
87
|
+
draw_text "-", :at => [-5, 0]
|
88
|
+
end
|
89
|
+
|
90
|
+
# create stamps for marks 0 to 100
|
91
|
+
0.upto(100) do |stamp_number|
|
92
|
+
create_stamp("#{stamp_number}_mark") do
|
93
|
+
draw_text stamp_number.to_s, :at => [0, 0]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Lateness
|
98
|
+
#unless details[:lateness].empty?
|
99
|
+
#stamp_at "minus", [x, total_mark_position[:y]-20]
|
100
|
+
#stamp_at "#{details[:lateness]}_mark", [x, total_mark_position[:y]-20]
|
101
|
+
#end
|
102
|
+
# Details
|
103
|
+
stamp_at "marker_name", [85, total_mark_position[:y]]
|
104
|
+
stamp_at "student_number", [215, total_mark_position[:y]-10]
|
105
|
+
stamp_at "date", [77, total_mark_position[:y]-21]
|
106
|
+
|
107
|
+
|
108
|
+
unless details[:requirements].nil?
|
109
|
+
part_one_total_mark = details[:requirements].inject(:+) +
|
110
|
+
details[:analysis].inject(:+) +
|
111
|
+
details[:specification].inject(:+) +
|
112
|
+
details[:design].inject(:+)
|
113
|
+
|
114
|
+
#Requirements
|
115
|
+
stamp_at "#{details[:requirements][0]}_mark", [x, requirements_position[:y]]
|
116
|
+
stamp_at "#{details[:requirements][1]}_mark", [x, requirements_position[:y]-10]
|
117
|
+
stamp_at "#{details[:requirements].inject(:+)}_mark", [x, requirements_position[:y]-27]
|
118
|
+
|
119
|
+
|
120
|
+
# Analysis
|
121
|
+
stamp_at "#{details[:analysis][0]}_mark", [x, analysis_position[:y]]
|
122
|
+
stamp_at "#{details[:analysis][1]}_mark", [x, analysis_position[:y]-10]
|
123
|
+
stamp_at "#{details[:analysis][2]}_mark", [x, analysis_position[:y]-20]
|
124
|
+
stamp_at "#{details[:analysis][3]}_mark", [x, analysis_position[:y]-30]
|
125
|
+
stamp_at "#{details[:analysis][4]}_mark", [x, analysis_position[:y]-40]
|
126
|
+
stamp_at "#{details[:analysis][5]}_mark", [x, analysis_position[:y]-51]
|
127
|
+
stamp_at "#{details[:analysis][6]}_mark", [x, analysis_position[:y]-61]
|
128
|
+
stamp_at "#{details[:analysis].inject(:+)}_mark", [x, analysis_position[:y]-77]
|
129
|
+
|
130
|
+
# Specification
|
131
|
+
stamp_at "#{details[:specification][0]}_mark", [x, specification_position[:y]]
|
132
|
+
stamp_at "#{details[:specification][1]}_mark", [x, specification_position[:y]-10]
|
133
|
+
stamp_at "#{details[:specification][2]}_mark", [x, specification_position[:y]-20]
|
134
|
+
stamp_at "#{details[:specification].inject(:+)}_mark", [x, specification_position[:y]-37]
|
135
|
+
|
136
|
+
# Design
|
137
|
+
stamp_at "#{details[:design][0]}_mark", [x, design_position[:y]]
|
138
|
+
stamp_at "#{details[:design][1]}_mark", [x, design_position[:y]-10]
|
139
|
+
stamp_at "#{details[:design][2]}_mark", [x, design_position[:y]-20]
|
140
|
+
stamp_at "#{details[:design][3]}_mark", [x, design_position[:y]-31]
|
141
|
+
stamp_at "#{details[:design][4]}_mark", [x, design_position[:y]-41]
|
142
|
+
stamp_at "#{details[:design][5]}_mark", [x, design_position[:y]-52]
|
143
|
+
stamp_at "#{details[:design][6]}_mark", [x, design_position[:y]-62]
|
144
|
+
stamp_at "#{details[:design][7]}_mark", [x, design_position[:y]-72]
|
145
|
+
stamp_at "#{details[:design][8]}_mark", [x, design_position[:y]-93]
|
146
|
+
stamp_at "#{details[:design][9]}_mark", [x, design_position[:y]-114]
|
147
|
+
stamp_at "#{details[:design][10]}_mark", [x, design_position[:y]-134]
|
148
|
+
stamp_at "#{details[:design].inject(:+)}_mark", [x, design_position[:y]-155]
|
149
|
+
end
|
150
|
+
|
151
|
+
go_to_page(2)
|
152
|
+
|
153
|
+
x = 385
|
154
|
+
y = 660
|
155
|
+
|
156
|
+
unless details[:implementation].nil?
|
157
|
+
# Implementation Report
|
158
|
+
stamp_at("#{details[:implementation][0]}_mark", [x, 648])
|
159
|
+
stamp_at("#{details[:implementation][1]}_mark", [x, 638])
|
160
|
+
stamp_at("#{details[:implementation][2]}_mark", [x, 627])
|
161
|
+
stamp_at("#{details[:implementation].inject(:+)}_mark", [x, 611])
|
162
|
+
|
163
|
+
# Code Listing
|
164
|
+
code_listing_y = 578
|
165
|
+
stamp_at("#{details[:code_listing][0]}_mark", [x, code_listing_y])
|
166
|
+
stamp_at("#{details[:code_listing][1]}_mark", [x, code_listing_y-10])
|
167
|
+
stamp_at("#{details[:code_listing][2]}_mark", [x, code_listing_y-20])
|
168
|
+
stamp_at("#{details[:code_listing][3]}_mark", [x, code_listing_y-31])
|
169
|
+
stamp_at("#{details[:code_listing][4]}_mark", [x, code_listing_y-41])
|
170
|
+
stamp_at("#{details[:code_listing][5]}_mark", [x, code_listing_y-51])
|
171
|
+
stamp_at("#{details[:code_listing][6]}_mark", [x, code_listing_y-62])
|
172
|
+
stamp_at("#{details[:code_listing][7]}_mark", [x, code_listing_y-72])
|
173
|
+
stamp_at("#{details[:code_listing][8]}_mark", [x, code_listing_y-82])
|
174
|
+
|
175
|
+
stamp_at("minus", [x, code_listing_y-98]) unless details[:code_listing][9] == 0
|
176
|
+
stamp_at("#{details[:code_listing][9]}_mark", [x, code_listing_y-98])
|
177
|
+
|
178
|
+
stamp_at("minus", [x, code_listing_y-109]) unless details[:code_listing][10] == 0
|
179
|
+
stamp_at("#{details[:code_listing][10]}_mark", [x, code_listing_y-109])
|
180
|
+
|
181
|
+
|
182
|
+
code_listing_total_marks = 0
|
183
|
+
0.upto(8) do |i|
|
184
|
+
code_listing_total_marks += details[:code_listing][i]
|
185
|
+
end
|
186
|
+
9.upto(10) do |i|
|
187
|
+
code_listing_total_marks -= details[:code_listing][i]
|
188
|
+
end
|
189
|
+
|
190
|
+
if code_listing_total_marks < 0
|
191
|
+
stamp_at("#{code_listing_total_marks*-1}_mark", [x, code_listing_y-125])
|
192
|
+
stamp_at("minus", [x, code_listing_y-125] )
|
193
|
+
else
|
194
|
+
stamp_at("#{code_listing_total_marks}_mark", [x, code_listing_y-125])
|
195
|
+
end
|
196
|
+
|
197
|
+
# Testing and Verification
|
198
|
+
testing_verification_y = 420
|
199
|
+
stamp_at("#{details[:testing_and_verification][0]}_mark", [x, testing_verification_y])
|
200
|
+
stamp_at("#{details[:testing_and_verification][1]}_mark", [x, testing_verification_y-10])
|
201
|
+
stamp_at("#{details[:testing_and_verification][2]}_mark", [x, testing_verification_y-21])
|
202
|
+
stamp_at("#{details[:testing_and_verification][3]}_mark", [x, testing_verification_y-31])
|
203
|
+
stamp_at("#{details[:testing_and_verification][4]}_mark", [x, testing_verification_y-42])
|
204
|
+
stamp_at("#{details[:testing_and_verification].inject(:+)}_mark", [x, testing_verification_y-58])
|
205
|
+
|
206
|
+
# User Manual
|
207
|
+
user_manual_y = 330
|
208
|
+
stamp_at("#{details[:user_manual][0]}_mark", [x, user_manual_y])
|
209
|
+
stamp_at("#{details[:user_manual][1]}_mark", [x, user_manual_y-10])
|
210
|
+
stamp_at("#{details[:user_manual][2]}_mark", [x, user_manual_y-21])
|
211
|
+
stamp_at("#{details[:user_manual][3]}_mark", [x, user_manual_y-31])
|
212
|
+
stamp_at("#{details[:user_manual][4]}_mark", [x, user_manual_y-41])
|
213
|
+
stamp_at("#{details[:user_manual][5]}_mark", [x, user_manual_y-52])
|
214
|
+
stamp_at("#{details[:user_manual][6]}_mark", [x, user_manual_y-62])
|
215
|
+
stamp_at("#{details[:user_manual].inject(:+)}_mark", [x, user_manual_y-79])
|
216
|
+
|
217
|
+
# Maturity, Consistency, Presentation and Innovation
|
218
|
+
mcpi_y = 219
|
219
|
+
stamp_at("#{details[:mcpi][0]}_mark", [x, mcpi_y])
|
220
|
+
stamp_at("#{details[:mcpi][1]}_mark", [x, mcpi_y-11])
|
221
|
+
stamp_at("#{details[:mcpi][2]}_mark", [x, mcpi_y-21])
|
222
|
+
stamp_at("#{details[:mcpi][3]}_mark", [x, mcpi_y-31])
|
223
|
+
|
224
|
+
stamp_at("minus", [x, mcpi_y-61]) unless details[:mcpi][4] == 0
|
225
|
+
stamp_at("#{details[:mcpi][4]}_mark", [x, mcpi_y-61])
|
226
|
+
|
227
|
+
mcpi_total_marks = 0
|
228
|
+
0.upto(3) do |i|
|
229
|
+
mcpi_total_marks += details[:mcpi][i]
|
230
|
+
end
|
231
|
+
mcpi_total_marks -= details[:mcpi][4]
|
232
|
+
if mcpi_total_marks < 0
|
233
|
+
stamp_at("#{mcpi_total_marks*-1}_mark", [x, mcpi_y-81])
|
234
|
+
stamp_at("minus", [x, mcpi_y-81])
|
235
|
+
else
|
236
|
+
stamp_at("#{mcpi_total_marks}_mark", [x, mcpi_y-81])
|
237
|
+
end
|
238
|
+
|
239
|
+
part_two_total_mark = details[:implementation].inject(:+) +
|
240
|
+
code_listing_total_marks +
|
241
|
+
details[:testing_and_verification].inject(:+) +
|
242
|
+
details[:user_manual].inject(:+) +
|
243
|
+
mcpi_total_marks
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
# Demonstration
|
248
|
+
unless details[:demonstration_mark].nil?
|
249
|
+
stamp_at("#{details[:demonstration_mark]}_mark",
|
250
|
+
[x, 106])
|
251
|
+
end
|
252
|
+
|
253
|
+
# Total Mark
|
254
|
+
=begin
|
255
|
+
total_mark = 0
|
256
|
+
|
257
|
+
total_mark += part_one_total_mark unless part_one_total_mark.nil?
|
258
|
+
total_mark += part_two_total_mark unless part_two_total_mark.nil?
|
259
|
+
unless details[:demonstration_mark].nil?
|
260
|
+
total_mark += details[:demonstration_mark]
|
261
|
+
end
|
262
|
+
|
263
|
+
go_to_page(1)
|
264
|
+
stamp_at "#{total_mark}_mark", [x, total_mark_position[:y]]
|
265
|
+
details[:total_mark] = total_mark
|
266
|
+
=end
|
267
|
+
end
|
268
|
+
puts "generated: #{details[:student_number]} marksheet"
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.generate_summary(details)
|
272
|
+
summary_details = { :marker_name => details[:marker_name],
|
273
|
+
:student_number => details[:student_number]
|
274
|
+
}
|
275
|
+
|
276
|
+
# part one
|
277
|
+
unless details[:requirements].nil?
|
278
|
+
# Requirements, Analysis and Specification
|
279
|
+
ras = details[:requirements].inject(:+) +
|
280
|
+
details[:analysis].inject(:+) +
|
281
|
+
details[:specification].inject(:+)
|
282
|
+
summary_details[:ras] = ras
|
283
|
+
summary_details[:design] = details[:design].inject(:+)
|
284
|
+
end
|
285
|
+
|
286
|
+
# part two
|
287
|
+
unless details[:implementation].nil?
|
288
|
+
# remove negative marks
|
289
|
+
details[:code_listing].nil?
|
290
|
+
code_listing = 0
|
291
|
+
0.upto(8) do |question|
|
292
|
+
code_listing += details[:code_listing][question]
|
293
|
+
end
|
294
|
+
9.upto(10) do |penalty|
|
295
|
+
code_listing -= details[:code_listing][penalty]
|
296
|
+
end
|
297
|
+
summary_details[:ir_cl] = details[:implementation].inject(:+) +
|
298
|
+
code_listing
|
299
|
+
|
300
|
+
summary_details[:tv_ui] = details[:testing_and_verification].inject(:+) +
|
301
|
+
details[:user_manual].inject(:+)
|
302
|
+
|
303
|
+
mcpi = 0
|
304
|
+
0.upto(3) do |question|
|
305
|
+
mcpi += details[:mcpi][question]
|
306
|
+
end
|
307
|
+
mcpi -= details[:mcpi][4]
|
308
|
+
summary_details[:mcpi] = mcpi
|
309
|
+
end
|
310
|
+
|
311
|
+
# Demonstration
|
312
|
+
unless details[:demonstration_mark].nil?
|
313
|
+
summary_details[:demonstration] = details[:demonstration_mark]
|
314
|
+
end
|
315
|
+
|
316
|
+
|
317
|
+
Prawn::Document.generate(self.summary_out_output_filename(details[:student_number]),
|
318
|
+
:template => self.summary_input_filename) do
|
319
|
+
create_stamp("marker_name") do
|
320
|
+
draw_text summary_details[:marker_name], :at => [0, 0]
|
321
|
+
end
|
322
|
+
|
323
|
+
create_stamp("student_number") do
|
324
|
+
draw_text summary_details[:student_number], :at => [0, 0]
|
325
|
+
end
|
326
|
+
|
327
|
+
# integer marks
|
328
|
+
0.upto(100) do |stamp_number|
|
329
|
+
create_stamp("#{stamp_number}_mark") do
|
330
|
+
draw_text stamp_number.to_s, :at => [0, 0]
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
# half marks for contribution
|
335
|
+
=begin
|
336
|
+
(0..100).step(0.5) do |stamp_number|
|
337
|
+
create_stamp("#{stamp_number}_mark") do
|
338
|
+
draw_text stamp_number.to_s, :at => [0, 0]
|
339
|
+
end
|
340
|
+
end
|
341
|
+
=end
|
342
|
+
|
343
|
+
stamp_at("student_number", [235,652])
|
344
|
+
stamp_at("marker_name", [90,627])
|
345
|
+
|
346
|
+
totals_x_position = 380
|
347
|
+
# Part One
|
348
|
+
# Requirements, Analysis and Specification]
|
349
|
+
unless summary_details[:ras].nil?
|
350
|
+
stamp_at("#{summary_details[:ras]}_mark", [totals_x_position,557])
|
351
|
+
# Design
|
352
|
+
stamp_at("#{summary_details[:design]}_mark",
|
353
|
+
[totals_x_position, 540])
|
354
|
+
end
|
355
|
+
|
356
|
+
# Part Two
|
357
|
+
unless summary_details[:ir_cl].nil?
|
358
|
+
# Implementation Report and Code Listing
|
359
|
+
if summary_details[:ir_cl] < 0
|
360
|
+
stamp_at("#{summary_details[:ir_cl]*-1}_mark",
|
361
|
+
[totals_x_position,520])
|
362
|
+
stamp_at("minus", [totals_x_position,520])
|
363
|
+
else
|
364
|
+
stamp_at("#{summary_details[:ir_cl]}_mark", [totals_x_position,520])
|
365
|
+
end
|
366
|
+
|
367
|
+
# Testing and Verification and User Manual
|
368
|
+
stamp_at("#{summary_details[:tv_ui]}_mark", [totals_x_position,503])
|
369
|
+
|
370
|
+
# Maturity, Consistency, Presentation and Innovation
|
371
|
+
if summary_details[:mcpi] < 0
|
372
|
+
stamp_at("minus", [totals_x_position,484])
|
373
|
+
stamp_at("#{summary_details[:mcpi]*-1}_mark",
|
374
|
+
[totals_x_position,484])
|
375
|
+
else
|
376
|
+
stamp_at("#{summary_details[:mcpi]}_mark",
|
377
|
+
[totals_x_position,484])
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
# Demonstration
|
382
|
+
unless summary_details[:demonstration].nil?
|
383
|
+
stamp_at("#{summary_details[:demonstration]}_mark",
|
384
|
+
[totals_x_position, 466])
|
385
|
+
end
|
386
|
+
|
387
|
+
# Total
|
388
|
+
total_mark = 0
|
389
|
+
# Part One
|
390
|
+
unless summary_details[:ras].nil?
|
391
|
+
total_mark += summary_details[:ras] unless summary_details[:ras].nil?
|
392
|
+
total_mark += summary_details[:design]
|
393
|
+
end
|
394
|
+
# Part Two
|
395
|
+
unless summary_details[:implementation].nil?
|
396
|
+
total_mark += summary_details[:ir_cl]
|
397
|
+
total_mark += summary_details[:tv_ui]
|
398
|
+
total_mark += summary_details[:mcpi]
|
399
|
+
end
|
400
|
+
# Demonstration
|
401
|
+
unless summary_details[:demonstration].nil?
|
402
|
+
total_mark += summary_details[:demonstration]
|
403
|
+
end
|
404
|
+
|
405
|
+
# Stamp totals
|
406
|
+
=begin
|
407
|
+
stamp_at("#{total_mark}_mark",
|
408
|
+
[totals_x_position, 450])
|
409
|
+
|
410
|
+
# Contribution to Digital Electronics
|
411
|
+
stamp_at("#{total_mark.to_f/2}_mark",
|
412
|
+
[totals_x_position, 431])
|
413
|
+
=end
|
414
|
+
end
|
415
|
+
|
416
|
+
puts "generated: #{details[:student_number]} summary"
|
417
|
+
end
|
418
|
+
|
419
|
+
|
420
|
+
def self.save_part_one(details)
|
421
|
+
# write to json file for later retrieval
|
422
|
+
File.open("#{data_directory}/#{details[:student_number]}_part1.json","w") do |f|
|
423
|
+
f.write(details.to_json)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def self.save_part_two(details)
|
428
|
+
# write to json file for later retrieval
|
429
|
+
File.open("#{data_directory}/#{details[:student_number]}_part2.json","w") do |f|
|
430
|
+
f.write(details.to_json)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def self.save_demonstration_mark(details)
|
435
|
+
# write to json file for later retrieval
|
436
|
+
File.open("#{data_directory}/#{details[:student_number]}_demonstration.json","w") do |f|
|
437
|
+
f.write(details.to_json)
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
end
|
442
|
+
|