Membuat Aplikasi Pengubah Angka ke Kata dengan Kotlin
Kali ini kita akan membuat aplikasi sederhana yang saya sebut dengan Pengubah Angka Ke Kata. Aplikasi ini akan mengubah sebuah angka menjadi kata berbahasa Indonesia. Misalnya kita memasukkan angka 235 maka aplikasi akan mengeluarkan “Dua Ratus Tiga Puluh Lima”.
Sebelum kalian memulai tutorial ini saya sarankan kalian mempelajari konsep berikut:
- Belajar Dasar Kotlin: Variabel dan Tipe Data Dasar
- Belajar Dasar Kotlin: Operator Dasar
- Belajar Dasar Kotlin: Kondisional
- Kotlin: Mengenal Null Safety
- Kotlin: Mengenal Range
Membuat Project
Pada tutorial ini saya menggunakan IntelliJ IDEA 2022.1 (Community Edition). Sebelum menulis kode kalian buat proyek baru di IDEA dengan opsi seperti ini:
Input | Isi |
---|---|
Name | angka_ke_kata |
Languages | Pilih Kotlin |
Build System | Pilih IntelliJ |
Untuk JDK kalian pilih JDK yang ada di system kalian. Saya menggunakan JDK 17. Kemudian klik Create.
Kemudian klik kanan pada src > main > kotlin kemudian pilih New > Kotlin Class/File
Isi nama file dengan AngkaKeKata dan kemudian pada pilihan di bawahnya pilih File. Lalu tekan Enter.
Maka akan file bernama AngkaKeKata.kt
akan terbuat.
Meminta Input Pengguna
Program kita pertama-pertama harus meminta input ke pengguna. Proses yang kita lakukan seperti ini:
- Mencetak kalimat perintah
- Meminta input dari pengguna menggunakan
readln
- Mengubah input pengguna menjadi Int
- Mengubah Int/angka menjadi kata
- Mencetak kata hasil
Isi AngkaKeKata.kt
dengan kode berikut:
fun main() {
println("Tolong masukkan angka yang akan diubah menjadi kata!")
val teks = readln()
val angka = teks.toInt()
val kata = angkaKeKata(angka)
println(kata)
}
fun angkaKeKata(angka: Int): String {
return "Tidak bisa"
}
Kemudian kalian bisa menjalankan kode dengan mengeklik tombol Run di sebelah kiri fungsi main
.
Angka apa pun yang kita masukkan aplikasi pasti akan mencetak Tidak Bisa.
Tolong masukkan angka yang akan diubah menjadi kata!
12
Tidak bisa
Selanjutnya kalian bisa menjalankan aplikasi dengan mengeklik tombol Run yang berada di Toolbar.
Angka Dasar (0-11)
Pertama kita mulai dengan kasus yang paling sederhana, kita hanya perlu menggunakan kondisional.
Ubah fungsi angkaKeKata
menjadi seperti ini:
fun angkaKeKata(angka: Int): String {
return when (angka) {
0 -> "Nol"
1 -> "Satu"
2 -> "Dua"
3 -> "Tiga"
4 -> "Empat"
5 -> "Lima"
6 -> "Enam"
7 -> "Tujuh"
8 -> "Delapan"
9 -> "Sembilan"
10 -> "Sepuluh"
11 -> "Sebelas"
else -> "Tidak bisa diubah"
}
}
Sederhana sekali bukan?. Lalu kenapa kita menambahkan cabang Else?. Pada kode di atas kita menggunakan When sebagai ekspresi untuk menghasilkan nilai, maka Kotlin memaksa kita menambahkan klausa Else agar When bisa menghasilkan nilai pada kondisi apa pun.
Kita coba lagi menjalankan kodenya. Kita coba dengan angka 7.
Tolong masukkan angka yang akan diubah menjadi kata!
7
Tujuh
Angka Belasan (12-19)
Pada kasus ini kita perlu melakukan proses seperti berikut:
- Mencari satuan dari angka, caranya dengan mengurangi angka dengan 10
- Mengubah satuan menjadi kata
- Menambah “Belas” ke hasil
Tambahkan kode berikut tepat sebelum cabang Else pada When:
|
|
Nilai String pada akhir blok kode menjadi nilai yang dihasilkan When yaitu kode baris ke 3.
Kita coba untuk mengubah angka 19. Hasilnya:
Tolong masukkan angka yang akan diubah menjadi kata!
19
Sembilan Belas
Angka Puluhan (20-99)
Pada kasus ini kita perlu melakukan proses seperti berikut:
- Mencari puluhan dari angka, dengan cara membagi angka dengan 10 kemudian membulatkannya ke bawah
- Mencari satuan dari angka, dengan cara mencari sisa pembagian (modulus) angka dengan 10.
Misalkan angka 23. Maka puluhannya 2 dan satuannya 3. - Hasilnya adalah puluhan + " Puluh " + satuan
- Jika satuannya 0, maka satuan tidak perlu ditambahkan ke hasil
Tambahkan kode berikut tepat sebelum cabang When Else:
in 20 until 100 -> {
val puluhan = floor(angka / 10.0).toInt()
val satuan = angka % 10
var result = "${angkaKeKata(puluhan)} Puluh"
if (satuan > 0)
result += " ${angkaKeKata(satuan)}"
result
}
Jika terjadi error pada floor
maka arahkan cursor ke floor
kemudian klik Import.
Lalu pilih pilihan paling atas sendiri.
Fungsi floor
digunakan untuk membulatkan angka ke bawah dan menghasilkan angka bertipe Double.
Fungsi floor
membutuhkan angka Double sehingga pada pembagian salah satu operannya adalah Double
(10.0
). Fungsi toInt
digunakan untuk mengubah Double menjadi Int agar bisa digunakan sebagai
argumen fungsi angkaKeKata
.
Kita coba angka 57. Hasilnya seperti ini:
Tolong masukkan angka yang akan diubah menjadi kata!
57
Lima Puluh Tujuh
Angka Ratusan (100-999)
Pada kasus ini kita perlu melakukan proses seperti berikut:
- Mencari ratusan dari angka, dengan cara membagi angka dengan 100 kemudian membulatkannya ke bawah
- Mencari sisa dari angka, dengan cara mencari sisa pembagian angka dengan 100.
Misalkan angka 235. Maka ratusannya 2 dan sisanya 35. - Jika ratusannya 1 maka hasilnya adalah “Seratus”, selain itu hasilnya adalah ratusan + " Ratus"
- Jika sisa lebih dari 0, maka hasilnya ditambah sisa yang diubah menjadi kata
Tambahkan kode berikut tepat sebelum cabang When Else:
in 100 until 1_000 -> {
val ratusan = floor(angka / 100.0).toInt()
val sisa = angka % 100
var result = if (ratusan == 1) "Seratus" else "${angkaKeKata(ratusan)} Ratus"
if (sisa > 0 )
result += " ${angkaKeKata(sisa)}"
result
}
Kita coba dengan angka 734. Hasilnya:
Tolong masukkan angka yang akan diubah menjadi kata!
734
Tujuh Ratus Tiga Puluh Empat
Angka Ribuan (1.000-999.999)
Pada kasus ini kita perlu melakukan proses seperti berikut:
- Mencari ribuan dari angka, dengan cara membagi angka dengan 1.000 kemudian membulatkannya ke bawah
- Mencari sisa dari angka, dengan cara mencari sisa pembagian angka dengan 1.000.
Misalkan angka 23.578. 23 adalah ribuan dan 578 adalah sisanya. - Jika ribuannya adalah 1, hasilnya adalah “Seribu”. Selain itu hasilnya adalah ribuan + " Ribu"
- Jika sisa lebih dari 0, maka hasilnya ditambah sisa yang diubah menjadi kata
Tambahkan kode berikut tepat sebelum cabang When Else:
in 1_000 until 1_000_000 -> {
val ribuan = floor(angka / 1_000.0).toInt()
val sisa = angka % 1_000
var result = if (ribuan == 1) "Seribu" else "${angkaKeKata(ribuan)} Ribu"
if (sisa > 0)
result += " ${angkaKeKata(sisa)}"
result
}
Kita coba dengan angka 5194. Hasilnya:
Tolong masukkan angka yang akan diubah menjadi kata!
5194
Lima Ribu Seratus Sembilan Puluh Empa
Merefractor Kode
Aplikasi yang kita buat sudah berjalan lancar dan sudah sesuai dengan keinginan kita. Sekarang kodenya seperti ini:
import kotlin.math.floor
fun main() {
println("Tolong masukkan angka yang akan diubah menjadi kata!")
val teks = readln()
val angka = teks.toInt()
val kata = angkaKeKata(angka)
println(kata)
}
fun angkaKeKata(angka: Int): String {
return when (angka) {
0 -> "Nol"
1 -> "Satu"
2 -> "Dua"
3 -> "Tiga"
4 -> "Empat"
5 -> "Lima"
6 -> "Enam"
7 -> "Tujuh"
8 -> "Delapan"
9 -> "Sembilan"
10 -> "Sepuluh"
11 -> "Sebelas"
in 12 until 20 -> {
val satuan = angka - 10
"${angkaKeKata(satuan)} Belas"
}
in 20 until 100 -> {
val puluhan = floor(angka / 10.0).toInt()
val satuan = angka % 10
var result = "${angkaKeKata(puluhan)} Puluh"
if (satuan > 0)
result += " ${angkaKeKata(satuan)}"
result
}
in 100 until 1_000 -> {
val ratusan = floor(angka / 100.0).toInt()
val sisa = angka % 100
var result = if (ratusan == 1) "Seratus" else "${angkaKeKata(ratusan)} Ratus"
if (sisa > 0)
result += " ${angkaKeKata(sisa)}"
result
}
in 1_000 until 1_000_000 -> {
val ribuan = floor(angka / 1_000.0).toInt()
val sisa = angka % 1_000
var result = if (ribuan == 1) "Seribu" else "${angkaKeKata(ribuan)} Ribu"
if (sisa > 0)
result += " ${angkaKeKata(sisa)}"
result
}
else -> "Tidak bisa diubah"
}
}
Namun, perhatikan kode secara seksama maka akan terlihat beberapa kode yang terlihat sangat mirip. Kode untuk mengubah angka ratusan dan ribuan terlihat mirip.
Agar kode lebih ringkas, kita dapat membuat fungsi baru bernama ubahAngkaKelipatan
. Fungsi ini
akan kita taruh di dalam fungsi angkaKeKata
.
fun angkaKeKata(angka: Int): String {
fun ubahAngkaKelipatan(pembagi: Int, kataKelipatan1: String, suffiks: String): String {
val kelipatan = floor(angka / pembagi.toDouble()).toInt()
val sisa = angka % pembagi
var result = if (kelipatan == 1) kataKelipatan1 else "${angkaKeKata(kelipatan)} $suffiks"
if (sisa > 0)
result += " ${angkaKeKata(sisa)}"
return result
}
// ...
}
Angka 100, 1000 kita representasikan dengan parameter pembagi
. Teks Seratus
dan Seribu
kita
representasikan dengan parameter kataKelipatan1
. Ratus
dan Ribu
kita representasikan dengan
parameter suffiks
. Variabel ratusan
dan ribuan
kita representasikan dengan variabel
kelipatan
.
Mengapa fungsi ubahAngkaKelipatan
kita masukkan ke dalam fungsi angkaKeKata
?. Karena pada fungsi
ubahAngkaKelipatan
kita perlu mengakses variabel angka
dan agar fungsi ini tidak bisa dipanggil
dari luar fungsi angkaKeKata
.
Kode untuk kasus puluhan, ratusan dan ribuan perlu kita ubah menjadi seperti ini:
in 20 until 100 -> ubahAngkaKelipatan(10, "", "Puluh")
in 100 until 1_000 -> ubahAngkaKelipatan(100, "Seratus", "Ratus")
in 1_000 until 1_000_000 -> ubahAngkaKelipatan(1_000, "Seribu", "Ribu")
Pada kasus puluhan, kita juga menggunakan menggunakan ubahAngkaKelipatan
karena proses pada kasus
puluhan sama dengan proses pada kasus ratusan dan ribuan. Bedanya pada kasus puluhan,
puluhan/kelipatannya tidak mungkin bernilai 1 karena kasus puluhan hanya terjadi pada angka 20
sampai 99. Oleh karena itu, pada kasus puluhan kataKelipatan1
kita kosongkan.
Kode bisa kalian coba lagi dan hasilnya akan tetap sama seperti tadi.
Angka Jutaan dan Milyaran
Pada kasus ini, proses yang kita lakukan mirip dengan kasus pada angka ribuan. Kita bisa gunakan
fungsi ubahAngkaKelipatan
pada kasus ini. Namun, pada terdapat sedikit perbedaan. 1.000.000 dibaca
Satu Juta bukan Sejuta.
Jadi, bagaimana kita mengatasi ini?. Jadi kita membuat kataKelipatan1
menjadi Nullable dan hanya
digunakan saat tidak null. Kita perlu mengubah fungsi ubahAngkaKelipatan
menjadi seperti ini:
fun ubahAngkaKelipatan(pembagi: Int, kataKelipatan1: String?, suffiks: String): String {
val kelipatan = floor(angka / pembagi.toDouble()).toInt()
val sisa = angka % pembagi
var result = if (kelipatan == 1 && kataKelipatan1 != null) kataKelipatan1
else "${angkaKeKata(kelipatan)} $suffiks"
if (sisa > 0)
result += " ${angkaKeKata(sisa)}"
return result
}
Ubah cabang Else pada When menjadi seperti berikut:
in 1_000_000 until 1_000_000_000 -> ubahAngkaKelipatan(1_000_000, null, "Juta")
else -> ubahAngkaKelipatan(1_000_000_000, null, "Milyar")
Untuk kode Else kita gunakan untuk Milyar karena Int hanya bisa menampung angka sampai 2 milyar.
Kita bisa coba 2147483647. Hasilnya:
Tolong masukkan angka yang akan diubah menjadi kata!
2147483647
Dua Milyar Seratus Empat Puluh Tujuh Juta Empat Ratus Delapan Puluh Tiga Ribu Enam Ratus Empat Puluh Tujuh
Angka tersebut merupakan angka maksimal yang bisa ditampung oleh Int.
Kode Akhir
Kode akhirnya seperti ini:
import kotlin.math.floor
fun main() {
println("Tolong masukkan angka yang akan diubah menjadi kata!")
val teks = readln()
val angka = teks.toInt()
val kata = angkaKeKata(angka)
println(kata)
}
fun angkaKeKata(angka: Int): String {
fun ubahAngkaKelipatan(pembagi: Int, kataKelipatan1: String?, suffiks: String): String {
val kelipatan = floor(angka / pembagi.toDouble()).toInt()
val sisa = angka % pembagi
var result = if (kelipatan == 1 && kataKelipatan1 != null) kataKelipatan1
else "${angkaKeKata(kelipatan)} $suffiks"
if (sisa > 0)
result += " ${angkaKeKata(sisa)}"
return result
}
return when (angka) {
0 -> "Nol"
1 -> "Satu"
2 -> "Dua"
3 -> "Tiga"
4 -> "Empat"
5 -> "Lima"
6 -> "Enam"
7 -> "Tujuh"
8 -> "Delapan"
9 -> "Sembilan"
10 -> "Sepuluh"
11 -> "Sebelas"
in 12 until 20 -> {
val satuan = angka - 10
"${angkaKeKata(satuan)} Belas"
}
in 20 until 100 -> ubahAngkaKelipatan(10, "", "Puluh")
in 100 until 1_000 -> ubahAngkaKelipatan(100, "Seratus", "Ratus")
in 1_000 until 1_000_000 -> ubahAngkaKelipatan(1_000, "Seribu", "Ribu")
in 1_000_000 until 1_000_000_000 -> ubahAngkaKelipatan(1_000_000, null, "Juta")
else -> ubahAngkaKelipatan(1_000_000_000, null, "Milyar")
}
}
Akhir Kata
Pada tutorial ini kalian telah belajar banyak sekali konsep dalam bahasa Kotlin.