Wykład
3
.gitignore
vendored
@ -174,3 +174,6 @@ cython_debug/
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
*~
|
||||
*.log
|
||||
*.aux
|
||||
|
29
README.md
@ -1,11 +1,11 @@
|
||||
# Modelowanie języka 2023
|
||||
# Modelowanie języka 2024
|
||||
|
||||
Tutaj znajdują się informacje dotyczące wykładu i ćwiczeń z
|
||||
„Modelowania języka”, zajęć prowadzonych przez prof. UAM dr. hab.
|
||||
Filip Gralińskiego.
|
||||
Filip Gralińskiego i dr. Pawła Skórzewskiego.
|
||||
|
||||
**Uwaga** Informacje podane w plikach w podkatalogach `wyk/` i `cw/`
|
||||
nie muszą być aktualne (są to materiały przeniesione z poprzedniego
|
||||
nie muszą być aktualne (częściowo są to materiały przeniesione z poprzedniego
|
||||
roku). W szczególności proszę nie wykonywać żadnych zadań z materiałów
|
||||
ćwiczeniowych, chyba że wyraźnie wskazano je tutaj lub pojawiły się
|
||||
jako zadanie na platformie Teams.
|
||||
@ -21,28 +21,7 @@ na trzy, mniej więcej równe objętością, działy:
|
||||
|
||||
## Zasady zaliczenia wykładu
|
||||
|
||||
Wykład kończy się egzaminem. Z egzaminu można uzyskać zwolnienie pod
|
||||
następującymi warunkami:
|
||||
|
||||
* ocena co najmniej dobry plus z ćwiczeń,
|
||||
* uzyskanie co najmniej 20 punktów wykładowych.
|
||||
|
||||
Punkt wykładowy można zdobyć za różnego rodzaju aktywności związane z wykładem:
|
||||
|
||||
* zgłoszenie (jakiegokolwiek: merytorycznego, językowego,
|
||||
technicznego) błędu w materiałach do wykładu (punkt otrzymuje
|
||||
pierwszy zgłaszający),
|
||||
* zadanie sensownego pytania na wykładzie,
|
||||
* odpowiedź na pytanie na wykładzie,
|
||||
* udział w dyskusji po wykładzie na platformie Teams (zadanie pytania
|
||||
lub odpowiedź na pytanie innego studenta).
|
||||
|
||||
Punkt wykładowy jest zaliczony tylko pod warunkiem obecności na danym wykładzie.
|
||||
|
||||
Dodatkowo przy liczeniu sumy punktów wykładowych obowiązują następujące ograniczenia:
|
||||
|
||||
* liczymy maksymalnie 3 punkty na wykład,
|
||||
* z każdego działu liczymy maksymalnie 8 punktów.
|
||||
Wykład kończy się egzaminem.
|
||||
|
||||
## Zasady zaliczenia ćwiczeń
|
||||
|
||||
|
773
wyk/01_Jezyk.ipynb
Normal file
@ -0,0 +1,773 @@
|
||||
{
|
||||
"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
|
||||
}
|
BIN
wyk/01_Jezyk.org
Normal file
BIN
wyk/01_Jezyk/dante.jpg
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
wyk/01_Jezyk/digitalsignal.jpg
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
wyk/01_Jezyk/evil-bom.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
wyk/01_Jezyk/hexl-mode.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
wyk/01_Jezyk/raster.png
Normal file
After Width: | Height: | Size: 301 B |
BIN
wyk/01_Jezyk/zdzblo.pdf
Normal file
BIN
wyk/01_Jezyk/zdzblo.png
Normal file
After Width: | Height: | Size: 43 KiB |
320
wyk/01_Jezyk/zdzblo.svg
Normal file
@ -0,0 +1,320 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="298.000000pt" height="420.000000pt" viewBox="0 0 298.000000 420.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,420.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1420 3723 c0 -5 4 -14 9 -22 7 -11 11 -9 20 8 10 18 9 21 -9 21 -11
|
||||
0 -20 -3 -20 -7z"/>
|
||||
<path d="M1517 3723 c-13 -12 -7 -33 8 -33 8 0 15 9 15 20 0 20 -11 26 -23 13z"/>
|
||||
<path d="M1590 3710 c0 -11 7 -20 15 -20 8 0 15 9 15 20 0 11 -7 20 -15 20 -8
|
||||
0 -15 -9 -15 -20z"/>
|
||||
<path d="M1692 3718 c-16 -16 -15 -28 3 -28 8 0 15 9 15 20 0 23 -2 24 -18 8z"/>
|
||||
<path d="M1779 3728 c-7 -24 -5 -38 7 -38 8 0 14 9 14 20 0 11 -4 20 -10 20
|
||||
-5 0 -10 -1 -11 -2z"/>
|
||||
<path d="M1864 3718 c-5 -7 -3 -8 7 -3 12 8 12 6 0 -8 -12 -15 -11 -17 3 -17
|
||||
9 0 16 8 16 20 0 22 -15 27 -26 8z"/>
|
||||
<path d="M1949 3728 c-7 -24 -5 -38 6 -38 8 0 11 7 8 20 -5 17 -11 26 -14 18z"/>
|
||||
<path d="M2037 3723 c-13 -12 -7 -33 8 -33 8 0 15 9 15 20 0 20 -11 26 -23 13z"/>
|
||||
<path d="M1290 3651 c-5 -11 -10 -46 -10 -78 0 -33 -5 -64 -12 -71 -8 -8 -8
|
||||
-15 0 -25 15 -18 18 -197 4 -223 -7 -14 -7 -25 0 -39 15 -25 12 -214 -3 -231
|
||||
-9 -10 -9 -18 0 -27 14 -18 17 -197 3 -223 -7 -14 -7 -25 0 -38 14 -25 11
|
||||
-205 -3 -223 -9 -9 -9 -17 0 -26 14 -18 17 -197 3 -223 -7 -13 -7 -25 0 -37 8
|
||||
-15 8 -51 -2 -152 0 -5 3 -28 8 -50 4 -22 4 -58 0 -80 -10 -49 -10 -51 -1 -99
|
||||
5 -22 15 -42 23 -44 13 -4 13 -3 2 11 -16 19 -18 143 -3 161 7 9 7 16 0 23
|
||||
-15 15 -13 144 3 155 10 6 10 10 1 16 -11 7 -16 45 -14 115 1 30 5 37 21 37
|
||||
19 0 20 1 5 24 -13 19 -16 53 -16 155 0 72 5 139 10 150 14 26 14 31 -3 31
|
||||
-15 0 -23 50 -18 113 3 29 7 37 23 37 18 0 18 1 4 24 -20 30 -23 272 -5 307 9
|
||||
16 8 23 -4 32 -14 12 -19 44 -17 120 1 30 5 37 21 37 19 0 20 1 5 24 -13 19
|
||||
-16 53 -16 155 0 72 5 139 10 150 14 24 14 31 1 31 -5 0 -14 -9 -20 -19z"/>
|
||||
<path d="M1387 3663 c-4 -3 -7 -431 -7 -950 l0 -943 360 0 360 0 0 950 0 950
|
||||
-353 0 c-195 0 -357 -3 -360 -7z m83 -88 l0 -75 -35 0 -35 0 0 75 0 75 35 0
|
||||
35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0
|
||||
-75 -40 0 -40 0 0 75 0 75 40 0 40 0 0 -75z m80 0 l0 -75 -35 0 -35 0 0 75 0
|
||||
75 35 0 35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90
|
||||
0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0
|
||||
75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -40 0 -40 0 0 75 0 75 40 0 40 0 0 -75z
|
||||
m-620 -175 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0
|
||||
-35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40
|
||||
0 0 -80z m80 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80
|
||||
-35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80
|
||||
35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0
|
||||
l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m-620 -170 l0 -80 -35 0 -35 0
|
||||
0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0
|
||||
-80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m80 0 l0 -80 -35 0
|
||||
-35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35
|
||||
0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80
|
||||
-35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80
|
||||
40 0 40 0 0 -80z m-620 -170 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z
|
||||
m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40
|
||||
0 0 80 0 80 40 0 40 0 0 -80z m80 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0
|
||||
-80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0
|
||||
-35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35
|
||||
0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m-620 -170 l0
|
||||
-80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0
|
||||
80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m80
|
||||
0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0
|
||||
80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z
|
||||
m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40
|
||||
0 0 80 0 80 40 0 40 0 0 -80z m-620 -175 l0 -75 -35 0 -35 0 0 75 0 75 35 0
|
||||
35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0
|
||||
-75 -40 0 -40 0 0 75 0 75 40 0 40 0 0 -75z m80 0 l0 -75 -35 0 -35 0 0 75 0
|
||||
75 35 0 35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90
|
||||
0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0
|
||||
75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -40 0 -40 0 0 75 0 75 40 0 40 0 0 -75z
|
||||
m-620 -170 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -35 0
|
||||
-35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -40 0 -40 0 0 75 0 75 40 0 40
|
||||
0 0 -75z m80 0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0 -75
|
||||
-35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0 75 0 75
|
||||
35 0 35 0 0 -75z m90 0 l0 -75 -35 0 -35 0 0 75 0 75 35 0 35 0 0 -75z m90 0
|
||||
l0 -75 -40 0 -40 0 0 75 0 75 40 0 40 0 0 -75z m-620 -175 l0 -80 -35 0 -35 0
|
||||
0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0
|
||||
-80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m80 0 l0 -80 -35 0
|
||||
-35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35
|
||||
0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80
|
||||
-35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80
|
||||
40 0 40 0 0 -80z m-620 -170 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z
|
||||
m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40
|
||||
0 0 80 0 80 40 0 40 0 0 -80z m80 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0
|
||||
-80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0
|
||||
-35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35
|
||||
0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m-620 -170 l0
|
||||
-80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0
|
||||
80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m80
|
||||
0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0
|
||||
80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z
|
||||
m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40
|
||||
0 0 80 0 80 40 0 40 0 0 -80z m-620 -170 l0 -80 -35 0 -35 0 0 80 0 80 35 0
|
||||
35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0
|
||||
-80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z m80 0 l0 -80 -35 0 -35 0 0 80 0
|
||||
80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90
|
||||
0 l0 -80 -35 0 -35 0 0 80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -35 0 -35 0 0
|
||||
80 0 80 35 0 35 0 0 -80z m90 0 l0 -80 -40 0 -40 0 0 80 0 80 40 0 40 0 0 -80z"/>
|
||||
<path d="M1424 3575 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1514 3575 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1597 3604 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1677 3604 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 3604 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1864 3575 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1947 3604 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M2034 3575 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1424 3405 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1507 3434 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1604 3405 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1684 3405 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1774 3405 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1857 3434 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1947 3434 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M2034 3405 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1417 3264 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1514 3235 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1604 3235 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1677 3264 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 3264 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1864 3235 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1947 3264 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M2027 3264 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1424 3065 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1514 3065 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1597 3094 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1677 3094 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 3094 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1864 3065 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1947 3094 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M2034 3065 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1424 2895 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1507 2924 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1604 2895 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1684 2895 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1774 2895 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1857 2924 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1954 2895 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M2027 2924 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1417 2744 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1514 2715 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1604 2715 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1677 2744 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 2744 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1857 2744 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1954 2715 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M2027 2744 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1424 2545 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1514 2545 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1597 2574 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1677 2574 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 2574 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1864 2545 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1947 2574 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M2034 2545 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1424 2375 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1507 2404 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1597 2404 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1677 2404 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 2404 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1857 2404 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1954 2375 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M2027 2404 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1417 2234 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1514 2205 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1604 2205 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1677 2234 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1774 2205 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1864 2205 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1954 2205 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M2034 2205 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1417 2064 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1507 2064 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1597 2064 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1677 2064 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1774 2035 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1857 2064 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1954 2035 c1 -28 5 -35 21 -34 11 0 14 3 8 6 -7 2 -13 18 -13 34 0
|
||||
16 -4 29 -8 29 -5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M2027 2064 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1417 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1507 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1597 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1677 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1767 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1857 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1947 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M2027 1894 c-12 -13 -8 -62 6 -67 23 -9 39 9 35 39 -3 27 -26 43 -41
|
||||
28z m20 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
<path d="M1188 3536 c-10 -7 -18 -19 -18 -26 0 -10 3 -10 15 0 20 16 19 6 -1
|
||||
-25 -16 -25 -16 -25 15 -25 23 0 31 4 30 18 0 10 -3 12 -6 5 -2 -7 -9 -13 -14
|
||||
-13 -5 0 -3 14 6 30 10 19 11 30 5 30 -6 0 -8 5 -5 10 9 14 -7 12 -27 -4z"/>
|
||||
<path d="M1188 3261 c-28 -28 -23 -51 10 -51 26 0 28 2 24 35 -5 39 -9 41 -34
|
||||
16z m9 -33 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z"/>
|
||||
<path d="M1192 3007 c-16 -19 -10 -57 9 -57 11 0 16 10 17 35 1 36 -8 44 -26
|
||||
22z"/>
|
||||
<path d="M1178 2725 c3 -26 9 -35 23 -35 30 0 33 21 6 46 -15 13 -28 24 -30
|
||||
24 -1 0 -1 -16 1 -35z m32 -15 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5
|
||||
10 10 10 6 0 10 -4 10 -10z"/>
|
||||
<path d="M1195 2475 c0 -19 4 -35 10 -35 6 0 10 12 9 28 -2 38 -3 42 -11 42
|
||||
-5 0 -8 -16 -8 -35z"/>
|
||||
<path d="M1187 2224 c-4 -4 -7 -16 -7 -26 0 -13 7 -18 26 -18 21 0 25 4 22 22
|
||||
-3 23 -27 35 -41 22z m20 -26 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1
|
||||
-19z"/>
|
||||
<path d="M612 2074 c4 -3 2 -19 -2 -35 -9 -29 -9 -29 36 -29 28 0 44 4 44 13
|
||||
0 9 3 8 9 -2 7 -11 11 -10 21 5 10 16 11 16 6 2 -3 -12 0 -18 9 -18 21 0 12
|
||||
44 -10 48 -10 2 -21 -2 -26 -10 -7 -11 -9 -11 -9 1 0 8 -7 11 -20 8 -11 -3
|
||||
-27 1 -34 9 -8 8 -18 14 -22 14 -4 0 -5 -3 -2 -6z m59 -47 c-10 -9 -11 -8 -5
|
||||
6 3 10 9 15 12 12 3 -3 0 -11 -7 -18z"/>
|
||||
<path d="M763 2057 c-6 -13 -8 -28 -5 -34 9 -13 112 -17 112 -4 0 6 -8 8 -17
|
||||
5 -17 -5 -17 -5 0 9 25 20 21 25 -18 25 -22 0 -39 -6 -46 -16 -8 -14 -9 -12
|
||||
-6 11 5 33 -6 35 -20 4z"/>
|
||||
<path d="M985 2059 c-6 -17 -9 -19 -16 -8 -6 10 -9 7 -10 -11 l-1 -25 -8 25
|
||||
c-4 14 -9 18 -9 10 -1 -13 -2 -13 -11 0 -9 13 -11 13 -19 1 -5 -8 -7 -20 -4
|
||||
-28 7 -17 63 -17 63 0 0 8 3 8 8 2 13 -20 74 -17 94 4 25 28 23 31 -17 31 -21
|
||||
0 -38 -6 -45 -17 -10 -15 -11 -14 -7 10 5 32 -9 36 -18 6z"/>
|
||||
<path d="M1099 2038 c-14 -27 -13 -28 62 -27 58 1 69 3 65 16 -3 8 -6 18 -6
|
||||
22 0 5 -25 8 -56 7 -41 -1 -58 -5 -65 -18z m51 -2 c0 -3 -4 -8 -10 -11 -5 -3
|
||||
-10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z"/>
|
||||
<path d="M642 1894 c4 -3 2 -19 -2 -35 -8 -26 -6 -29 15 -29 18 0 23 5 22 23
|
||||
-1 22 -19 47 -33 47 -4 0 -5 -3 -2 -6z"/>
|
||||
<path d="M797 1886 c-3 -9 -15 -12 -31 -9 -18 4 -26 1 -26 -8 0 -12 -2 -12 -9
|
||||
0 -12 19 -41 6 -41 -19 0 -13 7 -20 20 -20 11 0 20 6 20 13 0 9 3 8 9 -2 7
|
||||
-11 11 -10 21 5 9 14 10 15 6 2 -4 -14 5 -16 65 -17 38 0 69 4 69 9 0 5 -8 7
|
||||
-17 4 -17 -5 -17 -5 0 9 25 20 21 25 -18 25 -22 0 -39 -6 -46 -16 -8 -14 -9
|
||||
-12 -6 11 4 28 -7 37 -16 13z m-86 -39 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12 3
|
||||
-3 0 -11 -7 -18z"/>
|
||||
<path d="M1102 1878 c-6 -13 -11 -17 -11 -10 -1 6 -10 12 -21 12 -11 0 -20 -6
|
||||
-20 -12 0 -9 -3 -9 -8 -2 -4 5 -26 11 -49 11 -42 2 -59 -12 -43 -37 6 -9 10
|
||||
-8 20 6 10 16 11 16 6 2 -4 -15 1 -18 35 -18 24 0 38 -4 34 -10 -3 -5 1 -10
|
||||
10 -10 9 0 13 5 10 10 -3 6 0 10 9 10 8 0 17 6 19 13 4 10 6 10 6 0 1 -7 14
|
||||
-13 30 -13 16 0 32 6 34 13 4 10 6 10 6 0 1 -7 13 -13 27 -13 20 0 25 4 20 16
|
||||
-3 9 -6 21 -7 27 0 7 -4 3 -9 -8 -7 -16 -9 -17 -9 -3 -1 21 -47 20 -62 -2 -8
|
||||
-12 -10 -9 -6 13 5 33 -6 35 -21 5z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 21 KiB |
39
wyk/01_Jezyk/zdzblo.tex
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
\documentclass{article}
|
||||
\usepackage[a6paper]{geometry}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{bytefield}
|
||||
\thispagestyle{empty}
|
||||
\begin{document}
|
||||
|
||||
\begin{bytefield}{8}
|
||||
\bitheader[endianness=big]{0-7} \\
|
||||
\begin{leftwordgroup}{Ź}
|
||||
\bitboxes{1}{11000101} \\
|
||||
\bitboxes{1}{10111001}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{d}
|
||||
\bitboxes{1}{01100100}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{ź}
|
||||
\bitboxes{1}{11000101} \\
|
||||
\bitboxes{1}{10111010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{b}
|
||||
\bitboxes{1}{01100010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{ł}
|
||||
\bitboxes{1}{11000101} \\
|
||||
\bitboxes{1}{10000010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{o}
|
||||
\bitboxes{1}{01101111}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{\textit{koniec wiersza}}
|
||||
\bitboxes{1}{00001010}
|
||||
\end{leftwordgroup} \\
|
||||
\begin{leftwordgroup}{\textit{koniec napisu}}
|
||||
\bitboxes{1}{00000000}
|
||||
\end{leftwordgroup}
|
||||
\end{bytefield}
|
||||
\end{document}
|
533
wyk/02_Jezyki.ipynb
Normal file
270
wyk/02_Jezyki.org
Normal file
@ -0,0 +1,270 @@
|
||||
* Języki i ich prawa statystyczne
|
||||
|
||||
Jakim rozkładom statystycznym podlegają języki?
|
||||
|
||||
** Język naturalny albo „Pan Tadeusz” w liczbach
|
||||
|
||||
Przygotujmy najpierw „infrastrukturę” do /segmentacji/ tekstu na różnego rodzaju jednostki.
|
||||
Używać będziemy generatorów.
|
||||
|
||||
*Pytanie* Dlaczego generatory zamiast list?
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
import requests
|
||||
|
||||
url = 'https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt'
|
||||
pan_tadeusz = requests.get(url).content.decode('utf-8')
|
||||
|
||||
pan_tadeusz[100:150]
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
Księga pierwsza
|
||||
|
||||
|
||||
|
||||
Gospodarstwo
|
||||
|
||||
Powrót pani
|
||||
:end:
|
||||
|
||||
*** Znaki
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
from itertools import islice
|
||||
|
||||
def get_characters(t):
|
||||
yield from t
|
||||
|
||||
list(islice(get_characters(pan_tadeusz), 100, 150))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
['K', 's', 'i', 'ę', 'g', 'a', ' ', 'p', 'i', 'e', 'r', 'w', 's', 'z', 'a', '\r', '\n', '\r', '\n', '\r', '\n', '\r', '\n', 'G', 'o', 's', 'p', 'o', 'd', 'a', 'r', 's', 't', 'w', 'o', '\r', '\n', '\r', '\n', 'P', 'o', 'w', 'r', 'ó', 't', ' ', 'p', 'a', 'n', 'i']
|
||||
:end:
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
from collections import Counter
|
||||
|
||||
c = Counter(get_characters(pan_tadeusz))
|
||||
|
||||
c
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
Counter({' ': 63444, 'a': 30979, 'i': 29353, 'e': 25343, 'o': 23050, 'z': 22741, 'n': 15505, 'r': 15328, 's': 15255, 'w': 14625, 'c': 14153, 'y': 13732, 'k': 12362, 'd': 11465, '\r': 10851, '\n': 10851, 't': 10757, 'm': 10269, 'ł': 10059, ',': 9130, 'p': 8031, 'u': 7699, 'l': 6677, 'j': 6586, 'b': 5753, 'ę': 5534, 'ą': 4794, 'g': 4775, 'h': 3915, 'ż': 3334, 'ó': 3097, 'ś': 2524, '.': 2380, 'ć': 1956, ';': 1445, 'P': 1265, 'W': 1258, ':': 1152, '!': 1083, 'S': 1045, 'T': 971, 'I': 795, 'N': 793, 'Z': 785, 'J': 729, '—': 720, 'A': 698, 'K': 683, 'ń': 651, 'M': 585, 'B': 567, 'O': 567, 'C': 556, 'D': 552, '«': 540, '»': 538, 'R': 489, '?': 441, 'ź': 414, 'f': 386, 'G': 358, 'L': 316, 'H': 309, 'Ż': 219, 'U': 184, '…': 157, '*': 150, '(': 76, ')': 76, 'Ś': 71, 'F': 47, 'é': 43, '-': 33, 'Ł': 24, 'E': 23, '/': 19, 'Ó': 13, '8': 10, '9': 8, '2': 6, 'v': 5, 'Ź': 4, '1': 4, '3': 3, 'x': 3, 'V': 3, '7': 2, '4': 2, '5': 2, 'q': 2, 'æ': 2, 'à': 1, 'Ć': 1, '6': 1, '0': 1})
|
||||
:end:
|
||||
|
||||
Napiszmy pomocniczą funkcję, która zwraca *listę frekwencyjną*.
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
Counter({' ': 63444, 'a': 30979, 'i': 29353, 'e': 25343, 'o': 23050, 'z': 22741, 'n': 15505, 'r': 15328, 's': 15255, 'w': 14625, 'c': 14153, 'y': 13732, 'k': 12362, 'd': 11465, '\r': 10851, '\n': 10851, 't': 10757, 'm': 10269, 'ł': 10059, ',': 9130, 'p': 8031, 'u': 7699, 'l': 6677, 'j': 6586, 'b': 5753, 'ę': 5534, 'ą': 4794, 'g': 4775, 'h': 3915, 'ż': 3334, 'ó': 3097, 'ś': 2524, '.': 2380, 'ć': 1956, ';': 1445, 'P': 1265, 'W': 1258, ':': 1152, '!': 1083, 'S': 1045, 'T': 971, 'I': 795, 'N': 793, 'Z': 785, 'J': 729, '—': 720, 'A': 698, 'K': 683, 'ń': 651, 'M': 585, 'B': 567, 'O': 567, 'C': 556, 'D': 552, '«': 540, '»': 538, 'R': 489, '?': 441, 'ź': 414, 'f': 386, 'G': 358, 'L': 316, 'H': 309, 'Ż': 219, 'U': 184, '…': 157, '*': 150, '(': 76, ')': 76, 'Ś': 71, 'F': 47, 'é': 43, '-': 33, 'Ł': 24, 'E': 23, '/': 19, 'Ó': 13, '8': 10, '9': 8, '2': 6, 'v': 5, 'Ź': 4, '1': 4, '3': 3, 'x': 3, 'V': 3, '7': 2, '4': 2, '5': 2, 'q': 2, 'æ': 2, 'à': 1, 'Ć': 1, '6': 1, '0': 1})
|
||||
:end:
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
from collections import Counter
|
||||
from collections import OrderedDict
|
||||
|
||||
def freq_list(g, top=None):
|
||||
c = Counter(g)
|
||||
|
||||
if top is None:
|
||||
items = c.items()
|
||||
else:
|
||||
items = c.most_common(top)
|
||||
|
||||
return OrderedDict(sorted(items, key=lambda t: -t[1]))
|
||||
|
||||
freq_list(get_characters(pan_tadeusz), top=8)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
OrderedDict([(' ', 63444), ('a', 30979), ('i', 29353), ('e', 25343), ('o', 23050), ('z', 22741), ('n', 15505), ('r', 15328)])
|
||||
:end:
|
||||
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from collections import OrderedDict
|
||||
|
||||
def rang_freq_with_labels(name, g, top=None):
|
||||
freq = freq_list(g, top)
|
||||
|
||||
plt.figure(figsize=(12, 3))
|
||||
plt.ylabel('liczba wystąpień')
|
||||
|
||||
plt.bar(freq.keys(), freq.values())
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
rang_freq_with_labels('pt-chars', get_characters(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-chars.png]]
|
||||
|
||||
*** Słowa
|
||||
|
||||
Co rozumiemy pod pojęciem słowa czy wyrazu, nie jest oczywiste. W praktyce zależy to od wyboru *tokenizatora*.
|
||||
|
||||
Załóżmy, że przez wyraz rozumieć będziemy nieprzerwany ciąg liter bądź cyfr (oraz gwiazdek
|
||||
— to za chwilę ułatwi nam analizę pewnego tekstu…).
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :exports both :results raw drawer
|
||||
from itertools import islice
|
||||
import regex as re
|
||||
|
||||
def get_words(t):
|
||||
for m in re.finditer(r'[\p{L}0-9\*]+', t):
|
||||
yield m.group(0)
|
||||
|
||||
list(islice(get_words(pan_tadeusz), 100, 130))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
:results:
|
||||
['Ty', 'co', 'gród', 'zamkowy', 'Nowogródzki', 'ochraniasz', 'z', 'jego', 'wiernym', 'ludem', 'Jak', 'mnie', 'dziecko', 'do', 'zdrowia', 'powróciłaś', 'cudem', 'Gdy', 'od', 'płaczącej', 'matki', 'pod', 'Twoją', 'opiekę', 'Ofiarowany', 'martwą', 'podniosłem', 'powiekę', 'I', 'zaraz']
|
||||
:end:
|
||||
|
||||
Zobaczmy 20 najczęstszych wyrazów.
|
||||
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :results file
|
||||
rang_freq_with_labels('pt-words-20', get_words(pan_tadeusz), top=20)
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words-20.png]]
|
||||
|
||||
Zobaczmy pełny obraz, już bez etykiet.
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
|
||||
def rang_freq(name, g):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.plot(range(1, len(freq.values())+1), freq.values())
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
rang_freq('pt-words', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words.png]]
|
||||
|
||||
Widać, jak różne skale obejmuje ten wykres. Zastosujemy logarytm,
|
||||
najpierw tylko do współrzędnej $y$.
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
|
||||
def rang_log_freq(name, g):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.plot(range(1, len(freq.values())+1), [log(y) for y in freq.values()])
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
rang_log_freq('pt-words-log', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words-log.png]]
|
||||
|
||||
**Pytanie** Dlaczego widzimy coraz dłuższe „schodki”?
|
||||
|
||||
*** Hapax legomena
|
||||
|
||||
Z poprzedniego wykresu możemy odczytać, że ok. 2/3 wyrazów wystąpiło
|
||||
dokładnie 1 raz. Słowa występujące jeden raz w danym korpusie noszą
|
||||
nazwę /hapax legomena/ (w liczbie pojedynczej /hapax legomenon/, ἅπαξ
|
||||
λεγόμενον, „raz powiedziane”, żargonowo: „hapaks”).
|
||||
|
||||
„Prawdziwe” hapax legomena, słowa, które wystąpiły tylko raz w /całym/
|
||||
korpusie tekstów danego języka (np. starożytnego) rzecz jasna
|
||||
sprawiają olbrzymie trudności w tłumaczeniu. Przykładem jest greckie
|
||||
słowo ἐπιούσιος, przydawka odnosząca się do chleba w modlitwie „Ojcze
|
||||
nasz”. Jest to jedyne poświadczenie tego słowa w całym znanym korpusie
|
||||
greki (nie tylko z Pisma Świętego). W języku polskim tłumaczymy je na
|
||||
„powszedni”, ale na przykład w rosyjskim przyjął się odpowiednik
|
||||
„насущный” — o przeciwstawnym do polskiego znaczeniu!
|
||||
|
||||
W sumie podobne problemy hapaksy mogą sprawiać metodom statystycznym
|
||||
przy przetwarzaniu jakiekolwiek korpusu.
|
||||
|
||||
*** Wykres log-log
|
||||
|
||||
Jeśli wspomniany wcześniej wykres narysujemy używając skali
|
||||
logarytmicznej dla **obu** osi, otrzymamy kształt zbliżony do linii prostej.
|
||||
|
||||
Tę własność tekstów nazywamy **prawem Zipfa**.
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :results file
|
||||
import matplotlib.pyplot as plt
|
||||
from math import log
|
||||
|
||||
def log_rang_log_freq(name, g):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.plot([log(x) for x in range(1, len(freq.values())+1)], [log(y) for y in freq.values()])
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
log_rang_log_freq('pt-words-log-log', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-words-log-log.png]]
|
||||
|
||||
*** Związek między frekwencją a długością
|
||||
|
||||
Powiązane z prawem Zipfa prawo językowe opisuje zależność między
|
||||
częstością użycia słowa a jego długością. Generalnie im krótsze słowo, tym częstsze.
|
||||
|
||||
#+BEGIN_SRC ipython :session mysession :results file
|
||||
def freq_vs_length(name, g, top=None):
|
||||
freq = freq_list(g)
|
||||
|
||||
plt.figure().clear()
|
||||
plt.scatter([len(x) for x in freq.keys()], [log(y) for y in freq.values()],
|
||||
facecolors='none', edgecolors='r')
|
||||
|
||||
fname = f'02_Jezyki/{name}.png'
|
||||
|
||||
plt.savefig(fname)
|
||||
|
||||
return fname
|
||||
|
||||
freq_vs_length('pt-lengths', get_words(pan_tadeusz))
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
[[file:02_Jezyki/pt-lengths.png]]
|
BIN
wyk/02_Jezyki/pt-chars.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
wyk/02_Jezyki/pt-lengths.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
wyk/02_Jezyki/pt-words-20.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
wyk/02_Jezyki/pt-words-log-log.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
wyk/02_Jezyki/pt-words-log.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
wyk/02_Jezyki/pt-words.png
Normal file
After Width: | Height: | Size: 12 KiB |
5
wyk/helpers/add-intro.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
./helpers/fix-intro.pl $1
|
||||
|
||||
perl -pne 's/^{"cells":\[//' $1 | cat helpers/intro - | sponge $1
|
61
wyk/helpers/fix-intro.pl
Executable file
@ -0,0 +1,61 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
|
||||
binmode(STDERR, ':utf8');
|
||||
|
||||
my $intro_file = 'helpers/intro';
|
||||
my $intro_template = 'helpers/intro-template';
|
||||
|
||||
my $notebook_file = $ARGV[0];
|
||||
|
||||
my $number;
|
||||
|
||||
if (($number) = ($notebook_file =~ m{^(\d+)_})) {
|
||||
|
||||
} else {
|
||||
die "????";
|
||||
}
|
||||
|
||||
my $org_file = $notebook_file;
|
||||
$org_file =~ s{\.ipynb}{\.org};
|
||||
|
||||
my $title = undef;
|
||||
|
||||
open(my $org_fh, '<', $org_file);
|
||||
binmode($org_fh, ':utf8');
|
||||
|
||||
LOOP:
|
||||
while (my $line=<$org_fh>) {
|
||||
chomp $line;
|
||||
|
||||
if ($line =~ m{^\* (.*)}) {
|
||||
$title = $1;
|
||||
last LOOP;
|
||||
} elsif ($line =~ /\S/) {
|
||||
last LOOP;
|
||||
}
|
||||
}
|
||||
|
||||
if (not defined($title)) {
|
||||
die '???? TITLE';
|
||||
}
|
||||
|
||||
print STDERR "NUMBER: $number\n";
|
||||
print STDERR "TITLE: $title\n";
|
||||
|
||||
my $intro = '';
|
||||
|
||||
open(my $intro_ih, '<', $intro_template);
|
||||
binmode($intro_ih, ':utf8');
|
||||
while(my $line=<$intro_ih>) {
|
||||
$line =~ s{NUMBER}{$number};
|
||||
$line =~ s{TITLE}{$title};
|
||||
$intro .= $line;
|
||||
}
|
||||
close($intro_ih);
|
||||
|
||||
open(my $intro_oh, '>', $intro_file);
|
||||
binmode($intro_oh, ':utf8');
|
||||
print $intro_oh $intro;
|
||||
close($intro_oh);
|
18
wyk/helpers/intro
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
{
|
||||
"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> 02. <i>Języki i ich prawa statystyczne</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"
|
||||
]
|
||||
},
|
18
wyk/helpers/intro-template
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
{
|
||||
"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> NUMBER. <i>TITLE</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"
|
||||
]
|
||||
},
|