Module scrilla.util.helper

Expand source code
import argparse
from math import trunc
from typing import List, Tuple

from scrilla.static import definitions, constants


def truncate(number: float, digits: int) -> float:
    stepper = 10.0 ** digits
    return trunc(stepper * number) / stepper


def strip_string_array(array: List[str]) -> List[str]:
    new_array = []
    for string in array:
        new_array.append(string.strip())
    return new_array


def split_and_strip(string: str, upper: bool = True, delimiter=",") -> List[str]:
    if upper:
        return strip_string_array(string.upper().split(delimiter))
    return strip_string_array(string.lower().split(delimiter))


def round_array(array: List[float], decimals: int) -> List[float]:
    cutoff = (1/10**decimals)
    return [0 if element < cutoff else truncate(element, decimals) for element in array]


def intersect_dict_keys(dict1: dict, dict2: dict) -> Tuple[dict, dict]:
    """
    Generates two new dictionaries from the inputted dictionaries such that the new dictionaries contain the same keys. In other words, this function takes the intersection of the dictionary keys and generates two new dictionaries with *only* those keys.
    """
    return {x: dict1[x] for x in dict1.keys() if x in dict2.keys()}, {x: dict2[x] for x in dict2.keys() if x in dict1.keys()}


def complement_dict_keys(dict1: dict, dict2: dict):
    """
    Returns the a transformed first dictionary whose keys are a complement relative to the second dictionary keys. In other words, this function takes the complement of the first dictionary keys relative to the second dictionary keys. 
    """
    return {x: dict1[x] for x in dict1.keys() if x not in dict2.keys()}


def format_float_number(decimal: float):
    if decimal < 10 ** (-constants.constants['ACCURACY']):
        return 0
    return str(decimal)[:constants.constants['SIG_FIGS']]


def format_float_percent(decimal: float):
    if decimal < 10 ** (-constants.constants['ACCURACY']):
        return "0%"
    return str(100*float(format_float_number(decimal)))[:constants.constants['SIG_FIGS']]+"%"


def format_dict_percent(this_dict: dict, which_key: str) -> dict:
    buffer_dict = this_dict.copy()
    buffer_dict[which_key] = format_float_percent(this_dict[which_key])
    return buffer_dict


def format_dict_number(this_dict: dict, which_key: str) -> dict:
    buffer_dict = this_dict.copy()
    buffer_dict[which_key] = format_float_number(this_dict[which_key])
    return buffer_dict

################################################
# PARSING FUNCTIONS

# CLI PARSING


def format_args(args, default_estimation_method) -> argparse.Namespace:
    parser = argparse.ArgumentParser()

    choices = []
    for func in definitions.FUNC_DICT:
        choices.append(definitions.FUNC_DICT[func]['values'][0])
        choices.append(definitions.FUNC_DICT[func]['values'][1])

    parser.add_argument('function_arg', choices=choices)

    groups = [parser.add_mutually_exclusive_group()
              for arg_group in definitions.ARG_META_DICT['groups']]

    for arg in definitions.ARG_DICT:
        if definitions.ARG_DICT[arg]['format'] not in ('group', bool):
            parser.add_argument(definitions.ARG_DICT[arg]['values'][0],
                                definitions.ARG_DICT[arg]['values'][1],
                                definitions.ARG_DICT[arg]['values'][2],
                                definitions.ARG_DICT[arg]['values'][3],
                                default=None,
                                type=definitions.ARG_DICT[arg]['format'],
                                dest=arg)
        elif definitions.ARG_DICT[arg]['format'] == 'group':
            group_index = definitions.ARG_META_DICT['groups'].index(
                definitions.ARG_DICT[arg]['group'])
            groups[group_index].add_argument(definitions.ARG_DICT[arg]['values'][0],
                                             definitions.ARG_DICT[arg]['values'][1],
                                             definitions.ARG_DICT[arg]['values'][2],
                                             definitions.ARG_DICT[arg]['values'][3],
                                             action='store_const',
                                             dest=definitions.ARG_DICT[arg]['group'],
                                             const=arg)
        # NOTE: 'format' == group AND 'format' == bool => Empty Set, so only other alternative is
        # 'format' == bool
        else:
            parser.add_argument(definitions.ARG_DICT[arg]['values'][0],
                                definitions.ARG_DICT[arg]['values'][1],
                                definitions.ARG_DICT[arg]['values'][2],
                                definitions.ARG_DICT[arg]['values'][3],
                                action='store_true',
                                dest=arg)

    parser.set_defaults(estimation_method=default_estimation_method)
    parser.add_argument('tickers', nargs='*', type=str)
    return vars(parser.parse_args(args))


def get_first_json_key(this_json: dict) -> str:
    return list(this_json.keys())[0]


def replace_troublesome_chars(msg: str) -> str:
    return msg.replace('\u2265', '').replace('\u0142', '')

Functions

def complement_dict_keys(dict1: dict, dict2: dict)

Returns the a transformed first dictionary whose keys are a complement relative to the second dictionary keys. In other words, this function takes the complement of the first dictionary keys relative to the second dictionary keys.

Expand source code
def complement_dict_keys(dict1: dict, dict2: dict):
    """
    Returns the a transformed first dictionary whose keys are a complement relative to the second dictionary keys. In other words, this function takes the complement of the first dictionary keys relative to the second dictionary keys. 
    """
    return {x: dict1[x] for x in dict1.keys() if x not in dict2.keys()}
def format_args(args, default_estimation_method) ‑> argparse.Namespace
Expand source code
def format_args(args, default_estimation_method) -> argparse.Namespace:
    parser = argparse.ArgumentParser()

    choices = []
    for func in definitions.FUNC_DICT:
        choices.append(definitions.FUNC_DICT[func]['values'][0])
        choices.append(definitions.FUNC_DICT[func]['values'][1])

    parser.add_argument('function_arg', choices=choices)

    groups = [parser.add_mutually_exclusive_group()
              for arg_group in definitions.ARG_META_DICT['groups']]

    for arg in definitions.ARG_DICT:
        if definitions.ARG_DICT[arg]['format'] not in ('group', bool):
            parser.add_argument(definitions.ARG_DICT[arg]['values'][0],
                                definitions.ARG_DICT[arg]['values'][1],
                                definitions.ARG_DICT[arg]['values'][2],
                                definitions.ARG_DICT[arg]['values'][3],
                                default=None,
                                type=definitions.ARG_DICT[arg]['format'],
                                dest=arg)
        elif definitions.ARG_DICT[arg]['format'] == 'group':
            group_index = definitions.ARG_META_DICT['groups'].index(
                definitions.ARG_DICT[arg]['group'])
            groups[group_index].add_argument(definitions.ARG_DICT[arg]['values'][0],
                                             definitions.ARG_DICT[arg]['values'][1],
                                             definitions.ARG_DICT[arg]['values'][2],
                                             definitions.ARG_DICT[arg]['values'][3],
                                             action='store_const',
                                             dest=definitions.ARG_DICT[arg]['group'],
                                             const=arg)
        # NOTE: 'format' == group AND 'format' == bool => Empty Set, so only other alternative is
        # 'format' == bool
        else:
            parser.add_argument(definitions.ARG_DICT[arg]['values'][0],
                                definitions.ARG_DICT[arg]['values'][1],
                                definitions.ARG_DICT[arg]['values'][2],
                                definitions.ARG_DICT[arg]['values'][3],
                                action='store_true',
                                dest=arg)

    parser.set_defaults(estimation_method=default_estimation_method)
    parser.add_argument('tickers', nargs='*', type=str)
    return vars(parser.parse_args(args))
def format_dict_number(this_dict: dict, which_key: str) ‑> dict
Expand source code
def format_dict_number(this_dict: dict, which_key: str) -> dict:
    buffer_dict = this_dict.copy()
    buffer_dict[which_key] = format_float_number(this_dict[which_key])
    return buffer_dict
def format_dict_percent(this_dict: dict, which_key: str) ‑> dict
Expand source code
def format_dict_percent(this_dict: dict, which_key: str) -> dict:
    buffer_dict = this_dict.copy()
    buffer_dict[which_key] = format_float_percent(this_dict[which_key])
    return buffer_dict
def format_float_number(decimal: float)
Expand source code
def format_float_number(decimal: float):
    if decimal < 10 ** (-constants.constants['ACCURACY']):
        return 0
    return str(decimal)[:constants.constants['SIG_FIGS']]
def format_float_percent(decimal: float)
Expand source code
def format_float_percent(decimal: float):
    if decimal < 10 ** (-constants.constants['ACCURACY']):
        return "0%"
    return str(100*float(format_float_number(decimal)))[:constants.constants['SIG_FIGS']]+"%"
def get_first_json_key(this_json: dict) ‑> str
Expand source code
def get_first_json_key(this_json: dict) -> str:
    return list(this_json.keys())[0]
def intersect_dict_keys(dict1: dict, dict2: dict) ‑> Tuple[dict, dict]

Generates two new dictionaries from the inputted dictionaries such that the new dictionaries contain the same keys. In other words, this function takes the intersection of the dictionary keys and generates two new dictionaries with only those keys.

Expand source code
def intersect_dict_keys(dict1: dict, dict2: dict) -> Tuple[dict, dict]:
    """
    Generates two new dictionaries from the inputted dictionaries such that the new dictionaries contain the same keys. In other words, this function takes the intersection of the dictionary keys and generates two new dictionaries with *only* those keys.
    """
    return {x: dict1[x] for x in dict1.keys() if x in dict2.keys()}, {x: dict2[x] for x in dict2.keys() if x in dict1.keys()}
def replace_troublesome_chars(msg: str) ‑> str
Expand source code
def replace_troublesome_chars(msg: str) -> str:
    return msg.replace('\u2265', '').replace('\u0142', '')
def round_array(array: List[float], decimals: int) ‑> List[float]
Expand source code
def round_array(array: List[float], decimals: int) -> List[float]:
    cutoff = (1/10**decimals)
    return [0 if element < cutoff else truncate(element, decimals) for element in array]
def split_and_strip(string: str, upper: bool = True, delimiter=',') ‑> List[str]
Expand source code
def split_and_strip(string: str, upper: bool = True, delimiter=",") -> List[str]:
    if upper:
        return strip_string_array(string.upper().split(delimiter))
    return strip_string_array(string.lower().split(delimiter))
def strip_string_array(array: List[str]) ‑> List[str]
Expand source code
def strip_string_array(array: List[str]) -> List[str]:
    new_array = []
    for string in array:
        new_array.append(string.strip())
    return new_array
def truncate(number: float, digits: int) ‑> float
Expand source code
def truncate(number: float, digits: int) -> float:
    stepper = 10.0 ** digits
    return trunc(stepper * number) / stepper