Configuración del ambiente de trabajo

Miguel Alejandro Salgado Zapien

2021-05-10

Configuración del ambiente de trabajo

Durante la clase anterior se hablo de la configuración para el ambiente de trabajo.

Los pasos que seguiremos esta clase son:

Instalación del interprete de Python

Python es un lenguaje de programación interpretado, lo que significa que no necesitamos un compilador necesitamos un interprete.

Existen múltiples interpretes de Python, pero el mas común es CPython.

Esta escrito en C, es multi plataforma, existe abundante documentación para casi cualquier aspecto relacionado con el, ademas de una comunidad activa y participativa en su desarrollo y promoción.

Nos interesara trabajar con la versión mas reciente y estable del lenguaje e interprete y para ello instalaremos la versión mas reciente ofrecida en el sitio oficial de su fundación.

Si se trabaja Windows, lo mas conveniente es instalarlo directamente desde el sitio oficial (seguir el liga anterior), y seguir la siguiente guia

Si se trabaja con algún sistema tipo Unix favor de verificar la documentación oficial de su distribución para proceder con la instalación

Consideraciones al instalar.

Si se trabaja con Python, hay que estar seguros de que versión esta instalada en nuestro sistema, en ocasiones Python es instalado por otros programas debido a que lo tienen como dependencia.

Es importante verificar que el directorio de donde se encuentra el ejecutable python.exe, o python, este disponible en la variable de entorno PATH.

También es importante tener disponible en la variable de entorno PATH, el directorio donde reside el programa pip o pip3.

Una vez instalado

Hay que ejecutar un Hello World.

Grabe un archivo con el siguiente contenido en un archivo nombrado hello_world.py.

# Imprime el _PEP 20_
import this
# Modulo para interactuar con el sistema
import sys
# Imprimir un string 
print("Hello World")
# Imprimir un string con extrapolacion para 
# incluir los valores argumento de linea de comando
print(f"This are my arguments:\n{sys.argv}")

Instalación de dependencias.

Para las tareas que realizaremos en este curso es importante tener herramientas para la inspección, análisis y procesamiento de datos, por ello instalaremos los siguientes módulos.

Ejecutaremos en una linea de comandos el programa pip de la siguiente manera.

pip install PyYAML toml matplotlib pandas scikit-learn numpy scipy

Una vez instalados los paquetes hay que ejecutar un par de pruebas para verificar la funcionalidad de dichos paquetes.

Tome los ejemplos guárdelos con el nombre indicado, y después ejecute en una linea de comandos (ubicándose en el directorio que aloja a los archivos)

python {FILENAME}

Para Verificar la funcionalidad de toml y PyYaml, ejecutaremos el siguiente programas, y verificaremos que la salida sea similar a la aqui señalada.

Nombre sugerido para el archivo prueba_modulos_para_archivos_objeto.py

import json
import toml
import yaml

toml_string = """
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates
[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true
"""

yaml_string = """
none: [~, null]
bool: [true, false, on, off]
int: 42
float: 3.14159
list: [LITE, RES_ACID, SUS_DEXT]
dict: {hp: 13, sp: 5}
"""

json_string = """
{
    "key": "value",
    "list": [ "uno", 2, "tres", 14 ]
}
"""

_json_data = json.loads(json_string)
_toml_data = toml.loads(toml_string)
_yaml_data = yaml.load(yaml_string, Loader=yaml.CLoader)
print("=> json data")
print(type(_json_data))
print(_json_data.keys())
print(_json_data.values())
for (key, value) in _json_data.items():
    print(f"{key} - {value}")


print("=> yaml data")
print(type(_yaml_data))
print(_yaml_data.keys())
print(_yaml_data.values())
for (key, value) in _yaml_data.items():
    print(f"{key} - {value}")

print("=> toml data")
print(type(_toml_data))
print(_toml_data.keys())
print(_toml_data.values())
for (key, value) in _toml_data.items():
    print(f"{key} - {value}")
=> json data
<class 'dict'>
dict_keys(['key', 'list'])
dict_values(['value', ['uno', 2, 'tres', 14]])
key - value
list - ['uno', 2, 'tres', 14]
=> yaml data
<class 'dict'>
dict_keys(['none', 'bool', 'int', 'float', 'list', 'dict'])
dict_values([[None, None], [True, False, True, False], 42, 3.14159, ['LITE', 'RES_ACID', 'SUS_DEXT'], {'hp': 13, 'sp': 5}])
none - [None, None]
bool - [True, False, True, False]
int - 42
float - 3.14159
list - ['LITE', 'RES_ACID', 'SUS_DEXT']
dict - {'hp': 13, 'sp': 5}
=> toml data
<class 'dict'>
dict_keys(['title', 'owner', 'database'])
dict_values(['TOML Example', {'name': 'Tom Preston-Werner', 'dob': datetime.datetime(1979, 5, 27, 7, 32, tzinfo=<toml.tz.TomlTz object at 0x7ff72701e130>)}, {'server': '192.168.1.1', 'ports': [8001, 8001, 8002], 'connection_max': 5000, 'enabled': True}])
title - TOML Example
owner - {'name': 'Tom Preston-Werner', 'dob': datetime.datetime(1979, 5, 27, 7, 32, tzinfo=<toml.tz.TomlTz object at 0x7ff72701e130>)}
database - {'server': '192.168.1.1', 'ports': [8001, 8001, 8002], 'connection_max': 5000, 'enabled': True}

