Last active
August 29, 2015 14:20
-
-
Save simonsmiley/e1fa14421ccfa89a375f to your computer and use it in GitHub Desktop.
Programs for correcting students exercises Add new snippet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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