Skip to content

Instantly share code, notes, and snippets.

@simonsmiley
Last active August 29, 2015 14:20
Show Gist options
  • Save simonsmiley/e1fa14421ccfa89a375f to your computer and use it in GitHub Desktop.
Save simonsmiley/e1fa14421ccfa89a375f to your computer and use it in GitHub Desktop.
Programs for correcting students exercises Add new snippet
#!/bin/env python3
import os
import hashlib
def hashfile(afile, hasher, blocksize=65536):
buf = afile.read(blocksize)
while len(buf) > 0:
hasher.update(buf)
buf = afile.read(blocksize)
return hasher.digest()
## read the directory updating all files the students turned in
def read_directory():
path = os.getcwd()
filePaths = []
root = [x[0] for x in os.walk(path)]
dirs = [x[1] for x in os.walk(path)][0]
files = [x[2] for x in os.walk(path)]
del files[0]
del root[0]
for i in range(len(dirs)):
if dirs[i] == '__pycache__':
continue
for f in files[i]:
filePaths.append(os.path.join(root[i],f))
return filePaths
def check_hashes(files):
hashes = dict()
for f in files:
hashValue = hashfile(open(f, 'rb'), hashlib.md5())
if hashValue in hashes:
print("%s !!! %s" %(hashes[hashValue], f))
else:
hashes[hashValue] = f
def get_file_types(files):
types = set()
for f in files:
types.add(f.split('.')[-1])
for t in types:
print(t)
def main():
files = read_directory()
print('file types found:')
get_file_types(files)
print('hash collisions:')
check_hashes(files)
if __name__ == "__main__":
main()
#!/bin/env python3
import os
import sys
import subprocess
## global storage for student records, the path for the csv and the currently opened file
STUDENTS = []
PATH_TO_CSV = os.path.join(os.getcwd(), 'points.csv')
OPEN_FILE = None
SAVE_AFTER_NO_CORRECTIONS = 5 # use negative value to disable
## for storing students data
class Student:
def __init__(self, identifier):
self.identifier = identifier
self.points = '---'
self.comment = ''
self.filepaths = []
def set_points(self, points):
self.points = points
def append_file(self, filepath):
self.filepaths.append(filepath)
def __str__(self):
return "%s;%s;%s\n" % (self.identifier, self.points, self.comment)
def add_comment(self, comment):
self.comment = comment.replace(';', '-')
## read the directory updating all files the students turned in
def read_directory():
global STUDENTS
path = os.getcwd()
root = [x[0] for x in os.walk(path)]
dirs = [x[1] for x in os.walk(path)][0]
files = [x[2] for x in os.walk(path)]
del files[0]
del root[0]
for i in range(len(dirs)):
if dirs[i] == '__pycache__':
continue
s = Student(dirs[i])
for f in files[i]:
s.append_file(os.path.join(root[i],f))
STUDENTS.append(s)
STUDENTS= sorted(STUDENTS, key=lambda student: student.identifier)
## read the csv file updating students records
def read_csv_file():
global STUDENTS
csv_file = open(PATH_TO_CSV, 'r')
counter = 0
notifiy = False
for line in csv_file:
student = STUDENTS[counter]
data = line.split(';')
if data[0] == student.identifier:
student.set_points(data[1])
student.add_comment(data[2].rstrip())
else:
notifiy = True
counter += 1
if notifiy:
print('The csv does NOT match the downloads, aborting')
sys.exit(-1)
## dump all students into the csv
def dump_csv():
csv_file = open(PATH_TO_CSV, 'w')
for student in STUDENTS:
csv_file.write("%s" % student)
csv_file.close()
## opens files the students turned in, this the only OS dependent part, feel free to change it
def open_file(filepath):
global OPEN_FILE
if filepath[-3:].lower() == 'pdf':
OPEN_FILE = subprocess.Popen(['zathura', filepath], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
return True
return False
## start correcting one student
def correct_student(index):
global STUDENTS
global OPEN_FILE
student = STUDENTS[index]
print('Correcting student no. %d' % index)
file_to_open = ''
if len(student.filepaths) > 1:
for i in range(len(student.filepaths)):
print('%d: %s' % (i, student.filepaths[i]))
choosen_file = ''
while True:
try:
usr_input = input('Which file do you want to open?')
if usr_input == 'q':
return False
choosen_file = int(usr_input)
if choosen_file >= 0 and choosen_file < len(student.filepaths):
break
except ValueError:
pass
print('You have to input a valid number!')
file_to_open = student.filepaths[choosen_file]
else:
file_to_open = student.filepaths[0]
if not open_file(file_to_open):
student.points = '---'
student.add_comment('files could not be opened')
return True
while True:
try:
usr_input = input('Input the number of points:')
if usr_input == 'q':
return False
elif usr_input == '-':
if OPEN_FILE is not None:
OPEN_FILE.kill()
return True
points = int(usr_input)
if points >= 0:
student.set_points(points)
comment = input('If you want you can add a comment:\n')
if comment != '':
student.add_comment(comment)
if OPEN_FILE is not None:
OPEN_FILE.kill()
return True
except ValueError:
pass
print('You have to input a valid number!')
## updates the csv and exits
def save_and_exit():
global OPEN_FILE
if OPEN_FILE is not None:
OPEN_FILE.kill()
dump_csv()
sys.exit(0)
## start correcting
## you can choose a number to start with and the walk to the end :-)
## any student where the points entry in the csv is not '---' will be skipped!
## 'q' will exit the program
def correct():
global STUDENTS
starting_id = ''
while True:
starting_id = input('Enter the id to start with (0-%d):' % (len(STUDENTS) - 1))
try:
starting_id = int(starting_id)
break
except ValueError:
if starting_id == 'q':
save_and_exit()
print('wrong input, try again')
counter = 0
for i in range(starting_id, len(STUDENTS)):
if STUDENTS[i].points != '---':
continue
if not correct_student(i):
save_and_exit()
counter += 1
if SAVE_AFTER_NO_CORRECTIONS == counter:
dump_csv()
counter = 0
print('You reached the last student, saving and exiting')
save_and_exit()
def main():
read_directory()
read_csv_file()
correct()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment