Cerrábamos el módulo 1, en Del problema al algoritmo, con una promesa: que el título, el responsable y la prioridad de una tarea dejarían de estar escritos a mano dentro de un print y pasarían a ser información que el programa maneja. Esta lección cumple esa promesa. La pieza que lo hace posible se llama variable, y es, sin exagerar, el concepto sobre el que se apoya absolutamente todo lo demás del curso.
Tu tareafacil.py actual imprime texto fijo. Si Marta quiere registrar otra tarea, hay que abrir el editor, buscar la línea, cambiar el texto y guardar. Eso no es un programa: es un documento que se ejecuta. Un programa de verdad guarda datos, los consulta, los modifica y calcula con ellos. Para eso necesita sitios donde poner esos datos y nombres con los que referirse a ellos.
En esta lección aprenderás qué es exactamente una variable, cómo se crea con el operador de asignación =, qué nombres puedes ponerle y cuáles conviene ponerle, cuáles son los cinco tipos básicos de dato en Python (int, float, str, bool y None), cómo averiguar el tipo de cualquier valor con type(), y qué significa que Python tenga tipado dinámico. Al final reescribirás tareafacil.py para que la tarea de la Panadería Solé viva en variables.
Contenido
- Del texto fijo a los datos con nombre
- Qué es una variable
- La asignación: el operador
= - Reasignación y orden de ejecución
- Reglas y convenciones para los nombres
- Comentarios con
# - Los tipos básicos de Python
- Inspeccionar el tipo con
type() - Tipado dinámico: qué significa en la práctica
- Mutable e inmutable: una primera intuición
- TareaFácil: la tarea vive en variables
- Errores comunes y consejos
- Ejercicios
- Conclusión
- Del texto fijo a los datos con nombre
Recuperemos el tareafacil.py con el que cerraste la lección 01-04:
print("Titulo: Logotipo Panaderia Sole")
print("Descripcion: Tres propuestas en blanco y negro, formato vectorial")
print("Responsable: Luis")
print("Prioridad: alta")
print("Estado: pendiente")Este programa tiene tres problemas graves, y conviene nombrarlos antes de arreglarlos:
- El dato está atrapado en el texto. «Luis» no es un dato para el programa: es un puñado de letras dentro de una frase más larga. El programa no puede saber quién es el responsable, no puede compararlo con otro nombre, no puede contarlo.
- Repetir un dato obliga a repetirlo literalmente. Si el responsable apareciera en cuatro sitios y la tarea se reasignara a Nuria, habría que cambiar cuatro líneas. Olvidar una es un error garantizado.
- No hay forma de calcular nada. Con texto fijo no se puede decidir si una tarea es urgente, ni contar cuántas hay pendientes, ni nada parecido.
La solución es separar el dato de su presentación. El dato se guarda con un nombre; después se muestra. Así:
Dos líneas, y ya es otro programa. La primera línea guarda el texto "Luis" bajo el nombre responsable. La segunda muestra lo que hay guardado en ese nombre. Si mañana la tarea pasa a Nuria, se cambia una línea y todo lo que use responsable queda actualizado.
Eso es una variable.
- Qué es una variable
Una variable es un nombre que apunta a un valor guardado en la memoria del ordenador.
Conviene detenerse en la palabra apunta, porque es la clave. Mucha gente imagina la variable como una caja que contiene el valor. Es una imagen aceptable al principio, pero la imagen correcta en Python es otra: el valor vive en algún lugar de la memoria, y la variable es una etiqueta pegada a ese valor. La etiqueta no contiene nada; señala.
flowchart LR
subgraph nombres["Nombres (lo que escribes)"]
A["responsable"]
B["prioridad"]
C["dias_estimados"]
end
subgraph memoria["Memoria (donde viven los valores)"]
X["'Luis'"]
Y["'alta'"]
Z["3"]
end
A --> X
B --> Y
C --> Z
De ahí salen tres consecuencias prácticas que te ahorrarán confusiones más adelante:
- Un nombre apunta a un solo valor a la vez. Si lo haces apuntar a otro, deja de apuntar al anterior.
- Varios nombres pueden apuntar al mismo valor. No es un caso raro: ocurre continuamente.
- Usar el nombre equivale a usar el valor. Cuando escribes
print(responsable), Python sigue la flecha, encuentra"Luis"y trabaja con eso.
Y hay una cuarta consecuencia, más filosófica pero muy útil: el nombre es para ti, no para la máquina. Al ordenador le da igual que la variable se llame responsable o x7. A quien lea el programa dentro de seis meses —probablemente tú— no le dará igual en absoluto.
- La asignación: el operador
=
=Crear una variable en Python es tan simple como esto:
La estructura es siempre la misma:
El símbolo = se llama operador de asignación, y funciona de derecha a izquierda: primero se calcula lo que hay a la derecha, y el resultado se asocia al nombre de la izquierda. Es importante interiorizar ese orden desde el principio.
Léelo mentalmente como «pasa a valer» o «apunta a», nunca como «es igual a». Y aquí llegamos a un punto que confunde a casi todo el mundo al empezar.
Por qué = no es la igualdad matemática
En matemáticas, x = 5 es una afirmación: declara un hecho que se cumple. En Python, x = 5 es una orden: haz que el nombre x apunte al valor 5.
La diferencia se ve con toda claridad en esta línea, perfectamente válida en Python e imposible en matemáticas:
Matemáticamente, contador = contador + 1 sería absurdo: ningún número es igual a sí mismo más uno. Como orden, es perfectamente sensato:
- Se evalúa la parte derecha,
contador + 1. Python mira cuánto valecontadorahora mismo (0) y suma uno: el resultado es1. - Ese resultado,
1, se asigna al nombrecontador, que deja de apuntar al0y pasa a apuntar al1.
| Aspecto | En matemáticas | En Python |
|---|---|---|
Qué es = |
Una afirmación de igualdad | Una orden de asignación |
| Se lee | «x es igual a 5» | «x pasa a valer 5» |
x = x + 1 |
Contradicción, no tiene solución | Instrucción válida: incrementa x |
| ¿Se puede invertir? | Sí: 5 = x significa lo mismo |
No: 5 = x es un error de sintaxis |
Ese último punto es un buen control mental: en Python, a la izquierda del = va siempre un nombre; nunca un valor. Escribir 5 = x produce el error SyntaxError: cannot assign to literal.
Para comparar dos valores y preguntar si son iguales existe otro operador, ==, con dos signos. Lo verás en detalle en Operadores y expresiones. Por ahora quédate con la distinción: un = asigna, dos == comparan.
- Reasignación y orden de ejecución
Una variable puede cambiar de valor tantas veces como quieras. A eso se le llama reasignación, y es de donde viene el nombre «variable»: su valor varía.
Tras la segunda asignación, el nombre estado deja de apuntar a "pendiente" y apunta a "completada". El valor antiguo se pierde: no hay forma de recuperarlo si no lo guardaste en otro sitio.
flowchart LR
A1["estado"] -.->|"antes"| V1["'pendiente'"]
A2["estado"] ==>|"despues"| V2["'completada'"]
De aquí sale una regla que gobierna la lectura de cualquier programa: las instrucciones se ejecutan en orden, de arriba abajo, y el valor de una variable en un punto del programa es el que le dio la última asignación anterior a ese punto.
Compruébalo con este ejemplo, que conviene trazar mentalmente antes de leer la respuesta:
Muestra Nuria. La primera línea no «se pierde» ni «entra en conflicto» con la segunda: se ejecuta, y luego la segunda la sustituye. Es exactamente la misma lógica de la prueba de escritorio que practicaste en la lección 01-05, y sigue siendo la mejor herramienta para entender un fragmento de código: apunta en una tabla el valor de cada variable después de cada línea.
| Línea | Instrucción | responsable después |
|---|---|---|
| 1 | responsable = "Luis" |
"Luis" |
| 2 | responsable = "Nuria" |
"Nuria" |
| 3 | print(responsable) |
"Nuria" → imprime Nuria |
Un detalle importante: una variable debe existir antes de usarse. Si intentas mostrar un nombre al que no has asignado nada, Python protesta:
Léelo con calma: «el nombre prioridad no está definido». Casi siempre significa una de dos cosas: o se te ha olvidado la línea de asignación, o la has escrito después de usarla, o hay una errata en el nombre (prioridad frente a prioidad). Los mensajes de error de Python son informativos; cógeles cariño cuanto antes.
- Reglas y convenciones para los nombres
Hay dos niveles aquí, y no conviene mezclarlos: las reglas, que si incumples el programa no arranca, y las convenciones, que si incumples el programa funciona pero delatan a un principiante.
Reglas obligatorias
| Regla | Válido | No válido |
|---|---|---|
| Solo letras, dígitos y guion bajo | titulo_2 |
titulo-2, titulo 2 |
| No puede empezar por un dígito | tarea1 |
1tarea |
| Distingue mayúsculas de minúsculas | Titulo y titulo son dos variables distintas |
— |
| No puede ser una palabra reservada | entrada |
if, for, class, None |
Las palabras reservadas son las que Python usa para su propia sintaxis. Hay unas 35: False, None, True, and, as, assert, break, class, continue, def, del, elif, else, except, for, from, global, if, import, in, is, lambda, not, or, pass, raise, return, try, while, with, yield... No hace falta memorizarlas: cualquier editor decente las colorea de forma distinta, y ese cambio de color es la señal de que ese nombre está prohibido.
Técnicamente Python 3 acepta acentos y eñes en los nombres (año = 2026 funciona). No los uses. Complican la escritura, rompen en teclados distintos y ningún proyecto profesional los emplea.
Convenciones de estilo
Las convenciones de Python están recogidas en un documento llamado PEP 8, que es la referencia de estilo del lenguaje. Estas son las tres que necesitas ahora:
1. snake_case: minúsculas y guiones bajos. Las palabras se separan con _, todo en minúscula.
dias_estimados = 3 # correcto en Python
diasEstimados = 3 # estilo de Java o JavaScript, no de Python
DiasEstimados = 3 # en Python esto se reserva para clases (modulo 7)2. Nombres con significado. El mejor nombre es el que hace innecesario el comentario que lo explica.
| Mal | Regular | Bien |
|---|---|---|
x |
dias |
dias_estimados |
t |
texto |
titulo_tarea |
p |
prio |
prioridad |
a, b, c |
dato1, dato2 |
responsable, estado |
Un buen criterio: si tienes que subir a mirar la asignación para recordar qué guarda una variable, el nombre es malo. Y no temas los nombres largos: tareas_pendientes_de_luis es mejor que tpl. Se escribe una vez y se lee cien.
3. Constantes en MAYÚSCULAS. Cuando un valor no debe cambiar durante la ejecución —una tasa, un límite, un texto fijo—, se nombra en mayúsculas con guiones bajos:
Ojo con un matiz que sorprende a los que vienen de otros lenguajes: Python no impide cambiar una constante. NOMBRE_ESTUDIO = "otra cosa" funcionaría sin protestar. Las mayúsculas son una convención, un aviso a los humanos que leen el código: «esto no se toca». La disciplina la pone el programador, no el lenguaje.
- Comentarios con
#
#Un comentario es texto que Python ignora por completo al ejecutar. Sirve para explicarle algo a la persona que lea el código.
Se escriben con la almohadilla #. Todo lo que va desde # hasta el final de la línea se ignora:
# Datos de la tarea que Marta acaba de encargar a Luis
titulo = "Logotipo Panaderia Sole"
prioridad = "alta" # alta / media / bajaHay dos formas de usarlos, ambas visibles arriba: en una línea propia, para explicar el bloque que viene debajo, y al final de una línea de código, para aclarar ese detalle concreto. En este segundo caso, PEP 8 pide dejar al menos dos espacios antes del #.
Un aviso sobre el buen uso, sin extendernos porque la documentación tiene su propia lección en Documentación y comentarios: un comentario debe explicar por qué, no qué. Esto no aporta nada:
Esto sí:
Los comentarios también sirven para desactivar temporalmente una línea mientras pruebas algo, sin borrarla. En la mayoría de editores, Ctrl + / comenta y descomenta la línea donde está el cursor.
- Los tipos básicos de Python
Todo valor en Python pertenece a un tipo de dato. El tipo determina qué se puede hacer con ese valor: dos números se pueden restar, dos textos no; un texto se puede poner en mayúsculas, un número no.
Estos son los cinco tipos básicos con los que trabajarás en este módulo:
| Tipo | Nombre completo | Para qué sirve | Ejemplos literales |
|---|---|---|---|
int |
Entero | Cantidades sin decimales | 3, 0, -7, 1250 |
float |
Decimal (coma flotante) | Cantidades con decimales | 3.5, 0.0, -2.75, 19.99 |
str |
Cadena de texto (string) | Texto de cualquier longitud | "Luis", 'alta', "" |
bool |
Booleano | Verdadero o falso | True, False |
None |
Nulo (tipo NoneType) |
Ausencia de valor | None |
Vamos uno a uno, porque cada uno tiene su detalle.
int: números enteros
Se escriben sin comillas y sin decimales. Pueden ser negativos y no tienen límite práctico de tamaño en Python.
No uses separadores de miles con punto ni con coma: 1.250 no es mil doscientos cincuenta, es el decimal 1,25. Si necesitas legibilidad, Python permite el guion bajo: 1_250_000 es un entero válido y se lee mejor.
float: números con decimales
Llevan punto decimal, no coma. Este es el error número uno de quien programa en español:
horas_dedicadas = 7.5 # correcto
horas_dedicadas = 7,5 # NO es un decimal: Python entiende otra cosaUn aviso que te ahorrará desconcierto más adelante: los float son aproximaciones. El ordenador almacena los decimales en binario y algunos números no tienen representación exacta:
No es un fallo de Python: pasa en casi todos los lenguajes. Para lo que hacemos aquí es irrelevante, pero recuérdalo si algún día programas cálculos con dinero.
str: cadenas de texto
Van entre comillas, simples o dobles indistintamente, siempre que abras y cierres con las mismas:
Un texto puede contener espacios, números y símbolos. Y ojo con esto, porque es fuente de confusión constante:
edad_texto = "3" # esto es un str: el carácter tres
edad_numero = 3 # esto es un int: la cantidad tresParecen lo mismo y no lo son. Con 3 se puede hacer aritmética; con "3" no. Esta distinción será el corazón de la lección Conversión de tipos y validación.
También existe la cadena vacía, "": un texto sin ningún carácter. No es lo mismo que None ni que un espacio " ".
bool: verdadero o falso
Solo tiene dos valores posibles, y se escriben con la primera letra en mayúscula: True y False. Ni true, ni TRUE, ni Verdadero.
Los booleanos son la base de todas las decisiones que tomará el programa a partir del módulo 3. Guardar el estado de una tarea como completada = False es mucho más útil que como estado = "pendiente", porque un booleano se puede evaluar directamente.
None: ausencia de valor
None representa que no hay valor. Es un tipo con un único valor posible, y se escribe también con mayúscula inicial.
Es distinto de 0, de "" y de False. 0 es una cantidad, "" es un texto sin caracteres, False es una respuesta negativa; None significa «aquí no hay nada todavía». En TareaFácil lo usaremos, por ejemplo, para una fecha de entrega que aún no se ha fijado: no es una fecha vacía, es que no hay fecha.
- Inspeccionar el tipo con
type()
type()Python trae una herramienta para preguntar de qué tipo es un valor: la función type().
titulo = "Logotipo Panaderia Sole"
dias_estimados = 3
horas_dedicadas = 7.5
completada = False
fecha_entrega = None
print(type(titulo))
print(type(dias_estimados))
print(type(horas_dedicadas))
print(type(completada))
print(type(fecha_entrega))Salida:
La palabra class es el vocabulario interno de Python (los tipos son clases, algo que cobrará sentido en el módulo 7); de momento fíjate solo en el nombre entre comillas.
type() es tu mejor aliada cuando algo no funciona como esperas. Compara estos dos casos, aparentemente idénticos:
Al imprimirlos por separado, ambos muestran 3 en pantalla. Pero uno es un número y el otro es texto, y se comportan de forma radicalmente distinta. Cuando un programa haga algo inexplicable con un dato, lo primero es imprimir su type(). Ese reflejo te ahorrará horas.
Una precisión de vocabulario, para hablar con propiedad: type() es una función, y los paréntesis son la forma de «llamarla» pasándole un valor. Ya has usado otra función, print(). Cómo funcionan por dentro y cómo crear las tuyas es el asunto del módulo 4.
- Tipado dinámico: qué significa en la práctica
En la lección 01-03 vimos que Python tiene tipado dinámico. Ahora podemos ver qué significa eso con código delante.
En un lenguaje de tipado estático como Java o C, al crear una variable declaras su tipo y ese tipo queda fijado para siempre:
String responsable = "Luis"; // Java: responsable sera SIEMPRE texto
responsable = 5; // error: no compilaEn Python no se declara nada. El tipo lo determina el valor asignado, y cambia si asignas otro valor de otro tipo:
dato = "Luis"
print(type(dato)) # <class 'str'>
dato = 5
print(type(dato)) # <class 'int'>
dato = True
print(type(dato)) # <class 'bool'>Python no protesta en ningún momento. Insistamos en el matiz importante: el tipo pertenece al valor, no al nombre. La variable es una etiqueta, y una etiqueta puede pegarse hoy a un texto y mañana a un número.
| Aspecto | Tipado estático (Java, C) | Tipado dinámico (Python) |
|---|---|---|
| ¿Se declara el tipo? | Sí, obligatorio | No |
| ¿Puede cambiar el tipo? | No | Sí |
| ¿Cuándo se detecta un error de tipo? | Al compilar, antes de ejecutar | Al ejecutar, cuando se llega a la línea |
| Ventaja | Más seguridad, errores tempranos | Más rapidez y flexibilidad al escribir |
Y aquí un consejo que no es opcional: que Python te deje cambiar el tipo de una variable no significa que debas hacerlo. Una variable llamada dias_estimados que unas veces guarda 3 y otras "tres" es una fuente inagotable de errores. La disciplina profesional es clara: un nombre, un propósito, un tipo. Si necesitas otra cosa, crea otra variable.
- Mutable e inmutable: una primera intuición
Hay una distinción que conviene sembrar ya, aunque su alcance completo llegue con las listas del módulo 5.
Algunos valores en Python son inmutables: una vez creados, no se pueden modificar. Los números y las cadenas de texto lo son. Cuando parece que los modificas, en realidad estás creando un valor nuevo y reapuntando la etiqueta.
Mira este ejemplo:
Es tentador pensar que el texto "alta" se ha transformado en "media". No es así. Lo que ha ocurrido es que se ha creado un valor nuevo, "media", y la etiqueta prioridad ha dejado de señalar al primero para señalar al segundo. El texto "alta" no ha cambiado; simplemente ya nadie lo mira.
flowchart LR
P["prioridad"] -.->|"deja de apuntar"| A["'alta'<br/>(sigue existiendo,<br/>sin cambiar)"]
P ==>|"ahora apunta"| M["'media'<br/>(valor nuevo)"]
Se puede comprobar con id(), una función que devuelve un identificador único del valor en memoria. Si el valor fuera el mismo modificado, el identificador se mantendría; si es un valor nuevo, cambia:
prioridad = "alta"
print(id(prioridad)) # p. ej. 140234...816
prioridad = "media"
print(id(prioridad)) # un numero DISTINTO: es otro valor(Los números concretos varían en cada ejecución y en cada ordenador; lo único relevante es que son distintos.)
Y ahora la consecuencia práctica, que sí importa desde hoy:
responsable_original = "Luis"
responsable_copia = responsable_original
responsable_original = "Nuria"
print(responsable_original) # Nuria
print(responsable_copia) # Luisresponsable_copia sigue valiendo "Luis". La segunda línea la hizo apuntar al mismo valor que responsable_original, pero la tercera línea reapuntó solo a responsable_original; la otra etiqueta se quedó donde estaba. Con valores inmutables esto funciona siempre de forma intuitiva: reasignar una variable nunca afecta a las demás.
| Concepto | Significado | Tipos que has visto |
|---|---|---|
| Inmutable | El valor no se puede modificar; reasignar crea uno nuevo | int, float, str, bool, None |
| Mutable | El valor sí se puede modificar «en su sitio» | Listas y diccionarios (módulo 5) |
Todos los tipos de esta lección son inmutables, así que de momento vives en el mundo fácil. Guarda la idea: cuando llegues a las listas, donde la copia no se comporta así, sabrás exactamente qué está cambiando y por qué.
- TareaFácil: la tarea vive en variables
Vamos a lo prometido. Reescribimos tareafacil.py para que los cinco datos de la tarea —los cinco que definimos en el requisito R1 de la lección 01-01— dejen de estar escritos dentro de los print y pasen a ser variables.
Abre tu tareafacil.py y sustituye el contenido por esto:
# tareafacil.py - Estudio Alba
# Version 0.2: los datos de la tarea viven en variables
# --- Datos fijos del programa (constantes por convencion) ---
NOMBRE_APP = "TareaFacil"
VERSION = "0.2"
ESTUDIO = "Estudio Alba"
# --- Datos de la tarea ---
titulo = "Logotipo Panaderia Sole"
descripcion = "Tres propuestas en blanco y negro, formato vectorial"
responsable = "Luis"
prioridad = "alta" # alta / media / baja
completada = False # booleano: True cuando este terminada
dias_estimados = 3 # entero
horas_dedicadas = 7.5 # decimal
fecha_entrega = None # aun sin acordar con el cliente
# --- Salida por pantalla ---
print("=== TAREAFACIL - Estudio Alba ===")
print("")
print("Titulo:")
print(titulo)
print("Descripcion:")
print(descripcion)
print("Responsable:")
print(responsable)
print("Prioridad:")
print(prioridad)
print("Completada:")
print(completada)
print("Dias estimados:")
print(dias_estimados)
print("Horas dedicadas:")
print(horas_dedicadas)
print("Fecha de entrega:")
print(fecha_entrega)Ejecútalo con python tareafacil.py. Verás la ficha, ahora en dos líneas por dato.
Repasemos las decisiones que se han tomado en ese código, porque ninguna es casual:
NOMBRE_APP,VERSIONyESTUDIOvan en mayúsculas porque son constantes: no cambian durante la ejecución del programa.completadaes unbool, no el texto"pendiente". Es una elección deliberada: un booleano representa mejor un sí/no y se podrá evaluar directamente cuando lleguen los condicionales. Fíjate además en el nombre:completadase lee como una afirmación que es verdadera o falsa, que es justo como debe leerse un booleano.dias_estimadoses unintyhoras_dedicadasunfloat. Los días se cuentan enteros; las horas admiten medias.fecha_entregaesNone, no"". No es una fecha vacía: es que todavía no hay fecha. La diferencia es semántica y es importante.- Los comentarios explican lo que el nombre no puede decir: los valores admitidos en
prioridad, o el porqué delNone.
Ahora la mejora de verdad. Cambia estas dos líneas:
Guarda, ejecuta y comprueba que la ficha refleja los cambios. Has modificado dos líneas de datos y no has tocado ni una línea de las que muestran la información. En la versión anterior habrías tenido que editar el texto dentro de los print. Esa separación entre datos y presentación es una de las ideas más rentables de todo el oficio.
Lo que todavía chirría
Seamos honestos con las limitaciones de esta versión, que son el guion de las tres lecciones siguientes:
| Limitación actual | Se resuelve en |
|---|---|
Cada dato ocupa dos líneas y la ficha es fea; no se puede mezclar texto y variable en un solo print |
Entrada y salida de datos |
| No se puede calcular nada: ni si la tarea es urgente, ni cuánto queda | Operadores y expresiones |
| Los datos siguen escritos en el código: para otra tarea hay que editar el fichero | Entrada y salida de datos |
Nada impide escribir prioridad = "urgentisima" |
Conversión de tipos y validación |
Cuatro problemas, cuatro lecciones. Vamos a por ellos por orden.
Errores Comunes y Consejos
Confundir = con ==. Uno asigna, dos comparan. Escribir prioridad = "alta" cuando querías preguntar si la prioridad es alta no da error: cambia el valor de la variable silenciosamente. Es de los errores más difíciles de detectar precisamente porque no protesta.
Usar una variable antes de asignarla. NameError: name 'x' is not defined significa siempre lo mismo: ese nombre no existe todavía en ese punto del programa. Comprueba que la asignación está escrita, que está antes y que no hay ninguna errata en el nombre.
Errata en el nombre al reutilizarlo. responsable y responsble son dos variables distintas para Python. La segunda dará NameError, o peor: si por casualidad también existe, tu programa usará el dato equivocado. Deja que el autocompletado del editor escriba los nombres por ti.
Olvidar las comillas en un texto. responsable = Luis (sin comillas) hace que Python busque una variable llamada Luis y falle con NameError. Si es texto, va entre comillas. Siempre.
Escribir decimales con coma. precio = 19,99 no es un decimal. Python interpreta la coma como separador y crea algo que no es un número. En Python los decimales llevan punto.
Escribir true o false en minúscula. En Python son True y False, con mayúscula inicial. NameError: name 'true' is not defined es el aviso.
Poner un número entre comillas sin querer. dias = "3" es texto, no un número. Parece igual al imprimirlo y se comporta de forma completamente distinta. Ante la duda, type().
Nombres de una sola letra. Un x te parecerá clarísimo mientras lo escribes y un jeroglífico tres días después. La única excepción tolerada son los contadores de bucle, que verás en el módulo 3.
Usar palabras reservadas como nombres. Si el editor colorea tu nombre de variable igual que colorea if o for, cámbialo.
Consejo: prueba en el REPL. Antes de escribir algo en el fichero, pruébalo en el intérprete interactivo (python a secas en la terminal, como viste en 01-04). Asigna, imprime, consulta el type(). Es la forma más rápida de convertir una duda en una certeza.
Consejo: nombra primero, programa después. Cuando ataques un problema nuevo, escribe primero la lista de datos que intervienen y ponles nombre. La mitad del diseño de un programa es decidir qué variables existen.
Ejercicios
Ejercicio 1: Detectar y corregir errores
El siguiente programa contiene seis errores. Encuéntralos, explica cada uno y escribe la versión corregida.
1titulo = "Cartel feria del libro"
responsable = Nuria
prioridad = 'alta"
horas = 4,5
completada = false
print(titulo, responsable, prioridad, horas, completada, estado)Ejercicio 2: Tipos y trazado
a) Indica el tipo de cada valor sin ejecutar nada:
| Valor | Tipo |
|---|---|
"Marta" |
? |
12 |
? |
12.0 |
? |
"12" |
? |
True |
? |
None |
? |
"" |
? |
"True" |
? |
b) Traza este programa en una tabla (una fila por línea, una columna por variable) y di qué imprime:
tareas_totales = 8
tareas_hechas = 3
tareas_totales = 10
pendientes = tareas_totales
tareas_hechas = 5
print(pendientes)
print(tareas_hechas)Ejercicio 3: Ficha de tarea de Nuria
Escribe un fichero ficha_nuria.py que guarde en variables bien nombradas los datos de esta tarea de Estudio Alba y los muestre por pantalla:
- Título: Cartel para la feria del libro
- Descripción: Formato A2, dos versiones de color
- Responsable: Nuria
- Prioridad: media
- Todavía no está completada
- Se estiman 2 días de trabajo
- Lleva dedicadas 3,5 horas
- La fecha de entrega aún no está acordada
- El cliente de esta tarea no consta todavía
Requisitos: usa el tipo más adecuado para cada dato (no todo str), nombra las variables en snake_case y con significado, incluye una constante en mayúsculas con el nombre del estudio y añade al menos dos comentarios que aporten información real. Termina el programa imprimiendo el type() de tres variables de tipos distintos.
Soluciones
Solución 1.
Los seis errores:
| Nº | Línea | Error | Por qué |
|---|---|---|---|
| 1 | 1titulo = ... |
Nombre que empieza por dígito | Regla de Python: los nombres no pueden empezar por número |
| 2 | responsable = Nuria |
Texto sin comillas | Python busca una variable Nuria y no la encuentra → NameError |
| 3 | prioridad = 'alta" |
Comillas desparejadas | Se abre con simple y se cierra con doble → SyntaxError |
| 4 | horas = 4,5 |
Decimal con coma | En Python el separador decimal es el punto |
| 5 | completada = false |
Booleano en minúscula | En Python es False, con mayúscula inicial |
| 6 | print(... estado) |
Variable inexistente | estado no se ha asignado nunca → NameError |
Versión corregida:
titulo = "Cartel feria del libro"
responsable = "Nuria"
prioridad = "alta"
horas = 4.5
completada = False
estado = "pendiente" # faltaba definirla antes de usarla
print(titulo)
print(responsable)
print(prioridad)
print(horas)
print(completada)
print(estado)Nota: el print original pasaba varios valores separados por comas. Es válido en Python y se estudia en Entrada y salida de datos; aquí lo hemos separado en varios print para no adelantar materia.
Solución 2.
a) Tipos:
| Valor | Tipo | Observación |
|---|---|---|
"Marta" |
str |
Entre comillas → texto |
12 |
int |
Sin decimales ni comillas |
12.0 |
float |
El punto lo convierte en decimal aunque valga doce |
"12" |
str |
Entre comillas: es el texto «12», no el número |
True |
bool |
Mayúscula inicial |
None |
NoneType |
Ausencia de valor |
"" |
str |
Cadena vacía: sigue siendo un texto |
"True" |
str |
Con comillas es texto, no un booleano |
Las tres filas interesantes son 12 frente a 12.0, 12 frente a "12" y True frente a "True": parecen lo mismo en pantalla y no lo son.
b) Trazado:
| Línea | Instrucción | tareas_totales |
tareas_hechas |
pendientes |
|---|---|---|---|---|
| 1 | tareas_totales = 8 |
8 | — | — |
| 2 | tareas_hechas = 3 |
8 | 3 | — |
| 3 | tareas_totales = 10 |
10 | 3 | — |
| 4 | pendientes = tareas_totales |
10 | 3 | 10 |
| 5 | tareas_hechas = 5 |
10 | 5 | 10 |
Imprime 10 y luego 5.
La clave está en la línea 4: pendientes recibe el valor que tareas_totales tenía en ese instante (10, porque la línea 3 ya lo había cambiado). No queda «enlazada» a tareas_totales: si después esa variable cambiara, pendientes seguiría valiendo 10. Una asignación copia el valor del momento, no establece una relación permanente.
Solución 3.
# ficha_nuria.py - Estudio Alba
# Ficha de una tarea asignada a Nuria
ESTUDIO = "Estudio Alba" # constante: no cambia durante la ejecucion
titulo = "Cartel para la feria del libro"
descripcion = "Formato A2, dos versiones de color"
responsable = "Nuria"
prioridad = "media" # alta / media / baja
completada = False # pasara a True cuando se entregue
dias_estimados = 2
horas_dedicadas = 3.5
fecha_entrega = None # pendiente de confirmar con la organizacion
cliente = None # el encargo llego por la asociacion, sin cliente asignado
print("=== FICHA DE TAREA ===")
print(ESTUDIO)
print("")
print(titulo)
print(descripcion)
print(responsable)
print(prioridad)
print(completada)
print(dias_estimados)
print(horas_dedicadas)
print(fecha_entrega)
print(cliente)
print("")
print("--- Tipos ---")
print(type(titulo)) # <class 'str'>
print(type(dias_estimados)) # <class 'int'>
print(type(completada)) # <class 'bool'>Justificación de los tipos elegidos:
titulo,descripcion,responsableyprioridadson textos:str.completadaes un sí/no:bool. Es preferible a guardar el texto"pendiente".dias_estimadoses una cantidad entera:int.horas_dedicadasadmite medias horas:float, con punto decimal.fecha_entregayclienteno tienen valor todavía:None, no"".
Y la comprobación final imprime <class 'str'>, <class 'int'> y <class 'bool'>.
Conclusión
Has dado el paso que convierte un texto ejecutable en un programa. Ahora sabes que una variable es un nombre que apunta a un valor en memoria; que el = no afirma una igualdad sino que ordena una asignación, evaluando siempre primero la parte derecha; y que reasignar una variable simplemente mueve la etiqueta a otro valor, sin afectar a las demás variables que apuntaran al anterior.
Conoces las reglas de los nombres (letras, dígitos y guion bajo; sin empezar por número; sin palabras reservadas) y, más importante, las convenciones que separan al profesional del aficionado: snake_case, nombres con significado y constantes en MAYÚSCULAS. Dominas los cinco tipos básicos —int, float, str, bool y None—, sabes inspeccionarlos con type() cuando algo no cuadra, entiendes qué implica el tipado dinámico de Python y por qué conviene no abusar de él, y tienes una primera intuición de la inmutabilidad que te será muy útil cuando lleguen las listas.
Y tareafacil.py ya está en su versión 0.2: los cinco datos de la tarea del logotipo de la Panadería Solé viven en variables, y cambiar el responsable es cuestión de editar una línea de datos, no el código que los muestra.
Pero de momento el programa solo guarda información; no hace nada con ella. No sabe decir si la tarea es urgente, ni cuánto falta para la entrega, ni qué porcentaje del encargo lleva hecho Luis. Para eso hacen falta expresiones: combinar variables y valores mediante operadores para producir resultados nuevos. Es exactamente el tema de la siguiente lección, Operadores y expresiones, donde tus variables dejarán de estar quietas y empezarán a calcular.
Fundamentos de la Programación
Módulo 1: Introducción a la Programación
- ¿Qué es la programación?
- Historia de la programación
- Lenguajes de programación
- Entornos de desarrollo
- Del problema al algoritmo
Módulo 2: Conceptos Básicos
- Variables y tipos de datos
- Operadores y expresiones
- Entrada y salida de datos
- Conversión de tipos y validación de datos
Módulo 3: Estructuras de Control
Módulo 4: Funciones y Procedimientos
- Definición y uso de funciones
- Parámetros y retorno de valores
- Ámbito de variables
- Descomponer un programa en funciones
- Funciones como valores: lambda y orden superior
Módulo 5: Estructuras de Datos
- Listas y arreglos
- Cadenas de caracteres
- Diccionarios y conjuntos
- Tuplas y estructuras anidadas
- Guardar datos en archivos: texto, CSV y JSON
Módulo 6: Algoritmos Básicos
Módulo 7: Objetos y Organización del Código
- De los datos a los objetos: clases e instancias
- Atributos, métodos y constructor
- Colecciones de objetos
- Módulos, paquetes e importaciones
Módulo 8: Buenas Prácticas y Herramientas
- Documentación y comentarios
- Depuración y manejo de errores
- Control de versiones
- Pruebas automatizadas
- Estilo, legibilidad y refactorización
