2.4 Másik gép, azonos projekt

2.4.1 Cél és konkrét helyzet

A helyzet: az 2.3-ben felépített helyi Git-repót egy másik gépre visszük át, és azon egy tiszta könyvtárban futtatjuk a Northstar kezdőlabor ellenőrzőjét. A bemenet a klónozott lab projekt és a szállított CSV-k; egy megfigyelési egység egy teljes futtatási munkamenet az adott gépen. A cél kettős: (1) a három szerződött adatméret ellenőrzése a másik gépen is ugyanazt az eredményt adja, és (2) ha a futás eltér, a hibát az operációs rendszer, a fájljog vagy az interpreter szintjére tudjuk besorolni, ne pedig automatikusan algoritmushibának gondoljuk.

Előzetes becslés: a quickcheck.py sikeres futása customers=300, orders=2400, order_items=4796 kontrollértékeket és nulla kilépési kódot ad. Ez a három szám az adatszerződésből származó invariant; ha bármelyik eltér, az hibát jelez, de a hiba típusát még nem mondja meg. Ebben az alfejezetben pontosan ezt a szétválasztást gyakoroljuk.

2.4.2 Fogalmi magyarázat: három környezet és a hibák szétválasztása

Egy „másik gép, azonos projekt” forgatókönyvben három különböző réteget érdemes megkülönböztetni:

  1. Az operációs rendszer és fájlrendszer. A Windows alapértelmezett fájlrendszer-szemantikája különbözik a Linuxétól és a macOS-étől. A Windows útvonala C:\Users\anna\projekt, a POSIX rendszereké /home/anna/projekt; a Windows a backslash (\) elválasztót várja a héjban, a Python pathlib azonban mindkettőn a / jelet is elfogadja. A Linux fájlnevei kis- és nagybetű-érzékenyek (case-sensitive), a Windows és az alapbeállítású macOS fájlrendszer nem. Emiatt a Orders.CSV elnevezés Linuxon más fájl, mint az orders.csv, Windows-on viszont ugyanarra mutathat. A sorvég (line ending) is platformfüggő: Windows hagyományosan CRLF-et, Linux és macOS LF-et használ. A Git text=auto beállítás nélkül ezt a különbséget be tudja vinni a diffbe, ami zajt kelt a review-ban.

  2. A fájljogosultságok és a végrehajtási házirend. POSIX rendszeren egy script közvetlen futtatásához executable bit (futtathatósági bit) kell: chmod +x quickcheck.py, majd ./quickcheck.py. Windows-on ilyen bit nincs; ott a fájl kiterjesztése és a társítás számít, a PowerShell pedig a scriptekre külön végrehajtási házirendet (execution policy) alkalmaz. A git clone a fájl jogosultsági bitjét a repóból hozza, ha az ott commitolva volt; ha a scriptet Windowsról írták, a bit hiányozhat Linuxon.

  3. Az interpreter és a függőségek. A python parancs nem ugyanaz minden gépen. Windows-on a Microsoft Store-hoz irányíthat, ha nincs telepített interpreter; a py -3.12 launcher viszont konkrét verziót kér. Linuxon gyakran a python3 a helyes név, a python pedig hiányozhat. A virtuális környezet (venv) a géphez és a fájlúthoz kötött: a benne levő bin/python (POSIX) vagy Scripts/python.exe (Windows) nem hordozható a gépek között. A uv sync vagy a requirements.txt a függőségeket oldja fel, de az alapinterpretert a felhasználónak kell biztosítania. Ezek a különbségek mind környezethibák, nem pedig a kód logikájának hibái.

A WSL (Windows Subsystem for Linux) egy további réteg: a Windows-gazdarendszeren belül futó Linux-környezet, saját fájlrendszerrel, saját processztérrel és saját Python-telepítéssel. A WSL-ből a Windows meghajtó a /mnt/c alatt látszik, a Windowsból a WSL-fájlrendszer a \\wsl.localhost\<disztribúció> útvonalon. A kettő nem ugyanaz a fájl- és processzkörnyezet: a Windowsban telepített Python nem látja a WSL-beli virtuális környezet csomagjait, és fordítva. Egy Docker-konténer szintén külön fájl- és processzkörnyezet; a konténer munkakönyvtára alapértelmezésben nem a gazdagép projektmappája.

A parancssor szintjén a POSIX-héj (Bash, zsh) és a PowerShell parancsai eltérnek. A leggyakoribb megfeleltetések:

Feladat POSIX (Linux, macOS, WSL) PowerShell (Windows)
Könyvtár listázása ls -la Get-ChildItem -Force
Munkakönyvtár pwd Get-Location
Szövegfájl sorainak számolása wc -l fajl.csv (Get-Content fajl.csv).Count
Fájl hash sha256sum fajl Get-FileHash fajl -Algorithm SHA256
Környezeti változó echo "$HOME" echo $env:USERPROFILE
Fájl másolása cp a b Copy-Item a b

A táblázat nem teljes szótár, hanem annak illusztrációja, hogy ugyanaz a szándék más szintaxist igényel. A platformfüggő parancsok aktuális viselkedését a saját gép dokumentációja és a sources.md kulcsai alapján ellenőrizzük; ezt az alfejezetet nem konkrét webes futtatásból írjuk.

2.4.3 Teljes minimális példa: tiszta könyvtár klónozással

A példa bemenete a már létező helyi repó. A cél: a másik gépen a git clone után csak a repóban levő fájlokkal futtatni a kontrollt, semmilyen korábbi munkakönyvtárból örökölt állapottal.

Linuxon vagy macOS-en (Bash):

# A repót a lokális elérési útvonalról klónozzuk; távoli repónál URL jönne.
git clone /mnt/shared/northstar-lab northstar-bash
cd northstar-bash

# Interpreter-ellenőrzés: a projekt kiinduló célja Python 3.12.
python3 --version

# A függőségmentes kontroll futtatása tiszta klónból.
python3 quickcheck.py

Windows PowerShellben:

git clone C:\src\northstar-lab northstar-win
cd northstar-win

# A launcher konkrét verziót keres, ha több Python is telepítve van.
py -3.12 --version

py -3.12 quickcheck.py

A quickcheck.py a mellékelt CSV-ket ellenőrzi a manifest és az adatszerződés alapján. Szemléltető, elméletileg várt kimenet (a tanuló saját futtatása a mérvadó; ez a kimenet nem a könyvírás során mért futás):

customers   rows=300  OK
orders      rows=2400 OK
order_items rows=4796 OK
all checks passed
exit code: 0

A WSL-beli változathoz ugyanaz a Bash-szekvencia tartozik, de a klón célja a WSL saját fájlrendszerén belül legyen, például ~/northstar-wsl, nem pedig /mnt/c/..., mert a /mnt/c alatti munka lassabb és eltérő jogosultság-szemantikát adhat.

2.4.4 Eredmény értelmezése és kézi ellenőrzés

A kontroll akkor sikeres, ha a három sorban a szerződött méretek szerepelnek, és a kilépési kód 0. Ez a három szám nem mérés, hanem az adatszerződés invariánsa: a generátor alap seedjével készült fájlok rögzített sorméretei. Ha a fájlok a klónozás során változtak volna, a manifest hash-ellenőrzése ezt a sorszám-ellenőrzés előtt vagy mellett kimutatná.

Érdemes a quickcheck.py futását egy kézi kontrollal is plauzibilissé tenni, amikor a sorok számát a platform saját eszközével is megnézzük:

# Linux/macOS/WSL: a CSV első sora fejléc, tehát adatsor = sorok - 1.
wc -l data/customers.csv
# PowerShellben ugyanez; a Count a fejlécsorral együtt számol.
(Get-Content data\customers.csv).Count

Ha a két szám 300 (adatsor) plusz 1 fejlécsor, akkor a szemcsézettség egyezik. A wc -l csak akkor megbízható, ha a CSV-ben nincs beágyazott sortörés; a Northstar szintetikus adatában ez a szerződés része, más adatnál a CSV-értelmező a hiteles.

A példa lényege nem a három szám memorizálása, hanem az, hogy ugyanaz a repó ugyanazt a kontrollt adja három különböző környezetben. Ha az egyik gépen az eredmény eltér, a hibakeresés sorrendje:

  1. Interpreter-eltérés: a python --version más verziót ad-e, mint a projekt célja? Van-e aktív, másik projektből származó venv?
  2. Fájl- és útvonalhiba: a munkakönyvtár tényleg a klón gyökere? A fájlnév kis-nagybetűje egyezik-e a repóval?
  3. Fájljog: POSIX rendszeren a script futtatható-e közvetlenül, vagy csak python3 script.py módon?
  4. Algoritmushiba: csak akkor merül fel, ha az előző három réteg azonos, és a kód bemenete is azonos; ekkor a hiba a kód logikájában vagy az adatban van.

