Uso de issubclass()

logo python

En Python, issubclass(), es utilizado para conocer la herencia y relación que existe entre dos o más clases.

En el ejemplo creamos una clase llamada Planeta y una subclase que lleva el nombre de Continente.

Lo que haremos luego,  es verificar la relación que existe entre ellas

«…he olvidado ya el lugar de donde vengo y puede que no exista el sitio adonde voy…..»

J.Sabina

Diferencia entre número de coma flotante y decimal

logo python

5 y 5.0 no son iguales desde el punto de vista de la programación. A diferencia de otros lenguajes,  en Python es importante conocer la diferencia entre número de coma flotante y decimal.

Cuando pasamos un dato a Python, este  intenta determinar a que tipo de dato corresponde

 La lógica que aplica Python, es considerar que si haces una división entre enteros, estas esperando un entero como resultado, y eso es lo que ofrece.

Pero si lo que esperamos es un resultado en fracción, hay que decirle a Python que al menos uno de elloslo es, haciendo una declaración del tipo  foo  = x.0

Entonces si , el  lenguaje retornará un valor del tipo flotante, al dividir. 

En Python 3, esto ya funciona de modo automático, e incluso sin colocar el punto devolverá un flotante, por una cuestión de optimización del funcionamiento del lenguaje.

 Una forma de ayudar a Python, es indicando que uno de los elementos de la división es del tipo float, haciendo una conversión sencilla del tipo z = float (x) / y  de modo que transformamos el valor  de x en un número de coma flotante, antes de operar con el.  

Este comporamientos heredado de C, tiene su base en la diferencia que existe al operar a bajo nivel con números enteros, de coma flotante o decimales.

Conocer esta diferencia sobre todo  nos hará entender mejor lo que hacemos.

Los números de coma flotante, no representan todas las  fracciones decimales, sino que algunas son redondeadas; sin embargo el  Decimal, es capaz de representar estas, obedeciendo al limite de precisión qué le indiquemos. 

La diferencia entre coma flotante y decimal

Coma flotante

Como decía antes, los números de coma flotante obvian ciertas representaciones.

Estos se componen de un signo, ya sea negativo o positivo, la mantisa, que es el número binario de un solo dígito seguido por una parte fraccional y el exponente que indica en qué lugar se ubica la coma decimal.

Por ejemplo, el número 1,25 tiene signo positivo, una mantisa de 1,01 (en binario) y un exponente de 0.

 El número 5 también es positivo, y posee la misma mantisa,  y su exponente es 2, pero cómo hay que multiplicar su mantisa por 4 (2 a la 2); 1,25 x 4 vale 5.

Hay que decir que la norma IEEE 754, que define el tratamiento de los números con coma flotantes, esta presente en casi todos los sistemas. 

Debido a esto es lógico, que el tipo de datos de coma flotante basados en  C doublé, es común que aparezca implementado en un número de 64 bits del IEEE 754, que al mismo tiempo emplea un espacio de  52 bits para la mantisa.

Esto equivale a  que las cifras de coma flotante, sólo se pueden definir  hasta 54 bits de precisión.

Todo lo que exceda de ese espacio, será recortado,.

El problema surge cuando se requiere o se posee una salida en base 10, que como sucede a menudo con fracciones en base 10, estas son del tipo periódico en base 2.

Entonces como expresar estas fracciones periódicas, sin exceder los 52 bits pues creando una ligera imprecisión, que puede acarrear inexactitudes importantes a la larga.

Muchas veces esto es imperceptible y puede dejarse pasar. Si consideramos la magnificencia de C al devolver los datos, y la poca falta que puede hacernos una exactitud rigurosa, puede no ser necesario incluso considerarlo.

No obstante en cálculos aritméticos exigentes, esta omisión puede requerir soluciones complejas.  

 Decimal

Decimal, es un modulo creado para resolver esta situación.

Posee en su estructura las clases Decimal y Context, que le aportan una estructura útil, para los que extrañaban algo así en Python 2.

Las instancias de estas clases, se reparten la responsabilidad de ofrecer una solución robusta para construir el redondeo.

Mientras la clase Decimal representa a los números; Context se usa para agrupa aquellas propiedades, que definirán el resultado esperado, como son el modo de redondeo y la precisión

Una vez creado el numero es inmutable, por lo que no puede cambiarse su valor, y  es muy ductil ya que las instancias de Decimal se pueden crear a partir de enteros, cadenas y tuplas:

import decimal 
decimal.Decimal(567)
Decimal("1972")
>>>decimal.Decimal("9.8")
Decimal("1.1")

