<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Banter bloguje</title>
    <description>Blog o softwarovém inženýrství, programování v jazycích Java či Groovy, ale i o mimopracovních věcech, které mi přeletí přes nos.
</description>
    <link>https://blog.zvestov.cz/</link>
    <atom:link href="https://blog.zvestov.cz/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 19 Mar 2026 05:25:20 +0000</pubDate>
    <lastBuildDate>Thu, 19 Mar 2026 05:25:20 +0000</lastBuildDate>
    <generator>Jekyll v4.3.1</generator>
    
      <item>
        <title>Silné stránky programátorů</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2026-03-18/329815.png&quot; /&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://www.jednoprocento.cz/p/a-co-vy-uz-jste-prozili-svuj-tah&quot;&gt;Miloš Čermák přišel s trefným shrnutím&lt;/a&gt;: „AI je dnes v podstatě tři věci najednou: obtěžující, znepokojující a fascinující.“
I bez toho jsem již dřívě uvažoval, čím bych se živil, kdybych zrovna nebyl programátorem.
Pokusím se co nejméně plivat síru na AI a najít důvody, jak bych mohl obstát.&lt;/p&gt;

&lt;p&gt;Kdysi jsem napsal pro Heroine &lt;a href=&quot;https://www.heroine.cz/zeny-it/7677-u-budoucich-ajtaku-je-nejdulezitejsi-touha-nespokojit-se-s-prvnim-resenim-rika-lektor-programovani-pro-deti&quot;&gt;článek o kroužku programování&lt;/a&gt;, jako titulek si vybrali: „U budoucích ajťáků je nejdůležitější touha nespokojit se s prvním řešením.“&lt;br /&gt;
Ano, mimo jiné, ale kdybych měl jmenovat superschopnosti programátorů, co by to asi bylo?&lt;/p&gt;

&lt;div style=&quot;clear:both&quot;&gt;&lt;/div&gt;
&lt;!--more--&gt;

&lt;h2 id=&quot;psaní-kódu-versus-řešení-problémů&quot;&gt;Psaní kódu versus řešení problémů&lt;/h2&gt;

&lt;p&gt;Nejsme placení za psaní kódu (i když nás to baví), ale za řešení problémů.
Hned mi vytane &lt;a href=&quot;https://www.youtube.com/watch?v=aLK_sHpbWCc&quot;&gt;scéna z Pulp Fiction&lt;/a&gt;: „Jsem pan Wolf, řeším problémy.“&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://andrewmurphy.io/blog/if-you-thought-the-speed-of-writing-code-was-your-problem-you-have-bigger-problems&quot;&gt;Pokud jste si mysleli, že vaším problémem je rychlost psaní kódu, máte mnohem větší starosti.&lt;/a&gt;&lt;/p&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/aLK_sHpbWCc?si=OyEhkG3qyRI65env&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;analytická-mysl&quot;&gt;Analytická mysl&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://terriblesoftware.org/2025/11/25/what-actually-makes-you-senior/&quot;&gt;Klademe otázky, na které nikoho jiného nenapadlo se zeptat&lt;/a&gt;, a rozbíjíme špatná zadání.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.commitstrip.com/en/2016/08/25/a-very-comprehensive-and-precise-spec/&quot;&gt;Aby bylo možné nahradit programátory roboty, budou muset zákazníci přesně popsat, co chtějí.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2026-03-18/Strip-Les-specs-cest-du-code-650-finalenglish.jpg&quot; alt=&quot;&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://martinfowler.com/fragments/2026-03-10.html&quot;&gt;Martin Fowler a jeho kolegové se zamýšleli nad strojovou migrací COBOLu&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Přímý překlad by v nejlepším případě věrně zachytil stávající architektonická omezení, nahromaděné technické dluhy a zastaralá projektová rozhodnutí.
Neřešil by slabá místa; pouze by je převedl do jiného jazyka.&lt;/p&gt;

  &lt;p&gt;…&lt;/p&gt;

  &lt;p&gt;V praxi modernizace málokdy spočívá v zachování minulosti v nové syntaxi.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;hravost-a-odvaha&quot;&gt;Hravost a odvaha&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://stallman.org/articles/on-hacking.html&quot;&gt;Richard Stallman se zamýšlí nad původním významem slova Hacking.&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Je obtížné napsat jednoduchou definici něčeho tak rozmanitého jako je hacking, ale myslím si, že společným znakem těchto aktivit je hravost, chytrost a objevování.
Hacking tedy znamená zkoumání hranic možného v duchu hravé chytrosti.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Programátoři jsou podle mě troufalí až drzí, ve stylu Pipi Dlouhá punčocha: „To jsem ještě nikdy nedělala, to mi určitě půjde!“
Naučit se nový framework, &lt;a href=&quot;https://www.youtube.com/watch?v=s3n55CpS3CE&quot;&gt;opravit myčku&lt;/a&gt;, &lt;a href=&quot;/bydlen%C3%AD/2024/07/29/jak-jsem-debuggoval-kotel.html&quot;&gt;debuggovat kotel&lt;/a&gt; či &lt;a href=&quot;/bydlení/2013/09/23/jak-se-stavi-dum-svepomoci.html&quot;&gt;postavit dům svépomocí&lt;/a&gt;?
Pusťte mě k tomu!&lt;/p&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/s3n55CpS3CE?si=nyrIY2Iu8dedr3Ed&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;myšlení&quot;&gt;Myšlení&lt;/h2&gt;

&lt;p&gt;Budu &lt;a href=&quot;https://witter.cz/@calavera/116123006791829816&quot;&gt;citovat Frantu Řezáče&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Umět programovat znamená ve své podstatě umět myslet. Kdo to neumí sám, toho LLM nezachrání.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote class=&quot;mastodon-embed&quot; data-embed-url=&quot;https://witter.cz/@calavera/116123006791829816/embed&quot; style=&quot;background: #FCF8FF; border-radius: 8px; border: 1px solid #C9C4DA; margin: 0; max-width: 540px; min-width: 270px; overflow: hidden; padding: 0;&quot;&gt; &lt;a href=&quot;https://witter.cz/@calavera/116123006791829816&quot; target=&quot;_blank&quot; style=&quot;align-items: center; color: #1C1A25; display: flex; flex-direction: column; font-family: system-ui, -apple-system, BlinkMacSystemFont, &apos;Segoe UI&apos;, Oxygen, Ubuntu, Cantarell, &apos;Fira Sans&apos;, &apos;Droid Sans&apos;, &apos;Helvetica Neue&apos;, Roboto, sans-serif; font-size: 14px; justify-content: center; letter-spacing: 0.25px; line-height: 20px; padding: 24px; text-decoration: none;&quot;&gt; &lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; width=&quot;32&quot; height=&quot;32&quot; viewBox=&quot;0 0 79 75&quot;&gt;&lt;path d=&quot;M63 45.3v-20c0-4.1-1-7.3-3.2-9.7-2.1-2.4-5-3.7-8.5-3.7-4.1 0-7.2 1.6-9.3 4.7l-2 3.3-2-3.3c-2-3.1-5.1-4.7-9.2-4.7-3.5 0-6.4 1.3-8.6 3.7-2.1 2.4-3.1 5.6-3.1 9.7v20h8V25.9c0-4.1 1.7-6.2 5.2-6.2 3.8 0 5.8 2.5 5.8 7.4V37.7H44V27.1c0-4.9 1.9-7.4 5.8-7.4 3.5 0 5.2 2.1 5.2 6.2V45.3h8ZM74.7 16.6c.6 6 .1 15.7.1 17.3 0 .5-.1 4.8-.1 5.3-.7 11.5-8 16-15.6 17.5-.1 0-.2 0-.3 0-4.9 1-10 1.2-14.9 1.4-1.2 0-2.4 0-3.6 0-4.8 0-9.7-.6-14.4-1.7-.1 0-.1 0-.1 0s-.1 0-.1 0 0 .1 0 .1 0 0 0 0c.1 1.6.4 3.1 1 4.5.6 1.7 2.9 5.7 11.4 5.7 5 0 9.9-.6 14.8-1.7 0 0 0 0 0 0 .1 0 .1 0 .1 0 0 .1 0 .1 0 .1.1 0 .1 0 .1.1v5.6s0 .1-.1.1c0 0 0 0 0 .1-1.6 1.1-3.7 1.7-5.6 2.3-.8.3-1.6.5-2.4.7-7.5 1.7-15.4 1.3-22.7-1.2-6.8-2.4-13.8-8.2-15.5-15.2-.9-3.8-1.6-7.6-1.9-11.5-.6-5.8-.6-11.7-.8-17.5C3.9 24.5 4 20 4.9 16 6.7 7.9 14.1 2.2 22.3 1c1.4-.2 4.1-1 16.5-1h.1C51.4 0 56.7.8 58.1 1c8.4 1.2 15.5 7.5 16.6 15.6Z&quot; fill=&quot;currentColor&quot; /&gt;&lt;/svg&gt; &lt;div style=&quot;color: #787588; margin-top: 16px;&quot;&gt;Post by @calavera@witter.cz&lt;/div&gt; &lt;div style=&quot;font-weight: 500;&quot;&gt;View on Mastodon&lt;/div&gt; &lt;/a&gt; &lt;/blockquote&gt;
&lt;script data-allowed-prefixes=&quot;https://witter.cz/&quot; async=&quot;&quot; src=&quot;https://witter.cz/embed.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;br /&gt;
A mě baví myslet.&lt;/p&gt;

&lt;h2 id=&quot;zodpovědnost&quot;&gt;Zodpovědnost&lt;/h2&gt;

&lt;p&gt;Programátoři jsou za svoji práci zodpovědní.
&lt;a href=&quot;https://fazy.medium.com/agentic-coding-ais-adolescence-b0d13452f981&quot;&gt;AI agenti zlevňují výstupy. Nezlevňují však odpovědnost.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Tento výčet superschopností programátorů jistě nebude kompletní. 
Věřím, že bychom je uplatnili i jinde, kdyby nás náhodou nahradily stroje.&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.heroine.cz/zeny-it/7677-u-budoucich-ajtaku-je-nejdulezitejsi-touha-nespokojit-se-s-prvnim-resenim-rika-lektor-programovani-pro-deti&quot;&gt;U budoucích ajťáků je nejdůležitější touha nespokojit se s prvním řešením (Heroine)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://terriblesoftware.org/2025/11/25/what-actually-makes-you-senior/&quot;&gt;What Actually Makes You Senior&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://andrewmurphy.io/blog/if-you-thought-the-speed-of-writing-code-was-your-problem-you-have-bigger-problems&quot;&gt;If you thought the speed of writing code was your problem - you have bigger problems&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://fazy.medium.com/agentic-coding-ais-adolescence-b0d13452f981&quot;&gt;Verification debt: the hidden cost of AI-generated code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stallman.org/articles/on-hacking.html&quot;&gt;On Hacking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://naildrivin5.com/blog/2026/02/23/the-death-of-the-software-craftsman.html&quot;&gt;The Death of the Software Craftsman&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 18 Mar 2026 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2026/03/18/silne-stranky-programatoru.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2026/03/18/silne-stranky-programatoru.html</guid>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>Zastav Lego Pybricks na čáře</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2026-01-24/pybricks-logo.png&quot; /&gt;&lt;/div&gt;

&lt;p&gt;Stejně jako minulý rok se i letos zúčastníme soutěže &lt;a href=&quot;/software%20development/2025/03/23/first-lego-league-challenge.html&quot;&gt;FIRST Lego League Challenge&lt;/a&gt;.
Tentokrát už jsme si vyzkoušeli &lt;a href=&quot;https://pybricks.com/&quot;&gt;Pybricks&lt;/a&gt;.
Nečekejte ode mě shrnutí nebo nějakou recenzi, ale děti se mě zeptaly na jednu úlohu, kterou jsem v tom mumraji neodbavil okamžitou radou na místě.
Takže si plním za domácí úkol.
Jak zastavit Lego robota na černé čáře pomocí Pybricks?&lt;/p&gt;

&lt;div style=&quot;clear:both&quot;&gt;&lt;/div&gt;
&lt;!--more--&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2026-01-24/IMG_9414.jpeg&quot; alt=&quot;&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;pybricks&quot;&gt;Pybricks&lt;/h2&gt;

&lt;p&gt;Již loni se nám Pybricks dostal do hledáčku, že bychom tím nahradili prostředí &lt;a href=&quot;https://spike.legoeducation.com/&quot;&gt;Lego Spike&lt;/a&gt;.
Má nějaké zajímavé API jako například udržení rovného směru pomocí gyroskopu.
Varianta s Python kódem je zdarma, ale tím děti zatím trápit nechci.
Umožňuje používat i grafické bloky, na které jsou zvyklé, bohužel mi &lt;a href=&quot;https://pybricks.onfastspring.com/&quot;&gt;licence nepřijde zrovna levná&lt;/a&gt;.
I když použijete bloky, projekt si vyexportujete do Pythonu, což může v učení pomoci.&lt;/p&gt;

&lt;h2 id=&quot;zastavení&quot;&gt;Zastavení&lt;/h2&gt;

&lt;p&gt;Úloha „zastav se na čáře“ je velmi praktická.
Ostatně na herní plánu je několik čar, které můžete (ale nemusíte) k orientaci využít.
Lego má barevný senzor a k němu existuje &lt;a href=&quot;https://docs.pybricks.com/en/latest/pupdevices/colorsensor.html&quot;&gt;Pybricks API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Neuvědomil jsem si, že přesnost měření barvy bude záviset na okolním osvětlení a při použití hodnoty odrazivosti nebude černá nikdy nula (přece jen něco odrazí).
Chvilku jsem debugoval, jaké hodnoty naměřím na různých površích.
Nakonec jsem pro sebe použil hodnotu 20 (20 % odrazivosti).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2026-01-24/pybricks_debug.png&quot; alt=&quot;&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A pak už se k výslednému programu dostaneme poměrně přímočaře.
V blocích to může vypadat takto.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2026-01-24/pybricks_program.png&quot; alt=&quot;&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;V Pythonu takto.&lt;/p&gt;

&lt;noscript&gt;&lt;pre&gt;# pybricks blocks file:{&amp;quot;blocks&amp;quot;:{&amp;quot;languageVersion&amp;quot;:0,&amp;quot;blocks&amp;quot;:[{&amp;quot;type&amp;quot;:&amp;quot;blockGlobalSetup&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;bjK,wS1MYO7aiYkFSwd{&amp;quot;,&amp;quot;x&amp;quot;:4,&amp;quot;y&amp;quot;:51,&amp;quot;deletable&amp;quot;:false,&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_prime_hub&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;{)WuTTGMSJwLS.H*~PKI&amp;quot;,&amp;quot;extraState&amp;quot;:{&amp;quot;optionLevel&amp;quot;:1},&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;0ac8)M*M0@okqL6j*T]k&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;AXIS_TOP&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersAxis&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;G~~=qPiIM)z4Qy;ugq.J&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE&amp;quot;:&amp;quot;z&amp;quot;}}},&amp;quot;AXIS_FRONT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersAxis&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;=O,F=r_j:y!5C6~`*A2D&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE&amp;quot;:&amp;quot;y&amp;quot;}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_motor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;S?(a.C=~LVoJ~3YRo;}.&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;9-KY1{EjNJxUixuEoYJ?&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;PORT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersPort&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;pE~{$Zwzpz`i_VDqm^ab&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NAME&amp;quot;:&amp;quot;A&amp;quot;}}},&amp;quot;POSITIVE_DIRECTION&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersDirection&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;VrW-zLpmx[j,+8v+,L[1&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;SELECTION&amp;quot;:&amp;quot;Direction.COUNTERCLOCKWISE&amp;quot;}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_motor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;3,Y?*Mn1@v9fJ`yYW6Sf&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;@(Mc?VKF9P+IVA!,)0R;&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;PORT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersPort&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;r`9bbROX1dwatV7O$.:`&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NAME&amp;quot;:&amp;quot;E&amp;quot;}}},&amp;quot;POSITIVE_DIRECTION&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersDirection&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;Fk;M%s,~BY}0ww1j30bP&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;SELECTION&amp;quot;:&amp;quot;Direction.CLOCKWISE&amp;quot;}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_motor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;^b]cQj|TmdV%cZJhl0gI&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;#~*U;Y3)}OaA),GbQ/cW&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;PORT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersPort&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;?.^x_gX%wU.Xv.#3wRPP&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NAME&amp;quot;:&amp;quot;D&amp;quot;}}},&amp;quot;POSITIVE_DIRECTION&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersDirection&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;0Np/F+n#MjwgBk{6MrPK&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;SELECTION&amp;quot;:&amp;quot;Direction.CLOCKWISE&amp;quot;}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_motor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;I#`Wxj%/1]|h{X+ZQ;3Y&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;xE_y9@2/n%+##W#h*hFj&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;PORT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersPort&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;j1eKhU`bdoHdh)~]Hl2b&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NAME&amp;quot;:&amp;quot;C&amp;quot;}}},&amp;quot;POSITIVE_DIRECTION&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersDirection&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;|$c/*_TuT!~8{cQFN{[f&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;SELECTION&amp;quot;:&amp;quot;Direction.CLOCKWISE&amp;quot;}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_drive_base&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;B@6q{(N{H$OlQN@o(=#7&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;/@.Q%T4BjtqKCq7$UAbr&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_motor_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;h-`^(Zu#NTvZ*mW#2vcD&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;9-KY1{EjNJxUixuEoYJ?&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;kolo leve&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;}}}},&amp;quot;VAR2&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_motor_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;CD5,af-R[yO,bE]-?Uf_&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;@(Mc?VKF9P+IVA!,)0R;&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;kolo prave&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;}}}},&amp;quot;VALUE0&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;unit_distance&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;GNgo@U(M|24Obsy~%4x{&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE0&amp;quot;:88}}},&amp;quot;VALUE1&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;unit_distance&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;cIT+~l^nylC1%}(,bsKB&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE0&amp;quot;:144}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_color_sensor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;0]Gny{r@pu-me0u.qL+H&amp;quot;,&amp;quot;extraState&amp;quot;:{&amp;quot;optionLevel&amp;quot;:0},&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;4q7cl%:FR{.%!.~b;=4j&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;PORT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersPort&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;HrOt9)|o*,]VPV8SDZ9E&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NAME&amp;quot;:&amp;quot;B&amp;quot;}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_set_color_sensor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;x.AGwFp0|}^R*%F(%TcG&amp;quot;,&amp;quot;extraState&amp;quot;:{&amp;quot;optionLevel&amp;quot;:0},&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;^z-R_D5t#~Oky5)7@fjS&amp;quot;}},&amp;quot;inputs&amp;quot;:{&amp;quot;PORT&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockParametersPort&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;I!+TlWLqzTDYY6^$uKdf&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NAME&amp;quot;:&amp;quot;F&amp;quot;}}}}}}}}}}}}}}}}}}}}},{&amp;quot;type&amp;quot;:&amp;quot;blockGlobalStart&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;3tJe|AWl0baN(wH9a$@.&amp;quot;,&amp;quot;x&amp;quot;:990,&amp;quot;y&amp;quot;:44,&amp;quot;deletable&amp;quot;:false,&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockDriveBaseUseGyro&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;W=Lm:RpeA}v?nKUf*^6.&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;METHOD&amp;quot;:&amp;quot;DRIVEBASE_USE_GYRO_TRUE&amp;quot;},&amp;quot;inputs&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_drive_base_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;i{6(E*p~D3tY|M-^UtvG&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;/@.Q%T4BjtqKCq7$UAbr&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;drive base&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;DriveBase&amp;quot;}}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockDriveBaseConfigure&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;g3I/xPp1/oeRSee5-LA^&amp;quot;,&amp;quot;extraState&amp;quot;:{&amp;quot;optionLevel&amp;quot;:1},&amp;quot;fields&amp;quot;:{&amp;quot;METHOD&amp;quot;:&amp;quot;DRIVEBASE_STRAIGHT_SPEED&amp;quot;},&amp;quot;inputs&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_drive_base_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;Z+6V|uC*Z3_Z4Pd$0di/&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;/@.Q%T4BjtqKCq7$UAbr&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;drive base&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;DriveBase&amp;quot;}}}},&amp;quot;ARG0&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;unit_speed&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;oc%m!QtUlj%nS}0wUkdH&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE0&amp;quot;:500}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockFlowWhile&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;^w![3wsmge-,nl%)9)_2&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;MODE&amp;quot;:&amp;quot;WHILE&amp;quot;},&amp;quot;inputs&amp;quot;:{&amp;quot;BOOL&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockLogicTrue&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;|%RuaCQaVxPi_*BB*Hea&amp;quot;},&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockLogicCompare&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;0-l;i-(OX+f@B$[%Nv?7&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;OP1&amp;quot;:&amp;quot;GT&amp;quot;},&amp;quot;inputs&amp;quot;:{&amp;quot;A&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockMathNumber&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;0R9k4vfG#^mUZ#xuV!Yy&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NUM&amp;quot;:3}},&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockLightReflection&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;xPaTrirocgrfw:z($hfN&amp;quot;,&amp;quot;inputs&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_light_intensity_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;DOR_9uhk=S}7mpH~6ny:&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;4q7cl%:FR{.%!.~b;=4j&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;senzor levy&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorSensor&amp;quot;}}}}}}},&amp;quot;B&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockMathNumber&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;=Fis}(OW{eVsQ%GL+Xv?&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;NUM&amp;quot;:20}}}}}},&amp;quot;DO&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockDriveBaseDrive2&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;e!qh#u{yRC]5T}d88!wD&amp;quot;,&amp;quot;extraState&amp;quot;:{&amp;quot;optionLevel&amp;quot;:2},&amp;quot;fields&amp;quot;:{&amp;quot;METHOD&amp;quot;:&amp;quot;DRIVEBASE_DRIVE_STRAIGHT&amp;quot;},&amp;quot;inputs&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_drive_base_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;Fn3J0txHNG:z99+vK!pI&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;/@.Q%T4BjtqKCq7$UAbr&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;drive base&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;DriveBase&amp;quot;}}}},&amp;quot;ARG0&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;unit_distance&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;Zf;zZ*m@T_Mm5%_U]r.u&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE0&amp;quot;:50}}},&amp;quot;ARG1&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;parameters_stop_4&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;m4%XtpLADnb=l]x@*bmt&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE&amp;quot;:&amp;quot;Stop.NONE&amp;quot;}}}}}}},&amp;quot;next&amp;quot;:{&amp;quot;block&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;blockDriveBaseStop&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;FQcgVD9TN#4W;ib{Q}Dj&amp;quot;,&amp;quot;inputs&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;variables_get_drive_base_device&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;sJ%~bnFg:!9s?/VX*/M(&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VAR&amp;quot;:{&amp;quot;id&amp;quot;:&amp;quot;/@.Q%T4BjtqKCq7$UAbr&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;drive base&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;DriveBase&amp;quot;}}}},&amp;quot;VALUE0&amp;quot;:{&amp;quot;shadow&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;parameters_stop_3&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;ELOu@BWpK(Ie4(+d)AL_&amp;quot;,&amp;quot;fields&amp;quot;:{&amp;quot;VALUE&amp;quot;:&amp;quot;Stop.HOLD&amp;quot;}}}}}}}}}}}}}]},&amp;quot;variables&amp;quot;:[{&amp;quot;name&amp;quot;:&amp;quot;red&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;^TRnlnrf1|b]54?=RSAE&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;orange&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;T/Ga=6s={mOa/4,vyj]{&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;yellow&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;z6p)=?w#+g|y@lU:VFt*&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;green&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;PQR$ys-f%#*T_4`Rx0fH&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;cyan&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;n3GEOv6@N!|xg_x}=GL+&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;blue&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;G_|mnBi;ov8st$C/z;$W&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;violet&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;MMX}YsyH/D)kVHpH2a/t&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;magenta&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;@4TT%Ad^Qyn!IQ9HhF{H&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;white&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;Yknl*y[~$s;/3RGi{ju1&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;none&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;e|_}L8nQoa5[!)|??9+L&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorDef&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;prime hub&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;0ac8)M*M0@okqL6j*T]k&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;PrimeHub&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;drive base&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;/@.Q%T4BjtqKCq7$UAbr&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;DriveBase&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;kolo leve&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;9-KY1{EjNJxUixuEoYJ?&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;kolo prave&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;@(Mc?VKF9P+IVA!,)0R;&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;motor predni&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;#~*U;Y3)}OaA),GbQ/cW&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;motor zadni&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;xE_y9@2/n%+##W#h*hFj&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;motor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;4f^oLh]vR?;f9cEyqLvm&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;Motor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;senzor levy&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;4q7cl%:FR{.%!.~b;=4j&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorSensor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;senzor pravy&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;^z-R_D5t#~Oky5)7@fjS&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorSensor&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;sensor&amp;quot;,&amp;quot;id&amp;quot;:&amp;quot;-BWH)YE(r`_KzM)7#.kx&amp;quot;,&amp;quot;type&amp;quot;:&amp;quot;ColorSensor&amp;quot;}],&amp;quot;info&amp;quot;:{&amp;quot;type&amp;quot;:&amp;quot;pybricks&amp;quot;,&amp;quot;version&amp;quot;:&amp;quot;1.3.2&amp;quot;}}
from pybricks.hubs import PrimeHub
from pybricks.parameters import Axis, Direction, Port, Stop
from pybricks.pupdevices import ColorSensor, Motor
from pybricks.robotics import DriveBase

