import numpy as np
from typing import List


class BaggingBoosting:
    def __init__(self, *, cls_assessor: object, n_assessors: int, fraction_rate: float):
        self.cls_assessor = cls_assessor
        self.n_assessors = n_assessors
        self.fraction_rate = fraction_rate

        self._assessors = [None] * n_assessors

    def predict(self, x: np.ndarray) -> List[np.ndarray]:
        return [assessor.predict(x) for assessor in self._assessors]

    def precision(self, x: np.ndarray, y: np.ndarray) -> List[float]:
        _ids = self._sample_data(x)
        return [assessor.precision(x[_ids], y[_ids]) for assessor in self._assessors]

    def _sample_data(self, x: np.ndarray) -> np.ndarray:
        n_fraction_records = int(self.fraction_rate * x.shape[0])
        return np.random.choice(x.shape[0], n_fraction_records, replace=False)

    def fit(self, x: np.ndarray, y: np.ndarray):
        for i in range(self.n_assessors):
            _ids = self._sample_data(x)
            assessor = self.cls_assessor()
            assessor.fit(x[_ids], y[_ids])
            self._assessors[i] = assessor

import numpy as np
from typing import List


class BaggingBoosting:
    def __init__(self, *, cls_assessor: object, n_assessors: int, fraction_rate: float):
        self.cls_assessor = cls_assessor
        self.n_assessors = n_assessors
        self.fraction_rate = fraction_rate

        self._assessors = [None] * n_assessors

    def predict(self, x: np.ndarray) -> List[np.ndarray]:
        return [assessor.predict(x) for assessor in self._assessors]

    def precision(self, x: np.ndarray, y: np.ndarray) -> List[float]:
        _ids = self._sample_data(x)
        return [assessor.precision(x[_ids], y[_ids]) for assessor in self._assessors]

    def _sample_data(self, x: np.ndarray) -> np.ndarray:
        n_fraction_records = int(self.fraction_rate * x.shape[0])
        return np.random.choice(x.shape[0], n_fraction_records, replace=False)

    def fit(self, x: np.ndarray, y: np.ndarray):
        for i in range(self.n_assessors):
            _ids = self._sample_data(x)
            assessor = self.cls_assessor()
            assessor.fit(x[_ids], y[_ids])
            self._assessors[i] = assessor
