¿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.

Suma de matrices con Python

Suma de matrices con python

Hola a todos, bienvenidos a esta entrada, siguiendo la serie sobre operaciones con matrices en python, en esta ocasión veremos como llevar a cabo la suma de matrices con python.

Aprovecho para invitarte a que me sigas en mis redes Twitter o en la Fanpage de Facebook, donde podrás estar informado de nuevas entradas del blog, o si tienes alguna duda o comentario puedes decirmelo sin problema.

Operaciones con matrices en python

Hasta el momento las entradas de esta serie han sido las siguientes:

Creando la clase Base

Suma de matrices

Producto por un escalar

Producto de matrices (Pendiente)

Transpuesta (Pendiente)

Para esta entrada utilizaremos la clase base Matrix que realizamos en la entrada anterior.

Un poco de teoría

La suma de un conjunto de matrices A1, A2, …, An, es una de las operaciones más sencillas que se pueden realizar sobre esta estructura. Llevar a cabo esta suma depende en gran medida de que todas las matrices tengan igual dimensión y compartan el mismo valor para cada dimensión. Con esto, se da por entendido que no será posible sumar una matriz A de 3 x 2 con una matriz B de 4 x 2. Esto se justifica por la manera en que la suma de matrices se realiza.

El resultado de sumar dos matrices A y B es una nueva matriz C, que tiene en cada celda el resultado de sumar las correspondientes celdas de A y B, de modo que la primera celda de C, será C (0,0) = A (0,0) + B (0,0) y de manera general C (i,j) = A (i,j) + B (i,j) para todo par de indices válidos de A y B. Este procedimiento justifica el pre-requisito de que las dimensiones de todas las matrices coincidan. En resumen, la suma de n matrices se obtiene mediante la fórmula, C (i,j) = A1 (i,j) + A2 (i,j) + + An (i,j).

suma de matrices con pythonPuedes comprobar que los valores de las celdas de la primera fila de C coinciden con la suma de los valores de las celdas equivalentes en A y B.

5 = C (0,0) = A (0,0) + B (0,0) = 1 + 4

7 = C (0,1) = A (0,1) + B (0,1) = 2 + 5

9 = C (0,2) = A (0,2) + B (0,2) = 3 + 6

Pasemos al código

Para poder llevar a cabo la suma de matrices con python, el desarrollo del método suma queda de la siguiente manera:

def add(self, *matrix):
    """ Puede recibir varias matrices como argumentos """
    for i in range(self.rows):
        row = []
        for j in range(self.cols):
            tmp = self.get_value_of_position(i, j)
            for m in matrix:
                tmp += m.get_value_of_position(i, j)
            row.append(tmp)
        yield row

Como pueden observar, la función se implementa como un generador que retorna una fila (row) de la matriz C, cada que se alcanza la sentencia yield. Debo hacer mensión al ahorro de memoria que esto representa, ya que no estamos almacenando en memoria la estructura completa de C, lo cual es un beneficio cuando trabajamos sobre matrices de dimensiones considerables, esto se deriva de las bondades que nos brinda el uso de generadores.

Si visualizamos el código completo se encuentra de la siguiente manera:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# author: Gabriel Cueto <TheMushr00m - @Mushr00m_Dev>


