diff --git a/checker/comprog b/checker/comprog index 2715d50..0e0effa 100755 --- a/checker/comprog +++ b/checker/comprog @@ -23,7 +23,7 @@ case _"$LANG" in ;; _Cpp) - g++ -std=c++11 -g -o prog $@ + g++ -std=c++17 -Wall -Wno-sign-compare -g -o prog $@ ;; _Scala) @@ -53,6 +53,7 @@ case _"$LANG" in ;; _) - echo Unknown language $LANG + echo Unknown language $LANG + exit 1 ;; esac diff --git a/checker/src/com/horstmann/codecheck/Comparison.java b/checker/src/com/horstmann/codecheck/Comparison.java index 0669ea7..a340cab 100644 --- a/checker/src/com/horstmann/codecheck/Comparison.java +++ b/checker/src/com/horstmann/codecheck/Comparison.java @@ -12,7 +12,9 @@ public class Comparison { private static final int MANY_MORE_LINES = 10; // If actual lines > expected + MANY_MORE_LINES, truncate actual output - public boolean execute(String actual, String expected, Report report, String filename) throws IOException { + public boolean execute(String input, String actual, String expected, Report report, String filename) throws IOException { + // TODO: This is where the newlines went to die + List lines1 = getLines(actual.replace("〉\n", "〉")); List lines2 = getLines(expected.replace("〉\n", "〉")); @@ -36,6 +38,8 @@ public boolean execute(String actual, String expected, Report report, String fil } } else { + // Print inputs which are getting replaced + report.input(input); while (i < lines2.size()) { Report.Match m = new Report.Match(); m.actual = ""; @@ -62,7 +66,6 @@ public boolean execute(String actual, String expected, Report report, String fil m.explanation = null; matches.add(m); } - // TODO: Report needs to deal with 〈...〉 (replace with ...\n) report.compareTokens(filename, matches); } return outcome; diff --git a/checker/src/com/horstmann/codecheck/CppLanguage.java b/checker/src/com/horstmann/codecheck/CppLanguage.java index 6131a4c..d07dc34 100644 --- a/checker/src/com/horstmann/codecheck/CppLanguage.java +++ b/checker/src/com/horstmann/codecheck/CppLanguage.java @@ -79,7 +79,7 @@ public List writeTester(Path solutionDir, Path workDir, Path file, lines.add(i++, extern); // extern function from solution } lines.add(i++, "}"); - lines.add(i++, "main(int argc, char *argv[]) {"); + lines.add(i++, "int main(int argc, char *argv[]) {"); // We declare the student functions locally in main so that they don't conflict with // solution functions for (String extern : externs) { @@ -94,6 +94,7 @@ public List writeTester(Path solutionDir, Path workDir, Path file, // compare expected and actual lines.add(i++, "}"); } + lines.add(i++, " return 0;"); lines.add(i++, "}"); lines.add(i++, "namespace solution {"); lines.add("}"); diff --git a/checker/src/com/horstmann/codecheck/HTMLReport.java b/checker/src/com/horstmann/codecheck/HTMLReport.java index 2246391..253b164 100644 --- a/checker/src/com/horstmann/codecheck/HTMLReport.java +++ b/checker/src/com/horstmann/codecheck/HTMLReport.java @@ -486,8 +486,8 @@ public HTMLReport pass(boolean b) { @Override public HTMLReport compareTokens(String filename, List matchData) { caption(filename); - tableStart("output").rowStart().headerCell("Actual output") - .headerCell("Expected output").rowEnd().rowStart(); + tableStart("output").rowStart().headerCell("Actual") + .headerCell("Expected").rowEnd().rowStart(); builder.append(""); builder.append("
");
         for (Match m : matchData) {
diff --git a/checker/src/com/horstmann/codecheck/JavaScriptLanguage.java b/checker/src/com/horstmann/codecheck/JavaScriptLanguage.java
index b4ecae2..fa83d4c 100644
--- a/checker/src/com/horstmann/codecheck/JavaScriptLanguage.java
+++ b/checker/src/com/horstmann/codecheck/JavaScriptLanguage.java
@@ -4,9 +4,7 @@
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
diff --git a/checker/src/com/horstmann/codecheck/Main.java b/checker/src/com/horstmann/codecheck/Main.java
index 367eb99..199beda 100644
--- a/checker/src/com/horstmann/codecheck/Main.java
+++ b/checker/src/com/horstmann/codecheck/Main.java
@@ -285,7 +285,7 @@ private void testInput(Path mainFile,
                     // Report output but don't grade it
                     report.output(outerr);
                 } else {
-                    boolean outcome = comp.execute(outerr, expectedOuterr, report, null);
+                    boolean outcome = comp.execute(input, outerr, expectedOuterr, report, null);
                     score.pass(outcome, report);
                 }
             }        
@@ -304,7 +304,7 @@ private void testInput(Path mainFile,
                     score.pass(outcome, report);                   
                 } else {
                     String expectedContents = Util.read(p);                
-                    boolean outcome = comp.execute(contents.remove(0),
+                    boolean outcome = comp.execute(input, contents.remove(0),
                             expectedContents, report, f);
                     score.pass(outcome, report);
                 }
diff --git a/checker/src/com/horstmann/codecheck/PythonLanguage.java b/checker/src/com/horstmann/codecheck/PythonLanguage.java
index 219dcdd..4b435a0 100644
--- a/checker/src/com/horstmann/codecheck/PythonLanguage.java
+++ b/checker/src/com/horstmann/codecheck/PythonLanguage.java
@@ -10,8 +10,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import com.horstmann.codecheck.Language.Interleave;
-
 public class PythonLanguage implements Language {
 
     public PythonLanguage() {
diff --git a/checker/src/com/horstmann/codecheck/SMLLanguage.java b/checker/src/com/horstmann/codecheck/SMLLanguage.java
index 5d4243a..483d325 100644
--- a/checker/src/com/horstmann/codecheck/SMLLanguage.java
+++ b/checker/src/com/horstmann/codecheck/SMLLanguage.java
@@ -5,7 +5,6 @@
 import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Scanner;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
diff --git a/checker/src/com/horstmann/codecheck/codecheck.h b/checker/src/com/horstmann/codecheck/codecheck.h
index 3f155b0..2822fae 100644
--- a/checker/src/com/horstmann/codecheck/codecheck.h
+++ b/checker/src/com/horstmann/codecheck/codecheck.h
@@ -24,7 +24,7 @@ namespace codecheck {
    template void print(std::vector xs) { 
       std::cout << "{"; 
       for (int i = 0; i < xs.size(); i++) {
-         if (i > 0) std::cout << ","; std::cout << " ";
+         if (i > 0) { std::cout << ","; } std::cout << " ";
          print(xs[i]);
       }
       std::cout << " }";
@@ -43,4 +43,4 @@ namespace codecheck {
       print(y); std::cout << std::endl;
       std::cout << std::boolalpha << eq(x, y) << std::endl;
    }
-}
\ No newline at end of file
+}
diff --git a/todo.txt b/todo.txt
index 7d264ff..1317cab 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,4 +1,379 @@
-=CodeCheck
+awsweex /assets/receiveMessage.js
+
+sbt -jvm-debug 9999 -Dcom.horstmann.codecheck.s3credentials=/data/cay/projects/codecheck-legacy/instances/s3.properties run
+
+firefox file:///home/cay/projects/play-codecheck/ltitest/index.html
+
+gcloud compute ssh staging --zone us-central1-b
+
+=============================
+
+
+DynamoDB
+
+arn:aws:dynamodb:us-west-1:686205121574:table/CodeCheckWork
+
+Need to make a policy
+
+{
+    "Version": "2012-10-17",
+    "Statement": [
+        {
+            "Sid": "CodeCheckDynamoAccess",
+            "Effect": "Allow",
+            "Action": [
+                "dynamodb:PutItem",
+                "dynamodb:UpdateItem",
+                "dynamodb:DeleteItem",
+                "dynamodb:BatchWriteItem",
+                "dynamodb:GetItem",
+                "dynamodb:BatchGetItem",
+                "dynamodb:Scan",
+                "dynamodb:Query",
+                "dynamodb:ConditionCheckItem"
+            ],
+            "Resource": [
+                "arn:aws:dynamodb:us-west-1:686205121574:table/CodeCheck*",
+                "arn:aws:dynamodb:us-west-1:686205121574:table/CodeCheck*/index/*"
+            ]
+        }        
+    ]
+}
+
+
+rm -rf /tmp/work
+mkdir /tmp/work
+cd /tmp/work
+for f in $(aws s3 ls --recursive work.code-check.org | awk '{print $4}') ; do aws s3 cp s3://work.code-check.org/$f $f ; done
+
+for f in $(ls) ; do for g in $(ls $f) ; do for h in $(ls ${f}/${g}) ; do cat $f/$g/$h | jq "{ problems: del(.submittedAt, .ccid), submittedAt: .submittedAt, assignmentID: \"${f}\", workID: \"${g}/${h}\" }" > $f/$g/$h.json ; done ; done ; done
+
+# I had to patch /usr/local/lib/node_modules/dynamodb-data-types/bin/wrap.js
+# const ddt = require('../lib/dynamodb-data-types')
+# ddt.preserveArrays()
+# const attr = ddt.AttributeValue;
+
+for f in */*/*.json ; do echo $f ; aws dynamodb put-item --table-name CodeCheckWork --item "$(dynamo-dt-attr-wrap "$(cat $f)")" ; done
+
+
+
+
+
+TODO: Make use of Submissions instead of/in addition to Work table
+
+work() or launch()
+saveWork()
+viewSubmissions() and for LTI viewSubmission()
+
+work and launch query
+  context
+  assignment 
+  problem
+  submitter
+  deadline
+Get latest item before deadline
+
+Therefore, want to support viewSubmissions, which has input
+  context
+  assignment 
+  problem 
+  deadline
+  and yields: all submitters and their latest submissions
+
+primary key = context + assignment + problem
+sort key = submitter + submissionTime
+
+begins with submitter, <= submitter + deadline
+
+
+
+=========================================
+Security
+
+TODO Harden against tampering with interactives/send scores directly from CC
+
+TODO: JWT for authorization instead of !@#% session cookie
+https://en.wikipedia.org/wiki/JSON_Web_Token
+https://dzone.com/articles/jwt-authentication-with-play-framework
+
+SuperTokens https://supertokens.io/
+
+=======================================================================
+Non LTI
+
+TODO: For CS046 (or in general), could make it so that the "Download work" part works without registration. Does it go to the server for signing? 
+
+TODO: Download report. Jarsigner. Name it id-date.zip or id-assignment.zip for easy submission.
+
+TODO: REST API
+
+TODO: Why not param: { state: ..., score: ... }
+  If we want that, must adapt workAssignment.js, receiveMessage.js, codecheck.js
+
+TODO: Sort table in viewSubmissions https://www.willmaster.com/library/features/sorting-a-table-with-javascript.php
+
+TODO This is better than postMessage
+https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API/Using_channel_messaging
+
+TODO: Hide links in problem text when they can't be useful
+  (or make them more useful by sending message to parent?)
+
+Other ways to submit
+  To Google Sheet: http://codesmith.in/post-data-google-drive-sheet-through-mobile-app/
+  BlueJ Submitter Extension: https://bluej.org/extensions/submitter/submitter.html
+
+What about xAPI https://xapi.com/statements-101/
+
+TODO: Time zone new Date().getTimezoneOffset()
+Intl.DateTimeFormat().resolvedOptions().timeZone
+Toggle between your time and UTC?
+
+=======================================================================
+
+LTI provider
+
+Right now, editing problems created inside LMS hides the deadline. Is that what we want?
+
+TODO: Ask for inclusion in https://canvas.instructure.com/courses/2062633
+
+TODO: Unsatisfactory clone state in viewAssignment. Would be nice if URLs could be copied into LTI. Maybe ?role=Instructor which is ignored in LTI post? 
+
+TODO: https://github.com/IMSGlobal/basiclti-util-java/blob/master/src/test/java/org/imsglobal/lti/BasicLTIUtilTest.java
+
+=======================================================================
+
+LTI consumer
+
+When sending score/state, also cause server to send score as XML to lis_outcome_service_url (TODO: unless the lis_outcome_service_url is with CodeCheck)
+
+TODO: JWT
+
+TODO: Consistent spelling of lis_outcome_service_url etc
+
+		    // TODO: What about CodeCheck qids?
+
+
+What about docHeight?
+
+// TODO: Now the CodeCheck client will do the LTI communication. CodeCheck should do it.
+
+
+TODO: No point in expanding zip file on disk (problemPath)
+
+TODO: Would be nice for an instructor in LTI to see the per-problem work for all students
+
+
+=======================================================================
+
+Course
+
+For reusing assignments in coming semester, need notion of course. null course if none given.
+
+Concept 1: Course knows its assignments
+
+Course has assignments
+
+Name     Deadline     URL   [View submissions]  [Delete]
+
+
+Trash [Empty]
+
+Name     Deadline     URL   [View submissions]  [Undelete]
+
+
+Existing assignments are cloned into course
+New assignments have same edit key as course (course owner owns assignments)
+
+Can download all submissions in course
+
+Can clone entire course
+
+Concept 2: Course is simply a tag
+
+&tag=... for submissions, filter by tag
+
+
+
+
+
+=======================================================================
+
+Elements
+
+* horstmann_codecheck might as well get the file data if they don't currently exist. Just do this in JavaScript:
+               String fileData = new String(url.openStream().readAllBytes(), StandardCharsets.UTF_8);
+               String replacement = "
\n"; + + + +* horstmann_vitalsource (which is part of horstmann_all_min) defines + + horstmann_config.score_change_listener + horstmann_config.retrieve_state + + This should be moved to horstmann_common if not VS specific + + -> EPUB.Education.retrieve + -> postMessage retrieve + -> message retrieve + -> callback from nonceMap + +* Make it possible to copy the ID +https://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript, https://developer.mozilla.org/en-US/docs/Web/API/Element/auxclick_event + +* Compare protocol with https://github.com/acos-server/acos-server/blob/master/doc/development.md + +* Use client UI for interactivities.ws/makews script; in general, try to use client UI + +* You are right about the vertical lines. They shouldn't appear when the solved problem is restored. I fixed that in my code, + +* With MC, hide answer at outset + +* Long-term want proof that students have the book. Make them solve a trivial problem and store unlock code as the problem state + +* Example table enhancement if the solution has \n, provide a text area. Make it possible to not have Start button. If no entries in third column, show the first two at 50%. + + +========================================= +Docker + +Think of queue implementation once we have Docker + + +Dockerfile +JDK 8 image +Make second layer with our stuff +Third layer??? + +Now with a server + +Server must get problem zip (because we don't want any security inside, do that in Play), student JSON (all file content), and input (in run mode) + +Like checkNJS but with the zip base64-encoded (for now) + +Returning completableFuture +http://heidloff.net/article/developing-reactive-rest-apis-with-quarkus/ + +Seems the best entrypoint to Quarkus because there is no UI involved + + + +For now, gave up on checker-only Docker. Docker contains Play server. + +Instead of apparmor: chroot? But a non-root user doesn't have access to any root resources anyway +https://help.ubuntu.com/community/BasicChroot +Firejail? https://firejail.wordpress.com/ + +Killold upon invocation instead of cron + +docker build --tag codecheck:1.0 . +docker run -p 9000:9000 -it codecheck:1.0 + +docker ps (only running) +docker ps -a (running and stopped) +docker stop +docker kill +docker rm +Shell into container: docker exec -it /bin/bash +Prune all stopped containers: docker system prune + +TODO: Note that codecheck.env needs JDK 11 JAVA_HOME +Had to remove + # EXEC_CONTROL="cgexec -g cpu:codecheck --sticky nice -15" + EXEC_CONTROL="" +in codecheck--needs fix since it won't survive rebuild + + +Deployment at Google + +https://cloud.google.com/run/docs/setup + + + +What about secrets? https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets#secretmanager-access-secret-version-java + +(B) CodeCheck 20.04, gcinstall0, gcinstall, build, build.xml, codecheck.policy, runprog.apparmor, better scaling (containers?), //CFLAGS?, show warnings + + + +Podman? +https://developers.redhat.com/blog/2019/02/21/podman-and-buildah-for-docker-users/ +https://martinheinz.dev/blog/35?utm_source=tds&utm_medium=referral&utm_campaign=blog_post_35 + + +========================================= +Quarkus + +Quarkus fascicles in ~/Dropbox/ebooks/javaee +https://smallrye.io/ + +Or https://micronaut.io/ + +(B) Quarkus with CodeCheck, https://blogs.oracle.com/javamagazine/getting-started-with-kubernetes, https://cs50.readthedocs.io/, https://medium.com/google-cloud/serverless-computing-with-pascal-d7a16633db44 + + +https://de2.slideshare.net/isabelbaum/consolibmwebcastquarkusthebluehedgehogofjavawebframeworks?qid=a0824831-8b7b-4753-9800-f2001d647cdd&v=&b=&from_search=3 +https://github.com/ConSol/ibm-quarkus + +========================================= +GraalVM + + Security manager not supported + Java program needs to be run with separate java task (and sec.mgr.) + Reflective loading of report, language + Not clear how to pass Java properties -- as env properties instead? + Must take out Runner.java and change main class in manifest + /data/apps/graalvm-ce-java11-20.2.0/bin/native-image -cp /opt/codecheck/lib/\* --native-image-info --verbose -H:ConfigurationFileDirectories=conf-dir -H:+ReportExceptionStackTraces -H:+StackTrace -H:NativeLinkerOption=/data/apps/graalvm-ce-java11-20.2.0/lib/static/linux-amd64/glibc/libprefs.a --no-server --no-fallback -jar codecheck.jar + + All of those things would also have to be done when moving code to Quarkus + +https://blogs.oracle.com/developers/building-cross-platform-native-images-with-graalvm +https://jamesward.com/2020/05/07/graalvm-native-image-tips-tricks/ + +========================================== +Parsons Problems + +//TILE + +makes each line a tile, except includes following { + +//GOOD +moves to the left + +//BAD code +Adds to the distractors of the preceding line (unless at the end) + +Anything before the first //TILE is implicitly GOOD + +Parsing yields a data structure +{ left: [ GOOD strings ], right: [ strings or [ correct/distractors ]] } + +The items on the right are delivered scrambled, and so are the groups of correct/distractors + + + +========================================= +CodeCheck + +(B) Why don't we see the checkbox and paperclip in http://horstmann.com/sjsu/cs046/lesson6_1-14.html +(B) CodeCheck tab width in Ace editor, make it not convert spaces to tabs +(B) What are the tests??? http://codecheck.it/files?repo=jfe1cc&problem=ch04/c04_exp_4_104 +(B) Switch ~/web/com/sjsu/cs046/*.ch to min for obscurity, clean private/app + + +Brilliant idea: Make timeout relative to reference solution time, rather than absolute. (With % or x suffix, default 300/3x) Give a caution when submitting a slow reference solution + +Disable submit button (if not already done) + +Tyler's websocket stuff + +Try Codemirror--it can have read-only areas + +https://www.linuxjournal.com/content/simulate-typing-c-program If interleaveio is inherently unstable, may need to run without, compare result, and then run with for visual representation @@ -140,8 +515,6 @@ ivy grep -l test.run=true ~/codecheck/*/*/*/*/check.properties -Firejail: https://firejail.wordpress.com/ - AppArmor @@ -175,6 +548,9 @@ sudo aa-logprof Checker ======= +Currently with C++ problems, .h files are not syntax highlighted in the editor like .cpp file. That would be nice. (https://github.com/cayhorstmann/play-codecheck/issues/1) + + Bug in /home/cay/projects/codecheck/checker/../samples/python/test5: Shouldn't run two tests @@ -424,3 +800,22 @@ Problem with main Don't want main for regular work, but then how to recognize main file? Need main for CALL to feed arg 1 2 3 etc. Don't want main for test-engine/racket-tests + +============================= + +Related projects + +https://cscircles.cemc.uwaterloo.ca + Extensive Python question bank +https://open.kattis.com/ + For interview training or employers +https://www.autogradr.com/ + For universities. Got nice note from founder Tushar Soni when I signed up +https://github.com/MimirHQ/opencs1 + OER problem sets: +https://www.executeprogram.com/ + Commercial ($19/month) practice +https://codehs.com/info/platform/assignments + Commercial assignment system for high schools +https://www.onlinegdb.com/ + Online debugger