Paradigmata programování 2 (kombinované studium) doc. RNDr. Michal Krupka, Ph.D.
KMI/YPP2 - Paradigmata programování 2
Letní semestr 2017/18Informace k předmětu na Portálu UP.
Zadání k jednotlivým termínům zkoušky
Součástí každého řešení musí být dokumentace napsaná stejným stylem jako dokumentace k souborům k předmětu (např. 08.lisp). Řešení nemusí být úplné, u zkoušky zhodnotím, jestli stačí k udělení známky. Řešení mi posílejte mailem nebo vyjímečně přineste na zkoušku na flash disku (nikoli na svém počítači).
2. září 2019
Zadání aktualizováno 28. srpna (opraven nesprávný název souboru)Spinner je známý prvek grafického uživatelského rozhraní, sloužící k nastavení číselné hodnoty (počítadla) uživatelem. Obvykle se skládá ze dvou trojúhelníkových tlačítek umístěných nad sebou a textového pole. Kliknutí na horní trojúhelník počítadlo inkrementuje, kliknutí na dolní dekrementuje. Do textového pole může uživatel přímo zadávat hodnotu; v našem příkladě se bude zadávat tak, že uživatel klikne na číslo, tím otevře dialogové okno, do kterého pak zadá novou hodnotu. (Způsob zobrazení takového dialogového okna je popsán v zadání úlohy s inspektorem.)
Vaším úkolem je definovat třídu spinner
, která bude výše
uvedenou funkčnost realizovat, a jednoduchý testovací
program. Instance třídy spinner
bude grafický objekt,
skládající se z dvou trojúhelníkových tlačítek a volitelného
textového pole. Vlastnosti (všechny ke čtení i zápisu):
min-value
,max-value
: minimální a maximální povolená hodnota počítadla.value
: aktuální hodnota počítadla. Při zápisu je třeba kontrolovat, zda nastavovaná hodnota nepřesahuje povolené rozmezí.display-value-p
: pokud je nastavena, zobrazuje se i hodnota počítadla (číslo lze převést na text voláním(format nil "~s" číslo)
).- Volitelně můžete naprogramovat i vlastnost
value-step
: krok, o který se zvětší příp. zmenší hodnota počítadla po kliknutí na tlačítko. - Je také možné vykreslit tlačítko slabší barvou, pokud má být neaktivní (když byla dosažena maximální příp. minimální hodnota).
Spinner by měl vhodným způsobem informovat okolí (tj. vhodné objekty v okně) o změně hodnoty počítadla.
Testovací program by měl vhodně prověřit veškerou funkčnost spinneru. Mohl by například vytvořit okno, ve kterém je obdélník, jehož délka se mění podle aktuální hodnoty počítadla.
Ve svém řešení použijte soubor 08.lisp a soubory text-shape.lisp a 05_bounds.lisp k zobrazení textu.
27. a 28. června 2019
Implementujte potomka třídy window
s přidanými kontextovými (pop-up) menu. Základní funkčnost:
- Po kliknutí do okna pravým tlačítkem myši se otevře kontextová nabídka, nabízející seznam možných akcí.
- Pokud uživatel klikl na prázdné místo, v menu bude seznam grafických objektů, které je možno do okna přidat. Po výběru položky v menu se příslušný objekt na místo, kam uživatel klikl, přidá.
- Pokud uživatel klikl na existující grafický objekt (s nastavenou
vlastností
solidp
), bude v menu seznam akcí, které lze s tímto objektem vykonat. Mezi tyto akce může například patřit: změna barvy, změna tloušťky pera, vymazání objektu, případně další akce pro daný objekt specifické (u kruhu změna poloměru, u semaforu přechod na další fázi, u vlajky EU změna barevné verze na černobílou apod.).
Součástí řešení musí být dokumentace (podobně jako u příkladů řešených během semestru).
Čím více se kontextové menu bude funkčností podobat reálnému kontextovému menu (např. z Windows), tím lépe. Menu by zejména mělo splňovat následující požadavky:
- Vzhledově by mělo alespoň náznakem napodobovat menu známá z grafických operačních systémů: měl by to být svislý pruh skládající se z na sebe poskládaných popsaných vodorovných obdélníků (jednotlivých položek menu).
- Pokud uživatel klikne na položku menu, menu zmizí a provede se akce spojená se zvolenou položkou.
- Pokud uživatel klikne mimo menu (lhostejno, zda na jiný objekt nebo mimo a jakým tlačítkem), mělo by menu zmizet (a nic dalšího by se nemělo stát).
Další požadavky a poznámky:
- Jako základ použijte knihovnu micro-graphics a soubory 08.lisp a 08_text-shape.lisp. Můžete použít také další soubory s příklady, vlastní nebo moje: semafor, 07_cwa.lisp, 08.bulls-eye.lisp.
- K získávání dat od uživatele můžete použít funkce LispWorks:
capi:prompt-for-color
: požádá uživatele, aby zvolil barvu. Použití:(capi:prompt-for-color "Zadejte barvu")
capi:prompt-for-number
: požádá uživatele o číslo. Použití:(capi:prompt-for-number "Zadejte číslo")
capi:prompt-for-string
: požádá uživatele o text. Použití:(capi:prompt-for-string "Zadejte název")
14. června 2019
Definujte třídu switchable-shape
, jejíž instance
zobrazují pouze jeden, tzv. aktivní prvek.
Je to jediný prvek seznamu prvků instance (vlastnosti items
), který se při jejím vykreslování zobrazí.
Třída definuje vlastnost active-item-index
(pro čtení i
zápis) a active-item
(pouze pro čtení), které slouží k
práci s aktivním prvkem. Vlastnost active-item-index
obsahuje index aktivního prvku (celé číslo). Hodnota indexu může být také nil
; v
takovém případě se nezobrazuje nic. Vlastnost active-item
obsahuje
přímo aktivní prvek (nikoli jeho index) nebo nil
(to
pokud je hodnota active-item-index
rovna nil
).
Instance třídy switchable-shape
musí správně
reagovat na všechny zprávy, které jsou v souboru 08.lisp
definovány pro třídu, z níž třídu switchable-shape
dědičností odvodíte.
Součástí řešení by měl být i testovací program, například okno s tlačítky přepínajícími zobrazovaný obrázek. Toto okno by mohlo také zobrazovat index aktivního prvku, umožňovat jeho nastavení, umožňovat nastavování zobrazitelných obrázků apod. Ve svém řešení použijte soubor 08.lisp, případně další soubory s příklady.
Základní informace k předmětu
Předmět je věnován principům objektového programování. Použitým programovacím jazykem bude Common Lisp ve vývojovém prostředí LispWorks, Personal Edition. Studentům se doporučuje důkladně s tímto prostředím a jeho omezeními (platnými pro Personal Edition) seznámit.
Základní literaturou k předmětu je učební text Objektově orientované programování, kapitoly 1–8.
Požadavky na studenty
Průběžné výsledky studentů (chráněno heslem, sdělím na dotaz)
Během semestru studenti vypracují čtyři úkoly, zadávané postupně v následujících termínech:
Úkol | Zadání | Odevzdání |
---|---|---|
1. | 15. února | 13. března |
2. | 1. března | 3. dubna |
3. | 15. března | 24. dubna |
4. | 5. dubna | splnit do zápisu ke zkoušce |
Zadání úkolů budou zveřejňována na této stránce a diskutována během přednášek a případně na konzultacích. Řešení je třeba poslat mailem na adresu vyučujícího nejpozději ve stanovený termín odevzdání. Úkol bude vždy uznán nebo vrácen k dopracování. Splnění úkolů je nutnou podmínkou k připuštění ke standardní zkoušce. Pokud někdo tuto podmínku nesplní, bude mít obtížnější zkouškové zadání.
Témata přednášek
- 15. a 22. února: Úvod. Od Scheme k Lispu. Literatura: kapitoly 1 a 2.
- 1. a 8. března: Objekty, třídy, princip zapouzdření a polymorfismu. Literatura: kapitoly 3 a 4. Kód ke kapitolám: 03.lisp, 04.lisp. Příklady: 04_bulls-eye.lisp, 04_jp-flag.lisp. (Odkaz na knihovnu micro-graphics je dole.)
- 15. a 22. března: Dědičnost. Literatura: kapitola 5. Kód ke kapitole: 05.lisp. Příklady: 05_light.lisp, 05_flags.lisp, 05_bulls-eye.lisp, 05_bounds.lisp.
- 29. března a 5. dubna: Zpětná volání. Literatura: kapitola 6. Kód ke kapitole: 06.lisp.
- 12. a 26. dubna: Události. Literatura: kapitoly 7 a 8. Kód ke kapitolám: 07.lisp, 08.lisp. Příklady: 07_circle-window.lisp, 07_click-circle.lisp, 07_cwa.lisp, 08_bulls-eye.lisp, 08_changes-window.lisp, 08_text-shape.lisp, 08_button.lisp, 08_polygon-editor.lisp.
Zadání úkolů
Úkol 4
Termín zadání: 5. dubna, úkol splnit před přihlášením ke zkoušce
Úloha 8.10 z textu (příklad s třídou inspector-window
). Jako v
minulém úkolu musí řešení obsahovat dokumentaci pro uživatele.
Úkol 3
Termín zadání: 15. března, termín odevzdání: 24. dubna
Definujte třídu semaphore
, která bude potomkem třídy
picture
a jejíž instance budou simulovat dopravní
semafor. Dále definujte třídu crossroads
, která
bude rovněž potomkem třídy picture
a jejíž instance budou
představovat obrázky křižovatky. Své řešení
opatřete uživatelskou dokumentací ve stejném stylu jako je dokumentace v
souborech 05_light.lisp a
05_bulls-eye.lisp. (Jelikož má jít o dokumentaci
uživatelskou, dokumentujte pouze vlastnosti a zprávy určené uživateli.)
Požadavky na třídu semaphore
:
- Světla semaforu budou instancemi třídy
light
ze souboru 05_light.lisp. - Semafor bude mít nastavitelnou vlastnost
semaphore-type
s možnými hodnotami (minimálně):pedestrian
a:vehicle
. - Instance třídy
semaphore
se budou vykreslovat jako jednoduchý obrázek semaforu (správný počet koleček v obdélníku). - Semafor se může nacházet v jedné z několika fází, podle
svého typu. Např. semafor pro vozidla bude mít čtyři fáze (červená, červená +
oranžová, zelená, oranžová). Aktuální barvy světel semaforu musí
odpovídat jeho fázi. Číslo fáze bude uložené v
nastavitelné vlastnosti
semaphore-phase
. Počet fází bude uložen ve vlastnostiphase-count
. Fáze se číslují od nuly. - Pro přechod k následující fázi bude semafor
implementovat metodu
next-phase
.
Požadavky na třídu crossroads
:
- Vlastnost
items
bude nastavitelná uživatelem. Může obsahovat libovolné grafické objekty, z nichž některé mohou být semafory. - Třída definuje vlastnost
semaphores
(jen ke čtení), která bude obsahovat seznam všech semaforů v křižovatce. - Křižovatka se podobně jako semafor může nacházet v různých fázích.
Jednotlivé fáze křižovatky se budou opět přepínat zprávou
next-phase
a budou uloženy ve vlastnosticrossroads-phase
. Počet fází bude uložen ve vlastnostiphase-count
. - Fáze křižovatky určují, v jakých fázích jsou její semafory. To je zadáno nastavitelnou vlastností
program
, která obsahuje program semaforu. To je seznam seznamů. Jeho délka udává počet fází, i-tý podseznam programu určuje stav křižovatky v její i-té fázi. Každý podseznam má délku rovnou počtu semaforů v křižovatce a pro každý semafor obsahuje číslo jeho fáze. Příklad: pro křižovatku o třech semaforech a programem((0 0 0) (0 1 0) (0 2 1))
platí, že je-li křižovatka ve fázi2
, je její první semafor ve fázi0
, druhý ve fázi2
a třetí ve fázi1
.
Pracujte s načtenou knihovnou micro-graphics a načtenými soubory 05.lisp a 05_light.lisp.
Úkol 2
Termín zadání: 1. března, termín odevzdání: 3. dubna
Podobně jako v příkladech ve 4. kapitole verze textu
definujte
funkci make-my-picture
, která vytvoří nějaký obrázek. Obrázek
musí obsahovat alespoň jednu instanci každé ze tříd circle
,
picture
, polygon
a musí používat alespoň čtyři ze
zpráv set-color
, set-thickness
,
set-filledp
, move
, rotate
,
scale
.
Měla by akceptovat alespoň jeden parametr, který ovlivní nějaký
netriviální aspekt obrázku (podobně jako např. funkce make-bulls-eye
z
příkladu 4.6.7).
Vytvoření a vykreslení obrázku se pak provede
postupným vyhodnocením výrazů
(setf w (make-instance 'window)) (setf p (make-my-picture ... )) (set-shape w p) (redraw w)
Pracujte s načtenou knihovnou micro-graphics a souborem 04.lisp.
Úkol 1
Termín zadání: 15. února, termín odevzdání: 13. března
Implementujte knihovnu funkcí pro práci s rovinnými geometrickými útvary: body, kružnicemi, polygony a obrázky. Vnitřní reprezentaci útvarů zvolte podle vlastního uvážení. Používejte pouze část Common Lispu uvedenou v kapitole 2 učebního textu.
Implementované útvary a funkce:
Bod (point)
Bod je dán dvěma kartézskými souřadnicemi. Funkce make-point
, volána bez
parametru, vytvoří nový bod o souřadnicích (0,0). Funkce
x
a y
tyto souřadnice vrátí, funkce
set-x
a set-y
je nastaví a jako výsledek
vrátí tentýž bod:
(make-point) => point (x point) => x-ová souřadnice bodu point (y point) => y-ová souřadnice bodu point (set-x point 3) => point , nastaví x-ovou souřadnici bodu na 3 (set-y point 4) => point , nastaví y-ovou souřadnici bodu na 4
Bod lze dále posouvat o daný vektor pomocí funkce
move
. Funkce přičte k souřadnicím bodu souřadnice vektoru
a tentýž bod vrátí jako výsledek:
(move point dx dy) => point , posune bod o vektor (dx,dy)
Každý bod má barvu, která je vyjádřena svým názvem začínajícím
dvojtečkou (:red
, :yellow
a podobně). Barvu
lze zjišťovat funkcí color
a nastavovat funkcí
set-color
podobně jako x-ové a y-ové
souřadnice. Počáteční barva nově vytvořených bodů je :black
.
Všechny ostatní útvary musí rovněž jít posouvat funkcí
move
, zjišťovat jim barvu funkcí color
a nastavovat funkcí
set-color
. Počáteční barva nově vytvořených útvarů je
:black
.
Význam barvy útvaru nijak neinterpretujte. Jde jen o to, aby byl údaj
o barvě v útvaru uložen.
Kružnice (circle)
Kružnice je dána středem a poloměrem. Střed kružnice je bod
(tj. hodnota vytvořená funkcí make-point
), poloměr
kladné číslo. Kružnice se vytváří funkcí
make-circle
bez parametru podobně jako bod. Nově vytvořená kružnice má
střed o souřadnicích (0,0).
K dispozici jsou dále funkce na
zjištění středu (center
) a na zjištění a nastavení
poloměru (radius
, set-radius
). Funkce
fungují obdobně jako funkce zjišťující a nastavující vlastnosti
bodů. Funkce pro nastavení středu neexistuje, ale lze nastavovat
souřadnice existujícího středu (funkcemi set-x
a
set-y
aplikovanými na střed kruhu).
Jak bylo řečeno výše, pro kružnice fungují i funkce
move
, color
a
set-color
.
Polygon
Polygon je útvar, který je dán seznamem bodů – vrcholů polygonu. Nový polygon se vytváří
funkcí make-polygon
a má tento
seznam prázdný. K seznamu vrcholů lze přistupovat funkcemi
items
a set-items
. Funkce items
má tedy jeden parametr a vrací seznam vrcholů, funkce
set-items
má dva parametry (polygon a seznam vrcholů) a
vrací polygon.
Jak bylo řečeno výše, pro polygony fungují i funkce
move
, color
a
set-color
. Barva polygonu je údaj uložený v polygonu a
nijak nesouvisí s barvami jeho vrcholů.
Obrázek (picture)
Obrázek je útvar, který je dán seznamem libovolných jiných útvarů
(tedy bodů, kružnic, polygonů, případně dalších obrázků). Technicky
funguje velmi podobně jako polygon. Nový obrázek se vytváří
funkcí make-picture
a má
seznam podobrázků prázdný. K seznamu podobrázků lze přistupovat funkcemi
items
a set-items
. Funkce items
má tedy jeden parametr a vrací seznam geometrických útvarů, funkce
set-items
má dva parametry (obrázek a seznam geometrických útvarů) a
vrací obrázek.
Jak bylo řečeno výše, pro obrázky fungují i funkce
move
, color
a
set-color
. Barva obrázku je údaj uložený v obrázku a
nijak nesouvisí s barvami podobrázků.
Pokyny k vypracování úkolů
- Při opakovaném řešení úkolu zahrňte do mailu veškerou naši předchozí korespondenci o úkolu, ať vidím své připomínky.
- Řešení nepište přímo do mailu, vždy je připojte jako
soubor s příponou
.lisp
. Soubor musí mít v názvu vaše jméno a číslo úkolu. - Zdrojový kód musí obsahovat pouze definice (tedy výrazy
defun
,defvar
,defclass
,defmethod
a podobně). Jeho vyhodnocení by nikdy nemělo vést k vyhodnocení testovacích výrazů. Ty uvádějte pouze jako komentář (uvozený znaky#|
a|#
). - Zdrojový soubor musí být samostatný a musí obsahovat jen vaše řešení. Needitujte soubory, které dostáváte ode mě. Zdrojové soubory knihovny micro-graphics i zdrojové soubory k jednotlivým kapitolám textu musí zůstat beze změny, ke svému řešení je nepřikládejte.
- Soubor musí jít zkompilovat bez jediné chyby a warningu. (Kompilace se provádí volbou Compile Buffer z menu, lišty, nebo klávesovou zkratkou.)
- Kromě faktické správnosti musí úkol splňovat i základní
stylové požadavky na program napsaný v Lispu. (Velbloudí
notace, podtržítka v názvech funkcí, závorky na samostatném
řádku apod. nejsou povoleny. Názvy predikátů končí na
p
, nikoli na otazník jako ve Scheme, řádky musí být správně odsazovány atd.) - Pokud soubor není psán v čistém ASCII, musí být uložen v kódování UTF-8 (kódování nově vytvářených a otvíraných souborů lze nastavit v předvolbách; LispWorks nijak nemodifikuje kódování už existujících souborů).
Informace k průběhu zkoušky
Týden před každým termínem zkoušky bude zveřejněno zadání pro daný termín. Zadání bude mít praktický charakter, bude obnášet vytvoření programu a zpracování dokumentace. Obsahem a rozsahem bude podobné zadání čtvrtého úkolu. Každý student přijde ke zkoušce s vypracovaným řešením. Řešení nemusí být kompletní. Průběh zkoušky:
- Předvedení funkčnosti přineseného řešení a průvodní dokumentace.
- Diskuse nad řešením. Student bude navrhovat způsob úprav programu podle požadavků zkoušejícího.
- Zodpovězení teoretických otázek souvisejících s řešením.
Studenti, kteří nesplnili průběžné požadavky během semestru (čtyři úlohy), dostanou obtížnější zadání.
Odkazy
- Učební text: Objektově orientované programování. Ke zkoušce je třeba znát kapitoly 1–8.
- Knihovna micro-graphics: micro-graphics.zip.
- Lispworks Personal Edition
- Dokumentace ke Common Lispu (je také součástí dokumentace k LispWorks): Common Lisp HyperSpec
- Základní dokumentace k prostředí LispWorks (je také součástí dokumentace k LispWorks): LispWorks IDE User Guide (Windows, Mac, Linux/Unix)