This commit is contained in:
Filip Gralinski 2020-10-10 21:20:34 +02:00
commit 49bc1c434d
22 changed files with 502 additions and 0 deletions

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
*.class
summary.txt
*~
*.out
*.far
*.res
report.txt
TaskX02/run
*.jar
*.o
*.pyc
\#*
result.csv

35
Makefile Normal file
View 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
View 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
View File

1
TaskX01/complex.exp Normal file
View File

@ -0,0 +1 @@
15

5
TaskX01/complex.in Normal file
View File

@ -0,0 +1,5 @@
1
2
3
4
5

6
TaskX01/description.txt Normal file
View 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
View 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
View File

@ -0,0 +1 @@
4

2
TaskX01/simple.in Normal file
View File

@ -0,0 +1,2 @@
2
2

14
TaskX02/Makefile Normal file
View 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
View 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
View 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
View File

@ -0,0 +1 @@
3

3
TaskX02/simple.in Normal file
View File

@ -0,0 +1,3 @@
raz
dwa
trzy

5
TaskX03/description.txt Normal file
View 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
View File

@ -0,0 +1,4 @@
9 Szeregowy
4 Rico
8 Kowalski
7 Skipper

4
TaskX03/simple.in Normal file
View File

@ -0,0 +1,4 @@
Szeregowy
Rico
Kowalski
Skipper

52
blend.sh Executable file
View 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
View 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
View 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
View File