El siguiente ejemplo producira un archivo nombrado anatomy_of_a_plot.png, donde se ilustra las partes que component una grafica de matplotlib.

El producto debe lucir como el siguiente.

Nombre sugerido para el archivo prueba_modulos_matplotlib.py

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator, MultipleLocator

np.random.seed(19680801)

# X = numpy.linspace(0.5, 3.5, 100)
X = np.linspace(0.5, 3.5, 100)
Y1 = 1+X*0.5
Y2 = 1+np.cos(1+X/0.75)/2
Y3 = np.random.uniform(Y1, Y2, len(X))

# fig = matplotlib.pyplot.figure(figsize=(8, 8))
fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 1, 1, aspect=1)


def minor_tick(x, pos):
    if not x % 1.0:
        return ""
    return f"{x:.1f}"

ax.xaxis.set_major_locator(MultipleLocator(1.000))
ax.xaxis.set_minor_locator(AutoMinorLocator(5))
ax.yaxis.set_major_locator(MultipleLocator(1.000))
ax.yaxis.set_minor_locator(AutoMinorLocator(5))
# FuncFormatter is created and used automatically
ax.xaxis.set_minor_formatter(minor_tick)

ax.set_xlim(0, 4)
ax.set_ylim(0, 4)

ax.tick_params(which='major', width=1)
ax.tick_params(which='major', length=10)
ax.tick_params(which='minor', width=1.0, labelsize=5)
ax.tick_params(which='minor', length=5, labelsize=5, labelcolor='0.2')

ax.grid(linestyle=":", linewidth=0.5, color='.15', zorder=-10)

ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label="Blue signal", zorder=10)
ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label="Red signal")
ax.plot(X, Y3, linewidth=0,
        marker='o', markerfacecolor='w', markeredgecolor='k')

ax.set_title("Anatomy of a figure", fontsize=20, verticalalignment='bottom')
ax.set_xlabel("X axis label")
ax.set_ylabel("Y axis label")

ax.legend()


def circle(x, y, radius=0.15):
    from matplotlib.patches import Circle
    from matplotlib.patheffects import withStroke
    circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,
                    edgecolor='black', facecolor=(0, 0, 0, .0125),
                    path_effects=[withStroke(linewidth=5, foreground='w')])
    ax.add_artist(circle)


def text(x, y, text):
    ax.text(x, y, text, backgroundcolor="white",
            ha='center', va='top', weight='bold', color='blue')


# Minor tick
circle(0.50, -0.10)
text(0.50, -0.32, "Minor tick label")

# Major tick
circle(-0.03, 4.00)
text(0.03, 3.80, "Major tick")

# Minor tick
circle(0.00, 3.50)
text(0.00, 3.30, "Minor tick")

# Major tick label
circle(-0.15, 3.00)
text(-0.15, 2.80, "Major tick label")

# X Label
circle(1.80, -0.27)
text(1.80, -0.45, "X axis label")

# Y Label
circle(-0.27, 1.80)
text(-0.27, 1.6, "Y axis label")

# Title
circle(1.60, 4.13)
text(1.60, 3.93, "Title")

# Blue plot
circle(1.75, 2.80)
text(1.75, 2.60, "Line\n(line plot)")

# Red plot
circle(1.20, 0.60)
text(1.20, 0.40, "Line\n(line plot)")

# Scatter plot
circle(3.20, 1.75)
text(3.20, 1.55, "Markers\n(scatter plot)")

# Grid
circle(3.00, 3.00)
text(3.00, 2.80, "Grid")

# Legend
circle(3.70, 3.80)
text(3.70, 3.60, "Legend")

# Axes
circle(0.5, 0.5)
text(0.5, 0.3, "Axes")

# Figure
circle(-0.3, 0.65)
text(-0.3, 0.45, "Figure")

color = 'blue'
ax.annotate('Spines', xy=(4.0, 0.35), xytext=(3.3, 0.5),
            weight='bold', color=color,
            arrowprops=dict(arrowstyle='->',
                            connectionstyle="arc3",
                            color=color))

ax.annotate('', xy=(3.15, 0.0), xytext=(3.45, 0.45),
            weight='bold', color=color,
            arrowprops=dict(arrowstyle='->',
                            connectionstyle="arc3",
                            color=color))

ax.text(4.0, -0.4, "Made with https://matplotlib.org",
        fontsize=10, ha="right", color='.5')

fig.savefig("anatomy_of_a_plot.png")
#plt.show()

El siguiente ejemplo producira una salida a manera de tabla expresando relaciones entre las unidad metro y pies.

Nombre sugerido para el archivo prueba_pandas.py

import pandas as pd

data = {
  "metros": [1, 100, 1000],
  "pies": [3.28, 328.08, 3280.84]
}

df = pd.DataFrame(data)
print(df)
   metros     pies
0       1     3.28
1     100   328.08
2    1000  3280.84

Con estas pruebas es suficnete por ahora.

Se sugiere editar los ejemplos y jugar con los valores, para ver como afecta al resultado dicho cambio.

Instalacion de Jupyter Labs

Jupyter es un proyecto muy utilizado y respetado en el ecosistema de Python y de el analisis de datos en general.

Es un ambiente integrado para el desarrollo de proyectos principalmente para el lenguaje Python, (soporta otros lenguajes dependiendo el kernel de jupyter instalado).

La caracteristica mas notoria pudiera ser que es un ambiente web, facilitando su poratabilidad y el desarrollo de extensiones con tecnologias web.

Para instalarlo solo hay que ejecutar:

pip install jupyterlab

Una vez instalado hay que iniciar el servidor de jupyter-lab ejecutando

jupyter-lab

Esto iniciara el proceso del servidor, y abrirar una pestaña del explorador (generalmente en la direccion http://localhost:8888.

Dentro de jupyter-lab tenemos opciones como:

Entre otras opciones, a nosotros nos interesara trabajar principalmente con notebooks.

Son archivos codificados internamente como json, pero con extension ipynb (Interactive Python NoteBook).

En dicho archivo se almacena el estado y resultado de ejecucion, asi como todos los bloques de codigo o texto ingresados al notebook.

La ventaja mas interesante de trabajar con un notebook (en cualquier tecnologia), es la retroalimentacion inmediata del codigo ejecutado.

Ahora se sugiere, tomar el codigo de los ejemplos y reproducirlo en un notebook.

Las consideraciones a tener, es que jupyter nos ofrece poder exprear las salidas dentro del notebook mismo, de manera que no es necesario guardar archivos o ejecutar la declaracion print todo el tiempo, en el caso de diagrams, pandas y matplotlib es posible visualizar sus salidas dentro del mismo notebook.

Programacion Literaria

La programación literaria (o letrada) es un estilo de programación propuesto por Donald Knuth para documentar los programas. Él mismo la empleo en su sistema tipográfico T E X { } .

El estilo de programación literaria como se le ha llamado en español o programación letrada o instruida como se traduce literalmente, tal y como lo concibió Knuth, representa un movimiento disruptivo respecto a la escritura de programas en el orden y forma impuesto por el ordenador. En cambio permite a los programadores desarrollar sus programas en el orden fijado por la lógica y el flujo de sus pensamientos.

Wikipedia

Moraleja

Gracias a la utilización de los notebook, documentar nuestro proceso de pensamiento resulta mas sencillo, y podemos explicar los aspectos relevantes a nuestro código o proceso de solución de problemas de manera mas eficiente.

Jupyter nos permite exportar nuestros notebook a distintos formatos como HTML y PDF, en caso de ser necesario.

Programación de Scripts

La diferencia entre un programa y un script es muy ambigua, muchos dicen que dependen del lenguaje y otros de la naturaleza de el programa a ejecutar, pero a nosotros nos interesara referirnos a un script como:

Un programa sencillo, que solo presente dependencias previamente instaladas en el sistema y que realiza una tarea especifica, y que no requiera entradas del usuario una vez iniciada su ejecución.

Esta definición no es estricta pero es útil para ayudar a alegorizar los tipos de programas que escribiremos.

Ejemplo de Script

Este es un script que nos genera una gráfica de pastel, expresando la distribución de distintas extensiones de archivo en el directorio especificado.

#!/usr/bin/env python
from collections import defaultdict
from sys import argv
from pathlib import Path
import matplotlib.pyplot as plt

if __name__ == '__main__':
    try:
        _dir = Path(argv[1])
        if not _dir.is_dir():
            raise Exception()
    except:
        print("Invalid directory")
        exit(1)
    exts = defaultdict(lambda: 0)
    for file in _dir.iterdir():
        if file.is_dir():
            exts["directory"] += 1
        else:
            exts[file.suffix] += 1
    fig = plt.figure(figsize=(8, 8))
    ax = fig.add_subplot(1, 1, 1, aspect=1)
    plt.pie(exts.values(), labels = exts.keys())
    plt.show()

Uso

./scriptname.py <directory>