https://foro.gambas-es.org/viewtopic.php?f=1&t=4670
-----------------------------------
Shell
Miercoles, 03 Junio 2015, 21:44

¿ Fallo Del Operador Ternario IIF ?
-----------------------------------
Hola!.

He estado haciendo un ejemplo y me es imposible hacerlo con IIF. Entiende Verdadero cuando debería ser Falso.

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  Dim apalabras As String[] = ["agua", "fuego", "aire", "aire"]
  Dim cpalabras As New Collection
    
  Get(cpalabras, apalabras)
 
 Stop
 
   
End

Public Sub Get(cdiccionario As Collection, atemp As String[]) As Collection
  
  Dim palabra As String
  
  For Each palabra In atemp 
    'No funciona
    cdiccionario[palabra] = IIf(cdiccionario.Exist(palabra), sumar(cdiccionario, palabra), 1)      
    ' 'Si funciona
    ' If cdiccionario.Exist(palabra) Then 
    '   cdiccionario[palabra] = sumar(cdiccionario, palabra)
    ' Else
    '   cdiccionario[palabra] = 1
    ' Endif    
  Next
  
  Return cdiccionario
  
End


Public Function sumar(ctmpcoleccion As Collection, llave As String) As Integer
      
  ctmpcoleccion[llave] += 1
  
  Return ctmpcoleccion[llave]
  
End
[/code]

El efecto que hace es ir directamente a sumar cuando aun no existe la clave.
El error es:

"No coinciden los tipos, requerido Numérico, obtenido Null"

Con el grupo de sentencias if, else no hay problemas.  :???: 

Os subo el ejemplo.


-----------------------------------
shordi
Jueves, 04 Junio 2015, 11:01

Re: ¿ Fallo Del Operador Ternario IFF ?
-----------------------------------
Sin entrar a evaluar el código directamente, ojo con Gambas que a veces es engañoso con eso de la evaluación de expresiones.

Por ejemplo: Si una función que busca, como exist, devuelve cierto no hay que olvidar que está devolviendo -1 y si es falso 0. Si una función que busca, como instring, devuelve la posición de una subcadena, devolverá -1 si es que no encuentra nada, o sea "cierto". Si está en la primera posición, 0, o sea falso, si está más adelante devolverá su posición... pero no olvides que preguntar por cierto o falso en una cadena, por ejemplo, es lo mismo que si está llena o vacía, y en un número si su valor es distinto de 0, etc.

Por eso el uso de iif es algo que debe uno cuidar muy bien, porque luego pasa lo que pasa.

Saludos.


-----------------------------------
Shell
Jueves, 04 Junio 2015, 19:25

Re: ¿ Fallo Del Operador Ternario IFF ?
-----------------------------------
[quote user="shordi" post="26837"]Sin entrar a evaluar el código directamente, ojo con Gambas que a veces es engañoso con eso de la evaluación de expresiones.[/quote]

Me has dejado a cuadros.  :shock: 

[quote]
Por ejemplo: Si una función que busca, como exist, devuelve cierto no hay que olvidar que está devolviendo -1 y si es falso 0.
[/quote]

Según la instrucción devuelve un tipo Boolean.¿ Puedes explicar lo de True = -1 ?. No es lo que hemos aprendido. 

[quote]
Si una función que busca, como instring, devuelve la posición de una subcadena, devolverá -1 si es que no encuentra nada, o sea "cierto". Si está en la primera posición, 0, o sea falso,
[/quote]

Pues me temo que ahora la función InStr la han cambiado y ahora si no encuentra nada, devuelve 0..pero si siempre fue -1!. :???: 

El primer elemento de la cadena es 1, no es 0. No es como en los indices de un array. 
Pues lo encuentro confuso, si lo explicases con algún ejemplo, lo entenderemos mejor.   ;-) 
Entonces ya te has encontrado este problema alguna vez.

En cambio en este ejemplo si funciona. La colección tiene valores cuando la creamos, no esta vacía.
En este caso, la clave que se esta buscando no existe y se le asigna un valor por defecto a la clave buscada.

Estoy tratando de implementar el método Get de Python en los diccionarios (colecciones en Gambas).
En Python no existe una instrucción como Select Case y una posibilidad es con la ayuda de los diccionarios (colecciones)

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  Dim elecciones As Collection = ["uno": "primero", "dos": "segundo", "tres": "tercero"]
  
  Get(elecciones, "cuatro")
  Mostrar(elecciones)
  
End

Public Sub Get(diccionario As Collection, clave As String) As Collection
  
  Dim valordefecto As String = "otro"
  
  diccionario[clave] = IIf(diccionario.Exist(clave), diccionario[clave], valordefecto)
  Return diccionario
  
End

Public Sub Mostrar(diccionario As Collection)
  
  Dim elemento As String
  
  For Each elemento In diccionario
    Print "LLave: " & diccionario.Key, "Valor: " & elemento
  Next
  
