Kategorie: Zájmy

  • Průvodce tanečníka swingu

    Když jsem cca 2 roky zpátky procházel videa na YouTube, narazil jsem na tanec, který mě již na první pohled zaujal, nejen celkově, ale byl to především jeden prvek, který v něm tančily výhradně holky a ten prvek se mi strašně líbil. Tehda jsem měl nějaké matné ponětí, že se tomu celému nejspíše říká Swing, ale dnes již vím, že konkrétně ten tanec, který mě zaujal, se jmenuje Lindy Hop a ten prvek, který se mi na holkách tolik líbil, se nazývá „swivel“.

    Pokud zrovna nebydlíte ve velkoměstě, pak pro vás mohou být lekce swingu vzácností, protože ani zde v okolí jsem nemohl najít nikoho, kdo by to vyučoval. Až pak jednoho dne mě oslovila reklama na FB, oznamující otevření kurzu pro začátečníky a to přímo ve Starém Městě u Frýdku-Místku pod záštitou Old Town Swing. Rozhodování netrvalo dlouho a má přihláška již putovala elektronickou cestou přímo do Starého Města. Že nemám partnerku? Nevadí! Holek je na tančení přeci vždycky více … a tak vše mohlo začít, kde od této chvíle můj život již nebude úplně stejný jako dřív.

  • Jak skákat s kitem (pohledem začátečníka)

    Jelikož se mi poslední zimu podařilo „sesbírat všechny své koule“ a konečně opět pokročit ve skocích s kitem na lyžích, rozhodl jsem se sepsat pár dojmů skákajícího začátečníka a trošku více do detailu popsat, jak s kitem správně skákat.

    Úvod

    Skočit s kitem je principiálně docela jednoduché, ale co je na tom celém z počátku nejtěžší, je zachovat v hlavě klid a tento jednoduchý postup skutečně vykonat! Dále bych nedoporučoval skákat s malými kity (tj. cokoliv pod 10sqm). V samotné technice skoku bude taktéž záviset na druhu kita, proto můj popis budu více směřovat dle své vlastní zkušenosti na vynikající uzavřenou komoru Aeros NAVY 2 (11sqm). Dle toho, jaký kite vlastníte již nechám na vás, abyste si svou techniku skoku vyladili sami 🙂 .

    Technika skoku

    Abych to příliš nezesložiťoval, shrnul bych celý postup skoku do těchto jednoduchých kroků:

    1. Mám kite na pravé straně větrného okna a tedy jedu „doprava“
    2. Až naberu rychlost, zatáhnu za levou stranu baru a posílám kita nad svou hlavu (ne pomalu, ale ani moc rychle – je třeba vychytat) a začínám hranit mírně proti větru (tlačím na levou nohu a snažím se udržet si pozici – nesklouzávám lyžemi po větru)
    3. Během hranění a stoupání kita nad hlavu dám bar tak daleko/blízko od sebe, abych cítil neustálý tah kita, který zároveň nesmí být tak silný, abych již na lyžích neudržel hranu (nezačal sklouzávat po větru)
    4. Jakmile je kite téměř nade mnou (ideální pozici je třeba vychytat), přitáhnu bar k sobě a okamžitě tahám za pravou stranu baru, abych kite stočil postupně zpět do směru jízdy

    A to by mělo být de facto vše 🙂 . Jen jak jsem již zmínil dříve, doporučil bych si tento postup dopředu naučit nazpaměť neboť (pokud člověk ještě není zvyklý) v momentě, kdy vás kite zvedne, tak se mozek dostane do jakéhosi „stavu přežití“ a v tomto stavu není absolutně schopen přemýšlet – proto hlavně ono vrácení kitu zpět do směru jízdy musíte udělat zcela automaticky/intuitivně (bez přemýšlení). Pokud byste kite nestočili a nechali ho tak, velmi pravděpodobně dojde k tomu, že se zhoupnete dopředu a přistanete na záda – proto páteřák vždy s sebou! Nebo pokud byste, nedej bože, zatáhli za špatnou stranu (v tomto případě za levou), tak se můžete rozbít opravdu ošklivě …

    Pokud se vrátím k bodu 3 – jak moc mít bar od sebe – tak to se mi zároveň ukázalo jako dobré měřítko, jak bude skok cca vysoký. Pokud bude foukat hodně, kite mě donutí mít bar téměř úplně od sebe a dle toho můžu čekat, že skok bude vysoký. Proto bych ze začátku v takovém případě doporučil přitáhnout bar ne úplně k sobě, ale třeba jen do poloviny. Naopak, pokud si budu moct dovolit bar během stoupání kita mít blíže k sobě, znamená to, že fouká málo, nebo obecně, že kite má málo síly, což se projeví tak, že po úplném přitažení baru neskočím buď vůbec, anebo velmi málo.

    Jako ukázku výše popsané techniky skoku bych zvolil tento krátký úryvek (skočil jsem asi 10-20cm nad zem):

    To by bylo ke skokům vše, přeju vám krásné radovánky s vaším kitem, ale hlavně: skákejte bezpečně! 🙂

  • Koltin: GUI aplikace pro výpočet ceny benzínu dle spotřeby

    Vítejte v dalším díle věnovaném jazyku Kotlin, kde si ukážeme, jak psát nabušené GUÍ-tka založené na JavaFX za pomocí výborného frameworku TornadoFX. Náš výsledek bude vypadat takto a celé nakódění nám nezabere déle jak 30 minut:

  • Hra Hangman (Šibenice) v Kotlinu

    Rád s nadsázkou říkávám, že Kotlin je tak produktivní, že občas už ani sám nevím, co bych v něm dál napsal, neboť jak by se na Ostravsku řeklo „bo všecko je už zrobene“ 🙂 . A tak jsem si při příležitosti víkendové nudy řekl, že si jen tak napíšu jednoduchou konzolovou hru Hangman (Šibenice/Oběšenec). Pokud byste dokázali kód refaktorovat do ještě lepší podoby, podělte se v komentářích 🙂 , nicméně tady to je a přeji příjemnou zábavu:

    package com.svetylkovo.games.hangman
    
    object Hangman {
    
        private var remainingWrongAttempts = 5
        private var word = ""
    
        private val guessedLetters = mutableSetOf<Char>()
        private val wrongGuesses = mutableSetOf<Char>()
    
        @JvmStatic
        fun main(args: Array<String>) {
    
            println("Let's play Hangman!")
            println("Type a word to be guessed:")
    
            word = readLine()?.nullIfBlank() ?: "HANGMAN"
    
            clearScreen()
    
            println("\nStart guessing!\n")
    
            while (remainingWrongAttempts > 0) {
                val hiddenWord = getHiddenWord()
    
                if ('_' !in hiddenWord) {
                    println("You did it!")
                    return
                }
    
                println("Word: ${hiddenWord.replace(Regex("."), "$0 ")}")
                printWrongGuesses()
                println("Remaining wrong attempts: $remainingWrongAttempts")
                println("Guess a letter:")
    
                val letter = readLine()?.nullIfBlank()
                    ?.toUpperCase()
                    ?.first()
    
                if (letter != null) {
                    guessedLetters += letter
    
                    if (letter in word) {
                        println("\nCorrect!\n")
                    } else {
                        println("\nWrong!\n")
                        wrongGuesses += letter
                        remainingWrongAttempts--
                    }
                }
            }
    
            println("You've been hanged! :-(")
        }
    
        private fun printWrongGuesses() {
            if (wrongGuesses.isNotEmpty()) {
                println("Wrong guesses: ${wrongGuesses.joinToString(", ")}")
            }
        }
    
        private fun getHiddenWord() = word.map { letter ->
            if (letter in guessedLetters) letter else '_'
        }.joinToString("")
    
        private fun clearScreen() = repeat(25) { println() }
    
        private fun String.nullIfBlank() = if (isBlank()) null else this
    }
    
  • Kotlin a tail recursion

    Ještě za mých „dávných“ dob Scaly jsem si vzpomněl na takovou funkcionální pikantnost, která by se vám možná mohla hodit. Říká se jí tail recursion (optimization) a vztahuje se pouze na ten nejjednodušší typ rekurze, kdy funkce volá čistě jen samu sebe. Typicky by člověk tohle využil u procházení nějakých zanořených stromových struktur, ale abychom trochu potrápili mozkové závity a třeba se i někam dále posunuli, zkusíme si něco úplně jiného. Představme si, že jsme v ryze funkcionálním světě a chceme iterovat přes nějaký List a to bez použití jakýchkoli cyklů. Tzn. žádný while, ani for, nic … Je něco takového vůbec možné? Ano, je, a jak jistě tušíte, dá se to řešit právě pomocí rekurze.

    Challenge

    Ještě než vám ukážu svou verzi, která vás konec konců svou jednoduchostí možná až překvapí, zkuste trochu potrápit své mozkové závity a pokuste se naimplementovat metodu recursiveForeach() pouze za pomocí rekurze tak, aby jí šlo použít takovýmto způsobem:

    object TailRecursionTest {
    
        @JvmStatic
        fun main(args: Array) {
    
            val nums = listOf(1, 2, 3)
    
            recursiveForeach(nums) {
                println("The number is $it")
            }
        }
    }
    

    Řešení

    Jeden ze způsobů, jak to napsat, je např. tento:

        fun <T> recursiveForeach(list: List<T>, callback: (T) -> Unit)  {
            if (list.isNotEmpty()) {
                callback(list.first())
                recursiveForeach(list.drop(1), callback)
            }
        }
    

    a když daný kód spustím, na výstupu dostanu skutečně:

    The number is 1
    The number is 2
    The number is 3

    Limity stacku a klíčové slovo tailrec

    Jak jistě čekáte, tohle řešení má docela podstatnou nevýhodu, a sice pokud bude list příliš velký, dostanete StackOverflowError. Zkuste si např v kódu změnit:

    val nums = (1..10000).toList()
    

    Co s tím? Stačí před fun recursiveForeach přidat kouzelné slůvko tailrec. Co tohle udělá, je optimalizace tohoto rekurzivního kódu pomocí cyklů, takže již nedojde k zanořování a následnému přetečení zásobníku. Pokud spustíte kód nyní, StackOverflowError již nenastane. Když se podíváme pod pokličku a dekompilujeme si výsledný kód, uvidíme něco takového:

       public final void recursiveForeach(@NotNull List list, @NotNull Function1 callback) {
          while(true) {
             Intrinsics.checkParameterIsNotNull(list, "list");
             Intrinsics.checkParameterIsNotNull(callback, "callback");
             Collection var3 = (Collection)list;
             if (var3.isEmpty()) {
                return;
             }
    
             callback.invoke(CollectionsKt.first(list));
             list = CollectionsKt.drop((Iterable)list, 1);
          }
       }
    

    Sice rekurze až tak často nepíšu, ale někdy by se tato featura mohla určitě hodit 🙂 .

  • Bilance snowkitingové sezóny 2017/2018

    Svou druhou snowkite sezónu mám za sebou a tentokrát jsem si stanovil za cíl precizně trackovat, kolikrát se nám za celou zimu podařilo vyrazit za větrem, a kolik km jsem na lyžích celkově najel. Výsledky se mi zdají celkem fajn:

    Počet výjezdů: 11

    Celkově najeto: 137 km

    Cílem pro příští zimu budiž vyrazit alespoň 12x a najet alespoň 150km 🙂 .

  • Lateinit v Kotlinu a jeho výhoda oproti NullPointerException

    Kotlin občas na úrovni byte kódu generuje různý boilerplate, např. v podobě checků inicializace lateinit proměnných, a až donedávna mi unikala jednoduchá, avšak svým významem docela důležitá věc. Říkal jsem si, že pokud aplikace padne na NullPointerException v Javě, anebo na UninitializedPropertyAccessException v Kotlinu, tak že je to v důsledku totéž. Nicméně je zde jeden případ, kdy lateinit jednoznačně vede. Mějme tento kód v Javě:

    package com.svetylkovo.kotlin.lateinit;
    
    public class WithoutLateinit {
        private static String first;
        private static String second;
    
        public static void main(String[] args) {
            first = "First!";
            System.out.println("Total length is "+ String.valueOf(first.length() + second.length()));
        }
    }
    

    Pokud tento kód spustíme, dostaneme:

    Exception in thread "main" java.lang.NullPointerException
    at com.svetylkovo.kotlin.lateinit.WithoutLateinit.main(WithoutLateinit.java:9)

    Po nalezení řádku kódu, kde NullPointerException nastal, si můžeme jen lámat hlavu, která z těch dvou proměnných vlastně null byla a často (v reálných aplikacích) na to musíme ne-zcela triviálním způsobem přijít. Zkusme si stejnou situaci nasimulovat v Kotlinu s pomocí lateinit:

    package com.svetylkovo.kotlin.lateinit
    
    object LateinitTest {
        lateinit var first: String
        lateinit var second: String
    
        @JvmStatic
        fun main(args: Array<String>) {
            first = "First!"
            println("Total length is ${first.length + second.length}")
        }
    }
    

    Když spustíme tento kód, aplikace padne na:

    Exception in thread "main" kotlin.UninitializedPropertyAccessException: lateinit property second has not been initialized
    at com.svetylkovo.kotlin.lateinit.LateinitTest.main(LateinitTest.kt:10)

    kde stacktrace mluví za vše a místo toho, abych teprve začal hledat, co se vlastně stalo špatně, okamžitě vím, že to byla proměnná second, kterou jsem z nějakého (v tomto případě záměrného) důvodu zapomněl inicializovat.

    Posuďte sami, krom toho, že nás Kotlin dokáže NullPointerException zbavit již za překladu téměř úplně, nebylo by lepší v případech, kdy už by tato výjimka musela nastat, dostávat raději UninitializedPropertyAccessException s přesným popisem viníka, který za to může? 🙂

  • TaskMan: Úkoly s důrazem na priority

    Nedávno jsem na svém githubu založil nový projekt s názvem TaskMan, na kterém budu moct důkladněji prověřit kombinaci Kotlin JS + React a který mi zároveň pomůže v mé práci vnést více světla především do priorit mých úkolů pro daný den. Neboť (někteří) možná víte, jak to chodí … Když člověka úkolují hned 3 manažeři, ne vždy musí mít stejný názor na to, co je aktuálně to nejdůležitější a ne vždy vzájemně ví, co mi zrovna zadal ten druhý (resp. třetí). Proto přichází na scénu tato šikovná webová aplikace, která jim jednak umožní se přímo po připojení na můj PC podívat, co mám zrovna v plánu, ale taky mi mé priority změnit v případě, že jsem se do jejich gusta zrovna netrefil 🙂 .

    Během vývoje jsem si osvojil fajn nové triky, jak si napsat wrapper na NPM balíčky, které nemaji default export, ale taky jak na zcela custom JS knihovny, které vůbec svůj balíček v NPM systému nemají. A jak že to vypadá? No prostě Boooootstrapově:

    A nezapomeňte … ten, kdo úkoly uspává, uvidí kočičku! 😉

  • Sekvenční grupování v Kotlinu

    Nevím, jestli oficiálně něco takového již existuje, ale alespoň já jsem tento druh problému takhle nazval 🙂 . Opět jsem nedávno narazil na problém lehce bizarního parsování dat. Řekněme, že máte list řetězců, který je ve formátu „název skupiny“, pak následuje libovolný počet prvků, pak další název skupiny atd … a chcete tento list grupovat právě podle těchto skupin, kde zároveň jediné, co znáte předem, jsou jména těchto skupin, která jsou pevně daná s tím, že některé se v listu vyskytovat můžou, anebo nemusí. Pojďme si trochu potrápit hlavy a za předpokladu, že tento list není příliš velký, zkusme daný problém vyřešit s pomocí ne-až-tolik-známých operátorů, jako jsou dropWile(), drop() a takeWhile():

            val input = listOf(
                    "Group1",
                    "1",
                    "2",
                    "3",
                    "Group2",
                    "4",
                    "5",
                    "6",
                    "7",
                    "Group3",
                    "8",
                    "9"
            )
    
            val knownGroupNames = listOf("Group1", "Group2", "Group3")
    
            val groupsMap = knownGroupNames.map { groupName ->
                val groupItems = input.dropWhile { it != groupName }
                        .drop(1)
                        .takeWhile { it !in knownGroupNames }
    
                Pair(groupName, groupItems)
            }
            .toMap()
    
            groupsMap.forEach { group, items -> println("$group contains: ${items.joinToString(", ")}") }
    

    Výstupem je:
    Group1 contains: 1, 2, 3
    Group2 contains: 4, 5, 6, 7
    Group3 contains: 8, 9

    Tak co, rozlouskli jste to? 🙂

  • Ochutnávka Kotlin JS s create-react-kotlin-app

    Ještě před pár měsíci jsem byl názoru, že Node JS a celý jeho javascriptí ekosystém je svět sám pro sebe a že jakýkoliv pokus ho převzít ze strany jazyků, které vznikaly původně na JVMku, je jen marným počínáním. To by zřejmě byla pravda, pokud bych uvážil např. samostatný Kotlin JS vs. React, kde by React sám o sobě zvítězil na plné čáře. Avšak věci se pomalu začínají měnit od chvíle, kdy byly napsány Kotlin wrappery pro React, včetně „sesterského“ generátoru projektů založených na webpacku s názvem create-react-kotlin-app, které nám nyní umožní… hádejte co? 🙂