momente şi schiţe de informatică

contact:

Jurnal //docere.ro - actualizări, explicitări, istoric

oct/2014

Lucrând la Reformularea orarului generat de "asc-orare", cu Python și Sphinx am descoperit că multe școli își postează orarul ca fișier SWF (application/vnd.adobe.flash.movie); dar SWF vizează grafica vectorială, realizarea animațiilor, a jocurilor "prin Internet", a filmelor și rulează în browser prin intermediul unor anumite programe externe (Adobe Flash Player).

Prezentarea orarului are menirea evidentă, de a furniza informații utile celor interesați; în mod firesc, trebuie să ai posibilitatea de a identifica informația care interesează, de a o extrage (măcar prin procedeul elementar, Copy&Paste) și chiar de a o refolosi. O poză, sau un "movie" - nu-ți poate oferi decât posibilitatea de a admira "informația" pe ecran, sau pe hârtie.

Este drept pe de altă parte, că "utilizatorii" sunt în general nepretențioși, fiind atrași mai degrabă de grafică, de animație și de zorzoane, decât de "informație"; și mai sunt și tributari obișnuinței: dacă el știe "Microsoft Word", ba chiar și "Adobe Photoshop" și "PageMaker" - fii deștept și ferește-te de încercarea de a-l "învăța" să construiască un site folosind un editor de text (nu "Microsoft Word"), vreun limbaj de marcare și câte mai trebuie… îi ajung butonașele, iconițele, meniurile și mouse-ul - prin care poate simula că ar ști să citească și să scrie, sau că gândește.

Bineînțeles că piața încurajează perfid (prin orice mijloace) aceste obișnuințe, sesizând foarte exact de unde poate să iasă cât mai ușor banu'. Iar firmele care prin produsele oferite îți ușurează munca - "dă din mouse, n-ai nevoie să gândești sau să înveți ceva" - au și depistat punctele cheie care le pot asigura dominarea cu profit a cât mai multor generații de utilizatori: guvernul țării respective, care decide și impune "strategia de informatizare" a societății, adică a instituțiilor (și aici, firmele de software au noroc: guvernul conține juriști, istorici și alții, iar "consilieri pe informatică" se pot alege în mod convenabil); iar al doilea punct cheie este ministerul care prin programe școlare (coroborate desigur, cu măsuri temeinice precum instituirea examenului de "competențe digitale pentru conducerea calculatorului"), decide și girează "strategia de informatizare" în domeniul învățământului (și iarăși… firmele respective au foarte mult noroc!).

Ne-am înglodat până la urmă într-o capcană comercială fără speranță, devenind utilizatorii fideli ai clonelor specifice Microsoft, înlocuind adevărata informatică prin știința "point-and-click" (și "crack"). Toți am auzit de Bill Gates și foarte puțini, de Ken Thompson (nu mai dăm alte exemple); dar acest raport este foarte strâmb dacă vizăm dezvoltarea informaticii ca știință (clamând învățământ "de calitate"), în loc de a miza pe aspectele mercantile, cu dedesubturile specifice.

iul/2013 - sep/2014

Ce este edu.ro? Elementul <title> al paginii de bază indică www.edu.ro :: Ministerul Educaţiei Naţionale, iar oficialitățile îi zic: "site-ul Ministerului Educației Naționale". Noi constatăm însă că - în esență - este doar un depozit de documente oficiale; click pe un link oarecare de pe "site" îți oferă posibilitatea să descarci documentul vizat - fie un fișier produs cu Microsoft Word, fie un fișier PDF (fie o arhivă de asemenea documente), destinat în orice caz să fie tipărit ca atare pe hârtie.

În 2007 și 2009 s-au înființat CNCEIP și a C.N.E.E.; prima operă a acestor comisii de specialiști a constat în constituirea și depunerea pe site-ul respectiv, a unor seturi de câte 100 de variante de subiecte de bacalaureat (pentru diversele discipline), fiecare "variantă" constând din vreo trei fișiere PDF (câte unul pentru fiecare subiect dintre cele trei care o compun). Fișierele respective au fost preluate apoi și comasate pe diverse site-uri mai mult sau mai puțin oficiale și au fost tipărite de diverse edituri și xeroxate de nenumărații candidați.

"Recapitulare pentru bacalaureat" a devenit de atunci, partea centrală a activităţii… S-a generat o activitate organizatorică de rezonanţă naţională - implicând un consum enorm de hârtie şi de timpi de lucru - pentru "simularea" pe parcursul anului şcolar a probelor examenului; totodată, nu prea se mai face "matematică" (de exemplu) - ci se face "pregătire pentru bacalaureat" (diferența este foarte mare: matematica ar trebui să-ți folosească și după ce termini cu "bac"-ul, dar concentrarea obsesivă pe "bac" obturează de fapt, orice deschidere).

Așa stând lucrurile - mi-am propus un site bacmath, prezentând variantele pentru "matematică" astfel încât să se poată căuta și extrage informația dorită, după diverse criterii. Am plecat de la cele câte 300 de fișiere PDF ("MT-1", respectiv "MT-2") și a trebuit să analizez (folosind diverse utilitare obișnuite în Linux) "formatul PDF", a trebuit să văd cum anume aș putea transforma convenabil fișierele PDF respective (am folosit modulul Python pyPdf) și totodată, cum aș putea reda formulele și în general notația matematică bazându-mă pe un format textual (am adoptat firește, limbajul LaTeX - folosind biblioteca javaScript MathJax pentru a reda în browser formulele scrise în LaTeX):

Această investigație mi-a luat o vară întreagă (realizarea propriu-zisă a site-ului bacmath a fost o chestiune mult mai ușoară); este drept că încă n-am reușit să "montez" (ca text) toate variantele (cam jumătate dintre ele sunt redate tot în PDF, dar măcar într-un format concis).

