oafuncs 0.0.97.12__py3-none-any.whl → 0.0.97.14__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.
@@ -13,9 +13,6 @@ SystemInfo: Windows 11
13
13
  Python Version: 3.12
14
14
  """
15
15
 
16
-
17
-
18
-
19
16
  import datetime
20
17
  import os
21
18
  import random
@@ -711,13 +708,13 @@ def _download_file(target_url, store_path, file_name, check=False):
711
708
  file_name_split = file_name_split[:-1]
712
709
  # same_file = f"{file_name_split[0]}_{file_name_split[1]}*nc"
713
710
  same_file = "_".join(file_name_split) + "*nc"
714
-
711
+
715
712
  if match_time is not None:
716
713
  if check_nc(fname):
717
714
  if not _check_ftime(fname, if_print=True):
718
715
  if match_time:
719
716
  _correct_time(fname)
720
- count_dict['skip'] += 1
717
+ count_dict["skip"] += 1
721
718
  else:
722
719
  _clear_existing_file(fname)
723
720
  # print(f"[bold #ffe5c0]File time error, {fname}")
@@ -997,7 +994,7 @@ def _done_callback(future, progress, task, total, counter_lock):
997
994
  global parallel_counter
998
995
  with counter_lock:
999
996
  parallel_counter += 1
1000
- progress.update(task, advance=1, description=f"[cyan]Downloading... {parallel_counter}/{total}")
997
+ progress.update(task, advance=1, description=f"[cyan]{bar_desc} {parallel_counter}/{total}")
1001
998
 
1002
999
 
1003
1000
  def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_min=-80, lat_max=90, depth=None, level=None, store_path=None, dataset_name=None, version_name=None, num_workers=None, check=False, ftimes=1, interval_hour=3):
@@ -1034,19 +1031,19 @@ def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_mi
1034
1031
  print("Downloading a series of files...")
1035
1032
  time_list = get_time_list(ymdh_time_s, ymdh_time_e, interval_hour, "hour")
1036
1033
  with Progress() as progress:
1037
- task = progress.add_task("[cyan]Downloading...", total=len(time_list))
1034
+ task = progress.add_task(f"[cyan]{bar_desc}", total=len(time_list))
1038
1035
  if ftimes == 1:
1039
1036
  if num_workers is None or num_workers <= 1:
1040
1037
  # 串行方式
1041
1038
  for i, time_str in enumerate(time_list):
1042
1039
  _prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, None, depth, level, store_path, dataset_name, version_name, check)
1043
- progress.update(task, advance=1, description=f"[cyan]Downloading... {i + 1}/{len(time_list)}")
1040
+ progress.update(task, advance=1, description=f"[cyan]{bar_desc} {i + 1}/{len(time_list)}")
1044
1041
  else:
1045
1042
  # 并行方式
1046
1043
  with ThreadPoolExecutor(max_workers=num_workers) as executor:
1047
1044
  futures = [executor.submit(_download_task, var, time_str, None, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check) for time_str in time_list]
1048
1045
  """ for i, future in enumerate(futures):
1049
- future.add_done_callback(lambda _: progress.update(task, advance=1, description=f"[cyan]Downloading... {i+1}/{len(time_list)}")) """
1046
+ future.add_done_callback(lambda _: progress.update(task, advance=1, description=f"[cyan]{bar_desc} {i+1}/{len(time_list)}")) """
1050
1047
  for feature in as_completed(futures):
1051
1048
  _done_callback(feature, progress, task, len(time_list), counter_lock)
1052
1049
  else:
@@ -1059,13 +1056,13 @@ def _download_hourly_func(var, time_s, time_e, lon_min=0, lon_max=359.92, lat_mi
1059
1056
  time_str_end_index = int(min(len(time_list) - 1, int(i * ftimes + ftimes - 1)))
1060
1057
  time_str_end = time_list[time_str_end_index]
1061
1058
  _prepare_url_to_download(var, lon_min, lon_max, lat_min, lat_max, time_str, time_str_end, depth, level, store_path, dataset_name, version_name, check)
1062
- progress.update(task, advance=1, description=f"[cyan]Downloading... {i + 1}/{total_num}")
1059
+ progress.update(task, advance=1, description=f"[cyan]{bar_desc} {i + 1}/{total_num}")
1063
1060
  else:
1064
1061
  # 并行方式
1065
1062
  with ThreadPoolExecutor(max_workers=num_workers) as executor:
1066
1063
  futures = [executor.submit(_download_task, var, new_time_list[i], time_list[int(min(len(time_list) - 1, int(i * ftimes + ftimes - 1)))], lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, check) for i in range(total_num)]
1067
1064
  """ for i, future in enumerate(futures):
1068
- future.add_done_callback(lambda _: progress.update(task, advance=1, description=f"[cyan]Downloading... {i+1}/{total_num}")) """
1065
+ future.add_done_callback(lambda _: progress.update(task, advance=1, description=f"[cyan]{bar_desc} {i+1}/{total_num}")) """
1069
1066
  for feature in as_completed(futures):
1070
1067
  _done_callback(feature, progress, task, len(time_list), counter_lock)
1071
1068
  else:
@@ -1100,6 +1097,9 @@ def download(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_min=-80, l
1100
1097
  Returns:
1101
1098
  None
1102
1099
  """
1100
+ from oafuncs.oa_data import pbar
1101
+ from oafuncs.oa_cmap import get as get_cmap
1102
+
1103
1103
  _get_initial_data()
1104
1104
 
1105
1105
  # 打印信息并处理数据集和版本名称
@@ -1166,57 +1166,71 @@ def download(var, time_s, time_e=None, lon_min=0, lon_max=359.92, lat_min=-80, l
1166
1166
 
1167
1167
  global fsize_dict_lock
1168
1168
  fsize_dict_lock = Lock()
1169
-
1169
+
1170
1170
  if fill_time is not None:
1171
1171
  num_workers = 1
1172
1172
 
1173
- global use_idm, given_idm_engine, idm_download_list
1173
+ global use_idm, given_idm_engine, idm_download_list, bar_desc
1174
1174
  if idm_engine is not None:
1175
1175
  use_idm = True
1176
1176
  num_workers = 1
1177
1177
  given_idm_engine = idm_engine
1178
1178
  idm_download_list = []
1179
+ bar_desc = "Submitting to IDM ..."
1179
1180
  else:
1180
1181
  use_idm = False
1182
+ bar_desc = "Downloading ..."
1181
1183
 
1182
1184
  global match_time
1183
1185
  match_time = fill_time
1184
-
1186
+
1185
1187
  global mark_len
1186
- mark_len = 150
1188
+ mark_len = 100
1187
1189
 
1188
1190
  _download_hourly_func(var, time_s, time_e, lon_min, lon_max, lat_min, lat_max, depth, level, store_path, dataset_name, version_name, num_workers, check, ftimes, int(interval_hour))
1189
1191
 
1190
1192
  if idm_engine is not None:
1191
1193
  print("[bold #ecdbfe]*" * mark_len)
1192
- print("[bold #3dfc40]All files have been submitted to IDM for downloading")
1194
+ str_info = "All files have been submitted to IDM for downloading"
1195
+ str_info = str_info.center(mark_len, "*")
1196
+ print(f"[bold #3dfc40]{str_info}")
1193
1197
  print("[bold #ecdbfe]*" * mark_len)
1194
1198
  if idm_download_list:
1195
- file_download_time = 60 # 预设下载时间为1分钟
1196
- for f in idm_download_list:
1199
+ """ file_download_time = 60 # 预设下载时间为1分钟
1200
+ for f in pbar(idm_download_list,cmap='bwr',prefix='HYCOM: '):
1197
1201
  file_download_start_time = time.time()
1198
1202
  wait_success = 0
1199
1203
  success = False
1200
1204
  while not success:
1201
- if check_nc(f):
1205
+ if check_nc(f,print_switch=False):
1202
1206
  count_dict["success"] += 1
1203
1207
  success = True
1204
- print(f"[bold #3dfc40]File [bold #dfff73]{f} [#3dfc40]has been downloaded successfully")
1208
+ # print(f"[bold #3dfc40]File [bold #dfff73]{f} [#3dfc40]has been downloaded successfully")
1205
1209
  file_download_end_time = time.time()
1206
1210
  file_download_time = file_download_end_time - file_download_start_time
1207
1211
  file_download_time = int(file_download_time)
1208
- print(f"[bold #3dfc40]Time: {file_download_time} seconds")
1209
- file_download_time = max(60, file_download_time) # 预设下载时间为1分钟起步
1212
+ # print(f"[bold #3dfc40]Time: {file_download_time} seconds")
1213
+ file_download_time = max(60, file_download_time) # 预设下载时间为1分钟起步
1210
1214
  else:
1211
1215
  wait_success += 1
1212
- print(f"[bold #ffe5c0]Waiting {file_download_time} seconds to check the file {f}...")
1216
+ # print(f"[bold #ffe5c0]Waiting {file_download_time} seconds to check the file {f}...")
1213
1217
  time.sleep(file_download_time)
1214
1218
  if wait_success >= 10:
1215
1219
  success = True
1216
1220
  # print(f'{f} download failed')
1217
- print(f'[bold #ffe5c0]Waiting for more than 10 times, skipping the file {f}...')
1221
+ print(f"[bold #ffe5c0]Waiting for more than 10 times, skipping the file {f}...")
1218
1222
  count_dict["fail"] += 1
1219
- print('[bold #ecdbfe]-' * mark_len)
1223
+ # print("[bold #ecdbfe]-" * mark_len) """
1224
+ remain_list = idm_download_list.copy()
1225
+ for f_count in pbar(range(len(idm_download_list)), cmap=get_cmap('diverging_1'), prefix="HYCOM: "):
1226
+ success = False
1227
+ while not success:
1228
+ for f in remain_list:
1229
+ if check_nc(f, print_switch=False):
1230
+ count_dict["success"] += 1
1231
+ success = True
1232
+ remain_list.remove(f)
1233
+ break
1220
1234
 
1221
1235
  count_dict["total"] = count_dict["success"] + count_dict["fail"] + count_dict["skip"] + count_dict["no_data"]
1222
1236
  print("[bold #ecdbfe]=" * mark_len)
oafuncs/oa_down/idm.py CHANGED
@@ -4,7 +4,7 @@
4
4
  Author: Liu Kun && 16031215@qq.com
5
5
  Date: 2025-03-27 16:51:26
6
6
  LastEditors: Liu Kun && 16031215@qq.com
7
- LastEditTime: 2025-04-01 16:09:03
7
+ LastEditTime: 2025-04-01 22:31:39
8
8
  FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_down\\idm.py
9
9
  Description:
10
10
  EditPlatform: vscode
@@ -13,9 +13,11 @@ SystemInfo: Windows 11
13
13
  Python Version: 3.12
14
14
  """
15
15
 
16
+
16
17
  import datetime
17
18
  import os
18
19
  from subprocess import call
20
+
19
21
  from rich import print
20
22
 
21
23
  __all__ = ["downloader"]
@@ -50,6 +52,6 @@ def downloader(task_url, folder_path, file_name, idm_engine=r"D:\Programs\Intern
50
52
  time_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
51
53
  time_str = time_str.center(100, " ")
52
54
  print(f"[bold purple]{time_str}")
53
- print(f"[green]IDM Downloader: {file_name} download task has been added to the queue...[/green]")
55
+ print(f"[green]IDM Downloader: {file_name} download task has been added to the queue ...[/green]")
54
56
  print("[purple]*" * 100)
55
- print('\n')
57
+ print("\n")
oafuncs/oa_draw.py CHANGED
@@ -165,13 +165,19 @@ def add_lonlat_unit(lon=None, lat=None, decimal=2):
165
165
 
166
166
 
167
167
  # ** 添加网格线
168
- def add_gridlines(ax, projection=ccrs.PlateCarree(), color="k", alpha=0.5, linestyle="--", linewidth=0.5):
168
+ def add_gridlines(ax, xline=None, yline=None, projection=ccrs.PlateCarree(), color="k", alpha=0.5, linestyle="--", linewidth=0.5):
169
+ from matplotlib import ticker as mticker
169
170
  # add gridlines
170
171
  gl = ax.gridlines(crs=projection, draw_labels=True, linewidth=linewidth, color=color, alpha=alpha, linestyle=linestyle)
171
172
  gl.right_labels = False
172
173
  gl.top_labels = False
173
174
  gl.xformatter = LongitudeFormatter(zero_direction_label=False)
174
175
  gl.yformatter = LatitudeFormatter()
176
+
177
+ if xline is not None:
178
+ gl.xlocator = mticker.FixedLocator(np.array(xline))
179
+ if yline is not None:
180
+ gl.ylocator = mticker.FixedLocator(np.array(yline))
175
181
 
176
182
  return ax, gl
177
183
 
@@ -186,7 +192,7 @@ def add_cartopy(ax, lon=None, lat=None, projection=ccrs.PlateCarree(), gridlines
186
192
 
187
193
  # add gridlines
188
194
  if gridlines:
189
- ax, gl = add_gridlines(ax, projection)
195
+ ax, gl = add_gridlines(ax, projection=projection)
190
196
 
191
197
  # set longitude and latitude format
192
198
  lon_formatter = LongitudeFormatter(zero_direction_label=False)
oafuncs/oa_nc.py CHANGED
@@ -14,12 +14,12 @@ Python Version: 3.11
14
14
  """
15
15
 
16
16
  import os
17
+ from typing import List, Optional, Union
17
18
 
18
19
  import netCDF4 as nc
19
20
  import numpy as np
20
21
  import xarray as xr
21
22
  from rich import print
22
- from typing import Dict, List, Union
23
23
 
24
24
  __all__ = ["get_var", "extract", "save", "merge", "modify", "rename", "check", "convert_longitude", "isel", "draw"]
25
25
 
@@ -136,7 +136,18 @@ def save(file, data, varname=None, coords=None, mode="w", scale_offset_switch=Tr
136
136
  with nc.Dataset(file, mode, format="NETCDF4") as ncfile:
137
137
  # 如果 data 是 DataArray 并且没有提供 varname 和 coords
138
138
  if varname is None and coords is None and isinstance(data, xr.DataArray):
139
- data.to_netcdf(file, mode=mode)
139
+ encoding = {}
140
+ for var in data.data_vars:
141
+ scale_factor, add_offset = _calculate_scale_and_offset(data[var].values)
142
+ encoding[var] = {
143
+ "zlib": True,
144
+ "complevel": 4,
145
+ "dtype": "int16",
146
+ "scale_factor": scale_factor,
147
+ "add_offset": add_offset,
148
+ "_FillValue": -32767,
149
+ }
150
+ data.to_netcdf(file, mode=mode, encoding=encoding)
140
151
  return
141
152
 
142
153
  # 添加坐标
@@ -182,29 +193,10 @@ def save(file, data, varname=None, coords=None, mode="w", scale_offset_switch=Tr
182
193
  var.setncattr(key, value)
183
194
 
184
195
 
185
- def merge(file_list: Union[str, List[str]], var_name: Union[str, List[str], None] = None, dim_name: str = "time", target_filename: str = "merged.nc", chunk_config: Dict = {"time": 1000}, compression: Union[bool, Dict] = True, sanity_check: bool = True, overwrite: bool = True, parallel: bool = True) -> None:
186
- """
187
- NetCDF合并函数
188
-
189
- Parameters:
190
- file_list: 文件路径列表或单个文件路径
191
- var_name: 需要合并的变量(单个变量名/变量列表/None表示全部)
192
- dim_name: 合并维度,默认为'time'
193
- target_filename: 输出文件路径
194
- chunk_config: Dask分块配置,如{"time": 1000}
195
- compression: 压缩配置(True启用默认压缩,或自定义编码字典)
196
- sanity_check: 是否执行数据完整性校验
197
- overwrite: 是否覆盖已存在文件
198
- parallel: 是否启用并行处理
196
+ def merge(file_list: Union[str, List[str]], var_name: Optional[Union[str, List[str]]] = None, dim_name: Optional[str] = None, target_filename: Optional[str] = None) -> None:
197
+ from ._script.netcdf_merge import merge_nc
199
198
 
200
- Example:
201
- merge(["data1.nc", "data2.nc"],
202
- var_name=["temp", "salt"],
203
- target_filename="result.nc",
204
- chunk_config={"time": 500})
205
- """
206
- from ._script.netcdf_merge import merge as nc_merge
207
- nc_merge(file_list, var_name, dim_name, target_filename, chunk_config, compression, sanity_check, overwrite, parallel)
199
+ merge_nc(file_list, var_name, dim_name, target_filename)
208
200
 
209
201
 
210
202
  def _modify_var(nc_file_path, variable_name, new_value):
@@ -230,8 +222,7 @@ def _modify_var(nc_file_path, variable_name, new_value):
230
222
  variable = dataset.variables[variable_name]
231
223
  # Check if the shape of the new value matches the variable's shape
232
224
  if variable.shape != new_value.shape:
233
- raise ValueError(f"Shape mismatch: Variable '{variable_name}' has shape {variable.shape}, "
234
- f"but new value has shape {new_value.shape}.")
225
+ raise ValueError(f"Shape mismatch: Variable '{variable_name}' has shape {variable.shape}, but new value has shape {new_value.shape}.")
235
226
  # Modify the value of the variable
236
227
  variable[:] = new_value
237
228
  print(f"Successfully modified variable '{variable_name}' in '{nc_file_path}'.")
@@ -264,8 +255,7 @@ def _modify_attr(nc_file_path, variable_name, attribute_name, attribute_value):
264
255
  variable.setncattr(attribute_name, attribute_value)
265
256
  print(f"Successfully modified attribute '{attribute_name}' of variable '{variable_name}' in '{nc_file_path}'.")
266
257
  except Exception as e:
267
- print(f"[red]Error:[/red] Failed to modify attribute '{attribute_name}' of variable '{variable_name}' "
268
- f"in file '{nc_file_path}'. [bold]Details:[/bold] {e}")
258
+ print(f"[red]Error:[/red] Failed to modify attribute '{attribute_name}' of variable '{variable_name}' in file '{nc_file_path}'. [bold]Details:[/bold] {e}")
269
259
 
270
260
 
271
261
  def modify(nc_file, var_name, attr_name=None, new_value=None):
@@ -328,7 +318,7 @@ def rename(ncfile_path, old_name, new_name):
328
318
  print(f"An error occurred: {e}")
329
319
 
330
320
 
331
- def check(ncfile: str, delete_switch: bool = False) -> bool:
321
+ def check(ncfile: str, delete_switch: bool = False, print_switch: bool = True) -> bool:
332
322
  """
333
323
  Check if a NetCDF file is corrupted with enhanced error handling.
334
324
 
@@ -337,9 +327,10 @@ def check(ncfile: str, delete_switch: bool = False) -> bool:
337
327
  is_valid = False
338
328
 
339
329
  if not os.path.exists(ncfile):
340
- print(f"[#ffeac5]Local file missing: [#009d88]{ncfile}")
341
- # 提示:提示文件缺失也许是正常的,这只是检查文件是否存在于本地
342
- print("[#d6d9fd]Note: File missing may be normal, this is just to check if the file exists locally.")
330
+ if print_switch:
331
+ print(f"[#ffeac5]Local file missing: [#009d88]{ncfile}")
332
+ # 提示:提示文件缺失也许是正常的,这只是检查文件是否存在于本地
333
+ print("[#d6d9fd]Note: File missing may be normal, this is just to check if the file exists locally.")
343
334
  return False
344
335
 
345
336
  try:
@@ -352,7 +343,8 @@ def check(ncfile: str, delete_switch: bool = False) -> bool:
352
343
  # 二次验证确保变量可访问
353
344
  with nc.Dataset(ncfile, "r") as ds_verify:
354
345
  if not ds_verify.variables:
355
- print(f"Empty variables: {ncfile}")
346
+ if print_switch:
347
+ print(f"[red]Empty variables: {ncfile}[/red]")
356
348
  else:
357
349
  # 尝试访问元数据
358
350
  _ = ds_verify.__dict__
@@ -363,19 +355,23 @@ def check(ncfile: str, delete_switch: bool = False) -> bool:
363
355
  is_valid = True
364
356
 
365
357
  except Exception as e: # 捕获所有异常类型
366
- print(f"HDF5 validation failed for {ncfile}: {str(e)}")
358
+ if print_switch:
359
+ print(f"[red]HDF5 validation failed for {ncfile}: {str(e)}[/red]")
367
360
  error_type = type(e).__name__
368
361
  if "HDF5" in error_type or "h5" in error_type.lower():
369
- print(f"Critical HDF5 structure error detected in {ncfile}")
362
+ if print_switch:
363
+ print(f"[red]Critical HDF5 structure error detected in {ncfile}[/red]")
370
364
 
371
365
  # 安全删除流程
372
366
  if not is_valid:
373
367
  if delete_switch:
374
368
  try:
375
369
  os.remove(ncfile)
376
- print(f"Removed corrupted: {ncfile}")
370
+ if print_switch:
371
+ print(f"[red]Removed corrupted file: {ncfile}[/red]")
377
372
  except Exception as del_error:
378
- print(f"Delete failed: {ncfile} - {str(del_error)}")
373
+ if print_switch:
374
+ print(f"[red]Failed to delete corrupted file: {ncfile} - {str(del_error)}[/red]")
379
375
  return False
380
376
 
381
377
  return True
@@ -429,7 +425,7 @@ def isel(ncfile, dim_name, slice_list):
429
425
  return ds_new
430
426
 
431
427
 
432
- def draw(output_dir=None, dataset=None, ncfile=None, xyzt_dims=("longitude", "latitude", "level", "time"), plot_type="contourf",fixed_colorscale=False):
428
+ def draw(output_dir=None, dataset=None, ncfile=None, xyzt_dims=("longitude", "latitude", "level", "time"), plot_type="contourf", fixed_colorscale=False):
433
429
  """
434
430
  Description:
435
431
  Draw the data in the netCDF file
@@ -448,6 +444,7 @@ def draw(output_dir=None, dataset=None, ncfile=None, xyzt_dims=("longitude", "la
448
444
  draw(ncfile, output_dir, x_dim="longitude", y_dim="latitude", z_dim="level", t_dim="time", fixed_colorscale=False)
449
445
  """
450
446
  from ._script.plot_dataset import func_plot_dataset
447
+
451
448
  if output_dir is None:
452
449
  output_dir = str(os.getcwd())
453
450
  if isinstance(xyzt_dims, (list, tuple)):
oafuncs/oa_tool.py ADDED
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env python
2
+ # coding=utf-8
3
+ """
4
+ Author: Liu Kun && 16031215@qq.com
5
+ Date: 2025-04-04 20:17:42
6
+ LastEditors: Liu Kun && 16031215@qq.com
7
+ LastEditTime: 2025-04-04 20:17:45
8
+ FilePath: \\Python\\My_Funcs\\OAFuncs\\oafuncs\\oa_tool.py
9
+ Description:
10
+ EditPlatform: vscode
11
+ ComputerInfo: XPS 15 9510
12
+ SystemInfo: Windows 11
13
+ Python Version: 3.12
14
+ """
15
+ from typing import Iterable
16
+
17
+ __all__ = ["PEx", "email", "pbar"]
18
+
19
+ class PEx:
20
+ """
21
+ PEx 封装了 ParallelExecutor,
22
+ 并将其方法全部委托,使得直接调用 PEx 的方法能够达到与 ParallelExecutor 相同的效果。
23
+
24
+ 示例:
25
+ # 创建 PEx 实例
26
+ executor = PEx(max_workers=4)
27
+
28
+ # 使用 run 方法执行并行任务
29
+ result = executor.run(lambda x: x * x, [(i,) for i in range(5)])
30
+ print(result) # 输出: [0, 1, 4, 9, 16]
31
+ """
32
+
33
+ try:
34
+ from ._script.parallel import ParallelExecutor
35
+ except ImportError:
36
+ raise ImportError("ParallelExecutor could not be imported. Ensure the module '_script.parallel' exists and is accessible.")
37
+
38
+ def __init__(self, *args, **kwargs):
39
+ """
40
+ 初始化 PEx 实例,内部创建一个 ParallelExecutor 实例。
41
+
42
+ 参数:
43
+ *args: 传递给 ParallelExecutor 的位置参数。
44
+ **kwargs: 传递给 ParallelExecutor 的关键字参数。
45
+ """
46
+ self.executor = self.ParallelExecutor(*args, **kwargs)
47
+
48
+ def __getattr__(self, attr):
49
+ """
50
+ 将所有未定义的属性访问委托给内部的 ParallelExecutor 实例。
51
+
52
+ 参数:
53
+ attr (str): 要访问的属性名称。
54
+
55
+ 返回:
56
+ 对应属性的值。
57
+ """
58
+ return getattr(self.executor, attr)
59
+
60
+
61
+ def email(title="Title", content=None, send_to="16031215@qq.com"):
62
+ from ._script.email import send
63
+ send(title, content, send_to)
64
+
65
+
66
+ def pbar(iterable: Iterable, description: str = "Working ...", color: str = "cyan", cmap: str = None, lupdate_interval: float = 0.1, bar_length: int = None, **kwargs) -> Iterable:
67
+ """
68
+ 快速创建进度条的封装函数
69
+ :param iterable: 可迭代对象
70
+ :param prefix: 进度条前缀
71
+ :param color: 基础颜色
72
+ :param cmap: 渐变色名称
73
+ :param kwargs: 其他ColorProgressBar支持的参数
74
+
75
+ example:
76
+ from oafuncs.oa_data import pbar
77
+ from time import sleep
78
+ for i in pbar(range(100), prefix="Processing", color="green", cmap="viridis"):
79
+ sleep(0.1)
80
+ """
81
+ from ._script.cprogressbar import ColorProgressBar
82
+
83
+ return ColorProgressBar(iterable=iterable, description=description, color=color, cmap=cmap, update_interval=lupdate_interval, bar_length=bar_length, **kwargs)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oafuncs
3
- Version: 0.0.97.12
3
+ Version: 0.0.97.14
4
4
  Summary: Oceanic and Atmospheric Functions
5
5
  Home-page: https://github.com/Industry-Pays/OAFuncs
6
6
  Author: Kun Liu
@@ -1,24 +1,26 @@
1
1
  oafuncs/__init__.py,sha256=T_-VtnWWllV3Q91twT5Yt2sUapeA051QbPNnBxmg9nw,1456
2
2
  oafuncs/oa_cmap.py,sha256=OfJ2DOBOGX5X1GihE6CPcTV8bAFdDqJSXV7vbqUgV9s,7552
3
- oafuncs/oa_data.py,sha256=7Mm2tFpKScs7TDgPiHDS0l_xVqb65WZvuQJCZ9BbK5Y,12953
4
- oafuncs/oa_date.py,sha256=--3uXYq3_n9HBJbY1io1H1PE-FyiVxbQCyFUcudxQks,3210
5
- oafuncs/oa_draw.py,sha256=d23R6OEco7EbvcrL5YsnrSupnKKUn55hLw1B_d-kxOg,12308
3
+ oafuncs/oa_data.py,sha256=j_z4dOgugqyxc9STMTMZ0hKA46RyWgNtJeVWFaC8LPc,12141
4
+ oafuncs/oa_date.py,sha256=JnXZV1_kb0NO9vRHBOPJBDGV67JkYfMalavGfCGyr0I,3826
5
+ oafuncs/oa_draw.py,sha256=mpDiyVMi8-CDfbWWnuE8uXt0aShpW_7AgiBDkb1Mrvk,12571
6
6
  oafuncs/oa_file.py,sha256=nYTsMataaC790lSqxjuMB4uVqUJz_tMm_kRve4CHql4,17235
7
7
  oafuncs/oa_help.py,sha256=loyzTbjU_0VpSIBvAEUA_tqxG8MVsO0xFE_2hgQ3zMw,4188
8
- oafuncs/oa_nc.py,sha256=xouqfEFa1eSExP_ad09JQM5b0rpfPAHEFB7ctg7DkPE,18718
8
+ oafuncs/oa_nc.py,sha256=Ba1weu1lA6YUkmZ676z2iK1WAwX95cr4_DRrskoDTjo,18477
9
9
  oafuncs/oa_python.py,sha256=Q-6UGGw_dJff7Ef8i87fsLPoGeHV5jBzfb-7HP4THR0,4018
10
+ oafuncs/oa_tool.py,sha256=8B2cyZ4l3XrWbDMkMKAlvWaiQGP_FKLKVJaqbu6G4uU,2782
10
11
  oafuncs/_data/OAFuncs.png,sha256=y1_x-mUP3gFjcy6m8FqfvQO_HgjzPhQKfXjnSHjslZE,3436152
11
12
  oafuncs/_data/hycom_3hourly.png,sha256=azt_uPcXtl_8CSKRLLPCIf5pPrcxMiOzvoFQnwb0zUo,12411415
12
- oafuncs/_script/auto_optimized_parallel_executor.py,sha256=4QaEk9AM-IneHm8KKSQ6MjSLNSaAWM4AQ-8OWXYdsaI,17300
13
- oafuncs/_script/cprogressbar.py,sha256=F3LlFsKojP58mqcAqHRw3u-ffftXaYiN5dKj7zDi0iI,5658
14
- oafuncs/_script/netcdf_merge.py,sha256=mKHnjStCqP7bwUMVA5k9ZKwT1ZVv1PR-ehMKdpHMJ4s,14439
13
+ oafuncs/_script/cprogressbar.py,sha256=bDIb99JqCHwIZKsrRXLfqiArTuNUuG9GyestphJM43I,15491
14
+ oafuncs/_script/email.py,sha256=lL4HGKrr524-g0xLlgs-4u7x4-u7DtgNoD9AL8XJKj4,3058
15
+ oafuncs/_script/netcdf_merge.py,sha256=KYQ6ulXSjYEmcH5EhGRRZjNrU2uqyQPIaAWljKJdUsk,5088
16
+ oafuncs/_script/parallel.py,sha256=FS9FgaByq2yb9j6nL-Y0xP1VLvp4USMLBFMRsJDoqeQ,21848
15
17
  oafuncs/_script/parallel_example_usage.py,sha256=uLvE7iwkMn9Cyq6-wk5_RpbQk7PXM9d16-26lTknW9s,2646
16
18
  oafuncs/_script/plot_dataset.py,sha256=zkSEnO_-biyagorwWXPoihts_cwuvripzEt-l9bHJ2E,13989
17
19
  oafuncs/_script/replace_file_concent.py,sha256=eCFZjnZcwyRvy6b4mmIfBna-kylSZTyJRfgXd6DdCjk,5982
18
20
  oafuncs/oa_down/User_Agent-list.txt,sha256=pazxSip8_lphEBOPHG902zmIBUg8sBKXgmqp_g6j_E4,661062
19
21
  oafuncs/oa_down/__init__.py,sha256=kRX5eTUCbAiz3zTaQM1501paOYS_3fizDN4Pa0mtNUA,585
20
- oafuncs/oa_down/hycom_3hourly.py,sha256=TnLyXEFJthl4NOeuCXW5DM-h0T6JxhIVATW7XOC4sqw,66837
21
- oafuncs/oa_down/idm.py,sha256=pqktP4aKDxR3k8XLy9ceQQovvb4jjjT1VGF955PHIG8,1898
22
+ oafuncs/oa_down/hycom_3hourly.py,sha256=uLXKioUQO_UtXtXFa4MWolr4a6AQiI1bf-s7NuQGA-U,67661
23
+ oafuncs/oa_down/idm.py,sha256=6eKsbGZ91_187_jJawUc6lqKRdUTse6EfUJnlaSl5mo,1903
22
24
  oafuncs/oa_down/literature.py,sha256=2bF9gSKQbzcci9LcKE81j8JEjIJwON7jbwQB3gDDA3E,11331
23
25
  oafuncs/oa_down/test_ua.py,sha256=0IQq3NjqfNr7KkyjS_U-a4mYu-r-E7gzawwo4IfEa6Y,10851
24
26
  oafuncs/oa_down/user_agent.py,sha256=TsPcAxFmMTYAEHRFjurI1bQBJfDhcA70MdHoUPwQmks,785
@@ -31,11 +33,8 @@ oafuncs/oa_sign/__init__.py,sha256=QKqTFrJDFK40C5uvk48GlRRbGFzO40rgkYwu6dYxatM,5
31
33
  oafuncs/oa_sign/meteorological.py,sha256=mLbupsZSq427HTfVbZMvIlFzDHwSzQAbK3X19o8anFY,6525
32
34
  oafuncs/oa_sign/ocean.py,sha256=xrW-rWD7xBWsB5PuCyEwQ1Q_RDKq2KCLz-LOONHgldU,5932
33
35
  oafuncs/oa_sign/scientific.py,sha256=a4JxOBgm9vzNZKpJ_GQIQf7cokkraV5nh23HGbmTYKw,5064
34
- oafuncs/oa_tool/__init__.py,sha256=AvrCNR2-xad9ZRjthIdAoSk8UX4vOpEWLg6CV1NQNKc,161
35
- oafuncs/oa_tool/email.py,sha256=4lJxV_KUzhxgLYfVwYTqp0qxRugD7fvsZkXDe5WkUKo,3052
36
- oafuncs/oa_tool/parallel.py,sha256=LBFWEKPcILVCbfSulETJE4wGPiOw1P_Fl9DzjYoCqgk,21844
37
- oafuncs-0.0.97.12.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
38
- oafuncs-0.0.97.12.dist-info/METADATA,sha256=sWGGWvxD_dWTX6bNz5sdMoJe4r3-GemQnSJY2P79dFw,4226
39
- oafuncs-0.0.97.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
40
- oafuncs-0.0.97.12.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
41
- oafuncs-0.0.97.12.dist-info/RECORD,,
36
+ oafuncs-0.0.97.14.dist-info/licenses/LICENSE.txt,sha256=rMtLpVg8sKiSlwClfR9w_Dd_5WubTQgoOzE2PDFxzs4,1074
37
+ oafuncs-0.0.97.14.dist-info/METADATA,sha256=qMRlMGKHZEVI507q3lCtUN_e2rEOohFvXqCeReL6pf0,4226
38
+ oafuncs-0.0.97.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
39
+ oafuncs-0.0.97.14.dist-info/top_level.txt,sha256=bgC35QkXbN4EmPHEveg_xGIZ5i9NNPYWqtJqaKqTPsQ,8
40
+ oafuncs-0.0.97.14.dist-info/RECORD,,