Esta guía enseña el Tema B2, Programación, para el curso evaluado por primera vez en 2027, utilizando Python.
Prerrequisitos: pensamiento computacional de B1 (descomposición, abstracción, algoritmos como diagramas de flujo y pseudocódigo). Debe ser capaz de ejecutar un programa breve de Python y leer su salida.
6.2
Fundamentos de programación
¿Por qué falla un programa funcional el lunes?
El programa de caja de una tienda ha funcionado durante un mes. El lunes, un cliente digita two en lugar de 2 para la cantidad y el programa se detiene. Nada cambió en el código: cambió la entrada. Los buenos programas se escriben para cualquier entrada posible, no solo para las que intentó el programador.
Variables y tipos de datos
Una variable es un almacenamiento nombrado para un valor que puede cambiar mientras se ejecuta el programa. Una constante es un valor nombrado que no debería cambiar; en Python se escribe en mayúsculas por convención, como VAT_RATE = 0.2.
Cada valor tiene un tipo de dato, que determina qué puede almacenar y qué operaciones funcionan sobre él.
Tipo
Python
Ejemplo
Uso
entero
int
42
conteos, índices
real
float
3.75
mediciones, dinero en un cálculo
Booleano
bool
True
banderas, condiciones
cadena de texto
str
"Ada"
texto
int("42") convierte texto a entero y str(42) convierte un número a texto. Este cambio de tipo es necesario porque input() siempre devuelve una cadena de texto.
7 / 2 es 3.5; 7 // 2 es 3 (división entera); 7 % 2 es 1 (el residuo, módulo).
Cadenas de texto
Una cadena de texto es una secuencia de caracteres, indexada desde 0.
code = "ib-2027"
len(code) # 7
code[0] # "i"
code[3:7] # "2027": from index 3 up to, not including, 7
code.upper() # "IB-2027"
code.find("-") # 2; -1 if not found
"2027" in code # True
Las cadenas de texto en Python son inmutables: code.upper() devuelve una nueva cadena y deja code sin cambios. Unir cadenas con + es concatenación.
Excepciones: manejo de entrada incorrecta
Una excepción es un error que se genera mientras el programa se ejecuta, como ValueError para int("two") o ZeroDivisionError para 5 / 0. Si no se maneja, detiene el programa. Un bloque try … except la captura:
while True:
text = input("Quantity: ")
try:
qty = int(text)
break
except ValueError:
print("Enter a whole number.")
El bucle se repite hasta que el cambio de tipo tenga éxito, por lo que el programa nunca falla ante two. Un bloque finally, si está presente, se ejecuta independientemente de si ocurrió una excepción: se usa para cerrar archivos.
Depuración y tablas de trazado
Hay tres tipos de error:
Tipo
Cuándo aparece
Ejemplo
error de sintaxis
antes de ejecutar el programa
falta dos puntos después de if x > 0
error de ejecución
durante la ejecución, como una excepción
índice fuera del límite de una lista
error lógico
nunca reportado: la salida es incorrecta
< donde se esperaba <=
Una tabla de trazado registra el valor de cada variable después de cada paso, manualmente. Es el método estándar para encontrar errores lógicos y una pregunta de examen común.
total = 0
for k in range(1, 5):
if k % 2 == 0:
total = total + k
print(total)
k
k % 2 == 0
total
0
1
Falso
0
2
Verdadero
2
3
Falso
2
4
Verdadero
6
Salida: 6. Observe que range(1, 5) se detiene antes de 5. Otras técnicas de depuración incluyen imprimir statements en puntos clave, breakpoints en un depurador que pausan el programa y muestran las variables, y avanzar línea por línea.
Una estructura de datos estática tiene un tamaño fijo al crearse, como un array en Java o C. Una estructura de datos dinámica crece y disminuye mientras se ejecuta el programa, como una lista en Python.
Estático
Dinámico
tamaño
fijo
cambia en tiempo de ejecución
memoria
reservada por adelantado, puede haber desperdicio
usada según sea necesario
acceso
directo por índice, rápido
puede requerir trabajo adicional para crecer
riesgo
desbordamiento cuando está llena
agotamiento de memoria
Arrays unidimensionales y bidimensionales
Un array unidimensional almacena elementos de un solo tipo bajo un nombre, cada uno accesible mediante su índice. En Python, una lista cumple esta función:
marks = [67, 82, 45, 90]
marks[2] # 45
marks[2] = 50 # change one item
marks.append(71) # add at the end: [67, 82, 50, 90, 71]
len(marks) # 5
Un array bidimensional es una tabla: una lista de filas, donde cada fila es una lista. El primer índice selecciona la fila y el segundo la columna.
Antes de realizar una pop o dequeue, compruebe isEmpty: eliminar de una estructura vacía es un desbordamiento por falta. Empujar sobre una pila fija llena es un desbordamiento.
Todo algoritmo se construye a partir de tres constructos: secuencia (pasos en orden), selección (if, elif, else) e iteración (bucles).
Bucle
Python
Uso cuando
controlado por conteo
for i in range(n):
el número de repeticiones es conocido
controlado por condición
while condition:
repetir hasta que ocurra algo
sobre una colección
for item in items:
visitar cada elemento una vez
Un bucle while cuya condición nunca se vuelve falsa es un bucle infinito. La selección anidada o los bucles anidados colocan un constructo dentro de otro; la sangría indica cuál está dentro de cuál.
Funciones, parámetros y ámbito
Una función es un bloque de código con nombre que puede llamarse muchas veces. Recibe parámetros y puede devolver un valor. Dividir un programa en funciones es la modularidad: cada parte se escribe, prueba y reutiliza por separado.
def mean(values):
"""Return the mean of a non-empty list of numbers."""
total = 0
for v in values:
total = total + v
return total / len(values)
print(mean([4, 8, 9])) # 7.0
Una variable local como total existe solo dentro de la función mientras esta se ejecuta.
Una variable global se define a nivel de módulo y puede leerse donde las reglas de Python para el ámbito y la vinculación de nombres la resuelven; un nombre local puede oscurecerla. Usar muchas variables globales dificulta probar un programa, porque cualquier función podría modificarlas.
La docstring describe el contrato de la función: lo que necesita (una lista no vacía) y lo que devuelve. mean([]) viola el contrato y genera ZeroDivisionError.
El contrato de una función: las entradas que acepta, incluidos los casos límite, y la salida que promete para cada caso
Pruebe una función contra su contrato: valores normales, casos límite en el borde de lo que acepta (una lista de un elemento) y valores inválidos que debe rechazar (una lista vacía).
La notación Big O da un límite asintótico superior de cómo crece un costo elegido con respecto al tamaño de entrada $n$. Indique si el costo analizado es del peor caso, caso promedio o mejor caso. Se descartan constantes y términos menores.
Big O
Nombre
Ejemplo
Pasos para $n = 1000$
$O(1)$
constante
leer marks[2]
1
$O(\log n)$
logarítmica
búsqueda binaria
aproximadamente 10
$O(n)$
lineal
búsqueda lineal
1000
$O(n^2)$
cuadrática
ordenamiento burbuja, ordenamiento por selección
aproximadamente 1 000 000
Un solo bucle sobre los datos suele ser $O(n)$; un bucle dentro de otro bucle sobre los mismos datos suele ser $O(n^2)$.
Búsqueda lineal y búsqueda binaria
Una búsqueda lineal revisa cada elemento sucesivamente. Funciona en cualquier lista, ordenada o no, y tiene complejidad $O(n)$.
def linear_search(items, target):
for i in range(len(items)):
if items[i] == target:
return i
return -1
Una búsqueda binaria requiere una lista ordenada. Revisa el elemento central y descarta la mitad que no puede contener el objetivo, por lo que cada sondeo reduce a la mitad lo restante: $O(\log n)$.
Trazado para 23: low 0, high 8, mid 4 (16 < 23) → low 5; mid$(5 + 8) // 2 = 6$ (38 > 23) → high 5; mid 5: encontrado, devolver 5. En una lista desordenada, la búsqueda binaria puede omitir un valor existente, por lo que el contrato debe exigir entrada ordenada.
Ordenamiento burbuja y ordenamiento por selección
Un ordenamiento burbuja compara cada par de vecinos y los intercambia si están en el orden incorrecto. Después de cada pasada, el elemento más grande restante ha "subido" hasta el final.
def bubble_sort(a):
n = len(a)
for p in range(n - 1):
swapped = False
for i in range(n - 1 - p):
if a[i] > a[i + 1]:
a[i], a[i + 1] = a[i + 1], a[i]
swapped = True
if not swapped:
break
La bandera swapped permite detenerse anticipadamente cuando una pasada no realiza intercambios: la lista ya está ordenada.
Una ordenación por selección encuentra el elemento más pequeño en la parte no ordenada y lo intercambia en la siguiente posición.
def selection_sort(a):
for i in range(len(a) - 1):
smallest = i
for j in range(i + 1, len(a)):
if a[j] < a[smallest]:
smallest = j
a[i], a[smallest] = a[smallest], a[i]
Pasadas de cada ordenación sobre [5, 1, 4, 2]:
Tras cada pasada
Ordenación burbuja
Ordenación por selección
1
[1, 4, 2, 5]
[1, 5, 4, 2]
2
[1, 2, 4, 5]
[1, 2, 4, 5]
3
sin intercambios: detener
[1, 2, 4, 5]
Ambas son $O(n^2)$. La ordenación por selección realiza como máximo $n - 1$ intercambios; la ordenación burbuja puede detenerse antes en una lista casi ordenada.
Explorar
Search probes and boundary cases
Compare linear search with binary search on sorted data. Trace a match or an absent target; indices start at zero.
Las variables de un programa se pierden cuando este termina; un archivo mantiene los datos entre ejecuciones. Abra el archivo con un modo, utilícelo y luego ciérrelo.
Modo
Significado
Si el archivo existe
"r"
lectura
leer desde el inicio
"w"
escritura
vacío primero
"a"
agregado
añadir al final
El modo "w" destruye lo que había; el modo "a" lo conserva
with open("scores.txt", "a") as f:
f.write("Ada,91\n")
best_name, best = "", -1
with open("scores.txt", "r") as f:
for line in f:
name, score = line.strip().split(",")
if int(score) > best:
best_name, best = name, int(score)
print(best_name, best)
with cierra el archivo automáticamente, incluso si ocurre una excepción.
Cada línea leída termina en "\n"; strip() lo elimina antes de que split(",") divida la línea en campos.
Abrir un archivo faltante para lectura genera FileNotFoundError: cáptelo con try … except.
Indique el tipo de dato más adecuado para cada uno: (a) el número de estudiantes en una clase; (b) si una puerta está cerrada; (c) un código postal como "SW1A 1AA"; (d) una temperatura de 21.5 °C.
s = "Programming". Proporcione (a) len(s); (b) s[3:7]; (c) s.find("g").
Clasifique cada error como sintaxis, tiempo de ejecución o lógica: (a) print("Hi"; (b) un bucle que suma un elemento de menos; (c) int("abc").
Complete una tabla de trazado para x = 1 luego while x < 20: x = x * 3, e indique el valor final de x.
Los elementos 10, 20 y 30 se apilan sobre una pila vacía, luego se elimina un elemento y se empuja 40. Indique el elemento en la cima.
Los mismos elementos se procesan mediante una cola: encolar 10, 20, 30, desencolar una vez, encolar 40. Indique el elemento en la parte delantera.
Para la lista [3, 8, 12, 19, 25, 31, 40], liste los valores con los que una búsqueda binaria para 31 compara.
Muestre la lista [6, 3, 8, 2] después de cada pasada de un ordenamiento burbuja.
Escribe una función en Python count_over(marks, limit) que devuelva cuántos elementos de la lista son mayores que limit.
Explica por qué abrir "log.txt" con modo "w" cada vez que se inicia un programa provoca pérdida de datos, y menciona la solución.
Respuestas.
(a) entero; (b) booleano; (c) cadena, ya que contiene letras y espacios; (d) real.
(a) 11; (b) "gram"; (c) 3.
(a) sintaxis: un paréntesis faltante; (b) lógica; (c) tiempo de ejecución: un ValueError.
x toma los valores 1, 3, 9, 27; el bucle se detiene cuando x es 27. Valor final 27.
low 0, high 6: mid 3, valor 19 < 31, por lo tanto low = 4; mid$(4 + 6) // 2 = 5$, valor 31: encontrado. Comparado con 19 y 31.
Pasa 1: [3, 6, 2, 8]; pasa 2: [3, 2, 6, 8]; pasa 3: [2, 3, 6, 8].
Una respuesta:
def count_over(marks, limit):
count = 0
for m in marks:
if m > limit:
count = count + 1
return count
El modo "w" vacía un archivo existente antes de escribir, perdiendo así el registro anterior. Ábrelo con "a" para añadir.
power(2, 5) se llama a sí mismo con e = 4, 3, 2, 1, 0: 6 llamadas, devolviendo $2^5 =$32.
Se llama a sí mismo indefinidamente; cada llamada añade un marco a la pila de llamadas hasta que se agota la memoria, un desbordamiento de pila (en Python un RecursionError).
6.8
Consejos para el examen
En una tabla de trazado, proporcione una nueva fila cada vez que cambie una variable y muestre la salida por separado. Verifique dónde se detiene range.
Indique la convención de indexación (Python usa índices desde 0) antes de trazar una matriz o una búsqueda.
Para una respuesta de búsqueda binaria, indique que la lista debe estar ordenada y proporcione low, high y mid en cada comprobación.
La ordenación burbuja y la ordenación por selección son ambas $O(n^2)$: compárelas mediante intercambios, parada anticipada y pasadas, no mediante Big O.
"Explique" una pila o cola según su orden (LIFO o FIFO), sus dos operaciones y un uso real.
Al escribir código, utilice nombres claros, cierre los archivos con with y maneje la entrada incorrecta con try … except.
Más temas en Diploma del Bachillerato Internacional · IB Diploma · Computer Science · SL