Sindbad~EG File Manager
<?php
// Shows the actual submissions on a given assignment by a given student so they can see which problems have been received.
require_once('DB.php');
require_once('../queryWebGrades.php');
$ClassName = $_GET['ClassName'];
$Teacher = $_GET['Teacher'];
$School = $_GET['School'];
$StartDate = $_GET['StartDate'];
$AssignmentFile = $_GET['AssignmentFile'];
$SecretNumber = $_POST['StudentNumber'];
$AssignmentNumber = $_POST['AssignmentNumber'];
$errorflag = 0;
function dumpSubmissions($SecretNumber, $AssignmentNumber, $AssignmentFile)
{ $L = file($AssignmentFile);
$StudentNumber = getStudentNumber($SecretNumber);
$found = false;
foreach ($L as $line)
{ $line = trim($line);
if(substr($line,0,2)=="//") continue; // a comment-only line
if($line == "") continue; // a blank line
$line = split("//", $line);
$line = $line[0]; // discard comments
// is this a line starting a new assignment?
$start = substr($line,0,3);
if($start == "Ass")
{ // yes, it does start a new assignment
$p = explode(":",$line);
$p1 = preg_split("/[\s]+/",trim($p[0])); // allowing multiple spaces as in "Assignment 5"
if( $AssignmentNumber = trim($p1[1]))
{ $found = true; // specified assignment found
break;
}
}
}
if($found == false)
echo "The specified assignment number does not exist.<br>";
$sql = "SELECT * FROM `Homework` WHERE StudentNumber='$StudentNumber';";
$result = QueryWebGrades($sql);
echo "<table border = \"2\">";
while($r=$result->fetchRow())
{ echo "<tr>"; foreach($r as $item) { echo "<td> $item </td>";} echo "</tr>"; }
echo "</table>";
}
/*__________________________________________________*/
function oldTopic($topic)
// Return the MathXpert32 topic number corresponding to the MathXpert64 topic number $topic
{ if($topic < 155)
return $topic + 5;
return $topic + 6;
}
/*__________________________________________________*/
function getStudentNumber($SecretNumber)
// the secret number is congruent to 17 mod 23
// but student numbers auto-increment from 0
// Do not change this scheme as it is built into WebGrades.php
{ return (int)( $SecretNumber / 23);
}
/*__________________________________________________*/
function getSecretNumber($StudentNumber)
{ return 23 * $StudentNumber + 17;
}
/*__________________________________________________*/
function getCourseID( $ClassName, $Teacher, $School, $StartDate )
{
$sql = "SELECT * FROM `Classes` WHERE ClassName='$ClassName' AND Teacher='$Teacher' AND School='$School' AND StartDate='$StartDate';";
$r = QueryWebGrades($sql);
$found = false;
$row = $r->fetchRow();
if($row==NULL)
{ return "Class not found. Check the data specified in the web page that contained the form you submitted";
}
else
return $row[0];
}
/*__________________________________________________*/
function displaySecretNumbers()
// for professor's use in setting up his or her spreadsheet
{
$sql = "SELECT * FROM `Students`";
$result = QueryWebGrades($sql);
echo "<table border=\"2\">";
while($r = $result->fetchRow())
{ $StudentNumber = $r[0];
$Email = $r[1];
$FirstName = $r[2];
$LastName = $r[3];
$SecretNumber = getSecretNumber($StudentNumber);
echo "<tr><td>$SecretNumber</td><td>$LastName, </td><td>$FirstName </td><td>$Email</td></tr>";
}
echo "</table>";
}
/*__________________________________________________*/
function getGrades( $ClassName, $Teacher, $School, $StartDate, $AssignmentFile)
// fills the global array $Grades where $Grades[$AssignmentNumber][$StudentNumber] is the percentage of problems on that assignment solved by that student.
// counting late submissions as half a submission
{ $CourseID = getCourseID($ClassName, $Teacher, $School, $StartDate);
$L = file($AssignmentFile); // read the assignment file into an array of lines
$count = 0;
// Construct an array $Assignments of arrays of strings, each entry containing two or more lines of $AssignmentFile defining one assignment.
global $AssignmentNumbers;
global $StudentNumbers;
global $errorflag;
global $LatePenalty;
global $RequiredNumbers;
global $NumberOfProblems;
global $DueDates;
$Assignments=array();
foreach ($L as $line)
{ $line = trim($line);
if(substr($line,0,2)=="//") continue; // a comment-only line
if($line == "") continue; // a blank line
$line = split("//", $line);
$line = $line[0]; // discard comments
// is this a line starting a new assignment?
$start = substr($line,0,3);
if($start == "Ass")
{ // yes, it does start a new assignment
$count++;
$Assignments[$count] = array();
$Assignments[$count][0] = $line;
}
else
{ $Assignments[$count][] = $line;
}
}
// Now process each assignment one at a time
foreach($Assignments as $A)
{ // get the assignment number and due date
$line = $A[0];
$p = explode(":",$line);
$p1 = preg_split("/[\s]+/",trim($p[0])); // allowing multiple spaces as in "Assignment 5"
$AssignmentNumber = trim($p1[1]); // it will be a number if the assignment file is correctly formatted.
// echo "AssignmentNumber is $AssignmentNumber now<br>";
if(isset($p[2]))
{ // there is a second colon as in "Assignment 3: due 2010-09-10 : 20"
$RequiredNumber = trim($p[2]);
if(is_numeric($RequiredNumber))
$RequiredNumbers[$AssignmentNumber] = trim($p[2]);
}
if(!isset($RequiredNumbers[$AssignmentNumber]))
$RequiredNumbers[$AssignmentNumber] = "all";
$AssignmentNumbers[] = $AssignmentNumber;
$DueDate = trim($p[1]); // it will be in format yyyy-mm-dd
if(substr($DueDate,0,3) == "due" || substr($DueDate,0,3) == "Due")
{ $x = preg_split("/[\s]+/", $DueDate);
$DueDate = trim($x[1]); // discard "due"
}
$DueDates[$AssignmentNumber] = $DueDate;
$flag = 0;
$sql = "";
$sql32 = "";
$countproblems = 0; // number of problems in this assignment
foreach($A as $S)
{ if($flag == 0)
$flag = 1; // ignore the first entry, which is the line beginning with "Assignment"
else
{ if($flag > 1)
$sql = $sql . " OR ";
else
$flag = 2;
$p = explode(":",$S);
$p[0] = trim($p[0]);
if(is_numeric($p[0]))
{ $Topic = $p[0];
$OldTopic = oldtopic($Topic);
$Filename = "";
$sql = $sql . "((Topic='$Topic' AND Filename='') OR (Topic='$OldTopic' AND NOT Filename='') AND (";
/* That code deals with the issue that MathXpert32 uses different topic numbers than MathXpert64,
so we accept problems with the 'wrong' topic number $OldTopic, which is the MathXpert32 topic number,
provided a filename is mentioned; in MathXpert64 the filename is empty.
*/
}
else
{ $Filename = $p[0];
$Topic = "";
$sql = $sql . "(Filename='$Filename' AND (";
}
$q = explode(",",$p[1]);
$count = 0; // count the entries of $q as processed
$savecountproblems = $countproblems;
foreach($q as $e)
{ $e = trim($e);
if($count > 0)
$sql = $sql . " OR ";
if(is_numeric($e))
{ $sql = $sql . "ProblemNumber='$e'";
++$countproblems;
}
else if (substr($e,0,4) == "even")
{ // as in "evens 2-40"
$R = explode("-", trim(substr($e,5)));
$first = trim($R[0]);
$second = trim($R[1]);
if(!is_numeric($first) || !is_numeric($second))
{ echo("error in assignment file in assignment number $AssignmentNumber");
echo "first is <br>$first<br> and second is <br>$second<br>";
$errorflag = 1;
}
else if(($first % 2) == 1 || ($second % 2) == 1)
{ $errorflag = 1;
echo("error in assignment file in assignment number $AssignmentNumber");
echo("After the word 'evens', expecting two even numbers separated by a hyphen.");
}
else
{ $countproblems += ($second - $first)/2 + 1;
$sql = $sql . "(ProblemNumber BETWEEN '$first' AND '$second' AND (ProblemNumber % 2) == 0)";
}
}
else if (substr($e,0,3) == "odd")
{ // as in "odds 1-41"
$R = explode("-", trim(substr($e,4)));
$first = trim($R[0]);
$second = trim($R[1]);
if(!is_numeric($first) || !is_numeric($second))
{ echo("error in assignment file in assignment number $AssignmentNumber");
echo "first is <br>$first<br> and second is <br>$second<br>";
$errorflag = 1;
}
else if(($first % 2) == 0 || ($second % 2) == 0)
{ $errorflag = 1;
echo("error in assignment file in assignment number $AssignmentNumber");
echo("After the word 'odds', expecting two odd numbers separated by a hyphen.");
}
else
{ $countproblems += ($second - $first)/2 + 1;
$sql = $sql . "(ProblemNumber BETWEEN '$first' AND '$second' AND (ProblemNumber % 2) == 1)";
}
}
else if (substr($e,0,3) == "all")
{ // as in "evens 2-40"
$R = trim(substr($e,3));
if(!is_numeric($R) )
{ echo("error in assignment file in assignment number $AssignmentNumber");
echo "Expecting a number after the word 'all'.";
$errorflag = 1;
}
else
{ $countproblems += $R;
$sql = $sql . "(ProblemNumber BETWEEN '$first' AND '$second' AND (ProblemNumber % 2) == 0)";
}
}
else
{ $R = explode("-",$e);
$first = trim($R[0]);
$second = trim($R[1]);
if(!is_numeric($first) || !is_numeric($second))
{ echo("error in assignment file in assignment number $AssignmentNumber");
echo "first is <br>$first<br> and second is <br>$second<br>";
$errorflag = 1;
}
else
{ $countproblems += $second - $first + 1;
$sql = $sql . "(ProblemNumber BETWEEN '$first' AND '$second')";
}
}
++$count;
} // end processing this entry
$sql = $sql . "))"; // close the parens opened 18 or 22 lines above here
} // end processing this line
} // finished reading this assignment
// echo("$sql <br>");
$NumberOfProblems[$AssignmentNumber] = $countproblems;
$sqlquery = "SELECT Homework.StudentNumber, ProblemNumber, Topic, Filename FROM `Homework`,`Enrolled` WHERE (" . $sql . ") AND SubmissionDate <= '$DueDate' AND '$StartDate' <= SubmissionDate AND Enrolled.StudentNumber=Homework.StudentNumber AND Enrolled.ClassID='$CourseID' ORDER BY Homework.StudentNumber;";
$sqllate = "SELECT Homework.StudentNumber, ProblemNumber, Topic, Filename FROM `Homework`,`Enrolled` WHERE (" . $sql . ") AND SubmissionDate > '$DueDate' AND '$StartDate' <= SubmissionDate AND Enrolled.StudentNumber=Homework.StudentNumber AND Enrolled.ClassID='$CourseID' ORDER BY Homework.StudentNumber;";
// echo("Constructed query:<br>$sqllate<br>");
$r = QueryWebGrades($sqlquery);
$rlate = QueryWebGrades($sqllate);
$problemsSolved = array();
$problemsSolvedLate = array();
$cnt = 0;
while($q = $r->fetchRow())
{ $problemsSolved[]=$q;
++$cnt;
}
// echo "$cnt on-time submissions for Assignment $AssignmentNumber <br>";
while($qlate = $rlate->fetchRow())
{ $problemsSolvedLate[] = $qlate;
}
// These data suffice for one column of the eventual table, but we still need percentages computed for each student.
$StudentNumber = 1;
$countsolutions = 0;
foreach($problemsSolved as $record)
{ if($record[0] != $StudentNumber)
{ // starting a new student, so record the grade of the student we just finished with
$percent = (int)((100 * $countsolutions)/ $countproblems + 0.5);
if($percent > 100)
$percent = 100; // initially there were some duplicate entries due to a bug in WebGrades.php, so we could get more than 100 percent.
$Grades[$AssignmentNumber][$StudentNumber] = $percent;
if($StudentNumber==200 && $AssignmentNumber==10) echo "percent on time is $percent";
if(!in_array($StudentNumber,$StudentNumbers))
{ $StudentNumbers[] = $StudentNumber;
}
$StudentNumber = $record[0];
$countsolutions = 0;
}
++$countsolutions;
}
// last student has still not been recorded
$percent = (int)((100 * $countsolutions)/ $countproblems + 0.5);
if($percent > 100)
$percent = 100; // initially there were some duplicate entries due to a bug in WebGrades.php, so we could get more than 100 percent.
$Grades[$AssignmentNumber][$StudentNumber] = $percent;
if(!in_array($StudentNumber,$StudentNumbers))
{ $StudentNumbers[] = $StudentNumber;
}
$StudentNumber = 1;
$countsolutions = 0;
foreach($problemsSolvedLate as $record)
{ if($record[0] != $StudentNumber)
{ // starting a new student, so record the late grades of the previous student.
$percent = (int)((100 * $countsolutions)/ $countproblems + 0.5);
if($percent > 100)
$percent = 100; // initially there were some duplicate entries due to a bug in WebGrades.php, so we could get more than 100 percent.
$percent = $LatePenalty * $percent; // late problems count less
if(!isset($Grades[$AssignmentNumber][$StudentNumber]))
$Grades[$AssignmentNumber][$StudentNumber] = 0;
$Grades[$AssignmentNumber][$StudentNumber] += (int)($percent + 0.5);;
if(!in_array($StudentNumber,$StudentNumbers))
{ $StudentNumbers[] = $StudentNumber;
}
$StudentNumber = $record[0];
$countsolutions = 0;
}
++$countsolutions;
}
// last student has still not been recorded
$percent = (int)((100 * $countsolutions)/ $countproblems + 0.5);
if($percent > 100)
$percent = 100; // initially there were some duplicate entries due to a bug in WebGrades.php, so we could get more than 100 percent.
$percent = $LatePenalty * $percent; // late problems count less
if(!isset($Grades[$AssignmentNumber][$StudentNumber]))
$Grades[$AssignmentNumber][$StudentNumber] = 0;
$Grades[$AssignmentNumber][$StudentNumber] +=(int)($percent + 0.5);
if(!in_array($StudentNumber,$StudentNumbers))
{ $StudentNumbers[] = $StudentNumber;
}
}
return $Grades;
}
/*__________________________________________________*/
function dumpRawGrades($SecretNumber)
// display all the submissions of one student
{ $StudentNumber = getStudentNumber($SecretNumber);
$sql = "SELECT * FROM `Homework` WHERE StudentNumber='$StudentNumber' ORDER BY SubmissionDate";
echo "Grades of student with secret number $SecretNumber and student number $StudentNumber <br>";
$r = QueryWebGrades($sql);
while( $row = $r->fetchRow())
{ foreach($row as $item)
{ echo "$item ";
}
echo "<br>";
}
}
/*__________________________________________________*/
function TestSubmitHomework($SecretNumber, $Filename, $Topic, $ProblemNumber)
// Store the given number in the webgrades database
// return 0 for success or 1 for invalid studentNumber
// or 2 if for some reason the database entry failed.
{ $SubmissionDate = date("Y-m-d"); // today's date in format 2010-08-13 (SQL wants that format for insertion)
$StudentNumber = (int) ($SecretNumber / 23); // secret numbers are congruent to 17 mod 23. StudentNumbers use all numbers starting at 1.
$sql = "SELECT * FROM `Homework` WHERE StudentNumber='$StudentNumber' AND Filename='$Filename' AND Topic='$Topic' AND ProblemNumber='$ProblemNumber';";
echo "$sql <br>";
$r = QueryWebGrades($sql);
if(is_string($r))
return 2;
$result = $r->fetchRow();
if($result==NULL) // it hasn't already been submitted
{ var_dump($result); echo "<br>";
$sql = "INSERT INTO `Homework` (Topic, Filename, SubmissionDate, StudentNumber, ProblemNumber) VALUES('$Topic','$Filename','$SubmissionDate','$StudentNumber','$ProblemNumber');";
$r=QueryWebGrades($sql); // insert this data into the database.
if(is_string($r))
return 2;
}
return 0; // If we get here, it succeeded
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Homework Grades</title>
</head>
<body>
<?php
dumpTable('Students');
dumpRawGrades(339);
$StudentNumbers = array();
$Grades = getGrades( $ClassName, $Teacher, $School, $StartDate, $AssignmentFile);
sort($StudentNumbers); // they may not be in order, e.g. if some students didn't submit the first assignment
// Now output the table
?>
<p>
The following table shows the percentages of problems submitted on time. </p>
<p>
Letter grades are not yet calculated. I will write code to calculate and display letter grades in the next few days, I hope.
In the meantime, this page will at least allow you to see that your submissions are being received. <br>
In case it was not required to do all the problems, a low percentage score might still correspond to an A grade. For example in Assignment 3, you only have to do 10 of 50 problems, so 20% will be an A.</p>
<table border="2">
<?php
// make a header row with the assignment numbers
echo "<tr>";
echo "<th bgcolor = '#FF0000'>Student \ Assignment</th>";
foreach($AssignmentNumbers as $AssignmentNumber)
echo "<th bgcolor = '#FF0000'>$AssignmentNumber</th>";
echo "</tr>";
// now make a row for each student
$rownumber = 0;
foreach($StudentNumbers as $StudentNumber)
{ $color = ($rownumber % 2 == 0) ? "#CCCCFF" : "#FFFFCC";
echo "<tr align='center' bgcolor='$color'>";
$SecretNumber = getSecretNumber($StudentNumber);
echo "<td> $SecretNumber </td>";
foreach($AssignmentNumbers as $AssignmentNumber)
{ $percent = $Grades[$AssignmentNumber][$StudentNumber];
echo "<td width=40> $percent </td>";
}
echo "</tr>";
}
?>
</table>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists