Skip to content

Commit

Permalink
actualizo repo
Browse files Browse the repository at this point in the history
  • Loading branch information
rgrimson committed Nov 20, 2020
1 parent 7452e17 commit 7370106
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 54 deletions.
30 changes: 15 additions & 15 deletions Notas/08_Clases_y_Objetos/05_Teledeteccion.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ En este ejercicio vamos a trabajar con una imagen satelital obtenida por sensore
### Ejercicio 8.14: Optativo de teledetección
**Autora: [Mariela Rajngewerc](https://github.com/marielaraj/)**

La imagen original fue bajada de la página del [earthexplorer](https://earthexplorer.usgs.gov/). En esa página se pueden bajar imágenes con distinto nivel de pre-procesamiento. Para este ejercicio bajamos una imagen de nivel de procesamiento 2, esto quiere decir que los valores de los pixeles representan la reflectancia en superficie en distintas longitudes de onda. [Acá](https://www.usgs.gov/media/files/landsat-8-collection-1-land-surface-reflectance-code-product-guide) pueden encontrar el manual de estas imagenes donde les detallan la descripción tanto de los nombres de lor archivos como de los preprocesamiento que tienen realizados.
La imagen original fue bajada de la página del [earthexplorer](https://earthexplorer.usgs.gov/). En esa página se pueden bajar imágenes con distinto nivel de pre-procesamiento. Para este ejercicio bajamos una imagen de nivel de procesamiento 2, esto quiere decir que los valores de los pixeles representan la reflectancia en superficie en distintas longitudes de onda. [Acá](https://www.usgs.gov/media/files/landsat-8-collection-1-land-surface-reflectance-code-product-guide) pueden encontrar el manual de estas imagenes donde les detallan la descripción tanto de los nombres de lor archivos como de los preprocesamiento que tienen realizados.

Para este ejercicio hemos realizado un clip de cada una de las bandas originales de la imagen y ya multiplicamos a cada una de las bandas por el factor de escala indicado en el manual (0,0001).

Expand All @@ -32,11 +32,11 @@ En la carpeta [clip](https://drive.google.com/file/d/1uoigo5s2xgWfbBQdUcJfOdhfYM

### Ejercicio 8.15: Ver una banda
a) Usá [numpy](https://numpy.org/doc/stable/reference/generated/numpy.load.html) para levantar cada una de las bandas y `plt.imshow(banda)` para verla.
¿Se ve correctamente? Podés ajustar el rango de visualización de colores usando los parámetros `vmin` y `vmax`.
¿Se ve correctamente? Podés ajustar el rango de visualización de colores usando los parámetros `vmin` y `vmax`.

_Sugerencia_: Con `plt.hist(banda.flatten(),bins=100)` vas a ver un histograma de los valores en la matriz `banda`. Podés usarlo para guiarte en la búsqueda del rango que tiene sentido usar como vmin y vmax.
_Sugerencia_: Con `plt.hist(banda.flatten(),bins = 100)` vas a ver un histograma de los valores en la matriz `banda`. Podés usarlo para guiarte en la búsqueda del rango que tiene sentido usar como vmin y vmax.

b) Probá usando percentiles para fijar el rango. Algo como
b) Probá usando percentiles para fijar el rango. Algo como

```python
vmin = np.percentile(data.flatten(), q)
Expand Down Expand Up @@ -84,9 +84,9 @@ Creá un `np.array` que le asigne a cada píxel el número dado por el *identifi

c) Generá un gráfico con `matplotlib` mostrando las clases obtenidas.

d) Crear un colorMap para lograr asignarle a cada clase el color sugerido en la tabla. Para esto podés usar la función ListedColormap incluída en `matplotlib.colors` y crear un colorMap (cmap).
d) Crear un colorMap para lograr asignarle a cada clase el color sugerido en la tabla. Para esto podés usar la función ListedColormap incluída en `matplotlib.colors` y crear un colorMap (cmap).

e) Ponele una leyenda que indique el nombre de cada clase con el color asignado, para eso te sugerimos usar la función `mpatches` que se encuentra en `matplotlib.patches`. Para que puedas orientarte, te mostramos a continuación un ejemplo de resultado esperado:
e) Ponele una leyenda que indique el nombre de cada clase con el color asignado, para eso te sugerimos usar la función `Patch` que se encuentra en `matplotlib.patches`. Para que puedas orientarte, te mostramos a continuación un ejemplo de resultado esperado:

![](./img.png)

Expand All @@ -96,28 +96,28 @@ Si llegaste hasta acá, no te olvides de guardar tu trabajo en el archivo `NDVI.
En el ejercicio anterior definimos a mano los umbrales que distinguen las clases. Es posible hacer esto de forma automática. Para eso se usan técnicas de clustering. El siguiente código muestra un ejemplo con un clasificador muy sencillo: `kmeans`. Este clasificador está ya implementado en la biblioteca [sklearn](https://scikit-learn.org/stable/) que es una biblioteca dedicada al aprendizaje automático en python (probablemente la más usada para esto).

```python
# filtro datos ruidosos o que puedan traer problemas.
# filtro datos ruidosos o que puedan traer problemas.
# el NDVI debe estar entre -1 y 1.
ndvi[ndvi>1]=1
ndvi[ndvi<-1]=-1
ndvi[ndvi > 1] = 1
ndvi[ndvi < -1] = -1

#importo el clasificador y defino una instancia para clasificar con dos etiquetas
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=2)
kmeans = KMeans(n_clusters = 2)

#le saco la estructura bidimensional a la matriz NDVI y la llamo datos
datos = ndvi.reshape(-1,1) #datos es un vector con un dato de NDVI por pixel.

#entreno o ajusto el el clasificador con los datos (demora!)
kmeans.fit(datos) #ajusta el modelo
#usa el modelo ajustado para poner etiquetas
etiquetas = kmeans.predict(ndvi.reshape(-1,1))
etiquetas = kmeans.predict(ndvi.reshape(-1,1))

#visualizo los resultados recuperando la estructura bidimensional de la matriz
plt.imshow(etiquetas.reshape(ndvi.shape))
```

Probá ajustando el número de clusters (`n_clusters=5`, por ejemplo) y corriendo nuevamente el modelo. Ponele colores diferentes a las diferentes clases obtenidas.
Probá ajustando el número de clusters (`n_clusters = 5`, por ejemplo) y corriendo nuevamente el modelo. Ponele colores diferentes a las diferentes clases obtenidas.

Si tarda mucho podés trabajar con un pedazo de la imágen. Por ejemplo si hacés `ndvi_clip = ndvi[1000:2000,2000:3000]` te quedás con un cuadradito que es un octavo de la imagen original y podés usarlo para probar cosas rápido. Si te convencen los resultados podés correr tu algoritmo sobre la imágen completa.

Expand All @@ -138,7 +138,7 @@ plt.imshow(clases_ndvi, cmap=cmap, norm=norm)
```


Y este para las leyendas:
Y éste para las leyendas:
```python
import matplotlib.patches as mpatches
# Genero leyenda y grafico con leyenda
Expand All @@ -147,8 +147,8 @@ texts = ['Sin vegetacion', 'Area desnuda', 'Vegetacion baja',
patches = [mpatches.Patch(color=cmap(i), label="{:s}".format(texts[i]) ) for i in range(len(texts))]
plt.legend(handles=patches, bbox_to_anchor=(0.2,1.3), loc='center', ncol=1 )
plt.imshow(clases_ndvi, cmap=cmap, norm=norm)
plt.show()```

plt.show()
```


[Contenidos](../Contenidos.md) \| [Anterior (4 Objetos, pilas y colas)](04_Pilas_Colas.md) \| [Próximo (6 Cierre de la octava clase)](06_Cierre.md)
Expand Down
4 changes: 2 additions & 2 deletions Notas/09_Generadores_e_Iteradores/00_Resumen.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
# 9. Generadores e iteradores
Programar es básicamente escribir condicionales, ciclos y asignaciones de variables. Aunque no de cualquier forma.

Los ciclos, ya sean ciclos `while` o iteraciones `for` son una de las estructuras más ubicuas en cualquier lenguaje. Los programas hacen muchas iteraciones para procesar listas, leer archivos, buscar en bases de datos y demás.
Los ciclos, ya sean ciclos `while` o iteraciones `for` son una de las estructuras más ubicuas en cualquier lenguaje. Los programas hacen muchas iteraciones para procesar listas, leer archivos, buscar en bases de datos y demás.

Una de las características más poderosas de Python es la capacidad de redefinir la iteración mediante las llamadas "funciones generadoras". En esta sección veremos de que se trata ésto. Hacia el final vas a escribir programas que procesan datos en tiempo real, a medida que son generados.
Una de las características más poderosas de Python es la capacidad de redefinir la iteración mediante las llamadas "funciones generadoras". En esta sección veremos de qué se trata esto. Hacia el final vas a escribir programas que procesan datos en tiempo real, a medida que son generados.

Terminamos la clase con un ejercicio optativo que combina dos temas importantes: objetos y simulaciones. El ejercicio optativo propone simular en el espacio y tiempo la dinámica predador-presa utilizando para esto programación orientada a objetos.

Expand Down
32 changes: 17 additions & 15 deletions Notas/09_Generadores_e_Iteradores/01_protocolo_Iteracion.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ Podemos iterar sobre una gran diversidad de objetos.

```python
a = 'hola a todes'
for c in a: # Iterar las letras en a
for c in a: # Iterar sobre las letras en a
...

b = { 'nombre': 'Elsa', 'password':'foo'}
for k in b: # Iterar para cada clave de diccionario
b = {'nombre': 'Elsa', 'password':'foo'}
for k in b: # Iterar sobre las claves de diccionario
...

c = [1,2,3,4]
for i in c: # Iterar sobre los items en una lista ó tupla
c = [1, 2, 3, 4]
for i in c: # Iterar sobre los items en una lista o tupla
...

f = open('foo.txt')
for x in f: # Iterar sobre las líneas de un archivo ASCII
...
```

Podemos iterar sobre todos estos objetos porque cumplen con un *protocolo* que permite, justamente, iterar. Veamos algo sobre este protocolo:
Podemos iterar sobre todos estos objetos porque cumplen con un *protocolo* que permite, justamente, iterar. Veamos algo sobre este protocolo:

### El protocolo de iteración

Expand Down Expand Up @@ -95,10 +95,10 @@ for c in camion:
Construí la siguiente lista:

```python
a = [1,9,4,25,16]
a = [1, 9, 4, 25, 16]
```

Y ahora iterá sobre esa lista *a mano*: Llamá al método `__iter__()` para obtener un objeto iterador y llama al método `__next__()` para obtener sucesivamente cada uno de los elementos.
Y ahora iterá sobre esa lista *a mano*: Llamá al método `__iter__()` para obtener un objeto iterador y llama al método `__next__()` para obtener sucesivamente cada uno de los elementos.

```python
>>> i = a.__iter__()
Expand Down Expand Up @@ -127,7 +127,7 @@ La función nativa de Python `next()` es un "atajo" al método `__next__()` de u
>>> f = open('Data/camion.csv')
>>> f.__iter__() # Notar que esto apunta al método...
# ...que accede al archivo mismo.
<_io.TextIOWrapper name='Data/portfolio.csv' mode='r' encoding='UTF-8'>
<_io.TextIOWrapper name='Data/camion.csv' mode='r' encoding='UTF-8'>
>>> next(f)
'nombre,cajones,precio\n'
>>> next(f)
Expand Down Expand Up @@ -174,15 +174,15 @@ from camion import Camion

def leer_camion(filename):
'''
Lee un archivo con el contenido de un camión
Lee un archivo con el contenido de un camión
y lo devuelve como un objeto Camion.
'''
with open(filename) as file:
camiondicts = fileparse.parse_csv(file,
select=['nombre','cajones','precio'],
types=[str,int,float])

camion = [ Lote(d['nombre'], d['cajones'], d['precio']) for d in camiondicts ]
camion = [Lote(d['nombre'], d['cajones'], d['precio']) for d in camiondicts]
return Camion(camion)
...
```
Expand Down Expand Up @@ -245,7 +245,7 @@ Testealo, testealo, y testealo para asegurarte que funciona:
```

### Ejercicio 9.3: Un iterador adecuado
Cuando hagas clases que sean recipientes ó contenedores de estructuras de datos vas a necesitar que hagan algo más que simplemente iterar. Probá modificar la clase `Camion` de modo que tenga algunos de los "métodos mágicos" que mencionamos en la [Sección 8.3](../08_Clases_y_Objetos/03_Métodos_Especiales.md#métodos-especiales-para-convertir-a-strings). Aquí hay algunos:
Cuando hagas clases que sean recipientes o contenedores de estructuras de datos vas a necesitar que hagan algo más que simplemente iterar. Probá modificar la clase `Camion` de modo que tenga algunos de los "métodos mágicos" que mencionamos en la [Sección 8.3](../08_Clases_y_Objetos/03_Métodos_Especiales.md#métodos-especiales-para-convertir-a-strings). Aquí hay algunos:

```python
class Camion:
Expand Down Expand Up @@ -287,7 +287,9 @@ Lote('Lima', 100, 32.2)
>>> camion[1]
Lote('Naranja', 50, 91.1)
>>> camion[0:3]
[Lote('Lima', 100, 32.2), Lote('Naranja', 50, 91.1), Lote('Caqui', 150, 83.44)]
[Lote('Lima', 100, 32.2),
Lote('Naranja', 50, 91.1),
Lote('Caqui', 150, 103.44)]
>>> 'Naranja' in camion
True
>>> 'Manzana' in camion
Expand All @@ -297,8 +299,8 @@ False

Guardá tu versión de `camion.py` con estos cambios para entregar y para la revisión de pares.

**Un comentario importante sobre todo esto:**
Se considera *de buen estilo Python* al código que comparte ciertas normas de interacción con el resto del mundo Python. Este concepto aplicado a objetos contenedores significa que estos cumplen con las buenas costumbres de ser iterables, indexables y que admiten otras operaciones que naturalmente se esperan *a priori* que vayan a cumplir, justamente por el simple hecho de ser objetos contenedores.
**Un comentario importante sobre todo esto:**
Se considera *de buen estilo Python* al código que comparte ciertas normas de interacción con el resto del mundo Python. Este concepto aplicado a objetos contenedores significa que éstos cumplen con las buenas costumbres de ser iterables, indexables y que admiten otras operaciones que naturalmente se espera *a priori* que vayan a cumplir, justamente por el simple hecho de ser objetos contenedores.


[Contenidos](../Contenidos.md) \| [Próximo (2 Iteración a medida)](02_iteracion_a_medida.md)
Expand Down
44 changes: 22 additions & 22 deletions Notas/09_Generadores_e_Iteradores/02_iteracion_a_medida.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

En esta sección introducimos el concepto de función generadora. Estas funciones te permiten obtener el iterador que necesites.

### Un problema de iteración
### Un problema de iteración

Suponé que querés crear una secuencia particular de iteración: una cuenta regresiva, por decir algo.

Expand All @@ -27,7 +27,7 @@ def regresiva(n):
yield n
n -= 1
```
*Nota: "yield" se traduce como "rendir" ó "entregar"*
*Nota: "yield" se traduce como "rendir" ó "entregar".*

Por ejemplo:

Expand All @@ -43,7 +43,7 @@ Un generador es *cualquier* función que usa el commando `yield`.

El comportamiento de los generadores es algo diferente al del resto de las funciones.

Al llamar a un generador creás un objeto generador, pero su función no se ejecuta de inmediato.
Al llamar a un generador creás un objeto generador, pero su función no se ejecuta de inmediato.

```python
def regresiva(n):
Expand Down Expand Up @@ -82,7 +82,7 @@ Lo que hace `yield` es notable: produce un valor, y luego suspende la ejecución
>>> x.__next__()
8
```
Cuando finalmente se llega al final de la función, la iteración da un error.
Cuando finalmente se llega al final de la función, la iteración da un error.

```python
>>> x.__next__()
Expand Down Expand Up @@ -112,19 +112,19 @@ Por ejemplo, probá este generador que busca un archivo y entrega las líneas qu
>>> for line in open('Data/camion.csv'):
print(line, end='')

nombre,cantidad,precio
"Lima",100,32.20
"Naranja",50,91.10
"Limon",150,83.44
"Mandarina",200,51.23
"Durazno",95,40.37
"Mandarina",50,65.10
"Naranja",100,70.44
nombre,cajones,precio
Lima,100,32.2
Naranja,50,91.1
Caqui,150,103.44
Mandarina,200,51.23
Durazno,95,40.37
Mandarina,50,65.1
Naranja,100,70.44
>>> for line in filematch('Data/camion.csv', 'Naranja'):
print(line, end='')

"Naranja",50,91.10
"Naranja",100,70.44
Naranja,50,91.1
Naranja,100,70.44
>>>
```

Expand All @@ -143,9 +143,9 @@ bash % python3 sim_mercado.py

Después, olvidate de él. Dejálo ahí, corriendo.

Usando otra consola, mirá el contenido de `Data/mercadolog.csv`. Vas a ver que cada tanto se agrega una nueva línea al archivo.
Usando otra consola, mirá el contenido de `Data/mercadolog.csv`. Vas a ver que cada tanto se agrega una nueva línea al archivo.

Ahora que el programa generador de datos está en ejecución, escribamos un programa que abra el archivo, vaya al final, y espere nuevos datos. Para esto creá un programa llamado `vigilante.py` (es uno de los ejercicios a entregar) que contenga el siguiente código.
Ahora que el programa generador de datos está en ejecución, escribamos un programa que abra el archivo, vaya al final, y espere nuevos datos. Para esto creá un programa llamado `vigilante.py` (es uno de los ejercicios a entregar) que contenga el siguiente código.

```python
# vigilante.py
Expand All @@ -170,13 +170,13 @@ while True:

*Nota: EOF = End Of File (fin de archivo)*

Cuando ejecutes el programa vas a ver un indicador de precios en el mercado en tiempo real, con indicación de qué producto se trata, cuál es su precio, y cuál es el volumen de la operación (en cantidad de cajones).
Cuando ejecutes el programa vas a ver un indicador de precios en el mercado en tiempo real, con indicación de qué producto se trata, cuál es su precio, y cuál es el volumen de la operación (en cantidad de cajones).

*Observación:* La forma en que usamos el método `readline()` en este ejemplo es un poco rara, no es la forma en que se suele usar (dentro de un ciclo `for` para recorrer el contenido de un archivo). En este caso la estamos usando para mirar constantemente el fin de archivo para obtener los últimos datos que se hayan agregado (`readline()` devuelve ó bien el último dato o bien una cadena vacía).

### Ejercicio 9.6: Uso de un generador para producir datos
Si analizás un poco el código del [Ejercicio 9.5](../09_Generadores_e_Iteradores/02_iteracion_a_medida.md#ejercicio-95-monitoreo-de-datos-en-tiempo-real) vas a notar que la primera parte del programa "produce" datos (los obtiene del archivo) y la segunda los procesa y los imprime, es decir "consume" datos. Una característica importante de las funciones generadoras es que podés mover todo el código a una función reutilizable. Probalo vos.

Modificá el código del [Ejercicio 9.5](../09_Generadores_e_Iteradores/02_iteracion_a_medida.md#ejercicio-95-monitoreo-de-datos-en-tiempo-real) de modo que la lectura del archivo esté resuelta por una única función generadora `vigilar()` a la que se le pasa un nombre de archivo como parámetro. Hacelo de modo que el siguiente código funcione:

```python
Expand All @@ -202,20 +202,20 @@ if __name__ == '__main__':
Guradá esta versión de `vigilante.py` para entregar al final de la clase.

### Ejercicio 9.7: Cambios de precio de un camión
Modificá el programa `vigilante.py` para que sólo informe las líneas que tienen precios de lotes incluídos en un camión, e ignore el resto de los productos. Por ejemplo:
Modificá el programa `vigilante.py` para que sólo informe las líneas que tienen precios de lotes incluídos en un camión, e ignore el resto de los productos. Por ejemplo:

```python
if __name__ == '__main__':
import informe

camion = informe.leer_camion ('Data/camion.csv')

for line in vigilar('Data/mercadolog.csv'):
fields = line.split(',')
nombre = fields[0].strip('"')
precio = float(fields[1])
volumen = int(fields[2])

if nombre in camion:
print(f'{nombre:>10s} {precio:>10.2f} {volumen:>10d}')
```
Expand Down
Binary file modified Notas/Ejercicios.zip
Binary file not shown.

0 comments on commit 7370106

Please sign in to comment.