Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:2025:scala:secret_tema2 [2025/04/07 21:43]
razvang [Filtre peste Tabele]
pp:2025:scala:secret_tema2 [2025/04/10 12:09] (current)
tpruteanu
Line 82: Line 82:
 </​code>​ </​code>​
  
-**1.1.** Definiti metoda ''​toString''​ care returneaza tabelul in forma CSV.+**1.1** Definiti metoda ''​toString''​ care returneaza tabelul in forma CSV.
 <code scala> <code scala>
 override def toString: String = ??? override def toString: String = ???
 </​code>​ </​code>​
  
-**1.2** Definiti operatia de inserare a unei linii in tabel.+**1.2** Definiti metoda ''​fromCSV''​ care returneaza un tabel dintr-un string de tip CSV. 
 +<code scala> 
 +def fromCSV(CSV:​ String): Table = ??? 
 +</​code>​ 
 + 
 + 
 +**1.3** Definiti operatia de inserare a unei linii in tabel.
 <code scala> <code scala>
 def insert(row: Row): Table = ??? def insert(row: Row): Table = ???
 </​code>​ </​code>​
  
-**1.3** Definiti operatia de stergere a tuturor liniilor exact egale cu cea primita ca parametru.+**1.4** Definiti operatia de stergere a tuturor liniilor exact egale cu cea primita ca parametru.
 <code scala> <code scala>
 def delete(row: Row): Table = ??? def delete(row: Row): Table = ???
 </​code>​ </​code>​
  
