93 lines
4.5 KiB
Python
93 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
import os
|
|
from collections import defaultdict
|
|
|
|
import cakecms
|
|
|
|
HOST = 'https://cms.cispa.saarland'
|
|
TOKEN = os.environ['CMS_TOKEN']
|
|
TEMPFILE = '/tmp/cms.json'
|
|
|
|
cms = cakecms.CakeCMS(HOST, TOKEN)
|
|
# [optional] log queries to console
|
|
#cms.debug = True
|
|
# get a course list (dictionary)
|
|
|
|
if os.path.exists(TEMPFILE):
|
|
# read data from cached file
|
|
with open(TEMPFILE, 'r') as f:
|
|
data = json.loads(f.read())
|
|
cysec1_courses = data['cysec1_courses']
|
|
security_courses = data['security_courses']
|
|
advanced_lectures = data['advanced_lectures']
|
|
cysec1_students = set(data['cysec1_students'])
|
|
security_students = set(data['security_students'])
|
|
advanced_lecture_students = {k: set(v) for k, v in data['advanced_lecture_students'].items()}
|
|
else:
|
|
# read data from CMS
|
|
courses = cms.courses_index()
|
|
cysec1_courses = [course for course in courses if course['Course']['name'].strip() in ('Grundlagen der Cybersicherheit 1', 'Foundations of Cybersecurity 1')]
|
|
security_courses = [course for course in courses if course['Course']['name'].strip() == 'Security']
|
|
advanced_lectures = [course for course in courses if course['Course']['course_type'] == 'Advanced Lecture']
|
|
|
|
print('Cysec1:', [c['Course']['shortname'] for c in cysec1_courses])
|
|
print('Security:', [c['Course']['shortname'] for c in security_courses])
|
|
print('Advanced Lectures:', [c['Course']['shortname'] for c in advanced_lectures])
|
|
|
|
cysec1_students = set() # set of matriculations
|
|
for course in cysec1_courses:
|
|
studis = cms.students_index(course=course['Course']['shortname'])['students']
|
|
cysec1_students |= set(student['Student']['matriculation'] for student in studis)
|
|
|
|
security_students = set() # excluding cysec students
|
|
for course in security_courses:
|
|
studis = cms.students_index(course=course['Course']['shortname'])['students']
|
|
security_students |= set(student['Student']['matriculation'] for student in studis if student['Student']['subject'] not in ('Cybersicherheit', 'Entrepreneurial Cybersecurity'))
|
|
|
|
advanced_lecture_students = defaultdict(set) # lecture name -> set of matriculations
|
|
for course in advanced_lectures:
|
|
studis = cms.students_index(course=course['Course']['shortname'])['students']
|
|
advanced_lecture_students[course['Course']['name']] |= set(student['Student']['matriculation'] for student in studis)
|
|
with open(TEMPFILE, 'w') as f:
|
|
f.write(json.dumps({
|
|
'cysec1_courses': cysec1_courses,
|
|
'security_courses': security_courses,
|
|
'advanced_lectures': advanced_lectures,
|
|
'cysec1_students': list(cysec1_students),
|
|
'security_students': list(security_students),
|
|
'advanced_lecture_students': {k: list(v) for k, v in advanced_lecture_students.items()},
|
|
}))
|
|
|
|
# do your data analysis here!
|
|
print('Cybersecurity 1 (all iterations) :', len(cysec1_students), 'students')
|
|
print('Security (all iterations) :', len(security_students), 'students that do not study cybersecurity')
|
|
print('Cybersecurity 1 /\\ Security :', len(security_students & cysec1_students), 'students')
|
|
print('-'*60)
|
|
for lecture, matriculations in advanced_lecture_students.items():
|
|
print(f'{lecture:40s}: {len(matriculations)} students')
|
|
|
|
print('-'*60)
|
|
cysec_students_without_advanced_lecture = set(cysec1_students)
|
|
security_students_without_advanced_lecture = set(security_students)
|
|
for lec in advanced_lecture_students.values():
|
|
cysec_students_without_advanced_lecture -= lec
|
|
security_students_without_advanced_lecture -= lec
|
|
print(len(cysec_students_without_advanced_lecture), 'cysec1 students did not attend any advanced lecture')
|
|
print(len(security_students_without_advanced_lecture), 'security students did not attend any advanced lecture')
|
|
|
|
#count advanced lectures per student
|
|
for name, basic_set in [('cysec1', cysec1_students), ('security', security_students)]:
|
|
print('-'*60)
|
|
matriculation_to_advanced_count = {m: 0 for m in basic_set}
|
|
for students in advanced_lecture_students.values():
|
|
for m in students:
|
|
if m in matriculation_to_advanced_count:
|
|
matriculation_to_advanced_count[m] += 1
|
|
# statistics
|
|
cysec_advanced_count = defaultdict(lambda: 0)
|
|
for m, count in matriculation_to_advanced_count.items():
|
|
cysec_advanced_count[count] += 1
|
|
for count, num_students in sorted(cysec_advanced_count.items(), key=lambda a: a[0]):
|
|
print(f'{num_students:3d} {name} students took >> {count:2d} << advanced lectures')
|