¿ Fallo Del Operador Ternario IIF ?


Objetivo: ¿ 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.

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


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.

última edición por Shell el Sabado, 06 Junio 2015, 00:24; editado 2 veces

OperadorIIF_Prueba.tar.gz
Descripción:  
Descargar
Nombre del archivo: OperadorIIF_Prueba.tar.gz
Tamaño: 4.66 KB
Descargado: 44 veces
OperadorIIF_Prueba.tar.gz
Descripción:  
Descargar
Nombre del archivo: OperadorIIF_Prueba.tar.gz
Tamaño: 4.66 KB
Descargado: 44 veces
OperadorIIF_Prueba.tar.gz
Descripción:  
Descargar
Nombre del archivo: OperadorIIF_Prueba.tar.gz
Tamaño: 4.66 KB
Descargado: 44 veces

Objetivo: 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.

Perfil MP  
Objetivo: Re: ¿ Fallo Del Operador Ternario IFF ?
shordi escribió: [Ver mensaje]
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.


Me has dejado a cuadros.

Citar:

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.


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

Citar:

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,


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)

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


Salida:
Citar:

LLave: uno Valor: primero
LLave: dos Valor: segundo
LLave: tres Valor: tercero
LLave: cuatro Valor: otro


Ejemplo en Python:

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

#!/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()


Saludos

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

cito de la gambaswiki

Citar:
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.

Perfil MP  
Objetivo: 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:



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

En Python:

print not 0


Se obtiene False

En cambio en gambas si se hace:


Se obtiene -2 ! WTF.

Citar:

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.


Así que
print not 34.2


Nos da Falso.

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

Si hacemos en Gambas:
Print Not -87

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:

print not ''

Obtenemos True

En gambas es igual.

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

Saludos

Objetivo: 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.

Aritmértca binaria.

Saludos

Objetivo: 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".

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


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.

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


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

Operador IIF


Saludos

última edición por Shell el Sabado, 06 Junio 2015, 00:25; editado 1 vez
Objetivo: 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í:
if mivariable=0 or isnull(mivariable) then


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:
if isnull(mivariable) or mivariable=0

y todo arreglado.
Pues no, te repite el mismo error.

Es lo que hay.

Perfil MP  
Objetivo: Re: ¿ Fallo Del Operador Ternario IIF ?
Si vamos a la wikipedia de gambas y vemos lo que es NULL.

Nos dice:

Citar:

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.


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

Public Sub Main()

Dim mivariable As Integer

mivariable = Null

If mivariable = 0 Or IsNull(mivariable) Then Print mivariable

End

Da el error que comentas. En cambio si el código fuera este:

Public Sub Main()

Dim mivariable As Variant

mivariable = Null

If mivariable = 0 Or IsNull(mivariable) Then Print mivariable

End


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..

Citar:

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.


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.

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


Salida:

Citar:

Gatos
Perros
Paso 1
Hola
Paso 2
Spam
Queso
Paso 3
Rojo


Saludos


Página 1 de 1


  
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario

   

Está utilizando la versión (Lo-Fi). Para ver la versión completa del foro, haga clic aquí.

Powered by Icy Phoenix based on phpBB
Design by DiDiDaDo

Página generada en:: 0.2043s (PHP: 3% SQL: 97%)
Consultas SQL: 27 - Debug off - GZIP Activado