End
[/code]

Salida:
[quote]
LLave: uno	Valor: primero
LLave: dos	Valor: segundo
LLave: tres	Valor: tercero
LLave: cuatro	Valor: otro
[/quote]

Ejemplo en Python:

En este caso solo lo muestra, no se está asignando al diccionario la nueva clave y el valor.

[code linenumbers=false syntax=python]
#!/usr/bin/python3


def main():
    elecciones = dict(
        one = 'first',
        two = 'second',
        three = 'third',
        four = 'fourth',
        five = 'fifth'
        )
    v = 'seven'
    # Podemos usar el metodo get del diccionario para que en caso
    # de que no exista la llave, devuelva un valor por defecto
    print (elecciones.get(v,'other'))
 
        
if __name__=="__main__": main()
[/code]

Saludos


-----------------------------------
shordi
Jueves, 04 Junio 2015, 19:46

Re: ¿ Fallo Del Operador Ternario IFF ?
-----------------------------------
Lo de Instring me pasa por escribir de memoria...  :mryellow:  :mryellow:  :oops: 

cito de la gambaswiki

[quote]This native datatype represents a boolean value.
The value of a boolean can be either TRUE or FALSE.
When converting a boolean to a numeric value, TRUE becomes -1 and FALSE becomes 0.
[/quote]


-----------------------------------
Shell
Jueves, 04 Junio 2015, 21:00

Re: ¿ Fallo Del Operador Ternario IFF ?
-----------------------------------
Referente a la conversión. Cuando se convierte del tipo números a booleanos.
Primero fui al libro que tengo de Python, que creo que se asemeja la misma idea a la de Gambas.

Con números:
Si entendemos el 0 como Falso. Al hacer:

[code linenumbers=false syntax=gambas]
Print Not 0
[/code]

Obtenemos -1 , True. Lo que tu dices.
En cambio hay una diferencia entre Gambas y Python si hago esto:

En Python:

[code linenumbers=false syntax=python]
print not 0
[/code]

Se obtiene False

En cambio en Gambas si se hace:
[code linenumbers=false syntax=gambas]
Print Not 1
[/code]

Se obtiene -2 !  WTF. :o 

[quote]
En Python se convierte el tipo Integer a Float cuando los enteros son usados en expresiones envueltas en números de coma flotante.
Tanto números y cadenas pueden ser usados con operadores booleanos. Python trata el 0 y 0.0 como Falso y todos los números como Verdadero.
[/quote]

Así que
[code linenumbers=false syntax=python]
print not 34.2
[/code]

Nos da Falso.

En Gambas no funcionan los operadores booleanos con el tipo float, aunque admita números.

Si hacemos en Gambas:
[code linenumbers=false syntax=gambas]
Print Not -87
[/code]
Obtenemos 86

Ahora usemos cadenas. En Python, una cadena vacía es tratada como Falso y el resto de cadenas son tratadas como True.
Así al hacer:

[code linenumbers=false syntax=python]
print not ''
[/code]
Obtenemos True

En Gambas es igual.

Nota final.  En general se debería usar solo operadores booleanos con valores booleanos.

Saludos


-----------------------------------
Shell
Viernes, 05 Junio 2015, 09:00

Re: ¿ Fallo Del Operador Ternario IFF ?
-----------------------------------
http://gambaswiki.org/wiki/lang/not?l=es

Que ganas de complicarse.

Ejemplo NOT 5

5 = 0101

Aplicamos NOT 0101

Cambiamos los unos por ceros o viceversa. No olvidaros de poner el 1 de la izquierda, el de mayor peso, gordo, pero gordo.

11010

2e1 + 2e3 = 10

El ultimo 1 por la izquierda es 2 elevado a 4 = 16

10 - 16 = -6

Ale, olvidarse de operar en decimal, lo divertido es hacerlo en binario. Acabareis en cama soñando con unos y ceros..me acordare bien.
Que manera de desvariar.

[url=http://platea.pntic.mec.es/~lgonzale/tic/binarios/aritmetica.html]Aritmértca binaria.

Saludos


-----------------------------------
Shell
Sabado, 06 Junio 2015, 00:24

Re: ¿ Fallo Del Operador Ternario IIF ?
-----------------------------------
Hola!.

IIF comprueba las dos condiciones y puede que ejecute hasta las dos funciones que tengamos en caso de verdadero o falso.
Como sabemos en una colección una clave que no tiene asociado un valor , devuelve  nulo.
Como se esta intentando añadir un valor a una clave que no existe, devuelve nulo.

En caso de nulo debemos salir de la función. Entonces IIF asignara 1 como valor a la clave "palabra".

[code linenumbers=false syntax=gambas]
Public Function Get(cdiccionario As Collection, atemp As String[]) As Collection
  
  Dim palabra As String  
  
  For Each palabra In atemp 
    cdiccionario[palabra] = IIf(cdiccionario.Exist(palabra), sumar(cdiccionario, palabra), 1)         
  Next
  
  Return cdiccionario
  
End

Public Function sumar(ctmpcoleccion As Collection, llave As String) As Integer
  
  'Si no existe un valor asociado a la llave salir de la función
  If ctmpcoleccion[llave] = Null Then Return
  ctmpcoleccion[llave] += 1  
  Return ctmpcoleccion[llave]
  
End
[/code]

Ahora fijaros en este código, ambas funciones si vamos paso a paso, veremos que se ejecutan las dos. Aunque devuelva lo que le corresponde.

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  Dim valor As Integer
  Dim resultado As String
  
  valor = 10
  
  resultado = IIf(valor = 10, EsValor(valor), NoEsValor(valor))
  Print resultado
  
End

Public Function EsValor(num As Integer) As String
  
  Return "La variable valor contiene  " & num  
  
End

Public Function NoEsValor(num As Integer) As String
  
  Return "La variable Valor no contiene  " & num 
  
End
[/code]

Si queremos conocer más sobre el operador IIF y sus posibles Pros y Contras, visitar:

[url=http://en.wikipedia.org/wiki/IIf]Operador IIF


Saludos


-----------------------------------
shordi
Sabado, 06 Junio 2015, 06:28

Re: ¿ Fallo Del Operador Ternario IIF ?
-----------------------------------
Claro que ejecuta las dos, ¿Cómo va a saber entonces si es cierta o falsa?
Tal vez te extrañe que, si la primera es cierta...¿Para qué continuar evaluando la segunda? 
Repuesta: Gambas es así.
En otros compiladores existía la optimización en las evaluaciones y la evaluación se interrumpía una vez que era manifiestamente cierta o falsa. 
En Gambas no y es un problema con los nulos.
Si tienes una clase, variable, lo que sea y preguntas algo así:
[code linenumbers=false syntax=gambas]
if mivariable=0 or isnull(mivariable) then [/code]

Obtendrás un error en la primera comparación "expecting number obtainded NULL".
No problemo, te dices tú muy astuto, lo pregunto al revés:
[code linenumbers=false syntax=gambas]if isnull(mivariable) or mivariable=0[/code]
y todo arreglado.
Pues no, te repite el mismo error.

Es lo que hay.


-----------------------------------
Shell
Sabado, 06 Junio 2015, 09:03

Re: ¿ Fallo Del Operador Ternario IIF ?
-----------------------------------
Si vamos a la wikipedia de Gambas y vemos lo que es NULL.

Nos dice:

[quote]
La constante nula.
Esta constante se emplea para representar una referencia a un objeto nulo, una cadena de longitud cero, una fecha nula, o un valor Variant no inicializado.
[/quote]

No dice nada de números. Solo cadenas, fechas o un Variant no inicializado.
Así que si ejecuto este código. 

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  Dim mivariable As Integer
  
  mivariable = Null
  
  If mivariable = 0 Or IsNull(mivariable) Then Print mivariable
  
End
[/code]
Da el error que comentas.  En cambio si el código fuera este:

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  Dim mivariable As Variant
  
  mivariable = Null
  
  If mivariable = 0 Or IsNull(mivariable) Then Print mivariable
  
End
[/code]

No da error. Lo que no sé es por que no muestra una salida como Null

Expándete un poco en el código que nos quedamos a medias.. :roll: 

[quote]
En otros compiladores existía la optimización en las evaluaciones y la evaluación se interrumpía una vez que era manifiestamente cierta o falsa. 
[/quote]

No sé hasta que punto eso es cierto en Gambas. Jesús me demostró que en Gambas tambien existen los cortocircuitos, al igual que en Python.
Python es de lo los que evalúan la primera expresión y si no lo necesita, no continua con la segunda. De ahí el tema de los cortocircuitos.

[code linenumbers=false syntax=gambas]
Public Sub Main()
  
  If FalsoFizz("Gatos") Or If VerdaderoFizz("Perros") Then Print "Paso 1"
  
  If VerdaderoFizz("Hola") Or If VerdaderoFizz("Adios") Then Print "Paso 2"
  
  If VerdaderoFizz("Spam") And If VerdaderoFizz("Queso") Then Print "Paso 3"
  
  If FalsoFizz("Rojo") And If VerdaderoFizz("Azul") Then Print "Paso 4"
  
End

Public Function VerdaderoFizz(mensaje As String) As Boolean
  
  Print (mensaje)
  Return True
  
End

Public Function FalsoFizz(mensaje As String) As Boolean
  
  Print (mensaje)
  Return False
  
End
[/code]

Salida:

[quote]
Gatos
Perros
Paso 1
Hola
Paso 2
Spam
Queso
Paso 3
Rojo
[/quote]

Saludos


