Advertisement
jmreagle

GPA Calculate

Apr 26th, 2024
740
0
3 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.50 KB | Source Code | 0 0
  1. #!/usr/bin/env python3
  2. """Using dictionary of letter grades, calculate mean GPA from list
  3. of letter grades converted to points"""
  4.  
  5. # https://gist.github.com/reagle/9cc2f4e2f98446528128d1f6edfe3d73
  6. # add results to e-statement-1b-teaching-trace-table.xlsx
  7.  
  8. __author__ = "Joseph Reagle"
  9. __copyright__ = "Copyright (C) 2021-2024 Joseph Reagle"
  10. __license__ = "GLPv3"
  11. __version__ = "1.1"
  12.  
  13.  
  14. import statistics
  15. from collections import Counter
  16.  
  17. try:
  18.     import asciietch.graph as ag  # type:ignore
  19.  
  20.     asciietch_imported = True
  21. except ImportError:
  22.     asciietch_imported = False
  23.     print("`pip install asciietch` if you want nice graphs ▁▅█▂▁▃▁▂▁▁▁▂▁")
  24.     print("    https://github.com/linkedin/asciietch\n")
  25.  
  26. # https://registrar.northeastern.edu/article/how-to-calculate-your-gpa/
  27. POINTS = {
  28.     "A+": 4.0,
  29.     "A": 4.0,
  30.     "A-": 3.667,
  31.     "B+": 3.333,
  32.     "B": 3.0,
  33.     "B-": 2.667,
  34.     "C+": 2.333,
  35.     "C": 2.0,
  36.     "C-": 1.667,
  37.     "D+": 1.333,
  38.     "D": 1.0,
  39.     "D-": 0.667,
  40.     "F": 0,
  41. }
  42.  
  43.  
  44. def calc_gpa(grades: list[str]) -> float:
  45.     """Calculate mean GPA from list of letter grades converted to points."""
  46.     return statistics.mean([POINTS[grade] for grade in grades])
  47.  
  48.  
  49. def print_header():
  50.     """Print a header for the output."""
  51.     print(f"{'COURSE':<15} {'N':<5} {'MEAN':<10}", end="")
  52.     print(" ".join(f"{letter:<2}" for letter in POINTS.keys()))
  53.  
  54.  
  55. def print_course(title: str, grades: list[str]) -> None:
  56.     """Print single-line information for a course."""
  57.     print(f"{title:<15} N={len(grades):02d}  μ={calc_gpa(grades):.2f}", end="    ")
  58.     distribution = [grades.count(letter) for letter in POINTS]
  59.     counter = Counter(grades)
  60.     for letter in POINTS.keys():
  61.         if letter in counter:
  62.             print(f"{counter[letter]:<3}", end="")
  63.         else:
  64.             print("   ", end="")
  65.     if asciietch_imported:
  66.         grapher = ag.Grapher()
  67.         print(grapher.asciihist(distribution), end="")
  68.     print()
  69.  
  70.  
  71. COURSES = {  # Target: B+ / 3.33 average
  72.     ################### 2024 Spring
  73.     # 3.17 unusually weak work
  74.     "2024_CDA_1SP": "B+ A C+ C B- A- A- B B+ B+ A B- A D- A B C+ A A- B+ A- B A- B B",
  75.     # 3.74 unusually excellent work
  76.     "2024_OC_1SP": "B+ A A- B+ A B+ A A- A- A A- A A A-",
  77.     ################### 2023 Fall
  78.     # 3.35 unprecedented drops at start, leaving mostly strong students
  79.     "2023_CDA_2FA": "A- A A- B- A- A- A- C A A A- A A- D- A B- A- A- B- B+",
  80.     # 3.33 first time teaching public speaking (includes F no show; 3.52 without him)
  81.     "2023_PS_2FA": "B+ A- B A- A A- B- A B A- B+ A- A- A F B+ A A- B",
  82.     ################### 2023 Spring
  83.     # 3.31
  84.     "2023_CDA_1SP": (
  85.         "B B A A- A A- A- A- B+ A- A- A- A- A- A- F A B B+ A F A C+ A- A A A- B+ A- C+"
  86.     ),
  87.     # 3.60 excellent work from mature students
  88.     "2023_OC_1SP": "B+ A A B- B+ A- A- A A A- B A A B",
  89.     ################### 2022 Fall
  90.     # 3.44
  91.     "2022_CDA_2FA": (
  92.         "D+ A A B+ A- A- A- A B+ B+ A- A- A A- A- B+ A A B+ B B B+ A- B B B+ A C+"
  93.     ),
  94.     # 3.48
  95.     "2022_OC_2FA": "A- A B+ A C B+ B+ A- A",
  96.     ################### 2022 Spring
  97.     # 3.42
  98.     "2022_CDA_1SP": (
  99.         "C- A- A A- C- B A- A- A- B+ A B+ B+ A B+ B A- A- A A B+ A A- B A- B+ B"
  100.     ),
  101.     # 3.61, excellent students
  102.     "2022_PC_1SP": "B+ B+ A A- B+ B+ A B A- A A- A A A- A- A- B",
  103.     # "TEST": "A B B C C C D D D D F F F F F",
  104. }
  105.  
  106. print_header()
  107. for title, grades in COURSES.items():
  108.     print_course(title, grades.split(" "))
  109.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement