wilks-calculator
Version:
This library calculates performs calculations with the Wilks coefficient, which is a coefficient used by the International Powerlifting Federation to determine the relative strength of competitors. They also use this coefficient for determining the qual
181 lines (152 loc) • 5.88 kB
JavaScript
;
const maleValues = [
-216.0475144,
16.2606339,
-0.002388645,
-0.00113732,
7.01863E-06,
-1.291E-08
];
const femaleValues = [
594.31747775582,
-27.23842536447,
0.82112226871,
-0.00930733913,
4.731582E-05,
-9.054E-08
];
const imperial = 2.20462262185;
/**
* Returns a Wilks score based on the body weight of the lifter and the weight they have lifted.
*
* @param gender {string} The gender of the lifter the wilks score is calculated for ('m' for male, 'f' for female).
* @param bodyWeight {number} The body weight of the lifter the wilks score is calculated for.
* @param liftedWeight {number} The weight the lifter has lifted.
* @param unitType {string} Optional parameter for lifters using the imperial unit system ('kg' is default, 'imperial' for the imperial system).
*
* @returns {number} The Wilks score.
*/
function calculateWilksScore (gender, bodyWeight, liftedWeight, unitType = 'metric') {
if (!gender || !bodyWeight || !liftedWeight) {
throw new Error('Missing parameters, please fill in gender, body weight and weight.');
}
if (unitType === 'imperial') {
liftedWeight /= imperial;
bodyWeight /= imperial;
}
validateInput({gender: gender, bodyWeight: bodyWeight, liftedWeight: liftedWeight, unitType: unitType});
let coeff = 500 / calculateCoefficient(gender, bodyWeight);
return liftedWeight * coeff;
}
/**
* Returns a total amount of weight to lift based on the body weight of the lifter and the preferred Wilks score.
*
* @param gender {string} The gender of the lifter the wilks score is calculated for ('m' for male, 'f' for female).
* @param bodyWeight {number} The body weight of the lifter the wilks score is calculated for.
* @param wilksScore {number} The preferred Wilks score.
* @param unitType {string} Optional parameter for lifters using the imperial unit system ('kg' is default, 'imperial' for the imperial system).
*
* @returns {number} The total amount of weight to lift.
*/
function calculateWeightToLift (gender, bodyWeight, wilksScore, unitType = 'metric') {
if (!gender || !bodyWeight || !wilksScore) {
throw new Error('Missing parameters, please fill in gender, body weight and Wilks score.');
}
validateInput({gender: gender, bodyWeight: bodyWeight, wilksScore: wilksScore, unitType: unitType});
if (unitType === 'imperial') {
bodyWeight /= imperial;
}
let coeff = 500 / calculateCoefficient(gender, bodyWeight);
return unitType === 'imperial' ? imperial * (wilksScore / coeff) : wilksScore / coeff;
}
/**
* Returns the needed body weight based on the total amount of weight to lift and the preferred Wilks score.
*
* @param gender {string} The gender of the lifter the wilks score is calculated for ('m' for male, 'f' for female).
* @param liftedWeight {number} liftedWeight {number} The weight the lifter has lifted.
* @param wilksScore {number} The preferred Wilks score.
* @param unitType {string} Optional parameter for lifters using the imperial unit system ('kg' is default, 'imperial' for the imperial system).
*
* @returns {number} The total amount of weight to lift.
*/
function calculateNeededBodyWeight (gender, liftedWeight, wilksScore, unitType = 'metric') {
if (!gender || !liftedWeight || !wilksScore) {
throw new Error('Missing parameters, please fill in gender, lifted weight and Wilks score.');
}
validateInput({gender: gender, liftedWeight: liftedWeight, wilksScore: wilksScore, unitType: unitType});
if (unitType === 'imperial') {
liftedWeight /= imperial;
}
let coeff = 500 / (wilksScore / liftedWeight);
let bodyWeight = 0.0;
let result = 0.0;
do {
bodyWeight += 0.1;
result = calculateCoefficient(gender, bodyWeight);
} while (calculateDifference(coeff, result) > 0.5);
return unitType === 'imperial' ? imperial * bodyWeight : bodyWeight;
}
/**
* A helper function to determine the difference between the calculated coefficient and the input.
*
* @param a {number}
* @param b {number}
*
* @returns {number} The absolute difference between a and b.
*
* @private
*/
function calculateDifference(a, b) {
return Math.abs(a - b);
}
/**
* Calculates the coefficient based on the body weight and the gender.
*
* @param gender {string}
* @param bodyWeight {number}
*
* @returns {number} The coefficient.
*
* @private
*/
function calculateCoefficient(gender, bodyWeight) {
let coeff = 0;
let values = gender === 'm' ? maleValues : femaleValues;
for (let i = 0; i <= 5; i++) {
coeff += i === 0 ? values[i] : (values[i] * (bodyWeight ** i));
}
return coeff;
}
/**
* A helper function to validate the input.
*
* @param gender {string}
* @param bodyWeight {number}
* @param liftedWeight {number}
* @param wilksScore {number}
* @param unitType {string}
*
* @private
*/
function validateInput ({gender, bodyWeight = 0, liftedWeight = 0, wilksScore = 0, unitType}) {
if (typeof gender !== 'string' || (gender !== 'm' && gender !== 'f')) {
throw new Error('Gender is not valid. Please select m for Male or f for Female.')
}
if (typeof bodyWeight !== 'number' || bodyWeight < 0) {
throw new Error('Body weight is not valid.');
}
if (typeof liftedWeight !== 'number' || liftedWeight < 0) {
throw new Error('Weight is not valid.');
}
if (typeof wilksScore !== 'number' || wilksScore < 0) {
throw new Error('Wilks score is not valid.');
}
if (typeof unitType !== 'string' || (unitType !== 'metric' && unitType !== 'imperial')) {
throw new Error('Unit type is not valid. Please select metric or imperial.');
}
}
module.exports = {
calculateWilksScore: calculateWilksScore,
calculateWeightToLift: calculateWeightToLift,
calculateNeededBodyWeight: calculateNeededBodyWeight
};