Course topics

By WebNest Studio

Python Tutorial

Classic Python Programs for Practice

Small, classic programs are the best way to build fluency and prepare for coding interviews and exams. Each one combines basics — loops, conditions, functions, recursion, data structures — into a complete solution.

This lesson solves the most commonly asked programs, several in more than one way: Fibonacci numbers (including the nth Fibonacci number), prime checks and the Sieve of Eratosthenes, palindromes, factorial, the second largest number in a list, Tower of Hanoi, Armstrong numbers, anagrams, reversing, GCD, FizzBuzz, and a simple pattern.

How to Practise

For each program: write it yourself before reading the solution; test edge cases (empty list, 0, 1, negative numbers, duplicates); then improve it — can you make it faster, shorter, or more readable? Compare an iterative and a recursive solution where both exist.

Complexity Matters

Many of these programs have a naive solution and an efficient one: recursive Fibonacci is exponential, while the iterative version is linear; checking primes by testing every divisor is O(n), while testing up to √n is O(√n), and the Sieve finds all primes up to n in O(n log log n). Interviewers expect you to discuss this.

Examples

Fibonacci: first n numbers and the nth number (three ways)

Python
from functools import cache

def fibonacci_series(n):
    a, b, series = 0, 1, []
    for _ in range(n):
        series.append(a)
        a, b = b, a + b
    return series

def nth_fibonacci_iterative(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

@cache
def nth_fibonacci_recursive(n):
    return n if n < 2 else nth_fibonacci_recursive(n - 1) + nth_fibonacci_recursive(n - 2)

def fib_generator():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

print(fibonacci_series(10))
print(nth_fibonacci_iterative(50), nth_fibonacci_recursive(50))
gen = fib_generator()
print([next(gen) for _ in range(8)])
Output
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
12586269025 12586269025
[0, 1, 1, 2, 3, 5, 8, 13]

Primes: a single check and the Sieve of Eratosthenes

Python
import math

def is_prime(n):
    if n < 2:
        return False
    if n % 2 == 0:
        return n == 2
    return all(n % d for d in range(3, math.isqrt(n) + 1, 2))

def sieve(limit):
    is_p = [True] * (limit + 1)
    is_p[0:2] = [False, False]
    for n in range(2, math.isqrt(limit) + 1):
        if is_p[n]:
            is_p[n * n::n] = [False] * len(range(n * n, limit + 1, n))
    return [n for n, prime in enumerate(is_p) if prime]

print([n for n in range(20) if is_prime(n)])
print(is_prime(97), is_prime(1_000_003))
print(sieve(50))
Output
[2, 3, 5, 7, 11, 13, 17, 19]
True True
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Second largest number, palindromes, anagrams and reversing

Python
def second_largest(numbers):
    first = second = None
    for n in numbers:
        if first is None or n > first:
            first, second = n, first
        elif n != first and (second is None or n > second):
            second = n
    return second

def is_palindrome(text):
    cleaned = "".join(ch.lower() for ch in text if ch.isalnum())
    return cleaned == cleaned[::-1]

def are_anagrams(a, b):
    return sorted(a.replace(" ", "").lower()) == sorted(b.replace(" ", "").lower())

print(second_largest([10, 45, 32, 45, 8]), second_largest([5, 5]), sorted(set([10, 45, 32, 45, 8]))[-2])
print(is_palindrome("A man, a plan, a canal: Panama"), is_palindrome("Python"), str(12321) == str(12321)[::-1])
print(are_anagrams("Listen", "Silent"), are_anagrams("Dormitory", "Dirty room"), are_anagrams("abc", "abd"))
print("Webnest"[::-1], int(str(12345)[::-1]), " ".join(reversed("learn python daily".split())))
Output
32 None 32
True False True
True True False
tsenbeW 54321 daily python learn

Tower of Hanoi

Python
def hanoi(n, source, target, spare, moves):
    if n == 0:
        return
    hanoi(n - 1, source, spare, target, moves)
    moves.append(f"Move disk {n} from {source} to {target}")
    hanoi(n - 1, spare, target, source, moves)

moves = []
hanoi(3, "A", "C", "B", moves)
print("\n".join(moves))
print("total moves:", len(moves), "| formula 2^n - 1 =", 2 ** 3 - 1)
Output
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
total moves: 7 | formula 2^n - 1 = 7

Factorial, Armstrong numbers, GCD, FizzBuzz and a pattern

Python
import math

def factorial(n):
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

def is_armstrong(n):
    digits = str(n)
    return n == sum(int(d) ** len(digits) for d in digits)

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

print(factorial(10), math.factorial(10))
print([n for n in range(1, 1000) if is_armstrong(n) and n > 9])
print(gcd(84, 36), math.gcd(84, 36))
print(" ".join("FizzBuzz" if i % 15 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else str(i) for i in range(1, 16)))
for row in range(1, 5):
    print(" " * (4 - row) + "*" * (2 * row - 1))
Output
3628800 3628800
[153, 370, 371, 407]
12 12
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
   *
  ***
 *****
*******

Common Mistakes

  • Using plain recursive Fibonacci for large n without memoization.
  • Finding the second largest with sorted(nums)[-2], which fails with duplicates of the maximum.
  • Checking primes by testing all divisors up to n instead of √n.
  • Ignoring case, spaces and punctuation in palindrome and anagram checks.

Key Points to Remember

  • Classic programs build fluency with loops, recursion and data structures.
  • Prefer efficient versions: iterative/memoized Fibonacci, √n prime checks, the Sieve.
  • Handle edge cases: duplicates, empty input, 0 and 1.
  • Tower of Hanoi needs 2^n − 1 moves and is the classic recursion example.

Practice the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.