mIRC Homepage

isin v iswm?

Posted By: Mpot

isin v iswm? - 06/05/09 08:27 PM

How exactly do isin and iswm operate differently? Say, if you wanted to catch an expletive, which would be better?

Code:
on *:text:*:#: {
  if (expletive iswn $1-) { /kick $chan $nick }
  elseif (expletive2 iswm $1-) { /kick $chan $nick }
  etc
}


or

Code:
on *:text:*:#: {
  if (expletive isin $1-) { /kick $chan $nick }
  elseif (expletive2 isin $1-) { /kick $chan $nick }
  etc
}
Posted By: argv0

Re: isin v iswm? - 06/05/09 08:59 PM

iswm as stated by the help is a wildcard match,

a wildcard match is a string of text with the "*" character meaning "any set of 0 or more characters" and "?" meaning "exactly one character". If you don't specify any of these wildcard characters in a match, the comparison is made literally, from the beginning of the string to the end:

(HELLO iswm HELLO WORLD) is equivalent to (HELLO == HELLO WORLD) without wildcards -- this obviously will not work.

If you wrote *HELLO it would search for anything ending in HELLO

HELLO* would look for anything beginning with HELLO

*HELLO* would be anything with HELLO inside of it

The last behaviour, if you didn't catch it, is equivalent to that of the isin operator.

--

So really, iswm is a superset of the isin functionality. If you're only testing the existence of a substring in a larger string, use isin. If you have specific constraints on where the substring should be (beginning, end, or more complex constraints), use iswm to build a wildcard match.
Posted By: Mpot

Re: isin v iswm? - 06/05/09 09:09 PM

I think I follow you. So, in this situation, isin would be the right choice. Thanks.
Posted By: Mpot

Re: isin v iswm? - 06/05/09 09:25 PM

However, say, I wanted to put a list of expletives in a file:

Quote:

expletive1
expletive2
expletive3


Code:
if ($read(expletives.txt) isin $1-) { /kick $chan $nick }


How's that?
Posted By: Tomao

Re: isin v iswm? - 06/05/09 10:04 PM

I think it'd be better if you used:
Code:
if ($read(expletives.txt,w,$+(*,$1-,*))) { kick $chan $nick }

Posted By: Horstl

Re: isin v iswm? - 06/05/09 10:13 PM

I think the OP don't want to check TEXT isin <any line>, but <any line> isin TEXT. In this case - if a text file is used as the source - a loop is inevitable. e.g.:
Code:
  var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($v1 isin $1-) {
      kick $chan $nick Your message contained badword $qt($v1)
      break
    }
    inc %n
  }
Posted By: Mpot

Re: isin v iswm? - 06/05/09 11:32 PM

Originally Posted By: Horstl
I think the OP don't want to check TEXT isin <any line>, but <any line> isin TEXT. In this case - if a text file is used as the source - a loop is inevitable. e.g.:
Code:
  var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($v1 isin $1-) {
      kick $chan $nick Your message contained badword $qt($v1)
      break
    }
    inc %n
  }


I think that's what I'm looking for. Thanks. I have a question though. This line:
Code:
while ($read(C:\IcyBot2\expletives.txt,n,%n))
doesn't seem to have the while compare against something. Is that the same as != $null?
Posted By: RusselB

Re: isin v iswm? - 07/05/09 12:06 AM

Is that the same as != $null? -> Yes
Posted By: Mpot

Re: isin v iswm? - 07/05/09 12:18 AM

Thanks.
Posted By: qwerty

Re: isin v iswm? - 07/05/09 12:23 AM

Not exactly. if (something) is false whenever "something" is $null, 0 or $false.
Posted By: Horstl

Re: isin v iswm? - 07/05/09 12:28 AM

It's like != $null && != 0. But that's nit-picking in your concrete case, as you'll hardly add "0" as a badword to the file. smile

In other situations, especially if numerical values are involved, the difference between if (something) and if (something != $null) can be both a pitfall and useful for scripts. Take for example some "boolean switch" (0=false 1=true) in an .ini or the like.

You can see the difference at %y in this example:
Code:
alias test {
 var %x = 1, %y = 0, %z
 if (%x != $null) echo -a x has some value
 if (%y != $null) echo -a y has some value
 if (%z != $null) echo -a z has some value
 if (%x) echo -a x has a value that isn't 0
 if (%y) echo -a y has a value that isn't 0
 if (%z) echo -a z has a value that isn't 0
}

qwerty beat me to it
Posted By: Mpot

Re: isin v iswm? - 07/05/09 01:35 AM

So basically,

Code:
if (%x)
means "if %x exists and doesn't equal zero"

and

Code:
if (%x != $null)
means "if %x exists or equals zero"

Correct?
Posted By: Horstl

Re: isin v iswm? - 07/05/09 01:59 AM

Well, qwerty's answer was more precise.

I'll try to be precise just as much:
- your variable may "exist" without any value assigned
- if (%x != $null) is true if %x has *any* value assigned
- if (%x) is true if %x has a value asssigned AND this value is neither "0" nor "$false".
Posted By: Mpot

Re: isin v iswm? - 07/05/09 03:39 AM

Got it!
Posted By: hixxy

Re: isin v iswm? - 08/05/09 09:42 PM

Just to nitpick, if (%x) will also fail if the value of %x is mathematically 0. This means it will fail if %x is 00 or 000, etc.
Posted By: Mpot

Re: isin v iswm? - 11/05/09 07:10 PM

Little problem. One of the words on the list is "mom". People are getting kicked when they say "moment". Obviously this makes sense, but how would you go about forcing the script to evaluate each word as a whole? Tokenizing, perhaps?

Edit: Okay, I came up with this. It's either batshit crazy or it works.

Code:
on *:text:*:#auroratest: {
  var %text = $1-
  tokenize 32 %text
  var %n3 = $numtok(%text,32)
  var %n = 1
  var %word = $+($,%n2)
  var %2n = 1
  while ($read(C:\IcyBot2\expletives.txt,n,%n)) {
    while (%n2 <= %numtok) {
      if ($v1 == %word) { 
        kick $chan $nick You said $read(C:\IcyBot2\kicks.txt,w,* $+ $v1 $+ *)
        break
      }
      inc %n
      inc %n2
    }
  }
}
Posted By: 5618

Re: isin v iswm? - 11/05/09 07:38 PM

You could use $istok instead.
Code:
if ($istok($1-,your.mom.jokes,46))

In this example the if-statement is true if the *single* words "your" "mom" or "jokes" are in the line.
Posted By: Horstl

Re: isin v iswm? - 11/05/09 07:45 PM

I suggest (inside your original loop):
Code:
  if ($istok($1-,$v1,32)) { kick with some general reason }
(the $v1 is the line just read)

or, to repeat the match in the kick message:
Code:
  if ($findtok($1-,$v1,32)) { kick with reference to the matching token: $gettok($1-,$v1,32) }
(the first $v1 is the line just read, the second $v1 is the number of the token just found)

Or, if you have wildcard definitions in the file, you have to go for $wildtok instead of $findtok.
Posted By: Horstl

Re: isin v iswm? - 11/05/09 07:49 PM

This won't work, the parameters are the other way arround.
true: $istok(your.mom.jokes,mom,46)
not true: $istok(mom,your.mom.jokes,46)
Posted By: Mpot

Re: isin v iswm? - 11/05/09 08:04 PM

You've completely lost me.

($findtok($1-,$v1,32))

=

