16 decembrie 2011

Exercitii noi PL/SQL

I. Tabela student {matricol, nume, grupa, medie, bursa} si tabela note {matricol, data, nota}
a) un trigger pt fiecare insert/update/delete in tabela note care va actualiza corespunzator tabela student cu media care reiese;
Apoi se vor insera note diverse.
b) o procedura stocata care acorda burse unui student luat ca parametru (matricol) a.i. pt fiecare nota de 7,8 => add 100 la bursa, pt fiecare nota 9, 10 => add 200 la bursa
c) de apelat procedura intr-un cursor pt toti studentii intr-o grupa  (grupa data de la tastatura)
d) afisare tabel {matricol, nume, grupa, medie, nr.note, bursa}
codul sursa AICI

II. Pachetul facultate care contine o functie bonus (cu parametru matricol) si intoarce o valoare egala cu 100*nr.notelor de 10. Pachetul mai are un cursor ce selecteaza studentii care au  cel putin 3 note de 10 si media peste 9. Folosind cursorul si functia definita, se adauga bonusul la valoarea bursei studentului care respecta toate aceste conditii. Exceptie: pt studentul cu bursa > 1000, tratare prin setarea bursei la 1000.

// creare tabele

create table note (
matricol number(3),
cod_materie number(3),
nota number(2)
);

create table studenti (

matricol number(3),
bursa number(3)
);

// interfata pachet


CREATE OR REPLACE PACKAGE facultate AS

FUNCTION bonus (mymatricol IN number) RETURN number;

CURSOR smart IS
select S.matricol from studenti S
where S.matricol IN (
select N.matricol from note N
where (select count (*) from note where nota = 10 AND matricol = N.matricol) > 2
) AND (
select avg(nota)
from note
where matricol = S.matricol
) >= 9;

bursa_mare EXCEPTION;

END;

// implementare pachet


CREATE OR REPLACE PACKAGE BODY facultate AS

FUNCTION bonus (mymatricol IN number) RETURN number IS
numar number;
begin
numar:=0;
select count(*) into numar
from note
where matricol=mymatricol AND nota=10;
return 100*numar;
end bonus;

END facultate;

// programul principal


declare
vc facultate.smart%ROWTYPE;
valoare number;

BEGIN

open facultate.smart;
LOOP BEGIN
fetch facultate.smart into vc;
exit when facultate.smart%NOTFOUND;

valoare := facultate.bonus(vc.matricol);
IF valoare>1000 THEN raise facultate.bursa_mare; END IF;

update studenti set bursa=bursa+valoare
where matricol=vc.matricol;

EXCEPTION WHEN facultate.bursa_mare
THEN update studenti set bursa=1000 where matricol=vc.matricol;

END;
END LOOP;
close facultate.smart;
END;



Turnurile din Hanoi

A                 B                 C

Varianta cu Divide et Impera:


#include <iostream>

using namespace std;
int tija[67];
// tija['A'], tija['B'], tija['C'] = nr discuri de pe fiecare tija

void hanoi (int n, char a, char c, char b, int & nm) {

if (n==1) {
tija[a]--;
tija[c]++;
cout<<"Mutarea: "<<a<<"->"<<c<<" (A: "<<tija['A']<<" discuri, B:";
cout<<tija['B']<<" discuri, C: "<<tija['C']<<" discuri)"<<endl;
}
else {
// muta n-1 discuri din a in b, folosind c
hanoi (n-1, a, b, c, nm);
tija[a]--;
tija[c]++;
cout<<"Mutarea: "<<a<<"->"<<c<<" (A: "<<tija['A']<<" discuri, B:";
cout<<tija['B']<<" discuri, C: "<<tija['C']<<" discuri)"<<endl;
// muta n-1 discuri din b in c, folosind a
hanoi (n-1, b, c, a, nm);
}
nm++;
}

int main () {

int n;
int nr_miscari = 0;
char a='A', b='B', c='C';
cout<<"n=";
cin>>n;

tija['A']=4;
tija['B']=0;
tija['C']=0;
cout<<"Initial: (A: "<<tija['A']<<" discuri, B:";
cout<<tija['B']<<" discuri, C: "<<tija['C']<<" discuri)"<<endl;

// muta n discuri de pe tija a pe tija c, folosind tija b
hanoi (n,a,c,b, nr_miscari);

cout<<"S-au folosit "<<nr_miscari<<" miscari"<<endl;
return 0;
}

pentru jucat, apasati AICI
pentru solutia folosind stive, apasati AICI, la cap.3

12 decembrie 2011

Functii si pachete in PL/SQL

Acelasi tabel student {matricol, nume, grupa, medie, bursa} :

Functii
a) o functie nestocata care intoarce un mesaj: valideaza valoarea burselor primite de studenti dupa regulile:
1. studentii restantieri, cei cu media < 7 si cei cu media mai mica decat media grupei lor nu primesc burse
2. bursele nu pot depasi 1000 sau sa fie mai mici de 100
3. bursele nu pot fi > media*110
b) o functie stocata pe disc ce calculeaza bursa recomandata pt fiecare student, dupa regulile:
1. media peste 7 si media > media grupei
2. suma burselor studentilor din grupa sa nu depaseasca 2000
3. fiecare bursa sa fie cuprinsa intre 100 si 1000 si sa fie proportionala cu mediile din grupa (bursa=media*2000/suma_medii_grupa). De actualizat bursele cu aceste valori.
c) Pentru fiecare grupa calculat coeficientul grupei k = (nr_studenti cu media > media grupei)/nr total de studenti. Se vor da bonusuri studentilor proportional cu acest coeficient: bursa = bursa * (k+1). La coeficientul cel mai mic nu se da nimic, la coeficientul cel mai mare se da bonus inca o data valoarea bursei.
rezolvarile aici

Pachete
Au 2 parti: specificatia (un fel de interfata) si implementarea (functiilor, procedurilor).
In specificatie se pun variabilele globale, definitia tipurilor de date create, antetele functiilor si procedurilor, se denumesc exceptiile si se scriu cursoarele.
Obiectul creat se numeste facultate si are:
  • variabila globala nr_studenti
  • o functie: getter pentru nr_studenti
  • o procedura: setter pentru nr_studenti
  • definirea unui tip de date grupa cu campurile {nume, nr_studenti, medie}
  • o functie ce intoarce un obiect de tip grupa, cu parametru nr_matricol
  • o procedura care listeaza o grupa luata ca parametru, si afiseaza cele 3 campuri
  • un cursor care itereaza peste multimea de cei mai buni studenti pt fiecare grupa
  • o exceptie bursa_0
Se cere:
a) afisarea var globale nr_studenti
b) stergerea celui mai slab student din fiecare grupa, actualizarea var globale & reafisarea ei
c) folosind cursorul si functiile definite - listarea tuturor grupelor
d) folosind acelasi cursor, ridicarea exceptiei bursa_0 cand un student cu media cea mai mare din grupa are bursa 0; se trateaza cu actualizarea bursa=media*100.
rezolvarile aici

06 decembrie 2011

Aplicatie cu socketi TCP in Java

Un mini-messenger, fara interfata grafica, intre mai multi clienti conectati la un server. Serverul stocheaza mesajele de la un client si le furnizeaza destinatiei la cerere (atunci cand destinatia cere acest lucru).
Rularea se face din linia de comanda, iar mesajele care provin de la clienti sunt de forma:
sign_in*username
sign_out*username
send_message*sender*receiver*mesaj
receive_messages*username
Este doar un sablon, ce poate fi imbunatatit cu:
* interfata grafica pe partea clientului
* verificarea autenticitatii celui care trimite mesajul (send_message*sender*...) si a faptului ca e logat
* primire automata a mesajelor fara explicitare (receive_messages)
* etc

Descarcare aici

Triggeri in PL/SQL

Tabela student: {matricol, nume, grupa, medie, bursa}
1) creati un trigger care la fiecare inserare in tabela va popula bursa acelor stud cu medii > 7 , bursa = medie * 100; dupa acest trigger, insert 10 inreg in tabela; la inserare bursa=0
2) creati un nou trigger care se va asigura k la fiecare update al coloanei bursa , bursa nu se va da decat stud cu medii >= 7 si bursa e in intervalul 700..1000 (0 la medie<7, 700 la mai mic, 100 la mai mare); trigger pe toti studentii dintr-o grupa
3) folosind un view (proiectie a tabelei student), creati un trigger pe acest view care se executa la comanda delete si in momentul stergerii unui rand din view sa redistribuie bursa studentului respectiv celorlalti studenti din grupa sa; dar daca studentul este cel mai bun din grupa atunci stergerea este anulata;

1)
create table studenti (
matricol number(3),
nume varchar2(40),
grupa varchar2(5),
medie number(2),
bursa number(5)
);

CREATE OR REPLACE TRIGGER inserare
BEFORE INSERT ON studenti FOR EACH ROW
WHEN (new.bursa = 0 AND new.medie > 7)
BEGIN
:new.bursa := :new.medie * 100;
END;
/

insert into studenti values (100, 'ion', '341C1', 8, 0);
insert into studenti values (101, 'gheo', '341C1', 10, 0);
insert into studenti values (102, 'vasi', '341C1', 7, 0);
insert into studenti values (103, 'delia', '341C1', 5, 0);
insert into studenti values (104, 'diana', '341C1', 9, 0);

insert into studenti values (105, 'liviu', '341C5', 9, 0);
insert into studenti values (106, 'xena', '341C5', 8, 0);
insert into studenti values (107, 'raul', '341C5', 10, 0);
insert into studenti values (108, 'costin', '341C5', 9, 0);
insert into studenti values (109, 'daria', '341C5', 7, 0);

pentru celelalte exercitii rezolvate accesati (aici)

25 noiembrie 2011

Aplicatie Android pentru vreme

Aplicatia se foloseste de serviciul de la Google pentru aflarea vremii.
Codul se afla aici: http://code.google.com/p/weather-application-tg2011/








Update 2013:
Google a închis serviciul pentru aflarea vremii în timp real.
De aceea am modificat programul folosind API-ul de la OpenWeatherMap, codul se află aici

22 noiembrie 2011

Cajun Meet preview




O aplicatie pentru schimbul de carti de vizita intre studentii unei universitati.
Aplicatia realizeaza schimbul de carti de vizita prin wifi si creeaza o mica baza de date a contactelor obtinute.
Pentru asa-zisa comunicatie prin wifi, se foloseste un mediu partajat: Google SpreadSheet.

Many many thanks to gss-lib fara de care acest proiect nu ar fi putut fi implementat chiar atat de usor.

Simularea protocolului MESI in C


<--- schema pentru protocolul Mesi cu invalidare pentru memoria cache de tip "write back"

MESI = initialele celor 4 stari ale memoriilor cache asociate unor procesoare (Modified, Exclusive, Shared, Invalid)

Invalid -> la inceputul rularii toate cache-urile sunt "I" sau atunci cand un procesor face scriere pe propriul cache, rezulta celelalte cache-uri devin "I"

Exclusive -> cand se aduc datele din memoria principala intr-una dintre memoriile cache (celelalte cache-uri fiind pe starea "I")

Modified -> dupa fiecare write al unui procesor, memoria cache asociata devine "M" (si restul "I")

Shared -> dupa ce o memorie cache isi imparte datele cu o alta, indiferent cum erau inainte, ambele ajung in starea "S"

Simularea de mai jos este relativ simplista, nu afiseaza actiunea pe magistrala (BusRd, Flush, etc) si nici informatii despre sursa de date, ci doar starile succesive ale cache-urile asociate procesoarelor.

#include "stdio.h"
#include "stdlib.h"
#define N 3

char s[N];
int mem[N*4] = {1,0,1,0,0,1,1,0,1,1,0,1};
int cache[N][N], n;

void operatie (int p, char *op) {

int i;

if (*op == 'w') {
s[p] = 'M';
for (i=0; i < N; i++)
if (i != p)
s[i] = 'I';
goto afisare;
}
if (*op == 'r') {
if (s[p] == 'M' || s[p] == 'E')
goto afisare;
if (s[p] == 'I') {
int flag = 1;
for (i=0; i < N; i++)
if (s[i] != 'I')
flag = 0;
if (flag == 1) {
s[p] = 'E';
goto afisare;
}
for (i=0; i < N; i++)
if (s[i] == 'E' || s[i] == 'S' || s[i] == 'M')
s[i] = 'S';
s[p] = 'S';
}
goto afisare;
}
afisare:
for (i=0; i < N; i++)
printf("%c ", s[i]);
printf("\n");
}

int main () {

char *op = (char*) malloc (sizeof (char));
int i, j;
for (i=0; i < N; i++) {
for (j=0; j < N; j++)
cache[i][j] = 0;
s[i] = 'I';
}
printf("n=");
scanf("%d", &n);
printf("initial\n");
for (i=0; i < N; i++)
printf("%c ", s[i]);
printf("\n");
for (i=0; i < n; i++) {
int proc;
printf("P=");
scanf ("%d", &proc);
printf("op=");
scanf ("%s", op);
operatie (proc-1, op);
}

return 0;

}

Pentru test se poate folosi secventa:

Se citesc: n (numarul de operatii, 8) , P (indicele procesorului, 1..3) si operatia (r/w)
Sunt afisate cele N = 3 stari dupa fiecare pas.

Cautare paralela in OpenMP

Mai demult scriam o postare despre cautarea in paralel in Java, folosind thread-uri. De data aceasta am scris si in OpenMP, si este mult mai intuitiv si usor de inteles decat inainte.

De la tastatura se dau: n (nr de elemente), x (numarul cautat) si p (numarul de procesoare); se genereaza apoi n numere naturale intr-un vector care se ordoneaza folosind quicksort si pe care se va face cautarea paralela. Pozitia afisata reprezinta pozitia in acest vector ordonat.

#include "omp.h"
#include "stdio.h"
#include "stdlib.h"

int min (int a, int b) {

if (a < b)
return a;
return b;
}

int comp (const void * a,const void * b) {

if (*((int*)a)==*((int*)b))
return 0;
if (*((int*)a) < *((int*)b))
return -1;
return 1;
}

void cautare (int x, int a[], int n, int left, int right, int p) {

int pas = (right-left)/p+1;
int i, aux = -1;

if(left == right && a[left]==x)
return ;

#pragma omp parallel private(i) num_threads(p)
{
#pragma omp for
for(i = left; i<=right; i+=pas) {

int tid = omp_get_thread_num();
int next = min (n-1, i+pas-1);

if(a[i]<=x && x <= a[next]) {
aux = i;
if (i != next)
printf ("Thread %d a gasit: intre pozitiile %d si %d\n", tid, i, next);
else
printf ("Thread %d a gasit pozitia = %d\n", tid, i);
}
}
}
if(aux >= 0)
cautare (x,a,n,aux,aux+pas-1,p);
else
printf ("Element inexistent\n");
}

int main() {

int *a, n, i, p, x;

unsigned int iseed = (unsigned int)time(NULL);
srand (iseed);

printf ("n=");
scanf ("%d", &n);

a = (int *)malloc (n*sizeof(int));

for (i=0; i < n; i++)
a[i] = rand () % 1000;

// sortare a
qsort((void*)a, n, sizeof(int), comp);
printf ("Multime: {");
for (i=0; i < n-1; i++)
printf ("%d, " , a[i]);
printf ("%d}\n", a[n-1]);

printf ("x=");
scanf ("%d", &x);
printf ("p=");
scanf ("%d", &p);

cautare (x,a,n,0,n-1,p);

return 0;
}

18 noiembrie 2011

Proceduri PL/SQL

Arhiva conține rezolvări pentru exercițiile următoare:
(pe un tabel studenti cu câmpuri pentru matricol, nume, grupa, medie, bursa)

1. procedură nestocată cu parametru un număr fond_pentru_burse care va seta bursele studenților cu media > 7. Bursele sunt proporționale cu media, fondul trebuie consumat integral.
2. procedură nestocată care calculează pentru o grupă dată ca parametru: nr de studenți, media mediilor și suma burselor acordate. Apelată pentru toate grupele din tabelă
3. procedură stocată pe server ce include un cursor explicit, primește ca parametri 2 numere: medie și bonus. Iterează pe mai mulți studenți cu media > medie și adaugă bonusul la valoarea bursei lor.

Simulare CW-PRAM in MPI

Următorul program simulează cererile de scriere a 4 procesoare conectate la o memoria partajată. Conform logicii descrise în pdf [1] și a priorității procesoarelor, dispozitivul de control al memoriei poate îndeplini cererea și scrie în memoria partajată la o anumită adresă, sau nu.
Pentru comunicațiile între procesoare și dispozitivul de control s-au folosit operațiile de send/receive ale MPI-ului.

[1] arhiva se poate descărca de aici

09 noiembrie 2011

Cursoare in PL/SQL

Practic, intr-un cursor se stocheaza rezultatul unei interogari. Prin el se pot itera mai usor rezultatele, rand cu rand.

Exemple...
Intr-un tabel "student" cu coloanele [ matricol | nume | grupa | medie | bursa | obs ] vrem sa:
1) parcurgem lista de studenti si sa afisam studentii cu media > media grupei (folosind un cursor, cu instructiunea FETCH)
2) actualizam bursa studentilor cu media > 7, dupa formula bursa=media*100, plus bonusuri pentru "sef_grupa" (500) sau "sef_promotie" (1000)
3) listam toti studentii dintr-o grupa dupa bursa, descrescator, cu grupa citita de la tst si data la parametru pt cursor. Listarea cuprinde: [ Nume | Grupa | Medie | Bursa | Poz. in grupa | Poz. in facultate ]

Rezolvari...

1)

set serveroutput on;

declare
CURSOR my_cursor IS
select s.nume, s.grupa, s.medie
from student s
where s.medie > (select avg(medie) from student where s.grupa=grupa group by grupa);
var my_cursor%ROWTYPE;

BEGIN

OPEN my_cursor;
dbms_output.put_line(rpad('Nume',10,' ') || ' ' || rpad('Grupa', 5, ' ') || ' ' || rpad('Medie',5, ' '));

LOOP
FETCH my_cursor into var;
EXIT when my_cursor%NOTFOUND;

dbms_output.put_line (rpad(var.nume,10,' ') || rpad(var.grupa, 5, ' ') || ' ' || rpad(var.medie,5, ' '));

END LOOP;

CLOSE my_cursor;
END;
/

-------------------------------------------------------------------------------

2)

declare
CURSOR my_cursor IS
select matricol, obs
from student
where medie > 7;
var my_cursor%ROWTYPE;
adaos number:=0;

BEGIN
FOR var IN my_cursor
LOOP
EXIT WHEN my_cursor%NOTFOUND;

adaos := 0;
IF var.obs = 'sef_grupa' THEN adaos := 500; END IF;
IF var.obs = 'sef_promotie' THEN adaos := 1000; END IF;

UPDATE student SET bursa=medie*100+adaos WHERE var.matricol=matricol;

END LOOP;
END;
/

------------------------------------------------------------------------

3) (nu foarte eficient)

set serveroutput on;

declare
CURSOR myc (p_grupa varchar2) IS
select matricol,nume,grupa, bursa,medie
from student
where grupa=p_grupa
order by bursa DESC;
var myc%ROWTYPE;

CURSOR cursor2 IS
select matricol
from student
order by bursa DESC;
var2 cursor2%ROWTYPE;

poz_grupa number:=1;
poz_fac number:=0;
contor number:=1;
param varchar2(5);

BEGIN
dbms_output.put_line(rpad('Nume', 20, ' ') || ' ' || rpad('Grupa', 6, ' ') || ' ' || rpad('Bursa',6, ' ') || ' ' || rpad('Medie', 7, ' ') || rpad('Poz grupa',9,' ') || ' ' || rpad('Poz fac', 7, ' '));
param := &readparam;
FOR var IN myc(param)
LOOP
EXIT WHEN myc%NOTFOUND;

contor:=1;
FOR var2 IN cursor2
LOOP

IF var2.matricol = var.matricol THEN poz_fac := contor; END IF;
contor:= contor+1;

EXIT WHEN cursor2%NOTFOUND;
END LOOP;

dbms_output.put_line(rpad(var.nume,20, ' ') || ' ' || rpad(var.grupa, 6, ' ') || ' ' || rpad(var.bursa, 6, ' ') || ' ' || rpad(var.medie, 7, ' ') || ' ' || rpad(poz_grupa, 9, ' ') || ' ' || rpad(poz_fac, 7, ' '));
poz_grupa:=poz_grupa+1;
END LOOP;
END;
/

08 noiembrie 2011

Java RMI

How to make it work:

1) adaugarea in variabila de mediu PATH a caii sdk-ului pt java, daca nu exista deja:
C:\ProgramFiles\Java\jdk1.7.0\bin

2) pornire RMI cu:
start rmiregistry 1099
1099 reprezinta portul.

3) crearea fisierelor de policy (cu permisiuni de accesare) atat pt client cat si pt server:

grant codebase "file:///C:\\Users\\anna\\Desktop\\lab5\\Eclipse\\ProgramareClient\\-" {
permission java.security.AllPermission;
};

grant codebase "file:///C:\\Users\\anna\\Desktop\\lab5\\Eclipse\\ProgramareServer\\-" {
permission java.security.AllPermission;
};

unde calea trebuie sa duca la intreg folderul clientului/serverului, pentru a se putea accesa orice resursa de acolo. Fisierul numit "policy" se afla si el tot in acest folder.
Atentie la backslash - trebuie dublat.

4) In Eclipse - in Run configurations - Arguments, atat pt server cat si pt client se adauga (daca exista o astfel de arhiva jar):

server:
-classpath .;programare.jar -Djava.rmi.server.codebase=file:///C:\Users\anna\Desktop\lab5\Eclipse\ProgramareServer\programare.jar -Djava.rmi.server.hostname=localhost -Djava.security.policy=policy
Proprietatea java.rmi.server.codebase specificã locatia de unde pot fi descãrcate definitii pentru clasele provenind de la server.
Proprietatea java.rmi.hostname specificã numele masinii sau adresa care urmeazã a fi completatã în obiectele de tip ciot care vor fi exportate.

client: asemanator, dar fara hostname

-classpath .;programare.jar -Djava.rmi.server.codebase=file:///C:\Users\anna\Desktop\lab5\Eclipse\ProgramareClient\programare.jar -Djava.security.policy=policy

Aici, "programare.jar" contine definitia obiectelor transmise intre client si server (= obiecte serializabile).

------

Cu aceste configuratii realizate, puteti testa un mic program de gestiune a unui orar, in care clientul (student) poate sa rezerve un interval de timp in intervalele specificate in "orar.txt" , de exemplu spre a-i prezenta ceva profesorului. Serverul raspunde cu "da"/"nu" si in functie de asta face rezervarea in fisierul "rezervari.txt". Ulterior, folosind acelasi id cu care a trimis cerere pentru un interval de timp, clientul poate sa renunte la rezervare.

03 noiembrie 2011

Simularea unei retele omega

O retea omega este construita din m=log2(N) retele de conexiune "shuffle" cascadate.
O retea de dimensiune n*n contine (n/2)log(n) comutatoare, deci are complexitate de O(n*log(n)) < O(n^2) cat are o retea crossbar.
Programul atasat simuleaza traseul fiecarei conexiuni, de la intrare spre iesire. Varianta: mai multe perechi de intrari si iesiri pe 3 biti (log(8)).

Exceptii in PL/SQL

drop table stud;
create table stud (
matricol number(4) primary key,
nume varchar2(30) unique not null,
grupa varchar2(5),
medie number(10,2) check (medie>1 AND medie<=10),
bursa number(3)
);

insert into stud values (1, 'elena', '333CA', 8.7, 0);
insert into stud values (2, 'geanina', '331CA', 5.7, 0);
insert into stud values (3, 'simona', '332CA', 8.2, 0);
insert into stud values (4, 'cornel', '335CA', 9.5, 0);
insert into stud values (5, 'mihai', '334CA', 10, 0);


----------------------------------------------------------
Exceptie cand numele inserat nu este unic:
----------------------------------------------------------

set serveroutput on;

declare
smat number(4);
snume varchar2(30);
sgrupa varchar2(5);
smedie number(10,2);
sbursa number(3);
begin
smat := &matricol;
snume := &nume;
sgrupa := &grupa;
smedie := &medie;
sbursa := &bursa;

insert into stud values (smat, snume, sgrupa, smedie, sbursa);
dbms_output.put_line('inserat cu succes');
exception
when DUP_VAL_ON_INDEX then
dbms_output.put_line(' Nu s-a putut insera: numele nu este unic');
end;
/


-------------------------------------------------------
Exceptie cand bursa nenula pt student cu media<6
-------------------------------------------------------

set serveroutput on;

declare
smat number(4);
snume varchar2(30);
sgrupa varchar2(5);
smedie number(10,2);
sbursa number(3);
bursa_not_allowed exception;
begin
smat := &matricol;
snume := &nume;
sgrupa := &grupa;
smedie := &medie;
sbursa := &bursa;

if smedie<6 AND sbursa>0 then
raise bursa_not_allowed;
end if;
insert into stud values (smat, snume, sgrupa, smedie, sbursa);
dbms_output.put_line('inserat cu succes');

exception
when bursa_not_allowed then
dbms_output.put_line(' Nu s-a putut insera: bursa nenula pt student cu media sub 6');
end;
/


---------------------------------------------------------------
Idem primul exemplu - dar altfel
---------------------------------------------------------------

set serveroutput on;

declare
smat number(4);
snume varchar2(30);
sgrupa varchar2(5);
smedie number(10,2);
sbursa number(3);
default_name varchar2(30);
null_exc exception;
pragma exception_init (null_exc, -1400);
begin
smat := 17;
snume := null;
sgrupa := '321cc';
smedie := 8;
sbursa := 0;
default_name := 'default4';

insert into stud values (smat, snume, sgrupa, smedie, sbursa);
dbms_output.put_line('inserat cu succes');

exception
when null_exc then
dbms_output.put_line('Eroare: numele trebuie sa fie nenul!');
insert into stud values (smat, default_name, sgrupa, smedie, sbursa);
dbms_output.put_line('Am inserat: ' || smat || ' ' || default_name || ' ' || sgrupa || ' ' || smedie || ' ' || sbursa);
end;
/

28 octombrie 2011

Executii ciclice in PL/SQL

Se da un tabel student cu campurile:

nr_mat | nume | grupa | medie | bursa

Numerele matricole vor fi introduse consecutiv.

