Translate
lunes, 12 de febrero de 2018
Programación Orientada a Objetos en Python, parte 3
Python soporta la herencia y la herencia múltiple. Una definición de clase con múltiples clases base se ve así:
class ClaseDerivada(Base1, Base2, Base3):
<declaración-1>
.
.
.
<declaración-N>
Si un atributo no se encuentra en ClaseDerivada, se busca en Base1, luego (recursivamente) en las clases base de Base1, y sólo si no se encuentra allí se lo busca en Base2, y así sucesivamente.
El orden de resolución de métodos cambia dinámicamente para soportar las llamadas cooperativas a super(). Este enfoque es conocido en otros lenguajes con herencia múltiple como “llámese al siguiente método” y es más poderoso que la llamada al superior que se encuentra en lenguajes con sólo herencia simple.
No nos olvidemos del problema del diamante, Por ejemplo, todas las clases heredan de object, por lo tanto cualquier caso de herencia múltiple provee más de un camino para llegar a object. Para que las clases base no sean accedidas más de una vez, el algoritmo dinámico hace lineal el orden de búsqueda de manera que se preserve el orden de izquierda a derecha especificado en cada clase, que se llame a cada clase base sólo una vez, y que sea monótona (lo cual significa que una clase puede tener clases derivadas sin afectar el orden de precedencia de sus clases bases). En conjunto, estas propiedades hacen posible diseñar clases confiables y extensibles con herencia múltiple.
Programación Orientada a Objetos en Python, parte 2
Bueno, ya vimos clases y herencia en python. Esta segunda parte vamos a seguir hablando de la construcción de objetos.
La operación de instanciación crea un objeto vacío. En muchas ocasiones necesitamos crear objetos en un estado inicial particular. Por lo tanto se puede definir un método especial llamado __init__(), de esta forma:
def __init__(self):
self.datos = []
Cuando definimos un método __init__(), la instanciación de la clase automáticamente invoca a __init__(). Entonces, en este ejemplo, una instancia nueva e inicializada se puede obtener haciendo:
x = MiClase()
Por supuesto, el método __init__() puede tener argumentos para mayor flexibilidad. En ese caso, los argumentos que se pasen al operador de instanciación de la clase van a parar al método __init__(). Por ejemplo,
>>> class Complejo:
... def __init__(self, partereal, parteimaginaria):
... self.r = partereal
... self.i = parteimaginaria
...
>>> x = Complejo(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Python permite las variables de instancia son para datos únicos de cada instancia y las variables de clase son para atributos y métodos compartidos por todas las instancias de la clase:
class Perro:
tipo = 'canino' # variable de clase compartida por todas las instancias
def __init__(self, nombre):
self.nombre = nombre # variable de instancia única para la instancia
>>> d = Perro('Fido')
>>> e = Perro('Buddy')
>>> d.tipo # compartido por todos los perros
'canino'
>>> e.tipo # compartido por todos los perros
'canino'
>>> d.nombre # único para d
'Fido'
>>> e.nombre # único para e
'Buddy'
Todo valor es un objeto, y por lo tanto un objeto conoce su clase (también llamado su tipo). Ésta se almacena como objeto.__class__ y es un objeto.
La operación de instanciación crea un objeto vacío. En muchas ocasiones necesitamos crear objetos en un estado inicial particular. Por lo tanto se puede definir un método especial llamado __init__(), de esta forma:
def __init__(self):
self.datos = []
Cuando definimos un método __init__(), la instanciación de la clase automáticamente invoca a __init__(). Entonces, en este ejemplo, una instancia nueva e inicializada se puede obtener haciendo:
x = MiClase()
Por supuesto, el método __init__() puede tener argumentos para mayor flexibilidad. En ese caso, los argumentos que se pasen al operador de instanciación de la clase van a parar al método __init__(). Por ejemplo,
>>> class Complejo:
... def __init__(self, partereal, parteimaginaria):
... self.r = partereal
... self.i = parteimaginaria
...
>>> x = Complejo(3.0, -4.5)
>>> x.r, x.i
(3.0, -4.5)
Python permite las variables de instancia son para datos únicos de cada instancia y las variables de clase son para atributos y métodos compartidos por todas las instancias de la clase:
class Perro:
tipo = 'canino' # variable de clase compartida por todas las instancias
def __init__(self, nombre):
self.nombre = nombre # variable de instancia única para la instancia
>>> d = Perro('Fido')
>>> e = Perro('Buddy')
>>> d.tipo # compartido por todos los perros
'canino'
>>> e.tipo # compartido por todos los perros
'canino'
>>> d.nombre # único para d
'Fido'
>>> e.nombre # único para e
'Buddy'
Todo valor es un objeto, y por lo tanto un objeto conoce su clase (también llamado su tipo). Ésta se almacena como objeto.__class__ y es un objeto.
domingo, 11 de febrero de 2018
Programación Orientada a Objetos en Python
Como les dije anteriormente estoy estudiando nuevamente python para unas cosas que tengo que hacer. Más allá de esto, vamos a repasar los conceptos de poo en python.
Primero y principal python implementa la poo con clases, como lo hacen la mayoría de los lenguajes. Las clases son una abstracción de un conjunto de objetos, esto luego define el tipo de nuestros objetos. Veamos las clases en python:
class Objeto:
pass
class Antena:
pass
class Pelo:
pass
class Ojo:
pass
Como se puede ver se usa la convención CamelCase para el nombre de las clases, y por supuesto las clases pueden tener atributos y métodos:
class Objeto():
color = "verde"
tamanio = "grande"
aspecto = "feo"
antenas = Antena()
ojos = Ojo()
pelos = Pelo()
def flotar(self):
print 12
Por alguna razón que desconozco el primer parámetro de los métodos debe ser self (en este punto alguien me puede ayudar?). Y tambien se utiliza la misma convención.
Todo muy lindo pero donde están los objetos? veamos como instanciar objetos :
et = Objeto()
print et.color
print et.tamanio
print et.aspecto
et.color = "rosa"
print et.color
Una característica de poo es la herencia que esta implementada en python tambien, se agrega la clase padre entre paréntesis luego del nombre de la clase :
class NuevoObjeto(Objeto):
pie = Pie()
def saltar(self):
pass
Podemos heredar de la clase object que es la clase principal de Python:
class Antena(object):
color = ""
longitud = ""
class Pelo(object):
color = ""
textura = ""
Luego seguimos con el miniresumen.
sábado, 10 de febrero de 2018
Que trae de nuevo Java 9 ?
Voy a hacer un minipost de las características nuevas que trae Java 9, luego desarrollo cada una de forma individual.
JShell: REPL: Porfin!!! un repl en java. Para los que no saben que es un repl, la wikipedia dice lo siguiente : Un bucle Lectura-Evaluación-Impresión ("REPL" o "Read-Eval-Print-Loop"), también conocido como alto nivel interactivo o consola de lenguaje, es un entorno de programación computacional simple e interactivo que toma las entradas individuales del usuario, las evalúa y devuelve el resultado al usuario; un programa escrito en un entorno REPL es ejecutado parte por parte.
Métodos privados en las interfaces: Java 8 nos proporcionó la implementación de métodos predeterminado y estático en Interfaces; sin embargo, no podemos crear métodos privados en las interfaces. Si nos encontramos en una situación en la que tenemos múltiples métodos predeterminados en una interfaz que contiene la misma funcionalidad. En este escenario, normalmente refactorizaríamos estos métodos predeterminados para llamar a un método privado que contenga la funcionalidad compartida y ahora podemos hacer esto en java 9 :
public interface MyInterface {
default void interfaceDefaultMethod() { init(); }
default void interfaceSecondDefaultMethod() { init(); }
// This is the declaration of the Private Method in Interface
private void init() { ... }
}
Java 9 Module System: Claramente esto necesita un post en si. Pero para resumir podemos decir: Hasta la versión de Java 8 estábamos usando los contenedores monolíticos para diseñar nuestras aplicaciones basadas en Java. Hay dos problemas principales fundamentales con este diseño: Código difícil de encapsular y no hay ninguna noción de dependencias explícitas entre las diferentes partes de un sistema. Para evitar estos problemas fundamentales, Java 9 introdujo el sistema de módulos. Estos son algunos de los principales beneficios que obtenemos del Sistema de Módulos.
Los JDK, JRE, JAR actuales, etc. ahora están divididos en módulos más pequeños, por lo que solo podemos usar los módulos que deseamos. Esto ayuda a reducir la aplicación para dispositivos más pequeños.
Fuerte soporte para encapsulación. Las API internas no críticas están ocultas ahora, ya que los módulos ocultan detalles internos y no deseados de forma muy segura. Esto mejora la seguridad de la aplicación.
Mejoras en Javadoc: Java 9 ahora admite la búsqueda de documentación API internamente dentro de Javadoc.
HTTP/2 Client: Se ha lanzado una nueva API cliente HTTP/2 para soportar el protocolo HTTP/2 y las características de websockets. Este es un reemplazo del antiguo "HttpUrlConnection".
Nuevo esquema de cadena de versiones: Proporciona un formato de cadena de versión simplificado que ayuda a distinguir claramente las versiones principales, secundarias, de seguridad y actualización de parches.
El nuevo formato de cadena de versión se alinea con las prácticas actuales de la industria, en particular las versiones semánticas (servidor). El formato es el siguiente:
$ MAJOR. $ MENOR. $ SEGURIDAD. $ PATCH
Archivos JAR múltiple releases: Extiende el formato de archivo JAR para permitir que múltiples versiones de archivos de clase específicos de versiones de Java coexistan en un solo archivo.
Un JAR de múltiples releases (MRJAR) contiene directorios adicionales versionados para clases y recursos específicos para versiones de plataforma Java particulares.
Mejoras en Stream API: La mejora en Stream API permite filtrar flujos entrantes de datos de serialización de objetos para mejorar la seguridad y la solidez.
Los clientes de serialización de objetos pueden validar su entrada más fácilmente, y los objetos exportados de Invocación de Método Remoto (RMI) también pueden validar los argumentos de invocación más fácilmente.
Los clientes de serialización implementan una interfaz de filtro que está configurada en un ObjectInputStream. Para RMI, el objeto se exporta a través de RemoteServerRef que establece el filtro en MarshalInputStream para validar los argumentos de invocación ya que no están agrupados.
Mailrelay, una de las mejores plataformas de email marketing que existen en el mercado
MailRelay es una herramienta de envío de emails. No! No es un cliente de correo, es una plataforma de email marketing avanzado con características de gran alcance. Te permite crear, enviar y gestionar tus boletines enviados vía emails con estadísticas completas, a la vez podes analizar el comportamiento del suscriptor.
Mailing marketing ?? Si, tambien se lo conoce como ciberbuzoneo o en inglés: e-mailing es un método de marketing directo que utiliza el correo electrónico como medio de comunicación comercial para enviar mensajes a una audiencia. De esta forma podes tener al tanto a tus clientes de las novedades de tu empresa, nuevos productos, ofertas, etc...
Cuando se trata de correos masivos y envío masivo, no hay ninguna diferencia real entre los dos términos. Ambos significan envío masivo de email promocional para sus clientes y contactos. A veces, las personas confunden con correos masivos de spam. Sin embargo, la diferencia entre ambos es que el spam es no solicitado, mientras que el correo masivo es basado en permisos. Email marketing masivo tiene algunas ventajas muy profundas sobre todas las demás formas de marketing.
Con MailRelay podemos crear boletines y enviárselas a un grupo de suscriptores, a la vez la herramienta analiza el comportamiento del subscriptor, de esta forma podemos saber cual es el articulo más visitado, y que suscriptores vieron que articulo pudiendo analizar las necesidades de los clientes según esta información.
MailRelay no solo permite crear campañas de email marketing sino que tambien darle un correcto seguimiento y tener un contacto real con los clientes. Y es muy importante este seguimiento tanto para fidelizar al cliente como para estimular las ventas.
Entre otras ventajas podemos nombrar:
- Un seguimiento inteligente de los clientes: con esta herramienta podes saber que necesita cada suscriptor y podemos hacer un seguimiento de los clientes y sus necesidades.
- No vamos a ser catalogados como spam: Mailrelay cumple con todas las normas de correo electrónico anti-spam, haciendo que la puntuación antispam sea menos posible.
- Templates para nuestros boletines: Mailrelay cuenta con una completa biblioteca de templates gratuitos que podemos utilizar.
- SMTP de alto rendimiento: Mailrelay nos ofrece un servicio smtp que se distingue por su alto rendimiento.
- Facilidad de uso: No es necesario que contrates a un programador o un diseñador gráfico, cualquier persona puede utilizar este servicio.
- Atención personalizada: Recibe atención personalizada y respuesta inmediata a tus dudas.
Hoy día son muchas las empresas que buscan vender más, conseguir más visibilidad, fidelizar a sus clientes y destacar sobre su competencia. Objetivos todos dirigidos a garantizar la viabilidad de la empresa o proyecto. Objetivos que no son nada fáciles de conseguir y mantener.
Mailrelay tiene más de 15 años de experiencia en e-mail marketing, tanto desarrollando una herramienta de email marketing efectiva, como es Mailrelay, como ayudando a los clientes a mejorar sus resultados, llegar a la bandeja de entrada, solucionar sus problemas de spam, etc.
Como conclusión les aconsejo que vean con buenos ojos a Mailrelay dado su excelente soporte y sus ofertas. Y además es un excelente producto. Mailrelay te permite gestionar tu e-mail marketing de forma fácil y efectiva
Dejo link:
https://mailrelay.com/es
martes, 6 de febrero de 2018
20 libros que un desarrollador java debe leer en el 2018
En Dzone nos sugieren libros para leer en el 2018 y estoy bastante de acuerdo con la lista por lo tanto la comparto:
Puff!! Tenemos mucho para leer!!
Dejo link: https://dzone.com/articles/20-books-java-programmers-should-read-in-2018
1. Java 8 in Action
2. Clean Architecture
3. Grokking Algorithms
4. Building Microservices: Designing Fine-Grained Systems
5. Soft Skills
6. Database Design for Mere Mortals
7. Making Java Groovy
8. Groovy in Action, Second Edition
9. TCP/IP Illustrated
10. UML Distilled
11. Hibernate Tips
12. The Art of Agile Development
13. Essential Scrum
14. Java Performance Companion
15. High-Performance Java Persistence
16. Functional Programming in Scala
17. Scala for the Impatient
18. Head First JavaScript
19. SQL CookBook
20. The Complete Software Developer's Career Guide
Dejo link: https://dzone.com/articles/20-books-java-programmers-should-read-in-2018
lunes, 5 de febrero de 2018
Empezando con Elixir 11
Sigils
Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde ~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils cuando necesitamos extender el lenguaje.
Los Sigils disponibles son:
~ C Genera una lista de caracteres sin escape ni interpolación
~ c Genera una lista de caracteres con escape e interpolación
~ R Genera una expresión regular sin escape ni interpolación
~ r Genera una expresión regular con escape e interpolación
~ S Genera una cadena sin escape ni interpolación
~ s Genera una cadena con escape e interpolación
~ W Genera una lista de palabras sin escape ni interpolación
~ w Genera una lista de palabras con escape e interpolación
~ N genera una estructura NaiveDateTime
Una lista de delimitadores incluye:
<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples
Lista de caracteres
~c y ~C generan una lista de caracteres:
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = \#{2 + 7}'
Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.
Expresiones regulares
~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:
iex> re = ~r/elixir/
~r/elixir/
iex> "Elixir" =~ re
false
iex> "elixir" =~ re
true
Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.
iex> re = ~r/elixir/i
~r/elixir/i
iex> "Elixir" =~ re
true
iex> "elixir" =~ re
true
Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:
iex> string = "100_000_000"
"100_000_000"
iex> Regex.split(~r/_/, string)
["100", "000", "000"]
String
~s y ~S se utilizan para generar cadenas. Por ejemplo:
iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"
iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"
¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:
iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"
iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"
Word List
La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:
iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]
Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:
iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]
NaiveDateTime
Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.
En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}
Crear un Sigils
Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.
iex> defmodule MySigils do
...> def sigil_u(string, []), do: String.upcase(string)
...> end
iex> import MySigils
nil
iex> ~u/elixir school/
ELIXIR SCHOOL
Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.
Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde ~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils cuando necesitamos extender el lenguaje.
Los Sigils disponibles son:
~ C Genera una lista de caracteres sin escape ni interpolación
~ c Genera una lista de caracteres con escape e interpolación
~ R Genera una expresión regular sin escape ni interpolación
~ r Genera una expresión regular con escape e interpolación
~ S Genera una cadena sin escape ni interpolación
~ s Genera una cadena con escape e interpolación
~ W Genera una lista de palabras sin escape ni interpolación
~ w Genera una lista de palabras con escape e interpolación
~ N genera una estructura NaiveDateTime
Una lista de delimitadores incluye:
<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples
Lista de caracteres
~c y ~C generan una lista de caracteres:
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = \#{2 + 7}'
Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.
Expresiones regulares
~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:
iex> re = ~r/elixir/
~r/elixir/
iex> "Elixir" =~ re
false
iex> "elixir" =~ re
true
Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.
iex> re = ~r/elixir/i
~r/elixir/i
iex> "Elixir" =~ re
true
iex> "elixir" =~ re
true
Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:
iex> string = "100_000_000"
"100_000_000"
iex> Regex.split(~r/_/, string)
["100", "000", "000"]
String
~s y ~S se utilizan para generar cadenas. Por ejemplo:
iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"
iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"
¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:
iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"
iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"
Word List
La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:
iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]
Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:
iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]
NaiveDateTime
Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.
En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}
Crear un Sigils
Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.
iex> defmodule MySigils do
...> def sigil_u(string, []), do: String.upcase(string)
...> end
iex> import MySigils
nil
iex> ~u/elixir school/
ELIXIR SCHOOL
Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.
viernes, 2 de febrero de 2018
Un resumen de Scala for the Impatient, parte 36
Operadores de asignación.
Los operadores de asignación tienen la forma operador= y se utilizan de la siguiente forma:
a operator= b
que es igual a decir :
a = a operator b
Por ejemplo a+= b es equivalente a escribir a = a + b
Hay unos detalles técnicos :
<=, >= y != no son operadores de asignación
Un operador que comienza con = nunca es un operador de asignación (==, ===, =/=, etc)
Si a tiene un operador llamado operator= entonces este sera llamado directamente.
Precedencia.
Cuando tenemos más de un operador, sin paréntesis debemos definir las precedencias de los operadores. Dado que esto define el orden de resolución, por ejemplo :
1 + 2 * 3
El operador * se evalúa primero y luego la suma, esto fue definido por conversión. Lenguajes como C++ y Java tienen un numero fijo de operadores por lo tanto es más sencillo definir la precedencias (se pueden enumerar). En cambio en Scala tenemos un numero arbitrario de operadores por lo que se debe definir esto de forma general.
- La precedencia más alta esta dada por un caracter operador que no sea los antesesores.
- * / %
- + -
- :
- < >
- ! =
- &
- ^
- |
- Un carácter que no es un operador
- La menor precedencia es el operador de asignación
Los caracteres que estan en similar fila tiene similar precedencia. Por ejemplo + y -
Los operadores infijos tienen menor precedencia, por lo tanto :
a infixOp b postfixOp es similar a (a infixOp b)postfixOp
Asociatividad
Luego de definir la precedencia, es importante la asociatividad dado que exiten operadores que son asociativos. Por ejemplo 17 – 2 – 9 es similar a (17 – 2) – 9. El operador – es asociativo por la izquierda.
En scala todos los operadores son asociativos por la izquierda excepto :
- Los operadores que finalizan en :
- Los operadores de asignación.
Por ejemplo el operador :: construye listas con asosciatividad a la derecha por ejemplo :
1 :: 2 :: Nil esto es similar a 1 :: (2 :: Nil)
Esto generara una lista con elemento 1 y 2 es ese orden. Es decir el operador :: es un metodo de la lista que ingresa un elemento por la izquierda, convirtiendolo en el primer elemento.
Es decir 2 :: Nil es igual a Nil.::(2)
jueves, 1 de febrero de 2018
Aprende Go con un video
Go es un lenguaje de google, que rápidamente tomo importancia. Es un lenguaje interesante no solo por las características que tiene sino por las que no tiene. Es decir, se tomaron decisiones que son controversiales para el mundo del software.
Este video de casi una hora trata de darnos una primera pasada por el lenguaje, es un tur completo por el lenguaje. Esta muy bueno y todo muy bien explicado.
Este video de casi una hora trata de darnos una primera pasada por el lenguaje, es un tur completo por el lenguaje. Esta muy bueno y todo muy bien explicado.
miércoles, 31 de enero de 2018
Google lanzo Puppeteer 1.0
Puppeteer es una herramienta de automatización de pruebas esta basado en Chrome. Aprovechando Node.js y el protocolo Chrome DevTools, Puppeteer proporciona una alternativa a Selenium WebDriver.
Más allá del típico caso de uso de pruebas automáticas del navegador, Puppeteer se puede utilizar para una variedad de técnicas de automatización del navegador, incluida la realización de tareas repetitivas, el contenido de raspado y la generación de capturas de pantalla.
El proyecto proporciona un Try Puppeteer con el cual podemos comenzar rápidamente con Puppeteer.
Desde su lanzamiento inicial, Puppeteer ha sido ampliamente adoptado como una forma más sencilla de introducir la automatización en el flujo de trabajo del desarrollador. Muchos desarrolladores han escrito extensos tutoriales y brindado sus comentarios sobre el trabajo con Puppeteer.
Por lo que vamos a tener que probarlo.
Dejo link: https://github.com/GoogleChrome/puppeteer/
Más allá del típico caso de uso de pruebas automáticas del navegador, Puppeteer se puede utilizar para una variedad de técnicas de automatización del navegador, incluida la realización de tareas repetitivas, el contenido de raspado y la generación de capturas de pantalla.
El proyecto proporciona un Try Puppeteer con el cual podemos comenzar rápidamente con Puppeteer.
Desde su lanzamiento inicial, Puppeteer ha sido ampliamente adoptado como una forma más sencilla de introducir la automatización en el flujo de trabajo del desarrollador. Muchos desarrolladores han escrito extensos tutoriales y brindado sus comentarios sobre el trabajo con Puppeteer.
Por lo que vamos a tener que probarlo.
Dejo link: https://github.com/GoogleChrome/puppeteer/
sábado, 20 de enero de 2018
Consultar APIs REST con restQL
RestQL es un lenguaje de consultas de microservicio que facilita la obtención de información de múltiples servicios de la manera más eficiente. Parecido a GraphQL
Veamos un ejemplo:
from hero
with
name = "Restman"
from sidekick
with
hero = hero.id
only
skills
RestQL se integra a la perfección con su arquitectura de microservicio actual.
Solo se debe configurar los end points del servicio, corremos el servidor de restQL y luego comencemos a consultar.
Una arquitectura basada en microservicios no es una bala de plata. A pesar de sus beneficios inmediatos para los equipos de servicio, plantea por su propia naturaleza un desafío en términos de complejidad y rendimiento para los consumidores. restQL tiene como objetivo resolver esta brecha, reduciendo los viajes redondos y simplificando la orquestación de microservicios.
Dejo link:
http://restql.b2w.io/
Veamos un ejemplo:
from hero
with
name = "Restman"
from sidekick
with
hero = hero.id
only
skills
RestQL se integra a la perfección con su arquitectura de microservicio actual.
Solo se debe configurar los end points del servicio, corremos el servidor de restQL y luego comencemos a consultar.
Una arquitectura basada en microservicios no es una bala de plata. A pesar de sus beneficios inmediatos para los equipos de servicio, plantea por su propia naturaleza un desafío en términos de complejidad y rendimiento para los consumidores. restQL tiene como objetivo resolver esta brecha, reduciendo los viajes redondos y simplificando la orquestación de microservicios.
Dejo link:
http://restql.b2w.io/
miércoles, 17 de enero de 2018
Instalar mint desde un usb
Me toco instalar Linux Mint desde un usb y me llamo la atención lo fácil que es.
Los pasos a seguir son los siguientes:
- Bajamos la imagen de linux mint.
- Luego iniciamos una aplicación llamada mintStick
- Elegimos la imagen ISO, elegimos la unidad USB y presionamos empezar (ojo que esto nos va a borrar el contenido del usb)
- Luego este proceso demorara unos minutos.
- Y listo, ahora a bootear con el USB y comenzar el proceso de instalación como lo hacemos normalmente.
Así de simple, luego a disfrutar de nuestro mint!
domingo, 14 de enero de 2018
Empezando con Python de nuevo!
Hace mucho mucho tiempo que no hago nada en python y por x motivo debo volver a programar en este lenguaje. Por suerte me tope con la pagina: http://www.python.org.ar/ . En la cual se puede encontrar muchos recursos para empezar y de muy buena calidad.
Aprendiendo Python
¡Felicitaciones! No todos los días se toma el coraje de adentrarse en un mundo desconocido para muchos y tan divertido para otros. Me pone muy contento que te haya surgido la inquietud de ver "¿de qué se trata esto de Python?" y hayas llegado a este sitio web.
Aquí podrás encontrar unos pequeños lineamientos que te pueden ser de gran ayuda a la hora de aprender a programar en Python. Incluso, si no tienes conocimiento alguno de programación.
Antes que nada, algunos consejos para que no te desanimes en el camino del aprendizaje y te resulte más sencillo:
- Programar es muy divertido, pero como cualquier otra disciplina: lleva tiempo.
- A diferencia de otros lenguajes de programación, Python tiene una curva de aprendizaje mucho más rápida, lo cual te permitirá obtener resultados casi de inmediato.
- Al fin y al cabo, era mucho más fácil aprender a programar (y mantenerse actualizado) si se dominaba, al menos, un nivel básico de Inglés.
- Cualquiera puede aprender a programar. ¡Sí, cualquiera! No hay que ser un genio ni un maestro en nada. Yo pude, ;)
- En el camino, aprenderás a investigar y a resolver problemas por tu propia cuenta. Simplemente, con una conexión a Internet y leyendo varios foros/listas de correo o preguntando en diferentes canales de chat.
- ¡Sí, eso! Suscríbete a la lista de correo de tu región para así poder hacerle preguntas a otras personas que tienen más experiencia en el tema y siempre tienen ganas de ayudar.
¡Ahora sí, vamos a lo importante y centrémonos en aprender!
La teoría es cuando creés saber algo pero no anda. La práctica es cuando algo funciona pero no sabés porqué. El programador combina ambas: nada anda y no sabe porqué.Einstein + Anónimo
Antes de empezar a leer fuertemente los libros o tutoriales que te recomendamos aquí, me parece muy bueno pegarle una primera ojeada a algunos de ellos (los que más te llamen la atención) y en base a eso, determinar cuál puede ser más divertido y entusiasmante empezar a leer. Incluso, ¡hay algunos que son interactivos y están buenísimos!
¿Por dónde empezar?
No sé nada de Python, ni de programación, y quiero empezar desde lo más básico:
¿Por dónde seguir?
Tengo algún conocimiento en programación, o incluso en Python, y quiero leer algo un poquito más avanzado:
Me manejo con el Inglés
Tengo un dominio básico de lectura en inglés.
Soy científico y quiero analizar mis datos
Pertenezco al mundo de las ciencias de alguna manera: biología, química, genética, matemática, física, <coloque aquí su ciencia preferida> y quiero aprender a utilizar Python, por ejemplo, para analizar un enorme conjunto de datos de una forma automatizada.
Muchísimo más material!
¡Me re copé con Python, leí un montón de cosas y ahora quiero rockearla!
Aquí listamos todo el material excedente que consideramos muy útil para seguir con el estudio de Python y la programación, pero que quizás desorienta un poco al principio. En esta sección podés encontrar otras guías similares a esta, más herramientas y módulos, documentación que se encuentra en progreso y diferentes tutoriales orientados a públicos distintos.
- Byte of Python es un libro para iniciarse en Python, el autor proclama que es para quien lo unico que sabe de computación es grabar un archivo. Actualmente cuenta con ediciones para Python 2.x y 3.
- Instant Python es un curso de entrenamiento corto e intensivo. (Versión en español).
- Python Ya Python desde cero. Tutorial web interactivo. Permite escribir y ejecutar nuestros programas directamente en la página, sin necesidad de tener Python instalado.
- Tutor para No-Programadores Josh Cogliati 1999-2002 - Traducción Victor M. Rosas Garcia.
- Python no muerde - Roberto Alsina
- Python para todos Raúl González Duque
- El libro de Web2py en español
- El wiki oficial de Apache OpenOffice - Como crear macros con Python
sábado, 13 de enero de 2018
Empezando con Elixir 10
Mix
Antes de que podamos sumergirnos en las aguas más profundas de Elixir, primero tenemos que aprender Mix. Si está familiarizado con Ruby, Mix es Bundler, RubyGems y Rake combinados. Es una parte crucial de cualquier proyecto de Elixir y en esta lección vamos a explorar solo algunas de sus excelentes características.
Hasta ahora hemos estado trabajando exclusivamente dentro de iex, que tiene limitaciones. Para construir algo sustancial necesitamos dividir nuestro código en muchos archivos para administrarlo efectivamente; Mix nos permite hacer eso con proyectos.
Proyectos
Para hacer un nuevo proyecto debemos hacer :
$ mix new example
De la salida podemos ver que Mix ha creado nuestro directorio y una serie de archivos:
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/example.ex
* creating test
* creating test/test_helper.exs
* creating test/example_test.exs
Vamos a centrarnos mix.exs. Aquí configuramos nuestra aplicación, dependencias, entorno y versión. Vamos abrir este archivo :
defmodule Example.Mixfile do
use Mix.Project
def project do
[app: :example,
version: "0.0.1",
elixir: "~> 1.1-dev",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps]
end
# Configuration for the OTP application
#
# Type `mix help compile.app` for more information
def application do
[applications: [:logger]]
end
# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type `mix help deps` for more examples and options
defp deps do
[]
end
end
Antes de que podamos sumergirnos en las aguas más profundas de Elixir, primero tenemos que aprender Mix. Si está familiarizado con Ruby, Mix es Bundler, RubyGems y Rake combinados. Es una parte crucial de cualquier proyecto de Elixir y en esta lección vamos a explorar solo algunas de sus excelentes características.
Hasta ahora hemos estado trabajando exclusivamente dentro de iex, que tiene limitaciones. Para construir algo sustancial necesitamos dividir nuestro código en muchos archivos para administrarlo efectivamente; Mix nos permite hacer eso con proyectos.
Proyectos
Para hacer un nuevo proyecto debemos hacer :
$ mix new example
De la salida podemos ver que Mix ha creado nuestro directorio y una serie de archivos:
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/example.ex
* creating test
* creating test/test_helper.exs
* creating test/example_test.exs
Vamos a centrarnos mix.exs. Aquí configuramos nuestra aplicación, dependencias, entorno y versión. Vamos abrir este archivo :
defmodule Example.Mixfile do
use Mix.Project
def project do
[app: :example,
version: "0.0.1",
elixir: "~> 1.1-dev",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps]
end
# Configuration for the OTP application
#
# Type `mix help compile.app` for more information
def application do
[applications: [:logger]]
end
# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type `mix help deps` for more examples and options
defp deps do
[]
end
end
La primera sección es project. Aquí definimos el nombre de nuestra aplicación (app), especificamos nuestra versión (version), versión de Elixir (elixir) y finalmente nuestras dependencias (deps).
En application configuramos settings que se usa durante la generación de nuestro archivo de aplicación.
Interactivo
Puede ser necesario usar iex dentro del contexto de nuestra aplicación. Afortunadamente para nosotros, Mix lo hace fácil. Podemos comenzar una nueva sesión iex:
$ iex -S mix
Iniciar iex de esta manera cargará la aplicación y dependencias en el tiempo de ejecución.
Compilacion
Mix es inteligente y compilará los cambios cuando sea necesario. Para compilar de forma manual un proyecto Mix solo necesitamos ejecutar la compilación de Mix en nuestro directorio base:
$ mix compile
si se compilo con exito retornará :
Compiled lib/example.ex
Generated example app
Cuando compilamos un proyecto Mix crea un directorio _build para nuestros artefactos. Si miramos dentro de _build veremos nuestra aplicación compilada: example.app.
Administrar dependencias
Nuestro proyecto no tiene dependencias, pero lo hará en breve, así que seguiremos adelante y cubriremos las dependencias definitorias y las buscaremos.
Para agregar una nueva dependencia, primero debemos agregarla a nuestra mix.exs en la sección deps. Nuestra lista de dependencias se compone de tuplas con dos valores obligatorios y uno opcional: el nombre del paquete como un átomo, la cadena de versión y opciones.
Para este ejemplo, veamos un proyecto con dependencias, con phoenix_slim:
def deps do
[
{:phoenix, "~> 1.1 or ~> 1.2"},
{:phoenix_html, "~> 2.3"},
{:cowboy, "~> 1.0", only: [:dev, :test]},
{:slime, "~> 0.14"}
]
end
La dependencia cowboy solo es necesaria durante el desarrollo y la prueba.
Una vez que hemos definido nuestras dependencias, hay un último paso: obtenerlas. Esto es análogo a la instalación del paquete:
$ mix deps.get
Hemos definido y buscado nuestras dependencias de proyectos.
Entornos
Mix, al igual que Bundler, admite diferentes entornos. Mix funciona con tres entornos:
- :dev - El entorno predeterminado.
- :test - Usado por la prueba de mezcla. Cubierto más en nuestra próxima lección.
- :prod - se usa cuando enviamos nuestra aplicación a producción.
Se puede acceder al entorno actual utilizando Mix.env. Como se esperaba, el entorno se puede cambiar a través de la variable de entorno MIX_ENV:
$ MIX_ENV=prod mix compile
Comparando F# con C# parte 3
Vamos ha hacer un programa que baje una pagina en F# y en C# para comparar.
Veamos la implementación en F# :
// open es similar al using
open System.Net
open System
open System.IO
// Obtener los contenidos de una página web
let fetchUrl callback url =
let req = WebRequest.Create(Uri(url))
use resp = req.GetResponse()
use stream = resp.GetResponseStream()
use reader = new IO.StreamReader(stream)
callback reader url
Repasemos este código:
Ahora veamos la implementación equivalente de C#:
class WebPageDownloader
{
public TResult FetchUrl<TResult>(
string url,
Func<string, StreamReader, TResult> callback)
{
var req = WebRequest.Create(url);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
return callback(url, reader);
}
}
}
}
}
Como de costumbre, la versión C # tiene más 'ruido'.
Veamos la implementación en F# :
// open es similar al using
open System.Net
open System
open System.IO
// Obtener los contenidos de una página web
let fetchUrl callback url =
let req = WebRequest.Create(Uri(url))
use resp = req.GetResponse()
use stream = resp.GetResponseStream()
use reader = new IO.StreamReader(stream)
callback reader url
Repasemos este código:
- El "open" en la parte superior nos permite escribir "WebRequest" en lugar de "System.Net.WebRequest". Es similar a un encabezado "using System.Net" en C#.
- A continuación, definimos la función fetchUrl, que toma dos argumentos, un callback para procesar la pagina y la URL a buscar.
- Luego, creamos una Uri con la URL. F# tiene una estricta comprobación de tipos, por lo tanto, si en hubiéramos escrito: let req = WebRequest.Create(url), el compilador se habría quejado de que no sabía qué versión de WebRequest.Create usar.
- Al declarar los valores de respuesta, transmisión y lectura, se usa la palabra clave "use" en lugar de "let". Esto solo se puede usar junto con las clases que implementan IDisposable. Le dice al compilador que elimine automáticamente el recurso cuando se sale del alcance. Esto es equivalente a la palabra clave "using" C#.
- La última línea llama a la función callback con StreamReader y la url como parámetros. Note que nunca especificamos el timpo del callback.
Ahora veamos la implementación equivalente de C#:
class WebPageDownloader
{
public TResult FetchUrl<TResult>(
string url,
Func<string, StreamReader, TResult> callback)
{
var req = WebRequest.Create(url);
using (var resp = req.GetResponse())
{
using (var stream = resp.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
return callback(url, reader);
}
}
}
}
}
Como de costumbre, la versión C # tiene más 'ruido'.
- Hay diez líneas solo para llaves, y existe la complejidad visual de 5 niveles de anidación *
- Todos los tipos de parámetros deben declararse explícitamente, y el tipo TResult genérico debe repetirse tres veces.
Podemos probar el codigo de la siguiente manera :
let myCallback (reader:IO.StreamReader) url =
let html = reader.ReadToEnd()
let html1000 = html.Substring(0,1000)
printfn "Downloaded %s. First 1000 is %s" url html1000
html // return all the html
//test
let google = fetchUrl myCallback "http://google.com"
Finalmente, tenemos que recurrir a una declaración de tipo para el parámetro del lector (reader:IO.StreamReader). Esto es necesario porque el compilador F# no puede determinar el tipo del parámetro "reader" automáticamente.
Una característica muy útil de F# es que puede "pasar" parámetros en una función para que no tengan que pasarse en todo momento. Esta es la razón por la que el parámetro url se colocó en último lugar en lugar de primero, como en la versión de C#. La devolución de llamada se puede configurar una vez, mientras que la URL varía de llamada a llamada.
// build a function with the callback "baked in"
let fetchUrl2 = fetchUrl myCallback
// test
let google = fetchUrl2 "http://www.google.com"
let bbc = fetchUrl2 "http://news.bbc.co.uk"
// test with a list of sites
let sites = ["http://www.bing.com";
"http://www.google.com";
"http://www.yahoo.com"]
// process each site in the list
sites |> List.map fetchUrl2
La última línea (usando List.map) muestra cómo la nueva función se puede usar fácilmente junto con las funciones de procesamiento de listas para descargar una lista completa a la vez.
Aquí está el código de prueba C# equivalente:
[Test]
public void TestFetchUrlWithCallback()
{
Func<string, StreamReader, string> myCallback = (url, reader) =>
{
var html = reader.ReadToEnd();
var html1000 = html.Substring(0, 1000);
Console.WriteLine(
"Downloaded {0}. First 1000 is {1}", url,
html1000);
return html;
};
var downloader = new WebPageDownloader();
var google = downloader.FetchUrl("http://www.google.com",
myCallback);
// test with a list of sites var sites = new List<string> {
"http://www.bing.com",
"http://www.google.com",
"http://www.yahoo.com"};
// process each site in the list
sites.ForEach(site => downloader.FetchUrl(site, myCallback));
sites.ForEach(site => downloader.FetchUrl(site, myCallback));
}
De nuevo, el código tiene más ruido que el código F#, con muchas referencias explícitas de tipo. Lo que es más importante, el código C# no le permite pasar fácilmente algunos de los parámetros en una función, por lo que la devolución de llamada se debe referenciar explícitamente cada vez.
Suscribirse a:
Entradas (Atom)