-**1.4.** Definiti operatia de sortare a liniilor din tabel dupa o anumita coloana.+**1.5** Definiti operatia de sortare a liniilor din tabel dupa o anumita coloana. Functia are un parametru optional ce determina ordinea in care trebuiesc sortate. Mai mult despre parametrii optionali puteti gasi [[https://​docs.scala-lang.org/​tour/​default-parameter-values.html | aici]].
 <code scala> <code scala>
-def sort(column:​ String): Table = ???+def sort(column:​ String, ascending: Boolean = true): Table = ???
 </​code>​ </​code>​
  
-**1.5.** Definiti functia select care primeste o lista de stringuri si returneaza un nou obiect de tip Table ce contine doar coloanele specificate.+**1.6** Definiti functia select care primeste o lista de stringuri si returneaza un nou obiect de tip Table ce contine doar coloanele specificate.
 <code scala> <code scala>
 def select(columns:​ List[String]):​ Table = ??? def select(columns:​ List[String]):​ Table = ???
 </​code>​ </​code>​
  
-**1.6.** Definiti functia apply intr-un **companion object** al clasei ''​Table''​. Functia trebuie sa parseze un sir de caractere si sa returneze un tabel cu numele dat.+**1.7** Definiti functia cartesianProduct care primeste un alt tabel si returneaza un nou obiect de tip Table ce contine produsul cartezian al celor doua tabele. 
 +<code scala> 
 +def cartesianProduct(otherTable:​ Table): Table = ??? 
 +</​code>​ 
 + 
 +**1.8** Definiti functia join, care primeste un alt tabel si o coloana specifica pentru fiecare tabel. Aceasta functie va combina tabelele folosind coloanele indicate, rezultand intr-un nou tabel. 
 +  * Cand valorile din coloanele folosite pentru combinatie sunt identice, se va retine o singura valoare din acele coloane.  
 +  * Daca valorile difera, ele vor fi unite intr-un singur camp, separandu-le prin semnul ";"​. 
 +  * Se considera ca valorile de tip sir de caractere gol (""​) sunt echivalente cu NULL, adica acestea nu vor fi incluse daca exista o valoare specifica intr-o alta tabela. 
 +  * In situatiile in care o linie este prezenta in tabelul A dar nu are corespondent in tabelul B, se vor completa campurile corespunzatoare din tabelul B cu sirul vid ""​.  
 +  * Similar, daca o linieeste prezenta in tabelul B dar nu are corespondent in tabelul A, se vor completa campurile corespunzatoare din tabelul A cu sirul vid ""​. 
 +  * Numele coloanei utilizate pentru join in tabelul final va fi preluat din primul tabel.  
 +  * Se va intoarce eroare cand unul din tabele nu exista. Daca un tabel este gol, se va intoarce celalalt tabel. 
 +  * Liniile din rezultat sunt in ordinea: linii ce au intrări in ambele tabele, linii doar in prima tabela, linii doar in a doua tabela. 
 + 
 +<hidden Exemplu>​ 
 +**Exemplu:​** 
 + 
 +**Tabelul A** 
 +^id^name^age^ 
 +| 1  | Ana  | 20  | 
 +| 2  | Ion  | 30  | 
 +| 4 | Maria |     | 
 + 
 +**Tabelul B** 
 +^id^city^job^age^ 
 +| 1  | Cluj | IT  | 20  | 
 +| 2  | Iasi | HR  |     | 
 +| 3  | Buc  | MKT | 40  | 
 +| 4  | Buc  |     ​| ​    | 
 + 
 +**join("​A",​ "​id",​ "​B",​ "​id"​)** 
 +^id^name^age^city^job^ 
 +| 1  | Ana  | 20  | Cluj | IT  | 
 +| 2  | Ion  | 30  | Iasi | HR  | 
 +| 3  |      | 40  | Buc  | MKT | 
 +| 4  | Maria| ​    | Buc  |     | 
 +</​hidden>​ 
 + 
 +<code scala> 
 +def join(other: Table)(col1:​ String, col2: String): Table = ??? 
 +</​code>​ 
 + 
 +**1.9** Definiti functia apply intr-un **companion object** al clasei ''​Table''​. Functia trebuie sa parseze un sir de caractere si sa returneze un tabel cu numele dat.
 <code scala> <code scala>
 def apply(name: String, s: String): Table = ??? def apply(name: String, s: String): Table = ???
 </​code>​ </​code>​
 +
  
  
Line 130: Line 180:
   - Compound - reprezinta o conditie de filtrare compusa din mai multe conditii. Aceasta conditie este satisfacuta daca toate conditiile din lista conditions sunt satisfacute.   - Compound - reprezinta o conditie de filtrare compusa din mai multe conditii. Aceasta conditie este satisfacuta daca toate conditiile din lista conditions sunt satisfacute.
   - Not - reprezinta negarea unei conditii de filtrare.   - Not - reprezinta negarea unei conditii de filtrare.
-  - And- reprezinta conjunctia a doua conditii de filtrare. +  - And - reprezinta conjunctia a doua conditii de filtrare. 
-  - Or- reprezinta disjunctia a doua conditii de filtrare. +  - Or - reprezinta disjunctia a doua conditii de filtrare. 
-  - Equal- reprezinta o conditie de egalitate intre doua conditii de filtrare.+  - Equal - reprezinta o conditie de egalitate intre doua conditii de filtrare.
   - Any - reprezinta o conditie de filtrare care este satisfacuta daca cel putin una dintre conditiile din lista este satisfacuta.   - Any - reprezinta o conditie de filtrare care este satisfacuta daca cel putin una dintre conditiile din lista este satisfacuta.
   - All - reprezinta o conditie de filtrare care este satisfacuta daca toate conditiile din lista sunt satisfacute.   - All - reprezinta o conditie de filtrare care este satisfacuta daca toate conditiile din lista sunt satisfacute.
  
 <code scala> <code scala>
-trait FilterCond { def eval(r: Row): Option[Boolean] }+trait FilterCond { 
 +  ​def eval(r: Row): Option[Boolean] 
 +}
  
 case class Field(colName:​ String, predicate: String => Boolean) extends FilterCond { case class Field(colName:​ String, predicate: String => Boolean) extends FilterCond {
Line 164: Line 216:
 </​code>​ </​code>​
  
-**2.2.** Pentru a simplifica definirea conditiilor de filtrare, vom defini cateva operatori care sa ne permita sa scriem cod mai concis.+**2.2.** Pentru a simplifica definirea conditiilor de filtrare, vom defini cateva operatori ​in cadrul traitului `FilterCond` ​care sa ne permita sa scriem cod mai concis.
 Vom folosi urmatorii operatori ce extind clasa FilterCond: Vom folosi urmatorii operatori ce extind clasa FilterCond:
-  - === - pentru a verifica egalitatea a doua conditii de filtrare.+  - == - pentru a verifica egalitatea a doua conditii de filtrare.
   - && - pentru a face conjunctia a doua conditii de filtrare.   - && - pentru a face conjunctia a doua conditii de filtrare.
   - || - pentru a face disjunctia a doua conditii de filtrare.   - || - pentru a face disjunctia a doua conditii de filtrare.
   - !! - pentru a nega o conditie de filtrare.   - !! - pentru a nega o conditie de filtrare.
 <code scala> <code scala>
-extension (f: FilterCond) { 
-  def ==(other: FilterCond) = ??? 
-  def &&​(other:​ FilterCond) = ??? 
-  def ||(other: FilterCond) = ??? 
-  def !! = ?? 
-  // Puteti sa adaugati mai multi operatori :) 
-} 
-</​code>​ 
  
-**2.3.** In plus vom abstractiza instantierea unui obiect Field, astfel incat sa putem folosi un tuplu de forma  +def ==(other: FilterCond= ??? 
-(String, String ​=> Booleanpentru a crea un obiect Field. +def &&(otherFilterCond= ??? 
-<code scala> +def ||(otherFilterCond) ​= ??? 
-implicit ​def tuple2Field(t(String, String => Boolean)): Field = ???+def !! = ?? 
 +// Puteti sa adaugati mai multi operatori :)
 </​code>​ </​code>​
  
-**2.4.** Definiti operatia de filtrare a liniilor din tabel care respecta o anumita conditie.+**2.3.** Definiti operatia de filtrare a liniilor din tabel care respecta o anumita conditie.
 <code scala> <code scala>
 def filter(f: FilterCond):​ Table = ??? def filter(f: FilterCond):​ Table = ???
 </​code>​ </​code>​
  
-**2.5.** Definiti operatia de update a unei linii din tabel. Funcția primeste ca input o conditie care dicteaza liniile ce vor fi modificate. Valorile schimbate se găsesc intr-un Map[nume_coloana,​ valoare_noua]. Trebuiesc modificate TOATE liniile ce respectă condiția.+**2.4.** Definiti operatia de update a unei linii din tabel. Funcția primeste ca input o conditie care dicteaza liniile ce vor fi modificate. Valorile schimbate se găsesc intr-un Map[nume_coloana,​ valoare_noua]. Trebuiesc modificate TOATE liniile ce respectă condiția.
 <code scala> <code scala>
 def update(f: FilterCond, updates: Map[String, String]): Table = ??? def update(f: FilterCond, updates: Map[String, String]): Table = ???
Line 199: Line 244:
  
 O baza de date contine mai multe tabele, pe care putem aplica o serie de operatii: O baza de date contine mai multe tabele, pe care putem aplica o serie de operatii:
-  - create ​- creaza o noua tabela cu nume unic si o lista de coloane +  - insert ​- creaza o noua tabela cu nume unic si o lista de coloane 
-  - drop - sterge o tabela existenta+  - update - actualizeaza informatiile unei tabele deja existente 
 +  - delete ​- sterge o tabela existenta
   - selectTables - extrage din lista de tabele existente un subset de tabele   - selectTables - extrage din lista de tabele existente un subset de tabele
-  - join - combina doua tabele pe baza unei chei comune 
  
  
Line 212: Line 257:
 </​code>​ </​code>​
  
-**3.1.**. Implementati functia ​create, care primeste numele unei tabele si creeaza o noua tabela doar daca numele tabelei nu exista deja in baza de date. Daca numele tabelei exista, functia va intoarce baza de date nemodificata.+**3.1**. Implementati functia ​insert, care primeste numele unei tabele si creeaza o noua tabela doar daca numele tabelei nu exista deja in baza de date. Daca numele tabelei exista, functia va intoarce baza de date nemodificata.
 <code scala> <code scala>
-def create(tableName: String): Database = ???+def insert(tableName: String): Database = ???
 </​code>​ </​code>​
  
-**3.2.** Implementati functia ​drop, care primeste numele unei tabele si sterge ​tabela ​respectiva ​din baza de date.+**3.2** Implementati functia ​update ​care primeste numele unei tabele si tabela ​noua. Functia trebuie sa inlocuiasca tabela veche din baza de date cu noua tabela.
 Daca numele tabelei nu exista in baza de date, functia va intoarce baza de date nemodificata. Daca numele tabelei nu exista in baza de date, functia va intoarce baza de date nemodificata.
 <code scala> <code scala>
-def drop(tableName: String): Database = ???+def update(tableName: String, newTable: Table): Option[Database= ???
 </​code>​ </​code>​
  
-**3.3.** Implementati functia selectTables care primeste o lista de nume de tabele si extrage din baza de date doar acele tabele.+**3.3** Implementati functia delete, care primeste numele unei tabele si sterge tabela respectiva din baza de date. 
 +Daca numele tabelei nu exista in baza de date, functia va intoarce baza de date nemodificata. 
 +<code scala> 
 +def delete(tableName:​ String): Database = ??? 
 +</​code>​ 
 + 
 +**3.4** Implementati functia selectTables care primeste o lista de nume de tabele si extrage din baza de date doar acele tabele.
 Daca unul dintre numele de tabele nu exista in baza de date, functia va intoarce None. Daca unul dintre numele de tabele nu exista in baza de date, functia va intoarce None.
 <code scala> <code scala>
-def selectTables(tableNames:​ List[String]): ​Option[Database= ???+def selectTables(tableNames:​ List[String]):​ Database = ???
 </​code>​ </​code>​
  
-**3.4** Mai adăugati ceva (cautati voi functia de implementat :-D) la Table astfel incat sa putem accesa Rows din tabel folosind un index.+**3.5** Mai adăugati ceva (cautati voi functia de implementat :-D) la Table astfel incat sa putem accesa Rows din tabel folosind un index.
 Faceți același lucru si pentru Database ca sa putem accesa tabelele sale folosind index direct din numele unei instante. ​ Faceți același lucru si pentru Database ca sa putem accesa tabelele sale folosind index direct din numele unei instante. ​
 <code scala> <code scala>
Line 242: Line 293:
 </​code>​ </​code>​
  
-**3.5.** Implementati functia join, care primeste doua tabele si o coloana specifica pentru fiecare tabel. Aceasta functie va combina tabelele folosind coloanele indicate, rezultand intr-un nou tabel. +==== Query ====
-  * Cand valorile din coloanele folosite pentru combinatie sunt identice, se va retine o singura valoare din acele coloane.  +
-  * Daca valorile difera, ele vor fi unite intr-un singur camp, separandu-le prin semnul ";",​ urmand ordinea in care tabelele sunt enumerate in apelul functiei. +
-  * Se considera ca valorile de tip sir de caractere gol (""​) sunt echivalente cu NULL, adica acestea nu vor fi incluse daca exista o valoare specifica intr-o alta tabela. +
-  * In situatiile in care o linie este prezenta in tabelul A dar nu are corespondent in tabelul B, se vor completa campurile corespunzatoare din tabelul B cu sirul vid ""​.  +
-  * Similar, daca o linieeste prezenta in tabelul B dar nu are corespondent in tabelul A, se vor completa campurile corespunzatoare din tabelul A cu sirul vid ""​. +
-  * Numele coloanei utilizate pentru join in tabelul final va fi preluat din primul tabel.  +
-  * Se va intoarce eroare cand unul din tabele nu exista. Daca un tabel este gol, se va intoarce celălalt tabel. +
-  * Liniile din rezultat sunt in ordinea: linii ce au intrări in ambele tabele, linii doar in prima tabela, linii doar in a2a tabela.+
  
-<hidden Exemplu>​ +Testati structurile folosite executand niste query-uri, ce ar putea fi operatii necesare intr-un backend. ​**Query-urile ar trebuie sa fie one-linere, fara sa folositi ''​val''​ intermediare,​ dar puteti defini functii auxiliare (pentru filtre)**
-**Exemplu:**+
  
-**Tabelul A** +**4.1** Selectati din tabela ''​Customers''​ toti cei care au peste X ani si locuiesc intr-un oras din lista primita. Returnati raspunsul ordonat dupa ''​ID''​. 
-^id^name^age^ +<code scala> 
-| 1  | Ana  | 20  | +def query_1(db: Database, ageLimit: Int, cities: List[String]):​ Option[Table] = { 
-| 2  | Ion  | 30  | +... 
-| 4 | Maria |     |+}  
 +</​code>​
  
-**Tabelul B** +**4.2** Selectati din tabela ''​Orders''​ toate comenzile de dupa o data care nu au fost procesate de un angajat anume. Returnati doar ''​OrderID''​ si ''​Cost'',​ ordonat dupa ''​Cost''​ descrescator. 
-^id^city^job^age^ +<code scala> 
-| 1  | Cluj | IT  | 20  | +def query_2(db: Databasedate: StringemployeeID: Int): Option[Table] = { 
-| 2  | Iasi | HR  |     | +... 
-| 3  | Buc  | MKT | 40  | +} 
-| 4  | Buc  |     ​| ​    | +</code>
- +
-**join("​A"​"​id"​"​B",​ "​id"​)** +
-^id^name^age^city^job^ +
-| 1  | Ana  | 20  | Cluj | IT  | +
-| 2  | Ion  | 30  | Iasi | HR  | +
-| 3  |      | 40  | Buc  | MKT | +
-| 4  | Maria| ​    | Buc  |     | +
-</hidden>+
  
 +**4.3** Selectati din tabelele ''​Customers''​ si ''​Orders''​ cine a facut comenzii cu ''​Cost''​ peste o valoare data. Returnati ''​CustomerName'',​ ''​OrderID'',​ ''​EmployeeID''​ si ''​Cost'',​ ordonat dupa ''​EmployeeID''​ crescator.
 <code scala> <code scala>
-def join(table1Stringc1String, table2: String, c2: String): Option[Table] = ???+def query_3(dbDatabaseminCostInt): Option[Table] = 
 +... 
 +}
 </​code>​ </​code>​
  
Line 305: Line 343:
 </​code>​ </​code>​
  
-==== Puncatje ​====+==== Punctaje ​====
  
 Pentru ca avem cam multe exercitii de implementat,​ găsiți mai jos un tabel cu punctajele grupate: Pentru ca avem cam multe exercitii de implementat,​ găsiți mai jos un tabel cu punctajele grupate:
-WIP WIP WIP WIP 
 ^ Parte a temei ^ Functionalitate ^ Punctaj ^ ^ Parte a temei ^ Functionalitate ^ Punctaj ^
-| Table | toString | 0.5 +| Table | toString | 3 | 
-| Table | insert | 1.5 +| Table | fromCSV | 3 
-| Table | delete | 1.5 +| Table | insert | 
-| Table | sort | 1.5 +| Table | delete | 
-| Table | select | 1.5 | +| Table | sort | 
-| Table | apply 1.5 | +| Table | select | 3 | 
-| Table | filter | 4.5 +| Table | cartesianProduct | 7.5 | 
-| Table | update | 4.5 +| Table | join 7.5 
-| **TABLE** | **TOTAL** | **17** | +| Table | apply | 4 
-| Filter | Field | |+| Table | filter | 4 | 
 +| Table | update | 4 | 
 +| **TABLE** | **TOTAL** | **45** | 
 +| Filter | Field | |
 | Filter | Compound | 3 | | Filter | Compound | 3 |
-| Filter | Not | +| Filter | Not | 
-| Filter | And | +| Filter | And | 
-| Filter | Or | +| Filter | Or | 
-| Filter | Equal | +| Filter | Equal | 
-| Filter | Any | +| Filter | Any | 
-| Filter | All | +| Filter | All | 3 | 
-| **FILTER** | **TOTAL** | **22** | +| Filter | operator == | 1.5 | 
-| Database | create ​1.5 +| Filter | operator && | 1.5 | 
-| Database | drop 1.5 +| Filter | operator `|`| | 1.5 | 
-| Database | selectTables | 1.5 +| Filter | operator ! | 1.5 
-| Database | indexing | 1.5 +| **FILTER** | **TOTAL** | **30** | 
-Database ​join | 10 |+| Database | insert ​
 +| Database | update ​3 | 
 +| Database | delete| 3 
 +| Database | selectTables | 
 +| Database | indexing | 
 +**DATABASE** ​**TOTAL** ​**15** | 
 +| Query | query1 | 3 | 
 +| Query | query2 | 3 | 
 +| Query | query3 | 4 | 
 +| **QUERY** | **TOTAL** | **10** |
 | ''​TEMA 2''​ | ''​TOTAL''​ | ''​100''​ | | ''​TEMA 2''​ | ''​TOTAL''​ | ''​100''​ |