"""
126. Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

Only one letter can be changed at a time
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
Note:

Return an empty list if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]

Example 2:

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Output: []

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

"""

class WordLadderII:

    def doit_bfs_bidirect(self, beginWord, endWord, wordList):
        import collections
        import string

        if endWord not in wordList:
            return []

        def construct_paths(source, dest, tree):
            if source == dest:
                return [[source]]
            return [[source] + path for succ in tree[source] for path in construct_paths(succ, dest, tree)]

        def add_path(tree, word, neigh, is_forw):
            if is_forw:
                tree[word] += neigh,
            else:
                tree[neigh] += word,

        def bfs_level(this_lev, oth_lev, tree, is_forw, words_set):
            if not this_lev:
                return False

            if len(this_lev) > len(oth_lev):
                return bfs_level(oth_lev, this_lev, tree, not is_forw, words_set)

            for word in (this_lev | oth_lev):
                words_set.discard(word)

            next_lev, done = set(), False
            while this_lev:
                word = this_lev.pop()
                for c in string.ascii_lowercase:
                    for index in range(len(word)):
                        neigh = word[:index] + c + word[index + 1:]
                        if neigh in oth_lev:
                            done = True
                            add_path(tree, word, neigh, is_forw)
                        if not done and neigh in words_set:
                            next_lev.add(neigh)
                            add_path(tree, word, neigh, is_forw)

            return done or bfs_level(next_lev, oth_lev, tree, is_forw, words_set)

        tree, path, paths = collections.defaultdict(list), [beginWord], []
        bfs_level(set([beginWord]), set([endWord]), tree, True, set(wordList))

        return construct_paths(beginWord, endWord, tree)

    def doit_bfs(self, beginWord, endWord, wordList):
        from collections import defaultdict
        tree, words, n = defaultdict(set), set(wordList), len(beginWord)
        if endWord not in wordList:
            return []

        found, bq, eq, nq, rev = False, {beginWord}, {endWord}, set(), False
        while bq and not found:
            words -= set(bq)
            for x in bq:
                for i in range(n):
                    first, second = x[:i], x[i + 1:]
                    for c in 'qwertyuiopasdfghjklzxcvbnm':
                        y = first + c + second
                        if y in words:
                            if y in eq:
                                found = True
                            else:
                                nq.add(y)
                            tree[y].add(x) if rev else tree[x].add(y)
            bq, nq = nq, set()
            if len(bq) > len(eq):
                bq, eq, rev = eq, bq, not rev

        def bt(x):
            return [[x]] if x == endWord else [[x] + rest for y in tree[x] for rest in bt(y)]

        return bt(beginWord)

    def doit_bfs_bidirect(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: List[List[str]]
        """
        from collections import defaultdict

        beginset, endset, tree = set([beginWord]), set([endWord]), defaultdict(set)
        wl = set(wordList)

        if endWord not in wl:
            return []

        found, reverse = False, False
        while beginset and not found:

            wl -= beginset
            nextset = set()

            for w in beginset:

                for i in range(len(w)):
                    for c in 'abcdefghijklmnopqrstuvwxyz':
                        nw = w[:i] + c + w[i + 1:]
                        if nw in wl:
                            if nw in endset:
                                found = True
                            else:
                                nextset.add(nw)

                            if reverse:
                                tree[nw].add(w)
                            else:
                                tree[w].add(nw)

            beginset = nextset
            if len(beginset) > len(endset):
                beginset, endset = endset, beginset
                reverse = not reverse

        def build(x):
            if x == endWord:
                return [[x]]
            else:
                res = []
                for c in tree[x]:
                    for r in build(c):
                        res.append([x] + r)
                return res

        return build(beginWord)

if __name__ == '__main__':

    WordLadderII().doit_bfs_1("hit", "cog", ["hot","dot","dog","lot","log","cog"])

{'collections': 'collections', 'string': 'string', 'defaultdict': 'collections.defaultdict'}


"""Flux correlation"""
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stat
import math as m
from scipy.stats import linregress as regr
from pylab import *

MOLECULES = ['CN', 'HCN', 'CS']
DIST=436. #Ortiz-Leon 2017
L_sun = 3.86e26 #W
freq = [113490985000, 88631847000, 146969029000]
c = 299792458 # m/s
k = 1.38e-23  #Boltzmann constant [J/K]

rc('font', **{'family':'serif', 'serif':['Times New Roman']})
params = {'backend': 'pdf',
          #'axes.labelsize': 12,
          #'text.fontsize': 12,
          #'legend.fontsize': 12,
          #'xtick.labelsize': 7,
          #'ytick.labelsize': 7,
          # The comm. below determines whether you use LaTeX
          # for all text in matplotlib (you probably don't want
          # to turn this on, but may)
          'text.usetex': False,
          # four comm. below (math) determines what is used for math rendering
          'mathtext.rm': 'serif',
          'mathtext.it': 'serif:italic',
          'mathtext.bf': 'serif:bold',
          'mathtext.fontset': 'custom',
          #'figure.figsize': fig_size,
          'axes.unicode_minus': True}
matplotlib.rcParams.update(params)

conversion_factor = {3: 22, 2: 29, 1.3: 35, 0.8: 45}  #[mm]:[Jy/K] from http://www.iram.fr/GENERAL/calls/s14/s14.pdf?fbclid=IwAR3_XqJE1cvy86ppQbSpXS1xAJ4F2sUjevWGDx1Nr78-rdNkUIDksY7f3n8

def read_data(filename):
	file = open(filename,'r')
	data = file.readlines()
	file.close()

	return data

def write_data(end_filename, data, slope, intercept, pearson, stderr):
	file = open(end_filename,'w')
	for SMM, CN, HCN in data:
		file.write(f'{SMM:10.5} {CN:10.5} {HCN:10.5}\n')
	file.write(f'\n slope:{slope:10.5} intercept:{intercept:10.5} stderr:{stderr:10.5} pearson:{pearson:10.5}\n')
	file.close()

def create_flux_file(data, mol):
	fluxes = []
	for i in range(1,len(data)):
		line = data[i].split()
		previous_line = data[i-1].split()
		if mol == 0: #CN
			if line[1] == 'hcn10' and previous_line[1] == 'cn10':
				fluxes.append(float(previous_line[2])) # source CNflux
		if mol == 1: #HCN
			if line[1] == 'hcn10' and previous_line[1] == 'cn10':
				fluxes.append(float(line[2])) # source HCNflux
		if mol == 2: #CS
			if line[1] == 'hcn10' and previous_line[1] == 'cn10':
				fluxes.append(float(data[i+1].split()[2])) # source CSflux
	return fluxes

def plot_correlation(points, regresions, pearsons):
	fig = plt.figure(figsize = (15,15), dpi = 400)
	plt.tick_params(axis='y', which='both', right=False)
	fig.subplots_adjust(wspace=0)
	fig.subplots_adjust(hspace=0)

	ax1 = plt.subplot(3, 2, 1)
	# Set the tick labels font
	for label in (ax1.get_xticklabels() + ax1.get_yticklabels()):
	#    label.set_fontname('Arial')
   		label.set_fontsize(16)
	ax1.set_xlim([-1.0, 2.3])
	ax1.set_ylim([-6, -5.1])
	major_ticks_y = np.arange(-5.9, -5.1, 0.1)
	ax1.set_yticks(major_ticks_y)
	ax1.set_xticks([])
	plt.plot(points[0][0], points[0][1], 'k.', ms=7)
	Y = [elem*regresions[0][0]+regresions[0][1] for elem in points[0][0]]
	plt.plot(points[0][0], Y, 'k-', linewidth=0.8)

	ax2 = plt.subplot(3, 2, 2)
	for label in (ax2.get_xticklabels() + ax2.get_yticklabels()):
	#    label.set_fontname('Arial')
   		label.set_fontsize(16)
	ax2.set_xlim([1.0, 3.1])
	ax2.set_ylim([-6, -5.1])
	ax2.set_yticks([])
	ax2.set_xticks([])
	plt.plot(points[1][0], points[1][1], 'k.', ms=7)
	Y = [elem*regresions[1][0]+regresions[1][1] for elem in points[1][0]]
	plt.plot(points[1][0], Y, 'k-', linewidth=0.8)

	ax3 = plt.subplot(3, 2, 3)
	for label in (ax3.get_xticklabels() + ax3.get_yticklabels()):
	#    label.set_fontname('Arial')
   		label.set_fontsize(16)
	ax3.set_xlim([-1.0, 2.3])
	ax3.set_ylim([-6.1, -5.1])
	major_ticks_y = np.arange(-6, -5.1, 0.1)
	ax3.set_yticks(major_ticks_y)
	ax3.set_xticks([])
	plt.plot(points[2][0], points[2][1], 'k.', ms=7)
	Y = [elem*regresions[2][0]+regresions[2][1] for elem in points[2][0]]
	plt.plot(points[2][0], Y, 'k-', linewidth=0.8)

	ax4 = plt.subplot(3, 2, 4)
	for label in (ax4.get_xticklabels() + ax4.get_yticklabels()):
	#    label.set_fontname('Arial')
   		label.set_fontsize(16)
	ax4.set_xlim([1.0, 3.1])
	ax4.set_ylim([-6.1, -5.1])
	ax4.set_yticks([])
	ax4.set_xticks([])
	plt.plot(points[3][0], points[3][1], 'k.', ms=7)
	Y = [elem*regresions[3][0]+regresions[3][1] for elem in points[3][0]]
	plt.plot(points[3][0], Y, 'k-', linewidth=0.8)

	ax5 = plt.subplot(3, 2, 5)
	for label in (ax5.get_xticklabels() + ax5.get_yticklabels()):
	#    label.set_fontname('Arial')
   		label.set_fontsize(16)
	ax5.set_xlim([-1.0, 2.3])
	ax5.set_ylim([-5.8, -4.8])
	major_ticks_y = np.arange(-5.7, -4.8, 0.1)
	major_ticks_x = np.arange(-1, 2.2, 0.5)
	ax5.set_yticks(major_ticks_y)
	ax5.set_xticks(major_ticks_x)
	plt.plot(points[4][0], points[4][1], 'k.', ms=7)
	Y = [elem*regresions[4][0]+regresions[4][1] for elem in points[4][0]]
	plt.plot(points[4][0], Y, 'k-', linewidth=0.8)

	ax6 = plt.subplot(3, 2, 6)
	for label in (ax6.get_xticklabels() + ax6.get_yticklabels()):
	#    label.set_fontname('Arial')
   		label.set_fontsize(16)
	ax6.set_xlim([1.0, 3.1])
	ax6.set_ylim([-5.8, -4.8])
	ax6.set_yticks([])
	major_ticks_x = np.arange(1, 3.5, 0.5)
	ax6.set_xticks(major_ticks_x)
	plt.plot(points[5][0], points[5][1], 'k.', ms=7)
	Y = [elem*regresions[5][0]+regresions[5][1] for elem in points[5][0]]
	plt.plot(points[5][0], Y, 'k-', linewidth=0.8)

	ax1.set_ylabel(r"$L_{\mathrm{CN}}$ [L$_\odot$]", fontsize=20)
	ax3.set_ylabel(r"$L_{\mathrm{HCN}}$ [L$_\odot$]", fontsize=20)
	ax5.set_ylabel(r"$L_{\mathrm{CS}}$ [L$_\odot$]", fontsize=20)
	ax5.set_xlabel(r"$L_{\mathrm{bol}}$ [L$_\odot$]", fontsize=20)
	ax6.set_xlabel(r"$T_{\mathrm{bol}}$ [K]", fontsize=20)

	sources_list_Lbol = ['SMM8','SMM5','SMM2','SMM4','SMM12','SMM10','SMM3','SMM9','SMM6','SMM1']  #Lbol increasing
	sources_list_Tbol = ['SMM8','SMM2','SMM1','SMM3','SMM9','SMM4','SMM10','SMM12','SMM5','SMM6']  #Tbol increasing

	for i in range(len(sources_list_Lbol)):
		if sources_list_Lbol[i] in ['SMM1', 'SMM2', 'SMM3', 'SMM8', 'SMM9']:
			if sources_list_Lbol[i] == 'SMM3':
				ax1.text(points[0][0][i]+0.04, points[0][1][i]-0.03, sources_list_Lbol[i], fontsize=16, color='r')
				ax3.text(points[2][0][i]+0.04, points[2][1][i]-0.03, sources_list_Lbol[i], fontsize=16, color='r')
				ax5.text(points[4][0][i]+0.04, points[4][1][i]-0.03, sources_list_Lbol[i], fontsize=16, color='r')
			else:
				ax1.text(points[0][0][i]+0.02, points[0][1][i], sources_list_Lbol[i], fontsize=16, color='r')
				ax3.text(points[2][0][i]+0.02, points[2][1][i], sources_list_Lbol[i], fontsize=16, color='r')
				ax5.text(points[4][0][i]+0.02, points[4][1][i], sources_list_Lbol[i], fontsize=16, color='r')
		elif sources_list_Lbol[i] not in ['SMM1', 'SMM2', 'SMM3', 'SMM8', 'SMM9']:
			if sources_list_Lbol[i] == 'SMM4':
				ax1.text(points[0][0][i]-0.25, points[0][1][i]+0.02, sources_list_Lbol[i], fontsize=16, color='b')
				ax3.text(points[2][0][i]-0.25, points[2][1][i]+0.02, sources_list_Lbol[i], fontsize=16, color='b')
				ax5.text(points[4][0][i]-0.25, points[4][1][i]+0.02, sources_list_Lbol[i], fontsize=16, color='b')
			else:
				ax1.text(points[0][0][i]-0.15, points[0][1][i], sources_list_Lbol[i], fontsize=16, color='b')
				ax3.text(points[2][0][i]-0.15, points[2][1][i], sources_list_Lbol[i], fontsize=16, color='b')
				ax5.text(points[4][0][i]-0.15, points[4][1][i], sources_list_Lbol[i], fontsize=16, color='b')
	for i in range(len(sources_list_Tbol)):
		if sources_list_Tbol[i] in ['SMM1', 'SMM2', 'SMM3', 'SMM8', 'SMM9']:
			if sources_list_Tbol[i] == 'SMM3':
				ax2.text(points[1][0][i]+0.04, points[1][1][i]-0.01, sources_list_Tbol[i], fontsize=16, color='r')
				ax4.text(points[3][0][i]+0.04, points[3][1][i]-0.01, sources_list_Tbol[i], fontsize=16, color='r')
				ax6.text(points[5][0][i]+0.04, points[5][1][i]-0.01, sources_list_Tbol[i], fontsize=16, color='r')
			else:
				ax2.text(points[1][0][i]+0.02, points[1][1][i], sources_list_Tbol[i], fontsize=16, color='r')
				ax4.text(points[3][0][i]+0.02, points[3][1][i], sources_list_Tbol[i], fontsize=16, color='r')
				ax6.text(points[5][0][i]+0.02, points[5][1][i], sources_list_Tbol[i], fontsize=16, color='r')
		elif sources_list_Tbol[i] not in ['SMM1', 'SMM2', 'SMM3', 'SMM8', 'SMM9']:
			if sources_list_Tbol[i] == 'SMM4':
				ax2.text(points[1][0][i]-0.02, points[1][1][i]+0.02, sources_list_Tbol[i], fontsize=16, color='b')
				ax4.text(points[3][0][i]-0.02, points[3][1][i]+0.02, sources_list_Tbol[i], fontsize=16, color='b')
				ax6.text(points[5][0][i]-0.02, points[5][1][i]+0.02, sources_list_Tbol[i], fontsize=16, color='b')
			else:
				ax2.text(points[1][0][i]+0.02, points[1][1][i], sources_list_Tbol[i], fontsize=16, color='b')
				ax4.text(points[3][0][i]+0.02, points[3][1][i], sources_list_Tbol[i], fontsize=16, color='b')
				ax6.text(points[5][0][i]+0.02, points[5][1][i], sources_list_Tbol[i], fontsize=16, color='b')

	ax1.text(0.05, 0.05, 'r = '+ str(round(pearsons[0],2)) , transform=ax1.transAxes, fontsize=18, verticalalignment='bottom')
	ax2.text(0.05, 0.05, 'r = '+ str(round(pearsons[1],2)) , transform=ax2.transAxes, fontsize=18, verticalalignment='bottom')
	ax3.text(0.05, 0.05, 'r = '+ str(round(pearsons[2],2)) , transform=ax3.transAxes, fontsize=18, verticalalignment='bottom')
	ax4.text(0.05, 0.05, 'r = '+ str(round(pearsons[3],2)) , transform=ax4.transAxes, fontsize=18, verticalalignment='bottom')
	ax5.text(0.05, 0.05, 'r = '+ str(round(pearsons[4],2)) , transform=ax5.transAxes, fontsize=18, verticalalignment='bottom')
	ax6.text(0.05, 0.05, 'r = '+ str(round(pearsons[5],2)) , transform=ax6.transAxes, fontsize=18, verticalalignment='bottom')

	plt.savefig('Lbol_Tbol_correlations.eps', format='eps')
	plt.close()

def calculate_pearson(x, y):
	pearson = stat.pearsonr(x, y)
	#print(pearson)

	return pearson[0]

def fit_linear_regression(x, y):
	slope, intercept, r_value, p_value, stderr = stat.linregress(x,y)
	#print(slope, intercept, r_value, p_value, stderr)
	return slope, intercept, stderr

def sort_points(list_to_sort, other_list):
	if len(list_to_sort) != len(other_list):
		raise
	merged_list = [(list_to_sort[i], other_list[i]) for i in range(len(list_to_sort))]
	sorted_list = sorted(merged_list, key=lambda x: x[0])
	return [elem[0] for elem in sorted_list], [elem[1] for elem in sorted_list]

def calculate_Lbol_for_molecule(fluxes, mol, JytoK):
	Lbol_source = []
	for i in range(len(fluxes)):
		flux_Jy_kms = fluxes[i]*JytoK # 2k/lambda^2 * T_mb [Jy*km/s]
		flux_Jy_Hz = flux_Jy_kms/((c/1000.)/freq[mol])  # F [Jy*Hz] = F [Jy*km/s] / lambda[km]
		L_bol = (1e-26*flux_Jy_Hz*4.0*m.pi*(DIST*3.0857e16)**2)/L_sun
		#print(L_bol)
		Lbol_source.append(L_bol)

	return Lbol_source

def estimate_conversion_factor(freq):
	wavelength = c*1000/freq  #in mm
	mms = [elem for elem in conversion_factor.keys()]
	Jy_K = [elem for elem in conversion_factor.values()]
	a, b, r, p, stdev = regr(mms, Jy_K)
	y = a * wavelength + b

	return y

def make_log_list(old_list):
	new_list = []
	for elem in old_list:
		if elem != 0:
			new_list.append(m.log10(elem))
		else:
			new_list.append(elem)

	return new_list

def main():
	data = read_data('SMM_fluxes')

	Lbol_smm = [78.7, 4.1, 6.9, 4.4, 3.7, 43.1, 0.2, 10.3, 6.2, 5.7]
	Tbol_smm = [35, 31, 35, 77, 151, 532, 15, 35, 83, 97]

	points = []
	pearsons = []
	regresions = []

	for i in range(len(MOLECULES)):
		fluxes = create_flux_file(data, i)

		JytoK = estimate_conversion_factor(freq[i])
		Lbol_source = calculate_Lbol_for_molecule(fluxes, i, JytoK)

		Lbol, Lbol_source_1 = sort_points(Lbol_smm, Lbol_source)
		Lbol_log = make_log_list(Lbol)
		Lbol_source_log = make_log_list(Lbol_source_1)

		a, b, stderr = fit_linear_regression(Lbol_log, Lbol_source_log)
		pearson = calculate_pearson(Lbol_log, Lbol_source_log)

		points.append((Lbol_log, Lbol_source_log))
		pearsons.append(pearson)
		regresions.append((a, b))

		Tbol, Lbol_source_2 = sort_points(Tbol_smm, Lbol_source)
		Tbol_log = make_log_list(Tbol)
		Lbol_source_log = make_log_list(Lbol_source_2)

		a, b, stderr = fit_linear_regression(Tbol_log, Lbol_source_log)
		pearson = calculate_pearson(Tbol_log, Lbol_source_log)

		points.append((Tbol_log, Lbol_source_log))
		pearsons.append(pearson)
		regresions.append((a, b))
	plot_correlation(points, regresions, pearsons)

	#write_data('CN_Lbol_corr.txt', fluxes, a, b, pearson, stderr)
if __name__ == '__main__':
	main()


"""
Module for converting labelbox.com JSON exports to Pascal VOC 2012 format.
"""

import json
import logging
import os
from typing import Any, Dict
import io

from PIL import Image
import requests
from shapely import wkt
import cv2
import numpy as np

from lb.exceptions import UnknownFormatError
from lb.exporters.pascal_voc_writer import Writer as PascalWriter

LOGGER = logging.getLogger(__name__)

def from_json(images_input_dir, labeled_data, annotations_output_dir, images_output_dir,
              label_format='WKT'):
    """Convert Labelbox JSON export to Pascal VOC format.

    Args:
        labeled_data (str): File path to Labelbox JSON export of label data.
        annotations_output_dir (str): File path of directory to write Pascal VOC
            annotation files.
        images_output_dir (str): File path of directory to write images.
        label_format (str): Format of the labeled data.
            Valid options are: "WKT" and "XY", default is "WKT".
    """

    # make sure annotation output directory is valid
    try:
        annotations_output_dir = os.path.abspath(annotations_output_dir)
        assert os.path.isdir(annotations_output_dir)
    except AssertionError as exc:
        LOGGER.exception('Annotation output directory does not exist, please create it first.')
        raise exc

    # read labelbox JSON output
    with open(labeled_data, 'r') as file_handle:
        lines = file_handle.readlines()
        label_data = json.loads(lines[0])

    for data in label_data:
        try:
            write_label(
                images_input_dir,
                data['ID'],
                data['Labeled Data'],
                data['Label'],
                label_format,
                images_output_dir,
                annotations_output_dir)

        except requests.exceptions.MissingSchema as exc:
            LOGGER.warning(exc)
            continue
        except requests.exceptions.ConnectionError:
            LOGGER.warning('Failed to fetch image from %s, skipping', data['Labeled Data'])
            continue

def write_label(  # pylint: disable-msg=too-many-arguments
        images_input_dir: str, label_id: str, image_url: str, labels: Dict[str, Any], label_format: str,
        images_output_dir: str, annotations_output_dir: str):
    """Writes a single Pascal VOC formatted image and label pair to disk.

    Args:
        label_id: ID for the instance to write
        image_url: URL to download image file from
        labels: Labelbox formatted labels to use for generating annotation
        label_format: Format of the labeled data. Valid options are: "WKT" and
                      "XY", default is "WKT".
        annotations_output_dir: File path of directory to write Pascal VOC
                                annotation files.
        images_output_dir: File path of directory to write images.
    """
    #find image
    url_list = image_url.split("/")
    image_input_fqn = os.path.join(
        images_input_dir,
        '{image_dir}/{filename}'.format(image_dir=url_list[-2], filename=url_list[-1]))

    image = Image.open(image_input_fqn)

    image_fqn = os.path.join(
        images_output_dir,
        '{img_id}.{ext}'.format(img_id=label_id, ext=image.format.lower()))

    image.save(image_fqn, format=image.format)

    print(image_fqn)

    # resize the image
    width, height = 640, 640
    x_factor, y_factor, pad_top = resize_image(image_fqn, width, height)

    # generate image annotation in Pascal VOC
    xml_writer = PascalWriter(image_fqn, width, height)

    # remove classification labels (Skip, etc...)
    if not callable(getattr(labels, 'keys', None)):
        # skip if no categories (e.g. "Skip")
        return

    # convert label to Pascal VOC format
    for category_name, paths in labels.items():
        if label_format == 'WKT':
            xml_writer = _add_pascal_object_from_wkt(
                xml_writer, wkt_data=paths, label=category_name)
        elif label_format == 'XY':
            xml_writer = _add_pascal_object_from_xy(xml_writer, polygons=paths, label=category_name, x_factor=x_factor, y_factor=y_factor, pad_top=pad_top)
        else:
            exc = UnknownFormatError(label_format=label_format)
            logging.exception(exc.message)
            raise exc

    # write Pascal VOC xml annotation for image
    xml_writer.save(os.path.join(annotations_output_dir, '{}.xml'.format(label_id)))

def _add_pascal_object_from_wkt(xml_writer, wkt_data, label):
    polygons = []
    if isinstance(wkt_data, list):  # V3+
        polygons = map(lambda x: wkt.loads(x['geometry']), wkt_data)
    else:  # V2
        polygons = wkt.loads(wkt_data)

    for point in polygons:
        xy_coords = []
        for x_val, y_val in point.exterior.coords:
            xy_coords.extend([x_val, y_val])
        # remove last polygon if it is identical to first point
        if xy_coords[-2:] == xy_coords[:2]:
            xy_coords = xy_coords[:-2]
        xml_writer.add_object(name=label, xy_coords=xy_coords)
    return xml_writer

def _add_pascal_object_from_xy(xml_writer, polygons, label, x_factor, y_factor, pad_top):
    if not isinstance(polygons, list):
        LOGGER.warning('polygons is not [{geometry: [xy]}] nor [[xy]], skipping')
        return xml_writer
    for polygon in polygons:
        if 'geometry' in polygon:  # V3
            polygon = polygon['geometry']
        if not isinstance(polygon, list) \
                or not all(map(lambda p: 'x' in p and 'y' in p, polygon)):
            LOGGER.warning('Could not get an point list to construct polygon, skipping')
            return xml_writer

        xy_coords = []
        for point in polygon:
            xy_coords.extend([point['x']/x_factor, ((point['y']/y_factor)+pad_top)])
        xml_writer.add_object(name=label, xy_coords=xy_coords)
    return xml_writer

def resize_image(image_path, required_img_height, required_img_width):

        img = cv2.imread(image_path)

        height, width = img.shape[:2]

        aspect_ratio = float(width)/height

        scaled_height = required_img_height
        scaled_width = required_img_width

        # interpolation method
        if height > scaled_height or width > scaled_width:  # shrinking image
            interp = cv2.INTER_AREA
        else:  # stretching image
            interp = cv2.INTER_CUBIC

        # aspect ratio of image

        # compute scaling and pad sizing
        if aspect_ratio > 1:  # horizontal image
            new_width = scaled_width
            new_height = np.round(new_width/aspect_ratio).astype(int)
            pad_vert = (scaled_height-new_height)/2
            pad_top, pad_bot = np.floor(
                pad_vert).astype(int), np.ceil(pad_vert).astype(int)
            pad_left, pad_right = 0, 0
        elif aspect_ratio < 1:  # vertical image
            new_height = scaled_height
            new_width = np.round(new_height*aspect_ratio).astype(int)
            pad_horz = (scaled_width-new_width)/2
            pad_left, pad_right = np.floor(
                pad_horz).astype(int), np.ceil(pad_horz).astype(int)
            pad_top, pad_bot = 0, 0
        else:  # square image
            new_height, new_width = scaled_height, scaled_width
            pad_left, pad_right, pad_top, pad_bot = 0, 0, 0, 0

        # factors to scale bounding box values
        x_factor = float(width) / required_img_width
        y_factor = float(height) / (required_img_height - pad_bot - pad_top)

        # set pad color
        # color image but only one color provided
        if len(img.shape) is 3 and not isinstance(0, (list, tuple, np.ndarray)):
            padColor = [0]*3

        # scale and pad
        scaled_img = cv2.resize(img, (new_width, new_height), interpolation=interp)
        scaled_img = cv2.copyMakeBorder(
            scaled_img, pad_top, pad_bot, pad_left, pad_right, borderType=cv2.BORDER_CONSTANT, value=0)

        cv2.imwrite(image_path, scaled_img)
        LOGGER.info('Resized image at {}'.format(
            image_path))

        return x_factor, y_factor, pad_top


# use bh snapshot data from bh.py to get lagr.py for only BHs

import numpy as np
import scipy.spatial as sp

# KDTree method to find half value index
def find_half_index(a,fraction):
    points=np.vstack(fraction*a[-1])
    tree=sp.cKDTree(np.vstack(a))
    dis,index=tree.query(points)
    return index

fraction=np.array([0.001,0.003,0.005,0.01,0.03,0.05,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.95,0.99,1.0])

sf = open('bh_single.lst','r')
bf = open('bh_binary.lst','r')
mf = open('bh_merger.lst','r')

sd=sf.read()
sd=sd.splitlines()
bd=bf.read()
bd=bd.splitlines()
md=mf.read()
md=md.splitlines()

fout = open('lagr.bh.snap','a')
ib=0
im=0
for i in sd:
    time=i[10:]
    bflag = 'bh_binary.'+time in bd
    mflag = 'bh_merger.'+time in md

    ms,xs,ys,zs=np.loadtxt(i,usecols=(0,1,2,3),unpack=True)
    rs2 = xs*xs + ys*ys + zs*zs

    mb =  np.array([])
    rb2 = np.array([])

    if (bflag):
        m1,m2,xb,yb,zb=np.loadtxt('bh_binary.'+time,usecols=(0,1,2,3,4),unpack=True)
        mb=m1+m2
        rb2= xb*xb + yb*yb + zb*zb

    if (mflag):
        m1,m2,m3,xm,ym,zm=np.loadtxt('bh_merger.'+time,usecols=(0,1,2,3,4,5),unpack=True)
        mm= m1+m2+m3
        rm2= xm*xm + ym*ym + zm*zm
        rb2 = np.append(rb2,rm2)
        mb = np.append(mb,mm)

    r2=np.append(rs2,rb2)
    m=np.append(ms,mb)

    idall=r2.argsort()
    ids=rs2.argsort()
    idb=rb2.argsort()

    if (idall.size>1):
        r2=r2[idall]
        m=m[idall]
    mcum=m.cumsum()

    rindex=np.zeros(fraction.size)
    rlagr=np.zeros(fraction.size)
    mlagr=np.zeros(fraction.size)
    if(r2.size>fraction.size):
        rindex=np.array(find_half_index(mcum,fraction))
        rlagr=np.sqrt(r2[rindex])
        mlagr=mcum[rindex]/(rindex+1)

    if (ids.size>1):
        rs2=rs2[ids]
        ms=ms[ids]
    mscum=ms.cumsum()

    rsindex=np.zeros(fraction.size)
    rslagr=np.zeros(fraction.size)
    mslagr=np.zeros(fraction.size)
    if(rs2.size>fraction.size):
        rsindex=np.array(find_half_index(mscum,fraction))
        rslagr=np.sqrt(rs2[rsindex])
        mslagr=mscum[rsindex]/(rsindex+1)

    if (idb.size>1):
        rb2=rb2[idb]
        mb=mb[idb]
    mbcum=mb.cumsum()

    rbindex=np.zeros(fraction.size)
    rblagr=np.zeros(fraction.size)
    mblagr=np.zeros(fraction.size)
    if(rb2.size>fraction.size):
        rbindex=np.array(find_half_index(mbcum,fraction))
        rblagr=np.sqrt(rb2[rbindex])
        mblagr=mbcum[rbindex]/(rbindex+1)

    t=float(time)
    fout.write("%.8e " % t)
    for j in range(fraction.size):
        fout.write("%.8e " % rlagr[j])
    for j in range(fraction.size):
        fout.write("%.8e " % rslagr[j])
    for j in range(fraction.size):
        fout.write("%.8e " % rblagr[j])
    for j in range(fraction.size):
        fout.write("%.8e " % mlagr[j])
    for j in range(fraction.size):
        fout.write("%.8e " % mslagr[j])
    for j in range(fraction.size):
        fout.write("%.8e " % mblagr[j])
    for j in range(fraction.size):
        fout.write("%d " % (rindex[j]+1))
    for j in range(fraction.size):
        fout.write("%d " % (rsindex[j]+1))
    for j in range(fraction.size):
        fout.write("%d " % (rbindex[j]+1))
    fout.write("\n")

fout.close()


import sys
import infer
import pandas as pd
import numpy as np
import oss2
import odps as o
import os
import re
import cv2
import random
caffe_path = '/root/ssd-caffe/python/'
sys.path.insert(0, caffe_path)
import caffe
caffe.set_device(0)
caffe.set_mode_gpu()
from caffe.proto import caffe_pb2
from google.protobuf import text_format
import numpy as np
import cv2
import matplotlib.pyplot as plt
import time

auth = oss2.Auth('', '')
bucket = oss2.Bucket(auth, 'http://oss-cn-beijing.aliyuncs.com', '')

root_senet = '/root/caffemodel/senet/'
deploy_senet = root_senet + 'deploy.prototxt'
caffe_model_senet = root_senet + 'senet.caffemodel'
labels_filename = root_senet + 'labels.txt'
senet = caffe.Net(deploy_senet, caffe_model_senet, caffe.TEST)

root_googlenet = '/root/caffemodel/googlenet/'
deploy_googlenet = root_googlenet + 'deploy.prototxt'
caffe_model_googlenet = root_googlenet + 'googlenet.caffemodel'
googlenet = caffe.Net(deploy_googlenet, caffe_model_googlenet, caffe.TEST)

root_alexnet = '/root/caffemodel/alexnet/'
deploy_alexnet = root_alexnet + 'deploy.prototxt'
caffe_model_alexnet = root_alexnet + 'alexnet.caffemodel'
alexnet = caffe.Net(deploy_alexnet, caffe_model_alexnet, caffe.TEST)

def percentage(consumed_bytes, total_bytes):
    if total_bytes:
        rate = int(100 * (float(consumed_bytes) / float(total_bytes)))
        print('\r{0}% '.format(rate), end='')
        sys.stdout.flush()

def file_name(file_dir):
    L = []
    for root, dirs, files in os.walk(file_dir):
        for file in files:
            if os.path.splitext(file)[1] == '.jpg':
                L.append(os.path.join(root, file))
    return L

rootdir = '/root/clock_images/'
L = []
L = file_name(rootdir)

def list_shuffle_fecth(L, ratio=0.5, mode='youquhui_sample'):
    if mode == 'youquhui_sample':
        list_A = random.sample(L, int(ratio * len(L)))
        list_B = random.sample(L, int(ratio * len(L)))
    elif mode == 'wuquhui_sample':
        L = random.shuffle(L)
        list_A = L[0: int(ratio * len(L))-1]
        list_B = L[int(ratio * len(L)):,]
    else:
        pass
    return list_A, list_B

list_A, list_B = list_shuffle_fecth(L)

# f_a = open('/root/caffemodel/sample_val.txt', 'w')
#
# with open('/root/val_dataset.txt') as f:
#     data = f.readlines()
#     list_val = []
#     for k in range(len(data)):
#         l = data[k].split(' ')[0]
#         list_val.append(l)
#
#
# count = 0
# for file in list_val:
#     object_id = file.split('/')[-1]
#     ground_truth = file.split('/')[-2]
#     im = cv2.imread(file, 0)
#     im = cv2.resize(im, (225, 225))
#     tmp = np.zeros((225, 225, 1))
#     tmp[:, :, 0] = im
#     labels_alex, score_alex, labels_googlenet, score_googlenet, labels_senet, score_senet, labels_normalized, score_normalized \
#         = infer.infer_img(alexnet, googlenet, senet, tmp)
#
#     f_a.write(object_id + ',' + ground_truth + ',' + str(labels_alex) + ',' + str(score_alex) + ',' + str(labels_googlenet) + ',' + str(score_googlenet) + ',' + str(labels_senet) + ',' + str(score_senet) + ','+ str(labels_normalized)+ ',' + str(score_normalized) + '\n')
#     count = count + 1
#     print(count)
# f_a.close()

f_b = open('/root/caffemodel/sample_test.txt', 'w')

with open('/root/test_dataset.txt') as f:
    data = f.readlines()
    list_test = []
    for k in range(len(data)):
        l = data[k].split(' ')[0]
        list_test.append(l)

count = 0
for file in list_test:
    object_id = file.split('/')[-1]
    ground_truth = file.split('/')[-2]
    im = cv2.imread(file, 0)
    im = cv2.resize(im, (225, 225))
    tmp = np.zeros((225, 225, 1))
    tmp[:, :, 0] = im
    labels_alex, score_alex, labels_googlenet, score_googlenet, labels_senet, score_senet, labels_normalized, score_normalized \
        = infer.infer_img(alexnet, googlenet, senet, tmp)

    f_b.write(object_id + ',' + ground_truth + ',' + str(labels_alex) + ',' + str(score_alex) + ',' + str(labels_googlenet) + ',' + str(score_googlenet) + ',' + str(labels_senet) + ',' + str(score_senet) + ','+ str(labels_normalized)+ ',' + str(score_normalized) + '\n')
    count = count + 1
    print(count)
f_b.close()


'''pygame has been used for graphics
time is used for gameplay
random is used for generating deck
itertools is used for making combinations'''

import pygame
import os
import time
import random
import itertools

def showplayer():

    '''This function displays the cards present in the deck of the player.
    The cards are produced randomly. This function also displays the swap button'''
    for i in range(len(Lplayer)):
        gameDisplay.blit(pygame.transform.scale(Lplayer[i][0], (100, 150)), (Lplayer[i][1],0))
    font = pygame.font.Font('Pacifico.ttf', 28)
    text = font.render('Swap Cards', True, gray,red)
    gameDisplay.blit(text,(1050,0))

def showcomp():

    '''This function shows the back of cards present in the deck of the computer.
    These cards are also generated randomly'''

    for i in range(10):
        gameDisplay.blit(pygame.transform.scale(cback, (100, 150)), ((i)*100,600))

def showdeck():

    '''This functions displays the pile of cards present in deck.
    The cards are not visible unless you choose to pick one'''

    for i in range(len(Ldeck)):
        gameDisplay.blit(pygame.transform.scale(Ldeck[i][0], (100, 150)), (500,400))
    gameDisplay.blit(pygame.transform.scale(back, (100, 150)), (500,400))
    font = pygame.font.Font('Pacifico.ttf', 22)
    text = font.render('Deck', True, gray,red)
    gameDisplay.blit(text,(530,550))

def showavl():

    '''This available deck function contains and shows the crads that the players throw
    and are open to be chosen by the players till the next move'''

    gameDisplay.blit(pygame.transform.scale(empty, (100, 150)), (800,400))
    for i in range(len(Lavl)):
        gameDisplay.blit(pygame.transform.scale(Lavl[i][0], (100, 150)), (800,400))
    font = pygame.font.Font('Pacifico.ttf', 15)
    text = font.render('Available Cards', True, gray,red)
    gameDisplay.blit(text,(800,550))
def showchange():

    '''This function displays the card that you have put on stake for your next move'''

    gameDisplay.blit(pygame.transform.scale(empty, (100, 150)), (1000,400))
    for i in range(len(Lchange)):
        gameDisplay.blit(pygame.transform.scale(Lchange[i][0], (100, 150)), (1000,400))
    font = pygame.font.Font('Pacifico.ttf', 17)
    text = font.render('Current Card', True, gray,red)
    gameDisplay.blit(text,(1000,550))
def showchange1():

    '''This function shows the card picked up from deck'''

    gameDisplay.blit(pygame.transform.scale(empty, (100, 150)), (100,400))
    for i in range(len(Lchange1)):
        gameDisplay.blit(pygame.transform.scale(Lchange1[i][0], (100, 150)), (100,400))
    font = pygame.font.Font('Pacifico.ttf', 15)
    text = font.render('Card From Deck', True, gray,red)
    gameDisplay.blit(text,(100,550))
def clicked():

    '''This function identifies a click on the swap button and shows next below that'''

    font = pygame.font.Font('Pacifico.ttf', 15)
    text = font.render('Clicked', True, gray,red)
    gameDisplay.blit(text,(1100,50))
def rulefunc():

    '''This function prints the rules and regulations of the game'''

    font = pygame.font.Font('mainfont.otf', 25)
    text = font.render('This is the famous 10 card rummy in which you have to make 3 sets or runs(1 of 4 card and', True, gray,red)
    text1 = font.render('other of 3 cards. A set is a collection of cards with same rank.A run is a collection of', True, gray,red)
    text2 = font.render('consecutive ranked cards of same suite.', True, gray,red)
    font = pygame.font.Font('mainfont.otf', 20)
    text3 = font.render('This is a very user friendly interface. In this game you play against the computer.', True, gray)
    text4 = font.render('Whenever you want to make your turn, you have two options. 1) You can pick a card', True, gray)
    text5 = font.render('present in available deck. when clicked on available deck the card will move towards', True, gray)
    text6 = font.render('Desired card holder, in next move you can click on the card that you want to discard', True, gray)
    text7 = font.render('from your set of cards. This card will move in current card holder, after that you can', True, gray)
    text8 = font.render('click on the card from deck and it will be included in your deck. 2) You can choose', True, gray)
    text9 = font.render('the topmost card from deck, on clicking it will be displayed on the desired card', True, gray)
    text10 = font.render('holder.You will choose any card from your deck which will go in your current card.', True, gray)
    text11 = font.render('holder. Now if you want to exchange the card click on the card from deck and if you', True, gray)
    text12 = font.render('dont want to exchange click on your current card.', True, gray)

    gameDisplay.blit(text,(0,0))
    gameDisplay.blit(text1,(0,30))
    gameDisplay.blit(text2,(0,60))
    gameDisplay.blit(text3,(0,90))
    gameDisplay.blit(text4,(0,110))
    gameDisplay.blit(text5,(0,130))
    gameDisplay.blit(text6,(0,150))
    gameDisplay.blit(text7,(0,170))
    gameDisplay.blit(text8,(0,190))
    gameDisplay.blit(text9,(0,210))
    gameDisplay.blit(text10,(0,230))
    gameDisplay.blit(text11,(0,250))
    gameDisplay.blit(text12,(0,270))

    gameDisplay.blit(pygame.transform.scale(sc1, (300, 200)), (900,100))
    gameDisplay.blit(pygame.transform.scale(sc2, (300, 200)), (0,350))
    gameDisplay.blit(pygame.transform.scale(sc3, (300, 200)), (320,350))
    gameDisplay.blit(pygame.transform.scale(sc4, (300, 200)), (640,350))
    gameDisplay.blit(pygame.transform.scale(sc5, (300, 200)), (960,350))
    gameDisplay.blit(pygame.transform.scale(sc6, (300, 200)), (0,560))

    text1 = font.render('You also have the option to swap your card. This can be achieved by clicking on swap', True, gray)
    text2 = font.render('the card button and then clicking the two cards from your deck which you want to', True, gray)
    text3 = font.render(' exchange.', True, gray)
    text4 = font.render('Alert!!You have to keep your deck in the order of', True, gray)
    text5 = font.render('4 3 3 to be considered for evaluation', True, gray)
    text6 = font.render('Alert!!Do not long press', True, gray)
    font = pygame.font.Font('mainfont.otf', 40)
    text7=font.render('Click Anywhere to Start',True,gray)

    gameDisplay.blit(text1,(310,560))
    gameDisplay.blit(text2,(310,580))
    gameDisplay.blit(text3,(310,600))
    gameDisplay.blit(text4,(310,620))
    gameDisplay.blit(text5,(310,640))
    gameDisplay.blit(text6,(310,660))
    gameDisplay.blit(text7,(500,680))

def checkPlayer():

    '''This function checks the win of the player. It accepts innput of
    cards in the form of 4 3 3 i.e. a set or run of 4 cards first and then
    the other ones, in no specified order'''

    count=0
    c=0
    L1=LplayerD[:4]+[]
    L2=LplayerD[4:7]+[]
    L3=LplayerD[7:]+[]
    if (LplayerD[0][0]==LplayerD[1][0]==LplayerD[2][0]==LplayerD[3][0]):
       count+=1
    else:
        c=0
        L1t=L1+[]
        L1=[]
        for i in L1t:
           L1.append([int(i[0]),i[1]])
        i=0
        L1.sort()
        if (LplayerD[0][1]==LplayerD[1][1]==LplayerD[2][1]==LplayerD[3][1]):
           while(i<3):
              if(int(L1[i+1][0])==int(L1[i][0])+1):
                c+=1
              i+=1
           if(c==3):
              count+=1
    if(LplayerD[4][0]==LplayerD[5][0]==LplayerD[6][0]):
        count+=1
    else:
        c=0
        L2t=L2+[]
        L2=[]
        for i in L2t:
           L2.append([int(i[0]),i[1]])
        L2.sort()
        i=0
        if (LplayerD[4][1]==LplayerD[5][1]==LplayerD[6][1]):
           while(i<2):
              if(int(L2[i+1][0])==int(L2[i][0])+1):

                c+=1
              i+=1
           print(L2)
           if(c==2):
              count+=1
              print("1")
    if(LplayerD[7][0]==LplayerD[8][0]==LplayerD[9][0]):
       count+=1
    else:

        c=0
        L3t=L3+[]
        L3=[]
        for i in L3t:
           L3.append([int(i[0]),i[1]])
        L3.sort()
        i=0
        if(LplayerD[7][1]==LplayerD[8][1]==LplayerD[9][1]):
           while(i<2):
              if(int(L3[i+1][0])==int(L3[i][0])+1):
                c+=1
              i+=1
           if(c==2):
             count+=1
    if(count==3):
       win()

def win():

       gameDisplay.blit(pygame.transform.scale(wini, (1000, 350)), (0,0))
       font = pygame.font.Font('Pacifico.ttf', 44)
       gameDisplay.blit(text,(450,650))
def lost():

       gameDisplay.blit(pygame.transform.scale(losei, (1000, 350)), (0,0))
       font = pygame.font.Font('Pacifico.ttf', 44)
       gameDisplay.blit(text,(450,650))
'''For generating the deck and cards for each player'''
Lsuite=['C','D','H','S']
Lrank=['1','2','3','4','5','6','7','8','9','10','11','12','13']
L= list(itertools.product(Lrank,Lsuite))
random.shuffle(L)
pygame.init()
display_width = 1200
display_height = 800
gameDisplay = pygame.display.set_mode((display_width,display_height))
white = (255,255,255)
red=(201, 10, 20)
gray=(207, 167, 167)
clock = pygame.time.Clock()
x = 0
y = 0
playgame=True
mouse_x,mouse_y,mouse_x1,mouse_y1=0,0,0,0

'''Images used have been loaded here'''

Limg=[]
background=pygame.image.load('background.jpg')
empty=pygame.image.load('capture.png')
start=pygame.image.load('start.jpg')
sc1=pygame.image.load('s1.png')
sc2=pygame.image.load('s2.png')
sc3=pygame.image.load('s3.png')
sc4=pygame.image.load('s4.png')
sc5=pygame.image.load('s5.png')
sc6=pygame.image.load('s6.png')
for i in range(52):
    Limg.append([pygame.image.load(L[i][0]+L[i][1]+".png"),x])
    x+=100
    if(x>=1000):
       x=0
back=pygame.image.load("gray_back.png")
cback=pygame.image.load("red_back.png")
wini=pygame.image.load("win.jpg")
losei=pygame.image.load("lost.jpg")
'''All the variables used in gameplay are declared below.
For maintaining the cards of the deck, we are simultaneously'''

change=0
var=[[],[]]
temp1,temp2=None ,None
Lplayer=Limg[:10]+[]
LplayerD=L[:10]+[]
Lcomp=Limg[10:20]+[]
LcompD=L[10:20]+[]
Lcompt=LcompD+[]
LcompD=[]
for i in Lcompt:
   LcompD.append([i[0],i[1]])
print(LcompD)
Ldeck=Limg[20:]+[]
LdeckD=L[20:]+[]
Lavl=[]
LavlD=[]
Lchange=[]
LchangeD=[]
Lchange1=[]
Lchange1D=[]
play=False
swap=False
swap1=False
ch=False
chDeck=False
ch1=False
ch2=False
rules=False
won=False
draw=False
lose=False
while playgame:
    mouse_x, mouse_y = None, None
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            playgame = False
    gameDisplay.blit(pygame.transform.scale(background, (1200, 800)), (0,0))
    if play==False:
       gameDisplay.blit(pygame.transform.scale(start, (1200, 600)), (0,0))
       font = pygame.font.Font('Pacifico.ttf', 44)
       text = font.render('Start Playing!', True, gray,red)
       gameDisplay.blit(text,(450,650))
       if event.type == pygame.MOUSEBUTTONUP:
          play=True
          rules=True
          time.sleep(0.5)
    if rules==True:
       rulefunc()
       if pygame.mouse.get_pressed()[0]:
          play=True
          rules=False
    if win==True:
       win()
       if pygame.mouse.get_pressed()[0]:
          exit()
    if lose==True:
       lost()
       if pygame.mouse.get_pressed()[0]:
          exit()
    if draw==True:
       draw()
       if pygame.mouse.get_pressed()[0]:
          exit()
    if play==True and rules==False and won==False and lose==False:
        showplayer()
        showcomp()
        showdeck()
        showavl()
        showchange()
        showchange1()
        if ch2==True:
           a=Lcomp[5]
           d=LcompD[5]
           Lcomp.remove(Lcomp[5])
           LcompD.remove(LcompD[5])
           c=Lavl[len(Lavl)-1]
           b=LavlD[len(LavlD)-1]
           Lavl.remove(Lavl[len(Lavl)-1])
           LavlD.remove(LavlD[len(LavlD)-1])
           Lavl.append(a)
           LavlD.append(d)
           Lcomp.insert(4,c)
           LcompD.insert(4,b)
           ch2=False
           print(LcompD)
           time.sleep(0.2)
        if pygame.mouse.get_pressed()[0] and ch==False :
           mouse_x, mouse_y = pygame.mouse.get_pos()
           if len(Ldeck)==0:
             exit()
           if(mouse_x>500 and mouse_y>400 and mouse_x<600 and mouse_y<550 and ch2==False):
              Lchange1.append(Ldeck[len(Ldeck)-1])
              Lchange1D.append(LdeckD[len(LdeckD)-1])
              Ldeck.remove(Ldeck[len(Ldeck)-1])
              LdeckD.remove(LdeckD[len(LdeckD)-1])
              #time.sleep(0.5)
              ch=True
           elif(mouse_x>800 and mouse_y>400 and mouse_x<900 and mouse_y<550 and len(Lavl)>0 and ch2==False):
              Lchange1.append(Lavl[len(Lavl)-1])
              Lchange1D.append(LavlD[len(LavlD)-1])
              Lavl.remove(Lavl[len(Lavl)-1])
              LavlD.remove(LavlD[len(LavlD)-1])
              time.sleep(0.5)
              ch=True
           elif(mouse_x>1050 and  mouse_y<50 ):
              swap=True
        if swap==True:
           clicked()
        if(pygame.mouse.get_pressed()[0] and swap1==True and ch==False and ch2==False):
            mouse_x4, mouse_y4 = pygame.mouse.get_pos()
            if(mouse_y4<=150):
               i=0
               while i<len(Lplayer):
                 if(mouse_x4-100<=(int(Lplayer[i][1]))):
                    print(Lplayer[i][1],Lplayer[tempvar][1])
                    Lplayer[i][1],Lplayer[tempvar][1]=Lplayer[tempvar][1],Lplayer[i][1]

                    LplayerD[i],LplayerD[tempvar]=LplayerD[tempvar],LplayerD[i]
                    Lplayer.sort(key = lambda x: x[1])
                    swap1=False
                    swap=False
                    break
                 i+=1
        if(pygame.mouse.get_pressed()[0] and swap==True):
            mouse_x, mouse_y = pygame.mouse.get_pos()
            if(mouse_y<=150):
               i=0
               while i<len(Lplayer):
                 if(mouse_x-100<=(int(Lplayer[i][1]))):
                    tempvar=i
                    print(LplayerD)
                    ch1=True
                    swap1=True
                    break
                 i+=1
            time.sleep(0.5)
        if pygame.mouse.get_pressed()[0] and ch==True and swap==False and ch2==False:
           time.sleep(0.01)
           mouse_x1, mouse_y1 = pygame.mouse.get_pos()
           if(mouse_y1<=150):
               i=0
               while i<len(Lplayer):
                 if(mouse_x1-100<=(int(Lplayer[i][1]))):
                    Lchange.append(Lplayer[i])
                    LchangeD.append(LplayerD[i])
                    val=Lplayer[i][1]
                    var=(i,val)
                    Lplayer.remove(Lplayer[i])
                    LplayerD.remove(LplayerD[i])
                    ch1=True
                    break
                 i+=1
           time.sleep(0.5)
           print(LplayerD)
        if pygame.mouse.get_pressed()[0] and ch1==True and swap==False and ch2==False:
             mouse_x2, mouse_y2 = pygame.mouse.get_pos()
             if mouse_x2>1000 and mouse_x2<1100 and mouse_y2>400 and mouse_y2<550:
                Lplayer.insert(var[0],[Lchange[len(Lchange)-1][0],var[1]])
                LplayerD.insert(var[0],LchangeD[len(LchangeD)-1])
                Lchange.remove(Lchange[len(Lchange)-1])
                LchangeD.remove(LchangeD[len(LchangeD)-1])
                Lavl.append(Lchange1[len(Lchange1)-1])
                LavlD.append(Lchange1D[len(Lchange1)-1])
                Lchange1.remove(Lchange1[len(Lchange1)-1])
                Lchange1D.remove(Lchange1D[len(Lchange1D)-1])
                ch1=False
                ch=False
                ch2=True

             elif mouse_x2>100 and mouse_x2<200 and mouse_y2>400 and mouse_y2<550:
                Lplayer.insert(var[0],[Lchange1[len(Lchange1)-1][0],var[1]])
                LplayerD.insert(var[0],Lchange1D[len(Lchange1D)-1])
                Lchange1.remove(Lchange1[len(Lchange1)-1])
                Lchange1D.remove(Lchange1D[len(Lchange1D)-1])
                if(len(Lchange)>0):
                   Lavl.append(Lchange[len(Lchange)-1])
                   LavlD.append(LchangeD[len(Lchange)-1])
                   Lchange.remove(Lchange[len(Lchange)-1])
                   LchangeD.remove(LchangeD[len(LchangeD)-1])
                ch1=False
                ch=False
                ch2=True

        '''When the deck of the players are complete, then they are gone for auto evaluation'''

        if(len(LplayerD)==10):
           checkPlayer()
    pygame.display.update()
    clock.tick(30)
pygame.quit()
quit()


import argparse
from misc.helper2 import Helper2
from misc.helper2 import get_script_name_from_python_file
from misc.utils import say
from githubgateway import GithubAPIGateway
import sys
import pdb

def run():
  parser = argparse.ArgumentParser(
    prog = get_script_name_from_python_file(__file__),
    description="Adds or removes a label from the current branch's pull request"
  )

  parser.add_argument("-q", "--quiet", action="store_true", help="Don't output anything")
  parser.add_argument("-r", "--remove", action="store_true", help="Remove labels from PR")
  parser.add_argument("-n", "--pr-number", help="PR number")
  parser.add_argument("labels", nargs='+')
  label_pr(parser.parse_args())

def label_pr(args):
  h2 = Helper2()
  api = GithubAPIGateway(*h2.owner_and_repo(), token=Helper2.get_var('GITHUB_TOKEN'))
  pr_number = None

  if args.pr_number is None:
    pr = api.get_pr_from_branch(h2.current_branch())

    if pr is None:
      if not args.quiet:
        say("No PR on this branch")
      sys.exit(0)
    else:
      pr_number = pr['number']
  else:
    pr_number = args.pr_number

  if args.remove:
    for label in args.labels:
      res = api.remove_label_from_issue(pr_number, label)
  else:
    res = api.add_labels_to_issue(pr_number, args.labels, force_label_creation=True)

  return True

if __name__ == "__main__":
  run()


from odoo import models, fields, api, _
from odoo.exceptions import UserError, Warning, ValidationError
from datetime import datetime, timedelta, date
import time
from pytz import timezone

class NewModule(models.Model):
    _inherit = 'hr.employee'

    evaluation_method = fields.Selection(string="Evaluation Method", selection=[('dm', 'Direct Manager'), ('average', 'Average'),('pm','Parent Manager') ], required=False, )

    # @api.model
    # def name_search(self, name='', args=None, operator='ilike', limit=100):
    #     args = args or []
    #     domain_name = ['|', ('name', 'ilike', name), ('pin', 'ilike', name)]
    #     recs = self.search(domain_name + args, limit=limit)
    #     return recs.name_get()

class NewModule(models.Model):
    _inherit = 'hr.job'

    kpi_ids = fields.One2many(comodel_name="kpi.kpi", inverse_name="interval_employee", )
    state = fields.Selection(readonly=False)

    # @api.constrains('kpi_ids')
    # def get_hours_custom(self):
    #     total = 0.0
    #     for rec in self.kpi_ids:
    #         print ('************************************************')
    #         total += rec.weight
    #     print ('ttttttttttttttttt', total)
    #     if total > 1:
    #         raise UserError(_('weight % Must be in 100%'))

class KPIEMPLOYEE(models.Model):
    _name = 'kpi.kpi'

    name = fields.Char(string="KPI", required=False, )
    weight = fields.Float(string="weight %", required=False, )
    active_kpi = fields.Boolean('Active', default=False, )

    kra_kpi = fields.Char(string="KRA", required=False, )

    interval_employee = fields.Many2one(comodel_name="hr.job", string="Job Postion")

    state = fields.Selection([
        ('draft', 'New'), ('cancel', 'Cancelled'),
        ('review','Reviewing'),
        ('waiting', 'Waiting Activation'),
        ('activated', 'Activated')], string='Status',
        copy=False, default='draft', index=True, readonly=True,
        help="* New: New KPI"
             "* Waiting Activation: KPI Waiting HR Activation"
             "* Activated: KPI Activated"
             "* Cancelled: KPI Cancelled")

    def rest_kpi(self):
        self.active_kpi = False
        self.state = 'draft'

    def submit_kpi(self):
        self.state = 'waiting'

    def review_kpi(self):
        self.active_kpi = False
        self.state = 'review'

    def activate_kpi(self):
        self.active_kpi = True
        self.state = 'activated'

    def cancel_kpi(self):
        self.active_kpi = False
        self.state = 'cancel'

    @api.onchange('name', 'weight', 'kra_kpi', 'interval_employee')
    def _onchange_active_kpi(self):
        if self.active_kpi:
            self.active_kpi = False
            self.state = 'draft'

    # @api.onchange('name')
    # def tags_get(self):
    #     categ_ids = []
    #     employee_rec = self.env['hr.jop'].search([])
    #
    #     for emp in employee_rec:
    #         if emp == self.env.user:
    #             print ('1111111111111111111111111111111111111111111111111')
    #             categ_ids.append(emp.id)
    #     print ('+++++++++++++++++', categ_ids)
    #     return {
    #         'domain': {'interval_employee': [('id', 'in', categ_ids)]}
    #     }

    # @api.constrains('weight')
    # def get_kpi_employee(self):
    #     total = 0.0
    #     kpi_rec = self.env['kpi.kpi'].search([])
    #     for rec in kpi_rec:
    #         total += rec.weight
    #     print ('++++++++++++++++', total)
    #     if total > 1:
    #         raise UserError(_('total weight for certain Employee  must = 100%'))

    # @api.onchange('active_kpi')
    # def kpi_manger_check_active(self):
    #     manger_hr = self.env.user.has_group('surgi_evaluation.kpi_manger_groups_employee')
    #
    #     if not manger_hr:
    #         if self.name or self.weight or self.interval_employee:
    #             self.active_kpi = False

    ### Notice (1) ####
    # 1- weight Field need to be percentage filed
    # 3- view located in menu called ( KPI ) under Evaluation Menu for members in (KPI Manager Group)
    # 4- KPI Manager Group) see or edit kpi for his subordinates only
    # 5- KPI Manager Group) can make new Kpi for his subordinates only by limit employee in interval_employee on his subordinates only
    # 6- total weight Field for certain (interval_employee)  must = 100% (api.onchange for interval_employee) and with save
    # 7- any changes in KPI change active field to False (if not hr group )
    # 8- view for hr team as it's in employee form but add active field on it , total for active record only and must be 100%
    ### Notice (1) end ###

class NewModule(models.Model):
    _name = 'competencies.ratio'

    ### Notice (2) start ###
    core_ratio = fields.Float(string="Core Competencies Ratio", required=False, tracking=True, )
    function_ratio = fields.Float(string="Function Competencies Ratio", required=False,
                                  tracking=True, )  # defult value = 1
    kpi_ratio = fields.Float(string="KPI Competencies Ratio", required=False, tracking=True, )  # defult value = 1

    ### Notice (2) ####
    # 1- above Field need to be percentage filed
    # 3- view located in menu called ( Competencies Ratios ) under configuration menu under Evaluation Menu for HR team only
    ### Notice (2) end ###

class EvaluationEvaluation(models.Model):
    _name = 'evaluation.evaluation'

    # Notice every manager see evaluations for his subordinate only ##
    name = fields.Char(string="Evaluation", required=True, )
    # Notice we can enter registration_number or employee_id to get employee info ##
    # registration_number = fields.Char('Registration Number of the Employee',related='employee_id.registration_number', copy=False)
    employee_id = fields.Many2one(comodel_name="hr.employee", string="Employee", required=True, )
    department_id = fields.Many2one(comodel_name="hr.department", related='employee_id.department_id', readonly=True,
                                    store=True)
    employee_parent_id = fields.Many2one(comodel_name="hr.employee", related='employee_id.parent_id', readonly=True,
                                         store=True)
    jop_ids = fields.Many2one(comodel_name="hr.job", string="Job Postion", related='employee_id.job_id')

    # Notice Manager cant see inactive evaluation #
    active_evaluation = fields.Boolean('Active', default=True, tracking=True, )

    # Notice Manager cant edit or submit or change evaluation out of the below dates & duration #
    date_start = fields.Date('Start Date', required=True, )
    date_end = fields.Date('End Date')
    duration = fields.Float('Duration', store=True, readonly=True)  # compute='_compute_duration',
    check_read = fields.Boolean(string="Publish for Employee", default=False)
    check_esa = fields.Boolean(string="Employee Self Assessment Evaluated", default=False)
    check_direct_manager = fields.Boolean(string="Direct Manager Evaluated", default=False)
    check_indirect_manager = fields.Boolean(string="IN-Direct Manager Evaluated", default=False)

    is_evalualtion = fields.Boolean(string="Get", defaut=False)

    # Notice get all question in core.competencies which active only # HR ONLY
    core_competencies = fields.One2many(comodel_name="core2.competencies2", inverse_name="interval_core", )
    # Notice get all question in function.competencies which active only #  HR ONLY
    function_comp = fields.One2many(comodel_name="function2.competencies2", inverse_name="interval_function", )
    # Notice get all question in kpi.competencies for the mention employee which active only #
    employee_kpi = fields.One2many(comodel_name="kpi.competencies", inverse_name="interval_kpi", )

    total_competencies = fields.Float(string="Total Core", compute='get_total_core_competencies', store=True)
    total_function_comp = fields.Float(string="Total Function", required=False, compute='get_total_function_comp',
                                       store=True)
    total_employee_kpi = fields.Float(string="Total KPI", required=False, compute='get_total_total_employee_kpi',
                                      store=True)
    total_totals = fields.Float(string="Total", compute='get_total_total', store=True)
    state = fields.Selection(string="", selection=[('draft', 'Draft'), ('esa', 'Self Assessment'),('direct_manager', 'Direct Manager'),('indirect_manager', 'IN-Direct Manager'),('done', 'Done'), ], required=False, )

    check_eval = fields.Boolean(string="Check Evaluation", default=False)

    accrual_date = fields.Date('Accrual Date', required=False)

    # evaluate_by_parent = fields.Boolean(string="Evaluate By Parent Manager", )
    # evaluate_by_parent_indirect = fields.Boolean(string="Evaluate By Parent Indirect Manager", )
    #
    # parent_managager = fields.Many2one(comodel_name="hr.employee", related='employee_parent_id.parent_id',
    #                                    string="Parent Manager", store=True)

    indirect_manager_id = fields.Many2one(comodel_name="hr.employee",related='employee_id.in_direct_parent_id' ,string="Indirect Manager",store=True)

    state_quarter = fields.Selection(string="Quarter",
                                     selection=[('q1', 'Q1'), ('q2', 'Q2'), ('q3', 'Q3'), ('q4', 'Q4')])#, readonly=True
    month = fields.Selection([('January', 'January'), ('February', 'February'), ('March', 'March'), ('April', 'April'),
                              ('May', 'May'), ('June', 'June'), ('July', 'July'), ('August', 'August'),
                              ('September', 'September'), ('October', 'October'), ('November', 'November'),
                              ('December', 'December'), ], string='Month')#, readonly=True

    evaluation_method = fields.Selection(string="Evaluation Method", selection=[('dm', 'Direct Manager'), ('average', 'Average'),('pm','Parent Manager') ], required=False, )

    employee_full_name = fields.Char(string="Employee Full Name",related='employee_id.full_employee_name')
    registration_number = fields.Char(string="Registration Number of the Employee",related='employee_id.registration_number')
    emp_image = fields.Binary(related='employee_id.image_1920')

    employee_parent_manager= fields.Many2one(comodel_name="hr.employee", string="Employee Parent",
                                             compute='get_parent_employee',store=True
                                             )

    @api.depends('employee_id')
    def get_parent_employee(self):
        self.employee_parent_manager=False
        for rec in self:
            if rec.employee_id.parent_id:
                rec.employee_parent_manager=rec.employee_id.parent_id.parent_id.id

    @api.onchange('employee_id')
    def _compute_evaluation_method(self):
        self.evaluation_method=self.employee_id.evaluation_method

    # is_xx = fields.Boolean(string="", compute='_compute_indirect_manager' )

    # @api.depends('evaluate_by_parent_indirect')
    # def _compute_indirect_manager(self):
    #     print("sssssssssssssssssssssssssssssssssssssssssssssss")
    #     self.is_xx=True
    #     # if self.evaluate_by_parent_indirect==True:
    #     #     print("wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww")
    #     #     for rec in self.core_competencies:
    #     #         rec.is_indirect=True

    @api.onchange('date_start')
    def _compute_month_quarter(self):
        if self.date_start:
            month_name = str(datetime.strptime(str(self.date_start), '%Y-%m-%d').date().strftime('%B'))
            self.month = month_name
            if month_name in ['January', 'February', 'March']:
                self.state_quarter = 'q1'
            if month_name in ['April', 'May', 'June']:
                self.state_quarter = 'q2'
            if month_name in ['July', 'August', 'September']:
                self.state_quarter = 'q3'
            if month_name in ['October', 'November', 'December']:
                self.state_quarter = 'q4'

    #######################################

    def write(self, values):

        # values['is_evalualtion'] = True
        return super(EvaluationEvaluation, self).write(values)

    @api.onchange('name')
    def get_lines_cor(self):

        lines = [(5, 0, 0), ]
        lines2 = [(5, 0, 0), ]

        for rec in self.env['core.competencies'].search([]):

            if rec.active_core == True:
                lines.append((0, 0, {
                    'name': rec.name,
                    'kpi_weight': rec.kpi_weight,
                    'state_result': rec.state_result,
                    # 'state_result': "expectation",
                }))

        for rec in self.env['function.competencies'].search([]):
            if rec.active_function == True:
                lines2.append((0, 0, {
                    'name': rec.name,
                    'kpi_weight': rec.kpi_weight,
                    'state_result': rec.state_result,
                    # 'state_result': "expectation",
                }))
        self.update({'core_competencies': lines, 'function_comp': lines2})
        # self.update({'function_comp': lines2})

        # list_lines=[]
        # for rec in self.env['core.competencies'].search([('active_core','=','True')]):
        #     list_lines.append(rec.id)
        # print (list_lines,'----------------------------------')
        # self.write({'core_competencies': list_lines })
        #
        # list_lines2 = []
        # for rec in self.env['function.competencies'].search([('active_function', '=', 'True')]):
        #     list_lines2.append(rec.id)
        # print (list_lines, '----------------------------------')
        # self.write({'function_comp': list_lines2})
        #

    def submit_core(self):
        total = 0.0
        # total2 = 0.0
        # total3 = 0.0
        for rec in self.function_comp:
            total += rec.kpi_weight
        if total != 1:
            raise UserError(_('KPI Function weight  % Must be in 100%'))

        # for rec in self.core_competencies:
        #     total2 += rec.kpi_weight
        # if total2 != 1:
        #     raise UserError(_('KPI Competencies weight % Must be in 100%'))

        # for rec in self.employee_kpi:
        #     total3 += rec.kpi_weight
        # if total3 != 1:
        #     raise UserError(_('KPI Employee weight % Must be in 100%'))

        else:
            self.state = 'done'
            self.check_read = True

    def submit_esa(self):
        self.state = 'esa'
        self.check_esa = True

    def submit_direct_manager(self):
        self.state = 'direct_manager'
        self.check_direct_manager = True

    def submit_indirect_manager(self):
        self.state = 'indirect_manager'
        self.check_indirect_manager = True

    @api.constrains('function_comp')  # ,'core_competencies','employee_kpi'
    def submit_core_weight(self):
        total = 0.0
        # total2=0.0
        # total3=0.0
        for rec in self.function_comp:
            total += rec.kpi_weight
        if total != 1:
            raise UserError(_('KPI Function weight  % Must be in 100%'))

        # for rec in self.core_competencies:
        #     total2 += rec.kpi_weight
        # if total2 != 1:
        #     raise UserError(_('KPI Competencies weight % Must be in 100%'))
        #
        # for rec in self.employee_kpi:
        #     total3 += rec.kpi_weight
        # if total3 != 1:
        #     raise UserError(_('KPI Employee weight % Must be in 100%'))

    ####################################
    @api.onchange('name')
    def tags_get(self):
        categ_ids = []
        employee_rec = self.env['hr.employee'].search([])

        for emp in employee_rec:
            if emp.parent_id.user_id == self.env.user:

                categ_ids.append(emp.id)
        return {
            'domain': {'employee_id': [('id', 'in', categ_ids)]}
        }

    #######################################################
    @api.onchange('date_start', 'date_end')
    def _compute_duration_days(self):

        if self.date_start and self.date_end:
            date_start = datetime.strptime(str(self.date_start), "%Y-%m-%d").date()
            date_end = datetime.strptime(str(self.date_end), "%Y-%m-%d").date()
            print(date_start, date_end, '+++++++++++++++')
            self.duration = float(str((date_end - date_start).days))

    def _compute_duration(self):

        today_dat = date.today()
        # print ('salah000000000000000000000000000000000000000000000salah', today_dat)

        for rec in self.search([]):
            if rec.date_end:
                date_end = datetime.strptime(str(rec.date_end), "%Y-%m-%d").date()
                today_date = datetime.strptime(str(today_dat), "%Y-%m-%d").date()

            if today_date > date_end:
                rec.check_read = True

    @api.depends('total_competencies', 'total_function_comp', 'total_employee_kpi', 'total_totals', 'total_totals')
    def get_total_total(self):
        ratio = self.env['competencies.ratio'].search([], order='id desc', limit=1)
        for rec in self:
            # rec.total_totals = (rec.total_competencies + rec.total_function_comp + rec.total_employee_kpi) / 3
            # Notice equation we need
            rec.total_totals = ((rec.total_competencies * ratio.core_ratio) + (
                        rec.total_function_comp * ratio.function_ratio) + (rec.total_employee_kpi * ratio.kpi_ratio))

    @api.depends('core_competencies', 'total_competencies')
    def get_total_core_competencies(self):
        total = 0.0
        for rec in self.core_competencies:
            total += rec.score
        self.total_competencies = total

    @api.depends('function_comp', 'total_function_comp')
    def get_total_function_comp(self):
        total = 0.0
        for rec in self.function_comp:
            total += rec.score
        self.total_function_comp = total

    @api.depends('employee_kpi', 'total_employee_kpi')
    def get_total_total_employee_kpi(self):
        total = 0.0
        for rec in self.employee_kpi:
            total += rec.score
        self.total_employee_kpi = total

    # @api.depends('totalcore_comp','total_totalcore_comp')
    # def get_total_totalcore_comp(self):
    #    total = 0.0
    #        for rec in self.totalcore_comp:
    #            total += rec.score
    #        self.total_totalcore_comp = total

    #    @api.depends('employee_kpi','total_employee_kpi')
    #    def get_totaltotal_employee_kpi(self):
    #        total = 0.0
    #        for rec in self.employee_kpi:
    #            total += rec.score
    #        self.total_employee_kpi = total

    @api.onchange('employee_id', 'jop_ids')
    def total_lines_employee_id(self):
        print('111111111111111111111111111')
        lines = [(5, 0, 0), ]
        if self.jop_ids.kpi_ids:
            for rec in self.jop_ids.kpi_ids:
                # lines.append(rec.id)
                if rec.active_kpi == True:
                    lines.append((0, 0, {
                        'name': rec.name,
                        'kpi_weight': rec.weight,
                        'kra_kpi': rec.kra_kpi,
                        # 'state_result': "expectation",
                    }))
        else:
            lines = [(5, 0, 0), ]
        self.update({'employee_kpi': lines})

        # self.update({'employee_kpi': lines,})

        # self.update({self.employee_kpi: self.employee_id.kpi_ids.id, })

    # @api.onchange('employee_id')
    # def employee_kpi(self):
    #     print ('11111111111111111')
    # for rec in self.employee_id.kpi_ids:
    #     rec.employee_kpi==rec.
    # self.update({'employee_kpi': self.employee_id.kpi_ids.id,})

    # @api.constrains('function_comp')
    # def get_function_comp(self):
    #     x = 0
    #     total = 0.0
    #     total2 = 0.0
    #     for rec in self.function_comp:
    #         total += rec.percentage
    #         total2 += rec.kpi_weight
    #         if rec.kpi_weight > 0:
    #             x += 1
    #         print ('xxxxxxxxxxxxxxxx', x)
    #         if x == 3:
    #             print ('2222222222222222222222', x)
    #             raise UserError(_('يلزم الاجابة على سؤلين فقط لا غير'))
    #         # if total != 100:
    #         #    raise UserError(_('percentage % Must be in 100%'))
    #
    #         # if total2 >= 100:
    #         #    raise UserError(_('KPI weight % Must be in 100%'))

    # @api.constrains('core_competencies')
    # def get_hours_custom(self):
    #     print ('+++++++++++++++++++++++++++++++++++')
    #     total = 0.0
    #     total2 = 0.0
    #     for rec in self.core_competencies:
    #         total += rec.percentage
    #         total2 += rec.kpi_weight
    #     print ('ttttttttttttttttt', total)
    # if total != 100:
    #    raise UserError(_('percentage % Must be in 100%'))

    # if total2 >= 100:
    #    raise UserError(_('KPI weight % Must be in 100%'))

    # @api.model
    # def default_get(self, fields):
    #     res = super(SurveySurvey, self).default_get(fields)
    #     print ("depends------------------------------------------------------------------------")
    #     manager_rec = [(5, 0, 0), ]
    #     manager_rec_total = [(5, 0, 0), ]
    #     # if not self.managers_opinions:
    #     manager_rec.append((0, 0, {
    #         'name': "يفهم ويتعلم من الآخرون",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #
    #     manager_rec.append((0, 0, {
    #         'name': "يطور الأفكار الجديدة التي توفر حلولا لجميع أنواع التحديات في مكان العمل.",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #     manager_rec.append((0, 0, {
    #         'name': "يلتزم بجميع قوانين وأنظمه والمعايير الخاصة بالعمل.",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #     manager_rec.append((0, 0, {
    #         'name': "لايحتاج لساعات عمل زائده عن وقت العمل للانتهاء من المهام الموكله له",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #     manager_rec.append((0, 0, {
    #         'name': "لديه روح التعاون مع الاخرين",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #     ####################################3
    #     manager_rec_total.append((0, 0, {
    #         'name': "يحل التحديات الصعبة أو المعقدة.",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #     manager_rec_total.append((0, 0, {
    #         'name': " يتحمل المسؤولية الشخصية عن جوده العمل وحسن توقيته، ويحقق النتائج مع القليل من الرقابة",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #
    #     manager_rec_total.append((0, 0, {
    #         'name': " يتكيف مع احتياجات العمل المتغيرة ، والظروف ، ومسؤوليات العمل.",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #
    #     manager_rec_total.append((0, 0, {
    #         'name': " أداره الوقت والأولويات والموارد الخاصة لتحقيق الأهداف",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #
    #     manager_rec_total.append((0, 0, {
    #         'name': " يعطي الاخرين طاقه ايجابيه ودفعه للعمل",
    #         'kpi_weight': 20,
    #         'state_result': "expectation",
    #     }))
    #
    #     res.update({'core_competencies': manager_rec, 'function_comp': manager_rec_total})
    #     # res.update({'function_comp': manager_rec_total})
    #     return res

class NewModule(models.Model):
    _name = 'core.competencies'
    _rec_name = 'name'

    name = fields.Char(string='Core')  # , groups="hr.group_hr_user"
    percentage = fields.Float(string="Final %", required=False, )
    kpi_weight = fields.Float(string="Weight", required=False, )
    state_result = fields.Selection(string="Result", selection=[('expectation', 'Rank of Expectation'),
                                                                ('improvement', 'Need To Improvement'),
                                                                ('meet', 'Meet'), ('exceed', 'Exceed'),
                                                                ('fail', 'Fail'), ], required=False)
    score = fields.Float(string="Score", required=False, compute='get_score', readonly=True,)
    active_core = fields.Boolean('Active', default=True,)
    employee_self_assessment = fields.Float(string="Employee Self Assessment", required=False, )
    direct_manager = fields.Float(string="Direct Manager", required=False, )
    in_direct_manager = fields.Float(string="In Direct Manager", required=False, )

    # interval_core22 = fields.Many2one(comodel_name="evaluation.evaluation")

    @api.depends('percentage', 'kpi_weight')
    def get_score(self):
        for rec in self:
            rec.score = (rec.percentage * rec.kpi_weight)

    # @api.constrains('kpi_weight')
    # def get_kpi_employee(self):
    #     total = 0.0
    #     kpi_rec = self.env['core.competencies'].search([])
    #     for rec in kpi_rec:
    #         total += rec.kpi_weight
    #     print ('++++++++++++++++', total)
    #     if total > 1:
    #         raise UserError(_('total weight for certain Employee  must = 100%'))

class NewModule(models.Model):
    _name = 'core2.competencies2'
    _rec_name = 'name'

    name = fields.Char(string='Core')  # , groups="hr.group_hr_user"
    percentage = fields.Float(string="Final %", required=False, )
    kpi_weight = fields.Float(string="KPI weight", required=False, )
    state_result = fields.Selection(string="Result", selection=[('expectation', 'Rank of Expectation'),
                                                                ('improvement', 'Need To Improvement'),
                                                                ('meet', 'Meet'), ('exceed', 'Exceed'),
                                                                ('fail', 'Fail'), ], required=False, )
    score = fields.Float(string="Score", required=False, compute='get_score', readonly=True, )
    active_core = fields.Boolean('Active', default=True, )
    employee_self_assessment = fields.Float(string="Employee Self Assessment", required=False, )
    direct_manager = fields.Float(string="Direct Manager", required=False, )
    in_direct_manager = fields.Float(string="In Direct Manager", required=False, )

    interval_core = fields.Many2one(comodel_name="evaluation.evaluation")
    # evaluation_method = fields.Selection(string="Evaluation Method", selection=[('dm', 'Direct Manager'), ('average', 'Average'),('pm','Parent Manager') ],related='interval_core.evaluation_method' )

    @api.onchange('direct_manager','in_direct_manager','interval_core')
    def get_final_total(self):
        if self.interval_core.evaluation_method=='dm':
            self.percentage=self.direct_manager
        if self.interval_core.evaluation_method == 'average':
            self.percentage = (self.direct_manager+self.in_direct_manager)/2
        if self.interval_core.evaluation_method == 'pm':
            self.percentage = 0

    @api.depends('percentage', 'kpi_weight')
    def get_score(self):
        for rec in self:
            rec.score = (rec.percentage * rec.kpi_weight)

###########################################################################################################

class NewModule(models.Model):
    _name = 'function.competencies'
    _rec_name = 'name'

    name = fields.Char(string='Function')  # , groups="hr.group_hr_user"
    percentage = fields.Float(string="Final %", required=False, )
    kpi_weight = fields.Float(string="Weight", required=False, )
    state_result = fields.Selection(string="Result", selection=[('expectation', 'Rank of Expectation'),
                                                                ('improvement', 'Need To Improvement'),
                                                                ('meet', 'Meet'), ('exceed', 'Exceed'),
                                                                ('fail', 'Fail'), ], required=False)#,groups="hr.group_hr_user"
    score = fields.Float(string="Score", required=False, compute='get_score', readonly=True)
    active_function = fields.Boolean('Active', default=True)#, groups="hr.group_hr_user"
    employee_self_assessment = fields.Float(string="Employee Self Assessment", required=False, )
    direct_manager = fields.Float(string="Direct Manager", required=False, )
    in_direct_manager = fields.Float(string="In Direct Manager", required=False, )

    # interval_function = fields.Many2one(comodel_name="evaluation.evaluation")

    @api.depends('percentage', 'kpi_weight')
    def get_score(self):
        for rec in self:
            rec.score = (rec.percentage * rec.kpi_weight)

    # @api.constrains('kpi_weight')
    # def get_kpi_employee(self):
    #     total = 0.0
    #     kpi_rec = self.env['function.competencies'].search([])
    #     for rec in kpi_rec:
    #         total += rec.kpi_weight
    #     print ('++++++++++++++++', total)
    #     if total > 1:
    #         raise UserError(_('total weight for certain Employee  must = 100%'))

class NewModule(models.Model):
    _name = 'function2.competencies2'
    _rec_name = 'name'

    name = fields.Char(string='Questions')  # , groups="hr.group_hr_user"
    percentage = fields.Float(string="Final %", required=False, )
    kpi_weight = fields.Float(string="KPI weight", required=False, )
    state_result = fields.Selection(string="Result", selection=[('expectation', 'Rank of Expectation'),
                                                                ('improvement', 'Need To Improvement'),
                                                                ('meet', 'Meet'), ('exceed', 'Exceed'),
                                                                ('fail', 'Fail'), ])
    score = fields.Float(string="Score", required=False, compute='get_score', readonly=True, )
    active_function = fields.Boolean('Active', default=True)
    employee_self_assessment = fields.Float(string="Employee Self Assessment", required=False, )
    direct_manager = fields.Float(string="Direct Manager", required=False, )
    in_direct_manager = fields.Float(string="In Direct Manager", required=False, )

    interval_function = fields.Many2one(comodel_name="evaluation.evaluation")

    @api.onchange('direct_manager', 'in_direct_manager', 'interval_function')
    def get_final_total(self):
        if self.interval_function.evaluation_method == 'dm':
            self.percentage = self.direct_manager
        if self.interval_function.evaluation_method == 'average':
            self.percentage = (self.direct_manager + self.in_direct_manager) / 2
        if self.interval_function.evaluation_method == 'pm':
            self.percentage = 0

    @api.depends('percentage', 'kpi_weight')
    def get_score(self):
        for rec in self:
            rec.score = (rec.percentage * rec.kpi_weight)

##########################################################################3
class NewModule(models.Model):
    _name = 'kpi.competencies'
    _rec_name = 'name'

    name = fields.Char(string='KPI', )
    percentage = fields.Float(string="Final %", required=False, )
    kpi_weight = fields.Float(string="Weight", )
    state_result = fields.Selection(string="Result", selection=[('expectation', 'Rank of Expectation'),
                                                                ('improvement', 'Need To Improvement'),
                                                                ('meet', 'Meet'), ('exceed', 'Exceed'),
                                                                ('fail', 'Fail'), ], required=False)
    score = fields.Float(string="Score", required=False, compute='get_score', readonly=True)
    # active = fields.Boolean('Active', default=True)
    kra_kpi = fields.Char(string="KRA", )
    employee_self_assessment = fields.Float(string="Employee Self Assessment", required=False, )
    direct_manager = fields.Float(string="Direct Manager", required=False, )
    in_direct_manager = fields.Float(string="In Direct Manager", required=False, )
    interval_kpi = fields.Many2one(comodel_name="evaluation.evaluation")

    @api.onchange('direct_manager', 'in_direct_manager', 'interval_kpi')
    def get_final_total(self):
        if self.interval_kpi.evaluation_method == 'dm':
            self.percentage = self.direct_manager
        if self.interval_kpi.evaluation_method == 'average':
            self.percentage = (self.direct_manager + self.in_direct_manager) / 2
        if self.interval_kpi.evaluation_method == 'pm':
            self.percentage = 0

    @api.depends('percentage', 'kpi_weight')
    def get_score(self):
        for rec in self:
            rec.score = (rec.percentage * rec.kpi_weight)


""" Custom error handlers and the like """
import logging
import traceback
import ndb_json

ERROR_DICT = {}

class CustomException(Exception):
    """ Our own base custom exception """
    def __init__(self, error_code=None, details=None, response=None, *args, **kwargs):
        self.__error_code = error_code
        self.__details = details
        self.__response = response
        super(CustomException, self).__init__(*args, **kwargs)

    def __str__(self):
        return repr(self.__details)

    @property
    def error_code(self):
        """ Error_code property"""
        return self.__error_code

    @property
    def details(self):
        """ Details property """
        return self.__details

    @property
    def response(self):
        """ Response property"""
        return self.__response

    def respond(self, response=None, status=500):
        """ Mechanism for turning custom exception into
        restful response """
        if response is None:
            response = self.response
        err = ErrorReturn(
            response,
            error_code=self.error_code,
            details=self.details)
        logging.info("CE.r")
        logging.info(self.details)
        err.handle_response(status=status)

class ErrorReturn(object):
    """ Class that handles html response """
    def __init__(self, response, error_code=None, details=None):
        self.response = response
        self.__error_code = error_code
        self.__details = details

    @property
    def error_package(self):
        """ Error package property
        handles formatting based on what was set """
        return_package = {}
        if self.__error_code:
            return_package['code'] = self.__error_code
            return_package['description'] = ERROR_DICT[self.__error_code]
        else:
            return_package['code'] = 'N/A'
            return_package['description'] = 'N/A'

        if self.__details:
            return_package['details'] = self.__details
        return return_package

    def handle_response(self, status=None):
        """ General repsonse handler """
        logging.info("ER.h_r")
        logging.info(self.__details)
        if int(status) == 200:
            self._handle_200()
        elif int(status) == 400:
            self._handle_400()
        elif int(status) == 401:
            self._handle_401()
        elif int(status) == 403:
            self._handle_403()
        elif int(status) == 404:
            self._handle_404()
        elif int(status) == 500:
            self._handle_500()

    # Default to walk ourselves out of some of this error handling
    def _handle_200(self):
        error_info = self.error_package
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        self.response.headers['content-type'] = "application/json"
        self.response.write(ndb_json.dumps(error_info))
        self.response.set_status(200)

    def _handle_400(self):
        logging.info("400 in our own method")
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        error_info = self.error_package
        self.response.headers['content-type'] = "application/json"
        self.response.write(ndb_json.dumps(error_info))
        self.response.set_status(400)
        traceback.print_stack()

    def _handle_401(self):
        logging.info("401 in our own method")
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        error_info = self.error_package
        self.response.headers['content-type'] = "application/json"
        self.response.write(ndb_json.dumps(error_info))
        self.response.set_status(401)
        traceback.print_stack()

    def _handle_403(self):
        logging.info("403 in our own method")
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        error_info = self.error_package
        self.response.headers['content-type'] = "application/json"
        self.response.write(ndb_json.dumps(error_info))
        self.response.set_status(403)
        traceback.print_stack()

    def _handle_404(self):
        logging.info("404 in our own method")
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        error_info = self.error_package
        self.response.headers['content-type'] = "application/json"
        self.response.write(ndb_json.dumps(error_info))
        self.response.set_status(404)
        traceback.print_stack()

    def _handle_500(self):
        logging.info("500 in our own method")
        self.response.headers.add_header("Access-Control-Allow-Origin", "*")
        error_info = self.error_package
        self.response.headers['content-type'] = "application/json"
        self.response.write(ndb_json.dumps(error_info))
        self.response.set_status(500)
        traceback.print_stack()


import torch
import torchvision.transforms as transforms
import torchvision
from PIL import Image
from io import BytesIO
import requests

def apply_test_transforms(inp):
    trans = transforms.Compose([
        transforms.Resize(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ])
    return trans(inp)

def load_model_from_weights(weights_dir, num_classes):
    """Loads model from weight dir

    Args:
        weights_dir (str]): path to weights file
    """

    model = torchvision.models.densenet121(pretrained=False)
    for param in model.parameters():
        param.requires_grad = False
    n_inputs = model.classifier.in_features
    last_layer = torch.nn.Linear(n_inputs, num_classes)
    model.classifier = last_layer
    model.load_state_dict(torch.load(weights_dir))
    return model

def load_image(image_dir, url=False):
    if not url:
        img = Image.open(image_dir)
    else:
        response = requests.get(image_dir)
        img = Image.open(BytesIO(response.content))
    return img

def predict(model, filepath, classes, url=False, device="cpu"):
    im = load_image(filepath, url=url)
    im_as_tensor = apply_test_transforms(im)
    minibatch = torch.stack([im_as_tensor])
    minibatch = minibatch.to(device)
    pred = model(minibatch)
    _, classnum = torch.max(pred, 1)
    return classes[classnum]