Lesson 3
Managing Student Enrollments with Sets and Hashes
Introduction

Welcome to today’s lesson! We’ll explore how to use Ruby’s Set class in a practical context by creating a student enrollment system for courses. Imagine you’re managing enrollments for an online course platform, where students enroll in courses, check their enrollments, or get a list of classmates. Using Set is ideal here since it automatically prevents duplicates, ensuring each student can only enroll in a course once.

By the end of this lesson, you’ll have a solid understanding of how to use sets and hashes for handling unique collections. Let’s get started!

Introducing Methods to Implement

In this system, we’ll build four methods for managing student enrollments:

  • enroll(student, course): Adds a student to a course. If the student is already enrolled, it does nothing.
  • unenroll(student, course): Removes a student from a course. Returns true if the student was enrolled and has now been removed, otherwise returns false. If the course becomes empty after unenrolling the student, it should also be removed from the system.
  • is_enrolled(student, course): Checks if a student is enrolled in a course, returning true if they are and false otherwise.
  • list_students(course): Returns an array of all students enrolled in a given course. If no students are enrolled, it returns an empty array.

Let’s implement each method one step at a time.

Step 1: Define the Class

We’ll start by defining our EnrollmentSystem class and initializing it with a hash to store enrollments.

Ruby
1require 'set' 2 3class EnrollmentSystem 4 def initialize 5 @courses_enrollment = {} # Hash to store each course with its enrolled students 6 end 7end

This code sets up an empty courses_enrollment hash, where each course will map to a set of students. Now that we have our class structure, let’s move to the methods.

Step 2: Implement enroll Method

The enroll method adds a student to a course. If the course doesn’t exist yet in @courses_enrollment, we’ll create a new set for it.

Ruby
1def enroll(student, course) 2 @courses_enrollment[course] ||= Set.new # Initialize set if course doesn't exist 3 @courses_enrollment[course].add(student) # Add student to the course's set 4end

This method first checks if the course exists in @courses_enrollment. If it doesn’t, @courses_enrollment[course] ||= Set.new creates a new set for that course. Then, the student is added to the course’s set, ensuring the student is only enrolled once.

Ruby
1# Example usage 2es = EnrollmentSystem.new 3es.enroll("Alice", "Math101") 4puts es.inspect # Output: {"Math101"=>#<Set: {"Alice"}>}

We see here that after enrolling Alice in "Math101," the course is listed in @courses_enrollment with Alice as the only student.

Step 3: Implement unenroll Method

The unenroll method removes a student from a course. If the course or student isn’t found, it returns false. If the student is successfully removed, it also checks if the course is now empty and, if so, removes it.

Ruby
1def unenroll(student, course) 2 if @courses_enrollment[course] && @courses_enrollment[course].include?(student) 3 @courses_enrollment[course].delete(student) # Remove student from the course 4 @courses_enrollment.delete(course) if @courses_enrollment[course].empty? # Remove course if empty 5 return true 6 end 7 false 8end

Here, we first verify that both the course and the student exist in @courses_enrollment. If they do, @courses_enrollment[course].delete(student) removes the student from the course. If the course set becomes empty, @courses_enrollment.delete(course) removes the course entry altogether. This method returns true if the student was successfully unenrolled and false otherwise.

Ruby
1# Example usage 2es = EnrollmentSystem.new 3es.enroll("Alice", "Math101") 4es.unenroll("Alice", "Math101") 5puts es.inspect # Output: {}

In this example, Alice is enrolled and then successfully unenrolled. After Alice is removed, "Math101" no longer appears in @courses_enrollment since it has no enrolled students.

Step 4: Implement is_enrolled Method

The is_enrolled method checks if a student is enrolled in a course, returning true if they are and false otherwise.

Ruby
1def is_enrolled(student, course) 2 @courses_enrollment[course] && @courses_enrollment[course].include?(student) 3end

