Búsqueda binaria en Python

Búsqueda binaria en Python

Hola a todos, debido a que no quiero dejar de lado el blog durante largos periodos de tiempo, el día de hoy vengo a crear esta breve entrada, para dejar este vídeo que realicé, en donde explico el algoritmo de búsqueda binaria en Python.

búsqueda binaria en python

Ejemplo de búsqueda binaria

En este vídeo podremos apreciar una breve explicación de este algoritmo, viéndolo desde una perspectiva aplicada al lenguaje de programación Python, pero que con apenas esfuerzo, podremos realizarlo utilizando cualquier lenguaje. Esto gracias a que veremos el concepto del algoritmo.

Si tienes alguna duda o comentario no dudes en hacérmelo saber.

Espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Saludos y nos vemos la próxima.

Manejar entornos virtuales en Python

Manejar entornos virtuales en Python

Hola, como podrás haber notado, ya he pasado un tiempo sin escribir en el sitio, varias cosas han sucedido en mi vida personal y eso me ha hecho enfocarme en otras cuestiones, pero como le tengo mucho cariño al sitio, se me ocurrió realizar esta entrada sobre un tema relativamente sencillo, pero bastante útil para aquellos desarrolladores Python novatos (y no tanto) que desean aumentar su productividad, y seguir las buenas prácticas de la industria. Por lo tanto veremos como manejar entornos virtuales en Python.

El problema de no manejar entornos virtuales en python

Como sabrás, Python cuenta con una sencilla administración de paquetes con la herramienta pip, y si no tenemos cuidado y organización a la hora de utilizarla, podemos caer en ciertas situaciones que no son de mucho agrado para nosotros como desarrolladores.

Por ejemplo, suponiendo que tenemos un proyecto (proyecto_1) que tiene como dependencia un módulo en su versión 1.9.12, pero otro proyecto (proyecto_2) que necesitamos para nuestro día a día, tiene la dependencia a ese mismo módulo en su versión 2.0.11, como es un cambio de versión mayor hay muchas incompatibilidades que nuestro proyecto_1 no puede manejar.

Esto nos pone en una situación donde nos debemos preguntar ¿qué versión del paquete instalo? ¿cómo utilizar una versión específica de ese módulo para un determinado proyecto? Estas eran unas de las tantas interrogantes que se hacían los administradores y desarrolladores hace un par de años, cuando se trataba de mantener aplicaciones Python, o cuando necesitaban probar si, la nueva versión de un determinado módulo era compatible con la aplicación en desarrollo.

Para darle solución a las preguntas anteriores y las situaciones que las originan, fue que se encontró la forma de trabajar con entornos virtuales. Pero…

¿A qué me refiero con un entorno virtual en Python?

No son más que un conjunto de herramientas que permiten crear entornos aislados, donde cada uno de ellos es responsable de sus propios paquetes. Es decir, nos permiten crear una sandbox en la que instalar diferentes módulos que serán independientes, tanto de los que existen globalmente en el sistema (dentro del directorio site-packages), como de otros entornos virtuales. Bastante interesante cierto, y espera a ver lo simple que es su manejo.

Creando nuestro primer entorno virtual en Python

Ficha técnica para esta entrada:

  • OS: Linux dev 4.15.9-1-ARCH x86_64 GNU/Linux.
  • Distribución: Arch Linux
  • Versión de Python: Python 3.6.4 (Compatible con Python 3.x y Python 2.x)
  • Intérprete de comandos: Zsh

Para llevar a cabo esta tarea, utilizaremos a virtualenv y virtualenvwrapper de los que hablaremos un poco más a continuación:

  • Virtualenv: básicamente es el motor de todo esto, es el módulo que nos permite realizar la gestión de entornos virtuales para python en nuestro sistema (creación, administración, elminación, etc), se encuentra disponible a tráves de PyPi, pero aunque cumple su objetivo, eran necesarios demasiados pasos en un proceso cansado para lograr tener nuestros entornos funcionando.
  • Virtualenvwrapper: con el objetivo de facilitar el manejo de entornos virtuales con Python, se desarrolló este paquete, que como su nombre indica, contiene una serie de herramientas que actúan como wrapper sobre virtualenv, y facilitan su utilización.

