This commit is contained in:
Yadunand Prem
2022-09-29 17:29:07 +08:00
parent d8e797ae3a
commit e3a2b6a3b8
13 changed files with 649 additions and 0 deletions

76
Lab5/CS2030STest.java Normal file
View File

@@ -0,0 +1,76 @@
import java.net.URI;
import java.util.List;
import java.util.ArrayList;
import javax.tools.DiagnosticCollector;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class CS2030STest {
private static final String ANSI_RESET = "\u001B[0m";
private static final String ANSI_RED = "\u001B[31m";
private static final String ANSI_GREEN = "\u001B[32m";
public void expect(String test, Object output, Object expect) {
System.out.print(test);
if ((expect == null && output == null) || output.equals(expect)) {
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
} else {
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
System.out.println(" expected: " + expect);
System.out.println(" got this: " + output);
}
}
public static String clean(String txt) {
String res = "";
for (int i=0; i<txt.length(); i++) {
if (txt.charAt(i) != '\r' && txt.charAt(i) != '\n') {
res += txt.charAt(i);
}
}
return res;
}
public void expectPrint(String test, Object expect, ByteArrayOutputStream baos, PrintStream old) {
System.out.flush();
System.setOut(old);
expect(test, CS2030STest.clean(baos.toString()), expect);
}
public void expectCompile(String test, String statement, boolean success) {
System.out.print(test);
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String code) {
super(URI.create("string:///TempClass.java"), Kind.SOURCE);
this.code = "class TempClass {void foo(){" + code + ";}}";
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
boolean noError = ToolProvider
.getSystemJavaCompiler()
.getTask(null, null, new DiagnosticCollector<>(), null, null,
List.of(new JavaSourceFromString(statement)))
.call();
if (noError != success) {
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
if (!success) {
System.out.println(" expected compilation error but it compiles fine.");
} else {
System.out.println(" expected the statement to compile without errors but it does not.");
}
} else {
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
}
}
}

216
Lab5/Lab5.java Normal file
View File

@@ -0,0 +1,216 @@
import cs2030s.fp.Actually;
import cs2030s.fp.Immutator;
import cs2030s.fp.Constant;
import cs2030s.fp.Action;
import cs2030s.fp.Transformer;
import java.util.Map;
import java.util.HashMap;
import java.util.Scanner;
class Lab5 {
public static String getGrade(String module, String student, String assessment,
Map<String, Map<String, Map<String, String>>> db) {
try {
return db.get(module).get(student).get(assessment).toString();
} catch(Exception e) {
return "No such entry";
}
}
public static void main(String[] args) {
// Create a scanner to read from standard input.
Scanner sc = new Scanner(System.in);
// Read a single integer from the test file
// and then run the appropriate test case
switch (sc.nextInt()) {
case 1:
test1();
break;
case 2:
test2();
break;
case 3:
test3();
break;
case 4:
test4();
break;
case 5:
test5();
break;
case 6:
test6();
break;
}
}
public static void test1() {
String none = null;
System.out.println(Actually.err(new ArithmeticException("Err")).equals(Actually.err(new Exception("Err"))));
System.out.println(Actually.err(new ArithmeticException("Err")).equals(Actually.err(new Exception("Error"))));
System.out.println(Actually.err(new ArithmeticException("Err")).equals(Actually.err(new Exception(none))));
System.out.println(Actually.err(new ArithmeticException(none)).equals(Actually.err(new Exception(none))));
System.out.println(Actually.err(new ArithmeticException("Err")).equals(Actually.ok("Err")));
System.out.println(Actually.ok("Err").equals(Actually.ok("Err")));
System.out.println(Actually.ok("Err").equals(Actually.err(new Exception("Error"))));
System.out.println(Actually.ok("Err").equals("Err"));
System.out.println(Actually.ok(null).equals(Actually.ok("Err")));
System.out.println(Actually.ok(null).equals(Actually.ok(null)));
System.out.println(Actually.ok(null).equals("Err"));
System.out.println(Actually.ok(null).equals(null));
}
public static void test2() {
Constant<Integer> zero = new Constant<>() {
public Integer init() {
return 0;
}
};
Action<Integer> print = new Action<>() {
public void call(Integer i) {
System.out.println(i);
}
};
try {
Actually.<Number>ok(0).unwrap().toString();
} catch(Exception e) {
System.out.println(e.getMessage());
}
Actually.<Integer>ok(9).finish(print);
Actually.<Integer>err(new Exception("Err")).finish(print);
System.out.println(Actually.<Number>ok(9).except(zero).toString());
System.out.println(Actually.<Number>err(new ArithmeticException("div by 0")).except(zero).toString());
System.out.println(Actually.<Number>err(new ArithmeticException("div by 0")).unless(4).toString());
System.out.println(Actually.<Number>ok(0).unless(4).toString());
}
public static void test3() {
Immutator<Integer,Integer> inc = new Immutator<>() {
public Integer invoke(Integer p) {
return p+1;
}
};
Immutator<Integer,Integer> inv = new Immutator<>() {
public Integer invoke(Integer p) {
return 1/p;
}
};
Immutator<Number,Integer> incNum = new Immutator<>() {
public Number invoke(Integer p) {
return p+1;
}
};
Immutator<Number,Integer> invNum = new Immutator<>() {
public Number invoke(Integer p) {
return 1/p;
}
};
System.out.println(Actually.<Integer>ok(0).transform(inc).toString());
System.out.println(Actually.<Integer>ok(0).transform(inv).toString());
System.out.println(Actually.ok(0).transform(inc).toString());
System.out.println(Actually.ok(0).transform(inv).toString());
System.out.println(Actually.<Integer>ok(0).transform(incNum).toString());
System.out.println(Actually.<Integer>ok(0).transform(invNum).toString());
System.out.println(Actually.ok(0).transform(incNum).toString());
System.out.println(Actually.ok(0).transform(invNum).toString());
}
public static void test4() {
Transformer<Integer,Integer> inc = new Transformer<>() {
public Integer invoke(Integer p) {
return p+1;
}
};
Transformer<Integer,Integer> sqr = new Transformer<>() {
public Integer invoke(Integer p) {
return p*p;
}
};
Transformer<Integer,Integer> sqrPlusOneA = sqr.before(inc);
Transformer<Integer,Integer> sqrPlusOneB = inc.after(sqr);
Transformer<Integer,Integer> plusOneSqrA = sqr.after(inc);
Transformer<Integer,Integer> plusOneSqrB = inc.before(sqr);
System.out.println(sqrPlusOneA.invoke(2).toString());
System.out.println(sqrPlusOneA.invoke(2).toString());
System.out.println(plusOneSqrA.invoke(2).toString());
System.out.println(plusOneSqrB.invoke(2).toString());
}
public static void test5() {
Immutator<Actually<Integer>,Integer> half = new Immutator<>() {
public Actually<Integer> invoke(Integer p) {
if (p%2 == 0) {
return Actually.<Integer>ok(p/2);
} else {
return Actually.<Integer>err(new Exception("odd number"));
}
}
};
Immutator<Actually<Integer>,Integer> inc = new Immutator<>() {
public Actually<Integer> invoke(Integer p) {
return Actually.<Integer>ok(p+1);
}
};
Immutator<Actually<Integer>,Integer> make = new Immutator<>() {
public Actually<Integer> invoke(Integer p) {
return Actually.<Integer>ok(p);
}
};
Constant<Integer> zero = new Constant<>() {
public Integer init() {
return 0;
}
};
System.out.println(make.invoke(0).next(inc).next(inc).next(half).toString());
System.out.println(make.invoke(0).next(inc).next(half).next(inc).toString());
System.out.println(make.invoke(0).next(inc).next(inc).next(half).except(zero).toString());
System.out.println(make.invoke(0).next(inc).next(half).next(inc).except(zero).toString());
}
public static void test6() {
Map<String, Map<String, Map<String, String>>> nus =
Map.of(
"CS2030S", Map.of(
"Steve", Map.of(
"lab1", "A",
"lab2", "A-",
"lab3", "A+",
"lab4", "B",
"pe1", "C"
),
"Tony", Map.of(
"lab1", "C",
"lab2", "C",
"lab3", "B-",
"lab4", "B+",
"pe1", "A"
)
),
"CS2040S", Map.of(
"Steve", Map.of(
"lab1", "A",
"lab2", "A+",
"lab3", "A+",
"lab4", "A",
"midterm", "A+"
)
)
);
System.out.println(getGrade("CS2030S", "Steve", "lab1", nus));
System.out.println(getGrade("CS2030S", "Steve", "lab2", nus));
System.out.println(getGrade("CS2040S", "Steve", "lab3", nus));
System.out.println(getGrade("CS2040S", "Steve", "lab4", nus));
System.out.println(getGrade("CS2030S", "Tony", "lab1", nus));
System.out.println(getGrade("CS2030S", "Tony", "midterm", nus));
System.out.println(getGrade("CS2040S", "Tony", "lab4", nus));
System.out.println(getGrade("CS2040S", "Bruce", "lab4", nus));
}
}

