import threading
import logging
import time
import random

logging.basicConfig(level=logging.INFO, format='[%(levelname)s])] [%(threadName)s] [%(message)s]')

class MyCounter:
    def __init__(self, start=0):
        self.lock = threading.Lock()
        self.counter = start

    def increment(self):
        logging.info('waiting for lock')
        self.lock.acquire()
        try:  # in case of any error, lock must be released!
            logging.info('lock acquired')
            self.counter += 1
        finally:
            self.lock.release()

def worker(counter):
    for _ in range(3):
        r = random.random()
        logging.info('sleeping %0.02f', r)
        time.sleep(r)
        counter.increment()
    logging.info('worker done')

if __name__ == '__main__':

    my_lock = threading.Lock()
    print('1st lock', my_lock.acquire())
    print('2nd lock', my_lock.acquire(blocking=True, timeout=0.5))
    print('3rd lock', my_lock.acquire(blocking=False))
    my_lock.release()

    my_rlock = threading.RLock()
    print('1st Rlock', my_rlock.acquire())
    print('2nd Rlock', my_rlock.acquire())
    print('3rd Rlock', my_rlock.acquire())
    my_rlock.release()
    my_rlock.release()
    my_rlock.release()

    with my_lock:
        time.sleep(2)
        logging.info('in the with statement')
        print('my lock', my_lock.acquire(blocking=False))
    my_lock = threading.Lock()
    print('my lock', my_lock.acquire())
    my_lock.release()

    exit()

    counter = MyCounter()
    for i in range(3):
        t = threading.Thread(target=worker, args=(counter,))
        t.start()

    logging.info('waiting for worker threads........')
    main_thread = threading.currentThread()
    for t in threading.enumerate():
        if t is not main_thread:
            t.join()
    logging.info('final counter value: %d', counter.counter)


from django.core.checks import messages
from django.http import HttpResponseRedirect

from django.shortcuts import render

# Create your views here.
from django.template import loader

from home.models import Setting, ContactFormMessage, ContactFormu
from product.models import Product

def index(request):
  setting = Setting.objects.get(pk=1)
  context = {'setting':setting, 'page':'home'}
  return render(request, 'index.html',context)

  '''  template = loader.get_template('homebase.html')
  return HttpResponse(template.render())
'''

def hakkimizda(request):
  setting = Setting.objects.get(pk=1)
  context = {'setting':setting,'page':'hakkimizda'}
  return render(request, 'hakkimizda.html',context)

def computer(request):
  setting = Setting.objects.get(pk=1)
  context = {'setting':setting,'page':'computer'}
  return render(request, 'computer.html',context)

def products(request):
  setting = Setting.objects.get(pk=1)
  context = {'setting':setting,'page':'products'}
  return render(request, 'products.html',context)

def contact(request):
  setting = Setting.objects.get(pk=1)
  context = {'setting':setting,'page':'contact'}
  return render(request, 'contact.html',context)

def iletisim(request):

  if request.method == 'POST': #form post edildiyse
    form = ContactFormu(request.POST)
    if form.is_valid():
      data = ContactFormMessage() #model ile bağlantı kur
      data.name = form.cleaned_data['name'] #formdan bilgiyi al
      data.email = form.cleaned_data['email']
      data.phone = form.cleaned_data['phone']
      data.message = form.cleaned_data['message']
      data.save() #veritabanına kaydet
      messages.success(request,"Mesajınız başarıyla gönderilmiştir. Teşekkür ederiz.")
      return HttpResponseRedirect('/contact')

  setting = Setting.objects.get(pk=1)
  form =ContactFormu()
  context = {'setting':setting, 'form':form}
  return render(request, 'contact.html',context)


import numpy as np
import random as rd

# def producer(num, mode = 'random'):
#     numlist = []
#     for i in range((2**num)):
#         n1 = str(bin(i))  #string
#         n1 = n1[2:len(n1)]  #delete '0x'
#         n1 = n1.zfill(num)   #fill zeros

#         n2 = str(bin(rd.randint(0,2**(num-1))))  #string
#         n2 = n2[2:len(n2)]  #delete '0x'
#         n2 = n2.zfill(num)   #fill zeros

#         numlist.append((n1, n2))
#     return numlist