1) Setare bursa pt toti studentii dupa formula:

media < 6 => bursa = 0
media < 7 => bursa = media*100
media < 8 => bursa = media*120
media < 9 => bursa = media*150
media < 10 => bursa = media*200
media = 10 => bursa = media*250


declare
nr_mat_s number(2);
media_s number(10,2);
bursa_s number(4,2);
contor number(3):=1;
begin

LOOP
select nr_mat, medie, bursa into nr_mat_s, media_s, bursa_s
from student
where nr_mat = contor;

if media_s < 6 then
update student set bursa = 0 where nr_mat = nr_mat_s;
elsif media_s < 7 then
update student set bursa = medie*100 where nr_mat = nr_mat_s;
elsif media_s < 8 then
update student set bursa = medie*120 where nr_mat = nr_mat_s;
elsif media_s < 9 then
update student set bursa = medie*150 where nr_mat = nr_mat_s;
elsif media_s < 10 then
update student set bursa = medie*200 where nr_mat = nr_mat_s;
else
update student set bursa = medie*250 where nr_mat = nr_mat_s;
end if;

contor:=contor+1;
EXIT WHEN CONTOR = 11;
END LOOP;

EXCEPTION
WHEN NO_DATA_FOUND then
dbms_output.put_line('Nicio modificare');
END;
/


2) Pt fiecare grupa, adaugati 10% la bursa studentilor cu media >= 8, dar numai daca media grupei din care fac parte >= 7.60

declare
nr_mat_s number(2);
media_s number(10,2);
bursa_s number(4,2);
medie_grupa number(10,2);
grupa_s varchar2(5);
contor number(3):=1;
begin

LOOP
select nr_mat, medie into nr_mat_s, media_s
from student
where medie>=8 AND nr_mat = contor AND grupa IN
(select tabel.g
from
(select grupa g, avg(medie) a
from student
group by grupa) tabel
where tabel.a > 8
);

update student set bursa = bursa*1.1 where nr_mat = nr_mat_s;

contor:=contor+1;
EXIT WHEN CONTOR = 11;
END LOOP;

EXCEPTION
WHEN NO_DATA_FOUND then
dbms_output.put_line('Nicio modificare');
END;
/

3) Pentru fiecare student, afisati o linie de raport cu coloanele:

nr_mat | nume | grupa | medie | medie_grupa | bursa | obs
obs:
medie < 5 => obs = "Repetent"
medie = 10 => obs = "Sef de promotie"

set serveroutput on;

declare
nr_mat_s number(2);
medie_s number(10,2);
bursa_s number(15,2);
medie_grupa number(10,2);
grupa_s varchar2(5);
nume_s varchar2(30);
avg_s number(10,4);
obs varchar2(30);
contor number(3):=1;

begin
dbms_output.put_line(
rpad('Nr_mat',6) || rpad('Nume', 20) || rpad('Grupa', 5) || rpad('Medie', 10) ||
rpad('Medie_grupa', 11) || rpad('Bursa', 10) || rpad('Obs', 20)
);

LOOP
select s.nr_mat, s.nume, s.grupa, s.medie, tabel.a, s.bursa into nr_mat_s, nume_s, grupa_s, medie_s, avg_s, bursa_s
from student s, (select grupa g, avg(medie) a
from student
group by grupa) tabel
where s.grupa = tabel.g AND contor = s.nr_mat;

if medie_s < 5 then obs := 'Repetent';
elsif medie_s = 10 then obs := 'Sef promotie';
else obs := '-';
end if;

dbms_output.put_line(
rpad(to_char(nr_mat_s), 6) || ' ' || rpad(nume_s, 20) || ' ' || rpad(grupa_s, 5) || ' ' ||
rpad(to_char(medie_s), 10) || ' ' || rpad(to_char(avg_s), 11) || ' ' || rpad(to_char(bursa_s), 10) || ' ' ||
rpad(obs,20)
);

contor := contor + 1;
EXIT WHEN CONTOR = 11;
END LOOP;

EXCEPTION
WHEN NO_DATA_FOUND then
dbms_output.put_line('Nicio modificare');
END;
/

Performantele calculatoarelor paralele

Parametrii sunt:
* speed-up: S(n) = T(1)/T(n)
* eficienta: E(n) = S(n)/n
* redundanta: R(n) = O(n)/O(1) // O(n) = nr de operatii efectuate pt n procesoare
* utilizare: U(n) = R(n)*E(n)
* calitate: Q(n) = S(n)*E(n)/R(n)

Relatii importante:
1/n <= E(n) <= U(n) <= 1
0 <= Q(n) <= S(n) <= n

Simulare pentru:
T(1) = n^2
T(n) = 6*n^2/(n+5)
O(1) = n^2-1
O(n) = n^2+n*log(n)

program sursa (Matlab)

CRC is back!

Despre calculul CRC am mai scris si aici.
Dar de data asta am calculat mult mai explicit (babeste);


