{"id":607,"date":"2021-05-03T13:28:34","date_gmt":"2021-05-03T13:28:34","guid":{"rendered":"http:\/\/meatpie\/?p=607"},"modified":"2021-06-17T03:25:33","modified_gmt":"2021-06-17T03:25:33","slug":"weather-app-kotliny-kotlin","status":"publish","type":"post","link":"https:\/\/snersbots.co.uk\/index.php\/weather-app-kotliny-kotlin\/","title":{"rendered":"Weather App &#8211; Kotliny Kotlin"},"content":{"rendered":"\n<p>I used IntelliJ to convert to Kotlin. It gave me the class below. While it compiles and works, it does not look like Kotlin. I would like to take the resulting code and use Kotlin&#8217;s features to make it look more like Kotlin<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>The starting point is this ugly if &#8211; which has the lower clauses collapsed to fit in the screenshot. This needs to go.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"632\" height=\"395\" src=\"http:\/\/meatpie\/wp-content\/uploads\/2021\/05\/UglyIf.png\" alt=\"\" class=\"wp-image-613\" srcset=\"https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/UglyIf.png 632w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/UglyIf-300x188.png 300w\" sizes=\"auto, (max-width: 632px) 100vw, 632px\" \/><figcaption>This long if statement consists of pretty much duplicated code for minutely, hourly and daily.<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Templates<\/h2>\n\n\n\n<p>My first thought was templates. But after a little bit of scratching around I figures out the problem was not different types. All arrays are of type IntervalData, so that would not bring anything to the table. Maybe I&#8217;m wrong. I&#8217;ve not done much with templates in any language.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Base Class Method<\/h2>\n\n\n\n<p>And I could not try to implement it in the base class either, as I have called each array by different names &#8211; minutelyData, hourlyData and dailyData. I don&#8217;t want to change that. That conforms to my Objective C upbringing, where you name a variable with what it is, not some cryptic reference to it. Anyway that is not a very Kotliny solution<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">when<\/h2>\n\n\n\n<p>If you have an ugly if statement in Kotlin, the obvious starting place is <strong>when<\/strong>. This is a pretty cool piece of kit in Kotlin &#8211; it&#8217;s their answer to <strong>switch<\/strong>. <\/p>\n\n\n\n<p>I am watching a pretty cool course on Udacity: <a href=\"https:\/\/www.udacity.com\/course\/kotlin-bootcamp-for-programmers--ud9011\">Kotlin Bootcamp for Programmers<\/a>, free at the time of writing. It doesn&#8217;t nauseate you with trying to describe what a variable is. Every single concept is backed up by exercises, and it is 50% video and 50% exercises. Lesson 3 &#8216;Functions&#8217;, see &#8217;14. Compact Functions&#8217; where he takes a when statement, and ships out the logic to other variables and methods. Pretty cool. I&#8217;d like to do this if I can.<\/p>\n\n\n\n<p>I have got rid of the ugly if. . I&#8217;ve added a method called timeTilRain which takes in a time multiplier for number of minutes. But this is still not very readable, and it calculates the result twiceMore work required:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"735\" height=\"339\" src=\"http:\/\/meatpie\/wp-content\/uploads\/2021\/05\/Kotlin-when.jpg\" alt=\"Screenshot showing Kotlin when statement\" class=\"wp-image-638\" srcset=\"https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-when.jpg 735w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-when-300x138.jpg 300w\" sizes=\"auto, (max-width: 735px) 100vw, 735px\" \/><figcaption>The when statement is a lot more concise than the long ugly if statement<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">indexOfFirst<\/h2>\n\n\n\n<p>There is a function called &#8216;periodWhenIntensityExceeded&#8217; which uses a while loop. This looks like it needs a lambda:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/meatpie\/wp-content\/uploads\/2021\/05\/Kotlin-indexOfFirst-1024x114.png\" alt=\"Screenshot showing indexOfFirst functionality\" class=\"wp-image-640\" width=\"834\" height=\"92\" srcset=\"https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-indexOfFirst-1024x114.png 1024w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-indexOfFirst-300x33.png 300w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-indexOfFirst-768x85.png 768w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-indexOfFirst.png 1330w\" sizes=\"auto, (max-width: 834px) 100vw, 834px\" \/><figcaption>Nice, replaced all that waffle with an easy to read one-liner<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Kotlin Ternary Operator<\/h2>\n\n\n\n<p>It&#8217;s slightly different in Kotlin &#8211; just a case of remembering. Starts with the keyword if, and no curly braces.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"149\" src=\"http:\/\/meatpie\/wp-content\/uploads\/2021\/05\/Kotlin-ternary-if-1024x149.png\" alt=\"Screenshot showing a function with the Kotlin usage of the if statement on one line\" class=\"wp-image-646\" srcset=\"https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-ternary-if-1024x149.png 1024w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-ternary-if-300x44.png 300w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-ternary-if-768x112.png 768w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-ternary-if.png 1287w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Using if on one line is probably more readable than the standard ternary if statement<\/figcaption><\/figure>\n\n\n\n<p>Or let&#8217;s go one better and use the Elvis operator ?: This is for providing a default in the case of null.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">precipIntensity = jsonFloatValueFor(WeatherConstants.PRECIP_INTENSITY, jsonHourly) ?: 0f<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Kotlin Class Properties<\/h2>\n\n\n\n<p>You can declare the properties directly in the class parameters, by adding val or var before the variable name. Modifiers such as private, protected etc included.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"94\" src=\"http:\/\/meatpie\/wp-content\/uploads\/2021\/05\/Kotlin-class-with-props-1-1024x94.png\" alt=\"Screen shot showing the Precipitation class declared with properties\" class=\"wp-image-655\" srcset=\"https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-class-with-props-1-1024x94.png 1024w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-class-with-props-1-300x28.png 300w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-class-with-props-1-768x71.png 768w, https:\/\/snersbots.co.uk\/wp-content\/uploads\/2021\/05\/Kotlin-class-with-props-1.png 1121w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Properties declared directly in the class statement parameters. <\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Kotlin Playgound<\/h2>\n\n\n\n<p>The playground is really nice for trying out code. If you used it before on a Chromium browser and hated it, try it now. They&#8217;ve sorted out the viewing. It now is really a good experience. Nice one guys. https:\/\/play.kotlinlang.org\/<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Starting Code<\/h2>\n\n\n\n<p>Here is my starting class, as provided by IntelliJ when I clicked Convert to Kotlin.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">package com.sners.snowforecast.data\n\nimport java.util.ArrayList\n\n<em>\/\/precipIntensity: A numerical value representing the average expected intensity (in inches of liquid water per hour)\n\/\/ of precipitation occurring at the given time conditional on probability (that is, assuming any precipitation occurs at all).\n\/\/ A very rough guide is that a value of 0 in.\/hr. corresponds to no precipitation,\n\/\/ 0.002 in.\/hr. corresponds to very light precipitation,\n\/\/ 0.017 in.\/hr. corresponds to light precipitation,\n\/\/ 0.1 in.\/hr. corresponds to moderate precipitation,\n\/\/ and 0.4 in.\/hr. corresponds to heavy precipitation.\n\n\/**\n * Everything about Precipitation\n * @param inDaily daily weather data\n * @param inHourly hourly weather data\n * @param inMinutely minutely weather data\n * @param inCurrently current weather data\n *\/\n<\/em>class Precipitation(inDaily: Daily?, inHourly: Hourly?, inMinutely: Minutely?, inCurrently: Currently) {\n\n    <em>\/**\n     *  @property daily Daily weather info\n     *\/\n    <\/em>private val daily: Daily?\n\n    <em>\/**\n     *  @property hourly Hourly weather info\n     *\/\n    <\/em>private val hourly: Hourly?\n\n    <em>\/**\n     *  @property minutely Minutely weather info\n     *\/\n    <\/em>private val minutely: Minutely?\n\n    <em>\/**\n     *  @property currently Current weather info\n     *\/\n    <\/em>private val currently: Currently\n\n    <em>\/**\n     *  @property weatherHelper Helper class with useful weather functions\n     *\/\n    <\/em>private val weatherHelper = WeatherHelper()\n\n    <em>\/**\n     *  @property minPrecipLight Min precip to take into account\n     *\/\n    <\/em>private val minPrecipLight = 0.002\n\n    <em>\/**\n     *  @property minPrecipMedium Min precip to take into account if we're ignoring light precip\n     *\/\n    <\/em>private val minPrecipMedium = 0.017\n\n    init {\n        daily = inDaily\n        hourly = inHourly\n        minutely = inMinutely\n        currently = inCurrently\n\n    }\n\n    <em>\/**\n     * Time til Precipitation\n     * @param toIgnoreLightPrecip boolean\n     * @return Minutes til precipitation\n     *\/\n    <\/em>private fun timeTil(toIgnoreLightPrecip: Boolean): Long {\n\n        var minutesTilPrecip = -1\n        val minPrecip = if (toIgnoreLightPrecip) minPrecipMedium else minPrecipLight\n\n        val precipIntensity: Float = currently.precipIntensityNum\n        if (precipIntensity &gt; minPrecip) {\n            <em>\/\/ It's raining now\n            <\/em>minutesTilPrecip = 0\n        } else {\n            <em>\/\/ Check minutely\n            <\/em>if (null != minutely) {\n                val rainMinutes =\n                    periodWhenIntensityExceeded(minutely.minutelyData,minPrecip)\n                if (rainMinutes &gt;= 0) {\n                    minutesTilPrecip = (rainMinutes + 1)\n                }\n            }\n            if (minutesTilPrecip &lt; 1) {\n                <em>\/\/ Check hourly\n                <\/em>if (null != hourly) {\n                    val rainHours: Int =\n                        periodWhenIntensityExceeded(hourly.hourlyData, minPrecip)\n                    if (rainHours &gt;= 0) {\n                        minutesTilPrecip = ((rainHours + 1) * 60)\n                    }\n                }\n            }\n            if (minutesTilPrecip &lt; 1) {\n                <em>\/\/ Check hourly\n                <\/em>if (null != daily) {\n                    val rainDays: Int =\n                        periodWhenIntensityExceeded(daily.dailyData, minPrecip)\n                    minutesTilPrecip = if (rainDays &gt;= 0) {\n                        ((rainDays + 1) * 60 * 24)\n                    } else {\n                        -1\n                    }\n                }\n            }\n        }\n        return minutesTilPrecip.toLong()\n    }\n\n    <em>\/**\n     * Time til Precipitation as string\n     * @param toIgnoreLightPrecip boolean\n     * @return Formatted time string\n     *\/\n    <\/em>fun timeTilString(toIgnoreLightPrecip: Boolean): String? {\n\n        var timeTilString: String? = WeatherConstants.NONE_FORECAST\n        val timeTil = timeTil(toIgnoreLightPrecip)\n        if (timeTil &gt; 0) {\n            timeTilString = weatherHelper.formatTime(timeTil)\n        } else if (timeTil == 0L) {\n            timeTilString = WeatherConstants.NOW\n        }\n        return timeTilString\n    }\n\n    <em>\/**\n     * Period when Intensity Exceeded\n     * @param intervalData the data to search\n     * @param minValue The minimum value under which we ignore\n     * @return Integer index of element where condition was first met\n     *\/\n    <\/em>private fun periodWhenIntensityExceeded(intervalData: ArrayList&lt;IntervalData&gt;, minValue: Double): Int {\n        var periodFound = -1\n        var precipExceedsMin = false\n        var intervalCounter = 0\n        while (intervalCounter &lt; intervalData.size &amp;&amp; !precipExceedsMin) {\n            val fieldValue = intervalData[intervalCounter].precipIntensity\n            if (fieldValue &gt; minValue) {\n                precipExceedsMin = true\n                periodFound = intervalCounter\n            }\n            intervalCounter++\n        }\n        return periodFound\n    }\n\n\n\n}`<\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I used IntelliJ to convert to Kotlin. It gave me the class below. While it compiles and works, it does not look like Kotlin. I would like to take the resulting code and use Kotlin&#8217;s features to make it look more like Kotlin<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,8],"tags":[35,44,43],"class_list":["post-607","post","type-post","status-publish","format-standard","hentry","category-android","category-software","tag-kotlin","tag-kotlin-indexoffirst","tag-kotlin-when"],"_links":{"self":[{"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/607","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=607"}],"version-history":[{"count":28,"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/607\/revisions"}],"predecessor-version":[{"id":716,"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/posts\/607\/revisions\/716"}],"wp:attachment":[{"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=607"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/categories?post=607"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/snersbots.co.uk\/index.php\/wp-json\/wp\/v2\/tags?post=607"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}