Archivo

Archivo para la categoría ‘java’

Mi primer 10K: Joe Kleinerman 10K

Sábado, 7 de enero de 2012

Before the race
Mi primer 10K, no estuvo nada mal

Hoy corrí mi primer 10K; Decidí probar una estrategia dado que la distancia a batir es el doble de lo que yo estoy acostumbrado a correr; Comencé lento las 2 primeras millas, un poco más rápido las 2 siguiente y las 2 últimas con todo.

Central Park 6.2 mile loop
Recorrido alrededor de Central Park, 6.2 millas

Sin contar con una ida obligatoria al baño en la cual gaste por lo menos 40 segundos (el baño estaba ocupado) creo que salió bien :-)

Los resultados oficiales:

Last Name

First Name

Sex/
Age

Bib

Team

City

State

Country

Overall
Place
Gender
Place
Age
Place
Net
Time
Pace/
Mile
AG
Time
AG
Gender
Place

AG %

Nunez Zuleta Jose V M38 5735 0 DARIEN CT USA 2416 1701 316 0:55:05 08:54 0:52:51 1843 50.82
 Resultados oficiales

Esta es una de las carreras del 9+1 para tener una entrada garantizada el maratón de NYC, sólo me faltan 8 más :-)

java , , ,

¿Como configurar Netbeans 7.10 beta y JavaFX 2.0 beta en OSX?

Sábado, 15 de octubre de 2011

Es un poco fastidioso, pero una vez que se bajen los binarios y siguiendo las instrucciones (no muy precisas de Oracle) terminé haciendo esto:

Netbeans 1.7.1 (beta) + JavaFX 2.0 (beta)

¡Ahora a jugar! :-)

java, javafx

Hackeando mis datos en NikeRunning.com

Miércoles, 12 de octubre de 2011


Tipos de terreno para todas mis carreras, desde NikeRunning, mostrado con JavaFX

Desde que comencé a correr he utilizado a NikeRunning.com de una u otra manera; Primero comencé con mi Itouch y ahora lo utilizó con el NikeWatch.

Sin embargo, el sitio de Nike es un poco fastidioso; El sitio web está escrito en Flash (lo cual lo hace pesado), tiene gráficos limitados pero lo mas inconveniente es que mis datos están cautivos en el sitio web. Según ellos ya llevan tiempo trabajando en una migración que eliminará Flash:

Hello Everyone,

Thank you all for your feedback.

To let everyone know, we are in the process of revamping our website. We are in transition to move away from flash to HTML. The goal is to be faster and more efficient.

We thank you for your patience as we update our sites. There is not an estimated time of when the transition will be fixed, but I can assure you that I’ve seen parts of the site and it’s looks and feels amazing.

Stay tuned!

Buscando un poco en Google me conseguí conque se puede obtener toda la información de las carreras (siempre y cuando estas esten marcadas como públicas) usando el siguiente URL:

1
http://nikerunning.nike.com/nikeplus/v1/services/widget/get_public_run_list.jsp?userID=IDENTIFICADOR_DE_USUARIO

El archivo resultante está en formato XML.

Pero, ¿y de donde obtenemos el identificador del usuario? Es sencillo, simplemente vaya a nikerunning.nike.com y una vez que entre con su usuario y clave al sitio web haga click sobre una de sus corridas. El URL resultante se verá como esto:

1
http://nikerunning.nike.com/nikeos/p/nikeplus/en_US/plus/#//runs/gps/IDENTIFICADOR_DE_USUARIO/299193444/

En donde IDENTIFICADOR_DE_USUARIO es el número mágico que queremos usar.

Se me ocurrió por ejemplo escribir un pequeño programa en Jython y JavaFX el cual muestra la distribución de tipos de terreno encontrados mientras corrí:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/env jython
# Author: Jose Vicente Nunez Zuleta, josevnz@kodegeek.com
# This script parses the user run data and creates a simple distribtion by terrain types
# See: http://nikerunning.nike.com/nikeos/p/nikeplus/en_EMEA/plus/#//dashboard/
# Nike and Nikeplus/Nike+ are trademarks owned by Nike.
# License: BSD
import sys
from javafx.application import Application
from javafx.collections import FXCollections
from javafx.collections import ObservableList
from javafx.scene import Scene
from javafx.stage import Stage
from javafx.scene.chart import PieChart
from javafx.scene import Group
from com.kodegeek.fitness.nikerun.query import CannedQuery
from com.kodegeek.fitness.nikerun.public import PlusPublicService
 
class TerrainTypesChart(Application):
 
    def __getData__(self):
        args = self.getParameters().getRaw()
        pServ = PlusPublicService(args[0])
        data = pServ.getUserData()
        dp = CannedQuery('string', data)
        return dp.getTypesOfTerrain()
 
    def start(self, stage):
        scene = Scene(Group())
        stage.setTitle("Terrain types found in all races")
        stage.setWidth(500)
        stage.setHeight(500)
 
        count = self.__getData__()
        data = [PieChart.Data(key, value) for (key, value) in count.iteritems()]
        pieChartData = FXCollections.observableArrayList(data)
        chart = PieChart(pieChartData)
        chart.setTitle("Terrain types found")
 
        scene.getRoot().getChildren().add(chart)
        stage.setScene(scene)
        stage.show()
 
if __name__ == "__main__":
        Application.launch(TerrainTypesChart().class, sys.argv[1:])

La clase ‘PlusPublicService’ no es más que un simple cliente GET el cual se baja los datos del sitio de Nike:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
!/usr/bin/env jython
#
# Author: Jose Vicente Nunez Zuleta, josevnz@kodegeek.com
# See: http://nikerunning.nike.com/nikeos/p/nikeplus/en_EMEA/plus/#//dashboard/
# Nike and Nikeplus/Nike+ are trademarks owned by Nike.
# License: BSD
#
from httplib import HTTPConnection, HTTP_PORT
import sys
 
__URL__ = 'nikerunning.nike.com'
__SERVICE__ = '/nikeplus/v1/services/widget/get_public_run_list.jsp?userID='
 
class PlusPublicService:
 
        def __init__(self, userId, port = HTTP_PORT):
                self.service = __SERVICE__ + userId
                self.userId = userId
                self.port = port
 
        def getUserData(self, debug=0):
                data = None
                con = HTTPConnection(__URL__, self.port)
                con.set_debuglevel(debug)
                con.request('GET', self.service)
                response = con.getresponse()
                if response.status == 200:
                        data = response.read()
                else:
                        raise Exception("Error. Status = %s, reason = %s" % (response.status, response.reason))
                con.close()
                return data
 
if __name__ == "__main__":
        argv = sys.argv[1:]
        if len(argv) > 0:
                pServ = PlusPublicService(argv[0])
                print "%s" % pServ.getUserData(8)
        else:
                print "NikeRunning user id is required!"
                sys.exit(192)

Y para procesar mis datos utilizo un poco de XPATH en la clase ‘CannedQuery’ la cual tiene un método el cual se encarga de crear la distribución para los distintos tipos de terreno:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/usr/bin/env jython
# Author: Jose Vicente Nunez Zuleta, josevnz@kodegeek.com
# See: http://nikerunning.nike.com/nikeos/p/nikeplus/en_EMEA/plus/#//dashboard/
# Nike and Nikeplus/Nike+ are trademarks owned by Nike.
# License: BSD
 
from xml.dom.minidom import parse, parseString
from xml.etree import ElementTree
import sys
 
class DataParser(object):
 
        def __init__(self, type='string'):
                self.type = type
 
        def __parseDomFile__(self, file):
                return parse(open(file, 'r'))
 
        def __parseDomString__(self, string):
                return parseString(string)
 
        def __parseXpathFile__(self, file):
                return ElementTree.parse(file)
 
        def __parseXpathString__(self, string):
                return ElementTree.fromstring(string)
 
        def __getDom__(self, source):
                if self.type == 'string':
                        return self.__parseDomString__(source)
                else:
                        return self.__parseDomFile__(source)
 
        def __getTree__(self, source):
                if self.type == 'string':
                        return self.__parseXpathString__(source)
                else:
                        return self.__parseXpathFile__(source)
 
