Funcţii singulare

Mărimea: px
Porniți afișarea la pagina:

Download "Funcţii singulare"

Transcriere

1 Ministerul Educaţiei, Cercetării şi Tineretului Vlad Tudor Huţanu Carmen Popescu Manual de PENTRU CLASA A XII-A filiera teoretică, profil real, specializarea: matematică-informatică, intensiv informatică Aprobat prin ordinul MEdCT nr. 1561/83 din L&S Info-mat

2 Copyright L&S INFO-MAT Toate drepturile asupra acestei lucrǎri aparţin editurii L&S INFO-MAT. Reproducerea integralǎ sau parţialǎ a textului din aceastǎ carte este posibilǎ doar cu acordul în scris al editurii L&S INFO-MAT. Manualul a fost aprobat prin Ordinul Ministrului Educaţiei, Cercetǎrii şi Tineretului nr / 83 din în urma evaluǎrii calitative şi este realizat în conformitate cu programa analiticǎ aprobatǎ prin Ordin al ministrului Educaţiei şi Cercetǎrii nr din Refenţi ştiinţifici: Prof. Gradul I Carmen Mincǎ, Colegiul Naţional Sf. Sava", Bucureşti Prof.Gradul I, Enciu Magdalena, Colegiul Naţional Octav Onicescu, Bucureşti Tiparul executat la S.C. LuminaTipo S.R.L. Str. Luigi Galvani nr. 20 bis, Sector 2, Bucureşti, office@luminatipo.com Editura L&S INFO-MAT: Adresa: Str. Stânjeneilor nr. 6, bl. 30, sc. A, et. 1, apt. 11, sector 4, Bucureşti; Mobil: ; ; office@ls-infomat.ro; Web Site:

3 CUPRINS Partea I. Baze de date 7 Capitolul 1. Proiectarea bazelor de date Noţiuni introductive Normalizarea datelor Implementarea modelului conceptual Managementul de proiect 41 Teme de proiect 45 Partea a II-a. Programare WEB 47 Capitolul 2. Limbajul MySQL Ce este şi de ce învăţăm MySQL? Cum rulăm MySQL pe propriul calculator? Crearea unei baze de date Tabele. Noţiuni elementare Tipuri de date în MySQL Operatori utilizaţi în MySQL Funcţii MySQL Afişarea coloanelor care rezultă în urma unui calcul Valoarea NULL Valori implicite Cheie primară şi cheie unică Autoincrementare Sortarea datelor Filtrarea datelor Actualizări într-un tabel Funcţii agregate Utilizarea subinterogărilor Gruparea datelor Uniuni de tabele Elemente care privesc securitatea bazelor de date 85 Probleme Propuse 86

4 4 Manual de Informatică pentru clasa a XII-a Capitolul 3. Primii paşi către construcţia unui site Ce este Internetul? Protocolul TCP/IP Despre site-uri Un program care rulează sub FTP Cum scriem un fişier HTML? 99 Teste recapitulative 103 Capitolul 4. HTML, CSS primele noţiuni Structura de bază a unei pagini HTML+CSS Elemente HTML pentru afişarea textelor Atribute CSS pentru font-uri Atribute CSS pentru texte Liste Structura unui element HTML Atribute de culoare şi fond Atribute pentru margini Atribute pentru padding Atribute pentru bordură Elementul IMG Tabele Hiperlegături (link-uri) Hărţi imagine Elementele BASE, META şi SCRIPT Cadre (FRAMESET, FRAME şi IFRAME) Elementul MARQUEE Aşezarea implicită în pagină a diverselor elemente Alte modalităţi de aşezare în pagină a elementelor Atributul z-index Atributul display Caractere HTML Aspecte generale ale proiectării interfeţelor web 161 Probleme propuse 165 Capitolul 5. Limbajul PHP Introducere Formulare Elementul TEXTAREA Elementul SELECT Constante. Variabile. Operatori Instrucţiunile limbajului PHP 181

5 Cuprins Funcţii în PHP Funcţii matematice Afişarea datelor - echo şi print Funcţii pentru prelucrarea şirurilor de caractere Masive în PHP Variabile cookie Utilizarea în comun a limbajelor PHP şi MySQL Aplicaţii Proiectarea paginilor web 212 Probleme propuse 213 Teme de proiect 215 Partea a III-a. Programare orientată pe obiecte şi programare vizuală 216 Capitolul 6. Iniţiere în utilizarea limbajului Java Cum instalăm Java? Primul program Conceptul de Maşină Virtuală Java (JVM) Tipuri de aplicaţii Java Comentarii Afişarea şirurilor de caractere Tipuri de date Operatori Instrucţiuni Masive Citirea datelor de la tastatură 244 Probleme rezolvate Date membru Metode Exemple de utilizare a metodelor Supraîncărcarea metodelor 252 Capitolul 7. Programare orientată pe obiecte Principiile programării orientate pe obiecte Constructori Date membru statice şi metode statice Cuvântul cheie this Referinţe către obiecte Masive de obiecte Aplicaţii ale noţiunilor prezentate. Lucrul cu numere raţionale Studiul unor clase din limbajul Java Extinderea claselor (moştenirea) Polimorfism 282

6 6 Manual de Informatică pentru clasa a XII-a Clase abstracte Interfeţe Specificatori de acces (modificatori de acces) Excepţii (tratarea erorilor) 296 Probleme propuse 305 Capitolul 8. Programare vizuală Conceptele de bază ale programării vizuale în Java Studiul principalelor componente Obiecte grafice. Clasa Graphics Accesarea şi prelucrarea datelor 356 Probleme propuse 363 Teme de proiect 366 Anexa 1. Instalarea programelor Apache, PHP şi MySQL 367 Anexa 2. Dezvoltarea profesională în domeniul IT 369 Anexa 3. Caractere HTML 377 Indicaţii / Răspunsuri 380

7 PARTEA I CAPITOLUL Proiectarea bazelor de date În acest prim capitol veţi studia principiile generale ale proiectării bazelor de date, vă veţi familiariza cu diversele anomalii care pot invalida bazele de date, precum şi cu modalităţile de evitare ale acestora. De asemenea, se va defini modelul conceptual al unei baze de date. În ultima parte a capitolului, vor fi prezentate etapele realizării unui proiect, avantajele lucrului în echipă şi veţi învăţa cum să pregătiţi şi să susţineţi o prezentare în faţa publicului. Ce este modelul conceptual şi care este rolul său? Ce este un ERD? Ce este o entitate şi cum se reprezintă ea într-un ERD? Ce este o instanţă? Ce sunt şi cum se stabilesc atributele unei entităţi? Cum se stabilesc relaţii între entităţi? Ce tipuri de relaţii pot exista între entităţi? Cum se reprezintă relaţiile în ERD? Normalizarea datelor Cum se implementează modelul conceptual? Managementul de proiect Cuvinte cheie: dată, informaţie, cunoştinţă, analiză, model conceptual, entitate, instanţă, atribut, identificator unic, relaţie, normalizare, mapare, integritate, proiect, echipă, prezentare

8 8 Manual de Informatică pentru clasa a XII-a 1.1. Noţiuni introductive Date. Informaţii. Cunoştinţe Auzim adesea vorbindu-se despre era informaţiilor sau societatea informaţională sau tehnologia informaţiei, însă de multe ori cuvântul "informaţie" este folosit fără a-i înţelege clar sensul, diferenţa dintre date, informaţii sau cunoştinţe. În general, conţinutul gândirii umane operează cu următoarele concepte: Date constau în material brut, fapte, simboluri, numere, cuvinte, poze fără un înţeles de sine stătător, neintegrate într-un context, fără relaţii cu alte date sau obiecte. Ele se pot obţine în urma unor experimente, sondaje, etc. Informaţii prin prelucrarea datelor şi găsirea relaţiilor dintre acestea se obţin informaţii care au un înţeles şi sunt integrate într-un context. Datele, organizate şi prezentate într-un mod sistematic pentru a sublinia sensul acestora, devin informaţii. Pe scurt, informaţiile sunt date prelucrate. Informaţiile se prezintă sub formă de rapoarte, statistici, diagrame, etc. Cunoştinţe colecţii de date, informaţii, adevăruri şi principii învăţate, acumulate de-a lungul timpului. Informaţiile despre un subiect, reţinute şi înţelese, ce pot fi folosite în luarea de decizii, care pot forma judecăţi şi opinii, devin cunoştinţe. Cu alte cuvinte, cunoştinţele apar în momentul utilizării informaţiei Colectarea şi analizarea datelor. Modelul conceptual Primul pas în realizarea unei aplicaţii de baze de date este analiza datelor şi realizarea unei scheme conceptuale (model conceptual) ale acestora. În această etapă sunt analizate natura şi modul de utilizare a datelor. Sunt identificate datele care vor trebui memorate şi procesate, se împart în grupuri logice şi se identifică relaţiile care există între aceste grupuri. Analiza datelor este un proces uneori dificil, care necesită mult timp, însă este o etapă obligatorie. Fără o analiză atentă a datelor şi a modului de utilizare a acestora, vom realiza o bază de date care, putem constata în final, că nu întruneşte cerinţele beneficiarului. Ideea de bază a analizei datelor şi a construirii modelului conceptual este "să măsori de două ori şi să tai o singură dată". Informaţiile necesare realizării modelului conceptual se obţin folosind metode convenţionale precum intervievarea oamenilor din cadrul organizaţiei şi studierea documentelor folosite.

9 Capitolul 1. Proiectarea bazelor de date 9 Odată obţinute aceste informaţii, ele trebuie reprezentate într-o formă convenţională care să poată fi uşor înţeleasă de toată lumea. O astfel de reprezentare este diagrama entităţi-relaţii, numită şi harta relaţiilor sau ERD-ul (Entity Relationship Diagram). Aceste scheme sunt un instrument util care uşurează comunicarea între specialiştii care proiectează bazele de date şi programatori, pe de o parte şi beneficiari, pe de altă parte. Aceştia din urmă pot înţelege cu uşurinţă o astfel de schemă, chiar dacă nu sunt cunoscători în domeniul IT. În cele ce urmează, vom prezenta principalele elemente care intră în componenţa unui ERD precum şi convenţiile de reprezentare a acestora Entităţi. Instanţe. Atribute. Identificator unic O entitate este un lucru, obiect, persoană sau eveniment care are semnificaţie pentru afacerea modelată, despre care trebuie să colectăm şi să memorăm date. O entitate poate fi un lucru real, tangibil precum o clădire, o persoană, poate fi o activitate precum o programare sau o operaţie sau poate fi o noţiune abstractă. O entitate este reprezentată în ERD printr-un dreptunghi cu colţurile rotunjite. Numele entităţii este întotdeauna un substantiv la singular şi se scrie în partea de sus a dreptunghiului cu majuscule, ca în Fig. 1.1: PROFESOR PACIENT ELEV Figura 1.1. Exemple de entităţi şi modul de reprezentare O entitate este de fapt o clasă de obiecte şi pentru orice entitate există mai multe instanţe ale sale. O instanţă a unei entităţi este un obiect, o persoană, un eveniment particular din clasa de obiecte care formează entitatea. De exemplu, elevul X din clasa a IX-a A de la Liceul de Informatică din localitatea Y este o instanţă a entităţii ELEV. După cum se vede, pentru a preciza o instanţă a unei entităţi, trebuie să specificăm unele caracteristici ale acestui obiect, să-l descriem (să precizăm de exemplu numele, clasa, şcoala, etc.). Aşadar, după ce am identificat entităţile trebuie să descriem aceste entităţi în termeni reali, adică să le stabilim atributele. Un atribut este orice detaliu care serveşte la identificarea, clasificarea, cuantificarea, sau exprimarea stării unei instanţe a unei entităţi. Atributele sunt informaţii specifice ce trebuie cunoscute şi memorate. De exemplu, atributele entităţii ELEV sunt numele, prenumele, adresa, numărul de telefon, adresa de , data naşterii, etc.

10 10 Manual de Informatică pentru clasa a XII-a În cadrul unui ERD, atributele se vor scrie imediat sub numele entităţii, cu litere mici. Un atribut este un substantiv la singular (vezi Fig. 1.2). Figura 1.2. Exemplu de entitate ELEV # cnp * nume * prenume * data_nasterii * adresa telefon Un atribut poate fi obligatoriu sau opţional. Dacă un atribut este obligatoriu, pentru fiecare instanţă a entităţii respective trebuie să avem o valoare pentru acel atribut: de exemplu, este obligatoriu să cunoaştem numele elevilor. Pentru un atribut opţional putem avea instanţe pentru care nu cunoaştem valoarea atributului respectiv. De exemplu, atributul al entităţii ELEV este opţional, un elev putând să nu aibă adresă de . Un atribut obligatoriu este precedat în ERD de un asterisc *, iar un atribut opţional va fi precedat de un cerculeţ o. Atributele care definesc în mod unic instanţele unei entităţi se numesc identificatori unici (UID). UID-ul unei entităţi poate fi compus dintr-un singur atribut, precum codul numeric personal ce poate fi un identificator unic pentru entitatea ELEV. În alte situaţii, identificatorul unic este compus dintr-o combinaţie de două sau mai multe atribute. De exemplu, combinaţia dintre titlu, numele autorului şi data apariţiei poate forma unicul identificator al entităţii CARTE. Oare combinaţia titlu şi nume autor nu era suficientă? Răspunsul este NU, deoarece pot exista mai multe volume scrise de Mihai Eminescu având toate titlul Poezii, dar apărute la date diferite. Atributele care fac parte din identificatorul unic al unei entităţi vor fi precedate de semnul diez # (vezi Fig. 1.2 şi Fig. 1.3). Figura 1.3. Alt exemplu de entitate CARTE # titlu # autor # data_aparitiei * format * numar_pagini Observaţie! Atributele din UID sunt întotdeauna obligatorii, însă semnul # este suficient, nu mai trebuie pus şi un semn asterisc în faţa acestor atribute. Valorile unor atribute se pot modifica foarte des, ca de exemplu atributul vârstă. Spunem, în acest caz, că avem de a face cu un atribut volatil. Dacă valoarea unui atribut însă se modifică foarte rar sau deloc (de exemplu data naşterii) acesta este un atribut non-volatil. Evident este de preferat să folosim atribute non-volatile atunci când acest lucru este posibil.

11 Capitolul 1. Proiectarea bazelor de date 11 Identificaţi entităţile pentru următoarele scenarii. Identificaţi apoi pentru fiecare entitate atributele sale, stabiliţi opţionalitatea acestora şi precizaţi unicul identificator al fiecărei entităţi. Indicaţie. Subliniaţi substantivele care au semnificaţie pentru afacerea descrisă. Un substantiv va fi subliniat doar la prima sa apariţie. Dintre aceste substantive veţi alege apoi entităţile. 1. Pentru a se abona la diverse reviste, persoanele doritoare trebuie să furnizeze numele, adresa şi un număr de telefon. Fiecare revistă este identificată prin titlu, numărul volumului şi data apariţiei. Abonaţii semnează pentru abonare un contract pe o anumită perioadă de timp specificată prin data de început a abonamentului şi data finală. Bineînţeles că o persoană se poate abona la mai multe reviste în acelaşi timp. 2. Despre angajaţii unei firme se cunoaşte numele, titlul, numărul de telefon de la birou. Angajaţii pot fi implicaţi într-o serie de proiecte ce se desfăşoară în cadrul firmei. Despre fiecare proiect se cunoaşte numele, data la care a demarat proiectul şi se poate cunoaşte o dată la care se va finaliza proiectul. La fiecare proiect lucrează un singur angajat, însă un angajat poate fi implicat în mai multe proiecte. Fiecare angajat are un manager, cu excepţia directorului. Managerii pot fi şi ei implicaţi în proiecte Relaţii între entităţi În lumea reală, obiectele nu există izolat. Percepem obiectele din lumea reală doar în conexiune cu alte obiecte, de exemplu vom spune 'pământul se învârte în jurul soarelui', 'el este medic', etc. Aşadar, după ce aţi identificat care sunt entităţile şi atributele acestor entităţi, este timpul să punem în evidenţă relaţiile care există între aceste entităţi, modul în care acestea comunică între ele. O relaţie este o asociere, legătură sau conexiune existentă între entităţi şi care are o semnificaţie pentru afacerea modelată. Orice relaţie este bidirecţională, legând două entităţi sau o entitate cu ea însăşi. De exemplu, elevii studiază mai multe materii, o materie e studiată de către elevi. Orice relaţie este caracterizată de următoarele elemente: - numele relaţiei; - opţionalitatea relaţiei; - gradul (cardinalitatea) relaţiei.

12 12 Manual de Informatică pentru clasa a XII-a Să luăm ca exemplu relaţia existentă între entităţile JUCĂTOR şi ECHIPĂ. Vom spune: Numele relaţiei este: joacă. Un JUCĂTOR joacă într-o ECHIPĂ. Pentru a stabili opţionalitatea relaţiei trebuie să răspundem la următoarele întrebări: un jucător trebuie să joace într-o echipă? Se poate ca un jucător să nu joace în nicio echipă? Dacă acceptăm faptul că toţi jucătorii trebuie să joace într-o echipă, relaţia este obligatorie sau mandatorie şi vom spune că: Un JUCĂTOR trebuie să joace într-o ECHIPĂ. Dacă însă acceptăm că există jucători care nu joacă în nicio echipă (de exemplu, li s-a terminat contractul şi în momentul de faţă nu mai joacă la nicio echipă), atunci relaţia este opţională. În acest caz, vom spune că: Un JUCĂTOR poate juca la o ECHIPĂ. Cardinalitatea relaţiei este dată de numărul de instanţe ale entităţii din partea dreaptă a relaţiei care pot intra în relaţie cu o instanţă a entităţii din partea stângă a relaţiei. Adică va trebui să răspundem la întrebări de genul: la câte echipe poate juca un jucător? Răspunsurile posibile sunt unul şi numai unul sau unul sau mai mulţi. Vom spune: sau Un JUCĂTOR trebuie/poate să joace la o ECHIPĂ şi numai una. Un JUCĂTOR trebuie/poate să joace la una sau mai multe ECHIPE. Cea mai realistă variantă a relaţiei dintre JUCĂTOR şi ECHIPĂ este aşadar: Un JUCĂTOR poate să joace la o ECHIPĂ şi numai una. Am precizat însă mai înainte că orice relaţie este bidirecţională. Relaţia dintre ECHIPĂ şi JUCĂTOR o putem enunţa astfel: La o ECHIPĂ trebuie să joace unul sau mai mulţi JUCĂTORI Convenţii de reprezentare a relaţiilor În cadrul diagramei entităţi-relaţii, o relaţie va fi reprezentată printr-o linie ce uneşte cele două entităţi. Deoarece o relaţie este bidirecţională, linia ce uneşte cele două entităţi este compusă din două segmente distincte, câte unul pentru fiecare entitate. Tipul segmentului ce pleacă de la o entitate ne va indica opţionalitatea relaţiei dintre această entitate şi entitatea aflată în cealaltă parte a relaţiei. Dacă acest segment este continuu este vorba de o relaţie obligatorie, o linie întreruptă indică o relaţie opţională.

13 Capitolul 1. Proiectarea bazelor de date 13 De exemplu, în Fig. 1.4 segmentul ce pleacă de la entitatea JUCĂTOR, fiind întrerupt, înseamnă că un jucător poate juca la o echipă, adică relaţia este opţională. Segmentul ce pleacă dinspre entitatea ECHIPĂ este continuu, deci la o echipă trebuie să joace jucători. Figura 1.4. Reprezentarea relaţiilor Modul în care o linie se termină spre o entitate este important. Dacă se termină printr-o linie simplă, înseamnă că o instanţă şi numai una a acestei entităţi este în relaţie cu o instanţă a celeilalte entităţi. În exemplul anterior, linia de la JUCATOR la ECHIPA se termină în partea dinspre ECHIPA cu o linie simplă, deci un jucător joacă la o echipă şi numai una. Dacă linia se termină cu trei linii (picior de cioară), înseamnă că mai multe instanţe ale entităţii pot corespunde unei instanţe a celeilalte entităţi. În exemplul anterior, linia de la ECHIPĂ la JUCĂTOR se termină cu piciorul de cioară, înseamnă că unei instanţe a entităţii ECHIPĂ îi corespund mai multe instanţe ale entităţii JUCĂTOR, adică o echipă are unul sau mai mulţi jucători. Caracteristica relaţiei Valoare Mod de reprezentare Numele relaţiei un verb se scrie deasupra relaţiei relaţie obligatorie (TREBUIE) linie continuă Opţionalitatea relaţie opţională linie întreruptă (POATE) una şi numai una linie simplă Cardinalitatea picior de cioară una sau mai multe Tabelul 1.1. Moduri de reprezentare a unei relaţii Tipuri de relaţii Variantele de relaţii ce pot exista între două entităţi sunt prezentate mai jos: - relaţii one-to-one acest tip de relaţie este destul de rar întâlnit uneori, astfel de relaţii pot fi modelate transformând una dintre entităţi în atribut al celeilalte entităţi. - relaţii one-to-many sunt cele mai întâlnite tipuri de relaţii, însă şi aici, cazurile c) şi d) prezentate în Fig. 1.6, sunt mai puţin uzuale;

14 14 Manual de Informatică pentru clasa a XII-a Figura 1.5. Exemple de relaţii one-to-one Figura 1.6. Exemple de relaţii one-to-many - relaţii many-to-many aceste tipuri de relaţii apar în prima fază a proiectării bazei de date, însă ele trebuie să fie ulterior eliminate. Fig. 1.7 prezintă câteva exemple de astfel de relaţii. Figura 1.7. Exemple de relaţii many-to-many

15 Capitolul 1. Proiectarea bazelor de date Rezolvarea relaţiilor many-to-many După cum am precizat anterior, relaţiile many-to-many pot apărea într-o primă fază a proiectării bazei de date, însă ele nu au voie să apară în schema finală. Să considerăm relaţia dintre entităţile STUDENT şi CURS (vezi Fig. 1.8). Se ştie că orice curs se termină în general cu un examen. Unde vom memora nota studentului la fiecare examen? Figura 1.8. Exemplu de relaţie many-to-many Dacă încercăm să introducem atributul nota la entitatea STUDENT, nu vom şti cărei materii îi corespunde acea notă, întrucât unei instanţe a entităţii STUDENT îi corespund mai multe instanţe ale entităţii CURS. Invers, dacă încercăm să memorăm nota în cadrul entităţii CURS, nu vom şti cărui student îi aparţine acea notă. Rezolvarea unei relaţii many-to-many constă introducerea unei noi entităţi numită entitate de intersecţie, pe care o legăm de entităţile originale prin câte o relaţie one-to-many. Paşii în rezolvarea unei relaţii many-to-many sunt următorii: se găseşte entitatea de intersecţie - pentru exemplul nostru, vom introduce entitatea INSCRIERE: Figura 1.9. Rezolvarea relaţiilor many-to-many, pasul 1

16 16 Manual de Informatică pentru clasa a XII-a crearea noilor relaţii: o o o opţionalitatea: relaţiile care pleacă din entitatea de intersecţie sunt întotdeauna obligatorii în această parte. În partea dinspre entităţile originale, relaţiile vor păstra opţionalitatea relaţiilor iniţiale. cardinalitatea: ambele relaţii sunt de tip one-to-many, iar partea cu many va fi întotdeauna înspre entitatea de intersecţie. numele noilor relaţii: Figura Rezolvarea relaţiilor many-to-many, pasul 2 adăugarea de atribute în cadrul entităţii de intersecţie, dacă acestea există. În exemplul nostru ne poate interesa, să spunem, data la care s-a înscris un student la un curs, data la care a finalizat cursul, precum şi nota obţinută la sfârşitul cursului. Figura Rezolvarea relaţiilor many-to-many, pasul 3

17 Capitolul 1. Proiectarea bazelor de date 17 stabilirea identificatorului unic pentru entitatea de intersecţie: dacă entitatea de intersecţie nu are un identificator unic propriu, atunci acesta se poate forma din identificatorii unici ai entităţilor iniţiale, la care putem adăuga atribute ale entităţii de intersecţie. În exemplul nostru, identificatorul unic al entităţii de intersecţie este format din id-ul studentului, id-ul cursului şi data înscrierii la curs. Faptul că identificatorul unic al unei entităţi preia identificatorul unic din altă entitate cu care este legată este reprezentat grafic prin bararea relaţiei respective, înspre entitatea care preia UID-ul celeilalte entităţi: Figura Rezolvarea relaţiilor many-to-many, pasul 4 1. O bază de date va memora orarul unei universităţi. Fiecare curs este parte a unui modul, iar fiecărui curs îi este asociat exact un profesor. La fiecare curs participă mai mulţi studenţi. Fiecare poziţie din orar corespunde unei zile a săptămânii şi unei anumite ore. Fiecare poziţie din orar durează exact o oră, dar uneori un curs poate dura mai multe ore consecutive, însă nici un curs nu poate apărea în zile diferite sau la ore diferite neconsecutive ale aceleiaşi zile. Fiecare profesor şi fiecare student pot avea mai multe ore de curs la care participă în decursul unei săptămâni.

18 18 Manual de Informatică pentru clasa a XII-a Care dintre următoarele variante NU este o soluţie posibilă a acestei probleme? a) Se stabileşte o relaţie one-to-many între CURS şi POZITIE_ORAR; b) Se stabileşte o relaţie many-to-many între CURS şi POZITIE_ORAR; c) Pentru fiecare curs vom avea un atribut start care reţine ora de începere a cursului şi un atribut durată care memorează numărul de poziţii consecutive din orar "ocupate" de acel curs; d) Pentru fiecare curs vom avea două atribute primul şi ultimul care memorează prima şi respectiv ultima poziţie din orar ocupată de acel curs. 2. Fie următoarea hartă a relaţiilor: Figura Relaţia propusă pentru problema 2 Cum se citeşte corect relaţia dintre CLIENT şi MAŞINA? a) Fiecare CLIENT poate să închirieze o MAŞINĂ şi numai una. b) Fiecare CLIENT trebuie să închirieze o MAŞINĂ şi numai una. c) Fiecare CLIENT poate să închirieze una sau mai multe MAŞINI. d) Fiecare CLIENT trebuie să închirieze una sau mai multe MAŞINI. 3. Numele unei entitǎţi este de obicei: a) un verb; b) un substantiv ; c) un adverb; d) orice cuvânt. 4. Care dintre următoarele variante NU poate reprezenta un atribut al entităţii PANTOF? a) culoare; b) mărime; c) model; d) clasa. 5. Care dintre următoarele fraze pot fi citite din schema de mai jos? Figura Relaţia propusă pentru problema 5

19 Capitolul 1. Proiectarea bazelor de date 19 a) Un student poate să urmeze mai multe cursuri. b) Un curs poate fi urmat de mai mulţi studenţi. c) Un student trebuie să urmeze un singur curs. d) Un curs trebuie să fie urmat de un student. 6. Ce semnificaţie are piciorul de cioară ( ) în cadrul unui ERD? a) relaţia este obligatorie; b) relaţia este opţională; c) pot exista una sau mai multe instanţe ale entităţii lângă care apare semnul în relaţie cu o instanţă a celeilalte entităţi; d) niciuna din variantele anterioare. 1. Completaţi în tabelul următor, în prima coloană, câte un exemplu de entitate a cărui atribut este specificat în coloana a doua: Entitate Atribut culoare nr_calorii volum Tabelul Citiţi, în ambele sensuri, următoarele relaţii. Din ce atribute este compus UID-ul fiecărei entităţi? Figura Relaţiile propuse pentru problema 2

20 20 Manual de Informatică pentru clasa a XII-a 3. Rezolvaţi următoarele relaţii many-to-many: Figura Relaţiile propuse pentru problema 3 4. Daţi două exemple de relaţii one-to-many. (vezi baremele de notare şi de corectare de la pag. 380) 1. Reluaţi aplicaţiile de la pagina 11 şi stabiliţi relaţiile dintre entităţile de la fiecare exerciţiu. Rezolvaţi apoi eventualele relaţii many-to-many. Verificaţi să nu existe relaţii redundante în schemele obţinute. Pentru scenariile de la punctele 2-5, determinaţi entităţile, atributele acestora şi relaţiile dintre entităţi. Desenaţi harta relaţiilor pentru fiecare exerciţiu în parte. 2. O firmă produce mai multe tipuri de maşini, un model fiind caracterizat printr-un nume, mărimea motorului şi un sufix care indică gradul de lux al acesteia (de exemplu XL, GL). Fiecare model este construit din mai multe părţi, fiecare parte putând fi folosită pentru construirea mai multor modele de maşini. Fiecare parte are o descriere şi un cod. Fiecare model de maşină este produs de exact o fabrică a firmei, fabrică ce se poate găsi în una din ţările UE. O fabrică poate produce mai multe modele de maşini şi mai multe tipuri de părţi componente. De asemenea, fiecare tip de parte componentă poate fi produsă de o singură fabrică a firmei.

21 Capitolul 1. Proiectarea bazelor de date O universitate are în componenţa sa mai multe facultăţi, fiecare facultate având mai multe departamente. Fiecare departament oferă studenţilor mai multe cursuri. Un profesor poate lucra la un singur departament al unei singure facultăţi. Fiecare curs are mai multe secţiuni, iar o secţiune poate să facă parte din mai multe cursuri. Un profesor poate preda mai multe secţiuni, din acelaşi curs sau din cursuri diferite, dar o secţiune poate fi predată de mai mulţi profesori. 4. La o facultate este nevoie să se memoreze date despre studenţi, cursuri şi secţiunile fiecărui curs. Fiecare student are un nume, un număr de identificare, adresa de acasă, adresa temporară, pentru cei care nu fac facultatea în localitatea lor. Un student poate opta să urmeze un curs întreg sau doar anumite secţiuni ale unui curs. De asemenea, el poate urma mai multe cursuri şi/sau secţiuni de curs simultan. Un curs poate avea mai multe secţiuni, dar o secţiune poate fi parte a mai multor cursuri. 5. Angajaţii unei firme sunt redistribuiţi la diferitele departamente din cadrul firmei. Dorim ca în baza de date să memorăm, pentru fiecare angajat, departamentul la care lucrează acum, dar şi departamentul la care a lucrat prima dată, la angajarea în firmă.

22 22 Manual de Informatică pentru clasa a XII-a 1.2. Normalizarea datelor Ce este normalizarea? Normalizarea este o tehnică de proiectare a bazelor de date prin care se elimină (sau se evită) anumite anomalii şi inconsistenţe ale datelor. O bază de date bine proiectată nu permite ca datele să fie redundante, adică aceeaşi informaţie să se găsească în locuri diferite sau să se memoreze în baza de date informaţii care se pot deduce pe baza altor informaţii memorate în baza de date. Anomaliile care pot să apară la o bază de date nenormalizată sunt următoarele: - anomalii la actualizarea datelor închipuiţi-vă că la secretariatul şcolii voastre sunt memorate într-o tabelă informaţiile despre toţi elevii şcolii: nume, adresă, telefon, etc. De asemenea, la biblioteca şcolii există fişele voastre tot într-o tabelă. Aceste fişe conţin numele, prenumele, adresa, telefonul, data înscrierii la bibliotecă, etc. Acum câteva zile v-aţi schimbat domiciliul. Noua adresă trebuie modificată atât la secretariat cât şi în fişa de la bibliotecă şi în toate locurile în care această informaţie apare. Dacă modificarea nu se produce în unul dintre aceste locuri (fie că aţi uitat să anunţaţi, fie din alte motive), datele devin inconsistente. Alt scenariu: la o bibliotecă se înregistrează într-o tabelă următoarele date despre cărţi: ISBN, titlu, autor, preţ, subiect, editură şi adresa editurii. La un moment dat, o editură îşi schimbă adresa. Bibliotecara va trebui să modifice adresa editurii respective în înregistrările corespunzătoare tuturor cărţilor din bibliotecă apărute la respectiva editură. Dacă această modificare nu se face cu succes, unele dintre înregistrări rămânând cu vechea adresă, apare din nou o inconsistenţă a datelor. - anomalii de inserare în exemplul anterior, nu vom putea memora adresa unei edituri, lucru inacceptabil dacă dorim să avem informaţii şi despre edituri a căror cărţi nu le avem în bibliotecă, eventual de la care dorim să facem comenzi. - anomalii de ştergere să presupunem că într-o tabelă memorăm următoarele informaţii: codul studentului, codul cursului şi codul profesorului. La un moment dat, niciun student nu mai doreşte să participe la un anume curs. Ştergând toate înregistrările corespunzătoare cursului, nu vom mai putea şti niciodată cine preda acel curs. Conceptul de normalizare a bazelor de date a fost pentru prima dată introdus de către Edgar Frank Codd 1. Formele normale oferă indicaţii pe baza cărora puteţi decide dacă un anumit ERD este bine proiectat, neexpus anomaliilor şi inconsistenţelor. În principiu, normalizarea implică descompunerea unei entităţi în două sau mai multe entităţi, prin compunerea cărora se pot obţine exact aceleaşi informaţii. 1

23 Capitolul 1. Proiectarea bazelor de date 23 Formele normale se aplică fiecărei entităţi în parte. O bază de date (sau un ERD) se găseşte într-o anumită formă normală doar dacă toate entităţile se găsesc în acea formă normală. Edgar Codd a definit primele trei forme normale 1NF, 2NF şi 3NF. Ulterior, s-au mai definit formele normale 4NF, 5NF şi 6NF care însă sunt rar folosite în proiectarea bazelor de date Prima formă normală (1NF) O entitate se găseşte în prima formă normală dacă şi numai dacă: - nu există atribute cu valori multiple; - nu există atribute sau grupuri de atribute care se repetă. Cu alte cuvinte, toate atributele trebuie să fie atomice, adică să conţină o singură informaţie. Dacă un atribut are valori multiple, sau un grup de atribute se repetă, atunci trebuie să creaţi o entitate suplimentară pe care să o legaţi de entitatea originală printr-o relaţie de 1:m. În noua entitate vor fi introduse atributele sau grupurile de atribute care se repetă. Să considerăm entitatea din Fig. 1.17, referitoare la notele elevilor unei clase. Câteva observaţii referitoare la această entitate: câte discipline studiazǎ un elev? Câte perechi (disciplina, nota) va trebui să aibă entitatea ELEV? Să spunem că ştim exact numărul maxim de discipline pe care le poate studia un elev. Ce se întâmplă dacă în anul şcolar viitor acest număr de discipline va fi mai mare? În plus, la o materie un elev poate avea mai multe note. Câte note? Cum memorăm aceste note? Le punem în câmpul corespunzător disciplinei cu virgulă între ele? Cum rezolvăm această problemă? Vom crea o nouă entitate în care vom introduce disciplina şi nota la disciplina respectivă (vezi Fig. 1.18). În acest fel, fiecărui elev îi pot corespunde oricâte note, iar la o disciplină poate avea oricâte note, singura restricţie conform acestui model fiind că un elev nu va putea primi în aceeaşi zi, la aceeaşi materie, mai multe note. Să considerăm un alt exemplu. Pentru managementul unui proiect este important să ştim pentru fiecare membru al echipei care sunt abilităţile de care dispune, pentru a cunoaşte modul în care să atribuim sarcinile în cadrul grupului. Într-o primă etapă, am proiectat o entitate ANGAJAT, care are un atribut abilităţi, ca în Fig Însă se ştie că fiecare angajat are mai multe abilităţi pe care dorim să le memorăm. Aşadar, atributul abilităţi nu respectă prima formă normală. În consecinţă, vom crea o nouă entitate ABILITATE în care vom memora toate abilităţile fiecărui angajat (vezi Fig. 1.20).

24 24 Manual de Informatică pentru clasa a XII-a Figura 1.17 Figura 1.18 Figura 1.19 Figura A doua formă normală (2NF) O entitate se găseşte în a doua formă normală dacă şi numai dacă se găseşte în prima formă normală şi în plus, orice atribut care nu face parte din UID (Unique IDentifier) va depinde de întregul UID, nu doar de o parte a acestuia. De exemplu, dacă memorăm angajaţii unui departament într-o entitate ca mai jos: Figura Exemplu de entitate Se observă că data_nasterii şi adresa sunt două atribute care depind doar de id-ul angajatului, nu de întregul UID care este combinaţia dintre atributele id_dep şi id_angajat. Această situaţie se rezolvă prin crearea unei noi entităţi ANGAJAT, pe care o legăm de entitatea DEPARTAMENT printr-o relaţie 1:m.

25 Capitolul 1. Proiectarea bazelor de date 25 Figura Relaţia între cele două entităţi O situaţie mai specială este în cazul relaţiilor barate, când trebuie ţinut seama că UID-ul unei entităţi este compus din atribute din entitatea respectivă, plus un atribut sau mai multe provenite din relaţia barată. Să considerăm următorul exemplu: Figura Exemplu de relaţie barată Se observă că UID-ul entităţii APARTAMENT este compus din combinaţia a trei atribute: numărul apartamentului, numărul blocului şi strada. Deci, toate atributele din entitatea APARTAMENT care nu fac parte din UID, trebuie să depindă de întregul UID. Dar se ştie că atributul cod_postal depinde doar de strada şi de numărul blocului, nu şi de numărul apartamentului. Acest lucru ne spune că atributul nu este memorat la locul potrivit. Deoarece depinde doar de combinaţia (strada, nr_bloc), înseamnă că de fapt depinde de UID-ul entităţii bloc. Aşadar, vom muta atributul cod_postal în entitatea BLOC. Figura Rezultatul modificării efectuate Observaţie! Dacă o entitate se găseşte în prima formă normală şi UID-ul său este format dintr-un singur atribut, atunci ea se găseşte automat în a doua formă normală.

26 26 Manual de Informatică pentru clasa a XII-a A treia formă normală (3NF) O entitate se găseşte în a treia formă normală dacă şi numai dacă se găseşte în a doua formă normală şi în plus niciun atribut care nu este parte a UID-ului nu depinde de un alt atribut non-uid. Cu alte cuvinte, nu se acceptă dependenţe tranzitive, adică un atribut să depindă de UID în mod indirect. Luăm ca exemplu entitatea CARTE din Fig Atributul biografie_autor nu depinde de ISBN ci de atributul autor. Nerezolvarea acestei situaţii duce la memorarea de date redundante, deoarece biografia unui autor va fi memorată pentru fiecare carte scrisă de autorul respectiv. Rezolvarea acestei situaţii constǎ în crearea unei noi entităţi, să-i zicem AUTOR, pe care o legăm de entitatea CARTE printr-o relaţie 1:m (vezi Fig. 1.26). Figura Entitate Iniţială Figura Introducerea unei noi entităţi Atenţie! Acest model este corect doar dacă se acceptă că o carte are un singur autor. Lăsăm ca temă rezolvarea situaţiei în care o carte poate avea mai mulţi autori. În această situaţie, apare o relaţie many-to-many pe care trebuie să o rezolvaţi. 1. Care dintre următoarele enunţuri NU este un exemplu de redundanţă? a) O relaţie între două entităţi care poate fi dedusă din altă relaţie. b) O valoare dintr-o bază de date care poate fi obţinută direct pe baza altei valori. c) Două atribute din baza de date care au aceeaşi valoare. d) O valoare din baza de date care poate fi obţinută efectuând diferite calcule asupra altor valori. e) Niciuna dintre variantele anterioare.

27 Capitolul 1. Proiectarea bazelor de date Care dintre următoarele cerinţe NU sunt necesare pentru ca o entitate să se găsească în a treia formă normală? a) Trebuie să se găsească în a doua formă normală. b) Fiecare atribut care nu face parte din UID trebuie să depindă de întregul UID. c) Nu trebuie să existe dependenţe tranzitive. d) Niciuna dintre variantele anterioare. 3. Care este cea mai avansată formă normală în care se găseşte entitatea alăturată? a) 1NF; b) 2NF; c) 3NF; d) ERD-ul nu este normalizat. Figura Entitatea propusă 4. În ce formă normală se găseşte fiecare dintre următoarele entităţi? a) b) c) 5. Un magazin vinde o gamă variată de pantofi de diferite mărimi şi modele. Un model este identificat printr-un cod. Fiecare model are o descriere şi aceeaşi descriere se poate aplica mai multor modele. Atributul vanzare_saptamanala va memora numărul de pantofi de un anumit model şi o anumită mărime vânduţi săptămâna anterioară (de exemplu, 25 de perechi, model 17, mărimea 39). Atributul valoare_lunara_model reprezintă valoarea totală a pantofilor vânduţi pentru fiecare model în parte, indiferent de model. Desenaţi un ERD în forma normală 3NF, conţinând toate aceste informaţii. 6. Se dă următoarea schemă a unei baze de date existente într-o videotecă. Presupunând că videoteca dispune de un singur exemplar din fiecare film video, stabiliţi în ce formă normală se găseşte acest ERD. Dacă el nu se găseşte în forma normală 3NF, faceţi modificările necesare pentru aducerea sa la forma normală 3NF. Figura Schema propusă

28 28 Manual de Informatică pentru clasa a XII-a 7. Plecând de la următoarea entitate, desenaţi un ERD în forma normală 3NF: Figura Entitatea propusă pentru problema 7 8. Desenaţi ERD-ul pentru următorul scenariu şi aduceţi-l în forma normală 3NF: într-o clădire se găsesc mai multe birouri. Fiecare birou este identificat unic printr-un număr. În fiecare birou se găseşte un singur telefon. Un telefon poate fi de două tipuri: telefon interior (cu care nu se pot face apeluri în afara clădirii) şi telefon exterior, cu care se pot face apeluri atât în interiorul clădirii cât şi cu exteriorul. Fiecare telefon are un număr unic. Într-un birou pot lucra mai mulţi angajaţi, pentru fiecare cunoscându-se numele, prenumele, adresa, -ul, data naşterii şi data angajării. Se ştie că un angajat poate lucra într-un singur birou. 9. Modificaţi ERD-ul de la problema anterioară în ipoteza că într-un birou pot exista mai multe telefoane, folosite în comun de către toţi angajaţii care lucrează în acel birou. 10. Aduceţi modificările necesare entităţii alăturate astfel încât să obţineţi un ERD în forma normală 3NF. Entitatea reţine informaţii despre angajaţii unei agenţii de plasare a forţei de muncă, care oferă personal cu normă întreagă sau cu program redus, pentru diferite hoteluri din întreaga ţară. Se memorează numărul de ore lucrate de fiecare angajat în diferite hoteluri. Se ştie că numărul de contract este întotdeauna dependent de codul hotelului dar nu şi invers. Figura Entitatea propusă pentru problema 10

29 Capitolul 1. Proiectarea bazelor de date Implementarea modelului conceptual Modele de baze de date Bazele de date au fost concepute pentru stocarea volumelor mari de informaţii relativ omogene între care se pot stabili anumite relaţii. O bază de date este deci o colecţie structurată de date aflate în interdependenţă, date care pot fi consultate pentru a răspunde diferitelor interogări. Înregistrările returnate ca răspuns la o interogare devin informaţii care pot fi utilizate în luarea unor decizii ulterioare. Sistemul complex de programe care permite descrierea, organizarea, memorarea, regăsirea, administrarea şi securizarea informaţiilor dintr-o bază de date se numeşte sistemul de gestiune a bazelor de date (SGBD). Memorarea datelor conţinute de bazele de date se face pe suporturile de memorie internă sau externă folosite de calculatoare. SGBD este un software special asociat bazelor de date care asigură interfaţa între o bază de date şi utilizatorii ei, rezolvând toate cererile de acces la datele memorate. Pentru orice bază de date poate fi compusă o descriere a datelor şi obiectelor memorate, precum şi relaţiile existente între aceste obiecte. O astfel de descriere se numeşte schema bazei de date. Există mai multe modele de baze de date, acestea diferenţiindu-se în funcţie de modul de organizare a schemei bazei de date. Un model de bază de date nu este doar un mod de structurare a datelor, el defineşte de asemenea un set de operaţii care pot fi realizate cu datele respective. Cele mai cunoscute modele de baze de date sunt următoarele: Modelul tabelar toate datele sunt memorate sub forma unui singur tabel, un tablou bidimensional de date. Modelul ierarhic datele sunt organizate sub forma unor structuri arborescente, există deci o rădăcină cu mai mulţi dependenţi, care la rândul lor pot avea alţi dependenţi. IMS (Information Management System) produs de IBM este un exemplu de SGBD bazat pe acest tip de model. Modelul reţea este un model performant, dar complicat. O bază de date de tip reţea reprezintă o colecţie de noduri şi legături, fiecare nod putând fi legat de oricare altul. Legăturile trebuie stabilite având tot timpul în minte interogările posibile şi acţiunile viitoare probabile. Modelul relaţional reprezintă cel mai utilizat model de stocare a datelor, în care datele sunt organizate sub formă de tabele între care există diverse legături.

30 30 Manual de Informatică pentru clasa a XII-a Modelul obiectual, destinat să suporte modele de obiecte complexe (organizare de tip heap cu referinţe între componente) este oarecum asemănător reţelei, iar prin faptul că pentru accesare directă, stochează o hartă a ierarhiilor şi relaţiilor claselor de obiecte, are ascendent şi în modelul ierarhic. Modelul obiectual se pretează pentru înmagazinarea informaţiilor complexe: atribute descriptive asociate datelor multimedia, documentelor, desenelor, arhivelor, etc. Modelele hibride sunt mixturi ale modelelor prezentate anterior, din care cel mai semnificativ este modelul relaţional-obiectual, obţinut prin extensii ale modelului de organizare tabelar şi izvorât din tendinţa spre universalitate a bazei de date (entităţi complexe şi de naturi diferite, evoluând în condiţii eterogene) Baze de date relaţionale Bazele de date relaţionale au fost dezvoltate având în vedere în primul rând utilizatorii finali. Acest model are la bază teoria matematică a relaţiilor, ceea ce a făcut posibilă tratarea algoritmică a proiectării bazelor de date şi problema normalizării datelor. Modelul relaţional este un model simplu, bazat pe algebra relaţională, care a făcut posibilă dezvoltarea limbajelor relaţionale sub forma unui software specializat ce asistă procesul de implementare a bazelor de date. Astfel de limbaje sunt SQL-ul (Structured Query Language) şi QBE (Query By Example). În momentul de faţă, există multe sisteme performante de gestiune a bazelor de date relaţionale precum Oracle, DB2, MySQL, Informix, etc. În cazul bazelor de date relaţionale mari şi foarte mari, s-au impus SGBD-uri precum Oracle, DB2 şi Informix. Acestea au la bază tehnologia client-server. Transformarea modelului conceptual, a ERD-ului, în modelul fizic, adică în baza de date propriu-zisă, se numeşte mapare. Acest proces implică transformarea fiecărui element al ERD-ului. Prima etapă a acestui proces constă în crearea tabelelor bazei de date. Astfel: fiecărei entităţi îi va corespunde câte un tabel. Spre deosebire de entitate, un tabel va avea numele un substantiv la plural. De exemplu, entitatea ANGAJAT se va transforma în tabela ANGAJAŢI, entitatea ELEV, în tabela ELEVI, etc. Fiecare atribut al unei entităţi va deveni o coloană a tabelei. Fiecare coloană va memora date de acelaşi tip. Fiecare instanţă a unei entităţi se va transforma într-un rând (sau înregistrare) al tabelului corespunzător. Unicul identificator al entităţii devine cheia primară a tabelei. Coloana sau combinaţia de coloane care identifică în mod unic toate liniile unui tabel se numeşte cheie primară.

31 Capitolul 1. Proiectarea bazelor de date 31 Deci, orice tabelă are linii şi coloane şi conţine datele organizate conform anumitor structuri. În limbajul bazelor de date, coloanele se numesc câmpuri. Fiecare coloană reprezintă un câmp cu o denumire unică, de un anumit tip (şir de caractere, numeric, dată calendaristică, etc.), având o dimensiune prestabilită. Rândurile tabelei se numesc înregistrări. Vom vedea pe parcursul următorului paragraf cum mapăm relaţiile dintre entităţi. numele entităţii la plural numele tabelei atributul coloana Figura Maparea entităţilor instanţa linia Informaţiile despre o tabelă a bazei de date vor fi prezentate folosind diagramele de tabelă care sunt nişte tabele de forma celui din Tabelul 1.3, în care vom nota numele coloanelor pe care le va avea tabela bazei de date, notăm dacă o coloană face parte din cheia primară, caz în care vom scrie un pk (primary key) în coloana a treia, sau dacă face parte din cheia străină, caz în care vom scrie în coloana a doua un fk (foreign key), iar în ultima coloană vom nota dacă atributul este opţional sau obligatoriu. Pentru aceasta vom folosi aceleaşi simboluri ca şi în cazul ERD-ului. Asupra cheilor străine vom reveni în paragraful următor. În tabelul 1.3 vedeţi diagrama tabelei CĂRŢI corespunzǎtoare entitǎţii CARTE: Numele coloanei Tip cheie Opţionalitatea titlu Pk * autor Pk * data_apariţiei * format * nr_pagini * Tabelul 1.3. Exemplu de diagramă de tabel Se observă că deocamdată nu avem nicio cheie străină, deoarece cheia străină provine din relaţiile în care entitatea este implicată. Cum deocamdată această entitate nu are nici o relaţie cu nicio altă entitate, nu vom avea nicio cheie străină.

32 32 Manual de Informatică pentru clasa a XII-a Completaţi diagramele de tabelă pentru entităţile de mai jos: Figura Entităţi propuse ca exerciţiu Maparea relaţiilor Maparea relaţiilor one-to-many Să începem cu un exemplu. Vom considera ERD-ul din Fig. 1.33: Figura Exemplu de ERD Să ne reamintim cum se citeşte relaţia dintre cele două entităţi: Fiecare JUCĂTOR poate juca într-o ECHIPĂ şi numai una. La fiecare ECHIPĂ trebuie sǎ joace unul sau mai mulţi JUCĂTORI. Observăm că nu putem memora toţi jucătorii care joacă la o echipă în cadrul tabelei ECHIPA, deoarece ar trebui să introducem o coloană cu valori multiple. Invers însă, putem cu uşurinţă să memorăm, pentru fiecare jucător, echipa la care joacă, deoarece acesta nu poate juca decât la o singură echipă.

33 Capitolul 1. Proiectarea bazelor de date 33 Oare cum putem memora echipa la care joacă un jucător? Răspunsul este destul de simplu. Vom memora pentru fiecare jucător codul echipei la care joacă. Adică diagrama de tabel corespunzătoare entităţii JUCĂTOR va fi următoarea: Numele coloanei Tip cheie Opţionalitatea Nr_legitimatie Pk * Nume * Prenume * Data_nasterii * Adresa * Telefon o o cod_echipa Fk o Tabelul 1.4. Diagrama de tabel corespunzătoare entităţii JUCĂTOR De pe tabela anterioară puteţi deduce încă un element important al mapării relaţiilor: dacă relaţia pe partea many este opţională atunci şi coloanele cheii străine vor fi opţionale. Ce înseamnă acest lucru? Cum un jucător poate la un moment dat să nu joace la nici o echipă, câmpul cod_echipă va rămâne necompletat în dreptul lui (va avea valoarea NULL). Dacă însă relaţia este obligatorie pe partea many, atunci coloanele ce fac parte din cheia străină vor fi obligatorii. În general, la maparea unei relaţii de tip one-to-many vom introduce, în tabela corespunzătoare entităţii de pe partea many a relaţiei, cheia primară a entităţii de pe partea one a relaţiei. Câmpurile astfel introduse se vor numi chei străine (în engleză, foreign key). Aşadar: - cheia străină a unei tabele este cheia primară din tabela referinţă; - cheia străină este întotdeauna introdusă în tabela corespunzătoare entităţii din partea many a relaţiei Maparea relaţiilor one-to-one Dându-se două entităţi A şi B legate între ele printr-o relaţie one-to-one, este evident că putem include cheia primară a lui A în cadrul tabelei B, dar putem proceda la fel de bine şi invers, incluzând cheia primară a tabelei B în cadrul tabelei A, deoarece fiecărei instanţe a entităţii A îi corespunde cel mult o instanţă a entităţii B, dar şi invers, oricărei instanţe a entităţii B îi corespunde cel mult o instanţă a entităţii A. Pentru relaţia din Fig. 1.34, de exemplu, putem memora - pentru fiecare persoană, seria de paşaport, dar şi invers - pentru fiecare paşaport, putem memora cnp-ul deţinătorului.

34 34 Manual de Informatică pentru clasa a XII-a Decizia depinde de specificul afacerii modelate. Dacă, de exemplu, ne interesează în primul rând persoanele şi abia apoi datele de pe paşapoarte, atunci vom adopta probabil prima variantă, a memorării seriei de paşaport în cadrul tabelei PERSOANE, iar dacă însă baza de date este destinată evidenţei paşapoartelor, atunci probabil vom adopta varianta a doua. Figura Exemplu de ERD Uneori este convenabil să memorăm cheia străină în ambele părţi ale relaţiei, în exemplul nostru, pentru fiecare paşaport să memorăm cnp-ul persoanei care îl deţine, dar şi pentru fiecare persoană să memorăm seria de paşaport Maparea relaţiilor barate Relaţiile barate se transformǎ în urma mapǎrii în cheie străină în tabela aflată în partea many a relaţiei, la fel ca la maparea oricărei relaţii one-to-many. Bara de pe relaţie exprimă faptul că acele coloane ce fac parte din cheia străină vor deveni parte a cheii primare a tabelei din partea many a relaţiei barate. Pentru exemplul din Fig. 1.35, cheia primară a tabelei ATRIBUTE va fi formată din coloanele denumire_atribut şi denumire_entitate, aceasta din urmă fiind de fapt cheie străină în tabela ATRIBUTE: Figura Maparea relaţiilor barate Vom avea diagramele de tabel: Numele coloanei Tip cheie Opţionalitatea denumire Pk * Tabelul 1.5. Diagrama de tabel ENTITĂŢI

35 Capitolul 1. Proiectarea bazelor de date 35 Numele coloanei Tip cheie Opţionalitatea denumire_atribut Pk * denumire_entitate Pk, Fk * opţionalitate * Tabelul 1.6. Diagrama de tabel ATRIBUTE Să considerăm acum un exemplu în care există mai multe relaţii barate, în cascadă: Vom avea tabelele de mai jos: Figura Relaţii barate în cascadă Numele coloanei Tip cheie Opţionalitatea ida Pk * C1 * Tabelul 1.7. Diagrama de tabel pentru entitatea A Numele coloanei Tip cheie Opţionalitatea idb Pk * C2 * ida Pk, Fk * Tabelul 1.8. Diagrama de tabel pentru entitatea B Numele coloanei Tip cheie Opţionalitatea idc Pk * C3 * ida Pk, Fk * idb Pk, Fk * Tabelul 1.9. Diagrama de tabel pentru entitatea C Numele coloanei Tip cheie Opţionalitatea idd Pk * C4 * ida Fk * Tabelul Diagrama de tabel pentru entitatea D

36 36 Manual de Informatică pentru clasa a XII-a 1. Reluaţi exerciţiile propuse pe parcursul paragrafelor anterioare şi realizaţi maparea ERD-urilor obţinute. 2. Realizaţi maparea următoarei hărţi a relaţiilor. Figura Harta relaţiilor propusă ca aplicaţie Operaţii specifice prelucrării bazelor de date Orice sistem de gestiune a bazelor de date (SGBD) trebuie să asigure următoarele funcţii: definirea structurii bazei de date; încărcarea datelor în baza de date (adăugarea de noi înregistrări la baza de date); accesul la date pentru: o o o interogare (afişarea datelor, sortarea lor, calcule statistice, etc.); ştergere; modificare;

37 Capitolul 1. Proiectarea bazelor de date 37 întreţinerea bazei de date: o o o refacerea bazei de date prin existenţa unor copii de siguranţă; repararea în caz de incident; colectarea şi refolosirea spaţiilor goale; posibilitatea de reorganizare a bazei de date prin: o o restructurarea datelor; modificarea accesului la date; securitatea datelor. O parte din aceste operaţii pot fi realizate cu ajutorul limbajului SQL, altele cu ajutorul unor programe specializate, care sunt puse la dispoziţia administratorului bazei de date de către sistemul de gestiune al bazelor de date Reguli de integritate Detalierea caracteristicilor pe care trebuie să le prezinte un SGBD pentru a fi considerat relaţional a fost realizată de către E. F. Codd în 1985 sub forma a 13 reguli. Una dintre aceste reguli precizează că restricţiile de integritate trebuie să poată fi definite în limbajul utilizat de SGBD pentru definirea datelor. Regulile de integritate garantează că datele introduse în baza de date sunt corecte şi valide. Aceasta înseamnă că dacă există orice regulă sau restricţie asupra unei entităţi, atunci datele introduse în baza de date respectă aceste restricţii. Tipurile de reguli de integritate sunt următoarele: Integritatea entităţilor indică faptul că nici o coloană ce face parte din cheia primară nu poate avea valoarea NULL. În plus, pentru fiecare înregistrare, cheia primară trebuie să fie unică. Integritatea de domeniu acest tip de reguli permite ca într-o anumită coloană să se introducă doar valori dintr-un anumit domeniu. De exemplu, putem impune ca salariul unui angajat să fie cuprins între 4500 şi 5000 RON. Integritatea referenţială este o protecţie care asigură ca fiecare valoare a cheii străine să corespundă unei valori a cheii primare din tabela referită. De exemplu, referindu-ne la tabelele JUCĂTORI şi ECHIPE, corespunzătoare ERD-ului din Fig. 1.33, cod este cheie primară în tabela ECHIPE, iar în tabela JUCĂTORI, cod devine cheie străină. Astfel, valoarea câmpului cod din cadrul tabelei JUCĂTORI corespunzătoare unui anumit jucător trebuie să se regăsească printre valorile câmpului cod din tabela ECHIPE, altfel ar însemna că jucătorul respectiv joacă la o echipă inexistentă (vezi Fig. 1.38).

38 38 Manual de Informatică pentru clasa a XII-a Figura Exemplu de încălcare a integrităţii referenţiale Situaţii de încălcare a integrităţii referenţiale pot apărea: la adăugarea unei noi înregistrări în baza de date, se poate încerca introducerea unor valori invalide pentru câmpurile cheii străine; la actualizarea bazei de date; la ştergerea unei înregistrări. De exemplu, se şterge înregistrarea corespunzătoare unei anumite echipe (echipa se desfiinţează). Înregistrările jucătorilor care au jucat la acea echipă vor încălca integritatea referenţială, deoarece se vor referi la o echipă care nu mai există. Soluţiile posibile sunt ca la ştergerea unei echipe, toţi jucătorii care au activat la acea echipă să fie şi ei şterşi din baza de date (ştergere în cascadă), sau valoarea câmpului cod_echipă pentru acei jucători să fie setată la NULL, ceea ce înseamnă că acei jucători nu activează la nicio echipă Programe de validare şi de acţiune În realizarea modelului conceptual al unei baze de date se ţine cont de modul în care funcţionează afacerea modelată, datele care trebuie să fie memorate, relaţiile dintre acestea, etc. Modul de utilizare a diferitelor date, modul în care acestea sunt relaţionate pot diferi de la o afacere la alta. Regulile afacerii unei organizaţii se referă în esenţă la procesele şi fluxurile tuturor datelor şi activităţilor zilnice din cadrul organizaţiei. Cum funcţionează organizaţia? Care sunt activităţile sale?

39 Capitolul 1. Proiectarea bazelor de date 39 Regulile afacerii acoperă următoarele aspecte ale unei organizaţii: Orice tip de politici organizaţionale de orice tip şi de la orice nivel al organizaţiei. Orice tip de formule de calcul (ca, de exemplu, modul de calcul al ratelor pentru diverse împrumuturi, modul de calcul al salariilor, etc.). Orice tip de reguli impuse de lege sau reguli interne ale organizaţiei. Regulile simple ale afacerii pot fi implementate în modelul bazei de date prin intermediul relaţiilor dintre entităţi. Acest tip de reguli se numesc reguli structurale. Alte reguli ale afacerii pot fi implementate folosind regulile de integritate despre care am discutat în paragraful anterior. Există totuşi reguli pentru implementarea cărora va trebui să scriem programe speciale folosind limbaje specializate specifice SGBD-ului utilizat. Acest tip de reguli se numesc reguli procedurale. 1. Când mapaţi un ERD, care dintre următoarele afirmaţii NU este adevărată? a) Fiecare entitate este mapată într-o tabelă. b) Fiecare atribut este mapat într-o coloană a tabelei corespunzătoare. c) Fiecare entitate în parte este mapată într-o linie din tabelul corespunzător. d) Fiecare relaţie one-to-many se transformă într-o cheie străină. 2. Într-o tabelă, o instanţă a unei entităţi este mapată ca: a) o relaţie many-to-many; b) o linie din tabel; c) o coloană din tabel; d) un atribut; e) un index. 3. Două entităţi A şi B se găsesc într-o relaţie one-to-one care este opţională la ambele capete. Care dintre următoarele variante este o soluţie corectă de mapare? a) Combinarea celor două entităţi A şi B într-o singură relaţie. b) Crearea a două tabele separate şi includerea unei chei străine atât în tabela A cât şi în tabela B. c) Combinarea celor două entităţi A şi B într-o singură tabelă. d) Utilizarea unei chei primare care să fie o combinaţie a cheilor primare din A şi B. 4. Referitor la ERD-ul din Fig. 1.39, care dintre afirmaţiile de mai jos corespund unei variante corecte de mapare? a) Se preia cheia primară din tabela PERSOANE şi se adaugă ca şi cheie străină la tabela MASINI.

40 40 Manual de Informatică pentru clasa a XII-a Figura ERD propus pentru problema 4 b) Se preia cheia primară din tabela MASINI şi se adaugă ca şi cheie străină la tabela PERSOANE. c) Se creează o singură tabelă cu informaţiile din ambele entităţi. d) Se preiau cheile primare din ambele tabele şi se introduc într-o nouă tabelă numită PROPRIETARI. e) Oricare dintre variantele de mai sus este corectă. 5. O bază de date conţine următoarele tabele: Tabela DEPARTAMENTE Tabela ANGAJATI Tabela ANGAJARI DepNo Departament IdAngajat NumeAngajat IdAngajat DepNo 1 IT 1 Ionescu Electric 2 Georgescu Geografie 3 Vasilescu Istorie 4 Marinescu Business 5 Andreescu Desenaţi ERD-ul din care s-au obţinut prin mapare aceste tabele. (vezi baremele de notare şi de corectare de la pag. 380)

41 Capitolul 1. Proiectarea bazelor de date Managementul de proiect Ce este un proiect? Un proiect este o secvenţă de acţiuni intercorelate, care se derulează într-o perioadă de timp clar definită şi delimitată, orientate către îndeplinirea unor obiective cu caracter unic şi precis. Putem defini managementul de proiect ca fiind efortul planificării, organizării şi mobilizării resurselor pentru un scop dat. Managementul de proiect este de fapt un instrument, un set de metode şi tehnici care ne ajută să atingem cu eficacitate scopurile şi obiectivele propuse Etape în realizarea unui proiect Orice proiect trece printr-o serie întreagă de etape. Ceea ce este important de reţinut este faptul că orice proiect este un proces iterativ, în sensul că orice etapă poate fi repetată de mai multe ori, în funcţie de necesităţile de redefinire a anumitor cerinţe. Etapele principale pe care le parcurgem pentru realizarea unui proiect sunt următoarele: Definirea proiectului o o Validarea proiectului în această etapă vor fi analizate toate documentele prezente în propunerea de proiect. Această analiză va duce fie la confirmarea şi acceptarea proiectului, fie va duce la respingerea, sau eventual regândirea acestuia, în cazul în care propunerea de proiect nu a fost bine realizată, şi resursele au fost subestimate. Definirea proiectului constă în enunţarea problemei, stabilirea scopului proiectului, stabilirea unei liste a posibilelor soluţii etc. Orice proiect propus poate avea elemente pe care cel care l-a propus nu a considerat necesar să le detalieze, însă echipa de proiect poate avea nevoie de informaţii suplimentare pentru a înţelege corect enunţul proiectului. Organizarea proiectului o o Stabilirea obiectivelor Stabilirea grupului ţintă - când încercaţi să stabiliţi care este grupul ţintă al unui proiect trebuie să răspundeţi la următoarele întrebări: Cine trebuie să ştie despre proiect? Cine va folosi acest proiect? Asupra cui vor avea impact rezultatele proiectului? Cine finanţează acest proiect? Cine aprobă acest proiect? Cine livrează proiectul? Cine va trebui să fie instruit?

42 42 Manual de Informatică pentru clasa a XII-a o o o Stabilirea cerinţelor proiectului este un proces iterativ care poate implica negocierea. Fiind conducătorul proiectului, ştiţi ce este posibil şi ce nu în ceea ce priveşte scopul proiectului, timpul alocat, costurile, cerinţele de calitate etc. Un proiect care nu îndeplineşte cerinţele utilizatorului este din start un eşec. Stabilirea infrastructurii proiectului infrastructura se referă la elemente precum instrumente de comunicare în cadrul echipei (telefoane mobile, PDA, laptop, etc.), spaţiu de lucru pentru membrii echipei (birou), echipamente de birou, laboratoare, etc. Stabilirea sistemului de calitate a proiectului o Formarea echipei de proiect Planificarea proiectului planul proiectului prezintă desfăşurarea normală, ideală a unui proiect. Acesta oferă reperele necesare evaluării situaţiei proiectului. Fără existenţa unui plan dinainte stabilit, exercitarea controlului este practic imposibilă. Elaborarea proiectului în această etapă se stabilesc detaliile tehnice şi de design, se revizuiesc schemele tehnice, se revizuiesc criteriile de cost şi performanţă. Această etapă vizează conturarea unui model al aplicaţiei. Se proiectează bazele de date, se realizează interfeţele aplicaţiei (rapoarte, ecrane, meniuri etc), se proiectează prelucrările automate, etc. Dezvoltarea proiectului Implementarea proiectului constă în instalarea produsului şi testarea sa, instruirea viitorilor utilizatori. Se testează produsul în condiţii reale, şi se înlătură eventualele erori depistate în funcţionare. Tot în această fază personalul implicat în proiect este redus. Se încep activităţile de publicitate. Finalizarea proiectului se elaborează rapoartele finale, se eliberează personalul angajat în derularea proiectului Principiile lucrului în echipă Colaborarea înseamnă mai ales implicarea oamenilor în crearea propriilor soluţii la problemele cu care se confruntă. În cadrul unui proces colaborativ, oamenii au ocazia să afle punctul de vedere şi perspectiva celorlalţi şi să gândească împreună soluţii la problemele comune. Colaborarea este o artă! Sunteţi uneori puşi în situaţia de a vorbi şi colabora cu persoane pe care nu le cunoaşteţi, cu care nu sunteţi de acord sau pe care nu le agreaţi. Mărimea echipei de proiect este un factor important care poate influenţa modul de conducere al acesteia. Într-o echipă prea mare pot apărea probleme de comunicare, dificultăţi în luarea deciziilor. În general, se acceptă că o echipă pentru a putea fi eficientă nu trebuie să depăşească un număr de 10 persoane.

43 Capitolul 1. Proiectarea bazelor de date 43 În cazul proiectelor cu număr mare de persoane implicate, participanţii la proiect trebuie organizaţi în mai multe echipe satelit intercorelate, coordonate de o echipă principală al cărei rol principal este să asigure o comunicare facilă şi eficientă între toate echipele satelit. Fiecare membru al unei echipe de proiect trebuie să cunoască ceea ce se aşteaptă de la el. Trebuie stabilite de la început rezultatele aşteptate de la fiecare membru al echipei în parte, acţiunile ce trebuie executate pentru obţinerea rezultatului, relaţiile de subordonare în cadrul echipei, metodele de măsurare a performanţei fiecărui membru al echipei. Liderul echipei are în primul rând rolul de a stabili, menţine şi proteja un proces colaborativ care permite tuturor să participe neîngrădit la munca grupului Pregătirea şi susţinerea unei prezentări În momentul finalizării unui proiect va trebui să prezentaţi rezultatul muncii voastre în faţa clientului. Susţinerea unei prezentări în public este pentru oricine o sursă de stres. Mulţi oameni ar prefera să evite complet această problemă, dar de multe ori este imposibil de evitat. Indiferent că lucrăm singuri sau în echipă, vom putea fi puşi în situaţia de a face o prezentare publică. Adevărul este că susţinerea unei prezentări publice nu trebuie să fie un motiv de stres. Atât timp cât aveţi în minte câteva principii de bază, vorbitul în public va deveni o experienţă plăcută pentru voi. Iată câteva principii de care trebuie să ţineţi seama pentru a depăşi dificultăţile legate de vorbitul în public: Vorbitul în public NU este un motiv real de stres. Mulţi oameni erau la început îngroziţi de ideea de a vorbi în public. Le tremurau genunchii, vocea, gândurile o luau razna. Totuşi, ei au învăţat să elimine definitiv teama de a vorbi în public. Nu îţi propune să fi genial sau perfect, chiar dacă aşa ţi se pare că ar trebui. Ţi se poate întâmpla să greşeşti, ţi se poate întâmpla să uiţi porţiuni întregi din ceea ce vroiai să spui, poţi să nu glumeşti deloc şi totuşi prezentarea ta să aibă succes. Totul depinde de cum defineşti tu şi auditorul tău succesul. Auditorul tău nu aşteaptă de la tine să fi perfect. Cu cât încerci mai tare să fi perfect cu atât mai mult vei adânci anxietatea pe care o ai şi efectul va fi contrar celui scontat. Ceea ce este important atunci când faci o prezentare în faţa unui public este să oferi ceva auditorului. Atâta timp cât auditorul rămâne cu ceva de pe urma prezentării, ei o vor considera un succes. Nu încerca să transmiţi prea multe informaţii într-o prezentare. Nu trebuie să transmiţi tone de informaţii şi detalii, oferă publicului doar ceea ce el doreşte cu adevărat. Studiile arată că oamenii îşi amintesc doar foarte puţine elemente din ceea ce vorbitorii prezintă.

44 44 Manual de Informatică pentru clasa a XII-a Nu încerca să mulţumeşti pe toată lumea, acesta este un punct de vedere nerealist. Nu încerca să imiţi alţi prezentatori, e un lucru foarte dificil. Încearcă să fi tu însuţi, e mult mai uşor. Nu încerca să controlezi comportamentul auditorului. Dacă oamenii sunt agitaţi, nu încerca să le controlezi comportamentul. Dacă cineva vorbeşte cu vecinul, citeşte ziarul sau chiar a adormit în timpul prezentării tale, ignoră-l! Nu te scuza. Auditorul nu are de unde să ştie că ai uitat să spui ceva. Vorbeşte cu încredere, fi convins de ceea ce spui. Organizează logic conţinutul prezentării. Orice prezentare va avea o introducere, conţinutul propriu-zis şi o concluzie. Utilizează materiale audio-vizuale ajutătoare, dacă acestea sunt necesare. O prezentare în PowerPoint, bine realizată, poate fi de un real folos. o o Asigură-te din timp că întregul echipament (calculator, video-proiector, etc) funcţionează. Nu bombarda auditorul cu efecte sonore sau cu animaţii exagerate şi utilizează în mod echilibrat culorile. o Include în prezentarea electronică doar cele mai importante idei. o Nu încărca slide-urile cu prea multe texte. În general, se admit 7-10 cuvinte pe linie şi maximum 10 linii de text pe un slide. o Preferă un grafic în locul textelor, dar nu exagera cu mai mult de două grafice pe un slide. Păstrează contactul vizual cu auditorul. Încearcă în acest fel să faci fiecare persoană din public să se simtă implicată. Fă scurte pauze. Nu alerga prin prezentare, dă-ţi răgazul să respiri. Dă timp audienţei să reflecte la ceea ce ai spus. Adaugă puţin umor prezentării tale, dacă acest lucru este posibil. Păstrează treaz interesul auditorului pe parcursul întregii prezentări. Nu ţine mâinile în buzunar în timpul prezentării! Adoptă o ţinută adecvată în ziua prezentării. Atrage atenţia auditorului asupra a ceea ce spui, nu a mesajelor de pe tricou sau asupra bijuteriilor pe care le porţi! În acest moment v-aţi însuşit elementele de bază ale modelării bazelor de date. Aţi văzut diverse situaţii ce pot apărea pe parcursul creării modelului conceptual şi cum să rezolvaţi anumite situaţii problemă.

45 Capitolul 1. Proiectarea bazelor de date 45 În acest subcapitol aţi aflat cum se organizează un proiect, care sunt etapele de realizare ale lui şi cum să organizaţi munca într-o echipă. De asemenea, ştiţi cum să pregătiţi şi să faceţi o prezentare în faţa unui public. Este momentul să aplicaţi toate aceste cunoştinţe! Formaţi echipe de 2-4 elevi, alegeţi-vă o temă de proiect, fie din temele propuse în această secţiune, fie una propusă chiar de voi. Realizaţi modelul conceptual al afacerii modelate. Atenţie! Repartizaţi sarcinile în mod echitabil în cadrul echipei de proiect. Pregătiţi o prezentare a proiectului realizat, materialele vizuale (postere, pliante, prezentarea PowerPoint), care să vă ajute la susţinerea prezentării. Puteţi chiar organiza împreună cu cadrul didactic, un concurs la nivelul clasei sau al şcolii, la care să invitaţi şi alţi profesori din şcoală. Nu uitaţi să documentaţi fiecare presupunere pe care aţi făcut-o în realizarea proiectului! Tema 1: Campionatul Naţional de Fotbal. O bază de date memorează informaţii despre jucătorii şi cluburile din cele patru divizii din campionatul naţional de fotbal. Fiecare club de fotbal are un nume unic în întregul campionat. Un club de fotbal poate avea mai multe echipe în campionat. Pentru fiecare echipă se cunoaşte căpitanul său, care este unul dintre jucători. Jucătorii au asociat un identificator unic, un nume, nu neapărat unic şi sunt angajaţi la diferitele echipe. În baza de date se păstrează şi detalii privind nivelul abilităţilor (notă cuprinsă între 1 şi 10) fiecărui jucător pentru fiecare dintre poziţii de joc (portar, apărător, mijlocaş, etc). De exemplu, jucătorul Ionescu poate avea nivelul 10 pe postul de portar, 7 pentru poziţia de apărător, etc. Este important ca în baza de date să se memoreze un istoric al tuturor jucătorilor, la ce echipe au jucat, în ce perioadă, etc. Se va memora şi un istoric al golurilor marcate de fiecare jucător de-a lungul carierei. Pentru fiecare gol se va şti data, meciul în care a fost marcat, minutul, etc. Tema 2: Firmă de închirieri de maşini. Trebuie să proiectaţi baza de date a unei firme care oferă spre închiriere maşini de diferite tipuri. Trebuie să păstraţi informaţii despre maşinile firmei, firmele cu care firma are contracte de colaborare (de exemplu, garaje), maşinile închiriate, veniturile firmei şi bineînţeles date despre clienţii firmei. Maşinile sunt descrise prin date precum: producătorul, modelul, anul de fabricaţie, mărimea motorului, tipul de combustibil, numărul de pasageri, numărul de înmatriculare, preţul de cumpărare, data cumpărării, preţul de închiriere şi detalii privind asigurarea maşinii.

46 46 Manual de Informatică pentru clasa a XII-a Toate reparaţiile importante asupra maşinilor firmei sunt făcute de firme cu care colaborează. Unele firme solicită plata serviciilor de service imediat după ce reparaţia a fost făcută, altele acceptă plata în rate a serviciilor. Trebuie ţinută evidenţa clară a fiecărei maşini, a celor închiriate, a celor aflate în reparaţii, etc. Se păstrează de asemenea evidenţa tuturor veniturilor şi cheltuielilor firmei: cumpărarea de noi maşini, închirierea de maşini, cheltuieli de reparaţii, vânzarea unor maşini mai vechi din parcul auto (firma preferă să nu păstreze în parcul auto o maşină mai mult de un an), taxe de asigurare a maşinilor etc. Firma deţine un portofoliu de clienţi destul de stabil. Pentru clienţii privilegiaţi oferă reduceri la închirierea de maşini. Aceşti clienţi au de asemenea posibilitatea de a rezerva o maşină din timp. O maşină poate fi închiriată pentru o perioadă de timp de la o zi la un an. Plata pentru închirierea unei maşini se poate face cash sau cu credit card. Se acceptă orice tip de card. Datele importante despre clienţi precum numele, adresa, numărul de telefon, seria permisului de conducere, etc. vor fi şi ele memorate în baza de date. Tema 3: Firmă IT. Trebuie să proiectaţi baza de date a unei companii de dimensiune medie din domeniul IT. Firma livrează diferite produse clienţilor săi, de la simple aplicaţii create la cerere, până la instalări de echipamente hardware şi software particularizat. Firma are ca angajaţi diverşi experţi, consultanţi şi personal auxiliar. Întregul personal este angajat pe termen nelimitat, nu există angajaţi temporari sau colaboratori. Compania este împărţită în mai multe departamente, fiecare departament fiind condus de către un angajat din cadrul departamentului respectiv. Pentru un proiect care trebuie dezvoltat în cadrul firmei, se formează o echipă de persoane selectate din mai multe departamente. Managerul de proiect este pe deplin şi exclusiv responsabil de conducerea proiectului, independent de ierarhia de conducere din cadrul firmei. Tema 4: Spital. Un spital este format din mai multe secţii, precum Pediatrie, Oncologie, Dermatologie etc. În fiecare secţie sunt internaţi mai mulţi pacienţi, pe baza recomandării medicului de familie şi a confirmării făcute de către un specialist al spitalului. La internare, sunt înregistrate datele personale ale pacienţilor. O fişă separată ţine evidenţa investigaţiilor făcute pacientului pe toată perioada internării, rezultatele acestor investigaţii, tratamentul aplicat pacientului şi rezultatele obţinute în urma tratamentelor efectuate. Un pacient este repartizat unui anumit medic care coordonează toate investigaţiile şi tratamentele aplicate pacientului, însă acesta poate solicita şi altor colegi să examineze pacientul său. Medicii sunt specialişti în diverse ramuri ale medicinii, şi pot avea în supraveghere mai mulţi pacienţi, nu neapărat toţi din aceeaşi secţie. Tema 5: Editură. O editură editează cărţi ştiinţifice din diferite domenii. Cărţile sunt scrise de autori specializaţi într-un anumit domeniu. Firma are angajaţi mai mulţi editori care nu sunt neapărat specialişti în diferitele domenii, fiecare editor fiind responsabil pentru mai multe publicaţii. O carte acoperă unul din domeniile în care este specialist autorul, fiecare autor lucrează cu un editor, dar poate avea spre publicare o altă carte de care este responsabil un alt editor.

47 PARTEA A II-A CAPITOLUL Limbajul MySQL În acest capitol veţi învăţa MySQL, limbaj de programare specializat pentru gestiunea bazelor de date relaţionale pe Internet. Cu ajutorul programului EasyPHP, veţi putea lucra uşor pe calculatorul dvs. Ce este şi de ce învăţăm MySQL? Cum rulăm MySQL pe propriul calculator? Cum creăm o bază de date? Tabele noţiuni elementare Tipuri de date, operatori şi funcţii Afişarea c oloanelor care rezultă în urma unui calcul Valoarea NULL. Valori implicite Ce sunt cheile primare şi cheile unice? Autoincrementare Cum sortăm şi cum filtrăm datele? Cum actualizăm datele dintr-un tabel? Funcţii agregate Utilizarea subinterogărilor Cum putem grupa datele? Ce sunt uniunile de tabele? Cuvinte cheie: tipuri de date, operatori, funcţii, valoare implicită, cheie primară, cheie unică, autoincrementare, sortare, filtrare, actualizare, funcţii agregate, subinterogări, grupare, uniune

48 48 Manual de Informatică pentru clasa a XII-a 2.1. Ce este şi de ce învăţăm MySQL? În ultimii ani, utilizarea bazelor de date pe Internet a luat o amploare deosebită. Există o mulţime de aplicaţii, extrem de utile (care le utilizează), cum ar fi: - Aplicaţii de contorizare, aplicaţii prin care cei care au creat un site au posibilitatea să-şi contorizeze numărul de vizitatori ai site-ului respectiv sau, mai mult, contorizarea se poate extinde la nivel de pagină afişată. Pentru a evita cu un vizitator, care a deschis de mai multe ori pagina respectivă, să nu fie contorizat de mai multe ori, se va reţine adresa IP a acestuia. - Comerţ electronic, aplicaţii prin care anumite firme îşi promovează şi vând produsele de care dispun. În acest caz, bazele date vor reţine, pe de o parte, informaţii despre produse, iar pe de altă parte, comenzile clienţilor. Avantajele comerţului electronic sunt uriaşe pentru că nu implică cheltuieli pentru spaţiile de desfacere (magazine) şi, teoretic, oferta se adresează clienţilor din toată lumea. - Votul electronic, aplicaţii prin care se poate afla părerea vizitatorilor site-ului respectiv referitoare la tema supusă votului. Şi aici este important ca un vizitator să nu voteze de mai multe ori, motiv pentru care baza de date reţine adresa IP a vizitatorului. - Aplicaţii de comunicare - aplicaţii prin care diverşi vizitatori ai site-ului respectiv dezbat o anumită problemă, supusă discuţiei. În astfel de cazuri, bazele de date vor reţine informaţii despre cei care scriu (de multe ori, aceştia, mai întâi, trebuie să se înscrie în baza de date a site-ului) şi mesajele acestora. Există o mulţime de alte aplicaţii ale bazelor de date: site-urile diverselor ziare, posturi de televiziune, bazele de date create şi exploatate de motoarele de căutare, etc. Şirul acestora este practic infinit. Iată motivul pentru care ne vom iniţia în crearea şi exploatarea bazelor de date pe Internet. Ce este SQL? În practica creării şi utilizării bazelor de date relaţionale 1 s-a impus necesitatea existenţei unui limbaj standard care permite efectuarea acestor operaţii. Astfel, a apărut SQL - Structured Query Language. Limbajul este supervizat de comisia de standardizare ANSI (American National Standards Institute), motiv pentru care se mai numeşte şi ANSI SQL. SQL nu este un limbaj de firmă, el este implementat de o mulţime de SGBD-uri, de această dată consacrate, cum ar fi: Microsoft Access, Oracle, Microsoft SQL Server şi, bineînţeles, MySQL. Ce este MySQL? MySQL este un limbaj specializat pentru gestiunea bazelor de date relaţionale pe Internet. Aşa cum s-a mai spus, are la bază limbajul SQL. MySQL gestionează baze de date care se găsesc pe server, iar comenzile pot fi date cu ajutorul limbajului PHP, dar şi cu alte limbaje, de exemplu Java. 1 Revedeţi Capitolul 1. Proiectarea bazelor de date deoarece stă la baza tuturor noţiunilor prezentate aici!

49 Capitolul 2. Limbajul MySQL 49 Prin utilizarea pachetului EasyPHP putem să instalăm MySQL pe calculatorul nostru. Vedeţi Anexa 1! Exact în acest mod vom proceda pentru studiul limbajului MySQL, adică vom crea baze de date pe calculatorul nostru Cum rulăm MySQL pe propriul calculator? Mai întâi, instalaţi pachetul EasyPHP, urmând paşii prezentaţi în Anexa 1. Există două modalităţi prin care se pot da comenzi MySQL pe calculatorul nostru. A) Prin utilizarea unei ferestre MS-DOS. Pentru aceasta va trebui să identificaţi programul cmd.exe care simulează sistemul de operare amintit şi să creaţi un shortcut către acesta. Pentru comoditatea apelului, este indicat ca shortcut-ul să se găsească pe Desktop. În cazul nostru, va trebui ca fereastra CMD să fie deschisă în subfolder-ul bin, al folder-ului care conţine MySQL. Executaţi clic cu butonul drept al mouse-ului şi selectaţi Properties. În edit-ul Start in, al ferestrei care apare, introduceţi calea către subfolder-ul bin al folder-ului mysql. De exemplu, pe calculatorul pe care experimentăm utilizarea MySQL-ului, această cale este: "C:\Program Files\EasyPHP1-8\mysql\bin" Lansaţi în executare programul EasyPHP din meniu: Start, Programs, EasyPHP şi executaţi dublu-clic pe shortcut-ul către CMD. Daţi comanda: mysql -u root -p şi introduceţi parola aleasă. Să observăm că MySQL afişează prompter-ul mysql> (vedeţi în figura de mai jos fereastra CMD): De acum putem da comenzi MySQL! Figura 2.1. Prompter-ul MySQL din fereastra CMD Această modalitate de lucru prezintă avantajul că orice eveniment are loc numai ca urmare a unei comenzi date de la tastatură şi pentru început, din considerente pedagogice, este bine să procedăm aşa. Desigur, există şi numeroase dezavantaje, cum ar fi faptul că de multe ori se pierde timpul tastând, pentru că în cazul unei comenzi greşite aceasta trebuie reluată, ş.a.m.d.

50 50 Manual de Informatică pentru clasa a XII-a B) Se poate utiliza şi un ansamblu de script-uri PHP aflate în fişierul index.php din folder-ul de phpmyadmin. Daţi browser-ului pe care-l utilizaţi comanda: Va fi afişată o fereastră în care vi se va cere parola (vezi Fig. 2.2.). De acum puteţi lucra cu MySQL prin utilizarea unui mediu vizual. Figura 2.2. Fereastra de autentificare Observaţie! Din considerente pedagogice şi pentru generalitatea prezentării, în această carte vom folosi prima formă, cea în care se lucrează prin utilizarea unei ferestre MS-DOS Crearea unei baze de date În MySQL, pentru a crea o bază de date se dă comanda: CREATE DATABASE nume_baza; În urma acestei comenzi, teoretic, se creează baza de date cu numele indicat. În fapt, se creează un folder cu numele bazei de date în subfolder-ul data al folder-ului MySQL: C:\Program Files\EasyPHP1-8\mysql\data. Dacă există deja o bază de date cu acest nume, se refuză crearea uneia noi. În cazul în care, după deschiderea aplicaţiei sau în timpul sesiunii de lucru, se doreşte lucrul cu o anumită bază de date, se dă comada de mai jos: USE nume_baza; Pentru ştergerea unei baze de date se utilizează comanda: DROP DATABASE nume_baza Uneori, din anumite motive, dorim o listă a bazelor de date existente. În acest caz, se utilizează comanda de mai jos: SHOW DATABASES

51 Capitolul 2. Limbajul MySQL Tabele. Noţiuni elementare Într-un tabel coloanele sunt identificabile prin nume, iar rândurile, prin valorile pe care le memorează. Toate datele dintr-o coloană au acelaşi tip. Un tabel are un număr specificat de coloane, dar are un număr nespecificat de rânduri. Uneori, când ne referim la un rând, folosim şi termenul de înregistrare, iar atunci când ne referim la data din rând, situată într-o anumită coloană, folosim şi termenul de câmp 1. O instrucţiune prin care se poate crea un tabel este prezentată mai jos, unde ceea ce este trecut între paranteze drepte este considerat facultativ 2 : CREATE TABLE nume_tabel ( nume_coloana 1 tip_data [specificatori], nume_coloana 2 tip_data [specificatori],... nume_coloana n tip_data [specificatori] ); Specificatorii se referă la cheia primară, valori distincte, valori implicite, autoincrementare, dacă printre valorile reţinute se poate găsi sau nu valoarea NULL. Toate acestea sunt tratate separat. Exemplul 2.1. Se creează un tabel cu 3 coloane: prima conţine codul materialului şi poate reţine cel mult 5 caractere, a doua conţine denumirea materialului şi poate reţine până la 20 de caractere, iar ultima reţine cantitatea din fiecare material (în bucăţi) şi poate reţine un număr natural cu maximum 3 cifre: CREATE TABLE materiale (cod char(5), denumire char(20), cantitate_buc INT(3) ); Pentru introducerea rândurilor în tabel se utilizează comanda de mai jos, unde se introduc, pe rând, toate câmpurile unei linii, în ordinea în care au fost declarate coloanele: INSERT INTO nume_tabel VALUES (data 1, data 2...data n ); Exemplul 2.2. Se inserează în tabel două linii: INSERT IMTO materiale VALUES( 001, panouri,78); INSERT IMTO materiale VALUES( 007, placi,0); 1 Noţiunea de tabel este prezentată pe scurt. O prezentare amănunţită se găseşte în capitolul anterior, Proiectarea bazelor de date. 2 Specificatorii vor fi trataţi separat. Tabelul astfel creat nu conţine nicio înregistrare. Pentru adăugarea înregistrărilor utilizăm altă instrucţiune MySQL.

52 52 Manual de Informatică pentru clasa a XII-a În practica utilizării bazelor de date, instrucţiunea anterioară este considerată ca generatoare de erori, prin faptul că se poate greşi ordinea de introducere a datelor, iar efectul este acela că tabelul va conţine date eronate. Din acest motiv, se preferă forma de mai jos a instrucţiunii, deşi este necesar să scriem mai mult Se inserează în tabel valori pentru coloanele indicate în ordinea în care au fost declarate coloanele: INSERT INTO nume_tabel (nume_coloana 1,... nume_coloana k ) VALUES (data 1,...data k ); Pentru a afişa întreg tabelul se utilizează comanda: SELECT * FROM nume_tabel Exemplul 2.3. Pentru tabelul creat anterior se dă comanda: SELECT * FROM materiale Figura 2.3. Exemplu de tabel Există posibilitatea să afişăm numai anumite coloane ale tabelului, în ordinea pe care o dorim, dacă folosim instrucţiunea de mai jos: SELECT nume_coloana 1,... nume_coloana k FROM nume_tabel Să observăm faptul că, atunci când afişăm un tabel, în capul său se trece numele coloanelor din tabel. Dacă dorim ca în capul de tabel să figureze alt nume pentru o coloană, atunci, în instrucţiunea de mai sus, în loc de a scrie numai numele coloanei, vom scrie numele coloanei urmat de cuvântul cheie AS şi de numele care dorim să fie afişat în capul de tabel. Astfel, utilizăm alias-uri pentru numele coloanelor. Exemplul 2.4. Pentru tabelul de mai sus vom scrie: SELECT cod AS codul, denumire AS nume, cantitate_buc AS cantitate FROM materiale; Putem vizualiza numele tabelelor existente în baza de date prin utilizarea instrucţiunii următoare: SHOW TABLES [FROM nume_baza] În caz că am uitat care sunt coloanele dintr-un anumit tabel al bazei de date şi tipul acestora, putem utiliza instrucţiunea: SHOW COLUMNS FROM nume_tabel

53 Capitolul 2. Limbajul MySQL Tipuri de date în MySQL Aşa cum am văzut, coloanele au un anumit tip. Până în prezent, am utilizat câteva tipuri fără a oferi o prezentare unitară a acestora. Este momentul s-o facem acum. În linii mari, tipurile de date din MySQL se împart în: a) tipuri care reţin şiruri de caractere; b) tipuri numerice; c) tipuri care reţin data, ora. În continuare, vom prezenta detaliat pe fiecare în parte Tipuri de date care reţin şiruri de caractere Tipurile care reţin şiruri de caractere sunt prezentate mai jos: Tip CHAR[(n)] VARCHAR TINYTEXT TEXT MEDIUMTEXT LONGTEXT ENUM SET Descriere Un câmp de acest tip reţine un şir de caractere de lungime n (fixă). În caz că n nu este precizat, reţine un caracter. Ocupă n octeţi. Un câmp de acest tip reţine şiruri de cel mult 255 de caractere. Un octet reţine lungimea efectivă a şirului. Ocupă n+1 octeţi. La fel ca mai sus. Un câmp de acest tip reţine şiruri de cel mult de caractere. Doi octeţi reţin lungimea efectivă a şirului. Ocupă n+2 octeţi, unde n este numărul de caractere al şirului. Un câmp de acest tip reţine şiruri de cel mult caractere. Trei octeţi reţin lungimea efectivă a şirului. Ocupă n+3 octeţi. Un câmp de acest tip reţine şiruri de cel mult de caractere. Patru octeţi reţin lungimea efectivă a şirului. Ocupă n+4 octeţi. Baza va reţine un vector de şiruri de caractere. Un câmp de acest tip poate reţine un singur şir de caractere din vector. De altfel, coloana reţine indicele din şir. Vedeţi exemplul 2.5! Baza va reţine un vector de şiruri de caractere.. Un câmp de acest tip poate reţine unul sau mai multe şiruri de caractere din vector. De altfel, se reţine vectorul caracteristic al şirurilor. Vedeţi exemplul 2.6! Tabelul 2.1. Tipuri de date care reţin şiruri de caractere

54 54 Manual de Informatică pentru clasa a XII-a Exemplul 2.5. Se creează tabelul tsta care are două coloane: prima reţine un şir de cel mult de caractere şi a doua, un şir din mulţimea şirurilor luni, marti, miercuri. În tabel se inserează 3 linii şi, la sfârşit, tabelul este afişat. Să observăm că în cazul coloanelor de tip SET, dacă se încearcă memorarea unui şir inexistent în definiţia coloanei (în exemplu, şirul joi ), atunci acea coloană va reţine şirul vid. Figura 2.4. Tabelul tsta CREATE TABLE tsta ( v1 TEXT, v2 ENUM ( luni, marti, miercuri ) ); INSERT INTO tsta VALUES ( un sir, miercuri ); INSERT INTO tsta VALUES ( un sir, joi ); INSERT INTO tsta VALUES ( alt sir, luni ); SELECT * FROM tsta; Exemplul 2.6. Se creează tabelul tstb care conţine două coloane c1, de lungime fixă de 3 caractere şi c2 de tip SET. Un element al coloanei poate reţine o submulţime a mulţimii { dimineata, pranz, seara. Pentru a vedea cum se introduce submulţimea, analizaţi cele trei instrucţiuni INSERT. În figura alăturată puteţi observa tabelul rezultat în urma introducerii datelor. Observaţi faptul că, la ultima inserare, se încearcă introducerea unui şir, noaptea, care nu este prezent în definiţia tipului coloanei. Nu se semnalează eroare, dar şirul nu este introdus. CREATE TABLE tstb (c1 char(3), c2 SET ( dimineata, pranz, seara ) ); Figura 2.5. Tabelul tstb INSERT INTO tstb VALUES ( abc, dimineata,seara ); INSERT INTO tstb VALUES ( abc, seara,pranz ); INSERT INTO tstb VALUES ( abc, seara ); INSERT INTO tstb VALUES ( abc, seara,noaptea ); SELECT c1,c2 FROM tstb;

55 Capitolul 2. Limbajul MySQL Tipuri de date numerice Tipurile numerice se împart la rândul lor în tipuri întregi şi tipuri reale. Tipurile întregi se găsesc în tabelul de mai jos: Tip TINYINT SMALLINT MEDIUMINT INT BIGINT Descriere Un câmp de acest tip ocupă 1 octet. Reţine numere întregi cuprinse în intervalul [-128,127], iar dacă este urmat de UNSIGNED reţine numere naturale cuprinse în intervalul [0,255]. Un câmp de acest tip ocupă 2 octeţi. Reţine numere întregi cuprinse în intervalul [-32768,32767], iar dacă este urmat de UNSIGNED, reţine numere naturale cuprinse în intervalul [0,65535]. Un câmp de acest tip ocupă 3 octeti. Reţine numere întregi cuprinse în intervalul [ , ], iar dacă este urmat de UNSIGNED, reţine numere naturale cuprinse în intervalul [0, ]. Un câmp de acest tip ocupă 4 octet.i Reţine numere întregi cuprinse în intervalul [ , ], iar dacă este urmat de UNSIGNED, reţine numere naturale cuprinse în intervalul [0, ]. Un câmp de acest tip ocupă 8 octet.i Reţine numere întregi cuprinse în intervalul [ , ], iar dacă este urmat de UNSIGNED, reţine numere naturale cuprinse în intervalul [0, ]. Tabelul 2.2. Tipuri de date numerice întregi Observaţie! Uneori veţi folosi declaraţii de tip de genul int(4). Aceasta înseamnă că în coloană se rezervă automat o lăţime de 4 caractere pentru afişarea numerelor. De exemplu, dacă numărul reţinut este 1, atunci el este afişat ca bbb1, unde prin b am notat blank-ul. Aceasta nu afectează valorile care pot fi memorate. De exemplu, dacă dorim să memorăm numărul 12345, acesta va fi memorat şi se va afişa Dar, astfel este afectată lăţimea întregii coloane. Tipurile reale se găsesc în tabelul de mai jos: Tip FLOAT DOUBLE Ocupă 4 octeţi. Ocupă 8 octeţi. Descriere

56 56 Manual de Informatică pentru clasa a XII-a DECIMAL(n,d) Numărul este stocat ca şir de caractere. Parametrul n reprezintă numărul de cifre nenule aflate înaintea virgulei, plus, dacă este cazul, 1, pentru semnul -, iar d reprezintă numărul de zecimale. Dacă numărul introdus are înaintea virgulei un număr de cifre +1 (pentru semn) mai mare decât n, acesta este trunchiat, iar dacă numărul de zecimale este mai mare ca d, atunci se reţin exact d zecimale. În acest din urmă caz, numărul se rotunjeşte la exact d zecimale. Tabelul 2.3. Tipuri de date numerice reale Exemplul 2.7. O coloană are tipul decimal(2,3): Se introduce Se memorează şi afişează Tabelul 2.4. Cum se memorează şi se afişează diverse valori cu zecimale Tipuri de date care reţin anul, data şi ora În tabelul următor aveţi tipurile care reţin anul, data şi ora: Tip YEAR TIME DATE DATETIME Descriere Un câmp de acest tip reţine ani. O dată se introduce ca şir de caractere. De exemplu, pentru anul 2001 se poate introduce 2001 sau 1, iar pentru anul 1989 se poate introduce 1989 sau 89. Un câmp de acest tip reţine ora din zi - se introduce ca şir de caractere sub forma hh:mm:ss. Un câmp de acest tip reţine data. Aceasta se introduce sub forma yyyy-mm-dd. De exemplu, Un câmp de acest tip reţine date de forma dată şi oră. O dată se introduce ca şir de forma: yyyy-mm-dd hh:mm:ss Tabelul 2.5. Tipuri de date care reţin anul, data şi ora

57 Capitolul 2. Limbajul MySQL Operatori utilizaţi în MySQL Începem prin a prezenta principalii operatori în ordinea crescătoare a priorităţii lor. Utilitatea operatorilor va fi evidenţiată în paragrafele următoare, deocamdată doar îi prezentăm: 1., OR, XOR 2. &&, AND 3. BETWEEN, CASE WHEN, THEN, ELSE 4. ==,>=,<=,<,>,!=,<>,IS,IS,LIKE,IN & 7. <<, >> 8. -,+ (operatori binari) 9. *, /, DIV, %, MOD 10. ^ 11. -,+ (operatori unari) 12.!, NOT Pentru a putea testa un operator puteţi utiliza instrucţiunea SELECT. De exemplu, dacă daţi comanda SELECT 1+1;, rezultatul se vede în imaginea alăturată 1. Observaţie foarte importantă! În MySQL există o valoare specială, numită Null. Semnificaţia ei este valoare necunoscută. Modul în care este posibil ca un câmp să reţină respectiva valoare va fi prezentat ulterior. Deocamdată reţineţi faptul că, dacă Null este un operand, atunci rezultatul oricărei operaţii care se efectuează cu Null este Null. Evident, dacă operandul este Null, atunci el este necunoscut, iar operaţia va avea rezultat necunoscut, indiferent de celălalt operand sau de tipul operaţiei. Exemplul NullNull sau Null=NullNull. Operatorii se împart, aşa cum suntem deja obişnuiţi din alte limbaje de programare, în mai multe grupe. Acestea sunt prezentate în continuare Operatori aritmetici Operatorii aritmetici acţionează asupra tipurilor numerice şi returnează o valoare de tip numeric. Pot fi analizaţi în Tabelul În cele ce urmează, pentru a evidenţia rezultatul unei operaţii, vom utiliza caracterul. Spre exemplu,

58 58 Manual de Informatică pentru clasa a XII-a Operator Operaţie Rezultat + adunare 2+3 1; - scădere ; * înmulţire 3.5*26 / împărţire 5 / 2 2.5; DIV împărţire întreagă 5 DIV 2=2; -5 DIV 2 =-2 MOD sau % restul împărţirii întregi 5 MOD 21-5 MOD % 2 1; -5 % 2-1 -, + Minus şi plus, operatori unari --11 Tabelul 2.6. Operatori aritmetici Operatori de comparare Pot fi comparate două valori numerice sau două şiruri. Şirurile se compară lexicografic (ordinea din dicţionar) şi nu se face distincţie între literele mari şi cele mici. Rezultatul este 1 pentru adevărat şi 0 pentru fals. Operator Operaţie Rezultat < mai mic. <= mai mic sau egal 2 < 1 0; 1 <2 0; ab <b 1; 2 <=2 1; > mai mare >= mai mare sau egal = egalitate <> sau!= diferit 3>2 1 b > ab 1 7>=7 1; 7 XOR 8 0; 7=71 un = UN 1 1<>21; 1!=21; 1<>10 1!=10; Tabelul 2.7. Operatori de comparare Observaţie! Se pot compara şi date de tipul TIME, DATE, etc. În fapt, o astfel de comparare este lexicografică. Vedeţi exemplul 2.9!

59 Capitolul 2. Limbajul MySQL 59 Exemplul 2.9. Analizaţi operaţiile de comparare de mai jos: 1:12:3 < 2:00:00 1, = :12:3 < 13:00: compararea s-a facut lexicografic, motiv pentru care rezultatul este eronat. 01:12:3 < 13:00:00 1 pentru ca rezultatul să fie corect, chiar dacă compararea este lexicografică, trebuie ca orele, minutele, secundele să fie cu acelaşi număr de cifre. De fapt, atunci când se memorează în baza de date o astfel de valoare, operaţia este făcută automat. Acesta este motivul pentru care comparările efectuate cu date memorate în baza de date sunt corecte Operatori logici În MySQL se consideră 2 valori logice: false, reprezentat de 0 şi true reprezentat de 1 şi de orice valoare diferită de 0. Operatorii logici acţionează asupra valorilor logice şi returnează 1, pentru adevărat şi 0, pentru fals. Operator Operaţie Rezultat sau OR && sau AND NOT XOR sau logic, dacă ambii operanzi sunt 0, rezultatul este 0, altfel rezultatul este 1. şi, dacă ambii operanzi sunt diferiţi de 0, rezultatul este 1, altfel rezultatul este 0. negare, dacă operandul este 0, rezultatul este 1, altfel rezultatul este 0. sau exclusiv, dacă un operand este 0 şi altul diferit de 0, rezultatul este 1, altfel, rezultatul este 0. Tabelul 2.8. Operatori logici 2 1 1; 0 1 1; 0 0 0; 2 && 1 1; 2 && 0 0; 0 && 0 0; NOT 30; NOT 1=0; NOT 0=1; 7 XOR 0 1; 7 XOR 8 0; 0 XOR 0 0; Operatori logici pe biţi Se aplică tipurilor întregi şi acţionează asupra tuturor biţilor aflaţi pe poziţii corespondente. Operator Operaţie Rezultat & sau pe biţi, dacă ambii biţi sunt 0, rezultatul este 0, altfel rezultatul este 1. şi pe biţi, dacă ambii biţi sunt 1, rezultatul este 1, altfel rezultatul este & 1 0

60 60 Manual de Informatică pentru clasa a XII-a ^ ~ sau exclusiv pe biţi, dacă biţii sunt diferiţi, rezultatul este 1, altfel rezultatul este 0. negare, un bit 0 devine 1, un bit 1 devine 0. Tabelul 2.9. Operatori logici pe biţi 10^39 (1010 ^ ) ~ Operatori de deplasare Se aplică tipurilor întregi şi acţionează asupra tuturor biţilor aflaţi pe poziţii corespondente. Operator Operaţie Rezultat << >> deplasare stânga, deplasare către stânga a biţilor operandului din stânga cu k poziţii, unde k este operandul din dreapta. Poziţiile rămase libere se completează cu 0. deplasare dreapta, deplasare către dreapta a biţilor operandului din stânga cu k poziţii, unde k este operandul din dreapta. Tabelul Operatori de deplasare 1<<24 (1 trece în 100) 4>>21 (100 trece în 1) Alţi operatori Operatorii IS NULL, IS NOT NULL testează dacă o valoare este sau nu NULL (sunt singurii operatori prin care se testează acest lucru)! Exemplul Analizaţi operaţiile următoare: 1 IS NULL 0;, NULL IS NULL 1;, 1 IS NOT NULL 1;, NULL IS NOT NULL 0;. Operatorii IN, NOT IN testează apartenenţa unei valori la o mulţime. Valoarea poate fi de formă numerică sau de un tip care reţine un şir de caractere. Importanţa mare pe care o au aceşti operatori va rezulta studiind paragrafele următoare. Exemplul Analizaţi operaţiile următoare: 1 IN(1,2,3,4) 1;, 5 IN(1,2,3,4) 0;, 1sir IN ( 1sir, 2sir, 3sir ) 1;, 4sir IN ( 1sir, 2sir, 3sir ) 0;. Operatorul LIKE, NOT testează dacă un şir de caractere îndeplineşte anumite condiţii: dacă este prefixat sau nu de un anumit subşir, dacă este postfixat sau nu de acesta sau dacă subşirul se găseşte în interior. Pentru substituirea unui număr neprecizat de caractere necunoscute se utilizează caracterul %, iar pentru un singur caracter neprecizat se utilizează caracterul _.

61 Capitolul 2. Limbajul MySQL 61 Exemplul Analizaţi operaţiile următoare: popescu LIKE pop% 1; ( popescu este prefixat de subşirul pop ), ponescu LIKE pop% 0; ( ponescu nu este prefixat de subşirul pop ), ionescu LIKE %escu 1 ( ionescu este postfixat de subşirul escu ). Operatorul BETWEEN min AND max testează dacă o valoare se găseşte între o valoare minimă şi una maximă. În caz afirmativ returnează 1, altfel, 0. Se poate aplica şi pentru date care reţin şiruri de caractere (ordinea lexicografică), dar şi pentru datele de timp. Exemplul Analizaţi operaţiile următoare: 1 BETWEEN 0 AND 4 1;, mama BETWEEN min AND lin 1;, 2 BETWEEN 2 AND 2 1;, 1 BETWEEN 2 AND 4 0;, BETWEEN AND Operatorul CASE WHEN THEN ELSE. Poate fi aplicat în două forme: Forma 1. Se evaluează v şi dacă produce valoarea v i se returnează valoarea val i, iar dacă nicio condiţie v i nu este îndeplinită, se returnează valoarea val n+1 : CASE v WHEN v 1 THEN val 1 [WHEN v 2 THEN val 2 ]... [WHEN v n THEN val n ] [ELSE val n+1 ] END Exemplul Se afişează doi : CASE 2 WHEN 1 THEN unu WHEN 2 THEN doi WHEN 3 THEN trei ELSE alta valoare END; Forma 2. În această formă, dacă este îndeplinită condiţia i, se returnează valoarea v i,. Dacă niciuna din condiţiile v i nu este îndeplinită, se returnează valoarea v n+1 : CASE WHEN conditie 1 THEN v 1 [WHEN conditie 2 THEN v 2 ]... [WHEN conditie n THEN v n ] ELSE v n+1 END

62 62 Manual de Informatică pentru clasa a XII-a Exemplul Se afişează adevarat : CASE WHEN 1<2 THEN adevarat ELSE nu se poate END; 2.7. Funcţii MySQL În MySQL există o serie de funcţii predefinite. Întrucât astfel de funcţii au fost prezentate pentru limbajul studiat (Pascal sau C/C++), în acest paragraf vor fi tratate pe scurt. Pot fi testate prin utilizarea instrucţiunii SELECT Câteva funcţii matematice Funcţie Descriere Rezultat ABS(-2) 2; ABS(x) Modul de x. CEIL(x) FLOOR(X) Cel mai mic întreg mai mare sau egal cu x. Cel mai mare întreg mai mic sau egal cu x. CEIL(1.7) 2; CEIL(2)2; CEIL(-1.7)-1; FLOOR(-1.7) -2 FLOOR(2) 2; FLOOR(1.7) 1; EXP(x) e x EXP(1) LOG(b,x) Logaritm în baza b din x. LOG(2,4) 2; PI() π PI() POW(x,y) x y POW(2,3)8 ROUND(x) Cel mai apropiat întreg de x. ROUND(2.3)2; ROUND(2.7)3; ROUND(-2.8)-3; SIN(x) Sinus de x. SIN(PI()/2)1; COS(x) Cosinus de x. COS(0) 1 SIGN(x) SIGN(2) 1; Semnul lui x: -1, dacă x<0, 0, dacă SIGN(0) 0; x=0, 1 dacă x>0. SIGN(-2) -1; SQRT(x) Radical din x. SQRT(4) 2; Tabelul Funcţii matematice

63 Capitolul 2. Limbajul MySQL Câteva funcţii care lucrează asupra şirurilor de caractere Funcţie Descriere Rezultat LENGTH(x) Lungimea şirului x. CONCAT(x1,x2,..) INSTR(x,y) SUBSTRING(x, p,l) RTRIM(x) LTRIM(x) TRIM(x) UPPER(x) LOWER(x) FIND_IN SET (x, s1,s2,..sn ) FORMAT(x,d) STRCMP(x,y) Concatenează şirurile x1,x2,. Caută dacă y este subşir pentru x. În caz afirmativ, returnează indicele de început (indicii încep cu 1), altfel returnează 0. Returnează subşirul din x care începe în poziţia p şi are lungimea l. Returnează şirul fără blank-urile din dreapta. Returnează şirul fără blank-urile din stânga. Returnează şirul fără blank-urile din stânga şi din dreapta. Returnează şirul scris cu litere mari. Returnează şirul scris cu litere mici. Returnează indicele apariţiei şirului x în şirul de şiruri s1,s2,...,sn. Dacă x nu este găsit, returnează 0. Converteşte numărul real x la un şir cu d zecimale. Pentru ultima zecimală se face, dacă este cazul, rotunjirea. Compară lexicografic şirurile x şi y. Dacă x<y returnează -1, dacă x=y returnează 1, iar dacă x>y, returnează 1. LENGTH( abc ) 3; CONCAT( ab, c ) abc INSTR( abc, b )2 INSTR( abc, d )0 SUBSTRING( abc,2,1) b RTRIM( un ) un LTRIM( un ) un TRIM( un ) un UPPER( Un ) UN LOWER( Un ) un FIND_IN_SET ( b, a,b,c ) 2 FORMAT(1.789,2) 1.79 STRCMP( ma, mama ) -1 Tabelul Funcţii care lucrează asupra şirurilor de caractere Câteva funcţii care lucrează asupra datei şi orei Funcţie Descriere Rezultat NOW() Returnează data şi ora sub forma yyyy-mm-dd hh:mm:ss.

64 64 Manual de Informatică pentru clasa a XII-a YEAR(x) DAY(X) MONTH(x) TIME(x) HOUR(x) Dacă x este de tipul DATA, afişează anul extras din x. Ca mai sus, extrage ziua. Ca mai sus, extrage luna. Ca mai sus, extrage ora. Ca mai sus, extrage ora ca număr între 0 şi 23. YEAR(NOW()) returnează anul curent. DAY(NOW())returnează ziua curentă. MONTH(NOW()) returnează luna curentă. TIME(NOW()) returnează ora curentă. HOUR(NOW()) returnează ora curentă ca număr între 0 şi 23. MINUTE Ca mai sus, extrage minutul. returnează minutul MINUTE(NOW()) curent DATEDIFF (x,y) DATE_ADD (data,interv AL,nr, x) x şi y sunt de tip DATETIME sau DATE. Calculează diferenţa în zile dintre x şi y. Calculează data care se obţine dacă la valoarea data se adună nr, unde x specifică ce este nr: YEAR - ani, DAY - zile, MONTH - luni. DATEDIFF(NOW(), ) DATE_ADD(NOW(), INTERVAL, 10 DAY) Se obţine data care va fi peste 10 zile. DATE_SUB (data,interv AL,nr, x) La fel ca mai sus, numai că se obţine data diferenţă. DATE_SUB(NOW(), INTERVAL, 10 DAY) Se obţine data care a fost acum 10 zile. Tabelul Funcţii care lucrează asupra datei şi orei Două funcţii speciale Funcţia IF are forma de mai jos, unde expresie 1 este de un tip întreg. Dacă expresie 1 este nenulă, atunci se returnează expresie 2, altfel se returnează expresie 3. Atenţie: dacă expresie 1 este de tip real, se rotunjeşte la cel mai apropiat întreg. Dacă, de exemplu, acesta este 0.41, atunci se rotunjeşte la 0, prin urmare, rezultatul va fi altul... IF(expresie 1,expresie 2,expresie 3 ) Exemplul Analizaţi exemplele următoare: IF (1>2, adevarat, fals ) adevarat, IF (0.45, nu, da ) da ;. Funcţia IFNULL are forma de mai jos. Dacă expresie 1 nu este NULL, returnează expresie 1,, altfel returnează expresie 2. IFNULL(expresie 1, expresie 2 )

65 Capitolul 2. Limbajul MySQL 65 Exemplul Analizaţi exemplele următoare: IFNULL (0, este null ) 0, IFNULL (NULL, este NULL ) este NULL Afişarea coloanelor care rezultă în urma unui calcul O regulă elementară în crearea şi utilizarea bazelor de date spune că acestea vor reţine numai date care nu rezultă în urma unui calcul. Nerespectarea ei conduce la baze de date care ocupă mult spaţiu. Acum vom învăţa să afişăm datele care rezultă în urma unui calcul. Exemplul Priviţi tabelul din Fig. 2.6, numit prod, care reţine produsele existente într-un depozit. Pentru fiecare produs se cunoaşte cantitatea ( cant ) şi preţul unitar ( pret_unitar ), preţul unui exemplar din produsul respectiv. Să presupunem că dorim ca, pe lângă informaţiile afişate, să aflăm valoarea totală pentru fiecare produs în parte. Valoarea se obţine ca produs între cantitate şi preţul unitar. Figura 2.6. Tabelul prod Pentru aceasta, atunci când afişăm tabelul, vom crea o nouă coloană sub forma: expresie AS nume_coloana, unde expresie calculează valorile din coloana respectivă, iar nume_coloana va fi numele ei. Iată cum se afişează noul tabel, prezentat mai jos: Figura 2.7. Tabelul rezultat SELECT den, cant, pret_unitar, cant*pret_unitar AS valoare FROM prod; Exemplul Se dă tabelul alăturat, numit persoane. Se cere să se separe numele de prenume şi să se afişeze datele ca mai jos: Figura 2.9. Tabelul dorit Figura 2.8. Tabelul persoane

66 66 Manual de Informatică pentru clasa a XII-a Rezolvare. Se utilizează funcţii care operează asupra şirurilor de caractere: SELECT SUBSTRING(nume,1,INSTR(nume, )-1) AS prenume SUBSTRING(nume, 1+INSTR(nume, ),LENGTH(nume)) AS nume FROM persoane; Exemplul Se consideră tabelul din Fig. 2.10, numit pers, care cuprinde numele şi data naşterii pentru două persoane: Figura Tabelul pers Se cere să se afişeze numele şi vârsta fiecărei persoane. Figura Tabelul dorit Rezolvare. Se utilizează funcţii care operează asupra câmpurilor de tip DATE şi DATETIME. SELECT nume, YEAR(NOW())-YEAR(data_n) AS varsta FROM pers; Exemplul Se consideră un tabel, numit numar, alcătuit dintr-o singură coloană, c de tip INT. Se cere să se listeze acea coloană şi o alta, numită paritate, care să conţină două valori: par dacă numărul din c este par şi impar, în caz contrar (vezi figura alăturată). SELECT c, IF(C MOD 2, impar, par ) AS paritate FROM numar; Figura Tabelul rezultat 2.9. Valoarea NULL În MySQL, aşa cum s-a arătat, există o valoare specială, numită NULL. Semnificaţia ei este nicio valoare. Atunci când definim o coloană se poate trece specificatorul NULL. Oricum, se asumă implicit, NULL. De altfel, acest lucru poate fi testat. Creaţi un tabel, de exemplu, cu o coloană de un anumit tip, fără a specifica NULL sau NOT NULL şi apoi daţi comanda SHOW COLUMNS FROM nume_tabel; şi analizaţi tabelul afişat! Exerciţiu!

67 Capitolul 2. Limbajul MySQL 67 a) Atunci când o coloană are trecut specificatorul NULL sau nu s-a trecut nimic şi la introducerea unui rând, pentru coloana respectivă, nu este trecută o valoare pentru acel câmp, acolo se va memora valoarea specială NULL. b) Atunci când o coloană are trecut specificatorul NOT NULL şi la introducerea unui rând, în coloana respectivă, nu este trecută o valoare, acolo se va memora: - 0, dacă coloana este de tip numeric; - şirul vid, dacă coloana este de un tip care permite reţinerea de şiruri; - indicele 0 din şir, dacă coloana este de tip ENUM şi aceasta are ca efect afişarea primului şir al enumerării; - mulţimea vidă, dacă coloana este de tip SET. Analizaţi exemplele următoare şi verificaţi, de fiecare dată, tabelul afişat. Exemplul Rulaţi secvenţa de mai jos şi se va afişa tabelul alăturat: CREATE TABLE testnull (c1 INT NULL, c2 INT NOT NULL); INSERT INTO testnull (c2) VALUES (10); INSERT INTO testnull (c1) VALUES (7); Figura Tabelul rezultat SELECT * FROM testnull; Exemplul Se creează tabelul alăturat, în care coloanele reţin şiruri de caractere: CREATE TABLE testnull1 (c1 TEXT NULL, c2 TEXT NOT NULL); INSERT INTO testnull1(c1) VALUES ( Un sir ); INSERT INTO testnull1(c2) VALUES ( Alt sir ); Figura Tabelul rezultat SELECT * FROM testnull1; Exemplul Se creează tabelul din figura alăturată, în care coloanele reţin date de tip ENUM: CREATE TABLE testnull2 ( c1 ENUM( sir1, sir2, sir3 ) NULL, c2 ENUM( sir1, sir2, sir3 ) NOT NULL); INSERT INTO testnull2(c1) VALUES ( sir2 ); INSERT INTO testnull2(c2) VALUES ( sir1 ); Figura Tabelul rezultat SELECT * FROM testnull2;

68 68 Manual de Informatică pentru clasa a XII-a Exemplul Se creează tabelul alăturat, în care coloanele reţin date de tip SET. CREATE TABLE testnull3 ( c1 SET( sir1, sir2, sir3 ) NULL, c2 SET( sir1, sir2, sir3 ) NOT NULL); INSERT INTO testnull2(c1) VALUES ( sir1,sir2 ); INSERT INTO testnull2(c2) VALUES ( sir3 ); SELECT * FROM testnull3; Figura Tabelul rezultat Aşa cum am arătat, semnificaţia lui NULL este nicio valoare. De asemenea, am învăţat că o operaţie în care un operand este NULL, va avea rezultatul NULL. Acest fapt este util, pentru că, în caz contrar s-ar putea ajunge la rezultate false. Exemplul Tabelul alăturat elev prezintă numele, nota la engleză şi nota la franceză pentru doi elevi. Unul dintre ei, nu are notă la franceză (NULL). Figura Tabelul elev Se cere să se calculeze mediile celor doi elevi. Scriem interogarea: SELECT nume, (engleza+franceza)/2 AS media; Figura Rezultatul interogării Să observăm că pentru elevul căruia nu i se cunoaşte nota la franceză, nu i se cunoaşte nici media. Logic vorbind, aşa este corect. Dacă nu se cunoaşte o notă, nu se cunoaşte nici media deoarece n-ar fi normal ca pentru acest elev să se afişeze media Valori implicite În practică, nu întotdeauna se cunosc datele în totalitate. În astfel de cazuri, atunci când pentru un anumit rând nu se cunoaşte un câmp, fie acesta va reţine NULL, fie va reţine o valoare implicită, convenabil aleasă. De exemplu, dacă la un examen de admitere un elev nu se prezintă la o probă, se poate lua decizia ca, la acea probă, elevul să primească nota 1. Pentru ca un câmp, în absenţa datelor să aibă o valoare implicită, se foloseşte specificatorul DEFAULT: DEFAULT valoare_implicita Facem observaţia că pot lua valori implicite câmpurile cu lungime fixă. De exemplu, un câmp declarat CHAR(20) poate lua o valoare implicită, dar unul declarat TEXT nu poate lua o astfel de valoare.

69 Capitolul 2. Limbajul MySQL 69 Exemplul În tabelul următor, se reţin numele şi oraşul de domiciliu pentru mai multe persoane: Figura Tabelul propus Dacă oraşul de domiciliu nu este cunoscut, se preferă, în locul valorii NULL, să fie afişat şirul necunoscut : CREATE TABLE pers_oras (nume CHAR (25), domiciliu CHAR(30) DEFAULT necunoscut ); INSERT into pers_oras (nume) VALUES ( Gulagea Constantin ); INSERT into pers_oras VALUES ( Ionescu Mihai, Galati ); SELECT * FROM pers_oras; Cheie primară şi cheie unică A) Cheia primară este constituită dintr-un câmp (sau mai multe câmpuri) şi trebuie să îndeplinească simultan condiţiile: a) Valorile reţinute de coloana care alcătuieşte cheia primară trebuie să fie distincte. În cazul în care cheia este alcătuită din mai multe coloane, pentru a avea două chei distincte, este necesar ca acestea să fie diferite pentru cel puţin o coloană dintre ele. Tentativa de a înscrie în tabel o înregistrare care are cheia primară identică cu alta, existentă în tabel, este sancţionată cu eroare. b) Câmpul (câmpurile) care alcătuieşte (alcătuiesc) cheia primară trebuie să aibă o lungime fixă. De exemplu, nu poate fi cheie primară un câmp de tip TEXT. Raţiunea existenţei cheii primare este dată de accesul foarte rapid la înregistrarea de cheie dată. Trebuie ştiut că înregistrările unui tabel se reţin în ordinea introducerii lor. Atunci când, de exemplu, un câmp este declarat cheie primară, se construieşte un tabel auxiliar, invizibil pentru utilizator, în care pentru fiecare valoare din câmpul cheie primară se reţine poziţia rândului care are acea cheie. În acel tabel, cheile sunt în ordine crescătoare (dacă este vorba de şiruri de caractere, acestea se reţin în ordine lexicografică, ca mai jos). Pornind de la cheie, în tabelul invizibil se identifică rapid rândul cu acea cheie. În acest caz, se foloseşte căutarea binară, algoritm studiat la informatică (revedeţi) şi, după cum ştiţi, o astfel de căutare se face în O(log(n)). Din acel rând se află poziţia înregistrării cu acea cheie din tabelul iniţial. De aici, accesul la înregistrare este imediat. Căutarea clasică se efectuează în O(n).

70 70 Manual de Informatică pentru clasa a XII-a Exemplul Presupunem că tabelul principal are drept cheie primară câmpul "Nume": Tabel principal Nume Vârstă Înălţime (cm) Ion Maria Ana Cristian Mihai Tabel invizibil Nume Poziţie Ana 3 Cristian 4 Ion 1 Maria 2 Mihai 5 Pentru a preciza că o anumită coloană este cheie primară se foloseşte, atunci când se descrie coloana, specificatorul PRIMARY KEY. Exemplul Se creează un tabel în care prima coloană este cheie primară: CREATE TABLE ex_cheie_primara_un_camp (c1 INT PRIMARY KEY, c2 TEXT ); Dacă cheia primară este alcătuită din mai multe câmpuri, după descrierea coloanelor, se utilizează specificatorul PRIMARY KEY sub forma: PRIMARY KEY(nume_col1, nume_col2,...) Exemplul În tabelul următor cu trei coloane, coloanele c1 şi c2 alcătuiesc cheia primară: CREATE TABLE cheie_primara_doua_campuri (c1 INT, c2 CHAR(10), c3 TEXT, PRIMARY KEY(c1,c2) ); B) Cheie unică - se poate cere ca o coloană (sau mai multe) să conţină numai valori distincte. Pentru aceasta se va utiliza specificatorul UNIQUE KEY. În acest caz, dacă în coloana respectivă se va încerca o inserare cu o valoare care există deja, se va semnala eroare. Observaţie! Şi în acest caz, nu este permis să solicităm valori distincte pentru o coloană de un tip de lungime variabilă (cum ar fi, de exemplu, tipul TEXT). Exemplul Se creează un tabel în care în ambele coloane vor fi numai valori distincte: CREATE TABLE distincte ( c1 INT UNIQUE KEY, c2 char(10) UNIQUE KEY );

71 Capitolul 2. Limbajul MySQL Autoincrementare Cu siguranţă, aţi văzut o mulţime de tabele în care rândurile sunt numerotate. Mai jos, aveţi un astfel de tabel, cu numele unor persoane: Figura Tabelul cu număr de ordine Este incomod, ca la introducerea fiecărui rând să se specifice numărul de ordine pentru rândul respectiv. Din acest motiv, s-a pus la dispoziţia clienţilor un mecanism prin care incrementarea se face automat. Pentru ca o coloană să reţină numerele de ordine al rândurilor respective, este necesar ca, la definirea ei, să se utilizeze specificatorul AUTO_INCREMENT. Pentru a putea utiliza acest specificator, este necesar să fie îndeplinite condiţiile: a) coloana să fie de un tip întreg; b) coloana să reţină numai valori distincte - pentru a determina aceasta, coloana trebuie să fie declarată ca fiind cheie primară sau cu cheie unică. Exemplul Iată cum am creat tabelul din Fig. 2.20, numit auto : CREATE TABLE auto (nr_ord INT UNIQUE KEY AUTO_INCREMENT, nume CHAR(20) ); INSERT INTO auto (nume) VALUES( Marius Oprean ); INSERT INTO auto (nume) VALUES( Mihai Minca ); Există şi posibilitatea să se introducă valori dorite în coloana declarată cu autoincrementare. În acest caz, la următoarele introduceri, valorile implicite vor fi obţinute pornind de la valoarea introdusă. Exemplul Analizaţi tabelul alăturat, obţinut din cel anterior, la care s-au mai făcut inserările de mai jos: Figura Tabel modificat INSERT INTO auto VALUES(7, Doru Cran ); INSERT INTO auto (nume) VALUES( Dan Bitu );

72 72 Manual de Informatică pentru clasa a XII-a Sortarea datelor Uneori este necesar ca datele să fie afişate sortate după valorile unei coloane sau după valorile mai multor coloane. Dacă acestea sunt de tip şir de caractere, ele pot fi sortate în ordine lexicografică. Alăturat aveţi un tabel, numit sortare, pe care vom exersa modul de afişare a datelor sortate după anumite criterii. Exemplul Datele sunt afişate sortate crescător, după valorile existente în coloana nume. Să observăm că sortarea crescătoare este cea implicită, pentru a o obţine nu este necesar să o specificăm: SELECT * FROM sortare ORDER BY nume; Figura Tabel sortare Exemplul Pentru a sorta datele descrescător, se foloseşte specificatorul DESC. Mai jos, am sortat datele descrescător după valorile câmpului data_n (data naşterii): Figura Tabelul sortat crescător SELECT * FROM sortare ORDER BY data_n DESC; Figura Tabelul sortat descrescător după data naşterii Există posibilitatea să sortăm datele (crescător sau descrescător) după valorile existente în mai multe coloane. Practic, mai întâi se sortează datele după prima coloană specificată, apoi, păstrând această ordine, după a doua coloană, ş.a.m.d. Exemplul Datele sunt sortate crescător după valorile existente în coloana nume, apoi, păstrând această ordine, descrescător după valorile din coloana data_n. SELECT * FROM sortare ORDER BY nume, data_n DESC; Figura Tabelul sortat crescător după ambele coloane Observaţie! Avem două persoane cu numele Mihai. Mai întâi este afişată persoana născută în 1980, apoi cea născută în 1975 (sortate descrescător după câmpul data_n ).

73 Capitolul 2. Limbajul MySQL 73 Exemplul Există posibilitatea să afişăm numai un număr dorit de rânduri. Pentru aceasta se foloseşte clauza LIMIT, ca mai jos: SELECT * FROM sortare ORDER BY nume LIMIT 3; Figura Afişarea unor rânduri din tabel Filtrarea datelor Uneori nu suntem interesaţi să fie afişate toate liniile tabelului, ci numai unele, care îndeplinesc anumite condiţii. O astfel de operaţie se numeşte filtrare. Pentru a realiza operaţia de filtrare se ataşează instrucţiunii SELECT, la sfârşit, clauza WHERE condiţie. În acest fel, sunt selectate numai liniile pentru care condiţia din clauza WHERE este îndeplinită. În cazul în care datele se cer sortate, clauza ORDER BY se va trece după WHERE. Exemplul Se consideră un tabel precum cel de mai jos, în care se prezintă situaţia şcolară a elevilor unei clase: CREATE TABLE elevi ( nume TEXT, matematica INT, engleza INT, informatica INT); Figura Tabelul elevi 1. Afişaţi numele elevilor care au la matematică note mai mari sau egale cu 8. SELECT nume FROM elevi WHERE matematica>=8; Figura Exemplu de filtrare 2. La fel ca mai sus, numai că se cere ca numele elevilor să fie afişate în ordine alfabetică. SELECT nume FROM elevi WHERE matematica>=8 ORDER BY nume; Figura Exemplu de filtrare

74 74 Manual de Informatică pentru clasa a XII-a 3. Se cere să se afişeze numele elevilor care au promovat la fiecare materie şi media generală pe care aceştia o au. SELECT nume, (matematica+engleza+informatica)/3 AS media FROM elevi WHERE matematica>4 AND engleza>4 AND informatica>4; Figura Exemplu de filtrare Observaţie! Filtrarea datelor este un caz considerat particular al unui concept cu mult mai general, interogarea! De obicei, interogăm o bază de date cu ajutorul instrucţiunii SELECT Actualizări într-un tabel În general, prin actualizarea unui tabel înţelegem modificarea datelor reţinute de acesta şi/sau modificarea structurii sau numelui tabelului. A) Prin actualizarea datelor dintr-un tabel înţelegem operaţii precum inserarea unor linii, modificarea valorilor unor câmpuri şi ştergerea unor rânduri. A1) Pentru inserare, putem utiliza instrucţiunile de mai jos: 1. INSERT INTO nume_tabel [(nume_col 1, nume_col 2..) VALUES(expresie 1, expresie 2...) Această instrucţiune a fost deja prezentată, nu vom mai reveni asupra ei. 2. INSERT INTO [DISTINCT nume_tabel [(nume_col 1, nume_col 2..) SELECT... Într-un tabel se pot insera linii dintr-un alt tabel. Pentru aceasta se foloseşte instrucţiunea de mai sus (vezi Exemplul 2.38, pct. 1). Dacă se doreşte inserarea numai a liniilor distincte din tabelul sursă, utilizaţi specificatorul DISTINCT. A2) Pentru a modifica valorile reţinute de un câmp sau mai multe, se utilizează instrucţiunea de mai jos (vezi Exemplul 2.38, pct. 2): UPDATE nume_tabel SET coloana 1 =expresie 1,... coloana k =expresie k [WHERE conditie];

75 Capitolul 2. Limbajul MySQL 75 În urma executării acestei comenzi, pentru fiecare rând din tabel care îndeplineşte condiţia din WHERE, se actualizează coloanele indicate de SET cu expresiile corespunzătoare. Observaţie! În absenţa clauzei WHERE sunt afectate toate rândurile din tabel. A3) Ştergerea unui rând sau a mai multor rânduri se face cu instrucţiunea de mai jos (vezi Exemplul 2.38, pct. 3 şi pct. 4): DELETE FROM nume_tabel [WHERE conditie] Observaţie! În absenţa clauzei WHERE sunt şterse toate rândurile din tabel. B) Modificări ale numelui tabelului sau a structurii acestuia. B1) Pentru a modifica numele unui tabel se utilizează instrucţiunea: RENAME TABLE nume_vechi TO nume_nou B2) Pentru ştergerea unei coloane, chiar dacă conţine date, se utilizează instrucţiunea: ALTER TABLE nume_tabel DROP COLUMN nume_coloana B3) Pentru adăugarea unei coloane cu un tip de date, se utilizează instrucţiunea: ALTER TABLE nume_tabel ADD nume_col tip; Exemplul Fie tabelele de mai jos, ambele cu aceleaşi coloane, de acelaşi tip: Figura Tabelul prs Figura Tabelul prs1 1. Se cere să se insereze în tabelul prs, acele persoane din prs1 care sunt din Craiova. Alăturat, vedeţi tabelul prs actualizat. INSERT INTO prs (nume, oras) SELECT nume, oras FROM prs1 WHERE oras= craiova ; Figura Tabelul prs actualizat

76 76 Manual de Informatică pentru clasa a XII-a 2. S-a observat că Ioana şi Florin sunt de fapt din braila. Corectaţi datele din tabel! Alăturat aveţi afişat tabelul cu datele actualizate. UPDATE prs SET oras= braila WHERE nume IN ( ioana, florin ); Figura Tabelul actualizat 3. Ştergeţi din tabelul prs înregistrarea în care numele este Mirela (vezi figura alăturată): DELETE FROM prs WHERE nume= Mirela ; Figura Creaţi un nou tabel prs2, cu aceeaşi structură ca şi prs, care să conţină numai persoanele din prs care sunt din Braila şi Ploiesti. CREATE TABLE prs2 AS SELECT nume, oras FROM prs WHERE nume IN ( braila, ploiesti ); Figura Tabelul nou prs2 Exemplul În tabelul alăturat, prs, există mai multe înregistrări identice. Se cere să se elimine duplicatele. a) Creăm un alt tabel, de manevră, numit mand, care conţine aceleaşi înregistrări cu prs, doar că au fost eliminate duplicatele: CREATE mand AS SELECT distinct nume, oras FROM prs; b) Ştergem tabelul prs : DROP TABLE prs; Figura Tabelul prs c) Redenumim tabelul mand ca prs şi-l afişăm pe prs : RENAME TABLE mans TO PRD; SELECT * FROM prs; Figura Tabelul rezultat Observaţie! Mare atenţie când efectuaţi astfel de operaţii. În cazurile reale, în care tabelele au mii de rânduri, se pot produce pierderi de date. Din acest motiv, înainte de a actualiza un tabel, este bine să-i creaţi o copie de siguranţă pe care, după ce aţi rezolvat problema, s-o ştergeţi.

77 Capitolul 2. Limbajul MySQL Funcţii agregate Toate calculele făcute până în prezent au avut ca operanzi doar câmpurile unui aceluiaşi rând. Întrebarea este: se pot efectua calcule cu valorile reţinute de o coloană? Răspunsul este afirmativ. Pentru astfel de calcule se utilizează aşa-numitele funcţii agregate. În cele ce urmează, prezentăm aceste funcţii, iar pentru exemplificare utilizăm tabelul elevi, tabel pe care l-am creat în paragraful Funcţiile agregate sunt prezentate în tabelul de mai jos: Nume funcţie COUNT() MIN() MAX() SUM() AVG() Ce realizează Sub forma COUNT(*), afişează numărul de linii ale tabelului. Sub forma COUNT(nume_coloana), numără valorile, din coloana de nume dat, care nu sunt NULL. Sub forma MIN(nume_coloana), calculează cea mai mică valoare din coloană. Valorile NULL sunt ignorate. Sub forma MAX(nume_coloana), calculează cea mai mare valoare din coloană. Valorile NULL sunt ignorate. Sub forma SUM(nume_coloana), calculează suma valorilor dintr-o coloană. Valorile NULL sunt ignorate. Sub forma AVG(nume_coloana), calculează media aritmetică a valorilor dintr-o coloană. Valorile NULL sunt ignorate. Exemplul Câţi elevi sunt în tabel? Tabelul Funcţii agregate SELECT COUNT(*) AS numar_elevi FROM elevi; Figura Exemplul Care este numărul de note la engleză? Se afişează 4, pentru că un elev nu are notă la această disciplină (NULL). SELECT COUNT(engleza) AS numar_note_engleza FROM elevi; Figura Exemplul Care este media notelor la informatică? SELECT AVG(informatica) AS media_note_informatica FROM elevi; Exemplul Câţi elevi au nota 10 la engleză? SELECT COUNT(engleza) AS elevi_de_zece FROM elevi WHERE engleza=10; Figura Figura 2.42.

78 78 Manual de Informatică pentru clasa a XII-a Exemplul Câţi elevi au media generală peste 8? SELECT COUNT(nume) AS elevi_peste_8 WHERE (matematica+engleza+informatica)/3>8; Figura Rezultat Utilizarea subinterogărilor Aşa cum am arătat, filtrările sunt cazuri particulare de interogări. În general, orice rezultat care este obţinut cu ajutorul unei instrucţiuni SELECT este o interogare. La modul general, o interogare poate returna: A) o coloană, eventual cu un singur rând; B) mai multe coloane - în acest caz se poate spune că interogarea returnează un tabel. Problema care se pune în continuare este următoarea: pot fi utilizate datele returnate de o interogare pentru a efectua o nouă interogare? Răspunsul este, în general afirmativ şi este valabil începând cu versiunea MySQL incorporată în versiunea EasyPHP 1.8. În aceste cazuri, prima interogare care se efectuează este interogarea subordonată. Rezultatul ei este utilizat pentru a efectua o nouă interogare. Vom considera, pe rând, cazurile în care interogarea subordonată returnează o valoare, o coloană şi un tabel (mai multe coloane). Toate exemplele care urmează vor avea ca bază de plecare tabelul elevi, utilizat şi în paragrafele anterioare. A) Interogarea subordonată returnează o coloană cu un singur rând Exemplul Se cere să se determine numele elevilor care au cea mai mare notă la matematică. Figura Rezultatul dorit Practic, ar trebui să vedem care este cea mai mare notă la matematică, o primă interogare, problemă pe care o rezolvăm utilizând funcţia agregată MAX(), apoi într-o nouă interogare, aflăm numele elevilor care au această notă. În acest caz, interogarea subordonată returnează o valoare, cea maximă. SELECT nume, matematica FROM elevi WHERE matematica=(select MAX(matematica) FROM elevi); Mai întâi, se execută interogarea subordonată, apoi cea care o subordonează. În acest caz, interogarea subordonată calculează nota maximă obţinută la matematică (să observăm că aceasta nu este în mod obligatoriu 10), iar cealaltă interogare returnează numele elevilor cu această notă.

79 Capitolul 2. Limbajul MySQL 79 Exemplul Se cer numele elevilor care au cea mai mare medie la obiectele matematică şi informatică. Vom proceda în acelaşi mod. În primul rând, selectăm media maximă la obiectele amintite, apoi numele elevilor cu această medie. SELECT nume, (matematica+informatica)/2 AS media FROM elevi WHERE (matematica+informatica)/2= (SELECT MAX((matematica+informatica)/2) FROM elevi); Figura Rezultatul obţinut Exemplul Se cer numele elevilor şi media generală, unde media generală a lor este strict mai mare decât media elevilor din tabel. Se cere, de asemenea, ca elevii să fie ordonaţi în ordinea crescătoare a mediilor. Interogarea subordonată calculează media generală a elevilor, iar prima interogare afişează elevii care au media generală peste aceasta. SELECT nume, (matematica+informatica+engleza)/3 AS media FROM elevi where (matematica+engleza+informatica)/3> (SELECT AVG((matematica+engleza+informatica)/3) FROM elevi) ORDER BY media DESC; Figura Rezultatul obţinut Exemplul Care este numele elevilor care au aceeaşi notă la matematică ca şi elevul Popescu Marius? În acest caz, interogarea subordonată returnează nota la matematică a elevului Popescu Marius, iar interogarea care o subordonează returnează numele elevilor care au această notă: SELECT nume FROM elevi WHERE matematica= (SELECT matematica FROM elevi WHERE nume= Popescu Marius ); Figura Rezultatul obţinut B) Interogarea subordonată returnează un tabel În acest caz, tabelul returnat de interogarea subordonată trebuie să aibă un nume. Acesta se dă cu ajutorul clauzei AS. De asemenea, interogarea care subordonează adresează câmpurile tabelului, pornind de la numele său, urmat de. şi de numele coloanei. Exemplul Care este media generală la matematică şi la informatică a elevilor care au cel puţin 8 la una dintre discipline?

80 80 Manual de Informatică pentru clasa a XII-a Tabelul returnat de interogarea subordonată conţine notele la matematică şi la informatică ale elevilor care au cel puţin 8 la una dintre aceste discipline. Acest tabel se numeşte virtual. Interogarea principală calculează mediile la matematică şi informatică ale acestor elevi. SELECT AVG(virtual.matematica) AS medie_mate, AVG(virtual.informatica) AS medie_info FROM (SELECT matematica, informatica FROM elevi WHERE matematica>=8 OR informatica>=8) AS virtual; Figura Rezultatul obţinut Gruparea datelor Datele dintr-un tabel pot fi grupate în funcţie de valorile dintr-o anumită coloană. De exemplu, datele din tabelul din Fig pot fi grupate după valorile din coloana data. Astfel, un grup este alcătuit din rândurile de tabel corespunzătoare datei , altul, corespunzătoare datei ,..., altul corespunzător unei date necunoscute (NULL). Prelucrările datelor din fiecare grup se fac cu ajutorul funcţiilor agregate, aşa cum suntem deja obişnuiţi. Pentru a grupa datele din tabel după valorile unei coloane se utilizează clauza GROUP BY nume_coloana, adăugată după numele tabelului. Exemplele care urmează vă vor lămuri! Exemplul Se consideră tabelul vanzari cu structura de mai jos care conţine data vânzării, numele produsului vândut şi valoarea vânzării din produsul respectiv: CREATE TABLE vanzari ( data DATE, produs CHAR(15), valoare INT); Figura Tabelul vanzari Întrebări: 1. Care este numărul de vânzări din fiecare zi? Grupăm datele după dată şi numărăm vânzările pentru fiecare grup.

81 Capitolul 2. Limbajul MySQL 81 SELECT data, COUNT(*) AS numar_vanzari FROM vanzari GROUP BY data; Figura Numărul de vânzări din fiecare zi 2. Care este suma vânzărilor zilnice? Grupăm datele după dată şi însumăm vânzările pentru fiecare dată în parte: SELECT data, SUM(valoare) AS suma_vanzari FROM vanzari GROUP BY data; Figura Suma vânzărilor zilnice 3. Care este numărul de vânzări şi suma vânzărilor în fiecare zi (se va afişa un singur tabel)? SELECT data, COUNT(*) AS nr_vanzari, SUM(valoare) AS suma_incasata FROM vanzari GROUP BY data; Figura Numărul de vânzări şi suma încasată din fiecare zi 4. Care este data în care am am vânzări în valoare maximă, câte vânzări au fost şi care este suma încasată? Ar trebui să obţinem un tabel care să conţină data şi suma vânzărilor zilnice, apoi, din aceasta să selectăm vănzarea maximă şi, apoi, data la care s-a efectuat vânzarea zilnică. În MySQL, în varianta de care dispunem, nu este permisă mai mult de o interogare cu subordonata sa. Din acest motiv, vom crea un tabel de manevră ( manevra ) care conţine data şi suma vânzărilor zilnice (ca la punctul 2). Apoi din acesta, utilizând o interogare cu subinterogare, vom extrage datele cerute. În final, vom şterge tabelul manevra. CREATE TABLE manevra AS SELECT data, SUM(valoare) AS vanzare FROM vanzari GROUP BY data; Pentru probă, afişăm tabelul manevra. SELECT * FROM manevra; Figura Tabelul manevra

82 82 Manual de Informatică pentru clasa a XII-a Pornind de la manevra, obţinem datele cerute. SELECT data, vanzare FROM manevra WHERE vanzare= (SELECT MAX(vanzare) FROM manevra); Ştergem tabelul manevra : DROP TABLE manevra; Figura Rezultatul final Uniuni de tabele Un punct de maximă importanţă şi eficienţă în utilizarea bazelor de date este dat de uniunea de tabele. Uniunea este alcătuită din două sau mai multe tabele între care există o legătură. De cele mai multe ori, legătura este dată de valorile existente în câte o coloană a fiecărui tabel din uniune. Pentru tabelele care alcătuiesc uniunea se pot utiliza alias-uri de nume, sub forma nume_tabel AS alias_nume, introduse în clauza FROM. Alias-urile pot fi utilizate în orice parte a instrucţiunii select. În aceste cazuri, adresarea unei coloane a tabelului se face sub forma: alias_nume.nume_col. Avantajele utilizării alias-urilor sunt: - se pot asigura nume scurte pentru tabele, gen A, B,..., etc. - în cazul auto-uniunilor, caz care este prezentat în actualul paragraf, un singur tabel poate avea alias-uri diferite, fapt care permite anumite interogări speciale ca şi cum am avea mai multe tabele: A, B, etc. În astfel de cazuri, atunci când ne referim la o coloană, pentru a nu se crea confuzie, trebuie precizat tabelul, cum ar fi de exemplu: A.nume_col, B.nume_col, etc. 1) O primă formă de realizare a unei uniuni este utilizarea instrucţiunii SELECT în care la clauza FROM se trec, pe rând, toate tabelele care o alcătuiesc, iar legătura este precizată cu ajutorul clauzei WHERE. Vezi exemplele 2.51, pct. 1.a), 4, 5. 2) Atunci când uniunea este alcătuită din două tabele, se poate preciza o legătură de tip INNER sub forma de mai jos. În astfel de cazuri, se afişează datele din tabel 1 şi din tabel 2, pentru care este îndeplinită condiţia din ON. O astfel de uniune se mai numeşte şi uniune interioară. Vezi exemplul 2.51, pct. 1.b)! nume_tabel 1 [AS...]INNER JOIN nume_tabel 2 [AS...] ON conditia de uniune 3) Atunci când uniunea este alcătuită din două tabele, se poate preciza o legătură de tip LEFT OUTER sub forma de mai jos. În astfel de cazuri, se afişează toate datele din tabel 1, iar datele din tabel 2 se afişează numai dacă este

83 Capitolul 2. Limbajul MySQL 83 îndeplinită condiţia din ON, altfel, în locul lor se afişează valoarea implicită (NULL, de cele mai multe ori). O astfel de uniune se mai numeşte şi uniune exterioară stânga. Vezi exemplul 2.51, pct. 2. nume_tabel 1 [AS...]LEFT JOIN nume_tabel 2 [AS...] ON conditia de uniune 4) Atunci când uniunea este alcătuită din două tabele, se poate preciza o legătură de tip RIGHT OUTER sub forma de mai jos. În astfel de cazuri, se afişează toate datele din tabel 2, iar datele din tabel 1 se afişează numai dacă este îndeplinită condiţia din ON, altfel, în locul lor se afişează valoarea implicită (NULL, de cele mai multe ori). O astfel de uniune se mai numeşte şi uniune exterioară dreapta. Vezi exemplul 2.51, pct. 3. nume_tabel 1 [AS...]LEFT JOIN nume_tabel 2 [AS...] ON conditia de uniune Exemplul Priviţi tabelele de mai jos, numite "produse" (cel din stânga) şi "date_produse" (cel din dreapta). Logic, legătura dintre ele este dată de coloanele "cod", din fiecare tabel. Astfel, pentru un cod dat, din tabelul "produse" se poate extrage cantitatea existentă într-un magazin dintr-un anumit produs şi denumirea produsului, producătorul său din tabelul "date_produse". Figura Cele două tabele propuse ca exemplu 1. Pentru fiecare produs existent în magazin, care este trecut în tabelul "date_produse", să se afişeze denumirea şi cantitatea. Pentru a rezolva această problemă, vom utiliza două forme de interogare şi ambele dau acelaşi rezultat. a) SELECT B.denumire, A.cantitate FROM produse AS A, date_produse AS B WHERE A.cod=B.cod; Figura Rezultatul interogărilor b) SELECT B.denumire, A.cantitate FROM produse AS A INNER JOIN date_produse AS B ON A.cod=B.cod;

84 84 Manual de Informatică pentru clasa a XII-a 2. La fel ca la punctul anterior, numai că se vor trece datele existente pentru toate produsele din tabelul produse : SELECT B.denumire, A.cantitate FROM produse AS A LEFT OUTER JOIN date_produse AS B ON A.cod=B.cod; Figura Rezultat 3. La fel ca mai sus, numai că se vor trece datele existente pentru toate produsele din tabelul date_produse : SELECT B.denumire, A.cantitate FROM produse AS A RIGHT OUTER JOIN date_produse AS B ON A.cod=B.cod; Figura Rezultat 4. O problemă serioasă care apare în cerinţele de acest tip este dată de faptul că nu întotdeauna, orice cod din primul tabel, în exemplu produse, se află printre codurile din al doilea tabel, în exemplu, date_produse. Se cere să afişăm codurile din tabelul produse care nu se regăsesc între codurile din tabelul date_produse. Analizaţi interogarea de mai jos, este şi un exemplu de utilizare a operatorului NOT IN: SELECT cod FROM produse WHERE cod NOT IN (SELECT cod FROM date_produse); Figura Selectaţi codurile de produse din tabelul date_produse care nu se regăsesc printre codurile din tabelul produse 1. SELECT cod FROM date_produse WHERE cod NOT IN (SELECT cod FROM produse); Figura Auto-uniuni. Se pot obţine rezultate interesante dacă cele două tabele sunt, de fapt, unul şi acelaşi, dar au aliasuri diferite şi se consideră unite printr-o coloană. Exemplul În tabelul alăturat, numit st_or (referitor la localităţile din care provin studenţii unei grupe dintr-o facultate), care sunt persoanele care locuiesc în acelaşi oraş cu Ioana? Figura Tabelul st_or 1 În cazul în care considerăm tabelul produse drept tabel tată şi tabelul date_produse drept tabel fiu, pentru a fi respectată integritatea referenţială, ar trebui ca mulţimea acestor coduri să fie vidă.

85 Capitolul 2. Limbajul MySQL 85 Privim acelaşi tabel ca pe două tabele diferite legate prin câmpul oras. Unul dintre tabele are numele A şi al doilea are numele B. Interogarea constă în afişarea tuturor numelor din B care au aceeaşi valoare în câmpul oras cu înregistrarea din A care, pentru câmpul nume, reţine Ioana. SELECT B.nume FROM st_or AS A INNER JOIN st_or AS B ON A.oras=B.oras AND A.nume= Ioana ; Figura Rezultatul interogării Observaţie! Evident, aceeaşi problemă poate fi rezolvată prin utilizarea mecanismului subinterogărilor. Exerciţiu! Elemente care privesc securitatea bazelor de date Asigurarea securităţii bazelor de date este o problemă extrem de serioasă. Paragraful are numai rolul de a vă iniţia în această activitate. În realitate, problema este cu mult mai complexă. Sistemul de privilegii MySQL. O primă problemă care apare este de a securiza, pe cât posibil, bazele de date. Din acest punct de vedere, în afara administratorului, există posibilitatea ca la bazele de date să aibă acces şi alte persoane, identificabile prin nume şi parole. Totuşi, aceste persoane au acces numai la anumite operaţii cu bazele de date. Pentru ca o astfel de persoană (care nu este utilizator) să acceseze baza de date este necesar ca administratorul să introducă numele ei, parola şi operaţiile pe care le poate efectua. Astfel, administratorul va utiliza instrucţiunea MySQL numită GRANT, a cărei formă simplificată o prezentăm mai jos: GRANT operaţii ON nume_bază TO nume_utilizator IDENTIFIED BY parola ; Operaţiile permise sunt: SELECT, UPDATE, INSERT, INDEX, ALTER, CREATE, DROP şi trebuie să fie separate prin virgule. Atunci când accesul utilizatorului este permis pentru orice bază de date, se utilizează *.*. Exemplul De acum, utilizatorul lavinia cu parola puful are acces la operaţii de tip SELECT şi INSERT pentru orice bază de date. GRANT SELECT, INSERT ON *.* TO lavinia IDENTIFIED BY puful

86 86 Manual de Informatică pentru clasa a XII-a Pentru a revoca unele drepturi ale unui utilizator sau chiar toate, administratorul foloseşte instrucţiunea REVOKE. Pentru a revoca toate operaţiile permise, se utilizează ALL. REVOKE operaţii ON nume_bază FROM nume_utilizator Exerciţiu. Acordaţi drepturi unor utilizatori, verificaţi dacă le au, revocaţi anumite drepturi şi verificaţi apoi dacă le mai au. 1. Materiale. O firmă dispune de mai multe depozite. În fiecare depozit există mai multe materiale. Pentru fiecare material se cunoaşte preţul şi cantitatea. Se cere să se răspundă la întrebările de mai jos. Tabelul se numeşte materiale. Figura Tabelul materiale 1.1. Care sunt materialele existente într-un anumit depozit (în exemplu, Depozit 2 )? 1.2. Care sunt depozitele în care există un anumit material (în exemplu, material 3? Se presupune că numele materialului poate fi precedat de blank-uri Care este valoarea totală a tuturor materialelor din depozite? 1.4. Care este valoarea totală a materialelor din fiecare depozit? 1.5. Presupunem că material 1 se scumpeşte cu 10%. Actualizaţi datele din tabel Să se şteargă un anumit material ( material 2 ) din tabel. 2. Împrumuturi. Există persoane care au credite, în acelaşi timp, la mai multe bănci. O astfel de situaţie este prezentată în tabelul de mai jos, numit imprumuturi. Se cere să se răspundă la următoarele întrebări:

87 Capitolul 2. Limbajul MySQL 87 Figura Tabelul imprumuturi 2.1. Care sunt persoanele care au împrumutat de la Banca 1? 2.2. Care este suma împrumutată de fiecare bancă populaţiei? 2.3. Afişaţi, pentru fiecare persoană, numărul împrumuturilor pe care le-a efectuat Care sunt persoanele care au împrumutat o sumă maximă şi care este această sumă? 2.5. Care sunt persoanele care au împrumutat bani cel puţin de la o bancă la care a împrumutat şi Ionescu Grigore? 3. Proprietari, proprietăţi. Se dă un tabel ( proprietari ), în care pentru fiecare persoană se cunoaşte codul (cod) şi numele (nume). Se dă şi un alt tabel ( proprietati ) în care se cunoaşte codul proprietarului (cod_proprietar), tipul proprietăţii (tip_p) şi valoarea proprietăţii (valoare): Figura Tabelul proprietari Figura Tabelul proprietati 3.1. Afişaţi, pentru fiecare proprietar care are cel puţin o proprietate, numărul proprietăţilor Afişaţi numele proprietarilor care nu au proprietăţi Afişaţi codurile proprietarilor din tabelul proprietati care nu au corespondent în tabelul proprietari Afişaţi valoarea proprietăţilor pe care le are fiecare proprietar. Datele vor fi afişate în ordinea descrescătoare a proprietăţilor. 4. Prietenii. Se dau două tabele ( baieti şi fete ) în care pentru fiecare persoană se cunoaşte codul (cod), numele (nume) şi vârsta (varsta). De asemenea, mai există un tabel, numit prietenii, în care sunt reţinute relaţiile dintre băieţi şi fete.

88 88 Manual de Informatică pentru clasa a XII-a Figura Tabelul baieti 4.1 Care sunt prietenele lui Mihai, cel care are 18 ani? Observaţie! Se presupune că există un singur băiat Mihai care are 18 ani. 4.2 Afişaţi numele fetelor care nu au prieten. 4.3 Pentru fiecare băiat care are cel puţin o prietenă, afişaţi numele prietenelor pe care acesta le are. 4.4 Afişaţi numele unei fete cu un număr maxim de prieteni şi numărul prietenilor ei. 4.5 Afişaţi media de vârstă a băieţilor şi a fetelor. Figura Tabelul prietenii Figura Tabelul fete 5. Angajaţi. O firmă doreşte să reţină într-o bază de date un tabel referitor la angajaţi. Motivul este dat de faptul că se vrea obţinerea rapidă a răspunsurilor la întrebările de mai jos. Ce date va reţine tabelul? Cum obţinem răspunsul la întrebări? 5.1 Care sunt numele angajaţilor (în ordine alfabetică)? 5.2 Care sunt angajaţii cu vârsta sub 30 de ani? 5.3 Realizaţi o listă a femeilor angajate şi o alta a bărbaţilor angajaţi. 5.4 Realizaţi o listă a angajaţilor care au studii superioare. 5.5 Care sunt angajatele care sunt în concediu de maternitate? 5.6 Care sunt angajaţii cu o vechime în meseria pe care o practică la firmă de sub trei ani? 5.7 Care sunt angajaţii care au salariul minim pe economie? 5.8 Care sunt angajaţii care au salariul brut mai mare decât cel minim, dar mai mic decât 1000 de lei? 5.9 Care sunt angajaţii care ies la pensie anul următor? 5.10 Care sunt angajaţii care au copii şi câţi copii au? 5.11 Mâine este Sfânta Maria. Care este lista sărbatoritelor? 5.12 Găsiţi angajaţii care îşi sărbătoresc mâine ziua de naştere! 6. Cheltuieli / Venituri. George este o persoană căreia îi place să-şi ţină evidenţa veniturilor şi cheltuielilor. El are un tabel cu următoarele câmpuri: Data, Cheltuiala/Venit, Suma cheltuită sau încasată, Explicaţii (Text). Să presupunem că George şi-a completat tabelul câteva luni, în fiecare zi. Fiecare sumă cheltuită sau încasată este înregistrată pe o linie a tabelului. Se cere: 6.1 Care sunt veniturile totale ale lui George şi care sunt cheltuielile sale pe toată perioada cât a ţinut evidenţa?

89 Capitolul 2. Limbajul MySQL A reuşit George să economisească o sumă de bani în această perioadă sau a fost nevoit să se împrumute? Care este suma economisită sau împrumutată? 6.3 În care lună George a cheltuit cea mai mare sumă? 6.4 În care lună George a avut cele mai mari încasări? 6.5 Care este luna în care George a economisit cea mai mare sumă? 6.6 Creaţi un tabel care să conţină toate veniturile lui George pe întreaga perioadă şi un altul care să conţină toate cheltuieliule în aceeaşi perioadă. 6.7 Creaţi un tabel care să conţină, pentru fiecare lună în parte, suma încasărilor şi suma cheltuielilor. 7. Biblioteca. Ioana s-a angajat la o bibliotecă şi doreşte să ţină evidenţa cărţilor pe calculator. 7.1 Ioana doreşte, în primul rând, să ţină evidenţa titlurilor pe care le are la bibliotecă. Pentru aceasta, Ioana codifică toate titlurile şi reţine pentru fiecare titlul, editura şi autorul. 7.2 Pentru a ţine evidenţa numărului de exemplare din fiecare titlu, existente în gestiune, este nevoie de un alt tabel, numit Nr Exemplare. Creaţi-l!. 7.3 Care este legătura între cele două tabele? 7.4 În continuare, trebuie creat un tabel, numit Cititori, care conţine persoanele care împrumută cărţi de la bibliotecă (Nume, Adresa, Nr. telefon) Înainte de a împrumuta o carte, cititorul este înscris în acest tabel. Creaţi-l!. 7.5 De asemenea, trebuie creat un tabel (Imprumuturi) în care, pentru fiecare carte împrumutată, este scrisă o înregistrare care conţine numele cititorului şi codul cărţii (o înregistrare conţine un singur exemplar dintr-un titlu). Creaţi-l! 7.6 Se cere o situaţie în care sunt afişaţi cititorii care au împrumutat o carte de mai mult de două săptămâni. 7.7 Câte exemplare sunt împrumutate din fiecare carte? 7.8 Câte exemplare sunt împrumutate din cartea care are codul x? 7.9 Pentru fiecare carte împrumutată, se cere codul cărţii, tilul şi numărul exemplarelor aflate la cititori Un cititor solicită un anumit titlu. Ioana vrea să vadă dacă există exemplare neîmprumutate din acesta. 8. Problemă pentru lucrul în colectiv! Grilă. Scrieţi o grilă cu 18 itemi (18 întrebări la care răspunsul corect este unul singur, ales dintre 4 răspunsuri). În final se va afişa nota obţinută de cel care este testat prin utilizarea acestei grile. Fiecare răspuns corect este punctat cu 0.5 puncte şi un punct se acordă din oficiu. Desigur, dacă este necesar, itemii vor fi însoţiţi de imagini. Problema va fi rezolvată de echipe diferite, pe diverse domenii: informatică, matematică, biologie, limbi străine, chimie, istorie, ş.a.m.d. Un set de astfel de probleme va fi util elevilor din toată ţara! 9. Problemă pentru lucrul în colectiv! Magazin. Creaţi un site prin care o firmă vinde calculatoare şi diverese componente de calculatoare. Comenzile se pot face prin intermediul site-ului şi ele sunt stocate în baza de date. Se cere să se efectueze validarea datelor de intrare. De asemenea, reprezentanţii firmelor pot extrage din baza de date comenzile dintr-o anumită zi şi pot memora date referitoare la expedierea produselor. (pentru verificare, rezolvările se găsesc la pag. 381)

90 CAPITOLUL Primii paşi către construcţia unui site În acest capitol recapitulăm noţiunile referitoare la Internet care au fost studiate la Tehnologia Informaţiei şi a Comunicaţiilor. De asemenea, vom învăţa să instalăm şi să utilizăm un program FTP prin intermediul căruia vom putea transfera fişiere între calculatorul personal şi server. Ce este Internet-ul? Protocolul TCP / IP Ce trebuie să ştim despre site-uri? Un program FTP Cum scriem un fişier HTML? Cuvinte cheie: pagină web, site web, host, ISP, protocol, TCP/IP, DNS, URL, FTP, SMTP, client, server, proxy, HTML, browser

91 Capitolul 3. Primi paşi către construcţia unui site Ce este Internet-ul? Prin Internet înţelegem totalitatea calculatoarelor, aflate oriunde în lume, care comunică între ele. Spunem că două calculatoare comunică dacă între ele are loc un schimb de date. Convenim să numim host (în română, gazdă) un calculator care participă la schimbul de date. Reţeaua Internet conţine calculatoare de mare viteză, care comunică prin fibră optică şi/sau prin satelit şi au rolul de a transmite rapid informaţia, oriunde în lume. Anumite firme, numite ISP (Internet Service Provider, pe scurt provider ), dispun de calculatoare performante, numite server -e, legate la unul dintre calculatoarele cu rol de transmitere a informaţiei. Provider-ul oferă, contra cost sau din alte raţiuni, diverşilor clienţi posibilitatea cuplării propriilor PC-uri la server, adică accesul la Internet. Provider-ul oferă şi alte servicii, cum ar fi webhosting -ul (spaţiu pe hard-disc pentru găzduirea paginilor web, conturi pentru , precum şi soft specializat pentru manipularea acestora). Pentru a accesa Internet-ul de la un oarecare calculator, acesta trebuie să fie conectat la server-ul unui provider. Există mai multe variante de conectare. Precizăm faptul că modalităţile de conectare sunt prezentate în ordinea crescătoare a vitezei de transmisie a datelor. Nu vom prezenta vitezele de transmisie, deoarece acestea sunt într-o continuă creştere, mărginindu-ne numai la a preciza faptul că rata (viteza) de transfer ( Transfer Rate ) a datelor se exprimă în Mbps (mega biţi pe secundă). Principalele tipuri de conexiuni la Internet 1) Conectare prin intermediul cablului telefonic. Practic, calculatorul se conectează temporar la un server, prin intermediul unui dispozitiv numit modem. Prin formarea unui număr de telefon de acces, se obţine conexiunea cu acesta. Cât timp calculatorul este conectat, nu se mai poate utiliza telefonul. 2) Conectare prin ISDN ( Integrated Services Digital Network ) este un serviciu pus la dispoziţie de firma de telefonie fixă. Şi aici, conexiunea este temporară, deci se plăteşte în funcţie de timpul în care suntem conectaţi. Faţă de modalitatea anterioară, în afara vitezei mai mari pentru schimbul de date, aceasta prezintă avantajul că se poate utiliza în acelaşi timp şi telefonul. 3) Conectare prin intermediul liniilor telefonice închiriate. În acest caz, conexiunea este permanentă. Practic, utilizatorul face un contract cu furnizorul de telefonie fixă, care montează o linie telefonică între calculatoarele utilizatorului şi server-ul provider-ului. 4) Conectare prin cablu TV (coaxial). Conectarea permite transmisia datelor şi recepţia programelor TV în acelaşi timp.

92 92 Manual de Informatică pentru clasa a XII-a 5) Conectare prin fibră optică. Mediul fizic prin care sunt transferate datele este fibra optică, obţinând o rată de transfer mult mai ridicată decât cele anterioare. 6) Conectare prin cablu UTP (Unshielded Twisted Pair) - una dintre cele mai frecvente conexiuni la Internet. Principiul de bază este simplu: mai multe PC-uri se interconectează prin intermediul unui hub/switch, formând o reţea locală. Această reţea de calculatoare se conectează, la rândul ei, printr-o conexiune rapidă (de exemplu, prin fibră optică), cu provider-ul de Internet. 7) Conectare prin unde electro-magnetice terestre sau prin satelit. Aceste tehnologii sunt numite wireless (fără fir). În acest caz, echipamentele sunt mult mai costisitoare şi necesită operaţii complexe de instalare. În linii mari, putem considera că Internet-ul oferă următoarele servicii: World Wide Web (www) - putem crea şi vizita diverse pagini web; - serviciu de poştă electronică; Chat - modalitate prin care doi sau mai mulţi utilizatori pot discuta în acelaşi timp. Bineînţeles, acestea trei sunt doar baza de la care pornesc o multitudine de alte servicii, cum ar fi: e-commerce (comerţ pe Internet), e-banking (management financiar, plăţi on-line), diverse tipuri de liste de discuţii (forum, newsgroup), etc Protocolul TCP/IP Pentru ca două sau mai multe calculatoare să poată comunica este necesar să existe un protocol, adică un ansamblu de norme care trebuie respectate de calculatoare (de programale care rulează pe ele) pentru ca schimbul de date să aibă loc. Normele se referă la: găsirea calculatorului destinatar al transferului de date; transmiterea efectivă a datelor; modalităţi prin care expeditorul comunică faptul că au fost transmise toate datele, iar destinatarul că le-a recepţionat; compresia datelor - prin aplicarea anumitor algoritmi matematici, datele care urmează să fie expediate sunt prelucrate, de aşa natură, încât să fie memorate prin utilizarea unui spaţiu mai mic de memorie. Prin urmare, transmiterea lor durează mai puţin. Invers, la destinaţie sunt decompresate prin utilizarea aceloraşi algoritmi matematici.

93 Capitolul 3. Primi paşi către construcţia unui site 93 identificarea erorilor care pot interveni în transmiterea datelor. Problema este următoarea: de unde ştie calculatorul care a recepţionat date dacă acestea sunt corecte? Şi aici există mai mulţi algoritmi care permit identificarea şi corectarea erorilor. Pe Internet se foloseşte protocolul TCP/IP (Transmission Control Protocol/Internet Protocol). Protocolul este, de fapt, numele comun al unei familii de protocoale utilizate pentru transferul datelor în reţea. În continuare vom prezenta pe scurt câteva dintre protocoalele din familia TCP/IP. Orice calculator conectat la Internet are o adresă, numită adresă IP (Internet Protocol Adress). O adresă IP este alcătuită din 4 numere între 0 şi 255. Prin urmare, o astfel de adresă ocupă 4 octeţi. Cum transmisia datelor se face între două calculatoare, datele se transmit de la o adresă IP la alta. Protocolul IP (Internet Protocol) reglementează transmiterea datelelor de la o adresă IP la alta. Datele sunt transmise divizate în pachete (packets). Fiecare pachet conţine IP-ul expeditorului şi IP-ul destinatarului. Prin protocolul TCP (Transmission Control Protocol) se verifică corectitudinea transmisiei. În Internet se pot accesa anumite resurse, fişiere de orice tip (html, imagine, date, etc). Orice resursă are, aşa cum ştim, o anumită adresă, numită adresa URL (Uniform Resource Locator). De exemplu, dacă adresa unui site este ea este o adresă URL. De fapt, este adresa fişierului index, care are adresa completă în cazul în care fişierul index are extensia html. De asemenea, un fişier imagine, să spunem iepure.jpg, aflat în folder-ul img al site-ului din exemplu, are adresa URL: DNS (Domain Name System) asigură legătura dintre adresa URL a unui site şi adresa IP a acestuia. Practic, în edit-ul browser-ului se tastează adresa URL, acesta o transmite, dar prin algoritmul impus de acest protocol se găseşte adresa IP asociată. Transferul datelor se efectuează, aşa cum s-a arătat, utilizând adresa IP găsită. FTP (File Transfer Protocol) are rolul de a reglementa transferul fişierelor între două calculatoare. Există programe specializate care, prin utilizarea acestui protocol, transferă fişiere. De regulă, utilizarea lor se face în situaţia în care o persoană gestionează un site web aflat pe un alt calculator (server). Atunci când aceasta actualizează site-ul, transferă fişiere către server.

94 94 Manual de Informatică pentru clasa a XII-a SMTP (Simple Mail Transfer Protocol) are rolul de a reglementa transferul -urilor. Din cele prezentate până în acest moment, rezultă că fiecare calculator care participă la schimbul de date pe Internet are o adresă IP permanentă. În realitate nu este chiar aşa Unele calculatoare au într-adevăr o adresă IP permanentă, însă altele nu. Să prezentăm două cazuri: 1) Ne conectăm de la PC-ul de acasă, prin linie telefonică, la Internet. În acest caz, calculatorul nostru se numeşte client, iar cel al provider-ului server. Provider-ul dispune de o mulţime de adrese IP care urmează să fie alocate. Calculatorului nostru i se alocă, automat, o adresă IP care este disponibilă în acel moment. Un astfel de server rulează un soft special, care utilizează protocolul DHCP (Dynamic Host Configuration Protocol). După închiderea conexiunii, acea adresă IP se va putea aloca altui client. 2) Dispunem de o reţea de calculatoare şi dorim ca de pe fiecare calculator din reţea să putem accesa Internet-ul. În acest caz, se obişnuieşte ca un calculator al reţelei, numit server proxy, să fie cuplat la Internet printr-o linie închiriată (aceasta asigură o viteză de transfer suficient de mare). Toate celelalte calculatoare ale reţelei accesează Internet-ul prin intermediul său. Evident, pe server-ul proxy trebuie să existe un soft specializat. Toate calculatoarele din reţea au şi ele adrese IP, dar interne, nerecunoscute decât în reţeaua locală, nu şi pe Internet, dar server-ul proxy utilizează o adresă IP recunoscută pe Internet Despre site-uri Dacă o persoană (sau societate comercială), care are acces la Internet, doreşte să aibă un site, va apela la serviciile unei firme specializate (numită provider ). Provider-ul dispune (sau a închiriat la rândul lui) de unul sau mai multe calculatoare extrem de performante, cuplate la Internet prin linii care permit transferul rapid al datelor şi care rulează programe specializate, numite server -e şi pune la dispoziţie: spaţiu pe hard-disc-ul server-ului de cel puţin 10Mb; o adresă de Internet (de exemplu, 1 ). În spaţiul rezervat, persoana (firma) pune mai multe fişiere care conţin, de regulă, fişiere HTML (Hyper Text Markup Language), dar şi alte fişiere (gif, jpeg, doc). Prin aceste fişiere se poate descrie activitatea firmei, se poate face comerţ electronic, se poate prezenta o anumită temă, etc). 1 Aveţi posibilitatea ca site-ul să aibă asociată o adresa URL oferită gratuit de provider sau să cumpăraţi o astfel de adresă.

95 Capitolul 3. Primi paşi către construcţia unui site 95 Pentru a putea vizita o pagină, este necesar un program specializat, numit generic browser. Acesta trebuie să se găsească pe calculatorul celui care doreşte să viziteze pagina respectivă şi, în linii mari, are funcţiile: 1. permite utilizatorului să introducă adresa URL a paginii respective şi transmite cererea către server, pentru ca acesta să-i furnizeze fişierul HTML care conţine codul respectivei pagini, dar şi fişierele care reţin imaginile din pagină (cu extensia jpeg, gif, etc). 2. după ce primeşte codul HTML al paginii respective, interpretează comenzile pe care le conţine şi îl afişează. Evident, conţinutul site-ului poate fi accesat de pe orice alt calculator conectat la Internet. Terminologie. Calculatorul pe care se găseşte site-ul se numeşte, aşa cum am precizat, server, iar calculatoarele care accesează conţinutul site-ului se numesc, în acest caz, client. Un astfel de model de transmisie a datelor poartă denumirea de client-server (vezi Fig. 3.1). Server Cerere Răspuns Cerere Răspuns Cerere Răspuns Client 1 Client 3 Client 2 Figura 3.1. Exemplu de model de tip client-server Întrebările fireşti în acest moment sunt este: ce software este necesar să existe pe calculatorul client şi ce software trebuie să existe pe server?

96 96 Manual de Informatică pentru clasa a XII-a Software-ul necesar pentru calculatorul client Orice calculator client trebuie să dispună de un browser, cu ajutorul căruia să se poată vizualiza fişierele HTML. Există mai multe programe de tip browser, cum ar fi: Internet Explorer, Firefox, Mozilla, Opera, Netscape, fiecare dintre acestea având mai multe versiuni. Din păcate, între acestea există anumite diferenţe atunci când afişează fişierele HTML. Evident, există multe puncte comune. Este recomandabil, ca atunci când scriem codul necesar unei pagini web, să utilizăm specificaţiile de HTML standard şi, mai ales, să testăm pagina utilizând cât mai multe tipuri de browser-e. Pentru a gestiona un site web, aflat evident pe server, utilizatorul are nevoie de un program FTP prin care să poată efectua mai multe operaţii asupra spaţiului rezervat pe server: transfer sau ştergere de fişiere şi creare, modificare sau ştergere de folder-e Software-ul necesar pentru calculatorul server În primul rând, pe server trebuie să se găsească un program care răspunde cererilor browser-rui aflat, aşa cum s-a spus, pe calculatorul client. Un astfel de program se numeşte program de tip server. Atunci când, de exemplu, dorim să vizualizăm o anumită pagină, tastăm adresa URL în edit-ul browser-ului şi apăsăm tasta Enter sau efectuăm clic pe butonul GO. Browser-ul emite o cerere către server pentru ca acesta să-i trimită fişierul respectv. Evident, dacă este posibil, server-ul va furniza browser-ului fişierul solicitat. Cererea efectuată de browser şi răspunsul server-ului se fac prin respectarea unui anumit protocol. Acest proticol se numeşte HTTP (Hyper Text Transfer Protocol). Prin urmare, un program de tip server răspunde cererilor care se conformează protocolului HTTP. Există mai multe programe de tip server, cel mai popular fiind Apache, care lucrează pe server-e cu sistemul de operare Linux, dar şi pentru cele cu sistemul de operare Windows. El este dezvoltat de Apache Software Foundation şi este de tip open source 1. Un alt program de tip server este Microsoft IIS (Microsoft Internet Information Services), destinat sistemelor de operare de tip Windows. Facultativ, pe server se găsesc programele PHP şi MySQL. Bineînţeles, închirierea unui spaţiu pe un server care deţine aceste programe este mai scumpă. PHP-ul permite ca paginile web sa fie personalizate, iar cu ajutorul MySQL-ului se pot crea baze de date pe Internet. De asemenea, cu ajutorul PHP-ului se pot da comenzi MySQL-ului pentru crearea şi actualizarea bazelor de date. 1 Termenul descrie accesul gratuit la codul sursă al unui produs software, care este disponibil spre a fi copiat, modificat şi personalizat de către oricine, fără a fi impuse drepturi intelectuale restrictive asupra programului.

97 Capitolul 3. Primi paşi către construcţia unui site 97 Observaţie. Puteţi să obţineţi gratuit spaţiu pe server şi adresa URL pentru site-ul dvs., pentru că există firme care oferă aceasta utilizatorilor. Căutaţi cu Google! Din păcate, este puţin probabil să găsiţi gratuit un server care are PHP şi MySQL. Oricum, chiar şi în aceste condiţii, se pot crea site-uri reuşite utilizând doar limbajul HTML. Dacă doriţi un site care să conţină PHP şi MySQL, limbaje care vor fi prezentate în această carte, atunci trebuie să plătiţi acest serviciu suplimentar. Modalitatea de instalare a programelor Apache, PHP şi MySQL este detaliată în Anexa 1, care se găseşte la pag Un program care lucrează sub FTP Să presupunem că am obţinut un anumit spaţiu pe un server, avem o adresă URL pentru site şi acum vrem să-l construim şi să-l putem întreţine. Problema care se pune în continuare este transferul fişierelor de pe calculatorul personal (client) către server şi invers. În această carte vom utiliza un program care lucrează sub protocolul FTP şi anume WS_FTP95. Acest program poate fi descărcat de pe pagina web iar dacă această adresă nu mai este actuală, identificaţi o nouă locaţie de unde poate fi download-at (cu Google, textul ws_ftp95 download ). După ce aţi instalat programul, va apărea o cutie de dialog în care trebuie să introduceţi datele de identificare. Am presupus că adresa URL a site-ului este: (vezi Fig. 3.2). Figura 3.2. Fereastra de introducere a datelor de identificare Dacă introducerea datelor de identificare s-a făcut în mod corect, automat programul va afişa conţinutul fişierelor din site în cadrul din partea dreaptă şi a unui folder de pe propriul calculator în stânga. De aici şi modalitatea de lucru: vom avea pe hard-disc un folder care reţine fişierele care trebuie să fie transferate pe site. Acesta este folder-ul (în exemplu, PTest ) care este afişat de programul FTP (vezi Fig. 3.3). Pe server avem două fişiere, iar cel care ne interesează iniţial este index.html.

98 98 Manual de Informatică pentru clasa a XII-a Trecerea unui fişier de pe propriul calculator pe site se face prin operaţia Drag and Drop (se mută cursorul grafic asupra sa, apăsăm butonul stâng şi-l tragem către panoul din dreapta) sau selectăm fişierul şi-l transferăm cu ajutorul butonului săgeată. Analog, se poate muta un fişier de pe site pe calculatorul nostru. Figura 3.3. Fereastra programului WS_FTP95 Ştergerea unui fişier sau folder se face cu butonul Delete. Crearea unui folder (director) se face prin apăsarea butonului MkDir. Apăsarea săgeţii are ca efect trecerea în folder-ul părinte. Schimbarea unităţii de disc pe propriul calculator se face prin executarea unui clic asupra numelui ei (vezi fig. alăturată). Figura 3.4. Lista unităţilor de disc de pe calculatorul client După cum observaţi, este foarte simplu să lucrăm cu un program FTP. Pentru transfer, bifaţi butonul ASCII. Veţi fi scutiţi astfel de anumite erori care pot apărea la executare.

99 Capitolul 3. Primi paşi către construcţia unui site Cum scriem un fişier HTML? Presupunem că avem un site web şi putem să transferăm fişiere de la calculatorul nostru către el şi invers. Ştim că, pentru a scrie o pagină web, trebuie să cunoaştem limbajul HTML (HyperText Markup Language). Acesta este prezentat detaliat în Capitolul 4. Întrebarea la care răspundem în acest moment este următoarea: cum se scrie codul HTML? Browser-ul poate afişa un fişier HTML aflat pe calculatorul nostru. Un astfel de fişier are una dintre extensiile: htm sau html. Puteţi căuta cu Find un astfel de fişier şi executaţi dublu clic pe icon-ul său. Imediat va fi apelat browser-ul, iar acesta va afişa fişierul. Mai ştim că, atunci când browser-ul afişează un astfel de fişier, putem vedea codul său sursă (din meniul View, apelăm comanda Source). Automat, se va lansa programul NOTEPAD care realizează aceasta. De aici rezultă şi modul în care vom scrie astfel de fişiere: a) Vizualizăm cu My Computer folder-ul unde dorim să se găsească fişierul. b) Apelăm la meniul flotant (clic cu butonul drept al mouse-ului) şi alegem New şi Text Document. Programul NOTEPAD va crea un fişier fără conţinut, cu extensia txt. c) Modificăm numele şi extensia fişierului. La fel, atunci când cursorul grafic se găseşte deasupra icon-ului său, apăsăm butonul drept al mouse-ului şi alegem Rename. Vom scrie un nume dorit de noi, iar extensia va fi html. Fie numele său primul.html. Întrucât extensia html este asociată browser-ului (Internet Explorer, la noi), fişierul va avea de această dată icon-ul browser-ului (vezi Fig. 3.4). Figura 3.4. Exemplu de fişier HTML d) Executarea unui dublu clic asupra icon-ului are ca efect lansarea browser-ului care va afişa fişierul. Evident, în această fază, conţinutul său este vid. e) Apelaţi din meniu View şi Source. Programul NOTEPAD va încărca codul HTML al fişierului (conţinutul este vid), deschizând-ul astfel pentru editare.

100 100 Manual de Informatică pentru clasa a XII-a f) Scrieţi un text la alegerea dvs. Exemplu: Acesta este primul text. Salvaţi-l! g) În fereastra browser-ului apăsaţi butonul Refresh. Prin această operaţie am comandat reîncărcarea fişierului, întrucât i-am schimbat conţinutul. Textul va fi afişat de browser: Observaţii Figura 3.5. Vizualizarea fişierului prin browser Procedând astfel, putem scrie uşor cod HTML. Din când în când, vizualizăm efectul modificărilor şi identificăm eventualele erori. După cum vă puteţi da seama, operaţia de scriere a codului nu presupune accesul la Internet. Validatoare HTML Am văzut cum se scrie, în mod clasic, codul HTML. Dacă dorim, în scrierea codului se pot utiliza diverse validatoare (programe specializate) HTML. Care este rostul lor? Validatoarele HTML lucrează la fel de uşor ca NOTEPAD-ul. Ele scriu direct fişiere cu una din extensiile htm sau html. Apăsarea unui buton al validatorului are ca efect lansarea browser-ului care afişează fişierul (procedând astfel, lucrăm mai eficient). Putem valida fişierele HTML (adică verificăm corectitudinea din punct de vedere sintactic - la identificarea unei erori, ne este indicată locaţia sa).

101 Capitolul 3. Primi paşi către construcţia unui site 101 De ce este utilă operaţia de validare a fişierelor HTML? Trebuie urmărit modul în care procedează browser-ul atunci când codul HTML nu este corect. Browser-ul va afişa ceea ce distinge din cod, deci nu va semnala eroarea. Uneori, o eroare poate trece neobservată deoarece browser-ul de care dispunem trece peste ea. Dar, cum nu există un singur program de tip browser, un alt tip ar putea afişa informaţia incorect. Un exemplu de astfel de validator, gratuit, este CSE HTML Validator Lite, care poate fi descărcat de pe pagina: Nimeni nu vă opreşte să căutaţi şi alte validatoare HTML. Folosiţi motorul de căutare GOOGLE! Comentarii în documentul HTML Un document HTML poate conţine comentarii. Un comentariu arată ca mai jos şi poate fi aşezat oriunde în document. Evident, comentariile nu sunt afişate de către browser. <!-- Un comentariu --> <!-- Un comentariu pe mai multe linii --> În cazul unor pagini complexe, cu multe elemente, comentariile sunt extrem de utile pentru realizatorul site-ului. Indicând printr-un comentariu o anumită porţiune din fişier, el va şti mult mai uşor locaţia codului respectiv pentru a efectua modificarea. Prin Internet înţelegem totalitatea calculatoarelor, aflate oriunde în lume, care comunică între ele. Pentru a comunica ele pot fi conectate printr-una dintre formele de mai jos: cablul telefonic; ISDN (Integrated Services Digital Network); linii telefonice închiriate; cablu TV (coaxial); cablu UTP (Unshielded Twisted Pair); fibră optică; unde electro-magnetice terestre sau prin satelit.

102 102 Manual de Informatică pentru clasa a XII-a Pentru ca două sau mai multe calculatoare să poată comunica este necesar să existe un protocol, adică un ansamblu de norme care trebuie respectate de către calculatoare (de programale care rulează pe ele) pentru ca schimbul de date să aibă loc. Protocolul TCP/IP (Transmission Control Protocol/Internet Protocol) este numele comun al unei familii de protocoale utilizate pentru transferul datelor în reţeaua Internet. Dintre acestea, cele mai importante sunt: Orice calculator conectat la Internet are o adresă, numită IP, alcătuită din 4 numere între 0 şi 255. Protocolul IP (Internet Protocol) este răspunzător de transmiterea datelor de la o adresă IP la alta. Datele sunt transmise divizate în pachete (packets). Fiecare pachet conţine IP-ul expeditorului şi IP-ul destinatarului. Prin protocolul TCP (Transmission Control Protocol) se verifică corectitudinea transmisiei. DNS (Domain Name System) asigură legătura dintre adresa URL a unui site şi adresa IP a acestuia. FTP (File Transfer Protocol) are rolul de a reglementa transferul fişierelor între două calculatoare. SMTP (Simple Mail Transfer Protocol) are rolul de a reglementa transferul -urilor. În cazul site-urilor web folosim următoarea terminologie: calculatorul pe care se găseşte site-ul se numeşte server, iar calculatoarele care accesează conţinutul site-ului se numesc clienţi. Acest model de transmisie a datelor se numeşte client-server. 1. Pe calculatorul client trebuie să avem instalat un browser, program cu ajutorul căruia să putem vizualiza fişiere HTML. Există mai multe programe de tip browser, cum ar fi: Internet Explorer, Firefox, Mozilla, Opera sau Netscape. În cazul în care o persoană gestionează un site, aflat evident, pe sever, atunci aceasta trebuie să dispună pe calculatorul său de un program FTP prin care să transfere fişiere pe server, şă steargă fişiere aflate pe acesta, să creeze şi să şteargă folder-e de pe server. În această carte folosim programul ws_ftp Pe server trebuie să avem instalat un program specializat care să răspundă cererilor browser-rului. Un astfel de program se numeşte program de tip server. Cel mai des utilizat este Apache. Conversaţia între browser şi programul de tip server respectă protocolul HTTP (Hyper Text Transfer Protocol). De asemenea, pentru a studia materia din această carte trebuie să avem instalate PHP şi MySQL. Toate acestea se găsesc în pachetul EasyPHP care trebuie descărcat şi instalat pe calculatorul nostru. Fişierele HTML pot fi scrise cu ajutorul programului NOTEPAD, dar se pot folosi şi validatoare HTML. Acestea din urmă pot fi descărcate de pe Internet.

103 Capitolul 3. Primi paşi către construcţia unui site Stabiliţi legăturile logice dintre protocoale (stânga) şi ce reglementează ele (dreapta): 1. DNS a) transfer de fişiere 2. HTTP b) controlul transmisiei 3. TCP c) legătura dintre URL şi IP 4. FTP d) dialogul între client şi server 2. Stabiliţi legătura dintre coloanele din stânga şi cele din dreapta: 1. server a) program FTP 2. client b) Apache 3. Stabiliţi legătura dintre coloanele din stânga şi cele din dreapta: 1. server a) MySQL 2. client b) browser 4. Vizualizaţi codul HTML al unei pagini web aleasă de dvs. Multe puteţi învăţa privind modul în care au făcut alţii Creaţi-vă un site gratuit. Reţineţi adresa, numele de autentificare (user ID) şi parola. Acest site îl veţi utiliza pentru teste. 6. Creaţi un fişier pe hard-disc-ul dvs. un director numit PTest. Folder-ul va conţine un fişier numit index.html, iar în interiorul fişierului, textul: Asteptati sa invat in capitolul urmator HTML. 7. Upload-aţi fişierul pe site (adică treceţi fişierul de pe calculatorul dvs. pe server). Verificaţi operaţia prin afişarea fişierului de către browser. 8. Creaţi pe site-ul dvs. două folder-e: Images şi Personal. În viitor, primul va reţine fişierele imagine, iar al doilea, fişierele HTML auxiliare. 9. Lucrare de tip referat. Întocmiţi un referat despre un validator HTML. 10. Lucrare de tip referat. Întocmiţi un referat despre un program FTP. (pentru verificare, rezolvările exerciţiilor 1-3 se găsesc la pag. 383)

104 CAPITOLUL HTML, CSS primele noţiuni În acest capitol vom învăţa să creăm pagini Web utilizând limbajele HTML şi CSS, esenţiale în dezvoltarea oricărei aplicaţii hipermedia. Care este structura de bază a unei pagini HTML+CSS? Elemente HTML pentru afişarea textelor Atribute CSS pentru font-uri şi texte Cum realizăm o listă? Care este structura unui element HTML? Atribute de culoare şi fond Atribute pentru margini, padding şi bordură Cum introducem o imagine? Dar un tabel? Hiperlegături (link-uri) Hărţi imagine Ce rol au elementele BASE, META, SCRIPT? Ce sunt cadrele? La ce folosesc? Care sunt modalităţile de aşezare în pagină a elementelor? Caractere HTML Aspecte generale ale proiectării interfeţelor web Cuvinte cheie: HTML, CSS, element, tag, atribut, id, class, stil, listă, tabel, hiperlegătură, download, hartă imagine, cadru, bordură, margine, ţesătură, etichetă, proiectare

105 Capitolul 4 HTML, CSS - primele noţiuni 105 În cele ce urmează vom învăţa să creăm pagini web utilizând limbajul HTML. Pentru aceasta, vom recapitula cunoştinţele dobândite la orele de Tehnologia Informaţiei şi a Comunicării, dar vom învăţa si multe lucruri noi. Desigur, o pagină astfel creată, poate arăta foarte bine, dar, din păcate, lucrând numai cu HTML-ul, textele şi imaginile nu pot fi personalizate pe cât am dori, iar tehnicile prin care putem crea animaţie aproape că lipsesc. De asemenea, server-ul oferă vizitatorului o pagină care nu ţine cont şi de preferinţele acestuia şi nu-i oferă posibilitatea să scrie date pe site. Cu toate acestea, pentru a crea pagini web, studiul limbajului HTML este indispensabil, iar neajunsurile arătate pot fi eliminate studiind acest capitol Structura de bază a unei pagini HTML+CSS Mai jos, puteţi observa o pagină aşa cum este scrisă în Notepad şi aşa cum este afişată de browser-ul Internet Explorer: a) În Notepad b) În Internet Explorer Figura 4.1. Exemplu de pagină web Din analiza exemplului de mai sus, observăm că: pagina începe cu tag 1 -ul <HTML> şi se termină cu tag-ul </HTML>; pagina conţine un antet (HEAD) şi corpul propriu-zis (BODY); antetul este cuprins între etichetele <HEAD> şi </HEAD>; corpul este conţinut între etichetele <BODY> şi </BODY>. Opţional, antetul poate conţine titlul paginii cuprins între tag-urile <TITLE> şi </TITLE>. Titlul apare pe bara de titlu a ferestrei afişată de Explorer (pentru noi, acesta este "Exemplul 1"). 1 Termenul tag provine din limba engleză şi semnifică etichetă. În acest manual vom folosi ambii termeni: element si tag.

106 106 Manual de Informatică pentru clasa a XII-a Dvs. aţi studiat câteva noţiuni despre HTML în clasa a-ix-a. Acum trebuie să le recapitulăm, dar şi să le prezentăm într-o formă nouă, utilizând limbajul CSS (Cascading Style Sheets), limbaj recunoscut de către browser. Conform CSS, vom imagina elementele HTML ca având formă dreptungiulară. Pentru fiecare element HTML se poate selecta dimensiunea lui, culoarea, mărimea şi stilul de scriere a font-ului, culoarea de fond, culorile marginilor... şi, după cum vom vedea, chiar poziţia în document. A stabili toate acestea pentru un element sau pentru toate elementele de acelaşi tip (de exemplu, toate paragrafele) înseamnă a stabili un stil. Un fişier HTML + CSS poate conţine mai multe stiluri. Modul în care se stabilesc stilurile va fi tratat în amănunt, deocamdată ne mărginim să exemplificăm modul în care se pot preciza stilurile într-un fişier HTML. A) Prin utilizarea elementului <STYLE>...</STYLE>, care va fi conţinut de antet. În interiorul său se pot descrie stiluri pentru un grup de elemente, de exemplu P, pentru paragrafe sau pentru un singur element de un tip oarecare. A1. Toate elementele de un anumit tip au acelaşi stil. Exemplul 4.1. Paragraful are înălţimea de 4 cm, lăţimea de 3 cm, font-ul cu mărimea de 20 de puncte, culoarea de fond - galben, culoarea textului - roşu, iar scrisul italic. Oricâte paragrafe ar conţine documentul, toate vor avea acelaşi stil. <HTML> <HEAD> <STYLE> P {font-size:20pt; color:red; background:yellow; font-style:italic; width:3cm; height:4 cm; </STYLE> </HEAD> <BODY> <P> Acesta este primul exemplu de pagina...</p> </BODY> </HTML> Figura 2.2. Pagina rezultată pentru Exemplul 4.1. A2. Stilul este aplicat unui element, care este identificat prin intermediul atributului id al acestuia. Exemplul 4.2. Formăm un stil cu numele P1. Elementul care va avea acest stil va trebui să conţină atributul id care să aibă valoarea P1. Observaţi că, în exemplu, sunt două paragrafe. Numai unul dintre ele are asociat un stil, celalat se scrie aşa cum am văzut deja

107 Capitolul 4 HTML, CSS - primele noţiuni 107 <HTML> <HEAD> <STYLE> #P1 {font-size:20pt; color:red; background:yellow; font-style:italic; width:3cm; height:4 cm; </STYLE> </HEAD> <BODY> <P id="p1"> Un paragraf care are atasat un stil </P> <P> alt paragraf </P> </BODY> </HTML> A3. Stilul este aplicat unui element sau mai multor elemente, care sunt identificate prin intermediul atributului class. Exemplul 4.3. Se descrie clasa Stil, iar efectul este cel din exemplul anterior: <HTML> <HEAD> <STYLE>.Stil {font-size:20pt; color:red; background:yellow; font-style:italic; width=3cm; height:4 cm; </STYLE> </HEAD> <BODY> <P class="stil"> Un paragraf care are atasat un stil </P> <P> alt paragraf </P> </BODY> </HTML> Important! Există posibilitatea ca stilurile să fie memorate într-un fişier text (creat, de exemplu, cu programul Notepad), cu extensia.css. Codul HTML îl va apela utilizând tag-ul LINK. Elementul LINK reprezintă o modalitate prin care definim legătura între cele două fişiere (css şi html). Acesta are următoarele atribute: rel - defineşte tipul de fişier css; Figura 4.3. Pagina rezultată pentru Exemplul 4.2. type - indică browser-ului în ce limbaj este scris codul; href - se specifică locaţia fişierului (dacă fişierul css nu se găseşte în aceiaşi locaţie cu cel html, se scrie adresa completă a sa).

108 108 Manual de Informatică pentru clasa a XII-a Exemplul 4.4. Reluând exemplul anterior, formăm un fişier text cu numele unstil.css, care va conţine definiţia stilului:.stil {font-size:20pt; color:red; background:yellow; font-style:italic; width=3cm; height:4 cm; În aceste condiţii, fişierul HTML devine: <HTML> <HEAD> <LINK rel="stylesheet" type="text/css" href="unstil.css"> </HEAD> <BODY> <P class="stil"> Un paragraf care are atasat un stil </P> <P> alt paragraf </P> </BODY> </HTML> B) Există posibilitatea să scriem un stil pentru un anumit element, prin utilizarea atributului style. Cu ajutorul acestui atribut, putem defini ad-hoc orice stil. Exemplul 4.5. Testaţi codul sursă de mai jos: <HTML> <HEAD> </HEAD> <BODY> <P style="font-size:20pt; color:red; background:yellow; font-style:italic; width=3cm; height:4cm;"> Un paragraf care are atasat un stil </P> <P> alt paragraf </P> </BODY> </HTML> Din cele prezentate, rezultă că un element HTML are atributele: id, class şi style, iar acestea pot fi utilizate în funcţie de necesitate.

109 Capitolul 4 HTML, CSS - primele noţiuni Elemente HTML pentru afişarea textelor Elementul P are rolul de a permite introducerea unui paragraf. Pentru a-l folosi, utilizăm tag-urile: <P atribute> conţinut paragraf </P> Observaţii! Atunci când sunt afişate, paragrafele sunt separate printr-o linie vidă. Tag-ul </P> poate să lipsească, nu este obligatoriu! Un nou paragraf poate fi depistat prin tag-ul <P>. În Notepad, WordPad sau Word, paragrafele se separă prin tastarea unui Enter. În schimb, în HTML, Enter-ul nu are nici un efect. Vedeţi în exemplul anterior, al doilea paragraf (aşa cum a fost tastat în Notepad). El conţine un Enter (de fapt, în Notepad, sunt două paragrafe). Acesta a fost ignorat de Explorer. Fără o altă comandă, un rând al unui paragraf are lăţimea ferestrei afişată de browser. De exemplu, dacă micşorăm fereastra browser-ului, acelaşi paragraf va ocupa mai multe rânduri. Dacă două cuvinte ale unui paragraf sunt separate prin mai multe spaţii, browser-ul afişează doar un singur spaţiu. Elementul &nbsp Câteodată, avem nevoie să prevenim trecerea unui cuvânt pe linia următoare. Folosim elementul &nbsp pentru a evita acest lucru, prin scrierea sa înaintea cuvântului de interes. În cazul în care nu încape pe linie, se coboară şi cuvântul precedent pe linia următoare. Exemplul 4.6. Testaţi forma de mai jos: <P>Acest paragraf a fost afisat de Internet&nbspExplorer.</P> În figura alăturată se observă faptul că browser-ul a fost forţat să treacă cuvântul Internet pe rândul următor. Figura 4.4. Exemplu de utilizare a elementului &nbsp

110 110 Manual de Informatică pentru clasa a XII-a În continuare, vom prezenta cele mai importante elemente de formatare ale textului. Elementul BR - are ca efect forţarea afişării a ceea ce urmează pe rândul următor. Pentru a-l utiliza, se foloseşte un singur tag: <BR>. Exemplul 4.7. Paragraful următor este afişat pe două rânduri: <P> Mama merge <BR> la piata </P> Figura 4.5. Exemplu de utilizare a elementului <BR> Tag-ul <BR> nu creează un alt paragraf. Nu uitaţi, între două paragrafe se lasă o linie vidă. În cazul etichetei <BR>, rândul următor nu este separat de rândul curent prin linie vidă. Elementul B - are rolul de a determina browser-ul să afişeze îngroşat (bold) textul cuprins între cele două tag-uri ale sale: <B> şi </B>. Exemplul 4.8. Cuvintele trebuie şi ai sunt afişate îngroşat: <P> Ceea ce-ti <B>trebuie</B> vei gasi in ceea ce <B>ai</B>! </P> Figura 4.6. Exemplu de utilizare a elementului <B> Elementul I - are rolul de a determina browser-ul să afişeze înclinat (italic) textul cuprins între cele două tag-uri ale sale: <I> şi </I>. Exemplul 4.9. Cuvintele trebuie şi ai sunt afişate înclinat: <P> Ceea ce-ti <I>trebuie</I> vei gasi in ceea ce <I>ai</I>! </P> Figura 4.7. Exemplu de utilizare a elementului <I>

111 Capitolul 4 HTML, CSS - primele noţiuni 111 Elementul U - are rolul de a determina browser-ul să afişeze subliniat textul cuprins între cele două tag-uri ale sale: <U> şi </U>. Exemplul Cuvintele trebuie şi ai sunt afişate subliniat: <P> Ceea ce-ti <U>trebuie</U> vei gasi in ceea ce <U>ai</U>! </P> Figura 4.8. Exemplu de utilizare a elementului <U> Elementul S - are rolul de a determina browser-ul să afişeze tăiat textul cuprins între cele două tag-uri ale sale: <S> şi </S>. Exemplul Cuvintele trebuie şi ai sunt afişate tăiat: <P> Ceea ce-ti <S>trebuie</S> vei gasi in ceea ce <S>ai</S>! </P> Figura 4.9. Exemplu de utilizare a elementului <S> Elementul BIG - are rolul de a comanda browser-ului ca textul cuprins între tag-urile <BIG> şi </BIG> să fie scris mai mare decât restul textului. Exemplul Textul elementul BIG este scris mărit: <P>Un paragraf care foloseste <BIG>elementul BIG</BIG>!</P> Figura Exemplu de utilizare a elementului <BIG> Atenţie! Elementul BIG nu este suportat de toate browser-ele, deci este de preferat utilizarea tag-ului FONT. De exemplu: <P>Exemplu de <FONT size="+1">text marit</font>!</p>

112 112 Manual de Informatică pentru clasa a XII-a Elementul SMALL - are rolul de a comanda browser-ului ca textul cuprins între tag-urile <SMALL> şi </SMALL> să fie scris mai mic decât restul textului. Exemplul Textul elementul SMALL este scris micşorat: <P>Un paragraf care foloseste <SMALL>elementul SMALL</SMALL>!</P> Figura Exemplu de utilizare a elementului <SMALL> Elementul TT - are rolul de a comanda browser-ului ca textul cuprins între tag-urile <TT> şi </TT> să fie scris monospaţiat (adică toate caracterele ocupă aceeaşi lungime de spaţiu, precum font-ul Courier New ). Exemplul Textul elementul TT este scris monospaţiat: <P>Un paragraf care foloseste <TT>elementul TT</TT>!</P> Figura Exemplu de utilizare a elementului <TT> Elementul DEL - are rolul de a comanda browser-ului ca textul cuprins între tag-urile <DEL> şi </DEL> să fie scris tăiat, pentru a arăta că a fost şters (păstrându-l, totuşi, în document pentru a nu mai antrena şi alte modificări ale acestuia). Exemplul Textul elementul DEL este scris tăiat: <P>Un paragraf care foloseste <DEL>elementul DEL</DEL>!</P> Figura Exemplu de utilizare a elementului <DEL> Elementul SUP - are rolul de a comanda browser-ului ca textul cuprins între tag-urile <SUP> şi </SUP> să fie scris mai sus (ca o putere, exponent).

113 Capitolul 4 HTML, CSS - primele noţiuni 113 Exemplul Textul x*ln(x) este scris ca o putere: <P> 3<SUP>x*ln(x)</SUP> </P> Figura Exemplu de utilizare a elementului <SUP> Elementul SUB - are rolul de a comanda browser-ului ca textul cuprins între tag-urile <SUB> şi </SUB> să fie scris mai jos (ca un indice). Exemplul Textul i,j este scris ca un indice: <P> a<sub>i,j</sub> </P> Figura Exemplu de utilizare a elementului <SUB> Elementele H1, H2,..., H6 Pentru scrierea titlurilor se utilizează elementele H1, H2,..., H6. Fiecare titlu este scris între tag-urile: <H1> </H1>, <H2> </H2>,, <H6> </H6>. Mărimea diferă: pentru <H1> titlul este scris utilizând font-ul de dimensiune maximă, iar pentru <H6> dimensiunea este minimă. Exemplul Mai jos, observaţi cum este scris un titlu: <H1>Despre lenesi...</h1> <P>Lenesul gaseste in orice sarbatoare un prilej sa nu munceasca!</p> Figura Exemplu de utilizare a elementului <H1> Atenţie! Titlurile trebuie să fie folosite în ordine ierarhică. În general, un document HTML trebuie să aibă exact un element H1, pentru a indica titlul principal al paginii. Motoarele de căutare pot utiliza informaţiile din aceste titluri, deci ele trebuie să sintetizeze cât mai bine conţinutul textului.

114 114 Manual de Informatică pentru clasa a XII-a 4.3. Atribute CSS pentru font-uri În continuare vor fi prezentate principalele atribute CSS care pot fi utilizate, în cadrul unui stil, pentru a personaliza fontul cu care se va afişa textul. A) font-style poate lua valorile: normal italic B) font-variant poate lua valorile: normal C) font-weight poate lua valorile: small-caps normal bold D) font-size mărimea. Există mai multe modalităţi de a indica dimensiunea font-ului. Cea mai simplă este de a o indica în puncte: 10pt 15pt 20pt E) font grupează primele patru atribute, deci dacă îl folosim putem renunţa la acestea. Nu contează ordinea în care sunt scrise... Exemplul Mai jos, am descris un stil pentru paragrafe care are ca rezultat pagina din Figura 4.17: <HTML> <HEAD> <STYLE> P { font:italic bold 15pt; </STYLE> </HEAD> <BODY> <P>Un exemplu...</p> </BODY> </HTML> Figura Exemplu de paragraf personalizat cu ajutorul atributului font

115 Capitolul 4 HTML, CSS - primele noţiuni 115 F) font-family are rolul de a stabili o familie de font-uri cu care vor fi afişate textele. Vă daţi seama că nu se poate şti dacă cel care vizitează pagina are pe calculatorul său instalat sau nu un anumit font. Din acest motiv se trec, în ordine, familiile de font-uri care vor fi utilizate. La vizualizarea documentului, se verifică dacă există un font din prima familie. În caz afirmativ, se afişează textul cu un font din prima familie. Dacă un astfel de font nu există, se caută dacă există un font din a doua familie, ş.a.m.d. Exemple de valori: times, courier, arial, etc. Este recomandabil ca ultima valoare din listă să fie una dintre valorile de mai jos. Ele nu specifică o familie de font-uri, ci mai degrabă un stil de scriere. El va fi folosit atunci când nici una din familiile de font-uri nu a fost găsită, caz în care browser-ul caută un font apropiat de ultima valoare: serif sans-serif cursive monospace Exemplul Analizaţi stilul de mai jos: P { font-size:20pt; font-family:courier, monospace; 4.4. Atribute CSS pentru texte Limbajul CSS permite stilizarea la nivel de text prin intermediul unor atribute care sunt detaliate în cele ce urmează. A) text-decoration poate lua valorile: underline (cu o linie sub el), overline (cu o linie peste el), line-through (taiat în interior) şi none (fără nicio linie, clasic). underline overline line-through none

116 116 Manual de Informatică pentru clasa a XII-a Exemplul Putem să folosim şi combinaţii între aceste variante, precum cea de mai jos. Efectul poate fi observat în Figura <HTML> <HEAD> <STYLE> P {text-decoration: underline overline; </STYLE> </HEAD> <BODY> <P>Un exemplu...</p> </BODY> </HTML> Figura Exemplu de paragraf personalizat cu atributul text-decoration B) text-align alinierea textului poate lua valorile de mai jos: left right center justify Figura Exemple de aliniere a textului C) text-indent este folosit pentru indentarea textelor. Primul rând al textului va începe mai în dreapta cu o valoare precizată. Exemplul Pentru a obţine indentarea din figura alăturată, am folosit stilul de mai jos: P {text-indent:1cm; Figura Exemplu de indentare aplicată unui paragraf

117 Capitolul 4 HTML, CSS - primele noţiuni 117 D) line-height - înălţimea liniei atributul este folosit pentru a stabili distanţa dintre rândurile unui paragraf. Exemplul Am format două stiluri pe care le-am aplicat apoi celor două paragrafe (vezi Figura 4.21): <HTML> <HEAD> <STYLE> #unu {font-size: 15pt; line-height: 0.5cm; #doi {font-size: 15pt; line-height: 1cm; </STYLE> </HEAD> <BODY> <P id="unu">acest text a fost scris pentru a exemplifica spatierea intre randuri.</p> <P id="doi">acest text a fost scris pentru a exemplifica spatierea intre randuri.</p> </BODY> </HTML> Figura Exemple de paragrafe cu linii de înălţime diferită 4.5. Liste În HTML, există posibilitatea ca anumite enunţuri să fie numerotate sau marcate într-un anumit fel. O astfel de organizare poartă denumirea de listă. Astfel, în HTML se pot descrie trei tipuri de liste: liste ordonate, în care elementele sunt numerotate; liste neordonate, în care elementele sunt marcate de aşa natură încât nu se sugerează o anumită ordine a lor; liste de tip definiţie. În continuare, puteţi observa un exemplu pentru fiecare tip de listă:

118 118 Manual de Informatică pentru clasa a XII-a 1. Bloc 2. Vila 3. Casa Bloc Vila Casa Bloc Vila Casa Multe etaje, zeci de familii Unu sau doua etaje, cel mult 5 familii N-are etaje, o familie a) Listă ordonată; b) Listă neordonată; c) Listă de tip definiţie. Pentru a forma astfel de liste, avem nevoie de câteva elemente HTML care vor fi detaliate în cele ce urmează. Elementul OL (Ordered Lists) - creează o listă ordonată. Elementele listei sunt trecute între tag-urile <OL> şi </OL>. Elementul LI (List Item) - descrie un element al listei. Tag-ul obligatoriu este cel de început <LI>, cel de sfârşit fiind facultativ: </LI>. Exemplul Priviţi lista ordonată de mai jos: <P>Cine nu... nu castiga!</p> <OL> <LI> pierde <LI> risca <LI> ajunge </OL> Figura Exemplu de listă ordonată Elementul OL are atributul type. Valorile pe care le poate lua acest atribut, precum şi modul în care arată lista, se pot observa în continuare: a. pierde b. risca c. ajunge <OL tyle="a"> i. pierde ii. risca iii. ajunge <OL tyle="i"> 1. pierde 2. risca 3. ajunge <OL tyle="1"> A. pierde B. risca C. ajunge <OL tyle="a"> I. pierde II. risca III. ajunge <OL tyle="i">

119 Capitolul 4 HTML, CSS - primele noţiuni 119 Elementul UL (Unordered Lists) - descrie o listă neordonată. Elementele listei sunt cuprinse între tag-urile <UL> şi </UL>. Exemplul Priviţi lista neordonată de mai jos: <P>Periferice esentiale:</p> <UL> <LI> monitor <LI> tastatura <LI> mouse </UL> Figura Exemplu de listă neordonată Elementul UL are atributul type. Valorile pe care le poate lua acest atribut, precum şi modul în care arată lista se observă în continuare: <UL type="circle"> <UL type="square"> <UL type="disc"> Observaţii! Desigur, putem construi liste imbricate, aşa cum se poate observa cu uşurinţă din exemplul următor: Exemplul Analizaţi lista de mai jos: <P><U>Echipa castigatoare:</u></p> <UL type="square"> <LI>Jucatori: <OL type="1"> <LI> George <LI> Lavinia <LI> Mihai </OL> <LI>Rezerve: <OL type="1"> <LI> Cristian <LI> Flavius </OL> </UL> Figura Exemplu de liste imbricate Pentru a lăsa un rând liber, putem marca un paragraf prin <P> </P> sau... numai prin <P>.

120 120 Manual de Informatică pentru clasa a XII-a Elementul DL (Definition Lists) - are rolul de a descrie o listă de definiţii, delimitată de tag-urile <DL> şi </DL>. Elementul DT (Definition Term) - defineşte termenul din listă care trebuie descris. Se utilizează tag-ul <DT>. Elementul DD (Definition Description) - are rolul de a reţine descrierea termenului. Se utilizează tag-ul <DD>. Exemplul Priviţi lista de definiţii de mai jos: <DL> <DT>to elapse <DD>a trece, a se scurge <DT>I've never seen <DD> n-am (mai) vazut (niciodata) </DL> Figura Exemplu de listă de definiţii 4.6. Structura unui element HTML În general, un element HTML, P, OL, H6, etc. este alcătuit sub formă de cutie (box), cu structura următoare: Conţinut Ţesătură (padding) Bordură (border) Margine (margin) Figura Structura unui element HTML

121 Capitolul 4 HTML, CSS - primele noţiuni 121 Marginea (margin) nu este vizibilă de vizitatorul paginii. Rostul ei este de a păstra distanţa dintre cutie şi celelalte elemente. Bordura (border) în cazul în care creatorul paginii doreşte, aceasta poate fi făcută vizibilă (de exemplu i se stabileşte o altă culoare). Ţesătura (padding) poate fi dimensionată, dar nu poate fi făcută vizibilă printr-o culoare distinctă. Vom prefera termenul de padding. Conţinutul este dat de text şi/sau imagine. Observaţii! În ansamblu, părţile unor elemente de acelaşi tip pot fi dimensionate. Vedeţi paragrafele următoare! În general, pentru majoritatea elementelor se poate trece spaţiul ocupat de acestea: lăţimea (width) şi înălţimea (height). Înălţimea şi lăţimea cutiei include bordura, dar nu include marginile. În cazul în care conţinutul nu încape în cutie, nu se respectă înălţimea şi lăţimea dată de aceste atribute. În continuare, vom da exemple de elemente pentru care a fost scris un stil. În acest mod, vă puteţi face de la început o idee despre puterea limbajului CSS. De multe ori, putem face ca un element să arate cu totul altfel decât arată în forma implicită. În paragrafele următoare vor fi prezentate toate atributele, dar acum, vă prezentăm câteva elemente HTML cu înfăţişare neobişnuită. Exemplul Am creat un stil pentru un element H1. Bordura are culoare distinctă, iar textul este aliniat la stânga. Faptul că există un spaţiu între bordură şi text confirmă existenţa padding-ului (de 0.5 cm). H1 {border:solid 10pt red; background-color:green; padding:0.5cm 0.5cm 0.5cm 0.5cm; text-align:left; width:3cm;... <H1>Un element H1</H1> Figura Exemplu de element H1 stilizat Exemplul Am creat un stil pentru paragrafe. În acest caz, bordura are o formă specială. Fontul utilizat este din famila "Arial", scris îngroşat (bold) şi înclinat (italic). Textul este aliniat la centru (center): Figura Exemplu de paragraf stilizat

122 122 Manual de Informatică pentru clasa a XII-a P {border:groove 1cm red; background-color:yellow; padding: 1cm 1cm 1cm 1cm; width:5cm; height:5cm; text-align:right; font-family:arial; font-weight:bold; font-style:italic;... <P> Un exemplu de paragraf </P> Exemplul O listă pentru care s-a stabilit dimensiunea font-ului, culoarea de fond, culoarea, etc.: OL {font-size:20pt; font-weight:bold; color:black; background-color:blue;... <OL> <LI> masina <LI> bicicleta </OL> Figura Exemplu de listă stilizată 4.7. Atribute de culoare şi fond În general, o culoare poate fi recunoscută prin numele ei ("red", "green", "gray",...) sau prin valorile RGB (Red, Green, Blue). Puteţi alege culoarea în Paint (opţiunea Edit Colors), după care treceţi valorile în HTML. Este de preferat a doua variantă, pentru că prima este depreciată conform noilor standarde HTML. A) color specifică culoarea textului. Exemplul Mai jos, am setat o culoare pentru textul paragrafelor: P {font-size:40pt; color:rgb(12,56,23); Observaţie! Background-ul acoperă suprafaţa conţinutului şi a padding-ului. B) background-image pentru fundal se poate folosi chiar şi o imagine. Dacă imaginea este mai mică decât suprafaţa care trebuie afişată, atunci ea este multiplicată astfel încât să acopere întreaga suprafaţă.

123 Capitolul 4 HTML, CSS - primele noţiuni 123 Exemplul Se stabileşte imaginea ca fundal pentru întreg documentul (body). De asemenea, paragrafele vor avea textul de culoare albă, de 40 de puncte. <HTTML> <HEAD> <STYLE> P {font-size:40pt; color:rgb(255,255,255); body {background-image:url(c:\catelus\1.jpg); </STYLE> </HEAD> <BODY> <P> Un exemplu de catelus </P> </BODY> </HTML> Figura Exemplu de pagină cu o imagine pe fundal C) background-color stabileşte culoarea fundalului. Uneori este trecut şi în cazul în care pe fundal avem o imagine, pentru că este posibil ca, dintr-un motiv sau altul, imaginea să nu apară. Exemplul Paragrafele se scriu cu alb, pe fond roşu: P {font-size:12pt; color:rgb(255,255,255); background-color:rgb(255,0,0); sau P {font-size:12pt; color:white; background-color:red; Figura Un paragraf cu fundalul roşu şi textul alb Exemplul Pentru body se alege o imagine pentru fundal, iar dacă aceasta nu apare, ca măsură de siguranţă, s-a ales culoarea neagră: body {background-image:url(c:\catelus\1.jpg); background-color:black; D) background-repeat am văzut faptul că, dacă o imagine este mai mică decât spaţiul necesar pentru un element, atunci aceasta se repetă atât pe orizontală cât şi pe verticală până când se umple acest spaţiu. Există posibilitatea să controlăm această repetare prin valorile pe care le ataşăm acestui atribut: repeat repetarea se face atât pe orizontală cât şi pe verticală; repeat-x repetarea se face numai pe orizontală; repeat-y repetarea se face numai pe verticală; no-repeat imaginea nu se repetă.

124 124 Manual de Informatică pentru clasa a XII-a E) background-attachment poate lua două valori: fixed şi scroll (valoare implicită). În cazul în care pe fundal se găseşte o imagine, efectul este deosebit. Dacă valoarea este fixed, atunci defilează numai obiectele care se găsesc pe fundal (imaginea rămânând fixă), iar dacă valoarea este scroll, atunci defilează şi imaginea. Exemplul Analizaţi paginile de mai jos: body {background-repeat:fixed; Figura Exemple de pagini cu fundal fix sau mobil F) background-position dacă pe fundal se afişează o imagine, atunci i se poate preciza poziţia în raport cu fereastra. Există mai multe posibilităţi de precizare a poziţiei: body {background-repeat:scroll; procentual: de exemplu, 33% 50% (la 1/3 de partea stângă a ferestrei şi la 1/2 din înălţimea ei); în valori absolute: de exemplu, 2cm 3cm (la 2 cm de partea stângă a ferestrei şi la 3 cm de partea de sus); mixt: de exemplu, 2cm 50% (la 2 cm de partea stângă a ferestrei şi la jumătate raportat la înălţime); numai o valoare caz în care se referă numai la alinierea pe orizontală în raport cu marginea din stânga a ferestrei; prin cuvinte cheie: left (stânga), right (dreapta), top (sus) şi bottom (jos) de exemplu: body {background-position: left bottom; (în stânga-jos). Exemplul Mai jos, a fost creat un stil care defineşte o singură imagine pe fundal, la mijlocul ferestrei, care nu defilează (rămâne fixă): body {background-image: url(c:\catelus\1.jpg); background-repeat: no-repeat; background-position: 50% 50%; background-attachment: fixed; G) background o singură caracteristică pentru toate celelalte. Se trec, în ordine, toate valorile pentru background-image, background-repeat,...

125 Capitolul 4 HTML, CSS - primele noţiuni Atribute pentru margini Fiecare element poate avea margini. Rolul lor este de a o separa de alte elemente. Iată cum se pot stabili marginile: A) Margin-left mărimea marginii din stânga; B) Margin-right mărimea marginii din dreapta; C) Margin-top mărimea marginii de deasupra; D) Margin-bottom mărimea marginii de dedesupt; E) Margin toate marginile în ordinea: sus, drepta, jos şi stânga. Exemplul Pentru elementele de tip paragraf, a fost realizat un stil care defineşte marginile acestuia (fereastra este micşrată, pentru a evidenţia marginile): P {font-size:15pt; margin-left:1cm; margin-right:2cm; margin-top:3cm; top Figura Un paragraf cu margini modificate left right 4.9. Atribute pentru padding Padding-ul poate fi doar dimensionat, dar nu i se poate aplica o culoare distinctă: Padding-top partea de sus; Padding-left partea din stânga; Padding-bottom partea de jos; Padding-right partea din dreapta; Padding - toate marginile, în ordinea: sus, dreapta, jos şi stânga Atribute pentru bordură Mai întâi, putem stabili dimensiunile bordurii: Border-top-width partea de sus, Border-left-width partea din stânga, Border-bottom-width partea de jos şi Border-right-width partea din dreapta. Border-width le înlocuieşte pe primele 4. Se trec valorile în ordinea: sus, dreapta, jos şi stânga. Dacă se trece o singură valoare, aceasta va fi ataşată tuturor marginilor.

126 126 Manual de Informatică pentru clasa a XII-a Observaţie! Pentru grosimea bordurii se mai pot folosi valorile: thin (subţire), medium (medie) sau thick (groasă). Border-color culoarea bordurii. Se pot folosi maximum 4 culori, în ordinea: sus, dreapta, jos şi stânga. Dacă se trece o singură culoare, aceasta va fi ataşată tuturor marginilor. Border-style se trece în mod obligatoriu. Contrar, bordura nu este vizibilă. Valorile mai importante pe care le poate lua acest parametru se pot observa în figura de mai jos: solid double groove ridge inset outset Figura Diverse tipuri de borduri Border-top-style stilul bordurii în partea de sus; Border-right-style stilul bordurii în partea dreaptă; Border-bottom-style stilul bordurii în partea de jos; Border-left-style stilul bordurii în partea stângă Elementul IMG Ce farmec are o pagină dacă nu conţine una sau mai multe imagini? Elementul IMG - se utilizează pentru a ataşa unei pagini o imagine. Vom folosi tag-ul <IMG>. Forma generală a acestui element este: <IMG atribute>. Atributele lui sunt: src - identifică fişierul care conţine imaginea respectivă (poate fi de tipul: jpg, gif, etc.).

127 Capitolul 4 HTML, CSS - primele noţiuni 127 Observaţie! În această etapă învăţăm să creăm paginile pe propriul calculator, fără a fi conectaţi la Internet. Prin urmare, fişierul care conţine imaginea se va găsi într-un folder oarecare (în exemplul următor, el se găseşte în acelaşi folder în care găsim şi fişierul cu extensia htm (cel care conţine pagina). Din acest motiv, sursa nu conţine şi calea, dar, dacă este cazul, calea poate fi introdusă. ALT="nume" există posibilitatea ca imaginea să nu se poată încărca. Pentru astfel de situaţii este folosit parametrul ALT, unde nume conţine un text (alternativ) care va fi afişat în locul imaginii. Exemplul Fie tag-ul IMG următor: <IMG src="c:/eric.jpg", alt="eric"> Dacă imaginea este găsită, se face afişarea ca în figura din dreapta, altfel se afişează ce se vede mai jos: Figura 4.35 Figura Exemplu de pagină care conţine o imagine Exerciţiu! Luaţi o imagine oarecare şi faceţi diverse exerciţii de afişare a ei, utilizând cunoştinţele de CSS prezentate în paragrafele 4.7, 4.8 şi 4.9. Spre exemplu, analizaţi codul de mai jos (vezi şi Figura 4.37): <HTML> <HEAD> <STYLE> IMG {width:3cm; height:4cm;</style> </HEAD> <BODY> <P> Acest paragraf este scris pentru a verifica modul de aliniere pe orizontala in cazul unui element IMG, care este de tip INLINE <IMG src="eric.jpg", alt="eric">, deci se insereaza exact ca un cuvant intr-un paragraf</p> <P> Paragraful este un element de tip BLOC, asa ca se insereaza pe o linie noua! </BODY> </HTML> Figura Exemplu de pagină web

128 128 Manual de Informatică pentru clasa a XII-a Tabele În cadrul unei pagini web se pot introduce şi tabele, extrem de utile pentru evidenţierea unor date sau, pur şi simplu, pentru a delimita spaţiul paginii. Desigur, tabelul rezultat poate fi privit în mod clasic, cu linii şi coloane, aşa cum suntem obişnuiţi, dar poate fi folosit şi în alte scopuri, cum ar fi: aliniarea imaginilor (elemente de tip IMG în raport cu textul) sau scrierea în coloane. Din acest motiv, în sens larg, prin tabel vom înţelege o grupare în linii şi coloane a mai multor elemente HTML. Elementul TABLE - descrie un tabel, utilizând etichetele: <TABLE> şi </TABLE>. Elementul TR - descrie o linie a tabelului, care începe cu <TR> şi se termină atunci când este întâlnit un nou <TR>. Opţional, se poate folosi şi tag-ul </TR> pentru a închide linia curentă. Elemenul TD - descrie o celulă a tabelului. Se utilizează tag-urile <TD> şi, opţional, </TD>. Exemplul Mai jos, puteţi observa un prim tabel, cu două linii, aşa cum este descris şi aşa cum apare afişat (vezi Fig. 4.38): <TABLE border="5"> <TR> <TD> Un text </TD> <TD> Un text cu mult mai lung!</td> </TR> <TR> <TD> Text </TD> <TD> Text </TD> </TR> </TABLE> Figura Exemplu de tabel În continuare, prezentăm câteva atribute ale elementului TABLE. Border defineşte grosimea liniilor (în pixeli) care înconjoară tabelul. Pe pagina următoare (în Fig. 4.39), puteţi observa cum arată acelaşi tabel, în care atributul Border lipseşte. Simpla trecere a acestui atribut, fără a preciza numărul de pixeli, are ca efect crearea unui chenar standard.

129 Capitolul 4 HTML, CSS - primele noţiuni 129 Iată tabelul, fără atributul Border: Figura Exemplu de tabel fără chenar Observaţii! În absenţa altor formatări, toate celulele unei coloane au lăţimea impusă de cel mai lung conţinut al uneia dintre ele! În situaţia în care reducem dimensiunile ferestrei browser-ului, textul va fi dispus modificat, pentru ca tabelul să încapă în totalitate. Dincolo de această limită, fereastra nu mai poate fi micşorată. Figura Efectul redimensionării ferestrei browser-ului În cazul în care o linie conţine mai multe celule decât restul liniilor, automat toate liniile vor avea acelaşi număr maxim de celule: <TABLE BORDER="5"> <TR> <TD> O noua celula </TD> <TD>Un text </TD> <TD> Un text cu mult mai lung! </TD> </TR> <TR> <TD> Text </TD> <TD> Text </TD> </TR> </TABLE> Figura Exemplu de tabel în care două linii au un număr diferit de celule Un tabel poate conţine şi una sau mai multe imagini, aşa cum se vede mai jos, unde imaginea este conţinută de o celulă a tabelului: <TABLE BORDER="5"> <TR> <TD><IMG SRC="BP1.jpg"></TD> <TD>Un text cu mult mai lung! </TD></TR> <TR><TD>Text</TD><TD>Txt</TD> </TR> </TABLE> Figura Exemplu de tabel care conţine o imagine

130 130 Manual de Informatică pentru clasa a XII-a cellspacing - determină spaţiul, în pixeli, dintre celule. Exemplul În figura alăturată, este prezentat un tabel cu cellspacing="10". Figura Exemplu de tabel cellpadding determină, în pixeli, spaţiul lăsat în fiecare celulă a tabelului între text (imagine) şi marginile celulei. Exemplul Acelaşi tabel, din exemplul anterior, cu cellpadding = "15". Figura Exemplu de tabel Atenţie! Pentru ultimele două atribute, se poate alege o valoare procentuală, astfel încât marginile să aibă dimensiunea procentual, în raport cu dimensiunea disponibilă totală (lăţime şi înălţime). rules defineşte modul în care vor fi trasate liniile care separă celulele tabelului. Poate lua valorile: None Rows Cols All Figura Exemple de trasare a liniilor separatoare frame - defineşte părţile care vor fi trasate din chenarul care înconjoară tabelul. Atributul poate lua valorile: Above Below Hsides Vsides Lhs Rhs Figura Exemple de variante de trasare a chenarului unui tabel

131 Capitolul 4 HTML, CSS - primele noţiuni 131 Iată şi câteva atribute ale elementului TD: colspan="nr" - inserează în dreapta celulei, nr-1 celule al căror conţinut este vid, dar pot fi folosite pentru afişarea valorii reţinute de celula care are acest parametru. Efect secundar: pentru păstrarea formei dreptunghiulare, toate celelalte linii vor avea, în dreapta, câte o celulă al cărei conţinut este vid. Exemplul Considerăm tabelul de mai jos: <TABLE BORDER="5"> <TR> <TD> T11</TD> <TD> T12 </TD> <TD> T13</TD> </TR> <TR> <TD> T21</TD> <TD> T22 </TD> <TD> T23</TD> </TR> <TR> <TD> T31</TD> <TD> T32 </TD> <TD> T33</TD> </TR> </TABLE> Figura Tabelul iniţial care arată ca în Fig A doua celulă din linia 1 va conţine parametrul colspan: <TD colspan="2"> T12 </TD>. În figura alăturată, puteţi observa efectul! Figura Efectul obţinut Pentru a evita o astfel de situaţie, neplăcută, linia respectivă va conţine o celulă în minus, ca în exemplul următor. În plus, textul conţinut de celula cu acest parametru va fi aliniat în centru, pentru a vedea cum se poate folosi spaţiul astfel obţinut: <TABLE BORDER="5"> <TR> <TD> T11</TD> <TD colspan="2" align="center">t12 </TD></TR> <TR> <TD> T21</TD> <TD> T22 </TD> <TD> T23</TD></TR> <TR> <TD> T31</TD> <TD> T32 </TD> <TD> T33</TD></TR> </TABLE> Figura Ajustarea tabelului rowspan="nr" - inserează pe următoarele nr-1 linii, în aceeaşi coloană, câte o celulă al cărei conţinut este vid. Efect secundar: pentru păstrarea formei dreptunghiulare, toate liniile vor conţine câte o celulă în plus.

132 132 Manual de Informatică pentru clasa a XII-a Exemplul Considerăm tabelul de mai jos: <TABLE BORDER="5"> <TR> <TD> T11</TD> <TD rowspan="2" align="center"> T12</TD> <TD>T13</TD></TR> <TR> <TD> T21</TD> <TD> T22 </TD> <TD> T23</TD></TR> <TR> <TD>T31</TD><TD>T32</TD> <TD>T33</TD></TR> </TABLE> Figura Exemplu de tabel Pentru a corecta acest dezavantaj, următoarele nr-1 linii vor conţine câte o celulă mai puţin. Reluăm exemplul: <TABLE BORDER="5"> <TR> <TD>T11</TD> <TD rowspan="2" align="center"> T12</TD> <TD>T13</TD></TR> <TR> <TD>T21</TD><TD>T22</TD></TR> <TR> <TD>T31</TD><TD>T32</TD> <TD>T33</TD></TR> </TABLE> Exemplul Vom extinde celula T12 şi în dreapta şi în jos (cei doi parametri pot fi folosiţi şi simultan). Textul va fi scris în centrul pătratului astfel format (vezi Fig. 4.52): <TABLE BORDER="5"> <TR> <TD>T11</TD> <TD rowspan="2" colspan="2" valign="middle" align="center"> T12</TD></TR> <TR> <TD>T21</TD></TR> <TR> <TD>T31</TD> <TD>T32</TD> <TD>T33</TD></TR> </TABLE> Elementul CAPTION - are rolul de a permite scrierea titlului unui tabel. Titlul se scrie între cele două tag-uri, <CAPTION> şi </CAPTION>. Cele două etichete trebuie să se găsească imediat după <TABLE>. Exemplul Mai jos am introdus un titlu pentru un tabel oarecare: <TABLE> <CAPTION> Un titlu </CAPTION>... Figura Ajustarea tabelului Figura Extinderea unei celule

133 Capitolul 4 HTML, CSS - primele noţiuni 133 Elementul CAPTION are atributul align. Cele patru valori pe care le poate lua şi efectul lor, le puteţi observa mai jos: top bottom left right Figura Exemple de tipuri de aliniere a titlului unui tabel 1. Să se realizeze tabelul de mai jos. Acesta este un caz clasic de tabel. În afara tabelului propriu-zis, trebuie să utilizăm limbajul CSS pentru capul de tabel şi alinierea din coloana a doua. Figura Tabelul propus pentru exerciţiul 1 Rezolvare. Mai jos este prezentat codul sursă: <HTML> <HEAD> <STYLE>.Stil {font-size:20pt; background:yellow; font-style:bold; text-align:"center";.stil1 {text-align:"center"; </STYLE> </HEAD> <BODY> <TABLE border="5"> <TR class="stil"> <TD> <B> Nume tip </B> </TD> <TD> <B> Numar octeti </B> </TD> <TD> <B> Valoare </B> </TD> </TR>

134 134 Manual de Informatică pentru clasa a XII-a <TR> <TD> <B> float </B> </TD> <TD class="stil1"> 4 </TD> <TD> 3.4*10 <SUP> -38</SUP> si 3.4*10 <SUP> 38</SUP> </TD> </TR> <TR> <TD> <B>double</B> </TD> <TD class="stil1"> 8 </TD> <TD> 1.7*10 <SUP>-308</SUP> si 1.7*10 <SUP>308</SUP> </TD> </TR> <TR> <TD> <B>long double</b> </TD> <TD class="stil1"> 10 </TD> <TD>3.4*10<SUP>-4932</SUP> si 3.4*10<SUP>4932</SUP> </TD> </TR> </TABLE> </BODY> </HTML> 2. Formaţi o pagină web care să conţină un text oarecare, scris în stânga unei imagini (vezi Fig. 4.55). Rezolvare. Aparent, ar fi o problemă de aliniere în dreapta a unei imagini. În realitate, mascat, avem un tablel cu o singură linie şi două coloane. În prima se găseste un text, în a doua o imagine. Evident, dacă se inverează conţinutul celor două coloane, obţinem efectul alinierii la stânga a imaginii. <HTML> <HEAD> <STYLE> P {width:3cm; height:4cm; IMG {width:3cm; height:4cm; </STYLE> </HEAD> <BODY> <TABLE> <TR> <TD><P>Un text; Un text; Un text; Un text; Un text; Un text; Un text; Un text; Un text; Un text; Figura Pagina web propusă pentru exerciţiul 2 Un text; Un text; Un text; Un text; Un text;</p></td> <TD> <IMG src="eric.jpg", alt="eric"> </TD> </TR> </TABLE> </BODY> </HTML>

135 Capitolul 4 HTML, CSS - primele noţiuni Se cere să se scrie un text în două coloane, precum în imaginea de mai jos: Figura Pagina web pentru exerciţiul 3 Rezolvare. În fapt, vom construi un tabel cu două linii şi două coloane. Cele două elemente de pe prima linie sunt unite şi conţin titlul. În cele două coloane se scriu mai multe paragrafe. După cum ştiţi deja, lăţimea coloanelor depinde de mărimea ferestrei browser-ului, dar, mai ales, de conţinutul lor. Din acest motiv, s-a forţat prin CSS ca paragrafele să aibă lăţimea de 4 cm. În rest, analizaţi modul în care s-a realizat pagina respectivă: <HTML> <HEAD> <STYLE> P { width:4cm; H2 {text-align:"center" </STYLE> </HEAD> <BODY> <TABLE> <TR><TD colspan="2"><h2>scrierea pe coloane</h2></td></tr> <TR> <TD> <P>Un text scris pe doua coloane.</p> <P>Formam un tabel cu o singura linie si doua celule de date.</p></td> <TD> <P>Trebuie sa ne asiguram ca textul este impartit de asa natura astfel incat sa ocupe aproximativ acelasi spatiu in cele doua coloane.</td></tr> </TABLE> </BODY> </HTML>

136 136 Manual de Informatică pentru clasa a XII-a Hiperlegături 1 (link-uri) Elementul A (ancoră) - începutul unei ancore este marcat prin <a>, iar sfârşitul său prin </a>. O ancoră conţine adresa URL a unei resurse oarecare aflată pe un server şi un text lămuritor (sau o imagine) asupra legăturii. Practic, se afişează, subliniat, doar textul lămuritor. Ideea de bază este următoarea: dacă se execută clic pe acest text lămuritor, resursa indicată este adusă pe calculatorul vizitatorului, opţional sau nu şi este lansat programul care prelucrează resursa respectivă. Cel mai important atribut al unei ancore este href 2 (calea către legătură, referinţa). Numeroasele exemple care vor fi date în acest paragraf vă vor lămuri asupra modului de utilizare a acestui atribut Legături către alte pagini O legătură către un fişier HTML este afişată de browser cu o altă culoare şi este subliniată. Când este deasupra ei, cursorul grafic ia forma unei mâini, indicându-ne astfel că este o legătură pe care o putem utiliza. Exemplul Mai jos, puteţi observa modul în care am scris un paragraf care conţine o legătură. Dacă se execută dublu-clic asupra ei, de pe server este adus fişierul index care va fi afişat de browser. <P>Pentru mai multe informatii,<br> <A href=" vizitati site-ul NASA</A>! </P> Figura Exemplu de paragraf care conţine o hiperlegătură De asemenea, o legătură poate fi creată şi cu ajutorul unei imagini (nu numai cu ajutorul unui text). Exemplul Analizaţi codul de mai jos: <A href=" <IMG src="racheta1.bmp"></a> 1 Termenul este o traducere a celui din limba engleză, hyperlink. Din comoditate, este utilizată forma prescurtată a acestuia: legătură ( link ). 2 Denumirea atributului este un acronim pentru Hypertext REFerence.

137 Capitolul 4 HTML, CSS - primele noţiuni Operaţia download Uneori, este necesar ca utilizatorul paginii noastre să poată descărca, dacă doreşte, anumite fişiere. Descărcarea fişierelor poartă numele de download-are, termen care provine din limba engleză. Exemplul Considerăm o pagină care va conţine legătura către fişierul care trebuie download-at ( bpro2003.zip ). Iată cum am construit ancora: <A href=" Programa la informatica </A> După ce vizitatorul execută un clic pe legătură, va apărea o cutie de dialog precum cea de mai jos: Figura Cutia de dialog File Download Prin ea, vizitatorul poate comanda ca după descărcare, fişierul să fie automat deschis (Open) cu un program care are asociată respectiva extensie (în exemplu WinRAR, pentru a-l dezarhiva) sau să fie salvat pe hard, urmând a fi utilizat mai târziu, prin comanda Save. Exemplul Presupunem că utilizatorul are pe calculatorul de pe care accesează pagina, placă de sunet şi boxe, iar placa de suet este instalată. De asemenea, presupunem că acesta are instalat un program de redare a sunetelor, cum ar fi celebrul Winamp şi că site-ul conţine fişierul Trumpet1.wav. Se pune problema ca, atunci când vizitează pagina noastră, să poată asculta, la propria comandă, anumite mesaje audio. <A href=" Sunetul unei trompete </A>

138 138 Manual de Informatică pentru clasa a XII-a La executarea unui clic pe legătură, se download-ează fişierul Trompet1.wav şi este lansat în executare programul Winamp care realizează redarea sunetelor (în particular, sunetul unei trompete). Figura Legătură către un fişier audio Exemplul Similar exemplului anterior, presupunem că avem în C:\ fişierul video Party-1.avi. Considerăm că pentru extensia.avi avem asociat programul implicit, adică Windows Media Player. Pentru a apela fişierul, vom utiliza ancora de mai jos: <A href="c:/party-1.avi"> Imagini si sunete (fisier avi) </A> Figura Legătură către un fişier video Efectul este că se lansează programul amintit şi redă fişierul Legături relative la document Uneori, documentele HTML sunt lungi şi pot fi greu parcurse de vizitator. Desigur, utilizatorul le poate parcurge cu ajutorul barelor de defilare. Există posibilitatea ca, în anumite cazuri, să-l scutim de acest efort. Pentru aceasta, vom proceda astfel: În punctele de unde dorim să fie vizualizat documentul, creăm ancore cu nume. Numele unei ancore îl vom da prin atributul id. Exemple: <A id="top"></a> (am aşezat-o în partea de sus a documentului). <A id="mijloc"></a> (am "aşezat-o la mijlocul documentului). În punctele de unde dorim ca utilizatorul să poată vizualiza imediat documentul începând de la o anumită ancoră definită anterior creăm, tot cu ajutorul unei ancore, o hiperlegătură. Exemple: <A href="#top"> in top </A> <BR> (salt în partea de sus a documentului). <A href="#mijloc"> la mijloc </A> <BR> (salt la mijlocul documentului).

139 Capitolul 4 HTML, CSS - primele noţiuni 139 Pentru a vedea pe viu cum funcţionează acest mecanism, este necesar ca fişierul să fie suficient de mare, astfel încât zona care conţine ancora destinaţie să nu fie vizibilă în momentul trimiterii. Există posibilitatea ca alte pagini către care se face trimitere să fie vizualizate începând dintr-un anumit punct, care conţine o anume ancoră. Exemplul Un alt fişier HTML conţine o ancoră către fişierul anterior (numit lung.html ): <A href="c:\lung.html#mijloc"> Salt la fisierul HTML "lung.html", la mijloc </A> Figura Exemplu de hiperlegatură spre o pagină cu ancoră relativă Observaţie! Există cărţi sau documentaţii scrise utilizând HTML-ul. În loc să avem un cost ridicat al tipăririi ei pe hârtie, se preferă scrierea ei în format HTML şi livrarea ei către cititor pe un CD. Acesta va citi cartea direct pe calculator. Vă daţi seama. că, în astfel de cazuri, referinţele relative la document devin extrem de importante. Acest procedeu este des utilizat şi în cazul documentaţiilor on-line, oferite pe Internet Trimiterea automată a unui Dorim ca o persoană să ne poată trimite un , direct din pagina noastră. Ea nu va avea decât să execute un clic pe respectiva legătură şi, imediat, se va lansa programul de trimitere a -ului, iar adresa noastră va fi trecută automat în câmpul destinatarului (To). Exemplul Pentru a obţine acest efect, pentru atributul href se va completa mailto, urmat de : şi de adresa de <ADDRESS><A href="mailto:eu@unsite.ro"> Puteti sa-mi scrieti </A></ADDRESS> Puteti sa-mi scrieti Observaţie! În ultimul timp, acest procedeu este mai puţin folosit. Anumite motoare de căutare, identifică cuvântul cheie mailto şi extrag adresa de . Ulterior, această adresă este utilizată pentru a trimite mesaje publicitare nedorite (spam). Din acest motiv, este bine să scrieţi adresa fără acest atribut, iar cei interesaţi, cu un efort suplimentar, o copiază şi vă trimit ul.

140 140 Manual de Informatică pentru clasa a XII-a Hărţi imagine Poate aţi întâlnit pe anumite site-uri o hartă. Dacă se execută click pe o anumită regiune a ei, se afişează anumite informaţii, specifice regiunii respectve, dacă se ewxecută click pe altă porţiune se afişează alte informaţii, ş.a.m.d. În acest caz s-a folosit procedeul hartă-imagine. Un alt exemplu de folosire a aceluiaşi procedeu: a pagină web în care se prezintă un anumit tip de mobilă. Dacă se dă click pe imaginea ce reprezintă un scaun, se afişează preţul scaunui, dacă se dă click pe imaginea ce reprezintă masa se afişează preţiul mesei, etc. Cum s-au obţinut aceste efecte?. Problema este următoarea: se dă o imagine şi se cere ca, prin executarea unui clic asupra unei anumite parţi a ei, să se efectueze una dintre operaţiile prezentate în paragraful anterior, prin executarea unui clic în altă parte a ei, să se efectueze o altă operaţie de acelaşi tip, ş.a.m.d. Cu alte cuvinte, trebuie să se creeze un meniu care să se prezinte sub formă de imagine. Priviţi imaginea alăturată. Ea cuprinde 4 regiuni marcate. Una sub formă de dreptunghi, alta sub formă de cerc şi două sub formă de poligoane. Dorim ca atunci când executăm clic pe una din aceste regiuni, să se execute o anumită operaţie. Browser-ul va afişa poza fără a evidenţia aceste zone, dar atunci când cursorul grafic trece deasupra unei astfel de zone, el va lua forma unei mâini şi, aşa cum am spus, executarea unui clic determină efectuarea unei operaţii specifice zonei, de exemplu vizualizarea unei pagini. Figura Exemplu de imagine care cuprinde patru zone marcate Cum se introduce în HTML o hartă imagine? Mai jos, puteţi observa modul în care au fost scrise zonele din imaginea anterioară (câinele): <HTML> <BODY> <IMG src="c:/web/caini3.jpg" usemap="#caine">

141 Capitolul 4 HTML, CSS - primele noţiuni 141 <MAP NAME="caine"> <AREA SHAPE=RECT COORDS="25,14,90,44" HREF="patrat.htm"> <AREA SHAPE=CIRCLE COORDS="36,70,23" HREF="cerc.htm"> <AREA SHAPE=POLY COORDS="185,39,193,37,204,36,221,34,244, 47,246,47,247,50,248,57,257,62,262,64,269,67,264,73,259,81, 249,82,232,78,230,79,223,87,212,87,184,80,183,66,184,57,185, 41,186,35" HREF="cap.htm"> <AREA SHAPE=POLY COORDS="116,106,112,116,110,121,110,126, 107,128,104,132,104,141,104,147,104,152,99,156,95,163,97,165, 99,165,99,169,99,180,97,188,97,193,103,192,111,190,116,192,11 9,192,119,184,123,174,123,166,126,156,128,153,131,148,132,144,132,142,132,139,134,138,138,135,138,128,143,125,150,121,150, 117,150,115,152,113,152,110,116,106" HREF="picior.htm"> </MAP> </BODY> </HTML> Din analiza exemplului de mai sus, observăm că trebuie să utilizăm următoarele elemente: Elementul MAP - cu acesta descriem o hartă, utilizând două tag-uri: <MAP> şi </MAP>. Între ele se găseşte descrierea diverselor zone care alcătuiesc harta. Elementul are următorul atribut: name - numele hărţii. El trebuie trecut în atributul usemap al elementului IMG care descrie imaginea folosită ca o hartă: <IMG src="c:/web/caini3.jpg" usemap="#caine"> Elementul AREA - are rolul de a descrie o zonă din hartă pentru care, la executarea unui clic, se produce un anumit efect. Acest element utilizează tag-ul <AREA atribute>. Principalele atribute ale elementului AREA sunt: shape descrie tipul regiunii respective; href adresa fişierului html sau a unei alte resurse (la fel ca la ancore). După cum ştim, fiecare imagine este alcătuită din pixeli. Fiecare pixel este caracterizat de două coordonate (x,y), în sistemul de axe de mai jos: 0,0 X Figura Sistemul de coordonate asociat unei imagini Y

142 142 Manual de Informatică pentru clasa a XII-a Atributul SHAPE poate lua valorile: RECT COORDS="X1,Y1,X2,Y2" dreptunghi, unde X1,Y1 reprezintă coordonatele colţului din stânga-sus şi X2,Y2 sunt coordonatele colţului din dreapta-jos. CIRCLE COORDS="X1,Y1,R" cerc, unde X1,Y1 reprezintă coordonatele centrului, iar R raza cercului. POLY COORDS="X1,Y1, X2,Y2,..., Xn,Yn" poligon, unde X1,Y1, X2,Y2,... reprezintă coordonatele vârfurilor. x1,y1 x1,y1 x2,y2 x4,y4 x1,y1 R x3,y3 x2,y2 xn,yn RECT CIRCLE POLY Figura Coordonatele celor trei forme ale atributului SHAPE Totuşi, cum au fost obţinute coordonatele punctelor? Dacă pentru dreptunghi sau cerc aceste coordonate pot fi găsite relativ uşor (de exemplu, Paint-ul afişează coordonatele cursorului), în cazul poligoanelor închise, problema devine serioasă! Din acest motiv, s-au realizat mai multe programe prin care coordonatele se obţin automat Programul Map This! Programul Map This! este destinat obţinerii automate a coordonatelor punctelor care definesc regiunile, pentru o imagine cu extensia.gif sau.jpeg. Practic, se încarcă o imagine într-unul dintre formatele enumerate anterior şi se trasează, cu mouse-ul, regiunile pe ea. Imaginea arată precum cea din Fig (câinele). După ce regiunile au fost trasate, se salvează sub formă de fişier HTML coordonatele astfel obţinute. Programul este freeware şi poate fi obţinut de pe Internet. Căutaţi-l cu GOOGLE! El ştie mai multe decât ce este prezentat în acest paragraf, dar noi ne vom limita doar la ceea ce este strict necesar! Figura Programul Map This!

143 Capitolul 4 HTML, CSS - primele noţiuni 143 1) După apelul programului, se încarcă imaginea. Apelaţi File şi New. Va apărea o cutie de tip Open, cu ajutorul căreia puteţi selecta fişierul dorit (.jpeg sau.gif). 2) Pentru a putea lucra uşor cu imaginea, puteţi folosi Zoom in (măreşte imaginea) sau Zoom out (o micşorează). Figura Butoane de marire şi micşorare a imaginii Zoom in Zoom out 3) Pentru a trasa un dreptunghi, selectaţi butonul alăturat. Apoi, selectaţi dreptunghiul dorit (ca în Paint), de la colţul din stânga-sus, către colţul din dreapta-jos. În exemplu, am selectat un dreptunghi care include cuvântul PETS. Figura Selectarea unei forme dreptunghiulare 4) Pentru a trasa un cerc, apăsaţi butonul alăturat. Apoi, selectaţi cercul dorit. În exemplu, încadrăm în cercuri capetele celor doi: Figura Trasarea unor forme circulare 5) Pentru a trasa un poligon oarecare, apăsaţi butonul alăturat şi trasaţi poligonul. Executaţi un clic în punctul de unde doriţi să începeţi trasarea. Apoi deplasaţi cursorul pe prima latură, apoi executaţi un click, deplasaţi cursorul pe a doua latură, executaţi un clic, ş.a.m.d. În final, executaţi un dublu-clic şi figura se va închide. În exemplu, am încadrat în poligon căţelul. Atenţie: pentru a obţine o cât mai fină încadrare, trasaţi laturi mici pentru poligon. Figura Trasarea unei forme poligonale

144 144 Manual de Informatică pentru clasa a XII-a 6) După ce am încadrat toate regiunile care ne interesează, putem trece la scrierea referinţei (link-ului) pentru fiecare dintre ele. Din meniu, apelaţi View şi Area List. Va apărea o listă, aşa cum este cea de mai jos. Întrucât am selectat 4 regiuni, lista are 4 elemente. Selectarea unui element al ei (în exemplul 1) are ca efect faptul că zona care îi corespunde va apărea în imagine cu o culoare diferită, pentru a le putea distinge. Figura Lista Area List Un dublu-clic în listă, pe reprezentarea unei anumite regiuni, are ca efect scrierea link-ului respectiv. În exemplul următor, comandăm browser-ului încărcarea unui anumit fişier HTML (o pagină). Procedaţi la fel pentru fiecare regiune în parte. După ce aţi terminat această operaţie, treceţi la pasul următor. Spre exemplu, pentru zona 3 (Area #3), avem: Figura Fereastra de setări a une zone 7) Urmează salvarea hărţii. Apelaţi File şi Save As. Selectaţi CSIM. Salvaţi sub formă de fişier HTML. Există posibilitatea să salvaţi într-un fişier HTML deja scris (acesta va conţine src-ul cu imaginea). Dacă salvaţi într-un fişier diferit, puteţi apoi să-l deschideţi, să selectaţi descrierea (între <MAP> şi </MAP>) şi să o includeţi în fişierul dvs. De acum, puteţi folosi fără probleme hărţi imagine. În final, câteva amănunte de lucru : Ştergerea unei regiuni. Apăsaţi butonul alăturat şi aşezaţi cursorul grafic deasupra ei. Apoi, apăsaţi butonul drept al mouse-ului. Din meniul flotant care va apărea, selectaţi Delete Area. Ştergerea unui punct al liniei poligonale. Atunci când cursorul grafic staţionează asupra sa, cursorul ia formă de cruce. Dacă se apasă butonul drept şi se selectează Delete Point, punctul va fi şters şi, deci, ignorat pentru poligon. Figura 4.72 punct şters Exerciţiu de tip referat! Întocniţi un referat despre programul Map This! sau un altul cu acelaşi rol. Este foarte important să învăţaţi să vă autoducumentaţi. Nu întotdeauna, pentru orice temă, veţi găsi o carte care s-o trateze!

145 Capitolul 4. HTML, CSS primele noţiuni Elementele BASE, META şi SCRIPT Vom prezenta în continuare câteva elemente esenţiale care pot fi scrise în cadrul antetului (HEAD), extrem de utile în foarte multe situaţii. Elementul BASE - are forma generală <BASE href="adresa"> şi are rolul de a preciza o adresă de bază pentru resurse, iar celelalte adrese se obţin adăugând după adresa de bază o adresă specifică. Tag-ul <BASE> se va scrie în antetul paginii, adică în HEAD. Exemplul Pe calculatorul meu, am câteva imagini în folder-ul C:\LaMare (1.jpg, 2.jpg, etc.). Valoarea folder-ului va fi trecută în BASE (href). De acum, pot scrie adresa pe scurt ( 1.jpg ). <HEAD> <BASE href="c:/lamare/">... <BODY>... <IMG src="1.jpg"> Observaţii! Practic, se formează C:/LaMare/1.jpg. Vă daţi seama că în acest mod pot scrie şi o adresă de internet: <BASE href = " etc. Elementul META - este folosit pentru a furniza informaţii motoarelor de căutare. Unele dintre ele vizitează doar antetul pentru a obţine informaţii. Informaţiile conţinute de acest element nu sunt afişate de browser, dar este important să-l folosim pentru ca informaţiile conţinute în site-ul nostru să fie accesibile. Tag-ul <META> se găseşte în antet (HEAD). Observaţie! În antet se pot găsi mai multe elemente META. Atributele elementului META sunt: Atributul NAME pentru el se pot utiliza câteva cuvinte cheie care vor fi prezentate în cele ce urmează. Atributul CONTENT are un conţinut variabil în funcţie de valoarea trecută pentru NAME. Cum utilizăm cele două atribute? Pentru a specifica autorul unui document: <META NAME="Author" CONTENT="Mihai Popescu">

146 146 Manual de Informatică pentru clasa a XII-a Pentru a specifica titlul unui document: <META NAME="TITLE" CONTENT="Cresterea albinelor"> Pentru a specifica cuvintele cheie după care să fie regăsit site-ul dvs. Vă daţi seama de importanţa acestora... <META NAME="KEYWORDS" CONTENT="albine, matca, trantor, stup, polen, miere"> Important! Trebuie să treceţi forma scurtă a unui cuvânt. De exemplu, dacă trec "stup", motoarele vor furniza adresa site-ului, chiar dacă o persoană caută după cuvântul cheie "stupi". Pentru a specifica limba în care este scris site-ul (este utilă în cazul căutărilor avansate). În exemplu, site-ul este scris în limba română: <META NAME="LANGUAGE" CONTENT="RO"> Pentru a specifica textul pe care îl va afişa un motor de căutare, la listarea paginilor. Dacă acesta nu este trecut, motorul va afişa primele linii din pagină, ceea ce nu e foarte relevant. <META NAME="DESCRIPTION" CONTENT="Acest site este dedicat modalitatilor de crestere a albinelor"> Observaţii importante! Există şi alte atribute ale elementului META, dar aceştia doi sunt suficienţi. Majoritatea motoarelor de căutare se bazează în principal pe aceştia: Description şi Keywords. Optimizarea site-urilor pentru motoarele de căutare (SEO Search Engine Optimization) reprezintă o unealtă indispensabilă pentru a fi eficient pe Internet. Există firme specializate care se ocupă strict de această problemă, iar preţurile sunt mari La început, cei care au realizat motoarele de căutare au vrut să ajute programatorii web prin utilizarea tag-urilor META, pentru a evidenţia mai uşor şi mai bine conţinutul paginilor. Apoi, anumite persoane au folosit acest lucru pentru a obţine un avantaj şi au introdus cuvinte care nu aveau nici o legătură directă cu paginile respective, ci doar pentru a fi listaţi mai bine. Aşadar, tag-urile META nu mai erau utile, ci doar o unealtă pentru spam (informaţie nedorită). De aceea, unele motoare au renunţat definitiv la ele, iar altele, dimpotrivă, pun paginile la sfârşitul listei dacă elementele cheie din META nu se regăsesc în conţinutul paginii. În concluzie, reţineţi: Folosiţi tag-urile META cu grijă şi nu introduceţi cuvinte ce nu sunt incluse şi în fişierul HTML. Nu repetaţi cuvintele!

147 Capitolul 4. HTML, CSS primele noţiuni 147 Elementul SCRIPT - este folosit pentru introducerea anumitor secvenţe de program în cadrul paginilor web. Există mai multe limbaje (numite de scriptare) care permit scrierea acestor secvenţe, cum ar fi JavaScript sau VBScript. Programa nu include studiul acestor limbaje Cadre (FRAMESET, FRAME şi IFRAME) Există oare posibilitatea ca aceeaşi fereastră a browser-ului să afişeze mai multe fişiere HTML (sau alte resurse) simultan? Răspunsul este afirmativ. Exemplul Priviţi imaginea din Fig.4.73: fereastra este împărţită în 4 părţi: două dintre ele afişează două fişiere HTML, iar celelalte două afişează două imagini. Blocurile în care a fost împărţită fereastra poartă denumirea de cadre (frame-uri). Figura Exemplu de pagină web împărţită în cadre Cum s-a obţinut acest efect? Înainte de a prezenta sistematic noţiunile, ca să vă faceţi o idee, priviţi fişierul HTML de mai jos: <HTML> <HEAD> </HEAD> <FRAMESET rows="30%, 70%"> <FRAME scrolling="yes" src="c:/test.html"> <FRAMESET cols="30%,30%, 40%"> <FRAME scrolling="yes" src="c:/poze/cladire.jpg"> <FRAME scrolling="yes" src="c:/poze/birou.jpg"> <FRAME scrolling="yes" src="c:/c1.html"> </FRAMESET> </FRAMESET> </HTML>

148 148 Manual de Informatică pentru clasa a XII-a Elementul FRAMESET - are rolul de a împărţi fereastra în mai multe cadre. În fişierul HTML el înlocuieşte <BODY>. Pentru a-l folosi, vom utiliza două etichetele: <FRAMESET atribute> şi </FRAMESET>. Vom studia câteva atribute ale acestui element: Rows descrie liniile în care este împărţită fereastra; Cols descrie coloanele în care este împărţită fereastra. Observaţie! În exemplul dat iniţial, fereastra este împărţită în două linii. Apoi, a doua linie este împărţită în trei coloane. Probabil că vă veţi întreba: de ce a fost împărţită a doua linie în trei coloane şi nu prima? Observaţi cum se închid tag-urile <FRAMESET> şi </FRAMESET>. Iniţial, avem două linii. Prima linie conţine un element FRAME şi a doua un element FRAMESET. Acesta din urmă declară 3 coloane, deci între tag-urile lui se vor găsi 3 elemente FRAME: <FRAMESET rows="30%, 70%"> <FRAME...> <FRAMESET cols="30%,30%, 40%"> <FRAME...> <FRAME...> <FRAME...> </FRAMESET> </FRAMESET> Figura Schema paginii obţinute Exemplul Două linii, iar prima linie este împărţită în trei coloane. Prima linie conţine un FRAMESET, a doua un FRAME: <FRAMESET rows="30%, 70%"> -<FRAMESET cols="30%,30%, 40%"> <FRAME...> <FRAME...> <FRAME...> -</FRAMESET> <FRAME...> </FRAMESET> Figura Schema paginii obţinute Pentru a stabili dimensiunile liniilor (coloanelor), există mai multe modalităţi: 1) Procentual, ca în exemplele date: <FRAMESET rows="30%, 70%"> Avem 2 linii. Prima linie ocupă 30% din înălţimea ferestrei, iar a doua, 70%. <FRAMESET cols="30%,30%, 40%"> Avem 3 coloane. Prima coloană ocupă 30% din lăţimea ferestrei, a doua 30%, iar a treia 40%.

149 Capitolul 4. HTML, CSS primele noţiuni 149 2) Proporţional: <FRAMESET cols="1*, 2*, 3*"> =6. Prima coloană ocupă 1/6 din lăţime, a doua 2/6=1/3 din lăţime, iar a treia 3/6=1/2 din lăţime. 3) Mixt: <FRAMESET cols="50%*, 1*, 2*, 200"> Prima coloană ocupă 50% din lăţime, iar ultima 200 de pixeli. Ce a rămas se împarte proporţional între coloanele 2 şi 3, deci coloana 2 ocupă 1/3 şi coloana 3, 2/3. Observaţie! În cazul în care valorile sunt incoerente, nu s-au dat norme privind modul în care trebuie procedat. Prin urmare, fiecare tip de browser va proceda în modul său specific. Încercaţi... Elementul FRAME - este utilizat pentru a preciza conţinutul unui anumit cadru. Se utilizează un singur tag: <FRAME atribute>. Iată principalele proprietăţi: src adresa fişierului HTML sau a imaginii utilizate. de exemplu, cadrul afişează un fişier HTML: <FRAME src="c:/test.html"> sau cadrul afişează o imagine: <FRAME src="c:/poze/birou.jpg"> marginheight marginile, în pixeli sau procent %, faţă de partea de sus (top) şi cea de jos (bottom); marginwidth marginile, în pixeli sau procent %, faţă de partea din stânga (left) şi cea din dreapta (right). Sus şi jos marginea este de 100 pixeli, iar în stânga şi dreapta este de 150 pixeli: <FRAME marginwidth=150 marginheight=100 src="c:/poze/cladire.jpg"> frameborder - poate lua două valori: 1 (valoare implicită) sau 0. Dacă valoarea luată de acest atribut este 0, atunci cadrul nu mai este separat de celelalte printr-un chenar. Observaţie! Dacă vrem să nu se traseze chenarul separator între două cadre, trebuie ca amândouă să aibă valoarea 0 pentru acest atribut. E logic, nu? scrolling tratează prezenţa barei de scroll (defilare). Atributul poate lua una dintre cele trei valori:

150 150 Manual de Informatică pentru clasa a XII-a 1) auto valoarea implicită. Bara de scroll este prezentă numai dacă este cazul (ce trebuie afişat în cadru ocupă o suprafaţă mai mare decât cea a cadrului); 2) yes - bara de scroll este întotdeauna prezentă; 3) no bara de scroll nu este în nici un caz afişată. noresize prezenţa sa cere browser-ului să nu permită vizitatorului paginii respective să redimensioneze cadrul. Dacă este prezent pentru un cadru, atunci nu pot fi redimensionate nici cadrele învecinate.? name are rolul de a atribui un nume elementului FRAME. Probabil că vă veţi întreba: la ce foloseşte numele unui cadru? Ei bine, rolul este uriaş. Mai precis, dintr-un cadru, se poate comanda conţinutul oricărui cadru (inclusiv al cadrului curent). Exemplul Browser-ul afişează două cadre. Primul dintre ele conţine link-urile pentru capitolele unei cărţi. Al doilea, iniţial, afişează paragrafele primului capitol. La comanda vizitatorului paginii respective, se pot afişa, în al doilea cadru, paragrafele oricărui alt capitol. Figura Pagina propusă pentru Exemplul 4.57 Iată fişierul HTML iniţial, cel care creează cadrele şi în care unul dintre ele este numit cpt : <HTML> <HEAD> </HEAD> <FRAMESET cols="30%*, 70%"> <FRAME src="c:/ancore.html"> <FRAME name="cpt" src="c:/c1.html"> </FRAMESET> </HTML> Primul cadru afişează următorul fişier HTML:

151 Capitolul 4. HTML, CSS primele noţiuni 151 <HTML> <HEAD> </HEAD> <BODY> <A href="c:/c1.html" target="cpt"> Capitolul 1 </A> </br> <A href="c:/c2.html" target="cpt"> Capitolul 2 </A> </br> <A href="c:/c3.html" target="cpt"> Capitolul 3 </A> </BODY> </HTML> Fişierul de mai sus conţine trei ancore. Pentru fiecare ancoră s-a folosit un atribut nou, numit target. Acesta are rolul de a preciza ţinta, adică numele cadrului care va afişa fişierul HTML cerut. Observaţie! În absenţa atributului target, fişierul va fi afişat în cadrul care conţine ancora! Elementul IFRAME - permite crearea unui cadru în corpul (BODY) documentului. Cu alte cuvinte, cadrele se pot folosi şi în mod clasic. Pentru a-l descrie, se folosesc etichetele <IFRAME atribute> şi </IFRAME>. Exemplul Mai jos, un cadru conţinut de un document afişează un fişier HTML: <HTML> <HEAD></HEAD> <BODY> <P>Acesta este un paragraf</p> <IFRAME SRC="C:/c1.html"> </IFRAME> </BODY> </HTML> Figura Exemplu de pagină cu un cadru în interiorul corpului documentului Atributele elementului <IFRAME> sunt: name numele, am văzut care este rolul lui; frameborder poate lua valoarea 0 sau 1, la fel ca pentru elementul FRAME; src adresa fişierului HTML sau a imaginii utilizate; scrolling la fel ca orice cadru. Elementul NOFRAMES - este cuprins între tag-urile <NOFRAMES> şi </NOFRAMES>. În cazul în care browser-ul vizitatorului x nu poate afişa cadre, se utilizează pentru a scrie tag-urile HTML alternative. Ce-i drept, acest lucru se întâmplă din ce în ce mai rar (fabricanţii de soft s-au adaptat cerinţelor). De regulă, în acest caz, se vor utiliza <BODY> şi câteva ancore (câte una pentru fiecare cadru).

152 152 Manual de Informatică pentru clasa a XII-a Elementul MARQUEE Acesta creează un bloc în care elementele introduse între etichetele <MARQUEE> şi </MARQUEE> se mişcă într-o anumită direcţie. Acest efect se numeşte Scrolling Display şi poate fi util la afişarea anunţurilor (publicitare): Figura Efect obţinut cu ajutorul elementului MARQUEE Codul pentru a obţine animaţia de mai sus este: <MARQUEE>Salut! Uite masina mea! <IMG src="masina.jpg"> </MARQUEE> Se observă că elementul este la nivel de text, imaginea fiind aliniată cu textul introdus. Oricum, trebuie folosit cu grijă şi cu gust pentru că poate obosi vizitatorul cu prea multă mişcare... Cele mai importante atribute ale acestui element sunt: Direction direcţia de mişcare a blocului ("Left" sau "Right"). Valuarea implicită este dinspre stânga ("Left"). Behavior tipul de scroll aplicat. Poate lua valorile: Scroll valoare implicită - conţinutul se mişcă de la o margine la alta şi apoi reapare; Slide când se atinge marginea opusă (cea indicată de atributul Direction), mişcarea se opreşte; Alternate conţinutul se mişcă alternativ între cele două margini şi este întotdeauna vizibil. Scrolldelay timpul de tranziţie al elementelor de la o poziţie la alta (în milisecunde, valoarea implicită este de "85"). Astfel, stabilim viteza cu care se derulează animaţia : cu cât această valoare este mai mare, cu atât vom avea o tranziţie mai lentă a conţinutului. De exemplu: <MARQUEE Scrolldelay="500"> (jumătate de secundă).

153 Capitolul 4. HTML, CSS primele noţiuni 153 Scrollamount se setează numărul de pixeli cu care se mută conţinutul blocului, la fiecare pas. O valoare mai mare implică o viteză mărită de mişcare. Valoarea implicită este "6". De exemplu: <MARQUEE Scrollamount="10">. Loop numărul de cicluri pe care să le efectueze conţinutul. Implicit, valoarea este "INFINITE" (la nesfârşit). O problemă ar fi faptul că după terminarea ultimului ciclu, conţinutul dispare. Se poate rezolva însă cu atributul Behavior, specificând ca la ultimul ciclu să se oprească atunci când atinge marginea respectivă (cu "Slide"): De exemplu: <MARQUE Loop="3" Behavior="Slide">Salutare!</MARQUEE> Aşezarea implicită în pagină a diverselor elemente O întrebare foarte importantă: cum aranjează browser-ul în pagină diversele elemente (imagini, paragrafe, tabele, etc.)? Vă daţi seama de importanţa ei: orice creator de pagini web doreşte să amplaseze elementele care alcătuiesc o pagina într-un anumit fel... În HTML, există două tipuri de elemente: elemente la nivel de bloc şi elemente la nivel de text (inline). A) Elementele la nivel de bloc sunt aşezate pe rând nou. Exemple de elemente la nivel de bloc: P (paragraf), TABLE (tabel), TR (linie de tabel) H1..H6, OL, LI, UL (liste), DL, DT, DD (itemi din liste). B) Elemente la nivel de text (inline). Acestea se scriu pe linia curentă, în continuare. Exemple de elemente la nivel de text: B (bold), I (italic), IMG (imagini), DEL, DFN, etc. Exemplul Analizaţi codul sursă de mai jos: <HTML> <HEAD> <STYLE> IMG {width:3cm; height:4 cm; </STYLE> </HEAD>

154 154 Manual de Informatică pentru clasa a XII-a <BODY> <P> Acest paragraf este scris pentru a verifica modul de aliniere pe orizontala in cazul unui element IMG, care este de tip INLINE <IMG src="eric.jpg", alt="eric">, deci se insereaza exact ca un cuvant intr-un paragraf</p> <P> Paragraful este un element de tip BLOC, asa ca se insereaza pe o linie noua!</p> </BODY> </HTML> Figura Pagina web obţinută

155 Capitolul 4. HTML, CSS primele noţiuni Alte modalităţi de aşezare în pagină a elementelor În CSS există posibilitatea să se aşeze elementele în poziţiile dorite (alta decât cea în cazul fluxului normal). Această posibilitate este dorită de mult timp de către creatorii de pagini WEB. O astfel de aşezare se poate face prin utilizarea atributului position, care poate lua mai multe valori: static implicit aşezarea se face în flux normal; absolute aşezare în poziţii absolute există, totuşi, anumite nuanţe, motiv pentru care vom da mai multe exemple pentru a vă lămuri. Exemplul Un paragraf şi un tabel sunt aşezate în flux normal. O celulă a tabelului conţine o imagine: <P> Un text oarecare <TABLE border=3> <TR> <TD> A11 </TD> <TD id="tata"> <IMG src="c:\poze\cladire.jpg"></td></tr> <TR> <TD> A21 </TD> <TD> A22 </TD></TR> </TABLE> Figura Pagina web Exemplul Adăugăm componentei IMG un stil, prin care-i precizăm poziţia. Poziţia este dată în pixeli prin atributele top şi left. În acest caz, deplasarea este dată faţă de colţul din stânga-sus al ferestrei: <STYLE> IMG {position:absolute; left:30; top:50; </STYLE>... <P> Un text oarecare <TABLE border=3> <TR> <TD>A11</TD> <TD id="tata"> <IMG src="c:\poze\cladire.jpg"></td></tr> <TR> <TD>A21</TD> <TD>A22</TD></TR> </TABLE> Figura Pagina web Pare simplu, nu-i aşa? În realitate, lucrurile sunt puţin mai complicate. Aceasta se întâmplă atunci când elementul părinte este poziţionat în flux normal.

156 156 Manual de Informatică pentru clasa a XII-a Exemplul Elementul părinte al lui IMG este elementul TD (nu TABLE). Poziţionăm absolut şi elementul TD. Observăm că, în acest caz, elementul apare în afara tabelului, iar IMG este poziţionat relativ faţă de TD (vezi Fig. 4.82). <STYLE> IMG { position: absolute; left:30; top:50; #Parinte_TD { position:absolute; top:100; left:100; </STYLE>... <P> Un text oarecare <TABLE border="3"> Figura Pagina web <TR> <TD> A11 </TD> <TD id="parinte_td"> <IMG src="c:\poze\cladire.jpg"> A21 </TD> </TR> <TR> <TD>A21</TD> <TD>A22</TD> </TR> </TABLE>... Ideea de bază este următoarea: dacă un element este poziţionat absolut şi dacă părintele său, părintele părintelui,... sunt poziţionate în flux normal, atunci elementul este poziţionat în raport de colţul din stânga-sus al ferestrei. Dacă parintele este poziţionat absolut, atunci elementul este poziţionat relativ faţă de părinte. Exemplul De această dată, poziţionăm absolut tabelul şi imaginea. Aşa cum era de aşteptat, imaginea se aliniază în raport de colţul tabelului. <STYLE> IMG { position: absolute; left:30px; top:50px; TABLE { position:absolute; top:100px; left:100px; </STYLE> </HEAD> <BODY> <P> Un text oarecare <TABLE border=3>... Figura Pagina web Observaţie! Pentru poziţionarea absolută, orice element poziţionat în flux normal se consideră că se află la coordonatele (0,0) faţă de părintele său. Cu această constatare, un element este poziţionat, de fapt, relativ faţă de părinte.

157 Capitolul 4. HTML, CSS primele noţiuni 157 relative spre deosebire de poziţionarea absolută, în cazul poziţionării relative, un element este poziţionat în raport de elementul părinte, chiar şi în cazul în care acesta din urmă este pozionat în flux normal. Exemplul Mai jos, elementul IMG este poziţionat relativ faţă de elementul părinte (TD): <HTML> <HEAD> <STYLE> IMG { position: relative; left:30px; top:50px; </STYLE> </HEAD> <BODY> <P> Un text oarecare <TABLE border="3"> Figura Pagina web <TR> <TD>A11</TD> <TD id="parinte_td"> <IMG src="c:\poze\cladire.jpg"> A21 </TD> </TR> <TR> <TD>A21</TD> <TD>A22</TD> </TR> </TABLE> </BODY> </HTML> Observaţie! Atributele pot lua şi valori negative Atributul z-index Din studiul mecanismului de poziţionare a elementelor s-a putut distinge faptul că există posibilitatea ca anumite elemente să fie afişate suprapus. Pe de o parte, dacă nu dorim ca acest lucru să se întâmple, trebuie să fim atenţi la scrierea coordonatelor, dar, pe de altă parte, putem face ca această posibilitate să lucreze în interesul nostru. Mai mult, prin intermediul atributului z-index, putem controla ordinea de afişare a elementelor suprapuse. Exemplul Un tabel are culoarea de fond galbenă, un altul are culoarea albastră, iar în rest sunt identice. Primul tabel reţine pentru z-index, 1, iar al doilea, 2. Cele două tabele sunt afişate parţial suprapus, dar deasupra se găseşte cel care pentru z-index reţine 2 (vezi Fig a). Dacă se inversează valorile reţinute de z-index pentru cele două tabele, atunci tabelele sunt afişate în ordine inversă (vezi Fig b).

158 158 Manual de Informatică pentru clasa a XII-a a) b) Figura Ordinea tabelelor în funcţie de atributul z-index <HTML> <HEAD> <STYLE> #tabel1 { position: absolute; top:100; left:100; background-color:blue; z-index:1; #tabel2 { position: absolute; top:120; left:120; background-color:yellow; z-index:2; </STYLE> </HEAD> <BODY> <TABLE id="tabel1" border="3"> <TR> <TD> A11 </TD> <TD> <IMG src="c:\poze\cladire.jpg"> A21 </TD> </TR> <TR> <TD> A21 </TD> <TD> A22 </TD> </TR> </TABLE> <TABLE id="tabel2" border="3"> <TR> <TD> A11 </TD> <TD> <IMG src="c:\poze\cladire.jpg"> A21 </TD> </TR> <TR> <TD> A21 </TD> <TD> A22 </TD> </TR> </TABLE> </BODY> </HTML>

159 Capitolul 4. HTML, CSS primele noţiuni Atributul display Am învăţat faptul că în HTML există elemente de tip bloc (block), care se afişează la început de rând şi singure pe linie şi elemente de tip text (inline) care se afişează în continuarea rândului curent. Există posibilitatea de a schimba modul implicit de afişare, prin utilizarea atributului diplay. Acesta poate lua următoarele valori: Block elementele se afişează la început de rând. Exemplul Un element de tip bold va fi afişat block, deşi, implicit, se afişează inline: <HTML> <HEAD> <STYLE> B { display:block; </STYLE> </HEAD> <BODY> <P> Un <B>text</B> oarecare</p> </BODY> </HTML> Figura Element de tip bold afişat la început de rând Inline elementele se afişează în continuarea rândului curent. Exemplul Implicit, paragrafele se afişează la început de rând (block). De această dată, se afişează inline: <HTML> <HEAD> <STYLE> P { display:inline; </STYLE> </HEAD> <BODY> <P> Un text oarecare </P> <P> Alt text oarecare </P> </BODY> </HTML> Figura Element de tip paragraf afişat în continuarea randului curent none elementul (elementele) nu se va afişa.

160 160 Manual de Informatică pentru clasa a XII-a Caractere HTML În HTML există posibilitatea de introducere a caracterelor prin codul lor. Astfel, putem folosi şi caractere care nu se obţin direct de la tastatură, cum ar fi: semne matematice, litere greceşti, litere specifice limbii române, etc. Exemplul Pentru texte în limba română, putem introduce diacritice: "Mama merge la piaţă" Mama merge la piaţă "Ţara mea este România" Ţara mea este România "O şopârlă" O şopârlă Exemplul Pentru texte (formule) matematice : "Aria cercului este πr 2 " Aria cercului este &#960R;<SUP>2</SUP> "sin(ωt) " sin(ωt) Exemplul Pentru semne speciale (se pot lăsa mai multe spaţii între cuvinte): " Nu mai copiaţi..." Nu mai copiaţi... "Mama merge!" mama merge Observaţie! Prin folosirea spaţiului, browser-ul nu va pune cele două cuvinte pe linii diferite! Exemplul Evitarea confuziei de caractere pe care o poate face browser-ul (caracterul "<" are un anumit sens în HTML). Se afişează într-un paragraf, "m<v": <P> m<v </P>. Mai multe caractere puteţi găsi în Anexa 3. Aplicaţie. Realizaţi pagina web de mai jos: Figura Pagină cu caractere româneşti

161 Capitolul 4. HTML, CSS primele noţiuni Aspecte generale ale proiectării interfeţelor web Problema la care încercăm să răspundem în acest paragraf este următoarea: cum este bine să arate o pagină web? Vă daţi seama că, la această întrebare, nu se poate da un răspuns precis, dar se pot prezenta anumite reguli de care este bine să ţineţi cont. Cel mai important este conţinutul paginii, care trebuie să fie actualizat frecvent - el este cel care determină ca respectiva pagină să fie vizitată! Haideţi să pornim de la un exemplu simplu: ştim noţiunile de bază ale limbajului HTML şi un fotograf profesionist apelează la noi pentru un site care să-i descrie simplu şi la obiect activitatea. Deoarece clientul nostru nu este şi nici nu este necesar să fie familiarizat cu elementele tehnice, trebuie să-l întrebăm ce informaţii doreşte să fie incluse pe site. În mod evident, acesta ne va spune că doreşte să-şi prezinte lucrările anterioare (portofoliul), datele de contact, eventual o scurtă descriere a sa şi a echipamentului pe care-l utilizează şi onorariul pentru diversele servicii pe care le oferă. Reţinem toate informaţiile amintite anterior şi îi cerem, de asemenea, o serie de fotografii pe care le consideră reprezentative. Să trecem la treabă! În primul rând, informaţiile trebuie să fie bine structurate, pentru ca vizitatorul să nu piardă timp la identificarea acestora. Din prima discuţie cu clientul, am obţinut structura site-ului ne trebuie o pagină separată pentru fiecare categorie: 1. descrierea fotografului şi a activităţii pe care o profesează; 2. portofoliul care cuprinde o serie de fotografii de la diverse evenimente; 3. datele tehnice privitoare la dispozitivele fotografice, la studio, etc.; 4. preţurile în funcţie de serviciile oferite; 5. datele de contact (telefon fix, mobil, , adresa studioului, etc.); Pentru a nu plictisi potenţialii vizitatori, pe pagina principală a site-ului (index-ul) vom introduce prima categorie de informaţii, care vor oferi o prezentare generală a activităţii clientului. De asemenea, accesul la celelalte pagini trebuie să fie facil, de unde rezultă necesitatea unui meniu format din hiperlegături către acestea. Site-ul web trebuie să urmărească un anumit tipar, pentru a oferi unitate şi continuitate interfeţei. Rezultă că toate paginile trebuie să aibă părţi comune, cum ar fi un antet, aceeaşi culoare de fond, acelaşi font, etc., iar meniul menţionat anterior trebuie să fie prezent pe fiecare pagină. Multe ar putea fi spuse aici de exemplu, aveţi grijă să: evitaţi culorile stridente sau nepotrivite, animaţiile în exces şi mesajele prin care i se explică vizitatorului că, apelând la serviciile oferite, a dat norocul peste el ;

162 162 Manual de Informatică pentru clasa a XII-a verificaţi din când în când dacă link-urile externe (care sunt binevenite) spre paginile web indicate de acestea mai există sau nu; nu utilizaţi diverse efecte vizuale sau sonore, doar pentru a arăta vizitatorlui ce grozavă este echipa care a creat site-ul important este ca ele să aibă sens în contextul paginii. Ar fi dificil de prezentat modul de implementare complet al unui site web pentru că necesită o multitudine de linii de cod şi ferestre. Pur didactic, prezentăm o variantă mult simplificată a site-ului (pagina de contact), în figura de mai jos: Figura Exemplu simplu de site web Titlul Daniel Andone fotograf profesionist (element H2), poza din colţul din dreapta-sus, meniul (tabel cu cinci coloane), culoarea de fond şi zona de text (în figură, un tabel cu patru linii) se repetă pe fiecare pagină a site-ului, pentru a oferi continuitate navigării. Practic, putem avea patru pagini aproape identice, singura diferenţă fiind textul din zona de culoare albă. Observaţie! Tabelul care conţine informaţiile poate fi înlocuit cu un cadru de tip IFRAME sau, de ce nu, toată pagina poate fi structurată cu ajutorul frame-urilor. Bineînteles, acest exemplu este rudimentar şi trebuie luat ca atare. Dvs. puteţi realiza pagini mult mai complexe, utilizând noţiunile prezentate în cadrul acestui capitol.

163 Capitolul 4. HTML, CSS primele noţiuni 163 Un ultim pas, foarte important, pe care-l aveţi de făcut este testarea cu atenţie a documentului realizat. Nimic nu este mai deranjant decât o pagină care nu poate fi deschisă sau o imagine care nu poate fi afişată denotă lipsă de profesionalism din partea realizatorului. Bineînţeles, nimeni nu este prefect! Codul sursă pe care l-aţi implementat trebuie să fie bogat în comentarii cât mai sugestive, pentru că, de cele mai multe ori, persoana care realizează site-ul web nu este şi cel care-l întreţine în mod curent. Vă daţi seama cât de dificil ar fi să caute prin sute de linii de cod sau să incerce să înţeleagă mecanismul dezvoltat de dvs. Se pot realiza minuni prin utilizarea programelor profesioniste de prelucrare a imaginilor, cum ar fi Adobe Photoshop sau Corel. De asemenea, o animaţie haioasă dezvoltată cu programul Adobe (Macromedia) Flash poate să capteze atenţia vizitatorilor în mod favorabil. Merită măcar o încercare Poţi fi un excelent programator web, dar dacă nu ai o anumită înclinaţie artistică, nu vor ieşi din mâinile tale pagini frumoase. Apelează, dacă este cazul, la persoane care au această înclinaţie artistică. Pentru a crea o pagină web, avem nevoie de limbajul HTML care ne permite introducerea elementelor de bază, iar cu ajutorul CSS-ului, acestea pot fi personalizate din punct de vedere al aspectului sau a poziţiei în cadrul documentului. Mai jos, sunt prezentate principalele elemente HTML: Nume element(e) <HTML> şi </HTML> <HEAD> şi </HEAD> <BODY> şi </BODY> <STYLE> şi </STYLE> <TITLE> şi </TITLE> <P> şi </P> <BR> Descriere indică începutul şi sfârşitul documentului web indică începutul şi sfârşitul antetului indică începutul şi sfârşitul corpului paginii în interiorul lor, se descriu stilurile pentru elemente în interiorul lor, se introduce titlul paginii web indică începutul şi sfârşitul unui paragraf forţează trecerea pe linia următoare

164 164 Manual de Informatică pentru clasa a XII-a &nbsp <B> şi </B> <I> şi </I> <U> şi </U> <S> şi </S> <TT> şi </TT> <SUP> şi </SUP> <SUB> şi </SUB> <H1> şi <H/1>,, <H6> şi </H6> <OL> şi </OL> <UL> şi </UL> <LI> şi </LI> <DL>, <DT> şi <DD> <IMG src=" "> <TABLE> şi </TABLE> <TR> şi </TR> <TD> şi </TD> evită trecerea unui cuvânt pe linia următoare textul din interiorul lor este scris îngroşat textul din interiorul lor este scris înclinat textul din interiorul lor este scris subliniat textul din interiorul lor este scris tăiat textul din interiorul lor este scris monospaţiat textul din interiorul lor este scris ca exponent textul din interiorul lor este scris ca indice definesc titluri de diferite dimensiuni descriu o listă ordonată descriu o listă neordonată descriu un element al listei introduc o listă de definiţii introduce imaginea indicată prin parametrul src indică începutul şi sfârşitul unui tabel indică începutul şi sfârşitul unei linii din tabel indică începutul şi sfârşitul unei coloane din tabel <A href=" "> şi </A> hiperlegătură spre resursa indicată de atributul href <MAP> şi <AREA> <BASE href=" "> <META> <FRAMESET> şi </F > <FRAME> şi </FRAME> <IFRAME> şi </IFRAME> <NOFRAME> şi </N > <MARQUEE> şi </M > descriu o hartă imagine şi o zonă din ea defineşte adresa de bază pentru resurse furnizează diverse informaţii motoarelor de căutare împarte pagina în mai multe cadre precizează conţinutul unui cadru creează un cadru în corpul documentului conţinut alternativ al unui cadru defineşte un bloc care defilează conţinutul său Tabelul 4.1. Principalele elemente HTML

165 Capitolul 4. HTML, CSS primele noţiuni 165 Fiecare element poate fi personalizat prin intermediul limbajului CSS, definind stilul corespunzător între tag-urile <STYLE> şi </STYLE>. Putem defini o clasă de stiluri (atributul class) sau un stil individual (atributul id). Pentru un element, putem defini poziţia sa în cadrul paginii web: - aşezare implicită: la nivel de bloc (block) sau la nivel de text (inline); - prin CSS, cu ajutorul atributului position, care poate lua valorile: static implicit aşezarea se face în flux normal; absolute aşezare în poziţii absolute; relative în raport cu elementul părinte; - definirea ordinii de afişare prin intermediul atributului z-index. Modul implicit de afişare (block sau inline) se poate modifica prin utilizarea atributului display, pus la dispoziţie de limbajul CSS. La proiectarea unei interfeţe web, ţineţi minte că o structură bine definită, bazată pe simplitate şi care să ofere accesul rapid la informaţie poate fi cheia succesului. De asemenea, încercaţi să-i daţi o formă cât mai elegantă şi cu bun gust! 1. Cum se scrie pagina din figura alăturată? Figura Pagina propusă

166 166 Manual de Informatică pentru clasa a XII-a 2. Cum trebuie procedat pentru ca o pagină să arate ca alăturat? Figura Pagina propusă ca exerciţiu 3. Cum realizăm tabelul alăturat? Figura Pagina propusă 4. Presupunem că doriţi să prezentaţi un calculator. Pagina va cuprinde atât fotografia calculatorului cât şi un nume pentru el (vezi Fig. 4.93). Atunci când vizitatorul execută clic, fie pe imagine, fie pe text, trebuie ca browser-ul să afişeze o altă pagină cu detalii tehnice şi explicaţii suplimentare. Testul îl veţi face pe calculatorul dvs. (dar nimeni nu vă opreşte să-l puneţi şi pe site). Figura Exemplu de pagină 5. Puneţi pe pagină o astfel de imagine (din Yahoo) şi un mesaj. Dacă vizitatorul paginii execută clic, fie pe mesaj, fie pe imagine, va fi apelat programul de şi va putea să vă scrie, fără să mai completeze adresa! Figura Exemplu pentru exerciţiul 5 6. Doriţi ca vizitatorii site-ului dvs. să poată download-a o documentaţie pe care o aveţi acolo sub forma unui fişier word (extensia.doc). Cum trebuie să procedaţi? 7. Presupunem că trebuie să realizaţi o prezentare a animalelor domestice. Pagina principală va arăta ca în Fig. 4.95:

167 Capitolul 4. HTML, CSS primele noţiuni 167 Figura Pagina principală a prezentării Un alt fişier HTML (să-l numim lung.html ) va reţine, unul după altul, textele despre fiecare animal în parte. Se cere ca, atunci când vizitatorul execută clic pe Continuare, pentru un anumit animal, să apară direct textul corespunzător în fereastra care afişează textele. Mai jos, puteţi observa ce se afişează atunci când acesta execută clic pe Continuare la descrierea câinelui: Figura Descrierea câinelui din pagina lung.html 8. Cum trebuie procedat ca o ancoră să arate ca mai jos (culoarea este roşie)? Figura Ancora propusă 9. Doriţi să creaţi un site cu mai multe imagini grupate pe teme (flori, case, etc). Pentru aceasta, pagina principală va conţine două cadre, aşa cum se vede în Fig În primul dintre ele, aveţi ancore către documentele HTML care conţin imaginile dintr-o anumită categorie. În al doilea cadru, veţi afişa fişierul dorit de utilizator. Imaginile trebuie să fie aliniate în partea de jos. Figura Site-ul propus pentru problema 9

168 168 Manual de Informatică pentru clasa a XII-a 10. La fel ca la problema anterioară, numai că imaginile trebuie să arate ca în figura de mai jos: Figura Exemple de imagini pentru problema Lucru în echipă. Prin utilizarea cunoştinţelor dobândite până în acest moment, realizaţi un site pe o temă la alegere. Formaţi grupe de 2-4 elevi care să-şi împartă atribuţiile: un elev să se ocupe cu design-ul site-ului şi unul, doi sau trei elevi să caute documentaţie despre tema propusă (text, imagini sugestive, etc.). Unul dintre elevi, pe lângă atribuţiile sale, va avea rolul de coordonator al proiectului, iar un altul, se va ocupa la final de testarea site-ului realizat. Posibile teme: Sistemul nostru solar : descrierea fiecărei planete, elemente de teorie din astronomie, etc. Echipa de fotbal favorită : informaţii despre fiecare jucător, o listă cu titlurile câştigate, meciuri importante, etc. Clasa noastră. Adunaţi câteva informaţii despre fiecare elev şi realizaţi un site despre clasa voastră. Fiţi inventivi! Se pot realiza clasamente după o mulţime de criterii sau puteţi descrie anumite evenimente amuzante care s-au petrecut în trecutul vostru. Ştiinţa înainte de toate!. Prezentaţi un om de ştiinţă important: biografia sa, poze, lucrări importante şi citate (de exemplu, puteţi alege dintre: Albert Einstein, Sir Isaac Newton, Gregor Mendel, Marie Curie, etc.). Istorie. Realizaţi o pagină web despre ziua în care România a devenit un stat independent, în urma bătăliei de la Plevna. Geografie. Prezentaţi în detaliu, sub forma unui site web, grupările muntoase din ţara noastră, specificând informaţii semnificative despre fiecare în parte. Biologie. Creaţi un site care să prezinte într-o formă amuzantă evoluţia omului pe Pământ!

169 CAPITOLUL Limbajul PHP În acest capitol studiem limbajul PHP. După ce-l vom parcurge, vom şti să trimitem date de pe calculatorul client către server şi vom şti să le prelucrăm pe server. Vom cunoaşte cum să personalizăm paginile web, în funcţie de persoana care le accesează, dar adevărata forţă a limbajului se va vedea atunci când îl vom folosi la un loc cu limbajul MySQL. Introducere Cum realizăm un formular? Constante, variabile, operatori Care sunt instrucţiunile limbajului PHP? Funcţii PHP Funcţii matematice Cum afişăm datele? Funcţii pentru prelucrarea şirurilor de caractere Masive în PHP Ce sunt variabilele cookie? Cum le folosim? Utilizarea în comun a limbajelor PHP şi MySQL Aplicaţii Cuvinte cheie: formulare, input, submit, radio, checkbox, password, textarea, select, constante, variabile, operatori, echo, print, instrucţiuni, funcţii, masive, cookie, securitate

170 170 Manual de Informatică pentru clasa a XII-a 5.1. Introducere Numele limbajului era iniţial un acronim pentru Personal Home Page şi a fost inventat în 1994 de Rasmus Lerdof, care dorea să-şi contorizeze vizitatorii paginii sale de Internet. Astăzi, se cosideră că PHP este un limbaj de scriptare înglobat în HTML. Documentaţia oficială a limbajului se găseşte pe site-ul Script-urile scrise în acest limbaj se utilizează pe partea de server. Limbajul PHP este asemănător limbajului C. Script-urile scrise în acest limbaj rulează şi trebuie să se găsească pe server. În linii mari, ele au rolul de a prelucra datele pe care le trimite utilizatorul de pe propriul calculator şi de a transmite către browser rezultatele prelucrărilor. Nu toate site-urile permit utilizarea limbajului PHP. Din acest motiv, dacă vă interesează să-l utilizaţi, trebuie să studiaţi cu atenţie oferta de site-uri a firmei la care apelaţi (provider-ul). În ceea ce ne priveşte, pentru a învăţa limbajul PHP vom utiliza pachetul EasyPHP (vezi Anexa 1) care ne permite să rulăm PHP pe propriul calculator. Nu uitaţi, înainte de orice, lansaţi în executare programul EasyPHP din meniul Start/Programs! Practic, orice script PHP va fi memorat în subfolder-ul www al folder-ului EasyPHP1-8 din Program Files şi va fi apelat din browser prin Orice script PHP va avea extensia php. În situaţia în care rulaţi pe un site real, după ce creaţi şi testaţi script-urile pe propriul calculator, cu EasyPHP, le puteţi transfera pe server cu ajutorul unui program FTP. Orice script PHP este cuprins între: <?php...?> Exemplul 5.1. Script-ul de mai jos afişează un mesaj. Îl vom memora în www sub numele de "primul.php". Apelul şi rezultatul se pot observa alăturat. <?php echo "eu sunt primul script php";?> Figura 5.1. Rezultatul

171 Capitolul 5. Limbajul PHP 171 Observaţie foarte importantă! Atunci când se apelează un script, el este rulat pe server. Acesta va efectua operaţiile pe care le are programate şi eventual, va scrie ceva (de exemplu, ca în exemplul următor, cu "echo"). Rezultatul (adică ce este scris) este returnat către browser, iar acesta îl va trata ca pe un fişier html. Exemplul 5.2. Rulăm script-ul de mai jos care conţine câteva elemente de formatare. Rezultatul îl vedem în figura alăturată: <?php echo "eu sunt <B>primul</B><BR> script<b>php</b>";?> Figura 5.2. Rezultatul rulării Exemplul 5.3. Acelaşi script poate fi apelat şi ca un link, aşa cum observaţi mai jos (fişierul html putând fi plasat oriunde): <HTML> <HEAD></HEAD> <BODY> <P> Un text oarecare! <A href=" </BODY> </HTML> Exemplul 5.4. Script-urile PHP pot conţine direct elemente de HTML, pe lângă secvenţa propriu-zisă, PHP. Scrieţi script-ul următor în www şi apelaţi-l. Veţi vedea că se afişează conţinutul unei variabile PHP (variabilele PHP vor fi tratate separat). La apel se afişează "Bine ati venit domnule Ion Popescu!". <HTML> <HEAD> </HEAD> <BODY> <P> Bine ati venit domnule <?php $nume=" Ion Popescu!"; echo ($nume);?> </BODY> </HTML>

172 172 Manual de Informatică pentru clasa a XII-a 5.2. Formulare De la început trebuie spus că formularele sunt elemente ale limbajului HTML. Un formular este o grupare de componente HTML care permit trimiterea datelor şi a comenzilor către server. Pe server, comenzile sau datele sunt recepţionate de un script PHP care răspunde comenzilor şi prelucrează datele. Un formular se descrie între tag-urile <FORM action script> şi </FORM>. Prin script înţelegem numele script-ului care se rulează atunci când datele, comenzile sosesc pe server. Între cele două tag-uri se inserează diferite componente care permit introducerea datelor sau trimiterea comenzilor. Elementul INPUT este un element HTML de o mare complexitate. Poate fi de diverse tipuri (type): de la un buton de validare, la unul radio, un edit, etc. După cum sugerează şi numele, rolul elementului INPUT este de a permite utilizatorului să introducă date sau comenzi în pagina vizualizată de browser. Un element INPUT se descrie cu tag-ul următor (formă simplificată): <INPUT name="nume" type="tip" value="valoare" align="tip_aliniere"> unde valoare exprimă valoarea afişată de element Tipul submit Are aspectul unui buton. La apăsarea lui, datele sunt transmise către server, de unde, evident, răspunde un script care are rolul de a le prelucra. Exemplu 5.5. Nu se transmit date, dar la apăsarea butonului de tip submit se lansează un script care afişează un mesaj: <HTML> <HEAD> </HEAD> <BODY> <FORM action=" <INPUT type="submit" value="primul exemplu de apel PHP"> </FORM> </BODY> </HTML> Alăturat, observaţi cum este afişată sursa HTML de către browser: Figura 5.3. Fişierul HTML

173 Capitolul 5. Limbajul PHP 173 Iată şi script-ul PHP: <?php echo ("Ai apasat, am raspuns");?> Figura 5.4. Mesajul afişat În urma rulării, browser-ul afişează mesajul (vezi Fig. 5.4) Tipul text Este sub forma unui edit şi permite utilizatorului să introducă date. Acestea se trimit către browser la apăsarea unui buton de tip submit. Pentru ca datele să fie recuperate de către script-ul de pe server, trebuie ca tag-ul <form> să conţină parametrul method ="post". Atunci când browser-ul execută o cerere către server, trimite şi valorile reţinute de cele două input-uri de tip text. Variabila $_POST este un vector asociativ 1 care reţine toate valorile astfel transmise. Valoarea transmisă de input-ul de tip text numit a se recuperează prin $_POST[ a ], cea transmisă de input-ul de tip text b se recuperează prin $_POST[ b ]. Această modalitate de transmitere şi recepţionare a parametrilor este generală şi trebuie reţinută. Exemplul 5.6. Vizitatorul trimite două valori numerice a şi b. Script-ul PHP returnează suma lor: <HTML> <HEAD> </HEAD> <BODY> Figura 5.5. Exemplu de formular <FORM action=" method ="post"> <INPUT type="text" name="a"><br> <INPUT type="text" name="b"><br> <INPUT type="submit" value="suma?"> </FORM> </BODY> </HTML> Sursa este vizualizată de către browser, aşa cum puteţi observa în Fig Script-ul PHP care afişează suma celor două numere este: <?php // recuperarea datelor $a=$_post['a']; $b=$_post['b']; echo $a+$b; Figura 5.6. Rezultatul retransmis spre browser?> În PHP, variabilele încep cu caracterul $. 1 Vectorii asociativi sunt trataţi în cadrul acestui capitol.

174 174 Manual de Informatică pentru clasa a XII-a Tipul radio Tipul radio (butoane radio) se utilizează în cazul în care utilizatorul trebuie să aleagă o singură opţiune dintre mai multe posibile. Pentru fiecare buton radio se ataşează câte un element input de tip radio. Pentru a avea un comportament de grup, în sensul că se poate bifa un singur buton, toate butoanele trebuie să aibă un singur nume, în exemplul de mai jos, Buton. Opţional, pentru un buton se poate folosi opţiunea checked şi efectul este acela că de la început butonul este bifat. La apăsarea butonului submit, butonul bifat va trimite valoarea ataşată lui. Exemplul 5.7. Utilizatorul trebuie să bifeze un singur buton radio, iar pe server se va şti, în funcţie de valoarea primită, care buton a fost apăsat: <HTML> <HEAD> </HEAD> <BODY> <FORM action=" method ="post"> <P> Cumpar ziarul... <BR><BR> <INPUT name="buton" TYPE="radio" value=1 checked> zilnic <BR> <INPUT name="buton" TYPE="radio" value=2> saptamanal <BR> <INPUT name="buton" TYPE="radio" value=3> lunar<br><br> <INPUT type="submit" value="trimite"> </FORM> </BODY> </HTML> Script-ul PHP şi rezultatul afişat: Figura 5.7. Formular cu butoane radio <?php $b=$_post['buton']; echo $b;?> Figura 5.8. Afişarea rezultatului Tipul checkbox Acest tip se utilizează pentru ca în fereastra browser-ului să fie afişate butoane de marcare. Aceste butoane sunt utilizate pentru a permite utilizatorului să marcheze una, niciuna sau mai multe opţiuni. De reţinut: în acest caz, se transmit către server doar valorile butoanelor marcate. Exemplul 5.8. În continuare, observaţi modul în care facem ca browser-ul să afişeze butoanele de marcare şi script-ul PHP care depistează butoanele marcate:

175 Capitolul 5. Limbajul PHP 175 <FORM action=" method="post"> <P> Urmaresc postul tv </P> <INPUT NAME="buton1" TYPE="checkbox" value=1 checked> Realitatea <BR> <INPUT NAME="buton2" TYPE="checkbox" value=2> Antena 3 <BR> <INPUT NAME="buton3" TYPE="checkbox" value=3> Protv <BR><BR> <INPUT type="submit" value="go"> </FORM> <?php foreach ($_POST AS $i=>$nume) if ($i=="buton1") echo "Realitatea"."<BR>"; else if ($i=="buton2") echo "Antena 3"."<BR>"; else if ($i=="buton3") echo "Protv"; Figura 5.9. Formularul Figura Rezultatul Tipul password Componentele vizuale de acest tip se utilizează pentru introducerea parolelor, atât de necesare, de exemplu, pentru a avea acces la un site. Sunt asemănătoare cu cele de tip text, numai că, pentru fiecare caracter al parolei se afişează câte un *. Desigur, către server, datele sunt transmise corect. Exemplul 5.9. Se introduce o parolă, iar script-ul care o primeşte o afişează: <FORM action=" method="post"> <P> Introduceti parola </P> <INPUT NAME="parola" TYPE="password" <BR> <INPUT type="submit" value="go"> </FORM> Figura Formularul <?php echo $_POST['parola'];?> Figura Rezultatul

176 176 Manual de Informatică pentru clasa a XII-a 5.3. Elementul TEXTAREA Elementul TEXTAREA se utilizează pentru a introduce un text mai lung. El poate fi folosit în interiorul unui formular şi, la apăsarea butonului submit, conţinutul său este transmis către server. De remarcat este că pentru un element TEXTAREA se pot preciza numărul de linii (rows) şi de coloane (cols) pe care acesta să le afişeze. Exemplul <FORM action=" method="post"> <P>Adaugati comentariul dv.!</p> <TEXTAREA name="textul" rows="10" cols="20></textarea><br><br> <INPUT type="submit" value="scrie"> </FORM> Iată şi script-ul PHP care afişează şirul trimis: <?php echo $_POST['textul'];?> Figura Rezultatul Figura Formularul 5.4. Elementul SELECT Elementul SELECT se utilizează pentru ca browser-ul să afişeze o listă. Fiecare opţiune din listă este marcata de un element OPTION. Dacă este introdusă într-un formular, către server se va transmite opţiunea selectată. Figura Exemplul Mai jos este prezentat formularul care afişează lista din figura de mai sus şi script-ul PHP care afişează opţinea selectată din formular: <FORM action=" method="post"> <SELECT name="lista"> <OPTION value="optiunea 1"> Optiunea 1 </OPTION> <OPTION value="optiunea 2"> Optiunea 2 </OPTION>

177 Capitolul 5. Limbajul PHP 177 <OPTION value="optiunea 3"> Optiunea 3 </OPTION> </SELECT><BR> <INPUT type="submit" value="go"> </FORM> Scriptul PHP este: <?php $v=$_post["lista"]; echo $v;?> 5.5. Constante. Variabile. Operatori Constante În PHP se pot defini constante cu ajutorul funcţiei define. Forma generală a acesteia este: define("nume_constanta", valoare). Exemplul În script-ul următor se defineşte constanta e şi se probează dacă este recunoscută. La apel, se afişează 5.42: <?php define( "e", 2.71); echo (e+e);?> Variabile În PHP numele unei variabile începe cu $. În continuare, trebuie să fie o literă sau o liniuţă de subliniere. În rest, puteţi folosi şi cifre. Nu este necesar ca variabilele să fie declarate de la început. Ele se definesc atunci când sunt folosite. Mai mult, îşi schimbă tipul în funcţie de valoarea reţinută. Exemplul Analizaţi script-ul următor: iniţial, variabila $x reţine 1. Apoi, i se atribuie un şir de caractere. Operaţia este posibilă şi în urma ei se reţine şirul, aşa cum rezultă din valoarea afişată: <?php $x=1; $y="un sir"; $x=$y; echo ($x);?>

178 178 Manual de Informatică pentru clasa a XII-a În PHP este posibilă şi adresarea indirectă, aşa cum rezultă din exemplele următoare. Exemplul Se afişează 3. Didactic, putem stabili ceea ce se afişează, astfel: <?php $x="y"; $y=3; echo ($$x);?> $$x = $($x) = $y = 3. Exemplul Se afişează "Un sir". Astfel, avem: $$$z = $$($z) = $$y= $($y) = $x = "Un sir". <?php $x="un sir"; $y="x"; $z="y"; echo ($$$z);?> Operatori Mulţi dintre operatorii limbajului PHP sunt cunoscuţi din C++. Acesta este motivul pentru care vom prezenta doar anumite particularităţi specifice limbajului. Pentru început, prezentăm, în ordine descrescătoare, prioritatea operatorilor: 1.!, ++, --, (int), (double), (string); 2. *, %, /; 3. <. <=, >, >=; 4. ==,!=, ===,!=== ; 5. &; 6. ^; 7 &&; 8.?:; 9. =, +=, -=, /=. *=, %=, &=, =, ^=; 10. And; 11. Xor; 12. Or; 13,.

179 Capitolul 5. Limbajul PHP 179 În PHP se pot folosi operatori de conversie explicită, cunoscuţi din C++. Ca şi în C++, ei se aplică prefixat. Astfel, există: (int) - conversie către o valoare întreagă, (string) - conversie către şir, iar (double) - conversie către real. Exemplul Conversia unui număr real către un întreg are ca efect eliminarea zecimalelor. Script-ul următor afişează valoarea 7: <?php $x=1; $y=7.5; $x=(int)$y; echo ($x);?> Exemplul Conversia unui şir către un întreg reuşeşte chiar dacă şirul conţine şi caractere nenumerice! Caracterele numerice trebuie să ocupe primele poziţii! În exemplul următor, în urma conversiei, x va reţine 2 şi y va reţine 3. Se afişează suma, adică 5. <?php $x=" 2 siruri"; $y="3siruri"; $x=(int)$x; $y=(int)$y; echo ($x+$y);?> Observaţie! Uneori, conversiile se realizează implicit (fără utilizarea operatorului de conversie explicită). Exemplul Script-ul următor afişează -1.76: <?php $x="-2.76"; // sir echo (1+$x);?> Exemplul Se afişează -1: <?php $x="-2.76"; // sir $y="1.76"; echo ($x+$y);?> Exemplul Se afişează... tot 1: <?php $x="-2.76 tren"; $y="1.76masina"; echo ($x+$y);?>

180 180 Manual de Informatică pentru clasa a XII-a După efectuarea unei operaţii cu un operator din grupele 3 sau 4, se obţine o valoare logică: true (1) sau false (0). Operatorul === se referă la egalitate ca valoare şi ca tip, spre deosebire de == care se referă la egalitate doar ca valoare. Exemplele următoare vă vor convinge. Exemplul Script-ul următor afişează egali ca valoare : <?php $x="3"; $y=3; if ($x===$y) echo(" egali ca valoare si tip"); else if ($x==$y) echo ("egali ca valoare"); else echo "inegali ca valoare";?> Înlocuiţi în script-ul anterior primele două atribuiri cu atribuirile de mai jos. Veţi observa că se afişează numai egali ca valoare. Aceasta demonstrează că, deşi valorile logice au reţin 1 sau 0, ele rămân, de fapt, valori logice! $x=2>1; $y=1; Observaţie! Se poate deduce cu uşurinţă rolul operatorului!==. Operaţia pe care o efectuează returnează true, dacă este diferenţă între tip sau valoare şi false, în caz contrar. Este permisă atribuirea multiplă. Exemplul Script-ul următor afişează un sir : <?php $x=1; $y=-2; $z="un sir"; $x=$y=$z; echo ($x);?> Diferenţa dintre şi Or, && şi And, ^ şi Xor este doar de prioritate!

181 Capitolul 5. Limbajul PHP Instrucţiunile limbajului PHP Instrucţiunile PHP sunt asemănătoare celor din C/C++. Din acest motiv, ne vom limita la o scurtă prezentare a lor şi la câteva exemple de utilizare. Pentru exemplificare, vom folosi următorul document HTML care trimite o valoare x către server. Pe server se va găsi un script, numit index.php, care răspunde trimiţând o valoare către browser. <HTML> <HEAD> </HEAD> <BODY> <FORM action=" method="post"> <INPUT type="text" name="x"> <BR><BR> <INPUT type="submit" value="go"> </FORM> </BODY> </HTML> Instrucţiunea expresie Se foloseşte pentru diverse calcule sau atribuiri. Exemplul Analizaţi instrucţiunea: $x=$y*$y+1; Instrucţiunea IF Această instrucţiune are forma generală: if (expresie) instructiune 1 else instructiune 2 Dacă expresie produce la evaluare o valoare diferită de 0 (true), se execută instructiune 1, altfel se execută instructiune 2. Exemplul Dacă valoarea este în intervalul [1,2], se transmite către browser valoarea (x+1)/2, altfel se transmite valoarea (x-1)/2: <?php if ($x>=1 && $x<=2) $v=($x+1)/2; else $v=($x-1)/2; echo ($v);?>

182 182 Manual de Informatică pentru clasa a XII-a Instrucţiunea compusă Atunci când dorim ca mai multe instrucţiuni să fie interpretate ca una singură, instrucţiunile se trec între "{" şi "". Instrucţiunea switch are forma generală: switch (expresie) { case exp 1 : secventa instructiuni 1 ; break; case exp 2 : secventa instructiuni 2 ; break;... case exp n : secventa instructiuni n ; break; [default: secventa instructiuni n+1 ]; unde expresie are semnificaţia: expresie de tip întreg, exp i sunt expresii constante de tip întreg, iar instrucţiuni i, o secvenţă oarecare de instrucţiuni. Principiul de executare este: se evaluează expresia; dacă aceasta produce o valoare egală cu cea produsă de exp i, se execută, în ordine, instrucţiuni i şi se trece la instrucţiunea următoare, altfel se execută numai secvenţa instrucţiuni n+1. Observaţie! Alternativa default este facultativă. În absenţă, în cazul în care nu există coincidenţă de valori, se trece la instrucţiunea următoare. Exemplul Dacă valoarea transmisă pentru x este 1, 2, 3, 4, atunci valoarea respectivă este retransmisă către utilizator alfabetic, altfel, se va transmite un mesaj oarecare. <?php switch ($x) { case (1): echo( unu ); break; case (2): echo( doi ); break; case (3): echo( trei ); break; case (4): echo( patru ); break; default : echo ( Nu este 1, 2, 3 sau 4 );?> Instrucţiunea FOR Instrucţiunea for are forma generală: for(expresie iniţializare ;expresie test ;expresie incrementare ) instrucţiune

183 Capitolul 5. Limbajul PHP 183 După cum se vede, între paranteze se găsesc 3 expresii: Expresie initializare se foloseşte, de regulă, pentru iniţializarea variabilei de ciclare. Expresie test se foloseşte pentru a testa dacă se execută instrucţiunea subordonată - dacă expresia produce la evaluare o valoare diferită de 0 (true), instrucţiunea subordonată for se execută. Expresie incrementare se foloseşte pentru incrementarea variabilei de ciclare. Principiul de executare este: P1. Se evaluează expresie iniţializare. P2. Se evaluează expresia test. În cazul în care aceasta produce o valoare diferită de 0, se execută instrucţiunea subordonată for; apoi se trece la P3, altfel se trece la instrucţiunea următoare (se termină executarea instrucţiunii for). P3. Se evaluează expresia de incrementare şi se revine la P2. Exemplul Se calculează suma pătratelor primelor x numere naturale (x este număr natural): <?php $s=0; for ($i=1;$i<=$x;$i++) $s+=$i*$i; echo($s);?> Instrucţiunea WHILE Instrucţiunea while are forma generală: Principiul de executare este următorul: P1. Se evaluează expresia; while (expresie) instructiune P2. Dacă valoarea produsă de aceasta este diferită de 0, se execută instrucţiunea subordonată, apoi se revine la P1, altfel se trece la instrucţiunea următoare. Exemplul Se calculează suma de la exemplul anterior: <? $s=0; $i=1; while ($i<=$x) { $s+=$i*$i; $i++; echo($s);?> Observaţie! Script-ul oferă şi un exemplu de instrucţiune compusă.

184 184 Manual de Informatică pentru clasa a XII-a Instrucţiunea DO WHILE Forma generală a acestei instrucţiuni este următoarea: do instructiune while(expresie); Principiul de executare este următorul: P1. Se execută instrucţiunea subordonată; P2. Se evaluează expresia. În cazul în care valoarea produsă la evaluare este 0 (false), executarea instrucţiunii do se termină, altfel se trece la P1. Exemplul Se calculează suma pătratelor primelor x numere naturale (x este natural): <?php $s=0; $i=1; do { $s+=$i*$i; $i++; while ($i<=$x); echo($s);?> 5.7. Funcţii în PHP În PHP se pot crea funcţii fără prea mari diferenţe faţă de ce ştim din C/C++. Exemplul Mai jos este prezentat un script care utilizează o funcţie pentru a calcula aria unui triunghi, pe care apoi o afişează: <?php function aria_t($b, $h) { return $b*$h/2; $x=3; $y=8; echo(aria_t($x,$y));?> Pentru a întoarce rezultate se utilizează, aşa cum suntem deja obişnuiţi, return. Forma generală este: return expresie. Transmiterea parametrilor se face prin valoare şi prin referinţă.

185 Capitolul 5. Limbajul PHP 185 A) Dacă un parametru este transmis prin valoare, atunci valoarea sa rămâne neschimbată după executarea funcţiei. Prin valoare se pot transmite atât valori, cât şi conţinutul unor variabile. Exemplul Script-ul următor afişează 5, chiar dacă în funcţie s-a încercat modificarea valorii transmise: <?php function f($x) { $x++; $x=5; f($x); echo($x);?> Exemplul Script-ul următor exemplifică faptul că o funcţie poate fi apelată atât printr-o valoare care este conţinutul unei variabile, cât şi printr-o valoare oarecare. Se afişează 3 şi 7, deci 37. <?php function f($x) { echo($x); $x=3; echo(f($x)); echo (f(7));?> B) Dacă un parametru este transmis prin referinţă atunci, în corpul funcţiei, se poate modifica valoarea sa. Evident, un parametru transmis prin valoare trebuie să fie o variabilă. Pentru a transmite un parametru prin referinţă, el trebuie precedat de caracterul &. Exemplul În script-ul următor, se modifică valoarea parametrului transmis prin referinţă. Se va afişa 6, nu 5, cât era valoarea iniţială a variabilei $x: <?php function f(&$x) { $x++; $x=5; f($x); echo($x);?> O variabilă se numeşte globală dacă a fost definită în afara oricărei funcţii. Implicit, ea nu poate fi adresată din corpul unei funcţii. Totuşi, există o posibilitate de a face acest lucru: ataşăm cuvântul global înaintea acestei variabile! Exemplul Funcţia din script-ul următor returnează 3. Aceasta arată că a fost recunoscută variabila globală $x. În absenţa cuvântului global, această valoare nu ar fi putut fi returnată:

186 186 Manual de Informatică pentru clasa a XII-a <?php function f() { global $x; return $x; $x=3; echo(f());?> Variabilele locale sunt variabile create în corpul unei funcţii sau cele create prin transmiterea parametrilor formali (din antetul funcţiilor). Ele nu sunt recunoscute în afara funcţiilor. Nimic nou... În PHP, funcţiile pot fi şi recursive. Exemplul Script-ul de mai jos calculează n! prin utilizarea unei funcţii recursive: <?php function fact($n) { if ($n==0) return 1; else return $n*fact($n-1); echo(fact(4));?> Desigur, atunci când scriem un script mai complicat, cu multe funcţii, este necesar să dispunem de un mecanism prin care să putem include funcţii pe care le-am scris mai demult, sau pe care le-am primit de undeva... Includerea unor funcţii, dar nu numai, se realizează prin funcţia require("nume_fisier"). Funcţiile trebuie să se găsească pe site, într-un fişier text. Observaţi faptul că textul funcţiei (funcţiilor inserate) trebuie să fie încadrat între <? şi?>. Exemplul Funcţia afis() se găseşte în fişierul functia.ex, aflat pe site. Script-ul care o utilizează conţine require(): <?php function afis() { echo("eu sunt functia inserata");?> <? require("functia.ex"); afis();?> Pe lângă faptul că putem să scriem diverse funcţii, limbajul PHP este înzestrat cu numeroase alte funcţii. Cele mai importante vor fi tratate pe parcurs.

187 Capitolul 5. Limbajul PHP Funcţii matematice Multe dintre funcţiile prezentate le-aţi întâlnit dacă aţi studiat limbajul C/C++. Tabelul următor le prezintă succint: Funcţia Ce realizează Exemple abs(numar) sin(x), cos(x), tan(x) Returnează modulul numărului. Sinusul, cosinusul şi tangenta unui unghi. Argumentul x este dat în radiani exp(x) Returnează e x.. pow(x,y) Returnează x y. abs(-7)=7; abs(-2.23)=2.23; abs(2.3)=2.3 log10(x), log(x) max(x 1, x 2,... x n ), min(x 1, x 2,... x n ) ceil(x) round(x) floor(x) rand(min,max) Returnează log 10 ( x ), respectiv log 2 ( x ). Returnează maximul, minimul dintr-un şir de argumente numerice. Returnează cel mai mic întreg mai mare sau egal cu x. Returnează întregul rezultat prin rotunjirea lui x. Returnează cel mai mare întreg mai mic sau egal cu x. Returnează o valoare întreagă aleatoare între valorile întregi min şi max (inclusiv). pi() Returnează numărul π. sqrt(x) Returnează rădăcina pătrată a lui x. ceil(4.3)=5, ceil(-4.3)=-4 round(4.3)=4, round(4.7)=5. floor(4.3)=4, floor(-4.3)=-5 rand(1,10) poate returna orice valoare întreagă din [1,10]. sqrt(4)=2; Tabelul 5.1. Funcţii matematice

188 188 Manual de Informatică pentru clasa a XII-a 5.9. Afişarea datelor - echo şi print Pentru a afişa datele pe browser se folosesc echo şi print. Acestea nu sunt funcţii în accepţiunea clasică a cuvântului, deşi pot fi utilizate asemenea funcţiilor. Ele sunt construcţii speciale PHP. Ambele afişează şiruri de caractere. A) echo datorită simplităţii, a fost utilizată de multe ori până acum. Pentru că poate fi utilizată în multe feluri, o vom prezenta prin exemple şi vom renunţa la prezentarea formei generale. Exemplul Afişăm un şir de caractere folosind parantezele rotunde (apel ca în cazul funcţiilor): echo("un mesaj"); Exemplul Afişăm un şir de caractere fără să utilizăm parantezele rotunde. Pentru că este permisă o astfel de utilizare, spunem că echo nu este funcţie, ci construcţie specială. echo "Un mesaj"; Exemplul În cazul în care nu se folosesc paranteze, se pot afişa mai multe şiruri de caractere: echo "Un mesaj ", "Alt mesaj"; Exemplul Putem afişa şi conţinutul unor variabile, aşa cum rezultă din exemplul următor: <?php $x=6; echo ("Am $x mere"); // sau echo "Am $x mere";?> B) print se utilizează la fel ca echo, dar, dacă utilizăm paranteze, se poate folosi valoarea întoarsă: true, dacă şirul a fost expediat sau false, în caz contrar. Exemplul Priviţi exemplul de mai jos: print ("Un exemplu"); <?php $x=6; $y=8; print ("Ana are $x mere si <BR> $y pere");?> Observaţie! <BR> se utilizează pentru salt la linie nouă! Vezi HTML...

189 Capitolul 5. Limbajul PHP 189 Observaţii foarte importante! 1. În loc de se pot folosi şi. Diferenţa este dată de faptul că, în cazul folosirii, dacă şirul de caractere conţine numele unei variabile, nu se afişează conţinutul variabilei, ci se afişează numele variabilei. Exemplul Dacă comanda este echo Am $x mere se va afişa Am $x mere. 2. Nu se pot folosi incluse între şi nici incluse între. Exemplul Secvenţele de mai jos sunt incorecte: echo " Am o multime de prieteni"; echo Am 'o multime' de prieteni ; 3. În schimb, putem include între caracterele. Exemplul Instrucţiunea următoare afişează echo " Am 'o multime' de prieteni"; Am o multime de prieteni. 4. În schimb, putem include între caracterele. Exemplul Instrucţiunea următoare echo Am o multime de prieteni ; afişează Am o multime de prieteni Funcţii pentru prelucrarea şirurilor de caractere În PHP există un set puternic de funcţii, asemănătoare celor din C++, care lucrează cu şiruri de caractere. De asemenea, există şi un operator de concatenare a şirurilor. Şirurile se memorează ca o succesiune de caractere ASCII. Putem adresa fiecare caracter al şirului, aşa cum suntem obişnuiţi, prin indicele său. Primul caracter are indicele 0. Exemplul În secvenţa următoare, se afişează caracterul U : $sir="un exemplu"; echo ($sir[0]);

190 190 Manual de Informatică pentru clasa a XII-a Operatorul de concatenare a şirurilor este punctul. Exemplul Se afişează "Ana are 9 mere!". Observaţi faptul că valoarea numerică a fost convertită implicit către şir. $x=9; $sir="ana ". "are ". $x. " mere!"; echo $sir; Funcţia strlen(sir) returnează lungimea şirului (numărul de caractere ale şirului). Exemplul În secvenţa de mai jos se afişează 10 (se numără şi blank-ul): $sir="un exemplu"; echo strlen($sir); funcţia strpos(sir1, sir2, [poz_start]) caută dacă sir2 este subşir al lui sir1. În caz afirmativ, returnează poziţia de început a acestuia, altfel returnează false. Al treilea parametru specifică funcţiei indicele caracterului de unde să înceapă căutarea. Dacă nu este completat, căutarea începe din poziţia 0. Exemplul La executarea secvenţei următoare, se afişează 5: $sir="un exemplu"; echo (strpos($sir, "em")); Funcţia se utilizează şi pentru a testa dacă un şir include sau nu un anumit subşir. Dacă subşirul este găsit, se returnează poziţia de început a acestuia în subşir, dacă nu, se returnează false. După cum ştim, valoarea lui false este, de fapt, 0. Ce ne facem în cazul în care subşirul se găseşte şi începe în poziţia 0? Cum facem distincţia între acest caz şi cel în care subşirul nu este găsit? Priviţi secvenţa din exemplul de mai jos, care rezolvă corect problema şi subliniază importanţa operatorului ===. Exemplul Secvenţa este următoarea: <?php $sir="un exemplu"; $gasit=strpos($sir, "U"); if ($gasit===false) echo ("Nu este"); else echo ("Este");?> Valoarea întoarsă de funcţie este reţinută de variabila $gasit. Pentru a face distincţie între false şi 0, se foloseşte operatorul ===, care testează coincidenţa atât ca valoare, cât şi ca tip. De altfel, acesta este şi rostul unui astfel de operator. Acest procedeu se poate folosi şi pentru alte funcţii.

191 Capitolul 5. Limbajul PHP 191 Funcţia strstr(sir1,sir2) returnează sir1 din poziţia în care a fost găsit sir2, dacă sir2 este subşir pentru sir1 sau false, în caz contrar. Exemplul În secvenţa următoare se afişează exemplu : $sir="un exemplu"; $gasit=strstr($sir, "ex"); if ($gasit===false) echo ("Nu este in sir"); else echo ($gasit); Funcţia strcmp(sir1,sir2) compară lexicografic (alfabetic) sir1 cu sir2. Valoarea returnată este: <0, dacă sir1 < sir2; >0, dacă sir1 > sir2; 0, dacă sir1 = sir2. Exemplul Priviţi comparaţiile de mai jos: strcmp ("mama", "tata"); returnează un rezultat <0. strcmp ("ab", "a"); returnează un rezultat >0. strcmp ("abc", "abc"); returnează 0. Observaţie! Comparaţia face distincţie între literele mari şi cele mici! Funcţia substr(sir,ind,[lung]) returnează subşirul şirului sir, care începe în poziţia ind şi are lungimea lung. Dacă parametrul lung este absent, se returnează şirul care începe în poziţia ind şi ţine până la sfârşitul şirului sir. Exemplul După executarea secvenţei, se afişează exemplu : $sir="un exemplu"; echo (substr($sir,3)); Exemplul După executarea secvenţei, se afişează ex : $sir="un exemplu"; echo (substr($sir,3,2)); Funcţia substr_replace(sir1, sir2, ind, [lung]) returnează şirul rezultat prin înlocuirea în sir1, a subşirului care începe în poziţia ind şi are lungimea lung cu sir2. Dacă parametrul lung este absent, sir2 înlocuieşte subşirul care începe cu ind şi ţine până la sfârşitul şirului sir2. Exemplul Secvenţa următoare afişează Un templu : $sir="un exemplu"; echo (substr_replace($sir,"t",3,2)); Funcţia strtoupper(sir) returnează şirul convertit în litere mari, iar funcţia strtolower(sir) returnează şirul convertit în litere mici.

192 192 Manual de Informatică pentru clasa a XII-a Masive în PHP În PHP există o libertate extraordinară de lucru cu masive. Începem prin a spune că masivele nu se declară. Exemplul În script-ul următor, se creează şi se afişează un vector cu 5 componente: <?php for ($i=0;$i<5;$i++) $x[$i]=$i; for ($i=0;$i<5;$i++) echo( "$x[$i] <BR>" );?> Exemplul Se creează şi se afişează o matrice cu 5 linii şi 5 coloane. Elementele din linia i şi coloana j reţin valorile i+j. <?php for ($i=0;$i<5;$i++) for ($j=0;$j<5;$j++) $mat[$i][$j]=$i+$j; for ($i=0;$i<5;$i++) { for ($j=0;$j<5;$j++) echo($mat[$i][$j]." "); echo("<br>");?> În PHP, indicii pot fi şiruri de caractere. Exemplul Probaţi script-ul următor, unde un vector de indici nume de persoane, reţine numerele lor de telefon. Acesta este un tablou asociativ: <?php $x["ioana"]="0724xxx"; $x["valentina"]="031xxx"; $x["paul"]="0211xxx"; $x["cristian"]="0232xxx"; print $x["ioana"]."<br>"; print $x["valentina"]."<br>"; print $x["paul"]."<br>"; print $x["cristian"]."<br>";?> Faptul că există posibilitatea utilizării unor astfel de indici creează, pe lângă avantaje, probleme. Imaginaţi-vă că vreţi să parcurgeţi şi să listaţi un astfel de vector. Care este numărul componentelor? Să zicem că pe acesta îl reţinem într-o variabilă, dar ce valori ia variabila de ciclare? Funcţia count(nume_vector) returnează numărul de componente ale vectorului.

193 Capitolul 5. Limbajul PHP 193 Exemplul Pentru vectorul din script-ul anterior, cu ajutorul expresiei echo(count($x));, se afişează 4. Instrucţiunea de mai jos are rolul de a ne permite o parcurgere uşoară a unui vector cu numele vector, cu variabila de ciclare indice, în care citirea se face în variabila variabila: foreach(vector as indice=>variabila). Exemplul Se creează un vector şi se parcurge cu foreach(...), afişând rezultatele parcurgerii: <?php $x["ioana"]="0724xxx"; $x["valentina"]="031xxx"; $x["paul"]="0211xxx"; $x["cristian"]="0232xxx"; foreach($x as $i=>$nume) echo($i." ".$nume."<br>" );?> Iată ce se afişează (Fig. 5.16)! Figura Rezultatul script-ului Există şi alte funcţii care permit accesarea cu uşurinţă a elementelor vectorului. Ideea de la care se pleacă este următoarea: există un pointer care întotdeauna este asupra unui element al vectorului. Funcţia current(vector); returnează valoarea reţinută de elementul din vector asupra căruia se găseşte pointer-ul. Funcţia key(vector); returnează indicele elementului din vector asupra căruia se găseşte pointer-ul. Funcţia next(vector); deplasează pointer-ul pe elementul următor din vector şi returnează valoarea reţinută de acesta. Funcţia prev(vector); deplasează pointer-ul pe elementul anterior al vectorului şi returnează valoarea reţinută de acesta. Exemplul Analizaţi script-ul de mai jos: <?php $x["ioana"]="0724xxx"; $x["valentina"]="031xxx"; $x["paul"]="0211xxx"; $x["cristian"]="0232xxx"; echo(current($x)." ".key($x)."<br>"); echo(next($x)." ".key($x)."<br>"); echo(prev($x)." ".key($x)."<br>"); echo(count($x)."<br>");?> Figura Rezultatul script-ului

194 194 Manual de Informatică pentru clasa a XII-a Dacă, în general, sortarea unui vector (tablou) se poate efectua cu ajutorul unui algoritm oarecare de sortare, în cazul unui tablou asociativ, cum lesne vă puteţi da seama, problema este mai complicată. Din acest motiv, PHP-ul pune la dispoziţia programatorilor funcţii specifice. Exemplul Pentru a testa modul în care acestea efectuează sortarea, vom folosi script-ul următor, în care linia metoda de sortare se va înlocui cu funcţia respectivă: <?php $x["ioana"]="0724xxx"; $x["valentina"]="031xxx"; $x["paul"]="0211xxx"; $x["cristian"]="0232xxx";\ foreach($x as $i=>$nume) echo($i." ".$nume."<br>"); //metoda de sortare?> Funcţia Asort(vector) sortează crescător vectorul după valoarea reţinută de fiecare element. Rezultatul este prezentat în figura alăturată. Figura Funcţia Arsort(vector) sortează descrescător vectorul după valoarea reţinută de fiecare element. Rezultatul este prezentat alăturat. Figura Funcţia Ksort(vector) sortează crescător vectorul după indici (vezi figura alăturată). Figura Funcţia Krsort(vector) sortează descrescător vectorul după indici. Rezultatul este cel alăturat. Figura Funcţiile sort() şi rsort() sortează crescător, respectiv descrescător, un masiv de indici 0, 1,..., n. În cazul în care avem un masiv asociativ, vechile valori ale indicilor se pierd (vezi figura alăturată). Figura 5.22.

195 Capitolul 5. Limbajul PHP Variabile cookie Atunci când utilizarea Internet-ului a luat amploare, s-a pus următoarea problemă: cum trebuie procedat pentru ca server-ul să utilizeaze anumite opţiuni ale utilizatorului, astfel încât, atunci când acesta intră pe site, să nu mai piardă timpul selectându-le din nou? Mai mult, dacă se dispune de astfel de informaţii, pagina afişată pentru un anumit utilizator ar putea fi personalizată. Problema a fost rezolvată de cei de la firma Netscape în anul Mecanismul care stă la baza acestei probleme se bazează pe memorarea, pe calculatorul vizitatorului unui anumit site, a unor informaţii sub forma unor mici fişiere text. Operaţia poate fi comandată de pe server şi tot de pe server se poate comanda citirea, actualizarea sau ştergerea acestor mici fişiere, numite uzual, prin abuz de limbaj, variabile cookie. În PHP se poate lucra foarte uşor cu variabilele cookie. Pentru a crea o variabilă cookie se utilizează funcţia setcookie (nume_variabila, valoare, data_expirare) Exemplul În script-ul de mai jos, se creează o variabilă cookie numită copac. Variabila reţine valoarea verde şi expiră într-o oră. <?php // creeaza o variabila cookie setcookie("copac", "verde", time()+3600);?> Observaţii! 1. Nu pot exista simultan mai mult de 20 de variabile cookie. Dacă se creează una în plus, prima creată este ştearsă automat. 2. Pentru a şterge o variabilă cookie se creează o alta cu acelaşi nume, dar cu data de expirare înaintea datei curente (de exemplu, time()-1). Pentru a citi o variabilă cookie se utilizează conţinutul unui masiv asociativ, numit $HTTP_COOKIE_VARS. Fiecare componentă a sa, de indice numele variabilei cookie, reţine valoarea variabilei cookie. Exemplul În script-ul de mai jos se afişează valoarea variabilei cookie creată de script-ul anterior: <?php // afiseaza verde echo $HTTP_COOKIE_VARS["copac"];?> Analizaţi şi exemplele următoare

196 196 Manual de Informatică pentru clasa a XII-a Exemplul În script-ul de mai jos se creează 20 de variabile cookie numite V1, V2,..., V20 care reţin respectiv 1, 2,..., 20: <?php for ($i=1;$i<=20;$i++) setcookie("v".$i, $i, time()+10000); echo "OK complet"?> Exemplul În script-ul de mai jos se afişează conţinutul variabilelor cookie existente pe calculatorul vizitatorului: <?php foreach($http_cookie_vars as $i=>$nume) echo $i." ".$nume."<br>";?> Exemplul Script-urile care urmează exemplifică modul în care se pot reţine anumite informaţii pe care utilizatorul le-a tastat o dată. Apelat pentru prima dată, atunci când nu există variabila cookie nume, se cere numele vizitatorului. Acesta va introduce numele şi va apăsa butonul insereaza (vezi Fig. 5.23). Dacă respectivul vizitator, reintră pe acel site, reapelând script-ul, acesta va identifica variabila cookie nume, va prelua numele memorat şi, în loc ca vizitatorului să i se ceară din nou numele, se va afişa mesajul (vezi Fig. 5.24). Figura Figura <?php $gasit=0; // se cauta daca exista variabila cookie nume foreach($http_cookie_vars as $i=>$v) if($i=="nume") $gasit=1; //daca exista se afiseaza un mesaj if ($gasit==1) echo " Bine ati venit pe site-ul nostru domnule: ".$HTTP_COOKIE_VARS["nume"]; // daca nu exista, se afiseaza cele necesare pentru // identificare si se creeaza variabila nume else echo "<FORM action='cc.php' method ='post'>"."nume<br>". "<input name='nume' type='text'>;". "<BR>". "<INPUT type='submit', value='insereaza'>";?>

197 Capitolul 5. Limbajul PHP Utilizarea în comun a limbajelor PHP şi MySQL Crearea unei baze de date În acest paragraf prezentăm modul în care se utilizează împreună PHP şi MySQL. Vom presupune că server-ul care găzduieşte site-ul dispune de soft-ul necesar. Desigur, prezentarea aplicaţiilor se va face în continuare pe propriul calculator, prin utilizarea pachetului EasyPHP. Orice script PHP va fi scris în folder-ul www, inclus în folder-ul EasyPHP1-8 (versiunea pe care o aveam în momentul scrierii cărţii pe calculatorul nostru). Orice script PHP care lucrează cu MySQL trebuie să se conecteze la acesta. Pentru conectare, se utilizează funcţia mysql_connect() sub forma: resursa mysql_connect( nume_gazda, nume_utilizator, parola ) În cazul nostru, numele gazdei este localhost, iar numele utilizatorului şi parola sunt cele utilizate în Partea 1, Capitolul 2, atunci când am învăţat să utilizăm MySQL de la consolă. În cazul în care conectarea a reuşit se returnează resursa, altfel, se returnează FALSE. Pentru a da o comandă MySQL dintr-un script PHP se utilizează funcţia mysql_query(), care primeşte instrucţiunea sub forma unui şir de caractere. Şi aici, în caz că operaţia a reuşit, se returnează o valoare diferită de 0, altfel se returnează 0. resursa mysql_query(instructiune_mysql) Exemplul Se cere să se scrie un script, cre_baza.php, care creează baza de date, numită baza. Practic, script-ul va realiza conexiunea la MySQL, după care va da comanda de creare a bazei de date. În ambele operaţii, în caz de nereuşită, se va da un mesaj de eroare lămuritor. <?php // conectarea la MySQL $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) { echo "Nu s-a realizat conectarea la MySQL "; exit; // crearea bazei de date numita baza $rezultat=mysql_query("create DATABASE baza"); if (!$rezultat) echo "nu s-a reusit crearea bazei de date";?> Pentru a rula script-ul, se dă următoarea comandă browser-ului:

198 198 Manual de Informatică pentru clasa a XII-a Dacă dorim ca mesajele de eroare să ne ajute mai mult în depanare, vom utiliza două funcţii MySQL. Funcţia string mysqlerrno() returnează codul numeric al ultimei erori. Lista parametrilor este vidă. Funcţia string mysqlerror() returnează mesajul asociat ultimei erori. Şi în cazul ei, lista parametrilor este vidă. Exemplul Înlocuiţi ultimul echo din scriptul anterior cu: echo mysql_errno().":".mysql_error(); În cazul în care veţi rula din nou script-ul, va apărea o eroare care se datorează faptului că se încearcă crearea unei baze de date care există deja. Iată cum este afişată eroarea în acest caz: 1007: Can t create database baza ; database exists Observaţie! În perioada de început, este recomandabil să utilizaţi în paralel şi fereastra MS-DOS pentru a lucra cu MySQL, ca în Capitolul 2. De fiecare dată veţi testa dacă operaţia a reuşit. De exemplu, după ce aţi creat baza de date, numită baza, daţi comanda USE baza şi dacă nu apare eroare, înseamnă că baza de date a fost creată Accesul la o bază de date şi crearea unui tabel în baza de date Pentru a avea acces la o bază de date, se utilizează funcţia de mai jos, care returnează, aşa cum suntem obişnuiţi, o valoare diferită de 0 în caz de reuşită şi 0, în caz contrar. bool mysql_select_db(nume_baza) După realizarea accesului, putem crea tabelul prin utilizarea instrucţiunii mysql_query(). Exemplul Se cere să se scrie un script, cre_tabel.php, prin care să se creeze un tabel, numit vizitatori, care reţine, pentru fiecare persoană trecută în tabel, numele, vârsta şi adresa de . <?php // conectarea la MySQL $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) { echo "Nu s-a realizat conectarea la MySQL "; exit; // conectarea la baza de date $baza=mysql_select_db("baza");

199 Capitolul 5. Limbajul PHP 199 if (!$baza) { echo mysql_errno().":".mysql_error(); exit; // crearea tabelului $interogare="create TABLE vizitatori (nume CHAR(30), varsta INT, CHAR(20) PRIMARY KEY)"; $rezultat=mysql_query($interogare); if (!$rezultat) echo mysql_errno().":".mysql_error();?> Testaţi script-ul apelând: În toate operaţiile pe care le vom face de acum înainte cu această bază de date vom avea nevoie, în mod evident, de conectarea la MySQL şi accesul la baza de date. Pentru ca să nu repetăm această secvenţă, se scrie script-ul de mai jos, numit conectare.php(): <?php // conectarea la MySQL $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) {echo "Nu s-a realizat conectarea la MySQL "; exit; // conectarea la baza de date $baza=mysql_select_db("baza"); if (!$baza) {echo mysql_errno().":".mysql_error(); exit;?> Pentru ca un script să includă un altul şi să-l execute se foloseşte funcţia MySQL de mai jos, care are ca parametru numele script-ului care urmează să fie inclus: require_once(nume_script); Exemple de utilizare ale acestui script veţi găsi în paragrafele următoare Inserarea liniilor în tabel Am creat o bază de date, numită baza, cu un tabel, numit vizitatori. Rămâne să introducem date în acest tabel. Vom presupune că fiecare utilizator al bazei de date se autoînregistrează, scriind datele în nişte edit-uri afişate de pagină. Problema se rezolvă în două părţi. A) Se creează o pagină, s-o numim i_date.php, care conţine edit-urile prin care se introduc datele şi butonul la apăsarea căruia datele sunt transmise către server. Modul de creare a unei astfel de pagini a fost descris, prin urmare prezentăm numai codul ei şi tabelul pe care-l afişează. La apăsarea butonului inserează se apelează script-ul insereaza.php aflat pe server (în cazul nostru, în folder-ul www). Pagina va fi apelată prin comanda următoare:

200 200 Manual de Informatică pentru clasa a XII-a Codul sursă pentru pagina i_date.php este: <HTML> <HEAD> </HEAD> <BODY> <FORM action="insereaza.php" method ="post"> Nume<BR> <INPUT name="nume" type="text">; <BR> Varsta <BR> <INPUT name="varsta" type="text">; <BR> Adresa <BR> <INPUT name=" " type="text">; <BR> <INPUT type="submit", value="insereaza"> </FORM> </BODY> </HTML> Figura Pagina i_date.php B) După ce vizitatorul paginii respective îşi completează datele şi apasă butonul insereaza, acestea sunt transmise către server şi sunt preluate de către script-ul insereaza.php. Acesta preia datele şi le introduce în tabelul vizitatori. <?php require_once("conectare.php"); $nume= $_POST['nume']; $varsta= $_POST['varsta']; $ = $_POST[' ']; $cerere="insert INTO vizitatori (nume,varsta, ) VALUES('$nume',$varsta,'$ ')"; $rezultat=mysql_query($cerere); if (!$rezultat) echo mysql_errno().":".mysql_error();?> Observaţii! 1. Pentru câmpurile nume şi datele sunt de tip şir de caractere. Ele sunt memorate de variabilele $nume şi $ . Pentru a le introduce ca şiruri, vom trece variabilele între apostrofuri: $nume, $ . 2. După introducerea unui rând, testaţi dacă acesta a fost sau nu introdus în fereastra MS-DOS: SELECT * FROM vizitatori. Este foarte important ca datele introduse să fie validate. Astfel, numele trebuie să fie nevid, varsta trebuie să fie o valoare numerică mai mare sau egală ca 10 şi mai mică sau egală cu 90 şi adresa de trebuie să conţină Vom rescrie script-ul, de această dată cu validări.

201 Capitolul 5. Limbajul PHP 201 Observaţie! Atunci când se depistează o eroare, se afişează un mesaj lămuritor şi se reafişează formularul de introducere a datelor! <?php require_once("conectare.php"); $nume= $_POST['nume']; if (strcmp($nume,"")==0) {echo "Nu ati scris numele"; require_once("i_date.php"); exit; $varsta= $_POST['varsta']; if (!is_numeric($varsta) $varsta<10 $varsta>90) {echo "Varsta incorecta"; require_once("i_date.php"); exit; $ = $_POST[' ']; if (!strpos($ ,"@")) { echo "Adresa de gresita"; require_once("i_date.php"); exit; $cerere="insert INTO vizitatori (nume,varsta, ) VALUES('$nume',$varsta,'$ ')"; $rezultat=mysql_query($cerere); if (!$rezultat) echo mysql_errno().":".mysql_error();?> Afişarea unui tabel În acest paragraf vom arăta modul în care se listează rezultatul unei interogări. După cum am văzut, o interogare se realizează cu mysql_query(). Ea returnează o valoare care, în cazul în care interogarea a reuşit, este diferită de 0. În cazul în care rezultatul unei interogări este alcătuit din mai multe rânduri, ca de exemplu în cazul listării unui tabel, nu se afişează direct rezultatul, aşa cum suntem obişnuiţi. În astfel de cazuri, pornind de la valoarea returnată de mysql_query(), se afişează tabelul rând cu rând. Funcţia mysql_fetch_array() returnează un rând al unei interogări (în cazul de faţă, al unui tabel) sub forma unui tablou asociativ. După returnarea rândului, automat se trece la rândul următor. array mysql_fetch_array(resursa) Pornind de la tabloul asociativ returnat, se poate accesa orice câmp al interogării.

202 202 Manual de Informatică pentru clasa a XII-a Exemplul Analizaţi script-ul următor, unde se afişează datele introduse în tabel. Rezultatul îl puteţi observa în figura alăturată. <?php require_once("conectare.php"); $cerere="select * FROM vizitatori"; $rezultat=mysql_query($cerere); if (!$rezultat) echo mysql_errno().":".mysql_error(); // pentru fiecare rand al tabelului while($rand=mysql_fetch_array($rezultat)) echo $rand["nume"]." ".$rand["varsta"]." ". $rand[" "]."<br>";?> Figura Rezultatul obţinut Desigur, datorită formei inestetice, această afişare a tabelului nu ne convine. Din acest motiv, vom afişa tabelul, aşa cum îl observaţi alăturat. Pentru aceasta, vom rescrie script-ul afisare_tabel: <?php Figura require_once("conectare.php"); Rezultat estetic $cerere="select * FROM vizitatori"; // in urma interogarii, se returneaza tabelul $rezultat=mysql_query($cerere); if (!$rezultat) { echo mysql_errno().":".mysql_error(); exit; // afisam datele sub forma unui tabel echo "<TABLE BORDER=5>"; // afisam capul de tabel Echo "<TR><TD align='center'> <STRONG>Nume<TD><STRONG>Varsta<TD><STRONG>Adresa "; // Pentru fiecare rand al tabelului while($rand=mysql_fetch_array($rezultat)) { echo "<TR>"; echo "<TD>".$rand["nume"]. "<TD align='right'>".$rand["varsta"]."<td>". "<A href=mailto:".$rand[" "].">".$rand[" "]."</a>"; echo "</TR>"; echo "</TABLE>";?> Apelaţi script-ul prin:

203 Capitolul 5. Limbajul PHP Aplicaţii Inscrierea pe un site În unele site-uri se cere ca, în prealabil, vizitatorii respectivului site să se înscrie în baza de date a acestuia. De regulă, utilizatorului i se cere ID-ul (nickname-ul) şi parola. Acestea sunt memorate într-un tabel şi de câte ori utilizatorul doreşte să acceseze din nou site-ul, ele sunt cerute pentru identificare. Accesul la site se realizează numai atunci când ID-ul şi parola se regăsesc în baza de date. A) Pentru început, este necesar ca să se creeze o bază de date, de exemplu, inscrisi, care conţine un singur tabel, parole. Script-ul următor, btab.php, realizează cele de mai sus: <?php // conectarea la MySQL $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) { echo "Nu s-a realizat conectarea la MySQL "; exit; // crearea bazei de date numita baza $rezultat=mysql_query("create DATABASE inscrisi"); if (!$rezultat) { echo "nu s-a reusit crearea bazei de date"; exit; $baza=mysql_select_db("inscrisi"); $interogare="create TABLE parole ( nume CHAR(30) PRIMARY KEY, parola CHAR(10))"; $rezultat=mysql_query($interogare); if (!$rezultat) echo mysql_errno().":".mysql_error();?> În cele ce urmează, vom presupune că am rulat script-ul btab.php, deci baza de date şi tabelul sunt create. B) Dacă un vizitator accesează site-ul, este afişată pagina alăturată, în care i se cere, fie să se identifice, în cazul în care este înscris deja, fie să se înscrie, în caz contrar. Figura Pagina principală

204 204 Manual de Informatică pentru clasa a XII-a Pentru a realiza pagina respectivă, se foloseşte un simplu fişier HTML (sau PHP), vedeţi mai jos (index.php). În fapt, acesta conţine două ancore, către cele două script-uri PHP: identificare.php sau inscriere.php. Vizitatorul poate opta pentru oricare dintre ele. <HTML> <BODY> <H2> Bine ati venit pe site-ul...</h2> <A href=" Identificare </A><BR><BR> <A href=" Inscriere </A> </BODY> </HTML> C) Dacă utilizatorul optează pentru înscriere, atunci este rulat script-ul următor (inscriere.php), care afişează fereastra alăturată. Vizitatorului i se cere să introducă numele (ID-ul) şi parola. Atunci când se introduce parola, se afişează * pentru fiecare caracter introdus. Pentru a evita introducerea greşită a parolei, aceasta trebuie să fie introdusă de două ori. După introducerea datelor, vizitatorul va apăsa butonul inscrie-te. Efectul va fi acela de trimitere a datelor către server şi de apel al script-ului inscrie.php. <HTML> <BODY> <FORM action="inscrie.php" method ="post"> Nume<BR> <input name="nume" type="text">; <BR> Parola <BR> <input name="parola1" type="password">; <BR> Reintroduceti parola <BR> <input name="parola2" type="password">; <BR> <INPUT type="submit", value="inscrie-te!"> </FORM> </BODY> </HTML> Figura Pagina inscriere.php C1) Script-ul inscrie.php validează datele şi, în caz că acestea sunt valide, le înscrie în tabelul parole: - se testează dacă numele este nevid; - dacă cele două parole coincid; - dacă nu mai există un vizitator cu aceeaşi parolă (parola este cheie primară). În cazul în care una dintre aceste condiţii nu este îndeplinită, se afişează un mesaj de eroare corespunzător şi se reafişează formularul de introducere a datelor.

205 Capitolul 5. Limbajul PHP 205 <?php // conectare la mysql $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) { echo "Nu s-a realizat conectarea la MySQL "; exit; // declarare baza folosita $baza=mysql_select_db("inscrisi"); //Citirea numelui - trebuie sa fie nevid $nume= $_POST['nume']; if (strcmp($nume,"")==0) {echo "Nu ati scris numele"; require_once("inscriere.php"); exit; // citirea parolelor - trebuie sa fie identice $parola1= $_POST['parola1']; $parola2= $_POST['parola2']; if (strcmp($parola1,$parola2)!=0) {echo "parola incorecta"; require_once("inscriere.php"); exit; // se incearca inscrierea in tabel $cerere="insert INTO parole (nume,parola) VALUES('$nume','$parola1')"; $rezultat=mysql_query($cerere); if (!$rezultat) { echo "Nume existent in baza de date"; require_once("inscriere.php"); else echo "OK! Ati fost introdus in baza noastra de date";?> D) În cazul în care vizitatorul este deja înscris, va apela script-ul identificare.php prin intermediul ancorei respective. Acesta va cere numele şi parola, iar la apăsarea butonului Conecteaza-ma va trimite datele către server. Acestea sunt preluate de script-ul verif.php. <HTML> <BODY> <FORM action="verif.php" method ="post"> Nume<BR> <input name="nume" type="text">; <BR> Parola <BR> <input name="parola" type="password">; <BR> <INPUT type="submit", value="conecteaza-ma"> </FORM> </BODY> </HTML> Figura Pagina identificare.php

206 206 Manual de Informatică pentru clasa a XII-a D1) Se testează dacă în tabelul parole există înregistrarea cu ID-ul şi parola introdusă de utilizator. În caz că există, se rulează, de exemplu, un script php, în acest caz, rezultat.php, altfel se cere ca datele să fie reintroduse: <?php // conectare la mysql $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) { echo "Nu s-a realizat conectarea la MySQL "; exit; // declarare baza folosita $baza=mysql_select_db("inscrisi"); // citirea numelui si parolei $nume= $_POST['nume']; $parola= $_POST['parola']; // selectez, daca exista in tabel, randul corespunzator $cerere="select nume FROM parole WHERE nume='$nume' AND parola='$parola'"; $rezultat=mysql_query($cerere); $rand=mysql_fetch_array($rezultat); //echo $rand['nume']; if ($rand["nume"]!=$nume) {echo "Numele si/sau parola sunt eronate"; require_once("identificare.php"); else require_once("rezultat.php"); ;?> Fişierul rezultat.php este: <HTML> <BODY> <H1> pagina ce ar trebui afisata </BODY> </HTML> Determinarea adresei IP şi a browser-ului utilizatorului Uneori se doreşte obţinerea unor informaţii despre vizitatorii unui site. Astfel, se poate afla adresa IP a vizitatorului, browser-ul utilizat de acesta sau sistemul de operare pe care acesta îl utilizează. Toate acestea pot fi stocate în baze de date. Informaţiile astfel dobândite sunt extrem de importante pentru aplicaţii precum: - Aplicaţii prin care vizitatorii votează răspunsul la o anumită întrebare. Pentru a evita ca un vizitator să voteze de mai multe ori într-o zi, într-un tabel se va memora adresa IP a acestuia. De la o anumită adresă IP se poate vota o singură dată sau o singură dată pe zi, caz în care se va reţine şi ziua votării.

207 Capitolul 5. Limbajul PHP Aplicaţii prin care se contorizează vizitatorii unui site. Dacă o persoană vizitează site-ul într-o zi de mai multe ori, dar cu aceeaşi adresă IP, aceasta este numărată ca vizitator o singură dată. - Determinarea browser-ului are şi ea mai multe utilizări. Se ştie că, din păcate, diferite browser-e afişează uneori diferit acelaşi fişier download-at de pe server. Pentru a nu mai avea astfel de probleme, dacă se cunoaşte browser-ul utilizatorului, atunci server-ul expediază către calculatorul vizitatorului fişierul corespunzător. - Informaţii precum cele de mai sus pot fi folosite de site-urile care monitorizează vizitele la diferite alte site-uri şi întocmesc clasamentul acestora în funcţie de numărul de vizitatori. În acest paragraf vom învăţa să determinăm adresa IP şi browser-ul vizitatorului. $_SERVER este o variabilă predefinită de tip masiv asociativ. Cu ajutorul ei, script-ul PHP poate accesa o mulţime de informaţii. Pentru a afla adresa IP a vizitatorului se utilizează $_SERVER["REMOTE_ADDR"] şi pentru a afla informaţii despre browser se utilizează $_SERVER["HTTP_USER_AGENT"]. În acest din urmă caz, dacă şirul obţinut conţine subşirul MSIE 6.0, atunci browser-ul utilizator este Microsoft Internet Explorer versiunea 6.0, dacă conţine subşirul Netscape, atunci browser-ul este de tip Netscape, etc. Exemplul Mai multe informaţii puteţi obţine analizând script-ul următor care afişează browser-ul utilizatorului şi adresa IP a acestuia (vezi figura de mai jos): Figura Rezultatele script-ului propus ca exemplu <?php $brw = $_SERVER["HTTP_USER_AGENT"]; echo " Informatia generala: ".$brw. "<BR>"; // determinare browser if(strstr($brw,"msie 5.0")) $brw = "Microsoft Internet Explorer v5.0"; else if(strstr($brw,"msie 5.5")) $brw = "Microsoft Internet Explorer v5.5"; else if(strstr($brw,"msie 6.0")) $brw = "Microsoft Internet Explorer v6.0"; else if ( strstr($brw, "Netscape")) $brws = "Netscape";

208 208 Manual de Informatică pentru clasa a XII-a else if ( strstr($brw, "Firefox")) $brws = "Firefox"; else if ( strstr($brw, "Mozilla")) $brws = "Mozilla"; else if ( strstr($brw, "Opera")) $brws = "Opera"; else $brw = "Browser necunoscut"; echo " Browser ".$brw. "<BR>"; // adresa IP $ip = $_SERVER["REMOTE_ADDR"]; echo " Adresa IP ".$ip;?> 1. Creaţi un contor pentru un site care să numere vizitatorii site-ului respectiv. Un vizitator cu o anumită adresă IP se numără o singură dată într-o zi, indiferent de numărul de vizite ale site-ului pe care acesta le efectuează. 2. Creaţi un site care afişează o anumită întrebare, la care vizitatorii sunt invitaţi să răspundă alegând o opţiune dintre mai multe, afişate cu ajutorul unor butoane radio. Un vizitator cu o anumită adresă IP poate vota o singură dată într-o zi. În situaţia în care acesta încearcă să voteze de mai multe ori, se va afişa un mesaj prin care acesta este anunţat că a votat deja. Observaţie! În ambele cazuri veţi crea o bază de date cu un singur tabel, care reţine adresa IP a vizitatorului şi (eventual) data efectuării vizitei respective Cum se creează un forum? De câte ori n-am văzut sau am scris în diverse forum-uri... Unele sunt pe marginea unor articole din ziare, altele au scopuri precise, cu discuţii pe anumite teme (limbaje de programare, politică, literatură, etc.). În cele ce urmează ne propunem să creăm un forum mult simplificat, în care cei care doresc scriu mesaje, iar toţi ceilalţi le citesc. De ce avem nevoie pentru a realiza un astfel de forum? A) În primul rând, este necesară o bază de date, s-o numim forum şi un tabel, să-l numim mesaje. Un rând al tabelului va conţine un mesaj. În acest sens, va exista un număr de ordine pentru mesajul respectiv (nr), id-ul celui care a scris mesajul (id), titlul mesajului (titlu) şi textul propriu-zis al acestuia (textul). Script-ul următor, să-l numim f1.php, creează baza de date şi tabelul. Iniţial, tabelul este vid.

209 Capitolul 5. Limbajul PHP 209 <?php // conectarea la MySQL $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) { echo "Nu s-a realizat conectarea la MySQL "; exit; // crearea bazei de date numita baza $rezultat=mysql_query("create DATABASE forum"); if (!$rezultat) { echo "nu s-a reusit crearea bazei de date"; exit; $baza=mysql_select_db("forum"); $interogare="create TABLE mesaje(nr INT UNIQUE KEY AUTO_INCREMENT, id CHAR(20), titlu CHAR(100), textul LONGTEXT)"; $rezultat=mysql_query($interogare); if (!$rezultat) echo mysql_errno().":".mysql_error();?> B) Acum este necesar un script prin care utilizatorul scrie un mesaj. Practic, acesta trebuie să introducă mesajul, adică informaţiile cerute de tabel şi la apăsarea butonului Adauga mesajul să fie trimis către server. <HTML> <HEAD> </HEAD> <BODY> <FORM action="insereaza.php" method ="post"> ID <BR> <INPUT name="id" type="text">; <BR> Titlu <BR> <INPUT name="titlu" type="text">; <BR><BR> Mesajul dv <BR> <TEXTAREA name="mesajul" Figura Pagina care rows="10" cols="30"></textarea> conţine formularul <BR> <INPUT type="submit", value="adauga mesajul"> </FORM> </BODY> </HTML> C) Pe server, informaţiile transmise de către cel care a scris mesajul sunt preluate de către script-ul insereaza.php. Practic, se verifică dacă fiecare câmp în parte este nevid, după care mesajul este memorat în tabel.

210 210 Manual de Informatică pentru clasa a XII-a <?php // conectarea la MySQL $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) echo "Nu s-a realizat conectarea la MySQL "; // conectarea la baza de date $baza=mysql_select_db("forum"); if (!$baza) echo mysql_errno().":".mysql_error(); $id= $_POST['id']; if (strcmp($id,"")==0) { echo "Nu ati introdus ID-ul"; require_once("f2.php"); exit; $titlu= $_POST['titlu']; if (strcmp($titlu,"")==0) { echo "Nu ati scris titlul"; require_once("f2.php"); exit; $mesajul= $_POST['mesajul']; if (strcmp($mesajul,"")==0) { echo "Nu ati scris mesajul"; require_once("f2.php"); exit; $cerere="insert INTO mesaje (id,titlu,textul) VALUES('$id','$titlu','$mesajul')"; $rezultat=mysql_query($cerere); if (!$rezultat) echo mysql_errno().":".mysql_error();?> D) O persoană care doreşte să vizualizeze mesajele scrise de alţii, va apela script-ul următor, f3.php. Practic, acesta afişează tabelul mesajelor. După cum observaţi, pentru un mesaj, nu este afişat textul propriu-zis: Figura Pagina care conţine tabelul mesajelor Pentru a-l vizualiza pe acesta, va trebui să se execute clic pe titlul mesajului. De aici rezultă că titlul va trebui afişat ca un link. Aici intervine ceva interesant. Atunci când se execută clic, se va apela un alt script, f4.php, care va afişa mesajul cerut. Problema este că va trebui să fie cunoscut numărul curent al mesajului respectiv. Prin urmare, este necesar un link care să transmită şi un parametru. Este necesar un apel de forma: f4.php?nr_mesaj. De exemplu, dacă numărul mesajului este 3, vom scrie: f4.php?3. În rest, script-ul f3 afişează datele într-un tabel, aşa cum suntem deja obişnuiţi. <?php $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) {echo "Nu s-a realizat conectarea la MySQL "; exit; //conectarea la baza de date $baza=mysql_select_db("forum");

211 Capitolul 5. Limbajul PHP 211 if (!$baza) {echo mysql_errno().":".mysql_error(); exit; $cerere="select * FROM mesaje"; // in urma interogarii, se returneaza tabelul $rezultat=mysql_query($cerere); if (!$rezultat) { echo mysql_errno().":".mysql_error(); exit; echo "<TABLE BORDER=5>"; // afisam capul de tabel echo "<TR> <TD align='left'><strong>nr.curent <TD align='center'><strong>id<td><strong>titlu mesaj"; while($rand=mysql_fetch_array($rezultat)) { echo "<TR>"; echo "<TD align='right'>".$rand["nr"]. "<TD>".$rand["id"].<TD>"."<A href= ">".$rand["titlu"]."</a>"; echo "</TR>"; echo "</TABLE>";?> E) Script-ul de mai jos, f4.php, apelat de f3.php, primeşte ca parametru de intrare numărul mesajului. Practic, apelează MySQL-ul, deschide baza de date şi afişează corpul mesajului (textul propriu-zis al acestuia), indentificându-l cu ajutorul unei interogări. <?php $nr= $_SERVER["QUERY_STRING"]; $msql=mysql_connect("localhost","root","parolamea"); if(!$msql) {echo "Nu s-a realizat conectarea la MySQL"; exit; // conectarea la baza de date $baza=mysql_select_db("forum"); if (!$baza) {echo mysql_errno().":".mysql_error(); exit; $cerere="select textul FROM mesaje WHERE nr=$nr"; // in urma interogarii, se returneaza tabelul $rezultat=mysql_query($cerere); $rand=mysql_fetch_array($rezultat); echo $rand["textul"];?> 1. Adăugaţi script-ului f3.php o secvenţă în urma căreia, la apăsarea unui buton, să se poată introduce un mesaj (practic, să fie apelat script-ul f2.php). 2. Reproiectaţi aplicaţia astfel încât să existe posibilitatea unui răspuns la un mesaj.

212 212 Manual de Informatică pentru clasa a XII-a Proiectarea paginilor web În acest moment, puteţi spune că aveţi cunoştinţe solide astfel încât să puteţi dezvolta o aplicaţie hipermedia. Definirea modelului conceptual vă ajută la etapa de proiectare a unei baze de date, normalizarea acesteia asigură robusteţe şi siguranţă, iar prin intermediul limbajului MySQL o puteţi implementa. Limbajele HTML şi CSS oferă nenumărate posibilităţi de realizare a interfeţei cu utilizatorul final, iar PHP-ul, accesul la baza de date stocată pe server. Observaţie! Recitiţi Capitolul 1 pentru a vă reaminti noţiunile fundamentale care privesc proiectarea bazelor de date! O planificare riguroasă a proiectului este imperativă şi de cele mai multe ori, ducerea la bun sfârşit a acestuia necesită o întreagă echipă care să lucreze coordonat. Astfel, în cazul în care nu realizaţi proiectul singur, trebuie să formaţi o echipă care să-şi distribuie sarcinile cât mai eficient, în funcţie de aptitudini. Puteţi revedea subcapitolul 1.4. din Partea I, care descrie managementul de proiect. Nimeni nu pleacă la drum fără un plan bine pus la punct. De aceea, înainte de toate, trebuie să fixaţi clar toate etapele pe care trebuie să le parcurgeţi. 1. Trebuie să ştiţi cui i se adresează site-ul pe care doriţi să-l dezvoltaţi şi bineînţeles, discutaţi cu beneficiarul acestuia pentru a obţine toate informaţiile de care aveţi nevoie. În funcţie de datele pe care acesta doreşte să le cunoască despre vizitatorii site-ului sau pe cele care vrea să le reţină în urma interacţiunii cu aceştia, puteţi realiza modelul conceptual al bazei de date. 2. Analizaţi cu atenţie modelul conceptual, iar dacă este cazul, utilizaţi tehnica de normalizare a datelor pentru a preveni eventualele anomalii. 3. Utilizând modelul relaţional al bazelor de date, implementaţi modelul conceptual, iar cu ajutorul limbajului MySQL, creaţi baza de date! 4. Interfaţa grafică cu utilizatorul trebuie să fie bine structurată, simplu de utilizat, iar datele de intrare şi cele de ieşire trebuie alese corespunzător, în funcţie de particularităţile proiectului (revedeţi paragraful 4.23). Nu uitaţi! Realizarea interfeţei grafice reprezintă o etapă esenţială pentru că paginile web sunt unicul loc unde utilizatorul interacţionează în mod direct cu aplicaţia dvs. Upload-aţi pe server fişierele html astfel formate şi testaţi-le cu atenţie! 5. Realizaţi formularele care asigură colectarea şi trimiterea datelor către server. Multe aplicaţii hipermedia conţin formulare care au câmpuri opţionale, permiţând colectarea unor informaţii suplimentare despre utilizatori. 6. Creaţi script-urile PHP care să prelucreze datele introduse de utilizator şi care să răspundă comenzilor recepţionate. 7. La final, testaţi aplicaţia pentru a elimina anumite erori care pot apărea!

213 Capitolul 5. Limbajul PHP 213 De multe ori, codurile sursă pot avea sute de linii de cod, la care trebuie să adăugaţi comentarii sugestive pentru a putea vizualiza rapid secţiuni din cadrul acestora. Corectitudinea datelor introduse de către utilizatori trebuie să fie asigurată prin mesajele ajutătoare sau de eroare care trebuie să se regăsească în cadrul paginilor web se evită astfel introducerea unor informaţii eronate în baza de date. Cu ajutorul variabilelor cookie, puteţi oferi posibilitatea personalizării site-ului, în funcţie de preferinţele utilizatorului (de exemplu: diverse teme care au la bază câte un stil vezi CSS; afişarea informaţiilor de interes listă cu diverse categorii, etc.). Nicio aplicaţie nu poate fi considerată în totalitate terminată, ea fiind deschisă la eventuale îmbunătăţiri. De asemenea, pentru a fi asigurat succesul site-ului web, actualizaţi frecvent informaţiile pentru a ţine la curent vizitatorii fideli! Important! Pentru ca posesorul site-ului să poată vizualiza informaţiile reţinute în baza de date, realizaţi o interfaţă (o pagină web) specială, stabilind de comun acord care date trebuie să fie afişate în respectivele rapoarte, grafice, etc. 1. Care dintre afirmaţiile de mai jos sunt adevărate şi care sunt false? a) Un script PHP este executat de către browser. b) PHP-ul se instalează pe server. c) Un fişier HTML poate conţine un script PHP. d) Formularele se descriu în HTML. 2. Variantă simplificată de test online. Reluaţi problema 1. Veţi crea o pagină HTML care afişează problema şi oferă vizitatorului ca, acolo unde consideră că răspunsul este adevărat, să bifeze un buton de marcare. Datele se trimit către server. Pe server, răspunde un script PHP care, acolo unde vizitatorul a răspuns corect, afişează OK, iar unde nu a răspuns corect, afişează răspunsul corect şi o explicaţie. 3. Dintre afirmaţiile de mai jos, una singură este falsă. Care este? a) Funcţiile PHP admit parametri transferaţi prin referinţă. b) Funcţiile apelate de un script PHP trebuie să fie conţinute de acesta. c) Funcţiile PHP admit parametri transferaţi prin valoare. d) În PHP nu este necesar să declarăm tipul unei variabile. 4. Cum se testează online problema 3 (vedeţi problema 2)?

214 214 Manual de Informatică pentru clasa a XII-a 5. Validarea datelor. Scrieţi un fişier HTML care conţine un formular prin intermediul căruia se pot trimite către server numele vizitatorului şi vârsta sa. Pe server, se va găsi un script care testează dacă numele este alfabetic şi dacă vârsta este între 5 şi 90 de ani. Dacă aceste condiţii sunt îndeplinite, browser-ul va afişa OK, altfel se vor afişa mesaje de eroare corespunzătoare. 6. Semnalarea erorilor găsite la validare. Se cere să se scrie un formular prin care vizitatorul trimite către server un număr întreg din intervalul [1,10] şi un script PHP care verifică valoarea introdusă. În cazul în care valoarea introdusă este corectă, se va afişa OK, altfel se va da un mesaj de eroare, după care se va afişa din nou formularul (vezi figurile de mai jos). a) Formular iniţial b) Mesaj de eroare Figura Figuri propuse pentru problema 6 7. Verificare parolă. Se cere să se scrie un formular prin care i se cere vizitatorului să introducă o parolă. Pe server răspunde un script PHP care verifică parola. În caz de coincidenţă, se va afişa o pagină HTML, la alegerea dvs., iar altfel se va afişa un mesaj de eroare. 8. Imagini la alegere. Să se creeze un formular care conţine o listă. Vizitatorul selectează, după nume, o anumită fotografie şi trimite selecţia sa către server. Acolo, un script PHP afişează imaginea, dar şi lista, pentru ca vizitatorul să poată selecta o altă imagine. 9. Afişarea unui tabel atunci când nu se cunosc de la început datele. Să se creeze un formular care trimite 4 valori către server. Acolo se va găsi un script care afişează cele 4 valori sub forma unui tabel. Vedeţi mai jos. a) Formular iniţial b) Tabelul obţinut Figura Pagini propuse pentru problema 9 (pentru verificare, rezolvările se găsesc la pag. 383)

215 Capitolul 5. Limbajul PHP 215 Formaţi echipe de 2-4 elevi, alegeţi-vă o temă de proiect, fie din temele propuse în această secţiune, fie una propusă chiar de voi. Atenţie! Repartizaţi sarcinile în mod echitabil în cadrul echipei de proiect. Puteţi chiar organiza împreună cu cadrul didactic, un concurs la nivelul clasei sau al şcolii, la care să invitaţi şi alţi profesori din şcoală. Nu uitaţi să documentaţi fiecare presupunere pe care aţi făcut-o în realizarea proiectului! 1. Şeful clasei. Este de preferat ca orice clasă să aibă ales un elev care să se ocupe de problemele administrative. Dacă aveţi sau nu unul, este momentul unui nou scrutin! Nominalizaţi-vă un număr de 4-5 elevi care să candideze pentru acest titlu şi realizaţi o aplicaţie hipermedia care să permită sistemul votului electronic. Bineînţeles, problema poate fi extinsă: fiecare candidat să aibă o pagină separată, unde să poată să-şi facă o campanie electorală cât mai interesantă, rezultatele parţiale sau finale să poată fi vizualizate on-line, etc. Mult succes! 2. Forum. Fie că este vorba de maşini sau calculatoare, probleme personale sau profesionale, tuturor ne place să discutăm pe Internet! Păreri sunt multe şi de multe ori ne place să ne amuzăm sau să deschidem un nou topic pe forum, în speranţa că măcar virtual să ne facem auziţi. Realizaţi un astfel de site web! 3. Vânzare/Cumpărare. Toată lumea a auzit de succesul site-ului E-bay, recunsocut la nivel mondial în lumea comerţului electronic. Chiar dacă nu atât de complex, realizaţi şi voi un site care să permită: posibilitatea creării unui cont care să identifice unic fiecare vizitator; introducerea anunţurilor de tip vânzare/cumpărare; vizualizarea produselor existente în funcţie de categorie, preţ, etc.; afişarea unor rapoarte care să evidenţieze cele mai vândute produse, preferinţele obiectelor cumpărate în funcţie de vârstă, etc.; trimiterea unor mesaje între utilizatori simularea unei căsuţe poştale.

216 PARTEA A III-A CAPITOLUL Iniţiere în utilizarea limbajului Java În acest capitol vom învăţa să scriem programe în limbajul Java. Mai jos sunt prezentate principalele noţiuni pe care le veţi studia: Cum instalăm Java? Primul program Conceptul de Maşină Virtuală Java Care sunt tipurile de aplicaţii Java? Cum introducem comentariile? Afişarea şirurilor de caractere Tipuri de date Operatori Instrucţiuni Masive Citirea datelor de la tastatură Date membru Metode Exemple de utilizare a metodelor Supraîncărcarea metodelor Cuvinte cheie: instalare, maşină virtuală, stand-alone, applet, servlet, date, operatori, instrucţiuni, masive, date membru, metode, supraîncărcare

217 Capitolul 6. Iniţiere în utilizarea limbajului Java 217 După studiul acestui capitol, vom putea scrie programe la nivelul celor scrise în anii trecuţi în Pascal sau C/C++ 1. Limbajul Java este exclusiv orientat către programarea pe obiecte. Pentru a fi uşor de înţeles, în această primă parte, vom recurge la un mic artificiu: programul va fi în întregime conţinut într-o clasă, iar variabilele (datele membru) şi funcţiile (metodele) vor fi statice Cum instalăm Java? Pentru a lucra în Java, utilizăm software-ul pus la dispoziţie de firma Sun, creatoarea limbajului. În cele ce urmează, considerăm că lucrăm sub sistemul de operare Windows 2000 şi calculatorul are acces la Internet. A. Începem prin a download-a softul. Adresa este: Evident, vom alege o versiune recentă pentru sistemul Windows. B. Pentru că software-ul pus la dispoziţie de firma Sun lucrează prin comenzi date de la tastatură (ca în MS-DOS) va trebui să folosim, ca şi în cazul pachetului EasyPHP, programul CMD.exe. Pentru a utiliza cu uşurinţă acest program, vom crea pe Desktop un shortcut către el (vedeţi alăturat). C. Va trebui ca fereastra CMD să fie deschisă în subfolder-ul bin al folder-ului care conţine softul download-at şi instalat. Executaţi clic cu butonul drept al mouse-ului şi selectaţi Properties. La apariţia cutiei alăturate, introduceţi calea folder-ului amintit în edit-ul Start in. Figura 6.1. Cutia de dialog CMD.exe Properties D. Întrucât, în perioada de iniţiere, programele noastre se vor găsi în folder-ul bin, pentru a lucra mai uşor, este recomandabil să creăm pe Desktop şi un shortcut către acest folder. 1 Totuşi, programele pe care le vom putea realiza după studiul acestui capitol nu vor utiliza fişiere. Acestea vor fi tratate în capitolul următor. 2 În acest capitol, din considerente pedagogice, noţiunile de clasă, dată membru statică şi metodă statică nu vor fi explicate, ci doar aplicate în mod mecanic. În capitolul următor, se va reveni asupra acestor noţiuni.

218 218 Manual de Informatică pentru clasa a XII-a E. Deşi de la instalare, mediul Java ar trebui, implicit, să lucreze în folder-ul bin, este bine ca dvs. să-l setaţi corespunzător. În acest scop, vom folosi variabila de sistem CLASSPATH (calea către clase) care este iniţializată cu respectiva cale. Pentru aceasta, vom respecta următorii paşi: 1. Din meniul Start, apelaţi Settings, Control Panel şi System.. 2. Va apărea o cutie de dialog în care selectaţi Advanced şi Environment Variables...: Figura 6.2. Cutia de dialog System Properties 3. În cutia de dialog de mai jos, apăsaţi New: Figura 6.3. Cutia de dialog Environment Variables 4. În cutia de dialog din figura alăturată, introduceţi numele variabilei de sistem (CLASSPATH), apoi calea către folder-ul bin. Atenţie! Calea trebuie să corespundă locului unde aveţi instalat mediul Java pe calculatorul dvs. Apoi, apăsaţi OK! Figura 6.4. Cutia de dialog New User Variable

219 Capitolul 6. Iniţiere în utilizarea limbajului Java Primul program De acum putem scrie primul program. Trebuie să ştim că mediul Java, pus la dispoziţie de firma Sun, nu ne oferă un editor de text. Din acest motiv, textul programului va fi introdus cu ajutorul NOTEPAD-ului, dar va trebui să fim atenţi ca extensia fişierului text astfel obţinut să fie.java. Nu uitaţi! Pentru început, fişierul text care conţine programul trebuie să se găsească în folder-ul bin. Pentru a introduce şi rula un program, vom respecta paşii următori: A. Vom deschide shortcut-ul către bin din meniul flotant, vom alege New şi Text Document, apoi schimbăm numele fişierului în prima.java. Fişierul cu acest nume va fi deschis din meniul flotant asociat, cu Open with... şi Notepad. Apoi, se introduce programul de mai jos, care afişează mesajul Acesta este primul program Java şi salvăm programul: class prima { public static void main(string[] args) { System.out.println("Acesta este primul program Java"); Este obligatoriu ca numele clasei să coincidă cu numele fişierului. În exemplu, clasa se numeşte prima, iar fişierul este prima.java. Este obligatoriu ca extensia fişierului text să fie.java! B. Din fereastra CMD, apelăm compilatorul Java prin comanda: javac prima.java În urma acestei comenzi, se va crea fişierul prima.class. Acest fişier conţine programul compilat. Verificaţi existenţa lui în bin! C. Pentru a executa programul astfel compilat, vom da comanda: Iată cum arată acum fereastra CMD: java prima Figura 6.5. Fereastra CMD după rularea programului

220 220 Manual de Informatică pentru clasa a XII-a Perfect! Dacă aţi reuşit să rulaţi acest prim program, aţi făcut un pas important. Înseamnă că aţi instalat corect mediul şi de acum puteţi lucra liniştit. Sunt mulţi cei care se împotmolesc în acest punct şi din acest motiv, renunţă Să aruncăm o privire asupra programului: Orice program este inclus într-o clasă. Noţiunea de clasă aparţine programării orientate pe obiecte şi va fi explicată pe larg. În exemplu, clasa se numeşte prima. Aşa cum s-a precizat, numele clasei trebuie să coincidă cu numele fişierului text sursă (cel creat cu NOTEPAD), numai că acesta din urmă trebuie să aibă extensia.java. Orice program are o metodă (funcţie main()) şi executarea sa începe cu instrucţiunile acestei metode. În exemplu, programul afişează un şir de caractere. Instrucţiunea (apelul de metodă) care afişează acest şir de caractere este system.out.println(). După afişare, cursorul sare pe rândul următor. În Java, în locul termenului deja consacrat funcţie, vom folosi pe acela de metodă. Este obligatoriu ca metoda main() să conţină anumiţi parametri de intrare: String[] args. Asupra semnificaţiei acestor parametri revenim în capitolul următor. Elementele public şi static sunt modificatori. Prezenţa lor în antetul metodei main() este obligatorie. Şi asupra lor vom reveni. void este tipul metodei main(). Semnificaţia este cea din C++, adică metoda nu returnează nici o valoare. În Java, se face distincţie între literele mari şi cele mici. De exemplu, Mama şi mama sunt identificatori diferiţi Conceptul de Maşină Virtuală Java (JVM) Una dintre cerinţele care au stat la baza creării limbajului Java a fost aceea de a obţine un limbaj portabil. Aceasta înseamnă că un program scris pe un anumit calculator, pe care rulează un anumit sistem de operare, să poată rula fără modificări şi pe un alt calculator, pe care rulează alt sistem de operare. De exemplu, să se poată scrie un program care să fie rulat pe Windows şi pe Linux. Pentru a rezolva această problemă, cei de la Sun au recurs la următorul procedeu:

221 Capitolul 6. Iniţiere în utilizarea limbajului Java 221 Fiecare utilizator al unui sistem de operare poate download-a mediul specific acelui sistem de operare. De aceast lucru v-aţi convins atunci când aţi download-at mediul pentru Windows. Mediul specific pentru un anumit sistem de operare conţine un compilator special creat pentru el, care preia programul din fişierul sursă şi îl traduce într-un cod anume, numit byte-code. Compilatorul este programul javac, iar fişierul compilat are extensia.class. Programele în byte-code sunt rulate pe aşa numita Maşină Virtuală Java (JVM). Maşina virtuală Java este un suport software care trebuie să fie instalat pe calculatoarele care rulează astfel de fişiere. Când aţi instalat Java, implicit aţi instalat şi maşina virtuală Java. De altfel, maşina virtuală Java poate fi instalată şi în absenţa mediului de dezvoltare Java. Un fişier în byte-code (extensia.class) poate fi rulat pe orice calculator, indiferent de sistemul de operare pe care-l are, dacă are instalată maşina virtuală Java. Practic, se ia prima instrucţiune din fişierul byte-code, este tradusă în instrucţiuni ale calculatorului pe care rulează aplicaţia şi acestea din urmă sunt executate; se ia o a doua instrucţiune din byte-code care se traduce şi se rulează, ş.a.m.d. Se poate observa că Java are şi un compilator care traduce sursa în byte-code (javac.exe) dar şi un interpreter care traduce şi execută fiecare instrucţiune din byte-code în instrucţiuni ale calculatorului pe care se execută aplicaţia. Observaţie! Datorită faptului că Java este înzestrat cu interpreter (ia o instrucţiune, o traduce şi o execută, apoi altă instrucţiune, o traduce şi o execută,...), programele se execută mai lent. Acest fapt este compensat de procesoarele din ce în ce mai performante, dar şi de performanţele interpreter-ului Tipuri de aplicaţii Java În Java există trei tipuri de aplicaţii: 1. Aplicaţii de sine stătătoare (stand-alone). Acestea sunt precum aplicaţiile studiate în Pascal sau C++: se rulează pe un anumit calculator. 2. Aplicaţii care se rulează pe partea de client (applet-uri). Un applet este alcătuit dintr-unul sau mai multe fişiere cu extensia.class şi este utilizat în cadrul paginilor web. Practic, el este ataşat textului HTML, la fel cum se ataşează o imagine, iar fişierele care-l alcătuiesc se transferă pe site. El este adus pe calculatorul clientului atunci când se apelează pagina respectivă şi este executat prin intermediul browser-ului. 3. Aplicaţii care se execută pe partea de server (servlet-uri).

222 222 Manual de Informatică pentru clasa a XII-a 6.5. Comentarii În Java, se pot introduce comentarii oriunde dorim, la fel ca şi în cazul limbajului C++. Ele sunt de două feluri: 1. Comentariile la nivel de linie: // tot ce urmează după ele, pe linia celor două caractere, este considerat comentariu. 2. Comentarii pe mai multe linii se găsesc între /* şi */. Exemplul 6.1. Cod sursă care conţine comentarii: class prima { // un comentariu public static void main(string[] args) { /* Acesta este alt comentariu */ System.out.println("Acesta este primul program Java"); 6.6. Afişarea şirurilor de caractere Pentru afişarea datelor vom utiliza două metode: 1. System.out.print(sir_de_caractere); 2. System.out.println(sir_de_caractere); Ambele metode afişează şirul de caractere căutat. Diferenţa dintre ele este dată de faptul că după afişare: în primul caz, cursorul rămâne pe rândul curent (după ultimul caracter scris), iar în cazul al doilea, după ce s-a scris şirul de caractere, cursorul trece pe linia următoare Tipuri de date În teoria clasică a limbajelor de programare, prin tip de date se înţelege: o mulţime de valori; o mulţime de operaţii definite pe mulţimea valorilor. Limbajul Java extinde noţiunea de tip de date, la aceea de tip. Aici se lucrează cu clase, care descriu într-o unică structură atât date cât şi metode (funcţii). Obiectele sunt instanţieri ale claselor, deci fiecare obiect conţine atât date

223 Capitolul 6. Iniţiere în utilizarea limbajului Java 223 cât şi metode. Asupra acestor probleme vom reveni, dar reţineţi faptul că, în Java, prin tip vom înţelege o clasă, iar un obiect are un anumit tip dacă rezultă ca instanţiere a unei clase. Totuşi, limbajul Java utilizează şi tipuri în sens clasic, vezi prima definiţie. Pentru a nu se crea confuzii, aceste tipuri se numesc tipuri primitive. Astfel, avem tipuri de date primitive şi tipuri referinţă Tipurile de date primitive a) Tipuri întregi Tip Octeţi ocupaţi Numere întregi din intervalul byte 1 [-128,127] short 2 [-32768,32768] int 4 [ , ] long 8 [ , ] Tabelul 6.1. Tipuri de date întregi Exemplul 6.2. Declarăm şi afişăm mai multe variabile de tip întreg: short t=32767; byte z=-128, x=15; int a=100000; b) Tipuri reale Tip Octeţi ocupaţi Modulul valorilor între float 4 [ , ] double 8 [ , ] Tabelul 6.2. Tipuri de date reale Pentru iniţializarea tipurilor reale se folosesc literali. Observaţie! Pentru tipul real float, literalii trebuie urmaţi în mod obligatoriu de litera f. Excepţie fac literalii care reprezintă valori întregi. Exemplul 6.3. Priviţi iniţializările de mai jos: 1. float a=3,b=2.5f,c=-7,d=3e2f,g=-2.4e-2f; Valorile cu care am iniţializat variabilele sunt: 3, 2, 2.5, -7, , Aceleaşi valori se folosesc pentru a iniţializa variabile de tip double: 2. double a=3,b=2.5,c=-7,d=3e2,g=-2.4e-2;

224 224 Manual de Informatică pentru clasa a XII-a c) Tipul char O variabilă de tipul char reţine un caracter. În Pascal, C/C++, caracterele sunt reţinute prin utilizarea codului ASCII. În Java, codul utilizat pentru memorarea caracterelor este Unicode şi, în acest cod, un caracter ocupă 2 octeţi. Exemplul 6.4. Mai jos, puteţi observa declaraţia a trei variabile de tip char: char a='m', b='\u006d', c=109; System.out.println(a); System.out.println(b); System.out.println(c); Toate variabilele reţin caracterul m. Prima dată, caracterul este declarat în mod clasic, iar a doua oară, este declarat prin codul său în hexa şi a treia oară este declarat în zecimal. Cele afirmate sunt probate prin afişare, pentru că se afişează de trei ori m. Caracterele se pot declara sub formă de coduri escape: Caracter Semnificaţie \\ backslash \n newline \' apostrof \ ghilimele \r carriage return \t tab \f salt la pagină nouă Tabelul 6.3. Tipuri de caractere sub formă escape Exemplul 6.5. Priviţi declaraţiile de mai jos: 1. char a='\''; am declarat caracterul apostrof. Dacă am încerca să declarăm acest caracter prin char a='''; primim eroare de sintaxă. 2. char b='\n'; am declarat caracterul newline. Dacă se afişează acest caracter, cursorul sare pe linia următoare. 3. char c='\\'; am declarat caracterul backslash. Dacă am încerca să declarăm acest caracter prin char a='\'; primim eroare de sintaxă. d) Tipul boolean O variabilă de acest tip poate reţine la un moment dat, una din cele două valori: false (fals) sau true (adevărat). Exemplul 6.6. Se declară, se iniţializează şi se afişează conţinutul unei variabile de tip boolean: boolean c=true; System.out.println(c); Observaţie! Metodele System.out.print() şi System.out.println() permit afişarea tuturor tipurilor primitive.

225 Capitolul 6. Iniţiere în utilizarea limbajului Java Tipul referinţă O variabilă de tip referinţă reţine o referinţă (adresă) către un obiect. Cu ajutorul referinţei, putem accesa datele membru şi metodele obiectului. Numele tipului unei astfel de variabile coincide cu numele clasei. Cum obiectele sunt instanţieri ale claselor şi cum putem proiecta o infinitate de clase, înseamnă că există o infinitate de tipuri referinţă. Prin abuz de limbaj, vom spune despre o variabilă care poate reţine o referinţă către un anumit obiect că este de tip referinţă. Orice variabilă de tip referinţă poate reţine valoarea null. Ea are semnificaţia de nici o referinţă Observaţii importante Cu ajutorul celor două metode: System.out.print() şi System.out.println(), putem afişa conţinuturile variabilelor de un tip primitiv. Mai avem de precizat două lucruri esenţiale: a. Dacă în corpul unei metode, în exemplu main(), se găseşte o variabilă neiniţializată şi se încearcă afişarea conţinutului pe care îl are, tentativa este sancţionată prin eroare de sintaxă. Vedeţi mai jos: int i; System.out.println(i); b. Avem posibilitatea de a afişa mai multe variabile pe aceeaşi linie. Aceasta se obţine prin convertirea conţinutului variabilelor în şiruri de caractere şi concatenarea şirurilor cu ajutorul operatorului +. Vedeţi exemplul de mai jos care afişează pe o linie a=2 b=4.5: int a=2; float b=4.5f; System.out.println("a="+a+" b="+b); 6.8. Operatori În acest paragraf vor fi prezentaţi operatorii utilizaţi în Java Operatori aritmetici Există următorii operatori aritmetici: - minus (unar, adică acţionează asupra unui singur operand); + plus (unar); + (binar), pentru adunare;

226 226 Manual de Informatică pentru clasa a XII-a - (binar), pentru scădere; * (binar), are semnificaţia de înmulţire; / (binar), pentru împărţire; % (binar) restul împărţirii întregi. Observaţii! Operatorul '/' (împărţire) acţionează în mod diferit în funcţie de operanzi: a) dacă ambii sunt de tip întreg, rezultatul este întreg şi are semnificaţia de împărţire întreagă. Cu toate acestea, rezultatul este corect (din punct de vedere matematic) numai dacă valorile care se împart sunt pozitive. b) dacă cel puţin un operand este de unul din tipurile reale rezultatul este real (se efectuează împărţirea obişnuită). Operatorul '%' acţionează numai asupra operanzilor de tip întreg. Rezultatul obţinut este corect din punct de vedere matematic numai dacă ambii operanzi sunt numere naturale. În cazul în care se împart două valori întregi se procedează astfel: se face împărţirea întreagă a celor două valori care sunt considerate în modul; semnul câtului se stabileşte după regula semnelor (+ cu + rezultă +, + cu -, rezultă -), etc. în cazul operatorului '%', se face împărţirea ca anterior (se obţine C), iar restul se obţine după formula R=D-Î C. se pot utiliza oricâte perechi de paranteze rotunde, pentru a impune ca anumite operaţii să se facă prioritar. Exemplul 6.7. Fie declaraţia: int a=10;. Atunci expresia 4*a/3 este de tip int şi la evaluare se obţine 13. S-a înmulţit 4 cu conţinutul variabilei a (10) şi s-a obţinut 40. Apoi, 40/3=13 (a fost efectuată împărţirea întreagă). În aceleaşi condiţii, expresia 4*(a/3) are ca rezultat numărul 12. La început s-a efectuat a/3 şi s-a obţinut 3, apoi 4*3=12. Iată un exemplu în care se observă faptul că una este o expresie la matematică, şi alta în Java. Exemplul 6.8. Fie declaraţia: float a=10;. Expresia 4*(a/3) are rezultatul , la fel ca expresia 4*a/3. De această dată, s-a efectuat împărţirea a două numere reale. Exemplul 6.9. Fie declaraţia: int a= -10;. Atunci expresia a%3 are ca rezultat numărul -1. Exemplul Fie declaraţia: int a=-10;. Atunci expresia a*-3 are ca rezultat numărul 30.

227 Capitolul 6. Iniţiere în utilizarea limbajului Java 227 Exemplul Fie declaraţiile: int a=10; char b=2; float c=5;. Atunci expresia: a+b+c are rezultatul În exemple, apare o problemă foarte importantă: care este tipul rezultatului, în cazul în care o expresie aritmetică are operanzi de mai multe tipuri? Problema de mai sus se numeşte problema conversiilor aritmetice implicite (după cum vom vedea, conversiile se pot face şi explicit). Regula generală este: se converteşte unul din operanzi către tipul celuilalt (mai cuprinzător). De exemplu, dacă unul din operanzi este de tip int, iar celălalt de tip float, rezultatul va fi de tip float. Observaţie! Fără o conversie prealabilă, operatorii aritmetici nu acţionează asupra variabilelor de tip char. De exemplu, secvenţa char x= 1 ; x=x+1; este eronată din punct de vedere sintactic Operatori relaţionali În Java există următorii operatori relaţionali: < (mai mic); <= (mai mic sau egal); > (mai mare); >= (mai mare sau egal). Întrucât în Java există valorile logice true şi false, rezultatul unei operaţii logice este una dintre aceste valori. Exemplul Analizaţi expresiile de mai jos: 3>5 - expresia ia valoarea false; 3<5 - expresia ia valoarea true; 3+7>= expresia ia valoarea true (este posibil să scriem astfel de expresii, întrucât operatorii relaţionali au o prioritate mai mică decât operatorul aditiv) Operatori de egalitate Operatorii de egalitate sunt: == pentru egalitate;!= pentru inegalitate. Ca şi operatorii relaţionali, expresiile de acest tip returnează 0 sau 1, în funcţie de modul în care este respectată sau nu egalitatea (inegalitatea). Exemplul Expresiile: 3==3 are ca rezultat true; 3!=3 are ca rezultat false.

228 228 Manual de Informatică pentru clasa a XII-a Operatorii de incrementare şi decrementare Aceşti operatori sunt unari şi au rolul de a incrementa (adună 1) sau de a decrementa (scad 1) conţinutul unei variabile. Operatorii sunt: ++ pentru incrementare; -- pentru decrementare. Operatorii pot fi prefixaţi (aplicaţi în faţa operandului) sau postfixaţi (aplicaţi după operand). Exemplu: fie a o variabilă de tip int. Operatorul de incrementare prefixat aplicat variabilei a este ++a. Operatorul de incrementare postfixat aplicat variabilei a este a++. Operatorul de decrementare prefixat aplicat variabilei a este -a. Operatorul de decrementare postfixat aplicat variabilei a este a--. Care este diferenţa între efectul unui operator aplicat prefixat sau postfixat? Să ne gândim la faptul că pot fi expresii care conţin şi alţi operatori în afara celor de incrementare (decrementare). Dacă operatorul este prefixat, variabila este incrementată (decrementată) înainte ca valoarea reţinută de ea să intre în calcul. Dacă operatorul este postfixat, variabila este incrementată (decrementată) după ce valoarea reţinută de ea intră în calcul. Exemplul Fie a o variabilă de tip int care reţine valoarea 1. În urma evaluării expresiei 1+a++ se obţine valoarea 2, dar după evaluare, a va reţine valoarea 2 (variabila a fost incrementată după ce valoarea reţinută de ea a intrat în calcul). Exemplul La fel ca în cazul anterior, expresia 1-++a produce valoarea -1 (variabila a fost întâi incrementată, s-a obţinut 2, apoi s-a efectuat 1-2) Operatori logici Există trei tipuri de operatori logici care acţionează asupra datelor de tip boolean:! negare logică; && şi logic; sau logic. Aceşti operatori se aplică oricărei variabile şi constante de tip logic. Operatorul negare logică acţionează astfel: dacă operandul este o valoare true, rezultatul este false, altfel rezultatul este true. Operatorul şi logic (binar) acţionează astfel: dacă ambii operanzi sunt true rezultatul este true, altfel el este false.

229 Capitolul 6. Iniţiere în utilizarea limbajului Java 229 Operatorul sau logic (binar) acţionează astfel: dacă cel puţin unul din operanzi este true, rezultatul este true, altfel rezultatul este false. Exemplul În condiţiile: boolean a=true, b=false;!a returnează false; a b returnează true; a&&b returnează false; Operatorii logici binari garantează modul în care se tratează operanzii - întâi cel din stânga, apoi (dacă este cazul) cei din dreapta. Astfel, dacă operandul din stânga este true, operatorul sau logic nu mai acţionează asupra operandului din dreapta (este clar că rezultatul este true). Tot aşa, dacă operandul din stânga este false, operatorul şi logic nu mai evaluează operandul din dreapta (oricum rezultatul este false). Observaţia este foarte importantă pentru cazul în care al doilea argument este funcţie (metodă) de tip boolean Operatori logici pe biţi Limbajul Java este dotat cu un set de operatori care permit accesul la bit. Aceştia sunt: <<, >>, >>> operatori de deplasare; & şi pe biţi; sau pe biţi; ^ sau exclusiv pe biţi; ~ negare pe biţi (operator unar). Aceşti operatori acţionează numai asupra operanzilor de tip întreg. Operatorul << este binar. El are rolul de a deplasa către stânga conţinutul tuturor biţilor operandului din stânga sa, cu un număr de poziţii egal cu valoarea reţinută de al doilea operand. Poziţiile rămase libere (în dreapta) vor reţine valoarea 0. Dacă al doilea operand reţine valoarea m, o astfel de deplasare este echivalentă cu înmulţirea cu 2 m (evident, dacă m este mai mic decât numărul de biţi rezervat primului operand). Operatorul >> este binar. El are rolul de a deplasa către dreapta conţinutul tuturor biţilor operandului din stânga cu un număr de poziţii egal cu valoarea reţinută de al doilea operand. Atenţie: în poziţiile din stânga, rămase libere după deplasare, se copiază conţinutul bitului de semn (acesta reţine 1 în cazul numerelor negative şi 0, în cazul numerelor pozitive). Dacă operandul din stânga este un întreg pozitiv, poziţiile rămase libere (în stânga) vor reţine valoarea 0. În cazul întregilor pozitivi, dacă al doilea operand reţine valoarea m, o astfel de deplasare este echivalentă cu împărţirea întreagă cu 2 m. Operatorul >>> acţionează la fel ca şi operatorul >>, dar diferenţa este dată de faptul că poziţiile rămase libere din dreapta vor reţine 0.

230 230 Manual de Informatică pentru clasa a XII-a Atenţie! Operatorii de deplasare sunt utilizaţi doar pentru evaluarea expresiilor, operanzii, chiar dacă sunt variabile, rămân nemodificaţi! Desigur, valorile astfel obţinute pot fi atribuite. Aceasta înseamnă de fapt acces la bit. În cazul operatorilor binari &, ^,, rezultatul se obţine aplicând pentru fiecare pereche de biţi aflaţi pe aceeaşi poziţie regulile din tabelul următor: OP 1 OP 2 OP 1 &OP 2 OP 1^OP 2 OP 1 OP Tabelul 6.4. Rezultatele operatorilor binari Operatorul ~ (negare pe biţi) are rolul de a inversa conţinutul biţilor (dacă un bit conţine 0 va conţine 1 şi invers). Exemplul Dacă a este de tip int şi reţine 3, iar b este de acelaşi tip şi reţine 1, atunci: a&b returnează 1; a b returnează 3; a^b returnează 2; a<<2 returnează 6; a>>1 returnează 1; ~a returnează Operatori de atribuire În Java atribuirea este operator, dar după cum vom vedea, este şi instrucţiune. În plus, avem mai mulţi operatori de atribuire. Operatorul '=' se foloseşte într-o expresie de forma: Aici, v este o variabilă. v=expresie Principiul de executare este următorul: se evaluează expresia; variabilei v i se atribuie valoarea obţinută (dacă este cazul se efectuează conversia respectivă). Se pot efectua şi atribuiri multiple de forma: unde v, v 1, v 2,..., v n sunt variabile. v=v 1 =v 2 =...=v n =expresie,

231 Capitolul 6. Iniţiere în utilizarea limbajului Java 231 În acest caz, principiul de executare este următorul: se evaluează expresia; valoarea obţinută este atribuită variabilei v n (eventual convertită, dacă este cazul); conţinutul variabilei v n este atribuit variabilei v n-1 (eventual se efectuează conversia necesară);... conţinutul variabilei v 1 este atribuit variabilei v (eventual se efectuează conversia necesară). Acest operator se asociază de la dreapta la stânga. Ce am prezentat anterior evidenţiază acest lucru. Pentru atribuiri se mai pot utiliza şi operatorii: *=, /=, %=, +=, -=, <<=, >>=, &>, ^=, =. O atribuire de forma: v op=expresie, are acelaşi rezultat ca v=v op expresie (diferenţa este că în primul caz se generează un cod maşină eficient). Observaţie! Am văzut că atribuirea este un operator care figurează într-o expresie. Ca orice expresie, aceasta are o valoare rezultată în urma evaluării. În cazul atribuirilor, valoarea rezultată este valoarea atribuită variabilei care este prima din stânga, (într-un şir de atribuiri, eventual după conversie). Exemplul Fie declaraţiile: int a=5, b=3; float c;. În urma atribuirii c=a/b, c va conţine valoarea reală 1.0. Este normal să fie aşa întrucât expresia a/b este de tip int (se efectuează împărţirea întreagă şi se obţine 1), apoi această valoare este atribuită variabilei c (după ce este convertită). Exemplul Fie declaraţiile: int a,b; float c; şi expresia c=a=b=1. După evaluare, a reţine 1, b reţine 1, c reţine 1.0, iar valoarea rezultată în urma evaluării este 1.0 (reală). Exemplul Fie declaraţia: int a=3; şi expresia a*=2. În urma evaluării, a reţine valoarea 6, iar expresia va produce valoarea de tip int 6. Observaţie foarte importantă! Sunt permise doar atribuiri în care tipul variabilei căreia i se atribuie conţinutul unei variabile de alt tip, conţine, printre valorile permise, cele ale tipului variabilei care este atribuită. Exemplul Fie declaraţiile: long a=2; int b=3; a=b; // corect b=a; // incorect

232 232 Manual de Informatică pentru clasa a XII-a Exemplul Fie declaraţiile: char a=2; int b=3; b=a; //corect a=b; //incorect Exemplul Fie declaraţiile: float a=2; int b=3; a=b; //corect b=a; //incorect Exemplul Fie declaraţiile: float a=2; double b=3; b=a; //corect a=b; //incorect Observaţie! După cum observaţi, aici apare o diferenţă faţă de C/C++. Java, ca şi Pascal-ul, încearcă să te ferească de erori ascunse, rezultate în urma conversiilor implicite Operatorul condiţional Se foloseşte în expresii de genul: exp 1?exp 2 :exp 3 Cerinţa este ca exp 1 să fie de tipul boolean. Principiul de executare este următorul: se evaluează exp 1 ; dacă aceasta produce true, se evaluează exp 2 şi exp 3 este ignorată (nu se evaluează); altfel, se evaluează exp 3 şi exp 2 este ignorată. În ansamblu, expresia este de tipul lui exp 2 sau exp 3 şi produce valoarea exp 2 sau exp 3 (în funcţie de cea care se evaluează). Exemplul Variabila c ia valoarea 5 (valoarea maximă). int a=1, b=5, c; c=a>b?a:b; Exemplul Se afişează valoarea 5. int a=1, b=5, c; System.out.println(a>b?a:b); Exemplul Variabila h ia valoarea 9. Aici se observă că nu este obligatoriu ca exp 2 şi exp 3 să aibă acelaşi tip: int a=1, b=5; float d=9,h; h=a>b?a:d;

233 Capitolul 6. Iniţiere în utilizarea limbajului Java Operatorul de conversie explicită De multe ori, vrem ca unul sau mai mulţi operanzi să intre în calcul convertiţi aşa cum dorim (nu implicit). Pentru aceasta, înaintea operandului se trece între paranteze tipul său. Exemplul Variabila a ia valoarea 9. Iată că, deşi implicit conversia nu poate fi realizată, în acest mod s-a efectuat fără probleme. int a=1; double d=9.6; a=(int)d; Exemplul Se afişează 0.5. Iată că, deşi operanzii sunt întregi şi rezultatul ar trebui să fie 0, prin utilizarea operatorului de conversie explicită se obţine rezultatul corect. int a=3, b=6; System.out.println((float) a/b); Prioritatea (precedenţa) operatorilor Operatorii au o anumită prioritate (precedenţă). Mai jos, sunt prezentaţi operatorii în ordinea descrescătoare a priorităţii: 1) (),., [] 2) ++, --, +(unar), (unar),!, new, operatorul de conversie explicită 3) *, /, % 4) +, - (priviţi ca operatori binari) 5) <<, >>, >>> 6) <, <=, >, >= 7) ==,!= 8) & 9) ^ 10) 11) && 12) 13)?: 14) =, +=, etc (operatori de atribuire)

234 234 Manual de Informatică pentru clasa a XII-a 6.9. Instrucţiuni Instrucţiunea vidă Instrucţiunea nu face nimic, dar are sens în programul Java, după cum va rezulta din studiul altor instrucţiuni. Instrucţiunea vidă se marchează prin ; Instrucţiunea compusă Se utilizează atunci când se doreşte ca mai multe instrucţiuni să fie considerate ca o singură instrucţiune. Exemplul Mai jos, puteţi observa o instrucţiune compusă care subordonează mai multe instrucţiuni vide. { ; ; ; Instrucţiunile de incrementare şi de decrementare Se utilizează pentru a incrementa sau decrementa o anumită variabilă. Exemplul Diverse incrementări/decrementări: a++; ++a; a--; --a;. Observaţie! Există o diferenţă între operatorii de incrementare (decrementare) şi instrucţiunea de incrementare (decrementare). Instrucţiunea de incrementare (decrementare) conţine numai un operator de incrementare (decrementare), dar de exemplu, b=++a+1 este o instrucţiune (atribuire, vezi mai jos) care conţine şi un operator de incrementare Instrucţiunea de atribuire Conţine o expresie prin care unei variabile i se atribuie o altă expresie (aflată în dreapta operatorului de atribuire). Exemplul Analizaţi atribuirile următoare: a) int a, b=6; a=b+5; // după atribuire a reţine 11.

235 Capitolul 6. Iniţiere în utilizarea limbajului Java 235 b) int a, b=6; a=++b+5; // după atribuire a reţine 12. c) int a=1, b=6; a+=b; // după atribuire a reţine 7. d) a=b=c=1; // a, b, c sunt de tip int. Exemplul Iată o atribuire multiplă. Iniţial, c ia valoarea 1, apoi b=c, atunci b=1, apoi a=b, deci a=1. După atribuire a, b, şi c reţin 1. Observaţii! Nu sunt permise atribuiri de genul: ++a=b+5;. Există o diferenţă între operatorul de atribuire şi instrucţiunea de atribuire. De exemplu, a=b=c=1 este o instrucţiune de atribuire, dar conţine 3 operatori (de atribuire). Practic, o instrucţiune de atribuire conţine cel puţin un operator de atribuire Instrucţiunea IF Această instrucţiune are două forme: Forma 1. if (expresie de tip boolean) instrucţiune 1 else instrucţiune 2 Principiul de executare este următorul: se evaluează expresia; dacă valoarea produsă de aceasta este true, se execută instrucţiune 1 ; dacă valoarea produsă este false se execută instrucţiune 2. Forma 2. if (expresie de tip boolean) instrucţiune Principiul de executare este următorul: se evaluează expresia; dacă valoarea produsă de aceasta este true, se execută instrucţiunea subordonată, altfel se trece la cea următoare. Exemplul Se afişează cea mai mare valoare dintre valorile reţinute de variabilele a şi b: if (a>b) System.out.println(a); else System.out.println(b);

236 236 Manual de Informatică pentru clasa a XII-a Exemplul Se rezolvă ecuaţia ax+b=0, unde pentru valorile lui a şi b sunt reţinute variabilele cu acelaşi nume. if (a!=0) { x=-b/a; System.out.println(x); else if (b==0) System.out.println("infinitate de solutii"); else System.out.println("nu are solutie"); Instrucţiunea WHILE Forma generală a acestei instrucţiuni este: while (expresie de tip boolean) instrucţiune Principiul de executare este următorul: Se evaluează expresia; Dacă valoarea produsă de aceasta este true, se execută instrucţiunea subordonată, apoi se revine la evaluarea expresiei, altfel se trece la instrucţiunea următoare. Exemplul Pentru n>0, număr natural, să se calculeze suma cifrelor sale (pentru n=213, se va afişa 6): int n=213,s=0; while (n!=0) { s+=n%10; n/=10; System.out.println(s); Instrucţiunea DO WHILE Forma generală a acestei instrucţiuni este următoarea: do instrucţiune while(expresie); Principiul de executare este următorul: Se execută instrucţiunea subordonată; Se evaluează expresia. În cazul în care valoarea produsă la evaluare este false, executarea instrucţiunii do while se termină, altfel se trece la pasul anterior.

237 Capitolul 6. Iniţiere în utilizarea limbajului Java 237 Observaţie! Secvenţa se execută cel puţin o dată, după care se pune problema dacă să se repete sau nu (prin evaluarea expresiei logice). Exemplul Se dă un număr natural n, mai mare sau egal cu 1. Să se calculeze suma primelor n numere naturale nenule. int n=10,s=0,i=1; do { s=s+i; i=i+1; while (i<=n); System.out.println(s); Instrucţiunea FOR Instrucţiunea FOR are forma generală: for(expresie iniţializare ;expresie test ;expresie incrementare ) instrucţiune După cum se vede, între paranteze se găsesc 3 expresii: Expresie initializare se foloseşte de regulă pentru iniţializarea variabilei de ciclare. Este de remarcat faptul că în cadrul acestei expresii (cu rol special) este posibil chiar să declarăm variabila de ciclare (cu valoare iniţială). Expresie test este de tip boolean şi se foloseşte pentru a testa dacă se execută instrucţiunea subordonată - dacă expresia produce la evaluare true, instrucţiunea subordonată for se execută. Expresie incrementare se foloseşte pentru incrementarea variabilei de ciclare. Principiul de executare este: P1. Se evaluează expresie iniţializare (un caz special este când aceasta conţine şi declaraţia variabilei de ciclare); P2. Se evaluează expresie test. În cazul în care aceasta produce true, se execută instrucţiunea subordonată for; apoi se trece la P3, altfel se trece la instrucţiunea următoare (se termină executarea instrucţiunii for). P3. Se evaluează expresia de incrementare şi se revine la P2. Observaţie! Toate expresiile pot fi vide. În concluzie, expresiile de mai sus au rolul precizat în mod normal - dar nu obligatoriu şi nici restrictiv. De exemplu, dacă expresie test este vidă, se execută un ciclu infinit for(;;) instrucţiune. Exemplul Se afişează numerele, 10, 9,..., 1, fiecare pe câte un rând. Observaţi faptul că variabila i a fost declarată în cadrul ciclului for. for (int i=10;i>=1;i--) System.out.println(i);

238 238 Manual de Informatică pentru clasa a XII-a Exemplul Se afişează alfabetul, de la a la z şi pentru fiecare caracter se afişează şi codul său: for (char c='a';c<='z';c++) System.out.println(c+" "+(int)c); Instrucţiunea BREAK Are rolul de a forţa ieşirea dintr-un ciclu. În cazul în care există cicluri imbricate (un ciclu în interiorul altui ciclu), forţează doar ieşirea din primul ciclu (vezi secvenţa următoare, unde for-ul după j se execută doar pentru j=1). Se foloseşte pentru instrucţiunile for, while, do while şi în particular, pentru switch (cazul va fi studiat separat). Exemplul Analizaţi secvenţa de mai jos: for (int i=1;i<=4;i++) for (int j=1;j<=4;j++) if (j==2) break; else System.out.println(i+" "+j); Se afişează: Instrucţiunea CONTINUE Instrucţiunea este folosită în cazul ciclurilor (for, while, do while) şi are rolul de a determina ca, după executarea ei, să se sară direct la testul condiţiei de continuare. Astfel, se ignoră instrucţiunile care îi urmează în secvenţa care se repetă. Exemplul Secvenţa următoare afişează: 1, 3, 4. Dacă i ia valoarea 2, atunci se execută continue şi se sare peste apelul metodei de afişare. for (int i=1;i<=4;i++) { if (i==2) continue; System.out.println (i); Instrucţiunea SWITCH Instrucţiunea are forma particulară: switch (expresie) { case exp 1 : secvenţă instrucţiuni 1 ; break; case exp 2 : secvenţă instrucţiuni 2 ; break;... case exp n : secvenţă instrucţiuni n ; break; [default: secvenţă instrucţiuni n+1 ];

239 Capitolul 6. Iniţiere în utilizarea limbajului Java 239 unde: expresie are semnificaţia: expresie de tip întreg (sau char); exp i : sunt expresii constante de tip întreg (sau char); instrucţiuni i reprezintă o secvenţă oarecare de instrucţiuni. Principiul de executare este: se evaluează expresia; dacă aceasta produce o valoare egală cu cea produsă de exp i, se execută în ordine instrucţiuni i şi se trece la instrucţiunea următoare, altfel se execută numai secvenţa instrucţiuni n+1. Observaţie! Alternativa default este facultativă. În absenţă, în cazul în care nu există coincidenţă de valori, se trece la instrucţiunea următoare. Exemplul Secvenţa care urmează probează instrucţiunea switch. Se va afişa 1: int i =1; switch(i) { case 1: System.out.println(1);break; case 2: System.out.println(2);break; default: System.out.println("altceva"); Observaţie! Am prezentat o formă simplificată a instrucţiunii switch, mai precis, cea corespunzătoare programării structurate. În absenţa instrucţiunii break, în cazul în care există egalitate între expresie şi exp i se execută secvenţa corespunzătoare şi, pe rând, toate secvenţele care urmează, ş.a.m.d. Exemplul Secvenţa care urmează afişează: 2, altceva: int i =2; switch(i) { case 1: System.out.println(1); case 2: System.out.println(2); default: System.out.println("altceva"); Observaţie! În forma generală, instrucţiunea switch are rolul de a stabili mai multe puncte de intrare într-o secvenţă de instrucţiuni, în funcţie de valoarea pe care o reţine expresie Instrucţiunea apel metodă (funcţie) Aceasta va fi tratată la momentul potrivit. Pentru moment, putem da ca exemplu doar System.out.print() sau System.out.println().

240 240 Manual de Informatică pentru clasa a XII-a Instrucţiunea de declarare a variabilelor Până în prezent, am întâlnit-o de multe ori. Ea poate fi plasată oriunde în corpul unei metode (funcţii). Exemplul Instrucţiunea int x=2,y Masive În Java există un mecanism excepţional de lucru cu masive (vectori, matrice, etc). Din motive didactice, pentru început, vom prezenta declararea masivelor în doi paşi: Pasul 1. Se declară o variabilă care poate reţine o referinţă (adresă) către vector, matrice, etc. Exemplul Analizaţi declaraţiile de mai jos: a) int[] V; am declarat o variabilă referinţă către un vector cu componente de tip int. O declaraţie echivalentă poate fi făcută prin: int V[];. b) int[][] Mat; am declarat o variabilă referinţă către o matrice cu componente de tip int. c) float[] V, V1; am declarat două variabile referinţă către vectori, numite V, respectiv V1. Ambii vectori au componente de tip float. d) float Mat[][],Mat1[][]; am declarat două variabile de tip referinţă către matrice. Cele două variabile se numesc Mat şi Mat1. Pasul 2. Alocăm spaţiu în memorie pentru masiv (vector, matrice). Adresa vectorului va fi reţinută în variabila V. Exemplul Urmăriţi exemplele de mai jos: a) V=new int[4];. Am alocat spaţiu în memorie pentru un vector cu 4 componente de tip int (practic am creat vectorul). Referinţa către el va fi reţinută în V şi pornind de la această variabilă putem accesa V. b) Mat=new int [4][3];. Am alocat spaţiu în memorie pentru o matrice cu 4 linii şi 3 coloane cu componente de tip int. Prima componentă a unui vector are indicele 0, a doua indicele 1 ş.a.m.d. Tot aşa, liniile unei matrice se numerotează începând cu 0, coloanele unei matrice se numerotează începând cu 0.

241 Capitolul 6. Iniţiere în utilizarea limbajului Java 241 O componentă a unui vector se adresează pornind de la referinţă şi scriind indicele între paranteze drepte (exemplu V[3]). O componentă a unei matrice se adresează pornind de la referinţă si scriind între paranteze pătrate fiecare din cei doi indici (exemplu Mat[2][1]). Exemplul În secvenţa următoare se creează un vector, se iniţializează fiecare componentă a lui şi se afişează: int[] V; // sau int V[]; V=new int[4]; int i; for (i=0;i<4;i++) V[i]=i+1; for (i=0;i<4;i++) System.out.println(V[i]); Schema alăturată reflectă modul în care arată vectorul, după ce i-am iniţializat componentele. V referinţa Figura 6.6. Vectorul după ce a fost iniţializat Vectorii se pot declara şi aşa cum se vede mai jos, gata iniţializaţi. În urma unei astfel de declaraţii se poate lucra direct cu ei, exact ca anterior. int[] V={1,2,3,4; int i; for (i=0;i<4;i++) V[i]=i+1; for (i=0;i<4;i++) System.out.println(V[i]); Exemplul În secvenţa următoare se creează o matrice, se iniţializează fiecare componentă a ei şi se afişează: int[][] Mat; int i,j; Mat=new int [4][3]; for (i=0;i<4;i++) for (j=0;j<3;j++) Mat[i][j]=i+j; for (i=0;i<4;i++) { for (j=0;j<3;j++) System.out.print(Mat[i][j]+" "); System.out.println(); Ca şi vectorii, matricele se pot declara şi aşa cum se vede mai jos, gata iniţializate. În urma unei astfel de declaraţii se poate lucra direct cu ele, exact ca anterior. int[][] Mat={{1,2,3,4,{3,4,5,6; int i,j; for (i=0;i<2;i++) { for (j=0;j<3;j++) System.out.print(Mat[i][j]+" "); System.out.println();

242 242 Manual de Informatică pentru clasa a XII-a Declararea unui masiv se poate face şi într-un singur pas, ca mai jos: float[] V=new float[4]; De vreme ce numele masivului (V, Mat, în exemplele date) reţine o referinţă către masiv, înseamnă că unei astfel de variabile i se poate atribui o referinţă către alt masiv, ceea ce este echivalent cu faptul că atribuirea funcţionează în cazul masivelor ca în cazul variabilelor de unul din tipurile de date primitive. Totuşi, există o diferenţă esenţială: se atribuie doar referinţa, nu conţinutul masivului, care rămâne nemodificat. Masivul care nu mai este referit va fi şters, automat (fără ca, în acest scop, să fie scrisă o secvenţă specială). Exemplul Avem doi vectori, V şi V1. Cei doi vectori sunt creaţi şi iniţializaţi. După aceasta, se interschimbă referinţele către cei doi vectori şi, în vederea probării operaţiilor efectuate, se afişează. float[] V=new float[4], V1=new float[3], Man; int i; for (i=0;i<4;i++) V[i]=i+1; for (i=0;i<3;i++) V1[i]=9; Man=V1; V1=V; V=Man; for (i=0;i<4;i++) System.out.println(V1[i]); for (i=0;i<3;i++) System.out.println(V[i]); Grafic, interschimbarea de mai sus se poate prezenta astfel: după crearea şi iniţializarea celor doi vectori: V V Figura 6.7. Pasul întâi după efectuarea instrucţiunii Man=V1;, vom avea: V V Man Figura 6.8. Pasul al doilea

243 Capitolul 6. Iniţiere în utilizarea limbajului Java 243 după efectuarea instrucţiunii V1=V;, vom avea: V V Man Figura 6.9. Pasul al treilea după efectuarea instrucţiunii V=Man;, vom avea: V V Figura Ultimul pas O altă utilizare de excepţie a acestui mecanism este aceea prin care se declară un masiv exact cu numărul de componente dorit şi nu un număr de componente mare, care se presupune că indiferent de intrare, nu poate fi depăşit (ca în Pascal, C/C++). Aceasta conduce la economie de memorie. int n; // se citeste n; V=new int [n]; Deşi din punct de vedere teoretic nu se poate explica în acest moment, numărul de componente ale unui vector (masiv unidimensional) este returnat de data membru (vom învăţa despre date membru) length, apelată ca mai jos. În urma executării acestei secvenţe se afişează 10. int[] vector=new int[10]; System.out.println(vector.length); O matrice poate fi privită (şi, de fapt asta şi este) ca un vector de vectori. Fie declaraţia int Mat[][]=new int [4][5]. Putem spune că avem un vector cu 4 componente. Fiecare componentă este la rândul ei, un vector cu 5 componente. Atunci, length, aplicată matricei, reţine 4, şi aplicată, de exemplu, componentei de indice 2 returnează 5. La executarea secvenţei de mai jos se afişează 4 şi 5. int Mat[][]=new int [4][5]; System.out.println(Mat.length); System.out.println(Mat[2].length);

244 244 Manual de Informatică pentru clasa a XII-a În cazul matricelor (sau, în general, masivelor de dimensiune mai mare sau egală cu 2) există posibilitatea ca liniile să aibă lungime diferită. Cu alte cuvinte, o componentă a vectorului de vectori (matricea) poate avea un număr de componente, altă componentă, alt număr de componente. În secvenţa următoare am declarat o matrice cu 2 linii. Prima linie are 3 componente, a doua linie are două componente. În final, se afişează conţinutul unui element al matricei. int Mat[][]=new int [2][]; Mat[0]=new int[3]; Mat[1]=new int[2]; Mat[0][0]=1; Mat[0][1]=2; Mat[1][0]=3; System.out.println(Mat[0][1]); Vă daţi seama câtă economie de memorie se face? Aplicaţie! Secvenţa următoare creează, iniţializează şi afişează o matrice triunghiulară. Alăturat puteţi observa rezultatul rulării. Este ceva faptul că pentru a reţine o matrice triunghiulară se reţine exact atât cât este necesar! int[] vector=new int[10]; int Mat[][]=new int [4][]; int i, j, k=1; for (i=0;i<4;i++) { Mat[i]=new int[i+1]; // declararea este instructiune for (j=0;j<=i;j++) Mat[i][j]=k++; for (i=0;i<4;i++) Figura Rezultatul rulării { for (j=0;j<mat[i].length;j++) System.out.print(Mat[i][j]); System.out.println(); Citirea datelor de la tastatură Limbajul Java conţine o mulţime de facilităţi, dar pentru începători există o reală dificultate în a citi date de la tastatură. Ca să le înţelegem cu adevărat, sunt necesare cunoştinţe avansate de Java. Şi nu putem aştepta până atunci, pentru că este relativ dificil să prezinţi materia, mai ales la nivel de liceu, fără a putea citi ceva de la tastatură. Pentru a rezolva această problemă, s-a recurs, ca de altfel şi în alte cursuri de Java, la prezentarea unei clase prin care să putem realiza citirea de la tastaură a şirurilor de caractere. Vom prezenta această clasă referindu-ne doar la utilizarea ei. Ulterior, vom prezenta modul în care a fost realizată. Clasa pe care o vom folosi se numeşte cin şi este următoarea:

245 Capitolul 6. Iniţiere în utilizarea limbajului Java 245 import java.io.*; public class cin { static String linie () { String sir = ""; char ch; try { while ((ch = (char)system.in.read())!= 13) sir = sir+ch; catch (IOException e) { try { System.in.read(); catch (IOException e) { return sir; Textul de mai sus îl vom introduce în fişierul cin.java. Apoi, îl compilăm cu javac cin.java. În urma compilării rezultă fişierul cin.class. Acest fişier va fi utilizat de orice program care foloseşte o metodă din clasa cin. Dacă fişierele cin.java şi cin.class se vor găsi în folder-ul bin, atunci, fără nici o problemă, utilizăm aceste metode ca şi cum ar fi ale limbajului Java (practic, orice program care apelează clasele respective le găseste în bin). Metoda linie() are rolul de a citi un şir de caractere introdus de la tastatură. Rezultatul este de tip referinţă la String, adică referinţă către şirul de caractere citit. Şirul este citit cacter cu cacter. Atunci când utilizatorul apasă enter, se generează, de fapt, 2 caractere. Primul dintre ele este depistat de metodă. Pentru a elimina caracterul rezidual, se mai citeste un caracter. Exemplul Programul următor citeşte şi afişează o linie introdusă de la tastatură: class test { public static void main(string[] args) { String l=cin.linie(); System.out.println(l); Dacă dorim să citim numai un caracter, vom utiliza metoda charat(nr), care returnează caracterul aflat pe poziţia nr a şirului de caractere. Atenţie: primul caracter al şirului are indicele 0. Exemplul în programul următor se citeşte şi se afişează un caracter. Observaţi modul de utilizare al metodei charat(). class test { public static void main(string[] args) { String l=cin.linie(); char c=l.charat(0); System.out.println(c);

246 246 Manual de Informatică pentru clasa a XII-a Dacă dorim să citim numere, este sarcina noastră să convertim rezultatul către tipul dorit. Vom utiliza metode ale unor clase, numite înfăşurătoare, clase care vor fi prezentate la momentul potrivit. Metoda Integer.parseInt(sir) returnează şirul convertit către int. Exemplul Se citesc două numere naturale a şi b şi se afişează suma lor: class test { public static void main(string[] args) { System.out.print("a="); int a=integer.parseint(cin.linie()); System.out.print("b="); int b=integer.parseint(cin.linie()); System.out.println(a+b); Metoda Long.parseLong(sir) returnează şirul convertit către long. Metoda Float.parseFloat(sir) returnează şirul convertit către float. Metoda Double.parseDouble(sir) returnează şirul convertit către float. Observaţie! Nu trebuie să vă îngrijoraţi că nu aţi înţeles toate noţiunile prezentate. Pentru moment, luaţi-le ca atare. Toate vor fi studiate în amănunt. Să ne mulţumim cu faptul că putem citi şi afişa un şir de caractere. Întrucât cunoaştem deja operatorii şi instrucţiunile şi putem citi date cu ajutorul clasei cin, de acum putem să scriem mici programe. Toate instrucţiunile se vor găsi în main(). 1. Se citesc două numere reale. Se cere să se afişeze numărul cel mai mare dintre ele (calculul maximului). class test { public static void main(string[] args) { System.out.print("a="); double a=double.parsedouble(cin.linie()); System.out.print("b="); double b=double.parsedouble(cin.linie()); if (a>b) System.out.println(a); else System.out.println(b);

247 Capitolul 6. Iniţiere în utilizarea limbajului Java Se citeşte n, număr natural mai mare decât 0. Să se calculeze n. class prima { public static void main(string[] args) { System.out.print("n="); int i,s=0,n=integer.parseint(cin.token()); for (i=1;i<=n;i++) s+=i; System.out.println("Suma este " +s); Observaţi modul în care se afişează, mai întâi, şirul n=, si apoi se aşteaptă introducerea lui n. Prin expresia: "Suma este " +s se converteşte mai întâi tipul int către String (obiect care reţine un şir de caractere), apoi cele două se concatenează. În final, se afişează şirul astfel obţinut. Aceasta înseamnă că pentru a converti o valoare numerică, a, către şir, se poate face şirul sumă între şirul vid şi a: +a. De reţinut! 3. Se citeşte n şi un vector cu n componente numere reale. Să se afişeze conţinutul componentelor vectorului sortate crescător. Se va utiliza metoda bulelor. class test { public static void main(string[] args) { System.out.print("n="); int n=integer.parseint(cin.linie()),i; double man; boolean gasit; double V[]=new double[n]; for (i=0;i<n;i++) { System.out.print("V["+i+"]="); V[i]=Double.parseDouble(cin.linie()); do { gasit=false; for (i=0;i<n-1;i++) if (V[i]>V[i+1]) { man=v[i]; V[i]=V[i+1]; V[i+1]=man; gasit=true; while (gasit==true); for (i=0;i<n;i++) System.out.println(V[i]); 4. Mai jos puteţi observa o secvenţă simplă prin care se pot inversa liniile i şi j ale unei matrice cu n linii şi m coloane (i,j<n). int Man[]; Man=A[i]; A[i]=A[j]; A[j]=Man;

248 248 Manual de Informatică pentru clasa a XII-a Date membru În Java, există posibiltatea de a declara variabile vizibile la nivel de clasă, aşa cum se vede în programul de mai jos, unde se citesc conţinuturile numerice a două astfel de variabile şi se afişează suma lor. Ele sunt, de fapt, variabile globale la nivel de clasă. Ca să respectăm terminologia consacrată, le vom numi date membru (ale clasei care conţine main()). Pentru moment, pentru a putea lucra ca acest mod este obligatoriu ca datele membru să fie precedate de modificatorul static. Justificările celor prezentate acum vor fi date ulterior. class test { static int a,b; public static void main(string[] args) { a=integer.parseint(cin.linie()); b=integer.parseint(cin.linie()); System.out.println(a+b); Orice dată membru (variabilă) a clasei este iniţializată automat, la pornirea programului. Astfel, datele numerice sunt iniţializate cu 0, datele de tip boolean cu false, datele de tip caracter cu caracterul de cod 0, datele de tip referinţă cu null (nu conţin nici o adresă) Metode În esenţă, o metodă este alcătuită din: Antet - acesta conţine mai multe informaţii importante necesare compilatorului, numele metodei, lista parametrilor formali, tipul metodei şi, eventual, modificatori. Corpul metodei - acesta cuprinde instrucţiunile metodei. Exemplul În Fig. 6.12, puteţi observa metoda suma() ce are rolul de a calcula suma a două numere naturale. În schema ataşată, puteţi identifica elementele constitutive ale ei: Numele metodei se utilizează pentru a o identifica atunci când metoda este apelată. Lista parametrilor formali parametrii formali sunt valorile pe care metoda le primeşte la apel. În exemplu, lista este formată din doi parametri formali, x şi y, ambii de tipul int. Tipul metodei sau altfel spus, precizează natura rezultatului. În exemplu, metoda returnează o valoare întreagă (de tip int), dar pot fi metode de alt tip, cum ar fi float double, etc. Există şi metode care nu returnează nimic, caz în care tipul metodei este void.

249 Capitolul 6. Iniţiere în utilizarea limbajului Java 249 Modificator Tipul metodei Numele metodei Lista parametrilor formali Corpul metodei static int suma(int x, int y) { return x+y; Figura Exemplu de metodă Corpul metodei este sub forma unei instrucţiuni compuse. În exemplu, acesta conţine o singură instrucţiune, return, prin care se calculează şi se returnează suma parametrilor formali. Modificator static. Mai jos, puteţi observa modul în care se apelează metoda suma(): public class test { static int suma(int x, int y) {return x+y; public static void main(string[] args) { System.out.println(suma(2,3)); int x=2, y=5; System.out.println(suma(x,y)); System.out.println(suma(3,y)); Metodele care sunt de orice alt tip în afara tipului void, trebuie să returneze o valoare din tipul respectiv. Returnarea valorii se face prin utilizarea instrucţiunii return. În exemplu, metoda suma() prin return x+y; returnează suma celor doi parametrii primiţi. Mai jos puteţi observa modul în care se apelează o metodă de tip void: public class test { static void met() { System.out.println("Eu sunt o metoda de tip void"); public static void main(string[] args) { met(); Parametrii care figurază în apelul unei metode se numesc parametri efectivi. De exemplu, în apelul suma(2,3), parametrii efectivi sunt valorile 2 şi 3. În apelul suma(x,y) parametrii efectivi sunt conţinuturile variabilelor x şi y. Metodele se pot apela una pe alta, indiferent de poziţia pe care o ocupă definiţia lor în cadrul clasei. Exemplul În exemplul de mai jos, metoda met1() apelează metoda met(), deşi aceasta din urmă este definită, în cadrul clasei, după ea. class test { static void met1() { System.out.println("Met1"); met();

250 250 Manual de Informatică pentru clasa a XII-a static void met() {System.out.println("Met"); public static void main(string[] args) {met1(); În Java, parametrii se transmit numai prin valoare. Aceasta înseamnă că parametrul efectiv, chiar dacă este variabilă, râmâne nemodificat. Exemplul Priviţi exemplul următor: public class test { static void exemplu(double x) { x=3.7; public static void main(string[] args) { double x=5; exemplu(x); System.out.println(x); În main() avem o variabilă x, de tip double, iniţializată cu 5. Apelăm metoda de tip void exemplu(). În metodă, lui x i se atribuie altă valoare (3.7). După executarea metodei, se revine în main() şi se afişează x. Valoarea afişată este cea iniţială, 5. Conţinutul variabilei x din main() a rămas nemodificat. Am arătat faptul că numele unui masiv este o referinţă către masiv ce se găseşte în memorie. În acest caz, transmiterea unei referinţe către un masiv ca parametru al unei metode are ca efect posibilitatea modificării conţinuturilor componentelor masivului. Observaţie! Întrucât masivele conţin şi data membru length, dacă o metodă primeşte ca parametru o referinţă către masiv, atunci nu mai este necesar ca, în alte limbaje de programare, să transmitem şi numărul de componente ale masivului. Exemplul Metoda exemplu() calculează suma numerelor reţinute de un vector şi face ca fiecare componentă a vectorului să reţină valoarea 1. În programul principal se iniţializează vectorul, apoi se probează efectul metodei. public class test { static int exemplu(int[] t ) { int s=0,i; for (i=0;i<t.length;i++) s+=t[i]; for (i=0;i<t.length;i++) t[i]=1; return s; public static void main(string[] args) { int[] v=new int [5]; int i; for (i=0;i<5;i++) v[i]=integer.parseint(cin.linie()); System.out.println(exemplu(v)); for (i=0;i<v.length;i++) System.out.print(v[i]+" ");

251 Capitolul 6. Iniţiere în utilizarea limbajului Java Exemple de utilizare a metodelor 1. Se citesc două numere întregi m şi n. Se cere să se tipărească cel mai mare divizor comun şi cel mai mic multiplu comun al lor. Rezolvare. Presupunem cunoscut algoritmul care determină cel mai mare divizor comun pentru două numere. Cel mai mic multiplu comun al două numere se poate determina împărţind produsul lor la cel mai mare divizor comun al lor. Prin urmare, scriem o metodă cmmdc cu doi parametri formali m şi n, care întoarce o valoare întreagă - cel mai mare divizor comun al lor. public class test { static int cmmdc(int m, int n) { while (m!=n) if (m>n) m-=n; else n-=m; return m; public static void main(string[] args) { int m=integer.parseint(cin.linie()); int n=integer.parseint(cin.linie()); int cm=cmmdc(m,n); System.out.println(cm); 2. Superpalindrom. Un număr natural este palindrom dacă citit de la stânga la dreapta şi de la dreapta la stânga rămâne nemodificat. De exemplu, numărul este palindrom. Un număr natural este superpalindrom dacă este palindrom atât el cât şi pătratul său. Scrieţi un program care listează toate numerele cu această proprietate aflate între doi intregi m şi n. Rezolvare. Modul în care testăm dacă un număr este palindrom este acum lămurit. Mai mult, avem şi metoda. Nu trebuie decât să o folosim: public class test { static boolean palin(int i) { int isalv=i,iinv=0; while (i!=0) { iinv=iinv*10+i%10; i=i/10; return isalv==iinv; public static void main(string[] args) { int m=integer.parseint(cin.linie()); int n=integer.parseint(cin.linie()); for(int i=m;i<n;i++) if (palin(i)) if (palin(i*i)) System.out.println(i+" "+i*i); În Java metodele pot fi recursive, deci o metodă se poate autoapela.

252 252 Manual de Informatică pentru clasa a XII-a 3. Să se calculeze recursiv n!. Pentru a scrie o metodă recursivă care efectuează acelaşi calcul, vom porni de la o definiţie recursivă a lui n!. Aceasta este: public class test { static int fact(int n) { if (n==0) return 1; else return n*fact(n-1); public static void main(string[] args) { System.out.println(fact(3)); Supraîncărcarea metodelor În Java, metodele pot fi supraîncărcate. Aceasta înseamnă că putem avea două sau mai multe metode cu acelaşi nume, dar care diferă prin tipul şi/sau numărul parametrilor. Exemplul Priviţi programul de mai jos, care conţine două metode cu acelaşi nume, cu acelaşi număr de parametri (1), dar de tip diferit (int, respectiv float): public class test { static void eu_sunt(int n) { System.out.println("Parametru de tip int "+ n); static void eu_sunt(double n) { System.out.println("Parametru de tip double "+n ); public static void main(string[] args) { eu_sunt(3); eu_sunt(-2.7); Faptul că metodele pot fi supraîncărcate are consecinţe uriaşe în programare. Dacă în cazul programării clasice (neorientate pe obiecte) se poate programa şi în absenţa acestei facilităţi, în cazul programării orientate pe obiecte, facilitatea devine esenţială, aşa cum va rezulta din capitolele următoare. Un exemplu este chiar metoda println(), atât de utilizată până în acest moment. Ea afişează orice i-am transmite ca parametru: o valoare de tip int, o valoare de tip float, un caracter sau un şir de caractere. De fapt, există mai multe metode println() care diferă doar prin tipul parametrului. Sugestie! Pentru a vă obişnui cu programarea în Java, puteţi rezolva orice problemă din manualele pentru clasele a X-a şi a XI-a care nu necesită utilizarea fişierelor.

253 CAPITOLUL Programare orientată pe obiecte În acest capitol vom studia în detaliu programarea orientată pe obiecte, utilizând limbajul de programare Java. Mai jos sunt prezentate principalele noţiuni pe care le veţi învăţa: Care sunt principiile programării orientate pe obiecte? Ce este un constructor? Date membru statice şi metode statice Cuvântul cheie This Referinţe către obiecte Masive de obiecte Aplicaţii. Lucrul cu numere raţionale Studiul unor clase din limbajul Java Extinderea claselor (moştenirea) Ce este polimorfismul? Clase abstracte Interfeţe Specificatori de acces (modificatori de acces) Excepţii (tratarea erorilor) Cuvinte cheie: încapsulare, moştenire, polimorfism, constructor, static, nestatic, legare, this, referinţă, masiv, math, string, clasă înfăşurătoare, abstract, interfaţă, specificator de acces, excepţie

254 254 Manual de Informatică pentru clasa a XII-a 7.1. Principiile programării orientate pe obiecte Atunci când ne referim la programarea orientată pe obiecte, se mai pot folosi şi denumirile: programare obiectuală, programare orientată spre obiect sau pe scurt, OOP - Object Oriented Programming. În linii mari, se poate spune că OOP reuneşte trei principii fundamentale: încapsulare, moştenire şi polimorfism. 1. Prin încapsulare înţelegem mecanismul prin care datele (variabilele) şi funcţiile (numite în acest caz şi metode) sunt plasate împreună, într-o unică structură, numită clasă. Clasa generalizează noţiunea de tip de dată. Fiind dat un tip de dată, putem avea variabile care sunt de acel tip, adică acele variabile pot reţine numai date care respectă cerinţele tipului. Exemplul 7.1. Dacă trebuie să reţinem un număr real, putem alege tipul double şi să definim o variabilă de acest tip. Fiind dată o clasă, putem obţine obiecte rezultate prin instanţierea acelei clase. Pe lângă datele proprii, un obiect conţine şi metode, adică funcţii care permit lucrul cu datele reţinute de obiectul respectiv, dar şi cu date din afara obiectului. Exemplul 7.2. La matematică v-aţi întâlnit cu numere complexe! Ele sunt de forma: z=x+iy, unde x,y R. Prin urmare, pentru fiecare număr complex ar trebui să reţinem două valori reale, pentru x şi pentru y. Decidem că în acest caz, pentru a le reţine, avem nevoie de două variabile de tip double. Priviţi programul de mai jos care conţine două clase: Complex şi test: class Complex { // date membru double x,y; // metoda void afis() { System.out.println(x+" "+y); public class test { public static void main(string[] args) { // declar un numar complex Complex z1; z1= new Complex (); // Complex z1=new Complex(); // Datelor membru li se atribuie valori z1.x=3; z1.y=-4.7; // Afisez datele membru z1.afis();

255 Capitolul 7. Programare orientată pe obiecte 255 Să analizăm programul: clasa Complex: 1. Clasa conţine două date membru, x şi y, ambele de tip double. 2. Clasa conţine o metodă care are rolul de a afişa într-un mod convenabil datele membru ale clasei. clasa test - metoda main(): 1. Complex z1;- variabila z1 este de tip Complex. Prin urmare, ea poate reţine o referinţă (adresă) către un obiect de tip Complex. 2. z1=new Complex(); - se creează un obiect de tip Complex şi referinţa către el este reţinută de z1. 3. z1.x=3; z1.y=-4.7; - datelor membru x şi y ale obiectului a cărui referinţă este reţinută de z1 li se atribuie respectiv, valorile 3 şi z1.afis(); - se afişează numărul complex reţinut de obiectul referit de z1. Foarte important! A) La baza programării pe obiecte stă noţiunea de clasă. Clasa încorporează atât date membru, cât şi metode. A defini o clasă înseamnă a crea un tip (în sensul extins). Un obiect rezultă ca instanţiere a unei clase. Obiectul va avea ca tip numele clasei respective. Pentru a putea accesa datele membru şi metodele clasei respective se utilizează variabile de tip referinţă către obiectele clasei respective. B) Odată definită clasa, putem crea obiecte de tipul clasei respective. Într-o formă simplificată (mai precis, în absenţa unui constructor), crearea unui obiect de tipul unei clase se face prin construcţia de mai jos, unde v este o variabilă referinţă către obiectele clasei respective. Nume_clasa v=new Nume_Clasa() C) Un constructor al unei clase este o metodă specială a clasei respective care are rolul de a aloca în memorie spaţiul necesar obiectului dar şi de a iniţializa datele membru ale acestuia. Orice clasă are un constructor implicit (adică o metodă pe care nu a scris-o cel care a creat clasa). D) Operatorul new are dublu rol: - apelează constructorul clasei respective; - returnează referinţa (adresa) la care a fost creat obiectul respectiv. Exemplul 7.3. Complex z=new Complex(); - z reţine o referinţă către obiectul creat prin new: Figura 7.1. z x y

256 256 Manual de Informatică pentru clasa a XII-a E) Accesul la variabilele interne ale obiectului se realizează prin numele obiectului, urmat de operatorul. şi numele variabilei. Exemplul 7.4. În exemplu, Z va reţine numărul x+2i, iar aceste valori vor fi afişate: z1.x=1; z1.y=2; System.out.println(z1.x); System.out.println(z2.y); F) O clasă poate conţine una sau mai multe metode. Apelul unei metode de acest tip se face prin numele variabilei care reţine referinţa către obiect, urmat de. şi de numele metodei. Exemplul 7.5. z1.afis(). G) Datele membru ale unei clase sunt iniţializate implicit cu valoarea 0, dacă sunt de un tip numeric, sau cu caracterul de cod 0, dacă sunt de tip char, sau cu null dacă sunt de tip referinţă. 2. Prin moştenire se înţelege acea proprietate a claselor prin care o clasă poate prelua datele şi metodele unei (unor) clase anterior realizate. În Java, acest mecanism mai este cunoscut sub numele de "extinderea claselor". Evident, clasei nou construite i se pot adăuga noi date şi metode! Prin acest procedeu, se preia soft deja implementat şi acesta se dezvoltă. Avantajul uriaş al acestui mecanism este că persoana care preia un anumit soft trebuie să cunoască doar documentaţia de utilizare a acestuia. Extinderea claselor face obiectul unui paragraf separat. 3. Polimorfismul este legat de moştenire. În linii mari, prin polimorfism înţelegem posibilitatea ca atât clasa care este moştenită, cât şi moştenitoarea, să poată utiliza metode cu acelaşi nume, dar diferite. Fie mai multe clase C 0, C 1,..., C n, unde C 1 moşteneşte pe C 0, C 2 pe C 1,..., C n pe C n-1. Toate aceste clase redefinesc o metodă: f. Există posibilitatea ca, în timpul executării programului, să se ruleze o metodă f sau alta, tot f, în funcţie de tipul datelor care intervin. Procedeul este cu mult mai complex şi va face obiectul unui paragraf separat Constructori Aşa cum am arătat, orice clasă are un constructor implicit. Rolul lui este de a aloca spaţiu în memorie pentru obiect. Constructorul este apelat de operatorul new. Acesta din urmă are şi rolul de a returna referinţa către obiect, referinţă care este memorată de o variabilă de tip referinţă către obiect. Exemplul 7.6. Unei clase i se pot crea proprii constructori, aşa cum rezultă din exemplul următor, unde clasei prezentate în paragraful precedent i s-au adăugat doi constructori:

257 Capitolul 7. Programare orientată pe obiecte 257 class Complex { // date membru double x,y; // Constructor 1 Complex (double x1) { x=x1; // Constructor 2 Complex (double x1, double y1) { x=x1; y=y1; // metoda void afis() { System.out.println(x+" "+y); public class test { public static void main(string[] args) { Complex z1 = new Complex (2,3), z2 = new Complex (1); z1.afis(); z2.afis(); Primul constructor are un singur parametru şi se foloseşte pentru declaraţii de numere complexe care au partea imaginară 0. Al doilea constructor se utilizează pentru a declara numere complexe cu parte reală şi parte imaginară. În ambele cazuri nu mai este nevoie ca datele membru să fie iniţializate. De reţinut! A) Un constructor nu are tip. B) Un constructor are întotdeauna numele clasei căreia îi aparţine. C) Dacă unei clase i se ataşează un constructor, altul decât cel implicit, atunci nu se mai poate instanţia un obiect prin utilizarea constructorului implicit. De exemplu, pentru clasa definită în acest paragraf o instrucţiune de genul Complex z=new Complex() dă eroare de sintaxă. D) Unei clase i se pot ataşa mai mulţi constructori, după cum aţi văzut şi în exemplu. Ei trebuie să difere prin numărul parametrilor şi /sau tipul parametrilor, cu alte cuvinte, ca şi metodele, aceştia sunt supraîncărcaţi.

258 258 Manual de Informatică pentru clasa a XII-a 7.3. Date membru statice şi metode statice Atât datele membru cât şi metodele unei clase pot fi statice. Aceasta înseamnă că datele şi metodele declarate statice pot fi apelate, aşa cum suntem deja obişnuiţi, pornind de la un obiect al clasei respective, dar şi pornind de la numele clasei, aşa cum observaţi în exemplul următor. Exemplul 7.7. Clasa Matematica conţine o dată membru iniţializată (Pi). De asemenea, ea mai conţine două metode: Patrat() şi Cub() prin care se calculează x 2 şi x 3. Se calculează şi afişează aria unui cerc în două feluri: apelând data membru şi metoda pornind de la numele clasei (Matematica); apelând data membru şi metoda pornind de la numele unui obiect al clasei Matematica. class Matematica { static double Pi=3.1415; static double Patrat (double x) { return x*x; static double Cub (double x) { return x*x*x; public class Clasa1 { public static void main(string[] args) { int Raza=3; double Aria=Matematica.Pi*Matematica.Patrat(Raza); System.out.println(Aria); //altfel Matematica ob=new Matematica(); Aria=ob.Pi*ob.Patrat(Raza); System.out.println(Aria); Foarte important! A) Datele membru statice şi metodele statice nu sunt memorate de fiecare obiect al clasei respective. Ele sunt memorate o singură dată, în cadrul clasei respective. B) Sunt clase care au date membru şi/sau metode statice şi nestatice. Observaţie! O clasă indispensabilă, este clasa Math, care este prezentată în această carte. Ea conţine o mulţime de metode matematice care se utilizează mult în orice limbaj de programare. Clasa Matematica, din exemplu, este construită pe aceleaşi principii ca şi clasa Math.

259 Capitolul 7. Programare orientată pe obiecte Cuvântul cheie this În interiorul claselor se poate utiliza cuvântul cheie this. Semnificaţia sa este: referinţă către obiectul curent. Iată una dintre aplicaţiile sale: Dacă o metodă (sau un constructor) are o variabilă cu un anumit nume, de exemplu x, şi dacă, clasa are o dată membru cu acelaşi nume, pentru exemplul nostru tot x, atunci pentru a nu se crea confuzie, data membru va fi adresată prin this.x, iar variabila din metodă (sau constructor) prin x. Exemplul 7.8. Pentru clasa Complex cei doi constructori ar putea fi scrişi şi aşa: Complex (double x) { this.x=x; Complex (double x, double y) { this.x=x; this.y=y; 7.5. Referinţe către obiecte Metodele pot avea parametri de tip referinţă la obiecte şi pot returna referinţe către obiecte. Evident, referinţele sunt transmise prin valoare. Dar, pornind de la ele, se poate accesa obiectul ca şi când ar fi transmis prin referinţă. Exemplul 7.9. Adăugăm clasei Complex metoda Complex adun(complex z);. Metoda returnează o referinţă către un obiect de tip Complex care reţine numărul complex rezultat ca sumă între numărul reţinut de obiectul curent şi numărul complex transmis ca parametru: class Complex { double x,y; Complex (double x) { this.x=x; Complex (double x, double y) { this.x=x; this.y=y; void afis() { System.out.println(x+" "+y); Complex adun(complex z) { return new Complex (x+z.x,y+z.y);

260 260 Manual de Informatică pentru clasa a XII-a public class test { public static void main(string[] args) { Complex z1 = new Complex (2,3); Complex z2 =new Complex(3,4); Complex z=z1.adun(z2); z.afis(); Programul afişează suma numerelor complexe reţinute z1 şi z2, adică numărul complex z=5+7i, afişat ca: 5 7. Observaţi faptul că variabila care reţine referinţa către obiectul sumă a fost iniţializată cu ajutorul metodei adun() a obiectului z1. Observaţie! Clasele pot conţine variabile de tip referinţă la propriile obiecte (sau la obiectele altei clase). Exemplul Listă liniară simplu înlănţuită. Pornind de la această observaţie, construim o listă liniară simplu înlănţuită. Priviţi programul următor care creează şi afişează o listă liniară simplu înlănţuită: class Nod { int info; Nod adr_urm; public class Lista { static Nod v=null; // nu este obligatorie iniţializarea static void adaug(int nr) { Nod c=new Nod(); c.info=nr; c.adr_urm=v; v=c; static void afis() { Nod c=v; while (c!=null) { System.out.println(c.info); c=c.adr_urm; public static void main(string[] args) { for (int i=1;i<=9;i++) adaug(i); afis(); Un nod reţine o informaţie oarecare, s-o numim info şi să presupunem că este de tip int şi o referinţă către nodul următor (adr_urm). Evident, referinţa este către obiecte ale aceleiaşi clase. Clasa respectivă am numit-o Nod.

261 Capitolul 7. Programare orientată pe obiecte 261 Clasa care construieşte lista (Lista) conţine o dată membru de tip static de tip referinţă către un obiect al clasei Nod. De asemenea, clasa conţine şi două metode adaug() şi afis(). Metoda adaug() are rolul de a adăuga un nod listei liniare. Ea primeşte ca argument numărul care trebuie reţinut de info. Observaţi cum s-a procedat: s-a creat un nou obiect al clasei Nod, iar referinţa către el este reţinută de c. Data membru a acestui obiect, info, este iniţializată cu valoarea primită ca parametru de metodă, iar adr_urm cu referinţa către nodul anterior, este reţinută de v. În final, v reţine referinţa către ultimul nod creat. În acest fel, lista va reţine nodurile în ordinea inversă creării lor. Am preferat acest algoritm pentru simplitatea lui. Metoda afis() listează valorile reţinute de data membru info a fiecărui nod. O problemă de terminologie. Am văzut că metodele pot întoarce referinţe către obiecte. De asemenea, parametrii metodelor pot fi de tip referinţă către obiecte. Prin abuz de limbaj, pentru a nu complica exprimarea, vom spune uneori, că metodele întorc obiecte, vom vorbi despre obiectul (obiectele) primit ca parametru de o metodă. Însă, acestea trebuie înţelese ca referinţe către obiecte. Garbage Collector. Pe parcursul rulării unui program se pot aloca multe obiecte, iar altele devin inutile, adică nu mai există referinţă către ele. Dacă numărul obiectelor alocate este foarte mare, este posibil ca programul să nu mai dispună de suficientă memorie şi, prin urmare, executarea sa să nu mai poată continua. Pentru a rezolva această problemă, programele java conţin o secvenţă (fir de executare), numită Garbage Collector, care intervine automat (fără ca programul nostru să conţină instrucţiuni scrise special în acest scop) şi eliberează memoria ocupată de obiectele nereferite. Aceasta poate duce uneori, la o încetinire a executării programelor. Momentul în care intervine Garbage Collector nu este stabilit de programator. Cu alte cuvinte, în Java nu vom folosi destructori, existenţi în alte limbaje de programare, cum ar fi C Masive de obiecte Întrebarea este: se pot crea masive care reţin obiecte? De exemplu, putem să creăm un vector care reţine obiecte de tipul Complex? Răspunsul este afirmativ! Elementele unui masiv pot reţine referinţe către obiecte. Exemplul În programul următor se creează şi se afişează un vector cu componente de tip Complex (vezi figura alăturată): Figura 7.2. Rezultat

262 262 Manual de Informatică pentru clasa a XII-a class Complex { double x,y; Complex (double x) { this.x=x; Complex (double x, double y) { this.x=x; this.y=y; void afis() { System.out.println(x+" "+y); Complex adun(complex z) { return new Complex (x+z.x,y+z.y); public class test { public static void main(string[] args) { Complex[] V=new Complex[3]; for (int i=0;i<3;i++) V[i]=new Complex(i+1,i+2); for (int i=0;i<3;i++) V[i].afis(); Pentru a înţelege modul în care a fost construit vectorul de obiecte rezultate ca instanţe ale clasei Complex, analizaţi figura următoare: V V[0] V[1] V[2] 1 2 afis() x y 2 3 afis() x y 3 4 afis() x y Figura 7.3. Construcţia vectorului de obiecte Analizaţi şi exemplele care sunt prezentate în continuare! Exemplul În secvenţa următoare, V1 reţine o referinţă către un vector cu 10 componente care pot reţine referinţe către obiecte ale clasei Complex. Se instanţiază un obiect al clasei Complex şi referinţa sa este atribuită lui V1[2]. Ultimele trei instrucţiuni au rolul de a proba cele prezentate: Complex[] V1 =new Complex[10]; V1[2]=new Complex(10,11); V1[2].afis(); Exemplul În secvenţa următoare, V1 reţine o referinţă către o matrice cu 8 linii şi 5 coloane. Fiecare componentă a matricei poate reţine o referinţă către un obiect al clasei Complex. Se instanţiază un obiect al clasei Complex şi referinţa sa este atribuită lui V1[2][3].

263 Capitolul 7. Programare orientată pe obiecte 263 Complex[][] V1 =new Complex[8][5]; V1[2][3]=new Complex(10,11); V1[2][3].afis(); Exemplul V1 reţine o referinţă către o matrice cu 5 linii şi un număr neprecizat de coloane. Un element al matricei va reţine o referinţă către un obiect al clasei Complex. Linia de indice 3, va avea 6 elemente. Elementul aflat în linia de indice 3 şi coloana de indice 4 va reţine o referinţă către un obiect al clasei Complex. Apoi, se probează... Complex[][] V1=new Complex[5][]; V1[3]=new Complex[6]; V1[3][4]=new Complex(100,200); V1[3][4].afis(); 7.7. Aplicaţii ale noţiunilor prezentate. Lucrul cu numere raţionale Este momentul să învăţăm să creăm clase şi apoi să le utilizăm. Înainte de a prezenta aplicaţiile precizăm că, dacă lucrăm în folder-ul bin, aşa cum am lucrat până acum, putem compila o clasă oarecare fără ca ea să conţină metoda main(). Fişierul obţinut (are extensia.class) se va găsi în bin (dacă cel cu extensia.java este tot acolo). Orice altă clasă care conţine main() din bin, poate folosi clasa compilată, fără a o mai declara într-un fel. De altfel, această problemă va fi tratată pe larg în acest capitol. Aplicaţia 7.1. Să se creeze o clasă cu ajutorul căreia să se poată lucra uşor cu numere raţionale. Un număr raţional q este de forma m/n cu m şi n numere întregi şi n diferit de 0. Clasa va avea două date membru, m şi n, ambele tip int. Constructorul clasei este Rational(int m,int n). Obiectul este creat numai dacă n 0. Datorită faptului că un număr raţional poate fi reţinut în mai multe feluri (de exemplu, 2/3=4/6=8/12) se va reţine numărul simplificat (pentru exemplul dat, m=2 şi n=3, chiar dacă introducem 8 şi 12). Pentru a putea realiza simplificarea fracţiei, m şi n se împart la cel mai mare divizor comun al lor. Clasa va dispune de o metodă static int cmmdc(int m, int n), apelată de constructor, prin care se calculează cel mai mare divizor comun al valorilor reţinute de datele membru m şi n. Metoda Rational add(rational r) creează un obiect al clasei Rational care este rezultatul adunării dintre obiectul curent şi obiectul a cărui referinţă a fost primită ca parametru şi returnează referinţa către el. Faptul că a fost apelat constructorul cu datele membru ale obiectului sumă are ca efect faptul că obiectul care reţine suma este deja simplificat (m şi n au fost împărţite la cmmdc al lor).

264 264 Manual de Informatică pentru clasa a XII-a Metoda Rational sub(rational r) creează un obiect al clasei Rational care este rezultatul scăderii dintre obiectul curent şi obiectul a cărui referinţă a fost primită ca parametru şi returnează referinţa către el. Metoda Rational mul(rational r) creează un obiect al clasei Rational care este rezultatul înmulţirii dintre obiectul curent şi obiectul a cărui referinţă a fost primită ca parametru şi returnează referinţa către el. Metoda Rational div(rational r) creează un obiect al clasei Rational care este rezultatul împărţirii dintre obiectul curent şi obiectul a cărui referinţă a fost primită ca parametru şi returnează referinţa către el. Metoda boolean maimare (Ratioanal r) compară obiectul curent cu obiectul a cărui referinţă a fost primită ca parametru şi returnează true dacă obiectul curent este strict mai mare decât cel a cărui referinţă a fost transmisă ca parametru şi false, în caz contrar. Metoda boolean maimic (Ratioanal r) compară obiectul curent cu obiectul a cărui referinţă a fost primită ca parametru şi returnează true dacă obiectul curent este strict mai mic decât cel a cărui referinţă a fost transmisă ca parametru şi false, în caz contrar. Metoda boolean egal (Ratioanal r) compară obiectul curent cu obiectul a cărui referinţă a fost primită ca parametru şi returnează true dacă obiectul curent este egal cu cel a cărui referinţă a fost transmisă ca parametru şi false în caz contrar. Mai jos puteţi observa modul în care arată clasa Rational: class Rational { int m,n; static int cmmdc(int m, int n) { if (n!=0) return cmmdc(n, m%n); else return m; Rational (int m, int n) { if (n!=0) { int d=cmmdc(m,n); this.m=m/d; this.n=n/d; else System.out.println("Numitorul este nul"); Rational add(rational r) { return new Rational (m*r.n+r.m*n, n*r.n); Rational sub(rational r) { return new Rational (m*r.n-r.m*n, n*r.n); Rational mul(rational r) { return new Rational (m*r.m,n*r.n); Rational div(rational r) { if (r.m!=0) return new Rational (m*r.n,n*r.m); else return new Rational (0,1);

265 Capitolul 7. Programare orientată pe obiecte 265 boolean maimare(rational r) { return (double) m/n > (double)r.m/r.n; boolean maimic(rational r) { return (double) m/n < (double)r.m/r.n; boolean egal(rational r) { return (double) m/n == (double)r.m/r.n; În continuare, ne propunem să rezolvăm câteva aplicaţii în care intervin numere raţionale. Aplicaţia 7.2. Se citesc două numere raţionale q1 şi q2 ( 0). Se cere să se afişeze q1+q2, q1-q2, q1*q2, q1/q2. Rezultatele vor fi tot două numere raţionale. Rezolvare. Variabila q3 este de tip referinţă către un obiect al clasei Rational. După fiecare operaţie, ea va reţine referinţa către obiectul rezultat în urma operaţiei. class I { public static void main(string[] args) { int m=integer.parseint(cin.token()); int n=integer.parseint(cin.token()); Rational q1=new Rational (m,n); m=integer.parseint(cin.token()); n=integer.parseint(cin.token()); Rational q2=new Rational (m,n); Rational q3=q1.add(q2); System.out.println("Suma="+q3.m+"/"+q3.n ); q3=q1.sub(q2); System.out.println("Diferenta="+q3.m+"/"+q3.n ); q3=q1.mul(q2); System.out.println("Produsul="+q3.m+"/"+q3.n ); q3=q1.div(q2); System.out.println("Catul="+q3.m+"/"+q3.n ); Aplicaţia 7.3. Se citesc k numere raţionale. Se cere să se afişeze suma lor sub formă de număr raţional. Rezolvare. Obiectul s va reţine iniţial o referinţă către un număr raţional nul (m=0, n=1). Se citesc pe rând cele k numere raţionale. Pentru fiecare număr raţional citit, se construieşte obiectul suma între s şi obiectul care reţine numărul raţional, iar referinţa către el este atribuită lui s. În final, se afişează datele membru ale obiectului s. class I { public static void main(string[] args) { System.out.print("k="); int k=integer.parseint(cin.token()); Rational s=new Rational(0,1);

266 266 Manual de Informatică pentru clasa a XII-a for (int i=0;i<k;i++) { System.out.print("m="); int m=integer.parseint(cin.token()); System.out.print("n="); int n=integer.parseint(cin.token()); Rational q=new Rational (m,n); s=s.add(q); System.out.println("Suma="+s.m+"/"+s.n ); Aplicaţia 7.4. Se citeşte un vector cu k componente numere raţionale (obiecte ale clasei Rational). Se cere să se afişeze vectorul sortat crescător. Rezolvare. După citirea vectorului vom utiliza metoda de sortare prin interschimbare. Pentru comparare se utilizează metoda maimare(). class I { public static void main(string[] args) { System.out.print("k="); int k=integer.parseint(cin.token()); Rational [] V=new Rational [k]; for (int i=0;i<k;i++) { System.out.print("V["+i+"].m="); int m=integer.parseint(cin.token()); System.out.print("V["+i+"].n="); int n=integer.parseint(cin.token()); V[i]=new Rational(m,n); boolean gasit; Rational man; do { gasit=false; for (int i=0;i<k-1;i++ ) if (V[i].maiMare(V[i+1])) { man=v[i]; V[i]=V[i+1]; V[i+1]=man; gasit=true; while (gasit); for (int i=0;i<k;i++) System.out.println("V["+i+"].m=" + V[i].m + " V["+i+"].n="+V[i].n);

267 Capitolul 7. Programare orientată pe obiecte Studiul unor clase din limbajul Java Până în prezent am învăţat să construim şi să utilizăm clasele. Desigur, a fost doar un început, întrucât studiul claselor va continua şi în capitolul următor. Totuşi, este foarte important să cunoaştem şi să folosim clasele mai importante cu care limbajul Java este înzestrat. Pachetul java.lang conţine mai multe clase care alcătuiesc nucleul aplicaţiilor Java. Din acest motiv, pentru utilizarea lor nu mai este necesară folosirea directivei import Clasa Math Clasa Math face parte din pachetul java.lang şi conţine mai multe metode statice prin care se calculează valorile mai multor funcţii clasice din matematică (logaritmice, exponenţiale, trigonometrice, etc): Metoda Ce calculează? long abs(long x) Modul din x ( x ). double abs(double x)... int abs(int x)... float abs(float x)... int abs(int x)... double acos(double x) arccos(x) double asin(double x) arcsin(x) double ceil(double x) Cel mai mic întreg mai mare sau egal cu x. double floor(double x) Cel mai mare întreg mai mic sau egal cu x ([x], parte întreagă din x). double cos(double x) cos(x) double sin(double x) sin(x) double tan(double x) tg(x) double pow(double a, double b) a b double sqrt(double x) Radical din x. long round(double x) Cel mai apropiat întreg de x. int round (float x)... double random() Număr aleator (întâmplător) din intervalul [0,1). double max(double x, double y) max{x,y float max(float x, float y)... int max(int x, int y)... long max(long x, long y)... double min(double x, double y) min{x,y float min(float x, float y)... long min(long x, long y)...

268 268 Manual de Informatică pentru clasa a XII-a int min(int x, int y)... double exp(double x) e x double log (double x) Logaritm natural din x (ln(x)). double E Constanta e. double PI Constanta π. Tabelul 7.1. Metodele clasei Math Exemplul Analizaţi apelurile de mai jos: Math.ceil(2.35) returnează 3; Math.ceil(-2.35) returnează -2; Math.floor(2.35) returnează 2; Math.floor(-2.35) returnează -3; Math.round(2.35) returnează 2; Math.round(-2.35) returnează -2; Math.round(2.55) returnează 3; Math.round(-2.55) returnează -3; Math.round(-2.5) returnează -2; Math.round(2.5) returnează 3. Exemplul Programul de mai jos afişează o valoare naturală aleatoare din intervalul [1.101]. Math.random() returnează o valoare aleatoare în intervalul [0,1), Math.random()*100 returnează o valoare reală din intervalul [0,100), Math.ceil(Math.random()*100) returnează o valoare întreagă din intervalul [0,100], iar 1+Math.ceil(Math.random()*100) returnează o valoare naturală din intervalul [1,101]. public static void main(string[] args) { System.out.println(1+Math.ceil(Math.random()*100)); Clasa String Constructorii şi lungimea unui şir de caractere Un obiect al clasei String reţine un şir de caractere. Până acum am lucrat cu obiecte ale clasei String, dar acum este momentul ca această clasă să fie prezentată în mod sistematic. Clasa este înzestrată cu doi constructori: String(); - iniţializează un obiect String care reţine şirul vid. Exemplul Secvenţa de mai jos afişează "un sir": String s = new String (); s="un sir"; System.out.println(s);

269 Capitolul 7. Programare orientată pe obiecte 269 String (String s); - iniţializează un obiect String care reţine un şir de caractere dat. Exemplul Secvenţa de mai jos afişează "un sir". String s =new String ("Un sir"); System.out.println(s); int length() - întoarce numărul de caractere din şir. Exemplul Secvenţa de mai jos afişează "6": String s =new String ("Un sir"); System.out.println(s.length()); În Java nu este permisă adresarea unui caracter al şirului prin indice, pentru exemplul precedent, s[k]. În schimb, avem metoda de mai jos, unde primul caracter al şirului are indicele 0, al doilea are indicele 1, ş.a.m.d. char charat(int i) returnează caracterul de pe poziţia i. Exemplul Pentru şirul s, din exemplul precedent, instrucţiunea afişează n : System.out.println(s.charAt(1)); Compararea şirurilor de caractere Şirurile de caractere reţinute de obiectele clasei String pot fi comparate din punct de vedere lexicografic (ordinea din dicţionar). Pentru aceasta, clasa String conţine mai multe metode. int compareto (String s) compară şirul de caractere reţinut de obiectul curent cu şirul de caractere reţinut de s. Metoda returnează: o valoare negativă, dacă şirul reţinut de obiectul curent este situat, în ordine lexicografică, înaintea şirului reţinut de obiectul s; 0, dacă şirurile reţinute de cele două obiecte coincid; o valoare pozitivă, dacă şirul reţinut de obiectul curent este situat, în ordine lexicografică, după şirul reţinut de obiectul s. Exemplul Secvenţa afişează -2, 0, 2: String s =new String ("abc"); String s1=new String("cd"); System.out.println(s.compareTo(s1)+ " " +s.compareto(s)+" "+s1.compareto(s)); int comparetoignorecase(string s) la fel precum compareto(), numai că nu se face diferenţa între literele mari şi cele mici.

270 270 Manual de Informatică pentru clasa a XII-a Exemplul Secvenţa de mai jos afişează 0: String s =new String ("AB"); String s1=new String("ab"); System.out.println(s.compareToIgnoreCase("ab")); boolean equals(string s) returnează true dacă şirurile de caractere reţinute de obiectul curent şi cel transmis ca parametru sunt identice. boolean equalsignorecase(string s) la fel ca mai sus numai că nu se face distincţie între literele mari şi cele mici Subşiruri Vom înţelege prin subşir al un şir de caractere, mai multe caractere consecutive ale acestuia. De exemplu, text are ca subşir ex. boolean startswith(string s) returnează true dacă şirul reţinut de s precede şirul reţinut de obiectul curent. boolean endswith(string s) returnează true dacă şirul reţinut de s se află la sfârşitul şirului reţinut de obiectul curent. Exemplul Cu ajutorul metodelor startswidth() şi endswith(), secvenţa de mai jos afişează de două ori true: String s =new String ("123"); String s1=new String("12"); String s3=new String("23"); System.out.println(s.startsWith(s1)); System.out.println(s.endsWith(s3)); boolean regionmatches(int i1,string s,int i2,int l) compară două subşiruri de lungime l. Primul subşir este al obiectului curent şi începe de pe poziţia i1, al doilea subşir este al şirului s şi începe pe poziţia i2. În caz de egalitate, metoda returnează true, contrar returnează false. Exemplul Secvenţa de mai jos afişează şirul 567 coincid : if (s.regionmatches(4, s1, 2, 3)) System.out.println("567 coincid"); String substring (int index) metoda returnează subşirul şirului curent care este între poziţia index şi sfârşitul şirului. Exemplul Secvenţa de mai jos afişează : String s =new String (" "); System.out.println(s.substring(3));

271 Capitolul 7. Programare orientată pe obiecte 271 String substring (int index, int sf) metoda returnează subşirul şirului curent care este între poziţia index şi sf-1. Exemplul Secvenţa de mai jos afişează 45 : String s =new String (" "); System.out.println(s.substring(3,5)); String replace(char c1, char c2) metoda returnează şirul obţinut dacă se înlocuiesc, în şirul reţinut de obiectul curent, toate apariţiile caracterului c1 cu caracterul c2. Exemplul Secvenţa de mai jos afişează tata : String s =new String ("mama"); System.out.println(s.replace('m','t')); String replaceall(string s1,string s2) metoda returnează şirul obţinut dacă se înlocuiesc, în şirul reţinut de obiectul curent, toate apariţiile subşirului s1 cu subşirul s2. Exemplul Secvenţa de mai jos afişează *** doi *** doi trei : String s =new String ("unu doi unu doi trei"); System.out.println(s.replaceAll("unu","***" )); String replacefirst (String s1, String s2) la fel ca mai sus, doar că se înlocuieşte numai prima apariţie a subşirului. Exemplul Secvenţa de mai jos afişează *** doi unu doi trei : String s =new String ("unu doi unu doi trei"); System.out.println(s.replaceFirst("unu","***" )); String trim() întoarce subşirul şirului reţinut de obiectul curent, subşir obţinut prin eliminarea spaţiilor (blank-urilor de la început şi de la sfârşit). int indexof (String s) returnează indicele primei apariţii a subşirului s în şirul reţinut de obiectul curent. În cazul în care s nu este găsit ca subşir al şirului referit de obiectul curent, metoda returnează -1. Exemplul Secvenţa de mai jos afişează 4 : String s1=new String("un exemplu"); String s2=new String("xe"); System.out.println(s1.indexOf(s2)); Concatenarea şirurilor de caractere Aşa cum deja ştim, în Java şirurile de caractere pot fi concatenate cu ajutorul operatorului +.

272 272 Manual de Informatică pentru clasa a XII-a Exemplul Secvenţa următoare afişează Un sir Alt sir : String s =new String ("Un sir" ); String s1 = new String(" Alt sir"); s=s+s1; System.out.println(s); Acelaşi lucru este afişat şi de secvenţa de mai jos: String s =new String ("Un sir "+"Alt sir" ); System.out.println(s); Observaţie! După cum observaţi, concatenarea şirurilor nu este comutativă, deci înseamnă că prezintă importanţă ordinea în care şirurile sunt puse în expresie. Metoda String concat(string s) returnează şirul obţinut prin concatenarea şirului reţinut de obiectul curent cu s. Exemplul Secvenţa următoare afişează Un sir Alt sir : String s =new String ("Un sir "); String s1 =new String ("Alt sir"); System.out.println(s.concat(s1)); Parametrii metodei main() Acum suntem în măsură să analizăm parametrii metodei main(): public static void main(string[] args). Antetul conţine un vector cu elemente de tip String. În exemplu, numele vectorului este args. 1. Câte elemente are vectorul? Acest număr se poate afla uşor, ca la orice vector: args.length. 2. Unde se introduc şirurile de caractere primite ca parametri de către main()? Aceste şiruri se introduc pe linia de comandă a programului Java şi sunt separate prin spaţii. Exerciţiu! Programul de mai jos calculează suma valorilor introduse ca parametri. Evident, mai întâi acestea sunt convertite către int. Exemple de utilizare: a) Dacă apelul este java t 3 4 se va afişa 7. b) Dacă apelul este java t se va afişa 10. class t { public static void main(string[] args) { int s=0; for (int i=0;i<args.length;i++) s+=integer.parseint(args[i]); System.out.println("suma argumentelor este ="+s);

273 Capitolul 7. Programare orientată pe obiecte 273 În continuare, prezentăm două aplicaţii ale clasei String. Aplicaţia 7.5. Să se citească de la tastatură un şir de caractere, apoi să se afişeze. Rezolvare. Vom utiliza clasa cin (cea pe care am folosit-o şi până acum) pentru toate exerciţiile din acest paragraf. public static void main(string[] args) { String s =new String (); s=cin.linie(); System.out.println(s); Aplicaţia 7.6. Se citesc două şiruri de caractere. Să se listeze indicele fiecărei apariţii a primului şir citit ca subşir al celui de-al doilea şir citit. Iată cum arată executarea programului (figura alăturată). Figura 7.4. Rezultatul Rezolvare. Ideea este următoarea: după ce subşirul a fost identificat, se afişează poziţia de început, apoi se extrage din şir subşirul de început ce conţine inclusiv prima apariţie a subşirului, după care procedeul se repetă până când subşirul căutat nu mai este găsit. O problemă aparte este dată de faptul că trebuie, de fiecare dată, să afişăm poziţia de început a subşirului în şirul iniţial şi nu în şirul rămas. Din acest motiv, utilizăm mai multe variabile: poz - poziţia de început a subşirului în şirul rămas; ind - suma lungimilor şirurilor extrase. De fiecare dată se va afişa ca indice de apariţie a subşirului, ind+poz. public static void main(string[] args) { String subsir =new String (cin.linie()); String sir =new String (cin.linie()); int poz=0, ind=0, lsubs=subsir.length(); while (poz!=-1) { poz=sir.indexof(subsir); if (poz!=-1) { System.out.println(ind+poz); ind+=poz+lsubs; sir=sir.substring(poz+lsubs); Clase înfăşurătoare Pentru fiecare tip primitiv s-a construit câte o clasă înfăşurătoare. Un obiect al clasei înfăşurătoare poate reţine o valoare a tipului primitiv. Alăturat, puteţi observa corespondenţa între numele tipurilor primitive şi numele claselor înfăşurătoare. int Integer short - Short long Long byte Byte char Character float Float double Double boolean Boolean

274 274 Manual de Informatică pentru clasa a XII-a Fiecare clasă înfăşurătoare este înzestrată cu o metodă constructor. Exemplul Analizaţi liniile de mai jos: int n=4; Integer nr=new Integer(n); Double x=new Double (-12.34); Character c=new Character ('e'); Boolean este=new Boolean(true); Constructorii acestor clase sunt supraîncărcaţi, în sensul că există şi constructori care au ca parametru de intrare referinţe către obiecte de tip String. Exemplul Analizaţi liniile de mai jos: Integer nr=new Integer("10"); Double x=new Double ("-12.34"); Boolean este=new Boolean("true"); Fiecare clasă înfăşurătoare conţine o metodă care returnează valoarea reţinută de obiectul instanţiat de ea. Exemplul Se extrag valorile reţinute de obiectele create în primele exemple: int n1=nr.intvalue(); double x1=x.doublevalue(); char c1=c.charvalue(); boolean este1=este.booleanvalue(); Fiecare clasă care reţine o valoare numerică conţine câte o metodă statică (atenţie la apel!) pentru conversia către un tip primitiv a unui obiect de tip String. Astfel avem: a) int parseint(string s); // in Integer De exemplu: int t=integer.parseint("10"); b) parsefloat(string S); // in Float De exemplu: float b=float.parsefloat("-12.34"); c) double parsedouble (String s) // in Double De exemplu: double b=double.parsedouble("-12.34"); d) parselong(string s); // in Long De exemplu: long t=long.parselong("1000"); e) parsebyte(string s) // in Byte De exemplu: byte x=byte.parsebyte("12"); Dacă şirul de caractere nu poate fi convertit către valoarea numerică de tipul dorit, se generează o excepţie în urma căreia executarea programului se întrerupe.

275 Capitolul 7. Programare orientată pe obiecte 275 Conversia inversă, de la un tip primitiv către un şir se poate realiza uşor, aşa cum am mai întâlnit de multe ori concatenând un şir (eventual vid) cu o valoare numerică. Exemplul Secvenţa următoare afişează şirul 10 : int i=10; String s=new String(i+""); System.out.println(s); Clasele înfăşurătoare conţin constantele MIN_VALUE şi MAX_VALUE care reţin cea mai mică şi cea mai mare valoare a tipului respectiv. În cazul variabilelor de un tip real (float, double) MIN_VALUE are semnificaţia de cea mai mică valoare pozitivă care poate fi reţinută de tipul respectiv. Exemplul Priviţi liniile de mai jos: System.out.println(Integer.MIN_VALUE); System.out.println(Integer.MAX_VALUE); System.out.println(Double.MIN_VALUE); System.out.println(Double.MAX_VALUE); Figura 7.5. Rezultatul Clasele înfăşurătoare ale tipurilor reale (double, float) conţin constanta NaN (Not a Number). Valoarea NaN se obţine dacă, într-o expresie de tip real, se împarte 0 la 0, sau se extrage radical (indice 2) dintr-o valoare negativă, sau se aplică logaritmul unui număr negativ, etc. Exemplul Secvenţa de mai jos afişează NaN: double x=0,y=0,z; z=x/y; System.out.println(z); Exemplul Secvenţa de mai jos afişează NaN: int x=-2; System.out.println(Math.sqrt(x)); Clasele înfăşurătoare ale tipurilor reale (double, float) conţin metodele boolean isnan (double e), respectiv boolean isnan (float e). Cele două metode returnează true dacă se obţine NaN. Exemplul Secvenţa de mai jos afişează: "Ambii operanzi sunt 0": int x=0; double y=0; if (Double.isNaN(x/y)) System.out.println("Ambii operanzi sunt 0"); Exemplul Secvenţa afişează: "Radical dintr-un numar negativ": if (Double.isNaN(Math.sqrt(x))) System.out.println("Radical dintr-un numar negativ");

276 276 Manual de Informatică pentru clasa a XII-a Observaţie! Comparările precum cele de mai jos nu au efect. De exemplu, secvenţa nu afişează nici un mesaj: if (Math.sqrt(x)==Double.NaN) System.out.println("Radical din numar negativ"); Clasele înfăşurătoare ale tipurilor reale (double, float) conţin constantele POSITIVE_INFINITY, NEGATIVE_INFINITY. Constanta POSITIVE_INFINITY se obţine dacă, într-o expresie de tip real, se împarte o valoare pozitivă la 0, iar constanta NEGATIVE_INFINITY se obţine dacă, într-o expresie de tip real, se împarte la 0 o valoare negativă. double x=2; System.out.println(x/0); x=-2; System.out.println(x/0); Observaţie! Dacă expresia este de tip întreg, atunci se generează o excepţie (excepţiile vor fi studiate separat), iar programul este întrerupt, ca în secvenţa de mai jos: int x=2; System.out.println(x/0); Figura 7.6. Rezultatul Clasele înfăşurătoare ale tipurilor reale (double, float) conţin metoda booleană boolean isinfinite(double) (sau float) prin care se testează dacă s-a obţinut una din constantele de mai sus. Exemplul Secvenţa de mai jos afişează "Impartire la 0": double x=2; if (Double.isInfinite(x/0)) System.out.println("Impartire la 0"); 7.9. Extinderea claselor (moştenirea) 1. Pornind de la o clasă dată se poate crea o altă clasă, care o extinde (moşteneşte) pe aceasta. Noua clasă va avea toate datele membru şi toate metodele clasei de la care s-a pornit, cărora li se pot adăuga noi date membru şi/sau noi metode. În Java, clasa care este extinsă se numeşte superclasă, iar noua clasă se numeşte subclasă. Exemplul Analizaţi codul de mai jos: class C1 { int x,y;

277 Capitolul 7. Programare orientată pe obiecte 277 class C2 extends C1 { int z; void afis() { System.out.println(x+" "+ y+" "+z); public class C { public static void main(string[] args) { C2 ref= new C2(); ref.x=3; ref.y=4; ref.z=5; ref.afis(); Aici s-a extins clasa C1. Ea conţine două date membru x şi y, ambele de tip int. În exemplul dat, C1 este superclasă. Noua clasă C2 va conţine datele membru ale clasei C1 (în exemplu x şi y) dar şi o nouă dată membru (z, de tip int). De asemenea, clasa C2 conţine şi metoda afis(), care are rolul de a afişa conţinutul datelor membru ale unui obiect. În exemplu, clasa c2 este subclasă. Programul creează un obiect al clasei C2, numit ref, îi iniţializează datele membru şi le afişează. 2. Pentru a marca faptul că o clasă extinde o altă clasă se foloseşte cuvântul extends (în exemplu, class C2 extends C1). 3. Iniţializarea unui obiect al subclasei are ca efect apelul, în această ordine, al constructorului superclasei şi apelul constructorului subclasei. Este normal să fie aşa, pentru că subclasa include datele membru şi metodele superclasei. Exemplul Analizaţi programul de mai jos, în care fiecare clasă conţine câte un constructor: class Unu{ Unu () { System.out.println("Constructor 1"); class Doi extends Unu { Doi() { System.out.println("Constructor 2"); ; public class C { public static void main(string[] args) { Doi x=new Doi(); Programul afişează: Constructor 1 Constructor 2

278 278 Manual de Informatică pentru clasa a XII-a 4. Există posibilitatea ca anumite date membru sau metode să aibă acelaşi nume atât în superclasă cât şi în subclasă. În astfel de cazuri, implicit, la întâlnirea numelui datei membru (sau metodei) se apelează data membru (metoda) a subclasei. În cazul în care se doreşte ca să fie apelată data membru (metoda) a superclasei, se utilizează cuvântul cheie super. El are semnificaţia de obiect curent al superclasei. În exemplul de mai jos, x este dată membru atât a superclasei cât şi a subclasei. Exemplul Programul următor va afişa : class C1 { int x=1,y; class C2 extends C1 { int x; void afis() { System.out.println(super.x+" "+ y+" "+x); class C { public static void main(string[] args) { C2 pt= new C2(); pt.x=3; pt.y=2; pt.afis(); Observaţie! Cuvântul cheie super nu poate fi folosit în afara clasei. 5. În cazul în care superclasa este înzestrată cu un constructor care primeşte parametri, atunci este obligatoriu ca acesta să fie apelat de constructorul subclasei. De ce? Aşa cum am arătat, constructorul subclasei apelează automat constructorul superclasei. În cazul în care apelul nu este explicit, este apelat constructorul implicit (fără parametri) al superclasei. Ori, am învăţat faptul că, în condiţiile existenţei unui constructor cu parametri, nu mai este posibil să apelăm constructorul implicit, pentru că apare eroare. Mai mult, prima instrucţiune a constructorului subclasei trebuie să fie apelul constructorului superclasei. Apelul constructorului superclasei se face prin: super (lista_parametri). Exemplul Analizaţi programul următor, în care clasa Elev conţine numele şi prenumele unui elev, iar clasa Olimpic extinde clasa Elev şi conţine în plus o dată membru, materia la care elevul este olimpic şi o metodă prin care se afişează numele, prenumele elevului şi materia respectivă. class Elev { String nume, prenume; Elev (String nume, String prenume) { this.nume=new String(nume); this.prenume=new String(prenume);

279 Capitolul 7. Programare orientată pe obiecte 279 class Olimpic extends Elev { String materia; Olimpic(String nume, String prenume, String materia) { super(nume,prenume); // apel constructor al superclasei this.materia=new String(materia); void afis() { System.out.println(nume+" "+prenume+" "+materia); public class test { public static void main(string[] args) { //primul mod de creare a unui obiect olimpic Olimpic A=new Olimpic("Pascu", "Marius", "informatica"); //al doilea mod de creare a unui obiect olimpic String n=new String("Grosu"); String p=new String("Bogdan"); String mat=new String("matematica"); Olimpic B=new Olimpic(n,p,mat); A.afis(); B.afis(); 6. În Java, o clasă poate extinde (moşteni) o singură superclasă. Nu există un mecanism de moştenire multiplă, aşa precum există în alte limbaje. Din acest motiv, ierarhia claselor are o structură arborescentă Un exemplu de extindere a unei clase Fie clasa Complex, de mai jos. Are două date membru, x şi y, care reţin partea reală şi partea imaginară a unui număr complex. De asemenea, clasa este înzestrată cu un constructor şi metoda afis(), care afişează numărul complex reţinut de obiect. class Complex { double x,y; Complex (double x, double y) { this.x=x; this.y=y; void afis() { System.out.println(x+" "+y); Clasa este extinsă la o alta, Complex_op, care conţine şi metode prin care se efectuează operaţiile de mai jos cu numere complexe: z1 + z 2 = x1 + i y1 + x 2 + i y 2 = x1 + x 2 + i (y1 + y 2 ). z1 z 2 = x1 + i y1 x 2 i y 2 = x1 x 2 + i (y1 y 2 ). z = x + i y x + i y = x x y y + i (x y ( 1 1 )( 2 2 ) y ). + i y1 ( x1 + i y1 ) ( x2 i y2 ) x1x 2+ y1y2 + i( x2 y1 x1 y2 ) = = i y ( x + i y ) ( x i y ) x + y z1 2 x 1 z z 1 2 x = x

280 280 Manual de Informatică pentru clasa a XII-a Iată ce conţine, în plus, clasa Complex_op: Doi constructori. Primul dintre ei acceptă partea reală şi partea imaginară a unui număr complex. Al doilea, acceptă numai partea reală (număr real inclus evident în mulţimea numerelor complexe). Metodele add, sub, mul, div - efectuează operaţiile de adunare, respectiv scădere, înmulţire, împărţire a două numere complexe. Ele returnează numărul complex rezultat în urma operaţiei. class Complex_op extends Complex { Complex_op (double x, double y) { super(x,y); Complex_op (double x) { super(x,0); Complex_op add(complex_op z) { Complex_op t=new Complex_op (x+z.x,y+z.y); return t; Complex_op sub(complex_op z) { Complex_op t=new Complex_op (x-z.x,y-z.y); return t; Complex_op mul(complex_op z) { Complex_op t=new Complex_op (x*z.x-y*z.y, x*z.y+z.x*y); return t; Complex_op div(complex_op z) { double num=z.x*z.x+z.y*z.y; Complex_op t; if (num!=0) t=new Complex_op ((x*z.x+y*z.y)/num,(z.x*y-x*z.y)/num); else t=new Complex_op(0,0); return t; În continuare, sunt prezentate exemple de lucru cu numerele complexe. Exemplul Să se creeze două obiecte de tip Complex_op şi să se afişeze suma, diferenţa, produsul şi câtul lor. public class test { public static void main(string[] args) { // instantiez z si il afisez Complex_op z=new Complex_op(2,3); z.afis(); // instantiez z1 si il afisez Complex_op z1= new Complex_op(10); z1.afis();

281 Capitolul 7. Programare orientată pe obiecte 281 // Afisez suma dintre z si z1 z.add(z1).afis(); // Afisez diferenta dintre z si z1 z.sub(z1).afis(); // Afisez produsul dintre z si z1 z.mul(z1).afis(); // Afisez catul dintre z si z1 z.div(z1).afis(); Exemplul Se citesc a şi b două numere reale care reprezintă partea reală şi partea complexă a numărului z=a+b*i şi n, un număr natural mai mare sau egal cu 1. Se cere să se afişeze z n. public class test { public static void main(string[] args) { System.out.print("a="); double a=double.parsedouble(cin.token()); System.out.print("b="); double b=double.parsedouble(cin.token()); Complex_op z= new Complex_op(a,b); z.afis(); // initializez produsul cu 1; Complex_op P= new Complex_op(1); System.out.print("n="); int n=integer.parseint(cin.token()); for (int i=0;i<n;i++) P=P.mul(z); P.afis(); Exemplul Să se extindă clasa Complex_op, la o alta numită Cmpl, care să conţină, în plus, o metodă prin care returnează modulul numărului complex şi o altă metodă booleană care returnează true, în cazul în care numărul este real (y are valoarea 0). Rezolvare. Întrucât constructorii nu se moştenesc, a fost necesară rescrierea lor: class Cmpl extends Complex_op { Cmpl (double x, double y) { super(x,y); Cmpl (double x) { super(x,0); double modul() { return Math.sqrt(x*x+y*y); boolean real() { return y==0;

282 282 Manual de Informatică pentru clasa a XII-a Exemplul Se citeşte un vector de numere complexe. Se cere să se sorteze crescător elementele vectorului în funcţie de modulul lor. Rezolvare. Datorită faptului că avem nevoie de modulul numerelor complexe, vom apela la ultima clasă creată: Cmpl. Observaţi ierarhia acestor clase: la bază este Complex, apoi Complex_op, iar ultima este Cmpl. Programul utilizează şi metoda Afis(), care aparţine clasei complex. public class test { public static void main(string[] args) { System.out.print("n="); int n=integer.parseint(cin.linie()); Cmpl[] V=new Cmpl[n]; for (int i=0;i<n;i++) { System.out.print("V["+i+"].x="); double x=double.parsedouble(cin.linie()); System.out.print ("V["+i+"].y="); double y=double.parsedouble(cin.linie()); V[i]=new Cmpl(x,y); boolean gasit; Cmpl man; do { gasit=false; for (int i=0;i<n-1;i++) if (V[i].modul()>V[i+1].modul()) { man=v[i]; V[i]=V[i+1]; V[i+1]=man; gasit=true; while (gasit); for (int i=0;i<n;i++) V[i].afis(); Polimorfism Prin polimorfism vom înţelege posibilitatea ca atât superclasa, cât şi subclasa să aibă metode cu acelaşi nume (metodele pot fi redefinite). Deşi, în aparenţă, înţelegerea polimorfismului nu este dificilă, în realitate, apar anumite probleme pe care ne propunem să le rezolvăm în acest paragraf. Mai mult, polimorfismul reprezintă unul din punctele cheie ale programării orientate pe obiecte şi este un instrument puternic de programare.

283 Capitolul 7. Programare orientată pe obiecte 283 Fie B o clasă care extinde o clasă A. Prin urmare, toate datele membru şi metodele clasei A se regăsesc şi în clasa B. Am mai învăţat faptul că o metodă a clasei A poate fi redefinită, adică în clasa B scriem o metodă cu acelaşi nume (în exemplu, void tip()). Vom trata două cazuri, cazul în care metodele sunt nestatice şi cazul în care metodele sunt statice. I) Metodele şi datele membru sunt nestatice. Exemplul Fie O un obiect al clasei A şi O1 un obiect al clasei B. Vedeţi exemplul următor, al cărui rezultat îl puteţi observa în Fig. 7.7: class A { int i=1; void tip() { System.out.println("clasa A"); class B extends A { void tip() { System.out.println("clasa B"); public class test { public static void main(string[] args) { // Cazul 1 A O=new A(); O.tip(); // Cazul 2 B O1=new B(); O1.tip(); // Cazul 3 A O2=new B(); O2.tip(); Figura 7.7. Rezultatul În cazul 1 se apelează metoda tip() a clasei A. Se va afişa clasa A şi valoarea 1 (pentru i). Este normal să fie aşa, obiectul este al clasei A, referinţa este către un obiect al clasei A. În cazul 2 se apelează metoda tip() a clasei B. Se va afişa clasa B şi valoarea 2 (pentru i). Este normal să fie aşa, obiectul este al clasei B, referinţa este către un obiect al clasei B. În cazul 3, acesta este cazul interesant pe care-l studiem în acest moment, se va apela metoda tip() a clasei B, prin urmare se va afişa clasa B şi valoarea 1 (pentru i). Să observăm că obiectul este al clasei B, dar variabila care reţine referinţa către el este o referinţă către obiecte ale clasei A. Cu toate că a fost apelată metoda clasei B, a fost afişat conţinutul variabilei i a clasei A. Foarte important! În cazul unei metode a superclasei, redefinită în subclasă, două elemente prezintă importanţă: tipul variabilei referinţă (către obiecte ale superclasei sau către obiecte ale subclasei) şi tipul obiectului creat (al superclasei sau al subclasei). Se disting, astfel două cazuri:

284 284 Manual de Informatică pentru clasa a XII-a A) tipul referinţei şi tipul obiectului creat coincid (sunt fie ale superclasei, fie ale subclasei). În acest caz este apelată metoda care este din tipul comun. De asemenea, se afişează variabila care aparţine obiectului de tip comun. Vezi, mai sus, cazurile 1 şi 2. B) tipul referinţei este al superclasei, iar tipul obiectului creat este al subclasei (invers nu este posibil, aşa cum am arătat). În acest caz, dacă metoda redefinită este nestatică, Java ia în considerare tipul obiectului creat şi deci, va fi apelată metoda subclasei. Vezi, mai sus, cazul 3. În schimb, se obţine accesul la data membru a superclasei. II) Metodele şi datele membru sunt statice. Exemplul Reluăm problema pentru acest caz. Vedeţi programul de mai jos, iar rezultatul afişat de el, în Fig În cazurile 1 şi 2 comportamentul este acelaşi, dar în cazul 3 este apelată metoda superclasei, deci se afişează clasa A. Observaţi faptul că, în acest caz, comportamentul este diferit. class A { static int i=1; static void tip() { System.out.println("clasa A"); class B extends A { static int i=2; static void tip() { System.out.println("clasa B"); public class test { public static void main(string[] args) { // Cazul 1 System.out.println("Cazul 1"); A O=new A(); O.tip(); System.out.println(O.i); // Cazul 2 System.out.println("Cazul 2"); B O1=new B(); O1.tip(); System.out.println(O1.i); // Cazul 3 System.out.println("Cazul 3"); A O2=new B(); O2.tip(); System.out.println(O2.i); Figura 7.8. Rezultatul În terminologia programării orientate pe obiecte veţi întâlni termenul de legare (statică, dinamică). Care este semnificaţia lui? Pornind de la referinţa către obiect, se apelează o metodă redefinită. Am văzut că, în unele cazuri se apelează metoda superclasei, în altele, se apelează metoda subclasei. Cu alte cuvinte, se apelează (leagă) o metodă sau alta. Aceasta este semnificaţia termenului de legare (adică apel al unei metode sau alta).

285 Capitolul 7. Programare orientată pe obiecte 285 Legarea este statică dacă înainte de executarea programului se poate şti care metodă este apelată şi este dinamică dacă numai în momentul executării se decide metoda care va fi apelată. În Java este permisă şi legarea dinamică. Priviţi exemplul de mai jos, în care legarea dinamică este evidentă. Exemplul Dacă se introduce 0 se afişează clasa A, iar dacă se introduce o valoare diferită de 0 se afişează clasa B: class A { int i=1; void tip() { System.out.println("clasa A"); class B extends A { void tip() { System.out.println("clasa B"); public class Clasa1 { public static void main(string[] args) { A x; int n=integer.parseint(cin.token()); if (n==0) x=new A(); else x=new B(); x.tip(); Un exemplu de polimorfism Să se creeze o clasă numită Muncitor. Clasa va conţine data membru ore_lucrate şi un constructor prin care acesteia i se atribuie o valoare. De asemenea, clasa conţine o metodă nestatică salariu() prin care se calculează suma câştigată de acesta (se obţine ca produs între numărul orelor lucrate şi suma încasată pentru o oră lucrată, în exemplu 2 lei). Dintre muncitori, se selectează şeful de echipă, care are în subordine mai mulţi muncitori. Se ştie că şeful de echipă primeşte mai mult pentru o oră lucrată (în exemplu, 5 lei). Se construieşte clasa Sef_echipa, care este subclasă a clasei Muncitor. Metoda salariu() este redefinită. Dintre şefii de echipă, unii sunt selectaţi pentru a urma o şcoală de maiştri. După ce devin maiştri, au în subordine mai mulţi şefi de echipă. Să se construiască clasa Maistru, care are ca superclasă clasa Sef_echipa. Un maistru primeşte pe oră mai mult decât un şef de echipă (în exemplu 10 lei), deci metoda salariu() este redefinită. Se cere să se scrie un program care citeşte un număr natural n între 1 şi 3. Dacă n este 1, se construieşte un obiect al clasei muncitor, dacă n este 2, se construieşte un obiect al clasei sef_echipa, iar dacă n este 3, se construieşte un obiect al clasei Maistru. De asemenea, se citeşte numărul de ore lucrat de persoana respectivă. În final, se va afişa salariul încasat de persoana citită.

286 286 Manual de Informatică pentru clasa a XII-a class Muncitor { int ore_lucrate; Muncitor(int ore_lucrate) { this.ore_lucrate=ore_lucrate; double salariu() { return ore_lucrate * 2; class Sef_echipa extends Muncitor { Sef_echipa(int ore_lucrate) { super(ore_lucrate); double salariu() { return ore_lucrate * 5; class Maistru extends Sef_echipa { Maistru(int ore_lucrate) { super(ore_lucrate); double salariu() { return ore_lucrate * 10; public class test { public static void main(string[] args) { Muncitor x=null; int tip=integer.parseint(cin.token()); int ore=integer.parseint(cin.token()); switch (tip) { case 1: x=new Muncitor(ore); break; case 2: x=new Sef_echipa(ore); break; case 3: x=new Maistru(ore); break; System.out.println(x.salariu()); Observaţii! Exemplul dat se referă la polimorfism şi la legarea dinamică. Metoda salariu este prezentă în toate cazurile. Este rulată o metodă sau alta în funcţie de valoarea citită, prin urmare avem legare dinamică. Există multe alte metode de rezolvare ale acestei probleme. Judecând după problema în sine, ar rezulta că utilizarea polimorfismului poate fi evitată. Aşa este, dar în cazul programelor complexe (de exemplu, în programarea vizuală), utilizarea lui se dovedeşte extrem de utilă.

287 Capitolul 7. Programare orientată pe obiecte Clase abstracte Limbajul Java pune la dispoziţia programatorilor un mecanism care se dovedeşte uneori extrem de eficient şi anume clasele abstracte. O clasă abstractă conţine date membru (nu în mod obligatoriu) şi mai multe metode, dar unele pot fi, la rândul lor abstracte. Pentru o metodă abstractă, în clasă se trece doar prin antetul ei. Metodele abstracte urmează să fie redefinite în subclase. Orice clasă abstractă trebuie să fie precedată de cuvântul cheie abstract şi orice metodă abstractă din cadrul ei trebuie şi ea să fie precedată de acelaşi cuvânt cheie. Clasele abstracte nu se folosesc direct, adică nu se instanţiază obiecte ale lor, ci se utilizează doar pentru a fi extinse (sunt prin definiţie superclase). Exemplul În programul de mai jos clasa Ex este abstractă. Conţine două metode abstracte, afis1() şi afis2(), dar şi o metodă decid(), care în funcţie de un parametru apelează una dintre cele două metode abstracte. Pentru a putea folosi clasa Ex, o extindem obţinând astfel clasa Ex1. În clasa Ex1, redefinim cele două metode. Totuşi, clasa Ex1 nu redefineşte metoda decid(), deci orice obiect al ei va folosi metoda din clasa abstractă. Acest mecanism, permite ca în clasa abstractă să existe un anumit motor (metodă) care apelează alte metode care urmează a fi redefinite. Programul de mai jos apelează mai întâi Afis 1 şi apoi Afis 2: abstract class Ex { abstract void afis1(); abstract void afis2(); void decid(int b) { if (b>0) afis1(); else afis2(); class Ex1 extends Ex { void afis1() { System.out.println("Afis 1"); void afis2() { System.out.println("Afis 2"); public class test { public static void main(string[] args) { Ex1 a=new Ex1(); a.decid(1); a.decid(-1);

288 288 Manual de Informatică pentru clasa a XII-a Un exemplu de clasă abstractă Cei care au studiat backtracking în variantă iterativă, standardizată, au văzut faptul că există o unică metodă care apelează mai multe metode care au acelaşi nume, parametri şi acelaşi rol. A rezolva o problemă sau alta înseamnă a rescrie metodele specifice (init(), succesor(), ş.a.m.d.) dar motorul (metoda back()) rămâne aceeaşi. De aici şi ideea: o clasă abstractă (Bkt) va reţine metoda back(), care nu este abstractă, iar celelalte metode sunt abstracte. A rezolva o problemă înseamnă a crea o subclasă în care redefinim metodele necesare (init(), succesor(), valid(),...) conform cerinţelor problemei. Exemplul Programul de mai jos, utilizează clasa bkt, pentru a o extinde în vederea rezolvării problemei particulare de generare a tuturor permutărilor mulţimii {1,2,...,n, pentru n citit. abstract class Bkt { int[] st; int n; abstract void init(int k); abstract boolean am_succesor (int k); abstract boolean e_valid(int k); abstract boolean solutie(int k); abstract void tipar(); void back() { boolean AS; int k=1; st=new int[n+1]; init(k); while (k>0) { do { while ((AS=am_Succesor(k)) &&!e_valid(k)); if (AS) if (solutie(k)) tipar(); else {k++;init(k); else k--; class Permut extends Bkt { Permut (int n) { this.n=n; void init(int k) { st[k]=0; boolean am_succesor (int k) { boolean rasp=false; if (st[k]<n) { st[k]++; rasp=true; return rasp;

289 Capitolul 7. Programare orientată pe obiecte 289 boolean e_valid(int k) { boolean rasp=true; for (int i=1;i<k;i++) if (st[i]==st[k]) rasp=false; return rasp; boolean solutie(int k) { return k==n; void tipar() { for (int i=1;i<=n;i++) System.out.print(st[i]); System.out.println(); public class test { public static void main(string[] args) { System.out.print("n="); int n=integer.parseint(cin.token()); Permut x=new Permut(n); x.back(); Exerciţiu! Se cere să se rezolve problema celor n dame. Folosind clasele anterioare şi polimorfismul, problema devine foarte uşoară. Obţinem clasa Dame care extinde clasa Permut. O singură metodă trebuie redefinită, metoda boolean e_valid(int k). class Dame extends Permut { Dame (int n) { super(n); boolean e_valid(int k) { boolean rasp=true; for (int i=1;i<k;i++) if ((st[i]==st[k]) (Math.abs(st[k]-st[i])==Math.abs(k-i))) rasp=false; return rasp; Iar programul este asemănător celui anterior: public class test { public static void main(string[] args) { System.out.print("n="); int n=integer.parseint(cin.token()); Bkt x=new Dame(n); x.back();

290 290 Manual de Informatică pentru clasa a XII-a Interfeţe Prin interfaţă vom înţelege un proiect de clasă. O interfaţă poate conţine doar constante şi antete de metode. Ele sunt acceptate de limbaj şi se presupune că ulterior, interfeţele vor fi implementate de una sau mai multe clase. O interfaţă arată ca o clasă, numai că, în locul cuvântului class, se foloseşte cuvântul interface. Atunci când scriem o clasă care implementează o anumită interfaţă, se foloseşte cuvântul cheie implements, ca în exemplul de mai jos. O interfaţă poate fi implementată de una sau mai multe clase. Exemplul Mai jos, avem o interfaţă numită InterfA. Interfaţa este implementată de două clase, A şi B. În main() probăm toate acestea prin crearea a două obiecte, unul care instanţiază clasa A, altul care instanţiază clasa B. Programul afişează: Afis din clasa A=6 5 Afis din clasa B=7 5 iar codul este: interface InterfA { int i=5; void afis(); class A implements InterfA{ int i=6; public void afis() { System.out.println("Afis din clasa A="+i+" "+InterfA.i); class B implements InterfA { int i=7; public void afis() { System.out.println("Afis din clasa B="+i+" "+InterfA.i); public class test { public static void main(string[] args) { A x=new A(); x.afis(); B y=new B(); y.afis(); Mai observăm că: Constantele declarate în interfaţă (în exemplu constanta i, cu valoarea 5) se apelează prin numele interfeţei, urmat de. şi de numele constantei. Constantele pot fi redefinite de date membru (în exemplu de i cu valoarea 6 şi i cu valoarea 7). Atât constanta cât şi redefinirile ei pot fi apelate simultan.

291 Capitolul 7. Programare orientată pe obiecte 291 Variabila de tip referinţă către interfaţă poate memora o referinţă către orice clasă care implementează respectiva interfaţă. Mai mult, legarea este dinamică, aşa cum rezultă din exemplul următor. Exemplul Pentru clasele implementate anterior, se poate obţine acelaşi efect dacă main() se scrie astfel: public static void main(string[] args) { int tip=integer.parseint(cin.token()); if (tip==1) { interfa x=new A(); x.afis(); else { interfa y=new B(); y.afis(); Interfaţa poate extinde mai multe interfeţe. Exemplul Să observăm că o clasă poate extinde o singură clasă, dar o interfaţă poate extinde mai multe interfeţe, ca mai jos: interface A { void meta(); interface B { void metb(); interface C { void metc(); interface Extinsa extends A,B,C { void MetE(); A implementa o interfaţă extinsă înseamnă a implementa toate metodele interfeţelor care au stat la baza extinderii, plus metodele a căror antet se găseşte în interfaţa extinsă. Exemplul Mai jos se implementează clasa Extinsa: class Ex implements Extinsa { public void meta() {System.out.println("metA"); public void metb() {System.out.println("metB"); public void metc() {System.out.println("metC"); public void mete() {System.out.println("metE"); public class test { public static void main(string[] args) { Ex x=new Ex(); x.meta(); x.metb(); x.metc(); x.mete(); 4. O clasă poate implementa oricâte interfeţe. Exemplul Analizaţi programul următor: interface A { void meta(); interface B { void metb(); interface C { void metc();

292 292 Manual de Informatică pentru clasa a XII-a class Ex implements A,B,C { public void meta() { System.out.println("metA"); public void metb() { System.out.println("metB"); public void metc() { System.out.println("metC"); public class test { public static void main(string[] args) { Ex x=new Ex(); x.meta(); x.metb(); x.metc(); În multe programe se solicită citirea unui număr natural. Aceasta se poate face prin afişarea unui mesaj, apoi urmează citirea propriu-zisă a acestuia. Pentru a permite ca programul să rămână aproape neschimbat atunci când citim un număr natural într-un fel sau altul, metoda care citeşte se va găsi într-o interfaţă, care este implementată diferit de mai multe clase. Exemplul În acest exemplu interfaţa CitScriu conţine antetul unei metode de citire a unui număr natural. Două clase, IO1 şi IO2 implementează această interfaţă. Clasa Suma este înzestrată cu un constructor care are ca parametru o referinţă către obiectul care efectuează citirea şi o metodă, afis(), care citeşte două numere naturale şi afişează suma lor. Rulaţi programul şi prin crearea obiectului Suma, cu ajutorul instrucţiunii: Suma s=new Suma (new IO2());. interface CitScriu { int citeste(); class IO1 implements CitScriu { public int citeste() { System.out.print("Introduceti valoarea "); return Integer.parseInt(cin.linie()); class IO2 implements CitScriu { public int citeste() { System.out.print("Tastati valoarea dorita "); return Integer.parseInt(cin.linie()); class Suma { CitScriu x; Suma(CitScriu x) { this.x=x; void afis() { int n=x.citeste(); n+=x.citeste(); System.out.println("Suma este "+n); public class test { public static void main(string[] args) { Suma s=new Suma (new IO1()); s.afis();

293 Capitolul 7. Programare orientată pe obiecte Specificatori de acces (modificatori de acces) Forma generală prin care o clasă este definită se poate observa mai jos. Tot ce este trecut între paranteze drepte este opţional. [<Modificatori clasa>] class <nume clasa> [extends <nume clasa>] implements [lista interfete] { [...] Până acum, nu am prezentat modificatorii de clasă. Aceştia sunt: public, abstract şi final şi se folosesc în această ordine. 1. Modificatorul public. Dacă este trecut acest modificator, atunci clasa respectivă poate fi accesată de orice cod Java care accesează pachetul în care se găseşte acea clasă. Dacă acest modificator este absent, atunci clasa poate fi accesată doar din pachetul în care se găseşte. Clasele publice trebuie scrise în fişiere care le poartă numele şi au extensia.java. Observaţie foarte importantă! În cazul în care la crearea clasei nu se foloseşte clauza package (nu se realizează un pachet), se consideră că respectiva clasă face parte dintr-un pachet fără nume. Pachetul fără nume este alcătuit din totalitatea claselor fără clauza package care se găsesc într-un folder. Din acest motiv, cât timp am lucrat numai cu clase aflate în folder-ul bin, nu a fost nevoie ca acestea să conţină clauza package. 2. Modificatorul abstract - marchează o clasă abstractă (revedeţi clasele abstracte). În absenţă, se consideră că respectiva clasă nu este abstractă. 3. Modificatorul final este trecut atunci când nu se doreşte ca respectiva clasă să fie extinsă (derivată, moştenită), caz în care această operaţie este interzisă. În rest, am învăţat faptul că o clasă poate extinde o singură clasă, dar poate implementa mai multe interfeţe (vedeţi: extends, implements). Pentru definirea datelor membru în Java, avem forma generală: [<Modificatori>] <tip data> <Nume data membru 1 >[=valoare] [Nume data membru 2 ][=valoare]... Modificatorii sunt: 1. public - data membru poate fi accesată de oriunde este accesibilă (deci şi din afara pachetului) şi poate fi moştenită; 2. protected - data membru poate fi accesată de codul aflat în acelaşi pachet şi poate fi moştenită; 3. private - data membru poate fi accesată numai din clasa în care se află şi nu este moştenită (sau dacă vreţi, este moştenită, dar nu poate fi accesată din clasa care o moşteneşte, ceea ce este acelaşi lucru);

294 294 Manual de Informatică pentru clasa a XII-a 4. modificatorul implicit (package) are efect în absenţa modificatorilor de mai sus. Data poate fi accesată de cod din acelaşi pachet şi poate fi moştenită numai de clase ale aceluiaşi pachet; 5. final data membru este considerată constantă, deci nu poate fi modificată; 6. static - data membru nu este memorată de fiecare obiect al clasei respective (modificatorul a mai fost prezentat). Modificatorii public, protected, private şi cel implicit (package) se numesc modificatori de acces. Evident, o definiţie de dată membru va conţine numai unul din cei trei modificatori sau, în absenţa lor, se consideră că avem modificatorul implicit. Pentru declararea unei metode se utilizează forma generală: [<Modificatori>] <Tip metoda> <Nume> (<lista parametri>) [throws <TipClasa 1 >[<TipClasa 2 >]...]]<metoda> Modificatorii sunt prezentaţi mai jos, iar clauza throws va fi studiată în capitolul care tratează excepţiile. 1. Modificatorii de acces - au aceeaşi semnificaţie ca la datele membru. 2. final - specifică faptul că într-o clasă derivată, metoda nu poate fi redefinită. 3. static - are ca efect faptul că metoda nu este reţinută de fiecare obiect al clasei respective. Acest modificator a fost prezentat Exemple de utilizare a modificatorilor Exemplul Modificatorii sunt absenţi. Clasa poate fi accesată din interiorul pachetului, poate fi derivată, data membru i poate fi moştenită ca şi metoda met(). De asemenea, data membru şi metoda pot fi accesate de date aflate în acelaşi pachet. class A { int i=2; void met() {System.out.println( Test ); ; Exemplul Clasa test trebuie să se găsească în fişierul test.java (deoarece este publică). Pentru ea nu se pot crea subclase (pentru că are modificatorul final). Data membru i este statică, adică nu se regăseşte în fiecare obiect al clasei respective, iar metoda este nestatică, deci se regăseşte în fiecare obiect al clasei respective. public final class test { static int i=2; void met() {System.out.println("Test"); ;

295 Capitolul 7. Programare orientată pe obiecte 295 În aceste condiţii, definiţia clasei de mai jos este eronată, chiar dacă se găseşte în acelaşi pachet cu clasa test. class B extends test { Exemplul Fie clasele de mai jos: class A { private int i=2; void met() { System.out.println("Test"); void metp() { System.out.println(i); ; class B extends A { void met1() { System.out.println("Test1"); În aceste condiţii, dacă în clasa de mai jos, aflată în acelaşi pachet, se înlocuiesc cele trei puncte cu instrucţiunile următoare, atunci: public class test { public static void main(string[] args) { A x=new A();... a) System.out.println(x.i); - avem eroare, deoarece i are modificatorul private, deci nu poate fi accesat din afara clasei; b) x.met(); - se afişează Test pentru că metoda nu este privată; c) B y=new B(); y.met1(); - se afişează Test1; d) B y=new B(); y.met(); - se afişează Test; e) x.metp(); - se afişează 2. Deşi i este privat, el este afişat de met() care are acces la datele private ale propriei clase. Exemplul Fie clasa de mai jos. Atunci: class A { final int i=2; final void met() {System.out.println("Test"); void metp() { System.out.println(i); a) Clasa următoare, aflată în acelaşi pachet, este eronată pentru că data membru i este cu modificatorul final, este deci considerată constantă şi prin urmare nu i se poate modifica valoarea: public class test { public static void main(string[] args) { A x=new A(); x.i=4;

296 296 Manual de Informatică pentru clasa a XII-a b) Clasa următoare, aflată în acelaşi pachet, este eronată pentru că extinde clasa A şi redefineşte o metodă care conţine modificatorul final: class B extends A { void met() { System.out.println("Test1"); c) Clasa următoare, aflată în acelaşi pachet, este corectă pentru că, deşi extinde clasa A, redefineşte o metodă care nu are modificatorul final: class B extends A { void metp() { System.out.println("Test2"); Excepţii (tratarea erorilor) Prin excepţie vom înţelege o situaţie nedorită în care poate ajunge un program în timpul rulării. Există nenumărate exemple de excepţii: se doreşte citirea unui număr natural, dar din greşeală, utilizatorul introduce un caracter; datele introduse pentru diverse câmpuri nu sunt în plaja de valori admisă pentru câmpul respectiv; un vector are n componente (indicii sunt de la 0 la n-1) şi se încearcă, de exemplu, să se atribuie o valoare componentei de indice n; se încearcă deschiderea unui fişier inexistent;... Pentru a rezolva astfel de situaţii, în Java există un mecanism extrem de bine pus la punct (mecanism de tratare a excepţiilor) Mecanismul de tratare a excepţiilor Pentru a prezenta acest mecanism vom porni de la un exemplu extrem de simplu, atât de simplu încât ar putea fi tratat fără probleme şi în absenţa acestuia. Exemplul Să se citească şi să se afişeze un număr natural 1 n 5. Practic, problema se reduce la citirea unui întreg şi afişarea lui. Dar, în timpul executării, din greşeală, se poate introduce o valoare numerică care nu este între aceste valori. Cum procedăm, altfel decât în mod clasic?

297 Capitolul 7. Programare orientată pe obiecte 297 Priviţi exemplul următor, în care dacă numărul citit este între 1 şi 5, acesta este afişat, altfel se afişează mesajul 1<=n<=5: class Eroare extends Exception { void afis() { System.out.println("1<=n<=5"); class t { public static int citesc() throws Eroare { int n=integer.parseint(cin.linie()); if (n>=1 && n<=5) return n; else throw new Eroare(); public static void main(string[] args) { try { int numar=citesc(); System.out.println(numar); catch (Eroare er) {er.afis(); a) Clasa Eroare extinde clasa Exception (este obligatoriu să fie precizată această extensie. Ea conţine o singură metodă, void afis(), care are rolul de a afişa mesajul de eroare. b) La sfârşitul antetului metodei int citesc() se găseşte cuvântul cheie throws, urmat de numele clasei care tratează eroarea respectivă. Prin aceasta se anunţă că respectiva metodă poate întoarce fie un întreg (în caz de introducere reuşită a datelor, fie o referinţă către un obiect al clasei Eroare (în caz de introducere nereuşită a datelor). Iată deci, că în acest caz, metodele pot întoarce şi date de alt tip decât cel dat de tipul metodei! Acest aspect este esenţial. Instrucţiunea throw returnează referinţa către un obiect al clasei Eroare. c) Utilizarea metodei citesc() se face, în mod obligatoriu, cu ajutorul instrucţiunii try (încearcă). Secvenţa în care poate apărea excepţia, se găseşte în instrucţiunea compusă subordonată lui try (în exemplu int numar=citesc()). Dacă citirea reuşeşte, programul îşi încheie executarea, altfel, se verifică dacă obiectul întors de metodă este de tip Eroare (vezi clauza catch). În caz afirmativ, se execută metoda afis() a acestui obiect (er este referinţa către obiect). În sinteză, putem afirma: clauza throws are rolul de a specifica faptul că o metodă poate întoarce şi referinţe către obiectele altor clase (dacă extind clasa Exception). Dacă sunt mai multe clase, atunci numele acestora sunt separate prin virgulă. instrucţiunea throw - returnează referinţa către unul din obiectele claselor trecute după clauza throws. instrucţiunea try are forma generală (ceea ce este trecut între paranteze drepte este facultativ):

298 298 Manual de Informatică pentru clasa a XII-a try { secvenţa de instrucţiuni care pot conduce către excepţii catch (ER1 ob1) { secvenţa care tratează excepţia cu clasa Er1 [ catch (ER2 ob2) { secvenţa care tratează excepţia cu clasa Er2 catch (ER3 ob3) { secvenţa care tratează excepţia cu clasa Er2... catch (ERn obn) { secvenţa care tratează excepţia cu clasa Ern ] [ finally { secvenţa se execută indiferent dacă a fost eroare sau nu] Exemplul Extindem, ce-i drept, în mod artificial exemplul anterior. Pentru cele două excepţii (n<1 şi n>5) vom utiliza două metode diferite aflate în clase diferite (Eroare1 şi Eroare2). În acest caz metodele sunt de tip constructor, deci corpurile catch sunt vide. class Eroare1 extends Exception { Eroare1() { System.out.println("1<=n"); class Eroare2 extends Exception { Eroare2() { System.out.println("n<=5"); class t { public static int citesc() throws Eroare1,Eroare2 { int n=integer.parseint(cin.linie()); if (n<1) throw new Eroare1(); else if (n>5) throw new Eroare2(); else return n; public static void main(string[] args) { try { int numar=citesc(); System.out.println(numar); catch (Eroare1 er1) { catch (Eroare2 er2) { Una dintre raţiunile existenţei unui mecanism de tratare a excepţiilor este dată de faptul că, în anumite cazuri, excepţia poate fi tratată în mod corespunzător, după care secvenţa se poate relua (fără ca programul să-şi încheie executarea). Exemplul Revenim asupra exemplului dat, în care se citesc numere naturale din intervalul [1,5]. Programul următor citeşte şi afişează un vector cu 3 astfel de componente. În momentul în care s-a introdus un număr greşit citirea se reia. Programul îşi încheie executarea atunci când au fost citite toate cele 3 componente ale vectorului.

299 Capitolul 7. Programare orientată pe obiecte 299 class Eroare extends Exception { void afis() { System.out.println("1<=n<=5"); class e { public static int citesc() throws Eroare { int n=integer.parseint(cin.linie()); if (n>=1 && n<=5) return n; else throw new Eroare(); public static void main(string[] args) { int[] V=new int[3]; for (int i=0;i<3;i++) try { V[i]=citesc(); catch (Eroare er) { er.afis(); i--; System.out.println("Am citit"); for (int i=0;i<3;i++) System.out.print(V[i]+" "); Dacă clasa care tratează excepţia extinde clasa Exception, atunci este obligatoriu ca apelul metodei ce poate returna o excepţie să se facă în construcţia try, ca în exemplul anterior, sau metoda care apelează o astfel de metodă să conţină în antet clauza throws. Exemplul Dacă în metoda main() de mai sus, am avea V[]=citesc(), fără construcţia try, atunci am primi eroare de compilare. Exemplul citesc() poate fi apelată ca mai jos, unde metoda main() conţine clauza throws. Oricum, în acest caz, dacă numărul nu este în intervalul [1.5], excepţia este tratată printr-un mesaj implicit în care se precizează numele clasei căreia îi aparţine obiectul returnat. public static void main(string[] args) throws Eroare { System.out.println(citesc()); Clasa Exception conţine (printre altele): un constructor implicit (fără parametru): Exception(); un constructor cu parametru de tip String: Exception(String mes); o metodă care returnează mesajul mes, primit de constructor: String getmessage(). Exemplul În aceste condiţii, programul din exemplul 7.68 poate fi scris şi ca mai jos (mai simplu):

300 300 Manual de Informatică pentru clasa a XII-a class e { public static int citesc() throws Exception { int n=integer.parseint(cin.linie()); if (n>=1 && n<=5) return n; else throw new Exception("1<=n<=5"); public static void main(string[] args) { int[] V=new int[3]; for (int i=0;i<3;i++) try { V[i]=citesc(); catch (Exception er) {i--; System.out.println(er.getMessage()); System.out.println("Am citit"); for (int i=0;i<3;i++) System.out.print(V[i]+" "); Uneori, este deranjant faptul că instrucţiunea capabilă să producă o excepţie trebuie pusă automat sub try, iar clasa căreia îi aparţine trebuie să conţină clauza throws. Mai mult, chiar în Java există metode care pot produce excepţii, dar care pot fi folosite fără try. De exemplu, metoda parseint a clasei Integer. Priviţi programul următor, în care dacă şirul de caractere introdus poate fi convertit către un întreg se afişează numărul, altfel programul se termină cu excepţie. Şi toate acestea fără try... class e { public static void main(string[] args) { int n=integer.parseint(cin.linie()); Să analizăm antetul complet al metodei parseint: public static int parseint(string s) throws NumberFormatException Observăm că, în cazul în care apare o excepţie, se apelează la clasa NumberFormatException. De aici, putem deduce o primă observaţie: dacă dorim ca programul nostru să furnizeze un mesaj în caz de excepţie, putem proceda ca mai jos, adică să folosim construcţia try, şi în caz că se returnează un obiect al clasei NumberFormatException, să afişăm un mesaj de eroare lămuritor. class e { public static void main(string[] args) { System.out.print("n="); int n=1; try { n=integer.parseint(cin.linie()); catch (NumberFormatException e) { System.out.println("Valoare nenumerica"); System.out.println(n);

301 Capitolul 7. Programare orientată pe obiecte 301 Mai mult, citirea se poate efectua până când valoarea introdusă este corectă, ca în programul următor: class e { public static void main(string[] args) { int i=1, n=1; while (i==1) { System.out.print("n="); try { n=integer.parseint(cin.token()); i=0; catch (NumberFormatException e) { System.out.println ("Valoare nenumerica"); System.out.println(n); Dacă în secvenţa subordonată lui try se depistează o excepţie, se abandonează executarea tuturor instrucţiunilor. În exemplu, aceasta implică faptul că i rămâne 1, deci se reia secvenţa subordonată lui while. Dacă nu a apărut excepţia, i devine 0 şi prin urmare, executarea lui while este considerată încheiată. Dacă nu l-am fi declarat de la început pe n cu valoare iniţială, oricare ar fi ea, programul ar fi semnalat eroare la compilare, pentru că se ajunge la afişarea lui. Ori, în Java, nu este permisă afişarea conţinutului unei variabile neiniţializate. Totuşi, nu se rezolvă problema pusă: cum este posibil ca parseint să poată fi folosită fără construcţia try? Obiectele claselor care extind clasa RuntimeException sau Error pot fi apelate fără ca antetul lor să conţină clauza throws, ca mai jos: class Eroare extends RuntimeException { void afis() { System.out.println("1<=n<=5"); class e { public static int citesc() // fara throws { int n=integer.parseint(cin.linie()); if (n>=1 && n<=5) return n; else throw new Eroare(); public static void main(string[] args) {... Pot exista următoarele cazuri:

302 302 Manual de Informatică pentru clasa a XII-a a) Dacă în main() avem secvenţa de mai jos, atunci distingem două cazuri: int numar=citesc(); a1) Se introduce un număr între 1 şi 5 - programul nu generează excepţie şi totul este OK! a2) Se introduce un număr în afara intervalului. Va fi afişată o excepţie într-un format implicit şi nu se va afişa mesajul "1<=n<=5". b) Dacă în main() avem secvenţa: try { int numar=citesc(); System.out.println(numar); catch (Eroare er) { er.afis(); b1) Se introduce un număr între 1 şi 5 - programul nu generează excepţie şi totul este OK! b2) Se introduce un număr în afara intervalului. Va fi afişată excepţia cu mesajul "1<=n<=5" Metodele care pot returna, în caz de excepţii, obiecte ale unor alte clase Priviţi antetul metodei parseint a clasei Integer. Din considerente didactice, până acum antetul nu a fost prezentat integral. În cazul în care se întâlneşte o excepţie, se returnează un obiect al clasei NumberFormatException: public static int parseint(string s) throws NumberFormatException Exemplul Aceasta poate ajuta programatorul să gestioneze situaţia, ca în exemplul de mai jos, unde se citeşte o variabilă întreagă care este afişată. În cazul în care valoarea introdusă nu este corectă, se reia citirea. class e { public static void main(string[] args) { int i=0; while (i==0) try { int numar=integer.parseint(cin.token()); System.out.println(numar); i=1; catch (NumberFormatException e) { System.out.println("Numar eronat");

303 Capitolul 7. Programare orientată pe obiecte 303 Iată şi antetul complet al metodelor parsefloat şi parsedouble: 1. public static double parsedouble(string s) throws NumberFormatException 2. public static float parsefloat(string s) throws NumberFormatException În cazul împărţirii la 0 pentru tipuri întregi, se returnează un obiect al clasei ArithmeticException. Exemplul Vedeţi codul de mai jos: class t { public static void main(string[] args) { System.out.print("n="); int n=integer.parseint(cin.token()); System.out.print("m="); int m=integer.parseint(cin.token()); try { System.out.println(n/m); catch (ArithmeticException e) { System.out.println ("Impartire la 0 "); În cazul în care se încearcă să se atribuie o valoare unei componente inexistente a unui vector, se returnează pentru tipuri întregi un obiect al clasei ArrayIndexOutOfBoundsException. Exemplul Vedeţi codul de mai jos: class t { public static void main(string[] args) { int []v=new int[3]; System.out.print("indice="); int indice=integer.parseint(cin.token()); try { v[indice]=1; catch (ArrayIndexOutOfBoundsException e) { System.out.println ("Eroare indice"); Observaţie foarte importantă! Clasele ArrayIndexOutOfBoundsException, ArithmeticException ca şi multe altele de acest tip, sunt rezultate în urma unor derivări ale clasei Exception. Cum un parametru de tip referinţă către un obiect al superclasei poate reţine referinţe către obiectele subclaselor sale, atunci putem scrie clauza catch de forma: catch (Exception e) {...

304 304 Manual de Informatică pentru clasa a XII-a Exemple de tratare a excepţiilor Exemplul Validare pentru numere reale. Să se scrie un program care citeşte n, număr natural şi n numere reale. Se cere să se calculeze suma numerelor citite. Dacă un număr real se introduce greşit (nu respectă formatul de număr real) se reia citirea lui. Metoda parsedouble, a clasei Double, returnează fie un număr de format double, fie un obiect al clasei NumberFormatException. class e { public static void main(string[] args) { double s=0; System.out.print("n="); int n=integer.parseint(cin.linie()); for (int i=0;i<n;i++) try { double x=double.parsedouble(cin.linie());s+=x; catch (NumberFormatException e) { System.out.println("Numar eronat");i--; System.out.println("S="+s); Exemplul Validare alfabetică. Se citeşte un şir de caractere alcătuit din mai multe cuvinte separate prin blank-uri. Dacă şirul citit conţine numai literele alfabetului (mici sau mari) sau blank-uri, acesta se va afişa, altfel se va tipări mesajul sir nealfabetic. Metoda citsir() citeşte şirul şi îl validează. Dacă şirul este valid, el este returnat, altfel se returnează un obiect al clasei Nealfabetic. În main() se testează dacă a fost returnat şirul (try), caz în care acesta este afişat, sau a fost returnat un obiect al clasei Nealfabetic, caz în care se afişează mesajul de eroare sir nealfabetic prin utilizarea metodei mesaj() a obiectului. class Nealfabetic extends RuntimeException { String mesaj() { return "sir nealfabetic"; class e { static String citsir() { String sir=new String(cin.linie()); boolean gasit=false; for (int i=0;i<sir.length();i++) if ( (sir.charat(i)<'a' sir.charat(i)>'z') && (sir.charat(i)<'a' sir.charat(i)>'z') && sir.charat(i)!=' ') gasit=true; if (gasit) throw new Nealfabetic(); else return sir;

305 Capitolul 7. Programare orientată pe obiecte 305 public static void main(string[] args) { boolean corect=false; System.out.print("Tastati sirul "); String s=""; try { s=citsir(); System.out.println(s); catch (Nealfabetic e) { System.out.println(e.mesaj()); Exerciţiile 1. şi 2. se referă la clasa de mai jos, care se găseşte deja compilată în directorul bin: class a { int a=1; int a() { int a=2; return a; 1. Care dintre programele de mai jos este corect din punct de vedere sintactic? a) class ex { public static void main(string[] args) { a a=new a(); b) class ex { public static void main(string[] args) { a x=new a; c) class ex { public static void main(string[] args) { x a=new a(); d) class ex { public static void main(string[] args) { a x=new (); 2. Fiind dată x, o variabilă care reţine o referinţă către un obiect al clasei a, care dintre instrucţiunile de mai jos afişează valoarea 2? a) System.out.println(x.a); b) System.out.println(x.a.a); c) System.out.println(x.a()); d) Nici una dintre instrucţiunile de mai sus nu afişează valoarea 2.

306 306 Manual de Informatică pentru clasa a XII-a 3. Fiind dată clasa de mai jos, ce afişează instrucţiunea aflată în main(): A.M(3.5)? class A { static void M(int x) {System.out.println(1); static void M(float x) {System.out.println(2); static void M(double x) {System.out.println(3); static void M(char x) {System.out.println(4); a) 1; b) 2; c) 3; d) Ce afişează programul următor? class A { int a,b; A(int a, int b) { this.a=a; this.b=b; A (int x) {b=x; void Afis() {System.out.print (a+" "+b); class ex { public static void main(string[] args) { A x=new A(3); x.afis(); a) Eroare; b) 3 0; c) 0 0; d) Creaţi o clasă numită Lista, care operează cu liste liniare simplu înlănţuite. Un element al listei liniare simplu înlănţuite este descris de clasa Nod: class Nod { Nod adr_urm; int nr; Clasa Lista va conţine: Data membru v - adresa primului nod al listei. În cazul în care lista este nulă, v reţine null. Metoda void adaug (int nr) - adaugă la sfârşitul listei un nod care va reţine valoarea numerică nr, primită de metodă ca parametru. Metoda void afis() - care afişează valorile reţinute de noduri. 6. Adăugaţi clasei Lista o metodă void stergp() care permite ştergerea primului nod introdus. 7. Adăugaţi clasei Lista o metodă void stergu() care permite ştergerea ultimului nod introdus.

307 Capitolul 7. Programare orientată pe obiecte Adăugaţi clasei Lista o metodă void adaugi(int nr) care permite ca la începutul listei să se adauge un nod care să conţină valoarea nr, primită de metodă ca parametru. 9. Scrieţi un program care creează o listă liniară simplu înlănţuită. Programul va utiliza clasa Lista, creată anterior. Numerele se citesc de la tastatură şi se vor găsi în listă în ordinea în care au fost introduse. Şirul de numere se consideră încheiat atunci când se citeşte numărul 0 (acesta nu este introdus în listă). 10. Realizaţi o clasă numită Stiva, care operează cu stive alocate ca liste liniare simplu înlănţuite. Un element al listei este descris de clasa Nod: class Nod { Nod adr_prec; int nr; Clasa Stiva va conţine următoarele: Data membru varf - reţine adresa ultimului nod introdus în stivă. Metoda void push(int nr) - adaugă un nod stivei şi acesta va reţine valoarea numerică nr, primită de metodă ca parametru. Metoda int pop() - extrage un nod din stivă şi returnează valoarea pe care acesta o reţinea. Dacă stiva este vidă, returnează Scrieţi un program care să citească 0<a<b, numere naturale şi să afişeze un număr aleator în intervalul [a,b]. 12. Scrieţi un program care citeşte x, număr real, şi n>0, număr natural şi calculează P=sin(x)*sin(2x)*...sin(n*x). Se presupune că x reprezintă o valoare exprimată în radiani. 13. Se citeşte de la tastatură un şir de caractere. Şirul conţine cel puţin 10 caractere. Se cere să se afişeze numai primele 10 caractere din şir. 14. Se citeşte de la tastatură un şir de caractere. Dacă şirul are mai mult de 4 caractere să se afişeze numai primele 4, altfel se va afişa şirul citit. 15. Scrieţi o clasă, numită Afis, care conţine metoda String anum(int lung, String s) metodă ce are rolul de a întoarce şirul reţinut de s, pe lungimea lung. Dacă numărul de caractere ale şirului este mai mare decât lung, se întoarce subşirul format din primele lung caractere ale şirului, altfel se întoarce un şir pe lungimea lung, şir alcătuit din caracterele şirului iniţial la care se adaugă un număr corespunzător de blank-uri. Exemple pentru lung=5: Şirul: Mihai - se returnează Mihai. Şirul: tastatura - se returnează tasta. Şirul: aer - se returnează aer. Observaţie! O astfel de metodă este utilă pentru afişarea unui şir de caractere pe o anumită lungime.

308 308 Manual de Informatică pentru clasa a XII-a 16. Scrieţi un program care citeşte n, număr natural şi n şiruri de caractere. Programul va afişa pe câte o linie, primele 5 caractere ale fiecărui şir citit. Dacă şirul are mai puţin de 5 caractere, se va afişa şirul, urmat de un număr de blank-uri astfel încât lungimea totală afişată să fie de 5 caractere. 17. Adăugaţi clasei Afis metoda String num(int lung, int v) care are rolul de a returna şirul de lungime lung, alcătuit din şirul obţinut din convertirea întregului v în şir şi în cazul în care acest şir are lungimea mai mică decât lung, el va fi precedat de un număr corespunzător de blank-uri. În situaţia în care lungimea şirului obţinut din conversia numărului este mai mare decât lung, metoda va returna un mesaj de eroare. Exemple pentru lung=3: Numărul se returnează 125. Numărul 1 - se returnează 1. Şirul: se returnează "Numarul nu poate fi afisat"; 18. Scrieţi un program care citeşte n, număr natural şi n numere naturale. Programul va afişa, pe câte o linie, fiecare dintre cele n numere naturale citite. Numerele se vor afişa pe 5 caractere şi vor fi aliniate la dreapta. Exemplu: n=3, numerele citite sunt: 12234, 45, 4. Se va afişa: Observaţie! În practică, şirurile alcătuite din caractere se afişează aliniate la stânga, iar valorile numerice se afişează aliniate la dreapta. 19. Adăugaţi clasei Afis metoda String num(int lung, int zec, double v) care returnează şirul rezultat din conversia unui număr real (indiferent de numărul de zecimale). Şirul are lungimea lung, numărul este afişat aliniat la dreapta şi va avea zec zecimale. În ipoteza în care numărul nu poate fi afişat prin utilizarea a lung caractere, se va returna un mesaj de eroare. Num(5,2, ) returnează ; Num(5,2,3.3456) returnează 3.34 ; Num(5,2,-9) returnează ; Num(5,2,123) returnează Numarul nu poate fi afisat. 20. Scrieţi un program care citeşte n, număr natural şi n numere reale. Programul va afişa pe câte o linie fiecare număr citit. Numerele se vor afişa pe 8 caractere, vor fi aliniate la dreapta şi vor avea obligatoriu două zecimale (indiferent de numărul de zecimale pe care îl au). 21. Să se extindă clasa cin. Noua clasă se va numi Cit şi va conţine metodele: static int Intreg() // citeşte şi returnează un număr întreg; static double Real() // citeşte şi returnează un număr real; static char Caracter() // citeşte şi returnează un caracter; static String Sir() // citeşte şi returnează un şir de caractere.

309 Capitolul 7. Programare orientată pe obiecte Utilizaţi noua clasă într-un program care citeşte şi afişează un număr întreg, unul real şi un caracter. 23. Fiind dată clasa de mai jos (Baza), scrieţi o clasă (Lista) care creează o listă liniară simplu înlănţuită în care elementele sunt obiectele clasei Baza. Evident, elementele acestei liste nu au nici o altă informaţie, în afara celei de adresă. class Baza { Baza adr_urm; Lista va conţine: Baza v; - data membru; reţine vârful listei; Baza varf() - returnează vârful listei liniare (adresa primului element); void adaug (Baza Nod) - adaugă la sfârşitul listei un element. 24. Creaţi clasa Int, care să extindă clasa Baza şi să conţină în plus: int val; - dată membru; Int (int val) - constructor; int valoare() - returnează valoarea reţinută de val. 25. Scrieţi un program care creează o listă liniară simplu înlănţuită cu n elemente (n citit de la tastatură) de tip Int. Valorile reţinute de obiectele de tip Int sunt, de asemenea, citite de la tastatură. Lista va fi construită cu ajutorul clasei Lista. 26. Scrieţi un program care creează o listă liniară simplu înlănţuită cu n elemente (n citit de la tastatură) de tip String. Şirurile de caractere reţinute de obiectele de tip Sir sunt, de asemenea, citite de la tastatură. Lista va fi construită cu ajutorul clasei Lista. Testele de la 27 la 30 se referă la clasele următoare. De fiecare dată, instrucţiunea (sau setul de instrucţiuni) la care se referă întrebarea va fi scrisă în locul liniei lipsă (punctată): class A { int x=1; void met() {System.out.println("Clasa A"); class B extends A { int x=2; void met() {System.out.println("Clasa B"); class C extends B { int x=3; void met() {System.out.println("Clasa C"); public class test { public static void main(string[] args) {...

310 310 Manual de Informatică pentru clasa a XII-a 27. Ce se afişează în urma executării secvenţei: A x=new B();x.met();? a) Clasa A; b) Clasa B; c) Clasa C; d) EROARE. 28. Ce se tipăreşte în urma executării secvenţei: A x=new B(); System.out.println(x.x);? a) 1; b) 2; c) 3; d) EROARE. 29. Ce se afişează în urma executării secvenţei de mai jos? B x=(a)new B(); x.met(); a) Clasa A; b) Clasa B; c) Clasa C; d) EROARE. 30. Ce se tipăreşte în urma executării secvenţei: B x=new C(); x.met();? a) Clasa A; b) Clasa B; c) Clasa C; d) EROARE. 31. Utilizând polimorfismul, scrieţi un program care citeşte un număr natural n şi dacă este prim, afişaţi succesorul său în mulţimea numerelor prime, dacă este impar (fără a fi prim) afişaţi succesorul său în mulţimea numerelor impare, iar dacă este par, afişaţi succesorul său în mulţimea numerelor pare. Exemple: n=7 se afişează 11; n=21 se afişează 23; n=8 se afişează Se citesc n, număr natural şi n numere reale. Se cere să se afişeze suma numerelor citite. Pentru citirea numerelor, programul va utiliza mecanismul excepţiilor (în caz de introducere greşită a datelor - care nu corespund formatului de număr real, se va afişa un mesaj corespunzător şi se va relua citirea numerelor). 33. La fel ca mai sus numai că cele n numere citite trebuie să fie mai mici decât 10. De asemenea, se va folosi mecanismul excepţiilor atât pentru formatul real, cât şi pentru valorile admise. 34. Scrieţi un program care citeşte două numere reale a şi b şi afişează rezultatul împărţirii lui a la b. Dacă ambele numere sunt 0, se va afişa un mesaj lămuritor, dacă numai b este 0, se va tipări alt mesaj lămuritor, iar dacă împărţirea se poate face, se va afişa rezultatul împărţirii. Evident, programul va utiliza mecanismul excepţiilor şi metode ale claselor înfăşurătoare (de revăzut!). 35. La fel ca mai sus numai că se vor utiliza excepţiile şi la citirea numerelor a şi b, iar în caz că împărţirea nu se poate efectua se va repeta citirea numerelor a şi b. (pentru verificare, rezolvările se găsesc la pag. 384)

311 CAPITOLUL Programare vizuală Prin studierea acestui capitol vom învăţa să scriem propriile programe utilizând programarea vizuală. Astăzi, activitatea de programare este de neconceput în absenţa ei. De asemenea, studiul acestui capitol reprezintă o excelentă recapitulare a OOP. Vă veţi da seama că, în absenţa OOP, este foarte greu să realizezi un astfel de program. Pentru toate programele pe care le realizaţi, nu uitaţi să proiectaţi interfeţe frumoase şi uşor de înţeles pentru utilizatori. Concepte de bază ale programării vizuale în Java Studiul principalelor componente Obiecte grafice. Clasa Graphics Accesarea şi prelucrarea datelor Cuvinte cheie: fereastră, container, componentă, poziţionare, gestionare, meniu, accelerator, cutie de dialog, culoare, bară de unelte, imagine, date, flux, JDBC

312 312 Manual de Informatică pentru clasa a XII-a 8.1. Conceptele de bază ale programării vizuale în Java Pentru a înţelege conceptele care stau la baza programării vizuale vom porni de la un exemplu arhicunoscut în programarea clasică. Exemplul 8.1. Rezolvarea ecuaţiei de gradul 2. Am putut observa, atunci când am rezolvat în mod clasic problema, că programul obţinut este cât se poate de neprietenos si inestetic. În plus, un program clasic îndepărtează un eventual utilizator neinformatician al programului. Acesta are impresia că are nevoie de multe cunoştinţe pentru utilizarea programului. Figura 3.1. Interfaţa grafică cu utilizatorul şi cutia de dialog cu rezultatele Rulaţi programul următor şi testaţi-l! În primul rând veţi observa că interfaţa cu utilizatorul este una prietenoasă. Este evident pentru oricine că trebuie introduşi coeficienţii şi că, pentru a obţine rezultatul, trebuie apăsat butonul Rezultat. În fapt, interfaţa grafică cu utilizatorul este, dacă vreţi, ambalajul programului, pentru că acesta conţine, ascuns, algoritmul clasic de rezolvare. import java.awt.*; import java.awt.event.*; import javax.swing.*; class Fer extends JFrame implements ActionListener { JTextField a,b,c,r; JButton but; public Fer(String titlu) { super(titlu); setsize(210,200); setresizable(false); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); //a x.setlayout(new FlowLayout ()); JLabel et1=new JLabel ("a="); x.add(et1); a=new JTextField(15); x.add(a); //b JLabel et2=new JLabel ("b="); x.add(et2); b=new JTextField(15); x.add(b);

313 Capitolul 8. Programare vizuală 313 //c JLabel et3=new JLabel ("c="); x.add(et3); c=new JTextField(15); x.add(c); //butonul but=new JButton("Rezultat"); x.add(but); but.addactionlistener(this); setvisible(true); public void actionperformed (ActionEvent e) { double ar=0,br=0,cr=0, er=0; try // incerc sa-l citesc pe A { ar=double.parsedouble(a.gettext()); catch (NumberFormatException exc) { er=1; JOptionPane.showMessageDialog(this, "a este introdus gresit"); try // incerc sa-l citesc pe B { br=double.parsedouble(b.gettext()); catch (NumberFormatException exc) { er=1; JOptionPane.showMessageDialog(this, "b este introdus gresit"); try // incerc sa-l citesc pe c { cr=double.parsedouble(c.gettext()); catch (NumberFormatException exc) { er=1; JOptionPane.showMessageDialog(this, "c este introdus gresit"); if (er==0)// daca a b c sunt corecte rezolvarea ecuatiei if (ar!=0) if (br*br-4*ar*cr<0) JOptionPane.showMessageDialog(this, "Nu are solutii reale"); else JOptionPane.showMessageDialog(this, "x1="+(-br+math.sqrt(br*br-4*ar*cr))/(2*ar)+"\n"+ "x2="+(-br-math.sqrt(br*br-4*ar*cr))/(2*ar)); else if(br!=0) JOptionPane.showMessageDialog(this, "x1="+-cr/br); else if(cr!=0) JOptionPane.showMessageDialog(this, "NU are solutii"); else JOptionPane.showMessageDialog(this, "Infinitate de solutii");

314 314 Manual de Informatică pentru clasa a XII-a public class baza { public static void main(string args[]) { Fer fp=new Fer("Ecuatia de gradul 2"); La baza programării vizuale stă noţiunea de fereastră. Fereastra va conţine mai multe componente vizuale cum ar fi edit-uri, butoane, imagini, etc. Asupra lor utilizatorul poate acţioana cu mouse-ul sau prin intermediul tastaturii. În programul nostru, fereastra iniţială afişează trei etichete a=0, b=0, c=0 şi trei edit-uri care permit introducerea coeficienţilor a, b, c. Unele componente trebuie să răspundă unor evenimente. Un exemplu de eveniment este, executarea unui clic cu mouse-ul asupra unei componente. În programul nostru, executarea unui clic asupra butonului Rezultat lansează o metodă, numită actionperformed, care validează datele de intrare (verifică corectitudinea lor). În caz că acestea sunt valide (corecte), calculează rădăcinile ecuaţiei, altfel afişează mesaje de informare. Afişarea mesajelor de eroare şi a rezultatelor se face cu ajutorul unor cutii de dialog de informare. O fereastră şi, în general, orice componentă este un obiect al unei clase. Pentru a putea realiza un program care utilizează programarea vizuală, trebuie să putem răspunde întrebărilor următoare: 1. Cum putem stabili caracteristicile ferestrei? 2. Care este mecanismul prin care unei ferestre i se ataşează alte componente? 3. Care este mecanismul prin care componentele răspund evenimentelor? 4. Cum se stabileşte modul în care arată o componentă? 5. Cum putem scrie un program care să ruleze independent de rezoluţia monitorului? 6. Care este mecanismul prin care poziţionăm diversele componente în cadrul ferestrei? La toate aceste întrebări vom răspunde în acest paragraf! Prima fereastră O fereastră este un obiect al clasei JFrame. Clasa JFrame este reţinută în pachetul javax.swing. Exemplul 8.2. În continuare, puteţi observa un program care afişează o fereastră: Figura 8.2. Exemplu de fereastră

315 Capitolul 8. Programare vizuală 315 import javax.swing.*; public class pv { public static void main(string args[]) { JFrame fer=new JFrame("Prima mea fereastra"); fer.setsize(200,300); fer.setlocation(300,400); fer.setdefaultcloseoperation(jframe.exit_on_close); fer.setvisible(true); Să observăm că fereastra conţine meniul implicit, poate fi maximizată, minimizată (adusă pe bara de task-uri), dar poate fi şi închisă. Din analiza programului, deducem câteva metode pe care le are clasa JFrame: JFrame() - constructor. Dacă o fereastră este creată printr-un astfel de constructor ea apare fără titlu. JFrame(String titlu) - constructor. Construieşte o fereastră care afişează un anumit titlu (în exemplu, Prima mea fereastra). void setsize(int width, int height) - stabileşte lăţimea şi înălţimea ferestrei. void setlocation (int x, int y) - stabileşte poziţia unde va fi afişat colţul din stânga sus al ferestrei (şi implicit poziţia ferestrei), în raport cu colţul din stânga sus al ecranului. Parametrul x precizează distanţa pe orizontală a colţului ferestrei, iar y distanţa pe verticală a acestuia (ambele sunt date în pixeli). void setdefaultcloseoperation(int a) - stabileşte ce se întâmplă atunci când se închide fereastra (s-a păstrat acel buton x). Parametrii sunt constante de tip întreg ale clasei. Cea mai importantă constantă este EXIT_ON_CLOSE şi prin ea, se cere închiderea ferestrei şi încheierea executării programului. void setresizable(boolean ac) - dacă parametrul este false nu se pot modifica dimensiunile ferestrei. setvisible(boolean x) - stabileşte dacă fereastra este vizibilă (apare pe ecran) sau nu (deşi există, nu este afişată). În programul care rezolvă ecuaţia de gradul de 2, fereastra este un obiect al clasei Fer. Analizaţi cum am descris modul în care trebuie să arate fereastra.

316 316 Manual de Informatică pentru clasa a XII-a Mecanismul prin care se ataşează componente ferestrei. Clasa Container Foarte important! Pentru ca unei ferestre (obiect de tip JFrame) să i se poată ataşa alte componente (cum ar fi butoanele, liste, etc. care sunt obiecte de alte tipuri), este necesar ca aceasta să conţină o referinţă către o structură specială, care la rândul ei va reţine referinţe către obiectele (componentele) care sunt ataşate ferestrei. Structura care reţine referinţele către obiectele care se află pe fereastră este un obiect al clasei Container. Alăturat putem observa ierarhia claselor din care a rezultat clasa JFrame. Prin urmare, un obiect de tip JFrame sau dintr-o subclasă a lui JFrame conţine datele membru şi metodele clasei Container. Object Component Container Window java.awt.frame javax.swing.jframe Accesul la container-ul unei ferestre se face utilizând o metodă a clasei JFrame, numită getcontentpane(). Container getcontentpane() - returnează o referinţă către container-ul ferestrei. Pornind de la această referinţă, putem realiza două lucruri: 1. Putem adăuga ferestrei componentele dorite. Pentru aceasta se foloseşte metoda add() a clasei Container: Component add(component comp) - adaugă o componentă ferestrei. Important: toate componentele sunt derivate din clasa Component. Prin urmare, parametrul comp poate reţine referinţe către componente de orice tip. 2. Putem spune cum să fie aranjate în fereastră componentele adăugate. Important: Mecanismul din Java care rezolvă această problemă presupune existenţa unor aşa numiţi gestionari de poziţionare. Gestionarii de poziţionare sunt obiecte ale unor clase specifice. Ei aranjează automat componentele unui container. Pentru a ataşa unui container un gestionar de poziţionare, se utilizează metoda clasei Container numită setlayout(): void setlayout(layoutmanager gest) - ataşează unui container un gestionar de poziţionare. LayoutManager - este o interfaţă. Toţi gestionarii de poziţionare pe care îi vom studia într-un paragraf separat au rezultat ca urmare a implementării acestei interfeţe. Aceasta înseamnă că metoda poate fi utilizată pentru ataşarea oricărui gestionar de poziţionare. Observaţie! Pentru început, vom folosi gestionarul de poziţionare FlowLayout, care are un constructor fără parametri. Pe scurt, acesta aşează componentele în fereastră, pe linie, una după alta. Dacă o linie s-a umplut, se trece la linia următoare.

317 Capitolul 8. Programare vizuală 317 Clasa Container se găseşte în pachetul java.awt. Exemplul 8.3. Programul care urmează afişează două butoane! Apăsarea butoanelor nu are nici un efect. import java.awt.*; import javax.swing.*; class Fer extends JFrame { public Fer(String titlu) { Figura 8.3. Fereastră super(titlu); cu două butoane setsize(200,100); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); JButton A=new JButton("Buton 1"); x.add(a); JButton B=new JButton("Buton 2"); x.add(b); setvisible(true); public class pv { public static void main(string args[]) { Fer fp=new Fer("Doua butoane"); Observaţie! Butoanele ataşate sunt componente de tip JButton, care au un constructor de tip JButton(String s). Şirul s va apărea pe suprafaţa butonului. Exerciţiu! Analizaţi, în programul care rezolvă ecuaţia de gradul 2, modul în care am ataşat ferestrei principale componentele vizuale (etichetele, edit-urile şi butonul) Un mecanism prin care butoanele răspund evenimentului de apăsare Până în prezent ştim să construim o fereastră, ştim să-i ataşăm unul sau mai multe butoane, dar nu ştim să facem de aşa manieră încât la apăsarea butonului (click pe suprafaţa lui) să aibă loc o anumită acţiune. Este exact ce ne propunem să prezentăm în acest paragraf. În Java există o interfaţă numită ActionListener, ascultătorul de evenimente de tip ActionEvent. Un exemplu de eveniment de tip ActionEvent este apăsarea unui buton. Interfaţa conţine antetul unei singure metode: actionperformed(actionevent e). Pentru ca o componentă să poată răspunde la un eveniment de tipul ActionEvent, trebuie să implementeze clasa ActionListener. Aceasta înseamnă că: 1. Clasa care include componenta (fereastra) trebuie să conţină clauza implements ActionListener.

318 318 Manual de Informatică pentru clasa a XII-a 2. Să fie implementată metoda actionperformed(). Această metodă se va executa automat atunci când este apăsat butonul. Prin urmare, implementarea ei va scrie codul necesar acţiunii dorite. ActionEvent este o clasă care conţine metoda: String getactioncommand() - returnează şirul de caractere asociat componentei care a transmis evenimentul. Metoda poate fi utilizată pentru a depista componenta care a transmis evenimentul. Exemplul 8.4. Extindem programul prezentat în paragraful anterior. Când se apasă un buton, în fereastra CMD va apărea şirul reţinut de butonul apăsat: import java.awt.*; import java.awt.event.*; import javax.swing.*; class Fer extends JFrame implements ActionListener { public Fer(String titlu) { super(titlu); setsize(200,100); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); JButton A=new JButton("Buton 1"); x.add(a); JButton B=new JButton("Buton 2"); x.add(b); A.addActionListener(this); B.addActionListener(this); setvisible(true); public void actionperformed (ActionEvent e) { if( e.getactioncommand().compareto("buton 1")==0) System.out.println("Ai apasat Buton 1"); else System.out.println("Ai apasat Buton 2"); public class pv { public static void main(string args[]) { Fer fp=new Fer("Doua butoane"); Exerciţiu! Analizaţi, în programul care rezolvă ecuaţia de gradul 2, modul în care s-a implementat metoda actionperformed(). Veţi observa modul de citire a coeficienţilor. Aceştia sunt introduşi sub forma unor şiruri de caractere, se preiau din edit-uri şi se încearcă convertirea lor către un tip real. În cazul în care conversia reuşeşte, se presupune că au fost introduşi corect. Altfel, se va da mesaj de eroare. Atenţie! Validarea datelor de intrare este esenţială.

319 Capitolul 8. Programare vizuală Componente: elemente de design Prin componentă vom înţelege un obiect care are o reprezentare grafică. Exemple de componente: butoane, liste, edit-uri, etichete (am preferat denumirea lor din cursul de Tehnologia Informaţiei). Dacă o componentă este obiect, înseamnă că o componentă rezultă în urma instanţierii unei clase. Fiecare tip de componentă pe care o vom studia rezultă în urma instanţierii unei clase specifice ei. De exemplu, un buton rezultă în urma instanţierii clasei JButton, o etichetă rezultă în urma instanţierii clasei JLabel, un edit rezultă în urma instanţierii clasei JtextField, ş.a.m.d. Important! Clasele tuturor componentelor enumerate mai sus sunt subclase ale clasei JComponent. Aceasta înseamnă că putem folosi metodele clasei JComponent pentru orice componentă. Observaţie! Clasa JComponent este descendentă, dar nu direct, a unei alte clase numită Component. Atunci când prezentăm unele metode ale clasei JComponent, care sunt moştenite de la clasa Component nu vom mai face referire la acest lucru, ci le vom trata ca făcând parte din clasa JComponent. În continuare, prezentăm câteva metode ale clasei JComponent: void setbackground(color c) - metoda stabileşte culoarea de fond a componentei. Să observăm că parametrul ei este de tip Color. void setforeground(color c) - setează culoarea caracterelor (în cazul în care componenta conţine un text). Clasa Color conţine anumite constante care indică culoarea şi mai multe metode prin care se poate stabili o culoare. Exemple de constante de culoare: black, red, white, yellow, etc. De asemenea, clasa conţine constructorul Color(float r, float g, float b) prin care se poate forma o culoare în sistemul RGB(Red, Green, Blue), sistem studiat la tehnologia informaţiei. setfont(font f) setează font-ul cu care se scrie, stilul său şi mărimea. Parametrul este un obiect al clasei Font. Clasa Font are, printre altele, constructorul: unde: Font(String nume, int stil, int marime). nume - este numele font-ului; stil - stilul. Valorile uzuale sunt: Font.ITALIC (italic), Font.BOLD (bold), Font.PLAIN (clasic). Se pot folosi şi sume, cum ar fi pentru italic şi bold: Font.ITALIC+Font.BOLD. marime - mărimea font-ului.

320 320 Manual de Informatică pentru clasa a XII-a Exemplul 8.5. Butonul ( Apasa ) va avea fondul de culoare roşie, va conţine text scris cu verde, se va utiliza font-ul Arial, de mărime 20 şi este scris înclinat şi îngroşat (italic şi bold). Să observăm faptul că dimensiunea butonului este stabilită automat, în funcţie de mărimea textului pe care îl conţine. JButton A=new JButton("Apasa"); A.setBackground(Color.red); A.setFont(new Font("Arial",Font.ITALIC+Font.BOLD, 20)); A.setForeground(Color.GREEN); void settooltiptext(string text); - metoda setează un şir de caractere care va fi afişat atunci când cursorul mouse-ului staţionează asupra componentei. Şirul are rolul unui mesaj lămuritor despre funcţia respectivei componente. Exemplul 8.6. Priviţi liniile de cod de mai jos: JButton B=new JButton("Buton 2"); B.setToolTipText("Eu sunt butonul 2"); Figura 8.4. Mesaj lămuritor void setenabled(boolean v) - Face ca o componentă să fie activată (v reţine true) sau nu (v reţine false). O componentă dezactivată nu mai răspunde comenzilor şi are un aspect specific prin care utilizatorul este anunţat că aceasta este dezactivată. Exemplul 8.7. În imaginea alăturată butonul 1 este dezactivat şi butonul 2 este activat. Figura 8.5. Exemplu de buton dezactivat void setvisible(boolean v) - dacă parametrul reţine true, componenta este vizibilă, altfel ea este invizibilă Independenţa programelor de rezoluţie Se ştie că programele trebuie să ruleze independent de rezoluţia monitorului. O clasă care face posibil acest lucru este clasa ToolKit. În acest sens, cele mai importante metode ale ei sunt: public static Toolkit getdefaulttoolkit() - returnează un obiect Toolkit (conţine date despre setările curente); Dimension getscreensize() - returnează o referinţă către un obiect de tip Dimension care conţine lungimea (width) şi înălţimea (height) în pixeli a ecranului. Exemplul 8.8. Programul următor creează o fereastră care iniţial, ocupă întreg ecranul:

321 Capitolul 8. Programare vizuală 321 import java.awt.*; import javax.swing.*; class Fer extends Jframe { public Fer(String titlu) { super(titlu); setdefaultcloseoperation(jframe.exit_on_close); Toolkit ec=toolkit.getdefaulttoolkit(); Dimension dim = ec.getscreensize(); int i = dim.height; int l = dim.width; setsize(dim.width, dim.height); setvisible(true); public class pv { public static void main(string args[]) { Fer fp=new Fer("Fereastra pe intreg ecranul"); Poziţionarea componentelor Pentru a aşeza componentele în poziţia dorită, putem să utilizăm poziţionarea absolută (dar este nerecomandată pentru că programul trebuie să ruleze corect pe o diversitate de platforme) sau unul dintre gestionarii de poziţionare existenţi. Cum facem acest lucru? Veţi vedea în paragraful acesta! Oricum, trebuie să ştiţi că mecanismul este puţin mai complicat decât cel cu care aţi fost obişnuiţi în ipoteza că aţi studiat programarea vizuală (de exemplu, în Borland Delphi sau Borland Builder). Nu uitaţi! Programele Java trebuie să funcţioneze pe orice platformă! Poziţionarea absolută Pentru a utiliza poziţionarea absolută a componentelor trebuie să lucrăm în absenţa unui gestionar de poziţionare, iar coordonatele sunt date în pixeli. Pentru aceasta trebuie să cunoaştem următoarele: 1. Secvenţa de mai jos se utilizează pentru a lucra în absenţa unui gestionar de poziţionare: Container x=getcontentpane(); x.setlayout(null); 2. În poziţionarea absolută componentele trebuie dimensionate şi poziţionate, altfel nu sunt vizibile. Testaţi...

322 322 Manual de Informatică pentru clasa a XII-a Pentru dimensionarea componentelor, se utilizează următoarele metode ale clasei JComponent: setbounds(int x, int y, int lat, int inal); metoda poziţionează şi dimensionează componenta. Parametrii x şi y dau poziţia componentei raportată la colţul din stânga-sus al componentei care o găzduieşte, iar lat şi lung o dimensionează. Metoda de mai sus poate fi înlocuită cu următoarele două metode: setlocation(int x, int y) - metodă care are rolul de poziţionare; setsize(int lat, int lung) - metodă care are rolul de dimensionare. Exemplul 8.9. Utilizăm poziţionarea absolută şi aşezăm un buton în fereastră: Container x=getcontentpane(); x.setlayout(null); JButton A=new JButton ("Exemplu"); A.setBounds(10,10, 100, 40); Gestionarul de poziţionare FlowLayout Componentele sunt afişate pe linii, în ordinea în care au fost declarate. Pe fiecare linie ele sunt afişate de la stânga la dreapta (atâtea câte încap). Exemplul În continuare, puteţi observa cum a fost creată fereastra alăturată: class Fer extends JFrame { Figura 8.6. Exemplu de public Fer(String titlu) poziţionare a componentelor { super(titlu); setdefaultcloseoperation(jframe.exit_on_close); setsize(300,150); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); JButton A=new JButton("Buton 1"); x.add(a); JButton B=new JButton("Buton 2"); x.add(b); JButton C=new JButton("Buton 3"); x.add(c); JButton D=new JButton("Buton 4"); x.add(d); JButton E=new JButton("Buton 5"); x.add(e); JButton F=new JButton("Buton 6"); x.add(f); JButton G=new JButton("Buton 7"); x.add(g); setvisible(true);

323 Capitolul 8. Programare vizuală 323 Clasa FlowLayout conţine constante de aliniere pe linie, din care mai importante sunt: CENTER, aliniere în centru, opţiune implicită, LEFT, la stânga şi RIGHT, la dreapta. Clasa FlowLayout este înzestrată cu 3 constructori: a) FlowLayout() - distanţa între rânduri este de 5 unităţi, distanţa pe orizontală între componente este de 5 unităţi şi componentele sunt aliniate pe linie la centru (CENTER). b) FlowLayout(int aliniere) - se cere explicit ca alinierea să fie într-un anumit fel (CENTER, RIGHT, LEFT, acestea sunt constante ale clasei FlowLayout). c) FlowLayout(int aliniere,int dist_oriz,int dist_vert) - se specifică şi distanţa pe orizontală între componente şi distanţa pe verticală dintre ele. Exemplul Priviţi exemplele de utilizare a constructorilor de mai jos: FlowLayout (FlowLayout.LEFT) FlowLayout (FlowLayout.RIGHT,15,8) Figura 8.7. Exemple de utilizare a constructorilor De reţinut! 1. Dimensionarea componentelor şi poziţionarea lor este făcută automat de către gestionar. 2. Metodele utilizate în poziţionarea absolută pentru poziţionarea şi dimensionarea componentelor (setbounds(), setlocation(), setsize()) deşi sunt acceptate la compilare, nu au nici un efect. 3. Există totuşi o metodă care dimensionează componentele şi este acceptată de gestionarul FlowLayout. Ea aparţine clasei JComponent: setpreferredsize(dimension dim). Clasa Dimension are constructorul Dimension(int lat, int inalt) prin care se specifică lăţimea, respectiv înălţimea componentei. Exemplul Prin utilizarea gestionarului FlowLayout se adaugă unei ferestre două butoane, primul de dimensiune stabilită, al doilea de dimensiune implicită:

324 324 Manual de Informatică pentru clasa a XII-a Container x=getcontentpane(); x.setlayout(new FlowLayout()); JButton A=new JButton ("Buton 1"); A.setPreferredSize(new Dimension(100,100)); JButton B=new JButton ("Buton 2"); x.add(a); x.add(b); Figura 8.8. Exemplu de fereastră cu două butoane Gestionarul de poziţionare GridLayout Clasa GridLayout aranjează componentele într-o altă logică. Ideea de bază este aceea că se împarte suprafaţa ferestrei în mai multe dreptunghiuri de suprafaţă egală şi în fiecare dreptunghi astfel obţinut se aşează o componentă care este de cele mai multe ori extinsă ca suprafaţă, astfel încât să ocupe întreaga suprafaţă a dreptunghiului care îi revine. Pentru a înţelege modul de aranjare a componentelor vom prezenta pe scurt cei trei constructori ai clasei: a) GridLayout() - dacă avem n componente care trebuie aşezate, suprafaţa ferestrei este împărţită într-o singură linie şi n coloane. Fiecare componentă este aşezată într-un dreptunghi, iar componentele sunt fără spaţiu între ele. b) GridLayout(int nr_linii, int nr_coloane) - suprafaţa este împărţită în nr_linii nr_coloane dreptunghiuri. Fiecare dreptunghi reţine o componentă (vezi figura de mai jos). Figura 8.9. GridLayout(3,3) c) GridLayout(int nr_linii, int nr_col, int sp_o, int sp_v) - se procedează ca anterior, numai că se trec şi spaţiile pe orizontală şi pe verticală între dreptunghiurile generate. Figura GridLayout(3,3,5,8) Pentru GridLayout, metoda setpreferredsize() nu are niciun efect.

325 Capitolul 8. Programare vizuală Gestionarul de poziţionare BorderLayout Clasa BorderLayout împarte suprafaţa ferestrei în 5 părţi: nord (NORTH), sud (SOUTH), est (EAST), vest (WEST) şi centru (CENTER). În fiecare parte se poate aşeza o componentă. Exemplul Mai jos puteţi observa cum am obţinut aşezarea componentelor ca în fereastra din figura alăturată: x.setlayout(new BorderLayout ()); JButton A=new JButton("Buton 1"); x.add(a,borderlayout.south); JButton B=new JButton("Buton 2"); x.add(b,borderlayout.north); JButton C=new JButton("Buton 3"); x.add(c,borderlayout.west); JButton D=new JButton("Buton 4"); x.add(d,borderlayout.east); JButton E=new JButton("Buton 5"); x.add(e,borderlayout.center); Figura Exemplu de aşezare a componentelor De reţinut! 1. Pentru adăugarea unei componente container-ului se foloseşte metoda add cu 2 parametri, al doilea fiind cel care precizează poziţia în care este adăugată componenta. Vezi mai sus! 2. Componentele sunt extinse pentru a ocupa întreaga suprafaţă alocată. Vedeţi figura de mai sus. 3. Dacă lipseşte componenta din nord, sau cea din sud, spaţiul este ocupat de linia din centru. 4. Dacă lipseşte componenta din centru, spaţiul este lăsat liber. Dacă lipseşte componenta din est, sau cea din vest, spaţiul este ocupat de componenta din centru. 5. Metoda setpreferredsize() are efect parţial. Astfel rezultă: dacă este aplicată unei componente din nord sau din sud, se ia în considerare numai înălţimea transmisă de metodă. Dacă este aplicată unei componente din est, vest, sau centru se ia în considerare numai lăţimea componentei.

326 326 Manual de Informatică pentru clasa a XII-a 8.2. Studiul principalelor componente Componente de tip JButton Cu ajutorul componentelor de acest tip se creează butoane. În general, prin apăsarea unui buton se dau anumite comenzi programului. Vom prezenta cele mai importante metode (constructori): JButton() - creează un buton fără text, fără imagine asociată. JButton(String text) - creează un buton care afişează un text. JButton(Icon icon) - creează un buton care reţine o imagine de mici dimensiuni. Exemplul Liniile de mai jos formează butonul alăturat: Icon icon = new ImageIcon("om.gif"); JButton A=new JButton(icon); Figura Exemplu de buton JButton(String text,icon icon) - creează un buton cu text şi imagine. Exemplul Liniile de mai jos formează butonul alăturat: Icon icon = new ImageIcon("om.gif"); JButton A=new JButton( "Java...",icon); Figura Exemplu de buton cu text şi imagine metoda setverticaltextposition(constanta) setează poziţia pe verticală a textului în raport cu imaginea: deasupra (JButton.TOP), dedesubt (JButton.BOTTOM), în centru (JButton.CENTER). metoda sethorizontaltextposition(constanta) setează poziţia pe orizontală a textului în raport cu imaginea: stânga (JButton.LEFT), dreapta (JButton.RIGHT), în centru (JButton.CENTER). Exemplul Liniile de mai jos formează butonul alăturat: Icon icon = new ImageIcon("om.gif"); JButton A=new JButton( "Java...",icon); A.setVerticalTextPosition(JButton.TOP); A.setHorizontalTextPosition(JButton.CENTER); Mărimea imaginii determină mărimea butonului! Figura Exemplu

327 Capitolul 8. Programare vizuală Componente de tip JLabel Componentele de acest tip se utilizează pentru a afişa texte şi imagini, cu rol lămuritor. Clasa este înzestrată cu următoarele metode mai importante: JLabel(String S) - se utilizează pentru a afişa un şir de caractere. Exemplul Dacă constructorul ferestrei conţine secvenţa de mai jos, atunci pe fereastră apare ce se vede în figura alăturată: Container x=getcontentpane(); x.setlayout(new BorderLayout ()); JLabel A=new JLabel ("Un text"); x.add(a); Figura Exemplu JLabel(Icon image) - se utilizează pentru a afişa o imagine. Exemplul La fel ca mai sus, numai că pe fereastră se afişează o imagine: Container x=getcontentpane(); x.setlayout(new BorderLayout ()); Icon icon = new ImageIcon("idee.gif"); JLabel A=new JLabel (icon); x.add(a); JLabel(String text, Icon icon, int horizontalalignment) afişează o imagine şi un text. Ansamblul (imagine + text) se aliniază pe orizontală, conform ultimului parametru (CENTER, LEFT, RIGHT). setverticaltextposition(c), sethorizontaltextposition(c) pot fi folosite şi la JLabel la fel ca la Jbutton: Exemplul Se va afişa ce se vede alăturat: Container x=getcontentpane(); x.setlayout(new GridLayout()); Icon icon = new ImageIcon("idee.gif"); JLabel A=new JLabel ("Asta era!!!",icon,jlabel.center); A.setHorizontalTextPosition(Jlabel.CENTER); A.setVerticalTextPosition(JLabel.TOP); x.add(a); Figura Exemplu Figura Exemplu Componente de tip JPanel Componentele JPanel (paneluri) sunt de tip container, adică au rolul de a conţine pe suprafaţa lor alte componente, având în general un rol de grupare, dar şi unul de poziţionare a componentelor. Clasa este înzestrată cu următoarele metode:

328 328 Manual de Informatică pentru clasa a XII-a JPanel() - constructor, obiectul rezultat are gestionarul de poziţionare FlowLayout(). JPanel(LayoutManager layout) - constructor, obiectul rezultat are gestionarul de poziţionare transmis ca parametru. setlayout(layoutmanager layout); - setează gestionarul de poziţionare. add(component c) - adaugă o componentă obiectului. Exemplul Fereastra programului următor conţine o componentă de tip JPanel. Pe ea sunt ataşate 3 butoane. La apăsarea unui buton, componenta de tip JPanel va avea culoarea afişată de buton. import java.awt.*; import java.awt.event.*; import javax.swing.*; class Fer extends JFrame implements ActionListener { JPanel panel; public Fer(String titlu) { super(titlu); setsize(300,300); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); panel=new JPanel(); JButton A=new JButton("Rosu"); panel.add(a); A.addActionListener(this); JButton B=new JButton("Galben"); panel.add(b); B.addActionListener(this); JButton C=new JButton("Albastru"); panel.add(c); C.addActionListener(this); x.add(panel); setvisible(true); public void actionperformed (ActionEvent e) { String culoare=e.getactioncommand(); if (culoare.compareto("rosu")==0) panel.setbackground(color.red); else if (culoare.compareto("galben")==0) panel.setbackground(color.yellow); else panel.setbackground(color.blue); public class pv { public static void main(string args[]) { Fer fp=new Fer("Fereastra cu panel"); Figura Fereastra programului

329 Capitolul 8. Programare vizuală Componente de tip JTextField Componentele de tip JTextField (edit-uri) sunt utilizate pentru ca utilizatorul să introducă sau să afişeze şiruri de caractere de la tastatură, şiruri pe care programul urmează să le prelucreze. Cele mai importante metode ale acestui obiect sunt: JTextField(int nr) - creează un edit vid, dar care are o lăţime suficientă pentru a vizualiza simultan nr caractere. Şirul de caractere introdus poate avea orice lungime. Figura Un edit vid JTextField(String s) - creează un edit care iniţial afişează un şir de caractere. Figura Un edit cu text iniţial JTextField(String S, int nr) - creează un edit care iniţial afişează un şir de caractere şi care are o lăţime suficientă pentru a afişa simultan un număr de nr caractere. String gettext() - returnează şirul de caractere reţinut de edit la un moment dat. void settext(string s) - are rolul de a determina ca edit-ul să conţină şirul de caractere specificat. Exemplul Programul următor afişează fereastra din figura alăturată. Utilizatorul introduce un şir de caractere şi, la apăsarea butonului se afişează, în fereastra CMD, textul introdus de acesta. import java.awt.*; Figura Fereastra programului import java.awt.event.*; import javax.swing.*; class Fer extends JFrame implements ActionListener { JTextField txt; public Fer(String titlu) { super(titlu); setsize(300,200); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); JLabel et=new JLabel ("Numele dv:"); x.add(et); txt=new JTextField(15); x.add(txt); JButton but=new JButton("Ce-am introdus?"); x.add(but); but.addactionlistener(this); setvisible(true);

330 330 Manual de Informatică pentru clasa a XII-a public void actionperformed (ActionEvent e) { System.out.println(txt.getText()); public class pv { public static void main(string args[]) { Fer fp=new Fer("Exemplu de edit"); Componente de tip JComboBox Obiectele clasei JComboBox sunt aşa numitele liste, din care utilizatorul poate selecta o anumită opţiune (unică). Principalele metode ale clasei JComboBox sunt: JComboBox () constructor. void additem(object s) - adaugă listei o opţiune. Cum clasa Object este la baza ierarhiei de clase Java, parametrul efectiv poate fi o referinţă către orice obiect, inclusiv către tipul des utilizat String. Object getselecteditem() returnează şirul de caractere corespunzător opţiunii selectate. int getitemcount() - returnează numărul de opţiuni. int getselectedindex() - returnează indexul opţiunii selectate. Object getitemat(int ind) - returnează obiectul reţinut de item-ul de indice ind (dacă trebuie să obţinem un obiect de tip String, atunci convertiţi către String prin operatorul de conversie). Exemplul Programul următor afişează o listă. Selectaţi din listă o opţiune şi apăsaţi butonul. În fereastra CMD va fi afişată opţiunea selectată: import java.awt.*; import java.awt.event.*; import javax.swing.*; Figura Fereastra programului class Fer extends JFrame implements ActionListener { JComboBox lista; public Fer(String titlu) { super(titlu); setsize(300,200); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); JLabel et=new JLabel ("Selectati materia preferata:"); x.add(et); lista=new JComboBox(); lista.additem("matematica");

331 Capitolul 8. Programare vizuală 331 lista.additem("informatica"); lista.additem("engleza"); lista.additem("alta materie"); x.add(lista); JButton but=new JButton("Ce-am selectat?"); x.add(but); but.addactionlistener(this); setvisible(true); public void actionperformed (ActionEvent e) { System.out.println(lista.getSelectedItem()); public class pv { public static void main(string args[]) { Fer fp=new Fer("Exemplu de lista"); Componente de tip JCheckBox şi JRadioButton. Gruparea lor Obiectele clasei JCheckBox sunt aşa-numitele butoane de validare. Fereastra poate conţine unul sau mai multe astfel de butoane. Principalele metode ale acestei clase sunt: JCheckBox(String s) - creează un buton de validare care conţine şirul de caractere transmis ca parametru. JCheckBox(String s, boolean v) - creează un buton de validare care conţine şirul de caractere transmis ca parametru şi care este marcat sau nu în funcţie de valoarea pe care o reţine parametrul v, respectiv true sau false. JCheckBox(String s, Icon f) - creează un buton de validare care conţine şirul de caractere transmis ca parametru şi o imagine. boolean isselected() - returnează true dacă butonul a fost selectat şi false în caz contrar. String gettext() - returnează şirul de caractere reţinut de buton. Exemplul Programul următor afişează mai multe butoane de validare, din care unul (cel care afişează Informatica ) este selectat de la început! La apăsarea butonului Ce-am selectat? este afişată selecţia făcută. import java.awt.*; import java.awt.event.*; import javax.swing.*; Figura Fereastra programului

332 332 Manual de Informatică pentru clasa a XII-a class Fer extends JFrame implements ActionListener { JCheckBox b1,b2,b3,b4; public Fer(String titlu) { super(titlu); setsize(150,200); Container x=getcontentpane(); x.setlayout(new FlowLayout (FlowLayout.LEFT)); setdefaultcloseoperation(jframe.exit_on_close); JLabel et=new JLabel ("Selectati"); x.add(et); b1=new JCheckBox("Matematica");x.add(b1); b2=new JCheckBox("Informatica",true);x.add(b2); b3=new JCheckBox("Engleza"); x.add(b3); b4=new JCheckBox("Biologie");x.add(b4); JButton but=new JButton("Ce-am selectat?"); x.add(but); but.addactionlistener(this); setvisible(true); public void actionperformed (ActionEvent e) { if (b1.isselected()) System.out.println(b1.getText()); if (b2.isselected()) System.out.println(b2.getText()); if (b3.isselected()) System.out.println(b3.getText()); if (b4.isselected()) System.out.println(b4.getText()); public class pv { public static void main(string args[]) { Fer fp=new Fer("Validare"); Obiectele de tip JRadioButton sunt asemănătoare cu cele de tip JCheckBox, negrupate au acelaşi comportament, numai că arată ca nişte butoane radio. Butoanele pot fi grupate, adică pot fi toate tratate ca un întreg. Un exemplu convingător este dat de necesitatea grupării butoanelor radio (unde, la un moment dat, numai un singur buton poate fi selectat). Pentru a grupa butoanele se foloseşte un obiect al clasei ButtonGroup. Cele mai importante metode ale acestei clase sunt: ButtonGroup() - constructor; void add(abstractbutton b) - adaugă un buton grupului (clasa AbstractButton este superclasă pentru JButton, JRadioButton, JCheckBox). Enumeration getelements(); - returnează un pointer la grupul de butoane. int getbuttoncount() - returnează numărul de butoane din grup.

333 Capitolul 8. Programare vizuală 333 Exemplul Priviţi programul de mai jos: import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; class Fer extends JFrame implements ActionListener { ButtonGroup grup; public Fer(String titlu) { super(titlu); setsize(150,200); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout (FlowLayout.LEFT)); JLabel et=new JLabel ("Selectati"); x.add(et); JRadioButton b1=new JRadioButton("Matematica");x.add(b1); JRadioButton b2=new JRadioButton("Informatica",true); x.add(b2); JRadioButton b3=new JRadioButton("Engleza"); x.add(b3); JRadioButton b4=new JRadioButton("Biologie");x.add(b4); JButton but=new JButton("Ce-am selectat?"); x.add(but); but.addactionlistener(this); grup = new ButtonGroup(); grup.add(b1);grup.add(b2); grup.add(b3);grup.add(b4); setvisible(true); public void actionperformed (ActionEvent e) { Enumeration en=grup.getelements(); while (en.hasmoreelements()) { JRadioButton b=(jradiobutton)en.nextelement(); if(b.isselected()) System.out.println(b.getText()); public class pv { public static void main(string args[]) { Fer fp=new Fer("Validare"); Meniuri În Java, meniurile se construiesc prin utilizarea obiectelor mai multor clase. A) Clasa JMenuBar - obiectele acestei clase se utilizează pentru a obţine meniuri clasice, aflate în partea de sus a ferestrei. Cele mai importante metode ale acestei clase sunt: JMenuBar() - constructor; add(jmenu) - adaugă meniului componente de tip JMenu, vedeţi în continuare.

334 334 Manual de Informatică pentru clasa a XII-a B) Clasa JMenu - obiectele acestei clase au rolul de a înscrie în meniu anumite opţiuni, care la rândul lor pot conţine alte opţiuni. Cele mai importante metode ale acestei clase sunt: JMenu(String s) - constructor. Obiectul va afişa şirul s. add(jmenuitem meniu) - adaugă o componentă de tip JMenuItem (vedeţi mai jos clasa JMenuItem;). add (Component c) - adaugă o altă componentă (de un tip derivat din tipul Component). C) Clasa JMenuItem - o astfel de componentă care apare în meniu, arată ca o opţiune şi are rolul unui buton, adică selectată, conduce la o anumită acţiune. Cele mai importante metode ale acestei clase sunt: JMenuItem(String s) - constructor, opţiunea afişează şirul s; JMenuItem(Icon ic) - constructor, opţiunea afişează o mică imagine; JMenuItem(String s, Icon ic) - constructor, opţiunea afişează un şir de caractere şi o mică imagine. Exemplul Programul următor construieşte un meniu clasic. Pentru fiecare opţiune selectată, se afişează în fereastra CMD şirul generat de opţiune. import java.awt.*; import java.awt.event.*; import javax.swing.*; Figura class Fer extends JFrame implements ActionListener { TextArea t; public Fer(String titlu) { super(titlu); setsize(400,400); setdefaultcloseoperation(jframe.exit_on_close); //Bara meniu JMenuBar bara = new JMenuBar(); // Creez meniul principal JMenu meniu1 = new JMenu("Operatii 1"); bara.add(meniu1); JMenu meniu2 = new JMenu("Operatii 2"); bara.add(meniu2); // adaug itemi pentru fiecare optiune din meniul principal JMenuItem item11 = new JMenuItem("OP 11"); item11.addactionlistener(this); meniu1.add(item11); JMenuItem item12 = new JMenuItem("OP 12"); item12.addactionlistener(this); meniu1.add(item12); JMenuItem item21 = new JMenuItem("OP 21");

335 Capitolul 8. Programare vizuală 335 item21.addactionlistener(this); meniu2.add(item21); setjmenubar(bara); Container x=getcontentpane(); x.setlayout(new GridLayout ()); setvisible(true); public void actionperformed (ActionEvent e) { System.out.println(e.getActionCommand()); public class pv { public static void main(string args[]) { Fer fp=new Fer("Fereastra cu meniu"); Observaţie! Metoda clasei JFrame setjmenubar(jmenubar b) are rolul de a ataşa bara de meniu ferestrei. Meniurile pot conţine şi submeniuri. Pentru aceasta, unei componente de tip JMenu i se adaugă, pe lângă alte componente de tip JMenuItem, o altă componentă, tot de tip JMenu. Acesteia din urmă i se adaugă componente de tip JMenuItem. Exemplul Pentru a obţine meniul alăturat, adăugaţi programului de mai sus secvenţa următoare: //submeniuri JMenu altele = new JMenu("Altele"); meniu1.add(altele); JMenuItem item131 = new JMenuItem("OP 131"); altele.add(item131); item131.addactionlistener(this); JMenuItem item132 = new JMenuItem("OP 132"); altele.add(item132); item132.addactionlistener(this); Figura Exemplu de meniu Evident, procedeul se poate repeta pentru a obţine oricâte submeniuri doriţi. Acceleratori. În multe aplicaţii, anumite opţiuni din meniuri sunt înzestrate cu acceleratori (shortcut-uri de meniu) prin care o anumită comandă se poate obţine fie din meniu, fie dintr-o combinaţie de taste. Şi în Java se pot crea acceleratori şi acest mecanism este prezentat în continuare. Metoda: void setaccelerator(keystroke keystroke) are rolul de a ataşa unui obiect de tip JMenuItem un accelerator, adică de a invoca acţiunea specifică acestuia atunci când utilizatorul a apăsat fie o tastă, fie o combinaţie de taste. În primul caz (o tastă), se foloseşte metoda: static KeyStroke getkeystroke(char keychar),

336 336 Manual de Informatică pentru clasa a XII-a iar în al doilea caz, metoda: static KeyStroke getkeystroke(int keycode, int modifiers) Cum obţinem parametrii pentru a doua metodă getkeystroke()? Primul parametru este o constantă a clasei KeyEvent. Iată câteva astfel de constante: static int VK_1 (tasta 1), static int VK_2 (tasta 2), static int VK_F1 (tasta F1), static int VK_V (tasta V), ş.a.m.d. Al doilea parametru este o constantă a clasei ActionEvent: SHIFT_MASK, (codul 1), CTRL_MASK (codul 2), META_MASK (codul 4), ALT_MASK (codul 8). Exemplul În primul program de la începutul paragrafului, pentru item21 dorim să avem un accelerator, adică să obţinem acelaşi efect prin apăsarea combinaţiei de taste ALT+2 ca şi în cazul în care operăm selecţia din meniu: JMenuItem item21 = new JMenuItem("OP 21"); item21.setaccelerator(keystroke.getkeystroke (KeyEvent.VK_2, ActionEvent.ALT_MASK)); item21.addactionlistener(this); Figura Exemplu de meniu În acest caz, dacă apăsăm ALT+2, obţinem acelaşi efect ca atunci când operăm selecţia din meniu. Dacă dorim să obţinem o combinaţie din trei taste, de exemplu CTRL+ALT+2, vom folosi (datorită codificării din ActionEvent): getkeystroke(keyevent.vk_2, ActionEvent.ALT_MASK + ActionEvent.CTRL_MASK)); Cutii (casete) de dialog predefinite Cutiile de dialog predefinite sunt extrem de utile pentru introducerea sau afişarea unor date. Pentru a putea folosi astfel de cutii, vom utiliza clasa JOptionPane care conţine mai multe metode statice care le afişează. Cutiile sunt predefinite, conţinând automat anumite componente (nu mai este necesar ca acestea să fie create de programator) Cutii de dialog de intrare Iată câteva metode prin care putem apela astfel de cutii: public static String showinputdialog(object mes) creează şi afişează în centrul ecranului o cutie de dialog care afişează mesajul transmis ca parametru. În cazul în care utilizatorul apasă Cancel, se returnează pointer-ul null, motiv pentru care trebuie tratată această excepţie.

337 Capitolul 8. Programare vizuală 337 Exemplul Priviţi secvenţa de mai jos: try { String intr = JOptionPane.showInputDialog("a="); if (intr.length()==0) System.out.println("Intr vida"); else System.out.println(intr); catch(nullpointerexception exc) { System.out.println("S-a apasat Cancel"); Figura Exemplu de cutie de dialog public static String showinputdialog(object mes, Object val) - la fel ca mai sus, numai că edit-ul memorează de la început valoarea transmisă de al doilea parametru (valoare iniţială). În exemplul de mai jos, valoarea iniţial afişată este 0 : String intr = JOptionPane.showInputDialog("a=","0"); public static String showinputdialog(component par, Object mes) - ca mai sus, numai că se afişează o cutie de dialog care are o componentă părinte. În exemplul următor, afişarea se face cu ajutorul clasei care descrie fereastra principală, deci părintele este this (acest obiect): String intr = JOptionPane.showInputDialog(this,"a="); public static String showinputdialog(component par, Object mes, Object val) - ca mai sus, numai că se afişează o cutie de dialog în care edit-ul reţine şi o valoare iniţială Cutii de dialog pentru afişarea mesajelor (de informare) Astfel de cutii de dialog se utilizează pentru a transmite utilizatorului anumite mesaje de eroare, sau rezultate. public static void showmessagedialog(component par, Object mes) - afişează o cutie de dialog cu un mesaj dorit. Exemplul Secvenţa de mai jos afişează ferestra alăturată: int a=125; JOptionPane.showMessageDialog(this, "a="+a); Figura Exemplu

338 338 Manual de Informatică pentru clasa a XII-a Cutii de dialog de confirmare O astfel de cutie de dialog afişează trei butoane: Yes, No şi Cancel. public static int showconfirmdialog(component par,object mes); - metoda returnează un întreg a cărui valoare este dată de butonul pe care-l apasă utilizatorul: 0 pentru Yes, 1 pentru No sau 2 pentru Cancel. Observaţie! De fapt, se returnează indicele butonului apăsat: Yes are 0 pentru că este primul buton, No are 1 pentru că este al doilea buton, iar Cancel are 2 deoarece este al treilea buton. Exemplul Secvenţa următoare testează, prin afişare, valorile returnate de showconfirmdialog(): Figura Exemplu int a=125; int rasp= JOptionPane.showConfirmDialog(this,"a="+a+"?"); System.out.println(rasp); Componente de tip JTextArea Componentele de acest tip permit utilizatorului să introducă text pe mai multe linii. Se poate utiliza un singur font, de o singură mărime! Un astfel de text, cu un singur font, care nu permite să fie formatat se numeşte text plan. Cele mai importante metode ale clasei sunt: JTextArea() - constructor. void append(string S) - adaugă la sfârşitul şirului reţinut de componentă un alt şir. void insert(string s, int pozitie) - inserează în text, începând de la pozitie un şir de caractere. Dacă pozitie depăşeşte indicele ultimului caracter, atunci inserarea se face la sfârşitul şirului reţinut de componentă. void replacerange(string str, int start, int end) - înlocuieşte şirul dintre indicii start şi end cu şirul transmis ca parametru. Evident, dacă acesta din urmă este vid, se şterge întreg textul. setfont(font f) - setează fontul utilizat.

339 Capitolul 8. Programare vizuală 339 String gettext() - returnează şirul de caractere conţinut de componentă (inclusiv dacă el conţine newline, altfel spus, mai multe paragrafe). void settext(string s) - determină ca obiectul de tip JTextArea să reţină şirul s. void setbackground(color c) - setează culoarea de fond a suprafeţei care afişează literele. String getselectedtext() - returnează şirul de caractere selectat. void selectall() - selectează întreg textul reţinut de componentă. int getselectionstart() - returnează indicele primului caracter selectat. int getselectionend() - returnează indicele ultimului caracter selectat. void setlinewrap(boolean v) - dacă reţine true, setează obiectul ca textul scris fără newline (adică un singur paragraf) să se afişeze pe mai multe rânduri (în cazul în care nu încape pe lăţime). Dacă reţine false, acesta este afişat pe o singură linie, chiar dacă, la un moment dat, nu este toată vizibilă. Obiectele de tip JTextArea nu se afişează pe fereastră în mod direct, ci prin intermediul altor obiecte de tip JScrollPane, asemănătoare obiectelor de tip JPanel, dar care permit ataşarea unor bare de scroll, aşa cum se vede mai jos: JScrollPane panel = new JScrollPane(t); panel.setverticalscrollbarpolicy(jscrollpane. VERTICAL_SCROLLBAR_ALWAYS); panel.sethorizontalscrollbarpolicy(jscrollpane. HORIZONTAL_SCROLLBAR_ALWAYS); Exemplul Programul următor afişează o componentă de tip JTextArea şi un meniu. Utilizatorul introduce un text la alegerea sa. Textul poate fi salvat cu ajutorul meniului (File şi Save) şi poate fi recuperat tot cu ajutorul meniului (File şi Open). Pentru simplificarea programului, fişierul în care se salvează este întotdeauna test.txt. Înainte de a studia programul, recomand o scurtă recapitulare a lucrului cu fişiere. import java.io.*; import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; Figura Exemplu

340 340 Manual de Informatică pentru clasa a XII-a class Fer extends JFrame implements ActionListener { JTextArea t; public Fer(String titlu) { super(titlu); setsize(200,200); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new GridLayout()); JMenuBar bara = new JMenuBar(); JMenu meniu1 = new JMenu("File"); bara.add(meniu1); JMenuItem item11 = new JMenuItem("Open"); item11.addactionlistener(this); meniu1.add(item11); JMenuItem item12 = new JMenuItem("Save"); item12.addactionlistener(this); meniu1.add(item12); setjmenubar(bara); t=new JTextArea(); t.setlinewrap(true); JScrollPane panel = new JScrollPane(t); panel.setverticalscrollbarpolicy (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); panel.sethorizontalscrollbarpolicy (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); x.add(panel); setvisible(true); void scriufisier() throws IOException { FileOutputStream f=new FileOutputStream("test.txt"); PrintStream fchar=new PrintStream (f); StringTokenizer tok=new StringTokenizer(t.getText(),"\n"); while (tok.hasmoretokens()) fchar.println(tok.nexttoken()); fchar.close(); void citfisier() throws IOException { FileInputStream f=new FileInputStream("test.txt"); InputStreamReader fchar=new InputStreamReader (f); BufferedReader buf = new BufferedReader(fchar); t.settext(""); String linie; while ((linie=buf.readline() )!=null) t.append(linie+"\n"); public void actionperformed (ActionEvent e) { if( e.getactioncommand().compareto("save")==0) // Daca s-a selectat Save { try {scriufisier(); catch (Exception excp) { else // Daca s-a selectat Open { try {citfisier(); catch (Exception excp) {

341 Capitolul 8. Programare vizuală 341 public class pv { public static void main(string args[]) { Fer fp=new Fer("Fereastra din care pot introduce textul"); Cutii de tip Open / Save Astfel de cutii se utilizează în operaţiile de încărcare şi salvare a fişierelor. Cu ajutorul lor se selectează fişierele şi folder-ele necesare acestor operaţii. Ele pot fi obţinute cu metodele clasei JFileChooser(). Cele mai importante metode ale acestei clase sunt: JFileChooser() - constructor; int showopendialog(component fer_parinte) - afişează o cutie de dialog de tip Open, aşa cum este cea de mai jos: Figura Cutie de tip Open Valoarea returnată este 0, dacă s-a apăsat butonul Open sau este 1 dacă s-a apăsat butonul Close. Rolul ei este ca, atunci când a fost selectat un anumit fişier şi s-a apăsat Open, obiectul de tip JFileChooser să conţină date despre fişierul selectat. int showsavedialog(component fer_parinte) - afişează o cutie de dialog de tip Save, asemănătoare cu cutia precedentă. Valoarea returnată este 0 dacă s-a apăsat butonul Save şi 1 dacă s-a apăsat butonul Cancel. Ca şi cutia precedentă (de tip Open), rolul ei este ca obiectul de tip JFileChooser să conţină date despre fişierul salvat. Atenţie! Cutia de tip Open nu deschide fişierul, iar cutia de tip Save nu-l salvează. Rolul lor este de a obţine informaţiile necesare deschiderii şi salvării fişierelor. File getselectedfile() - metoda returnează, atât în cazul salvării, cât şi în cazul deschiderii fişierelor, date despre fişierul selectat (furnizate de showopendialog() şi showsavedialog()). Pentru a putea accesa aceste informaţii, trebuie să studiem câteva metode ale tipului File.

342 342 Manual de Informatică pentru clasa a XII-a void addchoosablefilefilter(filter x); - metoda se utilizează pentru a adăuga un filtru cutiilor de tip Open şi Save. Despre filtre vom învăţa în cadrul acestui paragraf. setcurrentdirectory(file f) - setează cutia astfel încât să se deschidă într-un anumit folder. Clasa File. Cele mai importante metode ale acestei clase sunt: File() - constructor; File(String nume) - construieşte un obiect care conţine numele unui fişier (folder). boolean isdirectory() - returnează true dacă fişierul reţinut de obiect este folder (director) sau false, în caz contrar. String getname() - returnează numele fişierului. String getpath() - returnează numele întreg al fişierului, inclusiv calea către el. Filtre. În partea de jos a cutiilor de tip Open sau Save se găseşte o listă (File Name). Dacă programul nostru nu conţine un filtru, implicit se afişează doar opţiunea All Files, adică cutiile vizualizează toate folder-ele şi toate fişierele, indiferent de tipul lor. În cazul în care dorim ca programul să conţină filtre, adică să se vizualizeze doar fişierele de un anumit tip (sau tipuri), vom utiliza clasa FileFilter. Clasa FileFilter este abstractă. Pentru a crea un filtru este necesar să rescriem două metode ale sale: public String getdescription() - trebuie să returneze un şir de caractere care va fi afişat de lista File of Type, listă conţinută de cutiile Open şi Save. public boolean accept(file f) - metodă care returnează true pentru un fişier care, fie are o extensie dorită, fie este de tip folder, altfel returnează false. Dacă metoda returnează true, fişierul este aflat de cutiile Open/Save, altfel acesta nu este afişat. Exemplul Programul de mai jos este un editor primitiv de fişiere text. El nu conţine în meniu decât două opţiuni: Open şi Save. Oricare dintre ele are ca efect afişarea cutiilor respective şi salvarea sau deschiderea cu afişare a unui fişier cu una din extensiile.java şi.txt. Afişarea fişierului se face cu ajutorul unei componente de tip JTextArea. import java.io.*; import java.util.*; import java.awt.*; Figura Rezultat

343 Capitolul 8. Programare vizuală 343 import java.awt.event.*; import javax.swing.*; class Filtre extends javax.swing.filechooser.filefilter { public boolean accept(file f) { if (f.isdirectory()) {return true; String nume_fis = f.getname(); return nume_fis.endswith(".java") nume_fis.endswith(".txt"); public String getdescription() { return "*.java" + " "+"*.txt"; class Fer extends JFrame implements ActionListener { JTextArea t; public Fer(String titlu) { super(titlu); setsize(200,200); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new GridLayout()); JMenuBar bara = new JMenuBar(); JMenu meniu1 = new JMenu("File"); bara.add(meniu1); JMenuItem item11 = new JMenuItem("Open"); item11.addactionlistener(this); meniu1.add(item11); JMenuItem item12 = new JMenuItem("Save"); item12.addactionlistener(this); meniu1.add(item12); setjmenubar(bara); t=new JTextArea(); t.setlinewrap(true); JScrollPane panel = new JScrollPane(t); panel.setverticalscrollbarpolicy (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); panel.sethorizontalscrollbarpolicy (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); x.add(panel); setvisible(true); void scriufisier(string nume) throws IOException {FileOutputStream f=new FileOutputStream(nume); PrintStream fchar=new PrintStream (f); StringTokenizer tok=new StringTokenizer(t.getText(),"\n"); while (tok.hasmoretokens()) fchar.println(tok.nexttoken()); fchar.close(); void citfisier(string nume) throws IOException { FileInputStream f=new FileInputStream(nume); InputStreamReader fchar=new InputStreamReader (f); BufferedReader buf = new BufferedReader(fchar); t.settext(""); String linie; while ((linie=buf.readline() )!=null) t.append(linie+"\n");

344 344 Manual de Informatică pentru clasa a XII-a public void actionperformed (ActionEvent e) { if( e.getactioncommand().compareto("open")==0) { JFileChooser c_op = new JFileChooser(); c_op.addchoosablefilefilter(new Filtre()); int valret = c_op.showopendialog(this); if (valret==0) { File f=c_op.getselectedfile(); { try { citfisier(f.getpath()); catch (Exception excp) { else { JFileChooser c_save = new JFileChooser(); c_save.addchoosablefilefilter(new Filtre()); int valret = c_save.showsavedialog(this); if (valret==0) { File f=c_save.getselectedfile(); { try { scriufisier(f.getpath()); catch (Exception excp) { public class pv { public static void main(string args[]) { Fer fp=new Fer("Fereastra din care pot introduce textul"); Componente de tip JColorChooser În programarea vizuală culorile au un rol fundamental. Pentru a uşura selectarea culorilor, Java pune la dispoziţia programatorilor clasa JColorChooser. În linii mari, această clasă permite afişarea unui panou prin care se selectează uşor culorile (fie direct, fie folosind sistemul RGB, fie folosind sistemul HSL). Iată cele mai importante metode ale acestei clase: JColorChooser() - constructor. În panoul culorilor este automat selectată culoarea albă; JColorChooser(Color c) - constructor. În panoul culorilor este automat selectată culoarea transmisă ca parametru; static Color showcolordialog (Component parinte, String mes, Color c) - lansează, modal, o cutie de dialog care conţine panoul culorilor. După cum observaţi, metoda returnează culoarea selectată (dacă se apasă butonul OK, iar dacă se apasă Cancel se returnează null). Parametrii sunt: parinte (fereastra părinte), mes (mesaj ce se afişează pe bara de titlu a cutiei) şi c (culoarea iniţial setată în cutie). Utilizarea acestei metode este cel mai simplu mecanism prin care utilizatorul poate selecta culoarea.

345 Capitolul 8. Programare vizuală 345 Color getcolor() - returnează culoarea selectată în cutie. Exemplul Din fereastra principală, la apăsarea unui buton se afişează o cutie de dialog specifică pentru selectarea culorii. Culoarea selectată va fi culoarea de fond a ferestrei principale. import java.awt.*; import java.awt.event.*; import javax.swing.*; class Fer extends JFrame implements ActionListener { Container x; public Fer(String titlu) { super(titlu); setsize(200,100); x=getcontentpane(); Figura Cutia de dialog x.setlayout(new FlowLayout ()); JButton A=new JButton("Alta culoare"); x.add(a); A.addActionListener(this); setvisible(true); public void actionperformed (ActionEvent e) { Color c=jcolorchooser.showdialog (this, "Alege culoarea",color.red); if (c!=null) x.setbackground(c); public class pv1 { public static void main(string args[]) { Fer fp=new Fer("Schimbarea culorii ferestrei"); fp.setdefaultcloseoperation(jframe.exit_on_close); Componente de tip JToolBar (bară de unelte) O astfel de componentă creează o bară cu unelte. Pe ea se aşează numeroase alte componente, întocmai ca pe un panel. De regulă se găseşte în partea de sus a ferestrei, dar întotdeauna sub meniu. Clasa JToolBar conţine următoarele metode mai importante: JToolBar() - constructor, creează o bară de unelte poziţionată orizontal; JToolBar(int orientare) - creează o bară de unelte orientată fie orizontal, orientare va avea valoarea JToolBar.HORIZONTAL, fie vertical, orientare va avea valoarea JToolBar.VERTICAL. Diferenţa de orientare afectează modul în care sunt aşezate pe ea diferitele componente (pe orizontal sau pe vertical).

346 346 Manual de Informatică pentru clasa a XII-a Component add(component comp) - adaugă o componentă; void addseparator() - adaugă un separator (spaţiu liber) între componente. Exemplul Mai jos puteţi observa programul care afişează o fereastră cu o bară de unelte şi în rest, un panel (componentă de tip JPanel): import java.awt.*; import javax.swing.*; class Fer extends JFrame { public Fer(String titlu) { super(titlu); setsize(600,800); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); JToolBar bara=new JToolBar(); bara.setbackground(color.red); bara.setlayout(new FlowLayout(FlowLayout.LEFT)); JPanel panel=new JPanel(); panel.setbackground(color.yellow); JComboBox lista=new JComboBox (); x.setlayout(new BorderLayout()); x.add(bara,borderlayout.north); x.add(panel,borderlayout.center); JButton A=new JButton("buton 1"); bara.add(a); A.setPreferredSize(new Dimension (70,30)); JButton B=new JButton("buton 2"); B.setPreferredSize(new Dimension (70,30)); bara.add(b); bara.addseparator(); lista.additem("optiunea 1"); lista.additem("optiunea 2"); bara.add(lista); lista.setpreferredsize(new Dimension (100,30)); setvisible(true); public class pv { public static void main(string args[]) { Fer fp=new Fer("Bara cu unelte"); fp.setdefaultcloseoperation(jframe.exit_on_close); Observaţii! Figura Rezultat 1. Pentru a poziţiona bara orizontal se preferă gestionarul GridLayout şi bara se aşează în nord.

347 Capitolul 8. Programare vizuală În aceste condiţii, panelul s-a aranjat în centru. Cum celelalte trei componente lipsesc, componenta din centru ocupă toată linia din mijloc, iar linia din mijloc ocupă şi partea de sud! 3. Pentru bară se preferă gestionarul FlowLayout (FlowLayout.LEFT) care aranjează componentele pe bară de la dreapta la stânga, dar aliniate stânga! 4. Pentru a ne asigura că butoanele şi lista au aceeaşi înălţime, am preferat dimensionarea lor prin setpreferredsize(). 5. Între cele două butoane şi listă a fost introdus un separator. Observaţi-l în imaginea de pe pagina anterioară! Componente de tip JTable Cu ajutorul componentelor de acest tip se creează tabele. În continuare prezentăm cele mai importante metode ale acestui tip. JTable(Object[][] celule, object[] cap_t) - constructor. Parametrul celule este o matrice de referinţe către obiectele afişate de celulele tabelului, iar cap_t este un vector de referinţe către obiectele afişate de capul de tabel. Numărul coloanelor matricei de referinţe celule trebuie să coincidă cu numărul elementelor vectorului de referinţe cap_t şi reprezintă numărul coloanelor din tabel. Înainte de a da primul exemplu de tabel, trebuie precizat că această componentă se plasează, de obicei, pe o componentă de tip JScrollPane. public void setpreferredscrollableviewportsize(dimension dim) are rolul de a preciza dimensiunea tabelului şi faptul că acesta trebuie să conţină o bara de scroll verticală (dacă tabelul are suficiente linii astfel încât să nu încapă în totalitate în spaţiul generat de dim). Exemplul Tabelul alăturat a fost obţinut cu secvenţa de mai jos: class Fer extends JFrame { public Fer(String titlu) { Figura Tabelul rezultat super(titlu); setsize(600,800); setdefaultcloseoperation(jframe.exit_on_close); Object[][] date = { {"x(0,0)", "x(0,1)","x(0,2)", {"x(1,0)", "x(1,1)","x(1,2)" ; String[] cap_tabel={"coloana 1","Coloana 2","Coloana 3"; Container x=getcontentpane(); x.setlayout(new FlowLayout()); JTable table = new JTable(date, cap_tabel); JScrollPane panel = new JScrollPane(table); table.setpreferredscrollableviewportsize(new Dimension(200,30)); x.add(panel);setvisible(true);

348 348 Manual de Informatică pentru clasa a XII-a Observaţie! Dacă dorim, putem inversa ordinea coloanelor în tabel prin drag and drop. Încercaţi! Tabelul este de fapt format din două componente: tabelul propriu-zis (de tip JTable) şi capul de tabel (de tip JTableHeader). JTableHeader gettableheader() - metoda returnează o referinţă către capul de tabel. Imediat ce creăm un tabel ne punem problema culorilor de fond şi de scriere, atât pentru capul de tabel cât şi pentru tabelul propriu-zis. Dacă ambele sunt componente, atunci putem utiliza metodele clasei JComponent: setbackground(), setforeground() şi setcolor(). Exemplul Adăugaţi exemplului anterior secvenţa de mai jos şi veţi obţine efectul scontat! // pentru tabel table.setfont(new Font("Arial",Font.ITALIC, 10)); table.setbackground(color.green); table.setforeground(color.red); // pentru capul de tabel JTableHeader cap= table.gettableheader(); cap.setfont(new Font("Arial",Font.BOLD, 12)); cap.setbackground(color.yellow); cap.setforeground(color.red); Observaţi faptul că fiecare celulă a tabelului este editabilă. Aceasta înseamnă că dacă executăm clic pe celula respectivă, ea se comportă ca un edit oarecare. De aici, rezultă că un tabel poate fi folosit şi pentru introducerea datelor, nu doar pentru afişarea lor! Object getvalueat(int linie, int coloana) întoarce o referinţă către obiectul memorat de celula respectivă; void setvalueat(object ref, int linie, int coloana) - memorează referinţa către obiect în linia şi coloana dată de indicii transmişi. JTable(int n_linii, int n_coloane) - este un alt constructor al tabelului, în care se creează un tabel cu n_linii şi n_coloane. Liniile sunt numerotate începând de la 0. De asemenea, coloanele sunt numerotate începând de la 0. Exemplul Programul următor creează un tabel fără date cu 2 linii şi 4 coloane. Utilizatorul introduce date în fiecare celulă a tabelului. La apăsarea butonului se afişează, în fereastra CMD, valorile reţinute de fiecare celulă. Observaţi că numele coloanelor a fost dat automat. Figura Tabelul rezultat

349 Capitolul 8. Programare vizuală 349 import java.awt.*; import javax.swing.*; import javax.swing.table.*; import java.awt.event.*; class Fer extends JFrame implements ActionListener { JTable table; public Fer(String titlu) { super(titlu);setsize(600,800); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout()); table = new JTable(3, 4); JScrollPane panel = new JScrollPane(table); table.setpreferredscrollableviewportsize (new Dimension(200, 30)); x.add(panel); JButton A=new JButton("Afiseaza"); x.add(a); A.addActionListener(this); setvisible(true); public void actionperformed (ActionEvent e) { if (table.getcelleditor()!= null) table.getcelleditor().stopcellediting(); for (int i=0;i<2;i++) for (int j=0;j<4;j++) System.out.println(i+" "+j+" "+table.getvalueat(i,j)); public class pv { public static void main(string args[]) { Fer fp=new Fer("Tabel"); Să urmărim metoda actionperformed(). Ce rost are acel if? Atunci când se scriu datele într-o celulă, până nu s-a trecut la celula următoare (clic pe suprafaţa ei), data conţinută de ea nu este memorată şi prin urmare, la afişare va apărea null (obiectul null). Pentru a evita aceasta, s-a utilizat metoda getcelleditor() a clasei JTable. TableCellEditor getcelleditor() - metoda returnează o referinţă către un obiect dacă o celulă a tabelului este sub editare şi null în caz contrar. TableCellEditor este o interfaţă care, evident, este implementată. Fără a intra în amănunte, interfaţa conţine antetul metodei stopcellediting(), metodă care are rolul de a stopa editarea şi, prin urmare, de memorare a tuturor datelor introduse în tabel.

350 350 Manual de Informatică pentru clasa a XII-a În continuare, vedem cum putem proiecta capul de tabel. Clasa JTable conţine metodele: TableColumnModel getcolumnmodel(). TableColumnModel este o interfaţă implementată de o anumită clasă (DefaultTableColumnModel). Prin urmare, putem utiliza metodele clasei pornind de la referinţa întoarsă de metodă. Cu ajutorul lor proiectăm capul de tabel. TableColumn getcolumn(int index) - returnează o referinţă către un obiect TableColumn. Un astfel de obiect conţine toate atributele unei coloane a tabelului. Iată câteva metode, mai importante ale acestui obiect: void setheadervalue(object ob) - setează obiectul afişat de coloana respectivă (numele coloanei). setpreferredwidth(int lat) - setează lăţimea coloanei. setresizable(boolean v); - în mod normal, marginile unei coloane se pot deplasa astfel încât lăţimea coloanei poate fi stabilită şi de utilizator. Dacă metoda primeşte ca parametru valoarea false, marginile nu mai pot fi stabilite de utilizator. Exemplul Secvenţa de mai jos ne arată cum putem construi un tabel precum cel alăturat, care conţine numele coloanelor, dar în care, primei coloane nu i se poate modifica lăţimea (implicit, şi celeilalte coloane). table = new JTable(6, 2); TableColumnModel mcoloane=table.getcolumnmodel(); TableColumn coloana=mcoloane.getcolumn(0); coloana.setheadervalue("coloana 1"); coloana.setpreferredwidth(150); coloana.setresizable(false); coloana=mcoloane.getcolumn(1); coloana.setheadervalue("coloana 2"); JScrollPane panel = new JScrollPane(table); table.setpreferredscrollableviewportsize (new Dimension(200,80)); Figura Tabelul rezultat Alte metode ale clasei JTable: void setgridcolor(color c) - setează culoarea liniilor care separă celulele tabelului. void setrowheight(int inalt) - setează înălţimea liniilor tabelului (în pixeli). void setselectionbackground(color c) - setează culoarea liniei selectate (atunci când se execută clic pe o celulă, se selectează întreaga linie).

351 Capitolul 8. Programare vizuală 351 void setselectionforeground(color c) - setează culoarea cu care se scrie în linia selectată (mai puţin celula în care se editează). setintercellspacing(dimension dim) - setează spaţiile între linii şi coloane. Aceasta nu afectează liniile separatoare dintre celule (vecine), ci numai spaţiul dintre părţile lor editabile. Primul parametru pentru dim este pentru linii, al doilea parametru este pentru coloane. void setshowhorizontallines(boolean v) - dacă parametrul este false, atunci nu mai sunt trasate liniile orizontale ale tabelului. setshowgrid(boolean v) - dacă parametrul este false, atunci nu mai sunt trasate liniile orizontale şi verticale ale tabelului Obiecte grafice. Clasa Graphics Afişarea imaginilor Pentru a afişa o imagine aflată într-un fişier, vom scrie o clasă care extinde clasa Canvas. Obiectele clasei Canvas conţin o metodă numită paint(graphics ecr). Această metodă este apelată automat atunci când componenta respectivă este afişată şi are rolul de a desena componenta. Observaţi că metoda paint() primeşte ca parametru o referinţă către un obiect al clasei Graphics şi, pornind de la ea, putem apela toate metodele acestei clase, cu ajutorul cărora putem afişa imaginea, putem scrie în mod grafic sau desena. În programul următor, clasa care construieşte componenta ce afişează imaginea se numeşte Imagine. Clasa Imagine conţine: 1. O referinţă către un obiect de tip Image. Un astfel de obiect poate reţine o imagine citită. Referinţa este utilizată în metoda paint() pentru a afişa imaginea respectivă. 2. Un constructor care citeşte imaginea stabileşte mărimea componentei (setsize()) şi culoarea de fundal (setbackground()). Pentru citirea imaginii se utilizează metoda clasei Toolkit numită getimage(): Image getimage(string fisier), unde parametrul reprezintă calea către fişierul respectiv. 3. Metoda paint() (redefinită, pentru a avea acces). Metoda desenează imaginea şi foloseşte metoda drawimage() a clasei Graphics): drawimage(image im, int a, int b, int latime, int inaltime, this), unde:

352 352 Manual de Informatică pentru clasa a XII-a Observaţii! a,b - coordonatele relative (faţă de colţul din stânga-sus al componentei care afişează imaginea; în exemplu Imagine) ale colţului din stânga sus al dreptunghiului care conţine imaginea. latime, inaltime - lăţimea şi înălţimea dreptunghiului care conţine imaginea. this - obiectul curent (cel al clasei Imagine). Nu tratăm semnificaţia generală a acestui parametru. Metoda poate redimensiona imaginea citită (o măreşte sau o micşorează) prin valorile transmise pentru latime şi inaltime. Fişierul imagine se găseşte în Bin (folder-ul curent), dar îi putem ataşa o cale. Exemplul următor conţine o componentă care afişează desenul în centrul ei. Desigur, imaginea putea acoperi întreaga suprafaţă a componentei Imagine, dar din considerente didactice, pentru a distinge întreaga suprafaţă unde am fi putut desena, am preferat să folosim setbackground(). Exemplul Programul de mai jos construieşte o fereastră care afişează o imagine: import java.awt.*; import java.awt.event.*; import javax.swing.*; class Imagine extends Canvas { Image im; Imagine() { Toolkit ec=toolkit.getdefaulttoolkit(); im=ec.getimage("calculator.jpg"); setsize(300,300); setbackground(color.yellow); public void paint (Graphics ecr) { ecr.drawimage(im,50,50,200,200,this); class Fer extends JFrame { Imagine p=new Imagine(); public Fer(String titlu) { super(titlu);setsize(150,200); setdefaultcloseoperation(jframe.exit_on_close); Container x=getcontentpane(); x.setlayout(new FlowLayout ()); x.add(p); setvisible(true); Figura Fereastra obţinută

353 Capitolul 8. Programare vizuală 353 public class pv { public static void main(string args[]) { Fer fp=new Fer("Imagine"); Cum scriem? Înainte de parcurgerea acestui paragraf, revedeţi , Afişarea imaginilor. Aţi putut observa acolo că metoda Paint primeşte ca referinţă un obiect al clasei Graphics. Putem utiliza metodele acestui obiect pentru a desena ceva sau pentru a încărca o imagine care se găseşte într-un fişier. Cele mai importante metode ale acestei clase sunt: void setfont (Font f) - setează obiectul pentru ca scrierea grafică să se realizeze cu un anumit font; void setcolor(color c) - setează culoarea de scriere (desenare); drawstring(string str, int x, int y) - scrie pe ecran un şir de caractere. Şirul este scris cu font-ul şi culoarea setate la un moment dat. Parametrii x şi y reprezintă coordonatele colţului din stânga sus al şirului de caractere afişat. Exemplul Iată cum arată metoda Paint() pentru a putea scrie două şiruri de caractere cu font-uri şi culori diferite: Figura Rezultat public void paint (Graphics ecr) { Font f=new Font("Arial",Font.ITALIC+Font.BOLD, 11); ecr.setfont(f); ecr.setcolor(color.red); ecr.drawstring("un exemplu de scriere",20, 30); ecr.setcolor(color.black); Font f1=new Font("CourierNew",Font.BOLD, 14); ecr.setfont(f1); ecr.drawstring("scriu cu alta culoare si alt font",20,50); Cum desenăm? drawline(int x1, int y1, int x2, int y2) - desenează o linie (segment) între punctele de coordonate (x1,y1) şi (x2,y2). drawrect(int x,int y,int latime,int inaltime) - desenează un dreptunghi pentru care colţul din stânga sus are coordonatele (x,y) şi de lăţime şi înălţime date.

354 354 Manual de Informatică pentru clasa a XII-a drawroundrect(int x,int y,int latime, int inaltime,int lat,int inal) - desenează un dreptunghi care are colţurile rotunjite, (vedeţi figura alăturată). inal lat Figura Dreptunghi cu colţurile rontunjite void fillrect(int x, int y, int latime, int inaltime), la fel ca drawrect(), numai că dreptunghiul este colorat în interior. void fillroundrect(int x,int y,int latime,int inaltime, int lat,int inal) - la fel ca drawroundrect(), numai că dreptunghiul rotunjit este colorat în interior. void drawpolygon(int[] X, int[] Y, int nr) - desenează un poligon care are nr vârfuri. Coordonatele x ale punctelor se găsesc în vectorul X, iar coordonatele y ale punctelor se găsesc în vectorul Y. Practic, primul punct are coordonatele (X[0],Y[0]), al doilea punct are coordonatele (X[1],Y[1]), ş.a.m.d. În final, pentru a obţine poligonul se unesc printr-un segment primul şi ultimul punct. Poligonul este oarecare, deci poate fi şi neconvex. Exemplul Analizaţi secvenţa de mai jos: ecr.setcolor(color.black); int[] X= {10, 100,25, 80; int[] Y= {10, 100,75, 30; ecr.drawpolygon(x, Y, 4); void fillpolygon(int[] X, int[] Y, int nr) - la fel ca mai sus, numai că poligonul este colorat în interior. void drawpolyline(int[] X, int[] Y, int nr) - la fel ca mai sus, numai că nu se mai uneşte primul punct cu ultimul punct. Astfel se obţine o succesiune de segmente. void drawoval(int x, int y, int latime, int inaltime) - desenează un oval. Coordonatele x şi y sunt ale colţului din stânga sus al dreptunghiului circumscris ovalului, iar latime şi inaltime sunt lăţimea şi înălţimea acelui dreptunghi. filloval(int x, int y, int latime, int inaltime) - la fel ca mai sus, numai că ovalul este colorat în interior.

355 Capitolul 8. Programare vizuală 355 drawarc(int x, int y, int latime, int inaltime, int u1, int u2) - trasează un arc. Arcul este o porţiune dintr-un oval şi primii 4 parametri sunt ai ovalului căruia îi aparţine arcul. Ultimii doi parametri sunt: unghiul de unde porneşte arcul şi numărul de grade al arcului. Unghiurile sunt date în grade Figura Un cerc şi gradele sale 270 fillarc(int x, int y, int latime, int inaltime, int u1, int u2) - la fel ca drawarc, numai că se consideră sectorul (nu numai arcul) şi acesta este colorat. De exemplu, în cazul în care latime şi inaltime reţin aceeaşi valoare, ovalul este de fapt un cerc. În acest caz avem un sector de cerc. drawimage(image im, int a, int b, int latime, int inaltime, this), unde: a,b sunt coordonatele relative (faţă de componenta creată, vezi setsize()) ale colţului din stânga-sus al dreptunghiului care conţine imaginea. latime, inaltime - lăţimea şi înălţimea dreptunghiului care conţine imaginea. this - obiectul curent (cel al clasei Imagine). Nu tratăm semnificaţia generală a acestui parametru. Observaţie! Metoda a mai fost folosită atunci când am afişat o imagine!

356 356 Manual de Informatică pentru clasa a XII-a 8.4. Accesarea şi prelucrarea datelor Citiri şi scrieri utilizând dispozitive standard şi fişiere În Java, fişierele sunt abordate pornind de la noţiunea de flux. Prin flux vom înţelege o cale pe care o urmează datele pentru a ajunge de la sursă la destinaţie. Putem imagina un flux ca o şosea pe care circulă maşini. Astfel, în Java, datele ar fi maşinile care circulă pe şosea. Există două tipuri de fluxuri: A) Fluxuri de intrare - de la sursă (un fişier), către destinaţie (programul), unde datele sunt prelucrate: program Sursa fişier Destinatie Figura Schema fluxului de intrare B) Fluxuri de ieşire - de la sursă (programul) către destinaţie (fişier), unde se reţin rezultatele: fişier Sursa program Destinatie Figura Schema fluxului de ieşire Observaţie! Clasele pe care le studiem în acest paragraf se găsesc în pachetul java.io. Pentru a lucra cu fişiere text, vom utiliza fluxuri de caractere. A) Fluxuri de intrare - se folosesc pentru citirea fişierelor text. Pentru a transforma un flux de octeţi într-un flux de caractere, vom utiliza constructorul clasei InputStreamReader (care extinde clasa Reader): public InputStreamReader(InputStream in) Întrucât clasa FileInputStream extinde clasa InputStream, parametrul in (de tip InputSTream) poate fi o referinţă către un obiect al clasei FileInputStream. Pentru a putea lucra cu uşurinţă cu caracterele, vom utiliza clasa BufferedReader care permite ataşarea fluxului de caractere al unei memorii, numită buffer. Practic, buffer-ul permite memorarea mai multor caractere citite, care urmează să fie prelucrate. Constructorul clasei BufferedReader este: public BufferedReader(Reader in1).

357 Capitolul 8. Programare vizuală 357 Întrucât clasa InputStreamReader extinde clasa Reader, parametrul in1 poate fi o referinţă către un obiect al clasei InputStreamReader. Clasa BufferedReader conţine metoda readline() care citeşte din fişier (flux) o întreagă linie de caractere: public String readline() throws IOException Acestea fiind spuse, puteţi analiza programul de mai jos care afişează toate liniile unui fişier text. Exemplul Dacă creaţi cu NOTEPAD un fişier cu mai multe linii, numit in.txt, programul îl afişează: import java.io.*; public class f { public static void main (String[ ] args) throws IOException { FileInputStream f=new FileInputStream("in.txt"); InputStreamReader fchar=new InputStreamReader (f); BufferedReader buf = new BufferedReader(fchar); String linie; while ((linie=buf.readline())!=null) System.out.println(linie); fchar.close(); B) Fluxuri de ieşire - se folosesc pentru scrierea fişierelor text. Clasa FileOutputStream creează un flux de ieşire către un fişier al cărui nume este transmis ca parametru. Ea extinde clasa OutputStream şi are constructorul: public FileOutputStream(String nume) throws FileNotFoundException Clasa PrintStream conţine mai multe metode print şi println care funcţionează exact ca System.out.print() şi System.out.print(). Practic, valoarea care este scrisă în fişier este mai întâi convertită către tipul String, aşa cum suntem deja obişnuiţi. Clasa este înzestrată cu constructorul: public PrintStream(OutputStream out) Exemplul Programul de mai jos creează un fişier text (numit out.txt) care conţine 3 linii, iar fiecare linie conţine câte un şir de caractere: import java.io.*; public class f { public static void main (String[ ] args) throws IOException { FileOutputStream f=new FileOutputStream("out.txt"); PrintStream fchar=new PrintStream (f); fchar.println("o linie");

358 358 Manual de Informatică pentru clasa a XII-a fchar.println("alta linie"); fchar.print("a treia linie"); fchar.close(); Instalarea soft-ului pentru lucrul cu bazele de date Java are implementat un mecanism excepţional de lucru cu bazele de date. Pe lângă faptul că, aşa cum ştim, Java poate rula pe orice sistem de operare, există posibilitatea ca, prin utilizarea acestui limbaj să putem lucra cu orice bază de date care are la bază SQL. Limbajul Java conţine o interfaţă standard numită JDBC (Java DataBase Connectivity), care oferă accesul la bazele de date accesabile prin SQL. Clasele şi interfeţele (în sens OOP) care alcătuiesc JDBC se găsesc în pachetul java.sql. Cu ajutorul acestei interfeţe, dintr-un program Java, se pot transmite comenzi SQL către baza de date. Pentru a accesa o bază de date construită cu un anumit SGBD este necesar să încărcăm clasa care conţine metodele de acces la acel tip de baze de date. În această carte ne referim la bazele de date realizate în MySQL, prin urmare, va fi necesară încărcarea clasei care conţine metodele de acces la bazele de date MySQL. Numele acestei clase este com.mysql.jdbc.driver. Clasa respectivă nu este conţinută în mediul de dezvoltare Java. Pentru a o folosi ea trebuie download-ată. Căutaţi pe internet arhiva mysql-connectorjava După download-are, dezarhivaţi-o într-un folder cu nume la alegerea dvs. În exemplu, acest folder este fdex. Pentru a avea acces la ea, calea către acest folder trebuie trecută în variabila de mediu CLASSPATH (aceasta poate conţine mai multe căi separate prin ;). Variabila CLASSPATH poate fi accesată din Start, Settings, Control Panel, System, Advanced, Environment Variables, dublu-clic pe CLASSPATH. În edit-ul afişat, treceţi calea către ce aţi download-at, în exemplu C:/fdex/mysql-connector-java Revedeţi modul în care am instalat Java pentru că şi acolo am utilizat variabila CLASSPATH Lucrul cu baze de date Acum, că am instalat software-ul necesar, putem prezenta modul în care lucrăm cu bazele date MySQL. Tot ce prezentăm aici, poate fi observat în programul aflat la sfârşitul acestui paragraf.

359 Capitolul 8. Programare vizuală Încărcarea clasei care accesează bazele de date. Pentru MySQL, această clasă este com.mysql.jdbc.driver. Pentru aceasta vom utiliza o metodă a clasei Class: forname(string nume_clasa). Dacă operaţia eşuează, inseamnă că nu am rezolvat corect problema instalării soft-ului, tratată în paragraful anterior. 2. Conectarea la MySQL se realizează cu metoda de mai jos a clasei DriverManager. Ea are trei parametri, adresa URL acolo unde lucrează MySQL, numelele utilizatorului (user) şi parola de acces (password). În cazul nostru, ne conectăm la bazele de date aflate pe propriul calculator, deci adresa URL are un format specific: jdbc:mysql://localhost/?". Foarte important! În cazul nostru, conectarea nu se poate realiza dacă nu este pornit programul EasyPHP. Connection getconnection (String url, String user, String password) Pentru a efectua o operaţie cu bazele de date, cu comenzi SQL, mai precis cele din MySQL, mai întâi, trebuie să creăm un obiect Statement care transmite comanda către MySQL (SGBD, în general). Aceasta se realizează cu ajutorul metodei Statement createstatement() a interfeţei Connection (nu uitaţi că am încărcat clasa care implementează interfeţele din JDBC). Pornind de la acest obiect, se pot aplica metode specifice care transmit comenzi MySQL. În acest manual, vom utiliza două astfel de metode în care şirul primit ca parametru este o instrucţiune (comanda SQL). a) int executeupdate(string sql) - trimite o comandă de punere la zi a bazei de date. Se foloseşte pentru instrucţiuni MySQL precum CREATE DATABASE, USE, CREATE TABLE, INSERT b) ResultSet executequery (String sql) - trimite o comandă de interogare a bazei de date. Imaginaţi rezultatul sub forma unui vector în care fiecare componentă reţine un rând al rezultatului interogării. Metoda boolean next() returnează următoarea componentă din vector. Dacă nu s-a ajuns la sfârşit, se returnează true. Informaţiile de pe coloane, asociate unui rând al interogării pot fi accesate cu ajutorul metodei: String getstring (String nume_camp). În cele ce urmează vom exemplifica câteva operaţii executate în baza de date şi existente în programul de mai jos. 3. Crearea unei baze de date...executeupdate ("CREATE DATABASE baza_de_date"); 4. Accesul la o bază de date...executeupdate ("USE baza_de_date");

360 360 Manual de Informatică pentru clasa a XII-a 5. Crearea unui tabel instr.executeupdate ("CREATE TABLE tbl (camp1 char(10), camp2 int(4))"); 6. Popularea cu date a unui tabel. Observaţi că apostrofurile sunt trecute sub forma de cod escape: instr.executeupdate ("INSERT INTO tbl (camp1,camp2) VALUES(\'valoare1\', 100)"); 7. Afişarea unui tabel (interogare) rez.executequery(" SELECT * from tbl"); while (rez.next()) System.out.println(rez.getString("camp1")+ " "+rez.getstring("camp2")); În afara celor prezentate, este nevoie să ştim doar MySQL. Oricum, noţiunile prezentate aici nu trebuie reţinute decât în principiu, pentru că oricând se poate consulta o documentaţie. Esenţial este să ştiţi să consultaţi o documentaţie şi s-o aplicaţi în programele pe care le realizaţi. Iată şi programul care creează o bază de date, în ea formează un tabel pe care îl populează cu două linii. În final, se afişează cele două linii ale tabelului: import java.sql.*; import java.io.*; public class test { static Connection cnc=null; static Statement instr=null; static ResultSet rez=null; static String URL="jdbc:mysql://localhost/?"; static String USER="root"; static String PAROLA="parolamea"; public static void main(string[] args) { // incarcarea clasei care acceseaza baza de date try { Class.forName("com.mysql.jdbc.Driver").newInstance(); System.out.println("OK "); catch (Exception ex) { System.out.println ("Nu gasesc clasa"); // Conectarea la MySQL try { cnc=drivermanager.getconnection(url, USER, PAROLA ); System.out.println ("M-am conectat la MySQL"); catch (SQLException ex) { System.out.println ("Nu m-am conectat la MySQL ");

361 Capitolul 8. Programare vizuală 361 // Crearea unei baze de date try { instr= cnc.createstatement(); instr.executeupdate ( "CREATE DATABASE baza_de_date" ); System.out.println ("am creat baza de date"); catch (SQLException e) { System.out.println ("nu am creat baza de date"); // Accesul la o baza de date try { instr= cnc.createstatement(); instr.executeupdate ( "USE baza_de_date" ); System.out.println ("utilizez baza de date"); catch (SQLException e) { System.out.println ("nu utilizez baza de date"); // Crearea unui tabel in baza de date try { instr= cnc.createstatement(); instr.executeupdate ("CREATE TABLE tbl (camp1 char(10), camp2 int(4))"); System.out.println ("am creat tabelul"); catch (SQLException e) {System.out.println ("nu am creat tabelul"); // Popularea unui tabel cu date try { instr= cnc.createstatement(); instr.executeupdate ("INSERT INTO tbl (camp1,camp2) VALUES(\'valoare1\', 100)"); instr.executeupdate ("INSERT INTO tbl (camp1,camp2) VALUES(\'valoare2\', 15)"); System.out.println("Date adaugate"); catch (SQLException e) { System.out.println ("nu inserare"); // Interogare de afisare a unui tabel try { instr= cnc.createstatement(); rez=instr.executequery(" SELECT * from tbl"); while (rez.next()) System.out.println(rez.getString("camp1")+ " "+rez.getstring("camp2")); catch (SQLException e) {

362 362 Manual de Informatică pentru clasa a XII-a Întrebare. Care este modalitatea prin care putem afişa elegant rezultatele interogării unei baze de date? Răspuns. Să nu uităm că am studiat o componentă care permite afişarea elegantă a unui tabel şi anume componenta de tip JTable. În continuare, prezentăm un program care afişează datele din tabelul tbl al bazei de date construite în cadrul exemplului anterior: import java.awt.*; import javax.swing.*; import javax.swing.table.*; import java.awt.event.*; import java.sql.*; import java.io.*; class Fer extends JFrame { static Connection cnc=null; static Statement instr=null; static ResultSet rez=null; static String URL="jdbc:mysql://localhost/?"; static String USER="root"; static String PAROLA="parolamea"; static String nr_linii; static Object[][] linii_date; Figura Fereastra programului propus public Fer(String titlu) { super(titlu); setsize(300,200); setdefaultcloseoperation(jframe.exit_on_close); // incarcarea clasei care acceseaza baza de date try {Class.forName("com.mysql.jdbc.Driver").newInstance(); catch (Exception ex) {System.out.println ("Nu gasesc clasa"); // Conectarea la MySQL try {cnc=drivermanager.getconnection(url, USER, PAROLA); catch (SQLException ex) {System.out.println ("Nu m-am conectat la MySQL "); //Accesul la o baza de date try { instr= cnc.createstatement(); instr.executeupdate ( "USE baza_de_date" ); // gasesc numarul de linii din tabel rez=instr.executequery(" SELECT COUNT(*) AS numar FROM tbl;"); rez.next(); nr_linii=rez.getstring("numar"); // masivul care retine liniile care vor fi afisate linii_date=new Object[Integer.parseInt(nr_linii)][2]; int i=0; rez=instr.executequery(" SELECT * from tbl");

363 Capitolul 8. Programare vizuală 363 while (rez.next()) { linii_date[i][0]=rez.getstring("camp1"); linii_date[i][1]=rez.getstring("camp2"); i++; catch (SQLException e) {System.out.println("erori in utilizarea bazei de date"); String[] cap_tabel = {"Camp 1", "Camp 2"; Container x=getcontentpane(); x.setlayout(new FlowLayout()); JTable table = new JTable(linii_date, cap_tabel); JScrollPane panel = new JScrollPane(table); table.setpreferredscrollableviewportsize (new Dimension(200, 30)); x.add(panel); setvisible(true); public class baza { public static void main(string args[]) { Fer fp=new Fer("Tabel"); Exerciţiu! Nu uitaţi că în celulele unei componente de tip JTable utilizatorul poate introduce date (celulele sunt editabile). Scrieţi un program care actualizează o bază de date pornind de la datele introduse de utilizator într-un tabel. Observaţie! Cu programele Java care rulează pe calculatorul nostru se poate lucra cu bazele de date care se află pe server! Este ceva Stabiliţi corespondenţa dintre elementele din stânga şi cele din dreapta: 1) gestionar de poziţionare; a) ataşează componente; 2) container; b) răspunde la evenimente; 3) ascultător de evenimente. c) poziţionează componentele. 2. Stabiliţi corespondenţa dintre coloanele din stânga şi cele din dreapta: 1) JPanel; a) mesaj lămuritor; 2) JButton; b) dă o comandă; 3) JTextField; c) mai multe şiruri; 4) JLabel; d) selectează o singură opţiune; 5) JComboBox; e) grupează mai multe componente; 6) JTextArea; f) pentru selecţii multiple; 7) JcheckBox. g) citeşte un şir de caractere.

364 364 Manual de Informatică pentru clasa a XII-a 3. Scrieţi un program în care o fereastră afişează un buton. La apăsarea butonului, programul va afişa în fereastra CMD rezoluţia ecranului. 4. Scrieţi un program în care o fereastră afişează două butoane: Buton 1 şi Buton 2. Ştiind că metoda boolean isenabled() a clasei JComponent returnează true dacă butonul este activ şi false, în caz contrar. Faceţi în aşa fel încât, la apăsarea primului buton, dacă al doilea buton este activ să devină inactiv şi invers, dacă este inactiv să devină activ. Figura Fereastra propusă Indicaţie! Pentru a face un buton activ/inactiv se foloseşte metoda setenabled(true/false). 5. Cum se poate ca o fereastră să afişeze cinci butoane, precum cea de mai jos? Figura Fereastra propusă 6. Se ştie că pentru a citi o parolă se utilizează o componentă de tip JPasswordField (clasă care are ca superclasă pe JTextField). Se ştie de asemenea, că pentru o componentă de tip JPasswordField, metoda gettext() este depreciată şi în locul ei se utilizează metoda: char[] getpassword(). Se cere ca programul dvs. să citească o parolă şi să afişeze OK dacă parola introdusă este şirul Mama şi NO, în caz contrar. Figura Exemplu 7. Realizaţi un program în care într-un edit să se poată introduce numere prin apăsarea unor butoane, ca alăturat. Extindeţi apoi programul pentru simularea unui calculator de buzunar. Figura Exemplu 8. Să se scrie un program care conţine trei metode prin care se determină dacă un număr natural n citit este prim sau nu. Prima dintre ele testează toţi divizorii numărului de la 2 la n-1, a doua divizorii de la 2 la n / 2, a treia de la 2 la n.

365 Capitolul 8. Programare vizuală 365 Pentru citirea numărului, fereastra va conţine o etichetă şi un edit, pentru selectarea algoritmului se va utiliza o listă, iar după introducerea numărului şi selectarea algoritmului, un buton va declanşa prelucrarea corespunzătoare. 9. Programul dvs. va efectua o copie a unui fişier text. Numele fişierului care se copiază va fi introdus într-un edit, iar numele fişierului destinaţie în alt edit. 10. Scrieţi un program care generează un fişier text cu n numere naturale. Valoarea lui n va fi introdusă cu ajutorul unui edit. 11. Scrieţi un program care creează, pornind de la fişierul anterior, un altul care conţine aceleaşi numere, dar sortate crescător. Se vor implementa mai mulţi algoritmi de sortare, iar selecţia celui care va sorta fişierul se va face cu ajutorul unei liste aflată pe fereastra principală. 12. Scrieţi un program care citeşte două numere reale. Programul va putea afişa suma, diferenţa, produsul şi câtul lor. Operaţia care se efectuează se va selecta dintr-un meniu. Rezultatul va fi afişat cu ajutorul unor cutii de dialog predefinite. 13. Creaţi un fişier text în care fiecare linie să conţină numele unei persoane şi vârsta ei. Datele se introduc secvenţial. Pentru a le introduce, o fereastră va avea ataşate două edit-uri (unul pentru nume şi altul pentru vârstă) şi un buton. La apăsarea butonului se va efectua validarea datelor (alfabetic pentru nume şi un număr natural între 1 şi 99 pentru vârstă). 14. Adăugaţi o listă ferestrei de la problema precedentă din care să se poată selecta mai multe opţiuni, în urma cărora programul va putea afişa: a) media vârstelor persoanelor a căror date au fost trecute în fişier; b) numărul de persoane care au datele trecute în fişier. 15. Scrieţi un program care afişează şi actualizează fişierul creat la problema 13. Pentru a realiza operaţiile propuse se va utiliza o componentă de tip JTextArea, iar operaţiile Open, Save şi Save As se vor selecta dintr-un meniu. 16. Scrieţi un program care generează un fişier text care conţine cel puţin numere naturale aleatoare. Apoi, scrieţi un alt program care sortează fişierul prin utilizarea mai multor metode de sortare. Metoda de sortare se va selecta dintr-o listă. La fiecare sortare, se va estima timpul rămas prin utilizarea unei componente de tip JProgressBar. 17. Scrieţi un program în care o componentă de tip JTextArea afişează un text preluat dintr-un fişier text dat. Se cere să se seteze font-ul şi mărimea lui prin selectarea lor din două liste. 18. Scrieţi un program în care se creează şi se actualizează un fişier text. Textul se introduce cu ajutorul unei componente de tip JTextArea. Pentru deschiderea fişierului şi salvarea lui, se utilizează cutii de dialog de tip Open / Save apelabile dintr-un meniu.

366 366 Manual de Informatică pentru clasa a XII-a 19. Completaţi programul anterior astfel încât culoarea suprafeţei componentei de tip JTextArea să poată fi selectată cu ajutorul unei componente de tip JColorChooser, apelabilă cu ajutorul unui buton aflat pe bara de unelte. De asemenea, fontul va fi selectat dintr-o listă, iar mărimea lui cu ajutorul unei componente de tip JSpinner, ambele aflate pe bara cu unelte (componentă de tip JToolBar). 20. Realizaţi un scurt referat despre tipul de aplicaţie Java numit applet. (pentru verificare, rezolvările se găsesc la pag. 384) Următoarele aplicaţii se vor realiza în colective formate din câte 5 elevi. Fiecare problemă rezolvată va fi însoţită de documentaţie. După ce o echipă rezolvă o problemă, predă documentaţia unei alte echipe, care pe baza ei va prezenta aplicaţia în faţa clasei. Este esenţial ca documentaţia să fie clară, astfel încât pe baza ei oricine să poată rula aplicaţia. O echipă poate fi alcătuită din: - 1 proiectant al bazelor de date (dacă este cazul); - 1 designer; - 3 programatori. 1. X şi 0. Toată lumea cunoaşte acest joc, asta e sigur! Realizaţi o interfaţă grafică prin care să poată fi jucat de către două persoane. Ca idee: trebuie să aveţi o comandă care să permită resetarea jocului; să se indice momentul în care unul dintre jucători a câştigat runda; alternativ, să se afişeze numele jucătorului care este la mutare; să fie disponibil un top al celor mai iscusiţi utilizatori, etc. 2. Dame. Scrieţi un program care afişează toate soluţiile pentru problema celor n dame. În exemplu, se consideră n=8. După afişarea unei soluţii, pentru a fi afişată următoarea soluţie, se va apăsa un buton. Pentru afişare, veţi utiliza o componentă de tip JTable. 3. Refaceţi proiectele de la finalul părţii a doua, realizând interfeţe grafice în Java care să permită accesul la informaţiile reţinute în bazele de date corespunzătoare. 4. Alegeţi o bază de date pe care a-ţi studiat-o pe parcursul acestui manual şi realizaţi o aplicaţie completă, care să permită accesul fie prin intermediul Internetului, fie printr-un program implementat în Java.

367 ANEXA 1 Instalarea programelor Apache, PHP şi MySQL Vom instala programele amintite pe calculatorul nostru, având, astfel, posibilitatea să le studiem fară să fim conectaţi la Internet. În ipoteza în care am învăţat să le folosim şi dorim să construim un site web, atunci vom închiria spaţiu pe server şi acolo vom transfera script-urile realizate pe propriul calculator. Toate programele amintite se găsesc în pachetul EasyPHP, iar instalarea lor se reduce la instalarea lui, care este, de altfel, gratuit. Pachetul conţine: Apache, PHP, MySQL şi PhpMyAdmin (ultimul conţine script-uri PHP prin care se facilitează lucrul cu MySQL). Adresa de unde poate fi descărcat pachetul este: 1. Se download-ează un executabil care, apelat, va instala programele din pachet (alegeţi opţiunile implicite). Executabilul download-at de noi este easyphp1-8_setup.exe. În urma rulării acestuia, se creează în Programa Files folder-ul EasyPHP1-8 care conţine programele din pachet. 2. Pentru a configura PhpMyAdmin se procedează astfel: 2.1. În folder-ul EasyPHP1-8 se găseşte directorul phpmyadmin. Acesta se copiază în folder-ul www (tot din EasyPHP1-8 ) În phpmyadmin se găseşte fişierul config.inc.php. Se execută dublu clic asupra sa şi în acest fel, datorită extensiei sale, este apelat browser-ul (Internet Explorer) care îl deschide. Pentru că dorim să-l modificăm, trebuie să vizualizăm sursa sa (fişierul aşa cum este, nu interpretat de către browser). Prin urmare, din meniul browser-ului vom selecta View şi Source. Astfel, va fi apelat programul Notepad care afişează sursa Cu opţiunea Find, căutaţi linia cfg['servers'][$i]['auth_type']. Observaţi că după acest şir de caractere găsiţi = config. În loc de = config veţi scrie = cookie Căutaţi şirul $cfg['blowfish_secret']. După acest şir se găseşte =. Înlocuiţi = cu un şir de caractere la alegerea dvs., de exemplu = vlad Salvaţi modificările Apelaţi adresa În acest fel este apelat fişierul index din directorul phpmyadmin ( index.php ). Trebuie să apară ce vedeţi în figura următoare:

368 368 Manual de Informatică pentru clasa a XII-a Numele de utilizator este root. Fără a introduce parola, apăsaţi butonul Autentificare. Se va afişa ce vedeţi alăturat: Figura A1.1. Pagina de autentificare pentru phpmyadmin Execuaţi dublu-clic pe link-ul Schimbare parola şi adăugaţi parola dorită (vezi Fig. A1.3). Din acest moment, phpmyadmin se poate apela prin Desigur, de fiecare dată se va intoduce parola pe care aţi hotarât să o aveţi. Observaţii! Figura A1.2. Pagina de administrare phpmyadmin Figura A1.3. Pagina de schimbare a parolei 1) De acum, am instalat pe calculatorul nostru software-ul de server. 2) Programele amintite pot fi instalate şi separat, dar mult mai complicat. Având în vedere scopul nostru exclusiv didactic, pachetul EasyPHP este soluţia ideală. 3) Pentru a utiliza acest software, introduceţi fişierul index în subfolder-ul www al pachetului şi apelaţi-l din browser prin Indexul poate avea extensia html sau php. Înainte de a efectua astfel de apeluri, trebuie lansat programul EasyPHP. Deschiderea lui se va face din meniul Start/Programs.

Microsoft Word - Curs_09.doc

Microsoft Word - Curs_09.doc Capitolul 7. Proiectarea conceptuală Scop: reprezentarea cerinţelor informale ale aplicaţiei în termenii descrierii complete şi formale dar independent de criteriul folosit pentru reprezentare în sistemul

Mai mult

Microsoft Word - Curs_08.doc

Microsoft Word - Curs_08.doc Partea a II-a. Proiectarea bazelor de date Capitolul 6. Tehnici de proiectare şi modele În capitolele precedente s-au analizat modele de baze de date şi limbaje, presupunând în cele mai multe cazuri că

Mai mult

Microsoft Word - Curs_10.doc

Microsoft Word - Curs_10.doc Capitolul 8. Proiectarea logică Scop - construirea unei scheme logice ce reprezintă corect şi eficient toate informaţiile descrise într-o schemă entitate-relaţie Etape: Restructurarea schemei E-R fază

Mai mult

Aggregating Data

Aggregating Data Subinterogări. Subinterogări multi-row. Formatarea rezultatelor unei interogări Obiective Prin parcurgerea acestui referat studentul va dobândi cunoştinţele necesare: identificării funcţiilor grup disponibile;

Mai mult

Logică și structuri discrete Limbaje regulate și automate Marius Minea marius/curs/lsd/ 24 noiembrie 2014

Logică și structuri discrete Limbaje regulate și automate Marius Minea   marius/curs/lsd/ 24 noiembrie 2014 Logică și structuri discrete Limbaje regulate și automate Marius Minea marius@cs.upt.ro http://www.cs.upt.ro/ marius/curs/lsd/ 24 noiembrie 2014 Un exemplu: automatul de cafea acțiuni (utilizator): introdu

Mai mult

Baze de date Anul 2 Teorie Examen 1. Diagrama entitate/relatie si diagrama conceptuala (curs 2-5) 2. Arbore algebric si expresie algebrica (curs 6-10)

Baze de date Anul 2 Teorie Examen 1. Diagrama entitate/relatie si diagrama conceptuala (curs 2-5) 2. Arbore algebric si expresie algebrica (curs 6-10) Baze de date Anul 2 Teorie Examen 1. Diagrama entitate/relatie si diagrama conceptuala (curs 2-5) 2. Arbore algebric si expresie algebrica (curs 6-10) 3. Forme normale (curs 6-10) 4. Notiuni teoretice

Mai mult

Microsoft Word - Curs_07.doc

Microsoft Word - Curs_07.doc 5.3 Modificarea datelor în SQL Pentru modificarea conţinutului unei baze de date SQL pune la dispoziţie instrucţiunile insert, delete şi update. 5.3.1 Inserări în baza de date Sintaxa instrucţiunii insert

Mai mult

proiectarea bazelor de date

proiectarea bazelor de date Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie şi Dezvoltare Durabilă Departamentul de Automatică, Energie, Mediu şi Dezvoltare Durabilă Proiectarea bazelor de date Lect.dr. Adrian

Mai mult

PHP (II)

PHP (II) PHP şi MySQL Bazele de date sunt colecţii de date, aranjate într-o anumită formă Operaţii : - Crearea bazei de date; - Conectarea la baza de date; - Inserarea datelor in baza de date; - Ștergerea datelor

Mai mult

UNIVERSITATEA DIN CRAIOVA Facultatea de Economie şi Administrarea Afacerilor Str. A.I. Cuza nr.13, cod Tel./Fax:

UNIVERSITATEA DIN CRAIOVA Facultatea de Economie şi Administrarea Afacerilor Str. A.I. Cuza nr.13, cod Tel./Fax: UNIVERSITATEA DIN CRAIOVA Facultatea de Economie şi Administrarea Afacerilor Str. A.I. Cuza nr.13, cod 200585 Tel./Fax: +40251 411317 http://feaa.ucv.ro GHID PRIVIND ORGANIZAREA ŞI DESFĂŞURAREA EXAMENULUI

Mai mult

Laborator 3

Laborator 3 Laborator 3 Programare III săptămâna 8-12.10.2018 OBIECTIVE: - Folosirea modificatorilor unei clase (public, abstract, final) - Folosirea modificatorilor de acces în declaraţiile membrilor unei clase Noţiuni:

Mai mult

PowerPoint Presentation

PowerPoint Presentation Proiectarea bazelor de date 5 Proiectarea bazelor de date Proiectare conceptuală (ex. diagrama de clase) Identificarea entităţilor şi a relaţiilor dintre ele Proiectarea logică Transformarea modelului

Mai mult

Baze de date

Baze de date BAZE DE DATE BAZA DE DATE RELAŢIONALĂ Chiar dacă F.E. Codd, ca matematician, a construit un model riguros, cu concepte matematice, baza de date relaţională este percepută de utilizatorii săi ca o colecţie

Mai mult

Subiectul 1

Subiectul 1 Subiectul 1 În fişierul Numere.txt pe prima linie este memorat un număr natural n (n

Mai mult

Addendum Syllabus 6 Microsoft Access 2016 REF Syllabus 6.0 Cunoașterea domeniilor în care se utilizează bazele de date Datorită potenţialului ma

Addendum Syllabus 6 Microsoft Access 2016 REF Syllabus 6.0 Cunoașterea domeniilor în care se utilizează bazele de date Datorită potenţialului ma REF 1.1.5 Syllabus 6.0 Cunoașterea domeniilor în care se utilizează bazele de date Datorită potenţialului mare de eficientizare a muncii, bazele de date îşi găsesc aplicaţii în diverse domenii: - transporturi

Mai mult

Microsoft Word - Fisa disciplinei BD_I_IE doc

Microsoft Word - Fisa disciplinei BD_I_IE doc FIŞA DISCIPLINEI 1. Date despre program 1.1 Instituţia de învăţământ superior Universitatea Alexandru Ioan Cuza din Iaşi 1.2 Facultatea Facultatea de Economie şi Administrarea Afacerilor 1.3 Departamentul

Mai mult

Laborator 4: Continuare Programare Orientată pe Obiecte Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 29 octombrie 2011

Laborator 4: Continuare Programare Orientată pe Obiecte Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 29 octombrie 2011 Laborator 4: Continuare Programare Orientată pe Obiecte Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 29 octombrie 2011 I. NOŢIUNI TEORETICE A. Suprascrierea metodelor O clasă derivată

Mai mult

Managementul Resurselor Umane

Managementul Resurselor Umane Universitatea Politehnica București Catedra de Calculatoare Laborator 4 Cereri SQL Autori Conf. Dr. Ing. Alexandru Boicea Ș.L. Dr. Ing. Ciprian-Octavian Truică Cuprins Cereri SQL Cereri simple 10.03.2019

Mai mult

EXCEL FĂRĂ SECRETE Grafice şi diagrame

EXCEL FĂRĂ SECRETE Grafice şi diagrame EXCEL FĂRĂ SECRETE Grafice şi diagrame Cuprins 1. Introducere... 3 2. Crearea graficelor în Excel... 3 3. Mutarea şi copierea graficelor... 11 2 EXCEL FĂRĂ SECRETE- Grafice şi diagrame 1. Introducere Informaţiile

Mai mult

Evaluarea unităţilor de dializă publice si private

Evaluarea unităţilor de dializă publice si private SISTEM INFORMATIC UNIC INTEGRAT AL ASIGURĂRILOR DE SĂNĂTATE DIN ROMÂNIA Evaluarea unităţilor de dializă publice si private Manual de referinţă Versiune document: 1.2 RELEASED Creat: 02.08.2007 Ultima actualizare:

Mai mult

Laborator 9: Fire de execuţie Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 20 noiembrie 2011

Laborator 9: Fire de execuţie Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 20 noiembrie 2011 Laborator 9: Fire de execuţie Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 20 noiembrie 2011 I. NOŢIUNI TEORETICE A. Ce este un fir de execuţie? Înainte de a defini conceptul de fir

Mai mult

FD Informatica

FD Informatica 1. Date despre program 1.1. Instituţia de învăţământ superior FIŞA DISCIPLINEI Universitatea Spiru Haret, Bucureşti 1.2. Facultatea Ştiinţe Economice 1.3. Departamentul Ştiinţe Economice 1.4. Domeniul

Mai mult

Atestat 2007

Atestat 2007 Cerinţe generale: 1. numele tabelei se va alege de către elev într-un mod corespunzator problemei 2. numele şi tipul câmpurilor tabelei se vor stabili de către elev în conformitate cu cerinţele din enunţ

Mai mult

PROGRAMARE ORIENTATA PE OBIECTE

PROGRAMARE ORIENTATA PE OBIECTE Curs 2 Principiile Programării Orientate pe Obiecte Programare Orientată pe Obiecte Tehnici de programare Programarea procedurală Modul în care este abordată programarea, din punct de vedere al descompunerii

Mai mult

Capitole Speciale de Informatică Curs 1: Extragerea informaţiilor. Modelul boolean şi modelul boolean extins 27 septembrie 2018 Extragerea informaţiil

Capitole Speciale de Informatică Curs 1: Extragerea informaţiilor. Modelul boolean şi modelul boolean extins 27 septembrie 2018 Extragerea informaţiil Capitole Speciale de Informatică Curs 1: Extragerea informaţiilor. Modelul boolean şi modelul boolean extins 27 septembrie 2018 Extragerea informaţiilor (engl. Information Retrieval, IR) constă în găsirea

Mai mult

Информационная система персонализации, печати и учета документов об образовании

Информационная система персонализации, печати и учета документов об образовании Sistemul Informaţional Personalizare a Actelor de Studii (SIPAS) 2018-2019 Contacte http://www.ctice.md:8088/gimnaziul Telefon : (022) 44-32-37 actedestudii@ctice.gov.md Conţinutul 1 2 3 4 Locul de muncă

Mai mult

programă şcolară pentru clasa a 11a, liceu

programă şcolară pentru clasa a 11a, liceu Anexă la OMECI nr. 5099 din 09.09.2009 MINISTERUL EDUCAŢIEI, CERCETĂRII ŞI INOVĂRII PROGRAME ŞCOLARE TEHNOLOGIA INFORMAŢIEI ŞI A COMUNICAŢIILOR (Sisteme de gestiune a bazelor de date) CLASA A XII-A CICLUL

Mai mult

CL2009R0976RO bi_cp 1..1

CL2009R0976RO bi_cp 1..1 2009R0976 RO 31.12.2014 002.001 1 Acest document reprezintă un instrument de documentare, iar instituţiile nu îşi asumă responsabilitatea pentru conţinutul său. B REGULAMENTUL (CE) NR. 976/2009 AL COMISIEI

Mai mult

Limbaje de Programare Curs 6 – Functii de intrare-iesire

Limbaje de Programare   Curs 6 – Functii de intrare-iesire Limbaje de Programare Curs 6 Funcţii de intrare-ieşire Dr. Casandra Holotescu Universitatea Politehnica Timişoara Ce discutăm azi... 1 Citire formatată 2 Citirea şirurilor de caractere 3 Citirea unor linii

Mai mult

Proiectarea Sistemelor Software Complexe

Proiectarea Sistemelor Software Complexe Proiectarea Sistemelor Software Complexe Curs 4 Arhitecturi de Sistem Software Bazate pe Tehnologii Middleware. Obiecte Distribuite. Rolul unui arhitect software este foarte asemănător cu cel al unui arhitect

Mai mult

Microsoft Word - O problema cu bits.doc

Microsoft Word - O problema cu bits.doc O problemă cu bits 1 Tiberiu Socaciu Enunţul Pe pagina Proful de Mate de pe Facebook 2 am primit de la un elev de clasa a IX-a următoarea provocare 3 : Vom oferi două soluţii, una folosind manipulări de

Mai mult

ALGORITMII ŞI REPREZENTAREA LOR Noţiunea de algoritm Noţiunea de algoritm este foarte veche. Ea a fost introdusă în secolele VIII-IX de către Abu Ja f

ALGORITMII ŞI REPREZENTAREA LOR Noţiunea de algoritm Noţiunea de algoritm este foarte veche. Ea a fost introdusă în secolele VIII-IX de către Abu Ja f ALGORITMII ŞI REPREZENTAREA LOR Noţiunea de algoritm Noţiunea de algoritm este foarte veche. Ea a fost introdusă în secolele VIII-IX de către Abu Ja far Mohammed ibn Musâ al- Khowârizmî în cartea sa intitulată

Mai mult

Microsoft Word - lab_access.doc

Microsoft Word - lab_access.doc Fişa de lucru nr. 1 2. Creaţi o bază de date nouă în directorul My Documents. Salvaţi-o cu numele vostru. 3. Creaţi o tabelă cu următoarele câmpuri: CNP Number-Double NUME Text de dimensiune 50 DATA Date/Time-Medium

Mai mult

E_d_Informatica_sp_MI_2015_bar_02_LRO

E_d_Informatica_sp_MI_2015_bar_02_LRO Examenul de bacalaureat naţional 2015 Proba E. d) Informatică Varianta 2 Filiera teoretică, profilul real, specializările: matematică-informatică matematică-informatică intensiv informatică Toate subiectele

Mai mult

Utilizare Internet

Utilizare Internet Curs 14 2014/2015 1 Functionalitate La toate temele 1p din nota este obtinut de indeplinirea functionalitatii cerute. orice tehnologie, orice metoda, sa faca ceea ce trebuie Forma paginii prezinta importanta

Mai mult

E_d_Informatica_sp_SN_2014_bar_10_LRO

E_d_Informatica_sp_SN_2014_bar_10_LRO Examenul de bacalaureat naţional 2014 Proba E. d) Informatică Varianta 10 Toate subiectele sunt obligatorii. Se acordă 10 puncte din oficiu. Timpul de lucru efectiv este de 3 ore. În rezolvările cerute,

Mai mult

Anexa nr. 2 FIŞA DISCIPLINEI 1. Date despre program 1.1 Instituţia de învăţământ superior UNIVERSITATEA DE VEST TIMISOARA 1.2 Facultatea FIZICA 1.3 De

Anexa nr. 2 FIŞA DISCIPLINEI 1. Date despre program 1.1 Instituţia de învăţământ superior UNIVERSITATEA DE VEST TIMISOARA 1.2 Facultatea FIZICA 1.3 De Anexa nr. 2 FIŞA DISCIPLINEI 1. Date despre program 1.1 Instituţia de învăţământ superior UNIVERSITATEA DE VEST TIMISOARA 1.2 Facultatea FIZICA 1.3 Departamentul FIZICA 1.4 Domeniul de studii FIZICA 1.5

Mai mult

2 BAZE TEORETICE ALE REȚELELOR DE CALCULATOARE CAPITOLUL 2 BAZE TEORETICE ALE REŢELELOR DE CALCULATOARE 2.1. Necesitatea standardizării (referenţierii

2 BAZE TEORETICE ALE REȚELELOR DE CALCULATOARE CAPITOLUL 2 BAZE TEORETICE ALE REŢELELOR DE CALCULATOARE 2.1. Necesitatea standardizării (referenţierii CAPITOLUL 2 BAZE TEORETICE ALE REŢELELOR DE CALCULATOARE 2.1. Necesitatea standardizării (referenţierii) reţelelor de calculatoare După cum am precizat în capitolul anterior, din punct de vedere fizic

Mai mult

Microsoft Word - TIC_tehnoredactare_12.doc

Microsoft Word - TIC_tehnoredactare_12.doc Anexa nr. la ordinul ministrului educaţiei, cercetării şi inovării nr. /. MINISTERUL EDUCAŢIEI, CERCETĂRII ŞI INOVĂRII PROGRAME ŞCOLARE TEHNOLOGIA INFORMAŢIEI ŞI A COMUNICAŢIILOR (Tehnoredactare asistată

Mai mult

Prezentarea calculatorului

Prezentarea calculatorului Universitatea Constantin Brâncuşi din Târgu-Jiu Facultatea de Inginerie şi Dezvoltare Durabilă Departamentul de Automatică, Energie, Mediu şi Dezvoltare Durabilă Baze de date Lect.dr. Adrian Runceanu Curs

Mai mult

Chertif Ionuț - Andrei Prietenul meu, calculatorul CLASA a V - a, 1 ora pe săptămână ARGUMENT Transformările societăţii româneşti din ultimii ani, dez

Chertif Ionuț - Andrei Prietenul meu, calculatorul CLASA a V - a, 1 ora pe săptămână ARGUMENT Transformările societăţii româneşti din ultimii ani, dez Prietenul meu, ul CLASA a V - a, ora pe săptămână ARGUMENT Transformările societăţii româneşti din ultimii ani, dezvoltarea şi răspândirea informaticii, impun o pregătire diversificată a tinerilor în acest

Mai mult

Microsoft Word - CarteC.doc

Microsoft Word - CarteC.doc Transmiterea parametrilor unei funcții Parametrii se transmit de la funcţia apelantă la funcţia apelată prin intermediul stivei. La apelul unei funcţii, pe stivă se crează o înregistrare de activare, care

Mai mult

MergedFile

MergedFile PROIECT DIDACTIC Clasa a VI-a Matematică Proiect didactic realizat de Nicoleta Popa, profesor Digitaliada, revizuit de Ioan Popa, profesor Digitaliada Textul și ilustrațiile din acest document începând

Mai mult

Facultatea de Științe Politice, Administrative și ale Comunicării Str. Traian Moșoiu nr. 71 Cluj-Napoca, RO Tel.: Fax:

Facultatea de Științe Politice, Administrative și ale Comunicării Str. Traian Moșoiu nr. 71 Cluj-Napoca, RO Tel.: Fax: Documentație pentru accesarea platformei e-learning de către studenți Pentru facilitarea demersurilor necesare bunei desfășurări a cursurilor se folosește platforma de e-learning a facultății (care se

Mai mult

Instructiuni licenta - 2

Instructiuni licenta - 2 Coperta, prima pagină ale Proiectului de Diplomă şi instrucţiuni de redactare 1. Conţinutul celor două pagini a) Coperta va conţine următoarele informaţii: - universitatea: Universitatea Politehnica din

Mai mult

G.I.S. Curs 3

G.I.S. Curs 3 G.I.S. Curs 3 Geogafia Mediului 1.04.2014 Dr. Constantin Nistor Formatul de date vectorial Datele vectoriale descriu lumea sub forma unui spaţiu populat de linii în variate aspecte şi feluri: puncte, linii,

Mai mult

CASA CORPULUI DIDACTIC BRAILA PROGRAM DE FORMARE INFORMATICA SI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: TIMOFTI V. AFRODITA COLEGIUL

CASA CORPULUI DIDACTIC BRAILA PROGRAM DE FORMARE INFORMATICA SI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: TIMOFTI V. AFRODITA COLEGIUL CASA CORPULUI DIDACTIC BRAILA PROGRAM DE FORMARE INFORMATICA SI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: TIMOFTI V. AFRODITA COLEGIUL NATIONAL VASILE ALECSANDRI, BACAU TIMOFTI AFRODITA

Mai mult

Fâciu N. Maria-Ema CASA CORPULUI DIDACTIC BRĂILA PROGRAM DE FORMARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: Fâciu N. M

Fâciu N. Maria-Ema CASA CORPULUI DIDACTIC BRĂILA PROGRAM DE FORMARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: Fâciu N. M CASA CORPULUI DIDACTIC BRĂILA PROGRAM DE FORMARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: PROIECTUL UNITĂŢII DE ÎNVĂŢARE ALGORITMI Notă: filmele didactice, dezbaterile, jocurile

Mai mult

1

1 1. Se consideră o bază de date în care se reţine evidenţa cărţilor dintr-o librarie. Pentru fiecare carte se cunosc următoarele informaţii: titlu, autor, editura, an N(4), preţ N(7). Realizaţi o Introducerea

Mai mult

PowerPoint Presentation

PowerPoint Presentation Expertiză. Competenţă ştiinţifică. Stabilitate. Seriozitate. Evaluări la nivel naţional 2014 Livia ŢOCA Examene şi concursuri naţionale 2014 Evaluări la nivel naţional, 2014 bacalaureat Simulare proba

Mai mult

Dorel LUCHIAN Gabriel POPA Adrian ZANOSCHI Gheorghe IUREA algebră geometrie clasa a VIII-a ediţia a V-a, revizuită mate 2000 standard EDITURA PARALELA

Dorel LUCHIAN Gabriel POPA Adrian ZANOSCHI Gheorghe IUREA algebră geometrie clasa a VIII-a ediţia a V-a, revizuită mate 2000 standard EDITURA PARALELA Dorel LUCHIAN Gabriel POPA Adrian ZANOSCHI Gheorghe IUREA algebră geometrie clasa a VIII-a ediţia a V-a, revizuită mate 000 standard 3 10 PP Algebră Capitolul I. NUMERE REALE Competenţe specifice: Determinarea

Mai mult

Capitole Speciale de Informatică Curs 4: Calculul scorurilor în un sistem complet de extragere a informaţiilor 18 octombrie 2018 Reamintim că în cursu

Capitole Speciale de Informatică Curs 4: Calculul scorurilor în un sistem complet de extragere a informaţiilor 18 octombrie 2018 Reamintim că în cursu Capitole Speciale de Informatică Curs 4: Calculul scorurilor în un sistem complet de extragere a informaţiilor 18 octombrie 2018 Reamintim că în cursul precedent am prezentat modelul de spaţiu vectorial

Mai mult

Utilizarea Internetului in Afaceri FSEGA, UBB Lect.univ.dr. Daniel Mican LABORATOR 4. Dezvoltarea site-urilor si blog-uri

Utilizarea Internetului in Afaceri FSEGA, UBB Lect.univ.dr. Daniel Mican LABORATOR 4. Dezvoltarea site-urilor si blog-uri LABORATOR 4. Dezvoltarea site-urilor si blog-urilor prin intermediul CMS-ului WordPress PREZENTAREA LUCRARII DE LABORATOR Lucrarea de laborator isi propune sa prezinte modul de creare a site-urilor si

Mai mult

1. Găsiți k numerele cele mai apropiate într-un şir nesortat Dându-se un şir nesortat și două numere x și k, găsiți k cele mai apropiate valori de x.

1. Găsiți k numerele cele mai apropiate într-un şir nesortat Dându-se un şir nesortat și două numere x și k, găsiți k cele mai apropiate valori de x. 1. Găsiți k numerele cele mai apropiate într-un şir nesortat Dându-se un şir nesortat și două numere x și k, găsiți k cele mai apropiate valori de x. Date de intrare: arr [] = {10, 2, 14, 4, 7, 6}, x =

Mai mult

GHERCĂ MAGDA CASA CORPULUI DIDACTIC BRĂILA PORTOFOLIU EVALUARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A Neamț SERIA 1 GRUPA 1 CURSANT: GHERCĂ G

GHERCĂ MAGDA CASA CORPULUI DIDACTIC BRĂILA PORTOFOLIU EVALUARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A Neamț SERIA 1 GRUPA 1 CURSANT: GHERCĂ G CASA CORPULUI DIDACTIC BRĂILA PORTOFOLIU EVALUARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A Neamț SERIA 1 GRUPA 1 CURSANT: GHERCĂ G MAGDA COLEGIUL NAŢIONAL ROMAN-VODĂ ROMAN PROIECTUL UNITĂŢII DE ÎNVĂŢARE

Mai mult

(Microsoft PowerPoint SIBIUEVIDENTA [Doar \356n citire])

(Microsoft PowerPoint SIBIUEVIDENTA [Doar \356n citire]) SECŢIUNEA ACHIZIŢII ŞI DEZVOLTAREA COLECŢIILOR BIBLIOTECA CENTRALĂ A UNIVERSITĂŢII LUCIAN BLAGA SIBIU 2010 E-PUBLICAŢII ŞI EVIDENŢELE DE BIBLIOTECĂ NOUA INTERFAŢĂ A BIBLIOTECII MAI ADECVATĂ TEHNOLOGIILOR

Mai mult

1. Operatii cu matrici 1 Cerinte: Sa se realizeze functii pentru operatii cu matrici patratice (de dimensiune maxima 10x10). Operatiile cerute sunt: A

1. Operatii cu matrici 1 Cerinte: Sa se realizeze functii pentru operatii cu matrici patratice (de dimensiune maxima 10x10). Operatiile cerute sunt: A 1. Operatii cu matrici 1 Sa se realizeze functii pentru operatii cu matrici patratice (de dimensiune maxima 10x10). Operatiile cerute sunt: A+B (adunare), aa (inmultire cu scalar), A-B scadere), AT (Transpusa),

Mai mult

manual_ARACIS_evaluare_experti_v5

manual_ARACIS_evaluare_experti_v5 PLATFORMĂ DE EVALUARE ONLINE PENTRU EXPERȚII ARACIS Page 1 CUPRINS Cap 1. Procesul de evaluare 3 Cap 2. Procedura de înregistrare și evaluare 3 cap 3. Instrucțiuni de completare a formularului de înregistrare

Mai mult

Microsoft Word - BAC sociologie

Microsoft Word - BAC sociologie Colecţia SUBIECTE POSIBILE Editura Paralela 45 Lucrarea este elaborată conform programei şcolare în vigoare pentru bacalaureat. Redactare: Daniel Mitran Tehnoredactare: Iuliana Ene Pregătire de tipar &

Mai mult

Microsoft Word - Ansamblul software CRONIS

Microsoft Word - Ansamblul software CRONIS Ansamblul software CRONIS este un sistem decizional multiagent pentru generarea, optimizarea şi managementul RRBCN/RNBCN pornind de la un set de date medicale complexe, rezultate din entități medicale

Mai mult

Web Social FSEGA, UBB Lect.univ.dr. Daniel Mican LABORATOR 2. Dezvoltarea blogurilor prin intermediul WordPress.com PREZE

Web Social FSEGA, UBB Lect.univ.dr. Daniel Mican LABORATOR 2. Dezvoltarea blogurilor prin intermediul WordPress.com PREZE LABORATOR 2. Dezvoltarea blogurilor prin intermediul WordPress.com PREZENTAREA LUCRARII DE LABORATOR Lucrarea de laborator isi propune sa prezinte modul de creare a blogurilor cu wordpress.com. WordPress

Mai mult

INFORMATICĂ ŞI MARKETING

INFORMATICĂ ŞI MARKETING CUPRINS CAPITOLUL 1... 7 UTILIZAREA CONCEPTELOR ŞI INSTRUMENTELOR TEHNOLOGIILOR INFORMAŢIEI ŞI COMUNICAŢIEI ÎN ACTIVITATEA DE MARKETING... 7 1.1 IMPACTUL TEHNOLOGIILOR INFORMAŢIEI ŞI COMUNICAŢIEI ASUPRA

Mai mult

Testare manuala: situatia in care o persoana initiaza fiecare test, interactioneaza cu el si interpreteaza, analizeaza si raporteaza rezultatele. Test

Testare manuala: situatia in care o persoana initiaza fiecare test, interactioneaza cu el si interpreteaza, analizeaza si raporteaza rezultatele. Test Testare manuala: situatia in care o persoana initiaza fiecare test, interactioneaza cu el si interpreteaza, analizeaza si raporteaza rezultatele. Testare automata: exista un mecanism pentru executia fara

Mai mult

Problema 1 Pentru informatizarea activităţii de tranzacţionare a titlurilor de valoarea se cunoaşte că un client este identificat prin CNP, nume, pren

Problema 1 Pentru informatizarea activităţii de tranzacţionare a titlurilor de valoarea se cunoaşte că un client este identificat prin CNP, nume, pren Problema 1 Pentru informatizarea activităţii de tranzacţionare a titlurilor de valoarea se cunoaşte că un client este identificat prin CNP, nume, prenume, adresă şi număr de telefon. Clienţi deţin un număr

Mai mult

PowerPoint Presentation

PowerPoint Presentation Forme Normale 4 Redundanţa Redundanţa este cauza principală a majorităţii problemelor legate de structura bazelor de date relaţionale: spaţiu utilizat, anomalii de inserare / stergere / actualizare. Redundanţa

Mai mult

PROGRAMA DE EXAMEN

PROGRAMA DE EXAMEN CENTRUL NAŢIONAL DE EVALUARE ŞI EXAMINARE PROGRAMA DE EXAMEN PENTRU EVALUAREA COMPETENŢELOR DIGITALE EXAMENUL DE BACALAUREAT 2014 PROGRAMA DE EXAMEN PENTRU EVALUAREA COMPETENŢELOR DIGITALE I. STATUTUL

Mai mult

Microsoft Word - 6 FD_Informatica SGBD II CIG 2017.doc

Microsoft Word - 6 FD_Informatica SGBD II CIG 2017.doc FIŞA DISCIPLINEI 1. Date despre program 1.1.Instituţia de învăţământ superior 1.2.Facultatea 1.3.Departamentul 1.4.Domeniul de studii 1.5.Ciclul de studii 1.6.Programul de studii/calificarea Universitatea

Mai mult

TRADIȚIE ȘI EXCELENȚĂ FACULTATEA DE FIZICĂ Str. M. Kogălniceanu nr. 1 Cluj-Napoca, RO Tel.: / Fax:

TRADIȚIE ȘI EXCELENȚĂ FACULTATEA DE FIZICĂ Str. M. Kogălniceanu nr. 1 Cluj-Napoca, RO Tel.: / Fax: REGULAMENTUL FACULTĂŢII DE FIZICĂ DE ORGANIZARE ŞI DESFĂŞURARE A EXAMENULUI DE FINALIZARE A STUDIILOR NIVEL LICENŢĂ ŞI MASTERAT Examenul de finalizare a studiilor la nivel licenţă şi masterat la Facultatea

Mai mult

Gheorghe IUREA Adrian ZANOSCHI algebră geometrie clasa a VII-a ediţia a V-a, revizuită mate 2000 standard EDITURA PARALELA 45 Matematică. Clasa a VII-

Gheorghe IUREA Adrian ZANOSCHI algebră geometrie clasa a VII-a ediţia a V-a, revizuită mate 2000 standard EDITURA PARALELA 45 Matematică. Clasa a VII- Gheorghe IUREA Adrian ZANOSCHI algebră geometrie clasa a VII-a ediţia a V-a, revizuită mate 2000 standard 3 Algebră Capitolul I. MULŢIMEA NUMERELOR RAŢIONALE Identificarea caracteristicilor numerelor raţionale

Mai mult

manual_ARACIS_evaluare_experti_v4

manual_ARACIS_evaluare_experti_v4 PLATFORMĂ DE EVALUARE ONLINE PENTRU EXPERȚII ARACIS Page 1 CUPRINS Cap 1. Procesul de evaluare 3 Cap 2. Procedura de înregistrare și evaluare 3 cap 3. Instrucțiuni de completare a formularului de înregistrare

Mai mult

Raportarea serviciilor de dializă la nivel CNAS

Raportarea serviciilor de dializă la nivel CNAS SISTEM INFORMATIC UNIC AL ASIGURĂRILOR DE SĂNĂTATE DIN ROMÂNIA INTEGRAT Raportarea serviciilor de dializă la nivel CNAS Manual de utilizare Versiune document: 1.2 RELEASED Creat: 13.09.2007 Ultima actualizare:

Mai mult

INDICATORI AI REPARTIŢIEI DE FRECVENŢĂ

INDICATORI AI REPARTIŢIEI DE FRECVENŢĂ STATISTICA DESCRIPTIVĂ observarea Obiective: organizarea sintetizarea descrierea datelor Analiza descriptivă a datelor Analiza statistică descriptivă reperezintă un tip de analiză ce servește la descrierea,

Mai mult

Microsoft Word - grile.doc

Microsoft Word - grile.doc SISTEME INFORMATICE ÎN ADMINISTRAŢIA PUBLICĂ TESTE GRILĂ PROPUSE PENTRU REZOLVARE 1. Pentru stabilirea corectă a resurselor financiare disponibile la un moment dat necesare susţinerii unor procese investiţionale

Mai mult

PowerPoint Presentation

PowerPoint Presentation CURS 2 Planificarea Tranzacţiilor Gestionarea Concurenţei Planificarea tranzacţiilor O planificare reprezintă ordonarea secvenţială a instrucţiunilor (Read / Write / Abort / Commit) a n tranzacţii astfel

Mai mult

Manual de utilizare Room Booking System

Manual de utilizare Room Booking System Manual de utilizare Room Booking System Cuprins 1. Autentificare 2. Utilizare aplicatie 2.1. Manage Reservation 2.2. Rooms 2.3. Manage Users 2.4. View Reservations 3. Sectiuni Adaugare/Editare 3.1 Adauga

Mai mult

Communicate at your best - Manual - Cap 3 - RO

Communicate at your best - Manual - Cap 3 - RO 1. Principii de bază Ce trebuie să luăm în considerare atunci când comunicăm la birou? Comunicarea la birou nu este nici complicată, nici foarte simplă. Fiecare dintre noi are competențe de bază în interacțiunea

Mai mult

MergedFile

MergedFile PROIECT DIDACTIC Clasa a V-a Informatică și T.I.C. Proiect didactic realizat de Anișoara Apostu, profesor Digitaliada, revizuit de Radu Tăbîrcă, inspector școlar Informatică Textul și ilustrațiile din

Mai mult

ADRIAN TRIF BAZE DE DATE APLICAŢII ACCESS UTPRESS Cluj-Napoca, 2019 ISBN

ADRIAN TRIF BAZE DE DATE APLICAŢII ACCESS UTPRESS Cluj-Napoca, 2019 ISBN ADRIAN TRIF BAZE DE DATE APLICAŢII ACCESS UTPRESS Cluj-Napoca, 2019 ISBN 978-606-737-380-6 Editura U.T.PRESS Str. Observatorului nr. 34 C.P. 42, O.P. 2, 400775 Cluj-Napoca Tel.:0264-401.999 e-mail: utpress@biblio.utcluj.ro

Mai mult

carteInvataturaEd_2.0_lectia5.pdf

carteInvataturaEd_2.0_lectia5.pdf Lect ia3 Diagrame Veitch-Karnaugh 5.1 Noţiuni teoretice Diagramele Veich-Karnaugh (V-K) sunt o modalitate de reprezentare grafică a funcţiilor logice. Pentru o funct ie de N variabile, diagrama corespunz

Mai mult

UNIVERSITATEA TEHNICA FACULTATEA DE AUTOVEHI CULE RUTI ERE, MECATRONI CA si MECANI CA Ghid pentru redactarea, elaborarea şi prezentarea Proiectului de

UNIVERSITATEA TEHNICA FACULTATEA DE AUTOVEHI CULE RUTI ERE, MECATRONI CA si MECANI CA Ghid pentru redactarea, elaborarea şi prezentarea Proiectului de Ghid pentru redactarea, elaborarea şi prezentarea Proiectului de diplomă/ lucrării de disertaţie CUPRINS 1. Introducere - Cadrul general 2. Structura proiectului de diplomă/lucrării de disertaţie 3. Reguli

Mai mult

Facultatea de Științe Politice, Administrative și ale Comunicării Str. Traian Moșoiu nr. 71 Cluj-Napoca, RO Tel.: Fax:

Facultatea de Științe Politice, Administrative și ale Comunicării Str. Traian Moșoiu nr. 71 Cluj-Napoca, RO Tel.: Fax: Documentație pentru accesarea platformei e-learning de catre profesori Platforma de e-learning a facultății poate fi accesată la adresa http://fspac.ubbcluj.ro/moodle. Conturile profesorilor sunt create

Mai mult

FIŞA DISCIPLINEI

FIŞA DISCIPLINEI FIŞA DISCIPLINEI 1. Date despre program 1.1.Instituţia de învăţământ superior 1.2.Facultatea 1.3.Departamentul 1.4.Domeniul de studii 1.5.Ciclul de studii 1.6.Programul de studii/calificarea Universitatea

Mai mult

Microsoft Visual C++ (abreviat MSVC) is a commercial integrated development environment (IDE) product engineered by Microsoft for the C, C++, and C++/

Microsoft Visual C++ (abreviat MSVC) is a commercial integrated development environment (IDE) product engineered by Microsoft for the C, C++, and C++/ Proiect (100 puncte) Pe o platformă online se comercializează produse alimentare și nealimentare. Pentru un produs, pe lângă atributele comune: cod identificare, denumire, descriere, categorie, preț etc.

Mai mult

DAN LASCU ADRIANA-LIGIA SPORIŞ ANDA OLTEANU PAUL VASILIU MATEMATICĂ. CULEGERE DE PROBLEME TIP GRILĂ PENTRU ADMITEREA ÎN ACADEMIA NAVALĂ MIRCEA CEL BĂT

DAN LASCU ADRIANA-LIGIA SPORIŞ ANDA OLTEANU PAUL VASILIU MATEMATICĂ. CULEGERE DE PROBLEME TIP GRILĂ PENTRU ADMITEREA ÎN ACADEMIA NAVALĂ MIRCEA CEL BĂT DAN LASCU ADRIANA-LIGIA SPORIŞ ANDA OLTEANU PAUL VASILIU MATEMATICĂ. CULEGERE DE PROBLEME TIP GRILĂ PENTRU ADMITEREA ÎN ACADEMIA NAVALĂ MIRCEA CEL BĂTRÂN Colecţia Matematică DAN LASCU ADRIANA-LIGIA SPORIŞ

Mai mult

Baze de date - Anul 2 Laborator 8 Limbajul de definire a datelor (LDD) (partea I) În general, instrucţiunile LDD sunt utilizate pentru definirea struc

Baze de date - Anul 2 Laborator 8 Limbajul de definire a datelor (LDD) (partea I) În general, instrucţiunile LDD sunt utilizate pentru definirea struc Baze de date - Anul 2 Laborator 8 Limbajul de definire a datelor (LDD) (partea I) În general, instrucţiunile LDD sunt utilizate pentru definirea structurii corespunzătoare obiectelor unei scheme: tabele,

Mai mult

Programe derulate în ediția a treia Junior IT Fun Factory *În cadrul Junior IT Fun Factory fiecare înscriere se face pentru un program individual în f

Programe derulate în ediția a treia Junior IT Fun Factory *În cadrul Junior IT Fun Factory fiecare înscriere se face pentru un program individual în f Programe derulate în ediția a treia Junior IT Fun Factory *În cadrul Junior IT Fun Factory fiecare înscriere se face pentru un program individual în funcție de preferințe. Pentru studierea mai multor discipline

Mai mult

Project Work-Based Learning in the Field of Mechatronics: Introducing VET Multipliers to Alternate Work-Based Learning in Romania and Macedonia PROIEC

Project Work-Based Learning in the Field of Mechatronics: Introducing VET Multipliers to Alternate Work-Based Learning in Romania and Macedonia PROIEC Project Work-Based Learning in the Field of Mechatronics: Introducing VET Multipliers to Alternate Work-Based Learning in Romania and Macedonia PROIECT COTAREA ÎN DESEN TEHNIC 1. INFORMAREA: 15 minute

Mai mult

Utilizarea îmbinării corespondenței pentru crearea şi imprimarea scrisorilor şi a altor documente Dacă utilizați îmbinarea corespondenței când doriți

Utilizarea îmbinării corespondenței pentru crearea şi imprimarea scrisorilor şi a altor documente Dacă utilizați îmbinarea corespondenței când doriți Utilizarea îmbinării corespondenței pentru crearea şi imprimarea scrisorilor şi a altor documente Dacă utilizați îmbinarea corespondenței când doriți să creați un set de documente, cum ar fi o scrisoare

Mai mult

Slide 1

Slide 1 Programare orientată pe obiecte 1. Dezvoltarea aplicațiilor OO 2. Diagrame UML de clase și obiecte Proiectarea orientată pe obiecte 1. Descoperim clasele 2. Determinăm responsabilităţile fiecărei clase

Mai mult

Microsoft Word - MANUAL_APP_ROMPOS_V7.docx

Microsoft Word - MANUAL_APP_ROMPOS_V7.docx MANUAL DE UTILIZARE ANCPI CUPRINS 1 Descrierea platformei... 2 2 ROVERS/RTK... 5 2.1 Introducere ROVER... 5 2.2 Introducere abonament ROVER... 6 2.3 Prelungire abonament ROVERS/RTK... 8 2.4 Ștergere rover...

Mai mult

Microsoft Word - Algoritmi genetici.docx

Microsoft Word - Algoritmi genetici.docx 1.1 Generalităţi Algoritmii genetici fac parte din categoria algoritmilor de calcul evoluționist și sunt inspirați de teoria lui Darwin asupra evoluției. Idea calculului evoluționist a fost introdusă în

Mai mult

Manual de utilizare a Sistemului Informațional al Institutului Național al Justiției (SI INJ) intranet.inj.md Ver.2 Manual de utilizare a Sistemului I

Manual de utilizare a Sistemului Informațional al Institutului Național al Justiției (SI INJ) intranet.inj.md Ver.2 Manual de utilizare a Sistemului I Manual de utilizare a Sistemului Informațional al Institutului Național al Justiției (SI INJ) intranet.inj.md Ver.2 Manual de utilizare a Sistemului Informațional al Institutului Național al Justiției

Mai mult

Microsoft Word - Alina-Mihaela ION - TEHNOLOGIA INFORMA?IEI CU APLICA?II

Microsoft Word - Alina-Mihaela ION - TEHNOLOGIA INFORMA?IEI CU APLICA?II Tehnologia informației cu aplicații în sistemul de învăţământ superior din domeniul economic Alina-Mihaela ION TEHNOLOGIA INFORMAȚIEI CU APLICAȚII ÎN SISTEMUL DE ÎNVĂŢĂMÂNT SUPERIOR DIN DOMENIUL ECONOMIC

Mai mult

Anexă nr.5hsu nr. 80/2019 Ghidul Metodologic privind elaborarea şi prezentarea lucrării de certificare a competențelor PREAMBUL Prezentul ghid are dou

Anexă nr.5hsu nr. 80/2019 Ghidul Metodologic privind elaborarea şi prezentarea lucrării de certificare a competențelor PREAMBUL Prezentul ghid are dou Anexă nr.5hsu nr. 80/2019 Ghidul Metodologic privind elaborarea şi prezentarea lucrării de certificare a competențelor PREAMBUL Prezentul ghid are două obiective esenţiale: stabilirea structurii lucrării

Mai mult

Microsoft Word - Ghid de elaborare a lucrarii de licenta MM-MK (ATENTIE - an referinta diagnostic economico-financiar pag.3)

Microsoft Word - Ghid de elaborare a lucrarii de licenta MM-MK  (ATENTIE - an referinta diagnostic economico-financiar pag.3) UNIVERSITATEA ROMÂNO-AMERICANĂ FACULTATEA DE MANAGEMENT-MARKETING DEPARTAMENTUL DE MANAGEMENT - MARKETING GHID DE ELABORARE A LUCRĂRII DE LICENŢĂ Domeniul de licență: Marketing Specializarea: Marketing

Mai mult

Laborator 1 suport teoretic Mediul de dezvoltare Eclipse GLOSAR - Aplicaţie: program obţinut în urma aplicării operației BUILD asupra unui proiect (ve

Laborator 1 suport teoretic Mediul de dezvoltare Eclipse GLOSAR - Aplicaţie: program obţinut în urma aplicării operației BUILD asupra unui proiect (ve Laborator 1 suport teoretic Mediul de dezvoltare Eclipse GLOSAR - Aplicaţie: program obţinut în urma aplicării operației BUILD asupra unui proiect (vezi Program C) - BUILD: operație complexă prin care

Mai mult

FILTRE DE REALIZARE CU CIRCUITE DE INTEGRARE

FILTRE DE REALIZARE CU CIRCUITE DE INTEGRARE FILTRE ACTIVE BIQUAD REALIZATE CU CIRCUITE DE INTEGRARE. SCOPUL LUCRĂRII Măsurători asupra unor filtre active biquad de tip RC realizate cu circuite de integrare.. ASPECTE TEORETICE Considerăm funcţia

Mai mult

Crearea ghidului de studiu Syllabus

Crearea ghidului de studiu Syllabus Crearea ghidului de studiu (Syllabus) Syllabus este principala unealtă prin care se ghidează activitatea studenților pe un site de curs Danubius Online. Un Syllabus este constituit dintr-o succesiune de

Mai mult

FIŞA DISCIPLINEI

FIŞA DISCIPLINEI Competenţe transversale Competenţe profesionale FIŞA DISCIPLINEI 1. Date despre program 1.1.Instituţia de învăţământ superior 1.2.Facultatea 1.3.Departamentul 1.4.Domeniul de studii 1.5.Ciclul de studii

Mai mult