import torch
import numpy as np
import pandas as pd
from scipy.stats import pearsonr, spearmanr
from seqeval.metrics import f1_score as ner_f1_score
from seqeval.metrics import classification_report as token_classification_report
from sklearn.metrics import (
    matthews_corrcoef,
    recall_score,
    precision_score,
    f1_score,
    mean_squared_error,
    r2_score,
    classification_report
)
from farm.utils import flatten_list
import logging

logger = logging.getLogger(__name__)

registered_metrics = {}
registered_reports = {}

def register_metrics(name, implementation):
    registered_metrics[name] = implementation

def register_report(name, implementation):
    """
    Register a custom reporting function to be used during eval.

    This can be useful:
    - if you want to overwrite a report for an existing output type of prediction head (e.g. "per_token")
    - if you have a new type of prediction head and want to add a custom report for it

    :param name: This must match the `ph_output_type` attribute of the PredictionHead for which the report should be used.
                 (e.g. TokenPredictionHead => `per_token`, YourCustomHead => `some_new_type`).
    :type name: str
    :param implementation: Function to be executed. It must take lists of `y_true` and `y_pred` as input and return a
                           printable object (e.g. string or dict).
                           See sklearns.metrics.classification_report for an example.
    :type implementation: function
    """
    registered_reports[name] = implementation

def simple_accuracy(preds, labels):
    # works also with nested lists of different lengths (needed for masked LM task)
    if type(preds) == type(labels) == list:
        preds = np.array(list(flatten_list(preds)))
        labels = np.array(list(flatten_list(labels)))
    assert type(preds) == type(labels) == np.ndarray
    correct = preds == labels
    return {"acc": correct.mean()}

def acc_and_f1(preds, labels):
    acc = simple_accuracy(preds, labels)
    f1 = f1_score(y_true=labels, y_pred=preds)
    return {"acc": acc, "f1": f1, "acc_and_f1": (acc + f1) / 2}

def f1_macro(preds, labels):
    return {"f1_macro": f1_score(y_true=labels, y_pred=preds, average="macro")}

def pearson_and_spearman(preds, labels):
    pearson_corr = pearsonr(preds, labels)[0]
    spearman_corr = spearmanr(preds, labels)[0]
    return {
        "pearson": pearson_corr,
        "spearman": spearman_corr,
        "corr": (pearson_corr + spearman_corr) / 2,
    }

def compute_metrics(metric, preds, labels):
    assert len(preds) == len(labels)
    if metric == "mcc":
        return {"mcc": matthews_corrcoef(labels, preds)}
    elif metric == "acc":
        return simple_accuracy(preds, labels)
    elif metric == "acc_f1":
        return acc_and_f1(preds, labels)
    elif metric == "pear_spear":
        return pearson_and_spearman(preds, labels)
    # TODO this metric seems very specific for NER and doesnt work for
    elif metric == "seq_f1":
        return {"seq_f1": ner_f1_score(labels, preds)}
    elif metric == "f1_macro":
        return f1_macro(preds, labels)
    elif metric == "squad":
        return squad(preds, labels)
    elif metric == "mse":
        return {"mse": mean_squared_error(preds, labels)}
    elif metric == "r2":
        return {"r2": r2_score(preds, labels)}
    elif metric == "top_n_recall":
        return {"top_n_recall": top_n_recall(preds, labels)}
    # elif metric == "masked_accuracy":
    #     return simple_accuracy(preds, labels, ignore=-1)
    elif metric in registered_metrics:
        metric_func = registered_metrics[metric]
        return metric_func(preds, labels)
    else:
        raise KeyError(metric)

def compute_report_metrics(head, preds, labels):
    if head.ph_output_type in registered_reports:
        report_fn = registered_reports[head.ph_output_type]
    elif head.ph_output_type == "per_token":
        report_fn = token_classification_report
    elif head.ph_output_type == "per_sequence":
        report_fn = classification_report
    elif head.ph_output_type == "per_token_squad":
        report_fn = lambda *args, **kwargs: "Not Implemented"
    elif head.ph_output_type == "per_sequence_continuous":
        report_fn = r2_score
    else:
        raise AttributeError(f"No report function for head.ph_output_type '{head.ph_output_type}'. "
                             f"You can register a custom one via register_report(name='{head.ph_output_type}', implementation=<your_report_function>")

    # CHANGE PARAMETERS, not all report_fn accept digits
    if head.ph_output_type in ["per_sequence"]:
        # supply labels as all possible combination because if ground truth labels do not cover
        # all values in label_list (maybe dev set is small), the report will break
        if head.model_type == "multilabel_text_classification":
            # For multilabel classification, we don't eval with string labels here, but with multihot vectors.
            # Therefore we need to supply all possible label ids instead of label values.
            all_possible_labels = list(range(len(head.label_list)))
        else:
            all_possible_labels = head.label_list
        return report_fn(
            labels,
            preds,
            digits=4,
            labels=all_possible_labels,
            target_names=head.label_list
        )
    else:
        return report_fn(labels, preds)

def squad_EM(preds, labels):
    # TODO write comment describing function
    n_docs = len(preds)
    n_correct = 0
    for doc_idx in range(n_docs):
        pred_start, pred_end, _ = preds[doc_idx][0][0]
        curr_labels = labels[doc_idx]
        if (pred_start, pred_end) in curr_labels:
            n_correct += 1
    return n_correct/n_docs

def squad_f1(preds, labels):
    f1_scores = []
    n_docs = len(preds)
    for i in range(n_docs):
        best_pred = preds[i][0]
        best_f1 = max([squad_f1_single(best_pred, label) for label in labels[i]])
        f1_scores.append(best_f1)
    return np.mean(f1_scores)

def squad_f1_single(pred, label, pred_idx=0):
    label_start, label_end = label
    pred_start, pred_end, _ = pred[pred_idx]
    if (pred_start + pred_end == 0) or (label_start + label_end == 0):
        if pred_start == label_start:
            return 1.0
        else:
            return 0.0
    pred_span = list(range(pred_start, pred_end + 1))
    label_span = list(range(label_start, label_end + 1))
    n_overlap = len([x for x in pred_span if x in label_span])
    if n_overlap == 0:
        return 0.0
    precision = n_overlap / len(pred_span)
    recall = n_overlap / len(label_span)
    f1 = (2 * precision * recall) / (precision + recall)
    return f1

def squad(preds, labels):
    em = squad_EM(preds=preds, labels=labels)
    f1 = squad_f1(preds=preds, labels=labels)
    top_recall = top_n_recall(preds=preds, labels=labels)
    return {"EM": em, "f1": f1, "top_n_recall": top_recall}

def top_n_recall(preds, labels):
    answer_in_top_n = []
    n_questions = len(preds)
    for i in range(n_questions):
        f1_score = 0
        current_preds = preds[i][0]
        for idx, pred in enumerate(current_preds):
            f1_score = max([squad_f1_single(current_preds, label, pred_idx=idx) for label in labels[i]])
            if f1_score:
                break
        if f1_score:
            answer_in_top_n.append(1)
        else:
            answer_in_top_n.append(0)

    return np.mean(answer_in_top_n)


from datetime import datetime
from pathlib import Path

import pandas as pd
import requests
import typer
from clearml import Task
from sklearn.metrics import accuracy_score
from tqdm import tqdm

from captcha.config import net_config

def check_equality(pred: list, label: list, save_path: str):
    if pred != label:
        pd.DataFrame(
            {"pred": [", ".join(map(str, pred))], "label": [", ".join(map(str, label))]}
        ).to_csv(f"{save_path}/unequal.csv", index=False, header=False, mode="a")
        return False
    return True

def get_response(files: list, url: str):
    files_opened = []
    for file in files:
        files_opened.append(("data", open(file, "rb")))

    response = requests.post(
        url=f"{url}/predict",
        files=files_opened,
    )
    return response

def metric_test(
    csv_path: str,
    url: str,
    batch_size: int = 15,
    task_name: str = "metric_test",
    log_clearml: bool = True,
):
    task = (
        Task.init(
            project_name="captcha_metrics",
            task_name=f"{task_name}_{net_config.model_path}",
        )
        if log_clearml
        else None
    )
    logger = None if task is None else task.get_logger()

    outputs_path = f"outputs/{datetime.now()}"
    Path(outputs_path).mkdir(exist_ok=True, parents=True)

    files = list(pd.read_csv(csv_path)["filepath"].values)
    batches = [
        files[i * batch_size : (i + 1) * batch_size]
        for i in range(int(len(files) / batch_size))
    ]
    preds = []
    labels = []
    equals = []
    for batch in tqdm(batches, desc=f"batch prediction... (batch_size={batch_size})"):
        predictons = get_response(batch, url).json()
        for item in range(len(predictons["predictions"])):
            eq = check_equality(
                predictons["predictions"][item],
                predictons["labels"][item],
                outputs_path,
            )
            equals.append(eq)
            preds.extend(predictons["predictions"][item])
            labels.extend(predictons["labels"][item])

    accuracy_per_symbol = accuracy_score(labels, preds)
    accuracy_per_image = sum(equals) / len(equals)
    print(
        f"data: {csv_path}\nmodel: {net_config.model_path}\naccuracy_per_symbol: {accuracy_per_symbol}"
    )
    print(f"\naccuracy_per_image: {accuracy_per_image}")

    if logger is not None:
        logger.report_scalar(
            f"Accuracy per symbol",
            net_config.model_path,
            iteration=0,
            value=accuracy_per_symbol,
        )
        logger.report_scalar(
            f"Accuracy per image",
            net_config.model_path,
            iteration=0,
            value=accuracy_per_image,
        )
        logger.flush()

if __name__ == "__main__":
    typer.run(metric_test)


#-*- coding:utf-8 -*-
"""
    desc: 二值化算法：OSTU
    author:MeteorMan
    datetime:2020/10/27
"""

import cv2
from matplotlib import pyplot as plt

#读取图片
img = cv2.imread('../img/2-1.png')

#1.将图像转换为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#绘制灰度图
plt.subplot(311)#采用3行1列布局，本次占用第1行第1列
plt.imshow(gray_img, 'gray')
plt.title('input image')
plt.xticks([])
plt.yticks([])

#2.对灰度图使用ostu算法
ret1, th1 = cv2.threshold(gray_img, 0, 255, cv2.THRESH_OTSU)
#绘制灰度直方图
plt.subplot(312)
plt.hist(gray_img.ravel(), 256)
#标注ostu阈值所在直线
plt.axvline(x=ret1, color='red', label='ostu')
plt.legend(loc='upper right')
plt.title('Histogram')
plt.xticks([])
plt.yticks([])

#绘制二值化图像
plt.subplot(313)
plt.imshow(th1, "gray")
plt.title('output image')
plt.xticks([])
plt.yticks([])
plt.show()


import json
import pickle
import random
from datetime import datetime

import nltk
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from flask import Flask, jsonify, render_template, request
from nltk.stem.porter import PorterStemmer

stemmer = PorterStemmer()

def bag_of_words(tokenized_sentence, all_words):
    tokenized_sentence = [stemmer.stem(w.lower()) for w in tokenized_sentence]

    bag = np.zeros(len(all_words), dtype=np.float32)
    for idx, w in enumerate(all_words):
        if w in tokenized_sentence:
            bag[idx] = 1.0

    return bag

# Fully connected neural network with three hidden layer

class NeuralNet(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(NeuralNet, self).__init__()
        self.l1 = nn.Linear(input_size, hidden_size)
        self.l2 = nn.Linear(hidden_size, hidden_size)
        self.l3 = nn.Linear(hidden_size, num_classes)
        self.relu = nn.ReLU()  # activation function

    def forward(self, x):
        out = self.l1(x)
        out = self.relu(out)
        out = self.l2(out)
        out = self.relu(out)
        out = self.l3(out)
        # no activation and no softmax, cross entropy loss applies that for us
        return out

random.seed(datetime.now())

device = torch.device('cpu')
FILE = "models/data.pth"
model_data = torch.load(FILE)

input_size = model_data['input_size']
hidden_size = model_data['hidden_size']
output_size = model_data['output_size']
all_words = model_data['all_words']
tags = model_data['tags']
model_state = model_data['model_state']

nlp_model = NeuralNet(input_size, hidden_size, output_size).to(device)
nlp_model.load_state_dict(model_state)
nlp_model.eval()

Description = pd.read_csv("data/Description.csv")
Description['Disease'] = Description['Disease'].apply(
    lambda x: x.lower().strip(" "))

Precaution = pd.read_csv("data/Precaution.csv")
Precaution['Disease'] = Precaution['Disease'].apply(
    lambda x: x.lower().strip(" "))

Severity = pd.read_csv("data/Severity.csv")
Severity = Severity.applymap(
    lambda s: s.lower().strip(" ").replace(" ", "") if type(s) == str else s)

with open('data/symptomsList.pickle', 'rb') as data_file:
    symptoms_list = pickle.load(data_file)

with open('models/model.pickle', 'rb') as modelFile:
    prediction_model = pickle.load(modelFile)

User_Request = set()

app = Flask(__name__)

def GET_Symptom(sentence):
    sentence = nltk.word_tokenize(sentence)
    X = bag_of_words(sentence, all_words)
    X = X.reshape(1, X.shape[0])
    X = torch.from_numpy(X)

    output = nlp_model(X)
    _, predicted = torch.max(output, dim=1)
    tag = tags[predicted.item()]

    probs = torch.softmax(output, dim=1)
    prob = probs[0][predicted.item()]
    prob = prob.item()

    return tag, prob

# app.route() has been added to handle both GET and POST requests

@app.route('/')
def index():
    data = []
    User_Request.clear()
    file = open("static/assets/files/symptoms.txt", "r")
    all_symptoms = file.readlines()
    for s in all_symptoms:
        data.append(s.replace("'", "").replace("_", " ").replace(",\n", ""))
    data = json.dumps(data)

    return render_template('index.html', data=data)

# app.route() has been added to handle both GET and POST requests

@app.route('/symptom', methods=['GET', 'POST'])
def Prediction():

    x_test = []
    severity = []

    print(request.json)

    sentence = request.json['sentence']
    if sentence.replace(".", "").replace("!", "").lower().strip() == "finish":

        if not User_Request:
            BOT_Response = random.choice(
                ["Whoops, I can't know what disease you may have if you don't enter any symptoms :)",
                 "Oh nooo, you forgot to enter your symptoms",
                 "Please enter some symptoms!"])
        else:

            for each in symptoms_list:
                if each in User_Request:
                    x_test.append(1)
                else:
                    x_test.append(0)

            x_test = np.asarray(x_test)

            disease = prediction_model.predict(x_test.reshape(1, -1))[0]
            print(disease)

            description = Description.loc[Description['Disease'] == disease.strip(
                " ").lower(), 'Description'].iloc[0]

            precaution = Precaution[Precaution['Disease'] == disease.strip(
                " ").lower()]

            precautions = 'Precautions: ' + \
                precaution.Precaution_1.iloc[0] + ", " + precaution.Precaution_2.iloc[0] + \
                ", " + precaution.Precaution_3.iloc[0]

            BOT_Response = "Predicted Disease: " + disease + \
                ".

 Description: " + description + "

" + precautions + ""

            for each in User_Request:

                severity.append(Severity.loc[Severity['Symptom'] == each.lower(
                ).strip(" ").replace(" ", ""), 'weight'].iloc[0])

            if np.mean(severity) > 4 or np.max(severity) > 5:
                BOT_Response = BOT_Response + \
                    "

TUDIA isn't a real Doctor, it is only a Chatbot. You should consider talking a real Doctor soon."

            User_Request.clear()
            severity.clear()

    else:
        symptom, prob = GET_Symptom(sentence)

        print("Symptom:", symptom, ", prob:", prob)

        if prob > .5:
            BOT_Response = "Hmm, Any other symptoms other than " + \
                symptom + "?"
            User_Request.add(symptom)
        else:
            BOT_Response = "Sorry, I am only able to answer questions relating to health issues"

        print("User symptoms:", User_Request)

    return jsonify(BOT_Response.replace("_", " "))

# run the flask
if __name__ == "__main__":
    app.run()


import numpy as np
import pandas as pd
import operator
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
from tkinter import *
from collections import Counter

datingTest = pd.read_table('datingTestSet.txt',header = None)
datingTest.head()

def myplot(traindata,labels):

    fig,axes = plt.subplots(nrows=2,ncols=2,sharex=False,sharey=False,figsize=(13,8))
    colorlist = []
    for i in labels:
        if i == 1:
            colorlist.append("red")
        if i == 2:
            colorlist.append("black")
        if i == 3:
            colorlist.append("orange")

    axes[0][0].scatter(x=traindata[:,0], y=traindata[:,1], color=colorlist, s=12, alpha=0.5)
    axes0_set_title = axes[0][0].set_title(u"the number of flyer miles and the video games")
    axes0_set_xlabel = axes[0][0].set_xlabel(u"Frequent flyer miles earned each year")
    axes0_set_ylabel = axes[0][0].set_ylabel(u"Time spent playing video games")
    plt.setp(axes0_set_title,size=9, weight="bold", color="red")
    plt.setp(axes0_set_xlabel,size=7, weight="bold", color="black")
    plt.setp(axes0_set_ylabel,size=7, weight="bold", color="black")

    axes[0][1].scatter(x=traindata[:,0],y=traindata[:,2], color=colorlist, s=12, alpha=0.5)
    axes1_set_title = axes[0][1].set_title(u"frequent flyer miles is proportional to ice cream")
    axes1_set_xlabel = axes[0][1].set_xlabel(u"Frequent flyer miles earned each year")
    axes1_set_ylabel = axes[0][1].set_ylabel(u"Weekly consumption of ice cream liters")
    plt.setp(axes1_set_title,size=9, weight="bold", color="red")
    plt.setp(axes1_set_xlabel,size=7, weight="bold", color="black")
    plt.setp(axes1_set_ylabel,size=7, weight="bold", color="black")

    axes[1][0].scatter(x = traindata[:,1],y=traindata[:,2], color=colorlist, s=12, alpha=0.5)
    axes2_set_title = axes[1][0].set_title(u"The percentage of video games and  ice cream")
    axes2_set_xlabel = axes[1][0].set_xlabel(u"Time spent playing video games")
    axes2_set_ylabel = axes[1][0].set_ylabel(u"Weekly consumption of ice cream liters")
    plt.setp(axes2_set_title,size=9, weight="bold", color="red")
    plt.setp(axes2_set_xlabel,size=7, weight="bold", color="black")
    plt.setp(axes2_set_ylabel,size=7, weight="bold", color="black")

    largeDoses = mlines.Line2D([],[],color="red",marker=".", markersize=6,label="largeDoses")
    smallDoses = mlines.Line2D([],[],color="black",marker=".", markersize=6, label="smallDoses")
    didntLike = mlines.Line2D([],[],color="orange",marker=".", markersize=6, label="didntLike")
    axes[0,0].legend(handles=[largeDoses,smallDoses,didntLike])
    axes[0,1].legend(handles=[largeDoses,smallDoses,didntLike])
    axes[1,0].legend(handles=[largeDoses,smallDoses,didntLike])

    plt.show()

def putinfile(file):
    putin=open(file)
    readfile=putin.readlines()
    datalength=len(readfile)
    traindata=np.zeros((datalength,3))
    labels=[]
    index=0
    for line in readfile:
        line = line.rstrip()
        line = line.split("\t")
        traindata[index,:] = line[0:3]
        if line[-1] == "largeDoses":
            labels.append(1)
        if line[-1] == "smallDoses":
            labels.append(2)
        if line[-1] == "didntLike":
            labels.append(3)
        index += 1
    return traindata, labels

def standdata(traindata):
    meandata0 = np.mean(traindata,axis=0)
    stddata0 = np.std(traindata,axis=0)
    length = traindata.shape[0]
    meandata1 = np.tile(meandata0,(length,1))
    stddata1 = np.tile(stddata0,(length,1))
    standdata = (traindata-meandata1)/stddata1
    return standdata, meandata0, stddata0

def classfy0(testdata,traindata,labels,k=10):
    length=traindata.shape[0]
    diffdata = traindata-np.tile(testdata,(length,1))
    sqrdata = diffdata**2
    sumdata = (sqrdata.sum(axis=1))**0.5
    sumdatasort = sumdata.argsort()
    classfy1 = {}
    classlist = []
    for i in range(k):
        classlist.append(labels[sumdatasort[i]])
    for i in classlist:
        classfy1[i] = classfy1.get(i,0)+1
    classfy2 = sorted(classfy1.items(),key=operator.itemgetter(1),reverse=True)
    classfy=classfy2[0][0]
    return classfy

def classfyperson():
    file="datingTestSet.txt"
    traindata, labels = putinfile(file)
    traindata, meandata0, stddata0 = standdata(traindata)

    test1=float(t0.get())
    test2=float(t1.get())
    test3=float(t2.get())
    testdata=np.array([test1,test2,test3])
    testdata=(testdata-meandata0)/stddata0
    classfy = classfy0(testdata,traindata,labels)
    text = []
    if classfy == 1:
        text.append("女嘉宾对你的感觉是：largeDoses.你很有机会哦！！！")
    elif classfy == 2:
        text.append("女嘉宾对你的感觉是：smallDoses.你需要加油努力！！")
    else:
        text.append("女嘉宾对你的感觉是：didntLike. 你没有机会,放弃吧！")
    Label(window, text=Counter(text).most_common(1)[0][0][:21]).grid(row=6, column=0)
    Label(window, text=Counter(text).most_common(1)[0][0][21:]).grid(row=6, column=1)
    return classfy

if __name__ == "__main__":

    window = Tk()
    window.title("Appointment match")
    window.geometry('500x250')
    Label(window, text='每年出差/旅行的公里数:').grid(row=0, column=0)
    Label(window, text='玩游戏消耗时间的百分比:').grid(row=1, column=0)
    Label(window, text='每周消费的冷饮公升数:').grid(row=2, column=0)
    t_0 = StringVar()
    t_1 = StringVar()
    t_2 = StringVar()
    t0 = Entry(window, textvariable=t_0)
    t1 = Entry(window, textvariable=t_1)
    t2 = Entry(window, textvariable=t_2)
    t0.grid(row=0, column=1, padx=10, pady=5)
    t1.grid(row=1, column=1, padx=10, pady=5)
    t2.grid(row=2, column=1, padx=10, pady=5)
    Button(window, text='确认', width=10, command=classfyperson).grid(row=3, column=0, sticky=W, padx=10, pady=5)
    Button(window, text='退出', width=10, command=window.quit).grid(row=3, column=1, sticky=E, padx=10, pady=5)
    window.mainloop()

    file = "datingTestSet.txt"
    traindata, labels = putinfile(file)
    myplot(traindata, labels)
    classfy = classfyperson()


import abc
import copy
import json
import math
from random import random
import numpy as np
import time

from matplotlib import pyplot as plt

class SA:
    def __init__(self, initial_solution, T=100, T_min=0.05, alpha=0.99, max_time=12000, iters=1, iters_2=10, iters_3=10):
        self.T = T  # initial temperature
        self.T_min = T_min  # minimum temperature
        self.alpha = alpha  # the coefficient of temperature decreasing
        self.max_time = max_time  # time
        self.iter = iters  # the number of iterations in each temperature, which changes the radii of the orbits
        self.iter_2 = iters_2  # the number of iterations which changes the radii of the star
        self.iter_3 = iters_3
        self.history = {'T': [], 'solutions': [], 'scores': []}

        self.curr_solution = initial_solution
        self.new_solution = None  # placeholder
        self.score = self.evaluation()
        self.best_score = float('inf')  # choose the largest number as the initial best score

        self.time = 30 * 60

    @abc.abstractmethod
    def move(self):
        """Create a similar solution"""
        pass

    @abc.abstractmethod
    def move_2(self):
        """Create a similar solution"""
        pass

    @abc.abstractmethod
    def move_3(self):
        """Create a similar solution"""
        pass

    @abc.abstractmethod
    def evaluation(self):
        """Evaluate the solution, and give a score"""
        pass

    def check(self, new_score):  # Metropolis
        if new_score <= self.score:
            return True
        else:
            p = math.exp((new_score - self.score) / self.T)
            # print(p)
            if random() > p:
                return True
            else:
                return False

    def annealing(self):
        count = 0
        flag = 0
        flag_2 = 0

        bests = list()
        start = time.time()

        print(
            '================================================Simulation================================================\n')
        print("{:<15}{:<24}{:<24}{:<24}{:<24}".format('Iteration', 'Temperature', 'Best Score', 'Global Best Score',
                                                      'Num of Accepted Solution'))
        # print('Iteration\t\tTemperature\t\t\t\tBest Score\t\t\tGlobal Best Score\t\t\tNum of Accepted Solution')
        flag_c = 0  # convergence
        max_flag_c = 100
        while self.T > self.T_min and self.time > time.time() - start and count < 30000:

            solutions = [self.curr_solution]
            scores = [self.score]
            movement1 = 0.01
            movement2 = 0.1
            movement3 = 1
            temp_score = self.best_score
            for i in range(self.iter):  # iter is the number of iterations applied in each temperature
                self.move(movement1)
                for j in range(self.iter_2):
                    if self.move_2(movement2) == -1:
                        continue
                    for p in range(self.iter_3):
                        self.move_3(movement3)
                        new_score = self.evaluation()
                        if self.check(new_score):  # check whether accept the new solution or not
                            solution_copy = copy.deepcopy(self.curr_solution)
                            solutions.append(solution_copy)
                            scores.append(new_score)
                        if new_score < self.best_score:
                            temp_score = new_score
            if self.best_score == temp_score:
                flag_c = flag_c+1
            else:
                self.best_score = temp_score
                flag_c = 0

            if flag_c > max_flag_c:
                break

            bests.append(self.best_score)

            score_min = min(scores)  # find the smallest score
            scores = np.array(scores)
            indexes = np.argsort(scores)
            index = indexes[0]
            self.history['T'].append(self.T)
            copied_solution = copy.deepcopy(self.curr_solution)

            copied_solution['star1']['orbital_radius'] = copied_solution['star1']['orbital_radius'] * copied_solution[
                'orbit_coefficient_1_2']
            copied_solution['star2']['orbital_radius'] = copied_solution['star2']['orbital_radius'] * copied_solution[
                'orbit_coefficient_1_2']

            copied_solution['star1']['mass'] = copied_solution['star1']['mass'] * copied_solution[
                'mass_coefficient_1_2']
            copied_solution['star2']['mass'] = copied_solution['star2']['mass'] * copied_solution[
                'mass_coefficient_1_2']

            self.history['solutions'].append(copied_solution)
            self.history['scores'].append(score_min)

            # best solution in this temperature
            self.curr_solution = copy.deepcopy(solutions[index])

            # cooling
            self.T = self.T * self.alpha
            count += 1

            print("{:<15}{:<24}{:<24}{:<24}{:<24}".format(count, self.T, score_min, min(self.history['scores']),
                                                          (len(solutions) - 1) / self.iter / self.iter_2 / self.iter_3))
            # print(len(solutions))

            if count % 300 == 0:
                self.evaluation(True)
                # print(self.curr_solution)
                # print(copied_solution)
                f = open('Solutions.json', 'w')
                json_file = json.dumps(self.history, sort_keys=False, indent=4, separators=(',', ': '))
                f.write(json_file)
                f.write('\n')
                f.flush()
                f.close()

            # no accepted solutions in past 5 iterations
            accept_rate = (len(solutions) - 1) / (self.iter * self.iter_2 * self.iter_3)
            if accept_rate < 0.01:
                flag += 1
            else:
                flag = 0

            if flag > 10:
                break

            if accept_rate > 0.5:
                flag_2 += 1
            else:
                flag_2 = 0

            if flag_2 > 10:
                movement1 = movement1 / 2
                movement2 = movement2 / 2
                movement3 = movement3 / 2

                flag_2 = 0
        # best solution
        scores = self.history['scores']
        score_min = min(scores)  # find the smallest score
        index = scores.index(score_min)
        solution = self.history['solutions'][index]
        print(solution)
        if flag_c > max_flag_c:
            masses1 = list()
            masses2 = list()
            radii1 = list()
            radii2 = list()
            orb_radii1 = list()
            orb_radii2 = list()
            temperatures1 = list()
            temperatures2 = list()
            luminosities1 = list()
            luminosities2 = list()
            for i in range(1, max_flag_c-1):
                mass1 = np.array(self.history['solutions'][-i]['star1']['mass'])
                masses1.append(mass1)

                mass2 = np.array(self.history['solutions'][-i]['star2']['mass'])
                masses2.append(mass2)

                radius1 = np.array(self.history['solutions'][-i]['star1']['radius'])
                radii1.append(radius1)

                radius2 = np.array(self.history['solutions'][-i]['star2']['radius'])
                radii2.append(radius2)

                orb_radius1 = np.array(self.history['solutions'][-i]['star1']['orbital_radius'])
                orb_radii1.append(orb_radius1)

                orb_radius2 = np.array(self.history['solutions'][-i]['star2']['orbital_radius'])
                orb_radii2.append(orb_radius2)

                temperature1 = np.array(self.history['solutions'][-i]['star1']['temperature'])
                temperatures1.append(temperature1)

                temperature2 = np.array(self.history['solutions'][-i]['star2']['temperature'])
                temperatures2.append(temperature2)

                luminosity1 = np.array(self.history['solutions'][-i]['star1']['luminosity'])
                luminosities1.append(luminosity1)

                luminosity2 = np.array(self.history['solutions'][-i]['star2']['luminosity'])
                luminosities2.append(luminosity2)

            max1 = np.max(np.array(masses1)) - solution['star1']['mass'], solution['star1']['mass'] - np.min(np.array(masses1))
            max2 = np.max(np.array(masses2)) - solution['star2']['mass'], solution['star2']['mass'] - np.min(np.array(masses2))
            max3 = np.max(np.array(radii1)) - solution['star1']['radius'], solution['star1']['radius'] - np.min(np.array(radii1))
            max4 = np.max(np.array(radii2)) - solution['star2']['radius'], solution['star2']['radius'] - np.min(np.array(radii2))
            max5 = np.max(np.array(orb_radii1)) - solution['star1']['orbital_radius'], solution['star1']['orbital_radius'] - np.min(np.array(orb_radii1))
            max6 = np.max(np.array(orb_radii2)) - solution['star2']['orbital_radius'], solution['star2']['orbital_radius'] - np.min(np.array(orb_radii2))
            max7 = np.max(np.array(temperatures1)) - solution['star1']['temperature'], solution['star1']['temperature'] - np.min(np.array(temperatures1))
            max8 = np.max(np.array(temperatures2)) - solution['star2']['temperature'], solution['star2']['temperature'] - np.min(np.array(temperatures2))
            max9 = np.max(np.array(luminosities1)) - solution['star1']['luminosity'], solution['star1']['luminosity'] - np.min(np.array(luminosities1))
            max10 = np.max(np.array(luminosities2)) - solution['star2']['luminosity'], solution['star2']['luminosity']- np.min(np.array(luminosities2))

            # (0.0018995985822873873, 0.0039048129299021905)(0.0002517162539118212, 0.0005174276776717668)
            # (0.04338698495735738, 0.05314646443909699)(0.2748217448053736, 0.22038367903134137)
            # (0.0016720164881031119, 0.0008103145636880749)(0.012618017712412666, 0.0061151092647664385)
            # (10.632141308024075, -10.632141308024075)(-0.7971023970940223, 10.165417302824608)
            # (0.4574050512393768, 0.4.691916878266029)(0.29281410831785104,0.2009242169958244)

            # print(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10)
            print(max1, max2, max3, max4, max5, max6, max7, max8, max9, max10)

        # plot
        plt.figure(figsize=(30, 8))
        # plt.gcf().set_size_inches(512 * 4 / 100, 512 * 2 / 100)
        plt.subplot(2, 3, 1)
        plt.margins(0, 0)
        plt.subplots_adjust(top=0.93, bottom=0.07, right=0.93, left=0.07)
        plt.subplots_adjust(hspace=0.3)
        plt.subplots_adjust(wspace=0.6)
        # plt.subplots_adjust(left=0.125, right=0.9, bottom=0.1, top=0.9)

        plt.ticklabel_format(axis="x", style="plain", scilimits=(0, 0))
        plt.xlabel('The number of iterations')
        plt.ylabel('Score')
        plt.plot(range(count), self.history['scores'])
        plt.title("Figure 1", fontsize='large', fontweight='bold')

        plt.subplot(2, 3, 2)
        plt.ticklabel_format(axis="x", style="plain", scilimits=(0, 0))
        plt.xlabel("The number of iterations")
        plt.ylabel("The value of radius")
        fig2_1 = plt.plot(range(count), [solution_index['star1']['radius'] for solution_index in self.history['solutions']],
                 label=r'Radius of primary star')
        fig2_2 = plt.plot(range(count), [solution_index['star2']['radius'] for solution_index in self.history['solutions']],
                 label=r'Radius of secondary star', color='red')
        plt.legend(loc='upper right')
        plt.title("Figure 2", fontsize='large', fontweight='bold')

        ax1 = plt.subplot(2, 3, 3)
        plt.ticklabel_format(axis="x", style="plain", scilimits=(0, 0))
        ax1.set_xlabel("The number of iterations")
        ax1.set_ylabel("Orbital radius of the primary star")

        plt.plot(range(count), [solution_index['star1']['orbital_radius'] for solution_index in self.history['solutions']],
                 label=r'Orbital radius (L: primary; R: secondary)')
        plt.legend(loc='upper right')
        ax2 = ax1.twinx()
        ax2.set_ylabel('Orbital radius of the secondary star')
        plt.plot(range(count), [solution_index['star2']['orbital_radius'] for solution_index in self.history['solutions']], label=r'Orbital radius (L: primary; R: secondary)')
        plt.title("Figure 3", fontsize='large', fontweight='bold')

        ax3 = plt.subplot(2, 3, 4)
        plt.ticklabel_format(axis="x", style="plain", scilimits=(0, 0))
        ax3.set_xlabel("The number of iterations")
        ax3.set_ylabel("Temperature of the primary star")
        plt.plot(range(count), [solution_index['star1']['temperature'] for solution_index in self.history['solutions']],
                 label=r'Temperature of primary star', color="red")
        plt.legend(loc='lower right')

        ax4 = ax3.twinx()
        plt.plot(range(count), [solution_index['star2']['temperature'] for solution_index in self.history['solutions']],
                 label=r'Temperature of secondary star')
        plt.legend(loc='upper right')
        ax4.set_ylabel("Temperature of the secondary star")
        plt.title("Figure 4", fontsize='large', fontweight='bold')

        ax5 = plt.subplot(2, 3, 5)
        plt.ticklabel_format(axis="x", style="plain", scilimits=(0, 0))
        ax5.set_xlabel("The number of iterations")
        ax5.set_ylabel("Luminosity of the primary star")
        plt.plot(range(count), [solution_index['star1']['luminosity'] for solution_index in self.history['solutions']],
                 label=r'Luminosity of primary star', color="red")
        plt.legend(loc='lower right')

        ax6 = plt.twinx()
        plt.plot(range(count), [solution_index['star2']['luminosity'] for solution_index in self.history['solutions']],
                 label=r'Luminosity of secondary star')
        plt.legend(loc='upper right')
        ax6.set_ylabel("Luminosity of the secondary star")
        plt.title("Figure 5", fontsize='large', fontweight='bold')

        ax7 = plt.subplot(2, 3, 6)
        plt.ticklabel_format(axis="x", style="plain", scilimits=(0, 0))
        ax7.set_xlabel("The number of iterations")
        ax7.set_ylabel("Mass of the primary star")

        plt.plot(range(count), [solution_index['star1']['mass'] for solution_index in self.history['solutions']],
                 label=r'Mass (L: primary; R: secondary)')
        plt.legend(loc='upper right')
        plt.title("Figure 6", fontsize='large', fontweight='bold')

        ax8 = plt.twinx()
        ax8.set_ylabel("Mass of the secondary star")
        plt.plot(range(count), [solution_index['star2']['mass'] for solution_index in self.history['solutions']])
        plt.show()


from collections import defaultdict

n, m = map(int, input().split())
indegree = [0] * (n+1)
graph = defaultdict(list)
result = []
q = []

for _ in range(m):
    student1, student2 = map(int, input().split())
    graph[student1].append(student2)
    indegree[student2] += 1

for i in range(1,n+1):
    if indegree[i] == 0:
        q.append(i)

while q:
    n = q.pop()
    result.append(str(n))

    for i in graph[n]:
        indegree[i] -= 1
        if indegree[i] == 0:
            q.append(i)

print(" ".join(result))


# print("Hello world!")

# s = input("输入一个数字:")

# print(s)
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,10)

y = np.sin(x)

plt.plot(x,y)

num=input("请输入你的名字：")
plt.show()

print(num)


from .base_mermaid import MermaidBase
from .utils import *
import mermaid.utils as py_utils
import mermaid.simple_interface as SI
class MermaidIter(MermaidBase):
    def name(self):
        return 'mermaid-iter'

    def initialize(self,opt):
        """
        :param opt: ParameterDict, task settings
        :return:
        """
        MermaidBase.initialize(self,opt)
        method_name =opt['tsk_set']['method_name']
        if method_name =='affine':
            self.affine_on = True
            self.nonp_on = False
        elif method_name =='nonp':
            self.affine_on = True
            self.nonp_on = True
        elif method_name=='nonp_only':
            self.affine_on = False
            self.nonp_on = True
        self.si = SI.RegisterImagePair()
        self.opt_optim = opt['tsk_set']['optim']
        self.compute_inverse_map = opt['tsk_set']['reg'][('compute_inverse_map', False,"compute the inverse transformation map")]
        self.opt_mermaid= self.opt['tsk_set']['reg']['mermaid_iter']
        self.use_init_weight = self.opt_mermaid[('use_init_weight',False,'whether to use init weight for RDMM registration')]
        self.init_weight = None
        self.setting_for_mermaid_affine = self.opt_mermaid[('mermaid_affine_json','','the json path for the setting for mermaid affine')]
        self.setting_for_mermaid_nonp = self.opt_mermaid[('mermaid_nonp_json','','the json path for the setting for mermaid non-parametric')]
        nonp_settings = pars.ParameterDict()
        nonp_settings.load_JSON(self.setting_for_mermaid_nonp)
        self.nonp_model_name  = nonp_settings['model']['registration_model']['type']
        self.weights_for_fg = self.opt_mermaid[('weights_for_fg',[0,0,0,0,1.],'regularizer weight for the foregound area, this should be got from the mermaid_json file')]
        self.weights_for_bg = self.opt_mermaid[('weights_for_bg',[0,0,0,0,1.],'regularizer weight for the background area')]
        self.saved_mermaid_setting_path = None
        self.saved_affine_setting_path = None
        self.inversed_map = None
        self.use_01 = True

    def set_input(self, data, is_train=True):
        data[0]['image'] =(data[0]['image'].cuda()+1)/2
        if 'label' in data[0]:
            data[0]['label'] =data[0]['label'].cuda()
        moving, target, l_moving,l_target = get_reg_pair(data[0])
        input = data[0]['image']
        self.input_img_sz  = list(moving.shape)[2:]
        self.original_spacing = data[0]['original_spacing']
        self.original_im_sz =  data[0]['original_sz']
        self.spacing = data[0]['spacing'][0] if self.use_physical_coord else 1. / (np.array(self.input_img_sz) - 1)
        self.spacing = np.array(self.spacing) if type(self.spacing) is not np.ndarray else self.spacing
        self.moving = moving
        self.target = target
        self.l_moving = l_moving
        self.l_target = l_target
        self.input = input
        self.fname_list = list(data[1])
        self.pair_path = data[0]['pair_path']

    def affine_optimization(self):
        """
        call affine optimization registration in mermaid
        :return: warped image, transformation map, affine parameter, loss(None)
        """
        self.si = SI.RegisterImagePair()
        extra_info = pars.ParameterDict()
        extra_info['pair_name'] = self.fname_list
        af_sigma = self.opt_mermaid['affine']['sigma']
        self.si.opt = None
        self.si.set_initial_map(None)
        if self.saved_affine_setting_path is None:
            self.saved_affine_setting_path = self.save_setting(self.setting_for_mermaid_affine,self.record_path,'affine_setting.json')

        cur_affine_json_saving_path =(os.path.join(self.record_path,'cur_settings_affine.json'),os.path.join(self.record_path,'cur_settings_affine_comment.json'))
        self.si.register_images(self.moving, self.target, self.spacing,extra_info=extra_info,LSource=self.l_moving,LTarget=self.l_target,
                                visualize_step=None,
                                use_multi_scale=True,
                                rel_ftol=0,
                                similarity_measure_sigma=af_sigma,
                                json_config_out_filename=cur_affine_json_saving_path,  #########################################
                                params =self.saved_affine_setting_path) #'../easyreg/cur_settings_affine_tmp.json'

        self.output = self.si.get_warped_image()
        self.phi = self.si.opt.optimizer.ssOpt.get_map()
        self.phi = self.phi.detach().clone()
        # for i in range(self.dim):
        #     self.phi[:, i, ...] = self.phi[:, i, ...] / ((self.input_img_sz[i] - 1) * self.spacing[i])

        Ab = self.si.opt.optimizer.ssOpt.model.Ab

        if self.compute_inverse_map:
            inv_Ab = py_utils.get_inverse_affine_param(Ab.detach())
            identity_map = py_utils.identity_map_multiN([1, 1] + self.input_img_sz, self.spacing)
            self.inversed_map = py_utils.apply_affine_transform_to_map_multiNC(inv_Ab, torch.Tensor(identity_map).cuda())  ##########################3
            self.inversed_map = self.inversed_map.detach()
        self.afimg_or_afparam = Ab
        save_affine_param_with_easyreg_custom(self.afimg_or_afparam,self.record_path,self.fname_list,affine_compute_from_mermaid=True)
        return self.output.detach_(), self.phi.detach_(), self.afimg_or_afparam.detach_(), None

    def nonp_optimization(self):
        """
        call non-parametric image registration in mermaid
        if the affine registration is performed first, the affine transformation map would be taken as the initial map
        if the init weight on mutli-gaussian regularizer are set, the initial weight map would be computed from the label map, make sure the model called support spatial variant regularizer

        :return: warped image, transformation map, affined image, loss(None)
        """
        affine_map = None
        if self.affine_on:
            affine_map = self.si.opt.optimizer.ssOpt.get_map()

        self.si =  SI.RegisterImagePair()
        extra_info = pars.ParameterDict()
        extra_info['pair_name'] = self.fname_list
        self.si.opt = None
        if affine_map is not None:
            self.si.set_initial_map(affine_map.detach(), self.inversed_map)

        if self.use_init_weight:
            init_weight = get_init_weight_from_label_map(self.l_moving, self.spacing,self.weights_for_bg,self.weights_for_fg)
            init_weight = py_utils.compute_warped_image_multiNC(init_weight,affine_map,self.spacing,spline_order=1,zero_boundary=False)
            self.si.set_weight_map(init_weight.detach(), freeze_weight=True)

        if self.saved_mermaid_setting_path is None:
            self.saved_mermaid_setting_path = self.save_setting(self.setting_for_mermaid_nonp,self.record_path,"nonp_setting.json")
        cur_mermaid_json_saving_path =(os.path.join(self.record_path,'cur_settings_nonp.json'),os.path.join(self.record_path,'cur_settings_nonp_comment.json'))
        self.si.register_images(self.moving, self.target, self.spacing, extra_info=extra_info, LSource=self.l_moving,
                                LTarget=self.l_target,
                                visualize_step=None,
                                use_multi_scale=True,
                                rel_ftol=0,
                                compute_inverse_map=self.compute_inverse_map,
                                json_config_out_filename=cur_mermaid_json_saving_path,
                                params=self.saved_mermaid_setting_path) #'../mermaid_settings/cur_settings_svf_dipr.json'
        self.afimg_or_afparam = self.output # here return the affine image
        self.output = self.si.get_warped_image()
        self.phi = self.si.opt.optimizer.ssOpt.get_map()
        # for i in range(self.dim):
        #     self.phi[:,i,...] = self.phi[:,i,...]/ ((self.input_img_sz[i]-1)*self.spacing[i])

        if self.compute_inverse_map:
            self.inversed_map = self.si.get_inverse_map().detach()
        return self.output.detach_(), self.phi.detach_(), self.afimg_or_afparam.detach_() if self.afimg_or_afparam is not None else None, None

    def save_setting(self,path, output_path,fname='mermaid_setting.json'):
        """
        save the mermaid settings into task record folder
        :param path: path of mermaid setting file
        :param output_path: path of task record folder
        :param fname: saving name
        :return: saved setting path
        """
        params = pars.ParameterDict()
        params.load_JSON(path)
        os.makedirs(output_path, exist_ok=True)
        output_path = os.path.join(output_path, fname)
        params.write_JSON(output_path, save_int=False)
        return output_path

    def save_image_into_original_sz_with_given_reference(self):
        """
        save the image into original sz (the sz before resampling) and with the original physical settings, i.e. spacing, origin, orientation
        :return:
        """
        # the original image sz in one batch should be the same
        self._save_image_into_original_sz_with_given_reference(self.pair_path,self.phi, inverse_phis=self.inversed_map, use_01=self.use_01)

    def forward(self,input=None):
        if self.affine_on and not self.nonp_on:
            return self.affine_optimization()
        elif self.affine_on and self.nonp_on:
            self.affine_optimization()
            return self.nonp_optimization()

        else:
            return self.nonp_optimization()

    def cal_val_errors(self):
        self.cal_test_errors()

    def cal_test_errors(self):
        self.get_evaluation()

    def get_jacobi_val(self):
        """
        :return: the sum of absolute value of  negative determinant jacobi, the num of negative determinant jacobi voxels
        """
        return self.jacobi_val

    def get_the_jacobi_val(self):
        return self.jacobi_val

    def __get_adaptive_smoother_map(self):
        """
        get the adaptive smoother weight map from spatial-variant regualrizer model
        supported weighting type 'sqrt_w_K_sqrt_w' and 'w_K_w'
        for weighting type == 'w_k_w'
        :math:'\sigma^{2}(x)=\sum_{i=0}^{N-1} w^2_{i}(x) \sigma_{i}^{2}'
        for weighting type = 'sqrt_w_K_sqrt_w'
        :math:'\sigma^{2}(x)=\sum_{i=0}^{N-1} w_{i}(x) \sigma_{i}^{2}'
        :return: adapative smoother weight map \sigma
        """
        model =  self.si.opt.optimizer.ssOpt.model
        smoother =  self.si.opt.optimizer.ssOpt.model.smoother
        adaptive_smoother_map = model.local_weights.detach()
        gaussian_weights = smoother.get_gaussian_weights().detach()
        print(" the current global gaussian weight is {}".format(gaussian_weights))

        gaussian_stds = smoother.get_gaussian_stds().detach()
        print(" the current global gaussian stds is {}".format(gaussian_stds))
        view_sz = [1] + [len(gaussian_stds)] + [1] * len(self.spacing)
        gaussian_stds = gaussian_stds.view(*view_sz)
        weighting_type = smoother.weighting_type
        if weighting_type == 'w_K_w':
            adaptive_smoother_map = adaptive_smoother_map**2 # todo   this is only necessary when we use w_K_W

        smoother_map = adaptive_smoother_map*(gaussian_stds**2)
        smoother_map = torch.sqrt(torch.sum(smoother_map,1,keepdim=True))
        #_,smoother_map = torch.max(adaptive_smoother_map.detach(),dim=1,keepdim=True)
        self._display_stats(smoother_map.float(),'statistic for weighted smoother map')
        return smoother_map

    def __get_momentum(self):
        param =  self.si.get_model_parameters()
        return param['m'].detach()
    def _display_stats(self, Ia, iname):
        """
        statistic analysis on variable
        :param Ia: the input variable
        :param iname: variable name
        :return:
        """

        Ia_min = Ia.min().detach().cpu().numpy()
        Ia_max = Ia.max().detach().cpu().numpy()
        Ia_mean = Ia.mean().detach().cpu().numpy()
        Ia_std = Ia.std().detach().cpu().numpy()

        print('{}:the: [min {:.2f},mean {:.2f},max {:.2f}](std {:.2f})'.format(iname, Ia_min,Ia_mean,Ia_max,Ia_std))

    def get_extra_to_plot(self):
        """
        plot extra image, i.e. the initial weight map of rdmm model
        :return:
        """
        if self.nonp_on:
            if self.nonp_model_name=='lddmm_adapt_smoother_map':
                return self.__get_adaptive_smoother_map(), 'inital_weight'
            else:
                return self.__get_momentum(), "Momentum"
        else:
            return None, None

    def set_val(self):
        self.is_train = False

    def set_debug(self):
        self.is_train = False

    def set_test(self):
        self.is_train = False


# -*- coding: utf-8 -*-
import smtplib
import email
# Constructing text
from email.mime.text import MIMEText
# Constructing picture
from email.mime.image import MIMEImage
# Collection objects
from email.mime.multipart import MIMEMultipart
from email.header import Header
class emaile:
    def __init__(self, sender, license, receiver, subject, attach_file):
        self.sender = sender
        self.license = license
        self.receiver = receiver
        self.subject = subject
        self.attach_file = attach_file

    def send_emaile(self):
        # SMTP Service
        mail_host = "smtp.163.com"
        # Sender's mailbox
        mail_sender = self.sender
        # E-mail authorization code
        mail_license = self.license
        # Recipient mailbox, could be multiple recipients
        mail_receivers = self.receiver

        mm = MIMEMultipart('related')

        # Message subject
        subject_content = self.subject
        # Sender
        mm["From"] = "sender_name" + "<" + self.sender + ">"
        # Accepter
        mm["To"] = "receiver_1_name<" + self.receiver[0] + ">,receiver_2_name<" + self.receiver[1] + ">"
        # Main object
        mm["Subject"] = Header(subject_content,'utf-8')

        # Emaile body
        body_content = """你好，请查收昨天的销售额！"""
        # Parameters
        message_text = MIMEText(body_content,"plain","utf-8")
        # Add text
        mm.attach(message_text)

        # Constructing attachments
        atta = MIMEText(open(self.attach_file, 'rb').read(), 'base64', 'utf-8')
        # Set attachment information
        atta["Content-Disposition"] = 'attachment; filename="3000.csv"'
        # Add attachments to email messages
        mm.attach(atta)

        # Create SMTP object
        stp = smtplib.SMTP()
        # Set the domain name and port of the sender's mailbox, the port address is 25
        stp.connect(mail_host, 25)
        # set_debuglevel(1) could print out all the information interacting with the SMTP server
        stp.set_debuglevel(1)
        # Log in to the mailbox
        stp.login(mail_sender,mail_license)
        # Send mail
        stp.sendmail(mail_sender, mail_receivers, mm.as_string())
        print("邮件发送成功")
        # Close SMTP object
        stp.quit()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Set Tool: Line-by-line text file union, intersection, difference etc.
Timo Würsch July 2013
"""

def textfile_to_set(filename, tolower):
    lines_as_set = set()
    with open(filename, "r") as f:
        for line in f:
            line = line.strip()
            if tolower:
                line = line.lower()
            if line != "":
                lines_as_set.add(line)
    return lines_as_set

if __name__ == '__main__':
    # Parse command line arguments
    import argparse, sys
    argument_parser = argparse.ArgumentParser()
    argument_parser.add_argument("-i", "--insensitive", help = "Make matching case insensitive. Default is case-sensitive.", action = "store_true")
    argument_parser.add_argument("fileA", help = "File with the elements for set A")
    argument_parser.add_argument("op", help = "Operator. One of: union (u, +), intersect (n, i), difference (d, -), equals (equal, is, =), strictsuperset (>, strictsuper), superset (>=, super), strictsubset (<, strictsub), subset (<=, sub)")
    argument_parser.add_argument("fileB", help = "File with the elements for set B")
    args = argument_parser.parse_args()
    if args.op.lower() in ["u", "union", "+"]:
        operator = "union"
    elif args.op.lower() in ["i", "intersect", "intersection", "n"]:
        operator = "intersection"
    elif args.op.lower() in ["d", "diff", "difference", "-"]:
        operator = "difference"
    elif args.op.lower() in ["equals", "equal", "is", "="]:
        operator = "equality"
    elif args.op.lower() in [">", "strictsuperset", "strictsuper"]:
        operator = "strictsuperset"
    elif args.op.lower() in [">=", "superset", "super"]:
        operator = "superset"
    elif args.op.lower() in ["<", "strictsubset", "strictsub"]:
        operator = "strictsubset"
    elif args.op.lower() in ["<=", "subset", "sub"]:
        operator = "subset"
    elif args.op.lower() in ["disjoint", "dis"]:
        operator = "disjoint"
    else:
        print("Unknown operator \"" + args.op + "\".")
        argument_parser.print_help()
        sys.exit(1)

    # Read files
    try:
        setA = textfile_to_set(args.fileA, args.insensitive)
    except IOError:
        print("Could not open file A \"" + args.fileA + "\"")
        sys.exit(1)
    try:
        setB = textfile_to_set(args.fileB, args.insensitive)
    except IOError:
        print("Could not open file B \"" + args.fileB + "\"")
        sys.exit(1)

    # Calculate
    if operator == "union":
        result = setA.union(setB)
    elif operator == "intersection":
        result = setA.intersection(setB)
    elif operator == "difference":
        result = setA.difference(setB)
    elif operator == "equality":
        result = setA == setB
    elif operator == "strictsuperset":
        result = setA > setB
    elif operator == "superset":
        result = setA >= setB
    elif operator == "strictsubset":
        result = setA < setB
    elif operator == "subset":
        result = setA <= setB
    elif operator == "disjoint":
        result = setA.isdisjoint(setB)

    # Output
    if type(result) == set:
        for element in result:
            print(element)
    elif type(result) == bool:
        if result:
            print(str(True))
        else:
            print(str(False))

    # That's all folks!
    sys.exit(0)


"""
Tests for most frequent UDF
"""
import numpy as np
import pytest

@pytest.mark.parametrize("source_type", ["snowflake", "spark"], indirect=True)
@pytest.mark.parametrize(
    "counts, expected",
    [
        ({}, None),
        ({"__MISSING__": None}, None),
        (None, None),
        ({"a": 1}, "a"),
        ({"a": 1, "b": 2, "c": 3}, "c"),
        ({"a": 1, "b": np.nan, "c": 3}, "c"),
        ({"a": np.nan}, None),
        ({"a": -1, "b": np.nan, "c": -3}, "a"),
    ],
)
@pytest.mark.asyncio
async def test_most_frequent_udf(session, to_object, counts, expected):
    """
    Test most frequent UDF
    """

    expr = to_object(counts)
    query = f"SELECT F_COUNT_DICT_MOST_FREQUENT({expr}) AS OUT"
    df = await session.execute_query(query)
    actual = df.iloc[0]["OUT"]
    assert actual == expected

@pytest.mark.parametrize("source_type", ["snowflake", "spark"], indirect=True)
@pytest.mark.parametrize(
    "counts, expected",
    [
        ({}, np.nan),
        ({"__MISSING__": None}, np.nan),
        # (None, np.nan),  skipped because spark returns None bypassing UDF call
        ({"a": 1}, 1),
        ({"a": 1, "b": 2, "c": 3}, 3),
        ({"a": 1, "b": np.nan, "c": 3}, 3),
        ({"a": np.nan}, np.nan),
    ],
)
@pytest.mark.asyncio
async def test_most_frequent_value_udf(session, to_object, counts, expected):
    """
    Test most frequent value UDF
    """

    expr = to_object(counts)
    query = f"SELECT F_COUNT_DICT_MOST_FREQUENT_VALUE({expr}) AS OUT"
    df = await session.execute_query(query)
    actual = df.iloc[0]["OUT"]
    np.testing.assert_allclose(actual, expected, equal_nan=True)


from zope.interface import implements
from zope.component import getUtility
from hurry.workflow.interfaces import IWorkflowState

from Products.CMFCore.utils import getToolByName

from getpaid.core.interfaces import IOrderManager
from getpaid.core.interfaces import workflow_states

from getpaid.pxpay.interfaces import IPXPayInvalidMessageError, \
     IPXPayNetworkError
from getpaid.pxpay.exceptions import PXPayInvalidMessageException, \
     PXPayNetworkException

fs = workflow_states.order.finance

def redirect_url(context, order_id):
    site_root = getToolByName(context, 'portal_url').getPortalObject()
    site_url = site_root.absolute_url()
    return_url = '/'.join((site_url,
                           '@@getpaid-order',
                           order_id,
                           '@@pxpay-communication-error'))
    return return_url

class PXPayInvalidMessageError(object):

    implements(IPXPayInvalidMessageError)

    redirect = True

    def __call__(self, context, request, order_id, message):
        msg = "invalid message recieved from pxpay "
        if order_id:
            msg += "order " + order_id
            order_manager = getUtility( IOrderManager )
            order = order_manager.get(order_id)
            state = order.finance_workflow.state().getState()
            if state == fs.REVIEWING:
                order.finance_workflow.fireTransition('processor-cancelled',
                                                      comment="payment gateway failed")
            if state == fs.CHARGING:
                order.finance_workflow.fireTransition('processor-charging-cancelled',
                                                      comment="payment gateway failed")
        if not self.redirect:
            raise PXPayInvalidMessageException("Invalid pxpay message for order " + \
                                               order_id)
        url = redirect_url(context, order_id)
        request.response.redirect(url)

class PXPayNetworkError(object):

    implements(IPXPayNetworkError)

    redirect = True

    def __call__(self, context, request, order_id):
        msg = "invalid message recieved from pxpay "
        if order_id:
            msg += "order " + order_id
            order_manager = getUtility( IOrderManager )
            order = order_manager.get(order_id)
            state = order.finance_workflow.state().getState()
            if state == fs.REVIEWING:
                order.finance_workflow.fireTransition('processor-cancelled',
                                                      comment="payment gateway failed")
            if state == fs.CHARGING:
                order.finance_workflow.fireTransition('processor-charging-cancelled',
                                                      comment="payment gateway failed")

        if not self.redirect:
            raise PXPayNetworkException("PXPay network error occured for order " + \
                                        order_id)
        url = redirect_url(context, order_id)
        request.response.redirect(url)


from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from PIL import ImageTk, Image
from test import *

class Order_Page:
    def __init__(self, root):
        self.root = root
        self.root.title("PHARMACY")
        self.root.geometry("1440x880+0+0")

        self.bg_img = ImageTk.PhotoImage(file = "bg_img_4.jpg")
        bg = Label(self.root, image = self.bg_img)
        bg.place(x = -200, y = -10)

        def Exit():
            self.root.destroy()

        def Order():
            Card = Card_entry.get()
            CVV = CVV_entry.get()
            Phone = Phone_entry.get()

            if len(Card) != 0 and len(CVV) != 0 and len(Phone) != 0:
                if len(Card) == 16:
                    if len(CVV) == 3:
                        if len(Phone) == 10:
                            messagebox.showinfo("THANK YOU", "YOUR ORDER WAS PLACED\n\n\t      THANK YOU\n\t      VISIT AGAIN")
                            Exit()
                        else:
                            messagebox.showinfo("ERROR", "INVALID PHONE NUMBER")
                    else:
                        messagebox.showinfo("ERROR", "INVALID CVV")
                else:
                    messagebox.showinfo("ERROR", "INVALID CARD NUMBER")
            else:
                messagebox.showinfo("ERROR", "PLEASE ENTER THE CORRECT DETAILS")

        Login_canvas = Canvas(self.root, width = 570, height = 400, bg = "#14a3df")
        Login_canvas.place(x = 420, y = 300)

        title = Label(self.root, text = "PHARMACY", font = ("times new roman", 100, "bold"), bg = "yellow", fg = "red", bd = 10, relief = GROOVE)
        title.place(x = 0, y = 0, relwidth = 1)

        place_order_title = Label(Login_canvas, text = "PLACE ORDER", font = ("times new roman", 50, "bold"), bg = "yellow", fg = "red", bd = 10, relief = GROOVE)
        place_order_title.place(x = 0, y = 0, relwidth = 1)

        order_button = Button(Login_canvas, text = "   ORDER   ", font = ("times new roman", 30, "bold"), relief = GROOVE, command = lambda:Order())
        order_button.place(x = 370, y = 350)

        exit_button = Button(Login_canvas, text = "    EXIT    ", font = ("times new roman", 30, "bold"), relief = GROOVE, command = lambda:Exit())
        exit_button.place(x = 50, y = 350)

        Card_Lable = Label(Login_canvas, text = " CARD NUMBER:  ", font = ("times new roman", 30, "bold"))
        Card_Lable.place(x = 15, y = 140)

        CVV_Lable = Label(Login_canvas, text = "   CVV NUMBER:   ", font = ("times new roman", 30, "bold"))
        CVV_Lable.place(x = 15, y = 200)

        Phone_Lable = Label(Login_canvas, text = "PHONE NUMBER:", font = ("times new roman", 30, "bold"))
        Phone_Lable.place(x = 15, y = 260)

        Card_entry = Entry(Login_canvas, font = ("times new roman", 25, "bold"), fg = "black", bg = "white", relief = GROOVE )
        Card_entry.place(x = 290, y = 140)

        CVV_entry = Entry(Login_canvas, font = ("times new roman", 25, "bold"), fg = "black", bg = "white", relief = GROOVE)
        CVV_entry.place(x = 290, y = 200)

        Phone_entry = Entry(Login_canvas, font = ("times new roman", 25, "bold"), fg = "black", bg = "white", relief = GROOVE)
        Phone_entry.place(x = 290, y = 260)

# OP = Tk()
# Order_Page(OP)
# OP.mainloop()


# program to read a DonkeyCar Catalog File
import os,json

# this program assumes that test.json is in the same directory as this script
# get the direcotry that this script is running
script_dir = os.path.dirname(__file__)
# get a relative path to the script dir
path_to_json_file = script_dir + '/test.json'

# Open the JSON test file for read only
f = open(path_to_json_file, 'r')

# returns JSON object as a dictionary
data = json.load(f)

# Iterating through the json file for the items in the drive data dictionary
for i in data['driveData']:
    print(i)

# Close the JSON file
f.close()


from __future__ import annotations

from typing import MutableMapping, MutableSequence

import proto  # type: ignore

from google.cloud.bigquery_storage_v1.types import arrow
from google.cloud.bigquery_storage_v1.types import avro
from google.cloud.bigquery_storage_v1.types import protobuf
from google.cloud.bigquery_storage_v1.types import stream
from google.cloud.bigquery_storage_v1.types import table
from google.protobuf import timestamp_pb2  # type: ignore
from google.protobuf import wrappers_pb2  # type: ignore
from google.rpc import status_pb2  # type: ignore

__protobuf__ = proto.module(
    package="google.cloud.bigquery.storage.v1",
    manifest={
        "CreateReadSessionRequest",
        "ReadRowsRequest",
        "ThrottleState",
        "StreamStats",
        "ReadRowsResponse",
        "SplitReadStreamRequest",
        "SplitReadStreamResponse",
        "CreateWriteStreamRequest",
        "AppendRowsRequest",
        "AppendRowsResponse",
        "GetWriteStreamRequest",
        "BatchCommitWriteStreamsRequest",
        "BatchCommitWriteStreamsResponse",
        "FinalizeWriteStreamRequest",
        "FinalizeWriteStreamResponse",
        "FlushRowsRequest",
        "FlushRowsResponse",
        "StorageError",
        "RowError",
    },
)

class CreateReadSessionRequest(proto.Message):
    r"""Request message for ``CreateReadSession``.

    Attributes:
        parent (str):
            Required. The request project that owns the session, in the
            form of ``projects/{project_id}``.
        read_session (google.cloud.bigquery_storage_v1.types.ReadSession):
            Required. Session to be created.
        max_stream_count (int):
            Max initial number of streams. If unset or zero, the server
            will provide a value of streams so as to produce reasonable
            throughput. Must be non-negative. The number of streams may
            be lower than the requested number, depending on the amount
            parallelism that is reasonable for the table. There is a
            default system max limit of 1,000.

            This must be greater than or equal to
            preferred_min_stream_count. Typically, clients should either
            leave this unset to let the system to determine an upper
            bound OR set this a size for the maximum "units of work" it
            can gracefully handle.
        preferred_min_stream_count (int):
            The minimum preferred stream count. This
            parameter can be used to inform the service that
            there is a desired lower bound on the number of
            streams. This is typically a target parallelism
            of the client (e.g. a Spark cluster with
            N-workers would set this to a low multiple of N
            to ensure good cluster utilization).

            The system will make a best effort to provide at
            least this number of streams, but in some cases
            might provide less.
    """

    parent: str = proto.Field(
        proto.STRING,
        number=1,
    )
    read_session: stream.ReadSession = proto.Field(
        proto.MESSAGE,
        number=2,
        message=stream.ReadSession,
    )
    max_stream_count: int = proto.Field(
        proto.INT32,
        number=3,
    )
    preferred_min_stream_count: int = proto.Field(
        proto.INT32,
        number=4,
    )

class ReadRowsRequest(proto.Message):
    r"""Request message for ``ReadRows``.

    Attributes:
        read_stream (str):
            Required. Stream to read rows from.
        offset (int):
            The offset requested must be less than the
            last row read from Read. Requesting a larger
            offset is undefined. If not specified, start
            reading from offset zero.
    """

    read_stream: str = proto.Field(
        proto.STRING,
        number=1,
    )
    offset: int = proto.Field(
        proto.INT64,
        number=2,
    )

class ThrottleState(proto.Message):
    r"""Information on if the current connection is being throttled.

    Attributes:
        throttle_percent (int):
            How much this connection is being throttled.
            Zero means no throttling, 100 means fully
            throttled.
    """

    throttle_percent: int = proto.Field(
        proto.INT32,
        number=1,
    )

class StreamStats(proto.Message):
    r"""Estimated stream statistics for a given read Stream.

    Attributes:
        progress (google.cloud.bigquery_storage_v1.types.StreamStats.Progress):
            Represents the progress of the current
            stream.
    """

    class Progress(proto.Message):
        r"""

        Attributes:
            at_response_start (float):
                The fraction of rows assigned to the stream that have been
                processed by the server so far, not including the rows in
                the current response message.

                This value, along with ``at_response_end``, can be used to
                interpolate the progress made as the rows in the message are
                being processed using the following formula:
                ``at_response_start + (at_response_end - at_response_start) * rows_processed_from_response / rows_in_response``.

                Note that if a filter is provided, the ``at_response_end``
                value of the previous response may not necessarily be equal
                to the ``at_response_start`` value of the current response.
            at_response_end (float):
                Similar to ``at_response_start``, except that this value
                includes the rows in the current response.
        """

        at_response_start: float = proto.Field(
            proto.DOUBLE,
            number=1,
        )
        at_response_end: float = proto.Field(
            proto.DOUBLE,
            number=2,
        )

    progress: Progress = proto.Field(
        proto.MESSAGE,
        number=2,
        message=Progress,
    )

class ReadRowsResponse(proto.Message):
    r"""Response from calling ``ReadRows`` may include row data, progress
    and throttling information.

    This message has `oneof`_ fields (mutually exclusive fields).
    For each oneof, at most one member field can be set at the same time.
    Setting any member of the oneof automatically clears all other
    members.

    .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields

    Attributes:
        avro_rows (google.cloud.bigquery_storage_v1.types.AvroRows):
            Serialized row data in AVRO format.

            This field is a member of `oneof`_ ``rows``.
        arrow_record_batch (google.cloud.bigquery_storage_v1.types.ArrowRecordBatch):
            Serialized row data in Arrow RecordBatch
            format.

            This field is a member of `oneof`_ ``rows``.
        row_count (int):
            Number of serialized rows in the rows block.
        stats (google.cloud.bigquery_storage_v1.types.StreamStats):
            Statistics for the stream.
        throttle_state (google.cloud.bigquery_storage_v1.types.ThrottleState):
            Throttling state. If unset, the latest
            response still describes the current throttling
            status.
        avro_schema (google.cloud.bigquery_storage_v1.types.AvroSchema):
            Output only. Avro schema.

            This field is a member of `oneof`_ ``schema``.
        arrow_schema (google.cloud.bigquery_storage_v1.types.ArrowSchema):
            Output only. Arrow schema.

            This field is a member of `oneof`_ ``schema``.
    """

    avro_rows: avro.AvroRows = proto.Field(
        proto.MESSAGE,
        number=3,
        oneof="rows",
        message=avro.AvroRows,
    )
    arrow_record_batch: arrow.ArrowRecordBatch = proto.Field(
        proto.MESSAGE,
        number=4,
        oneof="rows",
        message=arrow.ArrowRecordBatch,
    )
    row_count: int = proto.Field(
        proto.INT64,
        number=6,
    )
    stats: "StreamStats" = proto.Field(
        proto.MESSAGE,
        number=2,
        message="StreamStats",
    )
    throttle_state: "ThrottleState" = proto.Field(
        proto.MESSAGE,
        number=5,
        message="ThrottleState",
    )
    avro_schema: avro.AvroSchema = proto.Field(
        proto.MESSAGE,
        number=7,
        oneof="schema",
        message=avro.AvroSchema,
    )
    arrow_schema: arrow.ArrowSchema = proto.Field(
        proto.MESSAGE,
        number=8,
        oneof="schema",
        message=arrow.ArrowSchema,
    )

class SplitReadStreamRequest(proto.Message):
    r"""Request message for ``SplitReadStream``.

    Attributes:
        name (str):
            Required. Name of the stream to split.
        fraction (float):
            A value in the range (0.0, 1.0) that
            specifies the fractional point at which the
            original stream should be split. The actual
            split point is evaluated on pre-filtered rows,
            so if a filter is provided, then there is no
            guarantee that the division of the rows between
            the new child streams will be proportional to
            this fractional value. Additionally, because the
            server-side unit for assigning data is
            collections of rows, this fraction will always
            map to a data storage boundary on the server
            side.
    """

    name: str = proto.Field(
        proto.STRING,
        number=1,
    )
    fraction: float = proto.Field(
        proto.DOUBLE,
        number=2,
    )

class SplitReadStreamResponse(proto.Message):
    r"""Response message for ``SplitReadStream``.

    Attributes:
        primary_stream (google.cloud.bigquery_storage_v1.types.ReadStream):
            Primary stream, which contains the beginning portion of
            \|original_stream|. An empty value indicates that the
            original stream can no longer be split.
        remainder_stream (google.cloud.bigquery_storage_v1.types.ReadStream):
            Remainder stream, which contains the tail of
            \|original_stream|. An empty value indicates that the
            original stream can no longer be split.
    """

    primary_stream: stream.ReadStream = proto.Field(
        proto.MESSAGE,
        number=1,
        message=stream.ReadStream,
    )
    remainder_stream: stream.ReadStream = proto.Field(
        proto.MESSAGE,
        number=2,
        message=stream.ReadStream,
    )

class CreateWriteStreamRequest(proto.Message):
    r"""Request message for ``CreateWriteStream``.

    Attributes:
        parent (str):
            Required. Reference to the table to which the stream
            belongs, in the format of
            ``projects/{project}/datasets/{dataset}/tables/{table}``.
        write_stream (google.cloud.bigquery_storage_v1.types.WriteStream):
            Required. Stream to be created.
    """

    parent: str = proto.Field(
        proto.STRING,
        number=1,
    )
    write_stream: stream.WriteStream = proto.Field(
        proto.MESSAGE,
        number=2,
        message=stream.WriteStream,
    )

class AppendRowsRequest(proto.Message):
    r"""Request message for ``AppendRows``.

    Because AppendRows is a bidirectional streaming RPC, certain parts
    of the AppendRowsRequest need only be specified for the first
    request before switching table destinations. You can also switch
    table destinations within the same connection for the default
    stream.

    The size of a single AppendRowsRequest must be less than 10 MB in
    size. Requests larger than this return an error, typically
    ``INVALID_ARGUMENT``.

    .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields

    Attributes:
        write_stream (str):
            Required. The write_stream identifies the append operation.
            It must be provided in the following scenarios:

            -  In the first request to an AppendRows connection.

            -  In all subsequent requests to an AppendRows connection,
               if you use the same connection to write to multiple
               tables or change the input schema for default streams.

            For explicitly created write streams, the format is:

            -  ``projects/{project}/datasets/{dataset}/tables/{table}/streams/{id}``

            For the special default stream, the format is:

            -  ``projects/{project}/datasets/{dataset}/tables/{table}/streams/_default``.

            An example of a possible sequence of requests with
            write_stream fields within a single connection:

            -  r1: {write_stream: stream_name_1}

            -  r2: {write_stream: /*omit*/}

            -  r3: {write_stream: /*omit*/}

            -  r4: {write_stream: stream_name_2}

            -  r5: {write_stream: stream_name_2}

            The destination changed in request_4, so the write_stream
            field must be populated in all subsequent requests in this
            stream.
        offset (google.protobuf.wrappers_pb2.Int64Value):
            If present, the write is only performed if the next append
            offset is same as the provided value. If not present, the
            write is performed at the current end of stream. Specifying
            a value for this field is not allowed when calling
            AppendRows for the '_default' stream.
        proto_rows (google.cloud.bigquery_storage_v1.types.AppendRowsRequest.ProtoData):
            Rows in proto format.

            This field is a member of `oneof`_ ``rows``.
        trace_id (str):
            Id set by client to annotate its identity.
            Only initial request setting is respected.
        missing_value_interpretations (MutableMapping[str, google.cloud.bigquery_storage_v1.types.AppendRowsRequest.MissingValueInterpretation]):
            A map to indicate how to interpret missing value for some
            fields. Missing values are fields present in user schema but
            missing in rows. The key is the field name. The value is the
            interpretation of missing values for the field.

            For example, a map {'foo': NULL_VALUE, 'bar': DEFAULT_VALUE}
            means all missing values in field foo are interpreted as
            NULL, all missing values in field bar are interpreted as the
            default value of field bar in table schema.

            If a field is not in this map and has missing values, the
            missing values in this field are interpreted as NULL.

            This field only applies to the current request, it won't
            affect other requests on the connection.

            Currently, field name can only be top-level column name,
            can't be a struct field path like 'foo.bar'.
        default_missing_value_interpretation (google.cloud.bigquery_storage_v1.types.AppendRowsRequest.MissingValueInterpretation):
            Optional. Default missing value interpretation for all
            columns in the table. When a value is specified on an
            ``AppendRowsRequest``, it is applied to all requests on the
            connection from that point forward, until a subsequent
            ``AppendRowsRequest`` sets it to a different value.
            ``missing_value_interpretation`` can override
            ``default_missing_value_interpretation``. For example, if
            you want to write ``NULL`` instead of using default values
            for some columns, you can set
            ``default_missing_value_interpretation`` to
            ``DEFAULT_VALUE`` and at the same time, set
            ``missing_value_interpretations`` to ``NULL_VALUE`` on those
            columns.
    """

    class MissingValueInterpretation(proto.Enum):
        r"""An enum to indicate how to interpret missing values of fields
        that are present in user schema but missing in rows. A missing
        value can represent a NULL or a column default value defined in
        BigQuery table schema.

        Values:
            MISSING_VALUE_INTERPRETATION_UNSPECIFIED (0):
                Invalid missing value interpretation.
                Requests with this value will be rejected.
            NULL_VALUE (1):
                Missing value is interpreted as NULL.
            DEFAULT_VALUE (2):
                Missing value is interpreted as column
                default value if declared in the table schema,
                NULL otherwise.
        """
        MISSING_VALUE_INTERPRETATION_UNSPECIFIED = 0
        NULL_VALUE = 1
        DEFAULT_VALUE = 2

    class ProtoData(proto.Message):
        r"""ProtoData contains the data rows and schema when constructing
        append requests.

        Attributes:
            writer_schema (google.cloud.bigquery_storage_v1.types.ProtoSchema):
                The protocol buffer schema used to serialize the data.
                Provide this value whenever:

                -  You send the first request of an RPC connection.

                -  You change the input schema.

                -  You specify a new destination table.
            rows (google.cloud.bigquery_storage_v1.types.ProtoRows):
                Serialized row data in protobuf message
                format. Currently, the backend expects the
                serialized rows to adhere to proto2 semantics
                when appending rows, particularly with respect
                to how default values are encoded.
        """

        writer_schema: protobuf.ProtoSchema = proto.Field(
            proto.MESSAGE,
            number=1,
            message=protobuf.ProtoSchema,
        )
        rows: protobuf.ProtoRows = proto.Field(
            proto.MESSAGE,
            number=2,
            message=protobuf.ProtoRows,
        )

    write_stream: str = proto.Field(
        proto.STRING,
        number=1,
    )
    offset: wrappers_pb2.Int64Value = proto.Field(
        proto.MESSAGE,
        number=2,
        message=wrappers_pb2.Int64Value,
    )
    proto_rows: ProtoData = proto.Field(
        proto.MESSAGE,
        number=4,
        oneof="rows",
        message=ProtoData,
    )
    trace_id: str = proto.Field(
        proto.STRING,
        number=6,
    )
    missing_value_interpretations: MutableMapping[
        str, MissingValueInterpretation
    ] = proto.MapField(
        proto.STRING,
        proto.ENUM,
        number=7,
        enum=MissingValueInterpretation,
    )
    default_missing_value_interpretation: MissingValueInterpretation = proto.Field(
        proto.ENUM,
        number=8,
        enum=MissingValueInterpretation,
    )

class AppendRowsResponse(proto.Message):
    r"""Response message for ``AppendRows``.

    This message has `oneof`_ fields (mutually exclusive fields).
    For each oneof, at most one member field can be set at the same time.
    Setting any member of the oneof automatically clears all other
    members.

    .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields

    Attributes:
        append_result (google.cloud.bigquery_storage_v1.types.AppendRowsResponse.AppendResult):
            Result if the append is successful.

            This field is a member of `oneof`_ ``response``.
        error (google.rpc.status_pb2.Status):
            Error returned when problems were encountered. If present,
            it indicates rows were not accepted into the system. Users
            can retry or continue with other append requests within the
            same connection.

            Additional information about error signalling:

            ALREADY_EXISTS: Happens when an append specified an offset,
            and the backend already has received data at this offset.
            Typically encountered in retry scenarios, and can be
            ignored.

            OUT_OF_RANGE: Returned when the specified offset in the
            stream is beyond the current end of the stream.

            INVALID_ARGUMENT: Indicates a malformed request or data.

            ABORTED: Request processing is aborted because of prior
            failures. The request can be retried if previous failure is
            addressed.

            INTERNAL: Indicates server side error(s) that can be
            retried.

            This field is a member of `oneof`_ ``response``.
        updated_schema (google.cloud.bigquery_storage_v1.types.TableSchema):
            If backend detects a schema update, pass it
            to user so that user can use it to input new
            type of message. It will be empty when no schema
            updates have occurred.
        row_errors (MutableSequence[google.cloud.bigquery_storage_v1.types.RowError]):
            If a request failed due to corrupted rows, no
            rows in the batch will be appended. The API will
            return row level error info, so that the caller
            can remove the bad rows and retry the request.
        write_stream (str):
            The target of the append operation. Matches the write_stream
            in the corresponding request.
    """

    class AppendResult(proto.Message):
        r"""AppendResult is returned for successful append requests.

        Attributes:
            offset (google.protobuf.wrappers_pb2.Int64Value):
                The row offset at which the last append
                occurred. The offset will not be set if
                appending using default streams.
        """

        offset: wrappers_pb2.Int64Value = proto.Field(
            proto.MESSAGE,
            number=1,
            message=wrappers_pb2.Int64Value,
        )

    append_result: AppendResult = proto.Field(
        proto.MESSAGE,
        number=1,
        oneof="response",
        message=AppendResult,
    )
    error: status_pb2.Status = proto.Field(
        proto.MESSAGE,
        number=2,
        oneof="response",
        message=status_pb2.Status,
    )
    updated_schema: table.TableSchema = proto.Field(
        proto.MESSAGE,
        number=3,
        message=table.TableSchema,
    )
    row_errors: MutableSequence["RowError"] = proto.RepeatedField(
        proto.MESSAGE,
        number=4,
        message="RowError",
    )
    write_stream: str = proto.Field(
        proto.STRING,
        number=5,
    )

class GetWriteStreamRequest(proto.Message):
    r"""Request message for ``GetWriteStreamRequest``.

    Attributes:
        name (str):
            Required. Name of the stream to get, in the form of
            ``projects/{project}/datasets/{dataset}/tables/{table}/streams/{stream}``.
        view (google.cloud.bigquery_storage_v1.types.WriteStreamView):
            Indicates whether to get full or partial view
            of the WriteStream. If not set, view returned
            will be basic.
    """

    name: str = proto.Field(
        proto.STRING,
        number=1,
    )
    view: stream.WriteStreamView = proto.Field(
        proto.ENUM,
        number=3,
        enum=stream.WriteStreamView,
    )

class BatchCommitWriteStreamsRequest(proto.Message):
    r"""Request message for ``BatchCommitWriteStreams``.

    Attributes:
        parent (str):
            Required. Parent table that all the streams should belong
            to, in the form of
            ``projects/{project}/datasets/{dataset}/tables/{table}``.
        write_streams (MutableSequence[str]):
            Required. The group of streams that will be
            committed atomically.
    """

    parent: str = proto.Field(
        proto.STRING,
        number=1,
    )
    write_streams: MutableSequence[str] = proto.RepeatedField(
        proto.STRING,
        number=2,
    )

class BatchCommitWriteStreamsResponse(proto.Message):
    r"""Response message for ``BatchCommitWriteStreams``.

    Attributes:
        commit_time (google.protobuf.timestamp_pb2.Timestamp):
            The time at which streams were committed in microseconds
            granularity. This field will only exist when there are no
            stream errors. **Note** if this field is not set, it means
            the commit was not successful.
        stream_errors (MutableSequence[google.cloud.bigquery_storage_v1.types.StorageError]):
            Stream level error if commit failed. Only
            streams with error will be in the list.
            If empty, there is no error and all streams are
            committed successfully. If non empty, certain
            streams have errors and ZERO stream is committed
            due to atomicity guarantee.
    """

    commit_time: timestamp_pb2.Timestamp = proto.Field(
        proto.MESSAGE,
        number=1,
        message=timestamp_pb2.Timestamp,
    )
    stream_errors: MutableSequence["StorageError"] = proto.RepeatedField(
        proto.MESSAGE,
        number=2,
        message="StorageError",
    )

class FinalizeWriteStreamRequest(proto.Message):
    r"""Request message for invoking ``FinalizeWriteStream``.

    Attributes:
        name (str):
            Required. Name of the stream to finalize, in the form of
            ``projects/{project}/datasets/{dataset}/tables/{table}/streams/{stream}``.
    """

    name: str = proto.Field(
        proto.STRING,
        number=1,
    )

class FinalizeWriteStreamResponse(proto.Message):
    r"""Response message for ``FinalizeWriteStream``.

    Attributes:
        row_count (int):
            Number of rows in the finalized stream.
    """

    row_count: int = proto.Field(
        proto.INT64,
        number=1,
    )

class FlushRowsRequest(proto.Message):
    r"""Request message for ``FlushRows``.

    Attributes:
        write_stream (str):
            Required. The stream that is the target of
            the flush operation.
        offset (google.protobuf.wrappers_pb2.Int64Value):
            Ending offset of the flush operation. Rows
            before this offset(including this offset) will
            be flushed.
    """

    write_stream: str = proto.Field(
        proto.STRING,
        number=1,
    )
    offset: wrappers_pb2.Int64Value = proto.Field(
        proto.MESSAGE,
        number=2,
        message=wrappers_pb2.Int64Value,
    )

class FlushRowsResponse(proto.Message):
    r"""Respond message for ``FlushRows``.

    Attributes:
        offset (int):
            The rows before this offset (including this
            offset) are flushed.
    """

    offset: int = proto.Field(
        proto.INT64,
        number=1,
    )

class StorageError(proto.Message):
    r"""Structured custom BigQuery Storage error message. The error
    can be attached as error details in the returned rpc Status. In
    particular, the use of error codes allows more structured error
    handling, and reduces the need to evaluate unstructured error
    text strings.

    Attributes:
        code (google.cloud.bigquery_storage_v1.types.StorageError.StorageErrorCode):
            BigQuery Storage specific error code.
        entity (str):
            Name of the failed entity.
        error_message (str):
            Message that describes the error.
    """

    class StorageErrorCode(proto.Enum):
        r"""Error code for ``StorageError``.

        Values:
            STORAGE_ERROR_CODE_UNSPECIFIED (0):
                Default error.
            TABLE_NOT_FOUND (1):
                Table is not found in the system.
            STREAM_ALREADY_COMMITTED (2):
                Stream is already committed.
            STREAM_NOT_FOUND (3):
                Stream is not found.
            INVALID_STREAM_TYPE (4):
                Invalid Stream type.
                For example, you try to commit a stream that is
                not pending.
            INVALID_STREAM_STATE (5):
                Invalid Stream state.
                For example, you try to commit a stream that is
                not finalized or is garbaged.
            STREAM_FINALIZED (6):
                Stream is finalized.
            SCHEMA_MISMATCH_EXTRA_FIELDS (7):
                There is a schema mismatch and it is caused
                by user schema has extra field than bigquery
                schema.
            OFFSET_ALREADY_EXISTS (8):
                Offset already exists.
            OFFSET_OUT_OF_RANGE (9):
                Offset out of range.
            CMEK_NOT_PROVIDED (10):
                Customer-managed encryption key (CMEK) not
                provided for CMEK-enabled data.
            INVALID_CMEK_PROVIDED (11):
                Customer-managed encryption key (CMEK) was
                incorrectly provided.
            CMEK_ENCRYPTION_ERROR (12):
                There is an encryption error while using
                customer-managed encryption key.
            KMS_SERVICE_ERROR (13):
                Key Management Service (KMS) service returned
                an error, which can be retried.
            KMS_PERMISSION_DENIED (14):
                Permission denied while using
                customer-managed encryption key.
        """
        STORAGE_ERROR_CODE_UNSPECIFIED = 0
        TABLE_NOT_FOUND = 1
        STREAM_ALREADY_COMMITTED = 2
        STREAM_NOT_FOUND = 3
        INVALID_STREAM_TYPE = 4
        INVALID_STREAM_STATE = 5
        STREAM_FINALIZED = 6
        SCHEMA_MISMATCH_EXTRA_FIELDS = 7
        OFFSET_ALREADY_EXISTS = 8
        OFFSET_OUT_OF_RANGE = 9
        CMEK_NOT_PROVIDED = 10
        INVALID_CMEK_PROVIDED = 11
        CMEK_ENCRYPTION_ERROR = 12
        KMS_SERVICE_ERROR = 13
        KMS_PERMISSION_DENIED = 14

    code: StorageErrorCode = proto.Field(
        proto.ENUM,
        number=1,
        enum=StorageErrorCode,
    )
    entity: str = proto.Field(
        proto.STRING,
        number=2,
    )
    error_message: str = proto.Field(
        proto.STRING,
        number=3,
    )

class RowError(proto.Message):
    r"""The message that presents row level error info in a request.

    Attributes:
        index (int):
            Index of the malformed row in the request.
        code (google.cloud.bigquery_storage_v1.types.RowError.RowErrorCode):
            Structured error reason for a row error.
        message (str):
            Description of the issue encountered when
            processing the row.
    """

    class RowErrorCode(proto.Enum):
        r"""Error code for ``RowError``.

        Values:
            ROW_ERROR_CODE_UNSPECIFIED (0):
                Default error.
            FIELDS_ERROR (1):
                One or more fields in the row has errors.
        """
        ROW_ERROR_CODE_UNSPECIFIED = 0
        FIELDS_ERROR = 1

    index: int = proto.Field(
        proto.INT64,
        number=1,
    )
    code: RowErrorCode = proto.Field(
        proto.ENUM,
        number=2,
        enum=RowErrorCode,
    )
    message: str = proto.Field(
        proto.STRING,
        number=3,
    )

__all__ = tuple(sorted(__protobuf__.manifest))


from django.contrib import admin
from adminsortable2.admin import SortableAdminBase
from porch.models import Porch, PorchTypicalProject
from common.admin import (
    PageHWAWAdmin, PageDescriptionAdmin, PagePortfolioAdmin,
    PageRailingsAdmin, SimplePageAdmin
)
from common.helpers import formfield_overrides

class PorchAdmin(
    SortableAdminBase, SimplePageAdmin, PageHWAWAdmin,
    PageRailingsAdmin, PagePortfolioAdmin, PageDescriptionAdmin):
    list_display = ('name',)
    filter_horizontal = ('hwaw', 'block_railings', )

    def get_fieldsets(self, request, obj=None):
        fieldsets = super().get_fieldsets(request, obj)
        return fieldsets + (
            ('Типовой проект', {
                'fields': ('typical_project',)
            }),
        )

admin.site.register(Porch, PorchAdmin)

class PorchTypicalProjectAdmin(admin.ModelAdmin):
    formfield_overrides = formfield_overrides

admin.site.register(PorchTypicalProject, PorchTypicalProjectAdmin)


import tiktoken

def count(input_texts, output_texts, history=None):
    all_text = ""
    # チャットの履歴部分の連結
    if history:
        if isinstance(history, dict):
            for key, value in history.items():
                if isinstance(value, list):
                    for v in value:
                        all_text += v
                else:
                    all_text += value
        elif isinstance(history, list):
            for hist in history:
                if isinstance(hist, list):
                    for v in hist:
                        all_text += v
                else:
                    all_text += value
        else:
            all_text += history
    if isinstance(input_texts, list):
        for input_text in input_texts:
            all_text += input_text
    else:
        all_text += input_texts
    text = f"{all_text}{output_texts}"
    tiktoken_encoding = tiktoken.encoding_for_model("gpt-4-0613")
    encoded = tiktoken_encoding.encode(text)
    encode_count = len(encoded)
    return encode_count

if __name__ == "__main__":
    input_text = "こんにちは"
    history = {"user_input": ["初めまして"], "ai_input": ["初めまして、御用はなんでしょうか。"]}
    output_text = "こんにちは"
    print(count(input_text, output_text, history))


from django.forms import CharField, ModelForm
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms

from.models import LinkedAccount, PersonalDetails, WorkDetails

class LinkAccountForm(forms.Form):
    """Form for Linking Users to their Details"""
    id_number = forms.CharField(max_length=200)
    first_name = forms.CharField(max_length=200)

    def save(self, user):
        linked = LinkedAccount.objects.create(user=user)
        linked.save()

class CreateUserForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

class PersonalDetailsForm(ModelForm):
    class Meta:
        model = PersonalDetails
        fields = '__all__'
        exclude = ['user',]

class WorkDetailsForm(ModelForm):
    class Meta:
        model =WorkDetails
        fields = '__all__'