Nenad Božidarević

Zašto je testiranje važno?

Codility logoDanas mi je na Twitteru iskočilo nekoliko cvrkuta sledećeg sadržaja

I scored 94% in #c on @Codility!

I scored 100% in #csharp on @Codility!

I’ve got Golden Certificate Delta 2011 on @Codility!

Programski jezici, testiranje znanja, “code” u nazivu? Sasvim dovoljno da rasplamsa moju radoznalost…

Kao prvo, šta je Codility? Bez prevelikog udubljivanja u tematiku sajta i vršljanja po njemu, jasno se vidi da je ideja autora bila da iskombinuje sajt za zapošljavanje (npr. Freelancer.com) sa sajtom za vežbanje algoritama (odličan primer za ovo drugo bi bio domaći Z-Trening).

Codility saves time of software talent recruiters by filtering out job candidates who cannot write correct programs.

Codility administers short programming tests and checks whether solutions are rock solid.

Naime, da bi se poslodavcima olakšao proces selekcije, ovaj sajt pred zainteresovane programere stavlja određene algoritamske zadatke koje oni moraju rešiti za ograničeno vreme da bi pokazali svoje (neophodno) znanje. Naravno, ceo proces je automatizovan, pa se tako rešenja testiraju na predefinisanom skupu test primera. Veoma zanimljiva ideja, ali i nezgodna, jer poslodavac procenu kandidata (odnosno nekih njegovih kvalifikacija) prepušta računaru — setimo se problema koje je Skynet napravio.

Pročitaj ostatak teksta

Put u Bukurešt i AI Olympics

Otišli smo u Bukurešt, prisustvovali finalu takmičenja, slušali razna predavanja, i vratili se nazad u Beograd…

Pročitaj ostatak teksta

AI Olympics – razvoj veštačke inteligencije

AI-MAS Winter OlympicsKrajem prošle (kalendarske) godine kolega sa fakulteta mi je skrenuo pažnju na ovo zanimljivo takmičenje – AI-MAS Winter Olympics. U pitanju je takmičenje koje organizuje Politehnički Univerzitet u Bukureštu, odnosno njihov Artificial Intelligence and Multi-Agent Systems odsek, a cilj je razviti veštačku inteligenciju.

Iako “veštačka inteligencija” možda zvuči previše zahtevno, situacija nije uopšte toliko komplikovana. Naime, takmičarskim timovima su ponuđene tri kategorije u kojima mogu da učestvuju, a svaka kategorija predstavlja određenu (društvenu) igru za koju je potrebno razviti algoritam. S obzirom na poduži pravilnik za svaku igru, kao i to da u jednoj partiji učestvuje više timova, apsolutno je nemoguće pobediti sa nekom linearnom taktikom, i tu na scenu stupa najosnovniji oblik veštačke inteligencije. U zavisnosti od početnih uslova, okruženja, načina na koji igra protivnik i sl. potrebno je da vaš algoritam reaguje na najbolji mogući način.

Pročitaj ostatak teksta

Bash skripta za backup podataka

Hteo bih sa vama da podelim jednu veoma jednostavnu Bash skriptu za backup podataka. (Možda čak ne bi ni trebalo da je nazivam skriptom, s obzirom da je u pitanju samo jedna komanda.)

Otkad sam u potpunosti prešao na Linux, odnosno Ubuntu, Windows je iza sebe ostavio slobodnu jednu particiju od 120GB koju sam koristio za čuvanja podataka. Kada je postalo tesno, kupio sam još jedan hard disk, a ovaj odlučio da iskoristim za backup određenih podataka koje nikako ne želim da izgubim – kako lične, tako i “poslovne” prirode.

Skipta zapravo koristi program rsync koji vrši sinhronizaciju podataka. Ovo je vrlo korisno kada je u pitanju backup, zato što pri svakom pokretanju kopira samo nove i izmenjene fajlove. Ručno kopiranje bi zahtevalo ili overwrite starih fajlova, ili naknadno kopiranje svakog izmenjenog fajla posebno. Parametri za rsync su folderi koji se kopiraju i folder u koji se kopira. U mom slučaju to izgleda ovako:

