Coverage for pybeepop/beepop/daterangevalues.py: 50%
50 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 13:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 13:34 +0000
1"""
2Date Range Values Module for BeePop+ Environmental Simulation
4This module provides temporal parameter management for the BeePop+ bee colony simulation.
5It manages parameter values that vary over specific date ranges, supporting
6time-dependent environmental conditions and management interventions.
8The DateRangeValues system enables dynamic parameter changes throughout simulations,
9allowing for seasonal variations, treatment schedules, and environmental events
10that affect colony development over time.
12Classes:
13 DateRangeItem: Represents a single parameter value valid within a date range
14 DateRangeValues: Collection manager for time-dependent parameter values
15"""
17from datetime import datetime
18from typing import List, Optional
21class DateRangeItem:
22 """
23 Single time-dependent parameter value for BeePop+ environmental simulation.
25 Represents a parameter value that is valid within a specific date range,
26 enabling temporal variations in environmental conditions, management
27 practices, or other simulation parameters that change over time.
29 Attributes:
30 start_time (datetime): Beginning of the valid date range (inclusive)
31 end_time (datetime): End of the valid date range (inclusive)
32 value (float): Parameter value to apply during this date range
33 """
35 def __init__(self, start_time: datetime, end_time: datetime, value: float):
36 self.start_time = start_time
37 self.end_time = end_time
38 self.value = value
41class DateRangeValues:
42 """
43 Temporal parameter collection manager for BeePop+ environmental simulation.
45 Manages collections of time-dependent parameter values that can change over
46 specific date ranges during colony simulation. Supports environmental
47 variations, treatment schedules, seasonal effects, and other temporal
48 changes that affect bee colony development.
50 The system implements exact C++ compatibility for date range calculations.
52 Attributes:
53 items (List[DateRangeItem]): Collection of date-ranged parameter values
54 enabled (bool): Whether this parameter collection is active in simulation
55 file_format_version (int): Deprecated
56 """
58 def __init__(self):
59 self.items: List[DateRangeItem] = []
60 self.enabled: bool = True
61 self.file_format_version: int = 1
63 def add_item(self, start_time: datetime, end_time: datetime, value: float):
64 self.items.append(DateRangeItem(start_time, end_time, value))
66 def get_item(self, index: int) -> Optional[DateRangeItem]:
67 if 0 <= index < len(self.items):
68 return self.items[index]
69 return None
71 def get_active_item(self, the_date: datetime) -> Optional[DateRangeItem]:
72 """
73 Find the first item where the_date falls within the date range.
74 Implements the exact C++ logic from daterangevalues.cpp lines 67-98.
75 """
76 for item in self.items:
77 # Normalize dates to midnight (matching C++ VAR_DATEVALUEONLY behavior)
78 start_normalized = item.start_time.replace(
79 hour=0, minute=0, second=0, microsecond=0
80 )
81 end_normalized = item.end_time.replace(
82 hour=0, minute=0, second=0, microsecond=0
83 )
84 date_normalized = the_date.replace(
85 hour=0, minute=0, second=0, microsecond=0
86 )
88 # Calculate time spans exactly like C++ COleDateTimeSpan
89 time_since_start = date_normalized - start_normalized
90 time_till_end = end_normalized - date_normalized
92 # Convert to days (matching C++ GetDays() method)
93 time_since_start_days = time_since_start.days
94 time_till_end_days = time_till_end.days
96 # Apply exact C++ logic: (TimeSinceStart.GetDays() > 0) && (TimeTillEnd.GetDays() > 0)
97 if time_since_start_days > 0 and time_till_end_days > 0:
98 return item
100 return None
102 def get_active_value(self, the_date: datetime) -> Optional[float]:
103 item = self.get_active_item(the_date)
104 return item.value if item else None
106 def delete_item(self, index: int):
107 if 0 <= index < len(self.items):
108 del self.items[index]
110 def get_count(self) -> int:
111 return len(self.items)
113 def clear_all(self):
114 self.items.clear()
116 def is_enabled(self) -> bool:
117 return self.enabled
119 def set_enabled(self, enable_val: bool):
120 self.enabled = enable_val
122 def set_file_format_version(self, version: int):
123 self.file_format_version = version
125 def copy(self, destination: "DateRangeValues"):
126 destination.items = [
127 DateRangeItem(item.start_time, item.end_time, item.value)
128 for item in self.items
129 ]
130 destination.enabled = self.enabled
131 destination.file_format_version = self.file_format_version