#! /usr/bin/env python
"""
Train a YOLO_v2 model to Pascal VOC2007+2012 dataset.
"""
import argparse
import colorsys
from datetime import datetime
import h5py
import imghdr
import io
import random
import matplotlib.pyplot as plt
import numpy as np
import os
import pandas as pd
import PIL
import tensorflow as tf
from PIL import Image, ImageDraw, ImageFont
from keras import backend as K
from keras import backend as K
from keras.backend.tensorflow_backend import set_session
from keras.layers import Input, Lambda
from keras.models import Model
from keras.models import load_model
from yad2k.models.keras_yolo import (preprocess_true_boxes, yolo_body,
                                     yolo_eval, yolo_head, yolo_loss)
from yad2k.utils.draw_boxes import draw_boxes
import sys
import tqdm
IOU_THRESHOLD = 0.5
Precision_acc = 0
Average_precision = 0
cls_precision_acc = np.zeros([4])
cls_box_number = np.zeros([4])

def calculate_IoU(candidateBound, groundTruthBound):
    cx1 = candidateBound[0]
    cy1 = candidateBound[1]
    cx2 = candidateBound[2]
    cy2 = candidateBound[3]

    gx1 = groundTruthBound[0]
    gy1 = groundTruthBound[1]
    gx2 = groundTruthBound[2]
    gy2 = groundTruthBound[3]

    carea = (cx2 - cx1) * (cy2 - cy1) #C的面积
    garea = (gx2 - gx1) * (gy2 - gy1) #G的面积

    x1 = max(cx1, gx1)
    y1 = max(cy1, gy1)
    x2 = min(cx2, gx2)
    y2 = min(cy2, gy2)
    w = max(0, x2 - x1)
    h = max(0, y2 - y1)
    area = w * h #C∩G的面积

    iou = area / (carea + garea - area)

    return iou

YOLO_ANCHORS = np.array(
    ((0.57273, 0.677385), (1.87446, 2.06253), (3.33843, 5.47434),
     (7.88282, 3.52778), (9.77052, 9.16828)))
detectors_mask_shape = (13, 13, 5, 1)
matching_boxes_shape = (13, 13, 5, 5)
batch_size = 8

argparser = argparse.ArgumentParser(
    description='Train YOLO_v2 model to overfit on a single image.')

argparser.add_argument(
    '-d',
    '--data_path',
    help='path to HDF5 file containing pascal voc dataset',
    #default='~/datasets/PascalVOC/VOCdevkit/pascal_voc_07_12.hdf5')
    default='/var/tmp/YOLO/YAD2K-master/detectiondata/viva.hdf5')
argparser.add_argument(
    '-o',
    '--output_path',
    help='path to output test images, defaults to images/out',
    default='images/out')
argparser.add_argument(
    '-a',
    '--anchors_path',
    help='path to anchors file, defaults to yolo_anchors.txt',
    default='model_data/yolo_anchors.txt')

argparser.add_argument(
    '-c',
    '--classes_path',
    help='path to classes file, defaults to pascal_classes.txt',
    default='model_data/viva_classes.txt')
argparser.add_argument(
    '-t',
    '--training',
    action='store_true',
    help='training the model')

def _main(args):
    voc_path = os.path.expanduser(args.data_path)
    classes_path = os.path.expanduser(args.classes_path)
    anchors_path = os.path.expanduser(args.anchors_path)
    is_training = args.training
    with open(classes_path) as f:
        class_names = f.readlines()
    class_names = [c.strip() for c in class_names]

    if os.path.isfile(anchors_path):
        with open(anchors_path) as f:
            anchors = f.readline()
            anchors = [float(x) for x in anchors.split(',')]
            anchors = np.array(anchors).reshape(-1, 2)
    else:
        anchors = YOLO_ANCHORS

    voc = h5py.File(voc_path, 'r')
    total_img_number = voc['train/images'].shape[0]

    # Create model input layers.
    image_input = Input(shape=(416, 416, 3))
    boxes_input = Input(shape=(None, 5))
    detectors_mask_input = Input(shape=detectors_mask_shape)
    matching_boxes_input = Input(shape=matching_boxes_shape)
    roi_input = Input(shape=(None, 4))

    num_rois = 4
    pooling_regions = 13

    # Create model body.
    model_body = yolo_body(image_input, roi_input, len(anchors), len(class_names))
    model_body = Model([image_input, roi_input], model_body.output)
    # Place model loss on CPU to reduce GPU memory usage.
    with tf.device('/cpu:0'):
        # TODO: Replace Lambda with custom Keras layer for loss.
        model_loss = Lambda(
            yolo_loss,
            output_shape=(1, ),
            name='yolo_loss',
            arguments={'anchors': anchors,
                       'num_classes': len(class_names)})([
                           model_body.output, boxes_input,
                           detectors_mask_input, matching_boxes_input
                       ])
    model = Model(
        [image_input, roi_input, boxes_input, detectors_mask_input,
         matching_boxes_input], model_loss)
    model.compile(
        optimizer='adam', loss={
            'yolo_loss': lambda y_true, y_pred: y_pred
        })  # This is a hack to use the custom loss function in the last layer.

    gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.9,
                                allow_growth=True)
    config=tf.ConfigProto(gpu_options=gpu_options)
    set_session(tf.Session(config=config))
    iteration = 10
    num_steps = 1
    saved_file_name = 'iter40_batch8_weights.h5'
    max_num_box = [x.shape[0] for x in voc['train/boxes']]

    '''
    for x in voc['train/images']:
      print(x)
    '''
    #print("print imgs done")
    max_num_box = max(max_num_box) // 5
    #print("max_num_box = {}".format(max_num_box))
    #print("total_img_number = {}".format(total_img_number)) #10728
    batch_numbers = total_img_number//batch_size            #10728/24
    new_saved_file_name = 'new_iter50_batch8_weights.h5'
    model.load_weights(saved_file_name)
    #print("is_training = {}".format(is_training))
    if is_training:
        for ite in range(iteration):
            random.seed(ite)
            #print("{} : iteration{} start".format(datetime.now(),ite))
            choose_list = list(range(0, total_img_number))
            for batch_number in range(batch_numbers): #660
                if (batch_number%30==0):
                    model.save_weights(new_saved_file_name)
                    #print("{} : processing No.{} batch".format(datetime.now(),batch_number))
                image_data_batch = []
                roi_inputs_batch = []
                boxes_batch = []
                detectors_mask_batch = []
                matching_true_boxes_batch = []
                batch_start = batch_number*batch_size
                for i in range(batch_size):
                    #random_index = random.choice(choose_list)
                    #choose_list.remove(random_index)
                    image = PIL.Image.open(io.BytesIO(voc['train/images'][i]))
                    orig_size = np.array([image.width, image.height])
                    orig_size = np.expand_dims(orig_size, axis=0)
                    # Image preprocessing.
                    image = image.resize((416, 416), PIL.Image.BICUBIC)
                    image_data = np.array(image, dtype=np.float)
                    image_data /= 255.
                    # Box preprocessing.
                    # Original boxes stored as 1D list of class, x_min, y_min, x_max, y_max.
                    boxes = voc['train/boxes'][i]
                    boxes = boxes.reshape((-1, 5))
                    # Get extents as y_min, x_min, y_max, x_max, class for comparision with
                    # model output.
                    boxes_extents = boxes[:, [2, 1, 4, 3, 0]]

                    # Get box parameters as x_center, y_center, box_width, box_height, class.
                    boxes_xy = 0.5 * (boxes[:, 3:5] + boxes[:, 1:3])
                    boxes_wh = boxes[:, 3:5] - boxes[:, 1:3]
                    boxes_xy = boxes_xy / orig_size
                    boxes_wh = boxes_wh / orig_size
                    boxes = np.concatenate((boxes_xy, boxes_wh, boxes[:, 0:1]), axis=1)
                    detectors_mask, matching_true_boxes = preprocess_true_boxes(boxes, anchors, [416, 416])
                    boxes = np.pad(boxes, ((0,max_num_box-boxes.shape[0]),(0,0)), 'constant')

                    # Random ROI for all images
                    roi_inputs = np.zeros((num_rois, 4))
                    for i in range(num_rois):
                        x = np.random.randint(0, pooling_regions-1, size=1)
                        y = np.random.randint(0, pooling_regions-1, size=1)
                        w = np.random.randint(1, pooling_regions-x, size=1)
                        h = np.random.randint(1, pooling_regions-y, size=1)
                        roi_inputs[i,:] = np.array([x,y,w,h]).flatten()

                    image_data_batch.append(image_data.tolist())
                    roi_inputs_batch.append(roi_inputs.tolist())
                    boxes_batch.append(boxes.tolist())
                    detectors_mask_batch.append(detectors_mask.tolist())
                    matching_true_boxes_batch.append(matching_true_boxes.tolist())

                #print(matching_true_boxes.shape)
                image_data_batch = np.array(image_data_batch)
                roi_inputs_batch = np.array(roi_inputs_batch)
                boxes_batch = np.array(boxes_batch)
                detectors_mask_batch = np.array(detectors_mask_batch)
                matching_true_boxes_batch = np.array(matching_true_boxes_batch)

                model.fit([image_data_batch, roi_inputs_batch, boxes_batch, detectors_mask_batch, matching_true_boxes_batch],
                          np.zeros(len(image_data_batch)),
                          batch_size=batch_size,
                          epochs=num_steps,
                          verbose=0)

            #print("{} : iteration{} end".format(datetime.now(),ite))
            model.save_weights(new_saved_file_name)
            #print("weight saved as {}".format(new_saved_file_name))
       # print("{} : all done".format(datetime.now()))

    """
    image = PIL.Image.open(io.BytesIO(voc['train/images'][10]))
    orig_size = np.array([image.width, image.height])
    orig_size = np.expand_dims(orig_size, axis=0)
    # Image preprocessing.
    image = image.resize((416, 416), PIL.Image.BICUBIC)
    image_data = np.array(image, dtype=np.float)
    image_data /= 255.
    image_data = np.expand_dims(image_data, axis=0)

    # Create output variables for prediction.
    yolo_outputs = yolo_head(model_body.output, anchors, len(class_names))
    print("yolo_outputs) = {}".format(yolo_outputs))
    input_image_shape = K.placeholder(shape=(2, ))

    out_boxes, out_scores, out_classes = yolo_eval(
        yolo_outputs, input_image_shape, score_threshold=.001, iou_threshold=.001)

    print("out_boxes : {}".format(type(out_boxes)))
    print("out_scores : {}".format(type(out_scores)))
    print("out_classes : {}".format(type(out_classes)))
    #visualization
    out_boxes_temp = out_boxes
    out_scores_temp = out_scores
    out_classes_temp = out_classes
    bbox_pred = []
    bbox_c = []
    bbox_preds = []
    bbox_cls = []
    # Generate colors for drawing bounding boxes.
    hsv_tuples = [(x / len(class_names), 1., 1.)
                  for x in range(len(class_names))]
    colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
    colors = list(
        map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
            colors))
    try:
        max_score = max(out_scores)
        max_index = [i for i,j in enumerate(out_scores) if j==max_score]
        choosed_boxes = 0
        #print(len(out_scores))
        max_boxes = 1
        bbox_cls.append(np.array(bbox_c))
        bbox_preds.append(np.array(bbox_pred))
    except:
        xy_out_boxes = [0,0,10,10]
        bbox_pred.append(xy_out_boxes)
        bbox_c.append(0)
        bbox_cls.append(np.array(bbox_c))
        bbox_preds.append(np.array(bbox_pred))
        #print("fail {}".format(img_num))
        print("fail")

    font = ImageFont.truetype(
        font='font/FiraMono-Medium.otf',
        size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
    thickness = (image.size[0] + image.size[1]) // 300
    if True:
        out_boxes = out_boxes_temp
        out_scores = out_scores_temp
        out_classes = out_classes_temp
        #print("Number:{} processed ,Found {} boxes".format(img_num,len(out_boxes)))
        #draw the bounding box on image
        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = class_names[c]
            box = out_boxes[i]
            score = out_scores[i]
            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)
            top, left, bottom, right = box
            top = max(0, np.floor(top + 0.5).astype('int32'))
            left = max(0, np.floor(left + 0.5).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
            right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
            print(label, (left, top), (right, bottom))

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

            # My kingdom for a good redistributable image drawing library.
            for i in range(thickness):
                draw.rectangle(
                    [left + i, top + i, right - i, bottom - i],
                    outline=colors[c])
            draw.rectangle(
                [tuple(text_origin), tuple(text_origin + label_size)],
                fill=colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw

        image.save(os.path.join(output_path, image_file), quality=90)
    """
    for idx in range(0,100,100):
      image = PIL.Image.open(io.BytesIO(voc['train/images'][idx]))
      orig_size = np.array([image.width, image.height])
      orig_size = np.expand_dims(orig_size, axis=0)
      # Image preprocessing.
      image = image.resize((416, 416), PIL.Image.BICUBIC)
      image_data = np.array(image, dtype=np.float)
      image_data /= 255.
      image_data = np.expand_dims(image_data, axis=0)

      roi_inputs = np.zeros((num_rois, 4))
      for i in range(num_rois):
          x = np.random.randint(0, pooling_regions-1, size=1)
          y = np.random.randint(0, pooling_regions-1, size=1)
          w = np.random.randint(1, pooling_regions-x, size=1)
          h = np.random.randint(1, pooling_regions-y, size=1)
          roi_inputs[i,:] = np.array([x,y,w,h]).flatten()
      roi_inputs = np.expand_dims(roi_inputs, axis=0)

      # Create output variables for prediction.
      yolo_outputs = yolo_head(model_body.output, anchors, len(class_names))
      #print("yolo_outputs) = {}".format(yolo_outputs))
      input_image_shape = K.placeholder(shape=(2, ))
      boxes, scores, classes = yolo_eval(
	  yolo_outputs, input_image_shape, score_threshold=.005, iou_threshold=.001)

      #print(type([image.size[1], image.size[0]]))
      #print(type(K.learning_phase()))
      #print(K.learning_phase())
      # Run prediction on overfit image.
      #import pdb
      #pdb.set_trace() #中斷點
      sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.
      out_boxes, out_scores, out_classes = sess.run(
	  [boxes, scores, classes],
	  feed_dict={
	      model_body.input[0]: image_data,
	      model_body.input[1]: roi_inputs,
	      input_image_shape: [image.size[1], image.size[0]],
	      K.learning_phase(): 0
	  })
      #print('Found {} boxes for image.'.format(len(out_boxes)))
      #print(out_boxes)

      # Plot image with predicted boxes.
      image_with_boxes = draw_boxes(image_data[0], out_boxes, out_classes,
				    class_names, out_scores)
      #plt.imshow(image_with_boxes, interpolation='nearest')
      #plt.show()

    # Run prediction on overfit image.

    sess = K.get_session()  # TODO: Remove dependence on Tensorflow session.

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

    #For competition2

    #print("------------")

    num_test_img=voc['test/images'].shape[0]
    #print(num_test_img)

    #oc_path = os.path.expanduser("~/datasets/VOCdevkit/VOC2012/JPEGImages")

    # Generate colors for drawing bounding boxes.
    hsv_tuples = [(x / len(class_names), 1., 1.)
                  for x in range(len(class_names))]
    colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
    colors = list(
        map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
            colors))
    random.seed(10101)      # Fixed seed for consistent colors across runs.
    random.shuffle(colors)  # Shuffle colors to decorrelate adjacent classes.
    random.seed(None)       # Reset seed to default.

    output_path = os.path.expanduser(args.output_path)
    #voc_path = os.path.expanduser("~/datasets/VOCdevkit/VOC2012/JPEGImages")
    if not os.path.exists(output_path):
        #print('Creating output path {}'.format(output_path))
        os.mkdir(output_path)

    #print("-------------")
    '''

    #for img_num,image_file in enumerate(os.listdir(test_path)):
    '''
    '''
    try:
        image_type = imghdr.what(os.path.join(test_path, image_file))
        if not image_type:
            continue
    except IsADirectoryError:
        continue
    '''

    model_image_size = model.layers[0].input_shape[1:3]

    score_threshold = 0.05
    for img_num in range(num_test_img):

        image_file = str(img_num)+'.jpg'
        #print(image_file)
        image = PIL.Image.open(io.BytesIO(voc['test/images'][img_num]))
        #image = Image.open(os.path.join(test_path, image_file))
        if True:  # TODO: When resizing we can use minibatch input.
            resized_image = image.resize(
                tuple(reversed(model_image_size)), Image.BICUBIC)
            image_data = np.array(resized_image, dtype='float32')
        else:
            # Due to skip connection + max pooling in YOLO_v2, inputs must have
            # width and height as multiples of 32.
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            resized_image = image.resize(new_image_size, Image.BICUBIC)
            image_data = np.array(resized_image, dtype='float32')
            #print(image_data.shape)

        image_data /= 255.
        image_data = np.expand_dims(image_data, 0)  # Add batch dimension.

        out_boxes, out_scores, out_classes = sess.run(
            [boxes, scores, classes],
            feed_dict={
                model_body.input[0]: image_data,
                model_body.input[1]: roi_inputs,
                input_image_shape: [image.size[1], image.size[0]],
                K.learning_phase(): 0
            })

        out_boxes_temp = out_boxes
        out_scores_temp = out_scores
        out_classes_temp = out_classes

        try:
            max_score = max(out_scores)
            max_index = [i for i,j in enumerate(out_scores) if j==max_score]
            choosed_boxes = 0
            #print(len(out_scores))
            max_boxes = 4
        except:
            xy_out_boxes = [0,0,10,10]
            #print("fail {}".format(img_num))

        font = ImageFont.truetype(
            font='font/FiraMono-Medium.otf',
            size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = (image.size[0] + image.size[1]) // 300

        ''''''
        out_boxes = out_boxes_temp
        out_scores = out_scores_temp
        out_classes = out_classes_temp
        out_scores_order = out_scores.argsort()[:][::-1]

        exits=[0,0,0,0]
        bbox_pred=[]
        bbox_c=[]
        bbscore=[]
        #draw the bounding box on image
        '''
        for index in range(len(out_scores)):
            if (choosed_boxes<max_boxes) :
                #max_score = max(out_scores)
                #max_index = [i for i,j in enumerate(out_scores) if j==max_score]
                max_index = out_scores_order[index]
                box = out_boxes[max_index]
                top, left, bottom, right = box
                xy_out_boxes = [left,top,right,bottom]
                bbox_pred.append(xy_out_boxes)
                bbox_c.append(out_classes[max_index])
                choosed_boxes +=1
        '''

        class_set=set(out_classes)
        for index in range(len(out_classes)):
          max_index = out_scores_order[index]
          if exits[out_classes[max_index]]==0 :
            exits[out_classes[max_index]]=1
            box = out_boxes[max_index]
            top, left, bottom, right = box
            xy_out_boxes = [left,top,right,bottom]
            bbox_pred.append(xy_out_boxes)
            bbox_c.append(out_classes[max_index])
            bbscore.append(out_scores[max_index])
            choosed_boxes +=1
            if choosed_boxes==len(class_set):
              break

        #use all pred boxes
        '''
        print(out_classes)
        class_set=set(out_classes)
        for index in range(len(out_classes)):
          max_index = out_scores_order[index]
          #if exits[out_classes[max_index]]==0 :
          exits[out_classes[max_index]]=1
          box = out_boxes[max_index]
          top, left, bottom, right = box
          xy_out_boxes = [left,top,right,bottom]
          bbox_pred.append(xy_out_boxes)
          bbox_c.append(out_classes[max_index])
          bbscore.append(out_scores[max_index])
          choosed_boxes +=1
           # if choosed_boxes==len(class_set):
            #  break
        '''
        # bbox_pred, bbox_c, bbscore
        #-------------- calculate IoU ------------------------------
        IoU =[]
        AP = 0
        hit = 0
        reshaped_gt = voc['test/boxes'][img_num].reshape(-1,5)
        gt_box_number = reshaped_gt.shape[0]
        #sort_bbox_c = np.argsort(bbox_c, axis=0)

        # for each gt box, check if it's hit or not
        for idx_gt in range(gt_box_number):
            gt_cls = reshaped_gt[idx_gt][0]
            cls_box_number[gt_cls] +=1
            # for each pred boxes
            for idx_pred,pred_cls in enumerate(class_set):
                #print("pred_cls={}  idx_gt={}".format(pred_cls,idx_gt))
                if pred_cls == gt_cls:
                    IoUtemp = calculate_IoU(bbox_pred[idx_pred], reshaped_gt[idx_gt][1:])
                    IoU.append(IoUtemp)
                    #print("IoUtemp = {}".format(IoUtemp))
                    if IoUtemp>= IOU_THRESHOLD:
                        cls_precision_acc[gt_cls] += 1
        #print("Number:{} processed".format(img_num))
        if img_num%50==0:
            #print("Number:{} processed ,Found {} boxes".format(img_num,len(out_boxes)))
            #print(out_classes,out_scores,out_boxes)
            for i in range(len(bbox_pred)):
                predicted_class = class_names[i]
                box = bbox_pred[i]
                score = bbscore[i]
                label = '{} {:.2f}'.format(predicted_class, score)
                draw = ImageDraw.Draw(image)
                label_size = draw.textsize(label, font)
                top, left, bottom, right = box
                top = max(0, np.floor(top + 0.5).astype('int32'))
                left = max(0, np.floor(left + 0.5).astype('int32'))
                bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
                right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
                #print(label, (left, top), (right, bottom))

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

                # My kingdom for a good redistributable image drawing library.
                for j in range(thickness):
                    draw.rectangle(
                        [left + j, top + j, right - j, bottom - j],
                        outline=colors[i])
                draw.rectangle(
                    [tuple(text_origin), tuple(text_origin + label_size)],
                    fill=colors[i])
                draw.text(text_origin, label, fill=(0, 0, 0), font=font)
                del draw
            image.save(os.path.join(output_path, image_file), quality=90)
        #end for
    Average_precision = 0
    for cls in range(4):
        clss_precision = cls_precision_acc[cls]/cls_box_number[cls]
        Average_precision += clss_precision
        #print("Precision of Class {} = {}".format(cls,clss_precision))
    Average_precision = Average_precision/4
    #print("Average precision = {}".format(Average_precision))
    sess.close()

if __name__ == '__main__':
    args = argparser.parse_args()
    _main(args)


from flask import Flask, request, make_response
from flask_restful import reqparse, Resource, Api
import numpy as np
import pdb

from encode import Encoder
from decode import Decoder

app = Flask(__name__)
api = Api(app)

parser = reqparse.RequestParser()
parser.add_argument('hexcode', type=str)

class Hex(Resource):
    def get(self):
        return "Coming soon"
    def post(self):
        if 'image' in request.files:
            image_arr = np.fromstring(request.files['image'].read(), np.uint8)
            decoder = Decoder(image_arr)
            return decoder.decode()
        return "Error finding file, please upload image with key 'image'"

class Encode(Resource):
    def get(self):
        args = parser.parse_args()
        if 'hexcode' in args:
            hexcode = str(args['hexcode'])
            encoder = Encoder(hexcode)

            response = make_response(encoder.encode())
            response.headers['Content-Type'] = 'image/png'

            return response
        return "No hexcode to encode provided."

api.add_resource(Hex, '/')
api.add_resource(Encode, '/encode')

if __name__ == '__main__':
    app.run(host= '0.0.0.0', debug=True)


import os
from gtts import gTTS
import pygame

def get_next_filename(base_filename):
    # Extract the file extension (e.g., '.mp3')
    base_filename='[Your Path/output.mp3]'
    name, extension = os.path.splitext(base_filename)

    # Initialize a counter
    count = 1

    # Keep incrementing the counter until a unique filename is found
    while os.path.exists(f"{name}_{count}{extension}"):
        count += 1

    return f"{name}_{count}{extension}"

def text_to_speech(text, base_filename='output.mp3'):
    output_file = get_next_filename(base_filename)  # Get the next available filename
    tts = gTTS(text, lang='en')  # Create a gTTS object with text and language
    tts.save(output_file)  # Save the speech as an MP3 file
    pygame.mixer.init()
    pygame.mixer.music.load(output_file)  # Load the MP3 file
    pygame.mixer.music.play()  # Play the speech

if __name__ == "__main__":
    text = input("Enter the text you want to convert to speech: ")
    text_to_speech(text)
    input("Press Enter to exit...")


import sys

input = sys.stdin.readline

def rev(lst):
    lst = lst[::-1]
    return lst

def popleft(x):
    return x.pop(0)

ans = []
for i in range(int(input())):
    p = list(input().rstrip())
    n = int(input())
    x = list(map(int, input().split()))
    print("start")
    for j in range(len(p)):
        if p[j] == "R":
            x = rev(x)
        else:
            if len(x) == 0 :
                print("error")
                continue
            else :
                popleft(x)


"""
Functions for solving problems defined by configuration
files and performing goal-oriented error estimation.
"""
from firedrake import *
from firedrake.petsc import PETSc
from firedrake.mg.embedded import TransferManager
from pyroteus.error_estimation import get_dwr_indicator
import abc
from time import perf_counter

tm = TransferManager()

class Solver(abc.ABC):
    """
    Base class that defines the API for solver objects.
    """

    @abc.abstractmethod
    def __init__(self, mesh, ic, **kwargs):
        """
        Setup the solver.

        :arg mesh: the mesh to define the solver on
        :arg ic: the initial condition
        """
        pass

    @property
    @abc.abstractmethod
    def function_space(self):
        """
        The function space that the PDE is solved in.
        """
        pass

    @property
    @abc.abstractmethod
    def form(self):
        """
        Return the weak form.
        """
        pass

    @abc.abstractmethod
    def iterate(self, **kwargs):
        """
        Solve the PDE.
        """
        pass

    @property
    @abc.abstractmethod
    def solution(self):
        """
        Return the solution field.
        """
        pass

def get_solutions(
    mesh,
    config,
    solve_adjoint=True,
    refined_mesh=None,
    init=None,
    convergence_checker=None,
    **kwargs,
):
    """
    Solve forward and adjoint equations on a
    given mesh.

    This works only for steady-state problems.

    :arg mesh: input mesh
    :arg config: configuration file, which
        specifies the PDE and QoI
    :kwarg solve_adjoint: should we solve the
        adjoint problem?
    :kwarg refined_mesh: refined mesh to compute
        enriched adjoint solution on
    :kwarg init: custom initial condition function
    :kwarg convergence_checker: :class:`ConvergenceTracer`
        instance
    :return: forward solution, adjoint solution
        and enriched adjoint solution (if requested)
    """

    # Solve forward problem in base space
    V = config.get_function_space(mesh)
    out = {"times": {"forward": -perf_counter()}}
    with PETSc.Log.Event("Forward solve"):
        if init is None:
            ic = config.get_initial_condition(V)
        else:
            ic = init(V)
        solver_obj = config.Solver(mesh, ic, **kwargs)
        solver_obj.iterate()
        q = solver_obj.solution
        J = config.get_qoi(mesh)(q)
        qoi = assemble(J)
    out["times"]["forward"] += perf_counter()
    out["qoi"] = qoi
    out["forward"] = q
    if convergence_checker is not None:
        if convergence_checker.check_qoi(qoi):
            return out
    if not solve_adjoint:
        return out

    # Solve adjoint problem in base space
    out["times"]["adjoint"] = -perf_counter()
    with PETSc.Log.Event("Adjoint solve"):
        sp = config.parameters.adjoint_solver_parameters
        q_star = Function(V)
        F = solver_obj.form
        dFdq = derivative(F, q, TrialFunction(V))
        dFdq_transpose = adjoint(dFdq)
        dJdq = derivative(J, q, TestFunction(V))
        solve(dFdq_transpose == dJdq, q_star, solver_parameters=sp)
        out["adjoint"] = q_star
    out["times"]["adjoint"] += perf_counter()
    if refined_mesh is None:
        return out

    # Solve adjoint problem in enriched space
    out["times"]["estimator"] = -perf_counter()
    with PETSc.Log.Event("Enrichment"):
        V = config.get_function_space(refined_mesh)
        q_plus = Function(V)
        solver_obj = config.Solver(refined_mesh, q_plus, **kwargs)
        q_plus = solver_obj.solution
        J = config.get_qoi(refined_mesh)(q_plus)
        F = solver_obj.form
        tm.prolong(q, q_plus)
        q_star_plus = Function(V)
        dFdq = derivative(F, q_plus, TrialFunction(V))
        dFdq_transpose = adjoint(dFdq)
        dJdq = derivative(J, q_plus, TestFunction(V))
        solve(dFdq_transpose == dJdq, q_star_plus, solver_parameters=sp)
        out["enriched_adjoint"] = q_star_plus
    out["times"]["estimator"] += perf_counter()
    return out

def split_into_components(f):
    r"""
    Extend the :attr:`split` method to apply
    to non-mixed :class:`Function`\s.
    """
    return [f] if f.function_space().value_size == 1 else f.split()

def indicate_errors(mesh, config, enrichment_method="h", retall=False, **kwargs):
    """
    Indicate errors according to ``dwr_indicator``,
    using the solver given in the configuration file.

    :arg mesh: input mesh
    :arg config: configuration file, which
        specifies the PDE and QoI
    :kwarg enrichment_method: how to enrich the
        finite element space?
    :kwarg retall: if ``True``, return the forward
        solution and adjoint solution in addition
        to the dual-weighted residual error indicator
    """
    if not enrichment_method == "h":
        raise NotImplementedError  # TODO
    with PETSc.Log.Event("Enrichment"):
        mesh, ref_mesh = MeshHierarchy(mesh, 1)

    # Solve the forward and adjoint problems
    out = get_solutions(mesh, config, refined_mesh=ref_mesh, **kwargs)
    if retall and "adjoint" not in out:
        return out

    out["times"]["estimator"] -= perf_counter()
    with PETSc.Log.Event("Enrichment"):
        adj_sol_plus = out["enriched_adjoint"]

        # Prolong
        V_plus = adj_sol_plus.function_space()
        fwd_sol_plg = Function(V_plus)
        tm.prolong(out["forward"], fwd_sol_plg)
        adj_sol_plg = Function(V_plus)
        tm.prolong(out["adjoint"], adj_sol_plg)

        # Subtract prolonged adjoint solution from enriched version
        adj_error = Function(V_plus)
        adj_sols_plus = split_into_components(adj_sol_plus)
        adj_sols_plg = split_into_components(adj_sol_plg)
        for i, err in enumerate(split_into_components(adj_error)):
            err += adj_sols_plus[i] - adj_sols_plg[i]

        # Evaluate errors
        out["dwr"] = dwr_indicator(config, mesh, fwd_sol_plg, adj_error)
    out["times"]["estimator"] += perf_counter()

    return out if retall else out["dwr"]

def dwr_indicator(config, mesh, q, q_star):
    r"""
    Evaluate the DWR error indicator as a :math:`\mathbb P0` field.

    :arg mesh: the current mesh
    :arg q: the forward solution, transferred into enriched space
    :arg q_star: the adjoint solution in enriched space
    """
    mesh_plus = q.function_space().mesh()

    # Extract indicator in enriched space
    solver_obj = config.Solver(mesh_plus, q)
    F = solver_obj.form
    V = solver_obj.function_space
    dwr_plus = get_dwr_indicator(F, q_star, test_space=V)

    # Project down to base space
    P0 = FunctionSpace(mesh, "DG", 0)
    dwr = project(dwr_plus, P0)
    dwr.interpolate(abs(dwr))
    return dwr


from turtle import Turtle

class Paddle(Turtle):

    def __init__(self, xcor, ycor):
        super().__init__()
        self.shape("square")
        self.color("white")
        self.penup()
        self.turtlesize(stretch_wid=1, stretch_len=10, outline=0)
        self.goto(x=xcor, y=ycor)

    def move_right(self):
        new_x = self.xcor() + 30
        self.goto(new_x, self.ycor())

    def move_left(self):
        new_x = self.xcor() - 30
        self.goto(new_x, self.ycor())


# My implementation of a simple commandline rock paper scissors game in Python 3.8.3 :)
import random
import keyboard
import sys

def game():
    print("\n This is rock paper scissors. To play you just input rock, paper, or scissors fully.")
    choice = 0
    # validating input
    while True:
        choice = input("Pick rock, paper, or scissors: ").lower()
        if choice == "rock" or choice =="paper" or choice == "scissors":
            break

    # getting what the computer picked
    arr = ["rock", "paper", "scissors"]
    computerchoice = arr[random.randint(0, 2)]
    print("You picked " + choice + "." + " The computer picked " + computerchoice + ".")

    # dictionary connecting key to the values that make the key lose.
    dict = {"rock" : "paper",
            "paper" : "scissors",
            "scissors": "rock"}
    # comparing user input and computer's choice to see who won
    # if the user and computer picked the same thing
    if choice == computerchoice:
        print("It's a tie. If you want to play again press y. If you want to quit press q.")
        while True:
            if keyboard.is_pressed("y"):
                game()
            elif keyboard.is_pressed("q"):
                sys.exit()
    # if the computer picked something beats what the user picked, then the computer whens
    elif computerchoice == dict[choice]:
        print("The computer wins. If you want to play again press y, but if you want to quit press q.")
        while True:
            if keyboard.is_pressed("y"):
                game()
            elif keyboard.is_pressed("q"):
                sys.exit()
    # if the computer didn't win, and it isn't a tie, then it means that the user must've won
    else:
        print("Congrats! You won! If you want to play again press y, but if you want to quit press q.")
        while True:
            if keyboard.is_pressed("y"):
                game()
            elif keyboard.is_pressed("q"):
                sys.exit()

game()


import sys
import re
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
import json

## classes
class Node:
    def __init__(self, docId = None, next = None):
        self.docId = docId
        self.next = next
        self.freq = 1

    def incFrequency(self):
        self.freq += 1

class LinkedList:

    def __init__(self, token):
        self.start_node = None # Head pointer
        self.end_node = None # Tail pointer
        self.token = token

    # Method to traverse a created linked list
    def traverse_list(self):
        traversal = []
        if self.start_node is None:
            print("List has no element")
            return None
        else:
            n = self.start_node
            # Start traversal from head, and go on till you reach None
            while n is not None:
                traversal.append("DocID: "+str(n.docId)+", Freq: "+str(n.freq))
                n = n.next
            return traversal

    def getDocIds(self):
        docIds = []
        if self.start_node is not None:
            n = self.start_node
            # Start traversal from head, and go on till you reach None
            while n is not None:
                docIds.append(n.docId)
                n = n.next
        return docIds

    def print(self):
        traversal = self.traverse_list()
        if traversal == None:
            print("______________")
            print(self.token+ ": Empty")
            print("______________")
        else:
            print("______________")
            print(self.token+": ")
            print(traversal, ',')
            print("______________")

    # Method to insert elements in the linked list
    def insert(self, docId):

        # Initialze a linked list element of type "Node"
        new_node = Node(docId)
        currentHead = self.start_node # Head pointer

        # If linked list is empty, insert element at head
        if self.start_node is None:
            new_node = Node(docId)
            self.start_node = new_node
            self.end_node = new_node
            return "Inserted"
        else:
            if self.start_node.docId > docId:
                # If element to be inserted has lower docId than head, insert new element at head
                new_node = Node(docId)
                self.start_node = new_node
                self.start_node.next = currentHead
                return "Inserted"
            elif self.start_node.docId == docId:
                # if the head's docId and the new docid match, increment the frequency at the head node
                self.start_node.incFrequency()
            elif self.end_node.docId < docId:
                # If element to be inserted has higher docId than tail, insert new element at tail
                new_node = Node(docId)
                self.end_node.next = new_node
                self.end_node = new_node
                return "Inserted"
            elif self.end_node.docId == docId:
                # docId to be inserted exists at the tail, so just increment the frequency
                self.end_node.incFrequency()
            else:
                # If element to be inserted lies between head & tail, find the appropriate position to insert it
                ptr = self.start_node
                while True:
                    if ptr.docId == docId:
                        ptr.incFrequency()
                        return "Inserted"
                    else:
                        if ptr.next.docId > docId:
                            # it is 100% sure that ptr.docId < docId, and ptr.next != None
                            new_node = Node(docId)
                            nextTemp = ptr.next
                            ptr.next = new_node
                            new_node.next = nextTemp
                            return "Inserted"
                        else:
                            ptr = ptr.next
                return "Inserted"
## classes end here

def wordCount(tokens):
    tokenDict = {}
    for token in tokens:
        if token in tokenDict:
            tokenDict[token] += 1
        else:
            tokenDict[token] = 1
    return tokenDict

def tokenizeDocument(docContents):
    docContents = docContents.lower() # req a
    words = docContents.split(" ") # tokenize d
    filteredWords = []
    ps = PorterStemmer()
    for word in words:
        repWord = re.sub('[^a-z0-9]+', ' ', word) # b
        repWord = repWord.strip() # c
        if repWord == '' or repWord == ' ':
            continue
        wordsDelimitedBySpecChars = repWord.split(' ')
        for wordDelBySpecChar in wordsDelimitedBySpecChars:
            wordDelBySpecChar = wordDelBySpecChar.strip()
            if wordDelBySpecChar in stopwords.words('english') or wordDelBySpecChar == '':
                continue
            wordDelBySpecChar = ps.stem(wordDelBySpecChar) # f
            filteredWords.append(wordDelBySpecChar)
    return filteredWords

def buildPostingsList(docIdToTokens):
    postingsList = {} # key is token and value is LinkedList object
    for docId in docIdToTokens:
        tokenList = docIdToTokens[docId]
        for token in tokenList:
            if token in postingsList:
                linkedList = postingsList[token]
            else:
                linkedList = LinkedList(token)
                postingsList[token] = linkedList
            linkedList.insert(docId)
    return postingsList

def getQueryToTokens(queryFilePath):
    queryFileHand = open(queryFilePath)
    queries = queryFileHand.readlines()
    queryToTokens = {}
    for line in queries:
        if line == None:
            break
        tokens = tokenizeDocument(line)
        queryToTokens[line.strip()] = tokens
    return queryToTokens

def getPostingsListForQueries(queryToTokens, postingsList):
    queryPostingsList = {}

    for queryId in queryToTokens:
        queryTokens = queryToTokens[queryId]
        for queryToken in queryTokens:
            if queryToken not in queryPostingsList:
                queryPostingsList[queryToken] = postingsList[queryToken].getDocIds()

    return queryPostingsList

def generateOutputJson(outputFilePath, queryPostingsList, daatAnd):
    outputJson = {}
    outputJson['postingsList'] = queryPostingsList
    outputJson['daatAnd'] = daatAnd
    outputStr = json.dumps(outputJson)
    fileHandl = open(outputFilePath, "w")
    fileHandl.write(outputStr)
    fileHandl.close()

def getDaatAnd(queryToTokens, queryPostingsList):
    queryToResults = {}
    for query in queryToTokens:
        tokensInQuery = queryToTokens[query]
        docIntersectnForQuery = []
        if len(tokensInQuery) == 1:
            results = queryPostingsList[tokensInQuery[0]]
            num_comparisons = 0
            num_docs = len(tokensInQuery[0])
        else:
            num_comparisons = 0

            # make a dictionary with key as the token, and value as the len of postings list
            tokenToPostingsListLen = {}
            for token in tokensInQuery:
                tokenToPostingsListLen[token] = len(queryPostingsList[token])

            # sort the tokenToPostingsListLen by increasing order of length
            tokenToPostingsListLen = {k: v for k, v in sorted(tokenToPostingsListLen.items(), key=lambda item: item[1])}
            orderedTokens = list(tokenToPostingsListLen.keys())

            docIntersectnForQuery = queryPostingsList[orderedTokens[0]]
            for tokenIdx in range(1, len(orderedTokens)):
                token = orderedTokens[tokenIdx]
                tokenDocList2 = queryPostingsList[token]
                (intersectDoc, operations) = mergeLists(docIntersectnForQuery, tokenDocList2)
                docIntersectnForQuery = intersectDoc
                num_comparisons += operations

        queryToResults[query] = {
            'results' : docIntersectnForQuery,
            'num_docs' : len(docIntersectnForQuery),
            'num_comparisons' : num_comparisons
        }

    return queryToResults

def mergeLists(list1, list2):
    finalList = []
    p1 = 0
    p2 = 0
    comparisonCount = 0

    while p1 < len(list1) and p2 < len(list2):
        if list1[p1] < list2[p2]:
            comparisonCount += 1
            p1 += 1
        elif list1[p1] > list2[p2]:
            p2 += 1
            comparisonCount += 1
        else:
            finalList.append(list1[p1])
            comparisonCount += 1
            p1 += 1
            p2 += 1
    return (finalList, comparisonCount)

def getDocIdToTokens(pathToCorpus):
    """Step 1: Build Your Own Inverted Index
    Implement a pipeline which takes as input the given corpus, and returns an inverted
    index.
    1. Extract the document ID and document from each line.
    2. Perform a series of preprocessing on the document:
        a. Convert document text to lowercase
        b. Remove special characters. Only alphabets, numbers and whitespaces
        should be present in the document. only ascii!
        c. Remove excess whitespaces. There should be only 1 white space
        between tokens, and no whitespace at the starting or ending of the
        document.
        d. Tokenize the document into terms using white space tokenizer.
        e. Remove stop words from the document.
        f. Perform Porter’s stemming on the tokens.
        g. Sample preprocessing output"""
    fileHandl = open(pathToCorpus)
    completeDocList = fileHandl.readlines()
    docIdToTokens = {}

    for line in completeDocList:
        if line == None:
            break
        lineContents = line.split("\t")
        try:
            docId = int(lineContents[0])
            docContents = lineContents[1]
            tokens = tokenizeDocument(docContents)
            docIdToTokens[docId] = tokens
        except:
            print("Exception"+str(docId))
        #wordCnt = wordCount(tokens)
    return docIdToTokens

if __name__ == "__main__":
    """docText = "Management of ophthalmic perioperative period during 2019 novel coronavirus disease outbreak/ 新型冠状病毒肺炎疫情下眼科患者围手术期管理实践"
    tokens = tokenizeDocument(docText)
    docText = "Management of coronavirus is getting really hard. The outbreak is bad! Coronavirus is a deadly disease!"
    tokens2 = tokenizeDocument(docText)
    dic = {1:tokens, 2: tokens2}
    pl = buildPostingsList(dic)
    for token in pl:
        print(token)
        pl[token].print()
    exit()"""

    # expected jgan2_project2.py path_of_input_corpus output.json query.txt
    pathToCorpus = sys.argv[1] if sys.argv[1] != None else "Null"
    outputFilePath = sys.argv[2] if sys.argv[2] != None else "Null"
    queryFilePath = sys.argv[3] if sys.argv[3] != None else "Null"

    print("Corpus Path: "+pathToCorpus)
    print("Output Path: "+outputFilePath)
    print("Query  Path: "+queryFilePath)

    docIdToTokens = getDocIdToTokens(pathToCorpus)

    """print("Doc to tokens: ")
    for docID in docIdToTokens:
        st = ""
        for token in docIdToTokens[docID]:
            st += token+", "
        print(str(docID)+" " + st)"""

    print("Preparing Postings list")
    postingsList = buildPostingsList(docIdToTokens)
    """for token in postingsList:
        lList = postingsList[token]
        lList.print()"""
    print("Postings list created")

    queryToTokens = getQueryToTokens(queryFilePath)
    for queryId in queryToTokens:
        for query in queryToTokens[queryId]:
            print(query)

    queryPostingsList = getPostingsListForQueries(queryToTokens, postingsList)
    daatAnd = getDaatAnd(queryToTokens, queryPostingsList)
    generateOutputJson(outputFilePath, queryPostingsList, daatAnd)


# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client
from dotenv import load_dotenv
import os

load_dotenv()

ACCOUNT_SID = os.getenv('ACCOUNT_SID')
AUTH_TOKEN = os.getenv('AUTH_TOKEN')
TEST_PHONE_NUMBER = os.getenv('TEST_PHONE_NUMBER')
TWILIO_PHONE_NUMBER = os.getenv('TWILIO_PHONE_NUMBER')

def send(body='Some body', to=TEST_PHONE_NUMBER):
    # Your Account Sid and Auth Token from twilio.com/console
    # DANGER! This is insecure. See http://twil.io/secure
    account_sid = ACCOUNT_SID
    auth_token = AUTH_TOKEN
    client = Client(account_sid, auth_token)

    message = client.messages \
                    .create(
                        body=body,
                        from_=TWILIO_PHONE_NUMBER,
                        to='+'+to
                    )

    # print(message.sid)


import numpy as np
import sympy as sp
import itertools
import random

_t = sp.Symbol('t', real=True)

class OperatorError(Exception):
    pass

class Operator(object):
    """finite dimensional time-dependent operator"""
    def __init__(self, op):
        self._opfunc = as_valid_callable(op)
        self._dimension = self._opfunc(1).shape[0]

    @property
    def N(self):
        return self._dimension

    def __call__(self, t):
        # makes it slower but maybe is worth it
        if hasattr(t, '__iter__'):
            #TODO: use list comprehension -- functional programming
            retval = np.ndarray((len(t), self.N, self.N), dtype=complex)
            for i in range(len(t)):
                retval[i] = self._opfunc(t[i])
            #vfunc = np.vectorize(lambda t: self._opfunc(t))
            #print(vfunc(1))
            return retval
        else:
            return self._opfunc(t)

    #NOTE:  Problems with __radd__ and np.ndarrays:
    #       It wants to add elementwise.
    def __add__(self, other):
        other = asOperator(other)
        if self.N != other.N:
            raise OperatorError('cant add operators of different dimensions')
        def op_sum(t):
            return self(t) + other(t)
        return Operator(op_sum)

    def __mul__(self, other):
        other = asOperator(other)
        if self.N != other.N:
            raise OperatorError('cant mul operators of different dimensions')
        def op_mul(t):
            return np.dot(self(t), other(t))
        return Operator(op_mul)

    def __getitem__(self, indices):
        """operator entry"""
        i, j = indices
        def get_entry(t):
            if isinstance(t, (int, float)):
                return self(t)[i,j]
            else:
                return self(t)[::,i,j]
        return get_entry

def asOperator(qty):
    """factory pattern function"""
    if isinstance(qty, Operator):
        return qty
    else:
        return Operator(qty)

def as_valid_callable(op):
    """return verified callable operator"""
    if callable(op) and is_valid(op):
        return op

    if isinstance(op, sp.MatrixBase):
        opfunc = sp.lambdify(_t, sp.simplify(op), ['numpy'])
        return as_valid_callable(opfunc)

    if isinstance(op, (list, np.ndarray)):
        op = np.array(op).squeeze()
        return as_valid_callable(lambda t: op)

    raise TypeError('cannot convert {} to Operator'.format(type(op)))

def is_valid(op):
    """numerical validation"""
    valid_types = np.sctypes['complex']
    valid_types += np.sctypes['float']
    valid_types += np.sctypes['int']

    TMIN, TMAX, N = -100, 100, 100
    for _ in itertools.repeat(None, N):
        t = random.uniform(TMIN, TMAX)
        if not isinstance(op(t), np.ndarray):
            raise OperatorError('wrong return type')
        if not op(t).ndim == 2:
            raise OperatorError('wrong dimension')
        if not op(t).shape[0] == op(t).shape[1]:     #is square
            raise OperatorError('wrong shape')
        if not op(t).dtype.type in valid_types:
            raise OperatorError('wrong data type')
    return True

def is_hermitian(op):
    """numerical test for hermiticity"""
    TMIN, TMAX, N = -50, 50, 100
    for _ in itertools.repeat(None, N):
        t = random.uniform(TMIN, TMAX)
        if not np.allclose(op(t), op(t).conj().T):
            return False
    return True

def are_close(a, b, **kwargs):
    """check whether two operators are numerical close"""
    pass

# Pauli matrices
from sympy.physics.matrices import msigma
def gen_sigmas():
    """generate Pauli matrices.

    Usage:\n
    sp.Matrix(np.dot(vec, sigmas).reshape(2,2))
    """
    sigmas = []
    for i in range(4):
        if (i == 0):
            sigma = sp.Identity(2).as_explicit()
        else:
            sigma = sp.ImmutableMatrix(msigma(i))
        sigmas.append(sigma)
    return sigmas

sigmas = gen_sigmas()

##################
#### testsuit ####
##################

import unittest
class TestOperator(unittest.TestCase):
    def setUp(self):
        self.N_ITER = 100
        self.o1 = np.array([[1,0],[0,-1]])
        self.o2 = np.array([[0,1],[1,0]])
        self.o3 = np.array([[0,-1j],[1j,0]])

    def test_validity(self):
        # types
        with self.assertRaises(TypeError):
            as_valid_callable(2.)
        with self.assertRaises(OperatorError):
            a, b, c, d = ['a', 'b', 'c', 'd']
            as_valid_callable(np.array([[a,b],[c,d]]))
        with self.assertRaises(OperatorError):
            a, b, c, d = map(sp.S, ['a', 'b', 'c', 'd'])
            as_valid_callable(np.array([[a,b],[c,d]]))

        # shape
        with self.assertRaises(OperatorError):
            as_valid_callable(np.ndarray((1,2)))
        with self.assertRaises(OperatorError):
            as_valid_callable(sp.Matrix([1,2]))

        # dimension
        with self.assertRaises(OperatorError):      #squeeze
            as_valid_callable([0])
        with self.assertRaises(OperatorError):
            as_valid_callable(np.arange(8))
        with self.assertRaises(OperatorError):
            as_valid_callable(np.arange(8).reshape(2,2,2))

    def test_correctness(self):
        a1 = lambda t: np.array([[t, 2j],[-2j,-t]])
        a2 = as_valid_callable(a1)
        a3 = as_valid_callable(sp.Matrix([[_t, 2j],[-2j,-_t]]))
        for _ in itertools.repeat(None, self.N_ITER):
            t = random.uniform(-10, 10)
            self.assertTrue(np.allclose(a1(t), a2(t)))
            self.assertTrue(np.allclose(a2(t), a3(t)))

    def test_addition(self):
        op = Operator(self.o1 + self.o2)
        variants = []

        variants.append(Operator(self.o1) + Operator(self.o2))
        variants.append(Operator(self.o1) + self.o2)
        variants.append(Operator(self.o2) + Operator(self.o1))
        variants.append(Operator(self.o2) + self.o1)

        #variants.append(self.o1 + Operator(self.o2))
        #variants.append(self.o2 + Operator(self.o1))

        for _ in itertools.repeat(None, self.N_ITER):
            t = random.uniform(-10, 10)
            for other in variants:
                self.assertTrue(np.allclose(op(t), other(t)))

    def test_multiplication(self):
        op = Operator(np.dot(self.o1, self.o2))

        variantsTrue = []
        variantsTrue.append(Operator(self.o1) * Operator(self.o2))
        variantsTrue.append(Operator(self.o1) * self.o2)
        #variantsTrue.append(self.o1 * Operator(self.o2))

        variantsFalse = []
        variantsFalse.append(Operator(self.o2) * Operator(self.o1))
        variantsFalse.append(Operator(self.o2) * self.o1)
        #variantsFalse.append(self.o2 * Operator(self.o1))

        for _ in itertools.repeat(None, self.N_ITER):
            t = random.uniform(-10, 10)
            for other in variantsTrue:
                self.assertTrue(np.allclose(op(t), other(t)))
            for other in variantsFalse:
                self.assertFalse(np.allclose(op(t), other(t)))

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


import hou
import os
import json
import numpy as np

from pipe.am.environment import Environment
from pipe.am import pipeline_io
from pipe.am.body import Body
from pipe.am.project import Project
from pipe.am.element import Element
import pipe.gui.quick_dialogs as qd
import pipe.gui.select_from_list as sfl
from pipe.tools.houtools.utils.utils import *

class publish_set():

    def set_results(self, value):
        set_name = value[0]
        project = Project()
        self.body = project.get_body(set_name)

        obj = hou.node("/obj")
        set = obj.node(set_name)

        if set is None:
            qd.error("No set found with that name. Please check naming and try again.")
            return

        #migrate transforms for all the children to set_dressing_transform
        self.update_set_dressing_transform(set)

        #create children list (list of houdini objects)
        print("set: ", set)
        inside = set.node("inside")
        children = inside.children()

        set_file = os.path.join(Project().get_assets_dir(), set_name, "model", "main", "cache", "whole_set.json")

        '''
        The idea here is to get the set data from whole_set.json,
        get the set data from Houdini, and then compare the two.
        Here are the possible scenarios:
            1. There are items in the JSON file that aren't in the Houdini Set
                -remove the item from the Json file
                -remove the item's json files
            2. There are items in the Houdini Set that aren't in the JSON file
                -Add those to the JSON file
        '''

        items_to_delete = []
        set_data = []
        items_in_set = []

        items_to_delete, set_data, items_in_set = self.get_set_comparable_lists(children, set_file)

        self.delete_asset_json(items_to_delete, set_name)

        # TODO: To allow adding multiple copies of the same prop to a set in houdini, we'll want to add as many copies to the whole_set.json file
        # for child_name in child_names:
        #     child = inside.node(child_name)  # get the child node
        #     inside = child.node("inside")
        #     modify = inside.node("modify")
        #     modify_name = modify.type().name()
        #     name = modify_name.split("_")[0].lower()
        #
        #     if name not in items_in_set:
        #         set_data.append

        print("starting to work on children\n")
        for child in children:

            #find if it is scaled (set to big scale) and initialize variables----------------------------------------------------------
            #inside
            #import_node
            #out
            #set_transform
            #current_version
            #name

            isScaled = False
            print("child: " + str(child))
            print("current set_data: " + str(set_data))
            if child.type().name() == "dcc_geo":
                inside = child.node("inside")
                import_node = child.node("import")
                if child.parm("Scale_Object").evalAsInt() == 1:
                    child.parm("Scale_Object").set(0)
                    isScaled = True
            else:
                inside = child.node("inside")
                geo = inside.node("geo")
                inside = geo.node("inside")
                import_node = geo.node("import")

            out = inside.node("OUT")
            set_transform = inside.node("set_dressing_transform")
            current_version = child.parm("version_number").evalAsInt()
            #need a asset number or letter (I honestly just need to name it something and have that reflected in houdini)
            #import_number = child.parm("import_number").evalAsInt

            name = child.parm("asset_name").evalAsString()

            #---------------------------------------------------------------------------------------------------------------------------

            child_body = project.get_body(name)
            if child_body is None:
                qd.warning(str(name) + " not found in pipe. Please check that node is named correctly.")
                continue

            cache_dir = os.path.join(Project().get_assets_dir(), set_name, "model", "main", "cache")
            print("filepath: ", cache_dir)
            latest_version, version_string = self.body.version_prop_json(name, cache_dir)
            print('latest version: ', latest_version)
            new_version = latest_version
            latest_version -= 1

            prop_file = os.path.join(cache_dir, str(name) + "_" + str(current_version) + ".json")
            print("prop file: ", prop_file)

            #will have to change items_in_set to be checked
            if name in items_in_set:
                print("set contains asset: " + str(name))
                try:
                    with open(prop_file) as f:
                        prop_data = json.load(f)
                except Exception as error:
                    print("No valid JSON file for " + str(name) + ". Skipping changes made to this asset.")
                    continue

                for set_item in set_data:
                    if str(set_item['asset_name']) == str(name):
                        if set_item['version_number'] <= current_version:
                            print("updating ", set_item, " with version ", new_version)
                            set_item['version_number'] = new_version
                            break

            else:
                # create blank prop data and add it to the set
                print(str(name) + " not found in set file.")
                path = self.get_prim_path(out)
                prop_data = {"asset_name": name, "version_number": 0, "path" : str(path), "a" : [0, 0, 0], "b" : [0, 0, 0], "c" : [0, 0, 0] }
                set_data.append({"asset_name": str(name), "version_number": 0})
                print("appended set_data: " + str(set_data))
                new_version = 0
                items_in_set.append(name)

            print("current set_data: " + str(set_data))

            new_prop_file = os.path.join(Project().get_assets_dir(), set_name, "model", "main", "cache", str(name) + "_" + str(new_version) + ".json")

            # get a b and c from prop_data file. Each is an array of size 3, representing x,y,z coords
            a = prop_data['a']
            b = prop_data['b']
            c = prop_data['c']

            self.update_points_by_geo(out, prop_data['path'], a, b, c)

            # put the updated coords back into prop_data
            prop_data['a'] = a
            prop_data['b'] = b
            prop_data['c'] = c
            prop_data['version_number'] = new_version

            # TODO: add a commit and a publish for this set

            print("prop data (updated): ", prop_data)

            updated_prop_data = json.dumps(prop_data)
            outfile = open(new_prop_file, "w")
            outfile.write(updated_prop_data)
            outfile.close()

            print("prop file updated for " + str(name))
            print("")

            self.clear_transform(set_transform)
            self.set_space(child, set_name, name, new_version)

            if isScaled:
                child.parm("Scale_Object").set(1)

        #reloading the new data that was written
        try:
            read_from_json = import_node.node("read_from_json")
            read_from_json.parm("reload").pressButton()
        except:
            print("no nodes are in the set, cannot read from JSON")

        #rewriting the whole_set json file
        outfile = open(set_file, "w")
        print("set data: ", set_data)
        updated_set_data = json.dumps(set_data)
        outfile.write(updated_set_data)
        outfile.close()

        qd.info("Set " + str(set_name) + " published successfully!")

    def get_set_comparable_lists(self, children, set_file):
        set_data = []
        try:
            with open(set_file) as f:
                set_data = json.load(f)
        except Exception as error:
            qd.error("No valid JSON file for " + str(set_name))
            return
        print("SET_DATA FROM JSON: " + str(set_data))

        #create the list of asset names from the json file (list of strings)
        items_in_set = []
        items_in_set = [item['asset_name'] for item in set_data];
        print("Items in set from JSON: " + str(items_in_set))

        #create the list of asset names from the current houdini's set (list of strings)
        child_names = []
        child_names = [child.parm('asset_name').eval() for child in children]
        print("Items IN HOUDINI: " + str(children))
        print("Asset Names:" + str(child_names))

        #edit lists to only contain items that were explicitly in the set in Houdini
        #create the list of assets to delete (dictionary of asset_name and version_number)
        items_to_delete = []
        items_to_delete[:] = [{'asset_name': item['asset_name'], 'version_number': item['version_number']} for item in set_data if str(item['asset_name']) not in child_names]
        print("items deleted in set: " + str(items_to_delete))

        #edit set_data to include only objects (asset_name, version_number) that are still found in the set
        #note: it won't include anything in the scene that wasn't origionally in the json file
        set_data[:] = [item for item in set_data if str(item['asset_name']) in child_names]
        print("new set data: " + str(set_data))

        #edit doing the same thing as above except its only the asset name thats being saved this time
        items_in_set[:] = [item['asset_name'] for item in set_data if str(item['asset_name']) in child_names]
        print("new items in set: " + str(items_in_set))

        return items_to_delete, set_data, items_in_set

    def delete_asset_json(self, items_to_delete, set_name):
        print("deleting asset")
        set_file_dir = os.path.join(Project().get_assets_dir(), set_name, "model", "main", "cache")
        delete_dir = "backup"
        print(set_file_dir)
        if not os.path.isdir(os.path.join(set_file_dir, delete_dir)):
            os.makedirs(os.path.join(set_file_dir, delete_dir))
        for item in items_to_delete:
            for ver_num in range(int(item['version_number']) + 1):
                file_name = str(item['asset_name']) + '_' + str(ver_num) + '.json'
                old_abs_path = os.path.join(set_file_dir, file_name)
                new_abs_path = os.path.join(set_file_dir, delete_dir, file_name)
                print('moving: ' + file_name + ' to ' + os.path.join(delete_dir, file_name))
                print(old_abs_path)
                print(new_abs_path)
                #need to put this in a try catch block to avoid unnamed asset errors
                try:
                    os.rename(old_abs_path, new_abs_path)
                except:
                    print(old_abs_path + ' file doesn\t exist')

    def get_path_point_starting_num(self, geo, path):
        starting_point = None
        found = False
        for point in geo.points():
            for prim in point.prims():
                if str(path) in str(prim.attribValue("path")):
                    starting_point = point
                    found = True
                    break
            if found is True:
                break
        if not starting_point:
            qd.warning("Could not find the correct path for " + str(path) + ". Transform may be incorrect.")
            start_num = 0
        else:
            print("start point: ", starting_point)
            start_num = starting_point.number()
        return start_num

    def get_points_from_path(self, geo, point_num, num_points = 3):
        pointList = []
        for i in range(num_points):
            pointList.append(geo.iterPoints()[point_num + i])
        return pointList;

    def get_position_from_point(self, point):
        return point.position()[0], point.position()[1], point.position()[2]

    def get_prim_path(self, out):
        geo = out.geometry()
        try:
            pathList = geo.findPrimAttrib("path").strings()
        except:
            print("path attribute doesn't exist on object (error in update_points_by_geo)")
            return
        for path in pathList:
            start_num = self.get_path_point_starting_num(geo, path)

            point_a, point_b, point_c = self.get_points_from_path(geo, start_num, 3)

            a_x, a_y, a_z = self.get_position_from_point(point_a)
            b_x, b_y, b_z = self.get_position_from_point(point_b)
            c_x, c_y, c_z = self.get_position_from_point(point_c)

            c_a = np.array([c_x - a_x, c_y - a_y, c_z - a_z])
            b_a = np.array([b_x - a_x, b_y - a_y, b_z - a_z])

            c_a_norm = np.linalg.norm(c_a)
            b_a_norm = np.linalg.norm(b_a)

            if not np.array_equal(c_a/c_a_norm, b_a/b_a_norm) and not np.array_equal(c_a/c_a_norm, -1 * b_a/b_a_norm):
                break;
            print(path + '\'s first 3 points are in a line')
        return path

    def update_points_by_geo(self, out, path, a, b, c):

        geo = out.geometry()
        print("Updating points by geo:")
        print("Out is " + str(out))
        print("path: " + str(path))
        print("a: " + str(a))
        print("b: " + str(b))
        print("c: " + str(c))

        start_num = self.get_path_point_starting_num(geo, path)

        point_a, point_b, point_c = self.get_points_from_path(geo, start_num, 3)

        a_x, a_y, a_z = self.get_position_from_point(point_a)
        b_x, b_y, b_z = self.get_position_from_point(point_b)
        c_x, c_y, c_z = self.get_position_from_point(point_c)

        a[0] = a_x
        a[1] = a_y
        a[2] = a_z
        b[0] = b_x
        b[1] = b_y
        b[2] = b_z
        c[0] = c_x
        c[1] = c_y
        c[2] = c_z

    def get_full_transform(self, child):
        try:
            tx = child.parm("tx").evalAsFloat()
            ty = child.parm("ty").evalAsFloat()
            tz = child.parm("tz").evalAsFloat()
            rx = child.parm("rx").evalAsFloat()
            ry = child.parm("ry").evalAsFloat()
            rz = child.parm("rz").evalAsFloat()
            sx = child.parm("sx").evalAsFloat()
            sy = child.parm("sy").evalAsFloat()
            sz = child.parm("sz").evalAsFloat()
            px = child.parm("px").evalAsFloat()
            py = child.parm("py").evalAsFloat()
            pz = child.parm("pz").evalAsFloat()
            scale = child.parm("scale").evalAsFloat()

            return tx, ty, tz, rx, ry, rz, sx, sy, sz, px, py, pz, scale
        except:
            print("ERROR OCCURRED IN GET_FULL_TRANSFORM: " + str(child) + " had an issue with transforms")
            return 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0

    def set_space(self, child, set_name, child_name, version_number):
        if child.type().name() == "dcc_geo":
            child.parm("space").set("set")
            child.parm("space").eval()
            child.parm("set").set(set_name)
            child.parm("set").eval()

        child.parm("asset_name").set(child_name)
        child.parm("asset_name").eval()
        child.parm("version_number").set(version_number)
        child.parm("version_number").eval()

    def clear_transform(self, child):
        parm_scale_list = ["sx", "sy", "sz", "scale"]
        parm_list = ["tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz", "scale"]

        for parm in parm_list:
            if parm not in parm_scale_list:
                child.parm(parm).set(0.0)
            else:
                child.parm(parm).set(1.0)
            child.parm(parm).eval()

    def update_set_dressing_transform(self, setNode):
        print("Updating set_dressing_transform....")
        print(setNode)
        insideNode = setNode.children()
        setNode = insideNode[0]
        propNodes = setNode.children()
        print("Path to Set: " + str(setNode.path()))
        print("Nodes inside the set: " + str(propNodes))
        for geo in propNodes:
            tx, ty, tz, rx, ry, rz, sx, sy, sz, px, py, pz, scale = self.get_full_transform(geo)

            scaleValue = 1.0
            if geo.parm("Scale_Object").evalAsInt() == 1:
                try:
                    scaleValue = 1.0/geo.node("Scale_object_transform").parm("scale").eval()
                except:
                    print("ERROR: Scale value might be zero? Cannot divide by zero")
                    scaleValue = 1.0

            inside = geo.node("inside")
            transformNode = inside.node("set_dressing_transform")

            old_tx, old_ty, old_tz, old_rx, old_ry, old_rz, old_sx, old_sy, old_sz, old_px, old_py, old_pz, old_scale = self.get_full_transform(transformNode)
            old_sx -= 1.0
            old_sy -= 1.0
            old_sz -= 1.0
            old_scale -= 1.0

            transformNode.parm("tx").set(tx*scaleValue + old_tx)
            transformNode.parm("ty").set(ty*scaleValue + old_ty)
            transformNode.parm("tz").set(tz*scaleValue + old_tz)
            transformNode.parm("rx").set(rx + old_rx)
            transformNode.parm("ry").set(ry + old_ry)
            transformNode.parm("rz").set(rz + old_rz)
            transformNode.parm("sx").set(sx + old_sx)
            transformNode.parm("sy").set(sy + old_sy)
            transformNode.parm("sz").set(sz + old_sz)
            transformNode.parm("px").set(px*scaleValue + old_px)
            transformNode.parm("py").set(py*scaleValue + old_py)
            transformNode.parm("pz").set(pz*scaleValue + old_pz)
            transformNode.parm("scale").set(scale + old_scale)

            self.clear_transform(geo)


# create object "5 movies" - create movielist - print stoixeia twn tainiwn
from Lesson5.model.Car import Car
from Lesson5.model.Movie import Movie

# nissan 350z toyota supra mitsubishi evo 4 doors

nissan = Car("nissan", "350z", "2000", "2")
toyota = Car("toyota", "supra", "1992", "2")
evo = Car("mitsubishi", "evo", "1995", "4")

list = [nissan, toyota, evo]

print(list[1].manufacturer)

for i in list:
    print(i.manufacturer + " " + i.model + " " + i.releaseDate + " " + i.doors)

i = 0
while i < len(list):
    print(list[i].manufacturer + " " + list[i].model + " " + list[i].releaseDate + " " + list[i].doors)
    i += 1

print(type(nissan))


import random
import json
import os
import sys
import copy
import markovify
import numpy.random as npr

# Getting additional modules from the rpgbot directory
dir_p = os.path.dirname(os.path.realpath(__file__))
base_dir = dir_p + '\\..\\..\\..'
sys.path.append(base_dir)
import gen.char as char # noqa

class ChurchCreator:
    '''
        An abstract class designed to contain all of the methods
        used to create a church, including all details
        surrounding the church itself.

        Attributes:
            seed (str): an alphanumeric value intended to seed the RNG
    '''

    def __init__(self, seed=None):
        '''
            Initializes the class.

            Args:
                seed (str): for seeding the RNG
        '''
        if seed is not None:
            random.seed(seed)
            npr.seed(seed)

        # Setting filepaths
        adj_path = base_dir + "\\rsrc\\gnrl\\adjs.json"
        noun_path = base_dir + "\\rsrc\\gnrl\\nouns.json"
        desc_path = base_dir + '\\corp\\desc\\chrch.txt'
        spec_word_path = base_dir + '\\rsrc\\spec\\words.json'

        # Pull information from the resource directory
        self._nouns = json.loads(open(noun_path).read())['nouns']
        self._adjs = json.loads(open(adj_path).read())['adjs']
        self._sy = json.loads(open(spec_word_path).read())["chrch"]

        # Pull the desc corpus from the corp directory
        with open(desc_path) as f:
            desc_corpus = f.read()
            self._desc_model = markovify.Text(desc_corpus)

    def gen_name(self):
        '''
            Creates a random name for the Church.

            Returns:
                A string containing the name of the Church.
        '''
        noun = random.choice(self._nouns).capitalize()
        adj = random.choice(self._adjs).capitalize()
        sy = random.choice(self._sy)
        name = "{} of the {} {}".format(sy, adj, noun)
        return name

    def gen_desc(self):
        '''
            Creates a description for the Church object.

            Returns:
                A string describing the church's origins, nature
                and/or physical appearance.
        '''
        no_sent = random.randint(0, 2)
        desc = self._desc_model.make_short_sentence(150)
        for i in range(no_sent):
            desc = desc + " " + self._desc_model.make_short_sentence(150)
        return desc

    def gen_occu(self):
        '''
            Creates random characters which 'occupy' the church.

            Returns:
                A list of Character objects.
        '''
        no_occ = random.randint(1, 3)
        occu = []
        creator = char.CharacterCreator()
        for i in range(no_occ):
            occu.append(creator.gen_char().get_json())
        return occu

    def gen_chrch(self):
        ''' Creates and returns a Church object '''
        chrchdict = dict()
        chrchdict["name"] = self.gen_name()
        chrchdict["desc"] = self.gen_desc()
        chrchdict["occu"] = self.gen_occu()
        return Church(chrchdict)

class Church:
    '''
        An abstract class designed to represent a particular church,
        including all of its particular attributes.

        Attributes:
            name (str): The name of the church.
            desc (str): A description of the church.
            occu (list(Character)): The occupants of the church.
            type (str): The type of building ("chrch").
    '''

    def __init__(self, chrchdict):
        '''
            Initializes the class and its attributes.

            Args:
                shopdict (dict) : A dictionary containing all relevant
                                  information about the church.

        '''
        self.dict = copy.deepcopy(chrchdict)
        self.dict["type"] = "chrch"

    def __format__(self, form):
        return eval(form)

    def get_json(self):
        return self.dict


import argparse
import os
import json
import random
import numpy as np
import torch
from LAUG.nlu.jointBERT_new.dataloader import Dataloader
from LAUG.nlu.jointBERT_new.jointBERT import JointBERT

def set_seed(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)

parser = argparse.ArgumentParser(description="Test a model.")
parser.add_argument('--config_path',
                    help='path to config file')

if __name__ == '__main__':
    args = parser.parse_args()
    config = json.load(open(args.config_path))
    data_dir = config['data_dir']
    output_dir = config['output_dir']
    log_dir = config['log_dir']
    DEVICE = config['DEVICE']

    set_seed(config['seed'])

    if 'multiwoz' in data_dir:
        print('-'*20 + 'dataset:multiwoz' + '-'*20)
        from LAUG.nlu.jointBERT_new.multiwoz.postprocess import is_slot_da, calculateF1, recover_intent
    elif 'camrest' in data_dir:
        print('-' * 20 + 'dataset:camrest' + '-' * 20)
        from LAUG.nlu.jointBERT_new.camrest.postprocess import is_slot_da, calculateF1, recover_intent
    elif 'crosswoz' in data_dir:
        print('-' * 20 + 'dataset:crosswoz' + '-' * 20)
        from LAUG.nlu.jointBERT_new.crosswoz.postprocess import is_slot_da, calculateF1, recover_intent
    elif 'frames' in data_dir:
        print('-' * 20 + 'dataset:frames' + '-' * 20)
        from LAUG.nlu.jointBERT_new.frames.postprocess import is_slot_da, calculateF1, recover_intent

    intent_vocab = json.load(open(os.path.join(data_dir, 'intent_vocab.json')))
    tag_vocab = json.load(open(os.path.join(data_dir, 'tag_vocab.json')))
    req_vocab = json.load(open(os.path.join(data_dir, 'req_vocab.json')))
    req_slot_vocab = json.load(open(os.path.join(data_dir, 'req_slot_vocab.json')))
    slot_intent_vocab = json.load(open(os.path.join(data_dir,'slot_intent_vocab.json')))

    dataloader = Dataloader(intent_vocab=intent_vocab, tag_vocab=tag_vocab, req_vocab=req_vocab, req_slot_vocab=req_slot_vocab, slot_intent_vocab=slot_intent_vocab,
                            pretrained_weights=config['model']['pretrained_weights'])
    print('intent num:', len(intent_vocab))
    print('tag num:', len(tag_vocab))
    print('req_vocab = ', req_vocab)
    print('='*100)
    for data_key in ['val', 'test']:
        dataloader.load_data(json.load(open(os.path.join(data_dir, '{}_data.json'.format(data_key)))), data_key,
                             cut_sen_len=0, use_bert_tokenizer=config['use_bert_tokenizer'])
        print('{} set size: {}'.format(data_key, len(dataloader.data[data_key])))

    if not os.path.exists(output_dir):
        os.makedirs(output_dir)
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)

    model = JointBERT(config['model'], DEVICE, dataloader.tag_dim, dataloader.intent_dim,dataloader.req_dim,dataloader=dataloader)
    model.load_state_dict(torch.load(os.path.join(output_dir, 'pytorch_model.bin'), DEVICE))
    model.to(DEVICE)
    model.eval()

    batch_size = config['model']['batch_size']

    data_key = 'test'
    predict_golden = {'intent': [], 'slot': [], 'req':[],'overall': []}
    slot_loss, intent_loss,req_loss= 0, 0, 0
    for pad_batch, ori_batch, real_batch_size in dataloader.yield_batches(batch_size, data_key=data_key):
        pad_batch = tuple(t.to(DEVICE) for t in pad_batch)
        word_seq_tensor, tag_seq_tensor, intent_tensor, req_tensor, req_mask_tensor, word_mask_tensor, tag_mask_tensor, base_tag_mask_tensor, context_seq_tensor, context_mask_tensor = pad_batch
        if not config['model']['context']:
            context_seq_tensor, context_mask_tensor = None, None

        with torch.no_grad():
            slot_logits, intent_logits,req_logits, batch_slot_loss, batch_intent_loss, batch_req_loss = model.forward(word_seq_tensor,
                                                                                word_mask_tensor,
                                                                                tag_seq_tensor,
                                                                                tag_mask_tensor,
                                                                                intent_tensor,
                                                                                req_tensor,
                                                                                req_mask_tensor,
                                                                                context_seq_tensor,
                                                                                context_mask_tensor)
        slot_loss += batch_slot_loss.item() * real_batch_size
        intent_loss += batch_intent_loss.item() * real_batch_size
        req_loss += batch_req_loss.item() * real_batch_size
        for j in range(real_batch_size):
            predict_intent,predict_req, predict_slot, predict_overall = recover_intent(dataloader, intent_logits[j], req_logits[j*dataloader.req_dim: (j+1)*dataloader.req_dim], slot_logits[j*dataloader.slot_intent_dim:(j+1)*dataloader.slot_intent_dim], base_tag_mask_tensor[j*dataloader.slot_intent_dim:(j+1)*dataloader.slot_intent_dim],
                                        ori_batch[j][0], ori_batch[j][-4])
            predict_golden['overall'].append({
                'predict': predict_overall,
                'golden': ori_batch[j][3]
            })
            predict_golden['req'].append({
                'predict':predict_req,
                'golden':ori_batch[j][5] #req
            })
            '''
            predict_golden['slot'].append({
                'predict': predict_slot,#[x for x in predicts if is_slot_da(x)],
                'golden': ori_batch[j][1]#tag
            })
            '''
            predict_golden['intent'].append({
                'predict': predict_intent,
                'golden': ori_batch[j][2]#intent
            })
        print('[%d|%d] samples' % (len(predict_golden['overall']), len(dataloader.data[data_key])))

    total = len(dataloader.data[data_key])
    slot_loss /= total
    intent_loss /= total
    print('%d samples %s' % (total, data_key))
    print('\t slot loss:', slot_loss)
    print('\t intent loss:', intent_loss)

    for x in ['intent', 'req', 'overall']:
        precision, recall, F1 = calculateF1(predict_golden[x], x=='overall')
        print('-' * 20 + x + '-' * 20)
        print('\t Precision: %.2f' % (100 * precision))
        print('\t Recall: %.2f' % (100 * recall))
        print('\t F1: %.2f' % (100 * F1))

    output_file = os.path.join(output_dir, 'output.json')
    json.dump(predict_golden['overall'], open(output_file, 'w', encoding='utf-8'), indent=2, ensure_ascii=False)


