Skip to content

Dev#86

Open
PavelEgorov-ru wants to merge 10 commits into
rohitg00:mainfrom
PavelEgorov-ru:dev
Open

Dev#86
PavelEgorov-ru wants to merge 10 commits into
rohitg00:mainfrom
PavelEgorov-ru:dev

Conversation

@PavelEgorov-ru
Copy link
Copy Markdown

@PavelEgorov-ru PavelEgorov-ru commented May 8, 2026

What this PR does

Kind of change

  • New lesson
  • Fix to an existing lesson
  • Translation
  • New output (prompt, skill, agent, MCP server)
  • Docs / website / tooling

Checklist

  • Code runs without errors with the listed dependencies
  • No comments in code files (docs explain, code is self-explanatory)
  • Built from scratch first, then shown with a framework (for new lessons)
  • Lesson folder matches LESSON_TEMPLATE.md structure
  • ROADMAP.md row for the lesson is a markdown link ([Name](phases/...)), not bare text
  • One lesson per commit (atomic per-lesson rule)
  • Tested locally / code output matches what docs/en.md claims

Phase / lesson

Notes for reviewer

Summary by CodeRabbit

Release Notes

  • Documentation

    • Added comprehensive Russian lesson guides covering development environment setup, Git collaboration, GPU/cloud infrastructure, API integration, Jupyter workflows, and Python environment management.
    • Added setup and collaboration guidelines for Windows/WSL development.
  • New Features

    • Added example OpenRouter API integration script with SDK and HTTP implementations.
  • Exercises

    • Added interactive Jupyter notebooks for performance benchmarking and data analysis practice.
  • Configuration

    • Updated code formatting and linting configuration using Ruff.
    • Enhanced VS Code Python development settings.

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 8, 2026

@PavelEgorov-ru is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Establishes project collaboration rules between Claude and user, configures Windows/WSL/Cursor development setup, applies Ruff linting/formatting via VS Code and pyproject.toml, and delivers complete Russian-language Phase 00 curriculum (six lessons) covering dev environments, Git, GPU access, APIs, Jupyter notebooks, and Python virtual environments with practical code examples and exercises.

Changes

Project Collaboration Infrastructure

Layer / File(s) Summary
Claude collaboration rules & dual-clone workflow
.claude/CLAUDE.md
Defines Russian dialogue language, command execution model (user runs, Claude advises), and dual-clone architecture: Windows as read-only reference, WSL as canonical for edits/commits. Includes file access patterns (UNC paths), sync procedures, startup checklist for new machines, and pitfall warnings.
Windows + WSL2 + Cursor setup
.claude/setup.md
Step-by-step setup from WSL2 installation through SSH keys, repo cloning to dev branch, Cursor IDE integration with WSL, Windows anchor-clone creation for Claude sessions, and synchronization workflow via git pull.
Editor and project tooling configuration
.gitignore, .vscode/settings.json, pyproject.toml
Adds ignore rules for logs and VS Code artifacts, configures Ruff formatter with format-on-save in VS Code, and establishes global Ruff lint/format rules in pyproject.toml (line-length 88, Python 3.12, selected rule families, double quotes).

Phase 00 Course Content

Layer / File(s) Summary
Lesson 01: Development Environment
phases/00-setup-and-tooling/01-dev-environment/docs/ru.md
Introduces four-layer dependency model (system → package managers → runtimes → ML libraries), installation recipes for Python/uv, Node/pnpm, Rust, Julia, and NVIDIA CUDA. Includes verification script, toolchain/phase/language mapping, three exercises with diagnostics, and key terminology.
Lesson 02: Git & Collaboration
phases/00-setup-and-tooling/02-git-and-collaboration/docs/ru.md
Explains commits as snapshots, branch pointers, daily workflow commands, and fork/clone patterns. Provides command-to-use reference, three exercises (clone/branch/push, .gitignore rules, git log inspection), glossary, and takeaways on commits, branches, and avoiding large binaries.
Lesson 03: GPU Setup & Cloud
phases/00-setup-and-tooling/03-gpu-setup-and-cloud/docs/ru.md
Motivates GPU for training (CPU vs GPU throughput), covers local NVIDIA (nvidia-smi, CUDA PyTorch), Google Colab T4, cloud GPU marketplaces, CPU fallback pattern, benchmarking with torch.cuda.synchronize(), VRAM per-parameter sizing, and three exercises (local/Colab benchmarks, model capacity estimation).
Lesson 04: APIs & Keys
phases/00-setup-and-tooling/04-apis-and-keys/docs/ru.md, phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py
Lesson explains HTTP API structure, secure key storage (environment variables, .env), and compares SDK (Anthropic Python/TypeScript) with raw HTTP (urllib). Example script demonstrates OpenRouter calls using both OpenAI SDK with custom base URL and manual JSON over urllib.
Lesson 05: Jupyter Notebooks & Exercises
phases/00-setup-and-tooling/05-jupyter-notebooks/docs/ru.md, scratch/phase-00-lesson-05/exercise-*.ipynb
Lesson covers kernel execution model, cell types, magic commands (%timeit, %matplotlib, %pip, !), rich output, notebooks vs scripts, Colab specifics, and three common pitfalls. Two exercise notebooks: exercise-1 benchmarks list comprehension vs NumPy random generation with %timeit and speedup ratio; exercise-2 loads sales.csv, computes statistics, derives yearly metrics, and plots trends.
Lesson 06: Python Environments & Playground
phases/00-setup-and-tooling/06-python-environments/docs/ru.md, scratch/phase-00-lesson-06/playground-project/pyproject.toml
Lesson addresses dependency hell, explains PEP 668, venv mechanics and activation, compares tools (venv/uv/conda) with uv as course default, covers PyPI/import name mismatches, pyproject.toml structure, lockfile generation, and two isolation exercises. Playground project defines core numpy and optional torch/llm dependency groups.

