Translate

domingo, 8 de octubre de 2017

Swift 4 fue liberado



Este post llega muy tarde pero llego! Swift 4 fue liberado (hace rato)

Esta versión contiene muchos cambios y actualizaciones del lenguaje y la biblioteca estándar, especialmente las nuevas funciones de String, las colecciones extendidas, archivo y la serialización, entre otros.

En Swift 4 las cadenas son colecciones propiamente dichas por lo cual son directamente iterable y proporciona todos los métodos de las colecciones y las secuencias, por ejemplo:

for c in myString {
  print(c)
}
myString.filter { c in
  return boolCheck(c)
}
let l = myString.count
let myString2 = myString.dropFirst()

Otra nueva característica es que ahora los string soportan Unicode 9 and literales multi-lineas.

Swift 4 también mejora la forma en que puedes crear, usar y administrar tipos de colecciones, como Dictionary y Set.

En primer lugar, ahora puede crear un diccionario a partir de una secuencia de tuplas, así como especificar cómo manejar los duplicados, si los hay, tanto al crear un diccionario como al fusionar dos diccionarios:

let items = ["ItemA", "ItemB", "ItemC", "ItemA"]
let prices = [14.40, 41.63, 3.71, 15.63]
let catalog1 = Dictionary(uniqueKeysWithValues: zip(items, prices))
let catalog2 = Dictionary(prices, uniquingKeysWith: { (l, r) in
    l })
let catalog3 = Dictionary(prices, uniquingKeysWith: { (l, r) in
    l + r })
let merged = catalog.merge(catalog3) { (l, r) in r }

Dictionary y Set ahora se puede filtrar en otro  tipo, en lugar de en un Array. Además, los diccionarios soportan un nuevo método mapValues:

let catalog4 = catalog.filter { $0.value < 15.0 }
let catalog5 = catalog.mapValues { $0 * 1.2 }

Otra característica útil en los diccionarios es la posibilidad de especificar un valor predeterminado al acceder a sus elementos:

let price1 : Float = catalog['none', default: 0.0]
let price2 : Float? = catalog['none']

Swift 4 añade serialización a todos los tipos a través del protocolo Codable. Por ejemplo:

struct Card: Codable, Equatable {
    enum Suit: String, Codable {
        case clubs, spades, hearts, diamonds
    }

    enum Rank: Int, Codable {
        case two = 2, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace
    }

    var suit: Suit
    var rank: Rank

    static func ==(lhs: Card, rhs: Card) -> Bool {
        return lhs.suit == rhs.suit && lhs.rank == rhs.rank
    }
}
let hand = [Card(suit: .clubs, rank: .ace), Card(suit: .hearts, rank: .queen)]

Por ultimo, Swift 4 tiene dos modos, seleccionados a través de la opción -swift-version compiler. En el modo Swift 3.2, el compilador aceptará la mayoría de fuentes compatibles con los compiladores Swift 3.x. En este modo, la mayoría de las características del lenguaje Swift 4 estarán disponibles, pero las actualizaciones de las API existentes anteriormente no. En el modo Swift 4.0, obtendrá acceso a todas las funciones de Swift 4, a expensas de algunos cambios de origen, que como de costumbre pueden manejarse utilizando el asistente de migración de Xcode.

Ojo!! Hay mucho más para Swift 4.

Dejo link:
https://www.infoq.com/news/2017/09/swift-4-official-release
https://swift.org

jueves, 5 de octubre de 2017

Un resumen de Scala for the Impatient, parte 31


Sobre escribir métodos abstractos en Traits

Del ejemplo anterior, podemos deducir que TimestampLogger y ShortLogger extienden de ConsoleLogger, la cual extiende del trait Logger el cual no tiene implementación para el método log

trait Logger {
    def log(msg: String) // This method is abstract
}

Por lo tanto

trait TimestampLogger extends Logger {
    override def log(msg: String) { // Overrides an abstract method
        super.log(s"${java.time.Instant.now()} $msg") // Is super.log defined?
    }
}

Esto no debería compilar porque super.log no fue definido pero scala lo toma como que la clase TimestampLogger es abstracta y solo se puede utilizar si se mixea con una clase que implemente este método

Traits para interfaces ricas.

Un trait puede tener muchos métodos útiles que dependan de unos pocos abstractos. Un ejemplo de esto es el Iterator que define docenas de métodos en términos de los métodos abstractos next y hasnext. Vamos a construir métodos que nos permitan imprimir diferentes tipos de logs     

trait Logger {
def log(msg: String)
def info(msg: String) { log(s"INFO: $msg") }
def warn(msg: String) { log(s"WARN: $msg") }
def severe(msg: String) { log(s"SEVERE: $msg") }
}

Note que estamos combinando métodos abstractos con implementaciones concretas. 

abstract class SavingsAccount extends Account with Logger {
def withdraw(amount: Double) {
if (amount > balance) severe("Fondos insuficientes")
else …
}
}

Un campo concreto en Traits

Un campo de un traits puede ser concreto o abstracto. Si se asigna un valor al campo este será concreto, 

trait ShortLogger extends Logger {
val maxLength = 15 // A concrete field
abstract override def log(msg: String) {
super.log(
if (msg.length <= maxLength) msg
else s"${msg.substring(0, maxLength – 3)}...")
}
}

 Una clase puede mixear con el campo maxLenght

class SavingsAccount extends Account with ConsoleLogger with ShortLogger {
     var interest = 0.0
     def withdraw(amount: Double) {
          if (amount > balance) log("Fondos insuficientes")
          else …
     }
}

Note que la clase SavingsAccount tiene la variable interest, pero no balance, balance viene de Account

class Account {
     var balance = 0.0
}

La maquina virtual java no permite heredar campos de diferentes interfaces o super clases, por lo que el compilador scala debe copiarlos. 

Campos abstractos en Traits

Los campos que no son inicializados son abstractos, y deben ser sobreescritos por la subclase concreta. 

Por ejemplo: 

trait ShortLogger extends Logger {
     val maxLength: Int // An abstract field
     
      abstract override def log(msg: String) { ... }

      super.log(
                if (msg.length <= maxLength) msg
                else s"${msg.substring(0, maxLength – 3)}...")
                // El campo maxLength es utilizado en la implementación. 
}

Cuando se utiliza este trait se debe asignar un valor a maxLength: 

class SavingsAccount extends Account with ConsoleLogger with ShortLogger {
     val maxLength = 20 // No es necesario escribir override
}

Ahora todos los mensajes de registro se truncan después de 20 caracteres.

Esta forma de proporcionar valores para los parámetros de rasgo es particularmente útil cuando se construyen objetos sobre la marcha. Volvamos a nuestra cuenta de ahorros original:

class SavingsAccount extends Account with Logger { ... }

Ahora, podemos truncar los mensajes en una instancia de la siguiente manera:

val acct = new SavingsAccount with ConsoleLogger with ShortLogger {
      val maxLength = 20
}


miércoles, 4 de octubre de 2017

Monitoriando tu servidor con Monit

Tuve un requerimiento especial, me pidieron que cuando se baje el server (en este caso un tomcat se envíe un mail) y gracias a este requerimiento conocí a Monit

Monit es un software que se utiliza en linux con el podemos monitoriar nuestro servidor, procesos, aplicaciones, archivos, etc. Muy fácil de configurar podemos indicarle que nos envíe mail cuando hay un evento determinado o que baje una aplicación o que la reinicie.

Es muy fácil de instalar y configurar. Si estamos en alguna distribución rhel, la instalación sería:

 yum install monit

o en distros basadas en debian:

sudo apt-get install monit

Una vez instalado debemos modificar el archivo /etc/monit.conf esta muy bien comentado y tiene ejemplos de configuraciones, para escuchar procesos o servicio o archivos. Otra cosa que esta muy buena es que se puede enviar una notificación cuando un proceso ocupa mucho cpu o memoria.

Veamos un ejemplo de monit.conf :

###############################################################################
## Monit control file
###############################################################################
##
## Comments begin with a '#' and extend through the end of the line. Keywords
## are case insensitive. All path's MUST BE FULLY QUALIFIED, starting with '/'.
##
## Below you will find examples of some frequently used statements. For 
## information about the control file, a complete list of statements and 
## options please have a look in the monit manual.
##
##
###############################################################################
## Global section
###############################################################################
##
## Start monit in the background (run as a daemon):
#
set daemon  120           # check services at 2-minute intervals
    with start delay 240  # optional: delay the first check by 4-minutes
