Konec

2008-07-09 16:50 napsal Lukáš Havrlant

Tento blog stagnuje. Nic se tady neděje, a nevím, co bych tady měl psát. Původním tématem blogu byl webdeisgn a HTML. O tom už ale prakticky nic nevím. Snažil jsem se tady občas psát o osobních věcech nebo o nějakých kravinách. Ale prostě to tady nesedělo. Rubrika internet je agregována přímo na weblogy.cz, což je sice fajn, ale přespříliš lidí mi stejně nějak nesedí. Zkrátka a jednoduše řečeno, webdesignu už nerozumím, všechno ostatní je na tomto blogu OT, proto ho zavírám a zakonzervuju. A další blog už nebude. Tak. :-P

Tady ještě komentáře nechám, takže můžete vyjádřit názory ;-).

Komentáře [4]

Pro koho je určeno proc.linux.cz?

2008-07-01 14:18 napsal Lukáš Havrlant

Minule jsme dělali užitečné věci, tak dneska budeme kafrat.

Chvilkově koketuji s myšlenkou nasadit na počítač Linux. Nakonec jsem to skoro vždycky vzdal a šel jsem dělat něco zajímavého a prospěšného na Windowsech :-). Ale dneska jsem si řekl – musím se nějak donutit zkusti ten Linux. Přečtu si tedy důvody, proč bych měl Linux vyzkoušet. Heh, chuť instalovat Linux mě zase na pár okamžiků přešla. Přečtěte si to sami: Výhody operačního systému Linux. Docela by mě zajímalo, pro koho je tento seznam určen. Projdeme si to:

Moderní operační systém: Linux je moderní operační systém (OS), jehož ovládání je stejně přívětivé jako u jiných systémů a který obsahuje velké množství ovladačů pro nejrůznější standardizovaný hardware.

WinVista je také moderní operační systém, tento bod je tedy zbytečný.

Bezpečný – bez virů a spywaru: Na Linuxu není zpravidla nutné používat žádný komplikovaný zabezpečovací nebo antivirový systém.

Zde se autoři textu pravděpodobně obracejí na ty lidi, kteří zpravidla otevírají všechny přílohy v emailech, denně navštěvují hory porna (ale s příchodem redtube.com už vlastně ani na pornostránkách viry nechytnete ;-)) nebo mají počítač plný cracklých programů. Jinak nevím, kdo by ještě dnes mohl chytit vira. Za dva roky jsem na dvou počítačích (desktop a notebook) chytil pouze jednoho trojana na kolejní síti, jinak nic. Na XP používám firewall, na Vistě nepoužívám ani firewall ani antivir. Pokud bude uživatel alespoň trochu uvědomělý, jsou viry minulostí i na Windowsech (od Visty už člověk navíc defaultně nepracuje jako administrátor). Ze svého okolí vím, že problém se zabezpečením počítače mají akorát lidi, kteří mají nelegální cracklé Okna, nota bene bez SP2 a bez aktualizací. Sedm let neaktualizovaný systém a ještě se diví, že jim to blbne :-). Tento bod tedy bude stále více bezvýznamný.

Zcela ovladatelný: Linux neodesílá žádné citlivé informace bez vašeho vědomí. V naprosté většině případů systém nevyžaduje restart k projevení změn.

Koho vlastně tohle zajímá? Ani nevím, jestli mi Windows odesílá nějaké informace bez mého vědomí. Firewall na XP mi nikdy nic nezahlásil. Změny bez restartu jsou fajné, ale že by to měla být natolik zásadní výhoda, aby v tomto seznamu musela být…?

Kancelářské nástroje (Office): Mezi aplikacemi každé větší linuxové distribuce najdete kancelářský balík, tzv. office.

Na Windowsech defaultně žádný kancelářský balík není, to je pravda. Lze ale snadno doinstalovat. Tedy opět detail. Nezkušenému uživateli počítač zařizuje někdo jiný a zkušený si to tam umí doinstalovat.

Velké množství aplikací: V každé linuxové distribuci naleznete velké množství nejrůznějších aplikací – Prohlížeče internetu, přehrávače multimédií, kancelářský software, poštovní klienty, nejrůznější editory (včetně grafických i 3D), programovací nástroje (IDE, kompilátory), komunikační nástroje (ICQ, Jabber apod.), hry a další – které jsou schopny uspokojit všechny běžné potřeby při práci s počítačem. Přesto vás ale neomezuje pouze na tyto jako jediné možné, ale umožňuje vám vybrat si ty, které vám nejvíce vyhovují. Naprostá většina těchto aplikací je k dispozici zcela zdarma.

Je hezké, že nás autoři ubezpečili, že instalací Linuxu získám to, co jsem měl i na Windows. Opět nechápu, pro koho je tento bod určen. Například kterého běžného uživatele zajímá, že tam bude mít kompilátory? (Pomiňme fakt, že nikdo z nich ani neví, co to je.) Kdo kompilátor potřebuje, ví že tam je.

Variabilní a přizpůsobitelný: Linux lze výkonově i vzhledově přizpůsobit každému požadavku. Linux je možné používat na velkém množství zařízení od PDA, přes notebooky, stolní počítače až po specializované servery.

Opět další bezvýznamné chlubení. Koho by to mělo zaujmout? Pokud chci zkusit Linux na desktopu, opravdu mě nezajímá, že lze Linux použít i na serverech. Nehledě na to, že všechno z toho zvládá i Windows.

Víceuživatelský a víceúlohový: Nemusíte se přihlašovat a odhlašovat při administraci systému. Pracovat může i několik lidí najednou. Na Linuxu může existovat a pracovat velké množství uživatelů, a to i zároveň. Uživatelé mohou sdílet stejnou plochu, stejně tak jako mít svoji plochu zcela oddělenou. Při administraci systému není třeba se odhlašovat a znovu přihlašovat, i když běžně nepracujete jako administrátor. Na Linuxu může běžet zároveň velké množství aplikací od různých uživatelů.

Při vší vůli jsem vlastně nepochopil, co je tímhle bodem míněno. Pojmům „víceuživatelský“ a „víceúlohový“ příliš nerozumím. Zajímalo by mě, jak tento bod chápou lidi, kteří ví o IT ještě méně než já :-).

Vzdálená správa a použití: Na Linuxu je možné pracovat vzdáleně, a to mnoha různými způsoby.

To zní docela zajímavě. Je nějaký zásadní rozdíl mezi tímto a třeba připojením na vzdálenou plochu ve Windows?

Dostupný v češtině: Většina aplikací na vás bude mluvit česky.

No nevím, co jsem viděl Linuxy, tak většinou nebyly přeloženy úplně celé a byly tam dost chyby. U staršího Ubuntu určitě, nové jsem měl pouze anglicky, takže nevím. Každopádně Windowsy jsou v češtině celé.

Pro všechny zdarma: V podstatě všechny linuxové distribuce jsou k dispozici zdarma.

Ano, to je výhoda.

Osobně mě tento seznam spíše odradil, protože pokud bych se měl držet jen tohoto seznamu, tak jsem si zcela jistý, že bych Linuxem absolutně nic nezískal, mohl bych jenom ztratit. V podstatě mě zaujal jen ten poslední bod, a to jsem už dávno věděl. V tomto seznamu se opravdu vyskytují pouze body, které buď zájemce ubezpečují, že Linuxu má zhruba tytéž schopnosti jako Windows, ale žádný bod neupozorňuje na něco (zásadního), co by měl Linux a Windows ne. Celé mi to připomíná tu story s Aero a Berylem. Beryl existuje pod Linuxem už jistě nějaký ten čas. Ale kdy se o tom dověděl svět? Samozřejmě až ve chvíli, kdy Microsoft vyrazil s Aerem. To pak bylo na světě plno článků typu „ale to my máme už dávno a lepší!“ A zcela samozřejmě zase pozdě. Proč ty články nevznikly dřív? Stejné je to s tou stránkou proc.linux.cz.

To je na tom Linux opravdu tak špatně nebo jen nemá schopné textaře?

Komentáře [22]

Minirozšíření jdem.cz

2008-06-15 23:28 napsal Lukáš Havrlant

Docela jsem si oblíbil český web jdem.cz provozovaný Arthurem Dentem. Jen mě tak nějak vždycky na Opeře štvalo, že to pro neexistuje nějaké pohodlné rozšíření. Jakožto uživatel mám k dispozici pouze obecný bookmarklet, kterýžto má ale jednu zásadní vadu: po kliknutí se javascriptem otevře okénko, z kterého musím ručně zkopírovat odkaz a následně toto okno ještě zavřít. To mi přišlo takové neohrabané, respektive zdlouhavé. O něco lepší je rozšíření pro Firefox, ale tam mě zase nebavilo klikat na nástroje → jdem.cz → odkaz z aktuální adresy. Hmm, věčně nespokojený Lukáš :-).

A z oné mé nespokojenosti vzešel nápad udělat si vlastní jednoduché rozšíření pro jdem.cz; když už má jdem.cz přímo napsané API, tak proč ho nevyužít. Mimochodem za to API opravdu díky, respektive hlavně díky za ukázkový kód v PHP, předtím jsem tu adresu lovil přes file_get_contents, ale to nesežralo identifikátor za kanálkem #. No jo, já a PHP.

Tak tedy představuji další bookmarklet pro jdem.cz:

Zkrátit!

A teď v čem je to jiné – po kliknutí na bookmarklet se otevře stránka, kde se zavolá jdem.cz, které zkrátí adresu. Následně se tato adresa přes flash (spolehlivé javascript only řešení jsem nenašel) přímo nakopíruje do schránky a okno se navíc ještě zavře. Zde jsem ještě musel dát krátkou prodlevu, protože když jsem okno zavřel hned, prohlížeče s tím měly problémy. Čert ví proč. Bookmarklet je stejný jako originál, jen jsem změnil adresu. Možná by stálo za to to okénko ještě zmenšit. Funguje mi to v Opeře 9.50 i ve FF3; jinde netestováno.

A aby toho nebylo málo, napsal jsem si ještě uživatelský skript, který toto okénko zavolá při stisknutí klávesové zkratky. Zde je:

onkeydown=function()
{
        kldown(event.keyCode);
}

onkeyup=function()
{
        klup(event.keyCode);
}

var klshift=0;
var klalt=0;
var kla=0;

function kldown(k) {
        if(k==16) klshift=1;
        else if(k==18) klalt=1;
        else if(k==88) kla=1;
        if(klshift && klalt && kla) {
                // alert('Stisknuta kombinace ALT+SHIFT+X');
                x99=window.open('http://nastroje.havrlant.net/jdem/?q='+encodeURIComponent(document.location.href),'Jdem.cz','modal=1,status=0,scrollbars=1,toolbar=0,resizable=1,height=100,width=200,left='+(screen.width-785)/2+',top='+(screen.height-550)/2);
                setTimeout('x99.focus()',1000);
                klshift=0;
                klalt=0;
                kla=0;
        }
}

function klup(k) {
        if(k==16) klshift=0;
        else if(k==18) klalt=0;
        else if(k==88) kla=0;
}

Po stisknutí shift + alt + x se zobrazí stejné okno a do schránky se uloží zkrácená verze URL, na které zrovna jste. Původně psáno pro Operu, tu opici pro Javascript na Firefoxu nemám, takže jsem to nezkoušel. Pokud někdo chce jinou klávesovou kombinaci, nechť si skript přepíše, není to zase tak těžké.

Anebo editujte přímo soubor standard_keybo­ard.ini v profilu Opery, což je hafo jednodušší :-). Viz komentáře.

Líbí? Užívejte si to! Nelíbí? Hmm. :-)


Ještě jsem zapomněl poděkovat Měsíčkovi za pomoc při hledání spolehlivého řešení pro kopírování do schránky a DJ Mikymu, který mi nechtě pomohl s klávesovou zkratkou v Javascriptu.

Komentáře [12]

Potřebuje programátor vysokou školu?

2008-04-20 21:40 napsal Lukáš Havrlant

Nedávno jsme se zase na diskusi chytli, jakou vysokou školu pro programátora a samozřejmě jsme sklouzli i k tomu, jestli má vůbec VŠ smysl. Takže jak to je?

Já sám studuji první ročník aplikované informatiky na UPOLu. Loni jsem studoval první ročník informatiky na téže škole, ale bylo tam na můj vkus až moc detailní matematiky. Zkrátka mi stačil jeden semestr algebry a analýzy a věděl jsem, že tenhle obor nebude to pravé ořechové. Od hodně lidí už jsem slyšel, že VŠ člověka nenaučí programovat. Student získá patřičný rozhled, přičuchne k věcem, ke kterým by se jinak možná ani nedostal, ale programovat se prý nenaučí. Tímto vysílám otázku na ty, kteří už nějakou VŠ obor informatika mají za sebou – myslíte si, že vás škola naučila programovat?

Já sám si myslím, že mě škola učí programovat. Alespoň ta má. Hned na začátek tady vlepím seznam všech povinných a většiny volitelných předmětů, které mě za tři roky na bakalářském studiu potkají.

1. semetr:
– Algoritmická matematika (metody třídění)
– Informatická propedeutika (takové ty obecné znalosti – co je to http, připojení na vzdálenou plochu, ssh, základy linuxu, …)
– Paradigmata programování (funkcionální programování)
– Softwarová laboratoř (základy C)
– Úvod do informatiky (matika)

2. semestr:
– Matematika (algebra)
– Algoritmická matematika (metody vyhledávání)
– Paradigmata programování (OOP)
– Softwarová laboratoř (pokročilejší věci v C)
– Struktura počítačů (dvojková soustava, ASCII, Procesory, …)
(a jeden dobrý béčkový)
– Software pro matematiky (MatLab nebo Maple)

3. semestr:
– Matematika (analýza)
– Algoritmická matematika (teorie grafu)
– Formální jazyky a automaty
– Informatická propedeutika (TeX)
– Paradigmata programování (asi makra nebo dál OOP)
– Projektový seminář (samostatný projekt, kód)
– Softwarová laboratoř (C++ OOP)

4. semestr
– Matematika (analytika)
– Operační systémy (assembler)
– Projektový seminář (GUI)
– Softwarová laboratoř (dál C++)
(zde uvedu i béčkové předměty, je jich dost a jsou celkem zajímavé)
– Algoritmická matematika (dál teorie grafu)
– Matematická logika
– Paradigmata programování (paralelní programování)
– Jazyk C# (prostě cé kanál v .NET)

5. semestr
– Databázové systémy
– Informatická propedeutika (teoretická příprava na bakalářku, aneb jak ji napsat tak, aby se z toho pan docent nepozvracel)
– Operační systémy (pokračování)
– Počítačové sítě
– Projektový seminář (bakalářka)
– Vyčíslitelnost a složitost (náročnost algoritmů)
(výběr zajímavých béčkových předmětů)
– Metody vývoje softwaru („Předmět Metody vývoje softwaru se věnuje implementaci a nasazení informačních systémů ve větších společnostech, kde se klade důraz na přenostitelnost, interoperabilitu a integrovatelnost. Cílem je přiblížit architektury stávajících systémů založených na platformách Java, J2EE a SOA a připravit studenty do praxe v oboru.“)
– Programování v Common Lispu
– Platforma .NET
– Úvod do informačních technologií („Předmět uvádí do problematiky vytváření a provozu informačních systémů. Přibližuje dovednosti a činnosti nezbytné pro úspěšné vytvoření a dlouhodobě efektivní provozování informačního systému s vysokou přidanou hodnotou. Předmět je určen zejména posluchačům bakalářského oboru Informatika. Výuka bude vedena odbornými lektory firmy IBM.“)

