mIRC Home    About    Download    Register    News    Help

Print Thread
#13984 03/03/03 12:13 PM
Joined: Feb 2003
Posts: 33
G
Ameglian cow
OP Offline
Ameglian cow
G
Joined: Feb 2003
Posts: 33
I have a String with
eg: bier bier bier fanta vrb fanta cola bier
now i want to replace all bier's with 1bier and put the amout of bier in front of it so i should have:
4X bier 2X fanta 1X vrb 1X cola

how can i do that?


it's for in my Bartender Script:
the string is -->$readini($scriptdir/barman.ini,bill,$nick)

and in the channel it can be triggerd with
!bill
eg:
Code:
on 1:text:!*:#:{
  if ( $1 == !bill ) { /.msg $chan $readini( $scriptdir/barman.ini ,  bill , $nick ) }

<!Gods_Hell> !bill
<@Bartender> Gods_Hell's bill => bier bier bier fanta vrb fanta cola bier

i hope somone can help me out ...



#13985 03/03/03 04:17 PM
Joined: Dec 2002
Posts: 1,321
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Dec 2002
Posts: 1,321
Code:

on *:TEXT:!bill:#:{
  var %item = 1                                                     | ; Loop index
  var %bill                                                         | ; Output string
  var %order = $readini($scriptdirbarman.ini, bill, $nick)          | ; Input string
  while $gettok(%order, %item, 32) {                                | ; Total individual items
    inc $+(%,order.item.,$ifmatch)                                  | ;   Add 1 to the individual item count
    inc %item                                                       | ;   Go to the next order item
  }                                                                 | ;
  %item = 1                                                         | ; Build the output string backwards
  while $var(%order.item.*, %item) != $null {                       | ; Grab individual totals
    %bill = %bill $+ , $eval($ifmatch, 2) $gettok($ifmatch, -1, 46) | ;   Add them to the string   
    inc %item                                                       | ;   Get the next item
  }                                                                 | ;
  %bill = $right(%bill,-2)                                          | ; Cut off the initial ", "
  unset %order.item.*                                               | ; Clean out the temp variables
  msg $chan $nick $+ 's bill: %bill                                 | ; Output the string
}


DALnet: #HelpDesk and #m[color:#FF0000]IR[color:#EEEE00]C
#13986 03/03/03 07:00 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
I thought of a faster (although harder to grasp) method for this.
Code:
on *:text:!bill:#:{
  !.echo -q $regsub($sorttok($readini($scriptdirbarman.ini,bill,$nick),32),/(\S+)((?: \1)*)(?: |$)/g,\1\2 $+ $lf,%barman)
  tokenize 10 %barman
  barman $*
  msg # $nick $+ 's bill: $mid(%barman,3)
  unset %barman
}
alias barman %barman = %barman $+ , $0 $1
As you can see, it uses no loops at all, hence its speed. The number of 'drinks' might not be so large (so that speed becomes an issue), but it was fun to make smile


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#13987 03/03/03 09:02 PM
Joined: Dec 2002
Posts: 1,321
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Dec 2002
Posts: 1,321
qwerty: Just as a help for those who are trying to learn how to do what we're doing rather than just taking what we give them, would you explain why you did what you did, please? I don't mean you have to give line-by-line commentary necessarily (which I tend to do for scripts I intend others to learn from), but if not in-code comments, then at least why yours works, and if possible, how it works. I like the $* idea but decided against it in the interest of clarity.


DALnet: #HelpDesk and #m[color:#FF0000]IR[color:#EEEE00]C
#13988 03/03/03 11:40 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
I'll try to explain the logical steps of the process, pointing to the parts of the script that implement each step.

The first step is to group the identical words together. For example, if the $readini() returns something like this:
"beer fanta cola beer beer fanta cola fanta beer"
we want to reorder the words so that the line becomes:
"beer beer beer beer cola cola fanta fanta fanta"
Why? Because we are then able to break apart the line into chunks that only contain a number of identical words. The chunks in our example are
beer beer beer beer
cola cola
fanta fanta fanta
So, we break the line apart and then count how many times each word is repeated in each chunk.

The sorting of the line read from barman.ini is done with $sorttok($readini($scriptdirbarman.ini,bill,$nick),32)

The division of the line into chunks of identical words is done essiantially by 'tokenizing' the string, ie inserting characters (token separators) between different chunks. I chose the LF character ($lf or $chr(10)) for that, because it is safe: it can never be inside a word. The insertion of the LF separators is done with the $regsub(). I'm afraid I can't really say anything else about this part, since regular expressions knowledge is required; and those who do know regex will probably figure out this part anyway.

After the $regsub call, our string looks like this:
"beer beer beer beer<LF>cola cola<LF>fanta fanta fanta<LF>"
The next step is to split this line into tokens. This can be done in two ways: $gettok() or /tokenize. I chose tokenize, because it allows me to use the $* identifiers, thus avoiding the loop. So we perform a /tokenize on the line stored in %barman:
tokenize 10 %barman

Then we call the alias named 'barman' and pass it $*: this way, mirc executes the barman alias $0 times, each time passing it $1, $2, $3 etc. But the /tokenize command has filled $1 with "beer beer beer beer", $2 with "cola cola" and $3 with "fanta fanta fanta". Now, the barman alias, that sees each token as $1-, can easily get the number of instances of the word (which is $1) in $1-, which is $0. So it sets the variable like :
%barman = <old %barman value>, <total number of instances of a word> <word>
This is done for each LF-separated token in the original string, as we said.

%barman has now become
", 4 beer, 2 cola, 3 fanta"
$mid(%barman,3) is the same as $right(%barman,-2) and just cuts off the first two characters from %barman, (the trailing comma and the space right after it).

I guess it turned out to be a bit longer than a few in-code comments :tongue:

IMPORTANT
I just noticed that I forgot to unset %barman before I call /barman. So one more "unset %barman" is required, just above "barman $*". This way, the /barman alias will start with a clean %barman variable.

Code:
on *:text:!bill:#:{
  !.echo -q $regsub($sorttok($1-,32),/(\S+)((?: \1)*)(?: |$)/g,\1\2 $+ $lf,%barman)
  tokenize 10 %barman
  unset %barman
  barman $*
  msg # $nick $+ 's bill: $mid(%barman,3)
  unset %barman
}
alias barman %barman = %barman $+ , $0 $1

Last edited by qwerty; 03/03/03 11:48 PM.

/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#13989 04/03/03 09:28 AM
Joined: Feb 2003
Posts: 33
G
Ameglian cow
OP Offline
Ameglian cow
G
Joined: Feb 2003
Posts: 33
Aha thank you verry much
nice scripting btw and thx for the explenation dude's !!




Link Copied to Clipboard