#                           # (by default check immediately after monit start)
#
#
## Set syslog logging with the 'daemon' facility. If the FACILITY option is
## omitted, monit will use 'user' facility by default. If you want to log to 
## a stand alone log file instead, specify the path to a log file
#
set logfile syslog facility log_daemon                       
#
#
### Set the location of monit id file which saves the unique id specific for
### given monit. The id is generated and stored on first monit start.
### By default the file is placed in $HOME/.monit.id.
#
# set idfile /var/.monit.id
#
### Set the location of monit state file which saves the monitoring state
### on each cycle. By default the file is placed in $HOME/.monit.state. If
### state file is stored on persistent filesystem, monit will recover the
### monitoring state across reboots. If it is on temporary filesystem, the
### state will be lost on reboot.
#
# set statefile /var/.monit.state
#
## Set the list of mail servers for alert delivery. Multiple servers may be 
## specified using comma separator. By default monit uses port 25 - this
## is possible to override with the PORT option.
#
set mailserver localhost
#
#
## By default monit will drop alert events if no mail servers are available. 
## If you want to keep the alerts for a later delivery retry, you can use the 
## EVENTQUEUE statement. The base directory where undelivered alerts will be 
## stored is specified by the BASEDIR option. You can limit the maximal queue
## size using the SLOTS option (if omitted, the queue is limited by space 
## available in the back end filesystem).
#
# set eventqueue
#     basedir /var/monit  # set the base directory where events will be stored
#     slots 100           # optionaly limit the queue size
#
#
## Send status and events to M/Monit (Monit central management: for more
## informations about M/Monit see http://www.tildeslash.com/mmonit).
#
# set mmonit http://monit:monit@192.168.1.10:8080/collector
#
#
## Monit by default uses the following alert mail format:
##
## --8<--
## From: monit@$HOST                         # sender
## Subject: monit alert --  $EVENT $SERVICE  # subject
##
## $EVENT Service $SERVICE                   #
##                                           #
## Date:        $DATE                   #
## Action:      $ACTION                 #
## Host:        $HOST                   # body
## Description: $DESCRIPTION            #
##                                           #
## Your faithful employee,                   #
## monit                                     #
## --8<--
##
## You can override this message format or parts of it, such as subject
## or sender using the MAIL-FORMAT statement. Macros such as $DATE, etc.
## are expanded at runtime. For example, to override the sender:

set mail-format { from: monit@conexion-empleo.com }

#
## You can set alert recipients here whom will receive alerts if/when a 
## service defined in this file has errors. Alerts may be restricted on 
## events by using a filter as in the second example below. 
#

set alert franck.dagostini@gmail.com

# set alert manager@foo.bar only on { timeout }  # receive just service-
#                                                # timeout alert
#
#
## Monit has an embedded web server which can be used to view status of 
## services monitored, the current configuration, actual services parameters
## and manage services from a web interface.
#
set httpd port 2812 and
#     use address localhost  # only accept connection from localhost
  allow localhost        # allow localhost to connect to the server and
  allow admin:monit      # require user 'admin' with password 'monit'
#     allow @monit           # allow users of group 'monit' to connect (rw)
#     allow @users readonly  # allow users of group 'users' to connect readonly
#
#
###############################################################################
## Services
###############################################################################
##
## Check general system resources such as load average, cpu and memory
## usage. Each test specifies a resource, conditions and the action to be
## performed should a test fail.
#
check system conexion-empleo.com
  if loadavg (1min) > 4 then alert
  if loadavg (5min) > 2 then alert
  if memory usage > 75% then alert
  if cpu usage (user) > 70% then alert
  if cpu usage (system) > 30% then alert
  if cpu usage (wait) > 20% then alert
