Translate

martes, 26 de diciembre de 2017

Ordenar un arreglo en paralelo en Java 8

Java 8 trae muchas mejoras, tal vez la más importante es que podemos utilizar clausuras o closures en ingles. Pero a la vez Java 8 trae una cantidad interesantes de métodos que utilizan esta nueva propiedad, y a la vez nos brindan mayor facilidad para resolver problemas.

A la vez Java 8 proporciona una nueva característica que es ordenar un vector en paralelo. El método Arrays.sort() se usa para ordenar, pero java 8 proporciona un método nuevo que es el método parallelSort() para ordenar paralelamente los elementos de un vector.

El método parallelSort() pertenece a la clase Arrays, que está disponible en el paquete java.util. El método parallelSort() es más rápido que el método Array.sort() y este método sigue a fork / join framework para asignar las tareas de clasificación a varios subprocesos que están disponibles en el grupo de subprocesos. El método parallelSort () está sobrecargado para todos los tipos de datos primitivos y objetos que implementen Comparable<T>.

Veamos un simple ejemplo de como ordenar con este metodo:

import java.util.Arrays;

class ParallelSortExample
{
      public static void main(String args[]) {
            //Creamos un vector de enteros
            int a[] = {50, 10, 90, 40, 80};
            //Ahora los ordenamos
            Arrays.parallelSort(a);
            for(int i : a) {
                  System.out.println(i);
            }
      }
}

Output: 10
             40
             50
             80
             90

También podemos pasarle un Comparator que indique como debe ordenar, veamos un ejemplo:

package com.concretepage;

import java.util.Arrays;
import java.util.Comparator;
import java.util.function.Consumer;

public class ParallelSortWithComparator {

      public static void main(String[] args) {
             User[] users = User.getUsers();
            Comparator<User> ageComparator = Comparator.comparing(User::getAge);
            System.out.println("--Sort complete array--");
            Arrays.parallelSort(users, ageComparator);
            Consumer<User> printUser = u-> System.out.println(u.getName()+"-"+u.getAge());
            Arrays.stream(users).forEach(printUser);
            System.out.println("--Sort array from index 1 to 4--");
            users = User.getUsers();
            Arrays.parallelSort(users, 1, 4, ageComparator);
            Arrays.stream(users).forEach(printUser);
      }

}





domingo, 24 de diciembre de 2017

sábado, 23 de diciembre de 2017

Ukui desktop para Debian, Ubuntu y derivados



¡Útil, conveniente e intuitivo!

UKUI es un entorno de escritorio ligero basado en plugins para Linux y otras distribuciones Unix. Proporciona una experiencia más simple y agradable para navegar, buscar y administrar su equipo. Fue desarrollado utilizando GTK y Qt.

Veamos una imagenes:







Dejo link: http://www.ukui.org/

jueves, 21 de diciembre de 2017

Un resumen de Scala for the Impatient, parte 35

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.

Excepto para los operadores de asignación, la precedencia está determinada por el primer carácter del operador.

Precedencia más alta: un carácter de operador que no sea los de abajo
* / %
+ -
:
< >
! =
&
^
|

Un carácter que no es un carácter de operador
Prioridad más baja: operadores de asignación

Los caracteres en la misma fila producen operadores con la misma precedencia. Por ejemplo, + y -> tienen la misma precedencia.

Los operadores de Postfijos tienen una precedencia menor que los operadores de infijo:

a infixOp b postfixOp es igual a escribir : (a infixOp b)postfixOp


Asociatividad

Cuando hay un conjunto de operadores con la misma precedencia entra en juego la asociatividad, es decir si resuelve de derecha a izquierda o izquierda a derecha. En scala todos los operadores son asociativos por la izquierda excepto:

  • Los operadores que terminan en :
  • Los operadores de asignación


Por ejemplo el operador :: construye una lista por medio de asociatividad por la derecha:

1 :: 2 :: 3 :: Nil

esto significa

1 :: (2 :: (3 :: Nil))

Esto es así porque necesita construir primero la lista 3 :: Nil para que este parámetro sea usado por le expresión 2 :: (3 :: Nil)

La expresión 3 :: Dicha expresión es igual a la expresión Nil.::(3)




martes, 19 de diciembre de 2017

Un resumen de Scala for the Impatient, parte 34

