import numpy as np
import numpy.typing as npt
class ArrayableList:
"""
Stores a list and converts it to an array when you need one.
"""
lst: list[float]
converted: bool
arr: npt.NDArray[np.float64]
def __init__(self) -> None:
self.lst = []
self.converted = True
self.arr = np.array(self.lst)
def append(self, val: float) -> None:
self.lst.append(val)
self.converted = False
def array(self) -> npt.NDArray[np.float64]:
if self.converted:
return self.arr
else:
self.arr = np.array(self.lst)
self.converted = True
return self.arr
x = ArrayableList()
x.append(24601.0)
x.append(42.0)
print(x.lst)
arr1 = x.array()
print(arr1)
arr2 = x.array()
print(arr1 is arr2)
arr1[0] = 0
print(arr2)
x.append(0.0)
arr3 = x.array()
print(arr1 is arr3)
[24601.0, 42.0] [24601. 42.] True [ 0. 42.] False
import math
# camelCase
# snake_case
class StatsList:
"""
Stores a list of numbers and provides some simple statistics.
"""
lst: list[float]
sum: float
product: float
min: float
max: float
def __init__(self) -> None:
self.lst = []
self.sum = 0.0
self.product = 1.0
self.min = 0.0
self.max = 0.0
def append(self, val: float) -> None:
self.lst.append(val)
self.sum += val
self.product *= val
if len(self.lst) == 1:
self.min = val
self.max = val
else:
if val < self.min:
self.min = val
if val > self.max:
self.max = val
def pop(self, idx: int) -> float:
val = self.lst.pop(idx)
# sum
self.sum -= val
# product
if val == 0:
self.product = 1.0
for x in self.lst:
self.product *= x
else:
self.product /= val
# min
# max
if len(self.lst) == 0:
self.min = 0.0
self.max = 0.0
else:
if val == self.min:
self.min = min(self.lst)
if val == self.max:
self.max = max(self.lst)
return val
def mean(self) -> float:
return self.sum / len(self.lst)
def geometricMean(self) -> float:
return self.product ** (1/len(self.lst))
def __repr__(self) -> str:
return f"StatsList{self.lst}"
def __eq__(self, y) -> bool:
return self.lst == y.lst
def __ne__(self, y) -> bool:
return not (self == y)
def __lt__(self, y) -> bool:
return self.lst < y.lst
def __le__(self, y) -> bool:
return self < y or self == y
def __ge__(self, y) -> bool:
return not (self < y)
def __gt__(self, y) -> bool:
return self >= y and self != y
x = StatsList()
print(x.lst)
x.append(24601.0)
print(x.lst)
x.append(42.0)
print(x.lst)
print(x.sum, x.product)
x.append(-math.pi)
print(x.sum, x.product, x.mean(), x.geometricMean(), x.min, x.max)
x.pop(-1)
print(x.lst, x.mean())
x.append(0.0)
x.pop(-1)
print(x.lst, x.product)
print(x)
y = StatsList()
y.append(24601.0)
y.append(42.0)
print(x == y)
[] [24601.0] [24601.0, 42.0] 24643.0 1033242.0 24639.85840734641 -3246025.476580425 8213.286135782137 (74.03219834333919+128.22752892667992j) -3.141592653589793 24601.0 [24601.0, 42.0] 12321.5 [24601.0, 42.0] 1033242.0 StatsList[24601.0, 42.0] True
import csv
def csvStats(filename: str) -> dict[str, StatsList]:
r = {}
with open(filename) as ifh:
rdr = csv.DictReader(ifh)
for row in rdr:
for key in row:
# Individual cell in the CSV
if not (key in r):
r[key] = StatsList()
r[key].append(float(row[key]))
return r
stats = csvStats("nino34.csv")
for key in stats:
print(f"{key} mean: {stats[key].mean()}")
YR mean: 1987.3762376237623 MON mean: 6.485148514851486 TOTAL mean: 26.906149614961517 ClimAdjust mean: 26.894906490649106 ANOM mean: 0.011133113311331119
print(3 + 4)
print((3).__add__(4))
7 7
import numpy as np
import numpy.typing as npt
import typing
class ArrayableList:
"""
Stores a list and converts it into a NumPy array on demand, avoiding re-conversion.
"""
lst: list[float]
converted: bool
arr: npt.NDArray[np.float64]
def __init__(self, init: typing.Iterable) -> None:
self.lst = list(init)
self.converted = True
self.arr = np.array(self.lst)
def append(self, val: float) -> None:
self.lst.append(val)
self.converted = False
def array(self) -> npt.NDArray[np.float64]:
if self.converted:
return self.arr
else:
self.arr = np.array(self.lst)
self.converted = True
return self.arr
def __repr__(self) -> str:
return f"ArrayableList{self.lst}"
def __add__(self, y) -> ArrayableList:
return ArrayableList(self.array() + y.array())
def __sub__(self, y) -> ArrayableList:
return ArrayableList(self.array() - y.array())
def __mul__(self, y) -> ArrayableList:
return ArrayableList(self.array() * y.array())
def __truediv__(self, y) -> ArrayableList:
return ArrayableList(self.array() / y.array())
def __pow__(self, y) -> ArrayableList:
return ArrayableList(self.array() ** y.array())
def __mod__(self, y) -> ArrayableList:
return ArrayableList(self.array() % y.array())
x = ArrayableList([])
x.append(24601.0)
x.append(42.0)
arr1 = x.array()
#print(x.lst)
#print(arr1)
arr2 = x.array()
#print(arr2)
#print(arr1 is arr2)
arr1[0] = 0
#print(arr2)
x.append(123.0)
arr3 = x.array()
y = ArrayableList([])
y.append(1)
y.append(2)
y.append(3)
z = x + y
z.append(0)
print(z)
print(x)
ArrayableList[24602.0, 44.0, 126.0, 0] ArrayableList[24601.0, 42.0, 123.0]