Sentencias If-Then-Else y el "Metodo" $IIf(...)

Ver el tema anterior Ver el tema siguiente Ir abajo

Sentencias If-Then-Else y el "Metodo" $IIf(...)

Mensaje  Dark[Byte] el Vie Mayo 21, 2010 2:54 am

______________________________________________________________________________________________

Este pequeño tutorial es para inducir al Scripter Novato a equilibrar el uso de Sentencias If-Then-Else junto al Metodo $IIf(...) cuando sea conveniente y\o posible, o quizas sencillamente cuando quede mas prolijo por el bien de la legibilidad de su script o la simple estetica... XD
Podemos "ahorrar" unos cuantos bytes e innecesarias { } que pueden consumir CPU injustificadamente reduciendo la efectividad del Script.
A continuación un repaso de la sintaxis y el uso para la Sentencia y el Metodo...


*** Sentencia If-Then-Else ***
Las Estructuras de Control If-Then-Else, son bifurcaciones, tambien llamadas Sentencias Condicionales o de Logica Booleana, y forman parte de los principios de la Programación Estructurada moderna. Son una de las cosas mas utiles en mSL, y mejor dicho en cualquier lenguaje de programación.
Gracias a estas Sentencias podemos modificar el flujo de ejecución de las instrucciones en nuestro Script tanto en rutinas como en eventos, hay que destacar tambien que estas Sentencias se pueden encestar infinitamente una adentro de otra.
Otro tipo de Estructura de Bifurcación seria Case Switch pero no es nativa en mSL.
Si bien la sintaxis puede variar de lenguaje en lenguaje yo voy a hacer referencia aqui a la sintaxis en mSL que es el tema que nos concierne...

-Sintaxis de una Sentencia If-Then-Else:

.En Teoria:

If ... Si la condición se cumple...
Then ... Ejecutar instrucciones
Else ... Sino ejecutar otras instrucciones

.En Practica:

Código:
  If ( Condicion 1 ) {
      /*
      [Instrucciones 1]
      -Se ejecutan en caso de que se cumpla la Condicion 1
      -Luego de ejecutarse... el Script ignora los demas Else IF y el Else para continuar su curso...
      NOTA: NO IGNORA otros If, a estos tambien los verifica en caso de que hubieran
      */
    }
    Else If ( Condicion 2 ) {
      /*
      [Instrucciones 2]
      -Se ejecutan en caso de que se cumpla la Condicion 2
      -Ocurre lo mismo que en If...
      */
    }
    Else {
      */
      [Instrucciones 3]
      -Se ejecutan en caso de que no se cumpla ninguna Condición anterior
      -Luego de ejecutarse... el Script continua su curso...
      */
    }

Ahora veamos mas de cerca de que trata una Condición en una Sentencia If-Then-Else...

-Condicion simple o ideal:
... ( Esto es una Condición ) { ... }
... ( Valor1 Operador Valor2 ) { ... }

... ( 1 == 0 ) { ... }
Tenemos solo una Condicion: comparamos un valor con otro utilizando lo que se llama un Operador Relacional.

Operadores Relacionales mas usados:

Operador En Sintaxis Resulta Verdadero
== (V1 == V2) si V1 es igual a V2
=== (V1 === V2) si V1 es igual a V2 (Caso sensitivo)
!= (V1 != V2) si V1 no es igual a V2
!== (V1 !== V2) si V1 no es igual a V2 (Caso sensitivo)
< (V1 < V2) si V1 es menor que V2
<= (V1 <= V2) si V1 es menor o igual que V2
> (V1 > V2) si V1 es mayor que V2
>= (V1 >= V2) si V1 es mayor o igual que V2
isIn (V1 isIn V2) si V1 esta comprendido en V2
isInCS (V1 isInCS V2) si V1 esta comprendido en V2 (Caso sensitivo)
isWm (V1 isWm V2) si *V1* comodin esta comprendido en V2
isWmCS (V1 isWmCS V2) si *V1* comodin esta comprendido en V2 (Caso sensitivo)
isOn (V1 isOn V2) si V1 esta en canal #V2
isOp (V1 isOp V2) si V1 es operador en canal #V2


