## 2 Nelilaskin **Tehtävä:** Luvun toisessa tehtävässä tehdään yksinkertainen nelilaskin, mutta tällä kertaa siten, että ohjelma toipuu erilaisista virhesyötteistä. Toteuta ohjelmasi siten, että laskinmessa voi perusnelilaskintoimintojen lisäksi vaihtaa lukuja sekä lopettaa vasta sitten kun näin halutaan tehdä. Tee ohjelmaan luvun pyytämistä varten metodi, joka tarkastaa että käyttäjä oikeasti syötti jonkin liukuluvuksi muuntuvan arvon, eli jotain muuta kuin pelkästään painoi enteriä. Syötettä pyydetään niin kauan että jotain, vaikka kirjaimia jotka tyyppimuuntuu arvoon 0, syötetään. Lisäksi nollalla jaon yrittäminen tulee päättyä virheilnoitukseen "Taisit yrittää nollalla jakoa?". Muuten ohjelma tulostaa aina valintaa pyytäessään "Arvot luku1 = [arvo] ; luku2 = [Arvo}] \n 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta", ja laskutoimitus valittaessa "Tulos on [vastaus].". Jos valinta on virheellinen, tulostetaan "Virheellinen valinta" tai viallisen syötteen yhtyeydessä "Virheellinen syöte." Toimiessaan oikein ohjelma tulostaa seuraavaa: Example output: ``` Anna luku: 60 Anna luku: 3 Arvot luku1 = 60.0 ; luku2 = 3.0 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta Valitse toiminto: 1 Tulos on 63.0. Arvot luku1 = 60.0 ; luku2 = 3.0 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta Valitse toiminto: 2 Tulos on 57.0. Arvot luku1 = 60.0 ; luku2 = 3.0 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta Valitse toiminto: 3 Tulos on 180.0. Arvot luku1 = 60.0 ; luku2 = 3.0 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta Valitse toiminto: 4 Tulos on 20.0. Arvot luku1 = 60.0 ; luku2 = 3.0 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta Valitse toiminto: 6 ``` **Vastaus** ``` #!/usr/bin/env ruby # coding: utf-8 def lukuLukija # Alkuperäisessä implementaatiossa lukujen määrä oli valittavissa # Tehtävänannossa lukujen määrä on kuitenkin rajattu kahteen, # joten kovakoodaamme sen. lukujenMaara = 2 luvut = {} i = 0 while i < lukujenMaara print "Anna luku: " begin luvut.merge!(Hash["luku" + (i+1).to_s, Integer(gets.chomp).to_f]) i += 1 rescue ArgumentError # Kirjaimien tulee tehtävänannon mukaan muuntua arvoon 0 luvut.merge!(Hash["luku" + (i+1).to_s, 0.to_f]) i += 1 puts "Virheellinen syöte." end end return luvut end def lukuLaskin luvut = lukuLukija while true vastaus = 0 printf("\nArvot %s\n", luvut.map { |avain,arvo| avain + " = " + arvo.to_s }.join(" ; ") ) print "1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta\nValitse toiminto: " begin toiminto = Integer(gets.chomp) case toiminto when 1 vastaus = luvut["luku1"] + luvut["luku2"] when 2 vastaus = luvut["luku1"] - luvut["luku2"] when 3 vastaus = luvut["luku1"] * luvut["luku2"] when 4 # Tuottaa Infinity, jos jaetaan 0.0. # Nollalla jako testataan alhaalla. vastaus = luvut["luku1"] / luvut["luku2"] # Vain Integer-tyyppinen muuttuja voi antaa ZeroDivisionError-virheen # https://ruby-doc.org/core-2.7.0/ZeroDivisionError.html begin luvut["luku1"].to_i / luvut["luku2"].to_i rescue ZeroDivisionError puts "Taisit yrittää nollalla jakoa?" next end when 5 luvut = lukuLukija() next when 6 Process.exit(0) else warn "Virheellinen valinta" return end puts "Tulos on #{vastaus}." rescue ArgumentError warn "Virheellinen valinta" end end end lukuLaskin ```