Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/med.git] / src / MEDCoupling_Swig / MEDCouplingExamplesTest.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2012  CEA/DEN, EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 from MEDCoupling import *
22 import unittest
23
24 class MEDCouplingBasicsTest(unittest.TestCase):
25     def testExampleFieldDoubleBuildSubPart1(self):
26         from MEDCouplingDataForTest import MEDCouplingDataForTest
27 #! [PySnippetFieldDoubleBuildSubPart1_1]
28         mesh1=MEDCouplingDataForTest.build2DTargetMesh_1()
29         f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME)
30         f1.setTime(2.3,5,6)
31         f1.setMesh(mesh1)
32         array=DataArrayDouble.New()
33         arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.]
34         array.setValues(arr1,mesh1.getNumberOfCells(),2)
35         f1.setArray(array)
36 # ! [PySnippetFieldDoubleBuildSubPart1_1]
37 # ! [PySnippetFieldDoubleBuildSubPart1_2]
38         part1=[2,1,4]
39         f2=f1.buildSubPart(part1)
40 # ! [PySnippetFieldDoubleBuildSubPart1_2]
41         f2.zipCoords()
42         self.assertEqual(3,f2.getNumberOfTuples())
43         self.assertEqual(2,f2.getNumberOfComponents())
44         expected1=[5.,105.,4.,104.,7.,107.]
45         for i in xrange(6):
46             self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12)
47             pass
48         self.assertEqual(3,f2.getMesh().getNumberOfCells())
49         self.assertEqual(6,f2.getMesh().getNumberOfNodes())
50         self.assertEqual(2,f2.getMesh().getSpaceDimension())
51         self.assertEqual(2,f2.getMesh().getMeshDimension())
52         m2C=f2.getMesh()
53         self.assertEqual(13,m2C.getMeshLength())
54         expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7]
55         for i in xrange(12):
56             self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12)
57             pass
58         expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2]
59         self.assertEqual(expected3,list(m2C.getNodalConnectivity().getValues()))
60         expected4=[0,4,8,13]
61         self.assertEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues()))
62         # Test with field on nodes.
63 # ! [PySnippetFieldDoubleBuildSubPart1_3]
64         f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME)
65         f1.setTime(2.3,5,6)
66         f1.setMesh(mesh1)
67         array=DataArrayDouble.New()
68         arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.]
69         array.setValues(arr2,mesh1.getNumberOfNodes(),2)
70         f1.setArray(array)
71 # ! [PySnippetFieldDoubleBuildSubPart1_3]
72 # ! [PySnippetFieldDoubleBuildSubPart1_4]
73         part2=[1,2]
74         f2=f1.buildSubPart(part2)
75 # ! [PySnippetFieldDoubleBuildSubPart1_4]
76         self.assertEqual(4,f2.getNumberOfTuples())
77         self.assertEqual(2,f2.getNumberOfComponents())
78         expected5=[4.,104.,5.,105.,7.,107.,8.,108.]
79         for i in xrange(8):
80             self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12)
81             pass
82         self.assertEqual(2,f2.getMesh().getNumberOfCells())
83         self.assertEqual(4,f2.getMesh().getNumberOfNodes())
84         self.assertEqual(2,f2.getMesh().getSpaceDimension())
85         self.assertEqual(2,f2.getMesh().getMeshDimension())
86         m2C=f2.getMesh()
87         self.assertEqual(8,m2C.getMeshLength())
88         for i in xrange(8):#8 is not an error
89             self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12)
90             pass
91         self.assertEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:])
92         self.assertEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4])
93         self.assertEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues()))
94         #idem previous because nodes of cell#4 are not fully present in part3
95         part3=[1,2]
96         arrr=DataArrayInt.New()
97         arrr.setValues(part3,2,1)
98         f2=f1.buildSubPart(arrr)
99         self.assertEqual(4,f2.getNumberOfTuples())
100         self.assertEqual(2,f2.getNumberOfComponents())
101         for i in xrange(8):
102             self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12)
103             pass
104         self.assertEqual(2,f2.getMesh().getNumberOfCells())
105         self.assertEqual(4,f2.getMesh().getNumberOfNodes())
106         self.assertEqual(2,f2.getMesh().getSpaceDimension())
107         self.assertEqual(2,f2.getMesh().getMeshDimension())
108         m2C=f2.getMesh()
109         self.assertEqual(8,m2C.getMeshLength())
110         for i in xrange(8):#8 is not an error
111             self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12)
112             pass
113         self.assertEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:8])
114         self.assertEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4])
115         self.assertEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues()))
116         part4=[1,2,4]
117         f2=f1.buildSubPart(part4)
118         self.assertEqual(6,f2.getNumberOfTuples())
119         self.assertEqual(2,f2.getNumberOfComponents())
120         expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.]
121         for i in xrange(12):
122             self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12)
123             pass
124         self.assertEqual(3,f2.getMesh().getNumberOfCells())
125         self.assertEqual(6,f2.getMesh().getNumberOfNodes())
126         self.assertEqual(2,f2.getMesh().getSpaceDimension())
127         self.assertEqual(2,f2.getMesh().getMeshDimension())
128         m2C=f2.getMesh()
129         self.assertEqual(13,m2C.getMeshLength())
130         for i in xrange(12):
131             self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12)
132             pass
133         self.assertEqual(expected3[0:4],list(m2C.getNodalConnectivity().getValues())[4:8])
134         self.assertEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[0:4])
135         self.assertEqual(expected3[8:13],list(m2C.getNodalConnectivity().getValues())[8:13])
136         self.assertEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues()))
137         pass
138
139     def testExampleUMeshStdBuild1(self):
140 # ! [PySnippetUMeshStdBuild1_1]
141         coords=[-0.3,-0.3,0.,   0.2,-0.3,0.,   0.7,-0.3,0.,   -0.3,0.2,0.,   0.2,0.2,0., 
142                  0.7,0.2,0.,    -0.3,0.7,0.,    0.2,0.7,0.,     0.7,0.7,0. ]
143         nodalConnPerCell=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]
144 # ! [PySnippetUMeshStdBuild1_1]
145 # ! [PySnippetUMeshStdBuild1_2]
146         mesh=MEDCouplingUMesh.New("My2DMesh",2)
147 # ! [PySnippetUMeshStdBuild1_2]
148 # ! [PySnippetUMeshStdBuild1_3]
149         mesh.allocateCells(5)#You can put more than 5 if you want but not less.
150         mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[:4])
151         mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[4:7])
152         mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[7:10])
153         mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[10:14])
154         mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[14:])
155         mesh.finishInsertingCells()
156 # ! [PySnippetUMeshStdBuild1_3]
157 # ! [PySnippetUMeshStdBuild1_4]
158         myCoords=DataArrayDouble.New(coords,9,3)#here myCoords are declared to have 3 components, mesh will deduce that its spaceDim==3. 
159         mesh.setCoords(myCoords)#myCorrds contains 9 tuples, that is to say mesh contains 9 nodes.
160 # ! [PySnippetUMeshStdBuild1_4]
161 # ! [PySnippetUMeshStdBuild1_5]
162 # ! [PySnippetUMeshStdBuild1_5]
163         mesh.checkCoherency()
164         pass
165
166     def testExampleCMeshStdBuild1(self):
167 # ! [PySnippetCMeshStdBuild1_1]
168         XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] # 9 values along X
169         YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] # 7 values along Y
170         arrX=DataArrayDouble.New(XCoords)
171         arrX.setInfoOnComponent(0,"X [m]")
172         arrY=DataArrayDouble.New(YCoords)
173         arrY.setInfoOnComponent(0,"Y [m]")
174 # ! [PySnippetCMeshStdBuild1_1]
175 # ! [PySnippetCMeshStdBuild1_2]
176         mesh=MEDCouplingCMesh.New("My2D_CMesh")
177         mesh.setCoords(arrX,arrY)
178 # ! [PySnippetCMeshStdBuild1_2]
179 # ! [PySnippetCMeshStdBuild1_3]
180         self.assertEqual(8*6,mesh.getNumberOfCells())
181         self.assertEqual(9*7,mesh.getNumberOfNodes())
182         self.assertEqual(2,mesh.getSpaceDimension())
183         self.assertEqual(2,mesh.getMeshDimension())
184 # ! [PySnippetCMeshStdBuild1_3]
185         mesh=MEDCouplingCMesh.New("My2D_CMesh")
186 # ! [PySnippetCMeshStdBuild1_2bis]
187         mesh.setCoordsAt(0,arrX)
188         mesh.setCoordsAt(1,arrY)
189 # ! [PySnippetCMeshStdBuild1_2bis]
190         self.assertEqual(8*6,mesh.getNumberOfCells())
191         self.assertEqual(9*7,mesh.getNumberOfNodes())
192         self.assertEqual(2,mesh.getSpaceDimension())
193         self.assertEqual(2,mesh.getMeshDimension())
194         pass
195
196     def testExampleUMeshAdvBuild1(self):
197 # ! [PySnippetUMeshAdvBuild1_1]
198         coords=[-0.3,-0.3,0.,   0.2,-0.3,0.,   0.7,-0.3,0.,   -0.3,0.2,0.,   0.2,0.2,0., 
199                  0.7,0.2,0.,    -0.3,0.7,0.,    0.2,0.7,0.,     0.7,0.7,0. ]
200         nodalConnPerCell=[4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4]
201         nodalConnPerCellIndex=[0,5,9,13,18,23]
202 # ! [PySnippetUMeshAdvBuild1_1]
203 # ! [PySnippetUMeshAdvBuild1_2]
204         mesh=MEDCouplingUMesh.New("My2DMesh",2)
205 # ! [PySnippetUMeshAdvBuild1_2]
206 # ! [PySnippetUMeshAdvBuild1_3]
207         nodalConn=DataArrayInt.New(nodalConnPerCell,23,1)
208         nodalConnI=DataArrayInt.New(nodalConnPerCellIndex,6,1)
209         mesh.setConnectivity(nodalConn,nodalConnI,True)
210 # ! [PySnippetUMeshAdvBuild1_3]
211 # ! [PySnippetUMeshAdvBuild1_4]
212         myCoords=DataArrayDouble.New(coords,9,3)#here myCoords are declared to have 3 components, mesh will deduce that its spaceDim==3. 
213         mesh.setCoords(myCoords)#myCorrds contains 9 tuples, that is to say mesh contains 9 nodes.
214 # ! [PySnippetUMeshAdvBuild1_4]
215 # ! [PySnippetUMeshAdvBuild1_5]
216 # ! [PySnippetUMeshAdvBuild1_5]
217         mesh.checkCoherency()
218         pass
219
220     def testExampleDataArrayBuild1(self):
221 # ! [PySnippetDataArrayBuild1_0]
222         dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.]
223 # ! [PySnippetDataArrayBuild1_0]
224 # ! [PySnippetDataArrayBuild1_1]
225         arrayDouble=DataArrayDouble.New()
226         arrayDouble.setValues(dataDouble,5,3)# 5 tuples containing each 3 components
227 # ! [PySnippetDataArrayBuild1_1]
228 # ! [PySnippetDataArrayBuild1_1bis]
229         arrayDouble=DataArrayDouble.New(dataDouble,5,3)
230 # ! [PySnippetDataArrayBuild1_1bis]
231 # ! [PySnippetDataArrayBuild1_2]
232         dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24]
233 # ! [PySnippetDataArrayBuild1_2]
234 # ! [PySnippetDataArrayBuild1_3]
235         arrayInt=DataArrayInt.New()
236         arrayInt.setValues(dataInt,5,3)# 5 tuples containing each 3 components
237 # ! [PySnippetDataArrayBuild1_3]
238 # ! [PySnippetDataArrayBuild1_3bis]
239         arrayInt=DataArrayInt.New(dataInt,5,3)
240 # ! [PySnippetDataArrayBuild1_3bis]
241         pass
242
243     def testExampleFieldDoubleBuild1(self):
244         XCoords=[-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22] ; arrX=DataArrayDouble.New(XCoords)
245         YCoords=[0.07,0.1,0.37,0.45,0.47,0.49,1.007] ; arrY=DataArrayDouble.New(YCoords)
246         mesh=MEDCouplingCMesh.New("My2D_CMesh")
247         mesh.setCoords(arrX,arrY)
248 # ! [PySnippetFieldDoubleBuild1_1]
249         fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME)
250         fieldOnCells.setName("MyTensorFieldOnCellNoTime")
251         fieldOnCells.setMesh(mesh)
252         array=DataArrayDouble.New()
253         array.alloc(fieldOnCells.getMesh().getNumberOfCells(),9) # Implicitely fieldOnCells will be a 9 components field.
254         array.fillWithValue(7.)
255         fieldOnCells.setArray(array)
256         # fieldOnCells is now usable
257         # ...
258 # ! [PySnippetFieldDoubleBuild1_1]
259 # ! [PySnippetFieldDoubleBuild1_2]
260         f1=mesh.fillFromAnalytic(ON_CELLS,1,"x*x+y*y*3+2.*x") # f1 is scalar
261         f2=mesh.fillFromAnalytic(ON_CELLS,1,"cos(x+y/x)") # f2 is scalar too
262         f2bis=mesh.fillFromAnalytic(ON_CELLS,2,"x*x*IVec+3*y*JVec") # f2bis is a vectors field
263         f3=f1+f2 # f3 scalar
264         f4=f3/f2 # f4 scalar
265         f2bis.applyFunc(1,"sqrt(x*x+y*y)") # f2bis becomes scalar
266         f5=f2bis*f4 # f5 scalar
267         pos1=[0.48,0.38]
268         res=f4.getValueOn(pos1) # f4 is scalar so the returned value is of size 1.
269         # ...
270 # ! [PySnippetFieldDoubleBuild1_2]
271 # ! [PySnippetFieldDoubleBuild1_3]
272 # ! [PySnippetFieldDoubleBuild1_3]
273         pass
274
275     def testExampleFieldDoubleBuild2(self):
276         XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] ; arrX=DataArrayDouble.New(XCoords)
277         YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] ; arrY=DataArrayDouble.New(YCoords)
278         mesh=MEDCouplingCMesh.New("My2D_CMesh")
279         mesh.setCoords(arrX,arrY)
280 # ! [PySnippetFieldDoubleBuild2_1]
281         fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME)
282         fieldOnNodes.setName("MyScalarFieldOnNodeNoTime")
283         fieldOnNodes.setMesh(mesh)
284         array=DataArrayDouble.New()
285         array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),1) # Implicitely fieldOnNodes will be a 1 component field.
286         array.fillWithValue(7.)
287         fieldOnNodes.setArray(array)
288         # fieldOnNodes is now usable
289         # ...
290 # ! [PySnippetFieldDoubleBuild2_1]
291         pass
292
293     def testExampleFieldDoubleBuild3(self):
294         XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] ; arrX=DataArrayDouble.New(XCoords)
295         YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] ; arrY=DataArrayDouble.New(YCoords)
296         mesh=MEDCouplingCMesh.New("My2D_CMesh")
297         mesh.setCoords(arrX,arrY)
298 # ! [PySnippetFieldDoubleBuild3_1]
299         fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME)
300         fieldOnCells.setName("MyTensorFieldOnCellNoTime")
301         fieldOnCells.setTimeUnit("ms") # Time unit is ms.
302         fieldOnCells.setTime(4.22,2,-1) # Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1
303         fieldOnCells.setMesh(mesh)
304         array=DataArrayDouble.New()
305         array.alloc(fieldOnCells.getMesh().getNumberOfCells(),2) # Implicitely fieldOnCells will be a 2 components field.
306         array.fillWithValue(7.)
307         fieldOnCells.setArray(array)
308         # fieldOnCells is now usable
309         # ...
310 # ! [PySnippetFieldDoubleBuild3_1]
311         pass
312
313     def testExampleFieldDoubleBuild4(self):
314         XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] ; arrX=DataArrayDouble.New(XCoords)
315         YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] ; arrY=DataArrayDouble.New(YCoords)
316         mesh=MEDCouplingCMesh.New("My2D_CMesh")
317         mesh.setCoords(arrX,arrY)
318 # ! [PySnippetFieldDoubleBuild4_1]
319         fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES,CONST_ON_TIME_INTERVAL)
320         fieldOnNodes.setName("MyVecFieldOnNodeWithConstTime")
321         fieldOnNodes.setTimeUnit("ms") # Time unit is ms.
322         fieldOnNodes.setStartTime(4.22,2,-1)
323         fieldOnNodes.setEndTime(6.44,4,-1)# fieldOnNodes is defined in interval [4.22 ms,6.44 ms]
324         fieldOnNodes.setMesh(mesh)
325         array=DataArrayDouble.New()
326         array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),3) # Implicitely fieldOnNodes will be a 3 components field.
327         array.fillWithValue(7.)
328         fieldOnNodes.setArray(array)
329         # fieldOnNodes is now usable
330         # ...
331 # ! [PySnippetFieldDoubleBuild4_1]
332         pass
333
334     def testExampleDataArrayApplyFunc1(self):
335 # ! [PySnippetDataArrayApplyFunc1_1]
336         d=DataArrayDouble.New([1.,2.,11.,12.,21.,22.,31.,41.],4,2)
337         self.assertRaises(InterpKernelException,d.applyFunc,"x*y")
338 # ! [PySnippetDataArrayApplyFunc1_1]
339 # ! [PySnippetDataArrayApplyFunc1_2]
340         d=DataArrayDouble.New([1.,2.,11.,12.,21.,22.,31.,41.],4,2)
341         d1=d.applyFunc("smth*smth")
342         self.assertTrue(d1.isEqual(DataArrayDouble([1.,4.,121.,144.,441.,484.,961.,1681.],4,2),1e-12))
343 # ! [PySnippetDataArrayApplyFunc1_2]
344 # ! [PySnippetDataArrayApplyFunc1_3]
345         d2=d.applyFunc("smth*IVec+2*smth*JVec")
346         self.assertTrue(d2.isEqual(DataArrayDouble([1.,4.,11.,24.,21.,44.,31.,82.],4,2),1e-12))
347 # ! [PySnippetDataArrayApplyFunc1_3]
348 # ! [PySnippetDataArrayApplyFunc1_4]
349         dd=DataArrayDouble.New([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3)
350 # ! [PySnippetDataArrayApplyFunc1_4]
351 # ! [PySnippetDataArrayApplyFunc1_5]
352         dd1=dd.applyFunc(1,"f+sqrt(g)+h")
353         self.assertTrue(dd1.isEqual(DataArrayDouble([6.,36.,66.,96.],4,1),1e-12))
354 # ! [PySnippetDataArrayApplyFunc1_5]
355 # ! [PySnippetDataArrayApplyFunc1_6]
356         dd2=dd.applyFunc(1,"a+0.*b+c")
357         self.assertTrue(dd2.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12))
358 # ! [PySnippetDataArrayApplyFunc1_6]
359 # ! [PySnippetDataArrayApplyFunc1_7]
360         ddd=DataArrayDouble.New([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3)
361         ddd.setInfoOnComponents(["Y [m]","AA [m/s]","GG [MW]"])
362 # ! [PySnippetDataArrayApplyFunc1_7]
363 # ! [PySnippetDataArrayApplyFunc1_8]
364         ddd1=ddd.applyFunc2(1,"Y+GG")
365         self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12))
366 # ! [PySnippetDataArrayApplyFunc1_8]
367 # ! [PySnippetDataArrayApplyFunc1_9]
368         ddd1=ddd.applyFunc3(1,["X","Y","Z"],"X+Z")
369         self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12))
370 # ! [PySnippetDataArrayApplyFunc1_9]
371         pass
372
373     pass
374
375 unittest.main()