# Path: pythics/lib.py
# class GrowableArray(object):
#     def __init__(self, length, cols=1, dtype=np.float64):
#         self.__cols = cols
#         self.__initial_length = int(length)
#         # number of rows to grow by if we run out of space
#         self.__n_grow = self.__initial_length
#         self.__dtype = dtype
#         self.clear()
#         # properties of arrays
#         self.ndim = 2
# 
#     def clear(self):
#         # actual array size
#         self.__N = self.__initial_length
#         # the next place to put a value in the buffer
#         #   also the number of rows that have been filled
#         self.__n = 0
#         # allocate the initial data
#         self.__data = np.zeros((self.__N, self.__cols), dtype=self.__dtype)
# 
#     def append(self, value):
#         # convert the appended object to an array if it starts as something else
#         if type(value) is not np.ndarray:
#             value = np.array(value)
#         # add the data
#         if value.ndim == 1:
#             # adding a single row of data
#             n = self.__n
#             if n + 1 > self.__N:
#                 # need to allocate more memory
#                 self.__N += self.__n_grow
#                 self.__data = np.resize(self.__data, (self.__N, self.__cols))
#             self.__data[n] = value
#             self.__n = n + 1
#         elif value.ndim == 2:
#             # adding multiple rows of data
#             # avoid loops for appending large arrays
#             n = self.__n
#             L = value.shape[0]
#             N_needed = n + L - self.__N
#             if N_needed > 0:
#                 # need to allocate more memory
#                 self.__N += (N_needed / self.__n_grow + 1) * self.__n_grow
#                 self.__data = np.resize(self.__data, (self.__N, self.__cols))
#             self.__data[n:n+L] = value
#             self.__n += L
# 
#     def __as_array(self):
#         return self.__data[:self.__n]
# 
#     # some standard array methods
# 
#     @property
#     def shape(self):
#         return (self.__n, self.__cols)
# 
#     def __getitem__(self, key):
#         return self.__as_array().__getitem__(key)
# 
#     def __iter__(self):
#         return self.__as_array().__iter__()
# 
#     def __len__(self):
#         return self.__n
# 
#     def __repr__(self):
#         return self.__as_array().__repr__()
# 
#     def __setitem__(self, key, value):
#         return self.__as_array().__setitem__(key, value)
# 
#     def __str__(self):
#         return self.__as_array().__str__()
# 
#     def sum(self, *args, **kwargs):
#         return self.__as_array().sum(*args, **kwargs)


import logging
import time
import numpy as np
from pythics.lib import GrowableArray

#
# private data shared among functions
#
class Private(object):
    pass

private = Private()


#
# functions
#
def initialize(log_text_box, data_chart, **kwargs):
    # setup the logger and log display box
    # examples of how to use:
    #    private.logger.debug('this is a debug message')
    #    private.logger.info('this is an info message')
    #    private.logger.warning('this is a warning message')
    #    private.logger.error('this is an error message')
    #    private.logger.critical('this is a critical error message')
    #    private.logger.exception('this is an exception')
    private.logger = logging.getLogger('log')
    #private.logger.setLevel(logging.DEBUG)
    private.logger.setLevel(logging.INFO)
    sh = logging.StreamHandler(log_text_box)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    sh.setFormatter(formatter)
    private.logger.addHandler(sh)
    # store data in a GrawableArray so we can efficiently append to it

# Path: pythics/lib.py
# class GrowableArray(object):
#     def __init__(self, length, cols=1, dtype=np.float64):
#         self.__cols = cols
#         self.__initial_length = int(length)
#         # number of rows to grow by if we run out of space
#         self.__n_grow = self.__initial_length
#         self.__dtype = dtype
#         self.clear()
#         # properties of arrays
#         self.ndim = 2
# 
#     def clear(self):
#         # actual array size
#         self.__N = self.__initial_length
#         # the next place to put a value in the buffer
#         #   also the number of rows that have been filled
#         self.__n = 0
#         # allocate the initial data
#         self.__data = np.zeros((self.__N, self.__cols), dtype=self.__dtype)
# 
#     def append(self, value):
#         # convert the appended object to an array if it starts as something else
#         if type(value) is not np.ndarray:
#             value = np.array(value)
#         # add the data
#         if value.ndim == 1:
#             # adding a single row of data
#             n = self.__n
#             if n + 1 > self.__N:
#                 # need to allocate more memory
#                 self.__N += self.__n_grow
#                 self.__data = np.resize(self.__data, (self.__N, self.__cols))
#             self.__data[n] = value
#             self.__n = n + 1
#         elif value.ndim == 2:
#             # adding multiple rows of data
#             # avoid loops for appending large arrays
#             n = self.__n
#             L = value.shape[0]
#             N_needed = n + L - self.__N
#             if N_needed > 0:
#                 # need to allocate more memory
#                 self.__N += (N_needed / self.__n_grow + 1) * self.__n_grow
#                 self.__data = np.resize(self.__data, (self.__N, self.__cols))
#             self.__data[n:n+L] = value
#             self.__n += L
# 
#     def __as_array(self):
#         return self.__data[:self.__n]
# 
#     # some standard array methods
# 
#     @property
#     def shape(self):
#         return (self.__n, self.__cols)
# 
#     def __getitem__(self, key):
#         return self.__as_array().__getitem__(key)
# 
#     def __iter__(self):
#         return self.__as_array().__iter__()
# 
#     def __len__(self):
#         return self.__n
# 
#     def __repr__(self):
#         return self.__as_array().__repr__()
# 
#     def __setitem__(self, key, value):
#         return self.__as_array().__setitem__(key, value)
# 
#     def __str__(self):
#         return self.__as_array().__str__()
# 
#     def sum(self, *args, **kwargs):
#         return self.__as_array().sum(*args, **kwargs)


# Path: pythics/examples/chart_recorder.py
import logging
import time
import numpy as np
from pythics.lib import GrowableArray


#
# private data shared among functions
#
class Private(object):
    pass

private = Private()


#
# functions
#
def initialize(log_text_box, data_chart, **kwargs):
    # setup the logger and log display box
    # examples of how to use:
    #    private.logger.debug('this is a debug message')
    #    private.logger.info('this is an info message')
    #    private.logger.warning('this is a warning message')
    #    private.logger.error('this is an error message')
    #    private.logger.critical('this is a critical error message')
    #    private.logger.exception('this is an exception')
    private.logger = logging.getLogger('log')
    #private.logger.setLevel(logging.DEBUG)
    private.logger.setLevel(logging.INFO)
    sh = logging.StreamHandler(log_text_box)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    sh.setFormatter(formatter)
    private.logger.addHandler(sh)
    # store data in a GrawableArray so we can efficiently append to it

    private.data = GrowableArray(cols=2, length=1000)