Pe scurt, avem doua programe numite Generator si Verifier (~ Sender si Receiver din foto)
* Generatorul ia ca input, de la tastatura, un sir de biti de m caractere numit "Data" si un sir de biti de (n+1) caractere, numit Divisor. Sirul de biti este simulat in C++ cu un string ale carui valori sunt 1 si 0 (dar nefacandu-se verificarea inputului);
* Lui Data i se ataseaza n biti de 0, si se "imparte" la Divisor (important, divizorul trebuie sa aiba primul si ultimul bit de 1).
* Impartirea nu este una normala ci una numita "Modulo 2 Division" (link) de unde ne intereseaza restul, care devine CRC. Am implementat-o pur si simplu babeste, asa cum se face pe hartie (dar asta nu inseamna ca e si usor de inteles...);
* Datei initiale i se va atasa acest CRC, servit ca output intr-un fisier, alaturi de Divisor, pe randul doi. Asta este ceea ce face Generator;
* Verifier ia din acelasi fisier Data si Divisor si le imparte unul la altul (in acelasi mod);
* Daca restul este 0, datele au fost transmise corect de la "sender" la "receiver", altfel exista erori.
* Pentru simularea erorii, intervine programul Alter, care intrand in fisierul scris de Generator, inverseaza random un bit din Data (oricare dar nu cel mai semnificativ); daca se ruleaza Verifier, rezultatul va fi eroare.

Programele se pot descarca de aici.

20 octombrie 2011

Concepte de baza in IOS-ul routerelor


Pornind de la aceasta configuratie:

* Informatii despre versiunea de IOS, viteza procesorului, dimensiunea NVRAM, nr si tipul interfetelor existente:

in dynagen:
start Penny
telnet Penny

in Penny:
enable
show version
show running-config

* Configurarea routerelor cu nume si adresa ip (ex. pt Penny):
configure terminal
hostname Penny
interface 1/0
ip address 191.105.157.1 255.255.255.0
no shutdown

* Salvarea configuratiei curente:
copy running-config startup-config

* Configurarea unui echipament pt a putea fi accesat prin telnet, cu username si parola. Parola de enable sa fie secreta si salvata ca md5.
configure terminal
enable secret parola
username bumblebee password bumble

* Configurarea unui banner (mesaj de intampinare)
configure terminal
banner motd * Entering router... * &

* Afisare toate pachetele primite de router in timp real
debug ip packet
configure terminal
do ping google.com

12 octombrie 2011

Dynamips / Dynagen in Ubuntu

Dynagen este un emulator folosit pentru simularea mai profunda/reala a unor retele conectate prin routere Cisco.

INSTALARE DYNAMIPS/DYNAGEN IN UBUNTU:

sudo apt-get install dynamips
sudo apt-get install dynagen

Presupunem ca vrem sa implementam aceasta topologie:

La scrierea fiecarui fisier de configurare, trebuie sa rulam imaginea reala de IOS (sistemul de operare al routerelor Cisco), care se poate descarca de aici (daca aveti cont pe curs.cs) sau de aici (torrent). Binarul trebuie inclus la "image".

FISIER DE CONFIGURARE:

[localhost]

[[3640]]

image = /home/anna/Desktop/c3640-js.bin

ram = 160

[[router R1]]

model = 3640

slot0 = NM-4E

slot1 = NM-4T

E0/0 = R3 E0/0

E0/1 = s1 1

[[router R3]]

model = 3640

slot0 = NM-4E

E0/0 = R1 E0/0

E0/1 = R4 E0/0

E0/2 = R5 E0/0

E0/3 = R2 E0/0

[[router R2]]

model = 3640

slot1 = NM-4T

slot0 = NM-1E

E0/0 = R3 E0/3

[[router R5]]

model = 3640

slot1 = NM-4T

slot0 = NM-1E

E0/0 = R3 E0/2

[[router R4]]

model = 3640

slot0 = NM-4E

slot1 = NM-4T

E0/0 = R3 E0/1

E0/1 = s1 2

[[ETHSW s1]]

1 = access 1

2 = access 2

Acest fisier trebuie sa aiba extensia .net
RULARE

In consola:

dynamips -H 7200 &
dynagen task.net

In continuare se poate afisa configuratia creata:

list

Pentru fiecare router, modelul ales este 3640.

Slot0 si slot1 exprima prima cifra din notatia E0/x (Ethernet slot 0, portul x) sau S1/y (serial slot 1, port y).

Tipurile sloturilor pot fi: NM-4E (Ethernet cu 4 porturi), NM-4T (seriala cu 4 porturi), NM-1E (Ethernet cu un port), etc.

Pentru interfetele unui router, se asigneaza routerul la care se face conexiunea si interfata acestuia, iar in cazul unui switch legaturilor li se asigneaza tipul lor (access) si VLAN-ul (1,2).

06 septembrie 2011

Cursuri online la Stanford

Incepand cu data de 10 Octombrie, Stanford organizeaza cursuri
online de Inteligenta Artificiala, Invatare Automata si Baze de date.

Inscrierea este gratuita. Aceasta editie a cursului este inca
experimentala, dar vor exista prezentari online si teme de casa.
Durata este de 10 saptamani, va exista un examen partial si unul final.
La absolvire, se va obtine un statement of achievement.

Linkuri pentru informatii suplimentare & aplicare:


19 august 2011

Cursuri de assembler

Cursuri foarte bune, cu explicatii detaliate, ca la prosti (recunosc ca am avut revelatii citindu-le)

Recomandare: AICI

12 august 2011

Ce deosebeste Android de celelalte SO pentru mobile?

Primul mediu care imbina urmatoarele caracteristici:

- platforma deschisa, libera bazata pe Linux si open source

- reciclabilitate: parti ale unei aplicatii pot fi folosite in alta aplicatie, componente built-in pot fi inlocuite cu propriile versiuni, etc.

