diff --git a/wyk/01_Jezyk.ipynb b/wyk/01_Jezyk.ipynb index ac40f53..1b29e39 100644 --- a/wyk/01_Jezyk.ipynb +++ b/wyk/01_Jezyk.ipynb @@ -1,698 +1 @@ -{ - "cells": [ - { - "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**** 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 dyskretny określa 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 byśmy\n", - "spodziewali się dla zdania *Dzisiaj rano kupiłem w piekarni sześć\n", - "bułek* 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 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": [ - "0: \u0000\n", - "1: \u0001\n", - "2: \u0002\n", - "3: \u0003\n", - "4: \u0004\n", - "5: \u0005\n", - "6: \u0006\n", - "7: \u0007\n", - "8: \b\n", - "9:\n", - "10:\n", - "\n", - "11: \u000b", - "\n", - "12: \f", - "\n", - "13:\n", - "14: \u000e\n", - "15: \u000f\n", - "16: \u0010\n", - "17: \u0011\n", - "18: \u0012\n", - "19: \u0013\n", - "20: \u0014\n", - "21: \u0015\n", - "22: \u0016\n", - "23: \u0017\n", - "24: \u0018\n", - "25: \u0019\n", - "26: \u001a\n", - "27: \u001b\n", - "28: \u001c", - "\n", - "29: \u001d", - "\n", - "30: \u001e", - "\n", - "31: \u001f\n", - "32:\n", - "33: !\n", - "34: \"\n", - "35: #\n", - "36: $\n", - "37: %\n", - "38: &\n", - "39: '\n", - "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: " - ] - } - ], - "source": [ - "for code in range(0, 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 lub 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": [ - "### *Źdźbło* to ile bajtów w UTF-8?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Jeśli wczytasz jako wiersz w języku C, 11 bajtów!\n", - "\n", - "[./01_Jezyk/zdzblo.pdf](./01_Jezyk/zdzblo.pdf)\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 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" - ] - } - ], - "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.2" - }, - "org": null - }, - "nbformat": 4, - "nbformat_minor": 1 -} +{"cells":[{"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\nOtaczająca nas rzeczywistość fizyczna jest z natury ciągła\n(przynajmniej jeśli nie operujemy w mikroskali), lecz język\njest 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\nmatematycznej, w kontekście na przykład teorii automatów.\n\n****Alfabetem**** nazywamy skończony zbiór symboli.\n\n****Łańcuchem**** nad alfabetem $\\Sigma$ nazywamy dowolny, skończony,\ncią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\nW 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\nTo podejście, z jednej strony oczywiście nie do końca się pokrywa się z potocznym\nrozumieniem słowa *język*, z drugiej kojarzy nam się z takimi\nnarzędziami informatyki jak wyrażenia regularne, automaty skończenie\nstanowe 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\nrx = re.compile(r'ab+')\n\nrx.search('żabbba').group(0)"]},{"cell_type":"code","execution_count":1,"metadata":{},"outputs":[{"name":"stdout","output_type":"stream","text":"abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"}],"source":["import rstr\n\nrstr.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ą\nna probabilistyce. Język będziemy definiować poprzez ****rozkład\nprawdopodobieństwa****: sensownym wypowiedziom czy tekstom będziemy\nprzypisywać stosunkowe wysokie prawdopodobieństwo, „ułomnym” tekstom — niższe (być może zerowe).\n\nNa ogół nie mamy jednak do czynienia z językiem jako takim tylko z\njego przybliżeniami, ****modelami**** (model może być lepszy lub gorszy,\nale przynajmniej powinien być użyteczny…). Formalnie $M$ nazywamy\nmodelem 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\nRzecz jasna, skoro mamy do czynienia z rozkładem prawdopodobieństwa, to:\n\n$$\\sum_{\\alpha \\in \\Sigma^{*}} P_M(\\alpha) = 1.$$\n\nJeśli $M$ ma być modelem języka polskiego, oczekiwalibyśmy, że dla\nnapisó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\nzachodzić 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\nspodziewalibyśmy się dla zdania *Dzisiaj rano kupiłem w piekarni sześć\nbułek* dla sensownego modelu języka polskiego?\n\nMoglibyśmy sprowadzić tę definicję języka do tej „dyskretnej”, tzn.\nmoglibyśmy przyjąć, że łańcuch $\\alpha$ należy do języka wyznaczonego\nprzez 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ć\ndyskretny 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\nopartym na skończonym alfabecie, tj. zbiorze symboli. W praktyce\nalfabet nie musi być zgodny z potocznym czy językoznawczym rozumieniem\ntego słowa. To znaczy alfabet może być zbiorem znaków (liter), ale\nmodelować język możemy też przyjmując inny typ symboli: sylaby,\nmorfemy (cząstki wyrazów) czy po prostu całe wyrazy.\n\nPowinniśmy przy tym pamiętać, że, koniec końców, w pamięci komputera\nwszelkiego rodzaju łańcuchy są zapisywane jako ciągi zer i jedynek — bitów.\nOmó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\nKomputer 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\nNie, potrzebujemy *arbitralnego* kodowania dla wszystkich możliwych\nkształ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":"0: \u0000\n1: \u0001\n2: \u0002\n3: \u0003\n4: \u0004\n5: \u0005\n6: \u0006\n7: \u0007\n8: \b\n9:\n10:\n\n11: \u000b\n12: \f\n13:\n14: \u000e\n15: \u000f\n16: \u0010\n17: \u0011\n18: \u0012\n19: \u0013\n20: \u0014\n21: \u0015\n22: \u0016\n23: \u0017\n24: \u0018\n25: \u0019\n26: \u001a\n27: \u001b\n28: \u001c\n29: \u001d\n30: \u001e\n31: \u001f\n32:\n33: !\n34: \"\n35: #\n36: $\n37: %\n38: &\n39: '\n40: (\n41: )\n42: *\n43: +\n44: ,\n45: -\n46: .\n47: /\n48: 0\n49: 1\n50: 2\n51: 3\n52: 4\n53: 5\n54: 6\n55: 7\n56: 8\n57: 9\n58: :\n59: ;\n60: <\n61: =\n62: >\n63: ?\n64: @\n65: A\n66: B\n67: C\n68: D\n69: E\n70: F\n71: G\n72: H\n73: I\n74: J\n75: K\n76: L\n77: M\n78: N\n79: O\n80: P\n81: Q\n82: R\n83: S\n84: T\n85: U\n86: V\n87: W\n88: X\n89: Y\n90: Z\n91: [\n92: \\\n93: ]\n94: ^\n95: _\n96: `\n97: a\n98: b\n99: c\n100: d\n101: e\n102: f\n103: g\n104: h\n105: i\n106: j\n107: k\n108: l\n109: m\n110: n\n111: o\n112: p\n113: q\n114: r\n115: s\n116: t\n117: u\n118: v\n119: w\n120: x\n121: y\n122: z\n123: {\n124: |\n125: }\n126: ~\n127: "}],"source":["for code in range(0, 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\nWię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),\ncyfry, znaki interpunkcyjne, znaki specjalne itd.\n\nCo z pozostałymi znakami? Polskimi ogonkami, czeskimi haczykami,\nfrancuskimi akcentami, cyrylicą, koreańskim alfabetem, chińskimi\nznakami, rongorongo?\n\n워싱턴, 부산, 삼성\n\nRozwiązaniem jest Unikod (ang. *Unicode*) system, który przypisuje\nznakom 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****\nby zamienić kody w sekwencję bajtów. Najpopularniejszym kodowaniem jest UTF-8.\n\nW kodowaniu UTF-8 znaki zapisywane za pomocą 1, 2, 3 lub 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":["### *Ź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?how the sequence of bytes is \\alert{interpreted} during run-time?\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 -*-\nimport sys\nfor 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\nimport sys\nfor 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":{"org":null,"kernelspec":{"display_name":"Python 3","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.5.2"}},"nbformat":4,"nbformat_minor":0} \ No newline at end of file diff --git a/wyk/01_Jezyk.org b/wyk/01_Jezyk.org index cfb6589..524851d 100644 Binary files a/wyk/01_Jezyk.org and b/wyk/01_Jezyk.org differ diff --git a/wyk/01_Jezyk/raster.png b/wyk/01_Jezyk/raster.png new file mode 100644 index 0000000..1113dca Binary files /dev/null and b/wyk/01_Jezyk/raster.png differ diff --git a/wyk/01_Jezyk/zdzblo.png b/wyk/01_Jezyk/zdzblo.png new file mode 100644 index 0000000..0632af1 Binary files /dev/null and b/wyk/01_Jezyk/zdzblo.png differ