Svake godine više od 80% projekata na seminaru Računarstva propadne. Većina od tih 80% zbog grešaka koje se iz godine u godinu ponavljaju. Ovo je pokušaj da se bar neke od tih grešaka preduprede.
Kada birate projekat, prva stvar koju gledate je da uzmete stvar koja vas zaista interesuje, nemojte se voditi "samo da imam nešto" i "samo da odem na konferenciju" motivima jer će vam biti dosadno i naporno, a ne zabavno.
Vaš projekat će u 99% slučajeva biti eksperimentalnog tipa, iako to možda nije očigledno na prvi pogled. Ovo zvuči čudno ljudima, jer kad se kaže da se radi eksperiment, obično se prvo pomisli na laboratoriju sa gomilom nekih aparatura i instrumenata za merenje.
Vaš eksperiment će biti program uz pomoć kojeg ćete na neki način izmeriti i proveriti vašu hipotezu, što je sledeća vrlo bitna stvar.
Hipoteza je zapravo srž vašeg projekta. To je nekakvo tvrđenje koje pokušavate da pokažete eksperimentalnim putem (tj. programom).
Hipoteza mora da bude zasnovana na nekim činjenicama, ne može samo "da vam padne sa neba". Potrebno je da izložite zbog čega mislite da će vaša hipoteza važiti (odnosno neće).
Da bi krenuli da se bavite nekim problem, prva stvar koju treba da uradite je da proverite da li se neko drugi pre vas nije bavio istim, ili možda nečim sličnim.
Ovo je jako bitno, jer se često dešava da je ono što hoćete da uradite jako poznata stvar i da nema smisla raditi je ponovo. A može se desiti i da je problem obrađivan, samo drugačijim metodama, pa odmah dobijate način da izmerite koliko je npr. neka vaša metoda bolja / gora od postojećih. Ovakva vrsta projekta je veoma česta na računarstvu.
Druga stvar zbog kojih su reference bitne je to što morate da se pozivate na njih. To pokazuje da ste zapravo istraživali nešto o problemu, a često ćete koristiti neke metode koje su opisane u referencama ili ćete se oslanjati na neke osobine za koje je u nekom drugom radu pokazano da važe.
Dakle, da rezimiramo. Dve vrlo bitne komponente dobrog projekat su dobra hipoteza i reference koje podržavaju vašu hipotezu. Bez ta dva se ne može.
Polaznici (a posebno novi polaznici) često mešaju pravljenje programa koji radi nešto i programa koji pokazuje nešto novo - AKA eksperimenta.
Možda zvuči grubo, ali ako je vama neka stvar nova, ne znači da ona nije opštepoznata i da ne postoji 1001 standardni način na koji se to što hoćete radi. Tako da, ako vam padne na pamet da predložite nekakav specifičan program za projekat, obavezno proverite da li to već postoji (spoiler alert: verovatno postoji).
Nemojte da vas ovo obeshrabri od pravljenja takvih programa. Oni su fenomenalan način da se nauče nove stvari, samo nemaju istraživačku komponentu koja je potrebna da bi bili petnički projekat.
Svake godine (ili svakih par godina) u računarstvu postoji neka state-of-the-art tehnologija koja je postala izuzetno popularna i sasvim je normalno da želite da radite projekat koji ima veze sa njom.
Problem sa takvim tehnologijama / pojmovima / algoritmima je to što su još uvek relativno mladi i to što je potreban veoma visok nivo razumevanja nekih veoma teških stvari (uglavnom ili iz matematike ili iz programiranja, često iz oba) da bi se u toj oblasti dao nekakav doprinos.
Tako da, ako želite da radite na ovakvim projektima, dobro razmislite da li je realno da savladate sve što je potrebno.
Jer, nije isto zvati .train()
funkciju iz biblioteke i napisati tu istu funkciju da radi bolje (po kom god parametru).
Ova stvar se direktno nadovezuje na priču iznad. Ne možete da uradite projekat ako to što radite ne razumete.
Najveći problem je što za ovo "razumevanje" nema vremena na letnjem seminaru.
Kada dođete na letnji seminar podrazumeva se da vam je bar nekih 80% toga što radite jasno.
Ako ovo nije slučaj, često nećete imati vremena da uradite bilo šta, jer saradnici koje ste mogli da cimate pre seminara preko mejla / fejsa / nečeg levog ili nisu tu, ili će većinu vremena morati da pomažu i drugim polaznicima.
Ovo je još jedna od stvari na koji ljudi ne obrate dovoljno pažnje. Niko od vas ne traži da posedujete znanje programiranja kada dođete na seminar, niti vam je ono suštinski potrebno da razumete predavanja.
Ipak, ako krenemo od toga da će vaš rad biti zasnovan upravo na nekom programu pomoću kog ćete vi raditi vađe istraživanje, tada dolazimo do problema ako vi ne znate bar osnovne stvari koje se tiču programiranja.
Zašto je ovo problem? - Problem je jer ćete vi tih 10ak dana koliko ste na seminaru provesti u učenju nekog programskog jezika, i provaljivanju kako se rade jako rutinske i jako tehničke stvari, a nećete se zapravo baviti vašim problemom. Dakle, programiranje se ne uči na letnjem seminaru.
Nemojte ovo da shvatite kao neku vrstu pretnje, naravno da se od vas ne očekuje da ćete znati sve i da će sve ići glatko. Saradnici će biti tu da vam pomognu gde god da zapnete.
Ovaj deo će biti posvećen tehničkim aspektima projekta. Ovo je deo na kom zaglavi dosta polaznika i upravo zbog tehničkih stvari ne završi projekat.
Pre nego što uopšte pipnete programski kod, trebalo bi da isplanirate šta ćete i kako ćete da radite.
Za početak, bar da vidite ugrubo od kojih logičkih celina će da se sastoji vaš projekat i šta vam eventualno treba od third-party biblioteka.
Kad odradite ovo, tek onda treba da gledate u kom programskom jeziku je najbolje raditi projekat. Najčešće će to biti jezik koji već dobro poznajete, sem u retkim slučajevima, gde iz kog god razloga, morate da koristite specifičan jezik / framework / nešto treće.
Ovo je prva stvar koju treba da uradite kada završite sa planiranjem.
Na odabir programskog jezika pre svega treba da utiče činjenica koji programski jezik znate, jer se većina projekata može uraditi manje-više u bilo kom general-purpose jeziku.
Druga stvar o kojoj treba da razmislite je šta će tačno vaš program raditi. Jer je su za određene stvari određeni jezici bolji.
Npr. Ako radite neku obradu teksta, dobar izbor bi bio Python, jer ima sasvim lepe standardne pakete koji služe baš za to, dok C nema toliko dobru podršku. Obrnuto, ako želite da se bavite nekim mikrokontrolerima čija se memorija meri u kilobajtima, C vam može biti jedina opcija.
O ovome treba da odlučite pre nego što dođete na seminar i, ako se odlučite za jezik sa kojim niste upoznati, krenete da vežbate pisanje koda. Najbolja vežba za ovakve stvari je da osmislite i napravite neki mali program koji radi neku stvar koja vam je kul, ili koji vam automatizuje nešto što vas smara da radite. Novi programski jezik ne učite na seminaru.
Gotovo svi polaznici nekako smetnu sa uma da su njima rezultati zapravo najvažniji deo celog projekta i generalno ne vode previše računa šta rade sa njima.
Dakle, ceo vaš fensi program uglavnom služi za to da vam u neki .txt fajl upiše neki output koji pokazuje nešto. To nešto su uglavnom neki brojevi, procenti uspešnosti, ili nešto slično...
Ako ne sačuvate ove fajlove, vi nemate projekat.
Takođe, ako postoji više verzija projekta koji vam daju rezultate, veoma je važno da imate sačuvane rezultate za svaku verziju.
REZULTATE NIKAD NEMOJTE DA ČUVATE SAMO LOKALNO
Dakle, neki Google Drive, GitHub, bilo koji cloud hosting. Niste svesni koliko je teško iskopati rezultate kada se za par nedelja vratite projektu. Ili, ako vam na random crkne hard disk na računaru.
Rezultate čuvajte u lepom formatu, sa lepim imenima i kategorizovane tako da vam je, kada se za par nedelja od završetka letnjeg seminara i setite da bi trebalo da nastavite da radite na projektu, bilo lako da odmah nađete rezultate i vidite šta vam koji rezultati pokazuju.
Još jedna stvar zbog koje je bitna kategorizacija je da bi bili sigurni koji rezultati su oni koje ćete konačno prikazati u radu. Projekat koji nema validne rezultate nije projekat.
Nikako nemojte čuvati samo grafike, ili slike, ili šta god. Uvek čuvajte sirove podatke. Grafici koje vi nacrtate i stavite u vašu verziju rada koju šaljete na reviziju se uglavnom ne koriste kada je vreme da se rad spremi i "spakuje" u petničku svesku, nego će vam se skoro uvek samo tražiti sirovi podaci. Ovo se radi kako bi se napravili grafici boljeg kvaliteta od onih koje ste vi stavili (uglavnom je potreban veći dpi da bi to izgledalo lepo kad se odštampa).
Druga problematična stvar kod nečuvanja sirovih podataka je što onda dolazite u situaciju da neko vama treba da veruje na reč da je vama slika koju ste stavili merodavna i da zaista prikazuje dobijeni rezultat.
Kako je programiranje ono što vama suštinski uzima najveći deo vremena kod izrade projekta, ovaj deo će biti posvećen tome da vam pokaže i ukaže na neke stvari koje će vaš programerski život učiniti dosta srećnijim, a i lakšim.
Prva stvar o kojoj pričamo je Source Control. Verujem da su neki od vas već krenuli da uzdišu, ali ovo je jedan od krucijalnih alata koji se koristi svuda, pa ne postoji neki racionalan razlog da ga i vi ne koristite. Ako planirate da se profesionalno bavite bilo čim što ima veze sa programiranjem, podrazumevaće se da znate ovo.
Na source control možete da gledate kao na alat koji bukvalno pravi snapshot koda vašeg programa. Svaki ovaj snapshot se čuva, i svakom možete da se vratite.
Još jedna bitna stvar, ti snapshotovi se čuvaju i kod vas i na nekom serveru, tako da vi automatski dobijate backup vašeg programa i mogućnost da isti taj program svučete na bilo koji računar koji ima instaliran source control.
Možda niste svesni, ali gomila vas već koristi "primitivni" source control koji podrazumeva da vi vaš kod snimite na neki fleš, ili pošaljete sebi na mejl ili kao poruku na fejsu / vocapu / nečem trećem. Ovo radite upravo jer želite da sačuvate nekakve verzije vašeg programa.
Source control samo olakšava ovo. Takođe, još jedna bitna prednost je što možete čuvati i sve dobijene rezultate, i čak i da se desi da zagubite starije rezultate ili vam se zapali komp recimo, uvek možete da pristupite svim verzijama koje ste sačuvali.
Najpoznatiji i najkorišćeniji source control. Sigurno ste čuli za GitHub ili GitLab. Postoji još gomila drugih koji ispod haube koriste git. Takođe, najčešće korišćen u industriji.
Druga bitna stvar, koja uopšte nema veze sa projektom. Ako budete tražili posao (posebno prvi posao) profil na nekom od ovakvih sajtova izuzetno znači, jer to pokazuje da ste vi nešto radili i činjenica da li imate ili nemate git repoe koje neko može da pogleda će da pravi razliku između toga da li će vas zvati ili ne.
Stvari o kojima ćemo pričati ovde vas skoro sigurno smaraju, i gomila vas misli da su gubljenje vremena. Ja ću da pokušam da vam objasnim zašto to ipak nije tačno.
Dakle, rešili ste šta radite za projekat, imate plan, i došlo je vreme za pisanje koda. Baš zbog ovog pisanja koda propadne lep broj projekata. Ispod su, kao mala poglavlja, date neke česte greške koje se dešavaju u ovom procesu.
Koliko god vama ovo banalno zvučalo, dobro imenovanje unutar koda je jedna od najvažnijih stvari koje treba da naučite.
Zašto je ovo bitno, i zašto vas smaramo oko ovoga? - Bitno je jer ćete vi sigurno u nekom trenutku posle pisanja ključnih delova koda morati da se vratite istom tom kodu (iz kog god razloga).
Takođe, verovatno će vam u nekom trenutku trebati pomooć oko debagovanja, a tu će vam pomagati ljudi koji verovatno prvi put u životu prolaze detaljno kroz vaš kod. E, u ovakvim slučajevima dolazimo do zanimljivih situacija.
Razlika između:
cc = s.c i currentCoef = simulation.coef
ili:
d(): i drawScreen():
je ogromna
Prva stvar koju eliminišete dobrim imenovanjem je razmišljanje potrebno da se skonta šta piše u liniji koda. Druga stvar, koju dobijate, je beskonačno puta lakše debagovanje i promene koda, jer vam bukvalno piše šta se dešava.
Pretpostavimo sledeću situaciju: Bili ste na letnjem seminaru, odmah posle ste otišli na letovanje, i treba da doradite par stvari kada dođete. Dakle, 10 dana ne vidite komp. Razmislite kada će vam biti lakše da se "vratite" u kod, kada imate deskriptivna imena, ili kada imate 1 ili 2 slova na sve strane.
Takođe, nečitljiv kod vam niko neće debagovati, jer je samo potrebno previše vremena da bi se uopšte shvatilo šta se događa u kodu, da bi tek onda moglo i nešto da se izdebaguje.
Česta stvar na koju se nailazi kada polaznici pitaju za pomoć je projekat koji se sastoji iz par ogromnih funkcija ili, još gore, od jednog fajla sa jednom jedinom funkcijom.
Zašto je ovo problem? - Kod koji ćete pisati za projekat uglavnom je dosta složeniji od koda za, recimo izračuvananje površine trougla, i sigurno se sastoji iz više logičkih celina. Svaka logička celina ima jedan specifičan zadatak koji treba da uradi, predstaviću to na primeru obrade slike.
Hoćemo da učitamo sliku, da obojimo sve crne piksele u belo, da rotiramo sliku, i da na kraju sliku prebacimo u grayscale. Ovde odmah primećujemo par odvojenih logičkih celina:
- Učitavanje slike
- Pretvaranje crnih piksela u bele
- Rotiranje slike
- Prebacivanje slike u grayscale
Česta situacija na koju se nailazi je da je ceo ovaj logički tok stavljen u jednu funkciju. Ovo je izuzetno loša praksa jer vam na više načina otežava život:
- Funkcija je ogromna i teško je ispratiti šta se dešava
- Nešto ne radi, ne znate što, i treba da degabujete
Upravo zbog ove druge tačke vas toliko smaramo kad vidimo ovakve stvari. Kada imate manje funkcije, pre nego što sklopite ceo tok programa, možete zasebno da testirate svaki deo. Ovako ćete izbeći stuacije gde ste sve nakucali i tek onda krenuli da testirate (što je u principu i jedini način kada imate ogromnu funkciju) i odmah ćete znati gde vam je greška. Ovakvo pisanje koda je jedno od većih krivaca zašto projekti ne budu završeni na vreme - napišete par hiljada linija koda koji niste sigurni da li radi, a roknuli ste ga u jednu funkciju, i kada dođe vreme da se testira nemate apsolutno pojma šta je problem.
Zapamtite: Funkcija treba da radi samo jednu, tačno određenu stvar!
Ovo se nadovezuje, a često i ide u paru sa ovim iznad. Recimo da vam program ima više većih logičkih celina. Na primer treba da iscrtate nešto na obrađenoj slici i da onda sa te slike isčitate piksele i da gledate neku raspodelu ili da tražite neku korelaciju, jasno se vide 3 celine:
- Učitavanje i obrada slike
- Iscrtavanje poligona
- Statistička obrada
Najgora stvar koju možete da uradite je da sve, kao i kod tačke gore, zabijete u jedan fajl. Što više vežih logičkih celina imate to će vam složenost debagovanja rasti, i ako ne podelite kod na vreme, nećete ga izdebagovati nikad.
Mnogi Svi relativno novi programeri bi odmah da sednu i da kucaju. I to je donekle opravdano, ali ne i dobro, posebno ako radite na nečemu što ima više od 100 linija koda.
Prva stvar koju treba da uradite je da se dohvatite (digitalnog) papira i da ugrubo napišete / iscrtkate logiku vašeg programa i da zatim pokušate da sagledate čitavu celinu. U trenutku kada ovo pišete nije bitno da li znate kako tačno ćete implementirati to što ste napisali, bitno je da znate šta to treba da radi
Ako na ovaj način osmislite strukturu vašeg koda, uvek ćete imati čemu da se vratite ako mislite da ste se izgubili u razmišljanju ili programiranju.
Još jedna super stvar kod ovoga je što se odlično skalira, tj. kako ste napravili dijagrame i logiku za ceo projekat, tako sada možete krenuti u detaljnije definisanje manjih celina tog projekta prateći sličan princip.
Sa ovim treba stati kada vidite da je sva usitnjenja logika koju ste upisali dovoljno prosta da stane u funkciju koja će raditi samo to.
Kul programi koji vam mogu koristiti za pravljenje dijagrama:
Seli ste, smislili projekat, podelili ga na celine, smislili zadatke i sad treba da krenete da radite. Ono što će vam mnogo olakšati život u ovom trenutku je nekakav alat koji će pratiti te vaše zadatke i preko kog, ako ste ažurni, ćete uvek znati koliko stvari ste završili i koliko stvari vam je ostalo.
Svi alati za praćenje rade po sličnom principu, gde imate par nekakvih kategorija u koje onda upisujete zadatke koje treba da uradite. Nekakav najprostiji primer te podele bi bio projekat gde imate sledeće kategorije:
- Treba detaljno da se smisli šta da se uradi
- Treba da krene da se radi
- Trenutno se radi na tome
- Urađeno
Zašto je ovo dobro? - U svakom trenutku znate stanje svih zadataka koji treba da se odrade i u svakom trenutku vam je jasno vidljivo šta je sledeće što treba da se odradi i šta je najbitnije. Tako da ne gubite vreme na razmišljanje o tome šta treba sledeće i možete mnogo lakše da prioritizujete stvari.
Neki od tipičnih alata koji se koriste za ove stvari:
Gotovo svi projekti koji su do sada (uspešno) odrađeni na računarstvu (pa verovatno i u Petnici generalno) se mogu ugrubo svrstati u 3 kategorije:
- primena rešenja iz jednog domena na drugi problemski domen
- prilagođavanje opšteg rešenja na specifičan problemski poddomen
- unapređivanje / izmena postojećeg rešenja problema
U prvu kategoriju spadaju projekti koji ideje iz jednog problemskog domena primenjuju na neki drugi, ili malo uopštenije, rešavaju neki postojeći problem na nov način. Primer ovakvog projekta bi bio simulacija kretanja fluida pomoću celularnih automata (Nožinić, 2015). U tom projektu ideja iz jedne oblasti (celularni automati) korišćena je za rešavanje drugog problema - simulacije fluida. Kod njih je hipoteza prosto da će to rešenje davati zadovoljavajuće rezultate, da li zbog sličnosti dva domena, ili zbog nekih drugih faktora.
U drugu kategoriju spadaju projekti koji uzimaju opšte rešenje za neki opšti problem, i prilagođavaju ga nekim specifičnostima podproblema koji se posmatra. Tu se pretpostavlja da će rezultati biti znatno bolji, uz odgovarajući trade-off (vreme predprocesiranja, ...). Primeri ovakvih projekata su obično computer vision projekti, kod kojih se opšti "alati" kojima CV raspolaže primenjuju na konkretan problem (traženje meteora na noćnom nebu (Gavrić, 2016), procena oblačnosti (Tešić, 2016), ...).
U treću kategoriju (koja se donekle može smatrati podvrstom ove druge) ulaze oni projekti koji pokušavaju da unaprede postojeći algoritam / rešenje za neki problem. Primeri bi bili unapređivanje WiFi sigurnosnog protokola (Šikuljak, 2017) i traženje duplikata u kodu pomoću AST (Bebić, 2017). Kod oba su referentna rešenja unapređena dodavanjem jednog ili više koncepata, i posmatrano je kako i koliko to utiče na rezultate.
Problem nastaje kada vi imate ideju za projekat, a ona pokušava da bude negde između svega ovoga. Najčešće to ispadne između prve i druge kategorije, pa dobijete "primena jednog rešenja na isti taj problemski domen" - što kad se ovako već kaže vidite da nema mnogo smisla (ovde upadaju svi "primena ML na nešto" predlozi). Ukoliko već imate takav predlog, dobra ideja je da probate da ga "ugurate" u neki od ovih pomenutih kategorija.
primer : ako je predlog "primena ML na razlikovanje slika pasa i kaktusa" možete da sagledate specifičnosti tog problemskog domena i vidite kako se te specifinosti mogu iskoristiti za unapređivanje vašeg rešenja. Čitanjem literature shvatićete da su kaktusi (obično) zelene boje, a da psi (najčešće) nisu, te da jednostavno brojanje "zelenkastih" piksela može da da prilično dobre rezultate za vaš problem. Time ste uspešno upali u ovu drugu kategoriju, iskoristivši computer vision principe (u najširem mogućem smislu) da rešite (prilično) specifičan problem. Kao dodatan bonus, možete to novo rešenje porediti sa pravim ML-ov (recimo istreniranom CNN) i porediti ta dva rešenja.
Naravno, postoje veoma dobri projekti koji ne upadaju ni u jednu od ovih kategorija, naročito oni koji se bave obskurnim oblastima računarstva, ali ako već imate maglovitu ideju / interesantnu oblast kojom želite da se bavite, probajte da je sagledate kroz jednu od ovih grupa.