774 lines
19 KiB
Plaintext
774 lines
19 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
|
||
"<div class=\"alert alert-block alert-info\">\n",
|
||
"<h1> Modelowanie języka </h1>\n",
|
||
"<h2> 1. <i>Język i jego zapis</i> [wykład]</h2> \n",
|
||
"<h3> Filip Graliński (2022)</h3>\n",
|
||
"</div>\n",
|
||
"\n",
|
||
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Język — różne perspektywy\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Słowo wstępne\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"W matematyce istnieją dwa spojrzenia na rzeczywistość: ciągłe i dyskretne.\n",
|
||
"\n",
|
||
"Otaczająca nas rzeczywistość fizyczna jest z natury ciągła\n",
|
||
"(przynajmniej jeśli nie operujemy w mikroskali), lecz język\n",
|
||
"jest dyskretnym wyłomem w ciągłej rzeczywistości.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Lingwistyka matematyczna\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Przypomnijmy sobie definicję języka przyjętą w lingwistyce\n",
|
||
"matematycznej, w kontekście, na przykład, teorii automatów.\n",
|
||
"\n",
|
||
"****Alfabetem**** nazywamy skończony zbiór symboli.\n",
|
||
"\n",
|
||
"****Łańcuchem**** (****napisem****) nad alfabetem $\\Sigma$ nazywamy dowolny, skończony,\n",
|
||
"ciąg złożony z symboli z $\\Sigma$.\n",
|
||
"\n",
|
||
"****Językiem**** nazywamy dowolny, skończony bądź nieskończony, zbiór łańcuchów.\n",
|
||
"\n",
|
||
"W tym formalnym ujęciu językami są na przykład następujące zbiory:\n",
|
||
"\n",
|
||
"- $\\{\\mathit{poniedziałek},\\mathit{wtorek},\\mathit{środa},\\mathit{czwartek},\\mathit{piątek},\\mathit{sobota},\\mathit{niedziela}\\}$\n",
|
||
"- $\\{\\mathit{ab},\\mathit{abb},\\mathit{abbb},\\mathit{abbbb},\\ldots\\}$\n",
|
||
"\n",
|
||
"To podejście, z jednej strony oczywiście nie do końca się pokrywa się z potocznym\n",
|
||
"rozumieniem słowa *język*, z drugiej kojarzy nam się z takimi\n",
|
||
"narzędziami informatyki jak wyrażenia regularne, automaty skończenie\n",
|
||
"stanowe czy gramatyki języków programowania.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"abbb"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import regex as re\n",
|
||
"rx = re.compile(r'ab+')\n",
|
||
"\n",
|
||
"rx.search('żabbba').group(0)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import rstr\n",
|
||
"\n",
|
||
"rstr.xeger(r'ab+')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Ujęcie probabilistyczne\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Na tym wykładzie przyjmiemy inną perspektywą, częściowo ciągłą, opartą\n",
|
||
"na probabilistyce. Język będziemy definiować poprzez ****rozkład\n",
|
||
"prawdopodobieństwa****: sensownym wypowiedziom czy tekstom będziemy\n",
|
||
"przypisywać stosunkowe wysokie prawdopodobieństwo, „ułomnym” tekstom — niższe (być może zerowe).\n",
|
||
"\n",
|
||
"Na ogół nie mamy jednak do czynienia z językiem jako takim tylko z\n",
|
||
"jego przybliżeniami, ****modelami**** (model może być lepszy lub gorszy,\n",
|
||
"ale przynajmniej powinien być użyteczny…). Formalnie $M$ nazywamy\n",
|
||
"modelem języka (nad skończonym alfabetem $\\Sigma$), jeśli określa dyskretny rozkład prawdopodobieństwa $P_M$:\n",
|
||
"\n",
|
||
"$$P_M \\colon \\Sigma^{*} \\rightarrow [0,1].$$\n",
|
||
"\n",
|
||
"Rzecz jasna, skoro mamy do czynienia z rozkładem prawdopodobieństwa, to:\n",
|
||
"\n",
|
||
"$$\\sum_{\\alpha \\in \\Sigma^{*}} P_M(\\alpha) = 1.$$\n",
|
||
"\n",
|
||
"Jeśli $M$ ma być modelem języka polskiego, oczekiwalibyśmy, że dla\n",
|
||
"napisów:\n",
|
||
"\n",
|
||
"- $z_1$ — *W tym stanie rzeczy pan Ignacy coraz częściej myślał o Wokulskim.*\n",
|
||
"- $z_2$ — *Po wypełniony zbiornik pełny i należne kwotę, usłyszała w attendant*\n",
|
||
"- $z_3$ — *xxxxyźźźźźit backspace hoooooooooop x y z*\n",
|
||
"\n",
|
||
"zachodzić będzie:\n",
|
||
"\n",
|
||
"$$ P_M(z_1) > P_M(z_2) > P_M(z_3). $$\n",
|
||
"\n",
|
||
"****Pytanie**** Jakiej konkretnie wartości prawdopodobieństwa\n",
|
||
"spodziewalibyśmy się dla zdania *Dzisiaj rano kupiłem w piekarni sześć bułek*\n",
|
||
"dla sensownego modelu języka polskiego?\n",
|
||
"\n",
|
||
"Moglibyśmy sprowadzić tę definicję języka do tej „dyskretnej”, tzn.\n",
|
||
"moglibyśmy przyjąć, że łańcuch $\\alpha$ należy do języka wyznaczonego\n",
|
||
"przez model $M$, jeśli $P_M(\\alpha) > 0$.\n",
|
||
"\n",
|
||
"****Pytanie**** Czy moglibyśmy w ten sposób opisać język nieskończony? Czy może istnieć\n",
|
||
"dyskretny rozkład prawdopodobieństwa dla nieskończonego zbioru?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Co jest symbolem?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Model języka daje rozkład prawdopodobieństwa nad zbiorem łańcuchów\n",
|
||
"opartym na skończonym alfabecie, tj. zbiorze symboli. W praktyce\n",
|
||
"alfabet nie musi być zgodny z potocznym czy językoznawczym rozumieniem\n",
|
||
"tego słowa. To znaczy alfabet może być zbiorem znaków (liter), ale\n",
|
||
"modelować język możemy też przyjmując inny typ symboli: sylaby,\n",
|
||
"morfemy (cząstki wyrazów) czy po prostu całe wyrazy.\n",
|
||
"\n",
|
||
"Powinniśmy przy tym pamiętać, że, koniec końców, w pamięci komputera\n",
|
||
"wszelkiego rodzaju łańcuchy są zapisywane jako ciągi zer i jedynek — bitów.\n",
|
||
"Omówmy pokrótce techniczną stronę modelowania języka.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Kodowanie znaków\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Cóż może być prostszego od pliku tekstowego?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
" Ala ma kota.\n",
|
||
"\n",
|
||
"Komputer nic nie wie o literach.\n",
|
||
"\n",
|
||
"… w rzeczywistości operuje tylko na liczbach …\n",
|
||
"\n",
|
||
"… czy raczej na zerach i jedynkach …\n",
|
||
"\n",
|
||
"… a tak naprawdę na ciągłym sygnale elektrycznym …\n",
|
||
"\n",
|
||
"![img](./01_Jezyk/digitalsignal.jpg)\n",
|
||
"\n",
|
||
"… zera i jedynki są w naszej głowie …\n",
|
||
"\n",
|
||
"… co jest dziwne, *naprawdę* dziwne …\n",
|
||
"\n",
|
||
"… ale nikt normalny się tym nie przejmuje.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Jak zakodować literę?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Zakodowanie pikseli składających się na kształtu (****glyfu****) litery A\n",
|
||
"*oczywiście* nie jest dobrym pomysłem.\n",
|
||
"\n",
|
||
"![img](./01_Jezyk/raster.png)\n",
|
||
"\n",
|
||
"Nie, potrzebujemy *arbitralnego* kodowania dla wszystkich możliwych\n",
|
||
"kształtów litery A (*w naszych głowach*): A, $\\mathcal{A}$,\n",
|
||
"$\\mathbb{A}$, $\\mathfrak{A}$ powinny otrzymać ten sam kod, powiedzmy 65\n",
|
||
"(binarnie: 1000001).\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### ASCII\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"ASCII to 7-bitowy (****nie**** 8-bitowy!) system kodowania znaków.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"40: (\n",
|
||
"41: )\n",
|
||
"42: *\n",
|
||
"43: +\n",
|
||
"44: ,\n",
|
||
"45: -\n",
|
||
"46: .\n",
|
||
"47: /\n",
|
||
"48: 0\n",
|
||
"49: 1\n",
|
||
"50: 2\n",
|
||
"51: 3\n",
|
||
"52: 4\n",
|
||
"53: 5\n",
|
||
"54: 6\n",
|
||
"55: 7\n",
|
||
"56: 8\n",
|
||
"57: 9\n",
|
||
"58: :\n",
|
||
"59: ;\n",
|
||
"60: <\n",
|
||
"61: =\n",
|
||
"62: >\n",
|
||
"63: ?\n",
|
||
"64: @\n",
|
||
"65: A\n",
|
||
"66: B\n",
|
||
"67: C\n",
|
||
"68: D\n",
|
||
"69: E\n",
|
||
"70: F\n",
|
||
"71: G\n",
|
||
"72: H\n",
|
||
"73: I\n",
|
||
"74: J\n",
|
||
"75: K\n",
|
||
"76: L\n",
|
||
"77: M\n",
|
||
"78: N\n",
|
||
"79: O\n",
|
||
"80: P\n",
|
||
"81: Q\n",
|
||
"82: R\n",
|
||
"83: S\n",
|
||
"84: T\n",
|
||
"85: U\n",
|
||
"86: V\n",
|
||
"87: W\n",
|
||
"88: X\n",
|
||
"89: Y\n",
|
||
"90: Z\n",
|
||
"91: [\n",
|
||
"92: \\\n",
|
||
"93: ]\n",
|
||
"94: ^\n",
|
||
"95: _\n",
|
||
"96: `\n",
|
||
"97: a\n",
|
||
"98: b\n",
|
||
"99: c\n",
|
||
"100: d\n",
|
||
"101: e\n",
|
||
"102: f\n",
|
||
"103: g\n",
|
||
"104: h\n",
|
||
"105: i\n",
|
||
"106: j\n",
|
||
"107: k\n",
|
||
"108: l\n",
|
||
"109: m\n",
|
||
"110: n\n",
|
||
"111: o\n",
|
||
"112: p\n",
|
||
"113: q\n",
|
||
"114: r\n",
|
||
"115: s\n",
|
||
"116: t\n",
|
||
"117: u\n",
|
||
"118: v\n",
|
||
"119: w\n",
|
||
"120: x\n",
|
||
"121: y\n",
|
||
"122: z\n",
|
||
"123: {\n",
|
||
"124: |\n",
|
||
"125: }\n",
|
||
"126: ~\n",
|
||
"127: \n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"for code in range(40, 128):\n",
|
||
" print(f'{code}: {chr(code)}')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Jak zejść na poziom bitów?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Linux — wiersz poleceń\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Linux command line:\n",
|
||
"\n",
|
||
" $ echo 'Ala ma kota' > file.txt\n",
|
||
" $ hexdump -C file.txt\n",
|
||
" 00000000 41 6c 61 20 6d 61 20 6b 6f 74 61 0a |Ala ma kota.|\n",
|
||
" 0000000c\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Edytor tekstu (Emacs)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"![img](./01_Jezyk/hexl-mode.png)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Uwaga!\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"- kiedy dzieje się coś dziwnego, sprawdź, co tak *naprawdę* jest w pliku\n",
|
||
"- ASCII jest 7-bitowym kodowaniem (128 znaków)\n",
|
||
" - choć zazwyczaj uzupełnionym (ang. *padded*) do 8 bitów\n",
|
||
" - nie mów plik *plik ASCII*, kiedy masz na myśli *prosty/czysty plik tekstowy* (ang. *plain text file*)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Higiena plików tekstowych\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Piekło końca wiersza\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"![img](./01_Jezyk/dante.jpg)\n",
|
||
"\n",
|
||
"Więcej na [https://re-research.pl/pl/post/2017-01-28-00042-anatomia-pliku-tekstowego-2.html](https://re-research.pl/pl/post/2017-01-28-00042-anatomia-pliku-tekstowego-2.html)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Dobre rady\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"- żadnych niepotrzebnych spacji na końcu wiersza\n",
|
||
"\n",
|
||
"- żadnych niepotrzebnych pustych wierszy na końcu pliku\n",
|
||
"\n",
|
||
"- … ale ostatni wiersz powinien zakończyć się znakiem końca wiersza\n",
|
||
"\n",
|
||
"- nie używać znaków tabulacji (zamiast tego 4 spacje)\n",
|
||
" - wyjątek: pliki TSV\n",
|
||
" - wyjątek: pliki Makefile\n",
|
||
"\n",
|
||
"- uwaga na niestandardowe spacje i dziwne znaki o zerowej długości\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Unikod\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"ASCII obejmuje 128 znaków: litery alfabetu łacińskiego (właściwie angielskiego),\n",
|
||
"cyfry, znaki interpunkcyjne, znaki specjalne itd.\n",
|
||
"\n",
|
||
"Co z pozostałymi znakami? Polskimi ogonkami, czeskimi haczykami,\n",
|
||
"francuskimi akcentami, cyrylicą, koreańskim alfabetem, chińskimi\n",
|
||
"znakami, rongorongo?\n",
|
||
"\n",
|
||
"워싱턴, 부산, 삼성\n",
|
||
"\n",
|
||
"Rozwiązaniem jest Unikod (ang. *Unicode*) system, który przypisuje\n",
|
||
"znakom używanym przez ludzkość liczby (kody, ang. *code points*).\n",
|
||
"\n",
|
||
"| Znak|Kod ASCII|Kod Unikodowy|\n",
|
||
"|---|---|---|\n",
|
||
"| 9|57|57|\n",
|
||
"| a|97|97|\n",
|
||
"| ą|-|261|\n",
|
||
"| ł|-|322|\n",
|
||
"| $\\aleph$|-|1488|\n",
|
||
"| ặ|-|7861|\n",
|
||
"| ☣|-|9763|\n",
|
||
"| 😇|-|128519|\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### UTF-8\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Kody znaków są pojęciem abstrakcyjnym. Potrzebujemy konkretnego ****kodowania****\n",
|
||
"by zamienić kody w sekwencję bajtów. Najpopularniejszym kodowaniem jest UTF-8.\n",
|
||
"\n",
|
||
"W kodowaniu UTF-8 znaki zapisywane za pomocą 1, 2, 3, 4, 5 lub 6 bajtów\n",
|
||
"(w praktyce — raczej to 4 bajtów).\n",
|
||
"\n",
|
||
"| Znak|Kod Unikodowy|Szesnastkowo|UTF-8 (binarnie)|\n",
|
||
"|---|---|---|---|\n",
|
||
"| 9|57|U+0049|01001001|\n",
|
||
"| a|97|U+0061|01100001|\n",
|
||
"| ą|261|U+0105|11000100:10000101|\n",
|
||
"| ł|322|U+0142|11000101:10000010|\n",
|
||
"| $\\aleph$|1488|U+05D0|11010111:10010000|\n",
|
||
"| ặ|7861|U+1EB7|11100001:10111010:10110111|\n",
|
||
"| ☣|9763|U+2623|11100010:10011000:10100011|\n",
|
||
"| 😇|128519|U+1f607|11110000:10011111:10011000:10000111|\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### UTF-8 — ogólny schemat zamiany kodu na bajty\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"- 0x00 do 0x7F – 0xxxxxxx,\n",
|
||
"- 0x80 do 0x7FF – 110xxxxx 10xxxxxx\n",
|
||
"- 0x800 do 0xFFFF — 1110xxxx 10xxxxxx 10xxxxxx\n",
|
||
"- 0x10000 do 0x1FFFFF – 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n",
|
||
"- 0x200000 do 0x3FFFFFF – 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n",
|
||
"- 0x4000000 do 0x7FFFFFFF – 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx\n",
|
||
"\n",
|
||
"Symbol x oznacza znaczący bit.\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### *Źdźbło* to ile bajtów w UTF-8?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Jeśli wczytać jako wiersz w języku C, 11 bajtów!\n",
|
||
"\n",
|
||
"![img](./01_Jezyk/zdzblo.png)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Dlaczego UTF-8 jest doskonałym systemem kodowania?\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"- wstecznie kompatybilny z ASCII\n",
|
||
" - plik ASCII jest poprawnym plikiem UTF-8\n",
|
||
"- nie zajmuje dużo miejsca\n",
|
||
" - chyba że w tekście jest dużo „dziwnych” znaków\n",
|
||
"- proste grepowanie działa\n",
|
||
" - `grep UAM text-in-utf8.txt` zadziała\n",
|
||
" - ale nawet nie próbuj: `grep SRPOL text-in-utf16.txt`\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Porady\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"- zawsze używaj UTF-8\n",
|
||
" - bądź asertywny! jeśli w pracy każą używać czegoś innego — rezygnuj z pracy\n",
|
||
" - **NIE** używaj innych unikodowych kodowań: UTF-16, UTF-32, UCS-2\n",
|
||
" - **NIE** używaj nieunikodowych systemów kodowania\n",
|
||
" - ISO-8859-2, Windows-1250, Mazovia, IEA Świerk, …\n",
|
||
"- uwaga na pułapki UTF-8\n",
|
||
" - ustalenie długości napisu w znakach wymaga przejścia znak po znaku\n",
|
||
" - jeśli napis w kodowaniu UTF-8 zajmuje 9 bajtów, ile to znaków?\n",
|
||
" 3, 4, 5, 6, 7, 8 lub 9!\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### **NIE** używaj sekwencji BOM\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"![img](./01_Jezyk/evil-bom.png)\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Unikod/UTF-8 a języki programowania\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Pamiętaj, żeby być konsekwentnym!\n",
|
||
"\n",
|
||
"- kodowanie kodu źródłowego (literały!)\n",
|
||
" - czasami podawane na początku pliku\n",
|
||
" - … albo brane z ustawień *locale*\n",
|
||
" - … albo — domyślnie — UTF-8 (w nowszych językach programowania)\n",
|
||
"- kodowanie standardowego wejścia/wyjścia i plików\n",
|
||
"- jak sekwencje bajtów są interpretowane w czasie działania programu?\n",
|
||
" - *Źdźbło* jest łańcuchem złożonym z 6 czy 9 elementów??\n",
|
||
" - 9 bajtów\n",
|
||
" - 6 kodów\n",
|
||
" - `\"Źdźbło\"[1]` …\n",
|
||
" - `d`\n",
|
||
" - … albo śmieci\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Python 2\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"#!/usr/bin/python2\n",
|
||
"# -*- coding: utf-8 -*-\n",
|
||
"import sys\n",
|
||
"for line in sys.stdin:\n",
|
||
" line = line.decode('utf-8').rstrip()\n",
|
||
" if \"źdźbło\".decode('utf-8') in line:\n",
|
||
" print len(line), ' ', line"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"#### Python3\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"#!/usr/bin/python3\n",
|
||
"import sys\n",
|
||
"for line in sys.stdin:\n",
|
||
" line = line.strip()\n",
|
||
" if \"źdźbło\" in line:\n",
|
||
" print(len(line), ' ', line)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Uwaga: zakładając, że zmienna środowiskowa `LANG` jest ustawiona na UTF-8.\n",
|
||
"\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.10.9"
|
||
},
|
||
"org": null
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 1
|
||
}
|