How to practice Python when you can't write code despite understanding tutorials
Problem
I watched 20 hours of Python tutorials. I understood every concept. Variables? Got it. Loops? Easy. Functions? Makes sense.
But when I opened a blank text editor to write my first program, I froze.
I stared at the blinking cursor for 10 minutes. I couldn’t even write a simple temperature converter without looking up a tutorial.
I felt like I had learned Spanish vocabulary for 6 months but couldn’t order a taco. This is the comprehension-production gap.
Environment
- Python 3.11
- VS Code (but any editor works)
- Zero actual coding experience (only tutorial watching)
What happened?
I spent 2 months “learning” Python by watching tutorials. I could explain what a for loop does, identify a list comprehension, and tell you when to use a dictionary.
Here’s what I understood:
- Variables store data
- Functions organize code
- Loops repeat actions
- Conditionals make decisions
But when I tried to write this simple program:
def fahrenheit_to_celsius(fahrenheit): return (fahrenheit - 32) * 5 / 9
def celsius_to_fahrenheit(celsius): return (celsius * 9 / 5) + 32
# Add code to get user input and display resultI couldn’t finish it. I didn’t know:
- How to get input from the user
- Whether to use
input()or command-line arguments - How to format the output nicely
- Whether to put this in a
main()function or not
The problem? I had passive knowledge (reading) but no active skills (writing).
How to solve it?
I realized tutorials teach you to read code, not write it. So I built a progressive exercise system that bridges this gap through four tiers.
Tier 1: Code Modification (Entry Level)
Instead of writing from scratch, start by modifying working code.
Exercise 1: Temperature Converter Extension
def fahrenheit_to_celsius(fahrenheit): return (fahrenheit - 32) * 5 / 9
# YOUR TASK: Add the reverse function belowdef celsius_to_fahrenheit(celsius): # Round to 1 decimal place pass # Replace this with your code
# Test your codeprint(fahrenheit_to_celsius(100)) # Should print 37.78print(celsius_to_felsius(37)) # Should print 98.6I started with the given function and added:
def celsius_to_fahrenheit(celsius): fahrenheit = (celsius * 9 / 5) + 32 return round(fahrenheit, 1)It worked. This tiny win built confidence.
Exercise 2: List Operations Extension
def calculate_stats(numbers): total = sum(numbers) count = len(numbers)
# YOUR TASK: Add average and product calculations average = None # Replace None product = None # Replace None
return { 'sum': total, 'count': count, 'average': average, 'product': product }
# Testprint(calculate_stats([1, 2, 3, 4]))# Should return: {'sum': 10, 'count': 4, 'average': 2.5, 'product': 24}I added:
average = total / count if count > 0 else 0
product = 1for num in numbers: product *= numExercise 3: String Manipulator Update
def reverse_string(s): return s[::-1]
# YOUR TASK: Add palindrome checkerdef is_palindrome(s): pass # Return True if s reads same forwards/backwards
# Testprint(reverse_string("hello")) # "olleh"print(is_palindrome("racecar")) # Trueprint(is_palindrome("python")) # FalseI wrote:
def is_palindrome(s): return s == s[::-1]After 10 modification exercises, I stopped freezing on blank screens.
Tier 2: Bug Fixing (Beginner)
Now I practice reading code to find errors.
Exercise 4: Loop Counter Fix
def sum_list(numbers): total = 0 for i in range(len(numbers) + 1): # BUG HERE total += numbers[i] return total
# Test - This will crashprint(sum_list([1, 2, 3]))I ran it and got:
IndexError: list index out of rangeThe problem: range(len(numbers) + 1) goes too far. The list has indices 0, 1, 2, but the loop tries 0, 1, 2, 3.
I fixed it:
for i in range(len(numbers)): # Removed +1Exercise 5: Function Return Error
def calculate_discount(price, discount_percent): discount = price * (discount_percent / 100) final_price = price - discount # BUG: Missing return statement
# Testorder_total = calculate_discount(100, 20)print(order_total) # Prints: NoneI realized the function calculated but didn’t return anything. Added:
return final_priceExercise 6: List Index Error
def get_first_even(numbers): for i in range(1, len(numbers)): # BUG: Starts at wrong index if numbers[i] % 2 == 0: return numbers[i] return None
# Testprint(get_first_even([1, 2, 4, 6])) # Returns 4, should return 2I spotted it: The loop starts at index 1, skipping the first element.
Fixed:
for i in range(len(numbers)): # Start at 0Tier 3: Code Completion (Intermediate Beginner)
Fill in the blanks of partially-written code.
Exercise 7: Complete the Calculator
def calculate(a, b, operation): """ Perform basic arithmetic operations.
Args: a: First number b: Second number operation: 'add', 'subtract', 'multiply', or 'divide'
Returns: Result of calculation or None if invalid operation """ # YOUR TASK: Complete this function if operation == 'add': result = None elif operation == 'subtract': result = None elif operation == 'multiply': result = None elif operation == 'divide': result = None # Handle division by zero else: return None
return result
# Testprint(calculate(10, 5, 'add')) # Should print 15print(calculate(10, 5, 'subtract')) # Should print 5print(calculate(10, 5, 'multiply')) # Should print 50print(calculate(10, 5, 'divide')) # Should print 2.0print(calculate(10, 0, 'divide')) # Should handle gracefullyI completed it:
def calculate(a, b, operation): if operation == 'add': result = a + b elif operation == 'subtract': result = a - b elif operation == 'multiply': result = a * b elif operation == 'divide': if b == 0: return "Cannot divide by zero" result = a / b else: return None
return resultExercise 8: Finish the Filter
def filter_even_numbers(numbers): """ Return a new list containing only even numbers from input.
Args: numbers: List of integers
Returns: List of even integers """ # YOUR TASK: Complete this using list comprehension evens = [num for num in numbers if None] # Fix the condition
return evens
# Testprint(filter_even_numbers([1, 2, 3, 4, 5, 6])) # [2, 4, 6]print(filter_even_numbers([7, 11, 13])) # []I fixed the condition:
evens = [num for num in numbers if num % 2 == 0]Tier 4: From-Scratch Challenges (Advanced Beginner)
After 3 weeks of tiers 1-3, I started writing code from scratch.
Exercise 9: Password Generator
import randomimport string
def generate_password(length=12): """ Generate a random password with mixed characters.
Args: length: Password length (8-16 characters)
Returns: Random password string """ if length < 8 or length > 16: return "Password length must be between 8 and 16"
# Create character pools lowercase = string.ascii_lowercase uppercase = string.ascii_uppercase digits = string.digits special = "!@#$%^&*"
# Ensure at least one of each type password = [ random.choice(lowercase), random.choice(uppercase), random.choice(digits), random.choice(special) ]
# Fill remaining length all_chars = lowercase + uppercase + digits + special for _ in range(length - 4): password.append(random.choice(all_chars))
# Shuffle the password random.shuffle(password)
return ''.join(password)
# Testprint(generate_password(8)) # 8-character passwordprint(generate_password(12)) # 12-character passwordprint(generate_password(5)) # Error messageI wrote this from scratch after 3 weeks of practice. It took me 20 minutes, not 2 hours like before.
Exercise 10: CLI Quiz App
def run_quiz(): """ Run a simple command-line quiz with score tracking. """ questions = [ { 'question': 'What is the keyword to define a function in Python?', 'options': ['func', 'def', 'function', 'define'], 'answer': 'def' }, { 'question': 'Which data type is immutable?', 'options': ['list', 'dict', 'tuple', 'set'], 'answer': 'tuple' }, { 'question': 'What does len() function return?', 'options': ['Length of object', 'Type of object', 'Value of object', 'None'], 'answer': 'Length of object' }, { 'question': 'How do you start a comment in Python?', 'options': ['//', '#', '/*', '--'], 'answer': '#' }, { 'question': 'What is the output of print(2 ** 3)?', 'options': ['6', '8', '9', '5'], 'answer': '8' } ]
score = 0 total = len(questions)
for i, q in enumerate(questions, 1): print(f"\nQuestion {i}: {q['question']}")
for idx, option in enumerate(q['options'], 1): print(f" {idx}. {option}")
user_answer = input("Your answer (1-4): ").strip()
# Check if user entered a number if not user_answer.isdigit(): print("Invalid input! Please enter a number.") continue
answer_index = int(user_answer) - 1
# Validate range if answer_index < 0 or answer_index >= len(q['options']): print("Invalid choice! Please try again.") continue
selected_answer = q['options'][answer_index]
# Check correctness if selected_answer == q['answer']: print("Correct!") score += 1 else: print(f"Wrong! The correct answer is: {q['answer']}")
# Final score percentage = (score / total) * 100 print(f"\n{'='*40}") print(f"Quiz completed!") print(f"Your score: {score}/{total} ({percentage:.1f}%)")
if percentage >= 80: print("Excellent work!") elif percentage >= 60: print("Good job!") else: print("Keep practicing!")
# Run the quizif __name__ == "__main__": print("Welcome to the Python Quiz!") print("Answer 5 questions to test your knowledge.\n") run_quiz()This took 35 minutes to write. A month ago, I couldn’t have started it.
Where to practice?
I use several platforms depending on my goal:
| Platform | Difficulty | Cost | Best For | Link |
|---|---|---|---|---|
| CodingBat | Beginner | Free | Quick warm-ups (5-10 min) | codingbat.com/python |
| Edabit | Beginner-Intermediate | Freemium | Bite-sized daily practice | edabit.com/python |
| Exercism | All levels | Free | Mentor feedback on solutions | exercism.org/python |
| HackerRank | Beginner-Advanced | Freemium | Structured skill tracks | hackerrank.com/python |
| LeetCode | Intermediate-Advanced | Free | Algorithm practice | leetcode.com |
My daily routine (30 minutes):
- 5 minutes: Review yesterday’s code
- 15 minutes: New exercise at current tier
- 5 minutes: Read the solution (even if I solved it)
- 5 minutes: Write down what I learned in a code journal
My progression timeline
Week 1-2 (Tier 1): Modified 20 code snippets. Still felt slow, but I stopped freezing.
Week 3-4 (Tier 2): Fixed 15 bugs. Started recognizing common patterns (off-by-one errors, missing returns).
Week 5-6 (Tier 3): Completed 10 partial programs. Could write simple functions without looking up syntax.
Week 7+: Writing from scratch (Tier 4). Built password generator, quiz app, and a simple to-do list.
The reason
The comprehension-production gap is normal in language learning, and programming is a language. I had receptive fluency (reading) but no productive fluency (writing).
Cognitive science shows that deliberate practice - focused, progressive exercises with feedback - builds skills 10x faster than passive consumption.
My four-tier system works because:
- Tier 1 builds confidence through small wins
- Tier 2 trains pattern recognition (debugging)
- Tier 3 scaffolds the cognitive load (filling blanks)
- Tier 4 applies skills to new problems
Summary
In this post, I showed how to bridge the gap between understanding Python tutorials and actually writing code through a four-tier progressive exercise system. The key point is to start with code modification, then bug fixing, then completion, before attempting from-scratch projects.
Start with Tier 1, Exercise 1 right now. Don’t read the rest of this post until you’ve completed it. Seriously - paste that temperature converter code into your editor and add the reverse function. I’ll wait.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 CodingBat - Warm-up Python Problems
- 👨💻 LeetCode Easy Problems
- 👨💻 Exercism - Python Track with Mentor Feedback
- 👨💻 HackerRank Python Practice
- 👨💻 Edabit - Bite-sized Python Challenges
- 👨💻 Python Official Documentation
- 👨💻 Anders Ericsson - Deliberate Practice Research
- 👨💻 Josh Kaufman - The First 20 Hours
- 👨💻 r/learnprogramming
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments