|
36 | 36 | _logger = logging.getLogger(__name__) |
37 | 37 |
|
38 | 38 |
|
| 39 | +# Just 20 lines of code in this function, but unfortunately 8 of those are return |
| 40 | +# statements, and that's too many for pylint. |
| 41 | +def _clamp_to_bounds( # pylint: disable=too-many-return-statements |
| 42 | + value: Power, |
| 43 | + lower_bound: Power, |
| 44 | + upper_bound: Power, |
| 45 | + exclusion_bounds: timeseries.Bounds[Power] | None, |
| 46 | +) -> Power: |
| 47 | + """Clamp the given value to the given bounds. |
| 48 | +
|
| 49 | + Args: |
| 50 | + value: The value to clamp. |
| 51 | + lower_bound: The lower bound to clamp to. |
| 52 | + upper_bound: The upper bound to clamp to. |
| 53 | + exclusion_bounds: The exclusion bounds to clamp outside of. |
| 54 | +
|
| 55 | + Returns: |
| 56 | + The clamped value. |
| 57 | + """ |
| 58 | + # If the given bounds are within the exclusion bounds, return zero. |
| 59 | + # |
| 60 | + # And if the given bounds overlap with the exclusion bounds on one side, and the |
| 61 | + # given power is in that overlap region, clamp it to the exclusion bounds on that |
| 62 | + # side. |
| 63 | + if exclusion_bounds is not None: |
| 64 | + match _check_exclusion_bounds_overlap( |
| 65 | + lower_bound, upper_bound, exclusion_bounds |
| 66 | + ): |
| 67 | + case (True, True): |
| 68 | + return Power.zero() |
| 69 | + case (True, False): |
| 70 | + if value < exclusion_bounds.upper: |
| 71 | + return exclusion_bounds.upper |
| 72 | + case (False, True): |
| 73 | + if value > exclusion_bounds.lower: |
| 74 | + return exclusion_bounds.lower |
| 75 | + |
| 76 | + # If the given value is outside the given bounds, clamp it to the closest bound. |
| 77 | + if value < lower_bound: |
| 78 | + return lower_bound |
| 79 | + if value > upper_bound: |
| 80 | + return upper_bound |
| 81 | + |
| 82 | + # If the given value is within the exclusion bounds and the exclusion bounds are |
| 83 | + # within the given bounds, clamp the given value to the closest exclusion bound. |
| 84 | + if exclusion_bounds is not None: |
| 85 | + if exclusion_bounds.lower < value < exclusion_bounds.upper: |
| 86 | + if value - exclusion_bounds.lower < exclusion_bounds.upper - value: |
| 87 | + return exclusion_bounds.lower |
| 88 | + return exclusion_bounds.upper |
| 89 | + |
| 90 | + return value |
| 91 | + |
| 92 | + |
39 | 93 | def _check_exclusion_bounds_overlap( |
40 | 94 | lower_bound: Power, |
41 | 95 | upper_bound: Power, |
@@ -148,12 +202,12 @@ def _calc_target_power( |
148 | 202 | if upper_bound < lower_bound: |
149 | 203 | break |
150 | 204 | if next_proposal.preferred_power: |
151 | | - if next_proposal.preferred_power > upper_bound: |
152 | | - target_power = upper_bound |
153 | | - elif next_proposal.preferred_power < lower_bound: |
154 | | - target_power = lower_bound |
155 | | - else: |
156 | | - target_power = next_proposal.preferred_power |
| 205 | + target_power = _clamp_to_bounds( |
| 206 | + next_proposal.preferred_power, |
| 207 | + lower_bound, |
| 208 | + upper_bound, |
| 209 | + exclusion_bounds, |
| 210 | + ) |
157 | 211 | proposal_lower, proposal_upper = ( |
158 | 212 | next_proposal.bounds.lower or lower_bound, |
159 | 213 | next_proposal.bounds.upper or upper_bound, |
@@ -308,10 +362,8 @@ def get_status( |
308 | 362 | calc_lower_bound = max(lower_bound, proposal_lower) |
309 | 363 | calc_upper_bound = min(upper_bound, proposal_upper) |
310 | 364 | if calc_lower_bound <= calc_upper_bound: |
311 | | - lower_bound = calc_lower_bound |
312 | | - upper_bound = calc_upper_bound |
313 | 365 | lower_bound, upper_bound = _adjust_exclusion_bounds( |
314 | | - lower_bound, upper_bound, exclusion_bounds |
| 366 | + calc_lower_bound, calc_upper_bound, exclusion_bounds |
315 | 367 | ) |
316 | 368 | else: |
317 | 369 | break |
|
0 commit comments