Capítulo 2 de 14 8 secciones 11 min

Variables, números y texto

Los cuatro tipos que vas a usar siempre, el error de sumar texto con número, y por qué 0,1 más 0,2 no da 0,3.

Una variable en Python es un nombre que apunta a un valor. Los cuatro tipos que vas a usar todo el tiempo son int (números enteros), float (con decimales), str (texto) y bool (verdadero o falso). El error más común de la primera semana es sumar un número con un texto que parece número, y se resuelve convirtiéndolo con int() o float().

Una variable es una etiqueta, no una caja

Hola! Vamos con lo que hay dentro de una variable, que es la base de todo lo demás 🌸

Casi siempre te van a explicar que una variable es una caja donde guardas algo. Yo prefiero otra imagen, porque te va a ahorrar un dolor de cabeza más adelante: una variable es una etiqueta que le pegas a un valor.

ciudad = 'Arequipa'
ventas = 3
promedio = 1250.75

print(ciudad, ventas, promedio)
Arequipa 3 1250.75

El signo igual no significa "es igual a" como en matemáticas. Significa "desde ahora, este nombre apunta a este valor". Por eso esto que parecería una locura funciona sin problema:

contador = 10
contador = contador + 5

print(contador)
15

Se lee de derecha a izquierda: agarra lo que hay en contador, súmale 5, y pega la etiqueta contador al resultado.

Cómo se nombran las variables

Hay reglas que Python obliga y convenciones que obliga la comunidad. Las dos importan.

Lo que Python no te deja: empezar con un número, usar espacios, usar guiones, o usar una palabra reservada como class o for.

Lo que se acostumbra, y viene escrito en un documento que se llama PEP 8 (la guía de estilo oficial de Python):

  • 🐍 Todo en minúsculas y las palabras separadas con guion bajo: total_ventas, fecha_de_corte. Eso se llama snake_case.
  • 📝 Nombres que digan qué hay dentro. df2 no dice nada; ventas_limpias sí.
  • 🚫 Nada de tildes ni ñ, aunque Python las acepte. Te van a dar problemas al compartir código.

Te lo digo por experiencia: el código que escribes hoy lo lee otra persona dentro de tres meses, y muchas veces esa otra persona eres tú 😅

Los cuatro tipos que vas a usar siempre

Python tiene muchos tipos, pero para datos son cuatro los que aparecen todo el tiempo.

unidades = 12                 # int:   numero entero
monto = 1250.75               # float: numero con decimales
cliente = 'Minimarket El Sol' # str:   texto
pago = True                   # bool:  verdadero o falso

print(type(unidades))
print(type(monto))
print(type(cliente))
print(type(pago))
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

type() es la pregunta "qué eres tú" y la vas a usar más de lo que crees. Cuando algo no funcione y no entiendas por qué, imprime el tipo antes de seguir buscando 🔍

Un detalle sobre bool: por dentro es un número. Eso parece un dato curioso y en realidad es un truco que vas a usar seguido.

print(True + True)
print(sum([True, False, True, True]))
2
3

Sumar una lista de verdaderos y falsos te da cuántos verdaderos hay. Cuando lleguemos a pandas, así vas a contar cuántas filas cumplen una condición.

El error de la primera semana

Este te va a pasar. A todo el mundo le pasa, así que mejor que te pase aquí conmigo y no un viernes a las siete.

unidades = '12'      # ojo: vino como texto, con comillas
precio = 40

print(unidades * precio)
12121212121212121212121212121212121212121212121212121212121212121212121212121212

Ajá 😅

Multiplicar un texto por un número no es un error para Python: es repetir el texto esa cantidad de veces. Así que te repitió "12" cuarenta veces y no te avisó de nada.

Ese es el peor tipo de error: el que no falla. Un error que revienta lo ves; este te deja seguir trabajando con un resultado que no significa nada.

Con la suma sí revienta, y menos mal:

print(unidades + precio)
TypeError: can only concatenate str (not "int") to str

Léelo con calma que el mensaje es bueno: "solo puedo concatenar texto con texto, y me diste un int". O sea, Python vio un texto a la izquierda y asumió que querías pegar palabras.

La solución es convertir:

unidades = int('12')

print(unidades + precio)
print(type(unidades))
52
<class 'int'>

Las tres conversiones que vas a usar son int(), float() y str(). Y una advertencia que te ahorra rato: int() con un texto que tenga decimales no funciona.

int('40.5')
ValueError: invalid literal for int() with base 10: '40.5'

Ahí hay que pasar por float() primero, o directamente usar float() si no necesitas un entero.

Por qué 0,1 más 0,2 no da 0,3

Este es de los que más desconciertan, y no es un bug de Python.

print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
0.30000000000000004
False

