Android App Development Kotlin
Android App Development Kotlin
BVOC
DRONA FOUNDATION
Sr No INDEX
1 INTRODUCTION TO KOTLIN
1.1 What is Kotlin?
1.2 First Kotlin Program
1.3 The main() Function
1.6 Comments
1.7 Errors and Bugs
1.8 Formatting Conventions
1.9 Review and Resources
Article : From Editor to Output
Concept Review
1 QUIZ
1 PROJECT : ASCII ART
1
2 PROJECT : MAD LIBS
3 PROJECT : MATH MAGIC
5 CONDITIONAL EXPRESSIONS
5.1 Introduction to Conditionals
5.2 if Expression
2
5.3 if/else Expression
6 LISTS
6.1 Introduction to Lists
6.2 Creating an Immutable List
6.3 Accessing Elements in a List
3
7 SETS
7.7 Review
8 MAPS
8.1 Introduction to Maps
8.2 Creating an Immutable Map
8.3 Retrieving Keys and Values
9 LOOPS
4
9.5 Iterating Through Maps
10 FUNCTIONS
10.1 Introduction to Functions
10.2 Creating and Calling a Function
10.3 Arguments
11 CLASSES
11.1 Introduction to Classes
11.2 Creating a Class
5
11.3 Creating an Instance
6
1. INTRODUCTION TO KOTLIN
1.1 What is Kotlin?
Take a look at the image to the right. Codey is starting on the path to Dev City
which is filled with mobile apps, websites, and other applications.
In order to reach Dev City, one must journey through various landscapes like
Variable Valley, Conditional Creek, Land of Loops, and Function Forest.
7
In fact, this journey to Dev City is quite similar to the sequence of topics you’ll
encounter throughout this course. By completing each section of this course,
you’ll have gained a strong understanding of programming fundamentals in
Kotlin.
When you’re ready to continue, hit Next.
What better way to start learning about Kotlin than to run a Kotlin program?
Before we run our first program, let’s take a moment to understand our current
environment.
Code is written and edited in something called a code editor. The code editor for
a Codecademy exercise lives in the middle of the screen. If we look at the top of
the editor, we will see the file name [Link]. The .kt extension signifies that the
file contains Kotlin code.
8
In our code editor, there is a short Kotlin program:
fun main() {
println("Hello, World!")
}
Don’t worry about understanding what this code means yet. All this program does
is print the text "Hello, World!" to the output terminal, which exists on the right
side of our screen. When we click Run, the output terminal displays our code’s
final output.
We’ll be checking the output terminal a lot to ensure our code works as expected.
1.
Hit Run to execute our first Kotlin program.
[Link]
fun main() {
println("Hello, World!")
}
OUTPUT
Hello, World!
9
Think of writing code like going on an adventure: we always need to start
somewhere.
In Kotlin, the journey begins in the main() function.
The main() function is the “jumping off” point for our code and is the first part of
our program that will execute when we run our program. It will exist in every
single Kotlin project we create; in fact, without a main() function present, the
program will return an error.
The syntax for the main() function looks like this:
fun main() {
// Code will go here
}
OUTPUT
Coding is fun!
We can even use print statements to output number values and the result of
expressions. For example:
println(5 + 5)
We’ll mainly use println() throughout this course; however, there is another
option for printing values to the output terminal: print().
The difference between println() and print() is that println() creates a new line
after outputing a value, while print() doesn’t. For example:
println("One")
print("Two")
print("Three")
Will output:
One
TwoThree
2.
In [Link], use print() to output the expression 15 * 4.
[Link]
fun main() {
// Write your code below!
12
}
OUTPUT
Just keep swimming!
60
In the snippet above, the print statement containing "Huzzah!" is the first line of
code in the main() function; therefore, it will be printed to the output terminal
first followed by "Woohoo!" and then "Yehaw!":
13
Huzzah!
Woohoo!
Yehaw!
[Link]
fun main() {
// Add your code below
OUTPUT
11/2 - AU military goes to war against local emus.
11/4 - Ambush planned by military fails.
11/8 - AU military withdraws.
14
1.6 Comments
Documenting what our code is accomplishing is a good programming practice
because it makes our code understandable for both the programmer and anyone
else who reads it.
Comments allow us to write documentation inside of our
programs. Comments can be written anywhere throughout a program and can
contain text, symbols, or even code - all of which will be ignored by the compiler.
To write a single-line comment, type // into the program followed by the
comment we want to add:
// To be or not to be: that is the question.
// symbolizes the start of a comment. Note how text that appears in a comment
has a gray font-color.
We also have the option of using a multiline comment which allows us to write
comments throughout multiple lines. Multiline comments start with /* and end
with */:
/*
If you prick us, do we not bleed?
If you tickle us, do we not laugh?
If you poison us, do we not die?
And if you wrong us, shall we not revenge?
15
2.
Create a multiline comment that describes what you have learned so far about
programming with Kotlin.
[Link]
fun main() {
println("Howdy, partner!")
}
OUTPUT
Howdy, partner!
While every programmer is different, there is one experience we all share: getting
an error message. An error, or bug, causes our programs to behave in unexpected
ways.
When we receive an error message, it’s almost always because of something we
wrote incorrectly in our code. As a result, the compiler cannot translate our
program and returns an error message.
There are many different kinds of errors we can encounter. This may sound
daunting, but luckily the Kotlin compiler provides accurate and descriptive error
messages, allowing us to quickly and efficiently locate the issue.
For example, take a very close look at the following code:
fun main() {
printlnn("To err is human.")
16
}
1.
Run the code in [Link].
We will receive an error message.
2.
17
Read the error message and fix the code in the editor so that it can execute
properly.
PS: Check the hint for additional help!
[Link].
fun main() {
println("An error a day keeps the programmer away."
}
OUTPUT
An error a day keeps the programmer away.
In programming, formatting conventions are the suggested rules for how code
should be structured in a specific programming language. By following Kotlin’s
formatting standards, or coding conventions, we can drastically improve the
readability of our programs.
Some of Kotlin’s formatting conventions include:
Indentation:
Code within curly braces should be indented 4 spaces. While the Codecademy
code editor generally uses 2 spaces, or 1 tab, for indentation, be sure to use 4
spaces when writing Kotlin code off-platform.
fun main() {
// Code starts here
}
18
If we didn’t include indentation in our program, our code would still run without
error; however, our code would look like a giant block of text making it hard to
read. As programs get larger and more complicated, indentation for the purpose
of organization becomes more essential.
Comments:
When writing a comment, add a space (" ") between // and the start of the
comment:
// Write your comment here
Curly Brackets:
When creating the main() function, place the opening curly bracket { on the same
line as the main() function construct (in this case: fun main()). The closing
bracket } should be placed on its own separate line and should be vertically
aligned with the fun keyword:
fun main() {
// Code goes here
}
Keep the above conventions in mind when writing Kotlin code throughout this
course and off-platform. We’ll encounter more formatting conventions as we
progress through this course. To learn more, check out the coding conventions
in Kotlin’s Language Guide.
19
[Link]
fun main()
{
// Organize the code below
println("Down by the bay")
println("Where the watermelons grow,")
println("Back to my home")
println("I dare not go.");
println("For if I do");
println("My mother will say")
println("Did you ever use an app that taught you how to snap?")
println("Down by the bay!")
}
OUTPUT
Down by the bay
Where the watermelons grow,
Back to my home
I dare not go.
For if I do
My mother will say
Did you ever use an app that taught you how to snap?
Down by the bay!
20
1.9 Review and Resources
Great job completing the first lesson on learning Kotlin! Let’s go over all the
content we have discussed:
• Kotlin is a general-purpose programming language.
• The main() function is the starting point of all Kotlin programs.
• When we want to output something to the terminal, we can use print
statements like println() or print().
• Code is read from top to bottom.
• Comments are used to explain what is happening in our code.
Language and syntax and rules - oh my! Learning a new language can feel
daunting; luckily, there are many online resources available to us for the Kotlin
language:
• The Kotlin Language Guide contains the official documentation for Kotlin.
• The Kotlin’s Language Guide on Formatting discusses Kotlin’s coding
conventions and formatting standards.
• The Kotlin Style Guide contains Google’s Android coding standards for
Kotlin.
• The Codecademy Forum is a great resource and friendly place where
learners can view and ask coding questions.
These language guides and resources are invaluable to programmers, and we
highly encourage keeping them at hand and referencing frequently when
developing in Kotlin.
21
Here are some ideas on what you can do:
• Create the main() function.
• Print your age by subtracting the current year and your birth year.
• Print your favorite quote.
• Add comments about what your code is accomplishing.
When you’re ready to move on, click Up Next.
__________________________
From Editor to Output
Learn what happens behind the scenes when you Run a Kotlin program.
How does a program work? From our perspective, we write some code, run it,
and then something (usually) appears in the output terminal; however, that isn’t
the full story. In this article, we’re going to break down all of the work and
processes that happen between running our Kotlin code and seeing its output.
Behind the Scenes
When we run a program, a series of processes work together to evaluate and
format the code as needed. This process varies by language, but in Kotlin it looks
like this:
First, the compiler evaluates our entire program and ensures that it does not
contain any errors. It then translates our source code to Java bytecode in the form
of .class files. These files then get passed on to the JVM.
JVM stands for Java Virtual Machine and is the software responsible for executing
Java bytecode given to it from a compiler. The JVM doesn’t understand
programming languages like Kotlin; instead, it speaks to and analyzes bytecode.
The JVM then executes these instructions in the order they were given. Once the
22
JVM completes the final instruction, it terminates - meaning our program has
been fully executed.
What happens when there’s an error?
Since Kotlin is a statically compiled language, its code gets translated and its types
are checked before run time, specifically during compilation. Any errors in our
code get caught during this phase. If the compiler recognizes an error, it displays
an error message in the output terminal and terminates the rest of the processes
as shown below:
The bytecode is never generated, the JVM is never reached, and finally, our
code’s output is not displayed. Assuming we have an error such as this one:
[Link]:25: error: expecting ')'
println("Hello, World"
^
Until we resolve this error by adding a ) and rerunning our code, we will not be
able to see any output.
No Kotlin supported IDE? No problem!
In the case that we’re off the Codecademy platform and writing our Kotlin code
locally in an IDE without a built-in converter between Kotlin and Java code, we
can rely on the bash terminal.
The bash terminal is a command language interpreter that has the ability to
execute a series of commands contained in a script or program. With Kotlin
installed, we can run a series of commands which will manually compile our code,
execute it, and display its output. Take a look at how it’s done manually.
Assume we have the following program in a [Link] file:
fun main() {
println("Hello, World!")
}
23
In the bash terminal, we can enter the first command to compile our code and
save it in a .jar file:
$ kotlinc [Link] -include-runtime -d [Link]
Note: If we make changes to our code, we’d need to recompile our program and
run the above two commands again.
24
You’ve reached the end of the article - great job! We covered a vast majority of
information that gives us insight into what happens after we run our Kotlin code.
We now understand that our Kotlin code needs to be compiled into bytecode
before it can be passed on to the Java Virtual Machine which executes the code as
instructions. IDEs often automatically compile our code, but if we don’t have that
luxury, we can use a bash terminal to manually compile and execute our program.
Next time you’re running your code, you’ll know what’s happening from editor to
output. And if you want to learn more about how to use your bash terminal,
check out our Bash courses.
__________________________
CONCEPT REVIEW
The main() Function
The main() function is the starting off point of every Kotlin program and must be
included in the code before execution.
fun main() {
// Code goes here
}
Print Statements
A print statement outputs values to the output terminal.
Using a println() statement will create a new line in the output terminal after
printing values, while a print() statement will not.
25
println("Greetings, earthling!")
print("Take me to ")
print("your leader.")
/*
Prints:
Greetings, earthling!
Take me to your leader.
*/
Comments
Comments are used to document what is happening inside of a program and are
ignored by the compiler.
A single-line comment is used to write a comment on one line, while a multiline
comment is used to write longer comments that span over multiple lines.
// This is a single-line comment
/*
This
comment
uses
multiple
lines
*/
26
Order of Execution
Code is read, compiled, and executed in top-down order.
fun main() {
println("I will be printed first.")
println("I will be printed second.")
println("I will be printed third.")
}
__________________________
[Link]
1. Fill in the code below to create a program that prints, "Salutations, good
fellow!".
Fun ______ (){
_____ ("_____")
}
• outputLine
• Salutations, good fellow!
• println
• start
• main
• Goodbye, friend
Click or drag and drop to fill in the blank
27
2. True or False: The program below will run without an error.
fun main() {
println(Hello, World)
}
a) False
b) True
b) Nine
Four
One
c) One
Four
28
Nine
d) 1
4
9
b) // I am a comment.
c) /*
I
am
a
comment
*/
d) # I am a comment
6. After running this program, which of the following choices will appear first in
the output terminal?
fun main() {
// println("First")
println("Second")
println("Third")
println("Fourth")
}
a) Third
b) First
c) Second
d) Fourth
29
__________________________
[Link]
ASCII Art
Programming and art are often viewed as opposites, but that couldn’t be farther
from the truth. Coding can be a great medium for artistic creativity! One example
of this is ASCII art.
ASCII stands for American Standard Code for Information Interchange. Its general
purpose is to give every character, from letters to numbers to symbols, its own
unique character code so that the character can be recognized in a digital space.
It can also be used to create art!
ASCII art is a drawing technique that uses a combination of different keyboard
characters to create both simple and complex images:
The ASCII image above is made up of several characters; for example, the petals
on the flower were created using (, _, and ).
30
In this project, we will be using print statements to create our own ASCII art
image in Kotlin!
TASKS
Planning the Art
1.
Decide on an image you would like to recreate via ASCII art.
For example:
o Robot
o Plant
o Cat
2.
Before we try to use print statements, let’s draft our ASCII drawing in the editor.
Create a multiline comment. Inside the comment, use different letters, numbers,
and symbols to draft out your image.
4.
Now, we’ll create our print statements.
31
For every line in the ASCII art image, use println() to create a print statement that
contains all the values that exist in that line of art.
5.
Once all the print statements are created, run the program and see how the
drawing looks!
If something doesn’t look right, now is the time to go back into the code to make
the proper edits.
Keep editing the program until you feel satisfied with the final result.
Optional
6.
Great job completing the project!
If you want to keep challenging yourself, check out these additional tasks:
o Add a background to your ASCII image.
o Recreate the ASCII art using only one print statement. To accomplish
this, you’ll need to use \n. Check out the hint below to learn more!
32
2. DATA TYPES & VARIABLES
2.1 Introduction
In this lesson, we’ll explore the building blocks of a programming language - data
types and variables. A data type represents the type of value an object possesses.
Here are a few of the types of data supported in Kotlin:
• String: a sequence of characters enclosed in double quotes
• Integer (Int): whole numbers and their opposites
• Boolean: true or false values
Each variable in a Kotlin program will possess one of these types of data. Think of
a variable as a unique, virtual container holding a certain piece of information
that can then be used and referenced throughout a program.
Take a look at the animation on the right. Each item represents a variable holding
a specific type of data dependent on its value. Codey packs their backpack with
a lunchBox holding the value "sandwich" and a waterBottle with 32 ounces of
water. tentPacked holds a Boolean value which represents if the tent is in Codey’s
backpack. With these values, we can then write a program that checks if Codey
has everything they need for their journey.
This is just one of many programs we can build with these variables. Each variable
would have its own place and purpose in a program, and their respective data
types determine how we can interact with them.
33
2.2 Declaring a Mutable Variable
Now that we’ve familiarized ourselves with the concept of variables, let’s learn
how to create a variable in Kotlin. A complete variable declaration and
initialization resembles the following form:
var variableName: Type = value
Declaration:
• The var keyword specifies the beginning of a variable declaration. It
signifies a mutable variable which means its value can change throughout
the program.
• Following the keyword is the name of the variable
in camelCase format. camelCase refers to a naming convention where the
first word is lowercased, the first letter of the second is capitalized, and so
on. It’s important to create concise, yet descriptive variable names for
readability and maintainability. A famous software engineer once said:
34
“..I will cheerfully spend literally hours on identifier names: variable names,
method names, and so forth, to make my code readable…” - Joshua Bloch
• The variable name is then followed by the type of data that the variable is
intended to store. The type must always be capital.
println(notePlayed) // Prints: B
35
Notice how we did not need to use the var keyword on the second line as it is only
used upon initial declaration. We’ve also omitted the type of data since this
information needs to only be specified once.
[Link]
fun main() {
}
OUTPUT
11/05/2023
Sunny with a few clouds
36
2.3 Declaring an Immutable Variable
Another type of variable that exists in Kotlin is the immutable variable. The term,
immutable, signifies a variable whose value cannot mutate or change after its
initialization.
Immutable variables are denoted by the val keyword and are often referred to as
constants in some languages. Here’s how they’re declared in Kotlin:
val variableName: Type = value
Let’s see an example. The following variable contains the value of the Golden
Ratio:
val goldenRatio: Double = 1.618
Since we know this value stays constant, its best to declare it with
the val keyword as opposed to var as we don’t intend on changing it. Although a
declaration with var would have also been accepted by the compiler, the
preferred strategy is to declare variables with var only if we’re certain the value
will change somewhere throughout the program, otherwise always use val.
Let’s see what happens when we try to reassign goldenRatio to another value:
goldenRatio = 3.2
The above line of code would result in the following error in the terminal stating
that reassignment is not allowed:
[Link]:3: error: val cannot be reassigned
goldenRatio = 3.2
^
37
In [Link], declare an immutable variable, pi.
• It must have a type of Double
• It must hold the value, 3.14
Note: Since we haven’t utilized this variable and only declared it, you’ll see a
Warning message thrown by the compiler stating that the variable hasn’t been
used. A Warning is different from an Error and doesn’t prevent execution of your
program. Feel free to disregard this for now; it is just Kotlin’s way of ensuring that
we don’t have any unused code in our programs.
2.
On the following line, type the variable name and reassign it a
different Double value. Observe the error in the terminal.
fun main() {
// Write your code below
}
OUTPUT
[Link]:3: error: val cannot be reassigned
pi = 5.5
In Kotlin, we can save keystrokes and optimize our variable declarations with a
feature known as type inference.
Type inference indicates that the compiler can infer the type of a declared
variable, and its data type can be omitted in the declaration. Take a look at the
following variable declaration:
38
var lightsOn: Boolean = true
We’re explicitly stating the type of variable, but the Kotlin compiler is also
intelligent enough to make this assumption even with the absence of a type:
var lightsOn = true // valid declaration
The compiler recognizes that a true or false value stored in a variable falls under
the Boolean data type, thus the lightsOn variable is a Boolean.
It’s important to know that regardless of how a variable is declared, its type
cannot change throughout a program. A Boolean variable, whether explicitly
stated or inferred, can only hold a true or false value.
If we try to assign a value that’s not a Boolean:
lightsOn = "no" // error
39
now, we’ll cover what these symbols and names mean later in the course. For
now, we’ll just use it to show the type of data that was inferred by the compiler.
Above the print() statement, declare typeTest and initialize it with any value from
this list:
• "6"
• 6
• true
• "false"
• 2.6
Observe the inferred type in the terminal. Was it what you expected?
Assign and test a few other values for typeTest.
[Link]
fun main() {
OUTPUT
String
2.5 Review
Excellent job! You’ve completed the first lesson of the Data
Types & Variables section. Let’s review what was covered.
40
• A variable declaration consists of a val or var keyword followed by a name,
colon and data type.
• A variable initialization occurs when a value is assigned to a variable using
the assignment operator (=).
• A variable declaration and initialization can happen simultaneously on one
line or separately.
• A mutable variable is denoted by the var keyword and represents a value
that is expected to change throughout a program.
• An immutable variable is denoted by the val keyword and represents a
constant value.
• Kotlin can infer a variable’s type through type inference.
Feel free to utilize the empty [Link] file and output terminal on the right to
hone your understanding of variables and data types and practice writing Kotlin
code.
__________________________
41
CONCEPT REVIEW
Mutable Variables
A mutable variable is declared with the var keyword and represents a value that is
expected to change throughout a program.
var age = 25
age = 26
Immutable Variables
An immutable variable is declared with the val keyword and represents a value
that must remain constant throughout a program.
val goldenRatio = 1.618
Type Inference
When a data type is not specified in a variable declaration, the variable’s data
type can be inferred through type inference.
// The following variable is assigned a text value within double quotes, thus the
inferred type is String
String Concatenation
String concatenation is the process of combining Strings using the + operator.
var streetAddress = "123 Main St."
42
var cityState = "Brooklyn, NY"
String Templates
String templates contain String values along with variables or expressions
preceded by a $ symbol.
var address = "123 Main St. Brooklyn, NY"
println("The address is $address")
// Prints: The address is 123 Main St. Brooklyn, NY
43
• \t Inserts a tab
• \r Inserts a carriage return
• \' Inserts a single quote
• \" Inserts a double quote
• \\ Inserts a backslash
• \$ Inserts the dollar symbol
print("\"Excellent!\" I cried. \"Elementary,\" said he.")
Arithmetic Operators
The arithmetic operators supported in Kotlin
include + addition, - subtraction, * multiplication, / division, and % modulus.
5 + 7 // 12
9 - 2 // 7
8 * 4 // 32
25 / 5 // 5
31 % 2 // 1
Order of Operations
The order of operations for compound arithmetic expressions is as follows:
1. Parentheses
2. Multiplication
3. Division
44
4. Modulus
5. Addition
6. Subtraction
When an expression contains operations such as multiplication and division or
addition and subtraction side by side, the compiler will evaluate the expression in
a left to right order.
5 + 8 * 2 / 4 - 3 // 6
3 + (4 + 4) / 2 // 7
4*2+1*7 // 15
3 + 18 / 2 * 1 // 12
6-3%2+2 // 7
// Long Syntax
batteryPercentage = batteryPercantage + 10
45
Increment and decrement operators provide a shorthand syntax for adding or
subtracting 1 from a value. An increment operator consists of two consecutive
plus symbols, ++, meanwhile a decrement operator consists of two consecutive
minus symbols, --.
var year = 2019
year++ // 2020
year-- // 2019
__________________________
[Link]
1. Which choice correctly uses an augmented assignment operator that matches
the value of the arithmetic expression below?
var volume = 2
// Turn up the volume
volume = volume + 5
46
a) year++
b) volume += 5
c) year++ 5
d) year =+ 5
[Link] data type will the compiler infer from the following variable declaration?
var learningToCode = true
a) Char
b) String
c) Int
d) Boolean
47
5. Fill in the code below to display the result of using a String property and a
String function on the variable, funFact.
fun main() {
var funFact = "kotlin is named after an island." 🏝
}
• 32
• 6
• 15
• long
• Kotlin is named after an island.
• kotlin is named after an Island.
• Kotlin
Click or drag and drop to fill in the blank
6. Which of the following two data types get assigned by default to numerical
variables?
a) Long, Float
b) Byte, Float
c) Int, Double
d) Short, Double
48
println(1 - 2) // Prints: ___-1___
println(4 * 5) // Prints: ____20__
println(9 / 3) // Prints: ____3
println(10 % 8) // Prints: ___2
}
10. Which of the following choices display the correct use of String concatenation
with the given variables?
var name = "Grace Hopper"
var year = 1952
var invention = "compiler"
a) println('In ' + year + ', ' + name + ' completed her first ' + invention + '.')
49
c) println("In " + year + ", " + name + " completed her first " + invention + ".")
11. Complete the String quote with the appropriate character escape sequences
to match this output:
"Any fool can write code that a computer can understand. Good programmers
write code that humans can understand."
– Martin Fowler
fun main() {
var quote = "_______ Any fool can write code that a computer can understand.
Good programmers write code that humans can understand._____ _____ –
Martin Fowler"
print(quote)
}
• \"
• \n
• \"
• \newline
• \'
Click or drag and drop to fill in the blank
50
c) Increment and decrement operators provide a shorthand syntax for adding
or subtracting 10 from a variable.
d) Increment and decrement operators provide a shorthand syntax for adding
or subtracting 1 from a variable.
13. What is the benefit of using String templates over String concatenation?
a) String templates resemble a more concise syntax.
b) String concatenation does not exist in Java.
c) Developers only use String templates in their code.
d) String concatenation is a deprecated feature.
__________________________
[Link]
Mad Libs
For this project, we’ll use Kotlin to write a Mad Libs word game! Mad Libs
have short stories with blank spaces that a player can fill in, giving a funny
or unique result!
In order to create a Mad Libs game, you will need a story to be completed
and a specific type of words to fill in the blanks.
For this story, you and your friend will be working for the summer to save
money for a road trip! One of your favorite bands is playing at a venue far
away and you’ll be traveling with a friend to go see them.
In order to complete the program you will have to:
• Prompt the user for specific words.
• Use your knowledge of built-in methods to work with different data types
and conversions.
51
• Print the complete story with the variables in the right places.
Note: We’ll be using the bash terminal to collect user input. For instructions
on running the program in the bash terminal, see this exercise or
instruction 10 of this project.
User Prompts
1.
In order to complete the story, you will have to prompt the user for certain
words. We’ll be gathering 7 values from the user in order to complete our
story.
Take a look at lines 6 and 7 in [Link]. Line 6 prompts the user to enter
their name and line 7 stores their answer in a variable called name.
2.
Use a print statement to prompt the user to enter a friend’s name. Below
the prompt, store their answer in a variable called friendsName.
3.
An adjective will be used to describe the nature of your trip!
Use a print statement to prompt the user to enter an adjective. Store the
answer in a variable called adjective.
4.
What city will you and your friend be driving to?!
Use a print statement to prompt the user to enter a city. Store the answer
in a variable called city.
5.
We need to know what band you and your friend will be driving to see!
Use a print statement to prompt the user to enter a band name. Store the
answer in a variable called bandName.
6.
52
For this story, you and your friend will be working for the summer to save
money for your trip! You have already stored your friend’s name in a
variable called friendsName.
Using a string template, write print statement to prompt the user to enter
what kind of job they and friendsName will do in order to save money.
Store their answer in a variable called work.
8.
We will now prompt the user for an integer between 400 and 600 to
represent the distance to be traveled, and store the value in distance.
However, since distance is expecting a value of data type Int we must
convert the value from readLine(), which is a String, into an Int.
There are a number of ways to do this, look into the Kotlin
Documentation to find some built-in methods from Integer to convert a
String into an Int.
Note: See the Hint to see an example of storing user input as an Int.
9.
Now that we know the cost of gas and the distance to be traveled, we need
to calculate how much money you and your friend need for gas!
The math to calculate the cost for gas is: (cost of gas / mileage) * distance.
Use the formula above and the variables created to find the total cost of
gas and store it in a variable called totalForGas.
10.
If we were to print the total cost for gas, it’s likely to have an unnecessary
amount of decimal places.
In order to round down the value to 2 decimal points, we can use the
following equation:
53
[Link](totalForGas * 100) / 100.00
Reassign the value of totalForGas to the result of that equation.
Note: See the Hint to see the complete syntax.
11.
You and your friend managed to save up more money than expected to
cover all costs for your trip!
Create a new variable called totalMoneySaved and set it equal
to totalForGas plus 200.
13.
In order to run our program in this exercise we will follow these 3 steps:
1. Click the Run button when the code is complete
2. Use the following command in the terminal:
kotlinc [Link] -include-runtime -d [Link]
Optional
14.
Great job completing this project. If you feel like challenging yourself,
create your own “Mad Libs” story with new variables and prompts!
54
fun main () {
print("""
A long time ago, (name) and their friend (friendName) planned a(n) (adjective)
road trip to see their favorite band: (bandName).
The venue was (distance) miles away which meant they needed to save
$(totalForGas) dollars to get there.\n
Both of them worked as (work) for the whole summer and managed to save up
a total of $(totalMoneySaved) dollars!
To celebrate, they ended up driving to (city) for the whole weekend; seeing
their band and buying (bandName) t-shirts to remember their trip.
""".trimIndent())
}
__________________________
55
[Link]
Math Magic
Up until this point, you were a Kotlin developer in training. For this project, you’ll
take on another role and become a mathemagician 🏝♂️
We’ll build a program that determines a user’s age using our knowledge of
fundamental Kotlin concepts and arithmetic operations. Take a peek at the
solution code at the end of the project if you’d like to check your answers.
Now, grab your top hat and card deck, and let’s program a magic trick!
Variable Declarations
1.
Within the main() function, declare an immutable variable, userName, and assign
it a String value of your name.
2.
Next, declare a mutable variable, magicNum, to hold a value of type, Int. Don’t
initialize the variable with a value just yet; we will do that in the next step.
Abracadabra 🧙♂️
3.
Now that we’ve declared all the variables we’ll need in this program, we’re ready
to start coding our magic trick.
The first step is to multiply the first digit of your age by 5 and assign this operation
to magicNum.
4.
56
Next, add 3 to the value of magicNum.
5.
On the following line, multiply the value of magicNum by 2 and reassign the result
back to magicNum.
6.
Add the second digit of your age to magicNum and reassign this new value
to magicNum.
7.
Finally, subtract 6 from magicNum and reassign this new value back to magicNum.
On the following line, wrap magicNum in a println() statement that outputs:
[name]'s age is [magicNum].
8.
57
OUTPUT
Galina's age is 25
58
3. USING TEXT VARIABLES
3.1 Strings & Characters
In this lesson, we’ll continue working with variables and take a deeper dive into
the data types Strings and Characters.
// Strings
// Characters
// Fun fact
60
Strings in Kotlin can stand alone or be combined with other Strings in a process
known as String concatenation. With a plus operator, +, we are able to
concatenate or append one String to another resulting in a new word, phrase, or
sentence.
Take a look at the following example:
var firstName = "Mike"
var lastName = "Wazowski"
In the code above, we’ve combined the variables, firstName and lastName to
produce a full name with the + operator. Notice how we’ve added an empty
String, " ", between the two variables to create natural whitespace between the
two words.
In addition to outputting the result of a concatenated String, we can also store
this process in a variable for later use. For example:
val userGreeting = firstName + " " + lastName + ", how are you doing today?"
println(userGreeting)
The compiler replaces each variable with its value and outputs the final String:
Mike Wazowski, how are you doing today?
61
fun main() {
val dog = "Toto"
val state = "Kansas"
val movie = "The Wizard of Oz"
}
OUTPUT
Toto, I've a feeling we're not in Kansas anymore. - The Wizard of Oz, 1939
62
Assume we’re building the following program for a travel company that provides
a user with their itinerary:
val passengerName = "Alex"
val trainNumber = 2039
val timeOfDeparture = "16:00"
val timeOfArrival = "20:00"
Each variable gets evaluated within the text producing the final itinerary
information:
Mrs. Alex will be on the 2039 train departing at 16:00 to DevCity and arriving at
20:00.
String templates are widely used and are often the preferred syntax by Kotlin
developers. Keep in mind that String concatenation is also a valid strategy, so it’s
important to be familiar with both when collaborating with others.
Make sure to replace the brackets around each variable with the correct String
template notation.
fun main() {
63
val plant = "orchid"
val potSize = 6 // in inches
val dayNum = 7
}
OUTPUT
An orchid in a 6 inch pot must be watered every 7 days.
64
3. The assignment operator, =
4. The readLine() function
The program will prompt the user with a question, accept their input with
the readLine() function and return the String input once the Enter key is pressed.
The returned String will initialize the declared variable myColor.
We can now use a String template to output the user input contained in the
variable:
println("Your favorite color is $myColor")
The first step ensures the Kotlin file is saved. The second step compiles the Kotlin
file, [Link], into bytecode and saves it in a .jar file. The third step runs the
compiled application. This process is described in more detail in this Kotlin
Tutorial.
fun main() {
println("Please type your name and hit Enter.")
// Write your code below
66
Kotlin contains built-in properties and functions that can be used with its
various data types. We’ll be looking at the most common built-in property and
function for variables of the String type. You can access the full list in Kotlin’s
documentation.
In short, a property provides information on a particular value. Kotlin supports a
single String property, length which returns the number of characters in a String.
Let’s see an example:
val tallestMountain = "Mount Everest"
print([Link]) // Prints: 13
The number of characters in "Mount Everest" equates to 13. Notice how the
whitespace is also included in the count.
In addition, a String data type also contains built-in functions that can be used to
perform certain actions on the String it’s appended on. For example,
the capitalize() function returns a capitalized String:
var name = "codecademy"
println([Link]()) // Prints: Codecademy
Note that although the returned value is Codecademy, the original lowercase
String, "codecademy", goes unchanged:
println(name) // Prints: codecademy
To persist any changes made by the function, we can reassign the result
of [Link]() to name and update the variable:
name = [Link]()
println(name) // Prints: Codecademy
67
var capitalizedName = [Link]()
println(capitalizedName) // Prints: Codecademy
Note: Characters have their own built-in properties and functions in Kotlin.
Reference this page in Kotlin’s documentation for a list of all of them.
fun main() {
var word = "supercalifragilisticexpialidocious"
68
OUTPUT
Supercalifragilisticexpialidocious has 34 letters.
In Kotlin, we have the ability to format our text with the help of character
escape sequences. When escaped, specific characters such as t and n represent
an action or command to be performed by the compiler.
Take a look at some of the following escape sequences and their operations:
• \n Inserts a new line
• \t Inserts a tab
• \r Inserts a carriage return
• \' Inserts a single quote
• \" Inserts a double quote
• \\ Inserts a backslash
• \$ Inserts the dollar symbol
When used in text, each backslash, \, and character will be recognized and
evaluated by the compiler. More than one escape sequence can be used in a
single String.
One of the most commonly used escape sequences is the \" as it allows us to cite
quotations in a String. Take a look:
print("\"May the Force be with you.\" - Star Wars, 1977")
69
Try the character escape sequence challenge below to hone your understanding
of some of these behaviors.
Dear Learner 👋,
With love,
Codey
One Rule: You can only use a single print statement. Good luck!
P.S. When you’re ready, move on to the next exercise to review what you’ve
learned and see the answer to the above prompt.
fun main() {
// Add the correct escape sequences to the text below to achieve the output
shown in the instructions
print("Dear Learner 👋, I hope you're enjoying the Learn Kotlin course. You've
made tremendous progress. Keep going! And remember, Knowledge is power.
(Frances Beacon). With love, Codey")
}
70
OUTPUT
Dear Learner 👋, I hope you're enjoying the Learn Kotlin course. You've made
tremendous progress. Keep going! And remember, Knowledge is power. (Frances
Beacon). With love, Codey
3.7 Review
Great job! You’ve completed the second lesson on variables and learned the
fundamentals of text in Kotlin. Let’s review what was covered.
• Strings are sequences of characters wrapped in double-quotes.
• A Character represents a single digit, symbol, or letter wrapped in single
quotes.
• String concatenation is the process of joining Strings using a + operator.
• String templates are used to substitute variable values within a String using
a $ symbol.
• The readLine() function is used to accept a user’s input via the bash shell.
• The built-in length property determines the number of characters in a
String.
• The built-in capitalize() function is used to capitalize the String onto which
it’s appended.
• Character escape sequences allow for the compiler to perform certain
formatting operations on a String.
Run the code in [Link] and view Codey’s message. Feel free to also use this
space to hone your understanding of text variables and practice writing Kotlin
code.
fun main() {
72
4. USING NUMBER VARIABLES
4.1 Number Types
We’ve briefly worked with integers in the previous lesson, and in this section,
we’ll take a deeper dive into the various types of numbers that exist in Kotlin.
Kotlin numbers fall into two categories: integers and decimals as part of
the Number superclass. Take a look at the image on the right. Each book occupies
a certain amount of space on the shelf depending on its size. The same goes for
the various numerical data types in Kotlin. The larger a variable is in size (Bits), the
more space it occupies in our computer’s memory.
The books on the left side represent 4 different types of data for an integer value:
Bit
Name Min Value Max Value
(Size)
-
Long 64 9,223,372,036,854…
9,223,372,036,854…
Int 32 -2,147,483,648 2,147,483,647
Short 16 -32,768 32,767
Byte 8 -128 127
73
Name Bit (Size) Decimal Digit Precision
Double 64 15-16
Float 32 6-7
A Double variable contains a longer, more precise decimal precision than a Float.
For example:
var doubleNum: Double = 6.0 / 13.0
var floatNum: Float = 6.0f / 13.0f
println(doubleNum) // Prints: 0.46153846153846156
println(floatNum) // Prints: 0.46153846
When declaring a numerical variable in Kotlin, the compiler will determine which
of the above data types to assign to it. The default type for whole numbers
is Int and the default type for decimals is Double, thus we’ll be working with these
two types of data more closely throughout this lesson.
74
4.2 Arithmetic Operators
The arithmetic operators that exist in Kotlin resemble the operators we know
from basic math. They can be used in various applications from calculating the
average test grade for a student class to determining the total restaurant bill.
Kotlin supports the following arithmetic operators:
• + addition
• - subtraction
• * multiplication
• / division
• % modulus (divides and gives the remainder)
The above arithmetic operators aside from modulus, %, should all be familiar.
Modulus is a programming symbol that is used to calculate the division and return
the remainder. For example:
println(7 % 2)
In a print statement:
println(8 - 4)
// Prints: 4
Finally, use a println() statement to output finalAmount and see the total bill.
fun main() {
// Appetizer
val caesarSalad = 8.50
// Entree
val beefStroganoff = 18
// Dessert
val cheesecake = 6
77
Most programming languages follow a certain order of operations (similar
to PEMDAS) when evaluating such expressions. In Kotlin, this order looks like:
1. Parentheses
2. Multiplication
3. Division
4. Modulus
5. Addition
6. Subtraction
You may have noticed that we skipped over the E (Exponents) in PEMDAS. This is
because Kotlin does not have an exponent operator and instead relies on
the .pow() function to calculate exponentiation. We’ll cover this more in-depth in
the following exercise.
Let’s see a few examples of compound arithmetic expressions:
println(5 + 8 * 2 / 4 - 3) // Prints: 6
println(3 + (5 + 5) / 2) // Prints: 8
println(3 * 2 + 1 * 7) // Prints: 13
Since we have division, /, and multiplication, *, side by side, the left to right order
goes into effect and the expression evaluates as such:
Keep in mind both sets of rules when creating complex arithmetic expressions.
78
4.3 Order of Operations Instructions
1.
In [Link], we’ve set up multiple arithmetic expressions that are missing
arithmetic operators.
Add an arithmetic operator in place of ___ to complete each expression.
• answer1 should be 14
• answer2 should be 3
• answer3 should be 11
Note: You will see an error in the terminal on the right if there are still
any ___ present in your code. The error should go away after you’ve replaced
each ___ with the correct operator.
fun main() {
var answer1 = 7 - 5 + 4 ___ 3
var answer2 = (9 - 3) ___ 2
var answer3 = (6 ___ 8) + (4 - 7)
println(answer1)
println(answer2)
println(answer3)
}
79
As we build upon our programs, we’ll often need to update the values of variables
following certain calculations. Assume a program that increases the current speed
of a vehicle to match a speed limit of 55:
var currentSpeed = 45
currentSpeed = currentSpeed + 10
print(currentSpeed) // Prints: 55
80
Keeping the short syntax in mind, we can now refactor and optimize our previous
program to its final, concise state:
currentSpeed += 10
println(currentSpeed) // Prints: 55
🚗💨
fun main() {
var speedOfLight = 186_000
// Write your code here
var perfectSquare = 32
// Write your code here
81
var sheldonsFavoriteNum = 219
// Write your code here
var firstCountingNum = 10
// Write your code here
82
variableName++
The decrement operator represents the subtraction of 1 from a variable using two
consecutive minus operators, --:
variableName--
This shorthand syntax is most useful with loops and conditionals - concepts we’ll
explore later in this course. For now, let’s just get familiar with the syntax.
Assume we’re writing a program that keeps track of how many apples we have in
our basket whilst apple picking. 🍎
var apples = 5
We ate a Honey Crisp apple from our basket, so let’s subtract 1 from the total:
apples--
println(apples) // Prints: 5
Note: ++ and += 1 are the same operations and can be used interchangeably
throughout a program.
Refrain from using a print statement to get the answer. Instead, check the hint for
a breakdown of the solution when you’re ready.
fun main() {
var a = 5
a += 6
var b = a * 9
var c = b / 3
c++
var d = c + 8
d %= 4
d--
For more complex mathematical calculations, we can reference the Math library
which is inherited from Java. It consists of various mathematical functionalities
that cover a range of topics from logarithms, trigonometry, statistics, and more.
Let’s take a look at some of the most commonly used functions it provides.
84
[Link]() returns the first value raised to the power of the second value. It
accepts and returns Double values.
[Link](5.0, 3.0) // 125.0
[Link]() accepts a single Double value and returns the result of rounding
that value to the nearest Integer.
[Link](15.7) // 16
fun main() {
}
OUTPUT
4.0
5.0
20
6.0
4.7 Review
Excellent work! You’ve completed the final lesson on variables and learned the
fundamentals of numbers in Kotlin. Let’s review what was covered.
• The Number superclass
contains Int, Long, Short, Byte, Float and Double data types.
86
• The arithmetic operators supported by Kotlin include +, -, *, / and %.
• Augmented assignment operators include an arithmetic and assignment
operator used to calculate and reassign a value in one step.
• The increment operator includes two consecutive plus operators, ++, used
to add 1 to a value and reassign the result.
• The decrement operator includes two consecutive minus operators, --, used
to subtract one from a value and reassign the result.
• The order of operations includes parentheses, multiplication, division,
modulus, addition and subtraction.
• The Math library is inherited from Java and contains various
mathematical functions for use in a Kotlin program.
Feel free to utilize the empty [Link] file and output terminal on the right to
hone your understanding of numbers and practice writing Kotlin code.
87
5. CONDITIONAL EXPRESSIONS
5.1 Introduction to Conditionals
88
5.2 if Expression
An if expression is a conditional that executes a body of code only when a
specified Boolean value returns true.
Assume we had a Boolean variable called raining:
var raining = true
fun main(){
var isTuesday = true
// Write your code below
90
}
OUTPUT
Take out the trash.
if (isHerbivore) {
diet = "vegetables"
} else {
diet = "meat"
}
println("This animal can eat $diet.")
The else expression is not followed by a condition since it will only run code if
the if expression’s condition is false.
This expression is always placed as the last conditional and cannot exist without
an accompanying if expression.
91
1.
Create an if expression that checks if the value of saleHappening is true.
Inside the if expression, set the value of price to 12.
2.
Underneath the if expression, create an else expression that sets the value
of price to 15.
3.
Outside of the conditional expression, use println() and a string template to
output the following statement:
The total is [price] dollars.
fun main() {
var saleHappening = false
var price: Int
// Write your code below
}
OUTPUT
The total is 15 dollars.
92
5.4 Comparison Operators
To create more complex conditions for our conditionals to evaluate, we can use
comparison operators. Comparison operators evaluate the relationship between
two values in order to return an expression as true or false.
There are several comparison operators we can use in Kotlin: <, >, >=, and <=.
The less than operator (<) evaluates to true if the value on the left side of the < is
smaller than the value on the right:
var username = "beetle"
For the greater than operator (>), if the value on the left side of the > symbol is
larger than the value on the right, the expression returns true:
var username = "beetlejuice_beetlejuice_beetlejuice"
The less than or equal to operator (<=) returns true only if the value on the left is
less than or equal to the value on the right:
var liquidTemp = 27 // Fahrenheit
93
} else {
println("The liquid will remain liquid.")
}
// Prints: The liquid will freeze.
The greater than or equal to operator >= will return true if the value on the left is
greater than or equal to the value on the right:
var liquidTemp = 50 // Fahrenheit
1.
Dungeons & Dragons is a roleplaying game that uses dice to determine the
success of a player’s action.
Create an if expression that checks if the value of d20, which represents a 20-
sided pair of dice, is greater than or equal to 17.
Inside the if expression, create a println() statement that outputs, "The
incantation works and the dragon is defeated."
2.
94
Create an else expression that contains a println() statement that outputs "The
incantation fails and the dragon wins.".
fun main() {
var d20 = 13
// Write your code below
}
OUTPUT
The incantation fails and the dragon wins.
if (userPassword == attemptedPassword) {
println("The password you entered is correct.")
}
95
On the other hand, the inequality operator (!=) is used to determine if the values
on each side of the != operator are different. This expression returns true when
the two values being compared are not equal to each other.
We can use != to check if a gathering of 9 people can evenly split 16 slices of pizza
amongst themselves:
var slicesOfPizza = 16
var numPeople = 9
if (slicesOfPizza % numPeople != 0) {
println("The pizza cannot be split evenly.")
}
// Prints: The pizza cannot be split evenly.
1.
Create an if expression that checks if the value of num1 is even.
In the body of the if expression, use println() and a String template to output the
following:
[num1] is even.
2.
96
Create a second if expression that checks if the value of num2 is odd using !=.
In the body of the if expression, use println() and a String template to output the
following:
[num2] is odd.
fun main() {
var num1 = 8
var num2 = 9
// Write your code below
OUTPUT
8 is even.
9 is odd.
An else-if expression can be used to add a plethora of more conditionals for our
program to evaluate.
Let’s say we created a Kotlin program that determines what we will wear
depending on the temperature outside. If we just use an if/else expression, our
options are limited:
97
var temp = 60
In real life, wearing a winter coat in 60-degree weather can cause a person to
overheat. We need to wear something in between a heavy coat and a t-shirt, like
a light jacket. We can place an else-if expression in our code to represent this “in-
between” situation:
var temp = 60
98
both conditions are false, the instructions in the next conditional,
the else expression, will execute.
An if-else expression can contain as many else-if expressions as needed. When
using multiple else-if statements, the order in which they appear matters. The
moment the program evaluates one of the conditionals as true, the program will
execute that body of code and will not evaluate any of the conditionals that
appear after.
1.
The local coffee shop started a rewards program based on the amount of coffee a
customer buys. Use your knowledge of conditionals to create a program that
determines what kind of member a customer is based on the amount of rewards
points they have.
If rewardsPoints is greater than or equal to 50:
• Set the value of memberType to "Platinum".
Otherwise, if rewardsPoints is greater than or equal to 25:
• Set the value of memberType to "Gold".
Otherwise, if rewardsPoints is greater than or equal to 10:
• Set the value of memberType to "Silver".
Else:
• Set the value of memberType to "Bronze".
2.
99
Outside of the conditional expressions, use println() and a String template to
output the following:
fun main() {
var rewardsPoints = 17
var memberType: String
// Write your code below
}
OUTPUT
You are a Silver type member.
100
Since isSunny is true and temp has a value above 80, the expression inside the
condition becomes true so Wear sunglasses. is outputted to the terminal.
The logical OR operator (||) will only return true if at least one of the Boolean
expressions being compared has a true value.
var isSnowing = false
var temp = 38
Even though the first value isSnowing is false, the full expression will
return true because the other Boolean expression, temp < 40, is true.
The logical NOT operator, denoted by !, will evaluate the truth value of a Boolean
expression and then return its inverse. For example:
var isSnowing = true
println(!isSnowing) // Prints: false
We can even add ! before a multi-part expression. By adding the ! operator to our
previous code example, the Boolean expression now returns a false value:
var isSnowing = false
var temp = 38
Note: The truth tables displayed on the right side of the screen display the various
outcomes of Boolean expressions being evaluated using logical operators.
101
5.7 Logical Operators Instructions
1.
Take a look at [Link].
Replace each __ with a logical operator so that each expression evaluates
to true and 4 statements are printed to the terminal.
Use the truth tables on the right side of the screen to help make a decision about
which logical operator to use.
Note: Feel free to adjust the size of the code editor to get a better view of the
code.
fun main() {
var a = true
var b = false
var c = true
var d = false
if (a __ b) {
println("Hoorah!")
}
if (!b __ c) {
println("Woohoo!")
}
if (a __ d) {
102
println("Yay!")
}
if (!(!d __ b)) {
println("Wow!")
}
OUTPUT
Hoorah!
Woohoo!
Yay!
Wow!
103
5.8 Order of Evaluation
We can combine expressions containing logical operators to create even more
complex Boolean expressions. When combining logical operators, the order of
evaluation is as follows:
1. Boolean expressions contained within parentheses
2. NOT - !
3. AND - &&
4. OR - ||
Take a look at the following snippet of code:
var isSnowing = true
var isSunny = false
104
var temp = 38
Let’s discuss the order in which this expression is evaluated. Here is the Boolean
expression we are evaluating:
!isSunny && (temp > 40 || isSnowing)
Finally, we evaluate the expression using the logical AND operator (&&). Since
both sides of the operator have a true value, the expression inside
our if statement is true and we get the final output:
Wear a coat.
1.
105
Use your understanding of logical operators and their order of evaluation to
determine the value of the expression inside of the if expression.
If you believe the program will output "Hello", set the value
of expressionValue to true.
If you believe the program will output "Goodbye", set the value
of expressionValue to false.
Finally, use println() to output the value of expressionValue.
Note: Running the code will output the answer. Make sure to declare your
variable and finalize your answer before you hit Run.
fun main() {
var expressionValue: Boolean
}
OUTPUT
Goodbye
false
106
5.9 Nested Conditionals
Similar to the concept of a “dream inside of a dream” from the movie Inception, a
conditional can exist inside of another conditional. This occurrence is called
a nested conditional.
By nesting a conditional inside of another conditional, we can achieve more
complex and precise logical solutions.
For example, remember Conditional Creek? We can use a nested conditional to
replicate this situation:
var sailColor = "red"
var sailPattern = "striped"
if (sailColor == "red") {
println("Follow the lower river.")
if (sailPattern == "striped") {
println("Then take the right path.")
} else {
println("Then take the left path.")
}
} else {
println("Take the higher river.")
}
The first conditional checks the truth value of sailColor while the nested
conditional checks the truth value of sailPattern. This program will output the
following:
Follow the lower river.
Then take the right path.
107
1.
In order to be considered a planet, a celestial body must accomplish three
things according to the International Astronomical Union:
1. Must orbit a star (like the sun).
2. Must have enough mass in order to achieve hydrostatic equilibrium (a
nearly round shape).
3. Must have enough mass to clear debris/small objects from its orbit.
The difference between a planet and a dwarf planet comes from rule 3.
In [Link] create an if expression that checks
if orbitsStar AND hydrostaticEquilibrium are true.
Leave the body of the if expression blank for now.
2.
Inside the if expression, create a nested conditional that checks if the value
of clearedOrbit is true.
Inside the body of this nested if exression, create a println() statement that
outputs "Celestial body is a planet."
3.
Underneath the nested if expression, create an else expression that
outputs "Celestial body is a dwarf planet." using a println() statement.
fun main() {
var orbitsStar = true // Rule 1
108
var hydrostaticEquilibrium = true // Rule 2
var clearedOrbit = false // Rule 3
OUTPUT
Celestial body is a dwarf planet.
when (lightColor) {
"green" -> println("Go.")
"yellow" -> println("Slow down.")
"red" -> println("Stop.")
else -> println("Not a valid traffic light color.")
109
}
// Prints: Stop.
Note how in the example above, we did not place a value inside parentheses after
the when keyword and instead placed full expressions inside the branches’
arguments.
To explore other ways we can implement a when expression in our programs,
check out the Kotlin Language Guide.
2.
Optional
Take some time to experiment with your code by changing the value
of season and running your program.
fun main() {
var season = "Fall"
// Write your code below
111
OUTPUT
Grow pumpkins.
5.11 Range
if (num in 1..10) {
println("This value is between 1 and 10.")
}
when (letter) {
in 'a'..'m' -> println("Letter is in 1st half of alphabet.")
in 'n'..'z' -> println("Letter is in 2nd half of alphabet.")
else -> println("Not a valid value")
112
}
1.
The Scoville Scale is used to measure the heat, or pungency, of a pepper.
Use if, else-if, and else expression to determine the pungency of a chili pepper
based on the pepper’s Scoville Heat Units(SHU).
If the value of sHU is between…
0-699:
• Set pungency to "very mild".
700-2999:
• Set pungency to "mild".
3000-24999:
• Set pungency to "moderate".
25000-69999:
• Set pungency to "high".
Else:
• Set pungency to "very high"
2.
Use a String template and println() to output the following statement:
113
fun main() {
var sHU = 17000
var pungency: String
OUTPUT
A pepper with 17000 Scoville Heat Units has a moderate pungency.
5.12 Review
Great job getting to the end of this lesson. Let’s review the content we learned:
• Conditional expressions control the flow of execution in a program.
• An if expression executes a block of code when the value of its condition
is true.
• An else expression executes code when none of the previous expressions
have a true value.
• Comparison operators like >, <, >=, and <= are used to compare two values
to determine a true or false value.
• The == operator checks if two values are equivalent while the != operator
checks if two values are not equivalent.
114
• The logical AND operator (&&) returns true when two Boolean expressions
being compared are both true.
• The logical OR operator (||) returns true when at least one Boolean
expression being compared is true.
• The logical NOT operator (!) negates the value of a Boolean expression.
• else-if expressions are used to add more conditions to a
traditional if/else statement.
• A nested conditional is a conditional that appears inside of another
conditional.
• A when expression evaluates the value of a variable or expression in order
to dictate the flow of a program.
• The range operator .. creates a consecutive succession of values.
__________________________
115
CONCEPT REVIEW
If Expressions
An if expression is a conditional that runs a block of code when its condition has
a true value.
var morning = true
if (morning) {
println("Rise and shine!")
}
// Prints: Rise and shine!
Else Expressions
An else expression is a conditional that runs a block of code only when the
conditions contained in the previous expressions have false values.
var rained = false
if (rained) {
println("No need to water the plants today.")
} else {
println("Plants need to be watered!")
116
}
// Prints: Plants need to be watered!
Else-If Expressions
if (age < 18 ) {
println("You are considered a minor.")
} else if (age < 60) {
println("You are considered an adult.")
} else {
println("You are considered a senior.")
}
Comparison Operators
117
Comparison operators are symbols that are used to compare two values in order
to return a result of true or false. Comparison operators include >, <, >=, <=.
var myAge = 19
var sisterAge = 11
var cousinAge = 11
Logical Operators
Logical operators are symbols used to evaluate the relationship between two or
more Boolean expressions in order to return a true or false value.
Logical operators include !, &&, and ||.
var humid = true
var raining = true
var jacket = false
println(!humid)
// Prints: false
The logical AND operator (&&) is used to compare the relationship between two
Boolean expressions and will only return a true value if both expressions are true.
var humid = true
var raining = true
var shorts = false
var sunny = false
119
The OR Operator : ||
The logical OR operator (||) is used to compare the relationship between two
Boolean expressions and will return true when at least one of the expressions
are true.
var late = true
var skipBreakfast = true
var underslept = false
var checkEmails = false
// true OR true
println(skipBreakfast || late) // true
// true OR false
println(late || checkEmails) // true
// false OR true
println(underslept || late) // true
// false OR false
println(checkEmails || underslept) // false
120
The logical NOT operator (!) evaluates the value of a Boolean expression and then
returns its negated value.
var hungry = true
var full = false
println(!hungry) // false
println(!full) // true
Order of Evaluation
The order of evaluation when using multiple logical operators in a single Boolean
expression is:
1. Expressions placed in parentheses.
2. NOT(!) operator.
3. AND(&&) operator.
4. OR(||) operator.
!true && (false || true) // false
/*
(false || true) is evaluated first returning true. Then,
!true && true is evaluated returning the final result, false.
*/
121
!false is evaluated first returning true. Then true && true are evaluated, returning
true. Then, true || false is evaluated which ends up returning true.
*/
Nested Conditionals
if (wellRested) {
println("Best of luck today!")
if (studied) {
println("You should be prepared for your exam!")
} else {
println("Take a few hours to study before your exam!")
}
}
When Expressions
122
A when expression controls the flow of code by evaluating the value of a variable
in order to determine what code gets executed.
var grade = "A"
when(grade) {
"A" -> println("Excellent job!")
"B" -> println("Very well done!")
"C" -> println("You passed!")
else -> println("Close! Make sure to perpare more next time!")
}
// Prints: Excellent job!
if (height in 1..53) {
println("Sorry, you must be at least 54 inches to ride the rollercoaster.")
}
// Prints: Sorry, you must be at least 54 inches to ride the rollercoaster.
123
Equality Operators
Equality operators are symbols that are used to compare the equivalence of two
values in order to return true or false. Equality operators include == and !=.
var myAge = 22
var sisterAge = 21
__________________________
[Link]
1. Fill in the blanks to create a program that outputs "Winter is here." when the
value of isWinter is true or "Winter is coming." when isWinter is false.
var isWinter = false
if (____) {
println("Winter is here.")
} ______ {
println(______)
}
• "Winter is coming."
• else
124
• Otherwise
• isWinter
• isSummer
Click or drag and drop to fill in the blank
125
var liquidTemp = 50 // Fahrenheit
when {
liquidTemp <= 32 -> println("The liquid will freeze.")
liquidTemp >= 212 -> println("The liquid will vaporize.")
else -> println("The liquid will remain liquid.")
}
when (liquidTemp) {
32 -> println("The liquid will freeze.")
212 -> println("The liquid will vaporize.")
else -> println("The liquid will remain liquid.")
}
126
5. When does the logical AND (&&) operator return true?
a) The expression will always return true regardless of the values of each
expression.
b) When the two expressions being compared both have a true value.
c) When at least one of the expressions being compared has a true value.
d) When the two expressions being compared both have a false value.
7. What is an if expression?
a) A variable that has a true or false value.
b) An expression that executes a block of code when a specified condition
is true.
c) An expression that executes a block of code when a specified expression
is false.
d) A function that prints values to the terminal.
if ( _______== 0) {
if (num % 3 _____ 0) {
println(______)
127
}
}
[Link] in the blanks below to make the program output "You will pass the test." if
the value of studiedNotes is true.
var studiedNotes = true
_____ ( __ ) {
println( _____ )
}
• else
• studiedNotes
• "You will pass the test."
• If
128
• "true"
Click or drag and drop to fill in the blank
when (dogWeight) {
in 1..22 -> println("Small-sized dog.")
in 22..54 -> println("Medium-sized dog.")
in 55..150 -> println("Large-sized dog.")
else -> println("Not a valid weight input.")
}
a) Medium-sized dog.
c) Large-sized dog.
d) Small-sized dog.
if (!a || b) {
println("Good morning.")
} else {
println("Good night.")
}
a) Good night.
129
b) true
c) Good morning.
d) (!a || b)
if (timeOfDay == "morning") {
println("Eat breakfast.")
} else if (timeOfDay == "afternoon") {
println("Eat lunch.")
} else {
println("Eat dinner.")
}
a) Eat lunch.
b) Eat breakfast.
c) Eat snacks.
d) Eat dinner.
if (isSunny) {
println("Wear sunscreen!")
} else {
println("Leave the sunscreen home!")
}
a) Wear sunscreen!
b) Leave the sunscreen home!
c) false
d) true
__________________________
[Link]
Self-Grading Quiz
Working at a school that has recently switched to e-learning tactics, you have
been assigned the task of creating a self-grading quiz program for the math class.
Using your knowledge of Kotlin and conditionals, you will create a program that
collects and checks a student’s answers and then gives them a final letter grade.
As you go through the project, check off the boxes next to each instruction as you
complete them.
Note: We’ll be using the bash terminal to collect user input. For instructions on
running the program in the bash terminal, see this exercise or the hint in
instruction 11.
131
Creating Quiz Questions
1.
Take a look at the variables in [Link]; each variable represents a quiz answer.
We’ll create 4 quiz questions using print statements and 4 variables that store a
user’s input.
For question 1, create a print statement that asks "What is 75 / 5?".
Then, create a variable called studentAnswer1 that stores the user’s input as a
number-based value.
Note: See the Hint to learn how to store user input as an Int.
2.
For question 2 of the quiz, ask the user for the value of y in the equation: 6 * 2y =
36
Create a variable called studentAnswer2 that stores the user’s answer as an Int.
3.
Create a third print statement that asks the user to name the type of triangle that
has two equal sides.
Store the user’s answer as String in a variable called studentAnswer3.
4.
Create a print statement that asks the user for the value of 8 * 6 - (3 - 2).
Store the user’s input as an Int variable named studentAnswer4.
132
5.
Create a variable called points and set its value to 0.
This variable will be used to keep track of the student’s score.
6.
First, let’s grade question 1.
If the value of studentAnswer1 is equivalent to quizAnswer1, increase the value
of points by 25.
7.
Let’s move on to question 2. This question gives a student multiple opportunities
to earn points.
If the value of studentAnswer2 equals quizAnswer2, increase points by 25.
However, if the value of studentAnswer2 is the value of quizAnswer2 plus or
minus 1, increase points by 20 and output the following statement:
The answer [studentAnswer2] is within 1 point of [quizAnswer2].
8.
Let’s grade question 3.
If the value of studentAnswer3 equals quizAnswer3, increase points by 25.
However, increase points by 10 if the value of studentAnswer3 is equal
to "equilateral".
Otherwise, increase points by 1.
133
9.
Let’s grade question 4.
If studentAnswer4 equals quizAnswer4, then increase points by 25.
However, if studentAnswer4 has a value between 44 and 54,
increase points by 20.
Otherwise, increase points by 1.
11.
134
Run the code in the bash terminal to test your program.
See the Hint for instructions on running the code in the bash terminal.
Optional
12.
Great job completing the project!
If you want to keep challenging yourself, check out these additional tasks:
o Create your own set of quiz questions.
o If you used a when expression to find the student’s final letter grade,
modify your code to use an if/else-if/else statement, or vice versa!
fun main() {
val quizAnswer1 = 15
var quizAnswer2 = 3
val quizAnswer3 = "isosceles"
val quizAnswer4 = 47
135
6. LISTS
6.1 Introduction to Lists
In this section, we’re going to explore the various types of collections that exist in
Kotlin. A collection is a group of elements that exist in a single structure. The first
collection type we’ll learn about is one that’s most commonly used in Kotlin and
many other programming languages: a list.
A Kotlin list is very much similar to a real-world list: it represents an ordered
collection of elements that can contain duplicates. These elements can be of any
primitive data type and represent a myriad of real-world scenarios. These can
include student grades, restaurant ratings, a to-do list of tasks, and more.
Take a look at the image on the right. After a long day of sailing through the creek,
Codey is going to set up camp and rest for the night. Being the environmentally
friendly Kotlin developer that they are, they’ve opted to make a virtual to-do list
of things they need to get done before nightfall:
var toDo = listOf("gather wood", "start a fire", "set up tent", "eat dinner",
"stargaze")
Notice how the syntax of a list in its definition is different from its output. If Kotlin
isn’t your first programming language, you might recognize the output syntax
with square brackets to be identical to that of an array.
As opposed to lists, arrays in Kotlin have a fixed size, thus not being the most
convenient or easily applicable data structure. For that reason, we’ll be focusing
136
our time on exploring lists, but we encourage you to read up on arrays in
Kotlin’s documentation.
In Kotlin, the terms “mutable” and “immutable” apply not only to variables but
also to collections. Much like an immutable variable representing a read-only
value, an immutable list contains items that must never be altered. Its syntax is as
follows:
var/val listName = listOf(value1, value2, value3)
• For a list to be used and referenced throughout a program, it must be
stored in a variable. Make sure to use keywords val or var in your
declaration as well as a descriptive list name.
137
• The creation of the Kotlin list begins on the right side of the assignment
operator with the term, listOf. This indicates an immutable list.
• The term is then followed by a pair of parentheses that holds a collection of
elements separated by commas.
• Like variable declarations, the type of list can be inferred by the compiler or
declared by the user. For example, a list of String values would be
referenced as a List<String>.
Note: Once initialized as a List<String>, the list can only hold String values.
Keeping the above syntax in mind, let’s create an immutable list of String values
that represent the countries we’ve visited:
var countriesVisited = listOf("Japan", "Colombia", "Kenya", "Jordan")
Since countriesVisited was declared a mutable variable with the var keyword, we
can reassign the value of countriesVisited to store a different list if we’d like.
However, since the list was declared immutable with listOf, the contents of the
list cannot change. They must always remain "Japan", "Colombia", "Kenya",
and "Jordan".
println(countriesVisited)
// Prints: [Japan, Colombia, Kenya, Jordan]
Lastly, when printed to the screen, the list is contained within square brackets as
opposed to parentheses.
We’ve learned a handful of rules and new concepts in this exercise. Don’t get
discouraged if it doesn’t all stick right away; we’ll be getting ample practice
throughout this lesson. Keep going, and let’s create your first Kotlin list!
1.
138
In [Link], create an immutable list containing the following water sports:
• "Wind Surfing"
• "Sailing"
• "Swimming"
• "Jet Skiing"
• "Water Skiing"
Store this list in a variable, waterSports.
2.
Output the value of waterSports on the following line using a print statement.
fun main() {
}
OUTPUT
[Wind Surfing, Sailing, Swimming, Jet Skiing, Water Skiing]
139
A collection is of no use to us if we can’t access or work with its contents. In order
to access the elements within a list, we must reference the element’s “index”.
An index represents a numerical position within a list.
val oakIslandArtifacts = listOf("Lead cross", "Rhodolite garnet brooch", "Gold
brooch")
140
[Link]: Index 5 out of bounds for length 2
1.
Every year, the United States hosts hundreds of marathons, some of which have
made it into the list of top 10 marathons worldwide. In [Link], we’ll create
a list containing some of the most popular ones.
Declare a variable, unitedStatesMarathons and in it store an immutable list
containing the following marathon names:
• "Boston Marathon"
• "Bank of America Chicago Marathon"
• "TCS NYC Marathon"
• "Marine Corps Marathon"
Fun Fact: About 0.5% percent of the U.S. Population has run a full marathon. ♀️
2.
Access "Bank of America Chicago Marathon" using square brackets and its index
in the list. Wrap this code in a print statement to see the output.
fun main() {
141
OUTPUT
Bank of America Chicago Marathon
Elements can be accessed from any list, but only with mutable lists can we change
the contents of our list by adding, replacing, or removing elements. Previously
we’ve only created immutable lists; in this exercise, we’ll learn how to create a
mutable list and alter its contents.
The syntax for declaring a mutable list is as follows:
var/val listName = mutableListOf(value1, value2, value3)
A mutable list is defined by the term, mutableListOf as opposed to listOf as we’ve
seen previously. Although the syntax and structure of mutable and immutable
lists are the same, the compiler knows which operations can or can’t be
performed on the list given the term it’s defined with.
Assume we have a list that stores a student’s daily activities:
var dailyActivities = mutableListOf("going to school", "attending tennis practice",
"reading")
Now that it’s summertime and there’s no school, we would like to update the first
element of our list to reflect the new season. We can take our previous
knowledge of accessing elements a step further and assign a new value to an
element’s indexed position with the following syntax:
dailyActivities[0] = "swimming at the beach"
The value following the assignment operator will get replaced with the current
value at the 0 index. Printing the value of dailyActivities will result in the following
output and updated list:
142
[swimming at the beach, attending tennis practice, reading]
1.
In [Link], create a mutable list, openBroadwayShows which will store a list
of shows that are available for viewing on Broadway. This list should include the
following titles:
• "The Lion King"
• "Chicago"
• "The Cher Show"
• "Les Miserables"
2.
The Cher Show has been closed as of August 2019. Let’s remove it from the list
and replace it with a show that’s still open: "Wicked".
Next, use a print statement to output the value of openBroadwayShows and see
the updated list.
fun main() {
}
OUTPUT
[The Lion King, Chicago, Wicked, Les Miserables]
143
6.5 The size Property
We can append size to majorRivers and retrieve the number of elements in the
list:
println([Link]) // Prints: 5
Additionally, this code can be used to construct an informative String about our
list:
println("There are ${[Link]} major rivers in Europe.")
// Prints: There are 5 major rivers in Europe.
Furthermore, size can be used along with an element’s index to retrieve the last
element of a collection:
println(majorRivers[[Link] - 1]) // Prints: Elbe
144
This strategy is most commonly used when iterating over a collection or simply
grabbing the last element of a list when we don’t know how many list elements
there are in total. We’ll learn more about how to iterate over a collection later in
the course.
1.
In [Link], create a variable, fruitTrees, which stores a mutable list of the
following fruit trees:
• "Apple"
• "Plum"
• "Pear"
• "Cherry"
2.
On the next line, construct the following sentence using String template syntax:
I am growing [___] different types of fruit in my garden.
Replace the value within the brackets with [Link]. Use a print statement
to output this sentence to the screen.
fun main() {
145
}
OUTPUT
I am growing 4 different types of fruit in my garden.
The contains() function accepts a single value within its parentheses and returns a
Boolean true or false depending on whether or not that value exists within a list.
It does not need to change the contents of the list, thus it can be used on an
immutable list.
println([Link]('A')) // Prints: true
println([Link]('B')) // Prints: false
The random() function also only requires read-only access and returns a random
element from the list:
146
println([Link]()) // Prints: I
The add() function accepts a single value within its parentheses and appends that
value to the end of a list:
[Link](17)
println(primeNumbers) // Prints: 4, 5, 7, 11, 13, 17
Since this function changes the contents of the list, it can only be used on mutable
lists. Similarly, the remove() function, also only used on mutable lists, accepts a
single value within its parentheses and removes it from the list:
[Link](4)
println(primeNumbers) // Prints: 5, 7, 11, 13, 17
Note: If the value to be removed does not exist, the compiler will not throw an
error and simply return false.
These functions are just the tip of the iceberg of what’s supported for lists in
Kotlin; we encourage you to look through the documentation for immutable
lists and mutable lists to explore other available functionalities.
1.
In [Link], we’ve declared a mutable list containing the names of planets
within our solar system. We’ll use Kotlin’s built-in list functions to fix some of its
inaccuracies.
147
First, use the remove() function to delete the planet that does not fit in the list.
Check the hint for help.
2.
There is one planet that’s currently missing. On the following line, use
the add() function to add it to the list.
Hint: It’s the only planet in the entire solar system with a liquid surface.
3.
Implement the random() function on the following line to generate a random
planet from the list. Make sure to wrap your code in a println() statement to see
the output.
Run your program multiple times to see the randomly generated values.
fun main() {
}
OUTPUT
Neptune
148
6.7 Review
__________________________
149
CONCEPT REVIEW
Immutable Lists
Mutable Lists
A mutable list represents a collection of ordered elements that possess read and
write functionalities.
It can be declared with the term, mutableListOf followed by a pair of parentheses
containing elements that are separated by commas.
var fruits = mutableListOf("Orange", "Apple", "Banana", "Mango")
In order to retrieve an element from a list, we can reference its numerical position
or index using square bracket notation.
Note: Remember that the first element of a list starts at 0.
var cars = listOf("BMW", "Ferrari", "Volvo", "Tesla")
150
println(cars[2]) // Prints: Volvo
The size property is used to determine the number of elements that exist in a
collection.
var worldContinents = listOf("Asia", "Africa", "North America", "South America",
"Antarctica", "Europe", "Australia")
println([Link]) // Prints: 7
List Operations
The list collection supports various operations in the form of built-in functions
that can be performed on its elements.
Some functions perform read and write operations, whereas others perform read-
only operations.
The functions that perform read and write operations can only be used on
mutable lists while read-only operations can be performed on both mutable and
immutable lists.
var seas = listOf("Black Sea", "Caribbean Sea", "North Sea")
println([Link]("North Sea")) // Prints: true
// The contains() function performs a read operation on any list and determines if
an element exists.
151
[Link]("Baltic Sea") // Error: Can't perform write operation on immutable list
// The add() function can only be called on a mutable list thus the code above
throws an error.
Immutable Sets
Mutable Sets
A mutable set represents a collection of ordered elements that possess both read
and write functionalities.
It is declared with the term, mutableSetOf, followed by a pair of parentheses
holding unique values.
var womenInTech = mutableSetOf("Ada Lovelace", "Grace Hopper", "Radia
Perlman", "Sister Mary Kenneth Keller")
152
Elements in a set can be accessed using
the elementAt() or elementAtOrNull() functions.
The elementAt() function gets appended onto a set name and returns the
element at the specified position within the parentheses.
The elementAtOrNull() function is a safer variation of the elementAt() function
and returns null if the position is out of bounds as opposed to throwing an error.
var companies = setOf("Facebook", "Apple", "Netflix", "Google")
Immutable Maps
Mutable Maps
153
A mutable map represents a collection of entries that possess read and write
functionalities. Entries can be added, removed, or updated in a mutable map.
A mutable map can be declared with the term, mutableMapOf, followed by a pair
of parentheses holding key-value pairs.
var europeanDomains = mutableMapOf("Germany" to "de", "Slovakia" to "sk",
"Hungary" to "hu", "Norway" to "no")
println([Link])
// Prints: [Parasite, Green Book, The Shape Of Water]
println([Link])
// Prints: [Bong Joon-ho, Jim Burke, Guillermo del Toro]
println(oscarWinners["Parasite"])
// Prints: Bong Joon-ho
154
Adding and Removing Map Entries
An entry can be added to a mutable map using the put() function. Oppositely, an
entry can be removed from a mutable map using the remove() function.
The put() function accepts a key and a value separated by a comma.
The remove() function accepts a key and removes the entry associated with that
key.
var worldCapitals = mutableMapOf("United States" to "Washington D.C.",
"Germany" to "Berlin", "Mexico" to "Mexico City", "France" to "Paris")
[Link]("Brazil", "Brasilia")
println(worldCapitals)
// Prints: {United States=Washington D.C., Germany=Berlin, Mexico=Mexico City,
France=Paris, Brazil=Brasilia}
[Link]("Germany")
println(worldCapitals)
// Prints: {United States=Washington D.C., Mexico=Mexico City, France=Paris,
Brazil=Brasilia}
155
7. SETS
7.1 Introduction to Sets
In this lesson, we’ll learn another fundamental Kotlin collection known as a set. A
set is an un-ordered collection of unique elements. It’s most commonly applicable
in programs that work with data sets containing non-duplicate values such as
usernames or passwords. Upon creating or adding elements to a set, the set
automatically filters out any duplicates and always returns a unique collection.
As you progress through this lesson, you’ll notice that lists and sets are very
common in syntax and share a multitude of built-in functions. Their key difference
lies in their purpose and behavior in a program. A developer building a program
for a subway line’s train stops may choose to work with a list since trains often
cross paths, whereas a program that stores bank account information would most
likely be utilizing a set.
As we continue exploring other types of collections in Kotlin, keep in mind the
similarities and differences between each one you’ve learned. A good developer
doesn’t waste time memorizing every syntax in the book, but instead, focuses on
understanding what tools are available and how they can be applied to a
program.
156
7.2 Creating an Immutable Set
157
As previously discussed, Kotlin collections fall under two categories: mutable and
immutable, and sets are no exception. An immutable set is declared using
the setOf keyword and indicates a set whose values cannot change throughout a
program:
var/val setName = setOf(val1, val2, val3)
Note: Similarly to lists, the set type can be inferred by the compiler or declared in
the code. For example, a set comprised of String values would be inferred as
a Set<String>.
In the code below, we are creating a new set and storing it in the
variable, colorsOftheRainbow:
var colorsOfTheRainbow = setOf("red", "orange", "yellow", "green", "blue", "red")
Logging colorsOfTheRainbow to the console, notice that there is one less color in
the set. The last element, "red", was a duplicate String that the set object
recognized and removed:
println(colorsOfTheRainbow)
1.
In [Link], declare a variable, obsoleteTech, and assign it an immutable
set with the following values:
• "Rolodex"
• "Phonograph"
• "Videocassette recorder"
158
• "Video projector"
• "Rolodex"
2.
Output the value of the set using a print statement. Notice how there’s one less
item in the final set.
fun main() {
}
OUTPUT
[Rolodex, Phonograph, Videocassette recorder, Video projector]
Unlike lists, a set is an un-ordered collection, thus we can’t use square brackets
and indices to retrieve its elements. However, a set is an intelligent tool that
stores its elements in the order in which each element was inserted. We can
utilize this order along with a function, elementAt(), to access and retrieve
elements.
The elementAt() function accepts an Integer value and returns the element at
that position. This function is useful for collections that do not possess index
access.
[Link](integer)
159
Assume we’re writing a program that keeps track of animals that are no longer on
the endangered list:
var nonEndangered = setOf("Louisiana Black Bear", "Northern Brown Kiwi", "Gray
Wolf", "Arabian Oryx")
To retrieve the animal, "Gray Wolf" , we’d use the following syntax:
[Link](2) // Gray Wolf
Exception error:
Exception in thread "main" [Link]: Collection
doesn't contain element at index 5.
To avoid this, we can use the elementAtOrNull() function, a safer variation
of elementAt() to return null as opposed to an error when an element does not
exist in the set:
[Link](5) // null
1.
In [Link], declare a variable, islandsOfHawaii, and assign it an immutable set
containing the following elements:
160
• "Maui"
• "Lanai"
• "Oahu"
• "Kauai"
2.
On the following line, retrieve the island of Oahu from the set using
the elementAt() function and its position.
Wrap this code in a print statement to see the output.
3.
Use the elementAtOrNull() function to retrieve an element from the 6th position.
Wrap this code in a print statement to see the output. You should not see an
error in the terminal.
fun main() {
// Write your code below
}
OUTPUT
Oahu
null
161
7.4 Creating a Mutable Set
With immutable sets, we don’t have much control over the contents they store,
but with mutable sets, we are able to add, remove, or replace as many elements
as we’d like. This allows us to work both with sets that are populated with values
and empty sets, which are sets that are initialized without any values but can be
populated at a later time.
To initialize an empty mutable set, we’d use the following syntax:
var/val setName = mutableSetOf<Type>()
• The term, mutableSetOf is used to declare a mutable set.
• The term is followed by the type of data that we expect the set to hold and
a pair of empty parentheses.
Assume we’re developing a program for a building manager who would like to
keep track of the apartments they own. Unfortunately, we haven’t received the
apartment information from them just yet, so we create a mutable set and wait
until we can populate it with values:
var totalApts = mutableSetOf<String>()
While we wait, let’s practice declaring a set that comes prepopulated with values.
The syntax is as follows:
var/val setName = mutableSetOf(value1, value2, value3)
No need to specify the set type here as it will automatically be inferred by the
compiler. Let’s see an example:
var nycRadioStations = mutableSetOf(106.7, 101.1, 97.1, 103.5)
The compiler will infer mutableSetOf<Double> from the code above and will only
accept values of type Double within this set going forward.
162
7.4 Creating a Mutable Set Instructions
1.
In [Link], create a mutable set, apolloLandingSites, populated with the
following String values:
• "Mare Tranquillitatis"
• "Fra Mauro"
• "Hadley/Apennines"
• "Descartes"
• "Taurus-Littrow"
• "Oceanus Procellarum"
2.
Output the values of the set using a print statement. Think about what type of
Kotlin program can be written with this data.
fun main() {
OUTPUT
163
[Mare Tranquillitatis, Fra Mauro, Hadley/Apennines, Descartes, Taurus-Littrow,
Oceanus Procellarum]
To add or remove any elements from a set, we must utilize Kotlin’s built-in
set functions. Luckily, many of these functions can also be applied to other
collection types, thus you might recognize some of these syntaxes from a previous
lesson.
To add a single element to a set, we’d use the add() function as we did in the lists
lesson; however, if we were interested in adding many elements to a set at once,
the addAll() function would be more appropriate. Note that in contrast to lists, we
cannot add an element that already exists in the set.
Let’s take a look at how addAll() works. Recall the building example from the
previous exercise. The manager got back to us with the following list of
apartments:
var aptList = listOf("1A", "1B", "1C", "2A", "2B", "2C", "2C", "1A")
We’re ready to populate our empty set, totalApts, with these values. With the
help of the addAll() function, we’re able to populate our set with multiple values
at once:
[Link](aptList)
Looks like the manager may have accidentally added duplicate apartment
numbers. Luckily, the set removed the duplicate elements, and we’re left with
unique data.
164
Oppositely, we can also remove all elements from a collection using
the clear() function. Assume the building is selling their property and all of the
apartments need to be removed from the data set:
[Link]()
println(totalApts) // Prints: []
addAll() and clear() are highly useful, quick, and efficient ways of adding or
removing large amounts of data from a collection at once.
1.
Codey and his friends want to host a talent show, but before they proceed, they
need to ensure that there are at least 5 participants. They’ve gathered the
following list of names in [Link].
It’s our job to ensure that no name appears twice and that there are enough
participants for the show to take place.
First, use the addAll() function to add all of the list names to
the uniqueParticipants set at once.
2.
On the following line, use the size property to determine how many participants
are in the set. Create the following String template and wrap it in
a println() statement:
"The talent show has [[Link]] unique participants."
165
3.
Great Work! Since there were more than 5 unique participants, the talent show
was able to take place, and Codey won for knowing all 88 constellations by heart.
⭐️
Now it’s time to clear all of the participants from the set. On the following line,
use the correct function to empty the set.
Use a println() statement to output uniqueParticipants and ensure all values have
been cleared.
fun main() {
}
OUTPUT
The talent show has 5 unique participants.
[]
166
In addition to adding and removing elements from a set, the set collection
supports a myriad of other functionalities. You can find the entire list in
Kotlin’s documentation.
In this exercise, we’ll explore some of the most common set functions using the
following example:
var numbers = setOf(10, 15, 20, 25)
To retrieve, the first element of any set, we can use the first() function:
[Link]() // 10
To retrieve the last element of any set, we can use the last() function:
[Link]() // 25
Finally, if we’d like to sum up all of the elements in a set, we can use
the sum() function:
[Link]() // 70
Note: To see the output of each function call on a set, it must be wrapped in a
print statement.
1.
In [Link], we’ll write a program that determines if a class has failed or
passed a midterm.
First let’s gather the grades, and store them in a mutable set, testGrades, with the
following numerical values:
167
• 65
• 50
• 72
• 80
• 53
• 84
2.
Next, we’ll utilize the following formula to declare 3 variables that we’ll use to
calculate the average:
average = sum /number of elements
• First, declare the variable, sum, and within it store the result of calling
the sum() function on testGrades.
• Declare the variable, numStudents, and within it store the result of using
the size property on testGrades.
• Finally, declare the variable, average and assign it the division expression
of sum divided by numStudents.
3.
Lastly, set up a conditional that follows this logic:
• If the average grade is less than 65, then output the text, "Failed".
• Otherwise, output the text, "Passed".
fun main() {
7.7 Review
Great job! In this lesson, we’ve learned the following concepts:
• A set is an unordered Kotlin collection that stores unique elements.
• An immutable set is declared with the setOf keyword and indicates a set
whose values cannot change throughout a program.
• A mutable set is declared with the mutableSetOf keyword and indicates a
set whose values can be altered.
• Elements within a set can be accessed using
the elementAt() or elementAtOrNull() functions.
• The addAll() and add() functions are used to add elements to a collection.
• The first() and last() functions return the first and last elements of a
collection.
• The clear() function removes all elements from a collection.
You’ve now covered the second major collection that exists in Kotlin as well as
many other programming languages. Feel free to utilize the empty [Link] file
and output terminal on the right to hone your understanding of sets and practice
writing Kotlin code.
169
fun main() {
// Write your code below
170
8. MAPS
8.1 Introduction to Maps
The final collection we’ll cover in this section is a map. A map consists of a group
of key-value pairs where each key corresponds to a single value. A key-value pair
is referred to as an entry and resembles two connected pieces of data where a
key is a unique identifier, and the value represents its corresponding data.
Maps are applicable in a variety of programming scenarios and their syntax
resembles that of real data from the web. Take a look at the image on the right.
The legend is in the form of a Kotlin map, and it provides information about the
type of animals the journeyer should expect to encounter and watch out for in
their path.
The name of each place is in the form of a key, and each corresponding animal is
the value. Notice how data in a Kotlin map is enclosed within curly braces as
opposed to square brackets for lists and sets.
In this lesson, we’ll explore other unique characteristics of the map collection as
well as how to declare a map and utilize its various built-in operations.
171
8.2 Creating an Immutable Map
• Within the parentheses must exist unique keys along with their
corresponding values.
• The to keyword is used to link each key to its value.
• Each entry must be separated by a comma.
172
Note: The keys within a map must be unique, however, the values can duplicate.
To apply what we’ve learned so far, let’s create a map of instruments:
var instruments = mapOf("String" to "Cello", "Brass" to "Saxophone",
"Woodwinds" to "Flute")
Notice how…
• Each key is linked to its value with an = as opposed to the to keyword used
in the original declaration.
• The map is wrapped in curly braces as opposed to square brackets or
parentheses.
1.
In the previous exercise, we saw the following legend on a map:
{valley=scorpions, creek=snakes, forest=bears}
This code represents the output of a Kotlin map. In [Link], let’s write code to
reproduce this output.
First, declare a variable, codeysMap, and assign it to an immutable map with the
above key-value pairs.
2.
173
Next, wrap the name of the map in a println() statement to confirm that we’ve
generated the expected output.
fun main() {
// Write your code below 🏝
}
OUTPUT
{valley=scorpions, creek=snakes, forest=bears}
As we’ve seen with other collection types in Kotlin, we are able to retrieve and
access the contents of a collection with the help of built-in functions and other
tools. With the map collection, we are able to retrieve a value using the
shorthand [key] syntax.
Assume the following example that holds famous band names as keys and lead
singers as values:
var leadSingers = mapOf("The Rolling Stones" to "Mick Jagger", "Blondie" to
"Debbie Harry", "Queen" to "Freddie Mercury")
174
If we’re building an application that will display the names of the bands at the top
of the page, we can gather all keys at once using the keys property:
[Link] // [The Rolling Stones, Blondie, Queen]
Similarly, a set of all map values can be returned using the values property:
[Link] // [Mick Jagger, Debbie Harry, Freddie Mercury]
Each expression can be wrapped in a print statement to see its output or stored in
a variable for later use.
1.
In [Link], we’ve declared a map containing various forms of unique
transportation in different countries. Retrieve a transportation mode that exists in
Peru and wrap it in a print statement using a String template:
"A unique mode of transportation that exists in Peru is mapName[key]."
Make sure to replace the placeholders, mapName and key, with the correct
names.
2.
On the following line, output all keys from the uniqueTransport map using a single
property. Wrap this code in a println() statement.
175
Next, output all values from the map using a single property. Wrap this code in
a println() statement as well.
fun main() {
var uniqueTransport = mapOf("India" to "Tuktuk", "Egypt" to "Felucca", "Peru"
to "Totora Boat", "Hong Kong" to "Junk Boat")
}
OUTPUT
A unique mode of transportation that exists in Peru is Totora Boat.
[India, Egypt, Peru, Hong Kong]
[Tuktuk, Felucca, Totora Boat, Junk Boat]
As we’ve seen with lists and sets, a map can be declared mutable or immutable.
So far, we’ve only worked with maps whose entries are used for read-only
operations. Let’s explore how to declare mutable maps and have more control of
the data they hold.
To declare a mutable map, use the term, mutableMapOf in a map declaration:
var/val mapName = mutableMapOf(key1 to val1, key2 to val2, key3 to val2)
176
The above syntax can be used to declare the following mutable map of students
and their age:
var students = mutableMapOf("Willow" to 15, "Elijah" to 17, "Florence" to 16,
"Muhammed" to 15)
Using the [key] syntax, we are able to retrieve and reassign key values. Assume
Willow just celebrated her birthday and turned 16. We can update the age value
as so:
students["Willow"] = 16
Notice how we’ve used the assignment operator to assign a new value to the
key, "Willow".
Note: In a mutable map, values can be updated, however, keys can never change.
In order to update a key, the pair must be removed entirely and re-added. In the
next exercise, we’ll see how to add and remove values from a map.
Instructions
1.
In [Link], declare a mutable map, tvShows that will store key-value pairs of a
show’s name and its total number of episodes. Use the following information to
populate your map:
• "The Big Bang Theory": 278
• "Modern Family": 250
• "Bewitched": 254
• "That '70s Show": 200
2.
177
The Big Bang Theory’s final, 279th episode, aired on May 16th, 2019. Update the
value of this show in the map.
On the following line, wrap tvShows in a print statement to see the final map.
fun main() {
OUTPUT
{The Big Bang Theory=279, Modern Family=250, Bewitched=254, That '70s
Show=200}
Since a mutable map supports read and write operations, we are able to
manipulate its contents by adding or removing key-value pairs.
Assume we have the following mutable map that stores a country’s national tree:
var nationalTrees = mutableMapOf("Italy" to "Strawberry Tree", "Greece" to
"Olive", "Romania" to "Oak", "Canada" to "Maple")
We can utilize Kotlin’s built-in put() function to add a new entry to the mutable
map:
[Link]("Albania", "Olive")
Within the parentheses of the put() function, we’ve placed the key followed by a
comma and the value. The key-value pair will be added to the end of the map.
178
Say that for our program, we only need to track national trees in Europe. To
remove "Canada" from the map, we can use the remove() function:
[Link]("Canada")
Notice how we only need to specify the unique identifier, or key, for the pair
rather than the entire entry.
Outputting the final map with a println() statement will result in:
{Italy=Strawberry Tree, Greece=Olive, Romania=Oak, Albania=Olive}
Explore the other various map-specific operations here, as well as other general
map supported functionalities in Kotlin’s documentation.
1.
In [Link], we’ve populated a mutable map of famous paintings
in MoMa and their painters. We’ll use our knowledge of adding and removing
entries to update this map.
The if expression utilizes one of map’s built-in functions, containsValue(), to check
if a painting by Claude Monet does not exist in the map.
Within its body, use another function to add, "Water Lillies", painted by Claude
Monet to the map.
2.
The Mona Lisa permanently resides at The Louvre in Paris, France, and not at the
MoMA. Remove the key-value pair associated with this painting.
179
On the following line, use a print statement to output the final map.
fun main() {
// Write your code below 🏝
if () {
// Write your code for Step 1 here
}
OUTPUT
{Les Demoiselles d'avignon=Pablo Picasso, The Starry Night=Vincent Van Gogh,
The Persistance of Memory=Salvador Dali, Water Lillies=Claude Monet}
8.6 Review
Woohoo! Excellent work. You’ve completed the final lesson on collection types in
Kotlin. Let’s review what was covered:
180
• A map is a collection that stores key-value pairs of data.
• The keys within a map must be unique, however, the values can duplicate.
• An immutable map is declared with the mapOf keyword and indicates a
map whose entries cannot change throughout a program.
• A mutable map is declared with the mutableMapOf keyword and indicates
a Map whose entries can be altered.
• Values within a map can be accessed using shorthand [key] syntax.
• To return all the values in a map, use the values property. To return all the
keys in a map, use the keys property.
• The put() function accepts a key and a value to add to a map.
• The remove() function accepts a key and removes the entry associated with
that key.
You’ve now covered the third and final major collection that exists in Kotlin. Feel
free to utilize the empty [Link] file and output terminal on the right to hone
your understanding of maps and practice writing Kotlin code.
__________________________
181
[Link]
1. Fill in the blanks to add and remove entries from the given map.
var fictionMovies = ______ ("Action and Adventure" to "Jumanji", "Drama" to
"The Martian", "Fairytale" to "The Beauty and the Beast", "History" to "Hidden
Figures")
• :
• clear
• put
• ,
• "History"
• remove
• mutableSetOf
• "Fairytale"
• mapOf
• mutableMapOf
Click or drag and drop to fill in the blank
182
2. True or False: The map collection supports the properties, keys and values, that
are used to return a map’s keys and values in the form of a set.
a) True
b) False
4. Select the group of data that would best be stored in a map collection over a
list or set.
a) A group of all unique usernames.
b) A group of all usernames including duplicates.
c) A group of usernames and their corresponding email addresses.
183
c) A mutable list must be shorter in size than an immutable list since its
contents can change throughout a program.
d) A mutable list possesses read and write functionalities, however, an
immutable list possesses read-only functionalities.
7. Fill in the blanks with the type of Set needed for this program.
var womenInTech = _______("Ada Lovelace", "Grace Hopper", "Radia Perlman",
"Sister Mary Kenneth Keller")
[Link]("Katherine Johnson")
_____[_____]
• 3
• searchEngines
• 1
• "Yahoo"
• listOf
• searchengines
184
• 2
Click or drag and drop to fill in the blank
9. To retrieve a single element from a set, we can use the elementAt() function
where the position of the element would be specified between the parentheses.
Why are we able to specify the position of an element if a set is an unordered
collection?
var cuisines = setOf("French", "American", "Italian", "Carribean")
[Link](2) // Prints: Italian
11. Fill in the blanks to retrieve the value "The Big Apple" from the map.
var cityNicknames = mapOf("Denver" to "The Mile High City", "Seattle" to
"Emerald City", "Philadelphia" to "City of Brotherly love", "New York City" to "The
Big Apple")
185
cityNicknames _______ _________ _______
• }
• [
• "New York City"
• "Seattle"
• {
• "The Big Apple"
• "Denver"
• ]
Click or drag and drop to fill in the blank
__________________________
[Link]
Animal Sanctuary
Did you know that chimpanzees share 95 to 98 percent of the same DNA with
humans? Chimpanzees are some of the most intelligent, skillful, and remarkable
animals on the planet and its paramount that we do everything in our power to
protect and cherish their species.
For this reason, we are going to take a virtual trip over to Africa, home to many
chimpanzees, and volunteer at an animal sanctuary where we’ll be taking special
care of chimps. To do right by the chimps and be as successful as possible in our
role, we decide to write a Kotlin program that will help us keep track of the
chimps we’re caring for and our daily responsibilities.
186
We’ll have Bonnie, Jubilee, Frodo, and Foxie: 4 young chimpanzees in our care.
Foxie is the youngest of the group so she will require some extra attention.
Our program will ensure that during our shift we’ve…
• Fed all the chimps
• Played a random game with them
• Conducted a health check on Foxie
If at any point you’d like to reference the solution code, be sure to check out the
link in the final step. Good luck!
2.
Next, we’ll declare 3 variables to keep track of our time and how many
responsibilities we’ve completed.
First, declare a variable, responsibilitiesComplete, and assign it the value, 0.
Additionally, declare a variable, timeSpent, and also assign it the value of 0.
As we go through our program and check off tasks, we’ll add to these values.
187
Finally, declare a variable, totalShiftTime, which represents the hour length of our
daily shift. Set this value to 4. This value will not change throughout the program.
3.
Finally, we’re going to need to create the following two map collections:
o foxiesHealthCheck should be defined as an empty mutable map
with String keys and Any? values. Specifying Any? will allow us to
store a value of any type. We will add data on Foxie’s well being to
this map later in the project.
o chimpsHaveEaten should be defined as a mutable map populated
with the following values:
o "Bonnie" to false
o "Jubilee" to false
o "Frodo" to false
o "Foxie" to false
5.
Now it’s time to feed the chimps one by one. We’ll start with Bonnie. Construct
another print statement that relays this information:
188
Feeding Bonnie....
Following this print statement, write code to update the "Bonnie" key in the map
to hold the value true now that she’s been fed.
Repeat this process for each chimp in the map.
6.
Before we move on to the next responsibility, we must track the time that it took
and how many responsibilities we’ve completed thus far.
We spent an hour feeding all the chimps. Add 1 to timeSpent.
We’ve completed a single responsibility; also add 1 to responsibilitiesComplete.
Lastly, create a println() statement that outputs the following text:
All chimps have now been fed! You've completed [responsibilitiesComplete]
/ [total responsibilities]) responsibilities.
8.
189
Next, the chimps will get to play a random game that’s fun and stimulates their
thinking.
First, declare a set, games, containing the following values:
o "tug-of-war with a blanket"
o "catch and throw"
o "number game"
On the following line, use a function on games to return a random game from the
set. Store this code in a variable, randomGame.
Lastly, add a print statement to output the value of randomGame to see which
game the chimps will play.
9.
While the chimps finish their game, let’s write code to wrap up this task by
updating the time spent and the responsibilities we’ve completed thus far.
We’ve spent an hour preparing the game and playing with the chimps.
Add 1 to timeSpent.
Since we’ve completed another responsibility, also
add 1 to responsibilitiesComplete.
Lastly, create a print statement that outputs the following text:
Each chimp has now played a game of [randomGame]! You've completed
[responsibilitiesComplete] / [total responsibilities] responsibilities.
190
Add a print statement specifying what task needs to be accomplished now. Within
the print statement, write code to output the third responsibility:
Next, responsibilities[index].
11.
To do a health check on Foxie, we need to measure her temperature and assess
her mood. As we complete each task, we’ll update the foxiesHealthCheck map
with information on how she’s feeling today. Let’s get started.
Grabbing the thermometer and applying it under her arm, we see that Foxie’s
temperature is 32.7. Let’s write code that adds a "temperature" key with a value
of 32.7 to the map.
Next, assessing Foxie’s mood, we conclude that she’s in a “happy” state. Let’s
write code that adds a "mood" key with a value of "happy" to the map.
Finally, let’s add a print statement to relay our findings:
Foxie has a temperature of [temperature] and is feeling [mood].
12.
Now that we’ve completed the final task, let’s update the time spent and the
responsibilities we’ve completed.
We’ve spent an hour completing the health assessment. Add 1 to timeSpent.
Similarly, add 1 to responsibilitiesComplete.
Lastly, create a print statement that outputs the following text:
You've now completed [responsibilitiesComplete] / [total responsibilities]
responsibilities.
191
Wrapping Up
13.
Finally, we’ll add some logic to or program to check if we’ve completed all of our
responsibilities on time.
Set up an if-else expression with an else-if condition that accomplishes the
following:
o Check if the timeSpent was less than or equal to totalShiftTime and if
all of the responsibilities were complete.
o If so, output text that congratulates the caregiver on a great job of
completing the responsibilities on time.
o Check if the timeSpent was greater than or equal
to totalShiftTime and if all of the responsibilities were complete.
o If so, output text that states that all responsibilities were complete
but with overtime.
o In all other cases, output text that says all of the responsibilities were
not complete and took extra time.
14.
Excellent work! You’ve completed the project and built a useful program for
tracking the responsibilities of a caregiver.
Run your program several times to ensure it’s working as expected. You may see
that the text is all jumbled together. Use your knowledge of escape sequences to
format some of the print statements to your liking.
Finally, test your code with different values for timeSpent and see the different
outcomes for the random games.
Optional Challenges
15.
192
If you’re up for a challenge, check out these additional tasks:
o A chimp’s average body temperature is 32.7 degrees Celsius.
Anything higher than that should be notified to the vet. Add this logic
to the program.
o Optimize parts of your program as you see fit. For example, how can
we improve upon and avoid the repetitive use
of [Link]?
o Add an additional responsibility to the list and adjust the project as
needed.
fun main() {
// Write your code below 🏝
OUTPUT
193
number game
Each animal has now played a game of number game. You've completed 2 / 3
responsibilities.
Awesome work! You've completed all of your responsibilites for the day, and you
can clock out.
194
9. LOOPS
9.1 Introduction to Loops
Why write 100 lines of code when you can write 2? When we come across code
we want to repeat, we can rely on loops. Loops give us the ability to repeat
specified blocks of code as many times as we want.
Let’s say we wanted to output elements in a list. The process wouldn’t be that
bad if the list had 5 elements. We could write five println() statements. What if
the list had 100 elements? Or 1,000? Or even 100,000?!
Loops answer the call when we need to repeat a task over and over again, even if
it is millions of times.
In this lesson, we will look at loops that will repeat code a defined number of
times or based on a specific condition. We will look at how to combine loops to
obtain a higher number of repetitions as well as how to exit loops early or skip
code repetitions.
By the end of this lesson you will understand the best way to repeat tasks in a
controlled manner while keeping your code organized and readable.
195
9.2 for Loop
When we know how many times we want a section of code to repeat, we often
use a for loop.
A for loop starts with the for keyword and is followed by a statement that defines
a loop variable followed by identifying an iterator:
for(i in 1..4) {
println("I am in a loop!")
}
196
• We define i as the loop variable. This variable holds the current iteration
value and can be used within the loop body.
• The in keyword is between the variable definition and the iterator.
• The range 1..4 is the for loop iterator.
An iterator is an object that allows us to step through and access every individual
element in a collection of values. In most cases, the iterators we use
in for loops are ranges and collections. In this example, the range has 4 elements
so the for loop repeats 4 times:
I am in a loop!
I am in a loop!
I am in a loop!
I am in a loop!
It is important to note that the loop variable only exists within the loop’s code
block. Trying to access the loop variable outside the for loop will result in an error.
Here is an example of using the loop variable within the loop body:
for (i in 1..4) {
println("i = $i")
}
While the above example uses literal numbers 1..4 to define the range, we can
also use variables to define the boundaries of our loop’s range, giving us more
dynamic control over our loop’s iteration:
var num = 4
for (i in 1..num) {
println("i = $i")
}
197
i=1
i=2
i=3
i=4
1.
Create a for loop that outputs "Hello, Codey!" five times.
Make sure to use:
• i as the loop variable.
• The range 1 through 5 as the iterator.
• a println() in the loop body.
2.
Great job on setting up your first Kotlin for loop!
Now instead of just outputting text, it’s time to use the loop variable i in the loop
body.
Add another println() with a string template directly below the first println() so
the loop creates the following output:
Hello, Codey!
i=1
Hello, Codey!
i=2
Hello, Codey!
i=3
Hello, Codey!
198
i=4
Hello, Codey!
i=5
fun main() {
// Write your code below
}
OUTPUT
Hello, Codey!
i=1
Hello, Codey!
i=2
Hello, Codey!
i=3
Hello, Codey!
i=4
Hello, Codey!
i=5
199
functions downTo, until and step give us more control of a range and therefore
more control of our loops.
The downTo function simply creates a reverse order group of values, where the
starting boundary is greater than the ending boundary. To accomplish this,
replace the range operator (..) with downTo:
for (i in 4 downTo 1) {
println("i = $i")
}
We can see in the output that the first number in i is 4 and the last is 1:
i=4
i=3
i=2
i=1
The until function creates an ascending range, just like the (..) operator, but
excludes the upper boundary:
for (i in 1 until 4) {
println("i = $i")
}
Up until now, each of these functions, including the range operator (..), have
counted up or down by one. The step function specifies the amount these
functions count by:
200
for (i in 1..8 step 2) {
println("i = $i")
}
The loop variable i now increases by 2 for every iteration. The last number output
is 7, since 2 steps up from that is 9 which is outside the defined range, 1..8:
i=1
i=3
i=5
i=7
1.
Let’s look at how we can change the behavior of ranges in for loops by
implementing a loop that counts backwards.
Create a for loop that contains:
• i as the loop variable.
• an iterator that starts at 10 and ends at 1.
• a println() statement in the loop body with the string template "i= $i".
2.
Below the first loop, implement a for loop that counts up but stops just before the
upper boundary of the range. Make sure it contains:
• j as the loop variable.
• the range 1 up to but not including 10 as the iterator.
201
• a println() statement in the loop body with string template "j = $j".
3.
Finally, implement a for loop that iterates over a range in steps greater than 1.
Make sure it contains:
• k as the loop variable.
• a range 1 through 10 as the iterator that counts up by 2.
• a println() statement in the loop body with string template "k = $k".
Run the code and you will see that the new loop does not output the iterator’s
upper boundary 10. Counting up by 2 from 1 does not include 10.
fun main() {
println("-- 1st for loop output --")
// Write your code below
OUTPUT
-- 1st for loop output --
202
i = 10
i=9
i=8
i=7
i=6
i=5
i=4
i=3
i=2
i=1
203
k=3
k=5
k=7
k=9
In this example, we declare fruit as the loop variable and use fruitList as the
iterator. Each iteration of the loop will set fruit to the value of the current
element of fruitList. Therefore, the number of elements contained
in fruitList determines the number of times println("I have $fruit.") is executed:
I have apples.
I have oranges.
I have bananas.
When we first learned about lists and sets in the collections lesson, we discussed
their commonality as well as their differences. An additional similarity is that the
syntax for iterating through a list and a set is the same.
204
When iterating through a collection, it is often useful to know what element
number, or iteration, we are at. To iterate through the indices of a collection you
can use its indices property:
val fruitSet = setOf("apples", "oranges", "bananas")
Here we see the indices of fruitSet output. Remember that the first index of a list
or a set is always 0:
Index = 0
Index = 1
Index = 2
We can also get the index AND the iterator element using the
collection’s withIndex() function. In this case we need to destructure the loop
variable declaration by declaring two loop variables and enclosing them in
parentheses:
val fruitList = listOf("apples", "oranges", "bananas")
Using withIndex() and destructuring, we are able to access both the index and the
element of fruitList:
0 is the index of the element apples
1 is the index of the element oranges
2 is the index of the element bananas
205
9.4 Iterating Through Collections Instructions
1.
Now you’ll use collections as iterators. To start, implement a for loop using the
list mySchedule. The loop should contain:
• task as the loop variable.
• the list mySchedule as the iterator.
• a println() statement in the loop body that outputs the loop variable.
2.
Great, now look at the set myTasks which is declared with the same elements as
the list. We know that myTasks will have fewer elements since some of them are
repeated and will only be represented once in the set. Let’s confirm this by
printing out the indices AND the elements of the set.
Create another for loop that contains:
• taskIndex and task as destructured loop variables. Be sure to separate them
with a comma and enclose them in parentheses.
• myTasks using the withIndex() function as the iterator.
• a println() statement in the loop body with the
output taskIndex and task separated by a colon (:). Example output: 0: Eat
Breakfast
fun main() {
val mySchedule = listOf("Eat Breakfast", "Clean Up", "Work", "Eat Lunch", "Clean
Up", "Work", "Eat Dinner", "Clean Up")
206
val myTasks = setOf("Eat Breakfast", "Clean Up", "Work", "Eat Lunch", "Clean
Up", "Work", "Eat Dinner", "Clean Up")
OUTPUT
-- mySchedule Output --
Eat Breakfast
Clean Up
Work
Eat Lunch
Clean Up
Work
Eat Dinner
Clean Up
-- myTasks Output --
0: Eat Breakfast
1: Clean Up
207
2: Work
3: Eat Lunch
4: Eat Dinner
Notice that in order to access the attributes in a String template, we surround the
loop variable and the attribute in curly brackets.
We can also access the key and value of each entry by destructuring using two
loop variables in parentheses. The first variable is the entry’s key and the second
is the value:
val myClothes = mapOf("Shirts" to 7, "Pairs of Pants" to 4, "Jackets" to 2)
Lastly, we can iterate through just a map’s keys or values. A map has the
properties keys and values which can each be used as an iterator:
val myClothes = mapOf("Shirts" to 7, "Pairs of Pants" to 4, "Jackets" to 2)
println("KEYS")
for (itemName in [Link]) {
println(itemName)
}
println("\nVALUES")
for (itemCount in [Link]) {
println(itemCount)
}
VALUES
7
4
2
209
1.
The map favoriteColors holds the names of people and their favorite colors. The
keys of the map are the people’s names and the values of the map are their
favorite colors. Start by iterating through the map favoriteColors to access each
entry and output its key and value.
Implement a for loop that contains:
• favoriteEntry as the loop variable
• favoriteColors as the iterator
• a println() statement in the loop body that outputs the key and value of
each entry separated by a colon. Example output, Jesse: Violet
Be sure to use curly brackets in the string template when accessing the attributes
of the entry in the loop variable.
2.
Nice work. Now you’re going to create a loop that iterates through just the map’s
values.
Create another for loop that contains:
• color as the loop variable
• the values attribute of favoriteColors as the iterator.
• a println() statement in the loop body that outputs the value of each entry.
fun main() {
val favoriteColors = mapOf("Jesse" to "Violet", "Megan" to "Red", "Tamala" to
"Blue", "Jordan" to "Pink")
210
println("\n-- Key: Value Output --")
// Write your code below
}
OUTPUT
-- Key: Value Output --
Jesse: Violet
Megan: Red
Tamala: Blue
Jordan: Pink
When repeating code we may not have a range or defined collection to dictate
the number of loops we need to execute. In this case, we can rely on a while
loop which repeats code as long as a specified condition is true. If we revisit the
211
animation in the first exercise, we can see that Codey uses a while loop to hike
until time is no longer less than 17.
A while loop is similar to an if expression because it tests a condition and when
the condition is true a body of code is executed. The main difference is
the while loop will complete the body of code, check the condition, and repeat
the code if the condition is still true. If the condition is false, the while loop is
done and the program moves on:
var myAge = 16
In this example the while loop condition myAge < 20 initially evaluates to true.
The loop body is executed which outputs some text and myAge is incremented.
The loop repeats until myAge equals 20 at which point the loop exits and
continues running code outside the loop:
I am a teenager. // myAge is 16
I am a teenager. // myAge is 17
I am a teenager. // myAge is 18
I am a teenager. // myAge is 19
I am not a teenager. // myAge is 20
If myAge wasn’t incremented inside the loop body the loop condition would
always be true and repeat forever. This is known as an infinite loop. Infinite loops
lead to application crashes or other unwanted behavior so it is important that
they are avoided.
When a while loop condition never evaluates to true, the entire block of code is
skipped:
212
var myAge = 44
Since we’ve set the value of myAge to 44 and the condition will only be true once
the value is between 12 and 20, the code block is skipped and the
final println() gets executed:
I am not a teenager.
1.
Create a while loop that:
• repeats as long as the variable counter is less than 5.
• uses println() in the loop body to output the variable counter.
• increments the variable counter by 1 in the loop body.
Note: If the program keeps running and never ends, you have likely created
an infinite loop. To fix this, refresh the page and take another look at your loop
and make sure it has a terminating condition.
2.
A while loop condition can also check the elements of a collection. You’ll use
another counter variable, index, to access the collection’s elements.
213
Implement a second while loop that:
• has the condition, schoolGrades[index] != "6th".
• uses println() in the loop body to output the current element value
of schoolGrades.
• increments the variable index by 1 in the loop body.
When you’re done, you’ll see that the while loop exits once the element “6th” is
the current one.
fun main() {
var counter = 0
var index = 0
val schoolGrades = listOf("Kindergarten", "1st", "2nd", "3rd", "4th", "5th", "6th",
"7th")
}
OUTPUT
-- counter Output --
0
1
214
2
3
4
A do..while loop is just like a while loop except the looping condition is checked at
the end of the loop body. This is known as an exit-condition loop and means the
code in the body will execute at least once:
val myCondition = false
do {
print("I loop once!")
} while(myCondition)
This example shows that even though we have a false condition our loop will still
run the loop body once:
215
I loop once!!!!
One reason we would use a do..while loop is when our loop condition
initialization and update commands are the same. Using psuedocode we can
compare a while loop with a do..while loop using how someone might decide to
go outside:
Is it sunny outside?
while ( not sunny ) {
Is it sunny outside?
Stay inside.
}
Go outside!
The while loop example has a line before the loop to check if it is sunny outside.
The loop is entered if it is not sunny and then repeatedly checks if it is sunny
outside. When it is sunny, the loop exits and it’s time to go outside:
do {
Is it sunny outside?
Stay inside.
} while ( not sunny )
Go outside!
The do..while loop enters the loop and starts by checking if isSunny is true. The
loop body repeats if the isSunny is false.
The extra check prior to the loop is unnecessary since it is performed inside the
loop anyway. If we have to look outside to get our initial loop condition and to
update our loop condition, we might as well have that be the loop body and check
the condition at the end.
216
This difference may seem subtle, but if this loop is executed hundreds or
thousands of times a second, removing the one line of code using a do..while loop
may save time.
1.
We’ll implement a do..while loop that performs a Celsius to Fahrenheit
temperature conversion.
First, construct a do..while loop that checks if fahr does not equal 212.0. Inside
the loop body:
• paste the following 2 lines of code.
fahr = celsiusTemps[index] * fahr_ratio + 32.0
println("${celsiusTemps[index]}C = ${fahr}F")
fun main() {
var index = 0
val celsiusTemps = listOf(0.0, 87.0, 16.0, 33.0, 100.0, 65.0)
val fahr_ratio = 1.8
var fahr: Double
217
println("-- Celsius to Fahrenheit --")
// Write your code below
}
OUTPUT
-- Celsius to Fahrenheit --
0.0C = 32.0F
87.0C = 188.6F
16.0C = 60.8F
33.0C = 91.4F
100.0C = 212.0F
Loops inside loops, oh my! A nested loop represents one loop placed inside the
body of another loop which results in a higher dimensions of iterations. This
strategy is most often used when we’d like to compare the contents of two
different collections/iterators.
Below is an example of nested loops. The outer loop iterates through the
range 1..2 and the inner loop iterates through the range 'A'..'C':
for (i in 1..2) {
for (j in 'A'..'C') {
println("Outer loop: $i - Inner loop: $j")
}
}
218
It’s important to understand that for every iteration in the outer loop, the inner
loop will run through all of its own iterations.
In the example above, the inner loop iterates 3 times for each of the outer loop’s
2 iterations. Therefore, the println() statement is run 6 times:
Outer loop: 1 - Inner loop: A
Outer loop: 1 - Inner loop: B
Outer loop: 1 - Inner loop: C
Outer loop: 2 - Inner loop: A
Outer loop: 2 - Inner loop: B
Outer loop: 2 - Inner loop: C
When beginning with nested loops they may seem difficult to work with, but they
make advanced applications easy to implement.
1.
You’ll be building a grid of rows and columns much like the ones that exist in
Google and Excel sheets using nested loops. First start with a single loop.
Create a for loop that contains:
• i as the loop variable.
• a range of 1 through 6 as the iterator.
2.
Now you will implement another loop inside the first one.
Inside the first loop body, create a for loop that contains:
219
• j as the loop variable.
• a range of 'A' through 'F' as the iterator.
• a print() statement that outputs "$j$i ".
The empty space at the end of the String template is used to create a gap
between columns which helps us visualize what is happening in the code.
3.
There is now a single line of each loop variable concatenated to each other. The
last step will show off the dimensional nature of nested loops.
Outside of the inner loop but still inside of the outer loop:
• add an empty println() statement.
When you run the code you can now see that each inner loop iteration outputs a
column, while each outer loop iteration creates a new row.
fun main() {
// Write your code below
OUTPUT
A1 B1 C1 D1 E1 F1
A2 B2 C2 D2 E2 F2
A3 B3 C3 D3 E3 F3
A4 B4 C4 D4 E4 F4
A5 B5 C5 D5 E5 F5
A6 B6 C6 D6 E6 F6
220
9.9 Jump Expressions
The jump expressions, break and continue, are used to change the standard loop
behavior by exiting a loop early or skipping a single repetition.
The break expression is used to exit the loop at a particular iteration:
val myNumbers = listOf(4, 8, 2, 9, 12, 7, 16, 10, 3)
for (num in myNumbers) {
if (num > 9) {
break
}
println(num)
}
In this example:
• the for loop iterates through the list of Ints.
• each iteration the current number, num, is tested to see if it is greater than
9.
• if false, the number is output.
• if true, the break expression exits the loop.
We can see the below output stops before printing the number 12:
Output
4
8
2
9
The continue expression will skip the current execution of the loop body, but the
loop will keep going if there are iterations left. If the continue expression gets
executed, any code left in the current iteration will be skipped:
221
val myNumbers = listOf(4, 8, 2, 9, 12, 7, 16, 10, 3)
for (num in myNumbers) {
if (num > 9) {
continue
}
println(num)
}
This example is the same as the last but we replaced the break with continue. The
below output skips all values of num greater than 9, while printing out the rest
of numbers:
Output
4
8
2
9
7
3
The first example outputs the elements in myNumbers until you reach one
greater than 9. The second example outputs all elements
in myNumbers except those that are greater than 9.
Since jump expression are usually contained inside if expressions, they gives us
the ability to add a condition to exit a for loop or using another condition to exit
a while loop.
Don’t worry if this all doesn’t stick right away; keep practicing with each jump
expression and you’ll quickly get the hang of how and when each one is used.
1.
222
The code on the right is “looking” for something in different rooms of a house.
Thankfully we know that the item being searched for is in the "Living Room".
Your job is to instruct the for loop to stop looking once it reaches "Living Room":
• After the print("$room: ") statement add an if expression that tests if the
loop variable room is equal to "Living Room".
• Inside the if block use a println() statement to output the String, "Found It!"
• Inside the if block add the appropriate jump expression that will stop the
iteration.
2.
Good work! We also come across situations where we may want to skip a loop
iteration. The second for loop in the editor causes a division by zero error. This is
undesirable, and we need to add code to the body of the for loop to avoid this.
• At the start of the loop add an if expression that tests if number is 0.
• Inside the if expression add a continue expression.
fun main() {
val rooms = listOf("Kitchen", "Living Room", "Basement", "Bathroom")
println("Found Nothing.")
}
223
println("\n-- Divide By Zero --")
for (number in 12 downTo -12 step 4) {
// Write your code below
println("120/number = ${120/number}")
}
}
OUTPUT
-- Room Search --
Kitchen: Found Nothing.
Living Room: Found It!
-- Divide By Zero --
120/number = 10
120/number = 15
120/number = 30
120/number = -30
120/number = -15
120/number = -10
224
“How would we use jump expressions inside nested loops?” Good question! The
answer is labeled jump expressions. By adding a label to the outer loop of
nested loops, we can execute a jump expression from the inner loop and have it
act on the labeled outer loop.
First we need to give a name to our label. In the following example we choose the
name rps. The outer loop is marked using our label rps followed by the @ symbol:
val game = listOf("Rock", "Paper", "Scissor")
225
}
println("$p1 vs. $p2")
}
}
What we see now is the outer loop skips an iteration when p1 == "Paper" but
resumes with the final iteration when p1 is equal to “Scissor”:
Rock vs. Rock
Rock vs. Paper
Rock vs. Scissor
Scissor vs. Rock
Scissor vs. Paper
Scissor vs. Scissor
Labeled jump expressions give us more control over nested loops to help us
achieve the desired behavior from our code. Using them can be tricky, but once
understood they can be very powerful.
1.
Recall the 6x6 grid with “A1” to “F6”” cells from the previous exercise. We’ll take
a closer look at how we can manipulate the structure and output of this grid using
labeled jump expressions.
First, add a label grid to the outer loop.
2.
226
Add an if expression inside the inner loop, before the print("$j$i ") statement.
Have the condition test if the inner loop variable is equal to 'C'.
3.
Inside the if expression add a continue expression that jumps to the grid label.
Once you run the code you should see a single line of output. The outer loop
numbers go from 1 through 6, but the inner loop letters only go up through 'B'.
It is important to note that the println() statement at the end of the outer loop is
also skipped. The result is only one row is printed. This shows that a
labeled continue will skip any code proceeding it in the inner loop and at the end
of the outer loop.
fun main() {
// Write your code below
for (i in 1..6) {
for (j in 'A'..'F') {
// Write your code below
print("$j$i ")
}
println()
}
}
OUTPUT
A1 B1 A2 B2 A3 B3 A4 B4 A5 B5 A6 B6
227
__________________________
[Link]
1. Which program achieves the following output?
123456
123456
a) for(i in 'a'..'b'){
for(j in 1..6){
print("$j ")
}
println()
}
b) for(i in 'a'..'b'){
for(j in 1..6){
print("$j ")
}
}
c) for(i in 1..6){
for(j in 1..6){
print("$j ")
}
println()
}
d) for(i in 1..6){
for(j in 'a'..'b'){
print("$j ")
228
}
println()
}
229
_______
}
println("i = $i, j = $j")
}
}
• continue@myJump
• myJump@
• j == 4
• j>4
• break@myJump
• label@
Click or drag and drop to fill in the blank
ANS:
myJump@ for (i in 1..3) {
for (j in 1..10) {
if (j > 4) {
break@myJump
}
println("i = $i, j = $j")
}
}
230
a) 5 4 3 2 1 0
b) 4 3 2 1
c) 5 4 3 2 1
d) 1 2 3 4 5
6. Which of the following numbers will NOT be printed from this code?
val numbers = listOf(2,4,6)
a) 8
b) 12
c) 6
d) 4
7. When iterating through a map, what does the loop variable hold in each
iteration?
a) The map’s current entry key.
b) A list containing the map’s current entry key and value.
c) The map’s current entry value.
d) The map’s current entry.
do {
print("$num ")
num++
} while (num < 21)
a) 20
b) 20 21
c) 21
d) There is no output.
11. True or False: An infinite loop occurs when a while or do..while loop condition
is never false.
a) False
b) True
232
__________________________
[Link]
Shape Maker
How many output statements do you need to draw two-dimensional shapes?
Using loops, the answer to this question is 2. In this project, you will create a
square and a triangle of any size using nested loops with one print() statement
and one println() statement.
We’ll create a basic square pattern using loop concepts we covered in the
previous lesson. We’ll even take it a step further by getting our program to output
a checkerboard pattern.
Then, we’ll explore how nesting a while loop inside of a for loop can be used to
create a triangle pattern in the output terminal. This will give us a different
perspective of nested loops and how to control variables when using while loops.
Good luck with the project and have fun!
2.
233
Start your code under the first group of variables by creating a for loop with an
iterator that starts at 1 and goes through the value of sqSide. This will act as the
outer loop of the code.
Put a blank println() in the loop body. This will create the rows of the square.
3.
Now, let’s add an inner loop to output each column in a row.
Inside the outer for loop, create an inner for loop before the println() statement.
Use the same iterator as the outer loop.
Inside the inner loop body use a print() statement to output the value of sqChar1.
6.
Start off the code for the triangle pattern by using a for loop that counts down
from triRows to 1. This will act as the outer loop of the code.
Inside the loop body insert a blank println().
234
7.
Inside the for loop, create a while loop before the println() statement. The while
loop should repeat when triCount is less than triRowLen.
Increment triCount inside the loop. Make sure to run your code only after you’ve
added the increment, otherwise, you’ll run into an infinite loop. If you have, you
might need to refresh the web page.
8.
Add a print() statement to the while loop body directly below the increment to
output triChar1.
Run the code and look at the output. Do you see a single line of characters? Can
you figure out why your output is the way it is?
9.
The while loop is responsible for outputting triChar1. There is a possibility that the
condition triCount < triRowLen is true only for the first outer loop iteration
causing the inner loop to only output a single line.
To prevent this, outside the while loop (but inside the for loop), set triCount to its
initial value, 0. This will ensure that at the start of each iteration of
the for loop, triCount is less than triRowLen and the while loop body will execute.
10.
Run your code. Do you see a square? If so, why? The goal is to make a triangle!
To make our pattern look like a triangle, we need to adjust the length of each new
row. To accomplish this, decrement the value of triRowLen at the end of
the for loop’s body.
235
Confirm the output of a 2nd triangle and move to the next task to implement the
triangle outline.
12.
To create a triangle border, we need to output a visible character at the triangle
edges and blank space everywhere else.
In the inner loop, replace the print() statement with an if expression.
The if expression should test if the output is not an edge. There are three
conditions that must be true in order for a character to not be an edge:
o The while loop counter is not equal to 1.
o The while loop counter is not equal to the current row length.
o The for loop variable is not equal to the total number of rows.
If all three conditions are true, then output triChar2. Otherwise, output triChar1
Optional
13.
Great work on the project! Here are a couple more tasks you can work on if you
want to keep going.
o Change the values of sqChar1, sqChar2, triChar1 and triChar2 to see
how they affects the look of each shape.
o Use different conditions within the if expressions of the square shape
to explore what other patterns you can generate.
o In the triangle outline code, instead of using an else to
output triChar1, use a continue in the if block to skip the rest of
the while loop code.
fun main() {
// Square Variables
val sqSide = 7
val sqChar1 = "X "
val sqChar2 = "O "
// Write your code below
236
// Triangle Variables
val triRows = 10
var triCount = 0
var triRowLen = triRows
val triChar1 = "/ "
val triChar2 = " "
// Write your code below
OUTPUT
X O X O X O X
O X O X O X O
X O X O X O X
O X O X O X O
X O X O X O X
O X O X O X O
X O X O X O X
/ / / / / / / / / /
/ / / / / / / / /
/ / / / / / / /
/ / / / / / /
237
/ / / / / /
/ / / / /
/ / / /
/ / /
/ /
/
/ / / / / / / / / /
/ /
/ /
/ /
/ /
/ /
/ /
/ /
/ /
/
238
[Link]
10.1 Introduction to Functions
239
10.2 Creating and Calling a Function
fun main() {
241
// Invoke the function
greeting()
}
// Prints: Hello friend!
1.
Create a function named smores() that outputs the following statements
using println():
• "Roast a marshmallow."
• "Place marshmallow on a graham cracker."
• "Place chocolate on marshmallow."
• "Put a new graham cracker on chocolate."
• "Enjoy!"
2.
Invoke smores() in the main() function.
3.
Optional:
Call smores() again. Note how time is saved by calling a function instead of writing
the instructions again.
242
// Write your code below
fun main() {
// Write more code below
}
OUTPUT
Roast a marshmallow.
Place marshmallow on a graham cracker.
Place chocolate on marshmallow.
Put a new graham cracker on chocolate.
Enjoy!
10.3 Arguments
Arguments are pieces of data we can feed to our functions in order to produce
dynamic results. We can include as many arguments as the function needs.
Think of the println() function. When we use it, we give it a single argument: a
String value. This value is then passed and outputted to the terminal.
To pass arguments into a function, we need to add parameters to our function
header. Parameters are the names given to data being passed into a function. For
example:
243
fun calculateForce(mass: Int, acceleration: Int) {
var force = mass * acceleration
println("The force is $force Newtons.")
}
When calculateForce() is called, the values 5 and 12 are passed as arguments into
the function. The value of the parameter mass will be 5 and the value
of acceleration will be 12. Invoking the function with these argument values will
give us the following output:
The force of this object is 60 Newtons.
244
1.
Create a function called getSpeed() that accepts two Int
arguments: distance and time.
Inside the function, create a variable called speed that is equal to the value
of distance / time.
Use println() and a String template to output the following statement:
[speed] meters per second
2.
Invoke the getSpeed() function inside main().
Set the argument value of distance to 10 and the value of time to 3.
fun main() {
// Write more code below
}
OUTPUT
3 meters per second
245
10.4 Named and Default Arguments
fun main() {
// Invoke the function with named arguments.
calculateForce(acceleration = 12, mass = 5)
// Prints: The force is 60 Newtons.
}
Note that by naming our arguments when we invoke a function, we do not need
to place the arguments in the same order as they appear in the function header.
Default arguments provide values to function arguments if none are given when
the function is called. To implement this, we add an assignment operator and a
value after the argument in the function header, like so:
fun greetCustomer(name: String = "Customer") {
println("Hello, $name.")
}
246
If we invoke this function with a String value, that value will become the value
of name; however, if no argument is given, name will have a value of "Customer":
greetCustomer("Cynara") // Prints: Hello, Cynara.
greetCustomer() // Prints: Hello, Customer.
1.
An online shop has a special coupon code to get 15% off a customer’s final
purchase.
Create a function called getPrice() that accepts a Double type argument
named price as well as a String argument called couponCode that has a default
value of "None".
Leave the body empty for now.
2.
Inside the function, declare a Double type variable called finalPrice.
Then, create an if/else expression.
• If the value of couponCode is "save15", set finalPrice to price * .85.
• In the else expression, set finalPrice to price.
Outside the conditional, use println() and a String template to output the
following statement:
The total price is [finalPrice].
3.
247
Inside the main() function, invoke getPrice().
When invoking getPrice(), use named arguments to give price a value
of 48.0 and couponCode a value of "save15".
4.
Optional:
Invoke getPrice() for a second time. This time, only give the program a single
argument: 48.0.
Observe what happens when no argument for couponCode is given.
// Write your code below
fun main() {
// Write more code below
}
OUTPUT
The total price is 40.8.
248
The functions in the previous exercises produced output via println() statements
contained within its code body; however, we also have the ability to return a
value from a function.
A return statement returns a value from a function and passes it back to where
the function was invoked. This value can then be used throughout our program.
If we want a function to return a value, we must add the return type to the
function header as well as a return statement in the body. Take a look at the
following example where we create a function that takes in a list of Ints and
returns an Int value:
fun listSum(myList: List<Int>): Int {
var sum = 0
// iterate through each value and add it to sum
for (i in myList) {
sum += i
}
// return statement
return sum
}
• The return type describes the data type of the value being returned and is
stated after the parentheses and a colon : in the function header.
• The keyword return is used to declare a return statement. In this
case, sum is the value being returned.
• Any lines of code that exist after the return statement will not be executed.
Previously, we invoked functions by calling them on their own line of code;
however, we can also invoke a function and assign it to a variable for later use.
For example, we can set total to the return value of listSum() after sending it a list
of Int values (billsToPay):
var billsToPay = mutableListOf(44, 29, 104, 79)
1.
Following a recipe for vanilla cake, you are asked to add .75 ounces of vanilla
extract; however, you only have a teaspoon to measure the ingredients.
Create a function called ozToTsp() that takes a Double type argument
named oz and returns a Double type value.
Inside the function, create a variable tsp whose value is oz multiplied by 6. Use a
return statement to return the value of tsp.
2.
Inside main(), create a variable called tspNeeded and set its value
to ozToTsp() with an argument of .75.
Use println() and a String template to output the following statement:
fun main() {
250
// Write more code below
}
OUTPUT
You will need 4.5 tsp of vanilla extract for this recipe.
If one of our functions contains only a single expression, we can write the function
out with shorthand syntax. This syntax allows us to create a function using only a
single line of code.
For example, assume we create a function that returns a given number (num) to
the power of 2. Using the normal function syntax, our code would look like this:
fun powerOf2(num: Int): Int {
return num * num
}
Using the single expression function syntax, we can rewrite the above code by
removing the brackets ({ and }) as well as the return keyword:
fun powerOf2(num: Int): Int = num * num
Note how the return value (num * num) is prepended with an assignment
operator (=).
We can shorten this code even more by removing the return type. Using type
inference, the compiler can deduce the type of the return value, making our
function look like this:
251
fun powerOf2(num: Int) = num * num
1.
Create a single expression function called pyramidVolume().
The function will accept three Int types arguments: l, w, and h and return the
value of (l * w * h) / 3.
2.
Inside main(), create a variable called volume and set its value
to pyramidVolume() with the following arguments in their respective
order: length, width, height.
Use println() and a String template to output the following:
fun main() {
var length = 5
var width = 8
var height = 14
253
is stated after ->. In this case, the anonymous function takes in two Integers and
returns a single Double.
To call this anonymous function, we’ll simply call quotient like we would any
other variable:
println(quotient(10, 5)) // Prints: 2
1.
254
Working at a landscape company, a customer asks for grass to cover the area of
their triangle-shaped yard.
Create a variable called area and set its value to an anonymous function that
accepts two Int arguments: base and height and returns an Int value.
The return value should equal (base * height) / 2.
Use println() to output the value of area(15, 19).
2.
The customer comes back and asks for you to build a fence around their garden.
Create a variable called perimeter and set its value to a lambda expression that
accepts two Int values called side1 and side2 and returns an Int value.
The return value will equal the value of side1 + side2 times 2.
Use println() to output the value of perimeter(15, 24).
fun main() {
// Write your code below
}
OUTPUT
142
78
255
10.8 Review
Congratulations on completing this lesson. Let’s go over what we learned:
• A function is a reusable block of code that can be invoked throughout a
program.
• In order to execute a function, it must be called somewhere in the program.
• An argument is a piece of data fed to the function.
• Arguments have the option to be named and/or given default values.
• A return statement returns a piece of data from the function to where the
function was called.
• Functions with only a single expression can be written with a single line of
code using shorthand syntax.
• A function literal is an unnamed function that can be passed as an
expression.
__________________________
Recursion
What is Recursion?
Recursion is the process in which a function calls itself until a condition is met.
This concept is similar to a while loop in which a body of code will be executed
repeatedly until a condition is met.
256
Recursion is an advanced topic when it comes to functions and programming; it
often takes time and practice until a programmer is comfortable with creating
and using recursive functions so don’t feel discouraged if it doesn’t all stick right
away.
257
• recursiveSum(2) returns 2 + recursiveSum(1).
• recursiveSum(1) returns 1 + recursiveSum(0).
Once we call recursiveSum(0), the base case is reached because num is 0. Now,
we need to return the value from each call starting from the last call made.
• recursiveSum(0) returns 0.
• recursiveSum(1) returns 1 + 0 which equals 1.
• recursiveSum(2) returns 2 + 1 which equals 3.
• recursiveSum(3) returns 3 + 3 which equals 6.
• recursiveSum(4) returns 4 + 6 which equals 10.
Note: Like a while loop, a recursive function can run infinitely if we do not create
a base case that eventually stops the recursive calls.
Let’s practice creating our own recursive function:
Coding question
Happy New Year! Define a function called countDown() that accepts a single Int
argument called secondsToMidnight.
Inside countDown(), create an if/else expression to represent the base case and
recursive call.
• Base case: If secondsToMidnight is equivalent to 0, use println() to
output "Happy New Year!"
• Recursive call: In the else block, use println() to output the value
of secondsToMidnight. Then, on the following line, recursively
call countDown() with an argument of secondsToMidnight - 1.
Inside main(), invoke countDown() with an argument value of 10.
Tail-Recursive Functions
258
Recursive functions run the risk of stack overflow. Stack overflow occurs in
recursive functions when too much data is being used to store the values created
in each recursive call and can cause our program to crash.
Luckily for us, Kotlin has a solution for this: tail-recursive functions. When using a
tail-recursive function, the compiler can optimize the code to prevent stack
overflow.
Let’s recreate the recursiveSum() function from earlier. To declare a tail recursive
function, prepend tailrec to the fun keyword in the header:
tailrec fun recursiveSum(num: Int, sum: Int = 0): Int {
return if (num == 0) sum
else recursiveSum(num - 1, sum + num)
}
fun main() {
println(recursiveSum(num = 10)) // Prints: 55
}
We added a second argument, sum, to store the final return value. For a recursive
function to be considered for tail recursion, the final operation in the function
must be a call to itself. In this case, the final instruction is recursiveSum(num - 1,
sum + num).
The code return if (num == 0) sum translates to the base case being num == 0 and
the return value being sum. The code else recursiveSum(num - 1, sum + num) is
the recursive call that changes the argument num to decrease by 1 while adding
the value of num to the eventual return value sum.
Let’s practice creating tail-recursive functions:
Coding question
In math, a factorial function multiplies a positive number from its value down to
1.
For example 4! represents 4 * 3 * 2 * 1.
259
Define a tail-recursive function called factorial() that accepts an Int argument
named num and an Int argument named product that has a default value of 1.
The function will return an Int value.
Inside the function, return the value of product when the base case, num == 1, is
reached. Otherwise, recursively call the function with the arguments num -
1 and num * product, respectively.
Inside the main() function, create a variable called factorialValue and set its value
to factorial(10). Then, use println() to output factorialValue.
Wrap up
Great job reaching the end of this article. Let’s go over what we learned:
• Recursion is the process of a function calling itself within the function’s
code block.
• Every recursive function needs a base case and a recursive call.
• The base case defines what condition must be met in order to exit the
recursive function while the recursive call is used to call the function with a
new set of arguments.
• A tail-recursive function is a more efficient way of producing a recursive
function because it prevents stack overflow.
Recursion is one of the more advanced topics in this course; don’t feel
discouraged if the concept didn’t click right away. Recursion isn’t a fundamental
programming concept, but once you get the hang of it, it can be a valuable tool
for coding projects, interview questions, and more.
__________________________
[Link]
260
1. What is a function?
a) A function is a block of code that is repeated a set number of times.
b) A function is an unordered collection of unique elements.
c) A function is a named, reusable block of code that can be called throughout
a program.
d) A function is a true or false value.
fun main() {
greetFriend("Kamala")
}
a) Hi there, Kamala!
b) Hi there, Buddy!
c) Hi there, $name!
fun main() {
var listOfNumbers = mutableListOf(2, 3, 6, 7, 9, 10)
println(numberOfOddNumbers(myList = listOfNumbers))
}
a) numOdd
b) [2, 3, 6, 7, 9, 10]
c) 3
d) There is no output.
5. Fill in the code to have findDifference() return the variable difference which
equals the value of num1 subtracted by num2.
fun findDifference(num1: Int, num2: Int): _____ {
var difference = num1 ______ ______
______ difference
}
• -
• return
• String
• num4
• *
• num2
• Int
262
• sendBack
Click or drag and drop to fill in the blank
ANS:
fun findDifference(num1: Int, num2: Int): Int {
var difference = num1 - num2
return difference
}
7. Recreate the following function using the syntax for a single expression
function.
fun findRemainder(num1: Int, num2 Int): Int {
return num1 % num2
}
263
• num2
• =
Click or drag and
8. What is one major difference between a function literal and a basic function?
a) Function literals and basic functions are the same.
b) A function literal does not have a function name.
c) Function literals never take in an argument.
d) Function literals never return a value.
9. Based on the following function header, what data type will the following
function return?
fun isEvenOrOdd(num: Int): Boolean {
// Code goes here
}
a) Int
b) Boolean
c) This function returns no value.
d) String
fun main() {
getForce(acceleration = 2, mass = 5)
}
a) The force is with you.
264
b) The force is 10 Newtons.
__________________________
[Link]
DIY Functions
Up until this point, whenever we have wanted to gather information about
specific collections in our programs, we have relied on Kotlin standard library
functions to give us the answers.
For example, we’ve used the sum() function to tell us the sum of the values in a
list and the average() function to return the mean. We never had to fully
understand how the program calculates this information; all we had to do was call
a function on a collection and use whatever value the function returned.
In this project, we’re going to dive in and create five user-defined functions to
collect and gather information about a list of numbers.
As you go through the project, check off the boxes next to each instruction as you
complete them.
Note: We’ll be using the bash terminal to collect user input. For instructions on
running the program in the bash terminal, see this exercise or the hint in
instruction 17.
2.
Inside getListOfNumbers(), declare an empty mutable list called myList.
Then, create a loop that iterates 7 times and does the following:
o Ask the user to enter a number
o Append the user’s answer as an Int to myList. The value must be
stored as an Int to prevent errors in your code.
Outside the loop, return the value of myList.
Note: See the Hint to find out how to store user input as an Int.
3.
Inside the main() function, create a variable called values and set its value
to getListOfNumbers().
Output the value of values.
266
5.
Inside the function, do the following:
o Declare a variable called largestNumber and set it to the zeroeth
index of the list argument.
o Loop through each element of the list.
o Inside the loop, use a conditional to check if the element’s value is
larger than largestNumber; if it is, set largestNumber to that value.
o Return the value of largestNumber.
6.
Inside main() declare a variable called largestValue and set its value
to findMax() with values as its argument.
Then output the following message:
The largest number is [largestValue].
8.
Inside the function, do the following:
267
o Declare a variable called smallestNumber and set it to the first
element of the list argument.
o Loop through each element in the list argument.
o If the element’s value is less than smallestNumber,
set smallestNumber to that value.
o Return smallestNumber.
9.
Declare a variable called smallestValue in main() and set its value to findMin().
Use values as the argument in the function call.
Then, output the following statement:
The smallest number is [smallestValue].
11.
Inside the function, do the following:
o Declare a variable called sum and set its value to 0.
o Iterate through each value in the list argument.
o Inside the loop, add the value of the list variable to sum.
268
o Outside the loop, return the value of sum divided by the length of the
list argument.
12.
Inside main(), declare a variable called average and set its value
to findAverage() using values as the list argument.
Then, output the following statement:
The average is [average].
14.
Inside the function, do the following:
o Loop through each element of the list argument.
o Inside the loop, check if the value of the loop variable is equal to the
Int argument.
o If the condition is true, return true.
o Outside the loop, return false.
269
15.
Let’s get a value to check for from the user.
Inside main() use a print statement to ask the user to enter a number to check for.
Store this value as an Int variable called numToFind.
Note: See the Hint to find out how to store user input as an Int.
16.
Also in main(), declare a variable called containsValue and set it’s value
to checkIfListContains with the arguments values and numToFind.
If the value of containsValue is true, output that the value exists within the list.
Else, output that the value does not exist within the list.
18.
Run your code several times with different values to make sure the output works
correctly.
See the Hint for some test values.
Optional
19.
270
If you want to keep challenging yourself, check out these additional tasks:
o Create a function that returns the difference between the largest and
smallest number in the list.
o Create a function that takes in a list of numbers and returns a list
with all the values squared.
fun main() {
// Write more code below
__________________________
CONCEPT REVIEW
Functions
271
A function is a named, reusable block of code that can be called and executed
throughout a program.
A function is declared with the fun keyword, a function name, parentheses
containing (optional) arguments, as well as an (optional) return type.
To call/invoke a function, write the name of the function followed by
parentheses.
fun greet() {
println("Hey there!")
}
fun main() {
// Function call
greet() // Prints: Hey there!
}
Function Arguments
272
fun main() {
birthday("Oscar", 26) // Prints: Happy birthday Oscar! You turn 25 today!
birthday("Amarah", 30) // Prints: Happy birthday Amarah! You turn 30 today!
}
Default Arguments
fun main() {
favoriteLanguage("Manon") // Prints: Hello, Manon. Your favorite programming
language is Kotlin
Named Arguments
273
We can name our arguments when invoking a function to provide additional
readability.
To name an argument, write the argument name followed by the assignment
operator (=) and the argument value. The argument’s name must have the same
name as the parameter in the function being called.
By naming our arguments, we can place arguments in any order when the
function is being invoked.
fun findMyAge(currentYear: Int, birthYear: Int) {
var myAge = currentYear - birthYear
println("I am $myAge years old.")
}
fun main() {
findMyAge(currentYear = 2020, birthYear = 1995)
// Prints: I am 25 years old.
findMyAge(birthYear = 1920, currentYear = 2020)
// Prints: I am 100 years old.
}
Return Statement
In Kotlin, in order to return a value from a function, we must add a return
statement to our function using the return keyword. This value is then passed to
where the function was invoked.
If we plan to return a value from a function, we must declare the return type in
the function header.
// Return type is declared outside the parentheses
274
fun getArea(length: Int, width: Int): Int {
var area = length * width
// return statement
return area
}
fun main() {
var myArea = getArea(10, 8)
println("The area is $myArea.") // Prints: The area is 80.
}
fun main() {
println(fullName("Ariana", "Ortega")) // Prints: Ariana Ortega
println(fullName("Kai", "Gittens")) // Prints: Kai Gittens
}
275
Function Literals
fun main() {
// Anonymous Function:
var getProduct = fun(num1: Int, num2: Int): Int {
return num1 * num2
}
println(getProduct(8, 3)) // Prints: 24
// Lambda Expression
var getDifference = { num1: Int, num2: Int -> num1 - num2 }
println(getDifference(10, 3)) // Prints: 7
}
276
11. CLASSES
11.1 Introduction to Classes
277
11.1 Introduction to Classes Instructions
278
11.2 Creating a Class
Now let’s practice writing our own classes. A Kotlin class is declared at the top of a
Kotlin file, outside the main() function, with the class keyword followed by its
name:
class Name {
// class body
}
The name of a class should always start with an upper case letter and use the
camel case form. The class body is contained within curly braces and will hold all
of the properties and functions related to that class. We will take a closer look at
class functions in a later exercise.
Note: It is optional for a Kotlin class to contain a body, thus if the class has no
body, we can omit its curly braces, resulting in the following declaration:
class Name
Let’s revisit our real-world, Car example. Suppose we create the following class:
class Car
Our blueprint is complete! But it’s not of much use to us empty. Any car possesses
several properties including the year it was made, its model name, and color. Let’s
add these:
class Car {
val year = 2011
val model = "Jeep"
val color = "Blue"
}
279
We’ve created the properties, year, model, and color and initialized them with
values. Now any time we create a car object from this class, it will possess the
properties, year, model and color and hold their respective values. In the next
exercise, we’ll learn how to create objects from a class. For now, let’s practice
with the Kotlin class syntax.
1.
In [Link], declare an empty class called Book.
2.
Add the following properties and the values they hold:
• pages with the value, 320
• title with the value, "Harry Potter and the Sorcerer's Stone"
• author with the value, "J.K. Rowling"
fun main() {
280
11.3 Creating an Instance
Now that we’ve created our first class, let’s create an instance of it. An instance of
a class resembles an object that is a member of that given class.
Recall the Car class from the previous exercise:
class Car {
val year = 2011
val model = "Jeep"
val color = "Blue"
}
281
Voila! You’ve created your first object. Think about what you’ve learned
about classes and their properties. What is one way that we might need to
improve upon with this code? Follow the checkpoints below to find out.
1.
Within the main() function of [Link], create an instance of the Building class
and assign it to the variable, residentialBuilding.
2.
Create three print statements that use dot notation to output each value of the
instance, residentialBuilding.
3.
Optional:
If you create another instance of the Building class, say commercialBuilding, and
output its property values, what do you expect to see?
Check the Hint for a clue.
class Building {
val yearBuilt = 2016
val height = 400 // Feet
val type = "Limestone"
}
282
fun main() {
// Write your code below 🏝
OUTPUT
2016
400
Limestone
We’ve now introduced a pair of parentheses in the class header that define
properties, x and y. Previously, we would’ve had something like this:
class Name {
val x = "some value"
val y = "another value"
}
283
Each property would already have its default value set, but with primary
constructors, we give our program the ability to set the values when an instance is
created.
Refactoring our Car example from the previous exercise to utilize a primary
constructor in the header, we get the following line of code:
class Car(val year: Int, val model: String, val color: String)
Now we’ve successfully created unique instances of our Car class and customized
their values:
println([Link]) // Prints: 2011
println([Link]) // Prints: 2015
1.
In [Link], add a class, Person that contains a primary constructor with the
following properties:
• name with the type, String
• age with the type, Int
• favoriteColor with the type, String
2.
284
Within the main() function, create an instance of the Person class called me and
set the values for each property that resemble your characteristics.
On the following line, create another instance of the Person class
called myFriend and set the values for each property that resemble their
characteristics.
3.
Use a String template along with a println() statement for each object and output
the following text:
[name] is [age] years old and ___ favorite color is [favoriteColor].
Make sure to replace the ___ with the appropriate pronoun (my, her, his, or their)
to match the instance. Check the hint for guidance.
// Write your class below
fun main() {
// Create your instances below
OUTPUT
285
11.5 The Init Block
The primary constructor does not contain any code other than the properties and
their specified data types. What if we’d like to calculate a person’s age using the
year they were born? We can do this with an init block.
Init is short for initializer and allows us to add more logic to our classes.
Suppose the following class, Mascot:
class Mascot(val name: String, val platform: String, val yearCreated: Int)
We’d like to use the year the mascot was created to calculate its age. We can do
so by adding this logic within an init block:
class Mascot(val name: String, val platform: String, val yearCreated: Int) {
var age: Int
init {
age = 2020 - yearCreated
println("$name is a $platform mascot and is $age years old. ")
}
}
• We’ve created a variable, age, within the class that we’ll use to store the
value of the calculation.
• Within the init block, we add our mathematical expression followed by
a println() statement to output the final result.
Now when we call the class, we should expect to see a String output:
val codey = Mascot("Codey", "Codecademy", 2018)
// Prints: Codey is a Codecademy mascot and is 2 years old.
286
11.5 The Init Block Instructions
1.
In [Link], we’ve created a class that accepts several properties in its
primary constructor.
On the first line within the class, declare a variable, fullName and in it store the
combination of firstName and lastName with a single space in between.
You can use String concatenation or String templates.
2.
Below, create an init block and in its body, set up the following logic:
• if the yearsWorked is greater than 1, then output the text, "[full name] is
eligible for a raise!"
• else output the text, "[full name] is not eligible for a raise just yet."
Make sure to use the variable you created in the previous step and String
templates.
3.
Navigate to the main() function and create an instance, projectManager, of the
class Employee and pass in the following values:
• firstName is "Maria"
• lastName is "Gonzalez"
• yearsWorked is 2
class Employee(val firstName: String, val lastName: String, val yearsWorked: Int) {
287
// Write your code below
fun main() {
}
OUTPUT
Maria Gonzalez is eligible for a raise!
fun speak() {
println("Meow!")
}
}
We’ve created a simple class, Cat, with a primary constructor and a single
member function. We can now create an instance of the class as so and call
the speak() function:
var myCat = Cat("Garfield", "Persian")
[Link]() // Prints: Meow!
1.
Inspect the class, Dog, on the right. Inside the init block, we looped through the
list property, competitionsParticipated. Now, let’s add a member function below
the init block that shows off one of the dog tricks done in the competition.
Add a member function called, speak(), that outputs the following text:
[name] says: Woof!
2.
Create an instance of the Dog class within the main() function. Call the
instance, maxie. Pass in the following custom values for the properties:
• name: "Maxie"
289
• breed: "Poodle"
• list of competitions should include "Westminster Kennel Club Dog
Show" and "AKC National Championship"
Run your code. Then, call the speak() function on maxie on the following line.
init {
for (comp in competitionsParticipated) {
println("$name participated in $comp.")
}
}
fun main() {
}
OUTPUT
Maxie participated in Westminster Kennel Club Dog Show.
290
Maxie participated in AKC National Championship.
Maxie says: Woof!
11.7 Review
291
Run the code on the right and enter the following two commands for a special
message from Codey:
kotlinc [Link] -include-runtime -d [Link]
init {
println("Dear $name,")
}
fun message() {
println("Thank you for embarking on this journey with me. I couldn't have
gotten through the treacherous waters of Conditional Creek or hiked up the
Looping mountains without your help. You now have the fundamental knowledge
to go on and continue your Kotlin journey in the world of android application,
web development or more. The world is yours. Good luck! ")
}
fun signOut() {
fun main() {
292
println("Please enter your name...")
var learnerName = readLine()
var toLearner = Congratulations([Link]())
[Link]()
[Link]()
OUTPUT
__________________________
293
CONCEPT REVIEW
Classes
A class is an object-oriented concept which resembles a blueprint for individual
objects. A class can contain properties and functions and is defined using
the class keyword followed by a name and optional body.
If the class does not have a body, its curly braces can be omitted.
// A class with properties that contain default values
class Student {
var name = "Lucia"
var semester = "Fall"
var gpa = 3.95
}
294
var semester = "Fall"
var gpa = 3.95
}
fun main() {
var student = Student() // Instance
println([Link]) // Prints: Lucia
println([Link]) // Prints: Fall
println([Link]) // Prints: 3.95
}
Primary Constructor
A primary constructor defines each property value within a class header and
allows us to then set unique values when the object is instantiated.
To create a primary constructor using the shorthand syntax, we can follow the
name of the class with a pair of parentheses () inside of which each property is
defined and assigned a data type.
class Student(val name: String, val gpa: Double, val semester: String, val
estimatedGraduationYear: Int)
fun main() {
var student = Student("Lucia", 3.95, "Fall", 2022)
println([Link]) // Prints: Lucia
println([Link]) // Prints: 3.95
println([Link]) // Prints: Fall
println([Link]) // Prints: 2022
}
295
Init Blocks
The init block gets invoked with every instance that’s created and is used to add
logic to the class. The init keyword precedes any member functions and is
followed by a pair of curly braces.
class Student(val name: String, val gpa: Double, val semester: String, val
estimatedGraduationYear: Int) {
init {
println("$name has ${estimatedGraduationYear - 2020} years left in college.")
}
}
fun main() {
var student = Student("Lucia", 3.95, "Fall", 2022) // Prints: Lucia has 2 years left
in college.
}
Member Functions
A function declared within a class is known as a member function of that class. In
order to invoke a member function, we must call the function on an instance of
the class.
class Student(val name: String, val gpa: Double, val semester: String, val
estimatedGraduationYear: Int) {
init {
println("$name has ${estimatedGraduationYear - 2020} years left in college.")
}
296
// Member Function
fun calculateLetterGrade(): String {
return when {
gpa >= 3.0 -> "A"
gpa >= 2.7 -> "B"
gpa >= 1.7 -> "C"
gpa >= 1.0 -> "D"
else -> "E"
}
}
}
// When an instance is created and the function is called, the when expression
will execute and return a letter grade
fun main() {
var student = Student("Lucia", 3.95, "Fall", 2022) // Prints: Lucia has 2 years left
in college.
println("${[Link]}'s letter grade is ${[Link]()}.") //
Prints: Lucia's letter grade is A.
}
297
__________________________
[Link]
[Link] is the difference between the execution of code within an init block and
within a member function?
a) The init block needs to be called meanwhile all member functions execute
automatically when an instance is created.
b) There is no difference.
c) There must always be a member function within a class meanwhile
an init block is optional.
d) The init block gets executed automatically when an instance is created,
meanwhile, a member function needs to be specifically called upon.
2. Fill in the code to access property values for rose and orchid.
class Flower(val symmetrical: Boolean, val petals: Int, val color: String)
println(rose._____) // Prints: 5
println(_____._____) // Prints: Purple
println(rose _______ symmetrical) // Prints: true
• color
• orchid
• Int
• flower
• ,
298
• rose
• petals
• 5
• .
Click or drag and drop to fill in the blank
ANS:
println([Link]) // Prints: 5
println([Link]) // Prints: Purple
println([Link]) // Prints: true
3. What is a class?
a) A class is a type of Kotlin collection that stores unique elements.
b) A class repeats a body of code based on a given number or condition.
c) A class is a blueprint that contains properties and functions from which
we can instantiate objects.
d) A class is a reusable block of code that performs a certain task.
4. Fill in the blanks of the class, Doctor, and its instance in order to produce the
output:
Rakesh Gupta specializes in Cardiology and has 40 years of experience.
_____ Doctor(val name: _____, val specialty: String, val yearGraduated: _____) {
var yearsExperience: Int
______ {
yearsExperience = 2020 - yearGraduated
println("$name specializes in $specialty and has $yearsExperience years of
experience.")
}
299
}
ANS:
class Doctor(val name: String, val specialty: String, val yearGraduated: Int) {
var yearsExperience: Int
init {
yearsExperience = 2020 - yearGraduated
println("$name specializes in $specialty and has $yearsExperience years of
experience.")
}
}
__________________________
[Link]
Codey's Calculator
Codey’s made it to DevCity: a place full of Android applications, web
development, and other endless implementations of the Kotlin language!
301
In this project, we’ll utilize our knowledge of Kotlin classes to help Codey build a
basic calculator application that many of us have built-into our smartphones.
Our calculator will be able to:
• Find the sum +
• Find the difference -
• Find the product ✕
• Find the quotient ÷
• Find the power ^
A variation of this project exists in our Learn Java course so if you’re learning
Kotlin with a Java background, we highly recommend comparing the syntaxes and
code implementations once you’ve completed this project to better understand
the similarities and differences between the two languages.
Let’s get to calculating! 🏝
Create a Class
1.
The first step in creating Codey’s individual calculator is to generate a blueprint.
In [Link], declare the class, Calculator, that accepts a name property within
its primary constructor.
Note: Running your code will result in the following error:
could not find or load main class CalculatorKt
This error exists due to the absence of a main() function. If you’d like to get rid of
this error now, go ahead and also create an empty main() function below the
class. Otherwise, move on to the next step.
2.
302
Within the class body, add an init block that will output the owner of the
calculator using the name property.
4.
Next, implement the subtract() function which should calculate and return the
difference between two Integer values.
5.
Another arithmetic function most commonly used on a calculator is
multiplication.
Implement the multiply() function which will calculate and return the product
between two Integer values.
6.
The opposite calculation of multiplication is division. Add a member
function, divide(), which should calculate and return the quotient between two
Integer values.
The member function should return an error message if the user tries to divide
by 0.
7.
303
Lastly, create the power() function which should calculate and return the first
parameter raised to the power of the second.
Think of how you can implement this within the function body. Give it a shot in
the code editor. Move on to the next step for guided instruction.
8.
Within the body of the power() function, declare a new variable, result, and assign
it the value of 1.
To achieve the power calculation, use a looping technique to iterate over each
value, from 1 to param1. Within the body of the loop, reassign the value
of result to be result times param2.
Return result from the function.
Get to Calculating
9.
Now that we’ve implemented several arithmetic functionalities, let’s spring our
calculator to action. If you haven’t already done so, below the class, declare
a main() function.
In it, create a variable name of your choosing that will store an instance of
the Calculator class. Pass in the name, "Codey" in the class call, and run your
code. You should see the output statement from the init block.
10.
On the following line, call the add() function on your instance and pass in two
Integer values consecutively. Wrap your code in a println() statement to see the
output.
11.
304
Use the same syntax to call each member function on your instance on a separate
line and test their calculations. Make sure to wrap each line of code in
a println() statement to see the output.
Optional Challenges
12.
Excellent work! If you’re up for a challenge, check out these additional tasks:
o To mimic a real-world calculator, we can format our output to also
include the original calculation. 12 -> 5 + 7 = 12.
o Having the code as is without any additional output, we can refactor
some of the member functions to utilize a single expression syntax
and shorten the lines of code that they span.
o We can add another member function to the class that you’d like
your calculator to perform.
OUTPUT
Codey's Calculator 🏝
12
34
Error! Dividing by zero is not allowed.
2
305