from opencog.atomspace import types, TruthValue
import formulas
from spatiotemporal import temporal_formulas
from opencog.atomspace import get_type_name
from pln.rule import Rule

'''
go_shopping_1 contains get_cool_stuff_1
go_shopping_2 contains get_cool_stuff_2

go_shopping contains get_cool_stuff

how to do that kind of reasoning?
'''

class TemporalRule(Rule):
    """
    Base class for temporal Rules. They evaluate a time relation such
    as BeforeLink, based on some AtTimeLinks.
    """
    # TODO it can't use the formulas directly. They require some
    # preprocessing to create a temporal-distribution-dictionary
    # out of some AtTimeLinks. And how to find all of the AtTimeLinks
    # for an Atom?
    # Easy way: the inputs here will eventually find every element of
    # A and B, so just recalculate every time.
    def __init__(self, chainer, link_type, formula):
        A = chainer.new_variable()
        B = chainer.new_variable()
        ta = chainer.new_variable()
        tb = chainer.new_variable()

        Rule.__init__(self,
                      formula=formula,
                      outputs=[chainer.link(link_type, [A, B])],
                      inputs=[chainer.link(types.AtTimeLink, [ta, A]),
                              chainer.link(types.AtTimeLink, [tb, B])])

        self.name = get_type_name(link_type) + 'EvaluationRule'

        self.probabilistic_inputs = False

    def temporal_compute(self, input_tuples):
        links_a = []
        links_b = []
        for (link_a, link_b) in input_tuples:
            links_a.append(link_a)
            links_b.append(link_b)

        dist1 = make_distribution(links_a)
        dist2 = make_distribution(links_b)

        strength = self.formula(dist1, dist2)

        # I'm not sure what to choose for this
        count = len(input_tuples)
        tv = TruthValue(strength, count)

        # Todo: The variable 'target' is not defined, so this doesn't work
        return [(target, tv)]

