Raamatute hinnavaatluse ülesande soovitusi ja nõuandeid

Allikas: Lambda
Mine navigeerimisribale Mine otsikasti

Alltoodud soovitused on esialgsed, oktoobri alguse jooksul nad oluliselt täienevad: loe regulaarselt üle, leiad uusi ideid!

Kuidas andmeid hoida?

Hoia nii google base xml-st saadud olulisi andmeid (pealkiri, hind) kui panga csv-st saadud valuutakursse (valuuta, kurss) kahemõõtmeliste stringimassiividena. Rehkendamise ajal teisenda numbrid jooksvalt stringist numbriks.

Kuidas pihta hakata ja mis järjekorras programmeerida?

Põhimõte:

Hakka kirjutama valmis üksikuid juppe, alates lihtsamatest. Kui üks on valmis, testi ta läbi ja mine siis järgmise kallale. Testimiseks kirjuta trükkimisi vahele, hiljem kommenteeri mittevajalikud trükid välja või kustuta ära. Alles lõpuks pane kõik main-i sees kenasti kokku.

Väldi algul mistahes keerukusi ja lisavõimaluste tegemist! Ehita kõik algul valmis nii lihtsalt, kui saad, hiljem saad soovi korral koodi täiustada, kui aega jääb.

Soovitaksin teha tükid valmis näiteks sellises järjekorras:

  • Tõmba endale üks näite-XML failina google basest ja näite-CSV panga valuutakurssidega, ning kasuta progemisel algul sisendina neid faile, mitte aga võrguühendust! See on mugavam ja kiirem. Võrguühenduse pidev kasutamine lisa siis, kui enamus asju failide peal juba funkavad.
  • Programmeeri kõigepealt valmis valuutakursside csv faili massiivi lugemise funktsioon (tingimata tee selleks eraldi funktsioon!), katseta, et käiks ok.
  • Seejärel programmeeri valmis google base XML-st massiivi lugemise funktsioon. Katseta, et käiks ok.
  • Seejärel programmeeri valmis gbase massiivist csv tegemine nii, et hindadega esialgu ei tegelda, küll aga loetakse kokku raamatud. Katseta, et käiks ok.
  • Seejärel lisa hindadega tegelemine.

Mis juhtub, kui sa kõiki asju ei oska või ei jõua teha? Kui mingi mõistlik hulk komponente on tehtud ja töötavad, saad oma ülesande siiski arvestatud, ainult et väiksema arvu punktidega (kui praktikumijuhendaja hindab, et tehtud on pool tööd, siis saadki 5 punkti). Kui praktikumijuhendajale tundub, et tehtud on ikka väga vähe (kolmandik või vähem) siis ta üldjuhul seda ülesannet ei arvesta.

Võrgust lugemine

Kõigepealt soovitan teha eraldi katse selle http://java.sun.com/docs/books/tutorial/networking/urls/readingURL.html näiteprogrammiga.

Kui ta ei suuda võrgust lugeda, siis on tõenäoline põhjus selles, et Sinu arvuti ei saa otse internetti ühendust, vaid peab töötama läbi nn proxy.

NB! On võimalik (kuid mitte kindel: proovi järgi!) et kõik AK arvutiklasside arvutid peavad töötama läbi proxy. Siis viidatud näiteprogramm arvutiklassides võrgust lugeda otse ei suuda. Loe TTÜ AK proxy kohta: mida TTÜ AK arvutiklassides töötades vaja teha, KUI proxy osutub vajalikuks.

Tõenäoliselt aga Sinu koduarvutis või kusagil mujal arvutis sellist piirangut ei ole ja näiteprogramm suudab otse võrgust lugeda.

Kui sa ülaltoodud näiteprogrammi järgi url-i avamise ja sealt lugemise oma programmi sisse paned, siis tuleb nende operatsioonide ümber tingimata panna try { ... } catch (..) { ... }, täpselt nagu failioperatsioonidegi ümber.


Soovitusi funktsioonide kirjutamisel

Globaalsed muutujad

Päris mõistlik on kasutada mingit hulka globaalseid muutujaid ja massiive, näiteks:

  • gbdata: kahemõõtmeline massiiv, mis sisaldab google basest loetud infot
  • forexdata: kahemõõtmeline massiiv, mis sisaldab valuutakursse

Funktsioonid võivad vajadusel vabalt otse nende globaalsete muutujatega manipuleerida.


Stringi lõhkumine eraldaja järgi

Sinu programm peab päris mitmes kohas lammutama eraldajaga stringi tükkideks:

  • kettalt loetud csv faili rida, eraldajaks komad
  • käsurealt antud lause

Kuidas seda paremini teha?

Esiteks, iga sellise lammutamise tulemuseks tasub anda stringimassiivi, kus elementideks on järjest vajalikud stringid. Hea on, kui see stringimassiiv teha kohe õige pikkusega, siis saab mh lihtsamalt kontrollida, kui palju elemente temas on (massiiv.length annab massiivi pikkuse).

Valuutakursside rea lõhkumist saab teha eriti lihtsalt: saab eeldada, et reas on täpselt üks eraldaja, milleks on semikoolon.

Teiseks, mõistlik on kirjutada funktsioon, mis võtab ette lammutatava stringijupi, eraldaja-stringi (koma või semikooloni) ja annab tagasi stringimassiivi.

Stringi lammutamiseks on palju meetodeid, võid uurid näiteprogrammi splitproov.java ja kasutada seal olevaid ideid. NB! Selleks, et selle programmi lõike kasutada, on vaja, et sa temast aru saaksid. Vaata kindlasti ka massiivide kasutamise näiteprogrammi massiivproov.java. Samuti on see programm valuutakursside jaoks liigagi võimas: ta võimaldab lõhkuda stringe, milles võib olla kuitahes palju eraldajaid (valuutakurssidel teadupärast ainult üks).

Valuutafaili/stringi sisselugemine ja komade järgi splittimine

Sellest on veidi kirjas siinse jutu lõpuosas. Kindlasti tee funktsioon, mis saab ette stringi ja annab tagasi kahemõõtmelise massiivi temast leitud stringidest.

Muid soovitusi

Stringide võrdlemine

NB! Kui x ja y on stringid, siis võrdlemine

 x==y

ei anna oodatud tulemust! See võrdlus ainult kontrollib, kas x ja y on võrdsed pointerid, st viitavad samale stringile mälus. Aga, kui teeme nii:

 String x="ab";
 String y="ab";
 if (x==y) ...

siis x ja y on erinevad pointerid (kuigi stringide sisud on samad!) ja neid ei peeta võrdseks.

Selleks, et kontrollida, kas stringide sisud on samad, on vaja kasutada sellist spetsiaalset stringivõrdlust:

 x.equals(y)

(selle funktsiooni ja muud head stringifunktsioonid leiab nii Ecki õpikust kui ametliku manuaali lingilt http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html)

Võrdlemaks, kas string x on suurem kui string y (vajalik sorteerimisel), kasuta järgmist funktsiooni:

 x.compareTo(y)

Lisainfot (mitte väga olulist) leiad eelnevalt viidatud linkidest.

Mida compareTo välja annab? int-i. Mida see int näitab? Katseta ise: võrdle paari stringi (pane katse main funktsiooni) ja trüki tulemus-int välja.


Kuidas teha õige suurusega massiiv, kui näiteks stringist või failist andmeid loed?

Failist lugemise kohta vaata kindlasti ka näiteprogrammi ioproov.java

Probleem selles, et meil on vaja panna stringist/failist loetud stringijupid massiivi, aga me ei tea ette, kui palju neid tuleb. Seega, kui suur massiiv tuleks teha?

Siin on, nagu alati mitu lahendust.

Kõige primitiivsem lahendus on kohe teha hästi suur massiiv, ja kui data sinna ei mahu, anda lihtsalt viga. Selles praktikumiülesandes datat väga palju lugema ei pea, seega see lahendus võiks töötada, kuid ta on ebaelegantne ja raskelt laiendatav.

Lihtne ja ebaefektiivne universaal-lahendus on kõigepealt lugeda data välja, aga mitte massiivi panna: selle asemel lugeda kokku ridade arv.

Siis teeme õige suurusega massiivi ja loeme seejärel uuesti kõik read, seekord pannes nad massiivi sisse.

Elegantsem lahendus on vältida mitmekordset lugemist. Aga: kui sa endas väga kindel ei ole, soovitan algul realiseerida lihtsama lahenduse, mida äsja kirjeldasin.

Elegantsema lahenduse saab kirjutada näiteks nii:

Teeme esialgse, ajutise massiivi näiteks suurusega 100 rida (ja õige arv tulpasid). Hakkame sinna lugema. Kui datal mahtus ära, teeme uue massiivi, seekord õige (lühema) pikkusega, ja kopeerime esialgse massiivi vajalikud read sinna massiivi. Vana massiiv visatakse mõne aja pärast prahikoristaja poolt automaatselt ära.

Kui data ei mahtunud esialgsesse massiivi, teeme uue ajutise massiivi, seekord näiteks 2 korda suurema kui eelmine. Kopeerime vanast ajutisest kõik uude ajutisse ja jätkame data uude massiivi lugemist. Võib juhtuda, et nüüd mahub ära. Siis lõpuks teeme õige pikkusega (lühema) massiivi.

Kui ikka ei mahtunud, kordame protseduuri: teeme jälle uue, viimasest massiivist jällegi kaks korda suurema ajutise masssiivi. Jne jne.

NB! Selliselt ajutisi massiive tehes pane tähele, et kuna tulpade arv on neis alati õige, ei ole tegelikult vaja kopeerida vanast massiivist uude üksikute stringide kaupa (st topelttsükliga). Kahemõõtmeline massiiv on ju massiiv mitmest ühemõõtmelisest! Kopeerimise käigus saame kopeerida korraga terve rea (käsitledes massiive kui ühemõõtmelisi) ja see on palju kiirem meetod. Siin on veel võimalik teha mitu täiendavat optimeeringut, aga liiale ei ole optimeerimis-pingutustega ka mõtet minna.