# coding: utf-8

"""
    Schemas

    The CRM uses schemas to define how custom objects should store and represent information in the HubSpot CRM. Schemas define details about an object's type, properties, and associations. The schema can be uniquely identified by its **object type ID**.  # noqa: E501

    The version of the OpenAPI document: v3
    Generated by: https://openapi-generator.tech
"""

try:
    from inspect import getfullargspec
except ImportError:
    from inspect import getargspec as getfullargspec
import pprint
import re  # noqa: F401
import six

from hubspot.crm.schemas.configuration import Configuration

class PropertyModificationMetadata(object):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    """
    Attributes:
      openapi_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    openapi_types = {"archivable": "bool", "read_only_definition": "bool", "read_only_options": "bool", "read_only_value": "bool"}

    attribute_map = {"archivable": "archivable", "read_only_definition": "readOnlyDefinition", "read_only_options": "readOnlyOptions", "read_only_value": "readOnlyValue"}

    def __init__(self, archivable=None, read_only_definition=None, read_only_options=None, read_only_value=None, local_vars_configuration=None):  # noqa: E501
        """PropertyModificationMetadata - a model defined in OpenAPI"""  # noqa: E501
        if local_vars_configuration is None:
            local_vars_configuration = Configuration.get_default_copy()
        self.local_vars_configuration = local_vars_configuration

        self._archivable = None
        self._read_only_definition = None
        self._read_only_options = None
        self._read_only_value = None
        self.discriminator = None

        self.archivable = archivable
        self.read_only_definition = read_only_definition
        if read_only_options is not None:
            self.read_only_options = read_only_options
        self.read_only_value = read_only_value

    @property
    def archivable(self):
        """Gets the archivable of this PropertyModificationMetadata.  # noqa: E501

        :return: The archivable of this PropertyModificationMetadata.  # noqa: E501
        :rtype: bool
        """
        return self._archivable

    @archivable.setter
    def archivable(self, archivable):
        """Sets the archivable of this PropertyModificationMetadata.

        :param archivable: The archivable of this PropertyModificationMetadata.  # noqa: E501
        :type archivable: bool
        """
        if self.local_vars_configuration.client_side_validation and archivable is None:  # noqa: E501
            raise ValueError("Invalid value for `archivable`, must not be `None`")  # noqa: E501

        self._archivable = archivable

    @property
    def read_only_definition(self):
        """Gets the read_only_definition of this PropertyModificationMetadata.  # noqa: E501

        :return: The read_only_definition of this PropertyModificationMetadata.  # noqa: E501
        :rtype: bool
        """
        return self._read_only_definition

    @read_only_definition.setter
    def read_only_definition(self, read_only_definition):
        """Sets the read_only_definition of this PropertyModificationMetadata.

        :param read_only_definition: The read_only_definition of this PropertyModificationMetadata.  # noqa: E501
        :type read_only_definition: bool
        """
        if self.local_vars_configuration.client_side_validation and read_only_definition is None:  # noqa: E501
            raise ValueError("Invalid value for `read_only_definition`, must not be `None`")  # noqa: E501

        self._read_only_definition = read_only_definition

    @property
    def read_only_options(self):
        """Gets the read_only_options of this PropertyModificationMetadata.  # noqa: E501

        :return: The read_only_options of this PropertyModificationMetadata.  # noqa: E501
        :rtype: bool
        """
        return self._read_only_options

    @read_only_options.setter
    def read_only_options(self, read_only_options):
        """Sets the read_only_options of this PropertyModificationMetadata.

        :param read_only_options: The read_only_options of this PropertyModificationMetadata.  # noqa: E501
        :type read_only_options: bool
        """

        self._read_only_options = read_only_options

    @property
    def read_only_value(self):
        """Gets the read_only_value of this PropertyModificationMetadata.  # noqa: E501

        :return: The read_only_value of this PropertyModificationMetadata.  # noqa: E501
        :rtype: bool
        """
        return self._read_only_value

    @read_only_value.setter
    def read_only_value(self, read_only_value):
        """Sets the read_only_value of this PropertyModificationMetadata.

        :param read_only_value: The read_only_value of this PropertyModificationMetadata.  # noqa: E501
        :type read_only_value: bool
        """
        if self.local_vars_configuration.client_side_validation and read_only_value is None:  # noqa: E501
            raise ValueError("Invalid value for `read_only_value`, must not be `None`")  # noqa: E501

        self._read_only_value = read_only_value

    def to_dict(self, serialize=False):
        """Returns the model properties as a dict"""
        result = {}

        def convert(x):
            if hasattr(x, "to_dict"):
                args = getfullargspec(x.to_dict).args
                if len(args) == 1:
                    return x.to_dict()
                else:
                    return x.to_dict(serialize)
            else:
                return x

        for attr, _ in six.iteritems(self.openapi_types):
            value = getattr(self, attr)
            attr = self.attribute_map.get(attr, attr) if serialize else attr
            if isinstance(value, list):
                result[attr] = list(map(lambda x: convert(x), value))
            elif isinstance(value, dict):
                result[attr] = dict(map(lambda item: (item[0], convert(item[1])), value.items()))
            else:
                result[attr] = convert(value)

        return result

    def to_str(self):
        """Returns the string representation of the model"""
        return pprint.pformat(self.to_dict())

    def __repr__(self):
        """For `print` and `pprint`"""
        return self.to_str()

    def __eq__(self, other):
        """Returns true if both objects are equal"""
        if not isinstance(other, PropertyModificationMetadata):
            return False

        return self.to_dict() == other.to_dict()

    def __ne__(self, other):
        """Returns true if both objects are not equal"""
        if not isinstance(other, PropertyModificationMetadata):
            return True

        return self.to_dict() != other.to_dict()


# uncompyle6 version 3.7.4
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /Users/prihodad/Documents/projects/visitor/golm/golm/core/message_logger.py
# Compiled at: 2018-04-15 16:14:23
# Size of source mod 2**32: 771 bytes
from celery import shared_task

@shared_task
def on_message(uid, chat_id, message_text, dialog, from_user):
    from golm_admin.models import User, Chat, Message
    if chat_id is None:
        chat_id = uid
    user, was_created = User.objects.get_or_create(uid=uid, defaults={'uid': uid})
    if was_created:
        user.save()
    chat, was_created = Chat.objects.get_or_create(chat_id=chat_id, defaults={'chat_id':chat_id,  'user_uid':user})
    if was_created:
        chat.save()
    message = Message()
    message.chat = chat
    message.text = message_text
    message.is_from_user = from_user
    message.intent = dialog.context.get('intent', max_age=0)
    message.state = dialog.current_state_name
    message.save()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Sep  9 17:02:15 2019

@author: han
"""

names = ["Josh","Courtney","Salvatore","Terence","Shelia","Christie","Jane"]

surnames = ["Lopez","Nunez","Pearson","Hudson","Martin","Vaughn","Tucker"]

for i,j in zip(names,surnames):
    print(i,j)


from functions import *

def main():
    # Check if some excel file has not been converted into csv yet
    check_for_excel_files()
    turtlesData = getTurtlesData()

    # see instances for Obj turtleData created and its dfs
    checkInstancesAndItsDfs(turtlesData)
    #turtlesData[0].df
    #turtlesData[1].df

    # build dfs of all gps
    getAllGpsDataframes(turtlesData)

    # see dfs of all gps
    displayAllGpsDf(turtlesData)
    # or
    #turtlesData[0].allGpsDf
    #turtlesData[1].allGpsDf

    # get name for each ALL GPS DF turtleData
    createAllGpsDfCsvNameForEachInstance(turtlesData)

    # SAVE THE ALL GPS DATAFRAME in the Results Folder
    checkIfAllGpsDfHasBeenSaved(turtlesData)

    #
    assignTagDayDatetimeToEachInstance(turtlesData)

    # now we need to look at the all gps df and delete the duplicates rows, before calculating the errors by speed
    # deleting duplicate rows and 2019 date
    getAllCleanedGpsDataframes(turtlesData)

    # get name for each ALL CLEANED GPS DF turtleData
    createAllCleanedGpsDfCsvNameForEachInstance(turtlesData)

    # SAVE THE ALL CLEANED GPS DATAFRAME in the Results Folder
    checkIfAllCleanedGpsDfHasBeenSaved(turtlesData)

    # see dfs of reliable gps (Remove GPS Errors by Angular velocity/Rotational speed)
    getReliableGpsDataframes(turtlesData)

    # get name for each RELIABLE GPS DF turtleData
    createReliableGpsDfCsvNameForEachInstance(turtlesData)

    # SAVE THE RELIABLE GPS DATAFRAME in the Results Folder
    checkIfReliableGpsDfHasBeenSaved(turtlesData)

    # get name for each NO RELIABLE GPS DF turtleData
    createNoReliableGpsDfCsvNameForEachInstance(turtlesData)

    # SAVE THE NO RELIABLE GPS DATAFRAME in the Results Folder
    checkIfNoReliableGpsDfHasBeenSaved(turtlesData)

    # Clean Data, filtering 'no GPS Data' from 'GPS Data'

if __name__ == "__main__":
    main()