6. semestr
– Bakalářská práce
– Informační systémy (XHTML, XML, CSS, PHP, apache, …)
– Projektový seminář (bakalářka)
– Algoritmizace a programování („Datové struktury, algoritmy (třídění, vyhledávání, grafové algoritmy), paradigmata programování (procedurální, funkcionální, logické, objektové, paralelní).“ – tenhle předmět nechápu, možná to má být opáčko)
– Informační technologie („Databázové a informační systémy, softwarové inženýrství, počítačové sítě, softwarové inženýrství, základy počítačů.“)
– Matematické metody („Algebra, lineární algebra, geometrie, matematická analýza, numerické metody, pravděpodobnost a statistika.“ – taky opakování)
– Teoretické základy informatiky
(všechny béčkové)
– Lineární programování
– Grafové algoritmy
– Počítačová geometrie
– Softwarové inženýrství („Předmět je úvodem do softwarového inženýrství. Jeho záměrem je seznámit posluchače s postupy a technikami, které se používají při tvorbě a údržbě softwarových aplikací.“)
– Softwarová praxe („Cílem předmětu Softwarová praxe je předvést instalaci a práci s operačním systémem a uživatelskými i serverovými aplikacemi na bázi svobodného softwaru. Studenti budou seznámeni se strukturou a možnostmi operačního systému Linux, jeho konfigurací, nastavením sítě, síťovými službami (http, ftp, DHCP, DNS, CUPS, Samba, LDAP, SQL,…) i uživatelským prostředím. Absolvent předmětu by měl získat přehled o problematice správy Linuxu a v něm nejčastěji používaných služeb.“)
– Extrémní programování

Tak, to je všechno. Teď zkusím shrnout, kde všude se střetnu s programováním.

Hned v prvním semestru máme tři předměty, ve kterých programujeme. V softlabu se učíme C; prakticky výhradně syntax s občasnými zmíňkami o tom, jak by céčkový kód měl vypadat, aby se tomu dalo říkat céčkový kód. V algoritmice potom programujeme algoritmy třídění – bubblesort, quicksort,… Asi nic extra užitečného, ale zase se u toho docela naučíme myslet. Ono přepsat quicksort nebo heapsort z teoretického zadání ve skriptech do C není zase tak jednoduché. Nejzajímavější předmět jsou potom Paradigmata programování. Tady se vyloženě „učíme programovat“. Výuka v prvním semestru probíhá ve Schemu, což je dialekt Lispu a je to více méně funkcionální jazyk. A je strašně pěkný :-). Sice v něm nic moc praktického nevytvoříte, ale má jednoduchou syntaxi a je to zkrátka nejlepší programovací jazyk na výuku, jaký jsem zatím viděl. V tomhle předmětu do nás rvou obecné zásady programování a kromě toho se seznámíme s funkcionálním paradigma, což taky není k zahození.

Druhý semestr probíhá podobně, v softlabu bereme dál C, v algoritmice binární, AVL a B stromy (to je taky hezké procvičení programování) a v Paradigmatech už máme OOP v Lispu. Ono je možná trochu zvláštní, učit se OOP v jazyku, který se skoro nepoužívá, ale má to své nesporné výhody. Lisp má strašně jednoduchou syntax a tak se málokdy stává, že přemýšlíte, jak to či ono napsat. Když máme cvičení z PP, tak zkrátka vyloženě řeším OOP věci. Kdybychom se základy OOP učili třeba v C++, strávím polovinu času nad pointrama a výuka OOP jde do háje. Bývalá spolužačka (která nikdy předtím neprogramovala) třeba měla na výšce Pascal a asi po pěti týdnech začali brát OOP. Jen co se rozkoukali, tak už do nich házeli objekty a spolužačka se mezitím ztrácela v samotné syntaxi. Nepřijde mi to jako šťastné řešení.

Další ročníky už tak neznám, protože jsem je ještě neabsolvoval :-). Ale z doslechu od druháků/třeťáků: V Softwarové laboratoři se začne brát OOP prakticky v C++, v paradigmatech myslím makra. Důležitější je ale projekt – přes celý druhák máme rozplánovaný projekt, což je nějaký větší program typu šachy nebo dáma. První semestr se řeší samotný kód a druhý semestr GUI. Dobré na těhle projektech je, že nejste vázání jazykem – můžete si zvolit jaký jazyk chcete. Takže kromě obligátních C++, C#, Javy apod. tam můžete najít i projekty v Ruby nebo v Lispu. Jediné omezení je, že „výuka“ probíhá z části formou konzultací, takže byste si měli zvolit takový jazyk, který alespoň někdo z katedry ovládá. Já sám jsem třeba uvažoval o Lispu, protože to je opravdu hezký jazyk, ale do budoucna bude lepší, když to udělám v nějakém normálním jazyce.

Třetí ročník už je v podstatě obdoba druhého, akorát místo projektu děláte bakalářskou práci. Takže pokud to vemu kolem a koukolem, programováním strávím na VŠ opravdu hodně času; nemám zrovna pocit, že by mě tam neučili programovat. Za sebe mohu říci, že vyučující u nás jsou skvělí a neučí nás nějaké kraviny. Kromě toho i ostatní „neprogramátorské“ předměty mi přijdou docela zajímavé. Prakticky všechny předměty, které na aplikované informatice máme, jsou zábavnější než algebry a matalýzy… :-)

Nemyslím si, že by škola byla na prd, mně třeba dává docela dost. I samotní vyučující říkají, že absolventi naši univerzity vždy najdou do pár týdnů uplatnění, takže ta škola nebude úplně na nic. Nehledě na to, že se na VŠ učí věci, které bych se sám ze skript učit nechtěl (teorie grafu, například). Ale samozřejmě nijak nepopírám, že za pomoci moudrých knih a moře pokusů se lze naučit programovat stejně dobře či lépe.

Já hlasuji pro VŠ – už z toho důvodu, že sám bych se programovat nedonutil naučit. A i když jsem se donutil, tak to dopadlo špatně. Jaj, kolikrát já jsem se začal učit OOP… :-) Programátor VŠ nepotřebuje, ale hodí se.

Komentáře [30]

Můj oblíbený FTP klient

2008-02-20 20:06 napsal Lukáš Havrlant

Dlouhou dobu jsem neměl žádného použitelného FTP klienta. Všechny byly tak nějak na půli cesty k mému vysněnému programu. A nedávno jsem objevil něco, co jsem dodnes nevěděl a nechalo mě to zírat na monitor celou minutu bez jediného slova.

Takže jaký je nejlepší FTP klient? Ne, není to Total Commander. Ty soubory jsou tam malé, čert aby se v tom vyznal. Když uploaduji obrázek, musím si pamatovat název, protože tam není náhled, nemůžu mít otevřených více oken, ze kterých bych uploadoval, nefunguje mi drag&drop z normálních windowsáckých oken atp. Ze všech ostatních asi vychází nejlépe, ale i tak to pro mě není to pravé. Co dál? Pak tu jsou nějaké ty Filezilly a SmartFTP. SmartFTP jsem docela dlouho používal, to bylo docela dobré, Filezilla už byla o něco horší. Ale i na nich mě pořád něco prudilo, ty ikonky tam taky byly nějaké divné… A vůbec to prostě bylo divné.

Teď to teprve přijde. Poslední dva tři dny používám jako FTP klienta Explorer. Tak, a je to venku. Prostě jsem narazil na nějaký příspěvek v jakési diskusi (když jsem paradoxně hledal něco o Total Commanderu), který popisoval, jak se v Exploreru (tzn. v normálním windowsáckém okně) připojit na FTP. Zkrátka do adresy zapíšete ftp://jméno:hes­lo@server a ono vás to tam fakt připojí! Jde to i bez jména a hesla, akorát ho pak musíte zapsat zvlášť, ale to už je jedno. No není to úchvatné? Je to úchvatné! Já na to čuměl jak puk. Na FTP se už pár let připojuji, ale tohle mě ve snu nenapadlo…

Explorer ale splňuje všechny mé požadavky na FTP klienta: je přehledný, jsou tam hezky velké a jasné (= je hned vidět, co je to za soubor) ikonky a umí pohodlně uploadovat a downloadovat (Drag&Drop, to je pro mě nejpohodlnější). Třeba ve výše zmíněném SmartFTP jsem nepřišel na to, jak jednoduše stáhnout věci ze serveru. Mé oblíbené Drag&Drop tam na download nefungovalo. Můžu si to libovolně seřadit, Vista tam má plno kritérií (ačkoliv samozřejmě v praxi využijete dvě až tři kritéria).

Asi to není nic pro náročnějšího webmastera, ale nám, obyčejným smrtelníkům, by to mohlo vyhovovat.

Komentáře [11]

Typová kontrola atributů českého validátoru

2008-01-16 00:06 napsal Lukáš Havrlant

Vzpomínáte ještě na článek o chybujícím validátoru W3C? Ve zmíněném článku popisuji chyby, která standardní validátor není schopen odhalit. Jednou z těch chyb jsou právě atributy, které mají ve specifikaci určeny hodnoty, jež smí obsahovat. Ovšem standardní validátor toto není schopný reflektovat. Český validátor to již od desátého ledna umí.

Pochopitelně se nezobrazí chyba, ale pouze varování. Dokument s takovýmto kódem je stále validní, protože i se všemi těmi nesmysly (<img src="stojící medvěd" alt="Lední Medvěd">) je stále validní, vo tom žádná. Stručný přehled změn si demonstrujeme na následujícícm příkladu:

<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="cz">
<head>
<title>Titulek</title>
</head>
<body>
<p>

<a href="Stín Katedrál.mp3"
target="1. rám"
style="color: red"
onclick="return false"
class=""
id="kotva"
name="kotvička">Príma hudba</a>

<img src="medved.jpg"
height="stojici medved brtnik"
width="jak krava"
alt="Medved brtník močí za sloupem veřejného osvětlení">

<font color="pekelná modř">while(!asleep()) $sheep++;</font>

</body>
</html>

Validátor tedy hlídá tyto drobnosti:

  • Zda je určen výchozí stylovací a skriptovací jazyk.
  • Jestli máme správnou hodnotu atributu lang. Často se stává, že tam lidi píší cz namísto cs.
  • Kontroluje syntaktickou správnost adresy odkazu, ve které se nesmí vyskytnout mezery či diakritika (obojí lze zapsat pomocí % sekvencí).
  • Kontroluje také platnost hodnoty atributu target, který určitě nesmí začínat číslem a nemá obsahovat diakritiku.
  • Atribut class musí obsahovat alespoň jednu třídu.
  • Použijeme-li v odkazu jak atribut name, tak i id, musí být stejné.
  • Délky a výšky musí být buď pouze číselné hodnoty, nebo zápis číslo a procento.
  • Stejně tak validátor ohlídá, zda skutečně v atributu color používáte barvu nebo nějakou blbost.
  • …a jistě hlídá ještě pár dalších atributů.

Standardní validátor samozřejmě daný kód označí za validní bez žádných dalších varování.

Český validátor opravuje více chyb či nedostatků oproti tomu hlavnímu. Celý výčet změn si můžete přečíst přímo u zdroje. Je toho docela dost ;-).

Komentáře

Scheme aneb programujeme funkcionálně

2008-01-01 21:09 napsal Lukáš Havrlant

Tenhle článek se bude zabývat především programovacím jazykem Scheme, jakožto jednoho ze zástupců funkcionálního programování.

Představení imperativního paradigma

Předpokládám, že každý zná alespoň nějaké střípky z imperativního paradigma. Že ne? Ale jo, určitě jste už něco programovali v nějakém procedurálním jazyku (C, PHP, Pascal, …), což je právě imperativní paradigma. Nejprve bych stručně charakterizoval procedurální jazyky a na základě této charakteristiky bych vysvětlil jaký je rozdíl mezi funkcionálním a imperativním paradigmatem.

Klasický procedurální jazyk staví na efektu postupného provádění částí kódu a na efektu přiřazení. Efekt přiřazení je asi nejtypičtější rys procedurálního jazyka, je to ono magické prom=funkce(); (prom:=funkce(); v Pascalu) nebo prostější a=10; b=a; apod. Každou chvíli něco do něčeho ukládáme a následně s tím pracujeme. Dalším typickým rysem je použití cyklů. Chceme-li něco provádět vícekrát, obvykle použijeme nějaký vestavěný cyklus; klasicky for nebo while. Procedurální jazyky mají obvykle složitou syntax a mají také přísnější pojmenování identifikátorů funkcí a proměnných.

Scheme

Teď se vrhneme na funkcionální programování, tedy na Scheme. Scheme není čistě funkcionální jazyk, protože obsahuje procedury vyvolávající vedlejší efekty (například zde existuje příkaz přiřazení, typický rys z imperativního paradigma). Scheme má ve své podstatě strašně jednoduchou syntax, ale o to složitější sémantiku. Zapsat syntakticky správně program je téměř triviální, ovšem zapsat ho tak, aby dával smysl je již horší.

Nyní by se slušelo upozornit na to, že funkcionální programování je naprosto, ale opravdu naprosto, odlišné od „běžného“ programování v jazycích typu C (procedurální jazyky). Je to asi jako byste se pár let učili anglicky a německy a pak přešli na čínštinu. Prostě je to úplně jiná dimenze. Zapomeňte na efekt přiřazení. Zapomeňte na cykly. Zapomeňte na všechno na co jste byli zvyklí…

Prefixová notace

Jak v běžném jazyku zapíšete součet tři plus pět? Asi takhle, že jo? 3+5. Tak se to rychle odnaučte, jestli chcete Schemovat, protože Scheme používá tzv. prefixovou notaci, což znamená, že na prvním místě je operace a na dalších pozicích jsou operandy. Takže tři plus pět byste ve Schemu zapsali jako (+ 3 5). Ze začátku to bude dělat trochu guláš, ale postupem času si na to zvyknete a přijdete na výhody tohoto zápisu. Třeba když chcete sečíst vícero čísel, stačí vám stále jen jedno plus: (+ 1 2 3 4 5 6). Výsledek tohoto výrazu by byl 21. Další výhoda je v jednoznačnosti. V Céčku závorky ve výrazech můžete psát, ale nemusíte, takže z toho místy může vzniknout trochu nepořádek. Ve Schemu prostě ty závorky napsat musíte, jinak se ten výraz vůbec nevyhodnotí. Třeba 2+3*4 ve Schemu s prefixovou notací zapíšeme takto: (+ 2 (* 3 4)).

Trochu blbé je, že prefixové je všechno, takže třeba zápis if(a>b) by ve Schemu vypadal takhle: (if(> a b)), což je dost nepřehledné a pořádně jsem si na to nezvykl doteď.

Symbolický výraz – všechno je vším