BIN
Lab5/Lab5.pdf Normal file

Binary file not shown.

17
Lab5/Lab5.sh Normal file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
mkdir cs2030s
cd cs2030s
mkdir fp
cd ..
mv Action.java cs2030s/fp/Action.java
mv Actionable.java cs2030s/fp/Actionable.java
mv Actually.java cs2030s/fp/Actually.java
mv Constant.java cs2030s/fp/Constant.java
mv Immutator.java cs2030s/fp/Immutator.java
mv Immutatorable.java cs2030s/fp/Immutatorable.java
mv Transformer.java cs2030s/fp/Transformer.java
javac cs2030s/fp/*.java
javac *.java

24
Lab5/Test0.java Normal file
View File

@@ -0,0 +1,24 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class Test0 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
we.expectCompile("Actually<Object> a = new Actually<>() should not compile",
"cs2030s.fp.Actually<Object> a = new cs2030s.fp.Actually<>();", false);
we.expectCompile("Actually.Success<Object> s should not compile",
"cs2030s.fp.Actually.Success<Object> s;", false);
we.expectCompile("Actually.Failure f should not compile",
"cs2030s.fp.Actually.Failure f;", false);
we.expectCompile("Actually<String> success = Actually.ok(\"success\") should compile",
"cs2030s.fp.Actually<String> success = cs2030s.fp.Actually.ok(\"success\");", true);
we.expectCompile("Actually<Integer> none = Actually.ok(null) should compile",
"cs2030s.fp.Actually<Integer> none = cs2030s.fp.Actually.ok(null);", true);
we.expectCompile("Actually<Integer> four = Actually.ok(4) should compile",
"cs2030s.fp.Actually<Integer> four = cs2030s.fp.Actually.ok(4);", true);
we.expectCompile("Actually<Object> div0 = Actually.err(new ArithmeticException(\"Divide by 0\")) should compile",
"cs2030s.fp.Actually<Object> div0 = cs2030s.fp.Actually.err(new ArithmeticException(\"Divide by 0\"));", true);
}
}

73
Lab5/Test1.java Normal file
View File

@@ -0,0 +1,73 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class Test1 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
String none = null;
we.expect(
"Actually.err(new ArithmeticException(\"Err\")).equals(Actually.err(new Exception(\"Err\")))",
cs2030s.fp.Actually.err(new ArithmeticException("Err")).equals(cs2030s.fp.Actually.err(new Exception("Err"))),
true
);
we.expect(
"Actually.err(new ArithmeticException(\"Err\")).equals(Actually.err(new Exception(\"Error\")))",
cs2030s.fp.Actually.err(new ArithmeticException("Err")).equals(cs2030s.fp.Actually.err(new Exception("Error"))),
false
);
we.expect(
"Actually.err(new ArithmeticException(\"Err\")).equals(Actually.err(new Exception(null)))",
cs2030s.fp.Actually.err(new ArithmeticException("Err")).equals(cs2030s.fp.Actually.err(new Exception(none))),
false
);
we.expect(
"Actually.err(new ArithmeticException(null)).equals(Actually.err(new Exception(null)))",
cs2030s.fp.Actually.err(new ArithmeticException(none)).equals(cs2030s.fp.Actually.err(new Exception(none))),
false
);
we.expect(
"Actually.err(new ArithmeticException(\"Err\")).equals(Actually.ok(\"Err\"))",
cs2030s.fp.Actually.err(new ArithmeticException("Err")).equals(cs2030s.fp.Actually.ok("Err")),
false
);
we.expect(
"Actually.ok(\"Err\").equals(Actually.ok(\"Err\"))",
cs2030s.fp.Actually.ok("Err").equals(cs2030s.fp.Actually.ok("Err")),
true
);
we.expect(
"Actually.ok(\"Err\").equals(Actually.err(new Exception(\"Error\")))",
cs2030s.fp.Actually.ok("Err").equals(cs2030s.fp.Actually.err(new Exception("Error"))),
false
);
we.expect(
"Actually.ok(\"Err\").equals(\"Err\")",
cs2030s.fp.Actually.ok("Err").equals("Err"),
false
);
we.expect(
"Actually.ok(null).equals(Actually.ok(\"Err\"))",
cs2030s.fp.Actually.ok(null).equals(cs2030s.fp.Actually.ok("Err")),
false
);
we.expect(
"Actually.ok(null).equals(Actually.ok(null))",
cs2030s.fp.Actually.ok(null).equals(cs2030s.fp.Actually.ok(null)),
true
);
we.expect(
"Actually.ok(null).equals(\"Err\")",
cs2030s.fp.Actually.ok(null).equals("Err"),
false
);
we.expect(
"Actually.ok(null).equals(null)",
cs2030s.fp.Actually.ok(null).equals(null),
false
);
}
}

72
Lab5/Test2.java Normal file
View File

@@ -0,0 +1,72 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class Test2 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
PrintStream old = System.out;
ByteArrayOutputStream baos;
PrintStream ps;
cs2030s.fp.Constant<Integer> zero = new cs2030s.fp.Constant<>() {
public Integer init() {
return 0;
}
};
cs2030s.fp.Action<Integer> print = new cs2030s.fp.Action<>() {
public void call(Integer i) {
System.out.println(i);
}
};
try {
we.expect(
"Actually.<Number>ok(0).unwrap()",
cs2030s.fp.Actually.<Number>ok(0).unwrap().toString(),
"0"
);
} catch(Exception e) {
System.out.println("Unexpected error occurs");
}
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
cs2030s.fp.Actually.<Integer>ok(9).finish(print);
we.expectPrint("Actually.<Integer>ok(9).finish(print)",
"9",
baos,
old);
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
cs2030s.fp.Actually.<Integer>err(new Exception("Err")).finish(print);
we.expectPrint("Actually.<Integer>err(new Exception(\"Err\")).finish(print)",
"",
baos,
old);
we.expect(
"Actually.<Number>ok(9).except(zero)",
cs2030s.fp.Actually.<Number>ok(9).except(zero).toString(),
"9"
);
we.expect(
"Actually.<Number>err(new ArithmeticException(\"div by 0\")).except(zero)",
cs2030s.fp.Actually.<Number>err(new ArithmeticException("div by 0")).except(zero).toString(),
"0"
);
we.expect(
"Actually.<Number>err(new ArithmeticException(\"div by 0\")).unless(4)",
cs2030s.fp.Actually.<Number>err(new ArithmeticException("div by 0")).unless(4).toString(),
"4"
);
we.expect(
"Actually.<Number>ok(0).unless(4)",
cs2030s.fp.Actually.<Number>ok(0).unless(4).toString(),
"0"
);
}
}

71
Lab5/Test3.java Normal file
View File

@@ -0,0 +1,71 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class Test3 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
cs2030s.fp.Immutator<Integer,Integer> inc = new cs2030s.fp.Immutator<>() {
public Integer invoke(Integer p) {
return p+1;
}
};
cs2030s.fp.Immutator<Integer,Integer> inv = new cs2030s.fp.Immutator<>() {
public Integer invoke(Integer p) {
return 1/p;
}
};
cs2030s.fp.Immutator<Number,Integer> incNum = new cs2030s.fp.Immutator<>() {
public Number invoke(Integer p) {
return p+1;
}
};
cs2030s.fp.Immutator<Number,Integer> invNum = new cs2030s.fp.Immutator<>() {
public Number invoke(Integer p) {
return 1/p;
}
};
we.expect(
"Actually.<Integer>ok(0).transform(inc)",
cs2030s.fp.Actually.<Integer>ok(0).transform(inc).toString(),
"<1>"
);
we.expect(
"Actually.<Integer>ok(0).transform(inv)",
cs2030s.fp.Actually.<Integer>ok(0).transform(inv).toString(),
"[java.lang.ArithmeticException] / by zero"
);
we.expect(
"Actually.ok(0).transform(inc)",
cs2030s.fp.Actually.ok(0).transform(inc).toString(),
"<1>"
);
we.expect(
"Actually.ok(0).transform(inv)",
cs2030s.fp.Actually.ok(0).transform(inv).toString(),
"[java.lang.ArithmeticException] / by zero"
);
we.expect(
"Actually.<Integer>ok(0).transform(incNum)",
cs2030s.fp.Actually.<Integer>ok(0).transform(incNum).toString(),
"<1>"
);
we.expect(
"Actually.<Integer>ok(0).transform(invNum)",
cs2030s.fp.Actually.<Integer>ok(0).transform(invNum).toString(),
"[java.lang.ArithmeticException] / by zero"
);
we.expect(
"Actually.ok(0).transform(incNum)",
cs2030s.fp.Actually.ok(0).transform(incNum).toString(),
"<1>"
);
we.expect(
"Actually.ok(0).transform(invNum)",
cs2030s.fp.Actually.ok(0).transform(invNum).toString(),
"[java.lang.ArithmeticException] / by zero"
);
}
}

45
Lab5/Test4.java Normal file
View File

@@ -0,0 +1,45 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class Test4 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
cs2030s.fp.Transformer<Integer,Integer> inc = new cs2030s.fp.Transformer<>() {
public Integer invoke(Integer p) {
return p+1;
}
};
cs2030s.fp.Transformer<Integer,Integer> sqr = new cs2030s.fp.Transformer<>() {
public Integer invoke(Integer p) {
return p*p;
}
};
cs2030s.fp.Transformer<Integer,Integer> sqrPlusOneA = sqr.before(inc);
cs2030s.fp.Transformer<Integer,Integer> sqrPlusOneB = inc.after(sqr);
cs2030s.fp.Transformer<Integer,Integer> plusOneSqrA = sqr.after(inc);
cs2030s.fp.Transformer<Integer,Integer> plusOneSqrB = inc.before(sqr);
we.expect(
"sqrPlusOneA.invoke(2)",
sqrPlusOneA.invoke(2).toString(),
"5"
);
we.expect(
"sqrPlusOneB.invoke(2)",
sqrPlusOneA.invoke(2).toString(),
"5"
);
we.expect(
"plusOneSqrA.invoke(2)",
plusOneSqrA.invoke(2).toString(),
"9"
);
we.expect(
"plusOneSqrB.invoke(2)",
plusOneSqrB.invoke(2).toString(),
"9"
);
}
}

55
Lab5/Test5.java Normal file
View File

@@ -0,0 +1,55 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
public class Test5 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
cs2030s.fp.Immutator<cs2030s.fp.Actually<Integer>,Integer> half = new cs2030s.fp.Immutator<>() {
public cs2030s.fp.Actually<Integer> invoke(Integer p) {
if (p%2 == 0) {
return cs2030s.fp.Actually.<Integer>ok(p/2);
} else {
return cs2030s.fp.Actually.<Integer>err(new Exception("odd number"));
}
}
};
cs2030s.fp.Immutator<cs2030s.fp.Actually<Integer>,Integer> inc = new cs2030s.fp.Immutator<>() {
public cs2030s.fp.Actually<Integer> invoke(Integer p) {
return cs2030s.fp.Actually.<Integer>ok(p+1);
}
};
cs2030s.fp.Immutator<cs2030s.fp.Actually<Integer>,Integer> make = new cs2030s.fp.Immutator<>() {
public cs2030s.fp.Actually<Integer> invoke(Integer p) {
return cs2030s.fp.Actually.<Integer>ok(p);
}
};
cs2030s.fp.Constant<Integer> zero = new cs2030s.fp.Constant<>() {
public Integer init() {
return 0;
}
};
we.expect(
"make.invoke(0).next(inc).next(inc).next(half)",
make.invoke(0).next(inc).next(inc).next(half).toString(),
"<1>"
);
we.expect(
"make.invoke(0).next(inc).next(half).next(inc)",
make.invoke(0).next(inc).next(half).next(inc).toString(),
"[java.lang.Exception] odd number"
);
we.expect(
"make.invoke(0).next(inc).next(inc).next(half).except(zero)",
make.invoke(0).next(inc).next(inc).next(half).except(zero).toString(),
"1"
);
we.expect(
"make.invoke(0).next(inc).next(half).next(inc).except(zero)",
make.invoke(0).next(inc).next(half).next(inc).except(zero).toString(),
"0"
);
}
}

View File

View File

View File