#!/bin/sh
rsync -avv /media/data/Files /media/data/Pictures /media/backup

Dakle, prva dva parametra (ne računajući -avv) su folderi koji se kopiraju, a poslednji parametar je folder u koji se ti podaci kopiraju. Pritom, ova skripta neće brisati fajlove koji se nalaze u backupu, a nema ih na originalnoj lokaciji. Da bi se obezbedila i ova funkcionalnost, potrebno je dodati parametar --delete.

Na ovaj način, rsync kopira određene foldere, a ne njihov sadržaj. Ukoliko neko želi da kopira samo sadžaj određenog foldera, na primer sve što se nalazi na disku data, sintaksa bi bila sledeća:

#!/bin/sh
rsync -avv /media/data/ /media/backup

Jedina razlika je to što je dodata kosa crta na kraju putanje – ona označava sadržaj foldera, dok se bez nje kopira sâm folder.

Naravno, najbolji resurs je rsync man stranica. Ja skriptu pokrećem ručno, s vremena na vreme, ali verovatno bi bila dobra ideja automatizovati njeno izvršenje, recimo pomoću Cron-a.

Rad sa velikim brojevima u C++u (3. deo)

Treći deo razvoja klase za rad sa velikim brojevima. Ukoliko niste pročitali prethodna dva, počnite od prvog.

Dosta toga smo već iskodirali za našu klasu. Tačnije, obezbedili smo najbitnije, osnovne funkcionalnosti. Međutim, iz test primera se moglo primetiti da je ovakva klasa malo nezgodna za korišćenje.

a = a.saberi(b.podeli(c));

Zašto pisati ovako komplikovan kôd kad može jednostavnije:

a = a + b / c;

Ili čak:

a += b / c;

C++ nam dozvoljava da ovo uradimo uz pomoć preklapanja operatora (operator overloading), odnosno definisanja šta će koji operator da radi kada se susretne sa objektom naše klase. Neću da izmišljam toplu vodu objašnjavajući ovaj koncept, već ću vas samo uputiti na ovaj odličan tekst.

U C++u postoji nešto više od četrdeset operatora koji se mogu preklopiti, a mi ćemo iskoristiti samo one za koje već imamo napisane funkcije u klasi, pa će ovaj deo tutoriala zapravo biti veoma kratak. Počećemo sa još jednim proširenjem naše klase, pa posle nastavljamo sa operatorima za čitanje i ispisivanje brojeva.

	VelikiBroj operator + (const VelikiBroj& desni) const;
	VelikiBroj operator - (const VelikiBroj& desni) const;
	VelikiBroj operator * (const VelikiBroj& desni) const;
	VelikiBroj operator / (const VelikiBroj& desni) const;
	VelikiBroj operator += (const VelikiBroj& desni);
	VelikiBroj operator -= (const VelikiBroj& desni);
	VelikiBroj operator *= (const VelikiBroj& desni);
	VelikiBroj operator /= (const VelikiBroj& desni);
	bool operator == (const VelikiBroj& desni) const;
	bool operator != (const VelikiBroj& desni) const;
	bool operator < (const VelikiBroj& desni) const;
	bool operator <= (const VelikiBroj& desni) const;
	bool operator > (const VelikiBroj& desni) const;
	bool operator >= (const VelikiBroj& desni) const;

Svi ovi operatori su definisani tako da rade isključivo sa objektima naše klase VelikiBroj. Naravno, bilo bi pametno obezbediti i sabiranje običnih integera sa velikim brojevima, ali to prepuštam vama – ovo ne bi trebalo da predstavlja problem, s obzirom da su sve potrebne funkcije već implementirane.

Pročitaj ostatak teksta

Rad sa velikim brojevima u C++u (2. deo)

Ukoliko do ovog teksta niste došli sa prvog dela tutoriala, verujem da bi najsmislenije bilo prvo njega pročitati.

U prvom tekstu koji se bavi velikim brojevima odrađeni su najosnovniji elementi klase, konstruktori, ali i tri aritmetičke operacije – sabiranje, oduzimanje i množenje. Međutim, deljenje je izostavljeno, zbog svoje specifičnosti, pa ga obrađujem tek u ovom delu tutoriala.

