mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Jan 2011
Posts: 4
C
Self-satisified door
OP Offline
Self-satisified door
C
Joined: Jan 2011
Posts: 4
Hi,

I need your science guys !
I need advice on how to "build" a script.

I have two parameters to evaluate : Rating AND Ranking

Let's say i have Names who received both Rating and Ranking Value.
Now let's say i have gifts to give depending of a specific rule for each gift... Twisted isn't it ? :o)

For exemple :

To obtain Gift1, people needs to have rating>0 and ranking>0 (means every participant can have Gift1)
To obtain Gift2, people needs to have rating>5 and ranking>50
To obtain Gift3, people needs to have rating>5 and ranking>100
To obtain Gift4, people needs to have rating>6 and ranking>20
To obtain Gift5, people needs to have rating>6 and ranking>500
To obtain Gift6, people needs to have rating>6 and ranking>1000
And so on...

Now we have poeple's name with both value (rating and ranking)
Name1 : Rating=5.2 and Ranking=153
Name2 : Rating=6.5 and Ranking=70
Name3 : Rating=8 and Ranking=300

So Name1 will win gift1 and gift2 and gift3
Name2 will win gift1 and gift2 and gift4 (!!!but not gift3)
Name3 will win gift1 and gift2 and gift3 and gift4

My previous idea, maybe stupid was to make :

*Hash table : rating.hsh with item=name and data=rating
name1 - 5.2
name2 - 6.5
name3 - 8

*Hash table : ranking.hsg with item=name and data=ranking
name1 - 153
name2 - 70
name3 - 300

*ini files : gift.ini
[gift]
rating_0_to_5=gift1
rating_sup_to_5=gift1;gift2
rating_sup_to_6=gift1;gift2;gift3;gift4;gift5
ranking_0_to_20=gift1
ranking_0_to_50=gift1;gift4;gift2
ranking_0_to_100=gift1;gift4;gift2
ranking_0_to_500=gift1;gift4;gift2;gift3
ranking_0_to_1000=gift1;gift4;gift2;gift3;gift5
ranking_sup_to_1000=gift1;gift2;gift3:gift4;gift5;gift6

Now i'd like to give rating and ranking of a name to the script and script tells me which gift i have to offer to this name.

Thx for advance to all people who will take time to answer me.

PS : Sorry for my english but i am a foreigner ;o)

Conscience.

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
Quote:
Now i'd like to give rating and ranking of a name to the script and script tells me which gift i have to offer to this name.
In what way do you want the feed the data to the script?

Individually, like an input prompt asking you to enter rating and ranking, or a command like "/gifts <rating> <ranking>", so the result is printed to the screen or send to a channel as a message?
Or as batch, say a text file with a list of names, ratings and rankings, having mIRC create another text file with the results?

Quote:
Now we have poeple's name with both value (rating and ranking)
Name1 : Rating=5.2 and Ranking=153
Name2 : Rating=6.5 and Ranking=70
Name3 : Rating=8 and Ranking=300
Is this an example, or does such a file already exist? (It could be used for the "batch".)

In what format do you do/plan to store the gift rules (does a file/list already exist, or are you free to create it in a specific format?

What's the desired output format? A line of digits representing gift numbers, e.g. "1,2,4"? A complete phrase like "Name1 won 3 Gifts: gift1, gift2, and gift 4."? Something else?

The calculation itself would be unproblematic as per gift only two conditions have to be met. As long as you won't have thousands of names and thousands of rules to process, a simple loop (per name) over the rules would suffice to accumulate the result, without a need for hash tables, /filter, or the like.

Pseudocode:
Code:
while (lines of a user-data list) {
  var %name <name>, %rating <rating>, %ranking <ranking>, %gifts

  while (lines of a gift-rules list) {
    var %giftNo <gift number>, %min_rating <required rating>, %min_ranking <required ranking>

    if (%rating > %min_rating) && (%ranking > %min_ranking) { add Gift %giftNo to %gifts }
    continue with next rule
  }

  store result %gifts for name %name
  continue with next name
}

Joined: Jan 2011
Posts: 4
C
Self-satisified door
OP Offline
Self-satisified door
C
Joined: Jan 2011
Posts: 4
Hi !

Thanks for your answer and for the time you took for me !

In my craziest dreams here is how i'd like the things to work (but feel free to give advice if i'am going in a wrong direction) :

Well yet the name data are stored in 2 hash table : rating.hsh and ranking.hsh.
I decided to use hash table because they are very fast.
For both hash table item = name and data = value.
Note : when name is longer than 1 word, text is separated with dots, ex : jean.bernard.durand.
The data are "auto" added by users with an alias like this :

Code:
/addname <name.separated.with.dot> <rating> <ranking>
making this :
alias addname {
hadd rating $1 $2
hadd ranking $1 $3 
}


This is for the storage of the rating/ranking data

Now for the "rules" for the gifts i didn't do anything yet, was just thinking of creating an .ini file like this :

Code:
[gift]
rating_0_to_5=gift1
rating_sup_to_5=gift1;gift2
rating_sup_to_6=gift1;gift2;gift3;gift4;gift5
ranking_0_to_20=gift1
ranking_0_to_50=gift1;gift4;gift2

and so on...


But i think this was is not really clever... maybe have you a better idea ?

My rules are built like that :
gift 1 only if rating>5 and ranking>100
gift 2 only if rating>6 and ranking>500

I wish i can update rules and add new rules easily.

Note :If i decide to add new parameters like <year of birth (xxxx)> will it change the script a lot or is it easily doable ? O do i have to decide it now ?

Ok for the data storage and config.

Now the desired output format would be :
Code:
/check <name>
and the script would return :
<name> will be given : gift_x;gift_y;gift_z

I want gift to be separated by ";"

That's it ! Do u need some more precisions ?

Again thank a lot for your precious help !

Have a nice day.

Conscience.

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
Personally, I'd prefer to store the data in a single, physical file, in a chart format. As long as you're going to calculate one user a time, there's no noticeable performance gain with hash tables.
Even for batch calculation, sorting of lists etc you could load the file into memory as required, or use other fast means like the /filter command.
But if you prefer the two hash tables - fine with me. smile

However, I would'nt store the gift rules in your current way ("categories" with one or more gifts assigned each). Adding/changing/removing rules would mean to update multiple lines and could become tricky if your set of rules grows. Again, I'd prefer a more basic form: a chart.

As each gift has to meet some criteria (rating, ranking, (age), (...)), and as long as the general idea is "you have to match ALL critera of a gift to get it" and a user has to have AT LEAST xxx to match a criterion, why not create a file like:
Originally Posted By: giftrules.ini

[rules]
1=0 0
2=5 50
3=5 100
4=6 20
5=6 500
6=6 1000
The item name is the gift number, the data part contains all threshold values: the first column the required rating, the second column the required ranking. You can add more columns for more criteria as you like in the future, and the chart is easy to maintain.

A script could now while-loop over all rules with $readini. But as you like to work with hash tables, you can load this ini file into a table with
Code:
alias loadrules {
  if ($hget(gift.rules)) { hfree gift.rules }
  hmake gift.rules
  hload -i gift.rules giftrules.ini rules
}


Now the main part. Below's a basic commented outline for the check-alias. I hope you get the idea - feel free to ask though smile
You could also add some general checks to it:
- Tables "gift.rules", "rating" and "ranking" loaded?
- Parameter (user) given at all?
- User listed at all?
Code:
alias check {
  ; set an empty variable to store matching gifts, set rule-No counter to 1
  var %gifts, %ruleNo = 1

  ; loop all rules
  while ($hget(gift.rules,%ruleNo) != $null) {

    ; $gettok($v1,1,32) = required rating to get this gift, $gettok($v1,2,32) = required ranking 
    ; (if you create more columns, create variables accordingly)
    var %rule.rating = $gettok($v1,1,32), %rule.ranking = $gettok($v1,2,32)

    ; compare user's values to required values:
    ; "if <rating of name> is bigger than <required rating> AND <ranking of name> is bigger than <required ranking>"
    ; (if you create more columns, add conditions accordingly)
    if ($hget(rating,$1) > %rule.rating) && ($hget(ranking,$1) > %rule.ranking) {

      ; all conditions met: add the current gift to the string of matching gifts
      var %gifts = $addtok(%gifts,gift_ $+ %ruleNo,59)
    }

    ; continue with next rule
    inc %ruleNo
  }

  ; all rules processed: output result
  ECHO -a $1 will be given : %gifts
}


For testing, I created some users with your /addname command:
Code:
/addname Name1 5.2 153
/addname Name2 6.5 70
/addname Name3 8 300
/addname Name4 0.8 1000
/addname Name5 9 25

And my /check results are:
Quote:
Name1 will be given : gift_1;gift_2;gift_3
Name2 will be given : gift_1;gift_2;gift_4
Name3 will be given : gift_1;gift_2;gift_3;gift_4
Name4 will be given : gift_1
Name5 will be given : gift_1;gift_4

Last edited by Horstl; 14/01/11 12:42 AM.
Joined: Jan 2011
Posts: 4
C
Self-satisified door
OP Offline
Self-satisified door
C
Joined: Jan 2011
Posts: 4
Wow thanks a lot !!
It works great !!! laugh

Now I have 2 questions about this script !

First Question :

If I wanna change the rules thingy like that :

Code:
[rules]
book=0 0
ball=5 50
DVD=5 150


Is the "while" loop still working ?

Code:
while ($hget(gift.rules,%ruleNo) != $null) 


Is %ruleNo (=1,2,3,4...) refering to the "1=" or refering to the first line then second line and so on... ?

Second question :

Is it possible to "upgrade" the script like that :

Code:
giftrules.ini

[rules_fr]
book=0 0
ball=5 50
DVD=5 150

[rules_uk]
book=0 0
ball=4 40
DVD=6 250

[rules_de]
book=0 0
ball=3 32
DVD=7 250


Then people would be added like that : /addname Name1.country <rating> <ranking>
ex: /addname georges.eastwood.fr 5.3 156

And when the check comes script would act like this :
Code:
if fr isin <name_checked> then 
           compares name rating and ranking to [rules_fr] and give result
if uk isin <name_checked> then 
           compares name rating and ranking to [rules_uk] and give result


Sorry for not giving this idea first but I didn't know the script will progress that fast thanks to you blush

Have a nice day and thank you again.

Conscience.

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
Quote:
Is %ruleNo (=1,2,3,4...) refering to the "1=" or refering to the first line then second line and so on... ?
Take a moment to meditate on /help $hget smile

$hget(table,item) will return the data for the item of that name.
So far your gift names were consecutive numbers - a numerical loop could access each gift directly: to access the Nth item, just access item with name N.

As you now want the gift names (items) to be something else, the loop has first to compute the name of the Nth item:
$hget(table,N).item to return the name of the Nth item, then either $hget(table,itemname) or $hget(table,N).data to acces it's data.
Also note that hash tables inherently are unsorted: the Nth item isn't necessarily the first item of your ini file.
Code:
alias check {
  var %gifts, %ruleNo = 1

  ; loop for Nth rule
  while ($hget(gift.rules,%ruleNo).item != $null) {
    ; store item name (giftname) and get it's data (string of gift conditions)
    var %giftname = $v1, %data = $hget(gift.rules,%ruleNo).data

    ; parse that string, check conditions
    var %required.rating = $gettok(%data,1,32), %required.ranking = $gettok(%data,2,32)
    if ($hget(rating,$1) > %required.rating) && ($hget(ranking,$1) > %required.ranking) {

      ; all conditions met: add the current gift to the string of gifts-to-get
      var %gifts = $addtok(%gifts,%giftname,59)
    }

    ; continue with next rule
    inc %ruleNo
  }

  ; all rules processed: output result with the gifts sorted alphanumerically
  ECHO -a $1 will be given : $sorttok(%gifts,59,a)
}



Regarding your second question: there are several approaches to it...
One question is whether to store the country data in the name of the user, or store it as a separate value (like the rating/ranking values in separate tables).
Then, whether to add "country" simply as another condition-to-meet (being a new column of the rules chart) - or to use separate ini sections. For the latter, the script should load each section to a separate table.
As your script is for checking users individually, these questions don't matter in regard to performance, but in regard to useability and data management. If you have problems to anticipate the pros and cons of each layout, why not try out in actual code? smile


Example, for the case that you decide to store the country as a part of the username, and opt for separate ini topics
Code:
/addname Name1.fr 3 100
/addname Name2.fr 5.2 100
/addname Name3.fr 8 60
/addname Name1.uk 7 50
/addname Name2.uk 8.5 600
/addname Name3.uk 2 60

Originally Posted By: giftrules.ini

[giftrules_fr]
book_fr=0 0
ball=4 50
DVD_fr=6 50
Apple=2 80

[giftrules_uk]
book_en=0 0
ball=4 60
DVD_en=6 250
Banana=8 10

[giftrules_de]
book=0 0
ball=3 32
DVD=7 250


Code:
alias loadrules {
  ; loop all ini topics 
  var %n = 1
  while ($ini(giftrules.ini,%n)) {
    var %topic = $v1
    ; load topic into a hash table of the same name
    if ($hget(%topic)) { hfree %topic }
    hmake %topic
    hload -i %topic giftrules.ini %topic
    inc %n
  }
}

alias check {
  ; "country" is the last dot-delimited token of the username 
  var %country = $gettok($$1,-1,46)
  var %gifts, %ruleNo = 1

  ; loop all the rules of the table of that country 
  var %table = giftrules_ $+ %country
  while ($hget(%table,%ruleNo).item != $null) {
    ; store item name (giftname) and get it's data (string of gift conditions)
    var %giftname = $v1, %data = $hget(%table,%giftname)

    ; parse that string, check conditions
    var %required.rating = $gettok(%data,1,32), %required.ranking = $gettok(%data,2,32)
    if ($hget(rating,$1) > %required.rating) && ($hget(ranking,$1) > %required.ranking) {

      ; all conditions met: add the current gift to the string of gifts-to-get
      var %gifts = $addtok(%gifts,%giftname,59)
    }

    ; continue with next rule
    inc %ruleNo
  }

  ; all rules processed: output result with the gifts sorted alphanumerically
  ECHO -a $gettok($1,1--2,46) from %country will be given : $sorttok(%gifts,59,a)
}

Result:
Quote:
Name1 from fr will be given : Apple;book_fr
Name2 from fr will be given : Apple;ball;book_fr
Name3 from fr will be given : ball;book_fr;DVD_fr
Name1 from uk will be given : ball;book_en
Name2 from uk will be given : ball;Banana;book_en;DVD_en
Name3 from uk will be given : book_en


Joined: Jan 2011
Posts: 4
C
Self-satisified door
OP Offline
Self-satisified door
C
Joined: Jan 2011
Posts: 4
Well everything is fine for me !!!! grin

Thank you very much for the help.

I'll come back later with maybe another idea... who knows crazy



Link Copied to Clipboard