程序辅助评分
1. 构造学生的文件路径
读取/etc/passwd
文件,对班级内所有学生依次构造出源文件和可执行文件路径,关键代码如下:
with open('/etc/passwd', 'r') as f:
for line in f.readlines():
l = line.strip().split(':')
username = l[0]
uid = int(l[2])
gid = int(l[3])
user_info = l[4]
home_dir = l[5]
if gid == 201112:
class_id, student_id, chinese_name = user_info.split('-')
## empty source file
filename = os.path.join(home_dir, 'os_exp/exp4_sync_pv/process_synchronization_pv.c')
original_filename = '/home/qiankun/os_exp/exp4_sync_pv/process_synchronization_pv.c'
filename2 = os.path.join(home_dir, 'os_exp/exp4_sync_pv/semaphore.h')
original_filename2 = '/home/qiankun/os_exp/exp4_sync_pv/semaphore.h'
program = os.path.join(home_dir, 'os_exp/exp4_sync_pv/process_synchronization_pv')
2. 辅助评分
对于文件大小没有任何改变,没有可执行文件,直接判定为零分,代码如下:
if os.stat(filename).st_size == os.stat(original_filename).st_size and \
os.stat(filename2).st_size == os.stat(original_filename2).st_size:
lists.append([class_id, student_id, chinese_name, 0, 'Nothing added'])
continue
try:
output = subprocess.check_output([program], stderr=subprocess.STDOUT)
# If returncode is non-zero, raise a CalledProcessError.
except OSError as e:
if e.errno == 2:
lists.append([class_id, student_id, chinese_name, 0, 'no executable file'])
continue
接着。运行用户的可执行程序,将程序输出结果与正确结果相比较,以进程同步的实验为例,子进程先运行,子进程输出的父进程ID应该与父进程输出的进程ID相等,关键代码如下:
output = subprocess.check_output([program], stderr=subprocess.STDOUT)
# run correct
try:
l = output.strip().decode().split()
if l[1] == l[2]:
lists.append([class_id, student_id, chinese_name, 10, 'Match'])
else:
lists.append([class_id, student_id, chinese_name, 0, 'Wrong output: {}'.format(output)])
except Exception as e:
lists.append([class_id, student_id, chinese_name, 0, str(e)])
完整的代码见get_scores_exp4.py。