def make_distribution(time_links):
    dist = {}
    for link in time_links:
        time = get_integer(link.out[0])
        fuzzy_tv = link.tv.mean
        dist[time] = fuzzy_tv

    return dist

def get_integer(time_node):
    return int(time_node.name)

class TemporalTransitivityRule(Rule):
    # Todo:
    # Hackily infer transitive temporal relationships using the
    # deduction formula
    # This Rule is important but the TV formula is wrong
    def __init__(self,
                 chainer,
                 link_type,
                 formula=formulas.deductionIndependenceBasedFormula):
        A = chainer.new_variable()
        B = chainer.new_variable()
        C = chainer.new_variable()

        Rule.__init__(self,
                      formula=formula,
                      outputs=[chainer.link(link_type, [A, C])],
                      inputs=[chainer.link(link_type, [A, B]),
                              chainer.link(link_type, [B, C])])

        self.name = get_type_name(link_type) + 'TransitivityRule'

        self.probabilistic_inputs = False

# there should also be temporal modus ponens too (to predict that
# something will happen)

class PredictiveAttractionRule(Rule):
    def __init__(self, chainer):
        A = chainer.new_variable()
        B = chainer.new_variable()
        Rule.__init__(self,
                      formula=formulas.identityFormula,
                      outputs=[chainer.link(types.PredictiveAttractionLink,
                                            [A, B])],
                      inputs=[chainer.link(types.AndLink,
                                           [chainer.link(types.AttractionLink,
                                                         [A, B]),
                                            chainer.link(types.BeforeLink,
                                                         [A, B])])])

def create_temporal_rules(chainer):
    rules = []

    # directly evaluate temporal links
    combinations = [
        (types.BeforeLink, temporal_formulas.beforeFormula),
        (types.OverlapsLink, temporal_formulas.overlapsFormula),
        (types.DuringLink, temporal_formulas.duringFormula),
        (types.MeetsLink, temporal_formulas.meetsFormula),
        (types.StartsLink, temporal_formulas.startsFormula),
        (types.FinishesLink, temporal_formulas.finishesFormula),
        (types.EqualsLink, temporal_formulas.equalsFormula)]

    for (type, formula) in combinations:
        rules.append(TemporalRule(chainer, type, formula))

    for type, _ in combinations:
        # use temporal links to evaluate more temporal links
        rules.append(TemporalTransitivityRule(chainer, type))

    # Use the wrong formula to predict events
    #rules.append(ModusPonensRule(chainer, types.BeforeLink))

    #rules.append(PredictiveAttractionRule(chainer))

    return rules

    # There are lots of reverse links, (like (After x y) = (Before y x)
    # It seems like those would just make it dumber though?


from selenium import webdriver

def run():

    #open the driver
    driver = webdriver.Chrome(r'C:\Users\Iv\Downloads\chrome\chromedriver.exe')
    #get the web page
    driver.get('http://www.google.com/xhtml')
    # find the name="" in the html
    search_box = driver.find_element_by_name('q')
    # type "ChromeDriver" + enter
    search_box.send_keys('ChromeDriver')
    search_box.submit()

    driver.quit()


