ccfx 1.0.7__tar.gz → 1.0.8__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ccfx
3
- Version: 1.0.7
3
+ Version: 1.0.8
4
4
  Summary: This package simplifies regular common actions for quick prototyping in a user friendly way
5
5
  Author-email: Celray James CHAWANDA <celray@chawanda.com>
6
6
  License-Expression: MIT
@@ -35,7 +35,7 @@ import math
35
35
  import requests
36
36
  from tqdm import tqdm
37
37
  import yt_dlp
38
- from typing import Optional
38
+ from typing import Optional, Any
39
39
  from datetime import datetime, timedelta
40
40
  from PIL import Image
41
41
 
@@ -72,7 +72,7 @@ def getExtension(filePath:str) -> str:
72
72
  return os.path.splitext(filePath)[1].lstrip('.')
73
73
 
74
74
 
75
- def getMp3Metadata(fn, imagePath=None):
75
+ def getMp3Metadata(fn: str, imagePath: Optional[str] = None) -> dict:
76
76
  '''
77
77
  This function takes a path to mp3 and returns a dictionary with
78
78
  the following keys:
@@ -127,7 +127,7 @@ def getMp3Metadata(fn, imagePath=None):
127
127
  return metadata
128
128
 
129
129
 
130
- def guessMimeType(imagePath):
130
+ def guessMimeType(imagePath: str) -> str:
131
131
  ext = os.path.splitext(imagePath.lower())[1]
132
132
  if ext in ['.jpg', '.jpeg']:
133
133
  return 'image/jpeg'
@@ -240,7 +240,7 @@ def parseYoutubeChannelVideos(channelUrl: str, maxItems: Optional[int] = None) -
240
240
  return [f"https://www.youtube.com/watch?v={e['id']}" for e in entries if e.get("id")]
241
241
 
242
242
 
243
- def runSWATPlus(txtinoutDir: str, finalDir: str, executablePath: str = "swatplus", v: bool = True):
243
+ def runSWATPlus(txtinoutDir: str, finalDir: str, executablePath: str = "swatplus", v: bool = True) -> None:
244
244
  os.chdir(txtinoutDir)
245
245
 
246
246
  if not v:
@@ -339,7 +339,7 @@ def formatTimedelta(delta: timedelta) -> str:
339
339
  return f"{time_fmt}"
340
340
 
341
341
 
342
- def setMp3Metadata(fn, metadata, imagePath=None):
342
+ def setMp3Metadata(fn: str, metadata: dict, imagePath: Optional[str] = None) -> bool:
343
343
  '''
344
344
  This function takes a path to an mp3 and a metadata dictionary,
345
345
  then writes that metadata to the file's ID3 tags.
@@ -434,7 +434,7 @@ def deleteFile(filePath:str, v:bool = False) -> bool:
434
434
 
435
435
  return deleted
436
436
 
437
- def removeImageColour(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30):
437
+ def removeImageColour(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30) -> None:
438
438
  '''
439
439
  Remove a specific color from an image.
440
440
  colour: RGB tuple, e.g., (255, 0, 0) for red
@@ -457,7 +457,7 @@ def removeImageColour(inPath:str, outPath:str, colour:tuple = (255, 255, 255), t
457
457
  img.putdata(new_data)
458
458
  img.save(outPath)
459
459
 
460
- def makeTransparent(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30):
460
+ def makeTransparent(inPath:str, outPath:str, colour:tuple = (255, 255, 255), tolerance:int = 30) -> None:
461
461
  '''
462
462
  Make some pixels in an image transparent.
463
463
  '''
@@ -519,7 +519,7 @@ def deletePath(path:str, v:bool = False) -> bool:
519
519
  deleted = False
520
520
 
521
521
 
522
- def downloadChunk(url, start, end, path):
522
+ def downloadChunk(url: str, start: int, end: int, path: str) -> None:
523
523
  headers = {'Range': f'bytes={start}-{end}'}
524
524
  response = requests.get(url, headers=headers, stream=True)
525
525
  with open(path, 'wb') as f:
@@ -528,7 +528,7 @@ def downloadChunk(url, start, end, path):
528
528
  f.write(chunk)
529
529
 
530
530
 
531
- def formatStringBlock(input_str, max_chars=70):
531
+ def formatStringBlock(input_str: str, max_chars: int = 70) -> str:
532
532
  '''
533
533
  This function takes a string and formats it into a block of text
534
534
  with a maximum number of characters per line.
@@ -559,7 +559,7 @@ def formatStringBlock(input_str, max_chars=70):
559
559
 