Átviteli próba. A másik gépen futó azonos kód nem garantálja az azonos környezetet. Ellenőrizni kell az interpreter pontos verzióját, a függőségi rögzítést, a fájlkódolást, a sorvégeket, az architektúrát és a könyvtárjogokat. A futási jegyzőkönyvben a környezeti eltérés és az adateltérés külön hibakategória legyen.

A python3 quickcheck.py használata kikerüli a végrehajtási bit szükségességét, de nem garantálja, hogy a helyes interpreter érhető el, hogy a fájl olvasható, vagy hogy minden platformfüggőség teljesül. Ezért a »mindig működik« állítás helyett a konkrét előfeltételeket kell megadni.

2.4.5 Feladatok

  1. Értelmezés. Egy társ Windows PowerShellben a python quickcheck.py parancs után ezt az üzenetet kapja: Python was not found; run without arguments to install from the Microsoft Store. Melyik réteg hibája ez? Miért nem jelenti azt, hogy a quickcheck.py algoritmusa rossz? Mit javasolj neki első lépésben?

  2. Implementálás. Készíts egy launch_checklist.md nevű fájlt a repó dokumentációs mappájába. A lista három rovatot tartalmazzon: Linux/macOS, Windows PowerShell és WSL. Minden rovathoz írd be sorrendben: (a) a repó klónozása tiszta könyvtárba, (b) a Python-verzió ellenőrzése, (c) a projekt gyökerébe lépés, (d) a quickcheck.py futtatása, (e) a három elvárt kontrollérték rögzítése. A fájl legyen platformtáblával ellátott, hogy a társ a parancsok megfeleltetését is lássa.

  3. Hibadiagnózis. Egy Linuxos gépen a társ ezt futtatja: ./quickcheck.py, és ezt kapja: Permission denied. Ugyanott a python3 quickcheck.py sikeresen lefut. Mi a különbség a két parancs között? Melyik a helyes hosszú távú megoldás, ha a repó a scriptet parancsként szeretné futtatni, és mit nem szabad megtennie a diagnózis során?

  4. Megváltozott feltétel. A projektet egy macOS gépre viszed, ahol a python3 --version 3.11-et ír, a pyproject.toml pedig requires-python = ">=3.12"-t rögzít. A quickcheck.py mégis hiba nélkül fut, mert standard library-only. A starter_experiment.py azonban csomaghiánnyal bukik, amikor uv sync nélkül próbálod futtatni. Írd le, milyen kimenetből látod, hogy ez környezethiba, nem a kísérleti kód hibája, és milyen parancsokkal jutsz el a kontrollfutásig anélkül, hogy a Python 3.11-et kézzel felülírnád a rendszerben.

2.4.6 Megoldások és indoklás

  1. Megoldás. Ez interpreter-réteg-hiba: a python parancs a Microsoft Store által nyújtott álparancsra mutat, nem egy telepített CPythonra. A quickcheck.py hibátlan lehet; a bemenetet és a kódot meg sem kapta. Első lépés a py -3.12 --version vagy a python --version futtatása, illetve a telepített Python keresése a py -0 launcherrel. Ha nincs 3.12, a környezetet a projekt elvárásának megfelelően kell telepíteni; a kódhoz nem nyúlunk.

  2. Megoldás. A lényeg az ellenőrzőlista platformrovata. Egy lehetséges minimális változat:

    # Indítási ellenőrzőlista
    
    | Lépés | Linux/macOS | Windows PowerShell | WSL |
    |---|---|---|---|
    | Klón | `git clone <repó> ~/northstar` | `git clone <repó> C:\work\northstar` | `git clone <repó> ~/northstar-wsl` |
    | Lépés a gyökérbe | `cd ~/northstar` | `cd C:\work\northstar` | `cd ~/northstar-wsl` |
    | Python-verzió | `python3 --version` | `py -3.12 --version` | `python3 --version` |
    | Ellenőrző | `python3 quickcheck.py` | `py -3.12 quickcheck.py` | `python3 quickcheck.py` |
    | Elvárt értékek | 300 / 2400 / 4796; exit 0 | ugyanaz | ugyanaz |
    
    A cél: ugyanaz a három kontrollérték mindhárom környezetben.

    Az elvárt értékek sor: customers=300, orders=2400, order_items=4796, és a kilépési kód 0. Ha a klón forrása nem a szállított repó, a hash-ellenőrzés is kötelező.

  3. Megoldás. A ./quickcheck.py a fájlban levő shebang-et és a futtathatósági bitet használja; a python3 quickcheck.py explicit módon az interpretert hívja. A Permission denied azt jelenti, hogy a fájl nem futtatható közvetlenül, mert a bit hiányzik. A helyes hosszú távú megoldás, ha a scriptet parancsként akarjuk futtatni: chmod +x quickcheck.py, és a fájl első sora #!/usr/bin/env python3 legyen, majd ezt commitolni. Nem szabad a diagnózis során a rendszer Python-telepítését globálisan átírni, vagy a chmod-ot kihagyva Windowsról áthozott bitre támaszkodni. A python3 quickcheck.py a futtathatósági bittől függetlenül indítható, ha a megfelelő Python-interpreter elérhető, a fájl olvasható, és a szükséges függőségek telepítve vannak, ezért a kontroll szempontjából biztonságosabb.

  4. Megoldás. A környezethibára utaló jelek: a starter_experiment.py által importált csomag nevére vonatkozó ModuleNotFoundError, vagy a pyproject.toml Python-korlátjára hivatkozó uv-üzenet. Ez nem a kísérleti statisztika hibája; a script importálás előtt áll meg. A megoldás: telepíteni a projekt által elvárt 3.12-t (például uv python install 3.12), a projektben uv sync-kel feloldani a függőségeket, majd uv run python starter_experiment.py módon futtatni, ami a projekt környezetéhez köti az interpretert. A rendszer 3.11-ét nem kell felülírni; az uv a projektvenv-ben külön 3.12-t kezel. A quickcheck.py azért futott, mert standard library-only, így a függőségek hiánya nem érintette. A kettő különbsége pontosan mutatja az interpreter- és függőségi réteg szerepét.

