#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
'''
The code is base on official documentation at:
    https://help.aliyun.com/document_detail/92131.html
    一句话识别RESTful API2.0
'''
# Python 2.x 引入httplib模块
# import httplib
# Python 3.x 引入http.client模块
import http.client
import json
import sys
import codecs
import time

FORMAT = 'wav'
SAMPLE_RATE = 16000

MAX_RETRY=10
RETRY_INTERVAL=1.0

PUNC = False
ITN = False
VAD = False

APPKEY = ''
with open('APPKEY', 'r') as f:
    APPKEY = f.readline().strip()

TOKEN = ''
with open('TOKEN', 'r') as f:
    TOKEN = f.readline().strip()

# 服务请求地址
URL = 'http://nls-gateway.cn-shanghai.aliyuncs.com/stream/v1/asr'
URL += '?appkey=' + APPKEY
URL += '&format=' + FORMAT
URL += '&sample_rate=' + str(SAMPLE_RATE)

if PUNC:
    URL += '&enable_punctuation_prediction=' + 'true'
if ITN:
    URL += '&enable_inverse_text_normalization=' + 'true'
if VAD:
    URL += '&enable_voice_detection=' + 'true'

sys.stderr.write('Request: ' + URL + '\n')

def recognize(audio):
    with open(audio, mode = 'rb') as f:
        audio_data = f.read()

    host = 'nls-gateway.cn-shanghai.aliyuncs.com'
    # 设置HTTP请求头部
    httpHeaders = {
        'X-NLS-Token': TOKEN,
        'Content-type': 'application/octet-stream',
        'Content-Length': len(audio_data)
    }
    # Python 2.x 请使用httplib
    # conn = httplib.HTTPConnection(host)
    # Python 3.x 请使用http.client

    text = ''
    for i in range(MAX_RETRY):
        try:
            rec = ''
            conn = http.client.HTTPConnection(host)
            #print(conn)
            conn.request(method='POST', url=URL, body=audio_data, headers=httpHeaders)
            response = conn.getresponse()
            #print(response)

            r = response.read()
            sys.stderr.write(r.decode('utf8'))
            sys.stderr.write('\n\n')
            sys.stderr.flush()

            body = json.loads(r)

            status = body['status']
            is_success = body['message']
            if status == 20000000 and is_success == 'SUCCESS':
                rec = body['result']
                text = rec
                conn.close()
                break
            else :
                sys.stderr.write('Failed recognizing, will retry.\n')
                conn.close()
                time.sleep(RETRY_INTERVAL)
        except:
            sys.stderr.write('Exception, will retry.\n')
            conn.close()
            time.sleep(RETRY_INTERVAL)

    return text

if __name__ == '__main__':
    if len(sys.argv) != 3:
        sys.stderr.write("asr_api.py <in_scp> <out_trans>\n")
        exit(-1)

    scp   = codecs.open(sys.argv[1], 'r',  'utf8')
    trans = codecs.open(sys.argv[2], 'w+', 'utf8')

    n = 0
    for l in scp:
        l = l.strip()
        if (len(l.split()) == 2): # scp format: "key\taudio"
            key, audio = l.split(maxsplit=1)
            sys.stderr.write(str(n) + '\tkey:' + key + '\taudio:' + audio + '\n')
            sys.stderr.flush()

            text = ''
            text = recognize(audio)

            trans.write(key + '\t' + text + '\n')
            trans.flush()
            n += 1
        else:
            sys.stderr.write("Invalid line: " + l + "\n")
            sys.stderr.flush()

    scp.close()
    trans.close()


from django.conf.urls import patterns, url

import views
from rachelwebsite.views import message

urlpatterns = patterns('',
    url(r'^$', views.Overview.as_view(), name='overview'),
    url(r'^signup/sent/$', message.as_view(),
        {'title': 'Thank you!',
            'message': 'An email has been sent to you.  Please follow the instructions to complete your account setup.'},
        name='thankyou'),
)


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

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('polls', '0002_auto_20150319_0533'),
    ]

    operations = [
        migrations.AddField(
            model_name='question',
            name='id',
            field=models.AutoField(default=1, serialize=False, primary_key=True),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='question',
            name='question_text',
            field=models.CharField(max_length=200),
            preserve_default=True,
        ),
    ]


from ujscert.headquarter import views
from django.conf.urls import url

urlpatterns = [
    url(r'^api/ping$', views.pong_api_view, name='ping'),
    url(r'^api/index/host$', views.index_host_api_view, name="index_banner"),
    url(r'^api/index/web$', views.index_web_api_view, name="index_web"),
    url(r'^api/index/feed$', views.feed_api_view),
    url(r'^api/apps$', views.apps_api_view),

    url(r'^property/search$', views.search_home_view, name="search_home"),
    url(r'^property/search/$', views.search_view, name="search"),
    url(r'^property/host/(?P<ip>(\d{1,3}\.){3}\d{1,3})$', views.host_view, name="host_detail"),
    url(r'^property/web/(?P<domain>\S+)$', views.web_view, name="web_detail"),
    url(r'^property/export/$', views.export_view, name="export"),
    url(r'^alerts$', views.alert_view, name="alerts"),
]


#  -*- encoding: utf-8 -*-

from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from pathlib import Path

# Authorize Google Drive and Spreadsheet.
sheets_auth = {'scope': 'https://www.googleapis.com/auth/spreadsheets', 'service_name': 'sheets', 'version': 'v4'}
drive_auth  = {'scope': 'https://www.googleapis.com/auth/drive',        'service_name': 'drive',  'version': 'v3'}

def is_creds_available():
    token_path = Path('./credentials/token.json')
    credentials_path = Path('./credentials/credentials.json')

    scopes = sheets_auth['scope'] + ' ' + drive_auth['scope']

    store = file.Storage(token_path)
    creds = store.get()

    if not creds or creds.invalid:
        flow = client.flow_from_clientsecrets(credentials_path, scopes)
        creds = tools.run_flow(flow, store)

    return creds

def build_service(arg_auth):
    if arg_auth == 'sheets':
        auth = sheets_auth
    elif arg_auth == 'drive':
        auth = drive_auth

    creds = is_creds_available()

    auth_service_name = auth['service_name']
    auth_version = auth['version']
    service = discovery.build(auth_service_name, auth_version, http=creds.authorize(Http()))
    return service


from PySide2 import QtWidgets, QtCore, QtGui
import maya.cmds as cmds
import pymel.core as pm
import maya.mel as mel

from master_rigger import Splitter
from master_rigger import sanityChecker  # rename this later
from maya_tools.contexts.undoContext import UndoContext
reload(sanityChecker)

class GlobalToolWidget(QtWidgets.QFrame):

    def __init__(self):
        QtWidgets.QFrame.__init__(self)

        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

        self.setLayout(QtWidgets.QVBoxLayout())
        self.layout().setContentsMargins(1, 1, 1, 1)
        self.layout().setSpacing(0)
        self.layout().setAlignment(QtCore.Qt.AlignTop)

        global_widget = QtWidgets.QWidget()
        global_widget.setLayout(QtWidgets.QVBoxLayout())
        global_widget.layout().setContentsMargins(2, 2, 2, 2)
        global_widget.layout().setSpacing(5)
        global_widget.setSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                    QtWidgets.QSizePolicy.Fixed)

        publish_widget = QtWidgets.QWidget()
        publish_widget.setLayout(QtWidgets.QVBoxLayout())
        publish_widget.layout().setContentsMargins(2, 2, 2, 2)
        publish_widget.layout().setSpacing(5)
        publish_widget.setSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                     QtWidgets.QSizePolicy.Fixed)

        self.layout().addWidget(global_widget)
        self.layout().addWidget(Splitter.Splitter('Rig Mode'))
        self.layout().addWidget(publish_widget)

        # Layouts
        button_layout = QtWidgets.QHBoxLayout()
        publish_layout = QtWidgets.QHBoxLayout()

        # Add layouts to widget
        global_widget.layout().addLayout(button_layout)
        publish_widget.layout().addLayout(publish_layout)

        # Buttons
        self.flip_selection_button = QtWidgets.QPushButton('Flip Selection')
        self.add_iso_button = QtWidgets.QPushButton('Add to Isolate View')
        self.remove_iso_button = QtWidgets.QPushButton('Remove from Isolate View')

        button_layout.addWidget(self.flip_selection_button)
        button_layout.addWidget(self.add_iso_button)
        button_layout.addWidget(self.remove_iso_button)

        self.publish_mode_button = QtWidgets.QPushButton('Publish Mode')
        self.edit_mode_button = QtWidgets.QPushButton('Edit Mode')

        publish_layout.addWidget(self.publish_mode_button)
        publish_layout.addWidget(self.edit_mode_button)

        self.flip_selection_button.clicked.connect(self.flip_selection)
        self.add_iso_button.clicked.connect(self.add_to_isolate)
        self.remove_iso_button.clicked.connect(self.remove_from_isolate)

        self.publish_mode_button.clicked.connect(self.publish_mode)
        self.edit_mode_button.clicked.connect(self.edit_mode)

    def flip_selection(self):
        sel = cmds.ls(selection=True, recursive=True)
        flip = []

        namespace = None
        if ':' in sel[0]:
            sel = [obj.split(':')[1] for obj in sel]
            namespace = obj.split(':')[0]

        for item in sel:
            if '_L_' in item:
                flip.append(item.replace('_L_', '_R_'))
            elif '_R_' in item:
                flip.append(item.replace('_R_', '_L_'))
            elif item.startswith('R_'):
                flip.append('L_' + item[2:])
            elif item.startswith('L_'):
                flip.append('R_' + item[2:])
            elif item.endswith('_R'):
                flip.append(item[:-2] + '_L')
            elif item.endswith('_L'):
                flip.append(item[:-2] + '_R')
            else:
                cmds.warning('Nothing done.')

        if namespace:
            flip = [':'.join([namespace, item]) for item in flip]

        cmds.select(flip, replace=True)

    def add_to_isolate(self):
        mel.eval('isolateSelect -addSelected modelPanel4;')

    def remove_from_isolate(self):
        mel.eval('isolateSelect -removeSelected modelPanel4;')

    def publish_mode(self):
        with UndoContext():
            sanityChecker.publishMode()

    def edit_mode(self):
        with UndoContext():
            sanityChecker.editMode()


#!/usr/bin/env python
# coding: utf-8

# In[1]:

import numpy as np
import pandas as pd
import folium
import json
import argparse
import time
from selenium import webdriver
from pandas import json_normalize

def utf2asc(s):
    return str(str(s).encode('ascii', 'xmlcharrefreplace'))[2:-1]

parser = argparse.ArgumentParser()
parser.add_argument('--input_path', type=str, default='final_201709.csv')
parser.add_argument('--output_path', type=str, default='fmap-201709.csv')

args = parser.parse_args()

input_path, output_path = args.input_path, args.output_path

df = pd.read_csv(input_path)

fmap = folium.Map(location=[25.09124,121.5344], tiles='CartoDB positron', zoom_start=12.5)
for n in range(107):

    name = df['Station'].iloc[n]
    if df['label'].iloc[n] == 'A' :
        icon_url = "https://i.imgur.com/pae0T2U.png"
    elif df['label'].iloc[n] == 'B' :
        icon_url = "https://i.imgur.com/w7z8Wcq.png"
    elif df['label'].iloc[n] == 'C' :
        icon_url = "https://i.imgur.com/v9LvRvp.png"
    else:
        icon_url = "https://i.imgur.com/wnDXlOX.png"

    icon = folium.features.CustomIcon(icon_url,icon_size=(30, 30))  # Creating a custom Icon
    folium.Marker(
            location=[df['Latitude'].iloc[n],df['Longitude'].iloc[n]],
            popup= "<b>{}</b>".format( utf2asc(name) ),
            icon=icon
            ).add_to( fmap )