Tohle je asi úplně nejšílenější. Všechno může být vším, což částečně plyne z předchozí prefixové notace. Nejen že operátory píšeme na začátek seznamu (seznam je jednoduše řečeno několik symbolů oddělených mezerami a ohraničeny závorkami – třeba předchozí zápis se sčítáním (+ 1 2 3 4 5 6) je seznam.), ale i jakékoliv jiné procedury píšeme na začátek seznamu a další výrazy jsou argumenty procedury. Nové vazby vytváříme pomocí speciální formy define. Třeba tenhle výraz (define cislo 10) vytvoří vazbu ze smybolu cislo na číslo deset. Nic nečekaného. Když si necháme v interpretu vyhodnotit cislo, vrátí nám to 10. Novou proceduru můžeme vytvořit podobně:

(define proc
  (lambda(a b)
    (+ (* a a) (* b b))))

Tahle procedura vrací součet druhých mocnin předaných argumentů. A teď přijde ten hardcore. Tuhle proceduru můžeme předat jako argument úplně jiné procedury. Interpret Schemu totiž postupuje tak, že prochází seznamy a hledá vazby jednotlivých symbolů a následně je provede, přičemž je mu úplně šumafuk, jakou vazbu ten symbol má. Pokud provedeme třeba tohle: (define plus +), můžeme používat symbol plus úplně stejně jako normální symbol sčítání. Interpretu je jedno co se jak jmenuje (téměř) a co se kde aplikuje. Zkrátka jen suše vyhodnotí vazbu a provede co chceme.

Příklad: mějme tuhle proceduru:

(define porovnej
  (lambda(procedura a b c)
    (if(> (* c c) (procedura a b))
    #t
    #f)))

Tahle procedura bere čtyři argumenty – proceduru a tři čísla. Samozřejmě nikde není explicitně definované, jaké typy argumentů musíme předat, ale předáme-li špatné typy argumentů, program prostě dále při aplikaci vyhodí chybu. Procedura porovnej porovnává, jestli je větší druhá mocnina c nebo výsledek aplikace předané procedury na argumenty a a b. Příklad aplikace procedury porovnej:

(porovnej proc 2 3 4)

Proceduru proc jsme sepsali výše. Takže nejprve se provede umocnění čtyřky na druhou a poté se provede součet druhých mocnic 2 a 3. 16>13, výraz nám vrátí #t.

Otázka pro bystřé kluky a holky – jaký bude výsledek posledního řádku?

(define plus +)
(define + -)
(define - plus)
(+ 10 5)

Kdo si tipl pět, má bod; kdo tipl patnáct, nemá pro funkcionální programování vlohy; kdo tipl něco jiného, nemá vůbec pro programování vlohy ;o).

Filtrování prvků

Předchozí příklad s procedou jako argumentem nebyl úplně vhodný, protože byl více méně nesmyslný. Ale co třeba tohle? Představme si proceduru, která bere jako argument predikát (proceduru vracející buď #t nebo #f) a následně odstraní ze seznamu všechny prvky, které neodpovídají danému predikátu. Proceduru napíšeme snadno:

(define filter
  (lambda(pred? sez)
    (foldr (lambda(x y) (if (pred? x)
                            (cons x y)
                            y)) '() sez)))

Nebudeme teď moc rozebírat jak to funguje, na to by bylo třeba pár lekcí Schemu. Jen zdůrazním, že procedura filtr bere jako první argument predikát a jako druhý argument seznam. Možné příklady aplikace:

> (define seznam '(1 2 3 4 5 6 7 8 9 10))
> (filter even? seznam)
(2 4 6 8 10)

Predikát even? (mimochodem si všimněte, že ve Schemu bývá zvykem predikáty, vracející jen pravdivostní hodnoty, zakončovat otazníkem; příjemná konvence.) zjišťuje, zda je číslo sudé. Procedura vyfiltrovala všechna čísla, která nejsou sudá.

Další příklad:

> (filter (lambda(x) (> x 5)) seznam)
(6 7 8 9 10)

Tentokrát jsme si již vytvořili vlastní predikát, který zjišťoval, zda je číslo větší než pět. Čísla menší nebo rovna pěti procedura vyfiltrovala.

> (filter (lambda(x) (and (even? x) (> x 5))) seznam)
(6 8 10)

Teď jsme ponechali jen ta čísla, která jsou sudá a zároveň jsou větší než pět. Podobných příkladů najdeme plno…

Mapujeme…

Další užitečná procedura je map, která provádí mapování seznamu – na každý prvek seznamu aplikuje námi předanou proceduru. Opět si to ukážeme na příkladech:

> (map - seznam)
(-1 -2 -3 -4 -5 -6 -7 -8 -9 -10)

Zde jsme aplikovali operátor odčítání na předchozí seznam, takže všechna čísla nyní mají opačnou hodnotu. Další příklad:

> (map (lambda(x) (* x x)) seznam)
(1 4 9 16 25 36 49 64 81 100)

Zde jsme umocnili všechny prvky seznamu na druhou.

> (map (lambda(x) (>= x 6)) seznam)
(#f #f #f #f #f #t #t #t #t #t)

A nakonec jsme si zjistili, která čísla jsou větší nebo rovna šesti.

Něco takového lze pravděpodobně udělat třeba pomocí pointerů v Céčku, nejsem si tím každý. Každopádně to nebude tak elegantní jako ve Schemu, kde se to prostě používá naprosto běžně.

Cykly? E-e…

Zapomeňte na cykly, to jsem myslel vážně. Ve Schemu nejsou nebo se přinejmenším nepoužívají (tuším, že tam snad i nějaký cyklus je – on by v podstatě měl jít naprogramovat, ale zkrátka se nepoužívá). Všechno se řeší pomocí rekurze a iterace, což je místy docela šílenost. Třeba faktoriál vypadá ve schemu takhle:

(define fak
  (lambda(n)
    (if (<= n 1)
        1
        (* n (fak (- n 1))))))

A Fibonacciho posloupnost takto:

(define fib-iter
  (lambda(n)
    (let fib((a 0)
             (b 1)
             (n n))
      (if(< n 1)
         a
         (fib b (+ a b) (- n 1))))))

A to jsem ještě nepředstavil tzv. y-kombinator. To je hezká věcička. Myslíte si, že je možné provést rekurzi bez toho, aniž bychom tu proceduru nadefinovali? Tedy bez použití define? Do normálního jazyka bych tu otázku převedl takto: Je možné zacyklit funkci, kterou deklarujeme takhle…

function mojeFunkce(a, b, c…)
{
  //tělo funkce
}

…bez toho, aniž bychom v těle této funkce zavolali mojeFunkce()? Ve Schemu to jde docela jednoduše. Ještě předtím si ale musíme uvědomit jednu milou skutečnost. A sice, že tohle (lambda(x) (* x x)) se vyhodnotí na proceduru. Interpret vám po aplikaci toho kódu zobrazí #<procedure>. A na tuto proceduru můžete dále aplikovat argumenty. Takže třeba tohle: ((lambda(x) (* x x)) 5) se již vyhodnotí na 25. Lambda se opět vyhodnotí na proceduru a tahle procedura bere jediný argument – a my jí hned předáme pětku, takže interpret hodí do té procedury pětku a vrátí nám dvacet pětku. A teď ten y-kombinator:

((lambda(y) (y y 5))
 (lambda(fac n) (if(= n 0)
               1
               (* n (fac fac (- n 1))))))

Takže jak to teď proběhne: První lambda se vyhodnotí na proceduru beroucí jeden argument y. Tu okamžitě aplikujeme a jako argument jí předáme další – jinou – proceduru. Teď zpět k první lambdě. Vidíte tam tu magickou formuli y y 5? To znamená jen jediné. Zavolej proceduru, kterou jsme předali v argumentu a jako argument této volané procedury předáme tu samou proceduru. Poté předáme číslo, ze kterého chceme ten faktoriál počítat. Vidíte už trochu tu rekurzi? Vzhledem k tomu, že můžeme směle proceduru předat jako argument, můžete také pomocí argumentů provádět rekurze – stačí, když zavoláme tuto proceduru z argumentu a jako argument jí dáme zase tu proceduru z argumentu. Krása, ne? :-) Ještě bych rád upozornil na to, že to je spíše perlička, tak se hned nelekněte (u nás to málokdo pochopil na přednáškách a cvičeních, takže když jste princip y-kombinatoru nepochopili, neděste se).

Efekt přiřazení? E-e…

Zapomeňte na to, že si budete ve výpočtech ukládat nějaké hodnoty. Takhle to ve funkcionálním programování nefunguje. Ani dost dobře nemůže, protože ve funkcionálním programování jde především o postupném aplikování procedur, kde jako argumenty jsou předávány výsledky aplikace jiných procedur. Žádné zbytečné ukládání. Jedinou výjimku tvoří tzv. let-bloky, pomoci kterých můžeme ukládat hodnoty a poté pouze v těle tohoto let-bloku s nimi můžeme pracovat. V praxi to slouže jen pro ukládání hodnot, které bychom jinak museli počítat vícekrát. Například pokud v některé části kódu potřebujeme znát délku seznamu více než jednou, nebudeme při každém použití délky seznamu tu délku znova počítat, ale navážeme si tu délku na nějaký symbol. Jinak let-bloky prakticky nepoužíváme.

Závěrem…

…bych měl pár slov a odkazů pro ty, kterým se Scheme zalíbil. Ještě bych měl ale upozornit na to, že Scheme je v praxi více méně nepoužitelný jazyk a neznám obor, kde by se Scheme uplatnil. I když jsem slyšel o tom, že se Scheme používá při programování pluginů do Gimpu ;-). Nicméně je to dobrý odrazový můstek třeba pro LISP, který už by měl být použitelnější. Scheme je více méně klasický jazyk na učení, něco jako Pascal.

Jako interpret Schemu používám DrScheme (s jazykem „Pretty Big“, ostatní neznám – Language → Choose language → PLT → Pretty Big) a jestliže se chcete do Schemu ponořit naplno, stáhněte si PDF od dua Vychodil-Konečný. Nic lepšího v češtině nejspíše nenajdete.

Proč se mi Scheme líbí?

Scheme je krásný jazyk, obecně mě to funkcionální programování docela vzalo. Když něco programuju procedurálně, ať dělám co dělám, vždycky z toho vyjde prasárna. Neumím programovat v nějakém normálním jazyku tak, aby to bylo tak hezké, jako bych to napsal ve Schemu. Jako příklad na zkoušku ze Schemu jsem měl naprogramovaný determinant matice a inverzní matice. A když se teď na ten kód kouknu, je mi více méně jasný a na každém řádku vím co dělám.

(define determinant
  (lambda(matice)
    (if (ctvercova? matice)
        (let det((matrix (vynuluj-sloupec matice))
                 (nasobek 1))
          (if matrix
              (if(= (length matrix) 1)
                 (* nasobek (reditel matrix))
                 (det (vynuluj-sloupec (zbytek matrix)) (* nasobek (reditel matrix))))
              0))
        #f)))

I teď po měsící zkrátka vím o co jde. Jo a tohle samozřejmě není celý kód, je to jen ta hlavní procedura. Kdybych to napsal v céčku, vzejde z toho strašná prasárna…

Princip rekurze a iterace

2007-12-29 14:13 napsal Lukáš Havrlant

Rekurze je procedura/funkce, která volá sebe sama ve svěm těle. Další rozlišení bude následovat.

Rekurzivní procesy

V matematice známe funkce, které jsou definovány pomocí sebou samých. Nejtypičtější je samozřejmě faktoriál – n!. Faktoriál je definovaný nějak takhle: pokud je n menší nebo rovno jedné, je výsledek jedna. V opačném případě platí, že n! = n * (n – 1)! Vidíte tam tu hezkou rekurzi? Faktoriál n spočtete jako n krát faktoriál o jedna méně. Důležitá je ovšem ta hraniční (limitní) podmínka, že pokud je n jedna (nebo méně), je faktoriál jedna. Kdybychom tuto podmínku neměli, dostali bychom nekonečnou rekurzi, která by pro nás asi moc velký užitek neměla. Tohoto principu můžeme využít v programování. Ukázky budu psát v Céčku:

int fak(int n)
{
        if(n<=1)
        {
                return 1;
        }
        else
        {
                return (n*fak(n-1));
        }
}

Teď si trochu projdeme, co se vlastně v počítači stane a jakou má tahle funkce časovou složitost. Demonstrovat si to budeme na výpočtu příkladu fak(5). V tomto rekurzivním procesu nastanou dvě fáze – navíjení a odvíjení. Ve fázi navíjení se postupně volají jednotlivé faktoriály a nabalují se na sebe. V prvním kroku navíjecí fáze vzniká 5 * 4!. Ve druhém kroku 5 * 4 * 3! atd. Zde je důležité si uvědomit, že počítač si musí v každém kroku pamatovat předešlý výsledek, předešlé n. Když budu počítat faktoriál z milionu, musí mít počítač uloženo v paměti všech milion čísel, než dojde k jedničce (1 000 000, 999 999, 999 998, …).

Ve chvíli, kdy snížíme n na jedničku, navíjecí fáze se zastaví (dosáhli jsme limitní podmínky rekurze) a můžeme přistoupit k fázi odvíjení. Ta spočívá v aplikování násobení na mezivýpočty. Přehledně to ukazuje následující schéma:

|(fak 5)
| (fak 4)
| |(fak 3)
| | (fak 2)
| | |(fak 1)
| | |1
| | 2
| |6
| 24
|120

Nebo ještě přehledněji:

fak(5):
(5 * (fak(4)));
(5 * (4 *(fak(3)))));
(5 * (4 * (3 *(fak(2)))));
(5 * (4 * (3 * (2 *(fak(1)))));
(5 * (4 * (3 * (2 * (1)))));
(5 * (4 * (3 * (2))));
(5 * (4 * (6)));
(5 * (24));
(120);

Vidíme, že nejprve voláme proceduru fak a její argument postupně dekrementuje. To je fáze navíjení. Poté začíná samotný výpočetní proces – fáze odvíjení. Mezivýsledky se násobí a nakonec získáváme výsledek.

Teď něco ke složitosti. Časová složitost je poměrně jednoduchá, vždy provádíme n aplikací procedury fak, složitost je tedy lineární (ale nenechte se zmást lineární složitostí, faktoriál milionu stejně nespočítáte ;-)). Prostorová složitost (to je složitost, která nám říká, kolik spotřebujeme paměti během výpočtu) je také lineární, protože si vždy musíme pamatovat n čísel, která budeme ve fázi odvíjení násobit. V příkladu je to vidět v tomto řádku: (5 * (4 * (3 * (2 * (1))))); Počítač si musí vyhradit místo pro každé z těchto čísel a každé z těchto čísel si musí běhet výpočtu zapamatovat, aby je zde zase mohl z paměti vytáhnout a vypočítat výsledek.

Teď si ukážeme další příklad rekurzivní procedury a sice klasickou Fibonacciho posloupnost. Ta je definována nějak takhle:

n=0 -> fib(n)=0
n=1 -> fib(n)=1
jinak -> fib(n)=fib(n-1) + fib(n-2)

Neboli jde o součet dvou předchozích členů posloupnosti, přičemž posloupnost začíná čísly 0 a 1. Prvních pár členů vypadá takhle: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, … Proceduru, která počítá n-tý prvek téhle posloupnosti, napíšeme rekurzivně takto:

int fib(int n)
{
    switch(n)
    {
        case 0: return 0; break;
        case 1: return 1; break;
        default: return fib(n-2)+fib(n-1);
    }
}

Vypadá to poměrně jednoduše, striktně jsme se drželi definice. Tenhle postup je na první pohled správný, ale na ten druhý je samozřejmě špatně. Teď asi nastal čas, abychom si pověděli, jaký je rozdíl mezi lineárně rekurzivním procesem a stromově rekurzivním procesem. Lineárně rekurzivní procedura je procedura, která ve svém těle volá sebe sama nanejvýš jednou. Naopak stromově rekurzivní procedura volá sebe sama nejméně dvakrát. A to nám udělá strašný bordel ve složitosti.

Pokud volá procedura sebe sama pouze jednou, je to lineární složitost a počet prvků se plus minus rovná počtu aplikací procedury. To je v pořádku, tak to má být. Jestliže ovšem máme stromově rekurzivní proces, každá procedura volá sebe sama dvakrát (nebo vícekrát). Tedy v prvním kroku voláme původní proceduru dvakrát. V druhém kroku v každé nově vyvolané proceduře opět voláme další dvě procedury – celkem čtyři další procedury. V třetím kroku voláme dalších osm procedur, dále šestnáct procedur a tak dále. Dostáváme zřejmou složitost 2n.

A to je přesně případ Fibonacciho posloupnosti naprogramované stromově rekurzivním procesem. Prohlédněte si následující diagram zachycující, co se vlastně během aplikace té procedury děje:

|(fib 5)
| (fib 4)
| |(fib 3)
| | (fib 2)
| | |(fib 1)
| | |1
| | |(fib 0)
| | |0
| | 1
| | (fib 1)
| | 1
| |2
| |(fib 2)
| | (fib 1)
| | 1
| | (fib 0)
| | 0
| |1
| 3
| (fib 3)
| |(fib 2)
| | (fib 1)
| | 1
| | (fib 0)
| | 0
| |1
| |(fib 1)
| |1
| 2
|5

Jak vidíte, počítali jsme pátý člen a diagram je dlouhý jako týden před výplatou. Mimochodem si zde můžete všimnout, že fáze navíjení a odvíjení nemusí být v celém bloku celistvé a mohou se překrývat. Je evidentní, že tudy cesta nevede – zkuste si schválně u sebe doma spočítat třeba padesátý člen. Nejspíše se jen tak nedopočítáte. A jak teď z toho ven?

Iterativní procesy

Cesta vede přes lineárně iterativní procesy. O co jde? Ukázali jsme si, že stromově rekurzivní procedury, ve kterých voláme proceduru vícekrát než je zdrávo, nejsou vždy použitelné. Takže musíme srazit počet volání procedury na minimum, nejlépe na jedno volání. Což by se mohlo zdát jako problém, když i v definici Fibonacciho posloupnosti figuruje funkce fib dvakrát. Ale jde to.

V iterativních procesech si totiž předáváme mezivýpočty jako argumenty procedury. Nemusíme tedy volat dvakrát proceduru fib, stačí mít v této proceduře dva argumenty navíc, které budou sloužit k uchovávání předchozí dvou výsledků řady. Podívejme se na řešení:

int fib_iter(int n, int a=0, int b=1)
{
    if(n<=0)
    {
        return a;
    }
    else
    {
        fib_iter(n-1, b, a+b);
    }
}

Vystačili jsme si s jedním voláním procedury fib_iter a celá procedura je tak mnohem efektivnější. Vtip spočívá v tom, že si mezivýpočty posíláme v argumentech procedury. Hezky je to vidět hned v prvním kroku, kdy se a=0 a b=1. V dalším voláním procedury se do áčka uloží béčko, tedy jednička a do béčka součet a+b, tedy také jednička. V dalším kroku se do áčka zase uloží béčko, jednička a do béčka se uloží součet a+b, tedy dvojka. A tak dále a tak dále… Postupně také snižujeme n a až dojde nuly, vrátíme a, kde bude hodnota, kterou hledáme. Následující diagram to krásně zachycuje:

|(fib_iter 10 0 1)
|(fib_iter 9 1 1)
|(fib_iter 8 1 2)
|(fib_iter 7 2 3)
|(fib_iter 6 3 5)
|(fib_iter 5 5 8)
|(fib_iter 4 8 13)
|(fib_iter 3 13 21)
|(fib_iter 2 21 34)
|(fib_iter 1 34 55)
|(fib_iter 0 55 89)
|55

Teď si tento iterativní proces dále rozebereme. Jistě jste si všimli, že tenhle diagram je mírně odlišný od ostatních – chybí fáze odvíjení. Není totiž potřeba. U rekurzí jsme museli dospět do koncové podmínky a poté jsme mohli teprve vyhodnocovat výraz. Zde u iterativní verze po ukončení limitní podmínky máme výsledek okamžitě, netřeba nic odvíjet. Z toho vyplývá jedna důležitá vlastnost. Rekurze je v koncové pozici. Koncová pozice nastává v případě, kdy iterativně voláme procedury aniž bychom ji aplikovali s nějakou další operací. n * fak(n-1) není koncová pozice, protože je tam ještě ta operace násobení. fib_iter(10) je koncová pozice, protože se tam již jiná operace nenachází.

Jestliže je rekurzivní procedura v koncové pozici, jsme schopni provést optimalizaci na koncovou pozici. Když se nad tím zamyslíte, u rekurzí jsme si museli ve fázi navíjení pamatovat mezivýsledky, abychom je mohli aplikovat ve fázi odvíjení. Nic takového ovšem u lineárně iterativních procesů nemusíme provádět, protože zde fáze odvíjení odpadá. Klesá tedy prostorová složitost procedury – nemusíme si pamatovat n čísel, můžeme si dovolit přepisovat stále stejný chlíveček v paměti počítače. Když jsme rekurzivně počítali faktoriál ze sta, museli jsme mít vyhrazeno sto chlívečků na mezivýsledky 100, 99, 98, … U iterativní verze nám stačí jeden chlíveček, kde budeme postupně přepisovat 100, 9900, 970 200, … Z toho vyplývá, že prostorová složitost iterativních procedur v koncové pozici je konstatní. Časová složitost pochopitelně také klesá, to je vidět z diagramu, na lineární. Pomocí iterativní verze Fibonacciho posloupnosti již padesátý člen opravdu spočítáte.

Až někdy budete programovat v jazyku, ve kterém třeba nejsou cykly nebo prostě jen rekurze máte rádi, vzpomeňte si na iterativní procesy, ať tam nemáte samé procedury s exponenciální časovou složitostí ;-).

Komentáře [3]

Typografická klávesnice

2007-12-26 02:32 napsal Lukáš Havrlant

Docela dlouhou dobu mě štvalo, že standardní klávesnice neumožňuje správný zápis některých zvyklostí našeho jazyka. Tak třeba místo „českých uvozovek“ běžně používáme "programátorské uvozovky". To je první hověz. Dále kdo z vás dokáže na klávesnici napsat pomlčku? Ha? Ti bystřejší vědí, že na klávesnici se pomlčka nevyskytuje. To co je vedle shiftu je spojovník, nikoli pomlčka. Je v tom poměrně velký rozdíl, ale o tom si přečtěte na ÚJČ. Ti šílenější z vás zase vědí, že pomlčku můžeme zapsat jako alt+0150 (či alt+0151 pro čtverčíkovou pomlčku — dlouhou pomlčku). Výše zmíněné uvozovky lze zapsat jako alt+0132 a alt+0147. Stejně tak tři tečky… Tři tečky se správně nezapisují jako tři tečky za sebou, ale je to jeden znak, tzv. výpustka. Kódem lze zapsat alt+0133. To je drámo, co?

Nicméně si přiznejme, že psát uvozovky a pomlčky přes alt a číselný kód je trochu dojebové, protože je to značně pomalé a výsledný efekt skoro až nestojí za to. Takže vám nyní představím úžasnou věc – Microsoft Keyboard Layout Creator. Prográmek made in Microsoft, který dokáže přemapovat celou klávesnici. Můžete si pod jakékoliv tlačítko navolit jakýkoliv znak. Jestli jste šprýmaři, můžete někomu přepsat kompletně celou klávesnici tak, že se v tom nevyzná ani prase. Takže řešení je nasnadě – stáhnout si tenhle program a vytvořit svou vlastní klávesnici. Po prvním spuštění sice bude klávesnice prázdná, ale můžete si načíst již existující klávesnici – doporučuji načíst českou – a poté můžete pokračovat v úpravách. Potom už jen vytvoříte exáč, kterým onu klávesnici teprve nainstalujete. Výhodou tohohle exáče je, že ho můžete klidně někomu přeposlat. Takže nechce-li se vám vytvářet vlastní klávesnice, můžete si stáhnout tu moji. Popis mé typografické klávesnice následuje:

České uvozovky jsem si nastavil na klávesy alt gr + ů a alt gr + §. Jsou na nich vyzobrazeny klasické programátorské uvozovky, takže to k sobě pasuje. Nevýhoda je, že již nemůžete psát dolar $ jako alt gr + ů, což je v PHP docela zásadní záležitost, používáte-li českou klávesnici (upřímně řečeno dost dobře nechápu někoho, kdo používá anglickou klávesnici na programování, když na české jsou všechny potřebné znaky taky a k tomu – jako bonus – mám k dispozici ty naše nesmysly ěščřžýáíé…). Dolar jsem tedy přemístil o fous vedle alt gr + l. Pomlčky jsem vrazil pod alt gr + ú (půlčtverčíková) a alt gr + ) (čtverčíková). Uvažoval jsem o umístění alt gr + n a alt gr + m – je to blíž k pravému altu. Ale když jsem to zkusil, psalo se mi to hůře, bylo to zase až moc blízko :-). Výpustku jsem dal pod alt gr + p. Poslední znak, který tam mám, je nedělitelná mezera. Extra velcí blázni to budou vkládat po každé jednopísmenné předložce, ale já to většinou používám jen v číslech. Třeba když píšu 9 000, ať nemám devítku na konci řádku a nuly na začátku dalšího řádku. Nedělitelnou mezeru píši alt gr + mezerník.

A to je všechno, víc změn jsem tam neprovedl. Pokud vás to zaujalo a vyhovuje vám složení kláves, můžete si tu klávesnici stáhnout. Instalace je jednoduchá – spustíte setup a a poté v nastavení jazyků (to je to CS dole) musíte nastavit „typografickou“ klávesnici: CS → Zobrazit panel jazyků → možnosti (já to ve Vistě mám jako takovou malou šipku dolů vpravo dole) → Nastavení → Výchozí jazyk zadávání (v rolovátku nalezněte instalovanou klávesnici). Ta má se přesně jmenuje „České typograficka“. Je dobré restartovat počítač, protože jinak se po překliknutí do jiného okna může vrátit původní klávesnice. To je vše, dámy a pánové.

Typografická klávesnice

Související odkazy:

Komentáře [15]

Unreal Tournament 3

2007-12-14 14:31 napsal Lukáš Havrlant

Řežba jak má být.

Už demo UT3 slibovala, že to bude dobré pokračování nejklasičtější střílečky. A taky že jo! UT2004 jsem nehrál, ale vyrůstal jsem na Unreal Tournament (myslím ten nejpůvodnější) a poté UT2003, což se na dlouhou dobu stala ma nejoblíbenější hra ;-). Na UT3 jsem se těšil jako malé dítě a i kvůli tomu jsem si pořizoval Harryho.

První dojmy z Unrealu jsou dobré, hra je dynamická a svižná, jak má být. Akorát mě klasicky prudí kampaň, protože když si dávám nějakou instatní akcičku, jsem zvyklý tam mít tři hordy spolu a protihráčů, kdežto v kampani jsou běžně na tři prdele velkou mapu tři hráči na každé straně. Takže jdete jdete jdete, někoho zabijete a zase půl minutu jdete jdete jdete… Ale to bývalo vždycky.

Další věc je překlad. Ve dne i v noci jsem se děsil toho, že bude UT3 dabovaný. Jen si to představte, jak místo krásného [dabl kyl] vám v bedýnkách zní Pomeje a jeho „Dvojitý zásah!“. Nebo místo „Head Hunter“ vám Vojta Kotek křičí, že jste „Lovec hlav!“. Naštěstí se dabing nekonal, můžu vás zase uklidnit. Žádný Pomeje ani Vojta Kotek. Přeložené jsou jen zbraně a apod. a do videí jsou přidány titulky. Nicméně i tak si budete muset zvyknout, že odteďka bude vaší nejoblíbenější zbraní energopuška (namísto link gun)… :-( (ale už existuje jakýsi modul, který tam vrátí angličtinu – ale nezkoušel jsem to)

Co mě trochu prozatím zklamalo, je výběr postavy. Máte na výběr asi ze čtyř ras a v každé rase jsou cca čtyři (skoro stejné) postavy. Sice si je můžete libovolně ozdobit, ale ani při vší vůli ze žádné postavičky neuděláte ani Brutalise ani Harlequina, známé tváře z Unreal Tournament 2003. Ale je možné, že se další postavy odemknou s dohranou kampaní (i když se mi to nezdá pravděpodobné, kampaň jsem ještě nedohrál, ale mapy mám všechny, takže nevím, proč bych neměl mít postavy). To je trochu blbý, hraju teď za jakéhosi polorobota.

Ve zbraních snad žádná extra zásadní změna není, prostě jsou klasicky Unrealovské. Akorát jistě potěší vrácení legenrádních dvoupistelok – pokud během vraždění seberete někomu enforcer (což je skoro nemožné, protože nějaké zbraně jsou na každém kroku, takže si musíte vyhlídnout nějakého zrovna obživnuvšího), můžete používat dvě pistole zároveň, což je skvělé ;-). Byla to jedna z mých oblíbených zbraní v původním Unreal Tournament.

Teď pár slov k novému módu Warfare. Principem je, že musíme postupně ovládnout všechny stanoviště a poté musíte zničit soupeřovu kouli v jeho základně. Zní to docela jednoduše, ale ono ovládnout postupně pět šest bodů zase taková sranda není. Co je dobré je, že se vždy bojuje prakticky u jednoho stanoviště. Pokud stanoviště očíslujeme 1–2-3–4-5, tak na když ovládáte body 1–2-3 a soupeř 4–5, bojuje se výhradně u bodů 3 a 4, vzdálenější stanoviště (1–2 a 5) jsou kryté a nejdou dobýt. Takže nemůžete jen tak přeběhnout mapu a zabrat nějaké úplně jiné stanoviště. To je fajn. Ze začátku to bylo trochu zmatené, protože – i po přečtení manuálu- jsem to moc nechápal. Ale po pár hrách to člověk prostě pochopí… Nebo prohraje ;-).

Hru jsem objednával u xzone, doručeno to bylo hned další den (resp. v úterý v noci objednáno, ve čtvrtek ráno doručeno, bez problémů). Součástí balení je i bonusové DVD, které jsem ještě neviděl. Balení můžete vidět na fotce:

UT3 small

Jestli si teda chcete užít pořádnou akcičku, cákance krve stříkající r postaviček, do kterých to perete rotačákem nebo raketometem roztrhané kusy těl (pro slabší povahy: krev jde vypnout), rozhodně Unreal Tournament 3 doporučuji ;-).

Komentáře