Si hemos programado en C++ recordaremos que nos permite sobrescribir operadores, pero esto requería una muy pesada definición. Esto es muy diferente en Scala, las definiciones son mucho más fáciles y claras.

Sobrescribir operadores nos da una sintaxis más clara de nuestro código y nos acerca a la notación matemática.

En esta parte veremos como definir operadores binarios y unarios. Pero antes debemos aclarar algunos conceptos.

Identificadores

El nombre de las variables, funciones, clases, etc. se denominan identificadores. En Scala tenes más opciones de nombres para los identificadores que en java. Por supuesto podemos hacerlo igual que java, una letra seguida de letra o dígito. Como Java también permite caracteres unicode, es decir :


 es una variable valida.

También se puede utilizar caracteres de operadores en identificadores como :

  • Caracteres ASCII como ! # % & * + - / : < = > ? @ \ ^ | ~ , dígitos, . , ; marcas de puntuación, guión bajo, paréntesis () [] {} o comillas “ ' `     
  • Caracteres de símbolos matemáticos


Por ejemplo





es un identificador valido y se puede hacer:



de esta manera podemos escribir



de forma valida.

Note que las palabras :  @ # : = _ => <- <: <% >: fi  ̈ son palabras reservadas.

Por lo dicho anteriormente este es una variable valida:

val happy_birthday_!!! = "Bonne anniversaire!!!"

Por ultimo se puede incluir cualquier conjunto de palabras en `` como por ejemplo:

val `val` = 42

Si bien no parece útil, lo es por ejemplo si deseamos llamar a un método java que sea palabra reservada en scala, de esta forma podremos hacerlo.

Operador infijo

Se puede escribir:

a identificador b

Donde identificador es un método con 2 parámetros. Uno implícito y el otro explicito. Por ejemplo:

1 to 10

Que es igual a llamar 1.to(10)

Esto se denomina una expresión infija porque se encuentra entre los 2 parámetros. El operador puede contener letras o no, como el caso de -> :

1 -> 10 es igual a 1.->(10)

Para definir un operador en una clase, solo debe definir un método con el nombre del operador. Por ejemplo la clase Fraction:

class Fraction(n: Int, d: Int) {
    private val num = ...
    private val den = ...
    ...
    def *(other: Fraction) = new Fraction(num * other.num, den * other.den)
}

Operadores unarios

Los operadores infijos son binarios, es decir necesitan 2 parámetros. Un operador con un parámetro se lo denomina unario.

Los cuatro operadores: -, +, !, ~ se pueden utilizar como operadores prefijos, es decir se puede escribir el operador y luego el parámetro como por ejemplo :

 -a es idual a llamar a : a.unary_-

Si es postfijo, en ese caso no hay problema, se puede llamar el método con . o espacio, por ejemplo :

12 toString

es igual a llamar a : 12.toString()

Cuando utilizamos el operador unario postfijo con espacio y sin paréntesis nos puede dar un error de compilación. Dado que no queda expresado que no estamos utilizando parámetros. Veamos un ejemplo:

val result = 42 toString
println(result)

En este caso el compilador interpreta que se esta escribiendo lo siguiente :

val result = 42.toString(println(result))

Por esta razón nos lanzara un error de compilación, que dirá que el método tiene muchos parámetros. Por esta razón el compilador, lanza un warning cuando utilizamos esta notación, esto se puede desactivar con el parámetro del compilador -language:postfixOps o agregando el import :

import scala.language.postfixOps




lunes, 18 de diciembre de 2017

Goland, la nueva ide de Jetbrains para Go.


Una empresa que esta haciendo las cosas bien hace tiempo es Jetbrains y ahora ha lanzado una IDE para Go. Si no recuerdan bien Go es el lenguaje de google, que espera remplazar a c.

Como podemos ver Jetbrains suma un IDE a su lista de productos como PyCharm para Python y RubyMine para Ruby.

De GoLands podemos nombrar algunas de las características como:

  • Asistente de programación: al analizar el código fuente, proporciona características como la finalización del código, la navegación, la refactorización y el formateo, todos ellos específicos de Go.
  • Editor de código: resaltado de sintaxis y sugerencias de parámetros para facilitar la lectura y comprensión del código
  • Diseño ergonómico: la interfaz ha sido diseñada de la manera más directa y productiva posible
  • Desarrollo de front-end y back-end: soporte de primera clase para lenguajes y frameworks front-end, y herramientas para acceder y consultar bases de datos
  • Herramientas integradas: Herramientas comúnmente requeridas como depuradores, integración de control de versiones y corredores de prueba vienen instalados y no necesitan instalarse como complementos
  • Ecosistema de plugins: el ecosistema de plugins existente de JetBrains está disponible, abriendo muchas herramientas y características adicionales
  • Los desarrolladores que ya están familiarizados con IntelliJ se sentirán a gusto programando en go. 

La herramienta de depuración incluida también es similar a las de las suites de herramientas existentes de JetBrains. Los desarrolladores ahora podrán pasar por el código, agregar puntos de interrupción, evaluar expresiones, agregar relojes y más. Esto trae una modernización a aquellos más familiarizados con flujos de trabajo de depuración más débiles.

JetBrains planea expandir y mejorar este conjunto de características de forma regular, siguiendo el ciclo de lanzamiento típico de todas sus herramientas: las actualizaciones de versiones principales se realizarán trimestralmente, y las versiones menores y de parches suceden incluso con mayor frecuencia.

GoLand sigue el modelo estándar de licencia de JetBrains, con una prueba inicial de 30 días seguida de suscripciones mensuales o anuales, disponible tanto para individuos como para empresas. Para los usuarios de IntelliJ ultimate edition, su funcionalidad se puede instalar como un complemento.

Dejo link:
https://www.jetbrains.com/go/

sábado, 16 de diciembre de 2017

Primeros pasos con F#

Si bien hemos hablado de F# en el blog nunca hice un post del lenguaje en si, bueno vamos a cambiar eso.

Si vamos a la pagina de F# nos dira que es un lenguaje open source, multiplataforma y funcional. Capaz de resolver problemas complejos de forma simple.

Por que utilizar o aprender F#?

  • Concisión. F # no está lleno de "ruido" de codificación, como llaves, punto y coma, etc. Casi nunca tiene que especificar el tipo de un objeto, gracias a un potente sistema de inferencia de tipo. Y generalmente requiere menos líneas de código para resolver el mismo problema.
  • Conveniente. Muchas tareas de programación comunes son mucho más simples en F#. Esto incluye cosas como crear y usar definiciones de tipos complejos, hacer el procesamiento de listas, comparación e igualdad, máquinas de estado y mucho más. Y debido a que las funciones son objetos de primera clase, es muy fácil crear código poderoso y reutilizable creando funciones que tienen otras funciones como parámetros, o que combinan funciones existentes para crear nuevas funcionalidades.
  • Exactitud. F# tiene un sistema de tipo muy poderoso que evita muchos errores comunes, como las excepciones de referencia nula. Además, a menudo puede codificar la lógica de negocios utilizando el sistema de tipo en sí, de modo que es realmente imposible escribir código incorrecto, porque se detecta en tiempo de compilación como un error de tipo.
  • Concurrencia: F# tiene una serie de herramientas y bibliotecas integradas para ayudar con los sistemas de programación cuando ocurre más de una cosa a la vez. La programación asincrónica es directamente compatible, como lo es el paralelismo. F# también tiene un sistema de cola de mensajes y un excelente soporte para el manejo de eventos y programación reactiva. Y debido a que las estructuras de datos son inmutables por defecto, compartir estado y evitar bloqueos es mucho más fácil.
  • Completo. Aunque F # es un lenguaje funcional de corazón, admite otros estilos que no son 100% puros, lo que facilita mucho la interacción con el mundo no puro de sitios web, bases de datos, otras aplicaciones, etc. En particular, F# está diseñado como un lenguaje híbrido funcional / OO, por lo que puede hacer casi todo lo que C# puede hacer también. Por supuesto, F# se integra sin problemas con el ecosistema .NET, que le da acceso a todas las herramientas y bibliotecas .NET de terceros. Finalmente, es parte de Visual Studio, lo que significa que obtiene un buen editor con soporte IntelliSense, un depurador y muchos complementos para pruebas unitarias, control de código fuente y otras tareas de desarrollo.


Aquí hay una descripción general muy rápida sobre cómo leer el código F# para los recién llegados que no estén familiarizados con la sintaxis. La sintaxis F# es muy clara y directa cuando te acostumbras. En muchos sentidos, es más simple que la sintaxis C#, con menos palabras clave y casos especiales.

El siguiente código de ejemplo es un script sencillo de F # que muestra la mayoría de los conceptos que necesita de forma regular.

