Repository: pbiswas101/Mathball (js)

Issue:
Kaprekar Number
### Do the checklist before filing the issue:

- [ ] Is this something you can **debug and fix**?
- [x] Do you have Node.js and all the relevant dev-dependencies installed?
- [ ] Is this a **feature request** that you can add?

###### NOTE: Provide a clear and concise description of the feature that needs to be added! Or if its a bug, then provide the necessary steps to reproduce it.

- *Give your answer below:*

------------

[Function: **M.isKaprekar()**] needs to be added!
For more info:

https://www.geeksforgeeks.org/kaprekar-number/

*M.isKaprekar()* needs to accept a positive integer and all other arguments passed should throw a type error which needs to be handled gracefully! For error handling, you should refer to how other features like M.isArmstrong() is implemented.

Pull request description:
Adding queue data structure. Issue #89
### Do the checklist before submitting the PR:

- [x] Have you read the guidelines mentioned in **CONTRIBUTING.md**?
- [x] Have you squashed your commits?

**Q**: What version of *Node.js* you've used in the project? (`e.g. Node v10.11.0`)
**A**:v11.6.0

**Q**: Mention the *Issue Number*! (`e.g. Fixed #8`)
**A**:#89

- *Give additional information regarding the PR below:*

------------
Adding the queue data structure, with all the basic functions

Patch:
diff --git a/README.md b/README.md
index f81962f..c15c81a 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ $ npm install mathball --save
 
 - **Mathematical Utilities** - [Complex][49] - [frequency][40] - [gcd][10] - [isEven][11] - [isOdd][12] - [lcm][13] - [length][14] - [max][15] - [min][16] - [modInv][39] - [nCr][48] - [pow][46] - [sort][17] - [sum][18] - [toDegrees][50] - [toRadians][51]
 
-- **Data Structures** - [priorityQueue][44]
+- **Data Structures** - [priorityQueue][44] - [stack][53]
 
 - **Helper Methods** - [performance][28] - [pipe][29]
 
@@ -117,4 +117,5 @@ The MIT License 2019 - [Priyabrata Biswas][20].
 [49]: https://github.com/pbiswas101/Mathball/blob/master/src/complex/index.js
 [50]: https://github.com/pbiswas101/Mathball/blob/master/src/degree/index.js
 [51]: https://github.com/pbiswas101/Mathball/blob/master/src/radian/index.js
-[52]: https://github.com/pbiswas101/Mathball/blob/master/src/isStormer/index.js
\ No newline at end of file
+[52]: https://github.com/pbiswas101/Mathball/blob/master/src/isStormer/index.js
+[53]: https://github.com/pbiswas101/Mathball/blob/master/src/stack/index.js
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 327524f..4b2c60e 100644
--- a/src/index.js
+++ b/src/index.js
@@ -46,7 +46,8 @@ const performance = require('./performance'),
 	pipe = require('./pipe');
 
 /* Data Structure */
-const PriorityQueue = require('./PriorityQueue');
+const PriorityQueue = require('./PriorityQueue'),
+	Stack = require('./stack');
 
 /* M - Mathball Object */
 module.exports = {
@@ -90,6 +91,7 @@ module.exports = {
 	frequency,
 	isDeficient,
 	PriorityQueue,
+	Stack,
 	isCarmichael: carmichael.isCarmichael,
 	rangeFibonacci: fibonacci.rangeFibonacci,
 	Complex
diff --git a/src/stack/index.js b/src/stack/index.js
new file mode 100644
index 0000000..9d78b0d
--- /dev/null
+++ b/src/stack/index.js
@@ -0,0 +1,57 @@
+const validate = require("../validation/number");
+
+class Stack{
+    constructor(){
+        this.stack = [];
+    }
+
+    push(data){
+        validate(data, 'Stack.push');
+        this.stack.push(data);
+    }
+
+    pop(){
+        if(this.size() === 0){
+            return "Stack Underflow";
+        }
+
+        else{
+            return this.stack.pop();
+        } 
+    }
+
+    isEmpty(){
+        return (this.size() === 0);
+    }
+
+    head(){
+        if(this.size() === 0){
+            return "Empty Stack";
+        }
+        else{
+            return this.stack[this.size() -1];
+        }
+    }
+
+    size(){
+        return this.stack.length;
+    }
+
+    copy(){
+        let internal = new Stack();
+        
+        for(let i = 0; i<this.size(); i++){
+            internal.push(this.stack[i]);
+        }
+
+        return internal;
+    }
+
+    display(){
+        let temp = this.stack.reverse().join(' ');
+        this.stack.reverse();
+        return temp;
+    }
+}
+
+module.exports = Stack;
\ No newline at end of file


Test patch:
diff --git a/test/stack-spec.js b/test/stack-spec.js
new file mode 100644
index 0000000..3705dc4
--- /dev/null
+++ b/test/stack-spec.js
@@ -0,0 +1,69 @@
+const assert = require('assert'),
+        Stack = require('../src/stack/'),
+        sample = new Stack();
+
+describe('[Function: Stack]', () => {
+
+    sample.push(10);
+    sample.push(20);
+    sample.push(30);
+    
+    it('should be a function', () => {
+        assert.strictEqual(typeof Stack, 'function');
+    });
+
+    it(`should return '30' when 'head()' is called`, () => {
+        assert.strictEqual(sample.head(), 30);
+    });
+    
+    it(`should return 'false' when 'isEmpty()' is called`, () => {
+        assert.strictEqual(sample.isEmpty(), false);
+    });
+
+    it(`should return 'number' when 'size()' is called`, () => {
+        assert.strictEqual(typeof sample.size(), 'number');
+    });
+
+    it(`should return '3' when 'size()' is called`, () => {
+        assert.strictEqual(sample.size(), 3);
+    });
+
+    it(`should throw TypeError when a string is passed as argument in 'push()'`, () => {
+        assert.throws(() => sample.push('string'), TypeError);
+    });
+
+    it(`should return 'object' type when 'copy()' is called`, () => {
+        assert.strictEqual(typeof sample.copy(), 'object');
+    });
+
+    it(`should return '30 20 10' type when 'display()' is called`, () => {
+        assert.strictEqual(sample.display(), '30 20 10');
+    });
+
+    it(`should return '30' when 'pop()' is called`, () => {
+        assert.strictEqual(sample.pop(), 30);
+    });
+
+    it(`should return '20' when 'pop()' is called`, () => {
+        assert.strictEqual(sample.pop(), 20);
+    });
+
+    it(`should return '10' when 'pop()' is called`, () => {
+        assert.strictEqual(sample.pop(), 10);
+    });
+
+    it(`should return 'Stack Underflow' when 'pop()' is called`, () => {
+        assert.strictEqual(sample.pop(), 'Stack Underflow');
+    });
+
+
+    it(`should return 'Empty Stack' when 'head()' is called`, () => {
+        assert.strictEqual(sample.head(), 'Empty Stack');
+    });
+
+    it(`should return 'true' when 'isEmpty()' is called`, () => {
+        assert.strictEqual(sample.isEmpty(), true);
+    });
+
+});
+        
\ No newline at end of file