momente şi schiţe de informatică şi matematică
To attain knowledge, write. To attain wisdom, rewrite.

O aplicaţie pentru browser, cu determinanţi şi sisteme liniare

CSS | HTML | javaScript | lipsa de idei | modelare obiectuală
2007 nov

Ne propunem o mică aplicaţie pentru calculul determinanţilor şi pentru rezolvarea sistemelor de ecuaţii liniare, angajând numai ceea ce pune la dispoziţie un browser (în principal, javascript şi HTML). Dar în final ajungem să semnalăm ca necesitate şi ca sindrom: lipsa de idei.

Interfaţa aplicaţiei

Trebuie creată posibilitatea ca utilizatorul să poată introduce date ca: numărul de ecuaţii, coeficienţii necunoscutelor, vectorul termenilor liberi. Dar această separare a datelor este proastă (deşi este obişnuită în programele redate în manuale: cică afişează "a[1,1]=" şi după ce se introduce valoarea ("cin>>a[1][1]"), programul din manual continuă cu "a[1,2]=" aşteptând următoarea valoare, ş.a.m.d.).

Este suficient şi mult mai convenabil, ca utilizatorul să introducă "matricea extinsă" a sistemului: numărul de rânduri dă numărul n de ecuaţii, primele n numere de pe rând sunt coeficienţii necunoscutelor, iar ultimul coeficient (al n+1-lea) de pe fiecare rând este termenul liber al ecuaţiei; dacă pe fiecare linie există exact n numere, atunci programul va putea şti că se cere determinantul unei matrice de ordinul n (şi nu soluţionarea unui sistem). Mai convenabil se referă şi la manieră (simplitate) de programare; să introducă înseamnă fie să tasteze direct, fie să utilizeze Copy&Paste dintr-un fişier text care conţine coeficienţii.

Cea mai simplă interfaţă ar fi constituită dintr-un element textarea pentru introducerea matricei, un hyperlink care să activeze (la click) funcţia de analiză şi calcul necesară şi eventual un div pentru înscrierea soluţiei:

   <textarea id="id-date" rows="12" cols="32"></textarea>
   <p><a href="#" onclick="var sy = new sistem('id-date'); 
                                    sy.solutie('id-solutie');
                                    return false;"> OK </a></p>
   <div id="id-solutie"></div>

La click pe "OK" s-ar crea obiectul "sy", prin apelarea "constructorului" sistem('id-date') - al cărui rol ar fi acela de a analiza conţinutul din TEXTAREA şi de a constitui tablourile de coeficienţi necesare; "metoda" solutie('id-solutie') a obiectului "sy" va calcula determinantul (sau soluţia sistemului, după caz) şi va înscrie rezultatul în diviziunea identificată prin 'id-solutie'.

Modelarea funcţionalităţii aplicaţiei

Nu este de loc obligatoriu aici, dar folosim de obicei biblioteca prototype.js (inclusă de pagina noastră de bază); de fapt, acum chiar nu vom implica altceva decât funcţia $(element) care în esenţă, "prescurtează" funcţia DOM getElementById(element), precum şi maniera specifică pentru crearea unui obiect (folosind Class.create({...})). Altfel, prototype.js (sau o bibliotecă similară) ar deveni indispensabilă numai când aplicaţia ar utiliza cereri către server (ceea ce acum nu este cazul) şi am vrea ca rezultatul returnat de server să fie înscris într-o diviziune precizată.

