From 8c3037f0ad5ea805ffbec901ac5085d5b7b28712 Mon Sep 17 00:00:00 2001 From: Vaibhav Sinha Date: Thu, 6 Jun 2019 23:57:02 +0530 Subject: [PATCH] Diff float (#71) * Diff float * diff work modification * Changes for comments * Change test_script.sh to test_script * Move difffloat.py * Fix environment setting in Docker image * Cleanup * Changes to comment --- content/Dockerfile | 12 ++++--- content/main_tester.sh | 8 ++--- judge/default/examples/difffloat.py | 49 +++++++++++++++++++++++++++++ judge/default/test_script.sh | 26 +++++++-------- judge/handler.py | 4 +-- judge/models.py | 3 +- 6 files changed, 76 insertions(+), 26 deletions(-) create mode 100644 judge/default/examples/difffloat.py diff --git a/content/Dockerfile b/content/Dockerfile index 82fbcd1..80aba89 100644 --- a/content/Dockerfile +++ b/content/Dockerfile @@ -19,19 +19,21 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Install golang for Go RUN apt-get update && apt-get install -y --no-install-recommends \ golang && \ - echo 'export GOPATH=${HOME}/go' >> ~/.bashrc && \ - echo 'export PATH=${PATH}:${GOPATH}/bin' >> ~/.bashrc && \ - source ~/.bashrc && \ rm -rf /var/lib/apt/lists/* +# Set the PATH variables after golang install +ENV GOPATH=${HOME}/go +ENV PATH=${PATH}:${GOPATH}/bin + # Install ghc for Haskell RUN add-apt-repository -y ppa:hvr/ghc && \ apt-get update && apt-get install -y --no-install-recommends \ ghc-8.6.5 && \ - echo 'export PATH=${PATH}:/opt/ghc/bin/' >> ~/.bashrc && \ - source ~/.bashrc && \ rm -rf /var/lib/apt/lists/* +# Set the PATH variables after ghc install +ENV PATH=${PATH}:/opt/ghc/bin + ### TIMER_TOOL SUPPORT BELOW # Install dependencies for timer_tool (a.k.a. runsolver) diff --git a/content/main_tester.sh b/content/main_tester.sh index a04bb0f..be2da02 100755 --- a/content/main_tester.sh +++ b/content/main_tester.sh @@ -51,9 +51,6 @@ shift MEMLIMIT=$1 shift -# Effectively importing the testing function : validate_submission_output() -. ${PROB_FDR}/${PROB_CODE}/test_script.sh - # Run submission function # If the executable runs fine, then the output validation is done # Otherwise, an appropriate error code is returned @@ -94,7 +91,7 @@ run_submission() { case "$?" in "0") - validate_submission_output ${TEST_FDR}/outputfile_${TID}.txt ${TMP}/sub_output_${SID}_${TID}.txt + ./${PROB_FDR}/${PROB_CODE}/test_script ${TEST_FDR}/outputfile_${TID}.txt ${TMP}/sub_output_${SID}_${TID}.txt > /dev/null VERDICT=$(error_code_to_string $? ${TID}) ;; "1") @@ -149,6 +146,9 @@ error_code_to_string() { echo "$TESTCASE_ID $STRCODE" } +# Add executable permission +chmod +x ${PROB_FDR}/${PROB_CODE}/test_script + # Iterate over all testcase IDs passed as command line arguments for TESTCASE_ID in "$@"; do diff --git a/judge/default/examples/difffloat.py b/judge/default/examples/difffloat.py new file mode 100644 index 0000000..7b06ee0 --- /dev/null +++ b/judge/default/examples/difffloat.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 + +import sys + +PASS = 0 +FAIL = 1 +NA = 5 + + +def wa_exit(): + sys.exit(FAIL) + + +# Call the progarm by difffloat.py testcaseoutput.txt producedoutput.txt +if len(sys.argv) != 3: + print('Incorrect number of arguments') + sys.exit(NA) + +testcasefile = open(sys.argv[1], 'r') +outputfile = open(sys.argv[2], 'r') + +testcaselines = [] +try: + for line in testcasefile.readlines(): + testcaselines.append([float(x) for x in line.strip().split()]) +except ValueError: + print('Non convertible to float') + wa_exit() + +print(testcaselines) +try: + for i, line in enumerate(outputfile.readlines()): + float_line = [float(x) for x in line.strip().split()] + if i >= len(testcaselines) or len(testcaselines[i]) != len(float_line): + print('Different number of lines or number of values on some line') + wa_exit() + for j, vapprox in enumerate(float_line): + if abs(1 - (vapprox / testcaselines[i][j])) > 1e-6: + # Test for relative error + # See https://en.wikipedia.org/wiki/Approximation_error + print('Wrong value') + wa_exit() +except ValueError: + print('Non convertible to float') + wa_exit() + +# Correct answer +print('Correct answer') +sys.exit(PASS) diff --git a/judge/default/test_script.sh b/judge/default/test_script.sh index 653c1c5..c1aac05 100644 --- a/judge/default/test_script.sh +++ b/judge/default/test_script.sh @@ -9,18 +9,16 @@ NA=5 # If the output "passes" the requirements, then # return $PASS, otherwise return $FAIL # Any technical glitch returns $NA -validate_submission_output() { - diff $1 $2 > /dev/null +diff -b -Z $1 $2 > /dev/null - case "$?" in - "0") - return $PASS - ;; - "1") - return $FAIL - ;; - *) - return $NA - ;; - esac -} +case "$?" in + "0") + return $PASS + ;; + "1") + return $FAIL + ;; + *) + return $NA + ;; +esac diff --git a/judge/handler.py b/judge/handler.py index 3341ed9..659d446 100644 --- a/judge/handler.py +++ b/judge/handler.py @@ -144,8 +144,8 @@ def process_problem(code: str, contest: int, name: str, statement: str, input_fo if no_test_script: # Copy the default test_script if the user did not upload custom copyfile(os.path.join('judge', 'default', 'test_script.sh'), - os.path.join('content', 'problems', p.code, 'test_script.sh')) - p.test_script = os.path.join('content', 'problems', p.code, 'test_script.sh') + os.path.join('content', 'problems', p.code, 'test_script')) + p.test_script = os.path.join('content', 'problems', p.code, 'test_script') # In this case, either one of compilation_script or test_script hasn't been copied # and saving with update the link(s) diff --git a/judge/models.py b/judge/models.py index 9ee6c80..976478b 100644 --- a/judge/models.py +++ b/judge/models.py @@ -14,7 +14,8 @@ def start_code_name(instance, filename): def compilation_test_upload_location(instance, filename, is_compilation): # We disregard the filename argument file_prefix = 'compilation' if is_compilation else 'test' - file_name = '{}_script.sh'.format(file_prefix) + file_extension = '.sh' if is_compilation else '' + file_name = '{}_script{}'.format(file_prefix, file_extension) return 'content/problems/{}/{}'.format(instance.code, file_name)