예제 #1
0
def test_compute_single_clause_diff():
    from decimal import Decimal
    ctx = RequirementContext(areas=(AreaPointer.with_code('711'),))

    assert compute_single_clause_diff({'has-area-code(711)': '+ 0.50'}, ctx=ctx) == Decimal(0.5)
    assert compute_single_clause_diff({'has-area-code(711)': '+  .50'}, ctx=ctx) == Decimal(0.5)

    with pytest.raises(TypeError, match=r'unknown \$ifs key unknown-key'):
        assert compute_single_clause_diff({'unknown-key(711)': '+  .50'}, ctx=ctx) == Decimal(0)

    ctx = RequirementContext(
        areas=(AreaPointer.with_code('711'),),
        music_proficiencies=MusicProficiencies(keyboard_3=True, keyboard_4=False),
    )

    assert compute_single_clause_diff({'has-area-code(711) + passed-proficiency-exam(Keyboard Level III)': '+ 0.50'}, ctx=ctx) == Decimal(0.5)
    assert compute_single_clause_diff({'has-area-code(711) + passed-proficiency-exam(Keyboard Level IV)': '+  .50'}, ctx=ctx) == Decimal(0)

    assert compute_single_clause_diff({
        'has-area-code(711)': '+ 0.50',
        'has-area-code(711) + passed-proficiency-exam(Keyboard Level III)': '+ 0.50',
    }, ctx=ctx) == Decimal(1.0)

    assert compute_single_clause_diff({
        'has-area-code(711)': '+ 0.50',
        'has-area-code(711) + passed-proficiency-exam(Keyboard Level IV)': '+ 0.50',
    }, ctx=ctx) == Decimal(0.5)
예제 #2
0
def test_count_courses_optimization():
    ctx = RequirementContext()

    courses = [
        course_from_str('A 101'),
        course_from_str('B 101'),
        course_from_str('C 101'),
    ]

    rule = QueryRule.load(path=[],
                          c=c,
                          ctx=ctx,
                          data={
                              'from': 'courses',
                              'assert': {
                                  'count(courses)': {
                                      '$gte': 2
                                  }
                              },
                          })

    results = list(iterate_item_set(courses, rule=rule))

    assert results == [
        tuple([courses[0], courses[1]]),
        tuple([courses[0], courses[2]]),
        tuple([courses[1], courses[2]]),
        tuple([courses[0], courses[1], courses[2]]),
    ]
def test_pred_and_expr():
    ctx = RequirementContext(
        areas=(AreaPointer.with_code('711'), ),
        music_proficiencies=MusicProficiencies(
            keyboard_3=MusicProficiencyStatus.Exam,
            keyboard_4=MusicProficiencyStatus.No),
    )

    both_true = {
        '$and': [
            {
                'has-declared-area-code': '711'
            },
            {
                'passed-proficiency-exam': 'Keyboard Level III'
            },
        ]
    }
    actual = load_predicate_expression(both_true, ctx=ctx)
    assert actual.result is True
    assert isinstance(actual, PredicateExpressionCompoundAnd)

    area_but_not_exam = {
        '$and': [
            {
                'has-declared-area-code': '711'
            },
            {
                'passed-proficiency-exam': 'Keyboard Level IV'
            },
        ]
    }
    assert load_predicate_expression(area_but_not_exam,
                                     ctx=ctx).result is False
예제 #4
0
def init_kwargs(*, course='AMCON 101', path):
    return {
        'context': RequirementContext(),
        'course': course_from_str(course),
        'allow_claimed': False,
        'path': tuple(path),
    }
def test_pred_expr_passed_proficiency_exam():
    ctx = RequirementContext(music_proficiencies=MusicProficiencies(
        keyboard_3=MusicProficiencyStatus.Exam))
    assert load_predicate_expression(
        {
            'passed-proficiency-exam': 'Keyboard Level III'
        }, ctx=ctx).result is True
def test_load_predicate_expression():
    ctx = RequirementContext(areas=(AreaPointer.with_code('711'), ))

    with pytest.raises(
            TypeError,
            match=r"unknown predicate expression \{'unknown-key': '711'\}"):
        assert load_predicate_expression({'unknown-key': '711'}, ctx=ctx)
예제 #7
0
def test_load_predicate_constant_expands_to_several_nested():
    ppm = tuple(['saxophone', 'jazz saxophone'])
    constants = Constants(primary_performing_medium=ppm)
    ctx = RequirementContext()
    input_data = {'name': {'$in': ['piano', '$primary-performing-medium']}}

    c = load_predicate(input_data, c=constants, mode=DataType.Course, ctx=ctx)
    assert isinstance(c, Predicate)

    assert list(c.expected) == ['piano', 'saxophone', 'jazz saxophone']
