Автор Тема: Двупосочен английско-български речник с python 3  (Прочетена 1349 пъти)

rado84

  • Напреднали
  • *****
  • Публикации: 112
  • Window Manager: Cinnamon
    • Профил
Интересно! Въобще не очаквах да има такива или изобщо някакви отговори по темата, очаквах само анатеми и псувни. Което напоследък се е превърнало в стандарт в линукс общността и затова първоначално въобще не бях сигурен струва ли си да пускам тема тук. Защото някой иска помощ за нещо, даваш му я и вместо да каже поне едно "благодаря", почва да те псува и с "ти ли ще ми кажеш как да правя нещата?". И като види, че не му стига мозък да се справи сам, се връща за още помощ, сякаш си му длъжен с нещо, ама помагащият кораб вече е потънал. И естествено след няколко такива "срещи" започваш да се чудиш има ли смисъл да споделяш каквото и да било, където и да било или да си запазиш нещата за себе си, а останалите да ги оставиш да си трòшат главите...

Но... недоволни винаги ще има (за тях имам два крачола), а в крайна сметка направих програмката за себе си, защото KBGOFFICE е на последни издихания и е въпрос на време въобще да спре да тръгва. Едната фолбек GTK2 библиотека вече сдаде багажа и няма замяна, а кога и приложените към КБГОФИС qt4 библиотеки също ще бъдат пратени на майната им - също не се знае.

Сорсът е в .py файла. Нарочно не съм го компилирал - прави редакцията и тестването на код по-лесно. Ако някой толкова държи на бинарен файл, да си го компилира сам.

Относно ИИ - ИИ ми даде код за съвсем друга програма, която няма нищо общо с този речник. После видях, че мога да използвам онази програма като темплейт за речника. Единственото, което ИИ написа изцяло, беше кода за прочитане на '.dat' файловете, защото видях голям зор с тях. Оригинално са краднати от някакъв уиндоуски речник в средата на 90-те и постепенно са били допълвани с нови думи. Последното допълване е било през 2014-та от разработчиците на КБГОФИС.

Ако исках да лъжа и да се преструвам на програмист, нямаше изобщо да спомена ИИ и щях да си припиша заслугите, както правят тия от КДЕ. А истината е, че просто се опитвам да поддържам живо нещо, което е почти умряло и го правя с много малкото, което разбирам от програмиране, в т.ч. и от Питон.

За кодировката: в момента в кода има това:

Код:
        try:
            text = part.decode("utf-8")
        except:
            text = part.decode("cp1251", errors="ignore")

и работи. Защото не е ясно каква им е кодировката на тези файлове и за по-сигурно ИИ добави тази част, за да е сигурно, че текстът ще излезе като текст, а не като марсиански символи. A пък командата "file en-bg.dat" връща просто "data" и толкоз.
Като го направя с редакцията, която някой предложи няколко поста по-нагоре, програмата изобщо не иска да тръгне, така че за момента ще я оставя с "try-except" блока.

Първоначалният вариант на програмата беше да търси с натискането на всеки клавиш - както КБГ и както "SA Dictionary 2012" за уиндоус, но това караше програмата да се забавя и накрая просто да крашва, така че се наложи да сменя кода и да го направя да търси, едва след като напишеш думата и натиснеш ентър.

Не принуждавам никого да ползва този речник, просто реших да споделя нещо, което работи и което може да е полезна алтернатива на почти умряла програма.

И НЕ - НЕ СЪМ ПРОГРАМИСТ, НИКОГА НЕ СЪМ ТВЪРДЯЛ, ЧЕ СЪМ ТАКЪВ!
Щях да бъда, но некадърни учители ме отказаха преди години и започнах сам да си се уча "оттук, оттам" по малко.

А това да кажеш, че ИИ е написал целия код е глупост. Все едно да кажеш, че ИИ е написал всичките ми скриптове, което не е така. ИИ просто ми обясни какво е променлива в bash script и как се използва, оттам нататък всичките близо 300 скрипта, които събрах в кейс скриптове, са си изцяло мое творение и пригодени за автоматизация в моята система.