2.4.7 Gyakori tévedés és önellenőrzés

Gyakori tévedés: azt hinni, hogy a Windows, a WSL és a Docker ugyanazt a fájl- és processzkörnyezetet jelenti. Ellenpélda: a felhasználó a WSL-ben létrehoz egy virtuális környezetet a /home/anna/venv alatt, majd a Windows PowerShellben aktiválni próbálja a \\wsl.localhost\...\venv\Scripts\activate fájlt. A Windows Python nem a WSL-beli bin/python-t használja, a csomagok nem látszanak, és a ModuleNotFoundError elsőre algoritmushibának tűnik. A javítás a rétegek szétválasztása: a PowerShellben a Windows saját Pythonját és venv-jét kell használni, a WSL-ben pedig a WSL-beli környezetet. A Docker-konténer szintén külön: a konténerben futó script nem a gazdagép munkakönyvtárát látja automatikusan, csak a becsatolt kötetet.

Visszautalás. Az 1.4-ben a három hibacsalád a programozási, adatértelmezési és statisztikai hiba volt. Ez az alfejezet az első családon belül azonosít további rétegeket: az operációs rendszer, a fájljog és az interpreter hibái mind a kód futtatása előtt jelentkeznek, ezért nem szabad a statisztikai következtetés hibájának tekinteni őket. Az 2.3-ben a Git-réteg tanította, hogy a repó a projektet viszi, nem a gép állapotát; itt ennek következménye, hogy a klón után a környezetet mindig újra kell ellenőrizni.

Önellenőrzés. (1) Ha a quickcheck.py két gépen ugyanazt a három számot adja, akkor biztos, hogy a modell is ugyanazt fogja adni? Nem; a kontroll csak a bemenő adatméretet és a környezet egy részét ellenőrzi. (2) Melyik parancs mutatja meg először, hogy a python a Microsoft Store csapdájára mutat? A python --version hibaüzenete vagy a launcher hiánya. (3) Miért hibás a chmod-dal kapcsolatosan a „Windowsról hozott jogosultság” feltételezése? Mert a Windows-fájlrendszeren nincs POSIX futtathatósági bit; a bit a Git által tárolt metainformációból származik, ha a repóban rögzítve volt.

2.4.8 Rövid összefoglaló

Egy projekt másik gépen akkor folytatható, ha az operációs rendszer, a fájljog és az interpreter különbségeit nem keverjük a kód hibájával. A Linux, macOS, Windows és WSL eltérő fájlrendszer-szemantikát, sorvég- és jogosultságkezelést hoz; a PowerShell és a POSIX-héj parancsai más szintaxisúak ugyanarra a szándékra. A tiszta klónból futtatott quickcheck.py a szerződött 300/2400/4796 kontrollértékkel ellenőrzi, hogy a projekt bemenete azonos. A hibadiagnózis sorrendje: interpreter, fájl-útvonal, fájljog, és csak ezek után algoritmus. A következő alfejezetben ezt a réteget tovább szűkítjük: a Python-verziót és a csomagfüggőségeket izolált környezetbe zárjuk.