Kako naša klasa radi isključivo sa celim brojevima, deljenje će funkcionisati isto kao i deljenje dva integera – tačnije, rezultat će takođe biti ceo broj, pa će ovo biti celobrojno deljenje. Ukoliko rezultat operacije deljenja nije ceo broj, naša klasa će posmatrati samo deo broja pre decimalnog zareza, odnosno zaokružiće vrednost broja ka nuli.

Za slučaj da nije jasno, sledi nekoliko primera:

  • 6 / 3 = 2
  • 7 / 3 = 2
  • -10 / 3 = -3
  • -15 / -6 = 2
  • 24 / 0 = greška – deljenje nulom nije dozvoljeno

Ali prvo, da bismo olakšali proces deljenja, uvedimo dve funkcije za poređenje velikih brojeva.

Pročitaj ostatak teksta

Kalkulator kompleksnih izraza

Ovaj tekst je više pojašnjenje načina rada klase nego uputstvo za njeno pravljenje. Iz tog razloga bi bilo pametno prvo skinuti klasu i pratiti njen kôd uporedo sa čitanjem teksta.

Za jedan od projekata na fakultetu, iz predmeta Objektno-orijentisano programiranje, odlučio sam da uradim program za iscrtavanje grafika. Već sam se bavio ovim problemom, ali tri godine ranije, i to u Delphiju, pa sam ovaj put ozbiljnije prišao problemu koji je trebalo da realizujem u Javi.

Program je bio veoma jednostavan:

  • korisnik unese matematički izraz u kome figuriše promenljiva x
  • korisnik ručno unese granice za X i Y osu, odnosno odredi deo grafika koji želi da se prikaže (verovatno najveća mana programa)
  • grafik se iscrta

Sam GUI je realizovan uz pomoć Swinga, ali u to neću zalaziti. Ovde ću prikazati klasu za računanje (relativno) kompleksnih matematičkih izraza (doduše, ne na nivou Wolframa, pa ni kalkulatora koji dolazi uz Ubuntu) koja vuče korene iz tog projekta – pruža neke dodatne mogućnosti, ali bez iscrtavanja grafika (samim tim i bez promenljivih), pa je za demonstraciju njenih mogućnosti dovoljna konzolna aplikacija.

Pročitaj ostatak teksta

Borba sa Internet Explorerom

Ne mogu da kažem da sam se dovoljno bavio web sajtovima da bih bio HTML/CSS ekspert, iako to traje već nekoliko godina. Ali, ono što mogu da kažem jeste da sam se tokom tih nekoliko godina susreo sa previše problema, odnosno bagova. A ko drugi da bude kriv za to nego Internet Explorer.

Kada sam tek počinjao da se bavim ovim, XP je bio aktuelni Windows, i zajedno sa njim šesta verzija Internet Explorera. Otelotvorenje samoga đavola (ili Đavola?). Koliko god ja taj pretraživač želeo da potisnem, ostaje činjenica da se on i dalje koristi, kod nas verovatno i više nego u svetu, baš zbog te rasprostranjenosti Windowsa XP, pa zbog toga ne smem da ga zanemarim tokom razvoja nekog sajta.

Ovaj moj blog nije nikakav izuzetak. Proveo sam nekoliko nedelja radeći na HTML i CSS kôdu, pritom proveravajući njegov izgled samo u Firefoxu, pošto mi na Linuxu Internet Explorer i nije dostupan. Poučen pređašnjim iskustvom, znao sam na šta da obratim pažnju da ne bih posle morao da se patim ispravljajući greške, kao što sam znao da će sajt sigurno u redu izgledati u Operi, Chromu i Safariju ako ga sredim u Firefoxu.

I kao što sam znao da u Internet Exploreru neće. Pri samom kraju “dizajniranja” (ne smatram se dizajnerom, jer ni nemam oko za to) digao sam XP u virtuelnoj mašini, instalirao sve pretraživače, otvorio IE6, i… Pokušao da shvatim zašto se delovi teksta nalaze na najnelogičnijim mogućim mestima.

Pročitaj ostatak teksta