No te asustes. Pasa en todos los lenguajes, y en Excel también (solo que Excel te lo esconde al mostrarte el número).

La razón es que la computadora guarda los decimales en binario, y hay decimales que en binario no tienen representación exacta, igual que un tercio no la tiene en decimal: 0,3333... nunca termina.

Lo que importa son las dos consecuencias prácticas:

  • ⚠️ Nunca compares dos decimales con ==. Usa round() o compara la diferencia.
  • 💰 Para dinero, redondea al final y no en cada paso. Si el proyecto es contable de verdad, existe un tipo llamado Decimal que guarda los números exactos.
print(round(0.1 + 0.2, 2) == 0.3)

from decimal import Decimal
print(Decimal('0.1') + Decimal('0.2'))
True
0.3

Fíjate en que Decimal recibe el número entre comillas. Si le pasas Decimal(0.1) le estás dando el float que ya venía roto, y no arregla nada.

Texto, que es la mitad de tu trabajo

En datos reales, el 90% de lo sucio es texto: nombres con espacios de más, ciudades escritas de cuatro formas, números que vinieron como cadena. Así que estos métodos los vas a usar muchísimo.

cliente = '  minimarket EL SOL  '

print(cliente.strip())            # quita espacios de los extremos
print(cliente.strip().title())    # Primera Letra De Cada Palabra
print(cliente.strip().lower())    # todo minusculas
print(cliente.replace('EL', 'el').strip())
minimarket EL SOL
Minimarket El Sol
minimarket el sol
minimarket el SOL

Un detalle importante: estos métodos no modifican la variable, te devuelven una copia. Si quieres conservar el cambio hay que reasignarlo.

cliente.strip()
print(repr(cliente))              # sigue con sus espacios

cliente = cliente.strip()
print(repr(cliente))
'  minimarket EL SOL  '
'minimarket EL SOL'

Usé repr() para que se vean las comillas y los espacios. En la primera línea siguen ahí, aunque hayamos llamado a .strip() justo antes: el método devolvió una copia limpia y nadie la guardó.

Ese repr() va a ser tu mejor amigo depurando texto, porque un espacio de más es invisible con print normal 🔍

Y el que más rinde de todos, .split(), que parte un texto en una lista:

fila = 'C0045;Arequipa;Minimarket;480.37'
partes = fila.split(';')

print(partes)
print(partes[1])
print(float(partes[3]) * 2)
['C0045', 'Arequipa', 'Minimarket', '480.37']
Arequipa
960.74

Eso de arriba es, en miniatura, lo que hace pandas cuando lee un CSV 📊

f-strings: la forma de armar texto

Antes había tres maneras de meter una variable dentro de un texto y todas eran incómodas. Desde Python 3.6 hay una sola que vale la pena, y se llama f-string: una f antes de la comilla y las variables entre llaves.

cliente = 'Minimarket El Sol'
monto = 1250.756

print(f'{cliente} compró S/{monto}')
print(f'{cliente} compró S/{monto:.2f}')
print(f'{cliente:>25} | S/{monto:>10.2f}')
Minimarket El Sol compró S/1250.756
Minimarket El Sol compró S/1250.76
        Minimarket El Sol | S/   1250.76

Esos dos puntos dentro de las llaves son el formato, y valen oro:

  • 💵 :.2f deja dos decimales. Para plata, siempre.
  • 📐 :>10 alinea a la derecha en diez espacios, que es lo que hace que una tabla impresa se vea derecha.
  • 🔢 :, pone el separador de miles: f'{1250000:,}' sale 1,250,000.

El error que da la primera vez es olvidar la f:

print('{cliente} compró algo')
{cliente} compró algo

No revienta, simplemente te imprime las llaves tal cual. Si ves llaves en tu salida, te faltó la f 🙃

None, que no es cero ni vacío

None es el valor que dice "aquí no hay nada". No es el 0, no es el texto vacío, es la ausencia.

fecha_ultima_compra = None

print(fecha_ultima_compra is None)
print(fecha_ultima_compra == 0)
True
False

Se compara con is None y no con == None. Es la convención de Python y hay razones técnicas, pero con que te acostumbres basta.

Esto importa muchísimo en datos: cuando un cliente no tiene fecha de última compra, ese hueco no es un cero. Y tratarlo como cero te cambia el promedio y todas las conclusiones que salgan de ahí.

Ejercicios

1. Los cuatro tipos

Crea una variable de cada tipo con datos de una venta e imprime el tipo de cada una en una sola línea.

unidades = 8
monto = 340.5
canal = 'WhatsApp'
pagado = False

print(type(unidades), type(monto), type(canal), type(pagado))
<class 'int'> <class 'float'> <class 'str'> <class 'bool'>
2. El total de una venta

Con 8 unidades a S/34,90 cada una y 18% de IGV, imprime el total con dos decimales usando un f-string.

