Uso de staticmethod en Python

logo python

En otros artículos he hablado de decoradores, en este, me referiré al uso de staticmethod en Python y sus características.

Todos sabemos que Python está orientado a objetos y que las clases son la base de su programación, por eso el uso de decoradores es una ayuda importante en el manejo de estas.

staticmethod es un decorador que nos permite usar una funcion dentro de una clase sin que esta reciba argumentos.

Otros artículos sobre decoradores

Su forma de escribirlo, es colocando una arroba delante

@staticmethod

Este decorador permite llamar a una clase, aunque esta aun no haya sido convertida en un objeto.

Veamos un ejemplo, que ya he empleado al hablar de decoradores antes:

class boxeador(object):
    def __init__(self):
        pass
    @staticmethod
    def esquina():
        print("Has tenido suerte, tu esquina aun no tiene color")

def main():
    b = boxeador()
    b = b.esquina()
    

if __name__ == '__main__':
    main()

Como ven hemos podido llamar a esquina() sin que esta tenga ningún parámetro.

 Si eliminamos el decorador recibiríamos este error:

TypeError                                 Traceback (most recent call last)
<ipython-input-22-0a10128b3e82> in <module>
     12 
     13 if __name__ == '__main__':
---> 14     main()

<ipython-input-22-0a10128b3e82> in main()
      8 def main():
      9     b = boxeador()
---> 10     b = b.esquina()
     11 
     12 

TypeError: esquina() takes 0 positional arguments but 1 was given
'

Esto nos está indicando un error de tipo, que nos dice que a pesar de que la función esquina no tiene argumentos (parámetros),  la hemos llamado como si lo tuviera.

Y hasta aquí, como siempre espero que sirva de ayuda a alguien.

Un saludo

Entrena duro y en silencio, que el éxito sea tu grito

D

Cambiar el nombre a una columna con Pandas

logo python

Las vías que conozco,  para cambiar el nombre a una columna son tres . Podemos hacerlo con el método rename(), el cual puede aplicarse directamente a la columna, o pasarlo a través de una funcion lambda.

Ojo, es posible que haya más posibilidades, me refiero a las que uso y conozco.

Cambiar el nombre a una columna con Pandas

El método rename(),  se utiliza justo para modificar la etiqueta de los ejes, al aplicarlo nos devolverá un nuevo dataframe con los valores aplicados. Su sintaxis es:

dataframe.rename(mapper=None, index=None, columns=None, axis=None, copy=True, inplace=False, level=None, errors='ignore')

maper: Ya sea un diccionario o una función , indica las transformación a aplicar  al eje dado. Este parámetro y el eje se emplean para indicar que valores y ejes recibirán el cambio.

index: Nos permite establecer el eje. Si empleamos maper, index =0 , es lo mismo que maper = index

columns: Indica las columnas, si su valor es cero o se ignora, significa que es el mismo que maper.

axis: tiene por defecto el valor 0, que indica el índice, el valor 1 indica columnas. Pueden emplearse colocando el nombre del eje(índice, columnas), o el numero (0,1). El valor que recibe por defecto es el del índice.

copy: Su valor determinado es True, y esto garantiza copiar también los datos subyacentes.

inplace: valor por defecto False, si se convierte a True, al devolver el nuevo dataframe la copia anterior se ignora.

level: valor por defecto None, indica el numero o nombre del nivel. Si existen índices multiples solo modificara en el nivel indicado.

error: acepta raise o ignore, y ese último es su valor por defecto. Ignora el error del tipo keyerror, cuando index o columns contienen etiquetas que no existen.

Tenemos el siguiente dataframe:

Aplicándolo directamente seria algo asi:

Renombramos varias columnas usando mapping en las columnas Unnamed: 0 e Ischaemic heart disease, para ello pasamos los valores nuevos, en forma de diccionario.

Renombremos ahora los indices

Esto también podría lograrse escribiendo

data_df.rename({0: 'Año1', 1: 'Año1', 2: 'Año3'}, axis='index')

Incluso podemos cambiar el estilo :

A través de una función lambda:

Y esto es todo

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

…. hay que levantarse cada mañana con una esperanza y dormirse cada noche con una meta….

Y

Análisis de regresión simple.Python

logo python

En este post realizaré un análisis de regresión, en el que tomaremos una set de datos preparado previamente.

El problema real al que nos enfrentamos, es determinar la relación que pueda existir entre la cantidad de ventas de la empresa “El Dorado”, y el numero de vendedores que la han integrado durante el periodo que se estudia, que son 36 meses o sea los últimos 3 años.

El departamento ha cambiado de responsable en varias ocasiones, y cada uno ha aplicado políticas diferentes de ventas, algunas intensivas, buscando mayor productividad en las ventas, a bases de estímulos como bonos, primas, ascensos,  etc; y en otras ocasiones, en cambio,  se han aplicado medidas extensivas incrementando el numero de vendedores, en una afán por ampliar la cobertura de ventas.

Lo que vamos a hacer es implementar un análisis de regresión lineal.

La regresion lineal es una técnica estadística, que el machine learning adoptó y que incluye como uno de los algoritmos supervisados.

He escrito hace unos meses algún articulo sobre regresion lineal y resumiendo lo que hara este análisis es obtener una recta que se acerque lo mas posible a todos los puntos de datos representados en un plano.

En nuestro caso es una regresion simple (participan dos variables ) y la recta que buscamos obtener es, la mejor posible.

Esto quiere decir que de todas las rectas esta sea la que mejor se adapte al conjunto de puntos, lo que le permitirá tendencialmente  estimar o predecir valores, dentro del contexto de datos estudiados.

La recta tiene forma esta forma Y = mX + b;  donde Y es el resultado obtenido, X es la variable, m la pendiente (o coeficiente) de la recta y b el valor constante, que gráficamente expresa el “punto donde cuando X tiene valor cero, se produce la intercepción o corte con el eje Y.

 Su optimización o ajuste se logra aplicándole una función llamada de mínimos cuadráticos, o también conocida de error cuadrático.

Su nombre obedece a que esa funcion intenta minimizar el error existente entre los puntos o dados y los obtenidos, elevendo al cuadrado sus valores para evitar que se anulen.

De este modo el algoritmo, se centra en minimizar el coste de dicha función

Recordemos que los algoritmos de Machine Learning Supervisados, aprenden por sí mismos.

Utilizaremos un archivo de datos que ya tenemos, y que muestra el número de  ventas y vendedores por meses; o sea tendremos dos columnas: vendedores y ventas.

Y nuestro en nuestro análisis de regresión, lo que vamos a intentar  es determinar a partir de los vendedores que tenemos,  que valor podemos esperar en la ventas de acuerdo, a la relación dada entre ambas variables.

Trabajaremos con Jupiter Notebook,utilizaremos las librerías Pandas, SkLearn, Seaborn, Numpy, de modo que comenzaremos por ahí.

Importamos las librerías

Cargamos nuestro archivo en un dataset de pandas después de leerlo, definiendo el separador de columnas.

Adquirimos  la información de nuestro dataset, con el método info(). Observamos que tenemos dos tipos de datos : enteros en columna vendedores y decimales en la columna ventas.

Comprobamos la estructura del dataset, con el método shape, que nos dice que tenemos efectivamente dos columnas y 36 registros en cada una.

Con head(), visualizamos las 6 primeras filas de nuestro dataset

Convertimos por comodidad la columna venta a tipo entero, empleando el método astype() y guardamos esa transformación en un nuevo dataset, que es con el que continuaremos trabajando.

Definimos con columns(), los encabezados de las columnas

Obtenemos los valores estadísticos de nuestro dataset con el método describe()

Observamos entre otros valores,  que la media de vendedores es 23, con una desviación de 4,63; mientras que la de ventas es 42 millones y su desviación es de 7.12.

Visualizamos los datos, en gráficos, mostrando las columnas por separados

Empleando scatter mostramos  los puntos coloreados, separando los colores a partir de la media de vendedores (23)

En este punto creamos nuestra recta de regresion y visualizamos los coeficientes que la componen nuestra recta.

Nuestro error cuadrático no es elevado pero es alto y nuestra varianza esta más cerca de 0 que de 1, por lo que este modelo tal vez podría mejorarse.

