Egy tizenkét éves kis projekt története (a BIRMA.NET-ről először, és őszintén szólva első kézből)

Valahol 2007 végén megfogalmazódott bennem kis ötletnek tekinthető ennek a projektnek a megszületése, aminek csak 12 évvel később volt a sorsa, hogy végleges formát találjon (természetesen ebben az időpontban, bár a jelenlegi megvalósítás, a a szerző számára nagyon kielégítő) .

Az egész úgy kezdődött, hogy a könyvtári akkori hivatali feladataim ellátása során felhívtam a figyelmet arra, hogy a könyv- (és zenei) kiadványok tartalomjegyzékeinek szkennelt szövegéből a meglévő adatbázisba történő adatbevitel folyamata, láthatóan jelentősen leegyszerűsíthető és automatizálható, kihasználva a rendezettség és a bevitelhez szükséges összes adat megismételhetőségének tulajdonságát, mint például a cikk szerzőjének neve (ha cikkgyűjteményről beszélünk), a cikk címe. a cikk (vagy a tartalomjegyzékben megjelenő alcím) és az aktuális tartalomjegyzék tétel oldalszáma. Eleinte gyakorlatilag meg voltam győződve arról, hogy az interneten könnyen megtalálható a feladat elvégzésére alkalmas rendszer. Amikor némi meglepetést okozott, hogy nem találtam ilyen projektet, úgy döntöttem, hogy megpróbálom egyedül megvalósítani.

Meglehetősen rövid idő elteltével elkezdett működni az első prototípus, amelyet azonnal elkezdtem használni a mindennapi tevékenységeim során, és ezzel párhuzamosan hibakeresést végeztem minden olyan példán, ami a kezembe került. Szerencsére a megszokott munkahelyemen, ahol korántsem programozó voltam, így is megúsztam a munkámban látható „leállásokat”, amelyek során intenzíven debuggoltam az agyszüleményemet - ami a jelenlegi valóságban szinte elképzelhetetlen, ami azt jelenti, napi jelentések a napközben végzett munkáról. A program csiszolásának folyamata összesen nem kevesebb, mint egy évig tartott, de még ezután sem lehetett teljesen sikeresnek nevezni az eredményt – kezdetben túl sok különböző koncepciót fektettek le, amelyek megvalósítása nem volt teljesen egyértelmű: választható elemek, amelyek kihagyják; elemek előre megtekintése (a korábbi elemek keresési eredményekbe való behelyettesítése céljából); akár saját kísérletünk is valami reguláris kifejezések megvalósítására (amelynek egyedi szintaxisa van). Azt kell mondanom, hogy ezt megelőzően valamelyest felhagytam a programozással (kb. 8 évre, ha nem többre), így teljesen lekötötte a figyelmemet az új lehetőség, hogy tudásomat egy érdekes és szükséges feladatban alkalmazzam. Nem meglepő, hogy az eredményül kapott forráskód - részemről a tervezés egyértelmű megközelítésének hiányában - meglehetősen gyorsan a C nyelv különböző darabjainak elképzelhetetlen összemosásává vált a C++ egyes elemeivel és a vizuális programozás szempontjaival (kezdetben ez volt). úgy döntöttek, hogy olyan tervezőrendszert használnak, mint a Borland C++ Builder - „majdnem Delphi, de C-ben”). Mindez azonban végül meghozta gyümölcsét könyvtárunk napi tevékenységének automatizálásában.

