# Path: formulaic/materializers/types/scoped_factor.py
# class ScopedFactor:
#     def __init__(self, factor, reduced=False):
#         self.factor = factor
#         self.reduced = reduced
# 
#     def __repr__(self):
#         return repr(self.factor) + ("-" if self.reduced else "")
# 
#     def __hash__(self):
#         return hash(repr(self))
# 
#     def __eq__(self, other):
#         if isinstance(other, ScopedFactor):
#             return self.factor == other.factor and self.reduced == other.reduced
#         return NotImplemented
# 
#     def __lt__(self, other):
#         if isinstance(other, ScopedFactor):
#             if self.factor == other.factor:
#                 return self.reduced > other.reduced
#             return self.factor < other.factor
#         return NotImplemented


from .scoped_factor import ScopedFactor


class ScopedTerm:

    __slots__ = ("factors", "scale")

    def __init__(self, factors, scale=None):
        self.factors = tuple(sorted(factors))
        self.scale = scale

    def __hash__(self):
        return hash(self.factors)

    def __eq__(self, other):
        if isinstance(other, ScopedTerm):
            return self.factors == other.factors
        return NotImplemented

    def __repr__(self):
        factor_repr = (

# Path: formulaic/materializers/types/scoped_factor.py
# class ScopedFactor:
#     def __init__(self, factor, reduced=False):
#         self.factor = factor
#         self.reduced = reduced
# 
#     def __repr__(self):
#         return repr(self.factor) + ("-" if self.reduced else "")
# 
#     def __hash__(self):
#         return hash(repr(self))
# 
#     def __eq__(self, other):
#         if isinstance(other, ScopedFactor):
#             return self.factor == other.factor and self.reduced == other.reduced
#         return NotImplemented
# 
#     def __lt__(self, other):
#         if isinstance(other, ScopedFactor):
#             if self.factor == other.factor:
#                 return self.reduced > other.reduced
#             return self.factor < other.factor
#         return NotImplemented


# Path: formulaic/materializers/types/scoped_term.py
from .scoped_factor import ScopedFactor



class ScopedTerm:

    __slots__ = ("factors", "scale")

    def __init__(self, factors, scale=None):
        self.factors = tuple(sorted(factors))
        self.scale = scale

    def __hash__(self):
        return hash(self.factors)

    def __eq__(self, other):
        if isinstance(other, ScopedTerm):
            return self.factors == other.factors
        return NotImplemented

    def __repr__(self):
        factor_repr = (

            ":".join(f.__repr__() for f in sorted(self.factors))