unidades = 8
precio = 34.90
igv = 0.18

total = unidades * precio * (1 + igv)
print(f'Total: S/{total:.2f}')
Total: S/329.46

Fíjate en que redondeé solo al mostrar, no al calcular. Si redondeas en cada paso, los centavos se te van yendo.

3. El texto que parecía número

Te llega '250' como texto y '1.5' también. Multiplícalos y muestra el resultado con un decimal.

unidades = '250'          # como llega del sistema
factor = '1.5'            # el multiplicador de la promocion

resultado = int(unidades) * float(factor)
print(f'{resultado:.1f}')
375.0

Ojo con hacer int(factor): ahí revienta con un ValueError, porque int() no acepta un texto con punto decimal.

4. Limpiar un nombre de cliente

De ' BODEGA doña ROSA ' saca 'Bodega Doña Rosa'.

sucio = '   BODEGA doña ROSA  '
limpio = sucio.strip().title()

print(repr(limpio))
'Bodega Doña Rosa'

Usé repr() a propósito: muestra las comillas, así compruebas que de verdad no quedaron espacios. Es mi truco favorito para depurar texto 🔍

5. Partir una fila de CSV

De '2026-04-29,Cusco,Web,154.83' imprime la ciudad y el monto multiplicado por 1,18.

fila = '2026-04-29,Cusco,Web,154.83'
partes = fila.split(',')

print(partes[1])
print(f'{float(partes[3]) * 1.18:.2f}')
Cusco
182.70
6. La comparación que falla

Comprueba que 1.1 + 2.2 no es igual a 3.3, y después arregla la comparación.

print(1.1 + 2.2)                       # dos productos de S/1.10 y S/2.20
print(1.1 + 2.2 == 3.3)
print(round(1.1 + 2.2, 10) == 3.3)
3.3000000000000003
False
True

Redondear a diez decimales suena exagerado y es justo el punto: el error del binario está mucho más allá, así que con redondear a cualquier cantidad razonable de decimales el problema desaparece.

7. Una tabla alineada

Imprime tres líneas con nombre de ciudad y monto, de forma que los montos queden alineados a la derecha.

datos = [('Lima', 12500.5), ('Arequipa', 980.25), ('Cusco', 145600.0)]

for ciudad, monto in datos:
    print(f'{ciudad:<12} S/{monto:>12,.2f}')
Lima         S/   12,500.50
Arequipa     S/      980.25
Cusco        S/  145,600.00

Ese :<12 alinea a la izquierda y :>12,.2f alinea a la derecha con separador de miles y dos decimales. Con eso ya puedes imprimir un reporte decente sin ninguna librería.

8. Contar con booleanos

Tienes una lista de montos. Cuenta cuántos superan los S/1.000 usando el truco de sumar booleanos.

montos = [480.37, 1250.0, 95.5, 3400.2, 780.0, 1001.0]

print(sum(m > 1000 for m in montos))
3

Eso de dentro del sum es una comprensión, que vemos en el capítulo 3. Por ahora quédate con la idea: cada comparación devuelve True o False, y sumarlos cuenta los True.

9. El error de tipos, provocado

Provoca un TypeError sumando un texto y un número, y después arréglalo de dos formas distintas.

flete = '100'          # vino como texto del sistema
descuento = 50

print(int(flete) + descuento)      # los dos como numero
print(flete + str(descuento))      # los dos como texto
150
10050

Las dos son válidas y hacen cosas muy distintas. Elegir mal aquí es de donde salen los reportes con números absurdos.

10. None no es cero

Simula tres clientes donde uno no tiene fecha de última compra, y cuenta cuántos sí la tienen.

fechas = ['2025-08-22', None, '2026-01-05']

con_fecha = sum(f is not None for f in fechas)
print(f'{con_fecha} de {len(fechas)} tienen fecha')
2 de 3 tienen fecha

Este conteo es lo primero que haces al recibir cualquier archivo. En el capítulo 11 pandas te lo da en una línea, pero es exactamente la misma idea.

Lo que te llevas

  • 🏷️ Una variable es una etiqueta pegada a un valor, y el = se lee de derecha a izquierda.
  • 🔍 Cuando algo raro pase, type() antes que nada.
  • 💸 Los decimales no son exactos: no los compares con == y redondea al final.
  • ✍️ Los métodos de texto devuelven una copia, no modifican la variable.
  • 🕳️ None es ausencia, no cero, y confundirlos te cambia los promedios.

En el capítulo 3 vamos a guardar muchas cosas juntas: listas, tuplas y diccionarios. Ahí aparece el error de copiar una lista que en realidad no se copió, que es de los más traicioneros que hay.

Que tengas lindo día! 🌸

¿Tienes alguna duda o consulta?