Ugyanakkor úgy döntöttem, hogy minden esetre részt veszek professzionális szoftverfejlesztők képzésére. Nem tudom, hogy ott valóban a nulláról lehet-e „programozónak” tanulni, de az akkori képességeimet figyelembe véve valamennyire elsajátíthattam az akkoriban relevánsabb technológiákat, mint pl. mint C#, Visual Studio .NET alatti fejlesztéshez, valamint néhány Java, HTML és SQL-hez kapcsolódó technológia. A teljes képzés összesen két évig tartott, és egy másik projektem kiindulópontjaként szolgált, amely végül több éven át húzódott – de ez egy külön kiadvány témája. Itt csak annyit illene megjegyezni, hogy a leírt projekten már meglévő fejlesztéseim adaptálására tettem kísérletet egy teljes értékű, a szükséges funkcionalitást megvalósító C# és WinForms nyelvű ablak alkalmazás létrehozására, és ennek alapján a közelgő diplomaterv.
Az idő múlásával ez az ötlet méltónak tűnt számomra, hogy hangot adjon az olyan éves konferenciákon, amelyeken különböző könyvtárak képviselői vettek részt, mint a „LIBKOM” és a „CRIMEA”. Az ötlet igen, de nem az én akkori megvalósításom. Aztán abban is reménykedtem, hogy valaki kompetensebb megközelítésekkel átírja. Így vagy úgy, 2013-ig úgy döntöttem, hogy az előkészítő munkámról beszámolót írok, és a konferencián való részvételre vonatkozó támogatási kérelemmel elküldöm a Konferencia Szervező Bizottságának. Némi meglepetésemre jelentkezésemet jóváhagyták, és elkezdtem néhány fejlesztést végrehajtani a projekten, hogy előkészítsem a konferencián való bemutatásra.

A projekt addigra már új BIRMA nevet kapott, különféle további (nem is annyira teljes körűen megvalósított, inkább vállalt) képességeket szerzett - minden részlet megtalálható a beszámolómban.

Őszintén szólva nehéz volt a BIRMA 2013-at teljesnek nevezni; Őszintén szólva, ez egy nagyon durva mesterség volt, amelyet sietve készítettek. A kód tekintetében gyakorlatilag semmi különösebb újítás nem történt, leszámítva azt a meglehetősen tehetetlen kísérletet, hogy valamiféle egységes szintaxist alkossunk az elemző számára, ami megjelenésében az IRBIS 64 formázási nyelvre (és tulajdonképpen az ISIS rendszerére is) emlékeztet - zárójelekkel ciklikus szerkezetként; miért Akkoriban azt hittem, hogy ez elég klassz). Az értelmező reménytelenül megbotlott ezekben a megfelelő típusú zárójeles körökben (hiszen a zárójelek más szerepet is betöltöttek, nevezetesen az elemzés során opcionális, átugorható szerkezeteket jelöltek meg). Ismét utalok akkori beszámolómra mindenkit, aki a BIRMA akkor még nehezen elképzelhető, indokolatlan szintaxisával szeretne részletesebben megismerkedni.

Általánosságban elmondható, hogy a saját elemzőmmel való küszködésemen kívül semmi mást nem tudok mondani ennek a verziónak a kódjával kapcsolatban - kivéve a meglévő források fordított átalakítását C++-ba, miközben megőrzi a .NET kód néhány jellemző tulajdonságát (hogy őszinte legyek, ez az nehéz megérteni, hogy pontosan mi késztetett arra, hogy mindent visszatoljak - valószínűleg valami hülye félelem, amiért titokban tartom a forráskódomat, mintha valami egyenértékű lenne a Coca-Cola titkos receptjével).

Talán ez az ostoba döntés is az oka annak, hogy milyen nehézségekbe ütközik az így létrejött DLL-könyvtár párosítása egy házilag készített munkaállomás meglévő interfészével az adatok elektronikus katalógusba történő bevitelére (igen, egy másik fontos tényt nem említettem: mostantól minden a BIRMA „motor” kódja az elvárásoknak megfelelő volt, le van választva az interfész részről, és a megfelelő DLL-be csomagolva). Miért kellett külön munkaállomást írni ezekre a célokra, amely egyébként a megjelenésében és a felhasználóval való interakció módjában szégyentelenül másolta az IRBIS 64 rendszer ugyanazt a „Katalogizáló” munkaállomást - ez egy külön kérdés. Röviden: megadta a kellő szilárdságot az akkori fejlesztéseimnek a diplomamunkámhoz (egyébként az emészthetetlen értelmező motor önmagában valahogy nem volt elég). Ezen kívül ezután némi nehézségbe ütköztem, amikor a Cataloger munkaállomás interfészét saját moduljaimmal implementáltam, C++-ban és C#-ban is, és közvetlenül hozzáfértem a motoromhoz.

