Este tutorial adapta pedagógicamente el contenido original del Día 2. Las secciones marcadas como 📝 Ejercicio original del curso provienen de los archivos del curso. Los retos 🟢🟡🟠🔴, el proyecto extra y el proyecto integrador son creaciones de esta adaptación y no forman parte del curso original. Las correcciones técnicas al material original aparecen marcadas como 🛠️ Nota técnica.
Tabla de contenidos
- Antes de empezar: ¿qué construiremos hoy?
- Tipos de datos primitivos
TypeError, comprobación y conversión de tipos- Operaciones matemáticas y orden de prioridad
- Manipulación de números y f-strings
- 🚀 Proyecto del día: Calculadora de Propinas
- 🌟 Proyecto extra: Calculadora de Nota Definitiva
- 🏆 Proyecto integrador del Día 2: Planificador de Salida Pedagógica
- 🤖 Programar con apoyo de IA
- 🛠️ Correcciones técnicas al material original
- 📋 Matriz de trazabilidad
- 📦 Evidencias de aprendizaje del Día 2
0. Antes de empezar: ¿qué construiremos hoy?
(Fuente: 013 - Day 2 Goals- what we will make by the end of the day.md, 019 - You are already in the top 50%.md)
Al final del día tendrás una Calculadora de Propinas: el programa pregunta el total de la cuenta, el porcentaje de propina y entre cuántas personas se divide, y calcula cuánto paga cada una.
Parece sencillo, pero trae un problema nuevo. En el Día 1 todo era texto. Ahora necesitamos hacer cuentas con lo que escribe el usuario, y input() siempre entrega texto. Para resolverlo aprenderemos qué son los tipos de datos, cómo convertir un dato de un tipo a otro y cómo operar y mostrar números correctamente.
Prerequisito general: Día 1 completo:
print(),input(), variables, concatenación con+,len(), comentarios y lectura de errores (SyntaxError,IndentationError,NameError).
Idea motivadora del curso original: si llegaste al Día 2, ya superaste a más de la mitad de las personas que empiezan algo y lo abandonan el primer día.
1. Tipos de datos primitivos
(Fuente: 014 - Python Primitive Data Types.md)
Prerequisito: strings y
len()(Día 1, temas 1 y 4).
🎯 Objetivo de aprendizaje
- Distinguir los cuatro tipos de datos primitivos de Python:
str,int,floatybool. - Extraer caracteres individuales de un string usando subíndices, con índices positivos y negativos.
- Explicar por qué
"123" + "345"y123 + 345producen resultados diferentes.
🧠 ¿Qué aprenderemos?
- Strings (
str) y subíndices (subscripting). - Enteros (
int) y el guion bajo como separador de miles. - Números de punto flotante (
float). - Booleanos (
bool).
📖 Explicación conceptual
¿Por qué existen los tipos de datos? Un computador necesita saber qué clase de dato está manejando para saber qué puede hacer con él. Con dos números puede sumar. Con dos textos solo puede pegarlos. Por eso Python clasifica cada dato en un tipo.
Situación cotidiana: el número de tu documento de identidad está hecho de dígitos, pero nadie lo suma ni lo multiplica. Funciona como un texto. Tu estatura, en cambio, sí es una cantidad con la que se pueden hacer cálculos.
| Tipo | Nombre en Python | ¿Qué representa? | Ejemplos |
|---|---|---|---|
| Cadena de texto | str |
Texto, entre comillas | "Hola", "123", "10A" |
| Entero | int |
Números sin decimales, positivos o negativos | 7, -15, 1_000_000 |
| Punto flotante | float |
Números con parte decimal | 3.14159, 1.75, -0.5 |
| Booleano | bool |
Solo dos valores posibles: verdadero o falso | True, False |
Strings y subíndices
Un string es una secuencia de caracteres en orden, así que podemos sacar un carácter indicando su posición (índice) entre corchetes []:
print("Hello"[0]) # H → el PRIMER carácter está en la posición 0
print("Hello"[4]) # o → el último carácter (posiciones 0,1,2,3,4)
print("Hello"[-1]) # o → los índices negativos cuentan desde el finalEn programación se empieza a contar desde 0. Si un resultado te sale "corrido por uno", revisa si contaste desde 1.
Un número entre comillas no es un número
print("123" + "345") # 123345 → concatenación de textos
print(123 + 345) # 468 → suma matemáticaEl operador + hace cosas distintas según el tipo de dato. Con strings concatena. Con números suma.
Enteros largos más legibles Python permite separar los miles con guion bajo. El computador lo ignora, pero a las personas les ayuda a leer:
poblacion = 52_000_000 # es exactamente lo mismo que 52000000Float
El nombre viene de "punto flotante": el punto decimal puede "flotar" a cualquier posición del número. 3.14159 es un float.
En Python el separador decimal es el punto, nunca la coma:
1.75, no1,75.
Booleanos
Solo existen True y False. Siempre llevan la primera letra en mayúscula y van sin comillas. Los usaremos mucho desde el Día 3 para que el programa tome decisiones.
🔎 Ejemplo explicado
# Obtiene la inicial y la última letra del nombre del usuario
nombre = input("¿Cómo te llamas? ")
print("Tu inicial es: " + nombre[0])
print("Tu nombre termina en: " + nombre[-1])- Qué problema resuelve: extrae partes específicas de un texto que escribió el usuario.
- Cómo se ejecuta: el nombre queda guardado en
nombre.nombre[0]toma el primer carácter ynombre[-1]el último. Cada uno se concatena con un mensaje. - Resultado esperado: si el usuario escribe
Valentina, se imprimeTu inicial es: VyTu nombre termina en: a. - Por qué funciona la concatenación aquí:
nombre[0]también es unstr(un string de un solo carácter), así que se puede unir con otro string.
⚠️ Errores frecuentes
1. IndexError al contar desde 1
- Qué ocurre:
"Hola"[4]produceIndexError: string index out of range. - Por qué ocurre:
"Hola"tiene 4 caracteres, en las posiciones 0, 1, 2 y 3. La posición 4 no existe. - Cómo identificarlo: el mensaje dice
index out of range("índice fuera de rango"). - Cómo solucionarlo: el último índice válido siempre es
len(texto) - 1. También puedes usar-1.
2. Escribir true o "True" en lugar de True
- Qué ocurre:
trueproduceNameError, porque Python cree que es una variable."True"es un string, no un booleano. - Cómo solucionarlo: escribe
TrueoFalsecon mayúscula inicial y sin comillas.
3. Usar coma decimal
- Qué ocurre:
1,75no es un float. Python lo interpreta como dos valores separados,1y75. - Cómo solucionarlo: usa punto:
1.75.
📝 Ejercicio original del curso — Imprimir el último carácter
Enunciado: a partir de print("Hello"[0]), que imprime H, modifica el código para que se imprima el último carácter, o.
Objetivo: comprender que los índices empiezan en 0.
Conceptos: strings, subíndices.
Resultado esperado: o.
🔍 Antes de programar
- ¿Cuántos caracteres tiene
"Hello"? - Si el primero está en la posición 0, ¿en qué posición está el último?
- ¿Existe otra forma de llegar al último carácter sin contarlos?
🛠️ Nota técnica: la transcripción en español usa la palabra
"Hola"y afirma que[4]imprime la "o". Eso es un error de traducción:"Hola"solo tiene índices del 0 al 3. El curso original en inglés usa"Hello", que tiene 5 letras, y por eso aquí se conserva"Hello". Por la misma razón, donde la transcripción dice quelen("hola")da 5, el resultado real es 4 (con"Hello"sí es 5).
📝 Ejercicio original del curso — Cuestionario de tipos de datos
El curso menciona un cuestionario sobre tipos de datos después de esta lección. Su contenido no está incluido entre los archivos suministrados, así que no se reproduce aquí. La sección 🧩 cubre el mismo objetivo.
Retos adicionales (creados para esta adaptación)
🟢 Reto 1: Aplicación
Pide al usuario una palabra e imprime su primer carácter usando un índice positivo y su último carácter usando un índice negativo.
🟡 Reto 2: Ampliación
Pide nombre y apellido por separado e imprime las iniciales juntas, por ejemplo VR para Valentina Ríos.
🟠 Reto 3: Desafío
Pide una palabra e imprime su penúltimo carácter de dos formas: con un índice negativo y con un índice calculado a partir de len(). (Pista: palabra[len(palabra) - 2]). ¿Qué pasa si el usuario escribe una palabra de una sola letra? Pruébalo y explica el error.
🔴 Reto 4: Pensamiento computacional
La coordinación del colegio quiere asignar un código de casillero a cada estudiante. El código se forma con la primera letra del nombre, la última letra del apellido y el curso, separados por guiones. Por ejemplo: Valentina Ríos, 10A → V-s-10A. Diseña el programa: decide qué datos pedir, en qué variables guardarlos y cómo construir el código. Luego escribe tres casos de prueba con su resultado esperado antes de ejecutar.
🧩 Comprueba lo aprendido: Tema 1
- Conceptual: ¿por qué
"25"y25no son el mismo dato para Python? - Clasificación: escribe el tipo de cada valor:
"falso",False,0.0,-8,"3.14",1_500. - Predicción: ¿qué imprime
print("Python"[-2])? ¿Yprint("5" + "5")? - Depuración: corrige
print("Día"[3]). - Creación: pide una palabra e imprime una frase que diga cuál es su primera letra y cuántas letras tiene.
Evidencia: código del Reto 4 con sus tres casos de prueba escritos como comentarios.
2. TypeError, comprobación y conversión de tipos
(Fuente: 015 - Type Error, Type Checking and Type Conversion.md)
Prerequisito: Tema 1.
🎯 Objetivo de aprendizaje
- Interpretar un
TypeErrory unValueError. - Verificar el tipo de cualquier dato con
type(). - Convertir datos entre tipos con
int(),float(),str()ybool().
🧠 ¿Qué aprenderemos?
- Cada función espera ciertos tipos de datos.
- Comprobación de tipos (type checking) con
type(). - Conversión de tipos (type casting).
TypeErrorfrente aValueError.
📖 Explicación conceptual
Las funciones son máquinas con entradas específicas Una función es como una máquina de una fábrica que convierte papas en papas fritas. No necesitas saber cómo pela y corta por dentro, pero sí debes darle papas. Si le metes una piedra, la máquina falla.
len() funciona igual: sabe medir strings, pero no enteros.
print(len(12345)) # TypeError: object of type 'int' has no len()Un TypeError significa que le diste a una operación o función un tipo de dato que no sabe manejar.
¿Dónde averiguar qué acepta una función?
En la documentación oficial, en docs.python.org (se abre en otra pestaña). Allí dice, por ejemplo, que len() acepta secuencias como strings, pero no números. La documentación oficial es breve y a veces técnica, así que conviene complementarla con W3Schools o Stack Overflow.
Comprobar el tipo con type()
print(type("Hola")) # <class 'str'>
print(type(123)) # <class 'int'>
print(type(3.14)) # <class 'float'>
print(type(True)) # <class 'bool'>Convertir un tipo en otro
| Función | Convierte a | Ejemplo | Resultado |
|---|---|---|---|
int() |
entero | int("123") |
123 |
float() |
decimal | float("1.75") |
1.75 |
str() |
texto | str(6) |
"6" |
bool() |
booleano | bool(1) |
True |
print(int("123") + int("456")) # 579 → ahora sí sumaNo todo se puede convertir
int("ABC") # ValueError: invalid literal for int() with base 10: 'ABC'La diferencia con el TypeError es esta:
| Error | Significa | Ejemplo |
|---|---|---|
TypeError |
El tipo de dato no sirve para esa operación | len(123), "Edad: " + 17 |
ValueError |
El tipo es correcto, pero el valor concreto no se puede interpretar | int("ABC"), int("3.5") |
💡 El curso recomienda llevar un cuaderno de errores. Hasta ahora van cinco:
SyntaxError,IndentationError,NameError,TypeErroryValueError.
🔎 Ejemplo explicado
# Suma dos números escritos por el usuario
numero_1 = input("Escribe un número entero: ")
numero_2 = input("Escribe otro número entero: ")
print(type(numero_1)) # <class 'str'>
print(numero_1 + numero_2) # concatena: 5 y 3 → 53
print(int(numero_1) + int(numero_2)) # suma: 5 y 3 → 8- Qué problema resuelve: muestra por qué los datos de
input()necesitan conversión antes de operar con ellos. - Qué hace cada parte:
type()confirma que lo leído es texto. El primerprintpega los textos y el segundo convierte ambos aintantes de sumar. - Resultado esperado: con
5y3se imprime<class 'str'>, luego53y luego8.
⚠️ Errores frecuentes
1. Concatenar un número con un string
- Qué ocurre:
print("Tienes " + 17 + " años")produceTypeError: can only concatenate str (not "int") to str. - Por qué ocurre:
+no sabe "sumar" texto con número. - Cómo solucionarlo: convierte el número con
str(17). En el Tema 4 veremos una forma más cómoda, las f-strings.
2. Usar int() con un valor decimal escrito como texto
- Qué ocurre:
int("3.5")produceValueError. - Por qué ocurre:
int()no interpreta textos con punto decimal. - Cómo solucionarlo: si el usuario puede escribir decimales, usa
float().
3. Creer que bool("False") da False
- Qué ocurre: da
True. - Por qué ocurre:
bool()con un string solo revisa si está vacío (""daFalse) o no. No lee lo que dice el texto. - Cómo identificarlo: comprueba siempre con
print()ytype()en lugar de suponer.
📝 Ejercicio original del curso 1 — Corregir el TypeError de len()
Enunciado: el código print(len(12345)) produce un TypeError. Modifícalo para que funcione sin errores ni advertencias.
Conceptos: tipos de datos, argumentos de una función.
Resultado esperado: el programa imprime la longitud de un dato que len() sí acepta, como un string.
📝 Ejercicio original del curso 2 — Imprimir los cuatro tipos
Enunciado: escribe cuatro líneas de código que impriman, en cuatro líneas de salida, el tipo de un str, un int, un float y un bool, usando type().
Resultado esperado:
<class 'str'>
<class 'int'>
<class 'float'>
<class 'bool'>📝 Ejercicio original del curso 3 — Corregir el contador de letras
Enunciado: este código produce un TypeError después de que el usuario escribe su nombre. Arréglalo para que imprima cuántas letras tiene.
print("Number of letters in your name: " + len(input("Enter your name")))Conceptos: TypeError, type(), str(), variables.
Resultado esperado: con Angela, se imprime Number of letters in your name: 6.
🔍 Antes de programar
- ¿Qué tipo de dato devuelve
len()? - ¿Qué tipo tiene el texto de la izquierda del
+? - ¿Cómo puedes comprobar tu respuesta en lugar de adivinarla? (Pista:
type()) - ¿Ayudaría separar la línea en varias variables para verla mejor?
Estrategia que usa el curso (explicada, sin entregar el código final): divide la línea en variables con nombres claros, como name_of_the_user y length_of_name. Imprime el type() de cada parte, identifica cuál no es string y conviértela.
Retos adicionales (creados para esta adaptación)
🟢 Reto 1: Aplicación
Pide al usuario su año de nacimiento. Imprime su tipo antes y después de convertirlo con int().
🟡 Reto 2: Ampliación
Pide dos números. Muestra en una línea el resultado de concatenarlos y en otra el resultado de sumarlos, con un mensaje que explique la diferencia.
🟠 Reto 3: Desafío
Pide el nombre del usuario e imprime: Tu nombre tiene 9 letras y empieza por V. Debes combinar len(), subíndices, str() y concatenación, sin usar f-strings.
🔴 Reto 4: Pensamiento computacional
Investiga qué ocurre al aplicar int() y float() a cada uno de estos textos: "15", "15.5", " 15 ", "quince", "-3", "". Primero predice en una tabla (valor, int(), float()) y después verifica en Python. Escribe una conclusión: ¿qué tipo de conversión conviene para leer una estatura? ¿Y para leer una cantidad de personas? ¿Por qué?
🧩 Comprueba lo aprendido: Tema 2
- Conceptual: explica con tus palabras la diferencia entre
TypeErroryValueError. - Análisis: ¿qué imprime
print(type(str(10)))? - Predicción: ¿qué imprime
print(float("7") + 1)? - Depuración: corrige
edad = input("Edad: ")seguido deprint("El próximo año tendrás " + edad + 1). - Modificación: reescribe el Ejercicio original 3 en una sola línea. Luego compara su legibilidad con la versión en varias líneas.
Evidencia: tabla del Reto 4 con predicciones y resultados reales.
3. Operaciones matemáticas y orden de prioridad
(Fuente: 016 - Mathematical Operations in Python.md)
Prerequisito: Tema 2 (tipos
intyfloat).
🎯 Objetivo de aprendizaje
- Usar los operadores aritméticos de Python.
- Predecir el resultado de una expresión con varias operaciones según el orden de prioridad.
- Usar paréntesis para controlar ese orden.
🧠 ¿Qué aprenderemos?
- Operadores
+,-,*,/,//y**. - Conversión implícita a
floaten la división. - Orden de prioridad: PEMDAS, de izquierda a derecha.
📖 Explicación conceptual
| Operación | Operador | Ejemplo | Resultado |
|---|---|---|---|
| Suma | + |
7 + 3 |
10 |
| Resta | - |
7 - 3 |
4 |
| Multiplicación | * |
3 * 2 |
6 |
| División | / |
6 / 3 |
2.0 (siempre float) |
| División entera (floor division) | // |
5 // 3 |
1 |
| Potencia | ** |
2 ** 3 |
8 |
La división / siempre devuelve float, aunque sea exacta: 6 / 3 da 2.0. Python convierte el resultado automáticamente, y a eso se le llama conversión implícita.
La división entera // divide y luego descarta la parte decimal, redondeando hacia abajo: 5 // 3 da 1, aunque el resultado real sea 1.666… Es útil cuando necesitas un número entero, pero peligrosa si necesitas precisión.
Orden de prioridad: PEMDAS, de izquierda a derecha
- Paréntesis
() - Exponentes
** - Multiplicación
*y División///, con la misma prioridad - Adición
+y Sustracción-, también con la misma prioridad
Entre operaciones del mismo nivel se resuelve de izquierda a derecha. El curso lo resume como PEMDASLR (LR = Left to Right).
🔎 Ejemplo explicado
print(3 * 3 + 3 / 3 - 3)Paso a paso:
| Paso | Operación resuelta | Expresión resultante |
|---|---|---|
| 1 | 3 * 3 (multiplicación, la más a la izquierda) |
9 + 3 / 3 - 3 |
| 2 | 3 / 3 (división) |
9 + 1.0 - 3 |
| 3 | 9 + 1.0 (suma, a la izquierda) |
10.0 - 3 |
| 4 | 10.0 - 3 |
7.0 |
Resultado: 7.0. Es un float porque en el camino hubo una división /.
💡 El curso recomienda Thonny (thonny.org (se abre en otra pestaña)): con su depurador puedes avanzar paso a paso (F7) y ver cómo Python evalúa cada parte de la expresión.
⚠️ Errores frecuentes
1. Calcular el promedio sin paréntesis
- Qué ocurre:
nota1 + nota2 + nota3 / 3solo dividenota3entre 3. - Por qué ocurre: la división tiene prioridad sobre la suma.
- Cómo solucionarlo:
(nota1 + nota2 + nota3) / 3.
2. Usar ^ o x para potencias o productos
- Qué ocurre:
2 ^ 3da1, porque^es otra operación (XOR a nivel de bits) y no una potencia.3 x 2produceSyntaxError. - Cómo solucionarlo: usa
**para la potencia y*para la multiplicación.
3. Usar // cuando se necesitan decimales
- Qué ocurre:
7 // 2da3, y se pierde el.5. - Cómo solucionarlo: usa
/cuando la parte decimal importa, por ejemplo con dinero, medidas o notas.
📝 Ejercicio original del curso 1 — Predecir el resultado
Enunciado: sin ejecutar el código, predice con lápiz y papel qué imprime print(3 * 3 + 3 / 3 - 3). Luego verifícalo.
Resultado esperado: 7.0 (desarrollado paso a paso en el ejemplo anterior).
📝 Ejercicio original del curso 2 — Cambiar el resultado a 3
Enunciado: modifica solo con paréntesis la expresión 3 * 3 + 3 / 3 - 3 para que el resultado sea 3 en lugar de 7.
Conceptos: prioridad de operadores, paréntesis.
🔍 Antes de programar
- ¿Qué operación tiene hoy la prioridad más baja pero conviene hacer primero?
- Si una suma queda entre paréntesis, ¿cómo cambia el orden del resto?
- Prueba varias ubicaciones de paréntesis en papel antes de escribir código.
(El curso resuelve este reto encerrando una de las sumas entre paréntesis. Intenta descubrir cuál antes de consultar la solución.)
📝 Ejercicio original del curso 3 — Reto de código posterior
La lección termina remitiendo a un reto de código en la lección siguiente. Por la mención del cálculo del IMC en el archivo 017, todo indica que es un ejercicio de Índice de Masa Corporal. Su enunciado no está incluido entre los archivos suministrados. El Reto 2 de abajo propone una actividad equivalente, creada para esta adaptación.
Retos adicionales (creados para esta adaptación)
🟢 Reto 1: Aplicación
Predice y luego verifica: 2 + 3 * 4 ** 2, (2 + 3) * 4 ** 2, 10 - 4 - 2 y 2 ** 3 ** 2. (El último tiene una sorpresa: investiga en qué sentido se agrupan las potencias.)
🟡 Reto 2: Ampliación, Índice de Masa Corporal
Pide el peso en kg y la estatura en metros, y calcula el IMC con la fórmula peso / estatura². Decide qué conversión de tipo usar para cada dato y justifica tu decisión en un comentario.
🟠 Reto 3: Desafío, promedio de tres notas
Pide tres notas de 1.0 a 5.0 e imprime el promedio. Escribe primero la versión incorrecta, sin paréntesis, y después la correcta. Registra en un comentario la diferencia de resultados con las notas 3.0, 4.0 y 5.0.
🔴 Reto 4: Pensamiento computacional
Un video dura cierta cantidad de minutos (dato del usuario). Muestra la duración en horas completas y minutos restantes, por ejemplo 135 minutos = 2 horas y 15 minutos. Solo puedes usar los operadores de este tema: //, * y -. Diseña primero el algoritmo en pasos y después prográmalo.
🧩 Comprueba lo aprendido: Tema 3
- Conceptual: ¿por qué
6 / 3da2.0y no2? - Predicción: ¿qué imprime
print(10 // 4)? ¿Yprint(10 / 4)? ¿Yprint(type(10 // 4))? - Análisis: explica paso a paso la evaluación de
4 + 8 / 2 * 3. - Depuración: este código debería convertir 30 °C a Fahrenheit (86) pero no lo hace:
print(30 * 9 / 5 + 32 * 1 - 32). Corrígelo y explica el error. - Creación: calcula el área de un círculo con el radio que escriba el usuario, usando
3.14159como valor de π.
Evidencia: hoja con la tabla paso a paso de la evaluación de una expresión y el código del Reto 4.
4. Manipulación de números y f-strings
(Fuente: 017 - Number Manipulation and F Strings in Python.md)
Prerequisito: Tema 3.
🎯 Objetivo de aprendizaje
- Redondear números con
round()y distinguirlo del truncamiento conint(). - Actualizar variables con operadores de asignación compuesta (
+=,-=,*=,/=). - Construir mensajes que mezclan varios tipos de datos con f-strings.
🧠 ¿Qué aprenderemos?
int()frente around().round(numero, decimales).- Operadores de asignación compuesta.
- f-strings y formato con dos decimales (esto último es una ampliación de esta adaptación).
📖 Explicación conceptual
Truncar frente a redondear
imc = 30.85
print(int(imc)) # 30 → elimina los decimales
print(round(imc)) # 31 → redondea al entero más cercano
print(round(imc, 1)) # 30.9 → redondea a 1 decimalint()corta la parte decimal. No redondea.round(numero)redondea al entero más cercano.round(numero, n)redondea andecimales. Es útil con dinero o medidas.
🛠️ Nota técnica: el curso dice que
int()hace un floor (redondeo hacia abajo). Eso solo es cierto con números positivos:int(-3.7)da-3, porqueint()trunca hacia cero. También dice queround()redondea.5siempre hacia arriba, y no es así. Python usa el redondeo del banquero: los empates se resuelven hacia el número par, así queround(2.5)da2yround(3.5)da4. Además, algunos decimales no se guardan de forma exacta en la memoria, y por esoround(2.675, 2)da2.67. Ver la documentación oficial deround()(se abre en otra pestaña).
Operadores de asignación compuesta Sirven para actualizar una variable a partir de su propio valor anterior:
puntaje = 0
puntaje += 1 # equivale a: puntaje = puntaje + 1 → 1
puntaje += 5 # → 6
puntaje -= 2 # → 4
puntaje *= 3 # → 12
puntaje /= 4 # → 3.0 (la división produce float)f-strings
Mezclar tipos con + obliga a convertir todo con str(). Una f-string lo simplifica: se escribe una f justo antes de las comillas y cada variable va entre llaves {}.
puntaje = 0
estatura = 1.8
esta_ganando = True
# Con concatenación: hay que convertir cada valor
print("Tu puntaje es " + str(puntaje) + ", tu estatura es " + str(estatura))
# Con f-string: Python convierte automáticamente
print(f"Tu puntaje es {puntaje}, tu estatura es {estatura}, ¿vas ganando? {esta_ganando}")Ampliación (no aparece en el curso): mostrar siempre dos decimales
round(33.6, 2) da 33.6, porque un número no guarda ceros a la derecha. Para mostrar 33.60, se usa un formato dentro de la f-string:
valor = 33.6
print(f"Pagas ${valor:.2f}") # Pagas $33.60:.2f significa "mostrar como decimal con 2 cifras después del punto". Este formato solo cambia cómo se ve el número, no su valor.
🔎 Ejemplo explicado
# Marcador de un partido de microfútbol del intercolegiado
goles_local = 0
goles_local += 1
goles_local += 1
minutos_jugados = 38.5
print(f"El equipo local lleva {goles_local} goles en {minutos_jugados} minutos")
print(f"Promedio: {round(goles_local / minutos_jugados, 3)} goles por minuto")- Qué problema resuelve: lleva un marcador que se actualiza y lo muestra junto con otros datos de distinto tipo.
- Cómo se ejecuta:
+=suma un gol dos veces. Luego las f-strings insertan el entero, el float y un cálculo redondeado. - Resultado esperado:
El equipo local lleva 2 goles en 38.5 minutosyPromedio: 0.052 goles por minuto. - Observa: dentro de las llaves
{}también se pueden escribir expresiones completas, no solo variables.
⚠️ Errores frecuentes
1. Olvidar la f
- Qué ocurre:
print("Puntaje: {puntaje}")imprime literalmentePuntaje: {puntaje}. - Cómo solucionarlo: escribe la
fantes de las comillas:f"Puntaje: {puntaje}".
2. Esperar que round(x, 2) muestre dos ceros
- Qué ocurre:
round(55.0, 2)muestra55.0, no55.00. - Cómo solucionarlo: para mostrar, usa
f"{x:.2f}".
3. Usar += en una variable que no existe
- Qué ocurre:
NameError. - Por qué ocurre:
x += 1necesita un valor anterior dex. - Cómo solucionarlo: inicializa la variable antes, por ejemplo
puntaje = 0.
📝 Ejercicio original del curso — Reto de código posterior
La lección termina con "tengo un reto de codificación para ti". Su enunciado no está incluido entre los archivos suministrados. Los retos siguientes cubren los mismos conceptos.
Retos adicionales (creados para esta adaptación)
🟢 Reto 1: Aplicación
Predice el valor final: x = 10, x += 5, x *= 2, x -= 4, x /= 2. Verifica y explica por qué el resultado es un float.
🟡 Reto 2: Ampliación
Reescribe con f-string el Ejercicio original 3 del Tema 2 (el contador de letras). Compara ambas versiones: ¿cuál es más legible? ¿Por qué ya no necesitas str()?
🟠 Reto 3: Desafío, conversor de moneda
Pide una cantidad en pesos colombianos y la tasa de cambio del día (pesos por dólar). Muestra el equivalente en dólares con exactamente dos decimales. Prueba con valores que produzcan resultados como 12.5 y comprueba que se muestre 12.50.
🔴 Reto 4: Pensamiento computacional, meta de ahorro
Un estudiante quiere comprar unos audífonos. El programa pide el precio, cuánto ahorra por semana y cuántas semanas lleva ahorrando. Debe mostrar cuánto lleva ahorrado, cuánto le falta y qué porcentaje de la meta ha alcanzado, redondeado a 1 decimal. Todavía no conoces if, así que decide cómo presentar el caso en que ya superó la meta. (¿Qué muestra tu programa si "lo que falta" sale negativo? Escribe tu análisis en un comentario.)
🧩 Comprueba lo aprendido: Tema 4
- Conceptual: ¿qué diferencia hay entre
int(4.9)yround(4.9)? - Predicción: ¿qué imprimen
round(2.5),round(3.5)yround(7.456, 1)? Verifica y compara con lo que dice el curso. - Análisis: ¿qué hace el
:.2fenf"{precio:.2f}"? - Depuración: corrige
vidas = 3,vida -= 1,print("Te quedan {vidas} vidas"). Tiene dos errores. - Creación: con una sola f-string, imprime tu nombre (
str), tu edad (int), tu estatura (float) y si te gusta programar (bool).
Evidencia: captura del Reto 3 funcionando con al menos dos casos de prueba.
5. 🚀 Proyecto del día: Calculadora de Propinas
(Fuente: 018 - Day 2 Project- Tip Calculator.md, proyecto oficial del curso original)
Problema
Al salir a comer en grupo, repartir la cuenta con propina incluida genera confusión. Vas a construir un programa que lo calcule automáticamente.
Contexto
En Colombia, muchos restaurantes sugieren un "servicio voluntario" del 10 %. El mismo cálculo sirve para repartir cualquier gasto compartido: una pizza del grupo de estudio, la tula del paseo o el regalo para un profesor.
Objetivo
Construir un programa que pida el total de la cuenta, el porcentaje de propina y el número de personas, y muestre cuánto paga cada una, redondeado a dos decimales.
Requisitos funcionales
- Mostrar un mensaje de bienvenida:
¡Bienvenido a la calculadora de propinas! - Pedir el total de la cuenta. Puede tener decimales.
- Pedir el porcentaje de propina (10, 12 o 15), sin el símbolo
%. - Pedir entre cuántas personas se divide la cuenta.
- Mostrar:
Cada persona debe pagar: $X, con dos decimales.
Restricciones técnicas
input(), conversión de tipos, operaciones matemáticas, variables y f-strings. Sin condicionales, que llegan en el Día 3.
Explicación matemática del curso
Para calcular el 12 % de algo, se multiplica por 12 / 100 = 0.12.
- Cuenta de $150 → propina:
150 * 0.12 = 18→ total:150 + 18 = 168. - Forma abreviada:
150 * 1.12 = 168. - Entre 5 personas:
168 / 5 = 33.6→ se muestra como$33.60.
🛠️ Nota técnica sobre decimales extraños: si en tus pruebas aparece
168.00000000000003en lugar de168, no es un error tuyo. Es la forma en que los computadores representan internamente los númerosfloat. Por eso el resultado final se redondea o se formatea. Documentación oficial sobre este tema (se abre en otra pestaña).
🔍 Antes de programar: planificación
- Entradas: ¿cuáles son y qué tipo debe tener cada una? (Piensa: ¿una cuenta puede tener centavos? ¿Puede haber 3.5 personas?)
- Proceso: escribe la fórmula en papel, con paréntesis, antes de programarla.
- Salida: ¿qué formato debe tener?
- Divide el problema: entradas → propina → total → valor por persona → mostrar.
- Prueba en papel: con cuenta $100, propina 10 % y 2 personas, ¿cuánto debería pagar cada una?
Construcción paso a paso
Versión 1: bienvenida y primera entrada
Muestra la bienvenida, pide la cuenta y guárdala en una variable. Imprime su type(). ¿Qué tipo tiene? ¿Por qué no sirve todavía para hacer cálculos?
Versión 2: entradas convertidas
Convierte la cuenta a float, y la propina y el número de personas a int. El curso justifica estas decisiones así: una cuenta tiene centavos, pero "nunca he tenido una comida con 3.5 personas".
Versión 3: calcular el total con propina El curso muestra que hay varias formas válidas de hacerlo:
| Alternativa | Idea | Ventaja |
|---|---|---|
| Por pasos | porcentaje = propina / 100, luego valor_propina = cuenta * porcentaje, luego total = cuenta + valor_propina |
Muy fácil de seguir y depurar |
| En una línea | total = cuenta * (1 + propina / 100) |
Más compacta |
🛠️ Nota técnica: la transcripción escribe esta fórmula como
factura * (1 + propina) / 100), con paréntesis mal cerrados. Esa expresión produceSyntaxError, y si se corrige de forma literal acuenta * (1 + propina) / 100da un resultado erróneo. La forma correcta escuenta * (1 + propina / 100).
Imprime el total antes de continuar, para verificar este paso de forma aislada.
Versión 4: dividir y mostrar Divide el total entre las personas, redondea o formatea a dos decimales y muestra el resultado con una f-string.
Recomendación de esta adaptación: el curso usa
round(valor, 2), que da33.6y no33.60. Para mostrar dinero correctamente usaf"{valor:.2f}"(ver Tema 4).
Pruebas
| Cuenta | Propina | Personas | Resultado esperado |
|---|---|---|---|
| 100 | 10 | 2 | Cada persona debe pagar: $55.00 |
| 150 | 12 | 5 | Cada persona debe pagar: $33.60 |
| 124.56 | 12 | 7 | Cada persona debe pagar: $19.93 |
🧪 Prueba y depuración
Este código tiene cuatro errores. Encuéntralos, clasifícalos (SyntaxError, TypeError, NameError, ValueError o error de lógica) y corrígelos:
print("¡Bienvenido a la calculadora de propinas!")
cuenta = input("¿Cuál fue el total de la cuenta? $")
propina = int(input("¿Qué porcentaje de propina quieres dar? 10, 12 o 15? "))
personas = int(input("¿Entre cuántas personas se divide la cuenta? "))
total = cuenta * 1 + propina / 100
por_persona = total / persona
print("Cada persona debe pagar: ${por_persona:.2f}")Después responde: ¿qué pasa si el usuario escribe 12% en la propina? ¿Qué tipo de error aparece? ¿Cómo ayuda el texto de la pregunta a evitarlo?
⭐ Extensión del proyecto
- Muestra también el valor de la propina total y el total de la cuenta con propina.
- Muestra la cantidad en pesos colombianos con separador de miles. Investiga el formato
f"{valor:,.2f}". - Muestra cuánto aporta cada persona solo de propina.
6. 🌟 Proyecto extra: Calculadora de Nota Definitiva
Situación
Faltan dos semanas para cerrar el periodo y muchos estudiantes no saben cómo va su nota definitiva en Tecnología. Cada periodo tiene tres componentes con distinto peso:
| Componente | Peso |
|---|---|
| Talleres y ejercicios | 30 % |
| Proyecto | 40 % |
| Evaluación | 30 % |
Objetivo
Construir un programa que pida la nota de cada componente (escala de 1.0 a 5.0), calcule la nota definitiva ponderada y la muestre con un decimal. Además, debe mostrar cuánto aportó cada componente.
Requisitos funcionales
- Pedir el nombre del estudiante y las tres notas.
- Calcular el aporte de cada componente:
nota × peso / 100. - Calcular la nota definitiva como la suma de los aportes.
- Mostrar un informe con f-strings, por ejemplo:
Informe de Valentina
Talleres (30%): aporta 1.26
Proyecto (40%): aporta 1.92
Evaluación (30%): aporta 1.08
Nota definitiva: 4.3Decisiones que debes tomar
- ¿Guardas los pesos como
0.3o como30? ¿Qué ventajas tiene cada opción? - ¿
float()oint()para las notas? - ¿
round()o:.1fpara mostrar la nota? ¿Muestran siempre lo mismo? (Pista: prueba con una definitiva de4.0.)
Pruebas
| Talleres | Proyecto | Evaluación | Definitiva esperada |
|---|---|---|---|
| 4.2 | 4.8 | 3.6 | 4.3 (4.26) |
| 3.0 | 3.0 | 3.0 | 3.0 |
| 5.0 | 1.0 | 5.0 | 3.4 |
⭐ Extensión
- Agrega un cuarto componente, "Autoevaluación", con 10 %, y ajusta los pesos para que sumen 100 %.
- Calcula qué nota necesitaría el estudiante en la evaluación para llegar a 3.0, dadas las otras dos notas. (Requiere despejar una ecuación: escríbela primero en papel.)
7. 🏆 Proyecto integrador del Día 2: Planificador de Salida Pedagógica
Proyecto integrador de este día, creado para esta adaptación. Reúne los conceptos del Día 1 y del Día 2.
Situación problema
El curso 10A organiza una salida pedagógica a un parque temático o museo de ciencia. El representante del curso debe presentar un presupuesto claro a la coordinación y a las familias.
Pregunta orientadora
¿Cómo puede un programa transformar unos pocos datos (transporte, entradas, estudiantes, descuento) en un presupuesto confiable y fácil de leer?
Objetivo
Construir un programa que calcule el costo total de la salida y el valor que debe aportar cada estudiante.
Requerimientos
- Pedir: nombre del destino, costo total del bus, precio de la entrada por estudiante, número de estudiantes y porcentaje de descuento que ofrece el lugar sobre las entradas.
- Calcular:
- Subtotal de entradas = precio de entrada × estudiantes
- Descuento = subtotal de entradas × porcentaje / 100
- Costo total = bus + subtotal de entradas − descuento
- Aporte por estudiante = costo total / estudiantes
- Generar un código de la salida: las dos primeras letras del destino, en la forma en que las escriba el usuario, seguidas del número de estudiantes. Por ejemplo,
Ma40para Maloka con 40 estudiantes. - Mostrar un informe de varias líneas, usando
\no variosprint(), construido con f-strings y valores monetarios con dos decimales. - Incluir la verificación de tipo (
type()) de al menos una entrada antes y después de convertirla, dejada como comentario de prueba. - Usar nombres de variable descriptivos y comentarios que expliquen cada bloque: entradas, cálculos y salida.
Restricciones técnicas
Solo conceptos de los Días 1 y 2. Sin if ni ciclos.
Etapas de desarrollo
- Entradas y conversión de tipos. Prueba cada entrada.
- Cálculos, verificando cada resultado intermedio con
print()temporales. - Código de la salida con subíndices y
str(). - Informe final con f-strings.
- Limpieza: elimina los
print()de prueba y revisa nombres y comentarios.
Entregables
- Archivo
.pyfuncional. - Tabla con los casos de prueba y sus resultados.
- Registro de errores: al menos dos errores que hayas tenido, su tipo y cómo los corregiste.
Casos de prueba
| Bus | Entrada | Estudiantes | Descuento | Costo total | Aporte por estudiante |
|---|---|---|---|---|---|
| 800000 | 15000 | 40 | 10 | 1340000.00 | 33500.00 |
| 500000 | 20000 | 25 | 0 | 1000000.00 | 40000.00 |
Criterios técnicos de funcionamiento
- No se produce ningún
TypeError,ValueErrorniNameErrorcon entradas válidas. - Los cálculos coinciden con los casos de prueba.
- Todos los valores monetarios se muestran con dos decimales.
- El código es legible: nombres descriptivos, comentarios útiles y bloques separados.
Posibles extensiones
- Agregar un costo de refrigerio por estudiante.
- Mostrar valores con separador de miles (
:,.2f). - Calcular cuántos estudiantes más harían falta para bajar el aporte en cierta cantidad. (Requiere despejar una ecuación.)
8. 🤖 Programar con apoyo de IA
Los temas de hoy muestran por qué no basta con aceptar lo que dice una fuente, sea un video, un libro o una IA. El propio material del curso contiene afirmaciones inexactas sobre round() e int() (ver la sección 9). Verificar es parte del trabajo del programador.
Proceso recomendado:
- Formula el problema e intenta resolverlo solo.
- Si consultas una IA, pide explicaciones, no solo código.
- Lee y ejecuta lo que te sugiera, y pruébalo con casos límite:
.5, números negativos, textos inesperados. - Contrasta con la documentación oficial de Python (se abre en otra pestaña).
- Explica con tus palabras, en un comentario, cómo funciona.
Actividad: verificar afirmaciones. Pregunta a una IA: "¿Cómo redondea la función round() de Python los números terminados en .5?". Luego:
- Ejecuta
round(0.5),round(1.5),round(2.5)yround(3.5). - Compara los resultados con la respuesta de la IA, con lo que dice el curso (Tema 4) y con la documentación oficial.
- Escribe un párrafo: ¿quién tenía razón? ¿Cómo lo comprobaste?
9. 🛠️ Correcciones técnicas al material original
Siguiendo el principio de no suponer que un código funciona solo porque aparece en el curso, se revisaron las afirmaciones técnicas de las transcripciones:
| Archivo | Afirmación en la transcripción | Qué ocurre realmente | Tratamiento en este tutorial |
|---|---|---|---|
014 |
len("hola") da 5 |
Da 4. El original en inglés usa "Hello" |
Se usa "Hello" |
014 |
"Hola"[4] imprime "o" |
Produce IndexError |
Se usa "Hello"[4] y se explica el error |
017 |
int() hace floor |
int() trunca hacia cero. Difiere con negativos: int(-3.7) da -3 |
Nota técnica en el Tema 4 |
017 |
round() sube siempre con .5 |
Python redondea los empates al par: round(2.5) da 2 |
Nota técnica y actividad con IA |
018 |
round(valor, 2) muestra 33.60 |
Muestra 33.6 |
Se recomienda f"{valor:.2f}" |
018 |
factura * (1 + propina) / 100) |
Paréntesis desbalanceados. La lógica correcta es cuenta * (1 + propina / 100) |
Nota técnica en el proyecto |
016 |
// "da un entero" |
Solo si ambos operandos son int: 5.0 // 3 da 1.0 (float) |
Se menciona en la sección 🧩 del Tema 3 como punto de indagación |
10. 📋 Matriz de trazabilidad
| Contenido original | Archivo de origen | Concepto desarrollado | Ejercicio original | Reto adicional | Proyecto relacionado |
|---|---|---|---|---|---|
| Objetivos del día, Calculadora de Propinas | 013 |
Sección 0 | — | — | Sección 5 |
str, int, float, bool; subíndices; _ en números |
014 |
Tema 1 | Imprimir el último carácter. Cuestionario de tipos (mencionado, no suministrado) | Retos 1–4 del Tema 1 (casillero escolar) | Integrador (código de salida) |
TypeError, type(), conversión, ValueError |
015 |
Tema 2 | Corregir len(12345). Imprimir los 4 tipos. Corregir el contador de letras |
Retos 1–4 del Tema 2 (tabla de conversiones) | Proyectos 5, 6 y 7 |
Operadores, / frente a //, **, PEMDASLR |
016 |
Tema 3 | Predecir 3*3+3/3-3. Cambiar el resultado a 3. Reto de código posterior (mencionado, no suministrado) |
Retos 1–4 del Tema 3 (IMC, promedio, minutos) | Proyectos 5, 6 y 7 |
round(), int(), +=, f-strings |
017 |
Tema 4 | Reto de código posterior (mencionado, no suministrado) | Retos 1–4 del Tema 4 (moneda, ahorro) | Proyectos 5, 6 y 7 |
| Calculadora de Propinas | 018 |
Integración de los Temas 1–4 | Proyecto oficial completo | Depuración con 4 errores y extensiones | Sección 5 |
| Mensaje de cierre | 019 |
Motivación (Sección 0) | — | — | — |
| (No existe en el curso original) | — | — | — | Calculadora de Nota Definitiva | Sección 6 |
| (No existe en el curso original) | — | — | — | Planificador de Salida Pedagógica | Sección 7 |
11. 📦 Evidencias de aprendizaje del Día 2
- Código funcional de la Calculadora de Propinas, que pasa los tres casos de prueba.
- Código de al menos uno de los proyectos adicionales (Nota Definitiva o Salida Pedagógica).
- Tabla de predicción y verificación de conversiones (Reto 4 del Tema 2).
- Evaluación paso a paso de una expresión matemática según PEMDASLR.
- Cuaderno de errores actualizado con
TypeError,ValueErroreIndexError: qué los causa y cómo corregirlos. - Párrafo de la actividad de IA sobre
round(), con la verificación hecha en Python.