mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Apr 2006
Posts: 464
O
Fjord artisan
OP Offline
Fjord artisan
O
Joined: Apr 2006
Posts: 464
Hello All,

I have a hash table, with around 1000 items.
Each item has a data line, in the following format:

token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) token5 $chr(9) token6 $chr(9)

Now I need to loop trough the table quite often, and replace a certain token, with a new word.

So:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) Apple $chr(9) token6 $chr(9)
Becomes:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) Melon $chr(9) token6 $chr(9)

Now, I use this code for that:
Code:
    var %cnt = 1
    var %ttl = $hget(table,0).item
    while (%cnt <= %ttl) {
      var %id = %cnt
      var %old-string = $hget(table,%id)
      var %old-token = $gettok(%old-string,5,9))
      var %new-token = Melon
      var %new-string = $puttok(%old-string,%new-token,5,9)

      hdel table %id
      hadd table %id %new-string
      inc %cnt
    }


Is this the most efficient way of doing this?
I've noticed, that when this replacement has to be done like 20 times, it doesn't run very smoothly, and it seems to 'forget' replace some...

Does anyone have suggestions for this?

Thanks a lot!

Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
Code:
var %cnt = 1, %ttl = $hget(table,0).item
while %cnt <= %ttl {
  var %item = $hget(table,%cnt).item, %data = $hget(table,%cnt).data
  .hadd -m table %item $reptokcs(%data,$gettok(%data,5,9),Melon,1,9)
  inc %cnt
}


Note: Some of the items in the code are fixed, per your example, if you need something that is more flexible, you can try to work it out yourself and/or post back here and I'll do it up for you tonight.
Additionally, the above code is case sensitive, if you don't want that, remove the cs from $reptokcs

/help $reptok

Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
First of all, the reason it forgets to replace certain items is probably that $hget(table,%id) does not do what you think: $hget(table,3) does not return the data of the 3rd item, it returns the data of the item named "3". Compare with $hget(table,3).item (and $hget(table,3).data). So unless all your items names are consecutive numbers from 1 to $hget(table,0).item, things will go wrong.

You could first get the item name from the index with something like
var %name = $hget(table,%id).item
and change $hget(%table,%id) to to $hget(%table,%name) but be aware that this will slow down your script considerably ($hget().item/data is not an efficient way to access a hash table).

Also, not sure if you created all those variables just for testing purposes, but your script would run somewhat faster if you got rid of most of them. Here's what I mean (the following does not address the first problem):
Code:
var %cnt = 1, %ttl = $hget(table,0).item
while %cnt <= %ttl {
  hadd table %cnt $puttok($hget(table,%cnt),Melon,5,9)
  inc %cnt
}


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Ah you beat me to it. One thing though: there's no reason to change his $puttok() approach to $reptok()/$gettok(). Apart from the fact that it's unnecessarily longer/slower, it won't work correctly if the word "Apple" is in more than one places in the string (and it looks like OrionsBelt wants position-based substitutions rather than content-based).


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
Joined: Apr 2006
Posts: 464
O
Fjord artisan
OP Offline
Fjord artisan
O
Joined: Apr 2006
Posts: 464
Thanks for looking into that guys.

Quote:
So unless all your items names are consecutive numbers from 1 to $hget(table,0).item, things will go wrong.


It is consecutive. When a new item gets added, the %id is created with: var %id = $calc($hget(table,0).item + 1)

I will make the re-write like you proposed.
I made the variables so that its easier to understand whats happening for me, but I want it to be as short as possible.

Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
There were a number of possibilities that I thought of when writing my code. I just did it the way I did to match his example. I did state that if he wanted/needed it to be more flexible, to let me know.

I mean, I was able to think of a script that would allow him to replace the first occurance of Word A with Word B, 2nd occurance with Word C, 3rd occurance with Word D, etc. till Word A no longer is in the string, or until all of the replacement words were used, at which point, the balance could be left well alone, or the replacement words could repeat the sequence.

I didn't get it written up, as I wasn't in a location where I could write it up when I thought of it.

Joined: Apr 2006
Posts: 464
O
Fjord artisan
OP Offline
Fjord artisan
O
Joined: Apr 2006
Posts: 464
I still cant get this to work crazy

Code:
alias reduce-tok5 {
  var %cnt = 1, %ttl = $hget(table,0).item
  while (%cnt <= %ttl) {
    hadd table %cnt $puttok($hget(table,%cnt),$calc($gettok($hget(table,%cnt),5,9) - 1),5,9)
    inc %cnt
  }
}


The table currently contains 400 items (will slowly go up to about 3000).
Each item contains 13 tokens.
It still seems to skip some items, while running the loop.

I want to deduct token 5, once an hour.
So I call this alias, once every hour.

Does anyone have more idea's ?

Thanks in advance!

Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
Correct me if I'm wrong, but it sounds like you're wanting to remove the 5th token from each data string every hour.
If this is correct, you do realize that eventually it's possible for you to not have 5 items in the string.

Additionally, earlier you were talking about replacement, now you're talking about removal. Please clarify which it is.

If it's removal that you want
Code:
alias reduce-tok5 {
  var %cnt = 1, %ttl = $hget(table,0).item
  while %cnt <= %ttl {
    .hadd -m table %cnt $deltok($hget(table,%cnt).data,5,9)
    inc %cnt
  }
}


Joined: Oct 2005
Posts: 1,741
G
Hoopy frood
Offline
Hoopy frood
G
Joined: Oct 2005
Posts: 1,741
If you tell us exactly what you are trying to accomplish (rather than using other examples), we can help more efficiently.

To me, it sounds like you want to adjust a count/value (of some sort) every hour. Rather than using tokens, I would probably make a separate hash for that value that uses the same item names as the first hash. This allows you to alter the data directly for each hash item, rather than pulling data out or a string of tokens, changing it, and putting it back in.

-genius_at_work

Joined: Apr 2006
Posts: 464
O
Fjord artisan
OP Offline
Fjord artisan
O
Joined: Apr 2006
Posts: 464
Ok, I'm sorry if I'm not clear.
The code that I showed should make clear what I mean.
I'm not trying to remove any token.
I'm trying to decrease a number (token 5), every hour with 1.

So:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) 158 $chr(9) token6 $chr(9) token7

Becomes after 1 hour:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) 157 $chr(9) token6 $chr(9) token7

Becomes after 2 hours:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) 156 $chr(9) token6 $chr(9) token7

The earlier posted code does that.
The problem is that it seems to skip items. Sometimes it does process all items, and sometimes it just skips some.
The code itself does what it should, it just doesn't run stable.

Should I maybe export all items to a text file, make the modification that I want, and load it back into a hash file?

Joined: Aug 2004
Posts: 7,252
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
The only thing I can think of, is that occasionally your variables get the wrong values. Try changing your variable names to something that wouldn't be used in another script.
Code:
alias reduce-tok5 {
  var %reduce-tok5.cnt = 1, %reduce-tok5.ttl = $hget(table,0).item
  while (%reduce-tok5.cnt <= %reduce-tok5.ttl) {
    hadd table %reduce-tok5.cnt $puttok($hget(table,%reduce-tok5.cnt),$calc($gettok($hget(table,%reduce-tok5.cnt),5,9) - 1),5,9)
    inc %reduce-tok5.cnt
  }
}


Try that. If that still has problems, then I'm out of ideas.

Joined: Apr 2006
Posts: 464
O
Fjord artisan
OP Offline
Fjord artisan
O
Joined: Apr 2006
Posts: 464
Ok, thank you for this.
I've reduced the workload, so instead of reducing that token on all items, it now only reduces the ones that match certain criteria (way less items).

I've also refreshed the hash files.
I dont think all tokens were the same, in each item. This might have something to do with it.

For now it's working fine, lets just see how it goes when the file gets bigger.
Anyway, thank you for now.


Link Copied to Clipboard