13 marzo 2010

Java Best Practices

Después de mucho tiempo de no realizar ningún post vuelvo para compartir una presentación que estoy realizando sobre buenas prácticas de programación espero les sea útil.

La idea de estar presentación es ir actualizándola lo más que se pueda, así queda como un documento de referencia para las personas que estén interesadas en ir programando cada día mejor.
Aclaro que no soy ningún experto acepto cualquier comentario que puede ir mejorando la presentación ya que esto está pensado para todos y la idea es que si alguien tiene alguna idea que agregar me avise y la agregamos.


Saludos

Leer más...

04 agosto 2009

JavaFX Sintaxis Declarativa

En el post anterior hemos visto un ejemplo sobre cómo realizar un Hello World con JavaFX pero sin entrar en mucho detalle sobre algunas líneas del código, ahora seguiremos con algunos ejemplos más y explicando un poco sobre esto de Sintaxis Declarativa, por ejemplo un objeto puede ser creado con un Objeto Literal. Lo que significa una sintaxis declarativa concisa parecida a javascript, en lugar de explicar "como" realizar algo (el algoritmo, en los lenguajes imperativos), deberemos describir "que" es ese algo. Por ejemplo, en HTML, se declara el contenido de la página, pero no se explica cómo este será mostrado en la pantalla. Ahora veremos algunos ejemplos para aclarar esto.

Iremos desarrollando un ejemplos casi línea por línea para ir notando la simpleza del lenguaje e ir viendo algunos efectos, para este ejemplo usaremos una imagen que la pueden encontrar en el siguiente link ,comencemos.

Paso 1:


import javafx.stage.Stage;

Stage {
width: 400
height: 400
}

con las pocas líneas de arriba ya hemos definido una instancia de un objeto Stage, el cual es necesario para renderizar una ventana.

Paso 2:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 400
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
}
]
}
}

aquí hemos complicado un poco la cosa, pero veremos cada detalles, los primeros import de Scene, Image e ImageView son necesarios por los siguiente motivos.
Scene es el objeto el cual nos permite renderizar elementos gráficos dentro de el, el ImageView es el contenedor para una determinada imagen, y por último el Image es la imagen en sí. Si notamos la definición de Scene, vemos que a su propiedad content(Aquí dibujamos los elementos gráficos), hemos agregado una instancia de ImageView y a esta le hemos asignado la imagen previamente cargada en la variable image. Como podrán notar toda la sintaxis es muy simple y siempre nos preocupamos en la declaración de lo que deseamos y no en como generar todo esto.
El código hasta ahora nos generaría una ventana, con la imagen posicionada en el centro, pero nuestra Scene por defecto tiene un color blanco de fondo, si vemos en posts anteriores veremos que podíamos asignar colores en forma de gradientes, pues bueno eso haremos como siguiente paso.

Paso 3:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.Color;

/**
* @author softdesigner
*/

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 400
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
}
]
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 0.0
endY : 1.0
stops: [
Stop {
color : Color.WHITE
offset: 0.0
},
Stop {
color : Color.BLACK
offset: 1.0
}
]
}
}
}

Si vemos la propiedad fill del objeto Scene, nos damos cuenta que estamos asignando un LinearGradient a esta propiedad, como podemos deducir esto generara un Gradiente linear por medios de las propiedades startX, startY, endX, endY definimos la dirección lineal y por medio de los stops definimos que distintos Stop usar, cada Stop define necesita su propiedad color y su propiedad offset la cual indicada cuando se detendrá ese gradiente.

Muchas veces cuando estamos retocando imágenes o logrando algún efecto se nos plantea la necesidad de lograr un efecto de reflejo sobre el agua o algún material, JavaFX viene con muchas de estas dificultades resueltas ya que brinda diversos efectos para ser aplicados a nuestras imágenes, para ver esto usaremos un efecto de Reflection para lograr reflejar nuestra imagen.

Paso 4:


import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.Color;
import javafx.scene.effect.Reflection;

