Broken Calculator

Interface for helping solve the Broken Calculator project on Codecademy.

by XcsN

HTML

<div class="calculator">
    <div class="display">0</div>
    <div class="buttonArea">
        <div class="calcButton" id="exp">e<span class="superscript">x</span></div>
        <div class="calcButton" id="log">ln</div>
        <div class="calcButton" id="pow">x<span class="superscript">2</span></div>
        <div class="calcButton" id="sqr">&radic;</div>
        <div class="calcButton" id="sin">sin</div>
        <div class="calcButton" id="cos">cos</div>
        <div class="calcButton" id="asin">sin<span class="superscript">-1</span></div>
        <div class="calcButton" id="acos">cos<span class="superscript">-1</span></div>
        <div class="calcButton" id="reset">AC</div>
    </div>
</div>

CSS

.calculator {
    position:relative;
    margin:10px auto;
    background-color:#ddd;
    width:200px;
    padding:10px;
    border: 1px solid black;
    box-shadow: #000 0 4px 8px;
    border-radius:6px;
    font-family:monaco, monospace, courier new;
}

.display {
    height:36px;
    background-color:white;
    color:#222;
    
    font-size:30px;
    text-align:right;
    border:1px solid black;
}

.calcButton {
    border:1px solid black;
    border-radius:3px;
    background-color:#ccc;
    box-shadow: inset #000 0 0 5px;
    padding:5px;
    height:30px;
    font-size:20px;
    color:#224;
    text-align:center;
    margin:5px auto;
    position:relative;
    display:inline-block;
}

.superscript {
    font-size:0.5em;
    top:-0.7em;
    left:-0.2em;
    position:relative;
}

.buttonArea {
    width:100%;
    height:200px;
    margin:15px auto;
    position:relative;
    text-align:center;
}
.buttonArea:after { clear both; }

JavaScript

String.prototype.in = function(arr) {
    for(var i = 0; i < arr.length; i++)
        if(arr[i] == this)
            return true;
    return false;
};

function brokenCalculator() {
    var num = 0; var functionList = ["exp","log","pow","sqr","sin","cos","asin","acos","reset"];
    this.do = function(command) {
        if(command.in(functionList))
            num = this[command]();
            console.log(num);
            return num;
        };
    
    this.exp = function() {
        return Math.exp(num);
    };
    
    this.log = function() {
        return Math.log(num);
    };
    
    this.pow = function() {
        return num*num;
    };
    
    this.sqr = function() {
        return Math.sqrt(num);
    };
    
    this.sin = function() {
        return Math.sin(num);
    };
    
    this.cos = function() {
        return Math.cos(num);
    };
    
    this.asin = function() {
        return Math.asin(num);
    };
    
    this.acos = function() {
        return Math.acos(num);
    }
    
    this.reset = function() {
        return 0;
    }
}

function limitDigits(x, n) {
    var wholeDigits = Math.floor(Math.log(x) / Math.log(10)) + 1;
    var wholePart = Math.floor(x);
    if(wholePart > Math.pow(10,10))
        return "Infinity";
    var fracPart = x - wholePart;
    var decDigits = x % 1 ? 1 : 0;
    if(!decDigits)
        return wholePart;
    else {
        remainDigits = n - wholeDigits - decDigits -1;
        rounder = Math.pow(10,remainDigits);
        fracPart = Math.floor(fracPart * rounder);
        return wholePart + "." + fracPart;
    }
}

$(function() {
    bc = new brokenCalculator();
    $(".calcButton").click(function() {
        $(".display").text(limitDigits(bc.do($(this).attr("id")),11));
    });
});