Source code for app.engine.constantEffortStrategy

""" """

from app.core.container import Container
from app.engine.base_strategy import BaseStrategy
from app.engine.strategy_registry import register_strategy


[docs] @register_strategy(id="constantEffortStrategy", version="0.0.1") class ConstantEffortStrategy(BaseStrategy): # noqa def __init__(self): super().__init__( strategy_name="ConstantEffortStrategy", strategy_description="A strategy that rewards consistent effort over 5-minute intervals.", strategy_name_slug="constant_effort", strategy_version="0.0.1", variable_basic_points=1, variable_bonus_points=10, ) self.task_service = Container.task_service() self.user_points_service = Container.user_points_service() self.user_points_analytics_service = Container.user_points_analytics_service() self.default_points_task_campaign = 1 self.variable_basic_points = 1 self.variable_bonus_points = 10 self.variable_constant_effort_interval_minutes = 5 self.variable_max_points = 100
[docs] async def calculate_points( self, externalGameId, externalTaskId, externalUserId, data=None ): """ Award points for sustained effort within a rolling time window. If the user already has measurements in the last ``variable_constant_effort_interval_minutes`` minutes, the award scales with how consistent they have been (``ConstantEffortReward``); otherwise a flat basic point is granted (``BasicReward``). Args: externalGameId: External identifier of the game. externalTaskId: External identifier of the task. externalUserId: External identifier of the user. data: Optional event payload (unused by this strategy). Returns: tuple[int, str]: The points to award and the case name describing which branch produced them. """ task_measurements_count = self.user_points_analytics_service.get_user_task_measurements_count_the_last_seconds( externalTaskId, externalUserId, self.variable_constant_effort_interval_minutes * 60, ) self.debug_print(f"task_measurements_count: {task_measurements_count}") if task_measurements_count > 0: points = self._calculate_points_from_consistency( task_measurements_count + 1 ) return points, "ConstantEffortReward" return 1, "BasicReward"
def _calculate_points_from_consistency(self, consistent_effort_count): """ Map a consistent-effort streak to a bounded point value. Args: consistent_effort_count: Number of consecutive in-window measurements (including the current one). Returns: int: Points normalized against ``variable_max_points`` and clamped to the range ``[1, variable_max_points]``. """ normalized_points = (consistent_effort_count / self.variable_max_points) * 100 return min(max(int(normalized_points), 1), self.variable_max_points)