This method checks if both the course and the student exist in @courses_enrollment. If they do, it returns true; otherwise, it returns false.

Ruby
1# Example usage 2es = EnrollmentSystem.new 3es.enroll("Alice", "Math101") 4puts es.is_enrolled("Alice", "Math101") # Output: true 5puts es.is_enrolled("Bob", "Math101") # Output: false

Here, the output confirms that Alice is enrolled in "Math101" but Bob is not.

Step 5: Implement list_students Method

Finally, the list_students method returns an array of all students enrolled in a course. If no students are enrolled, it returns an empty array.

Ruby
1def list_students(course) 2 return @courses_enrollment[course].to_a if @courses_enrollment[course] 3 [] 4end

In this method, @courses_enrollment[course].to_a converts the set of students to an array. If the course is not in @courses_enrollment, it simply returns an empty array.

Ruby
1# Example usage 2es = EnrollmentSystem.new 3es.enroll("Alice", "Math101") 4es.enroll("Bob", "Math101") 5puts es.list_students("Math101").inspect # Output: ["Alice", "Bob"] 6puts es.list_students("Physics101").inspect # Output: []

This example shows that both Alice and Bob are listed in "Math101," while an empty array is returned for "Physics101," as no one is enrolled in it.

Combining Everything

Below is the complete implementation of the EnrollmentSystem class combining all the methods we discussed:

Ruby
1require 'set' 2 3class EnrollmentSystem 4 def initialize 5 @courses_enrollment = {} # Hash to store each course and enrolled students 6 end 7 8 def enroll(student, course) 9 @courses_enrollment[course] ||= Set.new 10 @courses_enrollment[course].add(student) 11 end 12 13 def unenroll(student, course) 14 if @courses_enrollment[course] && @courses_enrollment[course].include?(student) 15 @courses_enrollment[course].delete(student) 16 @courses_enrollment.delete(course) if @courses_enrollment[course].empty? 17 return true 18 end 19 false 20 end 21 22 def is_enrolled(student, course) 23 @courses_enrollment[course] && @courses_enrollment[course].include?(student) 24 end 25 26 def list_students(course) 27 return @courses_enrollment[course].to_a if @courses_enrollment[course] 28 [] 29 end 30end

This consolidated code provides a ready-to-use EnrollmentSystem class complete with methods to manage student enrollments effectively.

Example Usage for Enrollment System Methods

Below are examples demonstrating how to use the methods in the EnrollmentSystem class:

Ruby
1# Creating a new enrollment system 2es = EnrollmentSystem.new 3 4# Enrolling students 5es.enroll("Alice", "Math101") 6es.enroll("Bob", "Math101") 7puts es.inspect # Output: {"Math101"=>#<Set: {"Alice", "Bob"}>} 8 9# Checking enrollment 10puts es.is_enrolled("Alice", "Math101") # Output: true 11puts es.is_enrolled("Charlie", "Math101") # Output: false 12 13# Listing students in a course 14puts es.list_students("Math101").inspect # Output: ["Alice", "Bob"] 15puts es.list_students("Physics101").inspect # Output: [] 16 17# Unenrolling students 18es.unenroll("Alice", "Math101") 19puts es.list_students("Math101").inspect # Output: ["Bob"] 20 21# Removing an empty course 22es.unenroll("Bob", "Math101") 23puts es.inspect # Output: {}

These examples demonstrate how to use the EnrollmentSystem methods to enroll, check enrollment, list students, and unenroll students while maintaining the system's integrity.

Lesson Summary

In today’s lesson, we created an EnrollmentSystem class using Ruby’s Set and Hash classes to manage student enrollments. We implemented methods to enroll and unenroll students, check if a student is enrolled, and list students in a course. This exercise demonstrates how to efficiently manage unique collections in Ruby using sets, especially in scenarios requiring efficient lookups and duplicate prevention.

Try extending this class with additional features or tackle similar challenges to deepen your understanding. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.