# -*- encoding: utf-8 -*-
from __future__ import print_function
import types
import importlib
import inspect
import textwrap
from abjad.tools import abctools
from abjad.tools import systemtools

class CodeBlock(abctools.AbjadValueObject):
    r'''A code block.

    ::

        >>> import abjadbook
        >>> console = abjadbook.AbjadBookConsole()
        >>> input_file_contents = [
        ...     'staff = Staff(r"\clef bass c4 d4 e4 f4")',
        ...     'show(staff)',
        ...     'print(len(staff))'
        ...     ]
        >>> code_block = abjadbook.CodeBlock(input_file_contents)
        >>> code_block.interpret(console)
        >>> for output_proxy in code_block.output_proxies:
        ...     print(format(output_proxy))
        ...
        abjadbook.tools.CodeOutputProxy(
            (
                '>>> staff = Staff(r"\\clef bass c4 d4 e4 f4")',
                '>>> show(staff)',
                )
            )
        abjadbook.tools.LilyPondOutputProxy(
            lilypondfiletools.LilyPondFile()
            )
        abjadbook.tools.CodeOutputProxy(
            ('>>> print(len(staff))', '4')
            )

    ::

        >>> input_file_contents = [
        ...     'for leaf in staff:',
        ...     '    print(format(leaf))',
        ...     '    show(leaf)',
        ...     '',
        ...     ]
        >>> code_block = abjadbook.CodeBlock(input_file_contents)
        >>> code_block.interpret(console)
        >>> for output_proxy in code_block.output_proxies:
        ...     print(format(output_proxy))
        ...
        abjadbook.tools.CodeOutputProxy(
            (
                '>>> for leaf in staff:',
                '...     print(format(leaf))',
                '...     show(leaf)',
                '... ',
                '\\clef "bass"',
                'c4',
                )
            )
        abjadbook.tools.LilyPondOutputProxy(
            lilypondfiletools.LilyPondFile()
            )
        abjadbook.tools.CodeOutputProxy(
            ('d4',)
            )
        abjadbook.tools.LilyPondOutputProxy(
            lilypondfiletools.LilyPondFile()
            )
        abjadbook.tools.CodeOutputProxy(
            ('e4',)
            )
        abjadbook.tools.LilyPondOutputProxy(
            lilypondfiletools.LilyPondFile()
            )
        abjadbook.tools.CodeOutputProxy(
            ('f4',)
            )
        abjadbook.tools.LilyPondOutputProxy(
            lilypondfiletools.LilyPondFile()
            )

    '''

    ### CLASS VARIABLES ###

    __slots__ = (
        '_allow_exceptions',
        '_current_lines',
        '_document_source',
        '_executed_lines',
        '_hide',
        '_output_proxies',
        '_options',
        '_source_lines',
        '_starting_line_number',
        '_strip_prompt',
        '_stylesheet',
        '_text_width',
        )

    ### INITIALIZER ###

    def __init__(
        self,
        input_file_contents,
        allow_exceptions=None,
        document_source=None,
        executed_lines=None,
        hide=None,
        starting_line_number=None,
        strip_prompt=None,
        stylesheet=None,
        text_width=None,
        **options
        ):
        if allow_exceptions is not None:
            allow_exceptions = bool(allow_exceptions)
        self._allow_exceptions = allow_exceptions
        self._document_source = document_source
        if executed_lines is not None:
            executed_lines = tuple(executed_lines)
        self._executed_lines = executed_lines
        if hide is not None:
            hide = bool(hide)
        self._hide = hide
        self._output_proxies = []
        self._source_lines = tuple(input_file_contents)
        if strip_prompt is not None:
            strip_prompt = bool(strip_prompt)
        self._starting_line_number = starting_line_number
        self._strip_prompt = strip_prompt
        self._current_lines = []
        self._stylesheet = stylesheet
        if text_width is not None:
            if text_width is True:
                text_width = 80
            text_width = abs(int(text_width))
            if text_width < 1:
                text_width = None
        self._text_width = text_width
        self._options = options

    ### PUBLIC METHODS ###

    def as_docutils(
        self,
        configuration=None,
        output_directory=None,
        ):
        result = []
        if self.output_proxies:
            for output_proxy in self.output_proxies:
                subresult = output_proxy.as_docutils(
                    configuration=configuration,
                    output_directory=output_directory,
                    )
                result.extend(subresult)
        return result

    def as_latex(
        self,
        configuration=None,
        output_directory=None,
        relative_output_directory=None,
        ):
        import abjadbook
        result = []
        configuration = configuration or {}
        latex_configuration = configuration.get('latex', {})
        output_start_delimiter = latex_configuration.get(
            'output-start-delimiter',
            ('%%% ABJADBOOK START %%%',),
            )
        output_stop_delimiter = latex_configuration.get(
            'output-stop-delimiter',
            ('%%% ABJADBOOK END %%%',),
            )
        if self.output_proxies:
            result.extend(output_start_delimiter)
            before = latex_configuration.get('before-code-block', ())
            result.extend(before)
            for i, output_proxy in enumerate(self.output_proxies):
                lines = output_proxy.as_latex(
                    configuration=configuration,
                    output_directory=output_directory,
                    relative_output_directory=relative_output_directory,
                    )
                string = '\n'.join(lines)
                if isinstance(output_proxy, abjadbook.ImageOutputProxy):
                    if i < len(self.output_proxies) - 1:
                        next_proxy = self.output_proxies[i + 1]
                        if isinstance(next_proxy, abjadbook.ImageOutputProxy):
                            string += r'\\'
                result.append(string)
            after = latex_configuration.get('after-code-block', ())
            result.extend(after)
            result.extend(output_stop_delimiter)
            result = '\n'.join(result)
            result = [result]
        return result

    def flush(self):
        pass

    @staticmethod
    def from_latex_abjadextract_block(
        source_line,
        starting_line_number=None,
        **options
        ):
        import abjadbook
        code_address = source_line.partition('<abjadextract ')[-1].split()[0]
        module_name, sep, attr_name = code_address.rpartition(':')
        module = importlib.import_module(module_name)
        attr = getattr(module, attr_name)
        input_file_contents = inspect.getsource(attr).splitlines()
        executed_lines = 'from {} import {}'.format(
            module_name,
            attr_name,
            )
        executed_lines = (executed_lines,)
        code_block = abjadbook.CodeBlock(
            executed_lines=executed_lines,
            input_file_contents=input_file_contents,
            starting_line_number=starting_line_number,
            **options
            )
        return code_block

    @staticmethod
    def from_latex_abjad_block(
        input_file_contents,
        starting_line_number=None,
        **options
        ):
        import abjadbook
        code_block = abjadbook.CodeBlock(
            input_file_contents=input_file_contents,
            starting_line_number=starting_line_number,
            **options
            )
        return code_block

    @staticmethod
    def from_docutils_abjad_import_block(block):
        import abjadbook
        code_address = block['path']
        module_name, sep, attr_name = code_address.rpartition(':')
        module = importlib.import_module(module_name)
        attr = getattr(module, attr_name)
        input_file_contents = inspect.getsource(attr).splitlines()
        executed_lines = 'from {} import {}'.format(
            module_name,
            attr_name,
            )
        executed_lines = (executed_lines,)
        options = {}
        for key, value in block.attlist():
            key = key.replace('-', '_')
            options[key] = value
        code_block = abjadbook.CodeBlock(
            executed_lines=executed_lines,
            input_file_contents=input_file_contents,
            starting_line_number=block.line,
            **options
            )
        return code_block

    @staticmethod
    def from_docutils_abjad_input_block(block):
        import abjadbook
        input_file_contents = block[0][0].splitlines()
        input_file_contents = (str(_) for _ in input_file_contents)
        options = {}
        for key, value in block.attlist():
            key = key.replace('-', '_')
            options[key] = value
        code_block = abjadbook.CodeBlock(
            input_file_contents=input_file_contents,
            starting_line_number=block.line,
            **options
            )
        return code_block

    @staticmethod
    def from_docutils_literal_block(block):
        import abjadbook
        input_file_contents = []
        for line in block[0].splitlines():
            if line.startswith(('>>>', '...')):
                input_file_contents.append(line[4:])
        document_source = None
        parent = block.parent
        while not document_source and getattr(parent, 'parent'):
            document_source = getattr(parent, 'source', None)
            parent = parent.parent
        code_block = abjadbook.CodeBlock(
            input_file_contents=input_file_contents,
            starting_line_number=block.line,
            document_source=document_source,
            )
        return code_block

    def interpret(self, console):
        import abjadbook
        is_incomplete_statement = False
        input_file_contents = self.input_file_contents
        self.output_proxies[:] = []
        self.current_lines[:] = []
        self.setup_capture_hooks(console)
        if self.executed_lines:
            for executed_line in self.executed_lines:
                is_incomplete_statement = console.push(executed_line)
            code_output_proxy = abjadbook.CodeOutputProxy(input_file_contents)
            self.output_proxies.insert(0, code_output_proxy)
        else:
            result = '>>> '
            for i, line in enumerate(input_file_contents):
                result += line
                self.current_lines.append(result)
                with systemtools.RedirectedStreams(self, self):
                    is_incomplete_statement = console.push(line)
                if console.errored:
                    if self.allow_exceptions:
                        console.unregister_error()
                    else:
                        message = ''
                        if self.document_source:
                            message = str(self.document_source) + '\n'
                        message += 'Errored at line number {}\n    '.format(
                            self.starting_line_number + i)
                        message = message + '\n    '.join(self.current_lines)
                        raise abjadbook.AbjadBookError(message)
                if not is_incomplete_statement:
                    result = '>>> '
                    self.setup_capture_hooks(console)
                else:
                    result = '... '
        if is_incomplete_statement:
            with systemtools.RedirectedStreams(self, self):
                is_incomplete_statement = console.push('\n')
        self.push_code_output_proxy()
        if self.hide:
            self.output_proxies[:] = [
                _ for _ in self.output_proxies
                if not isinstance(_, abjadbook.CodeOutputProxy)
                ]

    def push_asset_output_proxy(self, asset_output_proxy):
        self.push_code_output_proxy()
        self.output_proxies.append(asset_output_proxy)

    def push_code_output_proxy(self):
        import abjadbook
        if not self.current_lines:
            return
        if self.strip_prompt:
            self.current_lines[:] = [
                _[4:].rstrip() for _ in self.current_lines
                if _.startswith(('>>> ', '... '))
                ]
            while not self.current_lines[-1]:
                self.current_lines.pop()
        code_output_proxy = abjadbook.CodeOutputProxy(self.current_lines)
        self.output_proxies.append(code_output_proxy)
        self.current_lines[:] = []

    def setup_capture_hooks(self, console):
        prototype = (types.MethodType, types.FunctionType)
        if isinstance(console.locals['graph'], prototype):
            console.locals['graph'] = self.graph
        console.locals['show'] = self.show
        console.locals['quit'] = self.quit
        topleveltools = console.locals['topleveltools']
        topleveltools.__dict__['graph'] = self.graph
        topleveltools.__dict__['show'] = self.show

    def write(self, string):
        if string:
            if string.endswith('\n'):
                string = string[:-1]
            lines = string.splitlines()
            if self.text_width is None:
                self.current_lines.extend(lines)
            else:
                for line in lines:
                    wrapped_lines = textwrap.wrap(line, self.text_width)
                    self.current_lines.extend(wrapped_lines)

    ### PROXIES ###

    def graph(
        self,
        expr,
        layout='dot',
        graph_attributes=None,
        node_attributes=None,
        edge_attributes=None,
        **kwargs
        ):
        r'''Proxies Abjad's toplevel `graph()` function.

        ::

            >>> import abjadbook
            >>> console = abjadbook.AbjadBookConsole()
            >>> input_file_contents = [
            ...     'meter = metertools.Meter((4, 4))',
            ...     'graph(meter)',
            ...     'print(format(meter))',
            ...     ]
            >>> code_block = abjadbook.CodeBlock(input_file_contents)
            >>> code_block.interpret(console)
            >>> for output_proxy in code_block.output_proxies:
            ...     print(format(output_proxy))
            ...
            abjadbook.tools.CodeOutputProxy(
                (
                    '>>> meter = metertools.Meter((4, 4))',
                    '>>> graph(meter)',
                    )
                )
            abjadbook.tools.GraphvizOutputProxy(
                documentationtools.GraphvizGraph(
                    attributes={
                        'fontname': 'Arial',
                        'penwidth': 2,
                        },
                    children=(
                        documentationtools.GraphvizNode(
                            attributes={
                                'label': '4/4',
                                'shape': 'triangle',
                                },
                            ),
                        documentationtools.GraphvizNode(
                            attributes={
                                'label': '1/4',
                                'shape': 'box',
                                },
                            ),
                        documentationtools.GraphvizNode(
                            attributes={
                                'label': '1/4',
                                'shape': 'box',
                                },
                            ),
                        documentationtools.GraphvizNode(
                            attributes={
                                'label': '1/4',
                                'shape': 'box',
                                },
                            ),
                        documentationtools.GraphvizNode(
                            attributes={
                                'label': '1/4',
                                'shape': 'box',
                                },
                            ),
                        documentationtools.GraphvizSubgraph(
                            attributes={
                                'style': 'rounded',
                                },
                            children=(
                                documentationtools.GraphvizNode(
                                    attributes={
                                        'color': 'white',
                                        'fillcolor': 'black',
                                        'fontcolor': 'white',
                                        'fontname': 'Arial bold',
                                        'shape': 'Mrecord',
                                        'style': 'filled',
                                        },
                                    children=(
                                        documentationtools.GraphvizGroup(
                                            children=(
                                                documentationtools.GraphvizField(
                                                    label='0',
                                                    ),
                                                documentationtools.GraphvizField(
                                                    label='++',
                                                    ),
                                                ),
                                            ),
                                        ),
                                    ),
                                documentationtools.GraphvizNode(
                                    attributes={
                                        'color': 'white',
                                        'fillcolor': 'black',
                                        'fontcolor': 'white',
                                        'fontname': 'Arial bold',
                                        'shape': 'Mrecord',
                                        'style': 'filled',
                                        },
                                    children=(
                                        documentationtools.GraphvizGroup(
                                            children=(
                                                documentationtools.GraphvizField(
                                                    label='1/4',
                                                    ),
                                                documentationtools.GraphvizField(
                                                    label='+',
                                                    ),
                                                ),
                                            ),
                                        ),
                                    ),
                                documentationtools.GraphvizNode(
                                    attributes={
                                        'color': 'white',
                                        'fillcolor': 'black',
                                        'fontcolor': 'white',
                                        'fontname': 'Arial bold',
                                        'shape': 'Mrecord',
                                        'style': 'filled',
                                        },
                                    children=(
                                        documentationtools.GraphvizGroup(
                                            children=(
                                                documentationtools.GraphvizField(
                                                    label='1/2',
                                                    ),
                                                documentationtools.GraphvizField(
                                                    label='+',
                                                    ),
                                                ),
                                            ),
                                        ),
                                    ),
                                documentationtools.GraphvizNode(
                                    attributes={
                                        'color': 'white',
                                        'fillcolor': 'black',
                                        'fontcolor': 'white',
                                        'fontname': 'Arial bold',
                                        'shape': 'Mrecord',
                                        'style': 'filled',
                                        },
                                    children=(
                                        documentationtools.GraphvizGroup(
                                            children=(
                                                documentationtools.GraphvizField(
                                                    label='3/4',
                                                    ),
                                                documentationtools.GraphvizField(
                                                    label='+',
                                                    ),
                                                ),
                                            ),
                                        ),
                                    ),
                                documentationtools.GraphvizNode(
                                    attributes={
                                        'shape': 'Mrecord',
                                        },
                                    children=(
                                        documentationtools.GraphvizGroup(
                                            children=(
                                                documentationtools.GraphvizField(
                                                    label='1',
                                                    ),
                                                documentationtools.GraphvizField(
                                                    label='++',
                                                    ),
                                                ),
                                            ),
                                        ),
                                    ),
                                ),
                            edge_attributes={
                                },
                            is_cluster=True,
                            name='cluster_offsets',
                            node_attributes={
                                },
                            ),
                        ),
                    edge_attributes={
                        'penwidth': 2,
                        },
                    is_digraph=True,
                    name='G',
                    node_attributes={
                        'fontname': 'Arial',
                        'fontsize': 12,
                        'penwidth': 2,
                        },
                    ),
                layout='dot',
                )
            abjadbook.tools.CodeOutputProxy(
                (
                    '>>> print(format(meter))',
                    'metertools.Meter(',
                    "    '(4/4 (1/4 1/4 1/4 1/4))'",
                    '    )',
                    )
                )

        '''
        import abjadbook
        graph = expr.__graph__(**kwargs)
        if graph_attributes:
            graph.attributes.update(graph_attributes)
        if node_attributes:
            graph.node_attributes.update(node_attributes)
        if edge_attributes:
            graph.edge_attributes.update(edge_attributes)
        output_proxy = abjadbook.GraphvizOutputProxy(
            graph,
            layout=layout,
            )
        self.push_asset_output_proxy(output_proxy)

    def play(self, expr):
        r'''Proxies Abjad's toplevel `play()` function.
        '''
        pass

    def quit(self):
        r'''Proxies Python's builtin `quit()` function.
        '''
        pass

    def show(self, expr, return_timing=False, **kwargs):
        r'''Proxies Abjad's toplevel `show()` function.

        ::

            >>> import abjadbook
            >>> console = abjadbook.AbjadBookConsole()
            >>> input_file_contents = [
            ...     'staff = Staff(r"\clef bass c4 d4 e4 f4")',
            ...     'show(staff)',
            ...     'print(len(staff))'
            ...     ]
            >>> code_block = abjadbook.CodeBlock(input_file_contents)
            >>> code_block.interpret(console)
            >>> for output_proxy in code_block.output_proxies:
            ...     print(format(output_proxy))
            ...
            abjadbook.tools.CodeOutputProxy(
                (
                    '>>> staff = Staff(r"\\clef bass c4 d4 e4 f4")',
                    '>>> show(staff)',
                    )
                )
            abjadbook.tools.LilyPondOutputProxy(
                lilypondfiletools.LilyPondFile()
                )
            abjadbook.tools.CodeOutputProxy(
                ('>>> print(len(staff))', '4')
                )

        '''
        import abjadbook
        illustration = expr.__illustrate__(**kwargs)
        output_proxy = abjadbook.LilyPondOutputProxy(
            illustration,
            stylesheet=self.stylesheet,
            )
        self.push_asset_output_proxy(output_proxy)

    ### PUBLIC PROPERTIES ###

    @property
    def allow_exceptions(self):
        return self._allow_exceptions

    @property
    def current_lines(self):
        return self._current_lines

    @property
    def document_source(self):
        return self._document_source

    @property
    def executed_lines(self):
        return self._executed_lines

    @property
    def hide(self):
        return self._hide

    @property
    def output_proxies(self):
        return self._output_proxies

    @property
    def input_file_contents(self):
        return self._source_lines

    @property
    def starting_line_number(self):
        return self._starting_line_number

    @property
    def strip_prompt(self):
        return self._strip_prompt

    @property
    def stylesheet(self):
        return self._stylesheet

    @property
    def text_width(self):
        return self._text_width


#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import plotly.graph_objects as go
from src.sparse_distributed_representation import TEMPORAL_IDX, ENC_IDX

def plot_sam(sam_region, raw_data, xyz_types, colour_nodes, temporal_key=0, title=None):

    node_x = []
    node_y = []
    node_z = []

    next_color = 10
    colour_labels = {}
    node_colour = []
    node_label = []
    node_size = []

    edge_x = []
    edge_y = []
    edge_z = []

    x_min_max = {'min': None, 'max': None}
    y_min_max = {'min': None, 'max': None}
    z_min_max = {'min': None, 'max': None}

    neuron_xyz = {}
    neurons = sam_region['neural_graph']['neurons']
    for neuron_key in neurons:
        for key in neurons[neuron_key]['pattern_sdr']['encoding']:
            if key[TEMPORAL_IDX] == temporal_key:
                if isinstance(neurons[neuron_key]['pattern_sdr']['encoding'][key], dict):
                    val = neurons[neuron_key]['pattern_sdr']['encoding'][key]['value']
                else:
                    val = neurons[neuron_key]['pattern_sdr']['encoding'][key]

                if key[ENC_IDX] == xyz_types[0]:
                    node_x.append(val)
                    if neuron_key not in neuron_xyz:
                        neuron_xyz[neuron_key] = {'x': val, 'z': 0.0, 'y': 0.0}
                    else:
                        neuron_xyz[neuron_key]['x'] = val
                elif key[ENC_IDX] == xyz_types[1]:

                    node_y.append(val)
                    if neuron_key not in neuron_xyz:
                        neuron_xyz[neuron_key] = {'y': val, 'x': 0.0, 'z': 0.0}
                    else:
                        neuron_xyz[neuron_key]['y'] = val

                elif len(xyz_types) == 3 and key[ENC_IDX] == xyz_types[2]:

                    node_z.append(val)
                    if neuron_key not in neuron_xyz:
                        neuron_xyz[neuron_key] = {'z': val, 'x': 0.0, 'y': 0.0}
                    else:
                        neuron_xyz[neuron_key]['z'] = val

                if colour_nodes is not None and key[ENC_IDX] == colour_nodes:
                    if key[ENC_IDX] not in colour_labels:
                        colour = next_color
                        colour_labels[key[ENC_IDX]] = next_color
                        next_color += 1
                    else:
                        colour = colour_labels[key[ENC_IDX]]
                    node_colour.append(colour)

        if len(xyz_types) == 2:
            node_z.append(0.0)

        if colour_nodes is None:

            if x_min_max['max'] is None or node_x[-1] > x_min_max['max']:
                x_min_max['max'] = node_x[-1]
            if x_min_max['min'] is None or node_x[-1] < x_min_max['min']:
                x_min_max['min'] = node_x[-1]
            if y_min_max['max'] is None or node_y[-1] > y_min_max['max']:
                y_min_max['max'] = node_y[-1]
            if y_min_max['min'] is None or node_y[-1] < y_min_max['min']:
                y_min_max['min'] = node_y[-1]
            if z_min_max['max'] is None or node_z[-1] > z_min_max['max']:
                z_min_max['max'] = node_z[-1]
            if z_min_max['min'] is None or node_z[-1] < z_min_max['min']:
                z_min_max['min'] = node_z[-1]

        node_label.append(neuron_key)
        node_size.append(10 + neurons[neuron_key]['n_bmu'])

    pairs = set()
    for neuron_key in neurons:
        for nn_key in neurons[neuron_key]['community']:
            pair = (min(neuron_key, nn_key), max(neuron_key, nn_key))
            if pair not in pairs:
                pairs.add(pair)
                edge_x.append(neuron_xyz[neuron_key]['x'])
                edge_x.append(neuron_xyz[nn_key]['x'])
                edge_x.append(None)

                edge_y.append(neuron_xyz[neuron_key]['y'])
                edge_y.append(neuron_xyz[nn_key]['y'])
                edge_y.append(None)

                if len(xyz_types) == 3:
                    edge_z.append(neuron_xyz[neuron_key]['z'])
                    edge_z.append(neuron_xyz[nn_key]['z'])
                else:
                    edge_z.append(0.0)
                    edge_z.append(0.0)

                edge_z.append(None)

    if colour_nodes is None:
        for idx in range(len(node_x)):
            r = max(min(int(255 * ((node_x[idx] - x_min_max['min']) / (x_min_max['max'] - x_min_max['min']))), 255), 0)
            g = max(min(int(255 * ((node_y[idx] - y_min_max['min']) / (y_min_max['max'] - y_min_max['min']))), 255), 0)
            if (z_min_max['max'] - z_min_max['min']) > 0:
                b = max(min(int(255 * ((node_z[idx] - z_min_max['min']) / (z_min_max['max'] - z_min_max['min']))), 255), 0)
            else:
                b = 0
            node_colour.append(f'rgb({r},{g},{b})')

    raw_x = []
    raw_y = []
    raw_z = []
    raw_size = []
    raw_colour = []
    for idx in range(len(raw_data)):
        raw_x.append(raw_data[idx][0])
        raw_y.append(raw_data[idx][1])
        if len(raw_data[idx]) == 3:
            raw_z.append(raw_data[idx][2])
        else:
            raw_z.append(0.0)
        raw_size.append(5)
        raw_colour.append(1)

    raw_scatter = go.Scatter3d(x=raw_x, y=raw_y, z=raw_z, mode='markers',  name='raw data', marker=dict(size=3, color=raw_colour, opacity=1.0, symbol='square'))
    neuron_scatter = go.Scatter3d(x=node_x, y=node_y, z=node_z, name='neuron', hovertext=node_label, mode='markers+text', marker=dict(size=node_size, color=node_colour, opacity=0.7))
    edge_scatter = go.Scatter3d(x=edge_x, y=edge_y, z=edge_z, name='nn edge', mode='lines', line=dict(width=1, color='grey'))

    fig = go.Figure(data=[raw_scatter, edge_scatter, neuron_scatter])

    compression_ratio = round(len(neurons) / len(raw_data), 2)

    if title is None:
        title = sam_region["name"]

    fig.update_layout(width=1200, height=1200,
                      title=dict(text=f'{title} Nos Neurons: {len(neurons)} Nos Raw Data:{len(raw_data)} Ratio: {compression_ratio}'))
    fig.show()

def plot_pors(pors, title=None):
    ema_similarity = []
    ema_stdev = []

    x_values = []
    similarity = []
    nos_neurons = []

    final_neurons = pors[-1]['nos_neurons']

    for x in range(len(pors)):

        x_values.append(x)
        por = pors[x]

        similarity.append(por['bmu_similarity'])
        nos_neurons.append(por['nos_neurons'] / final_neurons)
        ema_similarity.append(por['avg_bmu_similarity'])
        ema_stdev.append(por['std_bmu_similarity'])

    anomaly_score_scatter = go.Scatter(x=x_values, y=similarity, mode='lines', name='similarity', line=dict(width=2, color='black'))
    nos_neurons_scatter = go.Scatter(x=x_values, y=nos_neurons, mode='lines', name='nos neurons', line=dict(width=2, color='orange'))

    ema_similarity_scatter = go.Scatter(x=x_values, y=ema_similarity, mode='lines', name='avg similarity', line=dict(width=2, color='blue'))
    ema_stdev_scatter = go.Scatter(x=x_values, y=ema_stdev, mode='lines', name='std similarity', line=dict(width=2, color='purple'))

    fig = go.Figure(data=[nos_neurons_scatter, anomaly_score_scatter, ema_similarity_scatter,ema_stdev_scatter])

    por = pors[-1]

    compression_ratio = round(final_neurons / len(pors), 2)

    if title is None:
        title = por["name"]

    fig.update_layout(width=1200, height=1200,
                      title=dict(text=f'{title} nos neurons: {final_neurons} Nos Raw_data: {len(pors)} Ratio: {compression_ratio}'))
    fig.show()


import multiprocessing
import logging as log
import serial
from serial.tools import list_ports
from time import time

class SerialProcess(multiprocessing.Process):
    def __init__(self, result_queue):
        self.queue = result_queue
        multiprocessing.Process.__init__(self)
        self.exit = multiprocessing.Event()
        self.s = serial.Serial()
        log.info("SerialProcess ready")

    @staticmethod
    def list_ports():
        return list_ports.comports()

    def get_ports(self):
        ports = []
        for port in self.list_ports():
            ports.append(port[0])
        return ports

    def get_ports_full(self):
        ports = []
        for port in self.list_ports():
            ports.append(port)
        return ports

    def is_port_available(self, port):
        for ports in self.list_ports():
            if ports[0] == port:
                return True
        return False

    def open_port(self, port, bd=115200, timeout=0.5):
        self.s.port = port
        self.s.baudrate = bd
        self.s.stopbits = serial.STOPBITS_ONE
        self.s.bytesize = serial.EIGHTBITS
        self.s.timeout = timeout
        return self.is_port_available(self.s.port)

    def run(self):
        if self.is_port_available(self.s.port):
            if not self.s.isOpen():
                self.s.open()
                log.info("Port opened")
                timestamp = time()
                while not self.exit.is_set():
                    """
                    http://eli.thegreenplace.net/2009/08/07/a-live-data-monitor-with-python-pyqt-and-pyserial/
                    """
                    data = self.s.read(1)
                    data += self.s.read(self.s.inWaiting())
                    if len(data) > 0:
                        self.queue.put((data, (time() - timestamp)))
                    log.debug(data)
                log.info("SerialProcess finished")
                self.s.close()
            else:
                log.warning("Port is not opened")
        else:
            log.warning("Port is not available")

    def stop(self):
        log.info("SerialProcess finishing...")
        self.exit.set()


from .base import SimIRExpr

import logging
l = logging.getLogger(name=__name__)

class SimIRExpr_Unsupported(SimIRExpr):

    __slots__ = []

    def _execute(self):
        l.error("Unsupported IRExpr %s. Please implement.", type(self._expr).__name__)
        self.expr = self.state.solver.Unconstrained(type(self._expr).__name__, self.size_bits())
        self.state.history.add_event('resilience', resilience_type='irexpr', expr=type(self._expr).__name__, message='unsupported irexpr')


import os
import random

from twython.exceptions import TwythonError

from core.scripts.twitter_related import base
from core.twitter_related_scripts_runner import EventDispatcherSingleton
from core.utils.logging import log

class NobodyCares(base.BaseTimelineScript):
    def on_timeline_update(self, data):
        do_reply = (random.randint(0, 500) == 0)
        if not do_reply or data.get('in_reply_to_status_id_str', None) or data['entities']['user_mentions'] or len(
                data['text']) == 0:
            return

        log('Ok...sending nobody cares')

        script_dir = os.path.dirname(__file__)
        photo_rel_address = 'assets/nobody_cares.jpg'
        photo_path = os.path.join(script_dir, photo_rel_address)
        photo = open(photo_path, 'rb')

        log('Photo found')

        try:
            self.twitter.update_status_with_media(
                status='@' + data['user']['screen_name'],
                media=photo,
                in_reply_to_status_id=data['id_str']
            )
            EventDispatcherSingleton().terminate_scripts()
        except TwythonError as e:
            print(e)


# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html

import json
import os

class ZarascraperPipeline(object):
    def process_item(self, item, spider):
        return item

class JsonWriterPipeline(object):

    shop = 'zara'
    gender = 'mujer'
    dirToSave = '../../../dataset/'+gender+'/'

    def open_spider(self, spider):
        self.current_products_abrigos_chaquetas = []
        self.current_products_vestidos = []
        self.current_products_monos = []
        self.current_products_camisetas = []
        self.current_products_tops_bodies = []
        self.current_products_camisas_blusas = []
        self.current_products_faldas = []
        self.current_products_pantalones_largos = []
        self.current_products_pantalones_cortos = []
        self.current_products_sudaderas_jerseis = []

        self.new_products_abrigos_chaquetas = []
        self.new_products_vestidos = []
        self.new_products_monos = []
        self.new_products_camisetas = []
        self.new_products_tops_bodies = []
        self.new_products_camisas_blusas = []
        self.new_products_faldas = []
        self.new_products_pantalones_largos = []
        self.new_products_pantalones_cortos = []
        self.new_products_sudaderas_jerseis = []

        self.update_products_abrigos_chaquetas = []
        self.update_products_vestidos = []
        self.update_products_monos = []
        self.update_products_camisetas = []
        self.update_products_tops_bodies = []
        self.update_products_camisas_blusas = []
        self.update_products_faldas = []
        self.update_products_pantalones_largos = []
        self.update_products_pantalones_cortos = []
        self.update_products_sudaderas_jerseis = []

    def close_spider(self, spider):

        categoryList = ['abrigos_chaquetas'
        ,'camisas_blusas','camisetas',
        'faldas','monos','pantalones_cortos','pantalones_largos','sudaderas_jerseis',
        'tops_bodies', 'vestidos'
        ]

        for category in categoryList:
            dirToSave = self.dirToSave+category+'/'+self.shop+'/products/'

            if category == 'abrigos_chaquetas':
                current_products = self.current_products_abrigos_chaquetas
                new_products = self.new_products_abrigos_chaquetas
                update_products = self.update_products_abrigos_chaquetas
            elif category == 'vestidos':
                current_products =self.current_products_vestidos
                new_products = self.new_products_vestidos
                update_products = self.update_products_vestidos
            elif category == 'monos':
                current_products =self.current_products_monos
                new_products = self.new_products_monos
                update_products = self.update_products_monos
            elif category == 'camisetas':
                current_products =self.current_products_camisetas
                new_products = self.new_products_camisetas
                update_products = self.update_products_camisetas
            elif category == 'tops_bodies':
                current_products =self.current_products_tops_bodies
                new_products = self.new_products_tops_bodies
                update_products = self.update_products_tops_bodies
            elif category == 'camisas_blusas':
                current_products =self.current_products_camisas_blusas
                new_products = self.new_products_camisas_blusas
                update_products = self.update_products_camisas_blusas
            elif category == 'faldas':
                current_products =self.current_products_faldas
                new_products = self.new_products_faldas
                update_products = self.update_products_faldas
            elif category == 'pantalones_largos':
                current_products =self.current_products_pantalones_largos
                new_products = self.new_products_pantalones_largos
                update_products = self.update_products_pantalones_largos
            elif category == 'pantalones_cortos':
                current_products =self.current_products_pantalones_cortos
                new_products = self.new_products_pantalones_cortos
                update_products = self.update_products_pantalones_cortos
            elif category == 'sudaderas_jerseis':
                current_products =self.current_products_sudaderas_jerseis
                new_products = self.new_products_sudaderas_jerseis
                update_products = self.update_products_sudaderas_jerseis

            if len(current_products) > 0:
                try:
                    with open(dirToSave+'previous_products.json') as f:
                        previous_products = json.load(f)

                except FileNotFoundError as exc:
                        previous_products = []

                aux_previous_products = []
                for product in previous_products:

                    if product not in current_products:
                        aux_previous_products.append(product)

                with open(dirToSave+'current_products.json', 'w') as f:
                    json.dump(list(set(current_products)), f, indent = 2, separators = (',',': '))

                with open(dirToSave+'new_products.json', 'w') as f:
                    json.dump(list(set(new_products)), f, indent = 2, separators = (',',': '))

                with open(dirToSave+'update_products.json', 'w') as f:
                    json.dump(list(set(update_products)), f, indent = 2, separators = (',',': '))

                with open(dirToSave+'previous_products.json', 'w') as f:
                    json.dump(aux_previous_products, f, indent = 2, separators = (',',': '))

    def process_item(self, item, spider):
        if item['category'] == 'abrigos_chaquetas':
            self.current_products_abrigos_chaquetas.append(item['productId'])
            if item['new']:
                self.new_products_abrigos_chaquetas.append(item['productId'])
            elif item['update']:
                self.update_products_abrigos_chaquetas.append(item['productId'])
        elif item['category'] == 'vestidos':
            self.current_products_vestidos.append(item['productId'])
            if item['new']:
                self.new_products_vestidos.append(item['productId'])
            elif item['update']:
                self.update_products_vestidos.append(item['productId'])
        elif item['category'] == 'monos':
            self.current_products_monos.append(item['productId'])
            if item['new']:
                self.new_products_monos.append(item['productId'])
            elif item['update']:
                self.update_products_monos.append(item['productId'])
        elif item['category'] == 'camisetas':
            self.current_products_camisetas.append(item['productId'])
            if item['new']:
                self.new_products_camisetas.append(item['productId'])
            elif item['update']:
                self.update_products_camisetas.append(item['productId'])
        elif item['category'] == 'tops_bodies':
            self.current_products_tops_bodies.append(item['productId'])
            if item['new']:
                self.new_products_tops_bodies.append(item['productId'])
            elif item['update']:
                self.update_products_tops_bodies.append(item['productId'])
        elif item['category'] == 'camisas_blusas':
            self.current_products_camisas_blusas.append(item['productId'])
            if item['new']:
                self.new_products_camisas_blusas.append(item['productId'])
            elif item['update']:
                self.update_products_camisas_blusas.append(item['productId'])
        elif item['category'] == 'faldas':
            self.current_products_faldas.append(item['productId'])
            if item['new']:
                self.new_products_faldas.append(item['productId'])
            elif item['update']:
                self.update_products_faldas.append(item['productId'])
        elif item['category'] == 'pantalones_largos':
            self.current_products_pantalones_largos.append(item['productId'])
            if item['new']:
                self.new_products_pantalones_largos.append(item['productId'])
            elif item['update']:
                self.update_products_pantalones_largos.append(item['productId'])
        elif item['category'] == 'pantalones_cortos':
            self.current_products_pantalones_cortos.append(item['productId'])
            if item['new']:
                self.new_products_pantalones_cortos.append(item['productId'])
            elif item['update']:
                self.update_products_pantalones_cortos.append(item['productId'])
        elif item['category'] == 'sudaderas_jerseis':
            self.current_products_sudaderas_jerseis.append(item['productId'])
            if item['new']:
                self.new_products_sudaderas_jerseis.append(item['productId'])
            elif item['update']:
                self.update_products_sudaderas_jerseis.append(item['productId'])

        return item


#!/usr/bin/python
# Example of calling SecureNet Charge API from Python
import requests

secureNetId = '8008966'  # Replace with your own ID
secureKey = 'MgvfuwWMGUJl'  # Replace with your own Key
url = 'https://gwapi.demo.securenet.com/api/Payments/Charge'
data = {
    'amount': 1.23,
    'check': {
        'firstName': 'Fred',
        'lastName': 'Flintstone',
        'routingNumber': 222371863,
        'accountNumber': 123456
    },
    'developerApplication': {
        'developerId': 12345678,
        'version': '1.2'
    }
}

print("Sending charge request")
response = requests.post(
    url,
    headers={"content-type": "application/json"},
    auth=(secureNetId, secureKey),
    json=data,
    verify=True)

print("HTTP Status Code: {0}".format(response.status_code))
if (response.ok):
    json = response.json()
    print("success: {0}".format(json["success"]))
    print("result: {0}".format(json["result"]))
    print("message: {0}".format(json["message"]))
    print("transactionId: {0}".format(json["transaction"]["transactionId"]))


# -*- coding: utf-8 -*-

import logging

from latex import LatexDocument

from django.utils.translation import ugettext as _
from django.template import Template as DjTemplate
from django.template import Context as DjContext

from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.files.base import ContentFile

from storage.models import Template, GeneratedFile, KYCFile

logger = logging.getLogger("api.latex")

# https://pypi.python.org/pypi/django-latex/0.1
def _generatePDF(template, context={}):
    """
    Compute a pdf from a LaTeX @template, with some dynamic data in @context
    return a @GeneratedFile instance
    """
    t = DjTemplate(template.content)
    c = DjContext(context)

    latex_str = t.render(c)
    latex_str += '' # to django.utils.safestring.SafeText to unicode

    latex_doc = LatexDocument(latex_str)

    try:
        gen_file = GeneratedFile()
        gen_file.template = template
        result = latex_doc.as_pdf(debug=True) # returns a StringIO instance
    except LatexDocument.LatexPdfGenerationError as e:
        gen_file.errors = "Error during pdf generation: %s" % str(e)
        logger.error(str(e))
    else:
        gen_file.file.save("%s-%d" % (template.name, template.id,), ContentFile(result.read()))

    gen_file.save()

    return gen_file

def generateInvestorBook(ba):
    template = Template.objects.get(type='INVESTOR_BOOK')

    context = {
    	'business_angel': ba,
    }

    return _generatePDF(template, context)


from Tkinter import *
import ttk
import functools
import helpers
import chapter1.section1.problem1.problem1

def load_problem_one(tree, frame):
  tree.insert("ch1.1", "end", "ch1.1.1", text="Problem 1", tags=["ch1.1.1"])
  tree.tag_bind("ch1.1.1", '<1>',
    functools.partial(problem_one_view, tree, frame))

def problem_one_view(tree, frame, event):
  helpers.clear_frame(frame)

  prompt = Label(frame, text=u"Given a number \u03B1, find rational number " +
    u"p/q such that |\u03B1 - p/q| \u2264 1/q^2")
  prompt.grid(row=0, columnspan=3)

  entryLabel = Label(frame, text=u"Enter an \u03B1:")
  entryLabel.grid(row=1, column=0)
  alpha = Entry(frame)
  alpha.grid(row=1, column=1)
  submitButton = Button(frame,
    text="submit",
    command=functools.partial(problem_one_display_answer, tree, frame, alpha))
  submitButton.grid(row=1, column=2)

def problem_one_display_answer(tree, frame, alpha):
  helpers.clear_row(frame, 2)

  answer = chapter1.section1.problem1.problem1.problem(int(alpha.get()))

  answerText = Label(frame, text=u"With an \u03B1 of " +
    unicode(int(alpha.get())) + u" we have the inequality " +
    unicode(answer[0][2]) + u" \u2264 " + unicode(answer[0][3]) +
    u" when p=" + unicode(answer[0][0]) + u" and q=" +
    unicode(answer[0][1]))

  answerText.grid(row=2, columnspan=3)


"""
Copyright (C) 2014 The HDF Group
Copyright (C) 2014 John Evans

This example code illustrates how to access and visualize an NSIDC AMSR grid
file in Python.

If you have any questions, suggestions, or comments on this example, please use
the HDF-EOS Forum (http://hdfeos.org/forums).  If you would like to see an
example of any other NASA HDF/HDF-EOS data product that is not listed in the
HDF-EOS Comprehensive Examples page (http://hdfeos.org/zoo), feel free to
contact us at eoshelp@hdfgroup.org or post it at the HDF-EOS Forum
(http://hdfeos.org/forums).

Usage:  save this script and run

    python AMSR_E_L3_SI_25km_NH_06V_ASC.py

The HDF file must either be in your current working directory or in a directory
specified by the environment variable HDFEOS_ZOO_DIR.
"""

import os
import re

import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import mpl_toolkits.basemap.pyproj as pyproj
import numpy as np

USE_GDAL = False

def run(FILE_NAME):

    # Identify the data field.
    DATAFIELD_NAME = 'SI_25km_NH_06V_ASC'

    if USE_GDAL:
        import gdal
        GRID_NAME = 'NpPolarGrid25km'
        gname = 'HDF4_EOS:EOS_GRID:"{0}":{1}:{2}'.format(FILE_NAME,
                                                         GRID_NAME,
                                                         DATAFIELD_NAME)
        gdset = gdal.Open(gname)
        data = gdset.ReadAsArray().astype(np.float64)

        # Read projection parameters from global attribute.
        meta = gdset.GetMetadata()
        x0, xinc, _, y0, _, yinc = gdset.GetGeoTransform()
        nx, ny = (gdset.RasterXSize, gdset.RasterYSize)
        del gdset
    else:
        from pyhdf.SD import SD, SDC
        hdf = SD(FILE_NAME, SDC.READ)

        # Read dataset.
        data2D = hdf.select(DATAFIELD_NAME)
        data = data2D[:,:].astype(np.float64)
        # Read global attribute.
        fattrs = hdf.attributes(full=1)
        ga = fattrs["StructMetadata.0"]
        gridmeta = ga[0]

        # Construct the grid.  The needed information is in a global attribute
        # called 'StructMetadata.0'.  Use regular expressions to tease out the
        # extents of the grid.
        ul_regex = re.compile(r'''UpperLeftPointMtrs=\(
                                  (?P<upper_left_x>[+-]?\d+\.\d+)
                                  ,
                                  (?P<upper_left_y>[+-]?\d+\.\d+)
                                  \)''', re.VERBOSE)
        match = ul_regex.search(gridmeta)
        x0 = np.float(match.group('upper_left_x'))
        y0 = np.float(match.group('upper_left_y'))

        lr_regex = re.compile(r'''LowerRightMtrs=\(
                                  (?P<lower_right_x>[+-]?\d+\.\d+)
                                  ,
                                  (?P<lower_right_y>[+-]?\d+\.\d+)
                                  \)''', re.VERBOSE)
        match = lr_regex.search(gridmeta)
        x1 = np.float(match.group('lower_right_x'))
        y1 = np.float(match.group('lower_right_y'))
        ny, nx = data.shape
        xinc = (x1 - x0) / nx
        yinc = (y1 - y0) / ny

    # Apply the attributes information.
    # Ref:  http://nsidc.org/data/docs/daac/ae_si12_25km_seaice/data.html
    data[data == 0] = np.nan
    data *= 0.1
    data = np.ma.masked_array(data, np.isnan(data))

    # Construct the grid.  Reproject out of the GCTP stereographic into lat/lon.
    x = np.linspace(x0, x0 + xinc*nx, nx)
    y = np.linspace(y0, y0 + yinc*ny, ny)
    xv, yv = np.meshgrid(x, y)
    args = ["+proj=stere",
            "+lat_0=90",
            "+lon_0=-45",
            "+lat_ts=70",
            "+k=1",
            "+es=0.006693883",
            "+a=6378273",
            "+x_0=0",
            "+y_0=0",
            "+ellps=WGS84",
            "+datum=WGS84"]
    pstereo = pyproj.Proj(' '.join(args))
    wgs84 = pyproj.Proj("+init=EPSG:4326")
    lon, lat= pyproj.transform(pstereo, wgs84, xv, yv)

    units = 'K'
    long_name = DATAFIELD_NAME

    m = Basemap(projection='npstere', resolution='l', boundinglat=30, lon_0 = 0)
    m.drawcoastlines(linewidth=0.5)
    m.drawparallels(np.arange(0, 91, 20), labels=[1, 0, 0, 0])
    m.drawmeridians(np.arange(-180, 181, 45), labels=[0, 0, 0, 1])
    m.pcolormesh(lon, lat, data, latlon=True)

    cb = m.colorbar()
    cb.set_label(units)

    basename = os.path.basename(FILE_NAME)
    plt.title('{0}\n{1}'.format(basename, long_name))
    fig = plt.gcf()
    # plt.show()
    pngfile = "{0}.py.png".format(basename)
    fig.savefig(pngfile)

if __name__ == "__main__":

    # If a certain environment variable is set, look there for the input
    # file, otherwise look in the current directory.
    hdffile = 'AMSR_E_L3_SeaIce25km_V11_20050118.hdf'
    try:
        hdffile = os.path.join(os.environ['HDFEOS_ZOO_DIR'], hdffile)
    except KeyError:
        pass

    run(hdffile)


from django.conf.urls import url

from . import views

urlpatterns = [
    # 判断用户名是否重复
    url(r'^usernames/(?P<username>\w{5,20})/count/$', views.UsernameCountView.as_view()),
    # 判断手机号是否重复
    url(r'^mobiles/(?P<mobile>1[3-9]\d{9})/count/$', views.MobileCountView.as_view()),
    # 注册
    url(r'^users/$', views.UserView.as_view()),
]


from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'pyDnsAdmin.views.home', name='home'),
    # url(r'^pyDnsAdmin/', include('pyDnsAdmin.foo.urls')),
    url(r'^$', 'dashboard.views.index', name='dashboard'),

    url(r'^customer/', include('customer.urls')),
    url(r'^user/', include('useraccount.urls')),
    url(r'^recordtype/', include('recordtype.urls')),
    url(r'^nameserver/', include('nameserver.urls')),
    url(r'^domain/', include('domain.urls')),
    url(r'^revision/', include('revision.urls')),
#    url(r'^record/', include('record.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
)


"""transformer devmap"""

########### Make your changes below the line ######################

# subfolder under classifyapp_logs/
subfolder = 'devmap_logs/transformer_supervised_amd'
# choose 3 letters to identify your experiment
jobname = 'sta'

model = 'transformer_devmap'  # 'ggnn_SET' or 'transformer_SET' or 'x_pretraining' (dataset without split!)
dataset = 'devmap_amd'  # poj104, ncc, devmap_amd, _nvidia, threadcoarsening_Cypress, _Tahiti, _Fermi, _Kepler
kfold = '--kfold' # '' = no kfold, '--kfold' for kfold.
transfer = ''  # '--transfer=transformer_devmap' # '' for no transfer, '--transfer=transformer_devmap'
restore = ''  # "--restore=deeplearning/ml4pl/poj104/logs/ncc_logs/transformer/2020-03-02_04:12:31_000_31632_model_best.pickle"

# 4h runtime per submission
resubmit_times_per_job = 3

# a set of hyperparameters to grid search over
choices_dict = {
    'lr': [0.00025],
    'output_dropout': [0.0], #, 0.5],
    'aux_use_better': [False, True],
    'num_epochs': [200],
    # 'vocab_size': [8569],
    }

################ Make your changes above the line ################

template = """#!/bin/bash
#SBATCH --job-name={jobname}{i:03d}
#SBATCH --time={timelimit}
#SBATCH --partition=total
#SBATCH --gres=gpu:1
#SBATCH --mail-type=ALL
#SBATCH --cpus-per-task=8
#SBATCH --mail-user=zacharias.vf@gmail.com
#SBATCH --exclude=ault07,ault08,ault20
#SBATCH --dependency=singleton

source /users/zfisches/.bash_profile;
cd /users/zfisches/ProGraML;

srun python deeplearning/ml4pl/models/ggnn/run.py \
--dataset={dataset} \
--model={model} \
{kfold} \
{transfer} \
--log_dir=deeplearning/ml4pl/poj104/logs/{subfolder}/ \
{restore_by_pattern} \
--config_json="{config_str}" \
{restore} \
"""  # NO WHITESPACE!!!

# make this file executable from anywhere
import os, sys
from pathlib import Path
full_path = os.path.realpath(__file__)
print(full_path)
repo_root = full_path.rsplit('ProGraML', maxsplit=1)[0] + 'ProGraML'
print(repo_root)
#insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, repo_root)
repo_root = Path(repo_root)

from deeplearning.ml4pl.poj104.scripts.AULT_write_runscripts import write_runscripts

if __name__ == '__main__':
    write_runscripts(subfolder=subfolder, template=template, choices_dict=choices_dict, jobname=jobname, steps=resubmit_times_per_job, model=model, dataset=dataset, kfold=kfold, transfer=transfer, restore=restore)


from django import template
from realestate.models import RentOffer, SellOffer

register = template.Library()

@register.simple_tag
def dispaly_offer_label(offer):
    if isinstance(offer, RentOffer):
        label = "For Rent"
    elif isinstance(offer, SellOffer):
        label = "For Sale"
    else:
        label = "Offer Type not known"
    return label

# @register.simple_tag
# def url_replace(request, field, value):
#     """
#     Usage:
#      <a href="?{% url_replace request 'page' paginator.next_page_number %}">
#     """
#     dict_ = request.GET.copy()
#
#     dict_[field] = value
#
#     return dict_.urlencode()

from urllib.parse import urlencode

@register.simple_tag(takes_context=True)
def url_replace(context, **kwargs):
    query = context['request'].GET.dict()
    query.update(kwargs)
    return urlencode(query)


from pymavlink import mavutil
from dronekit import connect, VehicleMode, LocationGlobalRelative
import time

def send_body_ned_velocity(velocity_x, velocity_y, velocity_z, duration=0):
    msg = vehicle.message_factory.set_position_target_local_ned_encode(
        0,       # time_boot_ms (not used)
        0, 0,    # target system, target component
        mavutil.mavlink.MAV_FRAME_BODY_NED, # frame Needs to be MAV_FRAME_BODY_NED for forward/back left/right control.
        0b0000111111000111, # type_mask
        0, 0, 0, # x, y, z positions (not used)
        velocity_x, velocity_y, velocity_z, # m/s
        0, 0, 0, # x, y, z acceleration
        0, 0)
    for x in range(0,duration):
        vehicle.send_mavlink(msg)
        time.sleep(1)

takeoff_alt = 0.015
vehicle = connect('/dev/serial0', wait_ready= True,baud=57600)
while not vehicle.is_armable:
    time.sleep(1)
vehicle.mode = VehicleMode("GUIDED")
vehicle.armed = True
while not vehicle.armed:
    print('Waiting for arming...')
    time.sleep(1)
vehicle.simple_takeoff(takeoff_alt) # Take off to target altitude
while True:
    print('Altitude: %d' %  vehicle.location.global_relative_frame.alt)
    if vehicle.location.global_relative_frame.alt >= takeoff_alt * 0.95:
        print('REACHED TARGET ALTITUDE')
        break
    time.sleep(1)

# This is the command to move the copter 5 m/s forward for 10 sec.
print("move right")
velocity_x = -5
velocity_y = 0
velocity_z = 0
duration = 10
send_body_ned_velocity(velocity_x, velocity_y, velocity_z, duration)

# left at 5 m/s for 10 sec.
print("move left")
velocity_x = 5
velocity_y = 0
velocity_z = 0
duration = 10
send_body_ned_velocity(velocity_x, velocity_y, velocity_z, duration)

vehicle.mode = VehicleMode("LAND")


# -*- coding: utf-8 -*-
# @Time    : 2020/4/29 10:33 PM
# @Author  : Yinghao Qin
# @Email   : y.qin@hss18.qmul.ac.uk
# @File    : utils.py
# @Software: PyCharm
# Reference:
#   https://github.com/WZMIAOMIAO/deep-learning-for-image-processing/tree/master/pytorch_learning
#   https://github.com/39239580/googlenet-pytorch/blob/master/Inception_v1_mnist.py
#   https://www.kaggle.com/grfiv4/plot-a-confusion-matrix
import os
import itertools
import numpy as np
import matplotlib.pyplot as plt

def plot_accuracy_curve(train_list, test_list, show=False, save=True, path='results/accuracy_epoch.png'):
    """
    It is used to plot the accuracy curve. Note that train_list and test_list have the same size.

    :param train_list: the accuracy list containing accuracies per epoch for train data
    :param test_list: the accuracy list containing accuracies per epoch for test data
    :param show: whether to show the plot
    :param save: whether to save the plot
    :param path: if the plot is saved, the path that will be saved
    :return: no
    """
    num = len(train_list)
    x_axis = np.linspace(1, num, num, endpoint=True)
    plt.plot(x_axis, train_list, color='r', label='Train accuracy')
    plt.plot(x_axis, test_list, color='b', label='Test accuracy')
    plt.legend()
    plt.title('Accuracy against epoch in the train and test sets')
    plt.xlabel('Epoch')
    plt.ylabel('Accuracy(%)')
    if save:
        if not os.path.exists('results'):
            os.mkdir('results')
        else:
            pass
        plt.savefig(path)

    if show:
        plt.show()
    else:
        plt.close()
    plt.close()

def plot_loss_curve(train_list, test_list, show=False, save=True, path='results/loss_epoch.png'):
    """
    It is used to plot the accuracy curve. Note that train_list and test_list have the same size.

    :param train_list: the loss list containing losses per epoch for train data
    :param test_list: the loss list containing losses per epoch for train data
    :param show: whether to show the plot
    :param save: whether to save the plot
    :param path: if the plot is saved, the path that will be saved
    :return: no
    """
    num = len(train_list)
    x_axis = np.linspace(1, num, num, endpoint=True)
    plt.plot(x_axis, train_list, color='r', label='Train loss')
    plt.plot(x_axis, test_list, color='b', label='Test loss')
    plt.legend()
    plt.title('Loss against epoch in the train and test sets')
    plt.xlabel('Epoch')
    plt.ylabel('Loss')
    if save:
        if not os.path.exists('results'):
            os.mkdir('results')
        else:
            pass
        plt.savefig(path)

    if show:
        plt.show()
    else:
        plt.close()
    plt.close()

def get_confusion_matrix(classes, predicts_list, labels_list):
    """
    Given predicted results and ground-truth labels, the function return the corresponding confusion matrix.

    :param classes: the classes of labels, it is used to compute the length of the classes
    :param predicts_list: the list of predicted results
    :param labels_list: the list of label results
    :return: confusion matrix
    """
    size = len(classes)
    length = len(predicts_list)
    confusion_matrix = np.zeros((size, size))
    for i in range(size):
        for j in range(size):
            confusion_matrix[i][j] = np.sum([(predicts_list[k] == i) and (labels_list[k] == j) for k in range(length)])
    return confusion_matrix

def plot_confusion_matrix(cm, target_names, title='Confusion matrix', cmap=None, normalize=True):
    """
    Given a sklearn confusion matrix (cm), make a nice plot

    :param cm: confusion matrix from sklearn.metrics.confusion_matrix
    :param target_names: given classification classes such as [0, 1, 2], the class names,
                         for example: ['high', 'medium', 'low']
    :param title: the text to display at the top of the matrix
    :param cmap: the gradient of the values displayed from matplotlib.pyplot.cm
                  see http://matplotlib.org/examples/color/colormaps_reference.html
                  plt.get_cmap('jet') or plt.cm.Blues
    :param normalize: If False, plot the raw numbers
                  If True, plot the proportions
    :return: no
    Usage
    -----
        plot_confusion_matrix(cm  = cm,                  # confusion matrix created by sklearn.metrics.confusion_matrix
                          normalize    = True,                # show proportions
                          target_names = y_labels_vals,       # list of names of the classes
                          title        = best_estimator_name) # title of graph
    Citiation
    ---------
    http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html
    """

    accuracy = np.trace(cm) / float(np.sum(cm))
    misclass = 1 - accuracy

    if cmap is None:
        cmap = plt.get_cmap('Blues')

    plt.figure(figsize=(8, 6))
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()

    if target_names is not None:
        tick_marks = np.arange(len(target_names))
        plt.xticks(tick_marks, target_names, rotation=45)
        plt.yticks(tick_marks, target_names)

    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    thresh = cm.max() / 1.5 if normalize else cm.max() / 2
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        if normalize:
            plt.text(j, i, "{:0.4f}".format(cm[i, j]),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")
        else:
            plt.text(j, i, "{:,}".format(cm[i, j]),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))

    # the result will be stored at
    if not os.path.exists('results'):
        os.mkdir('results')
    else:
        pass
    plt.savefig('results/confusion_matrix.png')
    plt.show()


import datetime
import discord

class MessageUtils:

    @staticmethod
    def convert_time_delta(end: datetime, start: datetime):
        delta = end - start
        hours, remainder = divmod(int(delta.total_seconds()), 3600)
        minutes, seconds = divmod(remainder, 60)
        days, hours = divmod(hours, 24)

        days_text = 'days' if days != 1 else 'day'
        hours_text = 'hours' if hours != 1 else 'hour'
        minutes_text = 'minutes' if minutes != 1 else 'minute'
        seconds_text = 'seconds' if seconds != 1 else 'second'

        if days > 0:
            return f'{days} {days_text}, {hours} {hours_text}, {minutes} {minutes_text}, {seconds} {seconds_text}'
        if hours > 0:
            return f'{hours} {hours_text}, {minutes} {minutes_text}, {seconds} {seconds_text}'
        if minutes > 0:
            return f'{minutes} {minutes_text}, {seconds} {seconds_text}'
        return f'{seconds} {seconds_text}'

    @staticmethod
    def stringify_datetime(time: datetime):
        """
        Returns:
            a readable and formatted version of a datetime object
        """
        return time.strftime('%B %d, %Y at %H:%M:%S UTC')

class ColoredEmbed(discord.Embed):
    def __init__(self, **kwargs):
        super().__init__(colour=0x3dbbe5, **kwargs)


import base64
import ast

import json
import tweepy
import re
from collections import Counter
import time
from decouple import config
import sys
import os

from google.cloud import pubsub_v1

import argparse
import time

from google.cloud import firestore

import datetime

