diff --git a/lab/lab_11.ipynb b/lab/lab_11.ipynb
index 0a8ce14..ae05990 100644
--- a/lab/lab_11.ipynb
+++ b/lab/lab_11.ipynb
@@ -1,214 +1,423 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "expanded-entrance",
- "metadata": {},
- "source": [
- "# Komputerowe wspomaganie tłumaczenia"
- ]
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "expanded-entrance",
+ "metadata": {
+ "id": "expanded-entrance"
+ },
+ "source": [
+ "# Komputerowe wspomaganie tłumaczenia"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "atlantic-greenhouse",
+ "metadata": {
+ "id": "atlantic-greenhouse"
+ },
+ "source": [
+ "# Zajęcia 11 - urównoleglanie"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "hungarian-davis",
+ "metadata": {
+ "id": "hungarian-davis"
+ },
+ "source": [
+ "Na poprzednich zajęciach poznaliśmy techniki pozyskiwania tekstu z Internetu. Jeśli uda nam się w ten sposób pozyskać tekst w jednym języku oraz jego tłumaczenie na inny język, jesteśmy tylko o krok od uzyskania najbardziej przydatnego zasobu z punktu widzenia wspomagania tłumaczenia - pamięci tłumaczeń. Krokiem tym jest automatyczne urównoleglanie tekstu."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bronze-removal",
+ "metadata": {
+ "id": "bronze-removal"
+ },
+ "source": [
+ "Automatyczne urównoleglanie tekstu składa się z dwóch kroków:\n",
+ "1. Podziału tekstu źródłowego oraz docelowego na zdania.\n",
+ "2. Dopasowaniu zdań źródłowych do docelowych."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "junior-works",
+ "metadata": {
+ "id": "junior-works"
+ },
+ "source": [
+ "Zdania, o których mowa w punkcie 1., powinniśmy rozumieć jako segmenty, tj. niekoniecznie kompletne zdania w sensie gramatycznym. Standardowym sposobem podziału tekstu na segmenty jest dzielenie po znaku nowej linii lub zaraz po kropce, o ile jest ona częścią sekwencji: \".[spacja][Wielka litera]\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "legitimate-corrections",
+ "metadata": {
+ "id": "legitimate-corrections"
+ },
+ "source": [
+ "### Ćwiczenie 1: Zaimplementuj podstawowy algorytm segmentacji tekstu. Użyj odpowiedniego wyrażenia regularnego, łapiącego wielkie litery w dowolnym języku, np. \"Ż\" (użyj klasy unikodowej). Zwróć listę segmentów."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "german-dispute",
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "german-dispute",
+ "outputId": "740c001c-1646-4464-9314-b0327fe927f7"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "['To', 'Jest', 'Przykładowy', 'Ź', 'Ź', 'Ź', 'Tekst', 'Wielkimi', 'Literami', 'Na', 'Początku', 'Segmentów', 'Ź', 'Ź', 'Ź']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import regex as re\n",
+ "\n",
+ "def sentence_split(text):\n",
+ " pattern = r'(?\n",
+ "\n",
+ " \n",
+ " \n",
+ " \n",
+ " sample\n",
+ " KWT\n",
+ " KWT\n",
+ " 123\n",
+ " sample XLIFF file\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " Hola mundo!\n",
+ " \n",
+ " \n",
+ " \n",
+ " Archivo\n",
+ " \n",
+ " \n",
+ " \n",
+ " Nuevo\n",
+ " \n",
+ " \n",
+ " \n",
+ " Salir\n",
+ " \n",
+ " \n",
+ " \n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "import requests\n",
+ "from bs4 import BeautifulSoup\n",
+ "\n",
+ "\n",
+ "def create_hunaligna_file(text_en, text_pl, output_file):\n",
+ " sentences_en = text_en.split('. ')\n",
+ " sentences_pl = text_pl.split('. ')\n",
+ "\n",
+ " with open(output_file, \"w\", encoding=\"utf-8\") as f:\n",
+ " f.write(\"# Sentence pairs\\n\")\n",
+ " for i, (en, pl) in enumerate(zip(sentences_en, sentences_pl)):\n",
+ " f.write(f\"{i}\\n\")\n",
+ " f.write(\"# Source\\n\")\n",
+ " f.write(f\"{en.strip()}\\n\")\n",
+ " f.write(\"# Target\\n\")\n",
+ " f.write(f\"{pl.strip()}\\n\")\n",
+ "\n",
+ "def main():\n",
+ " url_en = \"https://en.wikipedia.org/wiki/Main_Page\"\n",
+ " url_pl = \"https://pl.wikipedia.org/wiki/Strona_g%C5%82%C3%B3wna\"\n",
+ "\n",
+ " text_en = get_page_text(url_pl)\n",
+ " text_pl = get_page_text(url_en)\n",
+ "\n",
+ " with open(\"english.txt\", \"w\", encoding=\"utf-8\") as f_en:\n",
+ " f_en.write(text_en)\n",
+ "\n",
+ " with open(\"polish.txt\", \"w\", encoding=\"utf-8\") as f_pl:\n",
+ " f_pl.write(text_pl)\n",
+ "\n",
+ " create_hunaligna_file(text_en, text_pl, \"hunaligna.txt\")\n",
+ "\n",
+ " print(\"Texts have been saved to 'english.txt' and 'polish.txt'\")\n",
+ " print(\"Hunaligna file has been created as 'hunaligna.txt'\")\n",
+ "\n",
+ "main()"
+ ],
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "yJFtZ0FwksXG",
+ "outputId": "867cfbf2-b2ad-405c-e8d0-19dcdaed82bd"
+ },
+ "id": "yJFtZ0FwksXG",
+ "execution_count": 11,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Texts have been saved to 'english.txt' and 'polish.txt'\n",
+ "Hunaligna file has been created as 'hunaligna.txt'\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "falling-greenhouse",
+ "metadata": {
+ "id": "falling-greenhouse"
+ },
+ "source": [
+ "### Ćwiczenie 4: Napisz konwerter formatu hunaligna na XLIFF."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "remarkable-pillow",
+ "metadata": {
+ "colab": {
+ "base_uri": "https://localhost:8080/"
+ },
+ "id": "remarkable-pillow",
+ "outputId": "59a072b2-79a0-4a57-8b00-cc704f9d1a7b"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "XLIFF file has been created as 'output.xliff'\n"
+ ]
+ }
+ ],
+ "source": [
+ "import xml.etree.ElementTree as ET\n",
+ "\n",
+ "def parse_hunaligna_file(filepath):\n",
+ " segments = []\n",
+ " with open(filepath, 'r', encoding='utf-8') as file:\n",
+ " segment = {}\n",
+ " for line in file:\n",
+ " line = line.strip()\n",
+ " if line.startswith(\"# Source\"):\n",
+ " segment['source'] = next(file).strip()\n",
+ " elif line.startswith(\"# Target\"):\n",
+ " segment['target'] = next(file).strip()\n",
+ " segments.append(segment)\n",
+ " segment = {}\n",
+ " return segments\n",
+ "\n",
+ "def create_xliff(segments, source_lang, target_lang, output_file):\n",
+ " xliff = ET.Element('xliff', version=\"1.2\")\n",
+ " file_elem = ET.SubElement(xliff, 'file', {\n",
+ " 'source-language': source_lang,\n",
+ " 'target-language': target_lang,\n",
+ " 'datatype': \"plaintext\",\n",
+ " 'original': \"file.txt\"\n",
+ " })\n",
+ " body = ET.SubElement(file_elem, 'body')\n",
+ "\n",
+ " for i, segment in enumerate(segments):\n",
+ " trans_unit = ET.SubElement(body, 'trans-unit', id=str(i))\n",
+ " source = ET.SubElement(trans_unit, 'source')\n",
+ " source.text = segment['source']\n",
+ " target = ET.SubElement(trans_unit, 'target')\n",
+ " target.text = segment['target']\n",
+ "\n",
+ " tree = ET.ElementTree(xliff)\n",
+ " tree.write(output_file, encoding='UTF-8', xml_declaration=True)\n",
+ "\n",
+ "def convert2xliff(hunalign_file_name, xliff_file):\n",
+ " source_lang = 'en'\n",
+ " target_lang = 'pl'\n",
+ "\n",
+ " segments = parse_hunaligna_file(hunalign_file_name)\n",
+ " create_xliff(segments, source_lang, target_lang, xliff_file)\n",
+ " print(f\"XLIFF file has been created as '{xliff_file}'\")\n",
+ "\n",
+ "\n",
+ "convert2xliff('hunaligna.txt', 'output.xliff')"
+ ]
+ }
+ ],
+ "metadata": {
+ "author": "Rafał Jaworski",
+ "email": "rjawor@amu.edu.pl",
+ "lang": "pl",
+ "subtitle": "11. Urównoleglanie",
+ "title": "Komputerowe wspomaganie tłumaczenia",
+ "year": "2021",
+ "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.8.10"
+ },
+ "colab": {
+ "provenance": []
+ }
},
- {
- "cell_type": "markdown",
- "id": "atlantic-greenhouse",
- "metadata": {},
- "source": [
- "# Zajęcia 11 - urównoleglanie"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "hungarian-davis",
- "metadata": {},
- "source": [
- "Na poprzednich zajęciach poznaliśmy techniki pozyskiwania tekstu z Internetu. Jeśli uda nam się w ten sposób pozyskać tekst w jednym języku oraz jego tłumaczenie na inny język, jesteśmy tylko o krok od uzyskania najbardziej przydatnego zasobu z punktu widzenia wspomagania tłumaczenia - pamięci tłumaczeń. Krokiem tym jest automatyczne urównoleglanie tekstu."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bronze-removal",
- "metadata": {},
- "source": [
- "Automatyczne urównoleglanie tekstu składa się z dwóch kroków:\n",
- "1. Podziału tekstu źródłowego oraz docelowego na zdania.\n",
- "2. Dopasowaniu zdań źródłowych do docelowych."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "junior-works",
- "metadata": {},
- "source": [
- "Zdania, o których mowa w punkcie 1., powinniśmy rozumieć jako segmenty, tj. niekoniecznie kompletne zdania w sensie gramatycznym. Standardowym sposobem podziału tekstu na segmenty jest dzielenie po znaku nowej linii lub zaraz po kropce, o ile jest ona częścią sekwencji: \".[spacja][Wielka litera]\""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "legitimate-corrections",
- "metadata": {},
- "source": [
- "### Ćwiczenie 1: Zaimplementuj podstawowy algorytm segmentacji tekstu. Użyj odpowiedniego wyrażenia regularnego, łapiącego wielkie litery w dowolnym języku, np. \"Ż\" (użyj klasy unikodowej). Zwróć listę segmentów."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "german-dispute",
- "metadata": {},
- "outputs": [],
- "source": [
- "def sentence_split(text):\n",
- " return []"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "continued-assessment",
- "metadata": {},
- "source": [
- "### Ćwiczenie 2: Uruchom powyższy algorytm na treści wybranej przez siebie strony internetowej (do ściągnięcia treści strony wykorzystaj kod z laboratoriów nr 7). Zidentyfikuj co najmniej dwa wyjątki od ogólnej reguły podziału na segmenty i ulepsz algorytm."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "guilty-morocco",
- "metadata": {},
- "outputs": [],
- "source": [
- "def sentence_split_enhanced(text):\n",
- " return []"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "experimental-recipient",
- "metadata": {},
- "source": [
- "Po podziale tekstu na segmenty po stronie źródłowej oraz docelowej, możemy przystąpić do kroku drugiego - dopasowania segmentów. Głównym wyzwaniem tego kroku jest fakt, iż po stronie źródłowej może być inna liczba segmentów, niż po stronie docelowej. Takie rozbieżności są bardzo częste, a wynikają między innymi z:\n",
- "* tłumaczenia jednego zdania źródłowego przy użyciu więcej niż jednego zdania\n",
- "* tłumaczenia więcej niż jednego zdania źródłowego przy użyciu jednego zdania\n",
- "* pominięcia zdania podczas tłumaczenia\n",
- "* rozbieżności pomiędzy wersjami tekstu źródłowego i docelowego (np. tekst źródłowy mógł być modyfikowany po przetłumaczeniu i tłumaczenie nie zostało zaktualizowane)\n",
- "* przetłumaczenia tekstu źródłowego tylko częściowo"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "australian-hundred",
- "metadata": {},
- "source": [
- "Problemy te rozwiązwyane są na różne sposoby. Najpopularniejszym programem do przeprowadzania urównoleglania jest [Hunalign](https://github.com/danielvarga/hunalign). Wejściem do programu są dwa pliki, zawierające po jednym segmencie w linii. Wyjściem - plik urównoleglony w wewnętrznym formacie hunaligna."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "russian-chambers",
- "metadata": {},
- "source": [
- "### Ćwiczenie 3: Odnajdź dowolną stronę, która jest dostępna w wielu językach. Pobierz z tej strony tekst oryginalny (tylko ze strony głównej) oraz przetłumaczony na dowolny inny język. Przy użyciu Pythona przygotuj pliki dla Hunaligna i uruchom go."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "controlled-pacific",
- "metadata": {},
- "source": [
- "Wyjściem z Hunaligna jest plik w specjalnym formacie Hunaligna. Problem jednak w tym, że niestety nie można go w prosty sposób zaimportować do jakiegokolwiek narzędzia typu CAT. Potrzebna jest konwersja do któregoś z bardziej popularnych formatów, np. XLIFF."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "divided-chain",
- "metadata": {},
- "source": [
- "XLIFF jest formatem do przechowywania pamięci tłumaczeń, który opiera się na XML-u. Przykładowy plik XLIFF wygląda następująco:"
- ]
- },
- {
- "cell_type": "raw",
- "id": "appropriate-timber",
- "metadata": {},
- "source": [
- "\n",
- "\n",
- " \n",
- " \n",
- " \n",
- " sample\n",
- " KWT\n",
- " KWT\n",
- " 123\n",
- " sample XLIFF file\n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " Hola mundo!\n",
- " \n",
- " \n",
- " \n",
- " Archivo\n",
- " \n",
- " \n",
- " \n",
- " Nuevo\n",
- " \n",
- " \n",
- " \n",
- " Salir\n",
- " \n",
- " \n",
- " \n",
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "falling-greenhouse",
- "metadata": {},
- "source": [
- "### Ćwiczenie 4: Napisz konwerter formatu hunaligna na XLIFF."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "remarkable-pillow",
- "metadata": {},
- "outputs": [],
- "source": [
- "def convert2xliff(hunalign_file_name):\n",
- " return 0"
- ]
- }
- ],
- "metadata": {
- "author": "Rafał Jaworski",
- "email": "rjawor@amu.edu.pl",
- "lang": "pl",
- "subtitle": "11. Urównoleglanie",
- "title": "Komputerowe wspomaganie tłumaczenia",
- "year": "2021",
- "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.8.10"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file