Notas Clase 01

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 5

CAPÍTULO 1

Conceptos Generales

Una computadora hace dos cosas, y sólo dos cosas: realiza cálculos y recuerda los resultados de esos cálculos. Pero hace
esas dos cosas extremadamente bien. Una computadora típica de escritorio realiza unos 100 mil millones de cálculos
por segundo.
Durante la mayor parte de la historia humana, la computación estuvo limitada por la rapidez con la que el cerebro
humano podía calcular y la precisión con la que la mano humana podía registrar los resultados computacionales. Esto
significaba que solo los problemas más pequeños podían ser atacados computacionalmente. Incluso con la velocidad
de las computadoras modernas, algunos problemas aún están más allá de los modelos computacionales modernos (por
ejemplo, comprender completamente el cambio climático), pero cada vez más problemas se están pudiendo resolver a
traves de una de solución computacional.
La idea de este curso es que cuando lo termines, te sientas cómodo utilizando el pensamiento computacional para
resolver muchos de los problemas que encuentre durante tus estudios, trabajo e incluso la vida cotidiana.

1.1 Pensamiento computacional

Todo conocimiento puede considerarse como declarativo o imperativo. El conocimiento declarativo se compone de
enunciados de hecho. Por ejemplo, «la raíz cuadrada de x es un número y tal que y*y =x», y «es posible viajar en tren
de París a Roma». Estas son declaraciones de hecho. Desafortunadamente, no nos dicen nada sobre cómo encontrar
una raíz cuadrada o cómo tomar trenes de París a Roma.
El conocimiento imperativo es el conocimiento de «cómo hacer», o recetas para deducir información. Heron of Ale-
xandria fue el primero en documentar una forma de calcular la raíz cuadrada de un número. Su método para encontrar
la raíz cuadrada de un número x, se puede resumir así:
1. Comience con una conjetura, g.
2. Si g*g está lo suficientemente cerca de x, deténgase y diga que g es la respuesta.
3. De lo contrario, cree una nueva suposición promediando g y x/g, es decir, (g + x/g)/2.
4. Usando esta nueva conjetura, que nuevamente llamamos g, repita el proceso hasta que g*g esté lo suficientemente
cerca de x.

1
Notas de Programacion

Considera encontrar la raíz cuadrada de 25.


1. Establezca g en algún valor arbitrario, por ejemplo, 3.
2. Decidimos que 3*3 = 9 no se acerca lo suficiente a 25.
3. Establecer g en (3 + 25/3)/2 = 5.67.
4. Decidimos que 5.67*5.67 = 32.15 aún no se acerca lo suficiente a 25.
5. Establezca g en (5.67 + 25/5.67)/2 = 5.04
6. Decidimos que 5.04*5.04 = 25.4 está lo suficientemente cerca, así que nos detenemos y declaramos que 5.04
es una aproximación adecuada a la raíz cuadrada de 25.
Tenga en cuenta que la descripción del método es una secuencia de pasos simples, junto con un flujo de control que
especifica cuándo ejecutar cada paso. Tal descripción se llama algoritmo. El algoritmo que usamos para aproximar la
raíz cuadrada es un ejemplo de un algoritmo de conjeturar y comprobar. Se basa en el hecho de que es fácil verificar si
una conjetura es lo suficientemente buena o no.

1.2 Algoritmo

