## 광주인공지능사관학교 Warm-up Project (Team - DOYA)
## 커리어넷에서 전공 관련된 정보들을 크롤링하자!
## 2020.09.09

import requests
from bs4 import BeautifulSoup, NavigableString, Tag
import csv

major_link = [] # 각 전공 별로의 href를 할당하기 위한 list
major_big = []

for page in range(1, 53):
    URL = f'https://www.career.go.kr/cnet/front/base/major/FunivMajorList.do?pageIndex={page}' # 1~52 페이지까지 있는 커리어넷의 홈페이지 특성에 따라 URL 할당

    response = requests.get(URL)
    soup = BeautifulSoup(response.text, 'html.parser')

    soup_section = soup.select('#view1 > ul > li')

    for data in soup_section:
        a_tag = data.select_one('a')['href']
        major_link.append(a_tag) # 1~52페이지까지 돌면서 각 전공들의 구체적인 내용들이 담겨 있는 href를 가지고 와서 major_link라는 리스트에 저장
        # len(major_link)는 516개 = 커리어넷에 있는 전공의 개수

major_dic = { # csv 파일에 넣기 위해서 dic를 만듦
    'major': "",
    'major_describe': ""
}

for link in major_link: # 각 전공의 link에 들어가서 데이터들을 가져옴
    major_small = [] # 초기화

    URL = 'https://www.career.go.kr' + link

    response = requests.get(URL)
    soup = BeautifulSoup(response.text, 'html.parser')

    title = soup.select_one('#contents > #frm > .word_tit > h2').text
    detail = soup.select('#tab1 > .word_ul')

    for i in detail:
        major_small.append(i.text.replace('\n', '').replace('\r', '')) # 전공과 관련된 설명 부분들을 모두 모아서 major_small 이라는 작은 list에 저장

    major_dic['major'] = title # 전공 이름
    major_dic['major_describe'] = major_small # 전공 설명

    with open('careernet_major.csv', 'a', newline='') as csvfile: # for문이 한번 실행 될때마다 하나의 전공을 한 행씩 저장하는 csv 파일 생성
        fieldnames = ['major', 'major_describe']
        csv_writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        csv_writer.writerow(major_dic)

    print(111)


from pprint import pprint

from googleapiclient import discovery

import google.auth
import re
import sys
import os

credentials, project = google.auth.default()
service = discovery.build('compute', 'v1', credentials=credentials)

#print(str(sys.argv))
if (len(sys.argv)) >=3:
    project = sys.argv[1]
    instance = sys.argv[2]
    zone = sys.argv[3]

    # Get instance details
    request = service.instances().get(project=project, zone=zone, instance=instance)
    response = request.execute()

    # Get machine type
    mtype = re.search(r'(.*)/(.*)', response['machineType']).group(2)

    # Get operating system name
    osu = response['disks'][0]['licenses'][0]
    os = re.search(r'(.*)/(.*)', osu).group(2)

    # Get disk size/count
    #dsize = str(response['disks'][0]['diskSizeGb']) + ' GB'
    num_disks = len(response['disks'])

    # Use machine type to get cpu count & memory size
    mrequest = service.machineTypes().get(project=project, zone=zone, machineType=mtype)
    mresponse = mrequest.execute()

    # Get cpu count
    cpu = mresponse['guestCpus']

    # Get memory size
    megabyte = mresponse['memoryMb']
    gigabyte = 1.0/1024
    memory = str(gigabyte * megabyte) + ' GB'

    # Get status
    status = response['status']

    # Check if the instance is running
    if status == 'RUNNING':
        publicip_status = "IP externo desativado"
        publicip = ""
    else:
        publicip_status = "VM desligada"
        publicip = ""

    # Get network Interfaces list of dictionaries
    ni = response['networkInterfaces']

    # Get private IP and public IP
    for d in ni:
        privateip = str(d['networkIP'])
        if 'accessConfigs' in d:
            if 'natIP' in d['accessConfigs'][0]:
                publicip = str(d['accessConfigs'][0]['natIP'])
                publicip_status = "IP reservado"
            else:
                publicip = "IP temporario"
        else:
            publicip = "NA"

    print(f'{project},{instance},{zone},{mtype},{status},{os},{cpu},{memory},{num_disks},{privateip},{publicip_status},{publicip}')


#!/usr/bin/python3
# -*- coding: utf-8 -*-
from ..utils import Db, Db2Cdata

class Paipan:
    def __init__(self):
        # 初始数据
        self.wuxingName = '木 火 土 金 水'.split(' ')
        self.tianganName = '甲 乙 丙 丁 戊 己 庚 辛 壬 癸'.split(' ')
        self.dizhiName = '子 丑 寅 卯 辰 巳 午 未 申 酉 戌 亥'.split(' ')
        # 导入数据
        self.db = Db()
        self.db2cdata = Db2Cdata()
        self.Wuxing = self.db.get_tabledict_dict("[基础表-五行]")
        self.Tiangan = self.db.get_tabledict_dict("[基础表-十天干]")
        self.Dizhi = self.db.get_tabledict_dict("[基础表-十二地支]")
        self.Bagua = self.db.get_tabledict_dict("[基础表-八卦]")
        self.Liushisigua = self.db.get_tabledict_dict("[基础表-六十四卦]")
        self.Liushijiazi = self.db.get_tabledict_dict("[基础表-六十甲子]")

    def paipan(self, lunar, ganzhi, qiguafangfa, qiguashuru, naganzhifangfa):
        # 阴阳爻符号
        self.yinyangYao = ['▅▅  ▅▅', '▅▅▅▅▅']
        # 六爻盘格式
        self.Pan = {'10': {'上卦': '  ', '下卦': '  ', '六十四卦': '  ', '卦宫': '', '补充': '  之  '}, '20': {'上卦': '  ', '下卦': '  ', '六十四卦': '  ', '卦宫': '', '补充': ' 日空亡：'},
                    '16': {'六神': '  ', '卦爻': '', '动爻': ' ', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}, '26': {'卦爻': '', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '},
                    '15': {'六神': '  ', '卦爻': '', '动爻': ' ', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}, '25': {'卦爻': '', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '},
                    '14': {'六神': '  ', '卦爻': '', '动爻': ' ', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}, '24': {'卦爻': '', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '},
                    '13': {'六神': '  ', '卦爻': '', '动爻': ' ', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}, '23': {'卦爻': '', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '},
                    '12': {'六神': '  ', '卦爻': '', '动爻': ' ', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}, '22': {'卦爻': '', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '},
                    '11': {'六神': '  ', '卦爻': '', '动爻': ' ', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}, '21': {'卦爻': '', '六亲': '  ', '纳干': ' ', '纳支': ' ', '五行': ' ', '世应': ' '}}
        # 根据不同的起卦方法取不同的卦数
        guashu = None
        dongyao = None
        if qiguafangfa in ['标准时间起卦', '输入动爻时间起卦']:
            guashu, dongyao = self._qigua_shijianqigua(lunar, ganzhi, qiguashuru, qiguafangfa)
        elif qiguafangfa in ['两数字起卦', '三数字起卦', '四数字无动爻起卦', '八数字起卦']:
            guashu, dongyao = self._qigua_shuziqigua(qiguashuru, qiguafangfa)
        elif qiguafangfa == '爻位起卦':
            guashu, dongyao = self._qigua_yaoweiqigua(qiguashuru, qiguafangfa)  # 起卦输入形如：[2,7,5,9,4,1,[1,3,6]]（前6个为爻位数字从上到初，第7个为动爻组）
        # 根据返回的取卦数化卦
        gua, gua_code = self._qigua_huagua(guashu, dongyao)
        # 装卦爻
        self.Pan['16']['卦爻'] = self.yinyangYao[(gua_code[0] & 0b100) >> 2]
        self.Pan['15']['卦爻'] = self.yinyangYao[(gua_code[0] & 0b010) >> 1]
        self.Pan['14']['卦爻'] = self.yinyangYao[(gua_code[0] & 0b001) >> 0]
        self.Pan['13']['卦爻'] = self.yinyangYao[(gua_code[1] & 0b100) >> 2]
        self.Pan['12']['卦爻'] = self.yinyangYao[(gua_code[1] & 0b010) >> 1]
        self.Pan['11']['卦爻'] = self.yinyangYao[(gua_code[1] & 0b001) >> 0]
        self.Pan['26']['卦爻'] = self.yinyangYao[(gua_code[2] & 0b100) >> 2]
        self.Pan['25']['卦爻'] = self.yinyangYao[(gua_code[2] & 0b010) >> 1]
        self.Pan['24']['卦爻'] = self.yinyangYao[(gua_code[2] & 0b001) >> 0]
        self.Pan['23']['卦爻'] = self.yinyangYao[(gua_code[3] & 0b100) >> 2]
        self.Pan['22']['卦爻'] = self.yinyangYao[(gua_code[3] & 0b010) >> 1]
        self.Pan['21']['卦爻'] = self.yinyangYao[(gua_code[3] & 0b001) >> 0]
        self.dongyao = dongyao
        # 装动爻
        for i in self.Pan.keys():
            if self.dongyao:
                for j in self.dongyao:
                    if int(i[1:2]) == j:
                        if self.Pan[i]['卦爻'] == '▅▅  ▅▅':
                            self.Pan[i]['动爻'] = 'X'
                        else:
                            self.Pan[i]['动爻'] = 'O'
        # 装卦名
        self.Pan['10']['上卦'] = gua[0]
        self.Pan['10']['下卦'] = gua[1]
        self.Pan['20']['上卦'] = gua[2]
        self.Pan['20']['下卦'] = gua[3]
        self.Pan['10']['六十四卦'] = gua[4]
        self.Pan['20']['六十四卦'] = gua[5]
        self.Pan['10']['卦宫'] = self.Liushisigua[gua[4]]['卦宫']
        self.Pan['20']['卦宫'] = self.Liushisigua[gua[5]]['卦宫']
        self.Pan['20']['补充'] += ganzhi['四柱空亡'][2]
        # 装天干、地支（五行）、世应、六亲、六神
        self._zhuanggua_dizhiwuxing(naganzhifangfa)
        self._zhuanggua_tiangan(ganzhi, naganzhifangfa)
        self._zhuanggua_shiying()
        self._zhuanggua_liuqin()
        self._zhuanggua_liushen(ganzhi)
        self.Res = {'农历': lunar, '干支': ganzhi, '八卦': self.Bagua, '动爻': self.dongyao, '盘': self.Pan}
        return self.Res

    def _qigua_shijianqigua(self, lunar, ganzhi, qiguashuru, qiguafangfa):
        # 时间起卦法
        bengua_shang_num = None
        bengua_xia_num = None
        dongyao = []
        if qiguafangfa == '标准时间起卦':
            # 此时的起卦输入作为灵动数，灵动数加入到本卦下卦数，影响本卦下卦
            # 纳甲筮法时间取数法（本卦：（年+月+日）%8，（年+月+日+时）%8，动爻：（年+月+日+时）%6，取先天八卦数）。余0取坤
            # 求年月日时数
            nianshu = self.dizhiName.index(ganzhi['年柱'][1:2]) + 1
            yueshu = lunar['月']
            rishu = lunar['日']
            shishu = lunar['时']
            # 根据时间计算取卦数
            bengua_shang_num = (nianshu + yueshu + rishu) % 8
            if bengua_shang_num == 0:
                bengua_shang_num += 8
            # 判断是否加入灵动数，影响下卦和动爻
            if qiguashuru is None:
                bengua_xia_num = (nianshu + yueshu + rishu + shishu) % 8
                dongyao.append((nianshu + yueshu + rishu + shishu) % 6)
            else:
                bengua_xia_num = (nianshu + yueshu + rishu + shishu + qiguashuru[0]) % 8
                dongyao.append((nianshu + yueshu + rishu + shishu + qiguashuru[0]) % 6)
            if bengua_xia_num == 0:
                bengua_xia_num += 8
            if dongyao[0] == 0:
                dongyao[0] += 6
        # 此时的起卦输入作为动爻(1-6)，可多动，影响变卦
        elif qiguafangfa == '输入动爻时间起卦':
            # 求年月日时数
            nianshu = self.dizhiName.index(ganzhi['年柱'][1:2]) + 1
            yueshu = lunar['月']
            rishu = lunar['日']
            shishu = lunar['时']
            # 根据时间计算取卦数
            bengua_shang_num = (nianshu + yueshu + rishu) % 8
            if bengua_shang_num == 0:
                bengua_shang_num += 8
            bengua_xia_num = (nianshu + yueshu + rishu + shishu) % 8
            if bengua_xia_num == 0:
                bengua_xia_num += 8
            # 根据起卦输入确定动爻
            for i in qiguashuru:
                if i not in dongyao:
                    dongyao.append(i)
        return [bengua_shang_num, bengua_xia_num], dongyao

    def _qigua_shuziqigua(self, qiguashuru, qiguafangfa):
        # 数字起卦法
        # 同样采用先天八卦纳数
        guashu = []
        dongyao = []
        if qiguafangfa == '两数字起卦':
            bengua_shang_num = qiguashuru[0] % 8
            if bengua_shang_num == 0:
                bengua_shang_num += 8
            bengua_xia_num = qiguashuru[1] % 8
            if bengua_xia_num == 0:
                bengua_xia_num += 8
            dongyao.append((qiguashuru[0] + qiguashuru[1]) % 6)
            if dongyao[0] == 0:
                dongyao[0] += 6
            guashu.append(bengua_shang_num)
            guashu.append(bengua_xia_num)
        elif qiguafangfa == '三数字起卦':
            bengua_shang_num = qiguashuru[0] % 8
            if bengua_shang_num == 0:
                bengua_shang_num += 8
            bengua_xia_num = qiguashuru[1] % 8
            if bengua_xia_num == 0:
                bengua_xia_num += 8
            dongyao.append((qiguashuru[0] + qiguashuru[1] + qiguashuru[2]) % 6)
            if dongyao[0] == 0:
                dongyao[0] += 6
            guashu.append(bengua_shang_num)
            guashu.append(bengua_xia_num)
        elif qiguafangfa == '四数字无动爻起卦':
            bengua_shang_num = qiguashuru[0] % 8
            if bengua_shang_num == 0:
                bengua_shang_num += 8
            bengua_xia_num = qiguashuru[1] % 8
            if bengua_xia_num == 0:
                bengua_xia_num += 8
            biangua_shang_num = qiguashuru[2] % 8
            if biangua_shang_num == 0:
                biangua_shang_num += 8
            biangua_xia_num = qiguashuru[3] % 8
            if biangua_xia_num == 0:
                biangua_xia_num += 8
            guashu.append(bengua_shang_num)
            guashu.append(bengua_xia_num)
            guashu.append(biangua_shang_num)
            guashu.append(biangua_xia_num)
        elif qiguafangfa == '八数字起卦':
            pass
        return guashu, dongyao

    def _qigua_yaoweiqigua(self, qiguashuru, qiguafangfa):
        # 爻位起卦法
        bengua_shang_num = None
        bengua_xia_num = None
        dongyao = []
        # 此时的起卦输入前6个为爻位数字，第7个为动爻数组
        yaowei_code = []
        for i in range(0, 6):
            if qiguashuru[i] in [1, 3, 5, 7, 9]:
                yaowei_code.append(1)  # 奇数为阳1
            else:
                yaowei_code.append(0)
        bengua_shang_code = yaowei_code[0]*4 + yaowei_code[1]*2 + yaowei_code[2]*1
        bengua_xia_code = yaowei_code[3] * 4 + yaowei_code[4] * 2 + yaowei_code[5] * 1
        for i in self.Bagua.keys():
            if eval(self.Bagua[i]['二进制']) == bengua_shang_code:
                bengua_shang_num = self.Bagua[i]['先天卦数']
            if eval(self.Bagua[i]['二进制']) == bengua_xia_code:
                bengua_xia_num = self.Bagua[i]['先天卦数']
        for i in qiguashuru[6]:
            if i not in dongyao:
                dongyao.append(i)
        return [bengua_shang_num, bengua_xia_num], dongyao

    def _qigua_huagua(self, guashu, dongyao):
        # 根据取卦数取卦，按照先天八卦数取卦
        bengua_shang_num = guashu[0]
        bengua_xia_num = guashu[1]
        bengua_xia = None
        bengua_shang = None
        biangua_xia = None
        biangua_shang = None
        bengua_shang_code = None
        bengua_xia_code = None
        biangua_shang_code = None
        biangua_xia_code = None
        for i in self.Bagua.keys():
            if bengua_shang_num == int(self.Bagua[i]['先天卦数']):
                bengua_shang = i
                bengua_shang_code = eval(self.Bagua[i]['二进制'])
            if bengua_xia_num == int(self.Bagua[i]['先天卦数']):
                bengua_xia = i
                bengua_xia_code = eval(self.Bagua[i]['二进制'])
        # 求本卦的六十四卦
        bengua = None
        bengua_code = None
        for i in self.Liushisigua.keys():
            if self.Liushisigua[i]['上卦名'] == bengua_shang and self.Liushisigua[i]['下卦名'] == bengua_xia:
                bengua = i
                bengua_code = eval(self.Liushisigua[i]['二进制'])
        # 动爻可有0个（用单个0表示）、1个或多个
        # 无动爻则卦数必然有4个，变卦根据后两个卦数得来
        if len(dongyao) == 0:
            biangua_shang_num = guashu[2]
            biangua_xia_num = guashu[3]
            for i in self.Bagua.keys():
                if biangua_shang_num == self.Bagua[i]['先天卦数']:
                    biangua_shang = i
                    biangua_shang_code = eval(self.Bagua[i]['二进制'])
                if biangua_xia_num == self.Bagua[i]['先天卦数']:
                    biangua_xia = i
                    biangua_xia_code = eval(self.Bagua[i]['二进制'])
        # 有动爻，则卦数只有两个，变卦由本卦和动爻计算得来
        elif len(dongyao) >= 1:
            dongyao_code = 0
            for i in dongyao:
                dongyao_code += 2 ** (i - 1)
            biangua_code = eval(self.Liushisigua[bengua]['二进制']) ^ dongyao_code
            biangua_shang_code = biangua_code // 8  # 取前三位
            biangua_xia_code = biangua_code % 8  # 取后三位
            for i in self.Bagua.keys():
                if biangua_shang_code == eval(self.Bagua[i]['二进制']):
                    biangua_shang = i
                if biangua_xia_code == eval(self.Bagua[i]['二进制']):
                    biangua_xia = i
        # 求变卦的六十四卦
        biangua = None
        biangua_code = None
        for i in self.Liushisigua.keys():
            if self.Liushisigua[i]['上卦名'] == biangua_shang and self.Liushisigua[i]['下卦名'] == biangua_xia:
                biangua = i
                biangua_code = eval(self.Liushisigua[i]['二进制'])
        return [bengua_shang, bengua_xia, biangua_shang, biangua_xia, bengua, biangua], [bengua_shang_code, bengua_xia_code, biangua_shang_code, biangua_xia_code, bengua_code, biangua_code]

    def _zhuanggua_dizhiwuxing(self, naganzhifangfa):
        if naganzhifangfa == '传统京氏':
            # 乾卦从最下面起的三爻为子，寅，辰；上面三爻为午，申，戌；
            # 兑卦从最下面起的三爻为巳，卯，丑；上面三爻为亥，酉，未；
            # 离卦从最下面起的三爻为卯，丑，亥；上面三爻为酉，未，巳；
            # 震卦从最下面起的三爻为子，寅，辰；上面三爻为午，申，戌；
            # 巽卦从最下面起的三爻为丑，亥，酉；上面三爻为未，巳，卯；
            # 坎卦从最下面起的三爻为寅，辰，午；上面三爻为申，戌，子；
            # 艮卦从最下面起的三爻为辰，午，申；上面三爻为戌，子，寅；
            # 坤卦从最下面起的三爻为未，巳，卯；上面三爻为丑，亥，酉；
            nazhi = {'乾': ['子', '寅', '辰', '午', '申', '戌'],
                     '兑': ['巳', '卯', '丑', '亥', '酉', '未'],
                     '离': ['卯', '丑', '亥', '酉', '未', '巳'],
                     '震': ['子', '寅', '辰', '午', '申', '戌'],
                     '巽': ['丑', '亥', '酉', '未', '巳', '卯'],
                     '坎': ['寅', '辰', '午', '申', '戌', '子'],
                     '艮': ['辰', '午', '申', '戌', '子', '寅'],
                     '坤': ['未', '巳', '卯', '丑', '亥', '酉']}
        elif naganzhifangfa == '先天甲子易':
            # 乾卦从最下面起的三爻为子，寅，辰；上面三爻为午，申，戌；
            # 兑卦从最下面起的三爻为巳，卯，丑；上面三爻为亥，酉，未；
            # 离卦从最下面起的三爻为卯，丑，亥；上面三爻为酉，未，巳；
            # 震卦从最下面起的三爻为午，申，戌；上面三爻为子，寅，辰；
            # 巽卦从最下面起的三爻为丑，亥，酉；上面三爻为未，巳，卯；
            # 坎卦从最下面起的三爻为辰，午，申；上面三爻为戌，子，寅；
            # 艮卦从最下面起的三爻为寅，辰，午；上面三爻为申，戌，子；
            # 坤卦从最下面起的三爻为未，巳，卯；上面三爻为丑，亥，酉；
            nazhi = {'乾': ['子', '寅', '辰', '午', '申', '戌'],
                     '兑': ['巳', '卯', '丑', '亥', '酉', '未'],
                     '离': ['卯', '丑', '亥', '酉', '未', '巳'],
                     '震': ['午', '申', '戌', '子', '寅', '辰'],
                     '巽': ['丑', '亥', '酉', '未', '巳', '卯'],
                     '坎': ['辰', '午', '申', '戌', '子', '寅'],
                     '艮': ['寅', '辰', '午', '申', '戌', '子'],
                     '坤': ['未', '巳', '卯', '丑', '亥', '酉']}
        bengua_xiagua = self.Pan['10']['下卦']
        biangua_xiagua = self.Pan['20']['下卦']
        bengua_shanggua = self.Pan['10']['上卦']
        biangua_shanggua = self.Pan['20']['上卦']
        for i in range(0, 6):
            if i < 3:
                self.Pan['1' + str(i + 1)]['纳支'] = nazhi[bengua_xiagua][i]
                self.Pan['1' + str(i + 1)]['五行'] = self.Dizhi[self.Pan['1' + str(i + 1)]['纳支']]['五行']
                self.Pan['2' + str(i + 1)]['纳支'] = nazhi[biangua_xiagua][i]
                self.Pan['2' + str(i + 1)]['五行'] = self.Dizhi[self.Pan['2' + str(i + 1)]['纳支']]['五行']
            else:
                self.Pan['1' + str(i + 1)]['纳支'] = nazhi[bengua_shanggua][i]
                self.Pan['1' + str(i + 1)]['五行'] = self.Dizhi[self.Pan['1' + str(i + 1)]['纳支']]['五行']
                self.Pan['2' + str(i + 1)]['纳支'] = nazhi[biangua_shanggua][i]
                self.Pan['2' + str(i + 1)]['五行'] = self.Dizhi[self.Pan['2' + str(i + 1)]['纳支']]['五行']

    def _zhuanggua_tiangan(self, ganzhi, naganzhifangfa):
        if naganzhifangfa == '传统京氏':
            # 乾纳甲壬坎纳戊
            # 离纳己土震纳庚
            # 坤纳乙癸巽纳辛
            # 艮纳丙火兑纳丁
            nagan = {'乾': ['甲', '壬'],
                     '兑': ['丁', '丁'],
                     '离': ['己', '己'],
                     '震': ['庚', '庚'],
                     '巽': ['辛', '辛'],
                     '坎': ['戊', '戊'],
                     '艮': ['丙', '丙'],
                     '坤': ['乙', '癸']}
            for i in self.Pan.keys():
                if i[1:2] in ['1', '2', '3']:  # 下卦
                    self.Pan[i]['纳干'] = nagan[self.Pan[i[0:1] + '0']['下卦']][0]
                if i[1:2] in ['4', '5', '6']:  # 上卦
                    self.Pan[i]['纳干'] = nagan[self.Pan[i[0:1] + '0']['上卦']][1]
        elif naganzhifangfa == '先天甲子易':
            rigan = ganzhi['日柱'][0:1]
            # 五子元遁
            if rigan in ['甲', '己']:
                gan_index = 1  # 甲子
            elif rigan in ['乙', '庚']:
                gan_index = 3  # 丙子
            elif rigan in ['丙', '辛']:
                gan_index = 5  # 戊子
            elif rigan in ['丁', '壬']:
                gan_index = 7  # 庚子
            elif rigan in ['戊', '癸']:
                gan_index = 9  # 壬子
            else:
                gan_index = 1
            for i in self.Pan.keys():
                if i == '10' or i == '20':
                    continue
                idx = self.dizhiName.index(self.Pan[i]['纳支']) + gan_index - 1
                if idx >= 10:
                    idx -= 10
                self.Pan[i]['纳干'] = self.tianganName[idx]

    def _zhuanggua_shiying(self):
        # 天同二世天变五
        # 地同四世地变初
        # 人同游魂（四世）人变归（三世）
        # 本宫六世三世异
        for i in range(0, 2):
            # 天同二世
            if self.Pan[str(i + 1) + '3']['卦爻'] == self.Pan[str(i + 1) + '6']['卦爻'] \
                    and self.Pan[str(i + 1) + '1']['卦爻'] != self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '2']['卦爻'] != self.Pan[str(i + 1) + '5']['卦爻']:
                self.Pan[str(i + 1) + '2']['世应'] = '世'
                self.Pan[str(i + 1) + '5']['世应'] = '应'
            # 天变五
            if self.Pan[str(i + 1) + '3']['卦爻'] != self.Pan[str(i + 1) + '6']['卦爻'] \
                    and self.Pan[str(i + 1) + '1']['卦爻'] == self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '2']['卦爻'] == self.Pan[str(i + 1) + '5']['卦爻']:
                self.Pan[str(i + 1) + '5']['世应'] = '世'
                self.Pan[str(i + 1) + '2']['世应'] = '应'
            # 地同四世
            if self.Pan[str(i + 1) + '1']['卦爻'] == self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '2']['卦爻'] != self.Pan[str(i + 1) + '5']['卦爻'] \
                    and self.Pan[str(i + 1) + '3']['卦爻'] != self.Pan[str(i + 1) + '6']['卦爻']:
                self.Pan[str(i + 1) + '4']['世应'] = '世'
                self.Pan[str(i + 1) + '1']['世应'] = '应'
            # 地变初
            if self.Pan[str(i + 1) + '1']['卦爻'] != self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '2']['卦爻'] == self.Pan[str(i + 1) + '5']['卦爻'] \
                    and self.Pan[str(i + 1) + '3']['卦爻'] == self.Pan[str(i + 1) + '6']['卦爻']:
                self.Pan[str(i + 1) + '1']['世应'] = '世'
                self.Pan[str(i + 1) + '4']['世应'] = '应'
            # 人同游魂（四世）
            if self.Pan[str(i + 1) + '2']['卦爻'] == self.Pan[str(i + 1) + '5']['卦爻'] \
                    and self.Pan[str(i + 1) + '1']['卦爻'] != self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '3']['卦爻'] != self.Pan[str(i + 1) + '6']['卦爻']:
                self.Pan[str(i + 1) + '4']['世应'] = '世'
                self.Pan[str(i + 1) + '1']['世应'] = '应'
            # 人变归（三世）
            if self.Pan[str(i + 1) + '2']['卦爻'] != self.Pan[str(i + 1) + '5']['卦爻'] \
                    and self.Pan[str(i + 1) + '1']['卦爻'] == self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '3']['卦爻'] == self.Pan[str(i + 1) + '6']['卦爻']:
                self.Pan[str(i + 1) + '3']['世应'] = '世'
                self.Pan[str(i + 1) + '6']['世应'] = '应'
            # 本宫六世
            if self.Pan[str(i + 1) + '3']['卦爻'] == self.Pan[str(i + 1) + '6']['卦爻'] \
                    and self.Pan[str(i + 1) + '1']['卦爻'] == self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '2']['卦爻'] == self.Pan[str(i + 1) + '5']['卦爻']:
                self.Pan[str(i + 1) + '6']['世应'] = '世'
                self.Pan[str(i + 1) + '3']['世应'] = '应'
            # 三世异
            if self.Pan[str(i + 1) + '3']['卦爻'] != self.Pan[str(i + 1) + '6']['卦爻'] \
                    and self.Pan[str(i + 1) + '1']['卦爻'] != self.Pan[str(i + 1) + '4']['卦爻'] \
                    and self.Pan[str(i + 1) + '2']['卦爻'] != self.Pan[str(i + 1) + '5']['卦爻']:
                self.Pan[str(i + 1) + '3']['世应'] = '世'
                self.Pan[str(i + 1) + '6']['世应'] = '应'

    def _zhuanggua_liuqin(self):
        # 首先确定得出的本卦是何宫（八宫六十四卦）
        # 然后以这个五行为“我”，根据所纳地支的五行，依“生我者父母，我生者子孙，克我者官鬼，我克者妻财，相同者兄弟”的关系来定六亲
        bengua_wuxing = self.Bagua[self.Pan['10']['卦宫']]['五行']
        fumu = self.db2cdata.get_wuxing_shengke(bengua_wuxing, return_type='生')
        zisun = self.db2cdata.get_wuxing_shengke(bengua_wuxing, return_type='泄')
        guangui = self.db2cdata.get_wuxing_shengke(bengua_wuxing, return_type='克')
        qicai = self.db2cdata.get_wuxing_shengke(bengua_wuxing, return_type='耗')
        xiongdi = self.db2cdata.get_wuxing_shengke(bengua_wuxing, return_type='助')
        for i in range(0, 6):
            if self.Pan['1' + str(i + 1)]['五行'] == fumu:
                self.Pan['1' + str(i + 1)]['六亲'] = '父母'
            if self.Pan['1' + str(i + 1)]['五行'] == zisun:
                self.Pan['1' + str(i + 1)]['六亲'] = '子孙'
            if self.Pan['1' + str(i + 1)]['五行'] == guangui:
                self.Pan['1' + str(i + 1)]['六亲'] = '官鬼'
            if self.Pan['1' + str(i + 1)]['五行'] == qicai:
                self.Pan['1' + str(i + 1)]['六亲'] = '妻财'
            if self.Pan['1' + str(i + 1)]['五行'] == xiongdi:
                self.Pan['1' + str(i + 1)]['六亲'] = '兄弟'
            if self.Pan['2' + str(i + 1)]['五行'] == fumu:
                self.Pan['2' + str(i + 1)]['六亲'] = '父母'
            if self.Pan['2' + str(i + 1)]['五行'] == zisun:
                self.Pan['2' + str(i + 1)]['六亲'] = '子孙'
            if self.Pan['2' + str(i + 1)]['五行'] == guangui:
                self.Pan['2' + str(i + 1)]['六亲'] = '官鬼'
            if self.Pan['2' + str(i + 1)]['五行'] == qicai:
                self.Pan['2' + str(i + 1)]['六亲'] = '妻财'
            if self.Pan['2' + str(i + 1)]['五行'] == xiongdi:
                self.Pan['2' + str(i + 1)]['六亲'] = '兄弟'

    def _zhuanggua_liushen(self, ganzhi):
        # 根据日干：甲乙起青龙，丙丁起朱雀，戊日起勾陈，己日起腾蛇，庚辛起白虎，壬癸起玄武（正好是对应的五行）
        # 按照青龙、朱雀、勾陈、腾蛇、白虎、玄武的顺序，由初爻装至六爻
        rigan = ganzhi['日柱'][0:1]
        liushen = ['青龙', '朱雀', '勾陈', '腾蛇', '白虎', '玄武']
        idx = 0
        if rigan in ['甲', '乙']:
            idx = 0
        if rigan in ['丙', '丁']:
            idx = 1
        if rigan in ['戊']:
            idx = 2
        if rigan in ['己']:
            idx = 3
        if rigan in ['庚', '辛']:
            idx = 4
        if rigan in ['壬', '癸']:
            idx = 5
        for i in range(0, 6):
            if i + idx > 5:
                idx -= 6
            self.Pan['1' + str(i + 1)]['六神'] = liushen[i + idx]
            self.Pan['2' + str(i + 1)]['六神'] = liushen[i + idx]

    def output(self):
        map_str = ''
        for i in self.Pan.keys():
            if i == '10' or i == '20':
                map_str += '上'
                map_str += self.Pan[i]['上卦']
                map_str += '下'
                map_str += self.Pan[i]['下卦']
                map_str += ' '
                map_str += self.Pan[i]['六十四卦']
                map_str += '('
                map_str += self.Pan[i]['卦宫']
                map_str += '宫)'
                map_str += self.Pan[i]['补充']
                if i[0:1] == '2':
                    map_str += '\n'
            else:
                if i[0:1] == '1':
                    map_str += self.Pan[i]['六神']
                map_str += self.Pan[i]['卦爻']
                if i[0:1] == '1':
                    map_str += self.Pan[i]['动爻']
                map_str += self.Pan[i]['六亲']
                map_str += self.Pan[i]['纳干']
                map_str += self.Pan[i]['纳支']
                map_str += self.Pan[i]['五行']
                map_str += self.Pan[i]['世应']
                if i[0:1] == '1':
                    map_str += '\t'
                if i[0:1] == '2':
                    map_str += '\n'
        return map_str


import re, psycopg2, os
from fastai.text import load_learner
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()

path = Path(__file__).parent
learn = load_learner("./", path/'models/deep_poet')
URI = os.getenv("URI")
def generate_poem(init,length,temp):
  return learn.predict(init, n_words=length, temperature=temp)

def getMax(poem):
  poem = re.sub('\n',"",poem)
  list = poem.split(" ")
  occ = {}
  max = 0
  for word in list:
    if len(word) > 3  :
      occ[word] = occ.get(word,0) + 1
      if occ[word] > max : max = occ[word]
  return max

def savePoem(poem, init, length, temp, counter, repetition_tolerance):
  connection = psycopg2.connect(URI) #.env uri
  cursor = connection.cursor()
  args = [poem, init, length, temp, counter, repetition_tolerance]
  cursor.execute("INSERT INTO poems VALUES (default, %s, %s, %s, %s, %s, %s)", args)
  connection.commit()

def write_poem(init, temp=0.55, length=100, repetition_tolerance=8, max=10):
  counter = 0
  poem = generate_poem(init,length,temp)
  while getMax(poem)>= repetition_tolerance :
      counter += 1
      poem = generate_poem(init,length,temp)
      if (counter > max) : break
  poem = re.sub(' i ', ' I ', poem)
  verses = poem.split("\n")
  for i in range(len(verses)):
      verses[i] = verses[i].strip()
      if len(verses[i]) > 1: verses[i] = verses[i][0].upper() + verses[i][1:]
      elif len(verses[i]) == 1 : verses[i] = verses[i].upper()
  poem = "<br>".join(verses)
  savePoem(poem, init, length, temp, counter, repetition_tolerance)
  return poem


#
# https://leetcode.com/problems/third-maximum-number/
#
# Given an integer array nums, return the third distinct maximum number in this array.
# If the third maximum does not exist, return the maximum number.
#
# Example 1:
#       Input: nums = [3, 2, 1]
#       Output: 1
#
# Example 2:
#       Input: nums = [1, 2]
#       Output: 2
#
# Example 3:
#       Input: nums = [2, 2, 3, 1]
#       Output: 1
#

from typing import List
import sys
import pdb
br = pdb.set_trace

solution_json = {
    "date": "2022/?/??",
    "design": 0,
    "coding": 0,
    "runtime": "?? ms",
    "fasterThan": "",
    "memory": "?? MB"
}

