repogym report

generated 2026-09-22 12:07 UTC · 5 runs
5runs
5passed
100%pass rate
1.000mean score
0errors

Leaderboard

agenttaskspassedpass ratemean scoremean steps
golden55100%1.0001.0

Runs

taskagentscorepassstepstimedetails
bugfix-mediangolden1.00✓10.4s
constraints 1.00
tests 1.00
patch (1 files)
diff --git a/stats.py b/stats.py
index 4bcbfa2..79ca32a 100644
--- a/stats.py
+++ b/stats.py
@@ -23,7 +23,7 @@ def median(values: Sequence[float]) -> float:
     mid = n // 2
     if n % 2 == 1:
         return ordered[mid]
-    return ordered[mid]
+    return (ordered[mid - 1] + ordered[mid]) / 2
 
 
 def variance(values: Sequence[float]) -> float:
bugfix-node-slugifygolden1.00✓10.4s
constraints 1.00
tests 1.00
patch (1 files)
diff --git a/slugify.js b/slugify.js
index 34f06e3..e30a4f7 100644
--- a/slugify.js
+++ b/slugify.js
@@ -21,7 +21,8 @@ function slugify(text, options = {}) {
     .replace(/[̀-ͯ]/g, '')
     .toLowerCase()
     .replace(/[^a-z0-9]+/g, separator);
-  slug = slug.replace(new RegExp(`^${escapeRegExp(separator)}`), '');
+  const sep = escapeRegExp(separator);
+  slug = slug.replace(new RegExp(`^(?:${sep})+|(?:${sep})+$`, 'g'), '');
   if (maxLength && slug.length > maxLength) {
     slug = slug.slice(0, maxLength);
     const idx = slug.lastIndexOf(separator);
feature-ratelimitergolden1.00✓10.4s
constraints 1.00
tests 1.00
quality 1.00
patch (1 files)
diff --git a/ratelimit.py b/ratelimit.py
index db31397..2b38883 100644
--- a/ratelimit.py
+++ b/ratelimit.py
@@ -56,3 +56,65 @@ class SlidingWindowLimiter:
         if len(events) >= self.limit:
             raise RateLimitExceeded(key, events[0] + self.window - now)
         events.append(now)
+
+
+class TokenBucket:
+    """Classic token bucket: ``capacity`` tokens, refilled at ``refill_rate`` per second.
+
+    Each key has its own bucket that starts full.  Tokens accumulate continuously
+    (fractional tokens are tracked) but never exceed ``capacity``.
+    """
+
+    def __init__(
+        self, capacity: float, refill_rate: float, clock: Optional[Callable[[], float]] = None
+    ):
+        if capacity <= 0:
+            raise ValueError("capacity must be positive")
+        if refill_rate <= 0:
+            raise ValueError("refill_rate must be positive")
+        self.capacity = float(capacity)
+        self.refill_rate = float(refill_rate)
+        self.clock = clock or time.monotonic
+        self._state: Dict[str, "tuple[float, float]"] = {}
+
+    def _refill(self, key: str) -> float:
+        now = self.clock()
+        tokens, last = self._state.get(key, (self.capacity, now))
+        tokens = min(self.capacity, tokens + (now - last) * self.refill_rate)
+        self._state[key] = (tokens, now)
+        return tokens
+
+    def tokens(self, key: str) -> float:
+        """Current token balance for ``key`` (after refilling)."""
+        return self._refill(key)
+
+    def try_acquire(self, key: str, tokens: float = 1.0) -> bool:
+        """Consume ``tokens`` if available and return whether it succeeded."""
+        if tokens <= 0:
+            raise ValueError("tokens must be positive")
+        if tokens > self.capacity:
+            raise ValueError("cannot request more tokens than the bucket capacity")
+        available = self._refill(key)
+        if available < tokens:
+            return False
+        self._state[key] = (available - tokens, self._state[key][1])
+        return True
+
+    def acquire(self, key: str, tokens: float = 1.0) -> None:
+        """Like :meth:`try_acquire` but raises :class:`RateLimitExceeded` with ``retry_after``."""
+        if tokens <= 0:
+            raise ValueError("tokens must be positive")
+        if tokens > self.capacity:
+            raise ValueError("cannot request more tokens than the bucket capacity")
+        available = self._refill(key)
+        if available < tokens:
+            retry_after = (tokens - available) / self.refill_rate
+            raise RateLimitExceeded(key, retry_after)
+        self._state[key] = (available - tokens, self._state[key][1])
+
+
+__all__ = [
+    "RateLimitExceeded",
+    "SlidingWindowLimiter",
+    "TokenBucket",
+]
perf-dedupe-recordsgolden1.00✓19.5s
constraints 1.00
tests 1.00
perf 1.00
patch (1 files)
diff --git a/dedupe.py b/dedupe.py
index 83ce1d4..2d371be 100644
--- a/dedupe.py
+++ b/dedupe.py
@@ -2,7 +2,7 @@
 
 from __future__ import annotations
 
-from typing import Dict, Iterable, List
+from typing import Dict, Iterable, List, Set
 
 
 def normalize_email(email: str) -> str:
@@ -19,14 +19,11 @@ def dedupe_records(records: Iterable[Dict[str, str]]) -> List[Dict[str, str]]:
     The *first* occurrence of an email wins and the original ordering is kept.
     """
     unique: List[Dict[str, str]] = []
+    seen: Set[str] = set()
     for record in records:
         email = normalize_email(record["email"])
-        duplicate = False
-        for existing in unique:
-            if normalize_email(existing["email"]) == email:
-                duplicate = True
-                break
-        if not duplicate:
+        if email not in seen:
+            seen.add(email)
             unique.append(record)
     return unique
 
@@ -34,11 +31,12 @@ def dedupe_records(records: Iterable[Dict[str, str]]) -> List[Dict[str, str]]:
 def merge_names(records: Iterable[Dict[str, str]]) -> Dict[str, List[str]]:
     """Map each normalised email to the distinct normalised names seen for it."""
     result: Dict[str, List[str]] = {}
+    seen: Dict[str, Set[str]] = {}
     for record in records:
         email = normalize_email(record["email"])
         name = normalize_name(record["name"])
-        names = result.get(email, [])
-        if name not in names:
-            names = names + [name]
-        result[email] = names
+        names_seen = seen.setdefault(email, set())
+        if name not in names_seen:
+            names_seen.add(name)
+            result.setdefault(email, []).append(name)
     return result
refactor-order-pipelinegolden1.00✓10.4s
constraints 1.00
tests 1.00
quality 1.00
patch (1 files)
diff --git a/orders.py b/orders.py
index d79f90e..681f88e 100644
--- a/orders.py
+++ b/orders.py
@@ -3,7 +3,7 @@
 from __future__ import annotations
 
 from dataclasses import dataclass, field
-from typing import Dict, List, Optional
+from typing import Callable, Dict, List, Optional
 
 
 @dataclass
@@ -13,6 +13,10 @@ class LineItem:
     unit_price: float
     category: str = "general"
 
+    @property
+    def line_total(self) -> float:
+        return self.quantity * self.unit_price
+
 
 @dataclass
 class Order:
@@ -26,79 +30,99 @@ class Order:
 
 TAX_RATES = {"US": 0.07, "CA": 0.13, "GB": 0.20, "DE": 0.19}
 FREE_SHIPPING_THRESHOLD = 100.0
+BASE_SHIPPING = {"US": 5.99, "CA": 9.99, "GB": 14.99, "DE": 14.99}
+DEFAULT_SHIPPING = 24.99
+HEAVY_SURCHARGE = 20.0
+HEAVY_CATEGORIES = {"furniture", "appliance"}
+TAX_EXEMPT_CATEGORIES = {"grocery", "book"}
+LOYALTY_RATES = {"silver": 0.02, "gold": 0.05, "platinum": 0.10}
+GIFT_FEE = 2.0
 
 
-def process_order(order: Order) -> Dict[str, float]:
-    """Compute subtotal, discounts, shipping, tax and total for an order."""
+def _validate(order: Order) -> None:
     if not order.items:
         raise ValueError("order has no items")
-    subtotal = 0.0
     for item in order.items:
         if item.quantity <= 0:
             raise ValueError(f"invalid quantity for {item.sku}")
         if item.unit_price < 0:
             raise ValueError(f"invalid price for {item.sku}")
-        subtotal = subtotal + item.quantity * item.unit_price
-    discount = 0.0
-    if order.coupon is not None:
-        if order.coupon == "SAVE10":
-            discount = discount + subtotal * 0.10
-        elif order.coupon == "SAVE20":
-            if subtotal >= 50:
-                discount = discount + subtotal * 0.20
-            else:
-                discount = discount + subtotal * 0.10
-        elif order.coupon == "FLAT5":
-            if subtotal > 5:
-                discount = discount + 5.0
-            else:
-                discount = discount + subtotal
-        elif order.coupon.startswith("BOGO-"):
-            sku = order.coupon[5:]
-            for item in order.items:
-                if item.sku == sku and item.quantity >= 2:
-                    discount = discount + (item.quantity // 2) * item.unit_price
-        else:
-            raise ValueError("unknown coupon")
-    if order.loyalty_tier == "gold":
-        discount = discount + (subtotal - discount) * 0.05
-    elif order.loyalty_tier == "platinum":
-        discount = discount + (subtotal - discount) * 0.10
-    elif order.loyalty_tier == "silver":
-        discount = discount + (subtotal - discount) * 0.02
-    if discount > subtotal:
-        discount = subtotal
+
+
+def _subtotal(order: Order) -> float:
+    return sum(item.line_total for item in order.items)
+
+
+def _coupon_save20(order: Order, subtotal: float) -> float:
+    return subtotal * (0.20 if subtotal >= 50 else 0.10)
+
+
+def _coupon_flat5(order: Order, subtotal: float) -> float:
+    return min(5.0, subtotal)
+
+
+def _coupon_bogo(order: Order, subtotal: float) -> float:
+    sku = (order.coupon or "")[5:]
+    return sum(
+        (item.quantity // 2) * item.unit_price
+        for item in order.items
+        if item.sku == sku and item.quantity >= 2
+    )
+
+
+COUPONS: Dict[str, Callable[[Order, float], float]] = {
+    "SAVE10": lambda order, subtotal: subtotal * 0.10,
+    "SAVE20": _coupon_save20,
+    "FLAT5": _coupon_flat5,
+}
+
+
+def _coupon_discount(order: Order, subtotal: float) -> float:
+    if order.coupon is None:
+        return 0.0
+    if order.coupon.startswith("BOGO-"):
+        return _coupon_bogo(order, subtotal)
+    handler = COUPONS.get(order.coupon)
+    if handler is None:
+        raise ValueError("unknown coupon")
+    return handler(order, subtotal)
+
+
+def _discount(order: Order, subtotal: float) -> float:
+    discount = _coupon_discount(order, subtotal)
+    discount += (subtotal - discount) * LOYALTY_RATES.get(order.loyalty_tier, 0.0)
+    return min(discount, subtotal)
+
+
+def _shipping(order: Order, discounted: float) -> float:
+    if order.loyalty_tier == "platinum" or discounted >= FREE_SHIPPING_THRESHOLD:
+        return 0.0
+    shipping = BASE_SHIPPING.get(order.country, DEFAULT_SHIPPING)
+    if any(item.category in HEAVY_CATEGORIES for item in order.items):
+        shipping += HEAVY_SURCHARGE
+    return shipping
+
+
+def _tax(order: Order, subtotal: float, discounted: float) -> float:
+    rate = TAX_RATES.get(order.country)
+    if rate is None:
+        return 0.0
+    ratio = discounted / subtotal if subtotal else 0.0
+    exempt = sum(item.line_total * ratio for item in order.items if item.category in TAX_EXEMPT_CATEGORIES)
+    return max(0.0, discounted - exempt) * rate
+
+
+def process_order(order: Order) -> Dict[str, float]:
+    """Compute subtotal, discounts, shipping, tax and total for an order."""
+    _validate(order)
+    subtotal = _subtotal(order)
+    discount = _discount(order, subtotal)
     discounted = subtotal - discount
-    shipping = 0.0
-    if discounted < FREE_SHIPPING_THRESHOLD:
-        if order.country == "US":
-            shipping = 5.99
-        elif order.country == "CA":
-            shipping = 9.99
-        elif order.country == "GB" or order.country == "DE":
-            shipping = 14.99
-        else:
-            shipping = 24.99
-        heavy = False
-        for item in order.items:
-            if item.category == "furniture" or item.category == "appliance":
-                heavy = True
-        if heavy:
-            shipping = shipping + 20.0
-    if order.loyalty_tier == "platinum":
-        shipping = 0.0
-    tax = 0.0
-    if order.country in TAX_RATES:
-        taxable = discounted
-        for item in order.items:
-            if item.category == "grocery" or item.category == "book":
-                taxable = taxable - item.quantity * item.unit_price * (discounted / subtotal if subtotal else 0)
-        if taxable < 0:
-            taxable = 0.0
-        tax = taxable * TAX_RATES[order.country]
+    shipping = _shipping(order, discounted)
+    tax = _tax(order, subtotal, discounted)
     total = discounted + shipping + tax
-    if "gift" in order.notes and order.notes["gift"] == "yes":
-        total = total + 2.0
+    if order.notes.get("gift") == "yes":
+        total += GIFT_FEE
     return {
         "subtotal": round(subtotal, 2),
         "discount": round(discount, 2),