import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.util.Date; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Test class for Hardy * * @author Michael Mrozek * Created Nov 27, 2007. */ public class TestHardy { private static final class Test { private final int n,answer,a1,a2,b1,b2,points; /** * @param n * @param answer Correct answer * @param points Points this test is worth */ public Test(int n,int answer,int a1,int a2,int b1,int b2,int points) { this.n=n; this.answer=answer; this.a1=a1; this.a2=a2; this.b1=b1; this.b2=b2; this.points=points; } /** * @return N */ public int getN() {return this.n;} /** * @return The points this test is worth */ public int getPoints() {return this.points;} /** * @param answer Student answer * @return True if the student's answer is correct */ public boolean checkAnswer(int answer,int a1,int a2,int b1,int b2) {return this.answer==answer && this.a1==a1 && this.a2==a2 && this.b1==b1 && this.b2==b2;} } private static final String PATH="/class/cs/csse220/200820/turnin/%/Hardy/extract"; private static final int TIMEOUT=20000; private static final Pattern pattern=Pattern.compile("([0-9]*) = ([0-9]*)\\^3 \\+ ([0-9]*)\\^3 = ([0-9]*)\\^3 \\+ ([0-9]*)\\^3"); private static final Test[] TESTS=new Test[] { // N c a1 a2 b1 b2 points new Test(1, 1729, 1, 12, 9, 10, 20), new Test(5, 32832, 4, 32, 18, 30, 15), new Test(20, 262656, 8, 64, 36, 60, 15), new Test(50, 1092728, 1, 103, 64, 94, 10), new Test(100, 4673088, 25, 167, 64, 164, 4), new Test(200, 16387189, 5, 254, 197, 206, 3), new Test(500, 106243219, 307, 426, 363, 388, 3), }; /** * @param args One argument for student username */ @SuppressWarnings("deprecation") public static void main(String[] args) { final String username=args[0]; final FileWriter resultsFile; try { resultsFile=new FileWriter(new File(PATH.replace("%",username)+"/Results.txt")); } catch(IOException e) { System.out.println("Unable to write the results file"); return; } //This print stream outputs to the console and the Results file at once, so the user can see the script's progress as it runs final PrintStream out=new PrintStream(new OutputStream() { @Override public void write(int b) throws IOException { System.out.write(b); resultsFile.write(b); } }); out.println(username+" - Summary for Hardy"); out.println("Graded on "+new Date()); out.println(); //Widths: 4 7 out.println("N Points Your Answer"); int total=0,earned=0; try { for(Test test : TESTS) { final Process p=Runtime.getRuntime().exec("java -cp "+PATH.replace("%",username)+" Hardy"); final String[] answer=new String[1]; final PrintWriter processOut=new PrintWriter(p.getOutputStream()); processOut.println(test.getN()); processOut.flush(); processOut.close(); //Any of the three threads can finish to continue execution final ThreadGroup threads=new ThreadGroup("Test Threads"); Thread studentOutput=new Thread(threads,new Runnable() { public void run() { final Scanner in=new Scanner(p.getInputStream()); while(!in.hasNextLine()) {/* Wait for student output */} answer[0]=in.nextLine(); in.close(); } }); studentOutput.start(); Thread studentError=new Thread(threads,new Runnable() { public void run() { final Scanner err=new Scanner(p.getErrorStream()); while(!err.hasNextLine()) {/* Wait for student error */} final String error=err.nextLine(); if(answer[0]==null) {answer[0]=error;} err.close(); } }); studentError.start(); Thread timeout=new Thread(threads,new Runnable() { public void run() { try { Thread.sleep(TIMEOUT); } catch(InterruptedException e) {/* Interrupted */} if(answer[0]==null) {answer[0]="[timeout]";} } }); timeout.start(); while(threads.activeCount()==3) {/* Wait for one thread to finish */} threads.stop(); //None of the threads have semaphore problems, so this is fine Matcher m=pattern.matcher(answer[0]); final int points=test.getPoints(); total+=points; if(m.matches()) { final int c=Integer.parseInt(m.group(1)); final int a1=Integer.parseInt(m.group(2)); final int a2=Integer.parseInt(m.group(3)); final int b1=Integer.parseInt(m.group(4)); final int b2=Integer.parseInt(m.group(5)); final boolean correct=test.checkAnswer(c,a1,a2,b1,b2); out.format("%-4s %2s/%-2s %s\n",test.getN(),correct ? points : 0,points,answer[0]); if(correct) {earned+=points;} } else { out.format("%-4s %2s/%-2s %s\n",test.getN(),0,points,answer[0]==null ? "Invalid output format; should be c = a1^2 + a2^2 = b1^2 + b2^2" : answer[0]); } p.destroy(); } } catch(IOException e) { out.println("IOException in student code"); e.printStackTrace(); } out.println(); out.println("Points earned: "+earned+"/"+total); try { resultsFile.flush(); resultsFile.close(); } catch(IOException e) {/* Nothing we can do */} } }