From 0c0ef36a89781aaa56aeb1acece26841594b4588 Mon Sep 17 00:00:00 2001 From: Adam Stelmaszyk Date: Sat, 22 Jun 2024 12:05:36 +0200 Subject: [PATCH] new code --- lab/lab_12.ipynb | 222 ++++++++++++++++++++++++++++++++++++++++---- lab/lab_13-14.ipynb | 113 +++++++++++++++++++--- 2 files changed, 304 insertions(+), 31 deletions(-) diff --git a/lab/lab_12.ipynb b/lab/lab_12.ipynb index c4dc223..daf3488 100644 --- a/lab/lab_12.ipynb +++ b/lab/lab_12.ipynb @@ -65,19 +65,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "broken-workstation", "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[6], line 10\u001b[0m\n\u001b[1;32m 6\u001b[0m f\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mdatetime\u001b[38;5;241m.\u001b[39mnow()\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m - \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mkey\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 8\u001b[0m keyboard\u001b[38;5;241m.\u001b[39mon_press(log_key)\n\u001b[0;32m---> 10\u001b[0m \u001b[43mkeyboard\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m/opt/homebrew/lib/python3.11/site-packages/keyboard/__init__.py:886\u001b[0m, in \u001b[0;36mwait\u001b[0;34m(hotkey, suppress, trigger_on_release)\u001b[0m\n\u001b[1;32m 884\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 885\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m--> 886\u001b[0m \u001b[43m_time\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m1e6\u001b[39;49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], "source": [ "import keyboard\n", + "from datetime import datetime\n", "\n", + "def log_key(key):\n", + " with open(\"txt/keylog.txt\", \"a\") as f:\n", + " f.write(f\"{datetime.now()} - {key.name}\\n\")\n", "\n", - "def report_key(event):\n", - " print(event)\n", + "keyboard.on_press(log_key)\n", "\n", - "keyboard.on_release(callback=report_key)\n", - "keyboard.wait()" + "keyboard.wait()\n" ] }, { @@ -96,6 +111,36 @@ "### Ćwiczenie 1: Wykorzystując powyższy kod napisz keylogger, który zapisuje wszystkie uderzenia w klawisze do pliku. Format pliku jest dowolny, każdy wpis musi zawierać precyzyjną godzinę uderzenia oraz uderzony klawisz. Uruchom program i przepisz paragraf dowolnie wybranego tekstu." ] }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e1fd5d69", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + ".remove_()>" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import keyboard\n", + "import time\n", + "\n", + "def log_keystroke(event):\n", + " with open(\"txt/keystroke_log.txt\", \"a\") as log_file:\n", + " log_time = time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime())\n", + " log_file.write(f\"{log_time} - {event.name}\\n\")\n", + "\n", + "keyboard.on_press(log_keystroke)\n", + "keyboard.wait()" + ] + }, { "cell_type": "markdown", "id": "valuable-bearing", @@ -117,12 +162,76 @@ "execution_count": 1, "id": "possible-holder", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This process is not trusted! Input event monitoring will not be possible until it is added to accessibility clients.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rozpocznij pisanie. Naciśnij 'esc' aby zakończyć i zobaczyć wyniki.\n", + "Średnia prędkość pisania: 733.09 znaków na minutę\n", + "Średnia prędkość pisania: 146.62 słów na minutę\n" + ] + } + ], "source": [ - "def calculate_typing_speed():\n", - " return 0" + "from pynput import keyboard\n", + "from datetime import datetime, timedelta\n", + "\n", + "key_times = []\n", + "last_time = None\n", + "\n", + "def on_press(key):\n", + " global last_time\n", + " current_time = datetime.now()\n", + " \n", + " if last_time and (current_time - last_time) > timedelta(seconds=5):\n", + " key_times.clear()\n", + " \n", + " key_times.append(current_time)\n", + " last_time = current_time\n", + "\n", + "def calculate_speed():\n", + " if len(key_times) < 2:\n", + " print(\"Zbyt mało danych do obliczenia prędkości pisania.\")\n", + " return\n", + " \n", + " total_time = (key_times[-1] - key_times[0]).total_seconds() / 60\n", + " \n", + " num_chars = len(key_times)\n", + " num_words = num_chars / 5\n", + " \n", + " chars_per_minute = num_chars / total_time\n", + " words_per_minute = num_words / total_time\n", + " \n", + " print(f\"Średnia prędkość pisania: {chars_per_minute:.2f} znaków na minutę\")\n", + " print(f\"Średnia prędkość pisania: {words_per_minute:.2f} słów na minutę\")\n", + "\n", + "def on_release(key):\n", + " if key == keyboard.Key.esc:\n", + " calculate_speed()\n", + " return False\n", + "\n", + "with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:\n", + " print(\"Rozpocznij pisanie. Naciśnij 'esc' aby zakończyć i zobaczyć wyniki.\")\n", + " listener.join()\n", + "\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "03ba2685", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "id": "ceramic-birth", @@ -141,28 +250,100 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 7, "id": "close-riverside", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "This process is not trusted! Input event monitoring will not be possible until it is added to accessibility clients.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Rozpocznij pisanie. Naciśnij 'esc' aby zakończyć i zobaczyć wyniki.\n", + "Przerwa: 3.82 sekund\n", + "Kontekst przed przerwą: ...fsdjfdnsjfjdnfjdfnj[Key.esc]\n", + "Kontekst po przerwie: ...\n", + "\n" + ] + } + ], "source": [ - "def find_pauses():\n", - " return []" + "from pynput import keyboard\n", + "from datetime import datetime, timedelta\n", + "\n", + "key_times = []\n", + "key_text = []\n", + "last_time = None\n", + "breaks = []\n", + "\n", + "def key_to_string(key):\n", + " try:\n", + " return key.char\n", + " except AttributeError:\n", + " if key == keyboard.Key.space:\n", + " return ' '\n", + " return f'[{str(key)}]'\n", + "\n", + "def on_press(key):\n", + " global last_time\n", + " current_time = datetime.now()\n", + " \n", + " key_times.append(current_time)\n", + " key_text.append(key_to_string(key))\n", + " \n", + " if last_time and (current_time - last_time) > timedelta(seconds=3):\n", + " context_start = max(0, len(key_text) - 20)\n", + " context_end = len(key_text)\n", + " context_before = ''.join(key_text[context_start:context_end])\n", + " \n", + " context_start = len(key_text)\n", + " context_end = min(len(key_text) + 20, len(key_text))\n", + " context_after = ''.join(key_text[context_start:context_end])\n", + " \n", + " breaks.append((current_time - last_time, context_before, context_after))\n", + " \n", + " last_time = current_time\n", + "\n", + "def report_breaks():\n", + " if not breaks:\n", + " print(\"Nie wykryto przerw dłuższych niż 3 sekundy.\")\n", + " return\n", + " \n", + " breaks.sort(reverse=True, key=lambda x: x[0])\n", + " \n", + " for duration, context_before, context_after in breaks:\n", + " print(f\"Przerwa: {duration.total_seconds():.2f} sekund\")\n", + " print(f\"Kontekst przed przerwą: ...{context_before}\")\n", + " print(f\"Kontekst po przerwie: {context_after}...\")\n", + " print()\n", + "\n", + "def on_release(key):\n", + " if key == keyboard.Key.esc:\n", + " report_breaks()\n", + " return False\n", + "\n", + "with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:\n", + " print(\"Rozpocznij pisanie. Naciśnij 'esc' aby zakończyć i zobaczyć wyniki.\")\n", + " listener.join()\n", + "\n" ] } ], "metadata": { "author": "Rafał Jaworski", "email": "rjawor@amu.edu.pl", - "lang": "pl", - "subtitle": "12. Key logging", - "title": "Komputerowe wspomaganie tłumaczenia", - "year": "2021", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, + "lang": "pl", "language_info": { "codemirror_mode": { "name": "ipython", @@ -173,8 +354,11 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" - } + "version": "3.11.9" + }, + "subtitle": "12. Key logging", + "title": "Komputerowe wspomaganie tłumaczenia", + "year": "2021" }, "nbformat": 4, "nbformat_minor": 5 diff --git a/lab/lab_13-14.ipynb b/lab/lab_13-14.ipynb index 740d7d9..2f36111 100644 --- a/lab/lab_13-14.ipynb +++ b/lab/lab_13-14.ipynb @@ -44,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "familiar-terrace", "metadata": { "scrolled": true @@ -91,6 +91,14 @@ " print(line.rstrip())" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "bee601d9", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "id": "dominant-insurance", @@ -120,13 +128,41 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "economic-southeast", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[('auto', 1)]\n", + "[('adam', 1), ('jest', 1), ('fajny', 1)]\n", + "[('brak', 1), ('słów', 1)]\n", + "[('chrzaszcz', 0)]\n" + ] + } + ], "source": [ - "def correct_text(text):\n", - " return []" + "from zipfile import ZipFile\n", + "\n", + "dictionary = set\n", + "\n", + "with ZipFile('data/hunspell_pl.zip') as zip_f:\n", + " with zip_f.open('hunspell_pl.txt') as f:\n", + " dictionary = set([line.strip().lower() for line in f.read().decode('utf-8').splitlines()])\n", + "\n", + "def correct_text(phrase):\n", + " return [(word, 1) if word in dictionary\n", + " else (word, 0)\n", + " for word in phrase.lower().split()]\n", + "\n", + "# 0 - źle\n", + "# 1 - dobrze\n", + "print(correct_text('Auto'))\n", + "print(correct_text('Adam jest fajny'))\n", + "print(correct_text('Brak słów'))\n", + "print(correct_text('Chrzaszcz'))" ] }, { @@ -168,13 +204,34 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "id": "built-sally", "metadata": {}, "outputs": [], "source": [ - "def L1(w):\n", - " return []" + "import numpy as np\n", + "\n", + "def levenshtein_distance(a, b):\n", + " n, m = len(a), len(b)\n", + " if n > m:\n", + " a, b = b, a\n", + " n, m = m, n\n", + "\n", + " current_row = np.arange(n + 1)\n", + " for i in range(1, m + 1):\n", + " previous_row, current_row = current_row, np.zeros(n + 1, dtype=int)\n", + " current_row[0] = i\n", + " for j in range(1, n + 1):\n", + " insertions = previous_row[j] + 1\n", + " deletions = current_row[j - 1] + 1\n", + " substitutions = previous_row[j - 1] + (a[j - 1] != b[i - 1])\n", + " current_row[j] = min(insertions, deletions, substitutions)\n", + "\n", + " return current_row[n]\n", + "\n", + "\n", + "def L1(word, dictionary, max_distance=1):\n", + " return [dict_word for dict_word in dictionary if levenshtein_distance(word, dict_word) <= max_distance]" ] }, { @@ -187,13 +244,45 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "coordinated-cooperation", "metadata": {}, "outputs": [], "source": [ - "def generate_suggestions(w):\n", - " return []" + "def generate_suggestions(word, dictionary):\n", + " return L1(word, dictionary)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "0c7843bb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['ato', 'alto', 'huto', 'luto', 'autko', 'autor', 'auto', 'aut']\n", + "['adams', 'adm', 'dam', 'ada', 'edam', 'adad', 'adym', 'asam', 'adaś', 'adat', 'aram', 'adam']\n", + "['fajny', 'fajno', 'tajny', 'farny']\n", + "[]\n" + ] + } + ], + "source": [ + "from zipfile import ZipFile\n", + "\n", + "dictionary = set\n", + "\n", + "with ZipFile('data/hunspell_pl.zip') as zip_f:\n", + " with zip_f.open('hunspell_pl.txt') as f:\n", + " dictionary = set([line.strip().lower() for line in f.read().decode('utf-8').splitlines()])\n", + " \n", + "print(generate_suggestions('auto', dictionary))\n", + "print(generate_suggestions('adam', dictionary))\n", + "print(generate_suggestions('fajny', dictionary))\n", + "print(generate_suggestions('chrzazszcz', dictionary))" ] } ], @@ -216,7 +305,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.10" + "version": "3.11.9" }, "subtitle": "13,14. Korekta pisowni", "title": "Komputerowe wspomaganie tłumaczenia",