RUFAS.util module#
- RUFAS.util.random() x in the interval [0, 1). #
- class RUFAS.util.Utility#
Bases:
object
- static convert_list_of_dicts_to_dict_of_lists(list_of_dicts: List[Dict[str, Any]]) Dict[str, List[Any]] #
Convert a list of dictionaries into a dictionary of lists.
Parameters#
- list_of_dictsList[Dict[str, Any]]
A list of dictionaries with string keys and integer values.
Returns#
- Dict[str, List[Any]]
A dictionary where keys are unique keys from input dictionaries, and values are lists of corresponding values from input dictionaries.
- static convert_dict_of_lists_to_list_of_dicts(dict_of_lists: dict[str, list[Any]]) list[dict[str, Any]] #
Convert a dictionary of lists into a list of dictionaries.
Parameters#
- dict_of_listsdict[str, list[Any]]
A dictionary where keys are unique keys and values are lists of corresponding values.
Returns#
- list[dict[str, Any]]
A list of dictionaries with string keys and integer values.
- static flatten_keys_to_nested_structure(input_dict: Dict[str, Any]) Dict[str, Any] #
Convert a dictionary with flat, dot-separated keys into a nested structure composed of dictionaries and lists based on the keys. Numeric segments in the keys indicate list indices, while non-numeric segments indicate dictionary keys.
Parameters#
- input_dictDict[str, Any]
A dictionary where the keys are strings that may include dots to signify hierarchical levels in the resulting nested structure. Numeric key segments result in list creations, and non-numeric segments result in dictionary creations.
Returns#
- Dict[str, Union[Dict, list]]
A nested structure of dictionaries and lists derived by interpreting the flat dictionary keys.
- static expand_data_temporally(data_to_expand: dict[str, dict[str, list[Any]]], fill_value: Any = nan, use_fill_value_in_gaps: bool = True, use_fill_value_at_end: bool = True) dict[str, dict[str, list[Any]]] #
Pads and expands data based on the simulation day(s) it was recorded on, relative to when other data was recorded, so that values are present for all days in a certain range.
Parameters#
- data_to_expanddict[str, dict[str, list[Any]]]
The data to be padded and expanded. The top level key is a variable name, and points to a dictionary that contains the keys “values” and optionally “info_maps”.
- fill_valueAny, default numpy.nan
Value that is used to pad the front of the data values, and optionally the values in between original values and after the last original value.
- use_fill_value_in_gapsbool, default True
If false, values between known data points are expanded with the last known value from the data set. If true, values between known data points are filled with fill_value.
- use_fill_value_at_endbool, default True
If false, values after last known data point are padded with the last known value from the data set. If true, values after the last known data point are filled with fill_value.
Returns#
- dict[str, dict[str, list[Any]]]
The filled data, so that gaps in the data are filled in with the last known value or fill_value.
Raises#
- TypeError
If a variable has no info maps.
- ValueError
If there is no data to be filled. If the number of info maps does not match the number of values for a variable. If a value for “simulation_day” is not present in every info map.
Notes#
This method assumes there will never be multiple values recorded for a single variable on a single simulation day.
- static deep_merge(target: Dict[Any, Any], updates: Dict[Any, Any]) None #
Recursively merges ‘updates’ into ‘target’. Supports deep merging for dictionaries and lists, including lists that contain dictionaries and dictionaries that contain lists.
Parameters#
- targetDict[Any, Any]
The primary dictionary to be updated.
- updatesDict[Any, Any]
The dictionary containing updates to be merged into target.
- static calc_average(num_values: int, cur_avg: float, new_value: float) Tuple[int, float] #
Calculate the new average given the number of values, the current average, and the new value.
Parameters#
num_values: number of values for the current average cur_avg: the current average value new_value: the new value to be averaged
Returns#
new_num_values: the new number of values for the new average new_avg: the new average value calculated
- static remove_items_from_list_by_indices(data: List[Any], indices_to_remove: List[int]) None #
Remove items from a list given a list of indices. The operation is done in-place.
Parameters#
- data: List[Any] a list of items
The list to remove items from
- indices_to_removeList[Any]
The list that contains indices of the items to be removed
Returns#
None
- static percent_calculator(denominator: float) Callable[[float], float] #
Return a percent calculator closure that already stores the value of the given denominator.
Parameters#
denominator: the denominator to
Returns#
A closure function that already stores the denominator internally so the user only needs to pass in the numerator.
- classmethod make_serializable(obj: object, max_depth: int = 3) object #
Converts the given object into a serializable object.
Parameters#
- obj
The object to be serialized.
- max_depthint, optional
The maximum depth of recursion.
Returns#
A serializable object.
- classmethod _make_serializable(obj: object, depth: int, max_depth: int) object #
Makes the given object serializable.
The object can be a primitive type, a list, a tuple, a set, a dictionary, or an instance of a custom class.
A recursive algorithm is used to traverse the object and convert it into a serializable object. The maximum depth of recursion is specified by the parameter max_depth.
Parameters#
- objobject
The object to be serialized.
- depthint
The current depth of recursion.
- max_depthint
The maximum depth of recursion.
Returns#
- object
A serializable object.
- classmethod _get_str(obj: object) str #
Returns a string representation of the given object.
Parameters#
- objobject
The object to be converted to a string.
Returns#
- str
A string representation of the given object.
Notes#
If the object has a custom __str__ method, then that method will be used. Otherwise, a variant of the default __str__ method will be used.
Normally, the default __str__ method returns a string of the format: <module>.<class> object at <memory address>. Here, we want to simplify that string to the format: <class> object at <memory address>.
This turns out to be saving quite a bit of space when serializing objects.
- classmethod empty_dir(dir_path: Path, keep: List[str] | None = None) None #
Empties the given directory, except for the files or subdirectories in the keep list.
Parameters#
- dir_pathPath
The path to the directory to be emptied.
- keepList, optional
A list of file or subdirectory names to be kept.
Returns#
None
- static get_timestamp(include_millis: bool = False) str #
Produces the current system time as a timestamp string.
Parameters#
- include_millisbool
If True, adds milliseconds to the timestamp.
Returns#
- str
The current time’s timestamp string.
Example#
>>> Utility.get_timestamp(include_millis=True) 28-Jun-2023_Wed_15-48-21.406585 >>> Utility.get_timestamp(include_millis=False) 28-Jun-2023_Wed_15-48-21
- static filter_dictionary(dict_to_filter: Dict[str, Any], filter_patterns: List[str], filter_by_exclusion: bool) Dict[Any, Any] #
Returns a filtered dictionary based on either inclusion or exclusion.
Parameters#
- dict_to_filterDict[str, Any]
The dictionary to be filtered.
- filter_patternsList[str]
A list of patterns by which to filter the dictionary.
- filter_by_exclusionbool
A flag indicating whether the dictionary should be filtered by exclusion or inclusion.
Returns#
- Dict[str, Any]
The filtered dictionary.
- static remove_special_chars(input_string: str | list[str]) str #
Function to remove special characters from a string.
Parameters#
- input_stringstr
The string from which the special characters should be removed.
Returns#
- str
The input string with the special characters filtered out.
- static is_leap_year(year: int) bool #
Helper method determines if the given year is a leap year
Parameters#
- year: int
The year.
Returns#
- bool
True if the year is a leap year, otherwise False.
- static generate_time_series(date: date, starting_offset: int, ending_offset: int) list[date] #
Generates a list of dates based on a given date and when the dates should start and end relative to the given date.
Parameters#
- datedatetime.date
Date around which the time series will be generated.
- starting_offsetint
Number of days before or after the given date to start the time series.
- ending_offsetint
Number of days before or after the given date to end the time series.
Raises#
- ValueError
If the starting_offset is greater than the ending_offset.
Examples#
>>> Utility.generate_time_series(datetime.date(2024, 6, 1), 0, 0) [datetime.date(2024, 6, 1)] >>> Utility.generate_time_series(datetime.date(2024, 6, 1), -2, 0) [datetime.date(2024, 5, 30), datetime.date(2024, 5, 31), datetime.date(2024, 6, 1)] >>> Utility.generate_time_series(datetime.date(2024, 6, 1), -2, -2) [datetime.date(2024, 5, 30)] >>> Utility.generate_time_series(datetime.date(2024, 6, 1), 0, 2) [datetime.date(2024, 6, 1), datetime.date(2024, 6, 2), datetime.date(2024, 6, 3)] >>> Utility.generate_time_series(datetime.date(2024, 6, 1), -1, 1) [datetime.date(2024, 5, 31), datetime.date(2024, 6, 1), datetime.date(2024, 6, 2)] >>> Utility.generate_time_series(datetime.date(2024, 6, 1), 3, 5) [datetime.date(2024, 6, 4), datetime.date(2024, 6, 5), datetime.date(2024, 6, 6)]
- static convert_celsius_to_kelvin(temperature: float) float #
Converts a temperature in degrees Celsius to degrees Kelvin.
- static convert_ordinal_date_to_month_date(year: int, day: int) date #
Generates a datetime.date based on a year and ordinal day.
- static generate_random_number(mean: float, std_dev: float) float #
Generates a normally distributed random number using the provided mean and standard deviation.
- static flatten_dictionary(input_dictionary: dict[str, Any], parent_key: str = '', separator: str = '.') dict[str, Any] #
Flatten a nested dictionary to a single level of depth by joining the keys with “.”
- static combine_saved_input_csv(saved_csv_working_folder: Path, output_csv_path: Path, import_csv_path: Path | None) None #
Merge multiple saved input data CSVs files into one single CSV file for a direct side-by-side comparison.
- static elongate_list(list_to_elongate: list[Any], reference_list_length: int) list[Any] #
Takes a list and lengthens it to match the length of the reference list, if the original length was 1.
Parameters#
- list_to_elongatelist[Any]
List to be extended if its length is 1.
- reference_list_lengthint
Length of that the list should be extended to, if it its original length is 1.
Returns#
- list[Any]
The elongated list.
Notes#
In the context of Schedule-descendant classes, the reference list length will always be the length of the years list.
- static determine_if_all_non_negative_values(values: list[int | float]) bool #
Checks that all values in a list are >= 0.
Parameters#
- valuesList[Any]
List of values to be checked.
Returns#
- bool
True if all values are >= 0, False otherwise.
- static validate_fractions(fractions: List[float]) bool #
Checks that all fractions passed are valid.
Parameters#
- fractionsList[float]
List of fractions to be valid
Returns#
- bool
True if all fractions passed are valid, False otherwise.
Notes#
A fraction is valid if it is in the range[0.0, 1.0]
- static round_numeric_values_in_dict(data: dict[str, any], significant_digits: int) dict[str, Any] #
Rounds all numeric values in a dictionary to the specified number of significant digits.
Parameters#
- datadict[str, any]
The dictionary containing numeric values to be rounded.
- significant_digitsint
The number of significant digits to round the numeric values to.
Returns#
- dict[str, any]
The dictionary with numeric values rounded to the specified number of significant digits.
Notes#
Some specific behavior of the round() function used by this method:
If significant_digits is None or 0, floats are converted to ints. round(12.7) -> 13 (int) round(12.3) -> 12 (int) round(-12.7) -> -13 (int) round(12.5) -> 12 (int) - If rounded number is 5, Python rounds to the nearest even number. round(11.5) -> 12 (int) - Because of this rule, both 11.5 and 12.5 round to 12.
If significant_digits is less than 0, it rounds to the nearest multiple of 10, 100, 1000, etc. round(1234, -2) -> 1200 (rounds to the nearest multiple of 100) round(1234, -3) -> 1000 (rounds to the nearest multiple of 1000) round(-1234, -1) -> -1230 (rounds to the nearest multiple of 10)
If significant_digits is 0, it rounds to the nearest integer and converts it to a float. round(12.7, 0) -> 13.0 (float) round(-12.3, 0) -> -12.0 (float)
- static compare_randomized_rate_less_than(reference_rate: float) bool #
Compare a random rate to a reference rate to determine if an event occurs.
Parameters#
- reference_ratefloat
Reference rate for comparison.
Returns#
- bool
True if the randomized rate is less than the reference rate, False otherwise.
- static validate_date_format(date_format: str) bool #
Checks if date_format is a valid Python datetime format for both strftime() and strptime().
Parameters#
- date_formatstr
The date format to be validated.
Returns#
bool
- static get_date_formatter(date_format: str | None) DateFormatter #
Get a matplotlib.dates.DateFormatter instance for the requested date format.
Parameters#
- date_formatstr
The format requested by the user. Common date formats are: - “%j/%Y”: Formats dates as “day_of_year/year” (e.g., “123/2024”). - “%d/%m/%Y”: Formats dates as “day/month/year” (e.g., “23/12/2024”). - “%m/%d/%Y”: Formats dates as “month/day/year” (e.g., “12/23/2024”). - “%b/%d/%Y”: Formats dates as “month_abbreviation/day/year” (e.g., “Dec/23/2024”). - “%B/%d/%Y”: Formats dates as “month_string/day/year” (e.g., “December/23/2024”). - “%m/%d/%y”: Formats dates as “month/day/year_without_century” (e.g., “12/23/24”). - “%m %d %Y”: Formats dates as “month day year” (e.g., “12 23 2024”). - “%m-%d-%Y”: Formats dates as “month-day-year” (e.g., “12-23-2024”).
Returns#
- matplotlib.dates.DateFormatter
A DateFormatter instance for the specified format.
Notes#
If the date_format is None or invalid, the default format “%d/%m/%Y” will be used instead.