Chyby jsou povinnost

Zjistil jsem, že každý správný programátor by měl dělat chyby. Možná to může vyznít bláznivě, ale mám pro to své důvody, kterých je hned několik:

Asi jako nejdůležitější důvod je ten, abychom si udrželi práci. Představte si situaci, kde po vás zákazník chce nějakou aplikaci, kterou mu dodáte před termínem ve vynikajícím stavu (tzn. kde nejsou žádné chyby a odpovídá představám zákazníka). Myslíte, že vás bude zákazník po předání ještě potřebovat nebo že dostanete speciální odměnu? Ale kdepak… jen když v aplikaci budou chyby a nebude dle očekávání, máte možnost ze zákazníka dostat další prácí za feature, které nebyly v zadání.

S tím úzce souvisí další důvod – musíme si naši práci udržet, poněvadž přeci nic jiného dělat neumíme. Nebo dokážete si představit (pokud jste pravý noční tvor nazývající se developer) jak někde něco děláte rukama? Třeba zametáte chodníky? Přece takový člověk by si o koště přerail obě ruce.

Další neméně důležitý důvod je vzdělání. Přeci chybami se člověk učí. Nikdy se nenaučíte nic tak dobře jako tím, že něco zkusíte a ono vám to dá ránu, která vás naučí, že tohle se dělat nesmí. Třeba strkat vidličku do zásuvky. A čím víc chyb uděláme, tím víc špatných možností vyloučíme. Pak jednoho dne, až toho hodně vyzkoušíme, budeme vědět, která řešení jsou ta správná.

No a takový poslední důvod je abychom si připadali jako lidé a nikoliv jako stroje. Protože chybovat je lidské.

Tak, a teď vážně…

Zdůrazňuji, že potuď to byl žert!

Tento článek je o testování, konkrétně o tom, co vlastně testovat. Postupů pro to je několik a záleží, v jaké situaci právě aplikace je. Začnu od ideálního případu, kdy se teprve aplikace začíná vyvíjet.

SLIME

Zatím jsem neprozkoumal mnoho postupů, jak pokrývat aplikaci testy, ale osobně se mi prozatím nejvíce zamlouvá SLIME (by Adam Goucher), což je zkratka ze security, languages, requirements, measurement a existing. 

Tedy nejprve otestovat bezpečnostní prvky. Například otestovat, že aplikace se ubrání proti různým útokům jako je napříkald XSS, CSRF, SQL injection, Clickjacking, zda se posílají hlavičky zvyšující bezpečnost a spoustu dalšího. Protože pokud aplikace bude mít problém s bezpečností, je většinou už jedno, že jinými chybami netrpí.

Další v pořadí je nutné otestovat, zda si aplikace poradí na všech místech s kódováním. Bylo by velmi nepříjemné narazit na skvělou aplikaci, kterou nemohu používat, protože místo písmenek vidím čtverečky kvůli špatnému kódování.

Dobrou technikou může být otestovat některé vlastnosti knihoven, na které je aplikace velmi závislá a není jisté, že autoři té knihovny nedostanou amok, kdy celé API změní bez předchozího upozornění. Poté může být velmi těžké zjišťovat, co se vlastně změnilo a co se musí upravit. Právě takovéhle testy by s tím měly pomoci.

Dále se hodí měřit výkon aplikace. Je to velmi podobné jako s jazyky – může se jednat o skvělou aplikaci, ale když budu čekat na odezvu příliš dlouho, velmi rychle mě to přestane bavit. Proto je dobré si napsat testy a nechat se upozornit, jakmile se výkon aplikace zhoršuje.

A nakonec testovat samotný kód, který vzniká. Jednotkové testy, integrační testy a tak dále.

80 % ve 20 %

Většinou se však snažíme testovat již existující aplikaci a tam už testovat předchozí body není úplně nutné, protože aplikace si prošla nějakým vývojem, kde se všechny popisované neduhy už (doufejme) opravily a testy by nepřinesly mnoho ovoce. Což ale neznamená, že to není užitečné – pokud se plánuje měnit jádro aplikace, určitě je užitečné si nejprve výše zmíněné testy napsat.

Popojďme ale dál k samotnému kódu aplikace. Určitě nejlepší strategie je začít těmi nejdůležitějšími a nejvíce používanými částmi aplikace. Existuje takové pravidlo 80/20, což znamená že 80 % všech chyb je 20 % kódu. Většinou toho nejvíce užívaného. Takže relativně během chvilky jsme schopni pokrýt spoustu věcí.

Mindmaps

Když už si myslíme, že jsme pokryli to nejdůležitější, chceme pokračovat dál a aplikace je tak rozsáhlá, že není lehké zjistit, co už pokryto je a co není, mohou pomoci mindmap grafy. Jedná se o diagram, ve kterém si postupně vyznačíme všechny funkčnosti aplikace.