Nota:
-Se puede usar el prefijo "!" para negar un Operador Relacional y lograr el resultado inverso, Ejemplo: !isIn
-El sulfijo "CS" en un Operador Relacional indica Caso sensitivo, Ejemplo: isWmCS
-Hay muchos mas... pero estos son los mas usados y sencillos de usar.


-Condición multiple u compleja:
... ( Esto es una Condición ) Operador ( Esto es otra Condición ) { ... }
... ( Valor1 Operador Valor2 ) Operador ( Valor3 Operador Valor4 ) { ... }

... ( ( 1 == 0 ) || ( 2 > 3 ) ) { ... }
... ( ( 1 == 0 ) && ( 2 > 3 ) ) { ... }

... ( ( 1 == 0 ) && ( 2 > 3 || 4 < 5 ) ) { ... }

Podemos declarar una Sentencia con multiples Condiciones pero aqui entran en juego los Operadores Lógicos. Incluso podemos usar multiples Operadores Relacionales entre multiples y diversos Operadores Logicos.

Operadores Lógicos:

Operador Nombre En Sintaxis Resultado
&& AND (y...) ( (V1 Op1 V2) && (V1 Op2 V2)) Sentencia verdadera solo si Op1 y Op2 son TRUE
|| OR (ó...) ( (V1 Op V2) || (V1 Op V2)) Sentencia verdadera si Op1 u Op2 son TRUE

.Ejemplos:

-Sentencia con Condicion simple:

Código:
 If ( Nick ison #Channel ) {
      ;Notificamos que Nick esta en el canal #Channel
      Echo -a ***Nick esta en #Channel
    }
    Else If ( Nick ison #Channel2 ) {
      ;Notificamos que Nick esta en el canal #Channel2
      Echo -a ***Nick esta en #Channel2
    }
    Else {
      ;Notificamos que Nick no esta ni en #Channel ni en #Channel2
      Echo -a ***Nick no esta en #Channel o en #Channel2 !
    }

-Sentencia con Condicion multiple tipica:

