ras-commander 0.40.0__py3-none-any.whl → 0.41.0__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.
ras_commander/RasUtils.py CHANGED
@@ -24,12 +24,13 @@ Example:
24
24
  import os
25
25
  from pathlib import Path
26
26
  from .RasPrj import ras
27
- from typing import Union, Optional, Dict
27
+ from typing import Union, Optional, Dict, Callable
28
28
  import pandas as pd
29
29
  import numpy as np
30
30
  import shutil
31
31
  from ras_commander import get_logger
32
32
  from ras_commander.logging_config import get_logger, log_call
33
+ import re
33
34
 
34
35
  logger = get_logger(__name__)
35
36
  # Module code starts here
@@ -622,6 +623,118 @@ class RasUtils:
622
623
  logger.info(f"Calculated error metrics: {metrics}")
623
624
  return metrics
624
625
 
626
+
627
+ @staticmethod
628
+ @log_call
629
+ def update_file(file_path: Path, update_function: Callable, *args) -> None:
630
+ """
631
+ Generic method to update a file.
625
632
 
633
+ Parameters:
634
+ file_path (Path): Path to the file to be updated
635
+ update_function (Callable): Function to update the file contents
636
+ *args: Additional arguments to pass to the update_function
626
637
 
638
+ Raises:
639
+ Exception: If there's an error updating the file
627
640
 
641
+ Example:
642
+ >>> def update_content(lines, new_value):
643
+ ... lines[0] = f"New value: {new_value}\\n"
644
+ ... return lines
645
+ >>> RasUtils.update_file(Path("example.txt"), update_content, "Hello")
646
+ """
647
+ try:
648
+ with open(file_path, 'r') as f:
649
+ lines = f.readlines()
650
+
651
+ updated_lines = update_function(lines, *args) if args else update_function(lines)
652
+
653
+ with open(file_path, 'w') as f:
654
+ f.writelines(updated_lines)
655
+ logger.info(f"Successfully updated file: {file_path}")
656
+ except Exception as e:
657
+ logger.exception(f"Failed to update file {file_path}")
658
+ raise
659
+
660
+ @staticmethod
661
+ @log_call
662
+ def get_next_number(existing_numbers: list) -> str:
663
+ """
664
+ Determine the next available number from a list of existing numbers.
665
+
666
+ Parameters:
667
+ existing_numbers (list): List of existing numbers as strings
668
+
669
+ Returns:
670
+ str: Next available number as a zero-padded string
671
+
672
+ Example:
673
+ >>> RasUtils.get_next_number(["01", "02", "04"])
674
+ "05"
675
+ """
676
+ existing_numbers = sorted(int(num) for num in existing_numbers)
677
+ next_number = max(existing_numbers, default=0) + 1
678
+ return f"{next_number:02d}"
679
+
680
+ @staticmethod
681
+ @log_call
682
+ def clone_file(template_path: Path, new_path: Path, update_function: Optional[Callable] = None, *args) -> None:
683
+ """
684
+ Generic method to clone a file and optionally update it.
685
+
686
+ Parameters:
687
+ template_path (Path): Path to the template file
688
+ new_path (Path): Path where the new file will be created
689
+ update_function (Optional[Callable]): Function to update the cloned file
690
+ *args: Additional arguments to pass to the update_function
691
+
692
+ Raises:
693
+ FileNotFoundError: If the template file doesn't exist
694
+
695
+ Example:
696
+ >>> def update_content(lines, new_value):
697
+ ... lines[0] = f"New value: {new_value}\\n"
698
+ ... return lines
699
+ >>> RasUtils.clone_file(Path("template.txt"), Path("new.txt"), update_content, "Hello")
700
+ """
701
+ if not template_path.exists():
702
+ logger.error(f"Template file '{template_path}' does not exist.")
703
+ raise FileNotFoundError(f"Template file '{template_path}' does not exist.")
704
+
705
+ shutil.copy(template_path, new_path)
706
+ logger.info(f"File cloned from {template_path} to {new_path}")
707
+
708
+ if update_function:
709
+ RasUtils.update_file(new_path, update_function, *args)
710
+ @staticmethod
711
+ @log_call
712
+ def update_project_file(prj_file: Path, file_type: str, new_num: str, ras_object=None) -> None:
713
+ """
714
+ Update the project file with a new entry.
715
+
716
+ Parameters:
717
+ prj_file (Path): Path to the project file
718
+ file_type (str): Type of file being added (e.g., 'Plan', 'Geom')
719
+ new_num (str): Number of the new file entry
720
+ ras_object (RasPrj, optional): RAS object to use. If None, uses the default ras object.
721
+
722
+ Example:
723
+ >>> RasUtils.update_project_file(Path("project.prj"), "Plan", "02")
724
+ """
725
+ ras_obj = ras_object or ras
726
+ ras_obj.check_initialized()
727
+
728
+ try:
729
+ with open(prj_file, 'r') as f:
730
+ lines = f.readlines()
731
+
732
+ new_line = f"{file_type} File={file_type[0].lower()}{new_num}\n"
733
+ lines.append(new_line)
734
+
735
+ with open(prj_file, 'w') as f:
736
+ f.writelines(lines)
737
+ logger.info(f"Project file updated with new {file_type} entry: {new_num}")
738
+ except Exception as e:
739
+ logger.exception(f"Failed to update project file {prj_file}")
740
+ raise
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ras-commander
3
- Version: 0.40.0
3
+ Version: 0.41.0
4
4
  Summary: A Python library for automating HEC-RAS operations
5
5
  Home-page: https://github.com/billk-FM/ras-commander
6
6
  Author: William M. Katzenmeyer
@@ -61,10 +61,11 @@ Create a virtual environment with conda or venv (ask ChatGPT if you need help)
61
61
 
62
62
  In your virtual environment, install ras-commander using pip:
63
63
  ```
64
- pip install pandas requests pathlib
64
+ pip install h5py numpy pandas requests tqdm scipy
65
65
  pip install ras-commander
66
66
  ```
67
67
 
68
+ If you have dependency issues with pip (especially if you have errors with numpy), try clearing your local pip packages 'C:\Users\your_username\AppData\Roaming\Python\' and then creating a new virtual environment.
68
69
 
69
70
 
70
71
  ## Requirements
@@ -0,0 +1,16 @@
1
+ ras_commander/RasCmdr.py,sha256=_opzPdFuja2wXmFu2iayP6igJqGeILAavPC1XsCC6ks,25010
2
+ ras_commander/RasExamples.py,sha256=XKnbqQTc5t43iFkjJLF3lgqZW4YaGh-79sGYDAmtqiU,19245
3
+ ras_commander/RasGeo.py,sha256=GiRtgRg0JsuCDkpYS6SkJoaLksPUskHGDRpJLYVUMz8,5411
4
+ ras_commander/RasGpt.py,sha256=-524sU_PBPxCmjDKJbDXg6Q3k1-Uhk2tYj6HeW8QFJ8,4201
5
+ ras_commander/RasHdf.py,sha256=Und1QcOpuHD2dCZvxPiwNXCoEQs_XG9WFGBlNwMDDrE,32689
6
+ ras_commander/RasPlan.py,sha256=GT8-2X_Or6ufrfpQPv6G3WMLuTNsOO0OCYh1jrbsqZ0,40303
7
+ ras_commander/RasPrj.py,sha256=-iEltmz7B-wXrs4R3iuj6tXX9i-6u_yEl7ZcLmasoWs,33980
8
+ ras_commander/RasUnsteady.py,sha256=37GKaYNJZ39y-khhy01LbHwZnf7HT0V2XKQ-UUaJHlY,4639
9
+ ras_commander/RasUtils.py,sha256=vA3DzvNMeKH3A4cMQLK2a3dihftXBGypYvoi-ckMlSs,29480
10
+ ras_commander/__init__.py,sha256=h4xld8gpvjTTpOOJcPKXwsRMUVGtg8tRqf64AHwZB3k,1051
11
+ ras_commander/logging_config.py,sha256=5bYd_5KMlf81bXsiu2mABBlw0USMhcu5uRv8DIYJSFE,2317
12
+ ras_commander-0.41.0.dist-info/LICENSE,sha256=_pbd6qHnlsz1iQ-ozDW_49r86BZT6CRwO2iBtw0iN6M,457
13
+ ras_commander-0.41.0.dist-info/METADATA,sha256=wYlsP7QFa-lYa5CUKg8Mbi6VFwojfJm_l1GK_TVgCew,15671
14
+ ras_commander-0.41.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
15
+ ras_commander-0.41.0.dist-info/top_level.txt,sha256=i76S7eKLFC8doKcXDl3aiOr9RwT06G8adI6YuKbQDaA,14
16
+ ras_commander-0.41.0.dist-info/RECORD,,
ras_commander/_version.py DELETED
@@ -1,16 +0,0 @@
1
- # file generated by setuptools_scm
2
- # don't change, don't track in version control
3
- TYPE_CHECKING = False
4
- if TYPE_CHECKING:
5
- from typing import Tuple, Union
6
- VERSION_TUPLE = Tuple[Union[int, str], ...]
7
- else:
8
- VERSION_TUPLE = object
9
-
10
- version: str
11
- __version__: str
12
- __version_tuple__: VERSION_TUPLE
13
- version_tuple: VERSION_TUPLE
14
-
15
- __version__ = version = '0.29.dev1+g22e75d4.d20240919'
16
- __version_tuple__ = version_tuple = (0, 29, 'dev1', 'g22e75d4.d20240919')
@@ -1,17 +0,0 @@
1
- ras_commander/RasCmdr.py,sha256=_opzPdFuja2wXmFu2iayP6igJqGeILAavPC1XsCC6ks,25010
2
- ras_commander/RasExamples.py,sha256=g2HIbppxIVeCKriy9Th1RDtrCPzFkdoP-BWEzHPsedY,25112
3
- ras_commander/RasGeo.py,sha256=cqKpN-1r_uXw24acqA8ubGGw2-Od51p-I_X0kGSkWBE,5395
4
- ras_commander/RasGpt.py,sha256=-524sU_PBPxCmjDKJbDXg6Q3k1-Uhk2tYj6HeW8QFJ8,4201
5
- ras_commander/RasHdf.py,sha256=_aJ2PAqFPAnTWN2btmASjWT8dHAFZveAorAu6QXLwgA,77162
6
- ras_commander/RasPlan.py,sha256=p9IVQ5vKzv01jcrY0-Lbx8N7YwkPf4WKovBNx_FgXpE,48835
7
- ras_commander/RasPrj.py,sha256=qDJJiWnAaf-Uzc31DVI5aTKjOulIEoVeH05-kjb4tZQ,34444
8
- ras_commander/RasUnsteady.py,sha256=37GKaYNJZ39y-khhy01LbHwZnf7HT0V2XKQ-UUaJHlY,4639
9
- ras_commander/RasUtils.py,sha256=P9SopqMd6awZyj0U2xNxc-pl1-HEktmyY1lz3LiduPs,25079
10
- ras_commander/__init__.py,sha256=h4xld8gpvjTTpOOJcPKXwsRMUVGtg8tRqf64AHwZB3k,1051
11
- ras_commander/_version.py,sha256=BReLomJ164W3bJhfQJi0gbNKc3DXCzwusmCheUzClB8,478
12
- ras_commander/logging_config.py,sha256=5bYd_5KMlf81bXsiu2mABBlw0USMhcu5uRv8DIYJSFE,2317
13
- ras_commander-0.40.0.dist-info/LICENSE,sha256=_pbd6qHnlsz1iQ-ozDW_49r86BZT6CRwO2iBtw0iN6M,457
14
- ras_commander-0.40.0.dist-info/METADATA,sha256=78DRlI1Qcckp4bsA3mxbdxMAU5WnANe_tPc1D8J24BE,15440
15
- ras_commander-0.40.0.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
16
- ras_commander-0.40.0.dist-info/top_level.txt,sha256=i76S7eKLFC8doKcXDl3aiOr9RwT06G8adI6YuKbQDaA,14
17
- ras_commander-0.40.0.dist-info/RECORD,,