Files
OpenBB/openbb_terminal/portfolio/portfolio_optimization/parameters/Parameter.py
montezdesousa faca7ab67d Portfolio optimization bug fixes (#3675)
* remove hcp

* add prams dict to statics

* little controller bug

* fix view bug

* avoid crash if one stock

* check params on setup

* create parameter class

* check and convert parameters using class

* change params name to avoid confusion

* create a parameter statics dict

* change some funcs names

* remove unused imports

* remove default dict

* optional type

* add multi choices

* cast only int and float

* fix completer

* fix bugs with parameter validation

* fix bugs with parameter validation

* add excel formatting

* sdk needs mapping as well, controller takes care of this in terminal

* small formating

* add some safe guard try except

* controller bugs

* oops

* change export path of parameters to portfolio folder

* add more commands to scripts

* catch optimization exception

* log errors

* black and exceptions

* add flag to test

* black

* flake8

* forgot this

* pylint

* change defaults

* fix ef default

* fix bl

* sync sdk defaults

* sync last defaults

* fix plot heat and add more choices to controller autocomplete

* patch weights

* fix wrong bool parsing

Co-authored-by: James Maslek <jmaslek11@gmail.com>
2022-12-02 23:56:41 +00:00

86 lines
2.7 KiB
Python

from dataclasses import dataclass
from typing import Any, List, Optional, Type
# pylint: disable=unidiomatic-typecheck
@dataclass(frozen=True)
class Parameter:
"""Class for storing parameters. This dataclass is frozen so no attributes can be changed after initialization.
Parameters
----------
name : str
Name of the parameter.
type_ : type
Type of the parameter.
default : Any
Default value of the parameter.
choices : Optional[List[Any]]
List of possible values for the parameter.
"""
name: str
type_: Type
default: Any
choices: Optional[List[Any]] = None
def __post_init__(self):
"""Post initialization."""
self.validate()
def validate(self):
"""Validate the value of the parameter.
Parameters
----------
value : Any
Value of the parameter.
Raises
------
TypeError
If the value is not of the correct type.
ValueError
If the value is not in the list of possible values.
"""
if not self.validate_type(self.default):
raise TypeError(
f"Default for '{self.name}' must be of type '{self.type_.__name__}'."
)
if self.choices is not None:
if not all(self.validate_type(choice) for choice in self.choices):
raise TypeError(
f"Choices must be of the same type as the parameter.\n"
f"'{self.name}': '{self.choices}' -> '{self.type_.__name__}'"
)
if self.choices is not None and self.default not in self.choices:
raise ValueError(
f"Parameter '{self.name}' must be one of type '{self.choices}'."
)
def validate_type(self, value: Any) -> bool:
"""Check if the value is of the correct type.
Parameters
----------
value : Any
Value of the parameter.
Returns
-------
bool
True if the value is of the correct type, False otherwise.
"""
# Temporary workaround until we drop Python 3.9 for:
# Error: Subscripted generics cannot be used with class and instance checks
#
# isinstance for subscripted generics (e.g. List[str]) is only available
# in Python 3.10, so this method does not check for the type of subscripted generics.
# TODO: Though we should implement it.
# See https://stackoverflow.com/questions/70825351/python-3-typeerror-subscripted-generics-cannot-be-used-with-class-and-instance # noqa: E501
try:
return isinstance(value, self.type_)
except Exception as _: # noqa: F841
return True