from bs4 import BeautifulSoup
import requests
import xlsxwriter

base_trade_url = 'https://www.realmeye.com/offers-by/'

pots = {
    2793: "Life Potion",
    2592: "Defense Potion",
    2591: "Attack Potion",
    2593: "Speed Potion",
    2636: "Dexterity Potion",
    2613: "Wisdom Potion",
    2612: "Vitality Potion",
    2794: "Mana Potion"
}
rev_pots = {v: k for k, v in pots.items()}

# In terms of Speed Pots ETA
pot_values = {
    "Life Potion": 8,
    "Defense Potion": 3,
    "Attack Potion": 3,
    "Speed Potion": 1,
    "Dexterity Potion": 1,
    "Wisdom Potion": 1.2,
    "Vitality Potion": 2,
    "Mana Potion": 5,
}

class Item:
    def __init__(self, item_id, qty):
        self.item_id = item_id
        self.qty = int(qty[1:])
        if item_id in pots.keys():
            self.name = pots[item_id]
            self.worth = self.qty * pot_values[self.name]
        else:
            self.name = 'OTHER_ITEM'
            self.worth = 0

    def __str__(self):
        return f'{self.qty} {self.name}'

class Trade:
    def __init__(self, selling_items, buying_items, qty, added, author, seen, server):
        self.selling_items = selling_items
        self.buying_items = buying_items
        self.qty = qty
        self.added = added
        self.author = author
        self.seen = seen
        self.server = server
        self.selling_worth = sum([i.worth for i in selling_items])
        self.buying_worth = sum(i.worth for i in buying_items)

def getBuyingList(id):
    buying_spd_pots_url = f'https://www.realmeye.com/offers-to/buy/{id}/pots'
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'}
    r = requests.get(buying_spd_pots_url, headers=headers)
    soup = BeautifulSoup(r.content, 'html.parser')

    tbl = soup.find("table", id="g").find("tbody")
    raw_trades = tbl.findAll("tr")

    trades_list = []

    for trade in raw_trades:
        trade_attributes = trade.findAll('td')

        selling_list = trade_attributes[0].findAll('span', {'class': 'item-static'})
        buying_list = trade_attributes[1].findAll('span', {'class': 'item-static'})

        selling_itms = []
        for itm in selling_list:
            data_id = int(itm.find('span', {'class': 'item'})['data-item'])
            data_qt = itm.find('span', {'class': 'item-quantity-static'}).text
            temp_item = Item(data_id, data_qt)
            selling_itms.append(temp_item)

        buying_itms = []
        for itm in buying_list:
            data_id = int(itm.find('span', {'class': 'item'})['data-item'])
            data_qt = itm.find('span', {'class': 'item-quantity-static'}).text
            buying_itms.append(Item(data_id, data_qt))

        trade_qty = trade_attributes[2].find('span')
        trade_added = trade_attributes[3].find('span').text
        trade_author = trade_attributes[5].find('a').text
        trade_seen = trade_attributes[6].find('span')
        trade_server = trade_attributes[7].find('abbr')
        if trade_server is not None:
            trade_server = trade_server.text

        trades_list.append(Trade(selling_itms, buying_itms, trade_qty, trade_added, trade_author, trade_seen, trade_server))
    return trades_list

col_headers = [
    {'header': 'USER'},
    {'header': 'SERVER'},
    {'header': 'SELLING'},
    {'header': 'BUYING'},
    {'header': 'SELLING WORTH'},
    {'header': 'BUYING WORTH'},
    {'header': 'DIFFERENCE'},
]

trades_file = open('trades.txt', 'w')
workbook = xlsxwriter.Workbook('Trades.xlsx')
worksheet = workbook.add_worksheet()

data = []
for pot_type in pots.values():
    trades_list = getBuyingList(rev_pots[pot_type])

    for trade in trades_list:
        buying_items_string = ''
        for item in trade.buying_items:
            if item.name == 'OTHER_ITEM':
                continue
            buying_items_string += f'{item}, '

        selling_items_string = ''
        for item in trade.selling_items:
            if item.name == 'OTHER_ITEM':
                continue
            selling_items_string += f'{item}, '

        user_url = f'{base_trade_url}{trade.author}'
        excel_hyperlink = f'=HYPERLINK(\"{user_url}\",\"{trade.author}\")'

        data.append([excel_hyperlink, trade.server, selling_items_string, buying_items_string, trade.selling_worth,
                     trade.buying_worth, trade.selling_worth - trade.buying_worth])

        printing_string = f'{trade.author}({trade.server}) has {selling_items_string}and wants {buying_items_string}'
        print(printing_string)
        trades_file.write(printing_string + '\n')

worksheet.add_table(0, 0, len(data), len(col_headers) - 1, {'data': data, 'columns': col_headers})
trades_file.close()
workbook.close()


import streamlit as st
import altair as alt
import inspect
from vega_datasets import data

@st.experimental_memo
def get_chart_19705(use_container_width: bool):
    import altair as alt

    source = "https://frdata.wikimedia.org/donationdata-vs-day.csv"

    chart = alt.Chart(source).mark_line().encode(
        alt.X('monthdate(date):T', title='Month', axis=alt.Axis(format='%B')),
        alt.Y('max(ytdsum):Q', title='Cumulative Donations', stack=None),
        alt.Color('year(date):O', legend=alt.Legend(title='Year')),
        alt.Order('year(data):O')
    )

    tab1, tab2 = st.tabs(["Streamlit theme (default)", "Altair native theme"])

    with tab1:
        st.altair_chart(chart, theme="streamlit", use_container_width=True)
    with tab2:
        st.altair_chart(chart, theme=None, use_container_width=True)

try:
    st.expander("See code").code(inspect.getsource(get_chart_19705))
    get_chart_19705(use_container_width=True)
except Exception as e:
    st.exception(e)


import sys
from collections import deque
#sys.stdin = open('input.txt', 'r')

def eat(p, depth):
    visited = [[0 for _ in range(N)] for _ in range(N)]
    q = deque([[p[0], p[1], depth]])
    compare = []
    mind = 401
    visited[p[0]][p[1]] = 1
    while len(q) > 0:
        r, c, d = q.popleft()
        if mind < d:
            break
        if 0 < arr[r][c] <= size-1:
            if len(compare) == 0:
                mind = d
            compare.append([r, c])

        for dr, dc in move:
            if 0 <= r+dr < N and 0 <= c+dc < N:
                if arr[r+dr][c+dc] <= size and not visited[r+dr][c+dc]:
                    visited[r+dr][c+dc] = 1
                    q.append([r+dr, c+dc, d+1])

    if len(compare) == 0:
        return 0

    compare.sort(key=lambda x: (x[0], x[1]))
    fish[arr[compare[0][0]][compare[0][1]]] -= 1
    position[0], position[1] = compare[0][0], compare[0][1]
    arr[compare[0][0]][compare[0][1]] = 0

    return mind

def shark():
    global answer
    global hungry
    global size

    while sum(fish[:min(size, 7)]) > 0:
        distance = eat(position, 0)
        if distance == 0:
            break
        answer += distance
        hungry += 1

        if hungry == size:
            hungry = 0
            size += 1

move = [[-1, 0], [0, -1], [1, 0], [0, 1]]
fish = [0 for i in range(7)]
position = [-1, -1]
size = 2
hungry = 0
answer = 0
arr = []
N = int(input().rstrip())
for i in range(N):
    temp = list(map(int, input().split()))
    arr.append(temp)
    for idx, j in enumerate(temp):
        if j != 0 and j != 9:
            fish[j] += 1
        if j == 9:
            position[0], position[1] = i, idx

arr[position[0]][position[1]] = 0
shark()
print(answer)


import random
import torch
import numpy as np
import argparse
import torch.nn as nn
import torch.optim as optim
import numpy as np
import os
from torchvision import transforms
from torchvision.utils import save_image

#import sys
from utils.dataframe import UCIDatasets
from utils.experiment import exp_imputation
from model.MIWAE import MIWAE
from model.imputer import imputer
from utils.dataframe import dataframe, UCIDatasets
from utils.trainer import VAE_trainer, GAN_trainer
from utils.experiment import *
"""
Use the MIWAE and not-MIWAE on UCI data

Find a data from here
https://archive.ics.uci.edu/ml/datasets.php
"""
parser = argparse.ArgumentParser(description='VAE Example')

parser.add_argument('--batch-size', type=int, default=16, metavar='N',
                    help='input batch size for training (default: 128)')
parser.add_argument('--epochs', type=int, default=100000, metavar='N',
                    help='number of epochs to train (default: 10)')
parser.add_argument('--no-cuda', action='store_true', default=False,
                    help='enables CUDA training')
parser.add_argument('--seed', type=int, default=1, metavar='S',
                    help='random seed (default: 1)')
parser.add_argument('--log-interval', type=int, default=10, metavar='N',
                    help='how many batches to wait before logging training status')
parser.add_argument('--data', type=str, default='whitewine', metavar='N',
                    help='which dataset from UCI would you like to use?')
args = parser.parse_args()
os.environ["CUDA_VISIBLE_DEVICES"] = "0,1"
args.cuda = not args.no_cuda and torch.cuda.is_available()

random.seed(args.seed)
np.random.seed(args.seed)
torch.manual_seed(args.seed)
torch.cuda.manual_seed(args.seed)

device = torch.device("cuda" if args.cuda else "cpu")

kwargs = {'num_workers': 1, 'pin_memory': True} if args.cuda else {}

name = args.data
n_hidden = 128
n_samples = 20
max_iter = args.epochs
batch_size = args.batch_size
impute_sample = 10000

###   the missing model   ###
# mprocess = 'linear'
# mprocess = 'selfmasking'
mprocess = 'selfmasking_known'

# ---- number of runs
runs = 1
RMSE_result = dict()
methods = ['miwae','notmiwae','mean','mice','RF']
for method in methods:
    RMSE_result[method] = []
"""
load data: white wine
"""
data = UCIDatasets(name=name)
N, D = data.N, data.D
dl = D - 1
optim_kwargs = {'lr': 0.0001, 'betas': (0.9, 0.999), 'eps': 1e-08 }
MIWAE_kwargs = {
    'data_dim': D, 'z_dim': dl, 'h_dim': n_hidden, 'n_samples': n_samples
    }
notMIWAE_kwargs = {
    'data_dim': D, 'z_dim': dl, 'h_dim': n_hidden, 'n_samples': n_samples, 'missing_process': mprocess
    }
data_kwargs = {
    'batch_size': batch_size
    }
imputer_par = {
    'missing_values': np.nan, 'max_iter': 10, 'random_state': 0, 'n_estimators': 100, 'n_neighbors': 3, 'metric': 'nan_euclidean'
    }
exp_kwargs = {
    'dataset':name, 'runs':runs, 'seed': args.seed,
}
config = {
    'exp_kwargs': exp_kwargs, 'optim_kwargs': optim_kwargs,
    'MIWAE_kwargs': MIWAE_kwargs, 'notMIWAE_kwargs': notMIWAE_kwargs,
    'data_kwargs': data_kwargs, 'imputer_par': imputer_par,
    }

def main():
    RMSE_result = exp_imputation( 'exp_imputation', model_list = ['miwae', 'notmiwae'], config = config, num_of_epoch = max_iter)

    print("RMSE_miwae = {0:.5f} +- {1:.5f}".format(np.mean(RMSE_result['miwae']), np.std(RMSE_result['miwae'])))
    print("RMSE_notmiwae = {0:.5f} +- {1:.5f}".format(np.mean(RMSE_result['notmiwae']), np.std(RMSE_result['notmiwae'])))
    print("RMSE_mean = {0:.5f} +- {1:.5f}".format(np.mean(RMSE_result['mean']), np.std(RMSE_result['mean'])))
    print("RMSE_mice = {0:.5f} +- {1:.5f}".format(np.mean(RMSE_result['mice']), np.std(RMSE_result['mice'])))
    print("RMSE_missForest = {0:.5f} +- {1:.5f}".format(np.mean(RMSE_result['RF']), np.std(RMSE_result['RF'])))

if __name__ == "__main__":
    main()


#!/usr/bin/python3
"""API for Users"""

from tasks.users import User
from tasks import storage
from api.v1.views import app_views
from flask import jsonify, abort, request, make_response
from flasgger.utils import swag_from

@app_views.route('/users', methods=['GET'], strict_slashes=False)
@swag_from('documentation/users/list_users.yml', methods=['GET'])
def list_users():
    """Retrives the list of all User objects"""
    users = storage.all(User)
    user_list = []
    for user in users:
        user_list.append(user.to_dict())
    return jsonify(user_list)

@app_views.route('/users/by_id/<id>', methods=['GET'], strict_slashes=False)
@swag_from('documentation/users/get_user_id.yml', methods=['GET'])
def get_user_id(id):
    """Retrieves a user by user id"""
    users = storage.get_user_by_id(User, id)
    if not users:
        abort(404)

    return jsonify([user.to_dict() for user in users])

@app_views.route('/users/<email_address>',
                 methods=['GET'], strict_slashes=False)
@swag_from('documentation/users/get_user_email.yml', methods=['GET'])
def get_user_email(email_address):
    """Retrieves a user by user's email_address"""
    users = storage.get_user_by_email(User, email=email_address)
    if not users:
        abort(404)

    return jsonify([users.to_dict()])

@app_views.route('/users/<email_address>',
                 methods=['DELETE'], strict_slashes=False)
@swag_from('documentation/users/delete_user.yml', methods=['DELETE'])
def delete_user(email_address):
    """Deletes user"""
    user = storage.get_user_by_email(User, email=email_address)
    if not user:
        abort(404)

    storage.delete(user)
    return make_response(jsonify({}), 200)

@app_views.route('/users/by_id/<id>',
                 methods=['PUT'], strict_slashes=False)
@swag_from('documentation/users/update_user.yml', methods=['PUT'])
def update_user(id):
    """Update a user"""
    users = storage.get_user_by_id(User, id=id)
    if not users:
        abort(404)

    if not request.get_json():
        abort(400, description="Not a JSON")

    ignore = ['__class__', 'id', 'created_at', 'updated_at']

    data = request.get_json()
    for user in users:
        for key, value in data.items():
            if key not in ignore:
                setattr(user, key, value)

    storage.save()
    users = storage.get_user_by_id(User, id=id)
    for user in users:
        return make_response(jsonify(user.to_dict()), 200)

@app_views.route('/users',
                 methods=['POST'], strict_slashes=False)
@swag_from('documentation/users/create_user.yml', methods=['POST'])
def create_user():
    """Create a new user"""
    if not request.get_json():
        abort(400, description="Not a JSON")

    if 'email_address' not in request.get_json():
        abort(400, description="Missing email address")
    if 'first_name' not in request.get_json():
        abort(400, description="Missing first name")
    if 'last_name' not in request.get_json():
        abort(400, description="Missing last name")

    data = request.get_json()
    new_user = User(**data)
    new_user.save()
    return make_response(jsonify(new_user.to_dict()), 201)


from django.shortcuts import render
import json
from django.http import HttpResponse
from django.http import JsonResponse
from .models import ServerCategorys,ServerPosts,Keywords,Aquestions,Attachments,Centers
from school.models import Schools
from major.models import Majors

# Create your views here.
#服务中心文章列表展示
def serverpostsList(request):
    server_post =ServerPosts .objects.filter(is_status=1)
    context ={'server_post':server_post}
    return render(request,'server/server_posts_list.html',context=context)

#查看服务文章详情
def detailserPos(request):
    ser_pos_id = request.POST.get('ser_pos_id',None)
    ser_posts = ServerPosts.objects.get(id=ser_pos_id)
    return render(request,'server/detail_ser_pos.html',context={'ser_posts':ser_posts})

#添加新服务文章:获取新页面
def addserPos(request):
    ques_school = Schools.objects.filter(is_status=1)
    cateid=ServerCategorys.objects.filter(is_status=1)
    keywords=Keywords.objects.all()
    context = {
        'ques_school': ques_school,
        'cateid': cateid,
        'keywords':keywords
    }
    return render(request, 'server/add_ser_pos.html',context=context)

#添加新服务文章，上传数据，除了标题外，都可不填
def addssserPos(request):
    #获取data的数据
    data = request.POST.get('data', None)
    data = json.loads(data)
    # print(data['post_school'])
    # 判断文章标题是否存在
    info = ServerPosts.objects.filter(post_title=data['post_title'], is_status=1).exists()
    if info:
        return JsonResponse({
            'status': 'fail',
            'message': '该服务文章已存在！',
            'info': ''
        })
    ServerPosts.objects.create(
        post_title=data['post_title'],
        source='舟炬教育' if data['source']=='' else data['source'],
        source_link='http://www.zhoujuedu.com' if data['source_link']=='' else data['source_link'],
        #这几项是外键的id如果不填，会报错，都给个默认值id吧
        #但是major的外键id不填却可以，什么原因呢
        cateid_id='1' if data['cateid']==' ' else data['cateid'],
        keywords_id='8' if data['keywords']==' ' else data['keywords'],
        server_post_school_id='11' if data['server_post_school']==' ' else data['server_post_school'],
        post_content=data['post_content'],
    )
    return JsonResponse({
        'status': 'success',
        'message': '创建成功',
        'info': ''
    })

#删除服务文章，其实是把status变为0
def delserPos(request):
    ser_pos_id=request.GET.get('ser_pos_id')
    ser_posts = ServerPosts.objects.get(id=ser_pos_id)
    context={'ser_posts':ser_posts}
    is_status = 0
    ser_posts.is_status = is_status
    ser_posts.save()
    return render(request, 'server/server_posts_list.html', context=context)

#编辑服务文章:接收数据
def editserPos(request):
    ser_pos_id = request.GET.get('ser_pos_id',None)
    ser_posts = ServerPosts.objects.get(id=ser_pos_id)
    ser_school = Schools.objects.filter(is_status=1).exclude(name=ser_posts.server_post_school.name)
    cateid = ServerCategorys.objects.filter(is_status=1).exclude(server_name=ser_posts.cateid.server_name)
    keywords = Keywords.objects.exclude(key_name=ser_posts.keywords.key_name)
    context = {
        'ser_posts':ser_posts,
        'ser_school':ser_school,
        'cateid':cateid,
        'keywords':keywords
    }
    return render(request,'server/edit_ser_pos.html',context=context)

#编辑服务文章:上传数据
def updateserPos(request):
    # 接收数据
    ser_pos_id = request.POST.get("ser_pos_id",None)

    '''处理数据'''
    data = request.POST.get('data',None)
    data = json.loads(data)

    '''对数据进行处理'''
    pos = ServerPosts.objects.filter(id=ser_pos_id)
    pos.update(**data)

    return HttpResponse(123)

#服务中心分类展示
def serverCates(request):
    server_cates =ServerCategorys .objects.filter(is_status=1)
    context ={'server_cates':server_cates}
    return render(request,'server/server_cates.html',context=context)

#添加服务中心分类:获取新页面
def addserCates(request):
    return render(request, 'server/add_ser_cates.html')

#添加新服务分类：上传数据，名称不允许为空，不允许重复
def addssserCates(request):
    server_name = request.POST.get('server_name')
    # 判断是否存在
    info = ServerCategorys.objects.filter(server_name=server_name).exists()
    if info:  # 如果为true，控制台返回值
        return JsonResponse({
            'status': 'fail',
            'message': '当前分类已存在',#在html写了框，没有用到这个
            'tagid': 'server_name'
        })
    # 如果不存在就增加数据
    ServerCategorys.objects.create(
        server_name=server_name,
    )
    return JsonResponse({
        'status': 'success',
        'message': '创建成功',
        'info': ''
    })

#删除服务分类，其实是把status变为0
def delserCates(request):
    ser_cates_id=request.GET.get('ser_cates_id')
    ser_cates = ServerCategorys.objects.get(id=ser_cates_id)
    context={'ser_cates':ser_cates}
    is_status = 0
    ser_cates.is_status = is_status
    ser_cates.save()
    return render(request, 'server/server_cates.html', context=context)

#编辑服务分类:接收数据
def editserCates(request):
    ser_cates_id = request.GET.get('ser_cates_id',None)
    ser_cates = ServerCategorys.objects.get(id=ser_cates_id)
    context = {
        'ser_cates':ser_cates,
    }
    return render(request,'server/edit_ser_cates.html',context=context)

#编辑服务分类:上传数据
def updateserCates(request):
    # 接收数据
    data = request.POST.get('data', None)
    ser_cateid = request.POST.get("ser_cateid",None)
    data = json.loads(data)
    ser_cates = ServerCategorys.objects.get(id=ser_cateid)

    if data['server_name'] != '':
        ser_cates.server_name = data['server_name']
    ser_cates.save()
    return JsonResponse({
        "status": "success",
        "message": "更改成功",
        "info": ""
    })

#教学中心列表展示
def servercenterList(request):
    center =Centers .objects.filter(is_status=1)
    context ={'center':center}
    return render(request,'server/server_center_list.html',context=context)

#查看教学中心详情
def detailserCenter(request):
    ser_cen_id = request.POST.get('ser_cen_id',None)
    ser_center = Centers.objects.get(id=ser_cen_id)
    return render(request,'server/detail_ser_center.html',context={'ser_center':ser_center})

#添加教学中心:获取新页面
def addserCenter(request):
    return render(request, 'server/add_ser_center.html')

#添加教学中心:上传数据,名称和编号不能为空
def addssserCenter(request):
    cen_name = request.POST.get('cen_name')
    cen_num=request.POST.get('cen_num')
    address = request.POST.get('address',None)
    phone = request.POST.get('phone',None)
    is_direct=request.POST.get('is_direct',None)
    #判断教学中心名称或编号是否存在
    info = Centers.objects.filter(cen_name=cen_name,is_status=1).exists()
    info2 = Centers.objects.filter(cen_num=cen_num,is_status=1).exists()
    # print(info)
    if info or info2:
        return JsonResponse({
            'status': 'fail',
            'message': '教学中心或编号已存在！',#在html写了框，没有用到这个
            'info': ''
        })
    Centers.objects.create(
        cen_name=cen_name,
        cen_num=cen_num,    #因为字段是int，导致如果为空会报错
        address=address,
        phone=phone,
        is_direct=is_direct,
    )
    return JsonResponse({
        'status': 'success',
        'message': '创建成功',
        'info': ''
    })

#删除教学中心，其实是把status变为0
def delserCenter(request):
    ser_center_id=request.GET.get('ser_center_id')
    ser_center = Centers.objects.get(id=ser_center_id)
    context={'ser_center':ser_center}
    is_status = 0
    ser_center.is_status = is_status
    ser_center.save()
    return render(request, 'server/server_center_list.html', context=context)

#编辑教学中心:接收数据
def editserCenter(request):
    ser_center_id = request.GET.get('ser_center_id',None)
    ser_center = Centers.objects.get(id=ser_center_id)
    context = {
        'ser_center':ser_center,
    }
    return render(request,'server/edit_ser_center.html',context=context)

#编辑教学中心:上传数据
def updateserCenter(request):
    # 接收数据
    ser_center_id = request.POST.get("ser_center_id",None)

    '''处理数据'''
    data = request.POST.get('data',None)
    data = json.loads(data)

    '''对数据进行处理'''
    cen = Centers.objects.filter(id=ser_center_id)
    cen.update(**data)

    return HttpResponse(123)

#附件表展示
def serverAtta(request):
    atta =Attachments .objects.filter(is_status=1)
    context ={'atta':atta}
    return render(request,'server/server_atta.html',context=context)

#查看附件详情
def detailserAtta(request):
    ser_atta_id = request.POST.get('ser_atta_id',None)
    ser_atta = Attachments.objects.get(id=ser_atta_id)
    return render(request,'server/detail_ser_atta.html',context={'ser_atta':ser_atta})

#添加附件:获取新页面
def addserAtta(request):
    return render(request, 'server/add_ser_atta.html')

#添加附件:上传数据,都不能为空
def addssserAtta(request):
    atta_name = request.POST.get('atta_name')
    filename=request.POST.get('filename')
    #判断是否存在
    info = Attachments.objects.filter(atta_name=atta_name,filename=filename).exists()
    # print(info)
    if info:
        return JsonResponse({
            'status': 'fail',
            'message': '附件已存在！',#在html写了框，没有用到这个
            'info': ''
        })
    Attachments.objects.create(
        atta_name=atta_name,
        filename=filename,
    )
    return JsonResponse({
        'status': 'success',
        'message': '创建成功',
        'info': ''
    })

#删除附件，其实是把status变为0
def delserAtta(request):
    ser_atta_id=request.GET.get('ser_atta_id')
    ser_atta = Attachments.objects.get(id=ser_atta_id)
    context={'ser_atta':ser_atta}
    is_status = 0
    ser_atta.is_status = is_status
    ser_atta.save()
    return render(request, 'server/server_atta.html', context=context)

#编辑附件:接收数据
def editserAtta(request):
    ser_atta_id = request.GET.get('ser_atta_id',None)
    ser_atta = Attachments.objects.get(id=ser_atta_id)
    context = {
        'ser_atta':ser_atta,
    }
    return render(request,'server/edit_ser_atta.html',context=context)

#编辑附件:上传数据
def updateserAtta(request):
    # 接收数据
    data = request.POST.get('data', None)
    ser_attaid = request.POST.get("ser_attaid",None)
    data = json.loads(data)
    ser_atta = Attachments.objects.get(id=ser_attaid)

    if data['atta_name'] != '':
        ser_atta.atta_name = data['atta_name']
    if data['filename'] != '':
        ser_atta.filename = data['filename']
    ser_atta.save()
    return JsonResponse({
        "status": "success",
        "message": "更改成功",
        "info": ""
    })

#模拟题表展示
def serverAques(request):
    aques =Aquestions .objects.filter(is_status=1)
    context ={'aques':aques}
    return render(request,'server/server_aques.html',context=context)

#查看模拟题附件详情
def detailserAqu(request):
    ser_aqu_id = request.POST.get('ser_aqu_id',None)
    ser_aqu = Aquestions.objects.get(id=ser_aqu_id)
    return render(request,'server/detail_ser_aqu.html',context={'ser_aqu':ser_aqu})

#添加新模拟题:获取新页面,五项都不允许为空
def addserAqu(request):
    que_school = Schools.objects.filter(is_status=1)
    context = {
        'ques_school': que_school,
    }
    return render(request, 'server/add_ser_aqu.html',context=context)

#获取院校id，反向获取到专业信息表的所有院校对应专业id（无重复名称的）
def get_maj(request):
    schid = request.POST.get('schid',None)
    info = Majors.objects.filter(school_id=schid,is_status=1)
    # print(info)
    # list = []
    # for item in info.all():
    #     list.append([item.id,item.major_name])

    lis = []
    lis2=[]
    for ite in info.all():
        if ite.major_name not in lis:
            lis.append(ite.major_name)
    print(lis)
    for i in lis:
        info1 = Majors.objects.filter(major_name=i).first()
        # print(info1.id)
        lis2.append(info1.id)
    print(lis2)
    #接下来就是把列表合并为一个，就可
    listss =[]
    lists = list(zip(lis2, lis))
    for item in lists:
        listss.append([item[0], item[1]])
    return JsonResponse({'data':listss})

#通过专业列表的id，得到专业名，再得到专业名和院校id匹配到的所有层次
def get_lev(request):
    majid = request.POST.get('majid',None)
    school =request.POST.get('school',None)
    # print(school)
    info = Majors.objects.get(id=majid)
    info2 = Majors.objects.filter(major_name=info.major_name,school_id=school,is_status=1)
    # print(info2)
    list = []
    for item in info2.all():
        level = ''
        if item.level == 0:
            level = '高起专'
        elif item.level == 1:
            level = '高起本'
        elif item.level == 2:
            level = '专升本'
        list.append([item.level, level])
    return JsonResponse({'data': list})

#添加模拟题:上传数据,都不能为空
def addssserAqu(request):
    ques_name = request.POST.get('ques_name')
    ques_filename=request.POST.get('ques_filename')
    ques_school = request.POST.get('ques_school')
    ques_major = request.POST.get('ques_major')
    ques_level = request.POST.get('ques_level')  #实际取到的值是0/1/2，并不能传入

    #判断是否存在
    info = Aquestions.objects.filter(ques_name=ques_name,ques_filename=ques_filename,is_status=1).exists()
    # print(info)
    if info or ques_school==' ' or ques_major==' ' or ques_level==' ':
        return JsonResponse({
            'status': 'fail',
            'message': '模拟题已存在或必填项未填写！',#在html写了框，没有用到这个
            'info': ''
        })
    # 专业id获取名称，通过名称和输入框传来的层次值（精确些还需要筛选order_school这个条件），查找到专业的id及其层次id
    mjid = Majors.objects.get(id=ques_major)
    qu_level=Majors.objects.get(major_name=mjid.major_name,level=ques_level,school_id=ques_school)
    # print(qu_level.id,qu_level.major_name)
    Aquestions.objects.create(
        ques_name=ques_name,
        ques_filename=ques_filename,
        ques_school_id=ques_school,
        ques_major_id=ques_major,
        ques_level_id=qu_level.id
    )
    return JsonResponse({
        'status': 'success',
        'message': '创建成功',
        'info': ''
    })

#删除模拟题，其实是把status变为0
def delserAqu(request):
    ser_aqu_id=request.GET.get('ser_aqu_id')
    ser_aqu = Aquestions.objects.get(id=ser_aqu_id)
    context={'ser_aqu':ser_aqu}
    is_status = 0
    ser_aqu.is_status = is_status
    ser_aqu.save()
    return render(request, 'server/server_aques.html', context=context)

#编辑模拟题附件:接收数据
#相同学校，相同专业名，不同层次，使之只显示一次专业名
def editserAqu(request):
    ser_aqu_id = request.GET.get('ser_aqu_id',None)
    ser_aqu = Aquestions.objects.get(id=ser_aqu_id)
    #下拉出的学校和专业列表，不包含is_status=0的，和当前这条数据的学校名和专业名
    ques_school = Schools.objects.filter(is_status=1).exclude(name=ser_aqu.ques_school.name)
    ques_major = Majors.objects.filter(is_status=1).exclude(major_name =ser_aqu.ques_major.major_name)
    majors = Majors.objects.filter(major_name=ser_aqu.ques_major.major_name,school_id=ser_aqu.ques_school.id,is_status=1).exclude(level=ser_aqu.ques_level.level)
    q_mj = Majors.objects.values('major_name').distinct().filter(is_status=1).exclude(major_name =ser_aqu.ques_major.major_name)
    q_mj_lis = []
    for i in q_mj:
        # print(i['major_name'])  #再通过名字和school_id取到符合条件的第一个
        q_mj2 = Majors.objects.filter(major_name=i['major_name'],school_id=ser_aqu.ques_school.id).first()
        if q_mj2 !=None:
            q_mj_lis.append(q_mj2)
    # print(q_mj_lis)
    context = {
        'ser_aqu':ser_aqu,
        'ques_school':ques_school,
        'ques_major':ques_major,
        'q_mj_lis':q_mj_lis,
        'majors':majors,
    }
    return render(request,'server/edit_ser_aqu.html',context=context)

#编辑模拟题附件：上传数据
def updateserAqu(request):
    # 获取数据
    data = request.POST.get('data', None)
    ser_aquid = request.POST.get('ser_aquid', None)

    data = json.loads(data)
    aqu = Aquestions.objects.get(id=ser_aquid)
    if data['ques_school'] != '':
        aqu.ques_school = Schools.objects.get(id=data['ques_school'])
        if data['ques_major'] != '':
            aqu.ques_major = Majors.objects.get(id=data['ques_major'])
            if data['ques_level'] !='':
                #data['ques_level']得到的值其实是0/1/2
                # print(mj.major_name)
                # print(data['ques_level'])
                mj =Majors.objects.get(id=data['ques_major'])
                aqu.ques_level = Majors.objects.get(major_name=mj.major_name,level=data['ques_level'],school_id=data['ques_school'])
                # print(aqu.ques_level)

    if data['ques_name'] != '':
        aqu.ques_name = data['ques_name']

    if data['ques_filename'] != '':
        aqu.ques_filename = data['ques_filename']

    aqu.save()
    return JsonResponse({
        "status": "success",
        "message": "信息更改成功",
        "info": ""
    })

#已删除服务中心文章列表展示
def deldserPos(request):
    server_post =ServerPosts .objects.filter(is_status=0)
    context ={'server_post':server_post}
    return render(request,'server/deld_ser_pos.html',context=context)

#已删除服务中心分类展示
def deldserCates(request):
    server_cates =ServerCategorys .objects.filter(is_status=0)
    context ={'server_cates':server_cates}
    return render(request,'server/deld_ser_cates.html',context=context)

#已删除教学中心列表展示
def deldserCenter(request):
    center =Centers .objects.filter(is_status=0)
    context ={'center':center}
    return render(request,'server/deld_ser_center.html',context=context)

#已删除附件表展示
def deldserAtta(request):
    atta =Attachments .objects.filter(is_status=0)
    context ={'atta':atta}
    return render(request,'server/deld_ser_atta.html',context=context)

#已删除模拟题表展示
def deldserAqu(request):
    aques =Aquestions .objects.filter(is_status=0)
    context ={'aques':aques}
    return render(request,'server/deld_ser_aqu.html',context=context)

#还原服务文章，其实是把status变为1
def posserPos(request):
    ser_pos_id=request.GET.get('ser_pos_id')
    ser_posts = ServerPosts.objects.get(id=ser_pos_id)
    context={'ser_posts':ser_posts}
    is_status = 1
    ser_posts.is_status = is_status
    ser_posts.save()
    return render(request, 'server/deld_ser_pos.html', context=context)

#还原服务分类，其实是把status变为1
def catesserCates(request):
    ser_cates_id=request.GET.get('ser_cates_id')
    ser_cates = ServerCategorys.objects.get(id=ser_cates_id)
    context={'ser_cates':ser_cates}
    is_status = 1
    ser_cates.is_status = is_status
    ser_cates.save()
    return render(request, 'server/deld_ser_cates.html', context=context)

#还原教学中心，其实是把status变为1
def centerserCenter(request):
    ser_center_id=request.GET.get('ser_center_id')
    ser_center = Centers.objects.get(id=ser_center_id)
    context={'ser_center':ser_center}
    is_status = 1
    ser_center.is_status = is_status
    ser_center.save()
    return render(request, 'server/deld_ser_center.html', context=context)

#还原附件，其实是把status变为1
def attaserAtta(request):
    ser_atta_id=request.GET.get('ser_atta_id')
    ser_atta = Attachments.objects.get(id=ser_atta_id)
    context={'ser_atta':ser_atta}
    is_status = 1
    ser_atta.is_status = is_status
    ser_atta.save()
    return render(request, 'server/deld_ser_atta.html', context=context)

#还原模拟题，其实是把status变为1
def aquserAqu(request):
    ser_aqu_id=request.GET.get('ser_aqu_id')
    ser_aqu = Aquestions.objects.get(id=ser_aqu_id)
    context={'ser_aqu':ser_aqu}
    is_status = 1
    ser_aqu.is_status = is_status
    ser_aqu.save()
    return render(request, 'server/deld_ser_aqu.html', context=context)

#永久删除服务文章，删除存在数据库的信息
def delesserPos(request):
    #获取id
    ser_pos_id = request.GET.get('ser_pos_id')
    ser_posts = ServerPosts.objects.get(id=ser_pos_id)
    context = {'ser_posts': ser_posts}
    ServerPosts.objects.get(id=ser_pos_id).delete()
    return render(request,'server/deld_ser_pos.html',context=context)

#永久删除服务分类，删除存在数据库的信息
def delesserCates(request):
    #获取id
    ser_cates_id = request.GET.get('ser_cates_id')
    ser_cates = ServerCategorys.objects.get(id=ser_cates_id)
    context = {'ser_cates': ser_cates}
    ServerCategorys.objects.get(id=ser_cates_id).delete()
    return render(request,'server/deld_ser_cates.html',context=context)

#永久删除教学中心，删除存在数据库的信息
def delesserCenter(request):
    #获取id
    ser_center_id = request.GET.get('ser_center_id')
    ser_center = Centers.objects.get(id=ser_center_id)
    context = {'ser_center': ser_center}
    Centers.objects.get(id=ser_center_id).delete()
    return render(request,'server/deld_ser_center.html',context=context)

#永久删除附件，删除存在数据库的信息
def delesserAtta(request):
    #获取id
    ser_atta_id = request.GET.get('ser_atta_id')
    ser_atta = Attachments.objects.get(id=ser_atta_id)
    context = {'ser_atta': ser_atta}
    Attachments.objects.get(id=ser_atta_id).delete()
    return render(request,'server/deld_ser_atta.html',context=context)

#永久删除模拟题附件，删除存在数据库的信息
def delesserAqu(request):
    #获取id
    ser_aqu_id = request.GET.get('ser_aqu_id')
    ser_aqu = Aquestions.objects.get(id=ser_aqu_id)
    context = {'ser_aqu': ser_aqu}
    Aquestions.objects.get(id=ser_aqu_id).delete()
    return render(request,'server/deld_ser_aqu.html',context=context)


# Import Package
import matplotlib.pyplot as plt
import time

# membuat fungsi integral
def funcSingle(x):
    return (5*x**7) - (9*x**4) + (4*x) - 2

def funcDouble(x, y):
    return (5*x**7) - (9*y**4) + (4*x) - 2

def funcTriple(x, y, z):
    return (5*x**7) - (9*y**4) + (4*z) - 2

# Nilai Exact
lipat1 = 234880.40
lipat2 = 328064.80
lipat3 = 656401.60

# mendeklarasikan rumus perhitungan
def trapezoidSingle(a, b, n):
    h = float(b-a)/n
    hA = h
    result = 0.5*funcSingle(a) + 0.5*funcSingle(b)
    for i in range(n):
        result += funcSingle(a + i*h)
    result *= hA
    return result

def trapezoidDouble(a, b, c, d, n):
    dx = (b - a) / n
    dy = (d - c) / n
    hA = dx * dy
    I = funcDouble(a, c) + funcDouble(b, d)
    for i in range(n):
        for j in range(n):
            xx = a + i * dx
            yy = c + j * dy
            I += funcDouble(xx, yy)
    I *= hA
    return I

def trapezoidTriple(a, b, c, d, g, h, n):
    dx = (b - a) / n
    dy = (d - c) / n
    dz = (h - g) / n
    hA = dx * dy * dz
    I = funcTriple(a, c, g) + funcTriple(b, d, h)
    for i in range(n):
        for j in range(n):
            for k in range(n):
                xx = a + i * dx
                yy = c + j * dy
                zz = g + k * dz
                I += funcTriple(xx, yy, zz)
    I *= hA
    return I

# Memanggil fungsi
mulaiSingleTrapezoid = time.time()
numericalSingleTrapezoid = trapezoidSingle(3, 5, 100)
stopSingleTrapezoid = time.time()
waktuSingleTrapezoid = stopSingleTrapezoid - mulaiSingleTrapezoid

mulaiDoubleTrapezoid = time.time()
numericalDoubleTrapezoid = trapezoidDouble(3, 5, 7, 9, 100)
stopDoubleTrapezoid = time.time()
waktuDoubleTrapezoid = stopDoubleTrapezoid - mulaiDoubleTrapezoid

mulaiTripleTrapezoid = time.time()
numericalTripleTrapezoid = trapezoidTriple(3, 5, 7, 9, 11, 13, 100)
stopTripleTrapezoid = time.time()
waktuTripleTrapezoid = stopTripleTrapezoid - mulaiTripleTrapezoid

print('\nSingle Trapezoid Integration :', numericalSingleTrapezoid)
print('Waktu Komputasi Single Trapezoid :', waktuSingleTrapezoid)
print('Error Single Trapezoid :', ((lipat1 - numericalSingleTrapezoid)/numericalSingleTrapezoid))

print('\nDouble Trapezoid Integration :', numericalDoubleTrapezoid)
print('Waktu Komputasi Double Trapezoid :', waktuDoubleTrapezoid)
print('Error Single Trapezoid :', ((lipat2 - numericalDoubleTrapezoid)/numericalDoubleTrapezoid))

print('\nDouble Trapezoid Integration :', numericalTripleTrapezoid)
print('Waktu Komputasi Triple Trapezoid :', waktuTripleTrapezoid)
print('Error Single Trapezoid :', ((lipat3 - numericalTripleTrapezoid)/numericalTripleTrapezoid))

# Plotting grafik komparasi waktu komputasi dengan jumlah N
data = {'Lipat-1':waktuSingleTrapezoid, 'Lipat-2':waktuDoubleTrapezoid, 'Lipat-3':waktuTripleTrapezoid}
parameter = list(data.keys())
nilai = list(data.values())
plt.bar(parameter, nilai, color='green', width=0.3)
plt.title('Grafik Waktu Komputasi Integrasi Metode Trapezoid')
plt.xlabel('Integal Lipat')
plt.ylabel('Waktu Komputasi')
plt.show()


from itertools import product
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler

class Dataset:
    def __init__(self, protein, fitxer, model_target='tetramers', randomize_fce=False,
                 chosen_features=('full_fce', 'avg'), score='Median_intensity',
                 selected_tetramers=(0, 1, 2, 3, 4, 5, 6, 7, 8), weighted=False):

        self.protein = protein
        self.pbm35 = fitxer

        if weighted:
            self.pbm35 = self.pbm35[["ID_REF", "VALUE", 'WEIGHT']]
            self.pbm35.columns = ["ID_REF", "VALUE", 'WEIGHT']
        else:
            self.pbm35 = self.pbm35[["ID_REF", "VALUE"]]
            self.pbm35.columns = ["ID_REF", "VALUE"]
        self.pbm35 = self.pbm35.dropna()

        inv_seq_data = self.pbm35.copy()
        inv_seq_data["ID_REF"] = inv_seq_data["ID_REF"].apply(self.inv_seq)
        self.pbm35 = pd.concat([self.pbm35, inv_seq_data])
        self.pbm35.reset_index(inplace=True)
        self.electrostatic, self.tetra_avg, self.tetra_fce, self.tetra_fce_reduced, self.onehot_1mer, self.integer, \
            self.presence_tetra, self.mgw = 8 * [None]

        self.feats = chosen_features
        self.score = score
        self.selected_tetramers = selected_tetramers
        self.randomize = randomize_fce
        self.model_target = model_target           # TODO include inverse sequences as well

        # Get list of all kmers for indices purposes
        self.sequences = list(self.pbm35["ID_REF"])
        self.p = len(self.sequences[0])

        # Get list of all tetramers per each octamer in order to get features
        self.featurize()

    def __str__(self):
        return f"{self.model_target}-based dataset for protein {self.protein} using features {self.feats}"

    def featurize(self):
        """
        Computing all features as specified in the constructor,
        and setting them as the respective attributes
        :return: None
        """
        tetra_fce = {line.split()[0]: np.array([float(x) for x in line.split()[1:]])
                     for line in open('fce_tetramer.dat')
                     if 'SHIFT' not in line}
        if 'avg' in self.feats:
            tetra_avg = {line.split()[0]: np.array([float(x) for x in line.split()[1:]])
                         for line in open('avg_tetramer.dat')
                         if 'SHIFT' not in line}
            self.tetra_avg = np.array([np.concatenate([tetra_avg[otmer[i:i+4]] for i in self.selected_tetramers])
                                       for otmer in self.sequences])
        if 'full_fce' in self.feats or 'diagonal_fce' in self.feats:
            if self.randomize:
                keys = list(tetra_fce.keys())
                permut_keys = np.random.permutation(keys)
                tetra_fce = {key: tetra_fce[val] for key, val in zip(keys, permut_keys)}
            self.tetra_fce = np.array([np.concatenate([tetra_fce[otmer[i:i+4]] for i in self.selected_tetramers])
                                       for otmer in self.sequences])
        # We might want to scramble the matchings to do 'negative control',
        # i.e., remove all physical information from the dataset
        # Let's also keep track of the reduced matrix
        if 'diagonal_fce' in self.feats:
            tetra_fce_reduced = {tt: tetra_fce[tt][list(range(0, 36, 7))] for tt in tetra_fce.keys()}
            self.tetra_fce_reduced = np.array([np.concatenate([tetra_fce_reduced[otmer[i:i+4]]
                                                               for i in self.selected_tetramers])
                                               for otmer in self.sequences])
        if 'onehot_1mer' in self.feats:
            # self.onehot_1mer = np.array([self.onehot_encoding(otmer) for otmer in self.sequences]).astype(np.int8)
            self.onehot_1mer = np.array([self.onehot_encoding(otmer) for otmer in self.sequences])
        if 'integer' in self.feats:
            # define encoding input values
            nucleotides = product('ACGT', repeat=4)
            char_to_int = dict((''.join(c), i) for i, c in enumerate(nucleotides))
            self.integer = np.array([[char_to_int[otmer[i:i+4]] for i in self.selected_tetramers]
                                     for otmer in self.sequences]).astype(int)
        if 'presence_tetramer' in self.feats:
            self.presence_tetra = np.array([self.presence(otmer, 4) for otmer in self.sequences]).astype(np.int8)
        #####
        if 'mgw' in self.feats:
            self.mgw = {line.split()[0]: [float(x) for x in line.split()[1:]]
                        for line in open('mgw_rohs.txt')
                        if 'SHIFT' not in line}
            self.mgw = np.array([np.concatenate([self.mgw[otmer[i:i+4]] for i in self.selected_tetramers])
                                 for otmer in self.sequences])

        if 'electrostatic' in self.feats:
            self.electrostatic = {line.split()[0]: [x for x in line.split()[1:]]
                                  for line in open('electrostatic.txt')
                                  if 'SHIFT' not in line}
            self.electrostatic = np.array([np.concatenate([self.electrostatic[otmer[i:i+4]]
                                                           for i in self.selected_tetramers])
                                           for otmer in self.sequences])

    @staticmethod
    def onehot_encoding(sequence):
        """
        Converts a sequence to a one-hot-encoded binary vector
        :param sequence: str, the DNA sequence to encode
        :return: np.array
        """
        # define encoding input values
        nucleotides = 'ACGT'
        # define mapping of chars to integers and viceversa
        char_to_int = dict((c, i) for i, c in enumerate(nucleotides))
        # integer encode input data
        integer_encoded = [char_to_int[char] for char in sequence]
        # one hot encode
        onehot_encoded = list()
        for value in integer_encoded:
            letter = [0 for _ in range(len(nucleotides))]
            letter[value] = 1
            onehot_encoded.extend(letter)
        return np.array(onehot_encoded)

    @staticmethod
    def presence(sequence, k):
        """
        Converts a sequence to a vector of "presence" features that specifies the count of
        a given k-mer occurrences in the sequence; the output vector has length 4**k
        :param sequence: str, the DNA sequence to encode
        :param k: int, length of the k-mers that will be counted
        :return: np.array
        """
        kmers = np.zeros(4**k)
        positions = {''.join(x): n for n, x in enumerate(list(product('ACTG', repeat=k)))}
        for i in range(len(sequence)-k+1):
            kmers[positions[sequence[i:i+k]]] += 1
        return kmers

    @property
    def scores(self):
        """
        Yields the selected target values/affinity scores, normalized to numbers between 0 and 1
        :return: np.array
        """
        keyw = "VALUE" if self.score == 'Median_intensity' else "Z-score"
        if self.model_target == "octamers":
            vals = self.pbm35[keyw].values
            return MinMaxScaler().fit_transform(vals.reshape(-1, 1))
        elif self.model_target == "tetramers":
            mean_scores = self.mean_score()
            vals = np.array([[mean_scores[i][otmer[i:i+4]] for i in self.selected_tetramers]
                             for otmer in self.sequences])
            return MinMaxScaler().fit_transform(vals)

    @staticmethod
    def inv_seq(seq):
        """
        Yields the complementary DNA sequence in the same 5'->3' direction
        :param seq: str, the DNA sequence
        :return: str
        """
        complementary = {"A": "T", "T": "A", "C": "G", "G": "C"}
        return ''.join([complementary[x] for x in seq[::-1]])

    @property
    def features(self):
        """
        Returns the combined matrix of features, pasted from individual pre-calculated attributes
        :return: np.array
        """
        avail = {'avg': 'tetra_avg', 'full_fce': 'tetra_fce', 'diagonal_fce': 'tetra_fce_reduced',
                 'onehot_1mer': 'onehot_1mer', 'integer': 'integer', 'presence_tetramer': 'presence_tetra',
                 'mgw': 'mgw', 'electrostatic': 'electrostatic'}
        return np.hstack([self.__getattribute__(avail[feat]) for feat in self.feats])

    def mean_score(self):
        """
        Generates a list of dictionaries, each containing the position-wise
        score per tetramer
        :return: list of dicts with {str: float} mappings
        """
        keyw = "VALUE" if self.score == 'Median_intensity' else "Z-score"
        if self.model_target == "tetramers":
            expt_scores = self.pbm35[keyw].values
            from collections import defaultdict
            position_scores = [defaultdict(lambda: 0) for _ in range(self.p - 3)]
            position_counts = [defaultdict(lambda: 0) for _ in range(self.p - 3)]
            for seq, score in zip(self.sequences, expt_scores):
                for i in range(self.p - 3):
                    position_scores[i][seq[i:i+4]] += score
                    position_counts[i][seq[i:i+4]] += 1
        else:
            raise NotImplementedError
        return [{ttmer: position_scores[i][ttmer]/position_counts[i][ttmer]
                 for ttmer in position_scores[i].keys()} for i in range(self.p - 3)]


import sys
from typing import Any
# I cant help but wonder how much overhead is added by including QObject, pyqtSignal, and QWidget solely for type hinting
from PyQt5.QtCore import QObject, Qt, pyqtSignal
from PyQt5.QtWidgets import QAction, QLayout, QStyleFactory, QWidget, QApplication, QMainWindow

from utilities.Common import wrapper

def addAllActionsToObject(parent, obj):
	""" Find all QActions whose parent is ``self`` and call ``obj.addAction()`` for each of them. """
	for member in vars(parent).values(): obj.addAction(member) if type(member) == QAction else None

# TODO: stop using such a shoddy method of doing this. Hopefully much of this can be replaced with lambdas
def funcLink(func: Any):
	if isinstance(func, wrapper):
		def link(): func.call()

		return link
	elif callable(func):
		# print(func.__name__ + ' is not a wrapper. It is a ' + type(func).__name__)
		return func
	else:
		return None

def setTriggerResponse(obj: QObject, func: Any, errMsgHead: str = None):
	"""	Set a ``QObject``'s response to being triggered.\\\n
	:param obj: The ``QObject`` for which to set the trigger response
	:param func: The function to call when the ``QObject`` is triggered
	:param errMsgHead: If ``func`` is None, this string will be used for an error message that will print to the console.
	"""
	_func = funcLink(func)
	if _func is not None:
		# obj.triggered.connect(_func, Qt.AutoConnection) #Qt.AutoConnection is the default anyways
		obj.triggered.connect(_func)
	else:
		if errMsgHead is None:
			print('A functionless object has been triggered.')
		else:
			print(errMsgHead + ' has no function')

def setClickedResponse(obj: QObject, func: Any, errMsgHead: str = None):
	"""	Set a ``QObject``'s response to being clicked.\\\n
	:param obj: The ``QObject`` for which to set the click response
	:param func: The function to call when the ``QObject`` is clicked
	:param errMsgHead: If ``func`` is None, this string will be used for an error message that will print to the console.
	"""
	_func = funcLink(func)
	if _func is not None:
		obj.clicked.connect(_func)
	else:
		if errMsgHead is None:
			print('A functionless object has been clicked.')
		else:
			print(errMsgHead + ' has no function')

def setStateChangedResponse(obj: QObject, func: Any, errMsgHead: str = None):
	"""	Set a ``QObject``'s response to a change in its state.\\\n
	:param obj: The ``QObject`` for which to set the response
	:param func: The function to call when the ``QObject`` experiences a state change
	:param errMsgHead: If ``func`` is None, this string will be used for an error message that will print to the console.
	"""
	_func = funcLink(func)
	if _func is not None:
		obj.stateChanged.connect(_func)
	else:
		if errMsgHead is None:
			print('A functionless object has changed states.')
		else:
			print(errMsgHead + ' has no function')

# noinspection PyUnusedLocal
def setSignalResponse(obj: QObject, signal: pyqtSignal, func: Any, errMsgHead: str = None):
	"""	Set a ``QObject``'s response to some signal.\\\n
	:param obj: The ``QObject`` for which to set the signal response
	:param signal: The signal to which the ``QObject`` is responding
	:param func: The function to call when the ``QObject`` is signaled
	:param errMsgHead: If ``func`` is None, this string will be used for an error message that will print to the console.
	"""
	# obj.signal = signal
	_func = funcLink(func)
	if _func is not None:
		obj.signal.connect(_func)
	else:
		if errMsgHead is None:
			print('A functionless object has been signaled.')
		else:
			print(errMsgHead + ' has no function')

def layoutContents(layout: QLayout): return (layout.itemAt(i) for i in range(layout.count()))

def setStyleFromString(widget: QWidget, styleName: str):
	widget.setStyle(QStyleFactory.create(styleName))

def setAppStyleFromString(styleName: str):
	print('styleName: ', styleName)
	try:
		QApplication.instance().setStyle(QStyleFactory.create(styleName))
	except AttributeError:
		print('No QApplication object exists.', file = sys.stderr)

# def stdMainSetup(appName: str, widgetType: QWidget or None, layout: QLayout) -> (QApplication, QWidget):
# 	import sys
# 	app = QApplication(sys.argv)
# 	app.setApplicationName(appName)
#
# 	display = QWidget() if widgetType is None else widgetType  # .__call__()
#
# 	actQuit = QAction('&Quit', display)
# 	actQuit.setShortcut('Ctrl+q')
# 	actQuit.triggered.connect(sys.exit)
# 	display.addAction(actQuit)
#
# 	display.setLayout(layout)
# 	display.show()
# 	return (app, display)

def stdMainSetup(appName: str, widgetType: QWidget or None) -> QMainWindow or QWidget:  # (QApplication, QWidget):
	QApplication.instance().setApplicationName(appName)

	display = QMainWindow() if widgetType is None else widgetType  # .__call__()
	actQuit = QAction('&Quit', display)
	actQuit.setShortcut('Ctrl+q')
	actQuit.triggered.connect(sys.exit)
	display.addAction(actQuit)

	# display.setWindowFlags(Qt.Window)

	#It's unfortunate that none of these seem to account for the space taken up by the Windows taskbar when it's not set to hidden/autohide
	# from PyQt5.QtGui import QGuiApplication
	# print(QGuiApplication.primaryScreen().availableVirtualSize())
	# print(QGuiApplication.primaryScreen().availableSize())
	# print(QGuiApplication.primaryScreen().availableVirtualGeometry())
	# print(QGuiApplication.primaryScreen().availableGeometry())
	# display.setMaximumSize()

	# display.setLayout(layout)
	# display.show()
	# return (_app, display)
	return display


import os
import requests

SHEETY_API = "https://api.sheety.co/d2dd5f6e5713c07f78a8b0452cbb68a8/flightDeals/users/"
SHEETY_TOKEN = os.environ["SHEETY_PRICES_TOKEN"]

class User:

    def add_user(self) -> None:
        bearer_headers = {
            "Authorization": f'Bearer {SHEETY_TOKEN}'
            }
        params = {
            "user": {
                "firstName" : str(input("Welcome to Flight Club. \nWe find the best flight deals and text you. \nWhat is your first name?")),
                "lastName": str(input("What is your last name?")),
                "phoneNumber": int(input("What is your phone number?"))
                }
            }

        response = requests.post(f'{SHEETY_API}', headers=bearer_headers, json=params)
        if response.status_code == 200:
            print("You're in the club!")

        else:
            print(f'Failed {response.json()}')

    def users_info(self) -> list:
        bearer_headers = {
            "Authorization": f'Bearer {SHEETY_TOKEN}'
        }

        response = requests.get(SHEETY_API, headers=bearer_headers)
        if response.status_code == 200:
            print("Successfully fetched the data")
            sheety_users = response.json()
            users_info = sheety_users["users"]
            print(users_info)
            return users_info
        else:
            print(f'Failed {response.status_code}')
            return []

if __name__ == "__main__":
    cos4 = User()
    cos4.add_user()
    cos4.users_info()


import numpy as np
from collections import namedtuple

Coordinate = namedtuple('Coordinate', ['latitude', 'longitude'])

def sin_d(angle):
  return np.sin(np.deg2rad(angle))

def cos_d(angle):
  return np.cos(np.deg2rad(angle))

def distance_in_km(coordinate_a, coordinate_b):
  lat_sine = sin_d((coordinate_b.latitude - coordinate_a.latitude)/2) ** 2
  lon_sine = sin_d((coordinate_b.longitude - coordinate_a.longitude)/2) ** 2
  cosine_a = cos_d(coordinate_a.latitude)
  cosine_b = cos_d(coordinate_b.latitude)
  return 2 * 6372.8 * np.arcsin(np.sqrt(lat_sine + cosine_a * cosine_b * lon_sine))

def azimuth(coordinate_a, coordinate_b):
  numerator_cosine = cos_d(coordinate_b.latitude)
  numerator_sine = sin_d(coordinate_b.longitude - coordinate_a.longitude)
  denominator_a = sin_d(coordinate_b.latitude) * cos_d(coordinate_a.latitude)
  denominator_b = cos_d(coordinate_b.latitude) * sin_d(coordinate_a.latitude)
  denominator_c = cos_d(coordinate_b.longitude - coordinate_a.longitude)
  numerator = numerator_cosine * numerator_sine
  denominator = denominator_a - denominator_b * denominator_c
  argument = (np.arctan2(numerator, denominator) + 2 * np.pi) % (2 * np.pi)
  return np.rad2deg(argument)

def bearing(coordinate_a, coordinate_b):
  delta_lambda = coordinate_b.longitude - coordinate_a.longitude
  start_latitude = coordinate_a.latitude
  end_latitude = coordinate_b.latitude
  start_longitude = coordinate_a.longitude
  argument_num = sin_d(delta_lambda) * cos_d(end_latitude)
  argument_denom_1 = cos_d(start_latitude) * sin_d(end_latitude)
  argument_denom_2 = sin_d(start_latitude) * cos_d(end_latitude) * cos_d(delta_lambda)
  result = np.arctan2(argument_num, argument_denom_1 - argument_denom_2)

  return (np.rad2deg(result) + 360) % 360

def coordinate_at_distance(start, distance, bearing):
  rad_distance = distance / 6372.8
  arg_1 = sin_d(start.latitude) * np.cos(rad_distance)
  arg_2 = cos_d(start.latitude) * np.sin(rad_distance) * cos_d(bearing)
  target_latitude = np.arcsin(arg_1 + arg_2)
  numer = sin_d(bearing) * np.sin(rad_distance) * cos_d(start.latitude)
  denom = np.cos(rad_distance) - sin_d(start.latitude) * np.sin(target_latitude)
  target_longitude = start.longitude + ((np.rad2deg(np.arctan2(numer, denom)) + 540) % 360 - 180)

  return Coordinate(latitude = np.rad2deg(target_latitude), longitude = target_longitude)


from collections import deque
n, k= map(int, input().split())
L=deque()
for i in range(1,n+1):
    L.append(i)

ans=[]
while L:
    for _ in range(k-1):
        q= L.popleft()
        L.append(q)
    q= L.popleft()
    ans.append(str(q))

print('<',end='')
print(', '.join(ans),end='')
print('>',end='')


import requests
import unittest

token_ya = 'Место для вашего токена'
api_base_url = 'https://cloud-api.yandex.net/'
headers = {
            'accept': 'application/json',
            'authorization': f'OAuth {token_ya}'
        }

class TestDocuments(unittest.TestCase):

    def test_create_folder1(self):
        response = requests.put(api_base_url + 'v1/disk/resources', params={'path': 'Test'}, headers=headers)
        assert response.status_code == 201

    def test_create_folder2(self):
        response = requests.put(api_base_url + 'v1/disk/resources', params={'path': 'Test'}, headers=headers)
        assert response.status_code == 409

    def test_get_folder(self):
        response = requests.get(api_base_url + 'v1/disk/resources', params={'path': 'Test'}, headers=headers)
        assert response.status_code == 200

    def test_get_folder2(self):
        response = requests.get(api_base_url + 'v1/disk/resources', params={'path': 'Нет такой папки'}, headers=headers)
        assert response.status_code == 404

if __name__ == '__main__':
    unittest.main()


# -*- coding: utf-8 -*-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved

"""
This file registers pre-defined datasets at hard-coded paths, and their metadata.

We hard-code metadata for common datasets. This will enable:
1. Consistency check when loading the datasets
2. Use models on these standard datasets directly and run demos,
   without having to download the dataset annotations

We hard-code some paths to the dataset that's assumed to
exist in "./datasets/".

Users SHOULD NOT use this file to create new dataset / metadata for new dataset.
To add new dataset, refer to the tutorial "docs/DATASETS.md".
"""

import os

from detectron2.data import MetadataCatalog, DatasetCatalog
from .register_coco import register_coco_instances, register_coco_panoptic_separated, \
    register_coco_amodal_cls_instances
from .register_cocoa import register_cocoa_instances
from .lvis import register_lvis_instances, get_lvis_instances_meta
from .cityscapes import load_cityscapes_instances, load_cityscapes_semantic
from .pascal_voc import register_pascal_voc
from .register_d2sa import register_d2sa_instances
from .register_kins import register_kins_instances
from .register_sailvos import register_sailvos_instances
from .builtin_meta import _get_builtin_metadata

# ==== Predefined datasets and splits for COCO ==========

_PREDEFINED_SPLITS_COCO = {}
_PREDEFINED_SPLITS_COCO["coco"] = {
    "coco_2014_train": ("coco/train2014", "coco/annotations/instances_train2014.json"),
    "coco_2014_val": ("coco/val2014", "coco/annotations/instances_val2014.json"),
    "coco_2014_minival": ("coco/val2014", "coco/annotations/instances_minival2014.json"),
    "coco_2014_minival_100": ("coco/val2014", "coco/annotations/instances_minival2014_100.json"),
    "coco_2014_valminusminival": (
        "coco/val2014",
        "coco/annotations/instances_valminusminival2014.json",
    ),

    "coco_2017_train": ("coco/train2017", "coco/annotations/instances_train2017.json"),
    "coco_2017_val": ("coco/val2017", "coco/annotations/instances_val2017.json"),
    "coco_2017_test": ("coco/test2017", "coco/annotations/image_info_test2017.json"),
    "coco_2017_test-dev": ("coco/test2017", "coco/annotations/image_info_test-dev2017.json"),
    "coco_2017_val_100": ("coco/val2017", "coco/annotations/instances_val2017_100.json"),
}

_PREDEFINED_SPLITS_COCO["coco_person"] = {
    "keypoints_coco_2014_train": (
        "coco/train2014",
        "coco/annotations/person_keypoints_train2014.json",
    ),
    "keypoints_coco_2014_val": ("coco/val2014", "coco/annotations/person_keypoints_val2014.json"),
    "keypoints_coco_2014_minival": (
        "coco/val2014",
        "coco/annotations/person_keypoints_minival2014.json",
    ),
    "keypoints_coco_2014_valminusminival": (
        "coco/val2014",
        "coco/annotations/person_keypoints_valminusminival2014.json",
    ),
    "keypoints_coco_2014_minival_100": (
        "coco/val2014",
        "coco/annotations/person_keypoints_minival2014_100.json",
    ),
    "keypoints_coco_2017_train": (
        "coco/train2017",
        "coco/annotations/person_keypoints_train2017.json",
    ),
    "keypoints_coco_2017_val": ("coco/val2017", "coco/annotations/person_keypoints_val2017.json"),
    "keypoints_coco_2017_val_100": (
        "coco/val2017",
        "coco/annotations/person_keypoints_val2017_100.json",
    ),
}

_PREDEFINED_SPLITS_COCO_PANOPTIC = {
    "coco_2017_train_panoptic": (
        # This is the original panoptic annotation directory
        "coco/panoptic_train2017",
        "coco/annotations/panoptic_train2017.json",
        # This directory contains semantic annotations that are
        # converted from panoptic annotations.
        # It is used by PanopticFPN.
        # You can use the script at detectron2/datasets/prepare_panoptic_fpn.py
        # to create these directories.
        "coco/panoptic_stuff_train2017",
    ),
    "coco_2017_val_panoptic": (
        "coco/panoptic_val2017",
        "coco/annotations/panoptic_val2017.json",
        "coco/panoptic_stuff_val2017",
    ),
    "coco_2017_val_100_panoptic": (
        "coco/panoptic_val2017_100",
        "coco/annotations/panoptic_val2017_100.json",
        "coco/panoptic_stuff_val2017_100",
    ),
}

_PREDEFINED_SPLITS_COCO_AMODAL = {
    "coco_2014_amodal_train": ("coco/train2014", "coco/amodal_annotations/COCO_amodal_train2014.json"),
    "coco_2014_amodal_val": ("coco/val2014", "coco/amodal_annotations/COCO_amodal_val2014.json"),
    "coco_2014_amodal_test": ("coco/test2014", "coco/amodal_annotations/COCO_amodal_test2014.json"),
    "cocoa_nostuff_train": ("coco/train2014", "coco/amodal_cls_annotations/COCO_amodal_train2014_detectron_no_stuff.json"),
    "cocoa_nostuff_train_visible": ("coco/train2014", "coco/amodal_cls_annotations/COCO_amodal_train2014_detectron_no_stuff.json"),
    "cocoa_nostuff_val": ("coco/val2014", "coco/amodal_cls_annotations/COCO_amodal_val2014_detectron_no_stuff.json"),
    "cocoa_nostuff_val_visible": ("coco/val2014", "coco/amodal_cls_annotations/COCO_amodal_val2014_detectron_no_stuff.json"),
}

def register_all_coco(root="datasets"):
    for dataset_name, splits_per_dataset in _PREDEFINED_SPLITS_COCO.items():
        for key, (image_root, json_file) in splits_per_dataset.items():
            # Assume pre-defined datasets live in `./datasets`.
            register_coco_instances(
                key,
                _get_builtin_metadata(dataset_name),
                os.path.join(root, json_file) if "://" not in json_file else json_file,
                os.path.join(root, image_root),
            )
    for (
        prefix,
        (panoptic_root, panoptic_json, semantic_root),
    ) in _PREDEFINED_SPLITS_COCO_PANOPTIC.items():
        prefix_instances = prefix[: -len("_panoptic")]
        instances_meta = MetadataCatalog.get(prefix_instances)
        image_root, instances_json = instances_meta.image_root, instances_meta.json_file
        register_coco_panoptic_separated(
            prefix,
            _get_builtin_metadata("coco_panoptic_separated"),
            image_root,
            os.path.join(root, panoptic_root),
            os.path.join(root, panoptic_json),
            os.path.join(root, semantic_root),
            instances_json,
        )

def register_all_cocoa(root="datasets"):
    for key, (image_root, json_file) in _PREDEFINED_SPLITS_COCO_AMODAL.items():
        # Assume pre-defined datasets live in `./datasets`.
        register_cocoa_instances(
            key,
            _get_builtin_metadata("cocoa"),
            os.path.join(root, json_file) if "://" not in json_file else json_file,
            os.path.join(root, image_root),
        )

# ==== Predefined datasets and splits for COCOA cls ==========

_PREDEFINED_SPLITS_COCO_AMODAL_CLS = {
    "cocoa_cls_train": ("coco/train2014", "coco/amodal_cls_annotations/COCO_amodal_train2014_with_classes.json"),
    "cocoa_cls_train_visible": ("coco/train2014", "coco/amodal_cls_annotations/COCO_amodal_train2014_with_classes.json"),
    "cocoa_cls_val": ("coco/val2014", "coco/amodal_cls_annotations/COCO_amodal_val2014_with_classes.json"),
    "cocoa_cls_val_visible": ("coco/val2014", "coco/amodal_cls_annotations/COCO_amodal_val2014_with_classes.json"),
}

def register_all_coco_amodal_cls(root="datasets"):
    for key, (image_root, json_file) in _PREDEFINED_SPLITS_COCO_AMODAL_CLS.items():
        # Assume pre-defined datasets live in `./datasets`.
        register_coco_amodal_cls_instances(
            key,
            _get_builtin_metadata("coco_amodal_cls"),
            os.path.join(root, json_file) if "://" not in json_file else json_file,
            os.path.join(root, image_root),
        )

# ==== Predefined datasets and splits for LVIS ==========

_PREDEFINED_SPLITS_LVIS = {
    "lvis_v0.5": {
        "lvis_v0.5_train": ("coco/train2017", "lvis/lvis_v0.5_train.json"),
        "lvis_v0.5_val": ("coco/val2017", "lvis/lvis_v0.5_val.json"),
        "lvis_v0.5_val_rand_100": ("coco/val2017", "lvis/lvis_v0.5_val_rand_100.json"),
        "lvis_v0.5_test": ("coco/test2017", "lvis/lvis_v0.5_image_info_test.json"),
    }
}

def register_all_lvis(root="datasets"):
    for dataset_name, splits_per_dataset in _PREDEFINED_SPLITS_LVIS.items():
        for key, (image_root, json_file) in splits_per_dataset.items():
            # Assume pre-defined datasets live in `./datasets`.
            register_lvis_instances(
                key,
                get_lvis_instances_meta(dataset_name),
                os.path.join(root, json_file) if "://" not in json_file else json_file,
                os.path.join(root, image_root),
            )

# ==== Predefined splits for raw cityscapes images ===========

_RAW_CITYSCAPES_SPLITS = {
    "cityscapes_fine_{task}_train": ("cityscapes/leftImg8bit/train", "cityscapes/gtFine/train"),
    "cityscapes_fine_{task}_val": ("cityscapes/leftImg8bit/val", "cityscapes/gtFine/val"),
    "cityscapes_fine_{task}_test": ("cityscapes/leftImg8bit/test", "cityscapes/gtFine/test"),
}

def register_all_cityscapes(root="datasets"):
    for key, (image_dir, gt_dir) in _RAW_CITYSCAPES_SPLITS.items():
        meta = _get_builtin_metadata("cityscapes")
        image_dir = os.path.join(root, image_dir)
        gt_dir = os.path.join(root, gt_dir)

        inst_key = key.format(task="instance_seg")
        DatasetCatalog.register(
            inst_key,
            lambda x=image_dir, y=gt_dir: load_cityscapes_instances(
                x, y, from_json=True, to_polygons=True
            ),
        )
        MetadataCatalog.get(inst_key).set(
            image_dir=image_dir, gt_dir=gt_dir, evaluator_type="cityscapes", **meta
        )

        sem_key = key.format(task="sem_seg")
        DatasetCatalog.register(
            sem_key, lambda x=image_dir, y=gt_dir: load_cityscapes_semantic(x, y)
        )
        MetadataCatalog.get(sem_key).set(
            image_dir=image_dir, gt_dir=gt_dir, evaluator_type="sem_seg", **meta
        )

# ==== Predefined splits for PASCAL VOC ===========
def register_all_pascal_voc(root="datasets"):
    SPLITS = [
        ("voc_2007_trainval", "VOC2007", "trainval"),
        ("voc_2007_train", "VOC2007", "train"),
        ("voc_2007_val", "VOC2007", "val"),
        ("voc_2007_test", "VOC2007", "test"),
        ("voc_2012_trainval", "VOC2012", "trainval"),
        ("voc_2012_train", "VOC2012", "train"),
        ("voc_2012_val", "VOC2012", "val"),
    ]
    for name, dirname, split in SPLITS:
        year = 2007 if "2007" in name else 2012
        register_pascal_voc(name, os.path.join(root, dirname), split, year)
        MetadataCatalog.get(name).evaluator_type = "pascal_voc"

_PREDEFINED_SPLITS_D2SA = {
    "d2sa_train": ("D2SA/images", "D2SA/annotations/D2S_amodal_training_rot0.json"),
    "d2sa_train_visible": ("D2SA/images", "D2SA/annotations/D2S_amodal_training_rot0.json"),
    "d2sa_train_aug": ("D2SA/images", "D2SA/annotations/D2S_amodal_augmented.json"),
    "d2sa_train_aug_visible": ("D2SA/images", "D2SA/annotations/D2S_amodal_augmented.json"),
    "d2sa_val": ("D2SA/images", "D2SA/annotations/D2S_amodal_validation.json"),
    "d2sa_val_visible": ("D2SA/images", "D2SA/annotations/D2S_amodal_validation.json"),
    "d2sa_test": ("D2SA/images", "D2SA/annotations/D2S_amodal_test_info.json"),
}

def register_all_d2sa(root="/root/detectron2/datasets"):
    for key, (image_root, json_file) in _PREDEFINED_SPLITS_D2SA.items():
        # Assume pre-defined datasets live in `./datasets`.
        register_d2sa_instances(
            key,
            _get_builtin_metadata("d2sa"),
            os.path.join(root, json_file) if "://" not in json_file else json_file,
            os.path.join(root, image_root),
        )

_PREDEFINED_SPLITS_KINS = {
    "kins_train": ("KINS/training/image_2", "KINS/instances_train.json"),
    "kins_train_visible": ("KINS/training/image_2", "KINS/instances_train.json"),
    "kins_val": ("KINS/testing/image_2", "KINS/instances_val.json"),
    "kins_val_visible": ("KINS/testing/image_2", "KINS/instances_val.json"),
}

def register_all_kins(root="datasets"):
    for key, (image_root, json_file) in _PREDEFINED_SPLITS_KINS.items():
        # Assume pre-defined datasets live in `./datasets`.
        register_kins_instances(
            key,
            _get_builtin_metadata("kins"),
            os.path.join(root, json_file) if "://" not in json_file else json_file,
            os.path.join(root, image_root),
        )

# Register them all under "./datasets"
register_all_coco()
register_all_cocoa()
register_all_coco_amodal_cls()
register_all_kins()
register_all_lvis()
register_all_cityscapes()
register_all_pascal_voc()
register_all_d2sa()


"""
DM decay spectra and associated functions.
Everything is provided and output in natural units!
"""
import os, sys
from scipy.special import erf
from scipy.interpolate import interp1d
import numpy as np
import pandas as pd
from units import *
from scipy import integrate

class Particle:
    def __init__(self, channel='b', m_chi=100*GeV, data_dir = '/tigress/smsharma/Fermi-SmoothGalHalo/DMFiles/'):
        """ Initialize the parameters to generate a sample of subhalos.

            :param channel: Decay channel -- 'b', 'W' and the like
            :param m_chi: Particle DM mass in natural units
            :param data_dir: Where the annihilation spectra are stored
        """

        self.data_dir = data_dir
        self.m_chi = m_chi
        self.channel = channel
        self.dNdLogx_df=pd.read_csv(self.data_dir+'AtProduction_gammas.dat', delim_whitespace=True)

        self.dNdE() # Interpolate spectra

    def dNdE(self):
        """ Make interpolated decay spectra for given mass and channel
        """
        self.m_chi_interp = self.m_chi/2. # Note: PPPC4DMID gives 2->2 spectra; the correct 1->2 spectra for mchi correspond to 2->2 spectra for mchi/2
        dNdLogx_ann_df = self.dNdLogx_df.query('mDM == ' + (str(np.int(float(self.m_chi_interp)/GeV))))[['Log[10,x]',self.channel]]
        self.Egamma = np.array(self.m_chi_interp*(10**dNdLogx_ann_df['Log[10,x]']))
        self.dNdEgamma = np.array(dNdLogx_ann_df[self.channel]/(self.Egamma*np.log(10)))
        self.dNdE_interp =  interp1d(self.Egamma, self.dNdEgamma)

    def Phi_decay(self, tau, Emin, Emax):
        """ Integrated flux for a given energy range from dNdE
            Everything in natural units!

            :param tau: Decay time constant
            :param Emin: Energy to integrate from
            :param Emax: Energy to integrate up to

        """
        N = 0
        if Emin < self.m_chi_interp:
            if Emax < self.m_chi_interp:
                N = integrate.quad(lambda x: self.dNdE_interp(x), Emin, Emax)[0]
            else:
                N = integrate.quad(lambda x: self.dNdE_interp(x), Emin, self.m_chi_interp)[0]
        return 1/(4*np.pi*tau*self.m_chi)*np.array(N)#/(Emax-Emin)


import hashlib
import json
import requests
import time
import salt_gen

time_start = time.perf_counter()
print(time_start)
salt = salt_gen.generator()  # 首次启动获取盐值

def w_rid():  # 每次请求生成w_rid参数
    global time_start, salt
    if (time.perf_counter() - time_start) > 24 * 60 * 60:  # 一天更新一次salt
        time_start = time.perf_counter()
        salt = salt_gen.generator()  # 尾部加盐，根据imgKey,subKey混淆得出
    wts = str(int(time.time()))  # 时间戳
    b = "mid=" + uid + "&platform=web&token=&web_location=1550101"
    a = b + "&wts=" + wts + salt  # mid + platform + token + web_location + 时间戳wts + 一个固定值
    return hashlib.md5(a.encode(encoding='utf-8')).hexdigest()

def get():
    DEFAULT_HEADERS = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
        "Referer": "https://www.bilibili.com/" + uid,
        "Content-Type": "application/json",
        "Accept": "*/*",
        "Origin": "https://space.bilibili.com",

    }
    API = {
        "url": "https://api.bilibili.com/x/space/wbi/acc/info",
        "params": {
            "mid": uid,
            "token": '',
            "platform": "web",
            "web_location": 1550101,
            "w_rid": w_rid(),
            "wts": str(int(time.time()))
        }
    }
    t = time.localtime()
    req = requests.request("GET", **API, headers=DEFAULT_HEADERS)
    if req.ok:
        con = req.json()
        if con["code"] == 0:
            title = con['data']['live_room']['title']
            liveStatus = con['data']['live_room']['liveStatus']
            name = con['data']['name']
            if liveStatus == 1:
                print(str(time.strftime("%Y-%m-%d %H:%M:%S", t)) + ' ' + name + ' 直播中, 标题：' + title)
            else:
                print(str(time.strftime("%Y-%m-%d %H:%M:%S", t)) + ' ' + name + ' 未开播')
            with open('liveStatus.json', 'w') as f:
                json.dump({
                    'title': title,
                    'liveStatus': liveStatus
                }, f)
        else:
            print('B站接口返回了错误:')
            print(con)
    else:
        print(f'网络错误, 错误码: {req.status_code}')

uid = input('请输入监控直播的主播UID：')
freq = int(input('请输入检测频率（秒每次，不建议小于60）：'))
while freq:
    get()
    time.sleep(freq)


#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-

import logging

from srm.file_operations import get_full_path

def setup_console_logger(str_format="%(levelname)s: %(message)s", level=logging.INFO):
    """
    Setup console logger.
    """
    root_logger = logging.getLogger()
    formatter = logging.Formatter(str_format)

    shandler = logging.StreamHandler()
    shandler.setLevel(level)
    shandler.setFormatter(formatter)

    root_logger.addHandler(shandler)
    root_logger.setLevel(level)

def setup_file_logger(filename="", str_format="%(levelname)s: %(message)s", level=logging.INFO):
    """Setup file logger"""
    root_logger = logging.getLogger()
    formatter = logging.Formatter(str_format)

    fhandler = logging.FileHandler(get_full_path(filename))
    fhandler.setLevel(level)
    fhandler.setFormatter(formatter)

    root_logger.addHandler(fhandler)
    root_logger.setLevel(level)


from app import app
from flask import Flask, jsonify, make_response, request

records = [
    {
        'id':1,
        'title':u'aaa',
        'descrption':u'bbb',
        'done':False
    },
    {
        'id':2,
        'title':u'ccc',
        'description':u'ddd',
        'done':True
    }
]

@app.route('/')
def index():
    return "<h1>----hello flask!----</h1>"

@app.route('/records', methods=['GET'])
def getRec():
    return jsonify({'records': records})

@app.route('/records', methods=['POST'])
def createRec():
    if not request.json or not 'title' in request.json:
        return make_response(jsonify({'-ERROR-': 'NEED TITLE'}), 400)
    task = {
        'id':records[-1]['id'] + 1,
        'title':request.json['title'],
        'description': request.json.get('description', ""),
        'done':False
    }
    records.append(task)
    return jsonify({'records': task}), 201

@app.route('/records/alltasks', methods=['GET'])
def getTtl():
    response = [item['title'] for item in records]
    return jsonify(response)

@app.route('/records/<ttlName>', methods=['DELETE'])
def deleteTask(ttlName):
    matching = [item for item in records if item['title'] == ttlName]
    if len(matching) == 0:
        return make_response(jsonify({'-ERROR-': 'NOT FOUND'}), 404)
    records.remove(matching[0])
    return jsonify({'sucess', True})

@app.route('/records/<ttlName>', methods=['PUT'])
def updateTask(ttlName):
    matching = [item for item in records if item['title'] == ttlName]
    if len(matching) == 0:
        return make_response(jsonify({'-ERROR-': 'NOT FOUND'}), 404)
    if not request.json:
        return make_response(jsonify({'-ERROR-': 'FORMAT ERR'}), 400)
    matching[0]['title'] = request.json.get('title', matching[0]['title'])
    matching[0]['description'] = request.json.get('description', matching[0]['description'])
    matching[0]['done'] = request.json.get('done', matching[0]['done'])
    return jsonify({'task':matching[0]})

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'-ERROR-': 'NOT FOUND'}), 404)


# start
# annotation
import os
import glob
import copy
from Bio import SeqIO
from Bio.Seq import Seq
import argparse
############################################ Arguments and declarations ##############################################
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter)
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')
required.add_argument("-i",
                      help="a folder of all input fasta for annotation",
                      type=str, default='.',
                      metavar='input/')
optional.add_argument("-fa",
                      help="file extension of fasta to annotate",
                      type=str, default='fasta',
                      metavar='fasta')
optional.add_argument("-seq",
                      help="input seq format: aa or dna",
                      type=str, default='aa',choices=['aa','dna'],
                      metavar='aa or dna')
# optional output setup
optional.add_argument("-s",
                      help="a folder to store all scripts",
                      type=str, default='.',
                      metavar='scripts/')
optional.add_argument("-o",
                      help="a folder to store all output",
                      type=str, default='annotation/',
                      metavar='annotation/')
# optional search parameters
optional.add_argument('-t',
                      help="Optional: set the thread number assigned for running XXX (default 1)",
                      metavar="1 or more", action='store', default=40, type=int)
optional.add_argument('-job',
                      help="Optional: command to submit jobs",
                      metavar="nohup or customized",
                      action='store', default='jobmit', type=str)
# requirement for software calling
optional.add_argument('-bw', '--bowtie',
                          help="Optional: complete path to bowtie if not in PATH",
                          metavar="/usr/local/bin/bowtie",
                          action='store', default='bowtie', type=str)
optional.add_argument('-sp', '--spades',
                          help="Optional: complete path to spades if not in PATH",
                          metavar="/usr/local/bin/spades",
                          action='store', default='spades', type=str)
optional.add_argument('-pro', '--prodigal',
                      help="Optional: complete path to prodigal if not in PATH, None for no prodigal (default)",
                      metavar="/usr/local/bin/prodigal",
                      action='store', default='None', type=str)
optional.add_argument('-bcf', '--bcftools',
                      help="Optional: complete path to bcftools if not in PATH",
                      metavar="/usr/local/bin/bcftools",
                      action='store', default='bcftools', type=str)
optional.add_argument('-sam', '--samtools',
                      help="Optional: complete path to bwa if not in PATH",
                      metavar="/usr/local/bin/samtools",
                      action='store', default='samtools', type=str)
optional.add_argument('-mini', '--minimap2',
                      help="Optional: complete path to minimap2 if not in PATH",
                      metavar="/usr/local/bin/minimap2",
                      action='store', default='minimap2', type=str)
optional.add_argument('--u','--usearch',
                        help="Optional: cluster genes with SNPs",
                        metavar="usearch",
                        action='store', default='usearch', type=str)
################################################## Definition ########################################################
args = parser.parse_args()

input_script_sub = args.s +'/annotate'
input_script = args.s
output_dir = args.o
try:
    os.mkdir(input_script_sub)
except IOError:
    pass

try:
    os.mkdir(output_dir)
except IOError:
    pass

all_fasta = glob.glob(os.path.join(args.i, '*' + args.fa))

# functions
def annotation(all_filter_gene_fasta_file):
    tag = os.path.split(all_filter_gene_fasta_file)[-1]
    # run prodigal
    if args.seq != 'aa':
        AAfile = all_filter_gene_fasta_file.replace('.'+args.fa.replace('.',''),'.aa')
        try:
            f1 = open(AAfile, 'r')
        except FileNotFoundError:
            os.system('prodigal -q -i %s -a %s' % (all_filter_gene_fasta_file, AAfile))
        all_filter_gene_fasta_file = AAfile
    print(AAfile)
    # run cluster
    cutoff = 0.7
    cmd_cluster = ('%s -sort length -cluster_fast %s -id %s -centroids %s.cluster.aa -uc %s.uc -threads %s\n'
                   % (args.u, all_filter_gene_fasta_file, cutoff, all_filter_gene_fasta_file,
                      all_filter_gene_fasta_file, 40))
    os.system(cmd_cluster)
    all_filter_gene_fasta_file = all_filter_gene_fasta_file + '.cluster.aa'
    # run metacyc
    cutoff = 50
    cutoff2 = 80
    database = '/scratch/users/mit_alm/database/metacyc/protseq.fsa'
    cmds = ("diamond blastp --query %s --db %s.dmnd --out %s.metacyc.txt --id %s --query-cover %s --outfmt 6 --max-target-seqs 2 --evalue 1e-1 --threads 40\n"
            %(all_filter_gene_fasta_file,database,all_filter_gene_fasta_file,cutoff,cutoff2))
    f1 = open(os.path.join(input_script_sub, tag + '.metacyc.sh'), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n%s'%(cmds))
    f1.close()
    # run eggnog
    cutoff = 0.01
    database = '/scratch/users/mit_alm/database/eggnog/xaa.hmm'
    cmds = ('hmmsearch --tblout %s.eggnog.1.txt --cpu 40 -E %s %s %s\n') %(all_filter_gene_fasta_file,cutoff,database,all_filter_gene_fasta_file)
    f1 = open(os.path.join(input_script_sub, tag + '.eggnog.1.sh'), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n%s'%(cmds))
    f1.close()
    database = '/scratch/users/mit_alm/database/eggnog/xab.hmm'
    cmds = ('hmmsearch --tblout %s.eggnog.2.txt --cpu 40 -E %s %s %s\n') % (
    all_filter_gene_fasta_file, cutoff, database, all_filter_gene_fasta_file)
    f1 = open(os.path.join(input_script_sub, tag + '.eggnog.2.sh'), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n%s' % (cmds))
    f1.close()
    database = '/scratch/users/mit_alm/database/eggnog/xac.hmm'
    cmds = ('hmmsearch --tblout %s.eggnog.3.txt --cpu 40 -E %s %s %s\n') % (
    all_filter_gene_fasta_file, cutoff, database, all_filter_gene_fasta_file)
    f1 = open(os.path.join(input_script_sub, tag + '.eggnog.3.sh'), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n%s' % (cmds))
    f1.close()
    # run kegg
    cutoff = 0.01
    database = '/scratch/users/mit_alm/database/kegg/kofam/profiles/prokaryote/prokaryote.hmm'
    cmds = ('hmmsearch --tblout %s.kegg.txt --cpu 40 -E %s %s %s\n') %(all_filter_gene_fasta_file,cutoff,database,all_filter_gene_fasta_file)
    f1 = open(os.path.join(input_script_sub, tag + '.kegg.sh'), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n%s'%(cmds))
    f1.close()
    # run customed database
    cutoff = 80
    cutoff2 = 80
    cmds = ''
    database = '/scratch/users/anniz44/scripts/database/SARG.db.fasta'
    cmds += ("diamond blastp --query %s --db %s.dmnd --out %s.SARG.txt --id %s --query-cover %s --outfmt 6 --max-target-seqs 2 --evalue 1e-1 --threads 40\n"
            %(all_filter_gene_fasta_file,database,all_filter_gene_fasta_file,cutoff,cutoff2))
    cutoff = 50
    cutoff2 = 50
    database = '/scratch/users/anniz44/scripts/database/AHR.aa.db'
    cmds += ("diamond blastp --query %s --db %s.dmnd --out %s.AHR.txt --id %s --query-cover %s --outfmt 6 --max-target-seqs 2 --evalue 1e-1 --threads 40\n"
            %(all_filter_gene_fasta_file,database,all_filter_gene_fasta_file,cutoff,cutoff2))
    cutoff = 60
    cutoff2 = 80
    database = '/scratch/users/anniz44/scripts/database/Butyrate.pro.aa'
    cmds += ("diamond blastp --query %s --db %s.dmnd --out %s.buty.txt --id %s --query-cover %s --outfmt 6 --max-target-seqs 2 --evalue 1e-1 --threads 40\n"
            %(all_filter_gene_fasta_file,database,all_filter_gene_fasta_file,cutoff,cutoff2))
    cutoff = 50
    cutoff2 = 80
    database = '/scratch/users/anniz44/scripts/database/IntI1_database.fasta'
    cmds += ("diamond blastp --query %s --db %s.dmnd --out %s.int.txt --id %s --query-cover %s --outfmt 6 --max-target-seqs 2 --evalue 1e-1 --threads 40\n"
            %(all_filter_gene_fasta_file,database,all_filter_gene_fasta_file,cutoff,cutoff2))
    cutoff = 50
    cutoff2 = 80
    database = '/scratch/users/anniz44/scripts/database/SRB.AA'
    cmds += ("diamond blastp --query %s --db %s.dmnd --out %s.SRB.txt --id %s --query-cover %s --outfmt 6 --max-target-seqs 2 --evalue 1e-1 --threads 40\n"
            %(all_filter_gene_fasta_file,database,all_filter_gene_fasta_file,cutoff,cutoff2))
    cutoff = 0.01
    database = '/scratch/users/anniz44/scripts/database/NR.hmm'
    cmds += ('hmmsearch --tblout %s.NR.txt --cpu 40 -E %s %s %s\n') %(all_filter_gene_fasta_file,cutoff,database,all_filter_gene_fasta_file)
    f1 = open(os.path.join(input_script_sub, tag + '.customed.sh'), 'w')
    f1.write('#!/bin/bash\nsource ~/.bashrc\n%s'%(cmds))
    f1.close()

# run clustering

for files in all_fasta:
    annotation(files)

# all scripts
f1 = open(os.path.join(input_script, 'allannotate.sh'), 'w')
f1.write('#!/bin/bash\nsource ~/.bashrc\n')
for sub_scripts in glob.glob(os.path.join(input_script_sub, '*.sh')):
    if 'jobmit' in args.job:
        f1.write('jobmit %s %s\n' % (sub_scripts, os.path.split(sub_scripts)[-1]))
    else:
        f1.write('nohup sh %s > %s.out &\n' % (sub_scripts, os.path.split(sub_scripts)[-1]))
f1.close()

################################################### END ########################################################


import requests
import threading
import sys
import re
import time

handle = str(input("please enter the cf handle : "))
roundID = int(input("please enter the contestID : "))

url = "https://codeforces.com/api/contest.standings?contestId={0}&handles={1}&showUnofficial=true".format(roundID, handle)

file = open("cf_logger.txt", "w")

def fn():
	while 1:
		t = time.time()
		with requests.get(url) as r:
			match = re.search(r"\"rank\":(\d),", r.text)
			s = str(int((t-t_start)/60)) + "  :  "
			if match:
				file.write(s + str(match.group(1)))
				file.write('\n')
		time.sleep(8)

x = threading.Thread(target = fn, daemon = True)
t_start = time.time()
x.start()

while str(input("press \"y\" to end the process : ")) != "y":
	pass

file.close()

sys.exit(0)


import threading
from urllib import parse
from urllib.request import urlopen
from django.contrib import admin
from django.contrib import messages
from django.urls import reverse
from django.utils.safestring import mark_safe

from mysite import settings
from vodmanagement.models import Vod
from epg.models import Channel, Program
from epg.utils import download_m3u8_files

@admin.register(Channel)
class ChannelModelAdmin(admin.ModelAdmin):
    list_display = ['channel_id', 'channel_name', 'rtmp_url']
    list_display_links = ['channel_id']  # image_tag
    list_editable = ['channel_name', 'rtmp_url']
    search_fields = ['channel_id', 'channel_name']

@admin.register(Program)
class ProgramModelAdmin(admin.ModelAdmin):
    """
    Program admin site view
    """
    list_display = ['channel', 'title', 'start_time', 'end_time', 'url']
    list_display_links = ['channel']
    list_filter = ['finished', 'channel']
    search_fields = ['title']
    actions = ['record']

    def get_queryset(self, request):
        return super(ProgramModelAdmin, self).get_queryset(request).filter(finished=1)

    def record(self, request, queryset):
        legal_program_cnt = 0
        for program in queryset:
            try:
                m3u8_file_path = parse.urlparse(program.url).path  # /CCTV1/20180124/123456.m3u8
                urlopen(program.url, timeout=5)
                print(m3u8_file_path)
            except Exception as e:
                self.message_user(request, '%s 转点播失败 请检查录播的网址是否可以访问'%(program.title), messages.ERROR)
                continue
            new_record = Vod(
                title=program.title,
                video=settings.RECORD_MEDIA_FOLDER + m3u8_file_path
                )
            new_record.save()
            p = threading.Thread(target=download_m3u8_files, args=(new_record.id, program.url, settings.RECORD_MEDIA_ROOT))
            p.start()
            legal_program_cnt += 1
            print('start downloading m3u8 files', program.url)
        record_url = reverse('admin:vodmanagement_vod_changelist')
        print(record_url)
        self.message_user(request, mark_safe('%s/%s 个节目正在转成点播,转换进度请到录制节目处查看。'%(legal_program_cnt,queryset.count(),record_url))
                          , messages.SUCCESS)

    record.short_description = '转为点播'


from datetime import date
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome(executable_path="C:\\Users\\mukunth\\PycharmProjects\\pythonProject\\mypackage\\chromedriver.exe")

#def datastream(value):
#    send1 = driver.get("http://demo.automationtesting.in/Alerts.html")
#    send2 = driver.find_element(By.CSS_SELECTOR, datastream1 ).click()
#    driver.implicitly_wait(5)
#    alert1 = driver.switch_to_alert
#    print(alert1.text)
#    alert1.accept()

#datastream1 = "button.btn.btn-danger"
#datastream(datastream1)
#driver.implicitly_wait(20)
#driver.quit()

##second selectform

#def keyvalue():
#    send1 = driver.get("http://demo.automationtesting.in/Frames.html")
#    send2 = driver.find_element(By.CSS_SELECTOR, "a.analystic").text
#    print(send2)
#
#    driver.switch_to.default_content()
#    driver.switch_to.parent_frame()

#keyvalue()
def keyvalue2():
    send1 = driver.get("https://online2pdf.com/pdf2word")
    send2 = driver.find_element(By.XPATH, "button[@type='button']")
    send2.send_keys("C:\\Users\\mukunth\\execution3.json")
    send2.click()
keyvalue2()
### some cases if you have router there the username and password are pop up before enter into config menu in that case do below steps
#https://admin:admin@"desired url"


"""empty message

Revision ID: 405b9e06626f
Revises:
Create Date: 2022-05-20 13:44:53.601560

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '405b9e06626f'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('entry',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('title', sa.String(length=80), nullable=False),
    sa.Column('body', sa.Text(), nullable=False),
    sa.Column('pub_date', sa.DateTime(), nullable=False),
    sa.Column('is_published', sa.Boolean(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('comment',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('body', sa.Text(), nullable=False),
    sa.Column('created', sa.DateTime(), nullable=True),
    sa.Column('is_published', sa.Boolean(), nullable=True),
    sa.Column('entry_id', sa.Integer(), nullable=True),
    sa.ForeignKeyConstraint(['entry_id'], ['entry.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_comment_created'), 'comment', ['created'], unique=False)
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_comment_created'), table_name='comment')
    op.drop_table('comment')
    op.drop_table('entry')
    # ### end Alembic commands ###


import numpy as np
import matplotlib.pyplot as plt

from tensorflow.keras.datasets import mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()

print(x_train.shape, y_train.shape)     # (60000, 28, 28), (60000,)
print(x_test.shape, y_test.shape)       # (10000, 28, 28), (10000,)

print(x_train[0])
print(y_train[0])

print(x_train[0].shape)         # (28, 28)

x_train = x_train.reshape(60000,28,28,1)/255.
x_test = x_test.reshape(10000,28,28,1)/255.

from tensorflow.keras.utils import to_categorical
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, MaxPooling2D, Flatten, Dropout

model = Sequential()
model.add(Conv2D(filters=256, kernel_size=(2,2), padding='same',
                 strides=1, input_shape=(28,28,1)))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(Conv2D(64, (2,2), padding='same', strides=1))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(Conv2D(64, (2,2), padding='same', strides=1))
model.add(MaxPooling2D(pool_size=2))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))

model.summary()

# ModelCheckPoint
import datetime
date_now = datetime.datetime.now()
print(date_now) # 컴퓨터에 설정되어 있는 시간
date_time = date_now.strftime('%m%d_%H%M')
print(date_time)

from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
filepath='../data/modelcheckpoint/'
filename='_{epoch:02d}-{val_loss:.4f}.hdf5'
modelpath = "".join([filepath, "k45_", '{timer}', filename])

# ModelCheckpoint Class 상속해서 파일을 생성해주는 def 고침.
import tensorflow as tf
from tensorflow import keras
from tensorflow.python.util.tf_export import keras_export
from tensorflow.python.distribute import distributed_file_utils
@keras_export('keras.callbacks.ModelCheckpoint')
class MyModelCheckpoint(tf.keras.callbacks.ModelCheckpoint):
    def _get_file_path(self, epoch, logs):
        """Returns the file path for checkpoint."""
        # pylint: disable=protected-access
        try:
        # `filepath` may contain placeholders such as `{epoch:02d}` and
        # `{mape:.2f}`. A mismatch between logged metrics and the path's
        # placeholders can cause formatting to fail.
            file_path = self.filepath.format(epoch=epoch + 1, timer=datetime.datetime.now().strftime('%m%d_%H%M'), **logs)
        except KeyError as e:
            raise KeyError('Failed to format this callback filepath: "{}". '
                        'Reason: {}'.format(self.filepath, e))
        self._write_filepath = distributed_file_utils.write_filepath(
            file_path, self.model.distribute_strategy)
        return self._write_filepath

cp = MyModelCheckpoint(filepath=modelpath, monitor='val_loss', save_best_only=True, mode='auto')

es = EarlyStopping(monitor='val_loss', patience=5)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
hist = model.fit(x_train, y_train, epochs=50, batch_size=32, validation_split=0.2, verbose=2, callbacks=[es, cp])
print(hist)

result = model.evaluate(x_test, y_test)
print('loss :', result[0])
print('acc :', result[1])

'''
# 시각화
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
font_path = './NanumGothic.ttf'
fontprop = fm.FontProperties(fname=font_path, size=8)

plt.figure(figsize=(10, 6))

plt.subplot(2,1,1)          # 2행 1열 중 첫번째
plt.plot(hist.history['loss'], marker='.', c='red', label='loss')
plt.plot(hist.history['val_loss'], marker='.', c='blue', label='val_loss')
plt.grid()

plt.title('손실비용', fontproperties=fontprop)
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(loc='upper right')

plt.subplot(2,1,2)          # 2행 2열 중 두번째
plt.plot(hist.history['acc'], marker='.', c='red', label='acc')
plt.plot(hist.history['val_acc'], marker='.', c='blue', label='val_acc')
plt.grid()

plt.title('정확도', fontproperties=fontprop)
plt.ylabel('acc')
plt.xlabel('epoch')
plt.legend(loc='upper right')

plt.show()
'''