Calculadora 2

by Thy forked from Black Graph (diff: 1298)
code is dirty ^^
you can: sin() cos() tan() x ( ) + - * / ^ pi ² ³
♥0 | Line 562 | Modified 2010-07-31 06:06:37 | MIT License
play

ActionScript3 source code

/**
 * Copyright Thy ( http://wonderfl.net/user/Thy )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/5wOq
 */

// forked from Thy's Black Graph and http://wonderfl.net/c/jW4u
// code is dirty ^^
// you can: sin() cos() tan() x ( ) + - * / ^ pi ² ³
package 
{
    import flash.events.KeyboardEvent;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    
    //
    //[SWF(width=465,height=465,frameRate=465, backgroundColor="#000000")]
    
    /**
     * ...
     * @author Thi
     */
    public class Main extends Sprite 
    {
        // Storage for all calculators (havent added to functionaly add more caolculators, yet)
        private var calculators:Vector.<Calculadora> = new Vector.<Calculadora>(1)
        
        // Storage for x, y, and others custom values. ["x", 0,"y",0,...]
        private var libraly:Array
        
        // temp var calculator
        private var calc:Calculadora
        
        // Result TF
        private var TF:TextField 
        
        private var delay:int
        
        
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            
            // create the library. Variables who will be used in some calculator who uses that library
            libraly = ["x", 1, "y", 2, "pi", Math.PI]
            
            // Text for result
            TF = new TextField()
            TF.autoSize = TextFieldAutoSize.LEFT
            TF.y = 40
            TF.text = "Result"
            stage.addChild(TF)
            
            // create a calculator
            calc = new Calculadora(libraly, "1 + 2 * 3 ^ 4")//".1*x^3-x*4+.1x^2-(.0045*x^4)", "y")
            addChild(calc)
            
            stage.addEventListener(KeyboardEvent.KEY_DOWN, changed)
            stage.addEventListener(Event.ENTER_FRAME, ef)
           
            
            // listener
           
            
            // make an first run for the calculator, just to show some result at the beggining
            justShowResult()
            
        }
        
        private function ef(e:Event):void
        {
            if(++delay == 0)
            {
                calc.convert() // converts the expression for a 'readable' expression
                calc.convert_to_rpn() // convert the expression for a way to calculate more easily
                calc.rpn() // just calculate (+,-,*,/,^)
                TF.text = String(calc.Return) 
            }

            
            
        }

        
        // you can ignore this function
        private function justShowResult():void
        {
            calc.convert()
            calc.convert_to_rpn()
            calc.rpn()
            TF.text = String(calc.Return)
        }
        
        private function changed(e:KeyboardEvent):void
        {
            delay = -5 
        }
        
        
    }
}
import flash.events.KeyboardEvent;
        
        
       

//package  
//{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TextEvent;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    /**
     * ...
     * @author Thi
     */
    /*public*/ class Calculadora extends Sprite
    {
        // public variables
        public var TF:TextField
        public var t:String
        public var libraly:Array
        public var Return:Number
        //
        public var upd:Boolean // updated the expression
        public var pos:Boolean // updated the 'result text', then must update the position
        
        // result TF
        public var tf:TextField
        public var r:String
        
        // '=' text
        private var eq:Sprite
        
        // text stuff
        private var format:TextFormat
        
        public function Calculadora(libraly:Array = null, t:String = null) 
        {
            this.libraly = libraly; // libraly, used for variables, example 'x = 0' or 'hello = 1'
            this.t = t; // the input expression, when this calss is called
            
            // init format
            format = new TextFormat("Arial", 20)
            
            // init text
            TF = new TextField()
            TF.defaultTextFormat = format
            TF.autoSize = TextFieldAutoSize.LEFT
            TF.type = "input"
            TF.border = true
            TF.borderColor = 0xC0C0C0
            TF.textColor = 0
            TF.text = t
            //TF.text = "IUHDSOIUDSANMOIDJASDIOSAMOM"
            //
            TF.x = 10
            TF.y = 10
            
            // add to Sprite content
            this.addChild(TF)
            // add text change listener
            
            // sets 'updated' to false
            upd = false
        }
        
        
        
        
        
        // RPN calculation
        
        // storage the elements when converting
        private var ele:Array
        private var num:Array // used for sotage big numbers or words (so 'HI' wont be storage as 'H','I', but "HI")
        
        // int for looping process
        private var i:int, j:int
        
        //
        private var length:int
        private var char:String, last:String
        
        // function who convert 'strings' to 'expressions'
        public function convert():void
        {            
            // clear arrays and integers and errorPreventing (Parentesis stuff)
            ele = []
            num = []
            i = j = 0
            preventError = false
            // setup length
            t = TF.text
            length = t.length
            
            while (i < length)
            {
                
                char = t.charAt(i)
                
                
                if (Number(char) || char == "0")
                {
                    // lats char is equal to the last char from elements
                    last = ele[ele.length - 1]
                    if (last == ")")
                    {
                        // push an multiplication (* symbol)
                        ele.push("*") 
                    }
                    //
                    j = i
                    while (Number(char) || char == "," || char == "." || char == "0") 
                    {
                        num.push(char)
                        ++j
                        char = t.charAt(j)
                    }
                    // so the '2 char or more' number has been 'built'
                    // add the 'big number' to the array
                    ele.push(num.join(""))
                    num = [] // clear
                    // the loop continues
                    i = j - 1
                    j = 0 // clear j
                } else if (char == "*" || char == "+" || char == "-" || char == "/" || char == "^") 
                {
                    ele.push(char)
                } else if (char == "." || char == ",")
                {
                    // create a big number, for example: .2 -> 0.2
                    num.push("0")
                    num.push(".")
                    //
                    j = i
                    if (Number(char) || char == "0")
                    {
                        while (Number(char) || char == "0")
                        {
                            num.push(char)
                            ++j
                            char = t.charAt(j)
                        }
                        // 'big number' ready
                        // make the array became a single 'number', then add it to elements
                        ele.push(num.join(""))
                        // keep looping..
                        i = j-1
                        // clear
                        num = []
                        j = 0
                    }
                    
                } else if (char == "(" || char == "[" || char == "{")
                {
                    preventError = true
                    // take the last element
                    last = ele[ele.length-1]
                    if (last != "+" && last != "-" && last != "*" && last != "/" && last != "^" && last != "undefined" && last != null && last != "sin" && last != "cos" && last != "tan") 
                    {
                        // add an multiplication
                        ele.push("*")
                    }
                    // then finnaly add the parentesis
                    ele.push("(")
                } else if (char == "²")
                {
                    ele.push("^")
                    ele.push("2")
                } else if (char == "³")
                {
                    ele.push("^")
                    ele.push("3")
                    
                } else if (char == ")" || char == "]" || char == "}")
                {
                    ele.push(")")
                    // so.. convert every ([{}]) -> ((()))
                } else if (char != " ")
                {
                    last = ele[ele.length -1]
                    if (last != "+" && last != "-" && last != "*" && last != "/" && last != "^" && last != "undefined" && last != "(" && last != "[" && last != "{" && last != null && last != "²" && last != "³" ) 
                    {
                        // add an multiply
                        ele.push("*")
                    }
                    j = i
                    while (char != "," && char != "." && char != "+" && char != "-" && char != "*" && char != "/" && char != "^" && char != "(" && char != "[" && char != "{" && char != ")" && char != "]" && char != "}" && char != " " && char != null && char != "undefined" && char != "" && char != "²" && char != "³") 
                    {
                        num.push(char)
                        ++j;
                        char = t.charAt(j)
                    }
                    // so the 'big word' has been formed. and then pushed at elements.
                    
                    // but before that see if its angle relactioned
                    var temp:String = num.join("")
                    if (temp == "sen" || temp == "seno")
                    {
                        temp = "sin"
                    } else if (temp == "cosseno")
                    {
                        temp = "cos"
                    } else if (temp == "tangent" || temp == "tangente" || temp == "tgt" || temp == "tg")
                    {
                        temp = "tan"
                    }
                    ele.push(temp)
                    // clear
                    num = []
                    temp = ""
                    // keep loopin'
                    i = j-1
                }
                ++i
            }
        }
        // so after this function, i have the expression more organized
        // but still an array with strings, like: [1,+,1] or [1,-,VAR,+,20,*,(,aVALUE,)]
        
        private var result:Array // store elements used on RPN calculation. It will last 1 element, the result
        private var calculation:Array // store elements that relacionates to the 'right order'.. like '*' first than '+'
        private var result2:Array // just a copy from result
        public function convert_to_rpn():void
        {    
            // clear stuff
            result = []
            calculation = []
            i = j = 0
            //
            while (i < ele.length)
            {
                // its not really a single char. can be an word or large number
                char = ele[i]
                
                if (Number(char) || char == "0")
                {
                    result.push(char)
                } else if (char == "(")
                {
                    calculation.push(char)
                } else if (char == "+" || char == "-" || char == "*" || char == "/" || char == "^" || char == "sin" || char == "cos" || char == "tan")
                {
                    calculation.push(char)
                    // call a function that organizes the order
                    Nopr()
                }  else if (char == ")")
                
                
                {
                    calculation.push(char)
                    close_parentesis()
                } else 
                {    
                    result.push(char)
                }
                // loopin' 'chars'
                ++i
            }
            
            // now add 'calculation' array (reverse) to the result array
            j = calculation.length
            while (j > 0)
            {
                if (calculation[j - 1] != "")
                {
                    result.push(calculation[j-1])
                }
                --j
            }
            // keep looping thought other 'chars'
            result2 = result
            
        }
            
        
        
        
        private var level1:uint, level2:uint
        private function Nopr():void
        {
            if (char == "+" || char == "-") 
            {
                level1 = 1;
            } else if (char == "*" || char == "/") 
            {
                level1 = 2;
            } else if (char == "^")
            {
                level1 = 4;
            } else if (char == "sin" || char == "cos" || char == "tan")
            {
                level1 = 8
            }
            if (calculation[calculation.length - 2] == "+" || calculation[calculation.length - 2] == "-") 
            {
                level2 = 1;
            } else if (calculation[calculation.length - 2] == "*" || calculation[calculation.length - 2] == "/") 
            {
                level2 = 2;
            } else if (calculation[calculation.length - 2] == "^") 
            {
                level2 = 3;
            } else if (calculation[calculation.length - 2] == "sin" || calculation[calculation.length - 2] == "cos" || calculation[calculation.length - 2] == "tan")
            {
                level2 = 4;
            } else 
            {
                level2 = 0;
            }
            if (level1 <= level2) 
            {
                result.push(calculation[calculation.length-2]);
                calculation.splice(calculation.length - 2, 1);
                // repeats
                Nopr();
            }
        }
        
        
        private var preventError:Boolean    
        private function close_parentesis():void
        {
            if (calculation[calculation.length - 2] != "(")
            {
                result.push(calculation[calculation.length - 2])
                calculation.splice(calculation.length - 2, 1)
                if (preventError)
                {
                    close_parentesis()
                }
                
            } else 
            {
                calculation.splice(calculation.length-2,2)
            }
        }
        
        
        private var n0:Boolean, n1:Boolean // if vars are number
        private var operator:Boolean
        public function rpn():void
        {
            result = result2.concat()
            
            
            i = 0
            while (i < result.length)
            {
                char = result[i]
                
                if (result.length > 1)
                {
                        
                    if (char == "+")
                    {
                        if (Number(result[i - 2]) || result[i - 2] == 0)
                        {
                            result[i] = Number(result[i - 2]) + Number(result[i - 1])
                            result.splice(i - 2, 2)
                            --i;
                        } else 
                        {
                            result[i] = Number(result[i - 1])
                            result.splice(i - 1, 1)
                        }
                        --i; 
                    } else if (char == "-")
                    {    
                        if (Number(result[i - 2]) || result[i - 2] == 0)
                        {
                            result[i] = Number(result[i - 2]) - Number(result[i - 1])
                            result.splice(i - 2, 2)
                            --i;
                        } else 
                        {
                            result[i] = - Number(result[i - 1])
                            result.splice(i - 1, 1)
                        }
                        --i; 
                    } else if (char == "*")
                    {                
                        result[i] = Number(result[i - 2]) * Number(result[i - 1])
                        result.splice(i - 2, 2)
                        --i; --i;
                    } else if (char == "/")
                    {                
                        result[i] = Number(result[i - 2]) / Number(result[i - 1])
                        result.splice(i - 2, 2)
                        --i; --i;
                    } else if (char == "^")
                    {
                        result[i] = Math.pow(Number(result[i - 2]), Number(result[i - 1]))
                        result.splice(i - 2, 2)
                        --i; --i;
                    } else if (!Number(char) && char != "0")
                    {
                        if (char == "sin")
                        {
                            result[i] = Math.sin(Number(result[i - 1]))
                            result.splice(i - 1, 1)
                            --i
                            
                        } else if (char == "cos")
                        {
                            result[i] = Math.cos(Number(result[i - 1]))
                            result.splice(i - 1, 1)
                            --i
                            
                        } else if (char == "tan")
                        {
                            result[i] = Math.tan(Number(result[i - 1]))
                            result.splice(i - 1, 1)
                            --i
                            
                        } else
                        {
                            // then char is a word, so now that word is search in the referenced libraly
                            j = 0
                            while (j < libraly.length)
                            {
                                if (char == libraly[j])
                                {
                                    ++j
                                    result[i] = libraly[j]
                                    --i
                                    break;
                                }
                                ++j; ++j;
                            }
                            // the index of the value has been found (j)    
                            if (j == 0 && libraly[0] != char)
                            {
                                ++i
                            }
                        }
                        
                        
                    }
                
                } else if (!Number(char) && char != "0")
                    {
                        if (char == "sin")
                            {
                                result[i] = Math.sin(Number(result[i - 1]))
                                result.splice(i - 1, 1)
                                --i
                                
                            } else if (char == "cos")
                            {
                                result[i] = Math.cos(Number(result[i - 1]))
                                result.splice(i - 1, 1)
                                --i
                                
                            } else if (char == "tan")
                            {
                                result[i] = Math.tan(Number(result[i - 1]))
                                result.splice(i - 1, 1)
                                --i
                            
                            } else {
                            

                            // then char is a word, so now that word is search in the referenced libraly
                            j = 0
                            while (j < libraly.length)
                            {
                                if (char == libraly[j])
                                {
                                    ++j
                                    result[i] = libraly[j]
                                    --i
                                    break;
                                }
                                ++j; ++j;
                            }
                            // the index of the value has been found (j)    
                            if (j == 0 && libraly[0] != char)
                            {
                                ++i
                            }
                        }
                    }
                ++i
            
            }
            
            // the returnable result, in (:Number)
            Return = Number(result[0])
            
            // changed the result variable, like 'y = 1*2+1', It will set 'y' (from libraly) to 3 (:Number)
            // then char is a word, so now that word is search in the referenced libraly
            /*i = 0, j = 0
            while (i < libraly.length)
            {
                if (tf.text == libraly[i])
                {
                    ++i
                    libraly[i] = Return
                    j = 1
                    break;
                }
                ++i; ++i;
            }
            if (j == 0)
            {
                 this just means that the word doesnt really exist in the libraly, so we create it
                libraly.push(tf.text)
                libraly.push(Return)
            }*/
            // now yes, this calculation thing ends :)
            
            
        }
        
        
    }

//}





//package  
//{
    import flash.display.Graphics;
    import flash.display.Sprite;
    /**
     * ...
     * @author Thi
     */
    /*public*/ class Graph extends Sprite
    {
        
        public var g:Graphics, X:String, Y:String
        private var libraly:Array
        
        private var valueX:Number, valueY:Number, scale:Number
        
        public function Graph(libraly:Array = null, X:String = "x", Y:String = "y", scale:Number = 10) 
        {
            this.libraly = libraly
            this.X = X
            this.Y = Y
            this.scale = scale
            
            g = this.graphics
            g.lineStyle(1, 0xFF0000)
            g.moveTo( -40, 250)
        }
        
        public function clear():void
        {
            g.clear()
            g.lineStyle(1, 0xFF0000)
            g.moveTo( -40, 250)
        }
        
        private var i:int
        public function line():void
        {
            if (!Number(X) && X != "0")
            {
                i = 0
                while (i < libraly.length)
                {
                    if (libraly[i] == X)
                    {
                        break;
                    }
                    ++i; ++i
                }
                valueX = Number(libraly[++i])
            } else
            {
                valueX = Number(X)
            }
            if (!Number(Y) && Y != "0")
            {
                i = 0
                while (i < libraly.length)
                {
                    if (libraly[i] == Y)
                    {
                        break;
                    }
                    ++i; ++i
                }
                valueY = Number(libraly[++i])
            } else
            {
                valueY = Number(Y)
            }
            //
            g.lineTo(valueX * scale + 232, 232 - valueY * scale)
            //g.lineTo(mouseX, mouseY)
        }
        
        public function move():void
        {
            if (!Number(X) && X != "0")
            {
                i = 0
                while (i < libraly.length)
                {
                    if (libraly[i] == X)
                    {
                        break;
                    }
                    ++i; ++i
                }
                valueX = Number(libraly[++i])
            } else
            {
                valueX = Number(X)
            }
            if (!Number(Y) && Y != "0")
            {
                i = 0
                while (i < libraly.length)
                {
                    if (libraly[i] == Y)
                    {
                        break;
                    }
                    ++i; ++i
                }
                valueY = Number(libraly[++i])
            } else
            {
                valueY = Number(Y)
            }
            //
            g.moveTo(valueX * scale + 232, 232 - valueY * scale)
            //g.lineTo(mouseX, mouseY)
        }
        
    }

//}

//package  
//{
    import flash.display.Graphics;
    import flash.display.Sprite;
    /**
     * ...
     * @author Thi
     */
    /*public*/ class Axis extends Sprite
    {
        
        public var cx:Number, cy:Number, range:Number, number:Number
        private var g:Graphics
        
        public function Axis(cx:Number = 0, cy:Number = 0, range:Number = 0, number:Number = 0) 
        {
            
            this.cx = cx
            this.cy = cy
            this.range = range
            this.number = number
            
            g = this.graphics
            
            
            draw()
        }
        
        public function draw():void
        {
            
            
            g.clear()
            g.lineStyle(1, 0xFFFFFF)
            //
            g.moveTo(0, cy)
            g.lineTo(cx * 2, cy)
            g.moveTo(cx, 0)
            g.lineTo(cx, cy * 2)
            //
            g.lineStyle(1, 0xFFFFFF, .2)
            var i:int = 0
            while (i < 2 * number)
            {
                g.moveTo(i*range*.5, 0)
                g.lineTo(i*range*.5,cy*2)
                
                g.moveTo(0, i*range*.5)
                g.lineTo(cx*2,i*range*.5)
                
                
                ++i
            }
            
            
            
        }
        
    }

//}