Řekněme, že naše aplikace je e-shop. Začneme prvotní tečkou někde uprostřed a z té uděláme větve „uživatel“, „produkty“, „košík“, … Z košíku udvětvíme dál na „přidat do košíku“ a to můžeme zase odvětvit na „dynamické přidání pomocí JS“ a „klasické přidání“ atd. Pak zbývá jen fajfkovat, co už otestováno je a co nikoliv.

Nutno podotknout, že existují i utility, které prozkoumají pokrytí testů. Nemám s nimi ale dobrou zkušenost – čísla nejsou přesná a lze to využít jen pro jednotkové testy.

Dělat chyby

No a když už aplikace obsahuje spoustu testů a jejich psaní nás stále neomrzelo, zbývá poslední trik o kterém je tento článek – dělat chyby.

A dělat je záměrně. Nikoliv však kvůli důvodům ze začátku, ale kvůli otestování testů. Při úspěšném rozbití (jinak skvěle fungující, samozřejmě) aplikace lze jednoduše zjistit, kde mají testy mezery a je potřeba některé upravit či další připsat.

Tato poslední metoda neplatí jen pro případ, kdy už se neví, jaké testy napsat. Dobré je při psaní testu ověřit, že test funguje. Pokud se praktikuje TDD, tak se to vlastně dělá; ale pokud se testy dopisují k existujícímu kódu, je potřeba funkčnost testu ověřit dodatečně. Test, který je neustále zelený, je k ničemu…

Tak dělejme chyby!

Datový typ boolean v MySQL

Už je to dlouho, co jsem se s vámi chtěl podělit o tip, jak vytvořit datový typ boolean v databázi MySQL trochu jinak. Nějak jsem na to úplně zapomněl, takže se s ním dělím dnes.

V MySQL datový typ boolean je, ale není to samostatný datový typ, nýbrž alias pro TINYINT(1). V normálních situacích by to mělo stačit, ale občas nastane prostě specifická situace, kdy to nepostačuje…

Dělám totiž na business aplikaci, kde je velmi často co nějaký formulářový prvek, to atribut v databázi. Každý takový formulářový prvek je nějak omezen a uživatele musíme případně upozornit, pokud takové hranice překročí. Programátor je od přírody tvorem lenivým a proto nic nepíše dvakrát (tzv. DRY) a tudíž ani my jsme nechtěli validace psát vícekrát.

„Vícekrát?“ ptáte se? Ano, vícekrát. Nejenom, že musím někde v kódu specifikovat validační pravidla, ale i databázi musím nějak nastavit. Už jenom tohle je dvakrát a to nepočítám nějaké menší kontroly na straně klienta – v JavaScriptu. Například věk. V databázi musím určit TINYINT a v kódu ošetřit vstup, aby mi minimálně databáze neodpověděla out of range.

Abychom to nemuseli dělat, napsali jsme si takovou fičuru – při nastartování aplikace se přečte celá databáze a pro každý atribut v každé tabulce se sestaví validační pravidlo. Jaký to je datový typ a jaká jsou omezení (maximum/minimum, maximální/minimální délka, možnost nastavit NULL, …). A tyto pravidla se využijí při validaci (která si samozřejmě můžeme v aplikaci ještě zpřísnit).

Tedy když pomocí SQL syntaxe řeknu, že e-mail může být maximálně 256 znaků dlouhý, nemusím toto stejné číslo použít znovu někde v kódu. A kdyby se náhodou toto omezení změnilo, stačí provést úpravu na jednom místě.

Řešení to je hezké a funguje nám to bez problémů dlouho (něco přes rok), ale měli jsme s tím při programování menší problém. Jednalo se o datový typ boolean. V databázi jsme ho měli jako každý jiný vytvořen pomocí TINYINT(1), jenže takto tam máme i atributy, které jsou skutečně celočíselné – nabývající od nuly do devíti.

Člověk je rozliší poměrně jednoduše podle názvu, ale robot generující validační pravidla to má o něco horší. Mohli jsme mu to usnadnit například nějakým speciálním zápisem do poznámky, ale to není úplně to pravé ořechové. Poznámka / komentář je jen poznámka / komentář. Něco takového by nemělo být rozhodujícím pro běh programu. To jsme tedy neudělali.

Udělali jsme to, že TINYINT(1) jsme převedli (kde se jednalo o logickou hodnotu) na BIT(1). Dřív byl BIT také alias pro TINYINT, ale od MySQL 5.0.3 je to samostatný datový typ, takže ho lze rozlišit a dokonce může správně nabývat pouze dvou hodnot.

Výhody to nemá – datově si nijak nepolepšíme (BIT(1) zabírá totéž jako BIT(2) nebo i BIT(8)) a nepolepšíme si ani nijak jinak. Vlastně si ještě ztížíme práci, protože BIT se přenáší jako BINARY, což je v MySQL řetězec. Na to je jednoduchá náprava: stačí hodnotu převádět například pomocí funkce CONVERT.

MySQL dokumentace radí i převádění pomocí přičtení nuly, ale to mi nepřijde zrovna přehledné. Ale je to kratší když pracujete v konzoli. ;)

Jinak žádné další problémy s použitím BITu jsme neměli. Dokonce je teď jasnější, že se jedná o logickou hodnotu, protože TINYINT(1) prostě neříká „hej, čau, já jsem nějaký flag!“ Což potvrzuje to, že máme skutečně atributy TINYINT(1), které nejsou logické.

Pokud tedy někdy přestane vyhovovat TINYINT(1) jako logická hodnota i vám a v MySQL stále nebude (stále není v poslední MySQL 5.6) pravý BOOLEAN, zkuste náhradní řešení s BIT(1).

Pro vysoký výkon se hodí naopak něco jiného: CHAR(0) DEFAULT NULL (v případe InnoDB). Tohle řešení se mi mi zdá velmi ugly, ale co bychom neudělali pro vysoký výkon, že? :) O tom už ale jinde, například v knize High Performance MySQL nebo v článku Efficient Boolean value storage for Innodb Tables.

Seriál Python profesionálně

Měl jsem chuť napsat sem něco o Pythonu. Později jsem zatoužil po víc a chtěl jsem napsat o zajímavostech v Pythonu – jak se v něm věci dělají jinak, jednodušeji, na co si dát pozor, a tak. Postupně jsem si sepisoval, co bych chtěl zmínit, když v tom jsem to celé přeskládal a přidal podstatně více věcí. Nakonec vznikl seriál.

Zkusil jsem to napsat zajímavě. Použil jsem popis nějakého problému s jeho postupným řešením od špatných řešení až po ta dobrá, kde jsem i na tom špatném ukazoval různé věci. Někomu se to líbí hodně, někomu vůbec (to hlavně puristům). Osobně jsem s výsledkem spokojen, i když to není úplně takové, jak jsem si představoval, že bude.

Ať tak či onak, pokud máte za sebou nějakou prvotní příručku Pythonu za sebou (například Dive Into Python 3, která je k nalezení i v češtině) a zatím jste můj krátký seriál o Pythonu nečetli, nezapomeňte to napravit. :)

A kdeže je? Na Zdrojáku pěkně prosím:

  • V prvním díle vás uvedu do seriálu a začnu s jednoduchými věcmi jako ternární operátor, iterace, cyklus a podobně. Ale nepřeskakujte tento díl – téměř s jistotou vše neznáte.
  • Ve druhém díle se posunu dál ke generátorům, lambda funkcím nebo například konext manageru.
  • Ve třetím díle se dozvíte pár vybraných tipů na nějaké moduly či proč si dávat pozor při definování defaultních parametrů ve funkci.
  • Ve čtvrtém díle předvedu několik návrhových vzorů, které jsou v Pythonu napsat jinak a lépe, než znáte z jiných jazyků.
  • A v posledním, pátém, díle se dozvíte, cože to je vlastně metatřída, jak ji napsat a příklady kde se dá šikovně použít.

Prosím, nepište komentáře k seriálu sem, ale k jednotlivým článkům na Zdroják, ať to je na jednom místě. Díky.

PEP8 a můj názor na něj

Dovolil jsem si napsat krátký seriál o Pythonu, kde jsem v prvním díle nedodržel kompletně PEP8. A to byl přesně důvod pro to, aby se rozjela smršť hádek. Některé komentáře byly trochu až drsné. Nesnažil jsem se s nikým hádat a další díly ještě přepsal, aby ukázky vyhovovaly PEP8. Nechci to však nechat být bez vyjádření.

Pokud PEP8 neznáte, možná bude dobré si ho v rychlosti proletět, aby bylo jasné, o čem je řeč. Je k nalezení na adrese http://www.python.org/dev/peps/pep-0008/.

PEP8 dobrý, ale…

Je velmi dobré se držet nějakého stylu, aby byl kód čitelný. A to není pouze jen tak. Na toto téma je velmi zajímavá přednáška Programming Style & Your Brain by Douglas Crockford, na kterou doporučuju se podívat (odpusťte mi, že odkazuju na přednášku, kde se používá JavaScript, když mluvím o Pythonu). Což je také důvod, proč si myslím, že je dobré, že Python něco takového má.

Jenže. Jenže podle mne to je až příliš konkrétní. Opravdu si myslím, že to je až příliš, protože spousta lidí to teď vidí jako něco, co se musí přesně do pontíku dodržovat. A když se to náhodou nedodrží v nějakém bodě, hned rozhořčeně píší do diskuze, jak je to špatné, když se to nedodržuje. Nebojí se pak ani říct, jak je to nečitelné či bijící do očí.

Aby mě náhodou někdo nepochopil špatně – konvece na názvy private či protected metod, pojmenování args a kwds, nemixování mezer a tabů, nepsat mezery navíc uvnitř příkazů, … vítám a vyžaduju. O tom žádná, to se musí. Bez těchto konvecí by v tom byl pěkný bordel.

Mě jde o něco jiného – o drobnosti. Například jak psát názvy nebo maximální šířka řádku.

Jak dodržuju PEP8

PEP8 se mi líbí a vyhovuje mi, takže PEP8 dodržuju až na pár drobností:

  • U názvů metod a proměnných používám camelCase (první písmeno malé), 
  • nebojím se použít (pokud to zlepší čitelnost) i 80. znak na řádce (klidně i pár dalších),
  • a pokračující řádky dělím trochu jinak; místo:
    def long_function_name(
            var_one, var_two, var_three,
            var_four, var_five):
        # ...
    používám (pokud zahrnu i změnu v názvech):
    def longFunctionName(
        varOne, varTwo, varThree,
        varFour, varFive,
    ):
        # ...

A podle mého názoru to není prohřešek. Něco jiného by bylo, kdybych například mixoval tabulátory a mezery nebo před public metodu psal podtřžítko.

Co jsem se dozvěděl z komentářů

Na mé mírné úpravy jsem se dozvěděl velmi zajímavé názory!

Když jsem u názvů metod použil camelCase, dozvěděl jsem se, že z toho „docela bolí oči, že to není JavaScript“. Jestli používá hodně tříd, tak ho docela lituju.

Nebo jiná perlička: „Za camel case normálně sekám ruce. To proto, že rozlišovat identifikátory pouze na základě velikosti písmen je zaručená cesta do záhuby a zdroj zcela zbytečných chyb.“ Při psaní tříd v Pythonu dle PEP8 pozor na ruce!

Dokonce jsem se dozvěděl, že nedodržovat PEP8 je „základní chyba“. No nevím, za použití camelCase mi ještě interpret ruce neutrhl. Dokonce ani nezobrazil žádné varování. (Ani žádný jiný jazyk.) Asi to nebude tak horké, jak se tvrdí…

Myslím, že tohle málo stačí pro to, abych ukázal, jak směšné takové diskuze jsou.

Týmové konvence jsou důležitější

Mnohem důležitější, než dodržování PEP8, je dodržování domluvených konvencí v týmu. Jelikož pracuju v Seznamu, tak někdo nezapomněl do diskuze přispět s odkazem na Python klienta pro API Skliku (prostě nějaký Python kód ze Seznamu), aby ukázal, jak (ne)dodržujeme PEP8 (pro zasmání ostatním diskutujícím) a že vlastně já to nemám tak strašné. Jiný diskutující se toho chytl a smál se. Samozřejmě, jak jinak. Docela bych rád viděl jak oni dodržují PEP8 v jejich zaměstnáních.

U malých a hlavně neprofesionálních firem se to nedělá, u těch ostatních je však bežné, že se na začátku (ať už projektu nebo firmy) stanoví nějaký coding style a ten se dodržuje, aby byl kód jednotný. A je úplně jaký bude; důležité je, aby s ním souhlasili všichni zúčastnění.

Například (což je i důvod zmíněného posměchu) v Seznamu na konci tříd, metod, cyklů, … používáme komentáře #endclass, #enddef, #endfor, … Já osobně tyto komentáře (u svých věcí) nepoužívám a k čitelnosti mi to nepomáhá (ale ani neubírá). Tento coding style se tu však zavedl a používá se. Jsou tu i vývojáři, kterým to přijde přínosem. Takže v práci tyto komentáře píšu a nemám s tím žádný velký problém.

V komentářích jsem našel také toto: „(…) respektuji konvence jazyka/prostředí, ve kterém dělám. Opačný přístup znamená, že jsem tam vetřelcem.“ Já na to říkám: Dodržováním konvencí jazyka mohu být vetřelcem pro tým, který má zavedený jiný coding style.

Sečteno podtrženo

Jděte se bodnout s tím z čeho vás bolí oči a za co sekáte ruce.

Jelikož to ale stejně neuděláte, budu příště na servrech, jako je Zdroják, dodržovat PEP8, ať máme všichni klid. Ve svých projektech budu ale nadále dodržovat svůj coding style a v práci budu nadále psát #endarticle.

Sublime Text: Téměř ideální IDE

Už je to nějaký pátek, co jsem narazil na IDE Sublime Text. Moc mě ale nenadchnul a tak jsem si dál používal Komodo IDE, protože jsem byl štastný držitel licence. A taky protože přeučovat se něčemu novému stojí čas a tím i peníze.

Firma ActiveState naštěstí nespí a díky tomu už (bohužel) nemohu svou licenci použít pro nejnovější editor Komodo IDE 7, které přináší spoustu vychytávek. Takže nadešel čas se na Sublime Text podívat blíže a rozhodnout se, komu přispěju svou troškou na další vývoj špičkového editoru.