Entre las funcionalidades que incluye virtualenvwrapper, encontramos la de crear diferentes entornos virtuales bajo el mismo directorio del sistema de ficheros, activar un entorno a través de un nombre dado, permitir fácilmente desactivar un entorno virtual para activar y trabajar con otro diferente, borrar un entorno y copiar completamente un entorno con un nombre distinto.

¿Sigues sin estar convencido de su uso?

La instalación de virtualenvwrapper es muy sencilla, basta con ejecutar el comando:

pip install virtualenvwrapper

Esto instalará además las dependencias necesarias (incluyendo a virtualenv)

Antes de comenzar a utilizar virtualenvwrapper, es conveniente modificar nuestro archivo de configuración de nuestro intérprete de comandos (.bashrc, .profile, .zshrc o similar) para añadir un par de líneas que nos faciliten la gestión de nuestros entornos.

La primer línea indicará cuál será el directorio a partir del que se crearán los diferentes entornos si se desea utilizar un directorio diferente al establecido por default, el cuál está establecido en $HOME/.virtualenvs. La segunda línea se encargará de invocar automáticamente al shell script virtualenvwrapper.sh, cada vez que abramos una terminal, sin esto no podríamos utilizar las opciones para manejar nuestros entornos.


export WORKON_HOME=$HOME/.pythonenvs

source /usr/bin/virtualenvwrapper.sh

Ahora procedamos a crear nuestro primer entorno virtual con el siguiente comando:

mkvirtualenv nombredelentorno --no-site-packages

A detalle, basta con invocar al comando mkvirtualenv seguido del nombre que indiquemos que tenga nuestro entorno, además añadimos el parámetro –no-site-packages para asegurar que el entorno se encuentre aislado del directorio site-packages de nuestro sistema.

Por defecto, el comando anterior se encargará de crear nuestro entorno y además activarlo para comenzar a trabajar, esto podrás notarlo en tu intérprete de comandos, ya que posiblemente verás el nombre de tu nuevo entorno en el prompt, en mi caso se aprecia así, siendo (entornoprueba) el entorno virtual que acabo de crear:

(entornoprueba) ..[themushr00m@dev] - [~] - [lun mar 19, 05:54]

Con el comando lsvirtualenv podremos obtener la lista de los entornos virtuales que tenemos creados, y si queremos cambiar de un entorno a otro, podemos hacerlo con el comando workon seguido del nombre del entorno que queremos utilizar.

Este comando se encargará de desactivar el entorno activado actualmente, como de activar el nuevo. Si ningún entorno se encuentra activado, únicamente activará el entorno indicado.

Si lo que queremos es dejar de trabajar en un entorno virtual, podemos desactivarlo con el comando deactivate.

Este es un consejo, si desean que el parámetro –no-site-packages sea aplicado a todos los entornos virtuales que vayan creando, sin tener que estar escribiéndolo siempre, pueden hacer lo siguiente:

En su archivo .bashrc, .profile, .zshrc o similar, justo debajo de las dos líneas que añadimos anteriormente (esto para que tengamos orden) añadimos la siguiente línea:

export VIRTUALENVWRAPPER_VIRTUALENV_ARGS='--no-site-packages'

Y bien, con esto ya pueden comenzar a trabajar con entorno virtuales en Python, añadiendo paquetes a ellos sin ningún riesgo de afectar las versiones instaladas globalmente en el sistema (siempre deben asegurarse que su entorno virtual se encuentra activado :D)

Otra opción interesante es la de enlazar un entorno virtual determinado a un directorio de trabajo, esto nos permitirá que al activar dicho entorno, nos posicionemos en el directorio de trabajo inmediatamente, ¿genial cierto?

Esto lo realizamos de forma sencilla, únicamente es necesario que tengamos activo el entorno virtual que deseamos y nos posicionemos en el directorio que deseamos y ejecutamos el siguiente comando:

setvirtualenvproject

De esta forma, cada vez que abramos nuestro intérprete de comandos, y activemos el entorno virtual, nos posicionará inmediatamente en el directorio de trabajo del proyecto que definimos.

Si son unos talibanes de la documentación no olviden visitar el sitio de documentación de virtualenvwrapper para ver la referencia completa de comandos y parámetros.

Para cerrar con este tema de manejar entornos virtuales con Python, debo decir que pueden crear entornos virtuales con diferente versión de Python sin importar cual sea la principal de sus sistema, pero esto se los dejaré de tarea para que mediante la curiosidad puedan adentrarse a esta fabulosa herramienta.

Espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Saludos y nos vemos la próxima.

Animaciones con Javascript: Tweens con GreenSock (GSAP)

animaciones con javascript

Hola a todos, estoy intentando no descuidar el blog, manteniendo mis actividades lo más organizadas posibles. Siguiendo la pauta que marqué con la entrada anterior intentaré que esta entrada sea lo más explicativa posible. Y bien, para no dar tantas vueltas sin sentido, en esta ocasión aprenderemos a crear animaciones con Javascript, para ello utilizaremos la librería GreenSock (GSAP).

animaciones con javascriptSeguro que en alguna página lo has visto en acción, o hayas escuchado sobre esta librería y ahora quieras meterte de lleno y comenzar a aprender su funcionamiento desde cero, ¿cierto? Si es tu caso, e incluso si no, deberías continuar leyendo, tal vez llegue a interesarte al final. 😉

Sigue leyendo

Código CSS Eficiente: Cuida el uso de IDs

código css eficiente

Hola a todos, esta ocasión también voy a escribir este post un poco corto, pero intentaré que sea lo más explicativo posible al problema. Planeo que se convierta en una serie de varias entradas que serán englobadas bajo el tema “Código CSS Eficiente“.

código css eficiente

Esta primera entrada hablaré sobre los IDs en los elementos HTML, y una situación “curiosa” con la que me encontré hace poco, siendo esta la premisa a mi recomendación de evitar en lo posible utilizarlos.

Sigue leyendo

Trabajando con WebSockets

Programación Python

Hola a todos, debido al trabajo he descuidado el blog estás últimas semanas, así que hoy decidí esforzarme en sacar tiempo y escribir este pequeño ejemplo de un tema qué alguien me preguntó hace unos días mediante Twitter.. En esta entrada llamada “Trabajando con WebSockets”, explicaré de forma breve pero concisa como trabajar con Web Sockets y JS.

A modo de ejemplo, crearemos lo más conocido para este tipo de “features”, un chat. Tal vez eres un dev que ha experimentado en el pasado con Socket.io y buscas saber un poco más sobre lo que hay por detrás, o simplemente estás intentando añadir carácteristicas “real-time” a tu app y no sabes por donde empezar, este post fue hecho pensando en ti. La aplicación final tendrá una apariencia como la siguiente:

Trabajando con WebSocketsLuce bien, ¿cierto? 😀 No sean tan duros, deben recordar que esto fue hecho en unos minutos, solo para poder ejemplificar la teoría, y poder centrarnos en lo realmente importante de este post.

¿Qué es un Web Socket?

Intentando ser simple, WebSocket es un protocolo nuevo para la web que funciona bajo TCP, por el cual, a diferencia de las conexiones HTTP (las que se utilizan normalmente en internet), este es bi-direccional, ¿que significa esto? Como te menciono, hoy por hoy en internet estamos usando una conexión en una sola dirección, solicitamos un recurso al servidor y esperamos la respuesta (o viceversa con ServerEvents, de los cuales planeo escribir pronto). Pero con web sockets el servidor te habla también, te puede llamar y mandar un mensaje en cualquier momento, cool ¿cierto?

Esto nos permite realizar cosas tan “mágicas” en nuestro sitios web, como podamos imaginar, siempre y cuando tengamos en cuenta algunos puntos importantes:

  • La comunicación se inicia con un handshake HTTP, por lo que si la conexión HTTP no se puede establecer, tampoco habrán WebSockets.
  • El soporte debe existir tanto en el cliente como en el servidor. (Tenemos HTML5 en el cliente y Socket.io o WS en el servidor 😀 )
  • A diferencia de los protocolos convensionales de TCP, donde podemos transmitir streams de bytes, en WebSockets solo se pueden transmitir texto/JSON.
  • Al igual que ocurre con HTTP, donde tenemos su versión segura (HTTPS), en los WebSockets contamos con la versión segura WSS, aunque debemos estar en el entendido que no todos los navegadores que soportan los WebSockets, soportarán WSS.

Lo interesante de los WebSockets es que nos dan este comportamiento “real-time”, que nos da la posibilidad de crear aplicaciones complejas de forma sencilla, ¿has querido hacer un juego multijugador? con los WS esto será algo “sencillo”.

Bien, muy interesante todo pero, ¿cómo funciona?

Trabajando con WebSocketsComo mencionaba anteriormente, para iniciar una conexión con el protocolo WS primero el cliente (el browser) le pide al servidor que quiere iniciar esta conexión (handshake: aquí se pasan unos datos secretos), si este proceso es satisfactorio, el servidor responde un “todo en orden, prosigue” y a partir de ahí dejan de utilizar HTTP y pasan a WS.

Además de darnos la posibilidad de una comunicación bi-direccional, también nos ahorramos el “payload”, es decir, esos bytes que se envían en las transmisiones que hacemos por HTTP, que contienen la información para que tanto el cliente, como el servidor sepan que estan recibiendo, qué tipo de conexión utilizamos, etc. Este “payload” es mejor conocido como “cabeceras HTTP”. Esto ya que recordemos que únicamente podemos transmitir texto y nos quedamos “conectados” al servidor hasta que nosotros (los clientes) decidamos que no queremos seguir conectados.

Pequeño ejemplo: Trabajando con WebSockets

Bien, tal vez tanta teoría te abruma, así que aquí te dejo el código del ejemplo para que puedas reproducirlo. y ver un poco de que se trata. Como el código cuenta con comentarios, voy a dejar implicita la explicación del mismo por esta ocasión (es un post express) 🙂

Primeramente y ya teniendo un proyecto creado, instalamos el paquete wsdesde NPM.

yarn add ws

Teniendo el siguiente index.html:


<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, maximum-scale=1.0">
    <title>Simple Chat App - VueJS and Web Sockets</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/lumen/bootstrap.min.css">
    <style>
        .container {margin-top: 40px;}
        #messages { height: auto; min-height: 150px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="col-xs-12 col-md-offset-3 col-md-6">
            <div class="panel panel-primary">
                <div class="panel-heading">Join the conversation!</div>
                <div class="panel-body">
                    <div class="form-group">
                        <label for="messages" class="form-control-label">Messages</label>
                        <div id="messages" class="form-control"></div>
                    </div>
                    <div class="form-inline">
                        <div class="form-group form-group-sm">
                            <label for="message_text" class="form-control-label">Write your message:</label>
                            <input type="text" class="form-control" id="message_text" />
                        </div>
                        <button class="btn btn-primary">Send</button>
                    </div>
                </div>
            </div>
            <p id="username-label"></p>
        </div>
    </div>

    <script src="app.js"></script>
</body>
</html>

Vemos que llama un script, cuyo contenido es el siguiente:


// app.js
// URL dónde se encuentra ejecutando nuestro servidor de WS
const wsUri = "ws://localhost:5001"
// Creamos un nuevo "cliente" de WS
let socket = new WebSocket(wsUri)
// Ya que la aplicación de ejemplo es una sala de chat
// al iniciar nos pide un nombre de usuario para utilizarlo
const name = prompt("What is your username?")
document.getElementById('username-label').innerText = `You are: ${name}`

// Controla la conexión al WS
socket.onopen = event => {
  // Descomentar para ver que recibimos por parte del WS
  //console.log(event)
  socket.send(JSON.stringify({
    type: "name",
    data: name
  }))
  console.log("Socket connected successfully...")
}

let messages = document.getElementById("messages")

// Nos suscribimos a los eventos de transferencia de mensajes
// por parte del servidor, si tuvieramos mensajes de diferentes tipos
// podríamos llevar a cabo una validación
socket.onmessage = event => {
  // Descomentar para ver que recibimos por parte del WS
  //console.log(event)
  const data = JSON.parse(event.data)
  messages.innerHTML += `<span class="text-success">${data.name}:</\span> ${data.data}<br /\>`
}

document.querySelector(".btn").onclick = event => {
  const text = document.getElementById("message_text").value
  socket.send(JSON.stringify({
    type: "message",
    data: text
  }))
  messages.innerHTML += `<span class="text-warning">You:</\span> ${text}<br /\>`
}

Creamos nuestro archivo server.js, que será el encargado de ejecutar el servidor con soporte para WS.


// server.js
// Referenciamos las librerías a utilizar

// Para manejar los WebSockets utilizaremos la librería 'ws'
// que nos facilita bastante el trabajo con estos.
const WS = require("ws").Server
// Puerto a donde escuchará nuestro servidor WS
const port = 5001
// Creamos nuestro servidor de WS
const server = new WS({ port })

// Nos suscribimos al evento de conexión
// el cual es llamado cuando un cliente se conecta
server.on("connection", ws => {
  // El método callback es llamado cuando
  // se conecta un nuevo cliente y en el argumento "ws"
  // vamos a tener un "enlace" a este cliente

  // Podemos enviar un mensaje al cliente
  // de bienvenida apenas se conecte
  // los parámetros son el nombre del mensaje y un json con los datos
  //ws.send('welcome', { greeting: 'Welcome WS client!' })

  // Los WebSockets se comunican en base a mensajes
  // por lo que debemos suscribirnos a cada uno de los
  // posibles mensajes que los clientes puedan enviar
  ws.on("message", message => {
    console.log(`Received: ${message}`)
    message = JSON.parse(message)
    // Ya que el cliente puede enviar mensajes de diferentes tipos
    // Validamos que el mensaje recibido sea del tipo "name"
    if(message.type === "name") {
      // Store the username that send the email
      ws.userName = message.data
      return
    }

    for(let client of server.clients) {
      // Cómo está será una aplicación de chat
      // enviamos el mensaje a todos los clientes
      // evitando enviarlo a "nosotros"
      if(client !== ws)
        client.send(JSON.stringify({
          type: "message",
          name: ws.userName,
          data: message.data
        }))
    }
  })

  // Nos suscribirnos también al evento
  // que se ejcuta cuando un cliente decide terminar la conexión
  ws.on("close", event => {
    console.log("A client was disconnected...")
  })

  // Todos los llamados a console.log son del servidor
  // con própositos de depuración
  console.log("New client connected...")
})

Ahora únicamente debemos ejecutar el servidor

node server.js

Tan sólo abrimos nuestro index.html en cualquier navegador que soporte WS (Chrome, Firefox, etc) y podremos ver nuestra aplicación funcionando.

Al principio expliqué que tanto el cliente como el servidor deben soportar web sockets, tenemos que tener en cuenta que es necesario HTML5 con web sockets, te dejo este enlace a Caniuse.com con el detalle de los navegadores que lo soportan.

Opciones como SocketIO se encargan de que la conexión funcione sin importar el navegador, esto lo hace intentando con otros mecanismos de transporte (XHR Pooling, Flash Sockets, etc.). No va a ser con web sockets pero va a funcionar como si lo fuera.

Creo que es todo por ahora, si gustan saber más al respecto de “ws”, pueden visitar su documentación, que siendo honestos es bastante clara. Recuerda que todo el código fuente puedes encontrarlo en el siguiente repositorio.

Espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Crear APIs REST con Python y Hug

Hug framework

Hola a todos, han sido unas semanas muy divertidas, en las cuales he ido aprendiendo a ser padre, por lo que deje un poco olvidado el blog; pero creí conveniente dedicarle un tiempo. En esta entrada, vamos a aprender a crear APIs REST con Python y Hug, un framework que llevo un tiempo utilizando en mis proyectos, y que me ha dejado un buen sabor de boca, debido a su rendimiento y facilidad para obtener productos finales.

Sigue leyendo

Un desarrollador siendo papá

Un desarrollador siendo papá…

Hola a todos, aquí estamos una vez más después de un tiempo sin escribir, he tenido descuidado mis redes sociales, y el blog en especial, debido a, cómo podrán intuir por el título del post, hace un mes tuve la dicha de convertirme en padre, y debo decir que ha traído un cambio grande en mi vida. Es por esto que en esta ocasión, quiero recordar que esto no deja de ser un blog, y compartir mi experiencia y forma de sentir con esto de ser un desarrollador siendo papá.

Un desarrollador siendo papá

Lo sé, lo sé, aún falta para que la imagen sea del todo cierta, sin embargo el sentimiento ya existe. Es desconcertante estar 8 horas en la oficina cada día (realmente un poco más) y estar pensando en las ganas que tienes de cargar a tu hija, tenerla en tus brazos, y saber que ella puede sentir que la proteges, y sobre todo, la amas.

Debo decir que por ahora soy muy feliz llegando a casa, y viendo a mi novia y a mi hija, es maravilloso. Como desarrollador de software, siempre he tratado de pensar lógicamente, paso horas y horas escribiendo código que, para los mortales, es un tipo de lengua ilegible.

También, otra actividad que realizo durante mucho tiempo es “debuggear” aplicaciones, esta práctica es un proceso que supone un reto para cualquier desarrollador de software, ya que se centra en buscar errores en la aplicación, para así poder corregirlos. Con esto como premisa debo decir que ya encontré mi mayor reto: mi hija.

Cada vez que llora, debo aplicar todo mi conocimiento en esta tarea para poder “saber” que está mal con ella, pañal sucio, hambre, sueño, o simplemente quiere que le den un paseo. Todo esto únicamente observando detalladamente sus gestos, movimientos, sonidos, etc. Es algo sumamente complejo, y la verdad, aún no tengo un algoritmo con el que lidiar del todo con eso, pero seguimos en la etapa de “testing”.

Anteriormente me centraba en pasar horas frente al ordenador, observando charlas de conferencias, probando la tecnología del momento, o simplemente viendo “Los simpsons”, pero ahora, paso horas viéndola dormir, cargandola y paseando por la casa con ella, y sobre todo, amándola.

Esta entrada no tiene ningún objetivo cultural, no creo que pueda transmitir conocimiento alguno, simplemente quería escribir un poco ya que repito, hace un mes me convertí en padre y es el mejor trabajo y cargo el cual he desempeñado, y espero poder realizarlo correctamente en lo que me resta.

Me despido y pronto terminaré esos “post” que tengo en borrador, para que podamos seguir con la temática habitual del blog

El papá más feliz…

Tipos estáticos en Python con Mypy

tipos estáticos en python

Tipos estáticos en Python

Hola a todos, en esta entrada vamos a hablar sobre los tipos estáticos en Python, utilizando Mypy, esta herramienta desarrollada principalmente por un equipo de Dropbox, incluyendo al creador del lenguaje Guido Van Rossum.

tipos estáticos en python

Tipado estático en lenguajes dinámicos

Desde hace un par de años, han salido a la luz verificadores de tipado estático para lenguajes dinámicos populares como Hack para PHP o Flow y TypeScript para Javascript, los cuales han sido ampliamente adoptados por la comunidad (yo soy un feliz usuario de Flow).

Hace unos años tres años, una sintaxis provisional de anotaciones para tipos estáticos fue añadida a Python 3, sin embargo, los tipos estáticos en Python no habían sido adoptados aún ampliamente, debido a que no existía una herramienta para llevar a cabo la verificación. Es aquí donde llegamos a Mypy.

¿Qué es Mypy?

Como podemos encontrar en su página oficial:

Mypy is an experimental optional static type checker for Python that aims to combine the benefits of dynamic (or “duck”) typing and static typing. Mypy combines the expressive power and convenience of Python with a powerful type system and compile-time type checking. Mypy type checks standard Python programs; run them using any Python VM with basically no runtime overhead.

Cabe decir que a pesar de que Mypy ya soporta la mayoría de las características de Python, aún se encuentra en desarrollo. Y como es bien sabido, nada como un ejemplo para ver de que estamos hablando, también sacado de la página oficial de Mypy.

tipos estáticos en PythonSe puede observar en la imagen la diferencia al utilizar el tipado estático que Mypy nos permite, como mencionaba en las líneas de arriba, se utiliza la sintaxis de anotaciones para tipos estáticos de Python, logrando con esto no afectar el rendimiento de nuestros scripts ni nos hace añadir códigos extraños y dotándonos de los beneficios de tener tipado estático en un lenguaje flexible y dinámico como lo es Python.

Instalando Mypy

Para instalar esta herramienta, debemos tener Python >= 3.3 y desde nuestra línea de comandos debemos ejecutar lo siguiente:


pip install mypy

Empezando con Mypy

Con Mypy contamos con dos tipos de anotaciones diferentes, la mencionada anteriormente (la sintaxis de anotaciones de tipos estáticos de Python) y la sintaxis utilizando comentarios. Veamos un ejemplo:

# Primero desde el módulo typing debemos
# importar los tipos que vamos a necesitar
from typing import List


# Utilizando la sintaxis de anotaciones
def sum_list_to_str(nums: List[int]) -> str:
    """Suma los números de una lista, y retorna el resultado como string"""
    return str(sum(nums))


# Utilizando comentarios
def sum_list_to_str_2(nums):
    # type: (List[int]) -> str
    """Suma los números de una lista, y retorna el resultado como string"""
    return str(sum(nums))

Para ejecutar los scripts con anotaciones de Mypy, podemos realizarlo utilizando cualquier intérprete de Python, esto se debe a que Mypy comparte esta excelente propiedad con el verficador de código de Javascript, Flow. Esto es grandioso ya que significa que podemos añadir Mypy a nuestros proyectos sin preocuparnos de como debemos correr estos proyectos con Python.

De igual manera, podemos utilizar Mypy como un linter, el cual puede mostrar nuestros errores en un formato agradable. Por ejemplo, vamos a cambiar el valor de retorno en nuestra segunda función para comprobar esto, quedando de la siguiente manera:

# Utilizando comentarios
def sum_list_to_str_2(nums):
    # type: (List[int]) -> int
    """Suma los números de una lista, y retorna el resultado como string"""
    return str(sum(nums))

Ahora, desde nuestra línea de comandos ejecutamos:


mypy mi_archivo.py

Output: mi_archivo.py:16: error: Incompatible return value type (got "str", expected "int")

Genial, ¿no crees? Gracias a esto será muy sencillo depurar nuestros scripts y evitar errores durante la ejecución que muchas veces se vuelven una pesadilla para reparar. Si te interesa profundizar sobre las anotaciones de tipo de Mypy, puedes consultar el Cheat Sheet de Mypy y también en PEP-484.

En resumen…

Utilizar Mypy es una excelente opción cuando:

  • Buscamos utilizar tipos estáticos en Python.
  • Verificar tipos en “tiempo de compilación”
  • Lograr un mantenimiento sencillo.
  • Buscamos que nuestro código sea simple de entender y más sencillo de modificar sin introducir “bugs”
  • Llevar nuestros scripts de dinámicos a estáticos.
  • Desarrollar nuestros scripts con tipado dinámico e ir añadiendo tipado estático conforme el código vaya madurando, o migrar código Python existente a tipado estático.
  • Declaraciones de tipo que actúen como documentación verificada por máquina.

Y bien, es todo por esta ocasión, espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Saludos.

Crear un blog con NodeJS y Hexo

crear un blog con nodejs

Crear un blog con NodeJS

Hola a todos, en esta entrada vengo a escribir sobre Hexo, una herramienta de línea de comandos que nos permitirá crear un blog con nodejs, y con esto, crear la estructura de un blog de forma muy sencilla.

crear un blog con nodejs

¿Qué es Hexo?

Bien, como en su propia página de documentación nos adelantan:

Hexo is a fast, simple and powerful blog framework. You write posts in Markdown (or other languages) and Hexo generates static files with a beautiful theme in seconds.

Como podemos apreciar Hexo nos permitirá crear un blog de una forma sencilla y rápida. Nos da la posibilidad de crear los post de nuestro blog utilizando Markdown (lo cual es grandioso) o algún otro lenguajes y generar archivos estáticos y con un hermoso tema en segundos.

Generando nuestro blog

Lo primero que debemos hacer es instalar hexo, para esto debemos tener instalado NodeJS previamente, y ejecutar alguno de los siguientes comandos:


# Utilizando npm

npm install -g hexo-cli

# Utilizando yarn (recomendado)

yarn global add hexo-cli

Con esto ya tendremos el binario de hexo listo para utilizar, ahora lo que debemos hacer es ejecutar el siguiente comando:


hexo init my_blog

Luego nos posicionamos en el directorio que nos ha creado el comando anterior:


cd my_blog

Instalamos las dependencias:


# Utilizando npm

npm install

# Utilizando yarn

yarn install

Si todo se instaló correctamente, simplemente ejecutamos el servidor de hexo:


hexo server

Ahora si navegamos a la url que nos muestra en la salida (http://localhost:4000/), podremos visualizar nuestro blog, que debería verse parecido a lo siguiente:

crear un blog con nodejsSencillo y rápido, ¿no? Cumplen lo que prometen 😀

Creando un post

Tal vez, te estás preguntando, ¿cómo se crean los post?

La respuesta es simple. Únicamente debemos ejecutar el siguiente comando:


hexo new post 'Titulo de tu post'

Donde debemos reemplazar ‘Titulo de tu post’ con el titulo que quieras que tenga tu post. Para realizar esto no es necesario que detengas el servidor de hexo. Y listo, solo debes comenzar a escribir el contenido de tu post en el archivo generado con el titulo que escribiste dentro de la carpeta source.

Y deberías tener un resultado como el siguiente:

crear un blog con nodejsSi desean saber más sobre este grandioso framework siempre pueden darle un vistazo a su buena documentación, que aunque aún tiene mucho por delante, es una buena opción si quieres algo simple y que te permita llevar a cabo el objetivo de un blog: escribir.

Y bien, es todo por esta ocasión, espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Saludos.

¿Qué es __name__ en Python?

¿Qué es __name__ en Python?

Hola a todos, ya llevo un rato sin escribir, esto se debe a que me encuentro pasando por muchas cosas personales, muy buenas, y me estoy enfocando en ellas, pero sin embargo tengo muchos borradores que espero ya terminar y publicar, como adelanto les puedo decir que tratan sobre Xamarin, Vue, Python y Ruby. Y bien, bienvenidos a esta entrada donde a petición de un usuario en FB voy a intentar explicar qué es __name__ en Python.

que es __name__ en python

Seguro que al estar leyendo un libro sobre Python, o leyendo el código de algún script de tu interés has visto algo como lo siguiente:


class MyComplexClass(object):
    def __init__(self):
    print("Hello World!")
    # Código de la clase con lógica demasiado compleja
    # ...

def init():
    my_complex = MyComplexClass()
    # Resto de la lógica del script
    # ...

if __name__ == '__main__':
    main()

Si eres curioso, o el libro donde viste esto es de un buen autor, seguro explicaron de que se trata, si no es tu caso, o buscando sobre el tema diste con el blog sigue leyendo, no te defraudaré 🙂

Pequeño paréntesis cultural

Muchos lenguajes de programación, normalmente los lenguajes compilados (llámese C, Java, Go, Rust, etc.), requieren de una función que actúe como punto de entrada, esto es, que será lo primero en ejecutarse al correr el programa. Comúnmente esta función de punto de entrada es main() (Espero haber sido breve).

Sigo sin saber qué es __name__ en Python

Lo sé, no desesperes, las líneas anteriores eran necesarias. Python, al igual que muchos de los lenguajes de script, ejecuta el código interpretando cada línea de arriba a abajo. Cuando el intérprete de Python encuentra el bloque if anterior (if __name__ == ‘__main__’), comprueba el atributo especial __name__, con el objetivo de ver si su valor actual es “__main__”.

Tiene sentido…al cumplirse esta condición, estaremos seguros de que nuestro módulo (script) es el primero en ser “cargado” por el intérprete de Python. Suponiendo que el código anterior esté almacenado en el archivo mi_super_script.py y lo ejecutamos:


python mi_super_script.py

El resultado será lo que este definido dentro de la función init(). Por lo tanto, aunque Python no especifica como tal, oficialmente una función de punto de entrada que será ejecutada en primer lugar, el bloque anterior es una forma “idiomática” de lograr el mismo objetivo.

Por lo tanto, con esto nos aseguramos de que ese código en especifico será ejecutado únicamente cuando nuestro script sea ejecutado, y no cuando sea importado. ¿A qué me refiero?


# mi_super_script.py
def main():
    print("Script 1!")

if __name__ == '__main__':
    main()

# mi_super_script_dos.py
import .mi_super_script

def init():
    print("Script 2!")

if __name__ == '__main__':
    init()

Si nosotros ejecutaramos ambos scripts, tendríamos la siguiente salida:


python mi_super_script.py

# Output: "Script 1!"

python mi_super_script_dos.py

# Ouput: "Script 2!"

Como podrás notar, a pesar de que en mi_super_script_dos.py estamos importando el código de mi_super_script.py la función main no ha sido ejecutada.

Generalmente no es útil sobreescribir el valor por defecto que el intérprete le otorga a __name__, pero existe un caso puntual donde esto se lleva a cabo con frecuencia: funciones decoradoras.

Voy a dejar ese tema para otra entrada si les interesa la relación que tienen con el atributo especial __name__ les sugiero leer esto y esto.

Y bien, es todo por esta ocasión, espero la explicación haya sido clara y cualquier comentario no dudes en dejarlo aquí abajo, o con confianza mencionalo por Twitter o en la Fanpage de Facebook, y aprovecho a invitarte para que me sigas en las redes y compartas el contenido del blog, con lo cual me harías un gran favor.

Saludos.