import sys
import time
import subprocess
import signal
import pexpect
import re

from functools import partial
from os.path import exists

from pylib.Tracker import Tracker
from guilib.LHWorker import LHWorker
from guilib.TrackerWindow import TrackerWindow
from guilib.QToaster import QToaster
from pexpect import popen_spawn

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QPushButton, QLabel, QMenuBar, QMenu, QAction, QVBoxLayout,
    QHBoxLayout, QStackedLayout, QWidget, QTableWidget, QTableWidgetItem, QFrame
)

from guilib.MainWindowStyle import main_window_style

lighthouse_connected = False

class MainWindow(QMainWindow):
    def __init__(self, parent=None, appconfig=None):
        super().__init__()
        self.appConfig = appconfig
        self.startUI()

    def load_stylesheet(self):
        self.setStyleSheet(main_window_style)

    def startUI(self):
        self.lhworker = LHWorker(None, self.appConfig)
        self.lhworker.console_open.connect(self.update_connect_ui_on)
        self.lhworker.console_close.connect(self.update_connect_ui_off)
        self.lhworker.devinfo_ready.connect(self.update_devtable_ui)

        #if self.style_path != None:
            #with open(self.style_path, "r") as spfh:
                #self.setStyleSheet(spfh.read())

        self.load_stylesheet()
        self.setObjectName("MainWindow")
        self.setWindowTitle("Tundra Debugger")
        self.resize(800, 800)
        self.create_menu_bar()

        self.identify_buttons = []
        self.select_buttons = []
        self.connected_serial = None

        page_layout = QVBoxLayout()
        status_label_layout = QHBoxLayout()
        top_label_layout = QHBoxLayout()
        top_button_layout = QHBoxLayout()
        middle_table_layout = QHBoxLayout()
        stack_layout = QStackedLayout()

        page_layout.addLayout(top_label_layout)
        page_layout.addLayout(top_button_layout)
        page_layout.addLayout(status_label_layout)
        page_layout.addLayout(middle_table_layout)
        page_layout.addLayout(stack_layout)

        self.status_label = QLabel("Not Connected")
        self.status_label.setObjectName("StatusLabel")
        status_label_layout.addWidget(self.status_label)
        status_label_layout.setAlignment(Qt.AlignHCenter | Qt.AlignTop)

        top_label = QLabel("Tundra Tracker Debugging Tool")
        top_label.setObjectName("TitleLabel")
        top_label_layout.addWidget(top_label)
        top_label_layout.setAlignment(Qt.AlignHCenter | Qt.AlignTop)

        self.button = QPushButton("Scan For Devices")
        self.button.setCheckable(True)
        self.button.setFixedWidth(240)
        self.button.setFixedHeight(30)
        self.button.clicked.connect(self.scan_button_pressed)
        top_button_layout.addWidget(self.button)

        self.tableWidget = QTableWidget()
        self.tableWidget.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
        self.tableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
        self.tableWidget.setObjectName("DeviceTable")
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.horizontalHeader().setVisible(False)
        self.tableWidget.setColumnCount(3)
        #self.tableWidget.setColumnWidth(0, 150)
        #self.tableWidget.setColumnWidth(1, 220)
        #self.tableWidget.setColumnWidth(2, 230)
        self.tableWidget.setLineWidth(0)
        self.tableWidget.setFrameStyle(QFrame.Box | QFrame.Plain)
        self.tableWidget.setFixedWidth(800)
        self.tableWidget.setFixedHeight(400)
        middle_table_layout.addWidget(self.tableWidget, alignment=Qt.AlignCenter)

        self.widget = QWidget()
        self.widget.setLayout(page_layout)
        self.setCentralWidget(self.widget)

    def format_table_cell(self, content):
        result = QTableWidgetItem(content)
        result.setTextAlignment(Qt.AlignHCenter)
        return result

    def update_devtable_ui(self, devices):
        self.devices = devices
        numdevs = len(devices)

        self.tableWidget.setRowCount(numdevs)
        self.identify_buttons = []
        self.select_buttons = []
        rowct = 0
        for device in devices:
            cell0 = self.format_table_cell(device.serial)
            self.tableWidget.setItem(rowct, 0, cell0)
            cell1 = self.format_table_cell(device.devclass)
            self.tableWidget.setItem(rowct, 1, cell1)

            conbutton = QPushButton("Connect")
            conbutton.setObjectName(device.serial)
            conbutton.setCheckable(True)
            conbutton.clicked.connect(partial(self.connect_button_pressed, device.serial))
            self.identify_buttons.append(conbutton)
            self.tableWidget.setCellWidget(rowct, 2, conbutton)
            rowct = rowct + 1

        self.tableWidget.resizeColumnsToContents()

    def update_connect_ui_on(self):
        self.status_label.setText("Connected.")
        corner = QtCore.Qt.BottomRightCorner
        QToaster.showMessage(self, "Connected to lighthouse console service.", corner=corner, desktop=False)

    def update_connect_ui_off(self):
        self.status_label.setText("Not Connected.")

    def create_menu_bar(self):
        menu_bar = self.menuBar()
        newAct = QAction('&New', self)
        openAct = QAction('&Open', self)
        saveAct = QAction('&Save', self)
        exitAct = QAction('&Exit', self)
        exitAct.triggered.connect(self.exitAction)

        copyAct = QAction('&Copy', self)
        pasteAct = QAction('&Paste', self)
        helpContentAct = QAction('&Help', self)
        aboutAct = QAction('&About', self)

        file_menu = menu_bar.addMenu('&File')
        file_menu.addAction(newAct)
        file_menu.addAction(openAct)
        file_menu.addAction(saveAct)
        file_menu.addAction(exitAct)

        edit_menu = menu_bar.addMenu('&Edit')
        edit_menu.addAction(copyAct)
        edit_menu.addAction(pasteAct)

        help_menu = menu_bar.addMenu('&Help')
        help_menu.addAction(helpContentAct)
        help_menu.addSeparator()
        help_menu.addAction(aboutAct)

    def newAction(self):
        print("New Action selected")

    def openAction(self):
        print("Open Action selected")

    def saveAction(self):
        print("Save Action selected")

    def exitAction(self):
        print("Exit Action selected")
        self.lhworker.close_console()
        sys.exit(0)

    def copyAction(self):
        print("Copy Action selected")

    def pasteAction(self):
        print("Paste Action selected")

    def helpContentAction(self):
        print("Help Content Action selected")

    def aboutAction(self):
        print("New Action selected")

    def id_button_pressed(self, serial):
        self.lhworker.identify_device(serial)

    def connect_button_pressed(self, serial):
        sending_button = self.sender()
        self.lhworker.connect_device(serial)
        self.connected_serial = serial
        self.device_window = TrackerWindow(self, serial, self.lhworker, self.appConfig)
        self.device_window.show()
        sending_button.setDefault(True)
        self.device_window.serial = serial;

    def scan_button_pressed(self):
        self.lhworker.start()
        #self.lhworker.get_devinfo()


r'''Save and restore replicated and sharded variables.
'''

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import uuid

from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import data_flow_ops
from tensorflow.python.ops import gen_io_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import string_ops
from tensorflow.python.platform import tf_logging as logging
from tensorflow.python.training import checkpoint_management
from tensorflow.python.training import checkpoint_utils
from tensorflow.python.training import saver
from tensorflow.python.util import nest

try:
  from tensorflow.python.training.saving.saveable_object_util import \
    op_list_to_dict
except ImportError:
  op_list_to_dict = saver.BaseSaverBuilder.OpListToDict

from hybridbackend.tensorflow.framework.context import Context
from hybridbackend.tensorflow.framework.ops import GraphKeys
from hybridbackend.tensorflow.framework.ops import ModeKeys
from hybridbackend.tensorflow.framework.rewriting import GraphRewriting
from hybridbackend.tensorflow.framework.rewriting import SessionRunRewriting

class HybridBackendSaverBuilderBase(object):  # pylint: disable=useless-object-inheritance
  r'''Base class of sharded saver builders.
  '''

def wraps_saver_builder(cls):
  r'''Wraps a saver builder to support hybrid parallelism.
  '''
  if issubclass(cls, HybridBackendSaverBuilderBase):
    return cls

  class HybridBackendSaverBuilder(cls, HybridBackendSaverBuilderBase):
    r'''Wrapped SaverBuilder with support for hybrid parallelism.
    '''
    def __init__(self, *args, **kwargs):
      name = kwargs.pop('name', 'hybrid_backend_saver_builder')
      self._restoreable_saveables = None
      self._rank = Context.get().rank
      self._world_size = Context.get().world_size
      super().__init__(*args, **kwargs)
      with ops.device(Context.get().devices[0]):
        with ops.device('/cpu:0'):
          self._local_barrier = data_flow_ops.Barrier(
            [dtypes.bool],
            shared_name=f'{name}_local_barrier')
          self._global_barrier = data_flow_ops.Barrier(
            [dtypes.bool],
            shared_name=f'{name}_global_barrier')

    @property
    def rank(self):
      return self._rank

    @property
    def world_size(self):
      return self._world_size

    def _AddShardedSaveOpsForV2(self, checkpoint_prefix, per_device):
      r'''Add ops to save the params in parallel, for the V2 format.

      Args:
        checkpoint_prefix: scalar String Tensor.  Interpreted *NOT AS A
          FILENAME*, but as a prefix of a V2 checkpoint;
        per_device: A list of (device, BaseSaverBuilder.VarToSave) pairs, as
          returned by _GroupByDevices().

      Returns:
        An op to save the variables, which, when evaluated, returns the prefix
          "<user-fed prefix>" only and does not include the sharded spec suffix.
      '''
      if self._world_size <= 1:
        return super()._AddShardedSaveOpsForV2(checkpoint_prefix, per_device)

      # Filter sharded saveables.
      sharded_saveables = []
      if self._rank != 0:
        sharded_saveables += ops.get_collection_ref(
          GraphKeys.SHARDED_VARIABLES)
        sharded_saveables += ops.get_collection_ref(
          GraphKeys.SHARDED_RESOURCES)
        sharded_saveables = [v for v in sharded_saveables if v is not None]
        sharded_saveables = op_list_to_dict(sharded_saveables).values()
        sharded_saveables = nest.flatten(sharded_saveables)

      # Save local partitions.
      checkpoint_uuid = uuid.uuid4()
      checkpoint_prefix_suffix = f'_temp_{checkpoint_uuid.hex}/part'
      tmp_checkpoint_prefix = string_ops.string_join(
        [checkpoint_prefix, checkpoint_prefix_suffix])

      num_shards = len(per_device)
      num_shards_tensor = constant_op.constant(num_shards)
      local_done = constant_op.constant([True], dtype=dtypes.bool)
      global_done = constant_op.constant(
        [True for _ in range(self._world_size - 1)], dtype=dtypes.bool)
      save_ops = []
      filenames = []
      last_device = None
      empty_filename = ''

      for shard, (device, saveables) in enumerate(per_device):
        # Only sharded saveables need to save for non-chief workers
        if self._rank != 0:
          saveables = [
            s for s in saveables
            if s.op in sharded_saveables or s in sharded_saveables]
        logging.vlog(
          1,
          f'Saving {len(saveables)} saveables for shard {shard} at process '
          f'{self._rank}: {[s.name for s in saveables]}')
        last_device = device
        with ops.device(device):
          with ops.device('/cpu:0'):
            filename = empty_filename
            if saveables:
              filename = self.sharded_filename(
                tmp_checkpoint_prefix, shard, num_shards_tensor)
              save_ops.append(self._AddSaveOps(filename, saveables))
            filenames.append(filename)

      with ops.control_dependencies([x.op for x in save_ops]):
        with ops.device(last_device):
          with ops.device('/cpu:0'):
            notify_local_done = [
              self._local_barrier.insert_many(0, keys=[f], values=local_done)
              for f in filenames]
            _, ready_filenames, _ = self._local_barrier.take_many(
              self._world_size * len(filenames))
            notify_global_done = self._global_barrier.insert_many(
              0,
              keys=[str(i) for i in range(self._world_size - 1)],
              values=global_done)
            _, ready_ranks, _ = self._global_barrier.take_many(1)

            if self._rank == 0:
              ready_filenames_mask = math_ops.logical_not(
                string_ops.regex_full_match(ready_filenames, empty_filename))
              ready_filenames = array_ops.boolean_mask(
                ready_filenames, ready_filenames_mask)
              with ops.control_dependencies(notify_local_done):
                with ops.control_dependencies([ready_filenames]):
                  merge_files = gen_io_ops.merge_v2_checkpoints(
                    ready_filenames, checkpoint_prefix, delete_old_dirs=True)
                with ops.control_dependencies([merge_files]):
                  with ops.control_dependencies([notify_global_done]):
                    return array_ops.identity(checkpoint_prefix)
            with ops.control_dependencies(notify_local_done):
              with ops.control_dependencies([ready_ranks]):
                return array_ops.identity(checkpoint_prefix)

    def _AddShardedRestoreOps(
        self, filename_tensor, per_device, restore_sequentially, reshape):
      r'''Add Ops to restore variables from multiple devices.

      Args:
        filename_tensor: Tensor for the path of the file to load.
        per_device: A list of (device, SaveableObject) pairs, as returned by
          _GroupByDevices().
        restore_sequentially: True if we want to restore variables sequentially
          within a shard.
        reshape: True if we want to reshape loaded tensors to the shape of the
          corresponding variable.

      Returns:
        An Operation that restores the variables.
      '''
      model_dir = Context.get().options.model_dir
      if model_dir is not None:
        latest_path = checkpoint_management.latest_checkpoint(model_dir)  # pylint: disable=protected-access
        if latest_path:
          self._restoreable_saveables, _ = zip(
            *checkpoint_utils.list_variables(model_dir))
      return super()._AddShardedRestoreOps(
        filename_tensor, per_device, restore_sequentially, reshape)

    def restore_op(self, filename_tensor, saveable, preferred_shard):
      r'''Create ops to restore 'saveable'.
      '''
      if (self._restoreable_saveables is not None
          and saveable.name not in self._restoreable_saveables
          and hasattr(saveable, 'initializer')):
        return saveable.initializer.outputs
      return super().restore_op(filename_tensor, saveable, preferred_shard)

  return HybridBackendSaverBuilder

