Kirjoittaja Aihe: Skriptiajuri  (Luettu 128809 kertaa)

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #40 : 10.12.23 - klo:13.20 »
Yritän tässä määritellä niitä mitä olen kutsunut vanhoiksi käskyiksi sillä eiväthän ne kirjaimellisesti ottaen käskyjä ole vaan dataan lisättäviä ohjeita siitä kuinka data tulisi esittää. Nopeilla käskyillä ei muuten ole matematiikan kanssa mitään tekemistä - silkkaa tekstikäsittelyä ne ovat.

Niiden nopeus tulee siitä että niiden toteuttamiseen tarvitaan vain merkki = tai käsky echo tai jotain senkaltaista nopeaa. Jos pelkästään tuloksia takastellaan niin datan muokkaamiseksi samallatavoin käytetään ohjelmina yleensä sed:iä, pieneltä osin myös awk:ia ja aivan mittömältä osaltaan myös bc:tä - mutta niillä tuloksen saaminen kestää niin kauan ettei niitä käyttäen saisi skripteistä nopeita. Ihmettelin aikanaan kun eräs virtuoosi sanoi että nopeutta haluttaessa pitää unohtaa sed, awk ja bc - täytyy siis olla niin että nopeiden skriptien olemassaolo on tiedetty aina?

Mutta enää en ihmettele sillä nuo vanhat käskyt suorittavat samantapaisia tehtäviä - kylläkin rajoitetummin mutta myös paljon nopeammin. Mutta jokatapauksessa ainoastaan sed, awk ja bc mielletään käyttökelpoisiksi - mikä suureltaosin taitaa johtua siitä etteivät virtuoosit ole koskaan tehneet noista BASH:in nopeista käskyistä minkäänlaista yhteenvetoa - sillä nopeiden käskyjen hyödyllisyys tulee täysin esiin vasta kun melkein kaikki käskyt skriptissä ovat noita vanhoja - sillä tulkki tulkkaa kerralla niitä isonkin joukon eikä tulkkia siis tarvita vähänväliä - joten joskus ne ovatkin parhaita.

Nopeat käskyt ovat vähän niinkuin BASH:in assembleria. Ja vaikka ne ovatkin ylivertaisia suorituskyvyltään niin luultavasti ne on hylätty samasta syystä kuin varsinainen assemblerkin : ohjelman tekeminen ja ylläpito niitä käyttäen on ihan liian kallista - rahallisesti jos skriptin ostaa ja jos skriptin tekee niin selkänahka paukkuu kauan. Virtuooseilla on siis ollut syytäkin tekoseensa - heitä on vaan on niin sopivaa mollata sillä onhan heillä leveät hartiat.

Toki nopeat käskyt toimivat vain niin hyvin kuin moitteettomat käskyt toimivat silloin kolmekymmentä vuotta siten. Esimerkiksi kun etsittävän alku on teksissä eri rivillä kun loppu niin plörinäksi menee. Samoin kirjoitusvirheitä ei suvaita ollenkaan.

***

- lukuja, tekstijonoja, matriiseja tai matriisien yksittäisiä jäseniä voidaan käsitellä 'äärettömän' monin eritavoin - on tosiaan mahdotonta muistaa käsittely-säännöistä pientä osaakaan vaan tiedostoista ne on haettava - eikä missään ole minkäänlaista yhteenvetoa vaan itse se on tehtävä - ja koska yhteenvedon tekeminen on liian suuri työ niin tuloksena on hutilointia ja sotkua - sillä yhteenvedon tekeminen kun olisi isollekin joukolle vaativa tehtävä. Ja nyt yhteenvedon tekeminen on hieman liian myöhäistä sillä ne vanhat käskythän on osin jo unohdettu - joten virtuoosit yrittävät tuhota BASH:in ennenkuin kukaan huomaa?

- nopeat käskyt toimivat vain yhden sanan alueella - mutta lauseesta tulee tavallaan yksi sana kun sen laittaa heittomerkkien väliin - tai myös muuttujalla nimeltään IFS voidaan määrätä sananväliksi merkki jota ei ole käytetty misssään jolloin monirivinenkin teksti tai tiedosto on yksi sana. Jokatapauksessa vanhojen käskyjen käyttämiseen ei tarvita jotakin grep-käskyn kaltaista järkälettä - kuten regex:ät tarvitsevat - joten ne ovat satoja kertoja nopeampia yhden sanan kanssa - tosin ne ovat myös satoja kertoja tehottomampia monirivisten tekstien kanssa sillä IFS:n kanssa leikkiminen on yleensä liian vaarallista - mutta oikeassa paikassa käytettynä ainoastaan nopeus merkitsee.

- BASH:issa jokaista käskyä käsitellään kymmenellä tavalla ennenkuin se lähetetään tulkattavaksi ja päteehän se nopeisiinkin käskyihin. Käsittelyjen suoritusjärjestys on päätetty etukäteen joten kaikki tehdään 'ennen tai jälkeen' monen muun tehtävän joten monet määreet kuten esimerkiksi IFS (= se määrää mikä merkki jakaa sanoja) muuttavat myöhemmin tulevat käsitteyt joskus ihan nurinkurisiksi. Tämmöinen  liian suuri monipuolisuus on myös painolasti kielen käytölle - BASH onkin turhan monipuolinen varsinaiseen ohjelmointiin - prottotyyppien tekemiseen BASH on tosin ihan kiva - ja alzheimerin välttelyssä BASH on erinomainen.

- voi olla varma että tästä kuvauksesta on moni merkittävä ominaisuus jäänyt pois sillä BASH:in kirous on se että kaikesta löytyy loppumattomiin uusia ominaisuuksia joten esimerkiksi kaikki käsikirjat ovat kelvottoman isoja tiiliskiven kokoisia raamattuja - esimerkiksi pääte-ohjelman käsikirja vaatisi viikkojen opiskelun ennenkuin homma olisi hanskassa - ja silti useimmat meistä käytävät päätettä käsikirjaa lukematta ja hyvin se sujuu niinkin - toiminta on silloin tosin joskus hidasta ja ärsyttävää mutta kaikki toimii kyllä jotenkin.

Jospa joskus tajuaisin päivittää tätäkin kuvausta - tai sitten ei, jottei tästäkin tulisi tiiliskiveä - sillä tiiliskiveä ei lue kukaan.

BASH on ainakin mielenkiintoista moniulotteista shakkia eikä hölmöilystäkään tule paineita - sillä onhan BASH siinä itsekin ihan omaa luokkaansa. Mutta jos saisi kirjastojen käyttämisen palautettua niin kuka tietää mitä BASH:ista tulisi.

***

Usein isoilla ja hitailla skripteillä on nopeat korvaajat - muihin kieliin verrattuna BASH on tosin hidas sittenkin. Koska ne on aikaisemmin tunnettu niin miksi ne on hylätty? Sillä ne ovat nopeampia, lyhyempiä ja ainakin tuntuvat vakaammiltakin.

Ehkäpä paras keino kuvata noita nopeita käskyjä on muutama esimerkki toimivista ohje-tyypeistä. Kaikki toimivat niin monella eritavalla ettei esimerkkejä kaikista voi antaa:

- tehtävä1: jaa annettu sana jonkun merkin kohdalta ja esitä joko etu- tai jälkiosa. Jakopiste voi olla myös sana - siis myöhemmin tehty uusissa käskyisä oleva 'parempi' cut-käsky joka jakaa vain yksittäisen merkkin ollessa jakopisteenä on varsinainen möhläys. Jakava merkki voi olla sanassa ensimmäinen jakavan merkin kaltainen tai sitten viimeinen. Jakava merkki voidaan esittää myös merkkiluokan osana, esimerkiksi: [1-9] -> siis nollan kohdalla ei tehdä mitään.
Esimerkiksi: desimaaliosa=${luku##*.} . Tai voidaan kirjoittaa pisteen sijaan: [.,] jolloin desimaalipisteenä voi olla joko piste tai pilkku - nopeudessa tuommoiset pikkujutut eivät tunnu vaikka niitä olisi montakin.

- tehtävä2: tuhoa, muuta tai tulosta sanasta jotakin määriteltävien ominaisuuksien perusteella. Esimerkiksi kun tekstijonona esitetystä desimaailuvusta pitäisi tehdä 'silmälle miellyttävä': poista kokonaisosasta etunollat ja desimaaaliosasta takanollat ja desimaalipistekin jos se jää viimeiseksi - eikä muihin nolliin saa kajota:
Koodia: [Valitse]
luku=${luku##+(0)}; [[ ${luku//[^.]/} ]] && luku=${luku%%+(0)}; echo ${luku%.}
Tällainenkin toiminta voidaan toteuttaa merkkiluokkien avulla - merkkiluokka on esimerkiksi: [0-9] elikä numroiden luokka - tai onhan noita: [:alnum:], [:alpha:], [:blank:], [:cntrl:], [:digit:],  [:graph:], [:lower:], [:print:], [:punct:], [:space:], [:upper:] ja [:xdigit:] - tai jotain muuta hakasulkujen välissä olevaa määritystä - kaksois-sulkuja kulemma kannattaa käyttää.

- tehtävä3. muuta joku sana/sanaryhmä jossain tiedostossa. Muutettavien sanojen ei tarvitse olla yhtäpitkiä - voit siis vaikka tuhota määrättävän sanan koko tiedostossa. Muutettavassa sanassa saa olla välilyöntejäkin. Muutettavia saa olla montakin samalla rivillä.
Koodia: [Valitse]
mika=BEGIN; miksi=ALOITA; < /boot/grub/grub.cfg readarray doku; printf "%s" "${doku[@]//"$mika"/"$miksi"}" | tee ~/poista_luettuasi
tulos ilmestyy näytölle ja myös kotikansion tiedostoon: ~/poista_luettuasi. Mitään ei varsinaisesti editoida - vaaraton esimerkki tämä on.

- tehtävä4: määrittele missä kohtaa annettavassa pitkässä sanassa on jokin kirjain/kirjainryhmä (= pos-funktio). Sekä etsittävässä ettäetsijässä saa olla välilyöntejä. Esimerkki:
Koodia: [Valitse]
isosana="Pitkät on puut Pisan mäellä, hongat Hornankalliolla"; pikkusana="Pisan m"; [[ "$isosana" =~ "$pikkusana" ]] && { echo -n 'pikkusana alkaa kohdalla:'; apu=${isosana%%$pikkusana*}; echo $((${#apu}+1)) ;} || echo 'pikkusanaa ei löydy'
- tästä olisi helppoa tehdä versio joka ilmoittaa kaikki ne paikat joista etsittävä löytyy.
- onko ihme että BASH:ia väheksytään kun tämöisistä super-nopeista ja vakaista on siirrytty epävakaisiin aikasyöppöihin?

tehtävä5: yhdistä kaksi edellistä grep-käskyn kaltaiseksi - siis tarkoituksena on käydä nimettävä tiedosto läpi ja jokaiselta riviltä miltä esittävä löytyy tulostetaan rivinumero ja löytökohta:
Koodia: [Valitse]
function grep2 () { < $2 readarray doku; rivino=0; for n in "${doku[@]}"; do rivino=$(($rivino+1)); apu=${n%%$1*}; [[ "$n" =~ "$1" ]] && { echo -n 'haettava löytyi riviltä: '$rivino' paikalta:'$((${#apu}+1)); echo ;} ; done ;}; grep2 "feature is" /boot/grub/grub.cfg
- siis kutsu on kokonaisuudessaan: grep2 mikä_ilmaisu mistä_tiedostosta. Sanassa mikä_ilmaisu saa olla välilyöntejä mikäli se laitetaan heittomerkkien väliin. Alkuperäinen grep ei edes salli heittomerkkejä ja ilman niitä se toimii hitaasti ja väärin.
- tämä on kolme kertaa hitaampi kuin alkuperäinen grep - mutta paljon nopeampi kuin BASH-skripti tavanomaisilla uusilla käskyillä. Silloin aikoinaan tällaisilla olisi hyvin voinut kilpailla grep-käskyn kanssa. Lisäksi tämän saa muokattua aivan sellaiseksi kuin käyttäjä haluaa.
- näistä nopeista käskyistä muodostetut skriptit lisäksi senjälkeenkun sen toimivat osat on koottu joko  toimivat tai sitten ei - mutta sitä uusien käskyjen raivostuttavaa taipumusta ei ole että alkuunsa saa virheellisiä tuloksia kunnes korjattuaan skiptiä miljoona kertaa alkaa saada oikeita tuloksia yhä useammin. Ovatko uudet käskyt siis paitsi satoja kertoja hitaampia niin myös loogisia pommeja?
« Viimeksi muokattu: 13.12.23 - klo:11.51 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #41 : 14.12.23 - klo:18.41 »
Awk, sed ja bc ovat olleet tähänasti täysin ehdottomia nopeus-kuninkaita. Nyt ne ovat tosiaan menettämässä asemaansa 'BASH:in nopeille käskyille' - näin alkuunsa vasta muutamassa pienessä tehtävässä. Mutta esimerkiksi awk häviää taiston pahimmillaan 'kymmenkertaisesti'. Eivät ne tosin saa tuommoisia rökäletappiota kuin pienissä asioissa ja todella suurissa ne ovat nopeampiakin - myöntääköhän Linux niille enemmän resursseja? Eikä tosiaan kaikkia ziljoonia awk- ja sed-skriptejä kerkiä edes ajatella korvaavansa - mutta BASH varmasti osaisi. Tarkempi kuvaus siiä kuinka asiat tehdään:

Awk:ia, sed:iä ja bc:tä käytetään BASH:issa putkittamalla tutkittava niihin. BASH käyttää putkitusta vain kutsuessaan toisia skriptikieliä mutta kutsuessaan toisia BASH-skriptejä se käyttää mieluummin funktioita. Koska heti BASH-opetuksen alussa opetetaan käyttämään putkitusta mutta funktioista ei puhuta juuri sen enempää kuin että väitetään ettei BASH osaa funktioita kunnolla käyttää - joten eihän funktioiden käyttöäkään osata tekemisestä puhumattakaan. Esimerkki  awk:in käytetyimmästä toiminnosta:
Koodia: [Valitse]

# tämä on tosin ihan pieni mutta yleisin awk skripti:
echo  "10 20 30 40 50 60" | awk '{print $3}'

# näin se korvataan BASH:in 'nopealla käskyillä':
function awk2 () { echo ${@:$(($1+1)):1} ;}; awk2 3 10 20 30 40 50 60 

# tai jos heittomerkejä ehdottomasti haluaa käyttää: function awk2 () { apu=$1; set $2; echo ${@:$apu:1} ;}; awk2 3 "10 20 30 40 50 60"
# tai jos valittavissa on välilyöntejä niin: function awk2 () { echo ${@:$(($1+1)):1} ;}; awk2 3 'nyt saat kokea, koito' 'kokea kovaosainen' 'apen luista leukaluuta, anopin kivistä kieltä'
- BASH:in käyttämä tapa on tosin paljon hankalamman näköinen - mutta vain koska BASH:issa funktio-kirjastot on "kielletty" - muuten koko awk on sekin tavallaan kirjasto joten tilanne on epäreilu. Mutta jokatapauksessa BASH on kymmenkunta kertaa nopeampi - pärjääköhäm Pythonkaan taistossa hautaan jo saatetun BASH:in kanssa tässä pikkujutussa?
- awk on suurissa matemaattisissa toimissa paljon parempi kuin BASH. Eikä toistaiseksi voi edes aavistella kuinka noissa isoissa matemaattisissa laskuissa käy - ja onnistuvatko ne edes.
- awk:ssa on myös sadoittain pieniä muutaman merkin käskyjä jotka suorittavat pieniä ihmeitä - mutta eihän niistäkään misään kunnon yhteenvetoa ole.
- alkaa tuntua siltä että suhmurointia on liikaa ja käry on varmasti käynyt aikaisemminkin. Onko professorien valta niin ehdoton että asiat voidaan yksinkertaisesti vaieta kuoliaaksi?

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #42 : 15.12.23 - klo:15.45 »
Sed selviytyy paljon paremmin: muutettaessa tekstistä annettu sana kaikilla toiseksi kuluu  kymmenen kilosanan tiedoston käsittelyyn aikaa noin millisekunti niinkuin sed:illäkin. Pienemmillä tiedostoilla BASH on jopa 4*nopeampi ja isommilla jopa 4*hitaampi.
 
Koodia: [Valitse]
apu=$(cat /dev/urandom | base64 | head -c 10000); time printf "%s" ${apu[@]//a/alku}     # apu:sta muodostetaan ensin 10000 sanan tiedosto.  Tämä on pelkkää BASH:ia
apu=$(cat /dev/urandom | base64 | head -c 10000); time echo ${apu[@]} | sed 's/a/alku/g' # tämä taas käyttää apunaan sed:iä

# toteutustapoja on muitakin, esimerkiksi:
< /boot/grub/grub.cfg readarray doku; time { echo "${doku[@]}" | sed 's/a/alku/g' ;}

- myös sed on niin suuri ettei sen toimintojen merkittävää osaakaan saa tutkittua ihmisiässä.
- myös pieniä sed-skripteja on tolkuton määrä - ja myös ne tekevät pieniä ihmeitä. 
« Viimeksi muokattu: 16.12.23 - klo:17.47 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #43 : 16.12.23 - klo:17.52 »
 
Käsitelläänpä sitten bc:

Kerro18 on huomattavasti nopeampi kuin bc - tosin kerro18 on vain 36 numeroinen liukuvanpilkun kertolasku. Samoin 72 numeron desimaalilukujen yhteenlasku on sekin nopeampi. Desmaalilukujen jakolaskukin toimii sekin nopeasti antaen noin 50 numeroa jotka yleensä kaikki oikein - valitettavasti eivät aina. Mutta sittenkin bc on ehdottomasti kunkku - nämä ovat vain vähäisiä säröjä bc:ssä.

Mutta esimerkiksi lukuja pyöristtessä bc on toistaitoinen: bc ei oikeastaan osaa pyöristää ollenkaan vaan se ainoastaan leikkaa sen desimalien lukumäärän määrämittaan. Ja sen leikkaamisenkin suorittamiseksi sen täyy tehdä jakolasku - se lasku voi kylläkin olla valelasku jossa jaetaan luvulla 1 joten mikään ei muutu. Mutta ihmiset eivät yleensä tiedä tätä eivätkä saa aina edes leikattua - ja taas saadaan lisää syytä mollata BASH:ia. Ja leikkaamiseenkin bc kuluttaa ylettömästi aikaa.

Mutta pyöristys-skripti pyöristää aina oikein ja on lisäksi salaman-nopea, 'kymmenenkertaa' nopeampi kuin bc:
Koodia: [Valitse]
function pyöristä () {
[[ ${1:0:1} = - ]]  && merkki=- || merkki=+
[[ $1 =~ \. ]] &&  desimaaliosa=${1##*.}000000000000000000 || desimaaliosa=0000000000000000000 # onko desimaalipistettä ...
kokonaisosa=${1%%.*}
apu=${desimaaliosa:0:$2}
desimaaliosa=$(($apu$merkki(( ${desimaaliosa:$2:1} >= 5 )) ))
echo $kokonaisosa.$desimaaliosa ;}

time pyöristä 1.22634 2          # tämä 'nopeilla käskyillä' toteutettu BASH-skripti kestää 0ms   
time bc<<<"scale=2; 1.22634/1"   # tämä bc:n lasku kestää 4ms - ja tulos on hieman virheelinen.
 
- tarkistelepa lausetta: $(($apu$merkki(( ${desimaaliosa:$2:1} >= 5 )) ))  -> BASH kokoaa ensin sellaisen tekstijonon kuin käsky määrää. Lähetettäessä tekstijono matematiikka-moottoriin sen osista jokainen määritellään sentyppisesti kuin hyvä tulee: siis jokainen osa voi olla tarpeen mukaan joko: tekstijono, numero, operaattori, laskutoimitus, funktiokutsu tai looginen arvo 0 tai 1 -> kaikki mitä sinne matematikka-moottoriin lähetetäänkin tuntuu toimivan.
- skandit funktion nimessä toimivat hyvin. Ei kyllä taida olla järkevää käyttää nimessä skandeja - mutta kokeillaan tämänkerran.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #44 : 19.12.23 - klo:10.40 »
Printf-käsky:llä on käynnissä ikuinen taistelu desimaalipisteen kanssa ja sillä lukujen koko rajoittuu 18 merkkiin. Kummankin puutteen voi poistaa 'nopeilla käskyillä' tehdyllä skrpteillä jotka osavat tulostaa  normaalissa esitysmuodossa annetun luvun tietellisessä esitysmuodossa tai päinvastoin - olipa luvuissa numeroita vaikka satoja - eikä desimaalipisteestä ole harmia:
Koodia: [Valitse]
function to_sci () { luku=$1
[[ ${luku:0:1} = - ]]  && { merkki=-; luku=${luku:1} ;} || { merkki=''; luku=${luku//+/} ;}
luku=${luku##+(0)}  # poistetaan etunollat - nimenomaan 0.xyx -> .xyz
apu=${luku%%.*}     # erotetaan kokonaiosa
exp=${#apu}         # lasketaan kokosasta positiivinen exponentti
[[ ${luku:0:1} = \[.,] ]] && { # katsotaan onko ensimmäin merkki desimaalipiste - silloin exponentti on negatiivinen
apu=${luku%%[1-9]*} # poistetaan kaikki siitälähtien kun ensimmäinen numero tulee desimaalipisteen jälkeisen nollasarjan perään. Siis tulos on desimaaipiste yksin jos nollia ei ole yhtään.
exp=$((1-${#apu}))  # lasketaan negatiivinen exponentti nollien lukumäärästä vähentäen yhden desimaalipisteestä
luku=${luku:1}      # palautetaan desimaaliosa jättäen desimaalipite pois
luku=${luku##+(0)}0 # poistetaa etunollat ja lisätään yksi peränolla
echo $merkki${luku:0:1}.${luku:1}e$(($exp-1)) # tulostetaan näin kun expnentti on negatiivinen - kokonaisosa on nyt ensimmäinen numero
} || { # halu dokumentoida aihuttaaa sen että ehtojen jälkeinen ryhmitys tulee rikkoa erotamalla nämä merkit tällätavoin
luku=${luku//[.,]/} # poistetaan desimaalipista sotkemasta
echo $merkki${luku:0:1}.${luku:1}0e$(($exp-1)) # tulostetaan näin kun exponentti on positiivinen - kokonaisosa on nyt ensimmäinen numero
} ;}

to_sci 1234567890123567890123456789012345678901234567890,1234567890111111111111111111111111111111111111111111111111111111111111111111
to_sci 1
to_sci +1
to_sci -1
to_sci .1
to_sci 0.1
to_sci -0.1
to_sci 10


- jos myöhemmin huomaa että muunnos toimii joskus väärin niin sehän olisi vain hyvä - joutuisi nimittäin korjaamaan ja ajukopan ränsistymistähän tässä koetetaan hidastaa.
- BASH:ia ei voi dokumentoidakaan kuten muita kieliä sillä ehtojen toinen tai kummatkin haarat saattavat olla koottuja lauseita ja mikäli ne kommentoi ninkuin normaalisti niin rakenne särkyy. Ei se kommentointi kuitenkaan raketti-tiedettä ole.
- BASH toteuttaa ilmaukset oikein silloinkin kun voisi vannoa ettei semmoista sotkua mikään pysty tulkitsemaan - joten skriptit lyhenevät ja nopeutuvat ikuisesti - tai onhan nollaa vaikeaa enää pienentää.
- nopeat käskyt' tosiaan ovat nopeita: näin monirivinen skripti on yhtänopea kuin yksi uusi käsky.

Muunnoksen kestoajan (noin .3 millisekuntia) määrittäminen:
alkuhetki=$(date +%s%N); to_sci 1234567890123567890123456789012345678901234567890.1234567890111111111111111111111111111111111111111111111111111111111111111111 ; loppuhetki=$(date +%s%N); aika=$((10#$loppuhetki-10#$alkuhetki-1000000)); apu=000000000$aika; apu=${apu: -14: -9}.${apu: -9}; echo ${apu##+(0)}
- printf "%e" 100000 kestää noin .2 millisekuntia

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #45 : 21.12.23 - klo:01.12 »

Tai muunnos tieteellisestä esitysmuodosta normaaliin esitysmuotoon: 
Koodia: [Valitse]
function from_sci ()
{ nollia=00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
kokonaisosa=${1%%.*} ; kokonaisia=${#kokonaisosa}
luku=${1//[.]/}
luku=${luku%%e*}
[[ ${luku:0:1} = - ]]  && { merkki=-; luku=${luku:1} ;} || merkki=''
exp=${1##*e}
 (( $exp > 0 )) && { luku=$luku$nollia; apu=$merkki${luku:0:$(($exp+$kokonaisia))}.${luku:$(($exp+$kokonaisia))};apu=${apu%%+(0)}; echo ${apu%.} ;} || { [[ -exp -gt $kokonaisia ]] && echo $merkki.${nollia:0:$((-$exp-$kokonaisia))}$luku || echo ${luku:0:$(($kokonaisia+exp))}.${luku:$(($kokonaisia+exp))} ;} ;}

# testausta ja suoritusajan määritystä  - yksi muunnos kestää luokaa 0.25 ms
time for expo in {-55..55}; do from_sci 123456789012345678901234567890123456890.12345678901234567901234567890123456789e$expo; done

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #46 : 22.12.23 - klo:09.16 »
Kirjastojen puutteen takia BASH:issa on runsaasti seuraavankaltaista: haluttaessa erottaa tekstistä joku sana käytetään yleensä seuraavantyyppistä toimintaa :
Koodia: [Valitse]
echo $text |  awk '{ print $3 }'       # BASH:in vastaava toiminto on:
matriisi=($text); echo ${matriisi[2]}  # ja se toimii kymmenkunta kertaa nopeammin. Onhan koodi vähän pidempi eikä ihan yleisesti
                                       # tunnettukaan. Mutta silti ihmettelen miksei sitä käytetä sillä virtuoosien on pakko
                                       # tuntea tuommoiset. Halutaanko vähätellä BASH:ia vaiko edistää awk:ia?
                                       # Mutta entäpä jos BASH:issa olisikin kirjasto ja siellä funktio:
                                       # function write () { matriisi=($1); echo ${matriisi[$2]} ;}. Silloin käsky olisikin:
write "$text" 2                        # Ja toiminto olisi edelleen melkein yhtä nopeaa.

-  käske: 
Koodia: [Valitse]
function write () { matriisi=($1); echo ${matriisi[$2]} ;}
käskystä jää sllähetkellä avattuna olevan päätteen muistin funktio - aivan niinkuin funktio olisi haettu kirjastosta. Käske sitten samassa pätteessä:
Koodia: [Valitse]
write "yksi lensi yli käenpesän" 2
-> tulostuu: yli .

- kyse on ajoista 4ms ja 0.5ms. Mutta ajetaanpa toiminto kuinka monesti tahansa samassa skriptissä niin toiminta kestää jokakerran melkein yhtäkauan. Ja kun samanlaisia pikkujuttuja on paljon niin koko BASH alkaa tahmaamaan. 
- voi käskeä nyös: set yksi lensi yli käenpesän; echo $3    # se on lyhyt ja nopea - niinkuin BASH taitaa olla aina jos ei hölmöillä.
« Viimeksi muokattu: 22.12.23 - klo:10.55 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #47 : 23.12.23 - klo:15.35 »
'nopeat käskyt' ovat paitsi nopeita niin niillä myös helppo määritellä nopeita ja monipuolisia toimintoja sillä ne eivät ole loogisia pommeja niinkuin uudet käskyt helposti ovat. Tosin vanha käskyt ovat vaikeasti muistettavaa merkki-sotkua. Esimerkiksi kun pyydetään:

kerro millä paikalla etsitty on hakulausekkeessa kun jossain haettavan jälkeen täytyy olla määrättävä sana:
Koodia: [Valitse]

merkkijono='abc def ghi jkl'; trigger=bc; arm=gh; etuosa="${merkkijono%%$arm*}";apu=${#etuosa}; [[ "${merkkijono:0:$apu}" =~ $trigger ]] && etuosa="${etuosa%%$trigger*}" && echo 'merkkino='$((${#etuosa}+1))
- tätä toimintoa varten on tehty myös regex - ja joku on puurtanut kuukausitolkkua kehittäessään sitä. Tämä tekemisessä meni parituntia - olihan tämä ensimmäinen laatuaan.
- kyse on aikaisemmin tuntemattomasta toiminnosta joten esimerkki on todennäköisesti huonosti valittu - mutta kannnattaa esittää sillä tiedähäntä mihin tämä johtaa.
- esimerkiksi tiedon etsimiseen rekistereistä tämäntapaisia tarvitaan - mutta BASH  on saanut niin huonon maineen hitaudestaan ja 'kiikkerästä' toiminnastaan etteivät luotettavasti toimivat 'nopeat käskyt' siihen minkäänlaista muutosta tuo.   


Tai sama haku hieman erilaisilla määrittelyillä: kerro millä paikalla etsitty on hakulausekkeessa kun haettavaa ennen täytyy jossakin olla määrättävä sana:
Koodia: [Valitse]

merkkijono='abc def ghi jkl'; trigger=bc; arm=gh; etuosa="${merkkijono%%$arm*}";apu=${#etuosa}; [[ "${merkkijono:$apu}" =~ $trigger ]] && etuosa="${etuosa%%$trigger*}" && echo 'merkkino='$((${#etuosa}+1))

- monipuolisemmillakaan hauilla nopeus ei juurikaan muutu.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #48 : 25.12.23 - klo:11.19 »
Yritän jatkuvasti saada jotain järkeä siihen miksi virtuoosit ovat tehneet BASH:ista surkimuksen - selitän tätä siis itsellenikin: on pakko miettiä asiat paljon paremmin kun asiat kirjoittaa.

BASH:in ylipapit alkoivat jo yli kolme vuosikymmentä sitten toivoa että BASH hiljokseen häviää - syytä haluun en tiedä, mutta tosiasia on että BASH on niin monipuolinen ettei yksikään professori kykene hallitsemaan siitä isompaa osaakaan täydellisesti vaan oppilaat hyppivät silmille kokoajan - onhan se käytännössä pätevä syy yrittää päästä siitä eroon.

Mutta BASH oli siihenaikaan niin voimissaan ettei sen tuhoamisesta olisi tullut mitään - mutta mistähyvänsä pääsee eroon kun vaan antaa sen päättäjille riittävän löysän talutushihan niin he varmasti hirttävät siihen itsensä - ja tässätapauksessa siinä sivussa meinisi myös BASH. Hullulta tuntuva konsti toimii aina vaikkakin se on kamalan hidas - kaikkialla muuallakin käytetään tuota samaa keinoa  - sillä ei ole mitään sellaista joka ei hyödyttäisi jotakuta ja lähettäisi toiset manalaan.

Aluksi virtuoosit alkoivat sanoa että BASH on surkean hidas kaikssa muussa kuin tietokoneen hoitamisessa - mikä on täysin totta. Sitten pienen säätelyn jälkeen aletiin sanoa että useissa asioissa BASH on myös liian omituinen - sekin ihan totta. Virtoosit puhuvatkin aina varmasti totta joten esimerkiksi voi luottaa siihen että 'advanced guidet' puhuvat BASH:in alkeista ihan asiaa - pidemmäälle nuo oppat eivät edes yritä mennä huolimatta nimestään. Mutta ne esimerkiksi vihjailevat ettei BASH osaa käyttää nimiparamereja funktioissa - mikä on sekin yksi ohjelmointikielen menestymisen ehdoista. Ehkä ne itsekin uskovat väitteiseensä.

Tavallaan väite pitää kyllä paikkansa koska nimiparametrit eivät toimi BASH:issa samallatavoin kuin muissa kielissä - sillä kun BASH:issa passaat funktioon muuttujan käyttäen sen nimeä niin funktiossa se on tosiaan pelkkä nimi - kunnes se sidotaan saman-nimisen muuttujan arvoihin ja tyyppimääreisiin - tyyppimääreitä ovat sen arvot ja onko se tavallinen muuttuja vaiko tavallinen- tai assosiatiivinen matriisi - ja lisäksi niiden tarkenteet. Sitominen tapahtuu seuraavalla tavalla:

BASH pitää kirjaa muuttujistaan ja niiden senhetkisistä arvoista niinkuin muutkin kielet - ja BASH antaa kirjanpitonsa skriptaajan käyttöön käskyllä: declare. Kun kirjanpidosta löytyy sama muuttujanimi niin siinähän se muuttuja on argumentteineen ja kun määritelmät kopioi sieltä niin muuttuja on täysin kunnollinen - mutta jos jättää tämän sitomisen tekemättä niin nimiparametrit eivät toimi. Sitomiseen on muuttujakuvausten käyttämisen lisäksi pari käskyäkin: let ja read - jos oletetaan ettei käskyä: eval käytetä. Voiko olla sattumaa että kolme käskyä ja yksi menetelmä toimivat oikein asiassa johon niitä ei ole tarkoitettu? Mahdollisuus on pienempi kuin saada lotossa 10 oikein - kyllä ne on aikoinaan tarkoituksella tehty ja nimiparametreja osattu käyttää.

Samalla ratkeaa sekin ettei parametreja tarvitse palauttaa sillä jokakrran muuttujaa käytettäessä muuttujakuvausta muutetaan vastaamaan tilannetta - ja muuttujakuvaus on globaali elikkä sama kuvaus on käytössä kaikkialla - niin pääohjelmassa kuin jokaisessa funktiossakin - joten jos sitä muutetaan jossakin niin se muuttuu kaikkialla.

- senkin virtuoosit tekivät että he 'kielsivät' käyttämästä käskyä: eval - se nimittäin on helpoin ratkaisu myös yhteensitomiseen. Ja taas välittämättä virtuoosien puheista BASH:in kehittäjät ovat laittaneet tiedostoon: ~/.bashrc noin kolme eval-käskyä. Ketä uskoa?

Koetan selittää funktio-parametrien palautusta toisellakin tavalla: funktoista ei ole täyttä hyötyä elleivät funktiosta palattua sinne lähetetyt muuttujat ole muuttuneet. Tähän muuttamiseen on kaksi keinoa: muuttoksen suorittaa joko funktion kutsuja saatuaan tulokset funktiosta takaisin tai funktio itse toimintansa yhteydessä. Muissa kielisssä muutoksen tekee funktion kutsuja ja sitävartenhan parametrien arvot tulee palauttaa sieltä funktiosta. Mutta BASH ei toimi näin möllillä tavalla vaan muutoksen tekee funktio itse - tämä edellyttää että käytetään nimiparametreja ja että kielessä on kyky yhdistää nimi sen arvoon - BASH:illa on tuo kyky mutta muilla kielillä ei - mutta kyky ei riitä ellei sitä myös käytetä ja virtuoosit jättävät kylmän tyynesti kyvyn käyttämättä. Kun virtuoosit sanovat että BASH ei osaa parametreja palauttaa niin he puhuvat siis ihan totta - eikähän mikään laki vaadi kertomaan ettei BASH:issa parametreja tarvitsekaan palauttaa - mikäli on toimittu oikein. 

---

Ja 'nopeat komennot' nopeuttavat toimintaa paljon - nopeuttivathan ne aikanaankin mutta niiden käyttäminen romahti koska 'nopeat komennot' ovat nopeita vain kun skriptissä melkein kaikki käskyt ovat niitä nopeita eikä ilmeisesti kukaan huomannut sitä.

Toistaiseksi on liian aikaista edes arvella kuinka paljon ne nopeuttavat kokonaisuutta, mutta jo tähänasti tehdyt 'nopeita komentoja' hyödyntävät funktiot tekevät melkoisen kyky-loikan yksittäisissä tapauksissa - ja tekevät ainakin sen että BASH on surkea enää vain vähän. Ja on täysin varmaa että paljon lisää löytyy.

Jotta uusia ominaisuuksia voisi käyttää järkevällä tavalla täytyy niiden käyttämiseksi kirjoittaa funktio joka täytyy voida sijoittaa kirjastoon - mutta  virtuoosithan 'kielsivät' kirjastot? Ja taas BASH:in kehittäjät ovat asentaneet jokaiseen koneeseen itselleen merkittävistä toimista kirjastollisen funktioita - välittämättä virtuoosien 'kirjasto-kiellosta'. Ja eikö kehittäjä ole verrattomasti tietävämpi kuin virtuoosi?
- voit itsekin käyttää noita super-omituisia funktioita - esimerkiksi funktio nimeltä: quote palauttaa sille lähetetyn sanan lainausmerkeissä. Käske: quote antti -> tulostaa 'antti'

Ja BASH:ista yritetään muinkin keinoin tehdä surkimusta: esimerkiksi 'nopeat komennot' haudattiin uusien käskyjen alle ettei kukaan vaan huomaisi niiden käyttökelpoisuutta - ja muut keinot haudattiin muun roskan alle - samaa keinoa käytetään kaikkialla: hyväkin menetelmä hukkuu kun päälle sataa tarpeeksi roskaa. Toinen konsti on vaieta asia kuoliaaksi - eihän kukaan usko mihinkään sellaiseen josta virtuoosit eivät koskaan puhu.

Teoriassa BASH kykeneekin samoihin ohjelmointitöihin kuin muutkin kielet - hidashan BASH on eikä siitä taida nopeaa saadakaan - mutta pikkuinen toivonkipinä siitäkin on. Varsin omituinenkin BASH on. Käytännössä BASH on melkolailla toivoton kieli - mikä johtuu virtuoosien määräämistä rajoituksista joilla ei tunnu olevan kunnon syytä - mutta jos niistä ei välitä niin taivas tuntuu olevan rajana. Mutta 'kirjastokiellosta' ei oikein pääse eroon: kirjastot toimivat kyllä ihan hyvin, mutta 'kirjastokielto' estää kirjastojen lisäämisen perus-asennukseen - ja kirjastojen puute tuhoaa kielen ajanoloon takuvarmasti - ihme että BASH sinnittelee edelleen. Silti netistä löytyy vielä ainakin kymmenen isoa BASH-kirjastoa - unohtuneet nettiin ajalta jolloin kirjasto-osoitin vielä toimi?

Ja tuloksena tästä 'kirjasto kiellosta' on että olemattoman pieniinkin ongelmiin tarkoitetut skriptit ovat tuhatrivisiä hirviöitä jonka lauseet koostuvat sanoista jotka ovat todella inhottavia kirjoitus-asultaan joten niitä ei edes muista vaan ne täytyy jokakerran hakea itsetehdyistä tiedostoista.
 
Omaan koneeseensa voi toki laittaa itsetehdyn kirjaston - minun koneessani iso kirjastoni on toiminut moitteettomasti jo yli kahdeksan vuotta - vaikka koneeni ovat vaihtuneet usein ja myös Ubuntun versiot vaihtunet parikertaa vuodessa.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #49 : 30.12.23 - klo:14.07 »
Ihan alkuunsa BASH:ia syytettiin eniten hitaudesta - ja hitaus olikin kiistatonta johtuen hitaista käskyistä - tulkattavasta käskystä tulee hidas jos siihen lisätään runsaasti ominaisuuksia jotka täytyy tulkata tarvitaan niitä tai ei - ja kussakin käytössä tarvitaan vain yhtä ominaisuutta ja muut ovat turhaa painolastia. Koska 'nopeat käskyt' osaavat tehdä vain yhtä asiaa ovat ne nopeita - ja näyttää yhä enemmän siltä että nopeus saattaakin usein olla paljon-paljon parempi kuin on luultu.

Seuraavaksi alettiin mollata BASH:ia kyvyttömäksi - mutta 'nopeilla käskyillä' tehdyt skriptit ovat kyvykkäitä ja helpommin räätälöitävissäkin - joten ne toimivat paremmin ja niinkuin niinkuin etukäteen olettaisi - mutta nykyisistä käskyistä kootut skriptit tekevät yleensä sitä mutta toisinaan tätä - sillä ne ovat loogisia pommeja tarkoituksella tai tahallaan.

Skriptit olisi viisainta kirjoittaa funktiomuotoon - silloin voisi kutsua noita pitkiä skriptejä yhdellä sanalla. Mutta tämän estämiseksi annettiin 'kirjastokieto'?

Kirjastokieltoon voi suhtautua:
- ei välitä
- kirjastot jätetään tekemättä mutta kyllä funktioita saa tehdä. Eikä niitä funktioita tarvitse kirjoittaa vaan kopioida koko roska kerralla - tosin skripteistä tulee niin tehden nopeasti kammottavan kokoisia. Mikä on erittäin vahingollista aloitettaessa ohjelmointi sillä ihminen tajuaa nopeiten sellaisen joka voidaan esittää yhdellä sivulla.

Ainoa järkeväntuntuinen selitys 'kirjastokiellolle' on se että kirjastoissa on jotakin joka on tietoturvariski. Mikä pitää varmasti paikkansa sillä tietokone on tietoturvariski vaikka sen maalaisi vihreäksi ja heittäisi mereen. Selitys semmoisenaan on siis yhtätyhjän kanssa.

***

Luinpa kuinka jättikokoisen tiedoston viimeisen lauseen etsimisessä hehkutettiin komentoa: 'echo tiedosto | tail -1' - että se on melkein voitamaton - awk ja sed mukaanlukien. Olihan se ihan selvä haaste joten tein satunnaisesta tekstistä giga-luokan tiedoston nimeltään: ~/temp - ja sitten skriptin sen viimeisen rivin tulostamiseksi.
- pienen koetiedoston voi tehdä minuutissa käskyllä:
Koodia: [Valitse]
rm ~/temp;touch ~/temp; for n in {1..10000}; do echo $n'     '$(cat /dev/urandom | base64 | head -c 100) >> ~/temp; done

Toimintanopeuksia tosi-suurella tiedostolla:
Koodia: [Valitse]

cat ~/temp | tail -1                                                                                           #  kesti: yli minuutin
truncate -s-1 ~/temp; echo -n "¤" >> ~/temp; a=$(timeout .001 tac ~/temp); echo ${a%%¤*} ; truncate -s-1 ~/temp #  kesti 10 ms


Mutta täytyy myöntää ettei skriptin toiminta ole moitteetonta sillä jokainen käyttökerta lisää viimeisen rivin loppun jotakin vaikka näennäisesti kaikki lisätty poistetaan eikä editorissakaan näy mitään - ilmeisesti olisi toinen viikkojen pituinen etsintä löytää käsky jolla se lisätty poistetaan.

***

Olen aina inhonnut sitä kun jostain asiasta väitetään ettei BASH osaa sitä - sillä en ole löytänyt yhtään sellaista ongelmaa johon ei löydy aikanaan ratkaisua - ihan toinen asia on että ratkaisua joutuu useinkin etsimään kuukausia - ratkaiseminen on niinkuin palapeli johon löytyy palasia kauan - ja vaikka asiaa ei tietoisesti edes ajattele niin palapeli lymyää jossain aivonperukoissa - ja sitten omia aikojaan ratkaisu selviää kuin itsestään. Tosin siitä löytämisestä ei ole mitään varsinaista hyötyä sillä BASH on päästetty niin pahaan kuntoon ettei sitä korjaa koskaan enää mikään määrä virtuooseja - mutta saahan onnistumisesta sentään paljon mielihyvää.

Mutta noita palapelin osia ei kukaan pysty kokoamaan pelkästään omista tiedoistaan sillä BASH on niin laaja ettei edes kaikkia sen käskyjäkään kukaan voi hallita täysin: esimerkiksi tuon äskeisen käskyryhmän palasia kokosin netistä vuosia sillä siinä on kolme 'ratkaistavaksi mahdotonta' ongelmaa - ja ilmeisesti siis neljäs pitäisi vielä löytää. Muuten useimmat löytyneet palaset olivat jopa yli parikymmentä vuotta vanhoja - ei oikeastaan ihme sillä silloin käyttäjät alkoivat paeta BASH:ista.

nm

  • Käyttäjä
  • Viestejä: 16250
    • Profiili
Vs: Skriptiajuri
« Vastaus #50 : 30.12.23 - klo:23.23 »
Toimintanopeuksia tosi-suurella tiedostolla:
Koodia: [Valitse]

cat ~/temp | tail -1                                                                                           #  kesti: yli minuutin
truncate -s-1 ~/temp; echo -n "¤" >> ~/temp; a=$(timeout .001 tac ~/temp); echo ${a%%¤*} ; truncate -s-1 ~/temp #  kesti 10 ms

Miten olisi:

Koodia: [Valitse]
tail -1 ~/temp

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #51 : 31.12.23 - klo:02.38 »
Oletpa oikeassa, sotkeuduin taas lahkeisiini. Taisi ylirasitus iskeä ja poistun lepäämään ainakin joksikin aikaa. Silti vielä: BASH:hissa on grep:in tai regex:in kaltaista nopeaa hakua, mutta kuitenkin ihan erilaista:
Koodia: [Valitse]

function etuosa () { apu="${1%%$2*}"; echo ${apu##* } ;}        # tulostaa ensimmäisen löydetyn edessäolevan
# tai: function etuosa () { apu="${1%$2*}"; echo ${apu##* } ;}  # tulostaa viimeisen löydetyn edessäolevan
# tai: function etuosa () { apu="${1%$2*}"; echo ${apu#* } ;}   # tulostaa koko välin ensimmäisestä viimeiseen löydettyyn
                   
etuosa "unten siivin luoksesi hiivin
        suutelen silmäsi uneen
                         
        vartiopaikalla suorana seisten
        kirjoitan nimesi lumeen" kal 
     
- siis 'ensimmäisen löydetyn edessäolevan' tapauksessa: kal on se mitä etsitään - tulostuu: vartiopai
- pitää määrätä hakutermi oikein tai saa tyhjää käskystä. Siis määritä haku näin:
  etuosa "keke roosberg syöksyi mutkaan nopeudella 235 km/t" " km/t" # näin löytyy tuo 235 - huomaa välilyönti hakutermin alussa.

--- tai:
Koodia: [Valitse]

function takaosa () { apu="${1##*$2}"; echo ${apu%% *} ;}        # tulostaa ensimmäisen löydetyn perässäolevan
# tai: function takaosa () { apu="${1#*$2}"; echo ${apu%% *} ;}  # tulostaa viimeisen löydetyn perässäolevan
# tai: function takaosa () { apu="${1#*$2}"; echo ${apu% *} ;}   # tulostaa koko välin ensimmäisestä viimeiseen löydettyyn
                                                   
takaosa "kun mä kuolen sadetakkini sä saat
         sillä olen varma että
         pilv1enpääl ei sada vettä
         huh hah hei ja rommia pullo" "ma "
- tulostuu:että . Ja "a " tuostaa:pullo . Ja ma*sa tulostaa:da .  Ja: [0-9][iest] tulostaa:npääl. Kaikki niinkuin pitäisikin.
- huomioi että * ylittää sekä välilyönnit että rivinsiirrotkin.
« Viimeksi muokattu: 01.01.24 - klo:00.21 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #52 : 03.01.24 - klo:11.34 »
- tiedostosta lukeminen tapahtuu näin:
Koodia: [Valitse]
   takaosa "$( < /boot/grub/grub.cfg)" BE # tulostuu: GIN . Tai kun on syytä olettaa että etsittävä löytyy 100:lta ensimmäiseltä riviltä jättikokoista tiedostoa:
   takaosa "$( head -100 ~/tmp)" aa
- eivät nämä BASH-toteutukset vastaa nopeudeltaan läheskään sitä mihin esimerkiksi käsky:grep kykenee eikä näistä luultavasti nopeita saakaan. Eikä ilman kirjastoja näistä saa helppoja käyttääkään. Mutta jos kirjastoja käyttäisi niin grep jäisi monipuolisuudessa toiseksi sillä näistä voi räätälöidä hieman erilaisia versioita vaikka kuinkapaljon - aikaisemmin tuntemattomiinkin tarpeisiin. Tuntuu yhä enemmän siltä että virtuoosit ovat keksineet BASH:ille vaikeuksia ettei se kilpailisi sed:in, awk:in, grep:in ja muiden semmoisten kanssa.       

***

Tai jos funktion halutaan tulostavan kaikki löydetyt niin funktio voidaan tehdä rekursiiviseksi. Näillä 'nopeilla käskyillä' rekursio on nopea joten nopeus-tappio on pieni. Tässä tulostus-suunta on viimeisestä ensimmäiseen mutta pienellä koodimuunnoksella sen saisi muutettua ensimmisestä vimeiseen. Esimerkiksi:
 
Koodia: [Valitse]


function takaosa () { apu="${1##*$2}"; apu=${apu//\"}; echo ${apu%% *}; [[ "${1%$2*}" =~ $2 ]] || return; takaosa \""${1%$2*}"\" "$2"  ;}

takaosa "ma1ma2makolme ma4 ma5
ma6

 ma7
ma8 ma9
ma10" ma

Tulostuu:
10
9
8
7
6
5
4
kolme
2
1

***

Tiedostosta etsittäesssä vain kutsu kirjoitettaisiin eritavalla:
Koodia: [Valitse]
function takaosa () { apu="${1##*$2}"; apu=${apu//\"}; echo ${apu%% *}; [[ "${1%$2*}" =~ $2 ]] || return; takaosa \""${1%$2*}"\" "$2"  ;}
takaosa "$( < /boot/grub/grub.cfg)" B

tulostuu:
 
EGIN
e
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN


- etsintä siis huomioi kirjainkoon joten sillä siellä on keran Be
- koetapa:  takaosa "$( < /boot/grub/grub.cfg)" b

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #53 : 05.01.24 - klo:13.45 »
Tällä kertaa tarkoituksena on muuttaa edellä esitetty rekursiivinen versio tavalliseksi - siis tavallaan tehdä uudestaan - ja usein kun skriptn tekee täysin uudelleen niin se samalla yleensä yksinkertaistuu ja nopeutuu - ellei mähli:
Koodia: [Valitse]
function takaosa () { apu="$(echo ${1//\\n/ })"; while [[ "$apu" =~ $2 ]]; do apu="${apu#*$2}"; echo ${apu%% *}; done ;}
takaosa "$( cat /boot/grub/grub.cfg)" B
tulostuu:
EGIN
e
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN
EGIN

- löytyneistä ensimmäinen on tekstin alustapäin ja viimeinen lopustapäin.
- EGINIT tulevat sanoista BEGIN. Yksinäinen e tulee siitä että tiedotossa yksi lause alkaa: Be
- haku voidaan kirjoittaa myös: 
Koodia: [Valitse]
takaosa "$(readarray -t a < /boot/grub/grub.cfg; echo "${a[@]}")" B   
- hakuaika putoaa kolmasosaan kun hakutermiksi kirjoitetaan pieni b - vaikka löytöjä tulee neljäkertaa enemmän - olen äimänkäkenä siitä mikä tuommoisen voisi aiheuttaa. A/a on vähän toistapäin.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #54 : 06.01.24 - klo:19.39 »
Kun pakolliset rinkulat on nyt tehty niin pistetäänpä vauhtia masiinaan (siis toiminta oli: etsitään tekstistä jokainen haettava ja tulostetaan yksinomaan niiden sanojen loppu jossa haettava on
- siis tulostetaan välilyöntiin tai rivinloppun asti):
Koodia: [Valitse]
function takaosa () { for word in ${@:1}; do [[ "$word" =~ $1 ]] && echo ${word#*$1}; done ;}
# kutsut ovat kirjoitusasultaan: sana:takaosa haettava_teksti teksti_josta_haetaan
# -   rivinsiirrot sallitaan. Silloin teksti täytyy laittaa heittomerkkien väliin:
time takaosa ma "ma1 kkk kkkma2 ma3 ma4jjjjj gggggma5
ma6 ma7 hhhhma9ppppp ma10 xyz ma11 ggggma12"
- tai mikäli kyse on tiedostoon kijoitetusta tekstistä:
Koodia: [Valitse]
time takaosa B $( cat /boot/grub/grub.cfg)
- 'nopeisiin käskyihin' perustuvat skriptit ovat pienissä etsintätehtävissä nopeampia kuin sed-awk-grep-regex toteutukset  mutta mutta vähänkin isommissa etsintätehtävissä ne ovat hitaampia ja isoilla tiedostoilla jopa yli kymmenenkertaa hitaampia - mutta 'nopeista käskyistä' tehty skripti tarjoaa sellaista mikä muille olisi mahdotonta tai ainakin hyvin vaikeaa - ja 'nopeista käskyistä' tehtyä skriptiä voi tästäkin räätälöidä edelleen mihin tarkoitukseen tahansa. 

- myös grep+regex on varsin pätevä tallaisiin toimiin - mutta muistihirviö-skriptaajienkin täytyy opiskella sitä tosikauan ennkuin alkaa sujumaan. Eikä noiden muidenkaan skriptikielten soveltaminen yksinkertaista ole.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #55 : 09.01.24 - klo:12.39 »
Nyt alkoi selvitä miksi BASH on siinä tilassa kuin se on kun luin Ruotsin liikennekaoksesta, Norjan suojelupoliisin varoituksista jne jne. Asiat tiedostetaan ja konferensseja pidetään - mutta itse ei varmasti tehdä mitään eikä anneta toistenkaan auttaa vaan kielletään kaikkia tekemästä mitään sillä siitähän seuraisi että saattaisi joutua johtamaan koko hommaa joten viini, laulu ja naiset täytyisi unohtaa. Vastuuta pakoillaan vaikka ulkopuoliset selväsanaisesti sanovat että katastrofi on jo muodostunut.

Samasta syystä väitetään esimerkiksi ettei BASH tunne desimaalilukuja? Tämän aasin-sillan kautta pääsen selvittämään desimaalilukujen vertaamista taas kertaalleen mutta tälläkertaa  matemtiikkamoottorin avulla - se '$((1+2))' - sillä mikäli joskus tekisi BASH-skriptin matematiikkaa varten tulisi sen vertailu-funktion olla tosinopea - bc:t ja muut voit unohtaa sillä vertailun täytyy olla tehty jo ennenkuin ne edes aloittavat. Ja 'nopeilla käskyillä' tehdyt skriptit ovatkin tosinopeita vaikka niissä olisi monia tai vielä useampia käskyjä.

Lukujen vertaaminen kannattaa tehdä matematiikkamoottorilla sillä se on paljon nopeampaa kuin tekstijono-vertailu - niin nopeaa ettei sitä saa mitattuakaan - ja myös desimaaliluvut täytyy hyväksyä mutta koska matematiikkamoottori ei hyväksy desimaaleja täytyy lukujen kokonais- ja desimaaliosat verrataan erikseen. Silloin toiminta on seuraavanlaista:

1. Kaikki muu kuin numerot, miinus-merkki ja desimaalipiste poistetaan - tai mikäli desimaalipiste on viimeisenä niin sekin poistetaan. Kokonaislukujen miinus-etumerkki laitetaan muistiin mutta etumerkkiä ei poisteta. Desimaaliosien loppuun lisätään nollia niin monta että ne ovat 18 numeroisia sillä desimaaliosien vertaaminen ei mene oikein ellei molemmissa desimaaaliosissa ole numeroita yhtämonta.
2. Mikäli kokonaisluvut ovat yhtäsuuret tulee lopputulos yksinomaan desimaalien vertaamisesta. Desimaalien vertaamisessa täytyy huomioida kokonais-osien etumerkkit.
3. Mutta jos kokonaisluvut eivät olleetkaan yhtäsuuria niin vertailutulos tulee yksinomaan kokonaislukujen vertaamisesta. Etumerkit huomioidaan automaattisesti.

Tämmöisistä täytyy ehdottomasti olla funktio kirjastossa sillä hermothan tämmöisiä väsätessä menee, aikaa haaskaantuu ziljoonaan kokeeseen ja sittenkin sielua jää kaivertamaan tieto siitä että ihan varmasti jotakin on jäänyt huomioimatta tai että on luonut sellaisen skripti-hirviön ettei pysty enää hallitsemaan sitä ... :
Koodia: [Valitse]

function onkoekasuurempi () { luku1=${1//[^-.0-9]/}; luku1=${luku1%.}; luku2=${2//[^-.0-9]/}; luku2=${luku2%.}; [[ ${luku1//[^-]/} ]] && m1=- || m1=''; [[ ${luku2//[^-]/} ]] && m2=- || m2=''; (( 10#0${luku1//.*/} == 10#0${luku2//.*/} )) && { desimaalit1=${luku1//*./}000000000000000000; desimaalit2=${luku2//*./}000000000000000000; (( $m1${desimaalit1:0:18} <= $m2${desimaalit2:0:18} )) && echo 0 || echo 1 ;} || { (( 10#0${luku1//.*/} <= 10#0${luku2//.*/} )) && echo 0 || echo 1 ;} ;}

onkoekasuurempi 12345679012345678.12345679012345678 12345679012345678.12345679012345678
onkoekasuurempi .1 0.1
onkoekasuurempi 1 .1
onkoekasuurempi 1 1
onkoekasuurempi +1 1
onkoekasuurempi -1 -1
onkoekasuurempi -1 1
onkoekasuurempi 1 -1
onkoekasuurempi 1.9 1.89
onkoekasuurempi 1.000000000000000001 1
onkoekasuurempi 2. 1.   # tai: onkoekasuurempi 2$ 1$ tai: onkoekasuurempi 2km/t 1km/t ...
- sekä desimaaliosat että kokonaisosa saavat olla 0 - 18 numeroisia, desimaalipilkku saa olla tai sitten ei ja verrattavat luvut voivat olla pelkkkiä numeroita tai niissä saa olla mukana mitähyvänsä lukuja tarkemmin määrittelevää tekstiä.
- tuleeko mieleen presedenssi kun antaa käskyn: luku=${luku//[^-.0-9]/} -> ei toimi jos kirjoittaa: luku=${luku//[^.-0-9]/}. Että yksinkertainen kieli?
- muuten esimerkiksi: onkoekasuurempi 6-2 4 -> 0 . Kokonaislukujen miinuslasku siis toimii mutta taitaa olla viisainta jättää muu matikka tässä yhteydessä pois.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #56 : 11.01.24 - klo:09.47 »
Funktion onkoekasuurempi lyhyempi versio osaa 'laskea' 32 numeron tarkkuudella 0.5 millisekunnissa. Silti lasku kuulunee skriptilajiin 'party trick' sillä eihän tämmöistä uskalla nykyään käyttää - mutta silloin kolmekymmentä vuotta sitten tämä olisi ollut kova juttu. Ja tiedähäntä mitä tästä saisi jalostettua - aikanaan se olisi kovastikin kannattanut mutta ei taida kannattaa enää tänäpäivänä. Tämä taas sarjassamme 'kummallisia sattumuksia'.
Koodia: [Valitse]
function onkoekasuurempi () { luku1=${1//[^-.0-9]/}; luku1=${luku1%.}; luku2=${2//[^-.0-9]/}; luku2=${luku2%.}; [[ ${luku1//[^-]/} ]] && m1=- || m1=''; [[ ${luku2//[^-]/} ]] && m2=- || m2=''; (( 10#0${luku1//.*/} == 10#0${luku2//.*/} )) && { desimaalit1=${luku1//*./}000000000000000000; desimaalit2=${luku2//*./}000000000000000000; (( $m1${desimaalit1:0:18} <= $m2${desimaalit2:0:18} )) && echo 0 || echo 1 ;} || { (( 10#0${luku1//.*/} <= 10#0${luku2//.*/} )) && echo 0 || echo 1 ;} ;} 
onkoekasuurempi 1234567890123456*1234567890123456 1524157875323881726870921383936 -> tulostaa 0 niinkuin pitäisikin
onkoekasuurempi 1234567890123456*1234567890123456 1524157875323881726870921383937 -> tulostaa 1 niinkuin pitäisikin

- 1234567890123456*1234567890123456 = 1524157875323881726870921383936
- ajatelkaa BASH:in monipuolisuutta - lukujen vertaamiseen tarkoitettu funktio on samalla myös osittain pätevä laskin - tekemättä kertakaikkiaan mitään.
- kyllä muutkin luvut toimivat samoin joten saisihan tästä tehtyä monenmoista.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #57 : 12.01.24 - klo:17.39 »
BASH oli kauan sitten kunkku - se jopa koettiin nopeaksi vaikka hidashan se on aina ollut eikä sen kykyjäkään ole koskaan paljoa hyödynnetty tietokoneen hoitamisen lisäksi - mutta eivät ne vaatimuksetkaan aikoinaan kovin kaksisia olleet. Mutta sitten virtuoosit siirsivät BASH:in satuun nimeltään: kuninkaalla ei ole vaatteita. Saman-nimisessä oikeassa sadussa tarvitaan pikkupoika sanomaan että alastihan kuningas on eikä komeasti vaatetettu niinkuin virtuoosit väittävät - ja senjälkeen kaikki muutkin uskalsivat myöntää etteivät he mitään vaatteita näe. Mutta BASH on päinvastainen tapaus: siinä virtuoosit väittävät ettei BASH:illa ole vaatteita. On melkein mahdotonta että tavis väittäisi vastaan ja sanoisi että BASH:in vaatteet ovat kyllä varsin resuiset mutta sittenkin vaatteita on - sillä häntä ei joko uskottaisi tai vaiettaisiin väitteet kuoliaaksi joten väittäjältä menisi maine - mutta minun maineeni meni jo kauan sitten joten voin väittää mitävaan.

Kyllä virtuoosit puheistani huolimatta ovat mielestäni hatun-noston arvoista ja pätevää porukkaa. Sitä en tosin käsitä miksi nimenomaan BASH on heidän hampaissaan.

On totuttu mollaamaan BASH:ia tyylliin: ei BASH osaa. Ei tietenkään osaa - mutta se on näennäistä sillä kirjastoissahan ne paremmat hommat luuraa ja virtuoosithan ovat asettaneet 'kirjastokiellon'. Mutta kyllä BASH sittenkin osaa - skriptin yhteydessä olevissa funktioissa. Onpa hankalaa mutta niin virtuoosit tahtovat.

Esimerkiksi ensimmäisen asteen funktiot - on omituista ettei BASH:in yhteydessä tästäkään edistyneemmästä ominaisuudesta kerrota mitään eikä niistä oikeastaan puhutakaan missään mitään - paitsi sana siellä ja toinen täällä sillä virtuoositkaan eivät malta olla ihan hiljaa edistyneemmästä BASH:ista. Tämäkin yhteenveto on koottu ziljoonilla verkkosivuilla olleista tiedoista.

'Ensimmäisen asteen funktiot' toimivat hyvin BASH:issakin. Mutta nimitys 'ensimmäisen asteen funktiot' on hämäävä ilmaisu sillä kyseessä on tulkin kyky tulkita muuttujalta näyttävä funktio-kutsuna mikäli siinä olevan tekstijonon ensimmäinen sana on sama kuin jonkin funktion nimi - eteenpäin viittaukset sallitaan - ja pitää muuttujassa mahdollisesti olevia loppuja arvoja tuon funktion parametreina.

Tuo parametri hommeli on muuten ovela juttu: luku on aina arvoparametri ja niin on tekstikin yleensä - mutta tekstijono tulkitaan nimiparametriksi mikäli saman-niminen muuttuja löytyy skriptistä jostain paikasta, vaikka myöhemminkin määriteltynä - suokaa anteeksi virtuoosit, eihän tämmöistä saisi kertoa - esimerkiksi tässätapauksessa muuttujasta jonka nimi on:numero puhutaan vasta funktiokutsun jälkeen joten tulkin täytyy sittenkin käydä skripti läpi ainakin kahdesti. Esimerkki:
Koodia: [Valitse]
function koe () { $1 numero; echo $numero ;}       # funktion nimeltä:koe parametri $1 on tekstijono:joo joka tulkitaan funktiokutsuksi ja muuttuja nimeltään numero sen nimi-parametriksi.
function joo () { readarray $1 < <(echo 12345) ;}  # tässä funktiossa $1 on nimiparametri nimeltään: numero - ja sille annetaan arvo 12345. Kun on palattu funktioon: koe ja jatketaan siinä
                                                   # olevan skriptin suoritusta välittömästi kutsu-paikan perästä ja tulostetaan muuttujan nimeltä:numero arvo käskyllä: echo $numero.
# annapa käsky:
koe joo 
# jolloin tulostuu: 12345
- siis vasta kääntäjä tekee päätöksen sitä minkä merkityksen se muuttujalle milloinkin antaa - tämä on siis aivan samanlainen tapaus kuin se jossa matematiikkamoottori tulkitsee sille annetun tekstin niinkuin hyväksi havaitsee.
- kun selittää kuinka joku menetelmä toimii kannattaa muuten selittää mahdollisimman paljon - silloin selittää myös itselleen joten tajuaa paremmin onko kaikki oikein. Ja vaikka selityksestä on useimmille lukijoilla pääosa itsestään selvää niin varmasti on joku sellainenkin lukija joka tarvitsee selitystä myös niissä itsestään selvissä kohdissa - ja sieltä pohjilta ne tulevat virtuoositkin kasvavat.

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #58 : 15.01.24 - klo:18.36 »
 Olipa kerran suurvisiiri joka halusi kalifiksi kalifin paikalle - siis tässätapauksessa BASH:in paikalle. Mutta BASH oli aivan liian vahva jotta sitä olisi kannattanut haastaa. Siispä BASH:ia täytyi huonontaa paljon. Valhe on viisainta perustaa totuuteen joten kuka nämä tekikin puhui aina täysin totta mutta asetti sanansa niin taitavasti että käyttäjät älyttivät itsensä:
1. luulemaan etteivät esimerkiksi desimaalilaskut BASH:issa onnistu eivätkä siten edes yrittäneet tehdä niitä.
2. luulemaan että BASH kuuluu niihin mölleihin ohjelmiin joiden täytyy parametreja palauttaa - siis on ihan totta ettei BASH osaa parametreja palauttaa muttei palauttamisessa mieltä olekaaan.
3. hän myös häivytti desimaalilaskentaan pystyvät käskyt historian hämäriin uudella käskykannalla joka on desimaalilaskuissa tuhansia kertoja hitaampaa. Käytännössä tämä johtaisi siihen että vaatimatonkin desimaalilasku kestäisi uudella käskykannalla 10 minuuttia eikä kukaan viitsi niin kauaa yhtä pientä laskua tehdä.

Tässä on yksi desimaalilaskujen toteutus jonka sain nyt moitteettomaan kuntoon - sanotte varmaan ettei tässä mitään desimaaleja ole - johon vastaan että eihän niitä muulloinkaan ole, mielikuvahan se desimaali on (tai tieteelisemmin selitettynä: desimaali on asteikko jossa luku esitetään. Ja  asteikko määritellään numero-laskuista hieman erillään - tässä tuo printf on siinä merkityksellisin tekijä.) :
Koodia: [Valitse]
function sqrt () {
apu=$(LC_NUMERIC=C printf "%.17e\n" $1); mant=${apu%%e*};apu=${apu##*e}; apu=${apu//+0/}; apu=${apu//-0/-}; (( $apu & 1 )) && kerroin=10 || kerroin=1; expo=$(($apu/2));   
in=${mant//./}"000000000000000000"; in=${in:0:17}
sqrt=2147483648  # 2^31 
delta=1073741824 # 2^30 # tämä tulee voida jakaa jatkuvasti kahdella siten että jako menee aina tasan 
for ((i=0;i<32;i++)); do
   x=$(($sqrt*$sqrt/$kerroin))
   (( $x>=$in )) && sqrt=$(($sqrt-$delta)) || sqrt=$(($sqrt+$delta))
   delta=$(($delta/2)); (( $delta )) || delta=1  # echo $((1/2)) lasketaan nollaksi - oikein pyöristettynä se on 1
done
#echo -n 'bc:stä ';bc -l <<< "sqrt($juurrettava)" # bc ei puutu laskuihin mitenkään vaan se laskee varmasti oikean tuloksen johon verrata. Mutta kun lauseen kommentoi niin silloin ei varmasti puutu.
apu=00000000000000000000000000000000000000000000000000$sqrt'000000000000000000000000000000000000000000000';apu=${apu:0:$((51+$expo))}.${apu:$((51+$expo))}
luku=${apu##+(0)}; [[ ${luku//[^.]/} ]] && luku=${luku%%+(0)}; echo ${luku%.}  ;}


juurrettava=9;time sqrt $juurrettava
tai: juurrettava=73.456789e-3; time sqrt $juurrettava

- neliöjuuri luvuista: 4,9,16,25...1152921504606846976 esitetään aina kokonaislukuna sillä laskettaessa niiden desimaaleiksi tulee 0.
- eihän tämmöisellä skriptillä enää nykyisin tee mitään. Mutta tarkoitus onkin varmistautua taas vähän lisää siitä että puhuu asiaa väitteessä että on sössitty tahallisesti.

HUOMAUTUS: ei ääretöntä lukualuetta ole nähtävästi mahdollista hoitaa moitteettomasti: esimerkiksi lasku luvuilla joissa eksponentti oli -8 tai -9 päätyivät virheeseen - sitä pienemmät ja suuremmat luvut toimvat. Siitä nämä 'nopeat käskyt' ovat mukavia että niitä saa tulla lisää monta ennenkuin se näkyy missään joten uusittu koodi on yhtä nopea kuin vanhakin.
« Viimeksi muokattu: 16.01.24 - klo:11.57 kirjoittanut petteriIII »

petteriIII

  • Käyttäjä
  • Viestejä: 662
    • Profiili
Vs: Skriptiajuri
« Vastaus #59 : 20.01.24 - klo:17.46 »
Edellisessä tehtävässä printf:n tehtävänä on muuntaa normaalilla tavalla esitetty luku tieteelliseen esitys muotoon: x.xxxxx e yy. 'Nopeilla käskyillä' tehtynä muunnos tapahtuu noin kuusikertaa nopeammin. Ei se koodin laadusta johdu vaan ohjelmien koosta: printf on 50K järkäle ja to_sci on vajaa kilo:
[
Koodia: [Valitse]
function to_sci () { apu=$1; [[ ${apu:0:1} = - ]]  && merkki=- || merkki=''; apu=${apu//[-+]/}; apu=${apu##+(0)}; kokonaisosa=${apu%%.*};[[ ${apu//[^.]/} ]] && desimaaliosa=${apu##*.} || desimaaliosa=0; [[ $kokonaisosa ]] && { expo=${#kokonaisosa}; echo $merkki${kokonaisosa:0:1}.${kokonaisosa:1}$desimaaliosa'e'$(($expo-1)) ;} || { apu=${desimaaliosa%%[1-9]*}; ekspo=$((${#apu}+1)); desimaaliosa=${desimaaliosa:$(($ekspo-1)):1}.${desimaaliosa:$(($ekspo))}; echo $merkki$desimaaliosa'0e'-$ekspo ;} ;}
# mutta ei ääretöntä kovin nopeasti saa testattua:tämä vaatii uskomattoman monia tarkituksia - tämä on vain alkua:
to_sci 1
to_sci 10
to_sci 010
to_sci 1000000
to_sci +1000000
to_sci -1000000
to_sci .1
to_sci .01
to_sci 0.01
to_sci -.01
to_sci +.01
to_sci -0.01
to_sci -0.01
to_sci 123456789012345678901234567890123456789012345678901234567890   # nimenomaan eksponentin tulee olla oikein
to_sci .00000000000000000000000000000000000000000000000001                      # nimenomaan eksponentin tulee olla oikein
to_sci .00000000000000000000000000000000000000000000000001234567890
to_sci -123.0124
to_sci -123.0000000000123

- näillä itsetehdyillä ohjelmilla on yksi voittamaton piirre valmisohjelmiin verrattuna: jos itsetehty toimii väärin niin sitten se korjataan. Mutta valmisohjelmalle et voi mitään.
- näillä itsetehdyillä on rajoitetussa määrin jopa toivottavaakin että joskus toimii väärin: tarkoituksenahan on aivojumppa. Ei merkitse kovin paljoa sekään että onnistuuko korjaamaan toiminnan oikeelliseksi - sekin riittää että yrittää.
- on inhottavaa ja pelottavaa tehdä uudentyyppisiä kokeita - sillä aivan varmaa on että jotakin on jäänyt huomaamatta ja varmasti joskus kompastuu - ja etukäteen ei voi tietää saako vikaa koskaan korjattua. Mutta todella tuntee elävänsä.