Let’s Learn How To Code Using Kotlin — Part 003

Cody Engel
7 min readJun 10, 2017

--

Wow, can you believe we are already on our fourth installment of this series? If you are new to this series I strongly recommend going back to the introduction as each part builds off of the previous parts. In part three we are going to continue learning about control flows by learning about our first type of loop. However before we get started make sure you create a new package named part_003 and create a new Kotlin file named app. Awesome, let’s get started.

Thanks Michael Bradley over on Unsplash

What Are Loops

Loops are another type of control flow which instruct your program to do something over and over again until while some condition is true. The most common type you’ll probably use in the real world is the for loop, followed by the while loop. In the program we’ll be writing today we are going to use the do while loop, which in my experience has very limited use cases but will is perfect for what we need to do. Also, don’t worry in part 004 and 005 I intend to go into further detail about the more common loops.

Let’s Make Our Even Odd Checker Better

Up until this point our programs have had a very linear progression. We asked you for input from the keyboard, we manipulated that input, and then gave you an output. If we wanted to give the program another input we had to restart the program, that’s not really ideal and so for this program we are going to add a loop so you can provide more input without restarting.

do {
// this is where you execute your code
} while (/* some condition is true */)

Here is our basic syntax of the do while loop. We instruct our program to do something and after it has done that it will check to see if some condition is true. If the condition is true then we will return back to the start of the loop and execute that code again. This is the only loop that allows you to execute code at least once regardless of what the condition is (because we check the condition after we have executed the code). For our program we want to check if at least one number is even or odd but we may want to do that multiple times, and so this loop ends up being perfect for just that.

So let’s take part 002 and surround our code with the above syntax. After we display if a number is even or odd we will want to prompt our user if they would like to check another number, if they enter y then we will, otherwise we will exit the loop and thank the user for using our program. Go ahead and try to do this for yourself, the code below will be the solution to this problem.

fun main(args : Array<String>) {

val userInput = Scanner(System.`in`)
do {
// Prompt the user to enter a number.
System.out.print("Enter a number to evaluate: ")
val number = userInput.nextLine().toInt()

// If it is divisible by 2, then it's even
if (number % 2 == 0) {
System.out.println("$number is even!")
} else {
// Otherwise it is odd
System.out.println("$number is odd!")
}

System.out.print("Do you want to continue? (y/n): ")
} while (userInput.nextLine() == "y")

System.out.println("Thanks for using the even/odd number checker!")
}

So there are a few parts about this that are new. First we’ve surrounded the majority of our original program in the do {...} block. I left the variable declaration for userInput outside of the loop as it doesn’t make sense to re-declare that for every iteration in the loop. I also added another call to print a line asking the user if they want to continue. Then in the while (...) section I check if the userInput is equal to the character y. If it isn’t then we print another line thanking the user for using our program and then the program completes.

Your program should look fairly similar to this.

Let’s Do This The Kotlin Way

So up until this point I have been writing these articles in a fairly basic and easy to understand manner. I want to thank fellow Medium author Ľuboš Mudrák for pointing out that Kotlin offers an easier way to read and print lines from the console (the console is the thing we’ve been running our programs in). So we are going to update our program to use that new method and also introduce the idea of nullability.

So go ahead and remove the userInput variable from your program. In the places where you were calling userInput replace that with readline(). You’ll notice that IntelliJ is signaling something is not quite right, feel free to see if you can fix it (though don’t feel bad if you get stuck). Next replace all of your calls to System.out.println(...) with just println(...)and the same can be done for System.out.print(...) except it will be print(...).

Now let’s get back to those error messages you are probably still seeing. When you call readline() there is a chance that it will return null as the value. Essentially in programming null means there is nothing there, and so if you attempt to do an operation on a null value your program will crash. The idea of null has been referenced as the billion dollar mistake (because null pointer exceptions cost companies a lot of money of money), you can read more about why null was a bad idea here.

Nonetheless, this is something that we have to deal with, in older languages like Java it was a very cumbersome process, Kotlin does a lot to protect us against null. One way Kotlin does this is it won’t let you accidentally compile a program that could do operations on a null value. That is why you are getting an error message. Here is what my program ended up looking like after I guarded against null.

fun main(args : Array<String>) {

do {
// Prompt the user to enter a number.
print("Enter a number to evaluate: ")
val number = readLine()?.let { it.toInt() }

number?.let {
// If it is divisible by 2, then it's even
if (it % 2 == 0) {
println("$number is even!")
} else {
// Otherwise it is odd
println("$it is odd!")
}
}

print("Do you want to continue? (y/n): ")
} while (readLine() == "y")

println("Thanks for using the even/odd number checker!")

}

So you will notice I use a question mark before calling let. Both of these are things that help safeguard against null values. The question mark tells the program to only do something if the variable is not null, if it is null then we will not perform the operation and then number will simply be null. The let keyword allows you to pass in the value of the object (variable) and perform some operation on it. We also use the it keyword to refer to the object being passed in (in this case, the value read from the keyboard).

So in plain english val number = readLine()?.let { it.toInt() } can be read something like this: if readline is not null then let us convert it to an integer and set number to that value.

Note that there is still a chance that number can be null if readLine() was null. That is why we also call let on number on the next line. Notice that within that block it and number can be used to refer to the same thing. For now if it is easier for you to understand feel free to ignore it and just use the number variable, just know that the Kotlin way of doing things you’d likely use the it keyword instead.

So with that let me refactor this one more time to show you how else your program could look using the let and it keyword. I’m going to move the declaration of number to be within the first let block which will allow us to completely remove the second let.

fun main(args : Array<String>) {

do {
// Prompt the user to enter a number.
print("Enter a number to evaluate: ")
readLine()?.let {
val
number = it.toInt()

// If it is divisible by 2, then it's even
if (number % 2 == 0) {
println("$number is even!")
} else {
// Otherwise it is odd
println("$number is odd!")
}
}

print("Do you want to continue? (y/n): ")
} while (readLine() == "y")

println("Thanks for using the even/odd number checker!")

}

So now we are only going to run the code if readLine() is not null. Once we know it isn’t null we declare the number variable which we know won’t be null and can safely run the program as we did before. Honestly I think this way is probably the most elegant solution.

So how did you feel about this installment of learning how to code? Was it too much information, not enough, or just right? Are there any areas that you would like for me to expand on more in future articles? Once you are ready to continue, part 004 is now available.

--

--