Skip to content

Commit 06995c6

Browse files
committed
Tweak time spent at space calculation
1 parent 3b587a9 commit 06995c6

File tree

2 files changed

+24
-17
lines changed

2 files changed

+24
-17
lines changed

api/src/tasks/delegate.py

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,9 @@ class MemberTaskInfo:
236236
# IDs of courses that this member has completed
237237
completed_courses: Set[int]
238238

239-
# Number of hours spent at the space since the day after the last task was either assigned or completed
239+
# Number of hours spent at the space since the day after the last task was completed
240240
# If the member has never completed a task, this will be a very large value.
241-
time_at_space_since_last_task: timedelta = field(
241+
time_at_space_since_last_task_completed: timedelta = field(
242242
serializer=lambda td: td.total_seconds(), deserializer=lambda seconds: timedelta(seconds=seconds)
243243
)
244244

@@ -377,22 +377,28 @@ def from_member(member_id: int, now: datetime) -> "MemberTaskInfo":
377377
if last_completed_task is not None:
378378
assert len(last_assigned_tasks) > 0
379379

380-
if last_assigned_tasks:
381-
day_after_last_task = last_assigned_tasks[0].created_at
382-
day_after_last_task += timedelta(days=1)
383-
day_after_last_task.replace(hour=0, minute=0, second=0, microsecond=0)
380+
if last_completed_task:
381+
after_last_task = last_completed_task.created_at
382+
# Start counting time spent at the space from when the last task was completed, plus some buffer time based on the task size.
383+
# 1. A member should never be automatically be delegated a task twice in a day
384+
# 2. If a member spends a lot of time at the space after completing a task, they should get a new task on their next visit
385+
# 3. If they don't spend much time at the space after completing a task, the may not get a new task on their next visit
386+
# 4. Larger tasks should have more buffer time, since they likely took more time and effort to complete.
387+
# 5. Trivial tasks should make the member get a new task immediately.
388+
after_last_task += TASK_SIZE_TO_TIME.get(last_completed_task.task_size, timedelta())
389+
# day_after_last_task += timedelta(days=1)
390+
# day_after_last_task.replace(hour=0, minute=0, second=0, microsecond=0)
384391

385-
# Count all visits after the day after the last task was assigned or completed.
386392
# and before the current time minus some margin to avoid counting ongoing visits.
387393
# This prevents us from assigning a task in the middle of a visit, instead of at the start.
388-
visits = visit_events_by_member_id(day_after_last_task, now - timedelta(hours=18), member_id=member_id).get(
394+
visits = visit_events_by_member_id(after_last_task, now - timedelta(hours=18), member_id=member_id).get(
389395
member_id, []
390396
)
391-
time_at_space_since_last_task = timedelta()
397+
time_at_space_since_last_task_completed = timedelta()
392398
for _, duration in visits:
393-
time_at_space_since_last_task += duration
399+
time_at_space_since_last_task_completed += duration
394400
else:
395-
time_at_space_since_last_task = timedelta(days=365 * 10) # A large value representing "infinity"
401+
time_at_space_since_last_task_completed = timedelta(days=365 * 10) # A large value representing "infinity"
396402

397403
purchased_product_time_cutoff = now - timedelta(days=365)
398404
purchased_product_count_by_name = {}
@@ -494,7 +500,7 @@ def from_member(member_id: int, now: datetime) -> "MemberTaskInfo":
494500
purchased_product_count_by_name=purchased_product_count_by_name,
495501
completed_card_ids=completed_card_ids,
496502
completed_card_names=completed_card_names,
497-
time_at_space_since_last_task=time_at_space_since_last_task,
503+
time_at_space_since_last_task_completed=time_at_space_since_last_task_completed,
498504
preferred_rooms=preferred_rooms,
499505
self_reported_skill_level=self_reported_skill_level,
500506
completed_courses=completed_courses,
@@ -1144,7 +1150,7 @@ def member_recently_received_task(ctx: TaskContext) -> bool:
11441150
# If a member has completed a task recently, don't assign them another one too soon.
11451151
# The wait depends on the size of the task
11461152
if ctx.member.last_completed_task is not None:
1147-
if ctx.member.time_at_space_since_last_task < TASK_SIZE_TO_TIME[ctx.member.last_completed_task.size]:
1153+
if ctx.member.time_at_space_since_last_task_completed < TASK_SIZE_TO_TIME[ctx.member.last_completed_task.size]:
11481154
return True
11491155

11501156
last_assigned_task = ctx.member.last_assigned_tasks[0] if ctx.member.last_assigned_tasks else None
@@ -1273,9 +1279,9 @@ def score_calculation_summary(self, line_prefix: str = "", column_width: int = 0
12731279
current_score = op.value
12741280
lines.append(f"{line_prefix}= {v_str} => {current_score:.2f}")
12751281

1276-
assert (
1277-
abs(current_score - self.score) < 0.0001
1278-
), f"Score calculation mismatch: calculated {current_score}, expected {self.score}"
1282+
assert abs(current_score - self.score) < 0.0001, (
1283+
f"Score calculation mismatch: calculated {current_score}, expected {self.score}"
1284+
)
12791285
return "\n".join(lines)
12801286

12811287

api/src/tasks/views.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ def get_member_task_info(member_id: int) -> dict:
139139
"preferred_rooms": sorted(member_info.preferred_rooms) if member_info.preferred_rooms else None,
140140
"self_reported_skill_level": member_info.self_reported_skill_level,
141141
"completed_tasks_by_label": sorted_completed_by_label,
142-
"time_at_space_since_last_task_hours": member_info.time_at_space_since_last_task.total_seconds() / 3600,
142+
"time_at_space_since_last_task_hours": member_info.time_at_space_since_last_task_completed.total_seconds()
143+
/ 3600,
143144
"total_completed_tasks": member_info.total_completed_tasks,
144145
}
145146

0 commit comments

Comments
 (0)