Source code for ioput.iostandard

"""File and directory operations.

This module includes standard operations to handle files and directories.

Functions
---------
make_directory
    Create a directory.
new_file_path_with_int
    Generate new and non-existent file path by extending with an integer.
write_summary_file
    Write summary data file with provided keyword-based parameters.
find_unique_file_with_regex(directory, regex)
    Find file in directory based on regular expression.
"""
#
#                                                                       Modules
# =============================================================================
# Standard
import os
import shutil
import re
# Third-party
import numpy as np
#
#                                                          Authorship & Credits
# =============================================================================
__author__ = 'Bernardo Ferreira (bernardo_ferreira@brown.edu)'
__credits__ = ['Bernardo Ferreira', ]
__status__ = 'Alpha'
# =============================================================================
[docs] def make_directory(directory, is_overwrite=False): """Create a directory. Parameters ---------- directory : str Directory path (without trailing slash). is_overwrite : bool, default=False If True, then directory overwrites existing directory with the same name. If False, then directory is extended with '_int' until non-existing directory is found, where int is an integer starting as 1. Returns ------- directory : str Created directory path. """ # Get absolute path directory = os.path.abspath(directory) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if os.path.isdir(directory): if is_overwrite: # Remove existing directory shutil.rmtree(directory) else: # Search for available directory name by extending it with an # integer new_directory = directory i = 1 while os.path.isdir(new_directory): new_directory = directory + '_' + str(i) i += 1 # Set new directory directory = new_directory # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create directory os.makedirs(directory) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return directory
# =============================================================================
[docs] def new_file_path_with_int(file_path): """Generate new and non-existent file path by extending with an integer. Parameters ---------- file_path : str File path. Returns ------- new_file_path : str File path extended with an integer. """ # Get file path root and extension root, ext = os.path.splitext(file_path) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Initialize new file path new_file_path = file_path # Initialize extension integer i = 1 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Find non-existent file path while os.path.isfile(new_file_path): new_file_path = root + '_' + str(i) + ext i += 1 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return new_file_path
# =============================================================================
[docs] def write_summary_file(summary_directory, filename='summary', summary_title=None, **kwargs): """Write summary data file with provided keyword-based parameters. Parameters ---------- summary_directory : str Directory where the summary file is written. filename : str, default='summary' Summary file name. summary_title : str, default=None Header of summary file. kwargs: dict Keyword-based parameters to be written in summary file. """ # Check summary file directory if not os.path.isdir(summary_directory): raise RuntimeError('The summary file directory has not been ' 'found:\n\n' + summary_directory) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Set summary file path summary_file_path = os.path.join(os.path.normpath(summary_directory), str(filename) + '.dat') # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Initialize summary file content summary = [] # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Set summary file title if isinstance(summary_title, str): summary += [f'{summary_title}\n', len(summary_title)*'-' + '\n'] # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Loop over summary parameters for key1, val1 in kwargs.items(): # Append parameter if isinstance(val1, dict): summary.append(f'\n"{str(key1)}":\n') for key2, val2 in val1.items(): if isinstance(val2, dict): summary.append(f'\n "{str(key2)}":\n') for key3, val3 in val2.items(): summary.append(f' "{str(key3)}": {str(val3)}\n') else: summary.append(f' "{str(key2)}": {str(val2)}\n') elif isinstance(val1, np.ndarray): summary.append(f'\n"{str(key1)}":\n {str(val1)}\n') elif isinstance(val1, str) and '\n' in val1: summary.append(f'\n"{str(key1)}":\n\n{str(val1)}\n') else: summary.append(f'\n"{str(key1)}": {str(val1)}\n') # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Write summary file open(summary_file_path, 'w').writelines(summary)
# ============================================================================= def find_unique_file_with_regex(directory, regex): """Find file in directory based on regular expression. Returns first occurrence if file matching regular expression is found. Parameters ---------- directory : str Directory where file is searched. regex : {str, tuple[str]} Regular expression to search for file. If tuple of regular expressions is provided, then search procedure loops over them. Returns ------- is_file_found : bool True if file is found, False otherwise. file_path : {str, None} File path. Set to None if file is not found. """ # Check directory if not os.path.isdir(directory): raise RuntimeError('The searching directory has not been found:\n\n' + directory) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Check regular expression if not isinstance(regex, str) and not isinstance(regex, tuple): raise RuntimeError('Regular expression(s) must be provided as str or ' 'tuple[str].') elif (isinstance(regex, tuple) and not all([isinstance(x, str) for x in regex])): raise RuntimeError('Regular expression(s) must be provided as str or ' 'tuple[str].') else: if isinstance(regex, str): # Convert to tuple regex = (regex,) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Check regular expression pattern try: for pattern in regex: re.compile(pattern) except re.error: raise RuntimeError('Invalid regular expression.') # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Get files in directory directory_list = os.listdir(directory) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Initialize file found flag is_file_found = False # Loop over training regex for pattern in regex: # Loop over files for filename in directory_list: # Check if file meeting pattern has been found is_file_found = bool(re.search(pattern, filename)) # Leave searching loop when file is found if is_file_found: break # Leave searching loop when file is found if is_file_found: break # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Set file path if is_file_found: dataset_file_path = os.path.join(os.path.normpath(directory), filename) else: dataset_file_path = None # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ return is_file_found, dataset_file_path