Proiect Etapa 2 - J. POO Morgan Chase & Co.
-
-
Data publicării: 17 decembrie, ora 10:34
Deadline HARD: 21 ianuarie, ora 10:00 dimineața
Ultimele modificări:
Publicare schelet - 20 Dec. 2024
Adăugat clarificări comandă withdrawSavings - 21 Dec.2024
Adăugat teste - 21 Dec.2024
Actualizat teste și enunț - 02 Ian. 2025
Actualizat teste - 05 Ian. 2025
Actualizat enunț și ref-uri pentru t14 si t18-20 pentru cazul unui asociat cu 2 roluri - 11 Ian. 2025
Actualizat DEADLINE HARD - 11 Ian. 2025
Publicare soluție oficială pentru etapa 1 în secțiunea resurse - 14 Ian. 2025
Pentru orice neclaritate vă rugăm să folosiți forumul, urmând ca doar responsabilii temei să vă răspundă la întrebări. Se preferă folosirea forumului tocmai pentru a evita repetarea întrebărilor.
Este obligatoriu să folosiți cel puțin 4 design pattern-uri. Trebuie sa precizati in README ce design pattern ati folosit, si motivatia & locatia unde a fost folosita
Depunctari lipsa design pattern-uri: Pentru fiecare design pattern lipsa (din cele 4), veti avea o depunctare de -2.5p din 10p (maxim cat se poate obtine pe tema fara bonusuri), astfel pentru:
0 design pattern-uri - -10p / 10p
1 design pattern-uri - -7.5p / 10p
2 design pattern-uri - -5p / 10p
3 design pattern-uri - -2.5p / 10p
Introducere
Ați supraviețuit primelor etape, dar acum vine partea cu adevărat interesantă: să adăugați funcționalitățile care vor transforma acest sistem de e-banking dintr-un simplu “salut” într-un “wow!” complet funcțional.
Așadar, echipati-va în tricoul de programator „Coffee + Code = Success” (și o cantitate semnificativă de cofeină), si puneti-va pe treabă ca sa securizati pozitia aia de CEO ! 😎
Obiectiv
Descriere
Scopul acestui proiect este să creăm o aplicație revoluționară, asemănătoare cu Revolut, dar cu un twist! Vrem să aducem o gamă largă de funcționalități care să îmbunătățească viața financiară a utilizatorilor. De la gestionarea rapidă a conturilor personale și tranzacțiilor, până la noi opțiuni super utile precum conturile pentru afaceri, care vor face viața antreprenorilor mult mai ușoară.
Mai mult, vom adăuga cashback pentru diverse plăți, astfel încât fiecare achiziție să devină o mică recompensă. Și dacă vrei să fii tratat ca un VIP, vei putea opta pentru un plan premium, care îți va oferi beneficii exclusive, cum ar fi tranzacții mai rapide, reduceri speciale și funcționalități avansate.
Așadar, nu e doar o aplicație bancară, ci o adevărată platformă care îți pune la dispoziție toate uneltele necesare pentru a-ți gestiona banii inteligent și cu stil!
Recap de la etapa anterioara
Toate comenzile de la etapa I rămân valabile, doar că vor suferi mici modificări.
Comenzile posibile de la etapa anterioară sunt :
Înainte de a incepe implementarea pentru etapa 2, asigurați-vă că aveți implementate corect comenzile de la etapa 1.
Utilizatori
Față de etapa anterioară, vom adaugă niște date suplimentare pentru utilizatori - data nașterii, ocupația și tipul de plan de administrare al contului.
Asemănător ca la etapa I, la inceputul fiecarui test va fi o listă cu utilizatori, iar noul format de date ale utilizatorilor vor fi :
firstName (String): prenumele utilizatorului.
lastName (String): numele de familie al utilizatorului.
email (String) : email-ul utilizatorului.
birthDate (String) : data de naștere a utilizatorului.
occupation (String) : ocupația utilizatorului.
Click pentru input utilizatori
Click pentru input utilizatori
"users": [
{
"firstName": "Laurence",
"lastName": "Bodin-Huet",
"email": "Laurence_Bodin-Huet@hotmail.fr",
"birthDate": "2001-08-08",
"occupation": "pyrotechnician",
},
{
"firstName": "Ruxandra",
"lastName": "Aane",
"email": "Ruxandra_Aane@hotmail.ro",
"birthDate": "1981-11-18",
"occupation": "firefighter",
}
]
Comerciantii
Similar cu utilizatorii, comercianții vor fi primiți la începutul fiecărui test după lista cu utilizatori.
Fiecare comerciant va avea următoarele informații:
commerciant (String) - numele comerciantului
id (int) - id-ul comerciantului
account (String) - IBAN-ul contului corespunzator comerciantului
type (String) - tipul de comerciant (ex: Tech)
cashbackStrategy (String) - metoda de cashback a comerciantului
Întrucat aceștia vor avea un IBAN, se vor putea face transferuri bancare către comercianți, nu doar plăți online cu cardul.
Acest tip de operație DOAR va retrage bani din contul utilizatorului, comerciantul nu trebuie să aibă cont creat.
Click pentru input comerciant
Click pentru input comerciant
"commerciants": [
{
"commerciant": "Samsung",
"id": 3,
"account": "RO69POOB6209498372540635",
"type": "Tech",
"cashbackStrategy": "nrOfTransactions"
},
{
"commerciant": "McDonalds",
"id": 8,
"account": "RO58POOB7344468893732422",
"type": "Food",
"cashbackStrategy": "nrOfTransactions"
}
]
Commerciant cashback
Fiecare comerciant vrea să atragă cât mai mulți clienți, așa că introduce strategia de cashback. Cu cât cheltui mai mult, cu atât câștigi mai mult înapoi 🤑.
Cashback-ul este calculat SEPARAT PER FIECARE CONT al utilizatorului - fiecare cont va avea o lista cu discounturile primite de la comerciantii de tip nrOfTransactions (Food, Clothes, Tech) si o suma totala de cheltuieli pentru comerciantii de tip spendingThreshold.
Un comerciant poate să aleagă unul din următoarele planuri de cashback:
nrOfTransactions
Odată ce un cashback a fost primit, nu contează de la care comerciant, nu se va mai primi a2a oară.
Cashback-ul pentru categoriile de Food, Clothes si Tech poate fi folosit pentru ORICE tip de comerciant - spendingThreshold sau nrOfTransactions - atata timp cat face parte din una din categoriile mentionate.
Exemplu suplimentar pentru un utilizator ce are 2 conturi - cont1 si cont2
card1, cont1 - discounts = {Food}
card2, cont2 - discounts = {Food, Clothes}
se face plata la KFC cu card1 → se face discount
se face plata la KFC cu card1 → NU se face discount pt ca nu mai am niciun fel de discount
se face plata la Zara cu card2 → se face discount
se face plata la KFC cu card2 → se face discount
se face plata la KFC cu card2 → NU se face discount pt ca nu mai am niciun fel de discount
Se contorizează numărul de tranzacții de la fiecare comerciant de acest tip în ordinea în care se primesc comenzile de plată cu cardul sau transfer bancar. În momentul în care se atinge unul dintre pragurile pentru numărul de tranzacții, atunci se va primi cashbackul aferent.
spendingThreshold (currency-ul va fi RON)
depinde de planul pe care îl are utilizatorul - standard, student, silver sau gold
pentru 100RON cheltuiți (suma totală a tranzacțiilor până acum)
0.1% cashback pentru standard și student
0.3% cashback pentru silver
0.5% cashback pentru gold
pentru 300RON cheltuiți
0.2% cashback pentru standard și student
0.4% cashback pentru silver
0.55% cashback pentru gold
pentru 500RON cheltuiți
0.25% cashback pentru standard și student
0.5% cashback pentru silver
0.7% cashback pentru gold
Cashback-ul se va efectua pentru tranzacția curentă la orice comerciant ce are tipul de cashback spendingThreshold.
Se va calcula totalul cheltuit per cont de la toți comercianții de acest tip.
Cashback-ul se va primi la tranzacția curentă pentru care s-a îndeplinit unul din pragurile precizate anterior.
Exemplu suplimentar pentru un utilizator ce are 2 conturi - acc1 si acc2
card1, acc1 → total1
card2, acc2 → total2
se face plata cu card1 → total1 + amount
se face plata cu card2 → total2 + amount
Se aplica cashback de fiecare dată când se îndeplinește una din condiții.
Exemple
Pentru un utilizator care are a efectuat 5 tranzacții la KFC, care este un comerciant ce are nrOfTransactions cashback, va primi înapoi 5% din valoarea următoarei plăți la oricare dintre comercianții de tip Clothes si 2% pentru următoarea tranzactie la oricare dintre comercianții de tip Food. Mai precis, in momentul in care face a2a tranzactie, el primeste discountul pentru Food, care se va aplica la a3a tranzactie intrucat KFC este un comerciant de tip Food, si la a5a tranzactie va primi discountul pentru Clothes pe care il va putea aplica la urmatoarea tranzactie la ORICE comerciant din categoria Clothes.
Pentru un utilizator ce deține plan de tip gold și care are a cheltuit 500RON la Zara până la momentul curent, care are spendingThreshold cashback, va primi înapoi 0.7% din tranzacția curentă.
Tipurile de tranzacții pentru care se aplica cashback sunt plățile online și transferurile bancare către comercianți.
Toate tranzacțiile în orice currency vor fi luate în considerare pentru cashback și suma totală va fi convertită in RON.
Curs valutar
Acesta se va regăsi în teste după lista de comercianți și va fi o listă goală dacă nu este folosit în testul curent.
Structura acestuia este:
from (String) - moneda care se dorește a fi convertită
to (String) - moneda în care se dorește conversia
rate (double) - rata de conversie
Click pentru input curs valutar
Click pentru input curs valutar
"exchangeRates": [
{
"from": "USD",
"to": "EUR",
"rate": 0.9
},
{
"from": "EUR",
"to": "RON",
"rate": 5
}
]
Service Plan
Acum vrem să ne mărim și noi profiturile ca să dezvoltăm afacerea. 😁
Lansăm planuri personalizate, create să se muleze perfect pe nevoile fiecărui utilizator. Cu un mic fee, vor putea debloca beneficii extra și funcționalități exclusive, iar upgrade-ul la un plan superior le va transforma complet experiența financiară!
Tipurile de plan
standard
student
silver
gold
Un utilizator va avea opțiunea de a trece la un plan mai bun prin efectuarea unei tranzacții de acest tip. În funcție de numărul de nivele pentru upgrade, se vor percepe următoarele fee-uri:
standard/ student to silver: 100RON fee
silver to gold: 250RON fee
standard/ student to gold: 350RON fee
Nu există posibilitatea de a face downgrade la plan, de exemplu de a trece de la gold la silver.
Utilizatorul nu trebuie să plăteasca neapărat fee-ul pentru upgrade de la silver la gold întrucât se va face upgrade automat dacă userul face 5 plăți de cel putin 300RON fiecare.
La crearea contului, tipul de plan va fi by default standard SAU student daca userul are ocupatie de student.
Odata ce utilizatorul isi face upgrade la plan, TOATE conturile asociate lui vor beneficia de noul plan.
Plata pentru fee-ul corespunzător upgrade-ului se face in RON.
Formatul comenzii pentru această acțiune este:
command (String) - “upgradePlan” - numele comenzii
newPlanType (String) - tipul de plan la care se face upgrade
account (String) - IBAN-ul contului corespunzător utlizatorului
timestamp (int) - momentul de timp în care comanda a fost solicitată
Click pentru input pentru upgrade plan
Click pentru input pentru upgrade plan
{
"command": "upgradePlan",
"newPlanType”: "silver",
"account": "RO69POOB6209498372540635",
"timestamp": 3
}
Mesaje posibile pentru această comandă:
Account updates
Vom introduce update-uri pentru contul de savings și un nou tip de cont - cel de business.
Savings Account
Uneori se întâmplă situații neprevăzute și să stăm mai prost cu banii așa că suntem nevoiți să retragem din contul de economii ca să ne rezolvăm problemele 💸💸.
Un utilizator ce are un cont de tip savings și cel puțin unul de tipul clasic va putea adăuga fonduri din cel de savings în unul din cele clasice, în funcție de currency-ul specificat în comandă.
Și cum anumiți părinți deschid conturi pentru copii ca să le ofere un viitor mai bun și să nu cheltuiască banii strânși, vom avea un minim de vârstă pentru a putea retrage bani - 21 de ani.
Structura comenzii este:
command (String) - ”withdrawSavings” - numele comenzii
account (String) - IBAN-ul contului corespunzător contului de savings al utilizatorului
amount (double) - suma care va fi retrasă din cont
currency (String) - moneda care va fi folosită pentru suma retrasă din cont
timestamp (int) - momentul de timp la care are loc această operație
Contul clasic destinație va fi primul cont creat în currency-ul dat ca parametru in comandă.
De exemplu, dacă currency-ul primit este EUR și suma de încărcat este 57, atunci se va calcula exchange-ul din contul de savings ca în cel clasic de euro să ajungă 57 de euro (incluzand și eventualul comision).
Click pentru input retragere fonduri din contul de economii
Click pentru input retragere fonduri din contul de economii
{
"command": "withdrawSavings",
"account": "RO58POOB7344468893732422",
"amount": 475.95,
"currency": "RON",
"timestamp": 2
}
Mesaje posibile pentru această comandă:
“Savings withdrawal”
“You don't have the minimum age required.”
“You do not have a classic account.”
“Account is not of type savings.”
“Insufficient funds”
“Account not found”
Business Account
Vrem să ne extindem clientela și să oferim un plan de banking pentru antreprenori. Aceștia vor avea avantajul de a împărți un singur cont cu toți angajații și să gestioneze ușor tranzacțiile pentru afacerea lor 📝.
Când se primește comanda de creare a unui cont business, userul primit va fi ownerul contului și apoi se vor putea adăuga utilizatori cu drept de acces la cont. De asemenea, ownerul poate seta balanța minimă (recap de la etapa 1 - suma sub care nu trebuie să scadă valoare contului altfel cardurile asociate vor fi blocate) și limite pentru tranzacțiile făcute de ceilalti utilizatori.
Vor fi 3 tipuri de utilizatori cu acces la cont:
owner
manager
are dreptul să facă orice fel de tranzacție: adăugare fonduri, făcut plăți, transferuri și să creeze sau să șteargă orice card asociat contului
poate sa faca plati cu orice fel de card
employee
poate să efectueze plăți - plăți cu cardul sau transfer bancar - în limita la 500RON inițial
poate să depună bani în contul de business în limita la 500RON inițial
poate să creeze carduri și să le șteargă doar pe cele create de el
poate sa faca plati cu orice fel de card
Structurile comenzilor
creare cont business
command (String) - ”addAccount” - numele comenzii
email (String) - email-ul utilizatorului căruia i se va crea un cont nou
currency (String) - moneda asociată contului
accountType (String) - tipul de cont care va fi creat
timestamp (int) - momentul solicitării comenzii
Numai ownerul poate schimba limita pentru plăți și depus bani, să adauge noi asociați, să seteze balanța minimă și să șteargă contul.
Un asociat
NU poate avea 2 roluri, poate fi doar employee sau manager. Se va lua rolul cand a fost prima data adaugat.
Acest lucru este valabil si pentru owner-ul contului de business - nu poate avea rol de manager sau employee.
Nu există plată distribuită pentru cont de business - se pot face doar plăți cu cardul sau transfer bancar.
Limitele initiale de pentru spending si deposit sunt de 500RON fiecare.
Click pentru input business account
Click pentru input business account
{
"command": "addAccount",
"email": "Amber_Morris@yahoo.us",
"currency": "USD",
"accountType": "business",
"timestamp": 40
},
{
"command": "addNewBusinessAssociate",
"account": "RO98POOB8412955460158769",
"role": "employee",
"email": "Tudor_Nemes@yahoo.ro",
"timestamp": 42
},
{
"command": "changeSpendingLimit",
"email": "Amber_Morris@yahoo.us",
"account": "RO98POOB8412955460158769",
"amount": 199,
"timestamp": 83
},
{
"command": "changeDepositLimit",
"email": "Julien_Techer@hotmail.fr",
"account": "RO69POOB9846198978826791",
"amount": 384,
"timestamp": 52
}
Mesaje posibile pentru această comandă:
Transaction updates
Vom avea câteva tranzacții noi și mici modificări la cele de bază implementate la etapa anterioară.
Comenzile de la etapa 1
Întrucât introducem un nou tip de cont - cel de business, va fi necesar adăugarea câmpului de email la comenzi:
Luati in considerare si toate corner case-urile de la etapa 1 .
De exemplu, un card nu poate fi sters daca inca exista bani in contul asociat acestuia sau un one-time card va fi sters si regenerat dupa orice utilizare - asta include si operatiile noi de la etapa 2 precum cashWithdrawal.
Mesajul de eroare
“User not found” va fi aplicat pentru urmatoarele comenzi noi de la aceasta etapa (pe langa cele existente de la etapa 1):
Pentru un cont de tip business, se presupune ca owner-ul seteaza functionalitatile asociate comenzilor de addNewBusinessAssociate, setMinBalance si upgradePlan.
Click pentru input adăugare fonduri
Click pentru input adăugare fonduri
{
"command": "addFunds",
"email": "Laurent_Mallet@yahoo.fr",
"account": "RO96POOB6738272785416988",
"amount": 589,
"timestamp": 17
}
Cash withdrawal
Evident că mai există situații când avem nevoie și de numerar, din nefericire nu există peste tot POS-uri încă 😢.
Un utillizator va putea retrage bani de la un bancomat din diverse locatii, comanda având următoarea structură:
command (String) - “cashWithdrawal” - numele comenzii
cardNumber (String) - numărul cardului care va fi folosit pentru plată
amount (double) - suma totală de retras in numerar
email (String) - email-ul utilizatorului
location (String) - locatia ATM-ului de unde se efectuează retragerea
timestamp (int) - momentul de timp în care comanda a fost solicitată
Plata se face DOAR in RON
Se percepe comision in functie de planul detinut de utilizator.
Click pentru input cash withdrawal
Click pentru input cash withdrawal
{
"command": "cashWithdrawal",
"cardNumber": "5873444688937324",
"amount": 45.5,
"email": "Joshua_Wood@gmail.us"
"location": "Ourense",
"timestamp": 5
}
Mesaje posibile pentru această comandă:
“Cash withdrawal of ${amount}.”
“Insufficient funds”
“Card has already been used”
“The card is frozen”
“Card not found”
“User not found”
“Cannot perform payment due to a minimum balance being set”
Custom split payment
Nu la toate date-urile trebuie mereu să fie mereu 50-50 împărțirea, așadar este normal ca fiecare să plătească cât consumă 🤵.
Pentru un split payment de tip custom, se va primi lista de utilizatori care participă la tranzacție și lista cu suma de plată corespunzătoare pentru fiecare utilizator.
accounts: [account1, account2,…]
amountForUsers: [sum_for_account1, sum_for_account2,…]
Posesorul contului inclus în split payment acceptă sau refuză plata (OBLIGATORIU). În cazul în care acesta acceptă plata, se așteaptă ca toți ceilalti implicati sa accepte, ulterior, odată ce toți au acceptat, să se porneasca mecanismul de plată care verifică dacă fiecare cont conține minim suma de plată atașată lui.
Un mesaj de eroare se va genera și atunci când un utilizator refuză plata, anulând întreg split payment-ul pentru toți ceilalți.
Structurile comenzilor
accept split payment
command (String) - “acceptSplitPayment” - numele comenzii
email (String) - email-ul utilizatorului
timestamp (int) - momentul de timp la care a avut loc comanda
reject split payment
command (String) - “rejectSplitPayment” - numele comenzii
email (String) - email-ul utilizatorului
timestamp (int) - momentul de timp la care a avut loc comanda
Un utilizator poate primi mai multe cereri de split payment, ce pot fi de tip “equal” sau “custom”.
Acestea vor fi procesate in ordinea primirii comenzilor și eliminate ulterior după ce au fost acceptate sau refuzate.
Comanda de split payment de la etapa anterioară, cea de tipul “equal”, acum funcționează la fel ca cea de tip “custom” și fiecare utilizator implicat în tranzacție va refuza sau accepta plata.
Click pentru input custom split payment
Click pentru input custom split payment
{
"command": "splitPayment",
"splitPaymentType": "custom",
"accounts": [
"RO69POOB6209498372540635",
"RO58POOB7344468893732422"
],
"amount": 25,
"amountForUsers": [
10, 15
],
"currency": "EUR",
"timestamp": 19
},
{
"command": "acceptSplitPayment",
"email": "Lucas_Garnier@outlook.fr",
"timestamp": 20
},
{
"command": "rejectSplitPayment",
"email": "Margaux_Nicolas@gmail.fr",
"timestamp": 21
}
Mesaje posibile pentru aceasta comandă:
“Split payment of ${amount} ${currency}” → apare la fiecare comandă de plată distribuită
“Account ${accounts[current_index]} has insufficient funds for a split payment.” → se ia primul cont găsit că are fonduri insuficiente pentru plata distribuită
“One user rejected the payment.” → cand unul din utilizatori a dat reject la plata
“User not found”
Report Updates
Un CEO mereu o să fie interesat de ce se întâmplă cu afacerea sa, în special cu banii săi, așa că vom oferi rapoarte special pentru ei 📊.
Aceștia vor putea alege între un raport legat de tranzacții sau de comercianți - “transaction” sau “commerciant”.
Modalitățile de plată luate în calcul pentru acest tip de raport sunt: plata cu cardul și transferul bancar. Ordinea utilizatorilor este cea reținută de contul de business, întâi afișându-se informațiile de utilizare a contului de către manageri, apoi pentru angajați.
Tipurile de raport
transaction
commerciant
pentru fiecare comerciant la care s-au efectuat plăți sau transferuri, va fi afișată suma totală cheltuită la acesta și lista de manageri și cea de angajați care au făcut plățile la acel comerciant
comercianții, managerii și angajații vor fi sortați crescător după nume
Comanda pentru generarea acestui tip de raport are următorul format:
command (String) - “businessReport” - numele comenzii
type (String) - tipul de raport de business
startTimestamp (int) - momentul de timp de start în care comanda a fost solicitată
endTimestamp (int) - momentul de timp de încheiere în care comanda a fost solicitată
account (String) - IBAN-ul contului corespunzator utlizatorului
timestamp (int) - momentul de timp în care comanda a fost solicitată
Click pentru input raport cont business
Click pentru input raport cont business
{
"command": "businessReport",
"type": "transaction",
"startTimestamp": 7,
"endTimestamp": 29,
"account": "RO69POOB1234567898765432",
"timestamp": 77
},
{
"command": "businessReport",
"type": "commerciant",
"startTimestamp": 7,
"endTimestamp": 29,
"account": "RO69POOB1234567898765432",
"timestamp": 77
}
Output pentru raport de tip transaction
Click pentru raport de tip transaction
Click pentru raport de tip transaction
{
"command" : "businessReport",
"output" : {
"IBAN" : "RO69POOB1234567898765432",
"balance" : 891.5,
"currency" : "RON",
“spending limit “: 10000000
“deposit limit”: 10000000
"managers" : [ {
"name" : “Chiriac Marius”,
"spent" : 500
“deposited” : 1200
}, {
"name" : “Pitic David”,
"spent" : 800
“deposited” : 900
} ]
"employees" : [ {
"name" : “Bunu Maria”,
"spent" : 50
“deposited” : 120
}, {
"name" : “Guinevere Benedict”,
"spent" : 40
“deposited” : 61.5
} ]
“total spent”: 1390
“total deposited”: 2281.5
},
"timestamp" : 77
}
Output pentru raport de tip commerciant
Click pentru raport de tip commerciant
Click pentru raport de tip commerciant
{
"command" : "businessReport",
"output" : {
"IBAN" : "RO69POOB1234567898765432",
"balance" : 891.5,
"currency" : "RON",
“spending limit “: 10000000
“deposit limit”: 10000000
"commerciants" : [ {
"commerciant" : “Lenovo”,
"totalReceived" : 2500
“managers”: [
“Popescu Marius”
],
“employers”:[
“Ionescu Ion”,
“Maiorescu Titu”
]
} ]
},
"timestamp" : 77
}
Mesaje posibile pentru această comandă:
Scheletul de cod
În rezolvarea temei va fi nevoie de folosirea unor obiecte pentru stocarea și maparea datelor primite în format JSON. Scheletul temei vă oferă mai multe clase utile pentru citirea și rularea temei. Acestea se regăsesc în cadrul scheletului astfel:
Clasele de input din cadrul pachetului fileio : Acestea se vor folosi pentru parsarea datelor de input. Astfel preluați toate informațiile necesare pentru a crea propriile clase pentru rezolvarea temei.
Clasa Main care este punctul de intrare pentru logica de rezolvare a temei.
Pentru a întelege mai bine cum funcționează citirea/scrie în fișierele JSON vă recomandăm să citiți Json & Jackson sau să folosiți biblioteca GSON.
Acest proiect folosește
Maven ca
dependency manager și
build system, ceea ce înseamnă că aveți următoarele fișiere în schelet:
pom.xml - fișier în care se adaugă dependințe și se detaliează procesul de build al proiectului.
target - folder care se generează când compilați proiectul deci include fișiere java compilate și jar-urile dependințelor.
.idea - folder care conține instrucțiuni pentur IntelliJ astfel încât acesta să găsească entry point-ul aplicației și să încarce anumite configurații.
Dacă aveți probleme cu proiectul vostru vă recomandăm următoarele soluții:
Să închideți proiectul din IntelliJ, să ștergeți din file explorer folderele .idea și target și să deschideți din nou folderul proiectului cu IntelliJ (File → open → selectați folderul în care se află pom.xml). Acest pas vă regenerează configurația IntelliJ-ului.
Să apăsați pe iconița “M” din dreapta în IntelliJ, după care să apăsați pe item-ul din listă, apoi pe lifecycle și apoi dublu click pe install. Acest pas vă reinstalează dependințele proiectului.
Să apăsați pe File → Invalidate cache și să bifați toate opțiunile. Proiectul o să se reîncarce ștergând toate configurațiile și fișierele cached.
Implementarea voastră va începe din funcția Main.action, unde veți adăuga în ArrayNode output pe parcursul execuției toate output-urile comezilor date.
Aveți în fișierul “pom.xml” toate dependințele necesare pentru rularea temei, mai exact bibliotecile Jackson, Lombok și GSON.
Output-ul nu trebuie formatat ca în ref-uri, fiindcă se verifică conținutul obiectelor și array-urilor JSON, nu textul efectiv. Cu toate acestea, dacă folosiți Jackson, vă recomandăm să utilizați
PrettyPrinter Documentație PrettyPrinter. Totodată, pentru a înțelege cum se poate realiza
scrierea în fișierele JSON de output, vă sugerăm să consultați
JSON Array.
Execuția temei
Se încarcă datele citite din fișierul de test, în format JSON, în obiecte.
Se primesc secvențial acțiuni și se execută pe măsură ce sunt primite, rezultatul lor având efect asupra Repository-ului.
După executarea unei acțiuni, se afișează rezultatul ei în fișierul JSON de ieșire.
La terminarea tuturor acțiunilor se termină și execuția programului.
După ce clonați repo-ul de pe GitHub, vă rugăm să vă faceți un repository propriu privat în care să vă puneți doar conținutul scheletului de pe repo-ul echipei de POO. Nu lucrați direct în folderul clonat de voi pe local, deoarece nu veți putea să dați push la commit-uri și este posibil să pierdeți punctajul pe commit-uri.
Vă rugăm să vă generați un .gitignore cu template-ul Maven dacă nu folosiți .gitignore-ul inclus în temă. Acesta vă ajută să definiți fișiere care să nu fie luate în considerare la diff check când rulați git status/git commit sau alte comenzi de git.
Pentru ca checker-ul să funcționeze trebuie să deschideți tema din Intellij la calea unde se află fișierul pom.xml.
Recomandări
Tema a fost concepută pentru a vă testa cunoștințele dobândite în urma parcurgerii laboratoarelor 1-9, aceasta putând fi rezolvată doar cu noțiunile invățate din acele laboratoare.
Tema fiind o specificație destul de stufoasă recomandăm citirea de cel putin două ori a enunțului inainte de inceperea implementării.
Pentru depanarea diferențelor dintre output-ul vostru si fișierele ref, vă recomandăm
acest site.
Verificați periodic această pagină, deoarece scheletul/cerința pot suferi modificări în urma unor erori din partea noastră.
Evaluare
Punctajul constă din:
80p implementare - trecerea testelor
10p coding style (vezi checkstyle)
5p README clar, concis, explicații axate pe design (flow, interacțiuni)
5p folosire git pentru versionarea temei
Pe pagina
Indicații pentru teme găsiți indicații despre scrierea readme-ului și
baremul folosit la corectarea temei. Vă incurajăm să treceți prin el cel puțin odată.
Pentru a primi punctajul pentru Git, după ce ați terminat tema și ați făcut toate commit-urile, executați comanda git log > git_log.txt
in rădăcina proiectului și adăugați fisierul in arhiva trimisă.
Pentru folosirea tool-ului
Git vă punem la dispoziție un tutorial actualizat și amplu despre el la acest
link și aveți de asemenea și un tutorial despre comenzile pe care puteți să le dați din IntelliJ la acest
link.
Folosirea git pentru versionare va fi verificata din folderul .git pe care trebuie să îl includeți în arhiva temei. Punctajul se va acorda dacă ați făcut minim 3 commit-uri relevante și cu mesaj sugestiv. NU este permis să aveți repository-urile de git publice până la deadline-ul hard.
Bonusuri:
La evaluare, putem oferi bonusuri pentru design foarte bun, cod bine documentat dar și pentru diverse elemente suplimentare alese de voi.
Temele vor fi testate împotriva plagiatului. Orice tentativă de copiere va duce la anularea punctajului de pe parcursul semestrului şi repetarea materiei atât pentru sursă(e) cât şi pentru destinație(ii), fără excepție.
Aveți grijă să puneți pe Vmchecker Next doar folderul src și fișierele git_log.txt și README.md. De asemenea, să ștergeți din arhivă folder-ul resources.
Checkstyle
Unul din obiectivele temei este învățarea respectării code-style-ului limbajului pe care îl folosiți. Aceste convenții (de exemplu cum numiți fișierele, clasele, variabilele, cum indentați) sunt verificate pentru temă de către tool-ul checkstyle.
Pe pagina de Recomandări cod găsiți câteva exemple de coding style.
Dacă numărul de erori depistate de checkstyle depășește 30, atunci punctele pentru coding-style nu vor fi acordate. Dacă punctajul este negativ, acesta se trunchiază la 0.
Exemple:
punctaj_total = 100
și nr_erori = 200
⇒ nota_finala = 90
punctaj_total = 100
și nr_erori = 29
⇒ nota_finala = 100
punctaj_total = 80
și nr_erori = 30
⇒ nota_finala = 80
punctaj_total = 80
și nr_erori = 31
⇒ nota_finala = 70
Upload temă
Arhiva o veţi urca pe VMChecker Next, unde sunt si informații despre structura ei.
FAQ
Q: Pot folosi biblioteca “X”?
A: Dacă doriți să folosiți o anumită bibliotecă vă recomandăm să întrebați pe forum, ca apoi să o validăm și să o includem și pe Vmchecker Next. Nu veți uploada pom.xml în arhivă deci nu este suficient doar să modificați acel fișier.
Q: Am descoperit edge case-ul “Y”, trebuie să îl tratez?
A: Nu. Toate datele necesare pentru soluționarea temei vă sunt date in cerință. Dacă totuși am omis ceva ne puteți contacta pe forum.
Q: Pot folosi clase de tip “Enum” pentru constante?
A: Da.
Q: Ce JDK recomandați?
A: 21
Q: Pot să fac în orice ordine testele?
A: Testele sunt incrementale, dar vă recomandăm să le implementați în ordinea dată de noi.
Resurse și linkuri utile