Lección 0
Bienvenida
- Cuando David era un estudiante de primer año, se sentía muy intimidado para tomar algún curso de informática. Para cuando era estudiante de segundo año, encontró el coraje para tomar el equivalente de CS50, aunque solo para aprobar/reprobar.
- De hecho, dos tercios de los estudiantes de CS50 nunca han tomado un curso de informática antes.
-
E igual de importante también:
Lo que importa en última instancia en este curso no es tanto en dónde terminas en relación con tus compañeros de clase, sino en dónde terminas en relación con en dónde comenzaste
¿Qué es la informática?
- La informática es fundamentalmente la resolución de problemas.
- Podemos pensar en la resolución de problemas como el proceso de tomar algún dato de entrada (detalles acerca de nuestro problema) y generar algún dato de salida (la solución a nuestro problema). La "caja negra" en el medio es la informática.
- Necesitamos una forma de representar los datos de entrada, de manera que podamos almacenar y trabajar con información de una forma estándar.
Binario
- Una computadora, en el nivel más básico, almacena datos en binario, un sistema numérico en el que solo hay dos dígitos, 0 y 1.
- Cuando aprendimos a contar por primera vez, es posible que hayamos usado un dedo para representar una cosa. Ese sistema se conoce como unario. Cuando aprendimos a escribir números con los dígitos del 0 al 9, aprendimos a usar el decimal.
- Por ejemplo, sabemos que lo siguiente representa ciento veintitrés.
1 2 3
- El
3
está en la columna de las unidades, el2
está en la columna de las decenas y el1
está en la columna de las centenas. - Entonces,
123
es 100×1 + 10×2 + 1×3 = 100 + 20 + 3 = 123. -
Cada lugar para un dígito representa una potencia de diez, ya que hay diez dígitos posibles para cada lugar.
-
En binario, con solo dos dígitos, tenemos potencias de dos para cada valor posicional:
4 2 1 0 0 0
-
Este todavía sería igual a 0.
-
Ahora, si cambiamos el valor binario a, por ejemplo,
0 1 1
, el valor decimal sería 3.
4 2 1 0 1 1
- Si quisieramos representar 8, necesitaríamos otro dígito:
8 4 2 1 1 0 0 0
- Y el binario tiene sentido para las computadoras porque las alimentamos con electricidad, que puede estar encendida o apagada, por lo que cada bit solo necesita estar encendido o apagado. En una computadora, hay millones o miles de millones de interruptores llamados transistores que pueden almacenar electricidad y representar un bit al estar "encendidos" o "apagados".
- Con suficientes bits, o dígitos binarios, las computadoras pueden contar cualquier número.
- 8 bits conforman un byte.
Representación de datos
- Para representar letras, todo lo que necesitamos hacer es decidir cómo los números se relacionan con las letras. Algunas personas, hace muchos años, decidieron colectivamente una relación estándar llamada ASCII. La letra "A", por ejemplo, es el número 65, y "B" es 66, y así sucesivamente. La relación también incluye puntuación y otros símbolos. Otros caracteres, como las letras con tildes y los emojis, son parte de un estándar llamado Unicode que usa más bits que ASCII para acomodar todos estos caracteres.
- Cuando recibimos un emoji, nuestra computadora en realidad solo está recibiendo un número decimal como
128514
(11111011000000010
en binario, si te resulta más fácil leer eso) que luego relaciona con la imagen del emoji.
- Cuando recibimos un emoji, nuestra computadora en realidad solo está recibiendo un número decimal como
- Una imagen, también, está compuesta por muchos puntos cuadrados más pequeños, o píxeles, cada uno de los cuales puede representarse en binario con un sistema llamado RGB, con valores para luz roja, verde y azul en cada píxel. Al mezclar diferentes cantidades de cada color, podemos representar millones de colores:
- Los valores de rojo, verde y azul se combinan para obtener un color amarillo claro:
- Los valores de rojo, verde y azul se combinan para obtener un color amarillo claro:
- Podemos ver esto en un emoji si hacemos suficiente zoom:
- Y los programas de computadora saben, según el contexto de su código, si los números binarios deben interpretarse como números, o letras, o píxeles.
- Y los videos son solo muchas, muchas imágenes mostradas una tras otra, a una cierta cantidad de cuadros por segundo. La música, también, puede representarse mediante las notas que se están reproduciendo, su duración y su volumen.
Algoritmos
- Entonces podemos representar entradas y salidas. La caja negra anterior contendrá algoritmos, instructivos paso a paso para resolver un problema:
- Digamos que queremos encontrar a un amigo, Mike Smith, en una guía telefónica.
- Podríamos empezar revisando el libro, una página a la vez, hasta encontrar a Mike Smith o llegar al final del libro.
- También podríamos revisar dos páginas a la vez, pero si vamos demasiado lejos, tendremos que saber cómo regresar una página.
- Pero una forma incluso más eficiente sería abrir la guía telefónica en el medio, decidir si Mike estará en la mitad izquierda o derecha del libro (porque el libro está en orden alfabético) y descartar inmediatamente la mitad del problema. Podemos repetir esto, dividiendo el problema a la mitad cada vez. Con 1024 páginas para empezar, solo necesitaríamos 10 pasos de dividir a la mitad antes de que solo nos quede una página para revisar.
- De hecho, podemos representar la eficacia de cada uno de esos algoritmos con una gráfica:
- Nuestra primera solución, una página a la vez, es como la línea roja: nuestro tiempo para resolver aumenta linealmente a medida que aumenta el tamaño del problema.
- La segunda solución, dos páginas a la vez, es como la línea amarilla: nuestra pendiente es menos pronunciada, pero sigue siendo lineal.
- Nuestra solución final es como la línea verde: logarítmica, ya que nuestro tiempo para resolver aumenta cada vez más lentamente a medida que aumenta el tamaño del problema. En otras palabras, si la guía telefónica pasara de 1000 a 2000 páginas, necesitaríamos un paso más para encontrar a Mike. Si el tamaño se duplicara nuevamente de 2000 a 4000 páginas, todavía solo necesitaríamos un paso más.
Pseudocódigo
-
Podemos escribir pseudocódigo, una sintaxis informal que es sólo una versión más específica del inglés (u otro idioma humano) que representa nuestro algoritmo:
1 Toma la guía telefónica 2 Abre la guía telefónica por la mitad 3 Mira la página 4 Si Smith está en la página 5 Llama a Mike 6 De lo contrario, si Smith está antes en la guía 7 Abre la mitad izquierda de la guía por la mitad 8 Vuelve a la línea 3 9 De lo contrario, si Smith está más tarde en la guía 10 Abre la mitad derecha de la guía por la mitad 11 Vuelve a la línea 3 12 De lo contrario 13 Termina
-
Algunas de estas líneas comienzan con verbos o acciones. Comenzaremos a llamarlas funciones:
1 Toma la guía telefónica 2 Abre la guía telefónica por la mitad 3 Mira la página 4 Si Smith está en la página 5 Llama a Mike 6 De lo contrario, si Smith está antes en la guía 7 Abre la mitad izquierda de la guía por la mitad 8 Vuelve a la línea 3 9 De lo contrario, si Smith está más tarde en la guía 10 Abre la mitad derecha de la guía por la mitad 11 Vuelve a la línea 3 12 De lo contrario 13 Termina
- También tenemos ramas que conducen a caminos diferentes, como bifurcaciones en el camino, que llamaremos condiciones:
1 Toma la guía telefónica 2 Abre la guía telefónica por la mitad 3 Mira la página 4 Si Smith está en la página 5 Llama a Mike 6 De lo contrario, si Smith está antes en la guía 7 Abre la mitad izquierda de la guía por la mitad 8 Vuelve a la línea 3 9 De lo contrario, si Smith está más tarde en la guía 10 Abre la mitad derecha de la guía por la mitad 11 Vuelve a la línea 3 12 De lo contrario 13 Termina
- Y las preguntas que deciden a dónde vamos se llaman expresiones booleanas, que eventualmente resultan en un valor verdadero o falso:
1 Toma la guía telefónica 2 Abre la guía telefónica por la mitad 3 Mira la página 4 Si Smith está en la página 5 Llama a Mike 6 De lo contrario, si Smith está antes en la guía 7 Abre la mitad izquierda de la guía por la mitad 8 Vuelve a la línea 3 9 De lo contrario, si Smith está más tarde en la guía 10 Abre la mitad derecha de la guía por la mitad 11 Vuelve a la línea 3 12 De lo contrario 13 Termina
- Finalmente, tenemos palabras que conducen a ciclos, donde podemos repetir partes de nuestro programa, llamados bucles:
1 Toma la guía telefónica 2 Abre la guía telefónica por la mitad 3 Mira la página 4 Si Smith está en la página 5 Llama a Mike 6 De lo contrario, si Smith está antes en la guía 7 Abre la mitad izquierda de la guía por la mitad 8 Vuelve a la línea 3 9 De lo contrario, si Smith está más tarde en la guía 10 Abre la mitad derecha de la guía por la mitad 11 Vuelve a la línea 3 12 De lo contrario 13 Termina
Scratch
- Podemos escribir programas con los bloques de construcción que acabamos de descubrir:
- funciones
- condiciones
- expresiones booleanas
- bucles
- Utilizaremos un lenguaje de programación gráfico denominado Scratch, en el que arrastraremos y soltaremos bloques que contienen instrucciones.
- Más adelante en nuestro curso, pasaremos a lenguajes de programación de texto como C, Python y JavaScript. Todos estos lenguajes, incluido Scratch, tienen características más potentes, como:
- variables
- la capacidad de almacenar valores y cambiarlos
- subprocesos
- la capacidad para que nuestro programa haga varias cosas a la vez
- eventos
- la capacidad de responder a los cambios en nuestro programa o entradas
- …
- variables
- Así es el entorno de programación para Scratch:
- A la izquierda, tenemos piezas de rompecabezas que representan funciones o variables, u otros conceptos, que podemos arrastrar y soltar en nuestra área de instrucciones en el centro.
- A la derecha, tenemos un escenario que nuestro programa mostrará a un ser humano, donde podemos agregar o cambiar fondos, personajes (llamados sprites en Scratch) y más.
- Podemos arrastrar algunos bloques para hacer que Scratch diga "hola, mundo":
- El bloque "cuando se hace clic en la bandera verde" es el inicio de nuestro programa, y debajo, hemos encajado un bloque "decir" y hemos escrito "hola, mundo"
- También podemos arrastrar el bloque "preguntar y esperar", con una pregunta como "¿Cuál es tu nombre?", y combinarlo con un bloque "decir" para obtener la respuesta:
- Pero no esperamos después de decir "Hola" con el primer bloque, por lo que podemos utilizar el bloque "decir () durante () segundos":
- Podemos utilizar el bloque "unir" para combinar dos frases para que Scratch pueda decir "hola, David":
- Fíjate que podemos anidar instrucciones y variables.
- De hecho, el bloque "decir" en sí es como un algoritmo, en el que proporcionamos una entrada de "hola, mundo" y produjo la salida de Scratch (el gato) "diciendo" esa frase:
- El bloque "preguntar", también, toma una entrada (la pregunta que queremos hacer) y produce la salida del bloque "respuesta":
- Luego, podemos usar el bloque "respuesta" junto con nuestro propio texto, "hola, ", como dos entradas al algoritmo de unión ...
- … que pasamos como entrada nuevamente al bloque "decir":
- Podemos intentar hacer que Scratch (el nombre del gato) diga miau:
- Pero cuando hacemos clic en la bandera verde, escuchamos el sonido del maullido una y otra vez de inmediato. ¡Nuestro primer error o equivocación! Podemos agregar un bloque para esperar, para que los maullidos suenen más normales.
- Pero cuando hacemos clic en la bandera verde, escuchamos el sonido del maullido una y otra vez de inmediato. ¡Nuestro primer error o equivocación! Podemos agregar un bloque para esperar, para que los maullidos suenen más normales.
- Podemos hacer que Scratch apunte hacia el mouse y se mueva hacia él:
- Veremos una oveja que puede contar:
- Aquí,
contador
es una variable, cuyo valor podemos establecer, usar y cambiar.
- Aquí,
- También podemos hacer que Scratch maulle si lo tocamos con el puntero del mouse:
- Alternativamente, podemos hacer que Scratch ruja si lo hacemos:
- Aquí, tenemos dos ramas o condiciones diferentes que se repetirán para siempre. Si el ratón lo está tocando, Scratch "rugirá", de lo contrario, solo maullará.
-
Podemos hacer que Scratch se mueva hacia adelante y hacia atrás en la pantalla con algunos bloques más que podemos descubrir mirando alrededor:
- Incluso podemos grabar nuestro propio sonido para reproducir.
-
Con dos "disfraces" o imágenes diferentes de Scratch con sus patas en posiciones diferentes, podemos incluso simular un movimiento de caminata animado: ![bloques etiquetados como "establecer estilo de rotación izquierda-derecha" y "para siempre" con "mover 10 pasos", "si toca el borde? entonces" con "reproducir hasta terminar el sonido ouch", "girar 180 grados" anidado dentro, y "siguiente disfraz"}(https://cs50.harvard.edu/x/2020/notes/0/bounce.png)
- Observamos otro programa, bark, donde podemos usar la barra espaciadora para silenciar un león marino:
- Tenemos una variable,
silenciado
, que esfalso
de forma predeterminada. Y nuestro programa comprobará constantemente si se presiona la barra espaciadora y establecerá silenciado enfalso
si esverdadero
overdadero
si no. De esta manera, podemos alternar si se reproduce el sonido o no, ya que nuestro otro conjunto de bloques para el león marino verifica la variablesilenciado
:
- Tenemos una variable,
- Con múltiples sprites o personajes, podemos tener diferentes conjuntos de bloques para cada uno de ellos:
- Para una marioneta, tenemos estos bloques que dicen "¡Marco!", y luego un bloque "evento de difusión". Este "evento" se utiliza para que nuestros dos sprites se comuniquen entre sí, como enviar un mensaje secreto. Por lo tanto, nuestra otra marioneta puede esperar este evento para decir "¡Polo!":
- Para una marioneta, tenemos estos bloques que dicen "¡Marco!", y luego un bloque "evento de difusión". Este "evento" se utiliza para que nuestros dos sprites se comuniquen entre sí, como enviar un mensaje secreto. Por lo tanto, nuestra otra marioneta puede esperar este evento para decir "¡Polo!":
- Ahora que conocemos algunos conceptos básicos, podemos pensar en el diseño o la calidad de nuestros programas. Por ejemplo, es posible que queramos hacer que Scratch tosa tres veces repitiendo algunos bloques:
- Si bien esto es correcto, podemos evitar repetir bloques con un bucle:
- El siguiente paso es abstraer parte de nuestro código en una función o hacerlo reutilizable de diferentes maneras. Podemos crear un bloque llamado "tos" y poner algunos bloques dentro de él:
- Ahora, todos nuestros sprites pueden usar el mismo bloque "tos", en tantos lugares como queramos.
- Incluso podemos poner una cantidad de veces en nuestra función de tos, por lo que solo necesitamos un solo bloque para toser cualquier cantidad de veces:
- Observamos algunos ejemplos y analizamos cómo podríamos implementar componentes de ellos con diferentes sprites que siguen el cursor del mouse o hacen que suceda algo más en el escenario.
- ¡Bienvenidos a bordo!