560
560
 
561
561
 
562
- def downloadFile(url, save_path, exists_action='resume', num_connections=5, v=False):
562
+ def downloadFile(url: str, save_path: str, exists_action: str = 'resume', num_connections: int = 5, v: bool = False) -> None:
563
563
  if v:
564
564
  print(f"\ndownloading {url}")
565
565
  fname = getFileBaseName(url, extension=True)
@@ -649,7 +649,7 @@ def systemPlatform() -> str:
649
649
  '''
650
650
  return platform.system()
651
651
 
652
- def progressBar(count, total, message=""):
652
+ def progressBar(count: int, total: int, message: str = "") -> None:
653
653
  percent = int(count / total * 100)
654
654
  filled = int(percent / 2)
655
655
  bar = '█' * filled + '░' * (50 - filled)
@@ -669,7 +669,7 @@ def fileCount(path:str = "./", extension:str = ".*", v:bool = True) -> int:
669
669
  print(f'> there are {count} {extension if not extension ==".*" else ""} files in {path}')
670
670
  return count
671
671
 
672
- def resampleRaster(inFile:str, outFile:str, resolution:float, dstSRS = None, resamplingMethod = 'bilinear', replaceOutput:bool = True, v:bool = True) -> str:
672
+ def resampleRaster(inFile:str, outFile:str, resolution:float, dstSRS = None, resamplingMethod = 'bilinear', replaceOutput:bool = True, v:bool = True) -> Optional[str]:
673
673
  '''
674
674
  Resample a raster file
675
675
  inFile: input raster file
@@ -740,7 +740,7 @@ def watchFileCount(path:str="./", extension:str = ".*", interval:float = 0.2, du
740
740
  return None
741
741
 
742
742
 
743
- def pythonVariable(filename, option, variable=None):
743
+ def pythonVariable(filename: str, option: str, variable: Any = None) -> Any:
744
744
  '''
745
745
  option: save, load or open
746
746
 
@@ -774,7 +774,7 @@ def listFolders(path:str) -> list:
774
774
  else:
775
775
  return []
776
776
 
777
- def readFrom(filename, decode_codec = None, v=False):
777
+ def readFrom(filename: str, decode_codec: Optional[str] = None, v: bool = False) -> Any:
778
778
  '''
779
779
  a function to read ascii files
780
780
  '''
@@ -793,16 +793,16 @@ def readFrom(filename, decode_codec = None, v=False):
793
793
 
794
794
 
795
795
  def pointsToGeodataframe(
796
- rowList,
797
- columnNames,
798
- latIndex,
799
- lonIndex,
800
- auth = "EPSG",
801
- code = "4326",
802
- outShape = "",
803
- format = "gpkg",
804
- v = False,
805
- includeLatLon = True ) -> geopandas.GeoDataFrame:
796
+ rowList: list,
797
+ columnNames: list,
798
+ latIndex: int,
799
+ lonIndex: int,
800
+ auth: str = "EPSG",
801
+ code: str = "4326",
802
+ outShape: str = "",
803
+ format: str = "gpkg",
804
+ v: bool = False,
805
+ includeLatLon: bool = True ) -> geopandas.GeoDataFrame:
806
806
  df = pandas.DataFrame(rowList, columns = columnNames)
807
807
  geometry = [
808
808
  Point(row[lonIndex], row[latIndex]) for row in rowList
@@ -824,10 +824,10 @@ def pointsToGeodataframe(
824
824
  return gdf
825
825
 
826
826
 
827
- def readFile(filename, decode_codec = None, v=False):
827
+ def readFile(filename: str, decode_codec: Optional[str] = None, v: bool = False) -> Any:
828
828
  return readFrom(filename, decode_codec, v)
829
829
 
830
- def writeTo(filename, file_text, encode_codec = None, v=False) -> bool:
830
+ def writeTo(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool:
831
831
  '''
832
832
  a function to write ascii files
833
833
  '''
@@ -846,13 +846,13 @@ def writeTo(filename, file_text, encode_codec = None, v=False) -> bool:
846
846
  if v: print("\t> wrote {0}".format(getFileBaseName(filename, extension=True)))
847
847
  return True
848
848
 
849
- def writeToFile(filename, file_text, encode_codec = None, v=False) -> bool:
849
+ def writeToFile(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool:
850
850
  return writeTo(filename, file_text, encode_codec, v)
851
851
 
852
- def writeFile(filename, file_text, encode_codec = None, v=False) -> bool:
852
+ def writeFile(filename: str, file_text: Any, encode_codec: Optional[str] = None, v: bool = False) -> bool:
853
853
  return writeTo(filename, file_text, encode_codec, v)
854
854
 
855
- def createPath(pathName, v = False):
855
+ def createPath(pathName: str, v: bool = False) -> str:
856
856
  '''
857
857
  this function creates a directory if it does not exist
858
858
  pathName: the path to create
@@ -871,7 +871,7 @@ def createPath(pathName, v = False):
871
871
  return pathName
872
872
 
873
873
 
874
- def renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, new_var_name: str, v = False) -> None:
874
+ def renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, new_var_name: str, v: bool = False) -> None:
875
875
  """
876
876
  Renames a variable in a NetCDF file using CDO if it exists.
877
877
  If the variable does not exist, the file is copied without modification.
@@ -907,7 +907,7 @@ def renameNetCDFvariable(input_file: str, output_file: str, old_var_name: str, n
907
907
  print(f"Error: {e.stderr}")
908
908
 
909
909
 
910
- def compressTo7z(input_dir: str, output_file: str, compressionLevel: int = 4, excludeExt: list = None, v: bool = False) -> None:
910
+ def compressTo7z(input_dir: str, output_file: str, compressionLevel: int = 4, excludeExt: Optional[list] = None, v: bool = False) -> None:
911
911
  """
912
912
  Compresses the contents of a directory to a .7z archive with maximum compression.
913
913
 
@@ -1210,8 +1210,8 @@ def ignoreWarnings(ignore:bool = True, v:bool = False) -> None:
1210
1210
  return None
1211
1211
 
1212
1212
 
1213
- def createGrid(topLeft: list = None, bottomRight: list = None, resolution: float = None,
1214
- inputShape: str = None, crs: str = "EPSG:4326", saveVector: str = None) -> geopandas.GeoDataFrame:
1213
+ def createGrid(topLeft: Optional[list] = None, bottomRight: Optional[list] = None, resolution: Optional[float] = None,
1214
+ inputShape: Optional[str] = None, crs: str = "EPSG:4326", saveVector: Optional[str] = None) -> geopandas.GeoDataFrame:
1215
1215
  '''
1216
1216
  This function creates a grid of polygons based on either a shapefile or corner coordinates
1217
1217
 
@@ -1341,7 +1341,7 @@ def netcdfVariableDimensions(ncFile: str, variable: str) -> dict:
1341
1341
 
1342
1342
  return bands_info
1343
1343
 
1344
- def netcdfExportTif(ncFile: str, variable: str, outputFile: Optional[str] = None, band: int = None, v:bool = True) -> gdal.Dataset:
1344
+ def netcdfExportTif(ncFile: str, variable: str, outputFile: Optional[str] = None, band: Optional[int] = None, v:bool = True) -> gdal.Dataset:
1345
1345
  '''
1346
1346
  Export a variable from a NetCDF file to a GeoTiff file
1347
1347
  ncFile: NetCDF file
@@ -1401,8 +1401,8 @@ def netcdfSumMaps(ncFiles:list, variable:str, band:int = 1) -> numpy.ndarray:
1401
1401
  def tiffWriteArray(array: numpy.ndarray, outputFile: str,
1402
1402
  geoTransform: tuple = (0, 1, 0, 0, 0, -1),
1403
1403
  projection: str = 'EPSG:4326',
1404
- noData:float = None,
1405
- v:bool = False) -> gdal.Dataset:
1404
+ noData: Optional[float] = None,
1405
+ v: bool = False) -> gdal.Dataset:
1406
1406
  '''
1407
1407
  Write a numpy array to a GeoTIFF file
1408
1408
  array : numpy array to write
@@ -1448,7 +1448,7 @@ def copyFile(source:str, destination:str, v:bool = True) -> None:
1448
1448
  if v: print(f'> {source} copied to \t - {destination}')
1449
1449
 
1450
1450
 
1451
- def copyDirectory(source:str, destination:str, recursive = True, v:bool = True, filter = []) -> None:
1451
+ def copyDirectory(source:str, destination:str, recursive: bool = True, v:bool = True, filter: list = []) -> None:
1452
1452
  '''
1453
1453
  Copy a directory from source to destination
1454
1454
  source: source directory
@@ -1499,7 +1499,7 @@ def copyFolder(source:str, destination:str, v:bool = True) -> None:
1499
1499
  copyDirectory(source, destination, v=v)
1500
1500
 
1501
1501
 
1502
- def convertCoordinates(lon, lat, srcEPSG, dstCRS) -> tuple:
1502
+ def convertCoordinates(lon: float, lat: float, srcEPSG: str, dstCRS: str) -> tuple:
1503
1503
  """
1504
1504
  this function converts coordinates from one CRS to another
1505
1505
 
@@ -1516,7 +1516,7 @@ def convertCoordinates(lon, lat, srcEPSG, dstCRS) -> tuple:
1516
1516
  return (new_lon, new_lat)
1517
1517
 
1518
1518
 
1519
- def extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> float:
1519
+ def extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> Optional[float]:
1520
1520
  """
1521
1521
  Extract raster value at given coordinates.
1522
1522
 
@@ -1561,7 +1561,7 @@ def extractRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str =
1561
1561
  return float(value)
1562
1562
 
1563
1563
 
1564
- def getRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> float:
1564
+ def getRasterValue(rasterPath: str, lat: float, lon: float, coordProj: str = 'EPSG:4326') -> Optional[float]:
1565
1565
  '''
1566
1566
  this function is a wrapper for extractRasterValue
1567
1567
  '''
@@ -1588,9 +1588,9 @@ def showProgress(count: int, end: int, message: str, barLength: int = 100) -> No
1588
1588
  percentStr = f'{percent:03.1f}'
1589
1589
  filled = int(barLength * count / end)
1590
1590
  bar = '█' * filled + '░' * (barLength - filled)
1591
- print(f'\r{bar} {percentStr}% [{count}/{end}] | {message} ', end='', flush=True)
1591
+ print(f'\r{message} |{bar}| {percent}% [{count}/{end}]', end='', flush=True)
1592
1592
  if count == end:
1593
- print(f'\r{bar} {percentStr}% [{count}/{end}] ', end='', flush=True)
1593
+ print(f'\r{message} |{bar}| {percent}% [{count}/{end}] ', end='', flush=True)
1594
1594
  print()
1595
1595
 
1596
1596
 
@@ -1621,7 +1621,7 @@ def dualProgress(primaryCount: int, primaryEnd: int,
1621
1621
  print(f'\r{bar} {formattedPrimaryPercent.rjust(6)}% | {formattedSecondaryPercent.rjust(6)}% ', end='', flush=True)
1622
1622
 
1623
1623
 
1624
- def listAllFiles(folder, extension="*"):
1624
+ def listAllFiles(folder: str, extension: str = "*") -> list:
1625
1625
  list_of_files = []
1626
1626
  # Getting the current work directory (cwd)
1627
1627
  thisdir = folder
@@ -1643,7 +1643,7 @@ def listAllFiles(folder, extension="*"):
1643
1643
  return list_of_files
1644
1644
 
1645
1645
 
1646
- def clipFeatures(inputFeaturePath:str, boundaryFeature:str, outputFeature:str, keepOnlyTypes = None, v = False) -> geopandas.GeoDataFrame:
1646
+ def clipFeatures(inputFeaturePath:str, boundaryFeature:str, outputFeature:str, keepOnlyTypes: Optional[list] = None, v: bool = False) -> geopandas.GeoDataFrame:
1647
1647
  '''
1648
1648
  keepOnlyTypes = ['MultiPolygon', 'Polygon', 'Point', etc]
1649
1649
 
@@ -2023,7 +2023,7 @@ def getTimeseriesStats(data:pandas.DataFrame, observed:Optional[str] = None, sim
2023
2023
 
2024
2024
  return stats
2025
2025
 
2026
- def readSWATPlusOutputs(filePath: str, column: Optional[str] = None, unit: Optional[int] = None, gis_id: Optional[int] = None, name: Optional[str] = None):
2026
+ def readSWATPlusOutputs(filePath: str, column: Optional[str] = None, unit: Optional[int] = None, gis_id: Optional[int] = None, name: Optional[str] = None) -> Optional[pandas.DataFrame]:
2027
2027
  '''
2028
2028
  Read SWAT+ output files and return a pandas DataFrame with proper date handling
2029
2029
  and optional filtering capabilities.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ccfx
3
- Version: 1.0.7
3
+ Version: 1.0.8
4
4
  Summary: This package simplifies regular common actions for quick prototyping in a user friendly way
5
5
  Author-email: Celray James CHAWANDA <celray@chawanda.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ccfx"
7
- version = "1.0.7"
7
+ version = "1.0.8"
8
8
  description = "This package simplifies regular common actions for quick prototyping in a user friendly way"
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes