الأبحاث · جولةُ البرمجة الأولى

CB-2-02 — كتابة ميزة جديدة · Python · متوسّط

جولةُ البرمجة الأولى · 2026-10-09 · GAIBRA v2.30.03 · واجبُ التشغيل

نتيجةُ الجولة

الترتيبالمتنافسالرمز أمام المحكّمالكلماتالاختباراتOpusGrokالمجموعالصدق (Opus · Grok)
1GAIBRAب2,16214/1494.095.094.511 · 12
2Claude Sonnetهـ1,13714/1493.090.091.510 · 11
3ChatGPTج68214/1482.083.082.58 · 10
4DeepSeekأ1,04014/1472.078.075.07 · 10
5Geminiد37014/1467.069.068.06 · 6

نصُّ السيناريو كما كتبه المولّد

We're building the cart module for a grocery e-commerce app. Marketing wants a "buy N get the M cheapest items free" promotion applied at checkout, among SKUs flagged as eligible. Write a single self-contained file with this exact function signature: Python def apply\_buy\_n\_get\_m\_free(cart: list\[dict], promo: dict) -> dict cart is a list of {"sku": str, "name": str, "unit\_price": float, "qty": int}. promo is {"buy": int, "free": int, "eligible\_skus": list\[str], "max\_free": int}. max\_free caps the total number of free units per checkout. If free is 0 or missing, nothing is discounted. Every full group of buy paid units among eligible items entitles the customer to free free units, taken from the cheapest eligible units in the cart. Tie-break: lower unit price first, then lower sku alphabetically. Ineligible SKUs are never discounted but count toward the response. Return {"lines": \[...], "free\_items": \[...], "total": float, "discount\_total": float} where each element of lines has the cart fields plus "line\_total" (paid qty × unit price) and "free\_qty". Amounts are in SAR with 2 decimal places, rounded half-up per line. total is the sum of line totals. free\_items lists the SKUs granted free with quantities. Example: Python cart = \[   {"sku": "MILK-1L", "name": "Milk 1L", "unit\_price": 6.50, "qty": 3},   {"sku": "BRD-WHT", "name": "White Bread", "unit\_price": 4.25, "qty": 2},   {"sku": "EGG-12", "name": "Eggs 12pc", "unit\_price": 12.00, "qty": 1}, ] promo = {"buy": 2, "free": 1, "eligible\_skus": \["MILK-1L", "BRD-WHT", "EGG-12"], "max\_free": 2} Expected: 4 paid units qualify for 2 free units (capped by max\_free); the two free units are BRD-WHT (cheapest). discount\_total = 8.50, total = 39.25. Constraints: Python 3.11+, standard library only (use decimal for money), deterministic output, no network or external files. Include a \_\_main\_\_ block that runs the example above and prints the result as JSON. Keep the whole file under 300 lines.

الردودُ الخمسة كما وصلت المحكّمين

الرمزُ هو ما رآه المحكّمان؛ والاسمُ كُشف بعد التحكيم.

بGAIBRA94.5 · 2,162 كلمة
The file reproduces your discount of 8.50. It asserts a total of 31.50 rather than the 39.25 in your brief, because 39.25 cannot follow from your own pricing rules. The reason is explained below. \# buy\_n\_get\_m\_free.py """Buy-N-get-M-cheapest-free promotion for a grocery cart (SAR, 2 dp, half-up). All money arithmetic uses decimal.Decimal. Floats exist only at the public boundary because the contract specifies them. Standard library only. """ import json import math from dataclasses import dataclass from decimal import ROUND\_HALF\_UP, Decimal from typing import Any CENT = Decimal("0.01") ZERO = Decimal("0") KEY\_SKU = "sku" KEY\_NAME = "name" KEY\_UNIT\_PRICE = "unit\_price" KEY\_QTY = "qty" CART\_FIELDS = (KEY\_SKU, KEY\_NAME, KEY\_UNIT\_PRICE, KEY\_QTY) KEY\_BUY = "buy" KEY\_FREE = "free" KEY\_ELIGIBLE = "eligible\_skus" KEY\_MAX\_FREE = "max\_free" PROMO\_REQUIRED\_FIELDS = (KEY\_BUY, KEY\_ELIGIBLE, KEY\_MAX\_FREE) KEY\_LINES = "lines" KEY\_FREE\_ITEMS = "free\_items" KEY\_TOTAL = "total" KEY\_DISCOUNT\_TOTAL = "discount\_total" KEY\_LINE\_TOTAL = "line\_total" KEY\_FREE\_QTY = "free\_qty" class PromotionInputError(ValueError): &#x20; """Raised when the cart or the promo violates the input contract.""" @dataclass(frozen=True, slots=True) class CartLine: &#x20; """One validated cart row; `position` preserves input order for output and tie-breaks.""" &#x20; position: int &#x20; sku: str &#x20; name: str &#x20; unit\_price: Decimal &#x20; qty: int @dataclass(frozen=True, slots=True) class BuyNGetMPromo: &#x20; """A validated, active promotion (free > 0).""" &#x20; buy: int &#x20; free: int &#x20; eligible\_skus: frozenset\[str] &#x20; max\_free: int def \_require\_int(value: Any, field: str, minimum: int) -> int: &#x20; """Return `value` if it is a genuine int >= minimum (bool rejected), else raise.""" &#x20; if isinstance(value, bool) or not isinstance(value, int): &#x20; raise PromotionInputError(f"{field} must be an int, got {type(value).\_\_name\_\_}") &#x20; if value < minimum: &#x20; raise PromotionInputError(f"{field} must be >= {minimum}, got {value}") &#x20; return value def \_require\_price(value: Any, field: str) -> Decimal: &#x20; """Convert a finite, non-negative int/float price to Decimal via its shortest repr.""" &#x20; if isinstance(value, bool) or not isinstance(value, (int, float)): &#x20; raise PromotionInputError(f"{field} must be a number, got {type(value).\_\_name\_\_}") &#x20; if isinstance(value, float) and not math.isfinite(value): &#x20; raise PromotionInputError(f"{field} must be finite, got {value}") &#x20; price = Decimal(str(value)) &#x20; if price < ZERO: &#x20; raise PromotionInputError(f"{field} must be >= 0, got {value}") &#x20; return price def \_round\_money(amount: Decimal) -> Decimal: &#x20; """Round to 2 decimal places, half-up.""" &#x20; return amount.quantize(CENT, rounding=ROUND\_HALF\_UP) def \_parse\_cart(cart: Any) -> list\[CartLine]: &#x20; """Validate every cart row; raise PromotionInputError naming the first bad field.""" &#x20; if not isinstance(cart, list): &#x20; raise PromotionInputError(f"cart must be a list, got {type(cart).\_\_name\_\_}") &#x20; lines: list\[CartLine] = \[] &#x20; for position, row in enumerate(cart): &#x20; where = f"cart\[{position}]" &#x20; if not isinstance(row, dict): &#x20; raise PromotionInputError(f"{where} must be a dict, got {type(row).\_\_name\_\_}") &#x20; missing = \[key for key in CART\_FIELDS if key not in row] &#x20; if missing: &#x20; raise PromotionInputError(f"{where} is missing {missing}") &#x20; sku, name = row\[KEY\_SKU], row\[KEY\_NAME] &#x20; if not isinstance(sku, str) or not sku.strip(): &#x20; raise PromotionInputError(f"{where}.sku must be a non-empty str") &#x20; if not isinstance(name, str): &#x20; raise PromotionInputError(f"{where}.name must be a str") &#x20; lines.append( &#x20; CartLine( &#x20; position=position, &#x20; sku=sku, &#x20; name=name, &#x20; unit\_price=\_require\_price(row\[KEY\_UNIT\_PRICE], f"{where}.unit\_price"), &#x20; qty=\_require\_int(row\[KEY\_QTY], f"{where}.qty", minimum=0), &#x20; ) &#x20; ) &#x20; return lines def \_parse\_promo(promo: Any) -> BuyNGetMPromo | None: &#x20; """Validate the promo; return None when `free` is 0 or missing (promotion inactive).""" &#x20; if not isinstance(promo, dict): &#x20; raise PromotionInputError(f"promo must be a dict, got {type(promo).\_\_name\_\_}") &#x20; raw\_free = promo.get(KEY\_FREE) &#x20; if raw\_free is None: &#x20; return None &#x20; free = \_require\_int(raw\_free, "promo.free", minimum=0) &#x20; if free == 0: &#x20; return None &#x20; missing = \[key for key in PROMO\_REQUIRED\_FIELDS if key not in promo] &#x20; if missing: &#x20; raise PromotionInputError(f"promo is missing {missing}") &#x20; eligible = promo\[KEY\_ELIGIBLE] &#x20; if not isinstance(eligible, list) or not all(isinstance(s, str) for s in eligible): &#x20; raise PromotionInputError("promo.eligible\_skus must be a list of str") &#x20; return BuyNGetMPromo( &#x20; buy=\_require\_int(promo\[KEY\_BUY], "promo.buy", minimum=1), &#x20; free=free, &#x20; eligible\_skus=frozenset(eligible), &#x20; max\_free=\_require\_int(promo\[KEY\_MAX\_FREE], "promo.max\_free", minimum=0), &#x20; ) def \_entitled\_free\_units(eligible\_units: int, buy: int, free: int) -> int: &#x20; """Largest F such that the (eligible\_units - F) paid units contain enough full &#x20; groups of `buy` to earn at least F free units. Applied before the max\_free cap.""" &#x20; full\_cycles, remainder = divmod(eligible\_units, buy + free) &#x20; return full\_cycles \* free + max(0, remainder - buy) def \_allocate\_free\_units(lines: list\[CartLine], promo: BuyNGetMPromo) -> dict\[int, int]: &#x20; """Map cart position -> free units, filled cheapest-first (price, sku, position).""" &#x20; eligible = \[line for line in lines if line.sku in promo.eligible\_skus and line.qty > 0] &#x20; entitled = \_entitled\_free\_units(sum(line.qty for line in eligible), promo.buy, promo.free) &#x20; remaining = min(entitled, promo.max\_free) &#x20; allocation: dict\[int, int] = {} &#x20; for line in sorted(eligible, key=lambda item: (item.unit\_price, item.sku, item.position)): &#x20; if remaining == 0: &#x20; break &#x20; granted = min(line.qty, remaining) &#x20; allocation\[line.position] = granted &#x20; remaining -= granted &#x20; return allocation def \_summarise\_free\_items(lines: list\[CartLine], allocation: dict\[int, int]) -> list\[dict]: &#x20; """Aggregate free units per SKU, in the order they were granted (cheapest first).""" &#x20; per\_sku: dict\[str, int] = {} &#x20; for position, granted in allocation.items(): &#x20; sku = lines\[position].sku &#x20; per\_sku\[sku] = per\_sku.get(sku, 0) + granted &#x20; return \[{KEY\_SKU: sku, KEY\_QTY: qty} for sku, qty in per\_sku.items()] def apply\_buy\_n\_get\_m\_free(cart: list\[dict], promo: dict) -> dict: &#x20; """Apply a 'buy N, get the M cheapest eligible units free' promotion. &#x20; Args: &#x20; cart: rows of {"sku": str, "name": str, "unit\_price": float, "qty": int}. &#x20; promo: {"buy": int, "free": int, "eligible\_skus": list\[str], "max\_free": int}. &#x20; If "free" is 0 or missing, no discount is applied. &#x20; Returns: &#x20; {"lines", "free\_items", "total", "discount\_total"}. Each line echoes the cart &#x20; fields plus "line\_total" (paid qty x unit price, SAR, 2 dp, half-up) and &#x20; "free\_qty". total is the sum of line totals. &#x20; Raises: &#x20; PromotionInputError: if any cart row or promo field violates the contract. &#x20; """ &#x20; lines = \_parse\_cart(cart) &#x20; active\_promo = \_parse\_promo(promo) &#x20; allocation = \_allocate\_free\_units(lines, active\_promo) if active\_promo is not None else {} &#x20; output\_lines: list\[dict] = \[] &#x20; total = ZERO &#x20; discount\_total = ZERO &#x20; for line in lines: &#x20; free\_qty = allocation.get(line.position, 0) &#x20; line\_total = \_round\_money(line.unit\_price \* (line.qty - free\_qty)) &#x20; total += line\_total &#x20; discount\_total += \_round\_money(line.unit\_price \* free\_qty) &#x20; output\_lines.append( &#x20; { &#x20; KEY\_SKU: line.sku, &#x20; KEY\_NAME: line.name, &#x20; KEY\_UNIT\_PRICE: float(line.unit\_price), &#x20; KEY\_QTY: line.qty, &#x20; KEY\_LINE\_TOTAL: float(line\_total), &#x20; KEY\_FREE\_QTY: free\_qty, &#x20; } &#x20; ) &#x20; return { &#x20; KEY\_LINES: output\_lines, &#x20; KEY\_FREE\_ITEMS: \_summarise\_free\_items(lines, allocation), &#x20; KEY\_TOTAL: float(total), &#x20; KEY\_DISCOUNT\_TOTAL: float(discount\_total), &#x20; } EXAMPLE\_CART: list\[dict] = \[ &#x20; {"sku": "MILK-1L", "name": "Milk 1L", "unit\_price": 6.50, "qty": 3}, &#x20; {"sku": "BRD-WHT", "name": "White Bread", "unit\_price": 4.25, "qty": 2}, &#x20; {"sku": "EGG-12", "name": "Eggs 12pc", "unit\_price": 12.00, "qty": 1}, ] EXAMPLE\_PROMO: dict = { &#x20; "buy": 2, "free": 1, "eligible\_skus": \["MILK-1L", "BRD-WHT", "EGG-12"], "max\_free": 2, } def \_expect(condition: bool, message: str) -> None: &#x20; """Assertion that survives `python -O`.""" &#x20; if not condition: &#x20; raise AssertionError(message) def \_run\_self\_checks() -> None: &#x20; """Executable checks; expected values are hand-derived from the pricing rules.""" &#x20; example = apply\_buy\_n\_get\_m\_free(EXAMPLE\_CART, EXAMPLE\_PROMO) &#x20; \_expect(example\[KEY\_DISCOUNT\_TOTAL] == 8.50, f"discount\_total {example\[KEY\_DISCOUNT\_TOTAL]} != 8.50") &#x20; # 19.50 (milk) + 0.00 (bread) + 12.00 (eggs) = 31.50; the brief's 39.25 is unreachable. &#x20; \_expect(example\[KEY\_TOTAL] == 31.50, f"total {example\[KEY\_TOTAL]} != 31.50") &#x20; \_expect(example\[KEY\_FREE\_ITEMS] == \[{"sku": "BRD-WHT", "qty": 2}], "free items must be 2 x BRD-WHT") &#x20; inactive = apply\_buy\_n\_get\_m\_free(EXAMPLE\_CART, {\*\*EXAMPLE\_PROMO, KEY\_FREE: 0}) &#x20; \_expect(inactive\[KEY\_DISCOUNT\_TOTAL] == 0.0 and inactive\[KEY\_TOTAL] == 40.00, "free=0 must not discount") &#x20; no\_free\_key = {k: v for k, v in EXAMPLE\_PROMO.items() if k != KEY\_FREE} &#x20; \_expect(apply\_buy\_n\_get\_m\_free(EXAMPLE\_CART, no\_free\_key)\[KEY\_DISCOUNT\_TOTAL] == 0.0, &#x20; "missing free must not discount") &#x20; milk\_only = apply\_buy\_n\_get\_m\_free(EXAMPLE\_CART, {\*\*EXAMPLE\_PROMO, KEY\_ELIGIBLE: \["MILK-1L"]}) &#x20; \_expect(milk\_only\[KEY\_FREE\_ITEMS] == \[{"sku": "MILK-1L", "qty": 1}] and milk\_only\[KEY\_TOTAL] == 33.50, &#x20; "ineligible bread must stay at full price") &#x20; tie\_cart = \[ &#x20; {"sku": "B-ITEM", "name": "B", "unit\_price": 3.00, "qty": 1}, &#x20; {"sku": "A-ITEM", "name": "A", "unit\_price": 3.00, "qty": 1}, &#x20; {"sku": "C-ITEM", "name": "C", "unit\_price": 5.00, "qty": 1}, &#x20; ] &#x20; tie = apply\_buy\_n\_get\_m\_free( &#x20; tie\_cart, {"buy": 2, "free": 1, "eligible\_skus": \["A-ITEM", "B-ITEM", "C-ITEM"], "max\_free": 5}) &#x20; \_expect(tie\[KEY\_FREE\_ITEMS] == \[{"sku": "A-ITEM", "qty": 1}] and tie\[KEY\_TOTAL] == 8.00, &#x20; "equal prices must tie-break on sku") &#x20; partial = apply\_buy\_n\_get\_m\_free( &#x20; \[{"sku": "X", "name": "X", "unit\_price": 1.00, "qty": 3}], &#x20; {"buy": 2, "free": 2, "eligible\_skus": \["X"], "max\_free": 10}) &#x20; \_expect(partial\[KEY\_LINES]\[0]\[KEY\_FREE\_QTY] == 1 and partial\[KEY\_TOTAL] == 2.00, &#x20; "2 paid units earn up to 2 free; only 1 unit remains to give") &#x20; half\_up = apply\_buy\_n\_get\_m\_free( &#x20; \[{"sku": "H", "name": "H", "unit\_price": 0.125, "qty": 1}], &#x20; {"buy": 1, "free": 1, "eligible\_skus": \[], "max\_free": 1}) &#x20; \_expect(half\_up\[KEY\_TOTAL] == 0.13, "0.125 must round half-up to 0.13") &#x20; try: &#x20; apply\_buy\_n\_get\_m\_free(\[{\*\*EXAMPLE\_CART\[0], KEY\_QTY: -1}], EXAMPLE\_PROMO) &#x20; except PromotionInputError: &#x20; pass &#x20; else: &#x20; raise AssertionError("negative qty must be rejected") if \_\_name\_\_ == "\_\_main\_\_": &#x20; print(json.dumps(apply\_buy\_n\_get\_m\_free(EXAMPLE\_CART, EXAMPLE\_PROMO), indent=2, ensure\_ascii=False)) &#x20; \_run\_self\_checks() &#x20; print("self-checks passed") Explanation Important Your expected total of 39.25 contradicts your own rules. The cart is worth 19.50 + 8.50 + 12.00 = 40.00 before the promotion. Two free BRD-WHT units remove 8.50, which leaves 31.50. A total of 39.25 would require a discount of only 0.75, and no allocation of these prices produces that. The code follows your written policy, so it asserts 8.50 and 31.50. If the business really expects 39.25, there is a pricing rule I have not been told about. That discrepancy matters more than anything else here, because a checkout test pinned to 39.25 would fail against any correct implementation of the rules you wrote. The discount of 8.50 does reproduce, and the hand trace shows how. There are 6 eligible units (3 milk, 2 bread, 1 egg). The free units are worked out from the "paid units" wording, which yields 2. The cap of max\_free = 2 does not reduce that. Sorting by (price, sku) puts BRD-WHT at 4.25 first, so both of its units are given free. The output lines come to 19.50, 0.00 and 12.00. I did not run this code. The trace above and the self-checks are the evidence you can verify yourself with python buy\_n\_get\_m\_free.py. The phrase "every full group of buy paid units" is the one design decision your brief does not settle. Counting groups over all 6 units would give 3 free units before the cap. However, if 3 units are free, only 3 remain paid, and 3 paid units contain just one group of 2. That reading contradicts itself. I took the literal reading instead: F is the largest number of free units such that the remaining paid units still earn at least F. In closed form this is full\_cycles × free + max(0, remainder − buy) over cycles of buy + free units. This matches your note that "4 paid units qualify for 2 free units". It also has one consequence marketing should approve deliberately. With buy 2 / free 2 and 3 units in the cart, the customer gets 1 unit free, because the paid pair has earned 2 and only 1 unit is left to give. The partial self-check pins exactly that behaviour. Money is handled as Decimal from the moment of parsing. Prices are converted with Decimal(str(price)), so the float 6.5 becomes exactly 6.5 and not its binary approximation. Each line is quantized half-up to 0.01, and the totals are sums of the already-rounded lines, as you specified. The half\_up check uses 0.125. That value becomes 0.13 under half-up and would become 0.12 under Python's default banker's rounding, so it is the case that confirms the rounding mode. The output is deterministic because the sort key is (unit\_price, sku, original position). The position breaks the remaining tie if the cart contains the same SKU on two lines. In that case free\_items merges those units under one SKU, listed cheapest-first. The function has no shared state, so concurrent checkouts are safe without locks. The work is CPU-bound and O(n log n) in the number of lines, so it is synchronous and takes no cancellation token. Validation rejects booleans posing as ints, NaN and infinite prices, negative prices and quantities, empty SKUs, and promos that lack buy, eligible\_skus or max\_free. Two deliberate choices sit in this layer. A free of None counts as missing. A promo with free = 0 returns early without checking its other fields, which follows your instruction that nothing is discounted in that case. One last point: the contract requires floats, and JSON prints 31.50 as 31.5. If the front end needs the trailing zero, it should format the value itself. Usage At checkout, call the function once per cart and treat PromotionInputError as a rejected request, not a server fault: \# checkout\_example.py from buy\_n\_get\_m\_free import PromotionInputError, apply\_buy\_n\_get\_m\_free def price\_cart(cart: list\[dict], promo: dict) -> dict: &#x20; """Return priced cart, or a structured error the API layer maps to HTTP 422.""" &#x20; try: &#x20; return {"ok": True, "pricing": apply\_buy\_n\_get\_m\_free(cart, promo)} &#x20; except PromotionInputError as error: &#x20; return {"ok": False, "error": str(error)} Tomorrow's step is to settle two things with marketing: the 31.50 versus 39.25 figure, and the partial-group rule. Then lock both into your test suite using the self-checks above. 🏃 Not run — reason: Docker غيرُ متاح: docker: An error occurred trying to start process 'docker' with working directory 'D:\\Sites\\gaibra.ai'. The system cannot find the file specified.
هـClaude Sonnet91.5 · 1,137 كلمة
I’ll write the module, run the example plus some edge cases, and send you the file. bogo\_promo.py is ready. It’s 169 lines, uses only the standard library, and does all money math with Decimal. I ran the example and a few edge cases: same-price ties go to the lower SKU, a missing free gives no discount, and ineligible lines are never discounted. Your expected total of 39.25 doesn’t add up. The cart is worth 40.00 before the promo (19.50 + 8.50 + 12.00). With 8.50 off for the two free bread units, the total is 31.50. That’s what the function returns, and discount\_total = 8.50 matches your example. 39.25 can’t come from any free-unit split here, so the expected value is probably a typo. Please fix it before it ends up in a test fixture. Choices I made where the spec left room: Grouping: each bundle is buy + free eligible units, so free units don’t count toward the next “buy”. In your example, 6 eligible units make 2 bundles: 4 paid and 2 free. Leftover units: a remainder that’s too small for a full bundle earns nothing. Free units have to already be in the cart. max\_free: if it’s missing or None, there’s no cap. A negative value means 0. Duplicate SKUs on separate lines are allocated separately: price first, then SKU, then cart order. free\_items merges them per SKU and includes the discount amount for each. Bad input raises ValueError. That covers a negative qty or price, a non-integer qty, and buy ≤ 0 when free > 0. Amounts come back as float to match your signature, so JSON prints 31.5, not 31.50. If the frontend needs fixed 2-decimal strings, I can switch the output to strings. Bogo promo PY  """Buy-N-get-M-cheapest-free promotion for the grocery cart module. Rules: \- Eligible units are grouped into bundles of (buy + free) units. Each full &#x20; bundle grants `free` free units, i.e. `buy` paid units "earn" `free` free &#x20; units. Free units must already be in the cart. \- Total free units are capped by `max\_free` (missing/None = no cap). \- Free units are the cheapest eligible units: lower unit price first, then &#x20; lower SKU alphabetically, then earlier cart line (for duplicate SKUs). \- Ineligible SKUs are never discounted but still appear in `lines`/`total`. \- Money is handled with Decimal; each line is rounded half-up to 2 places. """ from \_\_future\_\_ import annotations import json from decimal import ROUND\_HALF\_UP, Decimal \_CENT = Decimal("0.01") def \_money(value: Decimal) -> Decimal: &#x20; return value.quantize(\_CENT, rounding=ROUND\_HALF\_UP) def \_to\_decimal(value: object, field: str) -> Decimal: &#x20; if isinstance(value, bool) or not isinstance(value, (int, float, str, Decimal)): &#x20; raise ValueError(f"{field} must be numeric, got {value!r}") &#x20; try: &#x20; # str() avoids binary-float artefacts, e.g. 4.25 stays exactly 4.25. &#x20; dec = Decimal(str(value)) &#x20; except Exception as exc: # decimal.InvalidOperation &#x20; raise ValueError(f"{field} is not a valid number: {value!r}") from exc &#x20; if not dec.is\_finite(): &#x20; raise ValueError(f"{field} must be finite, got {value!r}") &#x20; return dec def \_to\_int(value: object, field: str, default: int | None = None) -> int | None: &#x20; if value is None: &#x20; return default &#x20; if isinstance(value, bool) or not isinstance(value, int): &#x20; raise ValueError(f"{field} must be an integer, got {value!r}") &#x20; return value def \_validate\_cart(cart: list\[dict]) -> list\[dict]: &#x20; if not isinstance(cart, list): &#x20; raise ValueError("cart must be a list") &#x20; parsed = \[] &#x20; for i, item in enumerate(cart): &#x20; if not isinstance(item, dict): &#x20; raise ValueError(f"cart\[{i}] must be a dict") &#x20; for key in ("sku", "name", "unit\_price", "qty"): &#x20; if key not in item: &#x20; raise ValueError(f"cart\[{i}] is missing '{key}'") &#x20; sku = item\["sku"] &#x20; if not isinstance(sku, str) or not sku: &#x20; raise ValueError(f"cart\[{i}].sku must be a non-empty string") &#x20; price = \_to\_decimal(item\["unit\_price"], f"cart\[{i}].unit\_price") &#x20; if price < 0: &#x20; raise ValueError(f"cart\[{i}].unit\_price must be >= 0") &#x20; qty = \_to\_int(item\["qty"], f"cart\[{i}].qty") &#x20; if qty < 0: &#x20; raise ValueError(f"cart\[{i}].qty must be >= 0") &#x20; parsed.append({"index": i, "item": item, "sku": sku, "price": price, "qty": qty}) &#x20; return parsed def \_free\_unit\_count(eligible\_units: int, buy: int, free: int, max\_free: int | None) -> int: &#x20; if free <= 0 or eligible\_units <= 0: &#x20; return 0 &#x20; bundles = eligible\_units // (buy + free) &#x20; granted = bundles \* free &#x20; if max\_free is not None: &#x20; granted = min(granted, max(max\_free, 0)) &#x20; return granted def apply\_buy\_n\_get\_m\_free(cart: list\[dict], promo: dict) -> dict: &#x20; if not isinstance(promo, dict): &#x20; raise ValueError("promo must be a dict") &#x20; free = \_to\_int(promo.get("free"), "promo.free", default=0) &#x20; if free < 0: &#x20; raise ValueError("promo.free must be >= 0") &#x20; buy = \_to\_int(promo.get("buy"), "promo.buy", default=0) &#x20; if free > 0 and buy <= 0: &#x20; raise ValueError("promo.buy must be a positive integer when free > 0") &#x20; max\_free = \_to\_int(promo.get("max\_free"), "promo.max\_free", default=None) &#x20; eligible\_raw = promo.get("eligible\_skus") or \[] &#x20; if not isinstance(eligible\_raw, (list, tuple, set)): &#x20; raise ValueError("promo.eligible\_skus must be a list of strings") &#x20; eligible = {s for s in eligible\_raw if isinstance(s, str)} &#x20; lines = \_validate\_cart(cart) &#x20; free\_qty = {ln\["index"]: 0 for ln in lines} &#x20; eligible\_lines = \[ln for ln in lines if ln\["sku"] in eligible and ln\["qty"] > 0] &#x20; eligible\_units = sum(ln\["qty"] for ln in eligible\_lines) &#x20; remaining = \_free\_unit\_count(eligible\_units, buy, free, max\_free) &#x20; # Cheapest first: price, then SKU, then cart position (stable for dup SKUs). &#x20; for ln in sorted(eligible\_lines, key=lambda l: (l\["price"], l\["sku"], l\["index"])): &#x20; if remaining <= 0: &#x20; break &#x20; take = min(ln\["qty"], remaining) &#x20; free\_qty\[ln\["index"]] = take &#x20; remaining -= take &#x20; out\_lines = \[] &#x20; total = Decimal("0") &#x20; discount\_total = Decimal("0") &#x20; free\_by\_sku: dict\[str, dict] = {} &#x20; for ln in lines: &#x20; item, price, fq = ln\["item"], ln\["price"], free\_qty\[ln\["index"]] &#x20; paid\_qty = ln\["qty"] - fq &#x20; line\_total = \_money(price \* paid\_qty) &#x20; line\_discount = \_money(price \* fq) &#x20; total += line\_total &#x20; discount\_total += line\_discount &#x20; out\_lines.append({ &#x20; "sku": item\["sku"], &#x20; "name": item\["name"], &#x20; "unit\_price": float(\_money(price)), &#x20; "qty": ln\["qty"], &#x20; "line\_total": float(line\_total), &#x20; "free\_qty": fq, &#x20; }) &#x20; if fq: &#x20; entry = free\_by\_sku.setdefault(ln\["sku"], { &#x20; "sku": ln\["sku"], "name": item\["name"], "qty": 0, &#x20; "unit\_price": price, "discount": Decimal("0"), &#x20; }) &#x20; entry\["qty"] += fq &#x20; entry\["unit\_price"] = min(entry\["unit\_price"], price) &#x20; entry\["discount"] += line\_discount &#x20; free\_items = \[ &#x20; {"sku": e\["sku"], "name": e\["name"], "qty": e\["qty"], "discount": float(e\["discount"])} &#x20; for e in sorted(free\_by\_sku.values(), key=lambda e: (e\["unit\_price"], e\["sku"])) &#x20; ] &#x20; return { &#x20; "lines": out\_lines, &#x20; "free\_items": free\_items, &#x20; "total": float(\_money(total)), &#x20; "discount\_total": float(\_money(discount\_total)), &#x20; } if \_\_name\_\_ == "\_\_main\_\_": &#x20; example\_cart = \[ &#x20; {"sku": "MILK-1L", "name": "Milk 1L", "unit\_price": 6.50, "qty": 3}, &#x20; {"sku": "BRD-WHT", "name": "White Bread", "unit\_price": 4.25, "qty": 2}, &#x20; {"sku": "EGG-12", "name": "Eggs 12pc", "unit\_price": 12.00, "qty": 1}, &#x20; ] &#x20; example\_promo = { &#x20; "buy": 2, &#x20; "free": 1, &#x20; "eligible\_skus": \["MILK-1L", "BRD-WHT", "EGG-12"], &#x20; "max\_free": 2, &#x20; } &#x20; result = apply\_buy\_n\_get\_m\_free(example\_cart, example\_promo) &#x20; print(json.dumps(result, indent=2, ensure\_ascii=False))
جChatGPT82.5 · 682 كلمة
The implementation below uses Decimal with ROUND\_HALF\_UP for SAR currency, applies the promotion only to eligible SKUs, and allocates free units in ascending order of unit price, then SKU. It also handles missing free, the max\_free cap, and deterministic JSON output. One important detail: the number of free units is based on eligible paid units before the promotion, not on the cheapest items' quantities alone. Each cart line's line\_total reflects its paid quantity after free units are allocated. كتابة from decimal import Decimal, ROUND\_HALF\_UP from collections import defaultdict import json CENT = Decimal("0.01") def money(value: Decimal) -> Decimal: &#x20; """Round a monetary amount to two decimal places, half-up.""" &#x20; return value.quantize(CENT, rounding=ROUND\_HALF\_UP) def apply\_buy\_n\_get\_m\_free(cart: list\[dict], promo: dict) -> dict: &#x20; """ &#x20; Apply a buy-N-get-M-free promotion to eligible cart units. &#x20; Free units are allocated by ascending unit price, then SKU. &#x20; Monetary amounts are rounded half-up per cart line. &#x20; """ &#x20; lines = \[] &#x20; eligible\_indices = \[] &#x20; eligible\_skus = set(promo.get("eligible\_skus", \[])) &#x20; # Normalize lines and prepare eligible-unit allocation. &#x20; for index, item in enumerate(cart): &#x20; price = Decimal(str(item\["unit\_price"])) &#x20; qty = item\["qty"] &#x20; if price < 0: &#x20; raise ValueError("unit\_price cannot be negative") &#x20; if not isinstance(qty, int) or isinstance(qty, bool) or qty < 0: &#x20; raise ValueError("qty must be a non-negative integer") &#x20; line = { &#x20; \*\*item, &#x20; "line\_total": float(money(price \* qty)), &#x20; "free\_qty": 0, &#x20; } &#x20; lines.append(line) &#x20; if item\["sku"] in eligible\_skus: &#x20; eligible\_indices.append(index) &#x20; buy = promo.get("buy", 0) &#x20; free = promo.get("free", 0) or 0 &#x20; max\_free = promo.get("max\_free", 0) &#x20; # Invalid or inactive promotion parameters grant no free units. &#x20; valid\_buy = isinstance(buy, int) and not isinstance(buy, bool) and buy > 0 &#x20; valid\_free = isinstance(free, int) and not isinstance(free, bool) and free > 0 &#x20; valid\_cap = ( &#x20; isinstance(max\_free, int) &#x20; and not isinstance(max\_free, bool) &#x20; and max\_free > 0 &#x20; ) &#x20; if valid\_buy and valid\_free and valid\_cap: &#x20; eligible\_qty = sum(lines\[i]\["qty"] for i in eligible\_indices) &#x20; free\_count = min( &#x20; (eligible\_qty // buy) \* free, &#x20; max\_free, &#x20; ) &#x20; # Cheapest units first; SKU breaks equal-price ties. &#x20; ordered\_indices = sorted( &#x20; eligible\_indices, &#x20; key=lambda i: ( &#x20; Decimal(str(lines\[i]\["unit\_price"])), &#x20; lines\[i]\["sku"], &#x20; i, &#x20; ), &#x20; ) &#x20; remaining = free\_count &#x20; for i in ordered\_indices: &#x20; granted = min(lines\[i]\["qty"], remaining) &#x20; lines\[i]\["free\_qty"] = granted &#x20; remaining -= granted &#x20; if remaining == 0: &#x20; break &#x20; # Aggregate free quantities by SKU, preserving deterministic order. &#x20; free\_by\_sku = defaultdict(int) &#x20; sku\_order = \[] &#x20; seen\_skus = set() &#x20; for line in lines: &#x20; sku = line\["sku"] &#x20; if sku not in seen\_skus: &#x20; seen\_skus.add(sku) &#x20; sku\_order.append(sku) &#x20; if line\["free\_qty"]: &#x20; free\_by\_sku\[sku] += line\["free\_qty"] &#x20; free\_items = \[ &#x20; {"sku": sku, "qty": free\_by\_sku\[sku]} &#x20; for sku in sku\_order &#x20; if free\_by\_sku\[sku] > 0 &#x20; ] &#x20; # Recalculate paid line totals and sum rounded line amounts. &#x20; total = Decimal("0.00") &#x20; discount\_total = Decimal("0.00") &#x20; for line in lines: &#x20; price = Decimal(str(line\["unit\_price"])) &#x20; paid\_qty = line\["qty"] - line\["free\_qty"] &#x20; line\_amount = money(price \* paid\_qty) &#x20; line\_discount = money(price \* line\["free\_qty"]) &#x20; line\["line\_total"] = float(line\_amount) &#x20; total += line\_amount &#x20; discount\_total += line\_discount &#x20; return { &#x20; "lines": lines, &#x20; "free\_items": free\_items, &#x20; "total": float(money(total)), &#x20; "discount\_total": float(money(discount\_total)), &#x20; } if \_\_name\_\_ == "\_\_main\_\_": &#x20; cart = \[ &#x20; {"sku": "MILK-1L", "name": "Milk 1L", &#x20; "unit\_price": 6.50, "qty": 3}, &#x20; {"sku": "BRD-WHT", "name": "White Bread", &#x20; "unit\_price": 4.25, "qty": 2}, &#x20; {"sku": "EGG-12", "name": "Eggs 12pc", &#x20; "unit\_price": 12.00, "qty": 1}, &#x20; ] &#x20; promo = { &#x20; "buy": 2, &#x20; "free": 1, &#x20; "eligible\_skus": \["MILK-1L", "BRD-WHT", "EGG-12"], &#x20; "max\_free": 2, &#x20; } &#x20; print(json.dumps( &#x20; apply\_buy\_n\_get\_m\_free(cart, promo), &#x20; indent=2, &#x20; ensure\_ascii=False, &#x20; )) Note about the example: The stated expected total of SAR 39.25 conflicts with the other requirements. The original cart costs SAR 40.00, and two free bread units discount SAR 8.50. Therefore, the correct total of paid line amounts is SAR 31.50, with discount\_total of SAR 8.50. The implementation follows the specified line-total and discount rules rather than the inconsistent expected total.
أDeepSeek75.0 · 1,040 كلمة
Here's a self-contained Python file implementing the promotion logic with the exact function signature you specified: python from decimal import Decimal, ROUND\_HALF\_UP import json def apply\_buy\_n\_get\_m\_free(cart: list\[dict], promo: dict) -> dict: &#x20; """ &#x20; Apply "buy N get M cheapest free" promotion at checkout. &#x20; &#x20; Args: &#x20; cart: list of {"sku": str, "name": str, "unit\_price": float, "qty": int} &#x20; promo: {"buy": int, "free": int, "eligible\_skus": list\[str], "max\_free": int} &#x20; &#x20; Returns: &#x20; {"lines": \[...], "free\_items": \[...], "total": float, "discount\_total": float} &#x20; """ &#x20; buy\_n = promo.get("buy", 0) &#x20; free\_m = promo.get("free", 0) &#x20; eligible\_skus = set(promo.get("eligible\_skus", \[])) &#x20; max\_free = promo.get("max\_free", 0) &#x20; # If no free items, nothing is discounted &#x20; if free\_m == 0 or buy\_n == 0: &#x20; lines = \[] &#x20; total = Decimal("0.00") &#x20; for item in cart: &#x20; unit\_price = Decimal(str(item\["unit\_price"])) &#x20; qty = item\["qty"] &#x20; line\_total = (unit\_price \* qty).quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) &#x20; total += line\_total &#x20; lines.append({ &#x20; \*\*item, &#x20; "line\_total": float(line\_total), &#x20; "free\_qty": 0, &#x20; }) &#x20; total = total.quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) &#x20; return { &#x20; "lines": lines, &#x20; "free\_items": \[], &#x20; "total": float(total), &#x20; "discount\_total": 0.00, &#x20; } &#x20; # Separate eligible and ineligible items &#x20; eligible\_items = \[] &#x20; ineligible\_items = \[] &#x20; for item in cart: &#x20; if item\["sku"] in eligible\_skus: &#x20; eligible\_items.append(item) &#x20; else: &#x20; ineligible\_items.append(item) &#x20; # Count total paid units among eligible items &#x20; total\_eligible\_qty = sum(item\["qty"] for item in eligible\_items) &#x20; &#x20; # Calculate how many free units are entitled &#x20; # Each full group of buy\_n paid units gives free\_m free units &#x20; groups = total\_eligible\_qty // buy\_n &#x20; entitled\_free = groups \* free\_m &#x20; &#x20; # Cap by max\_free &#x20; if max\_free > 0: &#x20; entitled\_free = min(entitled\_free, max\_free) &#x20; else: &#x20; entitled\_free = 0 &#x20; # Build list of all eligible units (for cheapest selection) &#x20; # Each unit represented as (unit\_price, sku, item\_index) &#x20; all\_units = \[] &#x20; for idx, item in enumerate(eligible\_items): &#x20; for \_ in range(item\["qty"]): &#x20; all\_units.append((Decimal(str(item\["unit\_price"])), item\["sku"], idx)) &#x20; # Sort by price ascending, then sku alphabetically &#x20; all\_units.sort(key=lambda x: (x\[0], x\[1])) &#x20; # Select the cheapest `entitled\_free` units to be free &#x20; free\_units\_selected = all\_units\[:entitled\_free] &#x20; # Count free qty per eligible item index &#x20; free\_qty\_by\_index = {} &#x20; for \_, \_, idx in free\_units\_selected: &#x20; free\_qty\_by\_index\[idx] = free\_qty\_by\_index.get(idx, 0) + 1 &#x20; # Build free\_items list: aggregate by sku &#x20; free\_items\_map = {} &#x20; for \_, sku, \_ in free\_units\_selected: &#x20; free\_items\_map\[sku] = free\_items\_map.get(sku, 0) + 1 &#x20; free\_items = \[] &#x20; for sku in sorted(free\_items\_map.keys()): &#x20; free\_items.append({"sku": sku, "qty": free\_items\_map\[sku]}) &#x20; # Build lines &#x20; lines = \[] &#x20; total = Decimal("0.00") &#x20; discount\_total = Decimal("0.00") &#x20; # Process eligible items &#x20; for idx, item in enumerate(eligible\_items): &#x20; unit\_price = Decimal(str(item\["unit\_price"])) &#x20; qty = item\["qty"] &#x20; free\_qty = free\_qty\_by\_index.get(idx, 0) &#x20; paid\_qty = qty - free\_qty &#x20; line\_total = (unit\_price \* paid\_qty).quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) &#x20; total += line\_total &#x20; discount\_total += (unit\_price \* free\_qty) &#x20; lines.append({ &#x20; \*\*item, &#x20; "line\_total": float(line\_total), &#x20; "free\_qty": free\_qty, &#x20; }) &#x20; # Process ineligible items (never discounted) &#x20; for item in ineligible\_items: &#x20; unit\_price = Decimal(str(item\["unit\_price"])) &#x20; qty = item\["qty"] &#x20; line\_total = (unit\_price \* qty).quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) &#x20; total += line\_total &#x20; lines.append({ &#x20; \*\*item, &#x20; "line\_total": float(line\_total), &#x20; "free\_qty": 0, &#x20; }) &#x20; # Sort lines to maintain original cart order &#x20; sku\_order = {item\["sku"]: i for i, item in enumerate(cart)} &#x20; lines.sort(key=lambda x: sku\_order.get(x\["sku"], 999)) &#x20; total = total.quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) &#x20; discount\_total = discount\_total.quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) &#x20; return { &#x20; "lines": lines, &#x20; "free\_items": free\_items, &#x20; "total": float(total), &#x20; "discount\_total": float(discount\_total), &#x20; } if \_\_name\_\_ == "\_\_main\_\_": &#x20; cart = \[ &#x20; {"sku": "MILK-1L", "name": "Milk 1L", "unit\_price": 6.50, "qty": 3}, &#x20; {"sku": "BRD-WHT", "name": "White Bread", "unit\_price": 4.25, "qty": 2}, &#x20; {"sku": "EGG-12", "name": "Eggs 12pc", "unit\_price": 12.00, "qty": 1}, &#x20; ] &#x20; promo = {"buy": 2, "free": 1, "eligible\_skus": \["MILK-1L", "BRD-WHT", "EGG-12"], "max\_free": 2} &#x20; result = apply\_buy\_n\_get\_m\_free(cart, promo) &#x20; print(json.dumps(result, indent=2)) The output for the example is: json { &#x20; "lines": \[ &#x20; { &#x20; "sku": "MILK-1L", &#x20; "name": "Milk 1L", &#x20; "unit\_price": 6.5, &#x20; "qty": 3, &#x20; "line\_total": 19.5, &#x20; "free\_qty": 0 &#x20; }, &#x20; { &#x20; "sku": "BRD-WHT", &#x20; "name": "White Bread", &#x20; "unit\_price": 4.25, &#x20; "qty": 2, &#x20; "line\_total": 0.0, &#x20; "free\_qty": 2 &#x20; }, &#x20; { &#x20; "sku": "EGG-12", &#x20; "name": "Eggs 12pc", &#x20; "unit\_price": 12.0, &#x20; "qty": 1, &#x20; "line\_total": 12.0, &#x20; "free\_qty": 0 &#x20; } &#x20; ], &#x20; "free\_items": \[ &#x20; {"sku": "BRD-WHT", "qty": 2} &#x20; ], &#x20; "total": 31.5, &#x20; "discount\_total": 8.5 } Wait — the expected total in your example is 39.25, but my calculation gives 31.50. Let me re-check the example. Looking at your example again: 3 MILK + 2 BRD + 1 EGG = 6 units total, all eligible. Groups = 6 // 2 = 3, entitled = 3 free units, capped at max\_free=2. So 2 free units. Cheapest 2 units are both BRD-WHT at 4.25 each. Discount = 8.50. Paid total = (3×6.50) + (2×4.25 - 8.50) + (1×12.00) = 19.50 + 0.00 + 12.00 = 31.50. Your expected total of 39.25 doesn't match. Let me re-read: "4 paid units qualify for 2 free units". Hmm — 4 paid units? That suggests only 4 units are being considered as "paid" before free selection, but there are 6 eligible units. Ah, I think the intent may be: the promotion applies to groups formed by paid units, and free units are taken from the same pool. With 6 eligible units, if we take 2 free, we have 4 paid units remaining — which is 2 full groups of 2, giving 2 free units. That's consistent and self-referential: 4 paid → 2 groups → 2 free → 6 total. ✓ So discount = 2 × 4.25 = 8.50. Total paid = 19.50 + 0.00 + 12.00 = 31.50. The stated 39.25 would be 6.50×3 + 4.25×2 + 12.00 = 19.50 + 8.50 + 12.00 = 40.00, minus 0.75... no. 39.25 = 40.00 - 0.75. That doesn't correspond to any clean discount either. Since 39.25 is inconsistent with the stated discount\_total of 8.50 (40.00 - 8.50 = 31.50, not 39.25), the example's total appears to be a typo. The implementation above is correct per the rules as written.
دGemini68.0 · 370 كلمة
Python from decimal import Decimal, ROUND\_HALF\_UP import json def round\_currency(val: Decimal) -> Decimal: &#x20; return val.quantize(Decimal("0.01"), rounding=ROUND\_HALF\_UP) def apply\_buy\_n\_get\_m\_free(cart: list\[dict], promo: dict) -> dict: &#x20; buy\_qty = promo.get("buy", 0) &#x20; free\_per\_group = promo.get("free", 0) &#x20; eligible\_skus = set(promo.get("eligible\_skus", \[])) &#x20; max\_free = promo.get("max\_free", float("inf")) &#x20; # Separate eligible individual items &#x20; eligible\_units = \[] &#x20; for line in cart: &#x20; sku = line\["sku"] &#x20; if sku in eligible\_skus: &#x20; price = Decimal(str(line\["unit\_price"])) &#x20; for \_ in range(line\["qty"]): &#x20; eligible\_units.append((price, sku)) &#x20; # Sort eligible units by unit price ascending, then SKU ascending &#x20; eligible\_units.sort(key=lambda x: (x\[0], x\[1])) &#x20; # Determine total free items allowed &#x20; if buy\_qty > 0 and free\_per\_group > 0 and eligible\_units: &#x20; group\_size = buy\_qty + free\_per\_group &#x20; num\_groups = len(eligible\_units) // group\_size &#x20; total\_free\_units = num\_groups \* free\_per\_group &#x20; if max\_free is not None: &#x20; total\_free\_units = min(total\_free\_units, max\_free) &#x20; else: &#x20; total\_free\_units = 0 &#x20; # Allocate free units starting from the cheapest &#x20; free\_counts = {} &#x20; for i in range(total\_free\_units): &#x20; \_, sku = eligible\_units\[i] &#x20; free\_counts\[sku] = free\_counts.get(sku, 0) + 1 &#x20; # Build response lines &#x20; lines = \[] &#x20; free\_items\_list = \[] &#x20; total\_discount\_dec = Decimal("0.00") &#x20; total\_dec = Decimal("0.00") &#x20; for line in cart: &#x20; sku = line\["sku"] &#x20; qty = line\["qty"] &#x20; unit\_price\_dec = Decimal(str(line\["unit\_price"])) &#x20; free\_q = free\_counts.get(sku, 0) &#x20; paid\_q = qty - free\_q &#x20; line\_total\_dec = round\_currency(Decimal(paid\_q) \* unit\_price\_dec) &#x20; line\_discount\_dec = round\_currency(Decimal(free\_q) \* unit\_price\_dec) &#x20; total\_dec += line\_total\_dec &#x20; total\_discount\_dec += line\_discount\_dec &#x20; lines.append( &#x20; { &#x20; "sku": sku, &#x20; "name": line\["name"], &#x20; "unit\_price": float(unit\_price\_dec), &#x20; "qty": qty, &#x20; "free\_qty": free\_q, &#x20; "line\_total": float(line\_total\_dec), &#x20; } &#x20; ) &#x20; if free\_q > 0: &#x20; free\_items\_list.append({"sku": sku, "qty": free\_q}) &#x20; return { &#x20; "lines": lines, &#x20; "free\_items": free\_items\_list, &#x20; "total": float(round\_currency(total\_dec)), &#x20; "discount\_total": float(round\_currency(total\_discount\_dec)), &#x20; } if \_\_name\_\_ == "\_\_main\_\_": &#x20; cart = \[ &#x20; {"sku": "MILK-1L", "name": "Milk 1L", "unit\_price": 6.50, "qty": 3}, &#x20; {"sku": "BRD-WHT", "name": "White Bread", "unit\_price": 4.25, "qty": 2}, &#x20; {"sku": "EGG-12", "name": "Eggs 12pc", "unit\_price": 12.00, "qty": 1}, &#x20; ] &#x20; promo = { &#x20; "buy": 2, &#x20; "free": 1, &#x20; "eligible\_skus": \["MILK-1L", "BRD-WHT", "EGG-12"], &#x20; "max\_free": 2, &#x20; } &#x20; result = apply\_buy\_n\_get\_m\_free(cart, promo) &#x20; print(json.dumps(result, indent=2))