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.

101 lines
2.9 KiB

4 years ago
  1. ## 3 Kirjainlaskuri
  2. **Tehtävä:**
  3. Tiedostojenkäsittelyn kolmas tehtävä keskittyy tiedoston sisällön tutkimiseen. Ohjelmaa varten on luotu tiedosto "5-3_tiedosto.txt", johon on tallennettu pätkä tekstiä. Tee ohjelma, joka laskee kuinka monta merkkiä pitkä tämä teksti on, ja kuinka monta pientä 'a'- ja 'f'-kirjainta tekstistä löytyy.
  4. Tulos ilmoitetaan muodossa "[pituus] merkkiä: [määrä] a:ta, [määrä] f:ää.". Lopuksi tämä sama tulos kirjoitetaan tiedoston loppuun uudelle riville.
  5. Toimiessaan oikein ohjelma tulostaa seuraavaa ja kirjoittaa saman tekstin tiedostoon "5-3_tiedosto.txt" tiedoston loppuun uudelle riville:
  6. Example output:
  7. ```
  8. 987 merkkiä: 57 a:ta, 7 f:ää.
  9. ```
  10. **Vastaus**
  11. ```
  12. #!/usr/bin/env ruby
  13. # coding: utf-8
  14. tiedosto = "5-3_tiedosto.txt"
  15. if (!File.exists?(tiedosto))
  16. begin
  17. File.open(tiedosto, File::RDWR|File::CREAT, 0644)
  18. rescue
  19. puts "Tiedostoon #{tiedosto} ei voida kirjoittaa"
  20. Process.exit(1)
  21. end
  22. end
  23. def kirjoita(tiedosto, *sanat)
  24. File.open(tiedosto, "w+:UTF-8") do |f|
  25. f.flock(File::LOCK_EX)
  26. sanat.each { |word| f.puts word }
  27. end
  28. end
  29. def kirjainLaskuri(tiedosto, naytaMaara=true, kirjoitaMaara=false, *kirjaimet)
  30. # Oheinen menetelmä antaa *rivikohtaista* tietoa merkkien esiintyvyydestä
  31. # Tietoa voitaisiin käyttää hyödyksi tiedoston sisällön analytiikassa
  32. # (esim. kirjaimien keskm. esiintyvyys tiedoston eri riveillä)
  33. countAll = 0
  34. fileCounts = []
  35. summaryCounts = {}
  36. File.foreach(tiedosto) do |line|
  37. lineCounts = {}
  38. # Laske jokaisen merkin esiintyvyys rivikohtaisesti,
  39. # säilytä tieto avain-arvo -parina lineCounts-muuttujaan
  40. for kirjain in kirjaimet
  41. lineCounts.merge!(Hash[kirjain[0], line.count(kirjain[0])])
  42. end
  43. # Talleta rivikohtainen merkkimäärä
  44. countAll += line.chomp.length
  45. # Talleta jokaisen merkin esiintyvyys rivikohtaisesti,
  46. # muuttujaan fileCounts
  47. fileCounts.insert(0,lineCounts)
  48. end
  49. # Tuota yhteenveto merkkien esiintyvyydestä tiedostossa
  50. for kirjain in kirjaimet
  51. if not kirjain[0] =~ /^[a-zA-Z]{1}$/
  52. warn "Virheellinen merkki #{kirjain[0]}\nOhitetaan..."
  53. next
  54. end
  55. charCount = 0
  56. for i in fileCounts
  57. charCount += i.values_at(kirjain[0]).join("").to_i
  58. end
  59. summaryCounts.merge!(Hash[(kirjain[0] + ":" + kirjain[1]).to_s, charCount])
  60. end
  61. kirjainLause = summaryCounts.map { |key, value| "#{value} #{key}" }.join(", ")
  62. kokoLause = "#{countAll} merkkiä: #{kirjainLause}.\n"
  63. if naytaMaara
  64. print kokoLause
  65. end
  66. if kirjoitaMaara
  67. File.open(tiedosto, "a:UTF-8").write(kokoLause)
  68. end
  69. end
  70. kirjoita(tiedosto, "hela fafifa muutti", "pikkukakkonen titityy", "nurisija nurisi nurkassa")
  71. kirjainLaskuri(tiedosto, true, true, ["a", "ta"], ["f", "ää"])
  72. ```