"""Convert expressions to float and vice versaMichel BierlaireTue Mar 25 18:43:36 2025"""from__future__importannotationsfrombiogeme.exceptionsimportBiogemeErrorfrom.base_expressionsimportExpressionOrNumeric,Expressionfrom.numeric_expressionsimportNumericfrom.numeric_toolsimportis_numeric
[docs]defvalidate_and_convert(expression:ExpressionOrNumeric)->Expression:"""Validates the expression and returns the converted expression if necessary."""ifisinstance(expression,bool):returnNumeric(1)ifexpressionelseNumeric(0)ifis_numeric(expression):returnNumeric(expression)ifnotisinstance(expression,Expression):raiseTypeError(f'This is not a valid expression: {expression}. It is of type {type(expression)}')returnexpression
[docs]defexpression_to_value(expression:ExpressionOrNumeric,betas:dict[str,float]|None=None)->float:""" Convert an expression to a float value, if possible. :param expression: The expression to convert. Can be a boolean, a numeric value, or an instance of Expression. :param betas: Optional dictionary of beta values used to initialize the expression, if applicable. :return: The numerical value of the expression as a float. :raises TypeError: If the input is not a valid expression type. :raises BiogemeError: If the expression cannot be evaluated to a numeric value. """ifisinstance(expression,bool)oris_numeric(expression):returnfloat(expression)ifnotisinstance(expression,Expression):raiseTypeError(f'This is not a valid expression: {expression}')ifbetasisnotNone:expression.change_init_values(betas=betas)try:value=expression.get_value()exceptBiogemeErrorase:error_msg=f'Expression {expression} too complex to be associated with a numeric value: {e}'raiseBiogemeError(error_msg)fromereturnvalue
[docs]defget_dict_values(the_dict:dict[int,ExpressionOrNumeric],betas:dict[str,float]|None=None)->dict[int,float]:"""If the dictionary contains Expressions, they are transformed into a numerical expression."""return{key:expression_to_value(expression=expr,betas=betas)forkey,exprinthe_dict.items()}
[docs]defget_dict_expressions(the_dict:dict[int,ExpressionOrNumeric],)->dict[int,Expression]:"""If the dictionary contains float, they are transformed into a numerical expression."""return{key:validate_and_convert(value)forkey,valueinthe_dict.items()}