Python Tutorial #16: Type Hints Deep Dive — Writing Safer Python

In the previous tutorial, we learned about context managers. Now let’s take a deep dive into type hints — annotations that make your code safer, more readable, and easier to refactor. We have been using basic type hints since Tutorial #3. Now it is time to learn the advanced types: Optional, Union, Literal, Annotated, TypeAlias, Callable, and more. By the end of this tutorial, you will know how to annotate any Python code and use tools like mypy to catch bugs before runtime. ...

April 28, 2026 · 10 min

Python Tutorial #15: Context Managers — with Statement and Resource Management

In the previous tutorial, we learned about decorators. Now let’s learn about context managers — the mechanism behind the with statement. You have been using with since the file I/O tutorial: with open("file.txt") as f: content = f.read() # File is automatically closed here But what actually happens behind the scenes? And how do you create your own with-compatible objects? By the end of this tutorial, you will understand the protocol behind context managers and know how to build your own for resource management, timing, transactions, and more. ...

April 28, 2026 · 9 min

Python Tutorial #14: Decorators — Functions That Modify Functions

In the previous tutorial, we learned about generators and iterators. Now let’s learn about decorators — a powerful pattern that lets you modify functions without changing their code. Decorators are one of Python’s most distinctive features. They are used everywhere: web frameworks (Flask, FastAPI), testing (pytest), caching, authentication, and validation. By the end of this tutorial, you will know how to create your own decorators and understand the ones you encounter in libraries. ...

April 28, 2026 · 9 min

Python Tutorial #13: Generators and Iterators — Lazy Data Processing

In the previous tutorial, we learned about file I/O. Now let’s learn about generators and iterators — tools for processing data lazily without loading everything into memory. A generator produces values one at a time. It only calculates the next value when you ask for it. This is called lazy evaluation. Instead of creating a list of one million items in memory, a generator produces them one by one. By the end of this tutorial, you will know how to create generators, build data pipelines, and use itertools for efficient data processing. ...

April 27, 2026 · 10 min

Python Tutorial #12: File I/O — Reading, Writing, and Working with Data

In the previous tutorial, we learned about error handling. Now let’s learn about file I/O — how to read, write, and work with files in Python. Almost every program needs to work with files. Configuration files, log files, data exports, user uploads — files are everywhere. By the end of this tutorial, you will know how to read and write text files, work with JSON and CSV, use pathlib for modern file system operations, and handle temporary files. ...

April 27, 2026 · 9 min

Python Tutorial #11: Error Handling — try/except, Custom Exceptions, and Patterns

In the previous tutorial, we learned about dataclasses and Pydantic. Now let’s learn about error handling — how to write code that fails gracefully instead of crashing. Every program encounters errors. Files go missing, networks fail, users enter bad data. Good error handling is the difference between a program that crashes with a confusing traceback and one that tells the user what went wrong and how to fix it. By the end of this tutorial, you will know how to catch errors, create custom exceptions, and choose the right error handling pattern. ...

April 27, 2026 · 9 min

Python Tutorial #10: Dataclasses and Pydantic — Modern Data Modeling

In the previous tutorial, we learned about OOP: classes, inheritance, and magic methods. Now let’s learn about dataclasses and Pydantic — modern ways to model data without writing boilerplate code. Regular classes need a lot of repetitive code: __init__, __repr__, __eq__. Dataclasses generate all of this for you. Pydantic adds validation on top. By the end of this tutorial, you will know when to use each one and how they compare. ...

April 26, 2026 · 9 min

Python Tutorial #9: OOP — Classes, Inheritance, and Magic Methods

In the previous tutorial, we learned about modules, packages, and virtual environments. Now let’s learn about object-oriented programming (OOP) — the most important paradigm in Python. OOP lets you group related data and behavior into classes. Instead of passing data between separate functions, you bundle everything together. By the end of this tutorial, you will know how to create classes, use inheritance, write magic methods, and design abstract interfaces. What is a Class? A class is a blueprint for creating objects. An object is an instance of a class. Think of a class like a cookie cutter, and objects are the cookies. ...

April 26, 2026 · 11 min

Python Tutorial #8: Modules, Packages, and Virtual Environments

In the previous tutorial, we mastered strings and regular expressions. Now let’s learn how to organize your code into modules and packages, and how to manage dependencies with virtual environments. This is where Python goes from writing scripts to building real projects. By the end of this tutorial, you will know how to import code, structure a project, install packages, and use modern tools like pyproject.toml and uv. What Is a Module? A module is simply a Python file. When you create a file called math_utils.py, you create a module called math_utils. ...

April 26, 2026 · 9 min

Python Tutorial #7: Strings — Methods, Formatting, and Regex Basics

In the previous tutorial, we learned about lists, dictionaries, sets, and tuples. Now let’s take a deep dive into strings — one of the most used data types in Python. We covered string basics in Tutorial #3. This tutorial goes further: advanced methods, formatting tricks, raw strings, and regular expressions. String Methods Strings have many built-in methods. Here are the most useful ones for daily work. Cleaning Text text = " Hello, World! " print(text.strip()) # "Hello, World!" — remove whitespace from both sides print(text.lstrip()) # "Hello, World! " — left side only print(text.rstrip()) # " Hello, World!" — right side only print(text.lower()) # " hello, world! " print(text.upper()) # " HELLO, WORLD! " A common pattern: strip whitespace and normalize case: ...

April 25, 2026 · 9 min