import numpy as np
import tensorflow as tf
from gensim.models import Word2Vec

tf.reset_default_graph()
sess = tf.InteractiveSession()

class Seq2seq():
	def __init__(self, rnn_size, num_layers, batch_size, vocab_size, mode,
				 max_encoder_steps, max_decoder_steps, embedding_size, beam_size=0):
		self.rnn_size = rnn_size
		self.num_layers = num_layers
		self.batch_size = batch_size
		self.vocab_size = vocab_size
		self.mode = mode
		self.max_encoder_steps = max_encoder_steps
		self.max_decoder_steps = max_decoder_steps
		self.beam_size = beam_size
		self.embedding_size = embedding_size

		self.build_model()

		self.saver = tf.train.Saver(tf.global_variables(), max_to_keep=50)

	def build_model(self):
		# Model input & output

		# shape = (batch_size, max_seq_len)
		self.encoder_inputs  = tf.placeholder(shape=(None, None), dtype=tf.int32, name='encoder_inputs')
		self.encoder_inputs_length = tf.placeholder(shape=[None], dtype=tf.int32, name='encoder_inputs_length')
		# shape = (batch_size, max_seq_len)
		self.decoder_inputs  = tf.placeholder(shape=(None, None), dtype=tf.int32, name='decoder_inputs')
		self.decoder_targets = tf.placeholder(shape=(None, None), dtype=tf.int32, name='decoder_targets')
		self.decoder_targets_length = tf.placeholder(shape=[None], dtype=tf.int32, name='decoder_targets_length')

		self.keep_prob_placeholder = tf.placeholder(dtype=tf.float32)
		self.sampling_probability = tf.placeholder(shape=[], dtype=tf.float32)

		# embeddings (gensin word2vec)
		w2v_model = Word2Vec.load("word2vec.model")
		w2v_embedding = np.zeros([len(w2v_model.wv.index2word), self.embedding_size])
		for idx, word in enumerate(w2v_model.wv.index2word):
			w2v_embedding[idx, :] = w2v_model[word]
		embeddings = tf.Variable(tf.convert_to_tensor(w2v_embedding, np.float32), trainable=False, name='embedding')

		encoder_inputs_embedded = tf.nn.embedding_lookup(embeddings, self.encoder_inputs)
		encoder_inputs_embedded = tf.transpose(encoder_inputs_embedded, [1,0,2])

		decoder_inputs_embedded = tf.nn.embedding_lookup(embeddings, self.decoder_inputs)
		decoder_inputs_embedded = tf.transpose(decoder_inputs_embedded, [1,0,2])

		# Encoder

		encoder_cell = self._create_cell()
		encoder_outputs, encoder_final_state = tf.nn.dynamic_rnn(encoder_cell, encoder_inputs_embedded, dtype = tf.float32, time_major = True)
#####???
		# encoder_outputs, encoder_final_state = tf.nn.bidirectional_dynamic_rnn(
		# 												cell_fw=self._create_cell(),
		# 												cell_bw=self._create_cell(),
		# 												inputs=encoder_inputs_embedded,
		# 												sequence_length=self.encoder_inputs_length,
		# 												dtype=tf.float32,
		# 												time_major=True )
#####???

		encoder_outputs = tf.transpose(encoder_outputs, [1,0,2]) # shape(batch_size,max_step,rnn_size)
		if self.mode == 'test':
			encoder_outputs = tf.contrib.seq2seq.tile_batch(encoder_outputs, multiplier=self.beam_size)

		# Decoder

		# Decoder cell with attention
		attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(
													num_units=self.rnn_size,
													memory=encoder_outputs,
													normalize=True)

		decoder_cell = tf.contrib.seq2seq.AttentionWrapper(
												cell=self._create_cell(),
												attention_mechanism=attention_mechanism,
												attention_layer_size=self.rnn_size,
												name='Attention_Wrapper')

		output_layer = tf.layers.Dense(self.vocab_size, kernel_initializer=tf.truncated_normal_initializer(mean=0.0, stddev=0.1))

		max_target_sequence_length = tf.reduce_max(self.decoder_targets_length, name='max_target_len')
		mask = tf.sequence_mask(self.decoder_targets_length, max_target_sequence_length, dtype=tf.float32, name='masks')

		# Define helper based on 'train' or 'infer' mode
		if self.mode == 'train':
			decoder_initial_state = decoder_cell.zero_state(batch_size=self.batch_size, dtype=tf.float32).clone(cell_state=encoder_final_state)
#####???
			training_helper = tf.contrib.seq2seq.ScheduledEmbeddingTrainingHelper(
											inputs=decoder_inputs_embedded,
											sequence_length=self.decoder_targets_length,
											embedding=embeddings,
											sampling_probability=self.sampling_probability,
											time_major=True)
#####???
			# training_helper = tf.contrib.seq2seq.TrainingHelper(
			# 								inputs=decoder_inputs_embedded,
			# 								sequence_length=self.decoder_targets_length,
			# 								# memory_sequence_length=?????????,
			# 								time_major=True, name='training_helper')

			# Decoder
			training_decoder = tf.contrib.seq2seq.BasicDecoder(
											cell=decoder_cell, helper=training_helper,
											initial_state=decoder_initial_state,
											output_layer=output_layer)

			decoder_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(
											decoder=training_decoder,
											impute_finished=True,
											maximum_iterations=max_target_sequence_length)

			# Calculate loss with sequence_loss
			decoder_logits_train = tf.identity(decoder_outputs.rnn_output)
			self.decoder_predict_train = tf.argmax(decoder_logits_train, axis=-1, name='decoder_pred_train')
			# decoder_logits_train = tf.transpose(decoder_logits_train, [1,0,2])

			self.loss = tf.contrib.seq2seq.sequence_loss(
									logits=decoder_logits_train,
									targets=self.decoder_targets,
									weights=mask)
			optimizer = tf.train.AdamOptimizer()

			# Clip gradient if gradient is too large
			gradients = optimizer.compute_gradients(self.loss)
			capped_gradients = [ (tf.clip_by_value(grad, -0.3, 0.3), var) for grad, var in gradients if grad is not None ]
			self.train_op = optimizer.apply_gradients(capped_gradients)

		else:
			# 如果使用beam_search，则需要将encoder的输出进行tile_batch，其实就是复制beam_size份。
			self.tiled_encoder_final_state = tf.contrib.seq2seq.tile_batch(encoder_final_state, multiplier=self.beam_size)

			batch_size = self.batch_size * self.beam_size

			decoder_initial_state = decoder_cell.zero_state(batch_size=batch_size, dtype=tf.float32).clone(cell_state=self.tiled_encoder_final_state)

			inference_decoder = tf.contrib.seq2seq.BeamSearchDecoder(
											cell=decoder_cell,
											embedding=embeddings,
											start_tokens=tf.fill([self.batch_size, ], 1),	# <BOS> = 1
											end_token=2, 									# <EOS> = 2
											initial_state=decoder_initial_state,
											beam_width=self.beam_size,
											output_layer=output_layer)

			inference_decoder_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(
															decoder=inference_decoder,
															maximum_iterations=self.max_decoder_steps)

			self.decoder_predict_decode = inference_decoder_outputs.predicted_ids
			self.decoder_predict_logits = inference_decoder_outputs.beam_search_decoder_output

	def _create_cell(self):
		def single_cell():
			cell = tf.contrib.rnn.LSTMCell(self.rnn_size)
			cell = tf.contrib.rnn.DropoutWrapper(cell, output_keep_prob=self.keep_prob_placeholder)
			return cell
		cell = tf.contrib.rnn.MultiRNNCell([ single_cell() for _ in range(self.num_layers) ])
		return cell

	def train(self, sess, encoder_inputs, encoder_inputs_length, decoder_inputs,
			  decoder_targets, decoder_targets_length, sampling_probability):
		feed_dict = { self.encoder_inputs : encoder_inputs,
					  self.encoder_inputs_length : encoder_inputs_length,
					  self.decoder_inputs : decoder_inputs,
					  self.decoder_targets : decoder_targets,
					  self.decoder_targets_length : decoder_targets_length,
					  self.sampling_probability : sampling_probability,
					  self.keep_prob_placeholder : 0.8 }

		_, loss = sess.run([self.train_op, self.loss], feed_dict=feed_dict)
		return loss

	def infer(self, sess, encoder_inputs):
		feed_dict = { self.encoder_inputs : encoder_inputs,
					  self.keep_prob_placeholder : 1.0 }

		predict, logits = sess.run([self.decoder_predict_decode, self.decoder_predict_logits], feed_dict=feed_dict)
		return predict, logits


from pyspark.sql import SparkSession
from pyspark.sql.types import *
import pyspark.sql.functions as F
# import logging
# logging.basicConfig(filename="C:\\Users\\aakan\\PycharmProjects\\logs\\pysparkloffile.log", filemode="w")
# log = logging.getLogger()
# log.setLevel(logging.WARN)

#creating function to create a spark session object
def create_sparkseesion():
    spark = SparkSession.builder\
                  .master("local[1]")\
                  .appName("assignment on pyspark")\
                  .getOrCreate()
    return spark

#creating a dataframe for product table
def product_dataframe(spark):
    product_schema=StructType([StructField(name='ProductName',dataType=StringType()),
                          StructField(name='Issue Date',dataType=StringType()),
                          StructField(name='Price',dataType=IntegerType()),
                          StructField(name='Brand',dataType=StringType()),
                          StructField(name='Country',dataType=StringType()),
                          StructField(name='Product_Number',dataType=IntegerType())
                          ])
    product_df = spark\
            .read\
            .format('csv')\
            .options(header=True)\
            .schema(product_schema)\
            .load("../../resource/product.csv")

    return product_df

#creating a function to convert  the issue date to timestamp format.
def issue_date_timestamp(product_df):
    df_timestamp_string = product_df.withColumn("Issue_Date_timsetampformat",F.from_unixtime(F.col("Issue Date")/1000,"yyyy-MM-dd'T'HH:mm:ssZZZZ"))
    return df_timestamp_string

#creating a function to convert  the issue date to date type.
def issue_date_datestamp(df_timestamp_string):
    df_date = df_timestamp_string.withColumn("Date",F.date_format(F.col("Issue_Date_timsetampformat"),"yyyy-MM-dd"))
    return df_date

#creating a function to remove starting space in Brand Column.
def remove_space(product_df):
    df_remove_space = product_df.withColumn("Brand_new",F.trim(F.col("Brand")))
    return df_remove_space

#creating a function to replace null values with empty spaces Country Column.
def replace_null(product_df):
    df_replace_null = product_df.withColumn("Country_new",F.when(F.col("Country") == "null", '').otherwise(F.col("Country")))
    return df_replace_null

#creating a function to create a dataframe for transaction table
def transaction_dataframe(spark):
    transaction_schema=StructType([StructField(name='SourceId',dataType=IntegerType()),
                          StructField(name='TransactionNumber',dataType=IntegerType()),
                          StructField(name='Language',dataType=StringType()),
                          StructField(name='ModelNumber',dataType=IntegerType()),
                          StructField(name='StartTime',dataType=StringType()),
                          StructField(name='ProductNumber',dataType=IntegerType())
                          ])
    transaction_df = spark\
            .read\
            .format('csv')\
            .options(header=True)\
            .schema(transaction_schema)\
            .load("../../resource/Product_transaction.csv")
    return transaction_df

# #creating a function to covert column names from camel case to snake case.

#creating a function to add a new column as start_time_ms and convert the StartTime column values to milliseconds.
def millisecond(transaction_df):
    df_millisecond = transaction_df.withColumn("StartTime_timestamp",F.to_timestamp(F.col("StartTime")))\
                                   .withColumn("start_time_ms",F.unix_timestamp(F.col("StartTime_timestamp")))\
                                   .drop("StartTime_timestamp")
    return df_millisecond

#creating a function to join both the dataframe
def joindataframe(df_replace_null,df_millisecond):
    joined_df = df_replace_null.join(df_millisecond,df_replace_null.Product_Number == df_millisecond.ProductNumber,"left")\
                                .drop("Product_Number")
    return joined_df

#creating a function to filter the country with language as EN
def filter_country(joined_df):
    df_filter = joined_df.filter(F.col("Language") == "EN")
    return df_filter
#


from styles import separator, Colors, displayStyledText

menu_keys_and_text = {
	"A": "Infix to Postfix",
	"B": "Infix to Prefix",
	"X": "Close"
}

def display_menu():
	# Displays menu from the menu_keys_and_text dictionary
	keys = menu_keys_and_text.keys()

	separator()
	print("Menu")

	for i in keys:
		print("[" + i + "] " + menu_keys_and_text[i])

	separator()

def getUserMenuInput():
	# Get user menu input, only accepts 'A', 'B', and 'X'
	# Display error if not a valid choice
	while True:
		userInput = input("Your choice: ").upper()

		if userInput in menu_keys_and_text.keys():
			return userInput

		displayStyledText(Colors.BG_RED, Colors.WHITE, "Invalid Input", Colors.BG_WHITE, Colors.RED, f'{userInput} is not a valid choice.')


import itertools
import sys
sys.stdin = open('input.txt', 'r')

board = [list(input()) for _ in range(5)]
adj = [(-1, 0), (0, 1), (1, 0), (0, -1)]

students = []
for i in range(5):
    for j in range(5):
        students.append((i, j))

answer = 0

for group in itertools.combinations(students, 7):
    ds = 0
    for i, j in group:
        if board[i][j] == 'S':
            ds += 1
    if ds >= 4:
        visit = {}
        for pos in group:
            visit[pos] = False

        queue = [group[0]]
        visit[group[0]] = True

        while queue:
            pos1 = queue.pop(0)
            for di, dj in adj:
                pos2 = (pos1[0]+di, pos1[1]+dj)
                if pos2 in group and visit[pos2] is False:
                    visit[pos2] = True
                    queue.append(pos2)

        if False not in visit.values():
            answer += 1

print(answer)


import pandas as pd
from util import ingressutil

class FidelityIngress:

  @staticmethod
  def is_valid(data_to_check: pd.DataFrame) -> bool:

    first_col_name = data_to_check.columns[0]
    return ('Account Name/Number' == first_col_name)

  @staticmethod
  def transform_data(statement: pd.DataFrame) -> []:

    # Find the first row that is the actual header row
    # Find the last row that ends the data table
    # Get the rows between header row and end row
    # Create a new table with new headers from the header row

    datatable = ingressutil.read_data_table(statement, None, None)

    # print('Fidelity datatable: ', datatable)

    poss = []

    # get the rows with positions (by checking Symbol column and it doesn't end with ** (which is cash))
    ass = datatable[pd.notna(datatable['Symbol']) & (datatable['Symbol'].str.endswith('**') == False)]

    for index, row in ass.iterrows():
      index
      poss.append([row['Symbol'], 'Fidelity', row['Account Name/Number'].strip(), float(row['Quantity']), float(row['Last Price'].replace('$', ''))])

    return poss

# sttmnt = pd.read_csv('../data/Copy of Portfolio_Positions_Jan-27-2021.csv',  thousands=',')

# print("is_valid: ", FidelityIngress.is_valid(sttmnt))
# print(FidelityIngress.transform_data(sttmnt))


class RingBuffer:
	def __init__(self):
		self.data = []
		self.cur=0
	def remove(self, key):
		self.data.remove(key)
	def length(self):
		return len(self.data)
	def append(self,x):
		"""append an element at the end of the buffer"""
		self.data.append(x)
	def get(self):
		self.cur+=1
		if len(self.data) == self.cur:
			self.cur=0
		return self.data[self.cur]
	def get_current(self):
		return self.data[self.cur]
	def previous(self):
		self.cur-=1
		if self.cur < 0:
			self.cur = len(self.data)-1
		return self.data[self.cur]
	def set(self, x):
		self.cur=x

class Dudo:
	def posibles(self, movimiento, maximo_dados):
		movimientos_posibles = []
		pinta = 0
		if movimiento[1] != 1:
			for i in range (movimiento[0], maximo_dados+1):
				if pinta == 0:
					if movimiento[0]!=0:
						movimientos_posibles.append(((movimiento[0]/2)+1,1))
					for j in range (movimiento[1]+1, 7):
						movimientos_posibles.append((i,j))
					pinta = 1
				else:
					for j in range (1,7):
						movimientos_posibles.append((i,j))
		else:
			for i in range (movimiento[0]+1, maximo_dados+1):
				movimientos_posibles.append((i,1))
			for i in range (movimiento[0]*2, maximo_dados+1):
				for j in range (2, 7):
					movimientos_posibles.append((i,j))
		return movimientos_posibles


# %%

# imports
import numpy as np
import json
import math

def angle_from_vis(start, middle, end):
    end_a = 180 + math.atan2(middle[1] - start[1],
                             middle[0] - start[0]) * 180 / math.pi
    start_a = math.atan2(end[1] - middle[1], end[0] -
                         middle[0]) * 180 / math.pi

    if end_a - start_a > 360:
        end_a = end_a - 360

    if (end_a - start_a) > 180:
        temp = end_a
        end_a = start_a
        start_a = temp

    angle = end_a - start_a
    if angle < 0 and (angle + 360) > 180:
        temp = end_a
        end_a = start_a
        start_a = temp

    angle = end_a - start_a
    if angle < 0:
        angle += 360

    return angle

def json_prep_anno(anno: dict, net=True):
    """make the anno dict ready to be json serlialised"""
    json_anno = {}

    # top level
    for key in anno.keys():

        json_anno[key] = {}

        if key == 'imgfac':
            json_anno[key] = anno[key]
            continue

        all_keys = list(set(anno[key].keys()).intersection(
            ['keypoints', 'segmentation', 'bbox']))

        # lower level
        for subkey in all_keys:
            try:
                if isinstance(anno[key][subkey][0], list):
                    json_anno[key][subkey] = []
                    for ele in anno[key][subkey]:
                        if net:
                            json_anno[key][subkey].append([
                                subele.item() for subele in ele])
                        else:
                            json_anno[key][subkey].append([
                                subele for subele in ele])
                else:
                    if net:
                        json_anno[key][subkey] = [ele.item()
                                                  for ele in anno[key][subkey]]
                    else:
                        json_anno[key][subkey] = [ele
                                                  for ele in anno[key][subkey]]
            except:
                print('failed here')

    return json_anno

def get_mid(a, b):
    return [0.5*(a[0] + b[0]), 0.5*(a[1] + b[1])]

def get_per(start, end, per):
    xper = start[0] + per * (end[0] - start[0])
    yper = start[1] + per * (end[1] - start[1])
    return [xper, yper]

def get_difference(a, b):
    return np.linalg.norm(np.array([b[0]-a[0], b[1]-a[1]]))

def signum_fc(x):
    if x < 0:
        return -1
    return 1

class Line():

    def __init__(self, m, b):
        self.m = m
        self.b = b

        self.ortho_m = -1 / self.m

    def intersect(self, line):
        div = (line.m - self.m)
        div = signum_fc(div) * (abs(div) + 1e-7)
        x = (self.b - line.b) / div
        y = self(x)
        return [x, y]

    def __call__(self, x):
        return x * self.m + self.b

class LineP1m(Line):

    def __init__(self, p1: list, m):
        # elevation
        self.m = m

        self.ortho_m = -1 / self.m

        # offset
        self.b = p1[1] - self.m * p1[0]

class LineP1P2(Line):
    """line class to handle all common calculus"""

    def __init__(self, p1: list, p2: list):
        # correct starting order
        if p1[0] < p2[0]:
            self.start_p = p1
            self.end_p = p2
        else:
            self.start_p = p2
            self.end_p = p1

        # elevation
        self.m = (self.end_p[1] - self.start_p[1]) / \
            ((self.end_p[0] - self.start_p[0]) + 1e-6)

        if (abs(self.m) < 1e-6):
            self.m = 1e-6

        self.ortho_m = -1 / self.m

        # offset
        self.b = self.start_p[1] - self.m * self.start_p[0]

        # midpoint of line
        self.midpoint = [0.5 * (self.start_p[0] + self.end_p[0]),
                         0.5 * (self.start_p[1] + self.end_p[1])]

        # further provide a far away points
        self.dist = 4000
        self.dist_min = [self.midpoint[0] - self.dist,
                         self.midpoint[1] - self.dist * self.m]
        self.dist_max = [self.midpoint[0] + self.dist,
                         self.midpoint[1] + self.dist * self.m]

def keyp_by_num(keyp_arr: list, num: int):
    """return the actual keypoint by number selection"""

    lenlist = len(keyp_arr)
    if lenlist <= (num - 1) * 3 + 1:
        return [0, 0]

    x = keyp_arr[(num - 1) * 3]
    y = keyp_arr[(num - 1) * 3 + 1]
    return [x, y]

def improve_key_acc(anno: dict, keyname: str, num: int, scale=0.4, use_max=False):
    """
    Idea: take the keypoint, find the closest matching point in the polygon
    take the scaled mean of both points
    """
    # take the keypoint
    keyp = keyp_by_num(anno[keyname]['keypoints'], num)  # [x, y]
    return improve_key(anno, keyname, keyp, scale, use_max=use_max)

def improve_key(anno: dict, keyname: str, keyp: list, scale=0.4, move_lim=80, use_max=False):
    """
    same as function above, only for the ready keypoint
    scale: 1 -> use keypoint, 0 -> use_segmentation
    """
    keyp = np.array(keyp)
    # get the segmentation
    if 'segmentation' not in anno[keyname].keys():
        return keyp

    segmentation = anno[keyname]['segmentation']
    # now find best match
    match_p = np.array([0, 0])
    min_diff = 1e8

    # iterate trough each polygon
    for poly in segmentation:
        if len(poly) > 2:
            x_arr, y_arr = poly[::2], poly[1::2]
            # iterate trough each point
            for x, y in zip(x_arr, y_arr):
                # get the current difference
                loc_point = np.array([x, y])
                diff = np.linalg.norm(keyp - loc_point)
                if diff < min_diff:
                    min_diff = diff
                    match_p = loc_point

    improved_keyp = scale * keyp + (1-scale) * match_p

    if use_max:
        improved_keyp[1] = max(keyp[1], match_p[1])

    # check the prodeced movement
    diff = get_difference(keyp, match_p)
    if diff > move_lim:
        print(
            f'warning: keypointdiff further than {move_lim}px - no improvement used')
        return keyp

    return improved_keyp.tolist()

def midpoint_calc(medial_point, medial_bottom_point, lateral_bottom_point, lateral_point):
    """
    calculate the midpoint:
    medial_point                          lateral_point
        |                                       |
    medial_bottom_point  ___ midpoint ___ lateral_bottom_point
    """
    # build bottom line
    bottom_line = LineP1P2(medial_bottom_point, lateral_bottom_point)

    # medial line orthogonal to bottom line
    ortho_line_medial = LineP1m(medial_point, bottom_line.ortho_m)
    medial_intersect = bottom_line.intersect(ortho_line_medial)

    # lateral line orthogonal to bottom line
    ortho_line_lateral = LineP1m(lateral_point, bottom_line.ortho_m)
    lateral_intersect = bottom_line.intersect(ortho_line_lateral)

    # final line with middle point
    bottom_line_final = LineP1P2(medial_intersect, lateral_intersect)
    return bottom_line_final.midpoint, medial_intersect, lateral_intersect

def get_hip_midpoint(anno: dict):
    """simpy use H1"""
    keyp = anno['F_t']['keypoints']
    h1 = keyp_by_num(keyp, 1)

    keyp = anno['H']['keypoints']
    h2 = keyp_by_num(keyp, 1)

    diff = get_difference(h1, h2)

    if diff > 30:
        print(f'warning: H1 and H2 differ by {diff}px')
        return h1

    return h2

def get_femur_midpoint(anno: dict, option=1, acc_boost=False):
    """
    option 0: F5
    option 1: F3 - 90° - F1 - MIDPOINT - F2 - 90° - F4
    """
    keyp = anno['F']['keypoints']

    # option 1 -> midpoint
    F1 = keyp_by_num(keyp, 1)  # medial bottom
    F2 = keyp_by_num(keyp, 2)  # lateral bottom
    F3 = keyp_by_num(keyp, 3)  # medial
    F4 = keyp_by_num(keyp, 4)  # lateral

    if acc_boost:
        F1 = improve_key_acc(anno, 'F', 1, use_max=True)
        F2 = improve_key_acc(anno, 'F', 2, use_max=True)
        F3 = improve_key_acc(anno, 'F', 3)
        F4 = improve_key_acc(anno, 'F', 4)

    F1, F2, switch = improve_f1f2(F1, F2, anno)

    if switch:
        F1 = improve_key(anno, 'F', F1)
        F2 = improve_key(anno, 'F', F2)

    # now consider cases:
    norm_f1f2 = get_difference(F1, F2)
    norm_f3f4 = get_difference(F3, F4)

    if norm_f3f4 > norm_f1f2:
        midpoint, medial, lateral = midpoint_calc(F3, F1, F2, F4)
    else:
        midpoint, medial, lateral = midpoint_calc(F1, F1, F2, F2)
        O2 = improve_key_acc(anno, 'O', 2)
        O3 = improve_key_acc(anno, 'O', 3)
        norm_o2o3 = get_difference(O2, O3)

        if norm_o2o3 > norm_f1f2:
            midpoint, medial, lateral = midpoint_calc(O2, F1, F2, O3)

    # option 0 -> F5
    if option == 0:
        midpoint = keyp_by_num(keyp, 5)

    return midpoint, medial, lateral

def improve_f1f2(f1, f2, anno, place=0.2):
    """Idea: Improve F1, F2 if both points are on the same condyle"""
    # decide whether the leg is left or right
    left0right1 = get_left0_right1(anno)
    # now define bbox f1f2:
    bbox_femur = anno['F']['bbox']  # [x, y, width, height]

    if len(bbox_femur) < 4:
        print(f'warning: bbox_femur has less than 4 entries, {len(bbox_femur)}')
        return f1, f2, False

    # calculate ccordinates
    f1f2y = bbox_femur[1] + bbox_femur[3]  # bottom line
    fleftx = bbox_femur[0] + place * bbox_femur[2]
    frightx = bbox_femur[0] + (1 - place) * bbox_femur[2]
    x_mid = bbox_femur[0] + 0.5 * bbox_femur[2]

    switch = 0

    # case right F2-F1
    if left0right1:
        f1bbox = [frightx, f1f2y]
        f2bbox = [fleftx, f1f2y]

        # if F1 on wrong side
        if x_mid > f1[0]:
            switch = 1
            f1 = f1bbox

        # if F2 on wrong side:
        if x_mid < f2[0]:
            switch = 1
            f2 = f2bbox

    # case left -> F1-F2
    else:
        f1bbox = [fleftx, f1f2y]
        f2bbox = [frightx, f1f2y]

        # if F1 on wrong side
        if x_mid < f1[0]:
            switch = 1
            f1 = f1bbox

        # if F2 on wrong side:
        if x_mid > f2[0]:
            switch = 1
            f2 = f2bbox

    if switch:
        print('called F1F2 swap')

    return f1, f2, switch

def improve_t1t2(anno: dict, t1, t2, t7, t3, t4, use_mode=True):
    """build t1 / t2 if t1 or t2 failed"""
    # first we need to know if the leg is left or right
    left0right1 = get_left0_right1(anno)
    norm_t1t2 = get_difference(t1, t2)
    norm_t7t1 = get_difference(t7, t1)

    if use_mode:
        key1 = 'T_low'
        key2 = 'T_up'
    else:
        key1 = 'S'
        key2 = 'S'

    # check if the points are on the same side
    if 0.4 * norm_t7t1 > norm_t1t2:
        print('switch activated t1t2')
        # find which point is on the wrong side

        # right leg
        if left0right1:
            if t7[0] < t2[0]:
                print(t2)
                # move T2 "left"
                diffx = 0.5 * abs(t7[0] - t4[0])
                t2[0] = t7[0] - diffx
                print(t2)
                t2 = improve_key(anno, key1, t2, 0)
                print(t2)
            else:
                # move T1 "right"
                diffx = 0.5 * abs(t7[0] - t3[0])
                t1[0] = t7[0] + diffx
                t1 = improve_key(anno, key2, t1, 0)

        else:
            if t7[0] > t2[0]:
                # move T2 "right"
                diffx = 0.5 * abs(t7[0] - t4[0])
                t2[0] = t7[0] + diffx
                t2 = improve_key(anno, key2, t2, 0)
            else:
                # move T1 "left"
                diffx = 0.5 * abs(t7[0] - t3[0])
                t1[0] = t7[0] - diffx
                t1 = improve_key(anno, key2, t1, 0)

    return t1, t2

def improve_t3t4t5t6(anno: dict, t3, t4, t5, t6, t7):
    """catch error if t3 and t5 are both on the wrong side"""
    left0right1 = get_left0_right1(anno)
    norm_t3t7 = get_difference(t3, t7)
    norm_t3t4 = get_difference(t3, t4)
    norm_t5t6 = get_difference(t5, t6)

    # if all points have failed
    if 0.4 * norm_t3t7 > max(norm_t3t4, norm_t5t6):
        print('activated t3456 switch')
        # find which point is on the wrong side
        diffx = 2 * abs(t7[0] - t3[0])
        print(diffx)

        # right leg
        if left0right1:

            # t4 and 6 wrong
            if t4[0] > t7[0]:
                print('t4 and 6 wrong, right leg')
                t4[0] = t7[0] - diffx
                t4 = improve_key(anno, 'T_up', t4, 0)

                t6[0] = t7[0] - diffx
                t6 = improve_key(anno, 'T_up', t6, 0)

            # t3 and 5 wrong
            else:
                t3[0] = t7[0] + diffx
                t3 = improve_key(anno, 'T_up', t3, 0)

                t5[0] = t7[0] + diffx
                t5 = improve_key(anno, 'T_up', t5, 0)

        # left leg
        else:

            # t4 and 6 wrong
            if t4[0] < t7[0]:
                t4[0] = t7[0] + diffx
                t4 = improve_key(anno, 'T_up', t4, 0)

                t6[0] = t7[0] + diffx
                t6 = improve_key(anno, 'T_up', t6, 0)

            # t3 and 5 wrong
            else:
                t3[0] = t7[0] - diffx
                t3 = improve_key(anno, 'T_up', t3, 0)

                t5[0] = t7[0] - diffx
                t5 = improve_key(anno, 'T_up', t5, 0)

    return t3, t4, t5, t6

def get_tibia_midpoint(anno: dict, option=1, acc_boost=False):
    """
    option 0: T7
    option 1: T5 - 90° - T1 - MIDPOINT - T2 - 90° - T6
    option 2: T5 - 90° - T3 - MIDPOINT - T4 - 90° - T6
    """
    keyp = anno['T_low']['keypoints']

    # option 1 -> midpoint
    T1 = keyp_by_num(keyp, 1)  # medial bottom 1
    T2 = keyp_by_num(keyp, 2)  # lateral bottom 1
    T3 = keyp_by_num(keyp, 3)  # medial bottom 2
    T4 = keyp_by_num(keyp, 4)  # lateral bottom 2
    T5 = keyp_by_num(keyp, 5)  # medial
    T6 = keyp_by_num(keyp, 6)  # lateral

    keyp_up = anno['T_up']['keypoints']
    T7 = keyp_by_num(keyp_up, 1)  # medial bottom 1

    if acc_boost:
        T1 = improve_key(anno, 'T_up', T1)
        T2 = improve_key(anno, 'T_up', T2)
        T3 = improve_key(anno, 'T_up', T3)
        T4 = improve_key(anno, 'T_up', T4)
        T5 = improve_key(anno, 'T_up', T5)
        T6 = improve_key(anno, 'T_up', T6)

    T3, T4, T5, T6 = improve_t3t4t5t6(anno, T3, T4, T5, T6, T7)
    T1, T2 = improve_t1t2(anno, T1, T2, T7, T3, T4)

    # finally use option 2
    midpoint, medial, lateral = midpoint_calc(T5, T3, T4, T6)

    norm_t1t2 = get_difference(T1, T2)
    norm_t3t4 = get_difference(T3, T4)
    norm_t5t6 = get_difference(T5, T6)

    # t3t4 together
    if norm_t3t4 < 0.4 * norm_t1t2:
        print('t5-t1-t2-t6')
        midpoint, medial, lateral = midpoint_calc(T5, T1, T2, T6)
    # t5t6 together
    if norm_t5t6 < 0.4 * norm_t3t4:
        print('t3-t1-t2-t4')
        T4 = improve_lateral_tibia(anno, T4)
        midpoint, medial, lateral = midpoint_calc(T3, T1, T2, T4)
    # t3t4 and t5t6 together
    if norm_t5t6 < norm_t1t2 and norm_t3t4 < norm_t1t2:
        print('t1-t1-t2-t2')
        midpoint, medial, lateral = midpoint_calc(T1, T1, T2, T2)

    # option 0 -> F5
    if option == 0:
        midpoint = keyp_by_num(anno['T_up']['keypoints'], 1)

    if option == 1:
        midpoint, medial, lateral = midpoint_calc(T5, T1, T2, T6)

    return midpoint, medial, lateral

def improve_lateral_tibia(anno, lateral):
     # further get Fi3
    keyp_fi = anno['Fi_up']['keypoints']
    fi_3 = keyp_by_num(keyp_fi, 1)
    l0r1 = get_left0_right1(anno)

    # case right
    if l0r1 == 1:
        lateral[0] = max(lateral[0], fi_3[0])
    else:
        lateral[0] = min(lateral[0], fi_3[0])
    return lateral

def get_sprung_midpoint(anno: dict, option=1, acc_boost=False):
    """
    option 0: S5
    option 1: S3 - 90° - S1 - MIDPOINT - S2 - 90° - S4
    """
    keyp = anno['S']['keypoints']

    # option 0 -> F5
    if option == 0:
        return keyp_by_num(keyp, 5)

    # option 1 -> midpoint
    S1 = keyp_by_num(keyp, 1)  # medial bottom
    S2 = keyp_by_num(keyp, 2)  # lateral bottom
    S3 = keyp_by_num(keyp, 3)  # medial
    S4 = keyp_by_num(keyp, 4)  # lateral
    S5 = keyp_by_num(keyp, 5)  # center

    if acc_boost:
        S1 = improve_key_acc(anno, 'S', 1)
        S2 = improve_key_acc(anno, 'S', 2)
        S3 = improve_key_acc(anno, 'S', 3)
        S4 = improve_key_acc(anno, 'S', 4)
        S5 = improve_key_acc(anno, 'S', 5)

    norm_s1s2 = get_difference(S1, S2)
    norm_s3s4 = get_difference(S3, S4)
    norm_s3s5 = get_difference(S3, S5)

    # detect switches
    S1, S2 = improve_t1t2(anno, S1, S2, S5, S3, S4, use_mode=False)

    if norm_s3s4 > norm_s1s2:
        midpoint, medial, lateral = midpoint_calc(S3, S1, S2, S4)

        if norm_s3s5 > norm_s1s2:
            midpoint = S5

    else:
        midpoint, medial, lateral = midpoint_calc(S1, S1, S2, S2)

    return midpoint, medial, lateral

def get_anatomical_axis(anno: dict, key='A_up'):
    """
    A1-mid-A2
    A3-mid-A4
    """
    # decide whether the leg is left or right
    left0right1 = get_left0_right1(anno)

    bbox = anno[key]['bbox']
    if len(bbox) < 4:
        bbox = [0, 0, 0, 0]

    keyp = anno[key]['keypoints']
    A1, A2, A3, A4 = keyp_by_num(keyp, 1), keyp_by_num(
        keyp, 2), keyp_by_num(keyp, 3), keyp_by_num(keyp, 4)

    norm12 = get_difference(A1, A2)
    norm34 = get_difference(A3, A4)
    norm13 = get_difference(A1, A3)
    norm24 = get_difference(A2, A4)

    diffy12 = abs(A1[1] - A2[1])
    diffy34 = abs(A3[1] - A4[1])
    diffy13 = abs(A1[1] - A3[1])

    # case A1 or A3 failed
    if (diffy13 < diffy12) and (norm13 < norm12):
        # A3 failed
        if diffy12 < diffy34:
            A3 = [A1[0], A4[1]]
        # A1 failed
        else:
            A1 = [A3[0], A2[1]]

    diffy12 = abs(A1[1] - A2[1])
    diffy34 = abs(A3[1] - A4[1])
    diffy24 = abs(A2[1] - A4[1])

    # case A2 or A4 failed
    if (diffy24 < diffy34) and (norm24 < norm34):
        # A4 failed
        if diffy12 < diffy34:
            A4 = [A2[0], A3[1]]
        # A2 failed
        else:
            A2 = [A4[0], A1[1]]

    # case right
    if left0right1:
        diffa1 = abs(A1[0] - (bbox[0] + bbox[2]))
        diffa2 = abs(A2[0] - bbox[0])
        diffa3 = abs(A3[0] - (bbox[0] + bbox[2]))
        diffa4 = abs(A4[0] - bbox[0])

    # case left
    else:
        diffa1 = abs(A1[0] - bbox[0])
        diffa2 = abs(A2[0] - (bbox[0] + bbox[2]))
        diffa3 = abs(A3[0] - bbox[0])
        diffa4 = abs(A4[0] - (bbox[0] + bbox[2]))

    # case A1 or A2 failed
    if (norm12 < 0.14 * norm13):
        midx = (A1[0] + A2[0]) / 2
        midsum = abs(A1[0] - midx) + abs(A2[0] - midx)

        if midsum < 0.14 * bbox[2]:
            A2 = [bbox[0] + (1-left0right1) * bbox[2], A2[1]]

        # case A2 failed
        elif diffa1 < diffa2:
            A2 = [bbox[0] + (1 - left0right1) * bbox[2], A1[1]]
        # case A1 failed
        else:
            A1 = [bbox[0] + left0right1 * bbox[2], A2[1]]

    # case A3 or A4 failed
    if (norm34 < 0.14 * norm13):
        # case A4 failed
        if diffa3 < diffa4:
            A4 = [bbox[0] + (1 - left0right1) * bbox[2], A3[1]]
        # case A1 failed
        else:
            A3 = [bbox[0] + left0right1 * bbox[2], A4[1]]

    # further check x compatibility
    diffx12 = abs(A1[0] - A2[0])
    diffx13 = abs(A1[0] - A3[0])
    diffx34 = abs(A3[0] - A4[0])
    diffx24 = abs(A2[0] - A4[0])

    # case A1 or A2 failed
    if diffx12 < 0.14 * diffx34:
        # case A2 failed
        if diffx13 < diffx24:
            A2 = [A4[0], A2[1]]
        # case A1 failed
        else:
            A1 = [A3[0], A1[1]]

    # case A3 or A4 failed
    if diffx34 < 0.14 * diffx12:
        # case A3 failed
        if diffx24 < diffx13:
            A3 = [A1[0], A3[1]]
        # case A4 failed
        else:
            A4 = [A2[0], A4[1]]

    mid1 = get_mid(A1, A2)
    mid2 = get_mid(A3, A4)
    return [mid1, mid2]

def get_mechanical_axis_femur(anno_results: dict):
    """
    mid_h - (intersect mid_f with F1-F2)
    """
    med_f, lat_f = anno_results['med_f'], anno_results['lat_f']
    mid_h = anno_results['mid_h']
    mid_f = anno_results['mid_f']

    line1 = LineP1P2(mid_h, mid_f)
    line2 = LineP1P2(med_f, lat_f)
    new_mid_f = line1.intersect(line2)

    return new_mid_f

def get_mechanical_axis_tibia(anno_results: dict):
    """
    mid_s - (intersect mid_t with T1-T2)
    """
    med_t, lat_t = anno_results['med_t'], anno_results['lat_t']
    mid_s = anno_results['mid_s']
    mid_t = anno_results['mid_t']

    line1 = LineP1P2(mid_s, mid_t)
    line2 = LineP1P2(med_t, lat_t)
    new_mid_t = line1.intersect(line2)

    return new_mid_t

def alternative(a, b, c):
    """
    https://manivannan-ai.medium.com/find-the-angle-between-three-points-from-2d-using-python-348c513e2cd
    """
    # to numpy
    a, b, c = np.array(a), np.array(b), np.array(c)

    # the relevant vecors
    ba, bc = a - b, c-b

    # now the main calculus
    cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
    angle = np.arccos(cosine_angle)

    return np.degrees(angle)

def angle_between_points(a, b, c):
    return (math.atan2(c[1]-b[1], c[0] - b[0]) - math.atan2(b[1]-a[1], b[0] - a[0])) * (180 / math.pi)

def get_left0_right1(anno):
    """determine whether the leg is left(0) or right(1)"""
    mid_h = get_hip_midpoint(anno)

    # [x(left), y(top), width, height]
    bbox = anno['F_t']['bbox']

    if len(bbox) < 4:
        bbox = [0, 0, 0, 0]

    # determine whether hip is left or right:
    bbox_mid_x = bbox[0] + 0.5 * bbox[2]

    # case ft right:
    if bbox_mid_x > mid_h[0]:
        return 0  # left
    # case ft left
    else:
        return 1  # right

def improve_f_t(anno, anno_results):
    """if the difference between mid_h and f_t is too small -> use """
    mid_h = anno_results['mid_h']
    ft = keyp_by_num(anno['F_t']['keypoints'], 2)

    # [x(left), y(top), width, height]
    bbox = anno['F_t']['bbox']
    if len(bbox) < 4:
        bbox = [0, 0, 0, 0]

    # determine whether hip is left or right:
    bbox_mid_x = bbox[0] + 0.5 * bbox[2]

    # case ft right:
    if bbox_mid_x > mid_h[0]:
        ftbbox = [bbox[0] + bbox[2], ft[1]]
    # case ft left
    else:
        ftbbox = [bbox[0], ft[1]]

    # distance between hip and the detected ft point
    dist_h_ft = get_difference(mid_h, ft)
    dist_ft_ffbbox = get_difference(ft, ftbbox)

    # if dist between hip and ft is smaller than the two fts
    if dist_h_ft < dist_ft_ffbbox:
        print('called ft improvement')
        ft = ftbbox
        if 'F_t2' in anno.keys():
            print('using the other side as reference')
            ft2 = keyp_by_num(anno['F_t2']['keypoints'], 2)
            ft = [ftbbox[0], ft2[1]]

    return ft

def anno_calculation(overall_img, anno: dict, option=2, acc_boost=False, k_len=25):
    """perform all angle calculations"""
    anno_results = {}
    anno_results['img_shape'] = overall_img.shape
    anno_results['l0r1'] = get_left0_right1(anno)
    anno_results['lm1r1'] = 1 if anno_results['l0r1'] else -1

    # get the midpoints of each joint
    anno_results['mid_h'] = get_hip_midpoint(anno)
    anno_results['mid_f'], anno_results['med_f'], anno_results['lat_f'] = get_femur_midpoint(
        anno, option=option, acc_boost=acc_boost)
    anno_results['mid_t'], anno_results['med_t'], anno_results['lat_t'] = get_tibia_midpoint(
        anno, option=option, acc_boost=acc_boost)
    anno_results['mid_s'], anno_results['med_s'], anno_results['lat_s'] = get_sprung_midpoint(
        anno, option=option, acc_boost=acc_boost)

    # some relevant points:
    anno_results['f_t'] = improve_f_t(anno, anno_results)

    # get the axis
    anno_results['ana_f'] = get_anatomical_axis(anno, key='A_up')
    anno_results['ana_t'] = get_anatomical_axis(anno, key='A_low')
    anno_results['mid_f'] = get_mechanical_axis_femur(anno_results)
    anno_results['mid_t'] = get_mechanical_axis_tibia(anno_results)

    # combined angles
    anno_results['MAD'] = mad(anno_results, anno, k_len)  # yes
    anno_results['Mikulicz auf TP'] = load_tibia(anno_results, anno)  # yes

    # calculate the femur
    anno_results['mLPFA'] = mlpfa(anno_results, anno)  # yes
    anno_results['AMA'] = ama_f(anno_results, anno)  # yes
    anno_results['JLCA'] = jlca(anno_results)  # yes
    anno_results['aLDFA'] = aldfa(anno_results)  # yes
    anno_results['mLDFA'] = mldfa(anno_results)  # yes

    # tibia angles
    anno_results['mMPTA'] = mmpta(anno_results)  # yes
    anno_results['mLDTA'] = mldta(anno_results)  # yes
    anno_results['KJLO'] = kjlo(anno_results)  # yes

    # central angle
    anno_results['mFTA'] = mech_tibiofemoral(anno_results)  # yes

    return anno_results

def kjlo(anno_results: dict):
    """
    angle: line(med_t - lat_t) - line(horizontal)
    """
    # get the tibial line
    med_t = anno_results['med_t']
    lat_t = anno_results['lat_t']
    l_tibia = LineP1P2(med_t, lat_t)

    if med_t[1] > lat_t[1]:
        p1 = med_t
        p2 = lat_t
    else:
        p1 = lat_t
        p2 = med_t

    # get the horizontal line
    hor_1 = [p1[0], p1[1]]
    hor_2 = [p2[0], p1[1]]
    hor_line = LineP1P2(hor_1, hor_2)

    # get the interception
    intersect = l_tibia.intersect(hor_line)

    # get the angle
    kjlo = angle_from_vis(p2, intersect, hor_2)
    anno_results['kjlo_start'] = p2
    anno_results['kjlo_mid'] = intersect
    anno_results['kjlo_end'] = hor_2
    anno_results['kjlo_tpos'] = hor_2.copy()
    anno_results['kjlo_tpos'][1] += 300
    anno_results['kjlo'] = kjlo
    ensure_visibility(anno_results, 'kjlo_tpos')

    return kjlo

def mlpfa(anno_results: dict, anno: dict):
    """
    angle: mid_f -> mid_h -> F6
    """
    mid_f = anno_results['mid_f']
    mid_h = anno_results['mid_h']
    f_t = anno_results['f_t']

    mlpfa = angle_from_vis(mid_f, mid_h, f_t)

    anno_results['mlpfa_start'] = mid_f
    anno_results['mlpfa_mid'] = mid_h
    anno_results['mlpfa_end'] = f_t
    anno_results['mlpfa_tpos'] = mid_h.copy()
    anno_results['mlpfa_tpos'][1] += 300
    anno_results['mlpfa'] = mlpfa
    ensure_visibility(anno_results, 'mlpfa_tpos')

    return mlpfa

def mldfa(anno_results: dict):
    """
    angle: lat_f -> mid_f -> mid_h
    """
    mid_h = anno_results['mid_h']
    lat_f = anno_results['lat_f']
    mid_f = anno_results['mid_f']

    mldfa = angle_from_vis(lat_f, mid_f, mid_h)

    anno_results['mldfa_start'] = lat_f
    anno_results['mldfa_mid'] = mid_f
    anno_results['mldfa_end'] = mid_h
    anno_results['mldfa_tpos'] = mid_f.copy()
    anno_results['mldfa_tpos'][1] -= 600
    anno_results['mldfa_tpos'] = optimize_pos('mldfa_tpos', anno_results)
    anno_results['mldfa'] = mldfa
    ensure_visibility(anno_results, 'mldfa_tpos')

    return mldfa

def ama_f(anno_results: dict, anno: dict, use_f5=False):
    """
    anatomic mechanical angle femur
    h1 ->  intersection -> Atop
    """
    mid_h = anno_results['mid_h']
    mid_f = anno_results['mid_f']

    # alternative, not quite succesfull
    if use_f5:
        keyp = anno['F']['keypoints']
        f5 = keyp_by_num(keyp, 5)
        mid_f = f5

    line1 = LineP1P2(mid_h, mid_f)

    top_a = anno_results['ana_f'][0]
    bottom_a = anno_results['ana_f'][1]
    line2 = LineP1P2(top_a, bottom_a)

    inter = line1.intersect(line2)

    ama_f = abs(limit_angle(angle_between_points(mid_h, inter, top_a)))

    anno_results['ama_f_start'] = mid_h
    anno_results['ama_f_mid'] = inter
    anno_results['ama_f_end'] = top_a
    anno_results['ama_f_tpos'] = top_a.copy()
    anno_results['ama_f_tpos'][0] += 100
    anno_results['ama_f'] = ama_f
    ensure_visibility(anno_results, 'ama_f_tpos')

    return ama_f

def aldfa(anno_results: dict):
    """
    anatomic mechanical angle femur
    top_a ->  mid_f -> lat_f
    """
    top_a = anno_results['ana_f'][0]
    bottom_a = anno_results['ana_f'][1]
    line1 = LineP1P2(top_a, bottom_a)

    med_f = anno_results['med_f']
    lat_f = anno_results['lat_f']
    line2 = LineP1P2(med_f, lat_f)

    inter = line1.intersect(line2)

    aldfa = abs(limit_angle(angle_between_points(top_a, inter, med_f)))

    anno_results['aldfa_start'] = top_a
    anno_results['aldfa_mid'] = inter
    anno_results['aldfa_end'] = lat_f
    anno_results['aldfa_tpos'] = lat_f.copy()
    anno_results['aldfa_tpos'][1] -= 800
    anno_results['aldfa'] = aldfa
    ensure_visibility(anno_results, 'aldfa_tpos')

    return aldfa

def limit_angle(angle):
    """
    fit angle between -180 and 180 degrees
    """
    # case: 270 -> -90
    if angle > 180:
        angle = angle - 360

    # case: -270 -> 90
    if angle < -180:
        angle = angle + 360

    if angle < -90:
        angle = angle + 180

    if angle > 90:
        angle = angle - 180

    return angle

def jlca(anno_results: dict):
    """
    angle: F1-F2 <-> (T3-T4  or T1-T2)
    """
    lm1r1 = anno_results['lm1r1']
    med_f, lat_f = anno_results['med_f'], anno_results['lat_f']
    med_t, lat_t = anno_results['med_t'], anno_results['lat_t']
    mid_f, mid_t = anno_results['mid_f'], anno_results['mid_t']

    left_0_right_1 = 0
    if med_f[0] > lat_f[0]:
        left_0_right_1 = 1

    line1 = LineP1P2(med_f, lat_f)
    line2 = LineP1P2(med_t, lat_t)
    inter = line1.intersect(line2)

    sign = -1
    # right
    if left_0_right_1:
        if inter[0] > mid_t[0]:
            sign = 1
    # left
    else:
        if inter[0] < mid_t[0]:
            sign = 1

    jlca = sign * angle_from_vis(lat_f, inter, lat_t)

    # catch too small jlca
    if jlca < -150:
        jlca += 180
        jlca *= -1

    # include abs
    jlca = abs(jlca)

    anno_results['jlca_start'] = mid_f
    anno_results['jlca_mid'] = inter
    anno_results['jlca_end'] = mid_t
    anno_results['jlca_tpos'] = lat_f.copy()
    anno_results['jlca_tpos'][0] += lm1r1 * 200
    anno_results['jlca_tpos'][1] -= 450
    anno_results['jlca'] = jlca
    ensure_visibility(anno_results, 'jlca_tpos')

    return jlca