/**
* @author softdesigner
*/

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 600
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
effect: Reflection {
fraction: 0.75
topOffset: 0.0
topOpacity: 0.5
bottomOpacity: 0.0
}
}
]
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 0.0
endY : 1.0
stops: [
Stop {
color : Color.WHITE
offset: 0.0
},
Stop {
color : Color.BLACK
offset: 1.0
}
]
}
}
}

Ahora tenemos nuestra imagen con un efecto de Reflection, este es asignado al ImageView ya que es el contenedor de la imagen y ahora explicaremos cada propiedad de este efecto.
fraction: Es la fracción que se muestra reflejada en base a la imagen original(Valor porcentual).
topOffset: Es la distancia entre la imagen y el comienzo de su reflejo(Valor libre).
topOpacity: Es la opacidad del comienzo del reflejo(Valor porcentual).
bottomOpacity: Es la opacidad del final del reflejo(Valor porcentual).

Para ir terminando el ejemplo como último detalle, queremos mostrar dos efectos al mismo tiempo, los cuales serán una DropShadow y un efecto Reflection.

Paso 5:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.paint.Color;
import javafx.scene.effect.Reflection;
import javafx.scene.effect.DropShadow;

/**
* @author softdesigner
*/

var image = Image {
url: "{__DIR__}JavaFX.png"
}

Stage {
width: 400
height: 600
scene: Scene {
content: [
ImageView {
x: 75
y: 60
image: image
effect: Reflection {
fraction: 0.75
topOffset: 0.0
topOpacity: 0.5
bottomOpacity: 0.0
input: DropShadow {
offsetX: 10
offsetY: 10
color: Color.BLACK
radius: 10
}
}
}
]
fill: LinearGradient {
startX : 0.0
startY : 0.0
endX : 0.0
endY : 1.0
stops: [
Stop {
color : Color.WHITE
offset: 0.0
},
Stop {
color : Color.BLACK
offset: 1.0
}
]
}
}
}

Si leemos acerca de la propiedad effect del ImageView descubriremos que solo acepta un objeto effect, y aquí nos entra la duda de cómo haremos mas agregar dos efectos al mismo tiempo, para esto casi todos los efectos tiene una propiedad input la cual recibe un effect, así que si nosotros quisiéramos ir encadenando efectos deberíamos hacerlo por medio de esta propiedad, en la parte superior del código se nota que el efecto Reflection recibe un input de un DropShadow, las propiedades del DrowShadow son las siguientes:
offsetX: Cantidad de pixeles sobre el eje x.
offsetY: Cantidad de pixeles sobre el eje y.
color: Color de relleno de la sombra.
radius: Radio del difuminado para la sombra.

Con esto daremos por finalizada esta mínima explicación y demostración sobre la Sintaxis declarativa que ofrece JavaFX y la simplicidad y poder de este lenguaje.
Les dejo un link al ejemplo del proyecto netbeans, luego intentare dejar el jnlp para que lo puedan descargar.

Proyecto
DeclarativeSyntax.rar



Saludos

Leer más...

02 agosto 2009

JavaFX GUI

El Api de JavaFX brinda a los desarrolladores la posibilidad de crear interfaces UI que seran independientes del dispositivo, podemos definir una division entre lo que seria un Common profile y un Desktop profile. El Common profile puede ser usado en aplicaciones de escritorio asi como en aplicaciones para mobiles. En cambio el Desktop profile es espefico de aplicaciones de escritorio.El SDK de JavaFX posee un JavaFX Mobile Emulator en el cual podemos ver como quedan nuestras aplicaciones sobre telefonos mobiles, en algun post veremos como usar esto. Daremos una breve explicacion sobre la separacion de categorias y que paquetes entran en juego, y dejaremos un link a los archivos de ejemplo de Sun.Este post sera una presentacion sobre el mundo JavaFX y dejaremos un videotutorial sobre como crear el indispensable HelloWorld para no fracasar en un nuevo lenguaje.

Contenidos

Common Profile:

  • User Interface Elements
  • Charts
  • Colors
  • Shapes
  • Fill Styles
  • Line Cap and Join Style
  • Text
  • Transformations
  • Layout
Desktop Profile:
  • Effects
  • Cursors
Common Profile:

User Interface Elements
Aqui encontraremos todos los componentes para poder crear interfaces de usuario,todos estos componentes se hayan en el paquete javafx.scene.control.

Archivo de ejemplo:
UIControls.fx

Charts
JavaFX ya provee muchos tipos de graficas prefabricadas, estas las podemos encontrar en el paquete javafx.scene.chart veremos una lista de las graficas disponibles:
Graficas de Area
Graficas de Barras
Graficas de Burbujas
Graficas de Lineas
Graficas de Pastel
Graficas de Dispersion

Colors
JavaFX nos provee una clase que se haya en el paquete javafx.scene.paint.Color la cual posee constantes de los colores predefinidos y a su vez metodos especificos para trabajar con ellos.

Archivo de ejemplo:
Colores

Shapes
Los Shapes son las formas basicas que podemos realizar obviamente que mezclandolas entre si podremos obtener otras figuras mas complejas. Esta se encuentra en el paquete javafx.scene.shape.

Archivo de ejemplo:
Shapes

Fill Styles
Los Fill son los tipos de relleno que podemos aplicar cuando pintamos ciertos elementos, a estos le podemos agregar patrones para lograr efecto de pintado ya sea degrade ya sea del tipo radial o lineal, y tambien colores solidos.

Archivo de ejemplo:
Fill Styles

Line Cap and Join Styles
Cuando construimos figuras geometricas muchas veces juntamos lineas y distinos estilos, esto es posible en base a las clases del paquete javafx.scene.shape el cual provee las herramientas necesarias para esto.

Archivo de ejemplo:
Line Cap and Join Styles

Text
Cuando escribimos texto, podemos asignar distintos formatos, estas caracteristicas estan englobadas en el paquete javafx.scene.text, podremos rotar las letras, moverlas de posicion, asignar distinas tipografias, etc.

Archivo de ejemplo:
Text

Transformations
Podemos aplicar diversas transformaciones por ejemplo rotaciones, translaccion de coordenadas, escalado de imagenes, etc.

Archivo de ejemplo:
Transformations

Layout
Los layout nos marcan la distribuccion de los elementos por la ventana, hay diversos tipos y estan almacenados en el paquete javafx.scene.layout.

Archivo de ejemplo:
HBox
VBox

Desktop Profile:

Effects
Podemos aplicar distintos efectos que ya vienen incorporados con JavaFX, estos efectos pueden ser aplicados a los elementos JavaFX UI.

Archivo de ejemplo:
Effects

Cursors
Podemos asignar distintos cursores sobre los elementos de JavaFX.

Archivo de ejemplo:
Cursors

Link General
Les dejo un link con un rar que posee todos los ejemplos de la pagina de Sun, por si el link de algun ejemplo no anda aca estan todos juntos.
Ejemplos

Después de esta pequeña introducción sobre los elementos gráficos y distintas caracterizas incluidas en JavaFX procederemos a hacer el primer ejemplo de nuestro largo camino de aprendizaje, sin más palabras el Hello World!!!
Espero el video tutorial sea entendible ya que este es el primero que hago y hay demasiados errores, espero pueda serle de utilidad y les sirva.

Saludos


Leer más...

31 julio 2009

Binding And Triggers

Hoy hablaremos de una de las características más poderosas de JavaFX la cual consiste en el binding entre datos, esto nos brinda la posibilidad de vincular dos variables entre si ya sea por el cambio de valor de una, o por la evaluación de una expresión. Además tenemos la posibilidad de asignar triggers que son bloques de códigos los cuales se ejecutan al cambiar el valor de una variable.

