Add methods to stats calculators to accept values one at a time

This can be more efficient for large quantities of values, since
it avoids the need to create a list of all values in advance
This commit is contained in:
Nyall Dawson 2016-05-16 08:59:47 +10:00
parent 2bbd5ca509
commit 4dea723cae
12 changed files with 416 additions and 62 deletions

View File

@ -53,12 +53,33 @@ class QgsDateTimeStatisticalSummary
*/
void reset();
/** Calculates summary statistics for a list of variants. Any non-string variants will be
/** Calculates summary statistics for a list of variants. Any non-datetime variants will be
* ignored.
* @param values list of variants
* @see addValue()
*/
void calculate( const QVariantList& values );
/** Adds a single datetime to the statistics calculation. Calling this method
* allows datetimes to be added to the calculation one at a time. For large
* quantities of dates this may be more efficient then first adding all the
* variants to a list and calling calculate().
* @param value datetime to add. Any non-datetime variants will be ignored.
* @note call reset() before adding the first datetime using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculate()
* @see finalize()
*/
void addValue( const QVariant& value );
/** Must be called after adding all datetimes with addValue() and before retrieving
* any calculated datetime statistics.
* @see addValue()
*/
void finalize();
/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic

View File

@ -69,6 +69,25 @@ class QgsStatisticalSummary
*/
void calculate( const QList<double>& values );
/** Adds a single value to the statistics calculation. Calling this method
* allows values to be added to the calculation one at a time. For large
* quantities of values this may be more efficient then first adding all the
* values to a list and calling calculate().
* @param value value to add
* @note call reset() before adding the first value using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculate()
* @see finalize()
*/
void addValue( double value );
/** Must be called after adding all values with addValues() and before retrieving
* any calculated statistics.
* @see addValue()
*/
void finalize();
/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic

View File

@ -57,19 +57,56 @@ class QgsStringStatisticalSummary
*/
void reset();
/** Calculates summary statistics for a list of strings.
/** Calculates summary statistics for an entire list of strings at once.
* @param values list of strings
* @see calculateFromVariants()
* @see addString()
*/
void calculate( const QStringList& values );
/** Calculates summary statistics for a list of variants. Any non-string variants will be
* ignored.
/** Calculates summary statistics for an entire list of variants at once. Any
* non-string variants will be ignored.
* @param values list of variants
* @see calculate()
* @see addValue()
*/
void calculateFromVariants( const QVariantList& values );
/** Adds a single string to the statistics calculation. Calling this method
* allows strings to be added to the calculation one at a time. For large
* quantities of strings this may be more efficient then first adding all the
* strings to a list and calling calculate().
* @param string string to add
* @note call reset() before adding the first string using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final string and before
* retrieving calculated statistics.
* @see calculate()
* @see addValue()
* @see finalize()
*/
void addString( const QString& string );
/** Adds a single variant to the statistics calculation. Calling this method
* allows variants to be added to the calculation one at a time. For large
* quantities of variants this may be more efficient then first adding all the
* variants to a list and calling calculateFromVariants().
* @param value variant to add
* @note call reset() before adding the first string using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculateFromVariants()
* @see finalize()
*/
void addValue( const QVariant& value );
/** Must be called after adding all strings with addString() and before retrieving
* any calculated string statistics.
* @see addString()
*/
void finalize();
/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic

View File

@ -49,18 +49,30 @@ void QgsDateTimeStatisticalSummary::calculate( const QVariantList& values )
Q_FOREACH ( const QVariant& variant, values )
{
if ( variant.type() == QVariant::DateTime )
{
testDateTime( variant.toDateTime() );
}
else if ( variant.type() == QVariant::Date )
{
QDate date = variant.toDate();
testDateTime( date.isValid() ? QDateTime( date, QTime( 0, 0, 0 ) )
: QDateTime() );
}
// QTime?
addValue( variant );
}
finalize();
}
void QgsDateTimeStatisticalSummary::addValue( const QVariant& value )
{
if ( value.type() == QVariant::DateTime )
{
testDateTime( value.toDateTime() );
}
else if ( value.type() == QVariant::Date )
{
QDate date = value.toDate();
testDateTime( date.isValid() ? QDateTime( date, QTime( 0, 0, 0 ) )
: QDateTime() );
}
// QTime?
}
void QgsDateTimeStatisticalSummary::finalize()
{
//nothing to do for now - this method has been added for forward compatibility
//if statistics are implemented which require a post-calculation step
}
void QgsDateTimeStatisticalSummary::testDateTime( const QDateTime& dateTime )

View File

@ -79,12 +79,33 @@ class CORE_EXPORT QgsDateTimeStatisticalSummary
*/
void reset();
/** Calculates summary statistics for a list of variants. Any non-string variants will be
/** Calculates summary statistics for a list of variants. Any non-datetime variants will be
* ignored.
* @param values list of variants
* @see addValue()
*/
void calculate( const QVariantList& values );
/** Adds a single datetime to the statistics calculation. Calling this method
* allows datetimes to be added to the calculation one at a time. For large
* quantities of dates this may be more efficient then first adding all the
* variants to a list and calling calculate().
* @param value datetime to add. Any non-datetime variants will be ignored.
* @note call reset() before adding the first datetime using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculate()
* @see finalize()
*/
void addValue( const QVariant& value );
/** Must be called after adding all datetimes with addValue() and before retrieving
* any calculated datetime statistics.
* @see addValue()
*/
void finalize();
/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic

View File

@ -51,6 +51,7 @@ void QgsStatisticalSummary::reset()
mFirstQuartile = 0;
mThirdQuartile = 0;
mValueCount.clear();
mValues.clear();
}
/***************************************************************************
@ -65,15 +66,30 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
Q_FOREACH ( double value, values )
{
mCount++;
mSum += value;
mMin = qMin( mMin, value );
mMax = qMax( mMax, value );
if ( mStatistics & QgsStatisticalSummary::Majority || mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Variety )
mValueCount.insert( value, mValueCount.value( value, 0 ) + 1 );
addValue( value );
}
finalize();
}
void QgsStatisticalSummary::addValue( double value )
{
mCount++;
mSum += value;
mMin = qMin( mMin, value );
mMax = qMax( mMax, value );
if ( mStatistics & QgsStatisticalSummary::Majority || mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Variety )
mValueCount.insert( value, mValueCount.value( value, 0 ) + 1 );
if ( mStatistics & QgsStatisticalSummary::StDev || mStatistics & QgsStatisticalSummary::StDevSample ||
mStatistics & QgsStatisticalSummary::Median || mStatistics & QgsStatisticalSummary::FirstQuartile ||
mStatistics & QgsStatisticalSummary::ThirdQuartile || mStatistics & QgsStatisticalSummary::InterQuartileRange )
mValues << value;
}
void QgsStatisticalSummary::finalize()
{
if ( mCount == 0 )
return;
@ -82,31 +98,29 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
if ( mStatistics & QgsStatisticalSummary::StDev || mStatistics & QgsStatisticalSummary::StDevSample )
{
double sumSquared = 0;
Q_FOREACH ( double value, values )
Q_FOREACH ( double value, mValues )
{
double diff = value - mMean;
sumSquared += diff * diff;
}
mStdev = qPow( sumSquared / values.count(), 0.5 );
mSampleStdev = qPow( sumSquared / ( values.count() - 1 ), 0.5 );
mStdev = qPow( sumSquared / mValues.count(), 0.5 );
mSampleStdev = qPow( sumSquared / ( mValues.count() - 1 ), 0.5 );
}
QList<double> sorted;
if ( mStatistics & QgsStatisticalSummary::Median
|| mStatistics & QgsStatisticalSummary::FirstQuartile
|| mStatistics & QgsStatisticalSummary::ThirdQuartile
|| mStatistics & QgsStatisticalSummary::InterQuartileRange )
{
sorted = values;
qSort( sorted.begin(), sorted.end() );
qSort( mValues.begin(), mValues.end() );
bool even = ( mCount % 2 ) < 1;
if ( even )
{
mMedian = ( sorted[mCount / 2 - 1] + sorted[mCount / 2] ) / 2.0;
mMedian = ( mValues[mCount / 2 - 1] + mValues[mCount / 2] ) / 2.0;
}
else //odd
{
mMedian = sorted[( mCount + 1 ) / 2 - 1];
mMedian = mValues[( mCount + 1 ) / 2 - 1];
}
}
@ -119,11 +133,11 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
bool even = ( halfCount % 2 ) < 1;
if ( even )
{
mFirstQuartile = ( sorted[halfCount / 2 - 1] + sorted[halfCount / 2] ) / 2.0;
mFirstQuartile = ( mValues[halfCount / 2 - 1] + mValues[halfCount / 2] ) / 2.0;
}
else //odd
{
mFirstQuartile = sorted[( halfCount + 1 ) / 2 - 1];
mFirstQuartile = mValues[( halfCount + 1 ) / 2 - 1];
}
}
else
@ -132,11 +146,11 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
bool even = ( halfCount % 2 ) < 1;
if ( even )
{
mFirstQuartile = ( sorted[halfCount / 2 - 1] + sorted[halfCount / 2] ) / 2.0;
mFirstQuartile = ( mValues[halfCount / 2 - 1] + mValues[halfCount / 2] ) / 2.0;
}
else //odd
{
mFirstQuartile = sorted[( halfCount + 1 ) / 2 - 1];
mFirstQuartile = mValues[( halfCount + 1 ) / 2 - 1];
}
}
}
@ -150,11 +164,11 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
bool even = ( halfCount % 2 ) < 1;
if ( even )
{
mThirdQuartile = ( sorted[ halfCount + halfCount / 2 - 1] + sorted[ halfCount + halfCount / 2] ) / 2.0;
mThirdQuartile = ( mValues[ halfCount + halfCount / 2 - 1] + mValues[ halfCount + halfCount / 2] ) / 2.0;
}
else //odd
{
mThirdQuartile = sorted[( halfCount + 1 ) / 2 - 1 + halfCount ];
mThirdQuartile = mValues[( halfCount + 1 ) / 2 - 1 + halfCount ];
}
}
else
@ -163,11 +177,11 @@ void QgsStatisticalSummary::calculate( const QList<double> &values )
bool even = ( halfCount % 2 ) < 1;
if ( even )
{
mThirdQuartile = ( sorted[ halfCount + halfCount / 2 - 2 ] + sorted[ halfCount + halfCount / 2 - 1 ] ) / 2.0;
mThirdQuartile = ( mValues[ halfCount + halfCount / 2 - 2 ] + mValues[ halfCount + halfCount / 2 - 1 ] ) / 2.0;
}
else //odd
{
mThirdQuartile = sorted[( halfCount + 1 ) / 2 - 2 + halfCount ];
mThirdQuartile = mValues[( halfCount + 1 ) / 2 - 2 + halfCount ];
}
}
}

View File

@ -91,6 +91,26 @@ class CORE_EXPORT QgsStatisticalSummary
*/
void calculate( const QList<double>& values );
/** Adds a single value to the statistics calculation. Calling this method
* allows values to be added to the calculation one at a time. For large
* quantities of values this may be more efficient then first adding all the
* values to a list and calling calculate().
* @param value value to add
* @note call reset() before adding the first value using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculate()
* @see finalize()
*/
void addValue( double value );
/** Must be called after adding all values with addValues() and before retrieving
* any calculated statistics.
* @see addValue()
*/
void finalize();
/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic
@ -201,6 +221,7 @@ class CORE_EXPORT QgsStatisticalSummary
double mFirstQuartile;
double mThirdQuartile;
QMap< double, int > mValueCount;
QList< double > mValues;
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsStatisticalSummary::Statistics )

View File

@ -52,6 +52,27 @@ void QgsStringStatisticalSummary::calculate( const QStringList& values )
{
testString( string );
}
finalize();
}
void QgsStringStatisticalSummary::addString( const QString& string )
{
testString( string );
}
void QgsStringStatisticalSummary::addValue( const QVariant& value )
{
if ( value.type() == QVariant::String )
{
testString( value.toString() );
}
finalize();
}
void QgsStringStatisticalSummary::finalize()
{
//nothing to do for now - this method has been added for forward compatibility
//if statistics are implemented which require a post-calculation step
}
void QgsStringStatisticalSummary::calculateFromVariants( const QVariantList& values )

View File

@ -77,19 +77,56 @@ class CORE_EXPORT QgsStringStatisticalSummary
*/
void reset();
/** Calculates summary statistics for a list of strings.
/** Calculates summary statistics for an entire list of strings at once.
* @param values list of strings
* @see calculateFromVariants()
* @see addString()
*/
void calculate( const QStringList& values );
/** Calculates summary statistics for a list of variants. Any non-string variants will be
* ignored.
/** Calculates summary statistics for an entire list of variants at once. Any
* non-string variants will be ignored.
* @param values list of variants
* @see calculate()
* @see addValue()
*/
void calculateFromVariants( const QVariantList& values );
/** Adds a single string to the statistics calculation. Calling this method
* allows strings to be added to the calculation one at a time. For large
* quantities of strings this may be more efficient then first adding all the
* strings to a list and calling calculate().
* @param string string to add
* @note call reset() before adding the first string using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final string and before
* retrieving calculated statistics.
* @see calculate()
* @see addValue()
* @see finalize()
*/
void addString( const QString& string );
/** Adds a single variant to the statistics calculation. Calling this method
* allows variants to be added to the calculation one at a time. For large
* quantities of variants this may be more efficient then first adding all the
* variants to a list and calling calculateFromVariants().
* @param value variant to add
* @note call reset() before adding the first string using this method
* to clear the results from any previous calculations
* @note finalize() must be called after adding the final value and before
* retrieving calculated statistics.
* @see calculateFromVariants()
* @see finalize()
*/
void addValue( const QVariant& value );
/** Must be called after adding all strings with addString() and before retrieving
* any calculated string statistics.
* @see addString()
*/
void finalize();
/** Returns the value of a specified statistic
* @param stat statistic to return
* @returns calculated value of statistic

View File

@ -62,64 +62,147 @@ void TestQgsStatisticSummary::cleanup()
void TestQgsStatisticSummary::stats()
{
//note - we test everything twice, once using the statistics calculated by passing
//a list of values and once using the statistics calculated by passing values
//one-at-a-time
QgsStatisticalSummary s( QgsStatisticalSummary::All );
QgsStatisticalSummary s2( QgsStatisticalSummary::All );
QList<double> values;
values << 4 << 2 << 3 << 2 << 5 << 8;
s.calculate( values );
s2.addValue( 4 );
s2.addValue( 2 );
s2.addValue( 3 );
s2.addValue( 2 );
s2.addValue( 5 );
s2.addValue( 8 );
s2.finalize();
QCOMPARE( s.count(), 6 );
QCOMPARE( s2.count(), 6 );
QCOMPARE( s.sum(), 24.0 );
QCOMPARE( s2.sum(), 24.0 );
QCOMPARE( s.mean(), 4.0 );
QCOMPARE( s2.mean(), 4.0 );
QVERIFY( qgsDoubleNear( s.stDev(), 2.0816, 0.0001 ) );
QVERIFY( qgsDoubleNear( s2.stDev(), 2.0816, 0.0001 ) );
QVERIFY( qgsDoubleNear( s.sampleStDev(), 2.2803, 0.0001 ) );
QVERIFY( qgsDoubleNear( s2.sampleStDev(), 2.2803, 0.0001 ) );
QCOMPARE( s.min(), 2.0 );
QCOMPARE( s2.min(), 2.0 );
QCOMPARE( s.max(), 8.0 );
QCOMPARE( s2.max(), 8.0 );
QCOMPARE( s.range(), 6.0 );
QCOMPARE( s2.range(), 6.0 );
QCOMPARE( s.median(), 3.5 );
QCOMPARE( s2.median(), 3.5 );
values << 9;
s.calculate( values );
s2.addValue( 9 );
s2.finalize();
QCOMPARE( s.median(), 4.0 );
QCOMPARE( s2.median(), 4.0 );
values << 4 << 5 << 8 << 12 << 12 << 12;
s.calculate( values );
s2.addValue( 4 );
s2.addValue( 5 ) ;
s2.addValue( 8 );
s2.addValue( 12 );
s2.addValue( 12 );
s2.addValue( 12 );
s2.finalize();
QCOMPARE( s.variety(), 7 );
QCOMPARE( s2.variety(), 7 );
QCOMPARE( s.minority(), 3.0 );
QCOMPARE( s2.minority(), 3.0 );
QCOMPARE( s.majority(), 12.0 );
QCOMPARE( s2.majority(), 12.0 );
//test quartiles. lots of possibilities here, involving odd/even/divisible by 4 counts
values.clear();
values << 7 << 15 << 36 << 39 << 40 << 41;
s.calculate( values );
s2.reset();
s2.addValue( 7 );
s2.addValue( 15 );
s2.addValue( 36 );
s2.addValue( 39 );
s2.addValue( 40 );
s2.addValue( 41 );
s2.finalize();
QCOMPARE( s.median(), 37.5 );
QCOMPARE( s2.median(), 37.5 );
QCOMPARE( s.firstQuartile(), 15.0 );
QCOMPARE( s2.firstQuartile(), 15.0 );
QCOMPARE( s.thirdQuartile(), 40.0 );
QCOMPARE( s2.thirdQuartile(), 40.0 );
QCOMPARE( s.interQuartileRange(), 25.0 );
QCOMPARE( s2.interQuartileRange(), 25.0 );
values.clear();
values << 7 << 15 << 36 << 39 << 40 << 41 << 43 << 49;
s.calculate( values );
s2.reset();
s2.addValue( 7 );
s2.addValue( 15 );
s2.addValue( 36 );
s2.addValue( 39 );
s2.addValue( 40 );
s2.addValue( 41 ) ;
s2.addValue( 43 );
s2.addValue( 49 );
s2.finalize();
QCOMPARE( s.median(), 39.5 );
QCOMPARE( s2.median(), 39.5 );
QCOMPARE( s.firstQuartile(), 25.5 );
QCOMPARE( s2.firstQuartile(), 25.5 );
QCOMPARE( s.thirdQuartile(), 42.0 );
QCOMPARE( s2.thirdQuartile(), 42.0 );
QCOMPARE( s.interQuartileRange(), 16.5 );
QCOMPARE( s2.interQuartileRange(), 16.5 );
values.clear();
values << 6 << 7 << 15 << 36 << 39 << 40 << 41 << 42 << 43 << 47 << 49;
s.calculate( values );
s2.reset();
s2.addValue( 6 );
s2.addValue( 7 );
s2.addValue( 15 );
s2.addValue( 36 );
s2.addValue( 39 );
s2.addValue( 40 );
s2.addValue( 41 );
s2.addValue( 42 );
s2.addValue( 43 );
s2.addValue( 47 );
s2.addValue( 49 );
s2.finalize();
QCOMPARE( s.median(), 40.0 );
QCOMPARE( s2.median(), 40.0 );
QCOMPARE( s.firstQuartile(), 25.5 );
QCOMPARE( s2.firstQuartile(), 25.5 );
QCOMPARE( s.thirdQuartile(), 42.5 );
QCOMPARE( s2.thirdQuartile(), 42.5 );
QCOMPARE( s.interQuartileRange(), 17.0 );
QCOMPARE( s2.interQuartileRange(), 17.0 );
values.clear();
values << 6 << 7 << 15 << 36 << 39 << 40 << 41 << 42 << 43 << 47 << 49 << 50 << 58;
s.calculate( values );
s2.addValue( 50 );
s2.addValue( 58 );
s2.finalize();
QCOMPARE( s.median(), 41.0 );
QCOMPARE( s2.median(), 41.0 );
QCOMPARE( s.firstQuartile(), 36.0 );
QCOMPARE( s2.firstQuartile(), 36.0 );
QCOMPARE( s.thirdQuartile(), 47.0 );
QCOMPARE( s2.thirdQuartile(), 47.0 );
QCOMPARE( s.interQuartileRange(), 11.0 );
QCOMPARE( s2.interQuartileRange(), 11.0 );
}
void TestQgsStatisticSummary::individualStatCalculations_data()
@ -165,6 +248,22 @@ void TestQgsStatisticSummary::individualStatCalculations()
s.calculate( values );
QVERIFY( qgsDoubleNear( s.statistic( stat ), expected, 0.00001 ) );
//also test using values added one-at-a-time
QgsStatisticalSummary s2( QgsStatisticalSummary::Statistics( 0 ) );
s2.setStatistics( stat );
s2.addValue( 4 );
s2.addValue( 4 );
s2.addValue( 2 );
s2.addValue( 3 );
s2.addValue( 3 );
s2.addValue( 3 ) ;
s2.addValue( 5 ) ;
s2.addValue( 5 ) ;
s2.addValue( 8 );
s2.addValue( 8 );
s2.finalize();
QCOMPARE( s2.statistics(), stat );
//make sure stat has a valid display name
QVERIFY( !QgsStatisticalSummary::displayName( stat ).isEmpty() );
}

View File

@ -24,19 +24,29 @@ from qgis.testing import unittest
class PyQgsDateTimeStatisticalSummary(unittest.TestCase):
def testStats(self):
# we test twice, once with values added as a list and once using values
# added one-at-a-time
dates = [QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
QDateTime(),
QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
QDateTime(),
QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))]
s = QgsDateTimeStatisticalSummary()
self.assertEqual(s.statistics(), QgsDateTimeStatisticalSummary.All)
s.calculate([QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
QDateTime(),
QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
QDateTime(),
QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))])
s.calculate(dates)
s2 = QgsDateTimeStatisticalSummary()
for d in dates:
s2.addValue(d)
s2.finalize()
self.assertEqual(s.count(), 9)
self.assertEqual(s2.count(), 9)
self.assertEqual(s.countDistinct(), 6)
self.assertEqual(s2.countDistinct(), 6)
self.assertEqual(set(s.distinctValues()),
set([QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
@ -44,10 +54,15 @@ class PyQgsDateTimeStatisticalSummary(unittest.TestCase):
QDateTime(),
QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))]))
self.assertEqual(s2.distinctValues(), s.distinctValues())
self.assertEqual(s.countMissing(), 2)
self.assertEqual(s2.countMissing(), 2)
self.assertEqual(s.min(), QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)))
self.assertEqual(s2.min(), QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)))
self.assertEqual(s.max(), QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)))
self.assertEqual(s2.max(), QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)))
self.assertEqual(s.range(), QgsInterval(693871147))
self.assertEqual(s2.range(), QgsInterval(693871147))
def testIndividualStats(self):
# tests calculation of statistics one at a time, to make sure statistic calculations are not
@ -60,7 +75,10 @@ class PyQgsDateTimeStatisticalSummary(unittest.TestCase):
{'stat': QgsDateTimeStatisticalSummary.Range, 'expected': QgsInterval(693871147)},
]
# we test twice, once with values added as a list and once using values
# added one-at-a-time
s = QgsDateTimeStatisticalSummary()
s3 = QgsDateTimeStatisticalSummary()
for t in tests:
# test constructor
s2 = QgsDateTimeStatisticalSummary(t['stat'])
@ -68,16 +86,25 @@ class PyQgsDateTimeStatisticalSummary(unittest.TestCase):
s.setStatistics(t['stat'])
self.assertEqual(s.statistics(), t['stat'])
s.calculate([QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
QDateTime(),
QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
QDateTime(),
QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))])
s3.setStatistics(t['stat'])
dates = [QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2011, 1, 5), QTime(15, 3, 1)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2015, 3, 4), QTime(11, 10, 54)),
QDateTime(QDate(2019, 12, 28), QTime(23, 10, 1)),
QDateTime(),
QDateTime(QDate(1998, 1, 2), QTime(1, 10, 54)),
QDateTime(),
QDateTime(QDate(2011, 1, 5), QTime(11, 10, 54))]
s.calculate(dates)
s3.reset()
for d in dates:
s3.addValue(d)
s3.finalize()
self.assertEqual(s.statistic(t['stat']), t['expected'])
self.assertEqual(s3.statistic(t['stat']), t['expected'])
# display name
self.assertTrue(len(QgsDateTimeStatisticalSummary.displayName(t['stat'])) > 0)

View File

@ -22,17 +22,32 @@ from qgis.testing import unittest
class PyQgsStringStatisticalSummary(unittest.TestCase):
def testStats(self):
# we test twice, once with values added as a list and once using values
# added one-at-a-time
s = QgsStringStatisticalSummary()
self.assertEqual(s.statistics(), QgsStringStatisticalSummary.All)
s.calculate(['cc', 'aaaa', 'bbbbbbbb', 'aaaa', 'eeee', '', 'eeee', '', 'dddd'])
strings = ['cc', 'aaaa', 'bbbbbbbb', 'aaaa', 'eeee', '', 'eeee', '', 'dddd']
s.calculate(strings)
s2 = QgsStringStatisticalSummary()
for string in strings:
s2.addString(string)
s2.finalize()
self.assertEqual(s.count(), 9)
self.assertEqual(s2.count(), 9)
self.assertEqual(s.countDistinct(), 6)
self.assertEqual(s2.countDistinct(), 6)
self.assertEqual(set(s.distinctValues()), set(['cc', 'aaaa', 'bbbbbbbb', 'eeee', 'dddd', '']))
self.assertEqual(s2.distinctValues(), s.distinctValues())
self.assertEqual(s.countMissing(), 2)
self.assertEqual(s2.countMissing(), 2)
self.assertEqual(s.min(), 'aaaa')
self.assertEqual(s2.min(), 'aaaa')
self.assertEqual(s.max(), 'eeee')
self.assertEqual(s2.max(), 'eeee')
self.assertEqual(s.minLength(), 0)
self.assertEqual(s2.minLength(), 0)
self.assertEqual(s.maxLength(), 8)
self.assertEqual(s2.maxLength(), 8)
#extra check for minLength without empty strings
s.calculate(['1111111', '111', '11111'])
@ -51,15 +66,25 @@ class PyQgsStringStatisticalSummary(unittest.TestCase):
]
s = QgsStringStatisticalSummary()
s3 = QgsStringStatisticalSummary()
for t in tests:
# test constructor
s2 = QgsStringStatisticalSummary(t['stat'])
self.assertEqual(s2.statistics(), t['stat'])
s.setStatistics(t['stat'])
s3.setStatistics(t['stat'])
self.assertEqual(s.statistics(), t['stat'])
s.calculate(['cc', 'aaaa', 'bbbbbbbb', 'aaaa', 'eeee', '', 'eeee', '', 'dddd'])
strings = ['cc', 'aaaa', 'bbbbbbbb', 'aaaa', 'eeee', '', 'eeee', '', 'dddd']
s.calculate(strings)
s3.reset()
for string in strings:
s3.addString(string)
s3.finalize()
self.assertEqual(s.statistic(t['stat']), t['expected'])
self.assertEqual(s3.statistic(t['stat']), t['expected'])
# display name
self.assertTrue(len(QgsStringStatisticalSummary.displayName(t['stat'])) > 0)