# -*- coding: utf8 -*-

import os
import sys
import re
import requests
import shutil
from bs4 import BeautifulSoup
# from datetime import datetime, timedelta
import libs.common as CMN
g_logger = CMN.WSL.get_web_scrapy_logger()

@CMN.CLS.Singleton
class WebScrapyWorkdayCanlendar(object):

    def __init__(self, date_start=None, date_end=None):
        self.source_url_parsing_cfg = CMN.DEF.DEF_SOURCE_URL_PARSING[CMN.DEF.DEF_WORKDAY_CANLENDAR_DATA_SOURCE_REFERENCE_INDEX]
        self.url_format = self.source_url_parsing_cfg["url_format"]
        self.encoding = self.source_url_parsing_cfg["url_encoding"]
        self.select_flag = self.source_url_parsing_cfg["url_css_selector"]
###############################################################################################
# Caution: The types of the following member variabiles are FinanceDate
        self.date_start = CMN.CLS.FinanceDate(CMN.DEF.DEF_START_DATE_STR) if date_start is None else date_start
        self.date_end = CMN.FUNC.get_last_url_data_date(CMN.DEF.DEF_TODAY_MARKET_DATA_EXIST_HOUR, CMN.DEF.DEF_TODAY_MARKET_DATA_EXIST_MINUTE) if date_end is None else date_end
# The start/end time of scrapying data from the web
        self.date_start_from_web = self.date_start
        self.date_end_from_web = self.date_end
# The first/last workday
        self.date_first = None
        self.date_last = None
###############################################################################################
        self.update_from_web_flag = False # Should be updated for just one time
        self.date_start_year = self.date_start.year
        self.workday_canlendar = None
        self.workday_year_list = None

    def initialize(self):
        # import pdb; pdb.set_trace()
        self.update_workday_canlendar()

    def is_workday(self, date_cur):
        return self.__is_workday(date_cur.year, date_cur.month, date_cur.day)

    def __is_workday(self, year, month, day):
        if self.workday_canlendar is None:
            raise RuntimeError("Workday Canlendar is NOT initialized")
        date_check = CMN.CLS.FinanceDate(year, month, day)
        if not self.is_in_range(date_check):
            raise RuntimeError("The check date[%s] is OUT OF RANGE[%s %s]" % (date_check, self.date_start, self.date_end))
        return day in self.workday_canlendar[year][month - 1]

    def update_workday_canlendar(self):
        # import pdb; pdb.set_trace()
# Update data from the file
        need_update_from_web = self.__update_workday_from_file()
# It's required to update the new data
        if need_update_from_web:
# Update data from the web
            self.__update_workday_from_web()
# Write the result into the config file
            self.__write_workday_canlendar_to_file()
# Copy the config file to the finance_analyzer/finance_recorder_java project
            self.__copy_workday_canlendar_config_file()

    def __copy_workday_canlendar_config_file(self):
        current_path = os.path.dirname(os.path.realpath(__file__))
        [working_folder, project_name, lib_folder] = current_path.rsplit('/', 2)
        dst_folderpath_list = [
            "%s/%s/%s" % (working_folder, CMN.DEF.DEF_COPY_CONF_FILE_DST_PROJECT_NAME1, CMN.DEF.DEF_CONF_FOLDER),
            "%s/%s/%s" % (working_folder, CMN.DEF.DEF_COPY_CONF_FILE_DST_PROJECT_NAME2, CMN.DEF.DEF_CONF_FOLDER),
        ]
        src_filepath = "%s/%s/%s/%s" % (working_folder, project_name, CMN.DEF.DEF_CONF_FOLDER, CMN.DEF.DEF_WORKDAY_CANLENDAR_CONF_FILENAME)
        for dst_folderpath in dst_folderpath_list:
            if os.path.exists(dst_folderpath):
                g_logger.debug("Copy the file[%s] to %s" % (CMN.DEF.DEF_WORKDAY_CANLENDAR_CONF_FILENAME, dst_folderpath))
                shutil.copy2(src_filepath, dst_folderpath)

    def __update_workday_from_file(self):
        need_update_from_web = True
        conf_filepath = CMN.FUNC.get_config_filepath(CMN.DEF.DEF_WORKDAY_CANLENDAR_CONF_FILENAME)
        g_logger.debug("Try to Acquire the Workday Canlendar data from the file: %s......" % conf_filepath)
        if not os.path.exists(conf_filepath):
            g_logger.warn("The Workday Canlendar config file does NOT exist")
            return need_update_from_web
        try:
            date_range_str = None
            with open(conf_filepath, 'r') as fp:
                for line in fp:
                    if date_range_str is None:
                        date_range_str = line
                        mobj = re.search("([\d]{4}-[\d]{2}-[\d]{2}) ([\d]{4}-[\d]{2}-[\d]{2})", date_range_str)
                        if mobj is None:
                            raise RuntimeError("Unknown format[%s] of date range in Workday Canlendar config file", line)
                        date_start_from_file = CMN.CLS.FinanceDate(mobj.group(1))
                        date_end_from_file = CMN.CLS.FinanceDate(mobj.group(2))
                        g_logger.debug("Original Date Range in Workday Canlendar config file: %s, %s" % (mobj.group(1), mobj.group(2)))
                        if date_start_from_file > self.date_start:
                            raise RuntimeError("Incorrect start date; File: %s, Expected: %s", date_start_from_file, self.date_start)
# Check the time range in the file and adjust the range of scrapying data from the web
                        if date_end_from_file >= self.date_end:
                            g_logger.debug("The last data has already existed in the file. It's no need to scrap data from the web")
                            need_update_from_web = False
                        else:
                            self.date_start_from_web = date_end_from_file + 1
                            g_logger.debug("Adjust the time range of web scrapy to %s %s" % (self.date_start_from_web, self.date_end_from_web))
                    else:
# Obtain the "year" value
                        mobj = re.search("\[([\d]{4})\]", line)
                        if mobj is None:
                            raise RuntimeError("Incorrect year format in Workday Canlendar config file: %s", line)
                        year = int(mobj.group(1))
                        # self.workday_canlendar[year] = self.__init_canlendar_each_year_list()
                        tmp_data_list = line.split(']')
                        if len(tmp_data_list) != 2:
                            raise RuntimeError("Incorrect data format in Workday Canlendar config file: %s", line)
# Parse the workday in each month
                        year_workday_list = tmp_data_list[1].rstrip("\n").split(";")
                        for year_workday_list_per_month in year_workday_list:
                            tmp_data1_list = year_workday_list_per_month.split(':')
                            if len(tmp_data1_list) != 2:
                                raise RuntimeError("Incorrect per month data format in Workday Canlendar config file: %s", line)
                            month = int(tmp_data1_list[0])
                            workday_list_str = tmp_data1_list[1]
                            workday_list = [int(workday_str) for workday_str in workday_list_str.split(",")]
# Check if there are nay duplicate elements in the list
                            if len(workday_list) != len(set(workday_list)):
                                # import pdb; pdb.set_trace()
                                raise RuntimeError("Duplicate element in [%d, %d]: %s", year, month, workday_list)
                            self.__set_canlendar_each_month(year, month, workday_list)
        except Exception as e:
            g_logger.error("Error occur while parsing Workday Canlendar config, due to %s" % str(e))
            raise e

        self.workday_year_list = sorted(self.workday_canlendar.keys())
        return need_update_from_web

    def __update_workday_from_web(self):
        if not self.update_from_web_flag:
            self.update_from_web_flag = True
        else:
            raise RuntimeError("Update workday from web should NOT be called more than once")
        # import pdb; pdb.set_trace()
        g_logger.debug("Try to Acquire the Workday Canlendar [%s:%s] data from the web......" % (self.date_start_from_web, self.date_end_from_web))
        if self.date_start_from_web.year == self.date_end_from_web.year and self.date_start_from_web.month == self.date_end_from_web.month:
            self.__update_workday_from_web_by_month(self.date_start_from_web.year, self.date_start_from_web.month, self.date_start_from_web.day, self.date_end_from_web.day)
        else:
            self.__update_workday_from_web_by_month(self.date_start_from_web.year, self.date_start_from_web.month, start_day=self.date_start_from_web.day)
            year = self.date_start_from_web.year
            month = self.date_start_from_web.month
            year_end = self.date_end_from_web.year
            month_end = self.date_end_from_web.month
            def get_next_month(cur_year, cur_month):
                next_year = cur_year + 1 if cur_month == 12 else cur_year
                next_month = 1 if cur_month == 12 else cur_month + 1
                return (next_year, next_month)
            while True:
                (year, month) = get_next_month(year, month)
                if year == year_end and month == month_end:
                    break
                self.__update_workday_from_web_by_month(year, month)
            self.__update_workday_from_web_by_month(self.date_end_from_web.year, self.date_end_from_web.month, end_day=self.date_end_from_web.day)
        self.workday_year_list = sorted(self.workday_canlendar.keys())
        # for year in self.workday_year_list:
        #     workday_month_list = self.workday_canlendar[year]
        #     print "%d: %s" % (year, workday_month_list)

    def __update_workday_from_web_by_month(self, year, month, start_day=None, end_day=None):
# Check if scrapying the whole month data
        # import pdb; pdb.set_trace()
        whole_month_data = False
#***************************************************
# # Check if the whole month data is required
#         if start_day is None and end_day is None:
#             whole_month_data = True
#         elif end_day is None and start_day == 1:
#             whole_month_data = True
#         elif start_day is None and end_day == CMN.FUNC.get_month_last_day(year, month):
#             whole_month_data = True
# # Assemble the URL
#         url = self.url_format.format(*(year, month))
#***************************************************
# Setup the start/end date if it's None
        if start_day is None: start_day = 1
        if end_day is None: end_day = CMN.FUNC.get_month_last_day(year, month)
        if start_day == 1 and end_day == CMN.FUNC.get_month_last_day(year, month):
            whole_month_data = True
        url = self.url_format.format(*(year, month, start_day, end_day))
# Scrap the web data
        # try:
        #     # g_logger.debug("Try to Scrap data [%s]" % url)
        #     res = CMN.FUNC.request_from_url_and_check_return(url)
        # except requests.exceptions.Timeout as e:
        #     # g_logger.debug("Try to Scrap data [%s]... Timeout" % url)
        #     fail_to_scrap = False
        #     for index in range(self.SCRAPY_RETRY_TIMES):
        #         time.sleep(randint(1,3))
        #         try:
        #             res = requests.get(url, timeout=CMN.DEF.DEF_SCRAPY_WAIT_TIMEOUT)
        #         except requests.exceptions.Timeout as ex:
        #             fail_to_scrap = True
        #         if not fail_to_scrap:
        #             break
        #     if fail_to_scrap:
        #         g_logger.error("Fail to scrap workday list data even retry for %d times !!!!!!" % self.SCRAPY_RETRY_TIMES)
        #         raise e
        req = CMN.FUNC.try_to_request_from_url_and_check_return(url)
# Select the section we are interested in
        req.encoding = self.encoding
        # print res.text
        soup = BeautifulSoup(req.text)
        web_data = soup.select(self.select_flag)
        workday_list = []
        web_data_len = len(web_data)
# Parse the web data and obtain the workday list
        if web_data_len != 0:
        # print "len: %d" % data_len
#***************************************************
            # for tr in web_data[2:]:
