{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "continued-dinner",
   "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> Komputerowe wspomaganie tłumaczenia </h1>\n",
    "<h2> 2. <i>Zaawansowane użycie pamięci tłumaczeń</i> [laboratoria]</h2> \n",
    "<h3>Rafał Jaworski (2021)</h3>\n",
    "</div>\n",
    "\n",
    "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "aggregate-listing",
   "metadata": {},
   "source": [
    "Wiemy już, do czego służy pamięć tłumaczeń. Spróbujmy przeprowadzić mały research, którego celem będzie odkrycie, w jaki sposób do pamięci tłumaczeń podchodzą najwięksi producenci oprogramowania typu CAT.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "golden-turkish",
   "metadata": {},
   "source": [
    "### Ćwiczenie 1: Wykonaj analizę funkcjonalności pamięci tłumaczeń w programach SDL Trados Studio 2021 oraz Kilgray memoQ. Dla obu programów wypisz funkcje, które są związane z TM oraz zaznacz, które funkcje są wspólne dla obu programów oraz których funkcji Tradosa brakuje w memoQ oraz odwrotnie."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "retired-burke",
   "metadata": {},
   "source": [
    "Odpowiedź:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "existing-approval",
   "metadata": {},
   "source": [
    "Jedną z funkcji dostępnych we wszystkich większych programach do wspomagania tłumaczenia jest znajdowanie bardzo pewnych dopasowań w pamięci tłumaczeń. Są one zwane **ICE** (In-Context Exact match) lub 101% match. Są to takie dopasowania z pamięci tłumaczeń, dla których nie tylko zdanie źródłowe z TM jest identyczne z tłumaczonym, ale także poprzednie zdanie źródłowe z TM zgadza się z poprzednim zdaniem tłumaczonym oraz następne z TM z następnym tłumaczonym."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "decimal-electricity",
   "metadata": {},
   "source": [
    " Rozważmy przykładową pamięć tłumaczeń z poprzednich zajęć (można do niej dorzucić kilka przykładów):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "confident-prison",
   "metadata": {},
   "outputs": [],
   "source": [
    "translation_memory = [\n",
    "                      ('Wciśnij przycisk Enter', 'Press the ENTER button'), \n",
    "                      ('Sprawdź ustawienia sieciowe', 'Check the network settings'),\n",
    "                      ('Drukarka jest wyłączona', 'The printer is switched off'),\n",
    "                      ('Wymagane ponowne uruchomienie komputera', 'System restart required')\n",
    "                     ]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "informal-breakdown",
   "metadata": {},
   "source": [
    "### Ćwiczenie 2: Zaimplementuj funkcję ice_lookup, przyjmującą trzy parametry: aktualnie tłumaczone zdanie, poprzednio tłumaczone zdanie, następne zdanie do tłumaczenia. Funkcja powinna zwracać dopasowania typu ICE. Nie pozwól, aby doszło do błędów podczas sprawdzania pierwszego i ostatniego przykładu w pamięci (ze względu na brak odpowiednio poprzedzającego oraz następującego przykładu)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "continental-submission",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ice_lookup(sentence, prev_sentence, next_sentence):\n",
    "    return []"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "figured-server",
   "metadata": {},
   "source": [
    "Inną powszechnie stosowaną techniką przeszukiwania pamięci tłumaczeń jest tzw. **fuzzy matching**. Technika ta polega na wyszukiwaniu zdań z pamięci, które są tylko podobne do zdania tłumaczonego. Na poprzednich zajęciach wykonywaliśmy funkcję tm_lookup, która pozwalała na różnicę jednego słowa."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "beautiful-fancy",
   "metadata": {},
   "source": [
    "Zazwyczaj jednak funkcje fuzzy match posiadają znacznie szersze możliwości. Ich działanie opiera się na zdefiniowaniu funkcji $d$ dystansu pomiędzy zdaniami $x$ i $y$. Matematycznie, funkcja dystansu posiada następujące właściwości:\n",
    "1. $\\forall_{x,y} d(x,y)\\geqslant 0$\n",
    "2. $\\forall_{x,y} d(x,y)=0 \\Leftrightarrow x=y$\n",
    "3. $\\forall_{x,y} d(x,y)=d(y,x)$\n",
    "4. $\\forall_{x,y,z} d(x,y) + d(y,z)\\geqslant d(x,z)$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "square-usage",
   "metadata": {},
   "source": [
    "Rozważmy następującą funkcję:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "fourth-pillow",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sentence_distance(x,y):\n",
    "    return abs(len(y) - len(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "mediterranean-cosmetic",
   "metadata": {},
   "source": [
    "### Ćwiczenie 3: Czy to jest poprawna funkcja dystansu? Które warunki spełnia?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "graduate-theorem",
   "metadata": {},
   "source": [
    "Odpowiedź:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "native-amber",
   "metadata": {},
   "source": [
    "A teraz spójrzmy na taką funkcję:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "continued-christopher",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sentence_distance(x,y):\n",
    "    if (x == y):\n",
    "        return 0\n",
    "    else:\n",
    "        return 3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "every-surveillance",
   "metadata": {},
   "source": [
    "### Ćwiczenie 4: Czy to jest poprawna funkcja dystansu? Które warunki spełnia?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "metallic-leave",
   "metadata": {},
   "source": [
    "Odpowiedź:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "executed-baptist",
   "metadata": {},
   "source": [
    "Wprowadźmy jednak inną funkcję dystansu - dystans Levenshteina. Dystans Levenshteina pomiędzy dwoma łańcuchami znaków definiuje się jako minimalną liczbę operacji edycyjnych, które są potrzebne do przekształcenia jednego łańcucha znaków w drugi. Wyróżniamy trzy operacje edycyjne:\n",
    "* dodanie znaku\n",
    "* usunięcie znaku\n",
    "* zamiana znaku na inny"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "square-brown",
   "metadata": {},
   "source": [
    "### Ćwiczenie 5: Czy dystans Levenshteina jest poprawną funkcją dystansu? Uzasadnij krótko swoją odpowiedź sprawdzając każdy z warunków."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bibliographic-stopping",
   "metadata": {},
   "source": [
    "Odpowiedź:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "attended-channels",
   "metadata": {},
   "source": [
    "W Pythonie dostępna jest biblioteka zawierająca implementację dystansu Levenshteina. Zainstaluj ją w swoim systemie przy użyciu polecenia:\n",
    "\n",
    "`pip3 install python-Levenshtein`\n",
    "\n",
    "I wypróbuj:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "secondary-wrist",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from Levenshtein import distance as levenshtein_distance\n",
    "\n",
    "levenshtein_distance(\"kotek\", \"kotki\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "concrete-satellite",
   "metadata": {},
   "source": [
    "Funkcja ta daje nam możliwość zdefiniowania podobieństwa pomiędzy zdaniami:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "associate-tuner",
   "metadata": {},
   "outputs": [],
   "source": [
    "def levenshtein_similarity(x,y):\n",
    "    return 1 - levenshtein_distance(x,y) / max(len(x), len(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "built-michael",
   "metadata": {},
   "source": [
    "Przetestujmy ją!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "focal-pathology",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9166666666666666"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "levenshtein_similarity('Program jest uruchomiony', 'Program jest uruchamiany')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "roman-ceiling",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9428571428571428"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "levenshtein_similarity('Spróbuj wyłączyć i włączyć komputer', 'Spróbuj włączyć i wyłączyć komputer')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "invisible-cambodia",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.631578947368421"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "levenshtein_similarity('Spróbuj wyłączyć i włączyć komputer', 'Nie próbuj wyłączać i włączać drukarki')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "administrative-phoenix",
   "metadata": {},
   "source": [
    "### Ćwiczenie 6: Napisz funkcję fuzzy_lookup, która wyszuka w pamięci tłumaczeń wszystkie zdania, których podobieństwo Levenshteina do zdania wyszukiwanego jest większe lub równe od ustalonego progu."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "genetic-cradle",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fuzzy_lookup(sentence, threshold):\n",
    "    return []"
   ]
  }
 ],
 "metadata": {
  "author": "Rafał Jaworski",
  "email": "rjawor@amu.edu.pl",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "lang": "pl",
  "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"
  },
  "subtitle": "2. Zaawansowane użycie pamięci tłumaczeń",
  "title": "Komputerowe wspomaganie tłumaczenia",
  "year": "2021"
 },
 "nbformat": 4,
 "nbformat_minor": 5
}