Majoritatea programelor procedează pur şi simplu direct (fără nicio "teorie"), conducând la grafice suficient de "corecte" - mizând pe ceea ce nouă ne lipseşte (şi suplinim prin instrumentele teoretice de "analiză matematică"): posibilităţile uriaşe de calcul "brut" şi de reflectare dinamică a calculelor, oferite de calculator.
O histogramă este o funcţie care partiţionează un set de date numerice într-un anumit număr de clase şi asociază fiecărei clase o valoare care reflectă numărul de date înregistrate pe acea clasă.
Abordăm metodic (iarăşi - ca un exerciţiu de elaborare a unei aplicaţii) construcţia unei histograme folosind elementele unui browser (javaScript, <canvas>).
De la simpla indicaţie din manual - la rezolvare (uneori, o cale plină de capcane), implicând şi unele pachete matematice (NumPy, matplotlib, mpmath), sau "artistice" (GIMP).
Care sunt "constantele" de avut în vedere? De peste tot - dar cu excepţia învăţământului nostru, înglodat în produse point-and-click - rezultă că pentru realizarea produselor informatice sunt angajate trei categorii de instrumente: terminal, editor de cod-sursă şi - după caz - compilator, sau interpretor de limbaj.
Obiceiul general este unul expeditiv: rezolvă (fără cuvinte), vezi rezultatul şi abandonează apoi problema (trecând imediat la o altă "problemă"). Discuţia pe marginea problemei şi evidenţierea unor conexiuni este de regulă neavenită, fiind considerată ca o divagaţie inutilă şi o pierdere de timp. Obiceiul este deasemenea, de a rezolva eminamente manual, folosind cel mult telefonul şi doar pentru a face adunări, înmulţiri şi extragere de radicali… Învăţământ de uzură.
Discutăm aici o problemă din manualul de matematică, implicând şi unele biblioteci publice care au fost create pentru a deservi diverse necesităţi matematice (fiind utilizate în munca de zi cu zi a cercetătorilor din diverse domenii şi devenind instrumente de lucru obişnuite în multe universităţi şi facultăţi).
Defineşte un MultiWidget() pentru a prelua (din trei elemente <input>) notele şi absenţele unui elev la un obiect şi constituie un formular dinamic cu câmpuri bazate pe acest widget - servind pentru updatarea sau înscrierea notelor şi absenţelor elevilor la obiectele specifice clasei respective.
Folosind (în SQL SELECT) clauza GROUP BY cu modificatorul WITH ROLLUP putem obţine "într-un singur pas" mediile generale pe fiecare obiect şi pe fiecare arie curriculară, pentru elevii unei clase specificate.
Exprimarea corespunzătoare pentru aceasta în Python-Django (pe lângă faptul că este portabilă) este desigur mai elegantă şi mult mai concisă faţă de cea direct în SQL - dar nicidecum mai eficientă (ba dimpotrivă).
Avem de pus la dispoziţia unor funcţii de prelucrare un formular pentru introducerea mediilor unui elev (selectat din lista prezentată) la obiectele şcolare existente în momentul execuţiei - deci un formular care să redea obiectele respective împreună cu câte o casetă pentru introducerea mediei.
La intrarea într-un anumit sistem social, individul respectiv primeşte din start anumite atribute (cum ar fi: un cod numeric personal; o legitimaţie de student; o ţinută vestimentară specifică sistemului, sau un echipament de protecţie) şi trebuie să-şi însuşească din start anumite reguli şi proceduri comportamentale de bază.
Funcţionarea sistemului respectiv implică operarea cu indivizi astfel educaţi.
La fel… variabilele sunt valori pre-"educate" după anumite tipare prevăzute de limbajul respectiv.
Sensul unei expuneri dinamice a situaţiilor şcolare (şi nu doar în momentul încheierii unui ciclu şcolar) este inspirat din sportul de performanţă: rezultatele curente ale potenţialilor competitori influenţează pozitiv efortul propriu de perfecţionare. Analog, putând observa în orice moment rezultatele proprii, comparativ cu rezultatele celorlalţi şi cu mediile clasei (pe obiecte, arii curriculare, etc.) - ar fi de sperat să constatăm o motivare suplimentară pentru îmbunătăţirea continuă a pregătirii proprii, în rândul elevilor…
media unui şir de numere folosind Python; reflectarea dinamică a situaţiei şcolare
Constituind //xxx.sitsco.com alături de //docere.ro - în fond, două virtualHost-uri, pe acelaşi server Apache - am avut în final o mare surpriză: la început, accesarea din browser şi a unuia şi a celuilalt a decurs normal, dar brusc unul dintre ele mi-a returnat Internal server error; repetând disperat CTRL+F5 am putut reaccesa, dar situaţia s-a reprodus când am revenit pe celălalt site.
Cele 20 de schiţe care sunt mapate aici conduc pas cu pas, la construcţia unui browser pentru partide de şah (vezi pgn_demo), prezentând deasemenea elemente specifice domeniului "computer-chess".
Împreună, aceste schiţe ilustrează tema generală a dezvoltării unei aplicaţii Web, angajând şi achiziţionând cunoştinţe de HTML, CSS, javaScript etc., precum şi cunostinţe specifice domeniului aplicaţiei.
Avem o imagine în care am reunit piesele de şah de o aceeaşi dimensiune n şi pe de altă parte, un câmp de dimensiune nxn. Problema este de a selecta din sprite-ul nostru o piesă şi a o poziţiona pe câmpul dat, încât definiţiile CSS necesare pentru aceasta să nu depindă de n. Investigăm cum să determinăm pentru acest caz, procentele necesare pentru background-position.
Proporţionăm din ce în ce mai fin procente pozitive… dar până la urmă ajungem la o soluţie neaşteptat de simplă, folosind procente negative!

Folosind o comandă SQL, extragem informaţii dintr-o bază de date într-un fişier text; acesta este prelucrat apoi printr-un mic program Python, pentru a obţine un fragment HTML (de exemplu, elemente <option>) care în final va fi integrat într-o pagină Web (într-un <select>).
Ca să avem despre ce vorbi, o bază de date ar trebui constituită din măcar două tabele relaţionate şi ar fi de dorit să cuprindă un număr consistent de înregistrări. Dăm un exemplu de creare a unei baze de date proprii prin specularea unor pagini Web care prezintă datele care ne-ar interesa (ideea generală web scraping: colectare automată a informaţiei de pe Web).
Am improvizat la clasă acest exerciţiu: să se scrie într-un fişier toţi termenii unei dezvoltări binomiale (a + b)n; care este cel mai mare termen, pentru a = 1/4, b = 5/4 şi n = 2008?
La Matematică aceşti C(n, k) sunt utilizaţi formal (operând cu expresii, nu cu valori), pe când într-un program ei sunt efectiv nişte numere - chiar dacă "mari" - şi apar veşnicele probleme de reprezentare şi de calcul, angajând un limbaj sau altul.
cu modestele noastre posibilităţi - alegem ca temă "aniversară" calculul mediei şcolare...
S-ar cuveni să consemnăm că Dennis_Ritchie a încetat din viaţă… Dennis Ritchie este creatorul limbajului C şi implicit - unul dintre pilonii principali ai informaticii moderne; sistemele de operare - iar Dennis Ritchie este coautor al sistemului Unix - şi limbaje ca Perl, Python, PHP, javaScript etc., Internetul cu ceea ce are la bază, inclusiv browserele toate - se bazează esenţial pe limbajul C.
Presupunem că avem un fişier Excel în care este scris orarul curent al şcolii. Scriem un program în Python şi apoi folosim Sphinx, pentru a transforma fişierul respectiv într-o documentaţie (site HTML) uşor de utilizat (având referinţe încrucişate între profesori, clase, discipline) şi de întreţinut.
Site-ul rezultat: orar.docere.ro.
Cu GeoGebra poţi trasa comod ("point-and-click") şi poţi analiza figuri geometrice oricât de complexe.
Avem la şahPGN un "browser" propriu pentru partide de şah. Un asemenea instrument ar trebui să poată fi configurat pentru a fi utilizat în mai multe contexte posibile; vizăm aici posibilitatea de a-l integra într-o pagină Web care angajează partide de şah.
Pe de altă parte, partida analizată reflectă corelaţia dintre centralizare şi atacul pe flanc (specifică de altfel nu numai pentru şah, dar de exemplu şi în tenis, sau alte jocuri).
Structuri de date în Prolog (termeni compuşi, liste, operatorul "univ") şi două exemplificări: problema rucsacului şi plata unei sume în unităţi monetare date.
În programarea logică, ideea de bază este exprimată prin Algorithm = Logic + Control. Componenta Logic vizează descrierea problemei: ce fapte se cunosc şi ce reguli trebuie folosite de către "Control" pentru a deduce ulterior alte fapte (noi).
Componenta Control reprezintă însuşi interpretorul - ori fiinţa raţională - care va "executa" programele; interpretorul de Prolog "aplică" metoda deducerii (plecând de la baza de date furnizată de program) şi un mecanism intern de backtracking recursiv - căutând sistematic valori cu care să "înlocuiască" necunoscutele implicate în scopul satisfacerii clauzelor curente.
Vizăm generarea s-partiţiilor angajând metode generale: căutare "brute force" şi backtracking. Formulăm în C++ şi în Prolog (incluzând un mecanism intern de backtracking, Prolog permite "rezumarea" programului la specificarea condiţiilor necesare pentru soluţii).
Se poate partiţiona {1,2,...,n} în două submulţimi pentru care sumele corespunzătoare să aibă diferenţa dată? Care ar fi minimul acestei diferenţe? Câte astfel de partiţii există (teoremă, program C++) şi cum pot fi generate într-o anumită ordine?
Simpla verificare directă a unui rezultat este mai degrabă neinteresantă şi de obicei încercăm să corelăm verificarea manuală cu aspecte de context; putem găsi astfel posibilităţi de simplificare în program, dar poate rezulta (mai interesant!) şi ideea de a o lua de la capăt…
CCD Vaslui mi-a oferit 24 de ore (în martie-aprilie 2011) de introducere în Linux şi iniţiere în dezvoltarea de aplicaţii Web - pentru profesori de informatică, dar care folosesc curent numai Windows şi nu au experienţă de lucru pe Web.
//web24.docere.ro prezintă (cu cizelarea cuvenită) lecţiile desfăşurate. Aici prezentăm unele elemente de substrat - motivaţii, tehnici metodologice - ale acestei încercări pe 24 de ore.
Selectaţi numerele din casetă şi înscrieţi propriile numere; click pe butonul 'CMMDC' va furniza cel mai mare divizor comun al numerelor respective.
Se exemplifică realizarea unui gadget (determinarea CMMDC); funcţia javaScript necesară conţine două funcţii "private": o funcţie de reducere "divide et impera" şi o funcţie care produce CMMDC a două numere (în javaScript, funcţiile sunt obiecte - încât pe lângă variabile obişnuite pot conţine şi alte obiecte, inclusiv alte funcţii).
Aplicaţiile care vizează jocul de şah implică în anumite componente, "Portable Game Notation" (sau PGN) pentru partide şi notaţia FEN pentru poziţii de şah particulare. Prezentarea decurge în legătură cu aplicaţiile (accesibile şi din bara de meniu) şahPGN şi şahEng şi integrează dezvoltarea obiectuală a unei aplicaţii pentru realizarea unor diagrame de şah (ceea ce prilejuieşte pe parcurs anumite evidenţieri şi lămuriri: partajarea codului de către instanţele unui obiect; folosirea metodei replace(), a obiectului String(); comportarea browserului faţă de caracterul "spaţiu" şi soluţia bazată pe "spacer.gif"; etc.).
Proiectul scorar este constituit din două aplicaţii: /frontend expune încadrarea şi orarul pentru utilizatorii obişnuiţi (cu diverse facilităţi de filtrare) şi /backend, care serveşte unui administrator pentru a înscrie şi modifica datele de încadrare şi de orar.
http://scorar.docere.ro/ demonstrează aplicaţia, pe un caz real.
http://admin.scorar.docere.ro/ permite actualizările şi editările necesare.
Codul sursă (PHP, symfony, jQuery) este menţinut public pe http://github.com/vladbazon/scorar.
symfony oferă un script PHP prin care se poate genera automat un schelet de proiect, de aplicaţie, sau de modul; de obicei, proiectul angajează o bază de date, iar scriptul respectiv poate genera modulele (desigur, câte unul) în concordanţă cu schema acesteia.
Să presupunem însă un caz "extrem": baza de date conţine câteva zeci de tabele şi relaţii şi vrem să generăm toate modulele de administrare aferente acestora. Atunci, în loc să invocăm direct scriptul menţionat - pentru fiecare tabel, de atâtea ori - va fi preferabil să concepem un script Bash care să ambaleze invocarea php symfony într-un "for lista modulelor de creat".
După ce am parcurs sau măcar am răsfoit manualele (şi le-am şi întrebuinţat într-o aplicaţie proprie) am ajuns la ideea că lucrurile se puteau totuşi "prinde" şi pe calea care—oarecum paradoxal—este cea mai obişnuită: nu cu manualul începi, ci instalezi produsul, frunzăreşti oleacă prin documentaţie, apoi încerci să lansezi o aplicaţie "default" - observând ce se petrece, experimentând şi corelând cu "mici" investigaţii pe codul-sursă.
Lucrând astfel - folosind manualul nu ca pe o carte care trebuie citită în prealabil şi în mod liniar, ci pentru a căuta clarificări şi validări - se poate ajunge la acea înţelegere a principiilor de lucru specifice care este suficientă în fond, pentru a începe să foloseşti produsul conform propriilor necesităţi. Obişnuinţa cu acest stil de lucru se dovedeşte benefică apoi şi pe parcursul dezvoltării propriilor aplicaţii.

imagine bazată pe scriptul JS din the-bazon-fractal
În realitatea comună, încadrarea şcolii e una, orarul e alta, iar "revista şcolii" e cu totul altceva; o trăsătură comună este în orice caz, faptul că au o existenţă temporară, cel mult anuală.
O aplicaţie Web unifică lucrurile, pe baza faptului că ele aparţin unui aceluiaşi domeniu, fiind bazate sau angajând aceleaşi structuri şi şabloane de date. Încadrarea, orarul, situaţiile şcolare, chiar şi "revista şcolii" ţin toate de: obiecte şi profile de învăţământ, profesori, clase, elevi, schimburi de lucru - indiferent de şcoală sau de an şcolar curent.

aplicaţie Web care să permită operaţii de listare, updatare, inserare, ştergere (pe scurt, "CRUD") pentru oricare tabel existent într-o bază de date precizată (presupunând drepturi de acces corespunzătoare).
Creem un server PHP (inclusiv pentru Windows cu XAMPP) care foloseşte Ymacs (permiţând în plus, încărcare şi scriere de fişiere de pe disc).
Realizarea unei aplicaţii Web implică lucrul într-un editor de text (pe mai multe fişiere, de diverse tipuri) şi "verificări" în browser. Integrând Ymacs, avem acum acest câştig metodologic: aplicaţia se poate dezvolta (sau/şi expune pas cu pas) lucrând numai în browser: într-un Tab al browserului se încarcă şi se editează corelativ fişierele necesare (folosind bufferele Ymacs), într-un alt Tab se testează aplicaţia pe parcursul lucrului.
Programa şcolară distinge "teorie" de "practică", indicând 1 oră teorie şi 2 ore laborator; ruperea este iminentă… Manualele propun mereu să se scrie un program care, vizând cam imprudent scrierea, în loc de construirea (realizarea) programului. Rezultanta în practica obişnuită a adoptării unor astfel de portiţe de evitare a eforturilor de corelare, constă în programe monolitice: o singură funcţie - void main() - sau în orice caz, un singur fişier (nume.CPP) şi un singur "tabel" - anulând astfel, orice "teorie" şi orice legătură cu realitatea.
Avem un fişier .XLS conţinând orarul unei şcoli, în forma de editare tabelară cea mai obişnuită. Pe de altă parte, avem o aplicaţie Web, pentru expunerea în diverse moduri şi pentru întreţinerea orarului, aplicaţie constituită pe o bază de date MySQL, cu o anumită organizare internă (tabele relaţionate corespunzător pentru şcoli, schimburi, obiecte, profesori, încadrări). Redăm aici prin secvenţe Perl instructive, diverse prelucrări necesare pentru extragerea şi organizarea convenabilă a datelor din fişierul .XLS iniţial, în vederea încorporării lor în aplicaţia "Orarul şcolii".
Ataşează unui tabel HTML o bară de navigare (cu handlere corespunzătoare), încât tabelul să fie redat pe pagini de câte un anumit număr de rânduri (cu posibilitate de trecere de la o pagină la o alta), părţile de antet/subsol fiind însă menţinute pe fiecare pagină.
Tabelele trebuie să poată fi paginate în mod independent (unul faţă de celălalt) şi trebuie avut în vedere (pe cât este firesc) şi cazul tablourilor imbricate.
Aici s-a generat un tabel abstract, cu antet şi subsol, cu pagini de câte (iniţial) 3 rânduri, paginabil prin acţionarea elementelor din bara de navigare ataşată.
Definim un obiect G care în primul rând, conţine trei containere - respectiv pentru Note, Teză şi Medie; acestea sunt ele însele nişte obiecte (şi anume nişte obiecte predefinite), încât putem folosi proprietăţile şi metodele specifice lor (în cadrul obiectului G definit de noi).
Note şi Teză sunt "de tip" <input>; ca obiect, un <input> are predefinite nişte metode de interacţiune - onClick(), onKeypress(), onKeyup(), onMouseover(), etc. iar acestea se pot "redefini" pentru a răspunde în modul dorit unor evenimente precum apăsarea unei taste sau click în cadrul containerului aferent, sau în exteriorul lui, etc.
Redefinim în obiectul G, metodele onKeyup() pentru <input>-urile Note şi Teză, în aşa fel încât fiecare tastare (sau ştergere) de notă/teză să declanşeze procedura de calcul şi înscriere a mediei.
După definirea astfel a obiectului G, adăugăm o funcţie care să-l creeze conform specificaţiilor lui şi să-l anexeze documentului. În final, includem totul în "paranteze de invocare" (...)();, astfel că toate variabilele implicate rămân ne-vizibile din afară şi pe de altă parte, funcţia finală (care şi ea trebuie inclusă în paranteze de invocare) va fi pusă în execuţie imediat după încărcarea scriptului.
După ce o punem la punct astfel, transformăm aplicaţia rezultată într-un bookmarklet: eliminăm comentariile şi spaţiile (folosind un compressor), eventual escapăm şi codificăm URL anumite caractere şi apoi adăugăm scriptul rezultat în Bookmarks (implicând pseudo-protocolul javascript: în loc de obişnuitul http:).
Care este media şcolară pentru notele 9, 10, 10 şi nota în teză 9?
Unele programe/calculatoare dau 9.50, ceea ce este corect (9.4(9) = 9.5); numai că regula precizată de minister este de a calcula media "cu două zecimale exacte", rezultând nu 9.4(9) ci 9.49 - adică media şcolară este 9 (şi nu 10).
Vizăm aici modelarea corectă a calculelor cu n zecimale exacte; "media şcolară" ca formular independent (<form>, setTimeout(), onkeypress); "media şcolară" ca plugin jQuery (de montat pe un tabel de elevi).
De regulă, Algoritmul lui Dijkstra este formulat cu "tablouri paralele": d[] pentru distanţe şi p[] pentru predecesori; acestea trebuie prevăzute în cadrul programului apelant (la nivel global) - fiind folosite inclusiv pentru transmiterea rezultatelor. Unele limbaje permit însă extinderea obiectelor pe parcursul execuţiei (în sensul adăugării de noi proprietăţi) - ceea ce permite integrarea rezultatelor în structura de date transferată algoritmului de către programul apelant.
var W = {
'A': [ ['B', 5], ['C', 3], ['E', 2] ],
'B': [ ['D', 6], ['C', 2] ],
...
};
W['A'].dist = 0; // nodul de start
W['B'].dist = 4; W['B'].prec = 'C';
W['C'].dist = 3; W['C'].prec = 'A';
Manuale versus programator (implementarea unui algoritm de teoria grafurilor)
Povestea arborelui parţial minimal
Implementarea clasică (apoi, folosind o structură priority_queue<double>) a algoritmului lui Prim
Compromisuri între stil şi eficienţă; biblioteci şi interfeţe
Revenim asupra unor construcţii javaScript din Ambiţiile Cavalerului; vizam drumuri hamiltoniene pe graful săriturii calului - dar poate fi mulţumit Sir Knight? …cavalerii ăştia erau în stare să susţină o cauză până-n pânzele albe.
Cursivitatea recursivităţii (reformulare "tail recursion")
de la 'too much recursion' la formula iterativă
demersurile aplicaţiei Knight
modelarea "problemei calului" (ca graf şi ca obiect de memorie), folosind javaScript
reprezentarea vizuală a grafului în fereastra browserului
modelarea căutării unui drum hamiltonian (backtracking)
backtracking compus cu un algoritm euristic
principiul lui Warnsdorff (1823): continuă pe acel drum din care vei avea cât mai puţine ramificaţii - altfel spus, iterează recomandarea evidentă: dacă ai de ales între a face un ultim pas până la destinaţie şi respectiv a ocoli, atunci încearcă mai întâi prima variantă
Manualul vizează în paralel limbajul Pascal şi limbajul C/C++ (plus… pseudocodul excesiv). Ideea de a viza împreună mai multe limbaje de programare este excelentă, dar "realizarea" ei în acest manual este… "în paralel": programele redate în C/C++ nu sunt altceva în acest manual, decât traduceri mot-à-mot ale programelor Pascal.
Limbajul Pascal nu are o instrucţiune return. Ca urmare, traducerea mot-à-mot a funcţiilor recursive din Pascal în C duce la formulări principial greşite: if(...) return 0; else return 1;
Câte cifre are n! şi care sunt cifrele iniţiale? Câte cifre zecimale are 22009 şi care sunt primele câteva cifre?
Există n încât n! să aibă n cifre zecimale? Există n încât n! să aibă n cifre hexazecimale?
Modelarea comparativă a calculului factorialelor în bazele 10, 106, 216 (în javaScript).
Cel mai mare număr natural care are Z cifre zecimale este 10Z - 1; cel mai mare număr natural care are T cifre în baza 256 este 256T - 1. Rezultă că Z = T * lg(256) ≈ T * 2.40824, adică:
reprezentarea în baza 256 necesită de minimum 2.4 ori mai puţine "locaţii" decât cea în baza 10, iar operarea bazată pe reprezentarea în baza 256 necesită de 2.4 ori mai puţine operaţii "cifră cu cifră" decât cea bazată pe reprezentarea zecimală obişnuită.
A vedea şi Factoriale (aplicaţie accesibilă şi de pe bara de meniu).
Array .prototype .q_sort = function(beg, end) { /* QuickSort */ }
de fapt, metoda existentă sort() este tot ceea ce este necesar! restul poate fi (ca aici) un exerciţiu didactic de prezentare a unor aspecte de lucru cu obiecte Javascript.
Rezolvarea unei probleme de matematică (de exemplu, demonstrarea convergenţei unui şir) poate fi sugerată de rezultatele investigaţiei printr-un program adecvat.
În cadrul documentului HTML ar fi suficient să prevedem următoarele elemente:
— două elemente <input>, pentru a permite utilizatorului să precizeze gama de termeni de calculat (rangul iniţial şi rangul final);
— un element <div> destinat scrierii termenilor şirului, pe măsură ce vor fi calculaţi;
— un <button> a cărui acţionare prin click să declanşeze calculul şi scrierea termenilor respectivi
— un <script> care să modeleze funcţia de calculare a termenilor şirului.
Numerele vizate la matematică nu sunt la fel cu cele vizate într-un limbaj de programare; ca urmare, transcrierea mot-à-mot de la formulă matematică la program poate atrage rezultate greşite.
greşit: int id_mijloc = (id_st + id_dr) / 2; // variabile C de tip "int"
corect: int id_mijloc = id_st + (id_dr — id_st) / 2;
Când suma depăşeşte sizeof(int), rezultatul va fi trunchiat modulo INT_MAX + 1; de aceea, prima variantă de mai sus este incorectă.
Borland C++ 5.5 it's free… because GNU-GCC is great.
Obţinere şi instalare. Testare; compatibilitate cu GCC.
Un exemplu, folosind STL (Standard Template Library)
Accesaţi http://cc.codegear.com/Free.aspx?id=24778 şi creaţi-vă un cont; după ce veţi activa contul respectiv (prin intermediul serviciului de Mail), veţi putea descărca pachetul freecommandLinetools.exe a cărui execuţie asigură instalarea (pe un sistem Windows, desigur).
Putem obţine suma 1 pentru numerele 1..n?
Analiză, ilustrare (backtracking), schema programului, implementări (cu BCC şi cu GCC).
Observaţii metodice asupra lucrului în laborator.
Cea mai proastă "tehnică" pe care am văzut-o este aceasta: deschide calculatorul (şi aşteaptă să se încarce Windowsul); click pe iconiţa "Borlandc" (se deschide IDE-ul Borland C++ 3.1); între timp, deschide caietul sau manualul la programul de "implementat" (la "laborator"), aşază-l verticat lângă ecran şi începe să scrii (sau: unul dictează, celălalt scrie); când ai terminat de copiat programul, mai tastezi CTRL-F9 şi gata… (trecem la altă problemă, că pe asta am făcut-o; "algoritmul este important, nu programul"-punct).
Cu asemenea obicei şi cu asemenea concepţii reducţioniste, poţi cel mult să înveţi să dactilografiezi (fără caractere româneşti!) - nicidecum nu vei reuşi să înveţi să programezi procedând astfel (punct!).
(click pe diagramă, pentru altă poziţie)
Problema damelor
randomizare, backtracking (javascript).
Elemente de DOM (Document Object Model) pentru reprezentarea în browser a soluţiilor.
Teza teoretică (îndelung abuzată în manuale - vivat "limbajul Pseudocod") este:
programe = algoritmi + structuri de date
Evidenţiind cu instrumente adecvate, codul furnizat de compilator (pentru programe simple în Pascal, C, etc.), ajungem la formula (de memorie+CPU):
program = zonă de cod (CS; IP) + zonă de date (DS)
Angajând apoi subprograme şi analizând implicaţiile către CPU, ale realizării transferului bidirecţional de control şi de parametri - se prelungeşte formula astfel:
program = zonă_cod (CS; IP) + zonă_date (DS) + zonă_stivă (SS; SP/ESP) + cadru_stivă (BP/EBP)
unde valorile de bază DS, CS, SS rezultă prin corelare - asigurată de către sistemul de operare - cu mediul de execuţie.
În acest articol de informatică… nu avem nici o linie de program!
Sintagma Păi aşa a zis… (baronul Epstein) şi if( ... ) return 0; else return ...;
şi un fals: Informatică = Windows + produse Microsoft (point-and-click) + pseudocod.
Sintagma se citeşte de la tastatură, să se scrie pe ecran", interpretoarele de comenzi şi editoarele de text. Grosolănia point-and-click şi faţetele unui program (-sursă, -obiect, -executabil; proces).
Avem de creat un element <table> (folosim .createElement(), .appendChild() şi altele); de modificat <tbody> în tabelul inserat, încât rândurile să apară ordonate după valorile de pe o coloană; de asociat o diagramă statistică (invocăm Google Chart).
Aplicaţia noastră de salarizare are ca idee de bază refolosirea datelor. Descriem aici concepţia aplicaţiei şi soluţia cu MySql a uneia dintre problemele concrete pe care le-am avut de rezolvat în legătură cu baza de date existentă.
Esenţială pentru WEB este posibilitatea de interconectare; documentele de pe Web nu au în vedere "formatul A4" (nu vizează operaţia de tipărire pe hârtie), pentru motivul evident că de pe hârtie nu este posibilă interconectarea cu alte documente.
Pentru reprezentarea pe hârtie avem două categorii de instrumente: aşa numitele "procesoare de text" What You See Is What You Get (de exemplu, binecunoscutul Word din pachetul comercial Microsoft-Office, sau aplicaţia "free" OpenOffice.org-Writer); respectiv, limbaje de marcare/programare (TeX, cu varianta LaTeX) şi formate de reprezentare "independente de dispozitiv", precum PDF.
Transformări de documente, cu Google Docs. Obţinerea variantei PDF a unui document HTML, folosind modulul perl HTML::Latex şi elemente conjuncturale de limbaj LaTeX.
Anterior (a vedea "Hello World!" şi Subrutină performantă pentru calculul factorialelor) am realizat o subrutină în limbaj de asamblare pentru n!. Într-o primă etapă, factorialul se obţine în forma binară (în baza 2^32); în a doua etapă, se converteşte la baza 10^9 şi implicit la forma zecimală uzuală. Forma binară se obţine în 0-5 secunde (n <= 100000); însă conversia la forma zecimală durează cam de cinci ori mai mult.
Este posibilă optimizarea secvenţei de conversie… dar de ce să se ocupe serverul de conversie? (şi nu browserul). Serverul trebuie să returneze rezultatul - punct! Iar rezultatul este în cazul de faţă o valoare numerică brută, în formă binară (cel mult, hexazecimală). Cel care l-a cerut (nu serverul), trebuie să ştie ce vrea să facă cu rezultatul obţinut - să-l afişeze treaba lui cum, sau să-l utilizeze ca atare (ca valoare numerică) în calcule proprii ulterioare.
Cererea http://<HOST>/cgi-bin/amifac.cgi?1234 primeşte de la server factorialul numărului 1234, în hexazecimal. Aplicaţia rezultată este pusă la dispoziţie on-line: click pe link-ul Factoriale din bara de meniu; interfaţa conţine şi o funcţie javascript de conversie la baza 10 a unui şir de cifre hexazecimale de orice lungime (folosind schema lui Horner).
Atitudinea funcţionărească şi atitudinea creatoare, faţă de "probleme".
A ignora legăturile posibile înseamnă a scăpa şansa de "a reinventa roata", adică şansa de a învăţa regândind lucrurile.
Ecuaţia µ2 - µ + 1 = 0 provine din (abcd) = (acdb) sau (abcd) = (adbc); deci un raport este echianarmonic dacă şi numai dacă el se păstrează în urma unei permutări circulare între trei numere... coeficienţii sunt funcţii simetrice de a, b, c - deci se vor putea exprima prin coeficienţii ecuaţiei de gradul trei care are ca rădăcini numerele a, b, c; regăsim pe această cale elementară - "reinventând roata", aşa-i? - condiţia în care o ecuaţie de gradul trei are rădăcini reale (o teoremă a lui Joachimsthal) şi restabilim o metodă (dată de Cayley) de rezolvare a ecuaţiilor de gradul trei.
O mică aplicaţie pentru calculul determinanţilor şi pentru rezolvarea sistemelor de ecuaţii liniare;
totodată, o mare semnalare: sindromul lipsă de idei (sau, criza de idei).
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ă". Abandonarea efortului de cunoaştere propus în Liceu pentru diversele discipline, poate avea drept rezultat firesc lipsa de idei.
La nivel de individ, lipsa de idei decurge din îngustimea domeniului de interes şi din necorelare…
Dar "lipsa de idei" este mai ales o stare comună, specifică sistemelor închise (care nu mai pot oferi perspective reale de dezvoltare) şi nu se poate să nu fie remarcată.
Optimizări (faţă de programul în limbaj de asamblare pentru n!, realizat în "Hello World!") asupra algoritmului, asupra conversiei (baza 109) şi asupra folosirii instrucţiunii de împărţire DIV.
Se înlocuieşte înmulţirea cu fiecare factor, prin înmulţire cu produs de factori, iar operaţiile sunt modelate acum în baza 232 (în loc de modelul iniţial, bazat pe reprezentarea în baza 216). Conversia la forma zecimală este realizată acum prin intermediul bazei 109 (numerele 0..109-1 - "încap" pe 32 biţi), în loc de 104, din varianta precedentă.
Instrucţiunea microprocesorului DIV necesită cel puţin 16/24/40 tacţi pe I80486 şi 17/25/41 tacţi pe Pentium, după cum împărţitorul are 8/16/32 biţi; se rescrie programul, înlocuind împărţirea la operand (cu DIV) prin înmulţirea cu inversul operandului (MUL fiind mai rapidă ca DIV).
Formulăm în diverse limbaje, soluţionarea unei aceleiaşi probleme—calculul factorialului (recursiv). Vizăm aspecte de elaborare, aspectele algoritmice necesare şi corelaţii fireşti între limbaje.
Câte cifre are n!; aplicaţie (javascript + HTML) bazată pe logaritmi. Aplicaţie pentru compararea numărului de operaţii cifră-cu-cifră necesare calculului n! în baza 10, respectiv în baza 256.
n! în limbajele bc, PHP, Python; modelare OOP în javascript folosind baza 106; program perl folosind modulul Math::BigInt; modelare OOP în perl folosind baza 106; program C folosind biblioteca GMP; modelare OOP în C++ (GCC g++) folosind baza 216 (şi conversie la baza 104); program în limbaj de asamblare GNU as şi elemente de programare în limbaj de asamblare sub Linux (transmiterea parametrilor, funcţia mmap(), folosirea apelurilor de sistem, instrucţiunea int 0x80; folosirea instrucţiunilor FPU; informaţii asupra fişierului executabil).
scriere nu înseamnă neapărat "scriere pe ecran", ci comunicare (între procese); parametrii pot fi transmişi prin intermediul "variabilelor de mediu" (de ex., prin QUERY_STRING).
CGI extinde funcţionalitatea clasică a serverului; browserul cere serverului nu un anumit fişier, ci rezultatul execuţiei unui anumit program; serverul lansează programul respectiv şi transmite browserului ceea ce "scrie" la STDOUT programul executat. Acest program poate să fie cam în orice limbaj (fie ca script, fie ca "executabil"), dar trebuie să fie locat într-un anumit director (/cgi-bin/) şi trebuie să-şi formuleze "outputul" prefixându-l cu anumite headere HTTP ('Content-type').
Se prezintă exemple de programe CGI: mimeTeX analizează o expresie matematică primită ca parametru şi returnează imaginea GIF corespunzătoare; programe în C, în perl, în limbaj de asamblare pentru lista de "environment variables".
Se generează TOC cu javascript (dinamic - după încărcarea sursei HTML în browser), respectiv transformând cu perl fişierul-sursă HTML iniţial (static - fişierul rezultat conţine şi TOC).
Printr-o funcţie javascript se colectează elementele "heading" din cadrul documentului încărcat şi se adaugă fiecăruia un atribut ID (pentru a referi secţiunea respectivă); apoi, se creează elemente <a> având ca valoare a atributului href tocmai id-ul fixat anterior; aceste link-uri constituie apoi, elementul TOC.
my $tw = new XML::Twig() construieşte un obiect de memorie conţinând datele şi "pointeri" la metodele specifice modulului XML::Twig (pentru construcţia în memorie a arborelui elementelor HTML), dar şi "pointeri" la funcţii de transformare ("handlere") specificate de utilizator - în cazul de faţă, pentru crearea subarborelui TOC.
Plecând de la necesităţile apărute într-o aplicaţie concretă de salarizare, se concepe un DOCTYPE şi se construieşte un document XML; se prezintă apoi elemente de perl pentru extragerea/actualizarea datelor dintr-un document XML, elemente de limbaj XSLT şi un program în XSLT pentru prezentarea documentului (a "Grilei de salarizare").
Documente tabelare mari… cu Microsoft-Word? adică ignorând principiul esenţial separă! datele de prezentarea lor. Evidenţiem - dar cam întortochiat - posibilitatea de a folosi XML (reprezentarea datelor) şi XSLT (prezentare). Cam "întortochiat", fiindcă mai e vorba şi de un act oficial fundamental pentru sistemul de învăţământ şi se pune măcar problema consistenţei, dacă nu şi chestiunea mai generală a restricţiilor pe care le poate suporta un sistem (până să fie sufocat) din partea unui aparat birocratic externalizat (în raport cu procesul de învăţământ) şi amplificat continuu.
Centralizatorul Educaţiei Naţionale este o operă de politică meschină, generată de "Statutul personalului didactic" şi nu de conţinutul intrinsec al procesului de învăţământ. Datorită prestaţiei funcţionăreşti, sistemul de învăţământ tinde să devină un sistem închis, fără perspective reale de evoluţie; începe să se bazeze pe birocraţie, pe standarde mediocre şi pe "dascăli", nu pe profesori (sau Profesori) iar scopul ajunge acuşi să fie acela de a produce/reproduce funcţionari (de tip point-and-click).
birocraţia instituită extensiv deasupra unui sistem oarecare, conduce în timp la blocarea şi regresia sistemului subordonat, apoi şi a celor conexe. (regula poate să vină de la nenea Iancu: cică de-aicea nu mai ieşiiii....)
Profesorul de Informatică ajunge să fie "calificat", nu fiindcă aşa scrie pe Diplomă şi undeva pe Centralizator; înveţi ceva informatică şi înveţi să programezi cam în 10 ani iar ca să înveţi pe alţii (dar a nu confunda aceasta, cu "să-i pregăteşti pentru BAC") este necesar să ai tu însuţi o anumită experienţă nebanală (şi continuă!) de realizare a unor aplicaţii mai complexe. Per total, această experienţă nu poate fi ştampilată, nici cuantificată undeva - dar tocmai procesul de a o dobândi şi capacitatea de a o împărtăşi, face deosebirea reală între pretenţii.
Modelare şah I-XX
construcţia unui PGN-browser()
Linux şi aplicaţii Web
în 24 de ore
Orar şcolar
documentaţie Sphinx