import torch

from . import utils

class Metric:
    @staticmethod
    def anisotropic_reconstruction(x, current, verts, faces,
                                   face_normals, bdry_edges):
        bs = x.shape[0]

        reshaped_faces = faces.view(bs, -1, 1).expand(-1, -1, 3)
        face_verts = torch.gather(verts, 1,
                                  reshaped_faces).view(-1, 3, 3)
        sq_dists, closest_faces = utils.point_face_distance(
            x.view(-1, 3),
            torch.tensor([x.shape[1] * i for i in range(bs)]).to(x.device),
            face_verts,
            torch.tensor([faces.shape[1] * i for i in range(bs)]).to(x.device),
            x.shape[1]
        )

        sq_dists_edges = utils.point_edge_distance(
            x.reshape(-1, 3),
            torch.tensor([x.shape[1] * i for i in range(bs)]).to(x.device),
            bdry_edges.view(-1, 2, 3),
            torch.tensor([bdry_edges.shape[1] * i
                          for i in range(bs)]).to(x.device),
            x.shape[1]
        )[0]
        bdry_idxs = (sq_dists - sq_dists_edges).abs() < 1e-5

        closest_normals = face_normals.flatten(0, 1)[closest_faces].view(
            bs, -1, 3)

        sq_dists = sq_dists[:, None]
        eps = torch.ones_like(sq_dists)
        eps[bdry_idxs] = 0
        eps = eps.view(bs, -1, 1)

        out = (current + (torch.sqrt(1-eps) - 1) *
               torch.einsum('abi,abj,abj->abi', closest_normals,
                            closest_normals, current))
        return out

    @staticmethod
    def uniform(x=None, current=None, verts=None, faces=None,
                face_normals=None, bdry_edges=None):
        return current


import asyncio

import pytest
from casbin import Enforcer
from tortoise import Tortoise

from casbin_tortoise_adapter import CasbinRule, TortoiseAdapter

@pytest.fixture(scope="session")
def event_loop():
    loop = asyncio.get_event_loop()
    yield loop
    loop.close()

@pytest.fixture(scope="session")
async def adapter():
    # connect to db and generate schemas
    await Tortoise.init(
        {
            "connections": {
                "default": "postgres://postgres:password@test-db:5432/casbin"
            },
            "apps": {"my_app": {"models": ["casbin_tortoise_adapter"]}},
        },
        _create_db=True,
    )
    await Tortoise.generate_schemas()

    # insert test cases into the db, ensure to cleanup afterwards
    try:
        yield TortoiseAdapter()
    finally:
        await Tortoise._drop_databases()
        await Tortoise.close_connections()

@pytest.fixture
async def enforcer(adapter):
    yield Enforcer("tests/rbac_model.conf", adapter)

@pytest.fixture
async def mock_data():
    await CasbinRule.all().delete()
    await CasbinRule.bulk_create(
        [
            CasbinRule(ptype="p", v0="alice", v1="data1", v2="read"),
            CasbinRule(ptype="p", v0="data2_admin", v1="data2", v2="read"),
            CasbinRule(ptype="p", v0="bob", v1="data2", v2="write"),
            CasbinRule(ptype="p", v0="data2_admin", v1="data2", v2="write"),
            CasbinRule(ptype="g", v0="alice", v1="data2_admin"),
        ]
    )