Hned zprvu musím říct, že jsem ho testoval jen doma na menší práci, protože se nemohu v práci zdržovat kvůli nesžití mých prstů s editorem. Tím jsem nemusel narazit na všechny vychytávky a mouchy. Ale teď už se pustím do popisu, co mě nadchlo a co nikoliv.

V tolika souborech, aby se pra…

Určitě to znáte. Je potřeba něco vyvíjet a jelikož jste „Clean Coder“, tak máte vše rozdělené do menších souborů. Bohužel se občas stane, že se některé soubory (v různých adresářích) jmenují úplně stejně. Ve svém oblíbeném editoru si otevřete několik souborů, z toho budou tři stejného názvu. Ze začátku víte, který je který (vždyť jste je teď otevřeli a seřadili), ale za chvíli už nevíte. A hledáte a hledáte.

Hodně srandovní je pozorovat kolegu, který má jEdit. Tam se taby rozmísťují do řádků a všelijak to samo přeskakuje.

Přesně tohle se vám se Sublime Text nestane. Po otevření souboru sice zůstane v záložce pouze jméno souboru, ale po otevření jiného souboru se stejným názvem, se u obou záložek zobrazí navíc cesta k souborům, aby se daly od sebe rozeznat.

Horší to je při otevření velmi velkého množství souborů. Sublime Text taby zmenšuje a tím se tam vejde méně a méně textu. Naštěstí nemívám otevřené velké množství souborů, aby by mi to vadilo, ale někomu to vyhovovat nemusí.

Jak se ta metoda jenom jmenuje

Jednou za čas se mi stane, že otevřu soubor a teď si nemohu vybavit, co to vlastně hledám. Tak prostě scrolluju. Až narazím na to, co hledám.

Něco takového se se Sublime Text dělá velmi hezky. A efektně. Po pravé straně je (defaultně, lze vypnout) zobrazen panel s náhledem celého zmenšeného souboru. To jsem ještě nikde jinde neviděl! Výborná věc. Sice to nepoužiju tak často, ale pro fotografickou paměť to je eňo ňuňo.

Jen dva prstíčky tam strčíme…

Poměrně častá situace (u mne) je, že potřebuju jen do některého souboru nahlédnout na nějakou informaci a pak ho zavřít. Případně ještě něco zkopírovat, třeba název objektu, metody, …

V jiných editorech musím soubor opravdu otevřít a pak opravdu zavřít. Se Sublime Text nikoliv. A nevymýšlím si! Po (jednom) kliknutí na soubor (v editoru) se ihned zobrazí. Ale není otevřen v tabu. Pokud překliknu jinam, tak není v žádném seznamu otevřených souborů a musím ho případně znovu najít ve stromové struktuře. V tomto stavu mohu v souboru klidně cokoliv označit a zkopírovat a stále nebude otevřen. Funkčnost je dotažena tak daleko, že jakmile začnu editovat, tak se mi soubor už opravdu otevře. Úžasné.

I don't care

Když jsem poprvé viděl funkci, která skrývá kusy kódu, které mě zrovna nezajímají, byl jsem nadšen. Dnes už to tolik nevyužám, protože Komodo IDE nabízí dělat si záložky a v rámci jednoho souboru jednou klávesou přes ně skákat. Navíc editory s tím docela otravují – je to designově ošklivé a někdy kód skrývají blbě, že to spíš obtěžuje (například skryjí i následující mezery po metodě). Takže to vypínám.

Sublime Text na to jde dobře a hezky. Šipky pro code folding zobrazuje jen tehdy, když najedu myší nad sloupec s čísly řádků. A kód skrývá tak, jak se má. I když teď bych raději ty záložky. :)

Když jsem u toho zobrazení jen když potřebuju – podobně funguje zobrazování bílých znaků. Většina editorů umožňuje zobrazovat mezery a tabulátory jako nějaké puntíky a šipky. Je to super věc, ale nikdy jsem to neměl zapnuté natrvalo, protože to je s tím velmi nepřehledné.

Sublime Text zobrazí mezery a tabulátory normálně (jako prázné místo). Ale po označení textu se tyto bílé znaky zamění na zmíněné puntíky a čáry. Inteligentní.

Příjemné na pohled

Každý správný editor musí mít podporu schémat. A každý takový editor musí mít minimálně jedno tmavé schéma. Jinak to nikdy nemůže být můj editor. Koukat několik hodin denně do monitoru nelze se světlým pozadím. Prostě bez tmavé ani ránu.

Původně jsem si oblíbil schéma Oblivion v Geditu. Toto jsem se snažil dostat i do Geany. A povedlo se. Potom jsem si oblíbil v Komodu schema Dark, které se mi líbí nejvíce do dnes. Ale až Sublime Text je editor, který má tmavé schema nasteveno defaultně; potěšilo. Dokonce i poměrně hezké. Ale žádný strach – Sublime jich má spoustu na výběr, i netmavých!

Z nuly na sto km/h pod sekundu

Sublime Text je rychlý. A to hodně!

