sábado, 29 de agosto de 2015

Tomar una parte de un string

La función substr en Php

La función substr() en Php retorna la porción de un string entre una posición de comienzo y una longitud dada. Si la longitud es omitida devuelve todos los caracteres hasta el final del string. Ambos parámetros podrían ser negativos.

// Ejemplos 
$rest = substr("0123456"2);      // retorna "23456"
$rest = substr("0123456", -2);     // retorna "56"
$rest = substr("0123456"22);   // retorna "23"
$rest = substr("0123456"2, -2);  // retorna "234"
$rest = substr("0123456", -3, -2); // retorna "4"
$rest = substr("0123456", -3, -3); // retorna ""

La función substr en Perl

La función substr() en Perl retorna una porción del string contenida entre la posición de comienzo y una longitud dada. Si la longitud es omitida devuelve todos los caracteres hasta el final del string. Ambos parámetros podrían ser negativos.

# Ejemplos
my $cadena = "0123456";
my $subcadena = substr($cadena,0,4); # $subcadena contiene "0123";
$subcadena = substr($cadena,1,4);    # $subcadena contiene "1234";
$subcadena = substr($cadena,2);      # $subcadena contiene "23456";
$subcadena = substr($cadena,-4,3);   # $subcadena contiene "345";
$subcadena = substr($cadena,-4,-3);  # $subcadena contiene "3";
$subcadena = substr($cadena,3,-4);   # $subcadena contiene "";
$subcadena = substr($cadena,3,-3);   # $subcadena contiene "3";


La función substring en Javascript

La función substring() en Javascript retorna una porción del string contenida entre dos índices. Si alguno es negativo lo considera como un 0.

var cadena = "0123456";
var rest = cadena.substring( 2);  // retorna "23456"
rest = cadena.substring( -2);     // retorna "0123456"
rest = cadena.substring( 23);   // retorna "2"
rest = cadena.substring( 22);   // retorna ""
rest = cadena.substring( 2, -2);  // retorna "01"
rest = cadena.substring( 0, 2);   // retorna "01"
rest = cadena.substring( -3, -2); // retorna ""
rest = cadena.substring( -3, -3); // retorna ""

La función substr en Javascript

La función substr() en Javascript retorna una porción del string contenida desde una posición inicial y hasta la cantidad de caracteres indicada como segundo parámetro. Si la longitud es negativa, la considera como un 0. Si la posición inicial es negativa, toma la posición inicial desde el final del string en vez de desde el principio.

var cadena = "0123456";
var rest = cadena.substr( 2);   // retorna "23456"
rest = cadena.substr( -2);      // retorna "56"
rest = cadena.substr( 23);    // retorna "234"
rest = cadena.substr( 22);    // retorna "23"
rest = cadena.substr( 2, -2);   // retorna ""
rest = cadena.substr( 0, 2);    // retorna "01"
rest = cadena.substr( -3, -2);  // retorna ""
rest = cadena.substr( -3, -3);  // retorna ""

La función slice en Javascript

La función slice() en Javascript retorna una porción del string contenida entre dos índices. Si algún índice es negativo, toma la posición desde el final del string en vez de desde el principio.

var cadena = "0123456";
var rest = cadena.slice( 2);  // retorna "23456"
rest = cadena.slice( -2);     // retorna "56"
rest = cadena.slice( 2, 3);   // retorna "2"
rest = cadena.slice( 2, 2);   // retorna ""
rest = cadena.slice( 2, -2);  // retorna "234"
rest = cadena.slice( 0, 2);   // retorna "01"
rest = cadena.slice( -3, -2); // retorna "4"
rest = cadena.slice( -3, -3); // retorna ""


miércoles, 26 de agosto de 2015

Saber si un string está contenido dentro de otro string


La función index y rindex en Perl

La función index en Perl devuelve la posición de un substring dentro de un string. Si no lo encuentra devuelve -1. Tiene un tercer parámetro opcional que marca en qué posición comenzar la búsqueda. Por defecto comienza a buscar desde el inicio del string.
La función rindex busca la última posición del substring dentro de un string. El tercer parámetro opcional marca en qué posición comenzar la búsqueda, si no se da ninguna posición empieza por el final del string.

my $cadena = "Mauricio compra todo con tarjeta";
my ($subc1,$subc2) = ('compra','vende');
print index($cadena,$subc1); # imprime 9
print index($cadena,$subc1,10); # imprime -1
print index($cadena,$subc2); # imprime -1

Encontrar todos los substrings


my $abc = "Luis le prestó a Ana lo que Luisa no le pudo prestar a Luisana\n";
my $pos = length($abc) - 1; # Calcular la posición del último carácter 
print "Luis se encontró en las posiciones: ";

while(1)
{
  $pos = rindex($abc, "Luis", $pos);
  last if($pos< 0);
  print $pos--, " ";  # 55 28 0
}

print "\n";


La función strpos y strrpos en Php

La función strpos en Php devuelve la primer ocurrencia de un substring dentro de un string. Si no lo encuentra devuelve false. El valor 0 no debe confundirse con el valor false, 0 es la primer posición del string. Tiene un tercer parámetro opcional que indica desde qué posición empezar la búsqueda.
La función strrpos busca desde el final de la cadena hacia atrás. El tercer parámetro indica desde qué posición empezar a buscar y puede ser negativo, en ese caso cuenta la posición a buscar desde el final del string.

$mystring = 'Daniel sólo vende en efectivo';
$findme   = 'Dan';
$pos = strpos($mystring, $findme);

// Debe usar el operador !== . Usar != podría dar resultados inesperados
// porque la posición de 'Dan' es 0. La comparación (0 != false) evalúa
// a false.
if ($pos !== false) {
     echo "El string '$findme' fue encontrado en el string '$mystring'";
         echo " y existe en la posición $pos";
} else {
     echo "El string '$findme' no fue encontrado en el string '$mystring'";
}
$foo = "0123456789a123456789b123456789c";

var_dump(strrpos($foo, '7', -5));  // Comienza la búsqueda hacia atrás en la 5ta
                                   // posición desde el final. Resultado: int(17)

var_dump(strrpos($foo, '7', 20));  // Comienza la búsqueda desde la posición 20
                                   // del string. Resultado: int(27)

La función indexOf y lastIndexOf en Javascript

La función indexOf en Javascript devuelve la posición de un substring dentro de un string. Si no lo encuentra devuelve -1. Tiene un tercer parámetro opcional que marca en qué posición comenzar la búsqueda. Por defecto comienza a buscar desde el inicio del string.
La función lastIndexOf busca la última posición del substring dentro de un string. El tercer parámetro opcional marca en qué posición comenzar la búsqueda, si no se da ninguna posición empieza por el final del string.

// Ejemplo 1
var str = "Los teléfonos celulares se vuelven cada día más inteligentes";
var n = str.indexOf("e"); 
alert(n); // muestra un 5

// Ejemplo 2
var str = "La inteligencia no se puede medir con un número";
var n = str.lastIndexOf("z", 20); 
alert(n); // muestra un -1

domingo, 23 de agosto de 2015

Calcular la longitud de un string


Función length en Perl

La función length trae la longitud de un string.

#Ejemplo
print length("cadena"); # imprime 6


Función strlen en Php

La función strlen devuelve la longitud de un string.

$str 'abecedario';
echo strlen($str); // imprime 10


Propiedad length en Javascript

La propiedad length devuelve la longitud de un string.

var str = "Hello World!";
var n = str.length; // 12

jueves, 20 de agosto de 2015

Unir un array de strings en un solo string



Comando join en Perl

En Perl la función join une los elementos contenidos en un array y forma un único string, usa un separador opcional. Su primer argumento es el separador, el segundo es el array o incluso un hash.

# Ejemplo 1

my %personales = ('apellido'=>'Perez', 'email'=>'perez@example.com');
my $comma_separated = join(",", %personales);

print $comma_separated . "\n"; # email,perez@example.com,apellido,Perez

# Ejemplo 2

my @frutas = ("Banana", "Naranja", "Manzana", "Mango");
my $energy = join('',@frutas);

print $energy . "$/"; # BananaNaranjaManzanaMango 


Comando implode en Php

En Php la función implode une los elementos contenidos en un array y forma un único string, usa un separador opcional. Si no se especifica utiliza el carácter vacío.


// Ejemplo 1

$personales = array('apellido', 'email', 'dirección');
$comma_separated = implode(",", $personales);

echo $comma_separated; // apellido,email,dirección

// Ejemplo 2

$frutas = ["Banana", "Naranja", "Manzana", "Mango"];
$energy = implode($frutas);

alert($energy); // BananaNaranjaManzanaMango 


Comando join en Javascript

En Javascript la función join une los strings contenidos en un array y forma un único string, usa un separador opcional. Si no se especifica el separador, utiliza el carácter ','.

// Ejemplo 1

var personales = new Array('apellido', 'email', 'dirección');
var comma_separated = personales.join(",");

alert(comma_separated); // apellido,email,dirección

// Ejemplo 2

var frutas = ["Banana", "Naranja", "Manzana", "Mango"];
var energy = frutas.join();

alert(energy); // Banana,Naranja,Manzana,Mango 

martes, 18 de agosto de 2015

Separar un string por un delimitador



Comando split en Perl

En Perl la función split devuelve un array de strings como resultado de dividir un array por un carácter delimitador o por un string. Por ejemplo:

# Ejemplo 1
my $pizza  = "porcion1 porcion2 porcion3 porcion4 porcion5 porcion6";
my @porciones = split(" ", $pizza);
print $porciones[0]; # porcion1
print $porciones[1]; # porcion2

# Ejemplo 2
my $data = "foo:*:1023:1000::/home/foo:/bin/sh";
my ($user, $pass, $uid, $gid, $gecos, $home, $shell) = split(":", $data);
print $user; # foo
print $pass; # *


# Ejemplo 3
use Data::Dumper;

my $str = 'one,two,three,four';

# limite positivo
my @count = split(',', $str, 2);
print Dumper(\@count);

# limite negativo no tiene efecto
@count = split(',',$str,-1);
print Dumper(\@count);
$VAR1 = [
          'one',
          'two,three,four'
        ];
$VAR1 = [
          'one',
          'two',
          'three',
          'four'
        ];


Comando explode en Php

En Php la función explode devuelve un array de strings como resultado de dividir un array por un carácter delimitador o por un string. Por ejemplo:

Array
(
    [0] => one
    [1] => two,three,four
)
Array
(
    [0] => one
    [1] => two
    [2] => three
)


Comando split en Javascript

En Javascript la función split devuelve un array de strings como resultado de dividir un array por un carácter delimitador o por un string. Por ejemplo:

// Ejemplo 1
var pizza  = "porcion1 porcion2 porcion3 porcion4 porcion5 porcion6";
var porciones = pizza.split(" ");
alert(porciones[0]); // porcion1
alert(porciones[1]); // porcion2

// Ejemplo 2
var str = "Hola Mundo!";
// sin usar delimitador devuelve el mismo string
var res = str.split();
alert(res); // Hola Mundo! 


// Ejemplo 3
var str = 'one,two,three,four';

// limite positivo
console.log(str.split(',', 2));

// limite negativo no tiene efecto
console.log(str.split(',', -1));
["one", "two"]

["one", "two", "three", "four"]


sábado, 15 de agosto de 2015

Adivina qué número estoy pensando

Juego con Perl POE

En este juego el ordenador piensa un número del 1 al 20 y te da 5 oportunidades para adivinar. Si le erras te da una pista sobre si su número es mayor o menor al número que le dijiste. Para ponerlo más difícil hay un timeout de 10 segundos para que adivines el número o perderás el juego.

Por qué POE

Cuando un programa necesita interacción con el usuario o con datos externos, necesitamos una estructura de programa que sea más expresiva.
POE es un framework para la creación de programas en Perl donde se presentan naturalmente tareas que implican reaccionar ante datos externos o eventos, como las comunicaciones de red o las interfaces de usuario. Los programas en POE son no-lineales, se configuran un montón de pequeñas subrutinas y se define la forma en que se llaman entre sí. POE cambiará automáticamente entre ellas mientras maneja la entrada y salida del programa.

#!/usr/bin/perl -w
use strict;

# Usar POE!
use POE qw/Wheel::ReadLine/;

# Necesitas hacer esto para Cygwin
#$/="\n\r";

