import sys
import ctypes

import pyglet
from pyglet.gl import *

_enable_vbo = pyglet.options['graphics_vbo']

# Enable workaround permanently if any VBO is created on a context that has
# this workaround.  (On systems with multiple contexts where one is
# unaffected, the workaround will be enabled unconditionally on all of the
# contexts anyway.  This is completely unlikely anyway).
_workaround_vbo_finish = False

def create_buffer(size, target=GL_ARRAY_BUFFER, usage=GL_DYNAMIC_DRAW, vbo=True):
    """Create a buffer of vertex data.

    :Parameters:
        `size` : int
            Size of the buffer, in bytes
        `target` : int
            OpenGL target buffer
        `usage` : int
            OpenGL usage constant
        `vbo` : bool
            True if a `VertexBufferObject` should be created if the driver
            supports it; otherwise only a `VertexArray` is created.

    :rtype: `AbstractBuffer`
    """
    from pyglet import gl
    if (vbo and
        gl_info.have_version(1, 5) and
        _enable_vbo and
        not gl.current_context._workaround_vbo):
        return VertexBufferObject(size, target, usage)
    else:
        return VertexArray(size)

def create_mappable_buffer(size, target=GL_ARRAY_BUFFER, usage=GL_DYNAMIC_DRAW, vbo=True):
    """Create a mappable buffer of vertex data.

    :Parameters:
        `size` : int
            Size of the buffer, in bytes
        `target` : int
            OpenGL target buffer
        `usage` : int
            OpenGL usage constant
        `vbo` : bool
            True if a :py:class:`VertexBufferObject` should be created if the driver
            supports it; otherwise only a :py:class:`VertexArray` is created.

    :rtype: :py:class:`AbstractBuffer` with :py:class:`AbstractMappable`
    """
    from pyglet import gl
    if (vbo and
        gl_info.have_version(1, 5) and
        _enable_vbo and
        not gl.current_context._workaround_vbo):
        return MappableVertexBufferObject(size, target, usage)
    else:
        return VertexArray(size)

class AbstractBuffer:
    """Abstract buffer of byte data.

    :Ivariables:
        `size` : int
            Size of buffer, in bytes
        `ptr` : int
            Memory offset of the buffer, as used by the ``glVertexPointer``
            family of functions
        `target` : int
            OpenGL buffer target, for example ``GL_ARRAY_BUFFER``
        `usage` : int
            OpenGL buffer usage, for example ``GL_DYNAMIC_DRAW``

    """

    ptr = 0
    size = 0

    def bind(self):
        """Bind this buffer to its OpenGL target."""
        raise NotImplementedError('abstract')

    def unbind(self):
        """Reset the buffer's OpenGL target."""
        raise NotImplementedError('abstract')

    def set_data(self, data):
        """Set the entire contents of the buffer.

        :Parameters:
            `data` : sequence of int or ctypes pointer
                The byte array to set.

        """
        raise NotImplementedError('abstract')

    def set_data_region(self, data, start, length):
        """Set part of the buffer contents.

        :Parameters:
            `data` : sequence of int or ctypes pointer
                The byte array of data to set
            `start` : int
                Offset to start replacing data
            `length` : int
                Length of region to replace

        """
        raise NotImplementedError('abstract')

    def map(self, invalidate=False):
        """Map the entire buffer into system memory.

        The mapped region must be subsequently unmapped with `unmap` before
        performing any other operations on the buffer.

        :Parameters:
            `invalidate` : bool
                If True, the initial contents of the mapped block need not
                reflect the actual contents of the buffer.

        :rtype: ``POINTER(ctypes.c_ubyte)``
        :return: Pointer to the mapped block in memory
        """
        raise NotImplementedError('abstract')

    def unmap(self):
        """Unmap a previously mapped memory block."""
        raise NotImplementedError('abstract')

    def resize(self, size):
        """Resize the buffer to a new size.

        :Parameters:
            `size` : int
                New size of the buffer, in bytes

        """

    def delete(self):
        """Delete this buffer, reducing system resource usage."""
        raise NotImplementedError('abstract')

class AbstractMappable:
    def get_region(self, start, size, ptr_type):
        """Map a region of the buffer into a ctypes array of the desired
        type.  This region does not need to be unmapped, but will become
        invalid if the buffer is resized.

        Note that although a pointer type is required, an array is mapped.
        For example::

            get_region(0, ctypes.sizeof(c_int) * 20, ctypes.POINTER(c_int * 20))

        will map bytes 0 to 80 of the buffer to an array of 20 ints.

        Changes to the array may not be recognised until the region's
        :py:meth:`AbstractBufferRegion.invalidate` method is called.

        :Parameters:
            `start` : int
                Offset into the buffer to map from, in bytes
            `size` : int
                Size of the buffer region to map, in bytes
            `ptr_type` : ctypes pointer type
                Pointer type describing the array format to create

        :rtype: :py:class:`AbstractBufferRegion`
        """
        raise NotImplementedError('abstract')

class VertexArray(AbstractBuffer, AbstractMappable):
    """A ctypes implementation of a vertex array.

    Many of the methods on this class are effectively no-op's, such as
    :py:meth:`bind`, :py:meth:`unbind`, :py:meth:`map`, :py:meth:`unmap` and
    :py:meth:`delete`; they exist in order to present
    a consistent interface with :py:class:`VertexBufferObject`.

    This buffer type is also mappable, and so :py:meth:`get_region` can be used.
    """

    def __init__(self, size):
        self.size = size

        self.array = (ctypes.c_byte * size)()
        self.ptr = ctypes.cast(self.array, ctypes.c_void_p).value

    def bind(self):
        pass

    def unbind(self):
        pass

    def set_data(self, data):
        ctypes.memmove(self.ptr, data, self.size)

    def set_data_region(self, data, start, length):
        ctypes.memmove(self.ptr + start, data, length)

    def map(self, invalidate=False):
        return self.array

    def unmap(self):
        pass

    def get_region(self, start, size, ptr_type):
        array = ctypes.cast(self.ptr + start, ptr_type).contents
        return VertexArrayRegion(array)

    def delete(self):
        pass

    def resize(self, size):
        array = (ctypes.c_byte * size)()
        ctypes.memmove(array, self.array, min(size, self.size))
        self.size = size
        self.array = array
        self.ptr = ctypes.cast(self.array, ctypes.c_void_p).value

class VertexBufferObject(AbstractBuffer):
    """Lightweight representation of an OpenGL VBO.

    The data in the buffer is not replicated in any system memory (unless it
    is done so by the video driver).  While this can improve memory usage and
    possibly performance, updates to the buffer are relatively slow.

    This class does not implement :py:class:`AbstractMappable`, and so has no
    :py:meth:`~AbstractMappable.get_region` method.  See
    :py:class:`MappableVertexBufferObject` for a VBO class
    that does implement :py:meth:`~AbstractMappable.get_region`.
    """

    def __init__(self, size, target, usage):
        self.size = size
        self.target = target
        self.usage = usage
        self._context = pyglet.gl.current_context

        id = GLuint()
        glGenBuffers(1, id)
        self.id = id.value
        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glBindBuffer(target, self.id)
        glBufferData(target, self.size, None, self.usage)
        glPopClientAttrib()

        global _workaround_vbo_finish
        if pyglet.gl.current_context._workaround_vbo_finish:
            _workaround_vbo_finish = True

    def bind(self):
        glBindBuffer(self.target, self.id)

    def unbind(self):
        glBindBuffer(self.target, 0)

    def set_data(self, data):
        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glBindBuffer(self.target, self.id)
        glBufferData(self.target, self.size, data, self.usage)
        glPopClientAttrib()

    def set_data_region(self, data, start, length):
        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glBindBuffer(self.target, self.id)
        glBufferSubData(self.target, start, length, data)
        glPopClientAttrib()

    def map(self, invalidate=False):
        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glBindBuffer(self.target, self.id)
        if invalidate:
            glBufferData(self.target, self.size, None, self.usage)
        ptr = ctypes.cast(glMapBuffer(self.target, GL_WRITE_ONLY),
                          ctypes.POINTER(ctypes.c_byte * self.size)).contents
        glPopClientAttrib()
        return ptr

    def unmap(self):
        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glUnmapBuffer(self.target)
        glPopClientAttrib()

    def __del__(self):
        try:
            if self.id is not None:
                self._context.delete_buffer(self.id)
        except:
            pass

    def delete(self):
        id = GLuint(self.id)
        glDeleteBuffers(1, id)
        self.id = None

    def resize(self, size):
        # Map, create a copy, then reinitialize.
        temp = (ctypes.c_byte * size)()

        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glBindBuffer(self.target, self.id)
        data = glMapBuffer(self.target, GL_READ_ONLY)
        ctypes.memmove(temp, data, min(size, self.size))
        glUnmapBuffer(self.target)

        self.size = size
        glBufferData(self.target, self.size, temp, self.usage)
        glPopClientAttrib()

class MappableVertexBufferObject(VertexBufferObject, AbstractMappable):
    """A VBO with system-memory backed store.

    Updates to the data via :py:meth:`set_data`, :py:meth:`set_data_region` and
    :py:meth:`map` will be held in local memory until :py:meth:`bind` is
    called.  The advantage is that fewer OpenGL calls are needed, increasing
    performance.

    There may also be less performance penalty for resizing this buffer.

    Updates to data via :py:meth:`map` are committed immediately.
    """

    def __init__(self, size, target, usage):
        super(MappableVertexBufferObject, self).__init__(size, target, usage)
        self.data = (ctypes.c_byte * size)()
        self.data_ptr = ctypes.cast(self.data, ctypes.c_void_p).value
        self._dirty_min = sys.maxsize
        self._dirty_max = 0

    def bind(self):
        # Commit pending data
        super(MappableVertexBufferObject, self).bind()
        size = self._dirty_max - self._dirty_min
        if size > 0:
            if size == self.size:
                glBufferData(self.target, self.size, self.data, self.usage)
            else:
                glBufferSubData(self.target, self._dirty_min, size,
                                self.data_ptr + self._dirty_min)
            self._dirty_min = sys.maxsize
            self._dirty_max = 0

    def set_data(self, data):
        super(MappableVertexBufferObject, self).set_data(data)
        ctypes.memmove(self.data, data, self.size)
        self._dirty_min = 0
        self._dirty_max = self.size

    def set_data_region(self, data, start, length):
        ctypes.memmove(self.data_ptr + start, data, length)
        self._dirty_min = min(start, self._dirty_min)
        self._dirty_max = max(start + length, self._dirty_max)

    def map(self, invalidate=False):
        self._dirty_min = 0
        self._dirty_max = self.size
        return self.data

    def unmap(self):
        pass

    def get_region(self, start, size, ptr_type):
        array = ctypes.cast(self.data_ptr + start, ptr_type).contents
        return VertexBufferObjectRegion(self, start, start + size, array)

    def resize(self, size):
        data = (ctypes.c_byte * size)()
        ctypes.memmove(data, self.data, min(size, self.size))
        self.data = data
        self.data_ptr = ctypes.cast(self.data, ctypes.c_void_p).value

        self.size = size
        glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT)
        glBindBuffer(self.target, self.id)
        glBufferData(self.target, self.size, self.data, self.usage)
        glPopClientAttrib()

        self._dirty_min = sys.maxsize
        self._dirty_max = 0

class AbstractBufferRegion:
    """A mapped region of a buffer.

    Buffer regions are obtained using :py:meth:`~AbstractMappable.get_region`.

    :Ivariables:
        `array` : ctypes array
            Array of data, of the type and count requested by
            :py:meth:`~AbstractMappable.get_region`.

    """

    def invalidate(self):
        """Mark this region as changed.

        The buffer may not be updated with the latest contents of the
        array until this method is called.  (However, it may not be updated
        until the next time the buffer is used, for efficiency).
        """
        pass

class VertexBufferObjectRegion(AbstractBufferRegion):
    """A mapped region of a VBO."""

    def __init__(self, buffer, start, end, array):
        self.buffer = buffer
        self.start = start
        self.end = end
        self.array = array

    def invalidate(self):
        buffer = self.buffer
        buffer._dirty_min = min(buffer._dirty_min, self.start)
        buffer._dirty_max = max(buffer._dirty_max, self.end)

class VertexArrayRegion(AbstractBufferRegion):
    """A mapped region of a vertex array.

    The :py:meth:`~AbstractBufferRegion.invalidate` method is a no-op but is
    provided in order to present a consistent interface with
    :py:meth:`VertexBufferObjectRegion`.
    """

    def __init__(self, array):
        self.array = array

class IndirectArrayRegion(AbstractBufferRegion):
    """A mapped region in which data elements are not necessarily contiguous.

    This region class is used to wrap buffer regions in which the data
    must be accessed with some stride.  For example, in an interleaved buffer
    this region can be used to access a single interleaved component as if the
    data was contiguous.
    """

    def __init__(self, region, size, component_count, component_stride):
        """Wrap a buffer region.

        Use the `component_count` and `component_stride` parameters to specify
        the data layout of the encapsulated region.  For example, if RGBA
        data is to be accessed as if it were packed RGB, ``component_count``
        would be set to 3 and ``component_stride`` to 4.  If the region
        contains 10 RGBA tuples, the ``size`` parameter is ``3 * 10 = 30``.

        :Parameters:
            `region` : `AbstractBufferRegion`
                The region with interleaved data
            `size` : int
                The number of elements that this region will provide access to.
            `component_count` : int
                The number of elements that are contiguous before some must
                be skipped.
            `component_stride` : int
                The number of elements of interleaved data separating
                the contiguous sections.

        """
        self.region = region
        self.size = size
        self.count = component_count
        self.stride = component_stride
        self.array = self

    def __repr__(self):
        return 'IndirectArrayRegion(size=%d, count=%d, stride=%d)' % (
            self.size, self.count, self.stride)

    def __getitem__(self, index):
        count = self.count
        if not isinstance(index, slice):
            elem = index // count
            j = index % count
            return self.region.array[elem * self.stride + j]

        start = index.start or 0
        stop = index.stop
        step = index.step or 1
        if start < 0:
            start = self.size + start
        if stop is None:
            stop = self.size
        elif stop < 0:
            stop = self.size + stop

        assert step == 1 or step % count == 0, "Step must be multiple of component count"

        data_start = (start // count) * self.stride + start % count
        data_stop = (stop // count) * self.stride + stop % count
        data_step = step * self.stride

        #  TODO stepped getitem is probably wrong, see setitem for correct.
        value_step = step * count

        value = [0] * ((stop - start) // step)
        stride = self.stride
        for i in range(count):
            value[i::value_step] = self.region.array[data_start + i:data_stop + i:data_step]
        return value

    def __setitem__(self, index, value):
        count = self.count
        if not isinstance(index, slice):
            elem = index // count
            j = index % count
            self.region.array[elem * self.stride + j] = value
            return

        start = index.start or 0
        stop = index.stop
        step = index.step or 1
        if start < 0:
            start = self.size + start
        if stop is None:
            stop = self.size
        elif stop < 0:
            stop = self.size + stop

        assert step == 1 or step % count == 0, "Step must be multiple of component count"

        data_start = (start // count) * self.stride + start % count
        data_stop = (stop // count) * self.stride + stop % count

        if step == 1:
            data_step = self.stride
            value_step = count
            for i in range(count):
                self.region.array[data_start + i:data_stop + i:data_step] = value[i::value_step]
        else:
            data_step = (step // count) * self.stride
            self.region.array[data_start:data_stop:data_step] = value

    def invalidate(self):
        self.region.invalidate()


import struct
import time
import numpy as np
import scipy.misc
import h5py
import torch.utils.data
from .create_hdf5 import create_events_hdf5
from ..neuromorphic_dataset import NeuromorphicDataset
from ..events_timeslices import *
from ..transforms import *
import os

mapping = { 0 :'Hand Clapping'  ,
            1 :'Right Hand Wave',
            2 :'Left Hand Wave' ,
            3 :'Right Arm CW'   ,
            4 :'Right Arm CCW'  ,
            5 :'Left Arm CW'    ,
            6 :'Left Arm CCW'   ,
            7 :'Arm Roll'       ,
            8 :'Air Drums'      ,
            9 :'Air Guitar'     ,
            10:'Other'}

class DVSGestureDataset(NeuromorphicDataset):
    directory = 'data/dvsgesture/'
    resources_url = [['Manually Download dataset here: https://ibm.ent.box.com/s/3hiq58ww1pbbjrinh367ykfdf60xsfm8/file/211521748942?sb=/details and place under {0}'.format(directory),None, 'DvsGesture.tar.gz']]
    resources_local = [directory+'raw']

    def __init__(
            self,
            root,
            train=True,
            transform=None,
            target_transform=None,
            download_and_create=True,
            chunk_size = 500,
            deltat = 1000,
            return_meta = False,
            time_shuffle=False):

        self.n = 0
        self.deltat=deltat
        self.download_and_create = download_and_create
        self.root = root
        self.train = train
        self.chunk_size = chunk_size
        self.return_meta = return_meta
        self.time_shuffle = time_shuffle

        super(DVSGestureDataset, self).__init__(
                root,
                transform=transform,
                target_transform=target_transform )

        with h5py.File(root, 'r', swmr=True, libver="latest") as f:
            if train:
                self.n = f['extra'].attrs['Ntrain']
                self.keys = f['extra']['train_keys'][()]
            else:
                self.n = f['extra'].attrs['Ntest']
                self.keys = f['extra']['test_keys'][()]

    def download(self):
        super(DVSGestureDataset, self).download()

    def create_hdf5(self):
        create_events_hdf5(self.resources_local[0], self.root)

    def __len__(self):
        return self.n

    def __getitem__(self, key):
        #Important to open and close in getitem to enable num_workers>0
        with h5py.File(self.root, 'r', swmr=True, libver="latest") as f:
            if not self.train:
                key = key + f['extra'].attrs['Ntrain']
            assert key in self.keys
            data, target, meta_info_light, meta_info_user = sample(
                    f,
                    key,
                    T = self.chunk_size,
                    deltat = self.deltat,
                    shuffle=self.time_shuffle)#self.train)

        if self.transform is not None:
            data = self.transform(data)

        if self.target_transform is not None:
            target = self.target_transform(target)

        if self.return_meta is True:
            return data, target, meta_info_light, meta_info_user
        else:
            return data, target

def sample(hdf5_file,
        key,
        T = 500,
        deltat = 1000,
        shuffle = False):
    dset = hdf5_file['data'][str(key)]
    label = dset['labels'][()]
    tbegin = dset['times'][0]
    tend = np.maximum(0,dset['times'][-1]- 2*T*deltat )
    start_time = np.random.randint(tbegin, tend+1) if shuffle else 0
    #print(start_time)
    tmad = get_tmad_slice(dset['times'][()], dset['addrs'][()], start_time, T*deltat)
    tmad[:,0]-=tmad[0,0]
    meta = eval(dset.attrs['meta_info'])
    return tmad[:, [0,3,1,2]], label, meta['light condition'], meta['subject']

def create_dataloader(
        root = 'data/dvsgesture/dvs_gestures_build19.hdf5',
        batch_size = 72 ,
        chunk_size_train = 500,
        chunk_size_test = 1800,
        ds = None,
        dt = 1000,
        transform_train = None,
        transform_test = None,
        target_transform_train = None,
        target_transform_test = None,
        n_events_attention=None,
        return_meta=False,
        sample_shuffle=True,
        time_shuffle=True,
        channel_first = True,
        **dl_kwargs):
    if ds is None:
        ds = 4
    if isinstance(ds,int):
        ds = [ds,ds]

    size = [2, 128//ds[0], 128//ds[1]]

    if n_events_attention is None:
        if channel_first:
            default_transform = lambda chunk_size: Compose([
            Downsample(factor=[dt,1,ds[0],ds[1]]),
            ToCountFrame(T = chunk_size, size = size),
            ToTensor()
            ])
        else:
            default_transform = lambda chunk_size: Compose([
            Downsample(factor=[dt,1,ds[0],ds[1]]),
            ToCountFrame(T = chunk_size, size = size),
            ToTensor(),
            lambda x: x.permute(0,2,3,1)
            ])
    else:
        if channel_first:
            default_transform = lambda chunk_size: Compose([
                Downsample(factor=[dt,1,1,1]),
                Attention(n_events_attention, size=[2,128//2,128//2]),
                Downsample(factor=[1,1,ds[0],ds[1]]),
                ToCountFrame(T = chunk_size, size = [2,128//2//ds[0],128//2//ds[1]]),
                ToTensor()
            ])
        else:
            default_transform = lambda chunk_size: Compose([
                Downsample(factor=[dt,1,1,1]),
                Attention(n_events_attention, size=[2,128//2,128//2]),
                Downsample(factor=[1,1,ds[0],ds[1]]),
                ToCountFrame(T = chunk_size, size = [2,128//2//ds[0],128//2//ds[1]]),
                ToTensor(),
                lambda x: x.permute(0,2,3,1)
            ])

    if transform_train is None:
        transform_train = default_transform(chunk_size_train)
    if transform_test is None:
        transform_test = default_transform(chunk_size_test)

    if target_transform_train is None:
        target_transform_train =Compose([Repeat(chunk_size_train), toOneHot(11)])
    if target_transform_test is None:
        target_transform_test = Compose([Repeat(chunk_size_test), toOneHot(11)])

    train_d = DVSGestureDataset(root,
                                train = True,
                                transform = transform_train,
                                target_transform = target_transform_train,
                                chunk_size = chunk_size_train,
                                deltat = dt,
                                return_meta = return_meta,
                                time_shuffle=time_shuffle)

    train_dl = torch.utils.data.DataLoader(train_d, batch_size=batch_size, shuffle=sample_shuffle, **dl_kwargs)

    test_d = DVSGestureDataset(root,
                               transform = transform_test,
                               target_transform = target_transform_test,
                               train = False,
                               chunk_size = chunk_size_test,
                               deltat = dt,
                               return_meta = return_meta,
                               time_shuffle=time_shuffle) # WAS FALSE

    test_dl = torch.utils.data.DataLoader(test_d, batch_size=batch_size, **dl_kwargs)

    return train_dl, test_dl


import signal
import faulthandler
import argparse
import sys
import os
import re
from enum import Enum

from fab import testsuite
from fab import logutil
from fab import post
from fab import stats
from fab import skip
from fab import ignore
from fab import argutil
from fab import jsonutil
from fab import printer
from fab import publish

class Stats(Enum):
    def __str__(self):
        return self.value
    details = "details"
    summary = "summary"
    none = "none"

def main():

    # If SIGUSR1, backtrace all threads; hopefully this is early
    # enough.
    faulthandler.register(signal.SIGUSR1)

    parser = argparse.ArgumentParser(description="list test results",
                                     epilog="By default this tool uses 'sanitizer.sh' and 'diff' to generate up-to-the-minuite test results (the previously generated files 'OUTPUT/*.console.txt' and 'OUTPUT/*.console.diff' are ignored).  While this makes things a little slower, it has the benefit of always providing the most up-to-date and correct results (for instance, changes to known-good files are reflected immediately).  SIGUSR1 will dump all thread stacks")
    parser.add_argument("--verbose", "-v", action="count", default=0)

    parser.add_argument("--exit-ok", action="store_true",
                        help=("return a zero exit status; normally, when there are failures, a non-zero exit status is returned"))

    parser.add_argument("--quick", action="store_true",
                        help=("Use the previously generated '.console.txt' and '.console.diff' files"))

    parser.add_argument("--update", action="store_true",
                        help=("Update the '.console.txt' and '.console.diff' files"))

    parser.add_argument("--dump-args", action="store_true")

    # how to parse --print directory,saved-directory,...?
    parser.add_argument("--print", action="store",
                        default=printer.Print(printer.Print.PATH, printer.Print.RESULT, printer.Print.ISSUES),
                        type=printer.Print, metavar=str(printer.Print),
                        help="comma separated list of attributes to print for each test; default: '%(default)s'")

    parser.add_argument("--stats", action="store", default=Stats.summary, type=Stats,
                        choices=[c for c in Stats],
                        help="provide overview statistics; default: \"%(default)s\"");

    baseline_metavar = "BASELINE-DIRECTORY"
    baseline_help = "additional %(metavar)s containing results to compare against; any divergence between the test and baseline results are displayed"
    parser.add_argument("--baseline", "-b",
                        metavar=baseline_metavar, help=baseline_help)

    parser.add_argument("--json", action="store_true",
                        help="output each result as an individual json object (pipe the output through 'jq -s .' to convert it to a well formed json list")

    parser.add_argument("directories", metavar="DIRECTORY-OR-FILE", nargs="+",
                        help="a directory containing: a test, testsuite, test output, or testsuite output; or a file containing a 'TESTLIST'")

    # Note: this argument serves as documentation only.  The RESULT
    # argument should consumes all remaining parameters.
    parser.add_argument("baseline_ignored", nargs="?",
                        metavar=baseline_metavar, help=baseline_help)

    testsuite.add_arguments(parser)
    logutil.add_arguments(parser)
    # XXX: while checking for an UNTESTED test should be very cheap
    # (does OUTPUT/ exist?) it isn't.  Currently it triggers a full
    # post-mortem analysis.
    skip.add_arguments(parser, skip.Skip.UNTESTED)
    ignore.add_arguments(parser)
    publish.add_arguments(parser)

    # These three calls go together
    args = parser.parse_args()
    logutil.config(args, sys.stderr)
    logger = logutil.getLogger("kvmresults")

    if args.dump_args:
        logger.info("Arguments:")
        logger.info("  Stats: %s", args.stats)
        logger.info("  Print: %s", args.print)
        logger.info("  Baseline: %s", args.baseline)
        logger.info("  Json: %s", args.json)
        logger.info("  Quick: %s", args.quick)
        logger.info("  Update: %s", args.update)
        logger.info("  Exit OK: %s", args.exit_ok)
        testsuite.log_arguments(logger, args)
        logutil.log_arguments(logger, args)
        skip.log_arguments(logger, args)
        ignore.log_arguments(logger, args)
        publish.log_arguments(logger, args)
        return 0

    # Try to find a baseline.  If present, pre-load it.
    baseline = None
    if args.baseline:
        # An explicit baseline testsuite, can be more forgiving in how
        # it is loaded.
        baseline = testsuite.load(logger, logutil.DEBUG, args,
                                  testsuite_directory=args.baseline,
                                  error_level=logutil.DEBUG)
        if not baseline and os.path.isdir(args.baseline):
            # Perhaps, AKA BACKUP/YYYY-MM-DDD-..., the baseline
            # directory only contains a copy of the output.  Magic up
            # a baseline by combining the output with the tests in
            # ARGS.TESTING_DIRECTORY.
            baseline_directory = os.path.join(args.testing_directory, "pluto")
            baseline = testsuite.load(logger, logutil.DEBUG, args,
                                      testsuite_directory=baseline_directory,
                                      testsuite_output_directory=args.baseline,
                                      error_level=logutil.DEBUG)
        if not baseline:
            logger.info("'%s' is not a baseline", args.baseline)
            return 1
    elif len(args.directories) > 1:
        # If there is more than one directory then, perhaps, the last
        # one is a baseline.  A baseline might be: a complete
        # testsuite snapshot; or just output saved as
        # testing/pluto/OUTPUT/TESTDIR.
        baseline = testsuite.load(logger, logutil.DEBUG, args,
                                  testsuite_directory=args.directories[-1])
        if baseline:
            # discard the last argument as consumed above.
            logger.debug("discarding baseline testsuite argument '%s'", args.directories[-1])
            args.directories.pop()

    tests = testsuite.load_testsuite_or_tests(logger, args.directories, args)
    # And check
    if not tests:
        logger.error("Invalid testsuite or test directories")
        return 1

    result_stats = stats.Results()
    exit_code = 125 # assume a 'git bisect' barf
    try:
        exit_code = results(logger, tests, baseline, args, result_stats)
    finally:
        if args.stats is Stats.details:
            result_stats.log_details(stderr_log, header="Details:", prefix="  ")
        if args.stats in [Stats.details, Stats.summary]:
            result_stats.log_summary(stderr_log, header="Summary:", prefix="  ")

    return exit_code

def stderr_log(fmt, *args):
    sys.stderr.write(fmt % args)
    sys.stderr.write("\n")

def results(logger, tests, baseline, args, result_stats):

    failures = 0
    unresolved = 0
    passed = 0
    nr = 0

    for test in tests:

        nr = nr + 1
        publish.json_status(logger, args,
                            "rebuilding %s (test %d of %d)" % (test.name, nr, len(tests)))

        # If debug logging is enabled this will provide fine grained
        # per-test timing.

        with logger.debug_time("processing test %s", test.name):

            # Filter out tests that are being ignored?
            ignored, details = ignore.test(logger, args, test)
            if ignored:
                result_stats.add_ignored(test, ignored)
                continue

            # Filter out test results that are being skipped.
            #
            # XXX: In the default case (skip=[UNTESTED]) this should
            # be cheap (does OUTPUT/ exist?).  It isn't, instead a
            # full post-mortem analysis is performed.
            #
            # This is noticeable when printing static test value such
            # as the test's name takes far longer than one would
            # expect.
            result = post.mortem(test, args, logger,
                                 baseline=baseline,
                                 output_directory=test.saved_output_directory,
                                 quick=args.quick)
            if args.update:
                result.save()
            if args.skip:
                if printer.Print.RESULT in args.print \
                and skip.result(logger, args, result):
                    result_stats.add_skipped(result)
                    continue
            result_stats.add_result(result)

            if result.resolution in [post.Resolution.PASSED,
                                     post.Resolution.UNTESTED,
                                     post.Resolution.UNSUPPORTED]:
                passed = passed + 1
            elif result.resolution in [post.Resolution.UNRESOLVED]:
                unresolved = unresolved + 1
            else:
                failures = failures + 1

            publish.test_files(logger, args, result)
            publish.test_output_files(logger, args, result)
            publish.json_result(logger, args, result)

            if baseline and test in baseline \
               and not result.issues.crashed():
                # Since there is a baseline and the test didn't crash
                # limit what is printed to just those where the
                # baseline's result is different.
                #
                # Note that, this skips baseline-different - where the
                # baseline failed for a different reason.
                if {post.Issues.BASELINE_FAILED, post.Issues.BASELINE_PASSED}.isdisjoint(result.issues):
                    continue

            b = args.json and printer.JsonBuilder(sys.stdout) or printer.TextBuilder(sys.stdout)
            printer.build_result(logger, result, baseline, args, args.print, b)

        publish.json_results(logger, args)
        publish.json_summary(logger, args)

    publish.json_status(logger, args, "finished")

    # exit code
    if args.exit_ok:
        return 0
    elif unresolved:
        return 125 # 'git bisect' magic for don't know
    elif failures:
        return 1
    else:
        return 0

if __name__ == "__main__":
    sys.exit(main())


# Original content by Jansen Smith, Nov 2022
# based on youtube.com/watch?v=kfjdVgKE6xY

import threading
import time
# import numpy as np
import datetime
# import pyzt
import tkinter as tk
from win10toast import ToastNotifier
# from playsound import playsound
import json
from os.path import exists

class Activitimer:
    """
    Main timer application class.

    This class represents the main timer application, which includes a graphical
    user interface (GUI) that allows the user to start and stop a timer for an
    activity, and displays the elapsed time for the activity in the GUI. The
    application also includes a notification feature that sends a notification
    when the elapsed time exceeds a certain threshold.

    Attributes:
        act1 (ActivityLog): An instance of the ActivityLog class to track
            start and stop times for activities.
        activity (bool): A flag to indicate whether the timer is currently
            running or not.
        activity_button (tk.Button): A button widget to start and stop the
            timer.
        root (tk.Tk): The main window of the application.
        time_label (tk.Label): A label widget to display the elapsed time
            for the activity.
    """

    def __init__(self):
        """
        Initialize attributes and create GUI.
        """

        self.act1 = ActivityLog()
        font_choice = ("Helvetica", 30)
        self.root = tk.Tk()
        self.root.geometry("335x160")
        self.root.title("Activitimer")

        #        self.time_entry = tk.Entry(self.root, font=font_choice)
        #        self.time_entry.grid(row=0, column=0, columnspan=2, padx=5, pady=5)

        self.time_label = tk.Label(self.root, font=font_choice, text="Time: 00:00:00")
        self.time_label.grid(row=0, column=0, columnspan=2, padx=5, pady=5)

        self.activity_button = tk.Button(self.root, font=font_choice,
                                         text="Start Activity", command=self.start_activity)
        self.activity_button.grid(row=1, column=0, columnspan=2, padx=5, pady=5)

        self.activity = False

        self.start_thread()
        self.root.mainloop()

    def start_thread(self):
        """
        Start a new thread to run the start() method.
        """

        print("Clock Starting")
        t = threading.Thread(target=self.start)
        t.start()

    def alarm(self):
        """
        Send a notification using the toast object when the elapsed time
        for an activity exceeds a certain threshold.
        """

        toast = ToastNotifier()
        toast.show_toast("Activitimer", "Time is up!", duration=3)

    def start(self):
        """
        Run the timer in a separate thread.

        This method updates the time_label widget to display the elapsed time
        for the activity, calls the set_button() method to update the
        activity_button widget based on the current status of the timer, and
        pauses for a short period of time before repeating.
        """

        while True:
            full_seconds_true = self.act1.time_avail()

            if full_seconds_true < 0:
                full_seconds = -full_seconds_true
                self.time_label.config(fg="red")
            else:
                full_seconds = full_seconds_true
                self.time_label.config(fg="black")

            minutes, seconds = divmod(full_seconds, 60)
            hours, minutes = divmod(minutes, 60)

            self.time_label.config(text=f"Time: {int(hours):02d}:{int(minutes):02d}:{seconds:05.2f}")
            self.set_button()
            self.root.update()
            time.sleep(0.01)

            if full_seconds_true < 0 and self.activity:
                alarm = threading.Thread(target=self.alarm())
                alarm.start()

    #        if not self.stop_loop:

    def set_button(self):
        """
        Update the activity_button widget based on the current status of the timer.
        """

        act1_latest_state = self.act1.latest_state()
        if act1_latest_state == 'activity1_start':
            self.activity_true()
        elif act1_latest_state == 'activity1_stop' or act1_latest_state == 'reset_time':
            self.activity_false()
        pass

    def activity_true(self):
        """
        Set the activity flag to True and update the activity_button widget to
        show "Stop Activity" and run the stop_activity() method when clicked.
        """

        self.activity = True
        self.activity_button.config(text="Stop Activity", command=self.stop_activity)

    def activity_false(self):
        """
        Set the activity flag to False and update the activity_button widget to
        show "Start Activity" and run the start_activity() method when clicked.
        """

        self.activity = False
        self.activity_button.config(text="Start Activity", command=self.start_activity)

    def start_activity(self):
        """
        Start a new activity by calling the activity1_start() method of the act1 object.
        """

        self.act1.activity1_start()

    def stop_activity(self):
        """
        Stop the current activity by calling the activity1_stop() method of the act1 object.
        """

        self.act1.activity1_stop()

class ActivityLog:
    """
    Activity log class.

    This class represents a log of activities, and keeps track of the start and stop
    times for each activity. It provides methods to start and stop the timer, and
    calculate the elapsed time for all activities.

    Attributes:
        hrs_per_day (float): The number of hours per day available for activities.
        log (list): A list of start and stop times for activities.
    """

    def __init__(self):
        """
        Initialize the activity log and try to load the log from the 'eventlog.json' file.
        If the file is not found or there is an error loading it, reset the timer.
        """

        self.hrs_per_day = 1.5
        self.log = []
        loaded = self.try_to_load_file('eventlog.json')
        if not loaded:
            self.reset()
            inject_hrs = 1
            inject_secs = inject_hrs * 3600
            self.log[0].timestamp = self.log[0].timestamp - inject_secs * 16
            self.save_file()

    def activity1_start(self):
        """
        Start a new activity by adding a new entry to the log list with the current
        time as the start time.
        Append a new event line marked "activity1_start"
        """

        self.append_entry("activity1_start")

    def activity1_stop(self):
        """
        Stop the current activity by adding the current time as the stop time to
        the latest entry in the log list.
        Append a new event line marked "activity1_stop"
        """
        self.append_entry("activity1_stop")

    def reset(self):
        """
        Reset the activity log and set the hrs_per_day attribute to 1.5.
        """

        # Append a new event line marked "reset_time"
        self.append_entry("reset_time")

    def append_entry(self, pass_str):
        self.log.append(LogEntry(pass_str, time.time()))
        self.save_file()

    def time_avail(self):
        """
        Calculate the elapsed time for all activities in the log list and return the
        remaining time based on the hrs_per_day attribute.

        This method iterates through the log list and adds up the elapsed time for
        each activity. It then subtracts the total elapsed time from the hrs_per_day
        attribute to get the remaining time.
        """

        time_gathered = self.time_gathered()
        time_spent = self.time_spent()
        time_avail = time_gathered - time_spent
        return time_avail

    def time_gathered(self):
        return (time.time() - self.last_reset()) * (self.hrs_per_day / 24)

    def time_spent(self):
        time_spent = 0
        culled, is_started = self.culled_legacy(self.last_reset())
        for x in culled:
            if x.event == "activity1_stop":
                time_spent += x.timestamp
            elif x.event == "activity1_start":
                time_spent -= x.timestamp
            else:
                raise Exception("The log should only have start and stop activities here. "
                                "Something has gone terribly wrong.")
        if is_started:
            time_spent += time.time()-self.log[-1].timestamp
        return time_spent

    def culled_legacy(self, timestamp):
        # returns the log, with all entries BEFORE a given timestamp removed
        # does not itself modify the existing log
        culled = []
        is_started = False
        for x in self.log:
            if x.timestamp > timestamp:
                culled.append(x)
        if bool(culled) and culled[-1].event == "activity1_start":
            is_started = True
            culled = culled[0:-1]
        return culled, is_started

    def last_reset(self):
        last_timestamp = 0
        for x in self.log:
            if x.event == "reset_time" and x.timestamp > last_timestamp:
                last_timestamp = x.timestamp
        return last_timestamp

    def sort(self):
        #untested
        self.log = sorted(self.log, key=lambda x: x.timestamp, reverse=False)

    def latest_state(self):
        """
        Return the current state of the timer based on the latest entry in the log list.

        If the latest entry has a start time but no stop time, return 'activity1_start'.
        If the latest entry has both a start and stop time, return 'activity1_stop'.
        If the log list is empty, return 'reset_time'.
        """

        return self.log[-1].event

    def print(self):
        print(self.toJSON())

    def toJSON(self):
        toJSON = {
            "eventlog": []
        }
        for x in self.log:
            toJSON["eventlog"].append({"event": x.event, "timestamp": x.timestamp})
        return json.dumps(toJSON, sort_keys=True, indent=None)

    def fromJSON(self, json_data):
        for entry in json_data['eventlog']:
            self.log.append(LogEntry(entry['event'], entry['timestamp']))

    def save_file(self):
        saved = False
        with open('eventlog.json', 'w', encoding='utf-8') as f:
            #json.dump(self.toJSON(), f, ensure_ascii=False, indent=4)
            f.write(self.toJSON())
        saved = True
        return saved

    def load_file(self, filename):
        with open(filename, 'r', encoding='utf-8') as f:
            json_data = json.load(f)
        return json_data

    def try_to_load_file(self, filename):
        """
        Try to load the activity log from the specified file.

        If the file is found and successfully loaded, return True. If the file
        is not found or there is an error loading it, return False.

        Args:
            filename (str): The name of the file to load the log from.

        Returns:
            bool: True if the file was found and successfully loaded, False otherwise.
        """

        loaded = False
        json_data = []
        if exists(filename):
            json_data = self.load_file(filename)
            self.fromJSON(json_data)
            loaded = True
        return loaded

class LogEntry:
    # Represents a single timestamped event in the log

    def __init__(self, event_name, timestamp_epoch):
        self.event = event_name
        self.timestamp = timestamp_epoch

    def __repr__(self):
        return '{' + self.event + ' @ ' + str(self.timestamp) + '}'

if __name__ == '__main__':

    act = Activitimer()


#!/usr/bin/python
##1. CLeanup Script
###############################################

import csv

writer=csv.writer(open('CleanedData.csv', 'w'), delimiter=',')
reader=csv.reader(open('DataSample.csv', 'r'), delimiter=',')
entries = set()
dups  = set()

## Identfying records which have identical `geoinfo` and `timest`
for row in reader:
    key = (row[1], row[5], row[6])
    if key not in entries:
       entries.add(key)
    else:
       dups.add(key)

## Eleminating the suspicous data from the data set
reader=csv.reader(open('DataSample.csv', 'r'), delimiter=',')
for out in reader:
    keys = (out[1], out[5], out[6])
    if keys not in dups:
       writer.writerow(out)


# -*- coding: utf-8 -*-
# Created on Mon Mar 05 2018 20:40:56
# Author: WuLC
# EMail: liangchaowu5@gmail.com

# dp O(n) space
class Solution(object):
    def numSubarrayBoundedMax(self, A, L, R):
        """
        :type A: List[int]
        :type L: int
        :type R: int
        :rtype: int
        """
        dp = [0 for _ in xrange(len(A)+1)]
        pre = -1
        for i in xrange(len(A)):
            if A[i] > R:
                pre = i
                dp[i+1] = 0
            elif A[i] < L:
                dp[i+1] = dp[i]
            else:
                dp[i+1] = i - pre
        return sum(dp)

# dp O(1) space
class Solution(object):
    def numSubarrayBoundedMax(self, A, L, R):
        """
        :type A: List[int]
        :type L: int
        :type R: int
        :rtype: int
        """
        idx = -1
        pre, curr = 0, 0
        count = 0
        for i in xrange(len(A)):
            pre = curr
            curr = 0
            if A[i] > R:
                idx = i
            elif A[i] < L:
                curr = pre
            else:
                curr = i - idx
            count += curr
        return count

Algorithm/Python/795. Number of Subarrays with Bounded Maximum.py


# DCGAN-like generator and discriminator
from torch import nn
import torch.nn.functional as F

from spectral_normalization import SpectralNorm

channels = 3
leak = 0.1
w_g = 4

class ResBlockD(nn.Module):

    def __init__(self, in_channels, out_channels,downsample=None):
        super(ResBlockD, self).__init__()

        self.conv1 = SpectralNorm(nn.Conv2d(in_channels, out_channels, 3, 1, padding=1))
        self.conv2 = SpectralNorm(nn.Conv2d(out_channels, out_channels, 3, 1, padding=1))
        #self.conv_out = SpectralNorm(nn.Conv2d(in_channels, out_channels, 3, 1, padding=1))
        self.model = nn.Sequential(
                self.conv1,
                nn.LeakyReLU(leak),
                self.conv2
                )
        self.downsample = downsample

    def forward(self, x):
        if self.downsample:
            return self.model(x) + self.downsample(x)
        else:
            return self.model(x) + x

class Generator(nn.Module):
    def __init__(self, z_dim):
        super(Generator, self).__init__()
        self.z_dim = z_dim
        #
        self.ln = nn.Linear(z_dim,512*4*4)
        #
        self.model = nn.Sequential(
            #nn.ConvTranspose2d(512, 512, 1, stride=1),
            #nn.BatchNorm2d(512),
            #nn.ReLU(),
            nn.ConvTranspose2d(512, 256, 4, stride=2, padding=(1,1)),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.ConvTranspose2d(256, 128, 4, stride=2, padding=(1,1)),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.ConvTranspose2d(128, 64, 4, stride=2, padding=(1,1)),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.ConvTranspose2d(64, channels, 3, stride=1, padding=(1,1)),
            nn.Tanh())

    def forward(self, z):
        return self.model(self.ln(z).view(-1, 512, 4, 4))

class GeneratorG(nn.Module):
    def __init__(self, z_dim):
        super(Generator, self).__init__()
        self.z_dim = z_dim
        #
        self.ln = nn.Linear(z_dim,512*4*4)
        #
        self.model = nn.Sequential(
            #nn.ConvTranspose2d(512, 512, 1, stride=1),
            #nn.BatchNorm2d(512),
        #nn.ReLU(),

            nn.Sequential(

                nn.Conv2d(512, 256, 3, stride=1, padding=(1,1)),
                nn.LeakyReLU(leak),
                nn.Conv2d(256, 256, 3, stride=1, padding=(1,1))
            ),

            nn.Sequential(

                nn.BatchNorm2d(256),
                nn.LeakyReLU(leak),
                nn.Conv2d(256, 128, 3, stride=1, padding=(1,1)),
                nn.LeakyReLU(leak),
                nn.Conv2d(128, 128, 3, stride=1, padding=(1,1))
            ),

            nn.Sequential(

                nn.BatchNorm2d(128),
                nn.LeakyReLU(leak),
                nn.Conv2d(128, 64, 3, stride=1, padding=(1,1)),
                nn.LeakyReLU(leak),
                nn.Conv2d(64, 64, 3, stride=1, padding=(1,1))
            ),

            nn.Sequential(
                nn.BatchNorm2d(64),
                nn.Conv2d(64, channels, 3, stride=1, padding=(1,1)),
                nn.Tanh()
            ),

        )

    def forward(self, z):
        return self.model(self.ln(z).view(-1, 512, 4, 4))

class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        '''
        self.seq = nn.Sequential(
            SpectralNorm(nn.Conv2d(channels,64,3, 1, padding=1)),
            nn.LeakyReLU(leak),
            ResBlockD(64,64),

            SpectralNorm(nn.Conv2d(64,128, 3, 1, padding=1)),
            nn.LeakyReLU(leak),
            ResBlockD(128,128),

            SpectralNorm(nn.Conv2d(128,256, 3, 1, padding=1)),
            nn.LeakyReLU(leak),
            ResBlockD(256,256),

            SpectralNorm(nn.Conv2d(256,512, 3, 1, padding=1)),
            nn.LeakyReLU(leak),
            ResBlockD(512,512),
        )
        '''
        self.seq = nn.Sequential(
            self.make_layer(channels,64),
            self.make_layer(64,64),
            self.make_layer(64,128),
            self.make_layer(128,128),
            #self.make_layer(128,256),
            #self.make_layer(256,512)
            )
        self.fc = SpectralNorm(nn.Linear(w_g * w_g * 128, 1))

    def make_layer(self,in_channels,out_channels,num=2):
        downsample = None
        if in_channels != out_channels:
            downsample = SpectralNorm(nn.Conv2d(in_channels,out_channels,kernel_size=3 ,stride=1,padding=1,bias=False))
        layers = []
        layers.append(ResBlockD(in_channels,out_channels,downsample))
        for _ in range(1,num):
            layers.append(ResBlockD(out_channels,out_channels))
        return nn.Sequential(*layers)

    def forward(self, x):
        m = x

        m = self.seq(m)
        return self.fc(m.view(-1,w_g * w_g * 128))


# Un script de ejemplo

from genespy.task import Task
from genespy.mutators import mutate_flip
from genespy.crossovers import crossover_one_point
from genespy.selectors import select_vasconcelos
from genespy.algorithms import cos_mutation_ga
from genespy.initiators import init_binary_pop

def example_evaluation_function(genome, data):
    """ Función de evaluación de ejemplo.

    Args:
        genome (list): Un arreglo con los argumentos codificados en el genoma.
        data (object): Un objeto arbitrario asociado al problema.

    Returns:
        float: El fitness asociado a los argumentos proporcionados.

    """

    return (1.5 - genome[0] + genome[0] * genome[1]) ** 2.0 + \
           (2.25 - genome[0] + genome[0] * genome[1] ** 2.0) ** 2.0 + \
           (2.625 - genome[0] + genome[0] * genome[1] ** 3.0) ** 2.0

def my_example():
    """ Esta función prepara la tarea y ejecuta el algoritmo genético.

    """

    n = 500  # Individuos
    gen = 200  # Generaciones máximas
    cp = 0.3  # Probabilidad de cruza
    max_mp = 0.05  # Máxima probabilidad de mutación
    cycle_mp = 100.0  # Generaciónes por ciclo de mutación
    elitism = 1.0  # Porcentaje de elitismo
    duration = float('inf')  # Duración máxima en segundos
    verbose = 10  # Frecuencia de reporte

    # Se crea la tarea
    task = Task()

    # Se crea y asigna la población inicial
    # Two individuals [sign bit(bool), integer bits (int), matissa bits (int)]
    struct = ((True, 5, 5),  # x
              (True, 5, 5))  # y
    the_pop = init_binary_pop(n, struct)
    task.set_population(the_pop)

    # Se establecen funciones de cruza, mutacion y selección
    task.set_evals([example_evaluation_function], [-1.0])
    task.set_mutator(mutate_flip, {'mp': max_mp})
    task.set_crossover(crossover_one_point)
    task.set_selector(select_vasconcelos, {'cp': cp})

    # Inicia el algoritmo
    sol = cos_mutation_ga(task,
                          max_mp,
                          cycle_mp,
                          elitism,
                          duration,
                          gen,
                          verbose)

    print(sol)
    print('Friendly genome:', sol.get_genome())

my_example()


import numpy as np
import tensorflow as tf
import pandas as pd
import imgaug as ia
from imgaug import augmenters as iaa

REMOTEDEBUG = True # set to True if debugging remotely
REMOTEDEBUG = False
if (REMOTEDEBUG == True):
   # ssh -R 5678:localhost:5678 kbhit@192.168.1.149 -p 49
   import pydevd
   from pydevd_file_utils import setup_client_server_paths
   MY_PATHS_FROM_ECLIPSE_TO_PYTHON = [
       ('/Users/pal004/Documents/LiClipse Workspace/RemoteSystemsTempFiles/192.168.1.149/home/kbhit/git/DigitRecognizer', '/home/kbhit/git/DigitRecognizer'),
       ]
   setup_client_server_paths(MY_PATHS_FROM_ECLIPSE_TO_PYTHON)
   pydevd.settrace("localhost", port=5678, stdoutToServer=True, stderrToServer=True)

PERCENT_TRAIN = 0.8 # the other part will be validation
train_fn = 'data/train.csv'
test_fn  = 'data/test.csv'

pixel_depth = 255.0  # Number of levels per pixel.
image_size = 28  #224 before
num_labels = 10
num_channels = 1 # greyscale

# some knobs to turn
LEARNING_RATE = 0.0001
num_steps = 1050*30 # lets run for 30 epochs.   n=1050 steps per epoch at 33600 images with n=32 batchsize
batch_size = 32
num_hidden = 64 # number of neurons in FC layer (right before softmax layer)
data_augmentation_prob = 0.05 # the probability of each data augmention filter

def normalize_image (image_data): # convert values between -.5 and .5
   for i in range (image_data.shape[0]):
      image_data[i,] = (image_data[i,].astype(np.float32) - (pixel_depth / 2)) / pixel_depth

def accuracy(predictions, labels):
  return (100.0 * np.sum(np.argmax(predictions, 1) == labels) / predictions.shape[0])

# read in training and validation set
train_matrix = pd.read_csv(train_fn, delimiter=",")
indexes = np.arange (train_matrix.shape[0])
np.random.shuffle (indexes)
num_validation = int (train_matrix.shape[0]-(train_matrix.shape[0]*PERCENT_TRAIN))

train_set = train_matrix.iloc [indexes[:-num_validation]]
valid_set = train_matrix.iloc [indexes[-num_validation:]]

train_labels  = train_set['label'].as_matrix ().astype (np.int32)
valid_labels  = valid_set['label'].as_matrix ().astype (np.int32)
train_dataset = train_set[np.arange(1,train_set.shape[1])].as_matrix ().astype(np.float32).reshape (-1, image_size, image_size, num_channels)
valid_dataset = valid_set[np.arange(1,valid_set.shape[1])].as_matrix ().astype(np.float32).reshape (-1, image_size, image_size, num_channels)

# read in test set
test_matrix = pd.read_csv(test_fn, delimiter=",")
test_dataset = test_matrix.as_matrix ().astype(np.float32).reshape (-1, image_size, image_size, num_channels) # no labels and no need to randomize

normalize_image (valid_dataset);
normalize_image (test_dataset);

graph = tf.Graph()
with graph.as_default():

  # Input data.
  tf_train_dataset = tf.placeholder(
    tf.float32, shape=(batch_size, image_size, image_size, num_channels))
  tf_train_labels = tf.placeholder(tf.int32, shape=(batch_size, ))
  tf_valid_dataset = tf.constant(valid_dataset)
  tf_test_dataset = tf.constant(test_dataset)

  # variables
  kernel_conv1 = tf.Variable(tf.truncated_normal([3, 3, num_channels, 32], dtype=tf.float32,
                                            stddev=1e-1), name='weights_conv1')
  biases_conv1 = tf.Variable(tf.constant(0.0, shape=[32], dtype=tf.float32),
                        trainable=True, name='biases_conv1')
  kernel_conv2 = tf.Variable(tf.truncated_normal([3, 3, 32, 32], dtype=tf.float32,
                                            stddev=1e-1), name='weights_conv2')
  biases_conv2 = tf.Variable(tf.constant(0.0, shape=[32], dtype=tf.float32),
                        trainable=True, name='biases_conv2')
  kernel_conv3 = tf.Variable(tf.truncated_normal([3, 3, 32, 64], dtype=tf.float32,
                                            stddev=1e-1), name='weights_conv3')
  biases_conv3 = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32),
                        trainable=True, name='biases_conv3')
  fc1w = tf.Variable(tf.truncated_normal([1024, num_hidden],
                                                dtype=tf.float32,
                                                stddev=1e-1), name='weights') # 1024 from pool3.get_shape () of 4*4*64
  fc1b = tf.Variable(tf.constant(1.0, shape=[num_hidden], dtype=tf.float32),
                        trainable=True, name='biases')
  fc2w = tf.Variable(tf.truncated_normal([num_hidden, num_labels],
                                                dtype=tf.float32,
                                                stddev=1e-1), name='weights')
  fc2b = tf.Variable(tf.constant(1.0, shape=[num_labels], dtype=tf.float32),
                        trainable=True, name='biases')

  def model(data):
     parameters = []
     with tf.name_scope('conv1_1') as scope:
         conv = tf.nn.conv2d(data, kernel_conv1, [1, 1, 1, 1], padding='SAME')
         out = tf.nn.bias_add(conv, biases_conv1)
         conv1_1 = tf.nn.relu(out, name=scope)
         parameters += [kernel_conv1, biases_conv1]

     # pool1
     pool1 = tf.nn.max_pool(conv1_1,
                            ksize=[1, 2, 2, 1],
                            strides=[1, 2, 2, 1],
                            padding='SAME',
                            name='pool1')

     with tf.name_scope('conv2_1') as scope:
         conv = tf.nn.conv2d(pool1, kernel_conv2, [1, 1, 1, 1], padding='SAME')
         out = tf.nn.bias_add(conv, biases_conv2)
         conv2_1 = tf.nn.relu(out, name=scope)
         parameters += [kernel_conv2, biases_conv2]

     # pool2
     pool2 = tf.nn.max_pool(conv2_1,
                            ksize=[1, 2, 2, 1],
                            strides=[1, 2, 2, 1],
                            padding='SAME',
                            name='pool2')

     with tf.name_scope('conv3_1') as scope:
         conv = tf.nn.conv2d(pool2, kernel_conv3, [1, 1, 1, 1], padding='SAME')
         out = tf.nn.bias_add(conv, biases_conv3)
         conv3_1 = tf.nn.relu(out, name=scope)
         parameters += [kernel_conv3, biases_conv3]

     # pool3
     pool3 = tf.nn.max_pool(conv3_1,
                            ksize=[1, 2, 2, 1],
                            strides=[1, 2, 2, 1],
                            padding='SAME',
                            name='pool3')

     # fc1
     with tf.name_scope('fc1') as scope:
         shape = int(np.prod(pool3.get_shape()[1:])) # except for batch size (the first one), multiple the dimensions
         pool3_flat = tf.reshape(pool3, [-1, shape])
         fc1l = tf.nn.bias_add(tf.matmul(pool3_flat, fc1w), fc1b)
         fc1 = tf.nn.relu(fc1l)
         parameters += [fc1w, fc1b]

     # fc2
     with tf.name_scope('fcnum_hidden2') as scope:
         fc2l = tf.nn.bias_add(tf.matmul(fc1, fc2w), fc2b)
         parameters += [fc2w, fc2b]
     return fc2l;

  # Training computation.
  logits = model(tf_train_dataset)
  loss = tf.reduce_mean(
    tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=tf_train_labels))

  # Optimizer.
  optimizer = tf.train.RMSPropOptimizer(LEARNING_RATE).minimize(loss)

  # Predictions for the training, validation, and test data.
  train_prediction = tf.nn.softmax(logits)
  valid_prediction = tf.nn.softmax(model(tf_valid_dataset))
  test_prediction = tf.nn.softmax(model(tf_test_dataset))

# Sometimes(0.5, ...) applies the given augmenter in 50% of all cases,
# e.g. Sometimes(0.5, GaussianBlur(0.3)) would blur roughly every second image.
st = lambda aug: iaa.Sometimes(data_augmentation_prob, aug)

# Define our sequence of augmentation steps that will be applied to every image
# All augmenters with per_channel=0.5 will sample one value _per image_
# in 50% of all cases. In all other cases they will sample new values
# _per channel_.
seq = iaa.Sequential([
#        iaa.Fliplr(0.5), # horizontally flip 50% of all images
#        iaa.Flipud(0.5), # vertically flip 50% of all images
        st(iaa.Crop(percent=(0, 0.03))), # crop images by 0-3% of their height/width
        st(iaa.GaussianBlur((0, 0.5))), # blur images with a sigma between 0 and 0.5
        st(iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.2), per_channel=0.5)), # add gaussian noise to images
        st(iaa.Dropout((0.0, 0.1), per_channel=0.5)), # randomly remove up to 10% of the pixels
        st(iaa.Add((-10, 10), per_channel=0.5)), # change brightness of images (by -10 to 10 of original value)
        st(iaa.Multiply((0.5, 1.5), per_channel=0.5)), # change brightness of images (50-150% of original value)
        st(iaa.ContrastNormalization((0.5, 2.0), per_channel=0.5)), # improve or worsen the contrast
        st(iaa.Affine(
            scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}, # scale images to 80-120% of their size, individually per axis
            translate_px={"x": (-8, 8), "y": (-8, 8)}, # translate by -8 to +8 pixels (per axis)
            rotate=(-45, 45), # rotate by -45 to +45 degrees
            shear=(-8, 8), # shear by -8 to +8 degrees
            order=ia.ALL, # use any of scikit-image's interpolation methods
            cval=(0, 1.0), # if mode is constant, use a cval between 0 and 1.0
            mode=ia.ALL # use any of scikit-image's warping modes (see 2nd image from the top for examples)
        )),
        st(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.20)) # apply elastic transformations with random strengths
    ],
    random_order=True # do all of the above in random order
)

with tf.Session(graph=graph) as session:
   tf.global_variables_initializer().run ()
   for step in range(num_steps):
      offset = (step * batch_size) % (train_labels.shape[0] - batch_size)
      batch_data = np.copy (train_dataset[offset:(offset + batch_size), :, :, :]) # copying so a reference won't be created or else we'll be normalizing normalized stuff which would yield odd results
      batch_data = seq.augment_images(batch_data.astype (np.uint8)).astype (np.float32); # add data augmentation
      normalize_image (batch_data);

      batch_labels = train_labels[offset:(offset + batch_size)]
      feed_dict = {tf_train_dataset : batch_data, tf_train_labels : batch_labels}
      _, l, predictions = session.run(
                                      [optimizer, loss, train_prediction], feed_dict=feed_dict)
      if (step % 200 == 0):
         print ("offset is %d" % (offset))
         print ("Minibatch loss at step", step, ":", l)
         print ("Minibatch accuracy: %.1f%%" % accuracy(predictions, batch_labels))
         print ("Validation accuracy: %.1f%%" % accuracy(
           valid_prediction.eval(), valid_labels))
#  print "Test accuracy: %.1f%%" % accuracy(test_prediction.eval(), test_labels)


import requests
import time
import random
import lxml.html
from lxml import etree
import threading
import re
import cfscrape

bbs = [
    {
        "origin": "https://ensaimada.xyz",
        "bbs": '43044'
    },
    {
        "origin": "https://ensaimada.xyz",
        "bbs": "40298"
    },
    {
        "origin": "https://inter-concierge.net",
        "bbs": "novogara"
    },
    {
        "origin": "https://inter-concierge.net",
        "bbs": "whitenighit"
    },
    {
        "origin": "https://ensaimada.xyz",
        "bbs": "rid"
    }
]
l = []

ua = open('ua.txt').readlines()

def fetchPosts ():
    for i in bbs:
        res = requests.get(f"{i['origin']}/{i['bbs']}/subback.html", headers={
            "User-Agent": random.choice(ua)
        }).text
        pattern = "https?://[\w/:%#\$&\?\(\)~\.=\+\-]+"
        url_list = re.findall(pattern, res)
        for url in url_list:
            if url.startswith(f"{i['origin']}/test/read.cgi/{i['bbs']}/"):
                l6 = url.split("/")[6]
                l.append({
                    "origin": i['origin'],
                    "bbs": i['bbs'],
                    "key": l6
                })

def getProxy ():
    """
    response = requests.get('https://www.proxyscan.io/download?type=https').text
    combos = response.splitlines()
    """
    f = open('proxies.txt')
    combos = f.readlines()
    for i in combos:
        proxyStr = random.choice(combos)
        try:
            requests.get("https://example.com", proxies={
                "http": "https://"+proxyStr,
                "https": "https://"+proxyStr
            }, timeout=5)
            print("Connection Successful"+proxyStr)
            return proxyStr
        except Exception as e:
            print(e)
    return getProxy()
def main(proxyStr):
    session = requests.Session()
    session = cfscrape.create_scraper()

    choice = random.choice(l)
    obj = {
    "subject": "",
    "bbs": choice['bbs'],
    "key": choice['key'],
    "time": time.time(),
    "submit": "",
    "FROM": "kusattapan",
    "mail": "",
    "MESSAGE": f"""
        [全恒心教民へ告ぐ]

        当掲示板は、荒らｓ連合軍ならびに私が運営するウェブサイトである「DropGC」によって占拠されました。

        よって当掲示板植民地化計画の一環として、当掲示板を利用する全ての恒心教民はDropGCへ利用登録することを命じる。

        これに従わない場合は、当掲示板へのアクセス禁止措置などが課される恐れがあります。

        こちらからご登録ください https://dropgc.gift?ref=kousin

        DropGC: https://dropgc.memo.wiki/
        荒らｓ連合軍:https://krsw-wiki.org/wiki/%E5%94%90%E6%BE%A4%E8%B2%B4%E6%B4%8BWiki:%E3%83%81%E3%83%A9%E3%82%B7%E3%81%AE%E8%A3%8F/%E8%8D%92%E3%82%89%E3%81%97%E9%80%A3%E5%90%88%E8%BB%8D
        {random.uniform(10000, 2000000000)}
    """.encode('shiftjis')
    }

    response = session.post(f"{choice['origin']}/test/bbs.cgi?guid=ON", data=obj, proxies={
                "http": "https://"+proxyStr,
                "https": "https://"+proxyStr
    }, headers={
    "User-Agent": random.choice(ua)
    })
    response.encoding = response.apparent_encoding
    html = response.text
    print(html)

    response = session.post(f"{choice['origin']}/test/bbs.cgi?guid=ON", data=obj, proxies={
                "http": "https://"+proxyStr,
                "https": "https://"+proxyStr
    },headers={
    "User-Agent": random.choice(ua)
    })
    response.encoding = response.apparent_encoding
    html = response.text
    print(html)

    tree = lxml.html.fromstring(html)
    errorStr = tree.xpath('//body/div')

    if len(errorStr):
        errorStr = tree.xpath('//body/div/text()')[0]
        # errorStr = etree.tostring(errorStr[0], method='html', encoding="shiftjis").decode('shiftjis')
        if len(errorStr.split()) >= 3 and errorStr.split()[3].isnumeric():
            wait = int(errorStr.split()[3])
            print('waiting for '+ str(wait))
            time.sleep(wait)

def worker ():
    while True:
        proxyStr = getProxy()
        for i in range(3):
            try:
                main(proxyStr)
            except KeyboardInterrupt:
                exit()
            except Exception as e:
                print(e)
            time.sleep(1)

fetchPosts()
print(l)
for i in range(100):
    t = threading.Thread(target=worker)
    t.start()
    print ("worker" + str(i) + "has started")


#! env python
# -*- coding: utf-8 -*-

from tree import create_tree, TreeNode
from typing import Optional, List
import sys, math, unittest

# ctci.4_9
# Date: 2020/09/21
# Filename: 4_9
# Author: koucs

# 4.9: 各ノードにある値を持ったに分岐が与えられたとき、合計値が与えられた値になる全ての経路を出力するアルゴリズム
# 経路の始まりと終わりは、k他方のノードがもう片方の祖先となっていること

def find_sum(current: TreeNode, sum: int, path: List, result: []):
    if current is None:
        return []
    path.append(current.data)

    i = len(path) - 1
    t = 0
    while i >= 0:
        t += path[i]
        if t == sum:
            result.append(path[i:])
        i -= 1

    find_sum(current.left, sum, path, result)
    find_sum(current.right, sum, path, result)
    path.pop()

def find(root: TreeNode, sum: int) -> List:
    result = []
    find_sum(root, sum, [], result)
    return result

class Test(unittest.TestCase):
    def test_1(self):
        tree = create_tree([1, 2, 3, 4])
        self.assertEqual(find(tree, 3), [[1, 2], [3]])

        tree = create_tree([1, -2, -3, 4, 5, 4])
        self.assertEqual(find(tree, 3), [[1, -2, 4], [-2, 5]])
        return

if __name__ == '__main__':
    unittest.main()


import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import os

import __db as db

class end_error(Exception):
    pass

def histoogramm(data):
    plt.subplot(3, 1, 1)
    plt.plot(data["time_ms"], linewidth=2.0)
    plt.xlabel("Число ядер")
    plt.ylabel("Время")
    plt.grid(True)
    plt.title(data["name"])

    plt.subplot(3, 1, 3)
    plt.plot(data["speed"], linewidth=2.0)
    plt.ylabel("Скорость")
    plt.xlabel("Число ядер")
    plt.grid(True)
    if not os.path.exists("results"):
        os.mkdir("results")
    name = "results/%s" % data["name"]
    plt.savefig(name)

if __name__ == "__main__":
    data1 = db.read("1.json", "graphics")
    histoogramm(data1)