Contenidos

  • Binding Overview
  • Binding and Objects
  • Binding and Functions
  • Binding with Sequences
  • Replace Triggers


Binding Overview
Empezaremos diciendo que para poder realizar el binding entre variables debemos usar la keyword bind, también existe una expresión bound que ahora veremos la cual crea una relación más amplia.

Binding and Objects
Veamos un ejemplo donde creamos un binding entre dos variables.
var x = 0;
def y = bind x;
x = 1;
println(y); // y ahora vale 1
x = 50;
println(y); // y ahora vale 50
Aquí se nota como nosotros solo modificamos los valores de la variable x esto automáticamente se ve reflejado en la variable y.
Ahora veremos un binding parecido pero cuando queremos hacer binding entre objetos.
var myStreet = "1 Main Street";
var myCity = "Santa Clara";
var myState = "CA";
var myZip = "95050";

class Address{
var street;
var city;
var state;
var zip;
}

def address = bind Address {
street: myStreet;
city: myCity;
state: myState;
zip: myZip;
};

println("address.street == {address.street}");
myStreet = "100 Maple Street";
println("address.street == {address.street}");
Aquí definimos la clase Address y luego definimos, 4 variables para iniciar este objeto, al crear nuestro objeto lo hacemos con la palabra bind, esto quiere decir que nuestra variable address siempre tendrá sus atributos actualizado en base a los valores de las variables con cuales fue iniciado.
Si ejecutamos el ejemplo veremos que el resultado es
address.street == 1 Main Street
address.street == 100 Maple Street
Un dato importante que debemos considerar es que con este tipo de binding por cada modificación, se genera un nuevo objeto Address y se asigna nuevamente a la variable.
Otra forma de realizar este binding sin generar un nuevo objeto es de la siguiente manera

var myStreet = "1 Main Street";
var myCity = "Santa Clara";
var myState = "CA";
var myZip = "95050";

class Address{
var street;
var city;
var state;
var zip;
}

def address = Address {
street: bind myStreet;
city: bind myCity;
state: bind myState;
zip: bind myZip;
};

println("address.street == {address.street}");
myStreet = "100 Maple Street";
println("address.street == {address.street}");
La única diferencia es que acá no se hace el bind sobre el objeto sino sobre cada atributo.

Binding and Functions
Aquí es donde entra en juego la keyword bound, no debemos confundir esto con el bind son dos cosas distintas que en combinación nos ofrecen alguna funcionalidad especifica.
Veamos un ejemplo de bind y bound para entender cómo funciona y como usarlo
// Paso 1
var scale = 1.0;

// Paso 2
class Point {
var x : Number;
var y : Number;
}

// Paso 3
bound function makePoint(xPos : Number, yPos : Number) : Point {
Point {
x: xPos * scale
y: yPos * scale
}
}

// Paso 4
var myX = 3.0;
var myY = 3.0;
def pt = bind makePoint(myX, myY);
println(pt.x);

// Paso 5
myX = 10.0;
println(pt.x);

// Paso 6
scale = 2.0;
println(pt.x);
Entendamos este ejemplo paso por paso.
Paso 1:
Aquí definimos una variable del tipo Number y la inicializamos en 1.0

Paso 2:
Definimos la clase Point

Paso 3:
Creamos una función la cual la marcamos con el atributo bound, aquí debemos saber que hay dos tipos de funciones las bound y las not-bound que se comportan de manera distinta si tan con binding sobre una variable.
Las funciones not-bound solo se ejecutan si sus parámetro cambian, en caso contrario las funciones bound siempre se ejecutan

Paso 4:
Creamos las variables las inicializamos y hacemos un bind entre la función y una variable del tipo Point.

Paso 5:
Cambiamos el valor de myX como esta variable fue usada como parámetro de la función con bind se dispara la función y cambia los valores del Point

Paso 6:
Cambiamos el valor de la scale y como esta es una función bound también se vuelve a ejecutar la función y nos cambia los valores de Point
Si ejecutamos el ejemplo el resultado será:
3.0
10.0
20.0
Si sacáramos el bound de la función el resultado sería:
3.0
10.0
10.0

Binding with Sequences
Aquí usaremos un bind entre secuencias pero además usando la expresión for. Tranquilamente podríamos hacer un bind común entre dos secuencias como si fueran variables, pero para ver el poder de esto usaremos una expresión for de la siguiente manera
// Definimos la secuencia 1
var seq1 = [1..10];

// Definimos la secuencia 2, pero con la diferencia que cada ítem será multiplicado por dos
def seq2 = bind for (ítem in seq1) ítem*2;
printSeqs();

function printSeqs() {
println("First Sequence:");
for (i in seq1){println(i);}
println("Second Sequence:");
for (i in seq2){println(i);}
}

Si ejecutamos el ejemplo el resultado será el siguiente:
First Sequence:
1
2
3
4
5
6
7
8
9
10
Second Sequence:
2
4
6
8
10
12
14
16
18
20

Se nota claramente como la secuencia 2 está relacionada con la secuencia 1,pero además aplica una multiplicación sobre cada ítem, para confirmar el bind vamos a insertar un elemento en la secuencia 1 y este debería estar presente en la secuencia 2
// Definimos la secuencia 1
var seq1 = [1..10];

// Definimos la secuencia 2, pero con la diferencia que cada ítem será multiplicado por dos
def seq2 = bind for (ítem in seq1) ítem*2;
insert 11 into seq1;
printSeqs();

function printSeqs() {
println("First Sequence:");
for (i in seq1){println(i);}
println("Second Sequence:");
for (i in seq2){println(i);}
}
Si volvemos a correr el ejemplo veremos que ahora la secuencia 1 tiene el ítem 1 y la secuencia 2 tiene el ítem 22.

Replace Triggers
Se le llama Replace Triggers a bloques de códigos que podemos asignar a las variables para que se ejecuten cuando sus valores cambien. Aquí debemos usar la sentencia on replace para poder definir el bloque de código que queremos ejecutar
var password = "foo" on replace oldValue {
println("\nALERT! Password has changed!");
println("Old Value: {oldValue}");
println("New Value: {password}");
};
password = "bar";
Primero creas la variables password donde la inicializamos con el valor "foo"(Supuestamente -Ahora explicare porque pongo esto-) y usamos la sentencia on replace seguido de un nombre a elección del valor anterior y luego definimos el código a ejecutar. al correr el ejemplo veremos lo siguiente

ALERT! Password has changed!
Old Value:
New Value: foo

ALERT! Password has changed!
Old Value: foo
New Value: bar

Vemos que se ejecuta dos veces ya que la variable en un comienzo esta inicializa en Null por eso nuestra inicialización en "foo" es supuesta.

Bueno con esto daremos por finalizada la introducción a las características de JavaFX en lo que sería la parte de scripting, ahora nos dedicaremos a la parte más visual donde empezaremos a usar todos estos conocimientos.

Saludos

Leer más...

27 julio 2009

Secuencias JavaFX

En esta ocasión hablaremos de las secuencias, estas son una adicción a los tipos básicos de JavaFX, el lenguaje nos provee de una estructura llamada secuencias la cual representa una lista ordenada de objetos (Aunque no sean solamente objetos), cada objeto dentro de la secuencia es llamado ítem. Para declarar una secuencia debemos usar [] y dentro introducir cada ítem separado por comas.

Contenido

  • Creating Sequences
  • Using Predicates
  • Accessing Sequence Items
  • Inserting Items into a Sequence
  • Deleting Items from a Sequence
  • Reversing the Items in a Sequence
  • Comparing Sequences
  • Using Sequences Slices