def get_user_interactions(list_dict):
    """Crawls the targeted user's timeline and returns interactions.
    Args:
        `list_dict`, dict: A dictionary containing the following variables:
            `search`, string: The name of the user who's timeline to search.
            `output`, list of tuples: paired list of search & interaction targets.
            `next_query`, list: a list of names to search on the next run.
            `limit`, int: A flag to indicate how many results should be returned.
            'level'

    Functionality:
        Initialize search for the specific user.
        Get the user's tweets from their timeline.
        Cycle through all the tweets' text and join it into a mega-string.
        Do some standardizing and replacing.
        Strip away everything except usernames, into a string.
        Make a list of the counts, and take the top (X) most common people.
        Creates a list of the `top` people. No duplicates
        Tuples the results of the search & output together.
        Make search inputs for the next level of crawling.

    Returns:
        This function is async and has no return statement, rather it
        instead updates the values of `output` and `next_query` extending
        the lists that were passed to it as args.
    """
    search, output, found, search_depth, level, errors = list_dict

    if level > 1:

        project_id = os.environ['GCP_PROJECT']
        db = firestore.Client()
        get_user = db.collection(u'interactions').document(search).get()
        user_info = get_user.to_dict()

        if user_info is not None:

            time = user_info['timestamp']

            d = time.strftime("%Y-%m-%d")
            d = datetime.datetime.strptime(d, "%Y-%m-%d")
            now = datetime.datetime.now()

            delta = now - d
            if delta.days < 7:
                print("User has already been checked this week.")

                print('TEST CHECK DB: ', time)
                print('since: ', delta)
                return

    try:
        twitter_user = TWITTER.get_user(search)
        print('grabbing timeline for user: ', search)
        print('The search depth is:', search_depth)
        tweets = twitter_user.timeline(
                    count=200,
                    exclude_replies=False,
                    include_rts=True,
                    tweet_mode='extended'
        )
        full_tweets = [i.full_text for i in tweets]
        long_string = " ".join(full_tweets)
        lowercase = long_string.lower()
        remove_orgin_user = lowercase.replace(search, "")
        out = re.findall(r'(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)',remove_orgin_user)

        if search_depth > 0:

            top = Counter(out).most_common(search_depth)
            if len(top) == 0:
                errors.append(search)
                return
            interactions = []
            for interaction_count in top:
                interactions += ([interaction_count[0]] * interaction_count[1])

            tweet_data = [(search, i) for i in interactions]
            output.extend(tweet_data)

            found_users = [person[0] for person in top]
            found.extend(found_users)

        elif search_depth == -1:
            top = Counter(out).most_common()
            tweet_data = [(search, i) for i in out]
            output = output.extend(tweet_data)

            found_users = [person[0] for person in top]
            found.extend(found_users)

    except tweepy.TweepError:
        errors.append(search)
        print("tweepy.TweepError")

    except:
        e = sys.exc_info()[0]
        errors.append(search)
        print("Error: %s" % e)

def interaction_chain(origin_user, first_search_depth, second_search_depth):
    from concurrent.futures import ThreadPoolExecutor as PoolExecutor
    """Calls our async function & loops through it for each target user."""

    # init function variables
    data = []
    level = 0

    start_time = time.time()
    last_time = time.time()

    users_to_search = []# Next search targets

    blacklist = []

    found_users = []
    found_users.extend(origin_user)

    past_users = []  # Current users deposited after llvl, cleans out f users.
    #past_users += origin_user
    print('test',found_users)

    # Updates the time for each loop.
    def funct_time(last, d, l):
        now = time.time()
        check_time = now - last
        print("\n\nLevel %s Completed\nLevel %s time to complete: %s." % (l, l, check_time))
        print("Level %s total cumulative interactions found:", (l, len(d)))
        return now

    # Dedupe & Check user list for previous runs (no duplicated work).
    def update_lists(searched_users, found_users, past_users, level):
        found_users = list(dict.fromkeys(found_users)) # Dedupe f_users.
        past_users.extend([x for x in searched_users if x not in blacklist]) # Deposit last search(ed)_users into past_users. (input to last run)

        found_users = [x for x in found_users if x not in past_users]

        searched_users = found_users #Overwrite ss_users list with cleaned ff_users loop output.
        found_users = [] #Reset ff_users for next run.
        level += 1
        if level == 1:
        	print("----------Entering %sst level. Searching the following users:----------\n" % level, searched_users)
        else: # on other runs...
            print("Level %s new connections found:" % len(searched_users), "\n\n")
            print("Total %s connections discovered so far." % (len(past_users)+len(searched_users)) )
            print("---------Beginning Level %s - Searching the following users:\n" % level, searched_users)
        return searched_users, found_users, past_users, level

    # Pre-run print.
    users_to_search, found_users, past_users, level = update_lists(users_to_search, found_users, past_users, level)

    # Level 1 Run.
    loop_num = 1
    with PoolExecutor(max_workers=20) as executor:
        for _ in executor.map(get_user_interactions, [(x, data, found_users, first_search_depth, level, blacklist) for x in users_to_search]):
            print("Loop # ", loop_num, " . Time so far:", time.time() - start_time)
            loop_num +=1
            pass

    last_time = funct_time(last_time, data, level)
    users_to_search, found_users, past_users, level = update_lists(users_to_search, found_users, past_users, level)

    # Level 2 Run.
    loop_num = 1
    with PoolExecutor(max_workers=20) as executor:
        for _ in executor.map(get_user_interactions, [(x, data, found_users, second_search_depth, level, blacklist) for x in users_to_search]):
            print("Loop # ", loop_num, " . Time so far:", time.time() - start_time)
            loop_num +=1
            pass

    last_time = funct_time(last_time, data, level)

    users_to_search, found_users, past_users, level = update_lists(users_to_search, found_users, past_users, level)

    print("Total time:", time.time() - start_time)
    print("Total Connections found:", (len(past_users)-1))
    print("Total Overall Interactions found:", len(data))
    num_total_interactions = len(data)
    print(past_users)
    return data, past_users

def get_callback(api_future, data):
    """Wrap message data in the context of the callback function."""

    def callback(api_future):
        try:
            print("Published message {} now has message ID {}".format(
                data, api_future.result()))
        except Exception:
            print("A problem occurred when publishing {}: {}\n".format(
                data, api_future.exception()))
            raise
    return callback

def publish(interactions, topic):
    """Publishes a message to a Pub/Sub topic."""
    # [START pubsub_quickstart_pub_client]
    # Initialize a Publisher client
    client = pubsub_v1.PublisherClient()
    # [END pubsub_quickstart_pub_client]
    # Create a fully qualified identifier in the form of
    # `projects/{project_id}/topics/{topic_name}`
    topic_path = client.topic_path('bert-optimization-testing', topic)

    # Data sent to Cloud Pub/Sub must be a bytestring

    data = json.dumps(interactions, ensure_ascii=False).encode('utf8')

    api_future = client.publish(topic_path, data=data)
    api_future.add_done_callback(get_callback(api_future, data))

    # Keep the main thread from exiting until background message
    # is processed.
    while api_future.running():
        time.sleep(0.1)

    print("data published")

def generate_recommendation_response(original_user, TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET, message_id, depth):
    """
    Takes in all the established variables and passes them to the correct functions.
    """
    # Create Twitter Connection
    first_search_depth = depth
    second_search_depth = depth

    twitter_auth = tweepy.OAuthHandler(config('TWITTER_CONSUMER_KEY'),config('TWITTER_CONSUMER_SECRET'))

    print('Twitter Consumer Key: ', config('TWITTER_CONSUMER_KEY'))
    print('Twitter Consumer Secret: ', config('TWITTER_CONSUMER_SECRET'))

    access_token = str(TWITTER_ACCESS_TOKEN)
    access_token_secret = str(TWITTER_ACCESS_TOKEN_SECRET)

    #access_token = config('ACCESS_TOKEN')
    #access_token_secret = config('ACCESS_SECRET')

    #print("Access Token: ", access_token)
    #print("Access Token Secret: ", access_token_secret)

    twitter_auth.set_access_token(access_token, access_token_secret)
    global TWITTER
    TWITTER = tweepy.API(twitter_auth)

    #original_user = str(original_user)
    output_data = [message_id]

    # Call the Multithreaded function
    response_data, users_found = interaction_chain(original_user, first_search_depth, second_search_depth)
    print("Called Multitreading Function")
    output_data.append(users_found)
    output_data.append(response_data)

    print(response_data)
    print(users_found)
    #post_to_firestore(response_data, interactions_found, original_user)
    publish(output_data, 'listen_for_interactions')

def hello_pubsub(event, context):
    """Triggered from a message on a Cloud Pub/Sub topic.
    Args:
         event (dict): Event payload.
         context (google.cloud.functions.Context): Metadata for the event.
    """
    pubsub_message = base64.b64decode(event['data']).decode('utf-8')
    print(pubsub_message)
    parsed = ast.literal_eval(pubsub_message)

    print(parsed[0])
    job_id = parsed[3]

    to_search = []
    search_users = []
    print(type(parsed[0]))
    search_users.extend([x for x in parsed[0]])
    print(search_users)
    print(search_users[0])
    num_of_searches = int(parsed[4]/5)

    if (parsed[4]%5) > 0:
        num_of_searches = num_of_searches + 1

    print('num of searches: ', num_of_searches)
    for i in range(num_of_searches):

        index = ((i+1)*5)-5
        print(index)
        to_search.append(str(search_users[index]))

    depth = 50 // (num_of_searches * 5)

    if depth < 3:
        depth = 3

    to_publish = []
    to_publish.append(job_id)
    to_publish.append(parsed[4])
    publish(to_publish, 'post_to_db')

    print(to_search)
    generate_recommendation_response(to_search, parsed[1], parsed[2], job_id, depth)


import logging
from typing import Optional

import requests

import layers.messages
import models
from requests import HTTPError
from layers.senders.base import BaseSender
from settings import FB_PAGE_TOKEN

logger = logging.getLogger(__name__)

class MessengerSender(BaseSender):
    def send_message(
        self,
        message: layers.messages.SentMessage,
        markdown: bool = False,
        buttons: Optional[list] = None,
    ):
        recipient = str(message.user_id).replace(models.APP_MESSENGER + " ", "")
        reply_to_message_id = (
            message.reply_to.split(" ")[1]
            if isinstance(message.reply_to, str)
            else None
        )
        if buttons is not None:
            message_json = {
                "attachment": {
                    "type": "template",
                    "payload": {
                        "template_type": "button",
                        "text": message.text,
                        "buttons": [
                            {
                                "type": "postback",
                                "title": button.text,
                                "payload": button.command,
                            }
                            for button in buttons
                        ],
                    },
                }
            }
        else:
            message_json = {"text": message.text}

        post_data = {
            "recipient": {"id": recipient},
            "message": message_json,
        }

        res = None
        try:
            res = requests.post(
                "https://graph.facebook.com/v2.6/me/messages",
                params={"access_token": FB_PAGE_TOKEN},
                json=post_data,
            )
            res.raise_for_status()
        except HTTPError as e:
            if res is not None:
                logger.error(res.text)
            raise e

        return (
            layers.messages.SentMessage.generate_id(
                app=models.APP_MESSENGER, app_id=res.json()["message_id"]
            ),
            post_data,
        )


"""Helper functions to use within OpsDroid."""

import os
import stat
import shutil
import logging
import filecmp

import nbformat
from nbconvert import PythonExporter

_LOGGER = logging.getLogger(__name__)

# pylint: disable=inconsistent-return-statements
def get_opsdroid():
    """Return the running opsdroid instance.

    Returns:
        object: opsdroid instance.

    """
    from opsdroid.core import OpsDroid

    if len(OpsDroid.instances) == 1:
        return OpsDroid.instances[0]

def del_rw(action, name, exc):
    """Error handler for removing read only files.

    Args:
        action: the function that raised the exception
        name: path name passed to the function (path and file name)
        exc: exception information return by sys.exc_info()

    Raises:
        OsError : If the file to be removed is a directory.

    """
    os.chmod(name, stat.S_IWRITE)
    os.remove(name)

# This is meant to provide backwards compatibility for versions
# prior to  0.12.0 in the future this will probably be deleted

def move_config_to_appdir(src, dst):
    """Copy any .yaml extension in "src" to "dst" and remove from "src".

    Args:
        src (str): path file.
        dst (str): destination path.

    Logging:
        info (str): File 'my_file.yaml' copied from '/path/src/
                       to '/past/dst/' run opsdroid -e to edit
                       the  main config file.

    Examples:
        src : source path with .yaml file '/path/src/my_file.yaml.
        dst : destination folder to paste the .yaml files '/path/dst/.

    """
    yaml_files = [file for file in os.listdir(src) if ".yaml" in file[-5:]]

    if not os.path.isdir(dst):
        os.mkdir(dst)

    for file in yaml_files:
        original_file = os.path.join(src, file)
        copied_file = os.path.join(dst, file)
        shutil.copyfile(original_file, copied_file)
        _LOGGER.info(
            _(
                "File %s copied from %s to %s "
                "run opsdroid -e to edit the "
                "main config file"
            ),
            file,
            src,
            dst,
        )
        if filecmp.cmp(original_file, copied_file):
            os.remove(original_file)

def file_is_ipython_notebook(path):
    """Check whether a file is an iPython Notebook.

    Args:
        path (str): path to the file.

    Examples:
        path : source path with .ipynb file '/path/src/my_file.ipynb.

    """
    return path.lower().endswith(".ipynb")

def convert_ipynb_to_script(notebook_path, output_path):
    """Convert an iPython Notebook to a python script.

    Args:
        notebook_path (str): path to the notebook file.
        output_path (str): path to the script file destination.

    Examples:
        notebook_path : source path with .ipynb file '/path/src/my_file.ipynb.
        output_path : destination path with .py file '/path/src/my_file.py.

    """
    with open(notebook_path, "r") as notebook_path_handle:
        raw_notebook = notebook_path_handle.read()
        notebook = nbformat.reads(raw_notebook, as_version=4)
        script, _ = PythonExporter().from_notebook_node(notebook)
        with open(output_path, "w") as output_path_handle:
            output_path_handle.write(script)

def extract_gist_id(gist_string):
    """Extract the gist ID from a url.

    Will also work if simply passed an ID.

    Args:
        gist_string (str): Gist URL.

    Returns:
        string: The gist ID.

    Examples:
        gist_string : Gist url 'https://gist.github.com/{user}/{id}'.

    """
    return gist_string.split("/")[-1]

def add_skill_attributes(func):
    """Add the attributes which makes a function a skill.

    Args:
        func (func): Skill function.

    Returns:
        func: The skill function with the new attributes.

    """
    if not hasattr(func, "skill"):
        func.skill = True
    if not hasattr(func, "matchers"):
        func.matchers = []
    if not hasattr(func, "constraints"):
        func.constraints = []
    return func


from http.server import BaseHTTPRequestHandler
from metricsHttpCallback import MetricsHttpCallback
from metricsUdpCallback import MetricsUdpCallback

class TreadmillRequestHandler(BaseHTTPRequestHandler):

    def __init__(self, tm, metrics, healthController, *args):

        self.tm = tm
        self.metrics = metrics
        self.healthController = healthController

        self.get_routes = {
            '/incline/setpoint' : tm.incline_setpoint,
            '/incline/feedback' : tm.incline_setpoint,
            '/incline/expected' : tm.incline_expected,
            '/incline/min' : tm.incline_min,
            '/incline/max' : tm.incline_max,
            '/speed/setpoint' : tm.speed_setpoint,
            '/speed/feedback' : tm.speed_feedback,
            '/speed/expected' : tm.speed_expected,
            '/speed/min' : tm.speed_min,
            '/speed/max' : tm.speed_max,
            '/distance' : tm.distance,
            '/timestamp' : tm.timestamp,
            '/state' : tm.state,
        }

        self.post_routes = {
            '/callbacks/health' : healthController.add_listener,
            '/callbacks/metrics/http' : self.add_http_callback,
            '/callbacks/metrics/udp' : self.add_udp_callback,
            '/incline/setpoint' : tm.go_to_incline,
            '/speed/setpoint' : tm.go_to_speed,
            '/start' : tm.start_workout,
            '/pause' : tm.pause,
            '/resume' : tm.resume,
            '/end' : tm.end_workout,
        }

        self.route_takes_arg = {
            '/callbacks/health' : True,
            '/callbacks/metrics/http' : True,
            '/callbacks/metrics/udp' : True,
        }

        self.route_takes_float_arg = {
            '/incline/setpoint' : True,
            '/speed/setpoint' : True,
        }

        BaseHTTPRequestHandler.__init__(self, *args)

    def add_http_callback(self, url):
        callback = MetricsHttpCallback(url)
        self.metrics.add_remote_callback(callback)

    def add_udp_callback(self, addr):
        callback = MetricsUdpCallback(addr)
        self.metrics.add_remote_callback(callback)

    def takes_float_arg(self, route):
        return route in self.route_takes_float_arg and self.route_takes_float_arg[route]

    def takes_arg(self, route):
        return route in self.route_takes_arg and self.route_takes_arg[route]

    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        content = self.rfile.read(content_length)
        response = self.route_post(content)
        self.wfile.write(response)

    def do_GET(self):
        response = self.route_get()
        self.wfile.write(response)

    def route_post(self, data):

        if self.path not in self.post_routes:
            return self.not_found()

        try:
            if self.takes_float_arg(self.path):
                response = self.post_routes[self.path](float(data))
            elif self.takes_arg(self.path):
                response = self.post_routes[self.path](data)
            else:
                response = self.post_routes[self.path]()

        except ValueError as e:
            return self.bad_request(str(e))

        return self.ok(response)

    def route_get(self):
        if self.path not in self.get_routes:
            return self.not_found()

        return self.ok(self.get_routes[self.path])

    def not_found(self):
        self.send_response(404)
        return bytes('Not Found\n', 'utf-8')

    def bad_request(self, response):
        self.send_response(400)
        return bytes(f'{response}\n', 'utf-8')

    def ok(self, response):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

        if response is None:
            response = 'ok'

        return bytes(f'{response}\n', 'utf-8')


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('pulse', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='twitterTweet',
            fields=[
                ('id', models.AutoField(auto_created=True, serialize=False, primary_key=True, verbose_name='ID')),
                ('tweet_id', models.IntegerField(default=0)),
                ('text', models.CharField(max_length=256)),
                ('created_at', models.DateTimeField()),
            ],
        ),
        migrations.AddField(
            model_name='twitteruser',
            name='favorite_count',
            field=models.IntegerField(default=0),
        ),
        migrations.AddField(
            model_name='twitteruser',
            name='pulse',
            field=models.IntegerField(default=0),
        ),
        migrations.AddField(
            model_name='twitteruser',
            name='retweet_count',
            field=models.IntegerField(default=0),
        ),
        migrations.AddField(
            model_name='twittertweet',
            name='linked_user',
            field=models.ForeignKey(to='pulse.twitterUser'),
        ),
    ]


import uuid
import datetime
from src.common.database import Database

__author__ = 'rlv'

class Post(object):

    def __init__(self, blog_id, title, content, author, date=datetime.datetime.utcnow(), _id=None):
        self.blog_id = blog_id
        self.title = title
        self.content = content
        self.author = author
        self._id = uuid.uuid4().hex if _id is None else _id
        self.date =  datetime.datetime.utcnow() if date is None else date

        # for example: post = Post(blog_id="135", title="a title",
        # content = "some content", author="rlv")

    def json(self):
        return {
            '_id': self._id,
            'blog_id': self.blog_id,
            'title': self.title,
            'content': self.content,
            'author': self.author,
            'date': self.date
        }

    def save_to_mongo(self):
        Database.insert(collection='posts', data=self.json())

    @classmethod
    def from_mongo(cls, id):
        # Post.from_mongo("id")
        post_data = Database.find_one(collection='posts', query={'_id': id})

        return cls(**post_data)

    @classmethod
    def from_blog(cls, id):
        # Post.from_blog("blog_id")
        # returning list of the posts from specific blog
        posts_list = []
        for post in Database.find(collection='posts', query={'blog_id': id}):
            posts_list.append(cls(**post))
        return posts_list

    @staticmethod
    def delete_post(id):
        Database.delete_one(collection='posts', query={'_id': id})

    def __str__(self):
        return ("\n{title}, written by {author} on {date}.\n{content}\n".format(title=self.title,
                                                                              author=self.author,
                                                                              date=self.date,
                                                                              content=self.content))