-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[HNT-405] Remove blocked topics from sections #791
[HNT-405] Remove blocked topics from sections #791
Conversation
296289d
to
3493e69
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think it's worth it to cover more scenarios in some unit tests.
blocked_section_ids = {rs.sectionId for rs in request.sections if rs.isBlocked} | ||
recommendations = [ | ||
r for r in recommendations if r.topic and r.topic.value not in blocked_section_ids | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think it would be nice to abstract this to a helper function with a few unit tests.
- verify it's only removing recommendations matching a blocked section
- verify it does nothing if no sections are marked as blocked
- verify it handles recommendations without topics as expected (is the expectation that a recommendation without a topic be excluded here? also how do recommendations without a topic get in?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also - do you think it's worth skipping the list comprehension (i think that's what it's called?) on line 329 if blocked_section_ids
has a length of 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I was curious what the performance impact was, so I did a quick benchmark:
import timeit
setup_code = '''
class DummyTopic:
def __init__(self, value):
self.value = value
class DummyRec:
def __init__(self, topic):
self.topic = topic
# Create 10,000 dummy recommendations.
# For this benchmark, each recommendation has a DummyTopic.
recommendations = [DummyRec(DummyTopic("dummy")) for _ in range(1000)]
# blocked_section_ids is empty.
blocked_section_ids = set()
'''
stmt = '''
filtered = [r for r in recommendations if not r.topic or r.topic.value not in blocked_section_ids]
'''
# Run the list comprehension 1000 times and measure the total time.
iterations = 1000
total_time = timeit.timeit(stmt=stmt, setup=setup_code, number=iterations)
avg_time_ms = (total_time / iterations) * 1000
print(f"Average time per iteration: {avg_time_ms:.3f} ms")
Average time per iteration: 0.028 ms
Currently we have a few hundred recommendations. At the cost of a few microseconds, I would lean towards letting list comprehension handle the case of an empty list.
if feed: | ||
for recommendation in feed["recommendations"]: | ||
assert recommendation["topic"] not in blocked_topics | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to say - if the new logic in the above file is fully tested in a unit test, the only line of code this function would really be testing (that isn't already tested) is line 327 in the file above:
if request.sections:
for peace of mind this test isn't bad though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks much better. great tests and use of a static method!
@@ -311,6 +311,14 @@ async def get_time_sensitive_recommendations( | |||
general_feed = [r for r in recommendations if not r.isTimeSensitive] | |||
return general_feed, need_to_know_feed | |||
|
|||
@staticmethod | |||
def exclude_recommendations_from_blocked_sections(recommendations, requested_sections): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice use of a static method!
References
JIRA: HNT-405
Description
If a user blocks a section using the Follow/Block feature (e.g. Food, Politics), we remove recommendations with those topics from sections, including 'Popular Today'.
PR Review Checklist
Put an
x
in the boxes that apply[DISCO-####]
, and has the same title (if applicable)[load test: (abort|skip|warn)]
keywords are applied to the last commit message (if applicable)