#***************************************************
            for tr in web_data[web_data_len - 1 : 0 : -1]:
                td = tr.select('td')
                date_list = td[0].text.split('/')
                if len(date_list) != 3:
                    raise RuntimeError("The date format is NOT as expected: %s", date_list)
                cur_day = int(date_list[2])
                if not whole_month_data and cur_day < start_day:
# Caution: It's NO need to consider the end date since the last data is always today
                    continue
                workday_list.append(cur_day)
        # import pdb; pdb.set_trace()
        self.__set_canlendar_each_month(year, month, workday_list)
# # Find the workday list
#         allday_list = []
#         if whole_month_data:
#             allday_list = range(1, CMN.get_month_last_day(year, month) + 1)
#         else:
#             list_start_date = 1 if start_day is None else start_day
#             list_end_date = CMN.get_month_last_day(year, month) if end_day is None else end_day
#             allday_list = range(list_start_date, list_end_date + 1)
# # Get the non-workday list and set to the data structure
#         non_workday_list = list(set(allday_list) - set(workday_list))
#         self.__set_canlendar_each_month(year, month, non_workday_list)

    def __set_canlendar_each_month(self, year, month, workday_list):
        if not workday_list:
            return
        if self.workday_canlendar is None:
            self.workday_canlendar = {}
        if year not in self.workday_canlendar:
            self.workday_canlendar[year] = self.__init_canlendar_each_year_list()
        self.workday_canlendar[year][month - 1].extend(workday_list)
        self.workday_canlendar[year][month - 1].sort()

    def __init_canlendar_each_year_list(self):
        workday_canlendar_year_list = []
        for index in range(12):
            workday_canlendar_year_list.append([])
        return workday_canlendar_year_list

    def __write_workday_canlendar_to_file(self):
        # import pdb; pdb.set_trace()
        conf_filepath = CMN.FUNC.get_config_filepath(CMN.DEF.DEF_WORKDAY_CANLENDAR_CONF_FILENAME)
        g_logger.debug("Write the Workday Canlendar data to the file: %s......" % conf_filepath)
        try:
            date_range_str = None
            with open(conf_filepath, 'w') as fp:
                g_logger.debug("Start to write workday into %s", CMN.DEF.DEF_WORKDAY_CANLENDAR_CONF_FILENAME)
                fp.write("%s %s\n" % (self.date_start, self.date_end))
                # year_list = sorted(self.workday_canlendar)
                for year in self.workday_year_list:
                    workday_month_list = self.workday_canlendar[year]
                    # print "%d: %s" % (year, workday_month_list)
                    # sys.stderr.write("%s" % ("[%04d]" % year + ";".join(["%d:%s" % (month + 1, ",".join([str(workday) for workday in workday_month_list[month]])) for month in range(12)]) + "\n"))
                    workday_each_year_str = "[%04d]" % year + ";".join(["%d:%s" % (month + 1, ",".join([str(workday) for workday in workday_month_list[month]])) for month in range(12) if len(workday_month_list[month]) != 0]) + "\n"
                    # for month in range(12):
                    #     workday_each_year_str += "%d:%s;" % (month + 1, ",".join([str(workday) for workday in workday_month_list[month]]))
                    # workday_each_year_str += "\n"
                    g_logger.debug("Write data: %s" % workday_each_year_str)
                    fp.write(workday_each_year_str)
                    # print workday_each_year_str
        except Exception as e:
            g_logger.error("Error occur while writing Workday Canlendar into config file, due to %s" % str(e))
            raise e

    def get_first_workday(self):
        if self.date_first is None:
            if self.workday_canlendar is None:
                raise RuntimeError("Incorrect Operation: self.workday_canlendar is None")
            year = self.workday_year_list[0]
            for month in range(12):
                if len(self.workday_canlendar[year][month]) != 0:
                    self.date_first = CMN.CLS.FinanceDate(year, month + 1, self.workday_canlendar[year][month][0])
                    break
            if self.date_first is None:
                raise RuntimeError("Fail to find the frst workday in the canlendar")
        return self.date_first

    def get_last_workday(self):
        if self.date_last is None:
            if self.workday_canlendar is None:
                raise RuntimeError("Incorrect Operation: self.workday_canlendar is None")
            # import pdb; pdb.set_trace()
            # workday_year_list = sorted(self.workday_canlendar.keys())
            year = self.workday_year_list[-1]
            for month in range(12):
                if len(self.workday_canlendar[year][month]) == 0:
                    self.date_last = CMN.CLS.FinanceDate(year, month, self.workday_canlendar[year][month - 1][-1])
                    break
            if self.date_last is None:
                month = 12
                self.date_last = CMN.CLS.FinanceDate(year, month, self.workday_canlendar[year][month - 1][-1])
        return self.date_last

    def is_in_range(self, date_cur):
        date_first = self.get_first_workday()
        date_last = self.get_last_workday()
        result = (self.get_first_workday() <= date_cur <= self.get_last_workday())
        if not result:
            g_logger.debug("Date[%s] is NOT in range[%s, %s]" % (date_cur, self.get_first_workday(), self.get_last_workday()))
        return result

    def find_index(self, date_cur):
        # import pdb; pdb.set_trace()
        if self.workday_canlendar is None:
            raise RuntimeError("Incorrect Operation: self.workday_canlendar is None")
        year_index = None
        month_index = None
        day_index = None
        try:
            year_index = self.workday_year_list.index(date_cur.year)
        except ValueError as e:
            return None
        year = self.workday_year_list[year_index]
        if len(self.workday_canlendar[year][date_cur.month - 1]) == 0:
            return None
        month_index = date_cur.month - 1
        try:
            day_index = self.workday_canlendar[year][month_index].index(date_cur.day)
        except ValueError as e:
            return None

        # g_logger.debug("The date[%s] index: %d %d %d" % (CMN.to_date_only_str(date_cur), year_index, month_index, day_index))
        return (year_index, month_index, day_index)

    def find_nearest_next_index(self, date_cur):
        if self.workday_canlendar is None:
            raise RuntimeError("Incorrect Operation: self.workday_canlendar is None")
        year_index = None
        month_index = None
        day_index = None
        is_workday = False
        if not self.is_in_range(date_cur):
            if date_cur > self.get_last_workday():
                return None
            else:
                date_cur = self.get_first_workday()
                is_workday = True
        else:
            is_workday = self.is_workday(date_cur)

        if is_workday:
            (year_index, month_index, day_index) = self.find_index(date_cur)
        else:
            if not self.is_in_range(date_cur):
                return None
            try:
                year_index = self.workday_year_list.index(date_cur.year)
            except ValueError as e:
                return None
            # year = self.workday_year_list[year_index]
            month_index = date_cur.month - 1
            day_list = self.workday_canlendar[date_cur.year][month_index]
            for index, day in enumerate(day_list):
                if day > date_cur.day:
                    day_index = index
                    break
            if day_index is None:
                if month_index == 11:
# A new year
                    year_index += 1
                    month_index = 0
                    day_index = 0
                else:
# A new month
                    month_index += 1
                    day_index = 0
        # g_logger.debug("The date[%s] index: %d %d %d" % (date_cur, year_index, month_index, day_index))
        return (year_index, month_index, day_index)

    def get_nearest_next_workday(self, date_cur):
        index_tuple = self.find_nearest_next_index(date_cur)
        if index_tuple is None:
            raise RuntimeError("Fail to find the nearest next workday from the date: %s" % date_cur)
        (year_index, month_index, day_index) = index_tuple
        year = self.workday_year_list[year_index]
        date_nearest_next = CMN.CLS.FinanceDate(year, month_index + 1, self.workday_canlendar[year][month_index][day_index])
        if not self.is_workday(date_cur):
            g_logger.debug("Find the nearest next workday[%s]: %s" % (date_cur, date_nearest_next))
        return date_nearest_next

    def find_nearest_prev_index(self, date_cur):
        if self.workday_canlendar is None:
            raise RuntimeError("Incorrect Operation: self.workday_canlendar is None")
        year_index = None
        month_index = None
        day_index = None
        is_workday = False
        if not self.is_in_range(date_cur):
            if date_cur < self.get_first_workday():
                return None
            else:
                date_cur = self.get_last_workday()
                is_workday = True
        else:
            is_workday = self.is_workday(date_cur)

        if is_workday:
            (year_index, month_index, day_index) = self.find_index(date_cur)
        else:
            try:
                year_index = self.workday_year_list.index(date_cur.year)
            except ValueError as e:
                return None
            # year = self.workday_year_list[year_index]
            month_index = date_cur.month - 1
            # import pdb; pdb.set_trace()
            day_list = self.workday_canlendar[date_cur.year][month_index]
            for index, day in reversed(list(enumerate(day_list))):
                if day < date_cur.day:
                    day_index = index
                    break
            if day_index is None:
                if month_index == 1:
# An old year
                    year_index -= 1
                    month_index = 11
                    day_index = len(self.workday_canlendar[date_cur.year - 1][month_index]) - 1
                else:
# An old month
                    month_index -= 1
                    day_index = len(self.workday_canlendar[date_cur.year - 1][month_index]) - 1
        # g_logger.debug("The date[%s] index: %d %d %d" % (CMN.to_date_only_str(date_cur), year_index, month_index, day_index))
        return (year_index, month_index, day_index)

    def get_nearest_prev_workday(self, date_cur):
        # import pdb; pdb.set_trace()
        index_tuple = self.find_nearest_prev_index(date_cur)
        if index_tuple is None:
            raise RuntimeError("Fail to find the nearest previous workday from the date: %s" % date_cur)
        (year_index, month_index, day_index) = index_tuple
        year = self.workday_year_list[year_index]
        date_nearest_prev = CMN.CLS.FinanceDate(year, month_index + 1, self.workday_canlendar[year][month_index][day_index])
        if not self.is_workday(date_cur):
            g_logger.debug("Find the nearest previous workday[%s]: %s" % (date_cur, date_nearest_prev))
        return date_nearest_prev

####################################################################################################

class WorkdayIterator(object):

    def __init__(self, date_start=None, date_end=None, ExceptionWhenStartLaterThanEnd=False):
        self.workday_canlendar_obj = WebScrapyWorkdayCanlendar.Instance()
        self.workday_canlendar = self.workday_canlendar_obj.workday_canlendar
        self.workday_year_list = self.workday_canlendar_obj.workday_year_list

        if date_start is None:
            date_start = self.workday_canlendar_obj.get_first_workday()
        assert (isinstance(date_start, CMN.CLS.FinanceDate)), "The type of start time[%s] is NOT FinanceDate" % date_start
        if date_end is None:
            date_end = self.workday_canlendar_obj.get_last_workday()
        assert (isinstance(date_end, CMN.CLS.FinanceDate)), "The type of end time[%s] is NOT FinanceDate" % date_end

        self.time_to_stop = False
        self.cur_year_index = None
        self.cur_month_index = None
        self.cur_day_index = None
        if date_start > date_end:
            if ExceptionWhenStartLaterThanEnd:
                raise ValueError("The start date[%s] should NOT be later than the end date[%s]" % (date_start, date_end))
            else:
                g_logger.debug("The start date[%s] is later than the end date[%s]" % (date_start, date_end))
            self.time_to_stop = True
        else:
            start_tuple = self.workday_canlendar_obj.find_index(date_start)
            if start_tuple is None:
                raise ValueError("The start date[%s] is NOT a workday" % date_start)
            (start_year_index, start_month_index, start_day_index) = start_tuple
            g_logger.debug("The start date[%s] index: %d %d %d" % (date_start, start_year_index, start_month_index, start_day_index))
            end_tuple = self.workday_canlendar_obj.find_index(date_end)
            if end_tuple is None:
                raise ValueError("The end date[%s] is NOT a workday" % date_end)
            (self.end_year_index, self.end_month_index, self.end_day_index) = end_tuple
            g_logger.debug("The end date[%s] index: %d %d %d" % (date_end, self.end_year_index, self.end_month_index, self.end_day_index))
            self.cur_year_index = start_year_index
            self.cur_month_index = start_month_index
            self.cur_day_index = start_day_index

    def __iter__(self):
        return self

    def next(self):
        # import pdb; pdb.set_trace()
        if self.time_to_stop:
            raise StopIteration
        if self.cur_year_index == self.end_year_index and self.cur_month_index == self.end_month_index and self.cur_day_index == self.end_day_index:
            self.time_to_stop = True
        year = self.workday_year_list[self.cur_year_index]
        date_cur = CMN.CLS.FinanceDate(year, self.cur_month_index + 1, self.workday_canlendar[year][self.cur_month_index][self.cur_day_index])
# Find the next element
        if self.cur_month_index == 11:
            if self.cur_day_index == len(self.workday_canlendar[year][self.cur_month_index]) - 1:
# A new year
                self.cur_year_index += 1
                self.cur_month_index = 0
                self.cur_day_index = 0
            else:
                self.cur_day_index += 1
        else:
            if self.cur_day_index == len(self.workday_canlendar[year][self.cur_month_index]) - 1:
# A new month
                self.cur_month_index += 1
                self.cur_day_index = 0
            else:
                self.cur_day_index += 1
        return date_cur

####################################################################################################

class WorkdayNearestIterator(WorkdayIterator):

    def __init__(self, date_start=None, date_end=None, ExceptionWhenStartLaterThanEnd=False):
        # import pdb;pdb.set_trace()
        workday_canlendar_obj = WebScrapyWorkdayCanlendar.Instance()
        date_nearest_start = workday_canlendar_obj.get_nearest_next_workday(date_start) if date_start is not None else None
        date_nearest_end = workday_canlendar_obj.get_nearest_prev_workday(date_end) if date_end is not None else None
        super(WorkdayNearestIterator, self).__init__(date_nearest_start, date_nearest_end, ExceptionWhenStartLaterThanEnd)


import numpy as np
import matplotlib.pyplot as plt
import cmath as cm
j=cm.sqrt(-1)
w=np.linspace(0,2*np.pi,1000)
x=[1.0/3.0,1.0/3.0,1.0/3.0,0.0]
y=[]
y=np.zeros(1000)
l=len(x)
for i in range(0,1000):
	sum=0
	for n in range(0,l-1):
		sum=sum+(x[n]*(np.exp(-j*w[i]*n)))
		y[i]=sum
	y=np.append(y,sum)
print(y)
p=np.abs(y)
plt.subplot(2,1,1)
plt.plot(p)
q=np.angle(y)
plt.subplot(2,1,2)
plt.plot(q)
plt.show()


'''

裁剪圖片

'''

from PIL import Image   # Importing Image class from PIL module

filename = r'C:/_git/vcs/_1.data/______test_files1/picture1.jpg'

# Opens a image in RGB mode
im = Image.open(filename)

# Size of the image in pixels (size of original image)
# (This is not mandatory)
width, height = im.size

print(width)
print(height)

# Setting the points for cropped image
left = 20
top = 20
right = width - 20 *2
bottom = height - 20 * 2

# Cropped image of above dimension
# (It will not change original image)
im1 = im.crop((left, top, right, bottom))

# Shows the image in image viewer
im.show()
im1.show()


from django.shortcuts import render
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from .models import Book, Author, BookRating, Genre
from .forms import RateBookForm

# Create your views here.

@login_required
def index(request):

   my_reviews = BookRating.objects.filter(user__pk=request.user.pk)
   book_list = Book.objects.all()
   review_ids = [r.book.pk for r in my_reviews]
   id_list = [book.pk for book in book_list]
   book_feed =[book for book in book_list if book.pk not in review_ids]
   book_feed = book_feed[:10]

   return render(
      request,
      'index.html',
      context={'book_list': book_feed},
   )

class BookListView(LoginRequiredMixin, generic.ListView):
   model = Book
   context_object_name = 'book_list'
   template_name='catalog/book_list.html'
   paginate_by = 10

class BookDetailView(LoginRequiredMixin, generic.DetailView):
   model = Book
   context_object_name = 'book'
   template_name='catalog/book_detail.html'

class AuthorListView(LoginRequiredMixin, generic.ListView):
   model = Author
   context_object_name = 'author_list'
   template_name='catalog/author_list.html'
   paginate_by = 10

class AuthorDetailView(LoginRequiredMixin, generic.DetailView):
   model = Author
   context_object_name = 'author'
   template_name='catalog/author_detail.html'

   def get_context_data(self, **kwargs):
       context = super(AuthorDetailView, self).get_context_data(**kwargs)
       context['books'] = Book.objects.filter(author__pk=context['author'].pk)
       return context

class BookRatingsByUserListView(LoginRequiredMixin, generic.ListView):
    """
    Generic class-based view listing books on loan to current user.
    """
    model = BookRating
    context_object_name = 'ratings'
    template_name ='catalog/bookrating_list_user.html'
    paginate_by = 10

    def get_queryset(self):
        return BookRating.objects.filter(user=self.request.user)

@login_required
def rate_book(request, pk):

    book = get_object_or_404(Book, pk = pk)

    rating = None

    try:
        rating = BookRating.objects.get(user=request.user, book=book)
    except BookRating.DoesNotExist:
        pass

    if request.method == 'POST':
        form = RateBookForm(request.POST)

        if form.is_valid():

            book_rating = BookRating()

            if rating:
                book_rating = rating
                book.accumulated_rate -= book_rating.rate
                book.number_of_reviews -= 1

            book_rating.book = book
            book_rating.user = request.user
            book_rating.rate = form.cleaned_data['rate']
            book_rating.comment = form.cleaned_data['comment']
            book_rating.status = form.cleaned_data['status']
            book_rating.save()

            book.accumulated_rate += form.cleaned_data['rate']
            book.number_of_reviews += 1
            book.save()

            return HttpResponseRedirect(reverse('my-readings'))

    else:
        init_data = {'rate': 0, 'comment': '', 'status': 'i'}
        if rating:
            init_data = {'rate': rating.rate, 'comment': rating.comment, 'status': rating.status}

        form = RateBookForm(initial=init_data)

    return render(request, 'catalog/book_rating.html', {'form': form, 'book': book})


from configparser import ConfigParser
config = ConfigParser()

class map_fact_production:
    def __init__(self, file_config):
        config.read(file_config, encoding='utf-8-sig')
        self.script = "insert into dbo.Table_Map_FACT_PRODUCTION (Etat_reel,Etat_erp) Values \n"

    def mapping(self):
        section_name = 'Table_Map_FACT_PRODUCTION'
        if (config.options(section_name) == []):
            self.script=" \n";
        else:
            for key, value in config.items(section_name):
                if(value == ""):
                    self.script=" \n";
                    break
                self.script = self.script+"("+key+","+value+"),\n"

        return self.script[:-2]+"\n"


# pylint: disable=invalid-name
"""handleRouteHealthCheck"""
from setup_adaguc import setup_adaguc
from flask_cors import cross_origin
from flask import Blueprint, Response

routeHealthCheck = Blueprint('routeHealthCheck', __name__)

@routeHealthCheck.route("/healthcheck", methods=["GET"])
@cross_origin()
def handleRouteHealthCheck():
    """handleRouteHealthCheck"""
    setup_adaguc(False)
    response = Response(
        response="OK",
        mimetype='text/plain',
        status=200,
    )
    return response


# THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY O
# ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
# PARTICULAR PURPOSE.
#
# Copyright 2020-2029 Zach (Yuzhe) Ni All rights reserved

#
# The purpose of this python program is to automatically create web pages (i.e. index.html, <posts>.html, <archivedate>.html).

import zipfile
import os, time, datetime

#
# Initialize all the variable
#

zipfilelist = {}
blog_description = open("blog.txt", "r")
blog = blog_description.read().split('\n')
allfile = []
bucket = { }
archive_content = ""
thumbnail = "title

"
strblogpost = "

  as2TITLEs2a

as2DATEs2a by Zach Ni
 as2Content2sa
"

#
# filtering metadata
#
for i in range(0,len(blog)-1,2):
    modified = os.path.getmtime(blog[i])
    Timestamped = time.ctime(modified).split(' ')[1]+' '+time.ctime(modified).split(' ')[2]+' '+time.ctime(modified).split(' ')[-1]
    Monthyearstamped = time.ctime(modified).split(' ')[1]+' '+time.ctime(modified).split(' ')[-1]
    a = {
        "filename" : blog[i],
        "title" : blog[i+1],
        "time" : os.stat(blog[i]).st_mtime,
        "Timestamped" : Timestamped,
        "Monthyearstamped" : Monthyearstamped
    }
    allfile.append(a)

#
# Sorting posts based on time in ascending order, allfile[-1] represents the metadata for the latest modified file
#
def sortcomp(e):
    return e["time"]
allfile.sort(key=sortcomp)

#
# Initialize buckets which contain specific month/year and their respective posts
#

for x in allfile:
    bucket[x['Monthyearstamped']] = []

for x in allfile:
    bucket[x['Monthyearstamped']].append(x)

#
# Create Archive Content for different year/month
#
for x in bucket:
    filename = ""
    for i in x.split(' '):
        filename += i
    filename += ".html"
    archive_content += thumbnail.replace("page",filename).replace("title",x)

#
# Read template for blog posts
#

template_file = open("template.html", 'r')
template = template_file.read()

#
# write to specific blog html file
#

for x in allfile:
    title = x['title']
    file = x['filename']
    Timestamped = x['Timestamped']
    Monthyearstamped = x['Monthyearstamped']
    content_file = open(file, 'r')
    content = content_file.read()
    result = template.replace("", content).replace("", title).replace("", Timestamped).replace("", archive_content)
    html_file = open(file.replace(".txt", ".html"), "w")
    zipfilelist[file.replace(".txt", ".html")] = 1
    html_file.write(result)
    html_file.close()

#
# Read Archives html file for creating specific datetime.html files and create them
#

content_file = open("Archives.html", 'r')
content = content_file.read()

for x in bucket:
    date = x
    filename = ""
    for i in date.split(' '):
        filename += i
    filename += ".html"
    post = ""
    for y in bucket[x]:
        title = y['title']
        file = y['filename']
        post += thumbnail.replace("page",file.replace(".txt", ".html")).replace("title",title)
    result = content.replace("",date).replace("",post).replace("",archive_content)
    html_file = open(filename, "w")
    zipfilelist[filename] = 1
    html_file.write(result)
    html_file.close()

#
# Write to index file
#

bp = ""
count = 0
for y in range(len(allfile)-1,-1,-1):
    count = count + 1
    x = allfile[y]
    if count > 3:
        break
    content_file = open(x['filename'], 'r')
    content = content_file.read()
    htmltext = x['filename'].replace(".txt",".html")
    bp += strblogpost.replace("as2TITLEs2a",x['title']).replace("as2DATEs2a",x['Timestamped']).replace('as2Content2sa',content).replace("as2LINK2sa",htmltext )

content_file = open("index32.html", 'r')
content = content_file.read()
result = content.replace("",bp).replace("", archive_content)
html_file = open("index.html", "w")
zipfilelist["index.html"] = 1
html_file.write(result)
html_file.close()

from zipfile import ZipFile

# zip related html pages

with ZipFile('pages.zip', 'w') as myzip:
    for file in zipfilelist:
        myzip.write(file)


# uncompyle6 version 3.7.0
# Python bytecode 2.4 (62061)
# Decompiled from: Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 22:39:24) [MSC v.1916 32 bit (Intel)]
# Embedded file name: C:\Cygwin\home\toonpub\player_1_0_46_qa\toontown\src\battle\DistributedBattleWaitersAI.py
from direct.directnotify import DirectNotifyGlobal
from toontown.battle import DistributedBattleFinalAI

class DistributedBattleWaitersAI(DistributedBattleFinalAI.DistributedBattleFinalAI):
    __module__ = __name__
    notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBattleWaitersAI')

    def __init__(self, air, bossCog, roundCallback, finishCallback, battleSide):
        DistributedBattleFinalAI.DistributedBattleFinalAI.__init__(self, air, bossCog, roundCallback, finishCallback, battleSide)

    def startBattle(self, toonIds, suits):
        self.joinableFsm.request('Joinable')
        for toonId in toonIds:
            if self.addToon(toonId):
                self.activeToons.append(toonId)

        self.d_setMembers()
        for suit in suits:
            self.pendingSuits.append(suit)

        self.d_setMembers()
        self.needAdjust = 1
        self.b_setState('ReservesJoining')


from __future__ import print_function

import click
from timeit import default_timer as timer

from dwave.cloud.qpu import Client
from dwave.cloud.utils import readline_input
from dwave.cloud.exceptions import (
    SolverAuthenticationError, InvalidAPIResponseError, UnsupportedSolverError)
from dwave.cloud.config import (
    load_config_from_file, get_default_config,
    detect_configfile_path, get_default_configfile_path)

@click.group()
def cli():
    """D-Wave cloud tool."""

@cli.command()
@click.option('--config-file', default=None, help='Config file path',
              type=click.Path(exists=True, dir_okay=False))
@click.option('--profile', default=None,
              help='Connection profile name (config section name)')
def configure(config_file, profile):
    """Create and/or update cloud client configuration file."""

    # determine the config file path
    if config_file:
        print("Using config file:", config_file)
    else:
        # path not given, try to detect; or use default, but allow user to override
        config_file = detect_configfile_path()
        if config_file:
            print("Found existing config file:", config_file)
        else:
            config_file = get_default_configfile_path()
            print("Config file not found, the default location is:", config_file)
        config_file = readline_input("Confirm config file path (editable): ", config_file)

    # try loading existing config, or use defaults
    try:
        config = load_config_from_file(config_file)
    except ValueError:
        config = get_default_config()

    # determine profile
    if profile:
        print("Using profile:", profile)
    else:
        existing = config.sections()
        if existing:
            profiles = 'create new or choose from: {}'.format(', '.join(existing))
            default_profile = ''
        else:
            profiles = 'create new'
            default_profile = 'prod'
        while not profile:
            profile = readline_input("Profile (%s): " % profiles, default_profile)
            if not profile:
                print("Profile name can't be empty.")

    if not config.has_section(profile):
        config.add_section(profile)

    # fill out the profile variables
    variables = 'endpoint token client solver proxy'.split()
    prompts = ['API endpoint URL (editable): ', 'Auth token (editable): ',
               'Client class (qpu or sw): ', 'Solver (can be left blank): ',
               'Proxy URL (can be left blank): ']
    for var, prompt in zip(variables, prompts):
        default_val = config.get(profile, var, fallback=None)
        val = readline_input(prompt, default_val)
        if val != default_val:
            config.set(profile, var, val)

    with open(config_file, 'w') as fp:
        config.write(fp)

    print("Config saved.")
    return 0

@cli.command()
@click.option('--config-file', default=None, help='Config file path',
              type=click.Path(exists=True, dir_okay=False))
@click.option('--profile', default=None, help='Connection profile name')
def ping(config_file, profile):
    """Ping the QPU by submitting a single-qubit problem."""

    try:
        client = Client.from_config(config_file=config_file, profile=profile)
    except Exception as e:
        print("Invalid config: {}".format(e))
        return 1
    if config_file:
        print("Using config file:", config_file)
    if profile:
        print("Using profile:", profile)
    print("Using endpoint:", client.endpoint)

    t0 = timer()
    try:
        solvers = client.get_solvers()
    except SolverAuthenticationError:
        print("Authentication error. Check credentials in your config file.")
        return 1
    except (InvalidAPIResponseError, UnsupportedSolverError):
        print("Invalid or unexpected API response.")
        return 2

    try:
        solver = client.get_solver()
    except (ValueError, KeyError):
        # if not otherwise defined (ValueError), or unavailable (KeyError),
        # just use the first solver
        if solvers:
            _, solver = next(iter(solvers.items()))
        else:
            print("No solvers available.")
            return 1

    t1 = timer()
    print("Using solver: {}".format(solver.id))

    timing = solver.sample_ising({0: 1}, {}).timing
    t2 = timer()

    print("\nWall clock time:")
    print(" * Solver definition fetch web request: {:.3f} ms".format((t1-t0)*1000.0))
    print(" * Problem submit and results fetch: {:.3f} ms".format((t2-t1)*1000.0))
    print(" * Total: {:.3f} ms".format((t2-t0)*1000.0))
    print("\nQPU timing:")
    for component, duration in timing.items():
        print(" * {} = {} us".format(component, duration))
    return 0


import numpy as np

def precompute_BM(img, kHW, NHW, nHW, tauMatch):
    """
    :search for similar patches
    :param img: input image
    :param kHW: length of side of patch
    :param NHW: how many patches are stacked
    :param nHW: length of side of search area
    :param tauMatch: threshold determine whether two patches are similar
    :return ri_rj_N__ni_nj: The top N most similar patches to the referred patch
    :return threshold_count: according to tauMatch how many patches are similar to the referred one
    """
    img = img.astype(np.float64)
    height, width = img.shape
    Ns = 2 * nHW + 1
    threshold = tauMatch * kHW * kHW
    sum_table = np.ones((Ns, Ns, height, width)) * 2 * threshold  # di, dj, ph, pw
    row_add_mat, column_add_mat = get_add_patch_matrix(height, width, nHW, kHW)
    diff_margin = np.pad(np.ones((height - 2 * nHW, width - 2 * nHW)), nHW, 'constant', constant_values=0.)
    sum_margin = (1 - diff_margin) * 2 * threshold

    for di in range(-nHW, nHW + 1):
        for dj in range(-nHW, nHW + 1):
            t_img = translation_2d_mat(img, right=-dj, down=-di)
            diff_table_2 = (img - t_img) * (img - t_img) * diff_margin

            sum_diff_2 = row_add_mat @ diff_table_2 @ column_add_mat
            sum_table[di + nHW, dj + nHW] = np.maximum(sum_diff_2, sum_margin)  # sum_table (2n+1, 2n+1, height, width)

    sum_table = sum_table.reshape((Ns * Ns, height * width))  # di_dj, ph_pw
    sum_table_T = sum_table.transpose((1, 0))  # ph_pw__di_dj
    argsort = np.argpartition(sum_table_T, range(NHW))[:, :NHW]
    argsort[:, 0] = (Ns * Ns - 1) // 2
    argsort_di = argsort // Ns - nHW
    argsort_dj = argsort % Ns - nHW
    near_pi = argsort_di.reshape((height, width, -1)) + np.arange(height)[:, np.newaxis, np.newaxis]
    near_pj = argsort_dj.reshape((height, width, -1)) + np.arange(width)[np.newaxis, :, np.newaxis]
    ri_rj_N__ni_nj = np.concatenate((near_pi[:, :, :, np.newaxis], near_pj[:, :, :, np.newaxis]), axis=-1)

    sum_filter = np.where(sum_table_T < threshold, 1, 0)
    threshold_count = np.sum(sum_filter, axis=1)
    threshold_count = closest_power_of_2(threshold_count, max_=NHW)
    threshold_count = threshold_count.reshape((height, width))

    return ri_rj_N__ni_nj, threshold_count

def get_add_patch_matrix(h, w, nHW, kHW):
    row_add = np.eye(h - 2 * nHW)
    row_add = np.pad(row_add, nHW, 'constant')
    row_add_mat = row_add.copy()
    for k in range(1, kHW):
        row_add_mat += translation_2d_mat(row_add, right=k, down=0)

    column_add = np.eye(w - 2 * nHW)
    column_add = np.pad(column_add, nHW, 'constant')
    column_add_mat = column_add.copy()
    for k in range(1, kHW):
        column_add_mat += translation_2d_mat(column_add, right=0, down=k)

    return row_add_mat, column_add_mat

def translation_2d_mat(mat, right, down):
    mat = np.roll(mat, right, axis=1)
    mat = np.roll(mat, down, axis=0)
    return mat

def closest_power_of_2(M, max_):
    M = np.where(max_ < M, max_, M)
    while max_ > 1:
        M = np.where((max_ // 2 < M) * (M < max_), max_ // 2, M)
        max_ //= 2
    return M

if __name__ == '__main__':
    import os
    import cv2
    from utils import add_gaussian_noise, symetrize

    # <hyper parameter>
    # ref_i, ref_j = 196, 142
    ref_i, ref_j = 164, 135
    # ref_i, ref_j = 271, 206

    kHW = 8
    NHW = 3
    nHW = 16
    tauMatch = 2500
    # <hyper parameter \>

    im = cv2.imread('test_data/image/Cameraman.png', cv2.IMREAD_GRAYSCALE)
    im = im[100:, :]
    ref_i, ref_j = 64, 135
    im_noisy = add_gaussian_noise(im, 10, seed=1)

    img_noisy_p = symetrize(im_noisy, nHW)
    near_pij, threshold_count = precompute_BM(img_noisy_p, kHW=kHW, NHW=NHW, nHW=nHW, tauMatch=tauMatch)

    im = cv2.cvtColor(img_noisy_p, cv2.COLOR_GRAY2RGB)
    # <draw search area>
    points_list = [(ref_j - nHW, ref_i - nHW), (ref_j + nHW, ref_i - nHW), (ref_j - nHW, ref_i + nHW),
                   (ref_j + nHW, ref_i + nHW)]
    for point in points_list:
        cv2.circle(im, point, 0, (0, 0, 255), 1)
    # <draw search area \>

    # <draw reference patch>
    cv2.rectangle(im, (ref_j, ref_i), (ref_j + kHW, ref_i + kHW), color=(255, 0, 0), thickness=1)
    # <draw reference patch \>

    # <draw similar patches>
    count = threshold_count[ref_i, ref_j]
    for i, Pnear in enumerate(near_pij[ref_i, ref_j]):
        if i == 0:
            continue
        if i > count:
            break
        y, x = Pnear
        cv2.rectangle(im, (x, y), (x + kHW, y + kHW), color=(0, 255, 0), thickness=1)
    # <draw similar patches \>

    # cv2.imshow('im', im)
    # cv2.waitKey()
    cv2.imwrite('BM_real_im_test.png', im)


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

import os
import datetime
import sys
import commands
import shutil
import random
import copy
import rospy
import numpy as np

from random import randint

import uav
import mapa
import grid
import posicionamento

def main():

    uavs = []
    for i in range(tam_uav):
        u = uav.UAV( 'ardrone_'+str(i), divisao, 'boustrophedon', bs)
        uavs.append(u)

    tam=tam_uav
    rospy.loginfo("[UAVs] Instanciando %d uavs.", tam)

    rospy.init_node('mestrado', anonymous=True)
    #rospy.Rate(10) # 1hz: equivale a 1 atualização por segundo

    # Ajustar posicionamento aleatório para cada uav
    p = posicionamento.Pos(uavs)
    p.inicializarBous()

    #Instante inicial
    now1=rospy.get_time()
    bsIni=rospy.get_time()

    #while (not rospy.is_shutdown() or bs['sair'] == False):
    while (not rospy.is_shutdown()):
        try:
            if bs['sair']==False:
                for u in uavs:
                    if bs['sair']==True:
                        break

                    bs["heat"]+=1
                    u.executarMissao(uavs)

                now2=rospy.get_time() #Instante atual
                #rospy.loginfo("[Tempo] now1: %.2f, now2: %.2f, dif: %.2f", now1, now2, now2-now1)

                if (now1 == 0.00 and now2 >= 670.0) or (now1 != 0 and now2-now1 >= 5.0):
                    now1=rospy.get_time()

                    if len(comando)>0:
                        if comando[0] == 'i':
                            incluir(uavs, p, tam).incluir(uavs)
                            tam+=1
                        elif comando[0] == 'e':
                            u_excluir=excluir(uavs, tam-1)
                            bs['mapa'].areasVisitadas += u_excluir.mapa.areasVisitadas
                            u_excluir.excluir(uavs)
                            tam-=1
                        del comando[0]

                #bs['mapa'].areasVisitadas
                bs_out = open('rascunho_bsAreasVisitadas.out', 'w+')
                np.savetxt(bs_out, bs['mapa'].areasVisitadas, fmt='%03.1f', delimiter=' , ', newline='\n',)
                bs_out.close()

            elif bs['sair']==True:
                break

        except rospy.ROSInterruptException:
            rospy.loginfo("Saindo...")
            rospy.is_shutdown()
        except rospy.service.ServiceException:
            rospy.loginfo("Exceção ServiceException lançada!")
            rospy.is_shutdown()

    base_station(bsIni)
    rospy.loginfo("Encerrando.")

def incluir(uavs, p, tam):
    u = uav.UAV('ardrone_'+str(tam), divisao, 'boustrophedon', bs)

    uavs.append(u)

    return u

def excluir(uavs, tam):
    pos=random.randint(0,tam)
    #pos=random.randint(0,4)

    u=uavs[pos]
    uavs.remove(u)

    return u

def base_station(bsIni):
    bsEnd=rospy.get_time()
    local_visitado = np.argwhere(bs['mapa'].areasVisitadas != 0)

    min    = np.amin(bs['mapa'].areasVisitadas)
    max    = np.amax(bs['mapa'].areasVisitadas)
    mean   = np.mean(bs['mapa'].areasVisitadas)
    median = np.median(bs['mapa'].areasVisitadas)
    avg    = np.average(bs['mapa'].areasVisitadas)
    std    = np.std(bs['mapa'].areasVisitadas)
    perc   = np.percentile(bs['mapa'].areasVisitadas,90)

    ts2 = datetime.datetime.now()
    timestamp=str(ts2.year)+str(ts2.month)+str(ts2.day)+'_'+str(ts2.hour)+str(ts2.minute)+str(ts2.second)

    bs_out = open(timestamp+'_bsAreasVisitadas.out', 'w+')

    dif=ts2-ts1

    tempo_min=divmod(dif.total_seconds(), 60)[0]

    np.savetxt(bs_out, \
               bs['mapa'].areasVisitadas, fmt='%03.1f', delimiter=' , ', newline=']\n[', \
               header='result=np.array([',
               footer=']]) \n \
 --- Cobertura: '+str((float(len(local_visitado)) / 400.0) * 100 )+'% ('+str(len(local_visitado))+'/400.0) \n \
 --- Percurso em: '+str(tempo_min)+' min ('+ts1.strftime("%H:%M")+', '+ts2.strftime("%H:%M")+') \n \
 --- Qtde de uavs: '+str(tam_uav)+', Comando: '+str(cp_comando)+' \n \
 --- Min: '+str(min)+', \n \
 --- Max: '+str(max)+', \n \
 --- Mean: '+str(round(mean,2))+', \n \
 --- Median: '+str(round(median,2))+', \n \
 --- Average: '+str(round(avg,2))+', \n \
 --- Std: '+str(round(std,2))+', \n \
 --- Percentile90: '+str(perc)+' ')

    bs_out.close()

    cmd='mv %s atuacao/' % (timestamp+'_bsAreasVisitadas.out')
    status, output0 = commands.getstatusoutput(cmd)

    cmd='ls -tr heat*.png | tail -n 1'
    status, output1 = commands.getstatusoutput(cmd)

    cmd='mv %s atuacao/%s' % (output1, timestamp+'_'+output1)
    status, output2 = commands.getstatusoutput(cmd)

    #os.system("avconv -start_number 20 -i heat%08d.png -r 10000 -c:v libx264 -crf 20 -pix_fmt yuv420p atuacao/"+timestamp+"_mapa_de_calor2.mp4")

def apagarDiretorios():
    # Apagando arquivo bs
    files = os.listdir("/home/grazieno/ros-mestrado")
    for f in files:
        if f.endswith(".out") or f.endswith(".png"):
            os.remove(f)

    # Apagando diretorios anteriores
    dirs = os.listdir("/home/grazieno/ros-mestrado")
    for d in dirs:
        if d.startswith("ardrone_"):
            shutil.rmtree(d)

if __name__ == "__main__":
    divisao = 'voronoi'
    tam_uav = int(sys.argv[1])

    #comando=[]
    #comando=['i']
    #comando=['e']
    comando=['i', 'e']

    cp_comando=copy.deepcopy(comando)

    ts1 = datetime.datetime.now()

    bs = {
        "mapa": mapa.Mapa(),  #idade,areasVisitadas,alvos,probabilidade
        "grid": grid.Grid(),  #grid com regioes de voronoi
        "sair": False,        #flag para execucao terminar
        "heat": 0             #contador para mapa de calor (heat)
    }

    #bs['mapa'].areasVisitadas[:]=1.0
    #bs['mapa'].areasVisitadas[0][0]=0

    apagarDiretorios()
    main()


from prometheus_client import Histogram, Counter, Summary, Info
import env

# Default labels
metric_label_keys = ['endpoint', 'app', 'hostname']

# Metrics
AMOUNT_TIMES_CALLED = Counter('amount_times_called', 'Amount of times a function was called', metric_label_keys)
REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request', metric_label_keys)
PONG_REQUESTS = Counter('pong_requests_total', 'Total times you hit your PONG', metric_label_keys)
MISS_REQUESTS = Counter('miss_requests_total', 'Total times you missed your PONG', metric_label_keys)

def get_labels_dict(*metric_values):
    labels = {
        "app": env.APP_NAME,
        "hostname": env.HOSTNAME,
    }
    for i, label_value in enumerate(metric_values):
        labels.__setitem__(metric_label_keys[i], label_value)
    return labels


from django.views.generic import TemplateView
from django.views.generic.base import RedirectView
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext_lazy as _
from .forms import AddNetworkForm, RenameSubnetForm, AddHostForm, SplitSubnetForm
from .models import Subnet, Host
import ipaddress

class RootView(TemplateView):
    def get(self, request, *args, **kwargs):
        return redirect('ip_list')

@method_decorator(login_required, name='dispatch')
class IPListView(TemplateView):
    template_name = "subnetbase/iplist.html"

    @staticmethod
    def get_subnet(pk):
        return Subnet.objects.get(pk=pk)

    @staticmethod
    def format_form_errors(errors):
        result = []
        for value in errors.itervalues():
            result.append(value)
        return result

    def get(self, request, *args, **kwargs):
        tree = Subnet.objects.all()
        return render(request, self.template_name, {'subnets_tree': tree, 'form': AddNetworkForm(),
                                                    'rename_form': RenameSubnetForm(), 'add_host_form': AddHostForm(),
                                                    'split_subnet_form': SplitSubnetForm()})

    def post(self, request, *args, **kwargs):
        form = AddNetworkForm(request.POST)
        tree = Subnet.objects.all()
        if form.is_valid():
            subnet = Subnet()
            subnet.subnet = form.cleaned_data['network']
            subnet.prefix = form.cleaned_data['prefix']
            subnet.title = form.cleaned_data['title']
            subnet.calculate()
            subnet.save()
            return redirect('ip_list')
        else:
            for msg in self.format_form_errors(form.errors):
                messages.error(request, msg)
            return render(request, self.template_name, {'subnets_tree': tree, 'form': form})

@method_decorator(login_required, name='dispatch')
class SplitSubnetView(TemplateView):

    def get(self, request, *args, **kwargs):
        messages.error(request, _('Method GET not supported for this URL'))
        return redirect('ip_list')

    def post(self, request, *args, **kwargs):
        form = SplitSubnetForm(request.POST)
        if form.is_valid():
            to_split = IPListView.get_subnet(form.cleaned_data['subnet'])
            if to_split.get_children is not None:
                messages.error(request, _('Subnet %(net)s/%(prefix)s already splited.') %
                               {'net': to_split.net, 'prefix': to_split.prefix})
                return redirect('ip_list')
            subnet = ipaddress.IPv4Network('%s/%s' % (to_split.net, to_split.prefix))
            new_prefix = form.cleaned_data['new_prefix']
            if new_prefix <= to_split.prefix or new_prefix > 32:
                messages.error(request, _('%(new_prefix)s is incorrect prefix for subnet %(subnet)s/%s(old_prefix)s') %
                               {'new_prefix': new_prefix, 'subnet': to_split.net, 'old_prefix': to_split.prefix})
                return redirect('ip_list')
            for splited in list(subnet.subnets(prefixlen_diff=new_prefix-to_split.prefix)):
                new_subnet = Subnet()
                new_subnet.subnet = str(splited.network_address)
                new_subnet.prefix = new_prefix
                new_subnet.calculate()
                new_subnet.parent = to_split
                new_subnet.title = form.cleaned_data['title']
                new_subnet.save()
            return redirect('ip_list')
        else:
            for msg in IPListView.format_form_errors(form.errors):
                messages.error(request, msg)
            return redirect('ip_list')

@method_decorator(login_required, name='dispatch')
class RenameSubnetView(RedirectView):

    def get(self, request, *args, **kwargs):
        messages.error(request, _('Method GET not supported for this URL'))
        return redirect('ip_list')

    def post(self, request, *args, **kwargs):
        form = RenameSubnetForm(request.POST)
        if form.is_valid():
            subnet = IPListView.get_subnet(form.cleaned_data['subnet'])
            subnet.title = form.cleaned_data['new_title']
            subnet.save()
            return redirect('ip_list')
        else:
            for msg in IPListView.format_form_errors(form.errors):
                messages.error(request, msg)
            return redirect('ip_list')

@method_decorator(login_required, name='dispatch')
class DeleteSubnetView(RedirectView):

    def get(self, request, *args, **kwargs):
        if 'subnet' in kwargs.keys():
            subnet = IPListView.get_subnet(kwargs.get('subnet'))
            siblings = subnet.get_siblings()
            for sibling in siblings:
                sibling.delete()
            subnet.delete()
            return redirect('ip_list')
        else:
            messages.error(request, _('No subnet specified'))
            return redirect('ip_list')

@method_decorator(login_required, name='dispatch')
class AddHostView(RedirectView):

    def get(self, request, *args, **kwargs):
        messages.error(request, _('Method GET not supported for this URL'))
        return redirect('ip_list')

    def post(self, request, *args, **kwargs):
        form = AddHostForm(request.POST)
        if form.is_valid():
            subnet = IPListView.get_subnet(form.cleaned_data['subnet'])
            for host in subnet.hosts.all():
                if host.address == form.cleaned_data['address']:
                    messages.error(request, _('Host with that address already exists'))
                    return redirect('ip_list')
            network = ipaddress.IPv4Network('%s/%s' % (subnet.subnet, subnet.prefix))
            try:
                ip = ipaddress.IPv4Address(subnet.subnet) + form.cleaned_data['address']
                if ip not in network:
                    messages.error(request, _('IP Address %(ip)s not part of subnet %(subnet)s') %
                                   {'ip': str(ip), 'subnet': str(network)})
                    return redirect('ip_list')
            except ipaddress.AddressValueError:
                messages.error(request, _('Invalid IP Address'))
                return redirect('ip_list')
            host = Host()
            host.description = form.cleaned_data['description']
            host.address = form.cleaned_data['address']
            if form.cleaned_data['mac']:
                host.mac = form.cleaned_data['mac']
            host.parent = subnet
            host.save()
            return redirect('ip_list')
        else:
            for msg in IPListView.format_form_errors(form.errors):
                messages.error(request, msg)
            return redirect('ip_list')

@method_decorator(login_required, name='dispatch')
class DeleteHostView(RedirectView):

    def get(self, request, *args, **kwargs):
        if 'host' in kwargs.keys():
            host_id = kwargs.get('host')
            host = Host.objects.get(pk=host_id)
            host.delete()
        else:
            messages.error(request, _('No host specified'))
            return redirect('ip_list')


#!/usr/bin/env python3

from activity_recognition_engine import ActivityRecognitionEngine
from gabriel_server.local_engine import runner
import logging

INPUT_QUEUE_MAXSIZE = 60
PORT = 9099
TOKENS = 2

logging.basicConfig(level=logging.INFO)

def main():
    def engine_setup():
        return ActivityRecognitionEngine()

    runner.run(engine_setup, ActivityRecognitionEngine.ENGINE_NAME, INPUT_QUEUE_MAXSIZE, PORT, TOKENS)

if __name__ == '__main__':
    main()


# coding=utf-8
import re
import requests
from requests.exceptions import ConnectionError

"""
爬虫api：
    搜索结果页：get_index_result(search)
    小说章节页：get_chapter(url)
    章节内容：get_article(url)
"""
class DdSpider(object):

    def __init__(self):
        self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0'}

    def parse_url(self, url):
        try:
            resp = requests.get(url, headers=self.headers)
            if resp.status_code == 200:
                # 处理一下网站打印出来中文乱码的问题
                resp.encoding = 'utf-8'
                return resp.text
            return None
        except ConnectionError:
            print('Error.')
        return None

    # 搜索结果页数据
    def get_index_result(self, search):
        url = 'http://zhannei.baidu.com/cse/search?q={search}&p={page}&s=1682272515249779940&entry=1'.format(
            search=search, page=0)
        resp = self.parse_url(url)
        resp = re.sub(r'', '', resp)
        resp = re.sub(r'', '', resp)
        p = re.compile(r'<a cpos="img".*?<img src="(.*?)".*?'
                       + r'(.*?).*?
(.*?)'
                       + r'
.*?<span.*?(.*?).*?title">(.*?).*?title">(.*?)', re.S)
        items = re.findall(p, resp)
        for i in items:
            data = {
                'image': i[0],
                'url': i[1],
                'title': i[2].strip(),
                'profile': i[3].strip().replace('\u3000', '').replace('\n', ''),
                'author': i[4].strip(),
                'style': i[5].strip(),
                'time': i[6].strip()
            }
            yield data

    # 小说章节页数据
    def get_chapter(self, url):
        resp = self.parse_url(url)
        p = re.compile(r'
 (.*?)
')
        chapters = re.findall(p, resp)
        for i in chapters:
            data = {
                'url': str(url) + i[0],
                'chapter': i[1]
            }
            yield data

    # 章节内容页数据
    def get_article(self, url):
        resp = self.parse_url(url)
        p = re.compile(r'
(.*?)
', re.S)
        article = re.findall(p, resp)
        # 文章中的'
'标签先不去除，后面在模版中使用
        return article[0].strip()

# dd = DdSpider()
# print(dd.get_article('http://www.23us.cc/html/158/158120/8275025.html'))


from django.shortcuts import render_to_response, HttpResponseRedirect
from models import BlogPost, Category
from django.template import RequestContext
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from settings import TEMPLATE_DIRS
from django.core.context_processors import csrf
from django.views.decorators.cache import cache_control
from django.contrib.syndication.views import Feed
from django.core.cache import cache
from django.contrib.comments import Comment

def clearcache():
    try:
        cache._cache.clear() #in-memory caching
        cache._cache.flush_all()
    except AttributeError:
    # try filesystem caching next
        old = cache._cull_frequency
        old_max = cache._max_entries
        cache._max_entries = 0
        cache._cull_frequency = 1
        cache._cull_frequency = old
        cache._max_entries = old_max

@cache_control(no_cache=True, must_revalidate=True)
def get_post_by_slug(request, blogpost_slug):
    """
    Single post with comments and a comment form.
    """
    clearcache()
    post = BlogPost.objects.get(slug=blogpost_slug)

    d = dict(post=post, user=request.user, page_title=post.short_body)
    d.update(csrf(request))

    return render_to_response(TEMPLATE_DIRS[0] + "post.html", d, context_instance=RequestContext(request))

@cache_control(no_cache=True, must_revalidate=True)
def main(request):
    """Main listing."""
    clearcache()
    posts = BlogPost.objects.all().order_by("-timestamp")
    paginator = Paginator(posts, 5)

    category_list = Category.objects.all().order_by('title')[:5] #getting 5 recent categories

    try:
        page = int(request.GET.get("page", '1'))
    except ValueError:
        page = 1
    try:
        posts = paginator.page(page)
    except (InvalidPage, EmptyPage):
        posts = paginator.page(paginator.num_pages)

    d = dict(posts=posts, user=request.user, post_list=posts.object_list, page_title='My blogposts',
             category_list=category_list[:5])
    d.update(csrf(request))
    return render_to_response(TEMPLATE_DIRS[0] + "list.html", d, context_instance=RequestContext(request))

@cache_control(no_cache=True, must_revalidate=True)
def get_by_category(request, category_slug):
    # Get specified category
    clearcache()
    posts = BlogPost.objects.all().order_by('-timestamp')
    category_posts = []
    for post in posts:
        if post.categories.filter(slug=category_slug):
            category_posts.append(post)

    # Add pagination
    paginator = Paginator(category_posts, 5)

    # Get the category
    category = Category.objects.filter(slug=category_slug)[0]

    # Get the specified page
    try:
        page = int(request.GET.get("page", '1'))
    except ValueError:
        page = 1
    try:
        category_posts = paginator.page(page)
    except (InvalidPage, EmptyPage):
        category_posts = paginator.page(paginator.num_pages)

    d = dict(posts=category_posts, user=request.user, post_list=category_posts.object_list, category=category,
             page_title=category.title)
    d.update(csrf(request))
    return render_to_response(TEMPLATE_DIRS[0] + "category.html", d, context_instance=RequestContext(request))

class PostsFeed(Feed):
    title = "Tim Shenkao's blog posts"
    link = "/feeds/posts/"
    description = "Posts from Tim Shenkao's blog"

    def items(self):
        return BlogPost.objects.order_by('-timestamp')[:5]

    def item_title(self, item):
        return item.title

    def item_description(self, item):
        return item.body

@cache_control(no_cache=True, must_revalidate=True)
def comment_posted(request):
    if request.GET.get('c', False):
        comment_id = request.GET['c']
        comment = Comment.objects.get(pk=comment_id)
        post = BlogPost.objects.get(id=comment.object_pk)
        if post:
            return HttpResponseRedirect(post.get_absolute_url())
    return HttpResponseRedirect("/")


#!/usr/bin/env python3

"""Read Octopus Agile price data from an existing SQLite database and update a
   Pimoroni Blinkt! display."""

import sqlite3
from urllib.request import pathname2url
import argparse
import blinkt

# set brightness, IT BURNS MEEEEEE, 100 is the max
BRIGHTNESS = 10

# define colour values for LEDs. Edit as you please...
colourmap = { 'magenta': { 'r': 155, 'g': 0, 'b': 200 },
              'red': { 'r': 255, 'g': 0, 'b': 0 },
              'orange': { 'r': 255, 'g': 30, 'b': 0 },
              'yellow': { 'r': 180, 'g': 100, 'b': 0 },
              'green': { 'r': 0, 'g': 255, 'b': 0 },
              'cyan': { 'r': 0, 'g': 160, 'b': 180 },
              'blue': { 'r': 0, 'g': 0, 'b': 255 }, }

def price_to_colour(price):
    """edit this function to change price thresholds - be careful that you
    don't leave gaps in the numbers or strange things will very likely happen.
    prices are including VAT in p/kWh"""

    if price > 28:
        return 'magenta'
    if 28 >= price > 17:
        return 'red'
    if 17 >= price > 13.5:
        return 'orange'
    if 13.5 >= price > 10:
        return 'yellow'
    if 10 >= price > 5:
        return 'green'
    if 5 >= price > 0:
        return 'cyan'
    if price <= 0:
        return 'blue'
    raise SystemExit("Can't continue - price of " + str(price) +" doesn't make sense.")

parser = argparse.ArgumentParser(description=('Update Blinkt! display using SQLite data'))
parser.add_argument('--demo', '-d', action='store_true',
                    help= 'display configured colours, one per pixel',)

args = parser.parse_args()

if args.demo:
    blinkt.clear()
    i = 0
    for colour in colourmap:
        blinkt.set_pixel(i, colourmap[colour]['r'],
            colourmap[colour]['g'], colourmap[colour]['b'], BRIGHTNESS/100)
        i += 1
    print ("Demo mode...")
    blinkt.set_clear_on_exit(False)
    blinkt.show()

else:
    try:
        # connect to the database in rw mode so we can catch the error if it doesn't exist
        DB_URI = 'file:{}?mode=rw'.format(pathname2url('agileprices.sqlite'))
        conn = sqlite3.connect(DB_URI, uri=True)
        cursor = conn.cursor()
        print('Connected to database...')
    except sqlite3.OperationalError as error:
        # handle missing database case
        raise SystemExit('Database not found - you need to run store_prices.py first.') from error

    cursor.execute("SELECT * FROM prices WHERE valid_from > datetime('now', '-30 minutes') LIMIT 8")
    rows = cursor.fetchall()

    # finish up the database operation
    if conn:
        conn.commit()
        conn.close()

    if not len(rows) >= 8:
        print('Not enough data to fill the display - we will get dark pixels.')

    blinkt.clear()

    i = 0

    for row in rows:
        print(str(i) + ": " + str(row[1]) + "p - " + str(price_to_colour(row[1])))
        PIXEL_VALUE_RED = colourmap[price_to_colour(row[1])]['r']
        PIXEL_VALUE_GREEN = colourmap[price_to_colour(row[1])]['g']
        PIXEL_VALUE_BLUE = colourmap[price_to_colour(row[1])]['b']
        blinkt.set_pixel(i, PIXEL_VALUE_RED,
            PIXEL_VALUE_GREEN, PIXEL_VALUE_BLUE, BRIGHTNESS/100)
        i += 1

    print ("Setting display...")
    blinkt.set_clear_on_exit(False)
    blinkt.show()


'''
方法二：继承Process类 ，需实现 run 方法

'''

from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name2):
        super() .__init__() # 需加上父类的 init方法，以免覆盖，造成某些功能无法使用
        self.name2=name2

    def run(self):
        print("<%s> is running" % self.name2)
        time.sleep(2)
        print("<%s> is done" % self.name2)

if __name__ == '__main__':
    p1=MyProcess('AIF333')
    p2=MyProcess('Iverson')
    p1.start()
    p2.start()
    print("===主进程is running ！===")


# coding: utf-8

# # Web crawling
#
# The following content heavily draws on [Web Scraping with Python](https://proquest.safaribooksonline.com/book/programming/python/9781491985564) (2018) by Ryan Mitchell.
#
# - First, we learn how create a list of URLs from a webpage.
# - Second, we learn how to crawl through the list of these URLs.

# ## Web crawling
#
# The idea behind web scrawling is recursion. Instead of scraping one web page, we do the same process over and over different web pages (or websites) using Uinform Resource locations (or URLs). Since web crawling substantially increases work load of the target's server, do this very carefully again within *technical*, *legal*, and *ethical* boundaries.

# ### Create a list of URLs
#
# Since we're studying computational methods, let's look at the list of past winners of Turing Award -- the computer science equivalent to Nobel prizes and collect links from the URL.
#

# To begin with, let's find out whether we can gain access to the web page.

# In[1]:

from urllib.request import urlopen
from urllib.error import HTTPError
from urllib.error import URLError

try:
    page = urlopen('https://en.wikipedia.org/wiki/Turing_Award')
except HTTPError as e:
    print(e)
except URLError as e:
    print("The server is broken")
else:
    print("The site is working")

# Then, let's scrap the table and the find the element (the URLs of the prize winners) we need.

# In[2]:

from bs4 import BeautifulSoup

soup = BeautifulSoup(page, "html.parser")

wiki_table = soup.find('table',{'class':'wikitable'})

# Find some patterns we can exploit.

# In[3]:

import re

wiki_table.find_all('tr')[1].find_all('td')[0].find('a').get('href') # first winner
wiki_table.find_all('tr')[2].find_all('td')[0].find('a').get('href') # second winner

# Calculate the total number of prize winners. Remember each row in the table contains information about a prize winner.

# In[4]:

winners=len(wiki_table.find_all('tr'))

# In[5]:

links = []

for i in range(0,winners-1):
    if i <= winners:
        links.append(wiki_table.find_all('tr')[i+1].find_all('td')[0].find('a').get('href'))
        print(links[i]) # to check whether we get the right list
    else:
        print("Something is wrong") # for debugging

# **Challenge**
#
# But we have one problem. The links are not the full URLs we look for. We want "https://en.wikipedia.org/wiki/Alan_Perlis" not "wiki/Alan_Perlis". How can you fix this?

# In[6]:

''.join(["https://en.wikipedia.org",links[0]]) # using join method

# In[7]:

new_links = []

for i in range(0,winners-1):
    if i <= winners-1:
        new_links.append(''.join(["https://en.wikipedia.org",links[i]]))
        print(new_links[i]) # to check whether we get the right list
    else:
        print("Something is wrong") # for debugging

# ### Crawl through the list

# Let's extract the birth information from each of the prize winner's Wikipage.

# In[8]:

try:
    test_page = urlopen(new_links[0])
except HTTPError as e:
    print(e)
except URLError as e:
    print("The server is broken")
else:
    print("The site is working")

test_soup = BeautifulSoup(test_page, "html.parser")
test_infobox = test_soup.find("table",{"class":"vcard"})

test_infobox.find(text = re.compile("Born")).find_next().text

# Now we loop the code over the list.

# In[9]:

birth_list = []

for url in new_links:
    req = urlopen(url)
    page = BeautifulSoup(req, 'html.parser')
    birth = page.find("table",{"class":"vcard"}).find(text = re.compile("Born")).find_next().text
    birth_list.append(birth)

# In[10]:

birth_list[0:winners-1]

##birth list cleaned
##regular expressions

birth_list_cleaned=[]

for element in birth_list:
    birth_list_cleaned.append(re.findall('[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]',element))


import sys
import validator
import json
import utxo_set
import config
import pending_pool
import pickle
from flask import (
    Flask,
    request
)

app = Flask(__name__)

@app.route('/transaction/new', methods=['POST'])
def submit_tx():
    if request.method == 'POST':
        next_transaction = request.get_data()
        next_transaction = next_transaction.decode('utf-8')
        pending_pool.database(next_transaction)
        return(str(next_transaction))

@app.route('/transaction/pending', methods=['GET'])
def pending_transaction():
    if request.method == 'GET':
        data = pending_pool.get_data('pool.pickle')
        if data != False:
            return str(data)
        else:
            return("Something get wrong!\nYou have no transaction in pool")

@app.route('/chain', methods=['GET'])
def get_chain():
    if request.method == 'GET':
        data = pending_pool.get_data('blockchain.pickle')
        if data != False:
            if (type(data) == str):
                data = json.loads(data)
            return str(data)
        else:
            return("Something get wrong!\nYou have no chain")

@app.route('/nodes', methods=['GET'])
def list_of_nodes():
    if request.method == 'GET':
        data = pending_pool.read_nodes_from_file('node')
        ret = ''.join(data)
        if data != False:
            return (ret)
        else:
            return("Something get wrong!\nYou have no nodes")

@app.route('/chain/length', methods=['GET'])
def chain_length():
    if request.method == 'GET':
        data = pending_pool.get_data('blockchain.pickle')
    if data != False:
        if type(data) is dict:
            lens = str(data['chain'][0]['height'])
        else:
            lens = str(data.chain[0].height)
        return lens
    else:
        return("0")

@app.route('/block/last', methods=['GET'])
def last_block():
    if request.method == 'GET':
        data = pending_pool.get_data('blockchain.pickle')
        if data != False:
            if type(data) is dict:
                block = data['chain'][0]
            else:
                block = data.chain[0]
            return str(block)
        else:
            return("Something get wrong!\nYou have no chain")

@app.route('/block', methods=['GET'])
def block_height():
    if request.method == 'GET':
        height = str(request.args.get('height'))
        data = pending_pool.get_data('blockchain.pickle')
        if data != False:
            i = len(data.chain) - 1
            while(i >= 0):
                if (int(data.chain[i].height) == int(height)):
                    return str(data.chain[i])
                i -= 1
            return "No such block!"
        else:
            return "There no chain data!"

@app.route('/balance', methods=['GET'])
def get_balance():
    if request.method == 'GET':
        addr = str(request.args.get('addr'))
        setik = utxo_set.get_utxo_set("Pitcoin", addr)
        balance = utxo_set.check_balance(setik)
        return('
Your balance is ' + str(balance) + ' satoshi
')

@app.route('/utxo', methods=['GET'])
def utxo():
    if request.method == 'GET':
        data = pending_pool.get_data('utxo.pickle')
        if data != False:
            return str(data)
        else:
            return("Something get wrong!\nYou have no utxo in pool")

@app.route('/block/new', methods=['POST'])
def receive_new_block():
    if request.method == 'POST':
        validator.mining(0)
        block = request.form
        if validator.block(block) == True:
            validator.consensus()
        validator.mining(1)
        return "OK"
    return ("OK")

@app.route('/getDifficulty', methods=['GET'])
def get_difficulty():
    if request.method == 'GET':
        data = pending_pool.get_data('blockchain.pickle')
        if data != False:
            diff = data.diff
            return str(diff)
        else:
            return("Something get wrong!\nYou have no chain")

def main():
    ip = pending_pool.read_nodes_from_file()
    if ip == False:
        PORT = input("Choose port\n")
        try:
            val = int(PORT)
            try:
                fd = open("port.txt", 'w')
                fd.write(PORT)
                fd.close()
                pending_pool.add_node_to_file("0.0.0.0:" + PORT)
                app.run(host='0.0.0.0', port=PORT, debug=False)
                print("!!!Server port was saved in a file port.txt!!!")
            except IOError:
                print("IOError")
        except (ValueError, PermissionError, OverflowError) as e:
            print("Invalid port, stupid")
    else:
        app.run(host=ip[0][:7], port=ip[0][8:13], debug=False)

if __name__ == '__main__':
    main()


import cx_Freeze

executables=[cx_Freeze.Executable("mygame.py")]

cx_Freeze.setup(
    name="Snake",
    options={"build_exe":{"packages":["pygame"],"include_files":["apple.png","snakehead.png"] }},
    description="Snake Game",
    executables=executables
)


from django.urls import path
from . import views

urlpatterns = [
    path("",views.home,name="home"),
    path("about/",views.about,name="about"),
    path("add",views.add,name="add"),
    path("register/",views.register,name="register")

]


from pystickynote.paths import NOTES_PATH
import PySimpleGUIQt as g
import sys
import json

if 'darwin' in sys.platform:
    NTB = False
else:
    NTB = True

def open_note(name, config):
    g.SetOptions(background_color=config.background_color, text_color=config.text_color,
                 input_elements_background_color=config.background_color, input_text_color=config.text_color,
                 button_color=(config.text_color, config.background_color), border_width=config.border_width, font=('Arial', int(config.font_size)))
    with open(NOTES_PATH, 'r+') as notes:
        note_obj = json.load(notes)
        match = False
        content = ''
    for k, v in note_obj.items():
        if name == k:
            match = True
            content = v
    if match == False:
        print('No Note Found With That Name')
        exit(1)
    layout = [
        [g.T(name, font=('Arial', int(config.title_size)), justification='center')],
        [g.Multiline(content, size=(50, 5), key='content')],
        [g.B('Close'), g.B('Delete'), g.B('Save')]
    ]

    window = g.Window('Create', no_titlebar=NTB, keep_on_top=True, grab_anywhere=True, layout=layout, alpha_channel=float(config.alpha))

    while True:
        event, value = window.Read()
        if event == 'Close':
            window.Close()
            break
        elif event == 'Save':
            note_obj[name] = value['content']
            with open(NOTES_PATH, 'r+') as notes:
                notes.seek(0)
                notes.truncate()
                json.dump(note_obj, notes, indent=4)
            window.Close()
            break
        elif event == 'Delete':
            new_layout = [
                [g.T('Are you sure you want to delete {}?'.format(name), justification='center')],
                [g.B('No'), g.B('Yes')]
            ]
            confirm_window = g.Window('', no_titlebar=NTB, keep_on_top=True, grab_anywhere=True, layout=new_layout)
            while True:
                event1, value1 = confirm_window.Read()
                if event1 == 'Yes':
                    note_obj.pop(name, [])
                    with open(NOTES_PATH, 'r+') as notes:
                        notes.seek(0)
                        notes.truncate()
                        json.dump(note_obj, notes, indent=4)
                    confirm_window.Close()
                    break
                else:
                    confirm_window.Close()
                    break
            window.Close()
            break


# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request

from AokaiSpider.items import CostPriceItemLoader, CostPriceItem
import time
from AokaiSpider.utils import zhesu

class CostAbsSpider(scrapy.Spider):
    name = 'cost-abs'
    breed = "ABS"
    allowed_domains = ['www.ex-cp.com']
    start_urls = ["http://www.ex-cp.com/plastic/list-16-1.html"]
    total_pages = 0
    strat_page = 1

    def parse(self, response):
        """
        """
        post_nodes = response.css(".catlist_li")
        cur_date = time.strftime('%Y-%m-%d', time.localtime(time.time()));
        for post_node in post_nodes:
            post_url = post_node.css("a::attr(href)").extract_first("")
            post_date = "2018-" + zhesu.date_time_convert(post_node.css("a::attr(title)").extract_first(""))
            if post_date == cur_date:
                yield Request(url=post_url, callback = self.parse_detail)

        # if self.total_pages == 0:
        #     common_url = response.css("#destoon_previous ::attr(value)").extract_first("")
        #     self.total_pages = int(self.get_page(common_url.strip()))
        #
        # c_page = 1 if int(self.get_page(response.url)) == None else int(self.get_page(response.url))
        # if c_page < self.total_pages:
        #     next_url = self.breed_url+ str(c_page + 1)+".html"
        #     print("ABS出厂价URL:" + next_url)
        #     yield Request(url=next_url, callback=self.parse)

    def parse_detail(self, response):
        print("current_detail_page:" + response.url)
        trs = response.css("tbody tr")
        date_time_str = "2018-" + zhesu.date_time_convert(response.css("#title::text").extract_first(""))
        date_time = int(time.mktime(time.strptime(date_time_str,'%Y-%m-%d')))
        for tr in trs[1:]:
            tds = tr.css("td")
            cost_item = CostPriceItem()
            cost_item["breed"] = self.breed
            cost_item["spec"] = tds[0].css("td::text").extract_first("").strip()
            cost_item["brand"] = tds[1].css("td::text").extract_first("").strip()
            cost_item["area"] = zhesu.area_convert(tds[2].css("td::text").extract_first("").strip())
            cost_item["price"] = tds[3].css("td::text").extract_first("").strip()
            cost_item["updown"] = tds[4].css("td::text").extract_first("").strip()
            cost_item["product_unit"] = "元/吨"
            cost_item["release_date"] = date_time*1000
            cost_item["release_date_str"] = date_time_str
            if cost_item["spec"] == None or cost_item["brand"] == None or cost_item["spec"] == "" or cost_item["brand"] == "" \
                or cost_item["area"] == None or cost_item["area"] == "" :
                continue
            yield cost_item

    def get_page(self, url):
        url = url[url.rindex("/") + 1:]
        attrs = url.replace(".html", "").split("-")
        return  attrs[len(attrs) - 1]


# Copyright Contributors to the Amundsen project.
# SPDX-License-Identifier: Apache-2.0

from typing import Any, Dict, List, Union  # noqa: F401

from databuilder.models.neo4j_csv_serde import Neo4jCsvSerializable, NODE_KEY, \
    NODE_LABEL, RELATION_START_KEY, RELATION_START_LABEL, RELATION_END_KEY, \
    RELATION_END_LABEL, RELATION_TYPE, RELATION_REVERSE_TYPE

class Watermark(Neo4jCsvSerializable):
    # type: (...) -> None
    """
    Table watermark result model.
    Each instance represents one row of table watermark result.
    """
    LABEL = 'Watermark'
    KEY_FORMAT = '{database}://{cluster}.{schema}' \
                 '/{table}/{part_type}/'
    WATERMARK_TABLE_RELATION_TYPE = 'BELONG_TO_TABLE'
    TABLE_WATERMARK_RELATION_TYPE = 'WATERMARK'

    def __init__(self,
                 create_time,  # type: str
                 database,  # type: str
                 schema,  # type: str
                 table_name,  # type: str
                 part_name,  # type: str
                 part_type='high_watermark',  # type: str
                 cluster='gold',  # type: str
                 ):
        # type: (...) -> None
        self.create_time = create_time
        self.database = database.lower()
        self.schema = schema.lower()
        self.table = table_name.lower()
        self.parts = []  # type: list

        if '=' not in part_name:
            raise Exception('Only partition table has high watermark')

        # currently we don't consider nested partitions
        idx = part_name.find('=')
        name, value = part_name.lower()[:idx], part_name.lower()[idx + 1:]
        self.parts = [(name, value)]
        self.part_type = part_type.lower()
        self.cluster = cluster.lower()
        self._node_iter = iter(self.create_nodes())
        self._relation_iter = iter(self.create_relation())

    def create_next_node(self):
        # type: (...) -> Union[Dict[str, Any], None]
        # return the string representation of the data
        try:
            return next(self._node_iter)
        except StopIteration:
            return None

    def create_next_relation(self):
        # type: (...) -> Union[Dict[str, Any], None]
        try:
            return next(self._relation_iter)
        except StopIteration:
            return None

    def get_watermark_model_key(self):
        # type: (...) -> str
        return Watermark.KEY_FORMAT.format(database=self.database,
                                           cluster=self.cluster,
                                           schema=self.schema,
                                           table=self.table,
                                           part_type=self.part_type)

    def get_metadata_model_key(self):
        # type: (...) -> str
        return '{database}://{cluster}.{schema}/{table}'.format(database=self.database,
                                                                cluster=self.cluster,
                                                                schema=self.schema,
                                                                table=self.table)

    def create_nodes(self):
        # type: () -> List[Dict[str, Any]]
        """
        Create a list of Neo4j node records
        :return:
        """
        results = []
        for part in self.parts:
            results.append({
                NODE_KEY: self.get_watermark_model_key(),
                NODE_LABEL: Watermark.LABEL,
                'partition_key': part[0],
                'partition_value': part[1],
                'create_time': self.create_time
            })
        return results

    def create_relation(self):
        # type: () -> List[Dict[str, Any]]
        """
        Create a list of relation map between watermark record with original table
        :return:
        """
        results = [{
            RELATION_START_KEY: self.get_watermark_model_key(),
            RELATION_START_LABEL: Watermark.LABEL,
            RELATION_END_KEY: self.get_metadata_model_key(),
            RELATION_END_LABEL: 'Table',
            RELATION_TYPE: Watermark.WATERMARK_TABLE_RELATION_TYPE,
            RELATION_REVERSE_TYPE: Watermark.TABLE_WATERMARK_RELATION_TYPE
        }]
        return results


# EC503 Final Project: Exploration of Dimensionality Reduction
# Implementation of Simple Autoencoder in Keras (fully connected)
# REFERENCE: https://blog.keras.io/building-autoencoders-in-keras.html

from keras.layers import Input, Dense
from keras.models import Model
from keras.datasets import mnist
import numpy as np
import matplotlib.pyplot as plt # plot digits
from keras.callbacks import TensorBoard # for logging
from sklearn import svm
from sklearn import cross_validation, grid_search
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.externals import joblib
from sklearn.svm import SVC
from sklearn import preprocessing

np.set_printoptions(threshold=np.inf)

# size of our encoded representation
encoding_dim = 32  # 32 floats -> compression of factor 24.5, assuming the input is 784 floats

# input placeholder
input_img = Input(shape=(784,))
# "encoded" is the encoded representation of the input
# Rectified linear activation is our activation function, to prevent vanishing gradient
encoded = Dense(encoding_dim, activation='relu')(input_img)
# "decoded" is the lossy reconstruction of the input, with standard sigmoid activation
decoded = Dense(784, activation='sigmoid')(encoded)

# this model maps an input to its reconstruction
autoencoder = Model(input_img, decoded)

### ENCODER ###
# this model maps an input to its encoded representation. This is what we want to explore.
encoder = Model(input_img, encoded)

### DECODER ###
# create a placeholder for an encoded (32-dimensional) input
encoded_input = Input(shape=(encoding_dim,))
# retrieve the last layer of the autoencoder model
decoder_layer = autoencoder.layers[-1]
# create the decoder model
decoder = Model(encoded_input, decoder_layer(encoded_input))

# Configure model using adadelta optimizer for gradients and cross entropy loss function
autoencoder.compile(optimizer='rmsprop', loss='mean_squared_error')

### DATA PREPROCESS ###
(x_train, train_labels), (x_test, test_labels) = mnist.load_data()

x_train = x_train.astype('float32') / 255.
x_test = x_test.astype('float32') / 255.
x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))
print(x_train.shape) # Encodes from 784 dimensions to 32 dimensions

# We fit the data to itself, since we want to reconstruct input data
autoencoder.fit(x_train, x_train,
                epochs=50,
                batch_size=256,
                shuffle=True,
                validation_data=(x_test, x_test),
                callbacks=[TensorBoard(log_dir='/tmp/autoencoder')]) # to check loss

# encode and decode some digits from test set
encoded_test = encoder.predict(x_test) # 0-9
encoded_train = encoder.predict(x_train)

# normalize each feature to increase probability of convergence :)
encoded_train = preprocessing.normalize(encoded_train)
encoded_test = preprocessing.normalize(encoded_test)

# print(encoded_train)
print(encoded_train.shape)
print(encoded_test.shape)

decoded_imgs = decoder.predict(encoded_test)

# CLASSIFY
#param = [
#    {
#        "kernel": ["linear"],
#        "C"     : [1, 10, 100, 1000]
#    },
#    {
#        "kernel": ["rbf"],
#        "C"     : [1, 10, 100, 1000],
#        "gamma" : [1e-2, 1e-3, 1e-4, 1e-5]
#    }
#]

param = [{"kernel": ["rbf"], "C": [1000], "gamma": [0.01]}]

# Turn off probability estimation, set decision function to One Versus One
svm = SVC(probability=False, decision_function_shape='ovo', cache_size=71680)

# 10-fold cross validation, use 4 thread as each fold and each parameter set can be train in parallel
clf = grid_search.GridSearchCV(svm, param, cv=5, n_jobs=4, verbose=3)
clf.fit(encoded_train, train_labels)

print("\nBest parameters set:")
print(clf.best_params_)

# Testing on classifier..
y_predict = clf.predict(encoded_test)

print(type(y_predict))
# labels_sort = ','.join(map(str, train_labels))

labels_sort = sorted(list(set(test_labels)))

# labels_sort = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

#labels_sort = np.array([0,1,2,3,4,5,6,7,8,9])
print("\nConfusion matrix:")
print("Labels: {0}\n".format(",".join(str(labels_sort))))
print(confusion_matrix(test_labels, y_predict, labels=labels_sort))

print("\nClassification report:")
print(classification_report(test_labels, y_predict))

# Classify
# clf = svm.SVC(decision_function_shape='ovo')
# clf.fit(encoded_data, train_labels)
# decisions = clf.predict(encoded_imgs)
# CCR = (decisions == test_labels) / len(test_labels)
# print(CCR)

# Plots
n = 10  # how many digits we will display
plt.figure(figsize=(20, 4))
for i in range(n):
    # display original
    ax = plt.subplot(2, n, i + 1)
    plt.imshow(x_test[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    # display reconstruction
    ax = plt.subplot(2, n, i + 1 + n)
    plt.imshow(decoded_imgs[i].reshape(28, 28))
    plt.gray()
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)
plt.show()

# n = 10
# plt.figure(figsize=(20, 8))
# for i in range(n):
#     ax = plt.subplot(1, n, i + 1)
#     plt.imshow(encoded_imgs[i].reshape(4, 4 * 2).T)
#     plt.gray()
#     ax.get_xaxis().set_visible(False)
#     ax.get_yaxis().set_visible(False)
# plt.show()