def mmpta(anno_results: dict):
    """
    angle: mid_s -> mid_t -> med_t
    """
    mid_s, mid_t, lat_t = anno_results['mid_s'], anno_results['mid_t'], anno_results['lat_t']
    med_t = anno_results['med_t']
    mmpta = angle_from_vis(mid_s, mid_t, med_t)
    lm1r1 = anno_results['lm1r1']

    anno_results['mmpta_start'] = mid_s
    anno_results['mmpta_mid'] = mid_t
    anno_results['mmpta_end'] = med_t
    anno_results['mmpta_tpos'] = med_t.copy()
    anno_results['mmpta_tpos'][1] += 500
    anno_results['mmpta_tpos'][0] -= lm1r1 * 250
    anno_results['mmpta'] = mmpta
    ensure_visibility(anno_results, 'mmpta_tpos')

    return mmpta

def mldta(anno_results: dict):
    """
    angle: mid_t -> mid_s -> lat_s
    """
    mid_t, mid_s, lat_s = anno_results['mid_t'], anno_results['mid_s'], anno_results['lat_s']
    mldta = angle_from_vis(mid_t, mid_s, lat_s)

    anno_results['mldta_start'] = mid_t
    anno_results['mldta_mid'] = mid_s
    anno_results['mldta_end'] = lat_s
    anno_results['mldta_tpos'] = lat_s.copy()
    anno_results['mldta_tpos'][0] -= 200
    anno_results['mldta_tpos'][1] -= 300
    anno_results['mldta'] = mldta
    ensure_visibility(anno_results, 'mldta_tpos')

    return mldta

def mad(anno_results: dict, anno: dict, k_len):
    """
    mikulicz line and the difference there
    """
    # first get the disctance for 25mm:
    keyp = anno['K']['keypoints']
    if len(keyp) > 5:
        K1, K2 = keyp_by_num(keyp, 1), keyp_by_num(keyp, 2)
        imgfac = k_len / get_difference(K1, K2)
        # use bounding box instead!
        if imgfac > 1e6:
            _, _, _, height_k = anno['K']['bbox']
            imgfac = k_len / height_k
    else:
        imgfac = 0

    if 'imgfac' in anno.keys():
        imgfac2 = anno['imgfac']
        if math.isnan(imgfac2):
            imgfac2 = 0
    else:
        imgfac2 = 0

    baseline = 0.14
    imgfac_ruler = imgfac2
    imgfac_sphere = imgfac
    facdiff1 = abs(imgfac - baseline) / baseline
    facdiff2 = abs(imgfac2 - baseline) / baseline

    if facdiff2 < facdiff1:
        imgfac = imgfac2

    if min(facdiff1, facdiff2) > 0.5:
        print('mad: warning: imgfac difference is too big, using baseline')
        print(imgfac_ruler)
        print(imgfac_sphere)
        print(imgfac)
        imgfac = baseline

    anno_results['imgfac'] = imgfac
    mid_h, mid_s, mid_t = anno_results['mid_h'], anno_results['mid_s'], anno_results['mid_t']
    mikulicz = LineP1P2(mid_h, mid_s)
    ortho_line_mikolicz = LineP1m(mid_t, mikulicz.ortho_m)
    intersect = mikulicz.intersect(ortho_line_mikolicz)
    miko_len = get_difference(mid_h, mid_s) * imgfac
    anno_results['Mikulicz'] = miko_len
    offset = get_difference(intersect, mid_t)

    # decide on signum
    med_t, lat_t = anno_results['med_t'], anno_results['lat_t']
    signum = 1
    diff1 = get_difference(intersect, med_t)
    diff2 = get_difference(intersect, lat_t)
    if diff2 < diff1:
        signum = -1

    return offset * imgfac * signum

def load_tibia(anno_results: dict, anno: dict):
    """
    percentage of load on tibia from 0% med to 100% lateral
    """
    left0_right1 = get_left0_right1(anno)

    mid_h, mid_s = anno_results['mid_h'], anno_results['mid_s']
    mikulicz = LineP1P2(mid_h, mid_s)

    med_t, lat_t = anno_results['med_t'], anno_results['lat_t']
    tibialine = LineP1P2(med_t, lat_t)

    intersect = mikulicz.intersect(tibialine)

    sign = 1

    if left0_right1 == 0 and intersect[0] < med_t[0]:
        sign = -1

    if left0_right1 == 1 and intersect[0] > med_t[0]:
        sign = -1

    load = sign * (get_difference(med_t, intersect) /
                   get_difference(med_t, lat_t)) * 100

    anno_results['miko_load'] = load
    anno_results['miko_inter'] = intersect
    anno_results['miko_inter_tpos'] = intersect.copy()
    ensure_visibility(anno_results, 'miko_inter_tpos')

    if load > 100 or load < 0:
        load = 0

    return load

def mech_tibiofemoral(anno_results: dict):
    """
    angle between both mechanical axis
    """
    mid_h, mid_f = anno_results['mid_h'], anno_results['mid_f']
    mid_t, mid_s = anno_results['mid_t'], anno_results['mid_s']

    fline = LineP1P2(mid_h, mid_f)
    tline = LineP1P2(mid_t, mid_s)

    intersect = fline.intersect(tline)
    load = anno_results['miko_load']

    signum = -1
    if load > 50:
        signum = 1

    mfta = signum * \
        abs(limit_angle(angle_between_points(mid_s, intersect, mid_h)))

    if intersect[1] > mid_t[1]:
        endp = mid_h.copy()
        startp = mid_t.copy()
    else:
        endp = mid_s.copy()
        startp = mid_f.copy()

    anno_results['mfta_start'] = startp
    anno_results['mfta_mid'] = intersect
    anno_results['mfta_end'] = endp
    anno_results['mfta_tpos'] = intersect.copy()
    anno_results['mfta_tpos'][0] -= 100
    anno_results['mfta_tpos'][1] += 200
    anno_results['mfta_tpos'] = optimize_pos('mfta_tpos', anno_results)
    anno_results['mfta'] = mfta
    ensure_visibility(anno_results, 'mfta_tpos')

    return mfta

def ensure_visibility(anno_results: dict, key: str, min_pos=200, max_pos=1000):
    """
    ensure that the keypoint is visible in the image
    """
    width = anno_results['img_shape'][1]
    pos = anno_results[key][0]

    if pos < min_pos:
        anno_results[key][0] = min_pos

    if (pos > (width - max_pos)):
        anno_results[key][0] = width - max_pos

def optimize_pos(key, anno_results: dict):
    """
    go trough all tpos and define if the current pos needs adaption
    """
    mypos = anno_results[key].copy()
    all_keys = anno_results.keys()
    pos_keys = [loc_key for loc_key in all_keys if '_tpos' in loc_key]
    pos_keys.remove(key)

    for diff in range(120, 0, -1):
        min_abs_diff = 1e8
        rel_pos = [0, 0]

        # get the minimal difference
        for key in pos_keys:
            other_pos = anno_results[key]
            if abs(mypos[1] - other_pos[1]) < min_abs_diff:
                min_abs_diff = abs(mypos[1] - other_pos[1])
                rel_pos = other_pos.copy()

        # move the current pos away from mindiff
        if min_abs_diff < 200:

            if rel_pos[1] > mypos[1]:
                mypos[1] -= diff
            else:
                mypos[1] += diff

    return mypos

# %%
if __name__ == '__main__':
    with open('../example_anno.json', 'r') as fp:
        anno = json.load(fp)

    anno_results = anno_calculation(None, anno)
    print(anno_results)
# %%


import basic as b
from random import sample

class Card():
    card_deck = []
    list_suit = ['H', 'D', 'S', 'C']  # H:Heart, D:Diamond, S:Spade, C:Club

    def get_card(self):
        player_card = sample(self.card_deck, 2)
        for item in player_card:
            self.card_deck.remove(item)
        return player_card

    def check_high_card(self, list_card, j=5):
        score = 0
        temp = b.get_list_card_number(list_card)
        temp = sorted(temp, reverse=True)
        if(temp.count(1) == 1):
            score += 14
            for i in range(4):
                temp[i] = int(temp[i])
                score += temp[i]
        else:
            for i in range(j):
                temp[i] = int(temp[i])
                score += temp[i]
        return score

    def check_pair(self, list_card):
        score = 0
        c = 2
        list_index = []
        temp = b.get_list_card_number(list_card)
        list_number =  b.get_list_number(temp)
        if(list_number.count(2) == 2):
            for i in range(len(temp)):
                if(temp.count(temp[i]) == 2):
                    if(int(temp[i]) == 1):
                        score += 88
                    else:
                        score += (c*(int(temp[i]) +28))
                    list_index.append(list_card[i])
            for index in list_index:
                list_card.remove(index)
            if (len(list_card) > 2):
                score += self.check_high_card(list_card, len(list_card) - 2)
        print('pair score:', score)
        return score

    def check_two_pair(self, list_card):
        score = 0
        c = 3
        temp = b.get_list_card_number(list_card)
        list_number =  b.get_list_number(temp)
        list_index = []
        if(list_number.count(2) >= 4):
            for i in range(len(temp)):
                number = temp[i]
                if(temp.count(number) == 2):
                    if(int(number) == 1):
                        score += 161
                    else:
                        score += (c*(int(number)+40)-1)
                    list_index.append(list_card[i])
            for index in list_index:
                list_card.remove(index)
            if (len(list_card) > 4):
                score += self.check_high_card(list_card, len(list_card) - 4)
        return score

    def check_set(self, list_card):
        temp = b.get_list_card_number(list_card)
        list_number =  b.get_list_number(temp)
        list_index = []
        score = 0
        c = 4
        if(list_number.count(3) == 3 and list_number.count(2) == 0):
            for i in range(len(temp)):
                number = temp[i]
                if(temp.count(number) == 3):
                    if(int(number) == 1):
                        score += 380
                    else:
                        score += (c*(int(number)+81))
                list_index.append(list_card[i])
            for index in list_index:
                list_card.remove(index)
            if (len(list_card) > 2):
                score += self.check_high_card(list_card, len(list_card) - 2)
        return score

    def check_quad(self, list_card):
        temp = b.get_list_card_number(list_card)
        list_number =  b.get_list_number(temp)
        score = 0
        c = 7
        list_index = []
        if(list_number.count(4) == 4):
            for i in range(len(temp)):
                number = temp[i]
                if(temp.count(number) == 4):
                    if(int(number) == 1):
                        score += 2214
                    else:
                        score += (c*(int(number)+302)+2)
                list_index.append(list_card[i])
            for index in list_index:
                list_card.remove(index)
            if (len(list_card) > 1):
                score += self.check_high_card(list_card, len(list_card) - 1)
        return score

    def check_full_house(self, list_card):
        temp = b.get_list_card_number(list_card)
        list_number =  b.get_list_number(temp)
        score = 0
        c = 15
        if(list_number.count(3) == 3 and list_number.count(2) == 2):
            for number in temp:
                if(temp.count(number) == 3):
                    if(int(number) == 1):
                        score += 2310
                    else:
                        score += ((int(number) + 140) * c)
                if(temp.count(number) == 2):
                    if(int(number) == 1):
                        score += 14
                    else:
                        score += int(number)
        return score

    def check_flush(self, list_card):
        temp1 = b.get_list_card_suit(list_card)
        temp2 = b.get_list_card_number(list_card)
        list_remove = []
        score = 0
        c = 6
        for suit in ['H', 'D', 'S', 'C']:
            if (temp1.count(suit) >= 5):
                for i in range(len(temp1)):
                    if (temp1[i] != suit):
                        index = temp2[i]
                        list_remove.append(index)
                for item in list_remove:
                    temp2.remove(item)
                temp2 = sorted(temp2, reverse=True)
                if(temp2.count(1) == 1):
                    score += 539
                    for i in range(4):
                        temp2[i] = int(temp2[i])
                        score += ((temp2[i]+76)*6 -1)
                else:
                    for i in range(5):
                        temp2[i] = int(temp2[i])
                        score += ((temp2[i]+76)*6 -1)
        return score

    def check_straight(self, list_card):
        score = 0
        c = 5
        temp = b.get_list_card_number(list_card)
        for i in range(len(temp)):
            temp[i] = int(temp[i])
        list_sorted = sorted(temp)
        if(len(list_sorted) >= 5):
            for i in range(len(list_sorted) - 4):
                if(list_sorted[i] == list_sorted[i + 4] - 4):
                    score += (c*(list_sorted[i] + 79) + 1)
                elif (list_sorted[0]== list_sorted[i + 1] - 9 == list_sorted[i + 4] - 12):
                    score += 446
        return score

    def check_straight_flush(self, list_card):
        temp1 = b.get_list_card_suit(list_card)
        temp = b.get_list_card_number(list_card)
        score = 0
        c = 9
        for suit in ['H', 'D', 'S', 'C']:
            if (temp1.count(suit) >= 5):
                for i in range(len(temp)):
                    temp[i] = int(temp[i])
                list_sorted = sorted(temp)
                if(len(list_sorted) >= 5):
                    for i in range(len(list_sorted) - 4):
                        if(list_sorted[i] == list_sorted[i + 4] - 4):
                            score += (c*(list_sorted[i] + 268) + 4)
                        elif (list_sorted[0]== list_sorted[i + 1] - 9 == list_sorted[i + 4] - 12):
                            score += 2506
        return score


from django.shortcuts import render
from .models import Room

# Create your views here.

home = [
    {'id':1, 'name':'Home One'},
    {'id':2, 'name':'Home Two'},
    {'id':3, 'name':'Home Three'},
]

roomData_niu = [
    {'id':1, 'name':'Frontend Developer'},
    {'id':2, 'name':'Backend Developer'},
    {'id':3, 'name':'Full Stack Developer'},
]

def home(request):
    roomData = Room.objects.all()
    print('---------')
    print(roomData)
    print('---------')
    context = {'roomData':roomData}
    return render(request, 'appPractice/home.html', context)

roomDetails = [
    {'id': 1, 'name':'Room One'},
    {'id': 2, 'name':'Room Two'},
    {'id': 3, 'name':'Room Three'},
]
def room(request, pk):
    roomName = None
    # context = {'roomData':roomData}
    # print('---------------')
    # print(pk)
    # print(int(pk))
    # print('---------------')
    # for i in roomData:
    #     print('---------------')
    #     print(i)
    #     print('---------------')
    #     if i['id'] == int(pk):
    #         roomName = i['name']
    roomName = Room.objects.get(id=pk)

    context = {'roomName':roomName}
    return render(request, 'appPractice/room.html', context)


from pathlib import Path
from typing import Optional, Type

from decouple import config
from langchain.callbacks.manager import CallbackManagerForToolRun
from langchain.tools import BaseTool
from pydantic import BaseModel, Field
from web3.middleware.geth_poa import geth_poa_middleware

from naturalchain.utils import NETWORKS, get_web3

class SmartContractDeployerToolInput(BaseModel):
    path_to_bytecode: str = Field(
        description="The path to the text file containing the bytecode of the smart contract"
    )
    network: NETWORKS = Field(
        description="The network to deploy the smart contract to."
    )

class SmartContractDeployerTool(BaseTool):
    name = "SmartContractDeployer"
    description = "Useful for deploying EVM-compatible smart contracts given a path to a file containing the bytecode and the network to deploy to. Returns the address of the deployed contract."
    args_schema: Type[BaseModel] = SmartContractDeployerToolInput

    def _run(
        self,
        path_to_bytecode: str,
        network: NETWORKS,
        run_manager: Optional[CallbackManagerForToolRun] = None,
    ) -> str:
        w3 = get_web3(network)
        # Load the bytecode as str
        with Path(path_to_bytecode).open("r") as f:
            bytecode = f.read()

        # Get the public address associated with the private key
        private_key = config("PRIVATE_KEY")
        public_address = w3.eth.account.privateKeyToAccount(private_key).address

        # Inject the PoA middleware to the w3 instance in case of a PoA network
        w3.middleware_onion.inject(geth_poa_middleware, layer=0)

        # Check if you have enough Ether
        balance = w3.eth.getBalance(public_address)
        if balance <= 0:
            raise ValueError(
                "Your account does not have enough balance to deploy a Smart Contract. Add some before proceeding."
            )

        # Estimate gas for deployment
        gas_estimate = w3.eth.estimateGas(
            {"from": public_address, "data": f"0x{bytecode}"}
        )

        # Get nonce
        nonce = w3.eth.getTransactionCount(public_address)
        # Get gas price
        gas_price = w3.eth.gasPrice

        # Prepare the transaction
        transaction = {
            "from": public_address,
            "gas": gas_estimate,
            "gasPrice": w3.eth.gasPrice,
            "data": f"0x{bytecode}",
            "nonce": nonce,
            "chainId": w3.eth.chainId,
        }

        # Sign the transaction
        signed_tx = w3.eth.account.signTransaction(transaction, private_key)

        # Send the transaction
        try:
            transaction_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        except ValueError as e:
            required_token = gas_estimate * gas_price
            raise ValueError(
                f"{e}. This operation required token: {required_token / 1e18}"
            )

        # Wait for the transaction receipt
        transaction_receipt = w3.eth.waitForTransactionReceipt(transaction_hash)

        # Get the contract address
        contract_address: str = transaction_receipt["contractAddress"]

        return contract_address

    async def _arun(
        self,
        description: str,
        run_manager: Optional[CallbackManagerForToolRun] = None,
    ) -> str:
        raise NotImplementedError("This tool does not support async mode.")

if __name__ == "__main__":
    tool = SmartContractDeployerTool()

    result = tool._run(
        path_to_bytecode="/Users/miguel/Developer/projects/naturalchain/smart_contracts/smart_contract_2023-05-13-11-09-42-bin",
        network="ethereum_sepolia",
    )

    print(result)


import dbus
import hexchat
import re

__module_name__ = 'AutoAFK'
__module_version__ = '0.2'
__module_author__ = 'Karol Babioch <karol@babioch.de>, Jens Reimann <jreimann@redhat.com>'
__module_description__ = 'Automatically change your nickname whenever you leave your computer.'

def get_networks():
    """Returns an unique list of networks currently connected to"""

    # Initialize networks
    networks = []

    # Get list of channels currently joined
    channels = hexchat.get_list("channels")

    # Iterate over all channels, get unique networks
    for channel in channels:

        # Check if network is unique
        if channel.network not in networks:

            networks.append(channel.network)

    return networks

def get_screensaver():
    """Try different addresses for getting a screensaver instance"""
    # Query D-Bus interface provided by GNOME
    bus = dbus.SessionBus()

    try:
        screensaver = bus.get_object('org.gnome.ScreenSaver', '/org/gnome/ScreenSaver')
        if screensaver:
            return dbus.Interface(screensaver, 'org.gnome.ScreenSaver')
    except:
        pass

    try:
        screensaver = bus.get_object('org.cinnamon.ScreenSaver', '/org/cinnamon/ScreenSaver')
        if screensaver:
            return dbus.Interface(screensaver, 'org.cinnamon.ScreenSaver')
    except:
        pass

    return None

# Global flags used by poll_dbus
# TODO Replace by proper OOP design (class)
away = False

def poll_dbus(userdata):
    """Checks whether the screensaver is active and invokes a name change. It
    uses the D-Bus interface provided by GNOME to detect whether the
    screensaver is currently active."""

    # Immediately return and re-schedule if plugin is disabled
    if not hexchat.get_pluginpref('autoafk_enabled'):

        return 1

    # Flag that indicates whether user is AFK and we changed the nick
    global away

    delay = hexchat.get_pluginpref('autoafk_delay')

    try:

        iface = get_screensaver()

        # Check whether screensaver is active and user has not been handled yet
        if iface and iface.GetActiveTime() > delay and not away:

            # Iterate over all networks
            for network in get_networks():

                nick = hexchat.get_info('nick')

                context = hexchat.find_context(server=network)
                context.command('NICK {0}{1}{2}'.format(hexchat.get_pluginpref('autoafk_prefix'), nick, hexchat.get_pluginpref('autoafk_suffix')))

            # Set global flags
            away = True

        elif iface and iface.GetActiveTime() == 0 and away:

            # Iterate over all networks
            for network in get_networks():

                nick = hexchat.get_info('nick')

                prefix = re.escape(hexchat.get_pluginpref('autoafk_prefix'))
                suffix = re.escape(hexchat.get_pluginpref('autoafk_suffix'))

                # Restore original nick using regular expressions
                nick = re.sub(r'(' + prefix + ')(?P<nick>.*)(' + suffix + ')', '\g<nick>', nick)

                context = hexchat.find_context(server=network)
                context.command('NICK {0}'.format(nick))

            # Mark user as back
            away = False

    except dbus.DBusException as e:

        print('AutoAFK: DBus exception: {}'.format(e))

    # Return 1 to keep timer in hexchat scheduler
    return 1

class SubcommandException(Exception):
    pass

def autoafk_help(word, word_eol, userdata):

    print('{0} module version {1} by {2}.'.format(__module_name__, __module_version__, __module_author__))
    print('')
    print('  Usage:')
    print('')
    print('    /AUTOAFK HELP                Outputs this usage help');
    print('    /AUTOAFK INFO                Outputs information about current state of addon');
    print('    /AUTOAFK ON|OFF              Turns this addon on or off (default is on)');
    print('    /AUTOAFK DELAY <seconds>     Waits given amount of seconds before considering you to be AFK (default is 0)');
    print('    /AUTOAFK PREFIX <prefix>     Puts a prefix in front of your nick when being AFK (default is empty)');
    print('    /AUTOAFK SUFFIX <suffix>     Attaches suffix to your nick when being AFK (default is |AFK)');
    print('')

# Text decorations
TEXT_BOLD = '\002'
TEXT_COLOR = '\003'
TEXT_HIDDEN = '\010'
TEXT_UNDERLINE = '\037'
TEXT_ORIGINAL = '\017'
TEXT_REVERSE_COLOR = '\026'
TEXT_BEEP = '\007'
TEXT_ITALIC = '\035'

def autoafk_info(word, word_eol, userdata):

    enabled = hexchat.get_pluginpref('autoafk_enabled')
    delay = hexchat.get_pluginpref('autoafk_delay')
    prefix = hexchat.get_pluginpref('autoafk_prefix')
    suffix = hexchat.get_pluginpref('autoafk_suffix')

    print('')
    print('AutoAFK:')
    print('')
    # TODO Use decorate function
    print('Status:  ' + TEXT_ITALIC + TEXT_BOLD + ('enabled' if enabled else 'disabled'))
    print('Delay:   ' + TEXT_ITALIC + TEXT_BOLD + str(delay) + TEXT_ORIGINAL + ' seconds')
    print('Prefix:  ' + (TEXT_ITALIC + TEXT_BOLD + prefix if len(prefix) > 0 else TEXT_ITALIC + 'disabled'))
    print('Suffix:  ' + (TEXT_ITALIC + TEXT_BOLD + suffix if len(suffix) > 0 else TEXT_ITALIC + 'disabled'))
    print('')

def autoafk_on(word, word_eol, userdata):

    hexchat.set_pluginpref('autoafk_enabled', True) # TODO Evaluate return value
    print('AutoAFK: Addon enabled.')

def autoafk_off(word, word_eol, userdata):

    hexchat.set_pluginpref('autoafk_enabled', False) # TODO Evaluate return value
    print('AutoAFK: Addon disabled.')

def autoafk_delay(word, word_eol, userdata):

    if len(word) < 2:

        raise SubcommandException('No argument provided')

    try:

        delay = int(word[1])
        hexchat.set_pluginpref('autoafk_delay', delay) # TODO Evaluate return value
        print('AutoAFK: Delay set to ' + str(delay) + ' seconds.')

    except ValueError:

        raise SubcommandException('Invalid delay specified')

def autoafk_prefix(word, word_eol, userdata):

    if len(word) < 2:

        prefix = ''

    else:

        prefix = word[1]

    hexchat.set_pluginpref('autoafk_prefix', prefix) # TODO Evaluate return value
    print('AutoAFK: Prefix set: ' + (TEXT_ITALIC + TEXT_BOLD + prefix if len(prefix) > 0 else TEXT_ITALIC + 'disabled'))

def autoafk_suffix(word, word_eol, userdata):

    if len(word) < 2:

        suffix = ''

    else:

        suffix = word[1]

    hexchat.set_pluginpref('autoafk_suffix', suffix) # TODO Evaluate return value
    print('AutoAFK: Suffix set: ' + (TEXT_ITALIC + TEXT_BOLD + suffix if len(suffix) > 0 else TEXT_ITALIC + 'disabled'))

def autoafk(word, word_eol, userdata):

    # Dispatch table for subcommands
    subcmds = {

        'HELP': autoafk_help,

        'INFO': autoafk_info,

        'ON': autoafk_on,
        'OFF': autoafk_off,

        'DELAY': autoafk_delay,

        'PREFIX': autoafk_prefix,
        'SUFFIX': autoafk_suffix,

    }

    # Check if there is a valid subcommand
    if len(word) > 1 and word[1] in subcmds:

        # Remove first elements (since we are consuming them here)
        word.pop(0)
        word_eol.pop(0)

        try:

            # Invoke function for subcommand
            subcmds[word[0]](word, word_eol, userdata)

        except SubcommandException as e:

            print('AutoAFK: ' + e.args[0])

    else:

        print('AutoAFK: Invalid command. Consult the output of /AUTOAFK HELP for a list of available commands')

    return hexchat.EAT_ALL