La intersección (b), tiene un valor de 9,67…. donde se corta la recta cuando el valor en X es 0

En función de observar el comportamiento del modelo, asignamos valores diferentes para ver su comportamiento

Ahora visualicemos la recta dentro de nuestro gráfico

Podemos observar nuestros datos de diferentes formas, en este caso con la librería seaborn, vemos el comportamiento de los datos en los diferentes periodos y su relación.

Para mejorarla tenemos varios caminos, podemos aplicar métodos como el gradiente, podemos hurgar en los datos y añadir más variables predictivas, referidas por ejemplo a la competencia, la innovación o la aceptación de los productos, pasando de una regresión simple a una regresión múltiple, podríamos también ampliar la cantidad de registros buscando mas años, desechar los valores extremos, etc.

En otros artículos iré aplicando algunos de estos métodos, haciendo referencia a estos mismos datos.

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

«El amor es la guerra perdida, entre el sexo y la risa»

R.Arjona

Calcular el porcentaje de una columna en pandas

logo python

Veamos como  calcular el porcentaje de una columna en Pandas, para lo cual usaremos sus propia función sum()

Como sabemos Pandas trabaja con dataframes o marcos de datos y también queda claro, que el porcentaje se obtiene dividiendo  el valor total entre  la suma de todos los valores y luego multiplicando ese resultado por 100.

Lo que hacemos, no es otra cosa que aplicar este mismo procedimiento a la columna que deseamos analizar.

Primero sumaremos toda la columna con sum(), que es el método que se emplea para sumar en Pandas.

La sintaxis seria esta:

df [porcentaje] =(df ['resultado'] / df ['column_a_sumar'].sum()) * 100

Otros post sobre Python

Viéndolo en un ejemplo practico seria esto:

import pandas as pd 
import numpy as np 

#tenemos una matriz accesorios con dos columnas (periodos y cantidad)   
accesorios = { 
     'periodos': ['periodo_1', 'periodo_2', 'periodo_3', 
             'periodo_4', 'periodo_5', 'periodo_6', 
             'periodo_7'], 
     'cantidad': [100, 40, 47, 78, 89, 78, 64]} 

# instanciamos accesorios como un dataframe de pandas,
# y definimos sus columnas
   
accesorios = pd.DataFrame(accesorios,  
                   columns = ['periodos', 
                             'cantidad']) 
# calculamos la columna porcentaje, la cual se añade automaticmente # al dataframe accesorios. Dividimos la cantidad entre la suma de 
# la columna y la multiplicamos por 100
accesorios['porcentaje'] = (accesorios['cantidad'] / 
                  accesorios['cantidad'].sum()) * 100
  
accesorios

Como ven hemos calculado el porcentaje de la columna para saber que magnitud del total representa cada período.

La salida es:

Out[1]:
	periodos	cantidad	porcentaje
0	periodo_1	100	20.161290
1	periodo_2	40	8.064516
2	periodo_3	47	9.475806
3	periodo_4	78	15.725806
4	periodo_5	89	17.943548
5	periodo_6	78	15.725806
6	periodo_7	64	12.903226

Y esto es todo, espero ayudar a alguien con este post.

No discutas nunca con un imbécil, te llevará a su terreno y allí te ganará por experiencia

D.

Pickle. serializar datos con Python

logo python

Al manejar datos, de gran volumen, que necesitamos por ejemplo guardar en archivos, para manejarlos con mayor facilidad, lo màs adecuado es emplear un modulo como Pickle, para serializarlos. 

El modulo pickle de Python, de que hablaré en ese post,  lo que hace es, serializar objetos para que puedan guardarse en un archivo y tener la opción de volver a cargarlos más adelante.

pickle() se utiliza para serializar y deserializar estructuras de objetos de Python,  esta acción es también conocida cómo clasificación o aplanamiento de los datos.

La serialización, en su explicación más simple no es otra cosa que  convertir un objeto que tenemos en la memoria, en un flujo de bytes que se puede almacenar en el disco o enviar a través de una red,  y que puede ser posteriormente recuperado, transformándolo nuevamente en un objeto Python deserializado.

Las ventajas de serializar nuestros datos, no es solamente que se puedan guardar en el disco para continuar trabajando con ellos, y que podamos también enviar nuestros datos a otros por TCP, o una conexión de socket.

Pickle es igualmente poderosa porque a través de ella podemos almacenar objetos de Python en una base de datos.

Sobre todo cuando trabajamos con algoritmos de aprendizaje automático, conocer su uso nos evitará tener que reescribir todo o entrenar el modelo nuevamente, ya que podemos guardarlos y recuperarlos cuando queramos.   

Datos

Pickle(), nos permite  serializar los siguientes datos:

Cadenas,

Listas,

Tuplas

Enteros

Flotadores

Booleanos,

Números complejos,

Diccionarios que contienen objetos serializables.

Dataframes

 Pickle(), también puede serializar las clases y funciones, incluso las lambdas.  En el caso de estas últimas se usa dill(), un paquete adicional diseñado para ello, a partir de un fork de multiprocessing(), el paquete de multiprocesamiento de Python

A pesar de su capacidad, elementos como los dict predeterminados, las clases internas, o los generadores pueden tener problemas para ser serializados.

Los dicts predeterminados, necesitan ser creados con una función a nivel de módulo.

Serializando archivos

Importamos pickle()  

import pickle

Creamos un diccionario  y luego estructuramos un archivo de salida llamado alumnos_dic.

#escribimos un diccionario sencillo
alumnos_dict = {'Jose': 7,'Arnoldo': 8,'Mario': 5, 'Maria': 78,'Amara': 50,'Rolando': 67,'Hemeregildo': 78,'Prudencio': 79,'Zoraida': 0}

Abrimos un archivo utilizando la función open(), para poder escribirlo en formato binario. En este articulo, puede leerse un poco mas sobre las opciones para usar open().

#abrimos nuestro archivo para escribir en formarto binario
alumnos_pick= open('alumnos', 'wb')

Serializamos el archivo inicial y obtenemos un nuevo objeto file, luego cerramos la conexión

#usamos dump para serializar
pickle.dump(alumnos_dict, alumnos_pick)
alumnos_pick.close()

Deserializar nuestro archivo

El proceso de volver a cargar un archivo serializado en Python, no es complejo.

Usaremos la función open () nuevamente, pero esta vez con 'rb' como segundo argumento.

alumnos_pick.close()

Lo que haremos será leer el formato binario con que serializamos anteriormente.

#usamos dump para serializar
pickle.dump(alumnos_dict, alumnos_pick)
alumnos_pick.close()

Asignamos su valor  a infile.

infile = open('alumnos','rb')

Para cargar el archivo utilizamos pickle.load (), con infile como argumento, al que asignaremos  a nuevo_alumnos.

nuevo_alumnos = pickle.load(infile)

El contenido del archivo ahora está asignado a esta nueva variable.

Nuevamente,  cerramos  el archivo al final.

infile.close()
nuevo_alumnos
output:{'Jose': 7, 'Arnoldo': 8, 'Mario': 5, 'Maria': 78, 'Amara': 50, 'Rolando': 67, 'Hemeregildo': 78, 'Prudencio': 79, 'Zoraida': 0}

Comparamos los archivos.

#comparamos ambos archivos
print(nuevo_alumnos==alumnos_dict)
print(type(nuevo_alumnos))
output: True 
<class 'dict'>

Comprimir archivos

Si el tamaño del archivo es grande, por ejemplo datasets, voluminosos, podemos ahorrar espacio comprimiendo, el archivo deserializado.

Hay diferentes vías, dos de ellas son bzip2 y gzip.  Puede ver otras en este articulo.

Su diferencia en esencia, radica en que  gzip  es más rápido, pero los archivos que crea bzip2, ocupan  la mitad de espacio que los que crea gzip.

Una cuestión importante y que puede tender a confundir es que deserializar, no es lo mismo que comprimir.  

La deserialización es la conversión de un objeto de una representación (datos en la memoria de acceso aleatorio (RAM)) a otra (texto en el disco); mientras que la compresión es el proceso de codificación de datos con menos bits, para ahorrar espacio en el disco.

Lo primero es importar bz2

import bz2

Luego como primer parámetro del método BZ2File, pasaremos el nuevo nombre del nuevo archivo compactado que se creará al ejecutarse el script

sfile = bz2.BZ2File('compress_alumnos', 'w')
pickle.dump(alumnos_dict, sfile)

Multiproceso

Pickle es especialmente sensible al multiprocesamiento, pues hay elementos como las funciones lambda que no pueden ser fácilmente serializadas.

Cuando necesitamos realizar tareas complejas que ocupan mucho espacio de memoria, es común distribuir esta tarea en varios procesos.

El multiprocesamiento, es la subdivisión de un proceso en varios que se ejecutan simultáneamente, generalmente en varias Unidades Centrales de Procesamiento (CPU) o núcleos de CPU, ahorrando tiempo, como es el caso de operaciones de entrenamiento de modelos de aprendizaje automático, la creación de redes neuronales, todos ellos procesos intensivos.

En Python, esto se hace usando el paquete de multiprocesamiento multiprocessing().

La ventaja de trabajar de esta forma, es que los procesos en que se divide una tarea no comparten espacio de memoria, y comparten datos entre ellos serializados 

En el ejemplo lo que haremos será crear una especie de abstracción llamada pool, para que trabaje en segundo plano procesando una tarea, y al que indicaremos cuantos procesadores empleará para ello.

#trabajando con multiprocesamiento
#importamos el modulo y creamos con la la funcion cos una tarea
import multiprocessing as mp
from math import cos
p = mp.Pool(2)
p.map(cos, range(10))
output:[1.0, 0.5403023058681398, -0.4161468365471424, -0.9899924966004454, -0.6536436208636119, 0.2836621854632263, 0.9601702866503661, 0.7539022543433046, -0.14550003380861354, -0.9111302618846769]

Si quisiéramos ejecutar en vez de cos() un lambda, nos lanzara un error, indicando que Pickle no puede serializar un lambda.

p.map(lambda x: 2**x, range(10))
output: .......
PicklingError: Can't pickle <function <lambda> at 0x7fe84683a830>: attribute lookup <lambda> on __main__ failed

Afortunadamente existe un modulo para resolver esto dill(), que pertenece a un fork, llamado pathos.multiprocessing

Pathos esta en desarrollo aun, y debe ser instalado desde github, según recomendaciones de su creador. Puedes ver este articulo en stackoverflow

El amor siempre empieza soñando y termina en insomnio

R.Arjona

Trabajar con el modulo re() de Python

logo python

Python tiene un módulo llamado re() para trabajar con las RegEx. Trabajar con el modulo re(), no es complejo.

Pueden ver un articulo que escribí hace un tiempo, sobre ello.

En Python, existen herramientas especificas, que funcionan como auxiliares y modificadores para el trabajo con las RegEx.

Me refiero tanto al uso del modulo re() , como al empleo de r o R antes de una RegEx como prefijo.

Cuando se escribe una expresión regular y se coloca el \ delante de ella, este equivale a un escape del carácter que le sigue, de este modo \n o \r provocará que el lenguaje escape estos caracteres; sin embargo cuando colocamos r delante, estos serán considerados y tratados como un carácter normal.

La sintaxis para esto, es por ejemplo r’[\n\r]’

Veamos como usar re()

re.findall()

Nos devuelve una lista de todas las cadenas que contienen la coincidencias

import re

cadena = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
pattern = '\D+'
buscamos todos aquellos caracteres que no sean digitos con re.findall()
coincid = re.findall(pattern, cadena)
coincid
ouput:['Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.']

pattern = '\d+'
output:[]

re.split()

Separa las cadenas donde existen las coincidencias y retorna una lista de  cadenas donde hay coincidencias.

pattern = '\D+'
cadena = 'amigos 12345 45:67'
#separamos las palabras de la cadena con re.split()
coincid = re.split(pattern, cadena)
coincid
output: ['', '12345', '45', '67']
pattern = '\d+'
output:cadena = 'amigos 12345 45:67'

#separamos las palabras de la cadena con re.split()
coincid = re.split(pattern, cadena)
coincid
output:['amigos ', ' ', ':', '']

Como se ve en el ejemplo se puede usar maxsplit para determinar el numero máximo de separaciones que deseamos que ocurran.

#utilizamos maxsplit 1
pattern = '\D+'
cadena = 'amigos 12345 45:67'
coincid = re.split(pattern, cadena, 1)
coincid
output:['', '12345 45:67']

#utilizamos maxsplit 3
pattern = '\D+'
cadena = 'amigos 12345 45:67'
coincid = re.split(pattern, cadena, 3)
coincid
output:['', '12345', '45', '67']

Re.sub()

Devuelve la cadena donde existe coincidencia y reemplaza el contenido con el valor de la variable replace.

#sustituimos en la cadena los valores con re.sub()
cadena = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
pattern = '\s+'
replace = ','
nueva_cadena = re.sub(pattern, replace, cadena)
nueva_cadena
out:'Cuanto,hice,hasta,hoy,,y,haré,,es,para,eso.,En,silencio,ha,tenido,que,ser,y,como,indirectamente,,porque,hay,cosas,que,para,lograrlas,han,de,andar,ocultas,,y,de,proclamarse,en,lo,que,son,levantarían,dificultades,demasiado,recias,para,alcanzar,sobre,ellas,el,fin.'

Podemos contar  utilizando count() como cuarto parámetro, para determinar cuántos reemplazosharenmos.

Si omitiéramos el valor sub(), reemplazará todas las coincidencias.

#añadiendo count() como parametro
string = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
pattern = '\s+'
replace = ','
nueva_cadena = re.sub(pattern, replace, string, 5)
nueva_cadena
output:'Cuanto,hice,hasta,hoy,,y,haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'

re.subn()

Es similar a sub(), pero devuelve una tupla con contiene la nueva cadena y la cantidad de sustitucones realizadas.

#empleamos re.subn(), para obgener una tupla que contiene la nueva cadena y la cantidad de substituciones realizadas
cadena = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
pattern = '\s+'
replace = ','
nueva_cadena = re.subn(pattern, replace, cadena)
nueva_cadena
output: ('Cuanto,hice,hasta,hoy,,y,haré,,es,para,eso.,En,silencio,ha,tenido,que,ser,y,como,indirectamente,,porque,hay,cosas,que,para,lograrlas,han,de,andar,ocultas,,y,de,proclamarse,en,lo,que,son,levantarían,dificultades,demasiado,recias,para,alcanzar,sobre,ellas,el,fin.', 44)

re.search()

Se emplea para la búsqueda de coincidencias directamente, utilizando dos argumentos, el patrón a buscar y la cadena donde buscarlo.

Su resultado es un objeto match, si no hubiera coincidencia retornaría None.

#empleamos re.search(), para hallar la subcadena silencio
sustituimos en la cadena los valores con re.sub()
cadena = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
busqueda = re.search('silencio',cadena)
busqueda
output:<re.Match object; span=(47, 55), match='silencio'>

El objeto que nos devuelve la variable búsqueda es del tipo match, con el cual podemos hacer también varias operaciones.

#operando con el resultado, ahora buscamos silencio al final de una cadena y hacemos algo
adena = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
busqueda = re.search('\Zsilencio',cadena)
if busqueda:
pass
else:
print('no se halló nada')
output:no se halló nada

Con re(), podemos buscar utilizando re.match(), que  recibe dos parámetros: los patrones que buscamos y el texto donde los buscamos.

match.group()

Nos permite agrupar los resultados en subcadenas.

#buscamos con match.group() el grupo de letras seguidas por una r
cadena = 'Cuanto hice hasta hoy, y haré, es para eso. En silencio ha tenido que ser y como indirectamente, porque hay cosas que para lograrlas han de andar ocultas, y de proclamarse en lo que son levantarían dificultades demasiado recias para alcanzar sobre ellas el fin.'
pattern = '(a|e|i)r'
match = re.search(pattern, cadena)
if match:
print(match.group())
else:
print('no se halló nada')
output:ar

#buscamos un grupo que tiene dos digitos separados por un espacio de una cadena no digital de seis caracteres
cadena = '234 567896 10 acceso dni color de los ojos'
pattern = '(\d{2}) (\D{6})'
match = re.search(pattern, cadena)
if match:
print(match.group())
else:
print('no se halló nada')
output: 10 acceso

Podemos condicionar cuantas subcadenas queremos y sus posiciones

#imprimiendo solo el primer subgrupo
match = re.search(pattern, cadena)
if match:
print(match.group(1))
else:
print('no se halló nada')
output:10

#obteniendo la posicion donde comienza el grupo, donde termina y una tupla con ambos valores
match = re.search(pattern, cadena)
if match:
print(match.start(), match.end(), match.span())
else:
print('no se halló nada')
output:11 20 (11, 20)

Match.string

Nos devuelve la cadena.

match.string
output:'234 567896 10 acceso dni color de los ojos'

«En total oscuridad cualquier cosa, puede ser luz»

Uso de classmethod en Python

logo python

En este post  intentaré explicar de forma sencilla el uso de classmethod en Python y las ventajas que nos ofrece dentro de la programación orientada a objetos.

Classmethod es lo que se llama en Ptyhon un decorador.

Los decoradores en Python son funciones que nos permiten o facilitan determinadas acciones, alteran, modelan o decoran, de ahí su nombre como se comportan otras funciones cuando van precedidas por ellos.

Los decoradores se escriben colocando una arroba delante, por lo que en nuestro caso seria algo asi:

@classmethod

Este decorador permite llamar a una clase, aunque esta aun no haya sido convertida en un objeto.

Veamos un ejemplo sencillo:

class boxeador(object):
    def __init__(self):
        pass
    @classmethod #nos permite usar esta funcion sin que la clase haya sido atribuida a un objeto
    def esquina(cls, color):
        print("Has tenido suerte, tu esquina es de color {}".format(color))

def main():
    color = input('El color que deseas es:')
    boxeador.esquina(color) #llamado de la funcion

if __name__ == '__main__':
    main()

Como ven hemos podido llamar a esquina() sin que esta haya sido atribuida a un objeto especifico.

Otros posts sobre Python

 Si eliminamos el decorador recibiríamos este error:

TypeError                                 Traceback (most recent call last)
<ipython-input-19-6d278ca6f532> in <module>
     11 
     12 if __name__ == '__main__':
---> 13     main()

<ipython-input-19-6d278ca6f532> in main()
      8 def main():
      9     color = input('El color que deseas es:')
---> 10     boxeador.esquina(color) #llamado de la funcion
     11 
     12 if __name__ == '__main__':

TypeError: esquina() missing 1 required positional argument: 'color'

O sea nos da un error de tipo, indicando que falta un argumento de posición llamado color, que no hemos asignado a ningún objeto.

Y hasta aquí, y como siempre espero que sirva de ayuda a alguien.

Un saludo

…Y todo, como el diamante, antes de luz , fue carbón

J. Martí

Encontrar la intersección en dos diccionarios en Python 3

logo python

Podemos  trabajar con intersección en dos diccionarios en Python 3, empleando el método keys.

La forma de expresarlo seria algo como esto

un_dict.keys () & otro_dict.keys 

Lo cual devolverá las claves comunes de los dos diccionarios como un conjunto.

Esta funcionalidad existía desde  Python 2.7, usando el método dict.viewkeys ().

La forma de usar  el list comprehension sería:

[key for key in some_dict if key in another_dict]

Pueden existir otras formas, una que conozco es  emplear el  contains(), pero considero estas menos recomendable.

Su forma es esta

filter (another_dict.__contains__, some_dict.keys())

Espero que sirva de ayuda a alguien.

Más sobre Python en mi blog

Muchas gracias

….un sueño es casi todo  y más que  nada, más que todo al soñarlo, casi nada después……

J.A. Buesa

El método pop() en Python.

logo python

El método pop() elimina y retorna un elemento de una lista.
Puede emplear un parámetro opcional,  que el índice del elemento que desea eliminar de la lista.

Si no se especifica ningún índice, pop() elimina y retorna el último elemento de la lista.
Si el índice especificado en el método pop() no está en el rango de la lista, lanzara el error- IndexError: pop index out of range exception. 

lista = [1,2,3,4,56,'a','er','soso',False,True]
lista.pop()
output
True

Espero modestamente que este artículo, sirva de ayuda a alguien.

Gracias

No podía despreciarlo, era el ultimo brindis de un bohemio por una reina

Translate »