// single line comments use a double slash
(* multi line comments use (* . . . *) pair -end of multi line comment- *)

// ======== "Variables" (but not really) ==========
// The "let" keyword defines an (immutable) value
let myInt = 5
let myFloat = 3.14
let myString = "hello" //note that no types needed

// ======== Lists ============
let twoToFive = [2;3;4;5]        // Square brackets create a list with
                                 // semicolon delimiters.
let oneToFive = 1 :: twoToFive   // :: creates list with new 1st element
// The result is [1;2;3;4;5]
let zeroToFive = [0;1] @ twoToFive   // @ concats two lists

// IMPORTANT: commas are never used as delimiters, only semicolons!

// ======== Functions ========
// The "let" keyword also defines a named function.
let square x = x * x          // Note that no parens are used.
square 3                      // Now run the function. Again, no parens.

let add x y = x + y           // don't use add (x,y)! It means something
                              // completely different.
add 2 3                       // Now run the function.

// to define a multiline function, just use indents. No semicolons needed.
let evens list =
   let isEven x = x%2 = 0     // Define "isEven" as an inner ("nested") function
   List.filter isEven list    // List.filter is a library function
                              // with two parameters: a boolean function
                              // and a list to work on

evens oneToFive               // Now run the function

// You can use parens to clarify precedence. In this example,
// do "map" first, with two args, then do "sum" on the result.
// Without the parens, "List.map" would be passed as an arg to List.sum
let sumOfSquaresTo100 =
   List.sum ( List.map square [1..100] )

// You can pipe the output of one operation to the next using "|>"
// Here is the same sumOfSquares function written using pipes
let sumOfSquaresTo100piped =
   [1..100] |> List.map square |> List.sum  // "square" was defined earlier

// you can define lambdas (anonymous functions) using the "fun" keyword
let sumOfSquaresTo100withFun =
   [1..100] |> List.map (fun x->x*x) |> List.sum

// In F# returns are implicit -- no "return" needed. A function always
// returns the value of the last expression used.

// ======== Pattern Matching ========
// Match..with.. is a supercharged case/switch statement.
let simplePatternMatch =
   let x = "a"
   match x with
    | "a" -> printfn "x is a"
    | "b" -> printfn "x is b"
    | _ -> printfn "x is something else"   // underscore matches anything

// Some(..) and None are roughly analogous to Nullable wrappers
let validValue = Some(99)
let invalidValue = None

// In this example, match..with matches the "Some" and the "None",
// and also unpacks the value in the "Some" at the same time.
let optionPatternMatch input =
   match input with
    | Some i -> printfn "input is an int=%d" i
    | None -> printfn "input is missing"

optionPatternMatch validValue
optionPatternMatch invalidValue

// ========= Complex Data Types =========

// Tuple types are pairs, triples, etc. Tuples use commas.
let twoTuple = 1,2
let threeTuple = "a",2,true

// Record types have named fields. Semicolons are separators.
type Person = {First:string; Last:string}
let person1 = {First="john"; Last="Doe"}

// Union types have choices. Vertical bars are separators.
type Temp =
| DegreesC of float
| DegreesF of float
let temp = DegreesF 98.6

// Types can be combined recursively in complex ways.
// E.g. here is a union type that contains a list of the same type:
type Employee =
  | Worker of Person
  | Manager of Employee list
let jdoe = {First="John";Last="Doe"}
let worker = Worker jdoe

// ========= Printing =========
// The printf/printfn functions are similar to the
// Console.Write/WriteLine functions in C#.
printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
printfn "A string %s, and something generic %A" "hello" [1;2;3;4]

// all complex types have pretty printing built in
printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
         twoTuple person1 temp worker

// There are also sprintf/sprintfn functions for formatting data
// into a string, similar to String.Format.


Dejo link:




miércoles, 13 de diciembre de 2017

Entrando en .NET Core con the Windows Compatibility Pack


Una de las mayores diferencias entre .net y .net core es que este ultimo corre en Linux. Pero para aplicaciones de grandes empresas, realizar una migración en un solo paso no es factible. Por este motivo, Microsoft recomienda una transición incremental:

Migrar a ASP.NET Core
Migrar a .NET Core
Migrar a Linux
Y luego Migrar a Azure (host en linux)

Si bien eso suena bien en teoría, si falta una API crítica los proyectos no llegarán ni al paso 2. En este caso es donde entra en juego he Windows Compatibility Pack para .NET Core. Abarcando 20,000 APIs, esta colección de paquetes .net tiene como objetivo abordar las necesidades de la librerías para los desarrolladores de aplicaciones web.

Las API recientemente portadas se dividen aproximadamente en dos categorías: solo Windows y multiplataforma. Las API solo de Windows incluyen:

  • Active directory
  • Criptografia
  • Registros de eventos y contadores de rendimiento
  • File system security
  • Named pipes
  • Registry Access
  • Windows Services


En su mayor parte, están relacionados con el sistema operativo Windows, y los equivalentes de Linux a menudo tienen un diseño diferente.

Las bibliotecas multiplataforma incluyen:

  • Caching
  • ConfigurationManager 
  • DatasetExtensions (usado para acceso a base de datos sin un ORM) 
  • ODBC database access
  • System.Configuration.ConfigurationManager (MEF v1)
  • System.Drawing
  • System.IO.Packaging 
  • System.ServiceModel (i.e. WCF)
Cabe señalar que estas API se están omitiendo intencionalmente de la distribución .NET Core completa. 



lunes, 11 de diciembre de 2017

Un resumen de Scala for the Impatient, parte 33

Self type


Cuando un trait extiende de una clase, hay una garantía de que la superclase está presente en cualquier clase que se mezcle con el trait. Scala tiene un mecanismo alternativo para garantizar esto,  se denomina self type.

Cuando un trait comienza con :

this: Type =>

entonces solo se puede mezclar en una subclase del tipo dado.

trait LoggedException extends ConsoleLogger {
    this: Exception =>
    def log() { log(getMessage()) }
}

Note que el trait no extiende de Exception, en cambio, tiene un tipo propio Excepción. Eso significa que solo se puede mezclar en subclases de Excepción.

En los métodos del rasgo, podemos llamar a cualquier método del self type. Por ejemplo, la llamada a getMessage() en el método de registro es válida, ya que sabemos que debe ser un trait extendido por una excepción.

Como se puede suponer si una clase que no sea una Excepción quiere utilizar LoggedException eso no va a compilar.

También se puede utilizar type self con un método determinado, sin especificar una clase.

trait LoggedException extends ConsoleLogger {
    this: { def getMessage() : String } =>
        def log() { log(getMessage()) }
}

Por lo tanto este trait podrá mezclarse con cualquier clase que implemente getMessage() .

Que pasa en la jvm?

Scala necesita pasar un trait a una clase o interfaz java para que esto pueda ser comprendido por la JVM. Y es muy útil entender como trabajan los traits.

Un trait con todos los métodos abstractos es convertido a una interfaz. Un trait con un método es como una interfaz con un método por defecto:

trait ConsoleLogger {
    def log(msg: String) { println(msg) }
}

Se convierte:

public interface ConsoleLogger {
    default void log(String msg) { ... }
}

Si un trait tiene campos, es transformado a una interfaz con los métodos getters y setters:

trait ShortLogger extends Logger {
    val maxLength = 15 // A concrete field
    ...
}

es transformado a:

public interface ShortLogger extends Logger {
    int maxLength();
    void weird_prefix$maxLength_$eq(int);
    default void log(String msg) { ... } // Calls maxLength()
    default void $init$() { weird_prefix$maxLength_$eq(15); }
}

Por supuesto las interfaces en java no tienen campos, por lo que llama a los metodos getters o setters cuando quiera acceder o cambiar este valor. El setter es necesario tambien para inicializar el campo. Esto sucede en el método $init$.

Cuando el rasgo se mezcla en una clase, la clase obtiene un campo maxLength, y el getter y el setter se definen para obtener y establecer el campo. Los constructores de esa clase invocan el método $init$ del trait. Por ejemplo:

class SavingsAccount extends Account with ConsoleLogger with ShortLogger

seria en java:

public class SavingsAccount extends Account
 implements ConsoleLogger, ShortLogger {
   private int maxLength;
   public int maxLength() { return maxLength; }
   public void weird_prefix$maxLength_$eq(int arg) { maxLength = arg; }
 
   public SavingsAccount() {
      super();
      ConsoleLogger.$init$();
      ShortLogger.$init$();
   }
...
}

jueves, 7 de diciembre de 2017

Top 5 de libros sobre c++


