Skip to content

Commit b6ba0b5

Browse files
committed
test-generator/generate-test.pl: The generator of tests
Signed-off-by: Marian Marinov <[email protected]>
1 parent 1974c08 commit b6ba0b5

File tree

1 file changed

+288
-0
lines changed

1 file changed

+288
-0
lines changed

test-generator/generate-test.pl

+288
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
#!/usr/bin/perl
2+
use strict;
3+
use warnings;
4+
use POSIX qw(strftime);
5+
use DBD::Pg;
6+
use PDF::Reuse;
7+
use utf8;
8+
9+
#
10+
# ./generate-tests.pl [variant]
11+
#
12+
13+
$|=1;
14+
15+
sub logger {
16+
print 'Error: ' . $_[0] ."\n" if defined($_[0]);
17+
}
18+
19+
my $debug = 0;
20+
my $pguser = 'netsec';
21+
my $pgpass = '';
22+
my $pgdb = 'DBI:Pg:database=smal;host=localhost;port=5432';
23+
my $pgconn = DBI->connect_cached( $pgdb, $pguser, $pgpass, { PrintError => 1, AutoCommit => 1 }) or die("$DBI::errstr\n");
24+
my $schema = 'public';
25+
# define which test we are going to generate, first or second
26+
my $first_test = 1;
27+
my %ques = ();
28+
my $qcount = 0;
29+
my $question_count = 1;
30+
my $max_questions = 50;
31+
my $variant = 1;
32+
$variant = $ARGV[0] if (defined($ARGV[0]) && $ARGV[0] =~ /^[0-9]+$/);
33+
my $filename = "test1-variant$variant";
34+
my $first_qid;
35+
36+
print "Generating test variant $variant\n";
37+
38+
$pgconn->{pg_enable_utf8}=1;
39+
# get the total count of questions in the table
40+
my $get_qcount = $pgconn->prepare(sprintf('SELECT count(*) FROM "%s".questions WHERE %s first_test', $schema, $first_test ? '' : 'NOT' ))
41+
or logger($DBI::errstr);
42+
$get_qcount->execute() or logger($DBI::errstr);
43+
$qcount = $get_qcount->fetchrow_array or logger($DBI::errstr);
44+
if ($first_test) {
45+
$first_qid = $pgconn->prepare(sprintf('SELECT id FROM "%s".questions WHERE first_test ORDER BY id LIMIT 1', $schema ))
46+
or logger($DBI::errstr);
47+
} else {
48+
$first_qid = $pgconn->prepare(sprintf('SELECT id FROM "%s".questions WHERE NOT first_test ORDER BY id LIMIT 1', $schema ))
49+
or logger($DBI::errstr);
50+
}
51+
52+
my $get_question = $pgconn->prepare(sprintf('SELECT question FROM "%s".questions WHERE id = ? LIMIT 1', $schema))
53+
or logger($DBI::errstr);
54+
my $right_asnwares = $pgconn->prepare(sprintf('SELECT answer FROM "%s".right_answers WHERE q_id = ?', $schema))
55+
or logger($DBI::errstr);
56+
my $wrong_asnwares = $pgconn->prepare(sprintf('SELECT answer FROM "%s".wrong_answers WHERE q_id = ?', $schema))
57+
or logger($DBI::errstr);
58+
59+
# %ques structure
60+
# key - question id
61+
# [0] - location of the right answare
62+
# [1] - [4] - randomly selected right or wrong answare
63+
# [5] - question text
64+
# [6] - question id
65+
my %questions_check = ();
66+
my %excluded = ();
67+
68+
my $id_compensation = 1;
69+
$id_compensation = $first_qid-1 if !$first_test;
70+
my $id = $id_compensation + int(rand($qcount));
71+
# generate random question positions
72+
while ($question_count <= $max_questions) {
73+
print "Num: $question_count" if $debug;
74+
my $rcount = 0;
75+
until (! exists $questions_check{$id} && ! exists $excluded{$id}) {
76+
$id = $id_compensation + int(rand($qcount));
77+
if ($rcount == 350) {
78+
print "Too random\n" if $debug;
79+
last;
80+
}
81+
$rcount++;
82+
}
83+
print " q_id: $id\n" if $debug;
84+
$questions_check{$id} = 1;
85+
$ques{$question_count} = [ -1, -1, -1, -1, -1, -1 ];
86+
$ques{$question_count}[6] = $id;
87+
my $location = 1 + int(rand(4));
88+
$ques{$question_count}[$location] = 66;
89+
$ques{$question_count}[0] = $location;
90+
$question_count++;
91+
}
92+
for (sort keys(%ques)) {print "$_ not defined\n" if (!defined($ques{$_}[0]));}
93+
94+
my $page_count = 1;
95+
# Starting position on the page(after the answer boxes)
96+
my $last_line = 666;
97+
98+
sub page_check {
99+
my $last_pos = $_[0];
100+
my $page_count = $_[1];
101+
print 'Page: '.${$page_count}.' Line: '.${$last_pos}."\n" if $debug;
102+
${$last_pos} -= 16;
103+
if (${$last_pos} < 40) {
104+
if (${$page_count} == 1) {
105+
prAdd("0.0 0.0 0.0 RG\n");
106+
prAdd("9.0 9.0 9.0 rg\n");
107+
for my $l (1..25) {
108+
my $pos = ($l * 18) + 20;
109+
prAdd("$pos 711 18 20 re\n");
110+
prAdd("$pos 676 18 20 re\n");
111+
}
112+
prAdd("B\n");
113+
}
114+
115+
${$last_pos} = 780;
116+
prPage();
117+
${$page_count}++;
118+
prText(520,800,'Page '.${$page_count});
119+
}
120+
}
121+
122+
prFile("$filename.pdf");
123+
prTTFont('/usr/share/fonts/arial.ttf');
124+
prText(35,800,"Linux System & Network Administration");
125+
prText(340,800,"TEST 1 2015");
126+
prText(532,800,"Page $page_count");
127+
prText(35,780,"Name: ______________________________________________________________________");
128+
prText(35,760,"SoftUni username: ______________________________");
129+
prText(510,760," Variant: $variant");
130+
for my $l (1..25) {
131+
my $pos = ($l * 18) + 24;
132+
if ($l > 9) {
133+
$pos = ($l * 18) + 22;
134+
}
135+
prText($pos,734,$l);
136+
prText($pos-1,699,$l+25);
137+
}
138+
139+
prFontSize('10');
140+
141+
# populate the questions
142+
my $tcount = 1;
143+
for (1..$max_questions) {
144+
my $qid = $_;
145+
next if ($ques{$qid}[6] !~ /^[0-9]+$/);
146+
# get the question
147+
$get_question->execute($ques{$qid}[6]) or logger($DBI::errstr);
148+
my $question = $get_question->fetchrow_array or logger($DBI::errstr);
149+
print 'Get question: (' . $ques{$qid}[6] . ') ' . $question . "\n" if $debug;
150+
# get all right answares
151+
$right_asnwares->execute($ques{$qid}[6]) or logger($DBI::errstr);
152+
my @answares = ();
153+
my $entry_count=0;
154+
while(my $data = $right_asnwares->fetchrow_array) {
155+
$answares[$entry_count] = $data;
156+
$entry_count++;
157+
}
158+
159+
# get all wrong answares
160+
$wrong_asnwares->execute($ques{$qid}[6]) or logger($DBI::errstr);
161+
my @mistakes = ();
162+
$entry_count = 0;
163+
# copy them into an array
164+
while (my @data = $wrong_asnwares->fetchrow_array) {
165+
$mistakes[$entry_count] = $data[0];
166+
$entry_count++;
167+
}
168+
169+
# get 3 random answares
170+
my @mis = ();
171+
if ($#mistakes <=2) {
172+
for (my $m=0; $m <=2 ; $m++) {
173+
$mis[$m] = $mistakes[$m] if defined($mistakes[$m]);
174+
}
175+
} else {
176+
my %inuse = ();
177+
for (my $m = 0; $m < 3; $m++) {
178+
my $num = 0 + int(rand($#mistakes));
179+
until (! exists $inuse{$num}) {
180+
$num = 0 + int(rand($#mistakes));
181+
}
182+
$inuse{$num} = 0;
183+
$mis[$m] = $mistakes[$num];
184+
}
185+
}
186+
187+
# save the random chosen wrong answares into the hash
188+
$entry_count = 0;
189+
for (my $m = 1; $m <= 4; $m++) {
190+
# skip the right answare place
191+
next if ($m == $ques{$qid}[0]);
192+
$ques{$qid}[$m] = $mis[$entry_count] if defined($mis[$entry_count]);
193+
$entry_count++;
194+
}
195+
196+
# save the question into the hash
197+
$ques{$qid}[5] = $question;
198+
# save the answare into the hash
199+
$ques{$qid}[$ques{$qid}[0]] = $answares[0 + int(rand($#answares))];
200+
# add ? to all questions that don't have one at the end
201+
print "Id: $qid Qid: $ques{$qid}[5]\n" if $debug;
202+
$ques{$qid}[5] =~ s/:\s*$// if ($ques{$qid}[5] =~ /:\s*$/);
203+
$ques{$qid}[5] = $ques{$qid}[5].' ?' if ($ques{$qid}[5] !~ /\?$/);
204+
205+
page_check(\$last_line,\$page_count);
206+
207+
my $q_len = length($ques{$qid}[5]);
208+
if ($q_len > 92) {
209+
my @lines = split /\n/, $ques{$qid}[5];
210+
for (my $l=0;$l<=$#lines;$l++) {
211+
$lines[$l] =~ s/\n/ /g;
212+
if ($l==0) {
213+
prText(35,$last_line,sprintf('%d. %s', $qid, $lines[$l]));
214+
} else {
215+
prText(35,$last_line,$lines[$l]) if ($lines[$l] !~ /^[\s|\n]*$/);
216+
}
217+
page_check(\$last_line,\$page_count);
218+
}
219+
} else {
220+
prText(35,$last_line,sprintf('%d. %s', $qid, $ques{$qid}[5]));
221+
}
222+
223+
my %a_names = ( 1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd' );
224+
$entry_count = 1;
225+
for (my $c=1;$c<5;$c++) {
226+
if (defined($ques{$qid}[$c]) && $ques{$qid}[$c] ne '-1') {
227+
printf(" %s) %s\n", $a_names{$entry_count}, $ques{$qid}[$c]) if $debug;
228+
page_check(\$last_line,\$page_count);
229+
prText(35,$last_line,sprintf(" %s) %s", $a_names{$entry_count}, $ques{$qid}[$c]));
230+
$entry_count++;
231+
}
232+
}
233+
$tcount++;
234+
}
235+
236+
prEnd();
237+
prFile("$filename-asnwares.pdf");
238+
prTTFont('/usr/share/fonts/arial.ttf');
239+
prText(510,760,"Вариянт: $variant");
240+
for my $l (1..25) {
241+
my $pos = ($l * 18) + 24;
242+
prText($pos,724,$l);
243+
prText($pos,684,$l+25);
244+
}
245+
246+
# print the right answares :)
247+
$tcount = 1;
248+
print "\nNum: \n" if $debug;
249+
# prAdd("0.0 0.0 0.0 RG\n");
250+
#for (sort keys(%ques)) {
251+
for (1..$max_questions) {
252+
print "$_ not defined\n" if (!defined($ques{$_}[0]) && $debug);
253+
my $right = 'a';
254+
$right = 'b' if ($ques{$_}[0] == 2);
255+
$right = 'c' if ($ques{$_}[0] == 3);
256+
$right = 'd' if ($ques{$_}[0] == 4);
257+
printf("%2d: %s \n",$tcount, $right) if $debug;
258+
prAdd("q 40 717 m 490 717 l S Q");
259+
prAdd("q 40 698 m 490 698 l S Q");
260+
prAdd("q 40 677 m 490 677 l S Q");
261+
prAdd("q 40 658 m 490 658 l S Q");
262+
prAdd("q 490 698 m 490 717 l S Q");
263+
prAdd("q 490 658 m 490 677 l S Q");
264+
if ($tcount <= 25) {
265+
my $pos = ($tcount * 18) + 24;
266+
my $pos2 = $pos - 2;
267+
prAdd("q $pos2 698 m $pos2 717 l S Q");
268+
# prAdd("9.0 9.0 9.0 rg\n");
269+
# prAdd("$pos2 700 18 20 re\n");
270+
# prAdd("t\n");
271+
prText($pos,702,$right);
272+
} else {
273+
my $pos = (($tcount - 25) * 18) + 24;
274+
my $pos2 = $pos - 2;
275+
prAdd("q $pos2 658 m $pos2 677 l S Q");
276+
prText($pos,662,$right);
277+
}
278+
279+
$tcount++;
280+
}
281+
282+
for my $l (1..25) {
283+
my $pos = ($l * 18) + 20;
284+
prAdd("$pos 700 18 20 re\n");
285+
prAdd("$pos 660 18 20 re\n");
286+
}
287+
prAdd("B\n");
288+
prEnd();

0 commit comments

Comments
 (0)