Skip to content

Commit

Permalink
Spreadsheet: Fix for issue #2646: Spreadsheet-Sum-Function does not w…
Browse files Browse the repository at this point in the history
…ork with units

This fix also fixes the other aggregates.
  • Loading branch information
eivindkv authored and wwmayer committed Dec 15, 2016
1 parent de27adb commit 25c56b7
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 22 deletions.
6 changes: 3 additions & 3 deletions src/App/Expression.cpp
Expand Up @@ -733,7 +733,7 @@ class Collector {
Collector() : first(true) { }
virtual void collect(Quantity value) {
if (first)
value.setUnit(value.getUnit());
q.setUnit(value.getUnit());
}
virtual Quantity getQuantity() const {
return q;
Expand Down Expand Up @@ -779,7 +779,7 @@ class StdDevCollector : public Collector {
void collect(Quantity value) {
Collector::collect(value);
if (first) {
M2 = Quantity(0, value.getUnit());
M2 = Quantity(0, value.getUnit() * value.getUnit());
mean = Quantity(0, value.getUnit());
n = 0;
}
Expand All @@ -795,7 +795,7 @@ class StdDevCollector : public Collector {
if (n < 2)
throw ExpressionError("Invalid number of entries: at least two required.");
else
return (M2 / (n - 1.0)).pow(Quantity(0.5));
return Quantity((M2 / (n - 1.0)).pow(Quantity(0.5)).getValue(), mean.getUnit());
}

private:
Expand Down
118 changes: 99 additions & 19 deletions src/Mod/Spreadsheet/TestSpreadsheet.py
Expand Up @@ -29,34 +29,114 @@ def setUp(self):
def testAggregates(self):
""" Test all aggregate functions """
sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet')
sheet.set('B3', '4')
sheet.set('B4', '5')
sheet.set('B5', '6')
sheet.set('B13', '4')
sheet.set('B14', '5')
sheet.set('B15', '6')
sheet.set('C13', '4mm')
sheet.set('C14', '5mm')
sheet.set('C15', '6mm')
sheet.set('C16', '6')

sheet.set('A1', '=sum(1)')
sheet.set('A2', '=sum(1;2)')
sheet.set('A3', '=sum(1;2;3)')
sheet.set('A4', '=sum(1;2;3;B3)')
sheet.set('A5', '=sum(1;2;3;B3:B5)')
sheet.set('A6', '=stddev(1;2;3)')
sheet.set('A7', '=average(1;2;3)')
sheet.set('A8', '=count(1;2;3)')
sheet.set('A9', '=min(1;2;3)')
sheet.set('A10', '=max(1;2;3)')
sheet.set('A11', '=stddev(B3)')
sheet.set('A12', '=stddev(B3:B5)')
sheet.set('A4', '=sum(1;2;3;B13)')
sheet.set('A5', '=sum(1;2;3;B13:B15)')

sheet.set('B1', '=min(1)')
sheet.set('B2', '=min(1;2)')
sheet.set('B3', '=min(1;2;3)')
sheet.set('B4', '=min(1;2;3;B13)')
sheet.set('B5', '=min(1;2;3;B13:B15)')

sheet.set('C1', '=max(1)')
sheet.set('C2', '=max(1;2)')
sheet.set('C3', '=max(1;2;3)')
sheet.set('C4', '=max(1;2;3;B13)')
sheet.set('C5', '=max(1;2;3;B13:B15)')

sheet.set('D1', '=stddev(1)')
sheet.set('D2', '=stddev(1;2)')
sheet.set('D3', '=stddev(1;2;3)')
sheet.set('D4', '=stddev(1;2;3;B13)')
sheet.set('D5', '=stddev(1;2;3;B13:B15)')

sheet.set('E1', '=count(1)')
sheet.set('E2', '=count(1;2)')
sheet.set('E3', '=count(1;2;3)')
sheet.set('E4', '=count(1;2;3;B13)')
sheet.set('E5', '=count(1;2;3;B13:B15)')

sheet.set('F1', '=average(1)')
sheet.set('F2', '=average(1;2)')
sheet.set('F3', '=average(1;2;3)')
sheet.set('F4', '=average(1;2;3;B13)')
sheet.set('F5', '=average(1;2;3;B13:B15)')

sheet.set('G1', '=average(C13:C15)')
sheet.set('G2', '=min(C13:C15)')
sheet.set('G3', '=max(C13:C15)')
sheet.set('G4', '=count(C13:C15)')
sheet.set('G5', '=stddev(C13:C15)')
sheet.set('G6', '=sum(C13:C15)')

sheet.set('H1', '=average(C13:C16)')
sheet.set('H2', '=min(C13:C16)')
sheet.set('H3', '=max(C13:C16)')
sheet.set('H4', '=count(C13:C16)')
sheet.set('H5', '=stddev(C13:C16)')
sheet.set('H6', '=sum(C13:C16)')

self.doc.recompute()
self.assertEqual(sheet.A1, 1)
self.assertEqual(sheet.A2, 3)
self.assertEqual(sheet.A3, 6)
self.assertEqual(sheet.A4, 10)
self.assertEqual(sheet.A5, 21)
self.assertEqual(sheet.A6, 1)
self.assertEqual(sheet.A7, 2)
self.assertEqual(sheet.A8, 3)
self.assertEqual(sheet.A9, 1)
self.assertEqual(sheet.A10, 3)
self.assertEqual(sheet.A11, u'ERR: Invalid number of entries: at least two required.')
self.assertEqual(sheet.A12, 1)

self.assertEqual(sheet.B1, 1)
self.assertEqual(sheet.B2, 1)
self.assertEqual(sheet.B3, 1)
self.assertEqual(sheet.B4, 1)
self.assertEqual(sheet.B5, 1)

self.assertEqual(sheet.C1, 1)
self.assertEqual(sheet.C2, 2)
self.assertEqual(sheet.C3, 3)
self.assertEqual(sheet.C4, 4)
self.assertEqual(sheet.C5, 6)

self.assertEqual(sheet.D1, u'ERR: Invalid number of entries: at least two required.')
self.assertEqual(sheet.D2, 0.7071067811865476)
self.assertEqual(sheet.D3, 1.0)
self.assertEqual(sheet.D4, 1.2909944487358056)
self.assertEqual(sheet.D5, 1.8708286933869707)

self.assertEqual(sheet.E1, 1)
self.assertEqual(sheet.E2, 2)
self.assertEqual(sheet.E3, 3)
self.assertEqual(sheet.E4, 4)
self.assertEqual(sheet.E5, 6)

self.assertEqual(sheet.F1, 1)
self.assertEqual(sheet.F2, (1.0 + 2.0) / 2.0)
self.assertEqual(sheet.F3, (1.0 + 2 + 3) / 3)
self.assertEqual(sheet.F4, (1.0 + 2 + 3 + 4) / 4)
self.assertEqual(sheet.F5, (1.0 + 2 + 3 + 4 + 5 + 6) / 6)

self.assertEqual(sheet.G1, Quantity('5 mm'))
self.assertEqual(sheet.G2, Quantity('4 mm'))
self.assertEqual(sheet.G3, Quantity('6 mm'))
self.assertEqual(sheet.G4, 3)
self.assertEqual(sheet.G5, Quantity('1 mm'))
self.assertEqual(sheet.G6, Quantity('15 mm'))

self.assertEqual(sheet.H1, u'ERR: Quantity::operator +=(): Unit mismatch in plus operation')
self.assertEqual(sheet.H2, u'ERR: Quantity::operator <(): quantities need to have same unit to compare')
self.assertEqual(sheet.H3, u'ERR: Quantity::operator >(): quantities need to have same unit to compare')
self.assertEqual(sheet.H4, 4)
self.assertEqual(sheet.H5, u'ERR: Quantity::operator +(): Unit mismatch in minus operation')
self.assertEqual(sheet.H6, u'ERR: Quantity::operator +=(): Unit mismatch in plus operation')

def assertMostlyEqual(self, a, b):
if type(a) is Quantity:
Expand Down

0 comments on commit 25c56b7

Please sign in to comment.