if $v2 (the bad word we're on) is anywhere in the $1- (the spoken line)

?
Posted By: Horstl

Re: isin v iswm? - 11/05/09 08:18 PM

You had had a loop doing a "isin" check to compare every line of the textfile to the current message.
Instead of a check for isin, you could check for $istok, $findtok, or $matchtok.
With token identifiers you need to specify the char that is seaparating what you're looking for. As you're trying to match whole words, which are separated by spaces, it's "32" (the ascii value of a space is 32). Sorry for my bad explanation - have a look at /help token identifiers smile

The code I was refering to:
Code:
 var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($v1 isin $1-) {
      kick $chan $nick Your message contained badword $qt($v1)
      break
    }
    inc %n
  }

The code, modified for "istok":
Code:
 var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($istok($1-,$v1,32)) {
      kick $chan $nick Your message contained some badword
      break
    }
    inc %n
  }
Because istok will only return "$true" or "$false", you cannot have a direct reference to the matching word.
But of course you could $read the line again to get the "bad" word that was matched by the message: "Your message contained the badword $read(expletives.txt,n,%n)"

The code, modified for "findtok":
Code:
 var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($findtok($1-,$v1,32)) {
      kick $chan $nick Your message contained the badword $gettok($1-,$v1,32)
      break
    }
    inc %n
  }
Findtok isn't returning $true or $false but the position of the matching token. With a gettok on the original message, you return the "bad" word that was matched.
Posted By: Mpot

Re: isin v iswm? - 11/05/09 08:35 PM

So $v1 changes from the current line in the text file, to the number of the token that matched the line?

Also, I modified the original to work like this:

Code:
on *:text:*:: {
  var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($v1 isin $1-) { 
      kick $chan $nick You said $read(kicks.txt,w,* $+ $v1 $+ *)
      break
    }
    inc %n
  }
}


I assume the correct modification is:

Code:
on *:text:*:: {
  var %n = 1
  while ($read(expletives.txt,n,%n)) {
    if ($v1 isin $1-) { 
      kick $chan $nick You said $read(kicks.txt,w,* $+ $gettok($1-,$v1,32) $+ *)
      break
    }
    inc %n
  }
}

?

Anyway, I appreciate the help. I'll have to look over this again when I'm not quite as exhausted, because I'm not quite getting the concept.

Thanks, Horstl.
Posted By: Horstl

Re: isin v iswm? - 11/05/09 09:21 PM

$v1 is the first parameter of the last if-condition that was matched/true. $v2 would be the second parameter, given there is one.
Example:
Code:
//if (3 isnum 1-5) echo -a $v1 is a number in the range of $v2 

Another example:
Code:
if (%a <= %b) && (%b > %a) { echo -s %a }
is the same as:
Code:
if (%a <= %b) && ($v2 > $v1) { echo -s $v2 }

In this piece of code:
Code:
while ($read(expletives.txt,n,%n)) {
    if ($v1 isin $1-) {
This loop keeps looping as long as $read(expletives.txt,n,%n) returns something (OK, as pointed out by some previous posts, something that is neither 0 nor $false smile )
The "$v1" in "if ($v1 isin $1-)" is the value returned by $read = the line that was read.
Using $v1 in the kick reason works as well, because the value of the first parameter of "if ($v1 isin $1-)" is the very same:
" kick $chan $nick You said something that contains $v1 "


But in this piece of code:
Code:
while ($read(expletives.txt,n,%n)) {
    if ($findtok($1-,$v1,32)) {
      kick $chan $nick Your message contained the badword $gettok($1-,$v1,32)
The $v1 in "if ($findtok($1-,$v1,32))" is the value of the first (and only) parameter of the while - the text returned by $read.
However in the kick command, $v1 refers to the value of the first (and only) parameter of the condition "if ($findtok($1-,$v1,32))", which is not the line read but the position of the token in the text message $1-.

...wish I could explain this in a more intelligible way smirk

Posted By: Tomao

Re: isin v iswm? - 11/05/09 11:21 PM

This tutorial has been throughly and helpfully useful, professor Horstl. Danke schön! wink
Posted By: Horstl

Re: isin v iswm? - 13/05/09 04:11 PM

/me sets mode +leg_puller Tomao whistle
© 2020 mIRC Discussion Forums