S
Saurav Danej
90-Day AI/ML LinkedIn Content System
← All days
2
Day 2 of 90Python

Set up Python so it never fights you again

POST 1 of 5 MorningPythonConcept

Why your Python setup keeps breaking

Every beginner Python question I've ever answered eventually traces back to one root cause — the environment is broken.

You install one library, it complains about another. You upgrade pip, half your venv evaporates. Your laptop now has python2, python3.9, python3.11, anaconda-python, brew-python, and the system one — all fighting for PATH supremacy. You spend more time googling 'ModuleNotFoundError' than actually writing code.

The fix isn't more tutorials. It's better tools. Most Python tutorials are stuck in 2018 — pip + venv + setup.py. That stack worked. It also generated 90% of the pain.

In 2026, the cleanest stack is three tools, set up once.

uv — a Rust-written installer + venv manager from Astral. Replaces pip, virtualenv, pyenv, and pip-tools in one binary. Roughly 50-100x faster, with proper lockfiles by default.

ruff — also from Astral. Lints AND formats your code. Replaces black, flake8, isort, and most of pylint. Same speed story — Rust under the hood, faster than anything Python-based.

pyproject.toml — one config file. Modern PEP-517 standard. Every modern tool reads it. Goodbye to setup.py + setup.cfg + tox.ini + .flake8 + .pre-commit-config.yaml soup.

The upfront cost of switching is one afternoon. The downstream payoff is — and I mean this literally — the rest of your Python career without environment fights.

We set this up tomorrow's section. Today, just believe me when I say the old way is what's been breaking you.
#AI#MachineLearning#Python#100DaysOfCode#BuildInPublic#PythonTips#uv
POST 2 of 5 MiddayPythonDeep dive

uv — the Python installer that's actually fast

Let's talk about uv specifically, because it's the single biggest quality-of-life upgrade Python has had in a decade.

uv is what pip should have been. Written in Rust by Astral (same team that built ruff), it's a drop-in replacement for pip + virtualenv + pyenv + pip-tools — all of them, in one self-contained binary.

The daily-life impact is hard to oversell.

uv venv creates a fresh virtual environment in about 50 milliseconds. The old stack took 5+ seconds. You stop avoiding venvs because they're now free.

uv pip install runs 10 to 100x faster than plain pip. Installing PyTorch + Transformers + a few utilities used to take 90 seconds; now it's under 10. On bigger projects with hundreds of dependencies, the difference is more like 5 minutes versus 30.

uv python install 3.12 installs the Python interpreter itself. No more pyenv, no more 'which python on this machine'. uv manages the runtime.

Lockfiles by default. Reproducible installs across teammates and CI without a separate tool like pip-tools.

If you've been waiting for 'Python with cargo's UX' — that's exactly what this is. Try it for one week on one project. Just one. By day three you won't go back. I switched in March 2025, and the only times I've used pip since are when working in someone else's old repo.

Install: curl -LsSf https://astral.sh/uv/install.sh | sh (or pipx install uv on Windows). Tomorrow we use it for real.
#AI#MachineLearning#Python#100DaysOfCode#BuildInPublic#uv#PythonTooling
POST 3 of 5 AfternoonPythonCode

Project setup in 4 commands

From zero to a working AI/ML project in four commands. Run them once at the start of every new repo and never think about your environment again.

First command, uv init creates a project skeleton — pyproject.toml, README, .python-version, src layout if you want it. It's like running 'cargo init' for Python.

Second, cd into the new directory. (Yes, this counts as a command. I'm being strict.)

Third, uv add adds dependencies. uv reads pyproject.toml, resolves the dependency graph, installs everything into a hidden .venv, and writes a lockfile so your teammates get the exact same versions. Add as many libraries as you want — it batches them and runs in seconds.

Fourth, uv run executes a Python script (or any command) inside the project's environment. No 'source .venv/bin/activate' dance. uv handles activation transparently.

That's the whole loop — init, cd, add, run. The .venv directory and uv.lock file go into .gitignore (well, .venv does; you commit uv.lock so installs are reproducible).

Upgrade dependencies later? uv lock --upgrade. Want to remove one? uv remove. Want a fresh environment from scratch? Delete .venv and rerun uv sync — it rebuilds in seconds from the lockfile.

Four commands. Once. Now you can stop thinking about Python plumbing and start writing the code that actually matters. We use this exact setup in every code post for the rest of the 90 days.
#AI#MachineLearning#Python#100DaysOfCode#BuildInPublic#DevSetup#uv
POST 4 of 5 EveningPythonTip

One pyproject.toml beats five config files

If you've worked on legacy Python projects, you've seen this graveyard — setup.py, setup.cfg, .flake8, .black, tox.ini, MANIFEST.in. Each one a snowflake config for some tool, each one slightly out of sync with the others, each one occasionally undone by an autoformatter that didn't read the right config.

Kill all of them. pyproject.toml replaces every single one.

PEP-517 made pyproject.toml the canonical Python config. PEP-518, 621, and a handful of others extended it. By 2026, every modern Python tool reads it — uv, ruff, pytest, mypy, hatch, build, even some legacy holdouts via plugins.

My minimum file is twelve lines. It declares the project name, Python version, dependencies, and tool configurations under [tool.<name>] sections. That's the entire build/config story.

[project] holds metadata and dependencies — name, version, python-requires, dependencies list.
[tool.ruff] holds your lint and format rules — line length, which rules to enable, which to ignore.
[tool.pytest.ini_options] holds your test configuration.
[tool.mypy] holds your type-check configuration.

One file. One source of truth. When you onboard a new dev, they read pyproject.toml and they know everything. When you change a rule, you change it in one place.

If a tool you use *still* wants its own dotfile, look for a [tool.<name>] section first — there almost always is one in modern releases. If there isn't, file an issue. The migration is one-way; the world is moving.

One file beats five. Always.
#AI#MachineLearning#Python#100DaysOfCode#BuildInPublic#CleanCode#PythonTooling
POST 5 of 5 NightPythonRecap

Day 2 — your environment will never fight you again

End of Day 2.

If you only do one practical thing this week, do today's setup. The compounding payoff is enormous. I genuinely believe that the gap between developers who ship and developers who don't often comes down to whether they have to fight their tools every morning.

What we set up today, in order.

Morning explained why your Python keeps breaking — too many tools, none of them sharing config. The fix is fewer tools that share more.

Midday introduced uv as that fewer-tools answer. One Rust-written binary that replaces pip + virtualenv + pyenv + pip-tools, runs 10-100x faster, and has proper lockfiles built in.

Afternoon was the four commands — uv init, cd, uv add, uv run. That's the entire create-a-new-project workflow. We'll use it again on Day 7 when we start the GitHub repo and again on Day 78 when we begin the automation week.

Evening was the case for one pyproject.toml over five legacy config files. PEP-517 won. The world is moving.

If your hands itched to migrate while reading this, that's good. Pick one project this weekend, port it to uv + ruff + pyproject.toml, time how long the install loop takes before and after. The first time you delete .venv and rebuild in 8 seconds instead of 90, you'll know.

Tomorrow, Day 3, we go into Python's type system. Variables, strings, numbers, and the part everyone underestimates — type hints. The reason your future self stops cursing your past self.

See you in the morning.
#AI#MachineLearning#Python#100DaysOfCode#BuildInPublic#Python3#DailyRecap