Write the function that sets a lead-score threshold from call capacity and a call's break-even, never splitting a tie, and read what a second rep buys.
codemediumExercise · 3 min · 51 of 60
On this page
Last month the threshold was typed in by hand and sent 500 leads to a team that can call 300. The function below makes the cut the same way every month.
Sales receives 5,000 leads a month, of which 4% convert, and can make 300 calls. The lead score is calibrated in whole percent: leads scored 21 converted about 21% of the time last quarter. This month's scores are 100 leads at 34, 200 at 21, 200 at 12, 500 at 8, 500 at 4, 1,000 at 2, 2,000 at 1 and 500 at 0.
A call costs $25, 20 minutes of a rep at $75 an hour, and a converted lead is worth $800 of expected margin, so a call pays when score × $800 ≥ 100 × $25, a score of at least 3.125. The CRM routes with one rule, "score ≥ t", so it cannot call some leads at a score and skip others at the same score. Last month someone set t = 10, sending 500 leads to 300 calls, and reps chose among them by instinct.
Write the function, then use it to say where t goes for 300 calls and what a second rep's extra 300 calls would buy.
def solve(scores, capacity, value, cost):
"""Pick the lead-score threshold for next month's call list.
scores: one calibrated score per lead, an integer percent.
capacity: calls the team can make this month.
value: dollars of expected margin from one converted lead.
cost: loaded dollars of one call.
Returns (threshold, calls): call every lead with score >= threshold.
A lead is worth a call when score / 100 * value >= cost (break-even is called).
Ties are never split: if calling every lead at the cut score would exceed
capacity, the threshold stays at the score above and the spare calls are
capacity - calls. With no lead worth a call, returns (None, 0).
"""
MONTH is the 5,000 scores above. The tie rule is the deterministic part of the contract: leads that share a score are all called or none is, and unused calls are reported, never filled by arrival order or lead ID.
A strong answer · Rubric · Where answers go wrong · Solution
Count the leads at each distinct score, then walk the scores from highest to lowest with a running total of calls. At each score, two checks. Break-even, in integers: stop if score × value < 100 × cost, since every lower score fails too; in floating point 29 ÷ 100 × 800 is 231.99999999999997, which would drop a lead that exactly breaks even on a $232 call. Capacity: stop if the whole band would pass it. Otherwise take the band and move the threshold down to it. Return the last score taken and the total, or (None, 0), which also covers a top band larger than capacity. The loop never splits a band and never returns a threshold below break-even. Test a tie at the cut (the fifth example), an exact break-even, that oversized top band and an empty month.
Read the results. At 300 calls the threshold is 21: the 34s and 21s, 34 + 42 = 76 expected converters, against 300 × 4% = 12 at random. At 400 it is still 21, with 100 calls spare, because the 200 leads at 12 do not fit whole. A second rep, 600 calls, moves it to 12: the extra calls reach the 200 leads at 12, about 24 converters and $19,200 of expected margin a month, and 100 calls stay spare because the 500 leads at 8 do not fit. With no capacity limit it stops at 4, 1,500 leads: break-even, not the model, ends the list.
What would change it: a finer score that splits the 12s and 8s, putting the spare calls to work, or a holdout showing calls cause fewer conversions than they find, which lowers value; predictive scoring covers both.
"Sort the leads, take the first 300, and use the 300th lead's score." It gives 21 this month by luck. At 400 calls it returns 12, and the router, applying "score ≥ 12", sends 500 leads to a 400-call team: the failure the situation began with.
"Call every lead above break-even." That is 1,500 leads for 300 calls; reps choose among them by instinct and the ranking is thrown away.
"if score / 100 * value > cost." Strict inequality skips leads that exactly break even, and the float division misses the boundary on its own, as at 29 × $800 against $232.
Python 3 · standard library44 lines · 12 of 12 tests passing
"""Pick the score threshold: the lowest lead score the call list reaches, set by
sales capacity and by the break-even of a call, never by splitting a tie."""
from collections import Counter
def month_of_leads():
"""The situation's month: 5,000 leads, 200 expected converters.
Top decile 100 at 34, 200 at 21, 200 at 12 (100 converters); then
500 at 8 (40), 500 at 4 (20), 1,000 at 2 (20), 2,000 at 1 (20), 500 at 0."""
bands = [(34, 100), (21, 200), (12, 200), (8, 500), (4, 500), (2, 1000), (1, 2000), (0, 500)]
return [score for score, count in bands for _ in range(count)]
def solve(scores, capacity, value, cost):
"""Pick the lead-score threshold for next month's call list.
scores: one calibrated score per lead, an integer percent (21 means about
21% of last quarter's leads with that score converted).
capacity: calls the team can make this month.
value: dollars of expected margin from one converted lead.
cost: loaded dollars of one call.
Returns (threshold, calls): call every lead with score >= threshold.
A lead is worth a call when score / 100 * value >= cost (break-even is called).
Ties are never split: if calling every lead at the cut score would exceed
capacity, the threshold stays at the score above and the spare calls are
capacity - calls. With no lead worth a call, returns (None, 0).
"""
per_score = Counter(scores)
threshold, calls = None, 0
# Invariant: `calls` counts every lead scored >= `threshold`, and
# calls <= capacity. Bands are taken whole, highest score first.
for score in sorted(per_score, reverse=True):
# Integer arithmetic: score * value >= 100 * cost. In floating point
# 29 / 100 * 800 is 231.99999999999997, which would drop a lead that
# breaks even exactly on a $232 call.
if score * value < 100 * cost:
break # every lower band is below break-even too
if calls + per_score[score] > capacity:
break # a router applies one number, so this band is all or none
threshold, calls = score, calls + per_score[score]
return threshold, calls
MONTH = month_of_leads()
The cases that ran
TESTS = [
# The situation: 300 calls take the 34s and the 21s, 76 expected converters.
((MONTH, 300, 800, 25), (21, 300)),
# 400 calls: the 200 leads at 12 do not fit, so 100 calls are spare.
((MONTH, 400, 800, 25), (21, 300)),
# A second rep, 600 calls: the 12s fit, the 500 at 8 do not; 100 spare.
((MONTH, 600, 800, 25), (12, 500)),
# Unlimited calls: break-even is 3.125%, so the cut stops above the 2s.
((MONTH, 5000, 800, 25), (4, 1500)),
# A tie at the cut: the two 20s would make 3 calls against 2.
(([30, 20, 20, 10], 2, 800, 25), (30, 1)),
# Capacity met exactly by whole bands.
(([30, 20, 20, 10, 5, 2], 3, 800, 25), (20, 3)),
# Nothing clears break-even: 3% of $800 is $24, under a $25 call.
(([3, 2, 1], 10, 800, 25), (None, 0)),
# Exactly break-even is called: 5% of $500 is $25.
(([5, 4, 3], 10, 500, 25), (5, 1)),
# Break-even where a float comparison would miss it: 29% of $800 is $232.
(([29, 10], 5, 800, 232), (29, 1)),
# The top band alone exceeds capacity, so no threshold fits.
(([40, 40, 40], 2, 800, 25), (None, 0)),
# Input order does not matter, and an empty month calls no one.
(([10, 34, 21, 34], 3, 800, 25), (21, 3)),
(([], 300, 800, 25), (None, 0)),
]