Acerca de:

Este blog contiene los códigos, ejemplos y bases de datos que he usado cuando aprendía acerca de algún tema específico. En lugar de borrarlos (una vez dominado ya el tema), he decidido publicarlos :)

viernes, 25 de marzo de 2022

Dibujando arbolitos fractales con la tortuga de Python

Éste fue un pequeño ejercicio para practicar recursividad. La idea es dibujar un arbolito fractal con tres ramitas. Ya antes había revisado el código para dibujar estos árboles, pero quise tener mi propia implementación. Después de un buen rato probando, dibujando en un papel cómo debían salir las ramitas, y dónde debía poner la bifurcación recursiva, terminé con este código:

import turtle as t

def drawit(x, y, angle, lenght, n):
    if n > 0:
        t.penup()
        t.goto(x, y)
        t.pendown()
        t.seth(angle)
        t.forward(lenght)
        cx = t.xcor()
        cy = t.ycor()
        drawit(cx, cy, angle + 30, lenght / 1.3, n-1)
        drawit(cx, cy, angle - 30, lenght / 1.3, n-1)
        drawit(cx, cy, angle, lenght / 1.3, n-1)
    else:
        t.hideturtle()
        return 0


drawit(0, -100, 90, 100, 7)
t.mainloop()


la variable n indica la profundidad hasta la que se dibujarán las ramas, otra forma es dibujar las ramas hasta que llegan a una longitud mínima. Las variables x, y, angle, lenght indican las coordenadas desde dónde se dibujarán las ramas, el ángulo y la longitud respectivamente. La función seth() de la tortuga setea el ángulo en el que se empezará a dibujar. Las funciones xcor() y ycor() capturan las coordenadas actuales de la tortuga.

La tortuga primero dibuja el tronco del árbol en la posición (0, -100) en un ángulo de 90 grados. A continuación se bifurca en tres ramas, cada una dibujando un "tronco" en el ángulo y la longitud indicadas a partir de las coordenadas donde la tortuga terminó de dibujar. Para evitar que se confunda, le ordeno ir a esas coordenadas, antes de empezar a dibujar, con la función goto().

El resultado es:


En esta web también dibujan un árbol fractal, y además le ponen color, voy a usar el mismo truco para colorear mi árbol:

import turtle as t
import math

def drawit(x, y, angle, lenght, n):
    if n > 0:
        t.penup()
        t.goto(x, y)
        t.pendown()
        t.seth(angle)

        t.pensize(math.log(lenght,2)/3)
        if n < 2:
            t.color('forest green')
        else:
            t.color('gray')

        t.forward(lenght)
        cx = t.xcor()
        cy = t.ycor()
        drawit(cx, cy, angle + 30, lenght / 1.3, n-1)
        drawit(cx, cy, angle - 30, lenght / 1.3, n-1)
        drawit(cx, cy, angle, lenght / 1.3, n-1)
    else:
        t.hideturtle()
        return 0


drawit(0, -100, 90, 100, 7)
t.mainloop()

Ahora mi árbol ya no parece muerto:


Luego me encontré con este otro arbolito, cuyo código es muy parecido al mío. En lugar de un contador, usa la longitud de las ramas para ponerle un límite a la profundidad de las recursiones. No fue difícil modificar mi código para dibujar un arbolito curvo, y después de probar un poco noté que en este caso es mejor usar una longitud mínima en lugar de la variable n para detener las recursiones. Al final, mi código es el siguiente:

import turtle as t

def drawit(x, y, angle, lenght, n):
    if lenght > 2:
        t.penup()
        t.goto(x, y)
        t.pendown()
        t.seth(angle)
        t.forward(lenght)
        cx = t.xcor()
        cy = t.ycor()
        drawit(cx, cy, angle + 25, lenght * 0.9, n-1)
        drawit(cx, cy, angle - 90, lenght * 0.45, n-1)
    else:
        t.hideturtle()
        return 0


drawit(200, -200, 90, 100, 10)
t.mainloop()


El resultado es:

Necesita algunos arreglos:

import turtle as t

def drawit(x, y, angle, lenght, n):
    if lenght > 2:
        t.penup()
        t.goto(x, y)

        if lenght < 10:
            t.color('gray')
        else:
            t.color('black')

        t.pensize(lenght/15)
        t.pendown()
        t.seth(angle)
        t.forward(lenght)
        cx = t.xcor()
        cy = t.ycor()
        drawit(cx, cy, angle + 25, lenght * 0.9, n-1)
        drawit(cx, cy, angle - 90, lenght * 0.45, n-1)
    else:
        t.hideturtle()
        return 0


drawit(180, -200, 90, 100, 10)
t.mainloop()


Finalmente queda así:

miércoles, 9 de marzo de 2022

Instalando Glassfish como servicio de Windows (versiones 4.1 y 5)

Estos días han sido días de Glassfish en mi laptop. Jugando con las versiones 4.1 y 5, y rebuscando en internet, encontré que se puede instalar como un servicio de Windows. Como mis Glassfish son todos para pruebas, trasteo, más trasteo y depuración, mi dominio es el que se usa por defecto: domain1. Los puertos son también los que vienen por defecto: 4848 para la consola de administración y 8080 para la conexión http.

Dos buenos tutoriales han sido:

https://www.asesoriaensig.com.mx/instalar-glassfish-4-como-servicio-en-windows-2008/

https://www.luv2code.com/2013/11/13/install-glassfish-4-as-a-windows-service/

Lo que me sucedió es que con el comando asadmin start-domain me inicia el glassfish pero después de un rato tiende a detenerse. Este comando es para pruebas o depuración, no para producción.

Para producción en Windows, el Glassfish debe arrancarse como servicio. Para eso existe este comandito el cual debe ejecutarse como Administrador o pasará lo que se menciona aquí:

asadmin create-service

Lo que no ponen los tutoriales es lo siguiente: tengo un millón de servicios en Windows ¿cómo ubico el de Glassfish? Bueno, en Windows se crea como nombre-del-dominio Glassfish Server:

Lo malo: este servicio funciona, Glassfish 5 se ejecuta en background, pero Windows 10 no lo administra bien, reinicié mi laptop y el servicio estaba detenido así que tuve que iniciarlo de forma manual, además la información de si se está ejecutando o no no se muestra correctamente. Esto no me ocurrió con Glassfsih 4.1 corriendo en Windows Server 2013.

Volviendo a mi Glassfish 5 corriendo en Windows 10, no me permitía depurar webservices en Netbeans apuntando a ese mismo Glassfish 5. Como sólo es un Glassfish de pruebas, lo mejor en este caso es eliminar el servicio.

Deshabilité el servicio, ejecuté el Windows Powershell como administrador e intenté eliminar el servicio de glassfish con el comando:

sc domain1

No se eliminó, luego intenté con el comando:

sc delete "domain1 GlassFish Server"

Y tampoco se eliminó. Busqué en internet que estaba pasando y en dos segundos hallé la solución. El comando es:

sc.exe delete "domain1"

Lo que debe mostrar al ejecutarse es:


Luego se deben borrar los archivos que deja el servicio en esta ruta:

glassfish5\glassfish\domains\domain1\bin

Lo malo es que eliminar el servicio de glassfish no detiene los procesos de glassfish, para esto debemos ir al Task Manager (taskmgr.msc), hacer clic derecho en las cabeceras de las columnas y elegir "Línea de comandos". Luego se deben matar todos los procesos de Java que tengan "glassfish" en algún lado de su línea de comandos:

Suele haber más de uno, hay que matarlos todos. Después de hacer todo esto, ya pude debuggear mis webservices desde Netbeans usando Glassfish 5.

Por otro lado, el ejecutable asadmin está en esta ruta:

C:\glassfish5\glassfish\bin