Generált kép, ami a refaktorálás, ellenőrzés folyamatos körforgását szimbolizálja.

Mutatjuk, hogyan javítsd az MI által generált kódot

Ismerős az érzés? Péntek délután van, kapkodsz, beírod a promptot a ChatGPT-nek: „Írj egy Python szkriptet, ami ár-adatokat gyűjt ki, és elmenti őket egy CSV fájlba”. Tíz másodperc múlva ott a kód. Lefuttatod. Működik. Hazamész. Aztán hétfőn, amikor integrálni kellene a főrendszerbe, rájössz, hogy amit kaptál, az nem szoftver, hanem egy időzített bomba.

Az MI-alapú kódgenerálás, legyen az ChatGPT, Claude vagy GitHub Copilot, elképesztő sebességet ad. De van egy hatalmas ára, amit sokan nem vesznek észre. A technikai adósság. Az MI ugyanis „egyszer futtatható”, run-once szkriptekben gondolkodik. Nem érdekli a karbantarthatóság, a modularitás vagy a típusbiztonság. Neki a cél a gyors válasz, nem a clean code.

Ebben a cikkben megmutatom a különbséget a „működő” MI-kód és a „fenntartható” mérnöki munka között. Veszünk egy tipikus generált kódrészletet, és lépésről lépésre átalakítjuk vállalati szintű megoldássá.

A probléma

Kértem a modelltől egy egyszerű szkriptet: elemezzen egy értékesítési CSV-t, és szűrje ki a hibás tranzakciókat. Ezt adta és ez az, amit a fejlesztők 80%-a gondolkodás nélkül bemásol:

A „rossz” generált kód:

import pandas as pd

# Hardcoded útvonal - ha áthelyezed a fájlt, összeomlik
data = pd.read_csv('sales_data.csv')

# Nincs hibakezelés. Mi van, ha hiányzik az 'amount' oszlop?
# Nincs függvény, minden a globális térben fut
results = []
for index, row in data.iterrows():
    if row['amount'] > 1000:
        discount = row['amount'] * 0.9
        results.append(discount)
    else:
        results.append(row['amount'])

data['final_price'] = results
data.to_csv('processed_sales.csv')
print("Kész!")

Mi a baj ezzel?

  1. Soronkénti iteráció használata: Pandasban ciklust írni bűn, lassú!
  2. Globális változók: Ha ezt be akarod hívni egy másik modulba, nem tudod.
  3. Szöveg érték: Mi az, hogy 1000? Mi az, hogy 0.9? Később senki nem fogja tudni, mik ezek a számok.
  4. Típusok hiánya: Milyen adatot vár? DataFrame-et? Listát?

1. lépés: Modularizálás és vektorizáció

Az első dolgunk, hogy a logikát kiszervezzük függvényekbe, és kihasználjuk a Pandas erejét a lassú Python ciklusok helyett.

import pandas as pd

def calculate_discounted_price(df):
    # Vektorizált művelet: 100x gyorsabb, mint a for ciklus
    # A logikát olvashatóan elkülönítjük
    df.loc[df['amount'] > 1000, 'final_price'] = df['amount'] * 0.9
    df.loc[df['amount'] <= 1000, 'final_price'] = df['amount']
    return df

def main():
    df = pd.read_csv('sales_data.csv')
    processed_df = calculate_discounted_price(df)
    processed_df.to_csv('processed_sales.csv')

if __name__ == "__main__":
    main()

Már jobb. De még mindig nem „production-ready”.

2. lépés: Típusmegjelölés, a jövőbeli énednek

Az MI gyakran elhagyja a típusmegjelöléseket (type hints), pedig ezek nélkül egy nagy projektben a kollégáid és az IDE-d, vakon repülnek. Mondjuk meg a kódnak, mi micsoda!

import pandas as pd
from pathlib import Path

# Konstansok kiszervezése - így egy helyen módosítható az üzleti logika
DISCOUNT_THRESHOLD = 1000
DISCOUNT_RATE = 0.9

