Ruby fundamentals through coding exercises
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

3.9 KiB

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