<commit_before>#!/usr/bin/env python3
from collections import namedtuple
from UliEngineering.EngineerIO import normalize_numeric, format_value

__all__ = ["ValueRange", "normalize_minmax_tuple"]

_ValueRange = namedtuple("ValueRange", ["min", "max", "unit"])

class ValueRange(_ValueRange):
    def __new__(cls, min, max, unit=None, significant_digits=4):
        self = super(ValueRange, cls).__new__(cls, min, max, unit)
        self.significant_digits = significant_digits
        return self

    def __repr__(self):
        return "ValueRange('{}', '{}')".format(
            format_value(self.min, self.unit, significant_digits=self.significant_digits),
            format_value(self.max, self.unit, significant_digits=self.significant_digits)
        )

def normalize_minmax_tuple(arg, name="field"):
    """
    Interprets arg either a single +- value or as
    a 2-tuple of + and - values.
    All vaues 

    If arg is a tuple:
        Return ValueRange(arg[0], arg[1]) (strings are normalized)
    Else:
        Return ValueRange(-arg, +arg) (strings are normalized)

    name is for debugging purposes and shown in the exception string
    """
    # Parse coefficient and compute min & max factors
    if isinstance(arg, tuple):
        # Check length 2
        if len(arg) != 2:
            raise ValueError("If {} is given as a tuple, it must have length 2. {} is {}".format(name, name, arg))
        # Parse tuple
        min_value = normalize_numeric(arg[0])
        max_value = normalize_numeric(arg[1])
    else:<commit_msg>Added ValueRange.minmax<commit_after>#!/usr/bin/env python3
from collections import namedtuple
from UliEngineering.EngineerIO import normalize_numeric, format_value

__all__ = ["ValueRange", "normalize_minmax_tuple"]

_ValueRange = namedtuple("ValueRange", ["min", "max", "unit"])

class ValueRange(_ValueRange):
    def __new__(cls, min, max, unit=None, significant_digits=4):
        self = super(ValueRange, cls).__new__(cls, min, max, unit)
        self.significant_digits = significant_digits
        return self

    def __repr__(self):
        return "ValueRange('{}', '{}')".format(
            format_value(self.min, self.unit, significant_digits=self.significant_digits),
            format_value(self.max, self.unit, significant_digits=self.significant_digits)
        )

    @property
    def minmax(self):
        """Return (min, max). Utility e.g. for unpacking a ValueRange ignoring Unit"""
        return (self.min, self.max)

def normalize_minmax_tuple(arg, name="field"):
    """
    Interprets arg either a single +- value or as
    a 2-tuple of + and - values.
    All vaues 

    If arg is a tuple:
        Return ValueRange(arg[0], arg[1]) (strings are normalized)
    Else:
        Return ValueRange(-arg, +arg) (strings are normalized)

    name is for debugging purposes and shown in the exception string
    """
    # Parse coefficient and compute min & max factors
    if isinstance(arg, tuple):
        # Check length 2
        if len(arg) != 2:
            raise ValueError("If {} is given as a tuple, it must have length 2. {} is {}".format(name, name, arg))
        # Parse tuple
        min_value = normalize_numeric(arg[0])
        max_value = normalize_numeric(arg[1])
    else:
{'fraction_non_alphanumeric': 0.11247695144437615, 'fraction_numerical': 0.006146281499692686, 'mean_word_length': 3.183804627249357, 'pattern_counts': {'":': 0, '<': 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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5368980', 'n_tokens_mistral': 996, 'n_tokens_neox': 954, 'n_words': 285}