Rad sa velikim brojevima u C++u (1. deo)

Ovo je prvi u seriji tutoriala iz programiranja čiji cilj nije da u potpunosti i bez greške obrade neku tematiku, već da programera uvedu u određen način razmišljanja koji je potreban za rešavanje dotičnog problema. Osnovno poznavanje programskog jezika se podrazumeva. Ostale tutoriale možete naći pretragom po odgovarajućem tagu.

U najrasprostranjenijim programskim jezicima rad sa celim brojevima je ograničen kako arhitekturom računara, tako i samim jezikom. Jedan od najčešćih problema sa ovim jeste maksimalna vrednost koju možemo sačuvati u memoriji kada radimo sa celim brojevima. Uzevši u obzir rasprostranjenost 64-bitnih arhitektura, može se slobodno reći da je raspon koji ceo broj može da pokrije od 9.223.372.036.854.775.808 do 9.223.372.036.854.775.807 kada se radi sa negativnim brojevima, odnosno od 0 do 18.446.744.073.709.551.615 kada se radi samo sa pozitivnim – tačnije, 264 različitih brojeva.

Korišćenjem floating-point brojeva mogu se zapisati i veće vrednosti, ali ovaj format, zbog načina čuvanja u memoriji, ne pokriva ravnomerno skup brojeva, pa se neke vrednosti ni ne mogu zapisati, a u svakom slučaju ne mogu da se predstave apsolutno svi celi brojevi. Iz tog razloga ovo nećemo razmatrati kao rešenje.

U većini slučajeva, 264 vrednosti je sasvim dovoljno, ali čim se dođe do nekih ozbiljnijih primena i operacija nad velikim podacima, svi osnovni tipovi podataka su neupotrebljivi. Međutim, ono što se može uraditi jeste čuvati brojeve kao niz (decimalnih) cifara – najjednostavnije, ali i čoveku najprirodnije rešenje. Oni koji programiraju u Javi sigurno znaju da ovaj jezik već ima klasu BigInteger za rad sa velikim brojevima, a na Internetu postoji mnogo klasa i za druge jezike koje su sigurno bolje od ove. Međutim, kao što sam naveo na početku teksta, ja vas samo uvodim u problem i pružam osnovnu ideju. Na vama je da je posle bolje istražite, razradite i usavršite. S obzirom da se ne smatram stručnjakom svi predlozi za unapređenje kôda su dobrodošli.

Pročitaj ostatak teksta

Re-Volt i Windows 7

Prvi, svečani tekst na blogu… Žao mi je, ništa od fanfare-a.

Da bih probio led, odnosno writer’s block, odlučio sam da za prvi tekst iskoristim tekst sa mog prethodnog bloga, i to jedini koji je uopšte privukao neku pažnju. Možda ovde neće biti zainteresovanih, ali mi je pomalo žao da gledam početnu stranu ovako praznu…

Već neko vreme na svoj računar nisam instalirao nijednu igru, pa me je zbog toga odjednom zahvatila nostalgija. Da bih je se otarasio, počeo sam da preturam po svojoj višegodišnjoj gomili diskova – naravno, nakon što sam je izvukao i obrisao (isto tako višegodišnju) prašinu – i naleteo na, u mojim očima, stari klasik koji kao da nije dobio dovoljno pažnje u Srbiji. Re-Volt.

Nekim čudom, CD je i dalje radio, i bez problema sam odradio instalaciju na Windowsu 7, ali sam kod pokretanja igre naleteo na problem: Can’t flip display buffers i iskakanje na desktop. Naravno, u pitanju je problem oko kompatibilnosti sa Windowsom 7 i Vistom, s obzirom da je igra iz 1999. godine, ali se lako rešava.

  1. Nakon instalacije, potrebno je odraditi update igre na verziju 1.207 (fajlove je potrebno prekopirati u folder sa igrom)
  2. Napraviti shortcut za pokretanje igre na desktopu
  3. Izmeniti podešavanja za shortcut, i to:
    • dodati -sli u Destination, posle putanje do fajla
    • pod Compatibility tabom izabrati Windows 98 i Run as administrator
  4. Pokrenuti igru, koja će sada verovatno da radi