Általánosságban elmondható, hogy furcsa módon a leendő BIRMA.NET meglehetősen ügyetlen prototípusa volt az, amely a következő négy évben a „munkalovam” lett. Nem mondható el, hogy ezalatt az idő alatt legalább nem próbáltam utat találni egy régóta fennálló ötlet új, teljesebb megvalósításához. Több újítás mellett kellett volna már beágyazott ciklikus szekvenciák, amelyek választható elemeket is tartalmazhattak volna – így akartam életre kelteni az univerzális sablonok ötletét a kiadványok bibliográfiai leírásához és sok más érdekességhez. Az akkori gyakorlati tevékenységem során azonban minderre kevés volt az igény, és az akkori megvalósítás bőven elegendő volt a tartalomjegyzékek beírásához. Emellett könyvtárunk fejlődési vektora egyre inkább a múzeumi archívumok digitalizálása, tudósítások és egyéb, számomra kevéssé érdeklő tevékenységek irányába kezdett elkanyarodni, ami végül arra kényszerített, hogy végre elhagyjam, helyet adva azoknak, akik örülj ennek az egésznek.

Paradox módon ezek után a drámai események után úgy tűnt, hogy a BIRMA projekt, amely akkor már egy tipikus hosszú távú építési projekt minden jellegzetességével rendelkezett, elkezdte felvenni régóta várt új életét! Több szabadidőm maradt a tétlen gondolatokra, újra elkezdtem fésülni a világhálót valami hasonló után (szerencsére most már sejtettem, hogy mindezt nem csak bárhol, hanem a GitHubon keresem), és valahol a ez év elején végre rábukkantam egy megfelelő termékre a jól ismert Salesforce cégtől jelentéktelen néven Gorp. Önmagában szinte mindent meg tud tenni, amire szükségem volt egy ilyen elemző motortól - nevezetesen intelligensen elkülönítheti az egyes töredékeket tetszőleges, de jól strukturált szövegtől, miközben meglehetősen felhasználóbarát felülettel rendelkezik a végfelhasználó számára, beleértve az olyan érthető esszenciákat, mint pl. mintát, sablont és előfordulást, egyúttal a reguláris kifejezések megszokott szintaxisát használva, ami összehasonlíthatatlanul olvashatóbbá válik az elemzésre kijelölt szemantikai csoportokra való felosztás miatt.

Általában úgy döntöttem, hogy ez az Gorp (Kíváncsi vagyok, mit jelent ez a név? Talán valami „általános irányultságú szabályos értelmező”?) – pontosan az, amit régóta keresek. Igaz, a saját igényeimre való azonnali megvalósítása olyan problémát okozott, hogy ez a motor túlságosan szigorúan követte a forrásszöveg szerkezeti sorrendjét. Egyes jelentésekhez, például naplófájlokhoz (nevezetesen a fejlesztők a projekt használatának egyértelmű példájaként helyezték el őket), ez teljesen megfelelő, de a beolvasott tartalomjegyzékek ugyanazon szövegei esetében ez nem valószínű. Hiszen ugyanaz az oldal tartalomjegyzékkel kezdődhet a „Tartalomjegyzék”, „Tartalom” szavakkal és minden olyan előzetes leírással, amelyet nem kell elhelyeznünk a tervezett elemzés eredményei között (és kézzel levágva). minden alkalom szintén kényelmetlen). Ezenkívül az egyes ismétlődő elemek, például a szerző neve, címe és oldalszáma között az oldal tartalmazhat bizonyos mennyiségű szemetet (például rajzokat és csak véletlenszerű karaktereket), amit szintén jó lenne levág. Az utolsó szempont azonban még nem volt annyira jelentős, de az első miatt a meglévő implementáció nem tudta egy bizonyos helyről elkezdeni keresni a szövegben a szükséges struktúrákat, hanem a kezdetektől egyszerűen feldolgozta, nem találta meg a meghatározott mintákat ott, és... befejeztem a munkámat. Nyilvánvalóan szükség volt némi módosításra, hogy legalább egy kis helyet hagyjunk az ismétlődő struktúrák között, és ez visszavitt a munkába.

A másik probléma az volt, hogy magát a projektet Java nyelven valósították meg, és ha a jövőben terveztem, hogy valamilyen módon összekapcsoljam ezt a technológiát ismert alkalmazásokkal a meglévő adatbázisokba való adatbevitelhez (például Irbis „Cataloguer”), akkor legalább legalább csináld ezt C#-ban és .NET-ben. Nem arról van szó, hogy maga a Java rossz nyelv – egyszer még egy érdekes ablakos alkalmazás megvalósítására is használtam, amely egy hazai programozható számológép funkcionalitását valósította meg (egy tanfolyami projekt részeként). És szintaktikailag nagyon hasonlít ugyanarra a C-sharpra. Nos, ez csak egy plusz: annál könnyebb lesz befejeznem egy meglévő projektet. Nem akartam azonban újra belecsöppenni az ablakos (vagy inkább asztali) Java-technológiák ebbe a meglehetősen szokatlan világába - elvégre maga a nyelv nem volt „szabva” ilyen használatra, és egyáltalán nem vágytam az ismétlésre. a korábbi tapasztalat. Talán éppen azért, mert a C# a WinForms-szal együtt sokkal közelebb áll a Delphi-hez, amellyel egykoron sokan kezdtük. Szerencsére elég gyorsan megtalálták a szükséges megoldást – a projekt formájában IKVM.NET, amely megkönnyíti a meglévő Java programok felügyelt .NET kódba való lefordítását. Igaz, magát a projektet addigra már felhagyták a szerzők, de a legújabb megvalósítása lehetővé tette, hogy a forrásszövegekhez szükséges műveleteket meglehetősen sikeresen elvégezzem. Gorp.

Így aztán elvégeztem az összes szükséges változtatást, és az egészet összeállítottam egy megfelelő típusú DLL-be, amelyet a Visual Studióban létrehozott .NET-keretrendszer bármely projektje könnyen „felvehetett”. Közben létrehoztam egy másik réteget a visszaküldött eredmények kényelmes bemutatására Gorp, megfelelő adatstruktúrák formájában, amelyeket kényelmes lenne táblázatnézetben feldolgozni (sorokat és oszlopokat egyaránt alapul véve; szótári kulcsokat és numerikus indexeket egyaránt). Nos, maguk az eredmények feldolgozásához és megjelenítéséhez szükséges segédprogramok meglehetősen gyorsan megíródtak.

Nem okozott különösebb bonyodalmat a tartalomjegyzékek beolvasott szövegeinek meglévő mintáinak elemzésére való megtanítása céljából az új motorhoz szükséges sablonok adaptálásának folyamata sem. Valójában egyáltalán nem is kellett hivatkoznom a korábbi sablonjaimra: egyszerűen elkészítettem az összes szükséges sablont a semmiből. Sőt, ha a rendszer előző verziójával való együttműködésre tervezett sablonok meglehetősen szűk keretet szabnak a segítségükkel helyesen értelmezhető szövegeknek, az új motor már lehetővé tette, hogy meglehetősen univerzális sablonokat fejlesszenek ki, amelyek többféle jelölésre alkalmasak. egyszer. Megpróbáltam bármilyen átfogó sablont írni bármilyen tetszőleges tartalomjegyzék szöveghez, bár természetesen még akkor is, ha minden új lehetőség megnyílik előttem, beleértve különösen az azonos beágyazott ismétlődő sorozatok megvalósításának korlátozott lehetőségét ( mint például több szerző vezetékneve és kezdőbetűje egymás után), ez utópiának bizonyult.

Talán a jövőben megvalósítható lesz a metasablonok egy bizonyos koncepciója, amely képes lesz ellenőrizni, hogy a forrásszöveg megfelel-e több rendelkezésre álló sablonnak egyszerre, majd a kapott eredményeknek megfelelően kiválasztja a a legalkalmasabb, valamilyen intelligens algoritmus segítségével. De most jobban foglalkoztatott egy másik kérdés. Olyan elemző, mint Gorp, minden sokoldalúsága és az általam végrehajtott módosítások ellenére eredendően még mindig képtelen volt egyetlen egyszerűnek tűnő dolog megtételére, amire a magam által írt elemzőm már az első verziótól kezdve képes volt. Mégpedig: képes volt megtalálni és kivonni a forrásszövegből minden olyan töredéket, amely megfelel a megfelelő helyen használt sablonon belül megadott maszknak, miközben egyáltalán nem érdekelte, mit tartalmaz az adott szöveg a töredékek közötti szóközökben. Eddig csak kis mértékben javítottam az új motoron, lehetővé téve, hogy a jelenlegi pozícióból megkeresse az ilyen maszkok adott sorozatának minden lehetséges új ismétlését, lehetővé téve, hogy a szövegben tetszőleges karakterkészletek jelenjenek meg, amelyek teljesen nem veszik figyelembe az elemzésben, a detektált ismétlődő struktúrák közé zárva. Ez azonban nem tette lehetővé a következő maszk beállítását, függetlenül attól, hogy az előző töredéket a megfelelő maszk segítségével kerestük: a leírt szövegstruktúra szigorúsága továbbra sem hagyott teret szabálytalan karakterek önkényes beillesztésére.

És ha a tartalomjegyzék példáinál, amelyekkel találkoztam, ez a probléma még nem tűnt olyan súlyosnak, akkor amikor egy új elemzési mechanizmust próbálunk alkalmazni egy hasonló feladatra, egy webhely tartalmának elemzésére (vagyis ugyanazon elemzésre), a korlátai itt jelentek meg teljes nyilvánvalóságukkal. Végtére is, elég egyszerű beállítani a szükséges maszkokat a webes jelölés töredékeihez, amelyek között a keresett adatoknak kell elhelyezkedniük (amelyeket ki kell bontani), de hogyan kényszeríthetjük rá az elemzőt, hogy azonnal lépjen a következőre hasonló töredék, a köztük lévő szóközökbe elhelyezhető összes lehetséges tag és HTML attribútum ellenére?

Kis gondolkodás után úgy döntöttem, bevezetek néhány szolgáltatási mintát (%all_efore) и (%all_after), ami azt a nyilvánvaló célt szolgálja, hogy biztosítsa, hogy minden, ami a forrásszövegben található, kihagyásra kerüljön az őket követő minták (maszkok) előtt. Sőt, ha (%all_efore) egyszerűen figyelmen kívül hagyta ezeket az önkényes zárványokat (%all_after), éppen ellenkezőleg, lehetővé tette, hogy hozzáadják őket a kívánt töredékhez, miután elmozdultak az előző töredékről. Elég egyszerűen hangzik, de ennek a koncepciónak a megvalósításához újra át kellett fésülnöm a gorp forrásokat, hogy megtegyem a szükséges módosításokat, nehogy megtörjem a már megvalósított logikát. Végül ezt is sikerült megcsinálnunk (bár még az elemzőm legelső, bár nagyon hibás implementációja is megíródott, sőt még gyorsabban is - pár hét alatt). Mostantól a rendszer valóban univerzális formát öltött – nem kevesebb, mint 12 évvel a működésre tett első kísérletek után.

Persze álmainknak ezzel még nincs vége. A gorp sablon elemzőt teljesen átírhatja C# nyelven is, bármelyik elérhető könyvtár használatával egy szabad nyelvtan megvalósításához. Úgy gondolom, hogy a kódot jelentősen le kell egyszerűsíteni, és ez lehetővé teszi számunkra, hogy megszabaduljunk az örökségtől a meglévő Java források formájában. De a meglévő típusú motorral nagyon sok érdekes dolgot lehet csinálni, beleértve a már említett meta-sablonok megvalósításának kísérletét, nem beszélve a különféle webhelyekről származó adatok elemzéséről (de nem tartom kizártnak hogy a meglévő speciális szoftvereszközök erre alkalmasabbak – csak még nem volt megfelelő tapasztalatom ezek használatáról).

Egyébként idén nyáron már kaptam egy meghívót e-mailben egy Salesforce technológiákat használó cégtől (az eredeti fejlesztője Gorp), adjon interjút a későbbi rigai munkához. Sajnos jelenleg nem vagyok kész az ilyen átcsoportosításokra.

Ha ez az anyag felkelt némi érdeklődést, akkor a második részben megpróbálom részletesebben leírni a sablonok összeállításának és utólagos elemzésének technológiáját a Salesforce-ban használt implementáció példáján keresztül. Gorp (a saját kiegészítéseim, néhány már leírt függvényszó kivételével gyakorlatilag nem változtatnak magán a sablon szintaxison, így szinte az összes dokumentáció az eredeti rendszerhez Gorp Az én verziómhoz is megfelelő).

Forrás: will.com

Hozzászólás