Ještě jsem nikde jinde neviděl takovou rychlost. Možná tak u obyčejného Geditu či Notepadu. Jenže ty neumějí to, co Sublime Text. Ostatní editory se s ním v rychlosti nemohou vůbec srovnávat. Například raději jeden řádek upravím ve vim-u, než abych zapínal Komodo (které startuje třeba 20 sekund). Sublime Text naběhne téměř okamžitě.

Rychlost není pouze při zapínání editoru, ale všude. Například rychlé otevírání souborů, vyhledávání, nahrazování, … A nejlépe s klávesovými zkratkami CTRL+P/R/G. Vyzkoušejte si. ;)

Správný programátor zvládne multitasking

Taková třešnička: pomocí CTRL + klik lze vkládat více kurzorů. Tím lze editovat několik řádků najednou. Taková blbina, ale hezká. Někdy se to může hodit více, než hromadné nahrazování. A hlavně, kdo může v jiném editoru psát více kódu najednou?! :)

Ale…

i tak to nebude můj hlavní editor. Ani doma, ani v práci. Proč? Inu, protože má i své nevýhody. První, taková drobnost, je správa projektů. Vygeneruje to víc, než jen jeden soubor (dva), a to je moc. Nemám rád, když to zaplní pracovní adresář „kravinama“, které nezačínají tečkou. Akorát se to motá pod nohama. Ani pak nevím, který soubor mám otevřít. A každý projekt se mi otevírá v novém okně.

Dál mi vadí, že si do postranního panelu se seznamem souborů musím adresář ručně přidat. Nemohu listovat z home či z root adresáře, jako v Komodu či Geditu a kdekoliv jinde. To mě docela zklamalo.

Při vyhledávání metod (pomocí zkratky CTRL+G) se sice rychle filtrují výsledky, ale pokud mám v souboru dvě třídy a oba mají metodu se stejným názvem, tak nerozeznám která je která. Komodo IDE to má vyřešené lépe – vypís zobrazí jako stromovou strukturu a nadřazený objekt neskryje.

(Ne)verzujeme

Zatím to byly drobnosti, které by šly překousnout, ale co mi opravdu vadí a přes co nejede vlak, je podpora verzovacích systémů. V Komodo IDE jsem si zvykl na rychlé zjištění stavu souboru, na rychlý náhled diff-u, na rychlý pohled do historie souboru.

Zde nic takového není. Našel jsem pouze nějaké rozšíření, které umí zjistit stav souboru a zobrazí nějakou konzoli, kterou mohu zavřít tak, že kliknu v menu na otevřít konzoli (páč klávesová zkratka nefunguje) a poté kliknu na zavřít konzoli. Jinak se toho nezbavím. A neumí to commitovat, neumí to zobrazit historii, diff. Nezobrazí stav souboru ikonkou v tabu ani v postranním panelu se seznamem souborů. A to je velká škoda!

Možná, pokud to někdo nestihne udělat přede mnou, bych si zkusil napsat vlastní extension pro Sublime Text pro podporu verzovacích systému. Se stejnou funkčností jako je má Komodo. Pak to bude super.

Takže

Suma sumárum to je velmi povedené vývojové prostředí. Vidím velkou šanci, že opustím mé oblíbené Komodo IDE a přejdu na Sublime Text. Vychytávek je opravdu spousta a určitě ho všem doporučuju minimálně zkusit. Ale já s jeho nasazením ještě posečkám.

Pokud podpora verzování je důležitá i pro vás, pak upozorním, že do 15. března je Komodo IDE 7 ve slevě. Jak nová licence, tak upgrade ze šestky.

Komunikace je důležitá

Nedávno jsme měli v práci opravdu kritickou situaci. Nasazovali jsme nový release aplikace a při tom se vloudila chybička. Ta nic ošklivého sice neprovedla, ale naneštěstí za ní následovala další, která kvůli té první už ano. Zničehonic jsme se dostali do pěkné ošklivé situace, ze které se nešlo dostat zpět. Aspoň ne jednoduše a bez újmy. I přesto, že jsme se pečlivě připravovali a promýšleli různé scénáře…

Co se dalo dělat. Muselo se to prostě dokončit a dostat do co nejlepšího stavu. Zůstali jsme tedy v práci o „něco“ déle a snažili se to dát do pořádku. Byla to rušná noc a po pár hodinách spánku i krušné ráno. Vlastně ještě několik dalších dní. Nic příjemného.

Proč to ale píšu – po každé takové situaci se snažím ohlédnout zpět a najít chyby, kterých jsem se dopustil. Po takové situaci jsou totiž vidět nejlépe mezery, které je potřeba eliminovat. A těmto chybám se příště, pokud možno, vyhnout velkým obloukem.

Ohlédl jsem se i nyní a našel u sebe nedostatek v komunikaci. Ne, že bych měl problém mluvit nebo tak podobně, ale spíš problém se přesně vyjádřit. Aby když popíšu hrníček na kávu, tak aby si spolukonzultant představil přesně ten samý hrníček jako já.

Hodně dobře problém dvojznačnosti popisuje ukázka z knížky The Cleaner Coder: A Code of Conduct for Professional Programmers od Robet C. Martin:

Sam (stakeholder): “OK, now these log files need to be backed up.”
Paula: “OK, how often?”
Sam: “Daily.”
Paula: “Right. And where do you want it saved?”
Sam: “What do you mean?”
Paula: “Do you want me to save it a particular sub-directory?”
Sam: “Yes, that'd be good.”
Paula: “What shall we call it?”
Sam: “How about 'backup'?”
Paula: “Sure, that'd be fine. So we'll write the log file into the backup directory every day. What time?”
Sam: “Every day.”
Paula: “No, I mean what time of day do you want it written?”
Sam: “Any time.”
Paula: “Noon?”
Sam: “No, not during trading hours. Midnight would be better.”
Paula: “OK, midnight then.”
Sam: “Great, thanks!”
Paula: “Always a pleasure.”

Later, Paula is telling her teammate Peter about the task.

Paula: “OK, we need to copy the log file into a sub-directory named backup every night at midnight.”
Peter: “OK, what file name should we use?”
Paula: “log.bakckup ought to do it.”
Peter: “You got it.”

In a different office, Sam is on the phone with his customer.

Sam: “Yes, yes, the log files will be saved.”
Carl: “OK, it's vital that we never lose any logs. We need to go back through all those log files, even months or years later, whenever there's an outage, event, or dispute.”
Sam: “Don't worry, I just spoke to Paula. She'll be saving the logs into a directory named backup every night at midnight.”
Carl: “OK, that sounds good.”

Ukázku zvěřejňuju s laskavým svolením autora 

Jak je z ukázky dobře vidět, oba se domluvili, oba byli spokojení, ale každý si to představil jinak. Sam, stejně jako zákazník Carl, měl na mysli zálohu každého dne, ale Paula to pochopila jako zálohu jen za poslední den. Bylo by velmi nešťastné, kdyby na to přišli až v produkčním nasazení.

Proto je potřeba se takových situací vyvarovat. Asi nejlépe to jde s akceptačními testy, jak posléze popisuje ve zmíněné knize Robert C. Martin. O těch se ale nebudu rozepisovat – přečtěte si knížku, anebo si akceptační testy vyguglete. Chci ukázat, jak může jednotlivec pomoct v obraně proti nejednoznačnosti (bez nutné aktivní účasti dalších lidí).

Poměrně jednoduše to lze pomocí odlehčených akceptačních testů. Například zrovna dnes jsem něco takového udělal: potřeboval jsem si ověřit, že vývoj nové funkcionality souhlasí se zadáním. Jednoduše jsem si proto přivolal zadavatele a poprosil, zda se může podívat na polotovar. Zda je to takhle OK. Ještě, že jsem to udělal! Nebyla tam nějaká drobná nejasnost, ale poměrně zásadní. Upravovat to později by mě stálo zbytečně dost času navíc. A hlavně firmu zbytečně více peněz.

Stále se ale může stát, že k nejednoznačnosti dojde a dělá se zbytečná práce. Proto je dobré být neustále na pozoru – hledat možné nesrovnalosti a případně si je ihned vyjasnit. Jako dobrá pomůcka si mi osvědčilo si po přečtení nebo vyslechnutí požadavku celý problém znovu projít, popsat ho svými(!) slovy, sdělit je zpět zadavateli a nechat si potvrdit, že vše souhlasí. Případně si o tom ještě promluvit.

Podle zkušeností mohu říct, že tyhle dvě pravidla pomohou snížit „ambiguity“ na minimum. Bohužel to je jen pro přijímání zpráv. Opačně se musí (pro jistotu) předpokládat, že si druhá strana nejednoznačnosti nevšimne, a podle toho se vhodně vyjadřovat. A to je přesně to, co mi zatím moc nejde a na čem musím zapracovat. Snad nebude dlouho trvat a budu psát pokračování k tomuto článku s ověřenými tipy, jak na to. :)

Hello World

Každý má nějakou úchylku. Někdo sbírá céčka, někdo známky, někdo Pokémony. Někdo nemůže být bez televize, někdo si musí kupovat svíčky a někdo má úplně něco jiného. No a já si píšu (resp. začal psát) různé programovací ukázky. Takový „hello world“ všeho možného.

Zatím jsem si vytvořil jen jednoduché ukázky – Hello World a výpočet Fibonacciho posloupnosti – v různých programovacích jazycích, se kterými jsem se už setkal. Jinými slovy zatím nic zajímavého. Postupně však budu přidávat složitější ukázky a nejen ukázky jazyků, ale i knihoven (Django, Closure, …). Pro mne to tak bude cvičení, abych nezkrněl; pro někoho jiného možný zdroj jednoduše pochopitelných ukázek.

