# Pensamiento computacional (borrador unidad 2)
Notas teoricas
# Unidad 2
## 2.1 Python
#### ¿Qué es Python?
Python es un lenguaje interpretado de alto nivel. Frecuentemente se lo clasifica como lenguaje de ["scripting"](https://es.wikipedia.org/wiki/Script). La sintaxis del Python tiene elementos de lenguaje C de programación.
Python fue creado por Guido van Rossum a principios de la década del '90 y lo nombró así en honor de Monty Python.
#### ¿Dónde conseguir Python?
Te recomendamos instalar Python 3.6 o más nuevo. En la documentación previa hablamos sobre [cómo instalar Python para este curso](../Instalacion.md).
#### ¿Cómo ejecuto Python en mi máquina?
Existen diferentes entornos en los que podés correr Python en tu computadora. Es importante saber que Python está instalado normalmente como un programa que se ejecuta desde la consola. Desde la terminal deberías poder ejecutar `python` así:
```
bash $ python
Python 3.8.1 (default, Feb 20 2020, 09:29:22)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print("hello world")
hello world
>>>
```
Si es la primera vez que ves una consola o terminal, sería conveniente que pares aquí, leas [un tutorial corto](https://tutorial.djangogirls.org/es/intro_to_command_line/) sobre cómo usar la consola de tu sistema operativo y luego vuelvas para seguir leyendo.
Existen diversos entornos fuera de la terminal en los que se puede escribir y ejecutar código Python. Pero para nosotros es importante que primero aprendas a usarlo desde la terminal: si lo sabés usar bien desde la terminal (que es su entorno natural) lo podrás usar en cualquier otro entorno. Ya en la próxima clase usarás Python dentro de un entorno de desarrollo. Por ahora, te recomendamos usarlo de esta manera que acabamos de explicar.
### Pasemos a ver algunos ejercicios para interiorizarnos un poquito más
#### Ejercicio 2.1: Python como calculadora
En tu máquina, iniciá Python y usalo como calculadora para resolver el siguiente problema:
* ¿Cuántas horas son 105 minutos?
* ¿Cuántos kilómetros son 20 millas? (un kilómetro corresponde a 0,6214 millas)
En tu terminal vas a ver algo del estilo:
```python
>>> 105/60
1.75
>>> 20 / 0.6214
32.1853878339234
```
### Ejercicio 2.2: Buscando ayuda
Usá el comando `help()` para obtener ayuda sobre la función `abs()`. Luego, usá el `help()` para obtener la ayuda sobre la función `round()`. Tipeá `help()` sólo para entrar en la ayuda en modo interactivo.
El `help()` no funciona con los comandos básicos de Python como `for`, `if`, `while`, etc. Si tipeás `help(for)` vas a obtener un error. Podés probar usando comillas como en `help("for")`, en algunos entornos funciona bien. Si no, siempre podés hacer una búsqueda en internet.
La documentación oficial en inglés de Python se encuentra en <http://docs.python.org>. Por ejemplo, encontrá ahí la documentación sobre la función `abs()` (ayuda: está dentro de "library reference" y relacionado a las "built-in functions").
## 2.2 Un primer programa
En esta sección vas a crear tu primer programa en Python, ejecutarlo y debuguearlo.
#### Ejecutando Python
Los programas en Python siempre son ejecutados en un intérprete de Python.
El intérprete es una aplicación que funciona en la consola y se ejecuta desde la terminal.
```bash
python3
Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
Les programadores no suelen tener problemas en usar el intérprete de esta forma, aunque no es la más cómoda para principiantes. Más adelante vamos a proponerles usar entornos de desarrollo más sofisticados, pero por el momento quedémosnos con la incomodidad que nos va a enseñar cosas útiles.
### Modo interactivo
Cuando ejecutás Python, entrás al modo *interactivo* en el que podés experimentar.
Si escribís un comando, se va a ejecutar inmediatamente. No hay ningún ciclo de edición-compilación-ejecución-debug en Python, como hay en otros lenguajes.
```python
>>> print('hello world')
hello world
>>> 37*42
1554
>>> for i in range(5):
... print(i)
...
0
1
2
3
4
>>>
```
Esta forma de escribir código (en una consola del lenguaje) que se evalúa inmediatamente e imprime el resultado, se denomina *bucle de Lectura-Evaluación-Impresión* (REPL por las siglas en inglés de «Read-Eval-Print-Loop»). Asegurate de poder interactuar con el intérprete antes de seguir.
Veamos en mayor detalle cómo funciona este REPL:
- `>>>` es el símbolo del intérprete para comenzar un nuevo comando.
- `...` es el símbolo del intérprete para continuar con un comando comenzado antes. Dejá una línea en blanco para terminar lo que ya ingresaste.
El símbolo `...` puede mostrarse o no dependiendo de tu entorno. En este curso lo mostraremos como líneas en blanco para facilitar el copy-paste de fragmentos de código (del que ya dijimos, ¡no hay que abusar!).
Antes vimos que el guión bajo `_` guarda el último resultado.
```python
>>> 37 * 42
1554
>>> _ * 2
3108
>>> _ + 50
3158
>>>
```
:::danger
*Esto solo es válido en el modo interactivo que estamos viendo. No uses el guión bajo en un programa.* :fire:
:::
Lo escribimos dos veces para recalcar bien que esto no se debe hacer nunca en un programa
### Crear programas
Los programas se guardan en archivos `.py`.
```python
# hello.py
print('hello world')
```
Podés crear estos archivos con tu editor de texto favorito. Más adelante vamos a proponerles usar el `spyder` que es un entorno de desarrollo integrado (IDE por «Integrated Development Environment», entorno de desarrollo integrado) que permite tener en la pantalla un editor y un intérprete al mismo tiempo, entre otras cosas. Pero por ahora usemos el block de notas, el gedit o tu editor favorito para seguir estos ejemplos.
### Ejecutar programas
Para ejecutar un programa, correlo en la terminal con el comando `python` seguido del nombre del archivo a ejecutar. Por ejemplo, en una línea de comandos Unix (por ejemplo Ubuntu):
```bash
bash % python hello.py
hello world
bash %
```
O en una terminal de Windows:
```
C:\SomeFolder>hello.py
hello world
C:\SomeFolder>c:\python36\python hello.py
hello world
```
Obervación: En Windows puede ser necesario especificar el camino (path) completo al intérprete de Python como en `c:\python36\python`.
Sin embargo, si Python está instalado del modo usual, podría alcanzar con que tipées el nombre del programa como en `hello.py`.
Tené en cuenta que con estos comandos estás corriendo el código de Python desde la línea de comandos de tu sistema operativo. El código se ejecuta, Python termina y el control vuelve a la terminal, saliendo de Python. Si necesitás ejecutarlo y seguir dentro del intérprete de Python podés usar `python -i hello.py`.
Si estás dentro del intérprete de Python y querés salir y volver a la línea de comandos, podés hacerlo mediante el comando `exit()`.
### Un ejemplo de programa
Resolvamos el siguiente problema:
> Una mañana ponés un billete en la vereda al lado del obelisco porteño. A partir de ahí, cada día vas y duplicás la cantidad de billetes, apilándolos prolijamente. ¿Cuánto tiempo pasa antes de que la pila de billetes sea más alta que el obelisco?
Acá va una solución:
```python
# obelisco.py
grosor_billete = 0.11 * 0.001 # grosor de un billete en metros
altura_obelisco = 67.5 # altura en metros
num_billetes = 1
dia = 1
while num_billetes * grosor_billete <= altura_obelisco:
print(dia, num_billetes, num_billetes * grosor_billete)
dia = dia + 1
num_billetes = num_billetes * 2
print('Cantidad de días', dia)
print('Cantidad de billetes', num_billetes)
print('Altura final', num_billetes * grosor_billete)
```
Cuando lo ejecutás, la salida será la siguiente:
```bash
bash % python3 obelisco.py
1 1 0.00011
2 2 0.00022
3 4 0.00044
4 8 0.00088
5 16 0.00176
6 32 0.00352
...
19 262144 28.83584
20 524288 57.67168
Cantidad de días 21
Cantidad de billetes 1048576
Altura final 115.34336
```
A continuación vamos a usar este primer programa como ejemplo para aprender algunas cosas fundamentales sobre Python.
### Comandos
Un programa de Python es una secuencia de comandos:
```python
a = 3 + 4
b = a * 2
print(b)
```
Cada comando se termina con una nueva línea. Los comandos son ejecutados uno luego del otro hasta que el intérprete llega al final del archivo.
### Comentarios
Los comentarios son texto que no será ejecutado.
```python
a = 3 + 4
# Esto es un comentario
b = a * 2
print(b)
```
Los comentarios comienzan con `#` y siguen hasta el final de la línea.
### Variables
Una variable es un nombre para un valor. Estos nombres pueden estar formados por letras (minúsculas y mayúsculas) de la a a la z. También pueden incluir el guión bajo, y se pueden usar números, salvo como primer caracter.
```python
altura = 442 # válido
_altura = 442 # válido
altura2 = 442 # válido
2altura = 442 # inválido
```
### Tipos
El tipo de las variables no debe ser declarado como en otros lenguajes. El tipo es asociado con el valor del lado derecho.
```python
altura = 442 # Entero
altura = 442.0 # Punto flotante
altura = 'Muy, muy alto' # Cadena de caracteres
```
Decimos que Python tiene tipado dinámico. El tipo percibido por el intérprete puede cambiar a lo largo de la ejecución dependiendo del valor asignado a la variable.
### Python distingue mayúsculas y minúsculas
Mayúsculas y minúsculas son diferentes para Python. Por ejemplo, todas las siguientes variables son diferentes.
```python
nombre = 'David'
Nombre = 'Diego'
NOMBRE = 'Rosita'
```
Los comandos de Python siempre se escriben con minúsculas.
```python
while x < 0: # OK
WHILE x < 0: # ERROR
```
## 2.3 Operaciones básicas con números
### Tipos de números
Python tiene 4 tipos de números:
* Booleanos
* Enteros
* Punto flotante
* Complejos (con parte real y parte imaginaria)
### Booleanos (bool)
Las variables booleanas se llaman así en honor al lógico inglés [George Boole](https://es.wikipedia.org/wiki/George_Boole). Pueden tomar dos valores: `True` y `False` (verdadero y falso).
```python
a = True
b = False
```
Internamente, son evaluados como enteros con valores `1`, `0`.
```python
c = 4 + True # 5
d = False
if d == 0:
print('d is False')
```
*No escribas código basado en esta convención. Sería bastante raro.*
### Enteros (int)
Representan números enteros (positivos y negativos) de cualquier magnitud:
```python
a = 37
b = -299392993727716627377128481812241231
```
Incluso se pueden especificar en diferentes bases:
```python
c = 0x7fa8 # Hexadecimal
d = 0o253 # Octal
e = 0b10001111 # Binario
```
Operaciones usuales:
```
x + y Suma
x - y Resta
x * y Multiplicación
x / y División (da un float, no un int)
x // y División entera (da un int)
x % y Módulo (resto)
x ** y Potencia
abs(x) Valor absoluto
```
La unidad mínima de almacenamiento de una computadora es un bit, que puede valer 0 o 1. Los números, caracteres e incluso imágenes y sonido son almacenados en la máquina usando bits. Los números enteros positivos, en particular, suelen almacenarse mediante su representación binaria (o en base dos).
| Número | Representación binaria |
| ------------- |-------------|
| 1 | 1|
| 2 | 10|
| 3 | 11|
| 4 | 100|
| 5 | 101|
| 6 | 110|
Hay algunas operaciones primitivas que se pueden hacer con los enteros a partir de su representación como bits:
```python
x << n Desplazamiento de los bits a la izquierda
x >> n Desplazamiento de los bits a la derecha
x & y AND bit a bit.
x | y OR bit a bit.
x ^ y XOR bit a bit.
~x NOT bit a bit.
```
Al desplazar a la izquierda, simplemente agregamos un cero en la última posición. Así, por ejemplo si corremos el 1 dos lugares a la izquierda obtenemos un 4:
```python
>>> 1 << 2 # 1 << 2 -> 100
4
>>> 6 & 3 # 110 & 011 -> 010
2
```
Al desplazar los bits de un número a la derecha un lugar, el último bit "se cae".
```python
>>> 1 >> 1 # 1 -> 0
0
>>> 6 >> 1 # 110 -> 11
3
```
### Punto flotante (float)
Usá una notación con decimales o una notación científica para especificar un valor de tipo punto flotante:
```python
a = 37.45
b = 4e5 # 4 x 10**5 o 400,000
c = -1.345e-10
```
Los números de tipo floats son representados en la máquina como números de doble precisión usando la representación nativa del microprocesador que sigue el estándar [IEEE 754](https://es.wikipedia.org/wiki/IEEE_754).
Para los que los conozcan: es el mismo tipo que los `double` en el lenguaje C.
> Un `float` almacenan hasta 17 digitos con un
> exponente entre -308 to 308
Cuidado que la aritmética de los números de punto flotante no es exacta.
```python
>>> a = 2.1 + 4.2
>>> a == 6.3
False
>>> a
6.300000000000001
>>>
```
Esto **no es un problema de Python**, si no el resultado de la forma en que el hardware de nuestras computadoras almacena los números de punto flotante.
Operaciones usuales:
```
x + y Suma
x - y Resta
x * y Multiplicación
x / y División (da un float, no un int)
x // y División entera (da un float, pero con ceros luego del punto)
x % y Módulo (resto)
x ** y Potencia
abs(x) Valor absoluto
```
Estas son las mismas operaciones que con los enteros. Otras operaciones usuales se encuentran en el módulo `math`.
```python
import math
a = math.sqrt(x)
b = math.sin(x)
c = math.cos(x)
d = math.tan(x)
e = math.log(x)
```
El módulo `math` también tiene constantes (`math.e`, `math.pi`), entre otras cosas.
### Comparaciones
Las siguientes comparaciones (suelen llamarse *operadores relacionales* ya que expresan una relación entre dos elementos) funcionan con números:
```
x < y Menor que
x <= y Menor o igual que
x > y Mayor que
x >= y Mayor o igual que
x == y Igual a
x != y No igual a
```
Observá que el `==` se usa para comparar dos elementos mientras que el `=` se usa para asignar un valor a una variable. Son símbolos distintos que cumplen funciones diferentes.
Podés formar expresiones booleanas más complejas usando
`and`, `or`, `not`
Acá mostramos algunos ejemplos:
(no te preocupes si por el `if`, en otra unidad lo vamos a explicar pero pensalo como un `que pasa si` )
```python
#si b es mayor o igual que a y al mismo tiempo menor o igual a c pasa:
if b >= a and b <= c:
print('b está entre a y c')
# si b NO es menor que a o mayor que c pasa otra cosa
if not (b < a or b > c):
print('b sigue estando entre a y c')
```
### Conversión de números
El nombre de un tipo (de datos) puede ser usado para convertir valores:
```python
a = int(x) # Convertir x a int
b = float(x) # Convertir x a float
```
Probalo.
```python
>>> a = 3.14159
>>> int(a)
3
>>> b = '3.14159' # También funciona con cadenas que representan números.
>>> float(b)
3.14159
>>>
```
*Cuidado: el separador decimal en Python es el punto, como en inglés, y no la coma del castellano. Por eso el comando `float(3,141592)` da un `ValueError`.*