# Register hooks
hexchat.hook_timer(1000, poll_dbus)
hexchat.hook_command('AUTOAFK', autoafk, help='Use /AUTOAFK HELP for a more detailed description of available commands')

# Set default preferences if not yet set
if not hexchat.get_pluginpref('autoafk_enabled'):
    hexchat.set_pluginpref('autoafk_enabled', True) # TODO Evaluate return value

if not hexchat.get_pluginpref('autoafk_delay'):
    hexchat.set_pluginpref('autoafk_delay', 0) # TODO Evaluate return value

if not hexchat.get_pluginpref('autoafk_prefix'):
    hexchat.set_pluginpref('autoafk_prefix', '') # TODO Evaluate return value

if not hexchat.get_pluginpref('autoafk_suffix'):
    hexchat.set_pluginpref('autoafk_suffix', '|AFK') # TODO Evaluate return value

# Print message once everything is set up and loaded
print('{0} module version {1} by {2} loaded.'.format(__module_name__, __module_version__, __module_author__))


#!/usr/bin/python3

"""
实现计算求最大公约数和最小公倍数的函数

version: 0.1
author: icro
"""

def gcd(x, y):
    (x, y) = (y, x) if x > y else (x, y)
    for factor in range(x, 0, -1):
        if x % factor == 0 and y % factor == 0:
            return factor

def lcm(x, y):
    return x * y // gcd(x, y)

if __name__ == '__main__':
    x = int(input('x = '))
    y = int(input('y = '))
    print('%d, %d的最大公约数是%d' % (x, y, gcd(x, y)))
    print('%d, %d的最小公倍数是%d' % (x, y, lcm(x, y)))


# -*- coding: utf-8 -*-

from django.http import Http404
from django.views.generic import RedirectView
from services.models import Service

class ZoomMeetingRedirect(RedirectView):
    def get_redirect_url(self):
        service = (
            Service.objects.select_related("zoom_meeting")
            .exclude(zoom_meeting_id=None)
            .order_by("-datetime")
            .first()
        )
        if not service:
            raise Http404
        return service.zoom_meeting.zoom_link

class YouTubeServiceRedirect(RedirectView):
    def get_redirect_url(self):
        service = (
            Service.objects.select_related("youtube_stream")
            .exclude(youtube_stream_id=None)
            .order_by("-datetime")
            .first()
        )
        if not service:
            raise Http404
        return service.youtube_stream.object_url


"""
Max Sum Contiguous Sub array

https://www.interviewbit.com/problems/max-sum-contiguous-subarray/

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example:

Given the array [-2,1,-3,4,-1,2,1,-5,4],

the contiguous subarray [4,-1,2,1] has the largest sum = 6.

For this problem, return the maximum sum.

"""

class Solution(object):
	# @param A : tuple of integers
	# @return an integer
	def maxSubArray(self, A):
		preMax = A[0]
		ans = A[0]

		for i in xrange(1, len(A)):
			preMax = max(A[i], A[i]+preMax)
			ans = max(ans, preMax)

		return ans


# Imports necessary packages
import random
from threading import Event

# Defines starting variables
questionDone = 0
gameFinished = 0
counter = 0
stockList = ["NFLX", "MSFT", "TSLA", "AMZN", "AAPL", "META", "GOOG", "INTC", "NVDA", "DJI", "DIS"]
randStockList = []
priceList = []
stockAmount = 0
walletBalance = 100

# Chooses 5 random stocks from the stockList
while counter <= 4:
    randomInt = random.randint(0,(len(stockList)- 1))
    randStock = stockList[randomInt]
    if randStock not in randStockList:
        randStockList.append(stockList[randomInt])
        counter += 1
counter = 0

# Chooses a random price for each stock
while counter != (len(randStockList)):
    randomPrice = random.randrange(1, 101)
    priceList.append(randomPrice)
    counter += 1
counter = 0

# Sets out the rules
print("\n * Hello and welcome to Finn's Stock Picker! You have $100 and you can pick any",len(randStockList),"stocks, after each turn the stocks will change in value randomly and you can sell your stock and buy more if you want. See how much you can earn! *\n")
Event().wait(4)

# Displays the stock options and values
print(" * The stocks you can choose from are: *")
while counter != (len(randStockList)):
    print(randStockList[counter],": $",priceList[counter],"\n")
    counter += 1
counter = 0

# Asks user what stock they want
while questionDone == 0:
    stockPick = str(input(" * What stock do you wish to buy? *\n")).upper()
    if stockPick in randStockList:
        stockNumber = randStockList.index(stockPick)
        stockAmount = round(walletBalance / priceList[stockNumber],4)
        print("\nYou have bought:",stockAmount,"Shares in",stockPick,"\n")
        questionDone += 1
    else:
        # Displays error
        print("\n* ",stockPick," Is not a valid answer *\n")
questionDone = 0

while gameFinished == 0:
    # Changes stock values
    Event().wait(2)
    while counter != (len(randStockList)):
        randomChange = round(random.uniform(-0.20, 2.50),2)
        priceList[counter] = priceList[counter] * randomChange
        counter += 1
    counter = 0

    # Displays the new stock values
    print(" * The new stock values are: *")
    while counter != (len(randStockList)):
        print(randStockList[counter],": $",priceList[counter],"\n")
        counter += 1
    counter = 0

    # Displays current portfolio value
    Event().wait(2)
    portfolio = round(stockAmount * priceList[stockNumber],4)
    print("You have",stockAmount,"Shares in",stockPick,", Which are now worth: $",portfolio,"\n")

    if portfolio <= 0:
        print("\n * Oh no! It looks like you have gone bankrupt! *\n")
        Event().wait(2)
        quit()

    # Asks user if they want to sell?
    while questionDone == 0:
        Event().wait(1.5)
        yesOrNo = str(input(" * Would you like to sell your shares and buy different ones? Y/N *\n")).upper()
        if yesOrNo == "Y":
            # Sells current stock
            walletBalance = portfolio
            stockAmount = 0

            question2Done = 0
            while question2Done == 0:
                # Asks user for new stock input
                print(" * You have: $",walletBalance," *\n")
                stockPick = str(input(" * What stock would you like to buy? *\n")).upper()
                if stockPick in randStockList:
                    stockNumber = randStockList.index(stockPick)
                    if priceList[stockNumber] >= 0:
                        stockAmount = round(walletBalance / priceList[stockNumber],4)
                        print("\nYou have bought:",stockAmount,"Shares in",stockPick,"\n")
                        question2Done += 1
                    else:
                        # Displays error
                        print("\n * This stock's value is too low to buy, please choose another *\n")

                else:
                    # Displays error
                    print("\n* ",stockPick," Is not a valid answer *\n")
            question2Done = 0
            questionDone = 1

        elif yesOrNo =="N":
            # Asks user if they want to end the game
            question2Done = 0
            while question2Done == 0:
                gameEnd = str(input(" * Would you like to close the game? Y/N *\n")).upper()
                if gameEnd == "Y":
                    # Quits game
                    print(" * You had : $",portfolio,"! *")
                    Event().wait(2)
                    quit()

                elif gameEnd == "N":
                    question2Done = 1

                else:
                    # Displays error
                    print("\n* ",gameEnd," Is not a valid answer *\n")
            question2Done = 0
            questionDone = 1

        else:
            # Displays error
            print("\n* ",yesOrNo," Is not a valid answer *\n")
    questionDone = 0


# removes words which are different by suffixes from the list

fname = 'corncob_caps.txt'
# assumes word list is sorted

suffixes = ['S'] # other suffixes like -ing are ok.. but this seriously hurts

words = set()

def rtrim(string, wordarray):
	for i in wordarray:
		if string.endswith(i):
			return string[:-1 * len(i)]
	return string

with open(fname) as f:
	for line in f:
		if not line[:-1].isalpha():
			continue
		line = line.strip() # remove \n
		trimline = rtrim(line, suffixes)
		if trimline not in words:
			words.add(line)

out = '\n'.join( sorted(words) )
open(fname + '.txt', 'w').write(out)


import discord
from discord.ext import commands
from time import sleep
from discord.utils import get
from discord.ext.commands import Bot
import csv
import re
from discord.ext.commands import has_permissions

Words = []
Wdir = ('./BWords.txt')

class BlacklistedWords(commands.Cog):
    '''Automod Blacklisted Words'''
    def __init__ (self, bot):
        self.bot = bot
        self.words = Words

    @commands.Cog.listener()
    async def on_ready(self):
        self.words = {}
        with open(Wdir, 'r') as txt:
             Words = txt.read().strip().split(',')
        print(f'Blacklisted {Words}')

    @commands.command()
    @has_permissions(manage_messages=True)
    async def Blacklist(self, ctx, arg):
        with open(Wdir, 'w+') as txt:
            Words = txt.read().strip().split(', ')
            Words.append(arg)
            txt.write(Words)
        print(Words)
        print(f'Blacklisted word {arg}')
        await ctx.send(f'You have blacklisted the word {arg}. If you would like to undo this, run db!whitelist {arg}.')
    @Blacklist.error
    async def BlacklistError(self, ctx, arg):
        await ctx.send('You do not have permission to do this. You must have Manage_Messages permission.')

    @commands.command()
    @has_permissions(manage_messages=True)
    async def Whitelist(self, ctx, arg):
        try:
            with open(Wdir, 'w') as txt:
                Words = txt.read().strip().split(', ')
                if arg in Words:
                    for arg in Words:
                        Words.remove(arg)
                        await ctx.send(f'Whitelisted {arg}')
                else:
                    await ctx.send(f'{arg} is not a blacklisted word.')
        except:
            await ctx.send(f'Unable to whitelist {arg}. Please contact me.')

        else:
            await ctx.send(f'{arg} is not a blacklisted word. This command is used to un-blacklist commands from the automod.')
    @Whitelist.error
    async def WhitelistError(self, ctx, arg):
        await ctx.send('You do not have permission to do this. You must have Manage_Messages permission.')

def setup(bot):
    bot.add_cog(BlacklistedWords(bot))


import scipy.stats as sp
import math

rrf = None
upsidedown = False

def compute_roles(C, level, hybrid, debug=False):
    if debug: print(f"... {level} {C}")

    counter_roles = dict()

    index = 0 if upsidedown else -1

    if debug: print(f"..... ag {index} {C.intersection(rrf.Pi[index][1])}")

    for s in C.intersection(rrf.Pi[index][1]):
        for r in rrf.get_expect_roles(s):
            val = counter_roles.get(r, 0)
            counter_roles[r] = val + 1

    C_prime = C.difference(rrf.L)

    coalition_roles = {r:0 for r in counter_roles}

    for ag in C_prime:
        for r in rrf.get_roles(ag):
            if hybrid and len(counter_roles) == 0:
                coalition_roles[r] = coalition_roles.get(r, 0) + 1
                continue

            if r in counter_roles: # from the first relative level
                coalition_roles[r] += 1

    if debug: print(f".....counter roles {counter_roles}")
    if debug: print(f".....counter coalition {dict(coalition_roles)}")

    return counter_roles, coalition_roles

def disturbance_entropy(C, level, hybrid, debug=False):
    required_roles, roles_in_coalition = compute_roles(C, level, debug)

    if hybrid:
        if len(roles_in_coalition) == 1:
            return 0

        total_p = sum(roles_in_coalition.values())
        if total_p == 0: # coalition has only a superior
            return 1

        p = [v/total_p for v in roles_in_coalition.values()]

        entropy = 1 - sp.entropy(pk=p) / math.log(len(p))
    else:
        if len(required_roles)==1:
            return 0

        if  len(required_roles)==0 or len(roles_in_coalition) == 0:
            return 1

        list_of_roles = required_roles.keys()

        total_p, total_q = sum(roles_in_coalition.values()), sum(required_roles.values())

        if total_p == 0:
            return 1

        q = [required_roles[r]/total_q for r in list_of_roles]
        p = [roles_in_coalition.get(r, 0)/total_p for r in list_of_roles]

        entropy = sp.entropy(pk=p, qk=q) / math.log(len(q))

    if debug: print(f".....entropy {entropy}")

    return entropy

def relationship(C, level, hybrid, debug=False):
    if len(C) == 1:
        return 0

    value, samples = 0, 0

    if hybrid:
        C_prime = C
        l_C = list(C)
        for i, a1 in enumerate(l_C):
            for a2 in l_C[i+1:]:
                value += rrf.get_rel(a1, a2)
                samples += 1
    else:
        pivotal_agents = C.intersection(rrf.Pi[level][1])

        if len(pivotal_agents) == 0:
            if debug: print(f"....no superior to compute relationship")
            return 0

        C_prime = C.difference(pivotal_agents)

        for p in pivotal_agents:
            for ag in C_prime:
                value += rrf.get_rel(p, ag)
                samples += 1

    if debug: print(f"....relationship {value} {samples} {len(C_prime)}")

    return value / samples

def v_1(C, level, hybrid=False, debug=False):
    entropy = disturbance_entropy(C, level, hybrid, debug)
    relation = relationship(C, level, hybrid, debug)

    return len(C) * (relation - entropy)


