math-utils-simple 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # math-utils-simple
2
2
 
3
- A simple math utility library for JavaScript.
3
+ A lightweight JavaScript math utility library built to scale for advanced use cases in the future.
4
4
 
5
5
  ## Install
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "math-utils-simple",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "A simple math utility library for npm",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/index.js CHANGED
@@ -54,4 +54,34 @@ export { default as roundToNearest } from "./rounding/roundToNearest.js";
54
54
  export { default as snap } from "./rounding/snap.js";
55
55
  export { default as isBetween } from "./rounding/isBetween.js";
56
56
  export { default as wrap } from "./rounding/wrap.js";
57
- export { default as normalize } from "./rounding/normalize.js";
57
+ export { default as normalize } from "./rounding/normalize.js";
58
+
59
+ // PERCENTAGES
60
+ export { default as percentage } from "./percentages/percentage.js";
61
+ export { default as increaseByPercentage } from "./percentages/increaseByPercentage.js";
62
+ export { default as decreaseByPercentage } from "./percentages/decreaseByPercentage.js";
63
+ export { default as percentageDifference } from "./percentages/percentageDifference.js";
64
+ export { default as percentageChange } from "./percentages/percentageChange.js";
65
+ export { default as findOriginalValue } from "./percentages/findOriginalValue.js";
66
+ export { default as findFinalValue } from "./percentages/findFinalValue.js";
67
+ export { default as discount } from "./percentages/discount.js";
68
+ export { default as markup } from "./percentages/markup.js";
69
+ export { default as profitPercentage } from "./percentages/profitPercentage.js";
70
+ export { default as lossPercentage } from "./percentages/lossPercentage.js";
71
+ export { default as margin } from "./percentages/margin.js";
72
+ export { default as relativeChange } from "./percentages/relativeChange.js";
73
+
74
+ // STATISTICS
75
+ export { default as sum } from "./statistics/sum.js";
76
+ export { default as average } from "./statistics/average.js";
77
+ export { default as median } from "./statistics/median.js";
78
+ export { default as mode } from "./statistics/mode.js";
79
+ export { default as range } from "./statistics/range.js";
80
+ export { default as variance } from "./statistics/variance.js";
81
+ export { default as standardDeviation } from "./statistics/standardDeviation.js";
82
+ export { default as max } from "./statistics/max.js";
83
+ export { default as min } from "./statistics/min.js";
84
+ export { default as count } from "./statistics/count.js";
85
+ export { default as frequency } from "./statistics/frequency.js";
86
+ export { default as quartiles } from "./statistics/quartiles.js";
87
+ export { default as interQuartileRange } from "./statistics/interQuartileRange.js";
@@ -0,0 +1,3 @@
1
+ export default function decreaseByPercentage(value, percent) {
2
+ return value * (1 - percent / 100);
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function discount(price, percent) {
2
+ return price * (1 - percent / 100);
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function findFinalValue(original, percent) {
2
+ return original * (1 + percent / 100);
3
+ }
@@ -0,0 +1,7 @@
1
+ export default function findOriginalValue(finalValue, percentIncrease) {
2
+ if (percentIncrease === -100) {
3
+ throw new Error("Percent increase cannot be -100.");
4
+ }
5
+
6
+ return finalValue / (1 + percentIncrease / 100);
7
+ }
@@ -0,0 +1,3 @@
1
+ export default function increaseByPercentage(value, percent) {
2
+ return value * (1 + percent / 100);
3
+ }
@@ -0,0 +1,11 @@
1
+ export default function lossPercentage(cost, sellingPrice) {
2
+ if (cost === 0) {
3
+ throw new Error("Cost cannot be zero.");
4
+ }
5
+
6
+ if (sellingPrice >= cost) {
7
+ return 0;
8
+ }
9
+
10
+ return ((cost - sellingPrice) / cost) * 100;
11
+ }
@@ -0,0 +1,7 @@
1
+ export default function margin(cost, sellingPrice) {
2
+ if (sellingPrice === 0) {
3
+ throw new Error("Selling price cannot be zero.");
4
+ }
5
+
6
+ return ((sellingPrice - cost) / sellingPrice) * 100;
7
+ }
@@ -0,0 +1,3 @@
1
+ export default function markup(cost, percent) {
2
+ return cost * (1 + percent / 100);
3
+ }
@@ -0,0 +1,7 @@
1
+ export default function percentage(value, total) {
2
+ if (total === 0) {
3
+ throw new Error("Total cannot be zero.");
4
+ }
5
+
6
+ return (value / total) * 100;
7
+ }
@@ -0,0 +1,7 @@
1
+ export default function percentageChange(oldValue, newValue) {
2
+ if (oldValue === 0) {
3
+ throw new Error("Old value cannot be zero.");
4
+ }
5
+
6
+ return ((newValue - oldValue) / oldValue) * 100;
7
+ }
@@ -0,0 +1,10 @@
1
+ export default function percentageDifference(a, b) {
2
+ if (a === 0 && b === 0) {
3
+ return 0;
4
+ }
5
+
6
+ return (
7
+ (Math.abs(a - b) / ((Math.abs(a) + Math.abs(b)) / 2)) *
8
+ 100
9
+ );
10
+ }
@@ -0,0 +1,7 @@
1
+ export default function profitPercentage(cost, sellingPrice) {
2
+ if (cost === 0) {
3
+ throw new Error("Cost cannot be zero.");
4
+ }
5
+
6
+ return ((sellingPrice - cost) / cost) * 100;
7
+ }
@@ -0,0 +1,7 @@
1
+ export default function relativeChange(a, b) {
2
+ if (b === 0) {
3
+ throw new Error("Reference value cannot be zero.");
4
+ }
5
+
6
+ return ((a - b) / b) * 100;
7
+ }
@@ -0,0 +1,13 @@
1
+ import sum from "./sum.js";
2
+
3
+ export default function average(array) {
4
+ if (!Array.isArray(array)) {
5
+ throw new TypeError("Expected an array.");
6
+ }
7
+
8
+ if (array.length === 0) {
9
+ throw new Error("Cannot calculate average of an empty array.");
10
+ }
11
+
12
+ return sum(array) / array.length;
13
+ }
@@ -0,0 +1,7 @@
1
+ export default function count(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ return array.length;
7
+ }
@@ -0,0 +1,13 @@
1
+ export default function frequency(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ const result = {};
7
+
8
+ for (const value of array) {
9
+ result[value] = (result[value] || 0) + 1;
10
+ }
11
+
12
+ return result;
13
+ }
@@ -0,0 +1,7 @@
1
+ import quartiles from "./quartiles.js";
2
+
3
+ export default function interQuartileRange(array) {
4
+ const { q1, q3 } = quartiles(array);
5
+
6
+ return q3 - q1;
7
+ }
@@ -0,0 +1,19 @@
1
+ export default function max(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ if (array.length === 0) {
7
+ throw new Error("Cannot find maximum of an empty array.");
8
+ }
9
+
10
+ let largest = array[0];
11
+
12
+ for (const value of array) {
13
+ if (value > largest) {
14
+ largest = value;
15
+ }
16
+ }
17
+
18
+ return largest;
19
+ }
@@ -0,0 +1,18 @@
1
+ export default function median(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ if (array.length === 0) {
7
+ throw new Error("Cannot calculate median of an empty array.");
8
+ }
9
+
10
+ const sorted = [...array].sort((a, b) => a - b);
11
+ const middle = Math.floor(sorted.length / 2);
12
+
13
+ if (sorted.length % 2 === 0) {
14
+ return (sorted[middle - 1] + sorted[middle]) / 2;
15
+ }
16
+
17
+ return sorted[middle];
18
+ }
@@ -0,0 +1,19 @@
1
+ export default function min(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ if (array.length === 0) {
7
+ throw new Error("Cannot find minimum of an empty array.");
8
+ }
9
+
10
+ let smallest = array[0];
11
+
12
+ for (const value of array) {
13
+ if (value < smallest) {
14
+ smallest = value;
15
+ }
16
+ }
17
+
18
+ return smallest;
19
+ }
@@ -0,0 +1,38 @@
1
+ export default function mode(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ if (array.length === 0) {
7
+ throw new Error("Cannot calculate mode of an empty array.");
8
+ }
9
+
10
+ const counts = new Map();
11
+
12
+ for (const value of array) {
13
+ counts.set(value, (counts.get(value) || 0) + 1);
14
+ }
15
+
16
+ let maxFrequency = 0;
17
+
18
+ for (const frequency of counts.values()) {
19
+ if (frequency > maxFrequency) {
20
+ maxFrequency = frequency;
21
+ }
22
+ }
23
+
24
+ // No mode if every value occurs equally often.
25
+ if (maxFrequency === 1) {
26
+ return [];
27
+ }
28
+
29
+ const modes = [];
30
+
31
+ for (const [value, frequency] of counts) {
32
+ if (frequency === maxFrequency) {
33
+ modes.push(value);
34
+ }
35
+ }
36
+
37
+ return modes.sort((a, b) => a - b);
38
+ }
@@ -0,0 +1,37 @@
1
+ import median from "./median.js";
2
+
3
+ export default function quartiles(array) {
4
+ if (!Array.isArray(array)) {
5
+ throw new TypeError("Expected an array.");
6
+ }
7
+
8
+ if (array.length === 0) {
9
+ throw new Error("Cannot calculate quartiles of an empty array.");
10
+ }
11
+
12
+ const sorted = [...array].sort((a, b) => a - b);
13
+
14
+ const q2 = median(sorted);
15
+
16
+ const middle = Math.floor(sorted.length / 2);
17
+
18
+ let lowerHalf;
19
+ let upperHalf;
20
+
21
+ if (sorted.length % 2 === 0) {
22
+ lowerHalf = sorted.slice(0, middle);
23
+ upperHalf = sorted.slice(middle);
24
+ } else {
25
+ lowerHalf = sorted.slice(0, middle);
26
+ upperHalf = sorted.slice(middle + 1);
27
+ }
28
+
29
+ const q1 = median(lowerHalf);
30
+ const q3 = median(upperHalf);
31
+
32
+ return {
33
+ q1,
34
+ q2,
35
+ q3,
36
+ };
37
+ }
@@ -0,0 +1,6 @@
1
+ import min from "./min.js";
2
+ import max from "./max.js";
3
+
4
+ export default function range(array) {
5
+ return max(array) - min(array);
6
+ }
@@ -0,0 +1,5 @@
1
+ import variance from "./variance.js";
2
+
3
+ export default function standardDeviation(array) {
4
+ return Math.sqrt(variance(array));
5
+ }
@@ -0,0 +1,7 @@
1
+ export default function sum(array) {
2
+ if (!Array.isArray(array)) {
3
+ throw new TypeError("Expected an array.");
4
+ }
5
+
6
+ return array.reduce((total, value) => total + value, 0);
7
+ }
@@ -0,0 +1,21 @@
1
+ import average from "./average.js";
2
+
3
+ export default function variance(array) {
4
+ if (!Array.isArray(array)) {
5
+ throw new TypeError("Expected an array.");
6
+ }
7
+
8
+ if (array.length === 0) {
9
+ throw new Error("Cannot calculate variance of an empty array.");
10
+ }
11
+
12
+ const mean = average(array);
13
+
14
+ let sum = 0;
15
+
16
+ for (const value of array) {
17
+ sum += (value - mean) ** 2;
18
+ }
19
+
20
+ return sum / array.length;
21
+ }