Más formalmente, un algoritmo es una lista finita de instrucciones que describen un conjunto de cálculos que, cuando
se ejecutan en un conjunto de entradas, continuarán a través de una secuencia de estados bien definidos y eventualmente
producirán una salida.
Un algoritmo es como una receta de un libro de cocina. Entonces, ¿cómo se captura la idea de una receta en un proceso
mecánico? Una forma es diseñar una máquina específicamente para calcular raíces cuadradas. Por extraño que parez-
ca, las primeras máquinas informáticas eran, de hecho, computadoras de programa fijo, lo que significa que estaban
diseñadas para resolver un problema matemático específico, por ejemplo, para calcular la trayectoria de un proyectil
de artillería. Una de las primeras computadoras (construida en 1941 por Atanasoff y Berry) resolvía sistemas de ecua-
ciones lineales, pero no podía hacer nada más. La máquina bombe de Alan Turing, desarrollada durante la Segunda
Guerra Mundial, fue diseñada para descifrar los códigos Enigma alemanes. Algunas computadoras simples todavía
usan este enfoque. Por ejemplo, una calculadora de cuatro funciones es una computadora de programa fijo. Puede ha-
cer operaciones aritméticas básicas, pero no se puede usar como un procesador de textos o para ejecutar videojuegos.
Para cambiar el programa de tal máquina, uno tiene que reemplazar el circuito.
La primera computadora verdaderamente moderna fue la Manchester Mark 1. Se distinguía de sus predecesoras por ser
una computadora con programa almacenado. Tal computadora almacena (y manipula) una secuencia de instrucciones
y tiene componentes que ejecutan cualquier instrucción en esa secuencia. El corazón de una computadora de este tipo
es un intérprete que puede ejecutar cualquier instrucción de un conjunto de instrucciones dado y, por lo tanto, puede
usarse para calcular cualquier cosa que pueda describirse usando esas instrucciones. El resultado del cálculo puede
ser incluso una nueva secuencia de instrucciones, que luego puede ejecutar la computadora que las generó. En otras
palabras, es posible que una computadora se programe a sí misma.
Tanto el programa como los datos que manipula residen en la memoria.
Por lo general, un contador de programa apunta a una ubicación particular en la memoria y el cálculo comienza ejecu-
tando la instrucción en ese punto. La mayoría de las veces, el intérprete simplemente pasa a la siguiente instrucción de
la secuencia, pero no siempre. En algunos casos, realiza una prueba y, sobre la base de esa prueba, la ejecución puede
saltar a otro punto en la secuencia de instrucciones. Esto se llama flujo de control y es esencial para permitirnos escribir
programas que realicen tareas complejas.
Las personas a veces usan diagramas de flujo para representar el flujo de control. Por convención, usamos cuadros
rectangulares para representar un paso de procesamiento, un diamante para representar una prueba y flechas para
indicar el orden en que se hacen las cosas. La figura contiene un diagrama de flujo que representa un clásico bucle
for de C.

2 Capítulo 1. Conceptos Generales


Notas de Programacion

1.3 Lenguajes de programación

Para crear recetas, o secuencias de instrucciones, necesitamos un lenguaje de programación en el que describirlas, una
forma de darle a la computadora sus órdenes de funcionamiento.
En 1936, el matemático británico Alan Turing describió un dispositivo informático hipotético que se ha dado en llamar
Máquina Universal de Turing. La máquina tenía una memoria ilimitada en forma de «cinta» en la que se podían escribir
ceros y unos, y un puñado de instrucciones primitivas simples para mover, leer y escribir en la cinta. La tesis de Church-
Turing establece que si una función es computable, se puede programar una máquina de Turing para calcularla.
El “si” en la tesis de Church-Turing es importante. No todos los problemas tienen soluciones computacionales. Turing
demostró, por ejemplo, que es imposible escribir un programa que tome un programa arbitrario como entrada, e imprima
verdadero si y solo si el programa de entrada se ejecutará para siempre. Esto se conoce como el problema de la detención.
La tesis de Church-Turing conduce directamente a la noción de completitud de Turing. Se dice que un lenguaje de
programación es Turing completo si se puede usar para simular una máquina universal de Turing . Todos los lenguajes
de programación modernos son Turing completos. Como consecuencia, cualquier cosa que pueda programarse en un
lenguaje de programación (p. ej., Python) puede programarse en cualquier otro lenguaje de programación (p. ej., Java).
Por supuesto, algunas cosas pueden ser más fáciles de programar en un lenguaje en particular, pero todos los lenguajes
son fundamentalmente iguales con respecto al poder computacional.
Afortunadamente, ningún programador tiene que construir programas a partir de las instrucciones primitivas de Turing.
En cambio, los lenguajes de programación modernos ofrecen un conjunto de primitivas más grande y conveniente. Sin
embargo, la idea fundamental de la programación como el proceso de ensamblar una secuencia de operaciones sigue
siendo central.
Cualquiera que sea el conjunto de primitivas que tenga y los métodos que tenga para ensamblarlas, lo mejor y lo peor
de la programación son lo mismo: la computadora hará exactamente lo que se le dice que haga, nada más, nada menos.
Esto es bueno porque significa que puede hacer que la computadora haga todo tipo de cosas divertidas y útiles. Es algo
malo porque cuando no hace lo que quieres que haga, normalmente no tienes a nadie a quien culpar sino a vos mismo.
Hay cientos de lenguajes de programación en el mundo. No existe la idea de el «mejor lenguaje». Diferentes lenguajes

1.3. Lenguajes de programación 3


Notas de Programacion

