sábado, 30 de enero de 2021

Aplanando listas en Python


Algunas veces tenemos una estructura de lista que dentro tiene listas, y se complica demasiado trbajar con estas estructuras, por lo tanto lo que podemos hacer es aplanarlas en una lista simple. Esto lo podemos hacer con itertools.chain.from_iterable del paquete itertools, veamos un ejemplo : 

a_list = [[1, 2], [3, 4], [5, 6]]

print(list(itertools.chain.from_iterable(a_list)))

# Output: [1, 2, 3, 4, 5, 6]

# o podemos hacer : 

print(list(itertools.chain(*a_list)))

# Output: [1, 2, 3, 4, 5, 6]



ReScript


Javascript no nos da un descanso...

Luego de aprender Javascript, aprendimos CofeScript (se acuerdan?) y luego Typescript y ahora llega Rescript. 

Rescript es el lenguaje similar a JavaScript que estabas esperando. Es el slogan de este lenguaje, aunque yo no esperaba nada :P 

Antes de ponerme a ver la instalación del entorno y todo eso, vamos a ver  el lenguaje, veamos unos ejemplos: 


// MyFile.res


let rec fib = n => {

  switch n {

  | 0 | 1 => 1

  | n => fib(n -1) + fib(n-2)

  }

}

Js.log(fib(0))


A simple vista se puede ver la influencia de los lenguajes funcionales. 

Rescript aporta un sistema de tipos, podemos tener estructuras o tipos, veamos ejemplos : 

//definimos una estructura persona

type rec person = {

  name: string,

  friends: array<person>

}

//Definimos tipos y los usamos 

type intCoordinates = (int, int, int)

type floatCoordinates = (float, float, float)


let a: intCoordinates = (10, 20, 20)

let b: floatCoordinates = (10.5, 20.5, 20.5)


En fin, ReScript nos brinda muchas ventajas, como tipos, lazy values, objetos, etc .. Pero no veo, claramente algunas ventajas para migrar un proyecto Typescript a Rescript. Como me gustan los vs, tengo que hacer un post Rescript vs Typescript.  

Dejo link: https://rescript-lang.org/


miércoles, 27 de enero de 2021

Libros Gratuitos de Java Code Geeks

 

Download IT Guides!

 

Apache Maven Cookbook

An XML file describes the software project being built, its dependencies on other external modules and components, the build order, directories, and required plug-ins. It comes with...

 
 

Apache Hadoop Tutorial

Hadoop has become the de-facto tool used for Distributed computing. For this reason we have provided an abundance of tutorials here at Java Code Geeks.

 
 

JBoss Drools Cookbook

Drools supports the JSR-94 standard for its business rule engine and enterprise framework for the construction, maintenance, and enforcement of business policies in an organization,...

 
 

Java Interview Questions

In the following sections we will discuss about object-oriented programming and its characteristics, general questions regarding Java and its functionality, collections in Java, garbage...

 

lunes, 25 de enero de 2021

De CSV a json con Python


Si tenemos que pasar un archivo csv a un formato Json podemos utilizar este comando mágico : 

python -c "import csv,json;print json.dumps(list(csv.reader(open('csv_file.csv'))))"

Y Listo!!

 

jueves, 21 de enero de 2021

Primeros pasos con Clojure, parte 21



Seguimos con Clojure... 

Los conjuntos ordenados se ordenan según una función de comparación que puede comparar dos elementos. De forma predeterminada, se utiliza la función de comparación de Clojure, que ordena en el orden "natural" los números, cadenas, etc.


user=> (conj (sorted-set) "Bravo" "Charlie" "Sigma" "Alpha")

#{"Alpha" "Bravo" "Charlie" "Sigma"}


También se puede utilizar un comparador personalizado con sorted-set-by.


user> (sorted-set-by > 3 5 8 2 1)

#{8 5 3 2 1}


into se utiliza para agregar una colección en otra.