SaverBuilder = wraps_saver_builder(saver.BulkSaverBuilder)

class HybridBackendSaverBase(object):  # pylint: disable=useless-object-inheritance
  r'''Base class of sharded savers.
  '''

def wraps_saver(cls):
  r'''Wraps a saver to support hybrid parallelism.
  '''
  if issubclass(cls, HybridBackendSaverBase):
    return cls

  class HybridBackendSaver(cls, HybridBackendSaverBase):
    r'''SaverBuilder with support for hybrid parallelism.
    '''
    def __init__(self, *args, **kwargs):
      self._rank = Context.get().rank
      self._world_size = Context.get().world_size
      kwargs['sharded'] = True
      kwargs['allow_empty'] = True
      with ops.device('/cpu:0'):
        super().__init__(*args, **kwargs)

    @property
    def rank(self):
      return self._rank

    @property
    def world_size(self):
      return self._world_size

    def _build(self, *args, **kwargs):
      r'''Builds saver_def.
      '''
      if self._world_size <= 1:
        super()._build(*args, **kwargs)
        return

      if self._builder is None:
        orig_saver_builder = saver.BulkSaverBuilder
        saver.BulkSaverBuilder = wraps_saver_builder(saver.BulkSaverBuilder)
        super()._build(*args, **kwargs)
        saver.BulkSaverBuilder = orig_saver_builder
      else:
        if not isinstance(self._builder, HybridBackendSaverBuilderBase):
          raise ValueError(
            '`SaverBuilder` must decorated by `wraps_saver_builder`')
        super()._build(*args, **kwargs)

    def save(self, *args, **kwargs):
      r'''Saves sharded variables.
      '''
      if self._world_size <= 1:
        super().save(*args, **kwargs)
        return

      write_meta_graph = (
        kwargs.pop('write_meta_graph', True)
        and self._rank == 0)
      kwargs['write_meta_graph'] = write_meta_graph
      write_state = kwargs.pop('write_state', True) and self._rank == 0
      kwargs['write_state'] = write_state
      super().save(*args, **kwargs)

    def export_meta_graph(self, filename=None, **kwargs):
      if self._rank == 0:
        return super().export_meta_graph(filename=filename, **kwargs)
      return None

  return HybridBackendSaver

Saver = wraps_saver(saver.Saver)

def replace_default_saver():
  r'''Try to replace default saver to HybridBackendSaver.
  '''
  rank = Context.get().rank
  savers = ops.get_collection_ref(ops.GraphKeys.SAVERS)

  if not savers:
    default_saver = Saver()
    ops.add_to_collection(ops.GraphKeys.SAVERS, default_saver)
    return
  if len(savers) > 1:
    raise ValueError(f'Multiple items found in collection SAVERS: {savers}')

  default_saver = savers[0]
  if isinstance(default_saver, HybridBackendSaverBase):
    return

  if not default_saver._sharded:  # pylint: disable=protected-access
    raise ValueError('Default saver must be sharded')
  if default_saver._builder is not None:  # pylint: disable=protected-access
    if not isinstance(default_saver._builder, HybridBackendSaverBuilderBase):  # pylint: disable=protected-access
      raise ValueError(
        'builder for default saver must decorated by `wraps_saver_builder`')
  else:
    def _wraps_build(build_fn):
      r'''Decorator to wrap saver build.
      '''
      def wrapped_build(self, *args, **kwargs):
        r'''Builds saver_def.
        '''
        orig_saver_builder = saver.BulkSaverBuilder
        saver.BulkSaverBuilder = wraps_saver_builder(saver.BulkSaverBuilder)
        build_fn(self, *args, **kwargs)
        saver.BulkSaverBuilder = orig_saver_builder
      return wrapped_build
    default_saver._build = _wraps_build(default_saver._build)  # pylint: disable=protected-access

  def _wraps_save(save_fn):
    def wrapped_save(self, *args, **kwargs):
      r'''Saves sharded variables.
      '''
      write_meta_graph = kwargs.pop('write_meta_graph', True) and rank == 0
      kwargs['write_meta_graph'] = write_meta_graph
      write_state = kwargs.pop('write_state', True) and rank == 0
      kwargs['write_state'] = write_state
      save_fn(self, *args, **kwargs)
    return wrapped_save
  default_saver.save = _wraps_save(default_saver.save)

class SaverRewriting(GraphRewriting):
  r'''Rewriting savers.
  '''
  def __init__(self):
    super().__init__()
    self._prev_add_weight = None
    self._prev_collect_pvar = None

  def wraps_saver_init(self, fn):
    r'''Wraps saver init function.
    '''
    def wrapped_saver_init(cls, *args, **kwargs):
      keep_checkpoint_max = Context.get().options.keep_checkpoint_max
      keep_checkpoint_every_n_hours = \
        Context.get().options.keep_checkpoint_every_n_hours
      if keep_checkpoint_max is not None:
        kwargs['max_to_keep'] = keep_checkpoint_max
      if keep_checkpoint_every_n_hours is not None:
        kwargs['keep_checkpoint_every_n_hours'] = \
          keep_checkpoint_every_n_hours
      kwargs['save_relative_paths'] = True
      fn(cls, *args, **kwargs)
    return wrapped_saver_init

  def begin(self):
    r'''Rewrites API.
    '''
    self._prev_saver_init = saver.Saver.__init__
    saver.Saver.__init__ = self.wraps_saver_init(self._prev_saver_init)

  def end(self):
    r'''Revert API rewriting.
    '''
    saver.Saver.__init__ = self._prev_saver_init

GraphRewriting.register(SaverRewriting)

class DefaultSaverRewriting(SessionRunRewriting):
  r'''A SessionRunHook replaces default saver.
  '''
  def begin(self):
    r''' initialize replica variables and enable synchronous dataset wrapper
    '''
    replace_default_saver()

SessionRunRewriting.register(
  DefaultSaverRewriting, [ModeKeys.TRAIN])


import pandas as pd
import requests
from scipy.stats import pearsonr
import json

# load collision data from local file
data = []
with open('collision_data.json', 'r') as f:
    for line in f:
        try:
            data.append(json.loads(line))
        except json.JSONDecodeError:
            continue
collision_data = pd.DataFrame(data)

# extract street name from on_street_name, off_street_name, and cross_street_name columns
collision_data['street_name'] = collision_data['on_street_name'].fillna('') + ' & ' + collision_data['off_street_name'].fillna('') + ' & ' + collision_data['cross_street_name'].fillna('')
collision_data['street_name'] = collision_data['street_name'].str.replace(' &  & ', ' & ').str.strip('& ')

# validate that the street_name column is present in the collision data
if 'street_name' not in collision_data.columns:
    missing_columns = {'street_name'}
    raise ValueError(f"Missing required columns in collision data: {missing_columns}")

# filter and group collision data by street name
collision_data = collision_data[['street_name', 'borough']].groupby('street_name').count().reset_index()
collision_data.rename(columns={'borough': 'collision_count'}, inplace=True)

# API request to load traffic volume data
url = "https://data.cityofnewyork.us/resource/7ym2-wayt.json"
params = {'$select': 'street_name, SUM(aadt)', '$group': 'street_name', '$order': 'street_name ASC'}
response = requests.get(url, params=params)

# Check if the request was successful
if response.status_code != 200:
    raise Exception(f"Request failed with status code {response.status_code}")

try:
    traffic_data = pd.read_json(response.content.decode('utf-8'))
except ValueError:
    # If there's an error reading the JSON, try to decode it as UTF-16
    traffic_data = pd.read_json(response.content.decode('utf-16'))

# merge collision and traffic volume data
merged_data = pd.merge(collision_data, traffic_data, on='street_name', how='inner')

# calculate Pearson correlation coefficient and p-value
corr, p_value = pearsonr(merged_data['sum_aadt'], merged_data['collision_count'])

# print the results
print("Pearson correlation coefficient:", corr)
print("p-value:", p_value)


import time
import arcade

SCREEN_WIDTH = 600
SCREEN_HEIGHT = 600
OPENING_SCREEN_DURATION = 0.5
OPENING_SCREEN_IMAGE = "images/background.jpg"

class OpeningScreen(arcade.View):
    def __init__(self):
        super().__init__()
        self.opening_time = None

    def on_show(self):
        self.opening_time = time.monotonic()

    def on_draw(self):
        arcade.start_render()
        arcade.draw_texture_rectangle(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_WIDTH, SCREEN_HEIGHT,
                                      arcade.load_texture(OPENING_SCREEN_IMAGE))

    def on_update(self, delta_time):
        if time.monotonic() - self.opening_time >= OPENING_SCREEN_DURATION:
            from Learn_With_Mazes.Learn_With_Mazes_Django.src.screens.MainMenu import MainMenu
            main_menu = MainMenu()
            self.window.show_view(main_menu)


import json
import sys
import subprocess
import re

class ModuleProxy():
  """
  This class provides a simple sandbox that allows code from arbitrary Python
  modules to be evaluated in a subprocess. Said code cannot access the state
  of the calling process, though it has the same user privileges as the caller.
  """
  def __init__(self, module_name):
    self.module_name = module_name

  def __getattr__(self, symbol_name):
    return ObjectProxy(self, symbol_name)

  def _get(self, symbol_name, call=False, *args):
    if call:
      script_tmpl = "import {}; print(repr({}.{}(*{})))"
      script = script_tmpl.format(
        self.module_name,
        self.module_name,
        symbol_name,
        repr(args)
      )
    else:
      script_tmpl = "import {}; print(repr({}.{}))"
      script = script_tmpl.format(self.module_name, self.module_name, symbol_name)

    raw_output = subprocess.check_output([sys.executable, '-c', script])
    # the Python JSON module won't parse string literals enclosed by single-quote
    # characters, so...
    output = re.sub(r"'", '"', raw_output.decode("utf-8").rstrip())
    # allows for simple scalar types and lists to be returned by evaluated code
    # without breaking sandbox
    return json.loads(output)

class ObjectProxy():
  def __init__(self, mod_proxy, symbol_name):
    self.mod_proxy = mod_proxy
    self.symbol_name = symbol_name

  def __call__(self, *args):
    return self.mod_proxy._get(self.symbol_name, True, *args)

  def __repr__(self):
    return repr(self.value())

  def value(self):
    return self.mod_proxy._get(self.symbol_name)

if __name__ == "__main__":
  # simple tests of this module
  fake_sys = ModuleProxy('sys')
  assert isinstance(fake_sys.executable.value(), str)
  fake_math = ModuleProxy('math')
  assert fake_math.floor(3.5) is 3
  print("tests ok")


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

from mxnet.gluon import data as gdata
import d2l

class FashionMnistDataLoader:
    def __init__(self, batch_size):
        self.mnist_train = gdata.vision.FashionMNIST(train=True)
        self.mnist_test = gdata.vision.FashionMNIST(train=False)

        print(f'len mnist_train : {len(self.mnist_train)}')
        print(f'len mnist_test : {len(self.mnist_test)}')

        features, label = self.mnist_train[0]
        print(f'check features data shape: {features.shape}, dtype: {features.dtype}')
        print(f'check label data: {label}, type: {type(label)}, dtype: {label.dtype}')

        self.train_iter, self.test_iter = d2l.load_data_fashion_mnist(batch_size)

    # This function has been saved in the d2l package for future use
    def get_fashion_mnist_labels(self, labels):
        text_labels = [
            't-shirt', 'trouser', 'pullover', 'dress', 'coat',
            'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot'
        ]
        return [text_labels[int(i)] for i in labels]

    # This function has been saved in the d2l package for future use
    def show_fashion_mnist(self, images, labels):
        d2l.use_svg_display()
        # Here _ means that we ignore (not use) variables
        _, figs = d2l.plt.subplots(1, len(images), figsize=(12, 12))

        for f, img, lbl in zip(figs, images, labels):
            f.imshow(img.reshape((28, 28)).asnumpy())
            f.set_title(lbl)
            f.axes.get_xaxis().set_visible(False)
            f.axes.get_yaxis().set_visible(False)


#!/usr/bin/python

# Requires kernel module bcm2835_gpiomem and udev rule /etc/udev/rules.d/20-gpio.rules
#SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="gpio", MODE="0660"
#SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
#SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:gpio /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"
#further information: https://sourceforge.net/p/raspberry-gpio-python/tickets/115/ and http://wiringpi.com/wiringpi-update-to-2-29/
from __future__ import division
from __future__ import with_statement
import RPi.GPIO as GPIO
import time
from datetime import datetime
import os, sys
import threading

import logging
logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', filename='/tmp/motionInterrupt.log', level=logging.DEBUG)

###Configuration
LCD_POWER_PIN=8
MOTION_PIN=11
LCD_POWER_DETECT_PIN = 24
TIME_UNTIL_TURN_OFF_MIN= 15 # time of no detected motion until the screen is turned off
CHECK_FOR_TURN_OFF_SEC = 30 # sleep time between test for turning off the display

###Global variables

#LCD state
lcd_on = True
#Lock to synchronize switching
lock_switch = threading.Lock()

###Functions

def init():
    global lcd_on
    global last_motion_time

    lcd_on = True

    # SoC als Pinreferenz waehlen
    GPIO.setmode(GPIO.BCM)

    GPIO.setwarnings(False)

    # Pin 24 vom SoC als Input deklarieren und Pull-Down Widerstand aktivieren
    GPIO.setup(MOTION_PIN, GPIO.IN)

    GPIO.setup(LCD_POWER_PIN, GPIO.OUT, initial=GPIO.HIGH)

    GPIO.setup(LCD_POWER_DETECT_PIN, GPIO.IN)

    last_motion_time = datetime.now()

    # Interrupt Event hinzufuegen. Pin 24, auf steigende Flanke reagieren und ISR "Interrupt" deklarieren
    GPIO.add_event_detect(MOTION_PIN, GPIO.FALLING, callback = motion_interrupt, bouncetime = 200)

    logging.info('Configuration: Turning off after %s min, checking time difference each %s s', TIME_UNTIL_TURN_OFF_MIN, CHECK_FOR_TURN_OFF_SEC)

    logging.info('Finished init()')

# ISR
def motion_interrupt(channel):
    # Access global variables
    global last_motion_time
    global lcd_on

    last_motion_time = datetime.now()

    logging.debug("Motion detected")
    #XXX may wait until we received several measures (filtering)

    if not lcd_on:
        logging.info("LCD is turned on again")
        switch_to_lcd_state(1)
        lcd_on = True

def get_lcd_state():
    # returns 0 if display is off (LED=off) and 1 if display is on (LED=on)
    return GPIO.input(LCD_POWER_DETECT_PIN)

def switch_to_lcd_state(target_state):
    """
    Switch the lcd to the given target state
    Keep trying until target state is achieved
    :param target_state: target state of the lcd 0=off 1=on
    """
    global lock_switch
    with lock_switch:
        while get_lcd_state() != target_state:
            press_lcd_power_key()
            time.sleep(1)

# Press Power key of LCD display
def press_lcd_power_key():
    GPIO.output(LCD_POWER_PIN, GPIO.LOW)
    time.sleep(0.1)
    GPIO.output(LCD_POWER_PIN, GPIO.HIGH)
    #print("power button pressed")

def check_idle_time_turn_off():
    global lcd_on
    now = datetime.now()
    diff_min = (now - last_motion_time).total_seconds() / 60

    logging.debug("Current time diff: %s", diff_min)

    if diff_min >= TIME_UNTIL_TURN_OFF_MIN and lcd_on == True:
        logging.info("Idle time exeeded, LCD is turned off")
        switch_to_lcd_state(0)
        lcd_on = False

def main_loop():
    init()
    # endless loop
    while True:
        time.sleep(CHECK_FOR_TURN_OFF_SEC)
        check_idle_time_turn_off()

###Main programm
if __name__ == '__main__':
    #alternative without process
    #main_loop()

    # start check in an own process
    print("Starting subprocess")
    fpid = os.fork()
    if fpid==0:
      # Running as daemon now. PID is fpid
      logging.debug("Daemon process started")
      main_loop()
    else:
        exit() #exit first start process


import os
import json
import torch
import logging
import re
import random
import nltk.data

# the telegram package holds everything we need for this tutorial
import telegram
from telegram.ext import Updater
from telegram.ext import CommandHandler
from telegram.ext import MessageHandler, Filters

from src.transformer import Transformer
from dataset import DialogueDataset, Vocab
from src.transformer import Chatbot

def clean_response(response):
    substitutions = [(r' </s>', r''),
                     (r' \.', '.'),
                     (r' !', r'!'),
                     (r' \?', r'?'),
                     (r' ,', r'?'),
                     (r' i ', r' I ')]
                     #('[.|!|?] *[a-z]', )]

    for (pattern, replacement) in substitutions:
        response = re.sub(pattern, replacement, response)

    sent_tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
    sentences = sent_tokenizer.tokenize(response)
    sentences = [sent.capitalize() for sent in sentences]
    response = ' '.join(sentences)
    return response

