Tässä projektissa ei oo paljo järkeä, mutta oli hauska yrittää ohjelmoida RED ohjelmointikielellä! :) Harjoituksen kannalta.
Ohjelmointiputkan Yleinen keskustelu osiossa on huimat 423 sivua vuodesta 2002 lähtien.
Tarkoitus olisi ollut käydä ne kaikki läpi ja tilastoida sanojen esiintymisiä.
EDIT: Sori, en huomioinnut, että mulla on turhan pitkiä kommenttirivejä koodissa. Täytyy jatkossa kirjoittaa lyhkäsempiä. Nyt niitä on vaikea lukea.
red[]
substr: func [string start length][ ;aliohjelma alimerkkijonon tuottamiseen
copy/part at string start length
]
numlen: func [value lengthi][;laittaa etunollia siis luvusta 5 tulee esimerkiksi 00005. Tarvitaan sorttaukseen suuruusjärjestykseen.
valstr: to-string value
vallen: length? valstr
apu: rejoin ["0000000" valstr]
kohta: 7 + vallen - lengthi + 1
apu: substr apu kohta lengthi
return apu
]
lmrk: to-char 34 ;lainausmerkki
hipsu: to-char 94
erotasanat: func[merkkijono][ ;aliohjelma erottaa blankolla erotetut sanat viestistä tai otsikosta
;poistetaan viestistä tai otsikosta joitakin tilpehöörimerkkejä
merkkijono: uppercase merkkijono
merkkijono: replace/all merkkijono "<p>" ""
merkkijono: replace/all merkkijono "</p>" ""
merkkijono: replace/all merkkijono "<br />" ""
merkkijono: replace/all merkkijono ">" ""
merkkijono: replace/all merkkijono "?" ""
merkkijono: replace/all merkkijono "." ""
merkkijono: replace/all merkkijono "," ""
merkkijono: replace/all merkkijono ">" ""
merkkijono: replace/all merkkijono ")" ""
merkkijono: replace/all merkkijono "(" ""
merkkijono: replace/all merkkijono "-" ""
merkkijono: replace/all merkkijono "!" ""
merkkijono: replace/all merkkijono ":" ""
merkkijono: replace/all merkkijono ";" ""
merkkijono: replace/all merkkijono "/" ""
merkkijono: replace/all merkkijono "#" ""
merkkijono: replace/all merkkijono "=" ""
merkkijono: replace/all merkkijono hipsu ""
merkkijono: replace/all merkkijono """ ""
merkkijono: replace/all merkkijono """ ""
merkkijono: replace/all merkkijono "'" ""
merkkijono: replace/all merkkijono "-" ""
merkkijono: replace/all merkkijono ";<BR" ""
merkkijono: replace/all merkkijono "<BR" ""
merkkijono: replace/all merkkijono "^/^-^-^-^-^-^-^-" ""
merkkijono: replace/all merkkijono "^/^-^-" ""
merkkijono: replace/all merkkijono "^/" ""
merkkijono: replace/all merkkijono ";^/" ""
merkkijono: replace/all merkkijono "&39" ""
merkkijono: replace/all merkkijono "<SPAN>" ""
sanoja: split merkkijono " "
if sanoja <> "" [
append sanat sanoja
]
]
sanat: copy[] ;taulukko blockki kaikille löytyneille sanoille
etsi1: "<tr class=" ;HTML-koodi elementti, mika edeltaa keskustelun otsikkoa
etsi2: "<a href=" ;HTML elementti mika aloittaa osoitteen
etsi3: ">" ;HTML elementti mika lopettaa osoitteen
etsi4: "</a>" ;elementti mikä lopettaa otsikon
etsi5: rejoin ["<div id=" lmrk "viesti-"] ;elementti mikä aloittaa viestin
etsi6: "</div>" ;elementti mikä lopettaa viestin. Tässäkin taitaa olla virhe, koska koodi tägikin loppuu tähän! ÄH! :(
sivunumero: 453
aika1: now/precise
loop 7 [ ;tutkitaan ohjelman hitauden ja kaatumisen (kooditägit) takia vain seitsemää vikaa sivua, eikä kaikkia 423. Kymmenenkin kesti liian kauan! :(
osoite: rejoin ["https://www.ohjelmointiputka.net/keskustelu/alue-6-yleinen-keskustelu/sivu-" sivunumero]
print osoite
tiedosto: read to-url rejoin ["https://www.ohjelmointiputka.net/keskustelu/alue-6-yleinen-keskustelu/sivu-" sivunumero]
sivunumero: sivunumero - 1
while [tiedosto: find tiedosto etsi1][ ;selataan sivua niin kauan kuin siitä loytyy otsikoita
indeksi1: index? tiedosto ;sen merkin indeksi, mista etsi1 loytyi
loop (length? etsi1) [tiedosto: next tiedosto] ; selataan osoitteen alkuun
indeksi1: index? tiedosto ;sen merkin indeksi, mista osoite alkaa
tiedosto: find tiedosto etsi2 ;etsitaan varsinaisen osoite, mista mennaan sitten alasivulle eli varsinaiseen keskusteluun
indeksi2: index? tiedosto
tiedosto: find tiedosto etsi3
indeksi3: index? tiedosto
osoite1: substr tiedosto -6 (indeksi2 - indeksi3 + 15)
;otetaan talteen myöskin otsikko
indeksi4: index? tiedosto
tiedosto: find tiedosto etsi4
indeksi5: index? tiedosto
otsikko: substr tiedosto 1 (indeksi4 - indeksi5 + 1)
erotasanat otsikko
;mennaan lukemaan alasivu eli varsinainen keskustelusivu
tiedosto2: read to-url rejoin ["https://www.ohjelmointiputka.net" osoite1]
while [tiedosto2: find tiedosto2 etsi5][ ;selataan sivua niinkauan kuin siitä loytyy viesteja
tiedosto2: find tiedosto2 "<p>" ;varsinainen viesti alkaa paragraphilla
indeksi6: index? tiedosto2
tiedosto2: find tiedosto2 etsi6
indeksi7: index? tiedosto2
viesti: substr tiedosto2 -3 (indeksi6 - indeksi7 - 5)
;tutkitaan onko viestissä nettilinkkejä - otetaan ne pois
apuri: viesti
while [apuri: find apuri "<a href="][
indeksi8: index? apuri
apuri: find apuri "</a>"
indeksi9: index? apuri
linkki: substr apuri 5 (indeksi8 - indeksi9 - 4)
viesti: replace/all viesti linkki ""
apuri: next apuri
]
;otetaan pois myös koodivinkit. Nyt kiinnostavat vai keskustelujen sanat
;TÄMÄ EI NYT VIELÄ TOIMIKAAN, JOTEN MUUTIN KOMMENTIKSI JA POISTIN! :(
;apuri: viesti
;while [apuri: find apuri "<div class='koodi"][
;
; indeksi8: index? apuri
; ;print indeksi8
; apuri: find apuri "</pre>"
; ;print "taalla ollaan"
; ;print apuri
; either apuri = none [
; indeksi9: indeksi8 + 10
; ][
; indeksi9: index? apuri
; ]
; ;indeksi9: index? apuri
; ;print indeksi9
; either apuri = none [
; koodi: none
; ][
; koodi: substr apuri 1 (indeksi8 - indeksi9)
; ]
; ;print koodi
; viesti: replace/all viesti koodi ""
;]
erotasanat viesti
]
]
]
;lasketaan sanojen esiintymät tosi tehottomalla tavalla, kahdessa silmukassa :( Tää taitaa olla ohjelmani pullonkaula? :(
tilastotaulukko: copy[] ;tilastotaulkko on RED-kielen ns. blockki (taulukko, lista), missä alkioina ovat lukumäärä ja sana
ind1: 1
loop length? sanat [
sana: sanat/(ind1)
ind2: 1
lukumaara: 0
loop length? sanat [
if sana = sanat/(ind2) [lukumaara: lukumaara + 1]
ind2: ind2 + 1
]
append/only tilastotaulukko to-block compose [(lukumaara) (sana)]
ind1: ind1 + 1
]
tilastotaulukko2: copy[] ;tilastotaulokkoon tulee sanasta monta esiintymää laitetaan tähän taulukkoon vain yksi
ind: 1
loop length? tilastotaulukko [
if ((tilastotaulukko/(ind)/1) >= 3) [ ;tulostetaan vain sanat, joita esiintyy vähintää kolme kertaa
tietue: rejoin [numlen tilastotaulukko/(ind)/1 6 " " tilastotaulukko/(ind)/2]
append tilastotaulukko2 tietue
]
ind: ind + 1
]
tilastotaulukko2: unique tilastotaulukko2 ;poistetaan monikerrat siis
sort/reverse tilastotaulukko2
ind: 1
loop length? tilastotaulukko2 [
print tilastotaulukko2/(ind)
ind: ind + 1
]
aika2: now/precise
print ["Aikaa kului aika paljon! " difference aika2 aika1]
haltKoodi kyllä jotenkuten (kai?) alustavasti toimii jo, mutta on melko hiidas ja viesteissä olevat kooditägit tuottavat pahoja ongelmia ja taitavat jopa kaataa ohjelman virheilmoitukseen:
*** Runtime Error 1: access violation
*** at: 5BFF28DBh
Tai jokin muu vastaavanlainen heksa luku. Mitähän tuokin sitten tarkoittaa? Kaatuuko ohjelma sivujen lataukseen serveriltä vaiko "koneen takia" (viittaisiko tuo muistipaikkaan?)
Pystyin nyt latamaan ja tutkimaan koodin kaatumisen takia vain seitsemää vikaa sivua. Kymmentä yritin, mutta ohjelma kaatui, ilmeisesti koska keskusteluissa oli kooditägejä.
Muutamat ekat tulokset:
LUKUMÄÄRÄ SANA ========= ==== 000294 ON 000196 EI 000098 SE 000098 JA 000070 JOO 000063 TOIMI 000063 MUTTA 000063 KUN 000056 OLE 000056 NYT 000049 VARMAAN 000049 MITÄ 000049 KYLLÄ 000049 IHAN 000049 EN 000042 JO 000042 ADMIN 000035 VÄHÄN 000035 VAPAALLAORG 000035 TULI 000035 TAI 000035 SITTEN ...JNE...
Sivujen lataukseen ei mennyt kauaa ja sitten seitsemän sivun käsittelyyn 57 sekuntia. Ottaisin ilolla vastaan pseudokielisiä kehitysideoita, jos saisitte jotain selkoa sotkuisesta koodistani ja te taitavammat haluaisitte auttaa. Ohjelmointikielien syntaksia olen valitettavasti itse huono ymärtämään. Siis mieluummin pseudokielellä tai ihan suomeksi.
Keksin jo tätä kirjoittaessa kehitysidean:
On ehkä typerää käydä viesteistä löytyneiden sanojen listaa läpi kahdessa sisäkkäisessä silmukassa (enkä ole edes 100% varma vielä, että ohjelma tuottaa oikean tuloksen - voisiko tosiaan seitsemän viimeisen sivun viesteissä olla 294 kpl "ON" sanaa?) Ensin pitäisi lukea sanat taulukkoon, kopioida se ja poistaa toisesta duplikaatit ja sitten käydä sitä taulukkoa läpi, mistä dublikaatteja ei olla poistettu ja ynnätä siihen pienempään taulukkoon lukumääriä. Tällöin jos sanoja olisi viesteissä yhteensä n2 kpl ja sanoja dublikaattien poiston jälkeen n1, niin käsittääkseni käsittelyaika olisi verrannollinen about n2:een, kun nyt se on verrannollinen n2 * n2. Tietysti tosin dublikaattien poistokin kestää, mutta siihen löytyisi oma tehokas ohjelmointikielen käsky. Minun ohjelmointitaidoilla ehkä helpommin sanottu kuin tehty muutos näin äkkiseltään. Tärkeintä olisi nyt löytää keino, millä kooditägit eivät kaada ohjelmaa.
Kannattanee muuten tutustua RED-kieleen...? https://www.red-lang.org/p/about.html Se on REBOL:sta kehitetty, noudattaa paljolti REBOL:n syntaksia, mutta paaaljon tehokkaampi.
PS: Vahingossa, sori, valitsin kieleksi Javascriptin, vaikka tämä käsittelee RED-ohjelmointia, kun muistin, että koodin väritys oltaisiin valittu aihepiiristä ja sitä ei pysty näköjään valinnan jälkeen poistamaan. RED-kielikin toimii melkein kaikilla alustoilla eikä vain Windowssissa.
PetriKeckman kirjoitti:
Ohjelmointiputkan Yleinen keskustelu osiossa on huimat 423 sivua vuodesta 2002 lähtien.
Tarkoitus olisi ollut käydä ne kaikki läpi ja tilastoida sanojen esiintymisiä.
Älä viitsi kuitenkaan turhaan latailla satoja ja tuhansia sivuja. Saatat joutua estolistalle, jos näyttää, että kuormitat sivustoa pahantahtoisesti.
Petri Keckman kirjoitti:
PS: Vahingossa, sori, valitsin kieleksi Javascriptin, vaikka tämä käsittelee RED-ohjelmointia, kun muistin, että koodin väritys oltaisiin valittu aihepiiristä
Eihän tässä ole mitään logiikkaa. Kun kieli ei ole JavaScript, tietenkään ei kuulu käyttää myöskään JavaScript-väritystä siihen. Voit kirjoittaa kooditagiin JS:n tilalle itse oikean kielen nimen.
Metabolix kirjoitti:
Älä viitsi kuitenkaan turhaan latailla satoja ja tuhansia sivuja.
Ohjelmaa kehittäessäni latasin tietenkin vain yhtä sivua.
Metabolix kirjoitti:
Eihän tässä ole mitään logiikkaa. Kun kieli ei ole JavaScript, tietenkään ei kuulu käyttää myöskään JavaScript-väritystä siihen. Voit kirjoittaa kooditagiin JS:n tilalle itse oikean kielen nimen.
Sori. En näin uutena tajunut tuota. Halusin jonkin värityksen. Luulin, että jos ei valitse kieltä ollenkaan, niin ei tule mitään väritystä.
EDIT: Poistin nyt "JS" tägin ja tuli kokonaan mustavalkoinen - ei kiva mielestäni :( EDIT2: Äh, ei tullukaan! :) Sori sähläys!
PetriKeckman kirjoitti:
Halusin jonkin värityksen.
Ei se JS-väritys kovin hyvältä näytä, kun tällä on todella vähän yhteistä JavaScriptin kanssa. Ei tarvitse jättää kieltä kokonaan pois: Kuten jo sanoin, voit laittaa itse tagiin oikean kielen (kuten nyt RED). Silloin paremman puutteessa tulee yleispätevä väritysyritys, ja jos joskus tehdään kielelle oikea väritys, vanhatkin koodit värittyvät sitten sen mukaan. Ilman mitään kielivalintaa tulee tosiaan väritöntä tekstiä, ja tämä sopii esimerkiksi tekstimuotoisten tulosteiden esittelyyn.
Metabolix kirjoitti:
Kuten jo sanoin, voit laittaa itse tagiin oikean kielen (kuten nyt RED)
Kuten jo sanoin, niin en ekaksi tajunnut tuota :) Kannattaiskohan tuosta mainita muille minun kaltaisille aloittelijoille ja hölmöille, jossain ohjeissa? Nyt tulee vaikutelma, että listasta on valittava jokin :)
EDIT: Siellähän se ohjeissa sanotaankin jo! Hyvä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.