Swift – Ejercicios propuestos (I)

Pedirle un número al usuario y decir si es par usando «if»

var numero:Int;

print("Dime un número: ", terminator:"")
numero = Int(readLine()!)!

// Comprobamos si es par
if numero % 2 == 0 {
	print("\(numero) es par")
}
else {
    print("\(numero) no es par")
}

Pedirle dos números al usuario y ver cuál es el mayor de ellos





Pedirle al usuario un número. Si es múltiplo de 10, pedirle un segundo número y comprobar si también es múltiplo de 10

var numero1 = 0
var numero2 = 0

print("Dime el primer numero: ", terminator:"")
numero1 = Int(readLine()!) ?? 0 

if numero1 % 10 == 0 {
    print("\(numero1) es multiplo de 10, dame otro numero: ", terminator:"")
    numero2 = Int(readLine()!) ?? 0 
    
    if numero2 % 10 == 0 {
        print("El número \(numero2) también es múltiplo de 10\n")
    }
    else {
        print("El número \(numero2) no es múltiplo de 10\n")
    }
}
else {
    print("El número \(numero1) no es múltiplo de 10\n")
}

Multiplicar dos números si el primero no es cero (si es cero, avisar de que el resultado será cero)

var numero1 = 0
var numero2 = 0

print("Dime el primer numero: ", terminator:"")
numero1 = Int(readLine()!) ?? 0 

print("Dime el segundo numero: ", terminator:"")
numero2 = Int(readLine()!) ?? 0 

if numero1 == 0 || numero2 == 0 {
    print("Te va a dar cero\n")
}
else {
    print("La multiplicación de \(numero2) y \(numero1) es \(numero1*numero2)\n")
}

Pedirle al usuario un número e indicar si es múltiplo de 2 o de 3 (de cualquiera de ellos, sin importar cuál)

print("Dime un numero: ", terminator:"")
var numero = Int(readLine()!) ?? 0 

if numero % 2 == 0 || numero % 3 == 0 {
    print("El \(numero) es multiplo de 2 o de 3")
}
else {
    print("El \(numero) no es multiplo ni de 2 ni de 3")    
}

Pedirle al usuario un número e indicarle si es múltiplo de 2 y de 3 (a la vez)

print("Dime un numero: ", terminator:"")
var numero = Int(readLine()!) ?? 0 

if numero % 2 == 0 && numero % 3 == 0 {
    print("El \(numero) es multiplo de 2 y de 3")
}
else {
    print("El \(numero) no es múltiplo de 2 y 3 al mismo tiempo")    
}

Pedirle al usuario un número e indicarle si es múltiplo de 2 pero no de 3





Pedirle al usuario un número e indicarle si no es múltiplo de 2 ni de 3





Pedirle al usuario dos números e indicarle si ambos son pares





Pedirle al usuario dos números e indicarle si al menos uno es par





Pedirle al usuario dos números e indicarle si uno y solo uno es par





Pedirle al usuario que escriba dos números e indicarle uno de estos casos: Uno de ellos (pero no los dos) es positivo, los dos son positivos, o ninguno es positivo





Pedirle al usuario que escriba tres números e indicarle cuál es el mayor





Pedirle al usuario que escriba dos números e indicarle si son iguales o cuál es el mayor

var numero1 = 0
var numero2 = 0

print("Dime el primer numero: ", terminator:"")
numero1 = Int(readLine()!) ?? 0 

print("Dime el segundo numero: ", terminator:"")
numero2 = Int(readLine()!) ?? 0 

if numero1 == numero2 {
    print("Los dos números son iguales\n")
}
else if numero1 > numero2 {
    print("El numero \(numero1) es mayor que \(numero2)\n")
}
else {
    print("El numero \(numero2) es mayor que \(numero1)\n")
}

Usar el operador condicional ?: para mostrar el valor absoluto de un número





Usar el operador condicional ?: para detectar el menor de dos números





Utilizar un switch para pedirle al usuario un número del 1 al 10 y escribirlo en letra («uno», «dos», etc.)





Utilizar switch para pedirle al usuario un carácter e indicar el tipo: cifra numérica, signo de puntuación y otro carácter