class TelegramBot:
    def __init__(self, token):
        """This chatbot takes a Telegram authorization toke and a handler function,
        and deploys a Telegram chatbot to respond to user messages with that token.

        token - a string authorization token provided by @BotFather on Telegram
        handle_func - a function taking update, context parameters which responds to user inputs
        """
        self.token = token
        self.bot = telegram.Bot(token=token)
        self.updater = Updater(token=token)
        self.dispatcher = self.updater.dispatcher
        self.updater.start_polling()

    def stop(self):
        """Stop the Telegram bot"""
        self.updater.stop()

    def add_handler(self, handler):
        """Add a handler function to extend bot functionality"""
        self.dispatcher.add_handler(handler)

class ChatBot:
    def __init__(self, args):
        # get the dir with pre-trained model

        load_dir = os.path.join(args.experiment_dir, args.old_model_dir)

        # initialize, and load vocab
        self.vocab = Vocab()
        vocab_filename = os.path.join(load_dir, "vocab.json")
        self.vocab.load_from_dict(vocab_filename)

        # load configuration
        with open(os.path.join(load_dir, "config.json"), "r") as f:
            config = json.load(f)

        args.response_len = config["response_len"]
        args.history_len = config["history_len"]

        # initialize an empty dataset. used to get input features
        self.dataset = DialogueDataset(None,
                                       history_len=config["history_len"],
                                       response_len=config["response_len"],
                                       vocab=self.vocab,
                                       update_vocab=False)

        # set device
        self.device = torch.device(args.device)

        # initialize model
        model = Transformer(
            config["vocab_size"],
            config["vocab_size"],
            config["history_len"],
            config["response_len"],
            d_word_vec=config["embedding_dim"],
            d_model=config["model_dim"],
            d_inner=config["inner_dim"],
            n_layers=config["num_layers"],
            n_head=config["num_heads"],
            d_k=config["dim_k"],
            d_v=config["dim_v"],
            dropout=config["dropout"],
            pretrained_embeddings=None
        ).to(self.device)

        # load checkpoint
        checkpoint = torch.load(os.path.join(load_dir, args.old_model_name),
                                map_location=self.device)
        model.load_state_dict(checkpoint['model'])

        # create chatbot
        self.chatbot = Chatbot(args, model)

        self.args = args

    def run(self):
        logging.basicConfig(
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            level=logging.INFO)

        greeting_text = "Hello! I am the Hawkbot! Let me tell you about myself" \
            "... please dont hurt my feelings!" \
                        "  If you would like to reset "\
                        "the conversation, please type '/reset'. "

        # initialize history dictionary for each chat id
        history = dict()

        def greeting(bot, update):
            # reset history, or create new history for chat id
            if update.message.chat_id in history:
                id = "{}_history".format(update.message.chat_id)
                if id in history:
                    history[id].append(history[update.message.chat_id])
                else:
                    history[id] = [history[update.message.chat_id]]
                history[update.message.chat_id].clear()
            else:
                history[update.message.chat_id] = list()

            # send a message
            bot.send_message(update.message.chat_id, greeting_text)

        def respond(bot, update):
            # initialize history for chat if it doesnt exist
            if update.message.chat_id not in history:
                greeting(bot, update)
            else:
                # get message, and add to history
                message = update.message.text
                history[update.message.chat_id].append(message)
                # get response, and add to history
                response = self._print_response(history[update.message.chat_id])
                history[update.message.chat_id].append(response)
                # send response from user
                bot.send_message(update.message.chat_id, clean_response(response))

                with open(self.args.save_filename, 'w') as f:
                    json.dump({"history": history, "args": vars(self.args)},
                              f, indent=4)

        # queries sent to: https://api.telegram.org/bot<token>/METHOD_NAME
        TOKEN = self.args.token

        bot = TelegramBot(TOKEN)
        bot.add_handler(MessageHandler(Filters.text, respond))
        bot.add_handler(CommandHandler('reset', greeting))

    # print the response from the input
    def _print_response(self, history):

        # generate responses
        responses, scores = self._generate_responses(history)
        # chose response
        if self.args.choose_best:
            response = responses[0][0]
        else:
            # pick a random result from the n_best
            idx = random.randint(0, min(self.args.n_best,
                                        self.args.beam_size) - 1)
            response = responses[0][idx]

        # uncomment this line to see all the scores
        # print("scores in log prob: {}\n".format(scores[0]))

        # create output string
        output = ""
        for idx in response[:-1]:
            token = self.vocab.id2token[idx]
            output += "{} ".format(token)
        print(f'{history[-1]} -> {output}')
        return output

    def _generate_responses(self, history):
        # get input features for the dialogue history
        h_seq, h_pos, h_seg = self.dataset.get_input_features(history)

        # get response from model
        response = self.chatbot.translate_batch(h_seq, h_pos, h_seg)
        return response


# Code to measure mean fluorescence intensity (instead of spot count) from each ROI.
# The integrated intensity = mean intensity * size of ROI

import os, sys, zarr
import numpy as np
import pandas as pd
from glob import glob
from skimage.measure import regionprops
from skimage.io import imread, imsave

def measure_intensity(lb, img_dir, channel, scale='s2'):
	"""
    Returns spot counts for each ROI.

    lb: segmenntation mask
    img_dir: n5 image file to measure fluorescence intensity
	channel: image channnel, e.g. c0, c1
	scale: image channel, e.g. s0, s1. Default to 's2', 4x4x2 downsampled
    """
	lb_id = np.unique(lb[lb!= 0])
	roi=len(lb_id)
	if type(img_dir)==str:
		# get n5 image data
		im = zarr.open(store=zarr.N5Store(img_dir), mode='r')
		img = im[channel+'/'+scale][:,:,:]
		if channel == 'c3': #default c3 to the channel where bleed-through correction is needed, modify if it does not apply.
			dapi=im['c2/'+scale][...] #default c2 to DAPI channel, change if dapi is in a different channel
			lo=np.percentile(np.ndarray.flatten(dapi),99.5)
			bg_dapi=np.percentile(np.ndarray.flatten(dapi[dapi!=0]),1)
			bg_img=np.percentile(np.ndarray.flatten(img[img!=0]),1)
			dapi_factor=np.median((img[dapi>lo] - bg_img)/(dapi[dapi>lo] - bg_dapi))
			img = np.maximum(0, img - bg_img - dapi_factor * (dapi - bg_dapi)).astype('float32')
			print('bleed_through:',dapi_factor)
			print('DAPI background:',bg_dapi)
			print('c3 background:',bg_img)
		df_mean = pd.DataFrame(data=np.empty([roi,1]), columns=['roi'], dtype=object)
		lb_stat = regionprops(lb,intensity_image=img)
		for i in range(0,roi):
			df_mean.loc[i, 'roi'] = lb_stat[i].label
			df_mean.loc[i, channel] = lb_stat[i].mean_intensity
	else:
		print('Image file is in wrong format')

	return(df_mean)


# -*- coding: utf-8 -*-
"""
Created on 2018/1/3 19:57

@author: JERRY
"""

import hashlib
import zlib
import json
from time import sleep
from threading import Thread
import ssl
import websocket
from datapool.general_config import bitmex_ws

basehost = bitmex_ws

########################################################################
class BitmexApi(object):
    """基于Websocket的API对象"""

    # ----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        self.apiKey = ''  # 用户名
        self.secretKey = ''  # 密码
        self.host = ''  # 服务器地址
        self.currency = ''  # 货币类型（usd或者cny）
        self.ws = None  # websocket应用对象
        self.thread = None  # 工作线程
        global x

    #######################
    ## 通用函数
    #######################

    # ----------------------------------------------------------------------
    def readData(self, evt):
        """解压缩推送收到的数据"""
        # 创建解压器
        decompress = zlib.decompressobj(-zlib.MAX_WBITS)

        # 将原始数据解压成字符串
        inflated = decompress.decompress(evt) + decompress.flush()

        # 通过json解析字符串
        data = json.loads(inflated)

        return data

    # ----------------------------------------------------------------------
    def generateSign(self, params):
        """生成签名"""
        l = []
        for key in sorted(params.keys()):
            l.append('%s=%s' % (key, params[key]))
        l.append('secret_key=%s' % self.secretKey)
        sign = '&'.join(l)
        return hashlib.md5(sign.encode('utf-8')).hexdigest().upper()

    # ----------------------------------------------------------------------
    def onMessage(self, ws, evt):
        """信息推送"""
        print('onMessage')
        data = json.loads(evt)

        print(data)

    # ----------------------------------------------------------------------
    def onError(self, ws, evt):
        """错误推送"""
        print('onError')
        print(evt)

    # ----------------------------------------------------------------------
    def onClose(self, ws):
        """接口断开"""
        print('onClose')

    # ----------------------------------------------------------------------
    def onOpen(self, ws):
        """接口打开"""
        print('onOpen')

    # ----------------------------------------------------------------------
    def connect(self, trace=False):
        """连接服务器"""
        self.host = 'wss://www.bitmex.com/realtime'
        websocket.enableTrace(trace)
        self.ws = websocket.WebSocketApp(url = self.host,
                                         on_message=self.onMessage,
                                         on_error=self.onError,
                                         on_close=self.onClose,
                                         on_open=self.onOpen)

        self.thread = Thread(target=self.ws.run_forever)
        self.thread.start()

    # ----------------------------------------------------------------------
    def reconnect(self):
        """重新连接"""
        # 首先关闭之前的连接
        self.close()

        # 再执行重连任务
        self.ws = websocket.WebSocketApp(self.host,
                                         on_message=self.onMessage,
                                         on_error=self.onError,
                                         on_close=self.onClose,
                                         on_open=self.onOpen)

        self.thread = Thread(target=self.ws.run_forever(sslopt={"cert_reqs": False}))
        self.thread.start()

    # ----------------------------------------------------------------------
    def close(self):
        """关闭接口"""
        if self.thread and self.thread.isAlive:
            self.ws.close()
            self.thread.join()

    # ----------------------------------------------------------------------
    def sendMarketDataRequest(self, arglist):
        """发送行情请求"""
        # 生成请求
        d = {}
        d['op'] = 'subscribe'
        d['args'] = arglist

        # 使用json打包并发送
        j = json.dumps(d)

        # 若触发异常则重连
        try:
            self.ws.send(j)
        except websocket.WebSocketConnectionClosedException:
            pass