class Student:
    def __init__(self, name: str, student_id: int):
        self._name = name
        self._student_id = student_id


    def name(self) -> str:
        return self._name


    def student_id(self) -> int:
        return self._student_id



class ClubMembershipError(Exception):
    def __init__(self, message: str):
        super().__init__(message)



class Club:
    def __init__(self):
        self._students = {}


    def number_of_students(self) -> int:
        return len(self._students)


    def add_student(self, student_to_add: Student) -> None:
        if self.is_member(student_to_add.student_id()):
            raise ClubMembershipError(f'Student with ID {student_to_add.student_id()} is already a member of the club')
        
        self._students[student_to_add.student_id()] = student_to_add


    def is_member(self, student_id: int) -> bool:
        return student_id in self._students


    def get_student_by_id(self, student_id: int) -> Student:
        if not self.is_member(student_id):
            raise ClubMembershipError(f'Student with ID {student_id} is not a member of the club')

        return self._students[student_id]
