ararpy 0.0.1a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ararpy/__init__.py +178 -0
- ararpy/calc/__init__.py +11 -0
- ararpy/calc/age.py +161 -0
- ararpy/calc/arr.py +490 -0
- ararpy/calc/basic.py +57 -0
- ararpy/calc/corr.py +240 -0
- ararpy/calc/err.py +117 -0
- ararpy/calc/histogram.py +166 -0
- ararpy/calc/isochron.py +194 -0
- ararpy/calc/jvalue.py +38 -0
- ararpy/calc/plot.py +68 -0
- ararpy/calc/raw_funcs.py +118 -0
- ararpy/calc/regression.py +961 -0
- ararpy/calc/spectra.py +63 -0
- ararpy/files/__init__.py +2 -0
- ararpy/files/arr_file.py +86 -0
- ararpy/files/basic.py +100 -0
- ararpy/files/calc_file.py +683 -0
- ararpy/files/export.py +1181 -0
- ararpy/files/json.py +49 -0
- ararpy/files/new_file.py +31 -0
- ararpy/files/raw.py +115 -0
- ararpy/files/raw_file.py +14 -0
- ararpy/files/xls.py +27 -0
- ararpy/smp/__init__.py +17 -0
- ararpy/smp/basic.py +371 -0
- ararpy/smp/calculation.py +94 -0
- ararpy/smp/consts.py +20 -0
- ararpy/smp/corr.py +376 -0
- ararpy/smp/initial.py +232 -0
- ararpy/smp/plots.py +636 -0
- ararpy/smp/sample.py +911 -0
- ararpy/smp/style.py +191 -0
- ararpy/smp/table.py +131 -0
- ararpy-0.0.1a1.dist-info/LICENSE +21 -0
- ararpy-0.0.1a1.dist-info/METADATA +269 -0
- ararpy-0.0.1a1.dist-info/RECORD +39 -0
- ararpy-0.0.1a1.dist-info/WHEEL +5 -0
- ararpy-0.0.1a1.dist-info/top_level.txt +1 -0
ararpy/calc/arr.py
ADDED
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# ==========================================
|
|
5
|
+
# Copyright 2023 Yang
|
|
6
|
+
# ararpy - calc - arr
|
|
7
|
+
# ==========================================
|
|
8
|
+
#
|
|
9
|
+
# Basic functions related to array-like objects
|
|
10
|
+
# List, np.array, pd.DataFrame
|
|
11
|
+
#
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# === Internal import ===
|
|
15
|
+
import traceback
|
|
16
|
+
|
|
17
|
+
from ..calc import err
|
|
18
|
+
# === External import ===
|
|
19
|
+
import re
|
|
20
|
+
import numpy as np
|
|
21
|
+
from scipy.stats import distributions
|
|
22
|
+
# import pandas as pd
|
|
23
|
+
# import decimal
|
|
24
|
+
# from math import exp, log, cos, acos, ceil, sqrt, atan, sin, gamma
|
|
25
|
+
# from typing import List, Any
|
|
26
|
+
# from scipy.optimize import fsolve
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# =======================
|
|
30
|
+
# Error propagation for array-like objects
|
|
31
|
+
# =======================
|
|
32
|
+
def mul(*args):
|
|
33
|
+
"""
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
args :
|
|
37
|
+
2D array like objects of numbers
|
|
38
|
+
lists: [[1, 2, 3], [1, 2, 3]], [[3, 4, 5], [3, 4, 5]]
|
|
39
|
+
np.array([[1, 2, 3], [1, 2, 3]]), np.array([[3, 4, 5], [3, 4, 5]])
|
|
40
|
+
pd.DataFrame([[1, 1], [2, 2], [3, 3]]), pd.DataFrame([[3, 3], [4, 4], [5, 5]])
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
2D list, [values, errors]
|
|
45
|
+
"""
|
|
46
|
+
n = np.shape([args])[-1]
|
|
47
|
+
k0, k1 = [1] * n, [0] * n
|
|
48
|
+
k2 = []
|
|
49
|
+
for i in range(n):
|
|
50
|
+
for arg in args:
|
|
51
|
+
k0[i] = np.multiply(k0[i], arg[0][i])
|
|
52
|
+
k1[i] = k1[i] + np.divide(arg[1][i] ** 2, arg[0][i] ** 2)
|
|
53
|
+
k2.append(abs(k0[i]) * k1[i] ** .5)
|
|
54
|
+
return [k0, k2]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def div(a, b):
|
|
58
|
+
"""
|
|
59
|
+
Y = a / b
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
a : two dimensional array like objects of numbers
|
|
63
|
+
b : two dimensional array like objects of numbers
|
|
64
|
+
lists: [[1, 2, 3], [1, 2, 3]], [[3, 4, 5], [3, 4, 5]]
|
|
65
|
+
np.array([[1, 2, 3], [1, 2, 3]]), np.array([[3, 4, 5], [3, 4, 5]])
|
|
66
|
+
pd.DataFrame([[1, 1], [2, 2], [3, 3]]), pd.DataFrame([[3, 3], [4, 4], [5, 5]])
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
[values, errors]
|
|
71
|
+
"""
|
|
72
|
+
n = np.shape([a, b])[-1]
|
|
73
|
+
k0, k1 = [], []
|
|
74
|
+
for i in range(n):
|
|
75
|
+
k0.append(np.divide(a[0][i], b[0][i]))
|
|
76
|
+
k1.append(
|
|
77
|
+
(np.divide(a[1][i] ** 2, b[0][i] ** 2) +
|
|
78
|
+
np.divide(a[0][i] ** 2 * b[1][i] ** 2, b[0][i] ** 4)) ** .5)
|
|
79
|
+
return [k0, k1]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def rec(a):
|
|
83
|
+
"""
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
a :
|
|
87
|
+
2D array like objects of numbers
|
|
88
|
+
|
|
89
|
+
Returns
|
|
90
|
+
-------
|
|
91
|
+
2D list, [values, errors]
|
|
92
|
+
"""
|
|
93
|
+
try:
|
|
94
|
+
n = np.shape(a)[1]
|
|
95
|
+
k0, k1 = [], []
|
|
96
|
+
for i in range(n):
|
|
97
|
+
k0.append(np.divide(1, a[0][i]))
|
|
98
|
+
k1.append(err.rec((a[0][i], a[1][i])))
|
|
99
|
+
return [k0, k1]
|
|
100
|
+
except IndexError:
|
|
101
|
+
return [1 / a[0], err.rec(a)]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def add(*args):
|
|
105
|
+
""" For y = x1 + x2 + ...
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
args : two dimensional lists, or tuple of two list
|
|
109
|
+
[x1, sx1], [x2, sx2], ...
|
|
110
|
+
|
|
111
|
+
Returns
|
|
112
|
+
-------
|
|
113
|
+
list
|
|
114
|
+
"""
|
|
115
|
+
n = np.shape(args)[-1]
|
|
116
|
+
k0, k1 = [], []
|
|
117
|
+
for i in range(n):
|
|
118
|
+
k0.append(sum([arg[0][i] for arg in args]))
|
|
119
|
+
k1.append(err.add(*[arg[1][i] for arg in args]))
|
|
120
|
+
return [k0, k1]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def sub(*args):
|
|
124
|
+
""" For y = x1 - x2 - ...
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
args : two dimensional lists, or tuple of two list
|
|
128
|
+
[x1, sx1], [x2, sx2], ...
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
|
|
133
|
+
"""
|
|
134
|
+
n = np.shape(args)[-1]
|
|
135
|
+
k0, k1 = [], []
|
|
136
|
+
for i in range(n):
|
|
137
|
+
k0.append(sum([arg[0][i] * [-1, 1][index == 0] for index, arg in enumerate(args)]))
|
|
138
|
+
k1.append(err.add(*[arg[1][i] for arg in args]))
|
|
139
|
+
return [k0, k1]
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def cor(sx: list, sy: list, sz: list):
|
|
143
|
+
"""
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
sx
|
|
147
|
+
sy
|
|
148
|
+
sz
|
|
149
|
+
|
|
150
|
+
Returns
|
|
151
|
+
-------
|
|
152
|
+
|
|
153
|
+
"""
|
|
154
|
+
n = np.shape([sx, sy, sz])[-1]
|
|
155
|
+
return [err.cor(sx[i], sy[i], sz[i]) for i in range(n)]
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def mul_factor(a, factor, isRelative: bool = False):
|
|
159
|
+
""" a × factor
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
a :
|
|
163
|
+
factor : two dimensional list
|
|
164
|
+
isRelative : if the error of factor is relative
|
|
165
|
+
|
|
166
|
+
Returns
|
|
167
|
+
-------
|
|
168
|
+
|
|
169
|
+
"""
|
|
170
|
+
f, sf = np.array(factor)
|
|
171
|
+
if isRelative:
|
|
172
|
+
sf = f * sf * 100
|
|
173
|
+
return mul(a, (f, sf))
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def rec_factor(factor, isRelative: bool = False):
|
|
177
|
+
""" 1 / factor
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
factor : two dimensional list
|
|
181
|
+
isRelative : if the error of factor is relative
|
|
182
|
+
|
|
183
|
+
Returns
|
|
184
|
+
-------
|
|
185
|
+
|
|
186
|
+
"""
|
|
187
|
+
f, sf = np.array(factor)
|
|
188
|
+
if isRelative:
|
|
189
|
+
sf = f * sf * 100
|
|
190
|
+
return rec((f, sf))
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# =======================
|
|
194
|
+
# Basic functions for array-like objects
|
|
195
|
+
# =======================
|
|
196
|
+
def partial(a: list, rows=None, cols=None):
|
|
197
|
+
""" Get partial object from a two dimensional list according to the given rows and cols.
|
|
198
|
+
|
|
199
|
+
Parameters
|
|
200
|
+
----------
|
|
201
|
+
a : two dimensional array-like object with shape of (m, n)
|
|
202
|
+
rows :
|
|
203
|
+
rows index like [1, 2, ...], or int
|
|
204
|
+
cols :
|
|
205
|
+
cols index like [0 ,1, ...], or int
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
array-like object, if rows or cols is int, one dimensional list will be returned
|
|
210
|
+
"""
|
|
211
|
+
res = []
|
|
212
|
+
try:
|
|
213
|
+
(m, n) = np.shape(a)
|
|
214
|
+
except ValueError:
|
|
215
|
+
# ValueError, the requested array has an inhomogeneous shape
|
|
216
|
+
return partial(homo(a), rows=rows, cols=cols)
|
|
217
|
+
if rows is None:
|
|
218
|
+
rows = list(range(n))
|
|
219
|
+
if cols is None:
|
|
220
|
+
cols = list(range(m))
|
|
221
|
+
if isinstance(cols, list):
|
|
222
|
+
res = [a[i] for i in cols]
|
|
223
|
+
elif isinstance(cols, int):
|
|
224
|
+
res = a[cols]
|
|
225
|
+
if isinstance(rows, list):
|
|
226
|
+
if isinstance(cols, list):
|
|
227
|
+
res = [[i[j] for j in rows] for i in res]
|
|
228
|
+
else:
|
|
229
|
+
res = [res[i] for i in rows]
|
|
230
|
+
elif isinstance(rows, int):
|
|
231
|
+
res = res[rows]
|
|
232
|
+
return res
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def array_as_float(p_object):
|
|
236
|
+
""" Get array of floats from list like object
|
|
237
|
+
Parameters
|
|
238
|
+
----------
|
|
239
|
+
p_object
|
|
240
|
+
|
|
241
|
+
Returns
|
|
242
|
+
-------
|
|
243
|
+
|
|
244
|
+
"""
|
|
245
|
+
try:
|
|
246
|
+
return np.array(p_object, dtype=np.float64)
|
|
247
|
+
except ValueError as e:
|
|
248
|
+
item = str(e).split('could not convert string to float: ')
|
|
249
|
+
return array_as_float(replace(p_object, item[1][1:-1], np.nan))
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def replace(array, old, new):
|
|
253
|
+
""" Replace all old items with new items in a array
|
|
254
|
+
|
|
255
|
+
Parameters
|
|
256
|
+
----------
|
|
257
|
+
array
|
|
258
|
+
old : function or object
|
|
259
|
+
new
|
|
260
|
+
|
|
261
|
+
Returns
|
|
262
|
+
-------
|
|
263
|
+
|
|
264
|
+
"""
|
|
265
|
+
if np.iterable(array) and not isinstance(array, str):
|
|
266
|
+
res = [replace(i, old, new) for i in array]
|
|
267
|
+
else:
|
|
268
|
+
if callable(old):
|
|
269
|
+
if old(array):
|
|
270
|
+
res = new
|
|
271
|
+
else:
|
|
272
|
+
res = old
|
|
273
|
+
elif array in [old]:
|
|
274
|
+
res = new
|
|
275
|
+
else:
|
|
276
|
+
res = array
|
|
277
|
+
return res
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def remove(array, old):
|
|
281
|
+
""" Remove all old items
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
array : n dimensional list
|
|
286
|
+
old : tuple, like (None, ), (None, np.nan)
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
|
|
291
|
+
"""
|
|
292
|
+
if is_oneD(array):
|
|
293
|
+
res = []
|
|
294
|
+
for each in array:
|
|
295
|
+
if each in old:
|
|
296
|
+
continue
|
|
297
|
+
res.append(each)
|
|
298
|
+
else:
|
|
299
|
+
res = [remove(each, old=old) for each in array]
|
|
300
|
+
return res
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def merge(*args):
|
|
304
|
+
""" Merge list objects, one dimensional or two dimensional list should be passed in.
|
|
305
|
+
|
|
306
|
+
Parameters
|
|
307
|
+
----------
|
|
308
|
+
args : one or two dimensional list
|
|
309
|
+
|
|
310
|
+
Returns
|
|
311
|
+
-------
|
|
312
|
+
|
|
313
|
+
"""
|
|
314
|
+
res = []
|
|
315
|
+
for arg in args:
|
|
316
|
+
if is_oneD(arg):
|
|
317
|
+
res.append(arg)
|
|
318
|
+
else:
|
|
319
|
+
res = res + arg
|
|
320
|
+
return res
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def is_empty(a):
|
|
324
|
+
""" Check if a list is empty. Return True if it is empty, or it is not a list,
|
|
325
|
+
or all items in it are '', None or np.nan.
|
|
326
|
+
|
|
327
|
+
Parameters
|
|
328
|
+
----------
|
|
329
|
+
a : list
|
|
330
|
+
|
|
331
|
+
Returns
|
|
332
|
+
-------
|
|
333
|
+
bool. True if a is empty or is not a instance of list
|
|
334
|
+
"""
|
|
335
|
+
if not isinstance(a, list) or a == [] or len(a) == 0:
|
|
336
|
+
return True
|
|
337
|
+
for i in a:
|
|
338
|
+
if i not in ['', None, np.nan]:
|
|
339
|
+
return False
|
|
340
|
+
return True
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def ndim(obj):
|
|
344
|
+
"""
|
|
345
|
+
|
|
346
|
+
Parameters
|
|
347
|
+
----------
|
|
348
|
+
obj
|
|
349
|
+
|
|
350
|
+
Returns
|
|
351
|
+
-------
|
|
352
|
+
|
|
353
|
+
"""
|
|
354
|
+
if np.iterable(obj) and not isinstance(obj, str):
|
|
355
|
+
if len(obj) == 0:
|
|
356
|
+
return 1
|
|
357
|
+
return max([ndim(i) for i in obj]) + 1
|
|
358
|
+
return 0
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def is_oneD(obj):
|
|
362
|
+
""" Check if a list-like object is one dimensional
|
|
363
|
+
Parameters
|
|
364
|
+
----------
|
|
365
|
+
obj
|
|
366
|
+
|
|
367
|
+
Returns
|
|
368
|
+
-------
|
|
369
|
+
|
|
370
|
+
"""
|
|
371
|
+
try:
|
|
372
|
+
return ndim(obj) == 1
|
|
373
|
+
except (ValueError, AttributeError):
|
|
374
|
+
return False
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def is_twoD(obj):
|
|
378
|
+
""" Check if a list-like object is two dimensional
|
|
379
|
+
Parameters
|
|
380
|
+
----------
|
|
381
|
+
obj
|
|
382
|
+
|
|
383
|
+
Returns
|
|
384
|
+
-------
|
|
385
|
+
|
|
386
|
+
"""
|
|
387
|
+
try:
|
|
388
|
+
return ndim(obj) == 2
|
|
389
|
+
except (ValueError, AttributeError):
|
|
390
|
+
return False
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def is_homo(obj):
|
|
394
|
+
""" Check if the requested obj is homogeneous
|
|
395
|
+
|
|
396
|
+
Parameters
|
|
397
|
+
----------
|
|
398
|
+
obj
|
|
399
|
+
|
|
400
|
+
Returns
|
|
401
|
+
-------
|
|
402
|
+
|
|
403
|
+
"""
|
|
404
|
+
try:
|
|
405
|
+
np.shape(obj)
|
|
406
|
+
except (ValueError, AttributeError):
|
|
407
|
+
return False
|
|
408
|
+
else:
|
|
409
|
+
return True
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def homo(obj):
|
|
413
|
+
""" Get a homogeneous two dimensional list. If the passed list object is inhomogeneous,
|
|
414
|
+
np.nan will be added to make it homogeneous.
|
|
415
|
+
|
|
416
|
+
Parameters
|
|
417
|
+
----------
|
|
418
|
+
obj : two dimensional list
|
|
419
|
+
|
|
420
|
+
Returns
|
|
421
|
+
-------
|
|
422
|
+
|
|
423
|
+
"""
|
|
424
|
+
if not is_twoD(obj):
|
|
425
|
+
return obj
|
|
426
|
+
try:
|
|
427
|
+
np.shape(obj)
|
|
428
|
+
except (ValueError, AttributeError):
|
|
429
|
+
pass
|
|
430
|
+
else:
|
|
431
|
+
return obj
|
|
432
|
+
length = max(len(i) for i in obj)
|
|
433
|
+
return [i if len(i) == length else i + [np.nan] * (length - len(i)) for i in obj]
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def transpose(obj, ignore: bool = True):
|
|
437
|
+
""" Get the transpose of a list-like object
|
|
438
|
+
Parameters
|
|
439
|
+
----------
|
|
440
|
+
obj : two dimensional list-like object
|
|
441
|
+
ignore : return obj if ingore error is true
|
|
442
|
+
|
|
443
|
+
Returns
|
|
444
|
+
-------
|
|
445
|
+
|
|
446
|
+
"""
|
|
447
|
+
try:
|
|
448
|
+
if not is_twoD(obj):
|
|
449
|
+
raise ValueError("The requested object is not two dimensional.")
|
|
450
|
+
obj = obj if is_homo(obj) else homo(obj)
|
|
451
|
+
m, n = np.shape(obj)
|
|
452
|
+
return [[obj[i][j] for i in range(m)] for j in range(n)]
|
|
453
|
+
except (ValueError, TypeError):
|
|
454
|
+
# print(traceback.format_exc())
|
|
455
|
+
if ignore:
|
|
456
|
+
return obj
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
# =======================
|
|
460
|
+
# Weighted mean
|
|
461
|
+
# =======================
|
|
462
|
+
def wtd_mean(a: list, e: list, sf: int = 1, adjust_error: bool = True):
|
|
463
|
+
"""
|
|
464
|
+
:param a: x
|
|
465
|
+
:param e: error
|
|
466
|
+
:param sf: sigma number for age error, default = 1
|
|
467
|
+
:param adjust_error: adjust error by multiply Sqrt(MSWD)
|
|
468
|
+
:return: error-weighted mean value | error in 1 sigma | number of data points | MSWD | Chisq | P value
|
|
469
|
+
"""
|
|
470
|
+
a, e = np.array([a, e])
|
|
471
|
+
e = e / sf # change error to 1 sigma
|
|
472
|
+
k2 = a.size
|
|
473
|
+
df = k2 - 1
|
|
474
|
+
if k2 == 0:
|
|
475
|
+
return np.nan, np.nan, 0, np.nan, np.nan, np.nan
|
|
476
|
+
wt = 1 / e ** 2
|
|
477
|
+
k0 = sum(a * wt) / sum(wt) # error weighting
|
|
478
|
+
k4 = sum((a - k0) ** 2 * wt) # Chi square
|
|
479
|
+
k3 = k4 / df # MSWD mentioned in Min et al., 2000
|
|
480
|
+
if adjust_error:
|
|
481
|
+
k1 = (k3 / sum(wt)) ** .5
|
|
482
|
+
else:
|
|
483
|
+
k1 = (1 / sum(wt)) ** .5
|
|
484
|
+
k5 = distributions.chi2.sf(k4, df)
|
|
485
|
+
return k0, k1, k2, k3, k4, k5
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
if __name__ == '__main__':
|
|
489
|
+
pass
|
|
490
|
+
|
ararpy/calc/basic.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: UTF-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
# ==========================================
|
|
5
|
+
# Copyright 2023 Yang
|
|
6
|
+
# ararpy - calc - basic
|
|
7
|
+
# ==========================================
|
|
8
|
+
#
|
|
9
|
+
#
|
|
10
|
+
#
|
|
11
|
+
"""
|
|
12
|
+
import copy
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def get_datetime(t_year: int, t_month: int, t_day: int, t_hour: int, t_min: int, t_seconds: int = 0, base=None):
|
|
16
|
+
"""
|
|
17
|
+
:param t_year: int
|
|
18
|
+
:param t_month: int
|
|
19
|
+
:param t_day: int
|
|
20
|
+
:param t_hour: int
|
|
21
|
+
:param t_min: int
|
|
22
|
+
:param t_seconds: int, default == 0
|
|
23
|
+
:param base: base time [y, m, d, h, m]
|
|
24
|
+
:return: seconds since 1970-1-1 8:00
|
|
25
|
+
"""
|
|
26
|
+
t_year, t_month, t_day, t_hour, t_min, t_seconds = \
|
|
27
|
+
int(t_year), int(t_month), int(t_day), int(t_hour), int(t_min), int(t_seconds)
|
|
28
|
+
if base is None:
|
|
29
|
+
base = [1970, 1, 1, 8, 0]
|
|
30
|
+
base_year, base_mouth, base_day, base_hour, base_min = base
|
|
31
|
+
if t_year % 4 == 0 and t_year % 100 != 0 or t_year % 400 == 0:
|
|
32
|
+
days = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
33
|
+
else:
|
|
34
|
+
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
|
35
|
+
delta_seconds = ((((t_year - base_year) * 365 + ((t_year + 1 - base_year) - (t_year + 1 - base_year) % 4) / 4 +
|
|
36
|
+
sum(days[base_mouth - 1:t_month - 1]) + t_day - base_day) * 24 + t_hour - base_hour) * 60 +
|
|
37
|
+
t_min - base_min) * 60 + t_seconds
|
|
38
|
+
return delta_seconds
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def merge_dicts(a: dict, b: dict):
|
|
42
|
+
"""
|
|
43
|
+
a and b, two dictionary. Return updated a
|
|
44
|
+
For example:
|
|
45
|
+
a = {"1": 1, "2": {"1": 1, "2": 2, "3": 3, "5": {}, "6": [1, 2]}}
|
|
46
|
+
b = {"1": 'b', "2": {"1": 'b', "2": 'b', "3": 'b', "4": 'b', "5": {"1": 'b'}, "6": [1, 2, 3]}}
|
|
47
|
+
Will return {'1': 1, '2': {'1': 1, '2': 2, '3': 3, '5': {'1': 'b'}, '6': [1, 2], '4': 'b'}}
|
|
48
|
+
"""
|
|
49
|
+
res = copy.deepcopy(a)
|
|
50
|
+
for key, val in b.items():
|
|
51
|
+
if key not in res.keys():
|
|
52
|
+
res[key] = val
|
|
53
|
+
elif isinstance(val, dict):
|
|
54
|
+
res[key] = merge_dicts(res[key], val)
|
|
55
|
+
else:
|
|
56
|
+
continue
|
|
57
|
+
return res
|