[?] Pow... err, triggering some function on certain convo events? |
Author: |
Message: |
Shondoit
Full Member
Hmm, Just Me...
Posts: 227 Reputation: 15
36 / /
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 )
If you could post how you solved the second issue ...
|
|
09-18-2006 05:57 AM |
|
|
phalanxii
Full Member
Posts: 146 Reputation: 5
32 / /
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.
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.
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 |
|
|
Shondoit
Full Member
Hmm, Just Me...
Posts: 227 Reputation: 15
36 / /
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...
-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.
|
|
09-18-2006 11:09 AM |
|
|
Matti
Elite Member
Script Developer and Helper
Posts: 1646 Reputation: 39
32 / /
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.
* Matti ends his crappy project.
This post was edited on 09-18-2006 at 06:36 PM by Matti.
|
|
09-18-2006 06:35 PM |
|
|
Shondoit
Full Member
Hmm, Just Me...
Posts: 227 Reputation: 15
36 / /
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()
}
|
|
09-18-2006 08:07 PM |
|
|
phalanxii
Full Member
Posts: 146 Reputation: 5
32 / /
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).
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 .
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 |
|
|
Shondoit
Full Member
Hmm, Just Me...
Posts: 227 Reputation: 15
36 / /
Joined: Jul 2006
|
RE: [?] Pow... err, triggering some function on certain convo events?
At the first piece: Yes indeed, it loops infinetly
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)
|
|
09-19-2006 05:20 AM |
|
|
CookieRevised
Elite Member
Posts: 15517 Reputation: 173
– / /
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 |
|
|
phalanxii
Full Member
Posts: 146 Reputation: 5
32 / /
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. 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 |
|
|
CookieRevised
Elite Member
Posts: 15517 Reputation: 173
– / /
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 |
|
|
Pages: (4):
« First
«
1
2
[ 3 ]
4
»
Last »
|
|
|