Public/Get-WeeklyBodyMetrics.ps1
|
<# .SYNOPSIS Gets weekly body metrics averages from Tanita body composition CSV data. .DESCRIPTION Reads a Tanita CSV file, extracts relevant fields, calculates fat mass, and groups entries by ISO calendar week. Outputs weekly averages for weight, body fat, fat mass, muscle mass, and segment muscle mass (left leg, right leg, trunk). .NOTES Expected CSV columns: - Date - Weight (kg) - Body Fat (%) - Muscle Mass (kg) - Muscle mass - left leg - Muscle mass - right leg - Muscle mass - trunk .EXAMPLE PS> Get-WeeklyBodyMetrics Opens a file picker for CSV files and prints weekly averages as a table. .EXAMPLE PS> Get-WeeklyBodyMetrics -CsvFile .\bodydata.csv Uses the specified CSV file and prints weekly averages as a table. .PARAMETER CsvFile Path to the input CSV file. Only files with the .csv extension are accepted. You can also use the aliases `BodyData`, `Path`, or the legacy alias `CsvPath`. .PARAMETER Enablelogging Optional switch to enable additional logging (project-dependent). #> Function Get-WeeklyBodyMetrics { [CmdletBinding()] param( [Parameter(Position = 0)] [Alias('BodyData', 'Path', 'CsvPath')] [ValidatePattern('(?i)\.csv$')] [string]$CsvFile, [switch]$Enablelogging ) $CurrentFunction = Get-FunctionName Write-Log -Message "### Start Function $CurrentFunction ###" $StartRunTime = (Get-Date).ToString($Script:DateFormatLog) #################### main code | out- host ##################### Invoke-Output -Type Header -Message "Calculating weekly averages for body composition data..." if (-not $CsvFile) { Add-Type -AssemblyName System.Windows.Forms $dialog = New-Object System.Windows.Forms.OpenFileDialog $dialog.Title = "Select CSV input file" $dialog.Filter = "CSV files (*.csv)|*.csv" $dialog.Multiselect = $false $dialog.CheckFileExists = $true $dialog.InitialDirectory = (Get-Location).Path $dialogResult = $dialog.ShowDialog() if ($dialogResult -ne [System.Windows.Forms.DialogResult]::OK -or [string]::IsNullOrWhiteSpace($dialog.FileName)) { Write-Host " [!] Canceled by user. No csv file was selected." -ForegroundColor Yellow return } $CsvFile = $dialog.FileName } if (-not (Test-Path -LiteralPath $CsvFile -PathType Leaf)) { throw "CSV file not found: $CsvFile" } if ([System.IO.Path]::GetExtension($CsvFile) -notmatch '^(?i)\.csv$') { throw "Only .csv files are allowed: $CsvFile" } $csvPath = (Resolve-Path -LiteralPath $CsvFile).Path Invoke-Output -Type Bullet -Message "Input CSV file: " -Textmaker "$csvPath" # === Read CSV and extract fields === $data = Import-Csv -Path $csvPath | ForEach-Object { $entry = $_ $date = [datetime]$entry."Date" $weight = [double]$entry."Weight (kg)" $fatPercent = [double]$entry."Body Fat (%)" $muscleMass = [double]$entry."Muscle Mass (kg)" $leftLeg = [double]$entry."Muscle mass - left leg" $rightLeg = [double]$entry."Muscle mass - right leg" $trunk = [double]$entry."Muscle mass - trunk" $muscleMass = [double]$entry."Muscle Mass (kg)" $fatMass = [math]::Round($weight * ($fatPercent / 100.0), 2) [PSCustomObject]@{ Date = $date Weight = $weight FatPercent = $fatPercent MuscleMass = $muscleMass LeftLeg = $leftLeg RightLeg = $rightLeg Trunk = $trunk FatMass = $fatMass Week = [System.Globalization.CultureInfo]::InvariantCulture.Calendar. GetWeekOfYear($date, [System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [System.DayOfWeek]::Monday) } } Invoke-Output -Type Bullet -Message "Number of entries:" -Textmaker $($data.Count) # === Group by week === $dataGrouped = $data | Group-Object Week # === Weekly analysis === $result = $dataGrouped | ForEach-Object { $group = $_.Group | Sort-Object Date $week = $_.Name [PSCustomObject]@{ KW = "KW$week" Count = $group.Count From = $group[0].Date.ToString("yyyy-MM-dd") To = $group[-1].Date.ToString("yyyy-MM-dd") Ø_Weight_kg = [math]::Round(($group | Measure-Object -Property Weight -Average).Average, 2) Ø_Fat_percent = [math]::Round(($group | Measure-Object -Property FatPercent -Average).Average, 2) Ø_Fat_mass_kg = [math]::Round(($group | Measure-Object -Property FatMass -Average).Average, 2) Ø_MuscleMass_kg = [math]::Round(($group | Measure-Object -Property MuscleMass -Average).Average, 2) Ø_LeftLeg_kg = [math]::Round(($group | Measure-Object -Property LeftLeg -Average).Average, 2) Ø_RightLeg_kg = [math]::Round(($group | Measure-Object -Property RightLeg -Average).Average, 2) Ø_Trunk_kg = [math]::Round(($group | Measure-Object -Property Trunk -Average).Average, 2) } } # === Output === $result | Format-Table -AutoSize Invoke-Output -Type Success -Message "Get-WeeklyBodyMetrics completed successfully." ######################## main code ############################ $runtime = Get-RunTime -StartRunTime $StartRunTime Write-Log -Message " Run Time: $runtime [h] ###" Write-Log -Message "### End Function $CurrentFunction ###" } |