user=> (def players #{"Alice" "Bob" "Kelly"})

user=> (def new-players ["Tim" "Sue" "Greg"])

user=> (into players new-players)

#{"Alice" "Greg" "Sue" "Bob" "Tim" "Kelly"}


into devuelve una colección del mismo tipo que su primer argumento.


miércoles, 20 de enero de 2021

Primeros pasos con Clojure, parte 20


Seguimos con Clojure... 

Los Set son conjuntos matemáticos, desordenados y sin duplicados. Los conjuntos son ideales para comprobar de forma eficaz si una colección contiene un elemento o para eliminar cualquier elemento arbitrario.

(def players #{"Alice", "Bob", "Kelly"})

Al igual que con los vectores y las listas, conj se usa para agregar elementos.

user=> (conj players "Fred")
#{"Alice" "Fred" "Bob" "Kelly"}

Como los conjuntos no tienen orden, se agrega en cualquier lado. 

La función disj ("disjoin") se utiliza para eliminar uno o más elementos de un conjunto.

user=> (disj players "Bob" "Sal")
#{"Alice" "Kelly"}

Para saber si un elemento ya esta contenido se hace : 

user=> (contains? players "Kelly")
true


martes, 19 de enero de 2021

Detectar cuellos de botella en Python


Esto puede ser extremadamente útil para identificar los cuellos de botella en scripts Python :


python -m cProfile my_script.py


cProfile es una implementación más rápida que profile, ya que está escrito en c


lunes, 18 de enero de 2021

Primeros pasos con Clojure, parte 19


Seguimos con Clojure... 

Las listas son listas enlazadas secuenciales que agregan nuevos elementos al principio de la lista, en lugar de al final como vectores.

Debido a que las listas se evalúan invocando el primer elemento como una función, debemos agregar el ' para evitar la evaluación:

(def cards '(10 :ace :jack 9))

Las listas no están indexadas, por lo que se deben recorre accediendo al primero y al resto.

user=> (first cards)

10

user=> (rest cards)

'(:ace :jack 9)

conj se puede usar para agregar elementos a una lista al igual que con los vectores. Sin embargo, conj  agrega elementos al frente de las listas:

user=> (conj cards :queen)

(:queen 10 :ace :jack 9)

Las listas también se pueden usar como una pila con peek y pop:

user=> (def stack '(:a :b))

#'user/stack

user=> (peek stack)

:a

user=> (pop stack)

(:b)


sábado, 16 de enero de 2021

Libros Gratuitos de Java Code Geeks

 

Download IT Guides!

 

Java Servlet Tutorial

A servlet can almost be thought of as an applet that runs on the server side-without a face. Java servlets make many Web applications possible.

Java...

 
 

Groovy Programming Cookbook

Groovy 1.0 was released on January 2, 2007, and Groovy 2.0 in July, 2012. Since version 2, Groovy can also be compiled statically, offering type inference and performance very close to...

 
 

Gradle Build Automation Handbook

Gradle was designed for multi-project builds which can grow to be quite large, and supports incremental builds by intelligently determining which parts of the build tree are up-to-date,...

 
 

Apache Solr Cookbook

Providing distributed search and index replication, Solr is designed for scalability and fault tolerance. Solr is the second-most popular enterprise search engine after Elasticsearch.
...

 

martes, 12 de enero de 2021

Primeros pasos con Clojure, parte 18

Seguimos con Clojure... 


En Clojure, hay cuatro tipos clave de colecciones : vectores, listas, conjuntos y mapas. De esos cuatro
tipos de colecciones, los vectores y las listas están ordenados.

Los vectores son una estructura de datos secuenciales indexados. Los vectores se representan con [] así:

[1 2 3]

"Indexado" significa que los elementos de un vector se pueden recuperar por índice. En Clojure (como en Java), los índices comienzan en 0, no en 1. Usamos la función get para recuperar un elemento en un índice:

user=> (get ["abc" false 99] 0)

"abc"

user=> (get ["abc" false 99] 1)

false

Todas las colecciones de Clojure se pueden contar:

user=> (count [1 2 3])

3

Además de la sintaxis literal [], los vectores Clojure se pueden crear con la función vector:

user=> (vector 1 2 3)

[1 2 3]

Los elementos se agregar a un vector con conj (abreviatura de unir). Los elementos siempre se agregan a un vector al final:

user=> (conj [1 2 3] 4 5 6)

[1 2 3 4 5 6]

Las colecciones de Clojure comparten propiedades importantes de valores simples como cadenas y números, como la inmutabilidad y la comparación de igualdad por valor.

Por ejemplo, creemos un vector y modifiquémoslo con conj.

user=> (def v [1 2 3])

#'user/v

user=> (conj v 4 5 6)

[1 2 3 4 5 6]

Aquí conj devolvió un nuevo vector, pero si examinamos el vector original, vemos que no ha cambiado:

user=> v

[1 2 3]

Cualquier función que "cambie" una colección devuelve una nueva instancia. Su programa deberá recordar o transmitir la instancia modificada para aprovecharla.

domingo, 10 de enero de 2021

Dragonwell se distribuirá con AdoptOpenJDK


AdoptOpenJDK y Alibaba anunciaron que Dragonwell JDK se construirá, probará y distribuirá utilizando la infraestructura de AdoptOpenJDK. Esto significa que los usuarios tienen más opciones y pueden optar por utilizar Dragonwell.

Dragonwell de Alibaba es una versión posterior de OpenJDK, que tiene algunas características importantes que no están disponibles en la línea principal de OpenJDK. Alibaba lo describe como una compilación OpenJDK optimizada para aplicaciones de comercio electrónico, financieras y logísticas. Alibaba utiliza Dragonwell para ejecutar sus aplicaciones en más de 100.000 servidores.

En 2019, Dragonwell se convirtió en código abierto y está disponible de forma gratuita. Linux x86-64 es oficialmente compatible, sin embargo, también hay una compilación aarch64 disponible y hay una versión experimental para Windows. Alibaba menciona que brindará soporte a largo plazo, pero no se ha definido el período exacto.

Las compilaciones para Dragonwell 8 y 11 se publicarán en el sitio web AdoptOpenJDK. Esto significa que la API AdoptOpenJDK se puede utilizar para descargar los binarios. Esto es particularmente útil para organizaciones que automatizan la instalación de nuevos binarios.

Una de las características únicas de Dragonwell es JWarmup. JWarmup intenta reducir los desafíos de rendimiento en caliente provocados por la compilación JIT. La solución utiliza métodos en caliente precompilados para mejorar el rendimiento. Para lograrlo, se definen dos fases: la pre-ejecución y la ejecución normal.

En la fase previa a la ejecución, los datos de generación de perfiles de los métodos en caliente se registran durante una prueba de carga y se almacenan en un archivo en el disco. Ese archivo se usa durante la ejecución normal donde el hilo JIT compila los métodos en el archivo en versiones nativas. Ahora esos métodos se ejecutan de forma nativa desde el inicio en lugar de interpretarse. Esto reduce la fase de calentamiento de una aplicación, lo que se traduce en un rendimiento mejorado para las aplicaciones que recién se inician.

Otra característica interesante es el soporte de corrutinas Wisp2. Wisp2 asigna subprocesos de Java a corrutinas en lugar de subprocesos a nivel de kernel. El rendimiento de la aplicación se mejora potencialmente ya que se pueden programar muchas corrutinas en una pequeña cantidad de líneas centrales. Esto reduce la sobrecarga de programación y puede mostrar una mejora en función de la carga de trabajo que se esté ejecutando.

El motor Wisp2 es similar en algunos aspectos a los objetivos de Project Loom, que también intenta eliminar el cuello de botella del número de subprocesos activos al permitir a los desarrolladores "virtualizar" sus subprocesos y multiplexarlos en un número menor de subprocesos de plataforma que utilizan enfoques a las corrutinas.

La idea central de Wisp2 es que (a diferencia de Loom) funciona de forma inmediata en el código existente habilitándolo con estos argumentos de Java:

java -XX: + UnlockExperimentalVMOptions -XX: + UseWisp2

Como Wisp2 no requiere cambios en el código fuente, el costo de la migración es bajo. Los desarrolladores no necesitan implementar corrutinas ellos mismos y las características de concurrencia de Java existentes aún se pueden usar.

Sin embargo, no todas las aplicaciones se benefician de Wisp2 y el impacto de mover automáticamente todos los hilos a las corrutinas puede ser muy grande (y no necesariamente positivo).

Las aplicaciones intensivas de Entrada-Salida donde las tareas se bloquean en eventos y luego se programan pueden beneficiarse del soporte de corrutinas. Por otro lado, las aplicaciones con uso intensivo de CPU probablemente no se beneficiarán de las corrutinas. La forma más sencilla de averiguar si una aplicación se beneficia de Wisp2 es habilitar el soporte y ejecutar una prueba de rendimiento.

Alibaba está trabajando activamente para contribuir con estas y otras características y parches al OpenJDK ascendente. Por ejemplo, JWarmup se describe en una propuesta de mejora de Java (JEP), pero todavía está en estado de borrador.

AdoptOpenJDK y Dragonwell son dos de las distribuciones más conocidas basadas en OpenJDK, pero hay muchas más opciones como: Corretto de Amazon, SapMachine de Sap, Liberica de BellSoft, Zulu de Azul y ojdkbuild. Las organizaciones entregan JDK y JRE con diferentes características y parches. Además, cada organización determina sus propios niveles de soporte, algunos de los cuales son de pago. Esto les da a los clientes más libertad, ya que pueden elegir su JDK preferido en función de las funciones y el soporte que necesitan.

Dejo link : https://blog.adoptopenjdk.net/2020/11/adoptopenjdk-welcomes-dragonwell/

Imprimir una lista y/o un diccionario con Python


Se puede imprimir una lista y/o un diccionario en un hermoso formato en Python repl con pprint. De esta forma: 


from pprint import pprint

my_dict = {'name': 'Yasoob', 'age': 'undefined', 'personality': 'awesome'}

print(dir(my_dict))


# ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

pprint(dir(my_dict))

# ['__add__',

#  '__class__',

#  '__contains__',

#  '__delattr__',

#  '__delitem__',

#  '__dir__',

#  '__doc__',

#  '__eq__',

#  '__format__',

#  '__ge__',

#  '__getattribute__',

#  '__getitem__',

#  '__gt__',

#  '__hash__',

#  '__iadd__',

#  '__imul__',

#  '__init__',

#  '__init_subclass__',

#  '__iter__',

#  '__le__',

#  '__len__',

#  '__lt__',

#  '__mul__',

#  '__ne__',

#  '__new__',

#  '__reduce__',

#  '__reduce_ex__',

#  '__repr__',

#  '__reversed__',

#  '__rmul__',

#  '__setattr__',

#  '__setitem__',

#  '__sizeof__',

#  '__str__',

#  '__subclasshook__',

#  'append',

#  'clear',

#  'copy',

#  'count',

#  'extend',

#  'index',

#  'insert',

#  'pop',

#  'remove',

#  'reverse',

#  'sort']


Dejo link : https://wiki.python.org/moin/Powerful%20Python%20One-Liners


miércoles, 6 de enero de 2021

Apache Netbeans 12.2 soporta Java 14 y 15


Toma tu torta!! Si, el querido Apache Netbeans soporta java 14 y 15. 

La versión 12.2 de Apache NetBeans ofrece, entre otros, soporte (mejorado) para Java 14 y 15. Las características de NetBeans como el color de código, el formateo de código y el autocompletado ahora admiten nuevas características del lenguaje Java como registros y palabras claves.

Por lo visto Netbeans sigue creciendo. 

Dejo link: https://netbeans.apache.org/download/nb122/nb122.html

https://bits.netbeans.org/12.2/javadoc/

lunes, 4 de enero de 2021

Primeros pasos con Clojure, parte 17


Seguimos con Clojure... 

Desde Clojure podemos llamar métodos de objetos y clases de Java de la siguiente manera : 

Hay algunos puntos que debemos tener en cuenta :
  • Los métodos Java no son funciones de Clojure
  • No se pueden almacenar ni pasar como argumentos
  • Puede envolverlos en funciones cuando sea necesario
;; make a function to invoke .length on arg
(fn [obj] (.length obj))

;; same thing
#(.length %)

domingo, 3 de enero de 2021

Compartir rápidamente un archivo a través de una red con Python


¿Alguna vez debíamos compartir rápidamente un archivo a través de una red? Python tiene una función solo para ti. Tenemos que estar en el directorio debemos servir a través de la red y escriba el siguiente código en su terminal:

# Python 2

python -m SimpleHTTPServer

# Python 3

python -m http.server


Podemos poner el puerto si lo deseamos por defecto es 8080, por ejemplo: 

python -m SimpleHTTPServer 9999


Y listo si accedes a http://localhost:8080 (en caso que no hayas cambiado el puerto) podes ver los archivos. 

sábado, 2 de enero de 2021

Primeros pasos con Clojure, parte 16

Seguimos con Clojure... 

 let vincula símbolos a valores en un "ámbito léxico". Un alcance léxico crea un nuevo contexto para los nombres, anidado dentro del contexto circundante. Los nombres definidos en un let tienen prioridad sobre los nombres en el contexto externo.


;;      bindings     name is defined here

;;    ------------  ----------------------

(let  [name value]  (code that uses name))


Cada let puede definir 0 o más enlaces y puede tener 0 o más expresiones en el cuerpo.


(let [x 1

      y 2]

  (+ x y))


Esta expresión let crea dos enlaces locales para x e y. La expresión (+ x y) está en el ámbito léxico de let y resuelve x en 1 ey en 2. Fuera de la expresión let, x e y no tendrán un significado continuo, a menos que ya estén vinculados a un valor.


(defn messenger [msg]

  (let [a 7

        b 5

        c (clojure.string/capitalize msg)]

    (println a b c)

  ) ;; end of let scope

) ;; end of function


La función  messenger toma un argumento msg. Aquí, defn también crea un alcance léxico para msg; solo tiene significado dentro de la función.

Dentro de ese alcance de función, let crea un nuevo alcance para definir a, b y c. Si intentáramos usar una expresión después de let, el compilador reportaría un error.

Clojure tiene clusuras, la expresión fn crea una "clausura". La clausura existe en  el ámbito léxico circundante (como msg, a, boc arriba) y captura sus valores más allá del ámbito léxico.


(defn messenger-builder [greeting]

  (fn [who] (println greeting who))) ; closes over greeting


;; greeting provided here, then goes out of scope

(def hello-er (messenger-builder "Hello"))


;; greeting value still available because hello-er is a closure

(hello-er "world!")

;; Hello world!

Primeros pasos con Clojure, parte 15


Seguimos con Clojure... 

apply es una función que invoca una función con 0 o más argumentos fijos y extrae el resto de los argumentos necesarios de una secuencia final. El argumento final debe ser una secuencia.


(apply f '(1 2 3 4))    ;; same as  (f 1 2 3 4)

(apply f 1 '(2 3 4))    ;; same as  (f 1 2 3 4)

(apply f 1 2 '(3 4))    ;; same as  (f 1 2 3 4)

(apply f 1 2 3 '(4))    ;; same as  (f 1 2 3 4)


Las 4 de estas llamadas son equivalentes a (f 1 2 3 4). apply es útil cuando los argumentos se le entregan como una secuencia, pero debe invocar la función con los valores en la secuencia.

Por ejemplo, puede usar aplicar para evitar escribir esto:


(defn plot [shape coords]   ;; coords is [x y]

  (plotxy shape (first coords) (second coords)))


En su lugar, puede simplemente escribir:


(defn plot [shape coords]

  (apply plotxy shape coords))

Primeros pasos con Clojure, parte 14


Seguimos con Clojure... 

Hay una forma más corta para la sintaxis de la función anónima fn implementada en el lector de Clojure: # (). Esta sintaxis omite la lista de parámetros y nombra los parámetros en función de su posición.

% se usa para un solo parámetro

% 1,% 2,% 3, etc. se utilizan para varios parámetros

% & se usa para los parámetros restantes (variadic)

Las funciones anónimas anidadas crearían una ambigüedad ya que los parámetros no tienen nombre, por lo que no se permite la anidación.

;; Equivalent to: (fn [x] (+ 6 x))

#(+ 6 %)

;; Equivalent to: (fn [x y] (+ x y))

#(+ %1 %2)

;; Equivalent to: (fn [x y & zs] (println x y zs))

#(println %1 %2 %&)

Primeros pasos con Clojure, parte 13


Seguimos con Clojure... 

Puede resultar útil pensar en defn como una contracción de def y fn. La fn define la función y la def la vincula a un nombre. Es decir, estas expresiones son equivalentes:

(defn greet [name] (str "Hello, " name))

(def greet (fn [name] (str "Hello, " name)))


Primeros pasos con Clojure, parte 12

 



Seguimos con Clojure... 

Clojure como buen lenguaje funcional tiene funciones anónimas, como por ejemplo : 

;;    params         body

;;   ---------  -----------------

(fn  [message]  (println message) )

Dado que la función anónima no tiene nombre, no se puede hacer referencia a ella más adelante. Más bien, la función anónima generalmente se crea en el punto en que se pasa a otra función. O es posible invocarlo inmediatamente (no es lo común):

;;     operation (function)             argument

;; --------------------------------  --------------

(  (fn [message] (println message))  "Hello world!" )


Aquí definimos la función anónima en la posición de función de una expresión más grande que inmediatamente invoca la expresión con el argumento.

Muchos lenguajes tienen tanto declaraciones, que imperativamente hacen algo y no devuelven un valor, como expresiones que lo hacen. Clojure solo tiene expresiones que devuelven un valor. Más adelante veremos que esto incluye incluso expresiones de control de flujo como el if.