Requiring Assignment 0 Submissions
The
file_filter
program can enforce that a given assignment (likely 0) be completely submitted and have all components passing before submissions of any other assignments are accepted. A sample filter which would go in
/u/csXXX/bin/file_filter and be designed to be called indirectly from the ISG
file_filter
is:
#!/usr/bin/env perl -w
use strict;
# The required assignment and the current term.
use constant LOGGED_ASSIGN => '00';
use constant TERM => '1095';
# The rejection error code, and corresponding filter message.
use constant ERRCODE => 51;
use constant REJMSG => 'Assignment ' . LOGGED_ASSIGN . ' has not been fully successfully submitted yet.';
# The course name, assignment and student id; guaranteed safe so untaint them.
$ARGV[0] =~ /^(.*)$/;
my $course = $1;
$ARGV[1] =~ /^(.*)$/;
my $assign = $1;
$ARGV[2] =~ /^(.*)$/;
my $student = substr($1, 0, 8);
# Constants that technically depend on .submitrc settings;
# should read .submitrc directly, but we aren't for simplicity.
my $pubtestlog = "/u/$course/course/publictests/" . TERM . '/' . LOGGED_ASSIGN . '.completedrun.log';
# If this assignment is not the one that's required first, check if we need
# to do filtering.
unless ($assign eq LOGGED_ASSIGN) {
my $passed = 0;
if ( -e $pubtestlog ) {
open( PTL, $pubtestlog ) or print "Cannot open log: $!\n" and exit ERRCODE;
while(my $pubtestline = <PTL>) {
# If this student has a perfect mark recorded, then the requirement
# has been met; terminate the loop
# NOTE: As we know the value of $student will not change for the
# lifetime of this program, we set this regex to compile only once.
if ($pubtestline =~ /^\s*\d+\s*${student}\s*\S*\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/o) {
if ($1 == $2) {
$passed = 1;
last;
}
}
}
close( PTL );
}
# Unless the student passed the required assignment, reject all
# submission attempts.
unless ($passed) {
print REJMSG . "\n";
exit ERRCODE;
}
}
# Now re-call the main ISG filter; this environment variable was set by the
# calling program, and again is known to be safe as a result.
$ENV{'ISG_FILTER'} =~ /^(.*)$/;
my $filter = $1;
$ENV{'PATH'} =~ /^(.*)$/;
$ENV{'PATH'} = $1;
for my $arg (@ARGV) {
$arg =~ /^(.*)$/;
$arg = $1;
}
exec $filter, $ARGV[0], $ARGV[1], $ARGV[2], $ARGV[3], $ARGV[4];
The public test log
/u/csXXX/course/publictests/term
is used to determine whether the assignment was passed; there must have been at least one public test request made where a perfect mark was earned from a public test request. Doing a full retest on every submission request would be too time consuming, and this confirms that the students confirmed that they received full marks.
This filter relies on marks being written to the mark list in the form
$student:$mark/$total
, which is created by calls of the form
writeToMarkList "$mark/$total"
inside of an
RST suite's computeMarks script. This is done automatically for users of
BitterSuite.