Translate

miércoles, 12 de julio de 2017

Real World OCaml


Quiero compartir este libro online gratuito, es sobre OCaml un lenguaje que desconozco totalmente.


Dejo link:
https://realworldocaml.org/

Keras, la red neuronal neutral escrita en Python


Como lo dije anteriormente Keras el la red neuronal neutral escrita en Python y con la capacidad de correr cualquier TensorFlow, CNTK o Theano.

Esta librería fue desarrollada con el foco a permitir una experimentación rápida.

Utilice Keras si necesita una librería de aprendizaje que:

  • Permite un prototipado fácil y rápido (a través de la facilidad de uso, modularidad y extensibilidad).
  • Soporta redes convolucionales y redes recurrentes, así como combinaciones de los dos.
  • Se ejecuta sin problemas en la CPU y la GPU.

La estructura de datos de Keras es un modelo, una forma de organizar capas. El modelo más simple es el modelo Sequential, una pila lineal de capas. Para arquitecturas más complejas, debe utilizar la API funcional de Keras, que permite crear gráficos arbitrarios de capas.

Veamos una secuencia:

from keras.models import Sequential

model = Sequential()
from keras.layers import Dense, Activation

model.add(Dense(units=64, input_dim=100))
model.add(Activation('relu'))
model.add(Dense(units=10))
model.add(Activation('softmax'))

Una vez que su modelo se vea bien, se configura el proceso de aprendizaje con .compile ():

model.compile(loss='categorical_crossentropy',
              optimizer='sgd',
              metrics=['accuracy'])

Si es necesario, puede configurar su optimizador. Un principio básico de Keras es hacer las cosas razonablemente simples, mientras que permite al usuario tener totalmente el control cuando lo necesitan (el control final es la fácil extensibilidad del código fuente).

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True))

Ahora puede iterar en sus datos de entrenamiento:

# x_train and y_train are Numpy arrays --just like in the Scikit-Learn API.
model.fit(x_train, y_train, epochs=5, batch_size=32)

Alternativamente, puede alimentar lotes a su modelo manualmente:

Model.train_on_batch (x_batch, y_batch)

Evalúe su rendimiento en una sola línea:

Loss_and_metrics = model.evaluate (x_test, y_test, batch_size = 128)

O generar predicciones sobre nuevos datos:

Classes = model.predict (x_test, batch_size = 128)

Y listo!

Dejo link: https://keras.io/

Tuplas en C#


Desde .net core, estoy estudiando un poco más C#

Vamos desde el principio, que es una tupla? Una tupla es una estructura de datos que especifica una secuencia de elementos.

Una tupla puede retornar un numero de elementos de diferente tipo sin expecificar una nueva estructura. Esto puede ser util para retornar diferentes elementos de defirente tipo o aceptarlos como parámetros.

System.Tuples es el namespace donde se pueden encontrar las tuplas en C#

Veamos un ejemplo:

class TupleExample
    {
        static void Main()
        {
            // Create three-item tuple.
            Tuple<int, string, bool> tuple =
                new Tuple<int, string, bool>(10, "csharpstar", true);
            // Access tuple properties.
            if (tuple.Item1 == 10)
            {
                Console.WriteLine(tuple.Item1);
            }
            if (tuple.Item2 == "easywcf")
            {
                Console.WriteLine(tuple.Item2);
            }
            if (tuple.Item3)
            {
                Console.WriteLine(tuple.Item3);
            }
        }
    }

Podemos no conoces el tipo de los elementos:

class TupleExample
    {
        static void Main()
        {
            // Use Tuple.Create static method.
            var tuple = Tuple.Create("Csharpstar", 10, true);

            // Test value of string.
            string value = tuple.Item1;
            if (value == "csharpstar")
            {
                Console.WriteLine(true);
            }

            // Test Item2 and Item3.
            Console.WriteLine(tuple.Item2 == 10);
            Console.WriteLine(!tuple.Item3);

            // Write string representation.
            Console.WriteLine(tuple);
        }
    }

Cuando utilizar tuplas?

Las tuplas se usan comúnmente de las siguientes maneras:

  • Para representar un solo conjunto de datos. Por ejemplo, una tupla puede representar un registro de base de datos, y sus componentes pueden representar campos individuales del registro.
  • Facilitar el acceso y la manipulación de un conjunto de datos.
  • Para devolver varios valores de un método sin utilizar parámetros de salida
  • Pasar valores múltiples a un método a través de un solo parámetro.

domingo, 9 de julio de 2017

GraphQL vs REST


Como sabrán me gustan las comparaciones, y estaba leyendo InfoQ y me encontre con un articulo sobre GraphQL vs REST.

Espero que todos conozcan REST, pero que es GraphQL? GraphQL es un lenguaje de consulta de datos, diseñado y usado en Facebook para solicitar y entregar datos a las aplicaciones móviles y web desde 2012. Para más info : https://emanuelpeg.blogspot.com.ar/2015/10/graphql.html

Cuales son sus ventajas ante rest y diferencias?

  • GraphQL reduce el trafico red al permitirle recuperar todos los datos que necesita en una sola consulta.
  • GraphQL es el modelo WYSIWYG, hacer que el código cliente sea menos propenso a errores.
  • HTTP RESTful aprovecha más consistencia y previsibilidad haciendo uso de códigos de http (por ejemplo 404 si no encuentra la entidad) y de los metodos Post, Put, Delete, etc.
  • Hypermedia de APIs Restful, permiten que los clientes vayan descubriendo la información y como encontrarla. 
  • HTTP ya implementa una caché, mientras que GraphQL no lo hace.
  • GraphQL es útil porque proporciona un esquema para los consumidores, pero estas no necesariamente esta documentada. 

Para concluir, no hay bala de plata, y es sólo una cuestión de elegir lo que tiene más sentido para los requerimientos.

Dejo link: https://www.infoq.com/news/2017/07/graphql-vs-rest
http://graphql.org/
https://apihandyman.io/and-graphql-for-all-a-few-things-to-think-about-before-blindly-dumping-rest-for-graphql/

miércoles, 5 de julio de 2017

Python Pedia

Si queres aprender python y más tecnologías Python Pedia es el sitio que estabas buscando. En este sitio podes encontrar todo sobre Python y muchas tecnologías más.

Entre las categorías encontramos desarrollo:

  • Científico y numérico
  • De Juegos
  • Web
  • Python core
  • Testing
  • Comunidad
  • Interfaces
  • Embebido
  • Redes
  • Acceso a base de datos
  • Tutoriales 
  • etc...
Dejo link: 

martes, 4 de julio de 2017

Un resumen de Scala for the Impatient, parte 24

Campos Abstractos

En Scala puede haber campos abstractos, y este campo abstracto es un campo sin valor inicial.

abstract class Person {
    val id: Int //no esta inicializado, por lo que es abstracto igual que su getter y setter
    var name: String //también abstracto
}

Esta clase si la vemos desde java no va tener estos atributos y los métodos getters y setters van a ser abstractos.

Dada la siguiente clase si queremos extenderla debemos definir estos atributos, por ejemplo:

class Employee(val id: Int) extends Person { // una subclase concreta
     var name = "" // propiedad concreta
}

Como se puede ver no es necesario la palabra clave “override” para sobrescribir campos.

A la vez se puede utilizar esta clase abstracta por medio de la instanciación de una clase anónima, la cual debe establecer los valores :

val fred = new Person {
     val id = 1729
     var name = "Fred"
}

Construcción ordenada y definición temprana. 

Cuando se desea sobrescribir un campo y se usa este campo en el constructor de la superclase, el resultado es un comportamiento poco intuitivo.

Veamos un ejemplo, supongamos que queremos modelar una criatura puede ver una dimensión y solo 10 unidades de medida:
   
class Creature {
    val range: Int = 10
    val env: Array[Int] = new Array[Int](range)
}

Pero una hormiga puede ver solo 2 :

class Ant extends Creature {
    override val range = 2
}

Desafortunadamente ahora tenemos un problema, el rango es un valor que es utilizado en el constructor de la superclase y el constructor de la superclase se ejecuta antes del constructor de la subclase. Vamos que sucede en mayor detalle:

  • Se llama al constructor de Ant
  • El constructor de Ant llama al constructor de criatura 
  • El constructor de criatura inicializa range en 10 y luego inicializa env con el método getter de range que fue sobrescrito, este no utiliza el de criatura sino el de hormiga que aun no fue inicializado. Por lo tanto env es un vector de 0, porque 0 es el entero por defecto. 
  • Hormiga establece a range en 2. 


Como se puede ver env se inicializo como un vector de 0 y debía ser de 2.

Existen diferentes soluciones a este problema pero podemos nombrar 3:

  • Declarar val como final. Esto es seguro pero no flexible. 
  • Declarar val como lazy, esto es seguro, flexible pero un poco ineficiente. 
  • Declarar este campo como “early definition” o  definición temprana en la subclase. 

En esta sección vamos a explorar la ultima opción. Para definir un campo con definición temprana lo podemos hacer de la siguiente manera:

class Bug extends {
     override val range = 3
} with Creature

Note que with es una palabra reservada, que se encuentra antes de la superclase.


domingo, 2 de julio de 2017

sábado, 1 de julio de 2017

Que cursos de codeschool puedo hacer de forma gratuita?

Empezó las vacaciones por lo tanto esta bueno si hacemos un cursito, y si es cortito, mejor. Estos cursos gratuitos vienen al pelo:

Try C#



Rangos en Kotlin


Todos hablan Kotlin, desde que es un lenguaje soportado por android se ha vuelto un famoso y con mucha publicidad. Y no vamos a ser la excepción.

En este caso vamos hablar de los rangos. Los rangos se define para cualquier tipo comparable, pero se usa principalmente para primitivos. Empecemos con algo simple un if, que nos permita saber si un numero se encuentra en un rango:

if ( i in 1 .. 10 ) { // equivalente a 1 <= i && i <= 10
  println(i);
}

Veamos un for:

for (i in 1..4) print(i) // imprime "1234"

for (i in 4..1) print(i) // no imprime nada

//Usando downTo()
for (i in 4 downTo 1) print(i) // Ahora si imprime!  "4321"

//Lo mismo pero con clausura:
(1..4).reversed().forEach(System.out::print)

//Si queremos saltarnos algunos valores:
for (i in 1..4 step 2) print(i) // imprime "13"

for (i in 4 downTo 1 step 2) print(i) // imprime "42"

//Si deseamos excluir el ultimo valor podemos usar until
for (i in 1 until 10) {
     println(i)
}

Dejo link: http://developersjournal.in/pondering-over-kotlin-ranges/




miércoles, 28 de junio de 2017

Parámetro implícito en Scala

"Este es el primer paso para implementar la abstracción contextual en Scala". ¿Qué quiero decir con esto?

Abstracción: La capacidad de nombrar un concepto y usar sólo el nombre después.

Contextual: Un fragmento de un programa produce resultados o resultados en algún contexto. Nuestros lenguajes de programación son muy buenos para describir y abstraer lo que se producen. Pero casi no hay nada disponible para abstraer sobre las entradas que los programas obtienen de su contexto. Un ejemplo para resolver esto es la inyección de dependencias.

Los tipos de funciones implícitas son una forma sorprendentemente sencilla y general de hacer abstractables los patrones de codificación que resuelven estas tareas, reduciendo el código clásico y aumentando la aplicabilidad. Para entender esto debemos entender los parámetro implícito

En un lenguaje funcional, las entradas a un cálculo se expresan más naturalmente como parámetros. Uno podría simplemente aumentar las funciones para tomar parámetros adicionales que representan configuraciones, capacidades, diccionarios, o cualquier otro dato contextual que las funciones necesiten. El único inconveniente de esto es que a menudo hay una gran distancia en el gráfico de llamadas entre la definición de un elemento contextual y el sitio donde se utiliza. En consecuencia, se hace tedioso definir todos esos parámetros intermedios y pasarlos a lo largo de donde finalmente se consumen.