def multiplier_producer(Bit, Datatype):
    numlist = []
    for i in range(2**(Bit//2)):
        for j in range(2**(Bit//2)):
            output = i*j
            b_input = str(bin(i))[2:].zfill(Bit//2) + str(bin(j))[2:].zfill(Bit//2)
            b_output = str(bin(output))[2:].zfill(Bit)
            numlist.append((b_input, b_output))
    return numlist

def generate_txt(data):
    f1 = open('data.txt', 'w')
    for i in data:
        for j in i:
            f1.write(j)
            f1.write(' ')
        f1.write('\n')
    f1.close()


import random
from turtle import Turtle

t = Turtle()

colours = ["CornflowerBlue", "DarkOrchid", "IndianRed", "DeepSkyBlue",
           "LightSeaGreen", "wheat", "SlateGray", "SeaGreen"]
direction = [0, 90, 180, 270]
t.pensize(15)
t.shape("classic")
t.color("#228B22")
t.speed("fastest")

for n in range(300):
    t.color(random.choice(colours))
    t.forward(30)
    t.setheading(random.choice(direction))


"""
This module takes care of starting the API Server, Loading the DB and Adding the endpoints
"""
from flask import Flask, request, jsonify, url_for, Blueprint
from api.models import db, User, Character, Favorite
from api.utils import generate_sitemap, APIException

api = Blueprint('api', __name__)
####################### GET ###############################

# Get all users
@api.route('/users', methods=['GET'])
def get_users():
    users = User.query.all()
    return jsonify([user.serialize() for user in users]), 200

# Get a user by ID
@api.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
    user = User.query.get(user_id)
    if not user:
        return jsonify({'error': 'User not found'}), 404
    return jsonify(user.serialize()), 200

# Get all favorites for all users
@api.route('/favorites', methods=['GET'])
def get_all_favorites():
    favorites = Favorite.query.all()
    return jsonify([favorite.serialize() for favorite in favorites]), 200

# Get a user's favorite characters
@api.route('/users/<int:user_id>/favorites', methods=['GET'])
def get_favorites(user_id):
    user = User.query.get(user_id)
    if not user:
        return jsonify({'error': 'User not found'}), 404
    favorites = user.favorites
    return jsonify([favorite.character.serialize() for favorite in favorites]), 200

# Get all characters
@api.route('/characters', methods=['GET'])
def get_characters():
    characters = Character.query.all()
    return jsonify([character.serialize() for character in characters]), 200

# Get a character by ID
@api.route('/characters/<int:character_id>', methods=['GET'])
def get_character(character_id):
    character = Character.query.get(character_id)
    if not character:
        return jsonify({'error': 'Character not found'}), 404
    return jsonify(character.serialize()), 200

@api.route('/favorites/<int:user_id>', methods=['GET'])
def get_user_favorites(user_id):
    user = User.query.get(user_id)
    if user is None:
        return jsonify({'message': 'User not found'}), 404

    favorites = user.favorites
    serialized_favorites = [f.serialize_with_user() for f in favorites]

    return jsonify(serialized_favorites), 200

# Add a favorite character for a user
@api.route('/users/<int:user_id>/favorites', methods=['POST'])
def add_favorite_character(user_id):
    data = request.get_json()
    character_id = data.get('character_id')

    # Ensure character exists
    character = Character.query.get(character_id)
    if not character:
        return jsonify({'error': 'Character not found'}), 404

    # Ensure user exists
    user = User.query.get(user_id)
    if not user:
        return jsonify({'error': 'User not found'}), 404

    # Create new favorite record
    favorite = Favorite(user=user, character=character)
    db.session.add(favorite)
    db.session.commit()

    return jsonify({'success': 'Character added to favorites'}), 200


#

from errorhandler import Error, ErrorList
from dir_stock.stock import StockRead
from widget_helper import Result, Graph, DisplayInfo

class AnalysisStock:
    def __init__(self, di: DisplayInfo, read_type: str):
        self.result = Result()
        self.di = di
        # Get Stock data
        self.stock_collection = StockRead(di, read_type)
        if self.stock_collection.result.exec_continue:
            print('Stock History Data (' + str(self.stock_collection.result.result_data) + ') set completed!')
            # Prepare Result Class
            self.result = Result()
        else:
            pass

    def inquiry(self) -> Result:
        self.result.action_name = 'Inquiry Stock History'
        self.result.result_type = 'dataframe'
        self.result.result_data = self.stock_collection.stocks.get(self.di.company + '.T')
        if self.result.exec_continue is False:
            er = Error(ValueError, self.di.company, 'Hit No Data')
            e_list = ErrorList().add_list(er)
            self.result.error_list = e_list
            self.result.exec_continue = False
        # result.to_excel('./test.xlsx')
        return self.result

    def generate_ranking(self) -> Result:
        # Calc Balance from Open Price to Close price
        change_value = self.stock_collection.close_price - self.stock_collection.open_price
        print(" *** change_value *** ")
        print(change_value)

        # Calc average of the balance
        mu = change_value.mean()
        mu_mean = mu.mean()
        mu_std = mu.std()
        mu_point = (mu - mu_mean) / mu_std

        print(" *** mu *** ")
        print(mu)
        print(mu_mean, mu_std)

        # Calc variance of the balance
        sigma2 = change_value.var()
        sigma2_mean = sigma2.mean()
        sigma2_std = sigma2.std()
        sigma2_point = (sigma2 - sigma2_mean) / sigma2_std

        print(" *** sigma2 *** ")
        print(sigma2)
        print(sigma2_mean, sigma2_std)

        print(" *** point *** ")
        print(mu_point)
        print(sigma2_point)

        point = mu_point + sigma2_point * -1
        point = point.sort_values(ascending=False)

        # filename = "rank"
        # self.data.save_data(filename, point)

        # print("Ranking")
        # print(point)

        point = point.head(10)
        # generate Graph Object
        g = Graph()
        g.set_title('Change Price Ranking Graph (Top10)')
        g.set_x_label('Company')
        g.set_y_label('Point : Average + Variant * -1')
        g.set_data_label('Point')
        g.set_data(point)

        # Generate Result Class
        self.result.action_name = 'generate stock ranking'
        self.result.result_type = 'bar graph'
        self.result.result_data = g
        self.result.exec_continue = True
        return self.result

if __name__ == '__main__':
    pass


# %%

import numpy as np
import os
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.metrics.pairwise import cosine_similarity

K = 5
n = 3
minihash = False
proj_func_num = 10

work_dir = r'D:\Documents\course\junior\BigDataAna\12-20大作业'
dataset_dir = work_dir + r'\datasets' + '\\'
# print(dataset_dir)

# 获取数据集
raw_data = pd.read_csv(dataset_dir + 'movies.csv')
# raw_data.info()
# print(raw_data.head())
index2Id = {k: v for k, v in enumerate(raw_data['movieId'])}
Id2index = {v: k for k, v in index2Id.items()}

# %%
genres = raw_data['genres'].values

# %%

train_data = pd.read_csv(dataset_dir + 'train_set.csv')
# train_data.info()
train_data.drop('timestamp', axis=1, inplace=True)
# train_data.info()

# %%

mat = train_data.pivot_table(index=['userId'], columns=['movieId'], values=['rating'])
mat.fillna(0, inplace=True)
util_mat = np.array(mat.values)
movie_id2index = {mat.columns[i][1]: i for i in range(util_mat.shape[1])}
index2movie_id = {v: k for k, v in movie_id2index.items()}
user_num = util_mat.shape[0]
movie_num = util_mat.shape[1]

# %%

# 获取tfidf特征矩阵
vectorizer = TfidfVectorizer()
tfidf_mat = vectorizer.fit_transform(genres).toarray()

# %%

from scipy.spatial.distance import pdist, squareform

if minihash:

    # 构建哈希签名矩阵
    mini_mat = np.array(tfidf_mat)
    mini_mat[mini_mat > 0] = 1
    mini_mat[mini_mat <= 0] = 0
    total_movie_num = mini_mat.shape[0]
    feature_num = mini_mat.shape[1]
    sig_mat = np.zeros((proj_func_num, total_movie_num))
    for i in range(proj_func_num):
        # print("pai%d/%d" % (i + 1, proj_func_num))
        pai = [j for j in range(feature_num)]
        np.random.shuffle(pai)
        pai_index = np.argsort(pai)
        for j in range(total_movie_num):
            for index in pai_index:
                if mini_mat[j, pai[index]] == 1:
                    sig_mat[i, j] = pai[index]
                    break

    # %%

    # 计算jiccard相似度 用scipy库
    print('calc sim mat')
    sig_mat = sig_mat.T  # 用行来算比较快
    sim_mat = 1 - squareform(pdist(sig_mat, 'jaccard'))
    print('sim mat cacl finish')
    sim_mat[np.isnan(sim_mat)] = 0

else:
    # 根据特征矩阵计算相似度矩阵
    sim_mat = cosine_similarity(tfidf_mat)
    sim_mat[sim_mat < 0] = 0

# %%

def recommender(mode, userId, util_mat, sim_mat, movie_id):
    userId = userId - 1  # userID 从1开始，矩阵从0开始
    user_num = util_mat.shape[0]
    movie_num = util_mat.shape[1]
    if mode == 1:  # 1为top k推荐 0为预测评分 2为预测单个movie的评分
        user_rate = np.zeros(util_mat.shape[1])
    else:
        user_rate = np.copy(util_mat[userId])

    rate_movie_index = []
    unrate_movie_index = []

    # 找出评了分和没评分的
    for cur_movie in range(movie_num):
        if util_mat[userId, cur_movie] == 0 and mode != 2:
            unrate_movie_index.append(cur_movie)
        else:
            rate_movie_index.append(cur_movie)

    if mode == 2:
        unrate_movie_index.append(movie_id2index[movie_id])

    for cur_movie in unrate_movie_index:
        total = 0
        pred = 0
        for another_movie in rate_movie_index:
            another_movie_rate = util_mat[userId, another_movie]
            if another_movie_rate != 0:
                cur_movie_in_sim_mat = Id2index[index2movie_id[cur_movie]]
                another_movie_in_sim_mat = Id2index[index2movie_id[another_movie]]
                pred += sim_mat[cur_movie_in_sim_mat, another_movie_in_sim_mat] * another_movie_rate
                total += sim_mat[cur_movie_in_sim_mat, another_movie_in_sim_mat]
        user_rate[cur_movie] = pred / total

    if mode == 0 or mode == 2:
        return user_rate
    else: # top k推荐
        user_rate[np.isnan(user_rate)] = 0
        rec_index = np.argsort(user_rate)[-K:]
        movie_id_list = list(mat.columns)
        rec = [movie_id_list[i][1] for i in rec_index]
        return rec

rec = recommender(1, 4, util_mat, sim_mat, 0)
print('recommend for user 671:', rec)

# %%

# 读取测试集
test = pd.read_csv(dataset_dir + 'test_set.csv')
test.drop('timestamp', axis=1, inplace=True)
users, movies, ratings = test['userId'], test['movieId'], test['rating']
# test.info()

# %%

# 开始预测
preds = []
pred_cache = {}
for i in range(len(test)):
    print('%d/%d...' % (i + 1, len(test)))
    rates = recommender(2, users[i], util_mat, sim_mat, movie_id=movies[i])
    preds.append(rates[movie_id2index[movies[i]]])

SSE = np.sum(np.square(preds - ratings))
print(SSE)
# %%


from dataclasses import dataclass
from typing import Union

#jeder spieler sammelt chips bekommt punkte
#pro zug bekommt spieler zufälligen chips
#punktewert des neuen chips wird zu Punktestand addiert
#mehr als 7 punkte nach weißem chip verloren
#bei orange passiert nichts
#bei rot und einem oder zwei orangenem extra punkte
#bei 3 oder mehr 2 extra
@dataclass
class White:
    points : int

@dataclass
class Orange:
    points : int

@dataclass
class Red:
    points : int

@dataclass
class GameState:
    stack : [White,Red,Orange]
    total : int

def add_chip(state : GameState, chips:Union[White,Orange,Red]):
    if isinstance(chips,Red):
        for chip in state.stack:
            if chip == Orange:
                chip = Orange
                if chip.points > 2:
                    stack.total += 2
                else:
                    stack.total += 1
    if isinstance(chips,White):
        old = state.total
        state.total +=  chips.points
        state.stack.append(chips)
        return state if old <= 7 and state.total < 8 else None

    if isinstance(chips,Orange):
        state.total += chips.points
        state.stack.append(chips)
        return state
    if isinstance(chips,Red):
        state.total += chips.points
        state.stack.append(chips)
        return state
state = GameState([], 0)
state = add_chip(state, White(3))
state = add_chip(state, Orange(3))
state = add_chip(state, Red(1))
stack = add_chip(state, White(1))
print(state.total)
print(state.stack)


import pywhatkit
import speech_recognition as sr

def listen():
    listener = sr.Recognizer()
    try:
        with sr.Microphone() as source:
            print("listening...")
            voice = listener.listen(source)
            command = listener.recognize_google(voice)
            command = command.lower()
    except:
        pass
    return command

def start():
    x = listen()
    if 'radhe' in x:
        print(x)
        return take_command()
    else:
        print("Kindly Mention Proper Name")

def take_command():
    print("What can I do for You?")
    cmd = listen()
    print(cmd)
    if 'play' in cmd:
        song = cmd.replace('play','')
        print("ok playing")
        print(song)
        pywhatkit.playonyt(song)
    elif 'heart' or 'dil' in cmd:
        import heart.py
        print("ok drawing heart")
        exec("heart.py")
start()


import matplotlib
from matplotlib import pyplot as plt
from tqdm import tqdm
import network
import utils
from torchvision import transforms as T
import torch.nn as nn

from PIL import Image
from glob import glob

import colorsys
import os
import time

import numpy as np
import torch
from PIL import ImageDraw, ImageFont

from network.models.detect.centernet import CenterNet as CenterNet_Resnet50
from utils.utils import (cvtColor, get_classes, preprocess_input, resize_image,
                         show_config)
from utils.utils_bbox import decode_bbox, postprocess

# ---------------------------------------------------#
#   检测图片
# ---------------------------------------------------#
def detect_image(image, img_data, model, opts, crop=False, count=False):
    # ---------------------------------------------------#
    #   计算输入图片的高和宽
    # ---------------------------------------------------#
    image_shape = np.array(np.shape(image)[0:2])

    # 图片预处理，归一化。获得的photo的shape为[1, 512, 512, 3]
    # image_data = np.expand_dims(np.transpose(preprocess_input(np.array(image_data, dtype='float32')), (2, 0, 1)), 0)

    with torch.no_grad():
        # 将图像输入网络当中进行预测！
        outputs = model(img_data)

        # 利用预测结果进行解码
        outputs = decode_bbox(outputs[0], outputs[1], outputs[2], opts.confidence, opts.device)

        # -------------------------------------------------------#
        #   对于centernet网络来讲，确立中心非常重要。
        #   对于大目标而言，会存在许多的局部信息。
        #   此时对于同一个大目标，中心点比较难以确定。
        #   使用最大池化的非极大抑制方法无法去除局部框
        #   所以我还是写了另外一段对框进行非极大抑制的代码
        #   实际测试中，hourglass为主干网络时有无额外的nms相差不大，resnet相差较大。
        # -------------------------------------------------------#
        results = postprocess(outputs, opts.nms, image_shape, opts.crop_size, opts.letterbox_image, opts.nms_iou)

        # --------------------------------------#
        #   如果没有检测到物体，则返回原图
        # --------------------------------------#
        if results[0] is None:
            return image

        top_label = np.array(results[0][:, 5], dtype='int32')
        top_conf = results[0][:, 4]
        top_boxes = results[0][:, :4]

    # ---------------------------------------------------------#
    #   设置字体与边框厚度
    # ---------------------------------------------------------#
    font = ImageFont.truetype(font='model_data/simhei.ttf',
                              size=np.floor(3e-2 * np.shape(image)[1] + 0.5 - 10).astype('int32'))
    thickness = max((np.shape(image)[0] + np.shape(image)[1]) // opts.crop_size, 1)
    # ---------------------------------------------------------#
    #   计数
    # ---------------------------------------------------------#
    if count:
        print("top_label:", top_label)
        classes_nums = np.zeros([opts.num_classes])
        for i in range(opts.num_classes):
            num = np.sum(top_label == i)
            if num > 0:
                print(opts.class_names[i], " : ", num)
            classes_nums[i] = num
        print("classes_nums:", classes_nums)
    # ---------------------------------------------------------#
    #   是否进行目标的裁剪
    # ---------------------------------------------------------#
    if crop:
        for i, c in list(enumerate(top_label)):
            top, left, bottom, right = top_boxes[i]
            top = max(0, np.floor(top).astype('int32'))
            left = max(0, np.floor(left).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom).astype('int32'))
            right = min(image.size[0], np.floor(right).astype('int32'))

            dir_save_path = "img_crop"
            if not os.path.exists(dir_save_path):
                os.makedirs(dir_save_path)
            crop_image = image.crop([left, top, right, bottom])
            crop_image.save(os.path.join(dir_save_path, "crop_" + str(i) + ".png"), quality=95, subsampling=0)
            print("save crop_" + str(i) + ".png to " + dir_save_path)
    # ---------------------------------------------------------#
    #   图像绘制
    # ---------------------------------------------------------#
    for i, c in list(enumerate(top_label)):
        predicted_class = opts.class_names[int(c)]
        box = top_boxes[i]
        score = top_conf[i]

        top, left, bottom, right = box

        top = max(0, np.floor(top).astype('int32'))
        left = max(0, np.floor(left).astype('int32'))
        bottom = min(image.size[1], np.floor(bottom).astype('int32'))
        right = min(image.size[0], np.floor(right).astype('int32'))

        label = '{} {:.2f}'.format(predicted_class, score)
        draw = ImageDraw.Draw(image)
        label_size = draw.textsize(label, font)
        label = label.encode('utf-8')
        print(label, top, left, bottom, right)

        if top - label_size[1] >= 0:
            text_origin = np.array([left, top - label_size[1]])
        else:
            text_origin = np.array([left, top + 1])

        for i in range(thickness):
            draw.rectangle([left + i, top + i, right - i, bottom - i], outline=opts.colors[c])
        # draw.rectangle([tuple(text_origin), tuple(text_origin + label_size)], fill=opts.colors[c])
        draw.text(text_origin, str(label, 'UTF-8'), fill=(0, 0, 0), font=font)
        del draw

    return image

def main(opts):
    # Setup dataloader
    image_files = []
    if os.path.isdir(opts.input):
        for ext in ['png', 'jpeg', 'jpg', 'JPEG']:
            files = glob(os.path.join(opts.input, '**/*.%s' % (ext)), recursive=True)
            if len(files) > 0:
                image_files.extend(files)
    elif os.path.isfile(opts.input):
        image_files.append(opts.input)

    # Set up model (all models are 'constructed at network.modeling)

    # det_model
    det_model = network.modeling.__dict__[opts.det_model](num_classes=opts.num_classes, output_stride=opts.output_stride)
    utils.set_bn_momentum(det_model.backbone, momentum=0.01)

    if opts.det_ckpt is not None and os.path.isfile(opts.det_ckpt):
        # https://github.com/VainF/DeepLabV3Plus-Pytorch/issues/8#issuecomment-605601402, @PytaichukBohdan
        checkpoint = torch.load(opts.det_ckpt, map_location=torch.device('cpu'))
        det_model.load_state_dict(checkpoint["model_state"])
        det_model = nn.DataParallel(det_model)
        det_model.to(opts.device)
        print("Resume model from %s" % opts.ckpt)
        del checkpoint
    else:
        print("No ck for predict")

        det_model = nn.DataParallel(det_model)
        det_model.to(opts.device)

    # seg_model
    seg_model = network.modeling.__dict__[opts.seg_model](num_classes=opts.num_classes + 2, output_stride=opts.output_stride)
    if opts.separable_conv and 'plus' in opts.seg_model:
        network.convert_to_separable_conv(seg_model.classifier)
    utils.set_bn_momentum(seg_model.backbone, momentum=0.01)

    if opts.seg_ckpt is not None and os.path.isfile(opts.seg_ckpt):
        # https://github.com/VainF/DeepLabV3Plus-Pytorch/issues/8#issuecomment-605601402, @PytaichukBohdan
        checkpoint = torch.load(opts.seg_ckpt, map_location=torch.device('cpu'))
        seg_model.load_state_dict(checkpoint["model_state"])
        seg_model = nn.DataParallel(seg_model)
        seg_model.to(opts.device)
        print("Resume model from %s" % opts.ckpt)
        del checkpoint
    else:
        print("[!] Retrain")
        seg_model = nn.DataParallel(seg_model)
        seg_model.to(opts.device)

    # 计算总的类的数量  classes_path = 'model_data/voc_house6.txt'
    opts.class_names, opts.num_classes = get_classes(opts.classes_path)

    # 画框设置不同的颜色
    hsv_tuples = [(x / opts.num_classes, 1., 1.) for x in range(opts.num_classes)]
    opts.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
    opts.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), opts.colors))

    # trans
    transform = T.Compose([
        T.ToTensor(),
        T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
    ])

    if opts.save_val_results_to is not None:
        os.makedirs(opts.save_val_results_to, exist_ok=True)

    # pre
    with torch.no_grad():
        seg_model = seg_model.eval()
        det_model = det_model.eval()
        for img_path in tqdm(image_files):
            ext = os.path.basename(img_path).split('.')[-1]
            img_name = os.path.basename(img_path)[:-len(ext) - 1]
            img = Image.open(img_path).convert('RGB')  # cvtColor
            re_image = img.resize((opts.crop_size, opts.crop_size), Image.BICUBIC)  # resize
            img_data = transform(re_image).unsqueeze(0)  # To tensor of NCHW
            img_data = img_data.to(opts.device)
            # seg
            pred = seg_model(img_data).max(1)[1].cpu().numpy()[0]  # HW
            colorized_preds = opts.decode_fn(pred).astype('uint8')
            colorized_preds = Image.fromarray(colorized_preds)  # seg_pred_img = Image.fromarray(colorized_preds)

            plt.imshow(re_image)
            plt.axis('off')
            plt.imshow(colorized_preds, alpha=0.7)
            ax = plt.gca()
            ax.xaxis.set_major_locator(matplotlib.ticker.NullLocator())
            ax.yaxis.set_major_locator(matplotlib.ticker.NullLocator())
            plt.savefig(os.path.join(opts.save_val_results_to, '%s_overlay.png' % img_name), bbox_inches='tight', pad_inches=0)
            plt.close()

            mask_img = Image.open(os.path.join(opts.save_val_results_to, '%s_overlay.png' % img_name)).convert('RGB')  # cvtColor
            mask_img = mask_img.resize((opts.crop_size, opts.crop_size), Image.BICUBIC)  # resize

            # det
            mask_img_data = transform(mask_img).unsqueeze(0)
            mask_img_data = mask_img_data.to(opts.device)
            if opts.crop_img:
                pred_img = detect_image(re_image, mask_img_data, det_model, opts=opts, count=True)  # resize img
            else:
                # pred_img = detect_image(img, mask_img_data, det_model, opts=opts, count=True)  # origin img
                pred_img = detect_image(mask_img, mask_img_data, det_model, opts=opts, count=True)
            # save
            if opts.save_val_results_to:
                pred_img.save(os.path.join(opts.save_val_results_to, img_name + '.jpg'))

            print('done')


from __future__ import print_function

from pymongo import MongoClient

db = MongoClient('localhost').condor

reserved_ips = {
    '18.12': 'MIT',
    '23.22': 'AWS',
    '35.9': 'AGLT2',
    '40.78': 'Azure',
    '40.112': 'Azure',
    '50.16': 'AWS',
    '50.17': 'AWS',
    '54.144': 'AWS',
    '54.145': 'AWS',
    '54.157': 'AWS',
    '54.158': 'AWS',
    '54.159': 'AWS',
    '54.161': 'AWS',
    '54.163': 'AWS',
    '54.166': 'AWS',
    '54.167': 'AWS',
    '54.197': 'AWS',
    '54.204': 'AWS',
    '54.205': 'AWS',
    '54.211': 'AWS',
    '54.227': 'AWS',
    '54.243': 'AWS',
    '72.36': 'Illinois',
    '128.9': 'osgconnect',
    '128.55': 'Berkeley',
    '128.84': 'NYSGRID_CORNELL_NYS1',
    '128.104': 'CHTC',
    '128.105': 'CHTC',
    '128.118': 'Bridges',
    '128.120': 'UCD',
    '128.205': 'osgconnect',
    '128.211': 'Purdue-Hadoop',
    '128.227': 'FLTech',
    '128.230': 'Syracuse',
    '129.74': 'NWICG_NDCMS',
    '129.93': 'Nebraska',
    '129.105': 'NUMEP-OSG',
    '129.107': 'UTA_SWT2',
    '129.119': 'SU-OG',
    '129.130': 'Kansas',
    '129.217': 'LIDO_Dortmund',
    '130.74': 'Miss',
    '130.127': 'Clemson-Palmetto',
    '130.199': 'BNL-ATLAS',
    '131.94': 'FLTECH',
    '131.215': 'CIT_CMS_T2',
    '131.225': 'USCMS-FNAL-WC1',
    '132.206': 'CA-MCGILL-CLUMEQ-T2',
    '133.82': 'Japan',
    '134.93': 'mainz',
    '136.145': 'osgconnect',
    '137.99': 'UConn-OSG',
    '137.135': 'Azure',
    '138.23': 'UCRiverside',
    '138.91': 'Azure',
    '141.34': 'DESY-HH',
    '142.150': 'CA-SCINET-T2',
    '142.244': 'Alberta',
    '144.92': 'HEP_WISC',
    '149.165': 'Indiana',
    '155.101': 'Utah',
    '163.118': 'FLTECH',
    '169.228': 'UCSDT2',
    '171.67': 'HOSTED_STANFORD',
    '174.129': 'AWS',
    '184.73': 'AWS',
    '192.5': 'Boston',
    '192.12': 'Colorado',
    '192.41': 'AGLT2',
    '192.84': 'Ultralight',
    '192.168': None,
    '192.170': 'MWT2',
    '193.58': 'T2B_BE_IIHE',
    '193.190': 'T2B_BE_IIHE',
    '198.32': 'osgconnect',
    '198.48': 'Hyak',
    '200.136': 'SPRACE',
    '200.145': 'SPRACE',
    '206.12': 'CA-MCGILL-CLUMEQ-T2',
    '216.47': 'MWT2',
}
reserved_ips.update({'10.%d'%i:None for i in range(256)})
reserved_ips.update({'172.%d'%i:None for i in range(16,32)})

reserved_domains = {
    'aglt2.org': 'AGLT2',
    'bridges.psc.edu': 'Bridges',
    'campuscluster.illinois.edu': 'Illinois',
    'cl.iit.edu': 'MWT2',
    'cm.cluster': 'LIDO_Dortmund',
    'cmsaf.mit.edu': 'MIT',
    'colorado.edu': 'Colorado',
    'cpp.ualberta.ca': 'Alberta',
    'crc.nd.edu': 'NWICG_NDCMS',
    'cci.wisc.edu': 'CHTC',
    'chtc.wisc.edu': 'CHTC',
    'cs.wisc.edu': 'CS_WISC',
    'cse.buffalo.edu': 'osgconnect',
    'discovery.wisc.edu': 'CHTC',
    'ec2.internal': 'AWS',
    'ember.arches': 'Utah',
    'fnal.gov': 'USCMS-FNAL-WC1',
    'grid.tu-dortmund.de': 'LIDO_Dortmund',
    'guillimin.clumeq.ca': 'Guillimin',
    'hcc.unl.edu': 'Crane',
    'hep.caltech.edu': 'CIT_CMS_T2',
    'hep.int': 'osgconnect',
    'hep.olemiss.edu': 'Miss',
    'hep.wisc.edu': 'HEP_WISC',
    'icecube.wisc.edu': 'NPX',
    'ics.psu.edu': 'Bridges',
    'iihe.ac.be': 'T2B_BE_IIHE',
    'internal.cloudapp.net': 'osgconnect',
    'isi.edu': 'osgconnect',
    'iu.edu': 'Indiana',
    'lidocluster.hp': 'LIDO_Dortmund',
    'math.wisc.edu': 'MATH_WISC',
    'mwt2.org': 'MWT2',
    'nut.bu.edu': 'Boston',
    'palmetto.clemson.edu': 'Clemson-Palmetto',
    'panther.net': 'FLTECH',
    'phys.uconn.edu': 'UConn-OSG',
    'rcac.purdue.edu': 'Purdue-Hadoop',
    'research.northwestern.edu': 'NUMEP-OSG',
    'stat.wisc.edu': 'CHTC',
    't2.ucsd.edu': 'UCSDT2',
    'tier3.ucdavis.edu':'UCD',
    'unl.edu': 'Nebraska',
    'uppmax.uu.se': 'Uppsala',
    'usatlas.bnl.gov': 'BNL-ATLAS',
    'wisc.cloudlab.us': 'CLOUD_WISC',
    'wisc.edu': 'WISC',
    'zeuthen.desy.de': 'DESY-ZN',
}

def get_domain(hostname):
    parts = hostname.lower().split('.')
    if '.'.join(parts[-3:]) in reserved_domains:
        return '.'.join(parts[-3:])
    elif '.'.join(parts[-2:]) in reserved_domains:
        return '.'.join(parts[-2:])
    if len(parts) > 3:
        return '.'.join(parts[-3:])
    elif len(parts) > 2:
        return '.'.join(parts[-2:])

def get_ip_range(ip, reserved=False):
    parts = ip.split('.')
    if len(parts) == 4 and all(p.isdigit() for p in parts):
        if '.'.join(parts[:2]) in reserved_ips:
            ret = reserved_ips['.'.join(parts[:2])]
            if ret and reserved:
                return ret
            else:
                return None
        return '.'.join(parts[:3])

# do initial lookup
domain_lookup = {}
ip_lookup = {}
for row in db.condor_history.find(filter={'MATCH_EXP_JOBGLIDEIN_ResourceName':{'$exists': True}},
                                  projection=['LastRemoteHost','StartdPrincipal','MATCH_EXP_JOBGLIDEIN_ResourceName']):
    site = row['MATCH_EXP_JOBGLIDEIN_ResourceName']
    if '.' in site or site.startswith('gzk'):
        continue
    if site == 'Local Job' and 'LastRemoteHost' in row:
        domain = get_domain(row['LastRemoteHost'].split('@')[-1])
        if not domain:
            continue
        if domain.endswith('chtc.wisc.edu'):
            site = 'CHTC'
        elif domain.endswith('hep.wisc.edu'):
            site = 'HEP_WISC'
        elif domain.endswith('cs.wisc.edu'):
            site = 'CS_WISC'
        elif domain.endswith('math.wisc.edu'):
            site = 'MATH_WISC'
        elif domain.endswith('icecube.wisc.edu'):
            site = 'NPX'
        elif domain.endswith('wisc.edu'):
            site = 'WISC'
        elif domain.endswith('wisc.cloudlab.us'):
            site = 'CLOUD_WISC'
        else:
            print('Local Job with strange domain:',domain)
            continue
    if 'LastRemoteHost' in row:
        domain = get_domain(row['LastRemoteHost'].split('@')[-1])
        if domain:
            if domain in reserved_domains:
                continue
            if domain in domain_lookup and domain_lookup[domain] != site:
                print('duplicate site name for domain',domain)
                print(domain_lookup[domain])
                print(site)
            else:
                domain_lookup[domain] = site
    if 'StartdPrincipal' in row:
        ip_range = get_ip_range(row['StartdPrincipal'].split('/')[-1])
        if ip_range:
            if ip_range in ip_lookup and ip_lookup[ip_range] != site:
                print('duplicate site name for ip_range',ip_range)
                print(ip_lookup[ip_range])
                print(site)
            else:
                ip_lookup[ip_range] = site

def fix_site(row):
    site = row['MATCH_EXP_JOBGLIDEIN_ResourceName']
    new_site = None
    if site.startswith('gzk'):
        new_site = 'CHTC'
    if site.endswith('chtc.wisc.edu'):
        new_site = 'CHTC'
    elif site.endswith('hep.wisc.edu'):
        new_site = 'HEP_WISC'
    elif site.endswith('cs.wisc.edu'):
        new_site = 'CS_WISC'
    elif site.endswith('math.wisc.edu'):
        new_site = 'MATH_WISC'
    elif site.endswith('icecube.wisc.edu'):
        new_site = 'NPX'
    elif site.endswith('wisc.cloudlab.us'):
        new_site = 'CLOUD_WISC'
    elif site.endswith('wisc.edu'):
        new_site = 'WISC'
    elif '.' not in site and site != 'Local Job':
        return # fine the way it is
    if new_site:
        filter = {'GlobalJobId':row['GlobalJobId']}
        update = {'$set':{'MATCH_EXP_JOBGLIDEIN_ResourceName':new_site}}
        db.condor_history.update_one(filter, update)
        return
    raise Exception('cannot fix')

def fix_host(row):
    host = row['LastRemoteHost'].split('@')[-1]
    domain = get_domain(host)
    if domain and domain in reserved_domains:
        filter = {'GlobalJobId':row['GlobalJobId']}
        update = {'$set':{'MATCH_EXP_JOBGLIDEIN_ResourceName':reserved_domains[domain]}}
        db.condor_history.update_one(filter, update)
        return
    if domain and domain in domain_lookup:
        filter = {'GlobalJobId':row['GlobalJobId']}
        update = {'$set':{'MATCH_EXP_JOBGLIDEIN_ResourceName':domain_lookup[domain]}}
        db.condor_history.update_one(filter, update)
        return
    print('unknown domain',domain)
    raise Exception('cannot fix')

def fix_ip(row):
    ip = row['StartdPrincipal'].split('/')[-1]
    ip_range = get_ip_range(ip, reserved=True)
    if not ip_range:
        raise Exception('reserved ip')
    if '.' not in ip_range: # reserved range
        filter = {'GlobalJobId':row['GlobalJobId']}
        update = {'$set':{'MATCH_EXP_JOBGLIDEIN_ResourceName':ip_range}}
        db.condor_history.update_one(filter, update)
        return
    if ip_range and ip_range in ip_lookup:
        filter = {'GlobalJobId':row['GlobalJobId']}
        update = {'$set':{'MATCH_EXP_JOBGLIDEIN_ResourceName':ip_lookup[ip_range]}}
        db.condor_history.update_one(filter, update)
        return
    print('unknown ip',ip_range)
    raise Exception('cannot fix')

# remap bad sites
for row in db.condor_history.find(projection=['GlobalJobId','LastRemoteHost','StartdPrincipal','MATCH_EXP_JOBGLIDEIN_ResourceName']):
    if 'MATCH_EXP_JOBGLIDEIN_ResourceName' in row:
        try:
            fix_site(row)
        except:
            pass
        else:
            continue
    if 'LastRemoteHost' in row:
        try:
            fix_host(row)
        except:
            pass
        else:
            continue
    if 'StartdPrincipal' in row:
        try:
            fix_ip(row)
        except:
            pass
        else:
            continue
    print('cannot fix')


import contextlib
import functools
import logging
import os
import shutil
import signal
import socket
import sys
import tempfile
import time
from subprocess import CalledProcessError
from subprocess import PIPE
from subprocess import Popen
from unittest import mock

from testifycompat import assert_not_equal
from testifycompat import setup
from testifycompat import teardown
from testifycompat import TestCase
from tron.commands import client
from tron.config import manager
from tron.config import schema

# Used for getting the locations of the executable
test_dir, _ = os.path.split(__file__)
repo_root, _ = os.path.split(test_dir)

log = logging.getLogger(__name__)

def wait_on_sandbox(func, delay=0.1, max_wait=5.0):
    """Poll for func() to return True. Sleeps `delay` seconds between polls
    up to a max of `max_wait` seconds.
    """
    start_time = time.time()
    while time.time() - start_time < max_wait:
        time.sleep(delay)
        if func():
            return
    raise TronSandboxException("Failed %s" % func.__name__)

def wait_on_state(client_func, url, state, field="state"):
    """Use client_func(url) to wait until the resource changes to state."""

    def wait_func():
        return client_func(url)[field] == state

    wait_func.__name__ = f"{url} wait on {state}"
    wait_on_sandbox(wait_func)

def wait_on_proc_terminate(pid):
    def wait_on_terminate():
        try:
            os.kill(pid, 0)
        except Exception:
            return True

    wait_on_terminate.__name__ = "Wait on %s to terminate" % pid
    wait_on_sandbox(wait_on_terminate)

def build_waiter_func(client_func, url):
    return functools.partial(wait_on_state, client_func, url)

def handle_output(cmd, out_err, returncode):
    """Log process output before it is parsed. Raise exception if exit code
    is nonzero.
    """
    stdout, stderr = out_err
    cmd = " ".join(cmd)
    if stdout:
        log.warn("%s STDOUT: %s", cmd, stdout)
    if stderr:
        log.warn("%s STDERR: %s", cmd, stderr)
    if returncode:
        raise CalledProcessError(returncode, cmd)

def find_unused_port():
    """Return a port number that is not in use."""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    with contextlib.closing(sock) as sock:
        sock.bind(("localhost", 0))
        _, port = sock.getsockname()
    return port

class TronSandboxException(Exception):
    pass

class SandboxTestCase(TestCase):

    _suites = ["sandbox"]

    sandbox = None

    @setup
    def make_sandbox(self):
        verify_environment()
        self.sandbox = TronSandbox()
        self.client = self.sandbox.client

    @teardown
    def delete_sandbox(self):
        if self.sandbox:
            self.sandbox.delete()
            self.sandbox = None

    def start_with_config(self, config):
        self.sandbox.save_config(config)
        self.sandbox.trond()

    def restart_trond(self):
        old_pid = self.sandbox.get_trond_pid()
        self.sandbox.shutdown_trond()
        wait_on_proc_terminate(self.sandbox.get_trond_pid())

        self.sandbox.trond()
        assert_not_equal(old_pid, self.sandbox.get_trond_pid())

class ClientProxy:
    """Wrap calls to client and raise a TronSandboxException on connection
    failures.
    """

    def __init__(self, client, log_filename):
        self.client = client
        self.log_filename = log_filename

    def log_contents(self):
        """Return the contents of the log file."""
        with open(self.log_filename) as f:
            return f.read()

    def wrap(self, func, *args, **kwargs):
        with mock.patch("tron.commands.client.log", autospec=True):
            try:
                return func(*args, **kwargs)
            except (client.RequestError, ValueError) as e:
                # ValueError for JSONDecode errors
                log_contents = self.log_contents()
                if log_contents:
                    log.warn(f"{e!r}, Log:\n{log_contents}")
                return False

    def __getattr__(self, name):
        attr = getattr(self.client, name)
        if not callable(attr):
            return attr

        return functools.partial(self.wrap, attr)

def verify_environment():
    for env_var in ["SSH_AUTH_SOCK", "PYTHONPATH"]:
        if not os.environ.get(env_var):
            raise TronSandboxException("Missing $%s in test environment." % env_var,)

class TronSandbox:
    """A sandbox for running trond and tron commands in subprocesses."""

    def __init__(self):
        """Set up a temp directory and store paths to relevant binaries"""
        self.tmp_dir = tempfile.mkdtemp(prefix="tron-")
        cmd_path_func = functools.partial(os.path.join, repo_root, "bin")
        cmds = "tronctl", "trond", "tronfig", "tronview"
        self.commands = {cmd: cmd_path_func(cmd) for cmd in cmds}
        self.log_file = self.abs_path("tron.log")
        self.log_conf = self.abs_path("logging.conf")
        self.pid_file = self.abs_path("tron.pid")
        self.config_path = self.abs_path("configs/")
        self.port = find_unused_port()
        self.host = "localhost"
        self.api_uri = f"http://{self.host}:{self.port}"
        cclient = client.Client(self.api_uri)
        self.client = ClientProxy(cclient, self.log_file)
        self.setup_logging_conf()

    def abs_path(self, filename):
        """Return the absolute path for a file in the sandbox."""
        return os.path.join(self.tmp_dir, filename)

    def setup_logging_conf(self):
        config_template = os.path.join(repo_root, "tests/data/logging.conf")
        with open(config_template) as fh:
            config = fh.read()

        with open(self.log_conf, "w") as fh:
            fh.write(config.format(self.log_file))

    def delete(self):
        """Delete the temp directory and shutdown trond."""
        self.shutdown_trond(sig_num=signal.SIGKILL)
        shutil.rmtree(self.tmp_dir)

    def save_config(self, config_text):
        """Save the initial tron configuration."""
        manager.create_new_config(self.config_path, config_text)

    def run_command(self, command_name, args=None, stdin_lines=None):
        """Run the command by name and return (stdout, stderr)."""
        args = args or []
        command = [sys.executable, self.commands[command_name]] + args
        stdin = PIPE if stdin_lines else None
        proc = Popen(command, stdout=PIPE, stderr=PIPE, stdin=stdin)
        streams = proc.communicate(stdin_lines)
        try:
            handle_output(command, streams, proc.returncode)
        except CalledProcessError:
            log.warn(self.client.log_contents())
            raise
        return streams

    def tronctl(self, *args):
        args = list(args) if args else []
        return self.run_command("tronctl", args + ["--server", self.api_uri])

    def tronview(self, *args):
        args = list(args) if args else []
        args += ["--nocolor", "--server", self.api_uri]
        return self.run_command("tronview", args)

    def trond(self, *args):
        args = list(args) if args else []
        args += [
            "--working-dir=%s" % self.tmp_dir,
            "--pid-file=%s" % self.pid_file,
            "--port=%d" % self.port,
            "--host=%s" % self.host,
            "--config-path=%s" % self.config_path,
            "--log-conf=%s" % self.log_conf,
        ]

        self.run_command("trond", args)
        wait_on_sandbox(lambda: bool(self.client.home()))

    def tronfig(
        self, config_content=None, name=schema.MASTER_NAMESPACE,
    ):
        args = ["--server", self.api_uri, name]
        args += ["-"] if config_content else ["-p"]
        return self.run_command("tronfig", args, stdin_lines=config_content)

    def get_trond_pid(self):
        if not os.path.exists(self.pid_file):
            return None
        with open(self.pid_file) as f:
            return int(f.read())

    def shutdown_trond(self, sig_num=signal.SIGTERM):
        trond_pid = self.get_trond_pid()
        if trond_pid:
            os.kill(trond_pid, sig_num)


import logging

import docker

class DockerSubmitter(object):
    @staticmethod
    def run_docker_container(image, command):
        client = docker.from_env()
        container = client.containers.run(image, command, detach=True)
        # Streaming the logs
        for line in container.logs(stream=True):
            logging.info(line.strip())


from loguru import logger
import colorama

class Episode:
    e_id = None
    num = None
    air_date = None
    link = None

    def __init__(self, e_id, num, air_date, link):
        logger.debug(f"Creating episode obj (id: {e_id}, num: {num})")
        self.e_id = e_id
        self.num = num
        self.air_date = air_date
        self.link = link

    def __repr__(self):
        return f"{self.e_id}-{self.num}"

    def __str__(self):
        return self.link

class Related:
    a_id = None
    type = None
    title = None
    slug = None

    def __init__(self, a_id, type, title, slug):
        self.a_id = a_id
        self.type = type
        self.title = title
        self.slug = slug

    def __repr__(self):
        return f"{self.a_id}-{self.title}"

    def get_anime_url(self):
        return f"https://animeunity.it/anime/{self.a_id}-{self.slug}"

class Anime:
    a_id = None
    title = None
    title_eng = None
    thumbnail = None
    cover_image = None
    status = None
    type = None
    slug = None
    year = None
    episodes = None
    episodes_length = None
    related = None

    def __init__(self, a_id, title, type, episodes_length):
        logger.debug(f"Creating Anime obj (id: {a_id}, num: {title})")
        self.a_id = a_id
        self.title = title
        self.episodes_length = episodes_length
        # Se è OVA o ONA e dura più di 50 min lo converto in film
        if int(self.episodes_length) > 50 and (type == 'OVA' or type == 'ONA'):
            self.type = 'Movie'
        else:
            self.type = type

    def __repr__(self):
        return f"{self.a_id}-{self.title}"

    def __str__(self):
        title = f"{colorama.Fore.BLUE} {str(self.a_id)}"
        if self.type != 'TV':
            title = f"{title} {colorama.Fore.CYAN} {self.type}"
        return f"{title} {colorama.Fore.GREEN} {self.title}{('{} ({})'.format(colorama.Fore.CYAN, self.title_eng), '')[self.title_eng is None]} {colorama.Style.RESET_ALL}"

    def get_anime_url(self):
        return f"https://animeunity.it/anime/{self.a_id}-{self.slug}"


from django.db import models
import pprint
from django.conf import settings

# Create your models here.
class Game(models.Model):

    CATEGORY_PC = 1
    CATEGORY_MOBILE = 2
    CATEGORY_CONSOLE = 3
    CATEGORY_OTHER = 4

    GAME_CATEGORY = (
        (CATEGORY_PC, 'PC'),
        (CATEGORY_MOBILE, 'Mobile'),
        (CATEGORY_CONSOLE, 'Console'),
        (CATEGORY_OTHER, 'Other'),
    )

    game_name = models.CharField(max_length=100)
    game_name_jp = models.CharField(max_length=100, null=True)
    game_name_sys = models.CharField(max_length=100, null=True, db_index=True)
    game_category = models.SmallIntegerField(
        choices=GAME_CATEGORY,
        default=CATEGORY_OTHER,
    )
    game_image = models.ImageField(upload_to='streamer', null=True, blank=True)
    game_icon = models.ImageField(upload_to='streamer', null=True, blank=True)
    active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def game_name_global(self):

        if settings.SERVER_SERVICE == 'jp':
            return self.game_name_jp
        else:
            return self.game_name

    def __str__(self):
        return self.game_name


#Deep Cross Entropy
#https://colab.research.google.com/github/Cheukting/rl_workshop/blob/master/exercises/rl_workshop_deep_crossentropy_method.ipynb
'''
Instead of using a table (like for cross entropy use a function)
Start with random uniform probability for policy
loop:
    evaluate policy (using neural network - input:state out:action probabilities) n-times
    get top p% of evaluations and store the states and actions
    Use states and actions to adjust the neural network (so that it is more likely to take top_scorer actions from given states)
'''

import gym
import time
import torch
import torch.nn as nn
import torch.nn.functional as f
import random
import numpy as np
import matplotlib.pyplot as plt
from torch.nn.modules.loss import BCELoss, CrossEntropyLoss

class Network(nn.Module):
    def __init__(self, state_vars, actions):
        super(Network, self).__init__()
        self.layer1 = nn.Linear(in_features=state_vars, out_features=20)
        self.tanh = nn.Tanh()
        self.layer5 = nn.Linear(in_features=20, out_features=actions)

    def forward(self, x):
        x = self.tanh(self.layer1(x))
        x = self.tanh(self.layer5(x))
        x = f.softmax(x, dim=0)
        return x

def run_session(policy):
    states = []
    actions = []
    total_reward = 0

    done = False
    obs = env.reset()
    for _ in range(10000):
        probabilities = policy(torch.tensor(obs, dtype=torch.float)).detach().numpy() #use network to get action probabilities
        action = np.random.choice(np.arange(n_actions), p=probabilities) #Make a choice

        new_obs, reward, done, info = env.step(action)
        total_reward += reward

        states.append(obs)
        actions.append(action)

        obs = new_obs

        if done:
            break
    #print(total_reward)
    return states, actions, total_reward

def run_n_sessions(n_sessions, policy, percentile):

    #Track the generation
    n_state_list = []
    n_action_list = []
    n_total_rewards = []

    #Sample many times from the policy distribution and store the results
    for _ in range(n_sessions):
        obs_list, action_list, total_reward = run_session(policy)
        n_state_list.append(obs_list)
        n_action_list.append(action_list)
        n_total_rewards.append(total_reward)

    #Get best (state, action) pairs index
    reward_cutoff = np.percentile(n_total_rewards, percentile)
    sessions = np.argwhere(np.array(n_total_rewards) >= reward_cutoff).flatten()
    #print(top_scorers)

    top_states = []
    top_actions = []

    #for each top scorer store the states and the actions from those states that were taken
    for session in sessions:
        top_states += [state for state in n_state_list[session]]
        top_actions += [action for action in n_action_list[session]]

    #calculate average reward for generation
    gen_avg_reward = sum(n_total_rewards)/len(n_total_rewards)

    return top_states, top_actions, gen_avg_reward, reward_cutoff

def train(iterations, a_n, policy):

    x = []
    y = []

    n_sessions=100
    percentile=70
    learning_rate=0.001
    loss_fn = BCELoss()

    for i in range(iterations):
        s, a, r, cutoff = run_n_sessions(n_sessions, policy, percentile)

        #For plotting
        y.append(r)
        x.append(i)

        #Set up data for forward and back pass
        a = f.one_hot(torch.LongTensor(a), num_classes=a_n).float()
        s = torch.FloatTensor(s)

        #Use top_scorers (state, actions) to train the network
        for run in zip(s, a):
            pred = policy(run[0])
            target = run[1]
            loss = loss_fn(pred, target)
            policy.zero_grad()
            loss.backward()
            with torch.no_grad():
                for param in policy.parameters():
                    param -= learning_rate * param.grad

        print('Iteration: {} | Avg Reward: {} | Cutoff: {}'.format(i, round(r, 2), cutoff))

    return x, y, policy

def plot(x, y):
    plt.plot(x, y)
    plt.xlabel('Iterations')
    plt.ylabel('Average Reward')
    plt.show()

def test_run(version):
    done = False
    obs = env.reset()
    total_reward = 0
    for _ in range(500):
        env.render()
        probabilities = policy(torch.tensor(obs, dtype=torch.float)).detach().numpy() #use network to get action probabilities
        action = np.random.choice(np.arange(n_actions), p=probabilities) #Make a choice

        new_obs, reward, done, info = env.step(action)
        total_reward += reward

        obs = new_obs

        if done:
            break
    env.close()
    print('{} Total Reward: {}'.format(version, total_reward))

#Initialize
env_name = 'CartPole-v0'
env = gym.make(env_name).env
n_actions = env.action_space.n #number of actions
n_states = len(env.observation_space.sample()) #number of aspects for state
policy = Network(state_vars=n_states, actions=n_actions)

#Run
test_run('Pre-Training')
x, y, policy = train(100, n_actions, policy)
plot(x, y)
test_run('Post-Training')


# mylist = [1,2,3,4]
# mylist = ["manjesh",1,2,3,2.3,True,[1,2,3]]
# print(mylist[:3])
# mylist[1] = "manjesh"        #assignment
# mylist.append("singh")          #append
# mylist.extend([1,2,3,'manjesh'])
# mylist.pop(2)   #remove 2 position data in list
# print(mylist)

# ---------------------------
# a =[1,2,3,[1,"e","a","m"]]
# print(a[3][1])

#----------------------------
matrix = [[1,2,3],[4,5,6],["p","q","r"]]
# print(matrix[0][0])

#list comprehension
firstcol = [row[0] for row in matrix]    #first element in each list
print(firstcol)


import torch.nn as nn
import torch.nn.functional as F

class ResBlock(nn.Module):
    """残差模块"""
    def __init__(self ,inChannals ,outChannals):
        """初始化残差模块"""
        super(ResBlock ,self).__init__()
        self.conv1 = nn.Conv2d(inChannals ,outChannals ,kernel_size=1 ,bias=False)
        self.bn1 = nn.BatchNorm2d(outChannals)  # # 数据归一化 保证每个特征被分类器平等对待 防止小数据被大数据吃掉
        self.conv2 = nn.Conv2d(outChannals ,outChannals ,kernel_size=3 ,stride=1 ,padding=1 ,bias=False)
        self.bn2 = nn.BatchNorm2d(outChannals)
        self.conv3 = nn.Conv2d(outChannals ,outChannals ,kernel_size=1 ,bias=False)
        self.relu = nn.PReLU()

    def forward(self ,x):
        """前向传播过程"""
        resudial = x
        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)
        out = self.conv2(out)
        out = self.bn2(out)
        out = self.relu(out)
        out = self.conv3(out)
        out += resudial
        out = self.relu(out)
        return out

class Generator(nn.Module):
    """生成模型(4x)"""
    def __init__(self):
        """初始化模型配置"""
        super(Generator ,self).__init__()
        # 卷积模块1
        self.conv1 = nn.Conv2d(3 ,64 ,kernel_size=9 ,padding=4 ,padding_mode='reflect' ,stride=1)
        self.relu = nn.PReLU()
        # 残差模块
        self.resBlock = self._makeLayer_(ResBlock ,64 ,64 ,5)
        # 卷积模块2
        self.conv2 = nn.Conv2d(64 ,64 ,kernel_size=1 ,stride=1)
        self.bn2 = nn.BatchNorm2d(64)
        self.relu2 = nn.PReLU()

        # 子像素卷积
        self.convPos1 = nn.Conv2d(64 ,256 ,kernel_size=3 ,stride=1 ,padding=2 ,padding_mode='reflect')
        self.pixelShuffler1 = nn.PixelShuffle(2)
        self.reluPos1 = nn.PReLU()

        self.convPos2 = nn.Conv2d(64 ,256 ,kernel_size=3 ,stride=1 ,padding=1 ,padding_mode='reflect')
        self.pixelShuffler2 = nn.PixelShuffle(2)
        self.reluPos2 = nn.PReLU()

        self.finConv = nn.Conv2d(64 ,3 ,kernel_size=9 ,stride=1)

    def _makeLayer_(self ,block ,inChannals ,outChannals ,blocks):
        """构建残差层"""
        layers = []
        layers.append(block(inChannals ,outChannals))

        for i in range(1 ,blocks):
            layers.append(block(outChannals ,outChannals))

        return nn.Sequential(*layers)

    def forward(self ,x):
        """前向传播过程"""
        x = self.conv1(x)
        x = self.relu(x)
        residual = x
        out = self.resBlock(x)
        out = self.conv2(out)
        out = self.bn2(out)
        out += residual
        out = self.convPos1(out)
        out = self.pixelShuffler1(out)
        out = self.reluPos1(out)
        out = self.convPos2(out)
        out = self.pixelShuffler2(out)
        out = self.reluPos2(out)
        out = self.finConv(out)

        return out

    class ConvBlock(nn.Module):
        """残差模块"""

        def __init__(self, inChannals, outChannals, stride=1):
            """初始化残差模块"""
            super(ConvBlock, self).__init__()
            self.conv = nn.Conv2d(inChannals, outChannals, kernel_size=3, stride=stride, padding=1,
                                  padding_mode='reflect', bias=False)
            self.bn = nn.BatchNorm2d(outChannals)  # 数据归一化 保证每个特征被分类器平等对待 防止小数据被大数据吃掉
            self.relu = nn.LeakyReLU()

        def forward(self, x):
            """前向传播过程"""
            out = self.conv(x)
            out = self.bn(out)
            out = self.relu(out)
            return out

    class Discriminator(nn.Module):
        def __init__(self):
            super(Discriminator, self).__init__()
            self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, padding_mode='reflect')
            self.relu1 = nn.LeakyReLU()

            self.convBlock1 = ConvBlock(64, 64, stride=2)
            self.convBlock2 = ConvBlock(64, 128, stride=1)
            self.convBlock3 = ConvBlock(128, 128, stride=2)
            self.convBlock4 = ConvBlock(128, 256, stride=1)
            self.convBlock5 = ConvBlock(256, 256, stride=2)
            self.convBlock6 = ConvBlock(256, 512, stride=1)
            self.convBlock7 = ConvBlock(512, 512, stride=2)

            self.avePool = nn.AdaptiveAvgPool2d(1)  # 自适应平均池化，指定输出（H，W）
            self.conv2 = nn.Conv2d(512, 1024, kernel_size=1)
            self.relu2 = nn.LeakyReLU()
            self.conv3 = nn.Conv2d(1024, 1, kernel_size=1)
            self.sigmoid = nn.Sigmoid()

        def forward(self, x):
            x = self.conv1(x)
            x = self.relu1(x)

            x = self.convBlock1(x)
            x = self.convBlock2(x)
            x = self.convBlock3(x)
            x = self.convBlock4(x)
            x = self.convBlock5(x)
            x = self.convBlock6(x)
            x = self.convBlock7(x)

            x = self.avePool(x)
            x = self.conv2(x)
            x = self.relu2(x)
            x = self.conv3(x)
            x = self.sigmoid(x)

            return x