Código:
 If ( ( Nick ison #Channel ) && ( Nick isop #Channel ) ) {
      ;Notificamos que Nick esta en el canal #Channel solo si es operador
      Echo -a ***Nick esta en #Channel
    }
    Else If ( ( Nick ison #Channel2 ) && ( Nick isvoice #Channel2 ) ) {
      ;Notificamos que Nick esta en el canal #Channel2 solo si tiene voz
      Echo -a ***Nick esta en #Channel2
    }
    Else {
      ;Notificamos que Nick no no esta ni en en #Channel ni en #Channel2 porque no tiene privilegios
      ;*...Sin embargo puede estar en alguno de esos canales como usuario normal...*
      Echo -a ***Nick no esta en #Channel o en #Channel2 !
    }


-Sentencia con Condicion multiple y Multiples Operadores Logicos:

Código:
 If ( ( Nick ison #Channel ) && ( Nick isop #Channel || Nick isvoice #Channel ) ) {
      ;Notificamos que Nick esta en el canal #Channel solo si es operador o si tiene voz
      Echo -a ***Nick esta en #Channel
    }
    Else If ( ( Nick ison #Channel2 ) && ( Nick isop #Channel2 || Nick isvoice #Channel2 ) ) {
      ;Notificamos que Nick esta en el canal #Channel2 solo si es operador o si tiene voz
      Echo -a ***Nick esta en #Channel2
    }
    Else {
      ;Notificamos que Nick no no esta ni en en #Channel ni en #Channel2 porque no tiene privilegios
      ;*...Sin embargo puede estar en alguno de esos canales como usuario normal...*
      Echo -a ***Nick no esta en #Channel o en #Channel2 !
    }


En estos tres ejemplos considerados vemos que son similares, pero NO IGUALES, y vemos que el uso de los Operadores Logicos como el "&&" o el "||" entre multiples Condiciones puede alterar, y mucho, el resultado de una Sentencia y por ende el comportamiento de tu Script. Lo cual puede terminar siendo objeto de errorres (BUGS!).

Suficiente de If-Then-Else para ser solo un repaso... vamos a pasar a lo siguiente...



*** Metodo\Identificador $IIf(...) ***

Anteriormente vimos lo que podemos llamar: forma estandar o convencional de una Sentencia If-Then-Else.
Ahora vamos a conocer lo que yo denomino Metodo $IIf(...) en mSL, que deberia de llamar Identificador, el cual no es en realidad un Metodo (en terminos de programación general), de hecho su significado nos dice todo: $IIf = Inmediate If. Traduscamoslo en nuestro Español como Sentencia If-Then-Else Inmediata.
Esta presente en varias ediciones del lenguaje Visual Basic donde se le clasifica como "Función", y tambien esta en lenguajes basados en C. Su sintaxis es identica en mSL como en VB.
Como conclusión es simplemente una forma alternativa de invocar una Sentencia If-Then-Else en una sintaxis mas corta y practica, voy a referirme a la misma con el termino "Metodo" simplemente porque es breve y me gusta....

-Sintaxis del Metodo $IIf(...):

.En Teoria:

If ... Si la condición se cumple...
Then ... Ejecutar parte verdadera
Else ... Sino ejecutar parte falsa

.En Practica:

$IIf( Condición, Parte Verdadera, Parte Falsa)

Veamos de cerca como es una Condicion para el metodo $IIf...

-Condicion simple o ideal:
...( Esto es una Condición, ......., ........)
...( Valor1 Operador Valor2, ......., ........)

...( 1 == 0 , ......., ........)

Una Condicion aqui se utiliza exactamente igual que en la sentencia If-The-Else... excepto por la falta de parentesis () propios de la condición. Los () que ves son los delimitadores de la sintaxis.
Los Operadores Relacionales disponibles son los mismos que se pueden usar en una Sentencia If-Then-Else Standard y el uso del prefijo ! y el sulfijo CS también es valido.

-Condición multiple u compleja:
...( Esto es una Condición Operador Esto es otra Condición, ......., ........)
...( Valor1 Operador Valor2 Operador Valor3 Operador Valor4, ......., ........)

...( 1 == 0 || 2 > 3 , ......., ........)
...( 1 == 0 && 2 > 3 , ......., ........)

...( 1 == 0 && ( 2 > 3 || 4 < 5 ), ......., ........)

En este caso tambien podemos declarar el metodo con multiples Condiciones determinadas por multiples i diversos Operadores Logicos al igual que en la sentencia If-The-Else. Los () de las Condiciones aqui tampoco son necesarios... a menos que hubiera multiples Operadores Logicos entre las multiples Condiciones.
Los Operadores Logicos disponibles son los mismos que se pueden usar en una Sentencia If-Then-Else Standard.

.Ejemplos:

-Metodo $IIf(...) con Condición simple:

Código:
 
    $IIf(Nick ison #Channel, Echo -a ***Nick esta en #Channel, Echo -a ***Nick no esta en #Channel)
    ;Notificamos que Nick esta en el canal #Channel, en el caso de que estuviera, y lo contrario si no estuviera...
   
La sintaxis anterior demasiado precaria... y aun asi estamos ahorrando espacio. Ejecutar esto desde la linea de comandos mediante el prefijo "//" no funciona, pero si funciona desde un Script Remoto.
Dado que $IIf(...) no es una /Instrucción y en realidad en el entorno de mSL es un Identificador vamos a usarlo de la siguiente forma que seria lo correcto e ideal:

Código:
Echo -a ***Nick $IIf(Nick ison #Channel, esta en #Channel, no esta en #Channel)
Ahora vemos lo util que puede ser y porque podemos ahorrar espacio usando esta version "Inmediata" de una Sentencia If-Then-Else


-Metodo $IIf(...) con Condición multiple tipica:

Código:
 
    Echo -a ***Nick $IIf(Nick ison #Channel && Nick isop #Channel, esta en #Channel, no esta en #Channel)
    ;Notificamos que Nick esta en el canal #Channel solo si es operador, si fuera un usuario normal nos notificaria que no esta en el #Canal... aunque en realidad podria estar
   

-Metodo $IIf(...) con Condición multiple y Multiples Operadores Logicos:

Código:

    Echo -a ***Nick $IIf(Nick ison #Channel && (Nick isop #Channel || Nick isvoice #Channel), esta en #Channel, no esta en #Channel)
    ;Notificamos que Nick esta en el canal #Channel solo si es operador o si tiene voz, si  fuera un usuario normal nos notificaria que no esta en el #Canal... aunque en realidad podria estar
   
Notar en este ejemplo la necesidad de parentesis () propios de al menos una de las condiciones.


*** Identificadores $V1 y $V2 ***
Los Identificadores $V* nos retornan el valor de los parametros en una Condición permitiendonos acceder rapida y practicamente al valor de dichos parametros PERO SOLO mientras estemos dentro de las instrucciones ejecutadas. Es decir al igual que las variables este Identificador tiene lo que llamamos Ámbito, Visibilidad o Scope (terminos generales de programación), lo cual nos determina su alcance en el Script, y podemos decir que es de caracter Local ya que como dije anteriormente solo se podra acceder a su valor mientras estemos dentro de las instrucciones ejecutadas. Y se comprende tambien que al declarar otra Condición en las mismas instrucciónes reemplazaria su valor por otro nuevo.
Funciona igualmente tanto en Sentencias If-Then-Else como en el metodo $IIf(...)

$V1 Primer parametro
$V2 Segundo parametro

.Ejemplos:

If ( 1 == 2 ) { ... } | Else { ... }
$V1 = 1
$v2 = 2


$IIf(A == B, ..., ...)
$V1 = A
$v2 = B

Cuando tenemos multiples Condiciones el identificador $V* toma los parametros de la ultima Condición declarada, vease a continuación...

If ( 1 == 2 ) || ( 2 == 3 ) || ( 3 == 4 ) { ... } | Else { ... }
$V1 = 3
$v2 = 4

$IIf(A == B || B == C || C == D, ..., ...)
$V1 = C
$v2 = D


*** Negando expresiones Booleanas con el prefijo "!" ***
El prefijo "!" es en realidad un Operador Lógico, no lo dije antes para no confundir, ya que no se utiliza en el mismo lugar que los demas de su tipo sino que se utiliza como prefijo en un Operador Relacional, o como prefijo directamente en una Condición a la cual negaria en caso de que fuera verdadera. Podría implementarse para evitar tener que usar un Else si se sabe que se espera que la condición sea verdadera, o bien para reducir espacio en la declaración de la condición.
En otras palabras el hecho de usar ese pefijo indicaria que se busca que la Condición sea falsa y si no lo usamos es porque estamos buscando que sea verdadera.
En esta sección ya no vamos a hacer referencia a su uso sobre un Operador Relacional porque ya lo vimos anteriormente en la tabla (Ejemplo: !isIn), vamos a ver como se puede utilizar directamente sobre una Condición.
Funciona igualmente tanto en Sentencias If-Then-Else como en el metodo $IIf(...)

.Ejemplos:

Código:
 
      If ( %a == $False ) { ... } | Else { ... }  -->    If ( !%a ) { ... } | Else { ... }
      If ( %a == $Null ) { ... } | Else { ... }    -->    If ( !%a ) { ... } | Else { ... }
     
      $IIf(%a == $False, ..., ...)                -->    $IIf(!%a, ..., ...)
      $IIf(%a == $Null , ..., ...)                -->    $IIf(!%a, ..., ...)

También podemos entender entonces que una Condición sin el prefijo ! equivale naturalmente a la expresión inversa veridica...

Código:
 
      If ( %a == $True ) { ... } | Else { ... }  -->    If ( %a ) { ... } | Else { ... }
      If ( %a != $Null  ) { ... } | Else { ... }    -->    If ( %a ) { ... } | Else { ... }
     
      IIf(%a == $True, ..., ...)                  -->    $IIf(%a, ..., ...)
      IIf(%a != $Null, ..., ...)                    -->    $IIf(%a, ..., ...)


*** Depurando ****
Veamos algunos errores de comprensión y de sintaxis. Y creo que esta de más decir que solo los errores de sintaxis dan error por parte del Engine del mSL, en cambio ante un error de comprensión no tendremos notificación alguna y simplemente nuestro Script no funcionara como quisieramos dando malos resultados y decepcionandonos:


.Error de comprensión usando diversas sentencias
Vamos a aclarar un error que los Scripters mas novatos suelen cometer...
Cuando usamos "Else If" estamos verificando solo por esa condicion y ninguna mas a su continuación.

Es decir... Considere esto:
Código:
  If ( Condicion 1 )
        Else If ( Condicion 2 )
        Else If ( Condicion 3 )
        Else If ( Condicion 4 )
        Else

Esta Sentencia solo verificara por una Condicion hasta llegar a Else...

Que no es lo mismo que... Considerar esto:

Código:
  If ( Condicion 1 )
        If ( Condicion 2 )
        If ( Condicion 3 )
        If ( Condicion 4 )
        Else

Esta Sentencia verificara por todas las Condiciones hasta llegar a Else...
Y obiamente el uso de Else podria no ser necesario.

Interesante es decir que el segundo caso considerado usualmente en tiempo de ejecución demora mas que el primer caso ya que tiene que verificar todas las condiciones antes de llegar a Else o el final.
En el primer caso donde se encuentre una condición que cumpla se ejecuta y sale de la Estructura para continuar con el Script ignorando los otros Else Ifs y el Else si hubiera.

.Error de sintaxis al hacer mal o ningún uso de parentesis ()
Cuando se trata de Condiciónes complejas sin importar si estamos utilizando Sentencias If-Then-Else o el Metodo $IIf(..) debemos de utilizar parentesis() propios de la Condición. Es la mejor manera de mostrarle exactamente al Engine del mSL lo que queremos que este interprete. De hecho los () no son estrictamente necesarios pero se recomienda a los mas novatos a usarlos por el bien de la legibilidad de su Script.


.Error de sintaxis usando Sub-Operadores
También suele verse la mala utilización de los Sub-Operadores "<=" y ">=" . Vease la siguiente tabla:

Incorrecto Correcto
( V1 =< V2 ) ( V1 <= V2 )
( V1 => V2 ) ( V1 >= V2 )

*** Sacando Conclusiones ***
Para el que llego hasta aqui si presto atención deberia de haber notado que el Metodo $IIf() en su sintaxis tipica tiene la desventaja de poder ejecutar solo dos partes (Una verdadera y la otra falsa).
Como si eso fuera poco, solo puede ejecutar UNA INSTRUCCIÓN en cualquiera de esas dos partes.
Y es que en realidad yo utilize a proposito como sintaxis ideal de la sentencia If-Then-Else una forma extendida... por lo que le deje en evidente ventaja a la Sentencia sobre el Metodo:
Primero considere:
Código:

      If ( Condicion ) {
      /*
      [Instrucciones 1]
      -Se ejecutan en caso de que se cumpla la Condicion
      -Luego de ejecutarse... el Script continua su curso...
      */
    }
    Else {
      */
      [Instrucciones 3]
      -Se ejecutan en caso de que no se cumpla la Condición anterior
      -Luego de ejecutarse... el Script continua su curso...
      */
    }

Aqui ya no estamos tomando la posibilidad de considerar varias Condiciones... como lo ise hoy al al principio de este tutorial... esta es la verdadera Sintaxis tipica para una Sentencia If-Then-Else, porque cumple exactamente con lo que la teoria nos explica...

If ... Si la condición se cumple...
Then ... Ejecutar instrucciones
Else ... Sino ejecutar otras instrucciones

Resumiendo solo hay dos posibilidades... solo ser verifica por una condición... aca no hay Else Ifs... y cuando declaramos Sentencias If-Then-Else tan basicas nisiquiera son necesarias las las llaves { } de ambas partes, a menos que hubiera varias instrucciones para ejecutar.

Ahora considere:

Código:
$IIf( Condición, Parte Verdadera, Parte Falsa)

Vemos que es exactamente lo mismo pero en una linea, con la limitación de solo poder ejecutar una instrucción.

Igualmente podemos imitar una sentencia If-Then-Else compleja con el metodo $IIf(...). Voy a utilizar el siguiente ejemplo que fue el caso mas complejo que vimos:

Código:
If ( ( Nick ison #Channel ) && ( Nick isop #Channel || Nick isvoice #Channel ) ) {
      ;Notificamos que Nick esta en el canal #Channel solo si es operador o si tiene voz
      Echo -a ***Nick esta en #Channel
    }
    Else If ( ( Nick ison #Channel2 ) && ( Nick isop #Channel2 || Nick isvoice #Channel2 ) ) {
      ;Notificamos que Nick esta en el canal #Channel2 solo si es operador o si tiene voz
      Echo -a ***Nick esta en #Channel2
    }
    Else {
      ;Notificamos que Nick no no esta ni en en #Channel ni en #Channel2 porque no tiene privilegios
      ;*...Sin embargo puede estar en alguno de esos canales como usuario normal...*
      Echo -a ***Nick no esta en #Channel o en #Channel2 !
    }

En este caso tuvimos en cuenta la posibilidad de verificar en #Channel y en #Channel2 para luego en caso de que ninguno cumpla con la condicion ejecutar un Else... y a primera vista esto no parece posible de realizarse con $IIf(...)... Sin embargo lo que no mencione antes es que los $IIf(...) se pueden
encestar tanto como sea necesario al igual que las Sentencias.

Con el Metodo $IIf(...) quedaria de la siguiente forma:
Código:
Echo -a ***Nick $IIf(Nick ison #Channel && (Nick isop #Channel || Nick isvoice #Channel), esta en #Channel, $IIf(Nick ison #Channel2 && (Nick isop #Channel2 || Nick isvoice #Channel2), esta en #Channel2, no esta en #Channel o en #Channel2 !))


*** Por las dudas... ***
Bueno si alguien todavia tiene alguna duda (aunque no lo creo), doy por ultimo otros simples ejemplos para poder terminar de comprender:

Con una Sentencia If-Then-Else Estandard:
Código:
 
Prueba1 {
  Var %a = $?="Un número:"
  Var %b = $?="Otro número:"
  If      %a > %b Echo -s Resultado: %a es mayor que %b
  ElseIf  %a < %b Echo -s Resultado: %a es menor que %b
  Else            Echo -s Resultado: %a es igual que %b
}   
   

Con una Sentencia If-Then-Else Inmediata:
Código:
 
Prueba2 {
  Var %a = $?="Un número:"
  Var %b = $?="Otro número:"
  Echo -s Resultado: %a es $IIf(%a > %b, mayor, $IIf(%a < %b, menor, igual) ) que %b
}

Otro Pequeño Ejemplo $IIf(...):
Código:

 //Echo -a $IIf($?="Escribe Algo:" == $?="Escribe Algo:", $Verdadero, $Falso)
 

Aquí una tabla con el resultado de posibles multiples Condiciones con multiples Operadores Lógicos...
Código:

If ($True) && ($True) { ... } | ;Veradero
;-
If ($True) && ($False) { ... } | ;Falso
;-
If ($False) && ($False) { ... }  | ;Falso
;-
If ($True) || ($True) { ... } | ;Verdadero
;-
If ($True) || ($False) { ... } | ;Falso
;-
If ($False) || ($False) { ... } | ;Verdadero
;-
If ($True) || ($False) && ($True) { ... } | ;Verdadero
;-
If ($True) || ($False) && ($False) { ... } | ;Verdadero
;-
If ($False) || ($True) || ($False) { ... } | ;Falso
;-
If ($True) && ($False) && ($False) { ... } | ;Falso

THE END
______________________________________________________________________________________________
GLOSARIO
-mSL = mIRC Scripting Language
-Engine mSL = el motor encargado de leer, interpretar y ejecutar nuestro Script, en este caso es el propio mIRC.
-Caso Sensitivo = Que distingue mayúsculas de minúsculas

NOTA:
-Algunos ejemplos son meramente explicativos
-No me hago responsable del mal uso de estos conocimientos
______________________________________________________________________________________________
Escrito por DarkByte para #mIRC-Scripting y #mSL en IRC-Hispano.Org
avatar
Dark[Byte]
Admin

Mensajes : 13
Fecha de inscripción : 20/05/2010
Localización : Uruguay

Ver perfil de usuario http://mirc-scripting.foroes.org

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.