import pandas as pd
from docx import Document

HST322J=[]

import sys

def extract_table(table_index,user_name):
    document=Document(r"colg.docx")

    table_data=[]
    table=document.tables[table_index]
    for row in table.rows:
        row_data=[]
        for cell in row.cells:
            row_data.append(cell.text.strip())
        table_data.append(row_data)
    df=pd.DataFrame(table_data[1:],columns=table_data[0])

    new_count=0

    for index,row in df.iterrows():
        value=row["Subjects1"]
        if user_name in value:
            value=df.loc[index,"ClassRollNo"]
            if value.isdigit()!=True:
                print(df.iloc[index])
                new_count+=1
            HST322J.append(value)

for i in range(17):
    extract_table(i,"PLS322J")

print(HST322J)
print(f"total no of studetns are {len(HST322J)}")
count=0

with open("roolno.txt",'w') as file:
    for data in HST322J:
        file.write(data+ ",")

for i in HST322J:
    if i.isdigit():
        count=count+1

print(f"new counter value is {count}")


from kivy.lang import Builder
from kivy.properties import NumericProperty, StringProperty, BooleanProperty

Builder.load_file("equipment.kv")

from entity import Entity, EntityDict

class EquipmentWidget(Entity):
    """ Equipment object """
    value = BooleanProperty(False)
    entity_type = 'equipment'
    update_interval = 10

    def __init__(self, id, name, state, c):
        super(EquipmentWidget, self).__init__(id, name, c)
        self.value = state
        self.update_timer.cancel()

    def postState(self, state):
        # Check whether the value has changed and if so post the new state to Reef-pi
        if self.value != state:
            self.connection.api_post(category='equipment', command='control', post_data=state, id=self.id)
            self.value = state

class EquipmentDict(EntityDict):
    """ A dictionary of equipment objects. Requires a reef-pi connection. """
    update_interval = 10 # Update the EquipmentDict every 10 seconds
    dict_type = "equipment"

    def __init__(self, c, **kwargs):
        super(EquipmentDict, self).__init__(c, **kwargs)

    def createItem(self, attributes, c):
        new_item = EquipmentWidget(attributes.get('id'), attributes.get('name'), attributes.get('state'), c)
        return new_item


'''
Write a program that reads a file and prints the letters in decreasing order of frequency.
Your program should convert all the input to lower case and only count the letters a-z.
Your program should not count spaces, digits, punctuation, or anything other than the letters a-z.
Find text samples from several different languages and see how letter frequency varies between languages.
Compare your results with the tables at https://wikipedia.org/wiki/Letter_frequencies.
'''

fhand = open('mbox-short.txt')

letters=dict()
for line in fhand :
    words = line.strip().split()
    for word in words :
        for letter in word :
            if letter.isalpha() :
                letter = letter.lower()
                letters[letter] = letters.get(letter,0) + 1

lst = list()
for k,v in sorted(letters.items()) : lst.append((v,k))
lst = sorted(lst, reverse=True)

for letter in lst :
    print(letter)


from __future__ import print_function, division

import os

import matplotlib.pyplot as plt
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.onnx
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import torchvision.io.image
from torchvision import datasets
from PIL import Image

def imshow(img):
    img = img / 2+0.5
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

def get_dataset(data_dir, data_transforms):
    image_dataset = datasets.ImageFolder(data_dir, data_transforms)
    dataset_size = len(image_dataset)
    classes = image_dataset.classes
    dataloader = torch.utils.data.DataLoader(image_dataset, batch_size=4, num_workers=4)
    return dataloader, classes, dataset_size

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 13 * 13, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 84)
        self.fc4 = nn.Linear(84, 2)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 13 * 13)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = self.fc4(x)
        return x

dir = os.path.abspath(os.curdir)
data_dir = os.path.join(dir, "faces/test")

data_transforms = transforms.Compose([
    transforms.RandomResizedCrop(64),
    transforms.ToTensor(),
    transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])

if __name__ == '__main__':
    PATH = os.path.join(dir, "face_model.pth")
    net = Net()
    net.load_state_dict(torch.load(PATH))

    print('filename,label')
    with torch.no_grad():
        for i in range(11582):
            if os.path.isfile(f'faces/test/unclassified/ {i + 1}.png'):
                image = Image.open(f'faces/test/unclassified/ {i + 1}.png')
                transformed = data_transforms(image)

                outputs = net(torch.reshape(transformed, (1, 3, 32, 32)))
                _, predicted = torch.max(outputs.data, 1)

                print(f'{i + 1}.png,{int(predicted)}')