SZUKAMY β-testerów Ścieżki Kariery Programisty AI! Zapisz się TU.

Ścieżka Kariery Computer Vision – Miesiąc 1. – Hello NumPy
Pierwszy kontakt z kodem – nareszcie! 🙂
Dobra, przetłumaczmy to sobie z polskiego na nasze – co tu właściwie trzeba zrobić?
Plan projektu:
- Stwórz folder hello_numpy:
W folderze sciezka-kariery-computer-vision (stworzonym w poprzednim zadaniu) załóż folder hello_numpy. (podkreślniki i małe litery czyli tzw. snake case to standard w nazywaniu plików i modułów w Pythonie). - Stwórz pliki projektu:
Wewnątrz folderu hello_numpy stwórz następujące pliki: hello_numpy.py, test_hello_numpy.py i README.md. - Uzgodnij kryteria akceptacji:
Opis zadania jest dość ogólnikowy. Dlatego warto uściślić kryteria zadania. Ja polecam następujące:
– macierz 3×3 liczb całkowitych w zakresie [-10, 10]
– wyznacznik w formie liczby całkowitej
– obsługa wyjątków - Stwórz nowy branch, np. m1-hello-numpy i przejdź na niego.
- Napisz kod.
- Dodaj testy do funkcji tworzącej macierz i do funkcji obliczającej wyznacznik (ang. determinant).
- Dodaj opis w pliku README.md projektu (nie pomyl z README całej ścieżki).
- Zrób commit i Merge Request do maina.
- Poklep się po pleckach – dobra robota! 🙂
Jest plan – czas na szybką implementację. 🙂
Ad. 1 i 2 – struktura projektu:
Zakładam folder, wewnątrz 3 pliki: hello_numpy.py , test_hello_numpy.py i README.md (tylko dla mojego mini projektu).
Zakładam folder, wewnątrz 3 pliki: hello_numpy.py , test_hello_numpy.py i README.md (tylko dla mojego mini projektu).
Ja jeszcze dodatkowo stworzyłam plik requirements.txt w folderze głównym sciezka-kariery-computer-vision. Dzięki temu będę mieć w jednym miejscu wszystkie zależności (bo będę używać jednego środowiska wirtualnego do wielu mini projektów i nie chcę się pogubić).
Ad. 4 – Nowy branch dla projektu
Tworzę i przełączam się na nowy branch: m1-hello-numpy.
git status
# On branch main
# Your branch is up to date with 'origin/main'.
git branch m1-hello-numpy
git checkout m1-hello-numpy
#Switched to branch 'm1-hello-numpy'
Ad. 5 – kodujemy
Kryteria są już dokładnie wyjaśnione, więc czas coś napisać. Ale co to jest ten determinant? Po polsku to wyznacznik i liczy się go tylko dla macierzy kwadratowych.
Najpierw krótkie przypomnienie z matematyki u pani Arietty z AjkaMat.pl (swoją drogą polecam – bardzo szybko i jasno wszystko tłumaczy).
No dobra, wszystko jasne. Teraz jeszcze krótkie wprowadzenie do samego NumPy’ja (czyt. „nampaj”). Zamiast czytać dokumentację (co IMO jest bardzo przydatne, kiedy już musisz znaleźć konkretną funkcję), zacznijmy od kolejnego filmiku na YouTubie – tym razem po angielsku od Nicholasa. Jeśli wolisz coś po polsku, polecam ten filmik na kanale MAP – ja oglądam w przyśpieszeniu 1.7, dzięki czemu nie zdążę się zanudzić…
Swoją drogą, dlaczego wszystkie te tutki są taaaakie dłuuugie i takie nieposkładane? Dlaczego naukę NumPy’ja zaczynamy od tablic, skoro wcześniej są jeszcze skalary (na których BTW bardzo często wysypuje się kod przy ML!).
Wracając do kodowania – ja używam funkcji np.random.randint (bo nasza macierz ma być wypełniona liczbami całkowitymi) i np.linalg.det do obliczenia wyznacznika.
SPOILER – kliknij, żeby zobaczyć moje rozwiązanie:
import numpy as np
def generate_int_matrix(low: int = -10, high: int = 10, size: tuple = (3, 3)) -> np.ndarray:
"""Tworzy losową macierz liczb całkowitych o zadanym rozmiarze i zakresie."""
if low > high:
raise ValueError("Parametr 'low' nie może być większy niż 'high'")
return np.random.randint(low, high + 1, size)
def calculate_determinant(matrix: np.ndarray) -> float:
"""Oblicza wyznacznik macierzy."""
if matrix.shape[0] != matrix.shape[1]:
raise ValueError("Macierz musi być kwadratowa")
return np.linalg.det(matrix)
if __name__ == "__main__":
matrix = generate_int_matrix()
det = int(round(calculate_determinant(matrix)))
print("\nMacierz 3×3:")
print(matrix)
print(f"\nWyznacznik: {det}")
Dlaczego tak?
Najpierw importuję numpy’ja. Następnie tworzę macierz z liczb całkowitych. Oczywiście typuję argumenty (<3 typowanie!) i dodaję wartości domyślne od -10 do 10 i rozmiar 3×3. Jednocześnie zostawiam użytkownikowi opcję zmiany tych argumentów, żeby funkcja była bardziej elastyczna.
W ramach obsługi wyjątków sprawdzam, czy low jest niższy od high.
Następnie tworzę funkcję do obliczania wyznacznika.
Najpierw sprawdzam, czy macierz jest kwadratowa, żeby w ogóle dało się obliczyć wyznacznik. Następnie wybieram np.linalg.det. Niestety ta funkcja zwraca floata, nawet jeśli macierz zawiera tylko inty. Ale żeby funkcja była elastyczna, nie ruszam tego tutaj.
Dopiero przy wywołaniu zaokrąglam wynik i zamieniam na inta, żeby to wyglądało czyściej na ekranie.
Gotowe! 🙂
Ad. 6 Testy
Z założenia testy powinny sprawdzać tzw. happy path (czy wszystko dobrze działa, jeśli użytkownik dsziała zgodnie z planem), egde cases czyli „przypadki brzegowe” i exception handling czyli „obsługę wyjątków”.
SPOILER – kliknij, żeby zobaczyć moje rozwiązanie:
Dlaczego tak?
Napisałam 7 testów, głównie do sprawdzenia happy path i obsługi wyjątków. Pewnie można więcej, ale wg mnie starczy.
import pytest
import numpy as np
from hello_numpy.hello_numpy import generate_int_matrix, calculate_determinant
def test_generate_int_matrix_defaultshape_and_type():
matrix = generate_int_matrix()
assert isinstance(matrix, np.ndarray)
assert matrix.shape == (3, 3)
assert issubclass(matrix.dtype.type, np.integer)
def test_generate_int_matrix_raises_on_invalid_range():
with pytest.raises(ValueError):
generate_int_matrix(low=10, high=5)
def test_generate_int_matrix_range():
low, high = -5, 5
matrix = generate_int_matrix(low=low, high=high)
assert np.all(matrix >= low)
assert np.all(matrix <= high)
def test_calculate_determinant_on_known_matrix():
matrix = np.array([[1, 2, 3],
[0, 1, 4],
[5, 6, 0]])
det = calculate_determinant(matrix)
assert round(det) == 1 # Znany wynik
def test_calculate_determinant_type():
matrix = generate_int_matrix()
det = calculate_determinant(matrix)
assert isinstance(det, float)
def test_calculate_determinant_non_square_raises():
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
with pytest.raises(ValueError):
calculate_determinant(matrix)
def test_calculate_determinant_raises_on_non_square_generated_matrix():
matrix = generate_int_matrix(size=(2, 4))
with pytest.raises(ValueError):
calculate_determinant(matrix)
Ad. 8 Commit i MergeRequest
Po stworzeniu opisu w README.md (za pomocą ChataGPT, bo jestem leniwą bułą i nie cierpię Markdown’a!), mogę robić commit i MR do maina.
git status
git add .
git commit -m "hello-numpy ready with tests and readme"
git push
# Jeśli wywali Ci błąd, bo nie masz zdalnego brancha:
git push --set-upstream origin m1-hello-numpy
Idę do GitHuba i tworzę Merge Request:
Sprawdzam, czy wszystko się zgadza i merdżuję.
I zadanie zrobione. 🙂
Co dalej?
→ Zapisz się do naszego newslettera, żeby nigdy nie przegapić żadnego wartościowego artykułu.
→ Zajrzyj do sekcji Kariera w AI, gdzie znajdziesz konkretne materiały o zmianach na rynku pracy – w Polsce i na świecie – oraz ścieżkach kariery związanych ze sztuczną inteligencją (nie tylko jako programista!).
→ A jeśli chcesz pisać modele i pracować jako Architekt AI, ale nie wiesz, od czego zacząć (lub utknąłeś gdzieś na ścieżce), odwiedź dział Nauka AI – czeka tam wiedza, ciekawostki i realne wsparcie.
! Uwaga
Niniejszy ebook ma charakter informacyjny i edukacyjny. Nie stanowi porady prawnej ani oferty pracy w rozumieniu przepisów krajowych lub unijnych.
Przy tworzeniu niniejszego artykułu korzystano ze wsparcia narzędzi opartych na sztucznej inteligencji – m.in. w zakresie porządkowania treści, analizy źródeł, przyspieszenia redakcji i wyszukiwania źródeł Jednak wszelkie decyzje dotycząca treści, interpretacji i ostatecznej formy zostały podjęte przez człowieka.


