Init
This commit is contained in:
commit
49bc1c434d
13
.gitignore
vendored
Normal file
13
.gitignore
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
*.class
|
||||||
|
summary.txt
|
||||||
|
*~
|
||||||
|
*.out
|
||||||
|
*.far
|
||||||
|
*.res
|
||||||
|
report.txt
|
||||||
|
TaskX02/run
|
||||||
|
*.jar
|
||||||
|
*.o
|
||||||
|
*.pyc
|
||||||
|
\#*
|
||||||
|
result.csv
|
35
Makefile
Normal file
35
Makefile
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
|
||||||
|
# gathering solved tasks
|
||||||
|
solutions:=$(shell ls Task???/Makefile)
|
||||||
|
|
||||||
|
reports:=$(solutions:Makefile=report.txt)
|
||||||
|
|
||||||
|
all: summary.txt
|
||||||
|
|
||||||
|
.PRECIOUS: %.out %.res
|
||||||
|
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
|
||||||
|
summary.txt: $(reports)
|
||||||
|
perl count-points.pl $^ | tee $@
|
||||||
|
|
||||||
|
%/report.txt: $$(subst .in,.res,$$(wildcard %/*.in))
|
||||||
|
echo CREATING REPORT FOR $@
|
||||||
|
perl create-report.pl $^ > $@
|
||||||
|
|
||||||
|
%.res: %.out %.exp
|
||||||
|
(diff $^ > $@ || exit 0)
|
||||||
|
|
||||||
|
%.out: $$(@D)/run %.in
|
||||||
|
chmod u+x $<
|
||||||
|
$< $*.arg < $(word 2,$^) > $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(BINARIES)
|
||||||
|
rm -f summary.txt
|
||||||
|
find . -name '*.out' -exec rm '{}' ';'
|
||||||
|
find . -name '*.res' -exec rm '{}' ';'
|
||||||
|
find . -name 'report.txt' -exec rm '{}' ';'
|
||||||
|
|
||||||
|
-include Task*/Makefile
|
10
TaskA01/description.yaml
Normal file
10
TaskA01/description.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
- title: Hamlet
|
||||||
|
- description: >-
|
||||||
|
Write a program to find lines containing the word "Hamlet".
|
||||||
|
Do not use regular expressions, just the simplest capabilities
|
||||||
|
of a programming language.
|
||||||
|
- points: 2
|
||||||
|
- deadline: 2020-10-15 23:59:59
|
||||||
|
- files:
|
||||||
|
- url: https://www.gutenberg.org/files/100/100-0.txt
|
||||||
|
name: shakespeare.in
|
0
TaskX01/Makefile
Normal file
0
TaskX01/Makefile
Normal file
1
TaskX01/complex.exp
Normal file
1
TaskX01/complex.exp
Normal file
@ -0,0 +1 @@
|
|||||||
|
15
|
5
TaskX01/complex.in
Normal file
5
TaskX01/complex.in
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
6
TaskX01/description.txt
Normal file
6
TaskX01/description.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Print the sum of integers read from the standard input.
|
||||||
|
Note: this is just an example of a task (and a solution).
|
||||||
|
The task has a solution already, do not solve it!
|
||||||
|
|
||||||
|
POINTS: 1
|
||||||
|
DEADLINE: 2019-10-30 23:59
|
10
TaskX01/run
Executable file
10
TaskX01/run
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
count += int(line)
|
||||||
|
|
||||||
|
print count
|
1
TaskX01/simple.exp
Normal file
1
TaskX01/simple.exp
Normal file
@ -0,0 +1 @@
|
|||||||
|
4
|
2
TaskX01/simple.in
Normal file
2
TaskX01/simple.in
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
2
|
||||||
|
2
|
14
TaskX02/Makefile
Normal file
14
TaskX02/Makefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
# Aby `make clean` mogło dzialać poprawnie, wszystkie pliki binarne
|
||||||
|
# (także pliki .jar dla Javy) powinny zostać dodane do zmiennej
|
||||||
|
# BINARIES.
|
||||||
|
# Takie pliki dobrze także dodać do pliku `.gitignore`, żeby
|
||||||
|
# git przez pomyłkę ich nie dodaj (nigdy nie wypychamy binariów!).
|
||||||
|
BINARIES += TaskX02/run
|
||||||
|
|
||||||
|
# Aby skompilować plik `run` ze źródła (`run.cpp`) należy wywołać
|
||||||
|
# kompilator języka C++ (GNU C++ - `g++`).
|
||||||
|
# $@ to plik wynikowy (`run`)
|
||||||
|
# $< to plik wejściowy (`run.cpp`)
|
||||||
|
TaskX02/run: TaskX02/run.cpp
|
||||||
|
g++ -o $@ $<
|
8
TaskX02/description.txt
Normal file
8
TaskX02/description.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
Print the number lines read from the standard input.
|
||||||
|
|
||||||
|
The task has a solution already, do not solve it!
|
||||||
|
This is an example of a solution in a compilable langauge
|
||||||
|
(Makefile is needed in which compilation process is described.)
|
||||||
|
|
||||||
|
POINTS: 0
|
||||||
|
DEADLINE: 2019-10-30 23:59
|
12
TaskX02/run.cpp
Normal file
12
TaskX02/run.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char* arv[])
|
||||||
|
{
|
||||||
|
unsigned int line_counter = 0;
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(std::cin, line))
|
||||||
|
++line_counter;
|
||||||
|
|
||||||
|
std::cout << line_counter << std::endl;
|
||||||
|
}
|
1
TaskX02/simple.exp
Normal file
1
TaskX02/simple.exp
Normal file
@ -0,0 +1 @@
|
|||||||
|
3
|
3
TaskX02/simple.in
Normal file
3
TaskX02/simple.in
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
raz
|
||||||
|
dwa
|
||||||
|
trzy
|
5
TaskX03/description.txt
Normal file
5
TaskX03/description.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
For each line read from the standard input print the number of characters
|
||||||
|
(not counting the end-of-line character), a space and the line read.
|
||||||
|
|
||||||
|
POINTS: 1
|
||||||
|
DEADLINE: 2019-10-30 23:59
|
4
TaskX03/simple.exp
Normal file
4
TaskX03/simple.exp
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
9 Szeregowy
|
||||||
|
4 Rico
|
||||||
|
8 Kowalski
|
||||||
|
7 Skipper
|
4
TaskX03/simple.in
Normal file
4
TaskX03/simple.in
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Szeregowy
|
||||||
|
Rico
|
||||||
|
Kowalski
|
||||||
|
Skipper
|
52
blend.sh
Executable file
52
blend.sh
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/bash -ex
|
||||||
|
|
||||||
|
PREFIX=djfz-2019
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
STUDENT_DIR=`ls -d ${PREFIX}-s??????`
|
||||||
|
|
||||||
|
echo "USING $STUDENT_DIR"
|
||||||
|
|
||||||
|
rm -rf arena
|
||||||
|
mkdir arena
|
||||||
|
|
||||||
|
cp -R $STUDENT_DIR/* arena/
|
||||||
|
ln -s ../$STUDENT_DIR/.git arena/.git
|
||||||
|
|
||||||
|
cp "${PREFIX}/create-report.pl" arena/
|
||||||
|
cp "${PREFIX}/count-points.pl" arena/
|
||||||
|
cp "${PREFIX}/overrides.txt" arena/
|
||||||
|
cp "${PREFIX}/Makefile" arena/
|
||||||
|
|
||||||
|
for TX in X01 X02 X03 X04 X05 X06 X07 X08 B00 B01 B02 B03 B04 B05 B06 C00 C01 C02 C03 C04 C05 C06 E01 E02 E03 E04 E05 E06 E07 # X05 X06 X07 X08 X09 X10 B03 B04 X10
|
||||||
|
do
|
||||||
|
mkdir -p arena/Task$TX
|
||||||
|
done
|
||||||
|
|
||||||
|
#cp $PREFIX/TaskA49/Makefile $PREFIX/TaskA49/run arena/TaskA49/
|
||||||
|
|
||||||
|
for AX in `seq -w 0 49`
|
||||||
|
do
|
||||||
|
mkdir -p arena/TaskA$AX
|
||||||
|
done
|
||||||
|
|
||||||
|
#for CX in `seq -w 0 6`
|
||||||
|
#do
|
||||||
|
# mkdir -p arena/TaskC0$CX
|
||||||
|
#done
|
||||||
|
|
||||||
|
find $PREFIX -name "*.in" -o -name "*.exp" | while read K; do
|
||||||
|
cp $K arena/${K#*/}
|
||||||
|
done
|
||||||
|
|
||||||
|
cd $PREFIX
|
||||||
|
|
||||||
|
for T in Task???
|
||||||
|
do
|
||||||
|
mkdir -p ../arena/$T
|
||||||
|
done
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
find ${PREFIX} -regextype egrep -regex '.*/(description.txt|.*\.arg|.*\.in|.*\.exp)' -print | while read T; do cp $T ${T/${PREFIX}/arena}; done
|
287
count-points.pl
Executable file
287
count-points.pl
Executable file
@ -0,0 +1,287 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use TAP::Parser;
|
||||||
|
use Data::Dumper;
|
||||||
|
use Cwd;
|
||||||
|
|
||||||
|
binmode(STDOUT, ':utf8');
|
||||||
|
binmode(STDERR, ':utf8');
|
||||||
|
|
||||||
|
my %overrides = ();
|
||||||
|
|
||||||
|
if (-r 'overrides.txt') {
|
||||||
|
read_overrides();
|
||||||
|
}
|
||||||
|
|
||||||
|
my @reports = sort @ARGV;
|
||||||
|
|
||||||
|
my $total;
|
||||||
|
my %section_points = ('A' => 0, 'B' => 0, 'C' => 0);
|
||||||
|
|
||||||
|
my $student_id = get_student_id();
|
||||||
|
|
||||||
|
if (defined $student_id) {
|
||||||
|
print "STUDENT ID is $student_id\n";
|
||||||
|
} else {
|
||||||
|
print "UNKNOWN STUDENT ID\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
intro();
|
||||||
|
|
||||||
|
for my $report (@reports) {
|
||||||
|
update_total($report, process_report($report));
|
||||||
|
}
|
||||||
|
|
||||||
|
outro($total);
|
||||||
|
|
||||||
|
sub get_student_id {
|
||||||
|
my $pwd = cwd();
|
||||||
|
|
||||||
|
if (my ($student_id) = ($pwd =~ m{-s(\d{5,7})(/arena)?})) {
|
||||||
|
return $student_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub update_total {
|
||||||
|
my ($report_file_path, $points) = @_;
|
||||||
|
|
||||||
|
my $section = get_section($report_file_path);
|
||||||
|
|
||||||
|
if (defined $section && $section ne 'A') {
|
||||||
|
if ($section_points{$section} > 0) {
|
||||||
|
print "UWAGA: TYLKO ZADANIE Z NAJWIĘKSZĄ LICZBĄ PUNKTÓW BĘDZIE LICZONE DLA DZIAŁU $section\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($points > $section_points{$section}) {
|
||||||
|
$total = $total - $section_points{$section} + $points;
|
||||||
|
$section_points{$section} = $points;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$total += $points;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_section {
|
||||||
|
my ($report_file_path) = @_;
|
||||||
|
|
||||||
|
if (my ($section) = ($report_file_path =~ m{Task([ABC])})) {
|
||||||
|
return $section;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_failures_and_successes {
|
||||||
|
my ($file_path) = @_;
|
||||||
|
|
||||||
|
open my $tap_fh, $file_path or die $!;
|
||||||
|
|
||||||
|
my $tap_parser = TAP::Parser->new( { source => $tap_fh } );
|
||||||
|
|
||||||
|
while ( my $result = $tap_parser->next ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return (scalar($tap_parser->actual_failed), scalar($tap_parser->passed))
|
||||||
|
}
|
||||||
|
|
||||||
|
sub process_report {
|
||||||
|
my ($report_file) = @_;
|
||||||
|
|
||||||
|
my ($task_id) = ($report_file =~ m{^(.*)/report\.txt$});
|
||||||
|
|
||||||
|
my $override_key = get_override_key($student_id, $task_id);
|
||||||
|
|
||||||
|
if (exists $overrides{$override_key}) {
|
||||||
|
my $override_points = $overrides{$override_key};
|
||||||
|
|
||||||
|
print $task_id, " ", "FROM overrides.txt: ", $override_points, "\n";
|
||||||
|
|
||||||
|
return $override_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($nb_of_failures, $nb_of_successes) = get_failures_and_successes($report_file);
|
||||||
|
|
||||||
|
my $success = ($nb_of_failures == 0 && $nb_of_successes > 0);
|
||||||
|
|
||||||
|
my ($points, $deadline, $total, $remainder) = parse_description($task_id);
|
||||||
|
|
||||||
|
print $task_id, " ", ($success ? "PASSED" : "FAILED");
|
||||||
|
|
||||||
|
if (!check_deadline($task_id, $deadline)) {
|
||||||
|
$success = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!check_if_the_right_task($student_id, $task_id, $total, $remainder)) {
|
||||||
|
print " WRONG TASK!";
|
||||||
|
$success = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$success) {
|
||||||
|
$points = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
print " POINTS: $points";
|
||||||
|
}
|
||||||
|
|
||||||
|
print "\n";
|
||||||
|
|
||||||
|
return $points;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub check_deadline {
|
||||||
|
my ($task_id, $deadline) = @_;
|
||||||
|
|
||||||
|
for my $file (glob "$task_id/*") {
|
||||||
|
if ($file !~ m{\.(in|arg|out|exp|\~)$|/(description\.txt|run)$}) {
|
||||||
|
my $dir_to_check = "../djfz-2019-s$student_id";
|
||||||
|
if (not defined($student_id)) {
|
||||||
|
$dir_to_check = '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
my $last_timestamp = `(cd $dir_to_check; git log -1 --format=\%cd --date=iso $file 2> /dev/null)`;
|
||||||
|
|
||||||
|
if ($last_timestamp =~ m{\S}) {
|
||||||
|
chomp $last_timestamp;
|
||||||
|
if ($last_timestamp gt $deadline) {
|
||||||
|
print " TOO LATE [$file: $last_timestamp later than $deadline]";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub check_if_the_right_task {
|
||||||
|
my ($student_id, $task_id, $total, $remainder) = @_;
|
||||||
|
|
||||||
|
if (defined($total)) {
|
||||||
|
if ($student_id % $total != $remainder) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 if $task_id =~ m{^TaskE} and not is_estudent($student_id);
|
||||||
|
|
||||||
|
return 0 if $task_id =~ m{^Task[AC]} and is_estudent($student_id);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub intro {
|
||||||
|
print_header();
|
||||||
|
print "SUMMARY\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub outro {
|
||||||
|
my ($points) = @_;
|
||||||
|
|
||||||
|
print "\nTOTAL POINTS: $points\n";
|
||||||
|
|
||||||
|
open my $fh, '>', 'result.csv';
|
||||||
|
print $fh "POINTS\n";
|
||||||
|
print $fh $points, "\n";
|
||||||
|
close($fh);
|
||||||
|
|
||||||
|
print_header();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub print_header {
|
||||||
|
print "=" x 20,"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parse_description {
|
||||||
|
my ($task_id) = @_;
|
||||||
|
|
||||||
|
open my $fh, '<', "$task_id/description.txt" or die "???";
|
||||||
|
|
||||||
|
my $points = 0;
|
||||||
|
my $deadline = undef;
|
||||||
|
my $total = undef;
|
||||||
|
my $remainder = undef;
|
||||||
|
|
||||||
|
while (my $line=<$fh>) {
|
||||||
|
if ($line =~ m{^POINTS\s*:\s*(\d+)\s*$}) {
|
||||||
|
$points = $1;
|
||||||
|
} elsif ($line =~ m{^DEADLINE\s*:\s*(.*?)\s*$}) {
|
||||||
|
$deadline = $1;
|
||||||
|
} elsif ($line =~ m{^REMAINDER\s*:\s*(\d+)/(\d+)\s*$}) {
|
||||||
|
$remainder = $1;
|
||||||
|
$total = $2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($points, $deadline, $total, $remainder);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub read_overrides {
|
||||||
|
open my $fh, '<', 'overrides.txt';
|
||||||
|
|
||||||
|
while (my $line=<$fh>) {
|
||||||
|
chomp $line;
|
||||||
|
my ($id, $task, $points, $info) = split/\s+/,$line;
|
||||||
|
|
||||||
|
$overrides{get_override_key($id, "Task".$task)} = $points;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_override_key {
|
||||||
|
my ($id, $task) = @_;
|
||||||
|
|
||||||
|
return $id.'+'.$task;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub is_estudent {
|
||||||
|
my ($id) = @_;
|
||||||
|
|
||||||
|
my $suffix = substr($id, 1);
|
||||||
|
|
||||||
|
my %estudents = map { $_ => 1 } split/\n/,<<'END_OF_NUMBERS';
|
||||||
|
16136
|
||||||
|
21804
|
||||||
|
30291
|
||||||
|
30686
|
||||||
|
32746
|
||||||
|
32753
|
||||||
|
32754
|
||||||
|
32757
|
||||||
|
32759
|
||||||
|
32778
|
||||||
|
32813
|
||||||
|
32837
|
||||||
|
34595
|
||||||
|
34596
|
||||||
|
34598
|
||||||
|
34599
|
||||||
|
34603
|
||||||
|
34604
|
||||||
|
34608
|
||||||
|
34650
|
||||||
|
34654
|
||||||
|
39546
|
||||||
|
40549
|
||||||
|
42335
|
||||||
|
42611
|
||||||
|
42612
|
||||||
|
42613
|
||||||
|
42614
|
||||||
|
50169
|
||||||
|
50711
|
||||||
|
52484
|
||||||
|
84146
|
||||||
|
END_OF_NUMBERS
|
||||||
|
|
||||||
|
if ($estudents{$suffix}) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
29
create-report.pl
Executable file
29
create-report.pl
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
print "1..".($#ARGV + 1),"\n";
|
||||||
|
|
||||||
|
my $counter = 1;
|
||||||
|
|
||||||
|
for my $test_case (@ARGV) {
|
||||||
|
|
||||||
|
my $test_case_name = $test_case;
|
||||||
|
$test_case_name =~ s{\.res$}{};
|
||||||
|
|
||||||
|
if (-s $test_case == 0) {
|
||||||
|
print "ok $counter $test_case_name\n";
|
||||||
|
} else {
|
||||||
|
print "not ok $counter $test_case_name\n";
|
||||||
|
|
||||||
|
open my $fh, '<', $test_case;
|
||||||
|
|
||||||
|
while (my $line=<$fh>) {
|
||||||
|
$line =~ s/^\s*---/===/;
|
||||||
|
|
||||||
|
print " $line";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++$counter;
|
||||||
|
}
|
0
overrides.txt
Normal file
0
overrides.txt
Normal file
Loading…
Reference in New Issue
Block a user