Archivo

Archivo para la categoría ‘python’

¿Cuanto esfuerzo poner al correr? Usando un monitor de pulsaciones

Domingo, 25 de diciembre de 2011

Primero que todo, ¡Feliz navidad!. Hoy me dieron de regalo un monitor de pulsaciones (Polar Link, compatible con Nike GPS awatch), la idea es mantener mis niveles de esfuerzo constantes y en niveles seguros.

Así que hoy me decidí a probarlo con una carrera corta de sólo dos millas, ni tan rápido ni tan lento; La configuración del dispositivo fué trivial y aunque se sintió raro tener una cinta en el pecho durante los primeros 5 minutos luego la sensación se disipó y pude olvidarme por completo que el aparato estaba allí.

La teoría sobre cuales rangos son seguros la pueden encontrar en este enlace, pero si usted es un corcho como yo ya seguro tiene un script para hacer las conversiones:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env python
# Heart rate range calculator, for both aerobic and anaerobic ranges
# http://kodegeek.com/blog
# http://www.livestrong.com/article/179970-a-healthy-heart-rate-while-running/
def heartRate(age, anaerobic=False):
        maxHearthRate = 220 - age
        bound = []
        if not anaerobic:
                bound.append(0.50 * maxHearthRate)
                bound.append(0.85 * maxHearthRate)
 
        else:
                bound.append(0.80 * maxHearthRate)
                bound.append(0.90 * maxHearthRate)
        return bound
 
if __name__ == "__main__":
        import sys
        args = sys.argv[1:]
        if len(args) == 2:
                res = heartRate(int(args[0]), {'true': True, 'false': False}.get(args[1].lower()))
                print "%s,  %s " % (res[0], res[1])

Por ejemplo, para alguien de mi edad estos deberian ser los rangos aeróbicos y anaeróbicos:

1
2
3
4
5
6
 
Macintosh:python josevnz$ python com/kodegeek/fitness/heartrate.py 38 false
91.0,  154.7 
Macintosh:python josevnz$ python com/kodegeek/fitness/heartrate.py 38 true
145.6,  163.8 
Macintosh:python josevnz$

Según el monitor, en promedio mis pulsaciones promedio estuvieron en 165, solamente estuve un %38 del tiempo dentro de mi rango aeróbico. Muy alto, al menos que este leyendo algo mal. Ahora me sale hacer mi tarea :-)

kodegeek, python, 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

Es el tiempo de recuperación, idiota

Jueves, 29 de septiembre de 2011

O algo así es como dice el articulo que apareció en la revista del mes de Octubre del 2011 ‘Running Times’, del atleta y escritor Peter Magil;. Allí el nos muestra como calcular cuanto descansar después de un entrenamiento usando las tablas creadas por el científico Tom Schwarts.

Mi implementación en Python a continuación:

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
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/env python
# Calculate days of recovery after a race. Based on the article appeared on the Running times magazine 
# "It's the Recovery Stupid" by Pete Magill, using Tom Schwartz tables
# author: josevnz@kodegeek.com
# http://kodegeek.com/blog
import sys
 
