summaryrefslogtreecommitdiff
path: root/src/08_stdlib.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/08_stdlib.md')
-rw-r--r--src/08_stdlib.md371
1 files changed, 371 insertions, 0 deletions
diff --git a/src/08_stdlib.md b/src/08_stdlib.md
new file mode 100644
index 0000000..3ac1542
--- /dev/null
+++ b/src/08_stdlib.md
@@ -0,0 +1,371 @@
+# La librería estándar
+
+La librería estándar se refiere a todas las utilidades que un lenguaje de
+programación trae consigo. Los lenguajes de programación, a parte de aportar la
+propia funcionalidad del lenguaje en sí mismo que simplemente sería la
+ejecución del código fuente que se le indique, suelen incluir funcionalidades
+que no están necesariamente relacionadas con ese proceso.
+
+El motivo de esto es facilitar el uso del lenguaje para las labores más
+comunes, incluyendo el código necesario para realizarlas sin necesitar añadidos
+externos.
+
+En lenguajes de programación de dominio específico la librería estándar suele
+contemplar muchos casos de ese dominio concreto. Por ejemplo, el lenguaje de
+programación Julia, aunque esté diseñado con el objetivo de ser un lenguaje
+válido para cualquier uso, su área de trabajo se centra en el entorno
+científico. Es por eso que incluye en su librería estándar paquetes de álgebra
+lineal, estadística y otros.
+
+Existen muchas diferentes aproximaciones a la librería estándar. Algunos
+lenguajes las mantienen extremadamente reducidas con el fin de que la
+implementación del lenguaje sea más liviana, con la contrapartida de forzar a
+quien los use a tener que utilizar herramientas externas o a desarrollarlas.
+
+Python es un lenguaje de propósito general con una extensísima librería
+estándar. Esto dificulta la selección de apartados a mostrar en este capítulo,
+pero facilita la programación de cualquier aplicación en éste lenguaje.
+
+Los paquetes estándar de python facilitan la lectura de infinidad de tipos de
+fichero, la conversión y el tratamiento de datos, el acceso a la red, la
+ejecución concurrente, etc. por lo que librería estándar es más que suficiente
+para muchas aplicaciones y no se requiere añadir módulos externos.
+
+Conocer la librería estándar y ser capaz de buscar en ella los paquetes que
+necesites te facilitará mucho la tarea, evitando, por un lado, que dediques
+tiempo a desarrollar funcionalidades que el propio lenguaje ya aporta y, por
+otro, que instales paquetes externos que no necesitas.
+
+Todos los apartados aquí listados están extremadamente bien documentados en la
+página oficial de la documentación de python y en la propia ayuda. Eso sí,
+tendrás que importarlos para poder leer la ayuda, pero ya sabes cómo se hace.
+
+A continuación se recogen los módulos más interesantes, aunque en función del
+proyecto puede que necesites algún otro. Puedes acceder al listado completo en
+la página oficial de la documentación[^stdlibdoc].
+
+[^stdlibdoc]: <https://docs.python.org/3/library/index.html#library-index>
+
+
+## Interfaz al sistema operativo: `os`
+
+Ya definimos previamente el concepto *interfaz* como superficie de contacto
+entre dos entidades. Esta librería facilita la interacción entre python y el
+sistema operativo.
+
+La comunicación con el sistema operativo es primordial para cualquier lenguaje
+de programación de uso general, ya que es necesario tener la capacidad de hacer
+peticiones directas al sistema operativo. Por ejemplo, cambiar de directorio
+actual para facilitar la inclusión rutas relativas en el programa, resolver
+rutas a directorios y un largo etc.
+
+En capítulos previos hemos hablado de las diferencias entre sistemas
+operativos. Esta librería, además, facilita el trabajo para esos casos. Por
+ejemplo, que el separador de directorios en UNIX es `/` y en Windows `\`, si
+quisiéramos programar una aplicación multiplataforma, nos encontraríamos con
+problemas. Sin embargo, el módulo `os.path` dispone de herramientas para
+gestionar las rutas de los directorios por nosotros, por ejemplo, la variable
+`os.path.sep` (copiada en `os.sep` por abreviar), guarda el valor del separador
+del sistema en el que se esté ejecutando la aplicación: `/` en UNIX y `\` en
+Windows.
+
+Este paquete es muy interesante para desarrollar código portable entre las
+diferentes plataformas.
+
+## Funciones relacionadas con el intérprete: `sys`
+
+Aunque el nombre de este módulo suene complicado, su uso principal es el de
+acceder a funcionalidades que el propio python controla. Concretamente, se usa
+sobre todo para la recepción de argumentos de entrada al programa principal,
+la redirección de entradas y salidas del programa y la terminación del
+programa.
+
+### Salida forzada: `sys.exit()`
+
+Para salir de forma abrupta del programa y terminar su ejecución, python
+facilita la función `sys.exit()`. Al ejecutarla la
+
+### *Standard streams*: `sys.stdin`, `sys.stdout` y `sys.stderr`
+
+Cuando se trabaja en programas que funcionan en la terminal se pueden describir
+tres vías de comunicación con el usuario:
+
+1. El teclado: de donde se obtiene lo que el usuario teclee mediante la función
+ `input`.
+2. La pantalla: a donde se escribe al ejecutar la función `print`.
+3. Y la salida de errores: Una salida especial para los fallos, similar a la
+ anterior, pero que se diferencia para poder hacer un tratamiento distinto y
+ porque tiene ciertas peculiaridades distintas. Los mensajes de error de
+ excepciones se envían aquí.
+
+Estas tres vías se conocen comúnmente como entrada estándar (*standard input*),
+`stdin`, salida estándar (*standard output*), `stdout`, y error estándar
+(*standard error*), `stderr`. Este concepto responde al nombre de *standard
+streams* y es una abstracción de los dispositivos físicos que antiguamente se
+utilizaban para comunicarse con una computadora. Hoy en día, estos tres
+*streams* son una abstracción de esa infraestructura y se comportan como
+simples ficheros de lectura en el primer caso y de escritura en los otros dos.
+
+Los diferentes sistemas operativos los implementan a su modo, pero desde el
+interior de python son simplemente ficheros abiertos, como si se hubiese
+ejecutado la función `open` en ellos y ellos se encargan de leer o escribir a
+la vía de interacción con el usuario correspondiente. Es decir, en realidad
+`print`, `input`, etc. son únicamente funciones que facilitan la labor de
+escribir manualmente en estos *streams*:
+
+``` python
+>>> import sys
+>>> chars = sys.stdout.write("Hola\n")
+Hola
+>>> chars # Recoge el número de caracteres escritos
+5
+```
+
+La realidad es que estos *streams* dan una flexibilidad adicional muy
+interesante. Como son únicamente variables de ficheros abiertos pueden
+cerrarse y sustituirse por otros, permitiéndote redireccionar la entrada o la
+salida de un programa a un fichero.
+
+El siguiente ejemplo redirecciona la salida de errores a un fichero llamado
+`exceptions.txt` y trata de mostrar una variable que no está definida. Python
+en lugar de mostrar el mensaje de una excepción, la escribe en el fichero al
+que se ha redireccionado la salida:
+
+``` python
+>>> sys.stderr = open("exceptions.txt", "w")
+>>> aasda # No muestra el mensaje de error
+>>>
+>>> with open("exceptions.txt") as f:
+... f.read() # Muestra el contenido del archivo
+...
+'Traceback (most recent call last):\n File "<stdin>", line 1, in \
+<module>\nNameError: name \'aasda\' is not defined\n'
+```
+
+
+### Argumentos de entrada: `sys.argv`
+
+Es posible añadir argumentos de entrada a la ejecución de los programas. Piensa
+en el propio programa llamado python, al ejecutarlo en la shell de sistema se
+le pueden mandar diferentes opciones que, por ejemplo, digan qué módulo debe
+ejecutar:
+
+``` bash
+python test.py
+```
+
+Para la shell de sistema, todo lo que se escriba después de la primera palabra
+es considerado un argumento de entrada.
+
+Cuando se ejecutan nuestros programas escritos en python, es posible también
+enviarles argumentos de entrada:
+
+``` bash
+python test.py argumento1 argumento2 ...
+```
+
+Lo que el python reciba después del nombre del módulo a ejecutar lo considerará
+argumentos de entrada de nuestro módulo y nos lo ordenará y dejará disponible
+en la variable `sys.argv`, una lista de todos los argumentos de entrada.
+
+Si muestras el contenido de la variable en la REPL, te responderá `['']` ya que
+la REPL se ejecuta sin argumentos. Sin embargo, si creas un módulo y le añades
+este contenido:
+
+``` python
+import sys
+print(sys.argv)
+```
+
+Verás que se imprime una lista con el nombre del archivo en su primer elemento.
+
+Si ejecutas el módulo desde la shell de sistema añadiéndole argumentos de
+entrada:
+
+``` bash
+python modulo.py arg1 arg2 arg3
+```
+
+La lista `sys.argv` recibirá todos, siempre a modo de string.
+
+Los argumentos de entrada son extremadamente interesantes para permitir que los
+programas sean configurables por quien los use sin necesidad de tener que
+editar el código fuente, cosa que nunca debería ser necesaria a menos que
+exista un error en éste o quiera añadirse una funcionalidad.
+
+## Procesamiento de argumentos de entrada: `argparse`
+
+Como la variable `sys.argv` entrega los argumentos de entrada tal y como los
+recibe y no comprueba si son coherentes, python dispone de una librería
+adicional para estas labores. El módulo `argparse` permite definir qué tipo de
+argumentos de entrada y opciones tiene tu programa y qué reglas deben seguir.
+Además, facilita la creación de ayudas como la que se muestra cuando ejecutas
+`python -h` o `pip -h` en la shell de tu sistema.
+
+Es una librería bastante compleja con infinidad de opciones que es mejor que
+leas en la propia documentación cuando necesites utilizarla.
+
+## Expresiones regulares: `re`
+
+Las expresiones regulares (*regular expression*, también conocidas como
+*regexp* y *regex*) son secuencias de caracteres que describen un patrón de
+búsqueda.
+
+En python se soportan mediante el módulo `re` de la librería estándar.
+
+## Matemáticas y estadística: `math` y `statistics`
+
+El módulo `math` soporta gran cantidad de operaciones matemáticas avanzadas
+para coma flotante. En él puedes encontrar logaritmos, raíces, etc.
+
+El módulo `statistics` soporta estadística básica como medias, medianas,
+desviación típica, etc.
+
+Ambos módulos tienen mucho interés ya que python se usa extensivamente en el
+análisis de datos. Aunque tiene librerías de terceros mucho más adecuadas para
+esta labor, para proyectos pequeños puede que sea suficiente con estos módulos.
+
+## Protocolos de internet: `urllib`
+
+`urllib` es un conjunto de paquetes que permiten seguir URLs o enlaces,
+principalmente para HTTP y su versión segura HTTPs. Soporta cookies,
+redirecciones, autenticación básica, etc.
+
+El siguiente ejemplo te muestra cómo descargar el primer boceto del estándar
+del protocolo HTTP de la página web del IETF. Recordando los apartados previos,
+fíjate en el uso de la sentencia `with` y en el uso de los corchetes para
+obtener un número limitado de caracteres de la recién decodificada respuesta.
+
+``` python
+>>> from urllib.request import urlopen
+>>> with urlopen("https://tools.ietf.org/rfc/rfc2068.txt") as resp:
+... print( resp.read().decode("utf-8")[:1750] )
+...
+
+
+
+
+
+
+Network Working Group R. Fielding
+Request for Comments: 2068 UC Irvine
+Category: Standards Track J. Gettys
+ J. Mogul
+ DEC
+ H. Frystyk
+ T. Berners-Lee
+ MIT/LCS
+ January 1997
+
+
+ Hypertext Transfer Protocol -- HTTP/1.1
+
+Status of this Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Abstract
+
+ The Hypertext Transfer Protocol (HTTP) is an application-level
+ protocol for distributed, collaborative, hypermedia information
+ systems. It is a generic, stateless, object-oriented protocol which
+ can be used for many tasks, such as name servers and distributed
+ object management systems, through extension of its request methods.
+ A feature of HTTP is the typing and negotiation of data
+ representation, allowing systems to be built independently of the
+ data being transferred.
+
+ HTTP has been in use by the World-Wide Web global information
+ initiative since 1990. This specification defines the protocol
+ referred to as "HTTP/1.1".
+
+>>>
+```
+
+## Fechas y horas: `datetime`
+
+`datetime`, que ya ha aparecido anteriormente, es un módulo para gestión de
+fecha y hora. `datetime` soporta gran cantidad de operaciones y tipos de dato.
+Entre ellos los `timedeltas`, diferencias temporales que te permiten sumar y
+restar fechas con facilidad con los operadores habituales.
+
+Con las facilidades de `datetime`, es poco probable que necesites importar una
+librería de gestión de fecha y hora independiente.
+
+## Procesamiento de ficheros: `json` y `sqlite3`
+
+Python habilita gran cantidad de procesadores de formatos de fichero, los dos
+que se lista en este apartado tienen especial interés.
+
+El primer módulo, `json`, sirve para manipular datos en formato JSON. Sus dos
+funciones principales `dumps` y `loads` vuelcan o cargan datos de JSON a
+diccionarios o listas en una sola orden debido que la propia estructura de JSON
+está formada por parejas clave valor o listas de valores ordenadas por índices.
+Esta es la razón por la que en muchas ocasiones se utilizan ficheros de formato
+JSON para intercambiar información entre aplicaciones de python: su lectura y
+escritura es extremadamente sencilla.
+
+El segundo módulo, `sqlite3`, facilita el acceso a ficheros en formato SQLite3,
+un formato binario con una interfaz de acceso que permite consultas SQL. El
+módulo `sqlite3` es capaz de convertir las tablas que SQLite3 retorna a
+estructuras de python de forma transparente y cómoda por lo que es un aliado
+interesante para aplicaciones que requieren una base de datos pequeña y
+resiliente.
+
+## Aritmética de coma flotante decimal: `decimal`
+
+En el apartado sobre datos tratamos la complejidad de los números de coma
+flotante y que su representación binaria puede dar lugar a problemas. Este
+módulo de aritmética decimal aporta una solución rigurosa a este problema con
+el fin de facilitar el uso de python en entornos que requieren precisión
+estricta que incluso puede requerir cumplir con normativas, como puede ser la
+banca.
+
+La documentación del módulo muestra un par de ejemplos muy interesantes usando
+la clase `Decimal` aportada por este. Se adjuntan a continuación para que los
+estudies y los disecciones en busca de las diferencias con el uso de los
+números de coma flotante normales:
+
+``` python
+>>> from decimal import *
+>>> round(Decimal('0.70') * Decimal('1.05'), 2)
+Decimal('0.74')
+>>> round(.70 * 1.05, 2)
+0.73
+
+>>> Decimal('1.00') % Decimal('.10')
+Decimal('0.00')
+>>> 1.00 % 0.10
+0.09999999999999995
+
+>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
+True
+>>> sum([0.1]*10) == 1.0
+False
+```
+
+## Lo que has aprendido
+
+Más que aprender, en este apartado has sobrevolado la librería estándar de
+python desde la distancia y te has parado a observar qué problemas comunes ya
+están resueltos en python.
+
+La realidad es que la librería estándar es mucho más extensa que lo listado en
+este apartado, pero aquí se han mencionado los módulos que más frecuentemente
+se suelen usar en entornos normales y algunos otros que tienen interés a la
+hora de afianzar conocimiento que has obtenido en capítulos previos, como es el
+caso del módulo `decimal`.
+
+Este capítulo empieza a mostrarte el interés de programar en python y las
+posibilidades que tienes con él, únicamente con la librería estándar. En el
+próximo verás la cantidad de funcionalidad adicional que le puedes añadir con
+un par de librerías escritas por terceros.
+
+Sirva también este capítulo como recordatorio de lo extensa que es la librería
+estándar de python. En el futuro, cuando tengas intención de buscar una
+librería para resolver un problema que te despista de trabajar en la
+funcionalidad principal de tu aplicación, empieza por la librería estándar.