class Matrix:
    _n = 0
    _m = 0
    _elems = None

    def __init__(self, n, m):
        """Inicializa la matriz con valor 0 en cada posición"""
        self._n = n
        self._m = m
        self._elems = []
        for i in range(self._n):
            self._elems.append([])
            for j in range(self._m):
                self._elems[i].append(0)

    def define_elem(self, i, j, v):
        """ Sobreescribe el valor de una celda """
        self._elems[i][j] = v

    def show_matrix(self):
        """ Imprime los valores almacenados en la matriz """
        for i in range(self._n):
            for j in range(self._m):
                # Imprime de una forma elegante la matriz
                print("| {0} ".format(self.get_value_of_position(i, j)), sep=',', end='')
            print('|\n')

    def get_cols(self):
        """ Devuelve el número de columnas en la matriz """
        return self._m

    def get_rows(self):
        """ Devuelve el número de filas en la matriz """
        return self._n

    def get_value_of_position(self, i, j):
        return self._elems[i][j]

    def add(self, *matrix):
        """ Puede recibir varias matrices como argumentos """
        for i in range(self.rows):
            row = []
            for j in range(self.cols):
                tmp = self.get_value_of_position(i, j)
                for m in matrix:
                    tmp += m.get_value_of_position(i, j)
                row.append(tmp)
            yield row

    cols = property(fget=get_cols)
    rows = property(fget=get_rows)

Recuerda que todo el código lo puedes encontrar en el repositorio en Github. Ahora, para poder ver en funcionamiento el método que creamos, podemos ejecutar algo como lo siguiente:

m1 = Matrix(3,3)
m1.define_elem(0,0,1)
m1.define_elem(0,1,2)
m1.define_elem(0,2,3)

m2 = Matrix(3,3)
m2.define_elem(0,0,4)
m2.define_elem(0,1,5)
m2.define_elem(0,2,6)

# Recorre el iterador generado
for e in m1.add(m2):
    print(e)

Seguro habrás observado, que la primera fila de m1 y m2 corresponden a los mismos valores mostrados en las matrices de la imagen de ejemplo A y B, la cual ilustraba la operación de suma de matrices. Por lo tanto, la primera fila del iterador resultante corresponde con la primera fila de la matriz C de la imagen. El resultado es el siguiente:


[5, 7, 9]
[0, 0, 0]
[0, 0, 0]

Y bien, es todo por esta ocasión, espero la explicación haya sido buena, 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.

Saludos.

Operaciones en matrices con Python – Creando la clase Base

matriz

Operaciones en matrices con Python

Hola a todos, luego de un tiempo sin escribir aquí les traigo esta entrada, la cual espero los ayude a entender este tema tan recurrente, como es el realizar operaciones en matrices con Python. En esta entrada veremos que es una matriz, y crearemos la clase que nos servirá de base para realizar las operaciones en las pr

Hasta el momento las entradas de esta serie han sido las siguientes:

Creando la clase Base

Suma de matrices

Producto por un escalar

Producto de matrices (Pendiente)

Transpuesta (Pendiente)

¿Qué es una matriz?

Las matrices son arreglos k-dimensionales donde se almacenan valores que pueden ser accedidos por indices. En las matemáticas, se conocen desde el año 200 a.C. y siempre han estado vinculadas al estudio de sistemas de ecuaciones. Toda una rama de esta ciencia está dedicada al estudio de matrices y durante mucho tiempo han sido ampliamente invetigadas.

Probablemente el caso más conocido de matriz se tenga cuando k = 2 (bidimensional), con n filas y m columnas, básicamente lo que se entiende por una tabla. A continuación podemos observar una matriz cuadrada donde n = m = 3.

operaciones en matrices con python

operaciones en matrices con python

Entre las operaciones más comunes en matrices se encuentran la suma, la resta y la multiplicación. Para comenzar el estudio de dichas operaciones, primero crearemos una clase matrix que represente a la estructura de datos y que en su momento servirá como contendor para diferentes funciones aplicadas sobre matrices.

#!/usr/bin/python
# -*- coding: utf-8 -*-
# author: Gabriel Cueto <TheMushr00m - @Mushr00m_Dev>


class Matrix:
    _n = 0
    _m = 0
    _elems = None

    def __init__(self, n, m):
        """Inicializa la matriz con valor 0 en cada posición"""
        self._n = n
        self._m = m
        self._elems = []
        for i in range(self._n):
            self._elems.append([])
            for j in range(self._m):
                self._elems[i].append(0)

    def define_elem(self, i, j, v):
        """ Sobreescribe el valor de una celda """
        self._elems[i][j] = v

    def show_matrix(self):
        """ Imprime los valores almacenados en la matriz """
        for i in range(self._n):
            for j in range(self._m):
                # Imprime de una forma elegante la matriz
                print("| {0} ".format(self.get_value_of_position(i, j)), sep=',', end='')
            print('|\n')

    def get_cols(self):
        """ Devuelve el número de columnas en la matriz """
        return self._m

    def get_rows(self):
        """ Devuelve el número de filas en la matriz """
        return self._n

    def get_value_of_position(self, i, j):
        return self._elems[i][j]

    cols = property(fget=get_cols)
    rows = property(fget=get_rows)

Como podrás observar, la matriz se inicializa con valor 0 en cada celda, y la modificación de estos valores tiene lugar mediante el método define_elem. Ahora es el momento de escribir el código para poder lograr nuestro objetivo, realizar operaciones en matrices. Esta de más decir, que los próximos métodos serán declarados como parte de la clase anterior.

Si deseas probar el código y visualizar como se genera la matriz, corre lo siguiente ya que tengas el código de la clase:

m = Matrix(3, 3)
m.show_matrix()

Espero el código de nuestra clase base haya quedado claro, si tienes alguna pregunta no dudes en hacerla en los comentarios, o mediante twitter.

Nuevamente te hago la invitación de que me sigas en mis redes, Twitter, Facebook, para que estes pendiente de nuevas entradas, charlas, proyectos, compartas contenido, etc.

Te pido una disculpa por si el código no se visualiza correctamente (sin identación), ya me encuentro trabajando en revisar esto, aunque creo que voy a enfocarme en el rediseño que estoy llevando a cabo para poder tenerlo pronto, sin embargo puedes encontrar todo el código en su repositorio de GitHub.

Gracias por leer la entrada, y no te pierdas las próximas donde realizaremos las operaciones con matrices. Saludos.

Primeros pasos con Axios

Consumiendo Servicios Web / REST APIs en Vuejs con Axios

Hola a todos, esta entrada es para actualizar lo visto en Realizando peticiones a un API con Vue. En esta ocasión tendremos nuestros primeros pasos con Axios, ya que como el mismo Evan You (creador de Vuejs) nos adelantaba, será retirado de los proyectos oficiales y se invita a utilizar librerías como Bluebird o Axios.

¿Qué es Axios?

Axios es un cliente HTTP basado en Promesas para Javascript, el cual puede ser utilizado tanto en tu aplicación Front-end, como en el Back-end con Nodejs. Utilizando Axios, es muy sencillo enviar peticiones a endpoints REST y realizar operaciones CRUD. Además, Axios puede ser utilizada desde una aplicación desarrollada con Javascript plano, al igual que utilizando un Framework como Vuejs. Para visualizar una lista completa con las caracteristicas de Axios, pueden visitar su página en Github, aunque aquí les menciono las que en mi opinión son las más importantes.

  • Realizar peticiones XMLHttpRequest (Ajax) desde el navegador de una manera sencilla.
  • Realizar peticiones HTTP desde Nodejs.
  • Soporta el API de Promesas.
  • Intercepta peticiones y respuestas.
  • Transforma la información de las peticiones y respuestas.
  • Cancela peticiones.
  • Transforma automáticamente la información en formato JSON.
  • Soporta protección del lado del cliente contra ataques CSRF (Cross-site request forgery).

En las próximas líneas, mi objetivo será que aprendas a instalar y añadir Axios a tu proyecto.

¿Qué vamos a realizar?

Para mostrar de forma más clara el tutorial, realizaremos una sencilla pero útil para el aprendizaje lista de posts. Pueden ver el acabado final en la siguiente imágen:

primeros pasos con axios - ejemplo

Primeros pasos con Axios…

Para añadir Axios, existen dos maneras:

Opción 1: Instalando Axios con Node Package Manager.

Para esto, sólo necesitas ejecutar uno de los siguientes comandos:


# Con npm

$ npm install -S axios

# Con yarn

$ yarn add axios

 

 

Con esto instalamos la librería dentro del directorio node_modules de nuestro proyecto.

Opción 2: Utilizando un CDN

La manera más sencilla de incluir axios es utilizando un Content Delivery Network, por ejemplo, incluyendo la siguiente etiqueta script en tu archivo index.html:


<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

 

 

Como lo que buscamos es probar la funcionalidad de Axios para el envío y recepción de información desde servicios web/ REST, necesitamos tener un backend, como esto está fuera del alcance de este tutorial, vamos a utilizar la instancia para pruebas del servidor JSON que se encuentra en http://jsonplaceholder.typicode.com/ la cual ofrece varios endpoints para pruebas.

Especificamente, haremos uso del endpoint http://jsonplaceholder.typicode.com/posts.

Implementación de la UI

Para esta entrada utilizaremos el siguiente código HTML:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Getting started with Axios</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/lumen/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="jumbotron">
<h1>Getting started with Axios and Vanilla javascript</h1>
<h4>This application uses Axios.</h4>
</div>
<h2>Axios Demo by <small>LaEsporaDelHongo.com</small></h2>
<div class="panel panel-primary">
<div class="panel-heading">GET Request</div>
<div class="panel-body">
<button class="btn btn-primary" onclick="getRequest()">Get Posts</button>
<button class="btn btn-warning" onclick="cleanResult(this)">Clear</button>
<div class="panel-body" id="getResult"></div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">GET Request with Parameters</div>
<div class="panel-body">
<input type="text" class="form-control" id="postId" placeholder="Post ID..." /><br>
<button class="btn btn-primary" onclick="getRequestWithParams()">Get Post</button>
<button class="btn btn-warning" onclick="cleanResult(this)">Clear</button>
<div class="panel-body" id="getResultWithParams"></div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">POST Request</div>
<div class="panel-body">
<form class="form-inline" id="postInputForm">
<div class="form-group">
<input type="text" class="form-control" id="postTitle" placeholder="Post Title..." />
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form><br>
<button class="btn btn-warning" onclick="cleanResult(this)">Clear</button>
<div class="panel-body" id="postResult"></div>
</div>
</div>
<div class="fotter">
<p>&copy; <a href="http://laesporadelhongo.com" target="_blank">LaEsporaDelHongo.com</a></p>
</div>
</div>
<!-- Axios Library -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
</body>
</html>

 

Se puede apreciar que utilizamos un tema de bootstrap, y añadimos las secciones de nuestra aplicación. También hacemos referencia al script de Axios y añadimos un archivo main.js donde se encuentran los métodos que vamos a utilizar.

Cada sección de la aplicación se encuentra definida entre los bloques de código:


<div class="panel panel-primary">...</div>

 

Cada sección contiene el código necesario para uno de los casos de uso de Axios que veremos a continuación, y que nos permitirá generar código utilizando la respuesta devuelta por el API. El código HTML de cada sección respectivamente:


<div class="panel-body" id="getResult"></div>

<div class="panel-body" id="getResultWithParams"></div>

<div class="panel-body" id="postResult"></div>

 

Donde la unica diferencia se encuentra en el atributo id de cada bloque.

El código JS que contiene el archivo main.js es el siguiente:


function generateSuccessHTMLOutput(response) {
return  '<h4>Result</h4>' +
'<h5>Status:</h5> ' +
'<pre>' + response.status + ' ' + response.statusText + '</pre>' +
'<h5>Headers:</h5>' +
'<pre>' + JSON.stringify(response.headers, null, '\t') + '</pre>' +
'<h5>Data:</h5>' +
'<pre>' + JSON.stringify(response.data, null, '\t') + '</pre>';
}

