import pytest from solution import Gradebook, GradeError, letter, weighted_average @pytest.mark.parametrize("score,expected", [ (100, "AA"), (90, "AA"), (89.99, "BA"), (85, "BA"), (80, "BB"), (75, "CB"), (70, "CC"), (60, "DC"), (50, "DD"), (49.5, "FF"), (0, "FF"), ]) def test_letter_thresholds_are_inclusive(score, expected): assert letter(score) == expected @pytest.mark.parametrize("score", [-1, 100.5]) def test_letter_out_of_range(score): with pytest.raises(GradeError): letter(score) def test_weighted_average_normalizes_weights(): assert weighted_average([80, 100], [1, 3]) == 95.0 assert weighted_average([70, 80, 90], [0.2, 0.3, 0.5]) == 83.0 def test_weighted_average_rounds_to_two_decimals(): assert weighted_average([1, 2, 2], [1, 1, 1]) == 1.67 def test_weighted_average_errors(): with pytest.raises(GradeError): weighted_average([1, 2], [1]) with pytest.raises(GradeError): weighted_average([], []) with pytest.raises(GradeError): weighted_average([50, 60], [0, 0]) def test_add_and_average(): g = Gradebook([0.4, 0.6]) g.add("Ali", [50, 100]) assert g.average("Ali") == 80.0 def test_add_rejects_duplicates_and_wrong_length(): g = Gradebook([0.5, 0.5]) g.add("Ali", [1, 2]) with pytest.raises(GradeError): g.add("Ali", [3, 4]) with pytest.raises(GradeError): g.add("Veli", [3]) def test_ranking_descending_with_alphabetical_ties(): g = Gradebook([1]) g.add("Zeynep", [70]) g.add("Can", [90]) g.add("Ayşe", [70]) assert g.ranking() == ["Can", "Ayşe", "Zeynep"] def test_passed_includes_threshold(): g = Gradebook([1]) g.add("A", [50]) g.add("B", [49.99]) g.add("C", [80]) assert g.passed() == ["C", "A"] assert g.passed(threshold=80) == ["C"]