Encontré un buen post sobre libros de c++, y yo justo necesito por lo tanto vamos a pegarle un repaso:

  • The C++ Programming Language, 4th Edition : Escrito por Bjarne Stroustrup es la biblia de c++ y la edición 4, nos enseña C++ 11
  • C++ Primer Plus (6th Edition) (Developer's Library) :Este libro es también uno de los libros populares de C ++, escrito por Stephen Prata. Es beneficioso tanto para estudiantes o programadores. 
  • Starting Out with C++ from Control Structures to Objects (9th Edition): Este libro es el mejor para los principiantes, está escrito por Tony Gaddis. El autor describe el concepto fundamental de una manera clara y fácil que hace que este libro sea amigable para los estudiantes.
  • Effective Modern C++ : Este es un excelente libro para el experimentado programador de C ++. El autor describe muy bien cómo escribir un software realmente genial usando C ++ 11 y C ++ 14 (C ++ moderno).
  • Accelerated C++: Practical Programming by Example: El libro es sorprendentemente pequeño, en menos de 300 páginas, los autores cubren muchas de las cosas. Cubre un alcance mucho más amplio de la programación C ++ que otros libros introductorios que he visto, y en un formato sorprendentemente compacto.


Dejo link: https://aticleworld.com/best-c-books/#.WicYcwOnLlE.google_plusone_share

miércoles, 6 de diciembre de 2017

Libros de algoritmos gratuitos


Quiero compartir este link donde se pueden bajar muchos libros de algoritmos estan todos en ingles pero son muy completos. Hay de todo, aprovechen!!

Dejo link: http://www.improgrammer.net/free-algorithm-books-for-download/

martes, 5 de diciembre de 2017

Un resumen de Scala for the Impatient, parte 32

Orden de construcción de trait

Como las clases, los traits pueden ser construidos y estos pueden construir sus propiedades y ejecutar métodos:

trait FileLogger extends Logger {
val out = new PrintWriter("app.log") // Part of the trait’s constructor
out.println(s"# ${java.time.Instant.now()}") // Also part of the constructor
def log(msg: String) { out.println(msg); out.flush() }
}


Esto se ejecutara en el constructor de cualquier objeto que incorpore este Trait.

El orden sera el siguiente: 
  1. El constructor de la super clase se ejecutara primero. 
  2. Luego el constructor de los traits, de izquierda a derecha. 
  3. Por cada traits, el constructor del padre (si lo tuviera) primero. 
  4. Si los traits tienen un constructor común, no ejecuta 2 veces el mismo constructor. 
  5. Luego de que todos los traits son construidos, la subclase es construida. 

Por ejemplo: 

class SavingsAccount extends Account with FileLogger with ShortLogger

El orden de construcción sería: 
  1. Account
  2. Logger (padre de FileLogger)
  3. FileLogger
  4. ShortLogger (tiene el padre en comun con FileLogger pero no vuelve a construirlo)
  5. SavingsAccount

Inicializando campos en los Traits

Los traits no pueden tener constructores con parámetros. Cada trait tiene un constructor sin parámetros. Esta limitación puede ser un problema para traits que necesitan ser adaptados para ser útiles. Por ejemplo el trait FileLogger seria útil poder definir el nombre del archivo.

val acct = new SavingsAccount with FileLogger("myapp.log")

Una posible solución es que el nombre de archivo sea un campo abstracto.

trait FileLogger extends Logger {
val filename: String
val out = new PrintStream(filename)
def log(msg: String) { out.println(msg); out.flush() }
}

La clase puede sobreescribir el filename pero el problema es que el constructor del trait se ejecuta antes por lo tanto no va funcionar. Esto se puede resolver con lo que se indico en el siguiente post

Aplicando esto nuestra clase sería:

val acct = new { // Early definition block after new
val filename = "myapp.log"
} with SavingsAccount with FileLogger

Otra alternativa es hacer que out sea lazy (es decir que se llame al constructor de out la primera vez que se utilice)

trait FileLogger extends Logger {
val filename: String
lazy val out = new PrintStream(filename)
def log(msg: String) { out.println(msg) } // No override needed
}

Cuando se llame al constructor de out el campo filename ya va estar seteado. Pero los valores lazy son un poco más ineficientes dado que se deben chequear al ser utilizados.

 Traits que extienden clases :

Como se puede ver un trait puede extender otro trait de esta manera podremos tener nuestra jerarquía de traits. Menos común un traits puede extender una clase. Esa clase se convierte en una superclase de cualquier clase que se mezcle con el trait.

Veamos un ejemplo: 

trait LoggedException extends Exception with ConsoleLogger {
    def log() { log(getMessage()) }
}

Una LoggerException tiene un método log que logea el mensaje. Por lo que vemos puede acceder al método getMessage que es de la clase Exception. 

Ahora podemos mix esto con el trait: 

class UnhappyException extends LoggedException { // This class extends a trait
    override def getMessage() = "arggh!"
}

¿Qué pasa si nuestra clase ya extiende otra clase? Eso está bien, siempre que sea una subclase de la superclase del trait. Por ejemplo,

class UnhappyException extends IOException with LoggedException

Pero si nuestra clase extiende de otra clase que no es hija o no es la clase padre del trait, esta clase no puede mezclarse con este trait. Por ejemplo: 

class UnhappyFrame extends JFrame with LoggedException
// Error: Unrelated superclasses

La clase no puede extender de Jframe y de Exception. 

lunes, 4 de diciembre de 2017

Juego de Serie en C# y mono!!

Cuando quiero aprender un nuevo lenguaje desarrollo un juego de series, es decir aparece una serie con un valor faltante y el jugador debe completarlo.

Uno de los requerimientos no funcionales es que se pueda agregar una serie nueva fácilmente, para cumplirlo vamos a utilizar las ventajas de herencia y polimorfismo.

Vamos a desarrollar este juego en C# y mono :

Empecemos desarrollo de la serie, la serie tiene como responsabilidad generarse y si lo hacemos de esta manera podemos utilizar la potencia del polimorfismo, para que no quede acoplado la generación de la serie con el desarrollo del juego:

using System;
using System.Collections.Generic;

namespace SecuenciaCSharep
{
public abstract class Secuencia
{
protected IList<int> values = new List<int>();

protected abstract void generate();

public Secuencia ()
{
this.generate();
}

public IList<int> getValues(){
return values;
}

}
}

Ahora vamos a ver las implementaciones de secuencia:

using System;

namespace SecuenciaCSharep
{
public class SecuenciaPar : Secuencia
{
protected override void generate () {
int semilla = new Random ().Next (99);
for (int i = 0; i<4; i++) {
this.values.Add (semilla * i * 2);
}
}

public SecuenciaPar ()
{
}
}
}

Y ahora la secuencia Impar: 

using System;

namespace SecuenciaCSharep
{
public class SecuenciaInPar : Secuencia
{
protected override void generate () {
int semilla = new Random ().Next (99);
for (int i = 0; i<4; i++) {
this.values.Add ((semilla * i * 2) + 1);
}  

}

public SecuenciaInPar ()
{
}
}
}

Ahora vamos a ver el juego, este tiene la responsabilidad de verificar si el usuario acertó y tambien debe llevar los puntos: 

using System;

namespace SecuenciaCSharep
{
public class Juego
{
private Secuencia secuencia;

private int puntaje = 0;

public void generar() {
int i = new Random ().Next (2);

switch (i) {
case 0:
secuencia = new SecuenciaPar ();
break;
default: 
secuencia = new SecuenciaInPar ();
break;
}
}

public Juego ()
{
this.puntaje = 0;
generar ();
}

public int getValue0() {
return secuencia.getValues()[0];
}

public int getValue1() {
return secuencia.getValues()[1];
}

private int getValue2() {
return secuencia.getValues()[2];
}

public int getValue3() {
return secuencia.getValues()[3];
}

public int getPuntaje() {
return this.puntaje;
}

public bool isOK(int n) {
if (this.getValue2 () == n) {
this.puntaje++;
this.generar ();
return true;
}
this.puntaje --;
this.generar ();
return false;
}

}
}

Ahora programemos la interfaz en este caso utilizaremos mono+Gtk:

using System;
using Gtk;
using SecuenciaCSharep;

public partial class MainWindow: Gtk.Window
{
private Juego juego;

public MainWindow (): base (Gtk.WindowType.Toplevel)
{
Build ();
juego = new Juego ();
this.regenerate ();
}

protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
Application.Quit ();
a.RetVal = true;
}

protected void OnButton1Clicked (object sender, EventArgs e)
{
int n = (int)this.spinbutton2.Value;
MessageDialog msd; 
if (juego.isOK (n)) {
msd = new MessageDialog (this, DialogFlags.Modal, MessageType.Info, ButtonsType.None, "Ganaste!! Puntaje : " + juego.getPuntaje());
} else {
msd = new MessageDialog (this, DialogFlags.Modal, MessageType.Info, ButtonsType.None, "Perdiste  Puntaje : " + juego.getPuntaje());
}
msd.Show ();
this.regenerate ();
}

private void regenerate() {
this.label1.Text = juego.getValue0 ().ToString();
this.label2.Text = juego.getValue1 ().ToString();
this.label3.Text = juego.getValue3 ().ToString();
this.spinbutton2.Value = 0;
}
}