class Recovery:
 
        def __init__(self):
                self.__ages = { '20':0, '30':1, '40':2, '50':3, '60':4, '70':5, '80':6 }
                self.__fitnessLevel = { 'LOW':0, 'MEDIUM':1, 'HIGH':2 }
                self.__daysBetweenWorkouts = [
                        [ 4.0, 3.0, 2.5 ],
                        [ 5.0, 4.0, 3.0 ],
                        [ 6.0, 4.5, 3.5 ],
                        [ 7.0, 5.0, 4.0 ],
                        [ 7.5, 6.0, 4.5 ],
                        [ 8.0, 6.5, 5.0 ],
                        [ 9.0, 7.0, 5.5 ]
                ]
                self.__races = { '5K':0, '8K':1, '10K':2, '15K':3, '1/2 Mar':4, 'Mar':5 }
                self.__intensityWorkout = { 'EASY':0, 'MEDIUM':1, 'HARD':2 }
                self.__recoveryDaysAfterRace = [
                        [ 2, 3, 5 ],
                        [ 3, 5, 8 ],
                        [ 3.5, 6, 9 ],
                        [ 4, 7, 11 ],
                        [ 5.5, 9, 14 ],
                        [ 9, 17, 26 ]
                ]
                self.__adjustment = { '20':1.0, '30':1.1, '40':1.2 , '50':1.3, '60':1.4, '70':1.5, '80':1.6 }
 
        def getAgeBracket(self, age):
                try:
                        dAge = int(age)
                        if dAge < 0:
                                raise Exception("Invalid age value: %s" % age)
                        for bracket in [ 20, 30, 40, 40, 50, 70, 80 ]:
                                if dAge >= bracket and dAge < = (bracket + 9):
                                        return str(bracket)
                        # > 80 years
                        return 80
                except (Exception), exp:
                        raise Exception("Invalid age: %s" % age)
 
        def getDaysBetweenWorkouts(self, age, level):
                try:
                        bracket = self.getAgeBracket(age)
                        dBracket = self.__ages[bracket]
                        intensity = self.__fitnessLevel[level]
                        return self.__daysBetweenWorkouts[dBracket][intensity] * self.__adjustment[bracket]
                except (Exception), exp:
                        raise Exception("Invalid age or level: age=%s, level=%s" % (age, level))
 
        def getDaysAfterRace(self, age, race, level):
                try:
                        bracket = self.getAgeBracket(age)
                        dBracket = self.__races[race]
                        intensity = self.__intensityWorkout[level]
                        return self.__recoveryDaysAfterRace[dBracket][intensity] * self.__adjustment[bracket]
                except (Exception), exp:
                        raise Exception("Invalid age race type or level: age=%s, race=%s, level=%s" % (age, race, level))
 
if __name__ == "__main__":
        recovery = Recovery()
        arg = sys.argv[1:]
        days = 0
        if len(arg) == 2:
                days = recovery.getDaysBetweenWorkouts(arg[0], arg[1])
                print "Days: %2.2f, for age: '%s' and level: '%s'" % (days, arg[0], arg[1])
        elif len(arg) == 3:
                days = recovery.getDaysAfterRace(arg[0], arg[1], arg[2])
                print "Days: %2.2f, for age: '%s' and level: '%s', race=%s" % (days, arg[0], arg[2], arg[1])
        else:
                sys.exit(192)
 
# "com/kodegeek/fitness/recoveryrun.py" 76L, 2539C written

Así que por ejemplo, si corremos una carrera de 5K con todo y tenemos 35 años de edad:

1
2
3
Macintosh:python josevnz$ ./com/kodegeek/fitness/recoveryrun.py 35 5K HARD
Days: 5.50, for age: '35' and level: 'HARD', race=5K
Macintosh:python josevnz$

¿Y si no es una carrera, pero un entrenamiento fuerte y soy medianamente resistente?

1
2
3
Macintosh:python josevnz$ ./com/kodegeek/fitness/recoveryrun.py 35 MEDIUM
Days: 4.40, for age: '35' and level: 'MEDIUM'
Macintosh:python josevnz$

Por cierto, hoy es mi día de descanso entre entrenamientos. Así que es hora de ejercitar el lado Geek un poquito. Estoy pensando en abrir un nuevo proyecto de código abierto para ir dejando estos pedazos de código relacionados con correr y ejercicios de resistencia. ¿Les suena buena idea?

Bueno, hasta la próxima entrega.

–José

kodegeek, python, vida sana

¿Corriendo muy rápido al principio de una carrera? No necesariamente

Martes, 12 de julio de 2011

Franela Vino Tinto 2011 - Edición Copa America
En plena Copa America, y yo ahora corriendo luciendo los colores de la Vino Tinto.

En preparación para mi carrera en el Yankee Stadium, me conseguí un excelente articulo en el sitio web de RunnersWorld, el cual explica que tan rápido hay que ir en la primera milla para tener una ventaja más que decente, sin quemarse después en el resto de la carrera. Esto se aplica para carreras de 5 kilómetros, el código es muy fácil de seguir:

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
#!/usr/bin/env python
# author: josevnz@kodegeek.com
# http://kodegeek.com/blog
import re
import sys
 
'''
Formula taken from:
http://www.runnersworld.com/article/0,7120,s6-238-244--11404-2-1-2,00.html"To
figure your 6 percent faster first mile: First convert your best 5-K
time to all seconds by multiplying the minutes by 60 and adding the
seconds. Say, you've run 24:19. That would be 24 x 60, + 19 = 1459.
Now divide this total by 3.1 (miles in 5-K) to get your average mile
time in seconds (1459/3.1 = 470.6, or about 7:51 pace). Next multiply
this figure by .94 to get a figure that's 6 percent faster (470.6 x
.94 = 4
42.36). Now divide by 60 to return the figure to minutes:seconds
(442.36/60 = 7:22). So you should aim to run your first mile in 7:22.
Good l
uck!"
'''
def calc_time(time):
       if len(time) == 0:
           return None
       if len(time[0]) > 0:
               m = re.search('(\d+):(\d+)', time[0])
               min = m.group(1)
               sec = m.group(2)
               if len(min) > 0 and len(sec) > 0:
                       secs = (int(min) * 60.0) + int(sec)
                       secs /= 3.1
                       secs *= 0.94
                       mins = secs / 60.0
                       n = re.search('(\d+)\.(\d+)', str(mins))
                       realsecs = "0." + n.group(2)
                       realsecs = round(float(realsecs) * 60)
                       return str(int(mins)) + ":" + str(int(realsecs))
       return None
 
 
if __name__ == "__main__":
       secs = calc_time(sys.argv[1:])
       print "Pace for first mile in 5K: %s" % secs

Por ejemplo, si usted hizo 22:30 en su última carrera (Bueno, eso lo hice yo :-) ):

Macintosh:python josevnz$ ./fastmile5k.py 22:30
Pace for first mile in 5K: 6:49
Macintosh:python josevnz$

¿Qué piensa usted, correr rápido al principio o ir lento y explotar gradualmente?

programación, python, vida sana

¿Como calcular cuantas calorias al día se deben consumir, usando Python?

Lunes, 30 de mayo de 2011

Está bien, es una excusa barata para usar Python para calcular una formula trivial :-) . Sin embargo la idea es útil:

  • Usted quiere saber cuantas calorías debe consumir al día para mantener un peso saludable
  • Sigue la proporción 40/ 30 / 30: %40 de proteínas, %30 de hidratos de carbono y %30 de grasas
  • Usted come 6 veces al día, para mantener su metabolismo activo

Por ejemplo, la salida del programa para una persona que pesa 196 libras:

1
2
3
4
5
Macintosh:python josevnz$ ./calories.py 
Please provide your weight in LB:
196
Daily calories for 196 lb: 2640. Grams of Protein: 44/264, Grams of Carbs: 33/198, Grams of Fat: 14/88
Macintosh:python josevnz$

programa que llama a la clase en Python:

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/env python
# Author: josevnz at kodegeek dot com
# http://kodegeek.com/blog
 
from sys import stdin
from com.kodegeek.fitness.nutrition import CalorieNeeds
 
if __name__ == "__main__":
        print "Please provide your weight in LB:"
        weight = int(stdin.readline())
        c = CalorieNeeds(weight)
        print "%s" % c

Y la clase en Python que hace el trabajo ‘pesado’:

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
#!/usr/bin/env python
class CalorieNeeds:
        """Simple class to determine the daily calorie intake. josevnz at kodegeek dot com"""
 
        def __init__(self, weight):
 
                self.weight = weight
 
                # Calculate daily calorie needs
                self.calorieIntake = (self.weight * 15) - 300
 
                # Calculate the 40/30/30 macronutriend breakdown
                # Proteins
                self.proteinsGramsDay = (self.calorieIntake * 0.40) / 4
                self.proteinsGramsPerMeal = self.proteinsGramsDay / 6
 
                # Carbs
                self.carbGramsDay = (self.calorieIntake * 0.30) / 4
                self.carbGramsPerMeal = self.carbGramsDay / 6
 
                # Fat
                self.fatGramsDay = (self.calorieIntake * 0.30) / 9
                self.fatGramsPerMeal = self.fatGramsDay / 6
 
        def __str__(self):
                return "Daily calories for %s lb: %d. Grams of Protein: %d/%d, Grams of Carbs: %d/%d, Grams of Fat: %d/%d" % (self.weight, self.calorieIntake, self.proteinsGramsPerMeal, self.proteinsGramsDay, self.carbGramsPerMeal, self.carbGramsDay, self.fatGramsPerMeal, self.fatGramsDay)
 
if __name__ == "__main__":
        """Self test code"""
        c = CalorieNeeds(158)
        print "%s" % c

Les dejo como ejercicio como convertir estos resultados a kilogramos, hoy tengo algo de pereza (el enlace para bajarse el código está aquí) :-)

–José

kodegeek, python, vida sana