Skip to content

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:

temperature_converter.py
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 result

I 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

temp_converter.py
def fahrenheit_to_celsius(fahrenheit):
return (fahrenheit - 32) * 5 / 9
# YOUR TASK: Add the reverse function below
def celsius_to_fahrenheit(celsius):
# Round to 1 decimal place
pass # Replace this with your code
# Test your code
print(fahrenheit_to_celsius(100)) # Should print 37.78
print(celsius_to_felsius(37)) # Should print 98.6

I 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

list_stats.py
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
}
# Test
print(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 = 1
for num in numbers:
product *= num

Exercise 3: String Manipulator Update

string_tools.py
def reverse_string(s):
return s[::-1]
# YOUR TASK: Add palindrome checker
def is_palindrome(s):
pass # Return True if s reads same forwards/backwards
# Test
print(reverse_string("hello")) # "olleh"
print(is_palindrome("racecar")) # True
print(is_palindrome("python")) # False

I 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

buggy_sum.py
def sum_list(numbers):
total = 0
for i in range(len(numbers) + 1): # BUG HERE
total += numbers[i]
return total
# Test - This will crash
print(sum_list([1, 2, 3]))

I ran it and got:

IndexError: list index out of range

The 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 +1

Exercise 5: Function Return Error

buggy_return.py
def calculate_discount(price, discount_percent):
discount = price * (discount_percent / 100)
final_price = price - discount
# BUG: Missing return statement
# Test
order_total = calculate_discount(100, 20)
print(order_total) # Prints: None

I realized the function calculated but didn’t return anything. Added:

return final_price

Exercise 6: List Index Error

buggy_filter.py
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
# Test
print(get_first_even([1, 2, 4, 6])) # Returns 4, should return 2

I spotted it: The loop starts at index 1, skipping the first element.

Fixed:

for i in range(len(numbers)): # Start at 0

Tier 3: Code Completion (Intermediate Beginner)

Fill in the blanks of partially-written code.

Exercise 7: Complete the Calculator

calculator.py
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
# Test
print(calculate(10, 5, 'add')) # Should print 15
print(calculate(10, 5, 'subtract')) # Should print 5
print(calculate(10, 5, 'multiply')) # Should print 50
print(calculate(10, 5, 'divide')) # Should print 2.0
print(calculate(10, 0, 'divide')) # Should handle gracefully

I 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 result

Exercise 8: Finish the Filter

list_filter.py
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
# Test
print(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

password_gen.py
import random
import 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)
# Test
print(generate_password(8)) # 8-character password
print(generate_password(12)) # 12-character password
print(generate_password(5)) # Error message

I wrote this from scratch after 3 weeks of practice. It took me 20 minutes, not 2 hours like before.

Exercise 10: CLI Quiz App

quiz_app.py
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 quiz
if __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:

PlatformDifficultyCostBest ForLink
CodingBatBeginnerFreeQuick warm-ups (5-10 min)codingbat.com/python
EdabitBeginner-IntermediateFreemiumBite-sized daily practiceedabit.com/python
ExercismAll levelsFreeMentor feedback on solutionsexercism.org/python
HackerRankBeginner-AdvancedFreemiumStructured skill trackshackerrank.com/python
LeetCodeIntermediate-AdvancedFreeAlgorithm practiceleetcode.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:

  1. Tier 1 builds confidence through small wins
  2. Tier 2 trains pattern recognition (debugging)
  3. Tier 3 scaffolds the cognitive load (filling blanks)
  4. 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:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments