def test_normal_gpa(): transcript = trns() area = AreaOfStudy.load(c=c, transcript=transcript, specification={ 'name': 'test', 'type': 'concentration', 'result': { 'all': [ { 'requirement': 'compsci' }, { 'requirement': 'art' }, ], }, 'requirements': { 'compsci': { 'result': { 'from': 'courses', 'where': { 'subject': { '$eq': 'CSCI' } }, 'assert': { 'count(courses)': { '$gte': 2 } }, } }, 'art': { 'result': { 'from': 'courses', 'where': { 'subject': { '$eq': 'ART' } }, 'assert': { 'count(courses)': { '$gte': 1 } }, }, }, }, }) solution = list( area.solutions(transcript=transcript, areas=[], exceptions=[]))[0] result = solution.audit() assert set(result.matched()) == set(transcript) assert result.gpa() == Decimal('2.0')
def test_audit__double_history_and_studio(): student: Dict[str, Any] = { 'areas': [ AreaPointer( code='140', status=AreaStatus.Declared, kind=AreaType.Major, name='Studio Art', degree='B.A.', dept='ART', gpa=None, ), AreaPointer( code='135', status=AreaStatus.Declared, kind=AreaType.Major, name='Art History', degree='B.A.', dept='ART', gpa=None, ), ], 'courses': [ course_from_str('DEPT 123'), ], } c = Constants(matriculation_year=2000) area = AreaOfStudy.load(c=c, areas=student['areas'], transcript=student['courses'], specification={ 'name': 'Art History Test', 'type': 'major', 'code': '140', 'degree': 'B.A.', 'result': { 'all': [{ 'course': 'DEPT 123' }], } }) messages = list( audit(area=area, transcript=student['courses'], area_pointers=student['areas'], exceptions=[], print_all=False, estimate_only=False, constants=c)) result = messages[-1].result assert result.result.items[-1].result.items[-1].result.assertions[ 0].assertion.expected == 18
def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("areas", nargs="+") parser.add_argument("--break", dest="break_on_err", action="store_true") args = parser.parse_args() for f in args.areas: with open(f, "r", encoding="utf-8") as infile: area_def = yaml.load(stream=infile, Loader=yaml.SafeLoader) try: c = Constants(matriculation_year=200) area = AreaOfStudy.load(specification=area_def, c=c) area.validate() except Exception: print('!!\t{}'.format(f)) traceback.print_exc() print() print() if args.break_on_err: return 1 return 0
def test_excluded_req_gpa(): transcript = trns() area = AreaOfStudy.load(c=c, transcript=transcript, specification={ 'name': 'test', 'type': 'concentration', 'result': { 'all': [ { 'requirement': 'compsci' }, { 'requirement': 'art' }, ], }, 'requirements': { 'compsci': { 'result': { 'from': 'courses', 'where': { 'subject': { '$eq': 'CSCI' } }, 'assert': { 'count(courses)': { '$gte': 2 } }, } }, 'art': { 'in_gpa': False, 'result': { 'from': 'courses', 'where': { 'subject': { '$eq': 'ART' } }, 'assert': { 'count(courses)': { '$gte': 1 } }, }, }, }, }) solution = list( area.solutions(transcript=transcript, areas=[], exceptions=[]))[0] result = solution.audit() assert area.result.items[1].in_gpa is False assert set(result.matched_for_gpa()) == set([transcript[0], transcript[1]]) assert transcript[2] not in set(result.matched_for_gpa()) assert result.gpa() == Decimal('2.5')
def run(args: Arguments, *, transcript_only: bool = False, gpa_only: bool = False) -> Iterator[Message]: # noqa: C901 if not args.student_files: yield NoStudentsMsg() return file_data = [] try: if args.archive_file: with tarfile.open(args.archive_file, 'r') as tarball: for student_file in args.student_files: data = tarball.extractfile(student_file) assert data is not None file_data.append(json.load(data)) else: for student_file in args.student_files: with open(student_file, "r", encoding="utf-8") as infile: file_data.append(json.load(infile)) except FileNotFoundError as ex: yield ExceptionMsg(ex=ex, tb=traceback.format_exc(), stnum=None, area_code=None) return for student in file_data: area_pointers = tuple( AreaPointer.from_dict(a) for a in student['areas']) constants = Constants( matriculation_year=0 if student['matriculation'] == '' else int(student['matriculation'])) transcript = tuple(load_transcript(student['courses'])) transcript_with_failed = tuple( load_transcript(student['courses'], include_failed=True)) if transcript_only: writer = csv.writer(sys.stdout) writer.writerow([ 'course', 'clbid', 'course_type', 'credits', 'name', 'year', 'term', 'type', 'grade', 'gereqs', 'is_repeat', 'in_gpa', 'attributes' ]) for c in transcript: writer.writerow([ c.course(), c.clbid, c.course_type.value, str(c.credits), c.name, str(c.year), str(c.term), c.sub_type.name, c.grade_code.value, ','.join(c.gereqs), str(c.is_repeat), str(c.is_in_gpa), ','.join(c.attributes), ]) return if gpa_only: for c in grade_point_average_items(transcript_with_failed): print(c.course(), c.grade_code.value, c.grade_points) print(grade_point_average(transcript_with_failed)) return for area_file in args.area_files: try: with open(area_file, "r", encoding="utf-8") as infile: area_spec = yaml.load(stream=infile, Loader=yaml.SafeLoader) except FileNotFoundError: yield AreaFileNotFoundMsg( area_file= f"{os.path.dirname(area_file)}/{os.path.basename(area_file)}", stnum=student['stnum']) return area_code = area_spec['code'] area_catalog = pathlib.Path(area_file).parent.stem exceptions = [ load_exception(e) for e in student.get("exceptions", []) if e['area_code'] == area_code ] area = AreaOfStudy.load( specification=area_spec, c=constants, areas=area_pointers, transcript=transcript, ) area.validate() yield AuditStartMsg(stnum=student['stnum'], area_code=area_code, area_catalog=area_catalog, student=student) try: yield from audit( area=area, exceptions=exceptions, transcript=transcript, transcript_with_failed=transcript_with_failed, constants=constants, area_pointers=area_pointers, print_all=args.print_all, estimate_only=args.estimate_only, ) except Exception as ex: yield ExceptionMsg(ex=ex, tb=traceback.format_exc(), stnum=student['stnum'], area_code=area_code)