From 136fd34a42e93d22efd41114acfa726a03a2ca6e Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Sun, 16 Jan 2022 17:39:47 +0800 Subject: =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD--=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E4=B8=80=E4=B8=AAexclude.txt=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=94=BE=E5=85=A5=E7=BB=9F=E8=AE=A1=E6=97=B6=E4=B8=8D?= =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=8C=85=E6=8B=AC=E7=9A=84=E5=AD=A6=E5=8F=B7?= =?UTF-8?q?=E3=80=82=E6=AF=8F=E8=A1=8C=E4=B8=80=E4=B8=AA=E5=AD=A6=E5=8F=B7?= =?UTF-8?q?=E3=80=82=E5=91=BD=E4=BB=A4=E8=A1=8C=E4=B8=8D=E5=8F=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- analyze.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/analyze.py b/analyze.py index 778d5d2..6f95e8f 100644 --- a/analyze.py +++ b/analyze.py @@ -12,6 +12,11 @@ # - tasks.json: a plain text file in JSON format specifying the course objectives and tasks in this course. # Each task is associated to at least one course objective (co). Each co in a task has an associated weight. # Make sure that all weights across tasks sum to 100. +# Optional files: +# +# - exclude.txt: a plain text file specifying a list of student numbers (one per line) which we do not want to include +# while computing the course objective fulfillment percentage. +# # # # Limitations: @@ -35,7 +40,7 @@ # could break down the task into several sub-tasks such that each # sub-task corresponds to only one course objective. # -# Copyright (C) 2019, 2020 Hui Lan +# Copyright (C) 2019, 2020, 2021 Hui Lan # # Contact the author if you encounter any problems: Hui Lan @@ -204,12 +209,36 @@ def check_availability(fname): sys.exit() +def remove_a_student(student_lst, s): + ''' student_lst is a list of tuples, each tuple in the form like (student_no, student_name). + s is a student number. Effect: student_lst shortened. + ''' + index = 0 + for x in student_lst: + sno = x[0] + if sno == s: + student_lst.pop(index) + return None + index += 1 + + +def all_gone(student_lst, lst): + ''' Return True iff none of the student number in lst is in student_lst''' + for x in student_lst: + sno = x[0] + if sno in lst: + return False + return True + + + # main GRADE_DIR = 'grade' TASK_FILE = 'tasks.json' # required file containing course objectives and tasks. check_availability(TASK_FILE) STUDENT_FILE = 'students.txt' # required file containing student numbers and student names. check_availability(STUDENT_FILE) +EXCLUDE_FILE = 'exclude.txt' GRADE_FILE = 'grade_file.xls' # output software_information = 'Course Objective Fulfillment Calculator\nCopyright (C) 2019 Hui Lan (lanhui@zjnu.edu.cn)' n = max([len(s) for s in software_information.split('\n')]) @@ -219,6 +248,7 @@ print(banner) task_dict = get_task_information(TASK_FILE) student_lst = get_student_information(STUDENT_FILE) make_individual_grade_files(GRADE_DIR, task_dict, student_lst) +print('Seen %d students.' % (len(student_lst))) # output results to terminal and file head_lst = ['student.no', 'student.name'] @@ -233,6 +263,23 @@ course_object_cumulative_score = {} for co in task_dict['course.objectives']: course_object_cumulative_score[co] = 0 +# Exclude some students from student list student_lst. The excluded students are specified in a file called exclude.txt. +if os.path.exists(EXCLUDE_FILE): + lst = [] + print('Read excluded students from %s.' % (EXCLUDE_FILE)) + with open(EXCLUDE_FILE) as f: + for line in f: + line = line.strip() + if line != '': + lst.append(line) + for s in lst: + print('Do not count %s' % (s)) + remove_a_student(student_lst, s) + assert all_gone(student_lst, lst) == True + print('Still have %d students after excluding the undesired students specified in %s.' % (len(student_lst), EXCLUDE_FILE)) + + +# Do statistics for s in student_lst: sno = s[0] sname = s[1] -- cgit v1.2.1