function generateErrorHTMLOutput(error) {
return  '<h4>Result</h4>' +
'<h5>Message:</h5> ' +
'<pre>' + error.message + '</pre>' +
'<h5>Status:</h5> ' +
'<pre>' + error.response.status + ' ' + error.response.statusText + '</pre>' +
'<h5>Headers:</h5>' +
'<pre>' + JSON.stringify(error.response.headers, null, '\t') + '</pre>' +
'<h5>Data:</h5>' +
'<pre>' + JSON.stringify(error.response.data, null, '\t') + '</pre>';
}

function cleanResult(e) {
// e.nextElementSibling it's the result container
e.nextElementSibling.innerHTML = '';
}

function getRequest() {
var resultEl = document.getElementById("getResult");
resultEl.innerHTML = "";
// We use Axios to perform a GET request
axios.get('http://jsonplaceholder.typicode.com/posts')
.then(function(response) {
console.log(response);
resultEl.innerHTML = generateSuccessHTMLOutput(response);
})
.catch(function(error) {
resultEl.innerHTML = generateErrorHTMLOutput(error);
})
}

function getRequestWithParams() {
var resulEl = document.getElementById('getResultWithParams');
var postId = document.getElementById('postId').value;
resulEl.innerHTML = '';
// We use Axios to perform a GET request with params
axios.get('http://jsonplaceholder.typicode.com/posts', {
params: {
id: postId
}
})
.then(function(response) {
console.log(response);
resulEl.innerHTML = generateSuccessHTMLOutput(response);
})
.catch(function(error) {
resulEl.innerHTML = generateErrorHTMLOutput(error);
});
document.getElementById('postId').value = '';
}

function getPostRequest(e) {
e.preventDefault();
var resultEl = document.getElementById('postResult');
var postTitle = document.getElementById('postTitle').value;
resultEl.innerHTML = "";
// We use Axios to perform a POST request.
axios.post('http://jsonplaceholder.typicode.com/posts', {
userId: '1',
title: postTitle,
completed: true
})
.then(function(response) {
console.log(response);
resultEl.innerHTML = generateSuccessHTMLOutput(response);
})
.catch(function(error) {
resultEl.innerHTML = generateErrorHTMLOutput(error);
});
document.getElementById('postTitle').value = '';
}
document.getElementById('postInputForm').addEventListener('submit', getPostRequest);

 

De este archivo, podemos observar que contamos con un par de funciones para generar código HTML, el cual será insertado en cada bloque mencionado anteriormente. También tenemos una función con la cual se limpian los elementos input, y las funciones con las cuales llevaremos acabo las peticiones al API.

Estas funciones cuentan con un sencillo código javascript, donde sólo cabe mencionar la sección de Axios:


# Get request

axios.get(url)

# Get request with params

axios.get(url, params)

# Post request

axios.post(url, params)

 

Axios en cada petición nos devuelve una promesa, la cual debemos manipular haciendo uso de los métodos .then/.catch para capturar la respuesta y los errores respectivamente.

Nota final con respecto a Vuejs

Para utilizar Axios con vuejs contamos con dos maneras de llevar acabo esto:


# Utilizando Axios de forma normal

import axios from 'axios'

axios.get(url)

# Utilizando Axios como si de Vue-resource se tratara.

import axios from 'axios'

Vue.prototype.$http = axios

this.$http.get(url)

Y bien, es todo por esta ocasión, pueden encontrar un ejemplo utilizando Vuejs y otro ejemplo con Vanilla js (el utilizado en esta entrada) en el siguiente repositorio. Cualquier duda o comentario no duden en escribirlo en la sección de abajo, o en Twitter. Si gustas apoyarme a seguir escribiendo como hasta ahora, comparte el blog con tus amigos, conocidos, colegas, en tus redes, donde gustes. O bien siguiendome en Twitter y dando like a la fan-page de Facebook. Hasta la próxima.