{ "cells": [ { "cell_type": "markdown", "id": "virtual-accreditation", "metadata": {}, "source": [ "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "
\n", "

Komputerowe wspomaganie tłumaczenia

\n", "

12. Key logging [laboratoria]

\n", "

Rafał Jaworski (2021)

\n", "
\n", "\n", "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)" ] }, { "cell_type": "markdown", "id": "featured-afghanistan", "metadata": {}, "source": [ "Badania nad komputerowym wspomaganiem tłumaczenia często prowadzone są przy użyciu metodologii testowania interfejsów użytkownika - UI/UX testing. Program typu CAT traktuje się wówczas jak każdy inny program komputerowy i przeprowadza testy wydajności i użyteczności." ] }, { "cell_type": "markdown", "id": "severe-protein", "metadata": {}, "source": [ "Testy takie prowadzone są zawsze na użytkownikach końcowych, w tym przypadku - na tłumaczach. Podstawowym celem testów jest próba zaobserwowania faktycznego sposobu pracy tłumacza - które funkcje programu są przez niego wykorzystywane najczęściej, jakich innych narzędzi poza CAT-em używa on do swojej pracy, które funkcje programu działają zgodnie, a które niezgodnie z intuicją użytkownika oraz wiele innych czynników. Aby wszystkie te analizy były możliwe, konieczne jest zgromadzenie jak największej ilości danych dotyczących przebiegu testu." ] }, { "cell_type": "markdown", "id": "constant-underground", "metadata": {}, "source": [ "Testy są przede wszystkim nagrywane. Nagrywany jest zarówno ekran komputera (screen capture), jak i sam użytkownik pracujący przy komputerze. To jednak nie wszystko - często stosuje się specjalne techniki eye-trackingu, które są w stanie określić, w który punk ekranu użytkownik aktualnie patrzy. Dane pozyskane w ten sposób używane są do analizy czasu znalezienia przez użytkownika potrzebnej mu funkcji oraz zidentyfikowania miejsc, gdzie tej funkcji poszukiwał. Można również wyznaczyć obszary ekranu, które często skupiają uwagę użytkownika. " ] }, { "cell_type": "markdown", "id": "analyzed-lodging", "metadata": {}, "source": [ "Dodatkowo stosuje się jeszcze jedną technikę, która jest szczególnie przydatna z punktu widzenia analizy procesu tłumaczenia. Wykonuje się pełny key logging, tj. zapisuje się każde uderzenie użytkownika w dowolny klawisz na klawiaturze wraz z precyzyjnym czasem tego uderzenia. Dane pozyskane w ten sposób pozwalają na przeprowadzenie szeregu interesujących analiz." ] }, { "cell_type": "markdown", "id": "incredible-stress", "metadata": {}, "source": [ "Zapoznajmy się najpierw z programem typu key logger:" ] }, { "cell_type": "markdown", "id": "arctic-horror", "metadata": {}, "source": [ "`sudo pip3 install keyboard`" ] }, { "cell_type": "code", "execution_count": 1, "id": "6f21555b", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting keyboard\n", " Downloading keyboard-0.13.5-py3-none-any.whl (58 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m58.1/58.1 kB\u001b[0m \u001b[31m936.6 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mMB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hCollecting pyobjc\n", " Downloading pyobjc-10.3-py3-none-any.whl (4.0 kB)\n", "Collecting pyobjc-core==10.3\n", " Downloading pyobjc_core-10.3-cp311-cp311-macosx_10_9_universal2.whl (774 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m774.8/774.8 kB\u001b[0m \u001b[31m7.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m31m10.5 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-AddressBook==10.3\n", " Downloading pyobjc_framework_AddressBook-10.3-cp36-abi3-macosx_11_0_universal2.whl (13 kB)\n", "Collecting pyobjc-framework-AppleScriptKit==10.3\n", " Downloading pyobjc_framework_AppleScriptKit-10.3-py2.py3-none-any.whl (3.9 kB)\n", "Collecting pyobjc-framework-ApplicationServices==10.3\n", " Downloading pyobjc_framework_ApplicationServices-10.3-cp311-cp311-macosx_10_9_universal2.whl (31 kB)\n", "Collecting pyobjc-framework-Automator==10.3\n", " Downloading pyobjc_framework_Automator-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-CFNetwork==10.3\n", " Downloading pyobjc_framework_CFNetwork-10.3-cp36-abi3-macosx_11_0_universal2.whl (18 kB)\n", "Collecting pyobjc-framework-Cocoa==10.3\n", " Downloading pyobjc_framework_Cocoa-10.3-cp311-cp311-macosx_10_9_universal2.whl (396 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m396.1/396.1 kB\u001b[0m \u001b[31m11.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-CoreAudio==10.3\n", " Downloading pyobjc_framework_CoreAudio-10.3-cp311-cp311-macosx_10_9_universal2.whl (35 kB)\n", "Collecting pyobjc-framework-CoreAudioKit==10.3\n", " Downloading pyobjc_framework_CoreAudioKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (7.4 kB)\n", "Collecting pyobjc-framework-CoreData==10.3\n", " Downloading pyobjc_framework_CoreData-10.3-cp36-abi3-macosx_11_0_universal2.whl (17 kB)\n", "Collecting pyobjc-framework-CoreMIDI==10.3\n", " Downloading pyobjc_framework_CoreMIDI-10.3-cp36-abi3-macosx_11_0_universal2.whl (17 kB)\n", "Collecting pyobjc-framework-CoreServices==10.3\n", " Downloading pyobjc_framework_CoreServices-10.3-cp36-abi3-macosx_11_0_universal2.whl (29 kB)\n", "Collecting pyobjc-framework-CoreText==10.3\n", " Downloading pyobjc_framework_CoreText-10.3-cp311-cp311-macosx_10_9_universal2.whl (30 kB)\n", "Collecting pyobjc-framework-DiscRecording==10.3\n", " Downloading pyobjc_framework_DiscRecording-10.3-cp36-abi3-macosx_11_0_universal2.whl (14 kB)\n", "Collecting pyobjc-framework-DiscRecordingUI==10.3\n", " Downloading pyobjc_framework_DiscRecordingUI-10.3-py2.py3-none-any.whl (4.3 kB)\n", "Collecting pyobjc-framework-DiskArbitration==10.3\n", " Downloading pyobjc_framework_DiskArbitration-10.3-py2.py3-none-any.whl (4.4 kB)\n", "Collecting pyobjc-framework-DVDPlayback==10.3\n", " Downloading pyobjc_framework_DVDPlayback-10.3-py2.py3-none-any.whl (7.8 kB)\n", "Collecting pyobjc-framework-ExceptionHandling==10.3\n", " Downloading pyobjc_framework_ExceptionHandling-10.3-py2.py3-none-any.whl (6.6 kB)\n", "Collecting pyobjc-framework-InstallerPlugins==10.3\n", " Downloading pyobjc_framework_InstallerPlugins-10.3-py2.py3-none-any.whl (4.4 kB)\n", "Collecting pyobjc-framework-IOBluetooth==10.3\n", " Downloading pyobjc_framework_IOBluetooth-10.3-cp36-abi3-macosx_11_0_universal2.whl (41 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m41.4/41.4 kB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-IOBluetoothUI==10.3\n", " Downloading pyobjc_framework_IOBluetoothUI-10.3-py2.py3-none-any.whl (3.6 kB)\n", "Collecting pyobjc-framework-LatentSemanticMapping==10.3\n", " Downloading pyobjc_framework_LatentSemanticMapping-10.3-py2.py3-none-any.whl (5.0 kB)\n", "Collecting pyobjc-framework-LaunchServices==10.3\n", " Downloading pyobjc_framework_LaunchServices-10.3-py2.py3-none-any.whl (3.5 kB)\n", "Collecting pyobjc-framework-OSAKit==10.3\n", " Downloading pyobjc_framework_OSAKit-10.3-py2.py3-none-any.whl (3.8 kB)\n", "Collecting pyobjc-framework-PreferencePanes==10.3\n", " Downloading pyobjc_framework_PreferencePanes-10.3-py2.py3-none-any.whl (4.4 kB)\n", "Collecting pyobjc-framework-Quartz==10.3\n", " Downloading pyobjc_framework_Quartz-10.3-cp311-cp311-macosx_10_9_universal2.whl (227 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m227.2/227.2 kB\u001b[0m \u001b[31m7.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-ScreenSaver==10.3\n", " Downloading pyobjc_framework_ScreenSaver-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.0 kB)\n", "Collecting pyobjc-framework-Security==10.3\n", " Downloading pyobjc_framework_Security-10.3-cp311-cp311-macosx_10_9_universal2.whl (41 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m41.0/41.0 kB\u001b[0m \u001b[31m1.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-SecurityFoundation==10.3\n", " Downloading pyobjc_framework_SecurityFoundation-10.3-py2.py3-none-any.whl (3.4 kB)\n", "Collecting pyobjc-framework-SecurityInterface==10.3\n", " Downloading pyobjc_framework_SecurityInterface-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-SearchKit==10.3\n", " Downloading pyobjc_framework_SearchKit-10.3-py2.py3-none-any.whl (3.3 kB)\n", "Collecting pyobjc-framework-SyncServices==10.3\n", " Downloading pyobjc_framework_SyncServices-10.3-cp36-abi3-macosx_11_0_universal2.whl (14 kB)\n", "Collecting pyobjc-framework-SystemConfiguration==10.3\n", " Downloading pyobjc_framework_SystemConfiguration-10.3-cp36-abi3-macosx_11_0_universal2.whl (21 kB)\n", "Collecting pyobjc-framework-WebKit==10.3\n", " Downloading pyobjc_framework_WebKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (44 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m44.7/44.7 kB\u001b[0m \u001b[31m1.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-AppleScriptObjC==10.3\n", " Downloading pyobjc_framework_AppleScriptObjC-10.3-py2.py3-none-any.whl (4.0 kB)\n", "Collecting pyobjc-framework-CoreLocation==10.3\n", " Downloading pyobjc_framework_CoreLocation-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-CoreWLAN==10.3\n", " Downloading pyobjc_framework_CoreWLAN-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-ImageCaptureCore==10.3\n", " Downloading pyobjc_framework_ImageCaptureCore-10.3-cp36-abi3-macosx_11_0_universal2.whl (16 kB)\n", "Collecting pyobjc-framework-IOSurface==10.3\n", " Downloading pyobjc_framework_IOSurface-10.3-py2.py3-none-any.whl (4.6 kB)\n", "Collecting pyobjc-framework-NetFS==10.3\n", " Downloading pyobjc_framework_NetFS-10.3-py2.py3-none-any.whl (3.8 kB)\n", "Collecting pyobjc-framework-OpenDirectory==10.3\n", " Downloading pyobjc_framework_OpenDirectory-10.3-py2.py3-none-any.whl (11 kB)\n", "Collecting pyobjc-framework-ServiceManagement==10.3\n", " Downloading pyobjc_framework_ServiceManagement-10.3-py2.py3-none-any.whl (4.9 kB)\n", "Collecting pyobjc-framework-iTunesLibrary==10.3\n", " Downloading pyobjc_framework_iTunesLibrary-10.3-py2.py3-none-any.whl (4.8 kB)\n", "Collecting pyobjc-framework-AVFoundation==10.3\n", " Downloading pyobjc_framework_AVFoundation-10.3-cp36-abi3-macosx_11_0_universal2.whl (67 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m68.0/68.0 kB\u001b[0m \u001b[31m2.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-CoreMedia==10.3\n", " Downloading pyobjc_framework_CoreMedia-10.3-cp311-cp311-macosx_10_9_universal2.whl (29 kB)\n", "Collecting pyobjc-framework-CoreMediaIO==10.3\n", " Downloading pyobjc_framework_CoreMediaIO-10.3-cp36-abi3-macosx_11_0_universal2.whl (17 kB)\n", "Collecting pyobjc-framework-StoreKit==10.3\n", " Downloading pyobjc_framework_StoreKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-SceneKit==10.3\n", " Downloading pyobjc_framework_SceneKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (33 kB)\n", "Collecting pyobjc-framework-libdispatch==10.3\n", " Downloading pyobjc_framework_libdispatch-10.3-cp311-cp311-macosx_10_9_universal2.whl (20 kB)\n", "Collecting pyobjc-framework-libxpc==10.3\n", " Downloading pyobjc_framework_libxpc-10.3-cp311-cp311-macosx_10_9_universal2.whl (19 kB)\n", "Collecting pyobjc-framework-AudioVideoBridging==10.3\n", " Downloading pyobjc_framework_AudioVideoBridging-10.3-cp311-cp311-macosx_10_9_universal2.whl (11 kB)\n", "Collecting pyobjc-framework-Accounts==10.3\n", " Downloading pyobjc_framework_Accounts-10.3-py2.py3-none-any.whl (4.7 kB)\n", "Collecting pyobjc-framework-EventKit==10.3\n", " Downloading pyobjc_framework_EventKit-10.3-py2.py3-none-any.whl (6.4 kB)\n", "Collecting pyobjc-framework-GameCenter==10.3\n", " Downloading pyobjc_framework_GameCenter-10.3-cp36-abi3-macosx_11_0_universal2.whl (19 kB)\n", "Collecting pyobjc-framework-Social==10.3\n", " Downloading pyobjc_framework_Social-10.3-py2.py3-none-any.whl (4.0 kB)\n", "Collecting pyobjc-framework-GameKit==10.3\n", " Downloading pyobjc_framework_GameKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (22 kB)\n", "Collecting pyobjc-framework-VideoToolbox==10.3\n", " Downloading pyobjc_framework_VideoToolbox-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-AVKit==10.3\n", " Downloading pyobjc_framework_AVKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-GameController==10.3\n", " Downloading pyobjc_framework_GameController-10.3-cp36-abi3-macosx_11_0_universal2.whl (20 kB)\n", "Collecting pyobjc-framework-MapKit==10.3\n", " Downloading pyobjc_framework_MapKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (22 kB)\n", "Collecting pyobjc-framework-MediaAccessibility==10.3\n", " Downloading pyobjc_framework_MediaAccessibility-10.3-py2.py3-none-any.whl (4.1 kB)\n", "Collecting pyobjc-framework-MediaLibrary==10.3\n", " Downloading pyobjc_framework_MediaLibrary-10.3-py2.py3-none-any.whl (3.9 kB)\n", "Collecting pyobjc-framework-MediaToolbox==10.3\n", " Downloading pyobjc_framework_MediaToolbox-10.3-cp36-abi3-macosx_11_0_universal2.whl (13 kB)\n", "Collecting pyobjc-framework-SpriteKit==10.3\n", " Downloading pyobjc_framework_SpriteKit-10.3-cp311-cp311-macosx_10_9_universal2.whl (17 kB)\n", "Collecting pyobjc-framework-CloudKit==10.3\n", " Downloading pyobjc_framework_CloudKit-10.3-py2.py3-none-any.whl (10 kB)\n", "Collecting pyobjc-framework-CoreBluetooth==10.3\n", " Downloading pyobjc_framework_CoreBluetooth-10.3-cp36-abi3-macosx_11_0_universal2.whl (13 kB)\n", "Collecting pyobjc-framework-CryptoTokenKit==10.3\n", " Downloading pyobjc_framework_CryptoTokenKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (13 kB)\n", "Collecting pyobjc-framework-FinderSync==10.3\n", " Downloading pyobjc_framework_FinderSync-10.3-py2.py3-none-any.whl (4.5 kB)\n", "Collecting pyobjc-framework-LocalAuthentication==10.3\n", " Downloading pyobjc_framework_LocalAuthentication-10.3-py2.py3-none-any.whl (5.7 kB)\n", "Collecting pyobjc-framework-MultipeerConnectivity==10.3\n", " Downloading pyobjc_framework_MultipeerConnectivity-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-NotificationCenter==10.3\n", " Downloading pyobjc_framework_NotificationCenter-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-Contacts==10.3\n", " Downloading pyobjc_framework_Contacts-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-ContactsUI==10.3\n", " Downloading pyobjc_framework_ContactsUI-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.2 kB)\n", "Collecting pyobjc-framework-Metal==10.3\n", " Downloading pyobjc_framework_Metal-10.3-cp36-abi3-macosx_11_0_universal2.whl (55 kB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m55.7/55.7 kB\u001b[0m \u001b[31m2.0 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", "\u001b[?25hCollecting pyobjc-framework-MetalKit==10.3\n", " Downloading pyobjc_framework_MetalKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (9.1 kB)\n", "Collecting pyobjc-framework-ModelIO==10.3\n", " Downloading pyobjc_framework_ModelIO-10.3-cp36-abi3-macosx_11_0_universal2.whl (21 kB)\n", "Collecting pyobjc-framework-NetworkExtension==10.3\n", " Downloading pyobjc_framework_NetworkExtension-10.3-cp36-abi3-macosx_11_0_universal2.whl (14 kB)\n", "Collecting pyobjc-framework-Photos==10.3\n", " Downloading pyobjc_framework_Photos-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-PhotosUI==10.3\n", " Downloading pyobjc_framework_PhotosUI-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-GameplayKit==10.3\n", " Downloading pyobjc_framework_GameplayKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (13 kB)\n", "Collecting pyobjc-framework-Intents==10.3\n", " Downloading pyobjc_framework_Intents-10.3-cp36-abi3-macosx_11_0_universal2.whl (32 kB)\n", "Collecting pyobjc-framework-MediaPlayer==10.3\n", " Downloading pyobjc_framework_MediaPlayer-10.3-py2.py3-none-any.whl (6.5 kB)\n", "Collecting pyobjc-framework-SafariServices==10.3\n", " Downloading pyobjc_framework_SafariServices-10.3-cp36-abi3-macosx_11_0_universal2.whl (7.4 kB)\n", "Collecting pyobjc-framework-ColorSync==10.3\n", " Downloading pyobjc_framework_ColorSync-10.3-py2.py3-none-any.whl (5.6 kB)\n", "Collecting pyobjc-framework-CoreML==10.3\n", " Downloading pyobjc_framework_CoreML-10.3-cp36-abi3-macosx_11_0_universal2.whl (11 kB)\n", "Collecting pyobjc-framework-CoreSpotlight==10.3\n", " Downloading pyobjc_framework_CoreSpotlight-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-ExternalAccessory==10.3\n", " Downloading pyobjc_framework_ExternalAccessory-10.3-cp36-abi3-macosx_11_0_universal2.whl (9.3 kB)\n", "Collecting pyobjc-framework-MetalPerformanceShaders==10.3\n", " Downloading pyobjc_framework_MetalPerformanceShaders-10.3-cp36-abi3-macosx_11_0_universal2.whl (33 kB)\n", "Collecting pyobjc-framework-Vision==10.3\n", " Downloading pyobjc_framework_Vision-10.3-cp36-abi3-macosx_11_0_universal2.whl (17 kB)\n", "Collecting pyobjc-framework-AdSupport==10.3\n", " Downloading pyobjc_framework_AdSupport-10.3-py2.py3-none-any.whl (3.0 kB)\n", "Collecting pyobjc-framework-BusinessChat==10.3\n", " Downloading pyobjc_framework_BusinessChat-10.3-py2.py3-none-any.whl (3.1 kB)\n", "Collecting pyobjc-framework-NaturalLanguage==10.3\n", " Downloading pyobjc_framework_NaturalLanguage-10.3-py2.py3-none-any.whl (4.9 kB)\n", "Collecting pyobjc-framework-Network==10.3\n", " Downloading pyobjc_framework_Network-10.3-cp36-abi3-macosx_11_0_universal2.whl (14 kB)\n", "Collecting pyobjc-framework-UserNotifications==10.3\n", " Downloading pyobjc_framework_UserNotifications-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-VideoSubscriberAccount==10.3\n", " Downloading pyobjc_framework_VideoSubscriberAccount-10.3-py2.py3-none-any.whl (4.3 kB)\n", "Collecting pyobjc-framework-AuthenticationServices==10.3\n", " Downloading pyobjc_framework_AuthenticationServices-10.3-cp36-abi3-macosx_11_0_universal2.whl (19 kB)\n", "Collecting pyobjc-framework-AutomaticAssessmentConfiguration==10.3\n", " Downloading pyobjc_framework_AutomaticAssessmentConfiguration-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.9 kB)\n", "Collecting pyobjc-framework-CoreHaptics==10.3\n", " Downloading pyobjc_framework_CoreHaptics-10.3-py2.py3-none-any.whl (5.0 kB)\n", "Collecting pyobjc-framework-CoreMotion==10.3\n", " Downloading pyobjc_framework_CoreMotion-10.3-cp311-cp311-macosx_10_9_universal2.whl (9.8 kB)\n", "Collecting pyobjc-framework-DeviceCheck==10.3\n", " Downloading pyobjc_framework_DeviceCheck-10.3-py2.py3-none-any.whl (3.3 kB)\n", "Collecting pyobjc-framework-ExecutionPolicy==10.3\n", " Downloading pyobjc_framework_ExecutionPolicy-10.3-py2.py3-none-any.whl (3.3 kB)\n", "Collecting pyobjc-framework-FileProvider==10.3\n", " Downloading pyobjc_framework_FileProvider-10.3-cp311-cp311-macosx_10_9_universal2.whl (18 kB)\n", "Collecting pyobjc-framework-FileProviderUI==10.3\n", " Downloading pyobjc_framework_FileProviderUI-10.3-py2.py3-none-any.whl (3.3 kB)\n", "Collecting pyobjc-framework-LinkPresentation==10.3\n", " Downloading pyobjc_framework_LinkPresentation-10.3-py2.py3-none-any.whl (3.4 kB)\n", "Collecting pyobjc-framework-OSLog==10.3\n", " Downloading pyobjc_framework_OSLog-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.0 kB)\n", "Collecting pyobjc-framework-PencilKit==10.3\n", " Downloading pyobjc_framework_PencilKit-10.3-py2.py3-none-any.whl (3.6 kB)\n", "Collecting pyobjc-framework-PushKit==10.3\n", " Downloading pyobjc_framework_PushKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.6 kB)\n", "Collecting pyobjc-framework-QuickLookThumbnailing==10.3\n", " Downloading pyobjc_framework_QuickLookThumbnailing-10.3-py2.py3-none-any.whl (3.8 kB)\n", "Collecting pyobjc-framework-Speech==10.3\n", " Downloading pyobjc_framework_Speech-10.3-cp36-abi3-macosx_11_0_universal2.whl (9.5 kB)\n", "Collecting pyobjc-framework-SoundAnalysis==10.3\n", " Downloading pyobjc_framework_SoundAnalysis-10.3-py2.py3-none-any.whl (3.8 kB)\n", "Collecting pyobjc-framework-SystemExtensions==10.3\n", " Downloading pyobjc_framework_SystemExtensions-10.3-cp36-abi3-macosx_11_0_universal2.whl (9.1 kB)\n", "Collecting pyobjc-framework-Accessibility==10.3\n", " Downloading pyobjc_framework_Accessibility-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-AdServices==10.3\n", " Downloading pyobjc_framework_AdServices-10.3-py2.py3-none-any.whl (3.1 kB)\n", "Collecting pyobjc-framework-AppTrackingTransparency==10.3\n", " Downloading pyobjc_framework_AppTrackingTransparency-10.3-py2.py3-none-any.whl (3.4 kB)\n", "Collecting pyobjc-framework-CallKit==10.3\n", " Downloading pyobjc_framework_CallKit-10.3-py2.py3-none-any.whl (4.9 kB)\n", "Collecting pyobjc-framework-ClassKit==10.3\n", " Downloading pyobjc_framework_ClassKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.7 kB)\n", "Collecting pyobjc-framework-KernelManagement==10.3\n", " Downloading pyobjc_framework_KernelManagement-10.3-py2.py3-none-any.whl (3.3 kB)\n", "Collecting pyobjc-framework-MetalPerformanceShadersGraph==10.3\n", " Downloading pyobjc_framework_MetalPerformanceShadersGraph-10.3-py2.py3-none-any.whl (6.0 kB)\n", "Collecting pyobjc-framework-MLCompute==10.3\n", " Downloading pyobjc_framework_MLCompute-10.3-py2.py3-none-any.whl (6.4 kB)\n", "Collecting pyobjc-framework-PassKit==10.3\n", " Downloading pyobjc_framework_PassKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (13 kB)\n", "Collecting pyobjc-framework-ReplayKit==10.3\n", " Downloading pyobjc_framework_ReplayKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-ScreenTime==10.3\n", " Downloading pyobjc_framework_ScreenTime-10.3-py2.py3-none-any.whl (3.4 kB)\n", "Collecting pyobjc-framework-UniformTypeIdentifiers==10.3\n", " Downloading pyobjc_framework_UniformTypeIdentifiers-10.3-py2.py3-none-any.whl (4.4 kB)\n", "Collecting pyobjc-framework-UserNotificationsUI==10.3\n", " Downloading pyobjc_framework_UserNotificationsUI-10.3-py2.py3-none-any.whl (3.5 kB)\n", "Collecting pyobjc-framework-Virtualization==10.3\n", " Downloading pyobjc_framework_Virtualization-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-DataDetection==10.3\n", " Downloading pyobjc_framework_DataDetection-10.3-py2.py3-none-any.whl (3.1 kB)\n", "Collecting pyobjc-framework-IntentsUI==10.3\n", " Downloading pyobjc_framework_IntentsUI-10.3-cp311-cp311-macosx_10_9_universal2.whl (9.6 kB)\n", "Collecting pyobjc-framework-LocalAuthenticationEmbeddedUI==10.3\n", " Downloading pyobjc_framework_LocalAuthenticationEmbeddedUI-10.3-py2.py3-none-any.whl (3.5 kB)\n", "Collecting pyobjc-framework-MailKit==10.3\n", " Downloading pyobjc_framework_MailKit-10.3-py2.py3-none-any.whl (4.5 kB)\n", "Collecting pyobjc-framework-MetricKit==10.3\n", " Downloading pyobjc_framework_MetricKit-10.3-cp311-cp311-macosx_10_9_universal2.whl (8.1 kB)\n", "Collecting pyobjc-framework-PHASE==10.3\n", " Downloading pyobjc_framework_PHASE-10.3-py2.py3-none-any.whl (6.2 kB)\n", "Collecting pyobjc-framework-ShazamKit==10.3\n", " Downloading pyobjc_framework_ShazamKit-10.3-cp311-cp311-macosx_10_9_universal2.whl (8.6 kB)\n", "Collecting pyobjc-framework-ScreenCaptureKit==10.3\n", " Downloading pyobjc_framework_ScreenCaptureKit-10.3-cp311-cp311-macosx_10_9_universal2.whl (11 kB)\n", "Collecting pyobjc-framework-AVRouting==10.3\n", " Downloading pyobjc_framework_AVRouting-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.6 kB)\n", "Collecting pyobjc-framework-BackgroundAssets==10.3\n", " Downloading pyobjc_framework_BackgroundAssets-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-ExtensionKit==10.3\n", " Downloading pyobjc_framework_ExtensionKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.3 kB)\n", "Collecting pyobjc-framework-HealthKit==10.3\n", " Downloading pyobjc_framework_HealthKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (19 kB)\n", "Collecting pyobjc-framework-MetalFX==10.3\n", " Downloading pyobjc_framework_MetalFX-10.3-cp36-abi3-macosx_11_0_universal2.whl (10 kB)\n", "Collecting pyobjc-framework-SafetyKit==10.3\n", " Downloading pyobjc_framework_SafetyKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.3 kB)\n", "Collecting pyobjc-framework-SharedWithYouCore==10.3\n", " Downloading pyobjc_framework_SharedWithYouCore-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.9 kB)\n", "Collecting pyobjc-framework-SharedWithYou==10.3\n", " Downloading pyobjc_framework_SharedWithYou-10.3-cp36-abi3-macosx_11_0_universal2.whl (9.1 kB)\n", "Collecting pyobjc-framework-ThreadNetwork==10.3\n", " Downloading pyobjc_framework_ThreadNetwork-10.3-py2.py3-none-any.whl (3.4 kB)\n", "Collecting pyobjc-framework-Cinematic==10.3\n", " Downloading pyobjc_framework_Cinematic-10.3-py2.py3-none-any.whl (4.2 kB)\n", "Collecting pyobjc-framework-SensitiveContentAnalysis==10.3\n", " Downloading pyobjc_framework_SensitiveContentAnalysis-10.3-py2.py3-none-any.whl (3.4 kB)\n", "Collecting pyobjc-framework-Symbols==10.3\n", " Downloading pyobjc_framework_Symbols-10.3-py2.py3-none-any.whl (2.9 kB)\n", "Collecting pyobjc-framework-CalendarStore==10.3\n", " Downloading pyobjc_framework_CalendarStore-10.3-py2.py3-none-any.whl (4.8 kB)\n", "Collecting pyobjc-framework-Collaboration==10.3\n", " Downloading pyobjc_framework_Collaboration-10.3-py2.py3-none-any.whl (4.5 kB)\n", "Collecting pyobjc-framework-DictionaryServices==10.3\n", " Downloading pyobjc_framework_DictionaryServices-10.3-py2.py3-none-any.whl (3.5 kB)\n", "Collecting pyobjc-framework-FSEvents==10.3\n", " Downloading pyobjc_framework_FSEvents-10.3-cp36-abi3-macosx_11_0_universal2.whl (12 kB)\n", "Collecting pyobjc-framework-InputMethodKit==10.3\n", " Downloading pyobjc_framework_InputMethodKit-10.3-cp36-abi3-macosx_11_0_universal2.whl (9.8 kB)\n", "Collecting pyobjc-framework-InstantMessage==10.3\n", " Downloading pyobjc_framework_InstantMessage-10.3-py2.py3-none-any.whl (5.0 kB)\n", "Collecting pyobjc-framework-ScriptingBridge==10.3\n", " Downloading pyobjc_framework_ScriptingBridge-10.3-cp36-abi3-macosx_11_0_universal2.whl (8.5 kB)\n", "Installing collected packages: pyobjc-core, pyobjc-framework-Cocoa, pyobjc-framework-WebKit, pyobjc-framework-Virtualization, pyobjc-framework-VideoSubscriberAccount, pyobjc-framework-UserNotifications, pyobjc-framework-UniformTypeIdentifiers, pyobjc-framework-ThreadNetwork, pyobjc-framework-SystemExtensions, pyobjc-framework-SystemConfiguration, pyobjc-framework-Symbols, pyobjc-framework-StoreKit, pyobjc-framework-Speech, pyobjc-framework-SoundAnalysis, pyobjc-framework-Social, pyobjc-framework-ShazamKit, pyobjc-framework-SharedWithYouCore, pyobjc-framework-ServiceManagement, pyobjc-framework-Security, pyobjc-framework-ScriptingBridge, pyobjc-framework-ScreenTime, pyobjc-framework-ScreenSaver, pyobjc-framework-SafariServices, pyobjc-framework-ReplayKit, pyobjc-framework-Quartz, pyobjc-framework-PushKit, pyobjc-framework-PreferencePanes, pyobjc-framework-PhotosUI, pyobjc-framework-Photos, pyobjc-framework-PencilKit, pyobjc-framework-PassKit, pyobjc-framework-OSAKit, pyobjc-framework-OpenDirectory, pyobjc-framework-NotificationCenter, pyobjc-framework-NetworkExtension, pyobjc-framework-Network, pyobjc-framework-NetFS, pyobjc-framework-NaturalLanguage, pyobjc-framework-MultipeerConnectivity, pyobjc-framework-MLCompute, pyobjc-framework-MetricKit, pyobjc-framework-Metal, pyobjc-framework-MediaToolbox, pyobjc-framework-MediaAccessibility, pyobjc-framework-MailKit, pyobjc-framework-libxpc, pyobjc-framework-libdispatch, pyobjc-framework-LatentSemanticMapping, pyobjc-framework-KernelManagement, pyobjc-framework-iTunesLibrary, pyobjc-framework-IOSurface, pyobjc-framework-IOBluetooth, pyobjc-framework-Intents, pyobjc-framework-InstallerPlugins, pyobjc-framework-InputMethodKit, pyobjc-framework-ImageCaptureCore, pyobjc-framework-HealthKit, pyobjc-framework-GameController, pyobjc-framework-GameCenter, pyobjc-framework-FSEvents, pyobjc-framework-FinderSync, pyobjc-framework-FileProvider, pyobjc-framework-ExternalAccessory, pyobjc-framework-ExtensionKit, pyobjc-framework-ExecutionPolicy, pyobjc-framework-ExceptionHandling, pyobjc-framework-EventKit, pyobjc-framework-DVDPlayback, pyobjc-framework-DiskArbitration, pyobjc-framework-DiscRecording, pyobjc-framework-DeviceCheck, pyobjc-framework-DataDetection, pyobjc-framework-CryptoTokenKit, pyobjc-framework-CoreWLAN, pyobjc-framework-CoreSpotlight, pyobjc-framework-CoreMotion, pyobjc-framework-CoreML, pyobjc-framework-CoreMIDI, pyobjc-framework-CoreMediaIO, pyobjc-framework-CoreMedia, pyobjc-framework-CoreLocation, pyobjc-framework-CoreHaptics, pyobjc-framework-CoreData, pyobjc-framework-CoreBluetooth, pyobjc-framework-CoreAudio, pyobjc-framework-Contacts, pyobjc-framework-ColorSync, pyobjc-framework-Collaboration, pyobjc-framework-ClassKit, pyobjc-framework-CFNetwork, pyobjc-framework-CallKit, pyobjc-framework-CalendarStore, pyobjc-framework-BusinessChat, pyobjc-framework-BackgroundAssets, pyobjc-framework-AVRouting, pyobjc-framework-Automator, pyobjc-framework-AutomaticAssessmentConfiguration, pyobjc-framework-AuthenticationServices, pyobjc-framework-AudioVideoBridging, pyobjc-framework-AppTrackingTransparency, pyobjc-framework-AppleScriptObjC, pyobjc-framework-AppleScriptKit, pyobjc-framework-AdSupport, pyobjc-framework-AdServices, pyobjc-framework-AddressBook, pyobjc-framework-Accounts, pyobjc-framework-Vision, pyobjc-framework-VideoToolbox, pyobjc-framework-UserNotificationsUI, pyobjc-framework-SyncServices, pyobjc-framework-SpriteKit, pyobjc-framework-SharedWithYou, pyobjc-framework-SensitiveContentAnalysis, pyobjc-framework-SecurityInterface, pyobjc-framework-SecurityFoundation, pyobjc-framework-ScreenCaptureKit, pyobjc-framework-SceneKit, pyobjc-framework-SafetyKit, pyobjc-framework-QuickLookThumbnailing, pyobjc-framework-OSLog, pyobjc-framework-ModelIO, pyobjc-framework-MetalPerformanceShaders, pyobjc-framework-MetalKit, pyobjc-framework-MetalFX, pyobjc-framework-MediaLibrary, pyobjc-framework-MapKit, pyobjc-framework-LocalAuthentication, pyobjc-framework-LinkPresentation, pyobjc-framework-IOBluetoothUI, pyobjc-framework-IntentsUI, pyobjc-framework-InstantMessage, pyobjc-framework-GameKit, pyobjc-framework-FileProviderUI, pyobjc-framework-DiscRecordingUI, pyobjc-framework-CoreText, pyobjc-framework-CoreServices, pyobjc-framework-CoreAudioKit, pyobjc-framework-ContactsUI, pyobjc-framework-CloudKit, pyobjc-framework-AVKit, pyobjc-framework-AVFoundation, pyobjc-framework-Accessibility, pyobjc-framework-SearchKit, pyobjc-framework-PHASE, pyobjc-framework-MetalPerformanceShadersGraph, pyobjc-framework-MediaPlayer, pyobjc-framework-LocalAuthenticationEmbeddedUI, pyobjc-framework-LaunchServices, pyobjc-framework-GameplayKit, pyobjc-framework-DictionaryServices, pyobjc-framework-Cinematic, pyobjc-framework-ApplicationServices, pyobjc, keyboard\n", "Successfully installed keyboard-0.13.5 pyobjc-10.3 pyobjc-core-10.3 pyobjc-framework-AVFoundation-10.3 pyobjc-framework-AVKit-10.3 pyobjc-framework-AVRouting-10.3 pyobjc-framework-Accessibility-10.3 pyobjc-framework-Accounts-10.3 pyobjc-framework-AdServices-10.3 pyobjc-framework-AdSupport-10.3 pyobjc-framework-AddressBook-10.3 pyobjc-framework-AppTrackingTransparency-10.3 pyobjc-framework-AppleScriptKit-10.3 pyobjc-framework-AppleScriptObjC-10.3 pyobjc-framework-ApplicationServices-10.3 pyobjc-framework-AudioVideoBridging-10.3 pyobjc-framework-AuthenticationServices-10.3 pyobjc-framework-AutomaticAssessmentConfiguration-10.3 pyobjc-framework-Automator-10.3 pyobjc-framework-BackgroundAssets-10.3 pyobjc-framework-BusinessChat-10.3 pyobjc-framework-CFNetwork-10.3 pyobjc-framework-CalendarStore-10.3 pyobjc-framework-CallKit-10.3 pyobjc-framework-Cinematic-10.3 pyobjc-framework-ClassKit-10.3 pyobjc-framework-CloudKit-10.3 pyobjc-framework-Cocoa-10.3 pyobjc-framework-Collaboration-10.3 pyobjc-framework-ColorSync-10.3 pyobjc-framework-Contacts-10.3 pyobjc-framework-ContactsUI-10.3 pyobjc-framework-CoreAudio-10.3 pyobjc-framework-CoreAudioKit-10.3 pyobjc-framework-CoreBluetooth-10.3 pyobjc-framework-CoreData-10.3 pyobjc-framework-CoreHaptics-10.3 pyobjc-framework-CoreLocation-10.3 pyobjc-framework-CoreMIDI-10.3 pyobjc-framework-CoreML-10.3 pyobjc-framework-CoreMedia-10.3 pyobjc-framework-CoreMediaIO-10.3 pyobjc-framework-CoreMotion-10.3 pyobjc-framework-CoreServices-10.3 pyobjc-framework-CoreSpotlight-10.3 pyobjc-framework-CoreText-10.3 pyobjc-framework-CoreWLAN-10.3 pyobjc-framework-CryptoTokenKit-10.3 pyobjc-framework-DVDPlayback-10.3 pyobjc-framework-DataDetection-10.3 pyobjc-framework-DeviceCheck-10.3 pyobjc-framework-DictionaryServices-10.3 pyobjc-framework-DiscRecording-10.3 pyobjc-framework-DiscRecordingUI-10.3 pyobjc-framework-DiskArbitration-10.3 pyobjc-framework-EventKit-10.3 pyobjc-framework-ExceptionHandling-10.3 pyobjc-framework-ExecutionPolicy-10.3 pyobjc-framework-ExtensionKit-10.3 pyobjc-framework-ExternalAccessory-10.3 pyobjc-framework-FSEvents-10.3 pyobjc-framework-FileProvider-10.3 pyobjc-framework-FileProviderUI-10.3 pyobjc-framework-FinderSync-10.3 pyobjc-framework-GameCenter-10.3 pyobjc-framework-GameController-10.3 pyobjc-framework-GameKit-10.3 pyobjc-framework-GameplayKit-10.3 pyobjc-framework-HealthKit-10.3 pyobjc-framework-IOBluetooth-10.3 pyobjc-framework-IOBluetoothUI-10.3 pyobjc-framework-IOSurface-10.3 pyobjc-framework-ImageCaptureCore-10.3 pyobjc-framework-InputMethodKit-10.3 pyobjc-framework-InstallerPlugins-10.3 pyobjc-framework-InstantMessage-10.3 pyobjc-framework-Intents-10.3 pyobjc-framework-IntentsUI-10.3 pyobjc-framework-KernelManagement-10.3 pyobjc-framework-LatentSemanticMapping-10.3 pyobjc-framework-LaunchServices-10.3 pyobjc-framework-LinkPresentation-10.3 pyobjc-framework-LocalAuthentication-10.3 pyobjc-framework-LocalAuthenticationEmbeddedUI-10.3 pyobjc-framework-MLCompute-10.3 pyobjc-framework-MailKit-10.3 pyobjc-framework-MapKit-10.3 pyobjc-framework-MediaAccessibility-10.3 pyobjc-framework-MediaLibrary-10.3 pyobjc-framework-MediaPlayer-10.3 pyobjc-framework-MediaToolbox-10.3 pyobjc-framework-Metal-10.3 pyobjc-framework-MetalFX-10.3 pyobjc-framework-MetalKit-10.3 pyobjc-framework-MetalPerformanceShaders-10.3 pyobjc-framework-MetalPerformanceShadersGraph-10.3 pyobjc-framework-MetricKit-10.3 pyobjc-framework-ModelIO-10.3 pyobjc-framework-MultipeerConnectivity-10.3 pyobjc-framework-NaturalLanguage-10.3 pyobjc-framework-NetFS-10.3 pyobjc-framework-Network-10.3 pyobjc-framework-NetworkExtension-10.3 pyobjc-framework-NotificationCenter-10.3 pyobjc-framework-OSAKit-10.3 pyobjc-framework-OSLog-10.3 pyobjc-framework-OpenDirectory-10.3 pyobjc-framework-PHASE-10.3 pyobjc-framework-PassKit-10.3 pyobjc-framework-PencilKit-10.3 pyobjc-framework-Photos-10.3 pyobjc-framework-PhotosUI-10.3 pyobjc-framework-PreferencePanes-10.3 pyobjc-framework-PushKit-10.3 pyobjc-framework-Quartz-10.3 pyobjc-framework-QuickLookThumbnailing-10.3 pyobjc-framework-ReplayKit-10.3 pyobjc-framework-SafariServices-10.3 pyobjc-framework-SafetyKit-10.3 pyobjc-framework-SceneKit-10.3 pyobjc-framework-ScreenCaptureKit-10.3 pyobjc-framework-ScreenSaver-10.3 pyobjc-framework-ScreenTime-10.3 pyobjc-framework-ScriptingBridge-10.3 pyobjc-framework-SearchKit-10.3 pyobjc-framework-Security-10.3 pyobjc-framework-SecurityFoundation-10.3 pyobjc-framework-SecurityInterface-10.3 pyobjc-framework-SensitiveContentAnalysis-10.3 pyobjc-framework-ServiceManagement-10.3 pyobjc-framework-SharedWithYou-10.3 pyobjc-framework-SharedWithYouCore-10.3 pyobjc-framework-ShazamKit-10.3 pyobjc-framework-Social-10.3 pyobjc-framework-SoundAnalysis-10.3 pyobjc-framework-Speech-10.3 pyobjc-framework-SpriteKit-10.3 pyobjc-framework-StoreKit-10.3 pyobjc-framework-Symbols-10.3 pyobjc-framework-SyncServices-10.3 pyobjc-framework-SystemConfiguration-10.3 pyobjc-framework-SystemExtensions-10.3 pyobjc-framework-ThreadNetwork-10.3 pyobjc-framework-UniformTypeIdentifiers-10.3 pyobjc-framework-UserNotifications-10.3 pyobjc-framework-UserNotificationsUI-10.3 pyobjc-framework-VideoSubscriberAccount-10.3 pyobjc-framework-VideoToolbox-10.3 pyobjc-framework-Virtualization-10.3 pyobjc-framework-Vision-10.3 pyobjc-framework-WebKit-10.3 pyobjc-framework-iTunesLibrary-10.3 pyobjc-framework-libdispatch-10.3 pyobjc-framework-libxpc-10.3\n", "\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip available: \u001b[0m\u001b[31;49m22.3\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m24.0\u001b[0m\n", "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n" ] } ], "source": [ "!pip install keyboard" ] }, { "cell_type": "code", "execution_count": 2, "id": "broken-workstation", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Exception in thread Thread-4 (listen):\n", "Traceback (most recent call last):\n", " File \"/Users/potoato/.pyenv/versions/3.11.0/lib/python3.11/threading.py\", line 1038, in _bootstrap_inner\n", " self.run()\n", " File \"/Users/potoato/.pyenv/versions/3.11.0/lib/python3.11/site-packages/ipykernel/ipkernel.py\", line 766, in run_closure\n", " _threading_Thread_run(self)\n", " File \"/Users/potoato/.pyenv/versions/3.11.0/lib/python3.11/threading.py\", line 975, in run\n", " self._target(*self._args, **self._kwargs)\n", " File \"/Users/potoato/.pyenv/versions/3.11.0/lib/python3.11/site-packages/keyboard/__init__.py\", line 294, in listen\n", " _os_keyboard.listen(self.direct_callback)\n", " File \"/Users/potoato/.pyenv/versions/3.11.0/lib/python3.11/site-packages/keyboard/_darwinkeyboard.py\", line 430, in listen\n", " raise OSError(\"Error 13 - Must be run as administrator\")\n", "OSError: Error 13 - Must be run as administrator\n" ] }, { "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[2], line 8\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(event)\n\u001b[1;32m 7\u001b[0m keyboard\u001b[38;5;241m.\u001b[39mon_release(callback\u001b[38;5;241m=\u001b[39mreport_key)\n\u001b[0;32m----> 8\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~/.pyenv/versions/3.11.0/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", "\n", "\n", "def report_key(event):\n", " print(event)\n", "\n", "keyboard.on_release(callback=report_key)\n", "keyboard.wait()" ] }, { "cell_type": "markdown", "id": "polish-census", "metadata": {}, "source": [ "UWAGA! Aby uruchomić powyższy kod na Linuxie konieczne są uprawnienia administratora (pytanie poza konkursem - dlaczego?)" ] }, { "cell_type": "markdown", "id": "incoming-hands", "metadata": {}, "source": [ "### Ć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": null, "id": "548e415e", "metadata": {}, "outputs": [], "source": [ "import keyboard\n", "import time\n", "\n", "def log_keystroke(event):\n", " with open(\"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", "metadata": {}, "source": [ "Celem powyższego ćwiczenia jest pozyskanie danych testowych. Dalsze analizy będziemy prowadzili już bez key loggera, starając się korzystać jedynie z danych zapisanych w pliku. Oczywiście, jeśli zajdzie taka konieczność, można w każdej chwili wygenerować sobie nowy plik." ] }, { "cell_type": "markdown", "id": "boxed-maple", "metadata": {}, "source": [ "### Ćwiczenie 2: Napisz program, który wyliczy średnią prędkość pisania. Wykryj, kiedy użytkownik zaczął pisać. Nie bierz pod uwagę przerw dłuższych niż 5 sekund. Podaj prędkość pisania w znakach na minutę oraz słowach na minutę." ] }, { "cell_type": "code", "execution_count": 3, "id": "possible-holder", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Zacznij pisać. Gdy skończysz naciśnij 'esc'...\n" ] }, { "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[3], line 46\u001b[0m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;18m__name__\u001b[39m \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__main__\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 45\u001b[0m calc \u001b[38;5;241m=\u001b[39m TypingSpeedCalculator()\n\u001b[0;32m---> 46\u001b[0m \u001b[43mcalc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstart\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 48\u001b[0m \u001b[38;5;66;03m# nie byłem wstanie uruchomić skryptu w pliku .ipynb\u001b[39;00m\n", "Cell \u001b[0;32mIn[3], line 39\u001b[0m, in \u001b[0;36mTypingSpeedCalculator.start\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mZacznij pisać. Gdy skończysz naciśnij \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mesc\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 38\u001b[0m keyboard\u001b[38;5;241m.\u001b[39mon_press(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mon_key_press)\n\u001b[0;32m---> 39\u001b[0m \u001b[43mkeyboard\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mesc\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 41\u001b[0m cpm, wpm \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcalculate_speed()\n\u001b[1;32m 42\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNapisałeś: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcpm\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m na minutę, czyli \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mwpm\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m słów na sekundę!\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", "File \u001b[0;32m~/.pyenv/versions/3.11.0/lib/python3.11/site-packages/keyboard/__init__.py:882\u001b[0m, in \u001b[0;36mwait\u001b[0;34m(hotkey, suppress, trigger_on_release)\u001b[0m\n\u001b[1;32m 880\u001b[0m lock \u001b[38;5;241m=\u001b[39m _Event()\n\u001b[1;32m 881\u001b[0m remove \u001b[38;5;241m=\u001b[39m add_hotkey(hotkey, \u001b[38;5;28;01mlambda\u001b[39;00m: lock\u001b[38;5;241m.\u001b[39mset(), suppress\u001b[38;5;241m=\u001b[39msuppress, trigger_on_release\u001b[38;5;241m=\u001b[39mtrigger_on_release)\n\u001b[0;32m--> 882\u001b[0m \u001b[43mlock\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 883\u001b[0m remove_hotkey(remove)\n\u001b[1;32m 884\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n", "File \u001b[0;32m~/.pyenv/versions/3.11.0/lib/python3.11/site-packages/keyboard/__init__.py:117\u001b[0m, in \u001b[0;36m_Event.wait\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 115\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwait\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m 116\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m--> 117\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[43m_UninterruptibleEvent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0.5\u001b[39;49m\u001b[43m)\u001b[49m:\n\u001b[1;32m 118\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n", "File \u001b[0;32m~/.pyenv/versions/3.11.0/lib/python3.11/threading.py:622\u001b[0m, in \u001b[0;36mEvent.wait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 620\u001b[0m signaled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_flag\n\u001b[1;32m 621\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m signaled:\n\u001b[0;32m--> 622\u001b[0m signaled \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_cond\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mwait\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 623\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m signaled\n", "File \u001b[0;32m~/.pyenv/versions/3.11.0/lib/python3.11/threading.py:324\u001b[0m, in \u001b[0;36mCondition.wait\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 323\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m--> 324\u001b[0m gotit \u001b[38;5;241m=\u001b[39m \u001b[43mwaiter\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43macquire\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 325\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 326\u001b[0m gotit \u001b[38;5;241m=\u001b[39m waiter\u001b[38;5;241m.\u001b[39macquire(\u001b[38;5;28;01mFalse\u001b[39;00m)\n", "\u001b[0;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "import keyboard\n", "import time\n", "\n", "class TypingSpeedCalculator:\n", " def __init__(self):\n", " self.start_time = None\n", " self.end_time = None\n", " self.total_chars = 0\n", " self.typing_events = []\n", "\n", " def on_key_press(self, event):\n", " current_time = time.time()\n", " if not self.typing_events:\n", " self.start_time = current_time\n", " print(\"Rozpoczęto odliczanie...\")\n", "\n", " if self.typing_events and (current_time - self.typing_events[-1][1] > 5):\n", " self.start_time = current_time\n", " self.total_chars = 0\n", " print(\"Pauza...\")\n", "\n", " self.typing_events.append((event.name, current_time))\n", " self.total_chars += 1\n", "\n", " def calculate_speed(self):\n", " if not self.typing_events:\n", " return 0, 0\n", " \n", " self.end_time = time.time()\n", " total_time_minutes = (self.end_time - self.start_time) / 60\n", " total_words = self.total_chars / 6\n", " cpm = self.total_chars / total_time_minutes\n", " wpm = total_words / total_time_minutes\n", " return round(cpm, 2), round(wpm, 2)\n", "\n", " def start(self):\n", " print(\"Zacznij pisać. Gdy skończysz naciśnij 'esc'...\")\n", " keyboard.on_press(self.on_key_press)\n", " keyboard.wait('esc')\n", "\n", " cpm, wpm = self.calculate_speed()\n", " print(f\"Napisałeś: {cpm} na minutę, czyli {wpm} słów na sekundę!\")\n", "\n", "if __name__ == \"__main__\":\n", " calc = TypingSpeedCalculator()\n", " calc.start()\n", "\n", "# nie byłem wstanie uruchomić skryptu w pliku .ipynb" ] }, { "cell_type": "markdown", "id": "ceramic-birth", "metadata": {}, "source": [ "Wróćmy teraz do procesu tłumaczenia. Analiza uderzeń klawiszy wykonanych podczas tłumaczenia pozwala wykryć dłuższe pauzy. Pauzy te najczęściej wskazują miejsca, w których tłumacz musi się głębiej zastanowić nad tłumaczeniem danego słowa lub frazy. Przerwę tę wykorzystuje na przykład na sprawdzenie tłumaczenia lub definicji w słowniku, przeglądanie wyników z pamięci tłumaczeń lub korzystanie z innych pomocy (eye-tracking mógłby w tym przypadku rozstrzygnąć, czym w istocie zajmuje się w tym momencie tłuamcz). Jest też możliwe, że tłumacz poświęca pauzę na tzw. cognitive pause-and-unload - rodzaj zamyślenia, pozwalający oczyścić myśli. Z punktu widzenia projektowania systemu wspomagającego tłumaczenie niezwykle istotna jest informacja, nad czym tłumacz musi się dłużej zastanowić. Minimalizacja liczby i czasu trwania takich przerw jest szansą na usprawnienie procesu tłumaczenia." ] }, { "cell_type": "markdown", "id": "great-cable", "metadata": {}, "source": [ "### Ćwiczenie 3: Napisz program do wykrywania przerw w pisaniu. Raportuj długość oraz miejsce wystąpienia przerwy podając 20-znakowy kontekst z każdej strony. Wykryj każdą przerwę dłuższą niż 3 sekundy, posortuj wyniki malejąco po długości przerwy." ] }, { "cell_type": "code", "execution_count": 2, "id": "close-riverside", "metadata": {}, "outputs": [], "source": [ "import keyboard\n", "import time\n", "\n", "class TypingBreakDetector:\n", " def __init__(self):\n", " self.last_time = None\n", " self.typing_data = []\n", " self.breaks = []\n", "\n", " def on_key_press(self, event):\n", " current_time = time.time()\n", " character = event.name\n", "\n", " if self.last_time:\n", " break_length = current_time - self.last_time\n", " if break_length > 3:\n", " context_before = ''.join([ch[0] for ch in self.typing_data][-20:])\n", " self.breaks.append((break_length, len(self.typing_data), context_before))\n", "\n", " self.typing_data.append((character, current_time))\n", " self.last_time = current_time\n", "\n", " def report_breaks(self):\n", " self.breaks.sort(reverse=True, key=lambda x: x[0])\n", "\n", " for length, position, context_before in self.breaks:\n", " context_after_index = position + 20\n", " context_after = ''.join([ch[0] for ch in self.typing_data[position:context_after_index]])\n", " print(f\"Przerwa: {length:.2f} sekund\")\n", " print(f\"Tekst przed: '{context_before}' [przerwa] po '{context_after}'\")\n", " print(\"\")\n", "\n", " def start(self):\n", " print(\"Rozpoczęto detekcję przerw w pisaniu. Pisz cokolwiek i zatrzymaj się, aby zobaczyć wyniki.\")\n", " keyboard.on_press(self.on_key_press)\n", " keyboard.wait('esc')\n", "\n", "if __name__ == \"__main__\":\n", " detector = TypingBreakDetector()\n", " detector.start()\n", " detector.report_breaks()\n" ] } ], "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.11.0" }, "subtitle": "12. Key logging", "title": "Komputerowe wspomaganie tłumaczenia", "year": "2021" }, "nbformat": 4, "nbformat_minor": 5 }