- foarte multe servicii disponibile: detectarea locatiei prin GPS sau trianghiularizare, baze de date SQL completa, browser, harti, ce pot fi incorporate in aplicatii.

- management automat al ciclului de viata al aplicatiei: programele sunt izolate unele de celalalte prin multiple straturi de securitate, ce asigura un nivel de stabilitate nemaintalnit la smart phones pana acum. Utilizatorul nu isi mai face griji in legatura cu ce aplicatii sunt active si sa le inchida pe unele ca sa ruleze altele (Android le va killari); optimizari pentru consumul redus de energie.

- grafica si sunete de inalta calitate: codec-uri, OpenGL, Smooth, etc

- portabilitate in jurul a numeroase dispozitive hardware: toate programele sunt scrise in Java si sunt executate de masina virtuala Dalvik, codul fiind portabil in ARM, x86 si alte arhitecturi. Suporta numeroase metode de intrare: tastatura, atingere, trackball. Interfata poate fi aranjata pentru orice rezolutie si orientare; insa cel mai important lucru este software-ul care se poate scrie pentru el.

mai multe aici

07 august 2011

Prima mea aplicatie Android


Un filtru de apeluri telefonice in functie de: apelant, ora si data apelului, locatia utilizatorului.
Cam asa va arata, mai multe detalii intr-o postare urmatoare....

24 iulie 2011

BUMBLEBEE



in sfarsit vi-l prezint pe Boomblebee, sponsorul si mentorul acestui blog :)
vizionare placuta

27 iunie 2011

Optimizari

Asa cum am relatat in postarea precedenta, algoritmul paralel implementat se dovedeste a fi foarte ineficient (cel putin la prima vedere).


Pentru a-l imbunatati, primii pasi vor fi sa:

  • - elimin recrearea contextului de fiecare data
  • - elimin recompilarea programului de fiecare data (+ 0.1-0.3 la fiecare apelare)
  • - incearc sa inlantuiesc mai multe seturi de kernel-uri in acelasi context (folosind event)
  • - evit daca pot interschimbarea haotica de date (e rau mai ales pe GPU)
  • - bitonic sort e un mod de a sorta datele foarte potrivit pentru arhitecturi paralele (inclusiv GPU-uri), sugestie in loc de bubble sort in kernel-uri
  • - incearc sa elimin/reduc acele loop-uri din kernel cumva (cu cat sunt mai multe branch-uri conditionale cu atat e mai rau)
  • - reduc alocarile/eliberarile de memorie, folosind eventual o memorie tampon prealocata.

Cod: se poate gasi aici: http://dl.dropbox.com/u/24465060/K_elem_v3.zip

Observatii: timpul de executie s-a imbunatatit considerabil doar urmand cateva dintre sugestii, desi sortarile in kernels au ramas bubble sort (= multe bucle, multe ramificatii, interschimbari haotice).

------------------------- Teste -----------------------------------------------


n = 2400
k = 2000

[1] GeForce 8600 GT (4 cu) = 0.50s
[2] GeForce 210 (2 cu) = 0.91s
[3] Cedar Radeon 5470 (2 cu) = 0.57s
[5] ATI RV730 (8 cu) = 0.69s

==================

n = 2000
k = 1282

[0] Intel(R) Core(TM)2 Duo CPU = 0.09s
[1] GeForce 8600 GT (4 cu) = 0.34s
[2] GeForce 210 (2 cu) = 0.65s
[3] Cedar Radeon 5470 (2 cu) = 0.54s
[4] Intel(R) Core(TM) i3 CPU = 0.13s
[5] ATI RV730 (8 cu) = 0.69s

==================

n = 1000
k = 333

[0] Intel(R) Core(TM)2 Duo CPU = 0.09s
[1] GeForce 8600 GT (4 cu) = 0.14s
[2] GeForce 210 (2 cu) = 0.32s
[3] Cedar Radeon 5470 (2 cu) = 0.56s
[4] Intel(R) Core(TM) i3 CPU = 0.13s
[5] ATI RV730 (8 cu) = 0.71s

==================

n = 443
k = 89

[0] Intel(R) Core(TM)2 Duo CPU = 0.10s
[1] GeForce 8600 GT (4 cu) = 0.14s
[2] GeForce 210 (2 cu) = 0.17s
[3] Cedar Radeon 5470 (2 cu) = 0.55s
[4] Intel(R) Core(TM) i3 CPU = 0.12s
[5] ATI RV730 (8 cu) = 0.67s

Concluzii:


  • nu este un algoritm care sa demonstreze eficienta calculului pe GPU comparativ cu calculul pe CPU – ceea ce intareste ideea ca DOAR anumite probleme pot fi executate mai rapid pe placa grafica si anume cele pe seturi mari de date cu aplicarea unor operatii repetitive (specific SIMD)
  • principale dezavantaje GPU: latenta mare de transfer a datelor din RAM catre VRAM (memoria placii grafice) si invers; aceasta poate fi acoperita prin executia rapida si repetata a unor task-uri
  • in cazul de fata, datorita memoriei locale limitate de pe GPU si a structurii algoritmului, valoarea lui n nu poate trece de un prag (aici, 2500) – posibil ca programul sa dea rezultate foarte bune in favoarea GPU pentru valori mult mai mari ale lui n
  • algoritmul a trebuit regandit de mai multe ori pentru a da rezultate cat mai bune atat pe CPU cat si pe GPU – programarea in OpenCL cere totusi cunoasterea arhitecturii platformelor