miércoles, 16 de diciembre de 2020

Python: simular tipado estático mediante anotaciones de tipo.

A mayo del 2020 Python se ubica en el tercer puesto del Index TIOBE que postula un listado de los lenguajes de programación más populares del mundo. Su sintaxis fácil de escribir y su tipado dinámico hacen de Python un lenguaje muy flexible en el desarrollo de todo tipo de aplicaciones.

Ahora bien, su tipado dinámico puede generar diversas discusiones entre programadores por los errores que suele generar al momento de compilar el código. Este tipo de errores se puede mitigar utilizando buenas prácticas al momento de codificar, la página oficial de Python nos ofrece un apartado muy interesante sobre el Annotation Type o Anotaciones de Tipo en español.

Las anotaciones de tipo nos permiten definir anotaciones en nuestro código para que este sea claro y fácil de entender para otros programadores que acostumbran utilizar el tipado estático.

Las anotaciones de tipo pueden ser usadas a partir de la versión 3.6 de Python.

Podemos utilizar estas anotaciones en:

1. Variables

Para las variables solo basta escribir el nombre de la variable seguido dos puntos y especificar el tipo. También es posible definir el tipo sin necesidad de inicializar la variable.

a : int = 12
b : float = 15.5
c : bool = True
d : str = 'Python'

#Variable sin inicializar
x : int

2. Colecciones

Para definir los tipos de las colecciones es necesario importar el módulo typing que viene incorporado en Python.

from typing import List, Set, Dict, Tuple

#Para las listas y los sets solo basta especificar
#el tipo entre corchetes
l : List[int] = [10, 20, 30]
s : Set[int] ={6, 9}

#Para los diccionarios debemos definir el tipo de datos para
#la clave y su valor
d : Dict[str, int] = {'item': 23}

#Para las tuplas podemos definir el tipo de dato
#para cada elemento en caso de que la tupla sea de tamaño fijo
t : Tuple[int, str, float, bool] = (1, 'Hola', 15.6, True)

#Si la tupla es de tamaño variable debemos definir el tipo
#seguido de puntos suspensivos
t : Tuple[float, ...] = (12.2, 15.3, 18.4, 16.2)

Si deseamos definir una lista de varios tipos de datos no podemos hacer el mismo procedimiento que se realiza con las tuplas. Para esto debemos hacer uso de la función Union del módulo typing.

from typing import List, Union

l: List[Union[int, str, float]] = [3, 5, 'hola', 'mundo', 15.6]

3. Funciones

En Python es posible hacer anotaciones de tipo en funciones sin necesidad de importar el módulo typing.

def numero_texto(num: int) -> str:
    return str(num)

def suma(n1: int, n2: int) -> int:
    return n1+n2

#Para valores por default debemos especificar
#el valor luego del tipo como una declaración normal de una variable
def multiplicacion(n1: int, n2:float=2.5) -> float:
    return n1*n2

Si por el contrario queremos hacer uso de colecciones debemos importar el módulo typing.

from typing import List

lista: List[int] = [1, 2, 3, 4, 5]

def imprimir_lista(x:List[int]) -> List[str]:
    print(str(x))

imprimir_lista(lista)

4. Clases

Para las clases podemos hacer uso de las mismas anotaciones referentes a variables y métodos dentro de una clase pero también existen algunas anotaciones extras que podemos realizar con las clases como definir anotaciones en métodos que no retornan ningún valor y definir como tipo las clases que ha creado el usuario.

class MiClase:

    attr1 : int = 100
    attr2 : str

        #Podemos usar la palabra None en caso de que el
        #método no retorne ningún valor
    def __init__(self) -> None:
        ...

    def metodo(self, n1: int, n2: int) -> int:
        return n1+n2

#Podemos incluir anotaciones referentes a la clase
#directamente en la instancia de la clase
instancia: MiClase = MiClase()

El uso de estas anotaciones facilita el mantenimiento del código y la legibilidad del mismo. Sin embargo, es importante recordar que estas anotaciones no impiden que el código de Python se ejecute, por ejemplo:

def multiplicacion(n1:int, n2: int) -> int:
    return n1*n2

print(multiplicacion(3, 'Hola'))

Se esperaría que el código no se compilara debido a que la función espera un número entero pero debido a la naturaleza del tipado dinámico de Python esto no sucede y obtendremos como resultado una cadena de texto. Sin duda es una desventaja pero es importante realizar estas anotaciones en proyectos de gran magnitud donde es fácil perder el control del código.