#
#    
## Check a file for existence, checksum, permissions, uid and gid. In addition
## to alert recipients in the global section, customized alert will be sent to 
## additional recipients by specifying a local alert handler. The service may 
## be grouped using the GROUP option.
#    
#  check file apache_bin with path /usr/local/apache/bin/httpd
#    if failed checksum and 
#       expect the sum 8f7f419955cefa0b33a2ba316cba3659 then unmonitor
#    if failed permission 755 then unmonitor
#    if failed uid root then unmonitor
#    if failed gid root then unmonitor
#    alert security@foo.bar on {
#           checksum, permission, uid, gid, unmonitor
#        } with the mail-format { subject: Alarm! }
#    group server
#
#    
## Check that a process is running, in this case Apache, and that it respond
## to HTTP and HTTPS requests. Check its resource usage such as cpu and memory,
## and number of children. If the process is not running, monit will restart 
## it by default. In case the service was restarted very often and the 
## problem remains, it is possible to disable monitoring using the TIMEOUT
## statement. This service depends on another service (apache_bin) which
## is defined above.
#    
#  check process apache with pidfile /usr/local/apache/logs/httpd.pid
#    start program = "/etc/init.d/httpd start" with timeout 60 seconds
#    stop program  = "/etc/init.d/httpd stop"
#    if cpu > 60% for 2 cycles then alert
#    if cpu > 80% for 5 cycles then restart
#    if totalmem > 200.0 MB for 5 cycles then restart
#    if children > 250 then restart
#    if loadavg(5min) greater than 10 for 8 cycles then stop
#    if failed host www.tildeslash.com port 80 protocol http
#       and request "/monit/doc/next.php"
#       then restart
#    if failed port 443 type tcpssl protocol http
#       with timeout 15 seconds
#       then restart
#    if 3 restarts within 5 cycles then timeout
#    depends on apache_bin
#    group server
#    
#    
## Check filesystem permissions, uid, gid, space and inode usage. Other services,
## such as databases, may depend on this resource and an automatically graceful
## stop may be cascaded to them before the filesystem will become full and data
## lost.
#
#  check filesystem datafs with path /dev/sdb1
#    start program  = "/bin/mount /data"
#    stop program  = "/bin/umount /data"
#    if failed permission 660 then unmonitor
#    if failed uid root then unmonitor
#    if failed gid disk then unmonitor
#    if space usage > 80% for 5 times within 15 cycles then alert
#    if space usage > 99% then stop
#    if inode usage > 30000 then alert
#    if inode usage > 99% then stop
#    group server
#
#
## Check a file's timestamp. In this example, we test if a file is older 
## than 15 minutes and assume something is wrong if its not updated. Also,
## if the file size exceed a given limit, execute a script
#
#  check file database with path /data/mydatabase.db
#    if failed permission 700 then alert
#    if failed uid data then alert
#    if failed gid data then alert
#    if timestamp > 15 minutes then alert
#    if size > 100 MB then exec "/my/cleanup/script" as uid dba and gid dba
#
#
## Check directory permission, uid and gid.  An event is triggered if the 
## directory does not belong to the user with uid 0 and gid 0.  In addition, 
## the permissions have to match the octal description of 755 (see chmod(1)).
#
#  check directory bin with path /bin
#    if failed permission 755 then unmonitor
#    if failed uid 0 then unmonitor
#    if failed gid 0 then unmonitor
#
#
## Check a remote host network services availability using a ping test and 
## check response content from a web server. Up to three pings are sent and 
## connection to a port and a application level network check is performed.
#
#  check host myserver with address 192.168.1.1
#    if failed icmp type echo count 3 with timeout 3 seconds then alert
#    if failed port 3306 protocol mysql with timeout 15 seconds then alert
#    if failed url
#       http://user:password@www.foo.bar:8080/?querystring
#       and content == 'action="j_security_check"'
#       then alert
#
#
###############################################################################
## Includes
###############################################################################
##
## It is possible to include additional configuration parts from other files or
## directories.
#
#  include /etc/monit.d/*

# mysql
check process mysqld with pidfile /var/lib/mysql/ns388683.pid
  group database
  start program = "/etc/init.d/mysql start"
  stop program = "/etc/init.d/mysql stop"
  if failed host 127.0.0.1 port 3306 then restart
  if 5 restarts within 5 cycles then timeout

# nginx
check process nginx with pidfile /opt/nginx/logs/nginx.pid
  start program = "/etc/init.d/nginx start"
  stop  program = "/etc/init.d/nginx stop"
  if failed host 127.0.0.1 port 80 then restart
  if cpu is greater than 40% for 2 cycles then alert
  if cpu > 60% for 5 cycles then restart 
  if 10 restarts within 10 cycles then timeout

# redis
check process redis with pidfile /var/run/redis.pid
  start program = "/etc/init.d/redis-server start"
  stop program = "/etc/init.d/redis-server stop"
  group redis

check file dump.rdb with path /var/lib/redis/dump.rdb
  if size > 100 MB then alert

# tomcat
check process tomcat with pidfile /var/run/tomcat/tomcat.pid
  start program = "/etc/init.d/tomcat start" 
  as uid solr gid solr
  stop program = "/etc/init.d/tomcat stop" 
  as uid solr gid solr
  if failed port 8080 then alert
  if failed port 8080 for 5 cycles then restart

A la vez tenemos un visor de todo lo monitoriado que se denomina mmonit, este producto permite ver en mayor detalle la información de monit, a la vez cuenta con algunos gráficos.

