<commit_before>"""Defines the VarKey class"""
from .small_classes import Strings, Quantity
from .small_scripts import mag, unitstr, veckeyed


class Count(object):
    "Like python 2's itertools.count, for Python 3 compatibility."

    def __init__(self):
        self.count = -1

    def next(self):
        "Increment self.count and return it"
        self.count += 1
        return self.count


class VarKey(object):
    """An object to correspond to each 'variable name'.

    Arguments
    ---------
    name : str, VarKey, or Monomial
        Name of this Variable, or object to derive this Variable from.

    **kwargs :
        Any additional attributes, which become the descr attribute (a dict).

    Returns
    -------
    VarKey with the given name and descr.
    """
    new_unnamed_id = Count().next
    subscripts = ("models", "idx")
    eq_ignores = frozenset(["units", "value"])
    # ignore value in ==. Also skip units, since pints is weird and the unitstr
    #    will be compared anyway

    def __init__(self, name=None, **kwargs):
        self.descr = kwargs
        # Python arg handling guarantees 'name' won't appear in kwargs
        if isinstance(name, VarKey):
            self.descr.update(name.descr)
        elif hasattr(name, "c") and hasattr(name, "exp"):
            if mag(name.c) == 1 and len(name.exp) == 1:
                var = list(name.exp)[0]
                self.descr.update(var.descr)
            else:
                raise TypeError("variables can only be formed from monomials"
                                " with a c of 1 and a single variable")
        else:
            if name is None:
                name = "\\fbox{%s}" % VarKey.new_unnamed_id()
            self.descr["name"] = str(name)

        from . import units as ureg  # update in case user has disabled units

        if "value" in self.descr:
            value = self.descr["value"]
            if isinstance(value, Quantity):
                self.descr["value"] = value.magnitude
                self.descr["units"] = Quantity(1.0, value.units)
        if ureg and "units" in self.descr:
            units = self.descr["units"]
            if isinstance(units, Strings):
                units = units.replace("-", "dimensionless")
                self.descr["units"] = Quantity(1.0, units)
            elif isinstance(units, Quantity):
                self.descr["units"] = units
            else:
                raise ValueError("units must be either a string"
                                 " or a Quantity from gpkit.units.")
        selfstr = str(self)
        self._hashvalue = hash(selfstr)
        self.key = self
        self.keys = set([self, self.name, selfstr, self.latex(),
                         self.str_without("models")])
        if "idx" in self.descr:
            self.veckey = veckeyed(self)
            self.keys.add(self.veckey)
        self.descr["unitrepr"] = repr(self.units)
        self._unitstr = None

    def __repr__(self):
        return self.str_without()

    def str_without(self, excluded=None):
        "Returns string without certain fields (such as 'models')."
        if excluded is None:<commit_msg>close #776<commit_after>"""Defines the VarKey class"""
from .small_classes import Strings, Quantity
from .small_scripts import mag, unitstr, veckeyed


class Count(object):
    "Like python 2's itertools.count, for Python 3 compatibility."

    def __init__(self):
        self.count = -1

    def next(self):
        "Increment self.count and return it"
        self.count += 1
        return self.count


class VarKey(object):
    """An object to correspond to each 'variable name'.

    Arguments
    ---------
    name : str, VarKey, or Monomial
        Name of this Variable, or object to derive this Variable from.

    **kwargs :
        Any additional attributes, which become the descr attribute (a dict).

    Returns
    -------
    VarKey with the given name and descr.
    """
    new_unnamed_id = Count().next
    subscripts = ("models", "idx")
    eq_ignores = frozenset(["units", "value"])
    # ignore value in ==. Also skip units, since pints is weird and the unitstr
    #    will be compared anyway

    def __init__(self, name=None, **kwargs):
        self.descr = kwargs
        # Python arg handling guarantees 'name' won't appear in kwargs
        if isinstance(name, VarKey):
            self.descr.update(name.descr)
        elif hasattr(name, "c") and hasattr(name, "exp"):
            if mag(name.c) == 1 and len(name.exp) == 1:
                var = list(name.exp)[0]
                self.descr.update(var.descr)
            else:
                raise TypeError("variables can only be formed from monomials"
                                " with a c of 1 and a single variable")
        else:
            if name is None:
                name = "\\fbox{%s}" % VarKey.new_unnamed_id()
            self.descr["name"] = str(name)

        from . import units as ureg  # update in case user has disabled units

        if "value" in self.descr:
            value = self.descr["value"]
            if isinstance(value, Quantity):
                self.descr["value"] = value.magnitude
                self.descr["units"] = Quantity(1.0, value.units)
        if ureg and "units" in self.descr:
            units = self.descr["units"]
            if isinstance(units, Strings):
                if units == "-":
                    units = "dimensionless"
                self.descr["units"] = Quantity(1.0, units)
            elif isinstance(units, Quantity):
                self.descr["units"] = units
            else:
                raise ValueError("units must be either a string"
                                 " or a Quantity from gpkit.units.")
        selfstr = str(self)
        self._hashvalue = hash(selfstr)
        self.key = self
        self.keys = set([self, self.name, selfstr, self.latex(),
                         self.str_without("models")])
        if "idx" in self.descr:
            self.veckey = veckeyed(self)
            self.keys.add(self.veckey)
        self.descr["unitrepr"] = repr(self.units)
        self._unitstr = None

    def __repr__(self):
        return self.str_without()

    def str_without(self, excluded=None):
        "Returns string without certain fields (such as 'models')."
        if excluded is None:
{'fraction_non_alphanumeric': 0.11065573770491803, 'fraction_numerical': 0.004255989911727617, 'mean_word_length': 1.884090909090909, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2525468', 'n_tokens_mistral': 1838, 'n_tokens_neox': 1759, 'n_words': 553}