Целият код на съвсем друга програма беше написан от ИИ - програма, чиято функция е просто да покаже данни на екрана. За речника използвах готовия код като темплейт и започнах да го променям, за да стане за речника. Играх си почти цяла седмица с копиране и нагаждане на код, за да стане това, което е сега. Но с четенето на дат файловете не успях да се справя и затова трябваше да питам ИИ как да стане. Именно тази дълга играчка беше причината да го оставя некомпилиран - просто променяш кода и го пускаш, вместо да си губиш времето с компилиране и после тестване. Освен това - какво по-opensource от това да го оставиш некомпилирано? :)
Активен

RESIST OS Cinnamon; Core i7-12700F; RTX 3070 Ti 8 GiB, 62.62 GiB DDR5-4800 (5200).

4096bits

  • Напреднали
  • *****
  • Публикации: 9225
    • Профил
Редакцияна на програмата работи при мен. Променен е само файла за GTK.
Няма причина да не работи, защото допълнителния код не прави никакви съществени изменения в логика или нещо такова.
Само заменя едни символи с други.

Транскрибирането няма да работи коректно, защото не съм въвел всички символи по IPA в mapping.
Просто трябва да се допълнят и останалите.
Въведени са само тези, които бяха в кода на оригиналната програма.
Изрових кода ѝ от Sourceforge.

За да не вкарат всички символи за транскрипцията, предполагам че просто използват такива от ascii или cp1251 които приличат на външен вид.
Дано да са ascii, че ако има cp1251 символи в транскрипцията, това биха се заменили навсякъде и малко се усложняват нещата.

.dat файла има проста структура и да се направи нещо да се допълва с нови думи, няма да е сложно.

Иначе изрових всички символи, които се ползват в транскрипцията.
То има и още, но са за други езици.
Тези, които се ползват от нас са ай тия:

[iː ɪ e æ ɑː ɒ ɔː ʊ uː ʌ ɜː ə e aɪ ɔɪ əʊ aʊ ɪə eə ʊə θ ð ʃ ʒ tʃ dʒ ŋ ɑ ɒ ʌ ə ˈ ˌ ː]
Тук са показани и двойните, но това няма много значение - копирах всичко.

Може да се допълнят липсващите в mapping от променения код, който предложих, когато се установи дума, в която все още се появяват странни символи в транскрипцията.

Другия начин е да се парсне речника и да се подмени изцяло траскрипцията със съответната за думата.

В интернет има много ресурси в различни формати, с думи и транкрипцията към тях.
Като тук например: https://github.com/open-dict-data/ipa-dict

Ако се прави това, може направо и целия .dat файл да се конвертира до UTF-8 и да се приключи с ненужната гимнастика.


Да уточня, че кода, който дадох е само на една от функциите в целия файл на  Python от GTK версията.
В нея е добавена тази таблица, която нарекох mapping и е променен последния ред в тази част:
Код:
try:
            text = part.decode("utf-8")
        except:
            text = part.decode("cp1251", errors="ignore")
« Последна редакция: Mar 09, 2026, 01:32 от 4096bits »
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

rado84

  • Напреднали
  • *****
  • Публикации: 112
  • Window Manager: Cinnamon
    • Профил
На мен повече ми се иска да намеря начин да конвертирам .дат файловете към по-модерен и четим формат - я обикновен .txt, я .json от въпросния open-dict или дори sqlite db, ако щеш. Въпросът е да е нещо лесно за редакция и допълване с нови думи и/или изрази. Засега обаче всичките ми търсения се провалят, но не защото няма възможни предложения как да стане, а защото самото конвертиране се проваля - на инструментите не им харесва скапаният .дат формат.

Транскрипцията не съм я и поглеждал даже да я оправям, защото я знам. Речника го ползвам единствено за проверка на правописа на някои думи, които до ден днешен ми "бъркат в мозъка" с изкецания си правопис, като например "hypocrisy" или пък тази, която няма запомняне и винаги трябва да я копирам: "unconsciousness". Знам как се произнаят и двете, и всички останали, просто на някои правописът им ми е труден и затова ми трябва локален речник като моя или като КБГ.

Но... ако намеря начин да конвертирам речниците към нормален формат без да трябва да преписвам дума по дума, то и транскрипцията ще може да се оправи и поддържа.

Edit: разбрах защо не искаше да тръгва с твоя код и се учудвам, че при теб изобщо е тръгнало!

