Ohjelmoinnin ongelmanurkkaus

Auttakaa taas miestä mäessä.

Kokeilen tehdä ohjelmaa joka myy tuotteita. Myynnissä on eri hintaisia tuotteita ja kun ohjelma lopettaa, niin yhteenvetona pitäisi saada tilastot myydyistä tuotteista ja saaduista maksuista.

while (!katsomo.equalsIgnoreCase("L"))
{
bruttoSumma = hinta+ hinta;
lkmYht = lkm + lkm;
if (katsomo.equalsIgnoreCase("A") || katsomo.equalsIgnoreCase("B") || katsomo.equalsIgnoreCase("C"))
{
//pyydä hinta
System.out.println("Kuinka monta lippua? ");
lkm = lukija.nextDouble();
lukija.nextLine();

//laske hinta, oma metodi.
hinta = laskeHinta(lkm,katsomo);

//tulosta alv
System.out.println(lkm+"lippua, yhteensä " + muotoiltu.format(hinta) + " euroa");
}
else{
//tulosta virheilmoitus
System.out.println("\n*** Annoit lajiksi " + katsomo + "\nPitää olla a tai b ***");
}
//pyydä laji
System.out.println("Anna katsomo L lopettaa");
katsomo = lukija.nextLine();
}

System.out.println(" yhteensä " +lkmYht+ "summa"+ bruttoSumma);
}

Tämä on siis osa ohjelmasta. While rakenteen alussa pyydän tallentamaan lukumäärän ja bruttosumman, ne ei kuitenkaan tulostu tuonne loppuun. Tai tulostuu, mutta luvut eivät täsmää oikeiden myynti lukujen kanssa.

Mitä teen väärin. Tai teen paljonkin väärin, mutta millä ratkaisen tuon tilasto jutun? En oikein tiedä miten tekisin tilastoile omaa metodia, kun logiikka ei riitä.
 
10% ALENNUS KOODILLA PAKKOTOISTO
^

Nyt ymmärrän mitä tuo tekee. Eli se laskee vain toiston viimeisessä kyselyssä vastaanotetut tiedot, eli plussaa yhteen viimeiseksi saamansa tiedot.

Miten tuo tehdään toimivasti?
 
^
Nyt ymmärrän mitä tuo tekee. Eli se laskee vain toiston viimeisessä kyselyssä vastaanotetut tiedot, eli plussaa yhteen viimeiseksi saamansa tiedot.

Miten tuo tehdään toimivasti?

Siinä on ainakin kaksi vikaa. Ensinnäkin, kun keräät kokonaisummia, niin sun pitää lisätä uuden kierroksen luku vanhaan kokonaissummaan. Eli
Koodi:
bruttoSumma = bruttoSumma + hinta;
lkmYht = lkmYht + lkm;

Toinen ongelma on se että nuo kannattaa lisätä vasta sen jälkeen kun ne on luettu ja laskettu, eli heti tuon laskeHinta() kutsun jälkeen.
 
Kiitos. Tuon ensinmäisen neuvon tajusin pari minuuttia ennen vastausta.

Mutta kiitos, nyt toimii kun laitoin laskehinta kutsun jälkeen.

Kiitos todella paljon.

:dance:
 
Minä täällä taas moi:jahas:

Tähän kysyin joskus aiemmin jo hjelppiä eli mikä tuossa mättää. Nyt siis kun käyttäjältä kysytään metreissä pituus ja vastaan esim 1.83 niin johan tulee punaista erroria. Eli miten tämän saa pelittämään? Kiitos :)


import java.util.Scanner;
public class Painoindeksi {
public static void main(String[] args) {
String nimi;
double pituus;
int paino;
double painoindeksi;

Scanner input = new Scanner(System.in);
System.out.println("Mikä on nimesi? ");
nimi = input.next();

System.out.println("Ilmoita pituutesi (metreinä): ");
pituus = input.nextDouble();

System.out.println("Ilmoita painosi(kilogrammoissa): ");
paino = input.nextInt();

// painoindeksi

painoindeksi = (paino / (pituus * pituus));

System.out.println(nimi + " , painoindeksisi on " + painoindeksi + ".");

}

}
 
Ok no tuolla pilkulla se onnistuu. Saako tuon tuloksen mitenkään pyöristettyä? Nythän siinä tulee jumalaton litanja numeroa putkeen..eli saisiko esim 24.7 muotoon?
 
Mureakuha:
"Tietojen tulostaminen

System.out luokan avulla konsolissa
[muokkaa]
Formatoitu tulostaminen

Java 5.0 mahdollistaa tulostuksen muotoiluun C:n printf-funktiota muistuttavalla tavalla.

String nimi = "Kalle Kuusisto";
int ika = 55;
System.out.printf("Nimi: %s%nIkä: %d", nimi, ika);

Formatoidussa tekstissä konversiomerkin %s ja %d kertovat tyypin. Sen jälkeen tulee argumentteja muotoilulle. Indeksin voisi määritellä esim. %2$f.2€ Tämä tarkoittaisi sitä, että otetaan toinen argumentti, jonka tyyppi on liukuluku ja kahden desimaalin tarkkuudella ja euron merkki sitten normaalina tekstinä. "
 
Ok. Voisiko joku selittää hyvin tuon sijoittamisen tai laittaa jonkin opettavan esimerkin. Tiedän, se on simppeli asia, mutta jokin siinä on etten saa itselle sitä selväksi. Voisi auttaa kummasti jatkossa tajuta tuo asia hyvin.
 
Ok. Voisiko joku selittää hyvin tuon sijoittamisen tai laittaa jonkin opettavan esimerkin. Tiedän, se on simppeli asia, mutta jokin siinä on etten saa itselle sitä selväksi. Voisi auttaa kummasti jatkossa tajuta tuo asia hyvin.


Sijoittamisen?

Javan tutoriaali selittää mun mielestä tuon lukujen käsittelyn tulostettaessa varsin hyvin.

http://java.sun.com/docs/books/tutorial/java/data/numberformat.html

Sama pätee tosiaan, vaikka olisit tulostamassa lukuja tiedostoonkin. System.out / System.err olion sijaan luot vaan itse uuden java.io.PrintStream -olion ja käytät sitä... Mikäli tuon lukemisen ja pienen kokeilun jälkeen tuo lukujen formatointi on hepreaa, niin kysy. (Muista lukea myös tutoriaalissa linkitettyjen luokkien dokumentaatio Javan API dokumentaatiosta.)

Muutenkin tuo javan tutoriaali auttaa aloittelevaa Java-koodaria todella monessa asiassa. http://java.sun.com/docs/books/tutorial/index.html

Ja sitten, kun peruskonseptit alkavat selvitä, niin javan API-dokumentaatio kattaa todella hyvin kaikki Javan luokat esimerkkeineen.

http://java.sun.com/javase/6/docs/api/

Hankalinta ton APIn käytössä on alkuvaiheessa keksiä oikeat englanninkieliset termit, joilla etsiä luokkia eri asioiden hoitamiseen. Tuohon tuo tutoriaalin lukeminen juuri auttaa...
 
Kokeneempia koodareita tämä huomio ei koske, olette varmasti oman työkalupakkinne ja työtapanne jo valinneet. :)

Tuli sellainen mieleen, että ovathan kaikki aloittelevat koodarit täällä ottaneet käyttöönsä jonkin IDEn (Integrated Development Environment) perinteisen Notepad + komentorivikääntäjän sijaan.

Itse suosin Eclipseä (www.eclipse.org). Sun liputtaa tietenkin oman NetBeansinsa puolesta...

Anyway, hommat helpottuvat kummasti, kun ohjelmointiin käytettävä työkalu sisältää älyä ja kykenee herjaamaan useimmista virheistä ennen ohjelman kääntämistä, täydentää koodia ja tarjoaa näppärän tavan liikkua koodissa tutkimassa mitä mikäkin muuttuja, metodi tai luokka on syönyt. Nuo edut vain käyvät ilmeisemmiksi, mitä isompia ohjelmistoja tulette tulevaisuudessa kirjoittamaan.

Samaan syssyyn suosittelen opettelemaan IDE:n tarjoaman debuggerin käytön. Debuggerin avulla on siis mahdollista kontrolloida ohjelman suoritusta ajon aikana ns. breakpointtien avulla. Ohjelman suoritus pysäytetään sen tullessa ohjelmoijan määrittämän breakpointin kohdalle. Tuolloin on mahdollista tutkia kaikkien ohjelmistossa käytettävien muuttujien ja olioiden tilaa ajonaikaisesti ja seurata ohjelman kulkua metodista toiseen. Löytyy helpommin esim. sen looppi, johon homma jää ikuisesti jumiin...

Säästyy todella paljon aikaa ja vaivaa, kun ei joudu kirjoittelemaan erilaisia debug-tulosteita niin paljon ympäri ohjelmaa ja sitten seuraamaan niiden avulla ohjelman suorituksen etenemistä.

Kannattaa opetella kommentoimaan koodia alusta alkaen ja nimeämään muuttujat & metodit kuvaavasti. On parempi kommentoida ja dokumentoida "liikaa" kuin liian vähän. Tämän huomaa, kun ensimmäisen kerran palaa lukemaan omaa koodiaan puolen vuoden päästä tai kajoaa toisen ihmisen kirjoittamaan koodiin. Suuri osa ohjelmointiin liittyvästä työstä on vanhan koodin muokkausta ja ylläpitoa, ja mikään ei turhauta enempää kuin käyttää tunteja tai päiviä helvetillisen dokumentoimattoman spagettikoodin lukemiseen ja toiminnan selvittämiseen, jotta saat tehtyä sinne yhden pienen muutoksen.

Kommenteissa kannattaa selittää jokaisen metodin alussa, mitä metodin on tarkoitus tehdä, metodin saamat muuttujat, palautusarvo ja poikkeukset. Itse koodissa kannattaa kommenteissa kertoa mitä kunkin muuttujan oletetaan sisältävän ja mihin sitä käytetään. Samoin kannattaa kommentoida, mikäli kikkailee jotain häröä koodissa.

Ja kun sitten joskus muokkaatte koodianne / muiden koodia, niin päivittäkää ne kommentit kanssa. :)


Linkkinä vielä klassikoksi noussut dokumentti siitä kuinka kirjoittaa hankalasti ylläpidettävää koodia:

http://freeworld.thc.org/root/phun/unmaintain.html
 
Sijoittamisen?

Javan tutoriaali selittää mun mielestä tuon lukujen käsittelyn tulostettaessa varsin hyvin.

http://java.sun.com/docs/books/tutorial/java/data/numberformat.html

Sama pätee tosiaan, vaikka olisit tulostamassa lukuja tiedostoonkin. System.out / System.err olion sijaan luot vaan itse uuden java.io.PrintStream -olion ja käytät sitä... Mikäli tuon lukemisen ja pienen kokeilun jälkeen tuo lukujen formatointi on hepreaa, niin kysy. (Muista lukea myös tutoriaalissa linkitettyjen luokkien dokumentaatio Javan API dokumentaatiosta.)

Muutenkin tuo javan tutoriaali auttaa aloittelevaa Java-koodaria todella monessa asiassa. http://java.sun.com/docs/books/tutorial/index.html

Ja sitten, kun peruskonseptit alkavat selvitä, niin javan API-dokumentaatio kattaa todella hyvin kaikki Javan luokat esimerkkeineen.

http://java.sun.com/javase/6/docs/api/

Hankalinta ton APIn käytössä on alkuvaiheessa keksiä oikeat englanninkieliset termit, joilla etsiä luokkia eri asioiden hoitamiseen. Tuohon tuo tutoriaalin lukeminen juuri auttaa...


Ok kiitos noista linkeistä. Koitin lueskella niitä ja kokeillakkin jotain. Silti jäi vielä hieman epäselväksi. Pointti oli löytää apua tämäntyyppisten tehtävien ratkaisuun. Kaikki sanovat että tämä on pirun helppo tehtävä ja tiedän sen itse myös, mutta en saa sitä tehtyä ja sekös nyt hajottaa kun olisi vaikeampia tehtäviä tehtävänä vaikka kuinka paljon. Eli:

Kirjoita ohjelma, joka pyytää käyttäjältä kaksi kokonaislukua. Ohjelma sijoittaa saadut luvut ohjelmaan muuttujiin a ja b. Tämän jälkeen ohjelma vaihtaa muuttujien a ja b arvot siten, että a:han tulee b:ssä ollut arvo ja b:hen a:ssa ollut arvo. (Huom ! Ohjelma ei saa hukata kummankaan muuttujan arvoa!). Lopuksi ohjelma kirjoittaa näytölle muuttujien a ja b muuttuneet arvot.

import java.util.Scanner;
public class Vaihto {
public static void main(String[] args) {
int muuttujaA = 0;
int muuttujaB = 0;
int muuttujaX = 0;

Scanner input = new Scanner(System.in);
System.out.println("Anna luku: ");
muuttujaA = input.nextInt();
System.out.println("Anna toinen luku: ");
muuttujaB = input.nextInt();

Tuossa vaiheessa sitten iskee tämä epävarmuus ja hommat lähtee käsistä.
 
muuttujaX = muuttujaA;
muuttujaA = muuttujaB;
muuttujaB = muuttujaX;

System.out.println( jne );

Älä mieti sitä syntaksia vaan logiikkaa. Kun tiedät miten, niin loppu onkin vaan ns. mekaanista suorittamista.
 
Ok kiitos noista linkeistä. Koitin lueskella niitä ja kokeillakkin jotain. Silti jäi vielä hieman epäselväksi. Pointti oli löytää apua tämäntyyppisten tehtävien ratkaisuun. Kaikki sanovat että tämä on pirun helppo tehtävä ja tiedän sen itse myös, mutta en saa sitä tehtyä ja sekös nyt hajottaa kun olisi vaikeampia tehtäviä tehtävänä vaikka kuinka paljon. Eli:

Kirjoita ohjelma, joka pyytää käyttäjältä kaksi kokonaislukua. Ohjelma sijoittaa saadut luvut ohjelmaan muuttujiin a ja b. Tämän jälkeen ohjelma vaihtaa muuttujien a ja b arvot siten, että a:han tulee b:ssä ollut arvo ja b:hen a:ssa ollut arvo. (Huom ! Ohjelma ei saa hukata kummankaan muuttujan arvoa!). Lopuksi ohjelma kirjoittaa näytölle muuttujien a ja b muuttuneet arvot.

import java.util.Scanner;
public class Vaihto {
public static void main(String[] args) {
int muuttujaA = 0;
int muuttujaB = 0;
int muuttujaX = 0;

Scanner input = new Scanner(System.in);
System.out.println("Anna luku: ");
muuttujaA = input.nextInt();
System.out.println("Anna toinen luku: ");
muuttujaB = input.nextInt();

Tuossa vaiheessa sitten iskee tämä epävarmuus ja hommat lähtee käsistä.

muuttujaX = muuttujaA;
muuttujaA = muuttujaB;
muuttujaB = muuttujaX;
System.out.printf("Muuttuja A:n arvo: %d, Muuttuja B:n arvo: %d",muuttujaA, muuttujaB);

e: Hidas kuin mikä.
 
Pari viestiä sitten pistin linkin mureakuhaan juuri tästä asiasta. Kertauksena:
"Formatoidussa tekstissä konversiomerkin %s ja %d kertovat tyypin. Sen jälkeen tulee argumentteja muotoilulle. Indeksin voisi määritellä esim. %2$f.2€ Tämä tarkoittaisi sitä, että otetaan toinen argumentti, jonka tyyppi on liukuluku ja kahden desimaalin tarkkuudella ja euron merkki sitten normaalina tekstinä.

%[indeksi$][liput][.tarkkuus]konversio

Konversio tunnukset

* d //Kokonaisluku kymmenjärjestelmässä
* f //Liukuluku
* e //Liukuluku kymmenpotenssimuodossa
* n //Rivinvaihto
* x //Kokonaisluku heksaluvuksi
* s //Merkkijono
* c //Unicode-merkki
* % //Prosenttimerkin tulostaminen "
 
Mikä tuo %d merkintä on?:david:

Kiitos!

Väsynyt ja Haukifile kävivätkin jo läpi kuinka kahden muuttujan arvo voidaan vaihtaa keskenään. Yritän tässä vielä antaa lisäselvitystä tuosta lukujen tulostamisesta...


Eli toi System.out.printf -funktio voi saada vaihtelevan määrän parametreja... Tuossa Väsyneen antamassa esimerkissä:


System.out.printf("Muuttuja A:n arvo: %d, Muuttuja B:n arvo: %d",muuttujaA, muuttujaB);

funktiokutsussa on tällä kertaa kolme parametria.

Ensimmäinen parametri on aina tulostettavaksi tarkoitettu merkkijono, eli lainausmerkkien sisällä oleva teksti. Tuohon tekstiin on mahdollista merkitä noilla %d (ja muilla %jotain) merkeillä kohdat, joihin sijoitetaan funktiokutsun muiden parametrien arvot halutulla tavalla muotoiltuna. Tässä tapauksessa eka %d korvataan muuttujaA:n kokonaislukuarvolla ja toinen %d muuttujaB:n kokonaislukuarvolla.


Eli funktion kutsu tulostaa ruudulle sitten esim tekstin: Muuttuja A:n arvo: 96, Muuttuja B:n arvo: 69


Koska System.out on java.io.PrintStream luokan edustaja (eli olio), löytyy tuon System.outin dokumentaatio java.io.PrintStream-luokan dokumentaatiosta. Java API-kertoo tarkemmin ko. metodin toiminnasta kohdassa:

http://java.sun.com/javase/6/docs/api/java/io/PrintStream.html#printf%28java.util.Locale,%20java.lang.String,%20java.lang.Object...%29


Alku aina hankalaa, mut kyllä se siitä.
 
Kiitokset ssi tuosta, selvensi aika paljon.

"The method println(int) in the type PrintStream is not applicable for the arguments (String, int, int)" erroria pukkaa nyt tuohon ohjelmaan.
 
Kiitokset ssi tuosta, selvensi aika paljon.

"The method println(int) in the type PrintStream is not applicable for the arguments (String, int, int)" erroria pukkaa nyt tuohon ohjelmaan.

Kuten dokumentaatio sanoo, ottaa tuo metodi argumentteinaan objecteja. int, float, char, boolean jne. paljaat tietotyypit pitää siis muuttaa ensin oliomuotoisiksi edustajikseen, jotta tuota funktiota voisi käyttää.

Eli int tyyppiä vastaa Integer-luokka eli. Metodin kutsu kuuluisi esim. tyyliin:

System.out.printf("blahblah %d, foobar %d", new Integer(muuttujaA), new Integer(muuttujaB));

Siinä javan tutoriaalissa varmasti selitetään olioiden/luokkien ja paljaiden tietotyyppien ero ihan ensimmäisinä asioina...


Tämä ei kuitenkaan ole kovin järkevä tapa tehdä asioita tuossa tapauksessa, että sulla on jo kokonaislukumuuttujissa noi arvot. Mitään tyypinmuunnoksia tai muotoiluahan ei tarvita. Eli tuo printf-metodin tarjoama mahdollisuus formatoida tulostetta tulee tarpeen silloin, kun haluat esittää tulostettaessa tietoa eri muodossa kuin se sulla on jossakin muuttujassa tallessa.

Voit siis tulostaa tässä tapauksessa tekstin helposti:

System.out.println("Muuttujan A arvo: " + muuttujaA + ", muuttujan B arvo: " + muuttujaB);

Tuossa funktiokutsussa hyödynnetään Javaan sisäänrakennettua ominaisuutta, jonka avulla +-merkeillä voidaan yhdistää (concatenate) useampia merkkijonoja ja paljaiden muuttujien arvoja yhdeksi pötköksi.

Eli luot tuossa yhden merkkijonon "Muuttujan A arvo: 96, muuttujan B arvo: 69".

Toisin kuin printf-funktio, println ei mahdollista syöteen muokkaamista. Myöskään tuo +-operaattorilla tehty yhdistäminen ei mahdollista syötteen muokkaamista. Eli jos sulla on float-tyyppinen muuttuja nimeltään X, jonka arvo on X=9.234232392349823498 ja käytät println-metodia tuon tulostamiseen saat ruudulle nuo kaikki desimaalit. printf:n avulla voit muotoilla tuota niin, että tulostaisit ruudulle vaikka vain "X=9.2".
 
Ok!

Tässä illan viimeiset kysymykset.

Miten saan laskettua bruttopalkasta xx% suuruisen vähennyksen kun vähennys saa kuitenkin olla korkeintaan xxxx euroa?

Toinen:

Ohjelman pitäisi tulostaa tuumia vastaavat senttimetrit 10" välein väliltä 10-100.

Edelleenkin jotain neuvoja vain. Tämän jälkeen pakko ottaa ryyppy ja hakata ps3 pari minuuttia.
 

Latest posts

Suositut

Back
Ylös Bottom