Problemas prácticos: Conceptos básicos de Kotlin

1. Antes de comenzar

Si bien trabajaste arduamente para conocer los conceptos básicos de la programación de Kotlin, es hora de poner en práctica lo que aprendiste.

Estos ejercicios ponen a prueba tus conocimientos sobre los conceptos que estudiaste. Se relacionan con casos de uso reales, algunos de los cuales probablemente ya viste.

Sigue las instrucciones a fin de encontrar una solución para cada problema. Si no puedes avanzar, algunos de los ejercicios tienen pistas que pueden ayudarte. El código de la solución estará disponible al final, pero te recomendamos que resuelvas los ejercicios antes de comprobar tus respuestas.

Considera las soluciones como una forma de resolver los problemas y no dudes en probar otras alternativas que prefieras. Puedes resolver algunos de los ejercicios de varias maneras y usar nombres diferentes para las funciones y variables.

Resuelve los problemas a un ritmo que te resulte cómodo. Se mostrará una duración determinada, pero no es necesario que cumplas con ese tiempo, ya que solo es una estimación. Recomendamos que te tomes todo el tiempo que necesites para resolver cada problema con cuidado.

Para resolver estos ejercicios, te sugerimos Kotlin Playground.

Requisitos previos

Requisitos

  • Una computadora con acceso a Internet y un navegador web

2. Impresión de mensajes

Comparte con tus amigos lo que aprendiste en esta ruta de aprendizaje.

  • ¿Puedes escribir una función main() que imprima estos mensajes en cuatro líneas separadas?
Use the val keyword when the value doesn't change.
Use the var keyword when the value can change.
When you define a function, you define the parameters that can be passed to it.
When you call a function, you pass arguments for the parameters.

3. Corrección de un error de compilación

Este programa imprime un mensaje que le notifica al usuario que recibió un mensaje de chat de un amigo.

fun main() {
    println("New chat message from a friend'}
}
  1. ¿Puedes determinar la causa raíz de los errores de compilación de este programa y corregirlos?
  2. ¿El código usa los símbolos apropiados para indicar la apertura y el cierre de la cadena y el argumento de la función?

Pista: Puedes usar Kotlin Playground a fin de ejecutar el código y ver los errores de compilación.

Después de corregir los errores, el programa debe compilarse sin problemas y, luego, imprimir este resultado:

New chat message from a friend

4. Plantillas de cadenas

Este programa informa a los usuarios sobre la próxima oferta promocional de un artículo en particular. Tiene una plantilla de cadenas, que se basa en la variable discountPercentage para el porcentaje de descuento y la variable item para el artículo en oferta. Sin embargo, existen errores de compilación en el código.

fun main() {
    val discountPercentage: Int = 0
    val offer: String = ""
    val item = "Google Chromecast"
    discountPercentage = 20
    offer = "Sale - Up to $discountPercentage% discount on $item! Hurry up!"

    println(offer)
}
  1. ¿Puedes determinar la causa raíz de esos errores y corregirlos?
  2. ¿Puedes determinar el resultado de este programa antes de ejecutar el código en Kotlin Playground?

Pista: ¿Puedes reasignar un valor a una variable de solo lectura?

Después de corregir los errores, el programa debe compilarse sin problemas y, luego, imprimir este resultado:

Sale - Up to 20% discount on Google Chromecast! Hurry up!

5. Concatenación de cadenas

Este programa muestra una cantidad total de personas en una fiesta. Entre ellas, hay adultos y niños. La variable numberOfAdults contiene la cantidad de adultos en el grupo, y la variable numberOfKids, la cantidad de niños.

fun main() {
    val numberOfAdults = "20"
    val numberOfKids = "30"
    val total = numberOfAdults + numberOfKids
    println("The total party size is: $total")
}

Paso 1

  • ¿Puedes determinar el resultado de este programa antes de ejecutar el código en Kotlin Playground?

Después de determinar el resultado, ejecuta el código en Kotlin Playground y, luego, verifica si el resultado coincide con el que se muestra.

Pista: ¿Qué sucede cuando usas el operador + en dos cadenas?

Paso 2

El código funciona y, además, imprime algunos resultados, pero los resultados no muestran la cantidad total de personas que asistirán a la fiesta.

  • ¿Puedes encontrar el problema del código y corregirlo de modo que imprima este resultado?
The total party size is: 50

6. Formato de mensajes

Este programa muestra el salario total que recibe un empleado este mes. El salario total se divide en dos partes: la variable baseSalary, que es lo que el empleado recibe todos los meses, y la variable bonusAmount, que es una bonificación adicional otorgada al empleado.

fun main() {
    val baseSalary = 5000
    val bonusAmount = 1000
    val totalSalary = "$baseSalary + $bonusAmount"
    println("Congratulations for your bonus! You will receive a total of $totalSalary (additional bonus).")
}
  1. ¿Puedes determinar el resultado de este código antes de ejecutarlo en Kotlin Playground?
  2. Cuando ejecutas el código en Kotlin Playground, ¿se imprime el resultado que esperabas?

7. Implementación de operaciones matemáticas básicas

En este ejercicio, escribirás un programa que realice operaciones matemáticas básicas y, luego, imprima el resultado.

Paso 1

La función main() contiene un error de compilación:

fun main() {
    val firstNumber = 10
    val secondNumber = 5

    println("$firstNumber + $secondNumber = $result")
}
  • ¿Puedes corregir el error de modo que el programa imprima este resultado?
10 + 5 = 15

Paso 2

El código funciona, pero la lógica para sumar dos números se encuentra dentro de la variable de resultado, lo que hace que el código sea menos flexible a la hora de volver a usarlo. En su lugar, puedes extraer la operación de suma en una función add() para que el código se pueda volver a usar. Para ello, actualiza el código con el que se muestra a continuación. Observa que el código ahora presenta una nueva variable val, llamada thirdNumber, e imprime el resultado de esta variable nueva con firstNumber.

fun main() {
    val firstNumber = 10
    val secondNumber = 5
    val thirdNumber = 8

    val result = add(firstNumber, secondNumber)
    val anotherResult = add(firstNumber, thirdNumber)

    println("$firstNumber + $secondNumber = $result")
    println("$firstNumber + $thirdNumber = $anotherResult")
}

// Define add() function below this line
  • ¿Puedes definir la función add() de modo que el programa imprima este resultado?
10 + 5 = 15
10 + 8 = 18

Paso 3

Ahora tienes una función reutilizable capaz de sumar dos números.

  • ¿Puedes implementar la función subtract() de la misma manera en que implementaste la función add()? Modifica la función main() también para usar la función subtract(), de modo que puedas verificar que funcione como se espera.

Pista: Piensa en la diferencia entre la suma, la resta y otras operaciones matemáticas. Comienza a trabajar en el código de solución a partir de allí.

8. Parámetros predeterminados

Gmail tiene una función que envía notificaciones al usuario cada vez que se intenta acceder a una cuenta en un dispositivo nuevo.

En este ejercicio, escribirás un programa que muestra un mensaje a los usuarios con esta plantilla de mensaje:

There's a new sign-in request on operatingSystem for your Google Account emailId.

Deberás implementar una función que acepte un parámetro operatingSystem y un parámetro emailId, cree un mensaje en el formato dado y lo muestre.

Por ejemplo, si se llamó a la función con "Chrome OS" para el operatingSystem y "sample@gmail.com" para el emailId, se debería mostrar esta cadena:

There's a new sign-in request on Chrome OS for your Google Account sample@gmail.com.

Paso 1

  1. ¿Puedes implementar la función displayAlertMessage() en este programa de modo que imprima el resultado que se muestra?
fun main() {
    val operatingSystem = "Chrome OS"
    val emailId = "sample@gmail.com"

    println(displayAlertMessage(operatingSystem, emailId))
}

// Define your displayAlertMessage() below this line.
  1. ¿El programa imprime este resultado?
There's a new sign-in request on Chrome OS for your Google Account sample@gmail.com.

Paso 2

Bien hecho. Mostraste el mensaje. Sin embargo, en algunos escenarios, notas que no puedes determinar el sistema operativo del usuario. En esos casos, deberás especificar el nombre del sistema operativo como Unknown OS. Puedes optimizar aún más el código para que no necesites pasar el argumento Unknown OS cada vez que se llame a la función.

  1. ¿Puedes encontrar una manera de optimizar el código con esta información de modo que imprima este resultado?
There's a new sign-in request on Unknown OS for your Google Account user_one@gmail.com.

There's a new sign-in request on Windows for your Google Account user_two@gmail.com.

There's a new sign-in request on Mac OS for your Google Account user_three@gmail.com.
  1. Para imprimir el mensaje anterior, reemplaza la implementación de la función main() por la siguiente:
fun main() {
    val firstUserEmailId = "user_one@gmail.com"

    // The following line of code assumes that you named your parameter as emailId.
    // If you named it differently, feel free to update the name.
    println(displayAlertMessage(emailId = firstUserEmailId))
    println()

    val secondUserOperatingSystem = "Windows"
    val secondUserEmailId = "user_two@gmail.com"

    println(displayAlertMessage(secondUserOperatingSystem, secondUserEmailId))
    println()

    val thirdUserOperatingSystem = "Mac OS"
    val thirdUserEmailId = "user_three@gmail.com"

    println(displayAlertMessage(thirdUserOperatingSystem, thirdUserEmailId))
    println()
}

9. Podómetro

El podómetro es un dispositivo electrónico que cuenta la cantidad de pasos que se dan. En la actualidad, casi todos los teléfonos celulares, relojes inteligentes y equipos para hacer ejercicio cuentan con podómetros integrados. La app de Salud y fitness usa los podómetros integrados a fin de calcular la cantidad de pasos que se dan. Esta función calcula la cantidad de calorías que quema el usuario en función de los pasos que da.

  • ¿Puedes cambiar el nombre de las funciones, de los parámetros de las funciones y de las variables utilizados en este programa según las prácticas recomendadas?
fun main() {
    val Steps = 4000
    val caloriesBurned = PEDOMETERstepsTOcalories(Steps);
    println("Walking $Steps steps burns $caloriesBurned calories")
}

fun PEDOMETERstepsTOcalories(NumberOFStepS: Int): Double {
    val CaloriesBURNEDforEachStep = 0.04
    val TotalCALORIESburned = NumberOFStepS * CaloriesBURNEDforEachStep
    return TotalCALORIESburned
}

10. Comparación de dos números

Los teléfonos celulares modernos tienen una función integrada que registra el tiempo de uso (es decir, el tiempo que usas el teléfono cada día).

En este ejercicio, implementarás una función que compara la cantidad de minutos que usaste el teléfono hoy y ayer. La función acepta dos parámetros de números enteros y muestra un valor booleano.

El primer parámetro contiene la cantidad de minutos de uso de hoy, y el segundo, la cantidad de minutos de uso de ayer. La función muestra un valor true si pasaste más tiempo en el teléfono hoy que ayer. De lo contrario, muestra un valor false.

Por ejemplo, si llamaste a la función con estos argumentos con nombre:

  • timeSpentToday = 300 y timeSpentYesterday = 250, la función muestra un valor true.
  • timeSpentToday = 300 y timeSpentYesterday = 300, la función muestra un valor false.
  • timeSpentToday = 200 y timeSpentYesterday = 220, la función muestra un valor false.

Pista: El operador de comparación > muestra un valor true si el valor anterior al operador es mayor que el que aparece después de este. De lo contrario, muestra un valor false.

11. Movimiento del código duplicado a una función

En este programa, se muestra el clima de diferentes ciudades. Incluye el nombre de la ciudad, las temperaturas máxima y mínima del día, y las probabilidades de lluvia.

fun main() {
    println("City: Ankara")
    println("Low temperature: 27, High temperature: 31")
    println("Chance of rain: 82%")
    println()

    println("City: Tokyo")
    println("Low temperature: 32, High temperature: 36")
    println("Chance of rain: 10%")
    println()

    println("City: Cape Town")
    println("Low temperature: 59, High temperature: 64")
    println("Chance of rain: 2%")
    println()

    println("City: Guatemala City")
    println("Low temperature: 50, High temperature: 55")
    println("Chance of rain: 7%")
    println()
}

Hay muchas similitudes en el código que imprime el clima de cada ciudad. Por ejemplo, hay frases que se repiten varias veces, como "City:" y "Low temperature:". Los códigos similares y repetidos crean el riesgo de que se produzcan errores en tu programa. Puede que hayas escrito mal una de las ciudades o que hayas olvidado uno de los detalles del clima.

  1. ¿Puedes crear una función que imprima los detalles del clima de una sola ciudad para reducir la repetición en la función main() y, luego, hacer lo mismo en las ciudades restantes?
  2. ¿Puedes actualizar la función main() a fin de llamar a la función que creaste para cada ciudad y pasar los detalles apropiados del clima como argumentos?

12. Código de solución

La solución usa la función println() para imprimir los mensajes en cada línea.

fun main() {
    println("Use the val keyword when the value doesn't change.")
    println("Use the var keyword when the value can change.")
    println("When you define a function, you define the parameters that can be passed to it.")
    println("When you call a function, you pass arguments for the parameters.")
}

Corrección de un error de compilación

El código contenía los siguientes dos errores de compilación:

  1. La cadena debe terminar con una comilla doble en lugar de una comilla simple.
  2. El argumento de la función debe terminar con un paréntesis en lugar de una llave.
fun main() {
    println("New chat message from a friend")
}

Plantillas de cadenas

Los errores de compilación son el resultado de la asignación de las variables de solo lectura discountPercentage y offer a valores nuevos. No se permite esta tarea.

fun main() {
    val discountPercentage = 20
    val item = "Google Chromecast"
    val offer = "Sale  - Up to $discountPercentage% discount off $item! Hurry Up!"

    println(offer)
}

Como solución alternativa, puedes declarar el número entero discountPercentage y la cadena offer con la palabra clave var. Sin embargo, sus valores son inmutables en el contexto del programa, por lo que puedes conservar la palabra clave val.

Concatenación de cadenas

Paso 1

El programa imprimirá este resultado:

The total party size is: 2030

Esta era una pregunta engañosa. Cuando se usa el operador + en valores de tipo String, se produce una cadena concatenada. Los números enteros están entre comillas dobles, por lo que se tratan como cadenas en lugar de números enteros, de modo que el resultado es 2030.

Paso 2

Puedes quitar las comillas dobles que rodean las variables numberOfAdults y numberOfKids a fin de convertirlas en variables de tipo Int.

fun main() {
    val numberOfAdults = 20
    val numberOfKids = 30
    val total = numberOfAdults + numberOfKids
    println("The total party size is: $total")
}

Recuerda que el compilador de Kotlin puede inferir el tipo de variables según los valores asignados a ellas. En este caso, el compilador infiere que las variables numberOfAdults y numberOfKids son de tipo Int.

Formato de mensajes

El programa imprimirá este resultado:

Congratulations for your bonus! You will receive a total of 5000 + 1000 (additional bonus).

"$baseSalary + $bonusAmount" usa la sintaxis de expresiones de plantillas. En las expresiones de plantillas, primero se evalúa el código y, luego, se concatena el resultado en una cadena.

En la pregunta, la variable $baseSalary se evalúa como un valor de 5000 y la variable $bonusAmount se evalúa como un valor de 1000. Luego, se concatena el resultado para producir "5000 + 1000" y se asigna a la variable result.

Implementación de operaciones matemáticas básicas

Paso 1

Define una variable result inmutable con la palabra clave val y, luego, asígnale el resultado de la operación de suma:

fun main() {
    val firstNumber = 10
    val secondNumber = 5

    val result = firstNumber + secondNumber
    println("$firstNumber + $secondNumber = $result")
}

Paso 2

  1. Crea una función add() que acepte los parámetros firstNumber y secondNumber, ambos del tipo Int, y que muestre un valor de tipo Int.
  2. Ingresa el código de la operación de suma dentro del cuerpo de la función add() y, luego, usa la palabra clave return para mostrar el resultado de la operación.
fun add(firstNumber: Int, secondNumber: Int): Int {
    return firstNumber + secondNumber
}

Paso 3

  1. Define una función subtract() que acepte un parámetro firstNumber y un parámetro secondNumber, ambos del tipo Int, y que muestre un valor Int.
  2. Ingresa el código de la operación de resta dentro del cuerpo de la función subtract() y, luego, usa la palabra clave return para mostrar el resultado de la operación.
fun subtract(firstNumber: Int, secondNumber: Int): Int {
    return firstNumber - secondNumber
}
  1. Modifica la función main() para usar la nueva función subtract(). Una solución de ejemplo podría verse así:
fun main() {
    val firstNumber = 10
    val secondNumber = 5
    val thirdNumber = 8

    val result = add(firstNumber, secondNumber)
    val anotherResult = subtract(firstNumber, thirdNumber)

    println("$firstNumber + $secondNumber = $result")
    println("$firstNumber - $thirdNumber = $anotherResult")
}

fun add(firstNumber: Int, secondNumber: Int): Int {
    return firstNumber + secondNumber
}

fun subtract(firstNumber: Int, secondNumber: Int): Int {
    return firstNumber - secondNumber
}

Parámetros predeterminados

Paso 1

  1. Crea una función displayAlertMessage() que acepte un parámetro operatingSystem y un parámetro emailId, ambos del tipo String, y que muestre un valor String.
  2. En el cuerpo de la función, usa una expresión de plantilla para actualizar el mensaje y mostrarlo.
fun displayAlertMessage(operatingSystem: String, emailId: String): String {
    return "There is a new sign-in request on $operatingSystem for your Google Account $emailId."
}

Paso 2

  • Asigna un valor "Unknown OS" al parámetro operatingSystem.
fun displayAlertMessage(
    operatingSystem: String = "Unknown OS",
    emailId: String
): String {
    return "There is a new sign-in request on $operatingSystem for your Google Account $emailId."
}

Podómetro

Los nombres de las funciones y las variables deben cumplir con la convención de mayúsculas y minúsculas.

Si los nombres contienen varias palabras, usa la minúscula para la primera letra de la primera palabra, usa mayúsculas para la primera letra de las palabras subsiguientes y quita los espacios que haya entre todas ellas.

Estos son algunos ejemplos de nombres de funciones:

  • calculateTip
  • displayMessage
  • takePhoto

Estos son algunos ejemplos de nombres de variables:

  • numberOfEmails
  • cityName
  • bookPublicationDate

Para obtener más información sobre los nombres, consulta el artículo sobre reglas de asignación de nombres.

Evita usar una palabra clave de Kotlin como nombre de función, ya que esas palabras ya tienen asignados significados específicos en el lenguaje Kotlin.

El código de solución debería verse como este fragmento de código:

fun main() {
    val steps = 4000
    val caloriesBurned = pedometerStepsToCalories(steps);
    println("Walking $steps steps burns $caloriesBurned calories")
}

fun pedometerStepsToCalories(numberOfSteps: Int): Double {
    val caloriesBurnedForEachStep = 0.04
    val totalCaloriesBurned = numberOfSteps * caloriesBurnedForEachStep
    return totalCaloriesBurned
}

Comparación de dos números

  • Crea una función compareTime() que acepte los parámetros timeSpentToday y timeSpentYesterday, ambos del tipo Int, y que muestre un valor de tipo Boolean.

La solución se basa en el operador de comparación >. El operador se evalúa como un valor de tipo Boolean, por lo que la función compareTime() solo muestra el resultado de timeSpentToday > timeSpentYesterday.

Por ejemplo, si pasas un argumento de 300 al parámetro timeSpentToday y un argumento de 250 al parámetro timeSpentYesterday, el cuerpo de la función se evaluará como 300 > 250, lo cual muestra un valor true porque 300 es mayor que 250.

fun main() {
    println("Have I spent more time using my phone today: ${compareTime(300, 250)}")
    println("Have I spent more time using my phone today: ${compareTime(300, 300)}")
    println("Have I spent more time using my phone today: ${compareTime(200, 220)}")
}

fun compareTime(timeSpentToday: Int, timeSpentYesterday: Int): Boolean {
    return timeSpentToday > timeSpentYesterday
}
Have I spent more time using my phone today: true
Have I spent more time using my phone today: false
Have I spent more time using my phone today: false

Movimiento del código duplicado a una función

  1. Crea una función que imprima los detalles del clima para la ciudad de Ankara después de la función main().

Como nombre de la función, puedes usar printWeatherForCity() o algo similar.

  1. Llama a la función desde la función main().

El programa debe imprimir los detalles del clima para Ankara.

fun main() {
    printWeatherForCity()
}

fun printWeatherForCity() {
    println("City: Ankara")
    println("Low temperature: 27, High temperature: 31")
    println("Chance of rain: 82%")
    println()
}

Ahora puedes crear otra función que sea más flexible, de manera que puedan imprimir los detalles del tiempo para otras ciudades.

  1. Reemplaza las partes específicas de Ankara de las sentencias println() por variables.

Recuerda usar la convención de mayúsculas y minúsculas para los nombres de variables y el símbolo $ antes de la variable de modo que se use el valor de esta en lugar de su nombre. Estas son plantillas de cadenas que aprendiste en un codelab anterior.

fun printWeatherForCity() {
    println("City: $cityName")
    println("Low temperature: $lowTemp, High temperature: $highTemp")
    println("Chance of rain: $chanceOfRain%")
    println()
}
  1. Cambia la definición de la función a fin de que esas variables sean parámetros que se deban pasar a la función cuando se la llame, y especifica el tipo de datos para cada parámetro.

El parámetro cityName es del tipo String, mientras que los parámetros lowTemp, highTemp y chanceOfRain son del tipo Int.

No se necesita un valor de return en la definición de la función porque los mensajes se imprimen en el resultado.

fun printWeatherForCity(cityName: String, lowTemp: Int, highTemp: Int, chanceOfRain: Int) {
    println("City: $cityName")
    println("Low temperature: $lowTemp, High temperature: $highTemp")
    println("Chance of rain: $chanceOfRain%")
    println()
}
  1. Actualiza la función main() para llamar a la función printWeatherForCity() y pasar los detalles del clima para Ankara.

El nombre de la ciudad es "Ankara", la temperatura mínima es 27, la temperatura máxima es 31 y la probabilidad de lluvia es 82.

fun main() {
    printWeatherForCity("Ankara", 27, 31, 82)
}

fun printWeatherForCity(cityName: String, lowTemp: Int, highTemp: Int, chanceOfRain: Int) {
    println("City: $cityName")
    println("Low temperature: $lowTemp, High temperature: $highTemp")
    println("Chance of rain: $chanceOfRain%")
    println()
}
  1. Ejecuta el programa para verificar que el resultado muestre los detalles del clima de Ankara.
  2. Llama a la función printWeatherForCity() con los detalles del clima de las otras ciudades.
fun main() {
    printWeatherForCity("Ankara", 27, 31, 82)
    printWeatherForCity("Tokyo", 32, 36, 10)
    printWeatherForCity("Cape Town", 59, 64, 2)
    printWeatherForCity("Guatemala City", 50, 55, 7)
}

fun printWeatherForCity(cityName: String, lowTemp: Int, highTemp: Int, chanceOfRain: Int) {
    println("City: $cityName")
    println("Low temperature: $lowTemp, High temperature: $highTemp")
    println("Chance of rain: $chanceOfRain%")
    println()
}
  1. Ejecuta el programa.

Debería mostrar el mismo resultado que el programa original, pero ahora tu código es más conciso y no contiene repeticiones innecesarias. Todo el código que imprime los detalles del clima de una ciudad se centraliza en un solo lugar: la función printWeatherForCity(). Si en algún momento deseas cambiar la forma en que se muestran los detalles del clima, puedes hacerlo en un solo lugar que se aplique a todas las ciudades.

13. Práctica adicional

Si deseas obtener más información sobre el lenguaje Kotlin, consulta la segmentación básica de Kotlin en JetBrains Academy. Para ir a un tema específico, ve al mapa del conocimiento a fin de ver la lista de temas del segmento.