AvocadoSmoothie.Barista
1.0.5
dotnet add package AvocadoSmoothie.Barista --version 1.0.5
NuGet\Install-Package AvocadoSmoothie.Barista -Version 1.0.5
<PackageReference Include="AvocadoSmoothie.Barista" Version="1.0.5" />
<PackageVersion Include="AvocadoSmoothie.Barista" Version="1.0.5" />
<PackageReference Include="AvocadoSmoothie.Barista" />
paket add AvocadoSmoothie.Barista --version 1.0.5
#r "nuget: AvocadoSmoothie.Barista, 1.0.5"
#:package AvocadoSmoothie.Barista@1.0.5
#addin nuget:?package=AvocadoSmoothie.Barista&version=1.0.5
#tool nuget:?package=AvocadoSmoothie.Barista&version=1.0.5
AvocadoSmoothie.Barista
Assembly : AvocadoSmoothie.Barista
Namespace : AvocadoSmoothie.Barista
Overview
- Median-based smoothing for numeric sequences (MiddleMedian and AllMedian).
- CSV export with automatic partitioning to respect Excel's row limits.
- Excel export (Interop on .NET Framework, late-binding COM on .NET Standard) with a chart and document properties.
This Readme documents and exemplifies the exact behavior and public API present in :
- SignatureMedian.vb
- CsvOrderTicket.vb
- CsvCustomOrder.vb
- CsvBrewService.vb
- ExcelOrderTicket.vb
- ExcelCustomOrder.vb
- ExcelBrewService.vb
Key concepts
- Radius vs Width :
- Radius (R) is the user-specified smoothing parameter.
- Window width (W) used by the median is W = (2 × R) + 1 and must be odd.
- SignatureMedian.ComputeMedians has a parameter named kernelRadius that actually receives W (the odd window width), not R.
- MiddleMedian vs AllMedian :
- MiddleMedian preserves the first and last BorderCount values unchanged.
- AllMedian applies smoothing across the full series.
Public API (exact signatures)
Class SignatureMedian
- Public Shared Function ComputeMedians(input As List(Of Double), useMiddle As Boolean, kernelRadius As Integer, borderCount As Integer, Optional progress As IProgress(Of Integer) = Nothing) As List(Of Double)
- Public Shared Sub Quicksort(list() As Double, min As Integer, max As Integer)
Class CsvOrderTicket
- Public Property InitialData As IList(Of Double)
- Public Property DatasetTitle As String
- Public Property KernelRadius As Integer
- Public Property BorderCount As Integer
- Public Property BasePath As String
- Public Property CancellationToken As Threading.CancellationToken
- Public Property Progress As IProgress(Of Integer)
- Public Sub Validate()
Class CsvBrewService (NotInheritable)
- Public Shared Function ExportCsvAsync(request As CsvOrderTicket) As Threading.Tasks.Task(Of List(Of String))
- Public Shared Async Function ExportCsvAsync(initialData As IList(Of Double), datasetTitle As String, kernelRadius As Integer, borderCount As Integer, basePath As String, Optional progress As IProgress(Of Integer) = Nothing, Optional cancelToken As Threading.CancellationToken = Nothing) As Threading.Tasks.Task(Of List(Of String))
Class ExcelOrderTicket
- Public Property InitialData As IList(Of Double)
- Public Property DatasetTitle As String
- Public Property KernelRadius As Integer
- Public Property BorderCount As Integer
- Public Property Progress As IProgress(Of Integer)
- Public Property CancellationToken As Threading.CancellationToken
- Public Sub ValidateBasic()
Class ExcelBrewService (NotInheritable)
- Public Shared Function ExcelCustomOrder(request As ExcelOrderTicket) As Threading.Tasks.Task
- Public Shared Async Function ExportExcelAsync(initialData As IList(Of Double), datasetTitle As String, kernelRadius As Integer, borderCount As Integer, progress As IProgress(Of Integer), Optional cancelToken As Threading.CancellationToken = Nothing) As Threading.Tasks.Task
Behavioral details
- SignatureMedian
- ComputeMedians
- input : List(Of Double). If empty, reports 0 to progress (when present) and returns an empty list.
- useMiddle :
- True : MiddleMedian. The first and last borderCount values are copied from input. The inner region is smoothed.
- False : AllMedian. The entire series is smoothed (borderCount ignored).
- kernelRadius : Odd window width W (despite the name). Offsets are computed as :
- offsetLow = (W - 1) \ 2
- offsetHigh = (W - 1) - offsetLow
- borderCount : Number of unchanged elements on both ends for MiddleMedian only.
- progress : Receives integer counts of processed elements :
- Reports 0 at start, periodic updates at roughly N / 200 intervals, and N at the end.
- Implementation :
- Parallel.For with a ThreadLocal window buffer Double().
- Per-position window bounds are clamped to [0, N - 1].
- Median is computed by sorting a copied slice and taking the middle (average of two middles for even length).
- Quicksort
- In-place ascending sort for Double().
- No-op if min >= max.
- Random pivot selection in [min, max].
- CSV export
- CsvOrderTicket.Validate
- Ensures :
- InitialData exists and non-empty.
- DatasetTitle non-empty.
- KernelRadius > 0.
- BorderCount ≥ 0.
- BasePath non-empty and its directory exists; otherwise throws DirectoryNotFoundException.
- Ensures :
- CsvBrewService.ExportCsvAsync overloads
- Overload with CsvOrderTicket :
- Throws ArgumentNullException if request Is Nothing.
- Calls request.Validate() and delegates.
- Core overload (initialData, datasetTitle, kernelRadius, borderCount, basePath, progress, cancelToken) :
- Validations :
- initialData non-empty; datasetTitle non-empty; basePath non-empty; kernelRadius > 0.
- Smoothing :
- kernelWidth = 2 * kernelRadius + 1 (odd).
- MiddleMedian computed first, then AllMedian, each via SignatureMedian.ComputeMedians with kernelRadius :=kernelWidth.
- Both computations run on Task.Run and honor cancelToken before invoking ComputeMedians.
- File partitioning :
- Excel row limit is 1,048,576 (EXCEL_MAX_ROW).
- HEADER_LINES = 11; The service computes maxDataRows = EXCEL_MAX_ROW - HEADER_LINES - 1.
- Splits data into parts by maxDataRows.
- File naming :
- If a single part : basePath is used.
- If multiple parts : {BaseName}_Part{index}{ext}. Default extension is ".csv" when missing.
- File content (UTF-8) :
- Line 1 : DatasetTitle
- Line 2 : "Part {p} of {P}" (even for single part : "Part 1 of 1")
- Line 3 : empty
- "Smoothing Parameters"
- $"Kernel Radius : {kernelRadius}" (R)
- $"Kernel Width : {kernelWidth}" (W = 2 * R + 1)
- $"Border Count : {borderCount}"
- empty
- $"Generated : {DateTime.Now.ToString("G", CurrentCulture)}"
- empty
- "Initial Data,MiddleMedian,AllMedian"
12+. Data rows :
- Values formatted with "G17" and InvariantCulture for each of Initial, Middle, All.
- Progress :
- During both median computations : progress receives forwarded counts from ComputeMedians (0 … N).
- During file writing : progress receives percentage computed as CInt((i + 1) / CDbl(N) * 100) for each written row (monotonic across parts).
- Cancellation :
- cancelToken.ThrowIfCancellationRequested() is called before each compute phase and at the beginning of each part iteration.
- Validations :
- Overload with CsvOrderTicket :
- Excel export
- ExcelOrderTicket.ValidateBasic
- Ensures :
- InitialData non-empty, DatasetTitle non-empty, KernelRadius > 0, BorderCount ≥ 0.
- Ensures :
- ExcelBrewService.ExportExcelAsync
- Validations :
- initialData non-empty; datasetTitle non-empty; kernelRadius > 0; borderCount ≥ 0.
- Smoothing :
- n = initialData.Count
- kernelWidth = 2*kernelRadius + 1
- ValidateSmoothingParameters(n, kernelWidth, kernelRadius, borderCount, useMiddle :=True)
- Enforces : windowSize ≤ dataCount; borderCount ≤ dataCount; and 2*borderCount < windowSize (strict).
- MiddleMedian computed first, with kernelRadius:=kernelWidth.
- ValidateSmoothingParameters(n, kernelRadius, kernelRadius, borderCount, useMiddle :=False)
- Implementation note : the second validation passes windowSize :=kernelRadius (R) rather than kernelWidth (W).
- AllMedian computed second, with kernelRadius :=kernelWidth.
- Progress :
- MiddleMedian : progress receives Math.Min(29, Math.Max(0, v)).
- AllMedian : maps ComputeMedians count to 30 … 59 using v / n.
- Excel writing : reports 60, progresses through writing & charting, then 100, delays 200 ms, and reports 0.
- Output workbook (platform dependent) :
- NET48 : strongly typed Microsoft.Office.Interop.Excel.
- Non-NET48 (net standard 2.0 path) : late-binding COM; requires Windows + Microsoft Excel installed; throws PlatformNotSupportedException on non-Windows and InvalidOperationException when Excel isn't registered. COM exceptions include a stage hint.
- Sheet layout :
- Worksheet name = datasetTitle.
- Headers :
- Cell(1,1) : datasetTitle
- Cell(3,1) : "Smoothing Parameters"
- Cell(4,1) : $"Kernel Radius : {kernelRadius}"
- Cell(5,1) : $"Kernel Width : {kernelWidth}"
- Cell(6,1) : $"Border Count : {borderCount}"
- Data placement :
- DATA_START_ROW = 4
- Columns :
- Initial Data from column 3 (with "Initial Data" label at row 3 in that column).
- MiddleMedian begins two columns to the right of the last Initial column, labeled "MiddleMedian".
- AllMedian begins two columns to the right of the last Middle column, labeled "AllMedian".
- If a series exceeds 1,048,576 - DATA_START_ROW + 1 rows, the series continues in the next column (vertical blocks; one column per block).
- Chart :
- Line chart placed near the data, after the last used column.
- Title : datasetTitle.
- Value axis title : "Value".
- Category axis title : "Sequence Number".
- Series names :
- "Initial Data"
- "Middle Median"
- "All Median"
- Built-in document properties :
- Title, Category, Subject, Author, Last Author, Keywords, Comments are populated. Comments vary with row count.
- Application state :
- Workbook Saved = False; Excel.Visible = True; DisplayAlerts = True.
- Validations :
- ExcelBrewService.ExcelCustomOrder
- Validates with request.ValidateBasic(), then delegates to ExportExcelAsync with matching parameters.
Exceptions
CsvOrderTicket.Validate
- ArgumentException : InitialData empty, DatasetTitle missing, BasePath missing.
- ArgumentOutOfRangeException : KernelRadius ≤ 0 or BorderCount < 0.
- DirectoryNotFoundException : The directory part of BasePath does not exist.
CsvBrewService.ExportCsvAsync (core overload)
- ArgumentException : initialData empty, datasetTitle missing, basePath missing.
- ArgumentOutOfRangeException : kernelRadius ≤ 0.
- OperationCanceledException : when cancelToken is requested.
- File I/O errors (e.g., UnauthorizedAccessException, IOException, PathTooLongException) can bubble from the FileStream/StreamWriter operations.
ExcelOrderTicket.ValidateBasic
- ArgumentException : InitialData empty, DatasetTitle missing.
- ArgumentOutOfRangeException : KernelRadius ≤ 0 or BorderCount < 0.
ExcelBrewService.ExportExcelAsync
- ArgumentException : initialData empty, datasetTitle missing.
- ArgumentOutOfRangeException : kernelRadius ≤ 0 or borderCount < 0.
- InvalidOperationException : smoothing parameter violations (e.g., windowSize > dataCount; for MiddleMedian also 2*borderCount ≥ windowSize).
- OperationCanceledException : when cancelToken is requested.
- NET48 :
- COM interop failures may surface as COMException during Excel automation.
- Non-NET48 (late-binding) :
- PlatformNotSupportedException on non-Windows.
- InvalidOperationException if Excel is not installed / registered.
- COMException with a stage hint on late-binding failures.
Usage examples (VB.NET)
- CSV export via ticket
Imports AvocadoSmoothie.Barista
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Module DemoCsv
Async Function RunAsync() As Task
' Create a list of Double values from 1 to 10000
Dim data As IList(Of Double) =
Enumerable.Range(1, 10000) _
.Select(Function(i) CDbl(i)) _
.ToList()
' Progress reporter that writes progress percentage to the console
Dim progress = New Progress(Of Integer)(
Sub(v) Console.WriteLine($"Progress : {v}")
)
' Cancellation token source for stopping the operation if needed
Dim cts = New CancellationTokenSource()
' Create a CSV export ticket with configuration
Dim ticket = New CsvOrderTicket With {
.InitialData = data,
.DatasetTitle = "My Dataset",
.KernelRadius = 5, ' R (window width W = 2*R + 1 = 11)
.BorderCount = 2,
.BasePath = "C:\Temp\MyDataset.csv",
.Progress = progress,
.CancellationToken = cts.Token
}
' Export CSV files asynchronously
Dim files = Await CsvBrewService.ExportCsvAsync(ticket)
' Output the created file paths
For Each f In files
Console.WriteLine("Created : " & f)
Next
End Function
End Module
- CSV export via core overload
Imports AvocadoSmoothie.Barista
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Module DemoCsvCore
Async Function RunAsync() As Task
' Generate a list of Double values representing a sine wave
' from 1 to 250,000 with a step of 1, scaled by 1/1000.0
Dim data As IList(Of Double) =
Enumerable.Range(1, 250000) _
.Select(Function(i) Math.Sin(i / 1000.0)) _
.ToList()
' Progress reporter that writes progress percentage to the console
Dim progress = New Progress(Of Integer)(
Sub(v) Console.WriteLine($"Progress : {v}")
)
' Cancellation token source for stopping the operation if needed
Dim cts = New CancellationTokenSource()
' Export CSV files asynchronously with the given parameters
Dim files = Await CsvBrewService.ExportCsvAsync(
initialData:=data,
datasetTitle:="Sine Series",
kernelRadius:=7, ' R (window width W = 15)
borderCount:=3,
basePath:="C:\Temp\SineSeries.csv",
progress:=progress,
cancelToken:=cts.Token
)
' Output the created file paths
For Each f In files
Console.WriteLine("Created : " & f)
Next
End Function
End Module
- Excel export via ticket
Imports AvocadoSmoothie.Barista
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Module DemoExcel
Async Function RunAsync() As Task
' Generate a list of Double values representing a cosine wave
' from 1 to 10,000 with a step of 1, scaled by 1/123.0
Dim data As IList(Of Double) =
Enumerable.Range(1, 10000) _
.Select(Function(i) Math.Cos(i / 123.0)) _
.ToList()
' Progress reporter that writes progress percentage to the console
Dim progress = New Progress(Of Integer)(
Sub(v) Console.WriteLine($"Progress : {v}")
)
' Cancellation token source for stopping the operation if needed
Dim cts = New CancellationTokenSource()
' Create an Excel export ticket with configuration
Dim ticket = New ExcelOrderTicket With {
.InitialData = data,
.DatasetTitle = "Cosine Series",
.KernelRadius = 9, ' R (window width W = 19)
.BorderCount = 4,
.Progress = progress,
.CancellationToken = cts.Token
}
' Generate the Excel workbook (visible, unsaved)
Await ExcelBrewService.ExcelCustomOrder(ticket)
End Function
End Module
- Excel export via core overload
Imports AvocadoSmoothie.Barista
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Module DemoExcelCore
Async Function RunAsync() As Task
' Generate a list of Double values representing a logarithmic series
' from 1 to 50,000 with a step of 1
Dim data As IList(Of Double) =
Enumerable.Range(1, 50000) _
.Select(Function(i) Math.Log(i)) _
.ToList()
' Progress reporter that writes progress percentage to the console
Dim progress = New Progress(Of Integer)(
Sub(v) Console.WriteLine($"Progress : {v}")
)
' Cancellation token source for stopping the operation if needed
Dim cts = New CancellationTokenSource()
' Export Excel file asynchronously with the given parameters
Await ExcelBrewService.ExportExcelAsync(
initialData:=data,
datasetTitle:="Log Series",
kernelRadius:=6, ' R (window width W = 13)
borderCount:=2,
progress:=progress,
cancelToken:=cts.Token
)
End Function
End Module
Notes and limitations
- SignatureMedian.ComputeMedians does not take a CancellationToken; cancellations are managed by callers before invoking it.
- For Excel export on non-NET48 targets :
- Windows is required.
- Microsoft Excel must be installed and registered (ProgID "Excel.Application").
- Excel export applies built-in document properties and inserts a line chart with three series.
- In ExcelBrewService.ExportExcelAsync, the second ValidateSmoothingParameters call uses windowSize:=kernelRadius (R) for the AllMedian pass; this is the exact implementation.
License and third-party dependencies
- Uses Microsoft Office Interop (NET48) or late-binding COM (Windows-only) to automate Excel. Ensure Excel is installed for Excel export scenarios on non-NET48 targets.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last Updated |
---|---|---|
1.0.5 | 103 | 9/6/2025 |
Introduced a comprehensive package description to provide clearer information about the package’s purpose and usage.