No lo he probado mmonit aun pero voy a hacerlo, por la pagina se ve muy bien.

Por lo pronto y como conclusión podemos decir que monit es un software liviano de fácil configuración que es excelente para notificar el estado de un server, proceso o archivo.

Dejo link: https://github.com/arnaudsj/monit
https://mmonit.com/monit/

martes, 3 de octubre de 2017

Las 10 librerías más útiles en Java


Antes que nada aclaro que no soy el autor de este post, solo estoy pasando a castellano (como puedo)  luego les dejo link del articulo original. Pero no me critiquen por librerías que yo no elegí.

Java.io:  contiene todas las clases para entrada y salida de programas hechos en java.

java.util: Contiene un conjunto de librerías utiles para el modelado de datos, colecciones, internalización etc.

java.lang: La librería fundamental en java contiene todas las interfaces y clases fundamentales. Esta librería esta importada por default.

java.security: Soporta criptografia, firma digital y diferentes clases que permiten encriptar y desencriptar datos.

Google Guava: la librería avanzada de colecciones, más utilizada. Guava provee diferente colecciones y algoritmos complejos.

Apache commons: una librería super utilizada que nos facilita mucho escribir código en java, con clases como el EqualsBuider, HashcodeBuilder, StringUtils, etc

jSoup: nos permite parcear html de forma fácil.

Gson: Nos permite serializar objetos a formato json y luedo deserializarlos.

Jfreechar: Potentisima librería para graficar datos, permite hacer diferentes tipos de graficos y pasarlos a imagen.

SWT: La librería para componentes graficos de java con la que fue hecha eclipse.

Dejo link:
http://www.geekboots.tech/2017/09/10-most-useful-java-libraries.html

miércoles, 27 de septiembre de 2017

MailRelay, la mejor plataforma 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.

Email 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.
  • Y además de estas características cuenta con muchas promociones y descuentos. Por ejemplo Mailrelay es el único software de email marketing que permite enviar gratis 75.000 emails al mes a 15.000 suscriptores con autorespondedores incluidos.
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

jueves, 21 de septiembre de 2017

Los Siete Círculos del Infierno del Desarrollador


Dejo link: https://blog.toggl.com/seven-circles-of-developer-hell/

Cómo proteger la base de datos de MongoDB?

Me llego el siguiente correo y quería compartirlo con ustedes:

Cómo proteger la base de datos de MongoDB
Fecha: martes, 26 de septiembre
Hora: 16:00 CEST (GMT +2) | 9:00 CDT (GMT -6)

Hola Pablo, 

Participe en este seminario web y descubra cómo proteger los datos, tanto internamente como en la nube. Asegúrese de que el activo más importante de su empresa esté a salvo. 
INSCRÍBASE AHORA

Este es el último de los cuatro seminarios web que componen la serie "Conceptos Avanzados", en los que se describen las características y funciones avanzadas de MongoDB. 

Esperamos verle pronto. 

Saludos cordiales,

El equipo de MongoDB
 
 Share on TwitterShare on FacebookShare on LinkedInShare on Google+ 
 
MongoDB Inc., 2017. Todos los derechos reservados.
Palacio de Miraflores, Suite 219 & 220, Carrera de San Jerónimo 15 - 2, Madrid 28014, Spain

Para darse de baja de futuros mensajes de MongoDB o para actualizar sus preferencias de correo electrónico haga clic aquí.
 
Para ver la versión en línea haga clic aquí.

Cómo diseñar una newsletter?

Si bien estos temas no son muy comunes en este blog, pero les cuento tuve que hacer un newsletter de las novedades del proyecto, como un release note pero con formato newsletter. Y por lo tanto me puse a investigar. Parece fácil pero lo fácil es hacer un newletter que no agrade, que no informe de un modo adecuado y lo difícil es hacerlo bien. 

Vamos de a poco, que es un newsletter? Si buscamos en la wikipedia podemos encontrar:

"Un boletín informativo es una publicación distribuida de forma regular, centrada en un tema principal. Muchos boletines son publicados por clubes, sociedades, asociaciones y negocios para proporcionar información de interés a sus miembros o empleados del mismo plantel. Su extensión es variable y puede tener varias funciones."