# flush STDOUT automaticamente
$|++;


  POE::Session->create(
    inline_states =>
      { _start    => \&handler_start,
        gotLine   => \&handler_gotLine,
        prompt    => \&handler_prompt,
        gameover    => \&handler_gameover,
        timeout   => \&handler_timeout,
        #_stop     => \&handler_stop,
      }
  );

my $limite= 20;
my $intentos_total= 5;
my $intentos= $intentos_total;
my $numero= int(rand($limite-1)) + 1;
print "Adivina el numero$/";
print "Hola!!!, estoy pensando un número del 1 al $limite. ";
print "Tienes $intentos oportunidades para adivinarlo$/";
$poe_kernel->run();
print "\n";

sub handler_start {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];

  # POE::Wheel::ReadLine obtiene la entrada de tu terminal y viene con un historial
  # cuando una nueva linea es ingresada, se ejecuta el evento gotLine
  $heap->{wheel} = POE::Wheel::ReadLine->new
      (
        InputEvent => 'gotLine',
    );

  # pide por el evento prompt para que se ejecute otra vez
  $kernel->yield('prompt');
}
sub handler_prompt {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];
  my $tiempo= 10;
  print "Tienes $tiempo segundos para adivinar, o perderás el juego!$/";
  if (2>$intentos){ 
    print "Es tu última oportunidad$/";
  }
  $heap->{wheel}->get('Tipea rápido: ');

  # dispara el evento timeout para dentro de una cantidad de segundos
  $kernel->delay('timeout',$tiempo);
}
sub handler_timeout {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];

  # informar al usuario que perdió
  print "$/El número era $numero, tardaste demasiado tiempo, game over$/";

  # setear esta variable a undef hará que termine nuestro Wheel
  # sin wheel y sin el evento delay pendiente la cola del kernel
  # está vacia y se realiza un shutdown
  $heap->{wheel}=undef;
}

sub handler_gameover {
  my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION];

  # informar al usuario que perdió
  print "\nEl número era $numero, lo siento, game over\n";

  # setear un delay sin el número de timeout limpia el evento
  # sin el evento delay pendiente la cola del kernel
  # está vacia y se realiza un shutdown
  $kernel->delay('timeout');
}

sub handler_gotLine {
  my ($kernel, $heap, $session, $arg, $exception) = 
            @_[KERNEL, HEAP, SESSION, ARG0, ARG1];

  if(defined $arg) {
    $heap->{wheel}->addhistory($arg);
    $intentos--;
    if ($numero==$arg){
      print "Excelente! Mi número era el $numero. Lo conseguiste en " . ($intentos_total - $intentos) . " intentos!$/";
      # setear un delay sin el número de timeout limpia el evento
      $kernel->delay('timeout');
      # setear esta variable a undef hará que termine nuestro Wheel
      $heap->{wheel}=undef;
      return;
    }elsif($numero>$arg){
      print "El número es mayor que $arg$/";
    }else{
      print "El número es menor que $arg$/";
    }
    if (1>$intentos){
      # se acabaron las oportunidades para adivinar el número
      $kernel->yield('gameover');
      return;
    }
  }
  else {
    print "Got input exception '$exception'.  Exiting...$/";

    # setear esta variable a undef hará que termine nuestro Wheel
    $heap->{wheel}=undef;
    # setear un delay sin el número de timeout limpia el evento
    $kernel->delay('timeout');

    return;
  }

  # ejecuto el evento prompt de nuevo para resetear el timeout e
  # imprimir un nuevo prompt
  $kernel->yield('prompt');
}

Salida


Adivina el numero
Hola!!!, estoy pensando un número del 1 al 20. Tienes 5 oportunidades para adivinarlo

Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 8
El número es mayor que 8
Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 18
El número es menor que 18
Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 
              El número era 14, tardaste demasiado tiempo, game over
Adivina el numero
Hola!!!, estoy pensando un número del 1 al 20. Tienes 5 oportunidades para adivinarlo

Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 1
El número es mayor que 1
Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 2
El número es mayor que 2
Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 3
El número es mayor que 3
Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 4
El número es mayor que 4
Tienes 10 segundos para adivinar, o perderás el juego!
Es tu última oportunidad
Tipea rápido: 5
El número es mayor que 5

