momente şi schiţe de informatică

Un Google gadget, pentru CMMDC

Creat: 2011/mar       Comentarii

gadget | iGoogle | javaScript | XML

De la poveşti conspirative la gadget

Într-un timp, pe la Olimpiada de Informatică se propuneau spre rezolvare formulări puerile, denumite - cu obişnuita emfază conspirativă oficială - poveşti, întinse pe cel puţin trei sferturi de pagină A4, cu fel de fel de roboţei îndrăgostiţi care se plimbau prin fel de fel de galaxii să-şi caute iubita şi cu fel de fel de cartofi, sticle şi borcane… un afront asupra inteligenţei liceenilor participanţi!

În ciuda diversităţii de "termeni" şi a mărimii formulărilor, toate "poveştile" respective se reduceau an de an, la vreun gadget din teoria grafurilor, de exemplu "să se determine un drum hamiltonian", sau "se cere un drum minim între două vârfuri ale unui graf conex". Cam asta ar fi un gadget - formularea scurtă a problemei la care se reduc toate "poveştile" constituite pe un acelaşi scenariu; lunga poveste scrisă pe A4 trebuie uitată sau recuzată, abordând în schimb "gadget"-ul corespunzător.

În termeni mai noi, un gadget este o anumită piesă de cod, postată pe un domeniu accesibil public prin Internet şi care poate fi invocată pentru execuţie dintr-o pagină Web proprie; invocarea respectivă înseamnă un acces la un server de gadget care determină şi interpretează codul respectiv, returnând conţinutul care în final este inserat în pagina Web respectivă (a vedea mai bine, Google Gadgets).

Scenariu Web pentru CMMDC

Să punem la dispoziţia userului un element <input>, în care să poată tasta nişte numere naturale (cu spaţiu între ele) şi un <button> a cărui acţionare să lanseze o funcţie javaScript care să determine şi să "afişeze" CMMDC-ul numerelor tastate:

<div style="text-align:center;">
  <p style="font-size:0.85em;color:brown;"> <!-- sugestii de operare -->
    Tastaţi numere naturale, separând prin spaţiu.</p>    

  <p>
    <!-- caseta în care utilizatorul va tasta numerele sale -->
    <input type="text" value="1236 456 123456" id="first" 
           style="font-family:monospace,Courier;padding:0.1em;font-size:1.1em;font-weight:bold;color:brown;width:95%;" /> 
  </p>

  <!--butonul care declanşează funcţia cmmdc_num(), înscriind şi rezultatul-->
  <p style="margin-top:1em;">
    <button onclick="document.getElementById('result').innerHTML=''+cmmdc_num('first');" 
            style="cursor:pointer;font-weight:bold;letter-spacing:0.4px;">CMMDC</button> 
    <span style="font-size:0.9em;"> este: </span> 

    <!-- Aici va fi înscris rezultatul returnat de cmmdc_num() -->
    <span id="result" style="color:brown;font-size:1.1em;"></span>
  </p> 
</div>

Pentru simplitate, nu am considerat un fişier .css separat, ci am preferat să stilăm in-line elementele HTML respective. Desigur, dacă am fi intenţionat să constituim o mică aplicaţie Web (şi nu un gadget), atunci am fi inclus o secţiune <head> în care să specificăm într-un element <script> fişierul .js care conţine funcţia cmmdc_num().

Determinăm CMMDC folosind metoda divide et impera:

function cmmdc_num(id_sir) { // ID-ul input-ului HTML în care s-au tastat numerele
    var sir_num = document.getElementById(id_sir).value;
    var T = sir_num.split(/\s+/); // 'split'-ează la spaţiu şirul respectiv, dând T[]

    return cmmdc_deti(0, T.length - 1); // determină CMMDC folosind "divide et impera"

    function cmmdc_deti(p, q) { // CMMDC-ul numerelor din secvenţa T[p], ..., T[q]
        var m, d1, d2;
        // m = rangul numărului din mijlocul secvenţei p-q a tabloului T[] 
        // d1, d2 = CMMDC-ul numerelor din prima, respectiv a doua jumătate a secvenţei

        if(q - p <= 1) return cmmdc(T[p], T[q]);

        m = (p+q) >> 1; // deplasare la dreapta cu 1 bit (împărţire întreagă la 2)
        d1 = cmmdc_deti(p, m); // CMMDC pentru primul subtablou, apoi pentru al doilea
        d2 = cmmdc_deti(m+1, q);
        return cmmdc(d1, d2); // CMMDC-ul celor două valori obţinute pe subtablouri
    };
    
    function cmmdc(a, b) { // varianta clasică (Euclid)
        while(b) {
            var t = b;
            b = a % b;
            a = t;
        }
        return a;
    };
};

Un singur lucru ar fi aici "special" (faţă de uzanţele obişnuite în C, de exemplu): corpul funcţiei cmmdc_num() conţine definiţiile altor două funcţii; aceasta este posibil pentru că în javaScript funcţiile sunt obiecte (iar un obiect poate îngloba şi variabile şi funcţii şi alte obiecte, deopotrivă). Funcţiile interne cmmdc_deti() şi cmmdc() sunt inaccesibile dinafara funcţiei cmmdc_num() şi au acces la variabilele contextului (la tabloul T[]).

Se poate verifica faptul că avem o aplicaţie Web funcţională: salvăm funcţia redată mai sus - anume, într-un fişier cmmdc.js - şi completăm fişierul HTML redat anterior (fie el 'cmmdc.html') cu <script type="text/javascript" src="cmmdc.js"></script>; apoi se deschide fişierul HTML în browser: file:///home/user_home/cmmdc/cmmdc.html - dar astfel, aplicaţia este vizibilă numai pe calculatorul propriu; pentru a o face vizibilă prin Internet (afară de soluţia obişnuită de a posta fişierele respective pe un server, accesând apoi prin http://) - putem să o transformăm într-un gadget.

Constituirea gadget-ului 'cmmdc.xml'

Un gadget apare ca un fişier XML în care se declară ca nod rădăcină <Module> şi care conţine cel puţin două elemente - <ModulePrefs> care este un container pentru diverse informaţii de identificare (eventual şi anumite reguli de procesare) şi <Content type="html">, care de obicei conţine (într-o secţiune CDATA) tot codul (HTML şi javaScript):

<?xml version="1.0" encoding="UTF-8" ?>
<Module>

  <ModulePrefs title="CMMDC pentru două sau mai multe numere" 
               title_url="http://docere.ro/cmmdc.xml">
  </ModulePrefs>

  <Content type="html">
    <![CDATA[ 
        <!-- fragmentul HTML redat mai sus -->
        <div style="text-align:center;">
            <!-- ... -->
        </div>

        <script type="text/javascript">
            function cmmdc_num(id_sir) {
                /* ... (funcţia redată mai mai sus) */        
            };
        </script>
    ]]> 
  </Content>

</Module>

Am postat fişierul XML creat astfel, la adresa indicată în atributul title_url al elementului <ModulePrefs>. Putem încărca de la adresa respectivă, punând în bara de adresă a browserului http://docere.ro/cmmdc.xml - dar bineînţeles că rezultatul nu va consta nicidecum în "execuţia" gadget-ului, ci va fi cel mult conţinutul fişierului 'cmmdc.xml':

"Execuţia" gadget-ului - transformarea fişierului .xml respectiv într-un conţinut funcţional care poate fi încorporat într-o pagină Web oarecare - este realizată de un "server de gadget-uri". Pentru a testa funcţionalitatea şi pentru a găsi cum anume o putem întegra într-o pagină Web proprie, putem folosi instrumentul Google Page Creator:

Înscriind adresa noastră şi apoi, click Syndicate obţinem o pagină care este referită în bara de adresă prin "http://www.gmodules.com/ig/creator?synd=open&url=http://docere.ro/cmmdc.xml"; în scopul testării şi pentru eventualitatea unor modificări în codul iniţial 'cmmdc.xml' - este indicat să includem între parametrii "Query-string" şi &nocache=1 (ca urmare, se va reîncărca 'cmmdc.xml' de la adresa indicată, în loc de a se folosi versiunea (mai veche) memorată deja în cache).

Ceea ce este important în pagina obţinută astfel (de pe care am redat parţial în imaginea de mai sus) este butonul Get the Code; acesta furnizează codul care trebuie scris într-o pagină Web pentru a folosi gadgetul respectiv. Redăm mai jos acest cod, dar în formă incorectă (pentru claritate - am separat parametrii pe câte o linie şi am şters caracterul '&' din "Query-String"-ul furnizat de 'Get the Code'):

<script src="http://www.gmodules.com/ig/ifr?
             url = http://docere.ro/cmmdc.xml
             synd = open
             w = 320
             h = 140
             title = CMMDC+pentru+dou%C4%83+sau+mai+multe+numere
             border = http%3A%2F%2Fwww.gmodules.com%2Fig%2Fimages%2F&amp;
             output = js">
</script>

Acest cod HTML trebuie înscris în fişierul HTML al paginii Web proprii, în locul unde vrem să apară conţinutul care va fi returnat de serverul Google.

//www.gmodules.com/ig/ifr? va prelua 'cmmdc.xml' de la adresa indicată în parametrul url, va interpreta codul respectiv, va completa conţinutul cu secţiunile <html>, <head> şi <body> (fixând şi title, width, height, border conform valorilor parametrilor title, w, h, border) şi va ambala rezultatul într-un element <iframe> pe care îl va returna browserului în care userul a deschis pagina Web respectivă (parametrul "ifr?" vrea să indice "iframe").

Inserarea gadget-ului într-o pagină iGoogle

Având un cont Google, la accesarea http://www.google.com/ se obţine o pagină Web precum:

Aceasta ar fi pagina Google standard, dar ea poate fi personalizată (rezultând o pagină Web proprie, găzduită pe http://google.com/ig/) - anume, accesând link-ul iGoogle (marcat prin cursor, în imaginea redată; a vedea şi adresa corespunzătoare, în bara de la baza imaginii).

După click pe linkul iGoogle indicat mai sus, rezultă:

Aici, linkul Adăugaţi Gadget (marcat de cursor, în imaginea redată) conduce la o pagină care listează gadget-urile salvate până la momentul curent pe //www.google.com/ig/directory; partea stângă a paginii conţine o listă de link-uri pentru a accesa mai uşor diverse categorii de gadget-uri, iar la sfârşitul acestei liste găsim:

Click pe linkul Adăugaţi feed sau obiect gadget (marcat în imaginea de mai sus) ne permite să indicăm adresa gadget-ului şi să adăugăm obiectul respectiv în pagina iGoogle proprie:

Revenind apoi la pagina iniţială, vedem că într-adevăr s-a inclus şi conţinutul corespunzător gadget-ului nostru:

Iar dacă am vrea aceasta, gadget-ul nostru 'cmmdc.xml' poate fi şi el înscris în directorul Google de gadget-uri /ig/directory - anume, accesând http://www.google.com/ig/submit (bineînţeles că ne abţinem - nefiind vorba decât de o ilustrare a lucrurilor şi nu de un gadget despre care să putem considera că ar merita un interes suficient de larg).

Desigur, oricine (dacă şi-a făcut în prealabil un cont Google) poate proceda cum am arătat mai sus în pagina iGoogle a sa, cu oricare gadget existent undeva.

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, 2018

//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