Notas de Programación para Ingenierı́a
Índice general
1. Introducción a la Computación 3
1.1. Funciones de la Computadora . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2. Pensamiento Computacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3. Computadoras de Programa Almacenado . . . . . . . . . . . . . . . . . . . . . . 4
1.4. Lenguajes de Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Algoritmos 6
2.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2. ¿Cómo funcionan los algoritmos? . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3. Tipos de Algorimos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4. Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5. Fases para crear un Algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6. Caracterı́sticas de un Algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3. Diagramas de Flujo 11
3.0.1. Diagramas de flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.0.2. Pseudocódigos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2
1 Introducción a la Computación
1.1. Funciones de la Computadora
Una computadora realiza dos funciones principales: realiza cálculos y almacena los re-
sultados de esos cálculos. Estas tareas las lleva a cabo de manera extremadamente eficiente.
Una computadora tı́pica puede realizar miles de millones de cálculos por segundo y almacenar
cientos de gigabytes de datos.
Históricamente, el cálculo estaba limitado por la velocidad del cerebro humano y la capa-
cidad de registrar los resultados manualmente, lo que restringı́a los problemas que se podı́an
resolver. Hoy en dı́a, aunque hay problemas que aún no pueden resolverse computacionalmente,
cada vez más problemas encuentran solución a través de la computación.
1.2. Pensamiento Computacional
El pensamiento computacional puede dividirse en conocimiento declarativo (hechos) y co-
nocimiento imperativo (cómo hacer algo). Los algoritmos, que son secuencias finitas de instruc-
ciones, permiten resolver problemas mediante el procesamiento de entradas y la generación de
salidas.
El conocimiento declarativo se compone de declaraciones de hecho. Por ejemplo, ”la raı́z
cuadrada de x es un número y tal que y*y = x..Esta es una declaración de hecho. Desafortuna-
damente, no nos dice
El conocimiento imperativo es el conocimiento de çómo hacer”, o recetas para deducir
información. Herón de Alejandrı́a fue el primero en documentar un método para calcular la raı́z
cuadrada de un número. Su método se puede resumir de la siguiente manera:
Empieza con una suposición, g.
Si gg está lo suficientemente cerca de x, detente y di que g es la respuesta.
De lo contrario, crea una nueva suposición promediando g y x/g, es decir, (g + x/g)/2.
Usando esta nueva suposición, que de nuevo llamamos g, repite el proceso hasta que gg
esté lo suficientemente cerca de x.
3
4 1 Introducción a la Computación
1.3. Computadoras de Programa Almacenado
Las primeras computadoras eran máquinas de programa fijo, diseñadas para realizar tareas
especı́ficas. La primera computadora moderna, la Manchester Mark 1, fue una máquina de
programa almacenado, lo que significa que podı́a almacenar y manipular una secuencia de
instrucciones (un programa) en su memoria. Esto la hizo extremadamente flexible y capaz de
ejecutar cualquier conjunto de instrucciones legales.
1.4. Lenguajes de Programación
Para crear programas, es necesario un lenguaje de programación que permita describir
secuencias de instrucciones. Un lenguaje de programación moderno ofrece un conjunto de pri-
mitivas más amplio y conveniente que las instrucciones primitivas de Turing. Un lenguaje de
programación se considera Turing completo si puede simular una Máquina Universal de Turing,
es decir, si puede usarse para calcular cualquier función computable.
Todos los lenguajes de programación modernos son Turing completos, lo que significa que
cualquier cosa que se pueda programar en un lenguaje, se puede programar en otro, aunque
algunas tareas puedan ser más fáciles en ciertos lenguajes.
Afortunadamente, ningún programador tiene que construir programas a partir de las ins-
trucciones primitivas de Turing. En cambio, los lenguajes de programación modernos ofrecen
un conjunto de primitivas más amplio y conveniente. Sin embargo, la idea fundamental de la
programación como el proceso de ensamblar una secuencia de operaciones sigue siendo central.
Cualquiera sea el conjunto de primitivas que se tenga, y cualquiera sean los métodos que se
tengan para usarlas, lo mejor y lo peor de la programación son lo mismo: la computadora hará
exactamente lo que le digas que haga. Esto es algo bueno porque significa que puedes hacer que
haga todo tipo de cosas divertidas y útiles. Es algo malo porque cuando no hace lo que quieres
que haga, por lo general no puedes culpar a nadie más que a ti mismo.
Existen cientos de lenguajes de programación en el mundo. No hay un lenguaje mejor
(aunque se podrı́a nominar a algunos candidatos como los peores). Diferentes lenguajes son
mejores o peores para diferentes tipos de aplicaciones. MATLAB, por ejemplo, es un excelente
lenguaje para manipular vectores y matrices. C es un buen lenguaje para escribir programas
que controlan redes de datos. PHP es un buen lenguaje para construir sitios web. Y Python es
un buen lenguaje de propósito general.
Cada lenguaje de programación tiene un conjunto de construcciones primitivas, una sinta-
xis, una semántica estática y una semántica. Por analogı́a con un lenguaje natural, como el
inglés, las construcciones primitivas son palabras, la sintaxis describe qué cadenas de palabras
constituyen oraciones bien formadas, la semántica estática define qué oraciones son significa-
tivas, y la semántica define el significado de esas oraciones. Las construcciones primitivas en
Python incluyen literales (por ejemplo, el número 3.2 y la cadena ’abc’) y operadores infijos
(por ejemplo, + y /).
La sintaxis de un lenguaje define qué cadenas de caracteres y sı́mbolos están bien formadas.
1.4 Lenguajes de Programación 5
Por ejemplo, en inglés la cadena “Cat dog boy.” no es una oración sintácticamente válida, porque
la sintaxis del inglés no acepta oraciones de la forma ¡sustantivo¿¡sustantivo¿¡sustantivo¿. En
Python, la secuencia de primitivas 3.2 + 3.2 está sintácticamente bien formada, pero la secuencia
3.2 3.2 no lo está.
La semántica estática define qué cadenas sintácticamente válidas tienen un significa-
do. En inglés, por ejemplo, la cadena “I are big,” tiene la forma ¡pronombre¿¡verbo de enla-
ce¿¡adjetivo¿, que es una secuencia sintácticamente aceptable. Sin embargo, no es un inglés
válido, porque el pronombre “I” es singular y el verbo “are” es plural. Esto es un ejemplo de un
error semántico estático. En Python, la secuencia 3.2/’abc’ está sintácticamente bien formada
(¡literal¿¡operador¿¡literal¿), pero produce un error semántico estático ya que no tiene sentido
dividir un número por una cadena de caracteres.
La semántica de un lenguaje asocia un significado con cada cadena de sı́mbolos sintácti-
camente correcta que no tenga errores semánticos estáticos. En los lenguajes naturales, la
semántica de una oración puede ser ambigua. Por ejemplo, la oración “I cannot praise this
student too highly,” puede ser tanto un elogio como una crı́tica. Los lenguajes de programación
están diseñados de manera que cada programa legal tenga exactamente un significado.
Aunque los errores de sintaxis son el tipo más común de error (especialmente para aque-
llos que están aprendiendo un nuevo lenguaje de programación), son el tipo de error menos
peligroso. Todos los lenguajes de programación serios hacen un trabajo completo al detectar
errores sintácticos y no permiten a los usuarios ejecutar un programa con incluso un solo error
sintáctico. Además, en la mayorı́a de los casos, el sistema del lenguaje proporciona una indica-
ción suficientemente clara de la ubicación del error, por lo que es obvio lo que se debe hacer
para corregirlo.
La situación con respecto a los errores semánticos estáticos es un poco más compleja. Al-
gunos lenguajes de programación, como Java, realizan una gran cantidad de comprobaciones
semánticas estáticas antes de permitir que un programa se ejecute. Otros, como C y Python
(lamentablemente), hacen relativamente menos comprobaciones semánticas estáticas. Python
realiza una cantidad considerable de comprobaciones semánticas estáticas mientras ejecuta un
programa. Sin embargo, no detecta todos los errores semánticos estáticos. Cuando estos errores
no se detectan, el comportamiento de un programa a menudo es impredecible. Veremos ejemplos
de esto más adelante en el libro.
No se suele hablar de un programa como si tuviera un error semántico. Si un programa
no tiene errores sintácticos ni errores semánticos estáticos, tiene un significado, es decir, tiene
semántica. Por supuesto, eso no significa que tenga la semántica que su creador pretendı́a que
tuviera. Cuando un programa significa algo diferente de lo que su creador piensa que significa,
pueden ocurrir cosas malas.
2 Algoritmos
2.1. Introducción
Un algoritmo es un procedimiento utilizado para resolver un problema o realizar un cálcu-
lo. Los algoritmos actúan como una lista exacta de instrucciones que llevan a cabo acciones
especı́ficas paso a paso en rutinas basadas en hardware o software.
Los algoritmos se utilizan ampliamente en todas las áreas de TI. En matemáticas, programa-
ción de computadoras y ciencias de la computación, un algoritmo generalmente se refiere a un
pequeño procedimiento que resuelve un problema recurrente. Los algoritmos también se utilizan
como especificaciones para realizar el procesamiento de datos y juegan un papel importante en
los sistemas automatizados.
Un algoritmo puede utilizarse para ordenar conjuntos de números o para tareas más compli-
cadas, como recomendar contenido a los usuarios en redes sociales. Los algoritmos generalmente
comienzan con una entrada inicial y con instrucciones que describen un cálculo especı́fico. Cuan-
do se ejecuta el cálculo, el proceso produce una salida.
2.2. ¿Cómo funcionan los algoritmos?
Los algoritmos funcionan siguiendo un conjunto de instrucciones o reglas para completar
una tarea o resolver un problema. Pueden expresarse en lenguajes naturales, lenguajes de
programación, pseudocódigo, diagramas de flujo y tablas de control. Las expresiones en lenguaje
natural son raras, ya que son más ambiguas. Los lenguajes de programación son normalmente
utilizados para expresar algoritmos ejecutados por una computadora.
Los algoritmos utilizan una entrada inicial junto con un conjunto de instrucciones. La entra-
da es la información inicial necesaria para tomar decisiones y puede representarse en forma de
números o palabras. Los datos de entrada se procesan mediante un conjunto de instrucciones o
cálculos, que pueden incluir procesos aritméticos y de toma de decisiones. La salida es el último
paso en un algoritmo y normalmente se expresa como más datos.
Por ejemplo, un algoritmo de búsqueda toma una consulta de búsqueda como entrada y la
ejecuta a través de un conjunto de instrucciones para buscar en una base de datos elementos
relevantes para la consulta. El software de automatización es otro ejemplo de algoritmos, ya
que la automatización sigue un conjunto de reglas para completar tareas. Muchos algoritmos
6
2.3 Tipos de Algorimos 7
componen el software de automatización, y todos trabajan para automatizar un proceso dado.
2.3. Tipos de Algorimos
Algoritmo de motor de búsqueda: Este algoritmo toma cadenas de búsqueda de pala-
bras clave y operadores como entrada, busca en su base de datos asociada páginas web relevantes
y devuelve resultados.
Algoritmo de cifrado: Este algoritmo de computación transforma datos de acuerdo con
acciones especificadas para protegerlos. Un algoritmo de clave simétrica, como el Estándar
de Cifrado de Datos, por ejemplo, utiliza la misma clave para cifrar y descifrar datos. Si el
algoritmo es lo suficientemente sofisticado, nadie sin la clave puede descifrar los datos.
Algoritmo codicioso: Este algoritmo resuelve problemas de optimización al encontrar la
solución localmente óptima, esperando que sea la solución óptima a nivel global. Sin embargo,
no garantiza la solución más óptima.
Algoritmo recursivo: Este algoritmo se llama a sı́ mismo repetidamente hasta que resuelve
un problema. Los algoritmos recursivos se llaman a sı́ mismos con un valor más pequeño cada
vez que se invoca una función recursiva.
Algoritmo de retroceso: Este algoritmo encuentra una solución a un problema dado
mediante enfoques incrementales y lo resuelve pieza por pieza.
Algoritmo de divide y vencerás: Este algoritmo común se divide en dos partes. Una
parte divide un problema en subproblemas más pequeños. La segunda parte resuelve estos
problemas y luego los combina para producir una solución.
Algoritmo de programación dinámica: Este algoritmo resuelve problemas dividiéndolos
en subproblemas. Los resultados se almacenan para ser aplicados a problemas correspondientes
futuros.
Algoritmo de fuerza bruta: Este algoritmo itera todas las posibles soluciones a un pro-
blema de manera ciega, buscando una o más soluciones a una función.
Algoritmo de clasificación: Los algoritmos de clasificación se utilizan para reorganizar
estructuras de datos basadas en un operador de comparación, que se utiliza para decidir un
nuevo orden para los datos.
Algoritmo de hashing: Este algoritmo toma datos y los convierte en un mensaje uniforme
mediante un hashing.
Un valor hash es un valor numérico de longitud fija que identifica datos de forma única.
Los valores hash se obtienen aplicando un algoritmo a una cadena de entrada. El algoritmo
descompone conjuntos de datos originales de diferentes longitudes en cadenas fijas.
Algoritmo aleatorio: Este algoritmo reduce los tiempos de ejecución y las complejidades
basadas en el tiempo. Utiliza elementos aleatorios como parte de su lógica. ¿Cuáles son algunos
ejemplos de algoritmos?
8 2 Algoritmos
El aprendizaje automático es un buen ejemplo de un algoritmo, ya que utiliza múlti-
ples algoritmos para predecir resultados sin ser programado explı́citamente para hacerlo. El
aprendizaje automático utiliza aprendizaje supervisado o no supervisado.
En el aprendizaje supervisado, los cientı́ficos de datos proporcionan algoritmos comple-
jos con datos de entrenamiento etiquetados y definen las variables que desean que el algoritmo
evalúe en busca de correlaciones. Tanto la entrada como la salida del algoritmo están especifi-
cadas.
El aprendizaje automático no supervisado implica algoritmos que entrenan con datos
no etiquetados y los examinan en busca de patrones que se pueden utilizar para agrupar puntos
de datos en subconjuntos. La mayorı́a de los tipos de aprendizaje profundo, incluidos las redes
neuronales, son algoritmos no supervisados.
El aprendizaje automático utilizado en inteligencia artificial también se basa en algoritmos.
Sin embargo, los sistemas basados en aprendizaje automático pueden tener sesgos inherentes
en los datos que alimentan el algoritmo de aprendizaje automático. Esto podrı́a resultar en
sistemas que son poco confiables y potencialmente dañinos.
2.4. Aplicaciones
Aunque los algoritmos se utilizan extensamente en informática, inteligencia artificial y es-
cenarios de aprendizaje automático, también se emplean frecuentemente en la vida cotidiana.
A continuación, se presentan algunos ejemplos de algoritmos utilizados en la vida real:
Seguir una receta. Las recetas proporcionan una serie de pasos para lograr un objetivo
particular, como preparar muffins de arándano o hacer salsa de espagueti desde cero. Las
recetas buscan producir resultados consistentes y ayudan a las personas, independiente-
mente de su origen, a crear un plato especı́fico siguiendo instrucciones detalladas. De esta
manera, las recetas reflejan los algoritmos de la informática, que delinean los pasos para
generar resultados reproducibles.
Atar los cordones de los zapatos. Atar los cordones de los zapatos es otro ejemplo
de seguir un algoritmo. Por ejemplo, hay un número finito de pasos que conducen a un
nudo tradicional correctamente atado, que a menudo se conoce como el nudo del çonejo.o
”bucle, paso y tira”.
Reconocimiento facial. El reconocimiento facial se utiliza ampliamente en los inicios
de sesión de iPhone, ası́ como en filtros de Snapchat e Instagram. Funciona proyectando
rasgos faciales desde una foto o video en un mapa biométrico utilizando un algoritmo. El
programa luego busca una coincidencia entre este mapa y una base de datos de rostros
para confirmar la identificación del usuario. Si el reconocimiento facial se utiliza para
filtros de Snapchat o Instagram, no es necesario buscar en la base de datos porque el
algoritmo simplemente construye un mapa del rostro y aplica el filtro a él.
Semáforos. Los semáforos utilizan algoritmos inteligentes para gestionar el flujo de tráfi-
co. Estos algoritmos agrupan diferentes movimientos, como ir recto o girar a la derecha,
2.5 Fases para crear un Algoritmo 9
en fases, lo que ayuda a garantizar la seguridad y la eficiencia. Por ejemplo, cuando un
automovilista se acerca a un semáforo en rojo, el semáforo está ciclando a través de estas
fases. Al evaluar el volumen de tráfico, un algoritmo decide cuándo es seguro para el
vehı́culo avanzar.
Clasificación de documentos y papeles. Este es un gran ejemplo de cómo los algorit-
mos pueden usarse para diversas tareas y propósitos, como clasificar archivos alfabética-
mente, por recuento de palabras, por fecha, o por cualquier otra especificación. Cuando
alguien organiza sus documentos personales o profesionales de acuerdo con un conjunto
de instrucciones, está aplicando el pensamiento algorı́tmico para simplificar el proceso de
organización mediante el uso de pequeñas tareas.
Buscar un libro en la biblioteca. Encontrar un libro en la biblioteca es como seguir
un algoritmo o un plan paso a paso. Por ejemplo, hay diferentes maneras de hacerlo,
como usar el sistema informático de la biblioteca o buscar etiquetas en los estantes que
muestran el género, el tema o el autor del libro. No importa qué método se elija, si puede
ser explicado y hecho por otros, entonces se puede clasificar como un algoritmo.
2.5. Fases para crear un Algoritmo
Análisis del Problema Consiste en conocer perfectamente en qué consiste y qué resultados
se desean obtener.
Planificación de la Resolución Dividiéndolo, si es complicado, en una secuencia de etapas
más simples. Esta fase se lleva a cabo en un papel, estableciendo lo más claramente posible la
finalidad de cada etapa, los datos que se necesitan de entrada, los datos que se producirı́an en
salida, los algoritmos (ver la Sección 5.2) que se utilizarán, etc.
Edición del Código Fuente Es decir, escritura del mismo utilizando un editor de textos
simple (sin formato) y un lenguaje de programación. Los programas fuente serán almacenados
en ficheros de texto, normalmente en el disco duro del ordenador.
Compilación y Ejecución
Corrección de Errores Los errores se corregirán en el código fuente, repitiendo los pasos
3 y 4 tantas veces como sea necesario. Si se producen errores en la lógica del programa, es decir,
si el programa “funciona” pero produce resultados incorrectos, hay que modificar el algoritmo
volviendo al paso 2. Estos errores son los más difı́ciles de detectar.
Documentación Una vez que el programa funcione correctamente, es conveniente revisar
el código fuente para ordenarlo, eliminar cálculos innecesarios e incluir las lı́neas de comentario
necesarias, que normalmente deben incluir unas breves explicaciones al principio del código
sobre la finalidad del programa y sus argumentos de entrada y de salida.
10 2 Algoritmos
2.6. Caracterı́sticas de un Algoritmo
Un algoritmo es un método para resolver un problema mediante una secuencia de pasos
bien definidos, ordenados y finitos.
Para que se pueda ejecutar el algoritmo es preciso, además, que se disponga de las “herra-
mientas” adecuadas para llevar a cabo cada uno de los pasos. Si no es ası́, estos deberán, a su
vez, ser descompuestos en una secuencia (algoritmo) de pasos más simples que sı́ se puedan
llevar a cabo.
Un programa de ordenador es una sucesión de órdenes que describen un algoritmo, escritas
de forma que puedan ser entendidas por el ordenador.
En un algoritmo (y por tanto en un programa) se distinguen las siguientes acciones:
Entrada: es la información de partida que necesita el algoritmo para arrancar.
Proceso: es el conjunto de todas las operaciones a realizar.
Salida: son los resultados obtenidos.
Un ejemplo elemental es el Algoritmo 5.1.
Algoritmo 5.1 Preparar una taza de té.
Entrada: tetera, taza, bolsa de té
Salida: taza de té
Inicio
Tomar la tetera
Llenarla de agua
Encender el fuego
Poner la tetera en el fuego
Esperar a que hierva el agua
Tomar la bolsa de té
Introducirla en la tetera
Esperar 1 minuto
Echar el té en la taza
Fin
3 Diagramas de Flujo
Las dos herramientas más utilizadas comúnmente para describir algoritmos son:
3.0.1. Diagramas de flujo
Son representaciones gráficas de secuencias de pasos a realizar. Cada operación se representa
mediante un sı́mbolo normalizado por el Instituto Norteamericano de Normalización (ANSI -
American National Standards Institute). Las lı́neas de flujo indican el orden de ejecución.
Algunos de los sı́mbolos principales se muestran en la Figura 3.1.
Inicio / Fin
Input / Output
Input / Leer
No Sı́
Op2 Decisión Op1
Figura 3.1: Sı́mbolos en diagramas de flujo.
Los diagramas de flujo suelen ser usados sólo para representar algoritmos pequeños, ya que
abarcan mucho espacio.
3.0.2. Pseudocódigos
Describen un algoritmo de forma similar a un lenguaje de programación pero sin su rigidez,
de forma más parecida al lenguaje natural. Presentan la ventaja de ser más compactos que
los diagramas de flujo, más fáciles de escribir para las instrucciones complejas y más fáciles de
transferir a un lenguaje de programación. El pseudocódigo no está regido por ningún estándar.
11
12 3 Diagramas de Flujo
En estos apuntes usaremos las palabras LEER/IMPRIMIR para representar las acciones de
lectura de datos (el programa recibe datos desde algún sitio) y salida de datos (el programa
escribe información en algún medio).
El Algoritmo 1 y la Figura 3.2 muestran respectivamente el pseudocódigo y el diagrama
de flujo del algoritmo para calcular la altura de una persona en pulgadas y pies a partir de la
altura en centı́metros introducida por el teclado.
Algorithm 1 Calcular una altura en pulgadas (1 pulgada = 2.54 cm) y pies (1 pie = 12
pulgadas), a partir de la altura en centı́metros, que se introduce por el teclado.
Inicio
IMPRIMIR ’Introduce la altura en centimetros:’
LEER altura
CALCULAR pulgadas = altura / 2.54
CALCULAR pies = pulgadas / 12
IMPRIMIR ’La altura en pulgadas es: ’, pulgadas
IMPRIMIR ’La altura en pies es: ’, pies
Fin
Inicio
Leer altura
pulgadas=altura/2.54
pies=pulgadas/12
Imprimir pulgadas, pies
Fin
Figura 3.2: Diagrama de flujo para determinar la altura de una persona en pulgadas y pies a
partir de la altura en centı́metros introducida por el teclado.