Zdrojové kódy mám na GitHub'u v repozitáři helloWorld.

EDIT: Na stránce se statistikou zastoupení jazyků je krásně vidět, jak je který jazyk ukecaný (díky tomu, že jsem všude napsal stejné ukázky). Nutno podotknout, že assembler je zkreslený, poněvadž má zatím pouze Hello World (nenašel jsem překladač pro Linux, který jsme měli ve škole, a zatím jsem nedostal odvahu v tom jiném napsat výpočet Fibonacciho posloupnosti).

UML diagramy s graphvizem

Školu nemám rád, často jsem z ní na nervy, ale za jednu věc jí jsem vděčný – za předmět „Technická dokumentace.“ Díky tomu jsem se dostal k LaTeXu, graphvizu a dalším zajímavým aplikacím. Dnes chci poukázat na graphviz a možnost s ním vytvářet UML diagramy, protože na něj těžce narazíte. Neviděl jsem na něj doporučení, pokud jsem ho přímo nehledal.

Graphviz

Graphviz lze nainstalovat (na Debian-like systémech) pomocí příkazu apt-get install graphviz. Pokud máte nainstalováno, tak si zkuste vytvořit soubor (řekněme že test.dot) s tímto obsahem:

digraph G {
    A -> B
    A -> C
}

a vygenerovat z toho například PNG obrázek pomocí příkazu dot -T png -O test.dot. Výsledek je dobrý, že? Pro více informací, ukázek a dalšího materiálu navštivtě stránky projektu.

Graphviz se sám postará o rozložení prvků – jen se nadefinují prvky a vztahy mezi nimi – a jde mu to dobře! To je přesně to, co se mi na tom líbí. Když jsem potřeboval vytvořit UML diagram, tak jsem prošel spoustu aplikací, ale buď aplikace nešla zkompilovat, nainstalovat, používat a nebo měla nějaký jiný problém. S graphvizem jsem udělal UML diagram za půl hodinky bez problémů.

UML diagramy

Nebudu to zbytečně okecávat – našel jsem si a upravil „šablonu“ pro UML diagramy:

digraph G {
    fontname = "Bitstream Vera Sans"
    fontsize = 8

    node [
        fontname = "Bitstream Vera Sans"
        fontsize = 8
        shape = "record"
    ]

    edge [
        fontname = "Bitstream Vera Sans"
        fontsize = 8
        arrowtail = "dot"
        arrowhead = "none"
    ]

    user [
        label = "{User|id: int\lname: varchar\l|delete()\lcreateContact()\l}"
    ]
    
    contact [
        label = "{Contact|user_id: int\lname: varchar\lnote: varchar\l|delete()\l}"
    ]
    
    user -> contact [
        taillabel = "1"
        headlabel = "0..*"
        label = "own"
    ]
    
    contact -> user [
        arrowhead = "empty"
        taillabel = "1"
        headlabel = "1"
        label = "contain"
    ]
    
}

A to vygeneruje následující obrázek:

Myslím, že z ukázky je vše patrné a není třeba to komentovat. Souhlasím, že zápis samotných boxíků není zrovna ideální, ale raději překousnu tento zápis než bojovat s aplikacemi, které si myslí, že mi usnadňují práci s rozmístěním boxů a čar (například aplikace Dia se mi stále snaží vnucovat divné rozložení čar i když si sám řeknu, jak to má být rozložené).

Na záver přidám ještě jednu ukázku – můj diagram vytvářený pro semestrální práci předmětu Databázové systémy: dbs-dot.zip.

CSS tip pro tisk odkazů

Před pár týdny jsem tu psal článek o tom, jak spousta serverů kašle na tisknutelnou formu webu. Dnes bych to chtěl doplnit o jeden hezký CSS tip, který tisknutelnou formu bezvadně vylepší!

Přesněji jde o tisknutí odkazů; představte si scénář: přijdete na web, vidíte zajímavý článek, vytisknete si ho, později si ho přečtete, je tam odkaz na nějaký další materiál a na ten se chcete po přečtení také podívat. Ale co se nestane! Už nevíte, kde jste na článek narazili a URL adresa článku se nevytiskla nebo je neúplná. Co teď? Teď zbývá jen doufat, že Google článek nalezne (bude i existovat nebo bude v Googlí cache) a tam i hledaný odkaz.

Celé to lze mít ale jednodušší – stačí do tisknutelné formy tisknout i URL adresy. Že to je nesmysl? Že by nestačilo pouze CSS, ale bylo by potřeba přidat podporu do systému? Ale kdeže… jednoduché CSS postačí. :)

Tento řádek:

a:after { content: " (" attr(href) ")"; }

stačí vložit do CSS souboru určený pro tisk a je hotovo. Při tisku se za text odkazu přidá mezera následovaná závorkou s textem převzatým z atributu href. Jak jednoduché!

Ještě doporučím zrušit podtržení – bez něj to vypadá lépe. :)