Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I wrote the code for my undergraduate TA jobs, to check assignment codes of students in Python class are correct or not.

Usage of the code is

$ python [test01.py[,test02 , ...] answer.dat grade.md

It will write grades (range 0~100) to a file called grade.md.

"""
Testing Assginments
by kidkkr
03-16-2017
"""

import os
import sys
from difflib import SequenceMatcher

class ResultChecker:
    """ Check python code result with answer data """
    __slots__ = '_srcFiles', '_ansFile', '_gradeFile', '_grade', '_ans'

    def __init__(self, srcFiles, ansFile, gradeFile):
        self._srcFiles = srcFiles 
        self._ansFile = ansFile 
        self._ans = open(self._ansFile, 'r').read()
        self._gradeFile = gradeFile
        self._grade = "# Grade File\n"

    def _run_code(self, src):
        print('-----------running ' + src + '..-----------')
        os.system('python ' + src + ' > result.swp')
        res = open('./result.swp', 'r').read()
        ratio = int(SequenceMatcher(None, res, self._ans).ratio() * 100)
        self._grade += src + ' ' + str(ratio) + '\n'
        print('result: ' + str(ratio))

    def check(self):
        for src in self._srcFiles:
            self._run_code(src)
        open(self._gradeFile, 'w').write(self._grade) # Write _grade to a file
        print('Checking has completed.')
        print(self._gradeFile + ":")
        print(self._grade)


def __main__():
    if len(sys.argv) < 2: # Check arguments
        raise ValueError('')

    srcFiles = sys.argv[1:-2]
    ansFile = sys.argv[-2]
    gradeFile = sys.argv[-1]

    ResultChecker(srcFiles, ansFile, gradeFile).check()


if __name__ == '__main__':
    __main__() 
share|improve this question
2  
Note that you should make sure you're being safe with untrusted scripts. Even if they're not malicious a student could break things that could cause future tests to fail or bigger problems. You should sandbox each run, either using something from here wiki.python.org/moin/Asking%20for%20Help/… or simply using a vm – Adam Martin 6 hours ago
up vote 5 down vote accepted

Here is something I would improve:

  • fix the variable naming - according to PEP8, use lower case and separate words with an underscore - e.g. _grade_file instead of _gradeFile
  • use argparse module instead of manually reading from sys.argv - you will get the auto-generated command-line help for free and it is generally more readable, structured and scalable. As a bonus, you may avoid checking the length of the sys.argv and reading the "files" into variables. Something along these lines:

    import argparse
    
    
    def parse_arguments():
        parser = argparse.ArgumentParser()
    
        parser.add_argument('--source-files', nargs="+", type=str)
        parser.add_argument('--answer-file', type=argparse.FileType('r'))
        parser.add_argument('--grade-file', type=argparse.FileType('w'))
    
        return parser.parse_args()
    

    Note the use of the special FileType argument type.

    And, because of the use of nargs="+", you should change the way you pass python file names - instead of a comma-separated list, use space:

    $ python --source-files test01.py test02.py --answer-file answer.dat --grade-file grade.md
    
  • use with context manager when opening files

  • try subprocess.Popen() instead of os.system() - with "popen" you may not need to temporarily write the result to a swap file and read the standard out and error directly
  • I understand that an underscore at the beginning of a variable name is a convention to mark "private variables", but, if the checker class would not be a part of a public-facing API, it would be okay to remove the underscores to improve on readability
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.