UNPKG

bowling-analysis-system

Version:

A comprehensive system for analyzing bowling techniques using video processing and metrics calculation

162 lines (143 loc) 4.64 kB
/** * @module utils/helpers * @description Common utility functions for the bowling analysis system */ const fs = require('fs'); const path = require('path'); /** * Ensures a directory exists, creates it if it doesn't * @param {string} dirPath - Directory path to ensure * @returns {boolean} Whether the directory exists or was created */ function ensureDirectoryExists(dirPath) { if (!fs.existsSync(dirPath)) { try { fs.mkdirSync(dirPath, { recursive: true }); return true; } catch (error) { console.error(`Error creating directory ${dirPath}: ${error.message}`); return false; } } return true; } /** * Loads JSON data from a file * @param {string} filePath - Path to the JSON file * @param {boolean} [silent=false] - Whether to suppress error messages * @returns {Object|null} Parsed JSON data or null if error */ function loadJsonFromFile(filePath, silent = false) { try { const resolvedPath = path.resolve(filePath); if (!fs.existsSync(resolvedPath)) { if (!silent) { console.warn(`File not found: ${resolvedPath}`); } return null; } const data = fs.readFileSync(resolvedPath, 'utf8'); return JSON.parse(data); } catch (error) { if (!silent) { console.error(`Error loading JSON from ${filePath}: ${error.message}`); } return null; } } /** * Saves data as JSON to a file * @param {string} filePath - Path to save the file * @param {Object} data - Data to save * @param {boolean} [createDir=true] - Whether to create directory if it doesn't exist * @returns {boolean} Whether the save was successful */ function saveJsonToFile(filePath, data, createDir = true) { try { const resolvedPath = path.resolve(filePath); const dirPath = path.dirname(resolvedPath); if (createDir) { ensureDirectoryExists(dirPath); } fs.writeFileSync(resolvedPath, JSON.stringify(data, null, 2)); return true; } catch (error) { console.error(`Error saving JSON to ${filePath}: ${error.message}`); return false; } } /** * Calculates the mean of an array of numbers * @param {Array<number>} values - Array of numerical values * @returns {number} Mean value */ function calculateMean(values) { if (!values || values.length === 0) return 0; return values.reduce((sum, val) => sum + val, 0) / values.length; } /** * Calculates standard deviation of an array of numbers * @param {Array<number>} values - Array of numerical values * @returns {number} Standard deviation */ function calculateStandardDeviation(values) { if (!values || values.length <= 1) return 0; const mean = calculateMean(values); const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length; return Math.sqrt(variance); } /** * Smooths an array using a moving average * @param {Array<number>} values - Array of values to smooth * @param {number} windowSize - Size of the smoothing window * @returns {Array<number>} Smoothed values */ function smoothArray(values, windowSize = 3) { if (!values || values.length === 0) return []; if (windowSize <= 1) return [...values]; const halfWindow = Math.floor(windowSize / 2); const result = []; for (let i = 0; i < values.length; i++) { let sum = 0; let count = 0; for (let j = Math.max(0, i - halfWindow); j <= Math.min(values.length - 1, i + halfWindow); j++) { if (values[j] !== null && values[j] !== undefined) { sum += values[j]; count++; } } result[i] = count > 0 ? sum / count : values[i]; } return result; } /** * Gets filename without extension * @param {string} filePath - File path * @returns {string} Filename without extension */ function getFilenameWithoutExtension(filePath) { const basename = path.basename(filePath); const lastDotIndex = basename.lastIndexOf('.'); return lastDotIndex === -1 ? basename : basename.slice(0, lastDotIndex); } /** * Generate a UUID v4 * @returns {string} A UUID v4 string */ function generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0; const v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } module.exports = { ensureDirectoryExists, loadJsonFromFile, saveJsonToFile, calculateMean, calculateStandardDeviation, smoothArray, getFilenameWithoutExtension, generateUUID };