# Set up all devices.
prime_hub = PrimeHub(top_side=Axis.Z, front_side=Axis.Y)
senzor_levy = ColorSensor(Port.B)
senzor_pravy = ColorSensor(Port.F)
kolo_leve = Motor(Port.A, Direction.COUNTERCLOCKWISE)
kolo_prave = Motor(Port.E, Direction.CLOCKWISE)
motor_predni = Motor(Port.D, Direction.CLOCKWISE)
motor_zadni = Motor(Port.C, Direction.CLOCKWISE)
drive_base = DriveBase(kolo_leve, kolo_prave, 88, 144)


# The main program starts here.
drive_base.use_gyro(True)
drive_base.settings(straight_speed=500)
while senzor_levy.reflection() &amp;gt; 20:
    drive_base.straight(50, then=Stop.NONE)
drive_base.straight(0)
&lt;/pre&gt;&lt;/noscript&gt;
&lt;script src=&quot;https://gist.github.com/banterCZ/c17931e17c3f1b34120e89869bf5e5bc.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Všimněte si, že bloku pohybu lze v &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;then&lt;/code&gt; nastavit, co dělat na konci bloku, což ovlivní, jak (ne)plynule pojede.
Stejně tak na konci nastavuji &lt;a href=&quot;https://docs.pybricks.com/en/latest/parameters/stop.html#Stop&quot;&gt;způsob zastavení&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Pybricks nabízí pokročilejší funkce oproti Lego Spike prostředí.
Varianta psaní v Pythonu je zdarma, za grafické bloky si připlatíte.
Spouštění programů ve fyzickém světě dokáže vždycky něčím překvapit, třeba zjištěním, že i černá barva odrazí nějaké světlo.&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/software%20development/2025/03/23/first-lego-league-challenge.html&quot;&gt;FIRST Lego League Challenge&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 24 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2026/01/24/zastav-lego-pybricks-na-care.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2026/01/24/zastav-lego-pybricks-na-care.html</guid>
        
        <category>kroužek programování</category>
        
        <category>lego</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>Jak zkoušíme bicí</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-12-27/263162.png&quot; /&gt;&lt;/div&gt;

&lt;p&gt;Na skautský tábor s námi jezdí jeden rodič, povoláním profesionální muzikant.
Už druhým rokem jsme tedy založili táborovou kapelu i z naprostých začátečníků, bylo to skvělé.
Dcera se vrátila s přáním, že chce začít hrát na kytaru.
Syn se přidal, že by taky rád něco zkusil, ale neví co.
Nakonec jsme vybrali bicí.
Máme už je doma od léta, tak sepisuji několik postřehů.&lt;/p&gt;

&lt;!--more--&gt;
&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;proč-zrovna-bicí&quot;&gt;Proč zrovna bicí&lt;/h2&gt;

&lt;p&gt;Při výběru nástroje jsem bral v potaz, že syn na tom není nejlépe s motorikou.
Zároveň jsem si nebyl jistý, jak pečlivě a pravidelně bude cvičit.&lt;/p&gt;

&lt;p&gt;První volbou bývá zobcová flétna a jelikož jsem na ni sám začínal, tak říkám, že to není volba ideální.
Vyloudit čistý tón dá práci.&lt;/p&gt;

&lt;p&gt;Navrhoval jsem piano, tam máte tón vždy čistý.
Případně foukací harmoniku, kde máte jistotu, že cokoliv zahrajete, je v tónice.&lt;/p&gt;

&lt;p&gt;Mám dojem, že bicí neprávem stojí trochu stranou.
Tak schválně.
Jak se jmenuje zpěvák a kytarista vaší oblíbené kapely?
A jak jejich bubeník?&lt;/p&gt;

&lt;p&gt;Přitom &lt;a href=&quot;https://www.cernejpudink.cz/2016/08/01/iggy-pop-chtel-bych-byt-tvuj-coklik/&quot;&gt;Iggy Pop začínal na bicí&lt;/a&gt;.
Nebo koukněte, jak válí &lt;a href=&quot;https://www.youtube.com/watch?v=l5wkTdVjE1s&quot;&gt;Mag White&lt;/a&gt;.&lt;/p&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/l5wkTdVjE1s?si=HER3iwdc6rJk32NP&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;pohled-hráče-na-baskytaru&quot;&gt;Pohled hráče na baskytaru&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/jak-zacit-hrat-na-hudebni-nastroj.html&quot;&gt;Začal jsem hrát baskytaru&lt;/a&gt; a od té doby si víc všímám bicích.
Koukněte třeba na super lekci &lt;a href=&quot;https://www.youtube.com/watch?v=PSw5uqkTPzs&quot;&gt;How to Play Bass with a Drummer (Foolproof Beginner Blueprint)&lt;/a&gt;.&lt;/p&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/PSw5uqkTPzs?si=GMgg7Szx6cIvjscK&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Zlý jazykové o mně tvrdí, že dělím věci na dvě kategorie: co jsem dělal a co teprve budu dělat.
Jo, chtěl jsem si bicí taky zkusit.
I proto, aby mě to posunulo jako basáka.&lt;/p&gt;

&lt;p&gt;Bavil jsem se s jedním bubeníkem, který mi opakoval mantru, že baskytarista klidně může zahrát špatnou notu, ale musí to být ve správný čas.
Jasně, ale kontroval jsem, že je to přece nástroj na pomezí rytmické a melodické sekce.
Načež se mi dostalo odpovědi: „Jsem byl na jednom jazzovém workshopu a pro ně je rytmické všechno od piana dál.“&lt;/p&gt;

&lt;h2 id=&quot;výběr-nástroje&quot;&gt;Výběr nástroje&lt;/h2&gt;

&lt;p&gt;Předně jsem chtěl elektronické bicí.
Nezabírají tolik místa.
Nadělají méně hluku, ale nenechte se zmást, že vás nebudou rušit vůbec.&lt;/p&gt;

&lt;p&gt;Už jsme kdysi jeden neúspěšný pokus učinili.
Jednak byly děti ještě příliš malé, jednak jsme měli „jen“ &lt;a href=&quot;https://www.lidl.cz/p/elektronicka-bici-souprava/p100367782&quot;&gt;nástroj z Lidlu&lt;/a&gt;, u kterého jsem narazil na limit, že jsem nedokázal pro výukový program správně namapovat MIDI signály pro tom bubny.&lt;/p&gt;

&lt;p&gt;Tentokrát jsem sáhl po serióznějším kousku, &lt;a href=&quot;https://www.thomann.de/cz/yamaha_dd_75.htm&quot;&gt;Yamaha DD-75&lt;/a&gt;.
Tahle firma dělá dobře všechno od motorek po kytary.&lt;/p&gt;

&lt;p&gt;Pedály, které k tomu dostane, jsou spíš tlačítka.
Na pár první hodin to stačí, ale pak vám to začne lézt na nervy.
U &lt;em&gt;hi-hat&lt;/em&gt; necítíte, zda vám nesjela noha a najednou hrajete &lt;em&gt;open hi-hat&lt;/em&gt;.
U kopáku chybí pořádná odezva.&lt;/p&gt;

&lt;p&gt;Za dobré pedály dáte víc než za samotné bicí.
&lt;a href=&quot;https://www.thomann.de/cz/yamaha_hh60.htm&quot;&gt;Yamaha HH-65 Hi-Hat Controller&lt;/a&gt; je super.
Bez pořádné přípravy jsem koupil &lt;a href=&quot;https://www.thomann.de/cz/yamaha_ku100_silent_kick_pedal.htm&quot;&gt;Yamaha KU100 Silent Kick Pedal&lt;/a&gt;, který je sice tichý a lepší než pouhé tlačítko, ale odezva taky příliš lehká.
Trochu kraválu snesu, takže pro mě je vítěz &lt;a href=&quot;https://www.thomann.de/cz/roland_kt_10_kick_trigger_pedal.htm&quot;&gt;Roland KT-10 Kick Trigger Pedal&lt;/a&gt;. Býval jsem se měl podívat na &lt;a href=&quot;https://www.youtube.com/watch?v=dPr82Tpbz1w&quot;&gt;recenzi od 65 Drums&lt;/a&gt;.&lt;/p&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/dPr82Tpbz1w?si=nq9Ssc2JWuJbStHD&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;výukový-program&quot;&gt;Výukový program&lt;/h2&gt;

&lt;p&gt;Vybíral jsem elektronický nástroj i z důvodu připojení na výukové nástroje přes MIDI.
Můžu doporučit &lt;a href=&quot;https://melodics.com/&quot;&gt;Melodics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Několik večerů jsem byl úplně marný.
Je to samá ruka, samá noha, a všechno zkoordinovat je fakt fuška.
Vzpomněl jsem si na jeden článek od &lt;a href=&quot;https://blog.duolingo.com/what-makes-arabic-hard-and-why-that-shouldnt-stop-you-from-learning-it/&quot;&gt;Duolingo: What makes Arabic hard (and why that shouldn’t stop you from learning it)&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Když dospějeme, mluvíme svým jazykem (nebo jazyky) jako mistr kytarista hraje na svůj nástroj: plynule, automaticky a velmi krásně. Proces učení se novému jazyku je jako když se mistr kytarista učí hrát na nový nástroj. Pokud dáte kytaristovi mandolínu, mnoho z dovedností, které již má, mu pomůže: ladění nástroje, brnkání atd. Flétna však vyžaduje zcela nové dovednosti. A bicí? Náš kytarista prakticky začíná od nuly, když se učí hrát na bicí.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Jakmile se z prvního šoku vzpamatujete, tak jejich program oceníte.
Dnešní didaktický standard je &lt;em&gt;gamifikace&lt;/em&gt;, oslavování několikadenních řad a gratulace k dosaženému pokroku.
Dostáváte zpětnou vazbu, zda jste udeřili brzy, pozdě čí víckrát, než bylo třeba.
Lekce jsem zábavné a už od začátku hrajete muziku.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=69z_pK3b1po&quot;&gt;Ukázka jedné lekce&lt;/a&gt;.&lt;/p&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/69z_pK3b1po&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Určitě doporučuji vyzkoušet si bicí.
Samo o sobě je to zábava a velká výzva pro motoriku.
I když hrajete na jiný nástroj, tak vás to hudebně posune.
Elektronické bicí jsou méně hlučné, ale ne úplně tiché.
Bez pořádných pedálů to není ono, ale nejsou úplně levné.&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/obecn%C3%A9/2025/02/23/operne-pisne-pro-intervaly.html&quot;&gt;Opěrné písně pro intervaly&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/jak-zacit-hrat-na-hudebni-nastroj.html&quot;&gt;Jak začít hrát na hudební nástroj&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 27 Dec 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/obecn%C3%A9/2025/12/27/jak-zkousime-bici.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/obecn%C3%A9/2025/12/27/jak-zkousime-bici.html</guid>
        
        <category>hudba</category>
        
        
        <category>obecné</category>
        
      </item>
    
      <item>
        <title>Ať žijí timeouty</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-11-27/26203.png&quot; /&gt;&lt;/div&gt;

&lt;p&gt;Žil byl, nebo tedy právě spíš nebyl, jednou jeden timeout (ono jich vlastně nakonec chybělo dokonce víc).
Stalo se to už před nějakou dobou, tak snad je to částečně odžité.
Na testovacím prostředí všechno vyzkoušené a krásně funguje.
Z produkce jsou hlášené divné chyby, které postupně vedly až ke zhroucení komponenty.
Dlouho se mi nedařilo bug reprodukovat natož odhalit příčinu.
Nakonec jsme na to samozřejmě přišli, proto si zapisuju poučení.
Stejně jako v případě leteckých havárií, se sešlo víc věcí najednou.&lt;/p&gt;

&lt;!--more--&gt;
&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;expozice&quot;&gt;Expozice&lt;/h2&gt;

&lt;p&gt;Java backend provolával službu třetí strany přes REST API.
Daná servisní metoda běžela úmyslně v databázové transakci i s vědomím, že REST volání může trvání neúměrně prodloužit.
Nicméně konzistence dat byla v tomto případě naprosto klíčová.
Tak klíčová, že bylo dokonce nezbytné použít pesimistické zamykání databáze.&lt;/p&gt;

&lt;h2 id=&quot;co-by-se-asi-tak-mohlo-pokazit&quot;&gt;Co by se asi tak mohlo pokazit&lt;/h2&gt;

&lt;p&gt;Tak já vám povím, co by se asi tak mohlo pokazit.&lt;/p&gt;

&lt;p&gt;Upřímně, vůbec nemám rád aplikační servery, ale jednu věc jim nemůžu upřít.
Mívaly výchozí nastavení timeoutu databázové transakce.
&lt;a href=&quot;https://docs.spring.io/spring-framework/reference/6.2/data-access/transaction/declarative/txadvice-settings.html&quot;&gt;Spring má výchozí timeout -1&lt;/a&gt;, tedy nekonečno.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/a/76520564/204950&quot;&gt;PostgreSQL nepodporuje lock na úrovni statementu a tudíž nefunguje Hibernate JPA hint&lt;/a&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spring.jpa.properties.jakarta.persistence.lock.timeout&lt;/code&gt;.
Můžete to nastavit globálně pro celou databázi pomocí &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALTER DATABASE powerauth SET lock_timeout=10000;&lt;/code&gt;, ale jednak to musíte vědět a jednak na to nesmíte zapomenout.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.baeldung.com/spring-webflux-timeout&quot;&gt;Spring WebClient postavený na Reactoru nenastavuje response timeout&lt;/a&gt;, výchozí hodnota je nekonečno.&lt;/p&gt;

&lt;h2 id=&quot;takže-se-to-pokazilo&quot;&gt;Takže se to pokazilo&lt;/h2&gt;

&lt;p&gt;Nepřekvapivě tedy zásek na volání REST API vyžral celý db connection pool.
Když se něco může pokazit, tak se to zaručeně pokazí, a je naší zodpovědností to ošetřit.
Byla to tedy naše chyba, že jsme správně nastavili všechny timeouty.
To přišlo opravit.
Ale proč situace nastávala opakovaně?&lt;/p&gt;

&lt;h2 id=&quot;co-se-vlastně-pokazilo&quot;&gt;Co se vlastně pokazilo&lt;/h2&gt;

&lt;p&gt;Služba třetí strany běžela za &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-tcp-reset#configurable-tcp-idle-timeout&quot;&gt;Azure Load Balancerem, který ukončoval idle TCP connection po čtyřech minutách&lt;/a&gt;.
K čemu tedy došlo na produkci jinému než při testu?&lt;/p&gt;

&lt;p&gt;Provolá se REST API, naváže se nové TCP spojení, odbaví se request, a spojení se vrátí do poolu.
Má se znovu provolat REST API, vyzvedne se spojení z poolu, které nikdo víc jak čtyři minut nepoužil.
Spojení je vadné, ale pool se mylně domnívá, že je stále živé.
K naší smůle není nastavený timeout.
Tady se dostávám na tenký led síťování, kterému nerozumím.
Spojení pravděpodobně nevypadlo z poolu, protože nebyl zapnutý &lt;em&gt;TCP reset&lt;/em&gt;, ale i kdyby byl, tak na něj stejně nemůžeme spoléhat.
Nabízí se ladit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;keepAlive&lt;/code&gt;, ale to nechávám zvídavému čtenáři k &lt;a href=&quot;https://www.baeldung.com/spring-webflux-timeout&quot;&gt;nastudování&lt;/a&gt;,&lt;/p&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Spring Boot není jediný a nebyl ani první, kdo razí přístup &lt;em&gt;convention over configuration&lt;/em&gt; a kdo přináší smysluplné výchozí hodnoty.
Tedy neměň, co nepotřebuješ.
Když není důvod něco specificky nastavovat, tak spoléhám na výchozí hodnoty.
Ale některé výchozí hodnoty jsou méně či více nebezpečné a je bezpodmínečně nutné vědět, co člověk dělá.&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.baeldung.com/spring-webflux-timeout&quot;&gt;Baeldung - Set a Timeout in Spring WebClient&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/76520564/204950&quot;&gt;Stack Overflow - How to set lock timeout in postgres - Hibernate&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hibernate.atlassian.net/browse/HHH-16071&quot;&gt;javax.persistence.lock.timeout does not fully work with PostgreSQL&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-tcp-reset#configurable-tcp-idle-timeout&quot;&gt;Azure - Load Balancer TCP Reset and Idle Timeout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 27 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/11/27/at-ziji-timeouty.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/11/27/at-ziji-timeouty.html</guid>
        
        <category>Java</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>IDDQD</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-10-17/doom_face.png&quot; /&gt;&lt;/div&gt;
&lt;p&gt;Jedná se o textový přepis přednášky, kterou jsem měl na nekonferenci &lt;a href=&quot;https://www.jopenspace.cz/&quot;&gt;jOpenSpace&lt;/a&gt; 2025, &lt;a href=&quot;https://www.youtube.com/watch?v=nFd82No3C7Q&quot;&gt;video záznam ke shlédnutí&lt;/a&gt;.
Je mi ctí, že jsem mohl dělat předskokana &lt;a href=&quot;https://www.youtube.com/watch?v=1-KYK7pvyUg&quot;&gt;Tomuchovi a jeho povídání o shaderech&lt;/a&gt; (náhodička, vůbec jsme se nedomlouvali předem, jako fakt).
Nepřináším žádné závratné novinky, nýbrž tichou, ale naléhavou, touhu po úniku z drsné přítomnosti do idylického bezpečí minulosti.
Ostatně už jsem vzpomínal na počítač &lt;a href=&quot;/software%20development/2023/10/23/pocta-c64.html&quot;&gt;Commodore 64&lt;/a&gt;.&lt;/p&gt;

&lt;!--more--&gt;
&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;videozáznam&quot;&gt;Videozáznam&lt;/h2&gt;

&lt;iframe class=&quot;center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/nFd82No3C7Q?si=prbEiGjW6W5Tcnlk&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;knihy&quot;&gt;Knihy&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2025-10-17/50_let_videoher.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Z nostalgie jsem si koupil si knihu &lt;a href=&quot;https://www.xzone.cz/kniha-level-50-let-videoher&quot;&gt;50 let videoher&lt;/a&gt;.
Ideální dárek pro starý fotry.
Sbírka článků z časopisu Level.
Úžasné provedení na křídovém papíře.
Kromě samotného úniku do dětství mě fascinují technologie, která stojí za skvělými produkty, stejně tak mě fascinují podmínky, které k tomu vedly.&lt;/p&gt;

&lt;p&gt;Mezi hrami samozřejmě nesměl chybět &lt;a href=&quot;https://en.wikipedia.org/wiki/Doom_(1993_video_game)&quot;&gt;Doom&lt;/a&gt;.
A když jsem hledal téma svůj letošní příspěvek, tak jsem si konečně přečetl knihu &lt;a href=&quot;https://fabiensanglard.net/gebbdoom/index.html&quot;&gt;The Game Engine Black Book: DOOM, Fabien Sanglard&lt;/a&gt; (k dispozici legálně zdarma).&lt;/p&gt;

&lt;p&gt;A ohledně názvu přednášky se nakonec ukázalo, že znalost &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDDQD&lt;/code&gt; není úplně stoprocentně sdílená.
Tak vězte, že se jednalo o &lt;em&gt;cheat&lt;/em&gt; nesmrtelnosti.&lt;/p&gt;

&lt;p&gt;Hře Doom předcházela hra &lt;a href=&quot;https://en.wikipedia.org/wiki/Wolfenstein_3D&quot;&gt;Wolfenstein 3D&lt;/a&gt;, které se tu nehodlám podrobněji věnovat.
Ostatně Fabien Sanglard o ní vydal samostatnou knihu.
Nicméně ve zkratce, zlí jazykové tvrdí, že šlo o 2,5D hru.
Stěny jsou pravoúhlé, podlahy a stropy bez textur.
Pohybujete se po jediné výškové úrovni, chybí výtahy.
Sprity jsou vykresleny 2D.&lt;/p&gt;

&lt;h2 id=&quot;rok-1993&quot;&gt;Rok 1993&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2025-10-17/ct_archiv.jpg&quot; alt=&quot;&quot; /&gt;
&lt;a href=&quot;https://www.ceskatelevize.cz/porady/10116288585-archiv-ct24/213411058210041/&quot;&gt;archiv ČT24&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Píše se rok 1993.
Zeman už je v politice.
Rozděluje se Československo.
Já chodím do třetí třídy.&lt;/p&gt;

&lt;p&gt;Mezitím tvůrčí duo John Romero (25 let) a John Carmack (22 let) vydávají ambiciózní tiskovou zprávu, že za 11 měsíců máme čekat převratnou novinku.
Romero Doomem dodnes žije a vyjadřuje se k němu, takže nemohl chybět ani v dokumentární seriálu &lt;a href=&quot;https://www.csfd.cz/film/894583-nejvyssi-skore/prehled/&quot;&gt;High Score&lt;/a&gt;, kde mimo jiné tvrdí, že na konzolích funguje plynulý scroll, to tehdejší PC hry neuměly.
Konzole tou dobou znamenalo například &lt;a href=&quot;https://en.wikipedia.org/wiki/Super_Nintendo_Entertainment_System&quot;&gt;Super Nintendo&lt;/a&gt; v ceně 199 USD (přepočteno na dnešní inflaci 446 USD).&lt;/p&gt;

&lt;p&gt;Když jsem slyšel scrollování, tak jsem si vzpomněl na hru &lt;a href=&quot;https://en.wikipedia.org/wiki/Duke_Nukem_II&quot;&gt;Duke Nukem 2D&lt;/a&gt;, známou svým &lt;a href=&quot;https://lethalguitar.wordpress.com/2022/07/14/how-duke-nukem-iis-parallax-scrolling-worked/&quot;&gt;dual-parallax scrollingem&lt;/a&gt;, ale vyšel až v prosinci 1993.
Ta doba byla těhotná pokrokem.&lt;/p&gt;

&lt;p&gt;O hry s 3D grafikou se snažili i na konzolích, první slavná je &lt;a href=&quot;https://en.wikipedia.org/wiki/Star_Fox_(1993_video_game)&quot;&gt;Star Fox&lt;/a&gt;.
Nedostatek výkonu mohli dohánět čipem v cartridge.&lt;/p&gt;

&lt;h2 id=&quot;pc&quot;&gt;PC&lt;/h2&gt;

&lt;p&gt;Platforma PC byla zamýšlená pro textové editory, tabulkové procesory, sem tam zobrazit graf a ne animaci se 70 snímky za vteřinu.
4MB RAM, 14” CRT monitor 320 x 200, bratru za 3000 USD (přepočteno na dnešní inflaci 6726 USD).&lt;/p&gt;

&lt;p&gt;Tou dobou máme procesor Intel a ne Pentium, ale 486.
Když jsem viděl digramy pipelingu, otevřely se mi staré rány z ČVUT.
Na škole mě to deptalo.
S příběhem mi to přišlo srozumitelné a bavilo mě to.
Jako děti jsme porovnávali jen taktovací frekvence, čím víc herzů, tím víc adidas.
Ale je potřeba koukat na změny v architektuře.
Procesor 386 například potřeboval dva takty na dekódování instrukce.
A přestože procesor 486 s matematickým koprocesorem (takže spíš 487, ale to už nechci zabíhat do detailů) zrychlil operace v plovoucí desetinné čárce až na třetinu, stále to bylo zoufale pomalé oproti celočíselným operacím.
Proto Doom zůstává u integerů.&lt;/p&gt;

&lt;p&gt;Procesory se vyvíjely rychlejším tempem než paměti.
Paměť DRAM byla levná, buňka obsahovala kapacitor a jeden tranzistor.
Po přečtení bylo nutné znovu zapsat.
Zápis bylo potřeba opakovat i bez čtení, protože kapacitor se vybíjel.&lt;/p&gt;

&lt;p&gt;SRAM byla výrazně rychlejší, ale dražší, jelikož konstrukce vyžadovala minimálně šest tranzistorů.
Využívala se pro cache.
Cache má další rychlostní výhodu, protože procesor s ní komunikuje přímo a nemusí přes sběrnici.&lt;/p&gt;

&lt;p&gt;I sběrnice se dočkaly vylepšení.
VESA byla asi desetkrát rychlejší než ISA.
Zvýšila se přenosová šířka na 32 bitů i frekvence.&lt;/p&gt;

&lt;p&gt;Sound Blaster přináší zvukovou kartu s CD kvalitou.&lt;/p&gt;

&lt;p&gt;A aby to nebyly jen nostalgické kecy, tak nějaké architektonické poučení.
Trh se zvukovými kartami byl značně fragmentovaný.
Tehdy sáhli po knihovně DMX, o které se dnes Romero vyjadřuje, že nebyla dobrá, že by si to býval napsal sám.
Ale už nepřipouští, že by to nejspíš za 11 měsíců vůbec nestihli.&lt;/p&gt;

&lt;p&gt;Můžete si připomenout loňskou přednášku &lt;a href=&quot;https://www.youtube.com/watch?v=k8WL-joze3I&quot;&gt;Zákony SW architektury (Lukáš Křečan)&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Všechna rozhodnutí v architektuře jsou kompromisy a žádné řešení není dokonalé&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Paralelní programování se realizovalo pomocí IRQ (Interrupt Request, signál požadavku na přerušení) a DMA (Direct Memory Access, přímý přístup do paměti).&lt;/p&gt;

&lt;h2 id=&quot;nextstep&quot;&gt;NeXTSTEP&lt;/h2&gt;

&lt;p&gt;Ač byll Doom cílený na platformu PC, tak samotný vývoj probíhal na superpočítačích NeXTSTEP.
Slavný příběh by vydal na samostatnou přednášku, Steve Jobs byl odejit z Applu, ten pak NeXTSTEP později kupuje atd.&lt;/p&gt;

&lt;p&gt;8MB RAM, 17” displej 1120 x 832, volitelně CD ROM bratru za 6 500 USD (přepočteno na dnešní inflaci 14 573 USD)&lt;/p&gt;

&lt;h2 id=&quot;programování&quot;&gt;Programování&lt;/h2&gt;

&lt;p&gt;Spojenectví mezi Sunem a Nextem symbolizují &lt;a href=&quot;https://developer.apple.com/documentation/foundation/nsarray&quot;&gt;písmena NS, které dodnes vidíte v API&lt;/a&gt;.
Je velmi pravděpodobné, že kód, který kdysi běžel na NeXTSTEP a přispěl ke stvoření Dooma, nyní běží na mnoha milionech Apple počítačích nebo telefonech.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2025-10-17/c_meme.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Doom byl napsaný v C++.
Kolem toho jsem se mihnul.
C/C++ pro mě znamená pointery.
Když slyším pointery, vybavím si tento vtípek a můj mozek vypíná.
Musíte se starat o pamět.
Funkce &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Malloc&lt;/code&gt; způsobovala fragmentaci paměti, tak si museli vyvinout vlastní &lt;em&gt;Zone memory manager&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Na PC měli v DOS Borland C++ editor, který měl sice zvýrazňování syntaxe, ale na obrazovku se nevešlo moc řádek a údajně neustále padal.
TextEdit na NeXTSTEP neuměl zvýrazňovat, ale zobrazil víc řádek, uměl je zabalovat a hlavně byl stabilní.&lt;/p&gt;

&lt;p&gt;Zatímco C++ dával na první místo výkon, tak Objective-C, ve kterém se programovalo na NeXTSTEP, upřednostňoval programátorskou produktivitu.
Nikdy jsem v něm nepsal, ale Objective-C pro mě znamená &lt;a href=&quot;https://en.wikipedia.org/wiki/Message_passing&quot;&gt;message passing&lt;/a&gt;, pro nás Java programátory dodnes něco převratného.
Přitom když budete děti učit &lt;a href=&quot;https://en.scratch-wiki.info/wiki/Broadcast&quot;&gt;Scratch, tak je to něco přirozeného&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2025-10-17/doom_screenshot.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Doom to jsou brokovnice, démoni a dynamické světelné podmínky.
A jak toho dosáhli bez 24 bitové barevné podpory?
Připravili si 32 palet o 256 barvách.&lt;/p&gt;

&lt;p&gt;Doom přináší multiplayer, hru více hráčů proti sobě, tehdy ještě bez centrálního serveru.
My jsme se propojovali přes sériové a paralelní kabely.&lt;/p&gt;

&lt;h2 id=&quot;distribuce&quot;&gt;Distribuce&lt;/h2&gt;

&lt;p&gt;Doom distribuovali na dvou disketách jako &lt;em&gt;shareware&lt;/em&gt;.
Tedy první epizoda zdarma, pokračování k zakoupení.&lt;/p&gt;

&lt;p&gt;Plná verze byla menší než 12 MB.
Samotný engine něco málo přes 700 KB a data ve WAD souboru (&lt;strong&gt;W&lt;/strong&gt;here’s &lt;strong&gt;A&lt;/strong&gt;ll the &lt;strong&gt;D&lt;/strong&gt;ata?) něco málo přes 11 MB.
Toto rozdělení usnadnilo hráčům pozdější vlastní úpravy.
Stejně tak umožnilo naportovat engine na současné architektury, viz &lt;a href=&quot;https://zdoom.org/downloads&quot;&gt;GZDoom&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Jak jsem již zmiňoval, Romero Doomem dodnes žije.
K 25. a 30. výročí vydal &lt;a href=&quot;https://romero.com/sigil&quot;&gt;Sigil I a Sigil II&lt;/a&gt;.
Chtěl, aby úrovně působily, jako by patřily k původní hře, jako by to byla skutečná pátá epizoda.
Osobně mi přijdou obtížnější než tehdejší úrovně.&lt;/p&gt;

&lt;p&gt;Dodnes se &lt;a href=&quot;https://canitrundoom.org&quot;&gt;hračičkové trumfují, na čem Dooma rozeběhnou&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Doom znamenal naše mládí.
Ve srovnání s tříáčkovými hrami za nimi stálo několik málo, pravda geniálních, lidí, kteří z tehdejšího hardware vyždímali naprosté maximum.
Magie, která za tím stála, je v dnešní Unity/Unreal engine době nepředstavitelná.
A proto je dobré si ji připomenout.&lt;/p&gt;

&lt;p&gt;Měli jsme vlastně štěstí, že jsme zrod takových legend zažili.
Dnes už se nepovažuji za hráče, tak nevím. 
Vznikají podobně přelomové tituly definující nový žánr?&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/software%20development/2023/10/23/pocta-c64.html&quot;&gt;Pocta C64&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 17 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/10/17/IDDQD.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/10/17/IDDQD.html</guid>
        
        <category>hry</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>Kniha Real-World Cryptography</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-09-16/50090498.jpg&quot; /&gt;&lt;/div&gt;
&lt;p&gt;Kniha &lt;a href=&quot;https://www.goodreads.com/book/show/50090498-real-world-cryptography&quot;&gt;Real-World Cryptography&lt;/a&gt; od David Wong je to nejpřístupnější, co si můžete o kryptografii přečíst, alespoň co je mi známo.
Dostatečně jednoduchá, abych ji pochopil.
Dostatečně složitá, abych se k ní musel vrátit.
Dál byste v podstatě nemuseli číst tento příspěvek a mohli si jít knihu rovnou koupit.
Nicméně uvádím, jak jsem ke svému závěru došel.&lt;/p&gt;

&lt;!--more--&gt;
&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;úvod&quot;&gt;Úvod&lt;/h2&gt;

&lt;p&gt;Posledních dvanáct let se motám kolem software, který se více či méně týká počítačové bezpečnosti.
Aby bylo jasno, nejsem kryptolog a nikdy jím nebudu, ale podílel jsem se například na &lt;a href=&quot;/software%20development/2015/12/15/jak-funguje-biometricky-pas.html&quot;&gt;vydávání biometrických pasů&lt;/a&gt;.
Každopádně se snažím v oboru celou dobu vzdělávat.
No a není to snadné.
Obor je to komplexní.
Že jste udělali chybu, se může projevit až později jako obrovský průšvih.
Když věci ladíte, někdy stačí jediný bit jinak a celé je to špatně, ale nevíte proč.&lt;/p&gt;

&lt;h2 id=&quot;co-jsem-zatím-četl&quot;&gt;Co jsem zatím četl&lt;/h2&gt;

&lt;p&gt;Naprostá nutnost je &lt;a href=&quot;https://www.goodreads.com/review/show/712097358&quot;&gt;Kniha kódů a šifer&lt;/a&gt; od Simon Singh (překlad Petr Koubský).
V roce 2022 vyšel dotisk (již 4. české vydání), tak by měla být k mání.
Je to populárně naučné, velmi čtivé.
Pracovně si s tím však nevystačíte.&lt;/p&gt;

&lt;p&gt;Kdysi jsem četl &lt;a href=&quot;https://goodreads.com/book/show/634845.Java_Cryptography__Java_Series_&quot;&gt;Java Cryptography&lt;/a&gt; (Jonathan Knudsen).
Dnes už prehistorie z roku 1998, popisující &lt;em&gt;Java Cryptography Architecture&lt;/em&gt; (JCA) v Java 1.2
Dlouho jsem to neměl v ruce.
API asi ještě bude platit.
Ale úplně chybí knihovna &lt;a href=&quot;https://www.bouncycastle.org/&quot;&gt;Bouncy Castle&lt;/a&gt; a píše se tam ještě o SHA-1.&lt;/p&gt;

&lt;p&gt;Sáhl jsem tedy po &lt;a href=&quot;https://goodreads.com/book/show/42372440.Java_Cryptography_Tools_and_Techniques&quot;&gt;Java Cryptography: Tools and Techniques&lt;/a&gt;.
To je extrém z druhé strany, já bych to pojmenoval &lt;em&gt;Bouncy Castle Recipes&lt;/em&gt;, tedy ukázky kódu, jak používat Bouncy Castle.
Chybí vysvětlení konceptů.
Pro mě těžko přístupné.
Zkrátka moc velký znalostní skok.&lt;/p&gt;

&lt;h2 id=&quot;kurzy&quot;&gt;Kurzy&lt;/h2&gt;

&lt;p&gt;Na Coursera jsem před lety absolvoval kurz &lt;a href=&quot;https://www.coursera.org/course/crypto&quot;&gt;Cryptography I&lt;/a&gt;.
Očekávaná zátěž sedm hodin týdně.
Zvládal jsem jen teorii, praktické úlohy už ne.
Dan Boneh je skvělý lektor, kurz je kvalitní, ale dost zaměřený na formální matematiku, což možná není to, co právě hledáte.&lt;/p&gt;

&lt;h2 id=&quot;real-world-cryptography&quot;&gt;Real-World Cryptography&lt;/h2&gt;

&lt;p&gt;Konečně se dostávám ke knize Real-World Cryptography, kterou považuji za poklad.
Vyšla v nakladatelství Manning, což už je záruka samo o sobě.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Většina zdrojů je poměrně náročná na matematiku a většina vývojářů, kteří se zabývají kryptografií, se nechce zabývat matematikou.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Didakticky mě velmi oslovila.
Staví znalosti od základních kamenů po složitější.
Přijde mi, že vysvětluje principy a vykládá jen tu nejnezbytnější matematiku.
Nezahlcuje, ale nechává prostor k dalšímu samostudiu.&lt;/p&gt;

&lt;p&gt;Věnuje se dokonce kryptoměnám i FIDO2.
Vysvětluje protokol Signal (který používá i WhatsApp).
Popisuje i &lt;em&gt;post-quantum cryptography&lt;/em&gt;, tedy kryptografii odolné vůči útoku za pomoci výpočetního výkonu kvantových počítačů.
Ač kniha vyšla v roce 2021, kdy tyto algoritmy ještě nebyly standardizované, nijak vás nesvede na scestí.&lt;/p&gt;

&lt;p&gt;Dál obsah pitvat nebudu, můžete &lt;a href=&quot;https://www.manning.com/books/real-world-cryptography&quot;&gt;si udělat představu sami&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Chci, abyste si uvědomili, že jste v privilegované pozici.
Kryptografie začala jako obor za zavřenými dveřmi, omezený pouze na členy vlády nebo akademiky udržované v tajnosti, a pomalu se stala tím, čím je dnes: vědou otevřeně studovanou po celém světě.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Doporučuji všem (nejen programátorům), kteří potřebují kryptografii nějak používat (což jsou stejně všichni).
Dostatečně jednoduchá, abych ji pochopil.
Dostatečně složitá, abych se k ní musel vrátit a pak pokračoval ve studiu jinde.&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/software%20development/2015/12/15/jak-funguje-biometricky-pas.html&quot;&gt;Jak funguje biometrický pas&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/software%20development/2014/11/02/on-line-studium-na-coursera.html&quot;&gt;On-line studium na Coursera&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 16 Sep 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/09/16/kniha-real-world-cryptography.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/09/16/kniha-real-world-cryptography.html</guid>
        
        <category>kniha</category>
        
        <category>security</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>Maven Daemon</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-08-23/maven-logo-black-on-white.png&quot; /&gt;&lt;/div&gt;

&lt;p&gt;Abych udržel tempo publikací na blogu, tak každý článek nemůže přinášet zásadní téma.
Zůstaňme tedy při zemi, u něčeho staršího.
Ač jsem někdy &lt;a href=&quot;/software%20development/2015/04/29/konflikt-tranzitivnich-zavislosti.html&quot;&gt;Maven haněl&lt;/a&gt;, tak tentokrát bych se ho rád zastal.
Doporučuji paralelní build a použití &lt;a href=&quot;https://cs.wikipedia.org/wiki/D%C3%A9mon_(software)&quot;&gt;démona&lt;/a&gt;, který (dle mého pozorování) není tak rozšířený, jak by býval mohl být.&lt;/p&gt;

&lt;!--more--&gt;
&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;přehled-buildovacích-nástrojů&quot;&gt;Přehled buildovacích nástrojů&lt;/h2&gt;

&lt;p&gt;Doporučuji k přečtení článek &lt;a href=&quot;https://blog.frankel.ch/final-take-gradle/&quot;&gt;My final take on Gradle (vs. Maven)&lt;/a&gt;.
Nechci papouškovat celý, ale stručné shrnutí.&lt;/p&gt;

&lt;h3 id=&quot;ant&quot;&gt;Ant&lt;/h3&gt;

&lt;p&gt;Ant taky pamatuju, takže můžu potvrdit, že neřešil závislosti a chyběla konzistence mezi projekty.&lt;/p&gt;

&lt;h3 id=&quot;maven&quot;&gt;Maven&lt;/h3&gt;

&lt;p&gt;Maven přináší závislosti a konvence.
Dnes už se jedná o běžný přístup konvence před konfigurací (&lt;em&gt;convention over configuration&lt;/em&gt;, není nutné explicitně konfigurovat, máte implicitní smysluplné nastavení).
Pro specifické úpravy si můžete napsat vlastní plugin, což není zase tak snadné.
Nemá podporu paralelního build a i &lt;a href=&quot;https://cwiki.apache.org/confluence/display/maven/parallel+builds+in+maven+3&quot;&gt;ve verzi 3 stále označen jako experimentální&lt;/a&gt;.
Očekávané zrychlení paralelního buildu je 20 až 50 %.&lt;/p&gt;

&lt;p&gt;Nicolas Fränkel v odkazovaném článku tvrdí, a já s ním souhlasím, že málo flexibility není bug ale žádoucí vlastnost.&lt;/p&gt;

&lt;h3 id=&quot;gradle&quot;&gt;Gradle&lt;/h3&gt;

&lt;p&gt;Gradle využívá Maven závislosti a přidává flexibilitu, které se až vymyká z rukou.
Od začátku myslí na rychlost buildu a systém cachování.
Prsí se, že oproti Mavenu jsou &lt;a href=&quot;https://gradle.org/gradle-and-maven-performance/&quot;&gt;v některých případech až 100 krát rychlejší&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;maven-daemon&quot;&gt;Maven Daemon&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/apache/maven-mvnd&quot;&gt;Maven Daemon&lt;/a&gt; je dlouhodobý proces běžící na pozadí.
Start JVM není úplně zanedbatelná operace.
S démonem tedy ušetříte start JVM při každém buildu a hlavně nepřijdete o JIT (Just-In-Time) optimalizace.
V neposlední řadě dostaneme vylepšený výstup paralelního build na konzoli.&lt;/p&gt;

&lt;h3 id=&quot;vlastní-pozorování&quot;&gt;Vlastní pozorování&lt;/h3&gt;

&lt;p&gt;V současné době mimo jiné přispívám do open source projektu &lt;a href=&quot;https://github.com/wultra/powerauth-server&quot;&gt;PowerAuth&lt;/a&gt;.
Níže naleznete dobu buildu na MacBook Pro s M1 procesorem.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvnd&lt;/code&gt; je příkaz pro build pomocí Maven Daemon.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Příkaz&lt;/th&gt;
      &lt;th&gt;Čas buildu&lt;/th&gt;
      &lt;th&gt;Poznámka&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvn clean package&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;46,6 s&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvn package&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;30,6 s&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvn clean package -T 1C&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;40 s&lt;/td&gt;
      &lt;td&gt;Paralelní běh, 1 thread na dostupný core.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvn package -T 1C&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;28,6&lt;/td&gt;
      &lt;td&gt;Paralelní běh, 1 thread na dostupný core.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvnd clean package&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;37,9 s&lt;/td&gt;
      &lt;td&gt;Démon, paralelně spouští &lt;em&gt;by default&lt;/em&gt;.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvnd package&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;26,4 s&lt;/td&gt;
      &lt;td&gt;Démon, paralelně spouští &lt;em&gt;by default&lt;/em&gt;, &lt;strong&gt;první běh&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mvnd package&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;22,8 s&lt;/td&gt;
      &lt;td&gt;Démon, paralelně spouští &lt;em&gt;by default&lt;/em&gt;, &lt;strong&gt;po zahřátí&lt;/strong&gt;.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;úskalí-paralelního-buildu&quot;&gt;Úskalí paralelního buildu&lt;/h3&gt;

&lt;p&gt;Jak jsme si již řekli, paralelní build v Mavenu stále není plně podporován.
Kromě problémových pluginů můžete narazit i na problémy ve svém kód, který třeba nezvládne paralelní běh integrační testů, takže si budete muset zamést i před svým prahem.&lt;/p&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Ač zrychlení paralelního buildu v Mavenu nedosahuje hodnot, jaké reklamuje Gradle, tak přesto by byla škoda toho nevyužít.
Když už se dáte cestu paralelního buildu v Mavenu, doporučuji využít Maven Daemon.
Při práci ve větších týmech a v situaci, kdy programátoři přechází mezi projekty, dávám přednost předvídatelnosti před rychlostí.&lt;/p&gt;

&lt;h2 id=&quot;související&quot;&gt;Související&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;/software%20development/2015/04/29/konflikt-tranzitivnich-zavislosti.html&quot;&gt;Konflikt tranzitivních závislostí&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 23 Aug 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/08/23/maven-daemon.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/08/23/maven-daemon.html</guid>
        
        <category>Maven</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>Úskalí GHA runneru</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-07-30/275576.png&quot; /&gt;&lt;/div&gt;

&lt;p&gt;Měl jsem takovou tvůrčí krizi.
Můžu to alespoň svádět na dobu LLM.
Má dneska vůbec smysl něco tvořit?
Jenže stroje vám, zatím, odpoví jen na to, co jste se zeptali.
Proto čtu online články i časopisy, které mi rozšiřují obzor, protože mi podsouvají informace, na které bych se býval nezeptal.
Jednak mám puzení něco psát, jednak je blog z velké části deník pro mě samotného, jako si psal &lt;a href=&quot;https://cs.wikipedia.org/wiki/Z_den%C3%ADku_kocoura_Modroo%C4%8Dka&quot;&gt;Kocour Modroočko&lt;/a&gt;, co všechno zažil (kdo neznáte zhudebněnou verzi s Dejdarem, pusťte si, je to poklad pro děti i dospělé).&lt;/p&gt;

&lt;p&gt;Pojďme se rozehřát něčím jednoduchým až banálním.&lt;/p&gt;

&lt;p&gt;Jeden z nejznámějších build nástrojů Jenkins se dříve konfiguroval jen klikáním v GUI.
Bylo to nepohodlné, špatně se to verzovalo, zálohovalo a možném code review ani nemluvě.
Naštěstí tu je s námi už nějakou dobu &lt;a href=&quot;https://www.jenkins.io/doc/book/pipeline/jenkinsfile/&quot;&gt;Jenkinsfile&lt;/a&gt;, který leží v repozitáři vedle zdrojového kódu.&lt;/p&gt;

&lt;p&gt;Vedle toho existuje lákavá alternativa &lt;a href=&quot;https://docs.github.com/en/actions/get-started/quickstart&quot;&gt;GitHub Actions&lt;/a&gt; (dále jen GHA).
Představte si, že byste se nemuseli starat o vlastní build server, jaká pohoda.
Do jaké pasti byste se asi tak mohli dostat?&lt;/p&gt;

&lt;!--more--&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;problém-s-gha&quot;&gt;Problém s GHA&lt;/h2&gt;

&lt;p&gt;Jenkins buildy jsme dávno přenesli na GHA.
Jeden z nich pouštěl baterii integračních testů vůči &lt;em&gt;dev&lt;/em&gt; prostředí.
Neříkám, že je to vzor hodný následování, ale v Jenkins to fungovalo a nějakou dobu i v GHA.&lt;/p&gt;

&lt;p&gt;Pak začaly testy padat na &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Connection timed out&lt;/code&gt;.
Nějakou chvíli to ignorujete, prostě síť je nespolehlivá, ale testy musí být přeci zelené.&lt;/p&gt;

&lt;p&gt;Z výše popsaného je patrné, že testy a server běží nezávisle na sobě.
I když je server v Azure a GHA je od Microsoftu, nic nezaručuje, že poběží ve stejném regionu.&lt;/p&gt;

&lt;p&gt;Hypotézu je potřeba ověřit.&lt;/p&gt;

&lt;h2 id=&quot;ověření-hypotézy&quot;&gt;Ověření hypotézy&lt;/h2&gt;

&lt;p&gt;Do konfigurace GHA přidáme&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Log runner IP and region&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;echo &quot;Public IP:&quot;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;curl -s https://ifconfig.me&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;echo -e &quot;\nRegion info (GeoIP):&quot;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;curl -s https://ipinfo.io&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Výsledek&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-log&quot;&gt;Public IP:
135.232.177.160
Region info (GeoIP):
{
  &quot;ip&quot;: &quot;135.232.177.160&quot;,
  &quot;city&quot;: &quot;Chicago&quot;,
  &quot;region&quot;: &quot;Illinois&quot;,
  &quot;country&quot;: &quot;US&quot;,
  &quot;loc&quot;: &quot;41.8500,-87.6500&quot;,
  &quot;org&quot;: &quot;AS8075 Microsoft Corporation&quot;,
  &quot;postal&quot;: &quot;60666&quot;,
  &quot;timezone&quot;: &quot;America/Chicago&quot;,
  &quot;readme&quot;: &quot;https://ipinfo.io/missingauth&quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A sakra, dev server běží ve West Europe.
&lt;a href=&quot;https://github.com/orgs/community/discussions/11727&quot;&gt;Dle této diskuse region u GHA nastavit bohužel nelze&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Nikdy se nedozvím, proč se to rozbilo až po čase. Možná Trump uvalil clo i na TCP spojení, nebo GitHub prostě jen čaroval s regiony runnerů.&lt;/p&gt;

&lt;h2 id=&quot;řešení&quot;&gt;Řešení&lt;/h2&gt;

&lt;p&gt;Jak z toho ven?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Připravit si &lt;a href=&quot;https://docs.github.com/en/actions/concepts/runners/self-hosted-runners&quot;&gt;self-hosted runner&lt;/a&gt;, s tím ale padá ona výhoda, že se nechcete o nic starat.&lt;/li&gt;
  &lt;li&gt;Přesunout server do jiného regionu (což se zase nemusí hodit pro jiné scénáře, kdy tam přistupujete z Evropy).&lt;/li&gt;
  &lt;li&gt;Vytvořit další instanci jen pro testy (v regionu, kde dle logu runner s testy běží).&lt;/li&gt;
  &lt;li&gt;Ideální, zato nejsložitější cesta, vytvořit image, který bude obsahovat jak server, tak testy, což zaručí, že všechno bude na jediném místě.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;I když jste nečetli knihu &lt;a href=&quot;/software%20development/2012/07/24/povestny-clovekomesic.html&quot;&gt;The Mythical Man-Month (Frederick P. Brooks)&lt;/a&gt;, jistě vám bude znám koncept &lt;a href=&quot;https://en.wikipedia.org/wiki/No_Silver_Bullet&quot;&gt;No Silver Bullet&lt;/a&gt;.
Je lákavé, že se nemusíte o nic starat, ale když už se o něco postarat potřebujete, tak je to pak komplikované až nemožné.&lt;/p&gt;
</description>
        <pubDate>Wed, 30 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/07/30/uskali-gha-runneru.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/07/30/uskali-gha-runneru.html</guid>
        
        <category>CI</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>Vietnam informatiky</title>
        <description>&lt;p&gt;Mým oblíbeným článkem, hlavně kvůli analogii z historie, je &lt;a href=&quot;https://blogs.newardassociates.com/blog/2006/the-vietnam-of-computer-science.html#tech&quot;&gt;The Vietnam of Computer Science&lt;/a&gt;, který před již mnoha lety napsal Ted Neward. S jeho laskavým svolením přináším překlad. Dlouho jsem si na něj netroufal, ale nakonec jsem učesal výsledek z DeepL. Překlad uvolňuji pod licencí &lt;a href=&quot;http://creativecommons.org/licenses/by-nc-sa/3.0/cz/&quot;&gt;Creative Commons BY-NC-SA 3.0&lt;/a&gt;, nicméně autorská práva stále náleží Tedu Newardovi.&lt;/p&gt;

&lt;h2 id=&quot;nabízím-analogii-k-objektově-relačnímu-mapování-a-problémům-které-představuje&quot;&gt;Nabízím analogii k objektově-relačnímu mapování a problémům, které představuje&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;26. června 2006&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Na Microsoft TechEd 2004 v San Diegu, jsem se na akci po konferenci účastnil rozhovoru s Harrym Piersonem a Clemensem Vastersem, a jak je typické, když se my tři sejdeme, předmětem našich diskusí byla architektonická témata. Kolem nás se shromáždil dav lidí stejných zájmů. Přišla řeč na technologie objektově-relačního mapování a tehdy jsem poprvé použil větu: „Objektově-relační mapování je Vietnamem informatiky“. V mezidobí jsem obdržel řadu žádostí o upřesnění diskuse, která se za tímto výrokem skrývá, a vzhledem k nedávnému oznámení Microsoftu ohledně „podpory entit“ v ADO.NET 3.0 a přijetí Java Persistence API jako náhrady za EJB Entity Beans i JDO se zdálo, že je čas přesně to udělat.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(2022 Poznámka: Tento článek je již patnáct let starý. Několikrát jsem byl v pokušení historickou část zkrátit - to je jedna z nejčastějších výtek k tomuto dílu -, ale v zájmu toho, aby po světě nekolovalo více jeho kopií, jsem ji zde ponechal. Pokud chcete lekci historie přeskočit, &lt;a href=&quot;#vietnam-a-or-mapování&quot;&gt;zde&lt;/a&gt; je rychlý odkaz na technologické kousky.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Žádný ozbrojený konflikt v dějinách USA nestrašil americkou armádu více než Válka ve Vietnamu, známá jako Vietnam. Tolik odlišných prvků se spojilo, aby vytvořily nejrozhodnější bod obratu v moderních amerických dějinách, že se vzpírá snaze jakéhokoli laika je od sebe oddělit. Přesto je příběh Vietnamu v podstatě prostý: Spojené státy zahájily vojenský projekt s jednoduchými, ale nejasnými a protichůdnými cíli a rychle se zapletly do šlamastyky, která nejenže svrhla dvě vlády (jednu legálně, druhou silou zbraní), ale také hluboce poznamenala americkou vojenskou doktrínu na další čtyři desetiletí (přinejmenším).&lt;/p&gt;

&lt;p&gt;Ačkoli se to může zdát banální, &lt;strong&gt;Objektově-relační mapování je Vietnamem informatiky.&lt;/strong&gt; Představuje šlamastyku, která začíná dobře, postupem času se komplikuje a zanedlouho své účastníky uvězní v závazku, který nemá jasné ohraničení, jasné podmínky vítězství ani jasnou strategii úniku.&lt;/p&gt;

&lt;!--more--&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h2 id=&quot;historie&quot;&gt;Historie&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.pbs.org/battlefieldvietnam/history/index.html&quot;&gt;PBS má dobré shrnutí války&lt;/a&gt;, ale pro ty, kteří se zajímají spíše o informatiku než o politickou/vojenskou historii, je stručná verze následující:&lt;/p&gt;

&lt;p&gt;Jižní Indočína, dnes známá jako Vietnam, Thajsko, Laos a Kambodža, má dlouhou historii bojů o autonomii. Před francouzskou koloniální nadvládou (která začala v polovině 19. století) bojovala Jižní Indočína o regionální nezávislost na Číně. Během druhé světové války oblast dobyli Japonci, aby ji později „osvobodili“ spojenci, což vedlo Francii k obnovení koloniální nadvlády (stejně jako Brity na jejich koloniálních územích jinde v Asii a Indii). Po Druhé světové válce však obyvatelé jižní Indočíny, kteří se zbavili jednoho utlačovatele, rozšířili své protiokupační úsilí na boj proti Francouzům namísto Japonců a v roce 1954 Francouzi kapitulovali a podepsali Ženevské mírové dohody, které Vietnamu formálně poskytly nezávislost. Bohužel globální tlaky toto úsilí poněkud zvrátily a místo trvalé mírové dohody vzniklo dočasné řešení, které rozdělilo zemi na 17. rovnoběžce a vytvořilo dva národy tam, kde dříve žádné takové rozdělení neexistovalo. V roce 1956 se měly konat volby, které měly zemi znovu sjednotit, ale USA se obávaly, že by těmito volbami získala příliš velkou moc Komunistická strana Vietnamu, a místo toho podpořily protikomunistický stát jižně od 17. rovnoběžky a vytvořily kolem něj řadu mnohostranných dohod, například SEATO. Zrodil se nový stát Jižní Vietnam a jeho prvním (pochybně) zvoleným vůdcem se stal Ngo Dinh Diem, přesvědčený antikomunista, který téměř okamžitě prohlásil, že jeho země je pod útokem komunistů. Eisenhowerova administrativa Diemovu vládu nadále podporovala, ale Diemova loajalita u lidu byla od počátku téměř nulová.&lt;/p&gt;

&lt;p&gt;V době nástupu Johna F. Kennedyho z Demokratické strany USA do Bílého domu se situace v Jižním Vietnamu začala vyhrocovat. Kennedy vyslal do Vietnamu tým, který měl prozkoumat tamní poměry a pomoci formulovat strategii v této otázce. V dokumentu, který je dnes známý jako „Bílá kniha z prosince 1961“, byly předloženy argumenty pro zvýšení vojenské, technické a ekonomické pomoci spolu s rozsáhlými americkými „poradci“, kteří měli pomoci stabilizovat Diemovu vládu a zlikvidovat Frontu národního osvobození, kterou USA nazvaly Vietkong. Není však tak všeobecně známo, že řada Kennedyho poradců argumentovala proti tomuto navýšení a označila Vietnam za „slepou uličku“.&lt;/p&gt;

&lt;p&gt;Tváří v tvář dvěma diametrálně odlišným cestám zvolil Kennedy, jak bylo pro jeho administrativu typické, střední cestu: místo masivního angažmá nebo úplného stažení se Kennedy raději rozhodl usilovat o omezené urovnání, vyslání pomoci, ale ne velkého počtu vojáků, což byla cesta, která byla od počátku téměř odsouzena k zániku. Řadou strategických omylů, včetně nuceného přesídlování venkovských vesničanů (tzv. strategický program Hamlet), byla Diemova podpora tak hluboce oslabena, že Kennedy váhavě a nejistě podpořil převrat, během něhož byl Diem zabit. O tři týdny později byl Kennedy rovněž zavražděn, což vyvolalo zmatek i na domácí politické scéně USA. Ironií osudu je, že konflikt, který Kennedy zahájil, bude ve skutečnosti později nejvíce spojován s jeho nástupcem.&lt;/p&gt;

&lt;h3 id=&quot;johnsonova-válka&quot;&gt;Johnsonova válka&lt;/h3&gt;

&lt;p&gt;V době atentátu na Kennedyho působilo ve Vietnamu 16 000 amerických poradců, z nichž většina nebyla zapojena do každodenních bojových operací. Kennedyho viceprezident a jeho nový nástupce Lyndon Baines Johnson (LBJ) však nebyl přesvědčen, že tato cesta vede k úspěchu, a dospěl k názoru, že je třeba jednat agresivněji. Johnson využil pochybného incidentu, při němž vietnamské hlídkové čluny zaútočily na americké torpédoborce&lt;sup&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; v Tonkinském zálivu, a využil proválečných nálad v Kongresu ke schválení rezoluce, která mu dávala pravomoc provést vojenskou akci bez výslovného vyhlášení války. Jednoduše řečeno, Johnson chtěl tuto válku vést „chladnokrevně“: „To znamenalo, že Amerika bude válčit ve Vietnamu s přesností chirurga a s malým dopadem na domácí kulturu. Omezená válka si vyžádala omezenou mobilizaci zdrojů, materiálních i lidských, a způsobila jen malé narušení každodenního života v Americe.“ (&lt;a href=&quot;http://www.pbs.org/battlefieldvietnam/history/index.html&quot;&gt;zdroj&lt;/a&gt;) V podstatě by se jednalo o válku, jejíž dopad by pocítili pouze Vietnamci - americký život a společnost by pokračovaly bez jakéhokoli povšimnutí událostí ve Vietnamu, a Johnson by se tak mohl věnovat své první velké lásce, své „Velké společnosti“, domácímu programu, který měl napravit mnoho neduhů americké společnosti, například chudobu&lt;sup&gt;&lt;a href=&quot;#2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. Historie to samozřejmě ví lépe a - možná krutě - nazývá vietnamský konflikt „Johnsonovou válkou“.&lt;/p&gt;

&lt;p&gt;Na úvod je třeba poznamenat, že Vietnam jako katastrofa je vnímán až v poslední době; Američané byli v průzkumech veřejného mínění ještě v roce 1967 přesvědčeni, že válka je dobrá věc, že je třeba zastavit komunismus a že Vietnam, pokud padne, bude prvním z řady států, které podlehnou komunistickému rozvratu. Tato „teorie domina“ byla běžným refrénem americké politiky druhé poloviny 20. století. Obavy tohoto druhu sužovaly americkou zahraniční politiku od doby, kdy komunisté úspěšně nebo téměř úspěšně rozvrátili několik evropských vlád v druhé polovině 40. let a poté Čínu v 50. letech. (Je třeba poznamenat, že Eisenhower a John Foster Dulles, kteří formulovali tuto teorii, nikdy nezařadili Vietnam do svého kruhu domina, které je třeba zachovat, a ve skutečnosti byl Eisenhower během některých svých setkání s Kennedym při přechodu do Bílého domu vůči Vietnamu překvapivě apatický.)&lt;/p&gt;

&lt;p&gt;V roce 1968 se však situace ve Vietnamu výrazně změnila, protože Severovietnamci a Vietkong zahájili ofenzívu Tet, kampaň, která zmařila veškeré ujišťování americké vlády, že ve válce ve Vietnamu vítězí. Paradoxně, stejně jako po většinu války, ztratily síly NVA/VC značný počet vojáků, mnohem více než jejich američtí protivníci, přesto je ofenzíva Tet historiky všeobecně považována za bod zlomu americké vůle ve válce. Po této události se veřejné mínění obrátilo proti Johnsonovi a ten na dramatické tiskové konferenci oznámil, že nebude usilovat o své znovuzvolení. Dále oznámil, že bude usilovat o vyjednávání s Vietnamci.&lt;/p&gt;

&lt;h3 id=&quot;nixonův-slib&quot;&gt;Nixonův slib&lt;/h3&gt;

&lt;p&gt;Naneštěstí byla americká vyjednávací pozice vážně oslabena právě těmi protesty, které Američany k jednacímu stolu vůbec přivedly; vedení NVA/VC uznalo, že síly NVA/VC, navzdory ohromujícím vojenským ztrátám, které je téměř zlomily (několikrát), mohou jednoduše pokračovat v tom, co dělaly, a vymáhat od Američanů ústupky, aniž by nabídly nějaké na oplátku. Johnsonův nástupce, republikán Richard Nixon, kandidující s programem, který se skládal převážně ze slibu „dostat Ameriku z Vietnamu“, se pokusil o několik taktik, jak vyvinout tlak na síly NVA/VC, aby vyjednávaly, včetně zvýšené přítomnosti vzdušných sil (například vánoční bombardování a operace Menu) a pravidelného narušování nedalekého Laosu a Kambodže, sledování linie zásobování ze Severního Vietnamu k buňkám v Jižním Vietnamu. Nic však nepomohlo a v roce 1973 Nixonova vláda podepsala Pařížskou mírovou dohodu, která ukončila americkou účast v tomto konfliktu. O dva roky později byl jižní Vietnam ovládnut a 30. dubna 1975 se komunistické síly zmocnily Saigonu, hlavního města Vietnamu, což si vynutilo evakuaci amerického velvyslanectví a nejpamátnější obraz války - proudy prchajících lidí, kteří hledali místo ve vrtulníku Huey umístěném na střeše velvyslanectví.&lt;/p&gt;

&lt;h3 id=&quot;konec-války&quot;&gt;Konec války&lt;/h3&gt;

&lt;p&gt;Druhá válka v jižní Indočíně skončila, Amerika zažila svou nejhlubší porážku v historii a Vietnam se stal synonymem pro „šlamastyku“. Její dopad na americkou kulturu byl nezměrný, neboť naučila celou generaci Američanů bát se své vlády a nedůvěřovat jí, naučila americké vůdce obávat se jakéhokoli množství amerických vojenských obětí a přinesla slovní spojení „jasná strategie odchodu“ přímo do amerického politického slovníku. Teprve když Ronald Reagan použil americkou armádu k „osvobození“ malého ostrovního státu Grenada, začali američtí prezidenti považovat americkou vojenskou intervenci za možný nástroj diplomacie, a i tehdy jen s velkým citem pro domácí obavy, jak zjistil Bill Clinton během svých mírových misí v Somálsku a Kosovu. Také z vyčíslitelného hlediska dopady Vietnamu zjevně nedosáhly Johnsonova cíle „chladnokrevné války“. Konečný součet: Ve válce sloužily 3 miliony Američanů, 150 000 jich bylo vážně zraněno, 58 000 mrtvých a více než 1 000 nezvěstných, nemluvě o téměř milionu obětí z řad NVA/Vietkongu, 250 000 jihovietnamských obětí a statisících - ne-li milionech, jak tvrdí někteří historici - civilních obětí.&lt;/p&gt;

&lt;h3 id=&quot;poučení-z-vietnamu&quot;&gt;Poučení z Vietnamu&lt;/h3&gt;

&lt;p&gt;Vietnam představuje pro studenty vojenských a politických dějin zajímavý problém - co přesně se pokazilo, kdy a kde? Je zřejmé, že neochota americké vlády přiznat svá selhání během války z ní činí snadného obětního beránka, ale žádná vláda v dějinách moderní společnosti nikdy nebyla vůči svému obyvatelstvu zcela upřímná, pokud jde o její válečné štěstí; jedním z takových příkladů je (ale nejen) pečlivá cenzura činnosti téže americké vlády během druhé světové války o padesát let dříve, známé v americké historii jako „poslední ‚dobrá‘ válka“. Je také lákavé poukázat na absenci vojenského cíle jako na zásadní selhání Vietnamu, ale jiné nevojenské cíle byly úspěšně realizovány vládami USA i jiných zemí, aniž by došlo k takovému kolosálnímu selhání, které provází vietnamský příběh. Navíc je důležité poznamenat, že USA měly ve skutečnosti jasný cíl v tom, co chtěly z konfliktu v jižní Indočíně vytěžit: zastavit pád jihovietnamské vlády, a pokud se tak nestane, zastavit „šíření“ komunismu. Byla to neochota americké vlády nasadit armádu naplno, jak vždy tvrdil generál William Westmoreland? Jistěže neúspěch ve Vietnamu nebyl vojenský; počty obětí jasně ukazují, že USA podle jakýchkoli jiných měřítek jasně vítězily.&lt;/p&gt;

&lt;p&gt;Jaké byly tedy hlavní neúspěchy ve Vietnamu? A co je důležitější, co to všechno má společného s O/R mapováním?&lt;/p&gt;

&lt;h2 id=&quot;vietnam-a-or-mapování&quot;&gt;Vietnam a O/R mapování&lt;/h2&gt;

&lt;p&gt;V případě Vietnamu se politický a vojenský aparát Spojených států potýkal se smrtelnou formou zákona snižujícího se mezního produktu. V případě automatizovaného objektově-relačního mapování jde o stejnou obavu - že počáteční úspěchy přinesou závazek používat O/R na místech, kde se úspěch stává nepolapitelnějším a časem není vůbec úspěšný kvůli časové a energetické režii potřebné k jeho podpoře ve všech možných případech použití. V podstatě největším poučením z Vietnamu - pro jakoukoli politickou či jinou skupinu - je vědět, kdy „sbalit fidlátka a zmizet“. Příliš často, jako tomu bylo ve Vietnamu, je snadné ospravedlnit další investice do určitého postupu naznačováním, že opuštění tohoto postupu nějakým způsobem znehodnocuje veškerou práci - nebo v případě Vietnamu životy amerických vojáků -, které již byly zaplaceny. Fráze jako „Došli jsme tak daleko, jistě to dotáhneme do konce“ a „Vycouvat teď znamená zahodit vše, co jsme doposud obětovali“ se stávají běžnými. Přinejmenším v pozdějších, hluboce rozhořčených letech druhé poloviny Vietnamské války přišly na přetřes otázky vlastenectví: pokud jste válku nepodporovali, byli jste zjevně zrádce, komunista, zjevně „neameričan“, neuctivý ke všem americkým veteránům jakékoli války vedené na jakémkoli území, ať už z jakéhokoli důvodu, a pravděpodobně jste kopali do svého psa. (Protestujícím nepomohlo ani to, že z války obviňovali vojáky a činili je odpovědnými - někdy i osobně - za rozhodnutí vojenských a politických vůdců, z nichž většinu vojáci ani protestující nikdy nepotkali).&lt;/p&gt;

&lt;p&gt;Při vědomí toho, že všechny analogie nakonec selžou a že téma Vietnamu je hlubší, než může tato esej zkoumat, lze se zde přesto poučit ze zcela jiné oblasti. Jedním z klíčových poučení z Vietnamu bylo nebezpečí toho, čemu se hovorově říká „šikmá plocha“: že určitý postup může přinést určitý počáteční úspěch, avšak další investice do tohoto postupu přináší stále méně úměrné výsledky a stále nebezpečnější překážky, jejichž jediným řešením se zdá být větší a větší nasazení zdrojů a/nebo opatření. Někteří to nazývají „lékovou pastí“, podle způsobu, jakým mohou léky (legální nebo nelegální drogy) po delším užívání vykazovat snížený účinek a vyžadovat zvýšené dávkování, aby přinesly stejné výsledky. Jiní tomu říkají „problém poslední míle“: s blížícím se koncem problému je z hlediska nákladů (peněžních i abstraktních) stále obtížnější najít stoprocentní řešení. Všichni v podstatě hovoří o tomtéž - o obtížnosti nalezení odpovědi, která by našemu hrdinovi umožnila „dokončit“ daný problém úplně a uspokojivě.&lt;/p&gt;

&lt;p&gt;Analýzu objektově-relačního mapování - a jeho vztahu k druhé válce v Jižní Indočíně - začneme především zkoumáním důvodů pro jeho vznik. Co vede vývojáře k tomu, že nepoužívají tradiční relační nástroje pro přístup k relační databázi a místo toho dávají přednost nástrojům, jako je ORM?&lt;/p&gt;

&lt;h3 id=&quot;nesoulad-objektově-relačních-impedancí&quot;&gt;Nesoulad objektově-relačních impedancí&lt;/h3&gt;

&lt;p&gt;Říci, že objekty a relační datové sady jsou nějakým způsobem konstruovány odlišně, obvykle nepřekvapí žádného vývojáře, který někdy používal obojí; s výjimkou extrémně zjednodušených situací je poměrně zřejmé, že způsob, jakým je navrženo relační datové úložiště, se jemně - a přesto hluboce - liší od způsobu, jakým je navržen objektový systém.&lt;/p&gt;

&lt;p&gt;Objektové systémy jsou obvykle charakterizovány čtyřmi základními komponentami: &lt;em&gt;identita&lt;/em&gt;, &lt;em&gt;stav&lt;/em&gt;, &lt;em&gt;chování&lt;/em&gt; a &lt;em&gt;zapouzdření&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Stav&lt;/em&gt; je celkem srozumitelný pojem, který se nejvíce blíží pojmu „data“.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Identita&lt;/em&gt; je ve většině objektově orientovaných jazyků implicitním pojmem v tom smyslu, že daný objekt má jedinečnou identitu, která je odlišná od jeho stavu (hodnoty jeho vnitřních proměnných) - dva objekty se stejným stavem jsou stále samostatné a odlišné objekty, přestože jsou bitově zrcadlovými obrazy jeden druhého. Jedná se o diskusi „identita vs. ekvivalence“, která se objevuje v jazycích jako C++, C# nebo Java, kde vývojáři musí rozlišovat mezi &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a == b&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a.equals(b)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Chování &lt;em&gt;objektu&lt;/em&gt; je poměrně snadno viditelné, jedná se o soubor operací, které mohou klienti vyvolat, aby nějakým způsobem manipulovali s objekty, zkoumali je nebo s nimi interagovali. (Tím se objekty liší od pasivních datových struktur v procedurálních jazycích, jako je C.)&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Zapouzdření&lt;/em&gt; je klíčovým detailem, který zabraňuje vnějším stranám manipulovat s vnitřními detaily objektu, a poskytuje tak klientům evoluční schopnosti rozhraní objektu.&lt;sup&gt;&lt;a href=&quot;#3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Z toho můžeme odvodit další zajímavé koncepty, jako je &lt;em&gt;typ&lt;/em&gt;, formální deklarace stavu a chování objektu, &lt;em&gt;asociace&lt;/em&gt;, která umožňuje, aby se typy na sebe navzájem odkazovaly prostřednictvím odlehčeného odkazu namísto úplného vlastnictví podle hodnoty (někdy se nazývá kompozice), &lt;em&gt;dědičnost&lt;/em&gt;, schopnost propojit jeden typ s jiným tak, že propojený typ zahrnuje veškerý stav a chování propojeného typu jako součást svého vlastního, a &lt;em&gt;polymorfismus&lt;/em&gt;, schopnost nahradit objekt tam, kde se očekává jiný typ.&lt;/p&gt;

&lt;p&gt;Relační systémy popisují formu ukládání a vyhledávání znalostí založenou na predikátové logice a pravdivostních výrocích. V podstatě každý řádek v tabulce je prohlášení o skutečnosti ve světě a jazyk SQL umožňuje operátově-efektivní vyhledávání dat těchto skutečností pomocí predikátové logiky k vytváření závěrů z těchto skutečností. [Date04] a [Fussell] definují relační model jako charakterizovaný vztahem, atributem, tuplem, hodnotou vztahu a proměnnou vztahu. Relace je ve své podstatě pravdivostní predikát o světě, výkaz faktů (atributů), které predikátu dodávají význam. Můžeme například definovat relaci „OSOBA“ jako &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{SSN, Jméno, Město}&lt;/code&gt;, která říká, že „existuje OSOBA s číslem sociálního pojištění SSN, která žije ve městě a jmenuje se Jméno“. Všimněte si, že v relaci je pořadí atributů zcela nespecifikované. &lt;em&gt;Tuple&lt;/em&gt; je pravdivostní výrok v kontextu relace, množina hodnot atributů, které odpovídají požadované množině atributů v relaci, například &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{PERSON SSN=&apos;123-45-6789&apos; Name=&apos;Catherine Kennedy&apos; City=&apos;Seattle&apos;}&lt;/code&gt;. Všimněte si, že dva tuply jsou považovány za identické, pokud jsou identické i hodnoty jejich relací a atributů. (To je opět na rozdíl od objektového systému, ve kterém jsou dva objekty identické pouze tehdy, pokud mají stejný jedinečný identifikátor - obvykle paměťovou adresu.)&lt;/p&gt;

&lt;p&gt;A &lt;em&gt;hodnota relace&lt;/em&gt; je tedy kombinací relace a množiny tuplů, které této relaci odpovídají, a proměnná relace je stejně jako většina proměnných zástupcem dané relace, ale může v průběhu času měnit hodnotu. Proměnná relace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lidé&lt;/code&gt; tak může být zapsána jako držitel relace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{Lidé}&lt;/code&gt;, a skládat se z hodnoty relace&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;{ {PERSON SSN=&apos;123-45-6789&quot; Jméno=&quot;Catherine Kennedy&apos; Město=&quot;Seattle&quot;},
  {PERSON SSN=&apos;321-54-9876&apos; Jméno=&apos;Charlotte Neward&apos; City=&apos;Redmond&apos;},
  {PERSON SSN=&apos;213-45-6978&apos; Jméno=&apos;Cathi Gero&apos; City=&apos;Redmond&apos;}. }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tyto pojmy se běžně označují jako tabulky (proměnná vztahu), řádky (tuply), sloupce (atributy) a kolekce proměnných vztahu jako databáze. Tyto základní typy prvků lze vzájemně kombinovat pomocí sady operátorů (podrobně popsaných v kapitole 7 v [Date04]): restrict, project, product, join, divide, union, intersection a difference, a ty tvoří základ formátu a přístupu k SQL, všeobecně uznávanému jazyku pro interakci s relačním systémem z operátorských konzolí nebo programovacích jazyků. Použití těchto operátorů umožňuje vytvářet odvozené hodnoty relací, relace, které jsou vypočteny z jiných hodnot relací v databázi - například můžeme vytvořit hodnotu relace, která demonstruje počet lidí žijících v jednotlivých městech využitím operátorů project a restrict napříč výše definovanou proměnnou relace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Lidé&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Již nyní je poměrně jasně vidět, že existují výrazné rozdíly mezi tím, jak relační a objektový svět nahlíží na „správný“ návrh systému, a postupem času se ukáží další. Je však důležité poznamenat, že dokud budou programátoři pro přístup k relačním datovým skladům preferovat objektově orientované programovací jazyky, bude vždy docházet k určitému druhu objektově-relačního mapování - oba modely jsou prostě příliš odlišné na to, aby je bylo možné tiše překlenout. (Pravděpodobně totéž platí pro objektově orientované a procedurální programování, ale to je jiný argument na jindy.)&lt;/p&gt;

&lt;p&gt;ORM může probíhat v různých formách, z nichž nejjednodušší je rozpoznat automatizovaný nástroj pro ORM, například TopLink, Hibernate / NHibernate nebo Gentle.NET. Další formou mapování je ruční mapování, při kterém programátoři používají relačně orientované nástroje, jako je JDBC nebo ADO.NET, pro přístup k relačním datům a jejich „ruční“ extrakci do podoby příjemnější pro objektově orientované vývojáře. Třetí možností je jednoduše přijmout tvar relačních dat jako „ten“ model, z něhož se vychází, a objekty kolem něj tomuto přístupu podřídit; tento přístup je v lexikonu vzorů znám také jako Table Data Gateway [PEAA, 144] nebo Row Data Gateway [PEAA 152]; mnoho vrstev pro přístup k datům v Javě i .NET tento přístup využívá a kombinuje ho s generováním kódu, aby se zjednodušil vývoj této vrstvy. Někdy kolem relačního/tabulkového modelu postavíme objekty, kolem nich umístíme nějaké další chování a nazveme je Active Record [PEAA, 160].&lt;/p&gt;

&lt;p&gt;Po pravdě řečeno, tento základní přístup - zotročení jednoho modelu podmínkami a přístupem druhého - byl tradiční odpovědí na nesoulad impedancí, která efektivně „řeší“ problém ignorováním jeho jedné poloviny. Bohužel, většina vývojových snah, podobně jako Kennedyho administrativa, není ochotna dotáhnout to do logického konce s plošným upřednostněním jednoho přístupu před druhým. Například zatímco většina vývojových týmů by ráda přijala přístup pouze „objektový“, na úrovni úložiště to předpokládá použití objektově orientovaného systému správy databází (OODBMS), což je téma, které často nemá žádnou odezvu ve vyšším managementu nebo v týmu správy podnikových dat. Opačný přístup - přístup „pouze relační“ - je vzhledem k tehdejším technologiím v době vzniku tohoto textu&lt;sup&gt;&lt;a href=&quot;#4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; téměř nesmyslné zvažovat.&lt;/p&gt;

&lt;p&gt;Vzhledem k tomu, že tedy není možné „uvolnit objekty na maximum“, jak by to nazval generál Westmoreland, zbývá nám nějaký hybridní přístup mapování objektů na relační, nejlépe takový, který je co nejvíce automatizovaný, aby se vývojáři mohli soustředit na svůj doménový model, a ne na detaily mapování objektů na tabulky. A tady bohužel začíná potenciální šlamastyka.&lt;/p&gt;

&lt;h3 id=&quot;problém-mapování-objektů-na-tabulky&quot;&gt;Problém mapování objektů na tabulky&lt;/h3&gt;

&lt;p&gt;Jedním z prvních a nejsnáze rozpoznatelných problémů při používání objektů jako front-end k relačnímu datovému skladu je problém, jak mapovat třídy na tabulky. Na první pohled se zdá, že jde o poměrně jednoduché cvičení - tabulky se mapují na typy, sloupce na instanční proměnné. Dokonce se zdá, že typy proměnných přímo odpovídají relačním typům sloupců, přinejmenším v poměrně izomorfní míře: VARCHAR na String, INTEGER na int a tak dále. Je tedy logické, že pro každou třídu definovanou v systému je definována odpovídající tabulka - pravděpodobně se stejným nebo příbuzným názvem -, která ji bude doprovázet. Nebo třeba, pokud se objektový kód zapisuje do již existujícího schématu, pak se třída mapuje na tabulku.&lt;/p&gt;

&lt;p&gt;Je však přirozené, že s postupem času se dobře vyškolený objektově orientovaný vývojář bude snažit využít dědičnost v objektovém systému a hledat způsoby, jak totéž provést v relačním modelu. Relační model bohužel nepodporuje žádný druh polymorfismu ani vztah typu IS-A, a tak se vývojáři nakonec ocitnou v situaci, kdy přijmou jednu ze tří možných variant mapování dědičnosti do relačního světa: table-per-class, table-per-concrete-class nebo table-per-class-family. Každá z nich s sebou nese potenciálně významné nevýhody.&lt;/p&gt;

&lt;p&gt;Přístup table-per-class je asi nejsnáze pochopitelný, protože se snaží minimalizovat „vzdálenost“ mezi objektovým a relačním modelem; každá třída v hierarchii dědičnosti dostane svou vlastní relační tabulku a objekty odvozených typů jsou sešity z relačních JOINů napříč různými tabulkami založenými na dědičnosti. Pokud má tedy například objektový model základní třídu OSOBA, od ní odvozenou třídu STUDENT a od ní odvozenou třídu ABSOLVENT, pak budou k uložení tohoto modelu zapotřebí tři tabulky: OSOBA, STUDENT a ABSOLVENT, z nichž každá bude obsahovat proměnné odpovídající stejnojmenné třídě. Vztah těchto tabulek k sobě však vyžaduje, aby každá z nich měla nezávislý primární klíč (takový, jehož hodnota není ve skutečnosti uložena v entitě objektu), aby každá odvozená třída mohla mít vztah cizího klíče k tabulce své nadtřídy. Důvod je jasný: objekt Absolvent je na základě svého vztahu IS-A ke třídám Student a Person kolekcí všech tří sad stavů a rozdíl mezi třídami je v okamžiku vytvoření objektu tohoto typu do značné míry odstraněn - například v Javě i .NET je samotný objekt kusem paměti, který obsahuje instanční proměnné definovaná ve všech jeho třídách a nadtřídách spolu s pointrem na tabulku metod definovaných stejnou hierarchií. To znamená, že při dotazování na konkrétní instanci na relační úrovni je třeba provést nejméně tři JOINy, aby se do pracovní paměti objektového programu dostal veškerý stav objektu.&lt;/p&gt;

&lt;p&gt;Vlastně je to ještě horší - pokud hierarchie objektů dále roste, řekněme tak, že zahrnuje třídy Professor, Staff, Undergrad (dědí od třídy Student) a celou hierarchii AdjunctEmployees (dědí od třídy Staff), a program chce najít všechny Persons, jejichž příjmení je Smith, pak je třeba provést JOINy pro každou odvozenou třídu v systému, protože sémantika „najít všechny osoby“ znamená, že dotaz musí vyhledat data v tabulce PERSON, ale pak provést nákladnou sadu spojení JOIN, aby získal zbytek dat z celého zbytku databáze, přičemž pro získání zbytku dat je třeba vytáhnout tabulku PROFESSOR, nemluvě o tabulkách UNDERGRAD, ADJUCTEMPLOYEE, STAFF a dalších. Vzhledem k tomu, že JOINy patří mezi nejdražší výrazy v dotazech RDBMS, je zřejmé, že se do toho nebudete brát na lehkou váhu.&lt;/p&gt;

&lt;p&gt;V důsledku toho vývojáři obvykle volí jeden ze dvou dalších přístupů, výhledově složitějších, ale efektivnějších při práci s relačním úložištěm: buď vytvoří tabulku pro každou konkrétní (nejvíce odvozenou) třídu a raději přijmou denormalizaci a její náklady, nebo vytvoří jedinou tabulku pro celou hierarchii, přičemž často v obou případech vytvoří diskriminační sloupec, který označuje, do které třídy patří každý řádek v tabulce. (Možné jsou i různé hybridy těchto schémat, ale obvykle nevytvářejí výsledky, které by se výrazně lišily od těchto dvou). Bohužel náklady na denormalizaci jsou u velkého objemu dat často značné a/nebo tabulka (tabulky) bude obsahovat značné množství prázdných sloupců, které budou potřebovat omezení NULLability na všechny sloupce, což eliminuje výkonná omezení integrity, která nabízí RDBMS.&lt;/p&gt;

&lt;p&gt;Mapováním dědičnosti to nekončí; asociace mezi objekty, typické asociace s kardinalitou 1:n nebo m:n, tak běžně používané v SQL a/nebo UML, se řeší zcela jinak: V objektových systémech je asociace jednosměrná, od asociátora k asociovanému objektu (což znamená, že asociované objekty netuší, že jsou ve skutečnosti asociovány, pokud není vytvořena explicitní obousměrná asociace), zatímco v relačních systémech je asociace ve skutečnosti obrácená, od asociovaného objektu k asociátorovi (prostřednictvím sloupců cizích klíčů). To se ukazuje jako překvapivě důležité, protože to znamená, že pro asociace m:n musí být použita třetí tabulka pro uložení skutečného vztahu mezi asociátorem a asociovaným a dokonce i pro jednodušší vztahy 1:n nemá asociátor žádnou vlastní znalost vztahů, ke kterým se asociuje - zjištění těchto údajů vyžaduje v určitém okamžiku JOIN proti některé nebo všem asociovaným tabulkám. (Kdy tato data skutečně získat, je předmětem diskuse - viz níže Paradox načítání).&lt;/p&gt;

&lt;h3 id=&quot;konflikt-mezi-schématem-a-vlastnictvím&quot;&gt;Konflikt mezi schématem a vlastnictvím&lt;/h3&gt;

&lt;p&gt;Diskuse o schématech mapování dědičnosti na tabulky a asociací také odhaluje základní chybu: V jádru mnoho nástrojů pro objektově-relační mapování předpokládá, že schéma je něco, co lze definovat podle schémat, která pomáhají optimalizovat dotazy ORM vůči relačním datům. To však popírá základní problém, že samotné databázové schéma často není pod přímou kontrolou vývojářů, ale je vlastněno jinou skupinou ve firmě, typicky skupinou správy databáze (DBA). Komu náleží odpovědnost za návrh databáze - a rozhodování o tom, kdy jsou změny schématu přípustné?&lt;/p&gt;

&lt;p&gt;V mnoha případech začínají vývojáři nový projekt na „zelené louce“, s prázdnou relační databází, jejíž schéma mohou definovat podle svého uvážení. Brzy po dokončení projektu (někdy i dříve, kvůli politickým problémům a/nebo „válce o území“) se však ukáže, že vlastnictví schématu vývojáři je přinejlepším dočasné - různá oddělení se začnou dožadovat reportů k databázi, DBA se zodpovídají za výkonnost databáze, což jim dává důvod volat po „refaktorování“ a denormalizaci dat, a ostatní vývojové týmy se mohou začít zajímat o to, jak by mohly využít data v ní uložená. Zanedlouho musí být schéma „zmrazeno“, čímž se potenciálně vytvoří překážka pro refaktorování objektového modelu. Kromě toho budou tyto další týmy očekávat relační model definovaný v relačních termínech, nikoliv takový, který podporuje zcela ortogonální formu perzistence - například sloupec „diskriminátor“ z problému mapování dědičnosti na tabulky bude pro relační generátory sestav, jako je Crystal Reports, představovat obtíže a pravděpodobně bude zcela nepoužitelný. Pokud nejsou vývojáři ochotni psát všechny sestavy (a jejich uživatelská rozhraní, a jejich tiskový kód, a jejich ad-hoc možnosti…) ručně, bude to obvykle nepřijatelný stav.&lt;/p&gt;

&lt;p&gt;(Abychom byli spravedliví, nejedná se ani tak o technický problém, jako spíše o problém politický, ale stále představuje vážný problém bez ohledu na jeho zdroj - nebo řešení. A jako takový stále představuje překážku pro řešení objektově-relačního mapování.”&lt;/p&gt;

&lt;h3 id=&quot;problém-dvojího-schématu&quot;&gt;Problém dvojího schématu&lt;/h3&gt;

&lt;p&gt;S otázkou vlastnictví schématu souvisí i to, že v řešení ORM jsou metadata k systému uložena zásadně na dvou různých místech: jednou ve schématu databáze a jednou v objektovém modelu (chcete-li, dalším schématu vyjádřeném v jazyce Java nebo C# namísto DDL). Aktualizace nebo refaktorování jednoho z nich bude pravděpodobně vyžadovat podobné úpravy druhého. Refaktorování kódu tak, aby odpovídal změnám schématu databáze, je obecně považována za jednodušší - refaktorování databáze často vyžaduje určitý druh migrace a/nebo úpravy dat již v databázi, kdežto u kódu takový požadavek není. (Objekty, alespoň v této diskusi, jsou efemérní instance v paměti, které zmizí, jakmile proces, který je drží, skončí. Pokud jsou objekty uloženy v nějakém druhu objektové formy, která může přetrvat napříč prováděním procesu - například serializované instance objektů uložené na disku - pak se refaktorování objektů stává stejně problematickou.)&lt;/p&gt;

&lt;p&gt;Důležitější je, že ačkoli není neobvyklé, aby byl kód nasazen specificky pro jednu aplikaci, často jsou instance databáze využívány více než jednou aplikací a pro firmu je často nepřijatelné vyvolat celofiremní refaktorování kódu jen proto, že refaktorování v jedné aplikaci vyžaduje podobné refaktorování řízené databází. V důsledku toho bude s postupným růstem systému narůstat tlak na vývojáře, aby „odpoutali“ objektový model od databázového schématu tak, aby změny schématu nevyžadovaly podobné refaktorování objektového modelu a naopak. V některých případech, kdy ORM takové odpojení neumožňuje, může být nutné nasadit zcela soukromou instanci databáze s přesným schématem, na kterém bylo postaveno řešení založené na ORM, čímž vznikne další datové silo v prostředí IT, kde sílí tlak na redukci takových sil.&lt;/p&gt;

&lt;h3 id=&quot;problémy-s-identitou-entit&quot;&gt;Problémy s identitou entit&lt;/h3&gt;

&lt;p&gt;Jako by tyto problémy nestačily, narážíme na další problém, a to &lt;em&gt;identitu&lt;/em&gt; objektů a vztahů. Jak bylo uvedeno výše, objektové systémy používají implicitní smysl pro identitu, obvykle založený na umístění objektu v paměti (všudypřítomný ukazatel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this&lt;/code&gt;); alternativně se někdy označuje jako OID (Object IDentifier), obvykle v systémech, které přímo nevystavují umístění v paměti, jako je například objektová databáze (kde je ukazatel v paměti jako identifikátor mimo proces databáze celkem k ničemu). V relačním modelu je však identita implicitně obsažena v samotném stavu - dva řádky s naprosto stejným stavem jsou obvykle považovány za poškození relačních dat, protože dvakrát tvrzená stejná skutečnost je nadbytečná a kontraproduktivní. Abychom byli spravedliví, měli bychom zde být trochu explicitnější; relační systém může ve skutečnosti povolit duplicitní tuply (jak je popsáno výše), ale to je často explicitně zakázáno explicitními relačními omezeními, jako jsou omezení PRIMARY KEY. V situacích, kdy jsou duplicitní hodnoty povoleny, neexistuje pro relační systém žádný způsob, jak určit, který ze dvou duplicitních řádků je načítán - neexistuje žádný implicitní smysl pro identitu relace kromě toho, který nabízejí její atributy. Totéž neplatí pro objektové systémy, kde dva objekty, které obsahují přesně identické bitové vzory na dvou různých místech paměti, jsou ve skutečnosti samostatné objekty. (To je důvod, proč se v Javě nebo C# rozlišuje mezi &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;==&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.equals()&lt;/code&gt;.) Důsledek je zde jednoduchý: pokud se mají oba systémy shodnout na smyslu identity, musí relační systém nabídnout nějaký jedinečný pojem identity (obvykle automaticky se zvyšující celočíselný sloupec), který bude odpovídat pojmu identity objektu.&lt;/p&gt;

&lt;p&gt;To vyvolává vážné obavy, pokud jde o automatizované systémy OR, protože smysl identity je zcela odlišný - pokud dvě samostatné uživatelské relace interagují se stejným vztahem v úložišti, nastupují systémy souběžnosti relačního databázového systému a zajišťují určitou formu souběžného přístupu, obvykle prostřednictvím transakční metafory (ACID). Pokud systém O/R načte relaci z úložiště (v podstatě vytvoří „pohled“ na data), máme nyní druhý zdroj identity dat, jeden v databázi (chráněný výše zmíněným transakčním schématem) a jeden v objektové reprezentaci těchto dat v paměti, která nemá žádnou konzistentní transakční podporu kromě té, která je zabudována v jazyce (například koncept monitorů v jazycích Java a .NET) nebo knihovny (například System.Transactions v .NET 2.0), které mohou být - a bohužel často jsou - vývojáři snadno ignorovány. Správa izolace a souběžnosti (&lt;em&gt;concurrency&lt;/em&gt;) není snadno řešitelný problém a bohužel jazyky a platformy běžně dostupné vývojářům zatím nejsou tak konzistentní a flexibilní jako metafora databázových transakcí.&lt;/p&gt;

&lt;p&gt;Tento problém dále komplikuje skutečnost, že mnoho systémů O/R zavádí do vrstvy O/R významnou podporu cachování (obvykle ve snaze zvýšit výkon a vyhnout se obcházení databáze), což zase přináší určité problémy, zejména pokud systém cachování není cache pro zápis, kde dochází ke skutečnému zápisu databáze; a co to vypovídá o transakční integritě, pokud se aplikační kód domnívá, že k zápisu došlo, ačkoli se tak ve skutečnosti nestalo? Tento problém se zase jen prohlubuje, pokud systém O/R běží ve více procesech před databázovým strojem, což se běžně vyskytuje ve scénářích clusterových aplikačních serverů. Nyní je identita dat rozložena do &lt;em&gt;n+1&lt;/em&gt; míst, přičemž &lt;em&gt;n&lt;/em&gt; je počet uzlů aplikačního serveru a &lt;em&gt;1&lt;/em&gt; je samotná databáze. Každý uzel musí nějakým způsobem signalizovat svůj záměr provést aktualizaci ostatním uzlům, aby získal nějakou konstrukci souběhu, která zabrání současnému přístupu (jinou instancí stejné relace nebo instancí jiné relace přistupující ke stejným datům), což zabere čas a zabíjí výkon. Dokonce i v případě cache určené pouze pro čtení musí být aktualizace datového úložiště nějakým způsobem signalizovány cache běžící v uzlech aplikačního serveru, což vyžaduje komunikaci mezi serverem a klientem pocházející z databáze; podpora tohoto postupu není v současných moderních relačních databázích dobře pochopena ani zdokumentována.&lt;/p&gt;

&lt;h2 id=&quot;obavy-z-mechanismu-získávání-dat&quot;&gt;Obavy z mechanismu získávání dat&lt;/h2&gt;

&lt;p&gt;Jakmile je entita uložena v databázi, jak ji přesně získáme? Čistě objektově orientovaný přístup by pro vyhledávání využíval objektové přístupy, v ideálním případě pomocí syntaxe ve stylu konstruktorů identifikujících požadované objekty, ale bohužel syntaxe konstruktorů není dostatečně obecná, aby umožnila něco tak flexibilního; zejména jí chybí možnost inicializovat kolekci objektů a dotazy často potřebují vrátit kolekci, nikoli pouze jednu entitu. (Vícenásobné cesty do databáze za účelem načtení jednotlivých entit jsou obecně považovány za příliš neekonomické, a to jak z hlediska latence, tak šířky pásma, než aby se daly považovat za věrohodnou alternativu - více viz níže Paradox času načítání.) Výsledkem je obvykle jeden z přístupů Query-By-Example (QBE), Query-By-API (QBA) nebo Query-By-Language (QBL).&lt;/p&gt;

&lt;p&gt;Přístup QBE spočívá v tom, že vyplníte šablonu objektu typu objektu, který hledáte, přičemž instanční proměnné jsou nastaveny na konkrétní hodnotu, která se použije jako součást procesu filtrace dotazu. Pokud se tedy například dotazujete na objekt/tabulku Osoba na osoby s příjmením Smith, nastavíte dotaz takto:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Person p = new Person(); // předpokládá, že všechny instanční proměnné jsou ve výchozím nastavení nulové
p.lastName = &quot;Smith&quot;;
ObjectCollection oc = QueryExecutor.execute(p);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Problém s přístupem QBE je zřejmý: zatímco pro jednoduché dotazy je naprosto dostačující, není zdaleka dostatečně expresivní pro podporu složitějšího stylu dotazů, které často potřebujeme provést - „najdi všechny osoby jménem Smith nebo Cromwell“ a „najdi všechny osoby, které se NEjmenují Smith“ jsou dva příklady. Ačkoli není nemožné vytvořit přístupy QBE, které si s tímto (a složitějšími scénáři) poradí, rozhodně to značně komplikuje rozhraní API. Ještě důležitější je, že to také nutí doménové objekty do nepříjemné pozice - musí podporovat nulovatelné instanční proměnné, což může být porušením doménových pravidel, která by se jinak objekt snažil podporovat - Osoba beze jména není v mnoha scénářích příliš užitečný objekt, ale právě to bude přístup QBE vyžadovat od doménových objektů v něm uložených. (Praktici QBE budou často tvrdit, že není nerozumné, aby implementace objektu toto zohledňovala, ale opět to není ani snadné, ani časté.)&lt;/p&gt;

&lt;p&gt;V důsledku toho je obvykle druhým krokem, aby objektový systém podporoval přístup „Query-By-API“, v němž jsou dotazy konstruovány pomocí dotazovacích objektů, obvykle něco ve tvaru:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Query q = new Query();
q.From(&quot;PERSON&quot;).Where(new EqualsCriteria(&quot;PERSON.LAST_NAME&quot;, &quot;Smith&quot;));
ObjectCollection oc = QueryExecutor.execute(q);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tady není dotaz založen na prázdné „šabloně“ objektu, který má být získán, ale na sadě „dotazovacích objektů“, které jsou společně použity k definování objektu ve stylu příkazu pro provedení proti databázi. Více kritérií je spojeno pomocí nějaké binomické konstrukce, obvykle objektů &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;And&lt;/code&gt; a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Or&lt;/code&gt;, z nichž každý obsahuje jedinečné objekty Criteria pro testování. Další objekty filtrace/manipulace lze označit na konci, obvykle připojením volání jako &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OrderBy(fieldName)&lt;/code&gt; nebo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GroupBy(fieldName)&lt;/code&gt;. V některých případech jsou tato volání metod vlastně objekty zkonstruované programátorem a explicitně zřetězené.&lt;/p&gt;

&lt;p&gt;Vývojáři si rychle všimnou, že výše uvedený přístup je (obecně) mnohem více slovní než tradiční přístup SQL a některé styly dotazů (zejména netradiční spojení, například vnější spojení) je mnohem obtížnější - ne-li nemožné - reprezentovat v přístupu QBA.&lt;/p&gt;

&lt;p&gt;Kromě toho tu máme ještě jeden subtilnější problém, a to závislost na disciplíně vývojářů: jak název tabulky &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PERSON&lt;/code&gt;, tak název sloupce v kritériích &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PERSON.LAST_NAME&lt;/code&gt; jsou standardní řetězce, které se přebírají tak, jak jsou, a do systému se vkládají za běhu bez jakékoliv kontroly platnosti. To představuje klasický problém v programování, chybu překlepu, kdy se vývojář ve skutečnosti nedotazuje na tabulku &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PERSON&lt;/code&gt;, ale na tabulku &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PRESON&lt;/code&gt;. Rychlý unit-test proti živé instanci databáze sice chybu odhalí, ale to předpokládá dvě skutečnosti - že vývojáři jsou zarytí do testování a že unit-testy jsou prováděny proti instancím databáze. Zatímco první z těchto skutečností se pomalu stává zárukou, protože stále více vývojářů je „nakaženo testováním“ (vypůjčím si terminologii Gama a Becka), druhá skutečnost je stále zcela otevřená diskusi a interpretaci vzhledem k tomu, že vhodné nastavení a rozpojení instance databáze pro unit testy je v databázi stále obtížně proveditelné. (Ačkoli existuje řada způsobů, jak tento problém obejít, zdá se, že se jich používá jen málo.)&lt;/p&gt;

&lt;p&gt;Setkáváme se také se základním problémem, že je od vývojáře vyžadováno větší povědomí o logické - nebo fyzické - reprezentaci dat - místo toho, aby se vývojář jednoduše soustředil na to, jak spolu objekty souvisejí (prostřednictvím jednoduchých asociací, jako jsou pole nebo instance kolekcí), musí mít nyní větší povědomí o formě, v níž jsou objekty uloženy, což činí systém poněkud zranitelným vůči změnám schématu databáze. Tomuto problému se někdy vyhýbá hybridní přístup mezi těmito dvěma přístupy, kdy systém převezme odpovědnost za interpretaci asociací a ponechá na vývojáři, aby napsal něco takového:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Query q = new Query();
Field lastNameFieldFromPerson = Person.class.getDeclaredField(&quot;lastName&quot;);
q.From(Person.class).Where(new EqualsCriteria(lastNameFieldFromPerson, &quot;Smith&quot;));
ObjectCollection oc = QueryExecutor.execute(q);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Což částečně řeší problém s uvědoměním si schématu a problém překlepu, ale stále ponechává vývojáře zranitelného vůči obavám ze slovíčkaření a stále neřeší složitost sestavení složitějšího dotazu, například dotazu na více tabulek (nebo chcete-li více tříd) spojených na základě několika kritérií různými způsoby.&lt;/p&gt;

&lt;p&gt;Dalším úkolem je tedy vytvořit přístup „Query-By-Language“, v němž je napsán nový jazyk, podobný jazyku SQL, ale nějakým způsobem „lepší“, který podporuje složité a výkonné dotazy běžně podporované jazykem SQL; dva příklady takového jazyka jsou OQL a HQL. Problémem je, že tyto jazyky jsou často podmnožinou jazyka SQL, a proto nenabízejí plnou sílu jazyka SQL. Ještě důležitější je, že vrstva O/R nyní ztratila důležitý „prodejní argument“, a to mantru „objekty a pouze objekty“, která ji zplodila; používat jazyk podobný SQL je téměř stejné jako používat samotné SQL, takže jak může být více „objektový“? Vývojáři sice nemusí znát fyzické schéma datového modelu (o mapování, o kterém jsme hovořili dříve, se může postarat interpret/executor dotazovacího jazyka), ale budou si muset být vědomi toho, jak jsou v jazyce reprezentovány asociace a vlastnosti objektů a jaká je podmnožina schopností objektů v rámci dotazovacího jazyka - je například možné napsat něco takového?&lt;/p&gt;

&lt;div class=&quot;language-hql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getSpouse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getSpouse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isThisAnAcceptableSpouse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isThisAnAcceptableSpouse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Jinými slovy, prohledejte databázi a najděte všechny svobodné osoby, které se navzájem považují za přijatelné. Zatímco metoda &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;isThisAnAcceptableSpouse&lt;/code&gt; je zjevně metodou, která patří do třídy Person (každá instance Person může mít svá vlastní kritéria, podle kterých posuzuje přijatelnost jiného svobodného - zda je to blondýna, bruneta nebo zrzka, zda vydělává více než 100 tisíc dolarů ročně a tak dále), není jasné, zda je provedení této metody možné v dotazovacím jazyce, a není ani jasné, zda by mělo být. I u těch nejtriviálnějších implementací dojde pravděpodobně k vážnému zásahu do výkonu, zejména pokud musí vrstva O/R přeměnit data relačních sloupců na objekty, aby bylo možné dotaz provést. Navíc nemáme žádnou záruku, že vývojář napsal tuto metodu tak, aby byla vůbec efektivní, a nemáme žádný způsob, jak vynutit nějakou implementaci zohledňující výkon.&lt;/p&gt;

&lt;p&gt;(Kritici budou tvrdit, že se jedná o řešitelný problém, a navrhnou dvě možná řešení. Jedním z nich je zakódovat preferenční údaje do samostatné tabulky a učinit ji součástí dotazu; výsledkem bude ohavně komplikovaný dotaz, který bude mít délku několika stránek a pravděpodobně bude vyžadovat experta na SQL, aby ho později rozplétal, když bude chtít přidat nová preferenční kritéria. Druhou možností je zakódovat tuto implementaci „přijatelnosti„“ do uložené procedury v rámci databáze, což nyní zcela odstraní kód z objektového modelu a ponechá nás bez jakéhokoli „objektového“ řešení - přijatelné, ale pouze pokud přijmete předpoklad, že ne všechna implementace může spočívat uvnitř samotného objektového modelu, což odmítá předpoklad „objekty a nic než objekty“, kterým mnozí zastánci O/R otevírají své argumenty.)&lt;/p&gt;

&lt;h3 id=&quot;problém-částečných-objektů-a-paradox-času-načítání&quot;&gt;Problém částečných objektů a paradox času načítání&lt;/h3&gt;

&lt;p&gt;Je již dlouho známo, že procházení sítě, například při tradičním požadavku SQL, trvá značnou dobu. (Podle hrubých srovnávacích testů se tato hodnota pohybuje v rozmezí tří až pěti řádů ve srovnání s jednoduchým voláním metody na platformě Java nebo .NET&lt;sup&gt;&lt;a href=&quot;#5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;; zhruba analogicky, pokud vám ráno cesta do práce trvá dvacet minut a nazýváme ji dobou potřebnou k provedení volání místní metody, čtyři řády k této hodnotě představují zhruba dobu potřebnou k cestě na Pluto, neboli necelých čtrnáct let v jednom směru). Tyto náklady jsou zjevně netriviální, takže v důsledku toho vývojáři hledají způsoby, jak tyto náklady minimalizovat optimalizací počtu síťových komunikací a načítaných dat.&lt;/p&gt;

&lt;p&gt;V jazyce SQL se této optimalizace dosahuje pečlivým strukturováním požadavku SQL, kdy se dbá na to, aby se načítaly pouze požadované sloupce a/nebo tabulky, nikoli celé tabulky nebo sady tabulek. Například při konstrukci pečlivě plánovaného tradičního uživatelského rozhranín vývojář předloží souhrnné zobrazení všech záznamů, z nichž si uživatel může vybrat jeden, a po výběru pak zobrazí kompletní sadu dat pro daný záznam. Zaměřme se na příklad relačního typu &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Persons&lt;/code&gt; popsaného dříve, dva dotazy k tomu určené by byly v tomto pořadí (za předpokladu, že je vybrán první z nich):&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;osoba&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Zejména si všimněte, že v každé fázi procesu jsou získány pouze požadované údaje - v prvním dotazu potřebné souhrnné informace a identifikátor (pro následný dotaz v případě, že by k přímé identifikaci osoby nestačilo jméno a příjmení) a ve druhém zbytek údajů k zobrazení. Většina odborníků na SQL se ve skutečnosti vyhýbá syntaxi sloupců se zástupným znakem &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*&lt;/code&gt; a raději v dotazu každý sloupec pojmenuje, a to jak z důvodu výkonu, tak z důvodu údržby - z důvodu výkonu, protože databáze bude lépe optimalizovat dotaz, a z důvodu údržby, protože bude menší pravděpodobnost, že budou vráceny nepotřebné sloupce, jak se budou DBA nebo vývojáři vyvíjet a/nebo refaktorovat příslušné databázové tabulky. Toto pojetí možnosti vrátit část tabulky (i když stále v relační podobě, což je důležité z výše popsaných důvodů uzavřenosti) je zásadní pro možnost optimalizovat tyto dotazy tímto způsobem - většina dotazů bude ve skutečnosti vyžadovat pouze část kompletního vztahu.&lt;/p&gt;

&lt;p&gt;To představuje problém pro většinu, ne-li všechny vrstvy mapování objektů a relací: cílem každé O/R je umožnit vývojáři vidět „nic než objekty“, a přesto vrstva O/R nemůže z jednoho požadavku na druhý říci, jak budou objekty vrácené dotazem použity. Je například zcela reálné, že většina vývojářů bude chtít napsat něco ve stylu:&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;QueryManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(....);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DisplayPersonsForSelection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;DisplayPersonData&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Jinými slovy to znamená, že jakmile je z pole &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt; vybrána osoba, která má být zobrazena, není třeba provádět žádnou další akci načítání - koneckonců máte svůj objekt, co víc by mělo být potřeba?&lt;/p&gt;

&lt;p&gt;Problém zde spočívá v tom, že data, která mají být zobrazena v prvním volání &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Display...()&lt;/code&gt;, nejsou celá osoba, ale podmnožina těchto dat; zde narážíme na první problém v tom, že objektově orientovaný systém, jako je C# nebo Java, nemůže vrátit pouze „části“ objektu - objekt je objekt, a pokud se objekt &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt; skládá z 12 instančních proměnných, pak bude všech 12 přítomno v každé vrácené osobě. To znamená, že systém stojí před jednou ze tří nepříjemných možností: za prvé, požadovat, aby objekty &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt; byly schopny obsahovat „nulovatelné“ proměnné, bez ohledu na doménová omezení, která tomu brání; za druhé, vrátit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt; kompletně vyplněný všemi daty, která objekt tvoří; nebo za třetí, poskytnout nějaký druh načítání na vyžádání, které získá tyto instanční proměnné, pokud a kdy vývojář k těmto proměnným přistupuje, a to i nepřímo, třeba prostřednictvím volání metody.&lt;/p&gt;

&lt;p&gt;(Všimněte si, že některé objektové jazyky, například ECMAScript, nahlížejí na objekty jinak než jazyky založené na třídách, například Java nebo C# či C++, a v důsledku toho je zcela možné vracet objekty, které obsahují různý počet instančních proměnných. Takový přístup však má jen málo jazyků, dokonce ani oblíbený dynamický jazyk Ruby, a dokud se takové jazyky nerozšíří, zůstává taková diskuse mimo oblast této eseje.)&lt;/p&gt;

&lt;p&gt;Pro většinu O/R vrstev to znamená, že objekty a/nebo pole objektů musí být načítány líným způsobem, získáváním dat na vyžádání, protože načítání všech instančních proměnných všech objektů/vztahů osob by pro tento konkrétní scénář „zjevně“ znamenalo obrovské plýtvání šířkou pásma. Obvykle se celá sada instančních proměnných objektu načte při přístupu k jakékoli dosud nevrácené instanční proměnné. (Tento přístup se upřednostňuje před přístupem po jednotlivých proměnných, protože je zde menší pravděpodobnost „problému N+1 dotazů“, kdy načtení všech dat z objektu vyžaduje 1 dotaz na načtení primárního klíče + N dotazů na načtení každé proměnné z tabulky podle potřeby. Tím se minimalizuje šířka pásma spotřebovaná na načtení dat - žádná nezpracovaná proměnná nebude mít načtena svá data - ale zjevně se nepodaří minimalizovat síťové interakce.)&lt;/p&gt;

&lt;p&gt;Naneštěstí jsou proměnné v rámci objektu jen částí problému - další problém, kterému čelíme, spočívá v tom, že objekty jsou často spojeny s jinými objekty, a to v různých kardinalitách (jeden k jednomu, jeden k mnoha, mnoho k jednomu, mnoho k mnoha), a mapování O/R musí předem rozhodnout, kdy tyto přidružené objekty načíst, a přes veškerou snahu vývojářů ORM budou vždy existovat běžné případy použití, kdy učiněné rozhodnutí bude přesně to špatné. Většina ORM nabízí nějakou vývojářem řízenou podporu rozhodování, obvykle nějaký konfigurační nebo mapovací soubor, který přesně určí, jaká bude politika načítání, ale toto nastavení je globální pro danou třídu a jako takové ho nelze situačně měnit.&lt;/p&gt;

&lt;h2 id=&quot;shrnutí&quot;&gt;Shrnutí&lt;/h2&gt;

&lt;p&gt;Pokud je tedy mapování objektů do relací v moderním firemním systému nutností, jak ho může někdo prohlásit za šlamastyku, ze které není úniku? Jako užitečná analogie zde opět slouží Vietnam - zatímco situace v jižní Indočíně vyžadovala reakci Američanů, Kennedyho a Johsonova administrativa měla k dispozici celou řadu reakcí, včetně stejné reakce, jakou vyvolal nedávný pád Suharta v Malajsii, tedy žádné. (Nezapomeňte, že Eisenhower a Dulles v první řadě nepovažovali jižní Indočínu za součást teorie domina; mnohem více je zajímalo Japonsko a Evropa.)&lt;/p&gt;

&lt;p&gt;Nabízí se několik možných řešení problému ORM, z nichž některá vyžadují určitý druh „globální“ akce celé komunity, jiná jsou přístupnější vývojovým týmům „v zákopech“:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Opuštění&lt;/strong&gt; Vývojáři se jednoduše zcela vzdají objektů a vrátí se k programovacímu modelu, který nevytváří nesoulad mezi objektovou a relační impedancí. I když je to nepříjemné, v určitých scénářích vytváří objektově orientovaný přístup více režie, než kolik ušetří, a návratnost investice jednoduše není taková, aby ospravedlnila náklady na vytvoření bohatého doménového modelu. ([Fowler] o tom hovoří poněkud do hloubky.) To tento problém poměrně elegantně odstraňuje, protože pokud neexistují žádné objekty, nedochází k impedančnímu nesouladu.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Celkové přijetí&lt;/strong&gt; Vývojáři se jednoduše zcela vzdají relačního úložiště a používají model úložiště, který odpovídá způsobu, jakým se na svět dívají jejich zvolené jazyky. Systémy objektového ukládání, jako je například projekt db4o (který je bohužel od roku 2021 v podstatě nefunkční), řeší problém elegantně tím, že ukládají objekty přímo na disk, čímž odstraňují mnoho (ale ne všechny) z výše uvedených problémů; neexistuje například žádné “druhé schéma”, protože jediné použité schéma je schéma samotných definic objektů. Ačkoli mnozí DBA při této myšlence omdlí, ve světě stále více orientovaném na služby, který se vyhýbá myšlence přímého přístupu k datům, ale místo toho vyžaduje, aby veškerý přístup probíhal přes bránu služby, čímž je mechanismus ukládání zapouzdřen mimo dosah zvědavých očí, je zcela reálné si představit, že vývojáři ukládají data ve formě, která je pro ně mnohem snazší než pro DBA.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ruční mapování&lt;/strong&gt; Vývojáři se prostě smíří s tím, že to nakonec není tak těžký problém, aby ho řešili ručně, a napíší rovnou kód pro relační přístup, který bude vracet relace do jazyka, přistupovat k tuplům a naplňovat objekty podle potřeby. V mnoha případech může být tento kód dokonce automaticky generován nástrojem zkoumajícím metadata databáze, čímž se eliminuje některá z hlavních kritik tohoto přístupu (a to: „Je to příliš mnoho kódu na psaní a údržbu“).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Přijetí omezení ORM&lt;/strong&gt; Vývojáři se jednoduše smíří s tím, že neexistuje způsob, jak efektivně a snadno uzavřít smyčku nesouladu O/R, a použijí ORM k vyřešení 80 % (nebo 50 % nebo 95 % nebo jakéhokoli procenta, které se jim zdá vhodné) problému a využijí SQL a přístup založený na relacích (například „surový“ JDBC nebo ADO.NET), aby se přenesli přes ty oblasti, kde by ORM způsoboval problémy. Takový postup však s sebou nese vlastní podíl rizik, protože vývojáři používající ORM si musí být vědomi jakéhokoli ukládání do cache, které v rámci něj řešení ORM provádí, protože „surový“ relační přístup zjevně nebude schopen tuto vrstvu ukládání do cache využít.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Integrace relačních konceptů do jazyků&lt;/strong&gt; Vývojáři se prostě smíří s tím, že tento problém by měl řešit jazyk, nikoli knihovna nebo framework. V posledních deseti nebo více letech se důraz na řešení problému O/R soustředil na snahu přiblížit objekty databázi, aby se vývojáři mohli soustředit výhradně na programování v jediném paradigmatu (tímto paradigmatem jsou samozřejmě objekty). V posledních několika letech však zájem o „skriptovací“ jazyky s mnohem silnější podporou množin a seznamů, jako je Ruby, podnítil myšlenku, že je možná vhodné jiné řešení: vnést relační koncepty (které jsou ve své podstatě založeny na množinách) do hlavních programovacích jazyků, což usnadní překlenutí propasti mezi „množinami“ a „objekty“. Práce v této oblasti je zatím omezená a omezuje se většinou na výzkumné projekty a/nebo „okrajové“ jazyky, ale v komunitě se zviditelňuje několik zajímavých snah, jako jsou hybridní funkcionální/objektové jazyky, například Scala nebo F#, a také přímá integrace do tradičních O-O jazyků, jako je projekt LINQ společnosti Microsoft pro C# a Visual Basic. Jednou z takových snah, která bohužel selhala, byla strategie SQL/J; i tam byl přístup omezený, nesnažil se začlenit množiny do Javy, ale pouze umožnit, aby vložená volání SQL byla předzpracována a přeložena do kódu JDBC překladačem.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Integrace relačních konceptů do frameworků&lt;/strong&gt; Vývojáři prostě uznávají, že tento problém je řešitelný, ale pouze se změnou perspektivy. Místo aby se spoléhali na to, že tento problém vyřeší návrháři jazyků nebo knihoven, zaujmou jiný pohled na „objekty“, který je více relační povahy, a vytvoří doménové rámce, které jsou více přímo postaveny na relačních konstrukcích. Například místo vytváření třídy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt;, která uchovává svá instanční data přímo v proměnných uvnitř objektu, vytvářejí vývojáři třídu &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Person&lt;/code&gt;, která uchovává svá instanční data v instanci RowSet (Java) nebo DataSet (C#), kterou lze sestavit s dalšími RowSet/DataSet do snadno přenositelného bloku dat pro aktualizaci proti databázi nebo rozbalit z databáze do jednotlivých objektů.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Všimněte si, že tento seznam není uveden v žádném konkrétním pořadí; zatímco některé jsou atraktivnější než jiné, to, které jsou „lepší“, je hodnotový soud, který si musí každý vývojář a vývojový tým udělat sám.&lt;/p&gt;

&lt;p&gt;Stejně jako je možné si představit, že USA mohly dosáhnout určitého „úspěchu“ ve Vietnamu, kdyby se držely jasné strategie a chápaly jasnější vztah mezi závazkem a výsledky (ROI, chcete-li), je možné si představit, že objektový/relační problém lze „vyhrát“ pečlivým a uvážlivým uplatňováním strategie, která si je celá vědoma svých vlastních omezení. Vývojáři musí být ochotni brát „výhry“ tam, kde je mohou získat, a nesklouznout na šikmou plochu tím, že se budou snažit vytvářet řešení, která budou stále dražší a méně výnosná. Bohužel, jak ukazuje historie Vietnamské války, ani vědomí nebezpečí šikmé plochy často nestačí k tomu, aby se zabránilo zabřednutí do bažiny. A co hůř, je to bažina, která je prostě příliš přitažlivá na to, aby se jí dalo vyhnout, píseň sirén, která stále přitahuje vývojové týmy všech velikostí korporací (včetně těch v Microsoftu, IBM, Oracle a Sunu, abychom jmenovali alespoň některé) ke skalám, a to s velkolepými výsledky. Přivažte se ke stěžni, pokud chcete píseň slyšet, ale nechte veslovat námořníky.&lt;/p&gt;

&lt;h2 id=&quot;poznámky-na-závěr&quot;&gt;Poznámky na závěr&lt;/h2&gt;

&lt;p&gt;&lt;a name=&quot;1&quot;&gt;&lt;/a&gt;[1] Pozdější analýzy zúčastněných ředitelů - včetně tehdejšího ministra obrany Roberta McNamary - dospěly k závěru, že polovina útoku se vůbec neuskutečnila.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;2&quot;&gt;&lt;/a&gt;[2] Je možná největší ironií války, že muž, kterého si osud vybral do čela během největšího amerického zahraničního angažmá, byl vůdce, jehož hlavní pozornost byla zaměřena výhradně na vlastní břehy. Kdyby se okolnosti nespikly jinak, hippies skandující před Oválnou pracovnou “Hej, hej LBJ, kolik kluků jsi dneska zabil” by dost možná byli Johnsonovými nejvěrnějšími stoupenci.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;3&quot;&gt;&lt;/a&gt;[3] Ironií osudu se ukazuje, že zapouzdření je z důvodu jednoduchosti údržby hlavní motivací téměř všech významných inovací v lingvistické informatice - procesní, funkcionální, objektové, aspektové, dokonce i relační technologie ([Date02]) a další jazyky uvádějí „zapouzdření“ jako hlavní hnací faktor.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;4&quot;&gt;&lt;/a&gt;[4] Za „relační“ programovací jazyky bychom snad mohli považovat jazyky uložených procedur jako T-SQL nebo PL/SQL, ale i v takovém případě je nesmírně obtížné vytvořit uživatelské rozhraní v PL/SQL.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;5&quot;&gt;&lt;/a&gt;[5] V tomto případě jsem poměřoval volání metod RMI v Javě s voláním lokálních metod. Podobné výsledky lze celkem snadno získat pro přístup k datům na bázi SQL měřením volání mimo proces proti voláním v procesu pomocí databázového produktu, který podporuje obojí, například Cloudscape/Derby nebo HSQL (Hypersonic SQL).&lt;/p&gt;

&lt;h2 id=&quot;reference&quot;&gt;Reference&lt;/h2&gt;

&lt;p&gt;[Fussell] Foundations of Object Relational Mapping, by Mark L. Fussell, v0.2 (mlf-970703)&lt;/p&gt;

&lt;p&gt;[Fowler] Patterns of Enterprise Application Architecture, by Martin Fowler&lt;/p&gt;

&lt;p&gt;[Date04] Introduction to Database Systems, 8th Edition, by Chris Date.&lt;/p&gt;
</description>
        <pubDate>Tue, 29 Apr 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/04/29/Vietnam-informatiky.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/04/29/Vietnam-informatiky.html</guid>
        
        <category>překlad</category>
        
        <category>OOP</category>
        
        <category>JPA</category>
        
        
        <category>software development</category>
        
      </item>
    
      <item>
        <title>FIRST Lego League Challenge</title>
        <description>&lt;div style=&quot;float: left; margin: 0 1em 1em 0; text-align: center;&quot;&gt;&lt;img src=&quot;/assets/2025-03-23/FLL_Challenge_Logo_v2.svg&quot; /&gt;&lt;/div&gt;

&lt;p&gt;Miluju lego, jako dítě jsem si s ním neskutečně vyhrál a moje láska k němu přetrvává i do dospělosti.
Nicméně pozorní čtenáři blogu vědí, že &lt;a href=&quot;/tag/krou%C5%BEek-programov%C3%A1n%C3%AD&quot;&gt;kroužek programování&lt;/a&gt; se snažím držet nízkonákladový, takže lego robotům jsem se dlouho vyhýbal.
Učitel informatiky na naší škole, Matěj Burda, přišel s nápadem, že ho zaujala soutěž &lt;a href=&quot;https://www.firstlegoleague.org/&quot;&gt;FIRST Lego League Challenge&lt;/a&gt;.
Říkal jsem si proč ne, kroužek stejně potřeboval po letech nový impulz.
Domluvili jsme se na tandemové výuce a šli do toho.
Jestli soutěž neznáte nebo váháte, zda se příští rok přihlásit, tak vás může následující text navnadit, abyste se příští rok zúčastnili i vy.&lt;/p&gt;

&lt;div style=&quot;clear:both&quot;&gt;&lt;/div&gt;
&lt;!--more--&gt;

&lt;h2 id=&quot;úvod&quot;&gt;Úvod&lt;/h2&gt;

&lt;p&gt;Jsem si vědom, že existuje &lt;a href=&quot;https://robosoutez.fel.cvut.cz/&quot;&gt;Lego soutěž při ČVUT&lt;/a&gt;, u které jsem se však osobně zařekl, že se jí nikdy účastnit nebudu.
Jednak používají již nedostupné stavebnice Mindstorm a hlavně mají pro mě naprosto nepřijatelné znění pravidel, viz níže.
Takhle nepřátelskému prostředí nehodlám děti vystavovat.
Pravidlu vyloučení rozumím, ale provedení otřesné.
I na vesnickém amatérském běžeckém závodě existuje způsob odvolání.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Organizátor ROBOSOUTĚŽE (Ing. Martin Hlinovský, Ph.D.) může rozhodnout o diskvalifikaci (vyloučení ze soutěže) jakéhokoliv týmu bez dalšího vysvětlení. Jeho rozhodnutí je konečné a nenapadnutelné.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Konec plivání sírý a pojďme se věnovat FIRST Lego League Challenge.
Předně jsem rád, že tedy pro lego roboty existuje alternativa.
Navíc alternativa mezinárodní.
Každoročně je soutěž zasazena do jiného symbolického rámce, letos se jednalo o podmořský svět.&lt;/p&gt;

&lt;p&gt;Skládá se ze čtyř disciplín, které jsou v hodnocení ekvivalentní:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Core values, týmová spolupráce&lt;/li&gt;
  &lt;li&gt;Design&lt;/li&gt;
  &lt;li&gt;Robot race&lt;/li&gt;
  &lt;li&gt;Inovační projekt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jednotlivým disciplínám se ještě budu věnovat, jen jsem chtěl vypíchnout, že mi to přišlo jako hodně práce (a hodně práce to skutečně je) a že je to možná zbytečné.
Dnes uznávám, že je to perfektně vymyšlený systém.
Děti to může mnohem víc posunout.
Klade to požadavky na všestrannost, stejně tak jako běžný život, a zajistí to, že nevyhrají fachidioti.&lt;/p&gt;

&lt;h2 id=&quot;robot-race&quot;&gt;Robot race&lt;/h2&gt;

&lt;p&gt;Nejatraktivnější disciplínou je právě &lt;em&gt;robot race&lt;/em&gt;, na kterou jsme ostatně soustředili i my.
Nejlépe vám to vysvětlí následující &lt;a href=&quot;https://www.youtube.com/watch?v=TDZoKKqyKsI&quot;&gt;video&lt;/a&gt;.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/J5u-2q_K3O0?si=YuWSt1wS_NwCsmLM&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;15 misí, nemusíte splnit všechny, na pořadí nezáleží.
Máte 3 pokusy, na každý 2,5 minuty, počítá se nejlepší výsledek.&lt;/p&gt;

&lt;p&gt;Bodování mi přijde geniálně motivační, i když totiž nevyřešíte žádnou překážku, neodcházíte s nulou.
Máte nějaké body, které vám zůstávají, pokud něco neshodíte (je to aspekt, který hraje roli u složitějších misí).&lt;/p&gt;

&lt;p&gt;Když jsem viděl zadání poprvé, tak mě napadlo, že je to úmyslně navržené tak, aby to nešlo v daném čase dokončit všechno. 
Ale jde, viz například tohle &lt;a href=&quot;https://www.youtube.com/watch?v=5mdZ78bceZs&quot;&gt;video&lt;/a&gt;, ale nenechte se tím zdeptat.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/5mdZ78bceZs?si=w9J8a-AsmZfXhnVE&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Netušil jsem, jak řešení misí uchopíme, až jsem našel &lt;a href=&quot;https://www.youtube.com/watch?v=Z8WmxYBjVVo&quot;&gt;sympatický youtube kanál&lt;/a&gt;, kde mají řešení nastíněné.
Tedy nemáte tam přímo zdrojový kód, ale video záznam z plnění mise a taky navržené přípravky.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Z8WmxYBjVVo?si=JZMXGPdfsQ7uJ9hE&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;inovační-projekt&quot;&gt;Inovační projekt&lt;/h2&gt;

&lt;p&gt;Inovační projekt pro nás byl velkou neznámou.
V podstatě si tým sám vybere nějaký problém, který se nějak dotýká daného tématu, a navrhne jeho řešení.
Naše děti jely na exkurzi do Mořského světa, ale nakonec tuto aktivitu úplně vypustily, kvůli čemuž ztratily spoustu bodů.&lt;/p&gt;

&lt;p&gt;Hledali jsme inspiraci u soupeřů.
Jeden tým si například vybral téma odpadků na plážích a následného rozpadání na mikroplasty.
Problém popsali a navrhli řešení v podobě robota, který bude prosívat písek.
Na 3D tiskárně vyrobili prototyp sít třech zrnitostí a na místě předvedli.
Za pomoci robota Meet Edison demonstrovali, že v písku je potřeba se pohybovat na pásech a ne na kolech.&lt;/p&gt;

&lt;h2 id=&quot;cena&quot;&gt;Cena&lt;/h2&gt;

&lt;p&gt;Jak jsem předeslal, mentální překážkou je pro mě cena.
Nemyslím si, že je nezasloužená (bez sponzorů by musela být ještě mnohem vyšší), ale pro někoho to možná může být nepřekonatelná bariéra.
Maloobchodní cena &lt;a href=&quot;https://ruzovka.cz/cs/lego-education/16469-lego-education-45678-spike-prime-set.html&quot;&gt;LEGO SPIKE Prime&lt;/a&gt; je 12 tisíc korun, do soutěže máte 10 % slevu.
Není povinný, ale hodí se, &lt;a href=&quot;https://ruzovka.cz/cs/lego-education/17895-lego-education-45681-spike-prime-expansion-set.html&quot;&gt;Expansion Set&lt;/a&gt; za skoro 4 tisíce korun.
Začínali jsme se stavebnicí na trojici, ale chce to spíš do dvojice.&lt;/p&gt;

&lt;p&gt;Startovné na jeden tým 8 tisíc korun (4 tisíce registrační poplatek, 4 tisíce herní plán).
Ceně za startovné rozumím, ale nechápu, proč je povinné kupovat tolik herních plánů, kolik máte týmu (výslovně jsem se na to ptal).
No nic, sadu jsme prodali spřízněnému kroužku na hraní, přesto bych firmě Lego tohle plýtvání osolil v &lt;a href=&quot;https://www.epravo.cz/top/clanky/co-je-to-esg-a-co-pro-vas-znamena-114345.html&quot;&gt;ESG&lt;/a&gt; 😉.&lt;/p&gt;

&lt;p&gt;V neposlední řadě si potřebujete vyrobit stůl na herní plán.&lt;/p&gt;

&lt;h2 id=&quot;aplikované-přírodní-vědy&quot;&gt;Aplikované přírodní vědy&lt;/h2&gt;

&lt;p&gt;Na kroužku mě baví to, že si můžeme nejenom hrát, ale že musí uplatnit i znalosti ze školy. 
Případně si uvědomí, že jim chybí a potřebují si je doplnit.&lt;/p&gt;

&lt;p&gt;Jedna matematická historka.
Nevím, jestli si ze mě jen puberťáci nedělali srandičky, ale to je vlastně jedno, didaktický úkol splněn.
Potřebujete popojet o deset centimetrů.
Jak robot ví, co je deset centimetrů?
Ovládáte jen otáčky.
Pojďme si robota zkalibrovat.
Změřme vzdálenost, kterou ujede na 10 otáček.
Naměřili 270 cm.
Kolik je tedy obvod kola?
V pátek odpoledne už někomu dochází šťáva, napovídám dělit deseti.
Jak to lze zjistit jinak?
Kontrolně měříme obvod svinovacím metrem.
Výpočet obvodu z průměru vypadá, že v sedmé třídě ještě nebrali.&lt;/p&gt;

&lt;p&gt;Přesah matematiky a fyziky.
Potřebuji pohnout ramenem o 90 stupňů.
O kolik pootočím motorem?
Zkusí o 90 a zjistí, že to nesedí.
A nesedí ani směr, protože převodovka.
Poměr zubu nepočítají, ale to nevadí, přístup pokus/omyl bereme.&lt;/p&gt;

&lt;p&gt;Pro přesné zatáčení si nevystačíme jen s ovládáním motorů.
Kola můžou různě prokluzovat, robot má nějakou setrvačnost a tak dále.
Rozhodovat se lze i na základě telemetrie, robot má integrovaný třísměrný gyroskop.&lt;/p&gt;

&lt;h2 id=&quot;didaktické-poznámky&quot;&gt;Didaktické poznámky&lt;/h2&gt;

&lt;p&gt;S přípravou na soutěž je dost práce.
Jen v kroužku hodinu týdně by se to pořádně nestihlo.
A to ještě nemluvím o inovačním projektu.
Díky tandemu s učitelem informatiky, jsme měli výhodu, že se děti částečně věnovaly robotům i během vyučování či v družině.&lt;/p&gt;

&lt;p&gt;Několik našich zvědů se jelo podívat na finále do Prahy.&lt;/p&gt;

&lt;p&gt;Mám dojem, že děti si doma staví z lego technik podle návodu, ale už ne tolik dle vlastní fantazie.
Usuzuju tak z pozorování stavby přípravků.&lt;/p&gt;

&lt;p&gt;Nemám dostatečný statistický vzorek, ale dívky mi přijdou houževnatější než chlapci, že to u nás víc táhly.&lt;/p&gt;

&lt;p&gt;Na příští ročník si musíme cvičně vyzkoušet vystoupení před komisí, aby je to tolik nestresovalo a získali nějakou sebedůvěru.&lt;/p&gt;

&lt;p&gt;Rozhraní editoru i návody jsou anglicky, na to nejsou zvyklí.
Rozhraní Microbit nebo Scratch jsou přeložená do češtiny.
Uchylovali se tedy k automatickému překladu v prohlížeči.&lt;/p&gt;

&lt;h2 id=&quot;oblastní-kolo-karlovy-vary&quot;&gt;Oblastní kolo Karlovy Vary&lt;/h2&gt;

&lt;p&gt;Přihlásili jsme se na oblastní kolo Karlovy Vary.
Pro nás je to hrozná dálka, skoro tři hodiny autem, ale byl to nejzazší termín, takže jsme získali víc času na přípravu.
Přesto za rok pojedeme zase tam.
Vládla tam skvělá atmosféra.
Rozhodčí velmi vřelí, dokonce i poradili (vůbec jsme si neuvědomili, že na robota se může jednou beztrestně sáhnout, tedy přijdete o jeden žeton přesnosti, ale ne o body).
Kolo je takové komorní.
Protože se účastní méně týmu, zbyl čas na nadstavbové klání mimo soutěž jen v &lt;em&gt;robot race&lt;/em&gt;.
Pokusíme si výlet prodloužit a domluvit exkurzi ve &lt;a href=&quot;https://www.witte-automotive.com/cz&quot;&gt;Witte&lt;/a&gt; (jeden ze sponzorů).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/2025-03-23/IMG_7806.jpg&quot; alt=&quot;&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Neměli jsme žádné ambice, jeli jsme na účast.
Chtěli jsme hlavně sbírat zkušenosti.
Jednu splněnou úlohu bych považoval za úspěch.
Nakonec jsme dopadli nad očekávání dobře.
Jeden tým exceloval v &lt;em&gt;robot race&lt;/em&gt; se získem 205 bodů.
Jelikož úplně vypustili inovační projekt, tak je to pravděpodobně stálo postupové místo.
Ocenila to i porota, udělila jim diplom „Rising All-Star“.
Mně to nervy nedrásá, naopak je to super výchovný prvek, že mají příští rok máknout (naše pobídky během roku nestačily).&lt;/p&gt;

&lt;h2 id=&quot;python&quot;&gt;Python&lt;/h2&gt;

&lt;p&gt;Vypozorovali jsme, že některé týmy používaly Python.
Po soutěži jse si tedy zkusili i my, ale skok na písmenkové jazyky je veliký.
Existuje ještě varianta &lt;a href=&quot;https://pybricks.com/&quot;&gt;Pybricks&lt;/a&gt; (placené, tedy další zářez do rozpočtu).
Jestli tomu rozumím správně, tak se programuje v blocích, ale vidíte výsledný Python kód (který nelze editovat).
Nemáme pořádně vyzkoušené, ale na první pohled mají předpřipravené bloky pro přesné zatáčení (berou například v potaz rozvor kol) nebo zapojí gyroskop pro udržení rovného směru.
Dále jsem si všiml, že robot umí vykroužit oblouk zatáčky, ne udělat prosté &lt;em&gt;vlevo vbok&lt;/em&gt; na místě.
Mělo by jít i nastavit poměr počtu zubů jednotlivých ozubených kol.&lt;/p&gt;

&lt;p&gt;Do řídící jednotky je potřeba flashnout jiný firmware a do operačního systému nainstalovat ovladač.
To je pro děti velká výzva.
Co jsme s hardware zažíval jako dítě já, oni už dnes (naštěstí) zažívat nemusejí, ale ani nemají tu znalost.
Beru to jako příležitost, že si můžou doplnit.&lt;/p&gt;

&lt;h2 id=&quot;závěr&quot;&gt;Závěr&lt;/h2&gt;

&lt;p&gt;Lego soutěž se mi líbí, příště pojedeme znovu.
Příprava zabere dost času, naštěstí máme přesah z kroužku do školního vyučování.
Velký úkol pro nás bude inovační projekt.
Jako jednu z nevýhod vidím vyšší počáteční investici do vybavení.&lt;/p&gt;
</description>
        <pubDate>Sun, 23 Mar 2025 00:00:00 +0000</pubDate>
        <link>https://blog.zvestov.cz/software%20development/2025/03/23/first-lego-league-challenge.html</link>
        <guid isPermaLink="true">https://blog.zvestov.cz/software%20development/2025/03/23/first-lego-league-challenge.html</guid>
        
        <category>kroužek programování</category>
        
        <category>lego</category>
        
        
        <category>software development</category>
        
      </item>
    
  </channel>
</rss>
