from typing import List

import numpy as np

from .user_function_result import UserFunctionResult

def create_loop_state(x_init: np.ndarray, y_init: np.ndarray) -> None:
    """
    Creates a loop state object using the provided data

    :param x_init: x values for initial function evaluations.
    :param y_init: y values for initial function evaluations
    """
    if x_init.shape[0] != y_init.shape[0]:
        error_message = "X and Y should have the same length. Actual length x_init {}, y_init {}".format(x_init.shape[0], y_init.shape[0])
        raise ValueError(error_message)

    initial_results = []
    for x, y in zip(x_init, y_init):
        initial_results.append(UserFunctionResult(x, y))
    return LoopState(initial_results)


class LoopState(object):
    """
    Contains the state of the loop, which includes a history of all function evaluations
    """
    def __init__(self, initial_results: List[UserFunctionResult]) -> None:
        """
        :param initial_results: The function results from previous function evaluations
        """
        self.results = initial_results
        self.iteration = 0

    def update(self, results: List[UserFunctionResult]) -> None:
        """
        :param results: The latest function results since last update
        """
        if not results:
            raise ValueError("Cannot update state with empty result list.")

        self.iteration += 1
        self.results += results

    @property
    def X(self) -> np.ndarray:
        """
        :return: Function inputs for all function evaluations
                 in a 2d array: number of points by input dimensions.
        """
        return np.array([result.X for result in self.results])

    @property
    def Y(self) -> np.ndarray:
        """
        :return: Function outputs for all function evaluations
                 in a 2d array: number of points by output dimensions.
        """
        return np.array([result.Y for result in self.results])

@@ -96,656 +96,8 @@
 lt%0A%0A
-def create_loop_state(x_init: np.ndarray, y_init: np.ndarray) -%3E None:%0A    %22%22%22%0A    Creates a loop state object using the provided data%0A%0A    :param x_init: x values for initial function evaluations.%0A    :param y_init: y values for initial function evaluations%0A    %22%22%22%0A    if x_init.shape%5B0%5D != y_init.shape%5B0%5D:%0A        error_message = %22X and Y should have the same length. Actual length x_init %7B%7D, y_init %7B%7D%22.format(x_init.shape%5B0%5D, y_init.shape%5B0%5D)%0A        raise ValueError(error_message)%0A%0A    initial_results = %5B%5D%0A    for x, y in zip(x_init, y_init):%0A        initial_results.append(UserFunctionResult(x, y))%0A    return LoopState(initial_results)%0A%0A
 %0Acla
@@ -1309,28 +1309,681 @@
 or result in self.results%5D)%0A
+%0A%0Adef create_loop_state(x_init: np.ndarray, y_init: np.ndarray) -%3E LoopState:%0A    %22%22%22%0A    Creates a loop state object using the provided data%0A%0A    :param x_init: x values for initial function evaluations.%0A    :param y_init: y values for initial function evaluations%0A    %22%22%22%0A    if x_init.shape%5B0%5D != y_init.shape%5B0%5D:%0A        error_message = %22X and Y should have the same length. Actual length x_init %7B%7D, y_init %7B%7D%22.format(x_init.shape%5B0%5D, y_init.shape%5B0%5D)%0A        raise ValueError(error_message)%0A%0A    initial_results = %5B%5D%0A    for x, y in zip(x_init, y_init):%0A        initial_results.append(UserFunctionResult(x, y))%0A    return LoopState(initial_results)

Fix return type