Re: Pieni kesäpähkinä survoilijoille!

[vastaus aiempaan viestiin]

Kirjoittaja: Kimmo Vehkalahti
Sähköposti:    -
Päiväys: 28.6.2004 15:29

Jalkapallon EM-kisojen yllätykselliset välieräparit ovat selvillä.
On korkea aika esittää oma ehdotukseni "kesäpähkinän" ratkaisuksi. :)

Kuten mainitsin, olen tehnyt sukrosta version, joka dokumentoi koko
touhun yksityiskohtaisesti. Sitä ennen esitän kuitenkin lyhyen version
ilman koodiin sisältyviä kommentteja (tämä auennee sukrontekijöille,
mutta voi muille näyttää hieman kryptiseltä):

*TUTSAVE MONTAKO
*{init}{line start}{erase}{erase}
*REPLACE ".msg" "" C{act}{home}{erase}
+ A: {R}{r}{save word W1}{l}
- if W1 '=' {sp} then goto Loppu
*{ref set 1}{jump END+2,END+2,1}+!{ref jump 1}
+ V: {d}{u}{ins line}
*REPLACE -{print W1} -{print W1}+ C{act}
*{home}{del line}
*{search}+{R}{r}{save char W1}{home}
- if W1 '=' ! then goto M
*{r}{save word W1}{l}{goto V}
+ M: {erase}{ref jump 1}{d}{u}{ins line}
*{del stack}REPLACE + + N{act}
*{home}LINEDEL CUR END "+"{act}
*{u}{line end} {print W1}{goto A}
+ Loppu: {end}

Tästä nähdään jo yhdellä silmäyksellä, että homma perustuu pariin
osittain sisäkkäiseen silmukkaan sekä REPLACE-komennon ahkeraan
käyttöön. Ensimmäinen REPLACE on kosmetiikkaa, toinen tekee työt
ja kolmannen voisi yhtä hyvin korvata silmukalla, joka hoitelisi
samalla LINEDELin työt (merkittyjen rivien laskenta ja poisto).

En selitä enempää, sillä kommentoitu versio selostaa yksityiskohdat:

*TUTSAVE MONTAKO
/ +--------------------------------------------------+
/ | "Montako vastausta kuhunkin aloitusviestiin on?" |
/ | KV:n ehdotus kesäpähkinän (2.6.2004) ratkaisuksi |
/ +--------------------------------------------------+
/
/ Oletetaan että käytössä on tyhjä toimituskenttä, tai ainakaan listan
/ jäljessä ei ole mitään muuta; ts. lista päättyy riviin END. Siirrytään
/ komentorivin alkuun ja putsataan se; sitä ennen tavanomainen {init}:
/
*{init}{line start}{erase}{erase}
/
/ Raivataan tässä tehtävässä turhat roinat (".msg") pois tieltä:
/
*REPLACE ".msg" "" C{act}{home}{erase}
/
/ Tällöin seuraavalta riviltä alkava lista näyttää tällaiselta:
/
/  000001 / 000001-000000
/  000002 / 000002-000000
/  000003 / 000003-000002
/  000004 / 000004-000000
/  000005 / 000005-000003
/  000006 / 000006-000005
/  ...
/
/ ----------------------------------------------------------------------
/
/ A niin kuin Asiaan tai niin kuin Aloitusviesti.
/ Siirrytään seuraavan rivin alkuun, askel oikealle, talletetaan sana
/ sukromuistipaikkaan nro 1 ja otetaan askel takaisin vasemmalle:
/
+ A: {R}{r}{save word W1}{l}
/
/ Jos sanan talletus lyö tyhjää, on tultu koko listan loppuun:
/
- if W1 '=' {sp} then goto Loppu
/
/ Aloitusviestejä on jäljellä: sukromuistiin tarttui nimen alkuosa.
/ Esimerkiksi, kun rivinä on
/  000011 / 000011-000000
/ niin sukromuistin ensimmäiseen paikkaan (W1) on saatu "000011".
/
/ Käydään laittamassa kentän loppuun loppumerkki "+!", jonka avulla
/ vastausten haku saadaan pyörimään vaivatta. Pannaan sitä ennen
/ kursorin paikka muistiin niin päästään helposti takaisin - sekä
/ samantien että myös hieman myöhemmin:
/
*{ref set 1}{jump END+2,END+2,1}+!{ref jump 1}
/
/ V niin kuin Vastaukset. Tehdään rivin verran tilaa ja merkataan
/ kaikki vastaukset käsiteltävänä olevaan viestiin '+'-merkillä
/ ("rutiini-idiomi" {d}{u} varmistaa {ins line}:n toiminnan myös
/ näkyvän ikkunan alimmalla rivillä):
/
+ V: {d}{u}{ins line}
*REPLACE -{print W1} -{print W1}+ C{act}
/
/ Edellä mainitussa esimerkkitapauksessa vastauksia on yksi (joitain
/ rivejä alempana):
/  000015 / 000015-000011
/ Se saa REPLACE:n toimesta peräänsä plussan:
/  000015 / 000015-000011+
/ Poistetaan edellä tehty rivi (siirrytään sitä ennen sen alkuun):
/
*{home}{del line}
/
/ Haetaan seuraavaa '+'-merkkiä. Aiemmin asetettu loppumerkki "+!"
/ takaa, että sellainen löytyy, vaikkei viestiin olisikaan ollut
/ yhtään vastausta. Talletetaan '+':n vieressä oleva tarkistusmerkki
/ ja siirrytään jo ennakoivasti rivin alkuun:
/
*{search}+{R}{r}{save char W1}{home}
/
/ Jos tarkistusmerkki on '!', on löydetty loppumerkki, jolloin voidaan
/ samantien lopettaa enempien '+'-merkkien haku ja siirtyä eteenpäin:
/
- if W1 '=' ! then goto M
/
/ Mikäli if-lause ohittuu, oli tarkistusmerkki jokin muu kuin '!',
/ joten uusi vastaus löytyi. Talletetaan sen nimi (rivin alkuunhan
/ siirryttiin jo edellä) ja aletaan katsoa onko siihen vastauksia:
/
*{r}{save word W1}{l}{goto V}
/
/ (Edellä mainitussa esimerkkitapauksessa tallentuu siis "000015", johon
/ on puolestaan kaksi vastausta. Ne löytyvät seuraavalla kierroksella,
/ johon tästä siirrytään aina niin kauan kunnes vastauksia ei enää ole.
/ Tällöin löydetään loppumerkki "+!" ja tullaan alla olevaan kohtaan M.)
/
/ ----------------------------------------------------------------------
/
/ M niin kuin Montako vastausta yhteensä löytyi. Poistetaan loppumerkki
/ (rivin alkuunhan siirryttiin jo edellä), ja jatketaan siirtymällä
/ käsiteltävänä olevan aloitusviestin kohdalle (paikka tallessa):
/
+ M: {erase}{ref jump 1}
/
/ Tehdään rivin verran tilaa ja lasketaan '+'-merkkien lukumäärä, ts.
/ kysytty vastausten kokonaismäärä. REPLACE (N-parametrilla) laittaa
/ tiedon sukromuistin loppuun, mitä varten ensin tyhjennetään muisti:
/
*{d}{u}{ins line}
*{del stack}REPLACE + + N{act}
/
/ Samalla työrivillä käytetään LINEDEL-komentoa, jolla poistetaan kaikki
/ rivit joissa esiintyy '+'. Näitä ei tulla jatkossa tarvitsemaan, joten
/ kohteena oleva lista lyhenee kokoajan (huomaa että samalla myös itse
/ aktivoitava rivi (CUR) häviää, koska siinä esiintyy merkki '+'):
/
*{home}LINEDEL CUR END "+"{act}
/
/ Siirrytään takaisin käsiteltävänä olevan aloitusviestin kohdalle ja
/ kirjoitetaan lukumäärä kyseisen rivin loppuun:
/
*{u}{line end} {print W1}
/
/ Siirrytään käsittelemään seuraavaa aloitusviestiä:
/
*{goto A}
/
/ Lopulta jäljelle jää lista pelkistä aloitusviesteistä, joiden perässä
/ on niihin liittyvien vastausten lukumäärä, esimerkiksi
/
/  000001 / 000001-000000 0
/  000002 / 000002-000000 6
/  000004 / 000004-000000 1
/  000011 / 000011-000000 5
/  000012 / 000012-000000 2
/  000020 / 000020-000000 2
/  ...
/
/ ----------------------------------------------------------------------
/
/ Loppu - lyhyt mutta pakollinen. Tänne tullaan kohdasta A, kun lista on
/ käyty kokonaisuudessaan läpi:
/
+ Loppu: {end}


Kuten sanottu, sukroa voisi viilailla edelleen, ja korvata REPLACE- ja
LINEDEL-komennot silmukalla jossa '+'-rivien lukumäärä laskettaisiin
ja rivit poistettaisiin. Tällainen viilailu on kuitenkin jokseenkin
turhaa, sillä Survon komentojen käyttö on nopeaa ja itsedokumentoivaa.
Muistutan myös, että tämäkin koodinpätkä on vain pieni osa laajempaa
sukroa, joka möyhii tekstitiedostoista ensin toimituskenttiä ja sitten
niistä HTML-tiedostoja.

Lista toimituskentistä oli muuten tehty INDEX-komennolla

INDEX ARKISTO\0*.EDT CUR+2 / CD=0 TIME=0 SIZE=0 DATE=0 TYPES=0 EDT=

jossa uutta on CD-täsmennys (ei vaihdeta työhakemistoa). Toinen uusi
optio on FORMAT-täsmennyksen optio FULL, jolla tiedostoihin saa mukaan
koko levy- ja hakemistopolun. Tällaisia mahdollisuuksia oli toivonut
Juha Valtonen jossain vaiheessa kevättä. Kun vihdoin ehdin vierailla
DESKTOP:in "konehuoneessa", havaitsin että CD-täsmennys on ollut jo
olemassa ennestään siitä lähtien kun DIR-komento on toteutettu INDEX-
komennon eräänä muotona; tarvitsi vain lisätä tuo FORMAT=FULL. Mikäli
oikein ymmärsin, niin Juha on näiden optioiden avulla tehnyt itselleen
työkaluja, joilla voi helpottaa erilaisten PDF- ym. dokumenttien availua
(/OPEN) tilanteissa, joissa ao. dokumentit sijaitsevat työhakemiston
alihakemistoissa.

Hauskaa kesänjatkoa kaikille kesäpähkinää pohtineille! Palataan asioihin
syksyn tullen.

terv. Kimmo

Vastaukset:

Survo-keskustelupalstan (2001-2013) viestit arkistoitiin aika ajoin sukrolla, joka automaattisesti rakensi viesteistä (yli 1600 kpl) HTML-muotoisen sivukokonaisuuden. Vuoden 2013 alusta Survo-keskustelua on jatkettu entistäkin aktiivisemmin osoitteessa forum.survo.fi. Tervetuloa mukaan!

Etusivu  |  Keskustelu
Copyright © Survo Systems 2001-2013. All rights reserved.
Updated 2013-06-15.