Python не приема / или // за коментари. Приема единствено # за коментари.
И сега, след като го поправих и махнах коментарите ти, ето какво излиза в транскрипцията:



90% от bash скриптовете, които си пиша, са на python и покрай тях научих някои тънкости на Питоня, като например това, че е много капризен на тема отстъпи и ако не внимаваш, е*аваш майката на скрипта. И по принцип в Python правилният отстъп е 4 символа (интервала). Ако имаш цикъл с for loop, командата в луупа трябва да е с отстъп 8 интервала, иначе забрави да тръгне.  ;D

Edit 2: трябваше да добавя още мапинг, за да започне да излиза както трябва. Добавих

Код:
"ў": "ə",

и сега вече "transfer" излиза с правилна транскрипция:

Код:
[træns'fə:]

Явно, че и на тази програма ще трябва да направя релийзи в гитхъб и след малко се захващам с това. Версия 0.0.2 е тази с твоя код и добавения от мен мапинг. Но първо трябва да видя дали този код ще работи в Qt версиите.

Edit 3: айде, вече си има и релийзи!  ;D
https://github.com/rado84-github/2-way-dictionary/releases
« Последна редакция: Mar 09, 2026, 05:36 от rado84 »
Активен

RESIST OS Cinnamon; Core i7-12700F; RTX 3070 Ti 8 GiB, 62.62 GiB DDR5-4800 (5200).

4096bits

  • Напреднали
  • *****
  • Публикации: 9225
    • Профил
Споделил си публично програмата в GitHub и се опитваш да я спасиш.
Добре ще е, транскрипцията да си е наред, ако ще я ползва и някой друг.


Хубаво е, че понаучаваш Питоня.
Улеснява живота.
Това, което аз направих си е вградена функционалност към инструментите за манипулиране стрингове в Python - на текст.

Относно конвертирането до JSON или в нещо друго...
Ами, ако искаш да е четимо, почти няма нещо друго.

Впрочем, ти почти си го направил.
Разделил си .dat файла на парчета (думи, заедно с превод), след това разделяш думата от превода.

Тук може да се направят вече две неща.

Да се създаде празен речник на Python. Този тип за данни с ключ/стойност. На други езиси го наричат hash table, map, object, hash map, table.
Та, да се вкара думата като 'key', а превода като 'value' на този речнки.
Прави се това в цикъла, който в момента съществува.
След като се парсне целия файл, имаш един голям dict на Python, който просто превръщаш в JSON и го хвърляш във файл.
Това е просто конвертиране от формата в .dat файла, в JSON

Второто нещо, което може да се направи вместо първото ми предложение е, да се направи както си трябва с този JSON.
Целия JSON обект да има едно поле, в което се указва езика, а под него данните. Те да включват и отделно поле за транскрипцията.

Например:
Код:
{
"language": "en-bg",
    {
    "word": "plank",
        {
        "transcription": "[plæŋk]",
        "translation": "Текста на превода"
        }
    },
    ...,
    ...,
}

Бях погледнал, колко са думите в двата .dat файла.
Едното файлче беше 43,000+ или 46,000+, другия беше към 48,000+ думи.
Не съм работил с големи по размер JSON файлове, но зная, че са бавни за обработка. Не съм сигурен, дали и тези са големи.
Зная, че се обработват и 1000 пъти по толкова. ;D
В Python ще са превърнати в dict обекти и това може и да помогне за бързината на търсене. Може би.

Оптималния вариант би било бази данни (sqlite3 нарпимер), защото са оптимизирани за търсене, заемат по-малък обем на диска, обаче не са четими. За въвеждане на дума и попълване на речника, ще трябва да се създаде и съответната функционалност директо в програмата или на ръка да си вкарваш данните през конзолата и интерфейса на sqlite3.

Другото е, че ще трябва да се преправи и системата за търсене.
Да се имплементира fuzzy find за въпросния dict.
Нещо като тава би работило:
Код:
for word in dict.kays():
    if "plank" in word:
        <добавяне на 'plank' към листа с намерени думи>

Може да има и по-бързи начини, не зная. Някой професионален програмист, ако им тук, да каже.

sqlite3 си има вградена функционалност за такъв тип търсене, но както се видя, не е никак сложно да се направи и за текстов обект, какъвто е JSON (dict obect в Python).


Погрешно го нарекох, като fuzzy find. Направо се търсят точни съвпадения.
« Последна редакция: Mar 09, 2026, 12:58 от 4096bits »
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

4096bits

  • Напреднали
  • *****
  • Публикации: 9225
    • Профил
Има някаква билиотека за определяне на кодировката.
Не съм я пробвал досега.

charset_normalizer
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

rado84

  • Напреднали
  • *****
  • Публикации: 112
  • Window Manager: Cinnamon
    • Профил
JSON го дадох просто като пример за нещо различн от дат, което да може да се отвори и с текстов редактор. Мисля да се хвана да инсталирал някоя лайт БД, за да видя кое как става (досега не ми се беше налагало да работя с БД и затова не знам как става). Идеята е речникът да е максимално лесен за редакция и по възможност с малък брой скобички и подравнявания, че там ако объркаш подравняването (както и в Питон), е*аваш макята на всичко и после ходѝ намирай проблема.

А "спасяване"... не бих го нарекъл така. По-скоро поддържане работещо. Защото с КБГ-то ми писна кажи-речи всяка година да си играя на котка и мишка с библиотеките, които непрекъснато отпадат от употреба и после са трудни или невъзможни за намиране. С GTK3 поне съм се подсигурил за много дълго време, а за QT5/6 имам един познат, който е по-навътре с този фреймуърк и когато може, помага с конвертирането на кода от GTK към QT. Което от друга страна означава, че ако някой ден той каже, че не може повече или че изобщо няма да се занимава с кодене, QT версиите ще останат "заседнали" във времето, докато GTK ще продължи да бъде поддържана. В такъв случай ще се наложи или да намерим някой от общността да конвертира от GTK към QT, или да прибягвам до AI. Последното ще е само много краен случай, ако няма друг начин. Щот' нали на Уиндоус 11 кода му го пише AI (поне така казват), а всички знаем до какво доведе това.  ;D 
Активен

RESIST OS Cinnamon; Core i7-12700F; RTX 3070 Ti 8 GiB, 62.62 GiB DDR5-4800 (5200).

remotexx

  • Напреднали
  • *****
  • Публикации: 5390
    • Профил
А бе що не се пробвате и на Пърл  ;D
https://www.youtube.com/watch?v=RCHhAEjEjKw
Активен

4096bits

  • Напреднали
  • *****
  • Публикации: 9225
    • Профил
А бе що не се пробвате и на Пърл  ;D
https://www.youtube.com/watch?v=RCHhAEjEjKw
Кой тук имаше подпис, който казваше, че Perl бил единствения език, който изглеждал еднакво преди и след криптиране на кода? :D

Форума ни не се ли обръщаше към нещо на Perl?
« Последна редакция: Mar 10, 2026, 06:53 от 4096bits »
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

4096bits

  • Напреднали
  • *****
  • Публикации: 9225
    • Профил
Снощи преди да си легна набързо сглобих това.
Превръща .dat файла в json.

Но изглежда почти половината думи са без транскрипция или аз нещо не правя, както трябва.
Защото скрипта елиминира напълно всичко между [ и ], както ние пишем транскрипцията и търси думата във външен файл и заменя транскрипцията направо.

Ако във външния файл думата не е намерена, транскрипция за нея няма да бъде записана в новия файл.

Един начин да се избегне това, ако оригиналната транскрипция е налича в .dat файла, е да се използва предишния метод - подмяна на символите, както беше направено в примера в някой от предишните постове.
За това обаче, ще трябва да се въведат в mapping абсолютно всички символи, за да е коректно всичко и съответно, това да се добави към скрипта, където трябва.

Външния файл, в който се търси за транскрипция на думата е взет от https://github.com/open-dict-data/ipa-dict/releases/tag/1.0
Името му е директно вписано в скрипта и си го търси в текушата директория на скрипта.
Нарочно го направих така, вместо да се дава като параметър, защото второто може просто да не проработи - ако се зададе друг json файл, може да е форматиран по друг начин, с други ключове и да не го прочете изобщо.
Ако се подменя с по-пълен файл, трябва да се подменят и съответните ключове във функция search_pro в началото на скрипта.

Друг вариант да се въведе транскриция за всяка дума, е да се пита в интернет в някой сайт за това.
Можех да го пробвам, но не ми се занимаваше, че исках да си лягам.
Там можеше да се сблъскам и с проблеми с блокаж на IP адреса ми, ако ги ударех с 20 000+ заявки.

Скрипта се стартира с: python dat2json.py en-bg.dat
Скриптчето не прави никакви проверки, дали файла (en-bg.dat) съществува или пък някакви други, за коректност на подадените параметри.
Той параметъра е само един - името на dat файла.

Същия скрипт може да се ползва и за bg-en.dat, като се махне/коментира напълно частта, която търси за транскрипция и съответния ключ в променливата new_record.

Код:
import json
import re
import sys
from pathlib import Path

dat_file = Path(sys.argv[1]).resolve()


def search_pron(word, data_file):
    try:
        pron = data_file["en_UK"][0][word.lower()]
        return f"[{pron.strip('/')}]"
    except KeyError:
        return ""


def to_json(dat_file):
    with open(dat_file, "rb") as dat:
        data = dat.read()

    # en_UK.json от https://github.com/open-dict-data/ipa-dict/releases/tag/1.0
    # може да се замени с ne_US.json за американско произношение
    with (
        open("en_UK.json", "r") as transcriptions,
        open(f"{dat_file.parent}/{dat_file.stem}.json", "w") as result,
        open("no_transription.txt", "w") as missing,
    ):
        records = data.split(b"\x00")  # взето от GTK3 версията на програмата
        words = len(records)
        print(f"Words in {dat_file.name}: {words}")

        transcr = json.load(transcriptions)
        new_data = {dat_file.stem: list()}

        counter = 1
        no_pron = 0
        # transcr_pn = re.compile(r"\[.*?\]") # "\[[^\]]*\]"
        transcr_pn = re.compile(r"\[[^\]]*\]")  # r'\[.*?\]'
        for record in records:
            # взето от GTK3 версията на програмата
            if not record:
                continue

            record = record.decode("cp1251", errors="ignore")

            # взето от GTK3 версията на програмата
            if "\n" not in record:
                continue

            pron = ""

            if transcr_pn.search(record):
                word, translation = record.split("\n", 1)
                translation = transcr_pn.sub("", translation).strip()
                pron = search_pron(word, transcr)
            else:
                word, translation = record.split("\n", 1)
                pron = search_pron(word, transcr)

            if not pron:
                missing.write(f"{pron}\n")
                no_pron = no_pron + 1

            new_record = {word: {"transcription": pron, "translation": translation}}

            new_data[dat_file.stem].append(new_record)

            print(f"\rProcessed: {counter}/{words}", end="")
            counter = counter + 1

        json.dump(new_data, result, ensure_ascii=False, indent=2)

        print("\n\nDone!")
        print(f"Words without transcription: {no_pron}")
        print("List available in no_transription.txt")


if __name__ == "__main__":
    to_json(dat_file)
« Последна редакция: Mar 14, 2026, 21:51 от 4096bits »
Активен

As they say in Mexico, "Dasvidaniya!" Down there, that's two vidaniyas.

rado84

  • Напреднали
  • *****
  • Публикации: 112
  • Window Manager: Cinnamon
    • Профил
Аз пък през последната седмица спя макс по 4 чàса (няма някаква конкретна причина), мозъкът ми е на каша и отказва да работи, така че това с конвертирането ще го мисля, ако или когато мозъкът ми се оправи.
Активен

RESIST OS Cinnamon; Core i7-12700F; RTX 3070 Ti 8 GiB, 62.62 GiB DDR5-4800 (5200).

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
Запис на файл във цикъла (не селед изпълнението му) Python
Общ форум
NikolaiTalev 2 6315 Последна публикация May 19, 2014, 10:41
от NikolaiTalev
Едно питане за python
Web development
korea60 11 11545 Последна публикация Jul 05, 2014, 11:06
от zxz
Python и неволи с форматиране на дата
Web development
runtime 0 3674 Последна публикация Oct 23, 2014, 18:11
от runtime
Python GIL
Общ форум
4096bits 1 2655 Последна публикация Oct 26, 2015, 17:51
от gat3way
Искам да се зарежда python 3.7 вместо python 2.7
Web development
3p0 36 41298 Последна публикация Dec 27, 2019, 00:49
от 4096bits