Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
214 lines (184 sloc)
7.83 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import floor | |
from body_scales import bodyScales | |
class bodyMetrics: | |
def __init__(self, weight, height, age, sex, impedance): | |
self.weight = weight | |
self.height = height | |
self.age = age | |
self.sex = sex | |
self.impedance = impedance | |
self.scales = bodyScales(age, height, sex, weight) | |
# Check for potential out of boundaries | |
if self.height > 220: | |
raise Exception("Height is too high (limit: >220cm)") | |
elif weight < 10 or weight > 200: | |
raise Exception("Weight is either too low or too high (limits: <10kg and >200kg)") | |
elif age > 99: | |
raise Exception("Age is too high (limit >99 years)") | |
elif impedance > 3000: | |
raise Exception("Impedance is too high (limit >3000ohm)") | |
# Set the value to a boundary if it overflows | |
def checkValueOverflow(self, value, minimum, maximum): | |
if value < minimum: | |
return minimum | |
elif value > maximum: | |
return maximum | |
else: | |
return value | |
# Get LBM coefficient (with impedance) | |
def getLBMCoefficient(self): | |
lbm = (self.height * 9.058 / 100) * (self.height / 100) | |
lbm += self.weight * 0.32 + 12.226 | |
lbm -= self.impedance * 0.0068 | |
lbm -= self.age * 0.0542 | |
return lbm | |
# Get BMR | |
def getBMR(self): | |
if self.sex == 'female': | |
bmr = 864.6 + self.weight * 10.2036 | |
bmr -= self.height * 0.39336 | |
bmr -= self.age * 6.204 | |
else: | |
bmr = 877.8 + self.weight * 14.916 | |
bmr -= self.height * 0.726 | |
bmr -= self.age * 8.976 | |
# Capping | |
if self.sex == 'female' and bmr > 2996: | |
bmr = 5000 | |
elif self.sex == 'male' and bmr > 2322: | |
bmr = 5000 | |
return self.checkValueOverflow(bmr, 500, 10000) | |
# Get fat percentage | |
def getFatPercentage(self): | |
# Set a constant to remove from LBM | |
if self.sex == 'female' and self.age <= 49: | |
const = 9.25 | |
elif self.sex == 'female' and self.age > 49: | |
const = 7.25 | |
else: | |
const = 0.8 | |
# Calculate body fat percentage | |
LBM = self.getLBMCoefficient() | |
if self.sex == 'male' and self.weight < 61: | |
coefficient = 0.98 | |
elif self.sex == 'female' and self.weight > 60: | |
coefficient = 0.96 | |
if self.height > 160: | |
coefficient *= 1.03 | |
elif self.sex == 'female' and self.weight < 50: | |
coefficient = 1.02 | |
if self.height > 160: | |
coefficient *= 1.03 | |
else: | |
coefficient = 1.0 | |
fatPercentage = (1.0 - (((LBM - const) * coefficient) / self.weight)) * 100 | |
# Capping body fat percentage | |
if fatPercentage > 63: | |
fatPercentage = 75 | |
return self.checkValueOverflow(fatPercentage, 5, 75) | |
# Get water percentage | |
def getWaterPercentage(self): | |
waterPercentage = (100 - self.getFatPercentage()) * 0.7 | |
if (waterPercentage <= 50): | |
coefficient = 1.02 | |
else: | |
coefficient = 0.98 | |
# Capping water percentage | |
if waterPercentage * coefficient >= 65: | |
waterPercentage = 75 | |
return self.checkValueOverflow(waterPercentage * coefficient, 35, 75) | |
# Get bone mass | |
def getBoneMass(self): | |
if self.sex == 'female': | |
base = 0.245691014 | |
else: | |
base = 0.18016894 | |
boneMass = (base - (self.getLBMCoefficient() * 0.05158)) * -1 | |
if boneMass > 2.2: | |
boneMass += 0.1 | |
else: | |
boneMass -= 0.1 | |
# Capping boneMass | |
if self.sex == 'female' and boneMass > 5.1: | |
boneMass = 8 | |
elif self.sex == 'male' and boneMass > 5.2: | |
boneMass = 8 | |
return self.checkValueOverflow(boneMass, 0.5 , 8) | |
# Get muscle mass | |
def getMuscleMass(self): | |
muscleMass = self.weight - ((self.getFatPercentage() * 0.01) * self.weight) - self.getBoneMass() | |
# Capping muscle mass | |
if self.sex == 'female' and muscleMass >= 84: | |
muscleMass = 120 | |
elif self.sex == 'male' and muscleMass >= 93.5: | |
muscleMass = 120 | |
return self.checkValueOverflow(muscleMass, 10 ,120) | |
# Get Visceral Fat | |
def getVisceralFat(self): | |
if self.sex == 'female': | |
if self.weight > (13 - (self.height * 0.5)) * -1: | |
subsubcalc = ((self.height * 1.45) + (self.height * 0.1158) * self.height) - 120 | |
subcalc = self.weight * 500 / subsubcalc | |
vfal = (subcalc - 6) + (self.age * 0.07) | |
else: | |
subcalc = 0.691 + (self.height * -0.0024) + (self.height * -0.0024) | |
vfal = (((self.height * 0.027) - (subcalc * self.weight)) * -1) + (self.age * 0.07) - self.age | |
else: | |
if self.height < self.weight * 1.6: | |
subcalc = ((self.height * 0.4) - (self.height * (self.height * 0.0826))) * -1 | |
vfal = ((self.weight * 305) / (subcalc + 48)) - 2.9 + (self.age * 0.15) | |
else: | |
subcalc = 0.765 + self.height * -0.0015 | |
vfal = (((self.height * 0.143) - (self.weight * subcalc)) * -1) + (self.age * 0.15) - 5.0 | |
return self.checkValueOverflow(vfal, 1 ,50) | |
# Get BMI | |
def getBMI(self): | |
return self.checkValueOverflow(self.weight/((self.height/100)*(self.height/100)), 10, 90) | |
# Get ideal weight (just doing a reverse BMI, should be something better) | |
def getIdealWeight(self, orig=True): | |
# Uses mi fit algorithm (or holtek's one) | |
if orig and self.sex == 'female': | |
return (self.height - 70) * 0.6 | |
elif orig and self.sex == 'male': | |
return (self.height - 80) * 0.7 | |
else: | |
return self.checkValueOverflow((22*self.height)*self.height/10000, 5.5, 198) | |
# Get fat mass to ideal (guessing mi fit formula) | |
def getFatMassToIdeal(self): | |
mass = (self.weight * (self.getFatPercentage() / 100)) - (self.weight * (self.scales.getFatPercentageScale()[2] / 100)) | |
if mass < 0: | |
return {'type': 'to_gain', 'mass': mass*-1} | |
else: | |
return {'type': 'to_lose', 'mass': mass} | |
# Get protetin percentage (warn: guessed formula) | |
def getProteinPercentage(self, orig=True): | |
# Use original algorithm from mi fit (or legacy guess one) | |
if orig: | |
proteinPercentage = (self.getMuscleMass() / self.weight) * 100 | |
proteinPercentage -= self.getWaterPercentage | |
else: | |
proteinPercentage = 100 - (floor(self.getFatPercentage() * 100) / 100) | |
proteinPercentage -= floor(self.getWaterPercentage() * 100) / 100 | |
proteinPercentage -= floor((self.getBoneMass()/self.weight*100) * 100) / 100 | |
return self.checkValueOverflow(proteinPercentage, 5, 32) | |
# Get body type (out of nine possible) | |
def getBodyType(self): | |
if self.getFatPercentage() > self.scales.getFatPercentageScale()[2]: | |
factor = 0 | |
elif self.getFatPercentage() < self.scales.getFatPercentageScale()[1]: | |
factor = 2 | |
else: | |
factor = 1 | |
if self.getMuscleMass() > self.scales.getMuscleMassScale()[1]: | |
return 2 + (factor * 3) | |
elif self.getMuscleMass() < self.scales.getMuscleMassScale()[0]: | |
return (factor * 3) | |
else: | |
return 1 + (factor * 3) | |
# Get Metabolic Age | |
def getMetabolicAge(self): | |
if self.sex == 'female': | |
metabolicAge = (self.height * -1.1165) + (self.weight * 1.5784) + (self.age * 0.4615) + (self.impedance * 0.0415) + 83.2548 | |
else: | |
metabolicAge = (self.height * -0.7471) + (self.weight * 0.9161) + (self.age * 0.4184) + (self.impedance * 0.0517) + 54.2267 | |
return self.checkValueOverflow(metabolicAge, 15, 80) |