KarrLab/obj_tables

View on GitHub
obj_tables/math/expression.py

Summary

Maintainability
F
1 wk
Test Coverage
A
99%

File expression.py has 1493 lines of code (exceeds 250 allowed). Consider refactoring.
Open

""" Utilities for processing mathematical expressions used by obj_tables models

:Author: Arthur Goldberg <Arthur.Goldberg@mssm.edu>
:Author: Jonathan Karr <karr@mssm.edu>
:Date: 2018-12-19
Severity: Major
Found in obj_tables/math/expression.py - About 3 days to fix

    Function tokenize has a Cognitive Complexity of 60 (exceeds 5 allowed). Consider refactoring.
    Open

        def tokenize(self, case_fold_match=False):
            """ Tokenize a Python expression in :obj:`self.expression`
    
            Args:
                case_fold_match (:obj:`bool`, optional): if set, casefold identifiers before matching;
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 day to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function eval has a Cognitive Complexity of 36 (exceeds 5 allowed). Consider refactoring.
    Open

        def eval(self, values, with_units=False):
            """ Evaluate the expression
    
            Approach:
    
    
    Severity: Minor
    Found in obj_tables/math/expression.py - About 5 hrs to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function _get_related_obj_id has a Cognitive Complexity of 26 (exceeds 5 allowed). Consider refactoring.
    Open

        def _get_related_obj_id(self, idx, case_fold_match=False):
            """ Try to parse a related object `ObjTables` id from :obj:`self._py_tokens` at :obj:`idx`
    
            Different `ObjTables` objects match different Python token patterns. The default pattern
            is (token.NAME, ), but an object of type :obj:`model_type` can define a custom pattern in
    Severity: Minor
    Found in obj_tables/math/expression.py - About 3 hrs to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function get_cls_and_model has a Cognitive Complexity of 24 (exceeds 5 allowed). Consider refactoring.
    Open

        def get_cls_and_model(self, id):
            """ Get the class and instance of a related model with id `id`
    
            Args:
                id (:obj:`str`): id
    Severity: Minor
    Found in obj_tables/math/expression.py - About 3 hrs to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function validate has a Cognitive Complexity of 23 (exceeds 5 allowed). Consider refactoring.
    Open

        def validate(cls, model_obj, parent_obj):
            """ Determine whether an expression model is valid
    
            One check eval's its deserialized expression
    
    
    Severity: Minor
    Found in obj_tables/math/expression.py - About 3 hrs to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function __init__ has a Cognitive Complexity of 18 (exceeds 5 allowed). Consider refactoring.
    Open

        def __init__(self, model_cls, attr, expression, objs):
            """ Create an instance of ParsedExpression
    
            Args:
                model_cls (:obj:`type`): the :obj:`Model` which has an expression
    Severity: Minor
    Found in obj_tables/math/expression.py - About 2 hrs to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function get_xlsx_validation has a Cognitive Complexity of 13 (exceeds 5 allowed). Consider refactoring.
    Open

        def get_xlsx_validation(self, sheet_models=None, doc_metadata_model=None):
            """ Get XLSX validation
    
            Args:
                sheet_models (:obj:`list` of :obj:`Model`, optional): models encoded as separate sheets
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function deserialize has a Cognitive Complexity of 12 (exceeds 5 allowed). Consider refactoring.
    Open

        def deserialize(cls, model_cls, value, objects):
            """ Deserialize :obj:`value` into an :obj:`Expression`
    
            Args:
                model_cls (:obj:`type`): :obj:`Expression` class or subclass
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function get_xlsx_validation has a Cognitive Complexity of 12 (exceeds 5 allowed). Consider refactoring.
    Open

        def get_xlsx_validation(self, sheet_models=None, doc_metadata_model=None):
            """ Get XLSX validation
    
            Args:
                sheet_models (:obj:`list` of :obj:`Model`, optional): models encoded as separate sheets
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function _set_lin_coeffs has a Cognitive Complexity of 11 (exceeds 5 allowed). Consider refactoring.
    Open

        def _set_lin_coeffs(self):
            """ Set the linear coefficients for the related objects
    
            Assumes `_validate()` has been called
            """
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function _match_tokens has a Cognitive Complexity of 11 (exceeds 5 allowed). Consider refactoring.
    Open

        def _match_tokens(self, token_pattern, idx):
            """ Indicate whether :obj:`tokens` begins with a pattern of tokens that match :obj:`token_pattern`
    
            Args:
                token_pattern (:obj:`tuple` of :obj:`int`): a tuple of Python token numbers, taken from the
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function get_str has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring.
    Open

        def get_str(self, obj_tables_token_to_str, with_units=False, number_units=' * __dimensionless__'):
            """ Generate string representation of expression, e.g. for evaluation by :obj:`eval`
    
            Args:
                obj_tables_token_to_str (:obj:`callable`): method to get string representation of a token
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function test_eval has a Cognitive Complexity of 10 (exceeds 5 allowed). Consider refactoring.
    Open

        def test_eval(self, values=1., with_units=False):
            """ Test evaluate this :obj:`ParsedExpression` with the value of all models given by :obj:`values`
    
            This is used to validate this :obj:`ParsedExpression`, as well as for testing.
    
    
    Severity: Minor
    Found in obj_tables/math/expression.py - About 1 hr to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function _get_coeffs_for_vars has a Cognitive Complexity of 9 (exceeds 5 allowed). Consider refactoring.
    Open

        def _get_coeffs_for_vars(self):
            """ Get coefficients for variables in a linear expression in standard form
    
            Returns:
                :obj:`list`: of :obj:`(:obj:`float`, :obj:`str`)`: coefficient and model id pairs
    Severity: Minor
    Found in obj_tables/math/expression.py - About 55 mins to fix

    Cognitive Complexity

    Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

    A method's cognitive complexity is based on a few simple rules:

    • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
    • Code is considered more complex for each "break in the linear flow of the code"
    • Code is considered more complex when "flow breaking structures are nested"

    Further reading

    Function make_obj has 7 arguments (exceeds 4 allowed). Consider refactoring.
    Open

        def make_obj(cls, model, model_type, primary_attr, expression, objs, allow_invalid_objects=False):
    Severity: Major
    Found in obj_tables/math/expression.py - About 50 mins to fix

      Avoid deeply nested control flow statements.
      Open

                                  if cls is not None:
                                      raise ParsedExpressionError(f"multiple models with id='{id}' in expression '{self.expression}'")
                                  cls, model = related_class, related_obj
      Severity: Major
      Found in obj_tables/math/expression.py - About 45 mins to fix

        Function _expr_has_a_constant has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.
        Open

            def _expr_has_a_constant(self):
                """ Determine whether the expression contains a constant term
        
                The expression must be transformed by removing unary operators, distribing multiplication,
                moving coeffecients left, and multiplying numbers before calling this.
        Severity: Minor
        Found in obj_tables/math/expression.py - About 45 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function visit_BinOp has a Cognitive Complexity of 8 (exceeds 5 allowed). Consider refactoring.
        Open

                def visit_BinOp(self, node):
                    self.generic_visit(node)
                    if (isinstance(node.op, ast.Mult) and
                        (isinstance(node.right, (ast.Num, ast.Name, ast.UnaryOp, ast.BinOp)) and
                         (isinstance(node.left, ast.BinOp) and
        Severity: Minor
        Found in obj_tables/math/expression.py - About 45 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function _get_disambiguated_id has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
        Open

            def _get_disambiguated_id(self, idx, case_fold_match=False):
                """ Try to parse a disambiguated `ObjTables` id from :obj:`self._py_tokens` at :obj:`idx`
        
                Look for a disambugated id (a Model written as :obj:`ModelType.model_id`). If tokens do not match,
                return :obj:`None`. If tokens match, but their values are wrong, return an error :obj:`str`.
        Severity: Minor
        Found in obj_tables/math/expression.py - About 35 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function _num_of_variables_in_a_product has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
        Open

            def _num_of_variables_in_a_product(node):
                """ Count all variables in a product of terms rooted at `node`
                """
                num_variables = 0
                if isinstance(node.op, ast.Mult):
        Severity: Minor
        Found in obj_tables/math/expression.py - About 35 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function _validate_nums has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
        Open

            def _validate_nums(self):
                """ Determine whether all numbers in the expression can be coerced into floats
        
                Returns:
                    :obj:`tuple`: :obj:`(False, error)` if :obj:`self.expression` has numbers that cannot be
        Severity: Minor
        Found in obj_tables/math/expression.py - About 35 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function visit_BinOp has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
        Open

                def visit_BinOp(self, node):
                    self.generic_visit(node)
                    if isinstance(node.op, ast.Sub):
                        if isinstance(node.right, (ast.Name, ast.Num)):
                            # subtrahend is Num or Name
        Severity: Minor
        Found in obj_tables/math/expression.py - About 35 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function _expr_has_constant_right_of_vars has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
        Open

            def _expr_has_constant_right_of_vars(self):
                """ Determine whether the expression contains constants to the right of a variable in a product
        
                The expression must be transformed by removing unary operators, and distribing multiplication
                before calling this.
        Severity: Minor
        Found in obj_tables/math/expression.py - About 35 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Function recreate_whitespace has a Cognitive Complexity of 7 (exceeds 5 allowed). Consider refactoring.
        Open

            def recreate_whitespace(self, expr):
                """ Insert the whitespace in this object's :obj:`expression` into an expression with the same token count
        
                Used to migrate an expression to a different set of model type names.
        
        
        Severity: Minor
        Found in obj_tables/math/expression.py - About 35 mins to fix

        Cognitive Complexity

        Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.

        A method's cognitive complexity is based on a few simple rules:

        • Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
        • Code is considered more complex for each "break in the linear flow of the code"
        • Code is considered more complex when "flow breaking structures are nested"

        Further reading

        Avoid too many return statements within this function.
        Open

                return None
        Severity: Major
        Found in obj_tables/math/expression.py - About 30 mins to fix

          Avoid too many return statements within this function.
          Open

                      return InvalidObject(model_obj, [attr_err])
          Severity: Major
          Found in obj_tables/math/expression.py - About 30 mins to fix

            Avoid too many return statements within this function.
            Open

                        return InvalidObject(model_obj, [attr_err])
            Severity: Major
            Found in obj_tables/math/expression.py - About 30 mins to fix

              Avoid too many return statements within this function.
              Open

                      return (self._obj_tables_tokens, self.related_objects, None)
              Severity: Major
              Found in obj_tables/math/expression.py - About 30 mins to fix

                Avoid too many return statements within this function.
                Open

                        return match_val
                Severity: Major
                Found in obj_tables/math/expression.py - About 30 mins to fix

                  There are no issues that match your filters.

                  Category
                  Status