Por lo tanto el newsletter o boletín informativo es una publicación digital informativa que se distribuye a través de email y con cierta periodicidad (diaria, semanal, mensual, bimensual o trimestral). Normalmente contienen artículos de interés sobre la marca y del ámbito en que la misma se desenvuelve. Los que reciben este tipo de comunicaciones son suscriptores que previamente han mostrado interés en la marca y han solicitado recibir información por correo.

En resumen es un email con las novedades y artículos relacionados que se envían a un conjunto de personas que se han subscrito a este newsletter.

Puede que tengamos un blog en nuestro sitio web, en cuyo caso podemos pensar que ya lo tenemos todo hecho, porque tendremos contenido para ir enviando en los mailings. O puede que no generemos contenido de forma asidua, y debamos comenzar ahora.

Pero volvamos al tema principal: Cómo diseñar una newsletter de manera efectiva y elegante? Y como pueden concluir estos son los principales objetivos de tu estrategia de email marketing. Y de marketing en general.

Las newsletters son herramientas muy poderosas, por esa razón las empresas más grandes los utilizan. A la hora de mantener una comunicación fluida, directa y personalizada con los lectores esta herramienta es muy eficiente. Pero, más allá de factores básicos como los contenidos, los asuntos, el horario o la frecuencia de envío, se encuentra un elemento que resulta determinante. Aunque son pocos los que se atreven a innovar en él. Se trata del diseño.

Los beneficios que aporta a tu negocio enviar comunicaciones periódicas en formato newsletter se fundamentan en una idea clave:

Este boletín de noticias sirve para comunicarte con tus clientes específicos, con tu comunidad de fans que dan un valor único a tu marca.

Por tanto, una buena segmentación de la base de datos de emails es clave para asegurarte que la comunicación es la adecuada y acorde con los intereses de tu audiencia.

Teniendo esto claro, siempre me gusta destacar 3 ventajas principales de enviar una newsletter regularmente y seguir una estrategia de email marketing sólida:

  • Es una vía promocional económica y de venta indirecta.
  • Incrementa la credibilidad de una marca.
  • Fideliza a la audiencia a través de la comunicación personalizada.

No obstante, debes tener muy en cuenta que los beneficios de enviar una newsletter no son inmediatos, sino que deberás realizar ciertas acciones para lograr conversiones (clics, suscripciones, ventas, etc.).

Por ejemplo, para atraer a los usuarios y lograr que se materialicen en conversiones, tendrás que implementar banners, botones promocionales o sorteos, servicios de prueba gratuitos o contenidos descargables tipo ebook.

La última opción (ofrecer ebooks y otros materiales), combinada con cualquier otra, es una de las vía que más ventajas puede aportar a tu negocio a la hora de dar una imagen de marca única y distintiva, y por ello es de la que quiero hablarte para que tú también puedas sacar el máximo provecho.

Puff, con los newsletter tenemos trabajo!!

domingo, 17 de septiembre de 2017

Elixir 1.5 fue liberado!

Elixir 1.5 trae muchas mejoras a la experiencia y calidad de vida del desarrollador. Es decir esta versión se centro que mejorar la interactividad con el desarrollador.

Entre las mejoras que tenemos podemos nombrar:

UTF-8 para atoms, nombres de funciones y variables, por ejemplo :

test "こんにちは世界" do
  assert :こんにちは世界
end

o

saudação = "Bom dia!"

Elixir 1.5 es más accesible a otros idiomas y comunidades. Los identificadores deben seguir siendo una secuencia de letras, seguida de dígitos y combinar marcas. Esto significa que los símbolos, como las notaciones matemáticas y emojis, no están permitidos en los identificadores.

IEx obtuvo muchas mejoras en la experiencia del desarrollador. En primer lugar, el sistema de autocompletado es ahora capaz de autocompletar variables y imports.

IEx también obtuvo nuevas funciones, como listar todas las funciones y macros en un módulo.

Por último, IEx también cuenta con un sistema de punto de interrupción para la depuración de código cuando se ejecuta en Erlang / OTP 20

Exception.blame/3 es una nueva función de Elixir que es capaz de adjuntar información de depuración a ciertas excepciones. Actualmente se utiliza para aumentar FunctionClauseErrors con un resumen de todas las cláusulas y qué partes de la cláusula coinciden y cuáles no.

Elixir v1.5 simplifica la forma en que los supervisores se definen y utilizan en Elixir. Elixir ahora permite especificaciones hijas, que especifican cómo se supervisará un proceso hijo, que se definirá en módulos.

Esta versión incluye muchas mejoras en funciones de calendario, como Date.range/2 y la posibilidad de convertir entre diferentes calendarios.

