<commit_before>"""
Simple Data Structures: 
Dict, DefaultDict, RecursiveDict, Struct
"""

import copy

def Dict(**entries):  
    """Create a dict out of the argument=value arguments. 
    >>> Dict(a=1, b=2, c=3)
    {'a': 1, 'c': 3, 'b': 2}
    """
    return entries

class DefaultDict(dict):
    """Dictionary with a default value for unknown keys."""

    def __init__(self, default):
        self.default = default

    def __getitem__(self, key):
        if key in self: return self.get(key)
        return self.setdefault(key, copy.deepcopy(self.default))
    
    def __copy__(self):
        copy = DefaultDict(self.default)
        copy.update(self)
        return copy
    
class RecursiveDict(dict):
    """Dictionary witch contains dictionary and that continues n-times, plust has a default value for unknown keys at last dictionary."""

    def __init__(self, ncount, default = None):
        self.ncount = ncount - 1
        self.default = default

    def __getitem__(self, key):
        if key in self: 
           return self.get(key)
        if self.ncount > 0:
           return self.setdefault(key, RecursiveDict(self.ncount - 1, self.default))
        return self.setdefault(key, copy.deepcopy(self.default))
    
    def __copy__(self):
        copy = RecursiveDict(self.ncount, self.default)
        copy.update(self)
        return copy
    
class Struct:
    """Create an instance with argument=value slots.
    This is for making a lightweight object whose class doesn't matter."""

    def __init__(self, **entries):
        self.__dict__.update(entries)

    def __cmp__(self, other):
        if isinstance(other, Struct):
            return cmp(self.__dict__, other.__dict__)
        else:
            return cmp(self.__dict__, other)

    def __repr__(self):
        args = ['%s=%s' % (k, repr(v)) for (k, v) in vars(self).items()]
        return 'Struct(%s)' % ', '.join(args)

def update(x, **entries):
    """Update a dict; or an object with slots; according to entries.
    >>> update({'a': 1}, a=10, b=20)
    {'a': 10, 'b': 20}
    >>> update(Struct(a=1), a=10, b=20)
    Struct(a=10, b=20)
    """
    if isinstance(x, dict):
        x.update(entries)   
    else:
        x.__dict__.update(entries) 
    return x <commit_msg>Add some doctests to structs<commit_after>"""
Simple Data Structures: 
Dict, DefaultDict, RecursiveDict, Struct
"""

import copy

def Dict(**entries):  
    """Create a dict out of the argument=value arguments. 
    >>> Dict(a=1, b=2, c=3)
    {'a': 1, 'c': 3, 'b': 2}
    """
    return entries

class DefaultDict(dict):
    """Dictionary with a default value for unknown keys.
    >>> d = DefaultDict([])
    >>> d[1].append(2)
    >>> d
    {1: [2]}
    """

    def __init__(self, default):
        self.default = default

    def __getitem__(self, key):
        """
        >>> d = DefaultDict(0)
        >>> d[1] += 1
        >>> d[1]
        1
        """
        if key in self: return self.get(key)
        return self.setdefault(key, copy.deepcopy(self.default))
    
    def __copy__(self):
        """
        >>> d = DefaultDict(0)
        >>> d[1] += 1
        >>> p = d.copy()
        >>> p
        {1: 1}
        """
        copy = DefaultDict(self.default)
        copy.update(self)
        return copy
    
class RecursiveDict(dict):
    """Dictionary witch contains dictionary and that continues n-times, plust has a default value for unknown keys at last dictionary.
    >>> d = RecursiveDict(2, [])
    >>> d[1]['keyword'].append(5)
    >>> d[1]['keyword']
    [5]
    """

    def __init__(self, ncount, default = None):
        self.ncount = ncount - 1
        self.default = default

    def __getitem__(self, key):
        """
        >>> d = RecursiveDict(2, [])
        >>> d[1]['keyword'].append(5)
        >>> d[1]['keyword']
        [5]
        """
        if key in self: 
           return self.get(key)
        if self.ncount > 0:
           return self.setdefault(key, RecursiveDict(self.ncount - 1, self.default))
        return self.setdefault(key, copy.deepcopy(self.default))
    
    def __copy__(self):
        """
        >>> d = RecursiveDict(2, [])
        >>> d[1]['keyword'].append(5)
        >>> p = d.copy()
        >>> p
        {1: {'keyword': [5]}}
        """
        copy = RecursiveDict(self.ncount, self.default)
        copy.update(self)
        return copy
    
class Struct:
    """Create an instance with argument=value slots.
    This is for making a lightweight object whose class doesn't matter.
    >>> a = Struct(a=1, b=2, c=3)
    >>> a.a
    1
    >>> a.b
    2
    >>> a.c
    3
    """

    def __init__(self, **entries):
        self.__dict__.update(entries)

    def __cmp__(self, other):
        """
        >>> a = Struct(a=1, b=2, c=3)
        >>> b = Struct(a=1, b=2, c=3)
        >>> c = Struct(a=3, b=2, c=3)
        >>> a == b
        True
        >>> a == c
        False
        """
        if isinstance(other, Struct):
            return cmp(self.__dict__, other.__dict__)
        else:
            return cmp(self.__dict__, other)

    def __repr__(self):
        args = ['%s=%s' % (k, repr(v)) for (k, v) in vars(self).items()]
        return 'Struct(%s)' % ', '.join(args)

def update(x, **entries):
    """Update a dict; or an object with slots; according to entries.
    >>> update({'a': 1}, a=10, b=20)
    {'a': 10, 'b': 20}
    >>> update(Struct(a=1), a=10, b=20)
    Struct(a=10, b=20)
    """
    if isinstance(x, dict):
        x.update(entries)   
    else:
        x.__dict__.update(entries) 
    return x 

if __name__ == "__main__":
    import doctest
    doctest.testmod()
{'fraction_non_alphanumeric': 0.15503462972828982, 'fraction_numerical': 0.01740365832001421, 'mean_word_length': 2.1819209039548024, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 110, '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': '82427', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1810, 'n_words': 496}