<commit_before>import math
from collections import OrderedDict

import numpy as np


class Property:
    """
    Base class for all properties.

    """
    def __init__(self):
        self._dtype = None
        self._ctype = None
        self._bit_width = None
        self._width = None
        self._best_type = None
        self._types = (
            # (bit_width, numpy_dtype, gpu_c_type)
            (8, np.uint8, 'char'),
            (16, np.uint16, 'short'),
            (32, np.uint32, 'int'),
        )

    @property
    def best_type(self):
        if self._best_type is None:
            self._best_type = self._types[-1]
            for t in self._types:
                type_width = t[0]
                if self.bit_width <= type_width:
                    self._best_type = t
                    break
        return self._best_type

    @property
    def dtype(self):
        if self._dtype is not None:
            return self._dtype
        self._dtype = self.best_type[1]
        return self._dtype

    @property
    def ctype(self):
        if self._ctype is not None:
            return self._ctype
        self._ctype = 'unsigned ' + self.best_type[2]
        return self._ctype

    @property
    def bit_width(self):
        if self._bit_width is None:
            self._bit_width = self.calc_bit_width()
        return self._bit_width

    @property
    def width(self):
        if self._width is None:
            type_width = self.best_type[0]
            self._width = int(math.ceil(self.bit_width / type_width))
        return self._width

    def calc_bit_width(self):
        return 1  # default, just for consistency

    def set_bsca(self, bsca):
        self._bsca = bsca


class IntegerProperty(Property):

    def __init__(self, max_val):
        self.max_val = max_val
        super(IntegerProperty, self).__init__()

    def calc_bit_width(self):
        return int(math.log2(self.max_val)) + 1

<commit_msg>Make IntegerProperty a descriptor (#20)<commit_after>import math
from collections import OrderedDict

import numpy as np

from hecate.core.variables import DeferredExpression


class Property:
    """
    Base class for all properties.

    """
    def __init__(self):
        self._dtype = None
        self._ctype = None
        self._bit_width = None
        self._width = None
        self._best_type = None
        self._bsca = None
        self._types = (
            # (bit_width, numpy_dtype, gpu_c_type)
            (8, np.uint8, 'char'),
            (16, np.uint16, 'short'),
            (32, np.uint32, 'int'),
        )

    @property
    def best_type(self):
        if self._best_type is None:
            self._best_type = self._types[-1]
            for t in self._types:
                type_width = t[0]
                if self.bit_width <= type_width:
                    self._best_type = t
                    break
        return self._best_type

    @property
    def dtype(self):
        if self._dtype is not None:
            return self._dtype
        self._dtype = self.best_type[1]
        return self._dtype

    @property
    def ctype(self):
        if self._ctype is not None:
            return self._ctype
        self._ctype = 'unsigned ' + self.best_type[2]
        return self._ctype

    @property
    def bit_width(self):
        if self._bit_width is None:
            self._bit_width = self.calc_bit_width()
        return self._bit_width

    @property
    def width(self):
        if self._width is None:
            type_width = self.best_type[0]
            self._width = int(math.ceil(self.bit_width / type_width))
        return self._width

    def calc_bit_width(self):
        return 1  # default, just for consistency

    def set_bsca(self, bsca):
        self._bsca = bsca


class IntegerProperty(Property):

    def __init__(self, max_val):
        self.max_val = max_val
        super(IntegerProperty, self).__init__()

    def calc_bit_width(self):
        return int(math.log2(self.max_val)) + 1

    def __get__(self, name):
        return DeferredExpression(self.var_name)

    def __set__(self, name, val):
        self._bsca._func_body += val.code


{'fraction_non_alphanumeric': 0.09134615384615384, 'fraction_numerical': 0.009134615384615385, 'mean_word_length': 1.8306122448979592, 'pattern_counts': {'":': 0, '<': 5, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '890777', 'n_tokens_mistral': 1297, 'n_tokens_neox': 1248, 'n_words': 313}