En el caso de las tuplas, se puede complejizar un poco mas y ofrecerle a Python en una tupla el signo, la mantisa como tupla de dígitos decimales, y el exponente:

>>> decimal.Decimal((1, (2, 3, 2, 3), -1))
Decimal('-232.3')

En estos casos hay que respetar que el  bit de signo es Booleano, por lo que 0 significa positivo y 1 significa negativo.

¿Y los flotantes?

Otro punto importante es que los creadores de Python dejaron fuera la conversión directa de números de coma flotante. La solución es convertir el número de coma flotante en una cadena con la precisión esperada y luego pasar esta al constructor de Decimal:

>>> f = 2.2
decimal.Decimal(str(f))
Decimal('2.2')
>>> decimal.Decimal('%.8f' % f)
Decimal('2.20000000')
La única limitación que nos da decimal ahora es que el exponente sea un numero entero.  Una operación en la que no se cumpla ese principio arrojara errores de estos tipos 
decimal.InvalidOperation: x ** (non-integer)
unsupported operand type(s) for ** or pow(): 'str' and 'str'

Otra muestra de la fortaleza de decimal es que permite combinar instancias de Decimal con enteros,  sin embargo esto no es posible con números de coma flotante:

Por otro lado, no todo podía ser color rosa, cuando utilizamos los modulos de Python math y cmath, estos se convierten a números de coma flotante antes de operar, y por supuesto el resultado del calculo será también un numero de coma flotante 

Usando Context

Las instancias de Context encapsulan las propiedades que deseamos asignar a nuestra operación de redondeo

  • prec es la precisión, el número de decimales.
  • rounding especifica el modo de redondeo. Existen varias constantes para las diferentes opciones: ROUND_DOWN (hacia cero), ROUND_CEILING (hacia arriba),   ROUND_HALF_EVEN (al más cercano), ROUND_UP, ROUND_05UP    ROUND_HALF_DOWN  ROUND_HALF_UP ROUND_FLOOR
  • • traps es un diccionario, que indica como tratar los errores.

Dentro de esto tenemos la opción de utilizar getcontext(), que como su nombre indica no es mas que un  contexto predeterminado local, que establece el hilo de ejecución  y que permite cambiar las propiedades en búsqueda de cambios en la precisión, el redondeo o captura de errores.

 Ahora cuando trabajes con un numero de coma flotante o con decimal, ya sabes un poco mas de que va el tema.

«Quien va en busca de montañas, no puede detenerse a recoger las piedras del camino»

El uso de NumPy.

laravel

NumPy, es  una de las librerías  de Python  mas conocida, debido  a la fortaleza que da al lenguaje en el procesamiento de matrices y arrays de diferente complejidad.

Su uso, es ampliamente reconocido como procesador de cálculos científicos, (que entre otras muchas opciones permite procesar matrices multidimensionales, ejecutar funciones de transmisión o de Algebra Lineal, integrar scripts de otros lenguajes  como C y Fortran y  trabajar con números aleatorios ), también es utilizado a menudo para almacenar datos genéricos, con la propiedad de que podemos definir tipos de datos arbitrarios, que pueden integrarse  con múltiples tipos de bases de datos.  

Recordando que en Python todo es un objeto, diremos que NumPy establece entonces un arreglo multidimensional y otras matrices derivadas, que no son más que otros  objetos.

 Lo que hace Numpy,  es dotarnos una herramienta que nos permite realizar operaciones en un arreglo de cualquier dimensión.

Python ofrece otras opciones para procesar  datos,  como  son sus listas, la diferencia es que Numpy permite realizar operaciones estadísticas y de álgebra, crear  funciones de entrada y salida de datos, ordenar los integrantes de un arreglo y ejecutar operaciones lógicas, extendiendo la capacidad de Python para procesar matrices e información científica

A continuación mostrar algunos de los comandos más usados de esta extensión:

 Para instalar NumPy, en  Windows necesitas Python y Pip en tu sistema.

pip install numpy

#Luego importar la librería con Import

import numpy

Array()

Una lista de python no es un arreglo, sino elementos que se encuentran encerrados entre encerrados entre corchetes, para convertirlos en un array de Numpy, basta con aplicar la siguiente sintaxis:

elementoLista = numpy.array

 import numpy
 l = [1, 2, 3, 4, 5]
 nuevo = numpy.array(l)
 print("la lista convertida a array es = ", nuevo) 

y obtenemos el nuevo array:

>>la lista convertida a array
es =  [1 2 3 4 5]

Del mismo modo haríamos si en vez de ser una lista es una tupla. Sabemos que la tupla contiene una serie de elementos encerrados entre paréntesis, entonces será:

 import numpy
 tupla = (1, 2, 3, 4, 5)
 nuevoarray = numpy.array(tupla)
 print("El nuevo array a partir de la tupla es  = ", nuevoarray) 

La salida será:

>>El nuevo array a partir de
la tupla es  =  [1 2 3 4 5]

Append()

numpy.append(array, value, axis)

append() añade los elementos al final del arreglo, ya sean columnas o valores independientes, por lo que se obtiene entonces un nuevo array actualizado.

Si no definimos el valor de axis(es opcional y asimila valores enteros),  la nueva matriz obtenida se aplanará.

Para añadir una columna lo haríamos de este modo: Considere el siguiente ejemplo donde creamos un arreglo bidimensional e insertamos dos columnas:

 import numpy
 uno = numpy.array([[0, 1, 2, 3,], [4, 5, 6, 8,]])
 dos = numpy.array([[7], [9]])
 nuevo = numpy.append(uno, dos, axis = 1)
 print(nuevo) 

eso nos dará como resultado:

 [[0,1,2,3,7],
 [4,5,6,8,9]] 

Si no usaramos un valor para axis

newArray = numpy.append(a, b)

El resultado seria

 [0, 1,2, 3, 4, 5, 6, 8, 7, 9]

Añadir una fila

 import numpy
 a1 = numpy.array([[0, 1, 2, 3], [4, 5, 6, 7]])
 nuevo = numpy.append(a1, [[8, 9, 10, 11, 12]], axis = 0)
 print(nuevo)
 [[0, 1, 2, 3]
 [, 5, 6, 7]
 [8, 9, 10, 11, 12]] 

Añadir un arreglo a otro

 import numpy
 x = numpy.array([8, 12, 16, 20, 24])
 y = numpy.array([28, 32, 36, 40, 44])
 nuevo = numpy.append(x, y)
 print("Nuevo array resultante = ", nuevo) 

el resultado es:

Nuevo array resultante =  [ 8 12 16 20 24 28 32 36 40 44]

Insert()

La diferencia con append(), es que insert(), permite decidir donde exactamente queremos agregar el elemento,  seleccionando el índice que deseamos.

 import numpy
 ar = numpy.array([0, 1, 2,3])#declaramos el array tipo numpy
 nuevo = numpy.insert(a, 2, 55)#insertamos en el índice 2 el valor 55
 print(nuevo) 

La salida será la siguiente:

[0, 1, 55, 2, 3]

delete()

Se utiliza para  eliminar un elemento de un arreglo NumPy  

 import numpy
 restar = numpy.array([1, 2, 3, 4, 5])
 nuevo = numpy.delete(restar, 2, axis = 0)
 print(nuevo) 

Obtendremos:

[1 2 4 5]

Eliminar una fila

import numpy
valores = numpy.array([[1, 2, 3, 4, 5], [6, 7, 8, 9,10], [11, 12, 25, 22]])
nuevo = numpy.delete(valores, 1, axis = 0)
print(nuevo) 

 esto nos dara como resultado:

[list([1, 2, 3, 4, 5]) list([11, 12, 25, 22])]

Size

El método size tiene diferentes usos, como obtener el número de elementos  en un array o calcular la longitud de este:

Calcular el número de elementos en un array

 import numpy
 ar = numpy.array([1000, 2000, 3000, 6000])
 if(ar.size != 0):
     print("la matriz no esta vacia")
 else:
     print("ar contiene = ", ar) 

La salida es la siguiente:

>>la matriz no esta vacia

 Si moficaramos  el código y colocaramos

 import numpy
 ar = numpy.array([1000, 2000, 3000, 6000])
 if(ar.size == 0):
     print("la matriz no esta vacia")
 else:
     print("ar contiene = ", ar) 

Obtendriamos

>>ar contiene =  [1000 2000 3000 6000]

where()

Nos devuelve el índice de un valor

 import numpy
 lista = numpy.array(['a', 2, 'b', 4, 'c'])
 print("c is found at index: ", index[0]) 

El resultado será:

>>c is found at index:  (array([4]),)

Si cambiamos la última línea de nuestro código

 import numpy
 lista = numpy.array(['a', 2, 'b', 4, 'c'])
 print("c is found at index: ", numpy.where(lista == '5')) 

Obtendremos también el tipo de dato

>>c is found at index:  (array([], dtype=int64),)

Obtener la longitud de un array

 import numpy
 cuerpo = numpy.array([1, 2, 3, 4, 5, 6])
 print("El tamaño del cuerpo  = ", cuerpo.size) 

 el resultado será:

>>El tamaño del cuerpo  =  6

Dividir un arreglo

Para dividir un arreglo utilizaremos dos puntos (:) y la sintaxis es la siguiente :

array[from:to]

 Funciona de este modo:

 import numpy
 parte = numpy.array([1, 2, 3, 4, 5, 6, 7, 8])
 print("Un pedazo del array parte es = ", parte[2:5]) 

Obtendremos:

>>un pedazo del array parte es
=  [3 4 5]

Lo que hemos hecho ha sido extraer del arreglo parte una sección del mismo que va del índice 2 al 5.

 Extraer los dos últimos elementos

 import numpy
 two_last= numpy.array([0, 1, 2, 3, 4, 5, 6, 7, 8])
 print("A subset of array a = ", two_last[-2:]) 

Resultado:

>>A subset of array a =  [7 8]

addition()  

Numpy, también permite aplicar funciones a los miembros de un arreglo o matriz multidimensional, mediante el uso de addition()

 import numpy
 addition = lambda x: (x + x*2)
 conjunto = numpy.array([1, 2, 3, 4, 5, 6])
 print("Resultado: ", addition(conjunto)) 

La salida es:

Resultado:  [ 3 6  9 12 15 18]

tolist

El método tolist, nos permitirá convertir un arreglo en una lista.

 import numpy
 x = numpy.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
 print("Convirtiendo un array en lista = ", x.tolist()) 

obtenemos entonces:

>>Convirtiendo un array en lista =  [10, 20, 30, 40, 50, 60, 70, 80,90]

savetxt()

Con savetxt(), podemos exportar un arreglo a formato de texto o csv: 

 import numpy
 a = numpy.array([16, 32, 48, 60])
 numpy.savetxt("mi.csv", a) 

Este código generará un archivo CSV en la ubicación donde se almacena nuestro archivo de código Python.

Puedes eliminar el relleno de ceros adicional de esta manera:

numpy.savetxt("miArray.csv", a,fmt='%.2f')

sort()

 Podemos  ordenar el arreglo NumPy usando el método sort (), que toma como eje  por defecto(-1), que indicará la forma en que queremos ordenar el arreglo, siendo  -1 el ultimo eje.

 import numpy
 x = numpy.array([56, 45, 17, 89, 3, 12, 5])
 print("array ordenado = ", numpy.sort(x)) 

el resultado:

>> array ordenado =  [ 3  5 12 17 45 56 89]

Normalizar un arreglo

Normalizar un arreglo, consiste en colocar los valores de un arreglo dentro de un  rango definido, siguiendo la sintaxís:

x = (x – xmin) / (xmax – xmin)

Con  los métodos max () y min () podemos organizar el array colocando los valores limites que esperamos:

 import numpy
 x= numpy.array([5000, 4800, 160, 80, 1200, 3000, 500])
 xmax = x.max()
 xmin = x.min()
 x = (x - xmin)/(xmax - xmin)
 print("array nomalizado x = \n", x)
 print(xmax )
 print(xmin ) 

 asi obtendremos:

 array nomalizado x =
 [1.  0.95934959 0.01626016 0.  0.22764228 0.59349593  0.08536585]
 5000
 80 

Indexar un arreglo

 import numpy
 x = numpy.array([40, 73, 77, 89])
 print("elemento en el indice 3 = ", x[3]) 

el resultado es:

>>elemento en el indice 3 =  89

Otro ejemplo, de su uso en un array multidimensional

 import numpy
 b = numpy.array([[10, 45, 36], [78, 9, 18]])
 print("elemento en el indice b[0][1] = ", b[0][1]) 

La salida será:

>>elemento en el indice
b[0][1] =  45

Y listo, esto es todo.

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

Gracias.

Entendiendo el concepto de clases

laravel

Entender el concepto de clases es un elemento basico cuando programamos,  ya que en si, las clases constituyen la base de la organización estructural del codigo de programacion moderno.
Las clases nos permiten crear objetos que podremos reusar o no, pero que facilitaran la escalabilidad y eficiencia del codigo.

¿Por que?

Porque la clase es como el molde de un zapatero.

Es la base para crear un objeto, lo cual permitira organizar el codigo de una manera muy como en el mundo que nos rodea.

Digamos sin ser muy profundos que un zapato  de caballero, tiene cualquiera que sea el modelo, varias partes comunes: tacon, puntera, plantilla, etc.

Entonces el molde será la clase, cada modelo  será un objeto de esa clase y cada caracteristica un atributo.

