diff --git a/pipeline/matching/generators/limited_schedules.py b/pipeline/matching/generators/limited_schedules.py index 0e9a6d9f..9a4151b8 100644 --- a/pipeline/matching/generators/limited_schedules.py +++ b/pipeline/matching/generators/limited_schedules.py @@ -1,19 +1,56 @@ -from typing import Iterator +from typing import Dict, Iterator, List, Tuple from pipeline.matching.core import MatchGenerator -from pipeline.types import Match, MatchingInput +from pipeline.types import Match, MatchingInput, MatchMetadata GENERATOR_LIMITED_SCHEDULES = "limitedSchedulesGenerator" class LimitedSchedulesGenerator(MatchGenerator): - def __init__(self, max_available: int = 0): + def __init__(self, max_available: int = 1): # Maximum number of available slots in a user's schedule for them to be # eligible for a limited availability match. self.max_available = max_available super().__init__(name=GENERATOR_LIMITED_SCHEDULES) + def create_matches(self, users_availability: Dict) -> List[Match]: + matched_users = [] + for userid_tuple, avail in users_availability.items(): + metadata = MatchMetadata( + generator=GENERATOR_LIMITED_SCHEDULES, availability=avail + ) + users = set(userid_tuple) + match = Match(users=users, metadata=metadata) + matched_users.append(match) + return matched_users + def generate(self, inp: MatchingInput) -> Iterator[Match]: - # TODO: Implement your generator - inp.logger.info("Luke Arrington was here!") - yield from [] + # get limited availability users + limited_availability = [] + for user in inp.users: + if len(user.schedule) <= self.max_available: + limited_availability.append(user) + + users_availability: Dict[Tuple, List] = {} + # compare limited users to all users + for limited_user in limited_availability: + for user in inp.users: + userid_tuple = (limited_user.uid, user.uid) + common_avail = [] + + if limited_user.uid == user.uid: + continue + + for l_avail in limited_user.schedule: + for avail in user.schedule: + # if the availabilities in limited user schedule and + # other user schedule are the same, then we have a match + if l_avail == avail: + common_avail.append(avail) + + if len(common_avail) >= 1: + users_availability[userid_tuple] = common_avail + + matches = self.create_matches(users_availability) + + yield from matches diff --git a/pipeline/matching/generators/limited_schedules_test.py b/pipeline/matching/generators/limited_schedules_test.py index 2aa7a822..70f763bb 100644 --- a/pipeline/matching/generators/limited_schedules_test.py +++ b/pipeline/matching/generators/limited_schedules_test.py @@ -28,9 +28,9 @@ def test_example(): displayName="A", schedule=[availability_1, availability_2, availability_3], ), - User(uid="2", displayName="B", interests=[availability_3]), + User(uid="2", displayName="B", schedule=[availability_3]), User( - uid="2", + uid="3", displayName="C", schedule=[availability_1, availability_2, availability_3], ), @@ -46,20 +46,55 @@ def test_example(): users={"1", "2"}, metadata=MatchMetadata( generator="limitedSchedulesGenerator", - limitedAvailability=[availability_3], + availability=[availability_3], ), ), Match( users={"2", "3"}, metadata=MatchMetadata( generator="limitedSchedulesGenerator", - limitedAvailability=[availability_3], + availability=[availability_3], ), ), ] - # TODO: Uncomment this assertion and delete the empty list assert - # assert actual == expected - assert actual == [] + + assert actual == expected # TODO: Add more test cases for your logic +# no limited available users +# multiple limited available users +# max available greater than 1 +# all limited available users? + + +def test_create_matches(): + # Part 1: Set up inputs + users_availability = { + (1, 2): [Availability(day="Mon", hour=9)], + (1, 3): [Availability(day="Tue", hour=13)], + } + + # Part 2: Get actual output + generator = LimitedSchedulesGenerator() + actual = generator.create_matches(users_availability) + + # Part 3: Define expected outputs and compare to actual + expected = [ + Match( + users={1, 2}, + metadata=MatchMetadata( + generator="limitedSchedulesGenerator", + availability=[Availability(day="Mon", hour=9)], + ), + ), + Match( + users={1, 3}, + metadata=MatchMetadata( + generator="limitedSchedulesGenerator", + availability=[Availability(day="Tue", hour=13)], + ), + ), + ] + print("Actual:", actual) + assert actual == expected