@@ -6,7 +6,10 @@ import 'dart:math';
66
77const analysisWindowDays = 30 ;
88const totalTrendWindowDays = 330 ;
9- const minThirtyDaysDownloadThreshold = 30000 ;
9+
10+ /// The total download count over 30 days at which a package is considered
11+ /// moderately popular.
12+ const popularityMidpoint = 30000.0 ;
1013
1114/// Calculates the exponential growth rate of a package's downloads.
1215///
@@ -74,13 +77,17 @@ double calculateLinearRegressionSlope(List<num> yValues) {
7477 return (n * sumXY - sumX * sumY) / denominator;
7578}
7679
77- /// Computes a trend score for a package, factoring in both its recent
78- /// relative growth rate and its overall download volume.
80+ /// Computes a trend score for a package, factoring in both its recent relative
81+ /// growth rate and its overall download volume.
82+ ///
83+ /// This function sanitizes the download history by trimming any trailing zeros
84+ /// in [totalDownloads] , which represent the time before the package was
85+ /// published. This ensures the trend is only calculated over the package's
86+ /// active lifetime.
7987///
80- /// This score is designed to balance how quickly a package is growing
81- /// ([computeRelativeGrowthRate] ) against its existing popularity. Popularity is
82- /// assessed by comparing the sum of its downloads over the available history
83- /// (up to [analysisWindowDays] ) against a [minThirtyDaysDownloadThreshold] .
88+ /// The final score is designed to balance how quickly a package is growing
89+ /// against its existing popularity. Popularity is assessed using a sigmoid
90+ /// function where the midpoint is defined by [popularityMidpoint] .
8491double computeTrendScore (List <int > totalDownloads) {
8592 final lastNonZeroIndex = totalDownloads.lastIndexWhere ((e) => e != 0 );
8693
@@ -122,12 +129,13 @@ List<double> safeLogTransform(List<int> numbers) {
122129/// download counts get a score near 1.
123130///
124131/// The function takes the total number of downloads in the last 30 days
125- /// ([total30Downloads] ) and the parameter [midpoint] at which the score is
126- /// exactly 0.5 and [steepness] controlling how quickly the score transitions
127- /// from 0 to 1. Higher values create a steeper, more sudden transition.
132+ /// ([total30Downloads] ) and the parameter [midpoint] (defaults to
133+ /// [popularityMidpoint] ) at which the score is exactly 0.5 and
134+ /// [steepness] controlling how quickly the score transitions from 0 to 1.
135+ /// Higher values create a steeper, more sudden transition.
128136double calculateSigmoidScaleScore ({
129137 required int total30Downloads,
130- double midpoint = 30000.0 ,
138+ double midpoint = popularityMidpoint ,
131139 double steepness = 0.00015 ,
132140}) {
133141 final double exponent = - steepness * (total30Downloads - midpoint);
0 commit comments