Composition
Related code
class Student: """Represents a student. attributes: name, grade """ pass class University: """Represents a university. attributes: name, students """ # Create students s1 = Student() s1.name, s1.grade = "Ariana", 95 s2 = Student() s2.name, s2.grade = "Besnik", 82 s3 = Student() s3.name, s3.grade = "Dafina", 91 ib = University() ib.name = "Ise Boletini" ib.students = [s1, s2, s3]
As we know, we can place any valid expression wherever it makes sense, and combine any concept with another. This flexibility allows us to mix classes, objects, and their attributes with other programming constructs like functions, loops, conditionals, lists, dictionaries, sets, and more. The goal of this lesson is to explore how we can compose these elements together to build more complex and realistic programs, rather than keeping them isolated.
print_scholarship_students
takes a university and prints the ones who are eligible for a
scholarship, based on their grade.
... def print_scholarship_students(uni): print("Scholarship Students:") for student in uni.students: if student.grade >= 90: print(f"{student.name} - Grade: {student.grade}")
... >>> print_scholarship_students(ib) Scholarship Students: Ariana - Grade: 95 Dafina - Grade: 91
get_grade_distribution
returns a dictionary that groups students into grade ranges like
"90-100", "80-89", etc. Each key maps to a list of student names.
... def get_grade_distribution(uni): distribution = { "90-100": [], "80-89": [], "below 80": [] } for st in uni.students: if st.grade >= 90: distribution["90-100"].append(st.name) elif st.grade >= 80: distribution["80-89"].append(st.name) else: distribution["below 80"].append(st.name) return distribution
>>> get_grade_distribution(ib) {'90-100': ['Ariana', 'Dafina'], '80-89': ['Besnik'], 'below 80': []}
get_top_students
returns a set of tuples where each tuple contains the name and grade of
students whose grade is higher than the average grade of all students.
... def get_top_students(uni): total = 0 for st in uni.students: total += st.grade avg = total / len(uni.students) top_students = set() for st in uni.students: if st.grade > avg: top_students.add((st.name, st.grade)) # tuple return top_students
>>> get_top_students(ib) {('Ariana', 95), ('Dafina', 91)}
Exercises
class Car: """Represents a car. attributes: brand, year, mileage """
Write a function that takes a list of cars and returns the set of brands whose mileage is below 50,000 and whose manufacturing year is 2016 or later.
class Gamer: """Represents a gamer. attributes: username, scores: list[int] """
Write a function that takes a list of gamers and returns a set of usernames whose average score is strictly higher than the average of all gamers combined.
class Athlete: """Represents an athlete. attributes: name, scores: list[tuple[event: str, score: float]] """
Write a function that takes a list of athletes and returns a dictionary where each key is an event, and the value is the highest score achieved in that event by any athlete.
class Student: """Represents a student. attributes: name, grade """ class School: """Represents a school. attributes: name: str, students: list[Student], top_students: set[Students] """
Write a function that takes a school and populates schools top_students with students who have grades in the top 10%.
class Race: """Represents a race. attributes: km: float, minutes: float """ class Runner: """Represents a runner. attributes: name, races: list[Race] """
Write a function that takes a list of runners and returns the name of the runner who improved the most, that is, the one with the biggest difference between their worst and best time (max - min).
Exercises
class Kickboxer: """Represents a fighter. attributes: name: str, wins: int, losses: int """
Write a function that takes a list of fighters and returns a list of tuples, each containing a fighter's name and their win ratio (wins / total matches), only if they've had more than 5 matches.
class Product: """Represents a product. attributes: name, price, tags: set[str]) """
Write a function that takes a list of products and a tag, products and tag, and returns a list of product names that contain the tag and cost more than the average price of all products.
class Airplane: """Represents an airplane. attributes: name, passengers (list of names), max_capacity """
Write a function that takes a list of airplanes and returns a list of names of planes that are over capacity.
class Answer: """Represents an answer. attributes: text: str, correct: bool """ class Contestant: """Represents a contestant. attributes: name: str, answers: list[Answer] """
Write a function that takes a list of contestants and returns the one with the longest streak of correct answers. Return their name.
class Attendance: """Represents attendance. attributes: date: str, present: bool """ class Worker: """Represents a worker. attributes: name, attendance: list[Attendance] """
Write a function that takes a list of workers and returns the name of the one with the longest streak of consecutive days present.