Estas son algunas mejoras que vienen en esta nueva versión.

Dejo link: https://elixir-lang.org/blog/2017/07/25/elixir-v1-5-0-released/

Blog de angular


Quiero recomendarles un excelente blog de angular y javascript de Todd Motto que es un Developer Expert de google. Este desarrollador abrió una empresa de cursos de angular "Ultimate Angular".

El blog esta muy completo como para tenerlo de referencia.

Dejo link: https://toddmotto.com

jueves, 14 de septiembre de 2017

Cómo utilizar el conector de BI con MongoDb?

Me llego el siguiente correo y quería compartirlo con ustedes: 

Come utilizar el conector de BI
Fecha: martes, 19 de septiembre
Hora: 16:00 CEST (GMT +2) | 9:00 CDT (GMT -6)

Hola Emanuelpeg,

Inscríbase en este seminario web y descubra cómo utilizar MongoDB como fuente de datos mediante el conector de BI en las plataformas analíticas y de BI basadas en SQL. También aprenderá cómo crear visualizaciones y paneles de control para extraer la información y el valor oculto de los datos multi-estructurados.
INSCRÍBASE AHORA

Este es el tercero de los cuatro seminarios web de la serie "Conceptos Avanzados", en los que se describen las características y funciones avanzadas de MongoDB. Le ayudarán a conocer MongoDB y los casos en los que resulta idónea esta solución.

Esperamos verle pronto.

Saludos cordiales,

El equipo de MongoDB
Share on Twitter Share on Facebook Share on LinkedIn Share on Google+
MongoDB Inc., 2017. Todos los derechos reservados.
Palacio de Miraflores, Suite 219 & 220, Carrera de San Jerónimo 15 - 2, Madrid 28014, Spain

Para darse de baja de futuros mensajes de MongoDB o para actualizar sus preferencias de correo electrónico haga clic aquí.
Para ver la versión en línea haga clic aquí.

miércoles, 13 de septiembre de 2017

Java EE se mueve a la organización eclipse




Como habíamos dicho en otro post: https://emanuelpeg.blogspot.com.ar/2017/08/java-ee-bajo-una-organizacion-open.html

Según lo que han publicado en el blog de la empresa Oracle, se quiere que el proceso de desarrollo de la especificación Java enterprise edition sea más ágil y responsivo. Por lo tanto se sugiere que sea parte de un fundación open source.

Bueno la Fundación Eclipse resultó seleccionada para albergar el proyecto y plataforma Java EE. La verdad que es una buenisima noticia.

Java EE en las manos de eclipse no creo que gane mayor agilidad pero sin duda va ser más abierto y comunitario.

Github de Java EE : https://github.com/javaee

Dejo link: https://blogs.oracle.com/theaquarium/opening-up-ee-update
http://middlewareblog.redhat.com/2017/09/12/java-ee-moves-to-eclipse/
https://mmilinkov.wordpress.com/2017/09/12/java-ee-moves-to-the-eclipse-foundation/

martes, 12 de septiembre de 2017

Blog sobre c++


Quiero recomendarles un blog sobre c++ para los que empiezan con el lenguaje.

Dejo link: http://www.freewebmentor.com/

domingo, 10 de septiembre de 2017

Empezando con Elixir 9


Composición

Ahora que sabemos cómo crear módulos y estructuras vamos a aprender cómo agregar la funcionalidad existente a ellos a través de la composición. Elixir nos proporciona una variedad de formas diferentes de interactuar con otros módulos.

alias

Nos permite alias nombres de módulo; utilizado con bastante frecuencia en código Elixir:

defmodule Sayings.Greetings do
  def basic(name), do: "Hi, #{name}"
end

defmodule Example do
  alias Sayings.Greetings

  def greeting(name), do: Greetings.basic(name)
end

# Without alias

defmodule Example do
  def greeting(name), do: Sayings.Greetings.basic(name)
end

Si hay un conflicto entre dos alias o simplemente deseamos alias a un nombre diferente por completo, podemos usar la opción: ":as"

defmodule Example do
  alias Sayings.Greetings, as: Hi

  def print_message(name), do: Hi.basic(name)
end

Incluso es posible alias múltiples módulos a la vez:

defmodule Example do
  alias Sayings.{Greetings, Farewells}
end

import

Si queremos importar funciones y macros en lugar de usar alias, podemos usar import/:

iex> last([1, 2, 3])
** (CompileError) iex:9: undefined function last/1
iex> import List
nil
iex> last([1, 2, 3])
3

Filtración

De forma predeterminada, todas las funciones y macros se importan, pero podemos filtrarlas mediante las opciones :only y :except.

Para importar funciones y macros específicas, debemos especificar los pares nombre de función y numero de parámetros a: only y :except. Comencemos importando sólo la función last/1 :

iex> import List, only: [last: 1]
iex> first([1, 2, 3])
** (CompileError) iex:13: undefined function first/1
iex> last([1, 2, 3])
3

Si importamos todo excepto last/1 e intentamos usar las mismas funciones que antes:

iex> import List, except: [last: 1]
nil
iex> first([1, 2, 3])
1
iex> last([1, 2, 3])
** (CompileError) iex:3: undefined function last/1

Hay dos átomos especiales, :functions y :macros, que importan sólo funciones y macros respectivamente:

import List, only: :functions
import List, only: :macros

require

Aunque se utiliza menos frecuentemente require/2 es importante. Requerir un módulo asegura que está compilado y cargado. Esto es muy útil cuando necesitamos acceder a las macros de un módulo:

defmodule Example do
  require SuperMacros

  SuperMacros.do_stuff
end

Si tratamos de llamar a una macro que aún no está cargada Elixir generará un error.

use

La macro "use" invoca una macro especial, llamada __using __/1, del módulo especificado. He aquí un ejemplo:

# lib/use_import_require/use_me.ex
defmodule UseImportRequire.UseMe do
  defmacro __using__(_) do
    quote do
      def use_test do
        IO.puts "use_test"
      end
    end
  end
end

y agregamos esta línea a UseImportRequire:

use UseImportRequire.UseMe

El uso de UseImportRequire.UseMe define una función use_test/0 mediante la invocación de la macro __using __/1.

Esto es todo lo que hace el uso. Sin embargo, es común que la macro __using__, a su vez, llame alias, require, o import. Esto a su vez creará alias o importaciones en el módulo de uso. Esto permite que el módulo que se utiliza para definir una política de cómo sus funciones y macros deben ser referenciados. Esto puede ser bastante flexible en que __using __/1 puede establecer referencias a otros módulos, especialmente submódulos.

El marco de Phoenix utiliza el use y __using __/1 para reducir la necesidad de alias repetitivas e import llamadas en módulos definidos por el usuario.

He aquí un ejemplo del módulo Ecto.Migration:

defmacro __using__(_) do
  quote location: :keep do
    import Ecto.Migration
    @disable_ddl_transaction false
    @before_compile Ecto.Migration
  end
end

La macro Ecto.Migration .__ using__/1 incluye una llamada de importación para que cuando utilice Ecto.Migration también importe Ecto.Migration. También configura una propiedad de módulo que asumimos que controla el comportamiento de Ecto.

Para recapitular: la macro de uso simplemente invoca la macro __using __/1 del módulo especificado. Para entender realmente qué es lo que necesita para leer la macro __using __/1.

Dejo link: https://elixirschool.com/en/lessons/basics/modules/

Empezando con Elixir 8

Estructuras

Una estructura puede verse como un mapa es decir como una estructura clave/valor. Una estructura debe definirse dentro de un módulo, del cual toma su nombre. Es común que una estructura sea la única cosa definida dentro de un módulo.

Para una estructura debemos utilizar la palabra clave defstruct y luego debemos definir los campos y los valores:

defmodule Example.User do
  defstruct name: "Sean", roles: []
end

Vamos a crear algunas estructuras:

iex> %Example.User{}
%Example.User{name: "Sean", roles: []}

iex> %Example.User{name: "Steve"}
%Example.User{name: "Steve", roles: []}

iex> %Example.User{name: "Steve", roles: [:admin, :owner]}
%Example.User{name: "Steve", roles: [:admin, :owner]}

Podemos actualizar nuestra estructura como si fuera un mapa:

iex> steve = %Example.User{name: "Steve", roles: [:admin, :owner]}
%Example.User{name: "Steve", roles: [:admin, :owner]}
iex> sean = %{steve | name: "Sean"}
%Example.User{name: "Sean", roles: [:admin, :owner]}

Lo más importante, puede combinar estructuras con mapas:

iex> %{name: "Sean"} = sean
%Example.User{name: "Sean", roles: [:admin, :owner]}

Dejo link: https://elixirschool.com/en/lessons/basics/modules/