commit 49bc1c434d8c899836a29a37b97034c27c1ac7c8 Author: Filip Gralinski Date: Sat Oct 10 21:20:34 2020 +0200 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd8cec1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.class +summary.txt +*~ +*.out +*.far +*.res +report.txt +TaskX02/run +*.jar +*.o +*.pyc +\#* +result.csv \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69e3feb --- /dev/null +++ b/Makefile @@ -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 diff --git a/TaskA01/description.yaml b/TaskA01/description.yaml new file mode 100644 index 0000000..fc4e716 --- /dev/null +++ b/TaskA01/description.yaml @@ -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 diff --git a/TaskX01/Makefile b/TaskX01/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/TaskX01/complex.exp b/TaskX01/complex.exp new file mode 100644 index 0000000..60d3b2f --- /dev/null +++ b/TaskX01/complex.exp @@ -0,0 +1 @@ +15 diff --git a/TaskX01/complex.in b/TaskX01/complex.in new file mode 100644 index 0000000..8a1218a --- /dev/null +++ b/TaskX01/complex.in @@ -0,0 +1,5 @@ +1 +2 +3 +4 +5 diff --git a/TaskX01/description.txt b/TaskX01/description.txt new file mode 100644 index 0000000..35cab96 --- /dev/null +++ b/TaskX01/description.txt @@ -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 diff --git a/TaskX01/run b/TaskX01/run new file mode 100755 index 0000000..4f962c2 --- /dev/null +++ b/TaskX01/run @@ -0,0 +1,10 @@ +#!/usr/bin/python2 + +import sys + +count = 0 + +for line in sys.stdin: + count += int(line) + +print count diff --git a/TaskX01/simple.exp b/TaskX01/simple.exp new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/TaskX01/simple.exp @@ -0,0 +1 @@ +4 diff --git a/TaskX01/simple.in b/TaskX01/simple.in new file mode 100644 index 0000000..51993f0 --- /dev/null +++ b/TaskX01/simple.in @@ -0,0 +1,2 @@ +2 +2 diff --git a/TaskX02/Makefile b/TaskX02/Makefile new file mode 100644 index 0000000..ebd0ebf --- /dev/null +++ b/TaskX02/Makefile @@ -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 $@ $< diff --git a/TaskX02/description.txt b/TaskX02/description.txt new file mode 100644 index 0000000..bcbbd3f --- /dev/null +++ b/TaskX02/description.txt @@ -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 diff --git a/TaskX02/run.cpp b/TaskX02/run.cpp new file mode 100644 index 0000000..90cd6c9 --- /dev/null +++ b/TaskX02/run.cpp @@ -0,0 +1,12 @@ +#include +#include + +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; +} diff --git a/TaskX02/simple.exp b/TaskX02/simple.exp new file mode 100644 index 0000000..00750ed --- /dev/null +++ b/TaskX02/simple.exp @@ -0,0 +1 @@ +3 diff --git a/TaskX02/simple.in b/TaskX02/simple.in new file mode 100644 index 0000000..036d7a3 --- /dev/null +++ b/TaskX02/simple.in @@ -0,0 +1,3 @@ +raz +dwa +trzy diff --git a/TaskX03/description.txt b/TaskX03/description.txt new file mode 100644 index 0000000..bcab497 --- /dev/null +++ b/TaskX03/description.txt @@ -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 diff --git a/TaskX03/simple.exp b/TaskX03/simple.exp new file mode 100644 index 0000000..fd1d062 --- /dev/null +++ b/TaskX03/simple.exp @@ -0,0 +1,4 @@ +9 Szeregowy +4 Rico +8 Kowalski +7 Skipper diff --git a/TaskX03/simple.in b/TaskX03/simple.in new file mode 100644 index 0000000..8750bae --- /dev/null +++ b/TaskX03/simple.in @@ -0,0 +1,4 @@ +Szeregowy +Rico +Kowalski +Skipper diff --git a/blend.sh b/blend.sh new file mode 100755 index 0000000..ec38ab6 --- /dev/null +++ b/blend.sh @@ -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 diff --git a/count-points.pl b/count-points.pl new file mode 100755 index 0000000..6b4407c --- /dev/null +++ b/count-points.pl @@ -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; +} diff --git a/create-report.pl b/create-report.pl new file mode 100755 index 0000000..b463edb --- /dev/null +++ b/create-report.pl @@ -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; +} diff --git a/overrides.txt b/overrides.txt new file mode 100644 index 0000000..e69de29