Utilizar un switch para pedirle al usuario una letra y ver si ha escrito una vocal, un dígito o una consonante





Pedirle al usuario su contraseña numérica mientras no escriba 1111





Pedir un número por teclado e imprimir el cuadrado de dicho número





Pedirle al usuario dos números continuamente y ver cuál es múltiplo de cuál, o si no son múltiplos





Contador descendente de números pares del 26 al 10, usando while





Calcular cuántas cifras tiene un número entero positivo





Utilizando un bucle de tipo repeat while, sumar números positivos hasta que introduzcamos un 0 o un número negativo

var numero:Int, total = 0

repeat {
    print("Dime un numero: ", terminator:"")
    numero = Int(readLine()!) ?? 0 
    total += numero
} while numero > 0

print("Total sumado: \(total)")

Utilizando un bucle de tipo repeat while, pedirle al usuario su identificador y contraseña hasta que no escriba 1234 y 1111 respectivamente





Utilizando un bucle repeat while, pedirle al usuario su identificador y contraseña hasta que no escriba Pedro y Peter respectivamente





Mostrar los números del 10 al 20 ambos incluidos





Contar del 1 al 50 usando for y decir cuales son múltiplos de 3





Mostrar los números divisibles entre 7 y 3 que estén entre el 100 y el 200, usando un bucle for in





Imprimir la tabla de multiplicar del 9 usando for in





Mostrar los 8 primeros números pares





Mostrar del 15 al 5 descendiendo





Bucle infinito para mostrar «Hola» sin parar en pantalla





Bucle infinito para mostrar los enteros positivos a partir del 1





Utilizando bucles anidados, mostrar si los números estre el 10 y el 20 son divisibles entre 5, 6 o 7





Utilizando bucles anidados, mostrar 10 veces los números del 1 al 5, en 10 líneas separadas





Dibujar un cuadrado de asteriscos del ancho y alto que diga el usuario





Imprimir un rectángulo de asteriscos del ancho y alto especificado por el usuario





Dibujar un triángulo de asteriscos creciente, de tantas alturas como diga el usuario





Dibujar un triángulo de asteriscos decreciente, de tantas alturas como diga el usuario





Imprimir los divisores comunes de dos números





Imprimir el máximo común divisor de dos números





Imprimir el máximo común divisor de dos números utilizando un break para terminar cuando se haya encontrado





Imprimir el mínimo común múltiplo de dos números





Imprimir el mínimo común múltiplo de dos números utilizando un break para terminar cuando se haya encontrado





Imprimir una cuenta atrás desde el número introducido por teclado (entre el 1 y el 10)





Adivinar un número prefijado en el programa





Adivinar un número del 1 al 100 (prefijado) en 6 intentos como máximo





Averiguar si un número dado por el usuario es primo





Imprimir los factores primos de un número dado por el usuario





Calcular un número elevado a otro usando multiplicaciones sucesivas





Dibujar un rectángulo hueco, utilizando la altura y la anchura proporcionadas por el usuario





Devolver el cambio de una compra con los billetes y monedas más grandes posibles





Pedirle al usuario edad y año de nacimiento y dar aviso de error en el momento en que introduzca un dato incorrecto (por ejemplo, que ponga «Hola» al pedirle la edad)





Hallar el volumen de una esfera dado su radio. Volumen = pi * radio al cubo * 4/3





Mostrar el valor de y para los primeros 20 valores de x: y = x2 – 1





Calcula el perímetro, área y diagonal de un rectángulo dados su ancho y alto





Pedir al usuario su nombre y su contraseña dos veces, hasta que las dos contraseñas introducidas coincidan





Utilizando funciones

Crear una función que reciba como parámetro la longitud del lado de un cuadrado y lo dibuje utilizando asteriscos





Crear una función que reciba como parámetros la base y la altura de un rectángulo y lo dibuje utilizando asteriscos





Crear una función que reciba como parámetros un carácter y un número y repita ese carácter tantas veces como indique el número





Crear un función que devuelva el cubo de un número real pasado por parámetro





Crear una función para pedirle un número al usuario. Dicha función debe recibir como parámetro el texto a mostrar al usuario y el límite inferior y superior del entero que éste debe introducir, y repetirle que lo introduzca hasta que ponga un número correcto





Crear una función que reciba un entero y devuelva un booleano indicando si el número es primo o no


	

Swift – Opcionales

Introducción

Como hemos comentado previamente, una de las ventajas que nos da Swift es la posibilidad de escribir código seguro. Esto implica que swift está preparado para que las aplicaciones no se encuentren con situaciones indeseadas al momento de ejecutar el código. Los opcionales son un mecanismo muy importante para conseguir este objetivo.

Los opcionales permiten indicar que un valor puede estar ausente. Esto significa que una variable opcional puede tener un valor y por lo tanto se puede acceder al mismo o que esa variable esta “vacía”.

La potencia de este enfoque es que si se sabe que una variable puede llegar a no tener valor en algún momento de su ciclo de vida, podemos escribir código adicional preguntando si ese valor existe o no, estando seguros en todo momento sobre qué hacer en cada caso.

Si no existieran los opcionales, puede darse el caso de que no contemplemos un escenario en donde el valor no exista y por lo tanto se generen comportamientos extraños en momentos de ejecución. Veamos un ejemplo:

let colores = ["azul", "negro", "verde", "rojo", "amarillo"]

let primerColor = colores.first

//primerColor es es String? en lugar de String

Primero definimos un array de String donde guardamos un listado de colores y luego, creamos una constante para obtener el primero color del arreglo usando la propiedad first.

Como puede darse el caso de que el array esté vacío, first no siempre va a devolver un valor; en algunos casos tomará el primer elemento pero en otros indicará que no se encontró un valor. Esto hace que el resultado sea un opcional.

nil

Volviendo al ejemplo anterior, para indicar la ausencia de un valor se usa un valor especial llamado nil.

Por lo tanto, la constante primerColor no se trata de un tipo String sino de un opcional de String, indicado con un signo de pregunta (?) String?.

Si quisiéramos definir una variable como opcional usamos la siguiente forma:

var segundoColor: String? = "negro"
print("\(segundoColor)")

//Devuelve:
//Optional(“negro”)

segundoColor = nil
print("\(segundoColor)")

//Devuelve:
//nil

Como vemos, definimos la variable indicando el tipo de dato y agregando un signo de pregunta para indicar que se trata de un opcional.

La asignación de un valor en ese momento es optativo, ya que de no hacerlo Swift infiere que su valor inicial es nil.

Si imprimimos esa variable usando print vemos que su valor es Optional(“negro”) en lugar de “negro” a secas.

Una variable opcional puede volver a valer nil si es necesario.

Recordemos que las variables no opcionales deben tener un valor al momento de su definición obligatoriamente.

Forced unwrapping

Si sabemos y estamos seguros que en un determinado momento una variable opcional tiene un valor en su interior, podemos usar la técnica de forced unwrapping (desenvoltura forzada) mediante el uso de un signo de exclamación al final del nombre de la variable (!):

var otroColor:String? = "celeste"
print(“\(otroColor!)”)
//Devuelve
//celeste

Como sabemos que la variable otroColor contiene un valor, usamos la desenvoltura forzada y accedemos al dato que el mismo encierra. Ya no estamos obteniendo un Optional(“celeste”) sino que directamente obtenemos “celeste”.

Si quisiéramos preguntar primero si esa variable vale nil o no, una posibilidad es usar una sentencia if:

if otroColor != nil {
    print("\(otroColor!)")
}

//Devuelve
//celeste

En este caso, primero nos aseguramos si la variable no vale nil (o sea, si tiene un valor) y luego hacemos el forced unwrapping, debido a que dentro del ifestamos seguros que esa variable tiene un valor.

Optional Binding

Si bien el enfoque anterior es perfectamente válido, no termina siendo muy cómodo si dentro del if se necesita usar muchas veces el valor dentro del opcional, ya que tendríamos que recordar de usar el ! en todos los casos.

Otra manera de hacer lo mismo pero un poco más eficiente es usando el optional binding (enlace opcional), en el cual se pregunta si un opcional contiene un valor y en caso afirmativo, se crea una constante o variable temporal para ser usada dentro del if o while como si se tratara de una versión no opcional. Una vez fuera de ese if o while, la misma deja de existir.

if let colorElegido = otroColor {
    print("El color elegido es \(colorElegido)")
}

//Devuelve:
//El color elegido es celeste

Como vemos, creamos una constante temporal llamada colorElegido que contiene el valor del opcional otroColor. Dentro del if usamos ese valor y ya fuera de él la constante ya no existe más.

Asimismo, podemos anidar varios enlaces opcionales e incluso usar otras comparaciones convencionales que devuelven true o false. Como resultado, sólo se ejecutarán las instrucciones dentro del if cuando todos los opcionales tengan un valor y todas las condiciones devuelvan true. Si alguno de estos casos no se da, el resultado final será false y no se ingresará al if.

let numeroPar = 30

if let colorElegido = otroColor, let numero = Int("45"), numeroPar < 50 {
    print("El color elegido es \(colorElegido) y el \(numeroPar) es menor a 50")
    print("\(numero)")
}

//Devuelve:
//El color elegido es celeste y el 30 es menor a 50
//45

Implicit unwrapped optionals

En muchas situaciones contamos con variables opcionales que en un momento determinado del programa son inicializados con un valor y que luego no van a volver a valer nil nunca más. Por tal motivo, es conveniente no tener que preguntar a cada instante si esa variable contiene un valor y hacer la desenvoltura correspondiente, ya que se asume que siempre se va a contener un valor.

Un ejemplo muy claro de este escenario se da cuando se programa para un sistema operativo como iOS, en donde los botones que vemos en pantalla al inicio de su ciclo de vida se crean en nil pero luego mientras se inicializan determinados componentes, las variables que hacen referencia a esos botones contienen valor, hasta tanto el usuario cambia de pantalla y se pierden esas referencias. Como en un momento de su ciclo de vida necesitó valer nil, es obligatorio usar un opcional, pero como luego siempre va a tener un valor, no es cómodo tener que usar un if let en cada uso. Para este tipo de casos, los implicity unwrapped optionals (opcionales desenvueltos en forma implícita) son ideales.

Para hacer uso de ellos, en lugar de declarar al opcional usando un signo de pregunta (?) se utiliza un signo de exclamación (!):

let posibleValor:String? = "Estamos aprendiendo Swift! Yeahh!"
let valorSeguro:String! = posibleValor!

print(posibleValor)
print(valorSeguro)

//Devuelve:
//Optional("Estamos aprendiendo Swift! Yeahh!")
//Estamos aprendiendo Swift! Yeahh!

Podríamos decir que este tipo de opcionales tienen realizan la desenvoltura de su valor en forma automática, sin necesidad de hacerlo explícito. Tengamos en cuenta que si una variable o constante vale nil e intentamos usar su valor, vamos a tener un error en tiempos de ejecución. Por lo tanto, hay que ser muy cuidadoso y pensar bien antes de usar este tipo de opcionales.

En el caso de que exista alguna posibilidad de que una variable se vuelva nil en algún momento del código, entonces no debemos usar este opcional implícito.

Por otro lado, si necesitamos preguntar si ese opcional implícito tiene un valor en su interior o si quisiéramos usar el optional binding, podemos hacerlo:

if valorSeguro != nil {
    print(valorSeguro)
}

if let dato = valorSeguro {
    print(dato)
}

nil-coalescing operator

Este operador, que podríamos traducirlo como operador que viene junto a nil, devuelve el valor que contiene un opcional haciendo una desenvoltura (a) y en caso de encontrar nil, devuelve otro valor (b). Su sintaxis es a ?? b.

Un punto a tener en cuenta es que tanto a como b deben ser del mismo tipo.

var animal:String? = "Perro"

let mascota = animal ?? "Gato"

print("\(mascota)")

//Devuelve Perro

En el ejemplo, definimos una variable opcional animal con el valor Perro. Al ser opcional, podría no contener un valor (ser nil). Luego se declara una constante mascota que va a valer Perro siempre que la variable animal tenga ese valor. En caso de ser nil, se incluye un valor adicional Gato.

Este operador es muy útil cuando queremos dar un valor por defecto en caso de que una variable o contante no tengan valor.