with open('MRT_lines.geojson', 'r', encoding='utf-8') as f:
    output = json.load(f)

df_feature = json_normalize(output['features'])

colorlst = ["#cc8528", "#e34043", "#fb9a99", "#ff9e17", "#ff9e17", "#33a02c", "#a7df72", "#2a54ff" ]

for i in range(8):
    points = df_feature['geometry.coordinates'][i]
    [ x.reverse() for x in points[0] ]
    folium.PolyLine(points, color=colorlst[i], weight=2.5, opacity=1).add_to(fmap)

fmap.save(output_path)


"""
Michael Tucker 2018
script to help get general classification of
"""
import numpy as np
import matplotlib.pyplot as plt
import argparse
from astropy.convolution import convolve, Box1DKernel
from matplotlib.widgets import TextBox,CheckButtons,Slider
import ipdb

#Various lines to look for in transient spectra

LINES = {
	'H':[4102.,4340.,4861.,6563.],
	'HeI':[3888.6, 4471.5, 5875.6, 6678.2],
	'HeII':[4686.0],
	'SiII':[6355.0, 5970.,],
	'NaI':[5890.0],
	'FeII':[4325.,4600.,5020.,5200.],
	'SII':[5630.,5450.],
	'CaII':[3950., 8500.],
	'OIII':[4959.0,5007.0,],
	'NII':[6583.0],
	'NeIII':[3869.0],
	'NeV':[3425.0]

}

COLORS = {
	'H':'b',
	'HeI':'g',
	'SiII':'m',
	'NaI':'c',
	'FeII':'m',
	'SII':'c',
	'CaII':'g',
	'HeII':'g',
	'OIII':'r',
	'NII':'g',
	'NeIII':'skyblue',
	'NeV':'skyblue'
}

#Line IDs from the following:
#Ia (Mazzali+ 1993)
#II
#
TRANSIENTS = {
	'Ia':['FeII','SiII', 'NaI', 'SII','CaII'],
	'Ib/c':[],
	'II':[],
	'CV':['H', 'He'],
	'Mstar':[],
	'AGN':['H', 'He', 'NII', 'NeIII', 'NeV'],

}

#main function call
def main(fname, z, lines, kernel):
	#read SNIFS spectrum
	wl, fl, err = np.genfromtxt(fname, unpack=True, dtype=float, comments='#')

	if z > 0.5:
		print('Input redshift > 0.5, setting z = 0.5')
		z = 0.5
	if kernel > 50:
		print('Input kernel > 50, setting kernel = 50')
	plot = Plotter(wl, fl, err, kernel, z, lines)
	plot.startPlot()

class Plotter():
	"""
	Interactive plotting class

	Inputs:
		wl: 1-D wavelength array
		fl: 1-D flux array
		err: 1-D error array
		kernel1: size of smoothing kernel (pixels) for smaller
	"""

	def __init__(self, wl, fl, err, kernel=5, redshift=0.0, lines=[]):
		#assign attributes
		self.wl = wl
		self.fl = fl
		self.err = err

		#apply two smoothing kernels
		self.kernel = kernel
		self.smooth = convolve(self.fl, Box1DKernel(self.kernel))

		self.redshift = redshift
		self.lines = [line.strip() for line in lines.split(',')]

	def startPlot(self):
		#setup plot
		self.fig, self.ax = plt.subplots(figsize=(12,8))
		self.ax.set_xlabel('Wavelength (AA)')
		self.ax.set_ylabel('Flux (erg/s/cm2/AA)')

		#actually plot spectrum
		self.spectrum, = self.ax.plot(self.wl, self.fl, 'k-', drawstyle='steps-mid')
		self.plotErrorbar(start=True)
		self.plotSmooth(start=True)
		self.xlims = self.ax.get_xlim()

		self.addLines(self.lines,start=True)

		axbox = plt.axes([0.1, 0.1, 0.5, 0.04])
		zslider = Slider(axbox, 'Redshift', 0., 0.5, valinit=self.redshift, valstep=0.001, valfmt='%1.3f')
		zslider.on_changed(self.addRedshift)

		axbox = plt.axes([0.1, 0.06, 0.5, 0.04])
		text_box2 = TextBox(axbox, 'kernel', initial=str(self.kernel))
		text_box2.on_submit(self.resizeKernel)

		axbox = plt.axes([0.1, 0.02, 0.5, 0.04])
		text_box3 = TextBox(axbox, 'lines (csv)', initial=','.join(self.lines))
		text_box3.on_submit(self.addLines)

		rax = plt.axes([0.7, 0.05, 0.14, 0.1])
		labels = ['Obs spec', 'Err spec', 'Smooth spec']
		visibility = [True, False, False]
		check = CheckButtons(rax, labels, visibility)
		check.on_clicked(self.button_press)

		self.ax.set_xlim(self.xlims)
		plt.subplots_adjust(bottom=0.22, top=0.95, left=0.1, right=0.95)

		plt.show()

	def button_press(self, button):
		#what to do when buttons are pushed
		if button == 'Err spec': self.plotErrorbar()
		elif button == 'Obs spec': self.plotSpec()
		elif button == 'Smooth spec': self.plotSmooth()

		self.fig.canvas.draw()

	def plotErrorbar(self, start=False):
		if start:
			upper = self.fl + self.err
			lower = self.fl - self.err
			self.errorbar = self.ax.fill_between(self.wl, lower, upper, color='k', alpha=0.2)
			self.errorbar.set_visible(False)
		else:
			if self.errorbar.get_visible() == False:
				self.errorbar.set_visible(True)
			else:
				self.errorbar.set_visible(False)

	def addLines(self, lines, start=True):
		if start:
			self.SpecLines = {}
			for line in LINES.keys():
				waves = LINES[line]
				allLines = [self.ax.axvline(wave*(1.0+self.redshift), 0.0,1.0,ls='-', lw=2.0, color=COLORS[line]) for wave in waves]
				for ll,wv in zip(allLines, waves):
					ll.set_visible(False)
					ll.restwave = wv

				self.SpecLines[line] = allLines
			if len(lines) == 0: return

		if type(self.lines) == str:
			self.lines = [line.strip() for line in lines.split(',')]
		for line in self.lines:
			if line in TRANSIENTS.keys():
				self.lines += TRANSIENTS[line]
				self.lines.remove(line)
			elif line not in LINES.keys(): print('WARNING (addLines): Line %s not found, skipping...')

		for line in LINES.keys():
			if line in self.lines: visible = True
			else: visible = False

			for wave in self.SpecLines[line]: wave.set_visible(visible)

		self.fig.canvas.draw()

	def updateLines(self):
		for line in self.SpecLines.keys():
			for wave in self.SpecLines[line]:
				wave.set_xdata(wave.restwave*(1.0+self.redshift))
		self.fig.canvas.draw()

	def plotSmooth(self, start=False):
		if start:
			self.smooth_plot, = self.ax.plot(self.wl, self.smooth, 'r-')
			self.smooth_plot.set_visible(False)
			return

		visible = self.smooth_plot.get_visible()
		if visible: self.smooth_plot.set_visible(False)
		else: self.smooth_plot.set_visible(True)

	def addRedshift(self, text):
		try:
			self.redshift = float(text)
			self.updateLines()
		except ValueError:
			print('WARNING (addRedshift): Could not convert string to float, check input.')

	def plotSpec(self):
		if self.spectrum.get_visible(): self.spectrum.set_visible(False)
		else: self.spectrum.set_visible(True)

	def resizeKernel(self, text):
		try:
			self.kernel = float(text)
		except ValueError:
			print('WARNING (resizeKernel): Could not convert string to float, check input.')
			return
		self.smooth = convolve(self.fl, Box1DKernel(self.kernel))
		self.smooth_plot.set_ydata(self.smooth)
		self.fig.canvas.draw()

if __name__=='__main__':
	parser = argparse.ArgumentParser(description="quick-class: quick script for guessing classification/redshift of SNIFS transient spex")
	parser.add_argument('fname', help='SNIFS spectrum file', type=str)
	parser.add_argument('--redshift', '-z', help='inital redshift estimate. Default: 0.0', default=0.0, type=float)
	parser.add_argument('--lines', '-l', help='initial lines to plot, csv w/o spaces (e.g. H,He,Si) or a transient type (e.g. Ia/II). Default: None', default='', type=str)
	parser.add_argument('--kernel', '-k', help='pixel width of smoothing kernel. Default: 5', default=5, type=int)

	args = parser.parse_args()
	main(args.fname, args.redshift, args.lines, args.kernel)


#coding=utf-8
#!/usr/bin/python
import os
import logging

rootPath = __file__[:-12]
#print rootPath
logPath = rootPath+"/myapp.log"
logging.basicConfig(level=logging.DEBUG,
                format='%(asctime)s %(filename)s[line:%(lineno)d] %(message)s',
                datefmt='%Y-%m-%d %H:%M:%S',
                filename=logPath,
                filemode='a')

#logging.debug('This is debug message')
#logging.info('This is info message')
#logging.warning('This is warning message')
def log(msg):

    logging.info(msg)


#!/usr/bin/python3
"""API"""

from models import storage
from os import getenv
from flask import Flask, jsonify
from api.v1.views import app_views

app = Flask(__name__)
app.register_blueprint(app_views, url_prefix='/api/v1')

@app.teardown_appcontext
def teardown(self):
    """method that calls storage.close()"""
    storage.close()

@app.errorhandler(404)
def error404(error):
    """
    handler for 404 errors that returns a JSON-formatted 404
    status code response
    """
    return jsonify({"error": "Not found"}), 404

if __name__ == "__main__":
    """run Flask server (variable app) """
    host = getenv("HBNB_API_HOST")
    port = getenv("HBNB_API_PORT")
    app.run(host=host if host is not None else '0.0.0.0',
            port=port if port is not None else '5000',
            threaded=True)


# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)]
# Embedded file name: T:\InGame\Gameplay\Scripts\Server\objects\gardening\gardening_tuning.py
# Compiled at: 2020-04-29 22:09:34
# Size of source mod 2**32: 11362 bytes
from objects.collection_manager import ObjectCollectionRarity
from objects.components.state import ObjectState, ObjectStateValue
from seasons.seasons_tuning import SeasonsTuning
from sims4.localization import TunableLocalizedString, TunableLocalizedStringFactory, LocalizationHelperTuning
from sims4.tuning.tunable import TunableList, TunableRange, TunableInterval, TunableMapping, TunableReference, TunableEnumEntry, TunableTuple, TunableVariant, TunablePercent, Tunable, TunableSet, TunablePackSafeReference
from statistics.commodity import Commodity
from ui.ui_dialog_notification import UiDialogNotification
import services, sims4.resources

class GardeningTuning:
    INHERITED_STATE = ObjectState.TunableReference(description='\n        Controls the state value that will be inherited by offspring.\n        ')
    SPONTANEOUS_GERMINATION_COMMODITY = Commodity.TunableReference()
    SPONTANEOUS_GERMINATION_COMMODITY_VARIANCE = TunableRange(description='\n        Max variance to apply when the spawn commodity is reset.  This helps\n        plants all not to sprout from seeds at the same time.\n        ',
      tunable_type=int,
      default=10,
      minimum=0)
    SCALE_COMMODITY = Commodity.TunableReference()
    SCALE_VARIANCE = TunableInterval(description="\n        Control how much the size of child fruit can vary from its father's\n        size.\n        ",
      tunable_type=float,
      default_lower=0.8,
      default_upper=1.2)
    EVOLUTION_STATE = ObjectState.TunableReference(description='\n        Object state which will represent the icon behind the main icon of \n        the gardening tooltip.  This should be tied to the evolution state\n        of gardening objects.\n        ')
    SHOOT_DESCRIPTION_STRING = TunableLocalizedString(description="\n        Text that will be given to a shoot description following ':' to its \n        fruit name.\n        e.g. 'Shoot taken from: Apple'\n        ")
    DISABLE_DETAILS_STATE_VALUES = TunableList(description='\n            List of object state values where the gardening details should not \n            be shown.  This is for cases like Wild plants where we dont want\n            details that will not be used.\n            ',
      tunable=ObjectStateValue.TunableReference(description='\n                The state that will disable the plant additional information.\n                '))
    DISABLE_TOOLTIP_STATE_VALUES = TunableList(description='\n            List of object state values where the gardening object will disable \n            its tooltip.\n            ',
      tunable=ObjectStateValue.TunableReference(description='\n                The state that will disable the object tooltip.\n                '))
    SPLICED_PLANT_NAME = TunableLocalizedStringFactory(description='\n        Localized name to be set when a plant is spliced. \n        ')
    SPLICED_STATE_VALUE = ObjectStateValue.TunableReference(description='\n        The state that will mean this plant has been already spliced.  \n        ')
    PICKUP_STATE_MAPPING = TunableMapping(description='\n        Mapping that will set a state that should be set on the fruit when \n        its picked up, depending on a state fruit is currently in.\n        ',
      key_type=(ObjectStateValue.TunableReference()),
      value_type=(ObjectStateValue.TunableReference()))
    GARDENING_SLOT = TunableReference(description='\n        Slot type used by the gardening system to create its fruit.\n        ',
      manager=(services.get_instance_manager(sims4.resources.Types.SLOT_TYPE)))
    GERMINATE_FAILURE_NOTIFICATION = UiDialogNotification.TunableFactory(description='\n        Notification that will tell the player that the plant has failed to\n        germinate.\n        ')
    UNIDENTIFIED_STATE_VALUE = ObjectStateValue.TunableReference(description='\n        The state value all unidentified plants will have.  Remember to add this\n        as the default value for a state in the identifiable plants state\n        component tuning.\n        ')
    SEASONALITY_STATE = ObjectState.TunablePackSafeReference(description="\n        A reference to the state that determines whether a plant is\n        Dormant/Indoors/In Season/Out of Season.\n        \n        The state value's display data is used in the UI tooltip for the plant.\n        ")
    SEASONALITY_IN_SEASON_STATE_VALUE = ObjectStateValue.TunablePackSafeReference(description='\n        A reference to the state value that marks a plant as being In Season.\n        \n        This state value is determined to detect seasonality.\n        ')
    SEASONALITY_ALL_SEASONS_TEXT = TunableLocalizedString(description='\n        The seasons text to display if the plant has no seasonality.\n        ')
    PLANT_SEASONALITY_TEXT = TunableLocalizedStringFactory(description="\n        The text to display for the plant's seasonality.\n        e.g.:\n        Seasonality:\n{0.String}\n        ")
    FRUIT_STATES = TunableMapping(description='\n        A mapping that defines which states on plants support fruits, and the\n        behavior when plants transition out of these states.\n        ',
      key_type=ObjectState.TunableReference(pack_safe=True),
      value_type=TunableTuple(states=TunableList(description='\n                The list of states that supports fruit. If the object changes\n                state (for the specified state track) and the new value is not\n                in this list, the fruit is destroyed according to the specified\n                rule.\n                ',
      tunable=ObjectStateValue.TunableReference(pack_safe=True),
      unique_entries=True),
      behavior=TunableVariant(description="\n                Define the fruit's behavior when plants exit a state that\n                supports fruit.\n                ",
      rot=TunablePercent(description='\n                    Define the chance that the fruit falls and rots, as opposed\n                    to just being destroyed.\n                    ',
      default=5),
      locked_args={'destroy': None},
      default='destroy')))
    FRUIT_DECAY_COMMODITY = TunableReference(description='\n        The commodity that defines fruit decay (e.g. rotten/ripe).\n        ',
      manager=(services.get_instance_manager(sims4.resources.Types.STATISTIC)))
    FRUIT_DECAY_COMMODITY_DROPPED_VALUE = Tunable(description='\n        Value to set the Fruit Decay Commodity on a harvestable that has\n        been dropped from a plant during a seasonal transition.\n        ',
      tunable_type=int,
      default=10)
    SPAWN_WEIGHTS = TunableMapping(description="\n        A fruit's chance to be spawned in a multi-fruit plant (e.g. via\n        splicing/grafting) is determined by its rarity.\n        \n        The weight is meant to curb the chance of spawning rarer fruits growing\n        on more common plants. It would never reduce the chance of the root\n        stock from spawning on its original plant.\n        \n        e.g.\n         A common Apple on a rare Pomegranate tree spawns at a 1:1 ratio.\n         A rare Pomegranate on a common Apple tree spawns at a 1:5 ratio.\n        ",
      key_type=TunableEnumEntry(tunable_type=ObjectCollectionRarity,
      default=(ObjectCollectionRarity.COMMON)),
      value_type=TunableRange(tunable_type=int,
      default=1,
      minimum=0))
    EXCLUSIVE_FRUITS = TunableSet(description='\n        A set of fruits, which, when added onto a plant, can restrict\n        what other fruits the plant produces to this set of fruits. \n        This is done by adjusting spawn weight of non-exclusive fruits \n        on the plant to zero. \n        ',
      tunable=TunableReference(manager=(services.get_instance_manager(sims4.resources.Types.OBJECT)),
      pack_safe=True))
    VERTICAL_GARDEN_OBJECTS = TunableSet(description='\n        A set of Vertical garden objects.\n        ',
      tunable=TunableReference(manager=(services.definition_manager()),
      pack_safe=True))

    @classmethod
    def is_spliced(cls, obj):
        if obj.has_state(cls.SPLICED_STATE_VALUE.state):
            if obj.get_state(cls.SPLICED_STATE_VALUE.state) == cls.SPLICED_STATE_VALUE:
                return True
        return False

    @classmethod
    def is_unidentified(cls, obj):
        if cls.UNIDENTIFIED_STATE_VALUE is not None:
            if obj.has_state(cls.UNIDENTIFIED_STATE_VALUE.state):
                if obj.get_state(cls.UNIDENTIFIED_STATE_VALUE.state) == cls.UNIDENTIFIED_STATE_VALUE:
                    return True
        return False

    @classmethod
    def get_seasonality_text_from_plant(cls, plant_definition):
        season_component = plant_definition.cls._components.season_aware_component
        if season_component is not None:
            seasons = []
            season_tuned_values = season_component._tuned_values
            for season_type, season_states in season_tuned_values.seasonal_state_mapping.items():
                if any((s is GardeningTuning.SEASONALITY_IN_SEASON_STATE_VALUE for s in season_states)):
                    season = SeasonsTuning.SEASON_TYPE_MAPPING[season_type]
                    seasons.append((season_type, season))

            if seasons:
                return GardeningTuning.PLANT_SEASONALITY_TEXT((LocalizationHelperTuning.get_comma_separated_list)(*tuple((season.season_name for _, season in sorted(seasons)))))

    ALWAYS_GERMINATE_IF_NOT_SPAWNED_STATE = ObjectStateValue.TunableReference(description='\n        If the specified state value is active on the gardening object, it will\n        have a 100% germination chance for when it is placed in the world in\n        any way other than through a spawner.\n        ')
    QUALITY_STATE_VALUE = ObjectState.TunableReference(description='\n        The quality state all gardening plants will have.  \n        ')


#!usr/bin/python
#coding:utf-8

import sqlite3
con=sqlite3.connect('me.db')
id=2
host="www.reading-china.com"
payload="me"
cursor=con.cursor()
sql="insert into info(id,host,payload) values({id},'{host}','{payload}')".format(id=id,host=host,payload=payload)
print(sql)
cursor.execute(sql)
con.commit()
con.close()


#!/bin/env python3

"""
Source:
https://sites.google.com/site/prologsite/prolog-problems/1
"""

def p01(alist):
    """
    1.01 (*) Find the last element of a list.
    """
    return alist[-1]

def p02(alist):
    """
    1.02 (*) Find the last but one element of a list.
    """
    return alist[-2]

def p03(alist, n):
    """
    1.03 (*) Find the K'th element of a list.
    """

    assert n < len(alist)

    return alist[n - 1]

def p04(alist):
    """
    1.04 (*) Find the number of elements of a list.
    """

    return len(alist)

def p05(alist):
    """
    1.05 (*) Reverse a list.
    """

    return alist[::-1]

def p06(alist):
    """
    1.06 (*) Find out whether a list is a palindrome.
    """

    return alist == alist[::-1]

def p07(nested):
    """
    1.07 (**) Flatten a nested list structure.
    """

    # nested = ['a', ['b', ['c', 'd'], 'e']]
    for i in nested:
        if isinstance(i, (list, tuple)):
            for j in p07(i):
                yield j
        else:
            yield i

def p07_1(items, seqtypes=(list, tuple)):
    # https://stackoverflow.com/questions/10823877/what-is-the-fastest-way-to-flatten-arbitrarily-nested-lists-in-python
    for i, x in enumerate(items):
        while i < len(items) and isinstance(items[i], seqtypes):
            items[i:i+1] = items[i]
    return items

def p07_2(nestedlist):
    # https://stackoverflow.com/questions/406121/flattening-a-shallow-list-in-python
    # only for one nested list
    from itertools import chain
    nestedlist = ['a', ['b'], ['c', 'd'], 'e']
    chain_it = chain(*nestedlist)

    return list(chain_it)

def p08(rep):
    """
    1.08 (**) Eliminate consecutive duplicates of list elements.
    If a list contains repeated elements they should be replaced with a single
    copy of the element. The order of the elements should not be changed.

    """

    rep = ["a","a","a","a","b","c","c","a","a","d","e","e","e","e"]
    norep = []

    for n, x in enumerate(rep):
        if n + 1 < len(rep):
            if rep[n] != rep[n + 1]:
                norep.append(x)
        else:
            norep.append(rep[n])

    return norep

def p09(somelist):
    """
    1.09 (**) Pack consecutive duplicates of list elements into sublists.
    If a list contains repeated elements they should be placed in separate
    sublists.
    """

    assert somelist is not None

    packed = []
    for index, value in enumerate(somelist):
        if index == 0 or value != somelist[index - 1]:
            packed.append([value])
        else:
            packed[-1].append(value)
    return packed

def p10(somelist):
    """
    1.10 (*) Run-length encoding of a list.
    Use the result of problem 1.09 to implement the so-called run-length
    encoding data compression method. Consecutive duplicates of elements are
    encoded as terms [N,E] where N is the number of duplicates of the element E.
    """

    assert somelist is not None

    packed = []
    for index, value in enumerate(somelist):
        if index == 0 or value != somelist[index - 1]:
            packed.append([1, value])
        else:
            packed[-1][0] += 1

    return packed

def p11(somelist):
    """
    1.11 (*) Modified run-length encoding.
    Modify the result of problem 1.10 in such a way that if an element has no
    duplicates it is simply copied into the result list. Only elements with
    duplicates are transferred as [N,E] terms.

    Example:
    ?- encode_modified([a,a,a,a,b,c,c,a,a,d,e,e,e,e],X).
    X = [[4,a],b,[2,c],[2,a],d,[4,e]]
    """
    assert somelist is not None

    old_list = p10(somelist)
    temp = []
    for i, e in enumerate(old_list):
        if e[0] == 1:
            temp.append(e[1])
        else:
            temp.append(e)
    return temp

if __name__ == '__main__':

    alist = ['a', 'b', 'c', 'd']
    somelist = ["a","a","a","a","b","c","c","a","a","d","e","e","e","e"]
    nestedlist = ['a', ['b', ['c', 'd'], 'e']]

    print(p01(alist))
    #
    print(p02(alist))
    #
    print(p03(alist, 2))
    #
    print(p04(alist))
    #
    print(p05(alist))
    #
    print(p06(alist))
    #
    print(list(p07(nestedlist)))
    print(list(p07_1(nestedlist)))
    print(p07_2(nestedlist))
    #
    print(p08(somelist))
    #
    print(p09(somelist))
    #
    print(p10(somelist))
    #
    print(p11(somelist))


#! /usr/bin/env Python
import zmq
import time
import sys
import json

class ZMQ(object):

    def __init__(self, port):
        self.port = port
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.REP)
        self.socket.bind("tcp://*:%s" % self.port)

    def run(self):
        # Wait for next request from client
        message = self.socket.recv()
        # print "Received request: ", message
        test = [1,2,3,4,5,6, self.port]
        reply = json.dumps(test)
        self.socket.send(reply)


import glob
import csv
import re
import pandas as pd
import nltk
nltk.download('stopwords')
from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.stem.snowball import SnowballStemmer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression

from flask import Flask, redirect, url_for, request, render_template
app = Flask(__name__)

#
# Naive Bayes Algorithm
#

#stopWords is the list of stopWords we will use to filter our dataset
#The SnowballStemmer will be used to stem all the remaining words in the dataset
stopWords = set(stopwords.words('english'))
stemmer =SnowballStemmer('english')

csv_file = "data/dataset.csv"
dff = pd.read_table(csv_file, sep = ',', names = ['Sentence','Tag'])

#cleaning the words in the dff dataframe
s = pd.Series ([[]], index=dff.index)
dff['Sentence'] = dff['Sentence'].str.lower().str.split().mask(dff['Sentence'].isnull(),s)

#take out the stopwords
dff['Sentence'] = dff['Sentence'].apply(lambda x:' '.join([item for item in x if item not in stopWords]))

#stem the remaining words
dff['Sentence'] = dff['Sentence'].str.lower().str.split().mask(dff['Sentence'].isnull(),s)
dff['Sentence'] = dff['Sentence'].apply(lambda x: ' '.join([stemmer.stem(item) for item in x]))

dff['Tag'] = dff.Tag.map({'NON_FACTUAL': 0, "FACTUAL": 1})

Xf = dff.Sentence
yf = dff.Tag

vf=CountVectorizer()
Xf_data = vf.fit_transform(Xf)

logregf = LogisticRegression()
logregf.fit(Xf_data, yf)

@app.route('/')
def index():
   return render_template('index.html')

@app.route('/result', methods = ['POST', 'GET'])
def result():
    if request.method == 'POST':
        input = request.form['input_paragraph']

        word_tokens = input.split(" ")

        filtered = [w for w in word_tokens if not w in stopWords]

        filtered = []

        for w in word_tokens:
            if w not in stopWords:
                filtered.append(w)

        filtered = [stemmer.stem(word) for word in filtered]
        test = [' '.join(filtered)]

        test_data = vf.transform(test)

        # output to be sent
        predict_result = logregf.predict(test_data)
        pred_prob = logregf.predict_proba(test_data)

        output = input
        if len(input) > 30:
            output = input[:30]
            output += "..."

        if predict_result == 0:
            prob = round(pred_prob[0][0], 2)
        else:
        	    prob = round(pred_prob[0][1], 2)

        return render_template('result.html', data = output, result = predict_result, prob = prob)

    else:
        return render_template('index.html')

if __name__ == '__main__':
   app.run(debug = True)


# coding=UTF-8
###############################################################################
def filter1(I):
    import lib.filter as fl
    run=1
    f1=fl.getOpenVolABS(I.get("小台純主力買企圖")-I.get("小台純主力賣企圖"),15,start=30)
    f2=fl.getOpenVolABS(I.get("大台純散戶買企圖")-I.get("大台純散戶賣企圖"),15,start=30)
    if (f1>0 and f1<10.5) or (f2>50 and f2<68):
        run=0
    return run

###############################################################################
def s1(self,PRICE,i,I): #1763
    if filter1(I)==0:
        return

    baseT= 30
    if i< (baseT+15) : return
    base1= I.get("大台純主力買企圖")[baseT]
    base2= I.get("小台純主力買企圖")[baseT]
    base3= I.get("大台純主力賣企圖")[baseT]
    base4= I.get("小台純主力賣企圖")[baseT]

    b=(I.get("大台純主力買企圖")[i-1]-base1)+(I.get("小台純主力買企圖")[i-1]-base2)
    s=(I.get("大台純主力賣企圖")[i-1]-base3)+(I.get("小台純主力賣企圖")[i-1]-base4)

    if (b-s)<-2 : self.EnterShort(PRICE)
    if (b-s)>2  : self.EnterLong(PRICE)

    self.CheckDailyExitAll(I.get("TIME")[i],PRICE)

###############################################################################
import os
STittle=u"[s31_1]大小台加總純主力企圖"
FName=os.path.split(__file__)[1].split('.')[0]
if __name__ == '__main__':
    exec(open(os.path.split(os.path.realpath(__file__))[0]+'\\init.py').read())


import os
import tensorflow as tf
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_score, recall_score, f1_score

def LoadData(num):
    X = np.load("./data/%d/X.npy" % num)
    y = np.load("./data/%d/y.npy" % num)

    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=666)

    return X_test, y_test

if __name__ == '__main__':
    os.environ["CUDA_VISIBLE_DEVICES"] = "1"

    X, y = LoadData(19)
    a = np.zeros(y.shape, np.float32)
    b = np.zeros(y.shape, np.float32)

    for num in range(19, 35, 2):
        X_test, y_test = LoadData(num)

        shared_model = tf.keras.models.load_model("./model/shared_model.h5")
        model = tf.keras.models.load_model("./model/model_%d.h5" % num)
        for i in range(8, len(model.layers), 1):
            model.layers[i] = shared_model.layers[i]

        y_pred = model.predict(X_test)

        for i in range(y_test.shape[0]):
            temp = np.abs(y_pred[i][0] - 0.5)
            if temp >= a[i][0]:
                a[i][0] = temp
                b[i][0] = y_pred[i]

    b[b >= 0.5] = 1
    b[b != 1] = 0

    print("probability:")
    print("precision=", precision_score(y, b))
    print("recall=", recall_score(y, b))
    print("f1=", f1_score(y, b))
    print()


import base64

import grok
from cbu.pyhod.session import start_session
from cbu.pyhod.files import add_input_file, get_file
from cbu.pyhod.jobs import add_job, get_job_status
from js.jquery import jquery
from zope.component import getUtility

from LCAClassifier.web import resource
from LCAClassifier.web.interfaces import ILCAClassifyJob
from LCAClassifier.web.interfaces import IMyMailer

class LCAClassifyJob(grok.Model):
    grok.implements(ILCAClassifyJob)

    def __init__(self, fasta_files, db_name, bitscore, minscore, email=None):
        super(LCAClassifyJob, self).__init__()
        self.all_fasta = 'All.fasta'
        self.input_file_names = fasta_files.keys()
        self.session_id = start_session()
        blast_job_ids, xml_files = self._megablast(fasta_files, db_name)
        self.jobid = self._classify(blast_job_ids, xml_files,
                                    bitscore, minscore,db_name)
        self.email = email
        self.email_sent = False

    @property
    def status(self):
        return get_job_status(self.jobid)

    def _megablast(self, fasta_files, db_name):
        """MEGABLAST job submission."""
        blast_job_ids = []
        xml_files = []
        add_input_file(self.session_id, self.all_fasta,
                       '\n'.join(fasta_files.values()))

        for fasta_file_name in fasta_files.keys():
            xml_file_name = '.'.join(fasta_file_name.split('.')[:-1]) + ".xml"
            xml_files.append(xml_file_name)
            add_input_file(self.session_id, fasta_file_name,
                           fasta_files[fasta_file_name])
            parameters = ("-i %s -o %s -m7 -b100 -v100 -d %s -a 2" %
                          (fasta_file_name, xml_file_name, db_name))
            job_id = add_job(self.session_id, "lca_megablast", parameters,
                             [fasta_file_name], [xml_file_name], [], True)
            blast_job_ids.append(job_id)

        return blast_job_ids, xml_files

    def _classify(self, blast_job_ids, xml_files, bitscore=2, minscore=155, db_name="silvamod"):
        """Classify job submission."""
        args = ("-v -o -a -i %s -s %s -r %s -d %s %s" %
                (self.all_fasta, minscore, bitscore, db_name, ' '.join(xml_files)))
        in_files = xml_files + [self.all_fasta]
        out_files = ["All_Composition.txt"]
        for xml_file in xml_files:
            assignedFastaOut = xml_file.replace(".xml", "_Assignments.fasta")
            out_files.append(assignedFastaOut)
            compoOut = xml_file.replace(".xml", "_Composition.txt")
            out_files.append(compoOut)

        classify_job_id = add_job(session_id=self.session_id,
                                  executable_name="lca_classify",
                                  parameters=args,
                                  prerequisite_job_ids=blast_job_ids,
                                  input_file_names=in_files,
                                  output_file_names=out_files,
                                  stage_output_files=True)
        return classify_job_id

class Index(grok.View):

    def update(self):
        resource.style.need()
        jquery.need()
        #resource.result.need()
        resource.pagereload.need()

    def filenames(self):
        for filename in self.context.input_file_names:
            yield '.'.join(filename.split('.')[:-1])

    def result(self):
        if (self.context.status != 'FINISHED' and
            self.context.status != 'ERROR' and
            self.context.status != 'ABORTED'):
            loader = self.static['ajax-loader.gif']
            return ('
Your job is running...
\n'
                    '
\n' % loader())

        if self.context.status == 'ERROR':
            return self._report_error('produced an error')

        if self.context.status == 'ABORTED':
            return self._report_error('was aborted')

        results = ('
\n
\n
\n'
                   '	\nFile name	\n'
                   '
\n
\n
\n')
        for filename in self.context.input_file_names:
            filename = '.'.join(filename.split('.')[:-1])
            result = ('
	'
                      '\n'
                      '    \n'
                      '        %s_Assignments.fasta\n'
                      '    \n'
                      '
'
                      '
	'
                      '\n'
                      '    \n'
                      '        %s_Composition.txt\n'
                      '    \n'
                      '
' % (filename, filename, filename, filename))
            results += result

        result = ('
	'
                  '\n'
                  '    \n'
                  '        All_Composition.txt\n'
                  '    \n'
                  '	\n
\n
\n
')
        results += result

        mailer = getUtility(IMyMailer)
        if self.context.email is not None:
            if not self.context.email_sent:
                url = grok.url(self.request, self.context)
                mailer.send_mail(self.context.email, 'Job finished', url)
                self.context.email_sent = True

        return results

    def _report_error(self, status):
        message = ("
Your job %s. Please contact the service group, "
                   "services@cbu.uib.no, and provide the following "
                   "job id: %s
" % (status, self.context.jobid))
        return message

class Status(grok.View):

    def render(self):
        return self.context.status

class Result(grok.View):

    def render(self):
        if (self.context.status != 'FINISHED' and
            self.context.status != 'ERROR' and
            self.context.status != 'ABORTED'):
            loader = self.static['ajax-loader.gif']
            return ('
Your job is running...
\n'
                    '
\n' % loader())

        if self.context.status == 'ERROR':
            return self._report_error('produced an error')

        if self.context.status == 'ABORTED':
            return self._report_error('was aborted')

        results = ('
\n
\n
\n'
                   '	\nFile name	\n'
                   '
\n
\n
\n')
        for filename in self.context.input_file_names:
            filename = '.'.join(filename.split('.')[:-1])
            result = ('
	'
                      '\n'
                      '    \n'
                      '        %s_Assignments.fasta\n'
                      '    \n'
                      '
'
                      '
	'
                      '\n'
                      '    \n'
                      '        %s_Composition.txt\n'
                      '    \n'
                      '
' % (filename, filename, filename, filename))
            results += result

        result = ('
	'
                  '\n'
                  '    \n'
                  '        All_Composition.txt.fasta\n'
                  '    \n'
                  '	\n
\n
\n
')
        results += result

        mailer = getUtility(IMyMailer)
        if self.context.email is not None:
            if not self.context.email_sent:
                url = grok.url(self.request, self.context)
                mailer.send_mail(self.context.email, 'Job finished', url)
                self.context.email_sent = True

        return results

    def _report_error(self, status):
        message = ("
Your job %s. Please contact the service group, "
                   "services@cbu.uib.no, and provide the following "
                   "job id: %s
" % (status, self.context.jobid))
        return message

class Download(grok.View):

    def render(self):
        output_name = self.request['output_name']
        output_type = self.request['output_type']
        filename = '%s_%s' % (output_name, output_type)
        results = base64.b64decode(get_file(self.context.session_id, filename))
        self.request.response.setHeader(
            'Content-Disposition',
            'attachment; filename="%s"' % filename)
        self.request.response.setHeader('Content-Type',
                                        'application/text')
        return results

class DownloadAll(grok.view):

    def render(self):
        return 'Not implemented'


# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------

import numpy as np
from ..common._registration import register_shape_calculator
from ..common.data_types import Int64TensorType, FloatTensorType

def calculate_sklearn_ordinal_encoder_output_shapes(operator):
    ordinal_op = operator.raw_operator
    op_features = sum(list(map(lambda x: x.type.shape[1], operator.inputs)))
    if np.issubdtype(ordinal_op.dtype, np.floating):
        operator.outputs[0].type = FloatTensorType(
            [operator.inputs[0].type.shape[0], op_features])
    else:
        operator.outputs[0].type = Int64TensorType(
            [operator.inputs[0].type.shape[0], op_features])

register_shape_calculator('SklearnOrdinalEncoder',
                          calculate_sklearn_ordinal_encoder_output_shapes)


# -*- encoding: utf-8 -*-
"""
@Author  :   VictorWong
@License :   (C) Copyright 2013-2019, Wuhan Guide Electric Technology com.,ltd.
@Contact :   victorwangms@163.com
@Software:   PyCharm
@File    :   debug_server.py
@Time    :   2019/4/29 8:15
@Desc    :
"""
import json
import os
import struct
import time
import traceback
from queue import Queue
from socket import socket, AF_INET, SOCK_STREAM, error
from threading import Thread, Lock

import numpy as np
from click._compat import raw_input

# 通信协议包头
HEADER = b'\x6f\x5f\x4f\x3f'

# 调试软件请求config文件指令码
ORDER_CONFIG = b'\x0f\x0f'
# 调试软件请求修改config指令码
ORDER_UPDATE_CONFIG = b'\x0f\x1f'
# 调试软件请求停止画图数据发送指令码
ORDER_STOP_PLOT = b'\x1f\x0f'
# 防打保龄业务请求开启画图
ORDER_STACK_PLOT = b'\x1f\x1f'
# 列车定位业务请求开启画图
ORDER_TRAIN_PLOT = b'\x1f\x2f'
# 集卡引导业务请求开启画图
ORDER_CHASSIS_PLOT = b'\x1f\x3f'
# 调试软件请求开启PLC通讯数据发送指令码
ORDER_START_PLC = b'\x2f\x0f'
# 调试软件请求停止PLC通讯数据发送指令码
ORDER_STOP_PLC = b'\x2f\x1f'
# 调试软件请求开启IRC通讯数据发送指令码
ORDER_START_IRC = b'\x3f\x0f'
# 调试软件请求停止IRC通讯数据发送指令码
ORDER_STOP_IRC = b'\x3f\x1f'
# 调试软件请求开启日志记录指令码
ORDER_LOG_SWITCH_ON = b'\x5f\x0f'
# 调试软件请求关闭日志记录指令码
ORDER_LOG_SWITCH_OFF = b'\x5f\x1f'
# 故障信息指令码
ORDER_ERROR = b'\x4f\x0f'

# 响应config文件修改成功
RESPONSE_CONFIG_OK = b'\x0f\xff'
# 响应关闭画图成功
RESPONSE_PLOT_OK = b'\x1f\xff'
# 响应关闭PLC通讯成功
RESPONSE_PLC_OK = b'\x2f\xff'
# 响应关闭IRC通讯成功
RESPONSE_IRC_OK = b'\x3f\xff'
# 响应日志记录关闭成功
RESPONSE_LOG_OK = b'\x5f\xff'

# 设备异常或程序故障
GENERAL_ERROR = b'\xff\xff\x00\x00'
# 工控机读取config文件错误
READ_CONFIG_ERROR = b'\xff\xff\x00\x01'
# 工控机config文件为空
CONFIG_EMPTY = b'\xff\xff\x00\x02'
# 操作端修改内存config错误
UPDATE_CONFIG_ERROR = b'\xff\xff\x00\x03'
# 修改操作端config后缓存失败
SAVE_CONFIG_ERROR = b'\xff\xff\x00\x04'
# 开启画图数据发送异常
START_PLOT_ERROR = b'\xff\xff\x00\x05'
# 关闭画图数据发送异常
STOP_PLOT_ERROR = b'\xff\xff\x00\x06'
# 开启日志记录异常
LOG_ON_ERROR = b'\xff\xff\x00\x07'
# 关闭日志记录异常
LOG_OFF_ERROR = b'\xff\xff\x00\x08'
# 开启PLC通讯异常
PLC_ON_ERROR = b'\xff\xff\x00\x09'
# 关闭PLC通讯异常
PLC_OFF_ERROR = b'\xff\xff\x00\x10'
# 开启IRC通讯异常
IRC_ON_ERROR = b'\xff\xff\x00\x11'
# 关闭IRC通讯异常
IRC_OFF_ERROR = b'\xff\xff\x00\x12'

def async_wrapper(func):
    def wrapper(*args, **kwargs):
        th = Thread(target=func, args=args, kwargs=kwargs)
        th.start()
        return th

    return wrapper

class DebugServer(object):
    def __init__(self, type_choice='sps'):
        # 服务器部署地址
        if type_choice == 'sps':
            self.server_address = ('0.0.0.0', 8181)
        elif type_choice == 'tps':
            self.server_address = ('0.0.0.0', 8282)
        elif type_choice == 'cps':
            self.server_address = ('0.0.0.0', 8383)
        self.sock = None
        # 用于储存操作端config数据
        self.config = None
        # 从调试端发送的数据
        self.data = None
        # 调试端的地址
        self.address = None
        # 连接调试端的套接字对象
        self.conn = None
        # socket监听轮询开关
        self.socket_flag = False
        # socket接收请求的轮询开关
        self.recv_flag = False
        # 处理调试端发送请求的轮询开关
        self.handle_requests_flag = False
        # 线程锁
        self.lock = Lock()
        # 记录不完整的请求数据
        self.data_cache = []
        # 箱高附加数据缓存
        self.box_height = None
        # 列车定位附加数据缓存
        self.train_data = None
        # 集卡引导附加数据缓存
        self.chassis_data = None
        # 日志路径缓存
        self.log_path = None
        # 配置文件的存储路径
        if self.server_address[1] == 8181:
            self.config_path = os.path.join(os.path.abspath(os.getcwd()), 'spsconfig.json')
        elif self.server_address[1] == 8282:
            self.config_path = os.path.join(os.path.abspath(os.getcwd()), 'tpsconfig.json')
        elif self.server_address[1] == 8383:
            self.config_path = os.path.join(os.path.abspath(os.getcwd()), 'cpsconfig.json')
        # 用于画图的xy坐标数据
        self.draw_data_x = []
        self.draw_data_y = []
        # 链接标志，True:有设备连入 FALSE：没有设备连接进来
        self.connect_flag = False

        self.PLC_msg = ''
        self.IRC_msg = ''
        self.Error_msg = ''

        self.q_data = Queue(30)
        self.q_response = Queue(30)

    def set_config(self, config):
        """
        初始化程序中的config
        :return:
        """
        self.config = config

    def set_Error_msg(self, msg):
        # 错误信息，包括扫描仪掉线，PLC断线，程序内部错误等信息
        self.Error_msg = msg

        command = HEADER + ORDER_ERROR + struct.pack('>l', 14 + len(
            self.Error_msg.encode('utf-8')))
        self.conn.send(command)

        # 获取PLC的信息

    def set_PLC_msg(self, msg):
        self.PLC_msg = msg

    def set_IRC_msg(self, msg):
        self.IRC_msg = msg

    def set_draw_data(self, x, y):
        # 画图数据x y坐标, 单位是m
        self.draw_data_x = x
        self.draw_data_y = y

    def set_box_height(self, box_height_list):
        # 获取17排箱子高度数据，单位是m
        self.box_height = box_height_list

    def set_train_data(self, box_type, middle_point):
        """
        设置列车定位的三字节信息数据，表述箱中心和箱的尺寸类型，单位是m
        :param train_data:
        :return:
        """
        if box_type == '20':
            self.train_data = b'\x02'
        else:
            self.train_data = b'\x04'
        if np.isnan(middle_point) or middle_point >= 30 or not middle_point:
            self.train_data += struct.pack('>h', 30000)
        else:
            self.train_data += struct.pack('>h', int(middle_point * 1000))

    def set_chassis_data(self, mountain_type, river_type, mountain_middle, river_middle):
        """
        设置集卡引导的9字节信息数据，分别表述山侧水侧的箱尺寸类型，箱的中心坐标，单位为m
        :param chassis_data:
        :return:
        """
        if mountain_type == '20':
            if river_type == '20':
                self.chassis_data = b'\x22'
            else:
                self.chassis_data = b'\x24'
        else:
            self.chassis_data = b'\x44'

        if np.isnan(mountain_middle) or mountain_middle >= 30 or not mountain_middle:
            self.chassis_data += struct.pack('>l', 30000)
        self.chassis_data += struct.pack('>l', int(mountain_middle * 1000))
        if np.isnan(river_middle) or river_middle >= 30 or not river_middle:
            self.chassis_data += struct.pack('>l', 30000)
        self.chassis_data += struct.pack('>l', int(river_middle * 1000))

    def set_log_path(self, log_path):
        """
        设置日志所在路径
        :param log_path:
        :return:
        """
        self.log_path = log_path

    def get_connect_flag(self):
        return self.connect_flag

    @async_wrapper
    def communication(self, conn, address):
        while self.recv_flag:
            try:
                self.data = conn.recv(10240)
                if self.data:
                    self.q_data.put(self.data)
            except error as e:
                print("Debug software at {} disconnect abnormal.{}".format(address, e))
                self.recv_flag = False
                self.connect_flag = False
                self.conn.close()
                break
            if not self.data:
                self.recv_flag = False
                self.connect_flag = False
                self.conn.close()
            time.sleep(0.1)

    def server_forever(self):
        self.sock = socket(AF_INET, SOCK_STREAM)
        self.sock.bind(self.server_address)
        self.sock.listen(10)
        print("listening...")
        try:
            self.get_requests()
        except Exception:
            print("Analysis requests from Debug end error." + traceback.format_exc())

        try:
            self.requests_handler()
        except Exception:
            print("Handle requests from Debug end error." + traceback.format_exc())
        while self.socket_flag:
            print('waiting...')
            self.conn, self.address = self.sock.accept()
            print("Debug software at {} connect success.".format(self.address))
            self.connect_flag = True
            self.recv_flag = True
            self.handle_requests_flag = True
            self.communication(self.conn, self.address)

            # try:
            #     self.get_requests()
            # except Exception:
            #     print("Analysis requests from Debug end error." + traceback.format_exc())
            #
            # try:
            #     self.requests_handler()
            # except Exception:
            #     print("Handle requests from Debug end error." + traceback.format_exc())

            time.sleep(0.1)

    @async_wrapper
    def get_requests(self):
        """
        异步解析出请求数据并放入容器
        :return:
        """
        while self.handle_requests_flag:
            if self.q_data.empty():
                time.sleep(0.1)
                continue
            data = self.q_data.get()
            nums = self.data.count(HEADER)
            if not nums:
                # 数据包中段也无包头
                self.data_cache.append(data)
                # 计算包是否完整, 数据长度，除去包头，指令码和数据长度
                data_len = struct.unpack('>l', self.data_cache[0][2:6])[0] - 10
                cur_len = 0
                for i in self.data_cache:
                    cur_len += len(i)
                if (cur_len - 6) == data_len:
                    # 已经拼接完整，直接处理
                    response = b''
                    for i in self.data_cache:
                        response += i
                    # 拼接玩后清除缓存，用于后续数据缓存
                    self.data_cache.clear()
                    self.q_response.put({response[:2]: response[6:]})
            else:
                requests = self.data.split(HEADER)
                # 包头位于数据包头时，除去切割头空元素
                if not requests[0]:
                    requests.remove(requests[0])
                # 数据包头包含上个数据包残余数据
                if nums < len(requests):
                    # 检测到包尾，可以用于拼接
                    self.data_cache.append(requests.pop(0))
                    if self.data_cache:
                        # 拼接得到完整数据
                        response = b''
                        for i in self.data_cache:
                            response += i
                        # 拼接玩后清除缓存，用于后续数据缓存
                        self.data_cache.clear()
                        self.q_response.put({response[:2]: response[6:]})
                for request in requests:
                    if len(request) < 6:
                        # 数据包头不完整，被分割到下个包了，需要拼接再解析
                        self.data_cache.append(request)
                    else:
                        # 数据长度解包后，除去包头，指令码和数据长度记录字节数
                        data_len = struct.unpack('>l', request[2: 6])[0] - 10
                        if not data_len:
                            # 没有附带数据的请求
                            self.q_response.put({request[:2]: None})
                            requests.remove(request)
                        elif len(request[6:]) != data_len:
                            # 请求数据不全可能还有数据在下一个包
                            self.data_cache.append(request)
                            requests.remove(request)
                        else:
                            # 附带数据的请求数据
                            self.q_response.put({request[:2]: request[6:]})
                            requests.remove(request)
            time.sleep(0.1)

    @async_wrapper
    def requests_handler(self):
        """
        异步轮询处理调试端发送过来的请求
        :return:`
        """
        while self.handle_requests_flag:
            if self.q_response.empty():
                time.sleep(0.1)
                continue
            command = self.q_response.get()
            # command是指令码，键值是请求数据
            if list(command)[0] == ORDER_CONFIG:
                # 请求config
                try:
                    self.response_config()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_UPDATE_CONFIG:
                # 请求修改config
                try:
                    self.response_update_config(command)
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_STACK_PLOT:
                # 请求发送画图数据
                try:
                    self.response_stack_plot()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_TRAIN_PLOT:
                # 请求发送画图数据
                try:
                    self.response_train_plot()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_CHASSIS_PLOT:
                # 请求发送画图数据
                try:
                    self.response_chassis_plot()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_STOP_PLOT:
                # 请求停止发送画图数据
                try:
                    self.response_stop_plot()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_START_PLC:
                # 请求开启PLC
                try:
                    self.response_start_plc()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_STOP_PLC:
                # 请求关闭PLC
                try:
                    self.response_stop_plc()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_START_IRC:
                # 请求开启IRC
                try:
                    self.response_start_irc()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_STOP_IRC:
                # 请求关闭IRC
                try:
                    self.response_stop_irc()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_LOG_SWITCH_ON:
                # 请求开启日志记录
                try:
                    self.response_log_switch_on()
                except Exception as e:
                    print(e)
            elif list(command)[0] == ORDER_LOG_SWITCH_OFF:
                # 请求关闭日志记录
                try:
                    self.response_log_switch_off()
                except Exception as e:
                    print(e)

            time.sleep(0.1)

    def response_config(self):
        """
        响应config文件数据
        :return:
        """
        try:
            with open(self.config_path, 'rb') as f:
                config_data = f.read()
            # 将config数据储存入内存
            self.config = json.loads(config_data.decode('utf-8'))
        except Exception as e:
            # 读取config文件失败，发送异常
            command = HEADER + ORDER_ERROR + struct.pack('>l', 14) + READ_CONFIG_ERROR
            self.conn.send(command)
            raise Exception("Read config file error.%s" % e)
        if not self.config:
            # config文件为空，响应
            command = HEADER + ORDER_ERROR + struct.pack('>l', 14) + CONFIG_EMPTY
            self.conn.send(command)
            return
        # 构造响应数据
        data_len = struct.pack('>l', len(HEADER) + len(ORDER_CONFIG) + len(config_data) + 4)
        command = HEADER + ORDER_CONFIG + data_len + config_data
        try:
            self.conn.sendall(command)
        except Exception as e:
            raise Exception("Response config error.%s" % e)

    def response_update_config(self, command):
        """
        响应修改config
        :return:
        """
        update_data = json.loads(command[list(command)[0]])
        failed_data = []
        for data in update_data:
            # 从调试端传输的json数据中遍历
            try:
                self.config.update({data: update_data[data]})
            except Exception as e:
                print(e)
                # 记录哪些数据修改失败，便于反馈
                failed_data.append(data)
        try:
            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 响应失败信息
            command = HEADER + ORDER_ERROR + struct.pack('>l', 14) + SAVE_CONFIG_ERROR
            try:
                self.conn.send(command)
            except Exception as e:
                raise Exception("Response saving updating config locally error message failed.%s" % e)
            raise Exception("After updating config, save config locally failed.%s" % e)
        if failed_data:
            # 响应失败信息
            failed_data = json.dumps({'failed_data': failed_data})
            data_len = struct.pack('>l', len(failed_data) + 14)
            command = HEADER + ORDER_ERROR + data_len + UPDATE_CONFIG_ERROR + failed_data.encode('utf-8')
            try:
                self.conn.sendall(command)
            except Exception as e:
                raise Exception("Response updating config error message failed.%s" % e)
            raise Exception("Handler updates config data failed some.")
        # 修改config文件成功
        command = HEADER + RESPONSE_CONFIG_OK + struct.pack('>l', 10)
        try:
            self.conn.send(command)
        except Exception as e:
            raise Exception("Response updating config success message failed.%s" % e)

    def response_stack_plot(self):
        """
        响应防打保龄开始画图
        :return:
        """
        # TODO 处理防打保龄画图数据的构造和发送
        try:
            self.config.update({'plotSwitch': True})

            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造错误响应数据
            command = HEADER + START_PLOT_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn plot switch on failed.%s" % e)
        # 开始响应画图数据
        try:
            self.send_stack_plot()
        except Exception as e:
            raise Exception("Send plot data error.%s" % e)

    @async_wrapper
    def send_stack_plot(self):
        # 发送画图数据
        while self.config.get('plotSwitch'):
            if not self.box_height:
                time.sleep(0.1)
                continue
            plot_data = b''.join([struct.pack('>l', int(i * 1000)) for i in self.draw_data_x])
            plot_data += b''.join([struct.pack('>l', int(i * 1000)) for i in self.draw_data_y])
            # 数据前添加34字节的箱高参数
            box_height_data = b''.join([struct.pack('>H', int(i * 1000)) for i in self.box_height])
            command = HEADER + ORDER_STACK_PLOT + struct.pack('>l',
                                                              10 + len(plot_data) + 34) + box_height_data + plot_data
            try:
                self.conn.sendall(command)
            except Exception:
                print(traceback.format_exc())
                self.config.update({'plotSwitch': False})
                with open(self.config_path, 'w') as f:
                    json.dump(self.config, f)
                break
            time.sleep(0.1)

    def response_train_plot(self):
        # TODO 处理列车定位画图数据的构造和发送
        try:
            self.config.update({'plotSwitch': True})

            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造错误响应数据
            command = HEADER + START_PLOT_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn plot switch on failed.%s" % e)
        # 开始响应画图数据
        try:
            self.send_train_plot()
        except Exception as e:
            raise Exception("Send plot data error.%s" % e)

    @async_wrapper
    def send_train_plot(self):
        # 发送画图数据
        while self.config.get('plotSwitch'):
            if not self.train_data:
                time.sleep(0.1)
                continue
            # 单位转换为mm传输
            plot_data = b''.join([struct.pack('>l', int(i * 1000)) for i in self.draw_data_x])
            plot_data += b''.join([struct.pack('>l', int(i * 1000)) for i in self.draw_data_y])
            # 在数据前添加3字节的箱中心和箱尺寸数据
            command = HEADER + ORDER_TRAIN_PLOT + struct.pack('>l',
                                                              10 + len(plot_data) + 3) + self.train_data + plot_data
            try:
                self.conn.sendall(command)
            except Exception:
                print(traceback.format_exc())
                self.config.update({'plotSwitch': False})
                with open(self.config_path, 'w') as f:
                    json.dump(self.config, f)
                break
            time.sleep(0.1)

    def response_chassis_plot(self):
        # TODO 处理集卡引导画图数据的构造和发送
        try:
            self.config.update({'plotSwitch': True})

            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造错误响应数据
            command = HEADER + START_PLOT_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn plot switch on failed.%s" % e)
        # 开始响应画图数据
        try:
            self.send_chassis_plot()
        except Exception as e:
            raise Exception("Send plot data error.%s" % e)

    @async_wrapper
    def send_chassis_plot(self):
        # 发送画图数据
        while self.config.get('plotSwitch'):
            if not self.chassis_data:
                time.sleep(0.1)
                continue
            plot_data = b''.join([struct.pack('>l', int(i * 1000)) for i in self.draw_data_x])
            plot_data += b''.join([struct.pack('>l', int(i * 1000)) for i in self.draw_data_y])
            # 附加9字节的集卡引导箱数据
            command = HEADER + ORDER_CHASSIS_PLOT + struct.pack('>l',
                                                                10 + len(plot_data) + 9) + self.chassis_data + plot_data
            try:
                self.conn.sendall(command)
            except Exception:
                print(traceback.format_exc())
                self.config.update({'plotSwitch': False})
                with open(self.config_path, 'w')as f:
                    json.dump(self.config, f)
                break
            time.sleep(0.1)

    def response_stop_plot(self):
        """
        响应停止画图
        :return:
        """
        try:
            self.config.update({'plotSwitch': False})

            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造错误响应数据
            command = HEADER + STOP_PLOT_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn plot switch on failed.%s" % e)
        # 关闭画图成功，响应
        command = HEADER + RESPONSE_PLOT_OK + struct.pack('>l', 10)
        self.conn.send(command)

    def response_start_plc(self):
        """
        响应开启PLC
        :return:
        """
        try:
            self.config.update({'PLCSwitch': True})
            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造异常响应
            command = HEADER + PLC_ON_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn PLC switch on failed.%s" % e)
        # 发送PLC通讯信息
        self.send_plc_info()

    @async_wrapper
    def send_plc_info(self):
        """
        发送PLC信息
        :return:
        """
        while self.config.get('PLCSwitch'):
            try:
                if self.PLC_msg:
                    command = HEADER + ORDER_START_PLC + struct.pack('>l', 10 + len(
                        self.PLC_msg.encode('utf-8'))) + self.PLC_msg.encode('utf-8')
                    self.conn.sendall(command)
            except Exception as e:
                print(e)
                self.config.update({'PLCSwitch': False})
                with open(self.config_path, 'w') as f:
                    json.dump(self.config, f)
                break
            time.sleep(1)

    def response_stop_plc(self):
        """
        响应停止PLC
        :return:
        """
        try:
            self.config.update({'PLCSwitch': False})
            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造异常响应
            command = HEADER + PLC_ON_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn PLC switch off failed.%s" % e)
        # 关闭PLC通讯成功
        command = HEADER + RESPONSE_PLC_OK + struct.pack('>l', 10)
        self.conn.send(command)

    def response_start_irc(self):
        """
        响应开启IRC
        :return:
        """
        try:
            self.config.update({'IRCSwitch': True})
            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造异常响应
            command = HEADER + IRC_ON_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn PLC switch on failed.%s" % e)
        # 发送PLC通讯信息
        self.send_irc_info()

    @async_wrapper
    def send_irc_info(self):
        while self.config.get('IRCSwitch'):
            try:
                if self.IRC_msg:
                    command = HEADER + ORDER_START_IRC + struct.pack('>l', 10 + len(
                        self.IRC_msg.encode('utf-8'))) + self.IRC_msg.encode('utf-8')
                    try:
                        self.conn.sendall(command)
                    except Exception:
                        print(traceback.format_exc())
                        self.config.update({'IRCSwitch': False})
                        with open(self.config_path, 'w') as f:
                            json.dump(self.config, f)
                        break
            except Exception as e:
                print(e)
            time.sleep(1)

    def response_stop_irc(self):
        """
        响应停止IRC
        :return:
        """
        try:
            self.config.update({'IRCSwitch': False})
            with open(self.config_path, 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造异常响应
            command = HEADER + PLC_ON_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn PLC switch off failed.%s" % e)
        # 关闭PLC通讯成功
        command = HEADER + RESPONSE_IRC_OK + struct.pack('>l', 10)
        self.conn.send(command)

    def response_log_switch_on(self):
        """
        处理开启日志请求并响应
        :return:
        """
        try:
            # 开启日志记录
            self.config.update({'logSwitch': True})

            with open(os.path.join(self.config_path), 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造异常信息响应
            command = HEADER + LOG_ON_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Turn log switch on failed.%s" % e)
        # 处理成功，发送成功响应
        command = HEADER + ORDER_LOG_SWITCH_ON + struct.pack('>l', 10 + len(
            self.log_path.encode('utf-8'))) + self.log_path.encode('utf-8')
        self.conn.send(command)

    def response_log_switch_off(self):
        """
        处理关闭日志请求并响应
        :return:
        """
        try:
            # 关闭日志记录
            self.config.update({'logSwitch': False})

            with open(os.path.join(self.config_path), 'w') as f:
                json.dump(self.config, f)
        except Exception as e:
            # 构造异常信息响应
            command = HEADER + LOG_OFF_ERROR + struct.pack('>l', 12)
            self.conn.send(command)
            raise Exception("Log switch on failed.%s" % e)
        # 处理成功，发送成功响应
        command = HEADER + RESPONSE_LOG_OK + struct.pack('>l', 10)
        self.conn.send(command)

if __name__ == '__main__':
    type = raw_input("请输入业务种类（防打保龄sps, 列车定位tps, 集卡引导cps）:")
    server = DebugServer(type)
    server.socket_flag = True
    server.handle_requests_flag = True

    server.server_forever()


import logging
import logging.handlers
import datetime

import config

async def utc_from_ts(timestamp):
    """Get a UTC string from a unix timestamp
    Specifically, for getting the launch time, so if timestamp is not an int, returns
    "To Be Announced"
    """
    try:
        formatted_date = datetime.datetime.utcfromtimestamp(timestamp).strftime(
            "%Y-%m-%d %H:%M:%S"
        )
        return f"{formatted_date} UTC"
    except TypeError:
        # timestamp is not int
        return "To Be Announced"

async def setup_logging():
    """Setup logging
    These settings will apply to any logging.info, error, debug, etc. call from now on
    This uses logging.basicConfig to setup the logging usage, which means this function
    has to be called before anything else even imports logging, otherwise the
    configuration set by this will not be used
    """
    log_file_handler = logging.handlers.TimedRotatingFileHandler(
        filename=config.LOG_PATH, when="W0", backupCount=10, encoding="UTF-8"
    )
    log_file_handler.setFormatter(logging.Formatter(config.LOG_FORMAT))

    logging.basicConfig(level=config.LOG_LEVEL, handlers=[log_file_handler])

    # Change discord to only log ERROR level and above
    logging.getLogger("discord").setLevel(logging.ERROR)


# -- coding: utf-8 --
import argparse
import json
import inspect
import re
from abc import ABCMeta, abstractmethod
from pathlib import Path
import feather
import sys
import os
import pandas as pd
import numpy as np
import category_encoders as ce
import seaborn as sns
from sklearn.ensemble import IsolationForest
sys.path.append(os.getcwd())

#Input Dataframe取得
def get_origin_dataframe():
    train = feather.read_dataframe('./data/input/train.feather')
    test = feather.read_dataframe('./data/input/test.feather')
    return train, test

#前処理済みDataframe取得
def get_preprocessing_dataframe():
    X_train = feather.read_dataframe('./data/input/finish_preprocessing_X_train.feather')
    Y_train = feather.read_dataframe('./data/input/finish_preprocessing_Y_train.feather')
    X_test = feather.read_dataframe('./data/input/finish_preprocessing_X_test.feather')
    return X_train, Y_train, X_test

#ベースラインDataframe取得
def get_base_line_dataframe():
    X_train = feather.read_dataframe('./data/input/base_line_train.feather')
    X_test = feather.read_dataframe('./data/input/base_line_test.feather')
    return X_train, X_test

#生成した特徴量のDataframe取得
def get_create_features_dataframe():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', default='./configs/default.json')
    options = parser.parse_args()
    config = json.load(open(options.config))

    features_list = config["features"]
    df_train = pd.DataFrame(index=[], columns=[])
    df_test = pd.DataFrame(index=[], columns=[])
    for feature in features_list:
        df_feat_train = feather.read_dataframe('./features/feather/{}_train.feather'.format(feature))
        df_feat_test = feather.read_dataframe('./features/feather/{}_test.feather'.format(feature))
        df_train = pd.concat([df_train,df_feat_train],axis=1)
        df_test = pd.concat([df_test,df_feat_test],axis=1)
    return df_train, df_test

def get_dataframe_set(df_train, df_test):
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', default='./configs/default.json')
    options = parser.parse_args()
    config = json.load(open(options.config))

    # 予測に使わないIDを保持・データフレームから削除
    ID = config["ID_name"]
    TARGET = config["target_name"]
    df_train.drop([ID], axis=1, inplace=True)
    df_test.drop([ID], axis=1, inplace=True)

    # 目的変数を別に取っておく
    y_train = df_train[TARGET].values
    df_train.drop([TARGET], axis=1, inplace=True)

    # 学習用データとテストデータの境目のインデックスを保持
    train_test_split_index = len(df_train)

    # 学習用データとテストデータを一度統合する
    df_all = pd.concat((df_train, df_test), ignore_index=True)

    return df_all, y_train, train_test_split_index

def check_columns_size(train, test):
    if  train.shape[1] != test.shape[1]:
        print("-------Warning ! : columns size not same :{} and {}-------".format(train.shape[1],test.shape[1]))

#カテゴリ変数のカラムリスト取得
def get_category_columns(df):
    categoricals = df.dtypes[df.dtypes == "object"].index.values.tolist()
    return categoricals

#数値変数のカラムリスト取得
def get_number_columns(df):
    numbers = df.dtypes[df.dtypes != "object"].index.values.tolist()
    return numbers

#one hot encoding (カテゴリ)
def one_hot_encoding(df):
    ce_ohe = ce.OneHotEncoder(cols=df.columns.tolist(), use_cat_names=True, drop_invariant=True)
    df_onehot = ce_ohe.fit_transform(df)
    return df_onehot

def one_hot_encoding_train_test(train, test):
    ce_ohe = ce.OneHotEncoder(cols=train.columns.tolist(), use_cat_names=True, drop_invariant=True)
    ce_ohe.fit(train)
    train_one_hot = ce_ohe.transform(train)
    test_one_hot = ce_ohe.transform(test)
    print(test_one_hot.shape[1])
    print(train_one_hot.shape[1])
    print(test_one_hot.shape[1]>train_one_hot.shape[1])
    if  train_one_hot.shape[1] < test_one_hot.shape[1]:
        train_one_hot = ce_ohe.transform(train)
        test_one_hot = ce_ohe.transform(test)
    return train_one_hot, test_one_hot

#ordinal encoding (カテゴリ)
def ordinal_encoding(df):
    ce_ord = ce.OrdinalEncoder(cols=df.columns.tolist())
    df_ord = ce_ord.fit_transform(df)
    return df_ord

#ordinal encoding (カテゴリの順序を考慮して ordinal encoding)
#dict : カテゴリと順序
def ordinal_ordered_encoding(df, column, dict):
    df_map = pd.DataFrame(df[column].map(dict), index=df.index.values)
    df_map = df_map.rename(columns={df_map.columns[0] : "{}".format(column)+"_ordered"})
    return df_map

#ターゲットエンコーディング
def target_encoding(df_train, df_valid, column, target):
    target = pd.DataFrame(target, columns=["target"])

    df_train.reset_index(drop=True, inplace=True)
    df_valid.reset_index(drop=True, inplace=True)
    target.reset_index(drop=True, inplace=True)
    df_valid = pd.concat([df_valid[column], target], axis=1)
    df_target = df_valid.groupby([column]).sum()
    se_target = pd.Series(df_target["target"], index=df_target.index)

    for c in df_train[column].value_counts().index:
        if c not in df_valid[column].value_counts().index:
            se_target[c] = 0
    se_target = se_target / len(se_target)
    dict = se_target.to_dict()
    df = pd.DataFrame(df_train[column].replace(dict))
    df.columns = ["{}_target".format(column)]

    return df

#カウントエンコーディング
def count_encoding(df, column):
    dict = df[column].value_counts().to_dict()
    count = df[column].replace(dict)
    count = pd.DataFrame(count)
    count.columns=["{}_count".format(column)]
    return count

#ランクカウントエンコーディング
def rank_count_encoding(df, columns_list):
    df_new = pd.DataFrame(index=df.index, columns=[])
    for column in columns_list:
        count_rank = df.groupby(column).transform("count").rank(ascending=False)
        df_new['{}_count_rank'.format(column)] = df[column].map(count_rank)
    return df_new

#単位円に変換(周期)
def circle_encoding(df, columns_list):
    df_new = pd.DataFrame(index=df.index, columns=[])
    for column in columns_list:
        max = df[column].max()
        df_new["{}_sin".format(column)] = df[column].apply(lambda x: np.sin((x / max) * 2 * round(np.pi, 2)))
        df_new["{}_cos".format(column)] = df[column].apply(lambda x: np.cos((x / max) * 2 * round(np.pi, 2)))
    return df_new

def binning(df, column ,num=8):
    df_new = pd.DataFrame(index=df.index, columns=[])
    df_new["{}_bin".format(column)] = pd.cut(df[column], num, labels=False)
    return df_new

#dfのカテゴリ変数をone hot encoding
def category_columns_to_one_hot(df):
    category_list = get_category_columns(df)
    df_one_hot = one_hot_encoding(df[category_list])
    return df_one_hot

#dfのカテゴリ変数をone hot encoding
def category_columns_to_one_hot_train_test(train, test):
    category_list = get_category_columns(train)
    df_one_hot_train, df_one_hot_test = one_hot_encoding_train_test(train[category_list], test[category_list])
    return df_one_hot_train, df_one_hot_test

#数値カラムにNANフラグを立てる
def get_nan_flag(df_train, df_test):
    #欠損値を含む数値カラム
    df_new = pd.DataFrame(index=[], columns=[])
    null_number_list = get_number_columns(df_train[df_train.isnull().any()[df_train.isnull().any() == True].index])
    split_index = len(df_train)
    df = pd.concat([df_train, df_test])
    for column in null_number_list:
        df_new["{}_is_nan".format(column)] = df[column].apply(lambda x : 1 if np.isnan(x) else 0)
    df_train = df_new[:split_index]
    df_test = df_new[split_index:].reset_index(drop=True)
    return df_train, df_test

#ゼロフラグを立てる
def get_zero_flag(df, percent):
    df_new = pd.DataFrame(index=df.index, columns=[])
    number_list = get_number_columns(df)
    sum = len(df)
    for column in number_list:
        if ((df[column]==0).sum() / sum) > percent:
            df_new["{}_is_zero".format(column)] = df[column].apply(lambda x: 1 if x == 0 else 0)
    return df_new

#ゼロの割合
def get_zero_percent(df):
    df_new = pd.DataFrame(index=df.index, columns=[])
    number_list = get_number_columns(df)
    sum = len(df)
    for column in number_list:
        zero_per = (df[column]==0).sum() / sum
        if  zero_per != 0 and zero_per != 1:
            df_new["{}_is_zero".format(column)] = df[column].apply(lambda  x: zero_per if x == 0 else 0)
    return df_new

#none→np.nan
def none_to_nan(df):
    for column in df.columns.values:
        df[column] = df[column].apply(lambda x : np.nan if x == None or x=="None" or x=="NONE" or x=="none" or x=="Nan" or x=="nan" or x=="NAN" else x)

#外れ値除去
def outliers_delete(X_train,y_train, percent=0.05):
    clf = IsolationForest(random_state=3, n_estimators=500, contamination=percent, behaviour='new')
    clf.fit(X_train)
    mv_outliers = pd.DataFrame(clf.predict(X_train))
    mv_outliers.columns = ['OutlierFlag']
    print("outlier counts : {}".format(mv_outliers[mv_outliers == -1].count()))
    y = pd.DataFrame(y_train)
    y.columns = ['Target']
    df_all_olcheck = pd.concat([mv_outliers, X_train, y], axis=1)
    df_all_r = df_all_olcheck[df_all_olcheck['OutlierFlag'] == 1].copy()
    df_all_r.drop("OutlierFlag", axis=1, inplace=True)
    y_train_r = df_all_r["Target"].values
    df_all_r.drop(["Target"], axis=1, inplace=True)
    return df_all_r, y_train_r

#相関の高いカラム取得
def high_corr(X_train, percent):
    list = []
    #共分散行列
    corr = X_train.corr()
    #上三角行列
    tri = pd.DataFrame(np.triu(corr, k=1), index=corr.index, columns=corr.index)

    for column in corr.columns:
        for index in corr.index:
            if tri[column][index] > percent or tri[column][index] < -percent:
                list.append((column, index))
    return list

#ターゲットと相関の高いDataframe取得
def high_corr_target(train):
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', default='./configs/default.json')
    options = parser.parse_args()
    config = json.load(open(options.config))

    #共分散行列
    corr = train.corr()
    #ターゲットとの相関
    c = corr[config["target_name"]].apply(lambda x: np.fabs(x)).sort_values(ascending=False)
    c = c.drop([config["target_name"]])
    df_c = pd.DataFrame(c.values, index=c.index, columns=["corr_to_target"])
    return df_c


#!/usr/bin/python

import datetime
import os
import re
import logging
import gzip
import sys
import threading
import traceback
import time

import requests

from gdt.logparse import gokoparse
from gdt.model import db_manager
import gdt.ratings.gdt_trueskill as ts

logging.basicConfig(level=logging.INFO)

LINK_REGEX = re.compile('href="(log\S*txt)"')
FILE_REGEX = re.compile("log\.(.*)\.(.*)\.txt")

# Download up to 200 logs simultaneously
sema = threading.BoundedSemaphore(value=200)

# Download a log and save it to file
def download_log(logfile, dayurl, log_dir):
    headers = {'Accept-Encoding': 'gzip, deflate'}
    url = dayurl + '/' + logfile
    logging.debug('Fetching %s' % url)
    r = requests.get(url, headers=headers)
    sema.release()
    gzip.open(log_dir + '/' + logfile, 'wt').write(r.text)

def download_new_logs(date):

    datestr = date.strftime('%Y%m%d')
    #dayurl = 'http://dominionlogs.goko.com/%s' % datestr
    dayurl = 'http://logs.prod.dominion.makingfun.com/%s' % datestr
    r = requests.get(dayurl)
    remote_logs = LINK_REGEX.findall(r.text)

    # Determine which logs haven't already been downloaded
    log_dir = '/mnt/raid/media/dominion/logs/%s' % datestr
    if not os.path.isdir(log_dir):
        os.makedirs(log_dir)
    local_logs = os.listdir(log_dir)
    not_downloaded = set(remote_logs) - set(local_logs)
    logging.info('Found %d new logs on Goko' % len(not_downloaded))

    # Download logs in threads.  Restrict max number of connections using
    # BoundedSemahore
    i = 0
    threads = []
    for lf in not_downloaded:
        i += 1
        sema.acquire()
        t = threading.Thread(target=download_log,
                             kwargs={'logfile': lf, 'dayurl': dayurl,
                                     'log_dir': log_dir})
        threads.append(t)
        t.start()

    # Wait for downloading to finish
    for t in threads:
        t.join()

    logging.info('Finished downloading')

def parse_new_logs(date):

    # Determine which logs we have downloaded but not yet parsed
    log_dir = '/mnt/raid/media/dominion/logs/%s' % date.strftime('%Y%m%d')
    local_logs = os.listdir(log_dir)
    dblogs = db_manager.search_daily_log_filenames(date)
    not_parsed = set(local_logs) - set(dblogs)
    logging.info('Found %d downloaded logs to be parsed' % len(not_parsed))

    # Parse the unparsed logs
    games = []
    failed = {}
    for logfile in not_parsed:
        (loghash, logtime) = FILE_REGEX.match(logfile).group(1, 2)
        logtime = datetime.datetime.fromtimestamp(int(logtime) / 1000)

        fail = False
        logfile_full = log_dir + '/' + logfile
        try:
            logtext = gzip.open(logfile_full, 'rt', encoding='utf-8').read()
        except:
            try:
                logtext = open(logfile_full, 'rt', encoding='utf-8').read()
            except:
                logging.warn('Cannot read file: ' + logfile_full)
                failed[logfile] = sys.exc_info()
                fail = True
        if not fail:
            try:
                game = gokoparse.parse_goko_log(logtext)
                game.logfile = logfile
                game.time = logtime
                games.append(game)
                if len(games) % 100 == 0:
                    logging.info('Parsed %d' % len(games))
            except:
                failed[logfile] = sys.exc_info()

    logging.info('Finished parsing')
    logging.info('%d games parsed' % len(games))
    logging.info('%d games failed' % len(failed))

    # Insert parsed games into database, 100 at a time
    # TODO: Logs are read in file order, not chronological order.  This
    # is a (minor) violation of the TrueSkill algorithm: a game played at
    # 11:59 PM might be processed before one played at 12:00 AM on the
    # same day (almost 24 hours earlier).
    count = 0
    total_inserted = 0
    try:
        db_manager.inserts(games)
        # Update ratings
        count = -1
        while count != 0:
          x = db_manager.get_last_rated_game()
          if x:
            (t, l) = x
          else:
            (t, l) = (None, None)

          count = ts.record_ratings(100, t, l, ts.isodominion_env)
          total_inserted += count
    except:
        logging.info(sys.exc_info())

    logging.info('inserted %d parsed games into DB' % total_inserted)

    # Notify of failed logs.  Record in database.
    for f in failed:
        logging.warn('Failed to parse: %s in %s' % (failed[f][0].__name__, f))
        for line in traceback.format_tb(failed[f][2]):
            logging.warn(line)
        #TODO: record failures
        db_manager.insert_parsefail(f)

    return total_inserted

if __name__ == '__main__':
    if len(sys.argv) == 3:
        start_dir = sys.argv[1]
        if sys.argv[2] == 'd':
            logging.info('Downloading and parsing logs starting on %s' + sys.argv[1])
            date = datetime.datetime.strptime(sys.argv[1], '%Y%m%d')
            while date < datetime.datetime.now():
                logging.info('Downloading and parsing logs for %s' + date.strftime('%-%m-%d'))
                download_new_logs(date)
                parse_new_logs(date)
        else:
            logging.error('Check usage.')
    elif len(sys.argv) == 2:
        start_dir = sys.argv[1]
        logging.info('Parsing ALL previous downloaded logs after %s.  This may take a while.' + sys.argv[1])
        for log_dir in sorted(os.listdir('/mnt/raid/media/dominion/logs')):
            if log_dir > start_dir:
                if re.match('\d{8}', log_dir):
                    log_day = datetime.datetime.strptime(log_dir, '%Y%m%d')
                    logging.info('Parsing logs from %s' % log_day.strftime('%Y-%m-%d'))
                    parse_new_logs(log_day)
    else:
        logging.warn('Now watching for new logs to be posted to the Goko log server.')
        logging.warn('Note: Games played before 12:00 AM today will not be handled.\n')

        next_day = datetime.datetime.now()
        while True:
            # This ensures that we don't miss the very last logs posted before
            # the date ticks over at midnight.  We're guaranteed to search for
            # "yesterday's" logs at least once "today."
            # NOTE we can still lose logs if the local system's time gets ahead
            # of Goko's server time.  Might be better to have a 10 minute
            # window (12:00-12:10AM) in which we search for both yesterday's
            # and today's logs.
            next_day = datetime.datetime.now()
            parsecount = 0
            try:
                download_new_logs(next_day)
                parsecount = parse_new_logs(next_day)
            except:
                # TODO: Do something about these errors
                logging.error(sys.exc_info()[1])
                logging.error(sys.exc_info()[2])
                pass
            print('Found %d new logs. Checking again in 5 seconds.' % parsecount)
            print()
            time.sleep(5)