Chirurgia cranio-cerebrală minim invazivă
Tehnicile minim invazive impun utilizarea unei tehnologii ultramoderne. Endoscoapele operatorii de diverse tipuri, microscopul operator dedicat, neuronavigația, neuroelectrofiziologia, tehnicile avansate de anestezie, chirurgia cu pacientul treaz reprezintă armamentarium fără de care neurochirurgia prin "gaura cheii" nu ar fi posibilă. Folosind tehnicile de mai sus, tratăm un spectru larg de patologii cranio-cerebrale. www.neurohope.ro |
[TEMA]X si 0 cu mai multe "table de joc"
#19
Posted 08 June 2015 - 07:41
Sa-nteleg ca trebuie sa plec de la conditia "Cat timp meciul nu e castigat"? Apoi sa incep sa pun functiile care imi verifica daca meciul e castigat, apoi sa implementez tabla de joc?
|
#20
Posted 08 June 2015 - 08:08
Gândești prea complicat, începe cu testarea unor fapte simple. De exemplu verificarea scenariului: după crearea tablei de joc, aceasta este goală.
Scrii mai întâi testul, care nu va compila deoarece clasa și metodele nu există. Din acest moment nu mai ai voie să modifici acest test. Apoi completezi metodele (până acum goale) care iterează / accesează simbolurile aflate la fiecare coordonată. La început încearcă să implementezi cel mai simplu tip de board, iar cel mai simplu e cea de dimensiunea 0 x 0. Acesta e minimul necesar pentru a face acest test să treacă. Apoi commit cu descrierea scenariului ca mesaj. Apoi treci la scenariul următor, și tot așa, din aproape în aproape, codul de producție se completează. Nu fă scenarii mari dintr-o dată, pentru că vrei să documentezi acea evoluție a proiectului pas cu pas, și asta nu o poți face decât prin commituri mici, cu mesaje foarte clare. Așa se programează sustenabil majoritatea proiectelor mai mari de câteva linii de cod. |
#21
Posted 13 June 2015 - 12:11
Am avut niste lucruri de rezolvat "pe final de an" si nu am avut timpul necesar sa ma apuc de scris cod. Ma apuc acum si mai am o intrebare: primul test de la care trebuie sa plec, il fac in GameConsoleLoop, nu?
Repository-ul in care lucrez este: https://github.com/AlinP25/TicTacToe . |
#22
Posted 14 June 2015 - 07:39
GlontzZz, on 13 iunie 2015 - 12:11, said:
primul test de la care trebuie sa plec, il fac in GameConsoleLoop, nu? OriginalCopy, on 08 iunie 2015 - 08:08, said:
Scrii mai întâi testul, care nu va compila deoarece clasa și metodele nu există. Vad ca-mi pierd timpul degeaba cu tine, si daca nu ma insel, am mai facut o data greseala asta. La revedere, drum bun! Edited by OriginalCopy, 14 June 2015 - 07:39. |
#23
Posted 14 June 2015 - 08:55
OriginalCopy, on 14 iunie 2015 - 07:39, said:
Ce nu ai inteles de aici: ? N-am tinut cont si de partea cu clasele, gandindu-ma ca pot crea cate un obiect pentru fiecare clasa, iar atunci cand accesez metodele cu ajutorul acelui obiect sa primesc eroarea ca nu au fost create... OriginalCopy, on 14 iunie 2015 - 07:39, said:
Vad ca-mi pierd timpul degeaba cu tine, si daca nu ma insel, am mai facut o data greseala asta. La revedere, drum bun! In regula, imi pare rau pentru timpul pierdut! Se poate inchide topicul, din moment ce s-a ajuns la concluzia ca e degeaba. Edited by GlontzZz, 14 June 2015 - 08:55. |
#24
Posted 14 June 2015 - 09:10
GlontzZz, on 14 iunie 2015 - 08:55, said:
N-am tinut cont si de partea cu clasele, gandindu-ma ca pot crea cate un obiect pentru fiecare clasa, iar atunci cand accesez metodele cu ajutorul acelui obiect sa primesc eroarea ca nu au fost create... Cu ce crezi ca e diferita iteratia 0 de restul care urmeaza? In programare trebuie sa eviti cazurile speciale, in primul rand in cod, dar de ce nu, si in proces. Fa totul intr-un proces integrativ, unitar, repetitiv, predictibil; nu fa nimic haotic, sau in dezacord cu modul in care te-ai hotarat sa operezi. |
#25
Posted 14 June 2015 - 09:16
Deci cumva sa plec cu el "de jos de tot", fara clase, testul initial fiind facut direct in main?
|
#26
Posted 14 June 2015 - 09:51
GlontzZz, on 14 iunie 2015 - 09:16, said:
Deci cumva sa plec cu el "de jos de tot", fara clase, testul initial fiind facut direct in main? Compilatorul iti va spune de fiecare data ce-i lipseste, si tu vei face aproape orbeste fix minimul necesar pentru a scapa de acel mesaj de eroare. La inceput, ai un singur fisier test/integration_tests.cpp cu acel main() in el, gol. Te asiguri ca e compilabil si ca ruleaza (ca build system functioneaza corect). Apoi adaugi in acest fisier: #include <Board.h> si mai jos un test care testeaza scenariul din postarea #20. In acest moment ai tot un singur fisier in tot proiectul: testul, fix atat. Si ca sa fim siguri ca iti putem revizui procesul, cel mai bine faci primul commit cu acest cod. Ii dai build si compilatorul iti spune ca nu gaseste fisierul Board.h. Adaugi fisierul src/Board.h. Nu spun sa definesti clasa, ci efectiv sa creezi un fisier gol astfel incat sa scapi de acea eroare a compilatorului. Apoi dai iar build, si iar compilatorul vine cu o eroare la tine, dar de data asta e ALTA eroare. Asta inseamna ca faci progrese. Progresul asta pe care-l faci e masurabil, predictibil, se vede concret ce faci. Si iar citesti mesajul de eroare, si iar faci fix strictul necesar pentru a scapa de acea eroare si pentru a primi fie o noua eroare, fie succes. Si tot asa, repeti ciclul, pana cand acest singur test trece cu succes. Apoi faci al doilea commit, in care explici ce ai implementat - de obicei vei folosi fix numele test case-ului, dar formulat frumos. Daca test case se numeste board_is_empty_after_creation(), mesajul va fi probabil "board is empty after creation". Apoi scrii un nou test case, si commit - doar cu testul care nu trece si care-ti va arata, pas cu pas, ce ai de facut ca sa-l faci sa treaca. Apoi codul, apoi commit cu mesajul. Apoi un nou test case, si commit. Apoi codul, apoi commit cu mesajul. Apoi un nou test case, si commit. ... Gata jocul. Fa orbeste asa cum iti spun si ai sa vezi ca dupa cateva astfel de cicluri TDD vei intra intr-un ritm foarte productiv. Exista studii care demonstreaza asta. Compilatorul iti spune ce ai de facut, nu trebuie decat sa-i urmezi "sfatul". Foloseste tehnologia asa incat ea sa te sustina in activitatea ta, nu trebuie sa fii mereu "incordat" si sa iei mereu toate deciziile: lasi compilatorul sa-ti arate ce ai nevoie. Doar testul trebuie sa fie curat, sa testeze un singur lucru, si sa testeze fix lucrul descris in numele functiei de test, nu mai mult, nu mai putin. Edited by OriginalCopy, 14 June 2015 - 09:46. |
#27
Posted 14 June 2015 - 12:16
Nu reusesc sa inteleg ceva la TDD (probabil si pentru ca e prima oara cand lucrez in acest mod).
M-am documentat si despre tinytest, si despre MinUnit, CppUnit si Boost. Cred ca o sa raman la MinUnit, deoarece mi se pare mai simplist si mai usor de inteles. Din pacate, nu reusesc sa imi dau seama de un lucru. Testele sunt facute in acelasi fisier ca si codul, sau trebuie separat (.cpp + .h)? |
#28
Posted 14 June 2015 - 12:19
|
#29
Posted 14 June 2015 - 12:30
Ma gandeam ca main-ul va fi intr-un fisier separat, iar toate testele puse in altul, sub forma unei clase. Dar se pare ca gandeam gresit...
Din ce vad, cum ai mentionat mai sus, vor vi 2 foldere: src si test. Nu pot fi puse si sub forma unui singur folder, toate in acelasi loc? Revin imediat si cu un git repo nou, de unde sa incep. |
#30
Posted 14 June 2015 - 12:35
Pot fi, daca ai mai facut TDD inainte si esti sigur ca n-o sa amesteci codul de productie cu codul de test.
Apropo, si testele tot cod sunt, ca vad ca ai scris asta: GlontzZz, on 14 iunie 2015 - 12:16, said:
Testele sunt facute in acelasi fisier ca si codul Deci desi pot fi puse varza la gramada, pune-le separat, pentru a micsora riscul de a introduce logica de testare in codul de productie. Logica de testare in cod de productie e un big no-no. |
#31
Posted 14 June 2015 - 16:49
In regula. Pana acum am asa (un fel de reguli pe care trebuie sa le respect, mi le-am scris pe o foaie si lipit de monitor):
- Separ testele de codul de productie: folderele src si test - Dau commit-uri mici si dese - Intai fac testul, abia apoi incep sa trec la codul de productie Ca repository voi avea: https://github.com/AlinP25/TicTacToe . Acum ma apuc sa fac ceea ce s-a precizat in postul #20. |
#32
Posted 14 June 2015 - 17:33
GlontzZz, on 14 iunie 2015 - 16:49, said:
- Dau commit-uri mici si dese Git inregistreaza toata activitatea, de aceea mesaje ca "integration_test.cpp added" nu isi au rostul. Daca vreau sa vad ce fisiere sunt implicate in fiecare commit, folosesc `git log --stat`. Deci degeaba imi spui mie, cititorul de git log (care poate fi un alt coleg de echipa, sau chiar tu, peste 2 ani cand revii in aceasta parte de cod cand proiectul va fi crescand la cateva milioane de linii de cod), ca ai adauga acel fisier. As prefera sa-mi spui ce semnifica el, sau motivatia de a-l adauga, lucruri de genul asta, mai abstracte. Asa nu: "integration_test.cpp added" Asa da: "create entry point for integration tests" Asa nu: "minunit.h added" Asa da: "vendor TDD library" Asa nu: "integration_test.cpp updated" uitandu-ma la diff, ce ai facut acolo a fost sa incluzi minunit.h in celalalt fisier. Puteai sa o faci inca de cand ai vendor-uit minunit.h, caz in care mesajul de commit ar fi fost "vendor and use minunit in integration tests". Un commit nu trebuie sa fie restrictionat la un singur fisier, poti modifica oricate fisiere e nevoie intr-un singur commit, daca acel commit are sens dpv logistic. Alternativ, putea sa sari peste acest commit, si sa adaugi #include in commitul in care ai fi apelat prima data cod din minunit. Nu ar fi fost o problema, codul compileaza si fara acel #include. Retine ca trebuie sa faci minimul de schimbari necesare pentru a iti atinge scopul descris in mesaj. Minimul. Vrei sa lucrezi cu cod cat mai putin, programatorii detesta codul. De ce? Pentru ca daca scrii mult cod, si apoi iti dai seama ca ai luat o decizie proasta, ghici cine trebuie sa maseze codul pana se curata? Tot tu. Cu cat e mai putin cod, cu atat ai mai putin de masat la el. |
#33
Posted 14 June 2015 - 19:48
Am o nelamurire la acest pas:
OriginalCopy, on 08 iunie 2015 - 08:08, said:
De exemplu verificarea scenariului: după crearea tablei de joc, aceasta este goală. Ca sa pot verifica tabla de joc, voi avea nevoie de un obiect al clasei Board. Cum sa fac testul la aceasta etapa? La asta m-am gandit, desi nu cred ca e bine: static char * test_board(){ mu_assert("Tabla de joc nu a fost initializata", bo.gameBoard != 0); } bo fiind obiectul pentru clasa Board, lucru ce va fi intampinat de catre compilator cu o eroare deoarece aceasta nu e creata. gameBoard va fi tabla de joc, la fel, inexistenta in momentul executarii testului. Sau sa fac o functie care verifica daca tabla este goala, iar acea functie sa o dau ca parametru pentru test? Am ideile de implementare ale testelor, doar ca imi e mai greu cand trec la fapte. |
|
#34
Posted 14 June 2015 - 20:14
Ce e "bo"? Nu lucra cu variabile globale. Cauta pe web de ce global variables are evil.
Pune tot codul relevant, inclusiv instantierile, in test cases. Testul e simplu, inventeaza o metoda cu un nume reprezentativ: Board board; mu_assert("the board must be empty after initialization", board.isEmpty()); That's it! Apoi implementeaza metoda. Scrie minimul de cod necesar pentru a face codul sa compileze si testul sa treaca. Si cu minimul, ma refer chiar la minimul! Nu te intereseaza daca are sens ce faci, sau daca e practic util ce faci, singurul lucru pe care-l urmaresti e sa faci compilatorul si linkerul sa taca, si mu sa zica "pass". Hai ca sunt curios daca te prinzi care e minimul de cod necesar. A, si obisnuieste-te sa scrii in engleza totul. https://github.com/A...cb5e37b400e171e "some updates" nu descrie cu claritate ce ai facut. Ce ai facut este: "prefix testing functions with mu_". In plus, nu stiu de ce ai sters acel "extern". De cand se aloca static memorie in headere? E gresit, lasa extern, si aloca variabila unde trebuie. Edited by OriginalCopy, 14 June 2015 - 20:18. |
#35
Posted 14 June 2015 - 20:27
Am facut un commit cu modificarile efectuate pana la validarea testului. Nu am primit eroare la compilare, doar ca atunci cand pornesc programul, primesc urmatoarea exceptie. Voi incerca sa vad poate reusesc sa rezolv...
OriginalCopy, on 14 iunie 2015 - 20:14, said:
"some updates" nu descrie cu claritate ce ai facut. Ce ai facut este: "prefix testing functions with mu_". In plus, nu stiu de ce ai sters acel "extern". De cand se aloca static memorie in headere? E gresit, lasa extern, si aloca variabila unde trebuie. Attached FilesEdited by GlontzZz, 14 June 2015 - 20:29. |
#36
Posted 14 June 2015 - 20:37
[ https://i.imgur.com/JLf6drO.png - Pentru incarcare in pagina (embed) Click aici ]
|
Anunturi
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users