De la clase  zapato pueden crearse diferentes objetos que seran usados de diferentes formas, venderse, exhibirse, trasladarse, y para eso necesitará relacionarse con otras clases, como tienda, caja, etc.

De estas relaciones es que hablaré, por la necesidad de su comprension para crear una mejor aplicación.

Las clases pueden relacionarse asociandose, dependiendo una de otra o mediante herencia.

Asociación

Tomemos como ejemplo una base de camiones para transporte. La relación de asociación es aquella necesaria para que la estructura funcione.

Como la que hay entre un usuario_chofer  y su camión, donde se relacionan en ambas direcciones, elusuario chofer posee un camión y ese  camion pertenece a ese chofer.

Una relación parecida  a esta pero de una sola dirección es la que se da entre  la clase combustible y camión. Digamos que hay dos acciones que el  camión realiza sobre el combustible en cada viaje: recibirlo y gastarlo por tanto es una relación unidireccional

Una expresion de esta relación seria algo asi

clase Camion {    
variable viaje;   
 función constructor() 
{        
 $viaje = new Combustible();     
}    
funcion publica recibir()      
funcion publica gastar()   

}

 clase Combustible { }

Lo anterior intenta mostrar la estructura básica de una clase, no está escrito en ningún lenguaje específico aunque inspirado en php y python

Ahí vemos dos clases camión y combustible con una variable viajes que crea un nuevo objeto de combustible sobre el cual incidirá el objeto camión del que se trate, con dos métodos recibir y gastar.

Hablemos de multiplicidad

Toda relación tiene multiplicidad doble, porque se ubica a cada lado de la relación y esta tiene un minimo y un maximo.

La mejor forma de explicarlo es entendiendo por ejemplo las relaciones entre las tablas de una base de datos del tipo relacional.

Los tipos son

1  indica que la multiplicidad a cada lado de la relación es de uno y solo uno

0..1  indica una multiplicidad de 0 o 1  y viene a ser el complemento de una relación de uno

