Coverage for src/couchers/reranker.py: 90%

20 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-08-28 14:55 +0000

1from datetime import timedelta 

2from itertools import zip_longest 

3 

4from couchers.utils import now, to_aware_datetime 

5from proto import api_pb2, search_pb2 

6 

7 

8def reranker(users: [search_pb2.SearchUser]) -> [search_pb2.SearchUser]: 

9 """ 

10 Given a list of users that are about to be returned in a search, reranks (re-orders) them better. 

11 """ 

12 

13 # this is our reranker v0: it just reorders users to be in a striped newbie/intermediate/experienced_host fashion 

14 boost_newbies, experienced_host, others = [], [], [] 

15 for user in users: 

16 if user.num_references > 3: 

17 experienced_host.append(user) 

18 elif ( 

19 user.num_references == 0 

20 and user.has_completed_my_home 

21 and user.hosting_status == api_pb2.HOSTING_STATUS_CAN_HOST 

22 and now() - to_aware_datetime(user.joined) < timedelta(days=180) 

23 ): 

24 boost_newbies.append(user) 

25 else: 

26 others.append(user) 

27 

28 # now we're going to rerank boost_newbies by joined date 

29 boost_newbies.sort(key=lambda user: to_aware_datetime(user.joined), reverse=True) 

30 

31 reconstructed_users = [] 

32 for users_from_groups in zip_longest(boost_newbies, experienced_host, others): 

33 for user in users_from_groups: 

34 if user is not None: 

35 reconstructed_users.append(user) 

36 

37 assert len(reconstructed_users) == len(users) 

38 

39 return reconstructed_users