From a2fff7b2b5e880c0af921add8d9227b515dfddfd Mon Sep 17 00:00:00 2001 From: Filip Gralinski Date: Sat, 26 Feb 2022 20:34:34 +0100 Subject: [PATCH] =?UTF-8?q?Poprawki=20w=20wyk=C5=82adzie=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wyk/01_Jezyk.ipynb | 2 +- wyk/01_Jezyk.org | Bin 11292 -> 11710 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/wyk/01_Jezyk.ipynb b/wyk/01_Jezyk.ipynb index d8d8198..0e726c1 100644 --- a/wyk/01_Jezyk.ipynb +++ b/wyk/01_Jezyk.ipynb @@ -15,4 +15,4 @@ "\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\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 +{"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**** (****napisem****) 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ść bułek*\ndla 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, 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\nSymbol 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 -*-\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 524851de8df6c16e248cb7d58acaebd4af61b3a0..9a43ea42e1411f916b4f5ab011846a8129a6272e 100644 GIT binary patch delta 568 zcmZvZ%}T>S6oqL;u;W5RAK-wSCZsmes`Ul(0xA?-O@6R#nxwQTZL+BpT)C3EbmhvW zFs=n@`y#%9dl$}3(ul;nxi@ppcjhK}YQ0~-zLj<~1Qh*25__u|b+q|MskK{G)qwUp zL)TYTh3n4zYip0y%gagy)@U_zy*gpv+wJ{x4Gj$^=#4C#!lK=1!N#OI=7H3UV%x>% z?IQ-%PTVe{5RJ7*VFNTbrYf#3&015s!kY!_1u=$p+x2OLg!&!IpS{o-i5*3HOh^s- zMAzYjyq}qzobw?qO^VH2OjW~3b!2^#xwvgALQGzA0V8wf#(a>3q4P@bH3YLxPpRBn z93*`t=nOxWxCu|0?E6NE{?{}qL7 W%R4)U)rk%XQQ6DE^Cr7j9?Cz3puda& delta 148 zcmdlNJttzr7Dir$yhMe9qN>X5qfLn^lMgdSFy{ejMo!_)_Dn}OIk}Qbk2a-d>nm*L z;mHu;Q^+YzQZP|SO3W%byt#byS_KQ{&AqA%SRFF*%N0s8QWc6*3rkb;l2aA((-e{_ zOHzv!GK&>r5_3|EN~$ySN>Ymoic(8bQ)(4bN{ce{(iMtI^K?rxb5l3#Xis7S0K9iL AY5)KL