El número era 13, lo siento, game over
Adivina el numero
Hola!!!, estoy pensando un número del 1 al 20. Tienes 5 oportunidades para adivinarlo

Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 10
El número es mayor que 10
Tienes 10 segundos para adivinar, o perderás el juego!
Tipea rápido: 15
Excelente! Mi número era el 15. Lo conseguiste en 2 intentos!

Desafío

Como tarea final te dejo una modificación para que al finalizar el juego te pregunte que si quieres volver a jugar, y que puedas jugarlo otra vez.

miércoles, 12 de agosto de 2015

Intervalos de horas que se superponen

Problema

Supongamos que tenemos una lista de horarios con hora de comienzo y de final. Y queremos saber si algún intervalo horario se superpone con algún otro. Los horarios vienen en formato 'HH:mm:ss' pero solo nos interesan las horas y los minutos. Supongamos también que está en formato de 24hs.
Deberíamos hacer una serie de consultas con cada intervalo, pero como puede haber intervalos que cruzan las 00hs, esas consultas se vuelven muy complicadas. Para simplificar, supongamos que sólo queremos saber si la hora de comienzo de un intervalo está superpuesta en algún otro intervalo. Por lo tanto si esa hora es mayor o igual al inicio de un intervalo pero menor estricto que el final de ese intervalo se considera que el intervalo examinado se encuentra superpuesto con el otro.

Por ejemplo el intervalo '21:00:00,23:00:00' se superpone con los intervalos '20:00:00,22:00:00', '22:00:00,01:30:00' y '09:00:00,21:00:00', pero no se superpone con el intervalo '23:00:00,04:00:00' ni con el intervalo '13:00:00,18:00:00'.



Solución

A continuación presento un script en Perl para solucionar este problema. Dado un array de intervalos y un índice que es el índice del array donde está el intervalo que quiero comparar con todos los demás, ejecuto una función que me retorna si se superpone con alguno de los otros intervalos.

#!/usr/bin/perl
use strict;
use Data::Dumper;

my @intervalos;
push(@intervalos,{'desde'=>'09:00:00','hasta'=>'12:00:00'});
push(@intervalos,{'desde'=>'12:00:00','hasta'=>'15:00:00'});
push(@intervalos,{'desde'=>'14:00:00','hasta'=>'17:00:00'});
push(@intervalos,{'desde'=>'17:30:00','hasta'=>'22:30:00'});
push(@intervalos,{'desde'=>'22:00:00','hasta'=>'00:00:00'});
push(@intervalos,{'desde'=>'23:59:00','hasta'=>'08:59:00'});

print Dumper(\@intervalos);

my $indice= 5;
my $es_superpuesto= ver_solapacion($indice,@intervalos);
print "Superpuesto: $es_superpuesto\n";

sub ver_solapacion{
  my ($indice,@intervalos)= @_;
  my $s= 0;
  my $pivote_indice= $intervalos[$indice]->{'desde'};
  print "Hora 'desde' del intervalo interesante: $pivote_indice \n";
  my $pivote= time_trans($pivote_indice);
  my $i= 0;
  foreach my $row (@intervalos){
    if ($i==$indice){ $i++; next; }
    my $a= time_trans($row->{'desde'});
    my $b= time_trans($row->{'hasta'});
    my $c= time_suma($a,$b);
    my $d= time_suma($a,$pivote);
    if ($d < $c){ $s=1; last; }
    $i++;
  }
  return $s;
}
sub time_trans{
  my ($hora)= @_;
  my @h= split(':',$hora);
  return  $h[0] + ($h[1]/100);
}
sub time_suma{
  my ($a,$b)= @_;
  if ($a>$b){ return 24 + $b; }
  return $b - $a;
}

Resultado: el intervalo está superpuesto

$intervalos = [
          {
            'hasta' => '12:00:00',
            'desde' => '09:00:00'
          },
          {
            'hasta' => '15:00:00',
            'desde' => '12:00:00'
          },
          {
            'hasta' => '17:00:00',
            'desde' => '14:00:00'
          },
          {
            'hasta' => '22:30:00',
            'desde' => '17:30:00'
          },
          {
            'hasta' => '00:00:00',
            'desde' => '22:00:00'
          },
          {
            'hasta' => '08:59:00',
            'desde' => '23:59:00'
          }
        ];
Hora 'desde' del intervalo interesante: 23:59:00 
Superpuesto: 1

sábado, 8 de agosto de 2015

