Script-fu III. část - Seznamy
autor: Ene dne 23. 06. 2003
Ne, nemusíte se obávat, nebudou to ani seznamy StB, ani Schindlerův seznam. V dnešním díle si povíme něco o seznamech používaných jazykem Script-Fu(tedy GIMPem) a práci s nimi. Seznamy jsou z hlediska jazyka Scheme/LISP základním stavebním kamenem, na kterém tento jazyk staví. Dnes si ukážeme jak je vytvářet a manipulovat s nimi. A nebojte se, tentokrát domácí úkol bude ;-).
Co jsou to seznamy?
Pokud máte zkušenosti s jinými programovacími jazyky tak pro vás seznamy nebudou nic nového, v podstatě se jedná o jednorozměrná pole – vektory dat. Nejlepším vysvětlením, ale může být jen příklad, a nejlepší bude vysvětlit si to na rozdílu seznam vs. jednotlivé hodnoty :)
Jednotlivými hodnotami, respektive proměnnými s takovýmito hodnotami jsou například:
(let* ( (a 3) ) a)
(a na konci vypíše hodnotu proměnné), kdežto pokud se bavíme o seznamech, respektive proměnných ukazujících na seznam, je definice trošku odlišná:
(let* ( (a ‘(1 2 3 4 5) ) ) a)
Pokud do Script-Fu konzole zadáte první příklad, výsledkem bude 8. Pokud zadáte druhý příklad, konzole vypíše seznam hodnot (1 2 3 4 5). Tedy v prvním případě se jedná o samostatnou hodnotu, kdežto v druhém je to již seznam hodnot. Hodnoty v seznamu se oddělují pouze mezerani
Možné způsoby vytváření seznamů
Definovat seznam se dá několika způsoby. První z nich jsme si ukázali hned v úvodu, tedy pomocí syntaxe:
‘(a b c d e)
kde ‘ je apostrof, kteřý interpretru jazyka říká, že v závorce následuje seznam hodnot. Hodnoty a, b,c, d a e jsou znaky obsažené v seznamu(mohou to být znaky, slova(uzavřená do uvozovek “, čísla…). Prázdný seznam je možné definovat pomocí prázdných závorek ať s apostrofem či bez něj.
př. seznamu:
(let* ( (x ‘(”zde” (3 3 5) (”jsou” “lvi” 3 () ) ) ) ) x )
Jak jste si určitě všimli, seznam nemusí obsahovat jen jednoduché hodnoty, ale také další seznamy, v tomto případě jeden prázdný a jeden se třemi prvky. Taky si všimněte, že pro definici dalších seznamů, už jsem nepoužil apostrofu, není to již potřeba.
Definice pomocí funkce list
Pomocí funkce list lze vytvářet seznamy skládající se z daných konstantních hodnot, ale také z předem definovaných proměnných. Syntaxe tohoto příkladu je:
(list seznam_hodnot_a_proměnných)
např:
(let* ( (x 1) (y 2) (z 3) ) (list x y z 4 5 6) )
Zkuste tento kód vložit do Script-Fu konzole a poznáte výsledek(jako na následujícím obrázku).

Obr. 1. Výsledek definice seznamu
Funkce cons
Poslední možností jak definovat seznam je pomocí funkce cons, která připojí zadanou hodnotu na začátek dalšího argumentu, kterým je seznam. Na začátek seznamu se tak dá připojit i hodnota daná předem definovanou proměnnou. Syntaxe funkce je následující:
(cons 1 ‘(2 3 4) )
Výsledkem je seznam (1 2 3 4)
Pokud chceme vytvořit seznam s jedním prvkem, stačí onen prvek připojit k prázdnému seznamu:
(cons 5 () )
Práce se seznamy
Funkce cons nám naznačila jednu důležitou věc. O seznamech se v případě Script-Fu dá smýšlet jako o entitách, které se skládají z hlavy a těla. Hlavou seznamu je první prvek a tělem je zbytek. Na tomto principu je založen způsob přístupu k prvkům v seznamu.
Přístup k hodnotám v seznamu…
…je realizován pomocí funkcí car a cdr, které fungují na principu konstrukce hlavička.tělo, o které jsem se zmínil v předchozím odstavci.
Funkce car
Funkce car slouží k přístupu k prvnímu prvku seznamu tj. hlavičce. Tento seznamvšak nesmí být prázdný. Pro přístup k prvnímu prvku neprázdného seznamu tak použijeme
(car ‘(”prvni” “zbytek =>” 3 “f”) )
což vrátí “první”.Pokud seznam obsahuje pouze jeden prve, bude tento vrácen jako hlavička seznamu.
Funkce cdr
Tuto funkci můžeme použít pro přístup k tělu seznamu, tedy to co je za prvním prvkem. Pokud je v seznamu pouze jeden prvek, bude výsledkem prázdný seznam. Použijeme-li předchozího příkladu
(cdr ‘(”prvni” “zbytek=>” 3 “f”) )
dostaneme jako výsledek seznam: (”zbytek=>” 3 “f”).

Přístup k dalším prvkům seznamu
Samozřejmě lze kombinovat fce car a cdr tak dlouho, dokud nedostaneme kýžený výsledek. Například máme-li seznam a a chceme jeho třetí prvek, zápis by mohl vypadat nějak takto(bez definic proměnných):
( car (cdr (cdr a) ) )
Ale Script-Fu nám dovoluje si práci trošku ulehčit a tak můžeme stejný případ zapsat i pomocí příkazu:
( caddr a )
kde a a d jsou zástupné znaky pro car a cdr. Samozřejmě toto zjednodušení má také nějaké omezení, ale na to přijdete už sami při řešení dnešního domácího úkolu.
Domácí úkol
Tentokrát jsem si ho vypůjčil z Mike Terry’s Black belt school of script-fu. Zadání je následující: Pomocí příkazů car a cdr dostaňte ze seznamu hodnotu 3. Pokud se vám to podaří udělat jen pomocí dvou příkazů tak z vás budu mít radost.
(let* (
(x '( (1 2 (3 4 5) 6) 7 8 (9 10) ) )
)
;sem zapiště řešení
)
Výsledky, aby jste nemohli opisovat, směřujte na mne pomocí “poslat zprávu” v levém menu, políčko komu bude obsahovat cornelius ;-). Nejrychlejší vyhlásím.
Pro dnešek jsem toho na Vás vychrlil dost, takže si dáme na chvíli oddech a krom hraní si s GIMPem taky zajdeme na koupaliště když je tam tak hezky a políbíme partnery a partnerky aby na našeho miláčka GIMPika nežárlily. Příště, u našeho prvního funkčního skriptu se těším na…čtenou.
Vím že jsem s tím už otravný, ale Pozor na mezery a závorky!
Cornelius
23.06.2003 19:53 at 19:53
and the winner is: Proj :) (odpoved prisla dnes 23.6. v 10:19)
Dalsi odpovedi jsem nezaznamenal, ale pokud se jeste najde nekdo, kdo si nevsiml te krpy kterou jsem udelal dnes ODPOLEDNE pri obnove clanku(a to zobrazene reseni) a zkusil si domaci ukol udelat sam, sem s vysledkem :)
cornelius