This episode takes you from scripts to a structured project: creating a package, writing a minimal setup.cfg or pyproject.toml, using pip install -e for development, and running the proper virtual environment workflow.

Up to this point you've been writing single scripts. Episode 7 changes that: we build a structured package, declare metadata with pyproject.toml, and install the package in editable mode for development.
The virtual environment we built in episode 0 now takes on a full role. After this episode, your project will have the same foundation as a professional library — ready for dependency management in episode 8 and publication in episode 19.
A package is a directory containing __init__.py. The standard Python project structure:
belajar_kalkulator/
belajar_kalkulator/
__init__.py
aritmetika.py
pyproject.toml
README.mdThe outer belajar_kalkulator directory is the project root, and the inner one is the package. The __init__.py file marks the directory as a package. Let's create it:
mkdir belajar_kalkulator
cd belajar_kalkulator
mkdir belajar_kalkulator
touch belajar_kalkulator/__init__.pyThe command mkdir belajar_kalkulator creates the project directory, then mkdir belajar_kalkulator creates the package directory inside it. touch __init__.py creates the package marker file.
Fill the package with modules and export functions through __init__.py:
def tambah(a, b):
return a + b
def kurang(a, b):
return a - b
def kali(a, b):
return a * bThe file aritmetika.py contains pure functions. To make them importable as from belajar_kalkulator import tambah, export them in __init__.py:
from belajar_kalkulator.aritmetika import tambah, kurang, kali
__all__ = ["tambah", "kurang", "kali"]__all__ defines what gets exported when you use from belajar_kalkulator import *. With this structure, the package can already be used locally.
pyproject.toml is the standard format for Python project metadata (PEP 621). Here's its minimal version:
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "belajar-kalkulator"
version = "0.1.0"
description = "Package kalkulator untuk belajar Python"
requires-python = ">=3.12"The [project] section declares the package's name, version, and description. build-backend determines the build tool. requires-python tells you the minimum Python version needed.
Before pyproject.toml became popular, setup.cfg was the main choice:
[metadata]
name = belajar-kalkulator
version = 0.1.0
description = Package kalkulator untuk belajar Python
[options]
packages = find:The setup.cfg form is also valid. However, pyproject.toml is now the standard and we'll deepen it in episode 19. For this series, we focus on pyproject.toml.
Editable mode installs the package so code changes take effect immediately without reinstalling:
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .pip install -e . installs the package from the current directory in editable mode. The -e flag means changes to your code are used directly without a reinstall — ideal for development.
Test that the package is installed correctly:
python3 -c "from belajar_kalkulator import tambah; print(tambah(3, 4))"The command python3 -c "from belajar_kalkulator import tambah" imports the package and calls the function. Output 7 means the package installed successfully. From anywhere inside the venv, this package can be imported.
Virtual environments isolate each project's dependencies. Without them, installing packages into the system Python could break other environments. The main rules:
As a project grows, dependencies must be recorded. Add them to pyproject.toml:
[project]
name = "belajar-kalkulator"
version = "0.1.0"
description = "Package kalkulator untuk belajar Python"
requires-python = ">=3.12"
dependencies = [
"pytest>=8.0"
]Writing dependencies in dependencies = [...] makes them install automatically when you run pip install -e .. This replaces manual one-by-one installation and becomes the basis for reproducible environments in episode 8.
One habit is mandatory: check the active environment before running Python. Run which python3 — the output should point to .venv/bin/python3. If not, activate the venv first. This consistency will save you from many dependency bugs.
Key takeaways:
In the next episode, episode 8, we'll cover dependency management and reproducible environments — comparing requirements.txt and pyproject.toml, Poetry and Flit, lockfiles with pip-tools, pipx for CLI tools, and virtualenv best practices. Your project will become truly reproducible!