What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » [?] Pow... err, triggering some function on certain convo events?

Pages: (4): « First « 1 2 [ 3 ] 4 » Last »
[?] Pow... err, triggering some function on certain convo events?
Author: Message:
Shondoit
Full Member
***

Avatar
Hmm, Just Me...

Posts: 227
Reputation: 15
36 / Male / Flag
Joined: Jul 2006
RE: [?] Pow... err, triggering some function on certain convo events?
The first one is pretty easy too... But I don't have the time atm (school :S )
If you could post how you solved the second issue (y) ...
My scripts:                            [Image: shondoit.gif]
+ Timezone
+ Camelo
+ Multisearch
09-18-2006 05:57 AM
Profile PM Find Quote Report
phalanxii
Full Member
***


Posts: 146
Reputation: 5
32 / Male / Flag
Joined: Aug 2006
Status: Away
RE: [?] Pow... err, triggering some function on certain convo events?
Well, I haven't gone through all your code to know if I'm changing the right thing, but for functions, I think you can add .toLowerCase() to Token in some places so that the code reads:
code:
if (typeof(Math[Token.toLowerCase()])=="function" || eval("typeof("+Token+")=='function'")) {
   if (eval("typeof("+Token+")!='function'")) {
      Token = "Math." + Token.toLowerCase()
   }
   (...)
I'm not sure what to do for properties though, because I don't know where these are evaluated. :S

Also, it seems that sometimes the values are approximated before further functions are performed on them. For example, "sin(PI)" doesn't return "0", but "1.22460635382238E-16" (really close to 0). I guess this doesn't matter too much, but it would be good if it returned "0". :)

As for the degrees, I think this works for sin, cos and tan (not sure about asin, acos, atan and atan2 though):
code:
for (Index in Params) {
   Params[Index] = Params[Index].Calculate()
   if(Degrees & /\b(cos|sin|tan)\b/.test(Token)) Params[Index] *= Math.PI / 180
}
Degrees is a global boolean. (Y)

EDIT: Found where to change for properties. :)
code:
if (typeof(Math[Operands[Index].toUpperCase()]) != "undefined" && typeof(Math[Operands[Index]]) != "function") {
   Operands[Index] = Math[Operands[Index].toUpperCase()]
}
This time we use .toUpperCase because the properties are uppercase.

EDIT #2: I've also just noticed that the calculate function will parse "1 + 2 + 3" and "1+(2+3)" but not "1+ (2+3)". Any way to fix that? (It seems to not parse if there is a space before the open bracket.)

This post was edited on 09-18-2006 at 10:45 AM by phalanxii.
09-18-2006 08:02 AM
Profile PM Find Quote Report
Shondoit
Full Member
***

Avatar
Hmm, Just Me...

Posts: 227
Reputation: 15
36 / Male / Flag
Joined: Jul 2006
RE: [?] Pow... err, triggering some function on certain convo events?
Thanks for the reply, I'll look into it as soon as I get home...

I checked, and the properties are indeed all uppercase, and the functions all lowercase...
It's normal for JScript to begin lowercase and use an capital by a wordbreak, so I thought it wasn't possible...

And about the sin(PI), this is a limitation of JScript, if you type this in a random HTML file, it still evaluates to 1.2246063538223772e-16

About the space before the parenthese, I though I fixed that... :S

-edit- I did fix it, but I haven't updated the code... will update when I get home (schoolbell is ringing, gtg)

This post was edited on 09-18-2006 at 11:11 AM by Shondoit.
My scripts:                            [Image: shondoit.gif]
+ Timezone
+ Camelo
+ Multisearch
09-18-2006 11:09 AM
Profile PM Find Quote Report
Matti
Elite Member
*****

Avatar
Script Developer and Helper

Posts: 1646
Reputation: 39
32 / Male / Flag
Joined: Apr 2004
O.P. RE: [?] Pow... err, triggering some function on certain convo events?
quote:
Originally posted by Shondoit
It took a little longer than I expected, becuase the function weren't called correctly... But here it is anyway
It's very easy to use... Just call StringName.Calculate()
i.e.:
var Expression = Message.substr(0,4)
Result = Expression.Calculate()

It supports presedence, exponents, parenthese multiplication ( 3(4+1) = 15) and Math object functions and constants, for example, you can calculate a function like this:
Result = "3(1 + sin(PI))^2".Calculate()
or
var x = -4
Result = "-sqrt(abs(x))".Calculate()
Awesome. :|
I think if there's a need of a calculator script, you deserve to make it, not me. My tab placement just sucks, and it's not worth to release it. I am sure you can make a good script with just that one function. (y)

* Matti ends his crappy project. :P

This post was edited on 09-18-2006 at 06:36 PM by Matti.
Plus! Script Developer | Plus! Beta Tester | Creator of Countdown Live | Co-developer of Screenshot Sender 5

Found my post useful? Rate me!
09-18-2006 06:35 PM
Profile E-Mail PM Web Find Quote Report
Shondoit
Full Member
***

Avatar
Hmm, Just Me...

Posts: 227
Reputation: 15
36 / Male / Flag
Joined: Jul 2006
RE: [?] Pow... err, triggering some function on certain convo events?
This is the fixed code... It supports different angle types (Angle = "degree" or Angle = "radians" and even supports "grad")
It supports Mixed case functions (Only if it is a function of the Math object) and I fixed the space problem...

But Mattike, please go on, you can desgin the GUI, the scriptcommands, ...etc. I don't really have the time for it, if you need any help, add me to WLM (I speak Dutch (y))

code:
String.prototype.ToPostfix = function () {
   var Stack = ""
   var Token = ""
   var Result = ""
   for (var i = 0; i < this.length; i++) {
      Token = this.charAt(i)
      switch (Token) {
         case "(":
            Stack += "("
            break
         case ")":
            while (Stack.length > 0 && Stack.charAt(Stack.length - 1) != "(") {
               Result += Stack.charAt(Stack.length - 1)
               Stack = Stack.substring(0, Stack.length - 1)
            }
            Stack = Stack.substring(0, Stack.length - 1)
            break
         case "^": case "*": case "/": case "+": case "-":
            PopStack()
            break
         default:
            while (/[^()\^*/+-]/.test(this.charAt(i + 1)) && i < this.length) {
               Token += this.charAt(i++ + 1)
            }
            if (/\+|-/.test(this.charAt(i + 1))) {
               if (/e/i.test(this.charAt(i)) && i > 0 && /\d/.test(this.charAt(i - 1))) {
                  Token += this.charAt(i++ + 1)
                  while (/[^()\^*/+-]/.test(this.charAt(i + 1)) && i < this.length) {
                     Token += this.charAt(i++ + 1)
                  }
               }
            }
            if (this.charAt(i + 1) == "(") {
               try {
                  if (typeof(Math[Token.toLowerCase()])=="function" || eval("typeof("+Token+")=='function'")) {
                     if (eval("typeof("+Token+")!='function'")) {
                        Token = "Math." + Token.toLowerCase()
                     }
                     Token += this.charAt(i++ + 1)
                     var ParamToken = ""
                     var Parentheses = 0
                     while ((/[^)]/.test(this.charAt(i + 1)) || Parentheses > 0) && i < this.length) {
                        if (this.charAt(i + 1) == "(") Parentheses++; else if (this.charAt(i + 1) == ")") Parentheses--
                        ParamToken += this.charAt(i++ + 1)
                     }
                     var Params = ParamToken.split(/\s*,\s*/)
                     for (Index in Params) {
                        Params[Index] = Params[Index].Calculate()
                     }
                     Token += Params.join(",")
                     Token += this.charAt(i++ + 1)
                     if (/^Math\.(sin|cos|tan)\((.+)\)$/.test(Token)) {
                        var Func = "Math." + RegExp.$1 + "(" + RegExp.$2 + "*Math.PI"
                        if (/^degrees?$/i.test(Angle)){
                           Token = Func + "/180)"
                        } else if (/^grad$/i.test(Angle)) {
                           Token = Func + "/200)"
                        }
                     }
                     if (/^Math\.(a(?:sin|cos|tan2?))\((.+)\)$/.test(Token)) {
                        var Func = "Math." + RegExp.$1 + "(" + RegExp.$2 + ")/Math.PI"
                        if (/^degrees?$/i.test(Angle)){
                           Token = Func + "*180"
                        } else if (/^grad$/i.test(Angle)) {
                           Token = Func + "*200"
                        }
                        Token = Token.Calculate()
                     }
                  } else {
                     PopStack("*")
                  }
               } catch (e) {
                  return undefined
               }
            }
            Result += "\x01" + Token + "\x01"
            break
      }
   }
   while (Stack.length > 0) {
      Result += Stack.charAt(Stack.length - 1)
      Stack = Stack.substring(0, Stack.length-1)
   }
   return Result.replace(/\s/g, "")
   
   function PopStack (Operator) {
      if (Operator == undefined) Operator = Token
      while (Stack.length > 0 && ((/[\^*/+-]/.test(Operator) && /[\^]/.test(Stack.charAt(Stack.length - 1))) || (/[*/+-]/.test(Operator) && /[*/]/.test(Stack.charAt(Stack.length - 1))) || (/[+-]/.test(Operator) && /[+-]/.test(Stack.charAt(Stack.length - 1))))) {
         Result += Stack.charAt(Stack.length - 1)
         Stack = Stack.substring(0, Stack.length - 1)
      }
      Stack += Operator
   }
}
String.prototype.CalculatePostfix = function () {
   var Stack = new Array()
   var Token = ""
   for (var i = 0; i < this.length; i++) {
      Token = this.charAt(i)
      if (/[^\^*/+-]/.test(Token)) {
         while (/[^\x01]/.test(this.charAt(i + 1)) && i < this.length) {
            Token += this.charAt(i++ + 1)
         }
         Token += this.charAt(i++ + 1)
         if (/\+|-/.test(this.charAt(i + 1))) {
            if (/e/i.test(this.charAt(i)) && i > 0 && /\d/.test(this.charAt(i - 1))) {
               Token += this.charAt(i++ + 1)
               while (/[^()\^*/+-]/.test(this.charAt(i + 1)) && i < this.length) {
                  Token += this.charAt(i++ + 1)
               }
            }
         }
         if (/\x01(.+)\x01/.test(Token)) {
            var Operands = RegExp.$1.split(/\x01\x01/)
            for (Index in Operands) {
               if(eval("typeof("+Operands[Index]+")=='undefined'")) {
                  if (typeof(Math[Operands[Index].toUpperCase()]) != "undefined" && typeof(Math[Operands[Index]]) != "function") {
                     Operands[Index] = Math[Operands[Index].toUpperCase()]
                  }
               }
            }
            Stack = Stack.concat(Operands)
         } else {
            return undefined
         }
      } else {
         if (Stack.length >= 2) {
            if (Token == "^") {
               Stack[Stack.length - 2] = Math.pow(eval(Stack[Stack.length - 2]), eval(Stack[Stack.length - 1]))
            } else {
               Stack[Stack.length - 2] = eval(eval(Stack[Stack.length - 2]) + Token + eval(Stack[Stack.length - 1]))
            }
            Stack.pop()
         }
      }
   }
   try {
      return eval(Stack[0])
   } catch (e) {
      return undefined
   }
}
String.prototype.Calculate = function () {
    var Infix = this.replace(/\s/, "")
    var Postfix = Infix.ToPostfix()
    if (Postfix != undefined) return Postfix.CalculatePostfix()
}
My scripts:                            [Image: shondoit.gif]
+ Timezone
+ Camelo
+ Multisearch
09-18-2006 08:07 PM
Profile PM Find Quote Report
phalanxii
Full Member
***


Posts: 146
Reputation: 5
32 / Male / Flag
Joined: Aug 2006
Status: Away
RE: [?] Pow... err, triggering some function on certain convo events?
Awesome! This is just what I need. :) For those of you who want it, here's a little code that I made for this:
code:
var Angle = "Radian";

function OnEvent_ChatWndEditKeyDown(ChatWnd, KeyCode, CtrlKeyDown, ShiftKeyDown){
   if(KeyCode == 116 && !CtrlKeyDown && !ShiftKeyDown) {
      var x = ChatWnd.EditText.substring(ChatWnd.EditText_GetCurSelStart(), ChatWnd.EditText_GetCurSelEnd()).Calculate()
      if(x != undefined) {
         ChatWnd.EditText_ReplaceSel(x)
      }
   }
}
This is to add to Shondoit's calculator so that you can use it in your chats. All you have to do, is type your expression, highlight it and press F5. Also, you can change Angle to "Radian", "Degree", or "Grad" (as seen in Shondoit's script). :D

Also, Shondoit you might want to check:
code:
if (/^Math\.(a(?:sin|cos|tan2?))\((.+)\)$/.test(Token)) {
   var Func = "Math." + RegExp.$1 + "(" + RegExp.$2 + ")/Math.PI"
   if (/^degrees?$/i.test(Angle)){
      Token = Func + "*180"
   } else if (/^grads?$/i.test(Angle)) {
      Token = Func + "*200"
   }
   [b]Token = Token.Calculate()[/b]
}
When I debug trace it, it seems that this loops because the angle setting is not changed. Perhaps change this to Token = eval(Token)?

-----

EDIT: Thought I might just add this in. If you want to make your own custom calculator functions, add the following code inside the script (you will need to match where it goes):
code:
      Token = eval(Token)
   }
else if (typeof(Custom[Token.toLowerCase()])=="function" || eval("typeof("+Token+")=='function'")) {
   if (eval("typeof("+Token+")!='function'")) {
      Token = "Custom." + Token.toLowerCase()
   }
   Token += this.charAt(i++ + 1)
   var ParamToken = ""
   var Parentheses = 0
   while ((/[^)]/.test(this.charAt(i + 1)) || Parentheses > 0) && i < this.length) {
      if (this.charAt(i + 1) == "(") Parentheses++; else if (this.charAt(i + 1) == ")") Parentheses--
      ParamToken += this.charAt(i++ + 1)
   }
   var Params = ParamToken.split(/\s*,\s*/)
   for (Index in Params) {
      Params[Index] = Params[Index].Calculate()
   }
   Token += Params.join(",")
   Token += this.charAt(i++ + 1)
}
else {
   PopStack("*")
}
If you know how to shorten this into the code, that would be great (Y).

Next, you define your own functions like this (these are a few of mine):
code:
var Custom = {
   "base" : function (Number, FromBase, ToBase) {
      if (Number != Math.floor(Number) || FromBase != Math.floor(FromBase) || ToBase != Math.floor(ToBase)) return undefined
      Number = String(Number)
      if (FromBase < 2) FromBase = 2
      if (FromBase > 10) FromBase = 10
      if (ToBase < 2) ToBase = 2
      if (ToBase > 36) ToBase = 36
      var Internal = 0
      var Character
      for (var i = Number.length - 1; i >= 0; i--) {
         Character = Number.charAt(i)
         if (Character >= FromBase) return undefined
         Internal += Character * Math.pow(FromBase, Number.length - 1 - i)
      }
      var Result = ""
      while (Internal > 0) {
         if (Internal % ToBase > 9) Result = String.fromCharCode(Internal % ToBase + 55) + Result
         else Result = Internal % ToBase + Result
         Internal = Math.floor(Internal / ToBase)
      }
      return Result
   },
   "choose" : function (Total, Choose) {
      if (Total == Choose || Total == 0 || Choose == 0) return 1
      if (Choose > Total) return 0
      Result = eval(Factorial(Total) + "/(" + Factorial(Total - Choose) + "*" + Factorial(Choose) + ")")
      return Result
      function Factorial (Number) {
         var Factorial = ""
         for (var i = 1; i < Number; i++) {
            Factorial += i + "*"
         }
         Factorial += Number
         return Factorial
      }
   },
   "root" : function (Base, Root) {
      if (Root == undefined) Root = 2
      return Math.pow(Base, 1 / Root)
   }
}
These functions work normally, like "choose(5,4)" will return 5. (Just if you wanted to know, "base" converts bases, "choose" finds the number of ways to choose k objects from n (max: 170, otherwise it returns infinity), and "root" finds the nth root of a number.)

-----

EDIT #2: I also noticed that you can't type negative numbers in your expression...?

This post was edited on 09-19-2006 at 02:57 AM by phalanxii.
09-18-2006 11:15 PM
Profile PM Find Quote Report
Shondoit
Full Member
***

Avatar
Hmm, Just Me...

Posts: 227
Reputation: 15
36 / Male / Flag
Joined: Jul 2006
RE: [?] Pow... err, triggering some function on certain convo events?
At the first piece: Yes indeed, it loops infinetly :S
At the second piece: No need to change my code, it already supports custom functions... Just write a function in the script, like this:
code:
function Root (Base, Root) {
   if (Root == undefined) Root = 2
   return Math.pow(Base, 1 / Root)
}
Debug.Trace("4".Calculate())

At the third piece: True, in normal maths the minus is used as negation and subtraction, I have to take a look at how to know the difference between the two... (After I get back from school again)
My scripts:                            [Image: shondoit.gif]
+ Timezone
+ Camelo
+ Multisearch
09-19-2006 05:20 AM
Profile PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15517
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: RE: [?] Pow... err, triggering some function on certain convo events?
quote:
Originally posted by phalanxii
Next, you define your own functions like this (these are a few of mine):
code:
var Custom = {
   "base" : function (Number, FromBase, ToBase) {
             ...much stuff...
      }


objectname.toString([radix])
(convert to a base)

and

parseInt(numString, [radix])
(convert from a base)

?

This post was edited on 09-19-2006 at 06:37 AM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
09-19-2006 06:34 AM
Profile PM Find Quote Report
phalanxii
Full Member
***


Posts: 146
Reputation: 5
32 / Male / Flag
Joined: Aug 2006
Status: Away
RE: RE: RE: [?] Pow... err, triggering some function on certain convo events?
quote:
Originally posted by CookieRevised
quote:
Originally posted by phalanxii
Next, you define your own functions like this (these are a few of mine):
code:
var Custom = {
   "base" : function (Number, FromBase, ToBase) {
             ...much stuff...
      }


objectname.toString([radix])
(convert to a base)

and

parseInt(numString, [radix])
(convert from a base)

?


Oh, cool. Never knew about that :$. Thanks, Cookie!



PS. Using Shondoit's way to make functions is much better and easier now... :)

EDIT: Here are my new and improved functions. :D
code:
function base (x, fromBase, toBase) {
   return parseInt(x, fromBase).toString(toBase).toUpperCase()
}
function choose (n, k) {
   if (n != Math.floor(n) || k != Math.floor(k) || n < 0 || k < 0 || k > n) return 0
   if (n == k || n == 0 || k == 0) return 1
   if (n > 170) return Number.POSITIVE_INFINITY
   return eval(Factorial(n) + "/(" + Factorial(n - k) + "*" + Factorial(k) + ")")
   function Factorial (x) {
      var Factorial = ""
      for (var i = 1; i < x; i++) {
         Factorial += i + "*"
      }
      Factorial += x
      return Factorial
   }
}
function gcd (a, b) {
   if (a != Math.floor(a) || b != Math.floor(b)) return undefined
   if (b == 0) return Math.abs(a)
   else return Math.abs(gcd(b, a % b))
}
function isprime (n) {
   if (n != Math.floor(n) || n < 0) return undefined
   if (n == 0 || n == 1) return false
   if (n == 2 || n == 3) return true
   if (n % 2 == 0 || n % 3 == 0) return false
   for (var k = 1; 6 * k <= Math.sqrt(n); k++) {
      if (n % (6 * k - 1) == 0 || n % (6 * k + 1) == 0) return false
   }
   return true
}
function lcm (a, b) {
   if (a != Math.floor(a) || b != Math.floor(b)) return undefined
   return Math.abs(a * b / gcd(a, b))
}
function root (b, n) {
   if (n == undefined) n = 2
   return Math.pow(b, 1 / n)
}

This post was edited on 09-20-2006 at 09:12 AM by phalanxii.
09-19-2006 06:48 AM
Profile PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15517
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: [?] Pow... err, triggering some function on certain convo events?
Note that with those functions, the operands can be negative too. Returning "undefined" when they are negative is not correct.

eg: even the result (eg: cgd) can be negative.......

PS: 2 and 3 are also prime numbers, your functions says it is not (n % 2 = 0).

In many books this isn't talked about (out of convenience, to avoid discussion, because they deal with lower grade maths, etc...), but the fact remains that it can and that they exist. Hence why you usually see "the greatest common divered of two positive integers" and not "greatest common divider of two integers" as the latter also requires the book or paper to explain those...

;)

This post was edited on 09-19-2006 at 11:01 AM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
09-19-2006 10:50 AM
Profile PM Find Quote Report
Pages: (4): « First « 1 2 [ 3 ] 4 » Last »
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On