Export historie prohlížeče: proč to dělat jednoduše, když to jde složitě?

Stala se mi – slovy klasika – takový ošklivý a skoro bych řekl zlý, nepěkná věc. Zavřel jsem si okno prohlížeče se spoustou záložek (karet, panelů) a omylem si toto zavřené okno nahradil nově otevřeným prázdným. Po jeho zavření se tak „naposledy zavřeným“ oknem stalo toto nové, prázdné a to původní bylo nenávratně ztraceno. Leda, že bych vynalezl stroj času a vrátil se do chvíle, kdy jsem tyto mé stránky měl naposledy otevřené...

A tak jsem začal bádat, jak z prohlížeče Opera vydolovat historii v nějakém rozumném, tedy strojově čitelném formátu. První myšlenka byla prohledat domovský adresář a hledat vše, co by mohlo mít co dočinění s Operou (tedy ~/.config/opera a ~/.cache/opera ), jestli tam třeba nenajdu soubor history.xml. Bohužel nic takového a googlení mě akorát přivedlo k myšlence, že něco takového dost dobře není možné. (Fail #1: V závěru se ukázalo, že to tak úplně není pravda, ale k tomu se dostaneme.)

Prohlížeč Opera je vlastně Chromium. Teoreticky by tak mnohé z toho, zde uvedeného, mohlo fungovat i v Chromiu a tudíž i v Google Chrome a snad dokonce možná i v Microsoft Edge.

Pár sekund jsem také uvažoval o tom, že by to mohl umět nějaký plugin. Prohlížečové pluginy obecně ale nemám zrovna v lásce, kromě blokování reklamy (což ovšem Opera dělá nativně), mám pocit, že jen prohlížeč zbytečně zpomalují. Navíc je to další potencionálně škodlivý (resp. děravý či napadnutelný) kód, ještě navíc přímo v prohlížeči.

Trocha Javascriptu ještě nikdy nikoho nezabila …

Navíc, možná proto jsem inspirován youtubery jako colinfurze nebo Michael Reeves (#karanténa) začal uvažovat o nějakém šíleném a bláznivém řešení. Navíc, jsem (si) chtěl ukázat, že se Tom Scott mýlí a hackovat jde stejně dobře i na Linuxu. A v momentě, kdy jsem zjistil, že historie v Opeře je jen další „HTML stránka“, bylo rozhodnuto: Trocha Javascriptu ještě nikdy nikoho nezabila! (Upřímně se obávám, že asi ano, tím si ale nekažme tuhle chytlavou frázi.)

historie v Opeře
Historie v Opeře je jen speciální stránka

Verze 1.0: vize

Moje myšlenka byla tedy jednoduchá – budu-li si chtít zazálohovat historii prohlížeče, otevřu „stránku“ historie (dostoupnou mj. pod url about://history), otevřu vývojářskou konzoli (tu vám na této stránce Opera oficiálně neumožní rozbalit, ale Ctrl+Shift+I funguje), vložím tam nějaký kus kódu, odentruju – a pár vteřin či desítek vteřin počkám. (Fail #2: Je zajímavé, že mě celou dobu nenapadlo prostě pomocí Ctrl+S celou stránku uložit a pak si ji někde v klidu zpracovat.)

Samotný kód pak měl za úkol projít celou stránku, sesbírat záznamy historie a „uložit je“. Nastala tedy otázka, jak/kam data „uložit“. Prohlížečový Javascript nemá moc možností jak ukládat data – ten nejzákladnější, tj. localStorage, se v Opeře sype do nějakých „data“ souborů kdesi v konfiguraci. Navíc bych si troufl říct, že by na této stránce ani nefungoval.

Prohlížečový javascript
Původní myšlenka byla o tom, že uživatel do prohlížeče nakopíruje nějaký kód a zmáčkne Enter

A tak jsem si řekl, že když už bude nějaký Javascriptový kód běžet v prohlížeči, proč rovnou nevytvořit jednoduchou node.js webovou službu, které bude prohlížečový skript data posílat? Taková služba pak může data sypat třeba do sqlite databáze. #Too_much_javascript_to_handle

Tak třeba by nikoho nezabilo ani trochu víc Javascriptu …

Já o pár vteřin později

Teoreticky. Pustil jsem se tedy do toho. Hned první drobný zádrhel byl, že Opera záznamy v historii zobrazuje (resp. načítá a zobrazuje nové a nové) postupně jak člověk scrolluje dolů stránkou (ne moc překvapivě). Nestačilo tak pouze otevřít stránku a vyextrahovat záznamy – bylo nutné odscrollovat postupně až dolů a nechat postupně načíst všechny záznamy.

Verze 1.1: první krůčky

Řekl jsem si, že než listovat celou stránkou úplně dolů a pak odesílat na node.js službu tisíce záznamů, mohl bych sledovat změny ve stránce a „reportovat“ průběžně všechny přidané záznamy. Pochopitelně s automatickým scrollováním, jakmile by byly všechny nově přidané záznamy bezpečně zpracovány.

Dalo se totiž očekávat, že Opera nebude úplně nadšená z toho, že někdo listuje historií až na úplné dno. Dle mých odhadů se mohlo jednat klidně o 10 tisíc záznamů (Fail #3: aktuální odhad mám cca 100 stránek za den, za rok a kousek tedy téměř 50 tisíc) a s ohledem na to, jak titěrně vypadal posuvník (scrollbar) už po prvních pár scrollech dolů, kdy jsem projel historii za poslední dva dny, dalo se tušit, že to bude záhul. (Fail #4: Při hlubším zkoumání vyprodukované databáze, jsem zjistil, že scrollování se vždy zastavilo asi na 95. dnu a další historie už se nenačítala. Podařilo se mi dohledat, že Opera si totiž pamatuje historii jen asi tři měsíce zpětně. Ve výsledku tak stránka byla asi 10x menší, než jsem očekával.)

Vytvořil jsem tedy skriptík, který monitoroval změny v dokumentu a reportoval nově přidané záznamy. S ohledem na to, že záznamy se přidávají po určitém počtu (konkrétně po stovce) a nikoliv po celých dnech, bylo potřeba sledovat i to (záznamy jednotlivých dnů Opera zobrazuje na oddělených panelech, takže přibývají jak dny v panelu posledního dne, tak i nové panely se svými záznamy).

Přidal jsem i automatické scrollování po skončení zpracování (a pro jistotou i nějaké čekání, přecijen natažení a zobrazení stovky záznamů vteřinku, dvě, pět zabere). Vše fungovalo naprosto skvěle, jen s jedním drobným zádrhelem – po asi třech odscrollováních došlo k zřejmě internal erroru v Opeře (prostě spadl kód, který měl renderovat HTML na základě dat z backendu) a stránka přestala na scrollování reagovat. Vlastně se tak trochu celá rozbila a přestala reagovat tak nějak všeobecně.

Verze 1.2: jeden krok vpřed, dva vzad

To mi docela zhatilo plány a vzhledem k tomu, že nepomohlo ani navýšení čekání (pro případ, že by šlo o souběh) či trochu efektivnější/efektnější způsob zpracování přidaných záznamů, musel jsem se s tímto poměrně elegantním řešením rozloučit.

Došlo to tak daleko, že jsem se chvíli dokonce hrabal zdrojovými kódy Opery, snažil jej zprvu debuggovat a po neúspěchu studovat, jak vyvolat načítání nových záznamů ručně, tj. bez scrollování. To se mi nepodařilo, zato jsem našel přímo modul implementující dotazování nad historií. Tedy něco, co by mi vracelo záznamy přímo jako Javascriptové objekty, bez nutnosti parsování HTML, resp. proházení stromu dokumentu!

Funguje to perfektně, až na to, že vlastně vůbec…

Bohužel, ani to se mi, zcela nepřekvapivě, nepodařilo rozchodit (povětšinou jsem byl poslán do oněch partií různými vrstvami bezpečnostní politiky) (dává to smysl, kdyby si jen tak nějaký Javascript mohl takhle hrát s interními věcmi prohlížeče, asi by prohlížeč brzo doprohlížečoval) . Koneckonců, v jednu chvíli jsem si říkal, že dost možná i proto mi můj skriptík padal – Opera zkrátka možná blokovala automatizované zpracování stránky. (Když nad tím tak přemýšlím, tak to je asi hloupost, padalo to na něčem ohledně stylů, což moc nevypadá jako úmysl.)

Dospělo to až tak daleko, že jsem chvíli koukal na stránku dokumentace k Browser History API pro vývojáře pluginů. Ani pořádně nevím, jak jsem se tam vlastně dostal, ale s ohledem na to, že jsem si plugin nechtěl instalovat jako uživatel, natož si jej přímo vyvíjet, stránku i celou myšlenku jsem rychle opustil a lehce ustoupil z mých požadavků.

Verze 1.3: Tak už to zmáčkni!

Rezignovaně jsem opustil představu, že celý problém vyřeší jedna nodej.js služba a jeden kód prostě vložený do konzole prohlížeče, a vytáhl bazuku. Sáhl jsem totiž po prográmku xdotool, který emuluje, resp. „fejkuje“ primitivní akce uživatele, tj. pohyb nebo klikání myší a stisky kláves.

Scrollování jsem tedy vyřešil jednoduchým Bashovým skriptíkem, který do svého ukončení prostě pořád dokolečka mačká Page Down (pochopitelně, opět, s nějakým čekáním). Spolu s tím jsem také z mého prohlížečového kódu vyhodil celý ten problematický monitoring stránky a prostě jej nechal staticky a jednorázově projít celou stránku a naposílat všechny nalezené záznamy.

Tohle celé jsem zabalil do jednoduchého skriptu, který:

  1. Požádá uživatele, aby otevřel v prohlížeči historii (to by samozřejmě šlo udělat jedním příkazem, ale myslím, že to celému skriptu přidává na „dramatičnosti“)
  2. Řekne mu, aby si otevřel vývojářské nástroje (opět, i to by šlo udělat pomocí xdotools, ale chtěl jsem ponechat co nejvíc kontroly uživateli)
  3. Spustí skript na scrollování dolů
  4. Jakmile stránka dojede dolů (nebo kdykoliv si uživatel usmyslí), má jej ukončit
  5. Nahodí se node.js služba, založí se databázový soubor, vytvoří tabulka
  6. Uživateli je předložen částečně minimizovaný (tj. bez nadbytečných bílých znaků) Javascriptový kód, který má spustit v prohlížeči
  7. Po doběhnutí uživatel dá pokyn k odpojení od databáze a zrušení služby
  8. Na závěr je jen pro kontrolu vypsán počet záznamů v databází a skript končí.

Nezbývalo, než to celé spustit. Všechno klapalo, dokonce i reportování node.js službě. Akorát to spadlo po pár sekundách, protože prohlížeč nedokázal udržet tolik otevřených spojení současně – XHR požadavky se totiž v základu posílají asynchronně, tedy se nečeká na dokončení předešlého a tudíž je prohlížeč chtěl poslat prakticky všechny v jeden okamžik. Opraveno a nyní už celý skript proběhl a nasbíral skutečná data. Jenže …

insufficient resources, moc současných spojení
UUUPS! Opera evidentně nezvládne víc, než pár tisíc současných spojení …

Verze 1.4: Zrychlujeme

… jenže stále tam bylo několik „ale“. Tak zaprvé, kód, který měl uživatel zkopírovat do prohlížeče, jen slepě odstraňoval nadbytečné bílé znaky. Což, jak jsem záhy zjistil, mělo nedozírné důsledky v případě, že v kódu byl někde jednořádkový komentář. V takovém případě tedy zakomentoval zbytek celého kódu. Oukej, nějakým způsobem jsem tam doplnil odstraňování jednořádkových (a když už, tak už i víceřádkových (bo minimizace!)) komentářů.

Další problém, který mě trápil, byla rychlost nahrávání. Nebylo nijak zvlášť překvapivé, že vzít jeden JSON záznam, poslat ho přes XHR na node.js server a tam ho jedním dotazem vložit do databáze bude při tisících takovýchto záznamů docela neefektivní. Přidal jsem tedy dávkové zpracování.

K mému poměrně velkému překvapení se nahrání tisíce záznamů propadlo z dvou a půl minut na 14 sekund (při posílání po 10), resp. na 6 sekund (při posílání po 20) nebo necelé tři sekundy (při posílání po 50). Musel jsem kvůli tomu ale navýšit maximální velikost požadavku na 10MB (občas bylo zřejmě některé URL příliš dlouhé) (Fail #5: zřejmě to nebylo URL, ale favicona ve formátu data:uri). Nakonec jsem tedy nechal velikost dávky na 20 (při 50 by se zvyšovala šance že node.js odmítne celý balík 50 záznamů, o které bych tak přišel).

Pak už jen drobnosti jako odpojit se korektně od databáze při ukončování, a doplnit trošku informativních výpisů (jak do konzole v prohlížeči, tak při běhu hlavního skriptu).

Mimochodem, shruba v této době (když jsem při jednom testování nechápavě zíral, proč se scrollování zastavilo na datu někdy v únoru – a dál ani krok) zjistil, že Opera si pamatuje historii jen tři měsíce zpětně. Na jednu stranu docela šok a zklamání, na druhou stranu motivace mít skript připravený k opětovnému použítí. Ale o tom pozděj, teď jedna odbočka.

Odbočka 1.1: Primitivní ale funkční

Dobře, ale – říkáte si, co se sesbíraným seznamem navštívených stránek? Samozřejmě, až budu mít sesbíraných víc záznamů, než poslední tři měsíce, půjdou dělat docela zajímavé statistiky. Od nenajvštěvovanějších serverů přes opakovaně navštěvované přímo konkrétní stránky, až po histogram návštěv různých webů dle denní doby/dne v týdnu. #Science

A nebo si vytvořit obrázek se faviconkami všech navštívených stránek. Tedy tak trochu něco jako reddit place nebo The Million dollar homepage – jen sestavené mnou samotným.

První verze faviconek
Prvotní verze stránky faviconek, ještě bez jednotné velikosti.

Koneckonců, z tohoto důvodu již úplně první verze exportéru historie pracovala s cestou k faviconám stránek zobrazených v historii. Myšlenka tedy byla jednoduchá – skript vezme vyexporotovanou databázi navštívených stránek a vygeneruje jednoduchou HTML stránku s obrázkem (faviconkou serveru) pro každý záznam z historie.

Teprve v tento moment jsem se hlouběji podíval na favicony získané z historie. Zjistil jsem, že to vlastně vůbec nejsou adresy reálných ikonek, nýbrž jen odkazy do interní cache favicon Opery. Tedy nepoužitelné. Použil jsem tedy starý trik, nechal jsem si vylistovat jen názvy serverů a ve stránce vyjmenoval všechny obrázky s URL https://SERVER/favicon.ico. Samozřejmě ne všechny takové existují (typicky třeba mnou docela často navštěvované mapy.cz) a tak se u nich pomocí alternativního textu zobrazil křížek. (Asi by šlo na jednotlivé servery poslat požadavky, ty zparsovat a získat přímo konkrétní adresy faviconek, předmětem tohoto skriptíku ale bylo jen rychlé a plus mínus funkční řešení.)

Na odzkoušení hypotézy celkem cool, ukázalo se, že to může fungovat. Ale jak pravil klasik – not great not terrible.

Odbočka 1.2: Hloupé, ale ještě funkčnější

Napadlo mě ale, že favicony by si prohlížeč zcela určitě měl cachovat. A taky, že (bavíme-li se stále o Opeře) – ano! V sqlite databázovém souboru ~/.config/opera/Favicons se nachází parta tabulek obsahující informace o faviconách. Pak už stačilo jen nastudovat si jejich strukturu a napsat stručný dotaz, který vylistuje URL favicon pro všechny servery. K mému překvapení, prohlížeč si pamatoval všechny favicony pro všechny servery v nedávné historii. (#Fail 6: Historii? Ano, cache favicon je vlastně také historie. Pamatuje si seznam navšítených adres (pro každou z nich i faviconku) a datum a čas posledního přístupu. Nevýhodou ale je, že si u každé stránky pamatuje vždy jen poslední přístup. Teoreticky by to ale jako jednoduchá strojově čitelná historie mohlo postačovat.)

Tentokrát už by mi obyčejný Bashový skript nestačil, takže jsem sáhl po Pythonu. Prostě si pro každý záznam v historii pomocí jeho serveru najde odpovídající URL favicony a tu vypíše jako obrázek. Protože ale mám k dispozici informací víc, každá faviconka je klikatelná (vede přímo na patřičnou stránku) a s popiskem (tooltipem) (titulek stránky). (Fail #7: Vzhledem k tomu, že historie a cache favicon se nacházejí v různých databázích, mám jejich „spojení“ řešené až na straně v Pythonu. Sqllite samozřejmě umí i to, pak by se skript zkrátil a většinu práce by odvedl jeden SQL dotaz. Skript by pak šel napsat i přímo v Bashi bez nutnosti Pythonu.)

faviconky!
Faviconky! (výřez!)

Tento skriptík je tedy trochu víc promakanější, ale hlavně – zobrazí favicony všechny (pochopitelně, pokud v mezičase některá nebyla přesunuta), a to včetně tooltipů a vlastně i konkrétních URL (po přejetí nad odkazem se jeho adresa zobrazuje někde dole). Jedinou nevýhodou je, že při generování musí být zavřená Opera. Databáze je pochopitelně Operou hojně využívána a je tak tímto procesem blokovaná. To trošku kazí dojem z vygenerované webové stránky, ale myslím, že přínosy jasně vedou.

Verze 1.5: budoucnost

Dobře, ale zpět k exportéru historie. Jak jsem zmiňoval, nyní už je dokončen a plně funkční, aktuálně se již jen dolaďují některé detaily, které usnadní dlouhodobější používání.

Jeden z nich by určitě mělo být nevkládání duplicitních záznamů (když budu zálohovat každý měsíc, předposlední a předpředposlední měsíc budu vždycky dvakrát). S tím souvisí, že skript by neměl vyžadovat neexistenci databázového souboru při spuštění a – nejlépe cestu k němu nemít zadrátovanou napevno, ale na vyžádání od uživatele.

Také s ohledem na zkušenosti získané tvorbou generátoru stránky s faviconkami, odebrat z exportu favicony. Je to hodnota nicneříkající a tudíž zbytečná. Obdobně, datum a čas návštěvy stránky by asi taky bylo rozumné ukládat jako datum a čas a ne jako text natvrdo vystřižený ze stránky.

Zapracovat by se dalo i na generátoru stránky s faviconkami. Například ikonky rozházet, a zobrazovat jejich velikost podle návštěvnosti daného serveru (tj. něco jako tag cloud). Nebo je prostě a jednoduše jen náhodně zamíchat.

Závěr

Závěrem bych tradičně jen uvedl odkaz na GitHub projektu (pokud odkaz nefunguje, pak ještě nebyla dokončena verze 1.5). Nepředpokládám, že by se našel někdo, kdo si jej stáhne či na něm nedejbože bude dělat úpravy.

Vlastně celý tento článek vznikl jen jako výpis strastí, se kterými se člověk může při takovém tom domácím hackování setkat. Dá se očekávát, že s prvním redesignem Opery se minimálně ta prohlížečová část celá rozsype, ale třeba do té doby nasbírám alespoň nějaké informace o mé aktivitě na internetu. A nebo třeba ne. Možná mě přestane bavit pokaždé nechat dlouhé minuty (kolik je to celkem se mi ještě nepodařilo přesně určit, celkový export jsem spouštěl vždycky přes noc) čekat, než se odscrolluje stránka s historií.

A nebo se mi podaří dopátrat alespoň některé ze ztracených záložek (stránek, panelů, karet), kvůli kterým tohle celé vzniklo. Ale musím se přiznat, že na to jsem v průběhu vývoje tohoto udělátka úplně zapomněl.

Jak jsem (nena)psal bakalářku

Jeden né zrovna veselý příběh jednoho studenta …

Jako každý třeťák mě čekala bakalářská práce. Abych pravdu řekl, určitým způsobem jsem se na to i těšil, protože jsem věděl, že budu dělat něco, co mě baví, co mám jako koníček – a ještě za to dostanu titul.

Předložil jsem mému vedoucímu práce návrh tématu, ten mi jej naprosto celý zkritizoval a navrhl mi vlastní. Kývl jsem mu na to, neboť se mi i toto téma líbilo.

Z mnohých důvodů však zde nemohu být konkrétní a zmínit přesné zadání a téma práce. Stejně tak nemohu zmiňovat moc implementačních detailů. Co však říci mohu je fakt, že se mělo jednat o webovou aplikaci vytvořenou v Javě.

Téma jak z pohádky

To byly koneckonců mé první dva požadavky – webová aplikace a to v Javě. Jako další jsem si dal za cíl, použít v práci i něco víc. V žádném případě jsem se nechtěl zařadit do skupiny těch, co opouští katedru informatiky s bakalářským titulem a tématem jako například „Mobilní aplikace – osobní trenér“. Dokonce, někoho, jehož téma zní „Implementace elektronického obchodu v PHP“ bych označil za ostudu katedry.

Ale o to teď nejde. Chtěl jsem tím naznačit, že u mé bakalářské práce bych se nespokojil s běžnými programátorskými nástroji. Mé téma proto obsahovalo nastudování si určité funkcionality (API) (když už ne téma z oblasti teoretické informatiky), se kterým se člověk moc často nesetká. A na znalosti tohoto API pak měla být vystavěna celá práce.

Samozřejmostí měla být použitelnost aplikace. Ihned po dokončení má být práce nasazena do provozu a věřím, že bude určitě používána.

Téma tedy přesně padlo do mého vzorce pro ideální bakalářku. Povím vám nyní, jaká byla má představa průběhu roku – její implementace.

„Jo, bezva, super, perfektní. Už se těším, až se do toho pustím.“

Když jsem práci dostal zadanou, předpokládal jsem, že do konce zimního semestru, nejpozději začátkem ledna, budu mít hotovou core knihovnu (tedy jednoduchou aplikaci implementující nastudované API). Dle mých odhadů a vzhledem k rozvrhu jsem si plánoval pracovat celkem volným tempem a poslední rok studia si užívat.

Letní semestr jsem počítal, že budu pracovat na webové aplikaci a vzhledem k dostatečnému množství času, i chodit do práce. Odevzdání práce jsem předpokládal s asi měsíční rezervou a poté se už jen 5-6 týdnů připravovat na státnice.

Normy plníme na 118%. Mínus 118%

Když jsem pracoval na zápočtovém projektu do předmětu Dovednosti vývojáře, ukázalo se, že podtitulem onoho projektu mohlo vcelku reálně být „menší databázová aplikace většího rozsahu“. Říkal jsem si: „Tak fajn, databázi pudu potřebovat i v bakalářce, tak to rovnou udělám jako webovou aplikaci a pak to jen upravím a budu mít ušetřenu půlku práce na bakalářce“. Dával jsem si proto na tomto projektu docela záležet.

Bohužel – můj návrh databázového frameworku nebyl úplně ideální a tak mi bylo jasné, že pro účely bakalářské práce budu muset vytvořit kompletně nový. Stejně tak, vzhledem k tomu, že jsem měl drobné komplikace s používaným webovým frameworkem, nabral jsem neskutečné zpoždění a tak i tu webovou aplikaci jsem solidně odflákl („bakalářka se nějak poddá, hlavně ať mám DOVY“).

Ve výsledku jsem tak na mé bakalářské práci začal pracovat až někdy v zápočtovém týdnu. Asi není třeba dodávat, že slovo „užívat si“ pro mě bylo vzdálené asi jako Paris Hilton a cena Grammy.

„Dobře, dodělám to  a přijdu Vám to ukázat.“ Od té doby mě vedoucí viděl jen na chodbě

Po zkouškách, které jsem nakonec nějak zázračně udělal (znáte to, čím méně se učíte, tím lépe to dopadá), jsem pokračoval v práci. Vedoucí mi mou core knihovnu opět zkritizoval slovy: „No, jako jo, pěkný, super, ale když …“. Řekl jsem mu, bylo to koncem ledna, že to dodělám, udělám základ webové aplikace a přijdu mu to ukázat. To se nakonec nikdy nestalo.

V letním semestru jsem měl poněkud nepraktický rozvrh – do školy jsem musel 3x až 4x do týdne (což je při 3 předmětech opravdu frustrující). Takže přes týden jsem byl téměř nepoužitelný. Sotva začalo pondělí, už byl pátek a já zjišťoval, že jsem neudělal téměř nic.

Web snadno a rychle!

Koncem března, se na mém facebooku objevil příspěvek, kde zmiňuji, že s dvou a půl měsíčním zpožděním mám konečně hotovou core knihovnu. Popisoval jsem ji slovy: „konzolová aplikace spustitelná pomocí sedmiřádkového příkazu o 8 parametrech, která zdá se i funguje“. Bohužel to poslední se mi podařilo o pár týdnů později vyvrátit.

V rychlosti jsem implementoval databázi a vrhl se na webovou aplikaci. Vzhledem k tomu, že jsem webovou aplikaci v Javě nikdy pořádně nedělal (a když už, tak buďto jen nějakou rychlovku – jako výše zmíněný projekt do DOVY), šlo to pomalu a nefungovalo to. Začal jsem zjišťovat, že webový framework, který používám, obsahuje opravdu spoustu chyb. Ty mě postupně tlačily do kouta –  a problémy jsem stále více a více řešil metodou: „Tak dobře, hold se bez toho uživatel bude muset obejít. Nemám čas vymýšlet, jak to udělat jinak, aby to mohlo fungovat.“.

Ale nevzdal jsem se. Nedokázal jsem si představit, že já, upocený a unavený potkám spolužáka vítězoslavně mávajícího bakalářským diplomem, na kterém je napsáno kdesi v rohu: „Implementace internetového obchodu v PHP“.

Pracoval jsem na 180%, spánek pro mě znamenalo jít si na dvě hodinky lehnout po snídani a hrnku silné kávy. (Dokážete si představit, jak jsem vypadal, když jsem zjistil, že nám káva došla?) Jakmile jsem opět narazil na něco, co nefunguje, přešel jsem do módu Hulk a nadával na celej svět.

„Dobré ráno, jdu spát“

Do toho všeho mi docházela RAM, takže počítač se začal víc než nepříjemně sekat. Pak ještě v lampičce praskla žárovka, začal blbnout mobil a asi týden jsem se potýkal s bolestí zad, protože se mi zlomila počítačová židle a já si musel zvykat na máminu.

Stavy zoufalství a vzteku se střídaly asi jak nálady bejvalky v období rudého klína. Do toho všeho jsem pozoroval i zoufalé obličeje mých nejbližších, kteří jediné, co mohli, tak smutně konstatovat: „Kéž bych ti tak mohl(a) nějak pomoct …“. Bohužel, zde byl i můj vedoucí práce v koncích (a to je na celé katedře na toto téma největší – pravda, jediný – odborník).

Zpočátku jsem všem v okolí říkával: „Mám tam tak na minimálně dva měsíce práce a za 4 týdny mám odevzdávat.“. Přemýlal jsem nad tím, jestli je možné, abych to mohl stihnout. Ne. Začal jsem uvažovat o tom, že to nestihnu. Začal jsem se s touto představou smiřovat. K dobru mi mělo být, že v tom nejsem sám. Z mých kamarádů nevím asi o nikom, kdo by šel v řádném termínu.

A co kdyby to byla pravda?

Vedoucí práce to přijal s pochopením. Znovu objevuji, jaké to je být vyspaný, umytý a opět zjišťuji, že kolem mě jsou nějací lidé. Doháním studijní agendu (fajn zjištění, že máte za tři dny odevzdávat index).

Velmi pomalu se začínám učit na státnice. Mám na to tři týdny. To snad zvládnu. V lepším případě začnu po večerech připravovat bakalářku na změnu frameworku.

A tak mi v tuto chvíli nezbývá než doufat, že to všechno nějak vyjde. Že jak tam přijdu, tak si nevytáhnu zásobníkové automaty. A nebo II. normální formu. A že ti, co ví naprosto přesně jak se implementuje e-shop v PHP poznají hněv docenta Vychodila při otázce: „Víte vy sakra vůbec, co je to append?“.

Moje další utilitky, především v Javě

 

Upozornění: Stále vyvíjím různé prográmky, aplikace a knihovny. Jen už neudržuji tuto stránku aktuální. Sledujte můj github!

Co vám budu povídat – prostě jsem přešel na Javu. Ale fak to už asi víte. Kromě větších (ze školních například Ročníkový projekt) prací si občas v Javě vytvořím i nějakou tu (konzolovou, samozřejmě) utilitku, která je moc složitá (nebo se mi s ní zkrátka nechce pitvat ;-)) na Bash nebo C. Tady je najdete, ke všem dodávám pochopitelně i zdrojové kódy:

Simple XML Breaker

Tento program vznikl pro účely testování ročníkového projektu a jeho ošetření možného chybného vstupu – XML souboru s daty (s uloženou hrou). Na výběr máte několik možných útoků (například odstranění náhodného řádku, vložení nesmyslného atributu nebo celé značky).

Simple XML Breaker zdrojové soubory

Simple XML Breaker spustitelný jar

 

plain2beamer

Mívám ve zvyku si psávat poznámky jako odrážky do běžného textového souboru, jen tak ve vimu (otevřít vim je pro mě záležitost asi 5 kláves). Nyní jsem však potřeboval sestavit LaTeXovou prezentaci v beameru – právě z těchto poznámek. Tak jsem si řekl, že začnu používat jednotný styl pro psaní těchto mých poznámek, které pak tímto programem přeložím do *.tex souboru, který poté mohu vysázet do *.pdf prezentace.

Například, dostal jsem přiděleno zorganizovat oslavu strýčkových narozenin. Sepsal jsem si tento seznam poznámek, který jsem si programem plain2beamer přeložil do tohoto texovského souboru a ten si nechal vysázet do úhledné pdf prezentace, kterou mohu prezentovat na některé schůzi organizačního výboru.

Původní verze:

plain2beamer zdrojové kódy

plain2beamer spustitelný jar

Verze 2.1 (a novější, pokud kdy bude):

Na githubu. Pozor, má trochu jiný formát (viz github).

Druhák na UPOLácké informatice: „Vydrž, Prťka, vydrž!“

Opravdu – s několikaměsíčním zpožděním jsem se konečně dokopal k sepsání mých studijních zážitků za další část mého studia. Dlouho jsem totiž přemýšlel, jak tento článek nazvat, aby bylo jasné, jak tvrdé období to mám za sebou.

Pokud vám někdo bude tvrdit, že Olomoucká informatika je lehká, dejte mu facku. Pokud bude tvrdit, že je těžká, dejte mu ji taky. Ve druháku se totiž potvrdilo, to jsem tušil už od několikátého týdnu v prváku.

Olomoucká informatika není ani lehká, ani těžká. Ona je, řekl bych, náročná. To ovšem neznamená, že strávíte tři čtvrtě zkouškového pod hromadami skript a knih. A to nejen proto, že na velkou část našeho učiva skripta vůbec nejsou a knížky leda v angličtině. Na něco takového na informatice prostě nenarazíte. Sice ano, bez učení to prostě nejde na žádné škole, ale na informatice nejde o to, kdo toho kolik umí, ale jestli tomu rozumí. Dokonce mě až překvapilo, kolikrát jsem od zkoušejícího slyšel něco ve smyslu: „No, dobrý, dobrý, vy to sice moc neumíte, ale vidím, že tomu rozumíte, podejte mi index, A“.

Nicméně pro mě osobně byla zkoušková období odreagovačka. Těšil jsem se na ně víc než malý Honzík na Vánoce. Krušné byly totiž oba semestry jako takové.

Třináctitýdenní peklo

To, že budu muset zase začít dělat domácí úkoly, s tím jsem se smířil již v prváku. Tehdy mě ale nenapadlo, že díky nim nebudu mít čas na nic jiného.
Můj denní režim vypadal opravdu tak, že jsem vstal, vcelku jedno kdy, sbalil se, šel do školy, tam vytáhl notebook a dělal úkoly než mi začala nějaká výuka. Úkoly jsem dělal i o pauzách mezi hodinami, a ještě klidně i pár hodin po skončení poslední hodiny. Když mě to přestalo bavit, nebo mě ze školy začali vyhánět, šel jsem domů, najíst se, pokusit se opět pracovat a následně padnout hlavou na klávesnici. Množství zkonzumované kávy a energetických nápojů vzrostlo (obzvláště  v letním semestru) o několik tisíc procent oproti obvyklému množství. Každý den jsem stříhal metr a počítal týdny a dny, kdy už to konečně skončí.

Když už jsem měl školy opravdu plné zuby, dělal jsem zápočtové úkoly do „Webové prezentace“ nebo „Základy tvorby webových stránek“

Druhák se totiž stal ročníkem „B předmětů“, tedy povinně volitelných. Pro nás aplikované, kteří jinak byli více tlačení do programování, byla většina předmětů teoreticko-informatických právě jako B. Takže nám těch povinných (ty, co byly na pomezí teoretické a aplikované informatiky) už pak moc nezbylo.

Já, který se o teoretickou informatiku zajímám, jsem si pozapisoval pár těchto předmětů. Avšak spolu s nimi pochopitelně i ty programátorské. Mezi nimi jsme měli na výběr ze tří jazyků – C++, C# a Java a pro hodně odvážné předmět PRCL (hodně pokročilé „Programování v Common Lispu“).

C++ jsem měl po oba semestry zapsané jako předmět, který budu v případě nouze odepisovat jako první. Nicméně díky téměř nulové absenci a nějaké té aktivitě v hodinách jsem tak dostal oba zápočty za účast, bez nutnosti vypracovávat nějaký projekt. Na předmětu se mi ale líbilo, jakým způsobem byl jazyk C++ odlišován od jazyka C, neboť všichni tyto dva velmi rozdílné jazyky ztotožňují.

Kurz C# byl strašný. 90% hodin, pokud vůbec byly, tak vyučující trávil proklikáváním se ve Visual Studiu a nebo vysvětlováním, že pole se indexuje od nuly. Tak, jak jsem C# nikdy neměl moc rád, tak tento dvousemestrální kurz mi ho znechutil ještě více. Každopádně vedlejším produktem ze zimního semestru byl můj zápočtový projekt, „hra“ Tamagoči, jedno malé bezvýznamné plus.

Poslední z vyučovaných jazyků byla Java. Doktor Krajča má ve zvyku být na studenty tvrdý a nemilosrdný, takže každý týden úkol na několik (ne-li desítek) hodin byl samozřejmostí, takže jej absolvovalo jen pár vybraných studentů (a to většinou ti, co odmítli dělat ročníkový projekt v C#). Kromě toho, že jsme byli seznámeni se spoustou praktických „funkcí“ (vlastní Swing komponenty, databáze, základy reflections API, …), tak jsme byli také silně tlačeni do kvality kódu. Což při porovnání kódu ročníkového projektu studenta, co ho psal v Javě, a toho, co ho psal v C#, bylo značně poznat.

Definice, věta, důkaz

Z předmětů teoretické informatiky bych rád zmínil Algoritmickou matematiku 3. Ta navazovala na 1 a 2 a znalosti rozšiřovala o obecné záležitosti ohledně složitostí a návrhu algoritmů. Celkem na pohodu a praktický předmět, doporučuji.

Paradigmata programování 3 byl předmět zpočátku velmi těžký, ale kdo jej nevzdal, dostalo se mu spousty moudrých rad a mimo jiné jsem – alespoň já – pochopil, proč do nás celý prvák vlastně tak intenzivně valili Scheme a Lisp (a proč je Lisp na katedře tak oblíbený).

Jeden z nejděsivějších předmětů za celý ročník bylo bezpochyby Paralelní programování. Kdo se už někdy setkal z vícevláknovými aplikacemi, vůbec se nebude divit, proč se tomuto předmětu říkávalo „Paranormální programování“. Svou koncepcí předmět tak trochu připomínal Počítačové sítě. Přednášky tak trochu o ničem, nebo jen teoretická příprava na zkoušku a (alespoň já) jsem se málokdy chytal. Na cvičení po nás chtěli něco vypracovávat, opět – téměř nikdo nevěděl, nestíhalo se, přetahovalo se, protože co se nestihlo na hodině, to znamenalo přijít o cenné body k zápočtu. Oba předměty jsem tak měl započteny s odřenýma ušima, ale obě zkoušky naopak dopadly celkem dobře. Každopádně jsem rád, že oba tyto předměty už uvidím až před státnicemi.

Odvahu na Matematickou logiku a Geometrii pro informatiky jsem nesebral (byť tyto předměty víceméně každý, kdo se neřadí mezi ty, co jsou rádi, že ještě studují, nějak udělal) a tak jsem zůstal jen u Geometrického praktika. Spolu se zápočtem jsem si odnesl také znalost programování v OpenGL a rozpracovanou 3D bludišťovku, na které nadále pracuji a bude brzy vydána.

Když už jsme u těch teoretických předmětů – nemůžu opomenout noční můru všech (především aplikovaných) informatiků – Formální jazyky a automaty. Znal jsem základy, vyznal se v matematických předpisech, byl si vědom důležitosti znát přesně definice a vůbec – učivo jsem z velké části chápal, ale i přes to jsem jak zápočet, tak zkoušku (díky drobnostem, samozřejmě) udělal tak tak. Paradoxem je, že spolužáci, kteří nadávali od půlky první přednášky, že se to nedá, studenti, kteří se na škole sotva drží a které měl tento předmět vyfiltrovat, ho tak nějak udělali téměř v pohodě (s o několik stupňů lepší známkou než já).

Kredity budou stačit

Ve výsledku nás tak měly Formální jazyky a automaty spolu s Operačními systémy 1 (které jsem udělal nějakým zázrakem, protože jsem absolutně neměl čas vypracovávat (ne povinné, ale silně doporučené) úkoly z cvičení) a Ročníkovým projektem důkladně profiltrovat, neboť se nás do druhého ročníku probojovalo až moc. Nevím, zda-li se tak podařilo, to se asi uvidí až příští rok, až budou tyto předměty opakovat, ale obávám se, že úspěnost studentů byla vysoká. Takže nás budou sekat na něčem letos.

Já jsem díky bohu zvládl předměty všechny, a žádný jsem si nakonec neodepsal nebo nevzdal. A jsem za to rád. I když vím, že jsem rok žil jen školou a spánkem, vím, že mi to něco dalo. A věřím, že 85 kreditů je adekvátní ohodnocení vynaloženého času a úsilí.

 

Sakra, jak já to dělám?

To se i já divím. Další semestr, další zápočtové, další zkouškové mám za sebou a vše z toho úspěšně.

Jako vždycky jsem si našel chvilku, abych vám popsal, jak probíhal předchozí semestr a vše s ním spjaté.

Informatická propedeutika 2, tedy standartní bloková výuka hned v prvním týdnu byla pro nemoc zrušena a to včetně zápočtového úkolu. Nicméně kredity zůstaly zachovány. Chudáci ti, co si ji nezpsali. To ale byla asi jedna z posledních dobrých zpráv na následujcí týdny.

Kromě propedutiky jsem měl také zapsané všechny ostatní B předměty (povinně volitelné) doporučené na zimní semestr druhého ročníku, takže rozvrh jsem měl opravdu nabitý. Ve škole sice jen 3 dny v týdnu, ale to téměř bez přestávek od rána (dopoledne) až do pozdního odpoledne, či večera.

Ze začátku semestru jsem hodně bojoval s Paradigmaty programování 3. Makra mi moc nesedla, (díky nim jsem taky dostal ze zkoušky B), trávil jsem nad úkoly do tohoto předmětu značnou část svého volného času. Poté už to celkem ušlo, člověk se naučil, že pokud programuje příklad a má víc než 4 řádky, nemá cenu v něm pokračovat a může ho rovnou smazat, protože by byl určitě špatně.

Když jsem nějak dohnal bodový skluz s Paráči (a že to byl opravdu boj), vrhnul jsem se na Ročníkový projekt. Neměl jsem moc čas studovat rozdíly mezi možnými variantami zadání (konkrétně impmentance deskových her Dameo, Fríská Dáma, Hawajská Dáma nebo Parašutistická Dáma), tak jsem sáhl hned po prvním. Jazyk implementace pro mě byla jasná volba – Java.

V porovnání se zbývajícími dvěma jazyky (C# a C++), které jsme měli na výběr (Common Lisp neuvažuji), jsem věděl, že právě Javu budu umět po absolohování semestru ze všech nejlíp. Na C++ jsem věčně dělal, že něco dělám, což se mi vrátlo formou zápočtu za aktivní účast, a na C# jsem se chodil akorát vyspat po náročném dni nebo, pokud jsem se na to zmohl, programovat úkoly do Javy.

V Úvodu do progrmaování 3 – Java jsme totiž opravdu proletěli velmi praktické věci (ano, pravda, vědět, že v C# se pole indexuje od nuly je taktéž velmi praktické ;-)) takže tvořit v ní pak slušný ročníkový projekt opravdu nebyl problém.

Nehledě na to, že vyučující neznal slova hezčí než: „No, to ujde“, „To je hnus“, „Todle je na poblití“, „a todle rači ani nečtu“ a navazoval tak na tradici předmětů Paradigmata programování, které si kladly za cíl učit nás slušnému programování.

Java logo
Ano tento šálek kávy mi dal opravdu značne zabrat

Jako další významný předmět bych jmenoval Počítačové sítě. Předmět, kterého jsem se opravdu velmi obával. Na síťařinu jsem nikdy nebyl, takže při životě mě držely mé (základní) znalosti o počítačových sítích ze střední. Na přednášky chodilo jen pár lidí, kteří poté měli Javu (a ani z daleka ne všichni), na cvičeních, byť byla zadání online, nikdo nic nevěděl, svépomocí jsem se ale nějak dobojoval k zápočtu.

Na zkoušku jsem se učil několik dní a s tím, že tak na třetině otázek mě vyhodí, u třetiny mu něco řeknu a tak na necelou jednu třetinu otázek jsem si i věřil. Vytáhl jsem si otázky z třetiny druhé a odcházel jsem s C.

Algoritmická matika byl také poměrně dobrý předmět. Začaly se brát více teroreticko-informatické záležitosti, více do algoritmů. Ze začátku to bylo super, celkem jednoduché učivo aplikované na mě známých problémech (Problém batohu, Dijkstrův algoritmus, …) přednášek jsem chápal, na cvičení se chytal. Ke konci jsem však na přednáškách spával a cvičení opouštěl v půlce, takže byla příprava na zkoušku o to těžší. Tahal to ze mě až z paty, ale prý jsem to chápal, každopádně A mě velmi překvapilo.

Třešničkou na závěr byla úplně obyčejná Matematika 2. Celou dobu semestru byla na cvičeních totální nuda, víceméně opakování ze střední, na tabuli jsem oči zvedl tak dvakrát za přednášku, prostě nuda. Bohužel na zkoušce jsem si vytáhl učivo poslední přednášky na které jsem pro jistotu nebyl vůbec a které jsme na střední brali jen tak okrajově, natož abych si pamatoval vzorečky a znal definice, takže jsem opakoval. Aby toho nebylo málo, na druhý pokus jsem si vytáhl naopak otázky skvělé, ale našel v mých znalostech par děr a tak jsem mírně smutný odcházel s C.

Díky množštví B předmětů byl můj rozvrh chudý na C (nepovinné) předměty. Pokračoval jsem tak pouze v SWM2 předmětem Sowtare pro matematiky 3, který jsem z půlky strávil přetahováním cvičení ze sítí a z druhé děláním něčeho, jakože aby se neřeklo. Na zápočtu po nás chtěl vyřešit nějakou složitější diferenciální rovnici, což nakonec dopadlo tak, že jsem zkopíroval jeho ukázkový kód a jen jej upravil.

No a o Webové prezentaci jsem se již rozepsal ve zvlášť článku Sedím na SLO/WP a strašně se nudím….

Jak říkám, po dobu semestru, a vůbec téměř do teď jsem neměl téměř volný čas, v podstatě pořád jsem dělal něco do školy, a když ne, pracoval jsem na Ročníkovém projektu. Byl to záhul, ale stálo to za to. Něco jsem se naučil, nasbíral jsem plno kreditů a teď vzhůru do nejnáročnějšího semestru za celé bakalářské studium.

Moje nová hra! Bludišťovka Anny’s Lab

Když jsem se letos (rok 2012) někdy koncem června vrhl na C++ s tím, že se jej přes prázdniny naučím, ať toho nemám poté v zimním semestru moc, opět jsem plánoval jaký to větší projekt si v něm napíši. Původně jsem si chtěl reimplementovat knihovnu clmg (Common Lisp Micro Graphics) sloužící k jednoduché grafice na základě objektové struktury, kterou jsem používali v Předmětu Paradigmata Programování 2.

Logo Anny's Lab
Logo Anny’s Lab

Ale přecházet z okenního rozhraní do klasického textového terminálu není u grafické knihovny úplně to nejideálnější a tak mi z clmg zůstala jen třída Point. Poté jsem si k ní začal dopisovat další tři třídy a bludišťovka se pomalu začala rýsovat.

Pod původním názvem Labyrinth tak začala vznikat obyčejná konzolová bludišťovka pro večery na chatě, kde nemám internet, nebo na přednášky, kde internet obvykle mám, ale zase mi většinou nestačí baterie notebooku na nějaké náročnější grafické hry.

Postupem času mi název Labyrinth přišel poněkud nevhodný a obyčejný (i když se zpětně zamyslím nad názvy Drag race a Předměstí Simulátor, nebylo by to nic neobvyklého). Vzhledem k tomu, že postavička, která se v labyrintu pohybuje je reprezentována zavináčem, vznikl návrh na zakomponování nějakého jména začínajícího na ‚A‘ do názvu programu. Když jsem hledal vhodný  znak, kterým se budou vykreslovat zdi, mi ze spousty znaků, které jsem zkoušel, padlo do oka velké písmeno W, které až náramně připomíná nějakou rostlinu nebo keřík.

Naštve
Naštve

A bylo jasno.  Mí skalní fanoušci navíc totiž ví, že do každého svého programu zakomponovávám nějakou osobu ženského pohlaví z mého okolí. A není proto divu, že předmětem kampaně Anny’s Lab se stala bioložka Anny pracující ve své laboratoři, které se poněkud přemnožil zmutovaný a geneticky upravený jinak úplně obyčejný trávník, který podobně jako v pohádce o Šípkové Růžence zaroste celým areálem (a vytvoří tak labyrint, kterým se musí Anny dostat ven). Od té doby jsem Anny’s Lab nenazýval jinak, než „Anča a Lenča“.

Kampaň je však jen jedna z mála funkcí, kterou Anny’s Lab nabízí. Celá hra je vlastně založená na tom, že se zvolí tzv. číslo labyrintu, podle kterého je poté labyrint náhodně vygenerován. Můžete tak hrát téměř nekonečný počet různých náhodných a pseudonáhodných labyrintů, různých velikostí a uspořádání.

Jednoduchý labyrint
Labyrint s jednoduchou strukturou

Vzhledem k tomu, že hra byla komplet vyvíjena na platformě GNU/Linux, je linuxu přímo šita na míru. Naopak na Windows s ní byly nemalé komplikace. Bohužel právě proto si nebudete moct pořádně užít hru Anny’s s použitím knihovny ncurses, kdy se hra vůbec neseká, každou klávesu nemusíte potvrzovat Enterem a dokonce se setkáte i se skromným barevným provedením.

Program používá starou knihovnu z MS DOS, kterou však na Windows za boha neseženete, zatímco na Linuxu ji nainstalujete jedním příkazem.

Střeva programu

Program je sice oficiálně psán v jazyce C++, já osbně bych spíš použil označení C/C++. Když jsem totiž chtěl načítat stisknuté klávesy bez potvrzování Enterem, vygooglil jsem funkci getch() z knihovny ncurses. Jenže tato knihovna byla určená pro jazyk C a nikoliv C++, takže většina vstupně-výstupních operací je realizována funkcemi jako printw a getch, držel jsem se standartu a kde nebyla použita knihovna ncurses, používal jsem funkce z knihovny cstdio – printf, getchar  a podob.

Čistého času jsem na Anny’s Lab pracoval něco kolem dvou a půl měsíce, kde z toho jsem ale fyzicky pracoval v průměru tak hodinu až dvě denně (to víte, prázdniny). Asi vás nepřekvapí, že nejvíce času padlo na jádro celé aplikace – metoda třídy Map na generování labyrintu.  Chtěl jsem být profesionální a najít si nějaký slušný algoritmus na generování. Tato diplomová práce věnující se přesně této problematice  mě však pouze přesvědčila, že opravdu nejlepším řešením bude úplně obyčejný hloubkově rekurzivní algoritmus typu „horník“.

První hra
První dohraná hra (17. srpna), můžete vidět tuny ladících výpisů

Nicméně pořád jsem je v reálném čase nedostal na Labyrint větší než 800×800. A bylo mi naprosto jasné proč. Ta metoda, která se starala o průchod jedním uzlem je sice na pochopení velmi jednoduchá, ale implementačně poněkud složitější. Neustálé kopírování konstantních parametrů a vytváření stále nových proměnných, jako iterační proměnná i na začátku každého volání zkrátka zbytečně žerou obrovské množství času.

Začal jsem tedy vzpomínat na cvičení z algoritmiky, jak přepsat hloubkovou rekurzi. Nejdřív jsem si ji přepsal použitím fronty na průchod do šířky, dokázal jsem generovat labyrint až do velikosti asi 12000×12000, nicméně vypadal jak hvězdice se středem ve startu. Po několika dnech intenzivního algoritmování jsem na to přišel.

Na zásobník si bude ukládat vždy čtveřici uzlů, do kterých se vydat (v pospřeházeném pořadí), také uzel, ze kterého se do tohoto „aktuálního“  došlo a ukazatel (index i), kterým z těch směrů se má nyní vydat. Pokud došel do validního uzlu, vytvořil si posloupnost s ním sousedících, spolu s ní na zásobník uložil bod, ze kterého tam došel, a index prvního z nich, načeš se do něj hned vydá. Pokud validní uzel nenašel, šel na další v pořadí (zvýšil index aktuálního uzlu o 1) a pokud další takový nebyl (byl poslední), odebere tuto celou skupinu ze zásobníku a jde o úroveň výš.

Toto řešení je taktéž celkem elegantní (obzvlášť, když je v C++ zásobník implementován ve standartní knihovně), a především velmi efektivní. Paměť mi většinu dojde, až když se snažím generovat labyrint větší než 14000×14000.

Až nebudu mít týden co dělat, nakoupím energiťáky, nachystám si rozvoz pizzy na rychlou volbu, vygeneruju si labyrint 10000×10000 a budu hrát…

Zbytek už byl celkem hračka. Až na pár drobností, jako třeba metoda, která k uzlu vrátila některý náhodný sousední uzel tak, aby ležel na mapě. Nejdřív jsem se snažil testovat, jestli není moc blízko okraji mapy, ale kraje mapy jsou 4 a navíc se můžou kombinovat (rohy), takže po asi 20 řádkách testování a ifování, jsem skončil tím, že jsem náhodně vygeneroval některý z okolích bodů (na to stačily 2 řádky) a to opakoval, dokud se tento náhodný uzel nenacházel v mapě.

Docela mě překvapilo i parsování argumentů z příkazové řádky. Když jsem si uvědomil, jako všelijaké kombinace chybných stavů můžou nastat, sáhl jsem až na dno kapsy a vytáhl výjimky a díky nim se kód rozrostl o pouhých 240 řádků.

A úplně zabilo, když jsem vlastně poprvé tvořil program rozdělený do více souborů (což jsem poněkud nešikovně dělal úplně nakonec), a vůbec to nechtělo fungovat. Nedošlo mi, že se soubory (a tedy i bloky funkcí celého programu) na sobě sice závisí, ale víceméně řetězovitě a ne každý na všech ostatních. Takže soubor s deklaracemi maker je naprosto nezávislý a tak jde zkompilovat rovnou. Na něm závisí soubor s deklaracemi všech funkcí, na něm pak definice pomocných funkcí, díky ní pak půjdou zkompilovat třídy Point a DrawabePoint, … až přes definice hlavních, „jaderních“ funkcí (a z nich ta úplně nejhlavnější – Hlavní Menu) až po samotnou funkci main.

Pak už stačilo jen napsat Makefile (a dva dny řešit, proč to nelinkuje knihovnu ncurses, ikdyž ji jistojistě inkluduji), zabalit, zkompilovat i na Windows (i to byla celkem estráda) no a napsat to, co si nyní čtete.

Ke stažení

Ke stažení dodávám jak zkompilované verze pro MS Windows, tak i balíčky zdrojových kódů pro obě platformy.

Anny’s Lab Verze pro Windows 32bit (.exe)

Anny’s Lab Verze pro Windows 64bit (.exe)

Kdo má koule na labyrint 5000x5000?
Kdo má koule na labyrint 5000×5000?

Anny’s Lab je totiž distribuován pod licencí GNU/GPL a je Open Source, tedy je volně ke stažení včetně zdrojových kódů.

Zdrojové kódy Pro Windows (Přibalen soubor pro Microsoft (c) Visual Studio)

Zdrojové kódy Pro Linux (Přibalen Makefile)

Ty předkládám především pro uživatele operačního systému GNU/Linux – v programu je přibalen také Makefile a tak si jej prostě zkompilujete pomocí programu make.

Pokud nemáte nainstalovanou knihovnu ncurses, musíte programu make říct, že Anny’s Lab funkce z ncurses nemá používat a to:

Nebo zakomentováním řádku

v souboru declarations.cpp. Více o používání knihovny v souboru COMPILATION a v hlavičkových komentářích souborů declarations.cpp a main.cpp.

 

 

Projekt do PROG2 – Parser aritmetických výrazů

Když jsem si předmět Programování v jazyce C pro fyziky zapisoval, věděl jsem, že bude zakončen poměrně rozsáhlým projektem. Ale když mi přišlo zadání, poněkud mi přeběhl mráz po zádech. Jako nejjednodušší byl označena hra Labyrint (bludiště je v textovém souboru, algoritmus najde nejkratší cestu), z dalších zadání bych jmenoval ještě Piškvorky, Lodě nebo kecálka Karla.

Příznakem „Dle mého osobního názoru asi nejtěžší“ bylo značeno zadání programu, který měl jako vstup textový řetězec reprezentující matematický výraz a jako výstup tento výraz ve formě stromové struktury. Samozřejmě, nějakým lidským způsobem reprezentovaný.

Tak jsem se pousmál, protože o vlastním parseru aritmetických výrazů sním už od dob, co jsem začal programovat a teď jsem měl konečně příležitost. Řekl jsem si tedy Challenge accepted a začal přemýšlet jak na to. V zadání byl sice návod na nejjednodušší postup, ale trvalo mi asi týden než jsem jej pochopil. Jeho filosofie spočívala v tom, že výraz je tvořen nějakým termem (jeden „sčítanec“), symbolem +/- a případně dalším (pod)výrazem. Je to tedy rekurzivní definice, a když se nad ní zamyslíme, zjistíme, že se vlastně jedná o lineární spojový seznam termů (kde každý term má příznak, jestli se k předchozímu přičítá nebo se od něj odčítá).

Velmi obdobně je definován i onen term – je to součin nebo podíl faktoru s dalším termem. Vyvrcholení nastává při definici faktoru – tedy činitele / dělitele / dělence. Tím může být obyčejné číslo, záporné číslo (v mé reprezentaci obecně funkce), nebo výraz v závorce. Kde pojmem výraz je myšlen opět ten výraz výše.

Krásně je z těchto definic poznat, že jejich rekurze může být ukončena pouze číslem, což nám poté umožní výraz jednoznačně vyčíslit (kromě jeho vypsání a případného vymazání z paměti). Pokud si toto uvědomíte, a nebojíte se pointerů, hloubkové rekurze a předávání odkazů na globální proměnné odkazem je pak implementace hračka.

Opravdu hračka. De facto celý program jsem zvládl za necelý den. Ve skutečnosti výraz a term jsou implementačně velmi podobné (liší se akorát tím, jestli jsou tvořeny termem a výrazem nebo formem a termem), takže je stačilo jen zkopírovat a upravit pár řádků. Nicméně kód tak narostl na přibližně 500 řádků. I já jsem zíral. 500 řádků plných pointerování, a práce s globálním indexem a já jsem to stihl za necelý pátek. O tom, že jsem komplet celý program tvořil v C write’n’run ani nemluvě. Ideální způsob, jak se naučit používat základní vimové příkazy, jako GG nebo / či :%s/foo/bar/g.

Jenže. To byl opravdu základ. Chybělo sice už jen dodělat funkčnost funkcí (s těmi jsem si vyhrál – byly totiž reprezentovány ukazateli na funkce) a ošetřit syntaktické chyby (a varování) vstupu.

Moje první idea byla, že pokud při parsování některého elementu dojde k syntaktické chybě (například 4+*6), vrátí jen jeho první část a to, počínaje chybou bude ignorovat. Až jsem to měl hotové, tak nějak jsem si uvědomil, že to je stejně pitomost. Přece, když je výrazu chyba, tak je ve výrazu chyba. Může to být překlep, ale co když není? Tento algoritmus prostě z chyby udělal varování a opravil ji tím nejjednodušším způsobem. Tím se však výraz stal nekonzistentní, tedy špatný. Takže jsem tam prostě nacpal, že jakmile narazí parser na chybu, nekompromisně vrací NULL s tím, že i procedura která ji volala, pak automaticky také vrací NULL, a tak to probublává až na samotný výraz, který se tím pádem také stane NULL.

Z původního algoritmu mi však ve funkcích na výpočet, vypsání a vymazání zůstaly testovací podmínky na testování konzistence výrazu, tak jsem je tam nechal (i když tam nemají význam).

Několik dní mi pak zabrala snaha vyřešit kontrolu parity závorek. Původní idea byla taková, že přibude další globální proměnná, nazvaná zanoření závorek – z, na počátku inicializovaná na začátku na nulu. Při začátku parsování faktoru „výraz v závorce“ se měla zvýšit o 1 a po dokončení opět snížit. Pokud na konci parsování celého výrazu byla hodnota větší, než 0, nebyla některá závorka uzavřena, a tak se program tvářil, jakoby byla na konci, ale pokud tam byla nějaká uzavírací navíc, tak ji měl přeskočit.

Ale jak chce odchytávat uzavřenou závorku u výrazu, který není výraz v závorce? Nijak. To by prostě nefungovalo. Řešením tedy bylo přesunout obsluhu uzavírající závorky do samotné funkce parsuj_vyraz, do míst, kde se testuje právě nalezený znak. Jenže tím bych totálně zabil přehlednost kódu. Při představě, že otevírání a zavírání závorky jsou každé na úplně jiném konci a v úplně jiné části kódu. Ale ani po mnoha dnech jsem nevymyslel ideální řešení, ale alespoň jsem tu obsluhu rozbil na aplikační a uživatelskou část. Aplikační jsem ponechal přehledně při parsování výrazu závorce (stará se jen o inkrementaci a dekrementaci proměnné z), zatímco uživatelskou jsem tedy rozházel po celém kódu, což už mi nepřišlo tak nehumální, neboť se tak ztratila mezi ostatními chybovými a varovnými hláškami celého programu.

Doufám, že vám program půjde zkompilovat (panu profesor s tím měl na Windows menší problémy). Po zkompilování si jej, linuxáci, můžete hodit do třeba do /bin a pokud si jej lehce zmodifikujete (tady dodávám mou, odevzdávanou verzi, nijak neupravenou), můžete jej volat třeba

nebo například

který vám samozřejmě ten_slozitej_vzorecek vyčíslí pro x=14.5.

V plánu mám po vzoru z Paradigmat programování 2 (kde jsme něco podobného dělali objektově v Lispu) vytvořit si program na parsování výrazů s proměnnými a derivování/integrování (případně další operace s funkcemi jako tabelace hledání inflexních bodů), přičemž na to asi použiji přecejen C++. Uvidím, jestli bude čas.

 

Nainstalovat (Linux)

Stáhnout zdrojový kód

Druhé zkouškové? 10:0 pro mě!

Ano, opravdu to znamená, co si myslíte. Nevím, jestli to bylo nějakým zázrakem či co, ale opravdu je to tak. I v letním semestru prvního ročníku studia Aplikované informatiky na Přírodovědecké fakultě Univerzity Palackého jsem prospěl se 100% úspěšností.

Po semestru, který byl opravdu teror, kdy jsem počítal dny, když už to konečně zkončí to zkončilo a přišel vytoužený odpočinek – zkouškové (možná se smějete, ale za malý moment vás vyvedu z omylu). Vraťme se tedy zpět k onomu třináctitýdennímu utrpení.

Jak jse mohli dočíst ve článku Hon na Céčka, tento semestr jsem měl opravdu nabitý. Začnu těmi hlavními předměty. Algoritmická matematika 2 dá se říct navazovala na jedničku. Braly se tam takové zajímavé věci jako základy teorie grafů a stromů, odkud se přešlo až po různé binární vyhledávací stromy a vyvrcholilo to hashováním. Doktor večerka po nás obšas i chtěl aby jsme na cvičeních něco dělali, ale do dalšího ho to obvykle přešlo, takže jako vždy pohoda (a když ne, stačilo říct: „Já vim, já si jenom tady todhle dodělám au ž jdu na to.“). Zápočtový test a úkol jsme víceméně všichni tak nějak udělali (mé poněkud neodpovídající hodnoty v úkolu jsem svedl na vadný algoritmus funkce <code>rand();</code>, podobně jako minulý semestr) a vzhůru na Bělehrad!

Tedy k panu profesoru Bělohlávkovi do kabinetu. Na první termín vyhodil prolovinu lídí po první větě, protože nedokázali přesně formulovat nějakou definici. I na dalších termínech takto pár lidí vyletělo, nicméně já mezi nimi nebyl. Já si vytáhl otázky, které mi nepřišly moc těžké. Ale znáte to – myslíte si to, jak to umíte, ale najendou jak na vás profesor promluví, všechno z vás najednou vyteče vašim podpažím a víte, že je zle. Neřekl jsem snad nic kloudného, zachránilo mě asi jen to, že jsem to celkem chápal (a po podobných zážitcích z minulého semestru bych řekl, že ke mně cítí určité sympatie, že by Starý Jano?). Bohužel otázku za D bludišťáků jsem po**al, a tak jsem s odcházel s Poker face a E v indexu. Ale mám to (na to, že jsem se to téměř neučil).

Druhý z těch těžších předmětu byly pochopitelně Pararáče (Paradigmata (Objektového) Progrmaování 2). Že prej budeme dělat už OOP, ale protože umíme všichni Scheme (a kdo ne, měl prostě smůlu), tak jsme to dělali v Lispu. Získání zápočtu byla oproti ALM opravdu řežba. Každý týden úkol, obvykle tak na 100-300 řádků kódu, a když je to nová látka, kterou ještě navíc moc nechápete, protože jste na přednášku, která byývala v pátek na 8, přišli  o půl hoďky pozděj, protože jste pomáhali sestře s bakalářkou, nebo jste si s úctou přispali, dá vám jeden úkol zabrat i na pár dní. Nicméně já to (samozřejmě) dal vcelku s přehledem. Akorát mě trošku mrzí, že jsem orpavdu neposlechl kamaráda a poslední úkoly jsem už tak trochu hodně lajdačil.

Díky tomu jsem přišel ke zkoušce suverénně s tím, že bez A neodcházím. První 4 hodiny programování tomu opravdu nasvědčovaly. Řešení jsem měl velmi dobré, Lašťovička jen přikyvoval hlavou a nic mi nevýtýkal. Když jsem se však vrhl na události, zhavaroval jsem na jejich fatálních neznalostech (způsobených do značené míry oným zanedbáváním posledních úkolů), takže provedení bylo sice velmi dobré (což na splnění stačilo), ale funkčnost mizivá. Známku E jsem tedy zdvořile odmítl a zapsal se na popříští termín. Mezitím jsem si vypracoval nanečisto zadání dalšího termínu, na kterém jsem události asi konečně opravdu pochopil a díky tomu jsem na můj druhý termín dostal A. A A by to nebylo, kdybych všude nenaházel <code>set-events</code> a nefungovalo to díky tomu na 100%,  protože by se mi v tom začal nimrat do hloubky a něco by si tam určitě našel.

Celkem v pohodě byl taky Úvod do programování 2, pokračování veleúspěšné jedničky. Pokročilejší věci v céčku, které použijete asi 3x v životě a to jen pokud chcete někoho vytočit, že mu to ve Visual Studiu hází errory. Další způsob, jak studenta okrás to pár dní drahocenného času.

Matematika 1 taky byla celkem v pohodě. Člověk se těší, že už konečně začne derivovat, a ono zase nic. Zasekli jsme se u matic a vektorů. Aspoň už umím číst transformační matici v Gimpu 🙂 (ale asi mi je to k ničemu, protože manipulace s ní není zrovna na 10 vteřin). Zápočet za domácí úkoly vypracovávané většinou ve škole s Lukáše a Laďou v týdnech, kdy nebyla Psychologie obchodního jendání (viz dále). Na zkoušku jsem (tradičně) přišel s půlhodinovým zpožděním a díky tuně numerických chyb jsem dostal D.

Tím končí předměty povinné. Asi nejzajímavější z Céček bylo Programování v jazyce C pro fyziky. Polopatě, podrobně, nepovinně na příkladech, ale rychlostí světla (co by jste také na Společené laboratoři optiky chtěli?) se proletělo téměř, to co v obou našich Úvodech do programování dohromady. Každý týden řádově 3-5 úkolů, takže dva až tři dny práce. Ale stálo to za to. Člověk se naučil zase něco nového, jiné příklady – znáte to.  Zkouška formou většího projetku – já si samozřejmě vybral ten nejtěžší, parser aritmetických výrazů do stormové struktury a práce s nimi. Přibližně 550 řádků, asi týden a něco práce. Sice mě to spolu s PP připravilo o veškerý čas, ale ty kredity za to stojí.

Programátorská odreagovačka ve formě Softaware pro Matematiky 2, taky ušla. Stačilo jen chodit na cvičení dávat tam pozor, psát si zápisky, a před zápočtem si to projít (nebo uložit do vhodné složky v notebooku ;-)). Matlab je zkrátka šikovná věcička, jeho znalostí jsem využíval (hlavně v Matice) co chvila ;-).

Z neprogramátorských předmětů bych zmíníl „ítépéesko“ a „KGPZS“, tedy Technologie počítačových sítí  a Grafické programy, oboje na Pedagogické fakultě. Zápočet z ITPS byl hodně o nervy – ještě aby ne. Když strávíte jedno a půl odpoledne odpovídáním na otázky „Stiskem jaké klávesy potvrdíme provedení příkazu Ping?“ a pak zjišťujete po všech čertech, jestli se odpovědi tutorovi, odeslaly, jestli je schválil či ne, a jestli tedy máte zápočet nebo ne. Nakonec jsem získal z každé kapitoly v průměru 130% bodů a šel jsem na abcd test. Asi jsem měl smolný den a těch pár věcí, kterými jsem si nebyl úplně jistý, … no zkrátka potupa jak blázen, dostal jsem E. Mé první E a to ze snad nejjendoduššího předmětu.

O Grafických programech vám toho moc neřeknu, protože blokovou výuku (1 přednášku) jsem zazdil a tak jsem akorát vypracovanou seminární práci poslal dle zadání na internetu (logo v svg a design webu v rastru). Aspoň už vím, jaké to je shánět někoho, o kom ani nevíte jak vypadá. Pět kreditů opravdu, ale opravdu zadarmo. A ještě jednou opravdu.

Předmět Evropská integrace pro studenty PřF se mi tedy moc nelíbil. Celou dobu otravné kecy o Evropské Unii, nuda, takže většinou programování úkolů do Programování pro Fyziky. Nedostatek zásuvek, pouze vepředu jich bylo požehnaně, ale když jsem pak vysílením (a samozřejme s úctou) usnul, byl jsem vzbuzen přednášejícím, jak do mě šťouchal prezenčkou. Ke všeobecnému veselí přispěl výrok, že mám na čele otisklý touchpad, ikdyž to byl jen rukáv od mikiny. Dva kredity a nazdar.

Nechci říct to nejlepší na závěr, ale Psychologii obchodního jendání bych rozhodně negativně nehodnotil. Člověk si užil zábavy a navíc se naučil něco sakra užitečného. Ani nevíte, jaké jsem měl na zkoužce z ALM nutkání pozvat pana profesora na kávu, jakožto první řešení při styku se zákazníkem na pokraji sil, který posílá zakoupený produkt už počtvrté na reklamaci. Nyní si dávám víc záležet na prvním dojmu, pozoruji postoje osob v mém okolí a snažím se jejich jednání přizpůsobovat.

Sečteno podtrženo, 10 podpisů v indexu, za celý ročník 17, a kreditů rovných 70. No to je skvělé, není to skvělé? Myslím, že to, že jsem 13 týdnů téměř nežil za to celkem i stojí.

Stačí vám to? Tím dneska končím. A jdu na jedno. To se přeci musí zapít, ne?!

 

 

Moje prográmky III (C*)

Po veleúspěšných dílech Moje prográmky I – Pascal a Moje prográmky II – Delphi příchází Moje prográmky III, s nyní už trochu rozsáhlejšími a v rodině jazyka C (C a C++) psanými prográmky.

A protože jsem fanda linuxu a tak nějak se mi nechtělo oficiálně distribuovat svoje kódy, tak jsem vytvořil Samorozbalovací instalátor pro Linux. Z následujícího rozbalovacího seznamu si pouze vyberete požadovaný program, stáhne se vám skript, kterému pouze nastavíte práva a spustíte a on se už o vše postará:

Instalátor má i nápovědu, volá se standartními přepínači:

Nainstalovat program:

 

Samozřejmě zde ovšem dodávám mou oblíbenou tabulku všech programů, jako vždy s krátkým popiskem funkce onoho programu.

Generátor mocnin dvojky

Výstupem jsou soubory s binárním, hexadecimálním a především dekadickým zápisem čísla 2EXP, kde EXP si volíte a v závislosti na vaší výpočetní kapacitě se může pohybovat klidně v řádech desetitisíců.

celý článek

 

Pascalův trojúhelník, binomická věta, kombinační čísla

Program využívá zajímavých vlastností Pascalova trojúhelníka a díky nim snadno mimo samotný trojúhelník může vypisovat také kombianční čísla a binomické rozvoje. Je obsluhován jednoduchou příkazovou řádkou.
Instalačka pro Linux ZDE
Zdrojový kód

martlin’s simple console ascii art generator 1 a 1.2

Programu jako argument předáte název bitmapy, ona vám ho vykreslí v ASCII znacích, které si také můžete zadat, nebo použije výchozí.

celý článek

 

Parser aritmetických výrazů

Závěrečný projekt do Programování pro fyziky, dá se říci pokročilejší konzolová kalkulačka. V tuto chvíli má aplikace jen minimální uživatelské rozhraní, takže je v praxi téměř nepoužitelná, slouží především k nastudování jednoho z algoritmů parsování.
Instalačka pro Linux ZDE

celý článek

 

Anny’s Lab

Velmi jednoduchá konzolová bludišťovka, napsaná přes prázdniny v C++. Program je poněkud rozsáhlejší, takže bohužel nejde použít samoinstalátor.

celý článek

 

To je zatím vše.

Paradigmata Programování 1, neboli ‚Scheme‘

Po příchodu na vysokou (tím myslím Univerzitu Palackého v Olomouci) kde, jak asi většina z vás tuší, studuji Aplikovanou informatiku. Jeden z předmětů, který se tam vyučuje, Paradigmata Programování začal asi tak nějak: „Kolegové mi říkali, že vás mám motivovat, tak jsem si tady připravl menší graf.“, řekl pan Docent Vychodil a na plátnech (tehdá ještě fungovaly oba projektory) se objevil Koláčový graf. Dle něj 75% loňkých studentů nedostalo zápočet a z těch 25%, co ho dostali zkoušku stejně udělala jen slabá polovina.

Když jsme po dvou a půl hodinách z přednášky odcházeli opravdu asi málokdo by si myslel, že by se scénář, který onen graf symbolizoval mohl naplnit. Vlastně to bylo jenom takové zvláštně zaspané počítání: třeba 10+20+30+(4*5)-1/2 by se v jazyce Scheme, o který v Paradigmatech programování šlo, zapsalo například takto: (+ 10 20 30 (* 4 5) (- (/ 2))) .

Postupně však začalo přituhovat, už na druhé přednášce začaly tuhnout úsměvy a na třetí studenti jen zoufale hleděli na prezentace (pokud ne do svých notebooků či očních víček).

Scheme je oblíbený výukový programovací jazyk. Učí se v něm programovat například studenti Bostonské univerzity, MIT, Rice University, … a také Univerzity Palackého v Olomouci.
abclinuxu.cz

Někdy kolem 22. listopadu (po dokončení HeliSim), asi týden po uveřejnění zadání, jsem si řekl, že se vrhnu ná zápočtový domácí úkol. Zmlsán kolegy, kteří si nevěděli rady ani s 5 řádkovými úkoly, které dostávali od ostatních cvičících (a posílali mi je, protože já jsem tou dobou už aktivně programoval), jsem si naivně myslel, že to také budu mít za víkend hotové.

Po dvaceti dnech, noc před termínem, jsem odesílal soubor zdrojového kódu o délce 289 řádků. Vzhledem k tomu, že se mi zrovna dvakrát nevyvedla první zápočtová písemka, musel jsem to nahnat na právě tomto domácím úkolu. Z možných 20 bodů jsem však získal pouze 13.5 bodu, neboť poslední 3 ůkoly, ty nejvíc bodované a ty, nad kterými jsem strávil asi 60% času jsem měl stejně špatně.

Ukázka programovacího jazyka Scheme
I přes mnoho komentářů je kód na hranici přehlednosti

Druhou zápočtovou písemku jsem napsal neuvěřitelně dobře, takže jsem ani nepotřeboval na opravnou – z 60 bodů jsem získal 40.5, přičemž na splnění zápočtu bylo bodů potřeba 40. Mezitím nám však řekli, že všechny zápočtové písemky, které jsme doposud psali byly proti písemné časti zkoušky med a tak jsem i já si začal říkat, že když to nedám, tak to nebude taková katastrofa.

Bohužel tak trochu nešikovně jsem si zapsal dvě nejtěžší zkoušky na 2 dny po sobě. Když jsem dal tu první, Úvod do informatiky, nemohl jsem to alespoň skromně neoslavit. Něco jsme popili, ale pak už jsem upaloval spát abych byl na Paradigmata fit. Kupodivu jsem nezaspal, a tak jsem běžel na test.

Ten, jak se poté prokázalo, jsem napsal na 96% ze 100% možných (nedivte se, na vysoké můžete bez problémů získat i 130% a to dokonce bez úplatků) a tak jsem šel (spolu s dalšími dvěma kolegy, kteří také měli víc než 71%) na kobereček k samotnému panu Docentu Vychodilovi. Ten se nás každého na něco zeptal, mě konkrétně na koerci (přetypování), a odcházel jsem s A v indexu.

Od toho okamžiku pořád někoho doučuji, učím a poučuji. Úplně nejdřív ale vznikl tento skromný manuál-příručka k jazyku Scheme, a ostatně proto vůbec píši tento článek. Mezi mými kolegy se stal velmi oblíbený, a při přípravě na zkoušky poměrně praktický.

Ale kam se hrabe nějaký student, který má A ze zkoušky na někoho, kdo má před jménem 2 tituly, a ještě jeden za ním? Tím chtěl básník říci: „Choďte na přednášky a cvičení“, jinak máte přestup z UP na ÚP v brzké době jistý.

Takže ještě jednou:

Příručka, manuál a přehled Jazyka Scheme