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!")
Attendees asked us:
collections.namedtuple
?@classmethod
? ✓xarray.DataArray
?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
collections.namedtuple
?collections.namedtuple
?tuple
?dict
?@classmethod
?__init__
?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)
xarray.DataArray
?numpy.ndarray
?pandas.Series
or pandas.DataFrame
?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:
...