<jupyter_start><jupyter_text>tdir<jupyter_code>def tdir(obj, methods=False, **kwargs):
    out = dict()
    for k, v in hdir(obj, **kwargs).items():
        if v == 'attribute':
            out[k] = type(getattr(obj, k))
            
        # Only methods that don't require additional arguments are added.
        elif methods and v == 'method':
            try:
                out[k] = type(getattr(obj, k)())
            except TypeError:
                continue
        
    return out    
tdir(6)
tdir(0, magics=True)
tdir(0, True)
a = 0
a.conjugate()<jupyter_output><empty_output><jupyter_text>hdir (aybe change to cdir for callable or mdir for methoddir or adir for attrdir)<jupyter_code>a = [1, 2, 3]
s = 'abc'
t = ('a', 'b')
d = {'a': 1, 'b': 2}
n = np.arange(5)

items = [a, s, t, d, n]
for item in items:
    print(hdir(item), end='\n\n')
def is_internal(name):
    return bool(re.match('_[^_]', name))
[is_internal(attr) for attr in ['_add', '__add__']]
def mdir(obj, magics=False, internals=False):
    out = {attr: ('method' if callable(getattr(obj, attr)) else 'attribute')
              for attr in dir(obj)}
    if magics and internals:
        return out
    
    def keep_attr(attr, magics, internals):
        return (magics or not attr.startswith('__')) and \
               (internals or not re.match('_[^_]', attr))

    return {k: v for k, v in out.items() if keep_attr(k, magics, internals)}
def hdir_new(obj, magics=False, internals=False):
    output = dict()
    for attr in dir(obj):
        # Exclude magics or internals if specified.
        if (not magics and attr.startswith('__')) or \
           (not internals and re.match('_[^_]', attr)):
            continue
            
        # Handle rare cases where...
        try:
            is_method = callable(getattr(obj, attr))
        except Exception:
            continue
        
        # Update output to specify whether attr is callable.
        if is_method:
            output[attr] = 'method'
        else:
            output[attr] = 'attribute'
    return output
# Testing alternative to try/except block.

# invoked = getattr(obj, attr, None)
# if not invoked:
#     continue
    
# if callable(invoked):
#     output[attr] = 'method'
# else:
#     output[attr] = 'attribute'
class Block:
    
    def __init__(self, x):
        self.x = x
        
    def a(self):
        return 'a'
    
    def _b(self):
        return '_b'
    
    def __str__(self):
        return 'Block'
b = Block(4)
for magic_bool in (True, False):
    for internal_bool in (True, False):
        args = (magic_bool, internal_bool)
        print(args)
        print(hdir(n, *args) == mdir(n, *args) == hdir_new(n, *args))
df = pd.DataFrame(np.random.randint(10, size=(5, 3)))
df
hdir_new(df, magics=True)
for flag1 in (True, False):
    for flag2 in (True, False):
        print(flag1, flag2)
        print(hdir_new(b, flag1, flag2), end='\n\n')
hdir_new(b, True, True)
%%timeit -n 50 -r 50
hdir_new(n)
def attr_filter_factory(magics, internals):
    
    def filter_(attr):
        if attr.startswith('__'):
            if not magics: 
                return False
            return True
        
        if attr.startswith('_'):
            if not internals:
                return False
            return True
        
        return True
    
    return filter_
filters = dict(dummy_filter=attr_filter_factory(True, True),
               no_magic_filter=attr_filter_factory(False, True),
               no_internal_filter=attr_filter_factory(True, False),
               no_magic_or_internal_filter=attr_filter_factory(False, False))
for name, f in filters.items():
    print(f'{name} \n__add__: {f("__add__")} \n_recurse: {f("_internal")}\n')
mdir(a)<jupyter_output><empty_output><jupyter_text>Example for htimer docstring<jupyter_code>import time

@htimer
def count_to(x):
    for i in range(x):
        time.sleep(.5)
    print(x)
count_to(10)<jupyter_output>10

[TIMER]: function <count_to> executed in roughly 5.0365 seconds (conservatively).
{'fraction_non_alphanumeric': 0.12931248448746588, 'fraction_numerical': 0.008687019111442046, 'mean_word_length': 2.4444444444444446, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, '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}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '485191', 'license': 'MIT', 'n_tokens_mistral': 1394, 'n_tokens_neox': 1360, 'n_words': 369, 'path': 'notebooks/scratch_hdir.ipynb', 'repo_name': 'hdmamin/htools', 'size': '4029'}