Programowanie z AI - Generowanie i Wyjaśnianie Kodu
AI jako partner programisty
Sztuczna inteligencja rewolucjonizuje sposób, w jaki piszemy kod. Narzędzia takie jak GitHub Copilot, ChatGPT czy Claude potrafią generować kod, wyjaśniać złożone fragmenty, pomagać w debugowaniu i automatyzować rutynowe zadania. W tym rozdziale nauczysz się efektywnie wykorzystywać AI w codziennej pracy programisty.
Generowanie kodu z opisu
Najprostsze zastosowanie - opisujesz, co chcesz osiągnąć, a AI generuje kod.
Podstawowe generowanie
Napisz funkcję w Pythonie, która:
- Przyjmuje listę liczb
- Zwraca tylko liczby parzyste
- Sortuje wynik malejąco
def filter_and_sort_even(numbers):
"""
Filtruje liczby parzyste i sortuje malejąco.
Args:
numbers: Lista liczb
Returns:
Lista parzystych liczb posortowanych malejąco
"""
even_numbers = [n for n in numbers if n % 2 == 0]
return sorted(even_numbers, reverse=True)
# Przykład użycia
numbers = [1, 4, 7, 2, 9, 8, 3, 6]
result = filter_and_sort_even(numbers)
print(result) # [8, 6, 4, 2]
Generowanie z komentarzami
Możesz też pisać specyfikację jako komentarze, a AI wypełni kod:
Wypełnij poniższy kod zgodnie z komentarzami:
def process_user_data(users):
# 1. Filtruj użytkowników powyżej 18 lat
# 2. Wyodrębnij tylko imiona i emaile
# 3. Posortuj alfabetycznie po imieniu
# 4. Zwróć jako listę słowników
pass
Generowanie zapytań SQL
AI doskonale radzi sobie z SQL - wystarczy opisać strukturę bazy i zadanie.
Baza danych ma następujące tabele:
Tabela: departments
Kolumny: DepartmentId (INT, PK), DepartmentName (VARCHAR)
Tabela: students
Kolumny: StudentId (INT, PK), StudentName (VARCHAR),
DepartmentId (INT, FK), EnrollmentDate (DATE)
Tabela: courses
Kolumny: CourseId (INT, PK), CourseName (VARCHAR),
Credits (INT)
Tabela: enrollments
Kolumny: StudentId (INT, FK), CourseId (INT, FK),
Grade (DECIMAL)
Napisz zapytanie SQL, które:
Znajdzie wszystkich studentów z działu "Computer Science",
którzy mają średnią ocen powyżej 4.0,
posortowanych po średniej malejąco.
SELECT
s.StudentId,
s.StudentName,
d.DepartmentName,
AVG(e.Grade) as AverageGrade
FROM students s
JOIN departments d ON s.DepartmentId = d.DepartmentId
JOIN enrollments e ON s.StudentId = e.StudentId
WHERE d.DepartmentName = 'Computer Science'
GROUP BY s.StudentId, s.StudentName, d.DepartmentName
HAVING AVG(e.Grade) > 4.0
ORDER BY AverageGrade DESC;
Zawsze podawaj pełną strukturę tabel (kolumny, typy, klucze). Im więcej kontekstu, tym dokładniejsze zapytanie.
Wyjaśnianie kodu
AI potrafi wyjaśnić działanie skomplikowanego kodu w przystępny sposób.
Wyjaśnij poniższy kod Python linijka po linijce.
Skieruj wyjaśnienie do początkującego programisty.
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
Odpowiedź AI: (szczegółowe wyjaśnienie każdej linijki z przykładami)
Różne poziomy szczegółowości
// Dla początkującego:
"Wyjaśnij jak dla kogoś, kto dopiero uczy się programować"
// Dla średnio-zaawansowanego:
"Wyjaśnij działanie, skupiając się na wzorcach projektowych"
// Dla zaawansowanego:
"Przeanalizuj złożoność obliczeniową i optymalizacje"
Debugging z AI
AI może pomóc znaleźć i naprawić błędy w kodzie.
Znajdowanie błędów
Ten kod powinien odwracać string, ale nie działa poprawnie.
Znajdź błąd i go napraw.
def reverse_string(s):
result = ""
for i in range(len(s)):
result += s[i]
return result
print(reverse_string("hello")) # Powinno: "olleh", Jest: "hello"
Błąd: Pętla iteruje od 0 do len(s)-1, dodając znaki
w oryginalnej kolejności zamiast odwrotnej.
Poprawiony kod:
def reverse_string(s):
result = ""
for i in range(len(s) - 1, -1, -1): # Iteracja od końca
result += s[i]
return result
# Lub bardziej pythonowy sposób:
def reverse_string(s):
return s[::-1]
Analiza stack trace
Mój kod zwraca następujący błąd. Wyjaśnij przyczynę
i zaproponuj rozwiązanie:
Traceback (most recent call last):
File "app.py", line 45, in process_data
result = data['users'][0]['email']
KeyError: 'users'
Kod:
def process_data(data):
result = data['users'][0]['email']
return result
Refaktoryzacja kodu
AI może pomóc ulepszyć istniejący kod, zachowując jego funkcjonalność.
Zrefaktoryzuj poniższy kod, aby był bardziej czytelny
i zgodny z dobrymi praktykami Pythona:
def calc(l):
t = 0
for i in range(len(l)):
if l[i] > 0:
t = t + l[i]
return t / len(l) if len(l) > 0 else 0
def calculate_positive_average(numbers: list[float]) -> float:
"""
Oblicza średnią arytmetyczną liczb dodatnich z listy.
Args:
numbers: Lista liczb do przetworzenia
Returns:
Średnia liczb dodatnich lub 0 jeśli lista pusta
"""
if not numbers:
return 0.0
positive_numbers = [n for n in numbers if n > 0]
positive_sum = sum(positive_numbers)
return positive_sum / len(numbers)
Rodzaje refaktoryzacji
- Czytelność - lepsze nazwy zmiennych, dokumentacja
- Wydajność - optymalizacja algorytmów
- Wzorce - zastosowanie design patterns
- Testowanie - dodanie testów jednostkowych
- Bezpieczeństwo - usunięcie podatności
Pisanie testów
AI może automatycznie generować testy jednostkowe dla istniejącego kodu.
Napisz testy jednostkowe (pytest) dla poniższej funkcji.
Uwzględnij przypadki brzegowe.
def validate_email(email: str) -> bool:
"""Sprawdza czy email ma poprawny format."""
import re
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
import pytest
from your_module import validate_email
class TestValidateEmail:
"""Testy dla funkcji validate_email."""
# Poprawne emaile
def test_valid_simple_email(self):
assert validate_email("[email protected]") == True
def test_valid_email_with_dots(self):
assert validate_email("[email protected]") == True
def test_valid_email_with_plus(self):
assert validate_email("[email protected]") == True
def test_valid_email_subdomain(self):
assert validate_email("[email protected]") == True
# Niepoprawne emaile
def test_invalid_no_at(self):
assert validate_email("userexample.com") == False
def test_invalid_no_domain(self):
assert validate_email("user@") == False
def test_invalid_no_tld(self):
assert validate_email("user@example") == False
def test_invalid_empty_string(self):
assert validate_email("") == False
def test_invalid_spaces(self):
assert validate_email("user @example.com") == False
# Przypadki brzegowe
def test_email_with_numbers(self):
assert validate_email("[email protected]") == True
def test_short_tld(self):
assert validate_email("[email protected]") == True
def test_single_char_tld(self):
assert validate_email("[email protected]") == False
Konwersja między językami
AI może tłumaczyć kod z jednego języka programowania na inny.
Przekonwertuj poniższy kod Python na JavaScript (ES6+):
def process_users(users):
active_users = list(filter(lambda u: u['active'], users))
names = list(map(lambda u: u['name'].upper(), active_users))
return sorted(names)
const processUsers = (users) => {
const activeUsers = users.filter(u => u.active);
const names = activeUsers.map(u => u.name.toUpperCase());
return names.sort();
};
// Lub w jednej linii:
const processUsers = (users) =>
users
.filter(u => u.active)
.map(u => u.name.toUpperCase())
.sort();
Generowanie dokumentacji
AI może automatycznie tworzyć dokumentację dla istniejącego kodu.
Dodaj kompletną dokumentację (docstring, komentarze,
type hints) do poniższej klasy:
class Cache:
def __init__(self, max_size=100, ttl=300):
self._data = {}
self._max_size = max_size
self._ttl = ttl
self._timestamps = {}
def get(self, key):
if key in self._data:
if time.time() - self._timestamps[key] < self._ttl:
return self._data[key]
else:
del self._data[key]
del self._timestamps[key]
return None
def set(self, key, value):
if len(self._data) >= self._max_size:
oldest = min(self._timestamps, key=self._timestamps.get)
del self._data[oldest]
del self._timestamps[oldest]
self._data[key] = value
self._timestamps[key] = time.time()
Najlepsze praktyki kodowania z AI
AI może generować kod, który wygląda poprawnie, ale zawiera błędy logiczne lub bezpieczeństwa. Zawsze testuj i przeglądaj.
Określ wersję języka, framework, biblioteki. "Python 3.11 z FastAPI i Pydantic v2" da lepsze wyniki niż "Python".
Staraj się zrozumieć wygenerowany kod. Pytaj o wyjaśnienia. To najlepsza forma nauki.
Jeśli pierwszy wynik nie jest idealny, doprecyzuj wymagania lub poproś o alternatywne podejście.
Popularne narzędzia AI dla programistów
| Narzędzie | Zastosowanie | Integracja |
|---|---|---|
| GitHub Copilot | Autouzupełnianie, generowanie kodu | VS Code, JetBrains, Neovim |
| ChatGPT | Wyjaśnienia, debugging, architektura | Web, API, integracje |
| Claude | Długi kontekst, analiza kodu | Web, API |
| Cursor | IDE z wbudowanym AI | Samodzielne IDE |
| Amazon CodeWhisperer | Autouzupełnianie, bezpieczeństwo | VS Code, JetBrains |
| Tabnine | Autouzupełnianie lokalne | Większość IDE |
Podsumowanie
- Generowanie kodu - opisz zadanie, otrzymaj implementację
- SQL - podaj strukturę bazy, otrzymaj zapytanie
- Wyjaśnienia - AI tłumaczy kod na różnych poziomach zaawansowania
- Debugging - pomoc w znajdowaniu i naprawianiu błędów
- Refaktoryzacja - ulepszanie istniejącego kodu
- Testy - automatyczne generowanie testów jednostkowych
- Dokumentacja - tworzenie docstringów i komentarzy
W kolejnym rozdziale poznasz najlepsze praktyki prompt engineering, w tym bezpieczeństwo promptów i ochronę przed prompt injection.
- Jak wykorzystywać AI do generowania kodu, zapytań SQL, testów jednostkowych i dokumentacji
- Jak AI pomaga w debugowaniu, refaktoryzacji i konwersji kodu między językami programowania
- Dlaczego zawsze trzeba weryfikować wygenerowany kod i podawać kontekst technologiczny (wersja języka, framework)
Następny krok: Najlepsze Praktyki Prompt Engineering — poznasz zasady bezpieczeństwa promptów, obronę przed prompt injection i najczęstsze błędy do uniknięcia.