def test_pred_expr_has_area_code():
    ctx = RequirementContext(areas=(AreaPointer.with_code('711'), ))
    assert load_predicate_expression({
        'has-declared-area-code': '711'
    },
                                     ctx=ctx).result is True
    assert load_predicate_expression({
        'has-declared-area-code': '000'
    },
                                     ctx=ctx).result is False
def test_pred_or_expr():
    ctx = RequirementContext(
        areas=(AreaPointer.with_code('711'), ),
        music_proficiencies=MusicProficiencies(
            keyboard_3=MusicProficiencyStatus.Exam,
            keyboard_4=MusicProficiencyStatus.No),
    )

    both_true = {
        '$or': [
            {
                'has-declared-area-code': '711'
            },
            {
                'passed-proficiency-exam': 'Keyboard Level III'
            },
        ]
    }
    assert load_predicate_expression(both_true, ctx=ctx).result is True

    exam_but_not_area = {
        '$or': [
            {
                'has-declared-area-code': '000'
            },
            {
                'passed-proficiency-exam': 'Keyboard Level III'
            },
        ]
    }
    assert load_predicate_expression(exam_but_not_area, ctx=ctx).result is True

    area_but_not_exam = {
        '$or': [
            {
                'has-declared-area-code': '711'
            },
            {
                'passed-proficiency-exam': 'Keyboard Level IV'
            },
        ]
    }
    assert load_predicate_expression(area_but_not_exam, ctx=ctx).result is True

    both_false = {
        '$or': [
            {
                'has-declared-area-code': '000'
            },
            {
                'passed-proficiency-exam': 'Keyboard Level IV'
            },
        ]
    }
    assert load_predicate_expression(both_false, ctx=ctx).result is False
def test_pred_expr_has_ip_course():
    ctx = RequirementContext().with_transcript([
        course_from_str('AMCON 101', in_progress=True),
        course_from_str('AMCON 102', in_progress=False),
    ])
    assert load_predicate_expression({
        'has-ip-course': 'AMCON 101'
    }, ctx=ctx).result is True
    assert load_predicate_expression({
        'has-ip-course': 'AMCON 102'
    }, ctx=ctx).result is False
예제 #11
0
def test_claims__claimed(benchmark):
    course = course_from_str('AMCON 101')

    context = RequirementContext()
    kwargs = {
        'course': course,
        'allow_claimed': False,
        'path': tuple(["$", "%Common Requirements", ".count", "[2]", "%Credits outside the major", ".query", ".assertions", "[0]", ".assert", '*AMCON 101']),
    }

    context.make_claim(**kwargs)

    benchmark(do_claim_2, context=context, **kwargs)
def test_su_during_covid_different_clause() -> None:
    ctx = RequirementContext()
    clause = load_predicate({"grade": {"$gte": "B"}}, c=c, mode=mode, ctx=ctx)
    assert isinstance(clause, Predicate)

    course = course_from_str(
        'CSCI 251',
        grade_code='S',
        grade_option=GradeOption.SU,
        su_grade_code='C',
        year=2019,
        term='3',
    )
    assert apply_predicate__grade(course, clause) is False
예제 #13
0
def test_ranges_eq(caplog):
    caplog.set_level(logging.DEBUG)
    c = Constants(matriculation_year=2000)
    ctx = RequirementContext()

    x = Assertion.load({"assert": {
        "count(courses)": {
            "$eq": 1
        }
    }},
                       c=c,
                       ctx=ctx,
                       data_type=DataType.Course,
                       path=['$'])
    result = x.input_size_range(maximum=5)
    assert list(result) == [1]
예제 #14
0
def test_overlaps(caplog: Any) -> None:
    # caplog.set_level(logging.DEBUG)
    global c

    area = AreaOfStudy.load(c=c, specification={
        "result": {"all": [
            {"requirement": "Core"},
            {"requirement": "Electives"},
        ]},
        "requirements": {
            "Core": {
                "result": {"all": [
                    {"course": "MUSIC 212"},
                    {"course": "MUSIC 214"},
                ]},
            },
            "Electives": {
                "result": {
                    "from": "courses",
                    "where": {
                        "$and": [
                            {"subject": {"$eq": "MUSIC"}},
                            {"level": {"$eq": [300]}},
                        ],
                    },
                    "all": [
                        {"assert": {"count(courses)": {"$gte": 2}}},
                    ],
                },
            },
        },
    })

    transcript = [course_from_str(c) for c in ["MUSIC 212", "MUSIC 214", "MUSIC 301", "MUSIC 302"]]
    ctx = RequirementContext().with_transcript(transcript)

    area.result.find_independent_children(items=area.result.items, ctx=ctx)

    solutions = list(area.solutions(student=Student.load(dict(courses=transcript)), exceptions=[]))
    assert len(solutions) == 1

    result = solutions[0].audit()

    assert result.ok() is True
def test_graded_during_covid() -> None:
    ctx = RequirementContext()
    clause = load_predicate({"grade": {
        "$gte": "C",
        "$during_covid": "C-"
    }},
                            c=c,
                            mode=mode,
                            ctx=ctx)
    assert isinstance(clause, Predicate)

    course = course_from_str(
        'CSCI 251',
        grade_code='C',
        grade_option=GradeOption.Grade,
        year=2019,
        term='3',
    )
    assert apply_predicate__grade(course, clause) is True
예제 #16
0
def test_clauses_in(caplog):
    caplog.set_level(logging.DEBUG)

    c = Constants(matriculation_year=2000)
    ctx = RequirementContext()
    course = course_from_str(s="CSCI 296")

    values = tuple([296, 298, 396, 398])
    x = load_predicate({"number": {
        "$in": values
    }},
                       c=c,
                       ctx=ctx,
                       mode=DataType.Course)
    expected_single = Predicate.from_args(key="number",
                                          expected=values,
                                          original=values,
                                          operator=Operator.In)
    assert x == expected_single

    assert x.apply(course) is True
예제 #17
0
def test_clauses(caplog):
    caplog.set_level(logging.DEBUG)

    c = Constants(matriculation_year=2000)
    ctx = RequirementContext()

    x = load_predicate({"attributes": {
        "$eq": "csci_elective"
    }},
                       c=c,
                       ctx=ctx,
                       mode=DataType.Course)
    expected_single = Predicate.from_args(key="attributes",
                                          expected="csci_elective",
                                          original="csci_elective",
                                          operator=Operator.EqualTo)
    assert x == expected_single

    crs = course_from_str(s="CSCI 121", attributes=["csci_elective"])

    assert x.apply(crs) is True
예제 #18
0
def test_resolution(caplog):
    caplog.set_level(logging.DEBUG)

    c = Constants(matriculation_year=2000)
    ctx = RequirementContext()

    x = Assertion.load({"assert": {
        "count(items)": {
            "$eq": 1
        }
    }},
                       c=c,
                       ctx=ctx,
                       data_type=DataType.Recital,
                       path=['$'])

    result = x.audit_and_resolve(tuple([IntThing()]), ctx=ctx)
    assert result.ok() is True

    result = x.audit_and_resolve(tuple([IntThing(), IntThing()]), ctx=ctx)
    assert result.ok() is False
def test_pred_expr_has_course():
    ctx = RequirementContext().with_transcript([course_from_str('AMCON 101')])
    assert load_predicate_expression({
        'has-course': 'AMCON 101'
    }, ctx=ctx).result is True
예제 #20
0
def test_ranges_eq_2(caplog):
    """ensure that a solution with fewer matching courses than requested is still proposed"""
    caplog.set_level(logging.DEBUG)
    c = Constants(matriculation_year=2000)
    ctx = RequirementContext()

    result = Assertion.load({
        "assert": {
            "count(courses)": {
                "$eq": 3
            }
        }
    },
                            c=c,
                            ctx=ctx,
                            data_type=DataType.Course,
                            path=['$']).input_size_range(maximum=2)
    assert list(result) == [2]

    result = Assertion.load({
        "assert": {
            "count(courses)": {
                "$neq": 3
            }
        }
    },
                            c=c,
                            ctx=ctx,
                            data_type=DataType.Course,
                            path=['$']).input_size_range(maximum=2)
    assert list(result) == [0, 1, 2]

    result = Assertion.load({
        "assert": {
            "count(courses)": {
                "$lt": 3
            }
        }
    },
                            c=c,
                            ctx=ctx,
                            data_type=DataType.Course,
                            path=['$']).input_size_range(maximum=2)
    assert list(result) == [0, 1, 2]

    result = Assertion.load({
        "assert": {
            "count(courses)": {
                "$lte": 3
            }
        }
    },
                            c=c,
                            ctx=ctx,
                            data_type=DataType.Course,
                            path=['$']).input_size_range(maximum=2)
    assert list(result) == [0, 1, 2, 3]

    result = Assertion.load({
        "assert": {
            "count(courses)": {
                "$gt": 3
            }
        }
    },
                            c=c,
                            ctx=ctx,
                            data_type=DataType.Course,
                            path=['$']).input_size_range(maximum=2)
    assert list(result) == [2]

    result = Assertion.load({
        "assert": {
            "count(courses)": {
                "$gte": 3
            }
        }
    },
                            c=c,
                            ctx=ctx,
                            data_type=DataType.Course,
                            path=['$']).input_size_range(maximum=2)
    assert list(result) == [2]