seminars.fb

Grab Bag → “Stocking Stuffers”

Seminar (Fri, Dec 11, 2020; 12 PM PST)

Theme: Grab Bag

Topic: Stocking Stuffers

Keywords: simulation design

Presenter James Powell james@dutc.io
Date Friday, December 11, 2020
Time 12:00 PM PST
print("Let's go!")

Questions

Attendees asked us:

from pathlib import Path

def walk(d, *, history=None):
    if history is None:
        history = set()
    history.add(d.resolve())
    yield d
    for x in d.iterdir():
        if x.is_dir() and x.resolve() not in history:
            yield from walk(x, history=history)
        else:
            yield x

toplevel = Path('dir1')
for f in (x for x in walk(toplevel) if x.is_file()):
    print(f'{f.resolve() = }')
/tmp/prasad
├── dir1
│   ├── dir2
│   │   ├── dir3 -> ../dir3
│   │   ├── dir4
│   │   │   └── file
│   │   ├── dir5
│   │   │   └── file
│   │   └── file
│   ├── dir3
│   │   ├── dir2 -> ../dir2
│   │   ├── dir6
│   │   │   └── file
│   │   ├── dir7
│   │   │   └── file
│   │   ├── dir8 -> ../dir8
│   │   └── file
│   ├── dir8
│   │   └── file
│   └── file
└── script.py

11 directories, 9 files

What is a collections.namedtuple?

What is a @classmethod?

class A:
    z = 300

class B(A):
    y = 20
    def __init__(self):
        self.x = 1

def _getattr(obj, attr):
    if attr in obj.__dict__:
        return obj.__dict__[attr]
    for cls in type(obj).__mro__:
        if attr in cls.__dict__:
            rv = cls.__dict__[attr]
            if hasattr(rv, '__get__'):
                return rv.__get__(obj, cls)
            return rv

obj = B()
print(f'{ getattr(obj, "x") = }')
print(f'{_getattr(obj, "x") = }')
print(f'{ getattr(obj, "y") = }')
print(f'{_getattr(obj, "y") = }')
#    A
#  B   C
#    D

# A (A, object)
# B (B,    A, object)
# C    (C, A, object)
# D (B, C, A, object)

class A:
    foo = lambda s: ['A.foo']
class B(A):
    foo = lambda s: ['B.foo', *super().foo()]
class C(A):
    foo = lambda s: ['C.foo', *super().foo()]
class D(B, C):
    foo = lambda s: ['D.foo', *super().foo()]

print(f'{A().foo() = }')
print(f'{B().foo() = }')
print(f'{C().foo() = }')
print(f'{D().foo() = }')
#    A
#  B   
#    \
#     C
#  | /
#  D

# A (A, object)
# B (B, A, object)
# C (C, B, A, object)
# D (B, C, object)

class A:
    pass
class B(A):
    pass
class C(B):
    pass
class D(B, C):
    pass
class A:
    @staticmethod
    def foo():
        return f'foo()'

    @classmethod
    def bar(cls):
        return f'bar({cls!r})'

    def quux(self):
        return f'quux({self!r})'

class B(A):
    pass

x = B()
print(f'{x.foo()  = }')
print(f'{B.foo()  = }')
print(f'{x.bar()  = }')
print(f'{B.bar()  = }')
print(f'{x.quux() = }')
class Board:
    def __len__(self):
        pass

b = Board()
print(f'{len(b) = }')
from numpy import array
board = array([
    [0, 1, 0, 1],
    [0, 1, 1, 1],
    [0, 1, 0, 1],
])
print(f'{board[:, 1] = }')
print(f'{board[1, :] = }')
from pandas import Series
s = Series([1, 2, 3, 4], index=[2, 3, 4, 5]) 
print(s)
print(s.iloc[0])
print(s.loc['a'])
class BoM:
    def __init__(self, components):
        self.components = components
    def __repr__(self):
        return f'BoM({self.components!r})'
    @classmethod
    def from_file(cls, filename):
        with open(filename) as f:
            ...
            return BoM(...)
    @classmethod
    def from_file_v2(cls, filename):
        with open(filename) as f:
            ...
            return BoM(...)
    @classmethod
    def from_file(cls, filename):
        with open(filename) as f:
            ...
            return BoM(...)
data = '''
Resistor,10
Capacitor,30,80
Inductor,20
'''

class Component:
    TYPES = {}

    @classmethod
    def from_line(cls, line):
        typ, *_ = line.split(',')
        comp_cls = cls.TYPES[typ]
        return comp_cls.from_line(line)

    def __init_subclass__(cls, name):
        if 'from_line' not in cls.__dict__:
            raise TypeError('must implement a from_line classmethod!')
        cls.TYPES[name] = cls

class Resistor(Component, name='Resistor'):
    def __init__(self, r):
        self.r = r
    @classmethod
    def from_line(cls, line):
        _, r = line.split(',')
        r = int(r)
        return cls(r)

class Capacitor(Component, name='Capacitor'):
    def __init__(self, c, x):
        self.c, self.x = c, x
    @classmethod
    def from_line(cls, line):
        _, c, x = line.split(',')
        c, x = int(c), int(x)
        return cls(c, x)

class Inductor(Component, name='Inductor'):
    def __init__(self, i):
        self.i = i
    @classmethod
    def from_line(cls, line):
        _, i = line.split(',')
        i = int(i)
        return cls(i)

#  class Transistor(Component, name='Transistor'):
#      pass

components = [Component.from_line(line) for line in data.strip().splitlines()]
print(f'{components = }')
from pandas import MultiIndex, DataFrame
df = DataFrame({
    'x': [1, 2, 3, 4]
})
#  df.index = *((*row,) for row in ['aa', 'ab', 'ac']),
MultiIndex.from_tuples
MultiIndex.from_arrays
df.index = MultiIndex.from_product([[*'ab'], [*'ab']])
print(df)

What is a xarray.DataArray?

What is a decorator?

from random import random
from time import sleep
from time import perf_counter
from collections import deque
from functools import wraps

telemetry = deque(maxlen=10)
def timed(f):
    @wraps(f)
    def new_f(*args, **kwargs):
        start = perf_counter()
        f(*args, **kwargs)
        stop = perf_counter()
        telemetry.append((stop - start))
    return new_f

@timed
def slow(msg):
    ''' do something slowly '''
    sleep(random())
    print(f'{msg!r}')
#  slow = timed(slow)

@timed
def fast(msg, msg2):
    ''' do something quickly '''
    sleep(random() / 100)
    print(f'{msg!r}, {msg2!r}')

slow('first')
slow('second')
slow('third')
fast('fourth', 'fifth')

print(f'{telemetry = }')
from itertools import product
from collections import namedtuple

def simulate(strategies):
    for x, y in product(strategies, strategies):
        print(f'{x.name} v {y.name}')

Strategy = namedtuple('Strategy', 'func name author example')
STRATEGIES = []
def strategy(name, author, example=None):
    def dec(f):
        s = Strategy(f, name, author, example)
        STRATEGIES.append(s)
        return f
    return dec

@strategy(
    name = "Adrian's Winning Strategy",
    author = 'Adrian Lewis',
    example = ...,
)
def adrian_strat():
    pass

@strategy(
    name = "James Winning Strategy",
    author = 'James P',
    example = ...,
)
def james_strat():
    pass

if __name__ == '__main__':
    simulate(STRATEGIES)

class Component:
    TYPES = {}
    def from_line(cls, line):
        ...

    @classmethod
    def register(name):
        def dec(comp_cls):
            if 'from_line' not in comp_cls.__dict__:
                raise TypeError("must implement from_line classmethod!")
            cls.TYPES[name] = comp_cls
            return comp_cls
        return dec

@Component.register('Resistor')
class Resistor:
    ...