Existen muchas más anotaciones de tipo por explorar que se pueden revisar por completo en el siguiente enlace:

lunes, 7 de septiembre de 2020

Cursos de Prestashop 1.7 en Youtube

 https://www.youtube.com/watch?v=Xav35c6GnlE&list=PLkfVWczuEdpO2xdyjKyVqUPAX7HaDQdCI

https://www.youtube.com/watch?v=sEwum1ACSag&list=PL0-IJh0LAbBfBhVg4D_IlOrw_gFpRunFD

miércoles, 2 de septiembre de 2020

jueves, 16 de julio de 2020

Cursos Google Docs y Google Sheets 2020

Google Docs: https://www.youtube.com/watch?v=2ZHf9JrG-sE&list=PLG1qdjD__qH4sftbDnm383KqPDpn9u0Rt
Google Sheets: https://www.youtube.com/watch?v=Z2VMC7p5J2Q&list=PLG1qdjD__qH7elIRiQoqRdY0ZzThfLnxn

viernes, 10 de julio de 2020

Tutorial API REST con Java (JAX-RS) (sin Maven ni Spring Boot)

https://www.oscarblancarteblog.com/api-rest-java-jax-rs/

Para responder con JSON:

@GET
    @Path("/json")
    public Response getJsonResponse() {
   
        Person person = new Person("Abhinayak", "Nepal");
   
        return Response
          .status(Response.Status.OK)
          .entity(person)
          .type(MediaType.APPLICATION_JSON)
          .build();
    }


miércoles, 27 de mayo de 2020

PostgreSQL: Aggregate Functions

General-Purpose Aggregate Functions






Example query



It should be noted that except for count, these functions return a null value when no rows are selected. In particular, sum of no rows returns null, not zero as one might expect. The coalesce function may be used to substitute zero for null when necessary.

Aggregate Functions for Statistics


miércoles, 6 de mayo de 2020

CSS Grid

https://css-tricks.com/snippets/css/complete-guide-grid/
https://developer.mozilla.org/es/docs/Web/CSS/CSS_Grid_Layout/Conceptos_B%C3%A1sicos_del_Posicionamiento_con_Rejillas

lunes, 13 de abril de 2020

Unbound classpath container: JRE System Library

https://sites.miis.edu/dreadkingrathalos/2017/06/05/unbound-classpath-container-jre-system-library-resolved/

viernes, 10 de abril de 2020

lunes, 30 de marzo de 2020

Java HashMap (Diccionarios)

Map<String, Integer> map = new HashMap<String, Integer>();

map.put("valor1", 15);
map.put("valor2", 20);
map.put("valor3", 1000);
map.put("valor4", 1500);
map.put("valor5", 2);

int valor1 = map.get("valor1");

// para saber el número más alto se debe recorrer el mapa
int valorMax = -1;

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    final int valorActual = entry.getValue();

    if (valorActual > valorMax)
        valorMax = valorActual;
}

System.out.println("Valor máximo: " + valorMax);
 
 
https://es.stackoverflow.com/questions/286092/diccionarios-en-java
https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html 

domingo, 23 de febrero de 2020

HTML5: Documento HTML mínimo.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Tittle</title>
    <meta name="description" content="Page Description. 160 char max">
    <meta name="keywords" content="keyword 1, keyword 2, keyword 3">
    <meta name="author" content="Author Name">
    <meta name="copyright" content="Copyright Owner">
    <meta charset="utf-8">
    <meta name="robots" content="index, follow">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <!-- CSS -->
    <link rel="stylesheet" href="web.css">
    <!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> -->
</head>

<body>

    <!-- HEADER $ NAVBAR-->
    <header>
        <a href="#">Tittle</a>
        <nav>
            <ul>
                <li><a href="#">Item</a></li>
                <li><a href="#">Item</a></li>
                <li><a href="#">Item</a></li>
                <li><a href="#">Item</a></li>
            </ul>
        </nav>
        <a href="#"><button>Log In</button></a>
    </header>
  
    <!-- CONTENT -->
    <main>
        Contenido
    </main>
  
    <!-- FOOTER -->
    <footer>
        hola footer
    </footer>

    <!-- JavaScript: Placed at the end of the document so the pages load faster -->
    <!-- <script src="bootstrap/js/bootstrap.min.js"></script> -->
    <!-- jQuery must come first, then Popper.js, and then our JavaScript plugins -->
    <!-- <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> -->
    <!-- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> -->
</body>

</html>