class CannedQuery(DataParser):
 
        def __init__(self, type, source):
                super(CannedQuery, self).__init__(type)
                self.source = source
                self.terrainMap = { '0': 'Not defined', '1': 'Road', '2': 'Trail', '3': 'Treadmill', '4': 'Track' }
 
        def getTypesOfTerrain(self):
                tree = self.__getTree__(self.source)
                count = {}
                for elem in tree.findall(".//terrain"):
                        key = 'Never collected'
                        if elem.text in self.terrainMap:
                                key = self.terrainMap[elem.text]
                        if key in count:
                                count[key] += 1
                        else:
                                count[key] = 1
                return count
 
if __name__ == "__main__":
        argv = sys.argv[1:]
        if len(argv) > 0:
                dp = CannedQuery('file', argv[0])
                count = dp.getTypesOfTerrain()
                print "%s" % count

Pienso abrir un proyecto con todas estas clases de Python (Jython) en unos pocos días. Quiero agregarle un par de cosas más antes de soltarlas al aire libre :-)

internet, java, javafx, kodegeek, vida sana

Jython + JavaFX: Comienzo duro

Domingo, 9 de octubre de 2011

Al fin Oracle liberó su versión final de JavFX en JavaOne 2011; También hay una versión beta para OSX la cual me baje de una vez.

Jugando con los ejemplos me dediqué a experimentar con el ejemplo de un gráfico de torta el cual se ve sencillo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.chart.PieChart;
import javafx.scene.Group;
 
public class PieChartSample extends Application {
 
    @Override public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Imported Fruits");
        stage.setWidth(500);
        stage.setHeight(500);
 
        ObservableList pieChartData =
                FXCollections.observableArrayList(
                new PieChart.Data("Grapefruit", 13),
                new PieChart.Data("Oranges", 25),
                new PieChart.Data("Plums", 10),
                new PieChart.Data("Pears", 22),
                new PieChart.Data("Apples", 30));
        final PieChart chart = new PieChart(pieChartData);
        chart.setTitle("Imported Fruits");
 
        ((Group) scene.getRoot()).getChildren().add(chart);
        stage.setScene(scene);
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

Lo compilamos y corremos:

1
2
3
Macintosh:javafx josevnz$ export CLASSPATH=/Users/Shared/javafx-sdk2.0.2-beta//rt/lib/jfxrt.jar:.
Macintosh:javafx josevnz$ javac PieChartSample.java -d .
Macintosh:javafx josevnz$ java PieChartSample

JavaFX Pie chartJavaFX gráfico de torta en acción

Así que traté de convertir este sencillo código a Jython:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env jython
import sys
from javafx.application import Application
from javafx.collections import FXCollections
from javafx.collections import ObservableList
from javafx.scene import Scene
from javafx.stage import Stage
from javafx.scene.chart import PieChart
from javafx.scene import Group
 
class PieChartSample(Application):
 
    def __init__(self):
        pass
 
    def start(self, stage):
        scene = Scene(Group())
        stage.setTitle("Imported Fruits")
        stage.setWidth(500)
        stage.setHeight(500)
 
        pieChartData = FXCollections.observableArrayList(
                PieChart.Data("Grapefruit", 13),
                PieChart.Data("Oranges", 25),
                PieChart.Data("Plums", 10),
                PieChart.Data("Pears", 22),
                PieChart.Data("Apples", 30))
        chart = PieChart(pieChartData)
        chart.setTitle("Imported Fruits")
 
        scene.getRoot().getChildren().add(chart)
        stage.setScene(scene)
        stage.show()
 
if __name__ == "__main__":
        PieChartSample().launch(sys.argv[1:])

Pero al correrlo me se queja que no estoy extendiendo bien la clase ‘Aplication’ y por eso falla:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Macintosh:javafx josevnz$ ./piechart.py 
*sys-package-mgr*: can't create package cache dir, '/Users/Shared/jython2.5.2/cachedir/packages'
Traceback (most recent call last):
  File "./piechart.py", line 36, in <module>
    PieChartSample().launch(sys.argv[1:])
	at javafx.application.Application.launch(Application.java:186)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
 
java.lang.RuntimeException: java.lang.RuntimeException: Error: class sun.reflect.NativeMethodAccessorImpl is not a subclass of javafx.application.Application
 
</module>

No tengo ni idea en donde esta el error, ¿alguno de ustedes tiene una pista? De verdad me muero de ganas por usar JavaFX con Jython, ya otros han tenido éxito similar con JRuby y Groovy.

Amanecerá y veremos.

Actualización: De la lista de Jython me llegaron muchas sugerencias, al final Weiqi Gao encontró cual era el verdadero problema y esta es la solución:

1
2
3
# The key to happiness in JavaFX + Jython is this:
if __name__ == "__main__":
    Application.launch(PieChartSample().class, sys.argv[1:])

La explicación detallada a continuación:

The trick is with the last line of code that launches the application, which is accomplished with the javafx.application.Application.launch() method. There are two overloaded versions of this method:

1
public static void launch(String[] args);

and

1
public static void launch(Class< ? extends Application> appClass, String[] args);

The first version must be called from a method in a class that extends Application, which is not the case in the above python code. So we have to use the second version.

The idiom for using the first version of launch() in Java is the following:

1
2
3
4
5
6
7
8
9
10
public class Foo extends Application {
    @Override
    public void start(Stage stage) {
      // build the scene graph and show it
    }
 
    public static void main(String[] args) {
      Application.launch(args); 
    }
}

The idiom for using the second version of launch() in Java is the following:

1
2
3
4
5
6
7
8
9
10
11
12
public class Foo extends Application {
  @Override
  public void start(Stage stage) {
    // build the scene graph and show it
  }
}
 
public class Launcher {
  public static void main(String[] args) {
    Application.launch(Foo.class, args);
  }
}

There is an inefficiency in my python code in that I instantiated PieChartSample once only to get its class. I think there is a better way of doing it but can’t think of how at the moment.

java, javafx, python

2011 Komen Greater NYC Race for The Cure

Miércoles, 7 de septiembre de 2011

Bueno, ya dejando atrás la carrera del Yankee Stadium ahora me lanzo con quizas la última carrera de 5 kilómetros de este año para mi.

El recorrido está aquí, es una carrera sin tiempo oficial y por diversión. La idea es colaborar contra el cáncer de seno.

Me estoy recuperando aún de la lesión de la carrera anterior. Sin embargo las medicinas y el calzado han hecho una gran diferencia. No creo que mejore los tiempos (poco tiempo para entrenar, más recuperación), pero al menos espero mantener lo que hice la última carrera.

java

Nueva carrera de 5 kilómetros, ¡esta vez en el Yankee Stadium!

Domingo, 12 de junio de 2011

Amigos y lectores del blog, este 7 de Agosto voy a correr la carrera de 5K en el Yankee Stadium en el estado de New York; Los fondos recolectados van a ser utilizados para estudios de cura contra el Cancer.

Yo estoy recaudando fondos como parte de la carrera, los invito a que donen cualquier cantidad ya que es para una buena causa.

Un abrazo y gracias de antemano,

–José

java , , , , , , ,

¿Como saber el tipo de un archivo? (I)

Sábado, 26 de febrero de 2011

Por alguna razón, este articulo viejo ha tenido algo de tráfico en los últimos días. Me dí cuenta que la idea de usar Java y JNI nunca se materializó, sólo dí unas pistas.

Una forma de hacer esto es llamando a la librería ‘magic’. Magic viene prácticamente en cualquier sistema operativo que se parezca a UNIX que se respete, como BSD, OSX y por supuesto Linux.

Si usted llama a la página man (man 3 libmagic) allí encontrará suficiente información. Por ejemplo, aquí les muestro un pequeño programa que hice en C el cual detecta el tipo de archivo que usted le pase por la línea de comandos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include 
#include 
 
/*
 * Program that shows how to use the magic library to figure out the type of a file
 * @author Jose V Nunez (josevnz@kodegeek.com)
 * License: BSD
 */
int main(int argc, char ** argv) {
 
        if (argc == 1) {
                printf("[ERROR]: Please provide the file name to check and try again!\n");
                return 1;
        }
 
        // See manpage libmagic for details on what this flags mean
        int flags = MAGIC_SYMLINK|MAGIC_COMPRESS|MAGIC_CONTINUE|MAGIC_PRESERVE_ATIME|MAGIC_ERROR;
 
        magic_t cookie = magic_open(flags);
        if (cookie == NULL) {
                printf("There was a problem opening the magic library!\n");
                return 1;
        }
        int status = magic_load(cookie, NULL);
        if (status != 0) {
                printf("Unable to load magic default database!, %s\n", magic_error(cookie));
                magic_close(cookie);
                return 1;
        }
 
        const char * file_details =  magic_file(cookie, argv[1]);
        printf("Type for file: %s is %s\n", argv[1], file_details);
 
        magic_close(cookie);
        return 0;
}

Para compilarlo les dejo un archivo Makefile:

1
2
3
CPPFLAGS += -O2 -L/Users/Shared/lib -I/Users/Shared/include -lmagic
all: magic.c
        $(CC) $(CPPFLAGS) magic.c -o magic

Y finalmente como se corre:

1
2
3
4
5
auyan:c josevnz$ make
cc -O2 -L/Users/Shared/lib -I/Users/Shared/include -lmagic magic.c -o magic
auyan:c josevnz$ ./magic /Users/josevnz/CTX.DAT
Mime type for file: /Users/josevnz/CTX.DAT is Java serialization data, version 5
auyan:c josevnz$

En la siguiente entrada las prometo como hacer esto desde Java (pista, vamos a utilizar JNI).

–José

c, java, mime magic libmagic jni java, opensource, programación , , , , , ,

Book reviews: JavaFX 1.2 Application Development Cookbook

Miércoles, 17 de noviembre de 2010

JavaFX 1.2 Application Development Cookbook is a really nice book; The cookbook title is a little bit misleading as the book is a quick progression over the features of the language and how it can be used to write applications, all done in a very professional y concise manner.

Then why it is difficult to wrote about this book? Well, the first issue is than the latest API (with significant changes) for JavaFX is 1.3 while the book is written for 1.2; There are several performance and stability improvements, new graphic controls so this was definitely an mandatory upgrade for anyone thinking seriously into using the language. But the real deal breaker here is than JavaFX script is being discontinued and instead is being made a proper Java API that can be used by your regular Java developers.

All this will happen on the ‘JavaFX 2.0′ version of the language, sometime next year. Also JavaFX script is not really dead … is reincarnated as an open source platform called Visage.

So if I were you I would wait to see how JavaFX 2.0 looks like instead, no investment in books or coding for the time being. As for Visage, I would rather go for a head to head comparison with other tools like Apache Pivot which is more mature at this point.

The good: The book is a good one, easy to read and with good concrete examples. The price tag is also good.

The bad: Not a problem with the book itself, but the technology is changing to fast and too much, so it doesn’t make sense to invest on this book. Wait until Oracle delivers JavaFX 2.0.

The ugly: Oracle should have pull the plug sooner. JavaFX has lost a lot of momentum and makes you wonder if now it’s real purpose will be to replace an aging Swing on the desktop.

There are great things scheduled for JavaFX, but we will have to wait some more to see them. Perhaps a new version of this book will be more than welcome once the new version is out.

–Jose

java, javafx, oracle, programación , , , ,

JavaFX Script ha muerto, Swing aún sigue en pie

Martes, 21 de septiembre de 2010

Bueno, es un cambio de tono que no esperaba. En JavaOne de este año anunciaron que JavaFX Script está muerto y en va a tener integración desde Swing y otros lenguajes dinámicos.

Las mentadas de madre no se hicieron esperar en Twitter y otros lados el día de hoy. Después de todo son 3 años en los cuales un producto se vuelve a reiniciar (yo me cuento entre quienes perdieron el tiempo leyendo sobre JavaFX). Por otro lado, Java Swing necesita mejoras pronto y quizas esta es la mejor decisión.

Como que alguien en Oracle se dio cuenta que la inversión en Swing de tantos años no se puede botar a la basura, sin embargo queda por verse si vale la pena invertir el tiempo en JavaFX antes de la versión 2.0 (apenas estamos en 1.3, la cual tiene todavía muchos huecos).

¿Quiere más detalles (código)? Aquí tienen una muestra de lo que viene…

java , , , ,

And the winner of the JavaFXpert RIA Exemplar Challenge

Lunes, 20 de septiembre de 2010

La aplicación es una belleza, además de que el código y el problema que resuelve son interesantes. Si agregar más nada
And the winner [of the JavaFXpert RIA Exemplar Challenge]

¡Ah, y tiene código abierto!

java, kodegeek, opensource, oracle, programación ,