Source code for src.utils.get_volume

"""
Get the total workout volume of each date in the table.
In the case of multiple workouts on the same day,
the volume is the sum of the volumes of the workouts.
"""

from pprint import pformat  # type: ignore
import re
from loguru import logger  # type: ignore
from typing import Any
from src.utils.get_bodyweight import get_bw  # type: ignore
from src.utils.set_db_and_table import set_db_and_table  # type: ignore
from src.utils.powerbands import bands_mapping  # type: ignore


[docs] def get_weight( s: dict, bodyweight: str, Sidea_9012_Olympic_Hex_Bar: str ) -> int: """Get the weight of the exercise. :param s: Dictionary containing the exercise details :type s: dict :param bodyweight: Bodyweight of the person in kg :type bodyweight: str :param Sidea_9012_Olympic_Hex_Bar: Weight of the barbell :type Sidea_9012_Olympic_Hex_Bar: str :return: Weight of the exercise :rtype: float """ weight_expr = ( s["weight"][:-3] .replace("BODYWEIGHT", bodyweight) .replace("Sidea_9012_Olympic_Hex_Bar", Sidea_9012_Olympic_Hex_Bar) ) # Replace POWERBAND_COLOR with actual resistance value def replace_powerband(match): color = match.group(1) return str(bands_mapping.get(color, 0)) # Default to 0 if unknown weight_regex = re.sub(r"POWERBAND_(GREEN|PURPLE|BLACK|RED)", replace_powerband, weight_expr) # Safe evaluation using eval() with restricted scope try: # Only allow basic math operations; no external functions allowed allowed_names: dict[str, dict[Any, Any]] = { "__builtins__": {}, } result = eval(weight_regex, allowed_names, {}) return result except Exception as e: logger.error(f"Error evaluating weight expression: {weight_regex} | {e}") return 0
[docs] def get_total_volume(table) -> list[tuple[str, int]]: """Get the total volume of all workouts, summing volumes for the same date. :param table: TinyDB table :type table: tinydb.table.Table :return: List of tuples containing the date and total volume of each workout :rtype: list[tuple[str, int]] """ bodyweight = str(get_bw()) Sidea_9012_Olympic_Hex_Bar = "31" date_and_volume: dict[Any, Any] = {} for item in table: total_volume = 0 for exercise in item["exercises"].keys(): number_of_sets = len(item["exercises"][exercise]) volume_partial = [] for s in item["exercises"][exercise]: weight = 1 if s["weight"][:-3] != "0": weight = get_weight(s, bodyweight, Sidea_9012_Olympic_Hex_Bar) volume_partial.append(s["reps"] * weight) total_volume += number_of_sets * max(volume_partial) # Sum volumes for the same date date = item["date"] if date in date_and_volume: date_and_volume[date] += total_volume else: date_and_volume[date] = total_volume # Convert the dictionary to a list of tuples return list(date_and_volume.items())
[docs] def main() -> None: """ Get the total volume of each workout in the table. """ datatype = "real" _, table, _ = set_db_and_table(datatype) date_and_volume = get_total_volume(table) logger.debug(pformat(date_and_volume))
if __name__ == "__main__": main()