"""Script to migrate a Maestrowf YAML file to a CoRR YAML file

To run use:

    $ python corr-sync.py --corr-output=corr.yaml --output-path=demo/sample_output

To run the tests:

    $ py.test --doctest-modules migrate_yaml.py

Test reading a sample Maestorwf file

>>> data_path = os.path.join(get_path(), 'lulesh_sample1.yaml')
>>> test_path = os.path.join(get_path(), 'corr-test.yaml')
>>> assert mapping(read_yaml(data_path)) == read_yaml(test_path)

"""

import os

# pylint: disable=redefined-builtin
from toolz.curried import pipe, get, curry, map, filter, tail
import yaml
import glob
import mimetypes
import click

def file_metadata(path):
    """Generate metadata for one file

    >>> from click.testing import CliRunner
    >>> with CliRunner().isolated_filesystem() as dir_:
    ...     test_file = os.path.join(dir_, 'hello.json')
    ...     with open(test_file, 'w') as f:
    ...         _ = f.write('{"hello": "hello"}')
    ...     metadata = file_metadata(test_file)
    >>> assert('hello.json' in metadata['path'])
    >>> assert metadata['metadata'] == {'encoding': 'utf-8',
    ...                                 'mimetype': 'application/json',
    ...                                 'size': 18}

    Args:
      path: the path to the file

    Returns:
      dictionary of metadata
    """
    return {
        'path': os.path.relpath(path),
        'metadata': {
            'encoding': 'utf-8',
            'mimetype': mimetypes.guess_type(path)[0],
            'size': os.path.getsize(path)
        }
    }

