Documente Academic
Documente Profesional
Documente Cultură
FACULTATEA DE MATEMATICĂ
SPECIALIZAREA: MATEMATICĂ INFORMATICĂ
Lucrare de Licenţă
Coordonator Ştiinţific,
Conf. Dr. Mihai Gontineac
Absolvent,
Barbu Aida-Claudia
IAŞI
2022
UNIVERSITATEA ALEXANDRU IOAN CUZA
FACULTATEA DE MATEMATICĂ
SPECIALIZAREA: MATEMATICĂ INFORMATICĂ
Lucrare de Licenţă
Elemente de programare ı̂n limbajul Scala
Coordonator Ştiinţific,
Conf. Dr. Mihai Gontineac
Absolvent,
Barbu Aida-Claudia
IAŞI
2022
2
Cuprins
1 Introducere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3 Variabile şi tipuri de date ı̂n Scala. Funcţiile println, printf şi read-
Line, For . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3
1 Introducere
Tema lucrării este ”Elemente de programare ı̂n limbajul Scala”. Scopul aces-
teia este de a oferi informaţii despre un limbaj de programare multiparadigma1 , lucru
realizat atât printr-o prezentare teoretică a limbajului de programare Scala, dar şi prin
compararea acestuia cu alte limbaje.
Motivul pentru care am ales această temă este de a ı̂nvaţa un alt limbaj de
programare. În lucrare am ı̂ncercat să punctez câteva noţiuni despre Scala, precum:
noţiunile de bază, motivul pentru care este un limbaj scalabil2 , o comparaţie ı̂ntre Scala,
Java, C] şi Python. Este prezentat programul pentru un calculator elementar ı̂n fiecare
din cele trei limbaje şi realizată ulterior o comparaţie. Pentru cunoscătorii limbajului
Java, Scala este mult mai uşor de ı̂nţeles deoarece se regăsesc noţiuni din Java.
Scala este un limbaj apărut ı̂n 2003. Din imaginea de mai jos putem observa
că ı̂n 2020 a devenit foarte utilizat de către programatori, ı̂n comparaţie cu alte limbaje
mai vechi. Mai observăm că el se regăseşte printre primele 15 limbaje de programare şi
este apreciat de programatori 53.2 %, iar ı̂n anul 2015 avea o rată de 1.3%.
1
Limbaj de programare care suportă mai multe stiluri fundamentale de programare.
2
Un limbaj de programare care combină metode orientate pe obiecte cu programarea funcţională,
care acceptă un stil de programare mai concis decât alte limbaje de uz general precum Java, reducând
cantitatea de cod pe care trebuie să o scrie dezvoltatorii
4
2 Introducere ı̂n Scala
Scala reprezintă o prescutare pentru Scalable Language, limbaj creat de Martin
Odersky. Acest limbaj de programare uneşte conceptul de programare orientată pe
obiect cu cel de programare funcţională. Programele scrise ı̂n Scala pot fi convertite ı̂n
bytecodes.
De ce Scala şi nu un alt limbaj de programare? Există multe motive pentru
care Scala este un limbaj popular printre programatori. Acestea pot fi: faptul că este
un limbaj foarte uşor de ı̂nvăţat, mai ales de către programatorii Java, este scalabil3 şi
productiv conţinând caracteristici ale altor limbaje precum C, C++, Java etc. Compi-
latorul poate interpreta clasele Java, poate utiliza cadrul, bibliotecile şi instrumentele
Java. După compilare, codul sursă poate fi rulat pe Maşina Virtuală Java. Poate
dezvolta aplicaţii bazate pe web (prin compilarea ı̂n JavaScript) şi desktop (prin com-
pilarea ı̂n bytecode Java Virtual Machine). Este utilizat ı̂n companii populare precum
Apple, Twitter, Walmart, Google ı̂n operaţiuni de backend, datorită scalabilităţii sale.
Trebuie precizat faptul că limbajul Scala nu este o extensie a limbajului Java.
Codul sursă poate fi scris ı̂n Scala ı̂n oricare dintre editorii de text populari, cum
ar fi: Notepad++, gedit etc. După ce scrieţi programul, salvaţi fişierul cu extensia .sc
sau .scala.
În continuare evidenţiem câteva diferenţe dintre Scala şi celelalte limbaje de
programare. Este pur orientat pe obiecte deoarece fiecare valoare din Scala este un
obiect. Fiecare funcţie este o valoare şi fiecare valoare este un obiect, prin urmare,
fiecare funcţie este un obiect, ceea ce face programarea funcţională 4 să fie abordabilăı̂n
Scala. În momentul compilării se realizează procesul de verificare şi punere ı̂n aplicare
a tipurilor statice, de cele mai multe ori, utilizatorul nu are nevoie să specifice un tip
de date. Pot fi adăugate noi construcţii de limbaje sub formă de biblioteci. Permite
programatorului să scrie codurile ı̂ntr-o maniera stabilă, reduce numărul de linii şi ajută
programatorul să codeze ı̂ntr-un singur tip. Java şi Scala au un mediu comun de rulare
ceea ce ajută utilizatorul să se mute cu uşurinţă de la Java la Scala. Cu ajutorul lui
Scala utilizatorul poate personaliza clasele din Java.
Avantaje:
5
Regăsim Traits( sunt colecţii de metode abstracte şi non-abstracte care pot fi
compilate in interfeţele Java).
Dezavantaje:
Aplicaţii:
1 //Exemplul 1:
2 var x = 10
3 x = 5 //funcţionează chiar dacă nu am pus var ı̂nainte
4 //Exemplul 2:
5 var x : Int = 100 //aici am menţionat explicit tipul de date al variabilei
b)Variabilă imutabilă: Cuvântul cheie este val. Putem declara astfel:
1 //Exemplu:
2 val = 10
3 x= 11 //ne apare o eroare deoarece am modificat conţinutul variabilei
4 imutabile, ceea ce nu e permis
6
Reguli pentru denumirea variabilelor ı̂n Scala: numele variabilei trebuie să fie
scrisă cu litere mici, poate conţine litere, cifre şi două caractere speciale ( şi $), nu
trebuie sa contină cuvântul cheie sau cuvântul rezervat. Spaţiile nu sunt permise ı̂n
numele variabilei.
1 object Exemplu
2 {
3 def main(args: Array[String])
4 {
5 hspace40pt Console.println(”Bine ai venit ı̂n Scala!”)
6 print(”Recent”)
7 print(” program”)
8 println()
9 printf(”Apărut ı̂n %d.”,2003)
10 }
11 }
Ieşire:
Bine ai venit ı̂n scala!
Recent program
Apărut ı̂n 2003.
ReadLine(): este o metodă prin care dăm intrări ı̂n modelul String de la tas-
tatură.
12 object Exemplu
13 {
14 def main(args: Array[String])
15 {
16 while(true) // while este de natură infinită
17 {
18 val valoare = scala.io.StdIn.realLine()
19 printf(”Rezultatul primit de la tastatură este: %s”, valoare)
20 println()
21 }
22 }
23 }
7
Ieşire:
//Se dă primul şir de caractere
exemplul
Rezultatul primit de la tastatură este: exemplul
8
Declararea şi definiţia funcţiei
Folosim ca şi cuvântul cheie def pentru a declara o funcţie. Numele funcţiei
(function name) poate conţine si caractere precum +, ∼, &, −, ++, n, / etc. În cazul ı̂n
care nu este specificat niciun tip de returnare, atunci funcţia primeşte tipul de returnare
implicit , şi anume Unit, care este echivalent cu void ı̂n celelalte limbaje. Un utilizator
poate crea o funcţie cu sau fără egal, dacă folosim egal atunci funcţia va returna valoarea
dorită, ı̂n caz contrar, funcţie nu va returna nicio valoare. Corpul funţiei este scris
ı̂ntre acolade.
Sintaxa:
def nume funcţie([lista parametrii]):[tip return] =
{
//corpul funcţiei
}
1 class Exemplu{
1 def ı̂mpărţire(a:Int, b:Int)={
3 a/b
4 }
5 }
6
7 object ExempluMain{
8 def main(args:Array[String]){
9 var x=new Exemplu()
10 x.ı̂mpărţire(10,0)
11 }
12 }
Există două tipuri de apelarea funcţiei:
a) nume funcţie(lista parametri): metoda standart
b)[instanţă].nume funcţie(lista parametri): funcţie cu ajutorul instanţei
9
→ public Thread.State getState():Returnează starea acestuia. Metoda este con-
cepută pentru monitorizare, nu pentru control.
→ public final boolean isAlive(): Testează dacă acesta este ı̂ncă activ.
→ public final void join() throws InterruptedException: Aşteaptă ca acesta
să se ı̂ntrerupă.
→ public void run: Metoda de rulare a obiectului este apelată doar ı̂n cazul ı̂n
care firul de execuţie foloseşte un obiect Run separat.
→ public final void setName(String name): Setează numele.
→ public final void setPrioriry(int newPriority): Setează prioritatea.
1 package A{
2 package B{
3 class a(x:int){
4 def get = x
5 }
6 }
7 }
După ce compilăm acest cod, se va crea un director numit A şi ı̂n interiorul
acestuia se va crea alt director cu numele B ce va conţine fişierul a.class.
Caracteristici avansate
Scala oferă multe caracteristici şi constructori avansaţi care uşurează pro-
gramarea. Acesta este un limbaj de programare orientat pe obiect, iar principala sa
facilitate de structurare a datelor este clasa. Tipurile de date sunt declarate ca nişte
clase abstracte şi toate formele tipului sunt declarate ca subclase ale clasei abstracte.
Un tip se numeşte abstract dacă identitatea sa nu este cunoscută cu precizie.
10
class numeClasăPărinte extends numeClasăCopil{
//Metode şi câmpuri
}
1 class InvalidExceţie(a:String) extends Exception(a) {}
1 val x= List(1,3,5,7,9)
2 val ieşire= x.map(i=>i∗2)
3 println(ieşire)
Valoarea ieşirii este calculată de ı̂ndată ce operaţia este aplicată asupra acesteia.
Valoarea nu este calculată până când nu avem nevoie de ea ı̂n ultima linie.
Scala foloseşte evaluarea leneşă pentru a optimiza procesul de calcul şi ajută la
rezolvarea dependenţelor circulare. Programatorul poate pierde controlul asupra codului
deoarece sunt scrise expresii pe care nu le evaluam, dacă avem erori sunt foarte dificil
11
de găsit. Creşte cu mult complexitatea programului, deoarece trebuie stocate toate
instrucţiunile.
1 object Exemplu{
2 def main(args:Array[String]){
3 val a= Map(”Pâine” − > 30, ”Ulei” − > 10)
4 val b= Map(”Făină” − > 20, ”Ulei” − > 10)
5 val concat= a.++(b)
6 println(”Concatenarea celor doua hărţi este: ”+concat)
7 }
8 }
•def-(element1,element2...):Map(X,Y) metodă utilizată pentru a şterge o serie
de chei din Map.
5
Obiectul nu poate fi schimbat.
12
1 object Exemplu {
2 def main(ars:Array[String]) {
3 val x=scala.collection.mutable.Map[String,Int](”Vârsta Anei ” -> 5,
4 ”Vârsta lui Mihai ” -> 20, ”Vârsta Irinei ” -> 15)
5 val y=x.-(”Vâsrta lui Mihai”)
6 println(”Lista finală: ” +y)
7 }
8 }
•def get(cheie:X):Opţiune[Y] folosită la returnarea valorii unei chei.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val y=Map(”Mihai”->22,”Florin”->20)
5 val x1=x.get(”Ana”)
6 val y1=y.get(”Ioan”)
7 println(x1)
8 println(y1)
9 }
10 }
La ieşire va returna Some(10) pentru primul println şi None pentru al doilea.
•def iterator:Iterator[(X,Y)] utilizată pentru returnarea unui iterator.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val y=Map(”Mihai”->22,”Florin”->20)
5 val x1=x.iterator
6 val y1=y.iterator
7 println(x1)
8 println(y1)
9 }
10 }
Aici returnează iterator nevid deoarece ambele sunt non-empty.
•def addString(x:StringBuilder):StringBuilder adaugă fiecare dintre elemente
ı̂n Map.
13
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val y=Map(”Mihai”->22,”Florin”->20)
5 val x1=x.addString(new StringBuilder())
6 val y1=y.addString(new StringBuildr())
7 println(x1)
8 println(y1)
9 }
10 }
•def addString(x:StringBuilder,y:String):StringBuilder la fel, adaugă elemente
doar că le adaugă cu un separator.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val y=Map(”Mihai”->22,”Florin”->20)
5 val x1=x.addString(new StringBuilder(),” ”)
6 val y1=y.addString(new StringBuilder(), ” ”)
7 println(x1)
8 println(y1)
9 }
10 }
•def apply(cheia:X):Y util pentru căutarea unei chei.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val y=Map(”Mihai”->22,”Florin”->20)
5 val x1=x.apply(”Maria”)
6 val y1=y.apply(”Mihai”)
7 println(x1)
8 println(y1)
9 }
10 }
•def clear():X utilizată pentru a şterge map.
14
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=scala.collection.mutable.Map(”Ana”->10,”Maria”->18)
4 val x1=x.clear()
5 println(x1)
6 }
7 }
•def clone():Map[X,Y] utilizată pentru a creea o clonă.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=scala.collection.mutable.Map(”Ana”->10,”Maria”->18)
4 val x1=x.clone()
5 println(x1)
6 }
7 }
•def count( x:(X,Y)=> Boolean): numără perechile de chei din Map.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val x1=x.count(i=>true)
5 println(x1)
6 }
7 }
•def equals(Map):Boolean verifică dacă două hărţi sunt egale.
1 object Exemplu {
2 def main(args: Array[String]){
3 val x=Map(”Ana”->10,”Maria”->18)
4 val y=Map(”Mihai”->22,”Florin”->20)
5 val x1=x.equals(y)
6 println(x1)
7 }
8 }
15
1 object Exemplu {
2 def main(args: Array[String]) {
3 val x= List(1,2,3)
4 val x1=List(9,8,7)
5 def y=(i:Int) => i*3
6 val rez= x.map(i=> y(i))
7 val rez2=rez.++(x1)
8 println(Lista devine: ” + rez2)
9 }
10 }
Ieşire: Lista devine: Listă(3,6,9,8,7).
1 class Exemplu{
2 def ı̂mpărţire(a:Int, b:Int)={ a/b}
3 }
4 object ExempluMain{
5 def main(args:Array[String]){
6 var x=new Exemplu()
7 x.ı̂mpărţire(10,0)
8 }
9 }
Pentru a gestiona excepţia, Scala oferă blocul try-catch. Un exemplu de utilizare
a bocului try-catch:
1 class Exemplu{
2 def ı̂mpărţire(a:Int , b:Int)={
3 try{ a/b}
4 catch{ case x:ExcepţieAritmetică=> println(x)}
5 println(”Se execută restul codului... ”)
6 }
7 }
8 object ExempluMain{
9 def main(args:Array[String]){
10 var x=new Exemplu()
11 x.ı̂mpărţire(10,0)
12 }
13 }
16
Blocul final este utilizat la eliberarea resurselor ı̂n timpul excepţiei. Resursele
pot fi fişiere, conexiune la reţea, la baza de date etc. Un exemplu cu acest bloc:
1 class Exemplu{
2 def ı̂mpărţire(a:Int , b:Int)={
3 try{
4 a/b
5 var array=Array(1,2)
6 array(10)
7 }
8 catch{
9 case x:ExcepţieAritmetică=> println(x)
10 casee:Exception =>println(e)
11 case throw:Throwable =>println(”o altă excepţie ”+throw)
12 }
13 finally{
14 println(” Se execută codul)
15 }
16 println(”Restul codului se execută”)
17 }
18 }
20 object ExempluMain{
21 def main(args:Array[String]){
22 var x=new Exemplu()
23 x.ı̂mpărţire(10,5)
24 }
25 }
Scala ne mai oferă cuvinte cheie pentru aruncarea explicit a unor excepţii, şi
anume throw şi throws. Un exemplu de utilizare a excepţiei throws:
1 class ExempluExcepţie{
2 @throws(classOf[NumarFormatExcepţie])
3 def validate()={ ”text”.toInt}}
4 object ExempluMain{
5 def main(args:Array[String]){
6 var x=new ExempluExcepţie()
7 try{
8 x.validate()
9 }
10 catch{
11 case e:NumarFormatExcepţie => println(”Excepţia”)
12 }
13 println(”Restul codului se execută”)
14 }
15 }
17
În Scala putem să ne creem propriile excepţii extinzând clasa Exception ı̂n timp
ce declarăm propria excepţie. Un exemplu de excepţie personalizată:
1 class InvalidExceţie(a:String) extends Exception(a) {}
2
3 class ExempluExcepţie{
4 @throws(classOf[InvalidExcepţie])
5 def validare(nr:Int){
6 if(nr¡20){
7 throw new InvalidExcepţie(”Excepţia personalizată”)
8 }
9 else{
10 println(”Programul funcţionează”)
11 }
12 }
13 }
14
15 object ExempluMain{
16 def main(args:Array[String]){
17 var x=new ExempluExcepţie()
18 try{
19 x.validare(5)
20 }
21 catch{
22 case x:Exception => println(”Excepţie curectă: ”+x)
23 }
24 }
25 }
Scala vs Java
Prima diferenţă dintre cele două limbaje este aceea că Java reprezintă un limbaj
de uz general ce poate fi orientat pe obiect, pe când Scala este atât limbaj orientat pe
obiect, cât şi de programare funcţională. În Scala compilatorul este mult mai flexibil, iar
limbajul este mai puţin pompos faţă de Java, putem vedea acest lucru prin urmatorul
program:
18
1 public class ExempluJava{
2 public static void main(String[]args){
3 System.out.println(”Exemplul ı̂n Java”);
4 }
5 }
6
7 object ExempluScala{
8 def main(args: Array[String]): Unit= {
9 println(”Exemplu ı̂n Scala”)
10 }
11 }
Chiar dacă la Scala avem un compilator flexibil, procesul de compilare este unul
lent faţă de procesul de compilare ı̂n cod octet din Java care este mai rapid. Putem
adăuga mai multe obiecte ı̂ntr-o listă la creearea acesteia, ı̂n timp ce ı̂n Java trebuie
creată mai ı̂ntâi lista, apoi adăugate pe rând obiectele, ca ı̂n exemplu de mai jos:
6
Reprezintă o strategie care ı̂ntârzie evaluarea unei expresii până când este necesară rezultatul expre-
siei
19
1 //Mai ı̂ntâi vom da un exemplu ı̂n Java:
2 public class Utilizator{
3 private String nume;
4 private List<Ordin> ordinul;
5 public Utilizator(){
6 ordinul = new ArrayList<Ordin>();
7 }
8 public String getNume(){
9 return nume;
10 }
11 public String setNume(String nume){
12 return ordinul;
13 }
14 }
15
16 public class Ordin{
17 private int id;
18 public Ordin(){
19 produse= new ArrayList<Produs>();
20 }
21 public int getId(){
22 return id;
23 }
24 public void setId(int id){
25 this.id=id;
26 }
27 }
28
29 //Acelaşi program scris ı̂n Scala:
30 class Utilizator{
31 var nume: String=
32 var ordinul: List[Ordin]= Nil;//Nill este echivalent cu Null
33 }
34
35 class Ordin{
36 var id: Int=
37 }
În ambele programe avem variabile, dar ı̂n Scala sunt implicit de tip imuabil(nu
se poate schimba), iar ı̂n Java de tip mutabil. Cuvântul cheie static este regăsit doar ı̂n
Java. Convertirea ı̂n Scala se face mult mai rapid, utilizând doar o linie de cod:
20
1 val numere= list.map(x=>s.toInt)
2
3 //Iar ı̂n Java:
4 List<Integer> numere = new ArrayList<Integer<();
5 for(String x: list){
6 numere.add(Integer.parseInt(x));
7 }
Scala vs Python
Phyton reprezintă un limbaj de programare dinamică care necesită mai puţină
tastare, oferă biblioteci noi şi alte funcţii noi, nu este necesar să specificam tipul obiecte-
lor. Scala este un limbaj de programare pur orientat pe obiecte, trebuie să spunem tipul
fiecarei variabile / funcţii/ obiecte. Dintre cele două limbaje, putem spune ca Phyton-ul
este mai uşor de ı̂nvăţat, chiar dacă este mai greu de ı̂nvăţat. Aşa cum ne sugerează şi
definiţia Scalei, ea oferă suport scalabil, iar Phyton nu oferă.
Limbajul Phyton este utilizat mai ales pentru proiecte la scară mică, ı̂n timp ce
Scala este utilizat la proiecte mari. Testarea ı̂n Phyton este mult mai complexă decât ı̂n
Scala, deci cea mai bună testare este cea ı̂n Scala.
Scala vs C++
C++ oferă cea mai bună performanţă, dar este cel mai extins program, pe
când Scala oferă cea mai concisă notaţie şi optimizare a codului. Din cauză că rulează
pe JVM, Scala poate accesa toate bibliotecile din Java, de aceea are mult mai multe
biblioteci faţă de C++. Putem spune ca Scala este pentru Java exact acelaşi lucru cum
este C++ pentru C. Limbajul C++ oferă cea mai rapidă compilare decât Scala.
Atât ı̂n Java, cât şi ı̂n C++, C, C] trebuie pus la fiecare linie de cod (aproape)
”;”, pe când la Scala, cum am putut observa din exemplele date până acum, nu trebuie
să punem ”;”.
Scala vs C]
C] ruleaza ı̂n .NET şi oferă multe biblioteci care conţin clase şi nu mai trebuie
specificate. Faţă de Scala, C] este un limbaj foarte complex şi mai greu de ı̂nvaţat.
Dacă dorim să modificăm codul ı̂n C] sau dacă scriem o linie noua de cod, trebuie să
recompilăm deoarece pot interveni erori şi la un număr mare de erori ţi se complică
munca, pe când un program ı̂n Scala este mult mai uşor de modificat, nefiind aşa de
complexa scrierea unui cod. Testarea se face mult mai usor şi mai eficientă in Scala
decât ı̂n alte limbaje.
21
Compararea Scala-Java-C]-Python pe un exemplu concret
Dimensiune folder: 13 KB - 17,1 KB - 42 KB - 4KB
Numărul de linii ı̂n cod: 478 - 269 - 195 - 75
Mod de lucru: Aplicaţie făcută ı̂n Intelij IDEA- Aplicaţie făcută ı̂n Notepad++-
Aplicaţie făcută ı̂n Visual Studio- Aplicaţie făcută ı̂n Python Idle.
Timp compilare: 3.34 secunde compilat direct ı̂n aplicaţie- 1.30 secunde pentru
compilare.bat şi 1.71 secunde pentru a se deschide aplicaţia cu start.bat- 4.78 secunde
compilat direct ı̂n aplicaţie- 2.08 secunde compilat direct din aplicaţie.
Descriere:
SCALA: În acest limbaj am prelucrat fiecare buton ı̂n parte, marea majoritate a
codului se repetă. Ceea ce ţine de creearea ferestrei este foarte simplu de realizat prin
câteva linii de cod. Codul este foarte uşor de ı̂nteles şi de scris deoarece apelam puţine
metode si funcţii şi nu mai suntem obligaţi să punem ; după fiecare linie după fiecare
linie de cod şi de aceea nu ne va genera foarte des erori. Compilatorul este mult mai
flexibil faţă de cel al altor limbaje. Modificarea/ ştergerea/ adăugarea unei linii de cod
este foarte uşor, nu ne conduce la prea multe erori de care nu putem scăpa foarte uşor.
JAVA: Suntem obligaţi să punem ; după fiecare linie ştim dacă sunt erori ı̂n codul
nostru deoarece este lucrat ı̂n notepad++, ceea ce duce la a pierde destul de mult timp
pe compilarea frecventă. Trebuie făcut un fişier de start şi de compilare faţă de celelalte
limbaje.
C]: Interfaţa o vom putea face după bunul plac ı̂n form1.Designer.cs, fără a necesita
să scriem cod ca ı̂n celelalte două limbaje. Codul este unul destul de complex, trebuie
pus ; la sfârşitul fiecarei linii de cod. Majoritatea erorilor sunt din cauza ; sau a utilizării
incorecte a unor metode/funcţii/clase. Trebuie să fim foarte atenţi când modificăm/
ştergem/adăugăm o linie de cod deoarece ne poate conduce foarte uşor la erori greu de
rezolvat.
PYTHON: Am prelucrat fiecare buton individual, codul butoanelor repetându-se.
S-a realizat o functie speciala pentru apasarea butoanelor, pentru butonul egal si delete.
Majoritatea erorilor ı̂ntâlnite aici au fost din cauza spaţiilor, nu avem erori din cauza ;,
dar există totuşi erori asemănătoare.
Pachete folosite ı̂n creearea aplicaţiei:
1 import javax.swing. {JComponent, KeyStroke}
2 import scala.swing.
3 import javax.swing. {BorderFactory, UIManager}
4 import scala.swing. MenuBar.NoMenuBar.{ contents, listenTo, reactions}
SCALA:
5 import scala.swing. event. {ButtonClicked, Key, KeyPressed}
6 import scala.swing. event.ButtonClicked
7 import scala.swing. event.KeyTyped
8 import scala.swing. event.KeyPressed
1 import java.awt.*;
JAVA:
2 import java.awt.event.*;
22
1 using System;
2 using System. Collections.Generic;
3 using System. ComponentModel;
4 using System.Data;
C]: 5 using System. Drawing;
6 using System.Linq;
7 usingSystem.Text;
8 using System. Threading.Tasks;
9 using System. Windows.Forms;
1 from tkinter import *
PYTHON:
2 import math
Crearea interfeţei cod:
10 object Calculator{
11 def main (args: Array [String]){
12 val calculator = new CalcGrid
13 val frame = new Frame{
14 title= ”Calculator”
15 val panel= calculator.CalcPanel()
SCALA: 16 contents = panel
17 size=new Dimension(450,520)
18 centerOnScreen()
19 }
20 frame.open()
21 }
22 }
4 public class Calculator extends Frame{
21 final int FRAME WIDTH= 600,FRAME HEIGHT= 600;
83 addWindowListener( new WindowAdapter() {
84 public void windowClosing(WindowEvent e){
85 System.exit(0);
JAVA: 86 }
87 });
88 setLayout(null);
89 setSize(FRAME WIDTH,FRAME HEIGHT);
90 setVisible(true);
91 }
C]: Aici interfaţa se creează o dată la deschiderea unui proiect ı̂n WindowsFormApp.
23
24 class CalcGrid(){
25 var NumTxt= new TextField{
26 background = new Color(200,130,20)
27 preferredSize=new Dimension(100,100)
28 border= BorderFactory.createCompound Broder(
SCALA: 29 BorderFactory.create LoweredBevelBorder(),
30 BorderFactory.create EmptyBorder(0,5,0,5))
31 editable =false
32 horizontalAlignment= Alignment.Right
33 visible= true
34 }
25 Calculator(String frameText){
26 super(frameText);
28 int tempX=TOPX, tempY=TOPY;
29 displayLabel.set Bounds(tempX,tempY, 240,HEIGHT);
JAVA: 30 displayLabel.set Background(Color.BLUE);
31 displayLabel.set Forefroung(Color.YELLOW);
32 add(displayLabel);
33 memLabel.setBounds (TOPX,TOPY+ HEIGHT+V SPACE, WIDTH, HEIGHT);
34 add(memLabel);
C]: Se creează caseta de text direct ı̂n formă, fără să necesite cod.
45 self.e = Entry(master)
PYTHON: 46 self.e.grid(row=0,column=0,columnspan=6,pady=3)
47 self.e.focus set()
Crearea butoanelor şi poziţionarea:
35 val btn0 = new Button(”0”) {
36 background = new Color(200, 130, 20)
37 preferredSize =new Dimension(70,45)
38 }
39 Se procedează la fel şi pentru restul butoanelor.
40 Definim o funcţie pentru operaţiile +,-,*,/.
SCALA: 117 def do oper(oper:String, l:Double, r:Double) :Double = oper match {
118 case ”+” => l+r
119 case ”-” => l-r
120 case ”*” => l*r
121 case ”/” => if (r == 0.0) Double.NaN
122 else l/r
123 }
9 String digitButonNumar[]= {”7”,”8”,”9”,”4”,”5”,”6”, ”1”,”2”, ”3”,
10 ”0”,”+/-”,”.”};
JAVA:
11 String operatorButonNumar[]= {”/”,”sqrt”,”*”,”%”, ”-”,”+”,”=”};
12 String specialButonNumar[]= {”C”};
C]: Se creează butoanele şi poziţionarea lor direct ı̂n aplicaţie.
24
51 Button(master,text=”=”,width=5,height=7,fg=”black”,bg=”light
52 green”,command=lambda: self.egal()).grid(row=3,column=4,rowspan=4)
53 Button(master,text=’C’,width=5,height=3,fg=”black”,bg=”light
54 green”,command=lambda: self.sterge()).grid(row=4,column=2)
55 Button(master,text=”+”,width=5,height=3,fg=”black”,bg=”light
56 green”,command=lambda: self.apasa(’+’)).grid(row=4,column=3)
57 Button(master,text=”x”,width=5,height=3,fg=”black”,bg=”light
58 green”,command=lambda: self.apasa(’x’)).grid(row=2,column=3)
59 Button(master,text=”-”,width=5,height=3,fg=”black”,bg=”light
60 green”,command=lambda: self.apasa(’-’)).grid(row=3,column=3)
61 Button(master,text=”/”,width=5,height=3,fg=”black”,bg=”light
62 green”,command=lambda: self.apasa(’/’)).grid(row=1,column=3)
63 Button(master,text=”7”,width=5,height=3,fg=”black”,bg=”light
64 green”,command=lambda: self.apasa(’7’)).grid(row=1,column=0)
65 Button(master,text=”8”,width=5,height=3,fg=”black”,bg=”light
66 green”,command=lambda: self.apasa(8)).grid(row=1,column=1)
67 Button(master,text=”9”,width=5,height=3,fg=”black”,bg=”light
68 green”,command=lambda: self.apasa(9)).grid(row=1,column=2)
69 Button(master,text=”4”,width=5,height=3,fg=”black”,bg=”light
PYTHON:
70 green”,command=lambda: self.apasa(4)).grid(row=2,column=0)
71 Button(master,text=”5”,width=5,height=3,fg=”black”,bg=”light
72 green”,command=lambda: self.apasa(5)).grid(row=2,column=1)
73 Button(master,text=”6”,width=5,height=3,fg=”black”,bg=”light
74 green”,command=lambda: self.apasa(6)).grid(row=2,column=2)
75 Button(master,text=”1”,width=5,height=3,fg=”black”,bg=”light
76 green”,command=lambda: self.apasa(1)).grid(row=3,column=0)
77 Button(master,text=”2”,width=5,height=3,fg=”black”,bg=”light
78 green”,command=lambda: self.apasa(2)).grid(row=3,column=1)
79 Button(master,text=”3”,width=5,height=3,fg=”black”,bg=”light
80 green”,command=lambda: self.apasa(3)).grid(row=3,column=2)
81 Button(master,text=”0”,width=5,height=3,fg=”black”,bg=”light
82 green”,command=lambda: self.apasa(0)).grid(row=4,column=1)
83 Button(master,text=”.”,width=5,height=3,fg=”black”,bg=”light
84 green”,command=lambda: self.apasa(’.’)).grid(row=4,column=0)
85 Button(master,text=”%”,width=5,height=3,fg=”black”,bg=”light
86 green”,command=lambda: self.apasa(’%’)).grid(row=1,column=4)
87 Button(master,text=”sqrt”,width=5,height=3,fg=”black”,bg=”light
88 green”,command=lambda: self.radical()).grid(row=2,column=4)
Pentru apăsarea butoanelor şi scrierea ı̂n caseta text:
25
126 listenTo(btn0)
127 reactions+={
128 case ButtonClicked(b) =>
129 if(b.eq(btn0) && (numTxt.text.length < max cols)) {
130 tmp=numTxt.text
131 if(tmp ==”0” || tmp== ”Error” || opPressed) tmp= ””
132 numTxt.text= tmp.concat(”0”)
133 opPressed = false
134 }
135 }
136 //Asemănător se va face şi pentru butoanele 1,2,3,4,5,6,7,8,9.
226 listenTo(btnPeriod)
227 reactions += {
228 case ButtonClicked(b) =>
229 if (b.eq(btnPeriod) && (numTxt.text.length < max cols)) {
230 tmp = numTxt.text
231 if (!isDecimal && tmp != ”Error” &&!tmp.contains(”.”)) {
232 numTxt.text = tmp.concat(”.”)
233 isDecimal = true
SCALA: 234 }
235 opPressed = false
236 }
237
349 listenTo(btnPlus)
250 reactions += {
251 case ButtonClicked(b) =>
252 if (b.eq(btnPlus)) {
253 tmp = numTxt.text
254 if (tmp != ”Error”) {
255 curr value = java.lang.Double. parseDouble(tmp)
256 if (!isFirstOperation) {
257 if (!leftOperand.isNaN)
258 leftOperand = do oper(previous oper, leftOperand, curr value)
259 if (leftOperand.isNaN)
260 numTxt.text = ”Error”
261
262 else
263 numTxt.text = leftOperand.toString
264 }
26
265 else {
266 leftOperand = curr value
267 isFirstOperation = false
268 }
269 previous oper = ”+”
270 opPressed = true
271 isDecimal = false
272 }
273 }
274 }
275 //La fel vom proceda şi pentru celelalte butoane.
379 def CalcPanel(): GridBagPanel = {
380 val contents = new GridBagPanel() {
381 var c = new Constraints()
382 c.gridx = 0
383 c.gridy = 0
384 c.gridwidth =20
SCALA:
385 c.insets = new Insets(5, 5, 5, 5)
386 c.fill = GridBagPanel.Fill.Horizontal
387 add(numTxt, c)
388 c.gridwidth =1
389 c.fill = GridBagPanel.Fill.None
390
391 c.gridx = 0
392 c.gridy = 1
393 add(btn7, c)
404 c.gridx = 0
405 c.gridy = 4
406 c.gridwidth = 2
407 c.fill = GridBagPanel.Fill.Horizontal
408 add(btn0, c)
409 c.gridwidth = 1
410 c.fill = GridBagPanel.Fill.None
411 //Aşa se vor poziţiona toate butoanele.
13 MyDigitButon digitButon[]= new MyDigitButon[digitButonNumar. length];
14 MyOperatorButon operatorButon[]= new MyOperatorButon[operatorButon
Numar.length];
JAVA: 15 MySpecialButon specialButon[]=new MySpecialButon[specialButonNumar.
length];
41 tempX=2*( WIDTH+H SPACE);
42 tempY=2*( HEIGHT+V SPACE);
27
43 for(int i=0;i <specialButon.length; i++){
44 specialButon[i]=new MySpecialButon(3*tempX,3*tempY+1,
WIDTH,HEIGHT,special ButonNumar[i],this);
45 specialButon[i]. setForeground(Color.RED);
46 tempX=tempX+ WIDTH+H SPACE;
47 }
52 int digitX=TOPX+ WIDTH+H SPACE;
53 int digitY=TOPY+2*( HEIGHT+V SPACE);
54 tempX=digitX;
55 tempY=digitY;
56 for(int i=0;i<digitButon.length; i++){
57 digitButon[i]=new MyDigitButon(tempX,tempY,
WIDTH,HEIGHT,digit ButonNumar[i],this);
58 digitButon[i]. setForeground(Color.BLUE);
59 tempX += WIDTH+H SPACE;
60 if((i+1)%3 == 0){
61 tempX=digitX;
62 tempY += HEIGHT+V SPACE;
63 }
64 }
68 int opX=digitX+2*( WIDTH+H SPACE)+ H SPACE;
JAVA: 69 int opY= digitY;
70 tempX=opX;
71 tempY=opY;
72 for(int i=0;i<operatorButon. length;i++){
73 tempX += WIDTH+H SPACE;
74 operatorButon[i]= new MyOperatorButon(tempX,tempY,
WIDTH,HEIGHT,operator ButonNumar[i],this);
75 operatorButon[i].set Foreground(Color.RED);
76 if((i+1)%2 ==0){
77 tempX=opX;
78 tempY+=HEIGHT+ V SPACE;
79 }
80 }
107 class MyDigitButon extends Button implements ActionListener{
108 Calculator calculator;
110 MyDigitButon(int x, int y, int width, int height, String vf, Calculator cl){
111 super(vf);
112 setBounds(x,y, width,height);
113 this.calculator=cl;
114 this.calculator.add (this);
115 addActionListener (this);
116 }
28
118 static boolean esteInString(String s, char ch){
119 for(int i=0;i < s.length();i++)
120 if(s.charAt(i) == ch)
121 return true;
122 return false;
123 }
125 public void actionPerformed(ActionEvent e){
126 String tempNumar=((MyDigitButon)e. getSource()).getLabel();
128 if(tempNumar.equals (”.”)){
129 if(calculator.set Sterge){
130 calculator.display Label.setText(”0.”);
131 calculator.setSterge= false;
132 }
133 else if(!esteIn String(calculator.display Label.getText(),’.’)){
134 calculator.display Label.setText(calculator. displayLabel.getText()
+”.”);
135 }
136 return;
137 }
JAVA:
139 int index = 0;
141 try{
142 index=Integer.parse Int(tempNumar);
143 }
144 catch(Number FormatException ex){
145 return;
146 }
148 if(index == 0 && calculator.displayLabel.get Text().equals(”0”))
149 return;
151 if(calculator.setSterge){
152 calculator.display Label.setText(””+index);
153 calculator.setSterge = false;
154 }
155 else
156 calculator.display Label.setText( calculator.displayLabel.get Text()
+index);
157 }
159 }
160 //Pe aceeaşi idee se fac toate butoanele.
29
30 double daNumar(){
32 double nr;
33 try{
35 nr = Convert.ToDouble( this.rezultat.Text);
36 }
37 catch (Exception){
39 nr = 0;
40 }
41 return nr;
42 }
46 void apas buton numar( Object sender, System.EventArgs e){
48 Button b = (Button)sender;
49 if (rezultat.Text.Length < 20){
51 if (anuleaza || rezultat.Text.Equals(”0”))
52 rezultat.Text = b.Text;
53 else
54 rezultat.Text = rezultat.Text + b.Text;
55 }
56 anuleaza = false;
57 buton operatie egal. Focus();
58 }
C]: 60 void apas buton operatie( Object sender, System.EventArgs e){
62 Button b = (Button)sender;
63 if (b.Text.Equals(”C”)){
65 rezultat.Text = ”0”;
66 numar = 0;
67 operatie = -1;
68 }
70 else if (b.Text.Equals(”+/-”){
72 if (daNumar() != 0){
74 if (!rezultat.Text.Substring(0, 1).Equals(”-”))
75 rezultat.Text = ”-” + rezultat.Text;
76 else
77 rezultat.Text = rezultat.Text.Substring(1,
rezultat.Text.Length - 1);
78 }
79 }
80 else if (b.Text.Equals(”.”)){
82 if (rezultat.Text.IndexOf(”.”) < 0)
83 rezultat.Text = rezultat.Text + ”.”;
84 }
85 else if (b.Text.Equals(”+”)){
87 numar = daNumar();
30
88 operatie = 0;
89 anuleaza = true;}
91 else if (b.Text.Equals(”-”)){
93 numar = daNumar();
94 operatie = 1;
95 anuleaza = true;
96 }
97 else if (b.Text.Equals(”*”)){
99 numar = daNumar();
100 operatie = 2;
101 anuleaza = true;
102 }
103 else if (b.Text.Equals(”/”)){
105 numar = daNumar();
106 operatie = 3;
107 anuleaza = true;
108 }
109 else if (b.Text.Equals(”sqrt”)){
111 numar = Math.Sqrt(daNumar());
112 rezultat.Text = Convert.ToString(numar);
113 anuleaza = true;
114 }
C]:
115 else if (b.Text.Equals(”%”)){
117 rezultat.Text = Convert.ToString(daNumar() / 100);
118 anuleaza = true;
119 }
121 else if (b.Text.Equals(”=”)){
123 switch (operatie){
125 case 0:
126 numar = numar + daNumar();
127 rezultat.Text = Convert.ToString(numar);
128 break;
129 case 1:
130 numar = numar - daNumar();
131 rezultat.Text = Convert.ToString(numar);
132 break;
133 case 2:
134 numar = numar * daNumar();
135 rezultat.Text = Convert.ToString(numar);
136 break;
137 case 3:
138 try{
140 numar = numar / daNumar();
141 rezultat.Text = Convert.ToString(numar);
31
142 }
143 catch (Exception){
145 rezultat.Text = ”Cannot divide by zero.”;
146 }
147 break;
C]:
148 }
149 anuleaza = true;
150 }
151 buton operatie egal. Focus();
152 }
6 def clc(self):
7 self.expression = self.e.get()
8 self.newtext=self.expression.replace(’/’,’/’)
9 self.newtext=self.newtext.replace(’x’,’*’)
11 def apasa(self, arg):
12 self.e.insert(END,arg)
14 def egal(self):
15 self.clc()
16 try:
17 self.value= eval(self.newtext)
18 except SyntaxError or NameError:
19 self.e.delete(0,END)
20 self.e.insert(0,’Invalid Input!’)
21 else:
22 self.e.delete(0,END)
23 self.e.insert(0,self.value)
PYTHON:
24 def sterge(self):
25 self.e.delete(0,END)
27 def radical(self):
28 self.clc()
29 try:
30 self.value= eval(self.newtext)
31 except SyntaxError or NameError:
32 self.e.delete(0,END)
33 self.e.insert(0,’Invalid Input!’)
34 else:
35 self.sqrtval=math.sqrt(self.value)
36 self.e.delete(0,END)
37 self.e.insert(0,self.sqrtval)
71 root = Tk()
73 obj=calc(root)
75 root.mainloop()
32
Interfaţa
Bibliografie
[1] Steps in Scala- Christos K.K.Loverdos and Apostolos Syropoulos 2010, ed
[4] https://www.toptal.com/scala/why-should-i-learn-scala
[5] https://www.geeksforgeeks.org/scala-programming-language/
[6] https://www.javatpoint.com/scala-constructor
33