son mejores o peores para diferentes tipos de aplicaciones. MATLAB, por ejemplo, es un buen 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. Python es un excelente lenguaje de propósito general.
Cada lenguaje de programación tiene un conjunto de construcciones primitivas, una sintaxis, una semántica estática
y una semántica. Por analogía con un lenguaje natural, por ejemplo, el español, las construcciones primitivas son
palabras, la sintaxis describe qué cadenas de palabras constituyen oraciones bien formadas, la semántica estática define
qué oraciones tienen significado y la semántica define el significado de esas oraciones. Las construcciones primitivas
en Python incluyen literales (p. ej., el número 3.2 y la cadena 'abc') y operadores infijos (p. ej., + y /).
La sintaxis de un lenguaje define qué cadenas de caracteres y símbolos están bien formadas. Por ejemplo, en español la
cadena «Gato perro niño.» no es una oración sintácticamente válida, porque la sintaxis del español no acepta oracio-
nes de la forma <sustantivo> <sustantivo> <sustantivo>. En Python, la secuencia de primitivas 3.2 + 3.2 está bien
formada sintácticamente, pero la secuencia 3.2 3.2 no lo está.
La semántica estática define qué cadenas sintácticamente válidas tienen un significado. Considere, por ejemplo, las
cadenas «el correr rápido» y “yo correr rápido”. Cada una tiene la forma <pronombre> <verbo regular> <adverbio>,
que es una secuencia sintácticamente aceptable. Sin embargo, ninguna de estas es válida en español, debido a la regla
que dice que el verbo infinitivo tomo una forma diferente según la persona que lo precede. Estos son ejemplos de errores
semánticos estáticos.
La semántica de un lenguaje asocia un significado con cada cadena de símbolos sintácticamente correcta que no tiene
errores semánticos estáticos. En lenguajes naturales, la semántica de una oración puede ser ambigua. Por ejemplo,
la oración «No puedo elogiar demasiado a este estudiante», puede ser halagador o condenatorio. Los lenguajes de
programación están diseñados para que cada programa legal tenga exactamente un significado.
Aunque los errores de sintaxis son el tipo de error más común (especialmente para aquellos que están aprendiendo un
nuevo lenguaje de programación), son el tipo de error menos peligroso. Todos los lenguajes de programación serios
detectan todos los errores sintácticos y no permiten a los usuarios ejecutar un programa con un solo error sintáctico.
Además, en la mayoría de los casos, el sistema de lenguaje proporciona una indicación suficientemente clara de la
ubicación del error para que el programador pueda solucionarlo sin pensar demasiado.
Identificar y resolver errores semánticos estáticos es más complejo. Algunos lenguajes de programación, por ejemplo,
Java, realizan muchas comprobaciones de semántica estática antes de permitir que se ejecute un programa. Otros, por
ejemplo, C y Python, realizan relativamente menos verificación de semántica estática antes de ejecutar un programa.
Python hace una cantidad considerable de verificación semántica mientras ejecuta un programa.
Si un programa no tiene errores sintácticos ni errores semánticos estáticos, tiene un significado, es decir, tiene se-
mántica. Por supuesto, puede que no tenga la semántica que pretendía su creador. Cuando un programa significa algo
diferente de lo que su creador cree que significa, pueden suceder cosas malas.
¿Qué podría pasar si el programa tiene un error y se comporta de forma no deseada?
Podría «crashearse», es decir, dejar de ejecutarse y producir una indicación obvia de que lo ha hecho. En un
sistema informático correctamente diseñado, cuando un programa falla, no daña el sistema en general. Por des-
gracia, algunos sistemas informáticos muy populares no tienen esta propiedad agradable. Casi todos los que
hemos usado una computadora personal hemos corrido algún programa que nos ha hecho tener que reiniciar
todo el sistema.
Podría seguir funcionando, y funcionando, y funcionando, y nunca detenerse. Si no tiene idea de cuánto tiempo
se supone que el programa tardará aproximadamente en hacer su trabajo, esta situación puede ser difícil de
reconocer.
Puede ejecutarse hasta el final y producir una respuesta que podría ser correcta o no.
Cada uno de estos resultados es malo, pero el último es sin duda el peor. Cuando un programa parece estar haciendo
lo correcto pero no lo hace, pueden ocurrir cosas malas: se pueden perder fortunas, los pacientes pueden recibir dosis
fatales de radioterapia, los aviones pueden estrellarse.

4 Capítulo 1. Conceptos Generales


Notas de Programacion

Siempre que sea posible, los programas deben escribirse de modo que cuando no funcionen correctamente, sea evidente.
Discutiremos cómo hacer esto a lo largo del curso.

1.4 Términos introducidos en el capítulo

conocimiento declarativo
conocimiento imperativo
algoritmo
cálculo/computo
computadora de programa fijo
computadora de programa almacenado
intérprete
contador de programa
flujo de control
diagrama de flujo
lenguaje de programación
literales
operadores infijos
sintaxis
semántica estática
semántica

1.4. Términos introducidos en el capítulo 5

También podría gustarte

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy