CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
AllenDowney

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: AllenDowney/ModSimPy
Path: blob/master/modsim/test_modsim.py
Views: 531
1
import unittest
2
from modsim import *
3
4
import os
5
6
import pint
7
from pint.errors import UnitStrippedWarning
8
9
import warnings
10
11
warnings.simplefilter("error", Warning)
12
13
14
class TestModSimSeries(unittest.TestCase):
15
def test_constructor(self):
16
s = ModSimSeries([1, 2, 3])
17
self.assertEqual(s[0], 1)
18
19
q = Quantity(2, UNITS.meter)
20
s[q] = 4
21
self.assertEqual(s[q], 4)
22
self.assertEqual(s[2], 4)
23
24
25
class TestModSimDataFrame(unittest.TestCase):
26
def test_constructor(self):
27
msf = ModSimDataFrame(columns=["A", "T", "dt"])
28
msf.row[1000] = [1, 2, np.nan]
29
msf.row["label"] = ["4", 5, 6.0]
30
31
col = msf.A
32
self.assertIsInstance(col, ModSimSeries)
33
self.assertEqual(col[1000], 1)
34
35
col = msf.T
36
self.assertIsInstance(col, ModSimSeries)
37
self.assertEqual(col[1000], 2)
38
39
col = msf.dt
40
self.assertIsInstance(col, ModSimSeries)
41
self.assertEqual(col["label"], 6.0)
42
43
row = msf.row[1000]
44
self.assertIsInstance(row, ModSimSeries)
45
46
self.assertEqual(row.A, 1)
47
self.assertEqual(row.T, 2)
48
self.assertTrue(np.isnan(row.dt))
49
50
self.assertEqual(row["A"], 1)
51
self.assertEqual(row["T"], 2)
52
self.assertTrue(np.isnan(row["dt"]))
53
54
55
class TestTimeFrame(unittest.TestCase):
56
def test_constructor(self):
57
msf = TimeFrame(columns=["A", "T", "dt"])
58
msf.row[1000] = [1, 2, np.nan]
59
msf.row["label"] = ["4", 5, 6.0]
60
61
col = msf.A
62
self.assertIsInstance(col, TimeSeries)
63
64
col = msf.T
65
self.assertIsInstance(col, TimeSeries)
66
67
col = msf.dt
68
self.assertIsInstance(col, TimeSeries)
69
70
row = msf.row[1000]
71
self.assertIsInstance(row, State)
72
73
row = msf.row["label"]
74
self.assertIsInstance(row, State)
75
76
77
class TestSweepFrame(unittest.TestCase):
78
def test_constructor(self):
79
msf = SweepFrame(columns=["A", "T", "dt"])
80
msf.row[1000] = [1, 2, np.nan]
81
msf.row["label"] = ["4", 5, 6.0]
82
83
col = msf.A
84
self.assertIsInstance(col, SweepSeries)
85
86
col = msf.T
87
self.assertIsInstance(col, SweepSeries)
88
89
col = msf.dt
90
self.assertIsInstance(col, SweepSeries)
91
92
row = msf.row[1000]
93
self.assertIsInstance(row, SweepSeries)
94
95
row = msf.row["label"]
96
self.assertIsInstance(row, SweepSeries)
97
98
99
class TestCartPol(unittest.TestCase):
100
def test_cart2pol(self):
101
theta, r = cart2pol(3, 4)
102
self.assertAlmostEqual(r, 5)
103
self.assertAlmostEqual(theta, 0.9272952180016122)
104
105
theta, r, z = cart2pol(2, 2, 2)
106
self.assertAlmostEqual(r, 2 * np.sqrt(2))
107
self.assertAlmostEqual(theta, np.pi / 4)
108
self.assertAlmostEqual(z, 2)
109
110
def test_pol2cart(self):
111
theta = 0.9272952180016122
112
r = 5
113
x, y = pol2cart(theta, r)
114
self.assertAlmostEqual(x, 3)
115
self.assertAlmostEqual(y, 4)
116
117
angle = 45 * UNITS.degree
118
r = 2 * np.sqrt(2)
119
z = 2
120
x, y, z = pol2cart(angle, r, z)
121
self.assertAlmostEqual(x, 2)
122
self.assertAlmostEqual(y, 2)
123
self.assertAlmostEqual(z, 2)
124
125
126
class TestLinspaceLinRange(unittest.TestCase):
127
def test_linspace(self):
128
warnings.simplefilter("error", Warning)
129
array = linspace(0, 1, 11)
130
self.assertEqual(len(array), 11)
131
self.assertAlmostEqual(array[0], 0)
132
self.assertAlmostEqual(array[1], 0.1)
133
self.assertAlmostEqual(array[10], 1.0)
134
135
array = linspace(0, 1, 10, endpoint=False)
136
self.assertEqual(len(array), 10)
137
self.assertAlmostEqual(array[0], 0)
138
self.assertAlmostEqual(array[1], 0.1)
139
self.assertAlmostEqual(array[9], 0.9)
140
141
def test_linrange(self):
142
array = linrange(0, 1, 0.1)
143
self.assertEqual(len(array), 10)
144
self.assertAlmostEqual(array[0], 0)
145
self.assertAlmostEqual(array[1], 0.1)
146
self.assertAlmostEqual(array[9], 0.9)
147
148
array = linrange(0, 1, 0.1, endpoint=True)
149
self.assertEqual(len(array), 11)
150
self.assertAlmostEqual(array[0], 0)
151
self.assertAlmostEqual(array[1], 0.1)
152
self.assertAlmostEqual(array[10], 1.0)
153
154
155
class TestAbsRelDiff(unittest.TestCase):
156
def test_abs_diff(self):
157
abs_diff = compute_abs_diff([1, 3, 7.5])
158
self.assertEqual(len(abs_diff), 3)
159
self.assertAlmostEqual(abs_diff[1], 4.5)
160
161
ts = linrange(1950, 1960, endpoint=True)
162
ps = linspace(3, 4, len(ts))
163
abs_diff = compute_abs_diff(ps)
164
self.assertEqual(len(abs_diff), 11)
165
self.assertAlmostEqual(abs_diff[1], 0.1)
166
167
# TODO: bring back this test when np.ediff1 is fixed
168
# self.assertTrue(np.isnan(abs_diff[-1]))
169
170
series = TimeSeries(ps, index=ts)
171
abs_diff = compute_abs_diff(series)
172
self.assertEqual(len(abs_diff), 11)
173
self.assertAlmostEqual(abs_diff[1950], 0.1)
174
# self.assertTrue(np.isnan(abs_diff[1960]))
175
176
def test_rel_diff(self):
177
rel_diff = compute_rel_diff([1, 3, 7.5])
178
self.assertEqual(len(rel_diff), 3)
179
self.assertAlmostEqual(rel_diff[1], 1.5)
180
181
ts = linrange(1950, 1960, endpoint=True)
182
ps = linspace(3, 4, len(ts))
183
rel_diff = compute_rel_diff(ps)
184
self.assertEqual(len(rel_diff), 11)
185
self.assertAlmostEqual(rel_diff[0], 0.0333333333)
186
# self.assertTrue(np.isnan(rel_diff[-1]))
187
188
series = TimeSeries(ps, index=ts)
189
rel_diff = compute_rel_diff(series)
190
self.assertEqual(len(rel_diff), 11)
191
self.assertAlmostEqual(rel_diff[1950], 0.0333333333)
192
# self.assertTrue(np.isnan(rel_diff[1960]))
193
194
195
class TestOdeSolvers(unittest.TestCase):
196
def test_run_euler(self):
197
s = UNITS.second
198
m = UNITS.meter
199
200
init = State(y=2 * m)
201
system = System(init=init, t_0=1 * s, t_end=3 * s)
202
203
def slope_func(state, t, system):
204
[y] = state
205
dydt = y / s + t * m / s ** 2
206
return [dydt]
207
208
results, details = run_euler(system, slope_func)
209
y_end = get_last_value(results.y)
210
self.assertAlmostEqual(y_end, 24.9737147 * m)
211
212
def test_run_ralston(self):
213
s = UNITS.second
214
m = UNITS.meter
215
216
init = State(y=2 * m)
217
system = System(init=init, t_0=1 * s, t_end=3 * s)
218
219
def slope_func(state, t, system):
220
[y] = state
221
dydt = y / s + t * m / s ** 2
222
return [dydt]
223
224
results, details = run_ralston(system, slope_func)
225
y_end = get_last_value(results.y)
226
self.assertAlmostEqual(y_end, 25.8344700133 * m)
227
228
def test_run_solve_ivp(self):
229
s = UNITS.second
230
m = UNITS.meter
231
232
init = State(y=2 * m)
233
system = System(init=init, t_0=1 * s, t_end=3 * s)
234
235
def slope_func(state, t, system):
236
[y] = state
237
dydt = y + t
238
return [dydt]
239
240
results, details = run_solve_ivp(system, slope_func)
241
y_end = get_last_value(results.y)
242
self.assertAlmostEqual(y_end, 25.5571533)
243
244
245
class TestRootFinders(unittest.TestCase):
246
def test_root_scalar(self):
247
def func(x):
248
return (x - 1) * (x - 2) * (x - 3)
249
250
res = root_scalar(func, [0, 1.9])
251
self.assertAlmostEqual(res.root, 1.0)
252
253
def test_root_secant(self):
254
def func(x):
255
return (x - 1) * (x - 2) * (x - 3)
256
257
res = root_bisect(func, [0, 1.9])
258
self.assertAlmostEqual(res.root, 1.0)
259
260
res = root_bisect(func, [0, 0.5])
261
self.assertFalse(res.converged)
262
263
264
class TestRunInterpolate(unittest.TestCase):
265
def test_has_nan(self):
266
a = [1, 2, 3]
267
self.assertFalse(has_nan(a))
268
self.assertFalse(has_nan(np.array(a)))
269
self.assertFalse(has_nan(pd.Series(a)))
270
a.append(np.nan)
271
self.assertTrue(has_nan(a))
272
self.assertTrue(has_nan(np.array(a)))
273
self.assertTrue(has_nan(pd.Series(a)))
274
275
def test_is_strictly_increasing(self):
276
a = [1, 2, 3]
277
self.assertTrue(is_strictly_increasing(a))
278
self.assertTrue(is_strictly_increasing(np.array(a)))
279
self.assertTrue(is_strictly_increasing(pd.Series(a)))
280
a.append(3)
281
self.assertFalse(is_strictly_increasing(a))
282
self.assertFalse(is_strictly_increasing(np.array(a)))
283
self.assertFalse(is_strictly_increasing(pd.Series(a)))
284
285
def test_interpolate(self):
286
index = [1, 2, 3]
287
values = np.array(index) * 2 - 1
288
series = pd.Series(values, index=index)
289
i = interpolate(series)
290
self.assertAlmostEqual(i(1.5), 2.0)
291
292
def test_interpolate_with_units(self):
293
index = [1, 2, 3]
294
values = np.array(index) * 2 - 1
295
series = pd.Series(values, index=index) * UNITS.meter
296
i = interpolate(series)
297
self.assertAlmostEqual(i(1.5), 2.0 * UNITS.meter)
298
299
300
class TestGradient(unittest.TestCase):
301
def test_gradient(self):
302
a = [1, 2, 4]
303
s = TimeSeries(a)
304
r = gradient(s)
305
self.assertTrue(isinstance(r, TimeSeries))
306
self.assertAlmostEqual(r[1], 1.5)
307
308
def test_gradient_with_units(self):
309
s = SweepSeries()
310
s[0] = 1 * UNITS.meter
311
s[1] = 2 * UNITS.meter
312
s[2] = 4 * UNITS.meter
313
r = gradient(s)
314
self.assertTrue(isinstance(r, SweepSeries))
315
self.assertAlmostEqual(r[1], 1.5 * UNITS.meter)
316
317
318
class TestGolden(unittest.TestCase):
319
def test_minimize(self):
320
def min_func(x, system):
321
return (x - system.actual_min) ** 2
322
323
system = System(actual_min=2)
324
res = minimize_golden(min_func, [0, 5], system, rtol=1e-7)
325
self.assertAlmostEqual(res.x, 2)
326
self.assertAlmostEqual(res.fun, 0)
327
328
def test_maximize(self):
329
def max_func(x, system):
330
return -(x - system.actual_min) ** 2
331
332
system = System(actual_min=2)
333
res = maximize_golden(max_func, [0, 5], system, rtol=1e-7)
334
self.assertAlmostEqual(res.x, 2)
335
self.assertAlmostEqual(res.fun, 0)
336
337
338
class TestVector(unittest.TestCase):
339
def assertArrayEqual(self, res, ans):
340
self.assertTrue(isinstance(res, np.ndarray))
341
self.assertTrue((res == ans).all())
342
343
def assertVectorEqual(self, res, ans):
344
self.assertTrue(isinstance(res, ModSimVector))
345
self.assertTrue((res == ans).all())
346
347
def assertVectorAlmostEqual(self, res, ans):
348
[self.assertQuantityAlmostEqual(x, y) for x, y in zip(res, ans)]
349
350
def assertQuantityAlmostEqual(self, x, y):
351
self.assertEqual(get_units(x), get_units(y))
352
self.assertAlmostEqual(magnitude(x), magnitude(y))
353
354
def test_vector_mag(self):
355
warnings.simplefilter("error", Warning)
356
m = UNITS.meter
357
358
v = [3, 4]
359
self.assertEqual(vector_mag(v), 5)
360
v = Vector(3, 4)
361
self.assertEqual(vector_mag(v), 5)
362
v = Vector(3, 4) * m
363
self.assertEqual(vector_mag(v), 5 * m)
364
self.assertEqual(v.mag, 5 * m)
365
366
def test_vector_mag2(self):
367
warnings.simplefilter("error", Warning)
368
m = UNITS.meter
369
370
v = [3, 4]
371
self.assertEqual(vector_mag2(v), 25)
372
v = Vector(3, 4)
373
self.assertEqual(vector_mag2(v), 25)
374
v = Vector(3, 4) * m
375
self.assertEqual(vector_mag2(v), 25 * m * m)
376
377
def test_vector_angle(self):
378
warnings.simplefilter("error", Warning)
379
m = UNITS.meter
380
ans = 0.927295218
381
v = [3, 4]
382
self.assertAlmostEqual(vector_angle(v), ans)
383
v = Vector(3, 4)
384
self.assertAlmostEqual(vector_angle(v), ans)
385
v = Vector(3, 4) * m
386
self.assertAlmostEqual(vector_angle(v), ans)
387
388
def test_vector_hat(self):
389
warnings.simplefilter("error", Warning)
390
m = UNITS.meter
391
v = [3, 4]
392
ans = [0.6, 0.8]
393
self.assertArrayEqual(vector_hat(v), ans)
394
395
v = Vector(3, 4)
396
self.assertVectorEqual(vector_hat(v), ans)
397
v = Vector(3, 4) * m
398
self.assertVectorEqual(vector_hat(v), ans)
399
400
v = [0, 0]
401
ans = [0, 0]
402
self.assertArrayEqual(vector_hat(v), ans)
403
v = Vector(0, 0)
404
self.assertVectorEqual(vector_hat(v), ans)
405
v = Vector(0, 0) * m
406
self.assertVectorEqual(vector_hat(v), ans)
407
408
def test_vector_perp(self):
409
warnings.simplefilter("error", Warning)
410
m = UNITS.meter
411
v = [3, 4]
412
ans = [-4, 3]
413
self.assertTrue((vector_perp(v) == ans).all())
414
v = Vector(3, 4)
415
self.assertTrue((vector_perp(v) == ans).all())
416
v = Vector(3, 4) * m
417
self.assertTrue((vector_perp(v) == ans * m).all())
418
419
def test_vector_dot(self):
420
warnings.simplefilter("error", Warning)
421
m = UNITS.meter
422
s = UNITS.second
423
v = [3, 4]
424
w = [5, 6]
425
ans = 39
426
self.assertAlmostEqual(vector_dot(v, w), ans)
427
v = Vector(3, 4)
428
self.assertAlmostEqual(vector_dot(v, w), ans)
429
self.assertAlmostEqual(vector_dot(w, v), ans)
430
431
v = Vector(3, 4) * m
432
self.assertAlmostEqual(vector_dot(v, w), ans * m)
433
self.assertAlmostEqual(vector_dot(w, v), ans * m)
434
435
w = Vector(5, 6) / s
436
self.assertAlmostEqual(vector_dot(v, w), ans * m / s)
437
self.assertAlmostEqual(vector_dot(w, v), ans * m / s)
438
439
def test_vector_cross_2D(self):
440
warnings.simplefilter("error", Warning)
441
m = UNITS.meter
442
s = UNITS.second
443
ans = -2
444
445
v = [3, 4]
446
w = [5, 6]
447
self.assertAlmostEqual(vector_cross(v, w), ans)
448
self.assertAlmostEqual(vector_cross(w, v), -ans)
449
450
v = Vector(3, 4)
451
self.assertAlmostEqual(vector_cross(v, w), ans)
452
self.assertAlmostEqual(vector_cross(w, v), -ans)
453
454
v = Vector(3, 4) * m
455
self.assertAlmostEqual(vector_cross(v, w), ans * m)
456
self.assertAlmostEqual(vector_cross(w, v), -ans * m)
457
458
w = Vector(5, 6) / s
459
self.assertAlmostEqual(vector_cross(v, w), ans * m / s)
460
self.assertAlmostEqual(vector_cross(w, v), -ans * m / s)
461
462
def test_vector_cross_3D(self):
463
warnings.simplefilter("error", Warning)
464
m = UNITS.meter
465
s = UNITS.second
466
ans = [-2, 4, -2]
467
468
v = [3, 4, 5]
469
w = [5, 6, 7]
470
self.assertArrayEqual(vector_cross(v, w), ans)
471
self.assertArrayEqual(-vector_cross(w, v), ans)
472
473
v = Vector(3, 4, 5)
474
self.assertVectorEqual(vector_cross(v, w), ans)
475
self.assertVectorEqual(-vector_cross(w, v), ans)
476
477
v = Vector(3, 4, 5) * m
478
self.assertVectorEqual(vector_cross(v, w), ans * m)
479
self.assertVectorEqual(-vector_cross(w, v), ans * m)
480
481
w = Vector(5, 6, 7) / s
482
self.assertVectorEqual(vector_cross(v, w), ans * m / s)
483
self.assertVectorEqual(-vector_cross(w, v), ans * m / s)
484
485
def test_scalar_proj(self):
486
warnings.simplefilter("error", Warning)
487
m = UNITS.meter
488
s = UNITS.second
489
ans = 4.9934383
490
ans2 = 7.8
491
492
v = [3, 4]
493
w = [5, 6]
494
self.assertAlmostEqual(scalar_proj(v, w), ans)
495
self.assertAlmostEqual(scalar_proj(w, v), ans2)
496
497
v = Vector(3, 4)
498
self.assertAlmostEqual(scalar_proj(v, w), ans)
499
self.assertAlmostEqual(scalar_proj(w, v), ans2)
500
501
v = Vector(3, 4) * m
502
self.assertQuantityAlmostEqual(scalar_proj(v, w), ans * m)
503
self.assertAlmostEqual(scalar_proj(w, v), ans2)
504
505
w = Vector(5, 6) / s
506
self.assertQuantityAlmostEqual(scalar_proj(v, w), ans * m)
507
self.assertQuantityAlmostEqual(scalar_proj(w, v), ans2 / s)
508
509
def test_vector_proj(self):
510
warnings.simplefilter("error", Warning)
511
m = UNITS.meter
512
s = UNITS.second
513
ans = [3.19672131, 3.83606557]
514
ans2 = Quantity([4.68, 6.24])
515
516
v = [3, 4]
517
w = [5, 6]
518
self.assertVectorAlmostEqual(vector_proj(v, w), ans)
519
self.assertVectorAlmostEqual(vector_proj(w, v), ans2)
520
521
v = Vector(3, 4)
522
self.assertVectorAlmostEqual(vector_proj(v, w), ans)
523
self.assertVectorAlmostEqual(vector_proj(w, v), ans2)
524
525
v = Vector(3, 4) * m
526
self.assertVectorAlmostEqual(vector_proj(v, w), ans * m)
527
self.assertVectorAlmostEqual(vector_proj(w, v), ans2)
528
529
w = Vector(5, 6) / s
530
self.assertVectorAlmostEqual(vector_proj(v, w), ans * m)
531
self.assertVectorAlmostEqual(vector_proj(w, v), ans2 / s)
532
533
def test_vector_dist(self):
534
warnings.simplefilter("error", Warning)
535
m = UNITS.meter
536
v = [3, 4]
537
w = [6, 8]
538
ans = 5
539
self.assertAlmostEqual(vector_dist(v, w), ans)
540
self.assertAlmostEqual(vector_dist(w, v), ans)
541
542
v = Vector(3, 4)
543
self.assertAlmostEqual(vector_dist(v, w), ans)
544
self.assertAlmostEqual(vector_dist(w, v), ans)
545
546
v = Vector(3, 4) * m
547
w = Vector(6, 8) * m
548
self.assertAlmostEqual(vector_dist(v, w), ans * m)
549
self.assertAlmostEqual(vector_dist(w, v), ans * m)
550
551
def test_vector_diff_angle(self):
552
warnings.simplefilter("error", Warning)
553
m = UNITS.meter
554
v = [3, 4]
555
w = [5, 6]
556
ans = 0.0512371674
557
self.assertAlmostEqual(vector_diff_angle(v, w), ans)
558
self.assertAlmostEqual(vector_diff_angle(w, v), -ans)
559
560
v = Vector(3, 4)
561
self.assertAlmostEqual(vector_diff_angle(v, w), ans)
562
self.assertAlmostEqual(vector_diff_angle(w, v), -ans)
563
564
v = Vector(3, 4) * m
565
w = Vector(5, 6) * m
566
self.assertAlmostEqual(vector_diff_angle(v, w), ans)
567
self.assertAlmostEqual(vector_diff_angle(w, v), -ans)
568
569
570
class TestSeriesCopy(unittest.TestCase):
571
def test_series_copy(self):
572
series = TimeSeries()
573
res = series.copy()
574
self.assertTrue(isinstance(res, TimeSeries))
575
576
577
class TestMagnitudeUnits(unittest.TestCase):
578
def test_magnitudes(self):
579
# scalar
580
x = 5
581
res = magnitudes(x)
582
self.assertEqual(res, 5)
583
res = magnitudes(x * UNITS.meter)
584
self.assertEqual(res, 5)
585
586
# list (result is NumPy array)
587
t = [1, 2, 3]
588
res = magnitudes(t)
589
self.assertEqual(res, [1, 2, 3])
590
res = magnitudes(t * UNITS.meter)
591
self.assertTrue((res == [1, 2, 3]).all())
592
593
# Series (result is list)
594
s = ModSimSeries([1, 2, 3])
595
res = magnitudes(s)
596
self.assertTrue((res == [1, 2, 3]).all())
597
res = magnitudes(s * UNITS.meter)
598
self.assertTrue((res == [1, 2, 3]).all())
599
600
# Quantity containing Series(result is Series)
601
res = magnitudes(UNITS.meter * s)
602
self.assertTrue((res == [1, 2, 3]).all())
603
604
def test_units(self):
605
# scalar
606
x = 5
607
res = get_units(x)
608
self.assertEqual(res, 1)
609
res = get_units(x * UNITS.meter)
610
self.assertEqual(res, UNITS.meter)
611
612
# list (result is list)
613
t = [1, 2, 3]
614
res = get_units(t)
615
self.assertEqual(res, [1, 1, 1])
616
res = get_units(t * UNITS.meter)
617
self.assertEqual(res, UNITS.meter)
618
619
# Series (result Series)
620
s = ModSimSeries([1, 2, 3])
621
res = get_units(s)
622
self.assertTrue((res == [1, 1, 1]).all())
623
624
# Series containing Quantities (result is a Series)
625
res = get_units(s * UNITS.meter)
626
self.assertTrue((res == [UNITS.meter] * 3).all())
627
628
# Quantity containing Series(result is a single Unit object)
629
res = get_units(UNITS.meter * s)
630
self.assertEqual(res, UNITS.meter)
631
632
633
class TestPlot(unittest.TestCase):
634
def test_plot(self):
635
os.environ["QT_XKB_CONFIG_ROOT"] = "/usr/share/X11/xkb"
636
637
t = [1, 2, 3]
638
plot(t)
639
640
t = [1, 2, 3] * UNITS.meter
641
plot(t)
642
643
x = [4, 5, 6]
644
plot(x, t)
645
646
x = [4, 5, 6] * UNITS.second
647
plot(x, t)
648
649
a = np.array(t)
650
plot(a)
651
652
x = np.array(x)
653
plot(x, a)
654
655
s = TimeSeries(t)
656
plot(s)
657
658
s = TimeSeries(t, x)
659
plot(s)
660
661
s = TimeSeries(a, x)
662
plot(s)
663
664
665
if __name__ == "__main__":
666
unittest.main()
667
668