Poem

🐰 Six lessons born in Russian tongue so clear,
With APIs, GPUs, and Jupyter near,
Git branches dance and venvs isolate,
While Claude and you collaborate—a worthy fate!
From Windows clones to WSL's embrace,
The course takes shape in cyberspace. 🚀

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Dev' is vague and generic, providing no meaningful information about the changeset's primary purpose or the specific modifications included. Replace with a descriptive title that summarizes the main change, such as 'Add setup documentation and tooling configuration' or 'Configure Ruff, VS Code, and development environment.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/CLAUDE.md:
- Around line 80-82: Two fenced code blocks containing shell/PowerShell examples
(the block with git -C "$env:USERPROFILE\Desktop\ai-engineering-from-scratch"
pull and the block with the wsl commands) are missing language identifiers; add
"powershell" (or "bash" if you prefer) after the opening triple backticks for
each fenced block so markdownlint MD040 is satisfied, e.g., change ``` to
```powershell for both the git example and the wsl/ls/whoami example.

In @.claude/setup.md:
- Around line 172-175: The fenced code block containing the two WSL commands
(the block starting with ``` and the lines `wsl -l -q` and `wsl bash -c
"whoami"`) is missing a language identifier which triggers MD040; add an
appropriate language tag (e.g., ```powershell or ```bash) immediately after the
opening backticks so the block becomes ```powershell (or ```bash) to satisfy
markdown linting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4324640b-fc7e-4870-8506-465df2851532

📥 Commits

Reviewing files that changed from the base of the PR and between 02cce05 and d63003f.

📒 Files selected for processing (2)
  • .claude/CLAUDE.md
  • .claude/setup.md

Comment thread .claude/CLAUDE.md
Comment on lines +80 to +82
```
git -C "$env:USERPROFILE\Desktop\ai-engineering-from-scratch" pull
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Specify fence languages for command examples

Line [80] and Line [99]: both fenced blocks are missing language identifiers (MD040). Please tag them (e.g., powershell) to keep markdownlint clean.

Suggested fix
-```
+```powershell
 git -C "$env:USERPROFILE\Desktop\ai-engineering-from-scratch" pull

```diff
-```
+```powershell
 wsl -l -q                                            # имя дистрибутива (первая строка = default)
 wsl bash -c "whoami"                                 # имя WSL-пользователя
 wsl bash -c "ls -d ~/ai-engineering-from-scratch"    # склонирован ли репо
</details>


Also applies to: 99-103

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.1)</summary>

[warning] 80-80: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/CLAUDE.md around lines 80 - 82, Two fenced code blocks containing
shell/PowerShell examples (the block with git -C
"$env:USERPROFILE\Desktop\ai-engineering-from-scratch" pull and the block with
the wsl commands) are missing language identifiers; add "powershell" (or "bash"
if you prefer) after the opening triple backticks for each fenced block so
markdownlint MD040 is satisfied, e.g., change topowershell for both the
git example and the wsl/ls/whoami example.


</details>

<!-- fingerprinting:phantom:triton:hawk -->

<!-- d98c2f50 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment thread .claude/setup.md
Comment on lines +172 to +175
```
wsl -l -q
wsl bash -c "whoami"
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language tag to the fenced command block

Line [172]: the fenced block is missing a language identifier (MD040), which can fail markdown lint checks in CI.

Suggested fix
-  - имя дистрибутива и пользователя получает через
-    ```
+  - имя дистрибутива и пользователя получает через
+    ```powershell
     wsl -l -q
     wsl bash -c "whoami"
     ```
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
wsl -l -q
wsl bash -c "whoami"
```
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 172-172: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/setup.md around lines 172 - 175, The fenced code block containing
the two WSL commands (the block starting with ``` and the lines `wsl -l -q` and
`wsl bash -c "whoami"`) is missing a language identifier which triggers MD040;
add an appropriate language tag (e.g., ```powershell or ```bash) immediately
after the opening backticks so the block becomes ```powershell (or ```bash) to
satisfy markdown linting.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
phases/00-setup-and-tooling/04-apis-and-keys/outputs/first_api_call_openrouter.py (2)

43-61: ⚖️ Poor tradeoff

Add error handling for HTTP requests and JSON parsing.

Similar to call_with_sdk(), this function lacks error handling:

  1. Line 45: Direct dictionary access will raise KeyError if OPENROUTER_API_KEY is not set.
  2. Line 60: urlopen() can raise URLError for network issues or HTTPError for HTTP errors (4xx, 5xx responses).
  3. Line 61: json.loads() can raise JSONDecodeError if the response is malformed.

For educational code demonstrating raw HTTP calls, proper error handling is essential to teach students resilient API integration patterns.

🛡️ Example error handling approach
+from urllib.error import HTTPError, URLError
+
 def call_raw_http() -> None:
     load_dotenv()
-    api_key = os.environ["OPENROUTER_API_KEY"]
+    api_key = os.environ.get("OPENROUTER_API_KEY")
+    if not api_key:
+        raise ValueError("OPENROUTER_API_KEY environment variable not set")
 
     headers = {
         "Content-Type": "application/json",
         "Authorization": f"Bearer {api_key}",
     }
     body = json.dumps(
         {
             "model": MODEL,
             "max_tokens": 256,
             "messages": [{"role": "user", "content": PROMPT}],
         }
     ).encode()
 
     req = urllib.request.Request(URL, data=body, headers=headers, method="POST")
-    with urllib.request.urlopen(req) as resp:
-        result = json.loads(resp.read())
+    try:
+        with urllib.request.urlopen(req) as resp:
+            result = json.loads(resp.read())
+    except (HTTPError, URLError) as e:
+        print(f"HTTP request failed: {e}")
+        raise
+    except json.JSONDecodeError as e:
+        print(f"Failed to parse JSON response: {e}")
+        raise
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@phases/00-setup-and-tooling/04-apis-and-keys/outputs/first_api_call_openrouter.py`
around lines 43 - 61, call_raw_http currently assumes OPENROUTER_API_KEY exists
and that network/JSON always succeed; change it to first read the key with
os.environ.get("OPENROUTER_API_KEY") and raise or log a clear error if missing
(instead of direct os.environ[...] access), then wrap the
urllib.request.urlopen(req) call in a try/except catching urllib.error.HTTPError
and urllib.error.URLError to handle HTTP/network failures, and finally wrap
json.loads(resp.read()) in a try/except catching json.JSONDecodeError to surface
a helpful parsing error; reference the function name call_raw_http and the
symbols URL, MODEL, PROMPT, api_key, req, resp, and result when implementing
these checks and logs/raises.

19-31: ⚖️ Poor tradeoff

Add error handling for environment variables and API calls.

As educational code, this function should demonstrate proper error handling:

  1. Line 24: Direct access to os.environ["OPENROUTER_API_KEY"] will raise KeyError if the variable is not set.
  2. Lines 27-31: The API call lacks error handling for network failures, authentication errors, or API rate limits.

Students learning from this code will benefit from seeing how to handle these common failure modes gracefully.

🛡️ Example error handling approach
 def call_with_sdk() -> None:
     load_dotenv()
+    
+    api_key = os.environ.get("OPENROUTER_API_KEY")
+    if not api_key:
+        raise ValueError("OPENROUTER_API_KEY environment variable not set")
 
     client = OpenAI(
         base_url="https://openrouter.ai/api/v1",
-        api_key=os.environ["OPENROUTER_API_KEY"],
+        api_key=api_key,
     )
 
-    response = client.chat.completions.create(
-        model=MODEL,
-        max_tokens=256,
-        messages=[{"role": "user", "content": PROMPT}],
-    )
+    try:
+        response = client.chat.completions.create(
+            model=MODEL,
+            max_tokens=256,
+            messages=[{"role": "user", "content": PROMPT}],
+        )
+    except Exception as e:
+        print(f"API call failed: {e}")
+        raise
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@phases/00-setup-and-tooling/04-apis-and-keys/outputs/first_api_call_openrouter.py`
around lines 19 - 31, In call_with_sdk(), avoid directly indexing
os.environ["OPENROUTER_API_KEY"]; instead validate the OPENROUTER_API_KEY with
os.getenv or an explicit check after load_dotenv and bail with a clear error/log
message if missing; then wrap the OpenAI client creation and the
client.chat.completions.create(...) call (which uses MODEL and PROMPT) in a
try/except that captures KeyError (env), network/auth errors and API errors
(e.g., request exceptions, authentication failures, rate limits), log or raise a
user-friendly message including the underlying exception details, and optionally
implement a simple retry/backoff for transient rate-limit/network errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@phases/00-setup-and-tooling/04-apis-and-keys/outputs/first_api_call_openrouter.py`:
- Around line 43-61: call_raw_http currently assumes OPENROUTER_API_KEY exists
and that network/JSON always succeed; change it to first read the key with
os.environ.get("OPENROUTER_API_KEY") and raise or log a clear error if missing
(instead of direct os.environ[...] access), then wrap the
urllib.request.urlopen(req) call in a try/except catching urllib.error.HTTPError
and urllib.error.URLError to handle HTTP/network failures, and finally wrap
json.loads(resp.read()) in a try/except catching json.JSONDecodeError to surface
a helpful parsing error; reference the function name call_raw_http and the
symbols URL, MODEL, PROMPT, api_key, req, resp, and result when implementing
these checks and logs/raises.
- Around line 19-31: In call_with_sdk(), avoid directly indexing
os.environ["OPENROUTER_API_KEY"]; instead validate the OPENROUTER_API_KEY with
os.getenv or an explicit check after load_dotenv and bail with a clear error/log
message if missing; then wrap the OpenAI client creation and the
client.chat.completions.create(...) call (which uses MODEL and PROMPT) in a
try/except that captures KeyError (env), network/auth errors and API errors
(e.g., request exceptions, authentication failures, rate limits), log or raise a
user-friendly message including the underlying exception details, and optionally
implement a simple retry/backoff for transient rate-limit/network errors.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc6e77eb-35ea-4aa8-a053-e782b423235d

📥 Commits

Reviewing files that changed from the base of the PR and between d63003f and c5cba13.

📒 Files selected for processing (4)
  • .gitignore
  • .vscode/settings.json
  • phases/00-setup-and-tooling/04-apis-and-keys/outputs/first_api_call_openrouter.py
  • pyproject.toml
✅ Files skipped from review due to trivial changes (1)
  • .vscode/settings.json

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
scratch/phase-00-lesson-05/exercise-2.ipynb (1)

28-164: ⚡ Quick win

Strip bulky rich outputs from the committed notebook JSON.

Large embedded HTML/DataFrame dumps and base64 plot payloads make diffs hard to review and increase merge friction. Prefer clearing outputs before commit and keeping results reproducible via execution.

Also applies to: 177-280, 346-356

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scratch/phase-00-lesson-05/exercise-2.ipynb` around lines 28 - 164, The
notebook contains bulky cell outputs (the "outputs" array with "text/html" and
large "text/plain" dumps and non-empty "execution_count") which should be
removed before committing; clear all cell outputs and reset execution_count to
null, e.g., remove the "outputs" entries and set "execution_count" to null for
affected cells (references: the "outputs" JSON key, "text/html"/"text/plain"
payloads, and "execution_count"). Fix by running a notebook output cleaner
(nbstripout, pre-commit hook, or jupyter nbconvert --ClearOutputPreprocessor) or
manually deleting the outputs in the notebook UI, then commit the cleaned
notebook so diffs no longer contain embedded HTML/plot payloads. Ensure you
apply the same cleanup to the other ranges mentioned (cells containing large
outputs around lines 177-280 and 346-356).
phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py (1)

73-76: ⚡ Quick win

Avoid executing two billable API calls by default.

Running both paths in __main__ is useful for demoing, but it can unintentionally double token usage/cost on every run. Prefer selecting mode via CLI arg or env flag.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py`
around lines 73 - 76, The script currently calls both call_with_sdk() and
call_raw_http() unconditionally in the if __name__ == "__main__" block which
doubles billable API usage; change the entrypoint to accept a CLI argument or
environment flag (e.g., via argparse or os.environ) to choose which path to run
("sdk", "raw", or "both") and only invoke call_with_sdk() or call_raw_http()
according to that selection, defaulting to a safe option (e.g., "sdk" or none)
to avoid accidental dual calls; update the __main__ block to parse the flag and
conditionally call the functions accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py`:
- Around line 24-25: Replace direct os.environ["OPENROUTER_API_KEY"] lookups
with an explicit validation that fails fast with a clear message: read the value
via os.getenv("OPENROUTER_API_KEY") (or check "OPENROUTER_API_KEY" in
os.environ), and if missing raise a RuntimeError or ValueError with a
descriptive message like "OPENROUTER_API_KEY environment variable is required".
Apply this change to both places where api_key=os.environ["OPENROUTER_API_KEY"]
appears (the api_key= parameter assignments shown in the diff around lines 24-25
and 45-46) so client creation uses the validated value instead of causing a bare
KeyError.
- Around line 59-61: The raw HTTP call using urllib.request.urlopen(req) lacks a
timeout and network error handling; update the call to pass a timeout (e.g.,
urllib.request.urlopen(req, timeout=10)) and wrap it in a try/except that
catches urllib.error.HTTPError, urllib.error.URLError, socket.timeout and a
generic Exception, converting them into a clear error return/raise (or logging)
so call_with_sdk() parity is maintained; locate the URL, req and
urllib.request.urlopen usage in this file and add the timeout plus the exception
handlers around the with urllib.request.urlopen(...) as resp: block.

In `@scratch/phase-00-lesson-05/exercise-1.ipynb`:
- Around line 128-130: Update the conclusion markdown string that currently
reads "Результат - в 8 раз быстрее работает способ с помощью numpy..." to
reflect the measured ~9.1x speedup reported earlier; locate the notebook cell
containing that exact Russian sentence (the markdown cell string) and change "8
раз" to "≈9.1 раза" (or "9.1 раз" for exact match) so the conclusion matches the
computed result.
- Around line 8-18: The notebook contains machine-specific executed output
(data.text/plain showing '/home/pavel/...') that should be removed; open
scratch/phase-00-lesson-05/exercise-1.ipynb and clear the cell outputs (remove
the "outputs" array and reset "execution_count" for that cell) or run a
notebook-clean step (e.g., "jupyter nbconvert
--ClearOutputPreprocessor.enabled=True" or use "git add --renormalize" after
clearing) so no local filesystem paths remain in the committed file; ensure you
save the notebook with outputs cleared before updating the PR.

In `@scratch/phase-00-lesson-05/exercise-2.ipynb`:
- Line 388: Replace the vague concluding string "продажи растут" with a precise
summary that matches the plotted series — for example, state that sales rise
until a peak and then decline (e.g., "продажи растут до пика, затем наблюдается
спад"), by editing the cell/string used for the final caption or conclusion in
the notebook where the literal "продажи растут" appears.

---

Nitpick comments:
In
`@phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py`:
- Around line 73-76: The script currently calls both call_with_sdk() and
call_raw_http() unconditionally in the if __name__ == "__main__" block which
doubles billable API usage; change the entrypoint to accept a CLI argument or
environment flag (e.g., via argparse or os.environ) to choose which path to run
("sdk", "raw", or "both") and only invoke call_with_sdk() or call_raw_http()
according to that selection, defaulting to a safe option (e.g., "sdk" or none)
to avoid accidental dual calls; update the __main__ block to parse the flag and
conditionally call the functions accordingly.

In `@scratch/phase-00-lesson-05/exercise-2.ipynb`:
- Around line 28-164: The notebook contains bulky cell outputs (the "outputs"
array with "text/html" and large "text/plain" dumps and non-empty
"execution_count") which should be removed before committing; clear all cell
outputs and reset execution_count to null, e.g., remove the "outputs" entries
and set "execution_count" to null for affected cells (references: the "outputs"
JSON key, "text/html"/"text/plain" payloads, and "execution_count"). Fix by
running a notebook output cleaner (nbstripout, pre-commit hook, or jupyter
nbconvert --ClearOutputPreprocessor) or manually deleting the outputs in the
notebook UI, then commit the cleaned notebook so diffs no longer contain
embedded HTML/plot payloads. Ensure you apply the same cleanup to the other
ranges mentioned (cells containing large outputs around lines 177-280 and
346-356).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2b89b862-ac10-41db-91fc-a2006f7b6697

📥 Commits

Reviewing files that changed from the base of the PR and between c5cba13 and 13333d0.

⛔ Files ignored due to path filters (1)
  • scratch/phase-00-lesson-05/sales.csv is excluded by !**/*.csv
📒 Files selected for processing (3)
  • phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py
  • scratch/phase-00-lesson-05/exercise-1.ipynb
  • scratch/phase-00-lesson-05/exercise-2.ipynb

Comment on lines +24 to +25
api_key=os.environ["OPENROUTER_API_KEY"],
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fail fast with a clear message when OPENROUTER_API_KEY is missing.

Using os.environ["OPENROUTER_API_KEY"] raises a bare KeyError. A clear validation error improves debuggability for first-time setup.

Suggested patch
+def _get_api_key() -> str:
+    api_key = os.getenv("OPENROUTER_API_KEY")
+    if not api_key:
+        raise RuntimeError("OPENROUTER_API_KEY is not set. Add it to your environment or .env file.")
+    return api_key
+
 def call_with_sdk() -> None:
     load_dotenv()
@@
-        api_key=os.environ["OPENROUTER_API_KEY"],
+        api_key=_get_api_key(),
@@
 def call_raw_http() -> None:
     load_dotenv()
-    api_key = os.environ["OPENROUTER_API_KEY"]
+    api_key = _get_api_key()

Also applies to: 45-46

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py`
around lines 24 - 25, Replace direct os.environ["OPENROUTER_API_KEY"] lookups
with an explicit validation that fails fast with a clear message: read the value
via os.getenv("OPENROUTER_API_KEY") (or check "OPENROUTER_API_KEY" in
os.environ), and if missing raise a RuntimeError or ValueError with a
descriptive message like "OPENROUTER_API_KEY environment variable is required".
Apply this change to both places where api_key=os.environ["OPENROUTER_API_KEY"]
appears (the api_key= parameter assignments shown in the diff around lines 24-25
and 45-46) so client creation uses the validated value instead of causing a bare
KeyError.

Comment on lines +59 to +61
req = urllib.request.Request(URL, data=body, headers=headers, method="POST")
with urllib.request.urlopen(req) as resp:
result = json.loads(resp.read())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find . -name "first_api_call_openrouter.py" -type f

Repository: rohitg00/ai-engineering-from-scratch

Length of output: 161


🏁 Script executed:

cat -n phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py

Repository: rohitg00/ai-engineering-from-scratch

Length of output: 2598


Add timeout and explicit network error handling for the raw HTTP call.

At line 60, urlopen has no timeout and no exception handling, so transient network/API issues can hang indefinitely or crash with an opaque traceback. This is particularly important since the call_with_sdk() implementation (which uses the OpenAI client) has built-in timeout and error handling, creating an asymmetry.

Suggested patch
+import urllib.error
 import urllib.request
 
 from dotenv import load_dotenv
@@
     req = urllib.request.Request(URL, data=body, headers=headers, method="POST")
-    with urllib.request.urlopen(req) as resp:
-        result = json.loads(resp.read())
+    try:
+        with urllib.request.urlopen(req, timeout=30) as resp:
+            result = json.loads(resp.read())
+    except urllib.error.HTTPError as e:
+        raise RuntimeError(f"OpenRouter HTTP error: {e.code} {e.reason}") from e
+    except urllib.error.URLError as e:
+        raise RuntimeError(f"OpenRouter network error: {e.reason}") from e
🧰 Tools
🪛 Ruff (0.15.12)

[error] 59-59: Audit URL open for permitted schemes. Allowing use of file: or custom schemes is often unexpected.

(S310)


[error] 60-60: Audit URL open for permitted schemes. Allowing use of file: or custom schemes is often unexpected.

(S310)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@phases/00-setup-and-tooling/04-apis-and-keys/code/first_api_call_openrouter.py`
around lines 59 - 61, The raw HTTP call using urllib.request.urlopen(req) lacks
a timeout and network error handling; update the call to pass a timeout (e.g.,
urllib.request.urlopen(req, timeout=10)) and wrap it in a try/except that
catches urllib.error.HTTPError, urllib.error.URLError, socket.timeout and a
generic Exception, converting them into a clear error return/raise (or logging)
so call_with_sdk() parity is maintained; locate the URL, req and
urllib.request.urlopen usage in this file and add the timeout plus the exception
handlers around the with urllib.request.urlopen(...) as resp: block.

Comment on lines +8 to +18
"outputs": [
{
"data": {
"text/plain": [
"'/home/pavel/ai-engineering-from-scratch/.venv/bin/python3'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove machine-specific notebook output before commit.

This committed output exposes a local filesystem path (/home/pavel/...) and adds non-reproducible noise to diffs. Please clear this output (or notebook outputs globally) before merge.

🧰 Tools
🪛 Ruff (0.15.12)

[warning] 9-9: Found useless expression. Either assign it to a variable or remove it.

(B018)


[warning] 13-13: Found useless expression. Either assign it to a variable or remove it.

(B018)


[warning] 17-17: Found useless expression. Either assign it to a variable or remove it.

(B018)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scratch/phase-00-lesson-05/exercise-1.ipynb` around lines 8 - 18, The
notebook contains machine-specific executed output (data.text/plain showing
'/home/pavel/...') that should be removed; open
scratch/phase-00-lesson-05/exercise-1.ipynb and clear the cell outputs (remove
the "outputs" array and reset "execution_count" for that cell) or run a
notebook-clean step (e.g., "jupyter nbconvert
--ClearOutputPreprocessor.enabled=True" or use "git add --renormalize" after
clearing) so no local filesystem paths remain in the committed file; ensure you
save the notebook with outputs cleared before updating the PR.

Comment on lines +128 to +130
"Результат - в 8 раз быстрее работает способ с помощью numpy. Если я правильно понимаю, потому, что бибилотека написана на C.\n",
"Первый способ использует интерпретатор python"
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align the conclusion text with the measured speedup.

The notebook reports ~9.1x speedup (Line 110), but the markdown says 8x. Please update the statement to match the computed result.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scratch/phase-00-lesson-05/exercise-1.ipynb` around lines 128 - 130, Update
the conclusion markdown string that currently reads "Результат - в 8 раз быстрее
работает способ с помощью numpy..." to reflect the measured ~9.1x speedup
reported earlier; locate the notebook cell containing that exact Russian
sentence (the markdown cell string) and change "8 раз" to "≈9.1 раза" (or "9.1
раз" for exact match) so the conclusion matches the computed result.

"id": "5528f3da-f9ba-4445-a853-646761d57e60",
"metadata": {},
"source": [
"продажи растут"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make the concluding statement more precise.

“продажи растут” is not fully accurate for the shown series (there is a decline after the peak). Please adjust the text to reflect the actual trend.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scratch/phase-00-lesson-05/exercise-2.ipynb` at line 388, Replace the vague
concluding string "продажи растут" with a precise summary that matches the
plotted series — for example, state that sales rise until a peak and then
decline (e.g., "продажи растут до пика, затем наблюдается спад"), by editing the
cell/string used for the final caption or conclusion in the notebook where the
literal "продажи растут" appears.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
scratch/lesson-06/playground-project/pyproject.toml (1)

5-10: ⚡ Quick win

Consider version upper bounds or more specific constraints.

All dependencies use only lower-bound constraints (>=), which may lead to breaking changes when major versions are released. For a playground project, consider either:

  • Adding upper bounds for stability: numpy >=1.26,<2.0
  • Using exact versions for reproducibility: numpy ==1.26.4
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scratch/lesson-06/playground-project/pyproject.toml` around lines 5 - 10,
Update the loose >= version constraints to safer ranges or pin exact versions:
replace "numpy >=1.26" with either a bounded spec like "numpy >=1.26,<2.0" or an
exact pin like "numpy ==1.26.4", and similarly tighten the optional-dependencies
lists for torch/torchvision ("torch>=2.3" -> e.g. "torch>=2.3,<3.0" or
"torch==2.3.x") and llm packages anthropic/openai ("anthropic>=0.39" and
"openai>=1.50" -> add upper bounds like "<1.0" or pin exact versions) so that
numpy, torch, torchvision, anthropic, and openai have either upper bounds or
exact pins for stability and reproducibility.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@phases/00-setup-and-tooling/01-dev-environment/docs/ru.md`:
- Line 123: Update the PyTorch pip index URL to reference CUDA 12.6: replace the
current command string containing "https://download.pytorch.org/whl/cu124" in
the docs line (the existing pip install invocation "uv pip install torch
torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124") so
it instead uses "cu126" (i.e., "https://download.pytorch.org/whl/cu126") to
align the installation instructions with the current PyTorch CUDA
recommendation.

In `@phases/00-setup-and-tooling/03-gpu-setup-and-cloud/docs/ru.md`:
- Around line 23-39: The fenced code block that begins with "1. Локальная NVIDIA
GPU" in ru.md lacks a language tag which triggers markdownlint MD040; update the
opening fence from ``` to a language-hint such as ```text (or ```plain) so the
block becomes ```text and keep the rest unchanged to satisfy the linter.
- Around line 72-80: The snippet uses an invalid attribute name on the device
properties: update the access of torch.cuda.get_device_properties(0).total_mem
to the correct attribute torch.cuda.get_device_properties(0).total_memory (and
ensure any other occurrences such as the similar use elsewhere are updated to
total_memory) so the GPU memory print uses the valid property name.

In `@phases/00-setup-and-tooling/06-python-environments/docs/ru.md`:
- Line 371: The Russian docs contain a typo in a subheading: replace the
incorrect "Gott'cha" string with the correct "Gotcha" in
phases/00-setup-and-tooling/06-python-environments/docs/ru.md; locate the
subheading text (the line containing "Gott'cha") and change it to "Gotcha" so
the heading reads correctly.

In `@scratch/lesson-06/playground-project/pyproject.toml`:
- Line 2: The project name in pyproject.toml is set to "pyproject", which
conflicts with the config filename and causes confusion; update the name field
in pyproject.toml (the "name" key) to a descriptive, non-conflicting package
name such as "lesson-06-playground" or "ai-engineering-playground" so the
project metadata no longer matches the filename.

---

Nitpick comments:
In `@scratch/lesson-06/playground-project/pyproject.toml`:
- Around line 5-10: Update the loose >= version constraints to safer ranges or
pin exact versions: replace "numpy >=1.26" with either a bounded spec like
"numpy >=1.26,<2.0" or an exact pin like "numpy ==1.26.4", and similarly tighten
the optional-dependencies lists for torch/torchvision ("torch>=2.3" -> e.g.
"torch>=2.3,<3.0" or "torch==2.3.x") and llm packages anthropic/openai
("anthropic>=0.39" and "openai>=1.50" -> add upper bounds like "<1.0" or pin
exact versions) so that numpy, torch, torchvision, anthropic, and openai have
either upper bounds or exact pins for stability and reproducibility.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d34ea5c-3d2f-41c9-b94e-c0121c11bc20

📥 Commits

Reviewing files that changed from the base of the PR and between 13333d0 and 0ba57a5.

⛔ Files ignored due to path filters (1)
  • scratch/lesson-06/playground-project/requirements.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • phases/00-setup-and-tooling/01-dev-environment/docs/ru.md
  • phases/00-setup-and-tooling/02-git-and-collaboration/docs/ru.md
  • phases/00-setup-and-tooling/03-gpu-setup-and-cloud/docs/ru.md
  • phases/00-setup-and-tooling/04-apis-and-keys/docs/ru.md
  • phases/00-setup-and-tooling/05-jupyter-notebooks/docs/ru.md
  • phases/00-setup-and-tooling/06-python-environments/docs/ru.md
  • scratch/lesson-06/playground-project/pyproject.toml

Дальше — PyTorch с CUDA:

```bash
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify that the PyTorch CUDA 12.4 wheel index exists and is the recommended version
curl -s https://download.pytorch.org/whl/cu124/ | head -20

Repository: rohitg00/ai-engineering-from-scratch

Length of output: 946


🌐 Web query:

What is the current recommended CUDA version for PyTorch installation as of May 2025?

💡 Result:

As of May 2025, the “current recommended” CUDA version for installing PyTorch (via the official PyTorch “Get Started” selector for CUDA-enabled binaries) is CUDA 12.6.[1][2] PyTorch’s official install selector lists supported CUDA binary builds (including 12.6 and 12.8); it also notes that choosing the latest CUDA version is often better, and points users to the specific CUDA version shown in the selector when installing.[1][2]

Citations:


Update CUDA version to 12.6 for PyTorch installation.

The --index-url references CUDA 12.4, but PyTorch's official installer recommends CUDA 12.6 as of May 2025. Update line 123 to use cu126 instead of cu124 to align with current PyTorch best practices.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@phases/00-setup-and-tooling/01-dev-environment/docs/ru.md` at line 123,
Update the PyTorch pip index URL to reference CUDA 12.6: replace the current
command string containing "https://download.pytorch.org/whl/cu124" in the docs
line (the existing pip install invocation "uv pip install torch torchvision
torchaudio --index-url https://download.pytorch.org/whl/cu124") so it instead
uses "cu126" (i.e., "https://download.pytorch.org/whl/cu126") to align the
installation instructions with the current PyTorch CUDA recommendation.

Comment on lines +23 to +39
```
1. Локальная NVIDIA GPU
Стоимость: $0 (если уже есть)
Настройка: CUDA + cuDNN + PyTorch с CUDA
Когда брать: Регулярная работа, большие датасеты, низкая латентность

2. Google Colab (free tier)
Стоимость: $0
Настройка: отсутствует — браузер и Google-аккаунт
Когда брать: Эксперименты, обучение, когда нет своей карты
Ограничения: 90 минут idle → отключение; сессии сбрасываются

3. Cloud GPU (Lambda, RunPod, Vast.ai)
Стоимость: $0.20–2.00/час за GPU
Настройка: SSH + установка библиотек
Когда брать: Серьёзная тренировка, большие модели, надолго
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a language hint to the fenced block to satisfy markdownlint MD040.

At Line 23, the fenced block has no language tag; this is already flagged by static analysis.

Proposed fix
-```
+```text
 1. Локальная NVIDIA GPU
    Стоимость:    $0 (если уже есть)
    Настройка:    CUDA + cuDNN + PyTorch с CUDA
@@
 3. Cloud GPU (Lambda, RunPod, Vast.ai)
    Стоимость:    $0.20–2.00/час за GPU
    Настройка:    SSH + установка библиотек
    Когда брать:  Серьёзная тренировка, большие модели, надолго
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 23-23: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@phases/00-setup-and-tooling/03-gpu-setup-and-cloud/docs/ru.md` around lines
23 - 39, The fenced code block that begins with "1. Локальная NVIDIA GPU" in
ru.md lacks a language tag which triggers markdownlint MD040; update the opening
fence from ``` to a language-hint such as ```text (or ```plain) so the block
becomes ```text and keep the rest unchanged to satisfy the linter.

Comment on lines +72 to +80
```python
import torch

print(f"CUDA available: {torch.cuda.is_available()}")
print(f"CUDA version: {torch.version.cuda}")
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"Memory: {torch.cuda.get_device_properties(0).total_mem / 1e9:.1f} GB")
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In official PyTorch documentation for torch.cuda.get_device_properties, what is the correct attribute for total GPU memory: total_memory or total_mem?

💡 Result:

In the official PyTorch documentation and API, the correct attribute for accessing the total GPU memory via torch.cuda.get_device_properties is total_memory [1][2][3]. The attribute total_mem is not a valid property of the object returned by this function. When you call torch.cuda.get_device_properties(device), it returns a _CudaDeviceProperties object [4], which includes the total_memory attribute (typically expressed in bytes) [1][3].

Citations:


Fix invalid PyTorch device property attribute name.

Line 79 uses total_mem, which is not a valid attribute. The correct attribute is total_memory (also see Line 231). This will cause an AttributeError when learners run the snippet.

Proposed fix
-    print(f"Memory: {torch.cuda.get_device_properties(0).total_mem / 1e9:.1f} GB")
+    print(f"Memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@phases/00-setup-and-tooling/03-gpu-setup-and-cloud/docs/ru.md` around lines
72 - 80, The snippet uses an invalid attribute name on the device properties:
update the access of torch.cuda.get_device_properties(0).total_mem to the
correct attribute torch.cuda.get_device_properties(0).total_memory (and ensure
any other occurrences such as the similar use elsewhere are updated to
total_memory) so the GPU memory print uses the valid property name.

без переустановки — стандартный режим разработки.

### Гott'cha: `--extra` — это имя группы, не пакета

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typo in subheading.

"Gott'cha" should be "Gotcha".

✏️ Proposed fix
-### Гott'cha: `--extra` — это имя группы, не пакета
+### Gotcha: `--extra` — это имя группы, не пакета
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Gotcha: `--extra` — это имя группы, не пакета
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@phases/00-setup-and-tooling/06-python-environments/docs/ru.md` at line 371,
The Russian docs contain a typo in a subheading: replace the incorrect
"Gott'cha" string with the correct "Gotcha" in
phases/00-setup-and-tooling/06-python-environments/docs/ru.md; locate the
subheading text (the line containing "Gott'cha") and change it to "Gotcha" so
the heading reads correctly.

@@ -0,0 +1,10 @@
[project]
name = "pyproject"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Rename the project to avoid confusion with the config file.

The project name "pyproject" conflicts with the standard configuration filename pyproject.toml, creating unnecessary confusion. Package names should be descriptive of the project's purpose, such as lesson-06-playground or ai-engineering-playground.

📦 Proposed fix
-name = "pyproject"
+name = "lesson-06-playground"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name = "pyproject"
name = "lesson-06-playground"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scratch/lesson-06/playground-project/pyproject.toml` at line 2, The project
name in pyproject.toml is set to "pyproject", which conflicts with the config
filename and causes confusion; update the name field in pyproject.toml (the
"name" key) to a descriptive, non-conflicting package name such as
"lesson-06-playground" or "ai-engineering-playground" so the project metadata no
longer matches the filename.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant