Aserciones y Precondiciones
Clase 21 de 22 • Curso de Introducción a Swift (2019)
Contenido del curso
Hernán Chilabert
Frank Moreno
Javier Eduardo Tapia Hernandez
Jerry Ontiveros Mendoza
Roberto Garcia Lopez
Victor Carmona Pale
Adrian Peralta
Sebastian Ayala Gonzalez
Juan Rodrigo de la Cruz García García Briseño
Oscar Giraldo Castillo
Edgardo Marcano
Maricel Romero
Platzi
Jonathan Macalupu Reyes
Wilson Montenegro
Jose Miguel Serrato Moreno
Denis Cordero
Adrian Peralta
Frank Moreno
Matias Duport Zuluaga
Jonathan Meixueiro
Luis Garay
Edgardo Marcano
La función assert() te permite verificar el estado de tu programa en tiempo de ejecución y fallar si las cosas no son como deberían ser. Una de las características interesantes de assert() es que se elimina automáticamente cuando construyes tu aplicación en modo de lanzamiento, pero si no queres que eso suceda, si queres que tu aplicación se bloquee si algo está muy mal, entonces deberías usar la función precondition() en su lugar.
let age = -5 assert(age >= 0, "La edad de una persona no puede ser negativa."
precondition() funciona de manera idéntica a assert(): dale una condición para verificar junto con un mensaje opcional para imprimir si la verificación falla. En tiempo de ejecución, incluso en el modo de liberación, Swift ejecutará la verificación por vos y se bloqueará si falla.
precondition(age >= 0, "La edad de una persona no puede ser negativa.")
En ambos casos devuelve este error:
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0). The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
Falta aclarar que pese a que assert y precondition son iguales, assert solo funciona en modo debug mientras que precondition funciona en debug y producción.
Gracias por el aporte, me sirvio para mis notas y poder entender mejor el tema
El concepto del debug siempre ha ayudado a poder localizar los posibles errores que existan en nuestro codigo que por malas practicas quizas no sean tan visibles para el programados, para eso es bueno conocer el buen manejo de los assert y los preconditions
import UIKit var hungry: Bool = true var thereIsGas: Bool = true var thereIsingredients: Bool = true func makeSandwich() throws{ if hungry { if thereIsGas { if thereIsingredients { print("Hora de comer") }else{ throw SandwichError.noyIngredients } }else{ throw SandwichError.notGas } } else{ throw SandwichError.notHungry } } do{ try makeSandwich() }catch SandwichError.notHungry{ notHungry() } catch SandwichError.notGas{ notGas() } catch SandwichError.noyIngredients{ noyIngredients() }catch let error { print(error.localizedDescription) } func notHungry(){ print("Mas tarde, no tengo hambre") } func notGas(){ print("Se termino el gas") } func noyIngredients(){ print("No tengo todos los ingredientes") } func verifySteps(){ print("Verificar si estan todos los ingredientes") } enum SandwichError: Error { case notHungry case notGas case noyIngredients }
El assert y precondition sirven para el mismo fin solo que en momentos diferentes, assert solo debug y precondition solo en build. ¿No bastaría con solo tener precondition?
las precondiciones me sonaron a: no compiles el código a menos que se cumpla esto , si no se cumple lanzame tal error para saber donde falló.
Creo que va mas por el lado de no permitir que la aplicacion siga su curso si algo no resulta como lo esperamos. Vendria a ser un equivalente a un codigo 500 en una API. Es decir seria un error en tiempo de ejecucion
los asserts son globales? Me refiero a que si la declaro después de la creación de la variable age pero esta es declarada al inicio de mi código al igual que el asserts pero la inserción de la edad del usuario es de los últimos datos el assert seguiría funcionando? o es como una condicional que se tiene que poner después del cambio de valor de la variable?
Hola @roganoalien los asserts vienen a ser funciones del sistema que sirven para checkear en debug si el resultado que esperabas es el indicado.
Generalmente suele ser usado cuando implementas test o pruebas dentro de tu código. Espero haberte ayudado.
Creo que la respuesta es vaga. Son globales o no?
A dónde está la documentación para leer?
La documentación para leer se encuentra en formato de lectura, que consiste en cápsulas cortas de contenido que puedes interiorizar, releer o reproducir varias veces hasta que lo apropies e identifiques los elementos que puedes aplicar en tu organización.
let areaTractorCrop = 50_000 let areaLandCrop = 10_000 if areaTractorCrop <= areaLandCrop { print("El tractor puede cosechar sin problemas") } else if areaTractorCrop <= areaLandCrop / 2 { print("El tractor puede cosechar sin problemas, pero requiere de más tiempo") } else { assertionFailure("Las dimensiones del tractor son demasiadas para el área requerida") }
// Reto let batteryPercentage = -10 if batteryPercentage < 20, batteryPercentage > 0{ print("bateria baja") }else if batteryPercentage > 20, batteryPercentage <= 100 { print("bateria ok") }else{ assertionFailure( "La carga de la bateria no puede ser mayor a 100% o menor a 0%") }
let gasLevel = -0.2 assert(gasLevel >= 0, "el nivel de gasonila no puede ser negativo") if gasLevel == 1.0 { print("el tanque esta lleno") } else if gasLevel >= 0.5 { print("el tanque esta a mas de la mitad") } else if gasLevel < 0.5 { if gasLevel <= 0 { assertionFailure("el nivel de gasonila no puede ser negativo") } else { print("el nivel de la gasonila esta a menos de la mitad") } }
esto es TDD?
Hola Denis, TDD es Desarrollo guiado por Tests (Test Driven Development), y las aserciones en TDD es una forma de validar que el código está haciendo lo que debería. Te dejo algunos puntos para entender mejor el proceso:
este es un pequeño vistazo, pero hay muchas más cosas que se pueden hacer en ese proceso básico que expliqué :)
Es bastante cool TDD.
No es TDD, solo es sintaxis que puede ser usada para TDD. Esa ligera diferencia se convierte en una gran diferencia en la calidad de código.
faltan por explicar muchas cosas de lo basico y ya estan pasando a nivel medio
Se me ocurrió de ejemplo el rango de peso pluma para una pelea en la UFC :D
import UIKit //UFC Feather weight limits (136–145 lb) let featherWeightLimits = (136, 145) let (minWeight, maxWeight) = featherWeightLimits let unitsWeight : String = "lb" var fighterWeight: Int16 fighterWeight = 140 //assert(fighterWeight <= featherWeightLimits.1, "Fighter is overweighted and disqualified") //precondition(fighterWeight <= featherWeightLimits.1, "Fighter is overweighted and disqualified") if fighterWeight >= featherWeightLimits.0 && fighterWeight <= featherWeightLimits.1 { print("Fighter is in range to keep the fighting") } else if fighterWeight < featherWeightLimits.0 { print("Fighter has a limit of two hours to bulk up or the fight is gonna call off") } else { assertionFailure("Fighter is overweighted and disqualified") }
Realicé este ejemplo sencillo sobre un control de tareas y tiempo en pantalla.
<code> var finishedHomework:UInt8 = 5 let assignedHomework:UInt8 = 8 precondition(finishedHomework == assignedHomework, "Debe realizar todas las tareas para jugar en el movil") precondition(finishedHomework >= 0, "Las tareas terminadas no pueden ser negativas") if finishedHomework == assignedHomework { print("Puede jugar en el movil") } else if assignedHomework > finishedHomework && finishedHomework >= 0{ preconditionFailure("Debe terminar todas las tareas para jugar en el movil") } else { preconditionFailure("Las tareas terminadas no pueden ser negativas") }
Excelente clase🤩ya quiero pasar a SwiftUI