Tehtävä:
Luvun kolemannessa tehtävässä tehdään jälleen yleishyödyllisiä toimintoja, ja luodaan vähästä harmistuvia varten työkalu, jolla on helppo poistaa vaarallisia ajatuksia ja sanoja tekstistä. Toisin sanoen, teemme sensurointityökalun, jolla tuhma teksti voidaan muuttaa näppärästi ketään loukkaamattomaan muotoon.
Rakenteellisesti ohjelma on varsin yksinkertainen. Tiedostoon "6-3a_tiedosto.txt" on tallennettu sanoja tai merkkiyhdistelmiä yksi per rivi. Tiedostossa "6-3c_tiedosto.txt" on teksti, joka saattaa sisältää näitä sensuroitaviksi haluttavia sanoja tai kirjainyhdistelmiä. A-tiedoston sanat ja merkkiyhdistelmät siis luetaan taulukkoon, ja C-tiedoston tekstistä poistetaan kaikki A-taulukossa olevat sanat ja kirjainyhdistelmät, korvaten ne viidellä tähti (*****)-merkillä.
Kun vaihto on tehty, tulostetaan ruudulle teksti "Tallennetaan siistitty versio...", ja kirjoitetaan siistitty teksti tiedostoon "6-3b_tiedosto.txt". Lopuksi vielä tulostetaan ruudulle teksti "Valmis! Lopetetaan."
Toimiessaan oikein ohjelma tulostaa seuraavaa:
Example output:
Tallennetaan siistitty versio...
Valmis! Lopetetaan.
Vastaus
#!/usr/bin/env ruby
# coding: utf-8
sensuurisanatTiedosto = "6-3a_tiedosto.txt"
tekstiTiedosto = "6-3c_tiedosto.txt"
kohdeTiedosto = "6-3b_tiedosto.txt"
$_sensuurimerkki = "*"
$_sensuurimerkkiMaara = 5
def luoTiedosto(tiedosto)
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
end
def kirjoita(tiedostohash)
tiedostohash.each { |tiedosto, sanat|
luoTiedosto(tiedosto)
File.open(tiedosto, "w+:UTF-8") do |f|
f.flock(File::LOCK_EX)
sanat.each { |word| f.puts word }
end
}
end
kirjoita(
{
tekstiTiedosto => ["Monesti kuitenkin käy niin, että lataan jonkin moduulin tai koitan selvitellä mistä vitusta oikein on keksinyt vaatia kaiken mahdollisen tupleina, tai vaihtoehtoisesti haluaisin käyttää jotain umpimielistä paskaa tekemään monimutkaisia asioita. Älä keksi pyörää uudestaan” on mielestäni ihan hyvä periaate; ikävä kyllä alkuperäisen keksijä jättää monesti kertomatta mihin tätä uutta hienoa pyörää voisi käyttää. Helpot tapaukset on niitä, joissa API on kuvattu skriptillä pureskeltuna generoituna tekstinä, joka ei aukea oikeastaan sen enempää kuin itse lähdesontakaan. Kehittäjille ehkä hyödyllinen, käyttäjille vihamielinen. Pahimmillaan olen nähnyt tilanteita, missä kaksi, jopa kolme, idioottia ovat keskenään ristiriitaisia ja neuvovat tekemään asiat eri tavoin, tai painottavat täysin eri asioita. Lopulta usein tuleekin paskaa, että on kokoamassa pelkkiin faktoihin perustuvaa kuvausta urheilukilpailusta haastattelemalla ulos heitettyjä humaltuneita katsojia, tai olevansa loukussa ”yksi valehtelee aina, yksi joskus ja loput puhuu totta”-tyyppisessä logiikkatestissä.","", "Mutta joo. Jo ohjelmistotekniikan peruskurssilla opetetaan, että ainoa asia joka on huonompi kuin puutteellinen ohjelmointi on virheellinen ohjelmointi, ja että kaikista viisain eläin on majava joka sukeltaa sateelta suojaan. Dokumentaatio ja käyttöohjeet voivat monesti vaikuttaa turhalta perseeltä, mutta ne eivät olekkaan tarkoitettu devaajille itselleen, vaan niille jotka käyttävät heidän tekemiään työkaluja. Ja vaikka ajatus vahingon kiertämään laittamisesta voikin houkuttaa, olisi siinä tapauksessa harkitsemisen arvoista ennemmin ryhtyä vaikka autokauppiaaksi.",""],
sensuurisanatTiedosto => ["moduuli", "vitu", "paskaa", "sonta", "idiootti", "ohjelm", "perse"]
}
)
########################################
def muodostaLista(tiedosto)
sanalista = []
if (File.readable?(tiedosto))
File.foreach(tiedosto) do |line|
sanalista.insert(0, line.chomp)
end
end
return sanalista
end
def sensuroiSanat(tekstiTiedosto, sanaTiedosto)
korvaavaSana = ""
i = 0
while i < $_sensuurimerkkiMaara
korvaavaSana += $_sensuurimerkki
i += 1
end
sensuuriLista = muodostaLista(sanaTiedosto)
korvaavatRivit = []
if (File.readable?(tekstiTiedosto))
File.foreach(tekstiTiedosto) do |line|
#rivinUudetSanat = []
uusiRivi = []
#for sana in line.split(" ")
# TODO Add upper/lowercase support
for sensuuriSana in sensuuriLista
line = line.gsub(sensuuriSana, korvaavaSana)
end
uusiRivi.insert(-1, line)
korvaavatRivit.insert(-1, uusiRivi)
end
end
return korvaavatRivit
end
def kirjoitaTiedostoon(tiedosto, lista)
File.open(tiedosto, "w+:UTF-8") do |f|
puts "Tallennetaan siistitty versio..."
f.flock(File::LOCK_EX)
#lista.each { |rivi| f.print rivi }
f.puts lista
end
puts "Valmis! Lopetetaan."
end
kirjoitaTiedostoon(kohdeTiedosto, sensuroiSanat(tekstiTiedosto, sensuurisanatTiedosto))