Morning! π βοΈ
This is it.
Only the bones are left - the def line, the loop header, and the two return verdicts. Everything in between is yours to write.
Don't scroll ahead. Look at the skeleton below and fill in the whole body from memory: the length check, the flag, the loop that hunts for a number, and the decision at the end.
However it comes out, you've done something most people learning to code never do: you didn't copy a function. You kept one.
In today's email...
-
π Day 5: Full recall - write the whole body yourself
-
π Assembling all four pieces into one function
-
π One last full trace, start to finish
-
β Write it from memory, then let Ada check it
THE FUNCTION π
def check_password(password):
____________________
____________________
____________________
for char in password:
____________________
____________________
____________________
return "Strong"
return "Medium"
TODAY'S LINE π
Today the whole body is blank, so let's assemble it in order - four pieces you've already learned:
-
The length check.
if len(password) < 8:βreturn "Weak". Catch the too-short passwords first and stop. -
The flag.
has_number = False. Start by assuming there's no digit. -
The loop.
for char in password:walks each character, andif char.isdigit():βhas_number = Trueflips the flag the moment it finds a number. -
The decision.
if has_number:βreturn "Strong", otherwise fall through toreturn "Medium".
Guard. Flag. Walk. Decide. If you can hold those four words, the lines come back on their own - that's the whole point of this week.

Read those four beats once, then look away and write them into the skeleton. That's the real skill you built this week - not memorizing characters, but understanding a function well enough to rebuild it. That transfers to every function you'll ever write.
TRACE IT π
One last walk - and this time take the least obvious password of the three, "raspberry":
-
Line 2
len("raspberry")is9. Is9 < 8? No. Keep going. -
Line 4
has_number = False. -
Lines 5-7 nine passes:
r,a,s,p,b,e,r,r,y. Not one of them is a digit, sohas_numbernever moves. -
Line 8
has_numberis stillFalse. The branch is skipped. -
Line 10
return "Medium". The default catches it.
Long enough to survive the gate, but nothing to make it strong. That's "Medium" - and the only line that ever produced it is the bare one at the bottom.
COMMON BUG π
When you write this from memory, there's one slip that gets almost everyone: putting the flag inside the loop.
for char in password:
has_number = False
if char.isdigit():
has_number = True
That resets the flag on every single pass. On "pass1word" the flag flips when the loop reaches the 1... and is wiped on the very next character. By the time the loop ends, has_number is False again and the function returns "Medium" for a password that clearly has a digit in it.
Only if the last character happens to be a digit does the answer survive to line 8. Which makes this the kind of bug that passes a lucky test: "Sunrise7" returns the right verdict even with this broken code, because the digit is last. "pass1word" doesn't.
The rule: anything you want to remember across the whole loop has to be created before the loop starts. Line 4 sits outside for a reason.
Second-most-common: mixing tabs and spaces while retyping. Python measures indentation, so a tab where the rest of the file uses spaces raises TabError. Pick four spaces and never look back.
WHY IT MATTERS π§
You can now read this function's shape anywhere: guard, gather, decide. Every rule engine, every input validator, every "is this record OK?" check in the world is that shape, wearing different clothes.
And you got there without a single flashcard. You saw a thing, then reached for it a little harder each day until reaching stopped being necessary. That's the method - and it works on the next 51 functions exactly the same way.
WITH ADA β
Write your full check_password() from memory first - no peeking - then hand it to Ada at py-and-jam.com.
She'll check it for you: run it, compare the verdicts, and point out anything that's off. If it runs clean and the results make sense, you've got it - cold.
LEVEL UP π Once your version passes, make the loop stop as soon as it's sure:
for char in password:
if char.isdigit():
has_number = True
break
break leaves the loop immediately. On a 40-character password with a digit up front, that's 39 passes you never have to run - and the answer is identical. Correct first, then fast: always in that order.
ANSWER KEY β
Blanked today: lines 2, 3, 4, 6, 7 and 8 - the entire body. Only the frame stayed: the def line, the loop header, and the two returns.
Today's blanked lines, in order:
if len(password) < 8:
return "Weak"
has_number = False
if char.isdigit():
has_number = True
if has_number:
The full function:
def check_password(password):
if len(password) < 8:
return "Weak"
has_number = False
for char in password:
if char.isdigit():
has_number = True
if has_number:
return "Strong"
return "Medium"

That's a real, working Python function - and it's yours now. A new one lands Monday morning: another everyday problem, solved in a handful of lines you'll keep the same way. Rest your hands this weekend. You've earned it. π The Py & Jam Team
There's a better way to learn.
Py & Jam delivers one memorable disappearing function to your inbox daily. Itβs a simple, effective way to build fluency without the frustration.