Los parámetros implícitos solucionan la mitad del problema. Ellos no tienen que ser propagados usando código de repetitivo; el compilador se encarga de eso. Esto los hace prácticos en muchos escenarios donde los parámetros simples serían demasiado engorrosos. Los parámetros implícitos también son muy útiles como un mecanismo general de paso del contexto.

Digamos que queremos escribir algún código que está diseñado para ejecutarse en una transacción. En aras de la ilustración, aquí hay una clase de transacción simple:

class Transaction {
  private val log = new ListBuffer[String]
 
  def println(s: String): Unit = log += s
 
  private var aborted = false
 
  private var committed = false

  def abort(): Unit = { aborted = true }

  def isAborted = aborted

  def commit(): Unit =
    if (!aborted && !committed) {
      Console.println("******* log ********")
      log.foreach(Console.println)
      committed = true
    }

}

La transacción encapsula un registro, al que se pueden imprimir mensajes. Puede estar en uno de los tres estados: run, commit o abort. Si la transacción se confirma, imprime el registro almacenado en la consola.

El método de transacción permite ejecutar un determinado código dentro de una transacción recién creada:

 def transaction[T](op: Transaction => T) = {
    val trans: Transaction = new Transaction
    op(trans)
    trans.commit()
  }

La transacción actual se debe pasar a lo largo de una cadena de llamadas a todos los lugares que necesitan para acceder a ella. Para ilustrar esto, aquí están tres funciones f1, f2 y f3 que se llaman entre sí, y también acceder a la transacción actual. La manera más conveniente de lograr esto es pasar la transacción actual como un parámetro implícito.

 def f1(x: Int)(implicit thisTransaction: Transaction): Int = {
    thisTransaction.println(s"first step: $x")
    f2(x + 1)
  }
  def f2(x: Int)(implicit thisTransaction: Transaction): Int = {
    thisTransaction.println(s"second step: $x")
    f3(x * x)
  }
  def f3(x: Int)(implicit thisTransaction: Transaction): Int = {
    thisTransaction.println(s"third step: $x")
    if (x % 2 != 0) thisTransaction.abort()
    x
  }

El programa principal llama a f1 en un nuevo contexto de transacción e imprime su resultado:

  def main(args: Array[String]) = {
    transaction {
      implicit thisTransaction =>
        val res = f1(args.length)
        println(if (thisTransaction.isAborted) "aborted" else s"result: $res")
    }
  }




lunes, 26 de junio de 2017

Un Ejemplo de Polimorfismo en C++


La idea es mostrar un ejemplo de polimorfismo para los que comienzan a programar en el paradigma orientado a objetos.

La idea es que una empresa tiene un conjunto de bienes los cuales tienen un valor y a la vez algunos bienes pueden ser amortizados (La amortización es un término económico y contable, referido al proceso de distribución de gasto en el tiempo de un valor duradero. Adicionalmente se utiliza como sinónimo de depreciación en cualquiera de sus métodos.)

Los bienes se clasifican en inmuebles, muebles y rodados. A la vez los inmuebles no pierden el valor en el tiempo (es decir no son amortizables) . El software debe proveer una forma de saber el valor de todos los bienes y calcular su amortización.

Para resolver este problema vamos a definir 1 clase abstracta bien que describa la característica que tienen los bienes de saber su valor y la característica de calcular la amortización. A la vez vamos a crear un gestor contable que imprima las amortizaciones.

Veamos la clase abstracta bien:

bien.h :

#ifndef BIEN_H
#define BIEN_H

#include <iostream>

class Bien
{
protected:
    double valor = 0.0;
public:
    Bien();
    double virtual amortizar() = 0;

    void setValor(double valor);

    friend std::ostream& operator<<(std::ostream& os, const Bien& obj);
};

#endif // BIEN_H

bien.cpp : 

#include "bien.h"

Bien::Bien()
{
    this->valor = 0;
}

void Bien::setValor(double valor){
    this->valor = valor;
}

std::ostream& operator<<(std::ostream& os, const Bien& obj){
    return os << "Bien : " << obj.valor;
}

Ahora veamos sus implementaciones, empecemos con el Rodado:

rodado.h :

 #ifndef RODADO_H
#define RODADO_H

#include <iostream>
#include "bien.h"

class Rodado : public Bien
{
protected:
    int km = 0;
public:
    Rodado();
    double amortizar();
    void setKm(int km);
};

#endif // RODADO_H

rodado.cpp : 

#include "rodado.h"

Rodado::Rodado()
{
}

double Rodado::amortizar(){
    int por = this->km /1000;
    return this->valor * ((0.1) * por);
}

void Rodado::setKm(int km){
    this->km = km;
}

Veamos mueble.h

#ifndef MUEBLE_H
#define MUEBLE_H

#include <iostream>
#include "bien.h"

class Mueble : public Bien
{
protected:
    int anioCreacion = 1900;
public:
    Mueble(int anioCreacion);
    double amortizar();
    void setAnioCreacion(int anioCreacion);
};

#endif // MUEBLE_H

mueble.cpp :

#include "mueble.h"

Mueble::Mueble(int anioCreacion)
{
    this->anioCreacion = anioCreacion;
}

double Mueble::amortizar(){
    int dif = 2017 - this->anioCreacion;
    return this->valor * (dif * 0.05);
}

void Mueble::setAnioCreacion(int anioCreacion){
    this->anioCreacion = anioCreacion;
}

Veamos el inmueble que le puse "Terreno" por lo tanto veremos a terreno.h :

#ifndef TERRENO_H
#define TERRENO_H

#include <iostream>
#include "bien.h"

class Terreno : public Bien
{
public:
    Terreno();
    double amortizar();
};

#endif // TERRENO_H

terreno.cpp :

#include "terreno.h"

Terreno::Terreno()
{
}

double Terreno::amortizar(){
    return 0.0; //no amortiza por eso retorna 0
}

Ahora veremos el gestor contable que no hace mucho en el ejemplo, pero usen la imaginación y piensen que debería guardar los registros, calcular asientos, etc. 

gestorcontable.h :

#ifndef GESTORCONTABLE_H
#define GESTORCONTABLE_H

#include <iostream>
#include "bien.h"

using namespace std;

class GestorContable
{
public:
    GestorContable();
    void imprimir(Bien * unBien);
};

#endif // GESTORCONTABLE_H


gestorcontable.cpp :

#include "gestorcontable.h"

GestorContable::GestorContable()
{
}

void GestorContable::imprimir(Bien * unBien){
    cout << *unBien << " amortizacion : "<< unBien->amortizar() << endl;
}

Como pueden ver el Bien es abstracto y sus especializaciones polimorficas y el gestor contable usa esas características y utiliza el polimorfismo de esta manera no importa que bien deba imprimir, como el calculo de la amortización lo sabe hacer cada bien, cada bien calculara su amortización por lo tanto lo hará correctamente. 

Recuerden que el polimorfismo se refiere a la propiedad por la que es posible enviar mensajes sintácticamente iguales a objetos de tipos distintos. El único requisito que deben cumplir los objetos que se utilizan de manera polimórfica es saber responder al mensaje que se les envía.

Espero que les sirva!!

Antes de despedirme les muestro el main:

 #include <iostream>
#include "bien.h"
#include "mueble.h"
#include "rodado.h"
#include "terreno.h"
#include "gestorcontable.h"

using namespace std;

int main()
{
    GestorContable gestorContable = GestorContable();

    Bien * unTerreno = new Terreno();
    unTerreno->setValor(12000.0);
    gestorContable.imprimir(unTerreno);

    Bien * unRodado = new Rodado();
    Rodado * o = 0;
    // Esto lo hago solo para mostrar un cambio de tipos. 
    if (o = reinterpret_cast<Rodado*> (unRodado)) {
        o->setKm(2450);
    }

    unRodado->setValor(400000.00);
    gestorContable.imprimir(unRodado);

    Bien * unMueble = new Mueble(2000);
    unMueble->setValor(47000.00);
    gestorContable.imprimir(unMueble);

    return 0;
}




domingo, 25 de junio de 2017

Un Ejemplo de Polimorfismo en Java


La idea es mostrar un ejemplo de polimorfismo para los que comienzan a programar en el paradigma orientado a objetos.

La idea es que una empresa tiene un conjunto de bienes los cuales tienen un valor y a la vez algunos bienes pueden ser amortizados (La amortización es un término económico y contable, referido al proceso de distribución de gasto en el tiempo de un valor duradero. Adicionalmente se utiliza como sinónimo de depreciación en cualquiera de sus métodos.)

Los bienes se clasifican en inmuebles, muebles y rodados. A la vez los inmuebles no pierden el valor en el tiempo (es decir no son amortizables) . El software debe proveer una forma de saber el valor de todos los bienes y calcular su amortización.

Para resolver este problema vamos a definir 2 interfaces una que describa la característica que tienen los bienes de saber su valor y otra que describa la característica de calcular la amortización.

public interface Valorizable {

public Double getValor();

}


public interface Amortizable {

public Double calcularAmortizacion();

}

Programemos los bienes, empesamos con el mueble que para el ejemplo le puse Edificio:

import java.util.Calendar;
import java.util.Date;

public class Edificio implements Valorizable, Amortizable {

private Double valor;
private Date fechaDeCreacion;

public Edificio(Double valorInicial, Date fechaDeCreacion) {
this.valor = valorInicial;
this.fechaDeCreacion = fechaDeCreacion;
}

@Override
public Double calcularAmortizacion() {
Calendar cal = Calendar.getInstance();
int actualYear =cal.get(Calendar.YEAR);
cal.setTime(fechaDeCreacion);
int year =cal.get(Calendar.YEAR);
int diferencia = actualYear - year;
Double amortizacion = (diferencia * valor) / 300;
this.valor = this.valor - amortizacion;
return amortizacion;
}

@Override
public Double getValor() {
return this.valor;
}

@Override
public String toString() {
return "mueble " + this.valor;
}

}

Seguimos con el rodado:

public class Rodado implements Amortizable, Valorizable{

private static final Double VALOR_AMORTIZACION = 0.2;
private Double valor;
private Integer kms;

public Rodado(Double valorInicial, Integer kms) {
this.valor = valorInicial;
this.kms = kms;
}

public Double getValor() {
return valor;
}

public Double calcularAmortizacion() {
Double amotizacion = 0.0;
if (valor > 0.0) {
amotizacion = (VALOR_AMORTIZACION * kms.doubleValue())/100;
valor = valor - amotizacion;
}
return amotizacion;
}

@Override
public String toString() {
return "rodado " + this.valor;
}

}

Y por ultimo programemos el terreno: 


public class Terreno implements Valorizable {

private Double valor= 0.0;
private String direccion = "";
public Terreno(Double valor, String direccion) {
this.valor = valor;
this.direccion = direccion;
}

@Override
public Double getValor() {
return valor;
}

@Override
public String toString() {
return this.direccion;
}
}

De esta manera podemos tratar a todos los objetos amortizables como si fueran del mismo tipo y a todos los valorables como si fueran del mismo tipo, sin importarnos como calculan el valor o la amortización. 

Veamos el main: 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class Main {


public static void main(String[] args) {
// Construyo los Objetos
Calendar cal = Calendar.getInstance();
cal.set(1990, 02, 02);
Edificio unEdificio  = new Edificio(150000.00, cal.getTime());
Rodado unRodado = new Rodado(12000.00, 1000);
Terreno unTerreno = new Terreno(600000.00, "Los colibies 234");
List<Amortizable> list = new ArrayList<>();
list.add(unEdificio);
list.add(unRodado);
//list.add(unTerreno); No es posible agregar un terreno porque no es Amortizable
System.out.println();
System.out.println("Calcular Amortizacion");
for (Amortizable amortizar : list) {
System.out.println(amortizar.calcularAmortizacion());
}
List<Valorizable> list2 = new ArrayList<>();
list2.add(unEdificio);
list2.add(unRodado);
list2.add(unTerreno);
System.out.println();
System.out.println("Imprimir el valor");
for (Valorizable valorizar : list2) {
System.out.println(valorizar.getValor());
}

// En Java es común el uso de polimorfismo, veamos un ejemplo: 
List<Object> list3 = new ArrayList<>();
list3.add(unEdificio);
list3.add(unRodado);
list3.add(unTerreno);
list3.add("Hola!");
System.out.println();
System.out.println("Hacer to String");
for (Object object : list3) {
System.out.println(object.toString()); //toString es llamado de forma polimorfica.
}


}

}

Recuerden que el polimorfismo se refiere a la propiedad por la que es posible enviar mensajes sintácticamente iguales a objetos de tipos distintos. El único requisito que deben cumplir los objetos que se utilizan de manera polimórfica es saber responder al mensaje que se les envía.

Espero que les sirva!!



Un resumen de Scala for the Impatient, parte 23


Sobrescribir campos

Se puede sobrescribir val (o un método sin parámetros) con una declaración val con el mismo nombre. La clase tiene privados los atributos y públicos los getters y setters por lo tanto se sobrescribirán estos métodos.

Por ejemplo:

class Person(val name: String) {
     override def toString = getClass.getName + "[name=" + name + "]"
}

class SecretAgent(codename: String) extends Person(codename) {
     override val name = "secret" // Don’t want to reveal name . . .
     override val toString = "secret" // . . . or class name
}

Este ejemplo muestra el mecanismo, pero es bastante artificial. Un caso más común es sobrescribir un def de una clase abstracta, veamos un ejemplo :

abstract class Person { // See Section 8.8 for abstract classes
     def id: Int // Each person has an ID that is computed in some way
     ...
}

class Student(override val id: Int) extends Person
// A student ID is simply provided in the constructor

Note las siguientes restricciones:
  • Un def solo puede ser sobrescrito por un def
  • Un val solo puede ser sobrescrito por otro val o un def sin parámetros
  • Un var solo puede ser sobrescrito por un var abstracto


Veamos un cuadro que describe la sobrecarga:



Con val
Con def
Con var
Sobrescribir val
La subclase tiene un campo privado (con el mismo nombre que el campo de la superclase: está bien).
Getter reemplaza al getter de superclase.
Error
Error
Sobrescribir def
La subclase tiene un campo privado.
Getter anula el método de superclase.
Como java.
Una var puede anular un par getter / setter.
Anular solo el getter produce un error.
Sobrescribir var
Error
Error
Sólo si la superclase var es abstracta

Subclases anónimas.

Como en java, se pueden implementar interfaces o extender clases abstractas implementando los métodos a continuación del llamado de dicha clase o interfaz, es más fácil explicar esto con un ejemplo:

val alien = new Person("Fred") {
     def greeting = "Greetings, Earthling! My name is Fred."
}

Técnicamente esto creo una persona con el método “greeting” implementado con el texto: "Greetings, Earthling! My name is Fred." El tipo es Person{def greeting: String}. Se puede utilizar este tipo como parámetro de la siguiente forma:

def meet(p: Person{def greeting: String}) {
     println(p.name + " says: " + p.greeting)
}

Clases Abstractas.

Como en java, podemos definir una clase abstracta con la palabra “abstract” y esta clase no se podrá instanciar. Normalmente esto es usado de la siguiente manera porque hay uno o más métodos que no podemos definir, es decir que son abstractos.

abstract class Person(val name: String) {
     def id: Int // No method body—this is an abstract method
}

Una subclase de Person va a estar obligada a implementar el método id o ser abstracta. A diferencia de java no es necesario utilizar la palabra abstract para los métodos, simplemente debemos omitir el cuerpo de la función.

Una subclase concreta esta obligada a sobre escribir este método:

class Employee(name: String) extends Person(name) {
     def id = name.hashCode // override keyword not required
}




jueves, 22 de junio de 2017

Empezando con Elixir 5


Estructuras de control

if y unless

Si hemos programado estamos familiarizados con el if y en menor medida con el unless. Estas estructuras son construidas en elixir por medio de macros y no forma parte del lenguaje.

Por otra parte es necesario aclarar que en elixir solo es falso el nil y el false (por supuesto)