from nltk.sentiment.vader import SentimentIntensityAnalyzer
import string
import re
import nltk
import os
import numpy as np
import pandas as pd
import tweepy
import sys
from textblob import TextBlob
from nltk.corpus import stopwords
def final():
    stoplist = set(stopwords.words("english"))

    consumer_key=""
    consumer_secret=""
    access_token=""
    access_token_secret=""

    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    api = tweepy.API(auth, wait_on_rate_limit=True)
    analyser = SentimentIntensityAnalyzer()

    def percentage(part, whole):
        return 100 * float(part)/float(whole)

    keyword = "primevideo"
    num_tweet = 100
    last_id = None

    tweets = tweepy.Cursor(api.search,  q=keyword, lang='en', max_id=last_id,
                        tweets_mode="extended").items(num_tweet)
    positive = 0
    negative = 0
    neutral = 0
    polarity = 0
    tweet_db = []
    neutral_list = []
    negative_list = []
    positive_list = []
    for tweet in tweets:

        tweet_db.append(tweet.text)
        analysis = TextBlob(tweet.text)
        score = analyser.polarity_scores(tweet.text)
        neg = score['neg']
        neu = score['neu']
        pos = score['pos']
        comp = score['compound']
        polarity += analysis.sentiment.polarity

        if neg > pos:
            negative_list.append(tweet.text)
            negative += 1

        elif pos > neg:
            positive_list.append(tweet.text)
            positive += 1

        elif pos == neg:
            neutral_list.append(tweet.text)
            neutral += 1

    positive = percentage(positive, num_tweet)
    negative = percentage(negative, num_tweet)
    neutral = percentage(neutral, num_tweet)
    polarity = percentage(polarity, num_tweet)
    positive = format(positive, '.1f')
    negative = format(negative, '.1f')
    neutral = format(neutral, '.1f')

    tweet_db = pd.DataFrame(tweet_db)
    neutral_list = pd.DataFrame(neutral_list)
    negative_list = pd.DataFrame(negative_list)
    positive_list = pd.DataFrame(positive_list)

    tweet_db.drop_duplicates(inplace=True)

    tweets = pd.DataFrame(tweet_db)
    tweets["text"] = tweets[0]

    def remove_rt(x): return re.sub('RT @\w+: ', " ", x)

    def rt(x): return re.sub(
        "(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", x)

    tweets["text"] = tweets.text.map(remove_rt).map(rt)
    tweets["text"] = tweets.text.str.lower()

    tweets[['polarity', 'subjectivity']] = tweets['text'].apply(
        lambda Text: pd.Series(TextBlob(Text).sentiment))
    for index, row in tweets['text'].iteritems():
        score = analyser.polarity_scores(row)
        neg = score['neg']
        neu = score['neu']
        pos = score['pos']
        if neg > pos:
            tweets.loc[index, 'sentiment'] = "negative"
        elif pos > neg:
            tweets.loc[index, 'sentiment'] = "positive"
        else:
            tweets.loc[index, 'sentiment'] = "neutral"
        tweets.loc[index, 'neg'] = neg
        tweets.loc[index, 'neu'] = neu
        tweets.loc[index, 'pos'] = pos

    tweets_negative = tweets[tweets["sentiment"] == "negative"]
    tweets_positive = tweets[tweets["sentiment"] == "positive"]
    tweets_neutral = tweets[tweets["sentiment"] == "neutral"]

    def count_words(data, feature):
        total = data.loc[:, feature].value_counts(dropna=False)
        percentage = round(data.loc[:, feature].value_counts(
            dropna=False, normalize=True)*100, 2)
        count_df = []
        count_df = pd.concat([total, percentage], axis=1,
                            keys=['Total', 'Percentage'])
        return count_df

    count_df = count_words(tweets, "sentiment")
    return(count_df.to_dict())
    count_df = count_words(tweets, "sentiment")
    print(count_df.to_dict())


import numpy as np
import cv2

def recording():
    # Create a VideoCapture object to read from webcam and write to the file
    cam = cv2.VideoCapture(0)
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter("output.avi",fourcc, 20.0, (640,480))
    # Read until video is completed
    while(cam.isOpened()):
        ret, frame = cam.read()
        if ret==True:
            # Display the frame
            cv2.imshow('frame',frame)
            # Writing frame to "output.avi"
            out.write(frame)
           # Press ESC to finish
            if cv2.waitKey(1) & 0xFF%256 == 27:
                break
        else:
            break
    # Release everything
    cam.release()
    out.release()

def processing():
    # Create a VideoCapture object to read from the file and write to the file
    cap = cv2.VideoCapture("output.avi")
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter("output_final.avi",fourcc, 20.0, (640,480))
    # Read until video is completed
    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret == True:
            # Make frame grayscale
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            # Decompose gray to 3-dimension colors
            colored = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
            # Draw the blue line
            img_1 = cv2.line(colored,(0,0),(511,511),(255,20,0),5)
            # Draw the pink rectangle
            img_2 = cv2.rectangle(img_1,(122,122),(34,34),(133,0,255),5)
            # Display final frame
            cv2.imshow('Final Video', img_2)
            # Write final video
            out.write(img_2)
            # Press ESC to finish
            if cv2.waitKey(30) & 0xFF%256 == 27:
                break
        else:
            break
    cap.release()
    out.release()

recording()
processing()
cv2.destroyAllWindows()


# -*- coding: utf-8 -*-
# 直接調用pyqt 不用designer

from PyQt4 import QtCore, QtGui
import datetime,json,sys,io
from BuyTicket import BuyTicket
from VPN import VPN

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle(u'台鐵訂票助手')

        app_icon = QtGui.QIcon()
        app_icon.addFile('img/train.png', QtCore.QSize(16, 16))
        app_icon.addFile('img/train.png', QtCore.QSize(24, 24))
        app_icon.addFile('img/train.png', QtCore.QSize(32, 32))
        app_icon.addFile('img/train.png', QtCore.QSize(48, 48))
        app_icon.addFile('img/train.png', QtCore.QSize(256, 256))
        self.setWindowIcon(app_icon)

        self.form_widget = FormWidget(self)
        self.font_size = 12
        font_label_standard = QtGui.QFont('微軟正黑體', self.font_size)
        QtGui.QApplication.setFont(font_label_standard)
        # 加入form_widget 表單主體
        self.setCentralWidget(self.form_widget)

        # 加入vpn設定
        VPNAction = QtGui.QAction(u'VPN設定', self)
        VPNAction.triggered.connect(lambda:self.form_widget.showVPNdialog(self.form_widget))
        # 加入menu bar 幫助
        AboutAction = QtGui.QAction(u'關於', self)
        AboutAction.triggered.connect(self.form_widget.showAbout)

        menubar = self.menuBar()
        AboutMenu = menubar.addMenu(u'選單')
        AboutMenu.addAction(VPNAction)
        AboutMenu.addAction(AboutAction)

class FormWidget(QtGui.QWidget):

    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        # 是否手動選擇VPN
        self.IsManuallyChooseVPN = False
        # 手動選出來的VPN列表 要傳遞給vpn class
        self.ManuallyVPNServer = None
        # VPN list的表頭
        self.VPNheader = None

        # ====================設定左邊layout 用來呈現訂票介面 裡面包含ticketInfo Layout====================
        self.leftLayout = QtGui.QGridLayout()

        # =============設定left layout的上方控件
        self.lbID = QtGui.QLabel( u"身份證字號：")
        self.lbID.setObjectName(u"lbID")
        self.leftLayout.addWidget(self.lbID,0,0)
        self.textID = QtGui.QLineEdit()
        self.textID.setObjectName(u"textID")
        reg_ex = QtCore.QRegExp("^[A-Za-z]{1}[12]{1}[0-9]{8}$")
        textID_validator = QtGui.QRegExpValidator(reg_ex, self)
        self.textID.setValidator(textID_validator)
        self.leftLayout.addWidget(self.textID,0,1)

        self.submitBtn = QtGui.QPushButton(u'啟動')
        self.submitBtn.setFont(QtGui.QFont('微軟正黑體', 20))
        self.submitBtn.setFixedSize(150,70)
        self.submitBtn.setIcon(QtGui.QIcon('img/power.png'))
        self.submitBtn.setIconSize(QtCore.QSize(40, 40))
        self.submitBtn.clicked.connect(lambda: self.Start(self))
        self.leftLayout.addWidget(self.submitBtn,0,3,2,2)

        self.vpnBtn = QtGui.QPushButton(u'開啟跳板')
        self.vpnBtn.setFixedSize(150, 40)
        self.vpnBtn.setIcon(QtGui.QIcon('img/vpn.png'))
        self.vpnBtn.setIconSize(QtCore.QSize(40, 40))
        self.vpnBtn.clicked.connect(lambda: self.OpenVPN(self))
        self.leftLayout.addWidget(self.vpnBtn, 2, 3, 2, 2)

        self.lb_StartStation = QtGui.QLabel(u'起站代碼')
        self.leftLayout.addWidget(self.lb_StartStation,1,0,1,1)
        self.cb_StartStation = ExtendedComboBox()
        self.cbStationAddItem(self.cb_StartStation)
        self.leftLayout.addWidget(self.cb_StartStation,1,1,1,1)

        self.lb_EndStation = QtGui.QLabel(u'到站代碼')
        self.leftLayout.addWidget(self.lb_EndStation,2,0,1,1)
        self.cb_EndStation = ExtendedComboBox()
        self.cbStationAddItem(self.cb_EndStation)
        self.leftLayout.addWidget(self.cb_EndStation,2,1,1,1)

        # =============ticketInfo Layout 用來放置去回程的控件
        self.TicketInfolayout = QtGui.QGridLayout()
        self.leftLayout.addLayout(self.TicketInfolayout,4,0,10,5)

        # =============設定位在ticketInfo裡的出發layout
        self.GoLayout = QtGui.QGroupBox()
        self.GoLayout.setTitle(u'【出發／單程】')
        vbox = QtGui.QGridLayout()
        self.lb_Go_Date = QtGui.QLabel(u'乘車日期')
        vbox.addWidget(self.lb_Go_Date,0,0,1,2)
        self.cb_Go_Date = QtGui.QComboBox()
        self.cbDateAddItem(self.cb_Go_Date)
        vbox.addWidget(self.cb_Go_Date,0,3,1,2)

        self.lb_Go_Num = QtGui.QLabel(u'訂票張數')
        vbox.addWidget(self.lb_Go_Num,1,0,1,2)
        self.cb_Go_Num = QtGui.QComboBox()
        self.cbNumAddItem(self.cb_Go_Num)
        vbox.addWidget(self.cb_Go_Num,1,3,1,1)

        self.lb_Go_Kind = QtGui.QLabel(u'車種')
        vbox.addWidget(self.lb_Go_Kind,2,0,1,2)
        self.cb_Go_Kind = QtGui.QComboBox()
        self.cbKindAddItem(self.cb_Go_Kind)
        vbox.addWidget(self.cb_Go_Kind,2,3,1,2)

        self.lb_Go_StartTime = QtGui.QLabel(u'起始時間')
        vbox.addWidget(self.lb_Go_StartTime, 3, 0, 1, 2)
        self.cb_Go_StartTime = QtGui.QComboBox()
        self.cbTimeAddItem(self.cb_Go_StartTime)
        vbox.addWidget(self.cb_Go_StartTime, 3, 3, 1, 1)

        self.lb_Go_EndTime = QtGui.QLabel(u'截止時間')
        vbox.addWidget(self.lb_Go_EndTime, 4, 0, 1, 2)
        self.cb_Go_EndTime = QtGui.QComboBox()
        self.cbTimeAddItem(self.cb_Go_EndTime)
        vbox.addWidget(self.cb_Go_EndTime, 4, 3, 1, 1)

        self.GoLayout.setLayout(vbox)
        self.TicketInfolayout.addWidget(self.GoLayout,0,0,1,3)

        # =============設定位在ticketInfo裡的回程layout
        self.BackLayout = QtGui.QGroupBox()
        self.BackLayout.setTitle(u'【回程】')
        self.BackLayout.setCheckable(True)
        backBox = QtGui.QGridLayout()

        self.lb_Back_Date = QtGui.QLabel(u'乘車日期')
        backBox.addWidget(self.lb_Back_Date,0,0,1,2)
        self.cb_Back_Date = QtGui.QComboBox()
        self.cbDateAddItem(self.cb_Back_Date)
        backBox.addWidget(self.cb_Back_Date,0,3,1,2)

        self.lb_Back_Num = QtGui.QLabel(u'訂票張數')
        backBox.addWidget(self.lb_Back_Num,1,0,1,2)
        self.cb_Back_Num = QtGui.QComboBox()
        self.cbNumAddItem(self.cb_Back_Num)
        backBox.addWidget(self.cb_Back_Num,1,3,1,1)

        self.lb_Back_Kind = QtGui.QLabel(u'車種')
        backBox.addWidget(self.lb_Back_Kind,2,0,1,2)
        self.cb_Back_Kind = QtGui.QComboBox()
        self.cbKindAddItem(self.cb_Back_Kind)
        backBox.addWidget(self.cb_Back_Kind,2,3,1,2)

        self.lb_Back_StartTime = QtGui.QLabel(u'起始時間')
        backBox.addWidget(self.lb_Back_StartTime, 3, 0, 1, 2)
        self.cb_Back_StartTime = QtGui.QComboBox()
        self.cbTimeAddItem(self.cb_Back_StartTime)
        backBox.addWidget(self.cb_Back_StartTime, 3, 3, 1, 1)

        self.lb_Back_EndTime = QtGui.QLabel(u'截止時間')
        backBox.addWidget(self.lb_Back_EndTime, 4, 0, 1, 2)
        self.cb_Back_EndTime = QtGui.QComboBox()
        self.cbTimeAddItem(self.cb_Back_EndTime)
        backBox.addWidget(self.cb_Back_EndTime, 4, 3, 1, 1)

        self.BackLayout.setLayout(backBox)
        self.TicketInfolayout.addWidget(self.BackLayout,0,3,1,3)

        # ====================設定右方layout====================
        self.rightLayout = QtGui.QGridLayout()
        self.lbPicBox = QtGui.QLabel(u'驗證碼：')
        self.rightLayout.addWidget(self.lbPicBox,0,0)
        self.captchaPic = QtGui.QLabel()
        self.captchaPic.setFixedSize(203,62)
        self.captchaPic.setStyleSheet(
            'border:1px solid rgb(0, 0, 0)'
        )
        self.rightLayout.addWidget(self.captchaPic,1,0,3,2)

        self.groupBoxGoResult = QtGui.QGroupBox()
        self.groupBoxGoResult.setStyleSheet("QGroupBox { background-color: rgb(255, 228,\
        224); border:1px solid rgb(122, 16, 0); }")
        self.groupBoxGoResult.setTitle(u'【去程訂票結果】')
        gorBox = QtGui.QVBoxLayout()
        self.Go_resultMsg = QtGui.QLabel()   #  用來顯示訂票結果
        self.Go_resultMsg.setStyleSheet('QLabel {color: red}')
        gorBox.addWidget(self.Go_resultMsg)
        self.groupBoxGoResult.setLayout(gorBox)
        self.rightLayout.addWidget(self.groupBoxGoResult,5,0,4,3)

        self.groupBoxBackResult = QtGui.QGroupBox()
        self.groupBoxBackResult.setStyleSheet("QGroupBox { background-color: rgb(255, 228,\
        224); border:1px solid rgb(122, 16, 0); }")
        self.groupBoxBackResult.setTitle(u'【回程訂票結果】')
        backrBox = QtGui.QVBoxLayout()
        self.Back_resultMsg =  QtGui.QLabel()  #  用來顯示訂票結果
        self.Back_resultMsg.setStyleSheet('QLabel {color: red}')
        backrBox.addWidget(self.Back_resultMsg)
        self.groupBoxBackResult.setLayout(backrBox)
        self.rightLayout.addWidget(self.groupBoxBackResult, 9, 0, 4, 3)

        # self.rightLayout.setRowMinimumHeight(4, 220)   #用來填補下面空白的部份

        # ==============設定下方log專用layout====================
        self.buttomLayout = QtGui.QGridLayout()
        self.lbLog = QtGui.QLabel(u'【狀態】')
        self.buttomLayout.addWidget(self.lbLog,0,0)
        self.clearBtn = QtGui.QPushButton(u'清除')
        self.clearBtn.clicked.connect(self.clearLog)
        self.buttomLayout.addWidget(self.clearBtn,0,4,1,1)
        self.textBrowser = QtGui.QPlainTextEdit()
        self.textBrowser.setReadOnly(True)
        self.buttomLayout.addWidget(self.textBrowser,1,0,1,5)

        # ====================主要layout======================
        self.mainLayout = QtGui.QGridLayout()
        self.mainLayout.addLayout(self.leftLayout,0,0)
        # 分隔線
        line = QtGui.QFrame()
        line.setFrameStyle(QtGui.QFrame.VLine| QtGui.QFrame.Sunken)
        self.mainLayout.addWidget(line,0,1)
        self.mainLayout.addLayout(self.rightLayout,0,2)
        # 分隔線
        hline = QtGui.QFrame()
        hline.setFrameStyle(QtGui.QFrame.HLine | QtGui.QFrame.Sunken)
        self.mainLayout.addWidget(hline,1,0,1,5)
        self.mainLayout.addLayout(self.buttomLayout,2,0,1,5)
        self.setLayout(self.mainLayout)

    # 將輸出訊息輸入到狀態視窗
    def logMsg(self,record):
        try:
            msg = unicode(record, 'utf-8')
        except:
            msg = record
        self.textBrowser.appendPlainText(msg)
    # 清除狀態欄
    def clearLog(self):
        self.textBrowser.clear()

    # 為訂票張數的combobox add item
    def cbNumAddItem(self, cb):
        cb.addItems([str(i) for i in range(1, 7)])

    # 為時間下拉選單產生時段
    def cbTimeAddItem(self, cb):
        cb.addItems([str(i).zfill(2) + ':00' for i in range(24)])
        cb.addItem('23:59')

    #  為車種下拉選單產生data
    def cbKindAddItem(self, cb):
        cb.addItem(u'全部車種', '*4')
        cb.addItem(u'自強號', '*1')
        cb.addItem(u'莒光號', '*2')
        cb.addItem(u'復興號', '*3')

    # 為日期下拉選單產生資料
    def cbDateAddItem(self, cb):
        date = datetime.datetime.now()
        strDate = date.date().strftime('%Y/%m/%d')
        dateOfWeek = ['一', '二', '三', '四', '五', '六', '日']
        cb.addItem(strDate + ' (' + unicode(dateOfWeek[date.date().weekday()],"utf-8") + ')', strDate + '-00')
        for i in range(14):
            date += datetime.timedelta(days=1)
            strDate = date.date().strftime('%Y/%m/%d')
            cb.addItem(strDate + ' (' + unicode(dateOfWeek[date.date().weekday()],"utf-8") + ')',
                       strDate + '-' + str(i + 1).zfill(2))

    # 產生車站下拉選單的資料
    def cbStationAddItem(self, cb):
        try:
            with io.open('station.json', 'r', encoding='utf8') as f:
                sdata = json.loads(f.read())
                # Sort it by station numbers
                sdata_sorted = sorted(
                    sdata, key=lambda s: s['ID']
                )
                for ii in range(len(sdata_sorted)):
                    cb.addItem(sdata_sorted[ii]['Station'], int(sdata_sorted[ii]['ID']))

        except IOError as ioerr:
            self.showMessage('查無車站json檔: ' + str(ioerr))

    # 顯示出對話視窗 要在connect裡傳參數可使用 lambda: self.showMessage(u'text you want to display')
    def showMessage(self,message=None):
        QtGui.QMessageBox.information(self, u"提示", message if message != None else u'發生錯誤!!')

    def showAbout(self):
        QtGui.QMessageBox.about(self,u"說明",
                                u"""
        台鐵訂票程式

Copyright © 2017 Lin Yich - All rights reserved.

這程式能實現台鐵自動化訂票

僅供學術交流用途，請勿從事非法活動

需求環境：請參閱Readme.md

                                """)
    # 將這視窗的內容pass到台鐵爬蟲 開始訂票程序
    def Start(self,mainWindow):
        do = BuyTicket(mainWindow)
        # disable開始按鈕
        self.submitBtn.setDisabled(True)
        do.Start()
        self.submitBtn.setDisabled(False)
    # 開啟VPN
    def OpenVPN(self,mainWindow):
        vpn = VPN(mainWindow)
        path = vpn.PathFromReg()
        if 'openvpn' in path.lower():
            vpn.ConnectVPN()
        else:
            QtGui.QMessageBox.warning(self, u"警告",u"尚未安裝OpenVPN，請參閱README.MD的說明")
    # 顯示vpn設定的對話框 並把值存檔下來
    def showVPNdialog(self,mainWindow):
        header,selectedValue, groupchecked, ok = VPNDialog.getVPNLists(mainWindow) #這段有點複雜 因為要取得dialog的回傳值 反正看得懂就好
        self.IsManuallyChooseVPN = groupchecked
        # 手動選出來的VPN列表 要傳遞給vpn class
        self.ManuallyVPNServer = selectedValue
        self.VPNheader = header

#========================================VPN設定對話框================================
class VPNDialog(QtGui.QDialog):
    def __init__(self, mainWindow, parent = None):
        super(VPNDialog, self).__init__(parent)

        layout = QtGui.QVBoxLayout(self)

        self.groupVpn = QtGui.QGroupBox()
        self.groupVpn.setTitle(u'【手動選擇VPN】 取消勾選則自動選擇最快Server')
        self.groupVpn.setCheckable(True)
        self.groupVpn.setMinimumSize(800,500)
        self.groupVpn.setChecked(mainWindow.IsManuallyChooseVPN) #從formWidget取得全域變數來設定groupBox的checked狀態
        # 取得vpn lists
        vpn = VPN(mainWindow)
        self.vpnLists,self.header = vpn.getVpnServerLists()
        vbox = QtGui.QVBoxLayout()
        self.TableView = QtGui.QTableView()
        self.TableView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) #只能選一個row
        self.TableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) #指定選擇整個row
        tm = MyTableModel(self.vpnLists, self.header, self)
        self.TableView.setModel(tm)

        header = self.TableView.horizontalHeader()
        header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(5, QtGui.QHeaderView.ResizeToContents)
        vbox.addWidget(self.TableView)
        self.groupVpn.setLayout(vbox)
        layout.addWidget(self.groupVpn)

        # 確認按鈕跟取消按鈕
        buttons = QtGui.QDialogButtonBox()
        action_btn = buttons.addButton(QtGui.QDialogButtonBox.Ok)
        action_btn.setText(u'確定')
        cancel_btn = buttons.addButton(QtGui.QDialogButtonBox.Cancel)
        cancel_btn.setText(u'取消')
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        layout.addWidget(buttons)

    def getIschecked(self):
        return self.groupVpn.isChecked()

    def getSelectedValue(self):
        try:
            return self.vpnLists[self.TableView.selectionModel().selectedRows()[0].row()]
        except:
            return None
    def getHeader(self):
        return self.header

    @staticmethod
    def getVPNLists(mainWindow,parent = None):
        dialog = VPNDialog(mainWindow)
        dialog.setWindowTitle(u'手動選擇VPN')
        app_icon = QtGui.QIcon()
        app_icon.addFile('img/train.png', QtCore.QSize(16, 16))
        app_icon.addFile('img/train.png', QtCore.QSize(24, 24))
        app_icon.addFile('img/train.png', QtCore.QSize(32, 32))
        app_icon.addFile('img/train.png', QtCore.QSize(48, 48))
        app_icon.addFile('img/train.png', QtCore.QSize(256, 256))
        dialog.setWindowIcon(app_icon)
        result = dialog.exec_()
        groupchecked = dialog.getIschecked()
        selectedValue = dialog.getSelectedValue()
        header = dialog.getHeader()
        return (header,selectedValue,groupchecked, result == QtGui.QDialog.Accepted)

#========================================產生給QTableView用的資料================================
class MyTableModel(QtCore.QAbstractTableModel):
    def __init__(self, datain, headerdata, parent=None, *args):
        """ datain: a list of lists
            headerdata: a list of strings
        """
        QtCore.QAbstractTableModel.__init__(self, parent, *args)
        self.arraydata = datain
        self.headerdata = headerdata

    def rowCount(self, parent):
        return len(self.arraydata)

    def columnCount(self, parent):
        return len(self.arraydata[0])

    def data(self, index, role):
        if not index.isValid():
            return QtCore.QVariant()
        elif role != QtCore.Qt.DisplayRole:
            return QtCore.QVariant()
        return QtCore.QVariant(self.arraydata[index.row()][index.column()])

    def headerData(self, col, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return QtCore.QVariant(self.headerdata[col])
        return QtCore.QVariant()

    def sort(self, Ncol, order):
        """Sort table by given column number.
        """
        self.emit(QtCore.SIGNAL("layoutAboutToBeChanged()"))
        self.arraydata = sorted(self.arraydata, key=lambda s: s[2])
        if order == QtCore.Qt.DescendingOrder:
            self.arraydata.reverse()
        self.emit(QtCore.SIGNAL("layoutChanged()"))

class ExtendedComboBox(QtGui.QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)

        self.setEditable(True)

        # add a filter model to filter matching items

        self.pFilterModel = QtGui.QSortFilterProxyModel(self)

        self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)

        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model

        self.completer = QtGui.QCompleter(self.pFilterModel, self)

        # always show all (filtered) completions

        self.completer.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)

        self.setCompleter(self.completer)

        # connect signals

        self.lineEdit().textEdited[unicode].connect(self.pFilterModel.setFilterFixedString)

        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox

    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)

            self.setCurrentIndex(index)
    # 當lose focus時 判斷combobox輸入的text有沒有在item中
    def event(self, event):
        if event.type() == QtCore.QEvent.FocusOut:
            text = self.currentText()
            if text:
                index = self.findText(text)
                if index == -1:
                    self.setStyleSheet('QComboBox{border:1px solid red}')
                else:
                    self.setStyleSheet('QComboBox{border:1px solid gray}')

        return QtGui.QComboBox.event(self, event)

    # on model change, update the models of the filter and completer as well

    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)

        self.pFilterModel.setSourceModel(model)

        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)

        self.pFilterModel.setFilterKeyColumn(column)

        super(ExtendedComboBox, self).setModelColumn(column)

if __name__ == '__main__':
    app =QtGui.QApplication(sys.argv)
    MainWindow = MainWindow()
    # MainWindow.resize(600, 400)
    MainWindow.show()
    app.exec_()


# Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
'''
Example
Given 4 points: (1,2), (3,6), (0,0), (1,3).
The maximum number is 3.
'''
# Definition for a point.
# class Point:
#     def __init__(self, a=0, b=0):
#         self.x = a
#         self.y = b

class Solution:
    # @param {int[]} points an array of point
    # @return {int} an integer
    def maxPoints(self, points):
        # Write your code here
        if len(points) <= 2:
            return len(points)
        res = 0
        for m in range(0, len(points) - 1):
            slopes = {"vertical": 1}
            same = 0
            for n in range(m + 1, len(points)):
                if points[n].x != points[m].x:
                    slope = float(points[n].y - points[m].y) / (points[n].x - points[m].x)
                    if slope not in slopes:
                        slopes[slope] = 2
                    else:
                        slopes[slope] += 1
                elif points[n].x == points[m].x and points[n].y != points[m].y:
                    slopes["vertical"] += 1
                else:
                    same += 1
            res = max(res, max(slopes.values()) + same)
        return res


import numpy as np
import matplotlib.pyplot as plt
import cv2

def detect_body(frame):
    body_img = frame.copy()
    body_classifier = cv2.CascadeClassifier("haarcascade_fullbody.xml")

    gray = cv2.cvtColor(body_img, cv2.COLOR_BGR2GRAY)

    bodies = body_classifier.detectMultiScale(gray)

    for (x, y, w, h) in bodies:
        cv2.rectangle(body_img, (x, y), (x+w, y+h), (255, 0, 0), 8)

    return body_img


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

from django.db import models
from django.utils.translation import ugettext_lazy as _
from mptt.models import MPTTModel, TreeForeignKey

class Category(MPTTModel):
    name = models.CharField(_('Name'), max_length = 127)
    image = models.ImageField(_(u'Image'), blank=True, null=True, upload_to="catalog/category/")
    description = models.TextField(_(u'Description'), blank=True, null=True)
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children')

    def get_absolute_url(self):
        return '/category/%d/' % self.id

    def __unicode__(self):
        return self.name

    class Meta:
        verbose_name = _(u'Category')
        verbose_name_plural = _(u'Categories')

class Manufacturer(models.Model):
    name = models.CharField(_(u'Name'), max_length = 127)
    image = models.ImageField(_(u'Image'), blank=True, null=True, default=None, upload_to="catalog/manufacturer/")
    description = models.TextField(_(u'Description'), blank=True, null=True, default=None)

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        return '/manufacturer/%d/' % self.id

    def product_list(self):
        from django.core import urlresolvers
        p = u''
        for i in Product.objects.filter(manufacturer=self):
            admin_url = urlresolvers.reverse(
                "admin:catalog_product_change", args=[i.id]
            )
            p += u'(edit) - %s
' % (admin_url, i.name)

        return p

    product_list.short_description = u'Товары'
    product_list.allow_tags = True

    def product_count(self):
        return Product.objects.filter(manufacturer=self).count()

    product_count.admin_order_field = 'product_count'

    class Meta:
        verbose_name = _(u'Manufacturer')
        verbose_name_plural = _(u'Manufacturers')

class Product(models.Model):
    name = models.CharField(_(u'Name'), max_length = 127)
    description = models.TextField(_(u'Description'), blank=True, null=True)
    price = models.IntegerField(_(u'Price'), default=0)
    category = models.ForeignKey(Category, verbose_name=_(u'Category'))
    manufacturer = models.ForeignKey(Manufacturer, verbose_name=_(u'Manufacturer'))
    on_demand = models.BooleanField(_(u'On Demand'), default=False)

    def __unicode__(self):
        return self.name

    def get_markertoys_id(self):
        try:
            pa = ProductAttribute.objects.get(product_id=self.id, name="markertoys_id")
            return pa.value
        except ProductAttribute.DoesNotExist:
            return ''

    def get_images(self):
        return ProductImages.objects.filter(product_id=self.id)

    def get_primary_image(self):
        from PIL import Image, ImageEnhance
        from django.conf import settings
        from django.core.files import File
        import os

        try:
            img = ProductImages.objects.filter(product_id=self.id)[0]
        except IndexError:
            return 0

        img = img.image
        image = Image.open( settings.MEDIA_ROOT + "/" + img.name ).convert('RGB')
        watermark = Image.open(settings.STATIC_ROOT + '/logo_text.png')
        opacity = 1

        imagename = "%s.wm.jpg" % img.name
        if os.path.isfile(imagename):
            return imagename

        assert opacity >= 0 and opacity <= 1
        if opacity < 1:
            if watermark.mode != 'RGBA':
                watermark = watermark.convert('RGBA')
            else:
                watermark = watermark.copy()
            alpha = watermark.split()[3]
            alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
            watermark.putalpha(alpha)

        layer = Image.new('RGBA', image.size, (0,0,0,0))
        layer.paste(watermark, (15, image.size[1]-45))

        i = Image.composite(layer,  image,  layer)
        #imagename = "%s.wm.jpg" % img.name
        i.save(settings.MEDIA_ROOT + "/" + imagename)

        return imagename

    def get_absolute_url(self):
        return '/product/%d/' % self.id

    class Meta:
        ordering = ['name']
        verbose_name = _(u'Product')
        verbose_name_plural = _(u'Products')

class ProductImages(models.Model):
    product = models.ForeignKey(Product, related_name='images')
    image = models.ImageField(_(u'Image'), blank=True, default=None, null=True, upload_to="catalog/product/")

    class Meta:
        verbose_name = _(u'Product image')
        verbose_name_plural = _(u'Product images')

class ProductAttribute(models.Model):
    product = models.ForeignKey(Product, related_name='attribute')
    name = models.CharField(max_length=127)
    value = models.CharField(max_length=255)


# from airflow import DAG
# from airflow.operators.python_operator import PythonOperator
# from airflow.operators.bash_operator import BashOperator
from datetime import datetime
from scrapy.crawler import CrawlerProcess
from fipe import FipeSpider

def extract():
    today_ = datetime.today()
    feed = {
        f"/home/rafa/Documents/docker-airflow/data/{today_.year}_{today_.month}.csv": {
            'format': 'csv',
            'encoding': 'utf8'
        }
    }
    settings = {"FEED": feed,
                "LOG_LEVEL": "INFO",
                "DOWNLOAD_DELAY": 1}

    process = CrawlerProcess(settings)
    process.crawl(FipeSpider, ano=today_.year, mes=today_.month)
    process.start()

def load():
    today_ = datetime.today()
    print("extracao concluida")

# default_args = {
#     "owner": "Rafael Junior Ribeiro",
#     "start_date": datetime(2021, 2, 7),
# }
# dag = DAG("fipe", default_args=default_args, schedule_interval="16 * * * *")
# today = datetime.today()
#
# extract_task = PythonOperator(task_id="extract_task",
#                               python_callable=extract,
#                               dag=dag)
#
# load_task = BashOperator(task_id="load_task",
#                          bash_command="""echo "extracao feita"! """,
#                          dag=dag)
#
# extract_task >> load_task


#!/usr/bin/python3
#it created by Carlos Williamberg on 05/29/2017.
import os, sys, time
import tensorflow as tf

from io import BytesIO
from picamera import PiCamera
from PIL import Image
import vs_io

def getPicture():
    stream = BytesIO()#create the in-memory stream
    camera = PiCamera()
    camera.start_preview()
    time.sleep(2)
    camera.capture(stream, format='jpeg')
    stream.seek(0)#"Rewind" the stream to the beginning so we can read its content
    camera.close()
    return stream

def savePicture():
    camera = PiCamera()
    #camera.resolution = (64, 64)
    camera.start_preview()
    time.sleep(2.5)
    camera.capture('img.jpg')
    camera.stop_preview()
    camera.close()

def main():
    # Loads label file, strips off carriage return
    label_lines = [line.rstrip() for line
                   in tf.gfile.GFile("retrained_labels.txt")]

    # Unpersists graph from file
    with tf.gfile.FastGFile("retrained_graph.pb", 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        tf.import_graph_def(graph_def, name='')
    with tf.Session() as sess:
        while(True):
            #image_data = getPicture()# Read in the image_data
            savePicture()
            image_data = tf.gfile.FastGFile('img.jpg', 'rb').read()

            # Feed the image_data as input to the graph and get first prediction
            softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')
            start_time = time.time()

            predictions = sess.run(softmax_tensor, \
             {'DecodeJpeg/contents:0': image_data})
            final = (time.time() - start_time)
            print("-- %s seconds ---" % final)
            # Sort to show labels of first prediction in order of confidence
            top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]
            human_string = label_lines[top_k[0]]
            score = predictions[0][top_k[0]]
            if (human_string == "faixapedestre" and score > 0.8):
                vs_io.notification()
            #for node_id in top_k:
                #human_string = label_lines[node_id]
                #score = predictions[0][node_id]
            print('%s (score = %.5f)' % (human_string, score))

if __name__ == '__main__':main()


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

# 设置神经网络参数
BATCH_SIZE = 50
NUM_EPOCH = 1000

NANOPORE_HEIGHT = 17
NANOPORE_WIDTH = 4
NANOPORE_CHANNEL = 2

OUTPUT_NODE = 2

# 第一个卷积层的深度和窗口大小
CONV1_DEEP = 32
FLITER1_SIZE = 2
CONV1_STRIDE_HOR = 1
CONV1_STRIDE_VEC = 2

# 第二个卷积层的深度和窗口大小
CONV2_DEEP = 64
FLITER2_SIZE = 2
CONV2_STRIDE_HOR = 2
CONV2_STRIDE_VEC = 1

# 全连接层大小
FC_SIZE = 128
KEEP_PROB = 0.7

# 数据存放位置
DATASET = "/data/nanopore/dL_network/network/cellflow_dataset/"
CELLFLOW_DATASET = "/data/nanopore/dL_network/network/cellflow_dataset/"

# 滑动平均模型的参数
MOVING_AVERAGE_DECAY = 0.99

# 学习率的设置
LEARNING_RATE_BASE = 0.01
SAMPLE_NUM = 60000
LEARNING_RATE_DECAY = 0.99

# 模型持久化设置
MODEL_SAVE_PATH = "/data/nanopore/dL_network/network/cnn_cellflow_res/cnn_tf_model/"
MODEL_NAME = "nanopore_classifier.ckpt"
PB_DIR = "/data/nanopore/dL_network/network/cnn_cellflow_res/cnn_tf_model_pb/"

# 用cellflow数据对模型进行评估时文件存储位置
CELLFLOW_EVAL = "/data/nanopore/dL_network/network/cnn_cellflow_res/cellflow_pred.tsv"


'''
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.
'''

# must not modify the array means sorting is not allowed
# only use constant space means cannot use binary search after storing and sorting the elements have been passed
# time should be less than O(n^2) meads cannot use brute force solution
# as we already know the range of the value is [1,n], get the mid value and count how many number in the input is less or equal to the mid, if count is larger than mid, shift right to mid, otherwise shift left to mid+1
class Solution(object):
    def findDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums) - 1
        left = 1
        right = n
        while left < right:
            mid = (left + right) / 2
            count = 0
            for num in nums:
                if num <= mid:
                    count += 1
            if count > mid:
                right = mid
            else:
                left = mid + 1
        return left


__author__ = 'Tonzh'
from distutils.core import setup

setup(
    name='HATT-add-on',
    version='1.0.2',
    packages=['Core', 'Core.Action','Core.Info','Core.Lib','Core.Utils','Core.Lib.cmd'],
    url='https://pypi.org/project/HATT-add-on/',
    license='1.0.1',
    author='Tonzh',
    author_email='tong.zhang@kikatech.com',
    description="this is a second develop from HATT",
    long_description=open("README.md").read(),
    install_requires=["Queue"],
    classifiers=[
        "Environment :: Web Environment",
        "Intended Audience :: Developers",
        "Operating System :: OS Independent",
        "Topic :: Text Processing :: Indexing",
        "Topic :: Utilities",
        "Topic :: Internet",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Programming Language :: Python",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 2.6",
        "Programming Language :: Python :: 2.7",
    ],
)


from spynnaker.pyNN.utilities import conf
from spynnaker.pyNN.utilities import constants
from spynnaker.pyNN.utilities import utility_calls
from spynnaker.pyNN import exceptions
from spynnaker.pyNN.models.neuron import master_pop_table_generators
from spynnaker.pyNN.utilities.running_stats import RunningStats
from spynnaker.pyNN.models.spike_source.spike_source_poisson \
    import SpikeSourcePoisson
from spynnaker.pyNN.models.utility_models.delay_extension_vertex \
    import DelayExtensionVertex
from spynnaker.pyNN.models.neuron.synapse_io.synapse_io_row_based \
    import SynapseIORowBased
from spynnaker.pyNN.models.neural_projections.projection_partitionable_edge \
    import ProjectionPartitionableEdge
from spynnaker.pyNN.models.neuron.synapse_dynamics.synapse_dynamics_static \
    import SynapseDynamicsStatic

from pacman.model.partitionable_graph.abstract_partitionable_vertex \
    import AbstractPartitionableVertex
from pacman.model.graph_mapper.slice import Slice

from data_specification.enums.data_type import DataType

from spinn_front_end_common.utilities import helpful_functions

from scipy import special
from collections import defaultdict
from pyNN.random import RandomDistribution
import math
import sys
import numpy

# TODO: Make sure these values are correct (particularly CPU cycles)
_SYNAPSES_BASE_DTCM_USAGE_IN_BYTES = 28
_SYNAPSES_BASE_SDRAM_USAGE_IN_BYTES = 0
_SYNAPSES_BASE_N_CPU_CYCLES_PER_NEURON = 10
_SYNAPSES_BASE_N_CPU_CYCLES = 8

class SynapticManager(object):
    """ Deals with synapses
    """

    def __init__(self, synapse_type, machine_time_step, ring_buffer_sigma,
                 spikes_per_second, population_table_type=None,
                 synapse_io=None):

        self._synapse_type = synapse_type
        self._ring_buffer_sigma = ring_buffer_sigma
        self._spikes_per_second = spikes_per_second
        self._machine_time_step = machine_time_step

        # Get the type of population table
        self._population_table_type = population_table_type
        if population_table_type is None:
            population_table_type = ("MasterPopTableAs" + conf.config.get(
                "MasterPopTable", "generator"))
            algorithms = helpful_functions.get_valid_components(
                master_pop_table_generators, "master_pop_table_as")
            self._population_table_type = algorithms[population_table_type]()

        # Get the synapse IO
        self._synapse_io = synapse_io
        if synapse_io is None:
            self._synapse_io = SynapseIORowBased(machine_time_step)

        if self._ring_buffer_sigma is None:
            self._ring_buffer_sigma = conf.config.getfloat(
                "Simulation", "ring_buffer_sigma")

        if self._spikes_per_second is None:
            self._spikes_per_second = conf.config.getfloat(
                "Simulation", "spikes_per_second")
        self._spikes_per_tick = max(
            1.0,
            self._spikes_per_second /
            (1000000.0 / float(self._machine_time_step)))

        # Prepare for dealing with STDP - there can only be one (non-static)
        # synapse dynamics per vertex at present
        self._synapse_dynamics = SynapseDynamicsStatic()

        # Keep the details once computed to allow reading back
        self._weight_scales = dict()
        self._delay_key_index = dict()
        self._retrieved_blocks = dict()

        # A list of connection holders to be filled in pre-run, indexed by
        # the edge the connection is for
        self._pre_run_connection_holders = defaultdict(list)

    @property
    def synapse_dynamics(self):
        return self._synapse_dynamics

    @synapse_dynamics.setter
    def synapse_dynamics(self, synapse_dynamics):

        # We can always override static dynamics or None
        if isinstance(self._synapse_dynamics, SynapseDynamicsStatic):
            self._synapse_dynamics = synapse_dynamics

        # We can ignore a static dynamics trying to overwrite a plastic one
        elif isinstance(synapse_dynamics, SynapseDynamicsStatic):
            pass

        # Otherwise, the dynamics must be equal
        elif not synapse_dynamics.is_same_as(self._synapse_dynamics):
            raise exceptions.SynapticConfigurationException(
                "Synapse dynamics must match exactly when using multiple edges"
                "to the same population")

    @property
    def synapse_type(self):
        return self._synapse_type

    @property
    def ring_buffer_sigma(self):
        return self._ring_buffer_sigma

    @ring_buffer_sigma.setter
    def ring_buffer_sigma(self, ring_buffer_sigma):
        self._ring_buffer_sigma = ring_buffer_sigma

    @property
    def spikes_per_second(self):
        return self._spikes_per_second

    @spikes_per_second.setter
    def spikes_per_second(self, spikes_per_second):
        self._spikes_per_second = spikes_per_second

    @property
    def maximum_delay_supported_in_ms(self):
        return self._synapse_io.get_maximum_delay_supported_in_ms()

    @property
    def vertex_executable_suffix(self):
        return self._synapse_dynamics.get_vertex_executable_suffix()

    def add_pre_run_connection_holder(
            self, connection_holder, edge, synapse_info):
        self._pre_run_connection_holders[(edge, synapse_info)].append(
            connection_holder)

    def get_n_cpu_cycles(self, vertex_slice, graph):

        # TODO: Calculate this correctly
        return 0

    def get_dtcm_usage_in_bytes(self, vertex_slice, graph):

        # TODO: Calculate this correctly
        return 0

    def _get_synapse_params_size(self, vertex_slice):
        per_neuron_usage = (
            self._synapse_type.get_sdram_usage_per_neuron_in_bytes())
        return (_SYNAPSES_BASE_SDRAM_USAGE_IN_BYTES +
                (per_neuron_usage * vertex_slice.n_atoms) +
                (4 * self._synapse_type.get_n_synapse_types()))

    def _get_exact_synaptic_blocks_size(
            self, post_slices, post_slice_index, post_vertex_slice,
            graph_mapper, subvertex, subvertex_in_edges):
        """ Get the exact size all of the synaptic blocks
        """
        memory_size = 0

        # Go through the subedges and add up the memory
        for subedge in subvertex_in_edges:

            edge = graph_mapper.get_partitionable_edge_from_partitioned_edge(
                subedge)
            if isinstance(edge, ProjectionPartitionableEdge):

                # Add on the size of the tables to be generated
                pre_vertex_slice = graph_mapper.get_subvertex_slice(
                    subedge.pre_subvertex)
                pre_slices = graph_mapper.get_subvertex_slices(edge.pre_vertex)
                pre_slice_index = graph_mapper.get_subvertex_index(
                    subedge.pre_subvertex)

                memory_size += self._get_size_of_synapse_information(
                    edge.synapse_information, pre_slices, pre_slice_index,
                    post_slices, post_slice_index, pre_vertex_slice,
                    post_vertex_slice, edge.n_delay_stages)

        return memory_size

    def _get_estimate_synaptic_blocks_size(self, post_vertex_slice, in_edges):
        """ Get an estimate of the synaptic blocks memory size
        """
        memory_size = 0

        for in_edge in in_edges:
            if isinstance(in_edge, ProjectionPartitionableEdge):

                # Get an estimate of the number of post sub-vertices by
                # assuming that all of them are the same size as this one
                post_slices = [Slice(
                    lo_atom, min(
                        in_edge.post_vertex.n_atoms,
                        lo_atom + post_vertex_slice.n_atoms - 1))
                    for lo_atom in range(
                        0, in_edge.post_vertex.n_atoms,
                        post_vertex_slice.n_atoms)]
                post_slice_index = int(math.floor(
                    float(post_vertex_slice.lo_atom) /
                    float(post_vertex_slice.n_atoms)))

                # Get an estimate of the number of pre-sub-vertices - clearly
                # this will not be correct if the SDRAM usage is high!
                # TODO: Can be removed once we move to population-based keys
                n_atoms_per_subvertex = sys.maxint
                if isinstance(in_edge.pre_vertex, AbstractPartitionableVertex):
                    n_atoms_per_subvertex = \
                        in_edge.pre_vertex.get_max_atoms_per_core()
                if in_edge.pre_vertex.n_atoms < n_atoms_per_subvertex:
                    n_atoms_per_subvertex = in_edge.pre_vertex.n_atoms
                pre_slices = [Slice(
                    lo_atom, min(
                        in_edge.pre_vertex.n_atoms,
                        lo_atom + n_atoms_per_subvertex - 1))
                    for lo_atom in range(
                        0, in_edge.pre_vertex.n_atoms, n_atoms_per_subvertex)]

                pre_slice_index = 0
                for pre_vertex_slice in pre_slices:
                    memory_size += self._get_size_of_synapse_information(
                        in_edge.synapse_information, pre_slices,
                        pre_slice_index, post_slices, post_slice_index,
                        pre_vertex_slice, post_vertex_slice,
                        in_edge.n_delay_stages)
                    pre_slice_index += 1

        return memory_size

    def _get_size_of_synapse_information(
            self, synapse_information, pre_slices, pre_slice_index,
            post_slices, post_slice_index, pre_vertex_slice, post_vertex_slice,
            n_delay_stages):

        memory_size = 0
        for synapse_info in synapse_information:
            undelayed_size, delayed_size = \
                self._synapse_io.get_sdram_usage_in_bytes(
                    synapse_info, pre_slices,
                    pre_slice_index, post_slices, post_slice_index,
                    pre_vertex_slice, post_vertex_slice,
                    n_delay_stages, self._population_table_type)

            memory_size = self._population_table_type\
                .get_next_allowed_address(memory_size)
            memory_size += undelayed_size
            memory_size = self._population_table_type\
                .get_next_allowed_address(memory_size)
            memory_size += delayed_size
        return memory_size

    def _get_synapse_dynamics_parameter_size(self, vertex_slice, in_edges):
        """ Get the size of the synapse dynamics region
        """
        return self._synapse_dynamics.get_parameters_sdram_usage_in_bytes(
            vertex_slice.n_atoms, self._synapse_type.get_n_synapse_types())

    def get_sdram_usage_in_bytes(self, vertex_slice, in_edges):
        return (
            self._get_synapse_params_size(vertex_slice) +
            self._get_synapse_dynamics_parameter_size(vertex_slice, in_edges) +
            self._get_estimate_synaptic_blocks_size(vertex_slice, in_edges) +
            self._population_table_type.get_master_population_table_size(
                vertex_slice, in_edges))

    def _reserve_memory_regions(
            self, spec, vertex, subvertex, vertex_slice, graph, sub_graph,
            all_syn_block_sz, graph_mapper):

        spec.reserve_memory_region(
            region=constants.POPULATION_BASED_REGIONS.SYNAPSE_PARAMS.value,
            size=self._get_synapse_params_size(vertex_slice),
            label='SynapseParams')

        in_edges = graph.incoming_edges_to_vertex(vertex)
        master_pop_table_sz = \
            self._population_table_type.get_exact_master_population_table_size(
                subvertex, sub_graph, graph_mapper)
        if master_pop_table_sz > 0:
            spec.reserve_memory_region(
                region=constants.POPULATION_BASED_REGIONS.POPULATION_TABLE
                                                         .value,
                size=master_pop_table_sz, label='PopTable')
        if all_syn_block_sz > 0:
            spec.reserve_memory_region(
                region=constants.POPULATION_BASED_REGIONS.SYNAPTIC_MATRIX
                                                         .value,
                size=all_syn_block_sz, label='SynBlocks')

        synapse_dynamics_sz = self._get_synapse_dynamics_parameter_size(
            vertex_slice, in_edges)
        if synapse_dynamics_sz != 0:
            spec.reserve_memory_region(
                region=constants.POPULATION_BASED_REGIONS.SYNAPSE_DYNAMICS
                                                         .value,
                size=synapse_dynamics_sz, label='synapseDynamicsParams')

    def get_number_of_mallocs_used_by_dsg(self):
        return 4

    @staticmethod
    def _ring_buffer_expected_upper_bound(
            weight_mean, weight_std_dev, spikes_per_second,
            machine_timestep, n_synapses_in, sigma):
        """
        Provides expected upper bound on accumulated values in a ring buffer
        element.

        Requires an assessment of maximum Poisson input rate.

        Assumes knowledge of mean and SD of weight distribution, fan-in
        & timestep.

        All arguments should be assumed real values except n_synapses_in
        which will be an integer.

        weight_mean - Mean of weight distribution (in either nA or
                      microSiemens as required)
        weight_std_dev - SD of weight distribution
        spikes_per_second - Maximum expected Poisson rate in Hz
        machine_timestep - in us
        n_synapses_in - No of connected synapses
        sigma - How many SD above the mean to go for upper bound;
                a good starting choice is 5.0.  Given length of simulation we
                can set this for approximate number of saturation events

        """

        # E[ number of spikes ] in a timestep
        # x /1000000.0 = conversion between microsecond to second
        average_spikes_per_timestep = (
            float(n_synapses_in * spikes_per_second) *
            (float(machine_timestep) / 1000000.0))

        # Exact variance contribution from inherent Poisson variation
        poisson_variance = average_spikes_per_timestep * (weight_mean ** 2)

        # Upper end of range for Poisson summation required below
        # upper_bound needs to be an integer
        upper_bound = int(round(average_spikes_per_timestep +
                                constants.POSSION_SIGMA_SUMMATION_LIMIT *
                                math.sqrt(average_spikes_per_timestep)))

        # Closed-form exact solution for summation that gives the variance
        # contributed by weight distribution variation when modulated by
        # Poisson PDF.  Requires scipy.special for gamma and incomplete gamma
        # functions. Beware: incomplete gamma doesn't work the same as
        # Mathematica because (1) it's regularised and needs a further
        # multiplication and (2) it's actually the complement that is needed
        # i.e. 'gammaincc']

        weight_variance = 0.0

        if weight_std_dev > 0:

            lngamma = special.gammaln(1 + upper_bound)

            gammai = special.gammaincc(1 + upper_bound,
                                       average_spikes_per_timestep)

            big_ratio = (math.log(average_spikes_per_timestep) * upper_bound -
                         lngamma)

            if -701.0 < big_ratio < 701.0 and big_ratio != 0.0:

                log_weight_variance = (
                    -average_spikes_per_timestep +
                    math.log(average_spikes_per_timestep) +
                    2.0 * math.log(weight_std_dev) +
                    math.log(math.exp(average_spikes_per_timestep) * gammai -
                             math.exp(big_ratio)))

                weight_variance = math.exp(log_weight_variance)

        # upper bound calculation -> mean + n * SD
        return ((average_spikes_per_timestep * weight_mean) +
                (sigma * math.sqrt(poisson_variance + weight_variance)))

    def _get_ring_buffer_to_input_left_shifts(
            self, subvertex, sub_graph, graph_mapper, post_slices,
            post_slice_index, post_vertex_slice, machine_timestep,
            weight_scale):
        """ Get the scaling of the ring buffer to provide as much accuracy as\
            possible without too much overflow
        """
        weight_scale_squared = weight_scale * weight_scale
        n_synapse_types = self._synapse_type.get_n_synapse_types()
        running_totals = [RunningStats() for _ in range(n_synapse_types)]
        total_weights = numpy.zeros(n_synapse_types)
        biggest_weight = numpy.zeros(n_synapse_types)
        weights_signed = False
        max_rate = self._spikes_per_second

        for subedge in sub_graph.incoming_subedges_from_subvertex(subvertex):
            pre_vertex_slice = graph_mapper.get_subvertex_slice(
                subedge.pre_subvertex)
            edge = graph_mapper.get_partitionable_edge_from_partitioned_edge(
                subedge)
            pre_slices = [
                graph_mapper.get_subvertex_slice(subv)
                for subv in graph_mapper.get_subvertices_from_vertex(
                    edge.pre_vertex)]
            pre_slice_index = pre_slices.index(pre_vertex_slice)
            if isinstance(edge, ProjectionPartitionableEdge):
                for synapse_info in edge.synapse_information:
                    synapse_type = synapse_info.synapse_type
                    synapse_dynamics = synapse_info.synapse_dynamics
                    connector = synapse_info.connector
                    weight_mean = abs(synapse_dynamics.get_weight_mean(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice) * weight_scale)
                    n_connections = \
                        connector.get_n_connections_to_post_vertex_maximum(
                            pre_slices, pre_slice_index, post_slices,
                            post_slice_index, pre_vertex_slice,
                            post_vertex_slice)
                    weight_variance = abs(synapse_dynamics.get_weight_variance(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice) * weight_scale_squared)
                    running_totals[synapse_type].add_items(
                        weight_mean, weight_variance, n_connections)

                    weight_max = (synapse_dynamics.get_weight_maximum(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice) * weight_scale)
                    biggest_weight[synapse_type] = max(
                        biggest_weight[synapse_type], weight_max)

                    spikes_per_tick = self._spikes_per_tick
                    if isinstance(edge.pre_vertex, SpikeSourcePoisson):
                        rate = edge.pre_vertex.rate
                        if hasattr(rate, "__getitem__"):
                            rate = max(rate)
                        elif isinstance(rate, RandomDistribution):
                            rate = utility_calls.get_maximum_probable_value(
                                rate, pre_vertex_slice.n_atoms)
                        if rate > max_rate:
                            max_rate = rate
                        spikes_per_tick = max(
                            1.0,
                            rate /
                            (1000000.0 / float(self._machine_time_step)))
                    total_weights[synapse_type] += spikes_per_tick * (
                        weight_max * n_connections)

                    if synapse_dynamics.are_weights_signed():
                        weights_signed = True

        max_weights = numpy.zeros(n_synapse_types)
        for synapse_type in range(n_synapse_types):
            stats = running_totals[synapse_type]
            max_weights[synapse_type] = min(
                self._ring_buffer_expected_upper_bound(
                    stats.mean, stats.standard_deviation,
                    max_rate, machine_timestep, stats.n_items,
                    self._ring_buffer_sigma),
                total_weights[synapse_type])
            max_weights[synapse_type] = max(
                max_weights[synapse_type], biggest_weight[synapse_type])

        # Convert these to powers
        max_weight_powers = [0 if w <= 0
                             else int(math.ceil(max(0, math.log(w, 2))))
                             for w in max_weights]

        # If 2^max_weight_power equals the max weight, we have to add another
        # power, as range is 0 - (just under 2^max_weight_power)!
        max_weight_powers = [w + 1 if (2 ** w) >= a else w
                             for w, a in zip(max_weight_powers, max_weights)]

        # If we have synapse dynamics that uses signed weights,
        # Add another bit of shift to prevent overflows
        if weights_signed:
            max_weight_powers = [m + 1 for m in max_weight_powers]

        return max_weight_powers

    @staticmethod
    def _get_weight_scale(ring_buffer_to_input_left_shift):
        """ Return the amount to scale the weights by to convert them from \
            floating point values to 16-bit fixed point numbers which can be \
            shifted left by ring_buffer_to_input_left_shift to produce an\
            s1615 fixed point number
        """
        return float(math.pow(2, 16 - (ring_buffer_to_input_left_shift + 1)))

    def _write_synapse_parameters(
            self, spec, subvertex, subgraph, graph_mapper, post_slices,
            post_slice_index, post_vertex_slice, input_type):

        # Get the ring buffer shifts and scaling factors
        weight_scale = input_type.get_global_weight_scale()
        ring_buffer_shifts = self._get_ring_buffer_to_input_left_shifts(
            subvertex, subgraph, graph_mapper, post_slices, post_slice_index,
            post_vertex_slice, self._machine_time_step, weight_scale)

        spec.switch_write_focus(
            region=constants.POPULATION_BASED_REGIONS.SYNAPSE_PARAMS.value)
        utility_calls.write_parameters_per_neuron(
            spec, post_vertex_slice,
            self._synapse_type.get_synapse_type_parameters())

        spec.write_array(ring_buffer_shifts)

        weight_scales = numpy.array([
            self._get_weight_scale(r) * weight_scale
            for r in ring_buffer_shifts])
        return weight_scales

    def _write_padding(
            self, spec, synaptic_matrix_region, next_block_start_address):
        next_block_allowed_address = self._population_table_type\
            .get_next_allowed_address(next_block_start_address)
        if next_block_allowed_address != next_block_start_address:

            # Pad out data file with the added alignment bytes:
            spec.comment("\nWriting population table required"
                         " padding\n")
            spec.switch_write_focus(synaptic_matrix_region)
            spec.set_register_value(
                register_id=15,
                data=next_block_allowed_address - next_block_start_address)
            spec.write_value(
                data=0xDD, repeats=15, repeats_is_register=True,
                data_type=DataType.UINT8)
            return next_block_allowed_address
        return next_block_start_address

    def _write_synaptic_matrix_and_master_population_table(
            self, spec, post_slices, post_slice_index, subvertex,
            post_vertex_slice, all_syn_block_sz, weight_scales,
            master_pop_table_region, synaptic_matrix_region, routing_info,
            graph_mapper, partitioned_graph):
        """ Simultaneously generates both the master population table and
            the synaptic matrix.
        """
        spec.comment(
            "\nWriting Synaptic Matrix and Master Population Table:\n")

        # Track writes inside the synaptic matrix region:
        next_block_start_address = 0
        n_synapse_types = self._synapse_type.get_n_synapse_types()

        # Get the edges
        in_subedges = \
            partitioned_graph.incoming_subedges_from_subvertex(subvertex)

        # Set up the master population table
        self._population_table_type.initialise_table(
            spec, master_pop_table_region)

        # For each subedge into the subvertex, create a synaptic list
        for subedge in in_subedges:

            edge = graph_mapper.get_partitionable_edge_from_partitioned_edge(
                subedge)
            if isinstance(edge, ProjectionPartitionableEdge):

                spec.comment("\nWriting matrix for subedge:{}\n".format(
                    subedge.label))

                pre_vertex_slice = graph_mapper.get_subvertex_slice(
                    subedge.pre_subvertex)
                pre_slices = graph_mapper.get_subvertex_slices(edge.pre_vertex)
                pre_slice_index = graph_mapper.get_subvertex_index(
                    subedge.pre_subvertex)

                for synapse_info in edge.synapse_information:

                    (row_data, row_length, delayed_row_data,
                     delayed_row_length, delayed_source_ids, delay_stages) = \
                        self._synapse_io.get_synapses(
                            synapse_info, pre_slices, pre_slice_index,
                            post_slices, post_slice_index, pre_vertex_slice,
                            post_vertex_slice, edge.n_delay_stages,
                            self._population_table_type, n_synapse_types,
                            weight_scales)

                    if edge.delay_edge is not None:
                        edge.delay_edge.pre_vertex.add_delays(
                            pre_vertex_slice, delayed_source_ids, delay_stages)
                    elif delayed_source_ids.size != 0:
                        raise Exception("Found delayed source ids but no delay"
                                        " edge for edge {}".format(edge.label))

                    if ((edge, synapse_info) in
                            self._pre_run_connection_holders):
                        holders = self._pre_run_connection_holders[
                            edge, synapse_info]
                        for connection_holder in holders:
                            connections = self._synapse_io.read_synapses(
                                synapse_info, pre_vertex_slice,
                                post_vertex_slice, row_length,
                                delayed_row_length, n_synapse_types,
                                weight_scales, row_data, delayed_row_data,
                                edge.n_delay_stages)
                            connection_holder.add_connections(connections)
                            connection_holder.finish()

                    if len(row_data) > 0:
                        next_block_start_address = self._write_padding(
                            spec, synaptic_matrix_region,
                            next_block_start_address)
                        spec.switch_write_focus(synaptic_matrix_region)
                        spec.write_array(row_data)
                        partition = partitioned_graph.get_partition_of_subedge(
                            subedge)
                        keys_and_masks = \
                            routing_info.get_keys_and_masks_from_partition(
                                partition)
                        self._population_table_type\
                            .update_master_population_table(
                                spec, next_block_start_address, row_length,
                                keys_and_masks, master_pop_table_region)
                        next_block_start_address += len(row_data) * 4
                    del row_data

                    if next_block_start_address > all_syn_block_sz:
                        raise Exception(
                            "Too much synaptic memory has been written:"
                            " {} of {} ".format(
                                next_block_start_address, all_syn_block_sz))

                    if len(delayed_row_data) > 0:
                        next_block_start_address = self._write_padding(
                            spec, synaptic_matrix_region,
                            next_block_start_address)
                        spec.switch_write_focus(synaptic_matrix_region)
                        spec.write_array(delayed_row_data)
                        keys_and_masks = self._delay_key_index[
                            (edge.pre_vertex, pre_vertex_slice.lo_atom,
                             pre_vertex_slice.hi_atom)]
                        self._population_table_type\
                            .update_master_population_table(
                                spec, next_block_start_address,
                                delayed_row_length, keys_and_masks,
                                master_pop_table_region)
                        next_block_start_address += len(delayed_row_data) * 4
                    del delayed_row_data

                    if next_block_start_address > all_syn_block_sz:
                        raise Exception(
                            "Too much synaptic memory has been written:"
                            " {} of {} ".format(
                                next_block_start_address, all_syn_block_sz))

        self._population_table_type.finish_master_pop_table(
            spec, master_pop_table_region)

    def write_data_spec(
            self, spec, vertex, post_vertex_slice, subvertex, placement,
            partitioned_graph, graph, routing_info, graph_mapper, input_type):

        # Create an index of delay keys into this subvertex
        for subedge in partitioned_graph.incoming_subedges_from_subvertex(
                subvertex):
            edge = graph_mapper.get_partitionable_edge_from_partitioned_edge(
                subedge)
            if isinstance(edge.pre_vertex, DelayExtensionVertex):
                pre_vertex_slice = graph_mapper.get_subvertex_slice(
                    subedge.pre_subvertex)
                partition = partitioned_graph.get_partition_of_subedge(subedge)
                self._delay_key_index[
                    (edge.pre_vertex.source_vertex, pre_vertex_slice.lo_atom,
                     pre_vertex_slice.hi_atom)] = \
                    routing_info.get_keys_and_masks_from_partition(partition)

        post_slices = graph_mapper.get_subvertex_slices(vertex)
        post_slice_index = graph_mapper.get_subvertex_index(subvertex)

        # Reserve the memory
        subvert_in_edges = partitioned_graph.incoming_subedges_from_subvertex(
            subvertex)
        all_syn_block_sz = self._get_exact_synaptic_blocks_size(
            post_slices, post_slice_index, post_vertex_slice, graph_mapper,
            subvertex, subvert_in_edges)
        self._reserve_memory_regions(
            spec, vertex, subvertex, post_vertex_slice, graph,
            partitioned_graph, all_syn_block_sz, graph_mapper)

        weight_scales = self._write_synapse_parameters(
            spec, subvertex, partitioned_graph, graph_mapper, post_slices,
            post_slice_index, post_vertex_slice, input_type)

        self._write_synaptic_matrix_and_master_population_table(
            spec, post_slices, post_slice_index, subvertex, post_vertex_slice,
            all_syn_block_sz, weight_scales,
            constants.POPULATION_BASED_REGIONS.POPULATION_TABLE.value,
            constants.POPULATION_BASED_REGIONS.SYNAPTIC_MATRIX.value,
            routing_info, graph_mapper, partitioned_graph)

        self._synapse_dynamics.write_parameters(
            spec, constants.POPULATION_BASED_REGIONS.SYNAPSE_DYNAMICS.value,
            self._machine_time_step, weight_scales)

        self._weight_scales[placement] = weight_scales

    def get_connections_from_machine(
            self, transceiver, placement, subedge, graph_mapper,
            routing_infos, synapse_info, partitioned_graph):

        edge = graph_mapper.get_partitionable_edge_from_partitioned_edge(
            subedge)
        if not isinstance(edge, ProjectionPartitionableEdge):
            return None

        # Get details for extraction
        pre_vertex_slice = graph_mapper.get_subvertex_slice(
            subedge.pre_subvertex)
        post_vertex_slice = graph_mapper.get_subvertex_slice(
            subedge.post_subvertex)
        n_synapse_types = self._synapse_type.get_n_synapse_types()

        # Get the key for the pre_subvertex
        partition = partitioned_graph.get_partition_of_subedge(subedge)
        key = routing_infos.get_keys_and_masks_from_partition(
            partition)[0].key

        # Get the key for the delayed pre_subvertex
        delayed_key = None
        if edge.delay_edge is not None:
            delayed_key = self._delay_key_index[
                (edge.pre_vertex, pre_vertex_slice.lo_atom,
                 pre_vertex_slice.hi_atom)][0].key

        # Get the block for the connections from the pre_subvertex
        master_pop_table_address = \
            helpful_functions.locate_memory_region_for_placement(
                placement,
                constants.POPULATION_BASED_REGIONS.POPULATION_TABLE.value,
                transceiver)
        synaptic_matrix_address = \
            helpful_functions.locate_memory_region_for_placement(
                placement,
                constants.POPULATION_BASED_REGIONS.SYNAPTIC_MATRIX.value,
                transceiver)
        data, max_row_length = self._retrieve_synaptic_block(
            transceiver, placement, master_pop_table_address,
            synaptic_matrix_address, key, pre_vertex_slice.n_atoms,
            synapse_info.index)

        # Get the block for the connections from the delayed pre_subvertex
        delayed_data = None
        delayed_max_row_length = 0
        if delayed_key is not None:
            delayed_data, delayed_max_row_length = \
                self._retrieve_synaptic_block(
                    transceiver, placement, master_pop_table_address,
                    synaptic_matrix_address, delayed_key,
                    pre_vertex_slice.n_atoms * edge.n_delay_stages,
                    synapse_info.index)

        # Convert the blocks into connections
        return self._synapse_io.read_synapses(
            synapse_info, pre_vertex_slice, post_vertex_slice,
            max_row_length, delayed_max_row_length, n_synapse_types,
            self._weight_scales[placement], data, delayed_data,
            edge.n_delay_stages)

    def _retrieve_synaptic_block(
            self, transceiver, placement, master_pop_table_address,
            synaptic_matrix_address, key, n_rows, index):
        """ Read in a synaptic block from a given processor and subvertex on\
            the machine
        """

        # See if we have already got this block
        if (placement, key, index) in self._retrieved_blocks:
            return self._retrieved_blocks[(placement, key, index)]

        items = \
            self._population_table_type.extract_synaptic_matrix_data_location(
                key, master_pop_table_address, transceiver,
                placement.x, placement.y)
        if index >= len(items):
            return None, None

        max_row_length, synaptic_block_offset = items[index]

        block = None
        if max_row_length > 0 and synaptic_block_offset is not None:

            # calculate the synaptic block size in bytes
            synaptic_block_size = self._synapse_io.get_block_n_bytes(
                max_row_length, n_rows)

            # read in and return the synaptic block
            block = transceiver.read_memory(
                placement.x, placement.y,
                synaptic_matrix_address + synaptic_block_offset,
                synaptic_block_size)

        self._retrieved_blocks[(placement, key, index)] = (
            block, max_row_length)
        return block, max_row_length

    # inherited from AbstractProvidesIncomingPartitionConstraints
    def get_incoming_partition_constraints(self):
        return self._population_table_type.get_edge_constraints()


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

# 1、爬取车家号（网址：https://chejiahao.autohome.com.cn/（4）
# 2、打开浏览器（8）
# 3、抓取首页代码（8）
# 4、获取任意车标题（8）
# 5、获取浏览数（8）
# 6、获取时间（8）
# 7、获取内容（8）
# 8、获取图片链接（8）
# 9、获取评论（8）
# 10、存入mongo（8）
# 11、存入txt（8）
# 12、存入csv（8）
# 13、在主要代码出写上注释（8）

import scrapy, json
from ..items import ChejiahaoItem

class CheSpider(scrapy.Spider):
    name = 'che'
    # allowed_domains = ['xxx']
    start_urls = ['https://chejiahao.autohome.com.cn/']

    def parse(self, response):
        title = response.xpath("//a/div[@class='introduceTop text-overflow']/text()")[0].extract()
        liulan = response.xpath("//*[@id='info-3373418']/div[3]/div[2]/span[1]/text()")[0].extract()
        shijian = response.xpath("//*[@id='info-3373418']/div[3]/div[2]/span[4]/text()")[0].extract()
        tupian = response.xpath("//div[@class='light-img']/div[1]/a/img[@class='indexlazy']/@src").extract()
        href = 'https://chejiahao.autohome.com.cn' + response.xpath("//div[@class='introduce fn-left']/a/@href")[
            0].extract()
        yield scrapy.Request(url=href, callback=self.parse_xq,
                             meta={'title': title, 'liulan': liulan, 'shijian': shijian, 'tupian': tupian})

    def parse_xq(self, response):
        title = response.meta['title']
        liulan = response.meta['liulan']
        shijian = response.meta['shijian']
        tupian = response.meta['tupian']
        content = response.xpath("//div[@class='introduce_content']/div[@class='chedan_describe']/text()")[
            0].extract().strip()
        pinglun = response.xpath("//div[@id='AutoBlogReplyList']//p[@class='user-comment']/text()").extract()
        comment_url = 'https://reply.autohome.com.cn/api/comments/show.json?id=3373418&page=1&appid=21&count=3&_=1551056189734'
        yield scrapy.Request(url=comment_url, callback=self.parse_pl,
                             meta={'title': title, 'liulan': liulan, 'shijian': shijian, 'tupian': tupian,
                                   'content': content})

    def parse_pl(self, response):
        title = response.meta['title']
        liulan = response.meta['liulan']
        shijian = response.meta['shijian']
        tupian = response.meta['tupian']
        content = response.meta['content']
        data = json.loads(response.text)
        pingluns = data['commentlist']
        pinglun = ''
        for pl in pingluns:
            pp = pl['RContent']
            pinglun += pp + ','
        item = ChejiahaoItem()
        item['title'] = title
        item['liulan'] = liulan
        item['shijian'] = shijian
        item['tupian'] = tupian
        item['content'] = content
        item['pinglun'] = pinglun
        yield item