Petr Zemek | Český blog - O věcech, které mě baví https://cs-blog.petrzemek.net/ cs Zvaná přednáška na VUT FIT: Vysoce kvalitní kód https://cs-blog.petrzemek.net/2023-07-28-zvana-prednaska-na-fit-vysoce-kvalitni-kod <span>Zvaná přednáška na VUT FIT: Vysoce kvalitní kód</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Za začátku května jsem měl na <a href="https://www.fit.vut.cz/">VUT FIT</a> zvanou přednášku na téma <em>"Vysoce kvalitní kód"</em>. V krátkém příspěvku uvádím odkazy na záznam a slajdy.</p> <!--break--><ul><li><strong>Předmět:</strong> <a href="https://www.fit.vut.cz/study/course/IVS/">IVS</a> (Praktické aspekty vývoje software)</li> <li><strong>Termín konání:</strong> 2023-05-03</li> <li><strong>Záznam:</strong> <a href="https://www.youtube.com/watch?v=ORnIXpITa4g">YouTube</a></li> <li><strong>Slajdy:</strong> <a href="https://github.com/s3rvac/talks/tree/master/2023-05-03-High-Quality-Code">GitHub</a></li> </ul><p>Pokud vše klapne, tak příští rok bych si chtěl udělat přednášku na téma <em>"Bezpečný kód"</em> :-).</p> </div> <span><span>Petr Zemek</span></span> <span>2023-07-28 - 18:29</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/2" hreflang="cs">škola</a></div> <div class="field__item"><a href="/taxonomy/term/1" hreflang="cs">FIT</a></div> <div class="field__item"><a href="/taxonomy/term/7" hreflang="cs">programování</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=230&amp;2=comment_node_blog&amp;3=comment_node_blog" token="SWfkA3jwNQStvLvR78Vyxi19XyLjiDAcMrwcxqXkSyk"></drupal-render-placeholder> </div> </div> </section> Fri, 28 Jul 2023 16:29:15 +0000 Petr Zemek 230 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2023-07-28-zvana-prednaska-na-fit-vysoce-kvalitni-kod#comments Upgradoval jsem Drupal na verzi 9 https://cs-blog.petrzemek.net/2023-05-07-drupal-upgrade-z-v7-na-v9 <span>Upgradoval jsem Drupal na verzi 9</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Tento příspěvek jsem sepsal jen pro info, abyste se nedivili, proč došlo ke změně stylu blogu :-). Upgradoval jsem totiž <a href="https://www.drupal.org/">Drupal</a>, což je systém, na kterém blog běží, a původní téma již nefunguje. Snad se mi podařilo vychytat všechny mouchy. Pokud byste náhodou narazili na problém, tak klidně napište do komentáře. Do konce roku bych chtěl ještě přejít na verzi 10, což je aktuálně poslední verze. Tento přechod by ale již měl být jednodušší.</p> </div> <span><span>Petr Zemek</span></span> <span>2023-05-07 - 19:07</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/5" hreflang="cs">blog</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=229&amp;2=comment_node_blog&amp;3=comment_node_blog" token="Ooh7tm7EIsmBgGBDCoIsuGy4lPixQLBNZm5PPzNaVb8"></drupal-render-placeholder> </div> </div> </section> Sun, 07 May 2023 17:07:34 +0000 Petr Zemek 229 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2023-05-07-drupal-upgrade-z-v7-na-v9#comments Hry mého mládí https://cs-blog.petrzemek.net/2023-03-08-hry-meho-mladi <span>Hry mého mládí</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Krátký návrat do minulosti k počítačovým hrám, které mě buď nějakým způsobem ovlivnily, a nebo na ně jen rád vzpomínám :-).</p> <!--break--><h2>Úvodem</h2> <p>Pár poznámek na úvod:</p> <ul><li>Jako mládí budu brát dejme tomu prvních 20 let života. Poté jsme se s hraním odmlčel.</li> <li>Při řazení jsem se snažil držet pořadí, v jakém hry vycházely (od nejstarších, po ty nejnovější).</li> <li>Někdy jsem seskupil více her do stejné položky. Především jsem tak učinil v případech, kdy spolu hry úzce souvisely.</li> <li>V textu je pár spoilerů, které jsem pro jistotu prefixoval <em>Spoiler alert</em>.</li> </ul><h2>Tak jaké hry to tedy jsou?</h2> <ul><li><strong><a href="https://en.wikipedia.org/wiki/Prince_of_Persia_(1989_video_game)">Prince of Persia</a></strong> (vydáno v roce 1990). Patrně první hra, kterou jsem kdy hrál :-). Tehdy jsme ještě neměli počítač doma. Vzpomínám si ale, že otec nám domů vozíval na víkendy počítač z práce, takže jsme mohli hrát tuto pecku. Byla to taky i hra, kterou jsme hrávali během prvních pár tříd na základce a přebíhali se, kdo se dostane dál :-).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Titus_the_Fox">Titus the Fox: To Marrakech and Back</a></strong> (vydáno v roce 1991). Po Prince of Persia se jednalo o mou druhou nejoblíbenější plošinovku. Nikdy jsem ji nedohrál. Vzpomínám si, že jsem se vždy dostal maximálně do sedmého levelu (budova, u které bylo potřeba se vyšplhat nahoru). Ten jsem nikdy nedokončil.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Lemmings_(video_game)">Lemmings</a></strong> (vydáno v roce 1991). Úžasná logická hra. Jedna z velmi mála her, které s námi hrával otec :-).</li> <li><strong><a href="https://en.wikipedia.org/wiki/The_Legend_of_Kyrandia">The Legend of Kyrandia</a></strong> (vydáno v roce 1992). Má nejoblíbenější adventura. Tehdy jsem ještě neuměl anglicky, ale naštěstí byl k dispozici český překlad. Druhé a třetí pokračování této série mě moc nenadchlo, což je škoda, protože na druhý díl jsem se strašně moc těšil. <em>Spoiler alert:</em> Nejvíce si vzpomínám na hlavolam v poslední části hry (hrad). Byla tam místnost s krbem a knihami, které šly vytahovat. Cílem bylo vytáhnout čtyři knihy, což hráči zpřístupnilo jeden z korunovačních klenotů potřebných k dokončení hry. V anglické verzi hry stačilo vytáhnout knihy s písmeny O, P, E, N (anglicky "otevřít"), což bylo dejme tomu logické. V české verzi však bylo nutné vytáhnout knihy O, T, E, V (prefix slova "otevřít"), což bylo logické již méně a dalo zabrat na to přijít :-).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Dune_II">Dune II</a></strong> (vydáno v roce 1992). První strategická hra, kterou jsem hrál. Hrával jsem tehdy buď za Atreidy, nebo Harkonneny, ale nikdy ne za Ordose. Mám pocit, že to bylo z toho důvodu, že Ordosové mi přišli nejslabší.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Disney%27s_Aladdin_(Virgin_Games_video_game)">Aladdin</a></strong> (vydáno v roce 1993) a <strong><a href="https://en.wikipedia.org/wiki/The_Lion_King_(video_game)">The Lion King</a></strong> (vydáno v roce 1994). Další mé dvě oblíbené plošinovky. Aladdina jsme tehdy ještě hrávali s bráchou u jedné klávesnice tak, že jeden z nás běhal a skákal a druhý šermoval a házel jablka :-)</li> <li><strong><a href="https://en.wikipedia.org/wiki/Superfrog">Superfrog</a></strong> (vydáno v roce 1994). Asi jedna z méně známých plošinovek. Nicméně patřila mezi mé oblíbené.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Jazz_Jackrabbit_(1994_video_game)">Jazz Jackrabbit</a></strong> (vydáno v roce 1994) a <strong><a href="https://en.wikipedia.org/wiki/Jazz_Jackrabbit_2">Jazz Jackrabbit 2</a></strong> (vydáno v roce 1998). Další mé oblíbené plošinovky. Vzpomínám si, že druhý díl jsme hodně hrávali s bráchou v režimu <em>split screen</em> (dva u jedné klávesnice).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Warcraft:_Orcs_%26_Humans">Warcraft</a></strong> (vydáno v roce 1995). Po Duně druhá strategická hra, která mě chytila. Taky se jedná asi o první strategii, kterou jsem hrál v režimu multi-plaery (tehdy ještě tuším přes <a href="https://en.wikipedia.org/wiki/Serial_cable">sériový kabel</a> - kdo z vás si na něj vzpomíná? :-)). Druhý díl mě moc nechytil, až ten třetí (viz níže).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Mortal_Kombat_II">Mortal Kombat II</a></strong> (vydáno v roce 1995). Má nejoblíbenější bojovka. Zajímavé postavy, komba, i fatalities.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Tyrian_(video_game)">Tyrian</a></strong> (vydáno v roce 1995). Skvělá arkádová střílečka. Řídili jste vesmírnou loď, kterou jste postupně vylepšovali.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Dungeon_Master_II:_The_Legend_of_Skullkeep">Dungeon Master II: The Legend of Skullkeep</a></strong> (vydáno v roce 1995). První a zároveň jeden z nejlepších "čtverečkovaných" dungeon crawlers, které jsem hrál. Úžasná grafika, hudba, lokace, vývoj postav, atd. Jen mě mrzelo, že hra byla poměrně krátká. První díl jsem zkoušel hrát taky, ale oproti druhému dílu mě nezaujal.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Worms_(1995_video_game)">Worms</a></strong> (vydáno v roce 1995), <strong><a href="https://en.wikipedia.org/wiki/Worms_2">Worms 2</a></strong> (vydáno v roce 1997) a <strong><a href="https://en.wikipedia.org/wiki/Worms_Armageddon">Worms Armageddon</a></strong> (vydáno v roce 1999). Úžasná multi-player hra, která se dala hrát i u jednoho počítače. Díly ve Worms sérii jsou prakticky na jedno brdo, takže pokud jste hráli jeden díl, tak jste hráli všechny. I tak si ale vzpomínám, že jsem hrál minimálně tyto tři zmíněné díly :-).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Heretic_(video_game)">Heretic</a></strong> (vydáno v roce 1996). Zatímco většina lidí vyrůstala u Dooma, já jsem vyrůstal u Heretica :-). Nevím proč, ale Heretic mě chytil víc, než Doom. Pokud mě paměť neklame, tak Heretic byla první <a href="https://en.wikipedia.org/wiki/First-person_shooter">FPS</a>, kterou jsem hrál v režimu multi-player (opět sériový kabel).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Shadow_Warrior_(1997_video_game)">Shadow Warrior</a></strong> (vydáno v roce 1997). Méně známá střílečka. Hrávali jsme ji tehdy s bráchou hodně po síti.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Fallout_(video_game)">Fallout</a></strong> (vydáno v roce 1997) a <strong><a href="https://en.wikipedia.org/wiki/Fallout_2">Fallout 2</a></strong> (vydáno v roce 1998). Můj vstup do říše izometrických RPG her. Jsem sice spíše přívržencem fantasy než sci-fi, ale oba Fallouty mě neskutečně bavily. Hrál jsem je několikrát a vždy přišel na něco nového. Líbil se mi rozvoj postavy, soubojový systém a šíře světa, kde se děj odehrával.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Might_and_Magic_VI:_The_Mandate_of_Heaven">Might and Magic VI: The Mandate of Heaven</a></strong> (vydáno v roce 1998). Tato hra mě tehdy neskutečně pohltila a považuji ji za jeden z nejlepších "nečtverečkovaných" dungeon crawlers. Především mě tehdy fascinoval rozvoj postav a šíře a rozmanitost světa, kde se hra odehrávala. <em>Spoiler alert:</em> Co za mě trochu zkazilo dojem byl závěr, kdy jsem fakt nečekal, že se hra zvrhne z čisté fantasy do "postřílej všechny mimozemšťany blastery" :-).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Carmageddon">Carmageddon</a></strong> (vydáno v roce 1997) a <strong><a href="https://en.wikipedia.org/wiki/Carmageddon_II:_Carpocalypse_Now">Carmageddon II</a></strong> (vydáno v roce 1998). Vrrrm vrrrrrrrrm :-). Závodní hry jsem moc v oblibě neměl, ale Carmageddon se mi hodně líbil :-). Druhý díl se mi líbil o chlup víc, než první.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Br%C3%A1ny_Skeldalu">Brány Skeldalu</a></strong> (vydáno v roce 1998). Celkem fajn český "čtverečkovaný" dungeon crawler. Líbilo se mi, že u hry byla možnost tvorby vlastních dobrodružství.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Heroes_of_Might_and_Magic_III">Heroes of Might and Magic III</a></strong> (vydáno v roce 1999) a datadisky. Skvělá tahová strategie. Především se mi líbila možnost si náhodně vygenerovat mapu na základě navolených voleb (velikost, přítomnost vody atd.). Nejčastěji jsem hrál asi za frakci <a href="https://mightandmagic.fandom.com/wiki/Castle_(town)">Castle</a>.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Baldur%27s_Gate_(video_game)">Baldur's Gate</a></strong> (vydáno v roce 1998) a datadisk, <strong><a href="https://en.wikipedia.org/wiki/Baldur%27s_Gate_II:_Shadows_of_Amn">Baldur's Gate II: Shadows of Amn</a></strong> (vydáno v roce 2000) a datadisk, <strong><a href="https://en.wikipedia.org/wiki/Icewind_Dale">Icewind Dale</a></strong> (vydáno v roce 2000) a datadisk. Moje srdcovky s ohledem na izometrické RPGs podle AD&amp;D pravidel :-). Konkrétně Baldur's Gate II považuji za jednu z nejlepších her, které jsem kdy hrál. Promyšlený herní svět a příběh, spousta postav přibratelných do družiny, vztahy mezi postavami (mimo Icewind Dale), spousta rozmanitých úkolů a mnoho dalšího. Každou z her jsem hrál několikrát, včetně jejich datadisků. Co se týče hlavní postavy, tak jsem většinou hrál za paladina (v Baldur's Gate II především kvůli <a href="https://baldursgate.fandom.com/wiki/Carsomyr">Carsomyru</a>, což je +5 obouruční meč, v datadisku pak až +6). Co se týče dalších her z této "série", tak <a href="https://en.wikipedia.org/wiki/Icewind_Dale_II">Icewind Dale II</a> jsem hrál, ale jen jednou (hra mě moc nezaujala). <a href="https://en.wikipedia.org/wiki/Planescape:_Torment">Planescape: Torment</a> mě pak minul úplně (asi kvůli tomu, že byla ze zvláštního prostředí a že jsem o hře četl, že se jedná spíš o hratelnou knihu).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Diablo_II">Diablo II</a></strong> (vydáno v roce 2000) a datadisk <strong><a href="https://en.wikipedia.org/wiki/Diablo_II:_Lord_of_Destruction">Diablo II: Lord of Destruction</a></strong> (vydáno v roce 2001). Pokud jde o "hack&amp;slash" RPGs, tak Diablo II s datadiskem u mě zvítězilo na plné čáře. Hra měla obrovskou znovuhratelnost, protože mapy byly generovány náhodně, a stejně tak předměty, které jste našli. Nejraději jsem hrával za <a href="https://diablo.fandom.com/wiki/Sorceress_(Diablo_II)">Sorceress</a> (Frozen Orb a Meteor) a <a href="https://diablo.fandom.com/wiki/Necromancer_(Diablo_II)">Necromancer</a> (Bone Spear/Spirit a Bone Prison).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Unreal_Tournament">Unreal Tournament</a></strong> alias UT99 (vydáno v roce 1999) a <strong><a href="https://en.wikipedia.org/wiki/Unreal_Tournament_2004">Unreal Tournament 2004</a></strong> alias UT2k4 (vydáno v roce 2004). Aaaaah, můj milovaný "unreal" :-). Tehdy jsem hrával pod nickem ZmAsteR ("Zemek Master"). Jednalo se o dvě hry, ve kterých jsem tehdy byl jeden z nejlepších lidí v republice. Hrával jsem na soutěžích, jak sám, tak za klany, i za českou reprezentaci. Na kvalifikaci na olympiádu za ČR jsem u UT 2004 skončil na čtvrtém místě. Níže pak přikládám jednak fotku z jedné LAN party, a jednak screenshot z UT 2004, jak jsme jednou vyklepli Anglii :-).<br /><center> <div> <a href="//cs-blog.petrzemek.net/images/ut2004-lan-party.png" title="Já na jedné LAN party"><img src="//cs-blog.petrzemek.net/images/ut2004-lan-party.png" alt="Já na jedné LAN party" width="200" style="display: inline; margin-right: 10px;" /></a><a href="//cs-blog.petrzemek.net/images/ut2004-cz-uk.png" title="Zápas proti anglické reprezentaci"><img src="//cs-blog.petrzemek.net/images/ut2004-cz-uk.png" alt="Zápas proti anglické reprezentaci" width="200" style="display: inline" /></a> </div> <p> </p></center> <p> Bohužel jsem tehdy neměl moc kvalitní připojení k Internetu (bezdrátové spojení, které lagovalo a vypadávalo), což mě tehdy dost omezovalo. Když jsem se pak na konci roku 2005 přesunul na univerzitní koleje, kde byla suprová optika (ping 12-20 ms do Německa), tak jsem s hraním skončil, protože jsem se chtěl víc věnovat škole a programování. Takže jsem nakonec to kvalitní spojení moc nevyužil. Hrávali jsme tehdy pro zábavu i s kamarády, ať už ve škole, nebo na LAN parties. Jó, to byly časy :-).</p> <p> Co se pak týče UT99 verus UT2k4, tak víc času jsem strávil u UT99, ale lepší jsem byl asi v UT2k4. U UT99 se mi hodně líbilo, jak moc se hrálo <a href="https://unreal.fandom.com/wiki/Capture_the_Flag">CTF</a>, které se u UT2k4 moc neujalo. Taktéž mi přišlo, že z hlediska 1v1 na profesionální úrovni se u UT2k4 točilo prakticky jen pár map (typicky Rankin, Ironic a Roughinery), kdežto u UT99 jich bylo víc. Co se pak týče <a href="https://en.wikipedia.org/wiki/Unreal_Tournament_2003">Unreal Tournament 2003</a>, tak tato verze šla úplně mimo mě (byl u ní dost odklon od UT99, a přešel jsem pak až k UT2k4). Další hry z Unreal série jsem nehrál. Pro zajímavost, configy mám ještě stále uložené <a href="https://github.com/s3rvac/dotfiles/tree/master/games">zde</a>.</p></li> <li><strong><a href="https://en.wikipedia.org/wiki/Quake_III_Arena">Quake III Arena</a></strong> (vydáno v roce 1999). Kromě Unreal Tournament jsem občas hrával i "kvejka". Líbilo se mi na něm to, že si člověk mohl zobrazení kompletně přizpůsobit svým představám, takže např. bylo možné si úplně vyhladit textury (aby nebily do očí) a zvýraznit postavu protivníka (<a href="https://qlhud.lifeisabug.com/files/screenshots/Something_OUMy3w.jpg">ukázka</a>), což např. v prvním Unreal Tournamentu možné nebylo. Nicméně pokud srovnám Quake III a Unreal Tournament z časového pohledu, tak Unreal Tournament jsem hrál asi 99% času a zbylé 1% tvoří Quake.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Age_of_Empires_II">Age of Empires II</a></strong> (vydáno v roce 1999) a datadisk <strong><a href="https://en.wikipedia.org/wiki/Age_of_Empires_II:_The_Conquerors">Age of Empires II: The Conquerors</a></strong> (vydáno v roce 2000). Za mě nejlepší multi-player strategická hra, kterou jsem hrával. Nejvíc si vzpomínám na to, jak spolužák přišel s tím, že jeho kamarád je v té hře prý hodně dobrý by si proti nám rád zahrál. Hráli jsme tehdy osm proti němu a vyklepal nás všechny :-D. Zjistil jsem pak, že se jednalo v té době o jednoho z nejlepších Čechů v této hře. Viděl jsem ho pak jednou hrát naživo v herně a na ten pohled nezapomenu - úplně mi to změnilo pohled na tu hru, kdy jsem si uvědomil, jak moc velká lama na strategické hry jsem byl :-).</li> <li><strong><a href="https://en.wikipedia.org/wiki/Counter-Strike_(video_game)">Counter-Strike</a></strong> (vydáno v roce 2000). "Kántra" jsem tehdy hrával v dřevních dobách verzí 1.0 - 1.6 s tím, že si ještě pamatuji, jak ve verzi 1.3 zrušili <a href="https://news.ycombinator.com/item?id=22221048">bunny hopping</a> :-) (kdo pamatujete?). Hrávali jsme tehdy hodně s kamarády v herně (5v5), ale hrával jsem i online, i když je fakt, že pouze čtvrtou Gamezone ligu :-). Counter-Strike mě hrozně moc bavil, ale v Unreal Tournamentu jsem byl mnohem lepší.</li> <li><strong><a href="https://en.wikipedia.org/wiki/Warcraft_III:_Reign_of_Chaos">Warcraft 3</a></strong> (vydáno v roce 2002) a datadisk <strong><a href="https://en.wikipedia.org/wiki/Warcraft_III:_The_Frozen_Throne">The Frozen Throne</a></strong> (vydáno v roce 2003). Třetí díl Warcraftu se mi líbil a chvíli jsem jej hrál i online (jen oddechově). Mou nejoblíbenější rasou byli Undead následovaní Orky.</li> </ul><h2>A co hry mimo počítač?</h2> <p>Na deskovky bych si raději vyhradil samostatný článek. Nicméně, když pominu počítačové a deskové hry, tak v mládí nejvíc vzpomínám na <a href="https://en.wikipedia.org/wiki/Game_Boy">Game Boy</a>. Tato konzole a hry na ní byly v devadesátých letech poměrně hodně drahé, takže jsem jich moc nehrál. Každopádně, nejvíc vzpomínám na následující dvě:</p> <ul><li><strong><a href="https://en.wikipedia.org/wiki/Super_Mario_Land_2:_6_Golden_Coins">Super Mario Land 2</a></strong> (vydáno v roce 1993)</li> <li><strong><a href="https://en.wikipedia.org/wiki/Wario_Land:_Super_Mario_Land_3">Wario Land: Super Mario Land 3</a></strong> (vydáno v roce 1994)</li> </ul><p>Kromě Game Boye jsem hry na konzolích prakticky nehrál, tedy mimo chvilkové hraní na <a href="https://en.wikipedia.org/wiki/Super_Nintendo_Entertainment_System">Super Nintendo Entertainment System (SNES)</a> či <a href="https://en.wikipedia.org/wiki/PlayStation">PlayStation</a>, když jsem byl u někoho na návštěvě.</p> <p>A jaké byly vaše nejoblíbenější hry? Hráli jste spíš na počítači, nebo na konzolích?</p> </div> <span><span>Petr Zemek</span></span> <span>2023-03-08 - 19:01</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/108" hreflang="cs">hry</a></div> <div class="field__item"><a href="/taxonomy/term/35" hreflang="cs">progaming</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=228&amp;2=comment_node_blog&amp;3=comment_node_blog" token="9vgJzkJKK_uHHIrj_uuOKCO5zocX77_4axgNTRl8BFs"></drupal-render-placeholder> </div> </div> <article data-comment-user-id="0" id="comment-2804" class="comment js-comment comment--level-1 by-anonymous" role="article" data-drupal-selector="comment"> <span class="hidden" data-comment-timestamp="1683536851"></span> <div class="comment__picture-wrapper"> <div class="comment__picture"> </div> </div> <div class="comment__text-wrapper"> <footer class="comment__meta"> <p class="comment__author"><a rel="nofollow" href="https://petrhlozek.cz/">Petr (neověřeno)</a></p> <p class="comment__time">4 měsíce 3 týdny zpět</p> </footer> <div class="comment__content"> <h3><a href="/comment/2804#comment-2804" class="permalink" rel="bookmark" hreflang="cs">Hry mého mládí</a></h3> <div class="text-content field field--name-comment-body field--type-text-long field--label-hidden field__item comment__text-content"><p>Dobrý den,</p> <p>na Váš web jsem se dostal díky Vaší přednášce <a href="https://www.youtube.com/watch?v=ORnIXpITa4g">https://www.youtube.com/watch?v=ORnIXpITa4g</a>. Díky za ni.</p> <p>Můj první počítač byla 286 s 1MB RAM, 40MB MFM diskem a grafikou Herkules, psal se rok 1996. Prince of Persia byla také moje první hra, Warcraft jsem také hrával přes sériový kabel (tehdy už na 386). U Dune II jsem strávil hodiny. Později Command &amp; Conquer u které jsem strávil dny a noci, týdny. U žádné jiné hry jsem nestrávil tolik času.<br /> Později Worms, které mě fakt bavily, hrávali jsme u kamaráda na počítači, můj je nezvládal.</p> <p>U Carmageddonu hodiny kdy jsme se s kamarádem předháněli kdo dostane větší počet bodů za kreativní odstranění lidí ze světa.</p> <p>Rád jsem hrával hru Lemris <a href="http://www.stare-hry.cz/hry/ostatni/lemris/">http://www.stare-hry.cz/hry/ostatni/lemris/</a> líbilo by se mi ji mít na telefonu, ale asi by neprošla schvalovacím procesem ve Store.</p> <p>Nezapomněl jste na F-29 Retaliator? Ten jsem hrál s bratrem přes sériový port a bylo to super! Měl jsem mezi našimi pokoji natažen sériový kabel na hry a paralelní na přenos dat pomocí Norton commanderu :-).</p> <p>Nějak mě hraní her (kromě Red Alert 2 Yuri's Revenge) přestalo bavit a raději jsem se věnoval/věnuji programování i když ne na takové úrovni jako Vy.</p> <p>Mějte se krásně.</p> <p>Petr Hložek</p> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=2804&amp;1=default&amp;2=cs&amp;3=" token="dVrSA_QZ45w3MJ_zzv8WuILadfVRRwQdgpXBpRwJ47o"></drupal-render-placeholder> </div> </div> </article> <div class="indented"> <article data-comment-user-id="1" id="comment-2805" class="comment js-comment by-node-author" role="article" data-drupal-selector="comment"> <span class="hidden" data-comment-timestamp="1683641186"></span> <div class="comment__picture-wrapper"> <div class="comment__picture"> </div> </div> <div class="comment__text-wrapper"> <footer class="comment__meta"> <p class="comment__author"><span>Petr Zemek</span></p> <p class="comment__time">4 měsíce 3 týdny zpět</p> <p class="visually-hidden">In reply to <a href="/comment/2804#comment-2804" class="permalink" rel="bookmark" hreflang="cs">Hry mého mládí</a> by <a rel="nofollow" href="https://petrhlozek.cz/">Petr (neověřeno)</a></p> </footer> <div class="comment__content"> <h3><a href="/comment/2805#comment-2805" class="permalink" rel="bookmark" hreflang="cs">Re: Hry mého mládí</a></h3> <div class="text-content field field--name-comment-body field--type-text-long field--label-hidden field__item comment__text-content"><p>Děkuji za komentář :-).</p> <p><cite>Nezapomněl jste na F-29 Retaliator?</cite></p> <p>F-29 Retaliator mě minul, stejně jako Command &amp; Conquer a Red Alert (ty jsem hrál jen velmi krátce).</p> <p><cite>Nějak mě hraní her (kromě Red Alert 2 Yuri's Revenge) přestalo bavit</cite></p> <p>Mám to podobně. Hry jsem hrával dost cca do konce roku 2005. Poté jsem s hraním přestal a věnoval se primárně studiu a programování. V současné době hrávám jen sporadicky.</p> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=2805&amp;1=default&amp;2=cs&amp;3=" token="kc3Z3GEL1lLX4G-t9baR89pioMc1K0eSZ82DstLuHq0"></drupal-render-placeholder> </div> </div> </article> </div> </section> Wed, 08 Mar 2023 18:01:34 +0000 Petr Zemek 228 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2023-03-08-hry-meho-mladi#comments Tipy na mysteriózní filmy https://cs-blog.petrzemek.net/2021-09-25-tipy-na-mysteriozni-filmy <span>Tipy na mysteriózní filmy</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Jakožto pravověrný fanoušek mysteriózních filmů se s vámi chci podělit o své tipy na skvělé kousky ;-).</p> <h2>Pár poznámek na začátek</h2> <ul><li>Před zhlédnutím těchto filmů si o nich doporučuji naprosto nic nečíst, a už rozhodně se nedívat na trailery. V některých případech totiž trailer vyzrazuje hlavní zvrat filmu, takže váš požitek z něj se sníží.</li> <li>U filmů jsem se snažil uvést i jejich žánr a případné dodatečné poznámky, na co si dát pozor. Např. pokud vám vadí násilí či krev, tak se zkuste (opatrně!) podívat na <em>MPAA</em> rating a <em>Parent Advisory</em> na IMDB. Pokud tam uvidíte něco ve stylu <em>"Rated R for strong grisly violence"</em>, tak to asi nebude film pro vás (či vaši drahou polovičku).</li> <li>Mysteriózních filmů je spoustu, ale ne všechny za to stojí (čti "ne všechny se mi líbily").</li> <li>U všech filmů doporučuji zkouknout verzi, kterou zde zmiňuji. Ve většině případů se jedná o originál (ne remake), protože remaky většiny filmů dopadly velmi špatně. Výjimkou je např. The Ring, u kterého se mi víc líbila americká verze, než ta původní japonská.</li> <li>Jako vždy, to, že se některý film líbí mně ještě neznamená, že se bude líbit vám.</li> <li>Je možné, že seznam budu průběžně aktualizovat. To jen, kdybyste v seznamu viděli film z roku 2022 i přesto, že tento blogový příspěvek byl napsán v roce 2021.</li> </ul><h2>Tipy</h2> <p>Filmy jsem seřadil podle roku vydání.</p> <ul><li><a href="https://www.csfd.cz/film/4386-okno-do-dvora/prehled/">Rear Window</a> (1954), thriller</li> <li><a href="https://www.csfd.cz/film/15745-jakubuv-zebrik/prehled/">Jacob's Ladder</a> (1990), drama / horor, násilí</li> <li><a href="https://www.csfd.cz/film/8411-obvykli-podezreli/prehled/">The Usual Suspects</a> (1995), drama / krimi / thriller</li> <li><a href="https://www.csfd.cz/film/2671-sedm/prehled/">Seven</a> (1995), drama / krimi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/35240-diplomova-prace/prehled/">Tesis</a> (1996), drama / horor / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/4123-l-a-prisne-tajne/prehled/">L.A. Confidential</a> (1997), drama / krimi / thriller</li> <li><a href="https://www.csfd.cz/film/149-horizont-udalosti/prehled/">Event Horizon</a> (1997), horor / sci-fi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/6255-lost-highway/prehled/">Lost Highway</a> (1997), drama / thriller</li> <li><a href="https://www.csfd.cz/film/33285-kostka/prehled/">Cube</a> (1997), horor / scifi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/2667-klub-rvacu/prehled/">Fight Club</a> (1999), drama / thriller</li> <li><a href="https://www.csfd.cz/film/8364-sesty-smysl/prehled/">The Sixth Sense</a> (1999), drama / thriller</li> <li><a href="https://www.csfd.cz/film/8212-8-mm/prehled/">8MM</a> (1999), krimi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/6869-zahada-blair-witch/prehled/">The Blair Witch Project</a> (1999), horor</li> <li><a href="https://www.csfd.cz/film/6995-memento/prehled/">Memento</a> (2000), thriller</li> <li><a href="https://www.csfd.cz/film/19026-vrazedna-terapie/prehled/">Session 9</a> (2001), horor / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/16367-donnie-darko/prehled/">Donnie Darko</a> (2001), drama / sci-fi</li> <li><a href="https://www.csfd.cz/film/6256-mulholland-drive/prehled/">Mulholland Drive</a> (2001), drama / thriller</li> <li><a href="https://www.csfd.cz/film/8227-telefonni-budka/prehled/">Phone Booth</a> (2002), thriller</li> <li><a href="https://www.csfd.cz/film/43514-kruh/prehled/">The Ring</a> (2002), horor / thriller</li> <li><a href="https://www.csfd.cz/film/168893-old-boy/prehled/">Oldboy</a> (2003), drama / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/157306-pecet-vraha/prehled/">Salinui chueok</a> (2003), drama / krimi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/71263-bazen/prehled/">Swimming Pool</a> (2003), drama</li> <li><a href="https://www.csfd.cz/film/70971-identita/prehled/">Identity</a> (2003), horor / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/16758-smrt-prichazi-v-bilem/prehled/">Dead End</a> (2003), horor / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/133466-miluj-me-prosim/prehled/">Wicker Park</a> (2004), drama / thriller</li> <li><a href="https://www.csfd.cz/film/197195-shutter/prehled/">Shutter</a> (2004), horor / thriller</li> <li><a href="https://www.csfd.cz/film/116212-mechanik/prehled/">The Machinist</a> (2004), drama / thriller</li> <li><a href="https://www.csfd.cz/film/38810-ztrata-pameti/prehled/">The I Inside</a> (2004), sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/45608-osudovy-dotek/prehled/">The Butterfly Effect</a> (2004), sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/173957-saw-hra-o-preziti/prehled/">Saw</a> (2004), horor / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/135406-sveraci-kazajka/prehled/">The Jacket</a> (2005), sci-fi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/202256-metoda/prehled/">El método</a> (2005), drama / thriller</li> <li><a href="https://www.csfd.cz/film/224351-neznamy/prehled/">Unknown</a> (2006), drama / thriller</li> <li><a href="https://www.csfd.cz/film/223160-dokonaly-trik/prehled/">The Prestige</a> (2006), drama / thriller</li> <li><a href="https://www.csfd.cz/film/241887-fermatuv-pokoj/prehled/">La Habitación de Fermat</a> (2007), thriller</li> <li><a href="https://www.csfd.cz/film/235331-pozemstan/prehled/">The Man from Earth</a> (2007), drama / sci-fi</li> <li><a href="https://www.csfd.cz/film/226199-sbohem-baby/prehled/">Gone Baby Gone</a> (2007), drama / krimi</li> <li><a href="https://www.csfd.cz/film/221713-zodiac/prehled/">Zodiac</a> (2007), drama / krimi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/230480-vymena/prehled/">Changeling</a> (2008), drama / historický / krimi / thriller / životopisný</li> <li><a href="https://www.csfd.cz/film/268852-zkouska/prehled/">Exam</a> (2009), thriller</li> <li><a href="https://www.csfd.cz/film/252831-pokuseni/prehled/">Chloe</a> (2009), drama / thriller</li> <li><a href="https://www.csfd.cz/film/229692-cerna-labut/prehled/">Black Swan</a> (2010), drama / thriller</li> <li><a href="https://www.csfd.cz/film/254156-pocatek/prehled/">Inception</a> (2010), thriller / akční / sci-fi / dobrodružný</li> <li><a href="https://www.csfd.cz/film/235492-proklety-ostrov/prehled/">Shutter Island</a> (2010), thriller / drama</li> <li><a href="https://www.csfd.cz/film/269231-zdrojovy-kod/prehled/">Source Code</a> (2011), sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/306043-la-cara-oculta/prehled/">La Cara oculta</a> (2011), thriller / drama</li> <li><a href="https://www.csfd.cz/film/300079-enter-nowhere/prehled/">Enter Nowhere</a> (2011), drama</li> <li><a href="https://www.csfd.cz/film/303916-divka-z-budoucnosti/prehled/">Sound of My Voice</a> (2011), drama / thriller</li> <li><a href="https://www.csfd.cz/film/140841-telo/prehled/">El cuerpo</a> (2012), krimi / thriller</li> <li><a href="https://www.csfd.cz/film/301629-slova/prehled/">The Words</a> (2012), drama / romantický</li> <li><a href="https://www.csfd.cz/film/303202-sinister/prehled/">Sinister</a> (2012), horor / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/351648-coherence/prehled/">Coherence</a> (2013), sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/309312-zprava-o-europe/prehled/">Europa Report</a> (2013), sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/257071-zmizeni/prehled/">Prisoners</a> (2013), drama / krimi / thriller, násilí</li> <li><a href="https://www.csfd.cz/film/346911-predestination/prehled/">Predestination</a> (2014), sci-fi / thriller / drama</li> <li><a href="https://www.csfd.cz/film/227786-interstellar/prehled/">Interstellar</a> (2014), sci-fi / dobrodružný / drama</li> <li><a href="https://www.csfd.cz/film/343881-vychozi-bod/prehled/">I Origins</a> (2014), drama / sci-fi / romantický</li> <li><a href="https://www.csfd.cz/film/371509-pod-zemi/prehled/">As Above, So Below</a> (2014), thriller / horor, násilí</li> <li><a href="https://www.csfd.cz/film/372088-fotky-zitrka/prehled/">Time Lapse</a> (2014), sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/346856-zmizela/prehled/">Gone Girl</a> (2014), drama / krimi / thriller</li> <li><a href="https://www.csfd.cz/film/359547-drishyam/prehled/">Drishyam</a> (2015), drama / thriller</li> <li><a href="https://www.csfd.cz/film/412019-darek/prehled/">The Gift</a> (2015), thriller</li> <li><a href="https://www.csfd.cz/film/457067-contratiempo/prehled/">Contratiempo</a> (2016), thriller</li> <li><a href="https://www.csfd.cz/film/379848-prichozi/prehled/">Arrival</a> (2016), drama / sci-fi / thriller</li> <li><a href="https://www.csfd.cz/film/548582-ittefaq/recenze/">Ittefaq</a> (2017), thriller</li> <li><a href="https://www.csfd.cz/film/586217-patrani/prehled/">Searching</a> (2018), drama / thriller</li> <li><a href="https://www.csfd.cz/film/651342-na-noze/prehled/">Knives Out</a> (2019), krimi / drama / thriller</li> <li><a href="https://www.csfd.cz/film/1069417-nevyzpytatelne-cesty-bozi/prehled/">Los renglones torcidos de Dios</a> (2022), drama / thriller</li> </ul><p>Co říkáte na můj výběr? Máte další tipy na skvělé mysteriózní filmy?</p> </div> <span><span>Petr Zemek</span></span> <span>2021-09-25 - 12:07</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/15" hreflang="cs">filmy</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=227&amp;2=comment_node_blog&amp;3=comment_node_blog" token="qBTh_wu-h1iK_O00PZol2Nk45q9yFQXwgn0rERjiu28"></drupal-render-placeholder> </div> </div> </section> Sat, 25 Sep 2021 10:07:04 +0000 Petr Zemek 227 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2021-09-25-tipy-na-mysteriozni-filmy#comments Jak na čitelnější testy: odstraňování zbytečných hodnot https://cs-blog.petrzemek.net/2021-04-03-jak-na-citelnejsi-testy-odstranovani-zbytecnych-hodnot <span>Jak na čitelnější testy: odstraňování zbytečných hodnot</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Rychlý tip, jak zčitelnit testy pomocí odstranění hodnot, které v testu nejsou potřeba.</p> <!--break--><h2>Původní kód</h2> <p>Mějme následující dva testy:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> test_is_admin_returns_true_when_user_has_admin_role<span style="color: black;">(</span><span style="color: black;">)</span>: <span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> User<span style="color: black;">(</span> name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'František Veselý'</span><span style="color: #66cc66;">,</span> birth_date<span style="color: #66cc66;">=</span>Date<span style="color: black;">(</span><span style="color: #ff4500;">1985</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">30</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">11</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> address<span style="color: #66cc66;">=</span>Address<span style="color: black;">(</span><span style="color: #483d8b;">'Jiráskova'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">225</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Rokycany'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">33701</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">email</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">'frantisek.vesely@gmail.com'</span><span style="color: #66cc66;">,</span> phone<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'+420608123456'</span><span style="color: #66cc66;">,</span> roles<span style="color: #66cc66;">=</span><span style="color: black;">[</span><span style="color: #483d8b;">'admin'</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> preferences<span style="color: #66cc66;">=</span>UserPreferences<span style="color: black;">(</span> theme<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'light'</span><span style="color: #66cc66;">,</span> timezone<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'Europe/Berlin'</span><span style="color: #66cc66;">,</span> <span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">)</span>   <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #dc143c;">user</span>.<span style="color: black;">is_admin</span><span style="color: black;">(</span><span style="color: black;">)</span>   <span style="color: #ff7700;font-weight:bold;">def</span> test_is_admin_returns_false_when_user_does_not_have_admin_role<span style="color: black;">(</span><span style="color: black;">)</span>: <span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> User<span style="color: black;">(</span> name<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'František Veselý'</span><span style="color: #66cc66;">,</span> birth_date<span style="color: #66cc66;">=</span>Date<span style="color: black;">(</span><span style="color: #ff4500;">1985</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">30</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">11</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> address<span style="color: #66cc66;">=</span>Address<span style="color: black;">(</span><span style="color: #483d8b;">'Jiráskova'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">225</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'Rokycany'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">33701</span><span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">email</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">'frantisek.vesely@gmail.com'</span><span style="color: #66cc66;">,</span> phone<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'+420608123456'</span><span style="color: #66cc66;">,</span> roles<span style="color: #66cc66;">=</span><span style="color: black;">[</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> preferences<span style="color: #66cc66;">=</span>UserPreferences<span style="color: black;">(</span> theme<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'light'</span><span style="color: #66cc66;">,</span> timezone<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'Europe/Berlin'</span><span style="color: #66cc66;">,</span> <span style="color: black;">)</span><span style="color: #66cc66;">,</span> <span style="color: black;">)</span>   <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">user</span>.<span style="color: black;">is_admin</span><span style="color: black;">(</span><span style="color: black;">)</span></pre></div> <p>Zkuste si tyto dva testy projít, pochopit, a pak pokračovat ve čtení.</p> <h2>Proč takto ne?</h2> <p>Oba testy obsahují hodnoty, které z hlediska testu nejsou vůbec potřeba. Obecně, testy by měly obsahovat pouze potřebný kód. Pokud je v testu kód, který můžete upravit či zrušit, aniž by to mělo na test vliv, tak je to typický příznak toho, že se jedná o nepotřebnou hodnotu. Programátor, který se snaží test pochopit se pak musí prokousat množstvím balastu, což jednak zdržuje, a jednak to odvádí pozornost.</p> <p>Další nevýhodou je, že pokud do třídy <span class="geshifilter"><code class="text geshifilter-text">User</code></span> přidáme nový atribut, tak musíme upravit množství testů, i když tento atribut vůbec nepotřebují. Recenzent koukající se na diff takového pull requestu se bude určitě divit, proč se kvůli přidání nového atributu muselo měnit tolik testů.</p> <h2>Jak to udělat lépe?</h2> <p>Vytvořením pomocné funkce, která se postará o vytvoření uživatele na základě předaných hodnot s tím, že za nezadané hodnoty doplní jakékoliv výchozí hodnoty. Testy pak budou mnohem čitelnější:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> test_is_admin_returns_true_when_user_has_admin_role<span style="color: black;">(</span><span style="color: black;">)</span>: <span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> any_user<span style="color: black;">(</span>roles<span style="color: #66cc66;">=</span><span style="color: black;">[</span><span style="color: #483d8b;">'admin'</span><span style="color: black;">]</span><span style="color: black;">)</span>   <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #dc143c;">user</span>.<span style="color: black;">is_admin</span><span style="color: black;">(</span><span style="color: black;">)</span>   <span style="color: #ff7700;font-weight:bold;">def</span> test_is_admin_returns_false_when_user_does_not_have_admin_role<span style="color: black;">(</span><span style="color: black;">)</span>: <span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> any_user<span style="color: black;">(</span>roles<span style="color: #66cc66;">=</span><span style="color: black;">[</span><span style="color: black;">]</span><span style="color: black;">)</span>   <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">user</span>.<span style="color: black;">is_admin</span><span style="color: black;">(</span><span style="color: black;">)</span></pre></div> <p>Další výhoda je ta, že testy budou typicky odolnější vůči změnám, např. přidání nového atributu do třídy <span class="geshifilter"><code class="text geshifilter-text">User</code></span>.</p> </div> <span><span>Petr Zemek</span></span> <span>2021-04-03 - 12:19</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/7" hreflang="cs">programování</a></div> <div class="field__item"><a href="/taxonomy/term/45" hreflang="cs">testování</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=226&amp;2=comment_node_blog&amp;3=comment_node_blog" token="7WAeWuh7l03rH7f1MZ5QjVbnY1znoLBJNie860reO98"></drupal-render-placeholder> </div> </div> </section> Sat, 03 Apr 2021 10:19:43 +0000 Petr Zemek 226 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2021-04-03-jak-na-citelnejsi-testy-odstranovani-zbytecnych-hodnot#comments Recenze knihy "Méně je více" https://cs-blog.petrzemek.net/2021-03-21-recenze-knihy-mene-je-vice <span>Recenze knihy &quot;Méně je více&quot;</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Recenze knihy <a href="https://www.databazeknih.cz/knihy/mene-je-vice-435929">Méně je více</a> od <a href="https://caitflanders.com/">Cait Flanders</a>.</p> <!--break--><p> <a href="https://en.wikipedia.org/wiki/Simple_living">Minimalizmus</a> je něco, co mě dlouhodobě zajímá. Po <a href="https://www.databazeknih.cz/knihy/menej-je-viac-142762">Menej je viac</a> (Leo Babauta) a <a href="https://www.melvil.cz/kniha-digitalni-minimalismus/">Digitální minimalismus</a> (Cal Newport) jsem se dostal ke knize <a href="https://www.databazeknih.cz/knihy/mene-je-vice-435929">Méně je více</a> od <a href="https://caitflanders.com/">Cait Flanders</a>.</p> <h2>Základní informace</h2> <ul><li><strong>Název knihy:</strong> Méně je více (přeloženo z anglického originálu <em>The Year of Less</em>)</li> <li><strong>Autor:</strong> Cait Flanders</li> <li><strong>Počet stran:</strong> 220</li> <li><strong>Rok vydání:</strong> originál 2018, překlad 2020</li> </ul><p>Obal (převzat z <a href="https://www.databazeknih.cz/knihy/mene-je-vice-435929">databazeknih.cz</a>):</p> <p></p><center><br /><a href="/images/kniha-mene-je-vice-obal.jpg" title="Obal knihy"><img src="/images/kniha-mene-je-vice-obal.jpg" alt="Obal knihy" /></a><br /></center> <h2>Jak bych stručně popsal obsah</h2> <p>Kniha je životním příběhem autorky, která se rozhodla opustit <a href="https://cs.wikipedia.org/wiki/Konzumerismus">konzumerismus</a> a po jeden rok nenakupovat nic než nezbytně nutné předměty, jako je jídlo či toaletní potřeby. Kromě toho se zbavila 70% všech věcí, které vlastnila. V knize popisuje měsíc po měsíci, jak se jí dařilo, na jaké komplikace narazila a co dělala. Každopádně, kromě této zkoušky Cait popisuje i další strasti, se kterými se musela vypořádat: dluhy, alkoholismus, obsesivní sledování televizních pořadů (angl. <a href="https://en.wikipedia.org/wiki/Binge-watching">binge watching</a>), zajídání pocitů nezdravým jídlem, toxickým vztahem s partnerem a problémy v rodině. Kniha na závěr obsahuje krátkého průvodce redukováním pro ty, kteří by ji chtěli následovat.</p> <h2>Co mě zaujalo</h2> <p>Níže jsem z knihy vypíchnul několik bodů, které mě zaujaly. Před každým je uvedeno číslo stránky, které můžete využít, pokud byste si chtěli přečíst i kontext či něco víc. Samozřejmě, je potřeba mít přístup k českému překladu.</p> <ul><li><strong>82:</strong> <em>"Nemůžeš ukončit čtrnáctiletý vztah s něčím (např. závislost) a očekávat, že si na to nikdy nevzpomeneš."</em> Nelze s něčím skoncovat a očekávat, že se k tomu člověk alespoň myšlenkově nikdy nevrátí. <a href="https://www.databazeknih.cz/knihy/sila-zvyku-157066">Zvyky je navíc potřeba nahrazovat jinými zvyky</a>. I tak ale je třeba počítat s tím, že své minulosti nelze úplně utéct. Je třeba to přijmout a pracovat s tím.</li> <li><strong>86:</strong> <em>"Když se vzdáte něčeho negativního, uvolníte tím místo pro něco pozitivního."</em> Autorka to uvádí na příkladu: Když nedočtu knihu, která se mi nelíbila, tak mi to poskytne víc čas číst knihy, které se mi líbí. Když něco dělám z donucení, tak je třeba se zamyslet nad tím, zda je to opravdu nezbytné, a pokud ne, tak jít raději dělat něco jiného. K čemu se snažit něco dokončit jen proto, protože jste s tím začali? Souvisejícím termínem jsou tzv. <a href="https://cs.wikipedia.org/wiki/Utopen%C3%A9_n%C3%A1klady">utopené náklady</a> (angl. <a href="https://en.wikipedia.org/wiki/Sunk_cost#Fallacy_effect">sunk cost fallacy</a>).</li> <li><strong>130:</strong> <em>"Ještě horší bylo pomyšlení na to, že jsem utratila peníze, abych ušetřila čas, a pak jsem téměř každou minutu promarnila."</em> Když se nad tím člověk zamyslí, tak na jedné straně spěcháme, abychom ušetřili pár minut, a na druhé straně pak ušetřený čas strávíme koukáním na seriály.</li> <li><strong>149:</strong> <em>"Pro koho toto kupuješ? Pro osobu, kterou jsi, nebo pro osobu, kterou bys chtěla být?"</em> Je třeba se podívat pravdě do očí. Každý o sobě máme představy, jak bychom měli vypadat, co bychom měli umět, co bychom měli dělat apod. Ne vždy jsou ale tyto představy reálné, a ne vždy je to něco, co skutečně chceme. Takže, než něco koupíme či si zapíšeme na TODO list, měli bychom se zamyslet nad motivací za danou položkou.</li> <li><strong>158:</strong> <em>"Věděla jsem, že nezdravým jídlem polykám své pocity."</em> To stejné se mnohdy dát říct o sledování seriálů, hraní her a dalších aktivitách. Pokud to člověk dělá pro odreagování, tak je to v pohodě. Horší je, když je to provozováno s cílem se alespoň na chvíli necítit tak špatně.</li> <li><strong>159:</strong> <em>"Je to zvláštní, když si je člověk zcela vědom toho, co dělá, a přece se rozhodne dělat to dál, navzdory tomu, že ví, že je to špatné."</em> Je to zvláštní, viďte?</li> <li><strong>209:</strong> <em>"Když strádáte, tak to nelze spravit žádným jídlem, pitím, nebo nakupováním. Musíte odhalit příčinu a zjistit, co se s vámi doopravdy děje."</em> Ač si to nechceme přiznat, je třeba hledat příčinu, ne se snažit pouze řešit následky.</li> </ul><h2>Zhodnocení</h2> <p>Kniha mě zaujala a přečetl jsem ji téměř jedním dechem. S autorkou jsem mnohdy soucítil, a spoustu z toho, co napsala, dávalo smysl a dokázal jsem se s tím ztotožnit. To, že (ne)nakupování se věnovala jen část knihy mi nevadilo. Kvalita sazby, tisku i překladu je na dobré úrovni. Pokud vnímáte, že nakupujete či doma schraňujete spoustu zbytečností, máte problém se závislostí, či jen rádi čtete životní příběhy, tak knihu mohu rozhodně doporučit.</p> <p>A nyní otázka na vás, na čtenáře: Máte nějakou svou oblíbenou knihu o minimalizmu, kterou byste mi doporučili? Budu rád, když se o svůj tip podělíte v komentáři :-).</p> </div> <span><span>Petr Zemek</span></span> <span>2021-03-21 - 12:27</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/51" hreflang="cs">knihy</a></div> <div class="field__item"><a href="/taxonomy/term/107" hreflang="cs">recenze</a></div> <div class="field__item"><a href="/taxonomy/term/77" hreflang="cs">osobní rozvoj</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=225&amp;2=comment_node_blog&amp;3=comment_node_blog" token="FBLGLcxk2BRU_KX48JNQ2hivA5lBpD3TlRg2Hpev-XM"></drupal-render-placeholder> </div> </div> </section> Sun, 21 Mar 2021 11:27:09 +0000 Petr Zemek 225 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2021-03-21-recenze-knihy-mene-je-vice#comments Řešení gamebooku "Strašlivý netvor" https://cs-blog.petrzemek.net/2021-02-01-reseni-gamebooku-straslivy-netvor <span>Řešení gamebooku &quot;Strašlivý netvor&quot;</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Když jsem byl menší, tak jsem měl velmi v oblibě tzv. <a href="https://cs.wikipedia.org/wiki/Gamebook">gamebooky</a> ze série <a href="https://cs.wikipedia.org/wiki/Fighting_Fantasy#Knihy_Fighting_Fantasy">Fighting Fantasy</a>. Vlastnili jsme je s bráchou skoro všechny, které v té době vyšly přeložené do češtiny (cca 40 knížek). Jeden jsem však nikdy nedohrál: <a href="https://www.databazeknih.cz/knihy/fighting-fantasy-straslivy-netvor-41162">Strašlivého netvora</a>. Rozhodl jsem se to po více než 20 letech napravit a tento svou obtížností nechvalně známý gamebook dohrát :-). Podařilo se. Ale byly to nervy.</p> <!--break--><h2>Proč je tento gamebook tak obtížný?</h2> <p>Důvodů je více:</p> <ul><li>V první části knihy neovládáte lidskou řeč, takže veškeré mluvené i psané slovo je zašifrované. Musíte najít místo, kde se dozvíte, jak šifra funguje, a potom si texty dešifrovat.</li> <li>Na začátku knihy nemáte schopnost samostatného rozhodování a rozhodují za vás hody kostkou. Takže i když např. víte, že někudy jít nechcete, tak s tím nic nenaděláte.</li> <li>Kniha obsahuje celou řadu smrtí či slepých cest.</li> <li>V knize je mnoho soubojů a několik zkoušek na štěstí či umění boje, u kterých je potřeba uspět (jinak následuje konec hry).</li> <li>V neposlední řadě je v knize spousta situací typu "pokud narazíš na odkaz s X, tak odečti/přičti Y a otoč na nový odkaz". Nepomůže vám tedy ani kompletní prohledání stavového prostoru, protože v mnoha případech nejsou potřebné přesuny v knize přímo zmíněny. Musíte je najít, např. dešifrováním řeči.</li> </ul><h2>Řešení</h2> <p>Následující řešení není jediné možné, ale troufám si tvrdit, že patří mezi ty nejkratší a nejbezpečnější (např. s ohledem na množství soubojů či zvyšování staminy a štěstí). Vycházím z <a href="https://www.databazeknih.cz/knihy/fighting-fantasy-straslivy-netvor-41162">českého překladu</a> vydaného v roce 1999.</p> <h3>Část I: Podzemní labyrint</h3> <ul><li><strong>1</strong>: Šlápnout trpaslíkovi na krk → <strong>185</strong>.</li> <li><strong>185</strong>: Prozkoumat tělo → <strong>399</strong>.</li> <li><strong>399</strong>: Zašifrovaný text na kousku kůže (<strong>337</strong>). Následuje hod kostkou. Je potřeba se eventuálně dostat na odkaz <strong>205</strong>. <ul><li><strong>308</strong>: → <strong>205</strong>.</li> <li><strong>148</strong>: Následuje hod kostkou. <ul><li><strong>419</strong>: → <strong>308</strong>.</li> <li><strong>72</strong>: Následuje hod kostkou. <ul><li><strong>419</strong>: → <strong>308</strong>.</li> <li><strong>170</strong>: Boj s Drápatcem (9/14). → <strong>389</strong>. Následuje hod kostkou. <ul><li><strong>230</strong>: → <strong>165</strong>.</li> <li><strong>165</strong>: Následuje hod kostkou. <ul><li><strong>344</strong>: → <strong>205</strong>.</li> <li><strong>408</strong>: Konec hry (z tohoto odkazu ji nelze dohrát).</li> </ul></li> </ul></li> </ul></li> </ul></li> </ul></li> <li><strong>205</strong>: Boj s hobitem (5/6). Záleží, jak rychle jej porazíte. Pokud během tří kol, tak → <strong>160</strong>. Pokud boj trvá déle, tak → <strong>86</strong>. Z odkazu <strong>86</strong> se pak po hodu kostkou dostanete buď na <strong>292</strong>, nebo <strong>48</strong> (oba odkazy jsou níže).</li> <li><strong>160</strong>: Zkouška štěstí. Při smůle se dostanete na odkaz <strong>48</strong>, odkud hru nelze dohrát (konec). Při štěstí → <strong>292</strong>.</li> <li><strong>292</strong>: -2 stamina a boj s rytířem (8/9). → <strong>446</strong>.</li> <li><strong>446</strong>: Obnovení veškeré ztracené staminy. Následuje hod kostkou. <ul><li><strong>277</strong>: Ztráta 1 umění boje. → <strong>101</strong>.</li> <li><strong>101</strong>: Následuje hod kostkou. <ul><li><strong>234</strong>: → <strong>447</strong>.</li> <li><strong>168</strong>: -2 stamina. → <strong>447</strong>. </li></ul></li> </ul></li> <li><strong>447</strong>: Boj s třemi masožrouty (6/6, 6/7, 6/6). → <strong>89</strong>.</li> <li><strong>89</strong>: → <strong>382</strong>.</li> <li><strong>382</strong>: Dar rozumu, čili konec rozhodování pomocí kostky :-). +2 stamina. Odchod dveřmi na západě → <strong>51</strong>.</li> <li><strong>51</strong>: Boj se silnorukým (7/8). → <strong>320</strong>.</li> <li><strong>320</strong>: Boj s válečnicí (7/7) a zlodějem (8/6). → <strong>281</strong>.</li> <li><strong>281</strong>: Prozkoumat matný kovový přívěšek → <strong>306</strong>.</li> <li><strong>306</strong>: Získání <em>kovového přívěšku</em>. Pokud otočíš na odkaz začínající na "Nevidíš vůbec nic", odečti od čísla odkazu 20 a přejdi na nový odkaz. +1 štěstí. → <strong>115</strong>.</li> <li><strong>115</strong>: Zkouška štěstí. Je potřeba mít štěstí (→ <strong>166</strong>), protože při smůle následuje konec hry.</li> <li><strong>166</strong>: Pokračovat na západ → <strong>358</strong>.</li> <li><strong>358</strong>: → <strong>257</strong>.</li> <li><strong>257</strong>: "Nevidíš vůbec nic", takže díky přívěšku jdeme na 257 - 20 → <strong>237</strong>.</li> <li><strong>237</strong>: Zářící přívěšek. Pokud otočíš na odkaz začínající na "Nacházíš se", přičti k číslu odkazu 20 a přejdi na nový odkaz. +1 štěstí. → <strong>458</strong>.</li> <li><strong>458</strong>: Vybrat kámen → <strong>110</strong>.</li> <li><strong>110</strong>: Získání <em>krystalové palice</em> s číslem 333 (bude potřeba na konci hry). → <strong>257</strong>.</li> <li><strong>257</strong> (jsme zpět na tomto čísle): Na západ → <strong>309</strong>.</li> <li><strong>309</strong>: Na západ → <strong>280</strong>.</li> <li><strong>280</strong>: Pokračovat dál → <strong>342</strong>.</li> <li><strong>342</strong>: Zaútočit → <strong>258</strong>.</li> <li><strong>258</strong>: Boj s válečníkem (8/9) a bojovníkem (7/8). → <strong>13</strong>.</li> <li><strong>13</strong>: Prohrabat pytel → <strong>147</strong>.</li> <li><strong>147</strong>: Dar řeči. → <strong>283</strong>.</li> <li><strong>283</strong>: Popis, jak dešifrovat řeč a text. +1 štěstí. → <strong>137</strong>.</li> <li><strong>137</strong>: Na sever → <strong>144</strong>.</li> <li><strong>144</strong>: Projít jeskyní → <strong>239</strong>.</li> <li><strong>239</strong>: → <strong>298</strong>.</li> <li><strong>298</strong>: Na východ → <strong>373</strong>.</li> <li><strong>373</strong>: Dveře vlevo → <strong>241</strong>.</li> <li><strong>241</strong>: Boj s orky (7/7, 8/7). → <strong>7</strong>.</li> <li><strong>7</strong>: Je třeba dešifrovat řeč, ve které je uvedeno, že pokud jí rozumíš, tak otoč na → <strong>200</strong>.</li> <li><strong>200</strong>: Hannicus. +2 štěstí a získání <em>stříbrného prstenu</em>. Nechat si jej → <strong>360</strong>.</li> <li><strong>360</strong>: Pokud se střetneš s Darrammousem a dostaneš možnost jej "chytit", tak můžeš prsten použít tak, že přičteš 50 k aktuálnímu odkazu a otočíš na nový odkaz. → <strong>138</strong>.</li> <li><strong>138</strong>: → <strong>15</strong>.</li> <li><strong>15</strong>: Nevšímat si ničeho → <strong>436</strong>.</li> <li><strong>436</strong>: Jít dveřmi na východní straně → <strong>49</strong>.</li> <li><strong>49</strong>: Zkouška štěstí. Je potřeba uspět (→ <strong>457</strong>), jinak hra končí.</li> <li><strong>457</strong>: → <strong>122</strong>.</li> <li><strong>122</strong>: Dveře v severní stěně → <strong>154</strong>.</li> <li><strong>154</strong>: Vylomit dveře → <strong>396</strong>.</li> <li><strong>396</strong>: -1 stamina. Zvednout pergamen → <strong>100</strong>.</li> <li><strong>100</strong>: Bojovat s démonem → <strong>327</strong>.</li> <li><strong>327</strong>: Vrátit se k pergamenu → <strong>192</strong>.</li> <li><strong>192</strong>: Pergamen. Dešifrováním textu zjistíš, že když se budeš domnívat, že jsi našel vstup do úkrytu Zharradana Marra, tak máš od odkazu odečíst 93 a pokračovat na novém odkazu. Taktéž se dozvíš, že si můžeš štěstí navýšit na původní hodnotu. Pokračovat dveřmi na jižní stěně → <strong>450</strong>.</li> <li><strong>450</strong>: → <strong>263</strong>.</li> <li><strong>263</strong>: -1 stamina. Boj s šílenou bestií (7/8). → <strong>209</strong>.</li> <li><strong>209</strong>: Nasytit se mrtvým člověkem → <strong>249</strong>.</li> <li><strong>249</strong>: Zisk <em>dvou zlaťáků</em> a 4 bodů staminy. Napít se zelené tekutiny → <strong>318</strong>.</li> <li><strong>318</strong>: Obnova staminy na její výchozí hodnotu. → <strong>293</strong>.</li> <li><strong>392</strong>: Překvapit tvory za dveřmi → <strong>66</strong>.</li> <li><strong>66</strong>: → <strong>161</strong>.</li> <li><strong>161</strong>: Prozkoumat místnost → <strong>104</strong>.</li> <li><strong>104</strong>: Vstoupit do výklenku → <strong>323</strong>.</li> <li><strong>323</strong>: Prozkoumat jiný výklenek → <strong>220</strong>.</li> <li><strong>220</strong>: Prozkoumat světélka → <strong>56</strong>.</li> <li><strong>56</strong>: Posypání <em>elfím prachem</em> (bude potřeba na konci hry). → <strong>405</strong>.</li> <li><strong>405</strong>: Dveře na severní stěně → <strong>300</strong>.</li> <li><strong>300</strong>: Vyzkoušet západní chodbu → <strong>213</strong>.</li> <li><strong>213</strong>: "Nacházíš se", takže díky zářícímu přívěšku jdeme na 213 + 20 → <strong>233</strong>.</li> <li><strong>233</strong>: Prozkoumat tajnou chodbu → <strong>369</strong>.</li> <li><strong>369</strong>: Dešifrováním řeči zjistíš, že pokud tvorovi rozumíš, máš přejít na → <strong>90</strong>.</li> <li><strong>90</strong>: Darramouss. Máme možnost jej "chytit za krk", takže díky prstenu z odkazu 360 jdeme na 90 + 50 → <strong>140</strong>.</li> <li><strong>140</strong>: Zamířit na sever → <strong>184</strong>.</li> <li><strong>184</strong>: Naznačit, že máš dovoleno odejít → <strong>3</strong>.</li> <li><strong>3</strong>: Neučiníš žádný posunek → <strong>437</strong>.</li> <li><strong>437</strong>: Zůstat na místě → <strong>38</strong>.</li> <li><strong>38</strong>: Ztráta přívěšku. → <strong>442</strong>.</li> </ul><h3>Část II: Venku z labyrintu</h3> <ul><li><strong>442</strong>: Rozhlédnout se kolem budovy → <strong>123</strong>.</li> <li><strong>123</strong>: Ženy z Dree. Splnit úkol (přinesení kořene veslanky) → <strong>324</strong>.</li> <li><strong>324</strong>: +8 stamina a +2 štěstí. Zamířit na jih → <strong>95</strong>.</li> <li><strong>95</strong>: Vesnice Coven. Opustit vesnici na západ → <strong>274</strong>.</li> <li><strong>274</strong>: Pomoct půlorkovi → <strong>291</strong>.</li> <li><strong>291</strong>: Boj s vesničanem (7/8). → <strong>438</strong>.</li> <li><strong>438</strong>: Získání společníka <em>Groga</em>. Pokud bude Grog s tebou, tak kdykoliv přijdete na odkaz končící číslicí 7, tak odečti 52 a pokračuj na novém odkaze. → <strong>107</strong>.</li> <li><strong>107</strong>: Grog je se mnou, takže jdeme na 107 - 52 → <strong>55</strong>.</li> <li><strong>55</strong>: Máme jít na západ, takže jdeme tam → <strong>177</strong>. (Pokud chcete zkratku, tak běžte rovnou na 130, protože na 177 není úplně nezbytné jít.)</li> <li><strong>177</strong>: Vejít dveřmi do budovy → <strong>252</strong>.</li> <li><strong>252</strong>: Rosina z Dree. Zaplatit dva zlaťáky získané na odkazu 249 → <strong>11</strong>.</li> <li><strong>11</strong>: Dozvíš se, že veslanka má modrý stonek a roste v bažinách. Dále získáš <em>provaz</em> (není potřeba) a +2 štěstí. → <strong>386</strong>.</li> <li><strong>386</strong>: → <strong>130</strong>.</li> <li><strong>130</strong>: +4 stamina. Jít na severozápad → <strong>190</strong>.</li> <li><strong>190</strong>: Pokračovat rákosím → <strong>307</strong>.</li> <li><strong>307</strong>: Grog je se mnou, takže jdeme na 307 - 52 → <strong>255</strong>.</li> <li><strong>255</strong>: Jít na sever → <strong>267</strong>.</li> <li><strong>267</strong>: Prozkoumat rostliny → <strong>380</strong>.</li> <li><strong>380</strong>: Vybrat <em>rostlinu s modrým stonkem</em> (jak nám řekla Rosina) → <strong>106</strong>.</li> <li><strong>106</strong>: Poznačit si k rostlině číslo 49. → <strong>18</strong>.</li> <li><strong>18</strong>: → <strong>315</strong>.</li> <li><strong>315</strong>: Bojovat → <strong>145</strong>.</li> <li><strong>145</strong>: Boj s ropucháčem (9/9). → <strong>287</strong>.</li> <li><strong>287</strong>: Grog je se mnou, takže jdeme na 287 - 52 → <strong>235</strong>.</li> <li><strong>235</strong>: Ztráta Groga, získání <em>orkovy krabice</em>, obnova štěstí na původní hodnotu. → <strong>92</strong>.</li> <li><strong>92</strong>: Zpět u čarodějnic. Utrhli jsme rostlinu, u které jsme si měli poznačit číslo 49. Takže jdeme na 92 + 49 → <strong>141</strong>.</li> <li><strong>141</strong>: Zisk <em>prstenu pravdy</em>. Až potkáme Hadí jazyk, tak máme od odkazu odečíst 50, čímž odhalíme jeho lži. Obnova staminy i štěstí na původní úroveň. → <strong>423</strong>.</li> <li><strong>423</strong>: Přiblížit se k dinosauru → <strong>127</strong>.</li> <li><strong>127</strong>: Zkouška umění boje. Je třeba uspět (→ <strong>5</strong>), jinak hru nelze dohrát.</li> <li><strong>5</strong>: → <strong>366</strong>.</li> <li><strong>366</strong>: Pomoct mu → <strong>429</strong>.</li> <li><strong>429</strong>: Boj s lupiči (8/9, 8/7). → <strong>448</strong>.</li> <li><strong>448</strong>: Zeptat se ho na Galéru → <strong>269</strong>.</li> <li><strong>269</strong>: Použít prsten pravdy z odkazu 141. Jdeme na 269 - 50 → <strong>219</strong>.</li> <li><strong>219</strong>: Pustit se podrostem → <strong>189</strong>.</li> <li><strong>189</strong>: Zkouška štěstí. Je třeba uspět buď teď hned (→ <strong>341</strong>), nebo uspět po neúspěchu (→ <span class="geshifilter"><code class="text geshifilter-text">376</code></span> → 341), jinak hra končí.</li> </ul><h3>Část III: Galéra (finále)</h3> <ul><li><strong>341</strong>: Boj s gobliny (6/5, 5/5). → <strong>312</strong>.</li> <li><strong>312</strong>: Zvolit dveře s džbánem a vodou (viz nápověda na odkazu 219) → <strong>346</strong>.</li> <li><strong>346</strong>: Začít se zrcadlem → <strong>422</strong>.</li> <li><strong>422</strong>: Jedná se o úkryt Zharradana Marra, takže dle textu na odkazu 192 půjdeme na 422 - 93 → <strong>329</strong>.</li> <li><strong>329</strong>: → <strong>121</strong>.</li> <li><strong>121</strong>: → <strong>199</strong>.</li> <li><strong>199</strong>: Odmítnout mu dát orkovu krabici → <strong>133</strong>.</li> <li><strong>133</strong>: Byli jsme posypáni elfím prachem na odkazu 56 → <strong>417</strong>.</li> <li><strong>417</strong>: Máme krystalovou palici z odkazu 110 → <strong>28</strong>.</li> <li><strong>28</strong>: U palice bylo číslo 333, takže jdeme na 28 + 333 → <strong>361</strong>.</li> <li><strong>361</strong>: → 460<strong></strong>.</li> <li><strong>460</strong>: Vítězství :-)</li> </ul><h2>Dešifrovací funkce řeči</h2> <p>Pro dešifrování zašifrované řeči lze použít následující funkci v Pythonu, která vychází z instrukcí na odkazu <strong>283</strong>:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> decrypt<span style="color: black;">(</span>text<span style="color: black;">)</span>: text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">' '</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">''</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'a'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'e'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'i'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'o'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'u'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'á'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'é'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'ě'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'í'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'ó'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'ú'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">' '</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'b'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'a'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'B'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'A'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'f'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'e'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'F'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'E'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'j'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'i'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'J'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'I'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'p'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'o'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'P'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'O'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'v'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'u'</span><span style="color: black;">)</span> text <span style="color: #66cc66;">=</span> text.<span style="color: black;">replace</span><span style="color: black;">(</span><span style="color: #483d8b;">'V'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'U'</span><span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">return</span> text</pre></div> <p>Každopádně, je potřeba vzít v potaz, že zašifrovaný text nelze dešifrovat 1:1. Důvodem je, že více různých textů se šifrovací funkcí mapuje na ten stejný zašifrovaný text. Nicméně, po dešifrování je text většinou čitelný. Jen je potřeba zapojit trochu fantazie :-)</p> </div> <span><span>Petr Zemek</span></span> <span>2021-02-01 - 06:15</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/51" hreflang="cs">knihy</a></div> <div class="field__item"><a href="/taxonomy/term/105" hreflang="cs">gamebook</a></div> <div class="field__item"><a href="/taxonomy/term/106" hreflang="cs">řešení</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=224&amp;2=comment_node_blog&amp;3=comment_node_blog" token="vkYVHH0WGlmMGkHIYntTYbdt2xARBzdo3uVUBl1IcZg"></drupal-render-placeholder> </div> </div> </section> Mon, 01 Feb 2021 05:15:44 +0000 Petr Zemek 224 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2021-02-01-reseni-gamebooku-straslivy-netvor#comments Advent of Code 2020 a mé dojmy z Go https://cs-blog.petrzemek.net/2020-12-31-advent-of-code-2020-a-me-dojmy-z-go <span>Advent of Code 2020 a mé dojmy z Go</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Letošní <a href="https://adventofcode.com/2020">Advent of Code</a> jsem využil k bližšímu seznámení s jazykem <a href="https://golang.org/">Go</a>. V příspěvku popisuji, co to Advent of Code je, které úkoly se mi líbily, které mi daly nejvíce zabrat a sumarizuji mé dojmy z Go.</p> <!--break--><h2>Co je to Advent of Code?</h2> <p>Pro ty, kteří o <a href="https://adventofcode.com/">Advent of Code</a> slyší prvně, bych jej chtěl krátce představit. Pokud víte, o co jde, tak tuto sekci klidně přeskočte.</p> <p>Stručně řečeno, jedná se o verzi <a href="https://cs.wikipedia.org/wiki/Adventní_kalendář">adventního kalendáře</a> pro programátory :-). Jen místo mlsání sladkostí každý den plníte zadaný úkol, za jehož vyřešení získáváte zlaté hvězdy. Advent of Code je tvořen 25 úkoly, z nich každý je rozdělen na dvě části. Za splnění každé části dostanete zlatou hvězdu. Cílem celého snažení je získat těchto hvězd 50 (25 krát 2). Před zahájením práce na druhé části každého z úkolů je nejdřív potřeba splnit první část. Až po jejím splnění se vám odtajní zadání druhé části. Druhá část většinou nějakým způsobem navazuje na první část. Např. se jedná o rozšíření zadání, bližší dospecifikování některé části zadání (čti <em>oprava</em>), či navýšení výpočetní náročnosti. Zadání každého úkolu je pro každého společné. Co se liší, tak jsou vstupní data, která má každý unikátní. Cílem úkolů je vstupní data načíst, zpracovat podle zadání a vypsat výsledek. Po splnění každé části vyplníte vaše řešení do formuláře a dozvíte se, zda bylo vaše řešení správné. Pokud nebylo, tak máte samozřejmě možnost po určité krátké době učinit další pokus. K vypracování můžete využít jakéhokoliv programovacího jazyka či nástrojů.</p> <p>Podoba a náročnost úkolů je značně variabilní. Zadání jsou ve své podstatě algoritmická, ale rámcově zapadají do <a href="https://cs.wikipedia.org/wiki/Santa_Claus">Santových</a> slastí a strastí. Např. v letošním Advent of Code se Santa vydal na zaslouženou dovolenou, a cílem bylo řešit překážky, na které narazil. Jednou z dovedností, kterou při řešení úkolů využijete, je schopnost odlišení, co je podstatné z hlediska zadání úkolu a co je jen omáčka. Úkoly jsou opravdu různorodé, a tak si např. vyzkoušíte louskání hesel, simulaci aplikačně-specifických procesorů, tvorbu syntaktických analyzátorů (kalkulačka s neobvyklými prioritami operátorů), řešení soustav rovnic, simulaci <a href="https://cs.wikipedia.org/wiki/Hra_života">celulárních automatů</a>, hraní her či řešení <a href="https://cs.wikipedia.org/wiki/Puzzle">puzzles</a> a rozpoznávání vzorů v obraze. Obtížnost jednotlivých úkolů se také velmi liší a závisí nejen na vašich znalostech a zkušenostech, ale i na tom, jak moc si s úkolem vyhrajete (zda vám jde o vymazlené řešení, či jedete na rychlost a čitelnost kódu a <a href="http://turnoff.us/geek/tdd-vs-ftt/">testy hážete za hlavu</a>). Za sebe mohu říct, že zatímco některé úkoly mi zabraly 1-2 hodiny, tak u některých jsem strávil klidně 10-20 hodin. A troufám si tvrdit, že pokud člověk netuší, jak některý z úkolů principiálně řešit (např. neznáte matematický vzorec či informatický koncept), tak musí jistý čas věnovat i studiu. Alespoň se tak člověk něco nového naučí :-).</p> <p>Advent of Code je v neposlední řadě také rychlostní soutěž. Ke zveřejnění každého úkolu dochází v určitý stanovený čas (letos tomu bylo v 06:00 CET), a čím dříve úkol vyřešíte, tím víc dostanete bodů (první získá 100 bodů, druhý 99 atd.). Pokud vás zajímá <a href="https://en.wikipedia.org/wiki/Competitive_programming">kompetitivní programování</a>, tak určitě neváhejte. Za sebe mohu říct, že za ty časy, za které to ti nejlepší lidé řešili, jsem někdy nebyl ani schopen pochopit zadání :-D.</p> <h2>Proč zrovna Go?</h2> <p>S jazykem <a href="https://golang.org/">Go</a> jsem měl jen omezené zkušenosti, které mi umožnily čtení a rozumné pochopení existujícího kódu, ale již určitě ne napsání vlastního kódu. Říkal jsem si, že letošní Advent of Code bych mohl využít právě na bližší seznámení s tímto jazykem, a tak jsem se do toho vrhnul střemhlav :-). Ze začátku jsem si sice vše musel dohledávat, ale později se to zlepšilo, protože úkoly v Advent of Code jsou algoritmické, takže není potřeba znát pokročilé koncepty z daného jazyka. Typicky stačí umět načíst vstupní data, naparsovat je do rozumných struktur, a zapsat algoritmus řešení. Co se týče datových struktur, tak obecně jako základ stačí umět práci s řetězci, poli (seznamy) a hashovacími tabulkami (asociativní pole, slovník).</p> <p>Kromě řešení Advent of Code jsem během prosince prošel <a href="https://tour.golang.org/">A Tour of Go</a>, přečetl <a href="https://www.manning.com/books/go-in-action">Go in Action</a> a absolvoval část <a href="https://www.oreilly.com/library/view/ultimate-go-programming/9780135261651/">Ultimate Go Programming</a> školení.</p> <h2>Co říkám na Advent of Code 2020?</h2> <p><strong>Pozor: Tato sekce obsahuje <a href="https://cs.wikipedia.org/wiki/Spoiler_(kultura)">brojlery</a>. Pokud plánujete Advent of Code 2020 řešit, tak zvažte text níže přesočit a pokračovat sekcí o Go.</strong></p> <p>Kdybych to měl shrnout, tak celkově mě letošní úkoly bavily, a většina z nich se dala vyřešit během pár hodin. Bylo tam však pár úkolů, u kterých jsem strávil větší množství času (viz dále). Velmi oceňuji, že zadání úkolů bývají velmi přehledně specifikovaná, zasazená do Santova kontextu a doplněná o různé vtipné reference. Taktéž je skvělé, že u každého úkolu je uveden i příklad vstupu a výstupu, což lze s výhodou využít při testování. Jen v jednom případě se mi stalo, že jsem i přes procházející testy napsal řešení, které na osobním vstupu nezafungovalo korektně (<a href="https://adventofcode.com/2020/day/19">den č. 19</a>).</p> <p>Co se týče vad na kráse, tak bych asi jen zopakoval to, co jsem již psal: Pokud nevíte, jak úkol řešit, tak se může stát, že vám zabere mnoho hodin, či klidně i několik dní, než dáte dohromady řešení. Některé úlohy tak bývají časově dost náročné, a pokud k tomu ještě člověk chodí do práce, tak účast na Advent of Code může být energeticky dosti náročná. Někdy taky člověk zjistí, že vytvořil sice funkční řešení, ale na osobním vstupu by běželo několik dní, a tak je potřeba zapracovat na optimalizaci :-). Je to sice mnohdy sranda, ale taky to jistý čas zabere. Každopádně, úkoly naštěstí není potřeba vyřešit hned během daného dne a můžete je splnit kdykoliv, i v jiném pořadí.</p> <h3>Které úkoly mě nejvíce bavily?</h3> <ul><li><a href="https://adventofcode.com/2020/day/14">Den č. 14</a>. Simulace bitových instrukcí na 36 bitových hodnotách v 36 bitovém paměťovém prostoru.</li> <li><a href="https://adventofcode.com/2020/day/17">Den č. 17</a>. Simulace <a href="https://cs.wikipedia.org/wiki/Hra_života">Hry života</a> (celulární automaty) v nekonečném trojrozměrném (a v druhé části čtyřrozměrném) prostoru :-).</li> <li><a href="https://adventofcode.com/2020/day/18">Den č. 18</a>. Vytvoření kalkulačky pro operace, ve kterých mají operátory zvláštní priority (např. násobení má stejnou prioritu, jako sčítání, či pak ve druhé části naopak). Nejdřív jsem to chtěl řešit ad-hoc algoritmem, ale nakonec jsem sáhl po osvědčené <a href="https://en.wikipedia.org/wiki/Simple_precedence_parser">precedenční syntaktické analýze zdola nahoru</a>, pro studenty FITu známé z předmětu <a href="https://www.fit.vut.cz/study/course/13981/.cs">IFJ</a>.</li> <li><a href="https://adventofcode.com/2020/day/20">Den č. 20</a>. Algoritmické řešení skládačky a následné vyhledávání <a href="https://cs.wikipedia.org/wiki/Lochnesská_nestvůra">Lochnessek</a> v obraze :-). Dalo mi to hodně zabrat, ale byla to zábava.</li> </ul><h3>Které úkoly mi daly nejvíce zabrat?</h3> <ul><li><a href="https://adventofcode.com/2020/day/10">Den č. 10, část 2</a>. První část byla v pohodě, ale druhá část již nešla upočítat obyčejným enumerováním všech variant. Bylo potřeba zapojit i tzv. <a href="https://en.wikipedia.org/wiki/Memoization">memoizaci</a>.</li> <li><a href="https://adventofcode.com/2020/day/13">Den č. 13, část 2</a>. Druhá část opět nešla vyřešit <a href="https://cs.wikipedia.org/wiki/Řešení_hrubou_silou">hrubou silou</a>, protože by to trvalo neskutečně dlouho. Bylo potřeba zjistit, jak efektivně řešit soustavy rovnic s modulem. Takovéto rovnice jsem nikdy neřešil, takže mi nějaký čas zabralo, než jsem přišel, jak na to.</li> <li><a href="https://adventofcode.com/2020/day/20">Den č. 20, obě části</a>. Tato úloha mě hodně bavila (viz výše), ale byla zároveň jedna z časově nejsložitějších. Než jsem naprogramoval všechna možná prohození a rotace jednotlivých částí puzzle (obrázků) a dal dohromady funkční <a href="https://cs.wikipedia.org/wiki/Backtracking">backtrackovací</a> řešení, tak jsem nad tím strávil odhadem 15 hodin.</li> <li><a href="https://adventofcode.com/2020/day/23">Den č. 23, část 2</a>. Musel jsem mé řešení optimalizovat, aby rozumně zvládlo spočítat 10 miliónů iterací, a i tak jsem zůstal na řešení, které na osobním vstupu běželo 4,5 hodiny. Víc už jsem se optimalizací nezabýval, protože tento úkol mě až tak moc nebavil. Mám ještě nápad na urychlení, tak jej pak možná někdy vyzkouším.</li> </ul><h3>Adventní kalendář</h3> <p>Vypadá letos takto:</p> <p></p><center><br /><a href="/images/advent-of-code-2020.png" title="Advent of Code 2020"><img src="/images/advent-of-code-2020.png" alt="Advent of Code 2020" /></a><br /></center> <p>Pořadí úkolů bylo v kalendáři promíchané, což je důvod, proč je např. úkol 17 za úkolem 8.</p> <h2>Co říkám na Go?</h2> <p>Jak jsem již zmiňoval, řešení úkolů z Advent of Code si nevyžaduje využití všech výdobytků jazyků (stačí vám zvládat práci se soubory, řetězci, poli, mapami a základní řídicí konstrukce), takže ne vše jsem si z Go vyzkoušel. Např. na konkurentní a paralelní zpracování jsem se nedostal. Mé postřehy níže tedy prosím berte s rezervou ;-).</p> <h3>Co se mi líbilo?</h3> <ul><li>Nejedná se o složitý jazyk a základy se lze naučit během víkendu.</li> <li>Pokud znáte <a href="https://cs.wikipedia.org/wiki/C_(programovací_jazyk)">Céčko</a> či jemu podobný jazyk, budete z hlediska syntaxe jako doma.</li> <li>Svižný překlad (oproti např. optimalizovanému C++).</li> <li>Vyprodukované binárky lze spustit bez nutnosti mít v systému nainstalované závislosti. Go totiž používá ve výchozím režimu <a href="https://www.geeksforgeeks.org/static-and-dynamic-linking-in-operating-systems/">statické linkování</a>. Usnadňuje to spuštění binárek na jiných systémech, což se hodí např. při deploymentu.</li> <li>Automatický paměťový <a href="https://cs.wikipedia.org/wiki/Garbage_collection">garbage collector</a>, včetně <a href="https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-escape-analysis.html">escape analysis</a> pro automatické určení, zda se má lokální proměnná vytvořit na zásobníku, nebo na haldě (angl. heap).</li> <li>Využívání návratových hodnot místo výjimek pro signalizaci chyb. Člověk tak na první pohled vidí, které funkce mohou selhat, a může se zařídit.</li> <li>Automatické formátování zdrojového kódu přes <span class="geshifilter"><code class="text geshifilter-text">gofmt</code></span>.</li> <li>Zobrazení dokumentace v terminálu přes <span class="geshifilter"><code class="text geshifilter-text">go doc $WHAT</code></span>.</li> </ul><h3>Co se mi nelíbilo?</h3> <ul><li>Jazyk mi připadal, jako kdyby někdo předělával Céčko do kabátu 21. století, ale záměrně ignoroval vymoženosti známé z jiných jazyků a snažil se jazyk udělat co nejjednodušší, i za cenu toho, že jazyk bude působit předpotopně. Např. když jej srovnám s Rustem, který se objevil jen rok po Go, tak je to jako srovnávat nebe a dudy. U Rustu mi přijde, že si s ním tvůrci vyhráli a obsahuje spoustu pokročilých konceptů a možností, a Go oproti němu působí dost zastarale.</li> <li>Viditelnost identifikátorů (názvy typů, funkcí, proměnných) závisí na jejich pojmenování. Pokud chcete mít identifikátor veřejně viditelný, musí začínat velkým písmenem. Interní identifikátory začínají malým písmenem. Toto opravdu nemám rád (<a href="https://cs-blog.petrzemek.net/2014-10-26-co-se-mi-nelibi-na-pythonu">ani v Pythonu</a>). Zbytečně to podle mě znepřehledňuje kód (názvy typů a proměnných mohou mít stejnou velikost písmen), při změně viditelnosti identifikátoru je potřeba změnit veškerý kód, který jej používá, a např. vytvoření typu nazvaného <span class="geshifilter"><code class="text geshifilter-text">password</code></span> s malým <span class="geshifilter"><code class="text geshifilter-text">p</code></span> vás nutí přemýšlet, jak pojmenovat proměnnou...</li> <li>Nemožnost vytvářet vlastní typově bezpečné generické typy a funkce (ve smyslu <a href="https://en.wikipedia.org/wiki/Template_(C%2B%2B)">šablon v C++</a> či <a href="https://doc.rust-lang.org/book/ch10-01-syntax.html">generických typů a funkcí v Rustu</a>). Jediná možnost je použít generické vestavěné typy <span class="geshifilter"><code class="text geshifilter-text">slice</code></span> (dynamické pole) a <span class="geshifilter"><code class="text geshifilter-text">map</code></span> (hashovací tabulka). Chcete vlastní generický typ, např. reprezentující množinu? Máte smůlu. Dále, nepřítomnost podpory pro generické typy a funkce vede na to, že ve standardní knihovně je např. <span class="geshifilter"><code class="text geshifilter-text">sort.Ints()</code></span>, <span class="geshifilter"><code class="text geshifilter-text">sort.Float64s()</code></span> a <span class="geshifilter"><code class="text geshifilter-text">sort.Strings()</code></span> místo jedné generické <span class="geshifilter"><code class="text geshifilter-text">sort()</code></span> funkce, či <a href="https://stackoverflow.com/questions/57648933/why-go-does-not-have-function-to-calculate-absolute-value-for-integer-datatype">nepřítomnost <span class="geshifilter"><code class="text geshifilter-text">Abs()</code></span> pro celočíselné typy</a> (je pouze pro typy v plovoucí řadové čárce).</li> <li>S bodem výše souvisí i to, že když jsem potřeboval <a href="https://cs.wikipedia.org/wiki/Mno%C5%BEina_(datov%C3%A1_struktura)">množinu</a> obsahující hodnoty typu <span class="geshifilter"><code class="text geshifilter-text">X</code></span>, tak jsem měl smolíka a musel jsem použít <span class="geshifilter"><code class="text geshifilter-text">map[X]bool</code></span>. Vede to na zbytečně nepřehledný kód a otázky typu <em>"K čemu je tam <span class="geshifilter"><code class="text geshifilter-text">bool</code></span>, když v kódu se <span class="geshifilter"><code class="text geshifilter-text">false</code></span> nikde nevyužije</em>?".</li> <li><a href="https://stackoverflow.com/questions/14426366/what-is-an-idiomatic-way-of-representing-enums-in-go">Neexistující typově bezpečné výčtové typy</a> (angl. <a href="https://en.wikipedia.org/wiki/Enumerated_type">enum</a>), včetně neexistence tzv. <a href="https://en.wikipedia.org/wiki/Tagged_union">sum types</a> (variant, discriminated union). Nelze si tak vytvořit typ pro hodnoty, které mohou být pouze X, Y, nebo Z.</li> <li>S bodem výše souvisí i to, že v jazyce a standardní knihovně není nic jako <a href="https://en.cppreference.com/w/cpp/utility/optional"><span class="geshifilter"><code class="text geshifilter-text">std::optional</code></span></a> v C++ či <a href="https://doc.rust-lang.org/std/option/"><span class="geshifilter"><code class="text geshifilter-text">std::option::Option</code></span></a> v Rustu a s tím související podpora pro <a href="https://en.wikipedia.org/wiki/Pattern_matching">pattern matching</a>. Ano, <a href="https://stackoverflow.com/questions/30731687/how-do-i-represent-an-optional-string-in-go">lze místo toho použít ukazatele</a> a místo <span class="geshifilter"><code class="text geshifilter-text">None</code></span> vrátit <span class="geshifilter"><code class="text geshifilter-text">nil</code></span> (či vrátit nulu v případě číselných typů a prázdný řetězec v případě řetězců), ale zbytečně to znepřehledňuje kód.</li> <li>V případě funkce, která vrací buď hodnotu, nebo chybu, je potřeba vrátit obojí, i když žádná rozumná hodnota nemusí existovat. Nebylo by lepší mít něco jako <a href="https://doc.rust-lang.org/std/result/enum.Result.html"><span class="geshifilter"><code class="text geshifilter-text">std::result::Result</code></span></a> a pattern matching v Rustu?</li> <li>Pro testování jsem používal standardní <span class="geshifilter"><code class="text geshifilter-text">testing</code></span> modul. Bohužel neobsahuje žádné <a href="https://cs.wikipedia.org/wiki/Aserce">aserce</a> typu <span class="geshifilter"><code class="text geshifilter-text">AssertEqual()</code></span>, a tak jsem si veškeré kontroly a výpisy musel psát ručně. A pro porovnání dvou <em>slices</em> jsem si musel napsat funkci, protože pro ně nebylo <span class="geshifilter"><code class="text geshifilter-text">==</code></span> podporováno.</li> <li>Jazyk se tváří, že je v něm podpora pro n-tice (např. lze vytvořit funkci vracející dvojici <span class="geshifilter"><code class="text geshifilter-text">int</code></span> a <span class="geshifilter"><code class="text geshifilter-text">error</code></span>). Ovšem záhy zjistíte, že tato syntax funguje pouze pro návrat hodnot z funkcí, a pokud chce člověk využít n-tice na jiných místech, musí si k tomu vytvořit strukturu.</li> <li>Jazyk sice obsahuje tzv. <a href="https://cs.wikipedia.org/wiki/Cyklus_foreach">foreach cyklus</a> v podobě <span class="geshifilter"><code class="text geshifilter-text">for index, element := range array {}</code></span>, ale pokud index nepotřebujete, tak je potřeba psát <span class="geshifilter"><code class="text geshifilter-text">for _, element := range array {}</code></span>. Když totiž člověk napíše <span class="geshifilter"><code class="text geshifilter-text">for x := range array {}</code></span>, tak v <span class="geshifilter"><code class="text geshifilter-text">x</code></span> budou indexy, nikoliv hodnoty. Nemohlo to být naopak? V drtivé většině případů mi stačilo iterovat přes hodnoty a index jsem nepotřeboval. Např. jako je tomu v Pythonu a v jeho <a href="https://docs.python.org/3/library/functions.html#enumerate"><span class="geshifilter"><code class="text geshifilter-text">enumerate()</code></span></a> funkci, kterou využijete, pokud kromě hodnot potřebujete i indexy. Podtržítka taktéž moc nepřidají na přehlednosti kódu.</li> <li>Jazyk sice obsahuje automatickou správu paměti ve formě garbage collectoru, ale když chcete např. otevřít soubor a ujistit se, že při skončení funkce bude vždy zavřen, tak nesmíte zapomenout použít explicitní konstrukci <a href="https://gobyexample.com/defer"><span class="geshifilter"><code class="text geshifilter-text">defer</code></span></a>. Mnohem víc se mi líbí přístup <a href="https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization">RAII</a> v C++ či Rustu, nebo <a href="https://en.wikibooks.org/wiki/Python_Programming/Context_Managers">context manager</a> v Pythonu (když už chceme pro porovnání zvolit jazyk, jehož implementace mají taktéž garbage collector).</li> </ul><h2>Zdrojové kódy</h2> <p>Zdrojáky k mým řešením všech cvičení jsou <a href="https://github.com/s3rvac/advent-of-code/tree/master/2020">u mě na GitHubu</a>.</p> </div> <span><span>Petr Zemek</span></span> <span>2020-12-31 - 14:00</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/7" hreflang="cs">programování</a></div> <div class="field__item"><a href="/taxonomy/term/103" hreflang="cs">advent of code</a></div> <div class="field__item"><a href="/taxonomy/term/104" hreflang="cs">go</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=223&amp;2=comment_node_blog&amp;3=comment_node_blog" token="gFmUIPMqnSZh1swij5HZR-wIj_urWSjpH_j8fgKx40I"></drupal-render-placeholder> </div> </div> </section> Thu, 31 Dec 2020 13:00:01 +0000 Petr Zemek 223 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2020-12-31-advent-of-code-2020-a-me-dojmy-z-go#comments Slasti a strasti práce z domova https://cs-blog.petrzemek.net/2020-10-10-slasti-a-strasti-prace-z-domova <span>Slasti a strasti práce z domova</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Je tomu již sedm měsíců od doby, co jsem byl naposled v kanceláři. Ano, čtete dobře. Z důvodu <a href="https://en.wikipedia.org/wiki/Coronavirus_disease_2019">doby Covidové</a> jsem stejně jako spousta dalších lidí přešel od jara na práci z domu. V příspěvku bych se chtěl podělit o své zkušenosti z pohledu toho, co funguje a nefunguje, a zamyslet se nad tím, zda bych chtěl v práci z domu pokračovat, nebo se vrátit do kanceláře.</p> <!--break--><h2>Smysl zamyšlení</h2> <p>Ať již za to může Covid či vývoj společnosti, tak trend začíná být zřejmý: stále více a více lidem je nabízena možnost částečné či trvalé práce z domu. Konkrétně můj zaměstnavatel <a href="https://www.frekvence1.cz/clanky/revoluce-na-ceskem-pracovnim-trhu-firma-avast-nabidne-trvalou-praci-z-domova.shtml">plánuje nabídnout svým lidem možnost trvalé práce z domova</a>. Chtěl jsem si proto zesumarizovat plusy a mínusy práce z domova při porovnání s prací v kanceláři. Jak asi tušíte, budu se primárně zaměřovat na to, co funguje a nefunguje pro mě osobně, ale část bodů bude pravděpodobně aplikovatelná i na další lidi.</p> <h2>Co pro mě při práci z domu funguje?</h2> <ul><li><strong>Klid a ticho.</strong> Oproti kanceláři (dá-li se tak <a href="https://www.czechcrunch.cz/2018/10/avast-otevrel-v-brne-kancelare-ve-stylu-silicon-valley-podivejte-se-jak-to-uvnitr-vypada/">prostorům ve stylu Silicon Valley</a> říkat) mám doma parádní klid. Neruší mě lidi chodící či bavící se kolem mě a nemusím nosit celou dobu sluchátka.</li> <li><strong>Ušetřený čas, náklady a nervy za dopravu.</strong> Cesta z domu do kanceláře a zpět mi každý pracovní den zabrala hodinu (půl hodinu tam, půl hodiny zpět). A to jsem schválně jezdil do práce brzy ráno, abych se vyhnul ranním a odpoledním špičkám. Dále ušetřím peníze za benzín a nervy při zácpách ve městě.</li> <li><strong>Skutečně flexibilní pracovní doba.</strong> Něco jako flexibilní pracovní dobu už jsem sice měl, ale když musíte do práce dojíždět, tak si těžko můžete dovolit např. pracovat část pracovní doby ráno a část večer. Dále si mohu kdykoliv dát pauzu a vypnout se.</li> <li><strong>Méně sociálních interakcí.</strong> Pro introverty a poustevníky je práce z domova z tohoto pohledu požehnáním.</li> <li><strong>Na oběd si lze uvařit, co člověk chce.</strong> Nemusím být vázaný na to, co je daný den k dispozici v kantýně či restauraci.</li> <li><strong>Možnost regulace teploty a klimatizace.</strong> Doma si člověk může nastavit teplotu jak chce a nemusí řešit, že regulace teploty/klimatizace nefunguje (z mé zkušenosti častý problém při práci z kanceláří).</li> <li><strong>Menší šance kontaktu s nemocnými lidmi či naopak nakažení ostatních.</strong> Někteří chodí do práce i když kašlou, smrkají a celkově se necítí dobře, místo toho, aby si vzali sick day či šli na nemocenskou. Naopak, pokud se člověk necítí nejlíp, ale chce pracovat (či má nějaký termín, do kdy musí práci dokončit), tak alespoň nenakazí ostatní.</li> <li><strong>Možnost si zařídit pracovní prostředí podle svého.</strong> V práci jste omezeni tím, co vám poskytne zaměstnavatel. Doma si vše můžete zařídit tak, jak chcete. Stojí to sice peníze, ale pro lidi, kteří tráví čas na počítači i mimo práci, to určitě stojí za zvážení.</li> <li><strong>Lze si vyzvednout poštu a balíky doručované přepravními službami.</strong> Konečně mohu dopravcům volajícím v jedenáct hodin dopoledne odpovědět, že jsem doma a balíček si mohu vyzvednout, aniž bych si jej musel nechat přepravit na výdejní místo.</li> </ul><h2>Co naopak nefunguje?</h2> <ul><li><strong>(Ne)Rovnováha mezi prací a životem (angl. work-life balance).</strong> Chybí mi vypnutí v podobě cesty z práce domů. Je totiž velmi těžké se během minuty přepnout z pracovního stavu do toho nepracovního. Dále, díky záznamům pracovní docházky, které si vedu, vidím, že při práci z domova pracuji ve výsledku víc hodin přesčas, než když jsem chodil do kanceláře. V neposlední řadě mám často tendenci se dívat, co se děje v práci. Celkově mám někdy pocit, že místo práce z domova žiji v práci :-). Výhoda je, že na tomto bodu mohu sám se sebou pracovat a něco s tím udělat.</li> <li><strong>Zvýšené finanční náklady.</strong> Elektřina, plyn, vodné, stočné apod. Je ale možné, že to firmy zohlední ve smlouvách pro lidi pracující z domova (náhrady části nákladů).</li> </ul><h2>S čím dalším bývá problém</h2> <p>Následující body se mě sice přímo netýkají, ale chtěl jsem je zde pro úplnost uvést, protože pro mnoho lidí mohou mít zásadní vliv na to, zda se vrátit do kanceláře, nebo jít cestou trvalé práce z domova.</p> <ul><li><strong>Nevhodné pracovní podmínky.</strong> Pokud vám doma běhají děti či nemáte vlastní místnost na práci, tak se vám zrovna nejlíp pracovat nebude.</li> <li><strong>Nekvalitní připojení k Internetu.</strong> Práce z domu klade vyšší nároky na vaše připojení k Internetu. Nekvalitní spojení ztěžuje práci nejen vám, a i vašim kolegům, kterým při video hovorech vypadáváte.</li> <li><strong>Nedostatek sociálních interakcí.</strong> Pokud jste sociálnější typ, tak vám živé interakce s jinými lidmi mohou chybět.</li> <li><strong>Absence klimatizace přes léto.</strong> Pokud doma nemáte klimatizaci, tak se přes léto můžete doslova zapotit.</li> </ul><h2>Závěr</h2> <p>Za mě je volba jasná: práci z domova jsem si zamiloval a neměnil bych. Osobně beru dvě zmíněné nevýhody jako cenu za všechny ty výhody.</p> <p>A jak to vidíte vy? Co funguje a nefunguje pro vás?</p> </div> <span><span>Petr Zemek</span></span> <span>2020-10-10 - 19:32</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/102" hreflang="cs">práce</a></div> <div class="field__item"><a href="/taxonomy/term/101" hreflang="cs">home office</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=222&amp;2=comment_node_blog&amp;3=comment_node_blog" token="54_1I1FRXUFNmrIlHumR7bnOAWP626k9tT0nK2BOUQk"></drupal-render-placeholder> </div> </div> <article data-comment-user-id="0" id="comment-2784" class="comment js-comment comment--level-1 by-anonymous" role="article" data-drupal-selector="comment"> <span class="hidden" data-comment-timestamp="1603387282"></span> <div class="comment__picture-wrapper"> <div class="comment__picture"> </div> </div> <div class="comment__text-wrapper"> <footer class="comment__meta"> <p class="comment__author"><a rel="nofollow" href="http://zdenekhajek.cz">zdenekhajek (neověřeno)</a></p> <p class="comment__time">2 roky 11 měsíců zpět</p> </footer> <div class="comment__content"> <h3><a href="/comment/2784#comment-2784" class="permalink" rel="bookmark" hreflang="und">Ahoj S3rváci,</a></h3> <div class="text-content field field--name-comment-body field--type-text-long field--label-hidden field__item comment__text-content"><p>Ahoj S3rváci,</p> <p>díky za článek. V podstatě souhlasím. Pracuji poslední týdny z HO a je to vynikající (oproti open space). Snad více zaměstnavatelů zareaguje jako Avast. Myslím, že v další podobné krizi obstojí firmy, které na to budou připraveny - budou umožnovat pracovat z domu.</p> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=2784&amp;1=default&amp;2=und&amp;3=" token="9qLE_HPwBDIk__GYBR1EKSNgTlEygNrrjzbjYwzZJSY"></drupal-render-placeholder> </div> </div> </article> </section> Sat, 10 Oct 2020 17:32:13 +0000 Petr Zemek 222 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2020-10-10-slasti-a-strasti-prace-z-domova#comments Co je nového v Pythonu 3.9 https://cs-blog.petrzemek.net/2020-10-09-co-je-noveho-v-pythonu-3-9 <span>Co je nového v Pythonu 3.9</span> <div class="text-content clearfix field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Na začátku října byl vydán <a href="https://www.python.org/downloads/release/python-390/">Python 3.9</a>. V článku bych chtěl popsat vybrané novinky, které mě zaujaly.</p> <!--break--><p> Oficiální shrnutí změn je <a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html">zde</a>. Úplný seznam pak lze nalézt v <a href="https://docs.python.org/release/3.9.0/whatsnew/changelog.html#changelog">changelogu</a>. V textu níže předpokládám znalost předchozích verzí Pythonu.</p> <h2>Nové operátory pro spojování a aktualizaci slovníků</h2> <p>Do vestavěné třídy <a href="https://docs.python.org/release/3.9.0/library/stdtypes.html#dict"><span class="geshifilter"><code class="text geshifilter-text">dict</code></span></a> byly přidány operátory na spojování (angl. merge) a aktualizaci (angl. update) slovníků. Mějme následující slovníky:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;">d1 <span style="color: #66cc66;">=</span> <span style="color: black;">{</span><span style="color: #483d8b;">'a'</span>: <span style="color: #ff4500;">1</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'b'</span>: <span style="color: #ff4500;">1</span><span style="color: black;">}</span> d2 <span style="color: #66cc66;">=</span> <span style="color: black;">{</span><span style="color: #483d8b;">'b'</span>: <span style="color: #ff4500;">2</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'c'</span>: <span style="color: #ff4500;">2</span><span style="color: black;">}</span></pre></div> <p>Místo</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;">d <span style="color: #66cc66;">=</span> d1.<span style="color: #dc143c;">copy</span><span style="color: black;">(</span><span style="color: black;">)</span> d.<span style="color: black;">update</span><span style="color: black;">(</span>d2<span style="color: black;">)</span></pre></div> <p>což potřebuje dočasnou proměnnou, nebo</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;">d <span style="color: #66cc66;">=</span> <span style="color: black;">{</span>**d1<span style="color: #66cc66;">,</span> **d2<span style="color: black;">}</span></pre></div> <p>což není příliš čitelné, lze nyní psát</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;">d <span style="color: #66cc66;">=</span> d1 | d2 <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span>d<span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># {'a': 1, 'b': 2, 'c': 2}</span></pre></div> <p>Pokud bychom chtěli první slovník aktualizovat obsahem druhého, tak lze nově napsat</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;">d1 |<span style="color: #66cc66;">=</span> d2 <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span>d1<span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># {'a': 1, 'b': 2, 'c': 2}</span></pre></div> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0584/">PEP-584</a></p> <h2>Nové řetězcové metody pro odstranění prefixu a suffixu</h2> <p>Do <a href="https://docs.python.org/release/3.9.0/library/stdtypes.html#str"><span class="geshifilter"><code class="text geshifilter-text">str</code></span></a>, <a href="https://docs.python.org/release/3.9.0/library/stdtypes.html#bytes"><span class="geshifilter"><code class="text geshifilter-text">bytes</code></span></a> a dalších typů přibyly dvě nové metody:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span><span style="color: #483d8b;">'Hey there'</span>.<span style="color: black;">removeprefix</span><span style="color: black;">(</span><span style="color: #483d8b;">'Hey '</span><span style="color: black;">)</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># there</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span><span style="color: #483d8b;">'Hey there'</span>.<span style="color: black;">removesuffix</span><span style="color: black;">(</span><span style="color: #483d8b;">' there'</span><span style="color: black;">)</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># Hey</span></pre></div> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0616">PEP-616</a></p> <h2>Zjednodušení typových anotací</h2> <p>V typových anotacích lze nyní používat vestavěné typy místo typů z <a href="https://docs.python.org/release/3.9.0/library/typing.html"><span class="geshifilter"><code class="text geshifilter-text">typing</code></span></a> modulu. Např. místo</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> typing   <span style="color: #ff7700;font-weight:bold;">def</span> concatenate<span style="color: black;">(</span>strings: typing.<span style="color: black;">List</span><span style="color: black;">[</span><span style="color: #008000;">str</span><span style="color: black;">]</span><span style="color: black;">)</span> -<span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">str</span>: ...</pre></div> <p>lze nyní napsat</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> concatenate<span style="color: black;">(</span>strings: <span style="color: #008000;">list</span><span style="color: black;">[</span><span style="color: #008000;">str</span><span style="color: black;">]</span><span style="color: black;">)</span> -<span style="color: #66cc66;">&gt;</span> <span style="color: #008000;">str</span>: ...</pre></div> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0585">PEP-585</a></p> <h2>Flexibilní typové anotace</h2> <p>Byla přidána možnost doplňování typových anotací o libovolná metadata s využitím <a href="https://docs.python.org/3.9/library/typing.html#typing.Annotated"><span class="geshifilter"><code class="text geshifilter-text">typing.Annotated</code></span></a> typu. Příklad níže ukazuje použití pro vytvoření typu <span class="geshifilter"><code class="text geshifilter-text">UnsignedShort</code></span>, který je z pohledu Pythonu aliasem pro <span class="geshifilter"><code class="text geshifilter-text">int</code></span>, ale nástroje či skripty mohou pro serializaci použít dodatečnou informaci o znaménkovosti a bitové šířce:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> typing   UnsignedShort <span style="color: #66cc66;">=</span> typing.<span style="color: black;">Annotated</span><span style="color: black;">[</span><span style="color: #008000;">int</span><span style="color: #66cc66;">,</span> <span style="color: black;">(</span><span style="color: #483d8b;">'u'</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">16</span><span style="color: black;">)</span><span style="color: black;">]</span></pre></div> <p>Samozřejmě takový nástroj či skript musí existovat :-). Příklad, založený na <a href="https://www.python.org/dev/peps/pep-0593/#combining-runtime-and-static-uses-of-annotations">této ukázce</a>, je čistě smyšlený.</p> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0593/">PEP 593</a></p> <h2>Nový modul: zoneinfo</h2> <p>Nový modul <a href="https://docs.python.org/release/3.9.0/library/zoneinfo.html#module-zoneinfo"><span class="geshifilter"><code class="text geshifilter-text">zoneinfo</code></span></a> přidává <a href="https://www.iana.org/time-zones">implementaci časových zón</a> do Pythoní standardní knihovny. Dříve k tomu bylo potřeba na všech platformách používat balíček <a href="https://pypi.org/project/tzdata/"><span class="geshifilter"><code class="text geshifilter-text">tzdata</code></span></a>. Nyní se buď použije databáze časových zón ze systému, nebo <span class="geshifilter"><code class="text geshifilter-text">tzdata</code></span> (pokud systém databázi časových zón neobsahuje). Každopádně, v případě, že vyvíjíte multiplatformní projekt, tak je <a href="https://docs.python.org/release/3.9.0/library/zoneinfo.html#data-sources">doporučeno</a> přidat závislost na <span class="geshifilter"><code class="text geshifilter-text">tzdata</code></span>. Jinak může nastat to, že vám <span class="geshifilter"><code class="text geshifilter-text">zoneinfo</code></span> modul bude vyhazovat výjimku <a href="https://docs.python.org/release/3.9.0/library/zoneinfo.html#zoneinfo.ZoneInfoNotFoundError">ZoneInfoNotFoundError</a>.</p> <p>Ukázka:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">datetime</span> <span style="color: #ff7700;font-weight:bold;">import</span> zoneinfo   dt <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2020</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> tzinfo<span style="color: #66cc66;">=</span>zoneinfo.<span style="color: black;">ZoneInfo</span><span style="color: black;">(</span><span style="color: #483d8b;">'Europe/London'</span><span style="color: black;">)</span><span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span>dt<span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># 2020-10-10 00:00:00+01:00</span> dt <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span><span style="color: black;">(</span><span style="color: #ff4500;">2020</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> <span style="color: #ff4500;">10</span><span style="color: #66cc66;">,</span> tzinfo<span style="color: #66cc66;">=</span>zoneinfo.<span style="color: black;">ZoneInfo</span><span style="color: black;">(</span><span style="color: #483d8b;">'Europe/Prague'</span><span style="color: black;">)</span><span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span>dt<span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># 2020-10-10 00:00:00+02:00</span></pre></div> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0615">PEP-615</a></p> <h2>Nový modul: graphlib</h2> <p>Druhým novým standardním modulem je <a href="https://docs.python.org/release/3.9.0/library/graphlib.html"><span class="geshifilter"><code class="text geshifilter-text">graphlib</code></span></a>. Jeho účelem je obsahovat operace nad grafovými datovými strukturami. Aktuálně obsahuje jedinou třídu <a href="https://docs.python.org/release/3.9.0/library/graphlib.html#graphlib.TopologicalSorter"><span class="geshifilter"><code class="text geshifilter-text">TopologicalSorter</code></span></a> implementující <a href="https://en.wikipedia.org/wiki/Topological_sorting">toplogické uspořádání grafu</a>.</p> <p>Ukázka:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> graphlib   <span style="color: #808080; font-style: italic;">#</span> <span style="color: #808080; font-style: italic;"># C --&gt; F</span> <span style="color: #808080; font-style: italic;"># ^ \</span> <span style="color: #808080; font-style: italic;"># / \ v</span> <span style="color: #808080; font-style: italic;"># A --&gt; B D --&gt; G</span> <span style="color: #808080; font-style: italic;"># \ /</span> <span style="color: #808080; font-style: italic;"># v</span> <span style="color: #808080; font-style: italic;"># E</span> <span style="color: #808080; font-style: italic;">#</span> graph <span style="color: #66cc66;">=</span> <span style="color: black;">{</span> <span style="color: #483d8b;">'A'</span>: <span style="color: black;">[</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'B'</span>: <span style="color: black;">[</span><span style="color: #483d8b;">'A'</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'C'</span>: <span style="color: black;">[</span><span style="color: #483d8b;">'B'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'D'</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'D'</span>: <span style="color: black;">[</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'E'</span>: <span style="color: black;">[</span><span style="color: #483d8b;">'B'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'D'</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'F'</span>: <span style="color: black;">[</span><span style="color: #483d8b;">'C'</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'G'</span>: <span style="color: black;">[</span><span style="color: #483d8b;">'D'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'F'</span><span style="color: black;">]</span><span style="color: #66cc66;">,</span> <span style="color: black;">}</span> ts <span style="color: #66cc66;">=</span> graphlib.<span style="color: black;">TopologicalSorter</span><span style="color: black;">(</span>graph<span style="color: black;">)</span> <span style="color: #ff7700;font-weight:bold;">print</span><span style="color: black;">(</span><span style="color: #008000;">list</span><span style="color: black;">(</span>ts.<span style="color: black;">static_order</span><span style="color: black;">(</span><span style="color: black;">)</span><span style="color: black;">)</span><span style="color: black;">)</span> <span style="color: #808080; font-style: italic;"># ['A', 'D', 'B', 'C', 'E', 'F', 'G']</span></pre></div> <p>Detaily: <a href="https://bugs.python.org/issue17005">bpo-17005</a></p> <h2>Dekorátorem nyní může být libovolný výraz</h2> <p>Drobná změna v gramatice, která umožní, aby dekorátorem mohl být libovolný výraz. Lze tedy např. mít pole dekorátorů a použít z něj konkrétní dekorátor:</p> <div class="geshifilter"> <pre class="python geshifilter-python" style="font-family:monospace;"><span style="color: #66cc66;">@</span>decorators<span style="color: black;">[</span><span style="color: #ff4500;">0</span><span style="color: black;">]</span> <span style="color: #ff7700;font-weight:bold;">def</span> foo<span style="color: black;">(</span><span style="color: black;">)</span>: ...</pre></div> <p>Předchozí verze Pythonu na takovémto kódu vyhazovaly <span class="geshifilter"><code class="text geshifilter-text">SyntaxError</code></span>, protože vyžadovaly, aby dekorátor obsahoval pouze identifikátory, tečky, a případně volání funkce na jeho konci.</p> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0614/">PEP 614</a></p> <h2>Nový parser</h2> <p><a href="https://github.com/python/cpython">CPython</a> (standardní implementace Pythonu v Céčku) obsahuje nový parser založený na <a href="https://en.wikipedia.org/wiki/Parsing_expression_grammar">PEG</a> gramatikách místo na <a href="https://en.wikipedia.org/wiki/LL_parser">LL(1)</a> gramatikách. Rychlostně to v CPythonu <a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#new-parser">vychází přibližně na stejno</a>. Nicméně PEG gramatiky <a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#new-parser">jsou flexibilnější s ohledem na vývoj nových jazykových vlastnostní</a>. Na to si však budeme muset počkat do některé z dalších verzí Pythonu :-).</p> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0617">PEP-617</a></p> <h2>Nový vývojový cyklus Pythonu</h2> <p>Když už se bavíme o nových verzích Pythonu, tak došlo ke změně cyklu vývoje Pythonu. Od Pythonu 3.9 budou nové hlavní verze vycházet co 12 měsíců, tedy každý říjen.</p> <p>Detaily: <a href="https://www.python.org/dev/peps/pep-0602">PEP-602</a></p> <h2>Ostatní změny</h2> <p>Kromě novinek výše je v Pythonu 3.9 samozřejmě mnoho dalších změn. Níže jsem sepsal odkazy na oficiální dokumentaci. Kdo budete mít zájem, tak na odkazy mrkněte.</p> <ul><li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#improved-modules">Vylepšení ve standardních modulech</a> - Hodí se alespoň proběhnout, zda tam pro vás není něco zajímavého s ohledem na moduly, které používáte.</li> <li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#optimizations">Optimalizace</a></li> <li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#deprecated">Co bylo zavrženo (angl. deprecated)</a> - V souvislosti s tím se hodí <a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#you-should-check-for-deprecationwarning-in-your-code">zkontrolovat deprecation varování</a> ve vašem kódu.</li> <li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#removed">Co bylo z Pythonu odstraněno</a></li> <li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#porting-to-python-3-9">Na co si dát pozor při přechodu na Python 3.9</a> - Např. z hlediska změn v API.</li> <li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#c-api-changes">Změny v C API</a></li> <li><a href="https://docs.python.org/release/3.9.0/whatsnew/3.9.html#build-changes">Změny v build systému</a></li> </ul><h2>Zdrojové kódy</h2> <p>Všechny zdrojové kódy jsou k dispozici <a href="https://github.com/s3rvac/blog/tree/master/cs-2020-10-09-co-je-noveho-v-pythonu-3-9">u mě na GitHubu</a>, takže si vše můžete vyzkoušet.</p> </div> <span><span>Petr Zemek</span></span> <span>2020-10-09 - 12:41</span> <div class="field field--name-taxonomy-vocabulary-1 field--type-entity-reference field--label-inline clearfix"> <div class="field__label">Tagy</div> <div class="field__items"> <div class="field__item"><a href="/taxonomy/term/7" hreflang="cs">programování</a></div> <div class="field__item"><a href="/taxonomy/term/44" hreflang="cs">Python</a></div> </div> </div> <section data-drupal-selector="comments" class="comments"> <div class="add-comment"> <div class="add-comment__form"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=221&amp;2=comment_node_blog&amp;3=comment_node_blog" token="03bLMJhdH-sH9_J4AJrmweO6mR-ZjRDE-qsBT8OKrU4"></drupal-render-placeholder> </div> </div> </section> Fri, 09 Oct 2020 10:41:18 +0000 Petr Zemek 221 at https://cs-blog.petrzemek.net https://cs-blog.petrzemek.net/2020-10-09-co-je-noveho-v-pythonu-3-9#comments