iex> if String.valid?("Hello") do
...>   "Valid string!"
...> else
...>   "Invalid string."
...> end
"Valid string!"

iex> if "a string value" do
...>   "Truthy"
...> end
"Truthy"

Se utiliza unless para analizar los casos falsos:

iex> unless is_integer("hello") do
...>   "Not an Int"
...> end
"Not an Int"

case

Esta estructura nos permite utilizar el pattern matching:

iex> case {:ok, "Hello World"} do
...>   {:ok, result} -> result
...>   {:error} -> "Uh oh!"
...>   _ -> "Catch all"
...> end

"Hello World"

El valor _ es similar al default de c o java. Y esto puede servir para prevenir errores:

iex> case :even do
...>   :odd -> "Odd"
...> end
** (CaseClauseError) no case clause matching: :even

iex> case :even do
...>   :odd -> "Odd"
...>   _ -> "Not Odd"
...> end
"Not Odd"

Dado que case se basa en pattern matching, se aplican todas las mismas reglas y restricciones. Si se quiere que coincida con variables existentes debe usar el operador pin ^ :

iex> pie = 3.14
 3.14
iex> case "cherry pie" do
...>   ^pie -> "Not so tasty"
...>   pie -> "I bet #{pie} is tasty"
...> end
"I bet cherry pie is tasty"

Permite tambien utilizar clausulas de protección:

iex> case {1, 2, 3} do
...>   {1, x, 3} when x > 0 ->
...>     "Will match"
...>   _ ->
...>     "Won't match"
...> end
"Will match"

cond

Cuando necesitamos hacer coincidir condiciones en vez de valores, podemos recurrir a cond.  Esto es similar a else if o elsif de otros lenguajes:

iex> cond do
...>   2 + 2 == 5 ->
...>     "This will not be true"
...>   2 * 2 == 3 ->
...>     "Nor this"
...>   1 + 1 == 2 ->
...>     "But this will"
...> end
"But this will"

Igual que case podemos tener un default que en este caso va ser el valor true :

iex> cond do
...>   7 + 1 == 0 -> "Incorrect"
...>   true -> "Catch all"
...> end
"Catch all"

with

with es útil cuando se puede usar una sentencia case anidada o situaciones que no se pueden canalizar de forma limpia. La expresión with se compone de las palabras clave, los generadores y, finalmente, una expresión.

Veamos un ejemplo simple y luego veremos algo más:

iex> user = %{first: "Sean", last: "Callan"}
%{first: "Sean", last: "Callan"}
iex> with {:ok, first} <- Map.fetch(user, :first),
...>      {:ok, last} <- Map.fetch(user, :last),
...>      do: last <> ", " <> first
"Callan, Sean"

En el caso de que una expresión no coincida, se devolverá un error:

iex> user = %{first: "doomspork"}
%{first: "doomspork"}
iex> with {:ok, first} <- Map.fetch(user, :first),
...>      {:ok, last} <- Map.fetch(user, :last),
...>      do: last <> ", " <> first
:error

Ahora veamos un ejemplo más grande sin with  y luego veamos cómo podemos refactorizarlo:

case Repo.insert(changeset) do
  {:ok, user} ->
    case Guardian.encode_and_sign(resource, :token, claims) do
      {:ok, token, full_claims} ->
        important_stuff(token, full_claims)
      error -> error
    end
  error -> error
end

Ahora usaremos with:

with {:ok, user} <- Repo.insert(changeset),
     {:ok, token, full_claims} <- Guardian.encode_and_sign(user, :token) do
  important_stuff(token, full_claims)
end

En Elixir 1.3 el with soporta el else:

import Integer

m = %{a: 1, c: 3}

a =
  with {:ok, number} <- Map.fetch(m, :a),
    true <- Integer.is_even(number) do
      IO.puts "#{number} divided by 2 is #{div(number, 2)}"
      :even
  else
    :error ->
      IO.puts "We don't have this item in map"
      :error
    _ ->
      IO.puts "It is odd"
      :odd
  end

Dejo link: https://elixirschool.com/lessons/basics/control-structures/