def apply_business_logic(df: pd.DataFrame) -> pd.DataFrame:
    """
    Kiszámítja a végső árat a kedvezmény szabályok alapján.
    
    Args:
        df (pd.DataFrame): A nyers értékesítési adatokat tartalmazó DataFrame.
        
    Returns:
        pd.DataFrame: A módosított DataFrame a 'final_price' oszloppal.
    """
    # Defensive programming: másolatot készítünk, hogy ne módosítsuk az eredetit véletlenül
    processed_df = df.copy()
    
    mask = processed_df['amount'] > DISCOUNT_THRESHOLD
    
    processed_df['final_price'] = processed_df['amount']
    processed_df.loc[mask, 'final_price'] = processed_df['amount'] * DISCOUNT_RATE
    
    return processed_df

3. lépés: Validáció és pydantic, a profi szint

Mi történik, ha a CSV-ben szöveg van a számok helyett? Az MI kódja összeomlik. A miénk nem fog, mert bevezetjük a pydantic könyvtárat az adatvalidációra. Ez ma az ipari sztenderd Pythonban.

from pydantic import BaseModel, ValidationError, PositiveFloat
from typing import List
import pandas as pd

# Adatmodell definiálása: Ez a szerződés (contract) az adatokkal
class SaleTransaction(BaseModel):
    transaction_id: int
    amount: PositiveFloat # Automatikusan ellenőrzi, hogy pozitív szám-e

def validate_data(df: pd.DataFrame) -> List[SaleTransaction]:
    """Validálja a bejövő sorokat a Pydantic modellel."""
    valid_transactions = []
    errors = []
    
    for record in df.to_dict(orient='records'):
        try:
            # Itt történik a validáció
            transaction = SaleTransaction(**record)
            valid_transactions.append(transaction)
        except ValidationError as e:
            errors.append(f"Hiba a {record.get('transaction_id')} tranzakciónál: {e}")
    
    if errors:
        print(f"Figyelem: {len(errors)} hibás sort találtunk!")
        # Itt logolhatnánk a hibákat fájlba
        
    return valid_transactions

# Így a kódunk nemcsak számol, de védi is a rendszert a szemét adatoktól.

4. lépés: Tesztelés, amit az MI mindig kihagy

Az MI megírja a kódot, de honnan tudod, hogy jól számol? Kérj tőle teszteket! A pytest a legjobb barátod. Íme egy trükk. Másold be a refaktorált függvényedet az MI-nek, és ezt a promptot add neki:

„Írj átfogó unit teszteket ehhez a függvényhez a pytest használatával. Vedd bele a határeseteket is (pl. pontosan 1000, 0, negatív számok).”

import pytest
import pandas as pd
# Feltételezve, hogy a fenti 'apply_business_logic' importálva van

def test_discount_application():
    # Setup - Tesztadat létrehozása
    input_data = pd.DataFrame({
        'amount': [500, 1000, 2000]
    })
    
    # Action - Futtatás
    result = apply_business_logic(input_data)
    
    # Assert - Ellenőrzés
    # 500 -> marad 500
    assert result.iloc[0]['final_price'] == 500
    # 1000 -> marad 1000 (határérték teszt)
    assert result.iloc[1]['final_price'] == 1000 
    # 2000 -> 1800 (kedvezményes)
    assert result.iloc[2]['final_price'] == 1800

Ne légy „copy-paste” fejlesztő!

Az MI egy kiváló junior asszisztens. Megírja az általad megadott prompt alapján, a sablont. De a te feladatod, hogy senior mérnökként viselkedj.

A mivagyunk.hu szabálya:

  1. Generáltass – Gyorsaság.
  2. Olvass és érts – Ellenőrzés.
  3. Refaktorálj – Minőség.
  4. Tesztelj – Biztonság.

A kód karbantartása a te felelősséged. Ha a generált kód miatt áll le a szerver hajnali 2-kor, a ChatGPT nem fogja felvenni a telefont. Te viszont igen.

Kérjük, ellenőrizd a mező formátumát, és próbáld újra.
Köszönjük, hogy feliratkoztál.

vagyunk.hu hírlevél

Hozzászólás

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük