Array Hack Challenge
Array Hack Challenge
๐ Array Hack Challenge Progress Tracker
๐ฏ Your Learning Journey
๐ Overall Progress
๐บ๏ธ Learning Milestones
๐ฏ Quick Actions
๐ง Array Hack Challenge: Building Better Calculators
Welcome to the ultimate guide on using Arrays to supercharge your calculator applications! Letโs explore how arrays can transform your basic calculator into a powerful computational tool.
๐ Why Arrays Make Calculators Amazing
Arrays are the secret weapon for creating professional calculators. Hereโs why:
- ๐ History Tracking - Store every calculation
- ๐ข Multi-Number Operations - Work with sets of data
- ๐ Statistical Functions - Mean, median, mode calculations
- ๐พ Memory Functions - Save and recall values
- ๐ฏ Advanced Operations - Matrix math, sequences, and more
๐ฏ Calculator Array Fundamentals
Basic Calculator Memory System
// Calculator memory using arrays
let calculatorMemory = [];
let calculationHistory = [];
let currentNumbers = [];
// Store a calculation
function storeCalculation(operation, result) {
calculationHistory.push({
operation: operation,
result: result,
timestamp: new Date().toLocaleString()
});
}
// Memory functions
function memoryStore(value) {
calculatorMemory.push(value);
console.log(`Stored: ${value}`);
}
function memoryRecall() {
return calculatorMemory.length > 0 ?
calculatorMemory[calculatorMemory.length - 1] : 0;
}
function memoryClear() {
calculatorMemory = [];
console.log("Memory cleared!");
}
๐ Line-by-Line Explanation: Basic Memory System
Letโs break down every line of the memory system code:
let calculatorMemory = [];
let
- Declares a variable that can be changed latercalculatorMemory
- Variable name for storing calculator memory values=
- Assignment operator[]
- Creates an empty array to hold memory values;
- Statement terminator
let calculationHistory = [];
- Creates another empty array specifically for storing past calculations
- This will hold objects containing operation details
let currentNumbers = [];
- Array to hold numbers currently being worked with
- Useful for multi-number operations
function storeCalculation(operation, result) {
function
- Keyword to declare a functionstoreCalculation
- Function name describing what it does(operation, result)
- Parameters: the math operation and its result{
- Opens the function body
calculationHistory.push({
calculationHistory
- Our array for storing calculations.push()
- Array method that adds elements to the end({
- Opens an object literal to store calculation data
operation: operation,
result: result,
timestamp: new Date().toLocaleString()
operation: operation
- Stores the math operation (like โ5 + 3โ)result: result
- Stores the calculated result (like 8)timestamp:
- Property to store when calculation happenednew Date()
- Creates a new date object with current time.toLocaleString()
- Converts date to readable text format
});
}
});
- Closes the object and the push() method call}
- Closes the function
function memoryStore(value) {
calculatorMemory.push(value);
console.log(`Stored: ${value}`);
}
Line-by-line breakdown:
function memoryStore(value)
- Function to save a value to memorycalculatorMemory.push(value)
- Adds the value to end of memory arrayconsole.log()
- Prints confirmation message to console`Stored: ${value}`
- Template literal showing stored value
function memoryRecall() {
return calculatorMemory.length > 0 ?
calculatorMemory[calculatorMemory.length - 1] : 0;
}
Detailed explanation:
function memoryRecall()
- Function with no parameters to get last stored valuereturn
- Sends a value back when function is calledcalculatorMemory.length > 0
- Checks if array has any elements?
- Ternary operator (if-then-else in one line)calculatorMemory[calculatorMemory.length - 1]
- Gets last array elementcalculatorMemory.length
- Total number of elements- 1
- Subtract 1 because arrays start at index 0
: 0
- If array is empty, return 0 instead
Example Usage:
// Using our calculator arrays
storeCalculation("5 + 3", 8);
storeCalculation("10 * 2", 20);
memoryStore(42);
console.log("Last calculation:", calculationHistory[calculationHistory.length - 1]);
console.log("Memory recall:", memoryRecall());
Usage explanation:
storeCalculation("5 + 3", 8)
- Stores addition operation and resultstoreCalculation("10 * 2", 20)
- Stores multiplication operation and resultmemoryStore(42)
- Saves number 42 to calculator memorycalculationHistory[calculationHistory.length - 1]
- Accesses last calculationmemoryRecall()
- Calls function to get last stored memory value
๐งฎ Advanced Calculator Features with Arrays
1. Multi-Number Operations
class ArrayCalculator {
constructor() {
this.numbers = [];
this.results = [];
}
// Add numbers to calculation set
addNumbers(...nums) {
this.numbers.push(...nums);
return this;
}
// Calculate sum of all numbers
calculateSum() {
const sum = this.numbers.reduce((total, num) => total + num, 0);
this.results.push({ operation: 'sum', result: sum, numbers: [...this.numbers] });
return sum;
}
// Calculate average
calculateAverage() {
const sum = this.calculateSum();
const avg = sum / this.numbers.length;
this.results.push({ operation: 'average', result: avg, numbers: [...this.numbers] });
return avg;
}
// Find maximum value
findMax() {
const max = Math.max(...this.numbers);
this.results.push({ operation: 'max', result: max, numbers: [...this.numbers] });
return max;
}
// Find minimum value
findMin() {
const min = Math.min(...this.numbers);
this.results.push({ operation: 'min', result: min, numbers: [...this.numbers] });
return min;
}
// Clear numbers for next calculation
clear() {
this.numbers = [];
return this;
}
// Get calculation history
getHistory() {
return this.results;
}
}
๐ Line-by-Line Explanation: Array Calculator
class ArrayCalculator {
class
- JavaScript keyword to create a blueprint for objectsArrayCalculator
- Name of our class (like a template for calculators){
- Opens the class definition
constructor() {
this.numbers = [];
this.results = [];
}
constructor()
- Special function that runs when creating new calculatorthis.numbers = []
- Creates empty array for current numbersthis
- Refers to the specific calculator object being created.numbers
- Property name for storing numbers
this.results = []
- Creates empty array for storing calculation results
addNumbers(...nums) {
this.numbers.push(...nums);
return this;
}
Detailed breakdown:
addNumbers(...nums)
- Method to add multiple numbers at once...nums
- Rest parameter that collects all arguments into an array
this.numbers.push(...nums)
- Adds all numbers to our array...nums
- Spread operator that unpacks the array of numbers
return this
- Returns the calculator object for method chaining
calculateSum() {
const sum = this.numbers.reduce((total, num) => total + num, 0);
this.results.push({ operation: 'sum', result: sum, numbers: [...this.numbers] });
return sum;
}
Line-by-line analysis:
calculateSum()
- Method to add all numbers togetherconst sum =
- Creates unchangeable variable for the sumthis.numbers.reduce()
- Array method that combines all elements(total, num) => total + num
- Arrow function that adds current number to totaltotal
- Accumulator that keeps running totalnum
- Current number being processed=>
- Arrow function syntaxtotal + num
- Addition operation
, 0
- Starting value for the accumulatorthis.results.push({...})
- Saves calculation details to historynumbers: [...this.numbers]
- Creates copy of numbers array using spread operator
calculateAverage() {
const sum = this.calculateSum();
const avg = sum / this.numbers.length;
this.results.push({ operation: 'average', result: avg, numbers: [...this.numbers] });
return avg;
}
Step-by-step explanation:
const sum = this.calculateSum()
- Calls our sum method to get totalconst avg = sum / this.numbers.length
- Divides sum by count of numbersthis.numbers.length
- Property that gives array size/
- Division operator
- Records the average calculation in results history
return avg
- Sends back the calculated average
findMax() {
const max = Math.max(...this.numbers);
this.results.push({ operation: 'max', result: max, numbers: [...this.numbers] });
return max;
}
Explanation:
Math.max()
- Built-in JavaScript function to find largest number...this.numbers
- Spread operator passes all array elements as separate arguments- Example:
Math.max(...[1,2,3])
becomesMath.max(1,2,3)
Usage Example:
const calc = new ArrayCalculator();
// Add multiple numbers and perform operations
calc.addNumbers(10, 25, 30, 15, 40)
.calculateSum() // Returns: 120
.calculateAverage() // Returns: 24
.findMax() // Returns: 40
.findMin(); // Returns: 10
console.log("All results:", calc.getHistory());
Usage breakdown:
const calc = new ArrayCalculator()
- Creates new calculator instancenew
- Keyword to create object from class
calc.addNumbers(10, 25, 30, 15, 40)
- Adds 5 numbers to calculator.calculateSum()
- Method chaining: calls sum on same object- Method chaining works because each method returns
this
๐ Statistical Calculator Functions
Advanced Statistics with Arrays
class StatisticalCalculator {
constructor() {
this.dataset = [];
}
// Add data points
addData(values) {
if (Array.isArray(values)) {
this.dataset.push(...values);
} else {
this.dataset.push(values);
}
return this;
}
// Calculate mean (average)
mean() {
return this.dataset.reduce((sum, val) => sum + val, 0) / this.dataset.length;
}
// Calculate median (middle value)
median() {
const sorted = [...this.dataset].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2 !== 0
? sorted[mid]
: (sorted[mid - 1] + sorted[mid]) / 2;
}
// Calculate mode (most frequent value)
mode() {
const frequency = {};
let maxFreq = 0;
let modes = [];
// Count frequencies
this.dataset.forEach(val => {
frequency[val] = (frequency[val] || 0) + 1;
if (frequency[val] > maxFreq) {
maxFreq = frequency[val];
}
});
// Find all values with max frequency
for (let val in frequency) {
if (frequency[val] === maxFreq) {
modes.push(Number(val));
}
}
return modes.length === this.dataset.length ? [] : modes;
}
// Calculate standard deviation
standardDeviation() {
const mean = this.mean();
const squaredDiffs = this.dataset.map(val => Math.pow(val - mean, 2));
const avgSquaredDiff = squaredDiffs.reduce((sum, val) => sum + val, 0) / this.dataset.length;
return Math.sqrt(avgSquaredDiff);
}
// Get data summary
getSummary() {
return {
data: [...this.dataset],
count: this.dataset.length,
mean: this.mean(),
median: this.median(),
mode: this.mode(),
standardDeviation: this.standardDeviation(),
min: Math.min(...this.dataset),
max: Math.max(...this.dataset)
};
}
}
๐ Line-by-Line Explanation: Statistical Calculator
addData(values) {
if (Array.isArray(values)) {
this.dataset.push(...values);
} else {
this.dataset.push(values);
}
return this;
}
Detailed breakdown:
addData(values)
- Method to add data points to our datasetif (Array.isArray(values))
- Checks if input is an arrayArray.isArray()
- Built-in function to test if something is an array
this.dataset.push(...values)
- If array, spread elements and add each oneelse
- If not an array (single value)this.dataset.push(values)
- Add the single value directly
mean() {
return this.dataset.reduce((sum, val) => sum + val, 0) / this.dataset.length;
}
Step-by-step:
mean()
- Method to calculate average (mean)this.dataset.reduce((sum, val) => sum + val, 0)
- Adds all valuessum
- Running totalval
- Current value being processed0
- Starting value for sum
/ this.dataset.length
- Divides total by count of values
median() {
const sorted = [...this.dataset].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2 !== 0
? sorted[mid]
: (sorted[mid - 1] + sorted[mid]) / 2;
}
Comprehensive explanation:
const sorted = [...this.dataset].sort((a, b) => a - b)
- Sorts data[...this.dataset]
- Creates copy so original isnโt changed.sort((a, b) => a - b)
- Sorts numbers in ascending ordera - b
- Comparison function: negative = a first, positive = b first
const mid = Math.floor(sorted.length / 2)
- Finds middle indexMath.floor()
- Rounds down to nearest integer
sorted.length % 2 !== 0
- Checks if odd number of values%
- Modulo operator (remainder after division)!== 0
- Not equal to zero (odd numbers have remainder 1)
? sorted[mid]
- If odd, return middle value: (sorted[mid - 1] + sorted[mid]) / 2
- If even, average two middle values
mode() {
const frequency = {};
let maxFreq = 0;
let modes = [];
// Count frequencies
this.dataset.forEach(val => {
frequency[val] = (frequency[val] || 0) + 1;
if (frequency[val] > maxFreq) {
maxFreq = frequency[val];
}
});
// Find all values with max frequency
for (let val in frequency) {
if (frequency[val] === maxFreq) {
modes.push(Number(val));
}
}
return modes.length === this.dataset.length ? [] : modes;
}
Mode calculation breakdown:
const frequency = {}
- Object to count how often each value appearslet maxFreq = 0
- Variable to track highest frequencylet modes = []
- Array to store most frequent valuesthis.dataset.forEach(val => {
- Loop through each data valuefrequency[val] = (frequency[val] || 0) + 1
- Count occurrencesfrequency[val]
- Get current count for this value|| 0
- If undefined, use 0 instead+ 1
- Add 1 to the count
if (frequency[val] > maxFreq)
- If this is new highest frequencymaxFreq = frequency[val]
- Update maximum frequencyfor (let val in frequency)
- Loop through all counted valuesif (frequency[val] === maxFreq)
- If value has maximum frequencymodes.push(Number(val))
- Add to modes arrayNumber(val)
- Convert string back to number
modes.length === this.dataset.length ? [] : modes
- Return empty if all values appear once
Statistics Example:
const stats = new StatisticalCalculator();
stats.addData([85, 90, 78, 92, 88, 85, 95, 82, 90, 87]);
console.log("Dataset Summary:");
console.log(stats.getSummary());
// Output: Complete statistical analysis of the dataset
Example explanation:
new StatisticalCalculator()
- Creates new statistics calculatorstats.addData([85, 90, 78, 92, 88, 85, 95, 82, 90, 87])
- Adds test scoresstats.getSummary()
- Calls method that returns object with all statistics
๐ฎ Interactive Calculator Features
Calculator History with Undo/Redo
class HistoryCalculator {
constructor() {
this.history = [];
this.currentIndex = -1;
this.currentValue = 0;
}
// Perform operation and save to history
calculate(operation, operand) {
let result;
switch(operation) {
case '+': result = this.currentValue + operand; break;
case '-': result = this.currentValue - operand; break;
case '*': result = this.currentValue * operand; break;
case '/': result = operand !== 0 ? this.currentValue / operand : 'Error'; break;
case '=': result = operand; break;
default: result = this.currentValue;
}
// Add to history (remove any future history if we're in the middle)
this.history = this.history.slice(0, this.currentIndex + 1);
this.history.push({
operation: `${this.currentValue} ${operation} ${operand}`,
result: result,
timestamp: Date.now()
});
this.currentIndex++;
this.currentValue = result;
return result;
}
// Undo last operation
undo() {
if (this.currentIndex > 0) {
this.currentIndex--;
this.currentValue = this.history[this.currentIndex].result;
return this.currentValue;
}
return "Cannot undo further";
}
// Redo operation
redo() {
if (this.currentIndex < this.history.length - 1) {
this.currentIndex++;
this.currentValue = this.history[this.currentIndex].result;
return this.currentValue;
}
return "Cannot redo further";
}
// Get full history
getHistory() {
return this.history.map((entry, index) => ({
...entry,
current: index === this.currentIndex
}));
}
// Clear all history
clearHistory() {
this.history = [];
this.currentIndex = -1;
this.currentValue = 0;
}
}
๐ Line-by-Line Explanation: History Calculator
constructor() {
this.history = [];
this.currentIndex = -1;
this.currentValue = 0;
}
Constructor breakdown:
this.history = []
- Array to store all calculation stepsthis.currentIndex = -1
- Points to current position in history (-1 = no history yet)this.currentValue = 0
- Stores current calculator display value
calculate(operation, operand) {
let result;
switch(operation) {
case '+': result = this.currentValue + operand; break;
case '-': result = this.currentValue - operand; break;
case '*': result = this.currentValue * operand; break;
case '/': result = operand !== 0 ? this.currentValue / operand : 'Error'; break;
case '=': result = operand; break;
default: result = this.currentValue;
}
Calculate method explanation:
calculate(operation, operand)
- Method to perform math operationslet result
- Variable to store calculation resultswitch(operation)
- Checks which operation to performcase '+'
- If operation is additionresult = this.currentValue + operand
- Add current value and operandbreak
- Exit switch statementcase '/'
- Division case with error checkingoperand !== 0
- Check if not dividing by zero? this.currentValue / operand
- If safe, do division: 'Error'
- Otherwise, return error messagedefault:
- If operation not recognized, keep current value
// Add to history (remove any future history if we're in the middle)
this.history = this.history.slice(0, this.currentIndex + 1);
this.history.push({
operation: `${this.currentValue} ${operation} ${operand}`,
result: result,
timestamp: Date.now()
});
this.currentIndex++;
this.currentValue = result;
return result;
History management:
this.history.slice(0, this.currentIndex + 1)
- Removes future history- If user was in middle of history and does new operation
slice()
creates new array with only elements up to current position
this.history.push({...})
- Adds new calculation to history`${this.currentValue} ${operation} ${operand}`
- Template literal for operation stringtimestamp: Date.now()
- Records when calculation happenedthis.currentIndex++
- Move to new position in historythis.currentValue = result
- Update calculator display
undo() {
if (this.currentIndex > 0) {
this.currentIndex--;
this.currentValue = this.history[this.currentIndex].result;
return this.currentValue;
}
return "Cannot undo further";
}
Undo functionality:
if (this.currentIndex > 0)
- Check if thereโs something to undothis.currentIndex--
- Move back one step in historythis.currentValue = this.history[this.currentIndex].result
- Restore previous resultreturn "Cannot undo further"
- Message when no more undo available
๐ฌ Matrix Calculator with Arrays
2D Arrays for Matrix Operations
class MatrixCalculator {
constructor() {
this.matrices = [];
}
// Create a new matrix
createMatrix(rows, cols, fillValue = 0) {
const matrix = [];
for (let i = 0; i < rows; i++) {
matrix[i] = [];
for (let j = 0; j < cols; j++) {
matrix[i][j] = fillValue;
}
}
return matrix;
}
// Add two matrices
addMatrices(matrix1, matrix2) {
if (matrix1.length !== matrix2.length ||
matrix1[0].length !== matrix2[0].length) {
throw new Error("Matrices must have same dimensions");
}
const result = [];
for (let i = 0; i < matrix1.length; i++) {
result[i] = [];
for (let j = 0; j < matrix1[i].length; j++) {
result[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return result;
}
// Multiply two matrices
multiplyMatrices(matrix1, matrix2) {
if (matrix1[0].length !== matrix2.length) {
throw new Error("Invalid dimensions for multiplication");
}
const result = this.createMatrix(matrix1.length, matrix2[0].length);
for (let i = 0; i < matrix1.length; i++) {
for (let j = 0; j < matrix2[0].length; j++) {
for (let k = 0; k < matrix2.length; k++) {
result[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
return result;
}
// Display matrix nicely
displayMatrix(matrix) {
return matrix.map(row =>
row.map(cell => cell.toString().padStart(6)).join(' ')
).join('\n');
}
}
๐ Line-by-Line Explanation: Matrix Calculator
createMatrix(rows, cols, fillValue = 0) {
const matrix = [];
for (let i = 0; i < rows; i++) {
matrix[i] = [];
for (let j = 0; j < cols; j++) {
matrix[i][j] = fillValue;
}
}
return matrix;
}
Matrix creation breakdown:
createMatrix(rows, cols, fillValue = 0)
- Method to create new matrixfillValue = 0
- Default parameter: use 0 if no value provided
const matrix = []
- Create empty array for the matrixfor (let i = 0; i < rows; i++)
- Loop for each rowi
- Row counter starting at 0i < rows
- Continue while i is less than number of rowsi++
- Increment i after each iteration
matrix[i] = []
- Create empty array for current rowfor (let j = 0; j < cols; j++)
- Inner loop for each columnj
- Column counter
matrix[i][j] = fillValue
- Set value at row i, column jmatrix[i]
- Access the row array[j]
- Access specific column in that row
addMatrices(matrix1, matrix2) {
if (matrix1.length !== matrix2.length ||
matrix1[0].length !== matrix2[0].length) {
throw new Error("Matrices must have same dimensions");
}
const result = [];
for (let i = 0; i < matrix1.length; i++) {
result[i] = [];
for (let j = 0; j < matrix1[i].length; j++) {
result[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return result;
}
Matrix addition explanation:
if (matrix1.length !== matrix2.length ||
- Check if same number of rows!==
- Strict inequality operator||
- Logical OR operator
matrix1[0].length !== matrix2[0].length)
- Check if same number of columnsmatrix1[0]
- First row of matrix1.length
- Number of columns in first row
throw new Error("...")
- Stops execution and shows error messageresult[i][j] = matrix1[i][j] + matrix2[i][j]
- Adds corresponding elements- Takes element from same position in both matrices and adds them
displayMatrix(matrix) {
return matrix.map(row =>
row.map(cell => cell.toString().padStart(6)).join(' ')
).join('\n');
}
Display formatting breakdown:
matrix.map(row =>
- Transform each row of the matrixrow.map(cell =>
- Transform each cell in the rowcell.toString()
- Convert number to string.padStart(6)
- Add spaces to make string 6 characters wide.join(' ')
- Combine cells in row with spaces between.join('\n')
- Combine rows with newlines between
Matrix Example:
const matrixCalc = new MatrixCalculator();
const matrix1 = [[1, 2], [3, 4]];
const matrix2 = [[5, 6], [7, 8]];
const sum = matrixCalc.addMatrices(matrix1, matrix2);
const product = matrixCalc.multiplyMatrices(matrix1, matrix2);
console.log("Matrix Addition:");
console.log(matrixCalc.displayMatrix(sum));
console.log("Matrix Multiplication:");
console.log(matrixCalc.displayMatrix(product));
Matrix example explanation:
const matrix1 = [[1, 2], [3, 4]]
- 2x2 matrix using nested arrays[1, 2]
- First row[3, 4]
- Second row
const sum = matrixCalc.addMatrices(matrix1, matrix2)
- Add matrices element by elementmatrixCalc.displayMatrix(sum)
- Format matrix for readable output
๐ฒ Random Number Generator with Arrays
Advanced Random Functions
class RandomCalculator {
constructor() {
this.generatedNumbers = [];
this.seeds = [];
}
// Generate random integers in range
generateIntegers(count, min, max) {
const numbers = [];
for (let i = 0; i < count; i++) {
const randomInt = Math.floor(Math.random() * (max - min + 1)) + min;
numbers.push(randomInt);
}
this.generatedNumbers.push(...numbers);
return numbers;
}
// Generate random decimals
generateDecimals(count, min, max, precision = 2) {
const numbers = [];
for (let i = 0; i < count; i++) {
const randomDecimal = (Math.random() * (max - min) + min).toFixed(precision);
numbers.push(parseFloat(randomDecimal));
}
this.generatedNumbers.push(...numbers);
return numbers;
}
// Shuffle an array (Fisher-Yates algorithm)
shuffleArray(array) {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
// Pick random elements from array
pickRandom(array, count = 1) {
const shuffled = this.shuffleArray(array);
return shuffled.slice(0, count);
}
// Generate random sequence
generateSequence(start, step, count) {
const sequence = [];
let current = start;
for (let i = 0; i < count; i++) {
sequence.push(current);
current += step + Math.floor(Math.random() * 3); // Add some randomness to step
}
return sequence;
}
// Get statistics of generated numbers
getStats() {
if (this.generatedNumbers.length === 0) return null;
const sorted = [...this.generatedNumbers].sort((a, b) => a - b);
return {
count: this.generatedNumbers.length,
min: sorted[0],
max: sorted[sorted.length - 1],
mean: this.generatedNumbers.reduce((sum, n) => sum + n, 0) / this.generatedNumbers.length,
numbers: [...this.generatedNumbers]
};
}
}
๐ Line-by-Line Explanation: Random Number Generator
generateIntegers(count, min, max) {
const numbers = [];
for (let i = 0; i < count; i++) {
const randomInt = Math.floor(Math.random() * (max - min + 1)) + min;
numbers.push(randomInt);
}
this.generatedNumbers.push(...numbers);
return numbers;
}
Random integer generation:
generateIntegers(count, min, max)
- Method to create random whole numbersconst numbers = []
- Array to collect generated numbersfor (let i = 0; i < count; i++)
- Loop to generate โcountโ numbersMath.random()
- Generates decimal between 0 and 1Math.random() * (max - min + 1)
- Scale to desired range(max - min + 1)
- Range size (inclusive of both min and max)
Math.floor(...)
- Rounds down to nearest integer+ min
- Shifts range to start at minimum value- Example: For min=1, max=6:
Math.floor(Math.random() * 6) + 1
gives 1-6
generateDecimals(count, min, max, precision = 2) {
const numbers = [];
for (let i = 0; i < count; i++) {
const randomDecimal = (Math.random() * (max - min) + min).toFixed(precision);
numbers.push(parseFloat(randomDecimal));
}
this.generatedNumbers.push(...numbers);
return numbers;
}
Random decimal generation:
precision = 2
- Default to 2 decimal placesMath.random() * (max - min) + min
- Scale random number to range.toFixed(precision)
- Rounds to specified decimal places and converts to stringparseFloat(randomDecimal)
- Converts string back to number
shuffleArray(array) {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
Fisher-Yates shuffle algorithm:
const shuffled = [...array]
- Create copy to avoid modifying originalfor (let i = shuffled.length - 1; i > 0; i--)
- Loop backwards through array- Start from last element, go down to index 1
const j = Math.floor(Math.random() * (i + 1))
- Pick random index from 0 to i[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
- Swap elements- Array destructuring assignment to swap values
- Swaps element at position i with element at random position j
pickRandom(array, count = 1) {
const shuffled = this.shuffleArray(array);
return shuffled.slice(0, count);
}
Random selection:
count = 1
- Default to picking 1 elementthis.shuffleArray(array)
- First shuffle the arrayshuffled.slice(0, count)
- Take first โcountโ elements from shuffled arrayslice(0, count)
- Creates new array with elements from index 0 to count-1
๐ Calculator Challenge Projects
Challenge 1: Scientific Calculator Array
// Build a calculator that handles scientific functions with arrays
class ScientificCalculator {
constructor() {
this.angleMode = 'degrees'; // or 'radians'
this.constants = {
PI: Math.PI,
E: Math.E,
GOLDEN_RATIO: (1 + Math.sqrt(5)) / 2
};
this.history = [];
}
// Convert degrees to radians if needed
toRadians(angle) {
return this.angleMode === 'degrees' ? angle * (Math.PI / 180) : angle;
}
// Trigonometric functions
sin(angle) { return Math.sin(this.toRadians(angle)); }
cos(angle) { return Math.cos(this.toRadians(angle)); }
tan(angle) { return Math.tan(this.toRadians(angle)); }
// Array-based factorial
factorial(n) {
if (n < 0) return null;
if (n <= 1) return 1;
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
// Fibonacci sequence using arrays
fibonacci(n) {
if (n <= 0) return [];
if (n === 1) return [0];
if (n === 2) return [0, 1];
const fib = [0, 1];
for (let i = 2; i < n; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
return fib;
}
// Calculate polynomial with coefficients array
polynomial(coefficients, x) {
let result = 0;
for (let i = 0; i < coefficients.length; i++) {
result += coefficients[i] * Math.pow(x, coefficients.length - 1 - i);
}
return result;
}
}
๐ Line-by-Line Explanation: Scientific Calculator
constructor() {
this.angleMode = 'degrees'; // or 'radians'
this.constants = {
PI: Math.PI,
E: Math.E,
GOLDEN_RATIO: (1 + Math.sqrt(5)) / 2
};
this.history = [];
}
Scientific calculator setup:
this.angleMode = 'degrees'
- Set default angle measurementthis.constants = {...}
- Object storing mathematical constantsPI: Math.PI
- Pi constant (approximately 3.14159)E: Math.E
- Eulerโs number (approximately 2.71828)GOLDEN_RATIO: (1 + Math.sqrt(5)) / 2
- Golden ratio calculationMath.sqrt(5)
- Square root of 5(1 + ...) / 2
- Golden ratio formula
toRadians(angle) {
return this.angleMode === 'degrees' ? angle * (Math.PI / 180) : angle;
}
Angle conversion:
this.angleMode === 'degrees'
- Check if calculator is in degree mode? angle * (Math.PI / 180)
- If degrees, convert to radians- Multiply by ฯ/180 to convert degrees to radians
: angle
- If already in radians, return unchanged
factorial(n) {
if (n < 0) return null;
if (n <= 1) return 1;
let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}
Factorial calculation:
if (n < 0) return null
- Factorial undefined for negative numbersif (n <= 1) return 1
- Base cases: 0! = 1, 1! = 1let result = 1
- Initialize resultfor (let i = 2; i <= n; i++)
- Loop from 2 to nresult *= i
- Multiply result by current number*=
is shorthand forresult = result * i
fibonacci(n) {
if (n <= 0) return [];
if (n === 1) return [0];
if (n === 2) return [0, 1];
const fib = [0, 1];
for (let i = 2; i < n; i++) {
fib[i] = fib[i - 1] + fib[i - 2];
}
return fib;
}
Fibonacci sequence generation:
if (n <= 0) return []
- Return empty array for invalid inputif (n === 1) return [0]
- First Fibonacci number is 0if (n === 2) return [0, 1]
- First two Fibonacci numbersconst fib = [0, 1]
- Initialize array with first two numbersfib[i] = fib[i - 1] + fib[i - 2]
- Each number is sum of previous twofib[i - 1]
- Previous number in sequencefib[i - 2]
- Number before that
polynomial(coefficients, x) {
let result = 0;
for (let i = 0; i < coefficients.length; i++) {
result += coefficients[i] * Math.pow(x, coefficients.length - 1 - i);
}
return result;
}
Polynomial evaluation:
polynomial(coefficients, x)
- Evaluate polynomial at value xcoefficients
- Array of polynomial coefficients [a, b, c, d] for axยณ + bxยฒ + cx + dfor (let i = 0; i < coefficients.length; i++)
- Loop through coefficientscoefficients[i]
- Current coefficientMath.pow(x, coefficients.length - 1 - i)
- x raised to appropriate powercoefficients.length - 1 - i
- Calculate power (highest power first)
result += ...
- Add term to running total
Challenge 2: Financial Calculator
class FinancialCalculator {
constructor() {
this.transactions = [];
this.rates = [];
}
// Compound interest calculation
compoundInterest(principal, rate, time, frequency = 12) {
const amount = principal * Math.pow(1 + rate / frequency, frequency * time);
return {
principal: principal,
amount: amount,
interest: amount - principal,
rate: rate,
time: time
};
}
// Loan payment calculator
loanPayment(principal, rate, payments) {
const monthlyRate = rate / 12;
const payment = principal * (monthlyRate * Math.pow(1 + monthlyRate, payments)) /
(Math.pow(1 + monthlyRate, payments) - 1);
// Generate amortization schedule
const schedule = [];
let balance = principal;
for (let i = 1; i <= payments; i++) {
const interestPayment = balance * monthlyRate;
const principalPayment = payment - interestPayment;
balance -= principalPayment;
schedule.push({
payment: i,
paymentAmount: payment,
principal: principalPayment,
interest: interestPayment,
balance: Math.max(0, balance)
});
}
return schedule;
}
// Investment return calculator
investmentGrowth(initialInvestment, monthlyContribution, annualReturn, years) {
const monthlyReturn = annualReturn / 12;
const months = years * 12;
const growth = [];
let balance = initialInvestment;
for (let month = 1; month <= months; month++) {
balance += monthlyContribution;
balance *= (1 + monthlyReturn);
if (month % 12 === 0) {
growth.push({
year: month / 12,
balance: balance,
totalContributions: initialInvestment + (monthlyContribution * month),
earnings: balance - (initialInvestment + monthlyContribution * month)
});
}
}
return growth;
}
}
๐ Line-by-Line Explanation: Financial Calculator
compoundInterest(principal, rate, time, frequency = 12) {
const amount = principal * Math.pow(1 + rate / frequency, frequency * time);
return {
principal: principal,
amount: amount,
interest: amount - principal,
rate: rate,
time: time
};
}
Compound interest formula:
frequency = 12
- Default to monthly compoundingprincipal * Math.pow(1 + rate / frequency, frequency * time)
- Compound interest formularate / frequency
- Interest rate per compounding period1 + rate / frequency
- Growth factor per periodfrequency * time
- Total number of compounding periodsMath.pow(base, exponent)
- Raises base to the power of exponent
interest: amount - principal
- Calculate total interest earned
loanPayment(principal, rate, payments) {
const monthlyRate = rate / 12;
const payment = principal * (monthlyRate * Math.pow(1 + monthlyRate, payments)) /
(Math.pow(1 + monthlyRate, payments) - 1);
Loan payment calculation:
const monthlyRate = rate / 12
- Convert annual rate to monthly- Complex loan payment formula:
monthlyRate * Math.pow(1 + monthlyRate, payments)
- NumeratorMath.pow(1 + monthlyRate, payments) - 1
- Denominator- This formula calculates fixed monthly payment for loan
// Generate amortization schedule
const schedule = [];
let balance = principal;
for (let i = 1; i <= payments; i++) {
const interestPayment = balance * monthlyRate;
const principalPayment = payment - interestPayment;
balance -= principalPayment;
schedule.push({
payment: i,
paymentAmount: payment,
principal: principalPayment,
interest: interestPayment,
balance: Math.max(0, balance)
});
}
Amortization schedule generation:
const schedule = []
- Array to store payment breakdownlet balance = principal
- Track remaining loan balancefor (let i = 1; i <= payments; i++)
- Loop for each paymentconst interestPayment = balance * monthlyRate
- Interest portion of paymentconst principalPayment = payment - interestPayment
- Principal portionbalance -= principalPayment
- Reduce remaining balanceMath.max(0, balance)
- Ensure balance never goes below zero
๐ก Pro Tips for Array-Based Calculators
Performance Optimization
// Efficient array operations for large datasets
class OptimizedCalculator {
// Use typed arrays for better performance with large numbers
createTypedArray(size, type = 'Float64Array') {
switch(type) {
case 'Int32Array': return new Int32Array(size);
case 'Float32Array': return new Float32Array(size);
case 'Float64Array': return new Float64Array(size);
default: return new Array(size);
}
}
// Batch operations for better performance
batchCalculate(numbers, operation) {
const results = new Array(numbers.length);
for (let i = 0; i < numbers.length; i++) {
switch(operation) {
case 'square': results[i] = numbers[i] * numbers[i]; break;
case 'sqrt': results[i] = Math.sqrt(numbers[i]); break;
case 'log': results[i] = Math.log(numbers[i]); break;
default: results[i] = numbers[i];
}
}
return results;
}
}
๐ Line-by-Line Explanation: Performance Optimization
createTypedArray(size, type = 'Float64Array') {
switch(type) {
case 'Int32Array': return new Int32Array(size);
case 'Float32Array': return new Float32Array(size);
case 'Float64Array': return new Float64Array(size);
default: return new Array(size);
}
}
Typed arrays for performance:
createTypedArray(size, type = 'Float64Array')
- Create optimized arrayswitch(type)
- Choose array type based on datanew Int32Array(size)
- Array for 32-bit integers (faster than regular arrays)new Float32Array(size)
- Array for 32-bit floating point numbersnew Float64Array(size)
- Array for 64-bit floating point numbers- Typed arrays use less memory and are faster for numerical computations
batchCalculate(numbers, operation) {
const results = new Array(numbers.length);
for (let i = 0; i < numbers.length; i++) {
switch(operation) {
case 'square': results[i] = numbers[i] * numbers[i]; break;
case 'sqrt': results[i] = Math.sqrt(numbers[i]); break;
case 'log': results[i] = Math.log(numbers[i]); break;
default: results[i] = numbers[i];
}
}
return results;
}
Batch processing explanation:
const results = new Array(numbers.length)
- Pre-allocate result array- Pre-allocation is faster than growing array dynamically
for (let i = 0; i < numbers.length; i++)
- Process each numbercase 'square': results[i] = numbers[i] * numbers[i]
- Square operationMath.sqrt(numbers[i])
- Square root operationMath.log(numbers[i])
- Natural logarithm operation- Processing in batches is more efficient than individual operations
๐ฏ Your Array Calculator Mission
Build Your Ultimate Calculator!
Now itโs your turn! Create a calculator that combines multiple array features:
- ๐ฑ Basic Calculator - Addition, subtraction, multiplication, division
- ๐ History System - Store and recall calculations
- ๐ Statistics Mode - Mean, median, mode calculations
- ๐ข Multi-Number Operations - Work with datasets
- ๐พ Memory Functions - Store and recall values
- ๐ฒ Random Generator - Generate number sets
- ๐ Advanced Functions - Scientific or financial calculations
Starter Template:
class UltimateCalculator {
constructor() {
this.history = [];
this.memory = [];
this.currentDataset = [];
// Add your properties here
}
// Implement your calculator methods here
calculate(operation, ...args) {
// Your calculation logic
}
// Add more methods for different features
}
๐ Starter Template Explanation:
class UltimateCalculator {
constructor() {
this.history = []; // Array to store calculation history
this.memory = []; // Array for memory storage functions
this.currentDataset = []; // Array for statistical operations
// Add your properties here
}
Template breakdown:
class UltimateCalculator
- Create your custom calculator classthis.history = []
- Store all calculations for undo/redo functionalitythis.memory = []
- Implement memory store/recall featuresthis.currentDataset = []
- Hold numbers for statistical calculations
calculate(operation, ...args) {
// Your calculation logic
}
calculate(operation, ...args)
- Main calculation method...args
- Rest parameter to accept any number of arguments- This method should handle different types of operations
๐ Ready to Build?
Arrays transform simple calculators into powerful computational tools! With the techniques in this guide, you can create calculators that:
- Remember everything with history arrays
- Handle complex data with multi-dimensional arrays
- Perform advanced statistics with data processing
- Support scientific functions with mathematical arrays
- Manage financial calculations with structured data
Your challenge: Pick one of the calculator examples and extend it with your own creative features!
Happy coding! ๐
๐ Cell 2 Table of Contents
๐๏ธ Complete Navigation Guide
๐ฏ Detailed Section Breakdown
๐ฐ Foundation Level (Start Here)
- ๐ง Array Hack Challenge: Building Better Calculators
- Welcome and introduction to array-powered calculators
- ๐ Why Arrays Make Calculators Amazing
- โ History Tracking capabilities
- โ Multi-Number Operations
- โ Statistical Functions
- โ Memory Functions
- โ Advanced Operations
- ๐ฏ Calculator Array Fundamentals
- Basic Calculator Memory System - Core array concepts
- ๐ Line-by-Line Explanation: Basic Memory System - Detailed code breakdown
- Example Usage - Practical implementation examples
๐ธ Intermediate Level
- ๐งฎ Advanced Calculator Features with Arrays
- Multi-Number Operations - ArrayCalculator class implementation
- ๐ Line-by-Line Explanation: Array Calculator - Comprehensive code analysis
- Usage Example - Practical applications
- ๐ Statistical Calculator Functions
- Advanced Statistics with Arrays - Mean, median, mode calculations
- ๐ Line-by-Line Explanation: Statistical Calculator - Detailed function breakdown
- Statistics Example - Real-world statistical computing
- ๐ฎ Interactive Calculator Features
- Calculator History with Undo/Redo - State management with arrays
- ๐ Line-by-Line Explanation: History Calculator - Navigation system analysis
๐บ Advanced Level
- ๐ฌ Matrix Calculator with Arrays
- 2D Arrays for Matrix Operations - Linear algebra implementation
- ๐ Line-by-Line Explanation: Matrix Calculator - Matrix math breakdown
- Matrix Example - Complex mathematical operations
- ๐ฒ Random Number Generator with Arrays
- Advanced Random Functions - Probability and distribution systems
- ๐ Line-by-Line Explanation: Random Number Generator - Algorithm analysis
๐๏ธ Project Challenges
- ๐ Calculator Challenge Projects
- Challenge 1: Scientific Calculator Array - Advanced mathematical functions
- ๐ Line-by-Line Explanation: Scientific Calculator - Scientific computing breakdown
- Challenge 2: Financial Calculator - Economic and financial calculations
- ๐ Line-by-Line Explanation: Financial Calculator - Financial algorithm analysis
โก Optimization & Best Practices
- ๐ก Pro Tips for Array-Based Calculators
- Performance Optimization - Efficient array operations
- ๐ Line-by-Line Explanation: Performance Optimization - Speed and memory improvements
- ๐ฏ Your Array Calculator Mission
- Build Your Ultimate Calculator! - Final project guidelines
- Starter Template - Foundation code structure
- ๐ Starter Template Explanation - Template code analysis
- ๐ Ready to Build? - Launch your calculator project
๐ Learning Progression Guide
๐ Recommended Path for Different Levels:
๐ฐ Beginner | ๐ธ Intermediate | ๐บ Advanced |
---|---|---|
1. Why Arrays Amazing | 1. Advanced Features | 1. Matrix Calculator |
2. Array Fundamentals | 2. Statistical Functions | 2. Random Generator |
3. Basic Memory System | 3. Interactive Features | 3. Challenge Projects |
4. Example Usage | 4. Usage Examples | 4. Performance Tips |
๐ฏ Key Skills Youโll Master:
- โ
Array Fundamentals:
push()
,pop()
,shift()
,slice()
- โ Object-Oriented Programming: Classes, methods, inheritance
- โ State Management: History tracking, undo/redo systems
- โ Mathematical Computing: Statistics, linear algebra, financial calculations
- โ Performance Optimization: Efficient algorithms and memory management
- โ Code Organization: Modular design and best practices
๐ Quick Start Navigation
Choose your learning path:
- ๐ฐ New to Arrays? โ Start with ๐ Why Arrays Make Calculators Amazing
- ๐ธ Know Basic Arrays? โ Jump to ๐งฎ Advanced Calculator Features
- ๐บ Ready for Challenges? โ Go to ๐ Calculator Challenge Projects
- โก Want to Optimize? โ Check ๐ก Pro Tips
๐ฏ Integrating Arrays into Starter Calculator Template
Letโs take the basic starter calculator and supercharge it with array functionality! Hereโs how to transform the simple calculator into a powerful array-enhanced tool.
๐ง Enhanced Starter Calculator with Array Features
---
title: JS Array-Enhanced Calculator
comments: true
hide: true
layout: opencs
description: A starter calculator enhanced with powerful array functionality for history, memory, and advanced operations.
permalink: /array-calculator
---
<!-- Enhanced Calculator with Array Features -->
<style>
.calculator-output {
grid-column: span 4;
grid-row: span 1;
border-radius: 10px;
padding: 0.25em;
font-size: 20px;
border: 5px solid black;
display: flex;
align-items: center;
justify-content: flex-end; /* Right align result */
}
/* History display styling */
.history-display {
grid-column: span 4;
max-height: 100px;
overflow-y: auto;
background: #f0f8ff;
border: 2px solid #4682b4;
border-radius: 8px;
padding: 8px;
font-size: 12px;
margin-bottom: 10px;
}
/* Memory indicator */
.memory-indicator {
position: absolute;
top: 5px;
right: 5px;
background: #32cd32;
color: white;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 10px;
font-weight: bold;
}
canvas {
filter: none;
}
</style>
<!-- Add a container for the animation -->
<div id="animation">
<div class="calculator-container" style="position: relative;">
<!-- Memory indicator (hidden by default) -->
<div class="memory-indicator" id="memoryIndicator" style="display: none;">M</div>
<!-- History display -->
<div class="history-display" id="historyDisplay">
<strong>History:</strong><br>
<span id="historyContent">No calculations yet</span>
</div>
<!-- Main display -->
<div class="calculator-output" id="output">0</div>
<!-- Calculator buttons -->
<!--row 1-->
<div class="calculator-number">1</div>
<div class="calculator-number">2</div>
<div class="calculator-number">3</div>
<div class="calculator-operation">+</div>
<!--row 2-->
<div class="calculator-number">4</div>
<div class="calculator-number">5</div>
<div class="calculator-number">6</div>
<div class="calculator-operation">-</div>
<!--row 3-->
<div class="calculator-number">7</div>
<div class="calculator-number">8</div>
<div class="calculator-number">9</div>
<div class="calculator-operation">*</div>
<!--row 4-->
<div class="calculator-clear">A/C</div>
<div class="calculator-number">0</div>
<div class="calculator-number">.</div>
<div class="calculator-operation">/</div>
<!--row 5 - Array enhanced buttons-->
<div class="calculator-operation" id="memStore">MS</div> <!-- Memory Store -->
<div class="calculator-operation" id="memRecall">MR</div> <!-- Memory Recall -->
<div class="calculator-operation" id="memClear">MC</div> <!-- Memory Clear -->
<div class="calculator-equals">=</div>
</div>
</div>
<!-- JavaScript with Array Integration -->
<script>
// ===== ARRAY-ENHANCED CALCULATOR =====
// Original calculator variables
var firstNumber = null; // stores the first number in calculation
var operator = null; // stores the current operator (+, -, *, /)
var nextReady = true; // flag for new number input
// ===== ARRAY FUNCTIONALITY =====
// Array-based memory system
let calculatorMemory = []; // array to store memory values
let calculationHistory = []; // array to store calculation history
let currentNumbers = []; // array for multi-number operations
// ===== DOM ELEMENTS =====
const output = document.getElementById("output"); // calculator display
const numbers = document.querySelectorAll(".calculator-number"); // number buttons
const operations = document.querySelectorAll(".calculator-operation"); // operation buttons
const clear = document.querySelectorAll(".calculator-clear"); // clear button
const equals = document.querySelectorAll(".calculator-equals"); // equals button
const historyContent = document.getElementById("historyContent"); // history display
const memoryIndicator = document.getElementById("memoryIndicator"); // memory indicator
// ===== ARRAY-ENHANCED FUNCTIONS =====
// Store calculation in history array
function storeCalculation(operation, result) {
// Create calculation object with operation details
const calculation = {
operation: operation, // the math operation performed
result: result, // the calculated result
timestamp: new Date().toLocaleString() // when calculation happened
};
// Add to history array using push()
calculationHistory.push(calculation);
// Keep only last 5 calculations to save space
if (calculationHistory.length > 5) {
calculationHistory.shift(); // remove first (oldest) element
}
// Update history display
updateHistoryDisplay();
}
// Update the visual history display
function updateHistoryDisplay() {
if (calculationHistory.length === 0) {
historyContent.innerHTML = "No calculations yet";
return;
}
// Build HTML string from history array
let historyHTML = "";
calculationHistory.forEach((calc, index) => {
historyHTML += `${calc.operation} = ${calc.result}<br>`;
});
historyContent.innerHTML = historyHTML;
}
// Memory store function using arrays
function memoryStore(value) {
calculatorMemory.push(value); // add value to memory array
console.log(`Stored: ${value}`); // log confirmation
memoryIndicator.style.display = "flex"; // show memory indicator
// Keep only last 3 memory values
if (calculatorMemory.length > 3) {
calculatorMemory.shift(); // remove oldest memory
}
}
// Memory recall function
function memoryRecall() {
// Check if memory array has values
if (calculatorMemory.length > 0) {
// Return last stored value (most recent)
return calculatorMemory[calculatorMemory.length - 1];
}
return 0; // return 0 if no memory
}
// Memory clear function
function memoryClear() {
calculatorMemory = []; // empty the memory array
memoryIndicator.style.display = "none"; // hide memory indicator
console.log("Memory cleared!");
}
// ===== ENHANCED CALCULATOR FUNCTIONS =====
// Number button listeners (same as original)
numbers.forEach(button => {
button.addEventListener("click", function() {
number(button.textContent);
});
});
// Enhanced number function with array logging
function number(value) {
if (value != ".") {
if (nextReady == true) {
output.innerHTML = value;
if (value != "0") {
nextReady = false;
}
} else {
output.innerHTML = output.innerHTML + value;
}
} else {
// Decimal point handling
if (output.innerHTML.indexOf(".") == -1) {
output.innerHTML = output.innerHTML + value;
nextReady = false;
}
}
}
// Operation button listeners (enhanced)
operations.forEach(button => {
// Skip memory buttons - they have separate listeners
if (!["MS", "MR", "MC"].includes(button.textContent)) {
button.addEventListener("click", function() {
operation(button.textContent);
});
}
});
// Enhanced operation function with history tracking
function operation(choice) {
if (firstNumber == null) {
firstNumber = parseInt(output.innerHTML);
nextReady = true;
operator = choice;
return;
}
// Perform calculation and store in history
const secondNumber = parseFloat(output.innerHTML);
const result = calculate(firstNumber, secondNumber);
// Store calculation in history array
const operationString = `${firstNumber} ${operator} ${secondNumber}`;
storeCalculation(operationString, result);
firstNumber = result;
operator = choice;
output.innerHTML = firstNumber.toString();
nextReady = true;
}
// Calculate function (same as original but with division added)
function calculate(first, second) {
let result = 0;
switch (operator) {
case "+":
result = first + second;
break;
case "-":
result = first - second;
break;
case "*":
result = first * second;
break;
case "/":
result = second !== 0 ? first / second : "Error"; // Added division with zero check
break;
default:
break;
}
return result;
}
// Enhanced equals function with history
equals.forEach(button => {
button.addEventListener("click", function() {
equal();
});
});
function equal() {
if (firstNumber !== null && operator !== null) {
const secondNumber = parseFloat(output.innerHTML);
const result = calculate(firstNumber, secondNumber);
// Store final calculation in history
const operationString = `${firstNumber} ${operator} ${secondNumber}`;
storeCalculation(operationString, result);
output.innerHTML = result.toString();
firstNumber = null;
operator = null;
nextReady = true;
}
}
// Enhanced clear function
clear.forEach(button => {
button.addEventListener("click", function() {
clearCalc();
});
});
function clearCalc() {
firstNumber = null;
operator = null;
output.innerHTML = "0";
nextReady = true;
// Note: History and memory persist through clear
}
// ===== MEMORY BUTTON LISTENERS =====
// Memory Store button
document.getElementById("memStore").addEventListener("click", function() {
const currentValue = parseFloat(output.innerHTML);
memoryStore(currentValue);
});
// Memory Recall button
document.getElementById("memRecall").addEventListener("click", function() {
const recalledValue = memoryRecall();
output.innerHTML = recalledValue.toString();
nextReady = true;
});
// Memory Clear button
document.getElementById("memClear").addEventListener("click", function() {
memoryClear();
});
// ===== ARRAY UTILITY FUNCTIONS =====
// Function to get full calculation history
function getCalculationHistory() {
return calculationHistory; // return the entire history array
}
// Function to get memory contents
function getMemoryContents() {
return calculatorMemory; // return the entire memory array
}
// Function to clear all history
function clearHistory() {
calculationHistory = []; // empty history array
updateHistoryDisplay(); // refresh display
}
// ===== CONSOLE HELPERS FOR TESTING =====
// These functions can be called from browser console for testing
// Log current state
function logCalculatorState() {
console.log("=== CALCULATOR STATE ===");
console.log("Current Display:", output.innerHTML);
console.log("First Number:", firstNumber);
console.log("Operator:", operator);
console.log("Next Ready:", nextReady);
console.log("Memory Array:", calculatorMemory);
console.log("History Array:", calculationHistory);
}
// Test memory functions
function testMemoryFunctions() {
console.log("=== TESTING MEMORY ===");
memoryStore(42);
memoryStore(100);
console.log("Memory after storing 42 and 100:", calculatorMemory);
console.log("Memory recall:", memoryRecall());
memoryClear();
console.log("Memory after clear:", calculatorMemory);
}
// Test history functions
function testHistoryFunctions() {
console.log("=== TESTING HISTORY ===");
storeCalculation("5 + 3", 8);
storeCalculation("10 * 2", 20);
storeCalculation("15 - 7", 8);
console.log("History after adding calculations:", calculationHistory);
console.log("Getting full history:", getCalculationHistory());
}
</script>
<!-- Vanta animations (same as original) -->
<script src="/team1-lessons/assets/js/three.r119.min.js"></script>
<script src="/team1-lessons/assets/js/vanta.halo.min.js"></script>
<script src="/team1-lessons/assets/js/vanta.birds.min.js"></script>
<script src="/team1-lessons/assets/js/vanta.net.min.js"></script>
<script src="/team1-lessons/assets/js/vanta.rings.min.js"></script>
<script>
// Vanta animation setup (same as original)
var vantaInstances = {
halo: VANTA.HALO,
birds: VANTA.BIRDS,
net: VANTA.NET,
rings: VANTA.RINGS
};
var vantaInstance = vantaInstances[Object.keys(vantaInstances)[Math.floor(Math.random() * Object.keys(vantaInstances).length)]];
vantaInstance({
el: "#animation",
mouseControls: true,
touchControls: true,
gyroControls: false
});
</script>
๐ Key Array Enhancements Made:
- ๐ History Array System:
calculationHistory[]
- Stores all calculations with timestampsstoreCalculation()
- Adds new calculations to historyupdateHistoryDisplay()
- Shows recent calculations on screen
- ๐พ Memory Array Functions:
calculatorMemory[]
- Stores multiple memory valuesmemoryStore()
- Adds values to memory usingpush()
memoryRecall()
- Gets last stored value using array indexing- Visual memory indicator when values are stored
- ๐ฏ Enhanced User Interface:
- History display panel showing recent calculations
- Memory indicator (M) when values are stored
- New memory buttons: MS (Store), MR (Recall), MC (Clear)
- Division operator added to complete basic operations
- ๐ง Array Management:
- Automatic history limiting (keeps last 5 calculations)
- Memory limiting (keeps last 3 values)
- Array manipulation using
push()
,shift()
, and indexing
- ๐งช Testing Functions:
- Console helper functions for debugging
- State logging for development
- Test functions for memory and history features
๐ก How Arrays Transform the Calculator:
Before (Basic): Simple calculator that forgets everything after each calculation
After (Array-Enhanced): Powerful calculator that:
- โ Remembers calculation history
- โ Stores multiple memory values
- โ Provides visual feedback
- โ Handles advanced operations
- โ Offers debugging capabilities
This demonstrates how arrays can transform a basic calculator into a professional-grade computational tool! ๐