Y eso es todo!!! a jugar se a dicho!!

Dejo el repositorio git: 

sábado, 2 de diciembre de 2017

Kotlin 1.2 introduce el proyecto multiplataforma


Kotlin se va para arriba y en su ultima versión permite compartir codigo desde la JVM a una plataforma javascript usando el proyecto multiplataforma. Además, incluye una serie de mejoras en el lenguaje y la biblioteca, y un mejor rendimiento del compilador.

Kotlin ahora ofrece a los desarrolladores la posibilidad de administrar fácilmente los proyectos destinados a ejecutarse tanto en la JVM como en las plataformas de JavaScript. En un futuro no muy lejano, el soporte nativo gracias a Kotlin Native.

El proyectos multiplataforma organiza sus módulos en un conjunto de módulos comunes y específicos para cada plataforma. Los módulos específicos de la plataforma contienen código que se ejecuta en la JVM o en JavaScript y puede acceder libremente a las bibliotecas específicas de la plataforma donde se ejecutan. Para cada módulo específico de la plataforma, debe existir un módulo común que proporcione las denominadas "declaraciones esperadas", es decir, declaraciones que deben implementarse en el módulo específico de la plataforma. Gracias a este mecanismo, puede llamar al código específico de la plataforma desde un código independiente de la plataforma. Mientras que los módulos comunes solo pueden contener el código de Kotlin y usar bibliotecas de Kotlin, los módulos de plataforma también pueden contener código en Java o JavaScript y se compilan en un formato específico.