var sistem = Class.create({
    initialize: function(id_area) {
        var d = $(id_area).value.replace(/^\s+/mg,"").replace(/\s+$/mg,"");
                              // elimină <i>spaţiile</i> iniţiale sau finale
        var w = d.split(/[\n\r]+/g);  // tabloul w[] conţine liniile matricei
        this.DIM = w.length;          // numărul de linii (sau ecuaţii)
        this.MAT = new Array();       // matricea coeficienţilor
        this.LIB = new Array();       // vectorul termenilor liberi
        for(var i = 0, n = this.DIM; i < n; i++) {
            var m = w[i].split(/\s+/);  // coeficienţii de pe linia de rang i
            if(m.length > n) {
                this.LIB[i] = parseFloat(m[n]);
                m.pop();  // elimină din m[] coeficientul de rang n (termen liber)
            }
            this.MAT[i] = []; 
            for(var j = 0; j < n; j++) {  // înscrie coeficienţii necunoscutelor
                this.MAT[i][j] = parseFloat(m[j]);
            }
        }
    },
    det: function() { // va returna determinantul matricei MAT[]
        var d = 1, C, L, i, k; var n = this.DIM;
        var a = [];  // face o copie a[] (pentru a nu afecta MAT[]) 
        for(i = 0; i < n; i++) {
            a[i] = [];
            for(k=0; k < n; k++)
                a[i].push(this.MAT[i][k]);
        }
        for(C = 0; C < n; C++) {  // caută în coloana C un element nenul 
            for(L = C; (L < n) && (!a[L][C]); L++);
            if(L == n) return 0;  // pe coloana C toate valorile sunt 0 (det = 0)
            if(L != C) {  // valorile de rang 0..C-1 sunt nule
                d = -d;  // interschimbă linia de rang C cu linia de rang L
                for(k = C; k < n; k++) { // ignoră zerourile iniţiale
                    var t = a[C][k];
                    a[C][k] = a[L][k];
                    a[L][k] = t;
                }
            }
            for(i = C+1; i < n; i++) { 
                for(k = C+1; k < n; k++){  // 0 în coloana C, dedesubtul liniei C
                    a[i][k] -= a[C][k] * a[i][C] / a[C][C];
                }
            }
        }  // s-a obţinut matrice triunghiulară
        for(i = 0; i < n; i++)
            d *= a[i][i];  // determinantul
        return d;
    },
    solutie: function(id_sol) {
        tsol = $(id_sol); var i, j, k, n = this.DIM;
        var d = this.det();  // determinantul matricei construite de initialize()
        if(this.LIB.length == 0 || d == 0) {  // încheie dacă d==0 sau LIB[] este vid
            tsol.innerHTML = 'are determinantul = ' + d.toFixed(6);
        } else {
            var sol = [];  // vectorul soluţiilor sistemului
            for(i = 0; i < n; i++) {
                var col = [];  // salvează temporar coloana de rang i din MAT[]
                for(j = 0; j < n; j++) col[j] = this.MAT[j][i]; 
                for(j = 0; j < n; j++) this.MAT[j][i] = this.LIB[j];
                                       // LIB[] devine coloana i din MAT[]
                var dx = this.det(); // determinantul matricei modificate MAT[] 
                sol[i] = dx / d;     // conform regulii lui Cramer
                for(j = 0; j < n; j++) this.MAT[j][i] = col[j];
                                       // recuperează coloana originală a MAT[]
            }
            var res = '<i>soluţia sistemului</i>:<br>';
            for(i=0; i < n; i++) {
                var v = sol[i].toFixed(6);
                res += 'x' + i + ' = ' + v + '<br>';
            }
            tsol.innerHTML = res;  // înscrie răspunsul în diviziunea indicată
        }   
    }   
});      

var asigură în javascript crearea unui obiect (variabilă). Class este un şablon de obiect (un "prototip") introdus de prototype.js. În momentul instanţierii unui astfel de obiect - var sy = new sistem('id-date'); - funcţia create() (din Class.create()) apelează automat funcţia precizată prin initialize; ca urmare, obiectul particular "sy" va încorpora variabilele DIM, MAT şi LIB (accesibile din exterior prin "sy.DIM" etc. şi din interior prin "this.DIM" etc.).

det() modelează metoda eliminării, aducând matricea la "forma triunghiulară"; solutie() modelează regula lui Cramer.

O necesitate: lipsa de idei

Reproduc de pe mail această solicitare de idei, din partea unui elev:

Am mai bine de un an de când am început să învăţ PHP şi MySQL şi am ajuns la un nivel la care mă descurc destul de bine şi pot face un site sau o aplicaţie web care să fie acceptabile din punct de vedere funcţional. Eu continui să învăţ dar vreau să fac ceva care să fie folositor la ceva sau cuiva (un site, o aplicaţie mai complexe). Aş dori să-mi daţi şi mie o idee sau să îmi propuneţi o colaborare deoarece eu chiar vreau să fac ceva şi să învăţ.

Am întâlnit elevi pasionaţi de informatică, dar care nu învaţă decât la "Informatică". Mai bine zis, deşi sunt pasionaţi de informatică, nu învaţă decât la "Informatică" (desigur, fără a se limita la ceea ce le propune "programa").

Această atitudine este principial greşită; informatica vizează mai toate domeniile şi în plus, se bazează cam pe toate domeniile (inclusiv şi cel mai mult, pe matematică) - încât abandonarea efortului de cunoaştere propus în Liceu pentru diversele discipline, poate avea drept rezultat firesc "lipsa de idei".

