A modo de despedida

Cómo podrán ver, hace ya más de un año que no publico ningún post. Y la razòn es sencilla; he dejado casi por completo la práctica de la programación. Mantengo el blog online porque veo que aún recibe muchas visitas y por tanto resulta útil a quienes se están iniciando en Gambas. De todas formas, aún respondo las consultas que llegan  y trato de ayudar en la medida de lo posible a quienes lo hacen. Otros intereses me han llevado a centrarme en otras tareas y la programación ya no es, ni cerca, una de mis prioridades.

Gracias a todos los lectores y quienes me han felicitado e incluso a quienes me han criticado. Y sigan adelante con Gambas.

Publicado en programación | 4 comentarios

Mejoras en los reportes condicionales (I)

Comenzando una serie de videos sobre el programa de los reportes condicionales, descubrí que podía optimizar muchísimo el código y reducir la cantidad de sentencias. De 697 líneas en el Fmain original, las reduje a poco más de 500 líneas. ¿Dónde había estado el error?

La esencia del programa había sido convertir las sentencias sql en variables, en principio sólo para los reportes imprimibles.

¿Podía hacerse lo mismo para los reportes por pantalla y usar la misma variable en ambos casos ?

Lo primero fue estudiar las diferencias entre una y otra.Veamos.

Para imprimir:

Public Sub pordirector1()

       Dim filtro As String

       filtro = cbxdirector.Current.text

            hresul = hconn.Exec(“Select * from films where director like ‘” & filtro & “‘”) ‘consulta sql”

              If hresul.Available = False Then ‘comprobar si hay resultado

                valor = “” ‘asignamos a valor un valor null

            Else

               valor = “Select * from films where director like ‘” & filtro & “‘”

           Endif

End

El mismo procedimiento , por pantalla:

Public Sub pordirector()

Dim filtro As String

      cargartabla

      filtro = cbxdirector.Current.text

      hresul = hconn.Exec(“Select * from films where director like ‘” & filtro & “‘”) ‘consulta sql”

         If hresul.Available = False Then

              message(“no hay resultados que coincidan con su búsqueda”)

        Else

       Endif

   mostrar

End

Las diferencias , marcadas en negrita , no eran insalvables. Y lo realmente medular, o sea la sentencia sql, es exactamente igual. Debía encontrar la forma de eliminar una de las dos y debía ser la segunda, ya que no devolvía la sentencia sql como variable sino que la ejecutaba directamente. Lo primero era crear u procedimiento único para lanzar los reportes por pantalla y ejecutar en él todo lo necesario.

Esta fue la solución:

Public Sub mostrar2()

     If valor <> “” Then

        cargartabla

        hresul = hconn.Exec(valor)

        mostrar

     Else

         tabla5.Clear

         Message(“No hay datos que coincidan”)

     Endif

End

Donde primero comprobamos que la sentencia no nos devuelva un valor vacío, lanzamos el exec con el parámetro valor, en caso contrario limpiamos la tabla para borrar búsquedas anteriores y mostramos el mensaje de aviso.

Esta porción de código me permitió eliminar 7 procedimientos casi iguales a sus pares, con el consiguiente ahorro y reutilización de código. Pero hay más.

Habìa una función que devolvìa un valor numèrico entero, para llamar a estos procedimientos en otra función posterior. Repasemos parte del còdigo.

 

Private Function elegir() ‘comprobar que casillas están seleccionadas

If chactor.Value And chactriz.value = False And chdirector.value = False And chtitulo.value = False And chanio.value = False Then
combinacion = 1
Else If
chactor.Value And chactriz.value And chdirector.value = False And chtitulo.value = False And chanio.value = False Then
combinacion = 2………….. etc

………………………………………………………………………………………………………………….

 

Public Sub combinar()
     If combinacion = 1 Then
            poractor
      Else If combinacion = 2 Then
         porambos
Else If combinacion = 3 Then………etc

…………………………………………………………………………………………………………………

Public Sub combinar2()
    If combinacion = 1 Then
            poractor1
    Else If combinacion = 2 Then
           porambos1
   Else If combinacion = 3 Then…………..etc

………………………………………………………………………………………………………………

De estos tres , sólo conservamos el primero, con la diferencia de que en lugar de devolver un número, llama directamente al procedimiento asociado.

Veamos como quedó:

Private Function elegir() ‘comprobar que casillas están seleccionadas

    If chactor.Value And chactriz.value = False And chdirector.value = False And chtitulo.value =         False And chanio.value = False Then
         poractor1
   Else If
     chactor.Value And chactriz.value And chdirector.value = False And chtitulo.value = False And       chanio.value = False Then
          porambos1

y continùa así en los 7 procedientos.

Publicado en programación | Deja un comentario

Los números de 2013

Los duendes de las estadísticas de WordPress.com prepararon un informe sobre el año 2013 de este blog.

Aquí hay un extracto:

La sala de conciertos de la Ópera de Sydney contiene 2.700 personas. Este blog ha sido visto cerca de 22.000 veces en 2013. Si fuera un concierto en el Sydney Opera House, se se necesitarían alrededor de 8 presentaciones con entradas agotadas para que todos lo vean.

Haz click para ver el reporte completo.

Publicado en programación | Deja un comentario

Terminando el juego

Ahora viene la parte más interesante, la que nos va a permitir desarollar el juego es sí.
Debemos analizar cúantas situaciones distintas se pueden dar.
En  python, la operación resto simplificaba mucho las cosas.
Pero al trasladar esto a Gambas, el resultado terminaba siendo caótico.
Había que buscar otro camino. Una estructura de decisión sería lo más adecuado, pero ¿cúantas combinaciones hay?
Si por cada elección del usuario hay 5 posibles de la computadora. Estos nos da 25 combinaciones posibles, de las
cuales sólo 5 marcan empate. Ufff. Nos quedan aún 20 situaciones diferentes.
Primero ,los empates. Esta es la más fácil. Si computadora y jugador eligen la misma opción, no hay ganador.
Sencillo. Con una sentencia condicional if fácilmente solucionamos esto. Pero, y, ¿para los otro 20 casos?
Sería una locura usar veinte sentencias condicionales, una para cada situación. Vamos a simplificar.
Por cada opción elegida por el jugador hay dos a las que vence y dos que lo derrotan.Usemos pues, solo las que vence.
Aún así son 10 condiciones diferentes a analizar. Podemos achicar aún más, agrupando vencedoras por pares, usando los  operadores lógicos, en este caso el and para concatenar sentencias y el or, que nos devuelve True en caso de que cualquiera de las dos condiciones sean verdaderas.
Así reducimos a cinco las condiciones, seis si sumamos la de empate, con lo que reducimos de 25 a sólo seis las condiciones a analizar.
Si es empate,el ciclo se cierra ahí. Si no, se va moviendo por lás demas hasta encontrar una cuya resultado sea True, si nunguna lo es,se
activa la sentencia por defecto, que le da el punto a la computadora. Veamos el código:

Public Sub jugar()

Dim jugador As String

modalidad()

elige()
jugador = ComboBox1.Current.Text
label2.text = jugador
label3.text = compu
If jugador = compu Then
label1.text = “No hay ganador”
Else If
jugador = “Spock” And (compu = “tijera” Or compu = “piedra”) Then
label1.text = “jugador gana”
puntaje_jugador = puntaje_jugador + 1
Else If
jugador = “lagarto” And (compu = “papel” Or compu = “Spock”) Then
label1.text = “jugador gana”
puntaje_jugador = puntaje_jugador + 1
Else If
jugador = “tijera” And (compu = “papel” Or compu = “lagarto”) Then
label1.text = “jugador gana”
puntaje_jugador = puntaje_jugador + 1
Else If
jugador = “piedra” And (compu = “tijera” Or compu = “lagarto”) Then
label1.text = “jugador gana”
puntaje_jugador = puntaje_jugador + 1
Else If
jugador = “papel” And (compu = “piedra” Or compu = “Spock”) Then
label1.text = “jugador gana”
puntaje_jugador = puntaje_jugador + 1
Else
label1.text = “computadora gana”
puntaje_compu = puntaje_compu + 1
End If
Label5.Text = puntaje_jugador
Label7.text = puntaje_compu
If puntaje_compu = puntaje_final Then
Message(“La computadora ha ganado, trata de nuevo”)
btntirada.Enabled = False
ComboBox1.Enabled = False
Else If
puntaje_jugador = puntaje_final Then
Message(“Has ganado,dame la revancha”)
btntirada.Enabled = False
ComboBox1.Enabled = False
Endif

End

Finalmente, comparamos el puntaje de cada uno con el puntaje final, en cuanto uno lo alcance se muestra el mensaje adecuado y
se bloquean el btntirada y el combobox , hasta que el usuario presione nuevo juego.
Se le prodrían agregar más cosas, como guardar cúantas partidas gana cada uno , hacerlo para jugar en red, etc. Pero la
idea de este programa era migrar de un lenguaje a otro (Python a Gambas) y mantener el blog en funcionamiento mientras el
curso de python sigue en curso.  Y hacer algo sencillo a la vez que diferente. Si visitan el foro de Gambas podrán ver el
Balckjakc realizado por un compañero forista, también basado en el desarrollo del curso mencionado en el primer post.
Para terminar, una captura de pantalla del programa en tiempo de diseño y en tiempo de ejecución.

diseño ejecucion

Y como siempre, el enlace al código fuente.
Hasta otro proyecto.

codigo fuente aquí

Publicado en programación | Etiquetado , , , , | Deja un comentario

Agregando procedimientos

Vamos a crear un procedimiento para elegir la modalidad de juego, o sea, a que puntaje hay que llegar para ganar la partida.
10 puntos, 50 o 100 puntos son las opciones elegidas y vamos a usar tres radiobutton.

option

Me parece el control ideal,ya que permite seleccionar solo una opción. Mediante su propiedad value, que es True si está seleccionado, vemos cúal fue seleccionado mediante unqa sentencia condicional del tipo if…else if…else. El código se muestra a continuación y es muy sencillo.

Public Sub modalidad()

If rb10.value Then
puntaje_final = 10
Else If rb50.value
puntaje_final = 50
Else
puntaje_final = 100
Endif

End
Además, vamos a inicializar las variables al comenzar el juego por primera vez, esto lo hacemos en el evento open del formulario.

Public Sub Form_Open()

Label5.Text = 0
Label7.text = 0
Me.center
btntirada.enabled = False

End
Como podemos ver, aparte de mostrar el valor 0 de los puntajes , centra el formulario en pantalla y pone el btntirada bloqueado, para evitar que se presione por accidente, lo que le daría el punto a la computadora. ¿por qué pasa eso? Porque cuando vayamos a las comparaciones para ver quien gana cada tirada,solo vamos a hacer los casos en los que el jugador gana y la opción else o por defecto, le da el punto al pc. Cuando escribamos este procedimiento lo veremos con más claridad.
El botón para el nuevo juego tiene que resetear los puntajes a cero y mostrarlos,y poner disponible el btntirada y el combobox del jugador, ya que en cuanto hay un ganador ambos son bloqueados para evitar tiradas por accidente, lo que podría generar errores en tiempo de ejecución.Veamos se código:
Public Sub btnnuevo_Click()

puntaje_compu = 0
puntaje_jugador = 0
btntirada.Enabled = True
ComboBox1.Enabled = True
Label5.Text = puntaje_jugador
Label7.text = puntaje_compu

End
Más simple aún es el código de evento change del combobox. Habilita el btntirada si no  está y llama al procedimiento jugar que ese el corazón del programa. Este mismo evento será llamado también por el evento click de btntirada, esto nos permite jugar con la opción que tengamos elegida en el combobox, o sea,el botón nos permite repetir nuestra tirada. Veamos ambos.
Public Sub ComboBox1_Change()

btntirada.enabled = True
jugar()

End

Public Sub btntirada_Click()

jugar()

End
Bien, en el próximo post mostraremos el procedimiento jugar y subiremos el código fuente.

Publicado en programación | Etiquetado , , , , | 1 Comentario

Un nuevo proyecto – Piedra, papel, tijera, lagarto, Spock

Bien, vamos a comenzar hoy un nuevo proyecto. Se trata de una versión ampliada del famoso piedra, papel y tijera, que todos hemos usado alguna vez. La lògica original es muy simple.El papel cubre la roca, la tijera corta el papel y la roca rompe la tijera. Aquì, al haber cinco posibles elecciones, es un poco màs complejo, pero no tanto. Vamos a auxiliarnos de siguiente esquema:
PPTLS

Como podemos ver, cada uno vence a los dos que tiene en sentido inverso a las agujas del reloj y le gana a los dos que tiene en sentido directo.Resumiendo,èstas son las posibles situaciones:
1-Tijera corta papel
2-Papel cubre piedra
3-Piedra mata lagarto
4-Lagarto envenena Spock
5-Spock rompe tijeras
6-Tijera decapita lagarto
7-Lagarto come papel
8-Papel desaprueba Spock
9-Spock vaporiza la piedra

Este proyecto forma parte del curso de Python que brinda coursera(https://www.coursera.org/course/interactivepython) y es una implementación en Gambas del mismo, y si bien se basa en las mismas reglas, la implementación es absolutamente distinta. Incluso en el curso, al ser el primer proyecto carece de interactividad y puntaje. O sea, que tomando como base su explicación, tomada casi en forma literal, vamos a arrancarlo en nuestro ide de manera independiente.
Para empezar, deberemos crear un procedimiento que en forma aleatoria realizará la elección por parte del PC. Y como esas variables las vamos a usar en todo el formulario, que además será el único, vamos a declararlas como private al principio del formulario para poder usarla en todos los procedimientos y funciones del mismo.

Private piedra As String
Private papel As String
Private tijera As String
Private lagarto As String
Private Spock As String
Private compu As String
Private n As Integer

Y este es el primer procedimiento a crear:

Public Sub elige()

n = Rnd(1, 6)
If n = 1 Then
compu = “Spock”
Else If n = 2 Then
compu = “lagarto”
Else If n = 3 Then
compu = “tijera”
Else If n = 4 Then
compu = “piedra”
Else If n = 5
compu = “papel”
End If

End

Donde n=Rnd nos elige al azar un número entre uno y cinco, y luego mientra una serie de condicionales if…then, else if…then, else….then, end if,asignamos a la variable compu la cadena correspondiente según el número sorteado.

Hasta el próximo post.

Publicado en programación | Etiquetado , , , | Deja un comentario

Terminemos el programa

Vamos ahora a ver el nuevo aspecto de fadmin , al que vamos a agregar un componente nuevo: el ToglleButtom. La diferencia que el botón común es que una vez presionado, se mantiene en ese estado. Y esto nos va a permitir usar el mismo botón para dos cosas diferentes.

fadmin

El nuevo aspecto de Fadmin

El botón seleccionado en la imagen es el nuevo, al que hemos llamado tgbadmin. Mediante su propiedad value vamos a hacer que nos cargue los usuarios o los materiales. Mediante el botón encima suyo llamamos al formulario para agregar usuarios visto en el post pasado. Veamos el código del procedimiento click de  tgbadmin:

Public Sub tgbadmin_Click()

If tgbadmin.value = True Then
tgbadmin.text = “Administrar materiales”
DataSource1.Table = “usuarios”
DataBrowser1.Enabled = True
Message(“No modifique contraseñas desde aqui. Puede cambiar tipo de usuario o eliminar usuarios. Si desea modificar la contraseña elimine y vuelva a crear el usuario “)
Else
tgbadmin.text = “Administrar usuarios”
DataSource1.Table = “materiales”
DataBrowser1.Enabled = True
Endif

End

Como vemos, según su propiedad value sea false o true carga una o otra tabla, y modifica a su vez su propio texto. Cuando la tabla cargada es usuarios el texto dice administrar usuarios y cuando es usuarios dice administrar materiales.

También es muy importante el mensaje resaltado en azul, ya que si modificamos la contraseña desde aquí , no será encriptada y nos dará error al introducirla. El evento open del formulario deberá ser modificado para que cargue por defecto la tabla materiales. Así queda el código:

Public Sub Form_Open()
Dim usuario As String     ‘inicializar variable
usuario = FMain.txtuser.text   ‘asignarle un valor
Me.Center
Me.Caption = “Administrador” & ” :  ” & usuario
hconn = Modcon.ConectarBase()        ‘conectamos a la base
DataSource1.Table = “materiales”
DataBrowser1.Enabled = True
tgbadmin.text = “Administrar usuarios”
End

Hasta aquí este programa. Adjunto el código fuente completo. Puedes descargarlo desde aquí

Publicado en programación | Etiquetado , , , , | Deja un comentario