Următoarele articole reflectă lucrul din primele patru sau cinci săptămâni, la o clasă de-a XI-a:

În ultimele vreo patru luni din 2013, am urmat pe coursera.org cursul "C++ For C Programmers", al lui Ira Pohl. M-am deprins astfel cu C++11, implicat în următoarea succesiune de articole:

Ocupându-mă de "expresii algebrice", am avut în vedere și constatarea generală a faptului că elevii (și desigur, profesorii care i-au învățat) lucrează foarte defectuos cu expresiile algebrice.

În sfârșit, în vacanța de vară tocmai încheiată am revenit la preocupări mai vechi legate de problematica programării jocului de șah:

Mi-am încheiat vacanța instituind site-ul creat astfel, //slightchess.

aug/2012 - iun/2013

A trecut aproape un an de la ultima "actualizare"! Între timp…

Am conceput colar (colar.sitsco.com --> colar.docere.ro) - "site de şcoală", încorporând însă ceva distinctiv: o aplicaţie de reflectare dinamică a situaţiei şcolare. Instituirea acestui site alături de //docere.ro a pus întâi problema lămurită în Corelarea a două site-uri cu Django şi mod_wsgi, iar chestiunile relevante pentru elaborarea aplicaţiei menţionate le-am prezentat în:

Am abordat "între timp" câteva probleme de matematică elementară (din manuale şcolare), implicând fireşte şi diverse module Python specializate pentru "matematică":

Munca la aceste trei articole m-a condus între altele, la studiul limbajului de marcare matematică MathML şi a bibliotecilor javaScript ASCIIMathML şi MathJax. Iar pe de altă parte, lucrul cu modulele Python menţionate m-a condus la ideea (dar deloc "nouă") de a realiza aplicaţii javaScript proprii, pentru obţinerea de histograme şi de grafice de funcţii; elaborarea acestora este descrisă în:

Între timp, la salar s-au adunat peste 100 de "comentarii"… Dar formularele mele pentru comentariu nu utilizau Captcha, astfel că "spamerii" au putut uşor să insereze automat (cam la aceeaşi oră din zi) mesaje comerciale; din acest motiv, la un anumit moment am eliminat pur şi simplu, posibilitatea de a adăuga comentarii la articole (lăsând-o doar pentru aplicaţia de salarizare). Am prididit în sfârşit, să corectez această neglijenţă (urmând eventual să reînfiinţez şi "comentarii pe articol"); şi desigur, corectura necesară a fost mult mai uşor de făcut, decât ştergerea zilnică a spamurilor…

În sfârşit - am eliminat Django 1.4 şi am "trecut" la versiunea Django 1.5; am avut de făcut unele modificări de cod, dar relativ uşoare (rămâne însă de revăzut manualul).

În altă ordine de lucruri - pe instantchess.com am ajuns la aproape 5000 de partide de şah (15 minute; 78% won, 19% lost), oscilând în "class: Experts"; n-am mai reflectat pe instant ("oprit" la aprilie 2012), fiindcă intenţionez (dar demult…) o "rescriere" a acestei aplicaţii.

Preocupările mele obişnuite au fost tulburate la un moment dat de o ofertă de lucru din partea unei mici agenţii Web (însă lucrurile s-au oprit aici: "câte ore, cât pe oră, cum plătim" - "16 ore (7 zile) / 30 Ron (plus taxe)"; cum adică "plus taxe": 16% impozit + 5.5% CAS). Menţionez acest episod pentru că oferta consta în a lucra la anumite proiecte folosind Symfony - framework la care eu renunţasem deja de vreo doi ani: PHP-ul meu folosea modulul Apache "prefork", iar Django foloseşte "worker" (şi aceste două MPM nu pot coexista simultan), încât pur şi simplu am eliminat PHP de pe sistemul meu.

Am revăzut în mare, excelenta documentaţie de la Symfony şi am căutat să văd cum pot instala şi PHP5 (folosind pe Apache modulul "worker"):

sudo apt-get install libapache2-mod-fastcgi php5-fpm php5 php-apc php5-mysql

Anterior (pe când lucram cu Symfony) aveam instalat PHP cu modulul Apache mod-php (şi implicit, cu "prefork"), prin care interpretorul PHP era încorporat în fiecare proces lansat de Apache pentru rezolvarea unei noi cereri (avantajul era că fişierele "*.php" erau interpretate direct şi nu transmise spre interpretare unui modul extern lui Apache); cu FPM/FastCGI, Apache nu va mai interpreta direct fişierele *.php, ci le va pasa de fiecare dată interfeţei externe FastCGI (scutind încorporarea de fiecare dată, a interpretorului PHP; în plus, separarea lucrurilor sporeşte siguranţa proceselor):

<IfModule mod_fastcgi.c>
    AddHandler php5-fcgi .php
    Action php5-fcgi /php5-fcgi
    Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
    FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization
>/IfModule>

Pe lângă acest fişier de configurare (constituit "global", în /etc/apache2/conf.d/ - încât să fie folosit de oricare dintre virtualHost-urile existente), au fost necesare modificări în /etc/php5/fpm/ (pe fişierele php.ini şi pool.d/www.conf) şi crearea directorului (cu anumite setări de permisiuni) /var/lib/apache2/fastcgi. Bineînţeles, la sfârşit trebuie restartate serverele:

sudo service apache2 restart && sudo service php5-fpm restart

În final, această "abatere" conjuncturală de la Python şi Django mi-a permis să reactivez local (şi măcar să revăd) unele aplicaţii (site-uri) create anterior cu PHP şi Symfony.

Simplificări şi optimizări

Am modificat şablonul paginii; imaginea vechii pagini de bază:

Foloseam django-contactme - dar de-acum renunţ să mai implic o aplicaţie specială (bazată pe form-uri şi pe confirmări) pentru "contact". Am indicat direct adresa mea de email; dacă utilizatorul nu are instalat un Email-client, atunci măcar poate copia adresa indicată pe primul rând al acestei pagini (pastând-o apoi în caseta "TO", când compune mesajul folosind serviciul său de email). Desigur, folosind astfel mailto: risc să primesc o mare de mesaje comerciale nesolicitate (spam-uri) - dar am configurat propriul serviciu de email astfel încât marea majoritate a acestora par a fi ignorate…

Am adoptat Django 1.4, făcând deocamdată doar reorganizarea necesară a codului şi câteva mici modificări în cadrul unor fişiere (inclusiv în definiţia vhost-ului). Pe server, a trebuit să elimin vechea versiune şi să o instalez pe cea nouă:

sudo service apache2 stop
sudo apt-get update
sudo apt-get install python-pip
sudo rm -r /usr/lib/python2.7/dist-packages/django # elimină Django.1.3.1
sudo pip install Django --upgrade
sudo a2enmod expires  # dorind Cache-Control pe fişierele statice, în vhost
sudo service apache2 start

În cazul Firefox-ului timpul de răspuns (la prima accesare) a fost cam mare (4-5 secunde); dar pare a fi mult mai bun, atât din Google-Chrome cât şi din Opera. După câteva retuşuri - urmând recomandările de la //developers.google.com/speed/docs/best-practices/ - am probat lucrurile folosind Firebug "Page Speed":

Scorul 87/100 arată că acum, mai este puţin loc de îmbunătăţiri "generale" (şi eventual, trebuie căutate îmbunătăţiri chiar în cadrul codului aplicaţiei - de exemplu în legătură cu mecanismele de obţinere a datelor din baza de date, faţă de care Django 1.4 aduce nişte perfecţionări).

În orice caz, îmbunătăţirile "generale" care ar mai putea fi făcute ţin de itemul Specify image dimensions (la care "Score" este acum 0/100). Într-adevăr, nu am indicat la nici un <img> dimensiunile imaginii respective…

Când browserul trasează pagina curent accesată, el înlocuieşte elementele <img> prin imaginile referite în atributul "src" (descărcându-le de la server, sau încărcând din cache - după caz); dar browserul începe să traseze pagina chiar înainte de a descărca imaginea propriu-zisă şi o trasează corect, dacă dimensiunile imaginii sunt cunoscute (deci, indicate în atributele "width" şi "heigth" ale elementului <img>). Altfel, dacă dimensiunile nu sunt indicate - browserul va trasa întâi "incorect" pagina, urmând ca după ce va descărca imaginea să revină asupra paginii trasate şi o corecteze pentru a face loc imaginii obţinute (iar aceaste re-trasări consumă timp).

Privitor la diferenţele dintre browsere, accesarea directă //docere.ro/grila.xml dă "eroare" în Firefox (Parsing an XSLT stylesheet failed), dar nu în Google-Chrome şi nici în Opera; aceasta se poate îndrepta "la o adică", intervenind în configurările Firefox cu about:config - vezi support.mozilla.org. Este interesant însă că "grila.xml" poate fi accesat indirect; de exemplu, în introducere XML şi XSLT fişierul respectiv este redat corect şi în Firefox, în urma accesării lui prin window.open().

