Last active
August 4, 2023 10:47
-
-
Save Friedjof/cedb9cad54b4ba172a7af182afc48bb9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
EIST 2023 Grading | |
Versions: | |
- GOE 1: grade + (1.0 + (.25 * hw_points / 90.0)) | |
Since: beginning of the first lecture | |
- GOE 2: grade + (1.0 + (.25 * hw_points / 101.0)) | |
Since: slack message from 2023-07-22 23:47:27 | |
- GOE 3: grade + (1.0 + (.35 * hw_points / 101.0)) | |
Since: since mail from 2023-08-02 14:48 | |
- GOE 4.1: grade * 1.1 + .25 * (hw_points / 101.0) * 100 | |
Since: since mail from 2023-08-03 11:19 - option 1 | |
- GOE 4.2: Register for the GORE exam | |
Since: since mail from 2023-08-03 11:19 - option 2 | |
- GOE 4.3: Register for the GORE exam | |
Since: since mail from 2023-08-03 11:19 - default | |
- GOE 5: grade * 1.1 + .25 * (hw_points / 101.0) * 100 | |
Since: since mail from 2023-08-04 09:38 | |
- GORE 1: Your homework does not count anymore. | |
Since: since mail from 2023-08-03 11:19 - default | |
""" | |
class Model: | |
def __init__(self, grade: float, hw_points: float): | |
self.grade = grade | |
self.hw_points = hw_points | |
class Controller: | |
def __init__(self, model: Model, view: 'View'): | |
self.model = model | |
self.view = view | |
self.can_talk = True | |
def run(self): | |
self.view.run(self) | |
def valid_hw_points_v1(self) -> bool: | |
return .0 <= self.model.hw_points <= 90.0 | |
def valid_hw_points_v2(self) -> bool: | |
return .0 <= self.model.hw_points <= 101.0 | |
def will_pass_v1(self) -> bool: | |
return self.model.hw_points >= 50.0 | |
def will_pass_v2(self) -> bool: | |
return self.model.hw_points >= 45.0 | |
def will_pass_v3(self) -> bool: | |
return self.model.hw_points >= 30.0 | |
def say(self, message: str, spaces: int = 4) -> None: | |
if self.can_talk: | |
print((" " * spaces) + str(message)) | |
def get_best_grade(self) -> float or None: | |
self.can_talk = False | |
grade_v1: float or None = self.goe_grading_v1() | |
grade_v2: float or None = self.goe_grading_v2() | |
grade_v3: float or None = self.goe_grading_v3() | |
grade_v4_option_1: float or None = self.goe_grading_v4_option_1() | |
grade_v5: float or None = self.goe_grading_v5() | |
self.can_talk = True | |
max_grade: dict = {"grade": .0, "version": ""} | |
for grade, v in [(grade_v1, "v1"), (grade_v2, "v2"), (grade_v3, "v3"), | |
(grade_v4_option_1, "v4.1"), (grade_v5, "v5")]: | |
if grade is not None and grade >= max_grade["grade"]: | |
max_grade["grade"] = grade | |
max_grade["version"] = v | |
if max_grade["grade"] == .0: | |
self.say(Msg.GORE_REGISTER, 0) | |
else: | |
self.say(Msg.BEST_GRADE.format( | |
grade=round(max_grade["grade"], 3), | |
score=self.calc_score(max_grade["grade"]), | |
version=max_grade["version"], | |
), 0) | |
def goe_grading_v1(self) -> float or None: | |
self.say(Msg.AUTOMATED_GRADING.format(1), 0) | |
if not self.valid_hw_points_v1(): | |
self.say(Msg.ERROR_INVALID_HW_POINTS_V1) | |
elif not self.will_pass_v1(): | |
self.say(Msg.ERROR_WILL_NOT_PASS_V1) | |
else: | |
return self.model.grade + (1.0 + (.25 * self.model.hw_points / 90.0)) | |
def goe_grading_v2(self) -> float or None: | |
self.say(Msg.AUTOMATED_GRADING.format(2), 0) | |
if not self.valid_hw_points_v2(): | |
self.say(Msg.ERROR_INVALID_HW_POINTS_V2) | |
elif not self.will_pass_v1(): | |
self.say(Msg.ERROR_WILL_NOT_PASS_V2) | |
else: | |
return self.model.grade + (1.0 + (.25 * self.model.hw_points / 101.0)) | |
def goe_grading_v3(self) -> float or None: | |
self.say(Msg.AUTOMATED_GRADING.format(3), 0) | |
if not self.valid_hw_points_v2(): | |
self.say(Msg.ERROR_INVALID_HW_POINTS_V2) | |
else: | |
return self.model.grade + (1.0 + (.35 * self.model.hw_points / 101.0)) | |
def goe_grading_v4_option_1(self) -> float or None: | |
self.say(Msg.AUTOMATED_GRADING.format(4.1), 0) | |
if not self.valid_hw_points_v2(): | |
self.say(Msg.ERROR_INVALID_HW_POINTS_V2) | |
elif not self.will_pass_v2(): | |
self.say(Msg.ERROR_WILL_NOT_PASS_V2) | |
else: | |
return self.model.grade * 1.1 + .25 * (self.model.hw_points / 101.0) * 100.0 | |
def goe_grading_v4_option_2(self) -> None: | |
self.say(Msg.AUTOMATED_GRADING.format(4.2), 0) | |
self.say(Msg.GORE_REGISTER) | |
self.say(Msg.GORE_REGISTER_HW_POINTS.format(self.model.hw_points)) | |
self.say(Msg.GORE_REGISTER_GRADE.format(self.model.grade)) | |
def goe_grading_v4_default(self) -> None: | |
self.say(Msg.AUTOMATED_GRADING.format(4.3), 0) | |
self.say(Msg.GORE_REGISTER) | |
self.say(Msg.GORE_REGISTER_GRADE_HW_POINTS.format(self.model.hw_points, self.model.grade)) | |
def goe_grading_v5(self) -> float or None: | |
self.say(Msg.AUTOMATED_GRADING.format(5), 0) | |
if not self.valid_hw_points_v2(): | |
self.say(Msg.ERROR_INVALID_HW_POINTS_V2) | |
elif not self.will_pass_v3(): | |
self.say(Msg.ERROR_WILL_NOT_PASS_V3) | |
else: | |
return self.model.grade * 1.1 + .25 * (self.model.hw_points / 101.0) * 100.0 | |
def get_model(self) -> Model: | |
return self.model | |
def set_model(self, model: Model) -> None: | |
self.model = model | |
@staticmethod | |
def calc_score(grade: float) -> float: | |
if grade < 20.0: | |
return 5.0 | |
elif grade < 25.0: | |
return 4.7 | |
elif grade < 30.0: | |
return 4.3 | |
elif grade < 40.0: | |
return 4.0 | |
elif grade < 45.0: | |
return 3.7 | |
elif grade < 50.0: | |
return 3.3 | |
elif grade < 55.0: | |
return 3.0 | |
elif grade < 60.0: | |
return 2.7 | |
elif grade < 65.0: | |
return 2.3 | |
elif grade < 70.0: | |
return 2.0 | |
elif grade < 78.0: | |
return 1.7 | |
elif grade < 86.0: | |
return 1.3 | |
else: | |
return 1.0 | |
def __repr__(self) -> str: | |
return Msg.STUDENT_LOOK.format(grade=self.model.grade, hw_points=self.model.hw_points) | |
def __eq__(self, other: 'Controller') -> bool: | |
return self.model.grade == other.model.grade and self.model.hw_points == other.model.hw_points | |
class View: | |
def __init__(self) -> None: | |
print(Msg.WELCOME) | |
def run(self, controller: Controller) -> None: | |
model = controller.get_model() | |
self.show_help() | |
self.show_model(model=model) | |
while True: | |
try: | |
option: str = input(Msg.INPUT_OPTION).lower() | |
except KeyboardInterrupt: | |
break | |
if option == "h": | |
self.show_help() | |
print(Msg.SEPERATOR) | |
elif option == "c": | |
print(Msg.SEPERATOR) | |
controller.set_model(self.get_student()) | |
model = controller.get_model() | |
self.show_model(model=model) | |
elif option == "1": | |
print(Msg.SEPERATOR) | |
r: float or None = controller.goe_grading_v1() | |
if r is not None: | |
controller.say(Msg.GRADE_OUTPUT.format( | |
grade=round(r, 3), score=Controller.calc_score(r))) | |
print(Msg.SEPERATOR) | |
elif option == "2": | |
print(Msg.SEPERATOR) | |
r: float or None = controller.goe_grading_v2() | |
if r is not None: | |
controller.say(Msg.GRADE_OUTPUT.format( | |
grade=round(r, 3), score=Controller.calc_score(r))) | |
print(Msg.SEPERATOR) | |
elif option == "3": | |
print(Msg.SEPERATOR) | |
r: float or None = controller.goe_grading_v3() | |
if r is not None: | |
controller.say(Msg.GRADE_OUTPUT.format( | |
grade=round(r, 3), score=Controller.calc_score(r))) | |
print(Msg.SEPERATOR) | |
elif option == "4": | |
print(Msg.SEPERATOR) | |
r: float or None = controller.goe_grading_v4_option_1() | |
if r is not None: | |
controller.say(Msg.GRADE_OUTPUT.format( | |
grade=round(r, 3), score=Controller.calc_score(r))) | |
else: | |
controller.goe_grading_v4_option_2() | |
print(Msg.SEPERATOR) | |
elif option == "5": | |
print(Msg.SEPERATOR) | |
r: float or None = controller.goe_grading_v5() | |
if r is not None: | |
controller.say(Msg.GRADE_OUTPUT.format( | |
grade=round(r, 3), score=Controller.calc_score(r))) | |
else: | |
controller.goe_grading_v4_default() | |
print(Msg.SEPERATOR) | |
elif option == "s": | |
self.show_model(model=model) | |
elif option == "g": | |
print(Msg.SEPERATOR) | |
controller.get_best_grade() | |
print(Msg.SEPERATOR) | |
elif option == "q": | |
break | |
else: | |
print(Msg.INVALID_OPTION) | |
print(Msg.GOODBYE) | |
@staticmethod | |
def show_model(model: Model) -> None: | |
print(Msg.SEPERATOR) | |
print(Msg.SHOW_STUDENT.format(grade=model.grade, hw_points=model.hw_points)) | |
print(Msg.SEPERATOR) | |
@staticmethod | |
def get_student() -> Model: | |
while True: | |
try: | |
hw_points: float = float(input(Msg.INPUT_HW_POINTS).replace(",", ".")) | |
grade: float = float(input(Msg.INPUT_GRADE).replace(",", ".")) | |
break | |
except ValueError: | |
print(Msg.INVALID_NUMBER) | |
return Model(grade=grade, hw_points=hw_points) | |
@staticmethod | |
def show_help() -> None: | |
print(Msg.SEPERATOR) | |
print("""Options: | |
[H]elp | |
[C]hange student grade and homework points | |
[1] to [4] - Run the grading algorithm | |
[G]et the best grade | |
[S]how the current student | |
[Q]uit""") | |
class Msg: | |
ERROR_INVALID_HW_POINTS_V1 = "Invalid HW points. Must be between 0 and 90." | |
ERROR_INVALID_HW_POINTS_V2 = "Invalid HW points. Must be between 0 and 101." | |
ERROR_WILL_NOT_PASS_V1 = "You need at least a 50% to pass the course. Register for the GORE exam." | |
ERROR_WILL_NOT_PASS_V2 = "You need at least a 45% to pass the course. Register for the GORE exam." | |
ERROR_WILL_NOT_PASS_V3 = "You need at least a 30% to pass the course. Register for the GORE exam." | |
GORE_REGISTER = "You need to register for the GORE exam." | |
GORE_REGISTER_HW_POINTS = "You can take the Homework points ({}) with you." | |
GORE_REGISTER_GRADE = "But do not forget to throw your grade ({}) in the rubbish." | |
GORE_REGISTER_GRADE_HW_POINTS = "You can take the Homework points ({}) with you. But do not forget to throw your " \ | |
"grade ({}) in the rubbish." | |
BEST_GRADE = "Best grade is {grade} (Points) [score: {score}] for version {version}" | |
AUTOMATED_GRADING = "Automated grading for version {}" | |
STUDENT_LOOK = "Student(grade={grade}, hw_points={hw_points})" | |
INPUT_OPTION = ">> " | |
INPUT_GRADE = " Enter your grade: " | |
INPUT_HW_POINTS = "Enter your homework points: " | |
INVALID_NUMBER = "Invalid number. Please try again." | |
INVALID_OPTION = "Invalid option. Please try again." | |
GRADE_OUTPUT = "{grade} (Points) this is a score of {score}" | |
SHOW_STUDENT = "Student(grade={grade}, hw_points={hw_points})" | |
GOODBYE = "Goodbye." | |
SEPERATOR = "-----------------------------------------" | |
WELCOME = "Welcome to the GORE grading system EIST23 (v1.0)" | |
if __name__ == '__main__': | |
m: Model = Model(0.0, 0.0) | |
v: View = View() | |
c: Controller = Controller(m, v) | |
c.run() |
fixed
WTF happened here?
This looks straight up mental. I don't think MVC is a good pattern for text based input-output. Are you okay?
You wanted a pattern, then you get some patterns. Feel free to add a graphical interface to the whole thing. You just need to customize the view.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am missing at least one strategy pattern in this codebase.