Using Python to grade a C program

This is a Python script that can be used to grade C code. It parses through the code to look for keywords using regular expressions for matching. This script would be called from an Advanced Code Test and it is set up to return partial points.

import os, requests, random, re, io, subprocess, shutil, sys
from subprocess import Popen, PIPE, STDOUT

sys.path.append('/usr/share/codio/assessments')
from lib.grade import send_partial_v2, FORMAT_V2_MD, FORMAT_V2_HTML, FORMAT_V2_TXT

score = 0
feedback = ""

## check function of code using output - keyboard flag to indicate input type
def check_output_c(file, input, keyboard=False):

  file_no_ext = os.path.splitext(file)[0]
  compile_cmd = "g++ " + file + " -o " + file_no_ext
  if keyboard:
    subprocess.Popen(compile_cmd, shell=True)
    #https://stackoverflow.com/questions/33976094/subprocess-stdin-input
    p = Popen(['./'+file_no_ext], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
    student_output = p.communicate(input=str.encode(input))[0]
  else:
    subprocess.Popen(compile_cmd, shell=True)
    student_output = subprocess.check_output(['./'+file_no_ext]).rstrip()

  return student_output.decode("utf-8").strip()       

  
## Run the student code and return the output
result = check_output_c('code/assignment2q2.c',"10",True)

if result != None:
  if re.search('0\s+3\s+6\s+9\s*',result):
    score+=4
    feedback+="You have all the correct elements in your code\n"
  else:
    feedback+="You do not have all the correct elements in your code\n"
else:
  feedback+="Your code did not execute\n"



# get student code
  
with open('code/assignment2q2.c') as response:
  answer = response.read()

#check student code
if 'for' in answer:
  feedback+="Correct for loop implementation.\n"
  score+=3
if 'scanf' in answer:
  feedback+="Correct scanf implementation.\n"
  score+=3
else:
  feedback+="Incorrect implementation.\n"


feedback+= "<h2>On this question you earned " + str(score) + " out of 10</h2>"
possible = 10
percent = (score/possible)*100
res = send_partial_v2(percent, feedback, FORMAT_V2_HTML)
exit(0 if res else 1)
1 Like