Veamos un ejemplo:

// Common module

package org.jetbrains.foo

expect class Foo(bar: String) {
    fun frob()
}

fun main(args: Array<String>) {
    Foo("Hello").frob()
}

// JVM module

package org.jetbrains.foo

actual class Foo actual constructor(val bar: String) {
    actual fun frob() {
        println("Frobbing the $bar")
    }
}

En un futuro Kotlin sera capaz de expresar el comportamiento en módulos comunes en un conjunto de bibliotecas multiplataforma, que incluyen una biblioteca de serialización, una biblioteca de pruebas y una biblioteca isomórfica HTML. Esto debería reducir la necesidad de recurrir a módulos de plataforma.

Además, el compilador de Kotlin se ha vuelto significativamente más rápido en la versión 1.2, superando a Kotlin 1.1 en un 25%. Se planea una mejora adicional para futuros lanzamientos menores de 1.2.

Dejo link: https://blog.jetbrains.com/kotlin/2017/11/kotlin-1-2-released/
http://kotlinlang.org/docs/reference/whatsnew12.html
http://kotlin.es/2017/11/1.2.0/

jueves, 30 de noviembre de 2017

Llega Linux Mint 18.3

Como saben soy fanático de linux Mint y ya está disponible su versión 18.3 en sus dos ediciones: Linux Mint Cinnamon y Linux Mint MATE. Se trata de una versión de soporte extendido que será mantenida hasta el año 2021, así que es un excelente momento para actualizar.

Linux Mint 18.3 Sylvia viene con muchas novedades, entre las que podemos nombrar un nuevo centro de software con muchas aplicaciones populares como Spotify y WhatsApp al alcance de un click, soporte para Flatpak, y nuevas herramientas de respaldo.

El centro de software  ha sido remodelado por completo, ahora es más moderno, rápido y ofrece una mejor experiencia de uso. Mira:



A mi entender la novedad más importante es que Linux Mint ahora soporta Flatpak, pero que es Flatpak? es una herramienta para que podamos instalar aplicaciones incluso si sus dependencias no son compatibles con Linux Mint. Es decir todo el software del mundo libre!!!

Más adelante tendremos su versión kde y Xfce.

Dejo link: https://www.linuxmint.com/release.php?id=31
https://linuxmint.com/rel_sylvia_cinnamon.php