Syllabus Lesson 134 of 141 · Ten doors and the field kit
Ten doors and the field kit

Final 3: a login guard that forgets

AI off This is a final exam, matched to the baseline exam you did in the first module: the same kind of problem, new data, the same difficulty. The tutor is switched off and there are no hints. Work alone. The course lines it up against your baseline in the next lesson.

A login service slows down password guessing by refusing attempts on an account that has had too many recently. It runs on a small machine for months, and bots try thousands of different account names a few times each.

The worked example

g = new_guard(2, 10)       # 2 attempts per 10 seconds
attempt(g, 'a', 0)    # True
attempt(g, 'a', 3)    # True
attempt(g, 'a', 9)    # False: 0 and 3 are in (-1, 9]
attempt(g, 'b', 9)    # True: b is separate
attempt(g, 'a', 10)   # True: 0 has left the window (0, 10]
attempt(g, 'a', 13)   # True: 3 has left (3, 13]
attempt(g, 'a', 14)   # False
attempt(g, 'a', 23)   # True
Your turn

Write new_guard(limit, window) and attempt(guard, account, t). attempt returns True if the account had fewer than limit allowed login attempts in the last window seconds, that is with times in (t - window, t], and then counts this one; otherwise it returns False (refused attempts do not count). t is a whole number of seconds and never goes down from one call to the next. Keep everything in guard: no globals.
Memory: over 20,000 calls, more than 5,000 different accounts pass through, most making a few attempts and never coming back. With limit=3, window=60, your guard may hold at most 2,500 items at any time, counted like kept() (deques and OrderedDicts count every item too), checked every 100 calls.

AI off: no tutor, hints or worked solution on this one. Your own thinking only.

Spotted a problem in this lesson? Report it · Ask about this lesson

This exercise opens soon

Finish the lesson before it and this one unlocks. The whole course is free, no account needed, and you can read this lesson right now.