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.

125 lines
3.9 KiB

4 years ago
  1. ## 2 Nelilaskin
  2. **Tehtävä:**
  3. Luvun toisessa tehtävässä tehdään yksinkertainen nelilaskin, mutta tällä kertaa siten, että ohjelma toipuu erilaisista virhesyötteistä.
  4. 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?".
  5. 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."
  6. Toimiessaan oikein ohjelma tulostaa seuraavaa:
  7. Example output:
  8. ```
  9. Anna luku: 60
  10. Anna luku: 3
  11. Arvot luku1 = 60.0 ; luku2 = 3.0
  12. 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta
  13. Valitse toiminto: 1
  14. Tulos on 63.0.
  15. Arvot luku1 = 60.0 ; luku2 = 3.0
  16. 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta
  17. Valitse toiminto: 2
  18. Tulos on 57.0.
  19. Arvot luku1 = 60.0 ; luku2 = 3.0
  20. 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta
  21. Valitse toiminto: 3
  22. Tulos on 180.0.
  23. Arvot luku1 = 60.0 ; luku2 = 3.0
  24. 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta
  25. Valitse toiminto: 4
  26. Tulos on 20.0.
  27. Arvot luku1 = 60.0 ; luku2 = 3.0
  28. 1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta
  29. Valitse toiminto: 6
  30. ```
  31. **Vastaus**
  32. ```
  33. #!/usr/bin/env ruby
  34. # coding: utf-8
  35. def lukuLukija
  36. # Alkuperäisessä implementaatiossa lukujen määrä oli valittavissa
  37. # Tehtävänannossa lukujen määrä on kuitenkin rajattu kahteen,
  38. # joten kovakoodaamme sen.
  39. lukujenMaara = 2
  40. luvut = {}
  41. i = 0
  42. while i < lukujenMaara
  43. print "Anna luku: "
  44. begin
  45. luvut.merge!(Hash["luku" + (i+1).to_s, Integer(gets.chomp).to_f])
  46. i += 1
  47. rescue ArgumentError
  48. # Kirjaimien tulee tehtävänannon mukaan muuntua arvoon 0
  49. luvut.merge!(Hash["luku" + (i+1).to_s, 0.to_f])
  50. i += 1
  51. puts "Virheellinen syöte."
  52. end
  53. end
  54. return luvut
  55. end
  56. def lukuLaskin
  57. luvut = lukuLukija
  58. while true
  59. vastaus = 0
  60. printf("\nArvot %s\n", luvut.map { |avain,arvo| avain + " = " + arvo.to_s }.join(" ; ") )
  61. print "1: + 2: - 3: * 4: / 5: Vaihda luvut 6: Lopeta\nValitse toiminto: "
  62. begin
  63. toiminto = Integer(gets.chomp)
  64. case toiminto
  65. when 1
  66. vastaus = luvut["luku1"] + luvut["luku2"]
  67. when 2
  68. vastaus = luvut["luku1"] - luvut["luku2"]
  69. when 3
  70. vastaus = luvut["luku1"] * luvut["luku2"]
  71. when 4
  72. # Tuottaa Infinity, jos jaetaan 0.0.
  73. # Nollalla jako testataan alhaalla.
  74. vastaus = luvut["luku1"] / luvut["luku2"]
  75. # Vain Integer-tyyppinen muuttuja voi antaa ZeroDivisionError-virheen
  76. # https://ruby-doc.org/core-2.7.0/ZeroDivisionError.html
  77. begin
  78. luvut["luku1"].to_i / luvut["luku2"].to_i
  79. rescue ZeroDivisionError
  80. puts "Taisit yrittää nollalla jakoa?"
  81. next
  82. end
  83. when 5
  84. luvut = lukuLukija()
  85. next
  86. when 6
  87. Process.exit(0)
  88. else
  89. warn "Virheellinen valinta"
  90. return
  91. end
  92. puts "Tulos on #{vastaus}."
  93. rescue ArgumentError
  94. warn "Virheellinen valinta"
  95. end
  96. end
  97. end
  98. lukuLaskin
  99. ```