class Solution:
    def __init__(self):
        self.module = sys.modules[__name__]

    def thirdMax(self, nums: List[int]) -> int:
        return -1


import math
import numpy
from keras.callbacks import Callback
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers.recurrent import LSTM
from sklearn import preprocessing
import matplotlib.pyplot as plt

# Keeps track of loss per batch
class LossHistory(Callback):
    def on_train_begin(self, logs={}):
        self.losses = ([],[])
        self.i = 0

    def on_batch_end(self, batch, logs={}):
        self.losses[0].append(self.i)
        self.losses[1].append(logs.get('loss'))
        self.i += 1

f = open("nome_city_feeder.csv", "r")
data = f.readlines()
f.close()

data = [data[i].rstrip('\n').split(',') for i in range(1, len(data))]

# Convert the data to float values
for i in range(len(data)):
    for j in range(1, len(data[i])):
        # I assigned each unique wind direction a number from 1 to 17
        # these values will be normalized later
        if j == 5:
            if data[i][5] == 'North':
                data[i][5] = 1.0
            elif data[i][5] == 'South':
                data[i][5] = 2.0
            elif data[i][5] == 'East':
                data[i][5] = 3.0
            elif data[i][5] == 'West':
                data[i][5] = 4.0
            elif data[i][5] == 'WNW':
                data[i][5] = 5.0
            elif data[i][5] == 'SSE':
                data[i][5] = 6.0
            elif data[i][5] == 'ENE':
                data[i][5] = 7.0
            elif data[i][5] == 'NE':
                data[i][5] = 8.0
            elif data[i][5] == 'WSW':
                data[i][5] = 9.0
            elif data[i][5] == 'SE':
                data[i][5] = 10.0
            elif data[i][5] == 'SSW':
                data[i][5] = 11.0
            elif data[i][5] == 'NW':
                data[i][5] = 12.0
            elif data[i][5] == 'ESE':
                data[i][5] = 13.0
            elif data[i][5] == 'SW':
                data[i][5] = 14.0
            elif data[i][5] == 'NNE':
                data[i][5] = 15.0
            elif data[i][5] == 'NNW':
                data[i][5] = 16.0
            elif data[i][5] == '':
                data[i][5] = 17.0
        else:
            data[i][j] = float(data[i][j])

# plots loss per batch
def plot_loss(x, y):
    plt.figure()
    plt.subplot()
    plt.xlabel("Batch Number")
    plt.ylabel("Loss")
    plt.plot(x, y)

def plot_predictions_vs_expected(predictions, y_expected):
    plt.figure()
    plt.subplot()
    plt.xlabel("Time (1 unit=10 min)")
    plt.ylabel("Amps (scaled to range 1 to 0)")
    plt.plot([i for i in range(len(predictions))],[y_expected[i][0][0] for i in range(len(predictions))], label="Expected Values")
    plt.plot([i for i in range(len(predictions))],[i[0][0] for i in predictions], label="Predictions")
    plt.legend()

def plot_expected_values(exp):
    plt.figure()
    plt.subplot()
    plt.ylim(0,1)
    plt.xlabel("Time (1 unit=10 min)")
    plt.ylabel("Amps (scaled to range 0 to 1)")
    plt.title("Expected Values")
    plt.plot([i for i in range(len(exp))],[exp[i][0][0] for i in range(len(exp))])

def plot_predicted_values(pred):
    plt.figure()
    plt.subplot()
    plt.ylim(0,1)
    plt.xlabel("Time (1 unit=10 min)")
    plt.ylabel("Amps (scaled to range 1 to 0)")
    plt.title("Predicted Values")
    plt.plot([i for i in range(len(pred))],[pred[i][0][0] for i in range(len(pred))], color='orange')

# adjust the input instances so the average amps are over time_period*10 minutes
def average_amps(train_data, validation_data, time_period):
    t = [([train_data[i][0]] + [float(sum(j[1] for j in train_data[(i-time_period+1):(i+1)])/time_period)] + train_data[i][2:]) for i in range(time_period-1, len(train_data))]
    v = [([validation_data[i][0]] + [float(sum(j[1] for j in validation_data[i-time_period+1:i+1])/time_period)] + validation_data[i][2:]) for i in range(time_period-1, len(validation_data))]
    return t, v

# pred_len is the time period to predict (example: each instance is
# the average over 10 min, so pred_len=1 will predict the next
# instance amp value given an instance vector, pred_len=4 will predict the
# average over the next 40 minutes given an instance),
# layers is the number of hidden layers to add to the network,
# nodes is the nodes per layer, if drop is a positive value it dropout is added,
# eps is the number of training epochs, x values are the instance vectors,
# y values are the expected amp values for the next time step,
# if no_amp is true then the amp values aren't included in the input vectors,
# returns the lstm model
def get_lstm_model(train_data, validation_data, pred_len, layers, nodes, drop, eps, b_size, no_amp):
    scaler = preprocessing.MinMaxScaler(feature_range=(0,1))
    start_index = 1
    if no_amp:
        start_index = 2

    x_train_data = train_data[:-pred_len]
    # The expected value, y, for a given x is is the average amps over the next n instances
    # where n=pred_len, if pred_len=1 the expected value is the amp value of the next instance
    y_train_data = [train_data[i][1] for i in range(pred_len, len(train_data))]
    x_validation_data = validation_data[:-pred_len]
    y_validation_data = [validation_data[i][1] for i in range(pred_len, len(validation_data))]

    # scale the data to range 0 to 1 and store as numpy.array
    x_train = numpy.array([[i] for i in scaler.fit_transform([x_train_data[i][start_index:] for i in range(len(x_train_data))])])
    y_train = numpy.array([[i] for i in scaler.fit_transform([[y_train_data[i]] for i in range(len(y_train_data))])])

    x_test = numpy.array([[i] for i in scaler.fit_transform([x_validation_data[i][start_index:] for i in range(len(x_validation_data))])])
    y_test = numpy.array([[i] for i in scaler.fit_transform([[y_validation_data[i]] for i in range(len(y_validation_data))])])

    # Create the model
    lstm_model = Sequential()
    # input layer
    lstm_model.add(LSTM(nodes, input_shape=(1, len(x_train[0][0])), return_sequences=True))
    # hidden layers
    for i in range(layers):
        lstm_model.add(LSTM(nodes, return_sequences=True))
    if drop > 0:
        lstm_model.add(Dropout(drop))

    # output layer
    lstm_model.add(Dense(1))
    lstm_model.compile(loss='mse', optimizer='adam')
    # history stores the loss per batch
    history = LossHistory()
    lstm_model.fit(x_train, y_train, batch_size=b_size, epochs=eps, validation_data=(x_test, y_test), callbacks=[history])

    predictions = lstm_model.predict(x_test)

    # create desired plots
    plot_expected_values(y_test)
    plot_predicted_values(predictions)
    plot_predictions_vs_expected(predictions, y_test)
    plot_loss(history.losses[0], history.losses[1])
    plt.show()
    return lstm_model

# split the data, 75% for training, 25% for validation
train_data = data[:int(len(data)*0.75)]
validation_data = data[int(len(data)*0.75):]

# input instances are 10 minutes apart, have 9 weather features and
# one amp measurement feature which is the average for the
# time period being predicted

# lstm to predict average amps over next ten minutes
next_ten_min_lstm = get_lstm_model(train_data, validation_data, 1, 1, 100, 0, 2, 64, False)
next_ten_min_lstm_no_amp = get_lstm_model(train_data, validation_data, 1, 1, 120, 0, 1, 64, True)

# lstm to predict average amps over next forty minutes
t, v = average_amps(train_data, validation_data, 4)
next_forty_min_lstm = get_lstm_model(t, v, 4, 2, 120, 0.2, 2, 300, False)
next_forty_min_lstm_no_amp = get_lstm_model(t, v, 4, 2, 100, 0, 2, 400, True)

# lstm to predict average amps over next 12 hours
t, v = average_amps(train_data, validation_data, 72)
next_twelve_hour_lstm = get_lstm_model(t, v, 72, 3, 100, 0.2, 2, 300, False)
next_twelve_hour_lstm_no_amp = get_lstm_model(t, v, 72, 2, 100, 0, 2, 400, True)

# lstm to predict average amps over next 24 hours
t, v = average_amps(train_data, validation_data, 144)
next_24_hour_lstm = get_lstm_model(t, v, 144, 3, 110, 0.2, 2, 500, False)
next_24_hour_lstm_no_amp = get_lstm_model(t, v, 144, 3, 120, 0.2, 3, 400, True)


"""Class for sending metrics to ElasticSearch ci-performance-test index."""
import datetime
import json
import time

import gflags
import requests

gflags.DEFINE_boolean("send_perf_metrics", False, "Send perf metrics to ElasticSearch for dashboard presentation.")

FLAGS = gflags.FLAGS
BASE_URL = "http://elasticsearch.dfinity.systems:9200"
INDEX = "performance-trend"

class ElasticSearch:
    """Client class for intercting with ElasticSearch."""

    def call_elastic_search(metric):
        """Client to make a call to ElasticSearch."""
        addr = f"{BASE_URL}/{INDEX}/_doc/"
        for i in range(3):
            try:
                response = requests.post(
                    url=addr,
                    data=json.dumps(metric, indent=4, default=str).encode(),
                    headers={"content-type": "application/json"},
                    timeout=30,
                )
                if response.status_code < 500:
                    if response.status_code < 400:
                        # success
                        print(f"Data points successfully sent to {addr}")
                        return True
                    else:
                        # client side error, log error and no retry
                        print(
                            f"Invalid input request: {metric}. Response received was: {response.status_code} {response.content}"
                        )
                        return False

                else:
                    # service side error, retry after 3 seconds
                    print(
                        f'Remote service error received when send metrics to {addr}. {response.status_code} {response.content}. {"" if (i == 2) else "Sleep 3 seconds before next retry."}'
                    )
                    time.sleep(3)

            except Exception as e:
                print(
                    f'Exception caught when send metrics to {addr}. {e}. {"" if (i == 2) else "Sleep 3 seconds before next retry."}'
                )
                time.sleep(3)
        return False

    def send_perf(name, is_success, request_type, revision, branch, is_ci_job, summaries):
        """Send a performance nightly data point performance-trend index in ElasticSearch."""
        if FLAGS.send_perf_metrics is False:
            return True

        (
            failure_rate,
            failure_rate_threshold,
            median_latency,
            median_latency_threshold,
            throughput,
            throughput_threshold,
        ) = summaries

        metric = {
            "timestamp": datetime.datetime.now().isoformat(),
            "rev": revision,
            "branch": branch,
            "is_ci_job": is_ci_job,
            "package": "replica-perf-trend",
            "performance": {
                "title": name,
                "request_type": request_type,
                "is_success": is_success,
                "metrics": {
                    "failure_rate": {
                        "value": failure_rate,
                        "threshold": failure_rate_threshold,
                    },
                    "median_latency": {
                        "value": median_latency,
                        "threshold": median_latency_threshold,
                    },
                    "throughput": {
                        "value": throughput,
                        "threshold": throughput_threshold,
                    },
                },
            },
        }
        return ElasticSearch.call_elastic_search(metric)

    def send_max_capacity(
        name, request_type, experiment_revision, experiment_branch, is_ci_job, rps, out_dir, unix_time=None
    ):
        """Send a maximum capacity data point to performance-trend index in ElasticSearch."""
        if FLAGS.send_perf_metrics is False:
            return True

        if unix_time is None:
            unix_time = int(time.time())
            timestamp = datetime.datetime.fromtimestamp(unix_time).isoformat()
        else:
            timestamp = datetime.datetime.fromtimestamp(unix_time).isoformat()

        metric = {
            "unix_time": unix_time,
            "timestamp": timestamp,
            "rev": experiment_revision,
            "branch": experiment_branch,
            "is_ci_job": is_ci_job,
            "package": "replica-perf-trend",
            "report_url": f"http://10.11.10.88:9099/{out_dir}/report.html",
            "performance": {"title": name, "request_type": request_type, "metrics": {"max-capacity": rps}},
        }

        return ElasticSearch.call_elastic_search(metric)


import json
import ast
from keyPath import PATH as PATH

def get_Keys():
    with open(PATH) as f:
        data = json.load(f)
        parsed_data = ast.literal_eval(data)
        print("***SECRET***")
        #print(data)
        #print(parsed_data)
        NOTION_DATABASE_ID = parsed_data['NOTION_DATABASE_ID']
        NOTION_INTEGRATION_TOKEN = parsed_data["NOTION_INTEGRATION_TOKEN"]
        GOOGLE_TO_DO_DAILY_TASKLIST_ID= parsed_data["GOOGLE_TO_DO_DAILY_TASKLIST_ID"]
        return(parsed_data)
        #print(NOTION_DATABASE_ID)
        #print(NOTION_INTEGRATION_TOKEN)
        #print(GOOGLE_TO_DO_DAILY_TASKLIST_ID)

def set_Keys(dictionary_of_keys):
    keys_dict = dictionary_of_keys
    print(keys_dict)
    secret_keys_json = json.dumps(keys_dict)
    with open('secret_keys.json', 'w') as json_file:
        json.dump(secret_keys_json, json_file)

def convert_to_RFC_datetime(year=1900, month=1, day=1, hour=0, minute=0):
    dt = datetime.datetime(year, month, day, hour, minute, 0, 000).isoformat() + 'Z'
    return dt

#set_Keys({"NOTION_DATABASE_ID" : "", "NOTION_INTEGRATION_TOKEN" : "", "GOOGLE_TO_DO_DAILY_TASKLIST_ID" : ""})
#get_Keys()


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

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('core', '0008_auto_20150321_2108'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='country',
            options={'ordering': ['iso2'], 'verbose_name': 'Country', 'verbose_name_plural': 'Countries'},
        ),
        migrations.AlterModelOptions(
            name='grouping',
            options={'ordering': ['name'], 'verbose_name': 'Channel Group', 'verbose_name_plural': 'Channel Groups'},
        ),
        migrations.AlterModelOptions(
            name='language',
            options={'ordering': ['iso2'], 'verbose_name': 'Language', 'verbose_name_plural': 'Languages'},
        ),
        migrations.RenameField(
            model_name='channel',
            old_name='primary_language',
            new_name='language',
        ),
    ]


"""strategyidx added to Position

Revision ID: 2c9f80fe65fc
Revises: 63ef97eb1cee
Create Date: 2020-04-21 10:24:50.332582

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '2c9f80fe65fc'
down_revision = '63ef97eb1cee'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('position', sa.Column('strategyidx', sa.Integer(), nullable=True))
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('position', 'strategyidx')
    # ### end Alembic commands ###


from unittest.mock import sentinel

import pytest

from commando.core import commando

class TestCommando:
    def test_it(self):
        exit_status = commando(
            [sentinel.repo_1, sentinel.repo_2],
            ["test", "command"],
            sentinel.commit_message,
            sentinel.branch,
            sentinel.pr_title,
            sentinel.pr_body,
        )

        assert not exit_status

    @pytest.fixture(autouse=True)
    def subprocess(self, mocker):
        return mocker.patch("commando.core.subprocess", autospec=True)


import numpy as np
import matplotlib.pyplot as plt

#plt.show(block=True) close figure to continue code.
N=np.array([100,200,400])

for n in N:

        K = np.linspace(0,6,50)
        t = np.linspace(0,10,1000)

        x1 = np.zeros([n,len(t)])

        R = np.zeros(len(K))

        #omegas for n oscillators
        w = np.random.standard_cauchy(n)

        #initial condition for oscillators
        x1[:,0] = np.random.uniform(0,2*np.pi,n)
        h = t[3]-t[2]

        def r(x):
            r1 = np.absolute(np.sum(np.exp(x*1j)))/n
            w1 = np.angle(np.sum(np.exp(x*1j)))/n
            return r1,w1

        def f1(y):
                a,b=r(y)
                return w + (k*a)*np.sin(b-y)

        for j in range(len(K)):
            k = K[j]
            for i in range(len(t)-1):
                x = x1[:,i]
                k1 = h*f1(x)
                k2 = h*f1(x+k1/2.0)
                k3 = h*f1(x+k2/2.0)
                k4 = h*f1(x+k3)
                t[i+1] = t[i] + h
                x1[:,i+1] = x + ((1.0/6)*(k1+2*k2+2*k3+k4))

            a1,b1=r(x1[:,len(t)-30])
            R[j]=a1

        plt.scatter(K,R)
        plt.title('r v/s K for N='+str(n))
        plt.xlabel('K')
        plt.ylabel('|r|')
        plt.show()


import os
import json

from typing import List, Dict, Any

from pindex.core import Pindex
from pindex.duplicates import find_duplicates
from pindex.util import Printer, human_readable, concat

def index(config: Pindex) -> Dict[int, List[Dict[str, Any]]]:
    all_files = {}
    total_size = 0
    printer = Printer(1)
    for root, _, files in os.walk(config.root):
        relative_path = os.path.relpath(root, config.root)
        for name in files:
            printer.print(
                f"Processed {human_readable(total_size)}   \r", end="")
            entry = {
                "name": name,
                "path": relative_path
            }
            try:
                size = os.path.getsize(os.path.join(root, name))
                total_size += size
                entry["size"] = size
                if size not in all_files.keys():
                    all_files[size] = []
                all_files[size].append(entry)
            except (FileNotFoundError, PermissionError):
                pass
    printer.print_last()
    print(f"\n{len(concat(all_files.values()))} "
          "file(s) have been indexed successfully")
    return all_files

def walk(config: Pindex):
    all_files = index(config)
    if config.find_duplicates:
        find_duplicates(config, all_files.copy())

    all_files = concat(all_files.values())

    with open(config.save, "w") as f:
        f.write(json.dumps({
            "root": config.root,
            "files": all_files
        }, indent=2))


import os
import sys

import progressbar as pb

from vinfraclient import exceptions
from vinfraclient import utils
from vinfraclient.argtypes import parse_list_options
from vinfraclient.cmd import base

def _image_arg(parser):
    parser.add_argument(
        "image",
        metavar="<image>",
        help="Image ID or name"
    )

def _common_set_options(parser):
    parser.add_argument(
        "--min-disk",
        type=int,
        metavar="<size-gb>",
        help=" Minimum disk size required to boot from image, in gigabytes"
    )
    parser.add_argument(
        "--min-ram",
        type=int,
        metavar="<size-mb>",
        help="Minimum RAM size required to boot from image, in megabytes"
    )
    parser.add_argument(
        "--os-distro",
        metavar="<os-distro>",
        help="OS distribution. To list available distributions, "
             "run 'vinfra service compute show'."
    )
    parser.add_argument(
        "--protected",
        dest="protected",
        action="store_true",
        default=None,
        help="Protect image from deletion."
    )
    parser.add_argument(
        "--unprotected",
        dest="protected",
        action="store_false",
        default=None,
        help="Allow image to be deleted.",
    )
    parser.add_argument(
        "--public",
        dest="visibility",
        action="store_const",
        const="public",
        default=None,
        help="Make image accessible to all users."
    )
    parser.add_argument(
        "--private",
        dest="visibility",
        action="store_const",
        const="shared",
        default=None,
        help="Make image accessible only to the owners."
    )

class ListImage(base.Lister):
    _description = "List compute images."
    _default_fields = ['id', 'name', 'size', 'status', 'disk_format']
    _sort_keys = ['id', 'name', 'status', 'created_at', 'updated_at'
                  'size', 'disk_format']

    def configure_parser(self, parser):
        parser.add_argument(
            '--limit',
            metavar='<num>',
            type=int,
            help='The maximum number of images to list. To list all images, '
                 'set the option to -1.'
        )
        parser.add_argument(
            '--marker',
            metavar='<image>',
            help='List images after the marker.'
        )
        parser.add_argument(
            '--name',
            metavar='<name>',
            action='filter',
            operators='contains',
            help='List images with the specified name or use a filter.'
        )
        parser.add_argument(
            '--id',
            metavar='<id>',
            action='filter',
            operators='in',
            help='Show an image with the specified ID or list images using '
                 'a filter.'
        )
        parser.add_argument(
            '--status',
            metavar='<status>',
            action='filter',
            operators='in',
            help='List images with the specified status or use a filter.'
        )
        parser.add_argument(
            '--placement',
            metavar='<placement>',
            action='filter',
            operators='any',
            help='List images added to a placement with the specified ID or '
                 'use a filter'
        )
        parser.add_argument(
            '--disk-format',
            metavar='<disk-format>',
            help='List images with the specified disk format.'
        )
        parser.add_argument(
            '--project',
            metavar='<project>',
            action='filter',
            operators='in',
            help='List images that belong to projects with the specified names or IDs. '
                 'Can only be performed by system administrators. '
                 'Specify multiple project IDs as a comma-separated list.'
        )
        parser.add_argument(
            "--domain",
            metavar="<domain>",
            help='List images that belong to a domain with the specified name or ID. '
                 'Can only be performed by system administrators.'
        )
        parser.add_argument(
            '--sort',
            metavar='<sort>',
            help="List images sorted by key.\n"
                 "The sorting format is <sort-key>:<order>. The order is 'asc' or 'desc'.\n"
                 "Supported sort keys: {}".format(', '.join(self._sort_keys))
        )

    def do_action(self, parsed_args):
        filters = {}
        if parsed_args.name:
            filters['name'] = parsed_args.name
        if parsed_args.id:
            filters['id'] = parsed_args.id
        if parsed_args.status:
            filters['status'] = parsed_args.status
        if parsed_args.placement:
            filters['traits'] = parsed_args.placement
        if parsed_args.disk_format:
            filters['disk_format'] = parsed_args.disk_format
        if parsed_args.project:
            manager = self.app.vinfra.compute.projects
            filters['project_id'] = utils.validate_resources_from_operator(
                manager, parsed_args.project)
        if parsed_args.domain:
            domain = utils.find_resource(self.app.vinfra.domains, parsed_args.domain)
            filters['domain_id'] = domain.id
        if parsed_args.sort:
            filters['sort'] = parsed_args.sort

        data = self.app.vinfra.compute.images.list(
            limit=parsed_args.limit, marker=parsed_args.marker,
            filters=filters)
        return data

class ShowImage(base.ShowOne):
    _description = "Display compute image details."

    def configure_parser(self, parser):
        _image_arg(parser)

    def do_action(self, parsed_args):
        image = utils.find_resource(self.app.vinfra.compute.images,
                                    parsed_args.image)
        return image

class CreateImage(base.TaskCommand):
    _description = "Create a new compute image."

    def configure_parser(self, parser):
        _common_set_options(parser)

        disk_formats = ['aki', 'ami', 'ari', 'detect', 'iso', 'ploop',
                        'qcow2', 'raw', 'vdi', 'vhd', 'vhdx', 'vmdk']
        container_formats = [
            'aki', 'ami', 'ari', 'bare', 'docker', 'ovf', 'ova']

        parser.add_argument(
            "--disk-format",
            type=str,
            metavar="<disk_format>",
            default="detect",
            choices=disk_formats,
            help="Disk format {} (default: detect)".format(
                ','.join(disk_formats)
            )
        )
        parser.add_argument(
            "--container-format",
            type=str,
            metavar="<format>",
            default="bare",
            choices=container_formats,
            help="Container format: {} (default: bare)".format(
                ','.join(container_formats)
            )
        )
        parser.add_argument(
            "--tags",
            metavar="<tags>",
            type=parse_list_options,
            help="A comma-separated list of tags"
        )
        parser.add_argument(
            "name",
            metavar="<image-name>",
            help="Image name"
        )
        parser.add_argument(
            "--verify",
            action='store_true',
            help="Verify the checksum of the uploaded image"
        )
        parser.add_argument(
            "--file",
            metavar="<file>",
            required=True,
            help="Create image from a local file"
        )
        parser.add_argument(
            "--uefi",
            metavar="<uefi>",
            dest='hw_firmware_type',
            action='store_const',
            const='uefi',
            default=None,
            help="Create image with UEFI."
        )

    def do_action(self, parsed_args):
        def image_create(stream, args):
            return self.app.vinfra.compute.images.create_async(
                stream, args.name, args.disk_format, args.container_format,
                min_disk=args.min_disk, min_ram=args.min_ram,
                os_distro=args.os_distro, protected=args.protected,
                visibility=args.visibility, tags=args.tags,
                verify=args.verify,
                hw_firmware_type=args.hw_firmware_type,
            )

        if parsed_args.verify and not parsed_args.wait:
            raise exceptions.ValidationError(
                'The --verify option must be used together with the --wait option')

        if parsed_args.hw_firmware_type and parsed_args.file.endswith('.iso'):
            raise exceptions.ValidationError(
                "UEFI option cannot be used with ISO images."
            )

        # NOTE(akurbatov): request to upload image can get unauthorized
        # response. Client can then try to reauth in background and repeat
        # request. But stream offset must be then reset. Make sure user
        # passed correct login and password to not complicate logic by simple
        # backend API call:
        self.app.vinfra.get_meta()

        try:
            stream = open(parsed_args.file, mode='rb')
        except Exception as err:
            raise exceptions.ValidationError(
                'Failed to open {} ({})'.format(parsed_args.file, err))

        if (
                parsed_args.formatter != 'table'
                or not self.app.stderr.isatty()
        ):
            return image_create(stream, parsed_args)

        pattern = 'Uploading image to server [elapsed time: %s]... '
        widgets = [pb.Timer(format=pattern), pb.AnimatedMarker()]
        pbar = pb.ProgressBar(maxval=80, term_width=80, widgets=widgets,
                              fd=self.app.stderr)
        with utils.progress_bar_context(self.app, pbar):
            return image_create(stream, parsed_args)

class DeleteImage(base.Command):
    _description = "Delete a compute image."

    def configure_parser(self, parser):
        _image_arg(parser)

    def do_action(self, parsed_args):
        image = utils.find_resource(self.app.vinfra.compute.images,
                                    parsed_args.image)
        return image.delete()

class SetImage(base.ShowOne):
    _description = "Modify compute image parameters."

    def configure_parser(self, parser):
        _common_set_options(parser)
        parser.add_argument(
            "--name",
            metavar="<name>",
            help="Image name"
        )
        _image_arg(parser)

    def do_action(self, parsed_args):
        image = utils.find_resource(self.app.vinfra.compute.images,
                                    parsed_args.image)
        return image.update(
            name=parsed_args.name, min_disk=parsed_args.min_disk,
            min_ram=parsed_args.min_ram, os_distro=parsed_args.os_distro,
            protected=parsed_args.protected, visibility=parsed_args.visibility)

class SaveImage(base.Command):
    _description = "Download a compute image."

    def configure_parser(self, parser):
        parser.add_argument(
            "--file",
            metavar="<filename>",
            help="File to save the image to (default: stdout)"
        )
        _image_arg(parser)

    def do_action(self, parsed_args):
        image = utils.find_resource(self.app.vinfra.compute.images,
                                    parsed_args.image)
        fdst = None
        if not parsed_args.file:
            fdst = sys.stdout
        else:
            if os.path.exists(parsed_args.file):
                raise exceptions.ValidationError(
                    'File "{}" exists'.format(parsed_args.file))
            fdst = open(parsed_args.file, 'wb')

        image.download(fdst)


import requests
import json

#url = "https://reports.sem-o.com/api/v1/documents/static-reports"
url= "https://reports.sem-o.com/api/v1/documents/static-reports?ReportName=Balancing%20and%20Imbalance%20Market%20Cost%20View&Date=>2019-11-10"
response = requests.get(url)
data = response.json()

listOfReports = []
#output to console
#print (data)
for item in data["items"]:
    #print(item["ResourceName"])
    listOfReports.append(item["ResourceName"])

for ReportName in listOfReports:
    #print(ReportName)
    url ="https://reports.sem-o.com/api/v1/documents/"+ReportName
    print(url)
    response= requests.get(url)
    aReport= response.json()

#other code
#save this to a file
filename = 'allreports.json'
# Writing JSON data
f =  open(filename, 'w')
json.dump(data, f, indent=4)


from torch.utils.data import DataLoader
from sentence_transformers import SentenceTransformer

from transformers import AutoTokenizer, AutoModel
import torch
import warnings
warnings.filterwarnings('ignore')

def expand_label(labels,sentences):
  new_labels = [0 for i in range(len(sentences))]
  for i in labels:
    new_labels[i] = 1
  return new_labels

class BERT_BASE_ENCODER:
    def __init__(self, model="bert-base-uncased", pooling="average"):
            self.bert = AutoModel.from_pretrained(model)
            self.pool=self.cls_pooling if pooling=="cls" else self.avg_pooling
            self.tokenizer = AutoTokenizer.from_pretrained(model)
            self.model = 'bert_cls_token'
            self.max_length = 512
            if torch.cuda.is_available():
                self.device = 'cuda'
                self.bert.to('cuda')
                print('Moved BERT to gpu!')
            else:
                print('No gpu is being used')
                self.device = 'cpu'

    def cls_pooling(self, model_output, attention_mask):
      return model_output[0][:,0]

    def avg_pooling(self, model_output, attention_mask):
      input_mask_expanded = attention_mask.unsqueeze(-1).expand(model_output[-1].size()).float()
      sum_embeddings = torch.sum(model_output[-1] * input_mask_expanded, 1)

      sum_mask = input_mask_expanded.sum(1)

      sum_mask = torch.clamp(sum_mask, min=1e-9)

      return sum_embeddings / sum_mask

    def encode(self, sentences, convert_to_tensor=False, batch_size=32):

        all_embeddings = []

        length_sorted_idx = np.argsort([-len(sen.split()) for sen in sentences])

        sentences_sorted = [sentences[idx] for idx in length_sorted_idx]

        for start_index in range(0, len(sentences), batch_size):

            sentences_batch = sentences_sorted[start_index:start_index + batch_size]

            encoded_input = self.tokenizer(sentences_batch, padding=True, truncation=True, return_tensors='pt',
                                           max_length=self.max_length)

            with torch.no_grad():

                if encoded_input['input_ids'].shape[0] > 100:
                    pass

                try:
                    model_output = self.bert(input_ids=encoded_input['input_ids'].to(self.device),
                                         attention_mask=encoded_input['attention_mask'].to(self.device),
                                         output_hidden_states=True).hidden_states
                except RuntimeError:
                    self.bert.to(self.device)
                    model_output = self.bert(input_ids=encoded_input['input_ids'].to(self.device),
                                             attention_mask=encoded_input['attention_mask'].to(self.device),
                                             output_hidden_states=True).hidden_states

                model_output = self.pool(model_output,
                                         encoded_input['attention_mask'].to(self.device)).detach().cpu()

                all_embeddings.extend(model_output)

        all_embeddings = [all_embeddings[idx] for idx in np.argsort(length_sorted_idx)]

        if convert_to_tensor:
            return torch.stack(all_embeddings)
        else:
            return np.asarray([emb.numpy() for emb in all_embeddings])

    def get_sentence_embedding_dimension(self):
        return 768

class ST_ENCODER:
  def __init__(self, model = "all-mpnet-base-v2"):
    self.model = SentenceTransformer(model)
  def encode(self, sentences, convert_to_tensor = False):
    if convert_to_tensor:
      return self.model.encode(sentences, pt=True)
    else:
      return self.model.encode(sentences)

  def get_sentence_embedding_dimension(self):
    return 768


import logging
import requests
from jinx.base import _JinxBase
from jinx.exceptions import JinxSymbolError

log = logging.getLogger(__name__)

class Stock(_JinxBase):
    """Base class for obtaining data abouot a stock from IEX.

    Attributes
    ----------
    symbol: str
        Ticker symbol
    """

    def __init__(self, symbol=None, **kwargs):
        super(Stock, self).__init__(**kwargs)
        if isinstance(symbol, str):
            self.symbol =symbol
        else:
            raise JinxSymbolError("Please input a symbol.")
        self.symbol = symbol

    def get_company(self):
        """Gets company data about the stock.

        Reference: https://iexcloud.io/docs/api/#company

        Data Weighting: ``1`` per symbol

        Returns
        -------
        dict
            Company data
        """
        path = "/stock/{}/company".format(self.symbol)
        params = {}
        return self._execute_iex_json_request(path=path, params=params)

    def get_cash_flow(self, period='quarter', last=1):
        """Pulls cash flow data. Available quarterly or annually.

        Reference: https://iexcloud.io/docs/api/#cash-flow

        Data Weighting: ``1000`` per symbol per period

        Parameters
        ----------
        period: str, default ``quarter``, optional
            Allows you to specify annual or quarterly cash flows. Defaults to
            quarterly. Values should be ``annual`` or ``quarter``.

        last: int, default ``1``, optional
            Specify the number of quarters or years to return.
            One quarter is returned by default. You can specify up to 12
            quarters with ``quarter``, or up to 4 years with ``annual``.

        Returns
        ------
        dict
            Stocks Cash Flow endpoint data
        """
        path = "/stock/{}/cash-flow".format(self.symbol)
        params = {'period':period, 'last':last}
        return self._execute_iex_json_request(path=path, params=params)

    def get_balance_sheet(self, period='quarter', last=1):
        """Pulls balance sheet data. Available quarterly or annually.

        Reference: https://iexcloud.io/docs/api/#balance-sheet

        Data Weighting: ``3000`` per symbol per period

        Parameters
        ----------
        period: str, default ``quarter``, optional
            Allows you to specify annual or quarterly cash flows. Defaults to
            quarterly. Values should be ``annual`` or ``quarter``.

        last: int, default ``1``, optional
            Specify the number of quarters or years to return.
            One quarter is returned by default. You can specify up to 12
            quarters with ``quarter``, or up to 4 years with ``annual``.

        Returns
        ------
        dict
            Stocks Balance Sheet endpoint data
        """
        path = "/stock/{}/balance-sheet".format(self.symbol)
        params = {'period':period, 'last':last}
        return self._execute_iex_json_request(path=path, params=params)

    def get_income_statement(self, period='quarter', last=1):
        """Pulls income statement data. Available quarterly or annually.

        Reference: https://iexcloud.io/docs/api/#income-statement

        Data Weighting: ``1000`` per symbol per period

        Parameters
        ----------
        period: str, default ``quarter``, optional
            Allows you to specify annual or quarterly cash flows. Defaults to
            quarterly. Values should be annual or quarter.

        last: int, default ``1``, optional
            Specify the number of quarters or years to return.
            One quarter is returned by default. You can specify up to 12
            quarters with ``quarter``, or up to 4 years with ``annual``.

        Returns
        ------
        dict
            Stocks Income Statement endpoint data
        """
        path = "/stock/{}/income".format(self.symbol)
        params = {'period':period, 'last':last}
        return self._execute_iex_json_request(path=path, params=params)

    def get_latest_financial_report_date(self):
        """Gets report date of latest financial report using data points.

        Reference: https://iexcloud.io/docs/api/#data-points

        Data Weighting: ``1``

        Returns
        ------
        dict
            Dictionary with one key: ``latestFinancialReportDate``
        """

        path = "/data-points/{}/LATEST-FINANCIAL-REPORT-DATE".format(
            self.symbol)
        params = {}

        text = self._execute_iex_text_request(path=path, params=params)
        stripped_text = text.replace('"',"")
        result_dict = {'latestFinancialReportDate':stripped_text}
        return result_dict


import numpy as np
import matplotlib.pyplot as plt

def rectanglemethod(func, a, b):
    x = np.linspace(a, b, 20)
    y = func(x)
    plt.plot(x, y, "bo-")

    integrale = 0
    for i in range(19):
        integrale = integrale + y[i]*(x[i+1]-x[i])
        x_rect = [x[i], x[i], x[i+1], x[i+1], x[i]]
        y_rect = [0   , y[i], y[i]  , 0     , 0   ]
        plt.plot(x_rect, y_rect,"r")
    print("integrale = ", integrale)

    plt.show()

func = lambda x:np.cos(x)
xmin = 0
xmax = 3*np.pi/2
rectanglemethod(func, xmin, xmax)


from sklearn import datasets,svm
import matplotlib.pyplot as plt

d=datasets.load_iris()
print(d.DESCR)

for i in range(0,len(d.data)):
    print(i+1, d.data[i],d.target[i])

s=svm.SVC(gamma=0.1,C=10)
s.fit(d.data,d.target)

new_d=[[6.4,3.2,6.0,2.5],[7.1,3.1,4.7,1.35]]

res=s.predict(new_d)
print("새로운 2개 샘플의 부류는",res)


import os
import argparse
import numpy as np
import pandas as pd
from sklearn.model_selection import StratifiedKFold

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Arguments')
    parser.add_argument('--data_csv_path', type=str,
                        help='path to the csv file containing the cell expression data of all cases along with their labels')
    parser.add_argument('--output_dir', type=str, help='directory to processed data files')

    args = parser.parse_args()
    os.makedirs(args.output_dir, exist_ok=True)

    # data should be downloaded from the link given in the paper.
    data = pd.read_csv(os.path.join(args.data_csv_path))

    # Merge Cytotoxic CD8 cells to CD8 cells
    data.loc[data['Annotation'] == 'Cytotoxic CD8', 'Annotation'] = 'CD8'
    data.reset_index(inplace=True)

    # Extracting and Saving Marker Names from the data CSV File
    non_marker_cols = ['patientID', 'centroidX', 'centroidY', 'cellLabel', 'cellSize', 'Annotation', 'pointNum',
                       'tissue_block', 'region', 'index']
    marker_names = [col_name for col_name in data.columns.tolist() if col_name not in non_marker_cols]
    marker_names.sort()
    marker_df = pd.DataFrame(marker_names, columns=['marker_name'])
    marker_df.to_csv(os.path.join(args.output_dir, 'marker_names.csv'), index=False)

    # Creating Class ID and Name Mapping for Unique Classes in a Dataset

    class_dict = {'class_id': [], 'class_name': [], 'sample_count': []}
    class_mapping = {}
    for i, class_name in enumerate(np.unique(data['Annotation'].tolist())):
        class_dict['class_id'].append(i)
        class_dict['class_name'].append(class_name)
        class_dict['sample_count'].append(np.sum(data['Annotation'] == class_name))
        class_mapping[class_name] = i
    pd.DataFrame(class_dict).to_csv(os.path.join(args.output_dir, 'class_names.csv'), index=False)

    # Count number cells per patient per class
    class_names = np.unique(data['Annotation']).tolist()
    case_names = np.unique(data['patientID']).tolist()
    case_names = [case_name for case_name in case_names if 'ctrl' not in case_name]
    df = pd.DataFrame(np.zeros((len(case_names), len(class_names))), columns=class_names, index=case_names)
    for case_name, row in df.iterrows():
        for class_name in class_names:
            temp_df = data[data['patientID'] == case_name]
            temp_df = temp_df[temp_df['Annotation'] == class_name]
            df.loc[case_name, class_name] = temp_df.shape[0]
    df['Total'] = np.sum(df.to_numpy(), axis=1)
    df.to_csv(os.path.join(args.output_dir, 'class_count.csv'))

    # Assigning fold id to each patient based on number of cells
    df = df.sort_values(['Total'])
    case_to_fold_mapping = {'case_name': df.index.tolist(), 'fold_id': [-1] * df.shape[0]}

    i, j = 0, df.shape[0] - 1
    fid = 0
    fold_count = 5
    cell_per_class = df.to_numpy()
    cell_per_fold = np.zeros((fold_count, df.shape[1]))
    while i < j:
        case_to_fold_mapping['fold_id'][i] = fid % fold_count
        case_to_fold_mapping['fold_id'][j] = fid % fold_count
        cell_per_fold[fid % fold_count, :] += cell_per_class[i, :] + cell_per_class[j, :]
        fid += 1
        i += 1
        j -= 1
    cell_per_fold = pd.DataFrame(cell_per_fold, columns=df.columns)
    cell_per_fold.to_csv(os.path.join(args.output_dir, 'cell_count_per_fold.csv'))
    case_to_fold_mapping = pd.DataFrame(case_to_fold_mapping)
    case_to_fold_mapping.to_csv(os.path.join(args.output_dir, 'case_to_fold_mapping.csv'))

    # Generating training and validation splits using fold information
    features_cols = []
    features_cols.extend(marker_names)
    features_cols.append('cellSize')
    features_cols.append('patientID')
    features = data[features_cols]
    labels = np.array([class_mapping[class_name] for class_name in data['Annotation'].tolist()])
    features['cell_label'] = labels

    for i in range(fold_count):
        train_patient_list = case_to_fold_mapping[case_to_fold_mapping['fold_id'] != i]['case_name'].tolist()
        test_patient_list = case_to_fold_mapping[case_to_fold_mapping['fold_id'] == i]['case_name'].tolist()

        train_split = features[features['patientID'].isin(train_patient_list)]
        test_split = features[features['patientID'].isin(test_patient_list)]
        train_split = train_split.drop(columns=['patientID'])
        test_split = test_split.drop(columns=['patientID'])

        print(i, train_split.shape, test_split.shape)

        os.makedirs(os.path.join(args.output_dir, 'splits', 'fold_%d' % i), exist_ok=True)
        train_split.to_csv(os.path.join(args.output_dir, 'splits', 'fold_%d' % i, 'train.csv'), index=False)
        test_split.to_csv(os.path.join(args.output_dir, 'splits', 'fold_%d' % i, 'test.csv'), index=False)

    # Generating training, validation and test splits using fold information
    for fid in range(5):
        os.makedirs(os.path.join(args.output_dir, 'splits', f"fold_{fid}"), exist_ok=True)
        train_csv = pd.read_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'train.csv'))
        features = train_csv.to_numpy()[:, :-1]
        labels = train_csv.to_numpy()[:, -1]
        skf = StratifiedKFold(n_splits=5, random_state=7325111, shuffle=True)
        for i, (train_index, valid_index) in enumerate(skf.split(features, labels)):
            train = train_csv.iloc[train_index]
            valid = train_csv.iloc[valid_index]
            print(f"Fold {fid}: {train.shape[0]}, {valid.shape[0]}")
            train.to_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'train.csv'), index=False)
            valid.to_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'valid.csv'), index=False)
            break

    # Generating subset of training sets in each fold for training the model with different number of training samples
    for fid in range(5):
        train_csv = pd.read_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'train.csv'))
        valid_csv = pd.read_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'valid.csv'))
        test_csv = pd.read_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'test.csv'))
        features = train_csv.to_numpy()[:, :-1]
        labels = train_csv.to_numpy()[:, -1]
        train_index = []
        skf = StratifiedKFold(n_splits=20, random_state=7325111, shuffle=True)
        for i, (_, train_index_) in enumerate(skf.split(features, labels)):
            train_index.extend(train_index_)
            if i in [0, 1, 4, 9, 14]:
                train = train_csv.iloc[train_index]
                print(
                    f"Fold {fid}: {(i + 1) * 5}%: {len(train_index) / features.shape[0]}, {train.shape[0] / features.shape[0]}")
                os.makedirs(os.path.join(args.output_dir, 'splits_%02d' % ((i + 1) * 5), f"fold_{fid}"), exist_ok=True)
                train.to_csv(os.path.join(args.output_dir, 'splits_%02d' % ((i + 1) * 5), f"fold_{fid}", 'train.csv'), index=False)
                valid_csv.to_csv(os.path.join(args.output_dir, 'splits_%02d' % ((i + 1) * 5), f"fold_{fid}", 'valid.csv'), index=False)
                test_csv.to_csv(os.path.join(args.output_dir, 'splits_%02d' % ((i + 1) * 5), f"fold_{fid}", 'test.csv'), index=False)

    # Generating train and valid sets with subset markers and classes
    selected_cols = ["CD11c", "CD163", "CD20", "CD4", "CD56", "CD68", "CD8", "CD3", "Pax-5", "cellSize", 'cell_label']

    pd.DataFrame(selected_cols, columns=['col_names']).to_csv(os.path.join(args.output_dir, 'selected_cols.csv'), index=False)
    selected_classes = ["CD4", "CD8", "DC", "M1", "M2", "NK", "Tumor", "B"]
    selected_labels = [class_mapping[class_name] for class_name in selected_classes]
    selected_labels_mapping = {class_mapping[class_name]: i for i, class_name in enumerate(selected_classes)}
    print(selected_labels_mapping)
    selected_labels_mapping[class_mapping['B']] = selected_classes.index('Tumor')
    print(selected_labels_mapping)
    class_dict = {'class_id': [], 'class_name': []}
    class_mapping = {}
    for i, class_name in enumerate(selected_classes):
        if class_name == 'B':
            continue
        class_dict['class_id'].append(i)
        class_dict['class_name'].append(class_name)
        class_mapping[class_name] = i
    pd.DataFrame(class_dict).to_csv(os.path.join(args.output_dir, 'selected_class_names.csv'), index=False)

    for fid in range(5):
        train = pd.read_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'train.csv'))
        valid = pd.read_csv(os.path.join(args.output_dir, 'splits', f"fold_{fid}", 'valid.csv'))

        train = train[selected_cols]
        valid = valid[selected_cols]

        train = train[train['cell_label'].isin(selected_labels)]
        valid = valid[valid['cell_label'].isin(selected_labels)]

        train['cell_label'] = train['cell_label'].map(selected_labels_mapping)
        valid['cell_label'] = valid['cell_label'].map(selected_labels_mapping)

        os.makedirs(os.path.join(args.output_dir, 'splits_marker_subset', f"fold_{fid}"), exist_ok=True)
        train.to_csv(os.path.join(args.output_dir, 'splits_marker_subset', f"fold_{fid}", 'train.csv'), index=False)
        valid.to_csv(os.path.join(args.output_dir, 'splits_marker_subset', f"fold_{fid}", 'valid.csv'), index=False)


import io
from logging import Logger
from typing import Dict
from dotenv import Any
from fastapi.datastructures import UploadFile
from fastapi.params import Depends, File, Query
from fastapi.responses import StreamingResponse
from fastapi.routing import APIRoute, APIRouter

''' APP level imports '''
from .QRGenerator import QRGenerator
from .services import QRGeneratorService
from .models import FileObject

def QRApp(log:Logger) -> APIRouter:

    router = APIRouter(
        prefix= "/qrcode",
        tags = ["QR Generator"]
    )

    @router.get("/", name="App Details", include_in_schema=False)
    async def Init():
        return {"QRGenerator":True}

    @router.get("/generate", responses= {
                200:{"content":{"image/png":{}}}
            },
            name="QR code Generator")
    async def q_r_code_generator(data:str= Query(..., max_length=150),
                                service:QRGenerator = Depends(QRGeneratorService)):
        '''
        Takes input as text and convert them into a QRcode png image
        '''
        log.debug(f"QR Code Generator: {data}")
        image_bytes = await service.generate(data)

        return StreamingResponse(io.BytesIO(image_bytes), status_code=200, media_type="image/png")

    @router.post("/file-details", name="Get File Details")
    async def image_echo(file:UploadFile= File(...)):

        file_name:str = file.filename
        file_size:str = str(file.spool_max_size)+" bytes"
        file_type:str = file.content_type

        return FileObject(name = file_name, size=file_size, content_type=file_type)

    @router.post("/logo-qrcode", name="Get QrCode having logo",
                responses={
                    200:{"content":{"image/png":{} }},
                    400:{"content":{"application/json":{}}}
                    })
    async def qrcode_logoed(file:UploadFile = File(...),
                            data:str=Query(..., max_length=150),
                            service:QRGenerator = Depends(QRGeneratorService)) -> StreamingResponse:

        if file.content_type not in ["image/png", "image/jpeg", "image/jpg"]:
            raise ValueError(f"File type: {file.content_type} not allowed")

        response = await file.read()
        serviceResponse = await service.generate_with_logo(data,response)
        return StreamingResponse(io.BytesIO(serviceResponse), status_code=200, media_type="image/png")

    return router


# -*- coding: utf-8 -*-
import csv
import imp
from importlib.metadata import requires
from django.http import HttpResponse

from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
import pandas as pd
from django.utils.html import strip_tags
from django.contrib import messages
from io import BytesIO as IO
from django.conf import settings
from django.contrib import admin
from django.contrib.auth import get_permission_codename
from django.contrib.auth.models import User, Permission
from django.contrib.contenttypes.models import ContentType
from .utility import *

from .models import Supplier
from .supportmodels import SupplierChannel

class ExportCsvMixin:
    def export_as_csv(self, request, queryset):
        meta = self.model._meta
        field_names = [field.name for field in meta.fields]

        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
        writer = csv.writer(response)

        writer.writerow(field_names)
        for obj in queryset:
            data = [getattr(obj, field) for field in field_names]
            print('Data')
            print(data)
            row = writer.writerow(data)
            print('Row')
            print(row)

        return response

    export_as_csv.short_description = "Export Selected"

    @admin.action(permissions=['export'], description='Export selected rows to excel',)
    def export_as_xls(self, request, queryset):
        """
        Generic xls export admin action.
        """
        limit = -1
        if request.user.has_perm("Supplier.export_excel_1000_admin"):
            limit = 1000#settings.EXPORT_RECORDS_ADMIN_LIMIT
        elif request.user.has_perm("Supplier.export_excel_100_buyer"):
            limit = 100
        elif request.user.has_perm("Supplier.export_excel_50_seller"):
            limit = 50
        else:
            messages.error(request, "This action is only for staff of brandc" )
            return HttpResponseRedirect(request.path_info)

        if limit > 0 and queryset.count() > limit:
            messages.error(request, "Can't export more then %s Records in one go." % str(limit))
            return HttpResponseRedirect(request.path_info)

        data = []
        for obj in queryset:
            data.append(obj.parse_to_json())

        excel_file = IO()
        xlwriter = pd.ExcelWriter(excel_file, engine='xlsxwriter')
        df = pd.DataFrame(data)
        df.to_excel(xlwriter, "Summary", index=False)

        # Get the xlsxwriter workbook and worksheet objects.
        workbook  = xlwriter.book
        worksheet = xlwriter.sheets['Summary']

        # Set a currency number format for a column.
        num_format = workbook.add_format({'num_format': '#,###'})
        for column in df:
            column_length = max(df[column].astype(str).map(len).max(), len(column))
            col_idx = df.columns.get_loc(column)
            #print('col_idx')
            #print(col_idx)
            worksheet.set_column(col_idx, col_idx, column_length)

        worksheet.set_column('J:J', 15)
        worksheet.set_column('M:M', 15, num_format)
        worksheet.set_column('N:N', 15, num_format)
        worksheet.set_column('O:O', 15, num_format)
        worksheet.set_column('P:P', 15, num_format)

        xlwriter.save()
        xlwriter.close()

        excel_file.seek(0)
        response = HttpResponse(excel_file.read(),
                                content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')

        response['Content-Disposition'] = 'attachment; filename="excel_file.xlsx"'
        return response

    export_as_xls.short_description = "Export selected to EXCEL"

    def has_export_permission(self, request):
        """Does the user have the export excel permission?"""
        #opts = self.opts
        #codename = get_permission_codename('export', opts)
        has_perm = request.user.has_perm('Supplier.export_excel_50_seller') | request.user.has_perm('Supplier.export_excel_100_buyer') | request.user.has_perm('Supplier.export_excel_1000_admin')
        return has_perm

    @admin.action(permissions=['syncfollower'], description='Sync follower number',)
    def sync_follower(self, request, queryset):
        limit = 4
        if limit > 0 and queryset.count() > limit:
            messages.error(request, "Can't sync more than %s Records in one go." % str(limit))
            return HttpResponseRedirect(request.path_info)
        shouldSetupFb = queryset.filter(channel=SupplierChannel.FB_PERSONAL).count() > 0
        driver = prepare_driver(shouldSetupFb)
        for obj in queryset:
            result = -1
            if support_sync(obj.channel):
                result = read_followers(driver, obj)
                if result > 0:
                    old_follower = obj.follower
                    obj.follower = convert_to_string_number(result)
                    try:
                        obj.save()
                        messages.info(request, obj.name + " was update follower number from " + old_follower + " to " +  str(obj.follower))
                    except Exception as e:
                        messages.warning(request, obj.name + " can not update follower number, let try manual for this record, the error is " + str(e))
                else:
                    messages.warning(request, obj.name + " can not update follower number, let try manual for this record")
            else:
                messages.warning(request, obj.name + " is not supported this feature")
        if driver:
            try:
                close_driver(driver)
                driver = None
            except:
                pass

        return HttpResponseRedirect(request.path_info)

    def has_syncfollower_permission(self, request):
        """Does the user have the sync follower permission?"""
        has_perm = request.user.has_perm('Supplier.sync_follower')
        return has_perm


from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.views import generic

from groups.forms import PostCreateForm, CommentCreateForm, GroupCreateForm
from .models import Group, GroupMember, Post, Comment

class GroupListView(LoginRequiredMixin, generic.ListView):
    model = Group

class GroupIndexView(LoginRequiredMixin, generic.DetailView):
    template_name = 'groups/group_main_page.html'
    form_class = PostCreateForm
    context_object_name = 'group'

    def get_queryset(self):
        return Group.objects.all()

    def get_context_data(self, **kwargs):
        context = super(GroupIndexView, self).get_context_data(**kwargs)
        return context

    def post(self, request,  *args, **kwargs):
        form = self.form_class(request.POST or None)

        if form.is_valid():
            title = form.cleaned_data['title']
            text = form.cleaned_data['text']
            group = Group.objects.filter(slug=self.kwargs.get('slug')).get()
            author = request.user

            post = Post(title=title, text=text, group=group, author=author)
            post.save()

            return HttpResponseRedirect(reverse("groups:post_details", kwargs={'pk': post.id}))
        else:
            return render(request, self.template_name, {'form': form})

class PostView(LoginRequiredMixin, generic.TemplateView):
    template_name = 'groups/post_detail.html'
    form_class = CommentCreateForm
    context_object_name = 'post'

    def get_context_data(self, **kwargs):
        context = super(PostView, self).get_context_data(**kwargs)
        context['post'] = Post.objects.filter(pk=self.kwargs.get('pk')).get()
        return context

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST or None)

        if form.is_valid():
            text = form.cleaned_data['text']
            post = Post.objects.filter(id=self.kwargs.get('pk')).get()
            author = request.user

            comment = Comment(text=text, post=post, author=author)
            comment.save()

            return HttpResponseRedirect(reverse('groups:post_details', kwargs={'pk': self.kwargs.get('pk')}))
        else:
            return render(request, self.template_name, {'form': form})

class CreateGroupView(LoginRequiredMixin, generic.View):
    template_name = 'groups/group_create_form.html'
    form_class = GroupCreateForm

    def get(self, request):
        form = self.form_class(None)
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST or None)

        if form.is_valid():
            name = form.cleaned_data['name']
            description = form.cleaned_data['description']

            group = Group(name=name, description=description)
            group.save()

            return HttpResponseRedirect(reverse('groups:join_group', kwargs={'slug': group.slug}))
        else:
            return render(request, self.template_name, {'form': form})

class JoinGroupView(LoginRequiredMixin, generic.RedirectView):

    def get_redirect_url(self, *args, **kwargs):
        return reverse('groups:index', kwargs={'slug': self.kwargs.get('slug')})

    def get(self, request, *args, **kwargs):
        group = get_object_or_404(Group, slug=self.kwargs.get('slug'))

        try:
            GroupMember.objects.create(user=self.request.user, group=group)

        except IntegrityError:
            messages.warning(
                self.request,
                "Warning, already a member of {}".format(group.name)
            )

        else:
            messages.success(
                self.request,
                "You are now a member of the {} group.".format(group.name)
            )

        return super().get(request, *args, **kwargs)

class LeaveGroupView(LoginRequiredMixin, generic.RedirectView):

    def get_redirect_url(self, *args, **kwargs):
        return reverse('groups:index', kwargs={'slug': self.kwargs.get('slug')})

    def get(self, request, *args, **kwargs):

        try:
            membership = GroupMember.objects.filter(
                user=self.request.user,
                group__slug=self.kwargs.get('slug')
            ).get()

        except GroupMember.DoesNotExist:
            messages.warning(
                self.request,
                "You can't leave this group because you aren't in it."
            )
        else:
            membership.delete()
            messages.success(
                self.request,
                "You have successfully left this group."
            )
        return super().get(request, *args, **kwargs)


import requests
import re
from bs4 import BeautifulSoup

url = 'https://www.ptt.cc/bbs/movie/index.html'
resultDICT = {'好評':0, '普通':0, '負評':0}
finalLIST = []
count = 0
find_name = '神力女超人'

for i in range(50): #往上爬3頁
	response = requests.get(url)
	if response.status_code == requests.codes.ok:
		soup = BeautifulSoup(response.text, "html.parser")

		titles = soup.find_all("div", class_="title")
		for title in titles:
			is_find = False
			a_title = title.select_one("a")
			if a_title:
				answerDICT = {'文章':'', '推':0, '箭頭':0, '噓':0}
				name = a_title.getText()
				answerDICT['文章'] = name
				resultLIST=re.findall(r"(?<=\[).+?(?=\])",name)
				if '影評' in resultLIST or all([label.find('雷')!=-1 for label in resultLIST]):
					count+=1
					if name.find(find_name)!=-1:
						is_find = True
						if all([label.find('好')!=-1 or label.find('優')!=-1 for label in resultLIST]):
							resultDICT['好評']+=1
						elif all([label.find('負')!=-1 or label.find('爛')!=-1 for label in resultLIST]):
							resultDICT['負評']+=1
						else:
							resultDICT['普通']+=1

				###
				if is_find:
					href = "https://www.ptt.cc" + title.select_one("a").get("href")
					response_2 = requests.get(href)
					if response_2.status_code == requests.codes.ok:
						soup_2 = BeautifulSoup(response_2.text, "html.parser")

						pushes = soup_2.find_all("div", class_="push")
						#print(pushes)
						userid = []
						for push in pushes:
							id = push.select_one(".push-userid").getText()
							if id not in userid:
								userid.append(id)
								push_tag = push.select_one(".push-tag").getText()
								if push_tag == '推 ':
									answerDICT['推'] += 1
								elif push_tag == '→ ':
									answerDICT['箭頭'] += 1
								elif push_tag == '噓 ':
									answerDICT['噓'] += 1
					finalLIST.append(answerDICT)
						#print(userid)
					#print(href)

		u = soup.select("div.btn-group.btn-group-paging a")#上一頁按鈕的a標籤
		url = "https://www.ptt.cc"+ u[1]["href"] #組合出上一頁的網址

		#print(soup.prettify())  #輸出排版後的HTML內容
	else:
		print('request error')

print(resultDICT)
for i in finalLIST:
	print(i)


"""
------------------
Project_Name:pythonProject
------------------
File Name:  serial_v1
Author :    nexus
date:       2021/7/22
------------------
串口输入测试
"""
import datetime
import re
import serial  # 导入模块
import time

com = "4"  # 端口号
bps = 9600  # 波特率
timex = None

def serial_input(com, bps, timex):
    try:
        ser = serial.Serial("COM" + com, bps, timeout=timex)  # 串口配置：端口，波特率，
        while True:
            if ser.in_waiting:
                str_a = ser.read(ser.in_waiting).hex().upper()
                str_list = re.findall(".{2}", str_a)  # 两个字节分隔
                new_str = " ".join(str_list)
                return new_str

        ser.close()  # 关闭串口
    except Exception as e:
        print("---异常---：", e)

def serial_cmd ():
    serial_cmda = new_str[6:8]
    return serial_cmda

while(1):
    new_str = serial_input(com, bps, timex)
    print(new_str)
    cmda = serial_cmd()
    print(cmda)