Kurs Python · Moduł 12: Projekt końcowy
Przygotowanie do Kariery
W tej lekcji5
Gratulacje! Ukończyłeś Python Safari. Masz za sobą dwanaście lokacji, ale sam certyfikat jeszcze nikogo nie zatrudnił. Rekruter ma kilkadziesiąt sekund na Twoje CV, a na rozmowie technicznej padną pytania, które sprawdzą, czy rozumiesz to, co piszesz. Teraz czas zamienić zdobyte umiejętności w pierwszą pracę. Przygotujemy CV, profil LinkedIn, odpowiedzi na typowe pytania i listę miejsc, gdzie warto szukać ofert.
CV dla Python Developera
Dobre CV programisty jest krótkie i konkretne: dane kontaktowe z linkiem do GitHuba, jednozdaniowe podsumowanie, umiejętności pogrupowane w kategorie i projekty z wynikami. Oto szablon:
1# Jan Kowalski
2Python Developer | AI/ML Specialist
3
4jan@example.com | linkedin.com/in/jan | github.com/jan
5
6## Summary
7Python developer z doświadczeniem w budowaniu aplikacji AI/ML.
8Specjalizacja: RAG systems, FastAPI, Machine Learning.
9
10## Skills
11
12**Languages:** Python, JavaScript, SQL
13**Frameworks:** FastAPI, Django, React
14**AI/ML:** LlamaIndex, LangChain, PyTorch, scikit-learn
15**Databases:** PostgreSQL, Qdrant, Redis
16**Tools:** Docker, Git, GitHub Actions, AWS
17
18## Projects
19
20### AI Document Assistant | [GitHub](link) | [Demo](link)
21- RAG system do przeszukiwania dokumentów
22- Tech: FastAPI, LlamaIndex, Qdrant, OpenAI
23- Wyniki: <2s response time, 92% accuracy
24
25### ML Pipeline | [GitHub](link)
26- End-to-end ML pipeline z MLflow
27- Tech: scikit-learn, XGBoost, MLflow, Docker
28- Wyniki: 15% improvement w accuracy
29
30## Education
31
32**Python Safari** - CodeWorlds (2024)
33- 12-modułowy kurs Python i AI
34- Capstone: AI Document Assistant
35
36## Certifications
37- [Nazwa certyfikatu]Sekcja Projects jest ważniejsza niż Education, bo pokazuje, co zbudowałeś. Liczby w polach "Wyniki" to przykład formatu, nie gotowe wartości: wpisz tylko to, co naprawdę zmierzyłeś w swoim projekcie. Rekruter może o każdą liczbę zapytać na rozmowie. Na początku kariery trzymaj CV na jednej stronie i wysyłaj je jako PDF, żeby formatowanie nie rozjechało się po drugiej stronie.
LinkedIn Optimization
LinkedIn działa jak wyszukiwarka, rekruterzy szukają po słowach kluczowych w nagłówku i sekcji About. Nagłówek to nie tylko stanowisko, to lista technologii:
1## Headline
2Python Developer | AI/ML | FastAPI | Building intelligent applications
3
4## About
5Passionate Python developer specializing in AI applications.
6
7RAG Systems & LLM Integration
8FastAPI & Async Python
9Machine Learning Pipelines
10
11Currently building: AI Document Assistant - semantic search for documents.
12
13Open to opportunities in AI/ML development.
14
15## Featured
16- Link do najlepszego projektu
17- Artykuł/post o technologii
18- Certyfikat/dyplomSekcja Featured to miejsce na link do najlepszego projektu. Jeden dobrze opisany projekt z demo mówi więcej niż lista dwudziestu technologii. Dodaj też link do GitHuba w danych kontaktowych, bo właśnie tam rekruter pójdzie szukać dowodów Twoich umiejętności.
Przygotowanie do Interview
Rozmowa techniczna dla Python developera zwykle obejmuje cztery obszary. Przejdźmy przez nie po kolei. Pierwszy to fundamenty języka, a klasyczne pytanie dotyczy GIL:
1# Typowe pytania techniczne
2
3# 1. Python fundamentals
4def explain_gil():
5 """
6 GIL (Global Interpreter Lock) - mechanizm w CPython,
7 który pozwala tylko jednemu wątkowi wykonywać
8 bytecode Pythona w danym momencie.
9
10 Rozwiązania:
11 - multiprocessing dla CPU-bound
12 - asyncio dla I/O-bound
13 - alternatywne interpretery (PyPy)
14 """
15 passGIL (Global Interpreter Lock) w standardowym CPythonie pozwala tylko jednemu wątkowi naraz wykonywać bytecode Pythona. Wątki nie przyspieszą więc obliczeń na procesorze. Warto dodać, że od Pythona 3.13 istnieje osobny build free-threaded bez GIL (PEP 703), w 3.14 oficjalnie wspierany (PEP 779), ale wciąż opcjonalny. Drugi obszar to programowanie asynchroniczne:
1# 2. Async Python
2async def explain_async():
3 """
4 async/await - model współbieżności w Pythonie.
5 - async def - definiuje coroutine
6 - await - czeka na wynik async operacji
7 - Idealne dla I/O-bound operations
8 """
9 passModuł asyncio daje obsługę async/await. Zasada do zapamiętania: async/await dla operacji I/O-bound (sieć, baza, pliki), multiprocessing dla CPU-bound. Trzeci obszar to wzorce projektowe, które znasz z lekcji o architekturze:
1# 3. Design Patterns
2def explain_patterns():
3 """
4 Najważniejsze wzorce:
5 - Repository Pattern - abstrakcja dostępu do danych
6 - Dependency Injection - luźne powiązania
7 - Factory Pattern - tworzenie obiektów
8 - Observer Pattern - reaktywność
9 """
10 passNa rozmowie nie wystarczy nazwa wzorca, pokaż przykład z własnego projektu, na przykład DocumentRepository. Czwarty obszar to projektowanie systemu:
1# 4. System Design
2def design_rag_system():
3 """
4 Komponenty:
5 1. API Gateway - routing, auth
6 2. RAG Service - query processing
7 3. Vector Database - embeddings storage
8 4. LLM Service - text generation
9 5. Cache - Redis for frequent queries
10 6. Monitoring - Prometheus + Grafana
11 """
12 passTo dokładnie architektura Twojego capstone projektu. Opowiedz, dlaczego wybrałeś każdy komponent, bo o to będą dopytywać.
Padną też pytania o narzędzia. Wirtualne środowisko tworzysz poleceniem python -m venv .venv, a aktywujesz na Linuksie i macOS przez source .venv/bin/activate. Plik requirements.txt zawiera listę zależności z wersjami. Pydantic w FastAPI waliduje dane i definiuje modele żądań oraz odpowiedzi. pytest domyślnie odkrywa pliki test_*.py oraz *_test.py.
Gdzie szukać pracy
Ostatni krok to wiedzieć, gdzie polować na oferty. Serwisy zmieniają się z czasem (GitHub Jobs i Stack Overflow Jobs już nie istnieją), więc traktuj tę listę jako punkt startu:
1## Junior/Mid Python Developer
2
31. **LinkedIn Jobs** - najlepsze źródło
42. **NoFluffJobs** - polski rynek IT
53. **JustJoinIT** - startupy i korpo
64. **Bulldogjob** - polski portal z ofertami IT
75. **Wellfound** (dawniej AngelList Talent) - startupy, oferty międzynarodowe
8
9## Freelance
10
111. **Upwork** - projekty długoterminowe
122. **Toptal** - premium, wymaga weryfikacji
133. **Fiverr** - mniejsze projekty
14
15## Open Source
16
171. Contribute to projects you use
182. Build your reputation
193. Network with developersOpen source to często niedoceniana droga: kontrybucja do biblioteki, której używasz, to publiczny dowód umiejętności i kontakt z doświadczonymi programistami.
Następne kroki
Plan na najbliższe tygodnie jest prosty: ukończ Capstone Project, opublikuj go na GitHubie, zaktualizuj CV i LinkedIn, aplikuj na pozycje i kontynuuj naukę. Moja rada: nie czekaj, aż poczujesz się "gotowy". Aplikuj, gdy masz jeden porządny projekt, bo rozmowy same w sobie są najlepszym treningiem.
Pamiętaj: to nie koniec, to początek Twojej przygody z Pythonem, a każda kolejna ekspedycja zaczyna się od mapy, którą narysowałeś w tym module.
Kod do tej lekcji: main.py
1# ===========================================
2# Safari Capstone: Core Service Layer
3# ===========================================
4# Implement the core business logic service that
5# manages wildlife operations and analytics.
6
7from dataclasses import dataclass, field
8from datetime import datetime
9from typing import Optional
10import json
11
12# --- Models ---
13@dataclass
14class Animal:
15 animal_id: str
16 species: str
17 name: str
18 weight_kg: float
19 region: str
20
21@dataclass
22class Observation:
23 obs_id: str
24 animal_id: str
25 latitude: float
26 longitude: float
27 observer: str
28 timestamp: str = ""
29
30# --- Repository ---
31class AnimalRepository:
32 def __init__(self):
33 self._data = {}
34
35 def save(self, animal): self._data[animal.animal_id] = animal
36 def get(self, aid): return self._data.get(aid)
37 def get_all(self): return list(self._data.values())
38 def delete(self, aid): return self._data.pop(aid, None) is not None
39 def find_by_species(self, sp):
40 return [a for a in self._data.values() if a.species.lower() == sp.lower()]
41
42# --- Core Service ---
43class SafariService:
44 """Core business logic for the safari management system."""
45
46 def __init__(self, repo: AnimalRepository):
47 self.repo = repo
48 self.observations: list[Observation] = []
49 self._next_obs_id = 1
50
51 def register_animal(self, species, name, weight_kg, region) -> Animal:
52 """Register a new animal in the system."""
53 prefix = species[:2].upper()
54 count = len(self.repo.find_by_species(species)) + 1
55 animal_id = f"{prefix}-{count:03d}"
56 animal = Animal(animal_id, species, name, weight_kg, region)
57 self.repo.save(animal)
58 return animal
59
60 def record_observation(self, animal_id, lat, lon, observer) -> Optional[Observation]:
61 """Record a new wildlife observation."""
62 animal = self.repo.get(animal_id)
63 if not animal:
64 return None
65 obs = Observation(
66 obs_id=f"OBS-{self._next_obs_id:04d}",
67 animal_id=animal_id,
68 latitude=lat,
69 longitude=lon,
70 observer=observer,
71 timestamp=datetime.now().isoformat()
72 )
73 self.observations.append(obs)
74 self._next_obs_id += 1
75 return obs
76
77 def get_species_stats(self) -> dict:
78 """Get population statistics grouped by species."""
79 stats = {}
80 for animal in self.repo.get_all():
81 species = animal.species
82 if species not in stats:
83 stats[species] = {"count": 0, "total_weight": 0.0, "regions": set()}
84 stats[species]["count"] += 1
85 stats[species]["total_weight"] += animal.weight_kg
86 stats[species]["regions"].add(animal.region)
87 # Convert sets to lists for JSON compatibility
88 for sp in stats:
89 stats[sp]["avg_weight"] = round(stats[sp]["total_weight"] / stats[sp]["count"], 1)
90 stats[sp]["regions"] = list(stats[sp]["regions"])
91 return stats
92
93 def get_observation_count(self, animal_id: str) -> int:
94 """Count observations for a specific animal."""
95 return sum(1 for o in self.observations if o.animal_id == animal_id)
96
97 def generate_report(self) -> str:
98 """Generate a summary report of all wildlife data."""
99 stats = self.get_species_stats()
100 total_animals = self.repo.get_all()
101 lines = [
102 "=== Safari Wildlife Report ===",
103 f"Total animals tracked: {len(total_animals)}",
104 f"Total observations: {len(self.observations)}",
105 f"Species tracked: {len(stats)}",
106 ""
107 ]
108 for species, data in stats.items():
109 lines.append(f"{species}: {data['count']} animals, "
110 f"avg {data['avg_weight']} kg, "
111 f"regions: {', '.join(data['regions'])}")
112 return "\n".join(lines)
113
114# --- Demo ---
115repo = AnimalRepository()
116service = SafariService(repo)
117
118# Register animals
119service.register_animal("Lion", "Simba", 195.0, "Savanna")
120service.register_animal("Lion", "Nala", 130.0, "Savanna")
121service.register_animal("Elephant", "Tembo", 5200.0, "Forest")
122service.register_animal("Cheetah", "Duma", 52.0, "Grassland")
123
124# Record observations
125service.record_observation("LI-001", -2.33, 34.83, "Dr. Darwin")
126service.record_observation("LI-001", -2.34, 34.84, "Dr. Darwin")
127service.record_observation("EL-001", -2.41, 34.92, "Ranger Kate")
128
129# Generate report
130print(service.generate_report())
131print(f"\nSimba observations: {service.get_observation_count('LI-001')}")
132print(f"\nSpecies stats:")
133print(json.dumps(service.get_species_stats(), indent=2))
134
135# TODO: Add a method to find the most observed animal
136# def most_observed_animal(self) -> Optional[str]:
137# counts = {}
138# for obs in self.observations:
139# counts[obs.animal_id] = counts.get(obs.animal_id, 0) + 1
140# if not counts:
141# return None
142# return max(counts, key=counts.get)
143
144# TODO: Add data export functionality
145# def export_data(self, format="json") -> str:
146# data = {
147# "animals": [vars(a) for a in self.repo.get_all()],
148# "observations": [vars(o) for o in self.observations],
149# "stats": self.get_species_stats()
150# }
151# return json.dumps(data, indent=2, default=str)
152Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co to jest GIL (Global Interpreter Lock) w Pythonie?
2. Kiedy używać async/await zamiast multiprocessing?
To 2 z 5 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w poziomie
Ułóż elementy:
- Klikanie w kolejności
Kliknij w kolejności:
- Edytor kodu
Stwórz .github/workflows/ci.yml z krokami: checkout, setup-python, install, test.
- Edytor kodu
Zainicjuj projekt Capstone
- Edytor kodu
Stwórz rdzeń aplikacji
- Edytor kodu
Zaimplementuj warstwę API
- Edytor kodu
Dodaj testy do projektu