Tipos de datos y conversiones: no todo lo que parece un número lo es
"3.2" + "1.0" produce "3.21.0" en Python. No se ha estropeado la calculadora: hemos pedido unir dos textos y el programa ha obedecido. La altura resultante solo existe como una secuencia de caracteres, aunque alguien termine copiándola a una columna titulada «metros». Mi admiración por los encabezados de Excel tiene límites: no cambian el tipo de lo que contienen.
Un tipo de dato determina qué operaciones tienen sentido con un valor. Para empezar basta con conocer las variables: veremos la diferencia entre sumar números, unir textos y convertir una altura recibida como cadena. Ese recorrido básico termina antes de «Ampliación». Después encontrarás un lector defensivo y su variante C#, para cuando hayas trabajado funciones, condiciones y excepciones. Son datos inventados; hoy no necesitamos abrir un modelo para distinguir un número de su disfraz.
El aspecto del dato no decide qué podemos hacer con él
En Python, 3.2 es un número de coma flotante, de tipo float; "3.2" es una cadena de texto, de tipo str. Las comillas forman parte de cómo escribimos la cadena en el código, no de su contenido. El número permite realizar operaciones aritméticas; el texto conserva caracteres que podríamos mostrar, buscar o unir con otros. Que ambos aparezcan de manera parecida en una pantalla no los convierte en intercambiables.
Podemos observar la diferencia sin preparar todavía una importación. Guarda este fragmento en un archivo Python y ejecútalo con el entorno del artículo anterior. type permite consultar el tipo de un valor y print muestra el resultado. La última línea une dos cadenas; no intenta sumar las alturas que esas cadenas podrían representar.
La salida será float, str, 4.2 y 3.21.0, cada resultado en una línea. En las dos primeras ves el tipo; en las siguientes, cómo cambia el significado de +. El sufijo _m nos recuerda que la altura del ejemplo está en metros: el nombre ayuda a entender el programa, aunque Python no lo interpreta como una unidad.
También hay números enteros, como un contador de puertas, y booleanos, que expresan verdadero o falso. Conviene conservar esas diferencias. Un identificador como "0032" suele necesitar texto para mantener los ceros iniciales; convertirlo a entero devuelve 32 y pierde esa representación. No convertiría todos los campos «que parecen números» al cargar una tabla. Primero decidiría si representan una magnitud, un recuento, un código o una respuesta lógica. La hoja puede tener columnas muy alineadas y una semántica bastante desordenada.
Convertir es aceptar una interpretación concreta
Supongamos que una exportación entrega la altura como texto. Nuestro acuerdo de intercambio será explícito: valores en metros, punto decimal, sin separador de miles y sin unidad escrita dentro de la celda. Admitiremos espacios alrededor del número y notación científica cuando el intérprete la reconozca. Una entrada como "3.2 m" no cumple ese acuerdo, aunque un humano entienda lo que pretende decir.
En Python, float("3.2") produce el número 3.2. Eso es una conversión explícita: la instrucción pide interpretar una cadena como número. float("3,2") no aplica automáticamente la configuración española de una hoja de cálculo; provoca un error de conversión. La referencia oficial de float describe la sintaxis admitida, incluida la posibilidad de representar valores especiales que tendremos que comprobar después.
Elegir punto decimal aquí no significa que la coma sea incorrecta en cualquier proceso. Significa que este lector de datos tiene un contrato. Si el origen usa coma, hay que acordar otra interpretación y aplicarla en la entrada. Sustituir todas las comas por puntos sin conocer el formato resulta especialmente frágil cuando aparecen miles o textos con ambos signos. La cadena "1,234" puede expresar cantidades distintas según la convención utilizada. No le pediría al importador que decida cuál nos conviene para terminar antes.
Con esto puedes completar el primer ejercicio: guarda altura_texto = "3.2", obtén altura_m = float(altura_texto) y muestra altura_m + 1.0. Debe aparecer 4.2; el texto original sigue siendo texto. Ya has distinguido representación, conversión y cálculo. No hace falta presentarle una función con siete salidas a quien acaba de descubrir las comillas. La ampliación siguiente añade los controles necesarios cuando esas entradas dejan de estar elegidas por nosotros.
Ampliación: rechazar una altura que no sirve para calcular
Para nuestro ejercicio, una altura debe ser un número finito mayor que cero. El formato válido y esa regla son comprobaciones diferentes. "-2" puede convertirse perfectamente y aun así incumplir la condición. Una cadena vacía ni siquiera permite obtener el número. En ambos casos rechazamos la entrada para este cálculo, pero conservamos motivos distintos.
Hay otro detalle menos vistoso: una conversión puede reconocer infinito o un valor especial «no es un número», conocido como NaN. No basta con comprobar que no se haya producido una excepción. La función math.isfinite permite excluir esos resultados en Python. No necesitamos explorar toda la aritmética de coma flotante ahora; sí evitar que una altura infinita supere el control de entrada por haber encontrado una representación numérica.
Este bloque es una ampliación para quien ya haya practicado funciones y excepciones. Si estás siguiendo los fundamentos en orden, puedes dejarlo para esa segunda lectura: la distinción entre texto, número y conversión ya está completa. Ahora reunimos en una función el número aceptado y el motivo de rechazo, sin sustituir un dato que no entendemos por un cero muy obediente.
try intenta la conversión y except ValueError trata ese fallo concreto. No oculta cualquier error del programa. return termina la función para esa entrada, de modo que una altura rechazada no sigue avanzando hasta la aceptación. repr hace visibles las comillas y el vacío al mostrar el original. Ese pequeño detalle evita tener que adivinar si la fila H03 no imprimió nada porque estaba vacía o porque alguien olvidó incluirla en el informe.
El control de tipo inicial también tiene una intención: esta función recibe textos de una frontera de intercambio. Si alguien le pasa directamente el booleano True, lo rechazará como tipo inesperado. No quiero que una propiedad «aprobado» se convierta en un metro de altura por una compatibilidad de tipos del lenguaje. Cuando el origen ya entregue números, podremos preparar un acceso adecuado para ellos. Mezclar ambas rutas sin explicarlo dificulta averiguar de dónde salió cada valor.
Variante C#: declarar la cultura de conversión
C# distingue también entre string, para texto, y tipos numéricos como double. Sus métodos de lectura permiten indicar la cultura con la que se interpreta una cadena. Para reproducir nuestro acuerdo usaremos CultureInfo.InvariantCulture: punto decimal y un formato independiente de la configuración regional del equipo. NumberStyles.Float admite signos, espacios exteriores y exponentes, sin habilitar separadores de miles.
La documentación de estilos numéricos de .NET permite comprobar esa elección. No daría por hecho que un lector ejecutado en otro equipo interpretará las mismas cadenas si depende de la cultura por defecto. Que dos personas utilicen Windows no constituye un contrato de intercambio; apenas constituye una coincidencia bastante frecuente.
Este programa puede guardarse como Program.cs en un proyecto de consola dirigido a .NET 8. La función devuelve un par con nombre, Valor y Motivo. El signo ? de double? permite representar la ausencia de número mediante null. TryParse indica si ha conseguido interpretar el texto; después comprobamos finitud y signo como en Python.
Ambos ejemplos deben aceptar H01 con valor 3.2; H02 y H04 producen «formato no admitido», H03 «sin valor», H05 «numero no finito» y H06 «debe ser mayor que cero». El formato de las líneas impresas es distinto, pero la decisión sobre estas seis entradas coincide. Eso no demuestra que los dos conversores admitan exactamente la misma gramática para cualquier cadena imaginable. Si una integración necesita esa equivalencia, habrá que definir los formatos admitidos y comprobarlos expresamente.
Conserva el rechazo hasta que alguien pueda resolverlo
El resultado útil de este ejercicio incluye la altura aceptada y las entradas que todavía necesitan una decisión. H02 puede requerir otra configuración del lector o una corrección del archivo de origen. H06 puede indicar una medición incorrecta o que hemos recibido otra magnitud. Cambiar ambas a 0 borraría precisamente la diferencia que permite investigarlas. Prefiero un informe con cinco preguntas identificadas a una suma con seis respuestas ficticiamente completas.
Antes de conectar el ejemplo a una tabla real, añade dos casos: " 3.2 " debería aceptarse y "0" debería rechazarse por la regla de positividad. Después prueba "3.2 m": la unidad dentro del texto no pertenece al formato acordado. El lector debe mostrar el rechazo, conservando ese original. Si necesitas aceptar esa forma, tendrás que enseñar al programa a reconocerla y decidir qué unidades admite; no ampliar la conversión hasta que deje de quejarse.
Los tipos ayudan a expresar qué clase de información manejamos. Las conversiones permiten atravesar una frontera entre representaciones. Ninguna de las dos cosas sustituye el acuerdo sobre qué significa el dato. Si en tu equipo recibís alturas con coma decimal, la pregunta interesante es dónde dejáis escrita esa convención y cómo detectáis una exportación que la incumple. Cuéntalo en comentarios: me interesa mucho más ese mecanismo que otro archivo convenientemente titulado datos_limpios.
Respuestas