def solution(routes):
    answer = 0

    routes.sort(key=lambda x: x[0], reverse=True)

    while routes:
        camera = min(routes, key=lambda x: x[1])[1]
        while routes[-1][0] <= camera:
            routes.pop()
            if not routes:
                break
        answer += 1

    return answer


#!/usr/bin/python3

def safe_print_list(my_list=[], x=0):
    try:
        count = 0

        for i in range(x):
            print("{:d}".format(my_list[i]), end='')
            count += 1
        print("\n")
        return count
    except IndexError:
        count = 0
        for _ in my_list:
            count += 1
        return count


'''
jak wysłać wyjątek?
    raise Exception('text')
wer 2  zad-42-2.py
 łapie wyjątek ale ponieważ jest wewnątrz pętli pozwala pracować ddalej do końca pętli
 czyli zbierze całą baze
 łapanie wyjątków jest lepsze od QUIT ponieważ umożliwia nam wykonanie jakiejś czynności kończącej np:
 zamkniećie połączenia z bazą danych ! zapis danych itp

Możemy twożyć własne wyjątki:
class ValueToSmall(Exception):
    pass : tu oczywiście właściwy kod

'''
try:
    while True:
        value = int(input('Podaj liczbę: '))
        if not value % 5 == 0:
            raise Exception('nie podzielna przez 5 ')

        print(value)
except Exception as e:
    print(e)


import os

from pandas_profiling import ProfileReport

from global_vars import DIABETES_PATH, GERMAN_CREDIT_PATH
from preprocessing_utils import gather_numeric_and_categorical_columns, read_arff_file_as_dataframe

# load diabetes file into DataFrame
from utils import tsne

df = read_arff_file_as_dataframe(DIABETES_PATH)
# Gather numeric and categorical columns into a list
numeric_columns, categorical_columns = gather_numeric_and_categorical_columns(df)
# iterate over all categorical columns and convert decode to string
df = df.apply(lambda col: col.str.decode(encoding='UTF-8') if col.name in categorical_columns else col)

diabetes_output_file = 'diabetes_eda_report.html'
if not os.path.exists(diabetes_output_file):
    design_report = ProfileReport(df)
    design_report.to_file(output_file=diabetes_output_file)

# diabetes tsne
tsne(df, categorical_columns, hue='class', filename='diabetes_tsne', save_figure=True)

# load german credit file into DataFrame
df = read_arff_file_as_dataframe(GERMAN_CREDIT_PATH)
# Gather numeric and categorical columns into a list
numeric_columns, categorical_columns = gather_numeric_and_categorical_columns(df)
# iterate over all categorical columns and convert decode to string
df = df.apply(lambda col: col.str.decode(encoding='UTF-8') if col.name in categorical_columns else col)

german_credit_output_file = 'german_credit_eda_report.html'
if not os.path.exists(german_credit_output_file):
    design_report = ProfileReport(df)
    design_report.to_file(output_file=german_credit_output_file)

# german_credit tsne
tsne(df, categorical_columns, hue='21', filename='german_credit_tsne', save_figure=True)


from moviepy.editor import *
from math import exp
import cv2
import numpy as np

def parse(clipName):
    clip = VideoFileClip(clipName).subclip(0,120)
    grey_frams=[]
    images=[]
    window=np.array(list())

    for frames in clip.iter_frames():
        im=cv2.cvtColor(frames,cv2.COLOR_RGB2GRAY)
        images.append(im)
        gf=np.matrix(im)
        grey_frams.append(gf)
    grey_frams=np.array(grey_frams)

    return (grey_frams,images)


##Ejercicio 1
# Cual es la complejidad del codigo?
#
# Entrada:
# -
# Salida:
'''
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
'''
# Lo que evidencia qque la complejidad de ese for es de n
# O(n)
#
# Autor:  Yeimy Huanca

n=10
for i in range(n):
    print (i+1)


import random
numberOfStreaks = 0
coinList = []

def coinFlip():
    flip = random.randint(0,1)
    if flip == 0:
        return 0
    else:
        return 1

for experimentNumber in range(10000):
    # lista com 100
    for flips in range(100):
        coinList.append(coinFlip()) # adiciona os resultados da função chamada já dentro do append pra lista

    # checkar os streaks
    streak = 0
    for coin in range(len(coinList)- 1):
        if coinList[coin] == coinList[coin + 1]: # compara o número com o próximo
            streak += 1
            if streak == 5: # repetiu 5x APÓS o 1o (6 numeros)
                numberOfStreaks += 1
                streak = 0
                break
        else:
            streak = 0
    coinList = [] # reseta a lista pra analisar uma nova
print('Chance of streak: %s%%' % (numberOfStreaks / 100))


#!/usr/bin/python3
import socket, os, pygame, copy, sys
from pygame.locals import *
import numpy as np

s = socket.socket()
host = '127.0.0.1'
port = 9999

# init pygame
pygame.init()
pygame.mixer.init()

#顏色
background = (194, 157, 91)
checkerboard = (80, 80, 80)
button = ( 52, 53, 44)

currentPlayer = 0   # you
nextPlayer = 0      # the other player of the game
allow = False       # check is your turn or not
running = True        # check can u keep playing game or not

# draw the whoke chessboard
def Draw_a_chessboard(screen):
    # fill background
    screen.fill(background)
    # draw chessboard
    for i in range(21):
        pygame.draw.line(screen, checkerboard, (40*i+3, 3), (40*i+3, 803))
        pygame.draw.line(screen, checkerboard, (3, 40*i+3), (803, 40*i+3))
    # draw lines
    pygame.draw.line(screen, checkerboard, (3, 3), (803, 3),5)
    pygame.draw.line(screen, checkerboard, (3, 3), (3, 803),5)
    pygame.draw.line(screen, checkerboard, (803, 3), (803, 803),5)
    pygame.draw.line(screen, checkerboard, (3, 803), (803, 803),5)

    # draw dots
    pygame.draw.circle(screen, checkerboard, (163, 163), 6)
    pygame.draw.circle(screen, checkerboard, (163, 403), 6)
    pygame.draw.circle(screen, checkerboard, (163, 643), 6)
    pygame.draw.circle(screen, checkerboard, (643, 163), 6)
    pygame.draw.circle(screen, checkerboard, (643, 403), 6)
    pygame.draw.circle(screen, checkerboard, (643, 643), 6)
    pygame.draw.circle(screen, checkerboard, (403, 163), 6)
    pygame.draw.circle(screen, checkerboard, (403, 403), 6)
    pygame.draw.circle(screen, checkerboard, (403, 643), 6)

    # set font
    s_font=pygame.font.Font('Anonymice Powerline Bold.ttf',28)

# draw chess
def Draw_a_chessman( x, y, screen, color):
    print("x, y, color = ", x, y, screen, color)
    if color == 1:
        Black_chess = pygame.image.load("Black_chess.png").convert_alpha()
        screen.blit(Black_chess,(40 * x + 3 - 15,40 * y + 3 - 15))
    if color == 2:
        White_chess = pygame.image.load("White_chess.png").convert_alpha()
        screen.blit(White_chess,(40 * x + 3 - 15, 40 * y + 3 - 15))

# create chessboard array
map=[]
for i in range(24):
    map.append([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])

# init chessboard array
def clear():
    global map
    for i in range(24):
        for j in range(24):
            map[i][j]=0

# start client
def start_client():
    global currentPlayer, nextPlayer, allow
    try:
        s.connect((host, port))
        print("Connected to :", host, ":", port)
        playerNum = s.recv(2048 * 10).decode()
        # check is player one or player two
        if playerNum == '1':
            allow = True
            currentPlayer = 1
            nextPlayer = 2
        else:
            allow = False
            currentPlayer =2
            nextPlayer = 1
        start_game()
        s.close()
    except socket.error as e:
        print("Socket connection error:", e)

# print end of msg
def end_of_game(screen):
    global allow, running
    # set screen background
    screen.fill(background)
    # set last msg
    if not allow:
        s = "you win!"
        allow = not(allow)
    else:
        s = "you lose"
        allow = not(allow)
    x = 30
    s_font=pygame.font.Font('Anonymice Powerline Bold.ttf',x)
    s_text=s_font.render(s,True,button)
    screen.blit(s_text,(340, 380))
    pygame.display.flip()
    # stop the game
    running=False

def start_game():
    global map, running,maps, r, h, currentPlayer, nextPlayer, allow
    # init game
    clear()
    # u
    map2=copy.deepcopy(map)
    maps=[map2]

    # set screen
    screen = pygame.display.set_mode([806,806])
    # set screen name
    pygame.display.set_caption("五子棋")

    # draw chessboard
    Draw_a_chessboard(screen)
    pygame.display.flip()
    clock=pygame.time.Clock()

    while True:
        win = False
        for event in pygame.event.get():
            # exit
            if event.type ==pygame.QUIT:
                pygame.quit()
                sys.exit()

            # if its your turn
            elif running and allow == 1 and event.type == MOUSEBUTTONDOWN:
                if event.button == 1:
                    x,y=event.pos[0],event.pos[1]
                    for i in range(19):
                        for j in range(19):
                            # choose a place
                            if i*40+3+20<x<i*40+3+60 and j*40+3+20<y<j*40+3+60 and not map[i][j] and running:
                                coordinates = str(i) + "," + str(j)
                                # draw your chosen chess
                                Draw_a_chessman(i+1,j+1,screen,currentPlayer)
                                # record it into chessboard array
                                map[i][j]=currentPlayer

                                # u
                                map3=copy.deepcopy(map)
                                maps.append(map3)
                                # send the chosen place to server
                                s.send(coordinates.encode())
                                # check if current player win or not
                                win = s.recv(1024).decode()
                                pygame.display.flip()
                    # give the permission to another one
                    allow = not(allow)
            # if its not your turn
            elif running and not allow:
                data = s.recv(1024)
                dataDecoded = data.decode().split(",")
                # draw the chess of another player
                x = int(dataDecoded[0])
                y = int(dataDecoded[1])
                win = dataDecoded[2]
                Draw_a_chessman(x+1,y+1,screen,nextPlayer)
                # record it inot checkboard array
                map[x][y]=nextPlayer
                # u
                map3=copy.deepcopy(map)
                maps.append(map3)
                # get the permission
                allow = not(allow)
                pygame.display.flip()

            # check if win or not
            if win == "1":
                end_of_game(screen)

        clock.tick(60)

start_client()


from flask import Response
from util import get_db_cursor
from app import app

@app.route('/geojson/<bbox>')
def geojson(bbox):
    args = map(float, bbox.split(','))
    with get_db_cursor() as cursor:
        cursor.execute("""select ST_AsGeoJSON(geom) as json, hoofdgrs from soil
                          where geom && ST_MakeEnvelope(%s, %s, %s, %s, 4326)""", args)
        # Insert "properties" element inside geojson string
        features = [row['json'][:-1] + ',"properties" : {"soil": "%s"}}' % row['hoofdgrs']
                        for row in cursor.fetchall()]

    return Response('{"type": "FeatureCollection", "features": [%s]}' % ','.join(features),
                    status=200, mimetype='application/json')


import os

import matplotlib
matplotlib.use('PDF')
import matplotlib.cm as cm
import matplotlib.pyplot as plt
from sklearn.lda import LDA
import numpy as np
from collections import defaultdict
from scipy.spatial.distance import cdist

from recognit import load
from recognit import pca
from recognit import predict
from recognit import visual as vis

base = os.path.dirname(__file__)
path = os.path.realpath(base + '/../data/faces')

# Load faces from the path.
faces = load.Faces(path, 'pgm')
faces.set_params(seed=895, train=0.60, valid=0.15)
faces.get_labels()

faces.get_data(id=0, exclude={4: ['2', '4']})
faces.create_matrices()

# Start principal component analysis.
clf = pca.PCA(faces.xtrain)
clf.find_principal_components()
clf.transform()

res = 0
trait = 0

d = []
x1 = []
x2 = []

for i in range(len(faces.yvalid)):
	s  = clf.project(faces.xvalid[:, i])
	d.append(np.min(cdist(clf.xtransform.T, s.T, "mahalanobis")))
	x1.append(s[0])
	x2.append(s[1])

for trait in range(4):
	prefix = 'res_' + str(res) + '_trait_' + str(trait) + '_'
	faces.set_params(seed=895, train=0.60, valid=0.15)
	faces.get_data(id=trait, exclude={4: ['2', '4']})
	faces.create_matrices()
	faceweights = defaultdict(list)

	for i, y in enumerate(faces.yvalid):
		faceweights[y].append([x1[i], x2[i], d[i]])

	fn = prefix + "face_scatter_w" + str(1) + "_v_w" + str(2) + ".pdf"
	title = r'Principal Components: $\omega_1$ vs. $\omega_2$'
	vis.scatter_face(title, faceweights, filename=fn)