import pandas as pd
import docx
from docx import Document  # docx用来操作word.docx,document用来新建空白文档
import win32com.client as wc
import win32com
import re
import time
import os
import pythoncom
import zipfile
class RemoteWord:
    def __init__(self, filename=None):
        self.xlApp = win32com.client.DispatchEx('Word.Application')
        self.xlApp.Visible = 0
        self.xlApp.DisplayAlerts = 0  # 后台运行，不显示，不警告
        if filename:
            self.filename = filename
            if os.path.exists(self.filename):
                self.doc = self.xlApp.Documents.Open(filename)
            else:
                self.doc = self.xlApp.Documents.Add()  # 创建新的文档
                self.doc.SaveAs(filename)
        else:
            self.doc = self.xlApp.Documents.Add()
            self.filename = ''

    def add_doc_end(self, string):
        '''在文档末尾添加内容'''
        rangee = self.doc.Range()
        rangee.InsertAfter('\n' + string)

    def add_doc_start(self, string):
        '''在文档开头添加内容'''
        rangee = self.doc.Range(0, 0)
        rangee.InsertBefore(string + '\n')

    def insert_doc(self, insertPos, string):
        '''在文档insertPos位置添加内容'''
        rangee = self.doc.Range(0, insertPos)
        if (insertPos == 0):
            rangee.InsertAfter(string)
        else:
            rangee.InsertAfter('\n' + string)

    def replace_doc(self, string, new_string):
        '''替换文字'''
        self.xlApp.Selection.Find.ClearFormatting()
        self.xlApp.Selection.Find.Replacement.ClearFormatting()
        self.xlApp.Selection.Find.Execute(string, False, False, False, False, False, True, 1, True, new_string, 2)

    def save(self):
        '''保存文档'''
        self.doc.Save()

    def save_as(self, filename):
        '''文档另存为'''
        self.doc.SaveAs(filename)

    def close(self):
        '''保存文件、关闭文件'''
        self.save()
        self.xlApp.Documents.Close()
        self.xlApp.Quit()

# path="K:\\mashuaifei\\iacuc\\B2020040-G1014-01" # 文件夹绝对路径
# files=[]
# for file in os.listdir(path):
#     if file.endswith(".doc"):
#         files.append(path+file)
#
# # doc文件另存为docx
# print(files)
# word = wc.Dispatch("Word.Application")
# for file in files:
#     doc = word.Documents.Open(file)
#     doc.SaveAs("{}x".format(file), 12)
#     doc.Close()
# word.Quit()
# print("完成！")
# word = wc.Dispatch("Word.Application")
# doc = word.Documents.Open("K:\\mashuaifei\\iacuc\\B2020040-G1014-01\\B2020040-G1014-01 食蟹猴静脉注射给予8MW2311和NovoA001 重复给药毒性预试验方案-终.doc")
# # 上面的地方只能使用完整绝对地址，相对地址找不到文件，且，只能用“\\”，不能用“/”，哪怕加了 r 也不行，涉及到将反斜杠看成转义字符。
# doc.SaveAs(r"K:\\mashuaifei\\iacuc\\B2020040-G1014-01\\B2020040-G1014-01 食蟹猴静脉注射给予8MW2311和NovoA001 重复给药毒性预试验方案-终.docx", 12, False, "", True, "", False, False, False,
#            False)  # 转换后的文件,12代表转换后为docx文件
# # doc.SaveAs(r"F:\\***\\***\\appendDoc\\***.docx", 12)#或直接简写
# doc.Close
# word.Quit

path = r"K:\\mashuaifei\\iacuc\\B2020040-G1014-01\\B2020040-G1014-01 食蟹猴静脉注射给予8MW2311和NovoA001 重复给药毒性预试验方案-终.docx"
file = docx.Document(path)
#for p in file.paragraphs:
#    print(p.text)
data = {}
lines = [0 for i in range(len(file.paragraphs))]
tables = file.tables
k = 0

for paragraph in file.paragraphs:
    lines[k] = paragraph.text
    k = k+1

#print(lines)
def locaation(index,lines):
    locate = []
    for j in index:
        for i in range(len(lines)):
            lines[i] = lines[i].replace(' ', '')
            if lines[i] == j:
                locate.append(i)
    return locate

def choose(index,lines1):
    data = []
    for j in index:
        if isinstance(j, list):
            for i in range(len(lines1)):
                if lines1[i].startswith(j[0]) or lines1[i].startswith(j[1]) :
                    if '：' in lines1[i]:
                        data.append(lines1[i])
                    else:
                        data.append(lines1[i+1])
        else:
            for i in range(len(lines1)):
                if lines1[i].startswith(j):
                #if lines[i] == j:
                    if '：' in lines1[i]:
                        data.append(lines1[i])
                    else:
                        data.append(lines1[i+1])
    return data

def docx_replace(old_file,new_file,rep):
    zin = zipfile.ZipFile (old_file, 'r')
    zout = zipfile.ZipFile (new_file, 'w')
    for item in zin.infolist():
        buffer = zin.read(item.filename)
        if (item.filename == 'word/document.xml' or 'header' in item.filename):
            res = buffer.decode("utf-8")
            for r in rep:
                res = res.replace(r,rep[r])
            buffer = res.encode("utf-8")
        zout.writestr(item, buffer)
    zout.close()
    zin.close()

index_1 = ['专题名称及编号','试验材料']
index_2 = ['试验系统', '动物的饲养和管理']
index_3 = ['试验材料', '溶媒']
index_3_1 = ['溶媒', '试验系统']
index_4 = ['试验设计', '观察与检查']
index_5 = [ '观察与检查', '大体解剖、脏器称量和组织病理学检查']
#index_6 = [ '动物饲养']
index_6 = ['临床病理', '大体解剖、脏器称量和组织病理学检查']
index_7 = ['一般状态观察', '临床病理']
index_7_1 = ['临床病理','大体解剖、脏器称量和组织病理学检查']
index_8 = ['大体解剖、脏器称量和组织病理学检查','数据采集和分析']

index_1_locate = locaation(index_1, lines)
index_2_locate = locaation(index_2, lines)
index_3_locate = locaation(index_3, lines)
index_3_1_locate = locaation(index_3_1, lines)
index_4_locate = locaation(index_4, lines)
index_5_locate = locaation(index_5, lines)
if len(index_5_locate)==1:
    index_5 = ['观察与检查', '大体解剖观察和组织病理学检查']
    index_5_locate = locaation(index_5, lines)
index_6_locate = locaation(index_6, lines)
if len(index_6_locate)==1:
    index_6 = ['观察与检查', '大体解剖观察和组织病理学检查']
    index_6_locate = locaation(index_6, lines)
index_7_locate = locaation(index_7, lines)
index_7_1_locate = locaation(index_7_1, lines)
if len(index_7_1_locate)==1:
    index_7_1 = ['观察与检查', '大体解剖观察和组织病理学检查']
    index_7_1_locate = locaation(index_7_1, lines)
index_8_locate = locaation(index_8, lines)
if len(index_8_locate)==1:
    index_8 = index_8 = ['大体解剖观察和组织病理学检查','数据采集和分析']
    index_8_locate = locaation(index_8, lines)

print(index_1_locate)
print(index_2_locate)
print(index_3_locate)
print(index_4_locate)
print(index_5_locate)
print(index_6_locate)
print(index_7_locate)

lines1 = lines[index_1_locate[0]: index_1_locate[1]]

lines2 = lines[index_2_locate[0]: index_2_locate[1]]
lines3 = lines[index_3_locate[0]: index_3_locate[1]]
lines3_1 = lines[index_3_1_locate[0]: index_3_1_locate[1]]
lines4 = lines[index_4_locate[0]: index_4_locate[1]]
lines5 = lines[index_5_locate[0]: index_5_locate[1]]
lines6 = lines[index_6_locate[0]: index_6_locate[1]]
lines7 = lines[index_7_locate[0]: index_7_locate[1]]
lines7_1 = lines[index_7_1_locate[0]: index_7_1_locate[1]]
lines8 = lines[index_8_locate[0]: index_8_locate[1]]

index_basic = ['专题名称：', '专题编号：', '试验目的', '姓名：', '试验操作：']
index_basic1 = ['{%study-title%}', '{%study-num%}','{%study-purpose%}', '{%sd%}','{%sy%}','{%person%}','{%day1%}' ,'{%day2%}', '{%day3%}','{%day4%}']
index_basic_day4 = ['解剖时间']

index_animal = ['品系：', '等级：', '性别和数量','体重：', '年龄：','来源', '实验动物选择依据和数量','动物数量选择理由：']
index_animal1 = ['{%species%}', '{%level%}', '{%n1%}','{%n2%}', '{%age1%}','{%age2%}','{%weight1%}','{%weight2%}','{%sourse%}', '{%reason1%}','{%reason2%}','{%reason3%}','{%agency1%}','{%agency2%}']

index_medicine = ['名称/代号：', '名称：','代号：']
index_design = ['组别设计：', '动物数量：', '性别比例：', '给药剂量：', ['给药容积：', '给药体积：'], '给药途径：', '给药速率：', '给药频率及周期：']
index_procedure = ['{%substance1%}','{%substance2%}', '{%yang%}', '{%ying%}', '{%others%}','{%group1%}', '{%group2%}',  '{%group3%}',  '{%group4%}',
                  '{%group5%}', '{%animal_num1%}', '{%animal_num2%}', '{%animal_num3%}', '{%animal_num4%}', '{%animal_num5%}',
                    '{%route1%}', '{%route2%}',  '{%route3%}',  '{%route4%}',  '{%route5%}', '{%dosage1%}',  '{%dosage2%}',
                   '{%dosage3%}', '{%dosage4%}', '{%frequency%}','{%volume%}','{%rate%}'
                   ]

index_procedure1 = ['{%jiankang%}', '{%xueye%}', '{%niaoye%}', '{%mianyi%}','{%tk1%}','{%tk2%}','{%ada%}', '{%baoding%}', '{%method%}','{%siyang%}']

index_anlesi = ['{%anlesi%}','{%yanke%}','{%niaoye1%}']

index_specimens = ['{%catch_reason%}', '{catch_prostion%}', '{%catch_frequency%}', '{%catch_volume%}', '{%catch_maxvolume%}']

index_observe = ['一般状态观察','体重', '摄食量', '眼科检查', '免疫原性（ADA）', ' 毒代血样采集']
index_collect = ['一般状态观察','体重', '摄食量', '眼科检查', '免疫原性（ADA）', ' 毒代血样采集']

# 去除字符串的标点符号
punctuation = '!，;:?"\'；。（）'
def removePunctuation(text):
    text = re.sub(r'[{}]+'.format(punctuation), ' ', text)
    return text.strip()

def calculate(time1, time2, type='day'):
     day1 = time.strptime(str(time1), '%Y-%m-%d')
     day2 = time.strptime(str(time2), '%Y-%m-%d')
     if type == 'day':
      day_num = (int(time.mktime(day2)) - int(time.mktime(day1))) / (
       24 * 60 * 60)
     return abs(int(day_num))

# part1

data_basic = choose(index_basic, lines1)
data_basic1 = [removePunctuation(i.split('：')[1]) if '：' in i else i for i in data_basic]
data_basic1_1 = [removePunctuation(i.split('：')[0]) if '：' in i else i for i in data_basic]
xm=0
for i in data_basic1_1:
    if i.startswith('姓名'):
        xm+=1
if xm ==2:
    data_basic1.pop(4)
else:
    pass

data_basic11 = choose(index_basic_day4, lines8)
day4 = data_basic11[0]
if '，' in day4:
    day4 = day4.split('，')[0]
else:
    pass

try:
    index_day = ['预定试验开始日期：', '预定试验结束日期：', '预定首次给药日期：', '给药期结束解剖：']
    data_day = data_basic = choose(index_day, lines1)
    day_list = [removePunctuation(i.split('：')[1]) if '：' in i else i for i in data_basic]
    if len(day_list) ==4:
        day1 = calculate(day_list[0],day_list[1])
        day2 = calculate(day_list[0],day_list[2])
        day3 = calculate(day_list[2],day_list[3])
        day = [day1,day2,day3,day4]
    else:
        pass
except:
    index_basic_specail = [ '预定试验开始日期：', '预定试验结束日期：','预定雌性动物首次给药日期：', '预定雌性动物给药期结束解剖日期：']
    data_basic_special = choose(index_basic_specail, lines1)
    day_list = [removePunctuation(i.split('：')[1]) if '：' in i else i for i in data_basic_special]
    if len(day_list) ==4:
        day1 = calculate(day_list[0],day_list[1])
        day2 = calculate(day_list[0],day_list[2])
        day3 = calculate(day_list[2],day_list[3])
        day = [day1,day2,day3,day4]
    else:
        pass
    day1 = calculate(day_list[0],day_list[1])
    day2 = calculate(day_list[0],day_list[2])
    day3 = calculate(day_list[2],day_list[3])
    day = [day1,day2,day3,day4]

day = ['','','',day4]
part1 = data_basic1[:5] +['王海洋、徐堃、沈双琪、吴自强、付梦洁、吴若林、孟庆喜'] + day
print(part1)
print('part1 no problem')
#part1 finished

#part2
data_animal = choose(index_animal, lines2)
data_animal1 = [removePunctuation(i.split('：')[1]) if len(i) < 30  else i for i in data_animal ]
number =[int(int(re.findall("\d+",data_animal1[2] )[0])/2)]

if '约' in data_animal1[4]:
    age = [(data_animal1[4].split('分')[0] if '分' in data_animal1[4] else data_animal1[4]).split('约')[1]]
else:
    age = [data_animal1[4].split('时')[1]]

if  len(data_animal1[3]) < 10:
    weight = [data_animal1[3],data_animal1[3]]
elif '雌' in data_animal1[3]:
    # 体重：购入时雌性150 ~ 180 g、雄性160 ~ 190 g。
    weight =[(data_animal1[3].split('g')[0]).split('雌性')[1] + 'g', (data_animal1[3].split('g')[1]).split('雄性')[1] + 'g']
else:
    weight =[(data_animal1[3].split('g')[0]).split('时')[1] + 'g',(data_animal1[3].split('g')[0]).split('时')[1] + 'g']
sourse = [data_animal1[5]+'(或其他合格供应商)']
reason1 = [ data_animal1[6]]
reason2 = [data_animal1[7][:200]]
reason3 = [data_animal1[7][200:]]

agency_index = ['遵循的法规及技术指导原则', '质量保证']
index_agency_locate = locaation(agency_index, lines)

if len(index_agency_locate) == 1:
    agency_index1 = ['遵循的法规及技术指导原则', '试验时间安排']
    index_agency_locate = locaation(agency_index1, lines)
print(index_agency_locate)
lines_agency = lines[index_agency_locate[0]: index_agency_locate[1]]
agency_ = ['《药物重复', '《药物毒代']
agency = []
for j in agency_ :
    for i in lines_agency :
        if i.startswith(j):
            agency.append(i)
if len(agency) ==1:
    agency.append('')
part2 = data_animal1[:2] + number + number + age +age+ weight + sourse +reason1+reason2+reason3 +agency
print(part2)
print('part2 no problem')
 # part2 finished

#part3
data_medicine = choose(index_medicine, lines3)
data_medicine1 = [removePunctuation(i.split('：')[1]) if len(i)<40  else i for i in data_medicine ]
# 判断试验材料有哪些
'''
如果实验材料只有一个，必然是供试品；
如果实验材料有两个，且没有空白组，两个供试品：否则一个供试品，一个空白组；
如果三个，且有空白组，即两个供试品，一个空白组 如：A2020006-T014-01
新增： 空白组还可是叫辅料组
'''
test_materials = []
print(data_medicine1)

for i in range(len(lines3)):
    if lines3[i].startswith('名称/代号：') or lines3[i].startswith('名称：') or lines3[i].startswith('代号：'):
        test_materials.append(lines3[i-2])
print(test_materials)
if len(test_materials) == 1:
    substance1 = data_medicine1[0]
    substance2 = ''
elif len(test_materials) == 2 and '空白对照品' not in test_materials and '辅料对照品' not in test_materials:
    substance1 = data_medicine1[0]+'，'+data_medicine1[1]
    substance2 = data_medicine1[1]
elif len(test_materials) == 2 and '空白对照品' in test_materials or '辅料对照品' in test_materials:
    substance1 = data_medicine1[0]
    substance2 = data_medicine1[1]
else:
    substance1 = data_medicine1[0]+'，'+data_medicine1[1]
    substance2 = data_medicine1[2]

#判断溶媒，只有在没有空白组的情况下有
'''
溶媒的判断方法同试验材料
当溶媒只有一个，那必然唯一填入
当溶媒有两个，那必然会需要配制

'''
data_medicine_rongmei = choose(index_medicine, lines3_1)
data_medicine_rongmei1 = [removePunctuation(i.split('：')[1]) if len(i)<40  else i for i in data_medicine_rongmei ]

if '空白对照品' not in test_materials and '辅料对照品' not in test_materials:
    if len(data_medicine_rongmei) ==1:
        other = data_medicine_rongmei1[0]
    elif len(data_medicine_rongmei) ==2:
        for i in range(len(lines3_1)):
            if lines3_1[i].startswith('配制方法'):
                other = (lines3_1[i-1]).split('的')[0]
    data_medicine11 = [substance1, substance2, 'NA', 'NA', other]
else:
    other = substance2
    data_medicine11 = [substance1, substance2, 'NA', 'NA', other]
# if len(data_medicine1) > 2:
#     data_medicine11 = [data_medicine1[0]+'，'+data_medicine1[1], data_medicine1[2], 'NA, ', 'NA', data_medicine1[2]]
# elif len(data_medicine1) == 2:
#     data_medicine11 = [data_medicine1[0],data_medicine1[1], 'NA, ', 'NA', data_medicine1[1]]
# else :
#     data_medicine11 = [data_medicine1[0], data_medicine1[1],'NA, ', 'NA', 'NA']

# 组别的拆分
'''
组别的情况越来越多样了,新情况;  '组别设计：溶媒对照组、WXSH0376低剂量组、WXSH0376中剂量组和WXSH0376高剂量组；
主要需要区分“顿号”“逗号”“和”。
'''
data_design = choose(index_design, lines4)
print(data_design)
group1 = [[removePunctuation(data_design[0].split('：')[1])][0].split('、')[i] for i in range(len([removePunctuation(data_design[0].split('：')[1])][0].split('、')))]
for i in group1:
    if '和' in  i:
        group = [i.split('和')[0],i.split('和')[1]]
        group1.remove(i)
        if '中' in ''.join(group):
            group1 = group1 + group
        else:
            group1 = group + group1
    else:
        pass

# 动物数量
# print(data_design[1])
# print((re.findall(r'\d+', removePunctuation(data_design[1].split('：')[1]))))
if ' 'in data_design[1]:
    animal_num = str(int(int(re.findall(r'\d+',removePunctuation(data_design[1].split('：')[1]).split(' ')[-1])[0])/(len(group1)*2)))
else:
    animal_num = str(int(int(re.findall(r'\d+', removePunctuation(data_design[1].split('：')[1]))[1]) / (len(group1) * 2)))
animal_num = [animal_num + '             ' + animal_num] *len(group1)

# 给药途径的判断
'''
先给出大概的几种方式，找到给药途径的话语，判断这几种方式在不在其中。
# 部分试验方案会存在多种方式在其中，需要s数计算来判断
'''
route_choice = ['皮下', '静脉','灌胃']
s = 0
for i in route_choice:
    if i in data_design[5]:
        s+=1
if s>=2:
    route = ['']*len(group1)
elif '灌胃' in data_design[5]:
    route = ['灌胃' ] * len(group1)
else:
    route= [removePunctuation(data_design[5].split('：')[1])]*len(group1)

#通过表格找到给药剂量
'''
情况是 从表格中提取剂量，但是表格不固定为第几个
加一个判断，表格的第二列指标是否是"试验物质"
'''
for table in tables[6:7]:
    table_total = []
    for i, row in enumerate(table.rows[:]):   # 读每行
        row_content = []
        for cell in row.cells[:]:  # 读一行中的所有单元格
            c = cell.text
            row_content.append(c)
        table_total.append(row_content)
print(table_total)
if table_total[0][1] !='试验物质':
    for table in tables[5:6]:
        table_total = []
        for i, row in enumerate(table.rows[:]):   # 读每行
            row_content = []
            for cell in row.cells[:]:  # 读一行中的所有单元格
                c = cell.text
                row_content.append(c)
            table_total.append(row_content)

if '溶酶对照组'in group1 or '空白对照组' in group1 or '辅料对照组' in group1:
    table_total.pop(0)
    table_total.pop(0)
    table_total.pop(0)
else:
    table_total.pop(0)
    table_total.pop(0)
#print(table_total) #以列表形式导出每一行数据
dosage = [table_total[i][2] + 'mg/kg' for i in range(len(table_total))]

# 给药频率
'''
到底要不要写给药几周
'''
frequency = [(removePunctuation(data_design[-1].split('：')[1])).split('；')[0] ]

# 因为体积容积的区分

volume1 = [((removePunctuation(data_design[4].split('：')[1])).split(' ')[0]).split('为')[1] ]
if 'mL/kg' in volume1:
    volume = volume1
else :
    volume = [re.findall(r'\d+',removePunctuation(data_design[4].split('：')[1]))[0] +' mL/kg']
try:
    rate = [((removePunctuation(data_design[-2].split('：')[1]))).split('约')[1]]
except:
    rate = ['找不到给药速率NA']
if len(group1) < 5 :
    i = 5-len(group1)
    group1 = group1 + i*['']
    animal_num = animal_num + i*['']
    route = route + i*['']
    dosage = dosage + i*['']
else:
    group1 = group1
    animal_num = animal_num
    route = route
    dosage = dosage

part3 = data_medicine11 + group1 + animal_num +route + dosage + frequency +volume + rate
data_observe = choose(index_observe, lines5)
for table in tables[7:8]:
    for i, row in enumerate(table.rows[:]):   # 读每行
        row_content = []
        for cell in row.cells[:]:  # 读一行中的所有单元格
            c = cell.text
            row_content.append(c)
        #print (row_content) #以列表形式导出每一行数据
print(part3)
print('part3 no problem')

# part4
## 健康检查到临床病理
'''
首先是健康检查项目：先判断是否有没有健康检查项目 ，从zhibiao这个列表得知
                    如果有，即写成jiankang
然后是临床检查项目： 判断血液，尿液是否在其中,从zhibiao1中得知

其他项目检查，同，判断ADA,TK在不在zhibiao1中
'''
sss = ['测定时间：', '观察时间：']
properties = []
zhibiao = []
for i in range(len(lines7)):
    if lines7[i].startswith('测定时间：') or lines7[i].startswith('观察时间：') or lines7[i].startswith('检测时间：') :
        property = lines7[i-1] + '：' + lines7[i]
        properties.append(property)
        zhibiao.append(lines7[i-1])

for i, j in enumerate(properties):
    if j.startswith('体重：'):
        properties[i] = ''.join(properties[i].split('（')[:-1])

# 体温，血压，心电，呼吸
if '体温' in ''.join(zhibiao):
    jiankang_1 = properties[3].replace('；','。')
    jiankang = ['体温、呼吸、心电、血压：'+(jiankang_1.split('时间：'))[1]]
else:
    jiankang = ['NA']

# 临床病理
properties_1 = []
zhibiao_1 = []
for i in range(len(lines7_1)):
    if lines7_1[i].startswith('测定时间：') or lines7_1[i].startswith('观察时间：')or lines7_1[i].startswith('检测时间：')  or lines7_1[i].startswith('检测的血样采集时间：')  or lines7_1[i].startswith('血样采集：') :
        property = lines7_1[i].split('：')[1][:-1]
        properties_1.append(property)
        zhibiao_1.append(lines7_1[i-1])
for i in range(len(lines7_1)):
    if lines7_1[i].startswith('采样时间：') or lines7_1[i].startswith('血样采集：'):
        if '剂量' in lines7_1[i]:
            if '采样时间：' in lines7_1[i]:
                property = lines7_1[i].split('采样时间：')[1] + lines7_1[i + 1]
            else:
                property = lines7_1[i].split('：')[1] + lines7_1[i + 1]
        else:
            property = lines7_1[i+1] + lines7_1[i + 2]
        properties_1.append(property)
        zhibiao_1.append(lines7_1[i-1])

print(zhibiao_1)
#尿液
if '尿液' in ''.join(zhibiao_1):
    niaoye1 = ['尿液：' + properties_1[1]]
    for i in range(len(lines7_1)):
        if '代谢笼' in lines7_1[i] or '底盘' in lines7_1[i]:
            niaoye_method1 = lines7_1[i]
    niaoye_method = niaoye_method1.split('：')[1]
    niaoye = [niaoye1[0]+ '（'+niaoye_method+'）。']
else:
    niaoye1 =['']
    niaoye = ['']
    niaoye_method = ''

# 血液
if '血液' in ''.join(zhibiao_1):
    xueye = ['血液学、凝血和血生化：' + properties_1[0]]
# 免疫
mianyi = ['免疫毒性指标：']

# 判断ADA,毒代是否在其中
if 'ADA' in ''.join(zhibiao_1):
    ada1 = properties_1[-2]
    ada = ['ADA：' + ada1 + '。']
else:
    ada1 = ''
    ada = ['']
if '毒代动力学' or '血样'in ''.join(zhibiao_1):
    tk_1 = properties_1[-1][0:200]
    tk_2 = properties_1[-1][200:]
else:
    tk_1 = ''
    tk_2 = ''
tk1 = ['TK：'+tk_1]
tk2 = [tk_2]

# 保定
index_bd =['动物的饲养和管理','试验设计']
index_bd_locate = locaation(index_bd, lines)
linesbd = lines[index_bd_locate[0]: index_bd_locate[1]]
print(linesbd)
for i in range(len(linesbd)):
    if linesbd[i].startswith('动物选择'):
        if '保定' in linesbd[i+2]:
            bd1 = linesbd[i+2]
        else:
            bd1 = linesbd[i+1]
if '不少于' in  bd1:
    j = re.sub('\D', '', bd1.split('不少于')[1])
else :
    j = 'NA'
if '猴' in data_animal1[0] and '保定' in bd1:
    i = '猴椅'
    baoding = '试验中涉及的保定方式有徒手保定和' + i + '保定，其中称重为徒手保定，保定时长约2 min；给药为'+i +'保定，保定时长为'+ j+'min。'
elif '鼠' in data_animal1[0] and '保定' in bd1 :
    i = '大鼠固定器'
    if j == 'NA' :
        baoding = '试验中涉及的保定方式有徒手保定和' + i + '保定，其中称重为徒手保定，保定时长约2 min；'
    else:
        baoding = '试验中涉及的保定方式有徒手保定和' + i + '保定，其中称重为徒手保定，保定时长约2 min；给药为'+i +'保定，保定时长为'+ j+'min。'

elif '犬' in data_animal1[0] and '保定' in bd1:
    i = '犬保定架'
    baoding = '试验中涉及的保定方式有徒手保定和' + i + '保定，其中称重为徒手保定，保定时长约2 min；给药为'+i +'保定，保定时长为'+ j+'min。'
else:
    baoding = '试验中涉及的保定方式有徒手保定保定，其中称重为徒手保定，保定时长约2 min。'

if '在' in bd1:
    baoding = [baoding + bd1.split('在')[1]]
else:
    baoding = [baoding]
for i in lines2:
    if i.startswith('剩余动物'):
        method = [i]
teminal = ['']

# 判断单笼合笼
for i in range(len(lines4)):
    if lines4[i].startswith('动物数量：'):
        shuliang =lines4[i]
    if lines4[i].startswith('性别比例：'):
        bili  = lines4[i]

if  int(re.sub('\D', '', shuliang.split('，')[0] )) >2:
    if '半' in bili:
        print('合笼')
        siyang = ['若动物出于兽医护理的需要或动物不相容的原因进行单笼饲养，将会作相应记录，并给予额外的环境丰富计划。']
else:
    print('单笼')
    siyang  =['']
part4 = jiankang + xueye + niaoye + mianyi + tk1 + tk2+ ada + baoding  + method +siyang

print(part4)
print('part4 no problem')
#part4 fininshed

#part other5
anlesi = []
for i in range(len(lines)):
    if lines[i] == '麻醉及安乐死方法':
        anlesi.append(lines[i+1])

if '眼科' in ''.join(zhibiao):
    c = '舒泰肌肉注射麻醉后进行检查，剂量参照机构SOP执行。'
else:
    c =''
anlesi.append(c)
anlesi.append(niaoye_method)

print(anlesi)
catch_huoti=[]
catch_huoti_index = []

# # 判断活体动物采集
# for i in range(len(lines7_1)):
#     if lines7_1[i].startswith('检测动物：') or lines7_1[i].startswith('采样动物：') or lines7_1[i].startswith('测定动物：') or lines7_1[i].startswith('检测的血样采集时间：') :
#         catch_huoti.append(lines7_1[i])
#         catch_huoti_index.append(i)  # 位置
# # 得到操作检测动物列表  ['检测动物：主试验各组待解剖大鼠；', '检测动物：主试验各组待解剖大鼠；', '检测动物：毒代卫星组存活动物；', '采样动物：所有计划测定的存活TK动物；']
# print(catch_huoti)
# print(catch_huoti_index)
#
# #判断,如果都有活体,执行if,否则sles
# if all("存活" in s for s in catch_huoti):
#     print('在临床就使用活体')
#     catch_reason = ['临床病理、TK、ADA血样']
#     for table in tables[7:8]:
#         row_content = []
#         for i, row in enumerate(table.rows[:]):  # 读每行
#             for cell in row.cells[:]:  # 读一行中的所有单元格
#                 c = cell.text
#                 #c = ''.join(filter(str.isdigit, c))
#                 c = ''.join(re.findall(r"\d+\.?\d*", c))
#                 row_content.append(c)
#     if row_content[0] =='':
#         for table in tables[8:9]:
#             row_content = []
#             for i, row in enumerate(table.rows[:]):  # 读每行
#                 for cell in row.cells[:]:  # 读一行中的所有单元格
#                     c = cell.text
#                     #c = ''.join(filter(str.isdigit, c))
#                     c = ''.join(re.findall(r"\d+\.?\d*", c))
#                     row_content.append(c)
#
#     row_content1 = [row_content[4] ,row_content[7] ,row_content[10]]
#     catch_volume = '临床病理样本约'+ str(sum([float(i) for i in row_content1])) + 'mL'
#     print(catch_volume)
#     catch_position = [
#         (([lines7_1[i] for i in range(len(lines7_1)) if lines7_1[i].startswith('采样方法：')][0]).split('，')[0]).split(
#             '：')[1]]
#     catch_volume_number = [float(''.join(re.findall(r"\d+\.?\d*", lines7_1[i]))) for i in range(len(lines7_1)) if
#                            lines7_1[i].startswith('采样方法：')]
#     catch_maxvolume_number = max(catch_volume_number)
#
#     catch_maxvolume = [catch_volume]
#     if isinstance(catch_maxvolume_number, float):
#         if len(catch_volume_number) == 2:
#             label = ['ADA', 'TK']
#             catch_maxvolume = [
#                 label[catch_volume_number.index(catch_maxvolume_number)] + '约' + str(catch_maxvolume_number) + 'mL']
#         else:
#             catch_volume_sum = ['找不到tk,ada其中一个的采血量']
#     else:
#         catch_volume_sum = ['找不到tk,ada的采血量']
# else:
#     # 由于临床没有活体 ,找到使用活体的指标
#     print('只有血样之后采用活体')
#     catch_reason = ['TK、ADA血样']
#     label = ['ADA','TK']
#     cunhuo_list = [catch_huoti_index[i]  for i in range(len(catch_huoti))  if '存活' in  catch_huoti[i] ]
#     catch_volume = [lines7_1[i] for i in cunhuo_list]
#     catch_position = [(([ lines7_1[i]  for i in range(len(lines7_1)) if lines7_1[i].startswith('采样方法：')][0]).split('，')[0] ).split('：')[1]]
#     catch_volume_number = [float(''.join(re.findall(r"\d+\.?\d*", lines7_1[i])))  for i in range(len(lines7_1)) if lines7_1[i].startswith('采样方法：') or  lines7_1[i].startswith('采样方法和采样量：') ]
#     catch_maxvolume_number = max(catch_volume_number)
#     catch_maxvolume =[label[catch_volume_number.index(catch_maxvolume_number)] + '约' + str(catch_maxvolume_number) +'mL']
#
#     catch_volume_sum_number = sum(catch_volume_number)
#     catch_volume_sum =['约' + str(catch_volume_sum_number) + 'mL' +'（' +catch_maxvolume[0] + '，'+ 'TK约' + str(catch_volume_number[1]) +'mL）']
# catch_frequency = ['24小时内不超过三次']
#
# print(catch_maxvolume)
# part_other = catch_reason +catch_position +catch_frequency +catch_maxvolume + catch_volume_sum
#finished

part_other = ['','','','','']
print(part1)
print(part2)
print(part3)
print(part4)
print(anlesi)
print(part_other )
# print(data_observe)

index = [0 for i in range(10)]
for j in index_1:
    for i in range(len(lines)):
        #if lines[i].startswith(j):
        if lines[i] == j:
            print(i)
            print(lines[i])

# pythoncom.CoInitialize()
# word_name = 'BTC-IAC-0011-3.0 IACUC-动物管理和使用审批表 3.0 2020-03-06生效'
# word_path_moban = r'K:\mashuaifei\iacuc\iacuc1\新建文件夹\moban.docx'
# doc = Document(word_path_moban)
# new_docx = part1[1] + word_name + '.docx'
# print(new_docx)
# doc.save(os.path.join(r'K:\mashuaifei\iacuc\iacuc1\新建文件夹\\', new_docx))
#
# replace_list = []
# for i,j in enumerate(index_basic1):
#     replace_list.append((j,part1[i]))
# for i,j in enumerate(index_animal1):
#     replace_list.append((j, part2[i]))
# for i,j in enumerate(index_procedure):
#     replace_list.append((j, part3[i]))
# for i,j in enumerate(index_procedure1):
#     replace_list.append((j, part4[i]))
# for i, j in enumerate(index_anlesi):
#     replace_list.append((j, anlesi[i]))
# # for i, j in enumerate(index_specimens ):
# #     replace_list.append((j, part_other[i]))
#
# print(replace_list)
#
# name_path = 'K:\mashuaifei\iacuc\iacuc1\新建文件夹' + "\\" + new_docx
# namedocx = os.path.abspath('K:\mashuaifei\iacuc\iacuc1\新建文件夹' + "\\" + new_docx)
# replace_docx = RemoteWord(namedocx)
# for i in replace_list:
#     if len(i)>200:
#         print(i)
# for i in replace_list:
#     try:
#         replace_docx.replace_doc(i[0], i[1])
#     except:
#         replace_docx.close()
#         print('its wrong')
# replace_docx.close()
# rep = {'{%study-num%}': data_basic1[1]}
# '''替换页眉'''
# new_docx1 = part1[1] + word_name + '1.docx'
# new = 'K:\mashuaifei\iacuc\iacuc1\新建文件夹' + "\\" + new_docx1
# docx_replace(name_path, new, rep)


import random
import sys  # We use sys.exit to exit the program
import pygame
from pygame.locals import *

# Global variables for the game
FPS = 32
SCREENWIDTH = 850
SCREENHEIGHT = 650
SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
GROUND = SCREENHEIGHT
GAME_SPRITES = {}
GAME_SOUNDS = {}
PLAYER = 'gallery/sprites/bird.png'
BACKGROUND = 'gallery/sprites/background.png'
PIPE = 'gallery/sprites/pipe1.png'
HIGHSCORE = 0
pygame.init()
font = pygame.font.Font('freesansbold.ttf', 32)
white = (255,255,255)

def welcomeScreen(SCORE):
    plx = int(SCREENWIDTH - GAME_SPRITES['player'].get_width())/2
    ply = int(SCREENHEIGHT - GAME_SPRITES['player'].get_height())/2
    msgx = int(SCREENWIDTH - GAME_SPRITES['message'].get_width())/2
    msgy = int(SCREENHEIGHT - GAME_SPRITES['message'].get_height())/2 - 30
    basex = -1
    hstext = font.render(f"High Score : {HIGHSCORE}", True, white)
    stext = font.render(f"You Scored {SCORE}", True, white)
    scr_x = int(SCREENWIDTH - stext.get_width())/2
    scr_y = GROUND+100
    while 1:
        SCREEN.blit(GAME_SPRITES['background'], (0,0))
        SCREEN.blit(GAME_SPRITES['base'], (basex,GROUND))
        if SCORE != -1:
            SCREEN.blit(stext, (scr_x,scr_y))
        SCREEN.blit(hstext, (3,3))
        SCREEN.blit(GAME_SPRITES['message'], (msgx,msgy))
        SCREEN.blit(GAME_SPRITES['player'], (plx,ply))
        pygame.display.update()
        FPSCLOCK.tick(FPS)
        for event in pygame.event.get():
            if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()

            elif event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
                return

def getRandomPipe():
    '''
    generate position of two pipes(one bottom straight & one top rotated) for blitting on the screen
    '''
    # Minimum distance b/w 2 pipes
    offset = SCREENHEIGHT/5

    # Distance from top to the base
    h = SCREENHEIGHT - GAME_SPRITES['base'].get_height()

    # Lower end of upper pipe
    y1 = random.randrange(int(SCREENHEIGHT/8),int(h - offset-5))

    # UPPER end of lower pipe
    y2 = y1 + offset    # This is the maximum height of the lower pipe
    y2 += random.randrange(h- y2-5)

    # Converting y1 into its upper length
    y1 -= GAME_SPRITES['pipe'][0].get_height()

    pipex = float(SCREENWIDTH + 5)
    pipe = [
        {'x': pipex, 'y' : y1},#upper pipe
        {'x': pipex, 'y': y2}#lower pipe
    ]
    return pipe

# Checks if the player collided or not
def iscollide(plx,ply,ups,lps):
    pipeheight = GAME_SPRITES['pipe'][0].get_height()
    for pipe in ups:
        if ply < pipeheight + pipe['y'] and pipe['x'] - GAME_SPRITES['player'].get_width()/1.2 < plx < pipe['x'] + GAME_SPRITES['pipe'][0].get_width():
            GAME_SOUNDS['hit'].play()
            return True

    for pipe in lps:
        if ply + GAME_SPRITES['player'].get_height() > pipe['y'] and pipe['x'] - GAME_SPRITES['player'].get_width()/1.2 < plx < pipe['x'] + GAME_SPRITES['pipe'][0].get_width():
            GAME_SOUNDS['hit'].play()
            return True
    return False

def mainGame():
    score = 0
    plx = int(SCREENWIDTH)/5
    ply = int(SCREENHEIGHT)/2
    basex = 0

    # Create two pipes for blitting on screen
    newp1 = getRandomPipe()
    newp2 = getRandomPipe()

    # My list of upper pipes
    ups = [
        {'x' : float(SCREENWIDTH + 5), 'y' : newp1[0]['y']},
        {'x' : float(SCREENWIDTH + 5 + (SCREENWIDTH/2)), 'y' : newp2[0]['y']}
    ]

    # My list of lower pipes
    lps = [
        {'x' : float(SCREENWIDTH + 5), 'y' : newp1[1]['y']},
        {'x' : float(SCREENWIDTH + 5 + (SCREENWIDTH/2)), 'y' : newp2[1]['y']}
    ]

    # Defining some variables for the movement
    pipvelX = float(-5 )    # Pipe veclocity
    plyVelY = -9    # Player Velocity
    plymaxvelY = 10 # Player max velocity
    plyAccY = 1     # Player acceleration while falling

    flpngV = -8    # velocity while flapping
    plyFlped = False    #True while flapping

    while 1:
        for event in pygame.event.get():
            if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()

            if event.type == KEYDOWN and (event.key == K_SPACE or event.key == K_UP):
                if ply > 0:
                    plyVelY = flpngV
                    plyFlped = True
                    GAME_SOUNDS['wing'].play()

        crashTest = iscollide(plx,ply,ups,lps)
        if crashTest:
            return score

        #Checking score
        plymid = plx + GAME_SPRITES['player'].get_width()/2
        for pipe in ups:
            pipmid = pipe['x'] + GAME_SPRITES['pipe'][0].get_width()/2
            if pipmid <= plymid < pipmid-pipvelX:
                score+=1
                print(f"SCORE : {score}")
                GAME_SOUNDS['point'].play()

        if plyVelY < plymaxvelY and not plyFlped:
            plyVelY += plyAccY

        plyFlped = False

        playerheight = GAME_SPRITES['player'].get_height()
        ply += min(plyVelY, GROUND - ply - playerheight)

        #Moves pipes to the left
        for up, lp in zip(ups,lps):
            up['x'] += pipvelX
            lp['x'] += pipvelX

        #Add a new pipe
        if 0 < ups[0]['x'] < 6:
            newpipe = getRandomPipe()
            ups.append(newpipe[0])
            lps.append(newpipe[1])

        # removing pipe if it is out of the screen
        if ups[0]['x'] <= -GAME_SPRITES['pipe'][0].get_width():
            ups.pop(0)
            lps.pop(0)

        #Blitting the pipe
        SCREEN.blit(GAME_SPRITES['background'], (0,0))
        SCREEN.blit(GAME_SPRITES['player'], (plx, ply))
        for up,lp in zip(ups,lps):
            SCREEN.blit(GAME_SPRITES['pipe'][0], (up['x'], up['y']))
            SCREEN.blit(GAME_SPRITES['pipe'][1], (lp['x'], lp['y']))
        SCREEN.blit(GAME_SPRITES['base'], (basex, GROUND))

        mydigits = [int(x) for x in list(str(score))]
        width = 0
        for digits in mydigits:
            width += GAME_SPRITES['number'][digits].get_width()

        xoffset = (SCREENWIDTH - width)/2
        for digit in mydigits:
            SCREEN.blit(GAME_SPRITES['number'][digit], (xoffset, SCREENHEIGHT*0.12))
            xoffset += GAME_SPRITES['number'][digit].get_width()

        pygame.display.update()
        FPSCLOCK.tick(FPS)

if __name__ == '__main__':
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    pygame.display.set_caption("Flappy Bird by Rocko")
    GAME_SPRITES['number']= (
        pygame.image.load('gallery/sprites/0-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/1-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/2-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/3-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/4-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/5-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/6-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/7-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/8-Number-PNG.png').convert_alpha(),
        pygame.image.load('gallery/sprites/9-Number-PNG.png').convert_alpha(),
    )
    #Game Sprites
    GAME_SPRITES['message'] = pygame.image.load('gallery/sprites/message.png').convert_alpha()
    GAME_SPRITES['base'] = pygame.image.load('gallery/sprites/base.png').convert_alpha()
    GAME_SPRITES['background'] = pygame.image.load(BACKGROUND).convert()
    GAME_SPRITES['player'] = pygame.image.load(PLAYER).convert_alpha()

    GAME_SPRITES['pipe'] =(
        pygame.transform.rotate(pygame.image.load(PIPE).convert_alpha(), 180),
        pygame.image.load(PIPE).convert_alpha()
    )
    # global GROUND
    GROUND -= GAME_SPRITES['base'].get_height()

    #Game Sounds
    GAME_SOUNDS['die'] = pygame.mixer.Sound('gallery/audio/die.wav')
    GAME_SOUNDS['hit'] = pygame.mixer.Sound('gallery/audio/hit.wav')
    GAME_SOUNDS['wing'] = pygame.mixer.Sound('gallery/audio/wing.wav')
    GAME_SOUNDS['point'] = pygame.mixer.Sound('gallery/audio/point.wav')
    GAME_SOUNDS['swoosh'] = pygame.mixer.Sound('gallery/audio/swoosh.wav')
    try:
        with open("HIGHSCORE.txt",'r') as f:
            HIGHSCORE = int(f.read())

    except:
        with open("HIGHSCORE.txt","w") as f:
            f.write("0")

    welcomeScreen(-1)
    while 1:
        SCORE = mainGame()
        if SCORE > HIGHSCORE:
            HIGHSCORE = SCORE
            with open("HIGHSCORE.txt","w") as f:
                f.write(str(SCORE))
        welcomeScreen(SCORE)


import torch

class OperationNumber():
    """
    统计网络处理一个数据所需的加乘操作数量
    """
    def __init__(self, net):
        """
        :param net: 已经加载预训练参数的网络模型
        这个待处理的网络输入的每一个 batch 包含不同的两部分图像，前一半是含噪图像数据 x + e，后一半是原始干净图像数据 x
        """
        self.net = net
        self.feature_name_list = list()
        self.layer_name_list = list()

        self.op_number_i_list = list()   # 保存当前层所需的操作数量

    def _is_leaf(self, module):
        """
        判断网络的一个模块是否是叶子节点，即层 layer
        :param module:
        :return:
        """
        if sum(1 for x in module.children()) == 0:
            return True
        elif module._get_name().startswith('BlurPool'):
            return True
        else:
            sum_padding = 0
            for name, layer in module.named_children():
                if 'padding' in name:
                    sum_padding += 1
            if sum_padding == sum(1 for x in module.children()):
                return True
        return False

    def hook_all_layers(self):
        """
        :return:
        """
        hook_OrderedDict = list()

        def hook(module, inputdata, output):
            """
            钩子函数，计算统计量
            :param module: 模块，层
            :param inputdata: 输入数据，元组，长度可能不是 1，保存张量
            :param output: 输出数据，元组
            :return:
            """
            m_name = module._get_name()
            if m_name.startswith('Conv'):   # 层类型，若是卷积保存其步长数
                self.layer_name_list.append(m_name+'_i{}o{}k{}s{}'.format(module.in_channels, module.out_channels, module.kernel_size[0], module.stride[0]))
            elif m_name.startswith('MaxPool') or m_name.startswith('AvgPool'):
                self.layer_name_list.append(m_name + '_k{}s{}'.format(module.kernel_size, module.stride))
            else:
                self.layer_name_list.append(module._get_name())
            #如果当前模块是叶子节点，则计算其所需的操作数量
            op_no = get_operation_NO(module, inputdata, output)
            self.op_number_i_list.append(op_no)

        def the_leaf(model, pre_name=''):
            """
            通过递归形式保存网络中所有层 layer 的名称，并给每一层后添加钩子函数
            :param model:
            :param pre_name:
            :return:
            """
            for index, param in enumerate(model.named_children()):                          # 逐个处理网络中的每一个模块
                name, layer = param
                name = name if pre_name == '' else pre_name + '.' + name
                if self._is_leaf(layer):                                                    # 若是层 layer
                    if layer._get_name().startswith('Dropout') or layer._get_name().startswith('Lambda'):
                        continue
                    hook_OrderedDict.append(layer.register_forward_hook(hook))              # 添加钩子函数
                    self.feature_name_list.append(name)                                     # 保存层名称
                else:
                    the_leaf(layer, pre_name = name)
        the_leaf(self.net, pre_name = '')

    def run(self, shape = (1,3,224,224)):
        input = torch.randn(shape)
        self.hook_all_layers()
        self.net(input)
        assert len(self.layer_name_list) == len(self.op_number_i_list), \
            'len(self.layer_name_list) = {}, len(self.op_number_i_list) = {}'\
                .format(len(self.layer_name_list),len(self.op_number_i_list))
        sum_op = 0
        for index, name in enumerate(self.layer_name_list):
            #feature_name = self.feature_name_list[index]
            text = '{} ==> {}'.format(name.ljust(48), self.op_number_i_list[index])
            sum_op += self.op_number_i_list[index]
            print(text)
        print('-'*100)
        print('-'*100)
        print('网络所需加乘操作数量总数为：{} ==> {} K ==> {} M ==> {} G'.
              format(sum_op, sum_op / (10**3), sum_op / (10**6), sum_op / (10**9)))

    def counter(self):
        params = list(self.net.parameters())
        k = 0
        for i in params:
            l = 1
            #print("该层的结构：" + str(list(i.size())))
            for j in i.size():
                l *= j
            #print("该层参数和：" + str(l))
            k = k + l
        print("总参数数量和：{} ==> {} K ==> {} M".format(k, k / 1000, k / 1000 / 1000))

def get_operation_NO(layer, inputdata, output):
    """
    计算 module 处理 inputdata 所需的加乘操作数量
    :param layer: module
    :param inputdata: input data
    :return:
    """
    type_name = layer._get_name()
    #print(type_name)
    if type_name in ['Conv2d']:
        x = inputdata[0]
        out_h = int((x.size()[2] + 2 * layer.padding[0] - layer.kernel_size[0]) // layer.stride[0] + 1)
        out_w = int((x.size()[3] + 2 * layer.padding[1] - layer.kernel_size[1]) // layer.stride[1] + 1)
        delta_ops = layer.in_channels * layer.out_channels * layer.kernel_size[0] * \
                    layer.kernel_size[1] * out_h * out_w // layer.groups

    elif type_name in ['DWT_3D_tiny']:
        x = inputdata[0]
        channels = x.size()[1]
        out_d = int((x.size()[2] + layer.kernel_size // 2) // layer.stride + 1)
        out_h = int((x.size()[3] + layer.kernel_size // 2) // layer.stride + 1)
        out_w = int((x.size()[4] + layer.kernel_size // 2) // layer.stride + 1)
        delta_ops = layer.kernel_size ** 3 * channels * out_d * out_h * out_w

    elif type_name in ['DWT_3D']:
        x = inputdata[0]
        channels = x.size()[1]
        out_d = int((x.size()[2] + layer.kernel_size // 2) // layer.stride + 1)
        out_h = int((x.size()[3] + layer.kernel_size // 2) // layer.stride + 1)
        out_w = int((x.size()[4] + layer.kernel_size // 2) // layer.stride + 1)
        delta_ops = 8 * layer.kernel_size ** 3 * channels * out_d * out_h * out_w

    elif type_name in ['IDWT_3D']:
        x = inputdata[0]
        channels = x.size()[1]
        out_d = int((x.size()[2] + layer.kernel_size // 2) + 1)
        out_h = int((x.size()[3] + layer.kernel_size // 2) + 1)
        out_w = int((x.size()[4] + layer.kernel_size // 2) + 1)
        delta_ops = 8 * layer.kernel_size ** 3 * channels * out_d * out_h * out_w

    elif type_name in ['Hardshrink']:
        x = inputdata[0]
        delta_ops = x.numel()

    elif type_name in ['Conv3d',]:
        x = inputdata[0]
        out_d = int((x.size()[2] + 2 * layer.padding[0] - layer.kernel_size[0]) // layer.stride[0] + 1)
        out_h = int((x.size()[3] + 2 * layer.padding[1] - layer.kernel_size[1]) // layer.stride[1] + 1)
        out_w = int((x.size()[4] + 2 * layer.padding[2] - layer.kernel_size[2]) // layer.stride[2] + 1)
        delta_ops = layer.in_channels * layer.out_channels * layer.kernel_size[0] * \
                    layer.kernel_size[1] * layer.kernel_size[2] * out_d * out_h * out_w // layer.groups

    elif type_name in ['Conv3d']:
        #print(type(inputdata), len(inputdata))
        #print(type(output), len(output))
        x = inputdata[0]
        #print(x.size())
        out_d = int((x.size()[2] + 2 * layer.padding[0] - layer.kernel_size[0]) // layer.stride[0] + 1)
        out_h = int((x.size()[3] + 2 * layer.padding[1] - layer.kernel_size[1]) // layer.stride[1] + 1)
        out_w = int((x.size()[4] + 2 * layer.padding[2] - layer.kernel_size[2]) // layer.stride[2] + 1)
        delta_ops = layer.in_channels * layer.out_channels * layer.kernel_size[0] * \
                    layer.kernel_size[1] * layer.kernel_size[2] * out_d * out_h * out_w // layer.groups

    ### ops_nonlinearity
    elif type_name in ['ReLU']:
        x = inputdata[0]
        delta_ops = x.numel()

    ### ops_pooling
    elif type_name in ['AvgPool2d']:
        x = inputdata[0]
        in_w = x.size()[2]
        in_h = x.size()[3]
        kernel_ops = layer.kernel_size * layer.kernel_size
        out_w = int((in_w + 2 * layer.padding - layer.kernel_size) // layer.stride + 1)
        out_h = int((in_h + 2 * layer.padding - layer.kernel_size) // layer.stride + 1)
        delta_ops = x.size()[1] * out_w * out_h * kernel_ops
    ### ops_pooling
    elif type_name in ['AvgPool3d', 'MaxPool3d', ]:
        x = inputdata[0]
        in_d = x.size()[2]
        in_w = x.size()[3]
        in_h = x.size()[4]
        kernel_ops = layer.kernel_size * layer.kernel_size * layer.kernel_size
        out_d = int((in_d + 2 * layer.padding - layer.kernel_size) // layer.stride + 1)
        out_w = int((in_w + 2 * layer.padding - layer.kernel_size) // layer.stride + 1)
        out_h = int((in_h + 2 * layer.padding - layer.kernel_size) // layer.stride + 1)
        delta_ops = x.size()[1] * out_d * out_w * out_h * kernel_ops

    elif type_name in ['AdaptiveAvgPool2d', 'AdaptiveAvgPool3d']:
        x = inputdata[0]
        delta_ops = x.numel()

    elif type_name in ['Linear']:
        weight_ops = layer.weight.numel()
        bias_ops = layer.bias.numel()
        delta_ops = weight_ops + bias_ops

    elif type_name in ['BatchNorm2d', 'BatchNorm3d']:
        x = inputdata[0]
        normalize_ops = x.numel()
        scale_shift = normalize_ops
        delta_ops = normalize_ops + scale_shift

    ### ops_nothing
    elif type_name in ['Dropout2d', 'DropChannel', 'Dropout']:
        delta_ops = 0

    elif type_name in ['SpatialGate_CT_C']:
        x = inputdata[0]
        delta_ops = 2 * x.numel()

    elif type_name in ['DWT2_2D']:
        x = inputdata[0]
        channels = x.size()[1]
        out_h = int((x.size()[2] + 2 * layer.pad_sizes[0] - layer.kernel_size) // layer.stride + 1)
        out_w = int((x.size()[3] + 2 * layer.pad_sizes[1] - layer.kernel_size) // layer.stride + 1)
        delta_ops = channels * layer.kernel_size * layer.kernel_size * out_h * out_w // layer.groups

    ### unknown layer type
    else:
        delta_ops = 0
        print('unknown layer type: %s' % type_name)

    return delta_ops

if __name__ == '__main__':
    from networks.neuron_net import Neuron_WaveSNet_V1, Neuron_WaveSNet_V2, Neuron_WaveSNet_V3, Neuron_WaveSNet_V4
    from networks.neuron_net import Neuron_SegNet, Neuron_UNet_V1, Neuron_UNet_V2
    net = Neuron_UNet_V1()
    net = Neuron_SegNet()
    #net = Neuron_WaveSNet_V4(wavename = 'db2')
    op_no = OperationNumber(net)
    op_no.run(shape = (1,1,32,128,128))
    op_no.counter()


import requests
import multiprocessing as mp
cookie = {'session':''}
def post(url):
    return requests.post(url+'free',cookies=cookie)
urls = ["http://tcp.olymp.hackforces.com:8090/" for i in range(80)]
if __name__ == '__main__':
    with mp.Pool(10) as pool:
        res = pool.map(post, urls)
        print(res)


from datetime import datetime
from django.shortcuts import render, redirect
from django.utils import timezone
from .models import Schedule, Route, Stop

# Create your views here.
def homeView(request):
    routes = Route.objects.all()
    context = {
        "routes": routes,
    }
    return render(request, "home/index.html", context)

def AllRoutes(request):
    AllRoutes = Route.objects.all()
    context = {
        "AllRoutes": AllRoutes,
    }
    return render(request, "home/all_routes.html", context)

def allSchedules(request, pk):
    route = Route.objects.get(id=pk)
    AllSchedules = Schedule.objects.filter(route=route).order_by("departure_time")

    context = {
        "AllSchedules": AllSchedules,
        "route": route,
    }
    return render(request, "home/all_schedules.html", context)

def allStops(request, pk):
    route = Route.objects.get(id=pk)
    AllStops = Stop.objects.filter(route=route).order_by("departure_time")
    context = {
        "AllStops": AllStops,
        "route": route,
    }
    return render(request, "home/all_stops.html", context)


#!/usr/bin/env python3

descr = """
This script will analyse integers occurring at the end of each line of a text
file. It will output their sum and the largest and smallest integers.
"""

import argparse
import itertools
import math
import re

# Pattern of an integer occurring at the end of a line (preceded by whitespace)
pattern = re.compile("\s[0-9]+$")

def line_integer(line):
    """Get trailing integer from a line."""
    match = pattern.search(line)
    if match:
        return int(match.group())
    else:
        return float('nan')

def process_file(file):
    """Print the sum, minimum and maximum of trailing integers in a file."""

    total = 0
    min_i = float('inf')
    max_i = -float('inf')

    with open(file, "r") as f:
        for i in itertools.filterfalse(math.isnan, map(line_integer, f)):
            total = total + i
            min_i = min(min_i, i)
            max_i = max(max_i, i)

    print("{file}: sum {total}".format(**locals()))
    print("{file}: min {min_i}".format(**locals()))
    print("{file}: max {max_i}".format(**locals()))

# Define and parse the script arguments
parser = argparse.ArgumentParser(description=descr)
parser.add_argument("file", nargs='+')
args = parser.parse_args()

# Run the actual job
for file in args.file:
    process_file(file)


from pupa.celery import app
from django.core.mail import send_mail
from .models import Order

@app.task
def order_created(order_id):
    # отправка уведомления по электронной почте при успешном создании заказа
    # send email notification when order is successfully created
    order = Order.objects.get(id=order_id)
    subject = 'Заказ №. {}'.format(order_id)
    message = 'Привет {0} (◕‿◕),\n\n\
    Рад сообщить тебе, что твой заказ под номером {1}\n\
    был успешно оформлен! ٩(◕‿◕)۶\n\n\
    Спасибо тебе (◕‿◕)♡,\n\
    С уважением yamitoys!'.format(order.first_name, order.id)
    mail_sent = send_mail(subject,
                          message,
                          'yamitoys@gmail.com',
                          [order.email])
    return mail_sent


# coding=utf8
import time
from psutil import net_io_counters
import tkinter as tk
import threading

KB = 1024
MB = KB * 1024
GB = MB * 1024

def format_speed_unit(speed: int):
    if speed < KB:
        return f"{speed}B/s"
    elif speed < MB:
        return f"{speed / KB:.2f}KB/s"
    elif speed < GB:
        return f"{speed / MB:.2f}MB/s"
    else:
        return f"{speed / GB:.2f}GB/s"

current_net_speed = f"↑{format_speed_unit(0)} ↓{format_speed_unit(0)}"

def get_net_speed():
    global current_net_speed
    while True:
        sent_before = net_io_counters().bytes_sent
        recv_before = net_io_counters().bytes_recv
        time.sleep(1)
        sent_now = net_io_counters().bytes_sent
        recv_now = net_io_counters().bytes_recv
        upload_speed = (sent_now - sent_before)
        download_speed = (recv_now - recv_before)
        current_net_speed = f"↑{format_speed_unit(upload_speed)} ↓{format_speed_unit(download_speed)}"

def update_speed():
    global current_net_speed
    label.config(text=current_net_speed)
    root.after(1000, update_speed)

if __name__ == '__main__':
    thread_a = threading.Thread(target=get_net_speed)
    thread_a.start()

    root = tk.Tk()
    label = tk.Label(root)
    label.pack()
    update_speed()
    root.mainloop()


from typing import List

class Solution:
    def finalPrices(self, prices: List[int]) -> List[int]:
        length = len(prices)
        answer = []

        for i in range(0, length - 1):
            price = prices[i]
            discount = 0

            for j in range(i + 1, length):
                if prices[j] <= prices[i]:
                    discount = prices[j]
                    break

            answer.append(price - discount)

        answer.append(prices[-1])
        return answer

print(Solution().finalPrices([8, 4, 6, 2, 3]))


from flask import Flask, request, redirect
from twilio.twiml.messaging_response import Message, MessagingResponse

app = Flask(__name__)

@app.route("/sms", methods=['GET', 'POST'])

def sms_reply():
    # Get message sent
    message_body = request.form['Body'].upper()

    if message_body.find('CONFIRM') >= 0:
        msg_reply = "Thanks for the confirmation!"

    elif message_body.find('RESCHEDULE') >= 0:
        msg_reply = "It appears you need to cancel or change your appointment, we will contact you."

    else:
        msg_reply = f"Unknown response: '{message_body}' - Please respond with CONFIRM or RESCHEDULE."

    # TwiML response
    resp = MessagingResponse()
    resp.message(msg_reply)

    return str(resp)

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


#http://codeforces.com/contest/1091/problem/B

import sys
import math
from collections import defaultdict

try:
    sys.stdin = open('input.txt', 'r')
    sys.stdout = open('output.txt', 'w')

except:
    pass

n=int(input())
coords=[]
params=[]
for i in range(n):
	c=[int(x) for x in input().split()]
	coords.append(c)
for i in range(n):
	p=[int(x) for x in input().split()]
	params.append(p)

init=[coords[0][0],coords[0][1]]
answers=defaultdict(lambda:0)

for c in coords:
	c1,c2=c[0],c[1]
	for p in params:
		p1,p2=p[0],p[1]
		a=(c1+p1,c2+p2)
		answers[a]+=1

for a in answers:
	if(answers[a]==n):
		p=a

print(p[0],p[1])

B - New Year and the Treasure Geolocation.py


import pytz

timezones = {1: {"zone": "Great Britain", "timezone": 'GB'},
             2: {"zone": "Greece", "timezone": 'Europe/Athens'},
             3: {"zone": "Spain", "timezone": 'Europe/Madrid'},
             4: {"zone": "France", "timezone": 'Europe/Paris'},
             5: {"zone": "Italy", "timezone": 'Europe/Rome'},
             6: {"zone": "Croatia", "timezone": 'Europe/Zagreb'},
             7: {"zone": "Sweden", "timezone": 'Europe/Stockholm'},
             8: {"zone": "Finland", "timezone": 'Europe/Helsinki'},
             9: {"zone": "Belgium", "timezone": 'Europe/Brussels'},
             }

for location in sorted(timezones):
    print("{}: {}".format(location, timezones[location]["zone"]))

print()
user = None

while user != 0:
    try:
        print("You can anytime press 0 to quit.")
        user = int(input("Please enter a timezone from 1-9: "))

        if user in timezones.keys():
            tzToDisplay = pytz.timezone(timezones[user]["timezone"])
            print("Here you go: ")
            print()
            print(f"Your local time is: {pytz.datetime.datetime.now().strftime('%A %x %X')}")
            print(f"Your UTC local time is: {pytz.datetime.datetime.utcnow().strftime('%A %x %X')}")
            print("Your chosen zone: {}\t The time: {}".format(timezones[user]["zone"],
                                                               pytz.datetime.datetime.now(tzToDisplay).strftime(
                                                                   '%A %x %X')))
            print("=" * 50)
            continue

        elif user == 0:
            print("Alright, you chose to quit")
            break

        else:
            print("Sorry, that is invalid.")
            print()
            continue

    except (ValueError, TypeError):
        print("Sorry, but you have to enter an integer from 1-9, or 0, not anything else!")
        print()
        continue


import random
from pathlib import Path

from hydra.utils import to_absolute_path
import numpy as np
import torch
from torch.utils.data import Dataset, DataLoader

def fix_seed(seed: int) -> None:
    """
    再現性の担保のために乱数シードの固定する関数.

    Args:
        seed (int): シード値
    """
    random.seed(seed)     # random
    np.random.seed(seed)  # numpy
    # pytorch
    torch.manual_seed(seed)
    if torch.cuda.is_available():
        torch.cuda.manual_seed_all(seed)

def load_utt_list(utt_list: str) -> list:
    """
    Load a list of utterances.

    Args:
        utt_list (str): path to a file containing a list of utterances

    Returns:
        List[str]: list of utterances
    """
    utt_ids = []
    with open(utt_list) as f:
        for utt_id in f:
            utt_id = utt_id.strip()
            if len(utt_id) > 0:
                utt_ids.append(utt_id)
    return utt_ids

def pad_2d(x: torch.Tensor, max_len: int, constant_values: int = 0):
    """
    Pad a 2d-tensor.

    Args:
        x (torch.Tensor): tensor to pad
        max_len (int): maximum length of the tensor
        constant_values (int, optional): value to pad with. Default: 0

    Returns:
        torch.Tensor: padded tensor
    """
    # 短い系列は後ろにパディングして最長系列の長さに揃える
    x = np.pad(
        x,
        [(0, max_len - len(x)), (0, 0)],
        mode="constant",
        constant_values=constant_values,
    )
    return x

def collate_fn_dulation(batch):
    """ 短い系列は最長系列の長さに揃えた上で,各データをtensorにして返す """
    lengths = [len(x[0]) for x in batch]
    lengths = torch.tensor(lengths, dtype=torch.long)
    max_len = max(lengths)

    x_batch = torch.stack([torch.from_numpy(pad_2d(x[0], max_len)) for x in batch])
    y_batch = torch.stack([torch.from_numpy(pad_2d(x[1], max_len)) for x in batch])

    return x_batch, y_batch, lengths

def get_dataloaders(data_config):
    data_loaders = {}

    for phase in ['train', 'dev']:
        utt_ids = load_utt_list(to_absolute_path(data_config[phase].utt_list))
        in_dir = Path(to_absolute_path(data_config[phase].in_dir))
        out_dir = Path(to_absolute_path(data_config[phase].out_dir))

        in_feats_paths = [in_dir / f'{utt_id}-feats.npy' for utt_id in utt_ids]
        out_feats_paths = [out_dir / f'{utt_id}-feats.npy' for utt_id in utt_ids]

        dataset = DulationDataset(in_feats_paths, out_feats_paths)
        data_loaders[phase] = DataLoader(
            dataset,
            batch_size=data_config.batch_size,
            shuffle=phase.startswith("train"),
            num_workers=data_config.num_workers,
            collate_fn=collate_fn_dulation,
            pin_memory=True,
        )

    return data_loaders

class DulationDataset(Dataset):
    def __init__(self, in_paths, out_paths):
        self.in_paths = in_paths
        self.out_paths = out_paths

    def __getitem__(self, idx):
        data = np.load(self.in_paths[idx])
        label = np.load(self.out_paths[idx])
        return data, label

    def __len__(self):
        return len(self.in_paths)

if __name__ == '__main__':
    data_dir = Path('../data/dump/jsut_sr16000/org/train/')
    in_paths = list(data_dir.glob('in_dulation/*.npy'))
    out_paths = list(data_dir.glob('out_dulation/*.npy'))

    dataset = DulationDataset(in_paths, out_paths)
    dataloader = DataLoader(dataset, batch_size=8,
                            collate_fn=collate_fn_dulation, num_workers=0)
    print(f'データ数: {len(dataset)}')
    print(f'イテレーション数: {len(dataloader)}')

    in_feats, out_feats, lengths = next(iter(dataloader))
    print(f'入力特徴量のサイズ: {in_feats.shape}')  # [batch, phoneme, feature]
    print(f'出力特徴量のサイズ: {out_feats.shape}')
    print(f'系列長のサイズ: {lengths.shape}')


from flask import Flask, render_template, request, session, redirect, url_for, flash
from flask_wtf import FlaskForm
from wtforms import (
    StringField,
    BooleanField,
    DateTimeField,
    RadioField,
    SelectField,
    TextField,
    TextAreaField,
    SubmitField,
)
from wtforms.validators import DataRequired

# create the app
app = Flask(__name__)
# Set the secret key
app.config["SECRET_KEY"] = "superkey"

# Default Route
@app.route("/")  # 127.0.0.1:5000
def index():
    return render_template("home.html")  # render the basic template

##########################
### Course management

# Custom parameters route
@app.route("/course/<input_name>")
def course_name(input_name):
    name = input_name
    return render_template("flask.html", name=name)

# List of courses
@app.route("/course/")
def course_list():
    user_logged_in = True
    course_list = ["flask", "pygame", "data science", "machine learning"]
    return render_template(
        "courses.html", log_ok=user_logged_in, courses_iter_list=course_list
    )

###############
# New Courses

# Sign up form to compile
@app.route("/course/new/")
def new_course():
    return render_template("course_new.html")

# Thank you page after form compiled
@app.route("/course/created")
def course_created():
    # grab first name variable from signup html page
    course_name = request.args.get("course-name")
    course_subject = request.args.get("course-subject")

    # save to database

    return render_template(
        "course_created.html", course_name=course_name, course_subject=course_subject
    )

###### ERROR HANDLER
## Page 404 error
@app.errorhandler(404)
def page_not_found(error):
    return render_template("404.html"), 404

################################################
#### ADVANCE FORMS WITH wtforms and flask_wtf
class InfoForm(FlaskForm):  # Inherit from FlaskForm
    name = StringField("What's the name of the course? ")
    submit = SubmitField("Submit")

# Route for the advance form
@app.route("/course/create/simple/", methods=["GET", "POST"])
def advance_form():
    name = False  # placeholder iniziale
    form = InfoForm()  # Oggetto InfoForm

    # Logic of the form
    if form.validate_on_submit():  # if you press: submit, this is what happend
        name = form.name.data  # get the data
        form.name.data = ""  # reset
    return render_template("course_advance.html", advance_form=form, course_name=name)

################################################
#### SUPER ADVANCE FORMS with validators, session, url for, ...
class CourseAdvanceForm(FlaskForm):
    """Definition of the form

    Args:
        FlaskForm (object): FlaskForm default main class
    """

    course_name = StringField(
        "What's the name of the course", validators=[DataRequired()]
    )
    course_active = BooleanField("The course is active?")
    difficulty = RadioField(
        "Please the difficulty of the course:",
        choices=[("easy", "Easy"), ("medium", "Medium"), ("hard", "Hard")],
    )
    platform = SelectField(
        u"Pick the platform you want to do the course:",
        choices=[("zoom", "Zoom"), ("skype", "Skype"), ("teams", "Teams")],
    )
    # the u before the string is the casting to unicode
    note = TextAreaField()
    submit = SubmitField("Submit")

@app.route("/course/create/advance", methods=["GET", "POST"])
def super_form():

    # Actions for the complicate form
    course_form = CourseAdvanceForm()

    # if the form is compiled
    if course_form.validate_on_submit():

        # save form information into session user cookie
        session["course_name"] = course_form.course_name.data
        session["course_active"] = course_form.course_active.data
        session["difficulty"] = course_form.difficulty.data
        session["platform"] = course_form.platform.data
        session["note"] = course_form.note.data

        # reset the form
        course_form.course_name.data = ""
        course_form.course_active.data = ""
        course_form.difficulty.data = ""
        course_form.platform.data = ""
        course_form.note.data = ""

        # go to the thankyou template page (thankyou function in python file)
        return redirect(url_for("course_result"))

    return render_template("course_advance_super.html", form=course_form)

@app.route("/course/create/advance/result")
def course_result():
    flash("Form compiled succesfully!")  # flash an alert message to the user
    return render_template("course_result.html")

## Main function (app run)
if __name__ == "__main__":
    app.run(debug=True)


from TestCore import TestCore
import os
import json
from cati.dotcati.Pkg import Pkg
from cati.frontend import Env

class test_dotcati_installer(TestCore):
    """ Test test_dotcati_installer """
    def run(self):
        """ Run test """
        self.assert_equals(self.run_command('pkg', [
            'install',
            'repository/test-repository/simple-test-package.cati'
        ]), 0)

        self.assert_true(os.path.isfile(self.env('/usr/bin/cati-testpkga')))

        self.assert_equals(self.run_command('pkg', [
            'install',
            'repository/test-repository/simple-test-package.cati'
        ]), 0)

        self.assert_true(os.path.isfile(self.env('/usr/bin/cati-testpkga')))

        pkg = Pkg.load_from_index(json.loads(open(Env.packages_lists('/testpkga/index'), 'r').read()), 'testpkga')
        self.assert_equals(pkg.installed(), '1.0')

        self.refresh_env()

        self.assert_equals(self.run_command('pkg', [
            'install',
            'repository/test-repository/testpkg-with-file-conflict-a.cati',
        ]), 0)

        self.assert_true(os.path.isfile(self.env() + '/etc/testpkg-with-file-conflict/test.txt'))

        self.refresh_env()

        os.mkdir(self.env() + '/app')

        self.assert_equals(self.run_command('pkg', [
            'install',
            'repository/test-repository/testpkg-with-file-conflict-a.cati',
            '--target=/app'
        ]), 0)

        self.assert_true(not os.path.isfile(self.env() + '/etc/testpkg-with-file-conflict/test.txt'))
        self.assert_true(os.path.isfile(self.env() + '/app/etc/testpkg-with-file-conflict/test.txt'))


import numpy as np

from .. import impurities, metrics
from ..ensemble.meta_algorithms import Bagging
from ..base.models import Model
from ..regression.models import LinearRegression
from ..utils.data_utils import permutate
from ..utils.decorator_utils import fit_method, predict_method
from ..utils.operation_utils import sign
from .optimizers import DecisionStumpSolver, CART, RandomTree

class DecisionStump(Model):
    model_type = "binary-classifier"

    def __init__(self, metrics=[metrics.Accuracy()]):
        self.feature_ = None
        self.threshold_ = None
        self.sign_ = 0

        self.compile(optimizer = DecisionStumpSolver(), metrics=metrics)

    @fit_method
    def fit(self, X, y):
        self.sign_, self.feature_, self.threshold_ = self.optimizer.execute(X, y)
        return self

    @predict_method
    def predict(self, X):
        x = X[:, self.feature_]
        theta = self.threshold_
        s = self.sign_
        return s * sign(x - theta)

class DecisionTree(Model):
    model_type = ["binary-classifier", "regressor"]

    def __init__(
        self,
        criterion = impurities.GiniIndex(),
        max_height = np.inf,
        optimizer = CART(),
        metrics = [metrics.Accuracy()]
    ):
        self.model_type = criterion.problem_type
        self.tree_ = None

        self.compile(criterion = criterion,
                     optimizer = optimizer,
                     max_height = max_height,
                     metrics = metrics)

    @fit_method
    def fit(self, X, y):
        self.tree_ = self.optimizer.execute(X, y)
        return self

    @predict_method
    def predict(self, X):
        return self.tree_.predict(X)

class RandomForest(Model):
    model_type = ["binary-classifier", "regressor"]

    meta_algorithm = Bagging(DecisionTree())

    def __init__(
        self,
        n_estimators = 5,
        optimizer = RandomTree(tree=CART(), criterion=impurities.GiniIndex(), random_subspace=(0.5, )),
        metrics = [metrics.Accuracy()],
        **kwargs
    ):
        self.model_type = optimizer.criterion.problem_type
        self.compile(
            n_estimators = n_estimators,
            optimizer = optimizer,
            metrics = metrics,
            **kwargs
        )

    @fit_method
    def fit(self, X, y, raw_importance=False):
        self.meta_algorithm = self.meta_algorithm.fit(X, y)
        self.feature_importances_ = self.eval_feature_importance(X, y, raw_importance)
        return self

    @predict_method
    def predict(self, X):
        return self.meta_algorithm.predict(X)

    def eval_feature_importance(self, X, y, raw=False):
        """Evaluate raw feature importance

        The instructive annotation comes from the referance of random forest
        by Leo Breiman and Adele Cutler.
        See: https://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm#varimp

        Parameters
        ----------
        X: 2-D array  (n_samples, n_features)
            The feature part of the training data

        y: 1-D array like   (n_samples, )
            The value or label from the training data

        raw: bool, default=False
            If `raw==True`, use the votes cast for right
            class as the evaluating metric in classification
            problem. If `raw==False`, use accuracy.

        Return
        ------
        importances: 1-D array (n_features, )
            Feature importance evaluated based on out-of-bag data.
        """
        bag = self.meta_algorithm
        oob_to_model = self.meta_algorithm.data_oob_status_
        correct_votes = np.empty(self.n_estimators)
        permuted_correct_votes = np.empty((X.shape[1], self.n_estimators))

        if self.model_type == "binary-classifier":
            if raw:
                metric = lambda y_pred, y_true: sum(y_pred == y_true)
            else:
                metric = metrics.Accuracy()
        elif self.model_type == "regressor":
            metric = metrics.R2()
        else:
            raise ValueError("Invalid model_type")

        # (1) In every tree grown in the forest, put down the oob cases
        # and evaluate the metrics (accuracy for classification and r^2 for
        # regression).
        # The author use votes for the correct as the metric (raw == True),
        # so we use "correct_votes" the variable name to match the instruction.
        for i in range(self.n_estimators):
            X_oob = X[oob_to_model[:, i], :]
            y_oob = y[oob_to_model[:, i]]
            y_pred = bag.base_models[i].predict(X_oob)
            correct_votes[i] = metric(y_oob, y_pred)

            # (2) Now randomly permute the values of variable m
            # in the oob cases and put these cases down the tree.
            for m in range(X.shape[1]):
                X_oob_m_permuted = permutate(X_oob, feature_idx=m)
                y_pred_m_permuted = bag.base_models[i].predict(X_oob_m_permuted)
                permuted_correct_votes[m, i] = metric(y_oob, y_pred_m_permuted)

        # (3) Subtract the metric evaluated in the variable-m-permuted
        #  oob data from the metric evaluated in the untouched oob data.
        performance_in_trees = correct_votes - permuted_correct_votes

        # (4) The average of this number over all trees in the forest
        # is the importance score for variable m.
        importances = np.mean(performance_in_trees, axis=1)

        return importances

class GradientBoostedDecisionTree(Model):
    model_type = "regressor"

    def __init__(
        self,
        n_estimators = 5,
        max_height = 5,
        metrics = [metrics.MeanSquaredError()]
    ):
        self.model_weight_ = np.empty(0)
        self.base_regression_trees_ = [DecisionTree(criterion = impurities.MeanSquaredError(),
                                                   max_height = max_height,
                                                   metrics = metrics) for _ in range(n_estimators)]
        self.compile(
            n_estimators = n_estimators,
            max_height = max_height,
            metrics = metrics
        )

    @fit_method
    def fit(self, X, y):

        residuals_i = y
        for i in range(self.n_estimators):
            # (1) obtain base-model_i by A({(xn, yn − sn)}) where `A`
            #     is regression tree algorithm, `sn` are predicting
            #     values evaluated by current boosting model. Therefore,
            #     `yn - sn` are the residuals.
            model_i = self.base_regression_trees_[i].fit(X, residuals_i)
            y_pred_i = model_i.predict(X)[:, None]

            # (2) compute the model weight for model_i by regressing residuals
            #     `yn − sn` on the predicting values of current model `gt(xn)`.
            #     Note that it is an "single variable linear regression".
            coef_i = LinearRegression().fit(y_pred_i, residuals_i).weight_[1]
            self.model_weight_ = np.append(self.model_weight_, coef_i)

            # (3) After the update of model weight has been done, compute the
            #     prediction based on the updated boosting model, and then
            #     substract the prediction from y to set new residuals for
            #     the next round of training.
            residuals_i = y - self.predict(X)

        return self

    @predict_method
    def predict(self, X):

        n_estimators = len(self.model_weight_)
        polls = np.empty((X.shape[0], n_estimators))

        for i in range(n_estimators):
            polls[:, i] = self.base_regression_trees_[i].predict(X)

        return polls @ self.model_weight_


from shapely import affinity
from shapely.geometry import LineString, Point, MultiPoint, GeometryCollection, MultiLineString
from shapely.ops import cascaded_union

from copter.sensors.Sensor import Sensor
from geometry.Circle import Circle
from geometry.PointVector import PointVector

__author__ = 'Martin'

class SensorMock(Sensor):
    def __init__(self, sensor_range, obstacles, other_copters):
        self.sensor_range = sensor_range
        self.sweep_resolution = 25
        self.obstacles = obstacles
        self.other_copters = other_copters

    def collect_obstacles_closest_points(self, copter_position):
        obstacle_entities = list(map(
            lambda obstacle: obstacle.geometric_entity.get_lib_conversion(),
            self.obstacles))
        return self.get_closest_points(copter_position, obstacle_entities)

    def collect_other_copters_closest_points(self, position):
        other_copters_circles = list(map(
            lambda copter: Circle(PointVector(copter.position.x, copter.position.y), copter.size).get_lib_conversion(),
            self.other_copters))
        return self.get_closest_points(position, other_copters_circles)

    # inspired by http://gis.stackexchange.com/q/81613
    def get_closest_points(self, copter_position, entities):
        position = copter_position.get_lib_conversion()
        all_entities = cascaded_union(entities)

        starting_sweep_line = LineString(
            [position, (position.x, position.y - self.sensor_range)])
        sweep_lines = [affinity.rotate(starting_sweep_line, i, position)
                       for i in range(0, 360, self.sweep_resolution)]
        radial_sweep = cascaded_union(sweep_lines)

        perimeter = []
        for radial_line in radial_sweep:
            intersection = radial_line.intersection(all_entities)

            if isinstance(intersection, Point):
                perimeter.append(intersection)
            elif isinstance(intersection.type, MultiPoint):
                intersection_dict = {}
                for intersection_point in intersection:
                    intersection_dict[position.distance(intersection_point)] = intersection_point
                # add closest intersection point
                perimeter.append(intersection_dict[min(intersection_dict.keys())])
            elif isinstance(intersection, LineString):
                closest_point = self.get_line_closest_point(position, intersection)
                perimeter.append(closest_point)
            elif isinstance(intersection, MultiLineString):
                for line in intersection:
                    closest_point = self.get_line_closest_point(position, line)
                    perimeter.append(closest_point)
            elif isinstance(intersection, GeometryCollection):
                pass
            else:
                raise ValueError("Unknown type {}".format(intersection.__class__.__name__))

        return list(map(lambda p: PointVector(p.x, p.y), perimeter))

    @staticmethod
    def get_line_closest_point(position, line):
        p1 = Point(line.coords[0][0], line.coords[0][1])
        p2 = Point(line.coords[1][0], line.coords[1][1])
        if position.distance(p1) < position.distance(p2):
            return p1
        else:
            return p2


import logging
import os
import socket

from contextlib import contextmanager
from threading import Lock

try:
    from odoo.tools import classproperty
except ImportError:
    from openerp.tools import classproperty

from werkzeug.local import Local

_logger = logging.getLogger(__name__)

try:
    import paramiko
except ImportError:
    _logger.warning('Cannot import paramiko.')

class SSHEnvironments(set):
    """ It provides a common object for all environments for a request """

class SSHEnvironment(object):
    """ It provides an environment for thread-safe management of SSH sessions

    Attributes:
        RETRY_EXCEPTIONS: (list) Exceptions that will cause an SSH
            reconnection attempt.
        RETRY_MAX: (int) Maximum amount of consecutive SSH connection
            reconnection attempts before failure.
        client: (paramiko.Client|None) Raw Paramiko SSH connection. None if
            not connected.
        host: (str) Node Hostname/IP that is used for connection.
        port: (int) Port number used for connection.
        username: (str) Username used for authentication.
        identify_file: (str) Path to the SSH identity file

    TODO:
        * Create a transport registry
        * Add locking at transport level
        * Allow host key policy configuration
    """

    RETRY_EXCEPTIONS = [
        paramiko.ssh_exception.SSHException,
        paramiko.ssh_exception.ChannelException,
        socket.error,
    ]
    RETRY_MAX = 5
    _local = Local()

    @classproperty
    def envs(cls):
        """ It returns the current, or creates new, Environments """
        try:
            return cls._local.environments
        except AttributeError:
            cls.reset()
            return cls._local.environments

    @classmethod
    def reset(cls):
        """ It creates a new set of Environments and scrubs the old """
        _logger.debug('Resetting SSHEnvironment')
        try:
            for env in cls._local.environments:
                env._cleanup()
        except AttributeError:
            pass
        cls._local.environments = SSHEnvironments()

    @contextmanager
    def get_channel(self, retry=True):
        """ It provides context manager yielding a new Paramiko channel """
        try:
            transport = self.client.get_transport()
            with transport.open_session() as channel:
                yield channel
        except tuple(self.RETRY_EXCEPTIONS + [AttributeError]):
            if retry:
                self._connect()
                with self.get_channel(False) as channel:
                    yield channel
            else:
                raise

    def _cleanup(self):
        """ It provides a handler to close existing resources """
        if self.client:
            try:
                self.client.close()
            except:  # pragma: no cover
                _logger.info('Client close failed for %s', self.client)
        self.client = None

    def _connect(self):
        """ It creates an SSH connection to remote node """
        self._cleanup()
        self.client = paramiko.SSHClient()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            self.client.connect(
                self.host,
                port=self.port,
                username=self.username,
                key_filename=os.path.expanduser(self.identity_file),
            )
            self._retry_left = self.RETRY_MAX
        except tuple(self.RETRY_EXCEPTIONS):
            if self._retry_left:
                self._retry_left -= 1
                self._connect()
            else:
                self.client = None
                raise

    def __wrap_method(self, method):
        """ It injects a lock and a reconnect onto the method """
        locked = self.__inject_lock(method)
        return self.__inject_reconnect(locked)

    def __inject_lock(self, method):
        """ It injects a thread lock onto the method """

        def __call_method(*args, **kwargs):
            self._lock.acquire(True)
            try:
                return method(*args, **kwargs)
            finally:
                self._lock.release()

        return __call_method

    def __inject_reconnect(self, method):
        """ It injects a reconnector onto the method """

        def __call_method(*args, **kwargs):
            try:
                return method(*args, **kwargs)
            except tuple(self.RETRY_EXCEPTIONS):
                self._connect()
                return method(*args, **kwargs)

        return __call_method

    def __new__(cls, host, port=22, username=None, identity_file=None,
                connect=True, *args, **kwargs
                ):
        """ It returns a cached SSHEnvironment, or creates a new one.

        The bulk of this method is only called once when the SSHEnvironment
        is instantiated for the first time. Subsequent instantiations will
        return a cached SSHEnvironment & skip the initiatizations.

        Params:
            host: (str) Host or IP of remote node.
            post: (int) Remote SSH port.
            username: (str|None) Username for connection. None for shell
                default.
            identity_file: (str|None) Path to the SSH identity file
            connect: (bool) If a connection should be initiated automatically
        """

        eval_args = (host, port, username, identity_file)

        for env in cls.envs:
            if env._eval_args == eval_args:
                return env

        self = object.__new__(cls, *args, **kwargs)
        cls.envs.add(self)

        self.host = host
        self.port = port
        self.username = username
        self.identity_file = identity_file
        self.client = None
        self._retry_left = self.RETRY_MAX
        self._args = args
        self._kwargs = kwargs
        self._eval_args = eval_args
        self._lock = Lock()

        if connect:
            self._connect()

        return self

    def __init__(self, *args, **kwargs):
        """ It initializes a new SSHEnvironment.

        Note that ``__init__`` will be run the first time an Environment is
        used in a session, regardless of whether it was cached. This method
        currently does nothing, but could be useful for environment prep

        Params:
            host: (str) Host or IP of remote node.
            post: (int) Remote SSH port.
            username: (str|None) Username for connection. None for shell
                default.
            identity_file: (str|None) Path to the SSH identity file
            connect: (bool) If a connection should be initiated automatically
        """
        pass

    def __getattr__(self, key):
        """ Provide passthrough to paramiko Client while locking the conn """
        try:
            return super(SSHEnvironment, self).__getattr__(key)
        except AttributeError:
            pass
        method = getattr(self.client, key)
        if not callable(method):
            return method
        return self.__wrap_method(method)

    def __str__(self):
        """ Allow object rebuilds """
        return '%(class)s(*%(args)r, **%(kwargs)r)' % {
            'class': self.__class__.__name__,
            'args': self._eval_args + self._args,
            'kwargs': self._kwargs,
        }

    def __repr__(self):
        return self.__str__()


"""
Create permission groups
Create permissions (read only) to models for a set of groups
"""
import logging

from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand
from django.contrib.auth.models import Group
from django.contrib.auth.models import Permission

grouppermdict= {
    'Validated User': [
         'auth.view_permission',
         'caserooms.add_caseroom',
         'caserooms.add_caseroomentry',
         'caserooms.change_caseroom',
         'caserooms.change_caseroomentry',
         'caserooms.delete_caseroom',
         'caserooms.delete_caseroomentry',
         'caserooms.view_caseroom',
         'caserooms.view_caseroomentry',
         'oauth2_provider.add_accesstoken',
         'oauth2_provider.delete_accesstoken',
         'oauth2_provider.view_accesstoken',
         'splineapp.add_spinesplinemodel',
         'splineapp.change_spinesplinemodel',
         'splineapp.delete_spinesplinemodel',
         'splineapp.view_spinesplinemodel',
         'users.add_consent',
         'users.add_contribution',
         'users.add_cost',
         'users.change_consent',
         'users.change_contribution',
         'users.change_cost',
         'users.change_user',
         'users.delete_consent',
         'users.delete_contribution',
         'users.delete_cost',
         'users.delete_user',
         'users.view_consent',
         'users.view_contribution',
         'users.view_cost',
         'users.view_user'
    ],
    'Non validated User': [
        'auth.view_permission',
        'oauth2_provider.add_accesstoken',
        'oauth2_provider.delete_accesstoken',
        'oauth2_provider.view_accesstoken',
        'users.add_consent',
        'users.change_consent',
        'users.change_user',
        'users.delete_consent',
        'users.delete_user',
        'users.view_consent',
        'users.view_user'
    ],
    'Staff': [
         'auth.add_permission',
         'auth.change_permission',
         'auth.delete_permission',
         'auth.view_permission',
         'caserooms.add_caseroom',
         'caserooms.add_caseroomentry',
         'caserooms.change_caseroom',
         'caserooms.change_caseroomentry',
         'caserooms.delete_caseroom',
         'caserooms.delete_caseroomentry',
         'caserooms.view_caseroom',
         'caserooms.view_caseroomentry',
         'contenttypes.add_contenttype',
         'contenttypes.change_contenttype',
         'contenttypes.delete_contenttype',
         'contenttypes.view_contenttype',
         'guardian.add_groupobjectpermission',
         'guardian.add_userobjectpermission',
         'guardian.change_groupobjectpermission',
         'guardian.change_userobjectpermission',
         'guardian.delete_groupobjectpermission',
         'guardian.delete_userobjectpermission',
         'guardian.view_groupobjectpermission',
         'guardian.view_userobjectpermission',
         'oauth2_provider.add_accesstoken',
         'oauth2_provider.change_accesstoken',
         'oauth2_provider.delete_accesstoken',
         'oauth2_provider.view_accesstoken',
         'splineapp.add_spinesplinemodel',
         'splineapp.change_spinesplinemodel',
         'splineapp.delete_spinesplinemodel',
         'splineapp.view_spinesplinemodel',
         'users.add_consent',
         'users.add_consentcontent',
         'users.add_contribution',
         'users.add_cost',
         'users.add_user',
         'users.add_userproof',
         'users.change_consent',
         'users.change_consentcontent',
         'users.change_contribution',
         'users.change_cost',
         'users.change_user',
         'users.change_userproof',
         'users.delete_consent',
         'users.delete_consentcontent',
         'users.delete_contribution',
         'users.delete_cost',
         'users.delete_user',
         'users.delete_userproof',
         'users.view_consent',
         'users.view_consentcontent',
         'users.view_contribution',
         'users.view_cost',
         'users.view_user',
         'users.view_userproof'
    ]

}

class Command(BaseCommand):
    help = 'Creates read only default permission groups for users'

    def handle(self, *args, **options):
        for k,v in grouppermdict.items():
            new_group, created = Group.objects.get_or_create(name=k)
            for permission in v:
                app_label=permission.split('.')[0]
                model_name=permission.rsplit('_')[-1]
                permstring=permission.split('.')[1]
                print('Getting Content Type for app {} and model {} with permstring {}'.format(app_label,model_name,permstring))
                content_type = ContentType.objects.get(app_label=app_label, model=model_name)
                print("Creating {}".format(permission))
                try:
                    model_add_perm = Permission.objects.get(codename=permstring, content_type=content_type)
                except Permission.DoesNotExist:
                    logging.warning("**** Permission not found with name '{}'.".format(permission))
                    continue

                new_group.permissions.add(model_add_perm)

        print("Created default group and permissions.")


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pdb

def sigmoid(z):
    z = z.astype(np.float64)
    return 1 / (1 + np.exp(-z))

def costFunction(X, y, weights):
    m = np.size(X,0)
    return (1 / m) * sum(-y * np.log(sigmoid(X.dot(weights))) - (1 - y) * np.log(1 - sigmoid(X.dot(weights))))

def costFunctionDerivative(X, y, weights, alpha):
    #pdb.set_trace()
    m = np.size(X,0)
    activation = sigmoid(X.dot(weights)) - y #Activation function g(z)
    activation = activation.astype(np.float64) #Turn it into float64
    temp_weights = np.copy(weights)

    for j in range(0, np.size(weights)):
        temp_weights[j] = weights[j] - alpha * (1/m) * np.sum((sigmoid(X.dot(weights)) - y) * X[:, j:j+1])
    return temp_weights

def gradientDescent(X, y, weights, alpha, iterations):
    print("Initial cost function: {0}".format(costFunction(X, y, weights)))
    for i in range(0, iterations):
        weights = costFunctionDerivative(X, y, weights, alpha)
    print("Final cost function: {0}".format(costFunction(X,y,weights)))
    return weights

def plotData(data, xAxis, yAxis):
    approved = data[data['approved'].isin([1])] #Students that passed
    ded = data[data['approved'].isin([0])] #Slept with the fishes

    fig, ax = plt.subplots(figsize=(16,9))
    ax.scatter(approved[xAxis], approved[yAxis], s=30, c='b', marker='o', label='approved')
    ax.scatter(ded[xAxis],ded[yAxis], s=30, c='r', marker='x', label='Ded')
    ax.legend()
    ax.set_xlabel(xAxis)
    ax.set_ylabel(yAxis)
    plt.show()

def main():
    #Load data
    headers=['exam1','exam2','approved']
    data = pd.read_csv('ex2data1.txt', names=headers, skipinitialspace=True, quotechar='"')

    #x = passenger class, Fare
    X = pd.DataFrame(data[['exam1','exam2']])
    #X = (X - np.mean(X)) / np.std(X) #Normalizing data
    X.insert(loc=0, column='Bias', value=1) #Adding column of 1's for the bias unit!
    #y = slept with the fishes
    y = data['approved']

    #Initializing weights at 0!
    weights = np.zeros((np.size(X,1),1))

    iterations = 1500
    alpha = 0.001

    #plotData(data, 'exam1', 'exam2')

    #Calculate cost function
    X = np.array(X.values) #Turn X into an ndarray for ease of usage
    y = np.array(y.values) #Turn y into an ndarray for ease of usage
    y = np.reshape(y, [np.size(y),1]) #Reshape it into (size,1) nd array instead of (size,)
    optimized_weights = gradientDescent(X, y, weights, alpha, iterations)

    #Load test data
    test_data = pd.read_csv('ex2data1.txt', names=headers, skipinitialspace=True, quotechar='"')
    test_y = pd.DataFrame(test_data['approved'])
    #x = passenger class, Fare
    X_OPT = pd.DataFrame(test_data[['exam1','exam2']])
    X_OPT.insert(loc=0, column='Bias', value=1) #Adding column of 1's for the bias unit!
    predictions = sigmoid(X_OPT.dot(optimized_weights))
    test_y.insert(loc=0, column='Predictions', value=predictions)
    print(test_y)
    #pdb.set_trace()

    index = 0
    for i in test_y['Predictions']:
        count = 0
        if(i > 0.5 and test_y['approved'][index] == 1):
            count += 1
        elif(i <= 0.5 and test_y['approved'][index] == 0):
            count += 1
        index += 1
    print("Accuracy rate: {0}%".format((count * 100)/np.size(test_data,0)))

    test_features = np.array([[1, 45, 85]], np.float64)
    print("Probability for 45 and 85: {0}%".format(sigmoid(test_features.dot(optimized_weights))))

if __name__ == '__main__':
    main()