oafuncs 0.0.60__py2.py3-none-any.whl → 0.0.61__py2.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.
- oafuncs/oa_cmap.py +8 -14
- oafuncs/oa_data.py +23 -41
- oafuncs/oa_down/hycom_3hourly.py +47 -89
- oafuncs/oa_down/refs_pdf.py +14 -25
- oafuncs/oa_draw.py +23 -47
- oafuncs/oa_file.py +34 -35
- oafuncs/oa_nc.py +18 -34
- oafuncs/oa_sign/meteorological.py +7 -14
- oafuncs/oa_sign/ocean.py +7 -12
- {oafuncs-0.0.60.dist-info → oafuncs-0.0.61.dist-info}/METADATA +1 -1
- oafuncs-0.0.61.dist-info/RECORD +22 -0
- oafuncs-0.0.60.dist-info/RECORD +0 -22
- {oafuncs-0.0.60.dist-info → oafuncs-0.0.61.dist-info}/LICENSE.txt +0 -0
- {oafuncs-0.0.60.dist-info → oafuncs-0.0.61.dist-info}/WHEEL +0 -0
- {oafuncs-0.0.60.dist-info → oafuncs-0.0.61.dist-info}/top_level.txt +0 -0
oafuncs/oa_draw.py
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-09-17 17:26:11
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-
|
8
|
-
FilePath: \\Python\\My_Funcs\\OAFuncs\\
|
7
|
+
LastEditTime: 2024-11-21 13:10:47
|
8
|
+
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_draw.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
11
11
|
ComputerInfo: XPS 15 9510
|
@@ -26,13 +26,13 @@ import xarray as xr
|
|
26
26
|
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
|
27
27
|
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
28
28
|
|
29
|
-
__all__ = ['create_gif', 'xy2lonlat', 'plot_contourf',
|
30
|
-
'plot_contourf_lonlat', 'plot_quiver', 'plot_contourf_cartopy']
|
29
|
+
__all__ = ['create_gif', 'xy2lonlat', 'plot_contourf', 'plot_contourf_lonlat', 'plot_quiver', 'plot_contourf_cartopy']
|
31
30
|
|
32
31
|
warnings.filterwarnings('ignore')
|
33
32
|
|
34
|
-
|
35
33
|
# ** 将生成图片/已有图片制作成动图
|
34
|
+
|
35
|
+
|
36
36
|
def create_gif(image_list: list, gif_name: str, duration=0.2): # 制作动图,默认间隔0.2
|
37
37
|
'''
|
38
38
|
func : 制作动图,将已有图片拼接
|
@@ -69,8 +69,7 @@ def xy2lonlat(xy, lonlat='lon', decimal=2):
|
|
69
69
|
# degrees = int(abs(x))
|
70
70
|
degrees = round(abs(x), decimal)
|
71
71
|
direction = "E" if x >= 0 else "W"
|
72
|
-
out_list.append(
|
73
|
-
f"{degrees:.{decimal}f}°{direction}" if x != 0 and x != 180 else f"{degrees}°")
|
72
|
+
out_list.append(f"{degrees:.{decimal}f}°{direction}" if x != 0 and x != 180 else f"{degrees}°")
|
74
73
|
return out_list if len(out_list) > 1 else out_list[0]
|
75
74
|
|
76
75
|
def format_latitude(y_list):
|
@@ -81,8 +80,7 @@ def xy2lonlat(xy, lonlat='lon', decimal=2):
|
|
81
80
|
# degrees = int(abs(y))
|
82
81
|
degrees = round(abs(y), decimal)
|
83
82
|
direction = "N" if y >= 0 else "S"
|
84
|
-
out_list.append(
|
85
|
-
f"{degrees:.{decimal}f}°{direction}" if y != 0 else f"{degrees}°")
|
83
|
+
out_list.append(f"{degrees:.{decimal}f}°{direction}" if y != 0 else f"{degrees}°")
|
86
84
|
return out_list if len(out_list) > 1 else out_list[0]
|
87
85
|
|
88
86
|
if lonlat == 'lon':
|
@@ -107,12 +105,6 @@ class _MyFormatter(mpl.ticker.ScalarFormatter):
|
|
107
105
|
|
108
106
|
def __call__(self, x, pos):
|
109
107
|
if ((abs(x) < 1e-2) or (abs(x) > 1e4)) and x != 0:
|
110
|
-
# if self.magnitude_max - self.magnitude_min == 1 and (int(math.modf(math.log10(abs(x)))[1]) == self.magnitude_min):
|
111
|
-
# a, b = '{:.1e}'.format(x).split('e')
|
112
|
-
# b = int(b)
|
113
|
-
# return '${}{:.2f} \\times 10^{{{}}}$'.format(' ' if self.p_n and x > 0 else '', float(a)/10, b+1)
|
114
|
-
# else:
|
115
|
-
# return '${}{} \\times 10^{{{}}}$'.format(' ' if self.p_n and x > 0 else '', *'{:.2e}'.format(x).split('e'))
|
116
108
|
if self.magnitude_max - self.magnitude_min == 1 and (int(math.modf(math.log10(abs(x)))[1]) == self.magnitude_min):
|
117
109
|
a, b = '{:.1e}'.format(x).split('e')
|
118
110
|
a = float(a) / 10
|
@@ -152,20 +144,16 @@ def plot_contourf(pic_data, picname=None, c_map='rainbow', minmax=None, labels=N
|
|
152
144
|
flag = (value_min < 0) and (value_max > 0)
|
153
145
|
norm = mpl.colors.TwoSlopeNorm(
|
154
146
|
vmin=-1 * v_bry, vcenter=0, vmax=v_bry) if flag else mpl.colors.Normalize(vmin=value_min, vmax=value_max)
|
155
|
-
cticks = [num for num in np.linspace(-1 * v_bry if flag else value_min,
|
156
|
-
|
157
|
-
levels = np.linspace(-1 * v_bry, v_bry,
|
158
|
-
20) if flag else None if value_min == value_max else np.linspace(value_min, value_max, 20)
|
147
|
+
cticks = [num for num in np.linspace(-1 * v_bry if flag else value_min, v_bry if flag else value_max, 9)] if value_min != value_max else None
|
148
|
+
levels = np.linspace(-1 * v_bry, v_bry, 20) if flag else None if value_min == value_max else np.linspace(value_min, value_max, 20)
|
159
149
|
|
160
150
|
shape = np.array(pic_data).shape
|
161
151
|
x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))
|
162
152
|
|
163
153
|
fig, ax = plt.subplots(figsize=figsize)
|
164
154
|
flag_lc = levels is not None and cticks is not None
|
165
|
-
CS = ax.contourf(x, y, pic_data, cmap=cmap, norm=norm, levels=levels, extend='both') if flag_lc else ax.contourf(
|
166
|
-
|
167
|
-
cb = fig.colorbar(CS, ax=ax, orientation='vertical', shrink=1, format='%.3g', spacing='uniform', ticks=cticks) if cticks is not None else fig.colorbar(
|
168
|
-
CS, ax=ax, orientation='vertical', shrink=1, format='%.3g', spacing='uniform')
|
155
|
+
CS = ax.contourf(x, y, pic_data, cmap=cmap, norm=norm, levels=levels, extend='both') if flag_lc else ax.contourf(x, y, pic_data, cmap=cmap, norm=norm, extend='both')
|
156
|
+
cb = fig.colorbar(CS, ax=ax, orientation='vertical', shrink=1, format='%.3g', spacing='uniform', ticks=cticks) if cticks is not None else fig.colorbar(CS, ax=ax, orientation='vertical', shrink=1, format='%.3g', spacing='uniform')
|
169
157
|
"""%.3g采用的是自动调整格式,也可设置为%.3f,则改为3位小数"""
|
170
158
|
|
171
159
|
# 将格式化器设置为自定义的函数
|
@@ -232,10 +220,8 @@ def plot_contourf_lonlat(data, lon, lat, interval=5, picname=None, c_map='rainbo
|
|
232
220
|
plt.contourf(data, cmap=c_map)
|
233
221
|
x_space = int(len(lon) * interval / (lon[-1] - lon[0]))
|
234
222
|
y_space = int(len(lat) * interval / (lat[-1] - lat[0]))
|
235
|
-
plt.xticks(np.arange(0, len(lon), x_space), [
|
236
|
-
|
237
|
-
plt.yticks(np.arange(0, len(lat), y_space), [
|
238
|
-
format_latitude(lat[i]) for i in range(0, len(lat), y_space)])
|
223
|
+
plt.xticks(np.arange(0, len(lon), x_space), [format_longitude(lon[i]) for i in range(0, len(lon), x_space)])
|
224
|
+
plt.yticks(np.arange(0, len(lat), y_space), [format_latitude(lat[i]) for i in range(0, len(lat), y_space)])
|
239
225
|
plt.colorbar()
|
240
226
|
plt.savefig(
|
241
227
|
picname, bbox_inches='tight') if picname is not None else plt.show()
|
@@ -288,14 +274,12 @@ def plot_quiver(u, v, lon, lat, picname=None, cmap='coolwarm', scale=0.25, width
|
|
288
274
|
cmap=cmap, # 矢量的颜色,多色
|
289
275
|
width=width)
|
290
276
|
# plt.quiverkey(quiver_plot, X=0.90, Y=0.975, U=1, label='1 m/s', labelpos='E', fontproperties={'size': 10})
|
291
|
-
plt.quiverkey(quiver_plot, X=0.87, Y=0.975, U=mean_S,
|
292
|
-
label=f'{mean_S:.2f} m/s', labelpos='E', fontproperties={'size': 10})
|
277
|
+
plt.quiverkey(quiver_plot, X=0.87, Y=0.975, U=mean_S, label=f'{mean_S:.2f} m/s', labelpos='E', fontproperties={'size': 10})
|
293
278
|
plt.colorbar(quiver_plot)
|
294
279
|
plt.xlabel('X')
|
295
280
|
plt.ylabel('Y')
|
296
281
|
|
297
|
-
plt.savefig(
|
298
|
-
picname, bbox_inches='tight') if picname is not None else plt.show()
|
282
|
+
plt.savefig(picname, bbox_inches='tight') if picname is not None else plt.show()
|
299
283
|
plt.clf()
|
300
284
|
plt.close()
|
301
285
|
|
@@ -353,8 +337,7 @@ def plot_contourf_cartopy(data, lon, lat, picname=None, cmap='rainbow', cn_fill_
|
|
353
337
|
cticks = cbar_ticks
|
354
338
|
norm = mpl.colors.BoundaryNorm(cticks, cmap.N)
|
355
339
|
|
356
|
-
cnplot = ax.contourf(X, Y, data, levels=levels, cmap=cmap,
|
357
|
-
norm=norm, transform=proj, extend='both', alpha=1, zorder=0)
|
340
|
+
cnplot = ax.contourf(X, Y, data, levels=levels, cmap=cmap, norm=norm, transform=proj, extend='both', alpha=1, zorder=0)
|
358
341
|
# cllevels = np.linspace(data_min, data_max, 9)
|
359
342
|
# clplot = ax.contour(X, Y, data, levels=levels[9::10], colors='k', linewidths=0.5, transform=proj, zorder=1, alpha=0.8, linestyle='--')
|
360
343
|
# 添加色标,并选择位置
|
@@ -376,15 +359,13 @@ def plot_contourf_cartopy(data, lon, lat, picname=None, cmap='rainbow', cn_fill_
|
|
376
359
|
cax = divider.new_horizontal(size="5%", pad=0.1, axes_class=plt.Axes)
|
377
360
|
fig.add_axes(cax)
|
378
361
|
# cbar = plt.colorbar(cnplot, cax=cax, orientation='vertical', extend='both', format='%.0f')
|
379
|
-
cbar = fig.colorbar(mpl.cm.ScalarMappable(cmap=cmap, norm=norm),
|
380
|
-
cax=cax, orientation='vertical', extend='both', format='%.3f')
|
362
|
+
cbar = fig.colorbar(mpl.cm.ScalarMappable(cmap=cmap, norm=norm), cax=cax, orientation='vertical', extend='both', format='%.3f')
|
381
363
|
cax.yaxis.set_ticks_position('right')
|
382
364
|
cax.yaxis.set_label_position('right')
|
383
365
|
else: # 上方
|
384
366
|
cax = divider.new_vertical(size="5%", pad=0.2, axes_class=plt.Axes)
|
385
367
|
fig.add_axes(cax)
|
386
|
-
cbar = plt.colorbar(
|
387
|
-
cnplot, cax=cax, orientation='horizontal', extend='both')
|
368
|
+
cbar = plt.colorbar(cnplot, cax=cax, orientation='horizontal', extend='both')
|
388
369
|
cbar.ax.tick_params(labelsize=10)
|
389
370
|
cbar.ax.xaxis.set_tick_params(direction='in', width=1, length=2)
|
390
371
|
# 添加cbar_ticks
|
@@ -396,11 +377,9 @@ def plot_contourf_cartopy(data, lon, lat, picname=None, cmap='rainbow', cn_fill_
|
|
396
377
|
# cbar.set_ticks(np.arange(round(levels[0]), round(levels[-1]), round((levels[-1]-levels[0])/9))) # 设置色标刻度
|
397
378
|
|
398
379
|
# 单独设置label
|
399
|
-
cbar.set_label(title, fontsize=10,
|
400
|
-
weight='bold')
|
380
|
+
cbar.set_label(title, fontsize=10, weight='bold')
|
401
381
|
# cax.set_position([0.1, 0.2, 0.02, 0.6]) # 调整色标位置
|
402
|
-
fig.savefig(
|
403
|
-
picname, bbox_inches='tight', dpi=600) if picname is not None else plt.show()
|
382
|
+
fig.savefig(picname, bbox_inches='tight', dpi=600) if picname is not None else plt.show()
|
404
383
|
plt.close()
|
405
384
|
|
406
385
|
|
@@ -408,23 +387,20 @@ if __name__ == '__main__':
|
|
408
387
|
# ** 绘制填色图
|
409
388
|
data = np.random.randn(100, 100)
|
410
389
|
picname = 'test.png'
|
411
|
-
plot_contourf(data, picname, c_map='rainbow', minmax=None,
|
412
|
-
labels=None, ticks_space=None, ticks=None, figsize=(12, 9))
|
390
|
+
plot_contourf(data, picname, c_map='rainbow', minmax=None, labels=None, ticks_space=None, ticks=None, figsize=(12, 9))
|
413
391
|
# ** 绘制矢量场
|
414
392
|
u = np.random.randn(100, 100)
|
415
393
|
v = np.random.randn(100, 100)
|
416
394
|
lon = np.linspace(0, 360, 100)
|
417
395
|
lat = np.linspace(-90, 90, 100)
|
418
396
|
picname = 'test.png'
|
419
|
-
plot_quiver(u, v, lon, lat, picname, cmap='coolwarm',
|
420
|
-
scale=0.25, width=0.002, x_space=5, y_space=5)
|
397
|
+
plot_quiver(u, v, lon, lat, picname, cmap='coolwarm', scale=0.25, width=0.002, x_space=5, y_space=5)
|
421
398
|
# ** 绘制经纬度填色图
|
422
399
|
data = np.random.randn(100, 100)
|
423
400
|
lon = np.linspace(0, 360, 100)
|
424
401
|
lat = np.linspace(-90, 90, 100)
|
425
402
|
picname = 'test.png'
|
426
|
-
plot_contourf_lonlat(data, lon, lat, interval=5,
|
427
|
-
picname=picname, c_map='rainbow')
|
403
|
+
plot_contourf_lonlat(data, lon, lat, interval=5, picname=picname, c_map='rainbow')
|
428
404
|
# ** 制作动图
|
429
405
|
image_list = ['test1.png', 'test2.png', 'test3.png']
|
430
406
|
gif_name = 'test.gif'
|
oafuncs/oa_file.py
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-09-17 15:07:13
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-11-
|
8
|
-
FilePath: \\Python\\My_Funcs\\OAFuncs\\
|
7
|
+
LastEditTime: 2024-11-21 13:07:54
|
8
|
+
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_file.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
11
11
|
ComputerInfo: XPS 15 9510
|
@@ -19,8 +19,7 @@ import os
|
|
19
19
|
import re
|
20
20
|
import shutil
|
21
21
|
|
22
|
-
__all__ = ['link_file', 'copy_file', 'rename_files', 'make_folder',
|
23
|
-
'clear_folder', 'remove_empty_folders', 'remove', 'file_size']
|
22
|
+
__all__ = ['link_file', 'copy_file', 'rename_files', 'make_folder', 'clear_folder', 'remove_empty_folders', 'remove', 'file_size']
|
24
23
|
|
25
24
|
|
26
25
|
def link_file(src_pattern, dst):
|
@@ -33,30 +32,30 @@ def link_file(src_pattern, dst):
|
|
33
32
|
param {*} src_pattern # 源文件或目录
|
34
33
|
param {*} dst # 目标文件或目录
|
35
34
|
'''
|
36
|
-
src_pattern= str(src_pattern)
|
35
|
+
src_pattern = str(src_pattern)
|
37
36
|
# 使用glob.glob来处理可能包含通配符的src
|
38
|
-
src_files= glob.glob(src_pattern)
|
37
|
+
src_files = glob.glob(src_pattern)
|
39
38
|
if not src_files:
|
40
39
|
raise FileNotFoundError('文件不存在: {}'.format(src_pattern))
|
41
40
|
|
42
41
|
# 判断dst是路径还是包含文件名的路径
|
43
42
|
if os.path.isdir(dst):
|
44
43
|
# 如果dst是路径,则保持源文件的文件名
|
45
|
-
dst_dir= dst
|
44
|
+
dst_dir = dst
|
46
45
|
for src_file in src_files:
|
47
|
-
src_file_basename= os.path.basename(src_file)
|
48
|
-
dst_file= os.path.join(dst_dir, src_file_basename)
|
46
|
+
src_file_basename = os.path.basename(src_file)
|
47
|
+
dst_file = os.path.join(dst_dir, src_file_basename)
|
49
48
|
if os.path.exists(dst_file):
|
50
49
|
os.remove(dst_file)
|
51
50
|
os.symlink(src_file, dst_file)
|
52
51
|
print(f'创建符号链接: {src_file} -> {dst_file}')
|
53
52
|
else:
|
54
53
|
# 如果dst包含文件名,则创建链接后重命名
|
55
|
-
dst_dir= os.path.dirname(dst)
|
54
|
+
dst_dir = os.path.dirname(dst)
|
56
55
|
os.makedirs(dst_dir, exist_ok=True)
|
57
56
|
# 只处理第一个匹配的文件
|
58
|
-
src_file= src_files[0]
|
59
|
-
dst_file= dst
|
57
|
+
src_file = src_files[0]
|
58
|
+
dst_file = dst
|
60
59
|
if os.path.exists(dst_file):
|
61
60
|
os.remove(dst_file)
|
62
61
|
os.symlink(src_file, dst_file)
|
@@ -72,19 +71,19 @@ def copy_file(src_pattern, dst):
|
|
72
71
|
param {*} src_pattern # 源文件或目录
|
73
72
|
param {*} dst # 目标文件或目录
|
74
73
|
'''
|
75
|
-
src_pattern= str(src_pattern)
|
74
|
+
src_pattern = str(src_pattern)
|
76
75
|
# 使用glob.glob来处理可能包含通配符的src
|
77
|
-
src_files= glob.glob(src_pattern)
|
76
|
+
src_files = glob.glob(src_pattern)
|
78
77
|
if not src_files:
|
79
78
|
raise FileNotFoundError('文件不存在: {}'.format(src_pattern))
|
80
79
|
|
81
80
|
# 判断dst是路径还是包含文件名的路径
|
82
81
|
if os.path.isdir(dst):
|
83
82
|
# 如果dst是路径,则保持源文件的文件名
|
84
|
-
dst_dir= dst
|
83
|
+
dst_dir = dst
|
85
84
|
for src_file in src_files:
|
86
|
-
src_file_basename= os.path.basename(src_file)
|
87
|
-
dst_file= os.path.join(dst_dir, src_file_basename)
|
85
|
+
src_file_basename = os.path.basename(src_file)
|
86
|
+
dst_file = os.path.join(dst_dir, src_file_basename)
|
88
87
|
if os.path.exists(dst_file):
|
89
88
|
if os.path.isdir(dst_file):
|
90
89
|
shutil.rmtree(dst_file)
|
@@ -97,11 +96,11 @@ def copy_file(src_pattern, dst):
|
|
97
96
|
print(f'复制文件或目录: {src_file} -> {dst_file}')
|
98
97
|
else:
|
99
98
|
# 如果dst包含文件名,则复制后重命名
|
100
|
-
dst_dir= os.path.dirname(dst)
|
99
|
+
dst_dir = os.path.dirname(dst)
|
101
100
|
os.makedirs(dst_dir, exist_ok=True)
|
102
101
|
# 只处理第一个匹配的文件
|
103
|
-
src_file= src_files[0]
|
104
|
-
dst_file= dst
|
102
|
+
src_file = src_files[0]
|
103
|
+
dst_file = dst
|
105
104
|
if os.path.exists(dst_file):
|
106
105
|
if os.path.isdir(dst_file):
|
107
106
|
shutil.rmtree(dst_file)
|
@@ -127,23 +126,23 @@ def rename_files(directory, old_str, new_str):
|
|
127
126
|
param {*} new_str # 新字符串
|
128
127
|
'''
|
129
128
|
# 获取目录下的所有文件
|
130
|
-
files= os.listdir(directory)
|
129
|
+
files = os.listdir(directory)
|
131
130
|
|
132
131
|
# 构建正则表达式以匹配要替换的字符串
|
133
|
-
pattern= re.compile(re.escape(old_str))
|
132
|
+
pattern = re.compile(re.escape(old_str))
|
134
133
|
|
135
134
|
# 遍历目录下的文件
|
136
135
|
for filename in files:
|
137
136
|
# 检查文件名中是否包含要替换的字符串
|
138
137
|
if pattern.search(filename):
|
139
138
|
# 构建新的文件名
|
140
|
-
new_filename= pattern.sub(new_str, filename)
|
139
|
+
new_filename = pattern.sub(new_str, filename)
|
141
140
|
|
142
141
|
# 构建旧文件的完整路径
|
143
|
-
old_path= os.path.join(directory, filename)
|
142
|
+
old_path = os.path.join(directory, filename)
|
144
143
|
|
145
144
|
# 构建新文件的完整路径
|
146
|
-
new_path= os.path.join(directory, new_filename)
|
145
|
+
new_path = os.path.join(directory, new_filename)
|
147
146
|
|
148
147
|
# 重命名文件
|
149
148
|
os.rename(old_path, new_path)
|
@@ -161,7 +160,7 @@ def make_folder(rootpath: str, folder_name: str, clear=0) -> str:
|
|
161
160
|
param {*} rootpath # 根目录
|
162
161
|
param {*} folder_name # 文件夹名称
|
163
162
|
'''
|
164
|
-
folder_path= os.path.join(str(rootpath), str(folder_name))
|
163
|
+
folder_path = os.path.join(str(rootpath), str(folder_name))
|
165
164
|
if clear:
|
166
165
|
shutil.rmtree(folder_path, ignore_errors=True)
|
167
166
|
os.makedirs(folder_path, exist_ok=True)
|
@@ -177,12 +176,12 @@ def clear_folder(folder_path):
|
|
177
176
|
clear_folder(r'E:\Data\2024\09\17\var1')
|
178
177
|
param {*} folder_path # 文件夹路径
|
179
178
|
'''
|
180
|
-
folder_path= str(folder_path)
|
179
|
+
folder_path = str(folder_path)
|
181
180
|
if os.path.exists(folder_path):
|
182
181
|
try:
|
183
182
|
# 遍历文件夹中的所有文件和子文件夹
|
184
183
|
for filename in os.listdir(folder_path):
|
185
|
-
file_path= os.path.join(folder_path, filename)
|
184
|
+
file_path = os.path.join(folder_path, filename)
|
186
185
|
# 判断是文件还是文件夹
|
187
186
|
if os.path.isfile(file_path) or os.path.islink(file_path):
|
188
187
|
os.unlink(file_path) # 删除文件或链接
|
@@ -203,12 +202,12 @@ def remove_empty_folders(path, print_info=1):
|
|
203
202
|
param {*} path # 文件夹路径
|
204
203
|
param {*} print_info # 是否打印信息
|
205
204
|
'''
|
206
|
-
path= str(path)
|
205
|
+
path = str(path)
|
207
206
|
# 遍历当前目录下的所有文件夹和文件
|
208
207
|
for root, dirs, files in os.walk(path, topdown=False):
|
209
208
|
# 遍历文件夹列表
|
210
209
|
for folder in dirs:
|
211
|
-
folder_path= os.path.join(root, folder)
|
210
|
+
folder_path = os.path.join(root, folder)
|
212
211
|
# 判断文件是否有权限访问
|
213
212
|
try:
|
214
213
|
os.listdir(folder_path)
|
@@ -238,8 +237,8 @@ def remove(pattern):
|
|
238
237
|
'''
|
239
238
|
# 使用glob.glob来获取所有匹配的文件
|
240
239
|
# 可以使用通配符*来匹配所有文件
|
241
|
-
pattern= str(pattern)
|
242
|
-
file_list= glob.glob(pattern)
|
240
|
+
pattern = str(pattern)
|
241
|
+
file_list = glob.glob(pattern)
|
243
242
|
for file_path in file_list:
|
244
243
|
if os.path.exists(file_path):
|
245
244
|
try:
|
@@ -268,10 +267,10 @@ def file_size(file_path, unit='KB'):
|
|
268
267
|
return "文件不存在"
|
269
268
|
|
270
269
|
# 获取文件大小(字节)
|
271
|
-
file_size= os.path.getsize(file_path)
|
270
|
+
file_size = os.path.getsize(file_path)
|
272
271
|
|
273
272
|
# 单位转换字典
|
274
|
-
unit_dict= {
|
273
|
+
unit_dict = {
|
275
274
|
'PB': 1024**5,
|
276
275
|
'TB': 1024**4,
|
277
276
|
'GB': 1024**3,
|
@@ -284,7 +283,7 @@ def file_size(file_path, unit='KB'):
|
|
284
283
|
return "单位不合法,请选择PB、TB、GB、MB、KB中的一个"
|
285
284
|
|
286
285
|
# 转换文件大小到指定单位
|
287
|
-
converted_size= file_size / unit_dict[unit]
|
286
|
+
converted_size = file_size / unit_dict[unit]
|
288
287
|
|
289
288
|
return converted_size
|
290
289
|
|
oafuncs/oa_nc.py
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-09-17 14:58:50
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-11-
|
8
|
-
FilePath: \\Python\\My_Funcs\\OAFuncs\\
|
7
|
+
LastEditTime: 2024-11-21 13:05:51
|
8
|
+
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_nc.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
11
11
|
ComputerInfo: XPS 15 9510
|
@@ -20,8 +20,7 @@ import netCDF4 as nc
|
|
20
20
|
import numpy as np
|
21
21
|
import xarray as xr
|
22
22
|
|
23
|
-
__all__ = ['get_var', 'extract5nc', 'write2nc',
|
24
|
-
'merge5nc', 'modify_var_value', 'modify_var_attr', 'rename_var_or_dim', 'check_ncfile']
|
23
|
+
__all__ = ['get_var', 'extract5nc', 'write2nc', 'merge5nc', 'modify_var_value', 'modify_var_attr', 'rename_var_or_dim', 'check_ncfile']
|
25
24
|
|
26
25
|
|
27
26
|
def get_var(file, *vars):
|
@@ -110,18 +109,15 @@ def write2nc(file, data, varname, coords, mode):
|
|
110
109
|
if dim in ncfile.dimensions:
|
111
110
|
# del nc.dimensions[dim]
|
112
111
|
if len(coord_data) != len(ncfile.dimensions[dim]):
|
113
|
-
raise ValueError(
|
114
|
-
"Length of coordinate does not match the dimension length.")
|
112
|
+
raise ValueError("Length of coordinate does not match the dimension length.")
|
115
113
|
else:
|
116
114
|
add_coords = False
|
117
|
-
print(
|
118
|
-
f"Warning: Coordinate '{dim}' already exists. Replacing it.")
|
115
|
+
print(f"Warning: Coordinate '{dim}' already exists. Replacing it.")
|
119
116
|
ncfile.variables[dim][:] = np.array(coord_data)
|
120
117
|
if add_coords:
|
121
118
|
# 创建新坐标
|
122
119
|
ncfile.createDimension(dim, len(coord_data))
|
123
|
-
ncfile.createVariable(dim, _numpy_to_nc_type(
|
124
|
-
coord_data.dtype), (dim,))
|
120
|
+
ncfile.createVariable(dim, _numpy_to_nc_type(coord_data.dtype), (dim,))
|
125
121
|
ncfile.variables[dim][:] = np.array(coord_data)
|
126
122
|
|
127
123
|
# 判断变量是否存在,若存在,则删除原变量
|
@@ -129,20 +125,17 @@ def write2nc(file, data, varname, coords, mode):
|
|
129
125
|
if varname in ncfile.variables:
|
130
126
|
print(f"Warning: Variable '{varname}' already exists.")
|
131
127
|
if data.shape != ncfile.variables[varname].shape:
|
132
|
-
raise ValueError(
|
133
|
-
"Shape of data does not match the variable shape.")
|
128
|
+
raise ValueError("Shape of data does not match the variable shape.")
|
134
129
|
else:
|
135
130
|
# 写入数据
|
136
131
|
ncfile.variables[varname][:] = data
|
137
132
|
add_var = False
|
138
|
-
print(
|
139
|
-
f"Warning: Variable '{varname}' already exists. Replacing it.")
|
133
|
+
print(f"Warning: Variable '{varname}' already exists. Replacing it.")
|
140
134
|
|
141
135
|
if add_var:
|
142
136
|
# 创建变量及其维度
|
143
137
|
dim_names = tuple(coords.keys()) # 使用coords传入的维度名称
|
144
|
-
ncfile.createVariable(
|
145
|
-
varname, _numpy_to_nc_type(data.dtype), dim_names)
|
138
|
+
ncfile.createVariable(varname, _numpy_to_nc_type(data.dtype), dim_names)
|
146
139
|
# ncfile.createVariable('data', 'f4', ('time','lev'))
|
147
140
|
|
148
141
|
# 写入数据
|
@@ -150,8 +143,7 @@ def write2nc(file, data, varname, coords, mode):
|
|
150
143
|
|
151
144
|
# 判断维度是否匹配
|
152
145
|
if len(data.shape) != len(coords):
|
153
|
-
raise ValueError(
|
154
|
-
"Number of dimensions does not match the data shape.")
|
146
|
+
raise ValueError("Number of dimensions does not match the data shape.")
|
155
147
|
|
156
148
|
|
157
149
|
def merge5nc(file_list, var_name, dim_name, target_filename):
|
@@ -234,11 +226,9 @@ def modify_var_value(nc_file_path, variable_name, new_value):
|
|
234
226
|
# Modify the value of the variable
|
235
227
|
variable[:] = new_value
|
236
228
|
dataset.close()
|
237
|
-
print(
|
238
|
-
f"Successfully modified variable {variable_name} in {nc_file_path}.")
|
229
|
+
print(f"Successfully modified variable {variable_name} in {nc_file_path}.")
|
239
230
|
except Exception as e:
|
240
|
-
print(
|
241
|
-
f"An error occurred while modifying variable {variable_name} in {nc_file_path}: {e}")
|
231
|
+
print(f"An error occurred while modifying variable {variable_name} in {nc_file_path}: {e}")
|
242
232
|
|
243
233
|
|
244
234
|
def modify_var_attr(nc_file_path, variable_name, attribute_name, attribute_value):
|
@@ -255,13 +245,11 @@ def modify_var_attr(nc_file_path, variable_name, attribute_name, attribute_value
|
|
255
245
|
try:
|
256
246
|
ds = nc.Dataset(nc_file_path, 'r+')
|
257
247
|
if variable_name not in ds.variables:
|
258
|
-
raise ValueError(
|
259
|
-
f"Variable '{variable_name}' not found in the NetCDF file.")
|
248
|
+
raise ValueError(f"Variable '{variable_name}' not found in the NetCDF file.")
|
260
249
|
|
261
250
|
variable = ds.variables[variable_name]
|
262
251
|
if attribute_name in variable.ncattrs():
|
263
|
-
print(
|
264
|
-
f"Warning: Attribute '{attribute_name}' already exists. Replacing it.")
|
252
|
+
print(f"Warning: Attribute '{attribute_name}' already exists. Replacing it.")
|
265
253
|
variable.setncattr(attribute_name, attribute_value)
|
266
254
|
else:
|
267
255
|
print(f"Adding attribute '{attribute_name}'...")
|
@@ -287,24 +275,20 @@ def rename_var_or_dim(ncfile_path, old_name, new_name):
|
|
287
275
|
with nc.Dataset(ncfile_path, 'r+') as dataset:
|
288
276
|
# If the old name is not found as a variable or dimension, print a message
|
289
277
|
if old_name not in dataset.variables and old_name not in dataset.dimensions:
|
290
|
-
print(
|
291
|
-
f"Variable or dimension {old_name} not found in the file.")
|
278
|
+
print(f"Variable or dimension {old_name} not found in the file.")
|
292
279
|
|
293
280
|
# Attempt to rename the variable
|
294
281
|
if old_name in dataset.variables:
|
295
282
|
dataset.renameVariable(old_name, new_name)
|
296
|
-
print(
|
297
|
-
f"Successfully renamed variable {old_name} to {new_name}.")
|
283
|
+
print(f"Successfully renamed variable {old_name} to {new_name}.")
|
298
284
|
|
299
285
|
# Attempt to rename the dimension
|
300
286
|
if old_name in dataset.dimensions:
|
301
287
|
# Check if the new dimension name already exists
|
302
288
|
if new_name in dataset.dimensions:
|
303
|
-
raise ValueError(
|
304
|
-
f"Dimension name {new_name} already exists in the file.")
|
289
|
+
raise ValueError(f"Dimension name {new_name} already exists in the file.")
|
305
290
|
dataset.renameDimension(old_name, new_name)
|
306
|
-
print(
|
307
|
-
f"Successfully renamed dimension {old_name} to {new_name}.")
|
291
|
+
print(f"Successfully renamed dimension {old_name} to {new_name}.")
|
308
292
|
|
309
293
|
except Exception as e:
|
310
294
|
print(f"An error occurred: {e}")
|
@@ -35,8 +35,7 @@ def sign_in_meteorological_home(email, password):
|
|
35
35
|
response = s.get(url)
|
36
36
|
response.raise_for_status()
|
37
37
|
soup = BeautifulSoup(response.text, 'lxml')
|
38
|
-
login_hash = soup.find('form', attrs={'name': 'login'})[
|
39
|
-
'action'].split('loginhash=')[1]
|
38
|
+
login_hash = soup.find('form', attrs={'name': 'login'})['action'].split('loginhash=')[1]
|
40
39
|
return login_hash
|
41
40
|
|
42
41
|
def get_login_formhash():
|
@@ -58,16 +57,14 @@ def sign_in_meteorological_home(email, password):
|
|
58
57
|
def write_response(response, default_path=r'F:\response_气象家园.txt'):
|
59
58
|
with open(default_path, 'w', encoding='utf-8') as f:
|
60
59
|
f.write('-'*350+'\n')
|
61
|
-
f.write(time.strftime(
|
62
|
-
'%Y-%m-%d %H:%M:%S', time.localtime()) + '\n')
|
60
|
+
f.write(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\n')
|
63
61
|
f.write(response.text)
|
64
62
|
f.write('-'*350+'\n')
|
65
63
|
|
66
64
|
def login():
|
67
65
|
url = 'http://bbs.06climate.com/member.php?'
|
68
66
|
# 登录密码需要转码为 216fc900fb57c27dd3c5e3dfbcac1849
|
69
|
-
mydata['password'] = hashlib.md5(
|
70
|
-
mydata['password'].encode()).hexdigest()
|
67
|
+
mydata['password'] = hashlib.md5(mydata['password'].encode()).hexdigest()
|
71
68
|
credentials = {
|
72
69
|
'password': mydata['password'],
|
73
70
|
}
|
@@ -97,8 +94,7 @@ def sign_in_meteorological_home(email, password):
|
|
97
94
|
'Referer': 'http://bbs.06climate.com/member.php?mod=logging&action=login',
|
98
95
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
|
99
96
|
}
|
100
|
-
response = s.post(url, params=query_params,
|
101
|
-
data=from_data, headers=head)
|
97
|
+
response = s.post(url, params=query_params, data=from_data, headers=head)
|
102
98
|
if '欢迎' in response.text:
|
103
99
|
print(' [bold green]登录成功')
|
104
100
|
try:
|
@@ -126,8 +122,7 @@ def sign_in_meteorological_home(email, password):
|
|
126
122
|
s.cookies.update(cookie)
|
127
123
|
response = s.get(url, params=query_params, headers=head)
|
128
124
|
response.raise_for_status()
|
129
|
-
success_indicators = ['累计签到', '连续签到', '特奖励',
|
130
|
-
'明日签到', '另奖励', '连续签到', '再连续签到', '奖励', '签到完毕']
|
125
|
+
success_indicators = ['累计签到', '连续签到', '特奖励', '明日签到', '另奖励', '连续签到', '再连续签到', '奖励', '签到完毕']
|
131
126
|
if any(indicator in response.text for indicator in success_indicators):
|
132
127
|
print(' [bold green]签到完毕')
|
133
128
|
else:
|
@@ -143,8 +138,7 @@ def sign_in_meteorological_home(email, password):
|
|
143
138
|
cumulate = soup.select('.pperwbm .times')[0].text
|
144
139
|
continuous = soup.select('.pperwbm .times')[1].text
|
145
140
|
last_sign = soup.select('.pperwbm .times')[2].text
|
146
|
-
info = {credit.split(': ')[0]: credit.split(
|
147
|
-
':')[1], user_group.split(': ')[0]: user_group.split(':')[1], '累计签到': cumulate+'次', '连续签到': continuous+'次', '上次签到': last_sign}
|
141
|
+
info = {credit.split(': ')[0]: credit.split(':')[1], user_group.split(': ')[0]: user_group.split(':')[1], '累计签到': cumulate+'次', '连续签到': continuous+'次', '上次签到': last_sign}
|
148
142
|
|
149
143
|
print('[bold blue]-----------签到信息-----------')
|
150
144
|
for k, v in info.items():
|
@@ -157,8 +151,7 @@ def sign_in_meteorological_home(email, password):
|
|
157
151
|
print(f'[bold blue]{k}: [bold green]{v}')
|
158
152
|
print('[bold blue]------------------------------')
|
159
153
|
|
160
|
-
mydata = {'username': None,
|
161
|
-
'email': email, 'password': password}
|
154
|
+
mydata = {'username': None, 'email': email, 'password': password}
|
162
155
|
s = requests.Session()
|
163
156
|
print('[bold purple]-----------气象家园-----------')
|
164
157
|
cookie = login()
|
oafuncs/oa_sign/ocean.py
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
Author: Liu Kun && 16031215@qq.com
|
5
5
|
Date: 2024-10-14 16:59:26
|
6
6
|
LastEditors: Liu Kun && 16031215@qq.com
|
7
|
-
LastEditTime: 2024-
|
8
|
-
FilePath: \\Python\\My_Funcs\\OAFuncs\\
|
7
|
+
LastEditTime: 2024-11-21 13:16:14
|
8
|
+
FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_sign\\ocean.py
|
9
9
|
Description:
|
10
10
|
EditPlatform: vscode
|
11
11
|
ComputerInfo: XPS 15 9510
|
@@ -40,14 +40,12 @@ def sign_in_love_ocean(email, password):
|
|
40
40
|
response = s.get(url, params=para_login)
|
41
41
|
response.raise_for_status()
|
42
42
|
soup = BeautifulSoup(response.text, 'lxml')
|
43
|
-
login_hash = soup.find('form', attrs={'name': 'login'})[
|
44
|
-
'action'].split('loginhash=')[1]
|
43
|
+
login_hash = soup.find('form', attrs={'name': 'login'})['action'].split('loginhash=')[1]
|
45
44
|
return login_hash
|
46
45
|
|
47
46
|
def _get_login_formhash():
|
48
47
|
url = 'https://www.52ocean.cn/member.php?'
|
49
|
-
para_login = {'mod': 'logging', 'action': 'login', 'infloat': 'yes',
|
50
|
-
'handlekey': 'login', 'inajax': '1', 'ajaxtarget': 'fwin_content_login'}
|
48
|
+
para_login = {'mod': 'logging', 'action': 'login', 'infloat': 'yes', 'handlekey': 'login', 'inajax': '1', 'ajaxtarget': 'fwin_content_login'}
|
51
49
|
response = s.get(url, params=para_login)
|
52
50
|
response.raise_for_status()
|
53
51
|
soup = BeautifulSoup(response.text, 'lxml')
|
@@ -72,8 +70,7 @@ def sign_in_love_ocean(email, password):
|
|
72
70
|
|
73
71
|
def _login():
|
74
72
|
url = 'https://www.52ocean.cn/member.php?'
|
75
|
-
mydata['password'] = hashlib.md5(
|
76
|
-
mydata['password'].encode()).hexdigest()
|
73
|
+
mydata['password'] = hashlib.md5(mydata['password'].encode()).hexdigest()
|
77
74
|
credentials = {
|
78
75
|
'password': mydata['password'],
|
79
76
|
}
|
@@ -103,8 +100,7 @@ def sign_in_love_ocean(email, password):
|
|
103
100
|
'Referer': 'https://www.52ocean.cn/member.php?',
|
104
101
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36'
|
105
102
|
}
|
106
|
-
response = s.post(url, params=query_params,
|
107
|
-
data=from_data, headers=head)
|
103
|
+
response = s.post(url, params=query_params, data=from_data, headers=head)
|
108
104
|
if '欢迎' in response.text:
|
109
105
|
print(' [bold green]登录成功')
|
110
106
|
try:
|
@@ -146,8 +142,7 @@ def sign_in_love_ocean(email, password):
|
|
146
142
|
print(f'[bold blue]{k}: [bold green]{v}')
|
147
143
|
print('[bold blue]------------------------------')
|
148
144
|
|
149
|
-
mydata = {'username': None,
|
150
|
-
'email': email, 'password': password} # 不要修改关键字
|
145
|
+
mydata = {'username': None, 'email': email, 'password': password} # 不要修改关键字
|
151
146
|
s = requests.Session()
|
152
147
|
print('[bold purple]-----------吾爱海洋-----------')
|
153
148
|
cookie = _login()
|