Skip to content

Instantly share code, notes, and snippets.

@gluxon
Last active January 22, 2018 18:23
Show Gist options
  • Save gluxon/8c01acc39d8037b214fc35f4bbb48b0e to your computer and use it in GitHub Desktop.
Save gluxon/8c01acc39d8037b214fc35f4bbb48b0e to your computer and use it in GitHub Desktop.
scheme-testing.md
  1. Select Custom Test Case for Test Case Type
  2. Paste the following bash script. Modify testFunction, testArguments, and testAssertion appropriately.
testFunction="inc"
testArguments="0"
testAssertion="(ref-approx-=? student reference 0.001)"
# Optional extra message, could be used to display info about the test case
testMessage="\"\""

# Get first file with .rkt extension.
studentAnswersFile="$(ls | grep ".rkt" | head -n 1)"
stdinToGenericTester="\"$studentAnswersFile\"\n$testFunction\n(list $testArguments)\n$testMessage\n(lambda (student reference) $testAssertion)\n"
RESULT=`echo -e $stdinToGenericTester | plt-r5rs genericTester.scm 2>> DEBUG`
# Treat the last line of the output as a fake exit status
EXITSTATUS=`echo "$RESULT" | tail -n 1`

# every student has to include the pledge in their code
pledge="I confirm that my submitted solutions are the result of my own intellectual effort, and comply with the 1729 honor code and the UConn standards for academic integrity"
# Check if pledge appears in stends answer file
if grep -q "$pledge" $studentAnswersFile ; then
  if [ $EXITSTATUS = "#t" ] ; then
    echo "true" > OUTPUT
  else
    echo "false" > OUTPUT
  fi
else
  echo "Error: Statement to uphold 1729 honor code was not found." >> DEBUG
  echo "false"> OUTPUT
fi
  1. Upload two files: genericTester.scm and referenceSolution.scm. A copy of genericTester.scm can be found below. referenceSolution.scm should be the perfect solution.
; Generic scheme function output comparison
; (Last modified 1/17/18)
;
; This file attempts to automate test running. To use it, zip it with the
; perfect code "referenceSolution.scm" and upload to Mimir.

(define (testEntry)
  (define student-answers-file (read (current-input-port)))
  (define test-function (read (current-input-port)))
  (define test-arguments (read (current-input-port)))
  (define test-extra-message (read (current-input-port)))
  (display "Testing function: " (current-error-port))
  (display test-function (current-error-port))
  (display "\n" (current-error-port))
  (if (not (eq? test-extra-message ""))
      (begin (display test-extra-message (current-error-port))
             (display "\n" (current-error-port))))
  ; Load student solution and grab their answer
  (load student-answers-file)
  (define student-out
    (apply (eval test-function (interaction-environment))
           (eval test-arguments (interaction-environment))))

  ; Load our solution and grab our answer.
  (load "referenceSolution.scm")
  (define reference-out
    (apply (eval test-function (interaction-environment))
           (eval test-arguments (interaction-environment))))

  ; test-assertion should be a lambda we can pass student-out and reference-out
  ; to. Ex: "(lambda (student reference) (< (abs (- student reference)) 0.0001))
  (define test-assertion (read (current-input-port)))

  (newline) ; ensure only #t or #f is the last line
  (display ((eval test-assertion (interaction-environment)) student-out reference-out))
  (newline))

(define (ref-bool-equal? a b)
  ; tests whether a and b have same truth value
  ; double negation forces true thing to be #t
  ; useful for boolean functions
  (not (not (or (and a b)(and (not a)(not b))))))

(define (ref-approx-=? a b tol)
  ; tests whether a is within tol of b
  ; a, b, and tol are numbers
  ; useful for floats
  (< (abs (- a b)) tol))

(define (ref-general-equal? x y)  ;; works for numbers, strings, symbols, lists
  (cond ((eq? x y) #t)
        ((and (number? x)(number? y))
        (= x y))
        ((and (string? x)(string? y))
         (string=? x y))
        ((and (pair? x)(pair? y))
         (and (ref-general-equal? (car x)(car y))
              (ref-general-equal? (cdr x)(cdr y))))
        (else
         #f)))

(define (ref-general-member? x y)
  (cond ((null? y) #f)
        ((ref-general-equal? x (car y))
         #t)
        (else
         (ref-general-member? x (cdr y)))))

(define (ref-remove-one x lst)
   (cond ((null? lst) lst)
         ((ref-general-equal? x (car lst))
          (cdr lst))
         (else
          (cons (car lst)(ref-remove-one x (cdr lst))))))

(define (ref-permutation? x y)
  (cond ((null? x)(null? y))
        ((null? y) #f)
        ((ref-general-member? (car x) y)
         (ref-permutation? (cdr x)(ref-remove-one (car x) y)))
        (else #f)))

(testEntry)

;; some useful (?) comparison functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment