From b9ac7166e4f698a8c95c1a8b9bed7085288eb0fe Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 10 Sep 2023 12:40:37 +0200 Subject: [PATCH] Sheet: Apply clang format --- src/Mod/Spreadsheet/Init.py | 59 +- src/Mod/Spreadsheet/InitGui.py | 54 +- src/Mod/Spreadsheet/SpreadsheetGlobal.h | 10 +- src/Mod/Spreadsheet/TestSpreadsheet.py | 1755 +++++++++++---------- src/Mod/Spreadsheet/TestSpreadsheetGui.py | 2 +- src/Mod/Spreadsheet/importXLSX.py | 720 +++++---- src/Mod/Spreadsheet/spreadsheet.dox | 1 - 7 files changed, 1329 insertions(+), 1272 deletions(-) diff --git a/src/Mod/Spreadsheet/Init.py b/src/Mod/Spreadsheet/Init.py index 5654dca637..0c8cc4c1b2 100644 --- a/src/Mod/Spreadsheet/Init.py +++ b/src/Mod/Spreadsheet/Init.py @@ -1,27 +1,27 @@ -#*************************************************************************** -#* Copyright (c) 2001,2002 Juergen Riegel * -#* Copyright (c) 2013 Yorik van Havre * -#* Copyright (c) 2013 Eivind Kvedalen * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2001,2002 Juergen Riegel * +# * Copyright (c) 2013 Yorik van Havre * +# * Copyright (c) 2013 Eivind Kvedalen * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ # FreeCAD init script of the Spreadsheet module @@ -30,12 +30,11 @@ ParGrp = App.ParamGet("System parameter:Modules").GetGroup("Spreadsheet") # Set the needed information -ParGrp.SetString("HelpIndex", "Spreadsheet/Help/index.html") -ParGrp.SetString("WorkBenchName", "Spreadsheet") -ParGrp.SetString("WorkBenchModule", "SpreadsheetWorkbench.py") +ParGrp.SetString("HelpIndex", "Spreadsheet/Help/index.html") +ParGrp.SetString("WorkBenchName", "Spreadsheet") +ParGrp.SetString("WorkBenchModule", "SpreadsheetWorkbench.py") # add Import/Export types -App.addImportType("Excel spreadsheet (*.xlsx)","importXLSX") - -App.__unit_test__ += [ "TestSpreadsheet" ] +App.addImportType("Excel spreadsheet (*.xlsx)", "importXLSX") +App.__unit_test__ += ["TestSpreadsheet"] diff --git a/src/Mod/Spreadsheet/InitGui.py b/src/Mod/Spreadsheet/InitGui.py index 8a8b7b2a1e..225695b920 100644 --- a/src/Mod/Spreadsheet/InitGui.py +++ b/src/Mod/Spreadsheet/InitGui.py @@ -1,25 +1,25 @@ -#*************************************************************************** -#* Copyright (c) 2002,2003 Juergen Riegel * -#* Copyright (c) 2013 Eivind Kvedalen * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU General Public License (GPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2002,2003 Juergen Riegel * +# * Copyright (c) 2013 Eivind Kvedalen * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License (GPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# ***************************************************************************/ # Spreadsheet gui init module # @@ -28,10 +28,13 @@ # runs when the gui is up -class SpreadsheetWorkbench ( Workbench ): +class SpreadsheetWorkbench(Workbench): "Spreadsheet workbench object" + def __init__(self): - self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/Spreadsheet/Resources/icons/SpreadsheetWorkbench.svg" + self.__class__.Icon = ( + FreeCAD.getResourceDir() + "Mod/Spreadsheet/Resources/icons/SpreadsheetWorkbench.svg" + ) self.__class__.MenuText = "Spreadsheet" self.__class__.ToolTip = "Spreadsheet workbench" @@ -42,7 +45,8 @@ class SpreadsheetWorkbench ( Workbench ): def GetClassName(self): return "SpreadsheetGui::Workbench" + Gui.addWorkbench(SpreadsheetWorkbench()) # Append the open handler -FreeCAD.addImportType("Spreadsheet formats (*.csv)","SpreadsheetGui") +FreeCAD.addImportType("Spreadsheet formats (*.csv)", "SpreadsheetGui") diff --git a/src/Mod/Spreadsheet/SpreadsheetGlobal.h b/src/Mod/Spreadsheet/SpreadsheetGlobal.h index 66c47f062c..5d59f0a562 100644 --- a/src/Mod/Spreadsheet/SpreadsheetGlobal.h +++ b/src/Mod/Spreadsheet/SpreadsheetGlobal.h @@ -29,19 +29,19 @@ // Spreadsheet #ifndef SpreadsheetExport #ifdef Spreadsheet_EXPORTS -# define SpreadsheetExport FREECAD_DECL_EXPORT +#define SpreadsheetExport FREECAD_DECL_EXPORT #else -# define SpreadsheetExport FREECAD_DECL_IMPORT +#define SpreadsheetExport FREECAD_DECL_IMPORT #endif #endif // SpreadsheetGui #ifndef SpreadsheetGuiExport #ifdef SpreadsheetGui_EXPORTS -# define SpreadsheetGuiExport FREECAD_DECL_EXPORT +#define SpreadsheetGuiExport FREECAD_DECL_EXPORT #else -# define SpreadsheetGuiExport FREECAD_DECL_IMPORT +#define SpreadsheetGuiExport FREECAD_DECL_IMPORT #endif #endif -#endif //SPREADSHEET_GLOBAL_H +#endif// SPREADSHEET_GLOBAL_H diff --git a/src/Mod/Spreadsheet/TestSpreadsheet.py b/src/Mod/Spreadsheet/TestSpreadsheet.py index 9028b9cdd4..7f6b13bd5d 100644 --- a/src/Mod/Spreadsheet/TestSpreadsheet.py +++ b/src/Mod/Spreadsheet/TestSpreadsheet.py @@ -1,23 +1,23 @@ -#*************************************************************************** -#* Copyright (c) 2016 Werner Mayer * -#* Copyright (c) 2016 Eivind Kvedalen * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU General Public License (GPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2016 Werner Mayer * +# * Copyright (c) 2016 Eivind Kvedalen * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License (GPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# ***************************************************************************/ import os import sys @@ -33,77 +33,77 @@ from FreeCAD import Units v = Base.Vector -#---------------------------------------------------------------------------------- +# ---------------------------------------------------------------------------------- # define the functions to test the FreeCAD Spreadsheet module and expression engine -#---------------------------------------------------------------------------------- +# ---------------------------------------------------------------------------------- class SpreadsheetCases(unittest.TestCase): def setUp(self): self.doc = FreeCAD.newDocument() self.TempPath = tempfile.gettempdir() - FreeCAD.Console.PrintLog( ' Using temp path: ' + self.TempPath + '\n') + FreeCAD.Console.PrintLog(" Using temp path: " + self.TempPath + "\n") def testAggregates(self): - """ Test all aggregate functions """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - 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') + """Test all aggregate functions""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + 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;B13)') - sheet.set('A5', '=sum(1;2;3;B13:B15)') + 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;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("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("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("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("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("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("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)') + 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) @@ -124,7 +124,9 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.C4, 4) self.assertEqual(sheet.C5, 6) - self.assertTrue(sheet.D1.startswith(u'ERR: Invalid number of entries: at least two required.')) + self.assertTrue( + sheet.D1.startswith("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) @@ -142,258 +144,272 @@ class SpreadsheetCases(unittest.TestCase): 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, Units.Quantity('5 mm')) - self.assertEqual(sheet.G2, Units.Quantity('4 mm')) - self.assertEqual(sheet.G3, Units.Quantity('6 mm')) + self.assertEqual(sheet.G1, Units.Quantity("5 mm")) + self.assertEqual(sheet.G2, Units.Quantity("4 mm")) + self.assertEqual(sheet.G3, Units.Quantity("6 mm")) self.assertEqual(sheet.G4, 3) - self.assertEqual(sheet.G5, Units.Quantity('1 mm')) - self.assertEqual(sheet.G6, Units.Quantity('15 mm')) + self.assertEqual(sheet.G5, Units.Quantity("1 mm")) + self.assertEqual(sheet.G6, Units.Quantity("15 mm")) - self.assertTrue(sheet.H1.startswith(u'ERR: Quantity::operator +=(): Unit mismatch in plus operation')) - self.assertTrue(sheet.H2.startswith(u'ERR: Quantity::operator <(): quantities need to have same unit to compare')) - self.assertTrue(sheet.H3.startswith(u'ERR: Quantity::operator >(): quantities need to have same unit to compare')) + self.assertTrue( + sheet.H1.startswith("ERR: Quantity::operator +=(): Unit mismatch in plus operation") + ) + self.assertTrue( + sheet.H2.startswith( + "ERR: Quantity::operator <(): quantities need to have same unit to compare" + ) + ) + self.assertTrue( + sheet.H3.startswith( + "ERR: Quantity::operator >(): quantities need to have same unit to compare" + ) + ) self.assertEqual(sheet.H4, 4) - self.assertTrue(sheet.H5.startswith(u'ERR: Quantity::operator -(): Unit mismatch in minus operation')) - self.assertTrue(sheet.H6.startswith(u'ERR: Quantity::operator +=(): Unit mismatch in plus operation')) + self.assertTrue( + sheet.H5.startswith("ERR: Quantity::operator -(): Unit mismatch in minus operation") + ) + self.assertTrue( + sheet.H6.startswith("ERR: Quantity::operator +=(): Unit mismatch in plus operation") + ) def assertMostlyEqual(self, a, b): if type(a) is Units.Quantity: - self.assertTrue( math.fabs(a.Value - b.Value) < 1e-14) - self.assertTrue( a.Unit == b.Unit) + self.assertTrue(math.fabs(a.Value - b.Value) < 1e-14) + self.assertTrue(a.Unit == b.Unit) else: - self.assertTrue( math.fabs(a - b) < 1e-14) + self.assertTrue(math.fabs(a - b) < 1e-14) def testFunctions(self): - """ Test all built-in simple functions """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '=cos(60)') # Cos - sheet.set('B1', '=cos(60deg)') - sheet.set('C1', '=cos(pi / 2 * 1rad)') - sheet.set('A2', '=sin(30)') # Sin - sheet.set('B2', '=sin(30deg)') - sheet.set('C2', '=sin(pi / 6 * 1rad)') - sheet.set('A3', '=tan(45)') # Tan - sheet.set('B3', '=tan(45deg)') - sheet.set('C3', '=tan(pi / 4 * 1rad)') - sheet.set('A4', '=abs(3)') # Abs - sheet.set('B4', '=abs(-3)') - sheet.set('C4', '=abs(-3mm)') - sheet.set('A5', '=exp(3)') # Exp - sheet.set('B5', '=exp(-3)') - sheet.set('C5', '=exp(-3mm)') - sheet.set('A6', '=log(3)') # Log - sheet.set('B6', '=log(-3)') - sheet.set('C6', '=log(-3mm)') - sheet.set('A7', '=log10(10)') # Log10 - sheet.set('B7', '=log10(-3)') - sheet.set('C7', '=log10(-3mm)') - sheet.set('A8', '=round(3.4)')# Round - sheet.set('B8', '=round(3.6)') - sheet.set('C8', '=round(-3.4)') - sheet.set('D8', '=round(-3.6)') - sheet.set('E8', '=round(3.4mm)') - sheet.set('F8', '=round(3.6mm)') - sheet.set('G8', '=round(-3.4mm)') - sheet.set('H8', '=round(-3.6mm)') - sheet.set('A9', '=trunc(3.4)')# Trunc - sheet.set('B9', '=trunc(3.6)') - sheet.set('C9', '=trunc(-3.4)') - sheet.set('D9', '=trunc(-3.6)') - sheet.set('E9', '=trunc(3.4mm)') - sheet.set('F9', '=trunc(3.6mm)') - sheet.set('G9', '=trunc(-3.4mm)') - sheet.set('H9', '=trunc(-3.6mm)') - sheet.set('A10', '=ceil(3.4)') # Ceil - sheet.set('B10', '=ceil(3.6)') - sheet.set('C10', '=ceil(-3.4)') - sheet.set('D10', '=ceil(-3.6)') - sheet.set('E10', '=ceil(3.4mm)') - sheet.set('F10', '=ceil(3.6mm)') - sheet.set('G10', '=ceil(-3.4mm)') - sheet.set('H10', '=ceil(-3.6mm)') - sheet.set('A11', '=floor(3.4)')# Floor - sheet.set('B11', '=floor(3.6)') - sheet.set('C11', '=floor(-3.4)') - sheet.set('D11', '=floor(-3.6)') - sheet.set('E11', '=floor(3.4mm)') - sheet.set('F11', '=floor(3.6mm)') - sheet.set('G11', '=floor(-3.4mm)') - sheet.set('H11', '=floor(-3.6mm)') - sheet.set('A12', '=asin(0.5)') # Asin - sheet.set('B12', '=asin(0.5mm)') - sheet.set('A13', '=acos(0.5)') # Acos - sheet.set('B13', '=acos(0.5mm)') - sheet.set('A14', '=atan(sqrt(3))') # Atan - sheet.set('B14', '=atan(0.5mm)') - sheet.set('A15', '=sinh(0.5)') # Sinh - sheet.set('B15', '=sinh(0.5mm)') - sheet.set('A16', '=cosh(0.5)') # Cosh - sheet.set('B16', '=cosh(0.5mm)') - sheet.set('A17', '=tanh(0.5)') # Tanh - sheet.set('B17', '=tanh(0.5mm)') - sheet.set('A18', '=sqrt(4)') # Sqrt - sheet.set('B18', '=sqrt(4mm^2)') - sheet.set('A19', '=mod(7; 4)') # Mod - sheet.set('B19', '=mod(-7; 4)') - sheet.set('C19', '=mod(7mm; 4)') - sheet.set('D19', '=mod(7mm; 4mm)') - sheet.set('A20', '=atan2(3; 3)') # Atan2 - sheet.set('B20', '=atan2(-3; 3)') - sheet.set('C20', '=atan2(3mm; 3)') - sheet.set('D20', '=atan2(3mm; 3mm)') - sheet.set('A21', '=pow(7; 4)') # Pow - sheet.set('B21', '=pow(-7; 4)') - sheet.set('C21', '=pow(7mm; 4)') - sheet.set('D21', '=pow(7mm; 4mm)') - sheet.set('A23', '=hypot(3; 4)') # Hypot - sheet.set('B23', '=hypot(-3; 4)') - sheet.set('C23', '=hypot(3mm; 4)') - sheet.set('D23', '=hypot(3mm; 4mm)') - sheet.set('A24', '=hypot(3; 4; 5)') # Hypot - sheet.set('B24', '=hypot(-3; 4; 5)') - sheet.set('C24', '=hypot(3mm; 4; 5)') - sheet.set('D24', '=hypot(3mm; 4mm; 5mm)') - sheet.set('A26', '=cath(5; 3)') # Cath - sheet.set('B26', '=cath(-5; 3)') - sheet.set('C26', '=cath(5mm; 3)') - sheet.set('D26', '=cath(5mm; 3mm)') + """Test all built-in simple functions""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "=cos(60)") # Cos + sheet.set("B1", "=cos(60deg)") + sheet.set("C1", "=cos(pi / 2 * 1rad)") + sheet.set("A2", "=sin(30)") # Sin + sheet.set("B2", "=sin(30deg)") + sheet.set("C2", "=sin(pi / 6 * 1rad)") + sheet.set("A3", "=tan(45)") # Tan + sheet.set("B3", "=tan(45deg)") + sheet.set("C3", "=tan(pi / 4 * 1rad)") + sheet.set("A4", "=abs(3)") # Abs + sheet.set("B4", "=abs(-3)") + sheet.set("C4", "=abs(-3mm)") + sheet.set("A5", "=exp(3)") # Exp + sheet.set("B5", "=exp(-3)") + sheet.set("C5", "=exp(-3mm)") + sheet.set("A6", "=log(3)") # Log + sheet.set("B6", "=log(-3)") + sheet.set("C6", "=log(-3mm)") + sheet.set("A7", "=log10(10)") # Log10 + sheet.set("B7", "=log10(-3)") + sheet.set("C7", "=log10(-3mm)") + sheet.set("A8", "=round(3.4)") # Round + sheet.set("B8", "=round(3.6)") + sheet.set("C8", "=round(-3.4)") + sheet.set("D8", "=round(-3.6)") + sheet.set("E8", "=round(3.4mm)") + sheet.set("F8", "=round(3.6mm)") + sheet.set("G8", "=round(-3.4mm)") + sheet.set("H8", "=round(-3.6mm)") + sheet.set("A9", "=trunc(3.4)") # Trunc + sheet.set("B9", "=trunc(3.6)") + sheet.set("C9", "=trunc(-3.4)") + sheet.set("D9", "=trunc(-3.6)") + sheet.set("E9", "=trunc(3.4mm)") + sheet.set("F9", "=trunc(3.6mm)") + sheet.set("G9", "=trunc(-3.4mm)") + sheet.set("H9", "=trunc(-3.6mm)") + sheet.set("A10", "=ceil(3.4)") # Ceil + sheet.set("B10", "=ceil(3.6)") + sheet.set("C10", "=ceil(-3.4)") + sheet.set("D10", "=ceil(-3.6)") + sheet.set("E10", "=ceil(3.4mm)") + sheet.set("F10", "=ceil(3.6mm)") + sheet.set("G10", "=ceil(-3.4mm)") + sheet.set("H10", "=ceil(-3.6mm)") + sheet.set("A11", "=floor(3.4)") # Floor + sheet.set("B11", "=floor(3.6)") + sheet.set("C11", "=floor(-3.4)") + sheet.set("D11", "=floor(-3.6)") + sheet.set("E11", "=floor(3.4mm)") + sheet.set("F11", "=floor(3.6mm)") + sheet.set("G11", "=floor(-3.4mm)") + sheet.set("H11", "=floor(-3.6mm)") + sheet.set("A12", "=asin(0.5)") # Asin + sheet.set("B12", "=asin(0.5mm)") + sheet.set("A13", "=acos(0.5)") # Acos + sheet.set("B13", "=acos(0.5mm)") + sheet.set("A14", "=atan(sqrt(3))") # Atan + sheet.set("B14", "=atan(0.5mm)") + sheet.set("A15", "=sinh(0.5)") # Sinh + sheet.set("B15", "=sinh(0.5mm)") + sheet.set("A16", "=cosh(0.5)") # Cosh + sheet.set("B16", "=cosh(0.5mm)") + sheet.set("A17", "=tanh(0.5)") # Tanh + sheet.set("B17", "=tanh(0.5mm)") + sheet.set("A18", "=sqrt(4)") # Sqrt + sheet.set("B18", "=sqrt(4mm^2)") + sheet.set("A19", "=mod(7; 4)") # Mod + sheet.set("B19", "=mod(-7; 4)") + sheet.set("C19", "=mod(7mm; 4)") + sheet.set("D19", "=mod(7mm; 4mm)") + sheet.set("A20", "=atan2(3; 3)") # Atan2 + sheet.set("B20", "=atan2(-3; 3)") + sheet.set("C20", "=atan2(3mm; 3)") + sheet.set("D20", "=atan2(3mm; 3mm)") + sheet.set("A21", "=pow(7; 4)") # Pow + sheet.set("B21", "=pow(-7; 4)") + sheet.set("C21", "=pow(7mm; 4)") + sheet.set("D21", "=pow(7mm; 4mm)") + sheet.set("A23", "=hypot(3; 4)") # Hypot + sheet.set("B23", "=hypot(-3; 4)") + sheet.set("C23", "=hypot(3mm; 4)") + sheet.set("D23", "=hypot(3mm; 4mm)") + sheet.set("A24", "=hypot(3; 4; 5)") # Hypot + sheet.set("B24", "=hypot(-3; 4; 5)") + sheet.set("C24", "=hypot(3mm; 4; 5)") + sheet.set("D24", "=hypot(3mm; 4mm; 5mm)") + sheet.set("A26", "=cath(5; 3)") # Cath + sheet.set("B26", "=cath(-5; 3)") + sheet.set("C26", "=cath(5mm; 3)") + sheet.set("D26", "=cath(5mm; 3mm)") - l = math.sqrt(5 * 5 + 4*4 + 3*3) - sheet.set('A27', '=cath(%0.15f; 5; 4)' % l) # Cath - sheet.set('B27', '=cath(%0.15f; -5; 4)' % l) - sheet.set('C27', '=cath(%0.15f mm; 5mm; 4)' % l) - sheet.set('D27', '=cath(%0.15f mm; 5mm; 4mm)' % l) + l = math.sqrt(5 * 5 + 4 * 4 + 3 * 3) + sheet.set("A27", "=cath(%0.15f; 5; 4)" % l) # Cath + sheet.set("B27", "=cath(%0.15f; -5; 4)" % l) + sheet.set("C27", "=cath(%0.15f mm; 5mm; 4)" % l) + sheet.set("D27", "=cath(%0.15f mm; 5mm; 4mm)" % l) self.doc.recompute() - self.assertMostlyEqual(sheet.A1, 0.5) # Cos - self.assertMostlyEqual(sheet.B1, 0.5) - self.assertMostlyEqual(sheet.C1, 0) - self.assertMostlyEqual(sheet.A2, 0.5) # Sin - self.assertMostlyEqual(sheet.B2, 0.5) - self.assertMostlyEqual(sheet.C2, 0.5) - self.assertMostlyEqual(sheet.A3, 1) # Tan - self.assertMostlyEqual(sheet.B3, 1) - self.assertMostlyEqual(sheet.C3, 1 ) - self.assertMostlyEqual(sheet.A4, 3) # Abs - self.assertMostlyEqual(sheet.B4, 3) - self.assertMostlyEqual(sheet.C4, Units.Quantity('3 mm')) - self.assertMostlyEqual(sheet.A5, math.exp(3)) # Exp - self.assertMostlyEqual(sheet.B5, math.exp(-3)) - self.assertTrue(sheet.C5.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A6, math.log(3)) # Log + self.assertMostlyEqual(sheet.A1, 0.5) # Cos + self.assertMostlyEqual(sheet.B1, 0.5) + self.assertMostlyEqual(sheet.C1, 0) + self.assertMostlyEqual(sheet.A2, 0.5) # Sin + self.assertMostlyEqual(sheet.B2, 0.5) + self.assertMostlyEqual(sheet.C2, 0.5) + self.assertMostlyEqual(sheet.A3, 1) # Tan + self.assertMostlyEqual(sheet.B3, 1) + self.assertMostlyEqual(sheet.C3, 1) + self.assertMostlyEqual(sheet.A4, 3) # Abs + self.assertMostlyEqual(sheet.B4, 3) + self.assertMostlyEqual(sheet.C4, Units.Quantity("3 mm")) + self.assertMostlyEqual(sheet.A5, math.exp(3)) # Exp + self.assertMostlyEqual(sheet.B5, math.exp(-3)) + self.assertTrue(sheet.C5.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A6, math.log(3)) # Log self.assertTrue(math.isnan(sheet.B6)) - self.assertTrue(sheet.C6.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A7, math.log10(10)) # Log10 + self.assertTrue(sheet.C6.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A7, math.log10(10)) # Log10 self.assertTrue(math.isnan(sheet.B7)) - self.assertTrue(sheet.C7.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A8, 3) # Round - self.assertMostlyEqual(sheet.B8, 4) - self.assertMostlyEqual(sheet.C8, -3) - self.assertMostlyEqual(sheet.D8, -4) - self.assertEqual(sheet.E8, Units.Quantity('3 mm')) - self.assertEqual(sheet.F8, Units.Quantity('4 mm')) - self.assertEqual(sheet.G8, Units.Quantity('-3 mm')) - self.assertEqual(sheet.H8, Units.Quantity('-4 mm')) - self.assertMostlyEqual(sheet.A9, 3)# Trunc - self.assertMostlyEqual(sheet.B9, 3) - self.assertMostlyEqual(sheet.C9, -3) - self.assertMostlyEqual(sheet.D9, -3) - self.assertEqual(sheet.E9, Units.Quantity('3 mm')) - self.assertEqual(sheet.F9, Units.Quantity('3 mm')) - self.assertEqual(sheet.G9, Units.Quantity('-3 mm')) - self.assertEqual(sheet.H9, Units.Quantity('-3 mm')) - self.assertMostlyEqual(sheet.A10, 4) # Ceil + self.assertTrue(sheet.C7.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A8, 3) # Round + self.assertMostlyEqual(sheet.B8, 4) + self.assertMostlyEqual(sheet.C8, -3) + self.assertMostlyEqual(sheet.D8, -4) + self.assertEqual(sheet.E8, Units.Quantity("3 mm")) + self.assertEqual(sheet.F8, Units.Quantity("4 mm")) + self.assertEqual(sheet.G8, Units.Quantity("-3 mm")) + self.assertEqual(sheet.H8, Units.Quantity("-4 mm")) + self.assertMostlyEqual(sheet.A9, 3) # Trunc + self.assertMostlyEqual(sheet.B9, 3) + self.assertMostlyEqual(sheet.C9, -3) + self.assertMostlyEqual(sheet.D9, -3) + self.assertEqual(sheet.E9, Units.Quantity("3 mm")) + self.assertEqual(sheet.F9, Units.Quantity("3 mm")) + self.assertEqual(sheet.G9, Units.Quantity("-3 mm")) + self.assertEqual(sheet.H9, Units.Quantity("-3 mm")) + self.assertMostlyEqual(sheet.A10, 4) # Ceil self.assertMostlyEqual(sheet.B10, 4) self.assertMostlyEqual(sheet.C10, -3) self.assertMostlyEqual(sheet.D10, -3) - self.assertMostlyEqual(sheet.E10, Units.Quantity('4 mm')) - self.assertMostlyEqual(sheet.F10, Units.Quantity('4 mm')) - self.assertMostlyEqual(sheet.G10, Units.Quantity('-3 mm')) - self.assertMostlyEqual(sheet.H10, Units.Quantity('-3 mm')) - self.assertMostlyEqual(sheet.A11, 3)# Floor + self.assertMostlyEqual(sheet.E10, Units.Quantity("4 mm")) + self.assertMostlyEqual(sheet.F10, Units.Quantity("4 mm")) + self.assertMostlyEqual(sheet.G10, Units.Quantity("-3 mm")) + self.assertMostlyEqual(sheet.H10, Units.Quantity("-3 mm")) + self.assertMostlyEqual(sheet.A11, 3) # Floor self.assertMostlyEqual(sheet.B11, 3) self.assertMostlyEqual(sheet.C11, -4) self.assertMostlyEqual(sheet.D11, -4) - self.assertMostlyEqual(sheet.E11, Units.Quantity('3 mm')) - self.assertMostlyEqual(sheet.F11, Units.Quantity('3 mm')) - self.assertMostlyEqual(sheet.G11, Units.Quantity('-4 mm')) - self.assertMostlyEqual(sheet.H11, Units.Quantity('-4 mm')) - self.assertMostlyEqual(sheet.A12, Units.Quantity('30 deg')) # Asin - self.assertTrue(sheet.B12.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A13, Units.Quantity('60 deg')) # Acos - self.assertTrue(sheet.B13.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A14, Units.Quantity('60 deg')) # Atan - self.assertTrue(sheet.B14.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A15, math.sinh(0.5)) # Sinh - self.assertTrue(sheet.B15.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A16, math.cosh(0.5)) # Cosh - self.assertTrue(sheet.B16.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A17, math.tanh(0.5)) # Tanh - self.assertTrue(sheet.B17.startswith(u'ERR: Unit must be empty.')) - self.assertMostlyEqual(sheet.A18, 2) # Sqrt - self.assertMostlyEqual(sheet.B18, Units.Quantity('2 mm')) - self.assertMostlyEqual(sheet.A19, 3) # Mod + self.assertMostlyEqual(sheet.E11, Units.Quantity("3 mm")) + self.assertMostlyEqual(sheet.F11, Units.Quantity("3 mm")) + self.assertMostlyEqual(sheet.G11, Units.Quantity("-4 mm")) + self.assertMostlyEqual(sheet.H11, Units.Quantity("-4 mm")) + self.assertMostlyEqual(sheet.A12, Units.Quantity("30 deg")) # Asin + self.assertTrue(sheet.B12.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A13, Units.Quantity("60 deg")) # Acos + self.assertTrue(sheet.B13.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A14, Units.Quantity("60 deg")) # Atan + self.assertTrue(sheet.B14.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A15, math.sinh(0.5)) # Sinh + self.assertTrue(sheet.B15.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A16, math.cosh(0.5)) # Cosh + self.assertTrue(sheet.B16.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A17, math.tanh(0.5)) # Tanh + self.assertTrue(sheet.B17.startswith("ERR: Unit must be empty.")) + self.assertMostlyEqual(sheet.A18, 2) # Sqrt + self.assertMostlyEqual(sheet.B18, Units.Quantity("2 mm")) + self.assertMostlyEqual(sheet.A19, 3) # Mod self.assertMostlyEqual(sheet.B19, -3) - self.assertMostlyEqual(sheet.C19, Units.Quantity('3 mm')) + self.assertMostlyEqual(sheet.C19, Units.Quantity("3 mm")) self.assertEqual(sheet.D19, 3) - self.assertMostlyEqual(sheet.A20, Units.Quantity('45 deg')) # Atan2 - self.assertMostlyEqual(sheet.B20, Units.Quantity('-45 deg')) - self.assertTrue(sheet.C20.startswith(u'ERR: Units must be equal')) - self.assertMostlyEqual(sheet.D20, Units.Quantity('45 deg')) - self.assertMostlyEqual(sheet.A21, 2401) # Pow + self.assertMostlyEqual(sheet.A20, Units.Quantity("45 deg")) # Atan2 + self.assertMostlyEqual(sheet.B20, Units.Quantity("-45 deg")) + self.assertTrue(sheet.C20.startswith("ERR: Units must be equal")) + self.assertMostlyEqual(sheet.D20, Units.Quantity("45 deg")) + self.assertMostlyEqual(sheet.A21, 2401) # Pow self.assertMostlyEqual(sheet.B21, 2401) - self.assertMostlyEqual(sheet.C21, Units.Quantity('2401mm^4')) - self.assertTrue(sheet.D21.startswith(u'ERR: Exponent is not allowed to have a unit.')) - self.assertMostlyEqual(sheet.A23, 5) # Hypot + self.assertMostlyEqual(sheet.C21, Units.Quantity("2401mm^4")) + self.assertTrue(sheet.D21.startswith("ERR: Exponent is not allowed to have a unit.")) + self.assertMostlyEqual(sheet.A23, 5) # Hypot self.assertMostlyEqual(sheet.B23, 5) - self.assertTrue(sheet.C23.startswith(u'ERR: Units must be equal')) - self.assertMostlyEqual(sheet.D23, Units.Quantity('5mm')) + self.assertTrue(sheet.C23.startswith("ERR: Units must be equal")) + self.assertMostlyEqual(sheet.D23, Units.Quantity("5mm")) - l = math.sqrt(3*3 + 4*4 + 5*5) - self.assertMostlyEqual(sheet.A24, l) # Hypot + l = math.sqrt(3 * 3 + 4 * 4 + 5 * 5) + self.assertMostlyEqual(sheet.A24, l) # Hypot self.assertMostlyEqual(sheet.B24, l) - self.assertTrue(sheet.C24.startswith(u'ERR: Units must be equal')) + self.assertTrue(sheet.C24.startswith("ERR: Units must be equal")) self.assertMostlyEqual(sheet.D24, Units.Quantity("7.07106781186548 mm")) - self.assertMostlyEqual(sheet.A26, 4) # Cath + self.assertMostlyEqual(sheet.A26, 4) # Cath self.assertMostlyEqual(sheet.B26, 4) - self.assertTrue(sheet.C26.startswith(u'ERR: Units must be equal')) - self.assertMostlyEqual(sheet.D26, Units.Quantity('4mm')) + self.assertTrue(sheet.C26.startswith("ERR: Units must be equal")) + self.assertMostlyEqual(sheet.D26, Units.Quantity("4mm")) - l = math.sqrt(5 * 5 + 4*4 + 3*3) - l = math.sqrt(l * l - 5*5 - 4*4) - self.assertMostlyEqual(sheet.A27, l) # Cath + l = math.sqrt(5 * 5 + 4 * 4 + 3 * 3) + l = math.sqrt(l * l - 5 * 5 - 4 * 4) + self.assertMostlyEqual(sheet.A27, l) # Cath self.assertMostlyEqual(sheet.B27, l) - self.assertTrue(sheet.C27.startswith(u'ERR: Units must be equal')) + self.assertTrue(sheet.C27.startswith("ERR: Units must be equal")) self.assertMostlyEqual(sheet.D27, Units.Quantity("3 mm")) def testRelationalOperators(self): - """ Test relational operators """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + """Test relational operators""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") # All should be 1 as result - sheet.set('A1', '=1 == 1 ? 1 : 0') - sheet.set('A2', '=1 != 1 ? 0 : 1') - sheet.set('A3', '=1e9 == 1e9 ? 1 : 0') - sheet.set('A4', '=1e9 != 1e9 ? 0 : 1') - sheet.set('A5', '=1 > 1 ? 0 : 1') - sheet.set('A6', '=2 > 1 ? 1 : 0') - sheet.set('A7', '=1 > 2 ? 0 : 1') - sheet.set('A8', '=1 < 1 ? 0 : 1') - sheet.set('A9', '=1 < 2 ? 1 : 0') - sheet.set('A10', '=2 < 1 ? 0 : 1') - sheet.set('A11', '=1 >= 1 ? 1 : 0') - sheet.set('A12', '=2 >= 1 ? 1 : 0') - sheet.set('A13', '=1 >= 2 ? 0 : 1') - sheet.set('A14', '=1 <= 1 ? 1 : 1') - sheet.set('A15', '=1 <= 2 ? 1 : 0') - sheet.set('A16', '=2 <= 1 ? 0 : 1') - sheet.set('A17', '=1 >= 1.000000000000001 ? 0 : 1') - sheet.set('A18', '=1 >= 1.0000000000000001 ? 1 : 0') - sheet.set('A19', '=1 <= 1.000000000000001 ? 1 : 0') - sheet.set('A20', '=1 <= 1.0000000000000001 ? 1 : 0') - sheet.set('A21', '=1 == 1.000000000000001 ? 0 : 1') - sheet.set('A22', '=1 == 1.0000000000000001 ? 1 : 0') - sheet.set('A23', '=1 != 1.000000000000001 ? 1 : 0') - sheet.set('A24', '=1 != 1.0000000000000001 ? 0 : 1') + sheet.set("A1", "=1 == 1 ? 1 : 0") + sheet.set("A2", "=1 != 1 ? 0 : 1") + sheet.set("A3", "=1e9 == 1e9 ? 1 : 0") + sheet.set("A4", "=1e9 != 1e9 ? 0 : 1") + sheet.set("A5", "=1 > 1 ? 0 : 1") + sheet.set("A6", "=2 > 1 ? 1 : 0") + sheet.set("A7", "=1 > 2 ? 0 : 1") + sheet.set("A8", "=1 < 1 ? 0 : 1") + sheet.set("A9", "=1 < 2 ? 1 : 0") + sheet.set("A10", "=2 < 1 ? 0 : 1") + sheet.set("A11", "=1 >= 1 ? 1 : 0") + sheet.set("A12", "=2 >= 1 ? 1 : 0") + sheet.set("A13", "=1 >= 2 ? 0 : 1") + sheet.set("A14", "=1 <= 1 ? 1 : 1") + sheet.set("A15", "=1 <= 2 ? 1 : 0") + sheet.set("A16", "=2 <= 1 ? 0 : 1") + sheet.set("A17", "=1 >= 1.000000000000001 ? 0 : 1") + sheet.set("A18", "=1 >= 1.0000000000000001 ? 1 : 0") + sheet.set("A19", "=1 <= 1.000000000000001 ? 1 : 0") + sheet.set("A20", "=1 <= 1.0000000000000001 ? 1 : 0") + sheet.set("A21", "=1 == 1.000000000000001 ? 0 : 1") + sheet.set("A22", "=1 == 1.0000000000000001 ? 1 : 0") + sheet.set("A23", "=1 != 1.000000000000001 ? 1 : 0") + sheet.set("A24", "=1 != 1.0000000000000001 ? 0 : 1") self.doc.recompute() self.assertEqual(sheet.A1, 1) @@ -422,89 +438,91 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.A24, 1) def testUnits(self): - """ Units -- test unit calculations. """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '=2mm + 3mm') - sheet.set('A2', '=2mm - 3mm') - sheet.set('A3', '=2mm * 3mm') - sheet.set('A4', '=4mm / 2mm') - sheet.set('A5', '=(4mm)^2') - sheet.set('A6', '=5(mm^2)') - sheet.set('A7', '=5mm^2') # ^2 operates on whole number - sheet.set('A8', '=5') - sheet.set('A9', '=5*1/K') # Currently fails - sheet.set('A10', '=5 K^-1') # Currently fails - sheet.set('A11', '=9.8 m/s^2') # Currently fails - sheet.setDisplayUnit('A8', '1/K') + """Units -- test unit calculations.""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "=2mm + 3mm") + sheet.set("A2", "=2mm - 3mm") + sheet.set("A3", "=2mm * 3mm") + sheet.set("A4", "=4mm / 2mm") + sheet.set("A5", "=(4mm)^2") + sheet.set("A6", "=5(mm^2)") + sheet.set("A7", "=5mm^2") # ^2 operates on whole number + sheet.set("A8", "=5") + sheet.set("A9", "=5*1/K") # Currently fails + sheet.set("A10", "=5 K^-1") # Currently fails + sheet.set("A11", "=9.8 m/s^2") # Currently fails + sheet.setDisplayUnit("A8", "1/K") self.doc.recompute() - self.assertEqual(sheet.A1, Units.Quantity('5mm')) - self.assertEqual(sheet.A2, Units.Quantity('-1 mm')) - self.assertEqual(sheet.A3, Units.Quantity('6 mm^2')) - self.assertEqual(sheet.A4, Units.Quantity('2')) - self.assertEqual(sheet.A5, Units.Quantity('16 mm^2')) - self.assertEqual(sheet.A6, Units.Quantity('5 mm^2')) - self.assertEqual(sheet.A7, Units.Quantity('5 mm^2')) - self.assertEqual(sheet.A8, Units.Quantity('5')) - self.assertEqual(sheet.A9, Units.Quantity('5 K^-1')) - self.assertEqual(sheet.A10, Units.Quantity('5 K^-1')) - self.assertEqual(sheet.A11, Units.Quantity('9.8 m/s^2')) + self.assertEqual(sheet.A1, Units.Quantity("5mm")) + self.assertEqual(sheet.A2, Units.Quantity("-1 mm")) + self.assertEqual(sheet.A3, Units.Quantity("6 mm^2")) + self.assertEqual(sheet.A4, Units.Quantity("2")) + self.assertEqual(sheet.A5, Units.Quantity("16 mm^2")) + self.assertEqual(sheet.A6, Units.Quantity("5 mm^2")) + self.assertEqual(sheet.A7, Units.Quantity("5 mm^2")) + self.assertEqual(sheet.A8, Units.Quantity("5")) + self.assertEqual(sheet.A9, Units.Quantity("5 K^-1")) + self.assertEqual(sheet.A10, Units.Quantity("5 K^-1")) + self.assertEqual(sheet.A11, Units.Quantity("9.8 m/s^2")) def testPrecedence(self): - """ Precedence -- test precedence for relational operators and conditional operator. """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '=1 < 2 ? 3 : 4') - sheet.set('A2', '=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8') - sheet.set('A3', '=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3') - sheet.set('A4', '=123') - sheet.set('A5', '=123 + 321') - sheet.set('A6', '=123 * 2 + 321') - sheet.set('A7', '=123 * 2 + 333 / 3') - sheet.set('A8', '=123 * (2 + 321)') - sheet.set('A9', '=3 ^ 4') - sheet.set('A10', '=3 ^ 4 * 2') - sheet.set('A11', '=3 ^ (4 * 2)') - sheet.set('A12', '=3 ^ 4 + 4') - sheet.set('A13', '=1 + 4 / 2 + 5') - sheet.set('A14', '=(3 + 6) / (1 + 2)') - sheet.set('A15', '=1 * 2 / 3 * 4') - sheet.set('A16', '=(1 * 2) / (3 * 4)') + """Precedence -- test precedence for relational operators and conditional operator.""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "=1 < 2 ? 3 : 4") + sheet.set("A2", "=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8") + sheet.set("A3", "=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3") + sheet.set("A4", "=123") + sheet.set("A5", "=123 + 321") + sheet.set("A6", "=123 * 2 + 321") + sheet.set("A7", "=123 * 2 + 333 / 3") + sheet.set("A8", "=123 * (2 + 321)") + sheet.set("A9", "=3 ^ 4") + sheet.set("A10", "=3 ^ 4 * 2") + sheet.set("A11", "=3 ^ (4 * 2)") + sheet.set("A12", "=3 ^ 4 + 4") + sheet.set("A13", "=1 + 4 / 2 + 5") + sheet.set("A14", "=(3 + 6) / (1 + 2)") + sheet.set("A15", "=1 * 2 / 3 * 4") + sheet.set("A16", "=(1 * 2) / (3 * 4)") # Test associativity - sheet.set('A17', '=3 ^ 4 ^ 2') # exponentiation is left-associative; to follow excel, openoffice, matlab, octave - sheet.set('A18', '=3 ^ (4 ^ 2)') # exponentiation is left-associative - sheet.set('A19', '=(3 ^ 4) ^ 2') # exponentiation is left-associative - sheet.set('A20', '=3 + 4 + 2') - sheet.set('A21', '=3 + (4 + 2)') - sheet.set('A22', '=(3 + 4) + 2') - sheet.set('A23', '=3 - 4 - 2') - sheet.set('A24', '=3 - (4 - 2)') - sheet.set('A25', '=(3 - 4) - 2') - sheet.set('A26', '=3 * 4 * 2') - sheet.set('A27', '=3 * (4 * 2)') - sheet.set('A28', '=(3 * 4) * 2') - sheet.set('A29', '=3 / 4 / 2') - sheet.set('A30', '=3 / (4 / 2)') - sheet.set('A31', '=(3 / 4) / 2') - sheet.set('A32', '=pi * 3') - sheet.set('A33', '=A32 / 3') - sheet.set('A34', '=1 < 2 ? <> : <>') - sheet.set('A35', '=min(A32:A33)') - sheet.set('A36', '=(1 < 2 ? 0 : 1) * 3') - sheet.set('A37', '=8/(2^2*2)') - sheet.set('A38', '=(2^2*2)/8') - sheet.set('A39', '=2^(2*2)/8') - sheet.set('A40', '=8/2^(2*2)') - sheet.set('A41', '=-1') - sheet.set('A42', '=-(1)') - sheet.set('A43', '=-(1 + 1)') - sheet.set('A44', '=-(1 - 1)') - sheet.set('A45', '=-(-1 + 1)') - sheet.set('A46', '=-(-1 + -1)') - sheet.set('A47', '=+1') - sheet.set('A48', '=+(1)') - sheet.set('A49', '=+(1 + 1)') - sheet.set('A50', '=+(1 - 1)') - sheet.set('A51', '=+(-1 + 1)') - sheet.set('A52', '=+(-1 + -1)') + sheet.set( + "A17", "=3 ^ 4 ^ 2" + ) # exponentiation is left-associative; to follow excel, openoffice, matlab, octave + sheet.set("A18", "=3 ^ (4 ^ 2)") # exponentiation is left-associative + sheet.set("A19", "=(3 ^ 4) ^ 2") # exponentiation is left-associative + sheet.set("A20", "=3 + 4 + 2") + sheet.set("A21", "=3 + (4 + 2)") + sheet.set("A22", "=(3 + 4) + 2") + sheet.set("A23", "=3 - 4 - 2") + sheet.set("A24", "=3 - (4 - 2)") + sheet.set("A25", "=(3 - 4) - 2") + sheet.set("A26", "=3 * 4 * 2") + sheet.set("A27", "=3 * (4 * 2)") + sheet.set("A28", "=(3 * 4) * 2") + sheet.set("A29", "=3 / 4 / 2") + sheet.set("A30", "=3 / (4 / 2)") + sheet.set("A31", "=(3 / 4) / 2") + sheet.set("A32", "=pi * 3") + sheet.set("A33", "=A32 / 3") + sheet.set("A34", "=1 < 2 ? <> : <>") + sheet.set("A35", "=min(A32:A33)") + sheet.set("A36", "=(1 < 2 ? 0 : 1) * 3") + sheet.set("A37", "=8/(2^2*2)") + sheet.set("A38", "=(2^2*2)/8") + sheet.set("A39", "=2^(2*2)/8") + sheet.set("A40", "=8/2^(2*2)") + sheet.set("A41", "=-1") + sheet.set("A42", "=-(1)") + sheet.set("A43", "=-(1 + 1)") + sheet.set("A44", "=-(1 - 1)") + sheet.set("A45", "=-(-1 + 1)") + sheet.set("A46", "=-(-1 + -1)") + sheet.set("A47", "=+1") + sheet.set("A48", "=+(1)") + sheet.set("A49", "=+(1 + 1)") + sheet.set("A50", "=+(1 - 1)") + sheet.set("A51", "=+(-1 + 1)") + sheet.set("A52", "=+(-1 + -1)") self.doc.addObject("Part::Cylinder", "Cylinder") # We cannot use Thickness, as this feature requires a source shape, @@ -515,14 +533,17 @@ class SpreadsheetCases(unittest.TestCase): self.doc.addObject("Part::Box", "Box") self.doc.Box.Length = 1 - sheet.set('B1', '101') - sheet.set('A53', '=-(-(B1-1)/2)') - sheet.set('A54', '=-(Cylinder.Radius + Box.Length - 1"/2)') + sheet.set("B1", "101") + sheet.set("A53", "=-(-(B1-1)/2)") + sheet.set("A54", '=-(Cylinder.Radius + Box.Length - 1"/2)') self.doc.recompute() self.assertEqual(sheet.getContents("A1"), "=1 < 2 ? 3 : 4") self.assertEqual(sheet.getContents("A2"), "=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8") - self.assertEqual(sheet.getContents("A3"), "=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3") + self.assertEqual( + sheet.getContents("A3"), + "=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3", + ) self.assertEqual(sheet.A1, 3) self.assertEqual(sheet.A2, 11) self.assertEqual(sheet.A3, 44) @@ -537,8 +558,8 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.A12, 85) self.assertEqual(sheet.A13, 8) self.assertEqual(sheet.A14, 3) - self.assertEqual(sheet.A15, 8.0/3) - self.assertEqual(sheet.A16, 1.0/6) + self.assertEqual(sheet.A15, 8.0 / 3) + self.assertEqual(sheet.A16, 1.0 / 6) self.assertEqual(sheet.A17, 6561) self.assertEqual(sheet.A18, 43046721) self.assertEqual(sheet.A19, 6561) @@ -551,9 +572,9 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.A26, 24) self.assertEqual(sheet.A27, 24) self.assertEqual(sheet.A28, 24) - self.assertEqual(sheet.A29, 3.0/8) - self.assertEqual(sheet.A30, 3.0/2) - self.assertEqual(sheet.A31, 3.0/8) + self.assertEqual(sheet.A29, 3.0 / 8) + self.assertEqual(sheet.A30, 3.0 / 2) + self.assertEqual(sheet.A31, 3.0 / 8) self.assertEqual(sheet.A37, 1) self.assertEqual(sheet.A38, 1) self.assertEqual(sheet.A39, 2) @@ -571,81 +592,84 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.A51, 0) self.assertEqual(sheet.A52, -2) self.assertEqual(sheet.A53, 50) - self.assertEqual(sheet.A54, Units.Quantity('9.7mm')) - self.assertEqual(sheet.getContents('A1'), '=1 < 2 ? 3 : 4') - self.assertEqual(sheet.getContents('A2'), '=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8') - self.assertEqual(sheet.getContents('A3'), '=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3') - self.assertEqual(sheet.getContents('A4'), '123') - self.assertEqual(sheet.getContents('A5'), '=123 + 321') - self.assertEqual(sheet.getContents('A6'), '=123 * 2 + 321') - self.assertEqual(sheet.getContents('A7'), '=123 * 2 + 333 / 3') - self.assertEqual(sheet.getContents('A8'), '=123 * (2 + 321)') - self.assertEqual(sheet.getContents('A9'), '=3 ^ 4') - self.assertEqual(sheet.getContents('A10'), '=3 ^ 4 * 2') - self.assertEqual(sheet.getContents('A11'), '=3 ^ (4 * 2)') - self.assertEqual(sheet.getContents('A12'), '=3 ^ 4 + 4') - self.assertEqual(sheet.getContents('A13'), '=1 + 4 / 2 + 5') - self.assertEqual(sheet.getContents('A14'), '=(3 + 6) / (1 + 2)') - self.assertEqual(sheet.getContents('A15'), '=1 * 2 / 3 * 4') - self.assertEqual(sheet.getContents('A16'), '=1 * 2 / (3 * 4)') - self.assertEqual(sheet.getContents('A17'), '=3 ^ 4 ^ 2') - self.assertEqual(sheet.getContents('A18'), '=3 ^ (4 ^ 2)') - self.assertEqual(sheet.getContents('A19'), '=3 ^ 4 ^ 2') - self.assertEqual(sheet.getContents('A20'), '=3 + 4 + 2') - self.assertEqual(sheet.getContents('A21'), '=3 + 4 + 2') - self.assertEqual(sheet.getContents('A22'), '=3 + 4 + 2') - self.assertEqual(sheet.getContents('A23'), '=3 - 4 - 2') - self.assertEqual(sheet.getContents('A24'), '=3 - (4 - 2)') - self.assertEqual(sheet.getContents('A25'), '=3 - 4 - 2') - self.assertEqual(sheet.getContents('A26'), '=3 * 4 * 2') - self.assertEqual(sheet.getContents('A27'), '=3 * 4 * 2') - self.assertEqual(sheet.getContents('A28'), '=3 * 4 * 2') - self.assertEqual(sheet.getContents('A29'), '=3 / 4 / 2') - self.assertEqual(sheet.getContents('A30'), '=3 / (4 / 2)') - self.assertEqual(sheet.getContents('A31'), '=3 / 4 / 2') - self.assertEqual(sheet.getContents('A32'), '=pi * 3') - self.assertEqual(sheet.getContents('A33'), '=A32 / 3') - self.assertEqual(sheet.getContents('A34'), '=1 < 2 ? <> : <>') - self.assertEqual(sheet.getContents('A35'), '=min(A32:A33)') - self.assertEqual(sheet.getContents('A36'), '=(1 < 2 ? 0 : 1) * 3') - self.assertEqual(sheet.getContents('A37'), '=8 / (2 ^ 2 * 2)') - self.assertEqual(sheet.getContents('A38'), '=2 ^ 2 * 2 / 8') - self.assertEqual(sheet.getContents('A39'), '=2 ^ (2 * 2) / 8') - self.assertEqual(sheet.getContents('A40'), '=8 / 2 ^ (2 * 2)') - self.assertEqual(sheet.getContents('A41'), '=-1') - self.assertEqual(sheet.getContents('A42'), '=-1') - self.assertEqual(sheet.getContents('A43'), '=-(1 + 1)') - self.assertEqual(sheet.getContents('A44'), '=-(1 - 1)') - self.assertEqual(sheet.getContents('A45'), '=-(-1 + 1)') - self.assertEqual(sheet.getContents('A46'), '=-(-1 + -1)') - self.assertEqual(sheet.getContents('A47'), '=+1') - self.assertEqual(sheet.getContents('A48'), '=+1') - self.assertEqual(sheet.getContents('A49'), '=+(1 + 1)') - self.assertEqual(sheet.getContents('A50'), '=+(1 - 1)') - self.assertEqual(sheet.getContents('A51'), '=+(-1 + 1)') - self.assertEqual(sheet.getContents('A52'), '=+(-1 + -1)') + self.assertEqual(sheet.A54, Units.Quantity("9.7mm")) + self.assertEqual(sheet.getContents("A1"), "=1 < 2 ? 3 : 4") + self.assertEqual(sheet.getContents("A2"), "=1 + 2 < 3 + 4 ? 5 + 6 : 7 + 8") + self.assertEqual( + sheet.getContents("A3"), + "=1 + 2 * 1 < 3 + 4 ? 5 * 2 + 6 * 3 + 2 ^ 4 : 7 * 2 + 8 * 3 + 2 ^ 3", + ) + self.assertEqual(sheet.getContents("A4"), "123") + self.assertEqual(sheet.getContents("A5"), "=123 + 321") + self.assertEqual(sheet.getContents("A6"), "=123 * 2 + 321") + self.assertEqual(sheet.getContents("A7"), "=123 * 2 + 333 / 3") + self.assertEqual(sheet.getContents("A8"), "=123 * (2 + 321)") + self.assertEqual(sheet.getContents("A9"), "=3 ^ 4") + self.assertEqual(sheet.getContents("A10"), "=3 ^ 4 * 2") + self.assertEqual(sheet.getContents("A11"), "=3 ^ (4 * 2)") + self.assertEqual(sheet.getContents("A12"), "=3 ^ 4 + 4") + self.assertEqual(sheet.getContents("A13"), "=1 + 4 / 2 + 5") + self.assertEqual(sheet.getContents("A14"), "=(3 + 6) / (1 + 2)") + self.assertEqual(sheet.getContents("A15"), "=1 * 2 / 3 * 4") + self.assertEqual(sheet.getContents("A16"), "=1 * 2 / (3 * 4)") + self.assertEqual(sheet.getContents("A17"), "=3 ^ 4 ^ 2") + self.assertEqual(sheet.getContents("A18"), "=3 ^ (4 ^ 2)") + self.assertEqual(sheet.getContents("A19"), "=3 ^ 4 ^ 2") + self.assertEqual(sheet.getContents("A20"), "=3 + 4 + 2") + self.assertEqual(sheet.getContents("A21"), "=3 + 4 + 2") + self.assertEqual(sheet.getContents("A22"), "=3 + 4 + 2") + self.assertEqual(sheet.getContents("A23"), "=3 - 4 - 2") + self.assertEqual(sheet.getContents("A24"), "=3 - (4 - 2)") + self.assertEqual(sheet.getContents("A25"), "=3 - 4 - 2") + self.assertEqual(sheet.getContents("A26"), "=3 * 4 * 2") + self.assertEqual(sheet.getContents("A27"), "=3 * 4 * 2") + self.assertEqual(sheet.getContents("A28"), "=3 * 4 * 2") + self.assertEqual(sheet.getContents("A29"), "=3 / 4 / 2") + self.assertEqual(sheet.getContents("A30"), "=3 / (4 / 2)") + self.assertEqual(sheet.getContents("A31"), "=3 / 4 / 2") + self.assertEqual(sheet.getContents("A32"), "=pi * 3") + self.assertEqual(sheet.getContents("A33"), "=A32 / 3") + self.assertEqual(sheet.getContents("A34"), "=1 < 2 ? <> : <>") + self.assertEqual(sheet.getContents("A35"), "=min(A32:A33)") + self.assertEqual(sheet.getContents("A36"), "=(1 < 2 ? 0 : 1) * 3") + self.assertEqual(sheet.getContents("A37"), "=8 / (2 ^ 2 * 2)") + self.assertEqual(sheet.getContents("A38"), "=2 ^ 2 * 2 / 8") + self.assertEqual(sheet.getContents("A39"), "=2 ^ (2 * 2) / 8") + self.assertEqual(sheet.getContents("A40"), "=8 / 2 ^ (2 * 2)") + self.assertEqual(sheet.getContents("A41"), "=-1") + self.assertEqual(sheet.getContents("A42"), "=-1") + self.assertEqual(sheet.getContents("A43"), "=-(1 + 1)") + self.assertEqual(sheet.getContents("A44"), "=-(1 - 1)") + self.assertEqual(sheet.getContents("A45"), "=-(-1 + 1)") + self.assertEqual(sheet.getContents("A46"), "=-(-1 + -1)") + self.assertEqual(sheet.getContents("A47"), "=+1") + self.assertEqual(sheet.getContents("A48"), "=+1") + self.assertEqual(sheet.getContents("A49"), "=+(1 + 1)") + self.assertEqual(sheet.getContents("A50"), "=+(1 - 1)") + self.assertEqual(sheet.getContents("A51"), "=+(-1 + 1)") + self.assertEqual(sheet.getContents("A52"), "=+(-1 + -1)") def testNumbers(self): - """ Test different numbers """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '1') - sheet.set('A2', '1.5') - sheet.set('A3', '.5') - sheet.set('A4', '1e2') - sheet.set('A5', '1E2') - sheet.set('A6', '1e-2') - sheet.set('A7', '1E-2') - sheet.set('A8', '1.5e2') - sheet.set('A9', '1.5E2') - sheet.set('A10', '1.5e-2') - sheet.set('A11', '1.5E-2') - sheet.set('A12', '.5e2') - sheet.set('A13', '.5E2') - sheet.set('A14', '.5e-2') - sheet.set('A15', '.5E-2') - sheet.set('A16', '1/1') - sheet.set('A17', '1/2') - sheet.set('A18', '2/4') + """Test different numbers""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "1") + sheet.set("A2", "1.5") + sheet.set("A3", ".5") + sheet.set("A4", "1e2") + sheet.set("A5", "1E2") + sheet.set("A6", "1e-2") + sheet.set("A7", "1E-2") + sheet.set("A8", "1.5e2") + sheet.set("A9", "1.5E2") + sheet.set("A10", "1.5e-2") + sheet.set("A11", "1.5E-2") + sheet.set("A12", ".5e2") + sheet.set("A13", ".5E2") + sheet.set("A14", ".5e-2") + sheet.set("A15", ".5E-2") + sheet.set("A16", "1/1") + sheet.set("A17", "1/2") + sheet.set("A18", "2/4") self.doc.recompute() self.assertEqual(sheet.A1, 1) self.assertEqual(sheet.A2, 1.5) @@ -667,364 +691,390 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.A18, 0.5) def testQuantitiesAndFractionsAsNumbers(self): - """ Test quantities and simple fractions as numbers """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '1mm') - sheet.set('A2', '1/2') - sheet.set('A3', '4mm/2') - sheet.set('A4', '2/mm') - sheet.set('A5', '4/2mm') - sheet.set('A6', '6mm/3s') + """Test quantities and simple fractions as numbers""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "1mm") + sheet.set("A2", "1/2") + sheet.set("A3", "4mm/2") + sheet.set("A4", "2/mm") + sheet.set("A5", "4/2mm") + sheet.set("A6", "6mm/3s") self.doc.recompute() - self.assertEqual(sheet.A1, Units.Quantity('1 mm')) + self.assertEqual(sheet.A1, Units.Quantity("1 mm")) self.assertEqual(sheet.A2, 0.5) - self.assertEqual(sheet.A3, Units.Quantity('2 mm')) - self.assertEqual(sheet.A4, Units.Quantity('2 1/mm')) - self.assertEqual(sheet.A5, Units.Quantity('2 1/mm')) - self.assertEqual(sheet.A6, Units.Quantity('2 mm/s')) + self.assertEqual(sheet.A3, Units.Quantity("2 mm")) + self.assertEqual(sheet.A4, Units.Quantity("2 1/mm")) + self.assertEqual(sheet.A5, Units.Quantity("2 1/mm")) + self.assertEqual(sheet.A6, Units.Quantity("2 mm/s")) def testRemoveRows(self): - """ Removing rows -- check renaming of internal cells """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A3', '123') - sheet.set('A1', '=A3') - sheet.removeRows('2', 1) - self.assertEqual(sheet.getContents("A1"),"=A2") + """Removing rows -- check renaming of internal cells""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A3", "123") + sheet.set("A1", "=A3") + sheet.removeRows("2", 1) + self.assertEqual(sheet.getContents("A1"), "=A2") def testInsertRows(self): - """ Inserting rows -- check renaming of internal cells """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('B1', '=B2') - sheet.set('B2', '124') + """Inserting rows -- check renaming of internal cells""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("B1", "=B2") + sheet.set("B2", "124") # Calling getContents() here activates ObjectIdentifier internal cache, # which needs to be tested as well. - self.assertEqual(sheet.getContents("B1"),"=B2") - sheet.insertRows('2', 1) - self.assertEqual(sheet.getContents("B1"),"=B3") + self.assertEqual(sheet.getContents("B1"), "=B2") + sheet.insertRows("2", 1) + self.assertEqual(sheet.getContents("B1"), "=B3") def testIssue3225(self): - """ Inserting rows -- check renaming of internal cells """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('B2', '25') - sheet.set('B3', '=B2') - sheet.insertRows('2', 1) - self.assertEqual(sheet.getContents("B4"),"=B3") + """Inserting rows -- check renaming of internal cells""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("B2", "25") + sheet.set("B3", "=B2") + sheet.insertRows("2", 1) + self.assertEqual(sheet.getContents("B4"), "=B3") def testRenameAlias(self): - """ Test renaming of alias1 to alias2 in a spreadsheet """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('B1', '124') - sheet.setAlias('B1', 'alias1') - sheet.set('B2', '=alias1') + """Test renaming of alias1 to alias2 in a spreadsheet""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("B1", "124") + sheet.setAlias("B1", "alias1") + sheet.set("B2", "=alias1") self.doc.recompute() self.assertEqual(sheet.get("alias1"), 124) self.assertEqual(sheet.get("B1"), 124) self.assertEqual(sheet.get("B2"), 124) - sheet.setAlias('B1', 'alias2') + sheet.setAlias("B1", "alias2") self.doc.recompute() self.assertEqual(sheet.get("alias2"), 124) - self.assertEqual(sheet.getContents("B2"),"=alias2") + self.assertEqual(sheet.getContents("B2"), "=alias2") def testRenameAlias2(self): - """ Test renaming of alias1 to alias2 in a spreadsheet, when referenced from another object """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('B1', '124') - sheet.setAlias('B1', 'alias1') - box = self.doc.addObject('Part::Box', 'Box') - box.setExpression('Length', 'Spreadsheet.alias1') - sheet.setAlias('B1', 'alias2') - self.assertEqual(box.ExpressionEngine[0][1], "Spreadsheet.alias2"); + """Test renaming of alias1 to alias2 in a spreadsheet, when referenced from another object""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("B1", "124") + sheet.setAlias("B1", "alias1") + box = self.doc.addObject("Part::Box", "Box") + box.setExpression("Length", "Spreadsheet.alias1") + sheet.setAlias("B1", "alias2") + self.assertEqual(box.ExpressionEngine[0][1], "Spreadsheet.alias2") def testRenameAlias3(self): - """ Test renaming of document object referenced from another object """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('B1', '124') - sheet.setAlias('B1', 'alias1') - box = self.doc.addObject('Part::Box', 'Box') - box.setExpression('Length', 'Spreadsheet.alias1') - box2 = self.doc.addObject('Part::Box', 'Box') - box2.setExpression('Length', '<>.alias1') + """Test renaming of document object referenced from another object""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("B1", "124") + sheet.setAlias("B1", "alias1") + box = self.doc.addObject("Part::Box", "Box") + box.setExpression("Length", "Spreadsheet.alias1") + box2 = self.doc.addObject("Part::Box", "Box") + box2.setExpression("Length", "<>.alias1") sheet.Label = "Params" - self.assertEqual(box.ExpressionEngine[0][1], "Spreadsheet.alias1"); - self.assertEqual(box2.ExpressionEngine[0][1], "<>.alias1"); + self.assertEqual(box.ExpressionEngine[0][1], "Spreadsheet.alias1") + self.assertEqual(box2.ExpressionEngine[0][1], "<>.alias1") def testAlias(self): - """ Playing with aliases """ - sheet = self.doc.addObject("Spreadsheet::Sheet","Calc") - sheet.setAlias("A1","Test") - self.assertEqual(sheet.getAlias("A1"),"Test") + """Playing with aliases""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Calc") + sheet.setAlias("A1", "Test") + self.assertEqual(sheet.getAlias("A1"), "Test") - sheet.set("A1","4711") + sheet.set("A1", "4711") self.doc.recompute() - self.assertEqual(sheet.get("Test"),4711) - self.assertEqual(sheet.get("Test"),sheet.get("A1")) + self.assertEqual(sheet.get("Test"), 4711) + self.assertEqual(sheet.get("Test"), sheet.get("A1")) def testAmbiguousAlias(self): - """ Try to set the same alias twice (bug #2402) """ - sheet = self.doc.addObject("Spreadsheet::Sheet","Calc") - sheet.setAlias("A1","Test") + """Try to set the same alias twice (bug #2402)""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Calc") + sheet.setAlias("A1", "Test") try: - sheet.setAlias("A2","Test") + sheet.setAlias("A2", "Test") self.fail("An ambiguous alias was set which shouldn't be allowed") except Exception: - self.assertEqual(sheet.getAlias("A2"),None) + self.assertEqual(sheet.getAlias("A2"), None) def testClearAlias(self): - """ This was causing a crash """ - sheet = self.doc.addObject("Spreadsheet::Sheet","Calc") - sheet.setAlias("A1","Test") - sheet.setAlias("A1","") - self.assertEqual(sheet.getAlias("A1"),None) + """This was causing a crash""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Calc") + sheet.setAlias("A1", "Test") + sheet.setAlias("A1", "") + self.assertEqual(sheet.getAlias("A1"), None) def testSetInvalidAlias(self): - """ Try to use a cell address as alias name """ - sheet = self.doc.addObject("Spreadsheet::Sheet","Calc") + """Try to use a cell address as alias name""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Calc") try: - sheet.setAlias("A1","B1") + sheet.setAlias("A1", "B1") except Exception: - self.assertEqual(sheet.getAlias("A1"),None) + self.assertEqual(sheet.getAlias("A1"), None) else: self.fail("A cell address was used as alias which shouldn't be allowed") def testSetInvalidAlias2(self): - """ Try to use a unit (reserved word) as alias name """ - sheet = self.doc.addObject("Spreadsheet::Sheet","Calc") + """Try to use a unit (reserved word) as alias name""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Calc") try: - sheet.setAlias("A1","mA") + sheet.setAlias("A1", "mA") except Exception: self.assertEqual(sheet.getAlias("A1"), None) else: self.fail("A unit (reserved word) was used as alias which shouldn't be allowed") def testPlacementName(self): - """ Object name is equal to property name (bug #2389) """ + """Object name is equal to property name (bug #2389)""" if not FreeCAD.GuiUp: return import FreeCADGui - o = self.doc.addObject("Part::FeaturePython","Placement") + + o = self.doc.addObject("Part::FeaturePython", "Placement") FreeCADGui.Selection.addSelection(o) def testInvoluteGear(self): - """ Support of boolean or integer values """ + """Support of boolean or integer values""" try: import InvoluteGearFeature except ImportError: return - InvoluteGearFeature.makeInvoluteGear('InvoluteGear') + InvoluteGearFeature.makeInvoluteGear("InvoluteGear") self.doc.recompute() - sketch=self.doc.addObject('Sketcher::SketchObject','Sketch') - sketch.addGeometry(Part.LineSegment(v(0,0,0),v(10,10,0)),False) - sketch.addConstraint(Sketcher.Constraint('Distance',0,65.285388)) - sketch.setExpression('Constraints[0]', 'InvoluteGear.NumberOfTeeth') + sketch = self.doc.addObject("Sketcher::SketchObject", "Sketch") + sketch.addGeometry(Part.LineSegment(v(0, 0, 0), v(10, 10, 0)), False) + sketch.addConstraint(Sketcher.Constraint("Distance", 0, 65.285388)) + sketch.setExpression("Constraints[0]", "InvoluteGear.NumberOfTeeth") self.doc.recompute() - self.assertIn('Up-to-date',sketch.State) + self.assertIn("Up-to-date", sketch.State) def testSketcher(self): - """ Mixup of Label and Name (bug #2407)""" - sketch=self.doc.addObject('Sketcher::SketchObject','Sketch') - sheet=self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.setAlias('A1', 'Length') + """Mixup of Label and Name (bug #2407)""" + sketch = self.doc.addObject("Sketcher::SketchObject", "Sketch") + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.setAlias("A1", "Length") self.doc.recompute() - sheet.set('A1', '47,11') + sheet.set("A1", "47,11") self.doc.recompute() - index=sketch.addGeometry(Part.LineSegment(v(0,0,0),v(10,10,0)),False) - sketch.addConstraint(Sketcher.Constraint('Distance',index,14.0)) + index = sketch.addGeometry(Part.LineSegment(v(0, 0, 0), v(10, 10, 0)), False) + sketch.addConstraint(Sketcher.Constraint("Distance", index, 14.0)) self.doc.recompute() - sketch.setExpression('Constraints[0]', u'<>.Length') + sketch.setExpression("Constraints[0]", "<>.Length") self.doc.recompute() - sheet.Label="Calc" + sheet.Label = "Calc" self.doc.recompute() - self.assertEqual(sketch.ExpressionEngine[0][1],'<>.Length') - self.assertIn('Up-to-date',sketch.State) + self.assertEqual(sketch.ExpressionEngine[0][1], "<>.Length") + self.assertIn("Up-to-date", sketch.State) def testCrossDocumentLinks(self): - """ Expressions across files are not saved (bug #2442) """ + """Expressions across files are not saved (bug #2442)""" # Create a box - box = self.doc.addObject('Part::Box', 'Box') + box = self.doc.addObject("Part::Box", "Box") # Create a second document with a cylinder doc2 = FreeCAD.newDocument() - cylinder = doc2.addObject('Part::Cylinder', 'Cylinder') - cylinder.setExpression('Radius', 'cube#Cube.Height') + cylinder = doc2.addObject("Part::Cylinder", "Cylinder") + cylinder.setExpression("Radius", "cube#Cube.Height") # Save and close first document - self.doc.saveAs(self.TempPath + os.sep + 'cube.fcstd') + self.doc.saveAs(self.TempPath + os.sep + "cube.fcstd") FreeCAD.closeDocument(self.doc.Name) # Save and close second document - doc2.saveAs(self.TempPath + os.sep + 'cylinder.fcstd') + doc2.saveAs(self.TempPath + os.sep + "cylinder.fcstd") FreeCAD.closeDocument(doc2.Name) # Open both documents again - self.doc = FreeCAD.openDocument(self.TempPath + os.sep + 'cube.fcstd') - doc2 = FreeCAD.openDocument(self.TempPath + os.sep + 'cylinder.fcstd') + self.doc = FreeCAD.openDocument(self.TempPath + os.sep + "cube.fcstd") + doc2 = FreeCAD.openDocument(self.TempPath + os.sep + "cylinder.fcstd") # Check reference between them - self.assertEqual(doc2.getObject('Cylinder').ExpressionEngine[0][1], 'cube#Cube.Height') + self.assertEqual(doc2.getObject("Cylinder").ExpressionEngine[0][1], "cube#Cube.Height") # Close second document FreeCAD.closeDocument(doc2.Name) def testMatrix(self): - ''' Test Matrix/Vector/Placement/Rotation operations''' + """Test Matrix/Vector/Placement/Rotation operations""" def plm_equal(plm1, plm2): from math import sqrt - qpair = zip(plm1.Rotation.Q, plm2.Rotation.Q) - qdiff1 = sqrt(sum([(v1 - v2)**2 for v1,v2 in qpair])) - qdiff2 = sqrt(sum([(v1 + v2)**2 for v1,v2 in qpair])) - return (plm1.Base-plm2.Base).Length < 1e-7 and (qdiff1 < 1e-12 or dqiff2 < 1e-12) - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + qpair = zip(plm1.Rotation.Q, plm2.Rotation.Q) + qdiff1 = sqrt(sum([(v1 - v2) ** 2 for v1, v2 in qpair])) + qdiff2 = sqrt(sum([(v1 + v2) ** 2 for v1, v2 in qpair])) + return (plm1.Base - plm2.Base).Length < 1e-7 and (qdiff1 < 1e-12 or dqiff2 < 1e-12) + + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") mat = FreeCAD.Matrix() - mat.scale(2,1,2) + mat.scale(2, 1, 2) imat = mat.inverse() - vec = FreeCAD.Vector(2,1,2) + vec = FreeCAD.Vector(2, 1, 2) - rot = FreeCAD.Rotation(FreeCAD.Vector(0,1,0),45) + rot = FreeCAD.Rotation(FreeCAD.Vector(0, 1, 0), 45) irot = rot.inverted() - pla = FreeCAD.Placement(vec,rot) + pla = FreeCAD.Placement(vec, rot) ipla = pla.inverse() - sheet.set('A1', '=vector(2, 1, 2)') + sheet.set("A1", "=vector(2, 1, 2)") # different ways of calling mscale() - sheet.set('B1', '=mscale(create(<>), A1)') - sheet.set('C1', '=mscale(create(<>), tuple(2, 1, 2))') - sheet.set('A2', '=mscale(create(<>), 2, 1, 2)') + sheet.set("B1", "=mscale(create(<>), A1)") + sheet.set("C1", "=mscale(create(<>), tuple(2, 1, 2))") + sheet.set("A2", "=mscale(create(<>), 2, 1, 2)") # test matrix power operation - sheet.set('B2', '=A2^-2') - sheet.set('C2', '=A2^-1') - sheet.set('D2', '=A2^0') - sheet.set('E2', '=A2^1') - sheet.set('F2', '=A2^2') - sheet.set('G2', '=matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)') - sheet.set('H2', '=G2^-1') + sheet.set("B2", "=A2^-2") + sheet.set("C2", "=A2^-1") + sheet.set("D2", "=A2^0") + sheet.set("E2", "=A2^1") + sheet.set("F2", "=A2^2") + sheet.set("G2", "=matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)") + sheet.set("H2", "=G2^-1") - sheet.set('A3', '=rotation(vector(0, 1, 0), 45)') + sheet.set("A3", "=rotation(vector(0, 1, 0), 45)") # test rotation power operation - sheet.set('B3', '=A3^-2') - sheet.set('C3', '=A3^-1') - sheet.set('D3', '=A3^0') - sheet.set('E3', '=A3^1') - sheet.set('F3', '=A3^2') + sheet.set("B3", "=A3^-2") + sheet.set("C3", "=A3^-1") + sheet.set("D3", "=A3^0") + sheet.set("E3", "=A3^1") + sheet.set("F3", "=A3^2") - sheet.set('A4', '=placement(A1, A3)') + sheet.set("A4", "=placement(A1, A3)") # test placement power operation - sheet.set('B4', '=A4^-2') - sheet.set('C4', '=A4^-1') - sheet.set('D4', '=A4^0') - sheet.set('E4', '=A4^1') - sheet.set('F4', '=A4^2') + sheet.set("B4", "=A4^-2") + sheet.set("C4", "=A4^-1") + sheet.set("D4", "=A4^0") + sheet.set("E4", "=A4^1") + sheet.set("F4", "=A4^2") # vector transformation with mixing matrix and placement and rotation - sheet.set('A5', '=A2*A3*A4*A1') - sheet.set('B5', '=B2*B4*B3*A1') - sheet.set('C5', '=C3*C2*C4*A1') - sheet.set('D5', '=D3*D4*D2*A1') - sheet.set('E5', '=E4*E2*E3*A1') - sheet.set('F5', '=F3*F4*F2*A1') + sheet.set("A5", "=A2*A3*A4*A1") + sheet.set("B5", "=B2*B4*B3*A1") + sheet.set("C5", "=C3*C2*C4*A1") + sheet.set("D5", "=D3*D4*D2*A1") + sheet.set("E5", "=E4*E2*E3*A1") + sheet.set("F5", "=F3*F4*F2*A1") # inverse of the above transformation with power -1 and minvert() - sheet.set('A6', '=A4^-1 * minvert(A3) * A2^-1 * A5') - sheet.set('B6', '=minvert(B3) * B4^-1 * minvert(B2) * B5') - sheet.set('C6', '=C4^-1 * C2^-1 * C3^-1 * C5') - sheet.set('D6', '=minvert(D4*D2) * minvert(D3) * D5') - sheet.set('E6', '=(E2 * E3)^-1 * E4^-1 * E5') - sheet.set('F6', '=(F3*F4*F2)^-1 * F5') + sheet.set("A6", "=A4^-1 * minvert(A3) * A2^-1 * A5") + sheet.set("B6", "=minvert(B3) * B4^-1 * minvert(B2) * B5") + sheet.set("C6", "=C4^-1 * C2^-1 * C3^-1 * C5") + sheet.set("D6", "=minvert(D4*D2) * minvert(D3) * D5") + sheet.set("E6", "=(E2 * E3)^-1 * E4^-1 * E5") + sheet.set("F6", "=(F3*F4*F2)^-1 * F5") # Rotate and translate. - sheet.set('A7', '=placement(vector(1; 2; 3), vector(1; 0; 0); 0)') - sheet.set('B7', '=mrotate(A7; vector(1; 0; 0); 90)') - sheet.set('C7', '=mrotatex(A7; 90)') - sheet.set('D7', '=mrotatey(A7; 90)') - sheet.set('E7', '=mrotatez(A7; 90)') - sheet.set('F7', '=mtranslate(A7; vector(1; 2; 3))') - sheet.set('G7', '=mtranslate(A7; 1; 2; 3)') + sheet.set("A7", "=placement(vector(1; 2; 3), vector(1; 0; 0); 0)") + sheet.set("B7", "=mrotate(A7; vector(1; 0; 0); 90)") + sheet.set("C7", "=mrotatex(A7; 90)") + sheet.set("D7", "=mrotatey(A7; 90)") + sheet.set("E7", "=mrotatez(A7; 90)") + sheet.set("F7", "=mtranslate(A7; vector(1; 2; 3))") + sheet.set("G7", "=mtranslate(A7; 1; 2; 3)") # Compatibility with old syntax. - sheet.set('A8', '=create(<>, 2, 1, 2)') - sheet.set('B8', '=create(<>, create(<>, 0, 1, 0), 45)') - sheet.set('C8', '=create(<>, A8, B8)') + sheet.set("A8", "=create(<>, 2, 1, 2)") + sheet.set("B8", "=create(<>, create(<>, 0, 1, 0), 45)") + sheet.set("C8", "=create(<>, A8, B8)") self.doc.recompute() - self.assertEqual(sheet.A1,vec) + self.assertEqual(sheet.A1, vec) - self.assertEqual(sheet.B1,mat) - self.assertEqual(sheet.C1,mat) - self.assertEqual(sheet.A2,mat) + self.assertEqual(sheet.B1, mat) + self.assertEqual(sheet.C1, mat) + self.assertEqual(sheet.A2, mat) - self.assertEqual(sheet.B2,imat*imat) - self.assertEqual(sheet.B2,mat**-2) - self.assertEqual(sheet.C2,imat) - self.assertEqual(sheet.C2,mat**-1) - self.assertEqual(sheet.D2,FreeCAD.Matrix()) - self.assertEqual(sheet.D2,mat**0) - self.assertEqual(sheet.E2,mat) - self.assertEqual(sheet.E2,mat**1) - self.assertEqual(sheet.F2,mat*mat) - self.assertEqual(sheet.F2,mat**2) + self.assertEqual(sheet.B2, imat * imat) + self.assertEqual(sheet.B2, mat**-2) + self.assertEqual(sheet.C2, imat) + self.assertEqual(sheet.C2, mat**-1) + self.assertEqual(sheet.D2, FreeCAD.Matrix()) + self.assertEqual(sheet.D2, mat**0) + self.assertEqual(sheet.E2, mat) + self.assertEqual(sheet.E2, mat**1) + self.assertEqual(sheet.F2, mat * mat) + self.assertEqual(sheet.F2, mat**2) - self.assertTrue(sheet.H2.startswith(u'ERR: Cannot invert singular matrix')) + self.assertTrue(sheet.H2.startswith("ERR: Cannot invert singular matrix")) - self.assertEqual(sheet.A3,rot) + self.assertEqual(sheet.A3, rot) rtol = 1e-12 - self.assertTrue(sheet.B3.isSame(irot*irot,rtol)) - self.assertTrue(sheet.B3.isSame(rot**-2,rtol)) - self.assertTrue(sheet.C3.isSame(irot,rtol)) - self.assertTrue(sheet.C3.isSame(rot**-1,rtol)) - self.assertTrue(sheet.D3.isSame(FreeCAD.Rotation(),rtol)) - self.assertTrue(sheet.D3.isSame(rot**0,rtol)) - self.assertTrue(sheet.E3.isSame(rot,rtol)) - self.assertTrue(sheet.E3.isSame(rot**1,rtol)) - self.assertTrue(sheet.F3.isSame(rot*rot,rtol)) - self.assertTrue(sheet.F3.isSame(rot**2,rtol)) + self.assertTrue(sheet.B3.isSame(irot * irot, rtol)) + self.assertTrue(sheet.B3.isSame(rot**-2, rtol)) + self.assertTrue(sheet.C3.isSame(irot, rtol)) + self.assertTrue(sheet.C3.isSame(rot**-1, rtol)) + self.assertTrue(sheet.D3.isSame(FreeCAD.Rotation(), rtol)) + self.assertTrue(sheet.D3.isSame(rot**0, rtol)) + self.assertTrue(sheet.E3.isSame(rot, rtol)) + self.assertTrue(sheet.E3.isSame(rot**1, rtol)) + self.assertTrue(sheet.F3.isSame(rot * rot, rtol)) + self.assertTrue(sheet.F3.isSame(rot**2, rtol)) - self.assertEqual(sheet.A4,pla) + self.assertEqual(sheet.A4, pla) - self.assertTrue(plm_equal(sheet.B4,ipla*ipla)) - self.assertTrue(plm_equal(sheet.B4,pla**-2)) - self.assertTrue(plm_equal(sheet.C4,ipla)) - self.assertTrue(plm_equal(sheet.C4,pla**-1)) - self.assertTrue(plm_equal(sheet.D4,FreeCAD.Placement())) - self.assertTrue(plm_equal(sheet.D4,pla**0)) - self.assertTrue(plm_equal(sheet.E4,pla)) - self.assertTrue(plm_equal(sheet.E4,pla**1)) - self.assertTrue(plm_equal(sheet.F4,pla*pla)) - self.assertTrue(plm_equal(sheet.F4,pla**2)) + self.assertTrue(plm_equal(sheet.B4, ipla * ipla)) + self.assertTrue(plm_equal(sheet.B4, pla**-2)) + self.assertTrue(plm_equal(sheet.C4, ipla)) + self.assertTrue(plm_equal(sheet.C4, pla**-1)) + self.assertTrue(plm_equal(sheet.D4, FreeCAD.Placement())) + self.assertTrue(plm_equal(sheet.D4, pla**0)) + self.assertTrue(plm_equal(sheet.E4, pla)) + self.assertTrue(plm_equal(sheet.E4, pla**1)) + self.assertTrue(plm_equal(sheet.F4, pla * pla)) + self.assertTrue(plm_equal(sheet.F4, pla**2)) tol = 1e-10 - self.assertLess(sheet.A5.distanceToPoint( - sheet.A2.multiply(sheet.A3.Matrix).multiply(sheet.A4.Matrix).multVec(vec)),tol) - self.assertLess(sheet.B5.distanceToPoint( - sheet.B2.multiply(sheet.B4.Matrix).multiply(sheet.B3.Matrix).multVec(vec)),tol) - self.assertLess(sheet.C5.distanceToPoint( - sheet.C3.Matrix.multiply(sheet.C2).multiply(sheet.C4.Matrix).multVec(vec)),tol) - self.assertLess(sheet.D5.distanceToPoint( - sheet.D3.Matrix.multiply(sheet.D4.Matrix).multiply(sheet.D2).multVec(vec)),tol) - self.assertLess(sheet.E5.distanceToPoint( - sheet.E4.Matrix.multiply(sheet.E2).multiply(sheet.E3.Matrix).multVec(vec)),tol) - self.assertLess(sheet.F5.distanceToPoint( - sheet.F3.Matrix.multiply(sheet.F4.Matrix).multiply(sheet.F2).multVec(vec)),tol) + self.assertLess( + sheet.A5.distanceToPoint( + sheet.A2.multiply(sheet.A3.Matrix).multiply(sheet.A4.Matrix).multVec(vec) + ), + tol, + ) + self.assertLess( + sheet.B5.distanceToPoint( + sheet.B2.multiply(sheet.B4.Matrix).multiply(sheet.B3.Matrix).multVec(vec) + ), + tol, + ) + self.assertLess( + sheet.C5.distanceToPoint( + sheet.C3.Matrix.multiply(sheet.C2).multiply(sheet.C4.Matrix).multVec(vec) + ), + tol, + ) + self.assertLess( + sheet.D5.distanceToPoint( + sheet.D3.Matrix.multiply(sheet.D4.Matrix).multiply(sheet.D2).multVec(vec) + ), + tol, + ) + self.assertLess( + sheet.E5.distanceToPoint( + sheet.E4.Matrix.multiply(sheet.E2).multiply(sheet.E3.Matrix).multVec(vec) + ), + tol, + ) + self.assertLess( + sheet.F5.distanceToPoint( + sheet.F3.Matrix.multiply(sheet.F4.Matrix).multiply(sheet.F2).multVec(vec) + ), + tol, + ) - self.assertLess(sheet.A6.distanceToPoint(vec),tol) - self.assertLess(sheet.B6.distanceToPoint(vec),tol) - self.assertLess(sheet.C6.distanceToPoint(vec),tol) - self.assertLess(sheet.D6.distanceToPoint(vec),tol) - self.assertLess(sheet.E6.distanceToPoint(vec),tol) - self.assertLess(sheet.F6.distanceToPoint(vec),tol) + self.assertLess(sheet.A6.distanceToPoint(vec), tol) + self.assertLess(sheet.B6.distanceToPoint(vec), tol) + self.assertLess(sheet.C6.distanceToPoint(vec), tol) + self.assertLess(sheet.D6.distanceToPoint(vec), tol) + self.assertLess(sheet.E6.distanceToPoint(vec), tol) + self.assertLess(sheet.F6.distanceToPoint(vec), tol) self.assertTrue(sheet.A7.Base.isEqual(FreeCAD.Vector(1, 2, 3), tol)) self.assertTrue(sheet.B7.Base.isEqual(FreeCAD.Vector(1, -3, 2), tol)) @@ -1039,154 +1089,154 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.C8, pla) def testIssue3128(self): - """ Regression test for issue 3128; mod should work with arbitrary units for both arguments """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '=mod(7mm;3mm)') - sheet.set('A2', '=mod(7kg;3mm)') + """Regression test for issue 3128; mod should work with arbitrary units for both arguments""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "=mod(7mm;3mm)") + sheet.set("A2", "=mod(7kg;3mm)") self.doc.recompute() - self.assertEqual(sheet.A1, Units.Quantity('1')) - self.assertEqual(sheet.A2, Units.Quantity('1 kg/mm')) + self.assertEqual(sheet.A1, Units.Quantity("1")) + self.assertEqual(sheet.A2, Units.Quantity("1 kg/mm")) def testIssue3363(self): - """ Regression test for issue 3363; Nested conditionals statement fails with additional conditional statement in false-branch""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '1') - sheet.set('B1', '=A1==1?11:(A1==2?12:13)') - sheet.set('C1', '=A1==1?(A1==2?12:13) : 11') + """Regression test for issue 3363; Nested conditionals statement fails with additional conditional statement in false-branch""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "1") + sheet.set("B1", "=A1==1?11:(A1==2?12:13)") + sheet.set("C1", "=A1==1?(A1==2?12:13) : 11") self.doc.recompute() # Save and close first document - self.doc.saveAs(self.TempPath + os.sep + 'conditionals.fcstd') + self.doc.saveAs(self.TempPath + os.sep + "conditionals.fcstd") FreeCAD.closeDocument(self.doc.Name) # Open documents again - self.doc = FreeCAD.openDocument(self.TempPath + os.sep + 'conditionals.fcstd') + self.doc = FreeCAD.openDocument(self.TempPath + os.sep + "conditionals.fcstd") - sheet = self.doc.getObject('Spreadsheet') - self.assertEqual(sheet.getContents('B1'), '=A1 == 1 ? 11 : (A1 == 2 ? 12 : 13)') - self.assertEqual(sheet.getContents('C1'), '=A1 == 1 ? (A1 == 2 ? 12 : 13) : 11') + sheet = self.doc.getObject("Spreadsheet") + self.assertEqual(sheet.getContents("B1"), "=A1 == 1 ? 11 : (A1 == 2 ? 12 : 13)") + self.assertEqual(sheet.getContents("C1"), "=A1 == 1 ? (A1 == 2 ? 12 : 13) : 11") def testIssue3432(self): - """ Regression test for issue 3432; numbers with units are ignored from aggregates""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '1mm') - sheet.set('B1', '2mm') - sheet.set('C1', '=max(A1:B1;3mm)') + """Regression test for issue 3432; numbers with units are ignored from aggregates""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "1mm") + sheet.set("B1", "2mm") + sheet.set("C1", "=max(A1:B1;3mm)") self.doc.recompute() - self.assertEqual(sheet.get('C1'), Units.Quantity('3 mm')) + self.assertEqual(sheet.get("C1"), Units.Quantity("3 mm")) def testIssue4156(self): - """ Regression test for issue 4156; necessarily use of leading '=' to enter an expression, creates inconsistent behavior depending on the spreadsheet state""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A3', 'A1') - sheet.set('A1', '1000') + """Regression test for issue 4156; necessarily use of leading '=' to enter an expression, creates inconsistent behavior depending on the spreadsheet state""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A3", "A1") + sheet.set("A1", "1000") self.doc.recompute() - sheet.set('A3', '') - sheet.set('A3', 'A1') - self.assertEqual(sheet.getContents('A3'), '\'A1') + sheet.set("A3", "") + sheet.set("A3", "A1") + self.assertEqual(sheet.getContents("A3"), "'A1") def testInsertRowsAlias(self): - """ Regression test for issue 4429; insert rows to sheet with aliases""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A3', '1') - sheet.setAlias('A3', 'alias1') - sheet.set('A4', '=alias1 + 1') - sheet.setAlias('A4', 'alias2') - sheet.set('A5', '=alias2 + 1') + """Regression test for issue 4429; insert rows to sheet with aliases""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A3", "1") + sheet.setAlias("A3", "alias1") + sheet.set("A4", "=alias1 + 1") + sheet.setAlias("A4", "alias2") + sheet.set("A5", "=alias2 + 1") self.doc.recompute() - sheet.insertRows('1', 1) + sheet.insertRows("1", 1) self.doc.recompute() self.assertEqual(sheet.A6, 3) def testInsertColumnsAlias(self): - """ Regression test for issue 4429; insert columns to sheet with aliases""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('C1', '1') - sheet.setAlias('C1', 'alias1') - sheet.set('D1', '=alias1 + 1') - sheet.setAlias('D1', 'alias2') - sheet.set('E1', '=alias2 + 1') + """Regression test for issue 4429; insert columns to sheet with aliases""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("C1", "1") + sheet.setAlias("C1", "alias1") + sheet.set("D1", "=alias1 + 1") + sheet.setAlias("D1", "alias2") + sheet.set("E1", "=alias2 + 1") self.doc.recompute() - sheet.insertColumns('A', 1) + sheet.insertColumns("A", 1) self.doc.recompute() self.assertEqual(sheet.F1, 3) def testRemoveRowsAlias(self): - """ Regression test for issue 4429; remove rows from sheet with aliases""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A3', '1') - sheet.setAlias('A3', 'alias1') - sheet.set('A5', '=alias1 + 1') - sheet.setAlias('A5', 'alias2') - sheet.set('A4', '=alias2 + 1') + """Regression test for issue 4429; remove rows from sheet with aliases""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A3", "1") + sheet.setAlias("A3", "alias1") + sheet.set("A5", "=alias1 + 1") + sheet.setAlias("A5", "alias2") + sheet.set("A4", "=alias2 + 1") self.doc.recompute() - sheet.removeRows('1', 1) + sheet.removeRows("1", 1) self.doc.recompute() self.assertEqual(sheet.A3, 3) def testRemoveRowsAliasReuseName(self): - """ Regression test for issue 4492; deleted aliases remains in database""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.setAlias('B2', 'test') + """Regression test for issue 4492; deleted aliases remains in database""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.setAlias("B2", "test") self.doc.recompute() - sheet.removeRows('2', 1) - sheet.setAlias('B3','test') + sheet.removeRows("2", 1) + sheet.setAlias("B3", "test") def testRemoveColumnsAlias(self): - """ Regression test for issue 4429; remove columns from sheet with aliases""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('C1', '1') - sheet.setAlias('C1', 'alias1') - sheet.set('E1', '=alias1 + 1') - sheet.setAlias('E1', 'alias2') - sheet.set('D1', '=alias2 + 1') + """Regression test for issue 4429; remove columns from sheet with aliases""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("C1", "1") + sheet.setAlias("C1", "alias1") + sheet.set("E1", "=alias1 + 1") + sheet.setAlias("E1", "alias2") + sheet.set("D1", "=alias2 + 1") self.doc.recompute() - sheet.removeColumns('A', 1) + sheet.removeColumns("A", 1) self.doc.recompute() self.assertEqual(sheet.C1, 3) def testRemoveColumnsAliasReuseName(self): - """ Regression test for issue 4492; deleted aliases remains in database""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.setAlias('B2', 'test') + """Regression test for issue 4492; deleted aliases remains in database""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.setAlias("B2", "test") self.doc.recompute() - sheet.removeColumns('B', 1) - sheet.setAlias('C3','test') + sheet.removeColumns("B", 1) + sheet.setAlias("C3", "test") def testUndoAliasCreationReuseName(self): - """ Test deleted aliases by undo remains in database""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + """Test deleted aliases by undo remains in database""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") self.doc.UndoMode = 1 self.doc.openTransaction("create alias") - sheet.setAlias('B2', 'test') + sheet.setAlias("B2", "test") self.doc.commitTransaction() self.doc.recompute() self.doc.undo() self.doc.recompute() - sheet.setAlias('C3','test') + sheet.setAlias("C3", "test") def testCrossLinkEmptyPropertyName(self): # https://forum.freecad.org/viewtopic.php?f=3&t=58603 base = FreeCAD.newDocument("base") - sheet = base.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.setAlias('A1', 'x') - sheet.set('x', '42mm') + sheet = base.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.setAlias("A1", "x") + sheet.set("x", "42mm") base.recompute() square = FreeCAD.newDocument("square") - body = square.addObject('PartDesign::Body','Body') - box = square.addObject('PartDesign::AdditiveBox','Box') + body = square.addObject("PartDesign::Body", "Body") + box = square.addObject("PartDesign::AdditiveBox", "Box") body.addObject(box) box.Length = 10.00 box.Width = 10.00 box.Height = 10.00 square.recompute() - basePath = self.TempPath + os.sep + 'base.FCStd' + basePath = self.TempPath + os.sep + "base.FCStd" base.saveAs(basePath) - squarePath = self.TempPath + os.sep + 'square.FCStd' + squarePath = self.TempPath + os.sep + "square.FCStd" square.saveAs(squarePath) base.save() @@ -1200,7 +1250,7 @@ class SpreadsheetCases(unittest.TestCase): base = FreeCAD.openDocument(basePath) square = FreeCAD.openDocument(squarePath) - square.Box.setExpression('Length', u'base#Spreadsheet.x') + square.Box.setExpression("Length", "base#Spreadsheet.x") square.recompute() square.save() @@ -1211,17 +1261,17 @@ class SpreadsheetCases(unittest.TestCase): def testExpressionWithAlias(self): # https://forum.freecad.org/viewtopic.php?p=564502#p564502 ss1 = self.doc.addObject("Spreadsheet::Sheet", "Input") - ss1.setAlias('A1', 'one') - ss1.setAlias('A2', 'two') - ss1.set("A1","1") - ss1.set("A2","2") + ss1.setAlias("A1", "one") + ss1.setAlias("A2", "two") + ss1.set("A1", "1") + ss1.set("A2", "2") self.doc.recompute() ss2 = self.doc.addObject("Spreadsheet::Sheet", "Output") - ss2.set("A1","=Input.A1 + Input.A2") - ss2.set("A2","=Input.one + Input.two") - ss2.set("A3","=<>.A1 + <>.A2") - ss2.set("A4","=<>.one + <>.two") + ss2.set("A1", "=Input.A1 + Input.A2") + ss2.set("A2", "=Input.one + Input.two") + ss2.set("A3", "=<>.A1 + <>.A2") + ss2.set("A4", "=<>.one + <>.two") self.doc.recompute() self.assertEqual(ss2.get("A1"), 3) @@ -1229,7 +1279,7 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(ss2.get("A3"), 3) self.assertEqual(ss2.get("A4"), 3) - project_path = self.TempPath + os.sep + 'alias.FCStd' + project_path = self.TempPath + os.sep + "alias.FCStd" self.doc.saveAs(project_path) FreeCAD.closeDocument(self.doc.Name) self.doc = FreeCAD.openDocument(project_path) @@ -1241,7 +1291,7 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(ss2.get("A3"), 3) self.assertEqual(ss2.get("A4"), 3) - ss1.set("A1","2") + ss1.set("A1", "2") self.doc.recompute() self.assertEqual(ss1.get("A1"), 2) @@ -1264,7 +1314,10 @@ class SpreadsheetCases(unittest.TestCase): sheet.body = ["Item1", "Item2", "Item3"] sheet.setExpression(".body.Enum", "cells[<>]") - sheet.setExpression(".cells.Bind.B1.ZZ1", "tuple(.cells; <> + str(hiddenref(Body.Configuration) + 2); <> + str(hiddenref(Body.Configuration) + 2))") + sheet.setExpression( + ".cells.Bind.B1.ZZ1", + "tuple(.cells; <> + str(hiddenref(Body.Configuration) + 2); <> + str(hiddenref(Body.Configuration) + 2))", + ) self.doc.recompute() self.doc.UndoMode = 0 @@ -1283,7 +1336,10 @@ class SpreadsheetCases(unittest.TestCase): sheet.body = ["Item1", "Item2", "Item3"] sheet.setExpression(".body.Enum", "cells[<>]") - sheet.setExpression(".cells.Bind.B1.ZZ1", "tuple(.cells; <> + str(hiddenref(Body.Configuration) + 2); <> + str(hiddenref(Body.Configuration) + 2))") + sheet.setExpression( + ".cells.Bind.B1.ZZ1", + "tuple(.cells; <> + str(hiddenref(Body.Configuration) + 2); <> + str(hiddenref(Body.Configuration) + 2))", + ) self.doc.recompute() self.doc.clearDocument() @@ -1310,7 +1366,7 @@ class SpreadsheetCases(unittest.TestCase): ss2.set("D1", "D1") ss2.set("D2", "D2") - ss1.setExpression('.cells.Bind.A3.C4', 'tuple(Spreadsheet2.cells, <>, <>)') + ss1.setExpression(".cells.Bind.A3.C4", "tuple(Spreadsheet2.cells, <>, <>)") self.doc.recompute() self.assertEqual(ss1.A3, ss2.B1) @@ -1321,7 +1377,7 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(ss1.C4, ss2.D2) self.assertEqual(len(ss1.ExpressionEngine), 1) - ss1.setExpression('.cells.Bind.A3.C4', None) + ss1.setExpression(".cells.Bind.A3.C4", None) self.doc.recompute() def testBindHiddenRefAcrossSheets(self): @@ -1335,22 +1391,24 @@ class SpreadsheetCases(unittest.TestCase): ss2.set("D2", "D2") self.doc.recompute() - ss1.setExpression('.cells.Bind.A3.C4', None) - ss1.setExpression('.cells.BindHiddenRef.A3.C4', 'hiddenref(tuple(Spreadsheet2.cells, <>, <>))') + ss1.setExpression(".cells.Bind.A3.C4", None) + ss1.setExpression( + ".cells.BindHiddenRef.A3.C4", "hiddenref(tuple(Spreadsheet2.cells, <>, <>))" + ) self.doc.recompute() - ss1.recompute() # True + ss1.recompute() # True self.assertEqual(ss1.A3, ss2.B1) - ss1.setExpression('.cells.Bind.A3.C4', None) - ss1.setExpression('.cells.BindHiddenRef.A3.C4', None) + ss1.setExpression(".cells.Bind.A3.C4", None) + ss1.setExpression(".cells.BindHiddenRef.A3.C4", None) self.doc.recompute() self.assertEqual(len(ss1.ExpressionEngine), 0) def testMergeCells(self): ss1 = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet1") - ss1.mergeCells('A1:B4') - ss1.mergeCells('C1:D4') + ss1.mergeCells("A1:B4") + ss1.mergeCells("C1:D4") self.doc.recompute() ss1.set("B1", "fail") self.doc.recompute() @@ -1359,8 +1417,8 @@ class SpreadsheetCases(unittest.TestCase): def testMergeCellsAndBind(self): ss1 = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet1") - ss1.mergeCells('A1:B1') - ss1.setExpression('.cells.Bind.A1.A1', 'tuple(.cells, <>, <>)') + ss1.mergeCells("A1:B1") + ss1.setExpression(".cells.Bind.A1.A1", "tuple(.cells, <>, <>)") ss1.set("A2", "test") self.doc.recompute() self.assertEqual(ss1.A1, ss1.A2) @@ -1370,10 +1428,10 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(ss1.B1, "fail") def testGetUsedCells(self): - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - test_cells = ['B13','C14','D15'] - for i,cell in enumerate(test_cells): - sheet.set(cell,str(i)) + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + test_cells = ["B13", "C14", "D15"] + for i, cell in enumerate(test_cells): + sheet.set(cell, str(i)) used_cells = sheet.getUsedCells() self.assertEqual(len(used_cells), len(test_cells)) @@ -1381,30 +1439,30 @@ class SpreadsheetCases(unittest.TestCase): self.assertTrue(cell in used_cells) for cell in test_cells: - sheet.set(cell,"") - sheet.setAlignment(cell,"center") + sheet.set(cell, "") + sheet.setAlignment(cell, "center") non_empty_cells = sheet.getUsedCells() - self.assertEqual(len(non_empty_cells), len(test_cells)) # Alignment counts as "used" + self.assertEqual(len(non_empty_cells), len(test_cells)) # Alignment counts as "used" def testGetUsedRange(self): - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - test_cells = ['C5','Z3','D10','E20'] - for i,cell in enumerate(test_cells): - sheet.set(cell,str(i)) + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + test_cells = ["C5", "Z3", "D10", "E20"] + for i, cell in enumerate(test_cells): + sheet.set(cell, str(i)) used_range = sheet.getUsedRange() - self.assertEquals(used_range,("C3","Z20")) + self.assertEquals(used_range, ("C3", "Z20")) - for i,cell in enumerate(test_cells): - sheet.set(cell,"") - sheet.setAlignment(cell,"center") + for i, cell in enumerate(test_cells): + sheet.set(cell, "") + sheet.setAlignment(cell, "center") used_range = sheet.getUsedRange() - self.assertEquals(used_range,("C3","Z20")) + self.assertEquals(used_range, ("C3", "Z20")) def testGetNonEmptyCells(self): - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - test_cells = ['B13','C14','D15'] - for i,cell in enumerate(test_cells): - sheet.set(cell,str(i)) + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + test_cells = ["B13", "C14", "D15"] + for i, cell in enumerate(test_cells): + sheet.set(cell, str(i)) non_empty_cells = sheet.getNonEmptyCells() self.assertEqual(len(non_empty_cells), len(test_cells)) @@ -1412,80 +1470,80 @@ class SpreadsheetCases(unittest.TestCase): self.assertTrue(cell in non_empty_cells) for cell in test_cells: - sheet.set(cell,"") - sheet.setAlignment(cell,"center") + sheet.set(cell, "") + sheet.setAlignment(cell, "center") non_empty_cells = sheet.getNonEmptyCells() - self.assertEqual(len(non_empty_cells), 0) # Alignment does not count as "non-empty" + self.assertEqual(len(non_empty_cells), 0) # Alignment does not count as "non-empty" def testGetNonEmptyRange(self): - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - test_cells = ['C5','Z3','D10','E20'] - for i,cell in enumerate(test_cells): - sheet.set(cell,str(i)) + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + test_cells = ["C5", "Z3", "D10", "E20"] + for i, cell in enumerate(test_cells): + sheet.set(cell, str(i)) non_empty_range = sheet.getNonEmptyRange() - self.assertEquals(non_empty_range,("C3","Z20")) + self.assertEquals(non_empty_range, ("C3", "Z20")) - for i,cell in enumerate(test_cells): - sheet.set(cell,"") - sheet.setAlignment(cell,"center") - more_cells = ['D10','X5','E10','K15'] - for i,cell in enumerate(more_cells): - sheet.set(cell,str(i)) + for i, cell in enumerate(test_cells): + sheet.set(cell, "") + sheet.setAlignment(cell, "center") + more_cells = ["D10", "X5", "E10", "K15"] + for i, cell in enumerate(more_cells): + sheet.set(cell, str(i)) non_empty_range = sheet.getNonEmptyRange() - self.assertEquals(non_empty_range,("D5","X15")) + self.assertEquals(non_empty_range, ("D5", "X15")) def testAliasEmptyCell(self): # https://github.com/FreeCAD/FreeCAD/issues/7841 - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.setAlias('A1', 'aliasOfEmptyCell') - self.assertEqual(sheet.getCellFromAlias("aliasOfEmptyCell"),"A1") + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.setAlias("A1", "aliasOfEmptyCell") + self.assertEqual(sheet.getCellFromAlias("aliasOfEmptyCell"), "A1") def testParensAroundCondition(self): - """ Parens around a condition should be accepted """ - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + """Parens around a condition should be accepted""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") - sheet.set('A1', '=(1 == 1) ? 1 : 0') + sheet.set("A1", "=(1 == 1) ? 1 : 0") self.doc.recompute() - self.assertEqual(sheet.getContents('A1'), '=1 == 1 ? 1 : 0') + self.assertEqual(sheet.getContents("A1"), "=1 == 1 ? 1 : 0") self.assertEqual(sheet.A1, 1) def testIssue6395(self): - """ Testing strings are correctly saved and restored""" - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') - sheet.set('A1', '\'36C') # Use a string that may be parsed as a quantity + """Testing strings are correctly saved and restored""" + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") + sheet.set("A1", "'36C") # Use a string that may be parsed as a quantity self.doc.recompute() - self.doc.saveAs(self.TempPath + os.sep + 'string.fcstd') + self.doc.saveAs(self.TempPath + os.sep + "string.fcstd") FreeCAD.closeDocument(self.doc.Name) - self.doc = FreeCAD.openDocument(self.TempPath + os.sep + 'string.fcstd') + self.doc = FreeCAD.openDocument(self.TempPath + os.sep + "string.fcstd") - sheet = self.doc.getObject('Spreadsheet') - self.assertEqual(sheet.getContents('A1'), '\'36C') - self.assertEqual(sheet.get('A1'), '36C') + sheet = self.doc.getObject("Spreadsheet") + self.assertEqual(sheet.getContents("A1"), "'36C") + self.assertEqual(sheet.get("A1"), "36C") def testVectorFunctions(self): - sheet = self.doc.addObject('Spreadsheet::Sheet','Spreadsheet') + sheet = self.doc.addObject("Spreadsheet::Sheet", "Spreadsheet") - sheet.set('A1', '=vcross(vector(1; 2; 3); vector(1; 5; 7))') + sheet.set("A1", "=vcross(vector(1; 2; 3); vector(1; 5; 7))") - sheet.set('B1', '=vdot(vector(1; 2; 3); vector(4; -5; 6))') + sheet.set("B1", "=vdot(vector(1; 2; 3); vector(4; -5; 6))") - sheet.set('C1', '=vangle(vector(1; 0; 0); vector(0; 1; 0))') + sheet.set("C1", "=vangle(vector(1; 0; 0); vector(0; 1; 0))") - sheet.set('D1', '=vnormalize(vector(1; 0; 0))') - sheet.set('D2', '=vnormalize(vector(1; 1; 1))') + sheet.set("D1", "=vnormalize(vector(1; 0; 0))") + sheet.set("D2", "=vnormalize(vector(1; 1; 1))") - sheet.set('E1', '=vscale(vector(1; 2; 3); 2; 3; 4)') - sheet.set('E2', '=vscalex(vector(1; 2; 3); -2)') - sheet.set('E3', '=vscaley(vector(1; 2; 3); -2)') - sheet.set('E4', '=vscalez(vector(1; 2; 3); -2)') + sheet.set("E1", "=vscale(vector(1; 2; 3); 2; 3; 4)") + sheet.set("E2", "=vscalex(vector(1; 2; 3); -2)") + sheet.set("E3", "=vscaley(vector(1; 2; 3); -2)") + sheet.set("E4", "=vscalez(vector(1; 2; 3); -2)") - sheet.set('F1', '=vlinedist(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))') - sheet.set('F2', '=vlinesegdist(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))') - sheet.set('F3', '=vlineproj(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))') - sheet.set('F4', '=vplanedist(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))') - sheet.set('F5', '=vplaneproj(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))') + sheet.set("F1", "=vlinedist(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))") + sheet.set("F2", "=vlinesegdist(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))") + sheet.set("F3", "=vlineproj(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))") + sheet.set("F4", "=vplanedist(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))") + sheet.set("F5", "=vplaneproj(vector(1; 2; 3); vector(2; 3; 4); vector(3; 4; 5))") self.doc.recompute() @@ -1498,7 +1556,10 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.C1, 90) self.assertEqual(sheet.D1, FreeCAD.Vector(1, 0, 0)) - self.assertLess(sheet.D2.distanceToPoint(FreeCAD.Vector(1/sqrt(3), 1/sqrt(3), 1/sqrt(3))), tolerance) + self.assertLess( + sheet.D2.distanceToPoint(FreeCAD.Vector(1 / sqrt(3), 1 / sqrt(3), 1 / sqrt(3))), + tolerance, + ) self.assertEqual(sheet.E1, FreeCAD.Vector(2, 6, 12)) self.assertEqual(sheet.E2, FreeCAD.Vector(-2, 2, 3)) @@ -1512,5 +1573,5 @@ class SpreadsheetCases(unittest.TestCase): self.assertEqual(sheet.F5, FreeCAD.Vector(1.72, 2.96, 4.2)) def tearDown(self): - #closing doc + # closing doc FreeCAD.closeDocument(self.doc.Name) diff --git a/src/Mod/Spreadsheet/TestSpreadsheetGui.py b/src/Mod/Spreadsheet/TestSpreadsheetGui.py index 3278a1a8a4..156c031205 100644 --- a/src/Mod/Spreadsheet/TestSpreadsheetGui.py +++ b/src/Mod/Spreadsheet/TestSpreadsheetGui.py @@ -40,7 +40,7 @@ class SpreadsheetGuiCases(unittest.TestCase): def tearDown(self): pass - #FreeCAD.closeDocument(self.doc.Name) + # FreeCAD.closeDocument(self.doc.Name) def injectSimpleData(self): """A utility function to initialize a blank sheet with some known data""" diff --git a/src/Mod/Spreadsheet/importXLSX.py b/src/Mod/Spreadsheet/importXLSX.py index 0377cd1f62..6ed01a74b8 100644 --- a/src/Mod/Spreadsheet/importXLSX.py +++ b/src/Mod/Spreadsheet/importXLSX.py @@ -1,31 +1,31 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -#*************************************************************************** -#* Copyright (c) 2016 Ulrich Brammer * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU General Public License (GPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#***************************************************************************/ +# *************************************************************************** +# * Copyright (c) 2016 Ulrich Brammer * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU General Public License (GPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# ***************************************************************************/ -__title__ = "FreeCAD Spreadsheet Workbench - XLSX importer" +__title__ = "FreeCAD Spreadsheet Workbench - XLSX importer" __author__ = "Ulrich Brammer " -__url__ = ["https://www.freecad.org"] +__url__ = ["https://www.freecad.org"] -''' +""" This library imports an Excel-XLSX-file into FreeCAD. Version 1.1, Nov. 2016: @@ -49,18 +49,21 @@ Features: known issues: - units are not imported - string support is minimal, the same as in FreeCAD -''' +""" import zipfile import xml.dom.minidom import FreeCAD as App -try: import FreeCADGui -except ValueError: gui = False -else: gui = True +try: + import FreeCADGui +except ValueError: + gui = False +else: + gui = True -if open.__module__ in ['__builtin__','io']: +if open.__module__ in ["__builtin__", "io"]: pythonopen = open @@ -69,36 +72,30 @@ if open.__module__ in ['__builtin__','io']: # sepToken defines a search tree for separator tokens with length of 1 to 3 characters # it is also used as a list of separators between other tokens. sepToken = { - '(':None, - '=':None, - '<':'branchLower', - '>':'branchHigher', - ')':None, -# '"':None, -# ';':None, - ' ':None, - ',':None, # Separator on lists - '!':None, #Connector to cells on other Sheets - '+':None, - '-':None, - '*':None, - '/':None, - '^':None - } + "(": None, + "=": None, + "<": "branchLower", + ">": "branchHigher", + ")": None, + # '"':None, + # ';':None, + " ": None, + ",": None, # Separator on lists + "!": None, # Connector to cells on other Sheets + "+": None, + "-": None, + "*": None, + "/": None, + "^": None, +} -branchLower ={ - '>':None, - '=':None - } +branchLower = {">": None, "=": None} -branchHigher = {'=':None} +branchHigher = {"=": None} # Needed to get a reference from a string to a dict -treeDict = { - 'branchLower':branchLower, - 'branchHigher':branchHigher - } +treeDict = {"branchLower": branchLower, "branchHigher": branchHigher} # The tokenDic is used in parseExpr. # The tokenDic contains the following information: @@ -110,380 +107,377 @@ treeDict = { tokenDic = { - '(' :( 1, '(', 0), - '=' :( 0 ,'==', 0), - '<>' :( 0 ,'!=', 0), - '>=' :( 0 ,'>=', 0), - '<=' :( 0 ,'<=', 0), - '<' :( 0 ,'<', 0), - '>' :( 0 ,'>', 0), - ',' :( 0 ,',', 0), - ')' :(-1 ,')', 0), - '!' :( 0 ,'.', 0), #Connector to cells on other Sheets -# '"' :( 2 ,'', 0), - '+' :( 0 ,'+', 0), - '-' :( 0 ,'-', 0), - '*' :( 0 ,'*', 0), - '/' :( 0 ,'/', 0), - '^' :( 0 ,'^', 0), - 'IF' :( 0, '', 3), - 'ABS' :( 0, 'abs', 0), - 'ACOS' :( 0, 'pi/180deg*acos', 0), - 'ASIN' :( 0, 'pi/180deg*asin', 0), - 'ATAN' :( 0, 'pi/180deg*atan', 0), - 'ATAN2':( 0, 'pi/180deg*atan2',0), - 'COS' :( 0, 'cos', 2), - 'COSH' :( 0, 'cosh', 2), - 'EXP' :( 0, 'exp', 0), - 'LOG' :( 0, 'log', 0), - 'LOG10':( 0, 'log10',0), - 'MOD' :( 0, 'mod', 0), - 'POWER':( 0, 'pow', 0), - 'SIN' :( 0, 'sin', 2), - 'SINH' :( 0, 'sinh', 2), - 'SQRT' :( 0, 'sqrt', 0), - 'TAN' :( 0, 'tan', 2), - 'TANH' :( 0, 'tanh', 2), - 'AVERAGE':( 0, 'average', 0), - 'COUNT':( 0, 'count',0), - 'MAX' :( 0, 'max', 0), - 'MIN' :( 0, 'min', 0), - 'STDEVA':( 0, 'stddev',0), - 'SUM' :( 0, 'sum', 0), - 'PI' :( 0, 'pi', 1), - '_xlfn.CEILING.MATH':( 0, 'ceil', 0), - '_xlfn.FLOOR.MATH' :( 0, 'floor', 0) - } + "(": (1, "(", 0), + "=": (0, "==", 0), + "<>": (0, "!=", 0), + ">=": (0, ">=", 0), + "<=": (0, "<=", 0), + "<": (0, "<", 0), + ">": (0, ">", 0), + ",": (0, ",", 0), + ")": (-1, ")", 0), + "!": (0, ".", 0), # Connector to cells on other Sheets + # '"' :( 2 ,'', 0), + "+": (0, "+", 0), + "-": (0, "-", 0), + "*": (0, "*", 0), + "/": (0, "/", 0), + "^": (0, "^", 0), + "IF": (0, "", 3), + "ABS": (0, "abs", 0), + "ACOS": (0, "pi/180deg*acos", 0), + "ASIN": (0, "pi/180deg*asin", 0), + "ATAN": (0, "pi/180deg*atan", 0), + "ATAN2": (0, "pi/180deg*atan2", 0), + "COS": (0, "cos", 2), + "COSH": (0, "cosh", 2), + "EXP": (0, "exp", 0), + "LOG": (0, "log", 0), + "LOG10": (0, "log10", 0), + "MOD": (0, "mod", 0), + "POWER": (0, "pow", 0), + "SIN": (0, "sin", 2), + "SINH": (0, "sinh", 2), + "SQRT": (0, "sqrt", 0), + "TAN": (0, "tan", 2), + "TANH": (0, "tanh", 2), + "AVERAGE": (0, "average", 0), + "COUNT": (0, "count", 0), + "MAX": (0, "max", 0), + "MIN": (0, "min", 0), + "STDEVA": (0, "stddev", 0), + "SUM": (0, "sum", 0), + "PI": (0, "pi", 1), + "_xlfn.CEILING.MATH": (0, "ceil", 0), + "_xlfn.FLOOR.MATH": (0, "floor", 0), +} class exprNode(object): - ''' This defines a tree class for expression parsing. - A tree is built, to step down into the levels of the expression.''' - def __init__(self, parent, state, actIndex): - self.state = state #see comment: State used for Angle-functions and IF-function - self.parent = parent # Parent tree node - self.lIndex = actIndex # Index to the list of tokens - self.result = '' + """This defines a tree class for expression parsing. + A tree is built, to step down into the levels of the expression.""" + + def __init__(self, parent, state, actIndex): + self.state = state # see comment: State used for Angle-functions and IF-function + self.parent = parent # Parent tree node + self.lIndex = actIndex # Index to the list of tokens + self.result = "" class FormulaTranslator(object): - ''' This class translates a cell-formula from Excel to FreeCAD.''' - def __init__(self): - self.tokenList = ['='] + """This class translates a cell-formula from Excel to FreeCAD.""" - def translateForm(self, actExpr): - self.getNextToken(actExpr) - #print("tokenList: ", self.tokenList) - self.resultTree = exprNode(None, 0, 1) - self.resultTree.result = self.tokenList[0] - self.parseExpr(self.resultTree) - #print('parseResult: ', self.resultTree.result) - return self.resultTree.result + def __init__(self): + self.tokenList = ["="] - def getNextToken(self, theExpr): - ''' This is the recursive tokenizer for an excel formula. - It appends all identified tokens to self.tokenList.''' - #print('next Token theExpr: ', theExpr) - #print('actTList: ', self.tokenList) - tokenComplete = False - keyToken = False - if len(theExpr)>0: - theTok = theExpr[0] - theExpr = theExpr[1:] - if theTok in sepToken: - keyToken = True - branch = sepToken[theTok] - while branch: - #print(branch, ' theExpr[0]: ',theExpr[0]) - if theExpr[0] in treeDict[branch]: - branch = treeDict[branch][theExpr[0]] - theTok = theTok + theExpr[0] + def translateForm(self, actExpr): + self.getNextToken(actExpr) + # print("tokenList: ", self.tokenList) + self.resultTree = exprNode(None, 0, 1) + self.resultTree.result = self.tokenList[0] + self.parseExpr(self.resultTree) + # print('parseResult: ', self.resultTree.result) + return self.resultTree.result + + def getNextToken(self, theExpr): + """This is the recursive tokenizer for an excel formula. + It appends all identified tokens to self.tokenList.""" + # print('next Token theExpr: ', theExpr) + # print('actTList: ', self.tokenList) + tokenComplete = False + keyToken = False + if len(theExpr) > 0: + theTok = theExpr[0] theExpr = theExpr[1:] - else: - branch= None - tokenComplete = True - self.tokenList.append(theTok) - self.getNextToken(theExpr) - else: - if len(theExpr)>0: - while (not tokenComplete): - if not self.isKey(theExpr): - theTok = theTok + theExpr[0] - theExpr = theExpr[1:] - if len(theExpr) == 0: + if theTok in sepToken: + keyToken = True + branch = sepToken[theTok] + while branch: + # print(branch, ' theExpr[0]: ',theExpr[0]) + if theExpr[0] in treeDict[branch]: + branch = treeDict[branch][theExpr[0]] + theTok = theTok + theExpr[0] + theExpr = theExpr[1:] + else: + branch = None tokenComplete = True + self.tokenList.append(theTok) + self.getNextToken(theExpr) else: - tokenComplete = True - self.tokenList.append(theTok) - self.getNextToken(theExpr) + if len(theExpr) > 0: + while not tokenComplete: + if not self.isKey(theExpr): + theTok = theTok + theExpr[0] + theExpr = theExpr[1:] + if len(theExpr) == 0: + tokenComplete = True + else: + tokenComplete = True + self.tokenList.append(theTok) + self.getNextToken(theExpr) + def isKey(self, theExpr): + # print('look up: ', theExpr) + keyToken = False + lenExpr = len(theExpr) + if theExpr[0] in sepToken: + branch = sepToken[theExpr[0]] - def isKey(self, theExpr): - #print('look up: ', theExpr) - keyToken = False - lenExpr = len(theExpr) - if theExpr[0] in sepToken: - branch = sepToken[theExpr[0]] + if branch is None: + keyToken = True + else: + # print('There is a branch. look up: ', theExpr[1]) + if (lenExpr > 1) and (theExpr[1] in treeDict[branch]): + branch = treeDict[branch][theExpr[0]] + if branch is None: + keyToken = True + else: + if (lenExpr > 2) and (theExpr[2] in treeDict[branch]): + keyToken = True + else: + keyToken = True + return keyToken - if branch is None: - keyToken = True - else: - #print('There is a branch. look up: ', theExpr[1]) - if (lenExpr > 1) and (theExpr[1] in treeDict[branch]): - branch = treeDict[branch][theExpr[0]] - if branch is None: - keyToken = True - else: - if (lenExpr > 2) and (theExpr[2] in treeDict[branch]): - keyToken = True + def parseExpr(self, treeNode): + token = self.tokenList[treeNode.lIndex] + treeNode.lIndex += 1 + if token in tokenDic: + lChange, newToken, funcState = tokenDic[token] else: - keyToken = True - return keyToken + lChange = 0 + newToken = token + funcState = 0 + # print('treeNode.state: ', treeNode.state, ' my.index: ', treeNode.lIndex-1, ' ', token, ' fState: ', funcState) + if token == ",": + if treeNode.state == 4: + newToken = ":" + treeNode.state = 6 + if treeNode.state == 3: + newToken = "?" + treeNode.state = 4 + if funcState == 3: + funcState = 0 + newNode = exprNode(treeNode, 3, treeNode.lIndex) + self.parseIF(newNode) + else: + treeNode.result = treeNode.result + newToken - def parseExpr(self, treeNode): - token = self.tokenList[treeNode.lIndex] - treeNode.lIndex += 1 - if token in tokenDic: - lChange, newToken, funcState = tokenDic[token] - else: - lChange = 0 - newToken = token - funcState = 0 - #print('treeNode.state: ', treeNode.state, ' my.index: ', treeNode.lIndex-1, ' ', token, ' fState: ', funcState) + if funcState == 2: + funcState = 0 + newNode = exprNode(treeNode, 2, treeNode.lIndex) + self.parseAngle(newNode) + treeNode.result = treeNode.result + ")" + elif funcState == 1: + treeNode.lIndex += 2 # do skip the 2 parentheses of the PI() - if token == ',': - if (treeNode.state == 4): - newToken = ':' - treeNode.state = 6 - if (treeNode.state == 3): - newToken = '?' - treeNode.state = 4 + if lChange == -1: + # print 'state: ', treeNode.state, 'parent.result: ', treeNode.parent.result, ' mine: ', treeNode.result + treeNode.parent.result = treeNode.parent.result + treeNode.result + treeNode.parent.lIndex = treeNode.lIndex + # print('Go one level up, state: ', treeNode.state) + if treeNode.state < 2: + # print(' Look up more token above') + if treeNode.lIndex < len(self.tokenList): + self.parseExpr(treeNode.parent) - if funcState == 3: - funcState = 0 - newNode = exprNode(treeNode, 3, treeNode.lIndex) - self.parseIF(newNode) - else: - treeNode.result = treeNode.result + newToken + elif lChange == 1: + # print('Go one level down') + newNode = exprNode(treeNode, 1, treeNode.lIndex) + self.parseExpr(newNode) + treeNode.lIndex = newNode.lIndex + else: + if treeNode.lIndex < len(self.tokenList): + # print('parse to the end') + self.parseExpr(treeNode) - if funcState == 2: - funcState = 0 - newNode = exprNode(treeNode, 2, treeNode.lIndex) - self.parseAngle(newNode) - treeNode.result = treeNode.result + ')' - elif funcState == 1: - treeNode.lIndex += 2 # do skip the 2 parentheses of the PI() - - if lChange == -1: - #print 'state: ', treeNode.state, 'parent.result: ', treeNode.parent.result, ' mine: ', treeNode.result - treeNode.parent.result = treeNode.parent.result + treeNode.result - treeNode.parent.lIndex = treeNode.lIndex - #print('Go one level up, state: ', treeNode.state) - if (treeNode.state < 2): - #print(' Look up more token above') - if treeNode.lIndex < len(self.tokenList): - self.parseExpr(treeNode.parent) - - elif lChange == 1: - #print('Go one level down') - newNode = exprNode(treeNode, 1, treeNode.lIndex) - self.parseExpr(newNode) - treeNode.lIndex = newNode.lIndex - else: - if treeNode.lIndex < len(self.tokenList): - #print('parse to the end') + def parseIF(self, treeNode): + # print('IF state: ', treeNode.state) + treeNode.result = treeNode.result + "(" + treeNode.lIndex += 1 self.parseExpr(treeNode) + # print('IF result: ', treeNode.result) + return - - - def parseIF(self, treeNode): - #print('IF state: ', treeNode.state) - treeNode.result = treeNode.result + '(' - treeNode.lIndex += 1 - self.parseExpr(treeNode) - #print('IF result: ', treeNode.result) - return - - def parseAngle(self, treeNode): - #print('Angle state: ', treeNode.state) - treeNode.result = treeNode.result + '(1rad*(' - treeNode.lIndex += 1 - self.parseExpr(treeNode) - #print('angle result: ', treeNode.result) - + def parseAngle(self, treeNode): + # print('Angle state: ', treeNode.state) + treeNode.result = treeNode.result + "(1rad*(" + treeNode.lIndex += 1 + self.parseExpr(treeNode) + # print('angle result: ', treeNode.result) def getText(nodelist): - rc = [] - for node in nodelist: - if node.nodeType == node.TEXT_NODE: - rc.append(node.data) - return ''.join(rc) + rc = [] + for node in nodelist: + if node.nodeType == node.TEXT_NODE: + rc.append(node.data) + return "".join(rc) def handleWorkSheet(theDom, actSheet, strList): - rows = theDom.getElementsByTagName("row") - for row in rows: - handleCells(row.getElementsByTagName("c"), actSheet, strList) + rows = theDom.getElementsByTagName("row") + for row in rows: + handleCells(row.getElementsByTagName("c"), actSheet, strList) def handleCells(cellList, actCellSheet, sList): - for cell in cellList: - cellAtts = cell.attributes - refRef = cellAtts.getNamedItem("r") - ref = getText(refRef.childNodes) + for cell in cellList: + cellAtts = cell.attributes + refRef = cellAtts.getNamedItem("r") + ref = getText(refRef.childNodes) - refType = cellAtts.getNamedItem("t") - if refType: - cellType = getText(refType.childNodes) - else: - cellType = 'n' # FIXME: some cells don't have t and s attributes + refType = cellAtts.getNamedItem("t") + if refType: + cellType = getText(refType.childNodes) + else: + cellType = "n" # FIXME: some cells don't have t and s attributes - #print("reference: ", ref, ' Cell type: ', cellType) + # print("reference: ", ref, ' Cell type: ', cellType) - if cellType == 'inlineStr': - iStringList = cell.getElementsByTagName("is") - #print('iString: ', iStringList) - for stringEle in iStringList: - tElement = stringEle.getElementsByTagName('t')[0] - theString = getText(tElement.childNodes) + if cellType == "inlineStr": + iStringList = cell.getElementsByTagName("is") + # print('iString: ', iStringList) + for stringEle in iStringList: + tElement = stringEle.getElementsByTagName("t")[0] + theString = getText(tElement.childNodes) - #print('theString: ', theString) - actCellSheet.set(ref, theString) + # print('theString: ', theString) + actCellSheet.set(ref, theString) - formulaRef = cell.getElementsByTagName("f") - if len(formulaRef)==1: - theFormula = getText(formulaRef[0].childNodes) - #print("theFormula: ", theFormula) - fTrans = FormulaTranslator() - actCellSheet.set(ref, fTrans.translateForm(theFormula)) + formulaRef = cell.getElementsByTagName("f") + if len(formulaRef) == 1: + theFormula = getText(formulaRef[0].childNodes) + # print("theFormula: ", theFormula) + fTrans = FormulaTranslator() + actCellSheet.set(ref, fTrans.translateForm(theFormula)) - else: - valueRef = cell.getElementsByTagName("v") - #print('valueRef: ', valueRef) - if len(valueRef)==1: - valueRef = cell.getElementsByTagName("v")[0] - if valueRef: - theValue = getText(valueRef.childNodes) - #print("theValue: ", theValue) - if cellType == 'n': - actCellSheet.set(ref, theValue) - if cellType == 's': - actCellSheet.set(ref, (sList[int(theValue)])) + else: + valueRef = cell.getElementsByTagName("v") + # print('valueRef: ', valueRef) + if len(valueRef) == 1: + valueRef = cell.getElementsByTagName("v")[0] + if valueRef: + theValue = getText(valueRef.childNodes) + # print("theValue: ", theValue) + if cellType == "n": + actCellSheet.set(ref, theValue) + if cellType == "s": + actCellSheet.set(ref, (sList[int(theValue)])) def handleWorkBook(theBook, sheetDict, Doc): - theSheets = theBook.getElementsByTagName("sheet") - #print("theSheets: ", theSheets) - for sheet in theSheets: - sheetAtts = sheet.attributes - nameRef = sheetAtts.getNamedItem("name") - sheetName = getText(nameRef.childNodes) - #print("table name: ", sheetName) - idRef = sheetAtts.getNamedItem("sheetId") - sheetFile = "sheet" + getText(idRef.childNodes) + '.xml' - #print("sheetFile: ", sheetFile) - # add FreeCAD-spreadsheet - sheetDict[sheetName] = (Doc.addObject('Spreadsheet::Sheet', sheetName), sheetFile) + theSheets = theBook.getElementsByTagName("sheet") + # print("theSheets: ", theSheets) + for sheet in theSheets: + sheetAtts = sheet.attributes + nameRef = sheetAtts.getNamedItem("name") + sheetName = getText(nameRef.childNodes) + # print("table name: ", sheetName) + idRef = sheetAtts.getNamedItem("sheetId") + sheetFile = "sheet" + getText(idRef.childNodes) + ".xml" + # print("sheetFile: ", sheetFile) + # add FreeCAD-spreadsheet + sheetDict[sheetName] = (Doc.addObject("Spreadsheet::Sheet", sheetName), sheetFile) - theAliases = theBook.getElementsByTagName("definedName") - for theAlias in theAliases: - aliAtts = theAlias.attributes - nameRef = aliAtts.getNamedItem("name") - aliasName = getText(nameRef.childNodes) - #print("aliasName: ", aliasName) + theAliases = theBook.getElementsByTagName("definedName") + for theAlias in theAliases: + aliAtts = theAlias.attributes + nameRef = aliAtts.getNamedItem("name") + aliasName = getText(nameRef.childNodes) + # print("aliasName: ", aliasName) + + aliasRef = getText(theAlias.childNodes) # aliasRef can be None + if aliasRef and "$" in aliasRef: + refList = aliasRef.split("!$") + adressList = refList[1].split("$") + # print("aliasRef: ", aliasRef) + # print('Sheet Name: ', refList[0]) + # print('Adress: ', adressList[0] + adressList[1]) + actSheet, sheetFile = sheetDict[refList[0]] + actSheet.setAlias(adressList[0] + adressList[1], aliasName) - aliasRef = getText(theAlias.childNodes) # aliasRef can be None - if aliasRef and '$' in aliasRef: - refList = aliasRef.split('!$') - adressList = refList[1].split('$') - #print("aliasRef: ", aliasRef) - #print('Sheet Name: ', refList[0]) - #print('Adress: ', adressList[0] + adressList[1]) - actSheet, sheetFile = sheetDict[refList[0]] - actSheet.setAlias(adressList[0]+adressList[1], aliasName) def handleStrings(theStr, sList): - print('process Strings: ') - stringElements = theStr.getElementsByTagName('t') - for sElem in stringElements: - print('string: ', getText(sElem.childNodes)) - sList.append(getText(sElem.childNodes)) + print("process Strings: ") + stringElements = theStr.getElementsByTagName("t") + for sElem in stringElements: + print("string: ", getText(sElem.childNodes)) + sList.append(getText(sElem.childNodes)) + def open(nameXLSX): - if len(nameXLSX) > 0: - z=zipfile.ZipFile(nameXLSX) + if len(nameXLSX) > 0: + z = zipfile.ZipFile(nameXLSX) - theDoc = App.newDocument() + theDoc = App.newDocument() + + sheetDict = dict() + stringList = [] + + theBookFile = z.open("xl/workbook.xml") + theBook = xml.dom.minidom.parse(theBookFile) + handleWorkBook(theBook, sheetDict, theDoc) + theBook.unlink() + + if "xl/sharedStrings.xml" in z.namelist(): + theStringFile = z.open("xl/sharedStrings.xml") + theStrings = xml.dom.minidom.parse(theStringFile) + handleStrings(theStrings, stringList) + theStrings.unlink() + + for sheetSpec in sheetDict: + # print("sheetSpec: ", sheetSpec) + theSheet, sheetFile = sheetDict[sheetSpec] + f = z.open("xl/worksheets/" + sheetFile) + myDom = xml.dom.minidom.parse(f) + + handleWorkSheet(myDom, theSheet, stringList) + myDom.unlink() + + z.close() + # This is needed more than once, otherwise some references are not calculated! + theDoc.recompute() + theDoc.recompute() + theDoc.recompute() + return theDoc + + +def insert(nameXLSX, docname): + try: + theDoc = App.getDocument(docname) + except NameError: + theDoc = App.newDocument(docname) + App.ActiveDocument = theDoc sheetDict = dict() stringList = [] - theBookFile=z.open('xl/workbook.xml') + z = zipfile.ZipFile(nameXLSX) + theBookFile = z.open("xl/workbook.xml") theBook = xml.dom.minidom.parse(theBookFile) handleWorkBook(theBook, sheetDict, theDoc) theBook.unlink() - if 'xl/sharedStrings.xml' in z.namelist(): - theStringFile=z.open('xl/sharedStrings.xml') - theStrings = xml.dom.minidom.parse(theStringFile) - handleStrings(theStrings, stringList) - theStrings.unlink() + if "xl/sharedStrings.xml" in z.namelist(): + theStringFile = z.open("xl/sharedStrings.xml") + theStrings = xml.dom.minidom.parse(theStringFile) + handleStrings(theStrings, stringList) + theStrings.unlink() for sheetSpec in sheetDict: - #print("sheetSpec: ", sheetSpec) - theSheet, sheetFile = sheetDict[sheetSpec] - f=z.open('xl/worksheets/' + sheetFile) - myDom = xml.dom.minidom.parse(f) + # print("sheetSpec: ", sheetSpec) + theSheet, sheetFile = sheetDict[sheetSpec] + f = z.open("xl/worksheets/" + sheetFile) + myDom = xml.dom.minidom.parse(f) - handleWorkSheet(myDom, theSheet, stringList) - myDom.unlink() + handleWorkSheet(myDom, theSheet, stringList) + myDom.unlink() z.close() # This is needed more than once, otherwise some references are not calculated! theDoc.recompute() theDoc.recompute() theDoc.recompute() - return theDoc - -def insert(nameXLSX,docname): - try: - theDoc=App.getDocument(docname) - except NameError: - theDoc=App.newDocument(docname) - App.ActiveDocument = theDoc - - sheetDict = dict() - stringList = [] - - z=zipfile.ZipFile(nameXLSX) - theBookFile=z.open('xl/workbook.xml') - theBook = xml.dom.minidom.parse(theBookFile) - handleWorkBook(theBook, sheetDict, theDoc) - theBook.unlink() - - if 'xl/sharedStrings.xml' in z.namelist(): - theStringFile=z.open('xl/sharedStrings.xml') - theStrings = xml.dom.minidom.parse(theStringFile) - handleStrings(theStrings, stringList) - theStrings.unlink() - - for sheetSpec in sheetDict: - #print("sheetSpec: ", sheetSpec) - theSheet, sheetFile = sheetDict[sheetSpec] - f=z.open('xl/worksheets/' + sheetFile) - myDom = xml.dom.minidom.parse(f) - - handleWorkSheet(myDom, theSheet, stringList) - myDom.unlink() - - z.close() - # This is needed more than once, otherwise some references are not calculated! - theDoc.recompute() - theDoc.recompute() - theDoc.recompute() - - diff --git a/src/Mod/Spreadsheet/spreadsheet.dox b/src/Mod/Spreadsheet/spreadsheet.dox index 75bd7cb3e7..740ef37b75 100644 --- a/src/Mod/Spreadsheet/spreadsheet.dox +++ b/src/Mod/Spreadsheet/spreadsheet.dox @@ -5,4 +5,3 @@ See \ref src/Mod/Draft/draft.dox as an example of how to populate this page */ -