guizans   21-05-2025, 14:38
#1
Hola a todos.

 Vamos a pensar en que tenemos una función que puede recibir tres, dos o un parámetro, y estos son de tipo Float. La función va a realizar una tarea u otra en función de los parámetros recibidos. Y aquí viene la duda. En otros lenguajes, cuando hay parámetros opcionales, los que no reciben valor tienen asignado Null o None. Pero esto no pasa en Gambas. Me quedaría como opción, asignarle el valor de cero, y si este cambia es que ha recibido un parámetro.
Código:
Private Function paseParametros(Optional a As Float = 0, Optional b As Float = 0, Optional c As Float = 0) As Float
 
  'Codigo aqui
 
End

 Hasta aquí funciona. ¿Pero y si uno de los tres parámetros que paso tiene que ser 0 y necesito que ejecute el código? En este caso, esto no me serviria, ya que no es lo mismo cero que Null, ya que el primero es un número y el segundo es valor vacio.

Le he estado dando vueltas y no se me ocurre ningula solución. ¿es una limitación de Gambas? Apuesto a que si.

Un saludo.

¿Por qué la solución te viene a la cabeza después de un rato de haber formulado la pregunta en el foro? Misterios de la vida.

La solución es en vez de usar Float usar Variant, ya que este si admite Null. No es una solución que me guste, ya que al especificar el tipo de parámetro se sabe de antemano el dato a pasar, pero con Variant puede ser cualquier cosa y hasta que se mira el código de la función no se sabe. Algo parecido le ocurre a Python y no pasa nada.

Un saludo.
Última modificación: 21-05-2025, 14:46 por guizans.
omoreno   21-05-2025, 18:18
#2
Hola Guizans.

Intenta con los parámetros de 3 puntos (...)

Código:
Public Function FindX(TableX As String, WhereX As String, ...) As Variant
  '
  Dim Res As Result
  '
  Res = ConnX.Find(TableX, ConnX.Subst(WhereX, ...))
  '
  Return Res
  '
  Catch
    Return Error.Text
  '
End

Luego la llamas pasando la cantidad de parámetros que se requieran.

Saludos.
Última modificación: 21-05-2025, 18:19 por omoreno.
omoreno   21-05-2025, 19:31
#3
Otra forma:

Código:
Public Sub WebButton1_Click()
  Message.Info(SumaX(28.75, 450.50, 450.75))
End
Private Function SumaX(...) As Variant
  '
  Message.Info("Total de Parámetros: " & Param.Count)
  Dim suma As Float
  For Each NumX As Float In Param
    suma += NumX
  Next
  '
  Return suma
  '
  Catch
     Return Error.Text
End

Saludos.
Última modificación: 21-05-2025, 19:36 por omoreno.
guizans   22-05-2025, 11:56
#4
Hola omoreno.

Si, conozco esa forma, pero te enfrentas al mismo problema. El número de parámetros a pasar está entre uno y tres. Y el tipo de dato es Float, eso fijo, con lo cual tu forma también es válida. A lo que me refiero, es que Gambas al declarar una variable numérica le asigna el cero a la variable, mientras que en otros lenguajes, como Java, esa variable e Null, con lo cual en este caso, es más fácil determinar si una variable pasada por parámetro ha sido usada.

Otra cosa que puede resultar útil en ciertos escenarios, tal como hace Java o Python, es aparte de pasar el parámetro, se indica a la variable que se le pasa, y que Gambas no permite. Esto sería un ejemplo:
Código:
pasarParametro(v=0.50, r=0.25)
 aunque cuando estás estás escribiendo, la ayuda que aparece te facilita mucho el trabajo.

Son peculiaridades propias de cada lenguaje, no existe el lenguaje perfecto, aunque Gambas se le aproxima mucho Big Grin 

Un saludo.
Shell   23-05-2025, 11:31
#5
Estoy algo perdido. ¿ Qué dificultad tiene que sea cero uno de los parámetros ?.


Código:
Public Sub Form_Open()

  paseParametros(10.5, 20.0) 'Se pasan 2 parámetros
  Print "---"
  paseParametros(0.0) 'Se pasa un 0
  Print "---"
  paseParametros(1.0, 2.0, 3.0) 'Se pasan 3 parámetros
  Print "---"
  paseParametros() 'No se pasa ningún parámetro

End

Public Sub paseParametros(Optional a As Float = -1, Optional b As Float = -1, Optional c As Float = -1)

  If a = -1 Then
    Print "El parametro " & Quote("a") & " no fue pasado"
  Else
    Print "El parametro " & Quote("a") & " fue pasado. Su valor es: " & Str(a)
  Endif

  If b = -1 Then
    Print "El parametro " & Quote("b") & " no fue pasado"
  Else
    Print "El parametro " & Quote("b") & " fue pasado. Su valor es: " & Str(b)
  Endif

  If c = -1 Then
    Print "El parametro " & Quote("c") & " no fue pasado"
  Else
    Print "El parametro " & Quote("c") & " fue pasado. Su valor es: " & Str(c)
  Endif

End

Saludos

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
guizans   26-05-2025, 22:43
#6
Hola Shell

Estás comitiendo el mismo error, es decir, que estás evaluando que los números pasados tienen que ser enteros positivos, ¿y si es uno de los parámetros que paso es -1?, tú código tampoco funcionaria correctamente. Por eso digo que hay una diferencia entre asignar un valor que se supone que no se va a usar a que la variable por defecto sea None, no es lo mismo.

No os rayeis, no pasa nada, es una simple curiosidad que me surgió a partir de un pequeño ejemplo que vi en Java y me plantee si se podía hacer de la misma forma en Gambas. Este el código que digo:

https://github.com/mouredev/Weekly-Chall...lenge41.kt


Un saludo.
Shell   29-05-2025, 12:19
#7
Bien. Entonces usemos Variant en el tipo de parámetro de la función.

Examina la forma de comprobar los parámetros al comienzo de la función.
Si no son nulos o no son float, ademas necesitas convertir a texto, ya que IsFloat necesita que le pase texto.
Comprueba la salida de la función.

Código:
Public Sub Form_Open()

  Print Ohm()
  Print Ohm(5.0)
  Print Ohm(5.0, 4.0)
  Print Ohm(5.0, Null, 4.0)
  Print Ohm(Null, 5.0, 4.0)
  Print Ohm(5.125, 4.0)
  Print Ohm(5.0, Null, 4.125)
  Print Ohm(Null, 5.0, 4.125)
  Print Ohm(5.0, 0.0)
  Print Ohm(5.0, Null, 0.0)
  Print Ohm(Null, 5.0, 0.0)
  Print Ohm(5.0, 4.0, 3.0)

End

Public Function Ohm(Optional v As Variant, Optional r As Variant, Optional i As Variant) As String

  Dim count As Integer

  ' Si alguno de los valores no es numérico (ni Null), entonces es inválido
  If (Not IsNull(v) And Not IsFloat(CStr(v))) Or (Not IsNull(r) And Not IsFloat(CStr(r))) Or (Not IsNull(i) And Not IsFloat(CStr(i))) Then
    Return "Valores inválidos"
  End If

  ' Si se han dado más de dos parámetros, no se puede calcular ninguno
  If IsFloat(CStr(v)) Then count += 1
  If IsFloat(CStr(r)) Then count += 1
  If IsFloat(CStr(i)) Then count += 1

  'Si no ha dado mínimo dos parámetros no se puede calcular
  If count <> 2 Then Return "Valores inválidos"

  'En caso de haber recibido dos parámetros aplicamos la ley de Ohm
  If IsFloat(CStr(v)) And IsFloat((CStr(r))) Then
    'Evita división por cero
    If CFloat(r) = 0 Then Return "Valores inválidos"
    'Devuelve la intensidad
    Return "I = " & Format$(CFloat(v) / CFloat(r), "0.00")

  Else If IsFloat(CStr(v)) And IsFloat(CStr(i)) Then
    'Evita división por cero
    If CFloat(i) = 0 Then Return "Valores inválidos"
    'Devuelve la resistencia
    Return "R = " & Format$(CFloat(v) / CFloat(i), "0.00")

  Else If IsFloat(CStr(r)) And IsFloat(CStr(i)) Then
    'Devuelve el voltaje
    Return "V = " & Format$(CFloat(r) * CFloat(i), "0.00")
  Else
    Return "Valores inválidos"
  End If

End Function

Salida de la función:

Cita:Valores inválidos
Valores inválidos
I = 1,25
R = 1,25
V = 20,00
I = 1,28
R = 1,21
V = 20,63
Valores inválidos
Valores inválidos
V = 0,00
Valores inválidos

Saludos

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
Grandamakulo   29-05-2025, 13:25
#8
Me «via metel ande naide me llama», pero, ¿y probando con IsNaN, IsNumber, IsBlank etc. según corresponda?

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
Shell   29-05-2025, 14:06
#9
(29-05-2025, 13:25)Grandamakulo escribió: Me «via metel ande naide me llama», pero, ¿y probando con IsNaN, IsNumber, IsBlank etc. según corresponda?

Todo depende de como lo quieras hacer o mejor dicho, que vas a comprobar. 

En el caso IsNumber o IsFloat, los dos esperan una cadena y ya con IsFloat compruebas si la cadena es un Float
IsNumber puede ser entero, real. IsFloat limita que tipo es.

Si gambas no tiene una cosa, hay que buscar algo alternativo. Que no se pueda hacer de la misma manera, claro, normal.
El uso de Variant, admite cualquier tipo de valor. Ya sea un entero, una cadena, real, null.

Que se puede optimizar la función, puede. Se trata más del uso de parámetros opcionales y poder pasar
lo que queramos. Siempre que no nos olvidemos de Null en el caso de que alguno de los parámetros
sea nulo.

IsNan o IsBlank no las he usado, no es algo habitual que use.

Saludos

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
guizans   29-05-2025, 19:27
#10
Hola Shell

Me gusta tú solución, y si, tienes toda la razón, que Gambas no tenga una cosa no quiere decir que no se pueda hacer de otra forma.

Un saludo.
  
Usuarios navegando en este tema: 2 invitado(s)
Powered By MyBB, © 2002-2025 MyBB Group.
Made with by Curves UI.