*  indica una relación de cero o varios ( presente en el lado extremo varios del tipo de relación de unos a varios

*..0 cero o varios

1..* uno o varios

La multiplicidad, define además que cuando la  mínima es 0, la relación es opcional y si es mayor o igual que 1 se establece como una relación obligatoria.

Entonces nuestras tablas en una base de datos relacional tendrán una relación de:

 uno a uno si a ambos lados de la relación existe un uno

de uno a muchos si a un lado hay un 1 y al otro  *

de muchos a  muchos si a cada lado hay un *

Y por supuesto sus inversos.

Y para analizar la obligatoriedad por ejemplo en una bd con dos tablas: viajes y camiones, podemos decir que  un camión  podrá tener o no viajes (opcional-> 0..*), pero un viaje pertenecerá si o si un camión (obligatoria->1..*)

Dependencia

Es el tipo de relación, que existe entre dos clases que se necesitan para que la estructura funcione, por ejemplo siguiendo en el área transporte:

no puede hacerse un viaje si no están al clases orden de viaje y camión.

Un modo de verlo es pensar en un objeto que solicita un recurso o un servicio  y otro que lo brinda.

 Herencia

Son relaciones que surge cuando una subclase hereda los atributos de una superclase.  Un ejemplo práctico es pensar en familias de animales, digamos que tenemos una clase llamada Paquidermos.

Esta superclase entre otros atributos tiene:

tipo, trompa(posee un método llamado añadirTrompa) y cola = corta

De  ella heredaran diferentes subfamilias,  elefantes, rinocerontes, hipopótamos, con características y comportamientos parecidos ( no sudan, piel gruesa, y grandes dimensiones). 

Sin embargo,  las subfamilias(subclases), pueden incorporar características nuevas comunes a solo algunas, ejemplo hipopótamos y rinocerontes necesitan refrescarse constantemente.

Podemos seguir creando subclases y derivando. Por ejemplo de la clase elefante,  pueden heredar las subclases elefante africano y elefante asiático.

Mientras que del rinoceronte heredaran  5 subclases: el de java, el indio, el negro, el blanco y el de Sumatra

Y del hipopotamo   heredaran: el hipopotamo común y el hipopotamo pigmeo.

Para estas subclases existirán atributos de con acceso de carácter privado, de carácter protegido y de carácter público.

Expliquémoslo a través del la subclase elefante:

Si en la superclase  existe el atributo tipo, para  la elefante será público  ya que puede acceder a el, tanto elefante como elefante africano y elefante asiático.

El atributo cola, será privado, y no podrá acceder ninguna subclase, para todos la cola tiene un valor “corta”.

Y la variable trompa, es protegida  ya que solo podrá acceder la propia clase Paquidermo  y sus  subclases mediante el método añadirTrompa.  

Otra propiedad de trabajar con clases es el encapsulamiento

Encapsulamiento

Es justo lo que hemos visto en la relaciones , o sea es el mecanismo  que se emplea para  organizar los  datos y métodos de un objeto,  limitando el acceso a ellos solo por el modo que se determine .

Por tanto al crear la clases y respetar estas relaciones estamos encapsulandotodo cuanto necesitamos en una entidad, o estructura, o dicho de otro modo en un objeto

Al encapsular podemos abstraer, o sea podemos al tener concentrados los componentes de un objeto, crear superclases que representan de la manera más abstracta posible los objetos que irán heredando de ellas.

Ser fácil entender entonces, que  las formas de encapsular pueden ser :

  • Estándar: Forma predeterminada según nos interese
  • Abierto : Se puede acceder al atributo de la clase desde el exterior de la Clase
  • Protegido : Solo es accesible desde la superclase y las subclases que heredan  de ella,
  • Semi cerrado : Solo es accesible desde la subclase heredada, para la subclase.
  • Cerrado : Solo es accesible desde la superclase.

Relacionado con la herencia tenemos que entender el poliformismo

Poliformismo

No es más que capacidad que tienen los objetos de una clase para  responder ante un  mensaje en dependencia de los parámetros que utilicemos al invocarlos o llamarlos.

Creo que la forma más sencilla de mostrarlo es que llamemos desde cualquiera de las clases que derivan de Paquidermos al atributo trompa, podremos acceder a él mediante el mismo método añadirTrompa ().

En definitiva el uso de clases y su aprovechamiento permite controlar el comportamiento del usuario,  evitando acciones indeseadas, además de  que el medio mas efectivo para controlar y manejar la complejidad de  las Clases , obligandolas a actuar como cajas negras, que dejan ver mediante una interfaz  el comportamiento pero no los detalles internos.

Lo cual es una ventaja ya que ayuda al programador a separar la interfaz de una clase de su implementación.

De este modo es más fácil limitar el acceso a los datos y que solo se haga mediante las funciones que ponemos a su disposición, con las validaciones que consideremos necesarias.

Y listo, esto es todo.

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

Gracias.

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

Desarrollar funciones en Python

logo python

Desarrollar funciones en Python pueden ser necesario para hallar solucion a problemas que otras funciones existentes no nos resuelven.

La librería del lenguaje no deja de crecer, pero es común que si actuamos como investigadores, en mas de una ocasion, no encontremos lo que necesitamos para obtener la respuesta que buscamos.

Funciones

En Python como en muchos otros lenguajes existen funciones y métodos.

Veamos a  una función como trozo de código que controla   o ejecuta un conjunto de instrucciones, y a la que podemos necesitar utilizar varias veces, esperando siempre el mismo comportamiento.

Los tipos de funciones en Python son tres:

Las que son predefinidas como print() o help().

Las que son definidas por el usuario, ya que este las crea

Las funciones anónimas, o  funciones lambda, llamadas  asi porque no se declaran bajo el standard def, que es el que usa python en el resto de los casos.

Docstring

Antes de ir más allá, algo básico a la hora de escribir código  en Python como en todo lenguaje de programación, son los comentarios, o la documentación que explique lo que estamos creando.

Añadir docstrings a la función, permite conocer su comportamiento esperado, ya que mediante su descripción documentamos todo aquello que consideramos importante, para entender que hace.

Los docstring se colocan justo después de la primera línea de la función, y se inicializan con tres comillas dobles,  y se finaliza de igual modo.

def  nada():
"""
   esta función no hara nada
   retornara un campo de tipo none
"""
   return 

Métodos

Los métodos son pequeñas funciones, que forman parte de una clase, por tanto se accede a ellos instanciando esta o con un objeto, a diferencia de una función típica que puede ser llamada sin esa restricción.

 Puede parecer confuso, pero la mejor forma de verlo es pensando que: todos los métodos son funciones pero no todas las funciones son métodos.

Por ejemplo una función puede ser:

def función_x(a,b,c):
   return a*b+c

Habiendo definido la función y lo que esperamos de ella, para llamarla solo debemos  asignar valores a sus parámetros

función_x(2,3,5)

Comparemos como seria al crear una clase:

class Resultado(object):  
   def solucion(self, a,b,c):  
   self.contents = a*b+c 
   return self.contents

Si ahora deseamos llamar  al método solución(), al pertenecer a la clase Resultado, necesitamos primero crear un objeto o instanciar la clase.

solucionInstance = resultado() 
solucionInstance.solucion(1,2,4)

Un elemento que puede llamar a confusión cuando empiezas en Python es la diferencia entre parámetros y argumentos.

Entenderlo es más sencillo de lo que parece:

Imagina que creas una función que suma dos variables, la variable A y la B

def letras(A, B) 
   return A+B

A y B son parámetros, sin embargo cuando debes llamar la función o el  método para ejecutarlo necesitas dar valor a  los parámetros cuando los llamas

Si  A = 1, B=5

def letras(1, 5)

La  función hará lo que está establecido en su comportamiento sumar 1+5

Cuando creamos la clase Resultado al método solución se le pasaron tres parámetros, sin embargo al crear el objeto se pasaron cuatro argumentos, pues se añadió self.

self , es siempre el primer argumento de cualquier clase y hace referencia a ella misma.

Cuando una función es creada por un usuario, se declara siempre igual:

  • La palabra def y luego el nombre de la función,  después se añaden los parámetros de la función entre paréntesis y después  dos puntos,  para terminar la línea.
  • La acción que la funcion debe ejecutar..
  • Y la llamada a return para que nos devuelva algo. No colocar return provocará que la función devuelva un objeto none, el cual no admite que se ejecuten funciones sobre el.
def función(a, b): 
   c=a+b 
   return c

Existen diferentes tipos de argumentos

Los que son por defecto, los requeridos, los argumentos keyword y los  variables.

Argumentos por defecto

Son que les asigna un valor mediante el operador =

def menos(a,b,d=3): 
   return a-b-d

Esta función puede ser llamada con todos sus parámetros,  o solo con alguno de ellos.

#llamandola con 1 parametro  
menos(b=2)
#llamandola con todos los parametros 
menos( a=10,b=12,d=4)

Argumentos requeridos

Son aquellos que tiene que ser pasados a la función en el momento adecuado y en un orden dado para garantizar su ejecución

En la función menos() a, b y d son argumentos requeridos, los cuales deben pasarse en un momento dado (al inicio) y en un orden ( ya que a-b-d), cambiar ese orden alteraría el resultado.

Argumentos keyword

Este tipo de argumentos son llamados utilizando el parametro al que corresponde para identificarlo

def sol(a,b): 
   return a+b 
   
#llamando la función con el uso de keywords 
def sol(a=2, b=3)

 Cuando usamos las keywords, podemos cambiar el orden de los argumentos, sin que ello afecte el resultado

def sol(b=3,a=2)

Argumentos de número  variable

Se utiliza cuando no se sabe el numero de argumentos esperado, y para ello se utiliza la sintaxis *args

def  varios(*args):   
   return sum(args)  
   #ejecutando la función 
   varios(3,6,7)

El asterisco * , se coloca antes del nombre de la variable que soporta los argumentos multiples:

def  diferentes(*varnueva):  
   x=2  
   for i in varnueva:  
   x += i*2  
   return x

Variables

Las  variables en Python pueden ser locales o globales, las primeras son las que se definen dentro de las funciones, por tanto solo se puede acceder a ellas desde dentro de la función, mientras que las variables globales puede obtenerla cualquier función.

Return

Return es el encargado de  devolver el resultado, ya sea uno o múltiples valores, y su uso nos permite , ampliar las posibilidades  de nuestra función o método.

Cuando necesitamos que el return nos devuelva multiples valores, utilizaremos tuplas

Desarrollar funciones en Python

Funciones anónimas

Son las funciones que en vez de declararse con def, son declaradas con la palabra lambda.

double = lambda x: x*3  
   double(5)

En este caso x es el argumento, y x*3 la instrucción que la función debe cumplir

Una función con dos argumentos podría ser

sum = lambda xmy:x+y  
   sum(4,2)

Las funciones anónimas pueden usarse por ejemplo, cuando se requieren funciones con un corto periodo de tiempo de vida, por ejemplo cuando se trabaja con maps(), filter() o reduce().

Main

La función main(), se usa comunenente en Python para agrupar los principales componentes de un sistema.

En un ejemplo sencillo podría ser algo asi:

def  main():  
   varios()  
   solucion() 
   main()

Existe un detalle a considerar, para llamar main() como clase, debe hacerse de esta forma:

__name__ ==’__main__’:

De lo contrario Python asumirá que estamos llamando a un modulo

main() también puede crearse utilizando __init__ para instanciar una clase o un objeto. El nuevo objeto instanciado es asignado al parámetro self

La estructura es esta:

class  nueva:  
""" Requires:  
   atrib_a 
   atrib_b 
"""
def  __init__ (self, atrib_a, atrib_b): 
   self.atrib_a =atrib_a 

 self.atrib_b = atrib_b 
 def  funcion1(self): 
 funcion1  = …acción…. 
 return funcion1 
 #llamando a main 
 if __name__ ==  ”__main__”: 
  solucion =  solucion(argumento1, argumento2) 
  funcion1  = solucion.funcion1() 
  print(funcion1) 

Y listo, esto es todo.

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

Gracias.

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

Formatos de compresión en Python

logo python

En su mayoría, los lenguajes poseen métodos para compactar archivos. Veamos en este post, formatos de compresión en Python.

zlib y gzip pertenecen a la librería zip de GNU, por su lado  bz2  es compatible con el proporciona acceso al formato zip2 más moderno.

 En ambos casos, estos métodos de compactación de datos en Python, aceptan cualquier  formato de entrada, y al mismo ofrecen  interfaces para leer y escribir archivos comprimidos de forma transparente.

tarfile lee y escribe el formato de archivo Unix.

zipfile funciona con archivos basados en el formato popularizado por el programa de PC PKZIP

Estos módulos, permiten  combinar varios archivos, en un sólo que puede ser manejado como una unidad. 

….. es el tiempo más lento del mundo, cuando va de prisa

R.Arjona

TypeError: ‘int’ object is not iterable. Python

python error

El error TypeError: ‘int’ object is not iterable, puede ser lanzado en Python, cuando intentamos iterar dentro de un vector, pero no indicamos un rango de recorrido.

Revisa si tienes algo como esto:

for i in len(vector)

Intenta cambiarlo por esto.

for I in range(len(vector))

Puedes ver aquí la causa del error index out of range

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

Gracias

«…..lo que realmente importa no es lo que te da la vida, sino lo que haces con ello….»

Diferencias entre flatten() y ravel() en Python

logo python

Muchas veces las usamos indistintamente pero existen diferencias entre flatten() y ravel(), en Python

Cuando necesitamos convertir un ndarray en un array de una sola dimensión, podemos valernos de algunas de estas dos funciones de numpy, la biblioteca para operar funciones numéricas que Python posee.

flatten() vs ravel()

Las diferencias entre ambas funciones no son muchas, pero existen. Veamos

flatten()

Solo nos retornará una copia del array original, por lo que si modificamos su composición en el transcurso de nuestro código, nos seguirá devolviendo el array inicial

Por otro lado en comparación con ravel(), es más lento y ocupa mayor cantidad de memoria.

flatten() además, es un método propio del objeto ndarray

ravel()

Su resultado es una vista o referencia del array que esta aplanando o convirtiendo, pero si este cambia, al ser una referencia, el también se ve afectado y actualiza su contenido.

Es mucho más rápido y no ocupa memoria.

ravel() actúa como una función, pero esta diseñado como una librería

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

Gracias


“Todo como el diamante, antes que luz es carbon”

JMarti

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

Diferencia entre json.load() y json.loads()

logo python

La diferencia entre json.load() y json.loads(), puede a menudo confundirnos cuando operamos con archivos json desde Python.

He aquí en que se diferencian:

json.load(): deserializa el archivo json, tomando como cadena (string), su contenido y soporta texto y binario, para convertirlo en un objeto Python, siguiendo esta tabla de conversión

JSONPython
objectdict
arraylist
stringstr
number (int)int
number (real)float
trueTrue
falseFalse
nullNone
tabla de conversion de datos json python

json.load()

deserializa el archivo en si mismo, ya que acepta el objeto file(archivo), por tanto acepta esta forma

with open("/abc/data.json", "r") as content:
print(json.load(content))

Esto no podríamos hacerlo con json.loads(), porque lanzaría un error del tipo:

TypeError: expected string or buffer

json.loads()

Deserializa un string, por tanto al usarlo deberíamos pasarle  el contenido del archivo empleando, por ejemplo read().

with open("json_data.json", "r") as content:
print(json.loads(content.read()))

Esto se debe, a que al emplear la función read(), estamos leyendo el contenido de la cadena o string,  y no el archivo como objeto.

Si intentaramos emplear json.load(), para deserializar solo el contenido obtendríamos este error:

with open("json_data.json", "r") as content:
print(json.load(content.read()))
AttributeError: 'str' object has no attribute 'read'

En este link dejo especificaciones sobre su sintaxis

Dicho de otro modo json.load() deserializa archivos y json.loads() deserializa strings.

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

Translate »