O ultimă "mică" modificare: am adoptat HTML5 doctype (în loc de <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">); constatarea mea este că această modificare… a redus simţitor timpul de răspuns! Aceasta ar putea să fie o impresie greşită - dar am experimentat (este drept că pe laptopul propriu, nu şi pe serverul care găzduieşte //docere.ro) cu ambele variante, ştergând cache şi restartând serverul de fiecare dată.

Browser pentru partide de şah (jQuery widget)

Am iniţiat seria Modelarea tablei şi jocului de şah (ajunsă deja la (IX)!). Pentru prezentarea inductivă (din aproape în aproape) şi elementară a lucrurilor, a trebuit să regândesc de la capăt toate aspectele implicate în realizarea aplicaţiei mele "PGN-browser" - ceea ce m-a condus la simplificări, adăugiri şi reorganizări importante, asupra vechiului cod al aplicaţiei.

Pare a fi o metodă general-valabilă, pentru perfecţionarea unei aplicaţii: regândeşte-o la un moment dat de la capăt, la nivelul la care să poţi prezenta elementar problematica respectivă (analog în fond, cu situaţia unui profesor: predând an de an un subiect mai delicat - ceea ce înseamnă un anumit efort de regândire a lucrurilor - ajunge el însuşi să-l înţeleagă mai bine).

Pentru a lucra unitar cu orice set de piese, a trebuit să fac o mică descoperire (vezi Poziţionarea procentuală a unei piese dintr-un sprite): dacă imaginile care compun un sprite au toate aceeaşi lăţime, atunci poziţionarea imaginii de index K într-un <div> de aceeaşi lăţime se face prin background-position: -K*100% (cu procent negativ). Ca urmare, am reuşit să unific în bună măsură definiţiile CSS care iniţial depindeau de setul de piese curent implicat în aplicaţie.

PGNdemo prezintă o demonstraţie pentru widget-ul actual; codul poate fi clonat de pe github.

Bineînţeles că am actualizat corespunzător aplicaţiile şahPGN, Instant şi Bliţuri, precum şi articolele Şah cu Fruit şi Crafty şi (parţial) PGNbrowser widget Demo and Complements.

Browser pentru partide de şah (jQuery widget)

În sfârşit am pus la punct browserul pentru partide de şah introdus în 2009 cu şahPGN şi folosit apoi în Instant şi în Bliţuri şi implicat în Şah cu Fruit şi Crafty.

Anterior foloseam câte o structură HTML conţinând un element <textarea> pentru textul PGN al partidei de şah, un <button> pentru încărcare (şi iniţializarea diagramei şi funcţionalităţilor) şi un <div> pentru diagramă (plus casetele şi butoanele specifice):

<div id="asPGN" style="display:none;">
    <textarea id="txtPGN" rows="2" cols="60"> </textarea>
    <button style="position:relative;left:0.5em;top:-1em;">Load PGN</button>
</div>
<div id="asBOARD" class="divForPGN"></div>

"Load PGN" crea un "browser_pgn" pentru partida înscrisă în <textarea>, înscriind în <div>-ul indicat diagrama poziţiei iniţiale, lista mutărilor, caseta adnotărilor, etc.:

$('#asPGN button').click(function() {
    var brwg = new docere_browser_pgn('txtPGN', 'asBOARD', true, 32);
    return false;
});

Iar dacă aveam nevoie numai de lista mutărilor (nu şi de "adnotări") trebuia să adaug în funcţia de mai sus ceva de genul:

    $('#asBOARD').find('div.ChessAnnotation')
        .css('width', '0px').css('display', 'none');

Surprinzător pentru mine, nu mi-a luat decât două zile ca să reconfigurez funcţiile respective într-un jQuery widget, iar acum cele de mai sus pot fi rezumate la un element <textarea> şi respectiv:

$(function() {
    $('#txtPGN').pgnbrowser({fld_size:32});
});

pentru a-i asocia un browser complet (diagramă cu câmpuri de anumită dimensiune, lista mutărilor, lista adnotărilor, câmpul de FEN, butoane pentru acţiunile specifice, textul PGN fiind vizibil). Sau, de exemplu pentru a "ascunde" elementul <textarea>, a nu mai produce caseta de adnotări, şi a poziţiona diagrama la mutarea a 10-a a albului:

$(function() {
    $('#txtPGN').pgnbrowser({fld_size: 24, cu_annot: false, cu_PGN: false})
                .pgnbrowser('goToMove', 10, true);
});

Folosind acum jQuery.widget(), avantajul constă în principal în faptul că devine imediată separarea între crearea infrastructurii pe de o parte şi iniţializările corespunzătoare unei noi partide pe de altă parte: $('#txtPGN').pgnbrowser({fld_size:32}) creează (o singură dată) infrastructura necesară (diviziunile pentru diagramă, mutări, adnotări, FEN; butoanele de acţiune şi handlerele aferente); iar apoi, când se aduce din baza de date un nou PGN (sau, se pastează unul direct în '#txtPGN'), se va executa doar metoda "_init()" a widget-ului (nu şi "_create()"), iar aici aceasta parsează noul PGN şi constituie lista mutărilor ş.a.m.d., corespunzător noii partide.

Am adăugat opţiunea Go, pentru parcurgerea automată a mutărilor (una pe secundă, începând din poziţia curentă şi până ce se face click oriunde în paragraful butoanelor).

Redarea unei colecţii de partide de şah (aplicaţie django)

instant redă partide jucate pe InstantChess (folosind aceleaşi module javaScript de modelare a jocului de şah ca şi şahPGN, sau link-ul "Bliţuri" de pe coloana din dreapta).

Deocamdată (la acest moment) nu am făcut nici o triere: am descărcat de pe InstantChess.com fişierul PGN cu partidele mele (câte au fost înregistrate în perioada iulie 2011 - aprilie 2012) şi l-am pastat în aplicaţia mea (în partea "administrativă"):

Funcţiile pe care le-am asociat pentru "Save" prelucrează fişierul PGN respectiv, separând partidele şi partenerii şi constituind o anumită bază de date (folosită apoi şi de "Bliţuri").

Dar nu pentru a exersa pe tema realizării de aplicaţii cu Python şi django, am conceput această aplicaţie - ci chiar pentru a putea studia "în linişte": încerc să-mi lămuresc cauzele pentru care pierd regulat la anumiţi aceiaşi jucători şi să depistez momentele critice ale jocului…

În viitor voi elimina unele partide (sau le voi reduce la poziţiile interesante) şi voi adăuga altele
(şi… voi scrie un articol amănunţit despre realizarea aplicaţiei cu Python, django şi jQuery). Deocamdată mi-am creat posibilitatea marcării partidelor care ar trebui şterse: o partidă marcată cu deleted nu prea este interesantă (evident - am preferat să le marchez în loc de a le şterge efectiv… ca să nu rămân cumva fără nici o partidă "interesantă").

La acest moment există acest defect: dacă numele este unul arab - vezi sfârşitul listei partenerilor - atunci itemurile respective apar "inversate" (în arabă se scrie "de la dreapta la stânga"); de exemplu, apare vlad.bazon - اشرف الشايب 1-0 unde eu am jucat într-adevăr cu albul, dar rezultatul "0-1" (care trebuia redat după al doilea nume) trebuie citit şi el, "de la dreapta" (corect fiind "1-0").

salar.sitsco.com versus docere.ro/salar

Am redirectat //salar.sitsco.com la docere.ro/salar, păstrând numai partea publică.

salar.sitsco.com a funcţionat între sep. 2006 şi feb. 2012, servind pentru calculul salariului personalului din învăţământul preuniversitar şi anume, în două variante: una individuală (partea "publică") şi una destinată salarizării unităţilor şcolare (cu autentificare).

salar.sitsco.com încă este şi la acest moment primul link din lista de 229.000 de rezultate găsite de Google pentru termenul de căutare 'salarizare invatamant'. De prin 2009 am folosit (dar numai pentru pagina de bază) serviciul Google Analytics şi putem reproduce această statistică:

Numărul de vizitatori a oscilat (ignorând 2012) între 884 (feb. 2011) şi 12.220 (feb. 2010), marea majoritate fiind desigur din România - între 383 (judeţul Ialomiţa) şi 27.716 (Bucureşti):

De-a lungul timpului (2007 - 2012) s-au adunat în baza de date peste 500 de "comentarii":

Dar majoritatea acestora au vizat situaţii individuale, solicitând lămuriri de natură legislativă (mulţumesc prof. Elena Manea - din Târgovişte - pentru asigurarea consultaţiilor legislative); deocamdată evit să mai implic şi pe docere.ro/salar, o rubrică de "comentarii".

Începând practic din noiembrie 2011, salarizarea în şcoli se face în sfârşit, în mod unitar - folosind o aplicaţie SIVECO pusă la dispoziţie de către Minister (şi atunci am desfiinţat partea destinată salarizării şcolilor - cred că prima încercare (2007) de tratare unitară prin Internet).

salar.sitsco.com a fost folosit în mod constant de numai 12 şcoli, operator fiind secretarul sau contabilul şcolii respective. S-au înscris pe parcurs şi alte diverse şcoli din ţară, dar (în principal pentru că n-am reuşit îndrumări de operare corespunzătoare) au abandonat după cel mult trei luni. Imaginile următoare sugerează concepţia aplicaţiei de salarizare pentru şcoli şi modul de operare:

Transfer pe x86-64 (AMD64)

Gazdă pentru //docere.ro este acum un Linux-VServer x86-64 (gazda anterioară avea i686 - 32-bit CPU). Pentru programele executabile existente, transferul de la 32-bit la 64-bit necesită eventual, recompilarea surselor respective (dacă nu chiar rescrierea lor, angajând regiştrii şi setul de instrucţiuni pentru 64-bit).

Aici avem doar două programe executabile: "amifac.cgi" (lansat de exemplu prin /cgi-bin/amifac.cgi?100, sau prin intermediul aplicaţiei factoriale) şi "mimetex.cgi" (/cgi-bin/mimetex.cgi?\huge \red \opaque \sqrt{a^2 + b^2}, sau vezi functii).

"amifac.s" a fost scris direct în limbaj de asamblare (pentru Intel I486) şi nu angajează nici o bibliotecă externă; ca urmare, executabilul respectiv rulează (chiar dacă este tocmai din 2007) şi pe noua platformă x86-64 (dat fiind că x86-64 păstrează compatibilitatea cu 32-bit).

În schimb, "mimetex.cgi" provine prin compilarea unor surse C, incluzând eventual (prin legare dinamică) biblioteci existente pe sistemul respectiv. Prin urmare, a fost necesar să obţinem sursele mimeTeX şi să le compilăm direct de la consola vserverului (deci, pentru x86-64), mutând apoi executabilul rezultat în /cgi-bin/ (înlocuindu-l astfel pe cel vechi).

reconstrucţie, cu Python şi Django

Lucrând pe ai-class, m-am ocupat mai mult de Python (văzând de exemplu AIMA-code repository). Am ajuns astfel să reconstruiesc acest site folosind Python şi Django (abandonând de-acum, PHP şi Symfony).

Modificările ţin de structura paginii de bază, de reorganizarea bazei de date, de metoda de întreţinere a articolelor şi de anumite îmbunătăţiri asupra aplicaţiilor încorporate. Dar în principiu - am urmărit să păstrez formatele, funcţionalităţile şi conţinuturile de pe "vechiul" site.

OBS. Unele bookmark-uri făcute pentru vechiul site nu vor mai funcţiona - pentru că am făcut greşala de a modifica unele URL-uri.

Vor fi de prezentat unele aspecte ale acestei transformări; dar aici, doar reproduc vechea pagină de bază, pentru a o compara cu cea actuală:

Cam "sar în ochi" link-uri care arată precum …; acestea fuseseră obţinute ("ingenios", desigur) invocând din browser un fişier ca:

<!DOCTYPE html>
<html> 
    <head> 
        <style type="text/css">
             @import url(http://fonts.googleapis.com/css?family=The+Girl+Next+Door); 
        </style> 
    </head> 
    <body> 
        <p style="font-family:'The Girl Next Door',cursive;font-size:1.5em;"> 
            <i>Actualizări</i></p> 
    </body> 
</html> 

şi făcând apoi un "screenshot" pe pagina rezultată astfel. Acum, în primul rând - am renunţat la asemenea artificii (vezi a treia coloană de link-uri din antetul paginii actuale); de asemenea, am înlocuit prezentarea secvenţială a aplicaţiilor "media dinamică", "săritura calului" şi "partide de şah" (vezi partea dreaptă a paginii) cu un container accordion.

Articolul 50 (rescriere)

Iniţial (două luni în urmă) "Articolul 50" era foarte concis, vizând numai justificarea cea mai simplă a egalităţii 0.(9) = 1. Acum l-am rescris complet, vizând (ca de obicei) mai multe chestiuni legate de tema respectivă ("tema" anunţată de titlu nu consta în calculul propriu-zis al mediei…).

Să precizez că am lucrat "între timp" - fiindcă de două luni muncesc "din greu" să înţeleg o serie de lecţii video în engleză (şi documente aferente), să răspund la Quiz-uri şi să rezolv Homework-uri şi Exams pe ai-class (Online Introduction to Artificial Intelligence, based on Stanford CS221):

După "Midterm" (primul examen), urmează acuşi examenul final… Mizez pe un rezultat onorabil, dar indiferent de aceasta - consider deocamdată că am făcut o foarte frumoasă şi destul de amplă experienţă de cunoaştere şi actualizare (ce voi valorifica în mod concret de aici - şi nu-i vorba de acte de "perfecţionare" - rămâne de văzut).

Linux şi aplicaţii Web în 24 de ore - revenire; Orar şcolar

Am creat subdomeniul //web24.docere.ro, pe care am montat (şi am revizuit) lecţiile postate anterior pe "//sites.google.com/site/ccd24h", pe care l-am desfiinţat (deşi constat acum că între timp, sites.google.com a îmbunătăţit substanţial instrumentele oferite pentru crearea de site-uri).

În fond, am experimentat astfel unul dintre cele mai simple şi eficiente sisteme de realizare a unei documentaţii: Sphinx. Dar motivaţia reală a iniţierii acestui experiment nu ţine de "lecţiile" evocate; Word-apetitul instituţiilor noastre a ajuns de nesuportat. Planificările noastre sunt şi ele nişte "documentaţii" (şi problema reală nu este de a le scrie pe hârtie…).

Am sesizat că şi orarul şcolii poate fi tratat ca "documentaţie" posibil de realizat folosind Sphinx: //orar.docere.ro. Scriptul Python conceput în acest scop este descris în Formularea orarului, cu Python şi Sphinx, unde însă lipseşte o secţiune finală despre "retuşurile" posibile asupra site-ului construit de Sphinx. Ar fi vorba nu de retuşuri care pot fi decise direct din conf.py (de exemplu, eliminarea barei şi paginii "Search", prevăzute în mod implicit de către Sphinx), cât de cele care pot fi realizate prin scripturi javaScript proprii (plasate în /_static); dar deocamdată acestea nu sunt bine puse la punct (încât - în loc de a le "pune la punct" - am renunţat să prezint şi "retuşuri"…).

Şah cu Fruit şi Crafty - revenire

Anterior, redarea diagramelor era oarecum defectuoasă:

Acum: diagrame variabile ca dimensiune; mutările şi adnotările scrollează concordant cu poziţia curentă; am repoziţionat caseta destinată adnotărilor.

Pe "sidebar" rulează o altă instanţă a browserului de partide PGN folosit în articol - redând (dar fără lista mutărilor şi fără adnotări) o partidă sau alta dintr-o mică selecţie de partide "uşoare" (cu timp de gândire de 15 minute), jucate de mine pe InstantChess.

Şah cu Fruit şi Crafty

Am reluat preocupările de "computer chess". Deocamdată - mă ocup să modific browserul de partide de şah în format PGN şahPGN, încât să poată fi şi Web-integrabil (integrat într-o pagină Web oarecare) şi în acest sens tocmai am publicat Şah cu Fruit şi Crafty.

Unele neajunsuri le-am semnalat eu însumi şi m-am decis să mă ocup de următoarele modificări:
— poziţionarea casetei de adnotări în dreapta listei mutărilor (şi nu dedesubt);
— caseta de adnotări să conţină din start toate adnotările existente în PGN-ul partidei respective;
— asigurarea scrolării mutărilor şi adnotărilor, concordant cu diagrama curentă;
— asigurarea posibilităţii de a folosi diagrame (şi implicit, piese) de mai multe dimensiuni (ceva mai mare pentru întreaga partidă, ceva mai mică pentru diagramele de analiză a partidei) - dar… evitând multiplicarea codului (cum am făcut deocamdată, pentru acest prim experiment).

Jurnal

Am iniţiat "Jurnal". Pentru perioada 2005-2010 pot doar să evoc unele aspecte semnificative. Altfel, "actualizări" acoperă anumite retuşuri sau modificări de conţinut petrecute pe acest site.

Atributul "explicitări" vizează un anumit substrat semnificativ, dar aflat într-un raport colateral faţă de conţinutul propriu-zis al unui articol.
Mai jos, aprilie 2011 conţine un exemplu relevant de "explicitare".

Symfony 2. Paginare, administrare

Symfony 2 este o rescriere completă a framework-ului Symfony (demarată prin 2009 şi lansată oficial în iulie 2011). Symfony 1.4 rămâne perfect viabil, dar am reconstruit totuşi docere.ro; n-am avut "dificultăţi inerente" adoptării un nou framework, dar a fost interesant să trebuiască să accept o schimbare majoră, pe care o evitasem comod până acum.

Anterior, păstram articolele într-un anumit director, ca fişiere .html sau .php. Dacă era necesar să modific ceva în vreun articol, făceam modificările respective pe copia mea de acasă şi apoi uploadam respectivul fişier pe server (fără să fie necesară vreo altă operaţie "remote-console").

Symfony 2 - şi Doctrine2, asociat - exploatează intensiv anumite mecanisme de cache (triplând performanţele în raport cu Symfony 1.4). Metoda explicitată mai sus "nu mai ţine": dacă modifici un fişier, atunci pentru actualizarea necesară pe server este obligatorie o comandă "cache:clear" (de la consolă). În plus, n-am reuşit să-mi dau seama cum trebuie configurate lucrurile încât Twig (limbaj introdus de Symfony 2 pentru crearea şabloanelor de pagină, asemănător cu Template::Toolkit) să "recunoască" direct şi fişiere .html (fără a înlocui extensia cu .html.twig).

Am ajuns astfel la o concluzie pe care o refuzasem comod până acum: ar trebui să depun articolele într-o bază de date, în loc să le păstrez în fişiere .html. Şi este drept că astfel, se simplifică şi gestionarea unor elemente asociate în mod firesc unui articol (de exemplu, "taguri").

Pentru paginarea listei de articole foloseam anterior - în maniera standard pentru Symfony 1.4 - clasa sfPager şi plugin-ul sfDoctrinePager. Acestea pot fi "adaptate" şi pentru Symfony 2 - dar am ajuns la părerea că pot folosi foarte bine un plugin jQuery propriu - Plugin jQuery pentru paginarea unui tabel HTML (revizuit şi adaptat pentru listă). Serverul trimite lista tuturor articolelor (selectând însă numai "meta-informaţii", nu şi blocul de conţinut al articolelor), iar paginarea decurge acum în browser.

Mi-am mai dat seama că în fond nu este necesară şi o interfaţă de administrare (cum aveam cu Symfony 1.4: /frontend pentru "producţie" şi respectiv /backend pentru "administrare"): poate fi suficient să foloseşti numai acasă o asemenea interfaţă (creată banal, folosind direct instrumente de generare ca "generate:doctrine:crud"), iar aceasta poate fi foarte bine şi complet separată chiar şi de copia locală a serverului "de producţie" (dar angajând desigur, aceleaşi entităţi).

Rolul acestei interfeţe de administrare ar fi deocamdată acesta: după ce am creat articolul - în modul obişnuit, ca fişier .html - folosesc aplicaţia de administrare pentru a prelua fişierul respectiv şi a-l înscrie în baza de date (acasă); desigur, înregistrarea rezultată va trebui inserată într-un fel sau altul (de dorit - direct din această interfaţă) şi în baza de date de pe server.

Prolog

Am început să mă ocup de Prolog (v. Introducere practică în Prolog), incitat fiind de acest articol: amb-in-javascript, în care - corect sau nu - eu am văzut că ar fi vorba întâi, de o anumită modelare a backtrackingului şi am făcut legătura cu faptul că interpretoarele de Prolog funcţionează în mod nativ ca un "mecanism backtraking"…

Considerentele implicite sunt legate iarăşi, de programa şcolară actuală. La noi se învaţă din start C++ (ba chiar de printr-a V-a sau a VI-a, ceea ce este absolut ridicol) şi elevii exersează "să programeze" folosind o interfaţă grafică, fără a şti de fapt "ce" programează ei. În alte părţi (inclusiv, facultăţi) se preferă de mult timp folosirea unui interpretor pentru demararea solidă a pregătirii programatorilor: SICP ("introductory courses at MIT").

Dar îmi amintesc un fapt de notorietate locală: acum mulţi ani (pe când unii părăseam Pascal şi treceam la C), un profesor făcea la clasele sale a V-a şi a VI-a (la liceul "M. Kogălniceanu") tocmai Prolog… Nu mai ştiu nume, nu ştiu ce vor fi ajuns unii sau alţii şi nici cât le-a folosit experimentul; dar acum apreciez că într-adevăr exact aşa ar trebui procedat, cu atât mai mult cu cât azi dispunem de interpretoare de Prolog care sunt şi uşor de folosit (v. swi-prolog).

În orice caz, pentru a asigura înţelegerea ("prinderea") mecanismelor tipice şi a metodelor de bază (inclusiv, backtracking) - este sigur mai bine, să foloseşti întâi un interpretor (decât să "respecţi programa", mecanic). Iar un interpretor de Prolog ar fi cu atât mai potrivit (faţă de unul de Perl, de exemplu) cu cât ar implica şi integrarea naturală a cunoştinţelor de "logică matematică" (din programa de matematică, clasa a IX-a).

reconstrucţie (Symfony 1.4) şi revizie generală

De prin 2009 am neglijat să mă ţin la curent cu dezvoltarea framework-ului Catalyst. De exemplu n-am reuşit să mă "dezvăţ" de Class::DBI, pentru a adopta şi eu DBIx::Class - încât uneori (mai ales pe salar) a trebuit să folosesc nişte trucuri pentru a evita să modific anumite mecanisme deja aflate în exploatare (autentificare/autorizare, integrare şi gestionare a bazei de date).

Bazându-te pe un web-framework pentru a-ţi produce site-ul, înţelegi - într-un târziu - un fapt esenţial: framework-ul nu este destinat utilizatorului final (pe care nu prea-l interesează "cum se face" una sau alta), ci tocmai programatorului de aplicaţii. Un framework nu se poate folosi precum un "produs final" (descarci, instalezi şi foloseşti vreo 10 ani); un framework oferă programatorului instrumente de dezvoltare bazate pe anumite standarde actuale şi odată cu progresele recunoscute în contextul acestora (şi cu noile dileme), se modifică în mod inerent şi frameworkul respectiv.

Cu alte cuvinte, dacă ai adoptat un anumit framework pentru a-ţi produce aplicaţia - atunci trebuie să urmăreşti permanent modificările apărute de-a lungul timpului şi să-ţi actualizezi corespunzător propriul cod. Când am început lucrul în 2005, Perl avea versiunea 5.04 (versiunea actuală este 5.19), iar Catalyst 2.99 (apoi 5.0, din 2006 5.7, iar actual 5.8).

Aceasta este important în special pentru Catalyst (şi pentru multe alte module Perl) - iată de ce: aplicaţia proprie este găzduită pe un server Linux/Apache; Linux-ul inglobează de regulă perl, împreună cu multe module Perl şi orice updatare a Linux-ului pe serverul respectiv va avea drept consecinţă eventuala updatare a interpretorului de Perl şi deasemenea, a pachetelor Perl folosite - încât se poate ajunge în situaţia ca aplicaţia "salar" să ruleze pe server cu o versiune de pachet Perl superioară celeia cu care ai produs iniţial aplicaţia respectivă (eu am păţit-o!) şi dacă n-ai modificat la timp lucrurile, atunci poţi avea şi surprize neplăcute.

Pentru a fi la curent cu dezvoltarea actuală a framework-ului folosit trebuie să te (re)documentezi permanent. Dar posibilităţile de documentare depind de framework-ul respectiv. Pentru Catalyst cea mai bună sursă de documentare rămâne însuşi codul propriu al pachetului - ceea ce este în fond general valabil, dar dificil totuşi de exploatat practic; din acest motiv am început să fiu nemulţumit (dar este vorba de propriile limite sau gusturi şi nicidecum de valenţele Catalyst-ului).

În 2010 am descoperit Symfony - un web-framework bazat pe PHP. Mie îmi era urât PHP-ul (dar nici nu-l ştiam decât de circumstanţă): îmi părea a fi un maldăr dezorganizat de funcţii amestecate, pentru toate cele (chiar aşa era, până la PHP 5) şi nu-mi plăcea de loc ideea de a îngloba cod executabil într-un fişier HTML, amestecând lucruri care ar trebui să rămână separate. Când zic mai înainte, "am descoperit" - mă refer în primul rând la documentaţia oferită de Symfony, care m-a cucerit imediat (demersuri generale şi motivaţii contextuale excelent construite şi expuse; logică remarcabilă de dezvoltare şi de expunere; claritate dusă până la amănunt).

Am reconstruit //docere.ro, folosind Symfony 1.4. Deasemenea, am reconstruit aplicaţia mea de "orar": scorar (accesibilă deocamdată şi la http://scorar.docere.ro/).

În plus, am reorganizat conţinutul şi am schimbat radical "layout"-ul. Până în decembrie 2010, pagina de bază arăta astfel:

iar pagina accesată prin link-ul "întregul articol" arăta astfel:

Am abandonat deocamdată, aplicaţia mea de "Şah prin corespondenţă" (al cărei link apare în partea dreaptă a imaginii de mai sus), am renunţat la "calendar" şi la scriptul "dimensiune text".

Cu acest prilej, am revăzut în amănunt conţinutul tuturor articolelor care se adunaseră - vezi "Notă - 2011", la sfârşitul articolului "Centralizatorul" Educaţiei Naţionale - de la Word la XML.

//docere.ro

Am adoptat (pe ambele site-uri) jQuery în loc de "prototype.js" (dar nu fiindcă aceasta din urmă n-ar fi şi ea, suficient de bună).

Am achiziţionat domeniul "docere.ro" (că "docere.com" nu era disponibil). "Docere" înseamnă "a învăţa" şi se potriveşte contextului - dar acum (în 2011) mi se pare că nu este o denumire bună pentru site… Din 2009, ceea ce era "lar.sitsco.com" a devenit actualul "docere.ro".

//lar.sitsco.com (perl, Catalyst; prototype.js)

La începutul anului 2005 apărea prima versiune stabilă a framework-ului perl Catalyst. M-am bazat pe Catalyst (împreună cu modulele perl Class::DBI şi Template::Toolkit) pentru a produce site-urile http://lar.sitsco.com şi salar.sitsco.com.

Pentru expunerea conţinutului în browser, am folosit un sistem de taburi-Ajax realizat folosind framework-ul (bibliotecă javaScript) prototype.js (ulterior am renunţat la "taburi").

Până la mijlocul lui 2007, lar.sitsco.com era un "site-ul şcolii" - orar, forum, documente şcolare ("regulament", "raport de autoevaluare", etc.), mici aplicaţii pentru browser (între care, o galerie de desene ale elevilor, oferite de profesorul I. Midvichi) şi articole.

Dar am constatat că "lar.sitsco.com" era foarte greu de ţinut minte; pe de altă parte, n-am găsit la vremea aceea soluţii acceptabile pentru a facilita editarea (în Word…) şi postarea de către alte persoane a unor "materiale" proprii acestora.

Şi ambele site-uri au fost contestate vehement: "nu putem admite afişarea situaţiilor şcolare pe Internet", "nu se poate face salarizarea prin Internet, din cauza hackerilor - că salariile sunt confidenţiale" (redare aproximativă după un "proces verbal" oficial, al unui "consiliu profesoral"), "siteul şcolii trebuie să aparţină elevilor şi să fie realizat de elevi", "revista şcolii şi siteul şcolii trebuie să conţină articole ale elevilor (nu ale profesorilor)", etc.

Mai mult - "poate şi altcineva să facă orarul" (în principiu, sunt şi eu de acord; numai că nu de principii este vorba aici), iar în perioada 2007-2009 am fost chiar degradat birocratic la statutul oficial de "profesor necalificat"…

Din 2007 am renunţat la pretenţiile de "site-ul şcolii" şi am adoptat (pentru lar.sitsco.com) statutul implicit de "blog" personal (punând totuşi secţiunea de "orar" la dispoziţia celui care face orarul şcolii).

Media Dinamică

Articolul 50

Drumuri

ŞahStartTemp

25
32
17
4
19
34
14
3
26
33
16
5
31
24
15
18
35
20
2
13
27
6
9
23
30
11
8
21
28
12
22
29
10
7

Ambiţiile Cavalerului

Localităţi

Judeţ:

Constituirea unei baze de date colectând cu Python de pe web

Bliţuri

Load another random Bliţ

//slightchess

Decoraţiuni hiperbolice

SALARII 2017

//bacMath
variante BAC matematică

Bacalaureat 2015 -
de la forma microsoftizată, la R

modelare ŞAH, I-XX
construcţia unui PGN-browser()

Linux şi aplicaţii Web
în 24 de ore

Orar şcolar - exemplu
după un orar generat de "aSc Orare"

Orar Adjust
ajustează orarul şcolar