Solution: Pretty time display

fun secondsToPrettyTime(seconds: Int): String { if (seconds < 0) return "Invalid input" if (seconds == 0) return "Now" // or // when { // seconds < 0 -> return "Invalid input" // seconds == 0 -> return "Now" // } val hours = seconds / SECONDS_IN_HOUR val minutes = (seconds % SECONDS_IN_HOUR)/MINUTES_IN_HOUR val secondsLeft = seconds % SECONDS_IN_MINUTE var result = "" if (hours > 0) { result += "$hours h" } if (minutes > 0) { result += " $minutes min" } if (secondsLeft > 0) { result += " $secondsLeft sec" } return result.trim() } // Constants should be defined outside of the function // we often name them using UPPER_SNAKE_CASE convention // const modifier is a low-level optimization private const val SECONDS_IN_MINUTE = 60 private const val MINUTES_IN_HOUR = 60 private const val SECONDS_IN_HOUR = 3600

This is not the only possible solution to this exercise. Especially transforming hours, minutes and secondsLeft into a string can be done in many different ways. I will show you a few popular solutions to this problem. Some of them use functions like listOfNotNull, joinToString, takeIf or buildString that are presented in the Functional Kotlin book (the next book I recommend you reading after Kotlin Essentials). Have patience, you will learn about them later, for now you can just treat them as curious examples of Kotlin code.

// Option 1 - This option is similar to the original, // but uses if as an expression, and adds strings with + val hoursString = if (hours > 0) "$hours h " else "" val minutesString = if (minutes > 0) "$minutes min " else "" val secondsString = if (secondsLeft > 0) "$secondsLeft sec " else "" return (hoursString + minutesString + secondsString).trim() // Option 2 - This option uses listOfNotNull to construct // a list of non-null elements, and then transforms those // elements into a single string using joinToString return listOfNotNull( if (hours > 0) "$hours h" else null, if (minutes > 0) "$minutes min" else null, if (secondsLeft > 0) "$secondsLeft sec" else null ).joinToString(separator = " ") // Option 3 - This option is similar to the previous one, // but uses takeIf to filter out null elements return listOfNotNull( "$hours h".takeIf { hours > 0 }, "$minutes min".takeIf { minutes > 0 }, "$secondsLeft sec".takeIf { secondsLeft > 0 }, ).joinToString(separator = " ") // Option 4 - This option uses buildString function // to construct a string by appending it with next parts // inside lambda expression block return buildString { if (hours > 0) append("$hours h ") if (minutes > 0) append("$minutes min ") if (secondsLeft > 0) append("$secondsLeft sec ") }.trim() // Option 5 - This is the most complicated option, // because it covers all possible cases in a when-expression. // I do not recommend using this solution, but I wanted to // show it as an example of how when-expression can be used. return when { hours == 0 && minutes == 0 && secondsLeft == 0 -> "" hours == 0 && minutes == 0 -> "$secondsLeft sec" hours == 0 && secondsLeft == 0 -> "$minutes min" minutes == 0 && secondsLeft == 0 -> "$hours h" minutes == 0 -> "$hours h $secondsLeft sec" secondsLeft == 0 -> "$hours h $minutes min" hours == 0 -> "$minutes min $secondsLeft sec" else -> "$hours h $minutes min $secondsLeft sec" }

Example solution in playground

import org.junit.Test import kotlin.test.assertEquals fun secondsToPrettyTime(seconds: Int): String { if (seconds < 0) return "Invalid input" if (seconds == 0) return "Now" // or // when { // seconds < 0 -> return "Invalid input" // seconds == 0 -> return "Now" // } val hours = seconds / SECONDS_IN_HOUR val minutes = (seconds % SECONDS_IN_HOUR)/MINUTES_IN_HOUR val secondsLeft = seconds % SECONDS_IN_MINUTE var result = "" if (hours > 0) { result += "$hours h" } if (minutes > 0) { result += " $minutes min" } if (secondsLeft > 0) { result += " $secondsLeft sec" } return result.trim() } // Constants should be defined outside of the function // we often name them using UPPER_SNAKE_CASE convention // const modifier is a low-level optimization private const val SECONDS_IN_MINUTE = 60 private const val MINUTES_IN_HOUR = 60 private const val SECONDS_IN_HOUR = 3600 fun main() { println(secondsToPrettyTime(-1)) // Invalid input println(secondsToPrettyTime(0)) // Now println(secondsToPrettyTime(45)) // 45 sec println(secondsToPrettyTime(60)) // 1 min println(secondsToPrettyTime(150)) // 2 min 30 sec println(secondsToPrettyTime(1410)) // 23 min 30 sec println(secondsToPrettyTime(60 * 60)) // 1 h println(secondsToPrettyTime(3665)) // 1 h 1 min 5 sec } class PrettyTimeTest { @Test fun testNegativeSeconds() { val seconds = -1 val expected = "Invalid input" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testOnlySeconds() { val seconds = 45 val expected = "45 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testOnlyMinutes() { val seconds = 60 val expected = "1 min" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testMinutesAndSeconds() { val seconds = 150 val expected = "2 min 30 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testMinutesAndSecondsWithRemainder() { val seconds = 1410 val expected = "23 min 30 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testOnlyHours() { val seconds = 3600 val expected = "1 h" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testHoursMinutesAndSeconds() { val seconds = 3665 val expected = "1 h 1 min 5 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testZeroSeconds() { val seconds = 0 val expected = "Now" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testHoursMinutesSecondsWithZeroMinutes() { val seconds = 3605 val expected = "1 h 5 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testHoursMinutesWithZeroSeconds() { val seconds = 7200 val expected = "2 h" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testMinutesSecondsWithZeroHours() { val seconds = 150 val expected = "2 min 30 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } @Test fun testLargeValue() { val seconds = 123456789 val expected = "34293 h 33 min 9 sec" assertEquals(expected, secondsToPrettyTime(seconds)) } }