Creating Sequences
Tenemos varias formas de declarar una secuencia por ejemplo podríamos encerrar los ítem entre [] separados por coma.
def weekDays1 = ["Lunes","Martes"];    // Aquí no definimos el tipo de Dato
def weekDays2: String[] = ["Miercoles","Jueves","Viernes"]; // Aquí informamos el tipo de los Items
Una cualidad importante de las secuencias es que pueden ser construidas en base a otras secuencias, para el ejemplo anterior podríamos hacer realizado la siguiente combinación
// Aquí obtendríamos una secuencia con todos los días
def days = [weekDays1, weekDays2, ["Sabado", "Domingo"]];
println(days) // Print [ Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo ]
tipo de los Items
Aquí en realidad el compilador aplana las secuencias anteriores para generar la nueva secuencia. JavaFX script también nos provee una forma más simple de trabajar con secuencias aritméticas.
Ejemplo
def nums = [1..100];
Esto crearía una secuencia la cual poseería los números del 1 al 100

Using Predicates

Nos referimos a predicados cuando usamos una expresión booleana para generar una nueva secuencia que sea formada por un sub conjunto de la secuencia original.
Ejemplo:
def nums = [1,2,3,4,5];
def numsGreater = nums[n | n > 2];
println(numsGreater); // Esto imprimiría [3, 4, 5]
Aquí estamos creando una nueva secuencia en base a una existente y un predicado, analicemos mejor este ejemplo, para esto desglosáremos la siguiente sentencia
nums[n | n > 2]

nums // Selecciono la secuencia previa
[ // Abro [ para marcar mi predicado
n // Defino la variable n
| // Se encarga de separar la variable del predicado
n // Indico un criterio de filtrado, que sería propiamente el predicado
] // Cierro el predicado

Accessing Sequence Items
Muchas veces nos vemos en la necesidad de acceder a los ítem que están almacenados en nuestras secuencias y para esto podemos usar los indexes de la secuencia.
def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
println(days[0]);
println(days[1]);
println(days[2]);
println(days[3]);
println(days[4]);
println(days[5]);
println(days[6]);
En este caso no habría problemas porque nosotros conocemos la cantidad de ítems, que hay en nuestra secuencia si nosotros quisiéramos conocer la cantidad de ítems que hay deberíamos usar la palabra reservada sizeof
def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
println(sizeof days); // Esto imprimiría el numero 7
Inserting Items into a Sequence
Otra palabra reservada del lenguaje es la palabra insert, esta es usada para lograr insertar elemento en una secuencia. Aquí debemos tener en cuenta un dato que no es menor y es que las secuencias realmente son inmutables(Inmutables quiere decir que después de estar creadas nunca se modifican), entonces nosotros en realidad al insertar un ítem en una secuencia en verdad por debajo se crea una nueva secuencia y se reasigna automáticamente, dando la impresión que modificamos la secuencia existente.
// Inicializamos la secuencia con un solo ítem
var days = ["Lunes"];
// Insertamos dos ítem al final de la secuencia
insert "Martes" into days;
insert "Jueves" into days;
// Insertamos un ítem antes que el ítem de la posición 2
insert "Miercoles" before days[2];
// Insertamos un ítem después que el ítem de la posición 3
insert "Viernes" after days[3];
Si usamos posiciones invalidas no sucede nada y los ítem son insertado al final o al comienzo dependiendo el caso, por ejemplo si insertáramos un ítem after days[24] veríamos que realmente se inserta al final de la secuencia o un ítem before days[-1]
este se inserta al comienzo.

Deleting Items from a Sequence

Como ya hemos insertado ítem también debe existir la posibilidad de borrarlos y esto se puede realizar por medio del keyword delete usando en distintas formas
def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
// Borramos el ítem "Lunes"
delete "Lunes" from days;
// Borramos el ítem de la posición 0
delete days[0];
// Borramos todos los ítem, pero la secuencia sigue siendo útil
delete days;
Esto es muy similar a lo anterior, cabe destacar que si elemento marcado o la posición seleccionada para borrar no existen, no se realiza ninguna acción de borrado.

Reversing the Items in a Sequence

Esta técnica nos permite invertir una secuencia en su totalidad usando tan solo la keyword reverse. Veamos un ejemplo para aclarar esto
// Iniciamos la secuencia con los números del 1 al 5
var nums = [1..5];
// Damos vuelta la secuencia
reverse nums;
// Esto imprime [ 1, 2, 3, 4, 5 ]
println(nums);
// Invertimos la secuencia pero ahora si asignamos su resultado
nums = reverse nums;
// Esto imprime [ 5, 4, 3, 2, 1 ]
println(nums);
El ejemplo de arriba nos muestra como las secuencia no se auto asignan su reverse y en este caso debe ser explicito por el programador, no funciona como los delete o insert donde se hace automáticamente.

Comparing Sequences

Para comparar las secuencias se tienen en cuenta dos puntos, el primero su longitud y el segundo la correspondencia entre sus ítem. Al cumplirse estos dos hitos podemos asegurar que las secuencias son iguales.
// Creamos dos secuencias iguales
def seq1 = [1,2,3,4,5];
def seq2 = [1,2,3,4,5];
// Comparamos y esta comparación retorna true
println (seq1 == seq2);
Ahora insertaremos un ítem a la seq2 para lograr que sea diferente que la otra y poder volver a ejecutar la comparación.
// Creamos dos secuencias iguales
var seq1 = [1,2,3,4,5];
var seq2 = [1,2,3,4,5];
// Insertamos un elemento en la seq
insert 6 into seq2;
// Imprimimos la seq2 para comprobar que cambio
println(seq2);
// Comparamos y esta comparación retorna false
println (seq1 == seq2);
Hasta aquí vimos el caso de igualdad y el caso donde la longitud es mayor, ahora nos queda pendiente ver cuando sus ítems tienen otra posición y esto también genera una desigualdad entre secuencias.
// Creamos dos secuencias iguales
var seq1 = [1,2,3,4,5];
var seq2 = [1,2,3,4,5];
// Insertamos un elemento en la seq
seq2 = reverse seq2;
// Imprimimos la seq2 para comprobar que cambio su orden
println(seq2);
// Comparamos y esta comparación retorna false
println (seq1 == seq2);
Aquí cubrimos los 3 casos de comparación entre secuencias, ahora vallamos al último punto

Using Sequences Slices

Antes proceder a explicar las distintas formas de conseguir un slice, deberíamos entender que es un slice, un slice básicamente consiste en una porción de alguna secuencia en base a un criterio o selección, se podría definir un slice como un subconjunto de la secuencia, un slice es una secuencia.
Podemos definir slice de las siguientes maneras
seq[a..b]
seq[a..<b]
seq[a..]
seq[a..<]

En las definiciones de arriba seq seria la secuencia que queremos obtener un slice y a y b los indexes de comienzo y fin, expliquemos cada uno

seq[a..b]

def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
// La nueva secuencia tendría los ítem "Sabado" y "Domingo"
def weekend = days[5..6];
Esta forma de crear un slice incluye ambos indexes

seq[a..<b]

def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
// La nueva secuencia tendría todos los ítem menos "Sabado" y "Domingo"
def weekdays = days[0..<5];
En este caso solo la primer posición es incluida y el otro no.

seq[a..]
def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
// La nueva secuencia tendría los ítem "Sabado" y "Domingo"
def weekend = days[5..];
Aquí estamos definiendo un slice que comience en la posición 5 y que incluya dicha posición hasta el final de la secuencia inclusive.

seq[a..<]

def days = ["Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado", "Domingo"];
// La nueva secuencia tendría todos los ítem menos el "Domingo"
def days2 = days[0..<];
Este tipo de slice es similar al anterior ya que comienza en la primera posición inclusive y va hasta el final de la secuencia pero sin incluir el último elemento

Hasta aquí hemos analizados las distintas acciones y tipos referido a las secuencias ya en el próximo post estaremos analizando el binding y los trigger en JavaFX, me voy despidiendo y espero el post les sea de utilidad

Saludos

Leer más...