## 3 Kirjainlaskuri **Tehtävä:** 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. Tulos ilmoitetaan muodossa "[pituus] merkkiä: [määrä] a:ta, [määrä] f:ää.". Lopuksi tämä sama tulos kirjoitetaan tiedoston loppuun uudelle riville. Toimiessaan oikein ohjelma tulostaa seuraavaa ja kirjoittaa saman tekstin tiedostoon "5-3_tiedosto.txt" tiedoston loppuun uudelle riville: Example output: ``` 987 merkkiä: 57 a:ta, 7 f:ää. ``` **Vastaus** ``` #!/usr/bin/env ruby # coding: utf-8 tiedosto = "5-3_tiedosto.txt" if (!File.exists?(tiedosto)) begin File.open(tiedosto, File::RDWR|File::CREAT, 0644) rescue puts "Tiedostoon #{tiedosto} ei voida kirjoittaa" Process.exit(1) end end def kirjoita(tiedosto, *sanat) File.open(tiedosto, "w+:UTF-8") do |f| f.flock(File::LOCK_EX) sanat.each { |word| f.puts word } end end def kirjainLaskuri(tiedosto, naytaMaara=true, kirjoitaMaara=false, *kirjaimet) # Oheinen menetelmä antaa *rivikohtaista* tietoa merkkien esiintyvyydestä # Tietoa voitaisiin käyttää hyödyksi tiedoston sisällön analytiikassa # (esim. kirjaimien keskm. esiintyvyys tiedoston eri riveillä) countAll = 0 fileCounts = [] summaryCounts = {} File.foreach(tiedosto) do |line| lineCounts = {} # Laske jokaisen merkin esiintyvyys rivikohtaisesti, # säilytä tieto avain-arvo -parina lineCounts-muuttujaan for kirjain in kirjaimet lineCounts.merge!(Hash[kirjain[0], line.count(kirjain[0])]) end # Talleta rivikohtainen merkkimäärä countAll += line.chomp.length # Talleta jokaisen merkin esiintyvyys rivikohtaisesti, # muuttujaan fileCounts fileCounts.insert(0,lineCounts) end # Tuota yhteenveto merkkien esiintyvyydestä tiedostossa for kirjain in kirjaimet if not kirjain[0] =~ /^[a-zA-Z]{1}$/ warn "Virheellinen merkki #{kirjain[0]}\nOhitetaan..." next end charCount = 0 for i in fileCounts charCount += i.values_at(kirjain[0]).join("").to_i end summaryCounts.merge!(Hash[(kirjain[0] + ":" + kirjain[1]).to_s, charCount]) end kirjainLause = summaryCounts.map { |key, value| "#{value} #{key}" }.join(", ") kokoLause = "#{countAll} merkkiä: #{kirjainLause}.\n" if naytaMaara print kokoLause end if kirjoitaMaara File.open(tiedosto, "a:UTF-8").write(kokoLause) end end kirjoita(tiedosto, "hela fafifa muutti", "pikkukakkonen titityy", "nurisija nurisi nurkassa") kirjainLaskuri(tiedosto, true, true, ["a", "ta"], ["f", "ää"]) ```