def glob_all_files_27(path):
    """Find all files in Py 2.7
    """
    import fnmatch
    import os

    matches = []
    for root, dirnames, filenames in os.walk(path):
        for filename in fnmatch.filter(filenames, '*'):
            matches.append(os.path.join(root, filename))

    return matches

def glob_all_files(path):
    """Find all files

    Args:
      path: the path to search for files

    Returns:
      a list of files
    """
    return pipe(
        os.path.join(path, '**'),
        lambda x: glob.glob(x, recursive=True),
        filter(os.path.isfile),
    )

def outputs(path):
    """Generate outputs metadata based on path

    Args:
      path: the path to the output data

    Returns:
      a list of file metadata

    """

    return pipe(
        path,
        glob_all_files_27,
        map(file_metadata),
        list
    )

@curry
def mapping(output_path, data):
    """Map from Maestrowf data to CoRR data

    Args:
      data: the Maestrowf data
      output_path: the path to the output data

    Returns
      the CoRR data
    """
    return {
        'execution': {
            'parameters': data['global.parameters'],
            'cmd_line': data['study'][-1]['run']['cmd']},
        'system': {'env': data['env']},
        'outputs': outputs(output_path),
        'inputs': [],
        'dependencies': []
    }

def get_path():
    """Return the local file path for this file.

    Returns:
      the filepath
    """
    return pipe(
        __file__,
        os.path.realpath,
        os.path.split,
        get(0)
    )

def read_yaml(filepath):
    """Read a YAML file

    Args:
      filepath: the path to the YAML file

    Returns:
      returns a dictionary
    """
    with open(filepath) as stream:
        data = yaml.safe_load(stream)
    return data

@curry
def write_yaml_data(filepath, data):
    """Write data to YAML file

    Args:
      filepath: the path to the YAML file
      data: a dictionary to write to the YAML file

    """
    with open(filepath, 'w') as stream:
        yaml.safe_dump(data, stream, default_flow_style=False, indent=2)
    return (filepath, data)

def find_yaml_file(path):
    """Find a YAML file in the path

    Args:
      path: find a YAML file on the path

    Returns:
      the path to the YAML file
    """
    return pipe(
        path,
        glob_all_files_27,
        filter(lambda x: tail(5, x) == '.yaml'),
        list,
        get(0)
    )
"""
@click.command()
@click.option('--corr-output',
              'corr_output',
              required=True,
              default='corr.yaml',
              help="Set the CoRR YAML file")
@click.option('--output-path',
              'output_path',
              required=True,
              help="Set the outputs capture path")"""
def main(corr_output, output_path, maestro_spec_path):
    """Read in a Maestrowf YAML, translate and write the CoRR YAML
    """
    return pipe(
        maestro_spec_path,
        read_yaml,
        mapping(output_path),
        write_yaml_data(corr_output)
    )

if __name__ == '__main__':
    # data = main()
    main()


from flask import Flask,render_template,request
import pickle

from sympy import re
model=pickle.load(open('stroke.pkl','rb'))
app=Flask(__name__)
@app.route('/',methods=['GET'])
def home():
    return render_template('stroke.html')
@app.route('/predict',methods=['POST','GET'])
def predict():
    if request.method=='POST':
        gender=request.form['gender']
        if gender=='Male':
            gender=1
        else:
            gender=0
        Age=int(request.form['Age'])
        bp=request.form['bp']
        if bp=='Yes':
            bp=1
        else:
            bp=0
        heart=request.form['heart']
        if heart=='Yes':
            heart=0
        else:
            heart=1
        married=request.form['married']
        if married=='Yes':
            married=1
        else:
            married=0
        work=request.form['work']
        if work=='never wroked':
            work=1
        elif work=='private':
            work=2
        elif work=='self employed':
            work=3
        elif work=='childern':
            work=4
        else:
            work=0
        house=request.form['house']
        if house=='Urban Housing':
            house=1
        else:
            house=0
        glucose=int(request.form['glucose'])
        bmi=int(request.form['bmi'])
        smoking=request.form['smoking']
        if smoking=='Used to Smoke':
            smoking=1
        elif smoking=='Never Smoked':
            smoking=2
        elif smoking=='Smokes':
            smoking=3
        else:
            smoking=0
        pred=model.predict([[gender,Age,bp,heart,married,work,house,glucose,bmi,smoking]])
        if pred==0:
            return render_template('pred.html',text='You will never have a stroke in the near future,maintain good health and diet.')
        else:
            return render_template('pred.html',text='You may have stroke in the near future Please take precautions and lead a stress free life as possible.')
    else:
        return render_template('stroke.html')
if __name__=='__main__':
    app.run(debug=True)


FONT = ("Courier", 24, "normal")
from turtle import Turtle

class Scoreboard(Turtle):
    def __init__(self):
        super().__init__()
        self.hideturtle()
        self.penup()
        self.s_count = 0
        self.goto(-250,250)
        self.score_count()
    def score_count(self):
        self.clear()
        self.write(arg=f"Score {self.s_count}", font=FONT)
        self.s_count += 1


# 此示例示意用F.seel方法来修改文件读写指针的位置
try:
    fr = open("my20bytes.txt", "rb")
    b1 = fr.read(3)
    print("读完3个字节后指针的位置在:", fr.tell())
    # 相对文件头偏移
    #fr.seek(5,0)
    # 相对于当前位置向后移动两个字节
    fr.seek(2,1) #走到了C 偏移两个到D
    # 相对于文件尾向前移动
    #fr.seek(-15, 2)
    b2 = fr.read(5)  # 要读取从第5个到第9个字节 b2=abcde
    print(b2)

    fr.close()
except OSError:
    print("文件打开失败")


import pandas as pd
from datetime import datetime
from sklearn.neighbors import KNeighborsRegressor

def transform_and_normalize_data(df, stores_df):
    df = pd.merge(df, stores_df, on='Store')
    X = df[['Store', 'Type', 'Size', 'Dept', 'Date', 'IsHoliday']].as_matrix()

    max_size = 0
    max_week = 0
    for i in range(int(X.size/6)):
        X[i][1] = ord(X[i][1]) - ord('A')
        if max_size < X[i][2]: max_size = X[i][2]
        X[i][4] = datetime.strptime(X[i][4], '%Y-%m-%d').isocalendar()[1]
        if max_week < X[i][4]: max_week = X[i][4]
    for i in range(int(X.size/6)):
        X[i][2] /= max_size
        X[i][4] /= max_week

    return X

# Retrieve stores' information.
stores_df = pd.read_csv('stores.csv')

# Retrieve and pre-process the training set.
train_df = pd.read_csv('train.csv')
X = transform_and_normalize_data(train_df, stores_df)
y = train_df[['Weekly_Sales']].as_matrix()

# Train the kNN model.
knn_regressor = KNeighborsRegressor(n_neighbors=50, weights='distance', p=1)
knn_regressor.fit(X, y)

# Retrieve and pre-process the testing set.
test_df = pd.read_csv('test.csv')
T = transform_and_normalize_data(test_df, stores_df)
ids = test_df[['Store', 'Dept', 'Date']].as_matrix()

# Write the prediction results to submission.csv file.
with open('submission.csv', 'w') as file:
    file.write('Id,Weekly_Sales\n')
    for i in range(int(T.size/6)):
        (store, store_type, size, dept, date, is_holiday) = (T[i][0], T[i][1], T[i][2], T[i][3], T[i][4], T[i][5])
        file.write("%s_%s_%s," % (ids[i][0], ids[i][1], ids[i][2]))
        file.write(str(knn_regressor.predict([[store, store_type, size, dept, date, is_holiday]])[0][0]))
        file.write('\n')


from Constants import*

class AmountEdit(QtGui.QLineEdit):
    def __init__(self, txt, parent=None):
        super(AmountEdit, self).__init__(parent)

        self.txt = txt
        #self.textChanged().connect(self.numbify)

    def paintEvent(self, QPaintEvent):
        QtGui.QLineEdit.paintEvent(self, QPaintEvent)
        if self.txt:
            panel = QtGui.QStyleOptionFrameV2()
            self.initStyleOption(panel)
            txtRect = self.style().subElementRect(QtGui.QStyle.SE_LineEditContents,
                panel, self)
            txtRect.adjust(2, 0, -10, 0)
            painter = QtGui.QPainter(self)
            painter.setPen(self.palette().brush(QtGui.QPalette.Disabled,
                QtGui.QPalette.Text).color())
            painter.drawText(txtRect, QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter,
                self.txt)

    def numbify(self):
        text = unicode(self.text()).strip()
        chars = '0123456789.'
        position = self.cursorPosition()
        string = ''.join([i for i in text if i in chars])
        if '.' in string:
            p = string.find('.')
            string = string.replace('.', '')
            string = string[:p]+'.'+string[p:]
        self.setText(string)
        self.setCursorPosition(position)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 17 14:48:01 2020

@author: Dr. Z

Draw squares in opposite directions at the same time.
"""

import turtle

LEFT = turtle.Turtle() #turtle draws square to left
RIGHT = turtle.Turtle() # draws to right
LEFT.speed(10)
RIGHT.speed(10)

running = True

while running:
    for i in range(2):
        for k in range(4):
            # draw squares
            RIGHT.forward(50)
            RIGHT.right(90)
            LEFT.forward(50)
            LEFT.left(90)

        LEFT.forward(100)
        RIGHT.forward(100)
    running = False # animation complete

turtle.done()


import pandas as pd
from sklearn.linear_model import LinearRegression
data = pd.read_csv("papsep2022.csv")

features = data[["place","area"]]
target = data["price"]

print(features)
print(target)

model = LinearRegression()
model.fit(features , target)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import shutil
import re
import numpy as np
import matplotlib.pyplot as plt
from tabulate import tabulate

from read_data import read_data_set
from fit_data import emg, fit_emg, get_mean_and_variance

DIR_NAME = "KD"
ACCEPTANCE_RE = re.compile("^\d{2}_\d{3}\d?$")
INITIAL_GUESS_S1 = [1.73491118e+03, 3.53554040e-02, 7.67608013e-02, 1.15105759e+00, 0]
INITIAL_GUESS_S2 = [2.50655373e+02, 1.03182670e+01, 6.82937190e-02, 2.84176352e-01, 0]

analyzed = {"13": {}, "23": {}}

for dir in [name for name in os.listdir(DIR_NAME) if os.path.isdir(os.path.join(DIR_NAME, name))]:
    if ACCEPTANCE_RE.match(dir):
        dir_path = os.path.join(DIR_NAME, dir)
        shutil.rmtree(dir_path + "_fitpng", ignore_errors=True)
        os.mkdir(dir_path + "_fitpng")
        from_to, voltage, header, units, indices, data = read_data_set(dir_path)
        hs1 = []
        hs2 = []
        mus1 = []
        mus2 = []
        sigmas1 = []
        sigmas2 = []
        taus1 = []
        taus2 = []
        cs1 = []
        cs2 = []
        mus_diff = []
        Delta_hs1 = []
        Delta_hs2 = []
        Delta_mus1 = []
        Delta_mus2 = []
        Delta_sigmas1 = []
        Delta_sigmas2 = []
        Delta_taus1 = []
        Delta_taus2 = []
        Delta_cs1 = []
        Delta_cs2 = []
        Delta_mus_diff = []

        if (units[1] == "V"):
            data[:, 1, :] *= 1000
        if (units[2] == "V"):
            data[:, 2, :] *= 1000
        for index, dataset in zip(indices, data):
            try:
                popt1, pcov1 = fit_emg(dataset[0], dataset[1], INITIAL_GUESS_S1)
            except:
                print("could not fit 1!")
                continue
            try:
                INITIAL_GUESS_S2[1] = dataset[0][np.argmax(dataset[2])]
                popt2, pcov2 = fit_emg(dataset[0], dataset[2], INITIAL_GUESS_S2)
            except:
                print("could not fit 2!")
                continue
            hs1.append(popt1[0])
            hs2.append(popt2[0])
            mu1 = popt1[1]
            mu2 = popt2[1]
            mus1.append(popt1[1])
            mus2.append(popt2[1])
            sigmas1.append(popt1[2])
            sigmas2.append(popt2[2])
            Delta_hs1.append(np.sqrt(pcov1[0][0]))
            Delta_hs2.append(np.sqrt(pcov2[0][0]))
            Delta_mus1.append(np.sqrt(pcov1[1][1]))
            Delta_mus2.append(np.sqrt(pcov2[1][1]))
            Delta_sigmas1.append(np.sqrt(pcov1[2][2]))
            Delta_sigmas2.append(np.sqrt(pcov2[2][2]))
            tau1 = popt1[3]
            Delta_mu1 = np.sqrt(pcov1[1][1])
            Delta_mu2 = np.sqrt(pcov2[1][1])
            tau2 = popt2[3]
            taus1.append(tau1)
            taus2.append(tau2)
            Delta_taus1.append(np.sqrt(pcov1[3][3]))
            Delta_taus2.append(np.sqrt(pcov1[3][3]))
            cs1.append(popt1[4])
            cs2.append(popt2[4])
            Delta_cs1.append(np.sqrt(pcov1[4][4]))
            Delta_cs2.append(np.sqrt(pcov2[4][4]))
            if mu1 and mu2:
                mus_diff.append(np.abs(mu2-mu1))
                Delta_mus_diff.append(np.sqrt(Delta_mu1**2+Delta_mu2**2))
            else:
                mus_diff.append(0)
                Delta_mus_diff.append(0)
            # palette = plt.get_cmap('Blues')
            # palette1 = plt.get_cmap('Oranges')
            # plt.plot(dataset[0], emg(dataset[0], *popt1), color=palette(1000))
            # plt.scatter(dataset[0][::10],dataset[1][::10], color=palette(900))
            # # plt.errorbar(dataset[0], dataset[1], 0.01/np.sqrt(3), color=palette(900), fmt='.')
            # plt.plot(dataset[0], emg(dataset[0], *popt2), color=palette1(1000))
            # plt.scatter(dataset[0][::10],dataset[2][::10], color=palette1(900))
            # # plt.errorbar(dataset[0], dataset[2], 0.01/np.sqrt(3), color=palette1(900), fmt='.')
            # plt.savefig(os.path.join(dir_path + "_fitpng", f"{from_to}_{voltage}_{index}.png"))
            # plt.xlabel('Time (µs)')
            # plt.ylabel('Voltage (mV)')
            # plt.grid(True)
            # plt.show()
            # plt.clf()
            print(units, from_to, voltage, index)
        analyzed[from_to][str(voltage)] = np.array([hs1, Delta_hs1, mus1, Delta_mus1, sigmas1, Delta_sigmas1, taus1, Delta_taus1, cs1, Delta_cs1, hs2, Delta_hs2, mus2, Delta_mus2, sigmas2, Delta_sigmas2, taus2, Delta_taus2, cs2, Delta_cs2])

data_dir = "DATA"
shutil.rmtree(data_dir, ignore_errors=True)
os.mkdir(data_dir)
for from_to, byfreq in analyzed.items():
    for voltage, data in byfreq.items():
        np.savetxt(os.path.join(data_dir, f"{from_to}_{voltage}.tsv"), data.T, delimiter="\t", header="h1 [mV]\t Delta h1 [mV] \t mu1 [us] \t Delta_mu1 [us]\tsigma1 [us]\t Delta_sigma1 [us] \t tau1 [us]\t Delta_tau1 [us] \t c1 [mV] \t Delta_c1 [mV]\th2 [mV]\t Delta h2 [mV] \t mu2 [us] \t Delta_mu2 [us]\tsigma2 [us]\t Delta_sigma2 [us] \t tau2 [us]\t Delta_tau2 [us] \t c2 [mV] \t Delta_c2 [mV]")
        f = open(os.path.join(data_dir, f"_tex_{from_to}_{voltage}.tex"), 'w+')
        f.write(tabulate(data.T,
                                         headers=["h1 [mV]", "Delta h1 [mV]", "mu1 [us]", "Delta_mu1 [us]", "sigma1 [us]", "Delta_sigma1 [us]", "tau1 [us]", "Delta_tau1 [us]", "c1 [mV]", "Delta_c1 [mV]", "h2 [mV]", "Delta h2 [mV]", "mu2 [us]", "Delta_mu2 [us]", "sigma2 [us]", "Delta_sigma2 [us]", "tau2 [us]", "Delta_tau2 [us]", "c2 [mV]", "Delta_c2 [mV]"],
                                         tablefmt='latex'))
        f.close()
print("done", analyzed)


#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import random
from math import *
import sys
import copy

class Reversi:
    M = 8
    DIRS = [(0, 1), (1, 0), (-1, 0), (0, -1),
            (1, 1), (-1, -1), (1, -1), (-1, 1)]

    def __init__(self):
        self.board = self.initial_board()
        self.fields = set()
        self.move_list = []
        self.history = []
        self.last_player = 1
        for i in range(self.M):
            for j in range(self.M):
                if self.board[i][j] is None:
                    self.fields.add((j, i))

    def initial_board(self):
        B = [[None] * self.M for _ in range(self.M)]
        B[3][3] = 1
        B[4][4] = 1
        B[3][4] = 0
        B[4][3] = 0
        return B

    def draw(self):
        for i in range(self.M):
            res = []
            for j in range(self.M):
                b = self.board[i][j]
                if b is None:
                    res.append('.')
                elif b == 1:
                    res.append('#')
                else:
                    res.append('o')
            print(''.join(res))
        print('')

    def clone(self):
        cl = copy.deepcopy(self)
        return cl

    def moves(self):
        res = []
        player = 1-self.last_player
        for (x, y) in self.fields:
            if any(self.can_beat(x, y, direction, player)
                   for direction in self.DIRS):
                res.append((x, y))
        return res

    def can_beat(self, x, y, d, player):
        dx, dy = d
        x += dx
        y += dy
        cnt = 0
        while self.get(x, y) == 1 - player:
            x += dx
            y += dy
            cnt += 1
        return cnt > 0 and self.get(x, y) == player

    def get(self, x, y):
        if 0 <= x < self.M and 0 <= y < self.M:
            return self.board[y][x]
        return None

    def do_move(self, move):
        player = 1 - self.last_player
        #print(player,len(self.move_list))
        assert player == len(self.move_list) % 2
        self.history.append([x[:] for x in self.board])
        self.move_list.append(move)

        if move is None:
            return
        x, y = move
        x0, y0 = move
        self.board[y][x] = player
        self.fields -= set([move])
        for dx, dy in self.DIRS:
            x, y = x0, y0
            to_beat = []
            x += dx
            y += dy
            while self.get(x, y) == 1 - player:
                to_beat.append((x, y))
                x += dx
                y += dy
            if self.get(x, y) == player:
                for (nx, ny) in to_beat:
                    self.board[ny][nx] = player

        self.last_player = 1-self.last_player

    def result(self):
        res = 0
        for y in range(self.M):
            for x in range(self.M):
                b = self.board[y][x]
                if b == 0:
                    res -= 1
                elif b == 1:
                    res += 1
        return res

    def get_result(self, playerjm):
        jmcount = len([(x,y) for x in range(8) for y in range(8) if self.board[x][y] == playerjm])
        notjmcount = len([(x,y) for x in range(8) for y in range(8) if self.board[x][y] == 3 - playerjm])
        if jmcount > notjmcount: return 1.0
        elif notjmcount > jmcount: return 0.0
        else: return 0.5

    def terminal(self):
        if not self.fields:
            return True
        if len(self.move_list) < 2:
            return False
        return self.move_list[-1] is None and self.move_list[-2] is None

class Node:

    def __init__(self, move = None, parent = None, state = None):
        self.move = move
        self.parent_node = parent
        self.child_nodes = []
        self.wins = 0
        self.visits = 0
        self.untried_moves = state.moves()
        self.last_player = state.last_player

    def select_child(self):
        s = sorted(self.child_nodes, key = lambda c: c.wins/c.visits + sqrt(2*log(self.visits)/c.visits))[-1]
        return s

    def add_child(self, m, s):
        n = Node(move = m, parent = self, state = s)
        self.untried_moves.remove(m)
        self.child_nodes.append(n)
        return n

    def update(self, result):
        self.visits += 1
        self.wins += result

    def __repr__(self):
        return "[M:" + str(self.move) + " W/V:" + str(self.wins) + "/" + str(self.visits) + " U:" + str(self.untried_moves) + "]"

    def TreeToString(self, indent):
        s = self.IndentString(indent) + str(self)
        for c in self.child_nodes:
             s += c.TreeToString(indent+1)
        return s

    def IndentString(self,indent):
        s = "\n"
        for i in range (1,indent+1):
            s += "| "
        return s

    def ChildrenToString(self):
        s = ""
        for c in self.child_nodes:
             s += str(c) + "\n"
        return s

def UCT(rootstate, itermax, verbose = False):
    rootnode = Node(state = rootstate)

    for i in range(itermax):
        node = rootnode
        state = rootstate.clone()

        # Select
        while node.untried_moves == [] and node.child_nodes != []:
            node = node.select_child()
            state.do_move(node.move)

        # Expand
        if node.untried_moves != []:
            m = random.choice(node.untried_moves)
            state.do_move(m)
            node = node.add_child(m,state)

        # Rollout
        while state.moves() != []:
            state.do_move(random.choice(state.moves()))

        # Backpropagate
        while node != None:
            node.update(state.get_result(node.last_player))
            node = node.parent_node
    '''
    if (verbose): print(rootnode.TreeToString(0))
    else: print(rootnode.ChildrenToString())'''

    return sorted(rootnode.child_nodes, key = lambda c: c.visits)[-1].move

M = 8

def initial_board():
    B = [ [None] * 8 for i in range(8)]
    B[3][3] = 1
    B[4][4] = 1
    B[3][4] = 0
    B[4][3] = 0
    return B

def field_values():
    B = [[[0 for i in range(8)] for j in range(8)] for i in range(2)]
    for i in range(2):
        B[i][0][0]=B[i][0][7]=B[i][7][0]=B[i][7][7]=30
        B[i][0][1]=B[i][1][0]=B[i][1][1]=-5
        B[i][0][6]=B[i][1][6]=B[i][1][7]=-5
        B[i][6][0]=B[i][6][1]=B[i][7][1]=-5
        B[i][6][6]=B[i][6][7]=B[i][7][6]=-5

    return B

def in_range(x,y):
    return x>=0 and x<8 and y>=0 and y<8

class Board:
    dirs  = [ (0,1), (1,0), (-1,0), (0,-1), (1,1), (-1,-1), (1,-1), (-1,1) ]

    def __init__(self):
        self.board = initial_board()
        self.vals = field_values()
        self.safe_fields = [[-1 for i in range(8)] for j in range(8)]
        self.fields = set()
        self.move_list = []
        self.history = []
        self.safe_history = []
        self.vals_history = []
        for i in range(M):
            for j in range(M):
                if self.board[i][j] == None:
                    self.fields.add( (j,i) )

    def draw(self):
        for i in range(M):
            res = []
            for j in range(M):
                b = self.board[i][j]
                if b == None:
                    res.append('.')
                elif b == 1:
                    res.append('#')
                else:
                    res.append('o')
            print (''.join(res))
        print ()

    def show(self):
        for i in range(M):
            for j in range(M):
                kwadrat(j, i, 'green')

        for i in range(M):
            for j in range(M):
                if self.board[i][j] == 1:
                    kolko(j, i, 'black')
                if self.board[i][j] == 0:
                    kolko(j, i, 'white')

    def moves(self, player):
        res = []

        for (x,y) in self.fields:
            if any( self.can_beat(x,y, direction, player) for direction in Board.dirs):
                res.append( (x,y) )
        if not res:
            return [None]
        return res

    def can_beat(self, x,y, d, player):
        dx,dy = d
        x += dx
        y += dy
        cnt = 0
        while self.get(x,y) == 1-player:
            x += dx
            y += dy
            cnt += 1
        return cnt > 0 and self.get(x,y) == player

    def safe(self,y,x,player):
        if in_range(x,y)==False:
            return False
        if self.board[y][x]!=player:
            return False
        hor = in_range(x,y) and (x==0 or x==7 or self.safe_fields[y][x-1]==player or self.safe_fields[y][x+1]==player)
        ver = in_range(x,y) and (y==0 or y==7 or self.safe_fields[y-1][x]==player or self.safe_fields[y+1][x]==player)
        diag_l = in_range(x,y) and (x==0 or x==7 or y==0 or y==7 or self.safe_fields[y-1][x+1]==player or self.safe_fields[y+1][x-1]==player)
        diag_r = in_range(x,y) and (x==0 or x==7 or y==0 or y==7 or self.safe_fields[y+1][x+1]==player or self.safe_fields[y-1][x-1]==player)

        return (hor and ver and diag_l and diag_r)

    def get(self, x,y):
        if 0 <= x < M and 0 <=y < M:
            return self.board[y][x]
        return None

    def undo(self):
        self.board = self.history.pop()
        self.safe_fields = self.safe_history.pop()
        self.vals = self.vals_history.pop()
        x = self.move_list.pop()
        if x!=None:
            self.fields.add(x)

    def change_vals(self, move, player):
        if move == (0,0):
            self.vals[player][1][1]=0
            self.vals[player][1][0]=self.vals[player][0][1]=10
        elif move == (7,0):
            self.vals[player][1][6]=0
            self.vals[player][0][6]=self.vals[player][1][7]=10
        elif move == (0,7):
            self.vals[player][6][1]=0
            self.vals[player][6][0]=self.vals[player][7][1]=10
        elif move == (7,7):
            self.vals[player][6][6]=0
            self.vals[player][6][7]=self.vals[player][7][6]=10

        if self.board[0][0]==player and self.board[1][0]==player:
            self.vals[player][2][0]=10

        if self.board[0][0]==player and self.board[0][1]==player:
            self.vals[player][0][2]=10

        if self.board[0][7]==player and self.board[0][6]==player:
            self.vals[player][0][5]=10

        if self.board[0][7]==player and self.board[1][7]==player:
            self.vals[player][2][7]=10

        if self.board[7][0]==player and self.board[6][0]==player:
            self.vals[player][5][0]=10

        if self.board[7][0]==player and self.board[7][1]==player:
            self.vals[player][7][2]=10

        if self.board[7][7]==player and self.board[7][6]==player:
            self.vals[player][7][5]=10

        if self.board[7][7]==player and self.board[6][7]==player:
            self.vals[player][5][7]=10

        if self.board[0][0]==player and self.board[1][0]==player and self.board[0][1]==player and (self.board[0][2]==player or self.board[2][0]==player):
            self.vals[player][1][1]=10

        if self.board[0][7]==player and self.board[1][7]==player and self.board[0][6]==player and (self.board[0][5]==player or self.board[2][7]==player):
            self.vals[player][1][6]=10

        if self.board[7][0]==player and self.board[7][1]==player and self.board[6][0]==player and (self.board[5][0]==player or self.board[7][2]==player):
            self.vals[player][6][1]=10

        if self.board[7][7]==player and self.board[7][6]==player and self.board[6][7]==player and (self.board[5][7]==player or self.board[7][5]==player):
            self.vals[player][6][6]=10

    def do_move(self, move, player):
        self.history.append([x[:] for x in self.board])
        self.safe_history.append(copy.deepcopy(self.safe_fields))
        self.vals_history.append(copy.deepcopy(self.vals))
        self.move_list.append(move)
        #print(self.move_list)
        if move == None:
            return
        x,y = move
        x0,y0 = move
        self.board[y][x] = player
        #self.safe_update(move,player)
        self.fields -= set([move])
        for dx,dy in self.dirs:
            x,y = x0,y0
            to_beat = []
            x += dx
            y += dy
            while self.get(x,y) == 1-player:
              to_beat.append( (x,y) )
              x += dx
              y += dy
            if self.get(x,y) == player:
                for (nx,ny) in to_beat:
                    self.board[ny][nx] = player

        self.change_vals(move,player)

    def result(self):
        res = 0
        for y in range(M):
            for x in range(M):
                b = self.board[y][x]
                if b == 0:
                    res -= 1
                elif b == 1:
                    res += 1
        return res

    def balance(self):
        x = self.count()
        return x[0] - x[1]

    def count(self):
        white = 0
        black = 0
        for i in range(8):
            for j in range(8):
                if self.board[i][j]==1:
                    white+=1
                elif self.board[i][j]==0:
                    black+=1
        return (black,white)

    def count_safe(self):
        white = 0
        black = 0

        if self.board[0][0]!=None:
            self.safe_fields[0][0]=self.board[0][0]
        if self.board[7][0]!=None:
            self.safe_fields[7][0]=self.board[7][0]
        if self.board[0][7]!=None:
            self.safe_fields[0][7]=self.board[0][7]
        if self.board[7][7]!=None:
            self.safe_fields[7][7]=self.board[7][7]

        line_0 = 0
        line_7 = 0

        for i in range(1,7):
            if self.board[0][i]!=None:
                line_0+=1
            if self.board[0][i]!=None and self.safe_fields[0][i-1]>=0 and self.safe_fields[0][i-1] == self.board[0][i]:
                self.safe_fields[0][i] = self.board[0][i]
            if self.board[7][i]!=None:
                line_7+=1
            if self.board[7][i]!=None and self.safe_fields[7][i-1]>=0 and self.safe_fields[7][i-1] == self.board[7][i]:
                self.safe_fields[7][i] = self.board[7][i]

        if line_0==6 and self.board[0][0]!=None and self.board[0][7]!=None:
            for i in range(1,7):
                self.safe_fields[0][i]=self.board[0][i]

        if line_7==6 and self.board[7][0]!=None and self.board[7][7]!=None:
            for i in range(1,7):
                self.safe_fields[7][i]=self.board[7][i]

        for i in range(6,0,-1):
            if self.board[0][i]!=None and self.safe_fields[0][i-1]>=0 and self.safe_fields[0][i-1] == self.board[0][i]:
                self.safe_fields[0][i] = self.board[0][i]
            if self.board[7][i]!=None and self.safe_fields[7][i-1]>=0 and self.safe_fields[7][i-1] == self.board[7][i]:
                self.safe_fields[7][i] = self.board[7][i]

        line_0 = 0
        line_7 = 0

        for i in range(1,7):
            if self.board[i][0]!= None:
                line_0+=1
            if self.board[i][0]!=None and self.safe_fields[i-1][0]>=0 and self.safe_fields[i-1][0] == self.board[i][0]:
                self.safe_fields[i][0] = self.board[i][0]
            if self.board[i][7]!=None:
                line_7+=1
            if self.board[i][7]!=None and self.safe_fields[i-1][7]>=0 and self.safe_fields[i-1][7] == self.board[i][7]:
                self.safe_fields[i][7] = self.board[i][7]

        if line_0==6 and self.board[0][0]!=None and self.board[0][7]!=None:
            for i in range(1,7):
                self.safe_fields[0][i]=self.board[0][i]

        if line_7==6 and self.board[7][0]!=None and self.board[7][7]!=None:
            for i in range(1,7):
                self.safe_fields[7][i]=self.board[7][i]

        for i in range(6,0,-1):
            if self.board[i][0]!=None and self.safe_fields[i-1][0]>=0 and self.safe_fields[i-1][0] == self.board[i][0]:
                self.safe_fields[i][0] = self.board[i][0]
            if self.board[i][7]!=None and self.safe_fields[i-1][7]>=0 and self.safe_fields[i-1][7] == self.board[i][7]:
                self.safe_fields[i][7] = self.board[i][7]

        for i in range(1,7):
            for j in range(1,7):
                x = self.board[i][j]
                if x!=None and (self.safe_fields[i][j-1]==x or self.safe_fields[i][j+1]==x) and (self.safe_fields[i-1][j]==x or self.safe_fields[i+1][j]==x) and (self.safe_fields[i-1][j-1]==x or self.safe_fields[i+1][j+1]==x) and (self.safe_fields[i+1][j-1]==x or self.safe_fields[i-1][j+1]==x):
                    self.safe_fields[j][j]=x

            for j in range(6,0,-1):
                x = self.board[i][j]
                if x!=None and (self.safe_fields[i][j-1]==x or self.safe_fields[i][j+1]==x) and (self.safe_fields[i-1][j]==x or self.safe_fields[i+1][j]==x) and (self.safe_fields[i-1][j-1]==x or self.safe_fields[i+1][j+1]==x) and (self.safe_fields[i+1][j-1]==x or self.safe_fields[i-1][j+1]==x):
                    self.safe_fields[j][j]=x

        for i in range(6,0,-1):
            for j in range(1,7):
                x = self.board[i][j]
                if x!=None and (self.safe_fields[i][j-1]==x or self.safe_fields[i][j+1]==x) and (self.safe_fields[i-1][j]==x or self.safe_fields[i+1][j]==x) and (self.safe_fields[i-1][j-1]==x or self.safe_fields[i+1][j+1]==x) and (self.safe_fields[i+1][j-1]==x or self.safe_fields[i-1][j+1]==x):
                    self.safe_fields[j][j]=x

            for j in range(6,0,-1):
                x = self.board[i][j]
                if x!=None and (self.safe_fields[i][j-1]==x or self.safe_fields[i][j+1]==x) and (self.safe_fields[i-1][j]==x or self.safe_fields[i+1][j]==x) and (self.safe_fields[i-1][j-1]==x or self.safe_fields[i+1][j+1]==x) and (self.safe_fields[i+1][j-1]==x or self.safe_fields[i-1][j+1]==x):
                    self.safe_fields[j][j]=x

        for i in range(8):
            for j in range(8):
                if self.safe_fields[i][j]==0:
                    black+=1
                elif self.safe_fields[i][j]==1:
                    white+=1

        return (black,white)

    def count_vals(self):
        n = len(self.move_list)-1
        if n>63:
            return (0,0)
        #print(n)
        black_sum = 0
        white_sum = 0

        for i in range(8):
            for j in range(8):
                if self.board[i][j]==0:
                    black_sum+=F.vals[n][i][j]
                elif self.board[i][j]==1:
                    white_sum+=F.vals[n][i][j]

        return (black_sum,white_sum)

    def terminal(self):
        if not self.fields:
            return True
        if len(self.move_list) < 2:
            return False
        return self.move_list[-1] == self.move_list[-2] == None

    def random_move(self, player):
        ms = self.moves(player)
        if ms:
            return random.choice(ms)
        return [None]

class Agent:
    def agent_move(self,board, player):
        move_list = board.moves(player)
        if player==0:
            max_eval = -float("inf")
            best_move = 0
            for x in move_list:
                board.do_move(x,player)
                eval_move = self.alpha_beta(board, 0, float("inf"), -float("inf"), 1-player)
                if eval_move > max_eval:
                    best_move = x
                    max_eval = eval_move
                board.undo()
        else:
            min_eval = float("inf")
            best_move = 0
            for x in move_list:
                board.do_move(x,player)
                eval_move = self.alpha_beta(board, 0, float("inf"), -float("inf"), 1-player)
                if eval_move < min_eval:
                    best_move = x
                    min_eval = eval_move
                board.undo()
        return best_move

    def corners(self,board):
        black_sum = 0
        white_sum = 0
        for i in range(8):
            for j in range(8):
                if board.board[i][j]==0:
                    black_sum+=board.vals[0][i][j]
                elif board.board[i][j]==1:
                    white_sum+=board.vals[1][i][j]
        return black_sum-white_sum

    def heuristic(self,board, player):
        saves = board.count_safe()

        n = len(board.move_list)

        return n*(saves[0]-saves[1])+(n/20)*board.balance()+3*self.corners(board)

    def alpha_beta(self,board, depth, alpha, beta, player):

        if depth == 0 or board.terminal():
            return self.heuristic(board, player)

        if player == 0:
            max_eval = - float("inf")
            move_list = board.moves(player)
            for x in move_list:
                board.do_move(x, player)
                eval_move = self.alpha_beta(board, depth-1, alpha, beta, 1-player)
                max_eval = max(max_eval,eval_move)
                alpha = max(alpha, eval_move)
                board.undo()
                if beta<=alpha:
                    break
            return max_eval
        else:
            min_eval = float("inf")
            move_list = board.moves(player)
            for x in move_list:
                board.do_move(x,player)
                eval_move = self.alpha_beta(board, depth-1, alpha, beta, 1-player)
                min_eval = min(min_eval,eval_move)
                beta = min(beta, eval_move)
                board.undo()
            return min_eval

def play_game():
    agent_player = 0
    ties = 0
    agent_wins = 0
    mcts_wins = 0
    for i in range(10):
        state = Reversi()
        agent_board = Board()

        agent = Agent()
        while (state.moves() != []):

            if state.last_player == 1-agent_player:
                m = agent.agent_move(agent_board,agent_player)
            else:
                m = UCT(rootstate = state, itermax = 100, verbose = False)
            state.do_move(m)
            agent_board.do_move(m,state.last_player)
            #print(state.last_player,m)
            #state.draw()
            #raw_input()
        res = state.result()
        if res == 0:
            ties+=1
            print("tie")
        elif res<0:
            if agent_player==0:
                agent_wins+=1
                print("agent")
            else:
                mcts_wins+=1
                print("mcts")
        else:
            if agent_player==0:
                mcts_wins+=1
                print("mcts")
            else:
                agent_wins+=1
                print("agent")
        agent_player = 1-agent_player

    print(agent_wins,ties,mcts_wins)

if __name__ == "__main__":

    play_game()