Gdy pracujesz z modelem językowym na polskim tekście, szybko trafiasz na zwykłe, ale kłopotliwe sprawy: litery z ogonkami zajmują w pamięci więcej bajtów, sortowanie według kodów znaków ustawia „ł” za „z”, a nazwy plików bez polskich liter są bezpieczniejsze. Zanim uczniowie zaczną używać modeli, warto, by znali te mechanizmy. Na lekcji ćwiczą je w Pythonie na krótkim zdaniu, w którym są wszystkie polskie litery diakrytyczne.
Scenariusz jest przeznaczony na 45 minut dla klasy znającej napisy w Pythonie — na przykład po lekcji o kodowaniu znaków. Lekcja nie wymaga dostępu do żadnego modelu AI; dotyczy przygotowania tekstu. Wnioski o konkretnych modelach (w tym polskich) wymagają sprawdzenia w dokumentacji danego modelu — lekcja ich nie przesądza.
Przygotowanie stanowisk
Potrzebny jest Python 3 i edytor lub IDLE. Rozpakuj pakiet z sekcji materiałów do osobnego folderu i uruchamiaj skrypty z tego folderu. Program uruchomisz przez Run → Run Module albo poleceniem python start.py, python3 start.py lub py start.py.
Cele i plan lekcji
Po zajęciach uczeń potrafi:
- odróżnić liczbę znaków od liczby bajtów w UTF-8;
- wykryć i policzyć polskie litery diakrytyczne;
- usunąć ogonki w sposób bezpieczny (łącznie z literą „ł”);
- posortować słowa według polskiego alfabetu.
| Czas | Praca na lekcji |
|---|---|
| 0–5 min | Problem: dlaczego „łódź” jest za „zebrą”? |
| 5–15 min | Znaki, bajty, normalizacja Unicode |
| 15–22 min | Polskie litery w Pythonie |
| 22–37 min | Trzy zadania |
| 37–42 min | Gdzie to ma znaczenie przy pracy z AI |
| 42–45 min | Pytania kontrolne |
Znaki a bajty
W UTF-8 znaki ASCII zajmują 1 bajt, a polskie litery z ogonkami — 2 bajty. Zdanie „Zażółć gęślą jaźń.” ma 18 znaków, ale 27 bajtów: każda z dziewięciu polskich liter (ż, ó, ł, ć, ę, ś, ą, ź, ń) zajmuje 2 bajty, czyli o jeden więcej niż litera łacińska. Rozmiar tekstu w bajtach ma znaczenie przy limitach długości (np. pól w bazie, rozmiaru plików), a modele przetwarzają tekst w jednostkach zwanych tokenami, których liczba zwykle różni się od liczby znaków i słów.
Polskie litery
W programie lista "ąćęłńóśźż" pozwala policzyć polskie litery i znaleźć, które występują. Zdanie wzorcowe zawiera wszystkie dziewięć liter diakrytycznych polskiego alfabetu (zażółć gęślą jaźń).
Usuwanie ogonków
Funkcja bez_ogonkow najpierw zamienia „ł/Ł” na „l/L” (litera „ł” nie rozkłada się na literę i akcent), a następnie normalizuje tekst do postaci NFD (litera i osobny znak akcentu) i usuwa znaki akcentów (kategoria Mn). Używa się jej do nazw plików i adresów, ale nie do tekstu, który ma być czytany lub analizowany po polsku — usunięcie ogonków zmienia znaczenie (np. „łabędź”, „labedz”).
Sortowanie
Domyślne sortowanie porównuje kody znaków: „ł”, „ć”, „ż” mają kody większe niż „z”, więc trafiają na koniec. Polski alfabet ma kolejność a ą b c ć d e ę f ... l ł m n ń o ó p r s ś t u w y z ź ż. Prosty klucz sortowania zamienia każdą literę na jej pozycję w alfabecie. Prawdziwe sortowanie według reguł językowych (zwane kolacją) uwzględnia dodatkowe zasady, np. wielkość liter, dlatego do zastosowań poważnych używa się bibliotek ustawień regionalnych.
Znaczenie przy pracy z AI
Czyść tekst przed wysłaniem do modelu, zachowując ogonki; nie ucinaj tekstu w bajtach w środku znaku; sprawdzaj kodowanie pliku (UTF-8).
Zadania
Zadanie 1. Znaki i bajty. Policz znaki, bajty UTF-8 i słowa w zdaniu „Zażółć gęślą jaźń.” oraz znajdź użyte polskie litery.
Zadanie 2. Bez ogonków. Napisz bez_ogonkow i przetestuj ją na dwóch zdaniach (łącznie z literą „ł”).
Zadanie 3. Sortowanie. Posortuj osiem słów domyślnie i według polskiego alfabetu, porównaj wyniki.
Dla chętnych: dodaj obsługę wielkich liter w kluczu sortowania i sprawdź słowa „Łódź” i „lato”.
Rozwiązanie i wyniki
import unicodedata
PL = "aąbcćdeęfghijklłmnńoóprsśtuwyzźż"
TEKST = "Zażółć gęślą jaźń."
# Zadanie 1: znaki, bajty, slowa
print("Znaki:", len(TEKST), "| bajty UTF-8:", len(TEKST.encode("utf-8")), "| slowa:", len(TEKST.split()))
polskie = [z for z in TEKST.lower() if z in "ąćęłńóśźż"]
print("Polskie litery:", len(polskie), sorted(set(polskie)))
# Zadanie 2: usuwanie znakow diakrytycznych (np. dla nazw plikow)
def bez_ogonkow(tekst):
tekst = tekst.replace("ł", "l").replace("Ł", "L")
rozlozony = unicodedata.normalize("NFD", tekst)
return "".join(z for z in rozlozony if unicodedata.category(z) != "Mn")
print(bez_ogonkow(TEKST))
print(bez_ogonkow("Łódź, żółw i świt"))
# Zadanie 3: sortowanie wedlug polskiego alfabetu
SLOWA = ["łódź", "lato", "zebra", "żaba", "ćma", "cebula", "ząb", "zamek"]
print("Domyslne:", sorted(SLOWA))
print("Polskie :", sorted(SLOWA, key=lambda s: [PL.index(z) for z in s]))
Program wypisze:
Znaki: 18 | bajty UTF-8: 27 | slowa: 3
Polskie litery: 9 ['ó', 'ą', 'ć', 'ę', 'ł', 'ń', 'ś', 'ź', 'ż']
Zazolc gesla jazn.
Lodz, zolw i swit
Domyslne: ['cebula', 'lato', 'zamek', 'zebra', 'ząb', 'ćma', 'łódź', 'żaba']
Polskie : ['cebula', 'ćma', 'lato', 'łódź', 'zamek', 'ząb', 'zebra', 'żaba']
Zdanie ma 18 znaków i 27 bajtów (dziewięć znaków z ogonkami zajmuje po 2 bajty), 3 słowa i wszystkie dziewięć polskich liter diakrytycznych. Po usunięciu ogonków wychodzi „Zazolc gesla jazn.”. Domyślne sortowanie umieszcza słowa na „ć”, „ł” i „ż” za „zebrą”, a sortowanie według polskiego alfabetu — w prawidłowych miejscach (np. „ćma” po „cebuli”). Plik rozszerzenie.py pokazuje, że „ł” ma kod 322, większy niż „z” (122).
Plik rozszerzenie.py (zadanie dla chętnych) wypisze:
b'\xc5\x82' 2 322 122
Typowe błędy
| Objaw | Co sprawdzić |
|---|---|
| Liczenie długości tekstu w bajtach zamiast w znakach | Polskie litery zajmują 2 bajty; użyj len(tekst) dla znaków. |
| Ucinanie tekstu w bajtach | Możesz przeciąć znak w połowie — tnij po znakach. |
| Pozostawienie „ł” po normalizacji | Litera „ł” wymaga osobnej zamiany. |
| Sortowanie po kodach znaków | Polskie litery trafiają na koniec; użyj klucza z alfabetem. |
| Zły plik (nie UTF-8) | Zapisz i otwórz plik w UTF-8. |
| Usuwanie ogonków z tekstu do analizy | Zmienia znaczenie słów. |
Pytania kontrolne i punktacja
- Dlaczego „Zażółć gęślą jaźń” ma 18 znaków, ale 27 bajtów?
- Dlaczego trzeba osobno zamienić „ł” przy usuwaniu ogonków?
- Dlaczego domyślne sortowanie ustawia „ł” za „z”?
Odpowiedzi: Bo polskie litery z ogonkami zajmują w UTF-8 po dwa bajty. Bo „ł” nie jest literą „l” z osobnym znakiem akcentu, więc normalizacja Unicode jej nie rozkłada. Bo porównuje kody znaków, a kod „ł” jest większy niż kod „z”.
Proponowana punktacja (razem 10 punktów): zadanie 1 — znaki, bajty, słowa i litery 3 pkt; zadanie 2 — funkcja i dwa testy 3 pkt; zadanie 3 — dwa sortowania i porównanie 2 pkt; kodowanie w pytaniach 2 pkt. Zadanie dla chętnych nie jest wymagane do pełnej oceny.
Materiały do pobrania
Rozpakuj ZIP przed otwarciem plików. Materiały są dostępne bez logowania; publiczne rozwiązanie służy nauce i samodzielnemu sprawdzeniu, a nie poufnemu sprawdzianowi.
Co dalej?
Następny krok to tokenizacja tekstu, praca z modelami na polskim tekście i ocena odpowiedzi. Ten materiał rozwija dział o odpowiedzialnym korzystaniu z AI w kursie AI w TablicaPro, gdzie znajdziesz prezentacje, ćwiczenia i testy do prowadzenia lekcji.
Źródła techniczne: UTF-8 w Wikipedii oraz moduł unicodedata. Zobacz też lekcję o kodowaniu znaków.
Poprowadź kolejne lekcje AI
Pełny kurs: prezentacje, ćwiczenia i testy do pracy z klasą.
Kup dostęp do kursu AI →