๐Ÿ’ป Exercise: Exercise: A retry budget

๐Ÿ“ Instructions

Implement a RetryBudget class constructed with max_retries. Provide can_retry() returning True while fewer than max_retries have been used, consume() that uses one retry and returns True if one was available (else False), and a remaining property. This is the bounded counter at the core of a reflection loop. Standard library only.

๐Ÿงช Initial Code / Tests

๐Ÿ“„ evaluate.py
from unittest import TestCase
from exercise import RetryBudget


class Evaluate(TestCase):
    def test_can_retry_initially(self):
        self.assertTrue(RetryBudget(2).can_retry())

    def test_consume_returns_true_while_available(self):
        b = RetryBudget(2)
        self.assertTrue(b.consume() and b.consume())

    def test_consume_false_past_budget(self):
        b = RetryBudget(1); b.consume()
        self.assertFalse(b.consume())

    def test_remaining_counts_down(self):
        b = RetryBudget(3); b.consume()
        self.assertEqual(b.remaining, 2)

โœ… Solutions

๐Ÿ“„ exercise.py
class RetryBudget:
    def __init__(self, max_retries):
        self.max_retries = max_retries
        self.used = 0

    def can_retry(self):
        return self.used < self.max_retries

    def consume(self):
        if not self.can_retry():
            return False
        self.used += 1
        return True

    @property
    def remaining(self):
        return max(0, self.max_retries - self.used)