Clase Cuenta Bancaria en JS usando Joose


Problema

Modelizaremos una cuenta bancaria normal. En esta cuenta se puede depositar dinero, retirar dinero y comprobar su saldo actual. No se puede retirar más dinero que el que hay en la cuenta. Además modelizaremos una cuenta corriente con una protección contra sobregiros opcional. La protección contra sobregiros protegerá al propietario de la cuenta corriente retirando automáticamente los fondos necesarios de la cuenta de sobregiro para asegurar que un cheque no rebotará.

Solución

Module("Banco", function (m) {
  Class("Cuenta", {
    has: {
      balance: {
        is: "rw",
        init: 0
      }
    },
    methods: {
      depositar: function (monto) {
        this.setBalance(this.getBalance() + monto)
      },
      retirar: function (monto) {
        if(this.getBalance() < monto) {
          throw "Cuenta sobregirada"
        }
        this.setBalance(this.getBalance() - monto);
        return this.getBalance();
      }
    }
  });
  
  Class("CuentaCorriente", {
    isa: m.Cuenta,
    has: {
      cuentaSobregiro: {
        isa: m.Cuenta,
        is: "rw"
      }
    },
    before: {
      retirar: function (monto) {
        var cantidadEnRojo = monto - this.getBalance()
        
        if(this.cuentaSobregiro && cantidadEnRojo > 0) {
           this.cuentaSobregiro.retirar(cantidadEnRojo);
           this.depositar(cantidadEnRojo);
        }
      }    
    }
  })
}) 

Explicacion

La clase Cuenta tiene un "balance" inicializado en 0 y dos métodos: "depositar" y "retirar". La CuentaCorriente es una subclase de Cuenta que tiene una "cuentaSobregiro" opcional que es de tipo Cuenta. Antes de retirar un monto de la CuentaCorriente verifica si puede sobregirar la cuenta.

Módulos

Module("Banco", function (m) {
...
} 

La función Module() crea el namespace "Banco". Toma como segundo argumento una función que crea las clases Cuenta y CuentaCorriente. La función obtiene un objeto módulo como parámetro, que más tarde será utilizado para facilitar el acceso a otras clases ubicadas dentro del namespace.

Restricciones de Tipo

has: {
  cuentaSobregiro: {
    isa: m.Cuenta,
    is: "rw"
  }
}, 

Aquí introducimos un nuevo atributo para la clase CuentaCorriente llamado "cuentaSobregiro". Usando la palabra clave isa ponemos una restricción de tipo sobre el atributo. Esta restricción es chequeada cada vez que el método setCuentaSobregiro() es usado. Ese método fue creado automáticamente cuando se definió el atributo como rw.

Modificador de método "before"

before: {
  retirar: function (monto) {
    var cantidadEnRojo = monto - this.getBalance()
    
    if(this.cuentaSobregiro && cantidadEnRojo > 0) {
       this.cuentaSobregiro.retirar(cantidadEnRojo);
       this.depositar(cantidadEnRojo);
    }
  }    
} 

Introducimos un método que será ejecutado antes del método retirar(). De esta manera el método original se ve aumentado en su comportamiento. Si el dinero actual en el balance de la cuenta no es suficiente para el retiro, se extrae lo que falta de la cuentaSobregiro y se deposita en la cuenta.

Modificador de método "override"

Otra posible implementación podría haber sido sobreescribir el método retirar() usando el modificador override, el cual permite llamar al método de la superclase haciendo this.SUPER()
override: {
  retirar: function (monto) {
    var cantidadEnRojo = monto - this.getBalance()
      
    if(this.cuentaSobregiro && cuentaSobregiro > 0) {                
      this.cuentaSobregiro.retirar(cantidadEnRojo);
      this.depositar(cantidadEnRojo);
    }

    this.SUPER(amount)
  }
} 

Instanciación de los objetos

Todos los objetos Joose reciben un inicializador estándar que permite inicializar los objetos usando argumentos por nombre en el constructor:
var cajaAhorros= new Banco.Cuenta({ balance: 100 });
var cuentaCorriente= new Banco.CuentaCorriente({ 
    balance:         200, 
    cuentaSobregiro: cajaAhorros
});
console.log("Una cuenta: ");
console.log(cajaAhorros);
console.log("Una cuenta corriente: ");
console.log(cuentaCorriente);
console.log("Operamos en la cuenta con un retiro parcial de 100");
cuentaCorriente.retirar(100);
console.log(cuentaCorriente);
console.log(cajaAhorros);
console.log("Sobregiramos la cuenta con un retiro mayor: 150");
cuentaCorriente.retirar(150);
console.log(cuentaCorriente);
console.log(cajaAhorros);
console.log("Sobregiramos demasiado la cuenta: 300");
cuentaCorriente.retirar(300);

Una cuenta: 
 a Banco.Cuenta { balance=100, meta=a Joose.Class, initialize=initialize(), más...}
Una cuenta corriente: 
 a Banco.CuentaCorriente { balance=200, cuentaSobregiro=a Banco.Cuenta, meta=a Joose.Class, más...}
Operamos en la cuenta con un retiro parcial de 100
 a Banco.CuentaCorriente { balance=100, cuentaSobregiro=a Banco.Cuenta, meta=a Joose.Class, más...}
 a Banco.Cuenta { balance=100, meta=a Joose.Class, initialize=initialize(), más...}
Sobregiramos la cuenta con un retiro mayor: 150
 a Banco.CuentaCorriente { balance=0, cuentaSobregiro=a Banco.Cuenta, meta=a Joose.Class, más...}
 a Banco.Cuenta { balance=50, meta=a Joose.Class, initialize=initialize(), más...}
Sobregiramos demasiado la cuenta: 300
uncaught exception: Cuenta sobregirada

lunes, 3 de agosto de 2015

Web API Console

Comandos


console.log(object[, object, …])
Escribe un mensaje en la consola. Como primer argumento puede aceptar un objeto o un string con especificadores de formato. Por ejemplo %s para string, %d para enteros, %f para flotantes o %o para objetos.
console.log("Usuario %s posee %d créditos", userName, creditCount);

console.debug(object[, object, ...])
Idéntico a console.log.

console.info(object[, object, ...])
Idéntico a console.log pero agrega un ícono "info".

console.warn(object[, object, ...])
Idéntico a console.log pero agrega un ícono "warning".

console.error(object[, object, ...])
Similar a console.log pero agrega un ícono "error" y una traza de la pila.

console.assert(expression[, object, ...])
Testea que una expresión sea verdadera. Si no lo es escribirá un mensaje de error en la consola junto a una traza de la pila. Por ejemplo:
console.assert(list.childNodes.length < 10, "List item count is >= 10");

console.clear()
Limpia la consola.

console.dir(object)
Muestra las propiedades del objeto.

console.trace()
Muestra una traza de la pila en el punto donde es llamado.

console.time(label)
Comienza un timer con una etiqueta label asociada. Cuando console.timeEnd(label) es llamado, el timer es detenido y se muestra en la consola el tiempo transcurrido.

console.profile([title])
Inicia el CPU profile con un título opcional. Para completar el profile llame a console.profileEnd() para que imprima el reporte.

console.count([label])
Escribe el número de veces count() fue ejecutado con el mismo label o las veces que se ejecutó la misma línea de código donde count() fue llamado y ejecutado.

console.table(data[, columns])
Similar a console.log pero muestra los datos en formato de tabla. Por ejemplo:
var languages = [
    { name: "JavaScript", fileExtension: ".js" },
    { name: "Perl", fileExtension: ".pl" },
    { name: "Python", fileExtension: ".py" },
    { name: "Erlang", fileExtension: ".erl" },
    { name: "PHP", fileExtension: ".php" }
];

console.table(languages);
Muestra por consola:

name fileExtension
"JavaScript" ".js"
"Perl" ".pl"
"Python" ".py"
"Erlang" ".erl"
"PHP" ".php"

domingo, 2 de agosto de 2015

HTML DOM querySelector()

Ejemplo

document.querySelector(".ejemplo");
Obtiene el primer elemento en el documento con la clase "ejemplo".
El método querySelector() retorna el primer elemento del documento que matchea con un específico selector CSS. Si se quiere obtener todos los elementos se puede usar querySelectorAll().

Sintaxis

document.querySelector(CSS selectors)
El parámetro especifica uno o más selectores CSS separados por comas, para buscar un elemento en el documento. Retorna un objeto NodeList o null si no es encontrado.

Más ejemplos

document.querySelector("p");
Obtiene el primer elemento párrafo en el documento.
document.querySelector("p.ejemplo");
Obtiene el primer elemento párrafo en el documento con la clase "ejemplo".
document.querySelector("#demo").innerHTML = "Hola Mundo!";
Obtiene el primer elemento con id="demo" y modifica su texto.
document.querySelector("div > p");
Obtiene el primer elemento párrafo cuyo parent es un elemento div.
document.querySelector("a[target]");
Obtiene el primer elemento <a> que tenga un atributo "target".

Ejemplo con múltiples selectores

<h2>Titulo de nivel 2</h2>
<h3>Titulo de nivel 3</h3>

document.querySelector("h2, h3").style.backgroundColor = "red";
El primer elemento que encuentra es un título de nivel 2, por eso lo colorea de rojo y no sigue buscando elementos de título de nivel 3.
En el ejemplo siguiente colorea el elemento de título de nivel 3 porque es el primer elemento que matchea con alguno de los selectores, luego no sigue buscando.
<h3>Titulo de nivel 3</h3>
<h2>Titulo de nivel 2</h2>

document.querySelector("h2, h3").style.backgroundColor = "red";

sábado, 1 de agosto de 2015

Clase Selfie en Joose JS

Código

Class("Fotografia", {
    has: {
        alto: {is: "ro"},
        ancho: {is: "rw"},
    },
    methods: {
        clear: function () {
            this.alto = 0;
            this.setAncho(0);
        }
    }
})
Class("Selfie", {
    isa: Fotografia,
    has: {
        etiqueta: {init: "yo"}
    },
    after: {
        clear: function () {
            this.etiqueta = "yo";
        }
    }
})
var foto= new Selfie({ancho: 360, alto:240});
foto.etiqueta= "Ricky Martin";

Explicación


Este es un ejemplo de Joose para crear una clase que hereda de otra. La función Class() toma dos parámetros: el nombre de la clase y la definición de la clase pasada como un objeto literal. La sintaxis para definir la clases es declarativa y fácil de leer. Las palabras clave como "has", "methods", "isa" y "after" son usadas para expresar diferentes aspectos de la clase.

Atributos


has: {
        alto: {is: "ro"},
        ancho: {is: "rw"},
    }, 

El primer elemento de la declaración de la clase Fotografía es un bloque "has" que define dos atributos de la clase: alto y ancho. El bloque alto: {is: "ro"} define "alto" como de sólo lectura. Mientras que el bloque ancho: {is: "rw"} define "ancho" como un atributo de lectura y escritura. Joose automáticamente crea los métodos getAlto() para "alto" y getAncho() y setAncho() para "ancho". El nombre de estos métodos sigue la convención camelCase, colocando la primera letra del atributo en mayúscula.

has: {
        etiqueta: {init: "yo"}
    }, 

El bloque etiqueta: {init: "yo"} define el atributo "etiqueta" con un valor por default que es el string "yo". Como no se especifica si es rw o ro, por defecto no se crean los métodos de acceso getEtiqueta() y setEtiqueta().

Métodos


methods: {
        clear: function () {
            this.alto = 0;
            this.setAncho(0);
        } 

El bloque "methods" define el método clear() para la clase Fotografía. Podemos poner todos los métodos que queramos. En este caso la función setea "alto" accediendo a la variable directamente, pero modifica "ancho" usando su método modificador creado con la declaración "rw".

Herencia


 isa: Fotografia, 

La cláusula "isa" en la definición de Selfie define que su super clase es Fotografía. Selfie hereda los métodos y atributos de su superclase.

Modificador de método


after: {
        clear: function () {
            this.etiqueta = "yo";
        }
    } 

Joose soporta los llamados modificadores de métodos. Uno de los 5 modificadores que declaran métodos con un comportamiento especial es "after". Aquí define que acciones ejecutar después de llamar al método con el mismo nombre definido en su superclase.

Inicialización


var foto= new Selfie({ancho: 360, alto:240}); 

El objeto literal {ancho: 360, alto:240} es pasado como argumento de un método especial llamada initialize() que lo usa para inicializar los valores del atributo del nuevo objeto.