-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
95 lines (67 loc) · 3.11 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
'''piadapter - pyodide Python component target from web app'''
import logging
import os
import sys
from dataclasses import dataclass
from functools import cache, partial
from piadapter.pi_digits import pi_digit_generator
from piadapter.utils import batched
@dataclass
class HistogramInterop:
num_digits: int
histogram: list[int]
logging.basicConfig(level=logging.DEBUG, format='PYTHON: {asctime} - {module} - {funcName} - {levelname} - {message}', style='{')
class PiAdapter:
def __init__(self) -> None:
self._cached_pi: list[int] = []
self.histograms = []
self._version = None
def __repr__(self) -> str:
return 'PiAdapter()'
def _cache_pi_digits(self, num_digits: int):
if len(self._cached_pi) < num_digits:
self._cached_pi = [d for d in pi_digit_generator(num_digits)]
def seed_pi_digits(self, pi_digits_seed: list[int]):
self._cached_pi = pi_digits_seed
def histograms_seed_cache(self, histograms: list[HistogramInterop]):
logging.info('PiAdapter.histograms_seed_cache(...)')
# seed the cache
self.histograms = {hi.num_digits: hi.histogram for hi in histograms}
from pprint import pformat
logging.info(f'PiAdapter.histograms_seed_cache: histograms={pformat(self.histograms, width=132, sort_dicts=False)}')
@cache
def histogram(self, num_digits: int) -> list[int]:
rc: list[int] = self.histograms[num_digits] if num_digits in self.histograms else []
if len(rc) == 0:
#
# leave this logic here for perf tests
#
self._cache_pi_digits(num_digits)
# leverage the fact that pi_digit_generator is idempotent for some max num_digits value
# the first num_digits of pi will be the same for any num_digits value up to and including num_digits
digits = [n for n in self._cached_pi[:num_digits]]
rc: list[int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]
for d in digits:
rc[d] += 1
from pprint import pformat
logging.info(f'PiAdapter.histogram({num_digits}): {pformat(rc)}')
return rc
def pi_digits(self, num_digits: int, n: int) -> list[list[int]]:
'''Return num_digits of PI batched n at a time'''
logging.info(f'PiAdapter.pi_digits({num_digits}, {n})')
self._cache_pi_digits(num_digits)
# leverage the fact that pi_digit_generator is idempotent for some max num_digits value
# the first num_digits of pi will be the same for any num_digits value up to and including num_digits
return [da for da in batched([int(digit) for digit in self._cached_pi[:num_digits]], n)]
def version(self):
if not self._version:
python_ver = f'{sys.version}]'
os_uname = os.uname()
os_version = f'{os_uname.sysname} {os_uname.machine} {os_uname.release}'
self._version = [
f'Python: {python_ver}',
f'Host: {os_version}'
]
logging.info(f'PiAdapter.version: {self._version}')
return self._version
pia = PiAdapter()