O manifestare tacită a "lipsei de idei" se tot întâlneşte la elevi chiar mari, atunci când li se solicită o "creaţie proprie"; fie se gândesc la fel de fel de joculeţele puerile (neapărat, cu pătrăţele "frumos" colorate şi cu IMG-uri), fie mai nou - caută ceva de-a gata pe Internet şi se apucă să "adapteze"; şi adesea, nici nu se produce acest prim câştig important: conştientizarea stării de "lipsă de idei". Cât timp această stare nu este conştientizată, nu prea se întâmplă nimic important mai departe; la următorul concurs de "creaţii software" elevul va produce iarăşi vreun joculeţ chinuit, sau îl va relua pe cel precedent. Atunci când această stare este conştientizată ca atare, progresul este asigurat (sau măcar, devine posibil) - pentru că se conştientizează implicit necesitatea unei soluţionări şi pentru că soluţia este totuşi, evidentă: diversificarea, adâncirea şi contextualizarea cunoştinţelor.

Corelarea cu alte discipline constituie un "izvor nesecat" de idei de lucru independent. Ca să dau un exemplu: ai învăţat (la Matematică) "regula lui Cramer" - păi iată imediat o idee bună de lucru: oferă o aplicaţie corespunzătoare, care să se poată folosi direct din browser. Muncind asupra unor asemenea mici aplicaţii, reuşeşti să "prinzi" mai bine de exemplu javascript, HTML, CSS etc. şi totodată, vei reuşi să-ţi însuşeşti mai bine şi domeniul pe care faci aplicaţia (că evident, trebuie însuşit calculul determinanţilor şi regula lui Cramer de la Matematică, pentru a putea face aplicaţia intenţionată). Ca să dau un alt exemplu: cei de la "economic" se ocupă de "conturi", de "balanţă contabilă" etc., iar tu înveţi "baze de date"; documentează-te în legătură cu "balanţa contabilă" şi foloseşte MySQL şi PHP ca să oferi o aplicaţie corespunzătoare.

De altfel, ultimele ediţii de manual de Matematică fac (în sfârşit!) şi diverse conexiuni cu informatica (a vedea de exemplu, manualul de cl. a XI-a) - încât însuşi studiul manualului devine o sursă de idei pentru diverse aplicaţii independente. O altă sursă pentru idei de lucru, pentru elevi şi de asemenea pentru profesori sunt "gazetele"; Gazeta de Matematică a publicat de-a lungul timpului şi articole pe diverse teme de informatică şi oricum, multe dintre temele şi problemele propuse aici permit diverse investigaţii "cu calculatorul"; iar Gazeta de Informatică a iniţiat diverse deschideri spre informatica modernă (pe lângă articole privind tehnicile de programare, de exemplu).

Nu trebuie să mai precizăm noi, dar totuşi: Internetul a devenit de mai mult timp, sursa majoră de idei de lucru; doar că trebuie să depăşeşti nivelul "Word", "messenger" şi "edu.ro"; eventual, mai trebuie să depăşeşti însuşi sistemul închis Windows…

Un sindrom: lipsa de idei

La nivel de individ, lipsa de idei decurge din îngustimea domeniului de interes şi din necorelare… Dar "lipsa de idei" este şi o stare comună şi nu se poate să nu fie remarcată (chit că devii "inamicul public nr. 1").

La un nivel mai general, lipsa de idei este o manifestare de lungă durată, caracteristică sistemelor închise (care nu oferă perspective reale de dezvoltare). Dezvoltarea ajunge să fie girată nu de competenţă şi creativitate, ci de un aparat funcţionăresc amplificat şi malformat continuu şi de diverse instanţe formale care inventează artificial şi ajustează încontinuu reglementări de restricţionare, stufoase şi alunecoase (cu responsabilitate chipurile faţă de "interesul public", de fapt cu tot soiul de influenţe din partea altor instanţe formale de reglementare, care numai competente pe domeniul respectiv nu sunt). Aparatul de conducere a devenit independent de domeniul pe care-l încorsetează, principiul fiind acela că nu este necesar nicidecum să ai competenţe asupra domeniului sau subdomeniului, ca să-l poţi gestiona (ceea ce este un fals grosolan şi induce falsuri grosolane pe subnivele). Competenţa individului din sistem este apoi curăţată de conţinutul real şi este fixată artificial de aparatul birocratic de deasupra; valorile sunt stabilite nu în mod intrinsec (datorită substanţei lor reale), ci sunt date din exterior, de bifări funcţionăreşti şi de voturi. Sistemul este partiţionat arbitrar în cât mai multe componente între care se elimină întretăierile şi corelările fireşti, înlocuindu-le prin legături de nivel birocratic, cât mai străine de substanţa reală a domeniului, angrenând totul într-un hăţiş incolor în care fiecare individ trebuie să devină un simplu funcţionar.

Un exemplu de astfel de sistem închis ajunge să fie sistemul de învăţământ, în care în ultimii ani s-a instalat o birocraţie sufocantă, capabilă acum să anihileze orice competenţă neformală; "birocraţie" însemnând nu atât sau nu numai aparatul funcţionăresc care semnează şi ştampilează, dar mai ales hăţişul de regulamente şi reglementări şi ordonanţe pe toate palierele sistemului, stufoase, întortochiate, instabile şi de multe ori cu un evident caracter chiţibuşeresc; unele reglementări sunt mai degrabă hilare sau inutile, de exemplu pentru că "bunul simţ" nu trebuie "reglementat", ci trebuie cultivat; conform regulamentelor, elevul este transformat într-un soi de funcţionar (chiar se încurajează această transformare: vezi campaniile de "Elevul Primar de Municipiu" sau "Elevul Ministru"). Unele reglementări chiar sunt hilare, de exemplu se suprapune competenţa individului cu înscrisul de pe o Diplomă emisă cu vreo 30 de ani în urmă, ignorând sau şmecherind realităţile (de aşteptat, fiindcă domeniul este străin funcţionarului pus să-l "gestioneze", de mai jos ca şi de mai sus). Profesorii au devenit "dascăli", iar competenţa aprobată şi gratificată înseamnă "competenţă" la nivelul actelor şi al voturilor abstracte (inclusiv de la persoane fără măcar minimă competenţă, incluzând evident şi părinţi), nu şi al înfăptuirilor reale (funcţionarul decide, nu competenţa specifică); disciplinele de învăţământ au devenit pompos "arii curriculare" fără legătură una cu alta şi în realitate sunt practicate la nivelul rezumatelor pentru "Bac" (ăsta-i termenul folosit oficial pentru inutilul "examen de bacalaureat"; s-a ajuns la susţinerea tacită a obiceiului "dacă nu-ţi trebuie la Bac, atunci ai 10, ca să nu-ţi strice media la "Dosarul de admitere"; şi-atunci care mai este sensul examenelor respective?).

S-au străduit mulţi factori decizionali ca să se ajungă aici, dar meritele pe care şi le asumă cam seamănă cu mândria elevului care-şi prezintă joculeţul întortochiat pe care l-a realizat el (adică, reprezintă o manifestare a "lipsei de idei", aflate încă în stadiul de neconştientizare). Reprezentanţii Sindicatelor au reuşit pompos să impună reglementări pur birocratice pentru separarea strictă a specializărilor şi implicit a disciplinelor de învăţământ - contrar principiului elementar al corelării pe care-l evidenţiam mai sus. Diverse persoane oficiale - relevând obişnuitul "învăţământul este prioritatea nr. 1" - atenţionează totuşi că nu-i o chestie chiar aşa de serioasă ("Dar băieţi, eu n-am fost elev bun şi iată ce am ajuns") şi au reuşit să oficializeze termenul mediocru de "dascăl" în locul singurului termen recunoscut dintotdeauna drept acoperitor de competenţă reală. Un exemplu relevant pentru "lipsa de idei" este şi faptul că în ultimii vreo 10 ani (poate că numai până în acest an, când se constată o primă temperare) "ideea" cea mai valoroasă şi cea mai merituoasă operată în şcoli (cu toate sacrificiile) a fost organizarea îndelungă şi cu implicări majore din partea profesorilor, elevilor, părinţilor, Inspectoratului, Televiziunii etc., a "balului bobocilor" (îmi amintesc şi eu dintr-un asemenea spectacol, foarte felicitat şi dat şi pe post: "Trăiască berea,…").

Mesajul citat la început ilustrează un simptom destul de grav şi care încă trece neobservat: elevul face şcoala cum i se propune, o termină şi ia şi Bac'u, dar constată că este în starea de "lipsă de idei"; nu este numai vina lui, pentru că nu este deloc un caz izolat. Această situaţie ar trebui să dea de gândit; ce poate fi mai grav, decât să vezi că patru ani de Liceu (ca să nu mai vorbim de precedenţii, tot de şcoală şi ca să nu mai vorbim eventual şi de cei care vor veni) se finalizează doar cu "lipsă de idei"?

vezi Cărţile mele (de programare)

docerpro | Prev | Next