import os
from locbert import optimization
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
import random
from utils import datautils
import config

global_vals = tf.constant(np.random.uniform(-5, -4, (3, 5)), tf.float32)

def get_ragged_vals(max_n_vals):
    all_vals = [[random.uniform(-1, 1) for _ in range(max_n_vals)]]
    for i in range(7):
        vals = list()
        rand_l = random.randint(1, max_n_vals)
        # print(rand_l)
        for _ in range(rand_l):
            vals.append(random.uniform(-1, 1))
        all_vals.append(vals)
    return all_vals

class DataGen:
    def __init__(self):
        pass

    def __iter__(self):
        return self.gen_val()

    def gen_val(self):
        for _ in range(3):
            yield tf.constant(np.random.uniform(-1, 1, (3, 5))), -1

# def input_fn():
#     print('CALLLLLLLLLLLLLLLLLLLL input fn')
#     def data_gen():
#         for _ in range(3):
#             yield np.random.uniform(-1, 1, (3, 5)), -1
#
#     dataset = tf.data.Dataset.from_generator(
#         data_gen,
#         output_types=(tf.float32, tf.int32))
#     return dataset

def get_padded_bert_input(tok_id_seqs):
    max_seq_len = max(len(seq) for seq in tok_id_seqs)
    tok_id_seq_batch = np.zeros((len(tok_id_seqs), max_seq_len), np.int32)
    input_mask = np.zeros((len(tok_id_seqs), max_seq_len), np.int32)
    for i, seq in enumerate(tok_id_seqs):
        tok_id_seq_batch[i][:len(seq)] = seq
        for j in range(len(seq)):
            input_mask[i][j] = 1
    return tok_id_seq_batch, input_mask

def to_one_hot(inds, vec_len):
    v = np.zeros(vec_len, dtype=np.float32)
    for ind in inds:
        v[ind] = 1
    return v

def input_fn():
    import json
    from locbert import tokenization

    batch_size = 4
    data_file = '/data/hldai/data/ultrafine/uf_data/crowd/test.json'
    type_vocab_file = '/data/hldai/data/ultrafine/uf_data/ontology/types.txt'
    reader_module_path = '/data/hldai/data/realm_data/cc_news_pretrained/bert'
    vocab_file = os.path.join(reader_module_path, 'assets/vocab.txt')
    tokenizer = tokenization.FullTokenizer(vocab_file, do_lower_case=True)

    types, type_id_dict = datautils.load_vocab_file(type_vocab_file)
    n_types = len(types)

    # texts = ['He is a teacher.',
    #          'He teaches his students.',
    #          'He is a lawyer.']
    texts = list()

    all_labels = list()
    with open(data_file, encoding='utf-8') as f:
        for i, line in enumerate(f):
            x = json.loads(line)
            text = '{} {} {}'.format(
                ' '.join(x['left_context_token']), x['mention_span'], ' '.join(x['right_context_token']))
            # print(text)
            texts.append(text)
            labels = x['y_str']
            tids = [type_id_dict.get(t, -1) for t in labels]
            tids = [tid for tid in tids if tid > -1]
            # if i > 5:
            all_labels.append(tids)
            if len(texts) >= 8:
                break
    print(len(texts), 'texts')

    def tok_id_seq_gen():
        tok_id_seqs = list()
        y_vecs = list()
        for i, text in enumerate(texts):
            tokens = tokenizer.tokenize(text)
            # print(tokens)
            tokens_full = ['[CLS]'] + tokens + ['[SEP]']
            tok_id_seq = tokenizer.convert_tokens_to_ids(tokens_full)
            # tok_id_seq = np.array([len(text)], np.float32)
            tok_id_seqs.append(tok_id_seq)
            y_vecs.append(to_one_hot(all_labels[i], n_types))
            if len(tok_id_seqs) >= batch_size:
                # tok_id_seq_batch, input_mask = get_padded_bert_input(tok_id_seqs)
                tok_id_seq_batch = tf.ragged.constant(tok_id_seqs)
                # y_vecs_tensor = tf.concat(y_vecs)
                yield {'tok_id_seq_batch': tok_id_seq_batch,
                       # 'input_mask': input_mask,
                       'vals': np.random.uniform(-1, 1, (3, 5))}, y_vecs
                tok_id_seqs = list()
                y_vecs = list()
        if len(tok_id_seqs) > 0:
            # tok_id_seq_batch, input_mask = get_padded_bert_input(tok_id_seqs)
            # y_vecs_tensor = tf.concat(y_vecs)
            tok_id_seq_batch = tf.ragged.constant(tok_id_seqs)
            yield {'tok_id_seq_batch': tok_id_seq_batch,
                   # 'input_mask': input_mask,
                   'vals': np.random.uniform(-1, 1, (3, 5))}, y_vecs

    # for v in iter(tok_id_seq_gen()):
    #     print(v)
    dataset = tf.data.Dataset.from_generator(
        tok_id_seq_gen,
        output_signature=(
            {
                'tok_id_seq_batch': tf.RaggedTensorSpec(dtype=tf.int32, ragged_rank=1),
                # 'tok_id_seq_batch': tf.TensorSpec(shape=None, dtype=tf.int32),
                # 'input_mask': tf.TensorSpec(shape=None, dtype=tf.int32),
                'vals': tf.TensorSpec(shape=None, dtype=tf.float32)
            },
            tf.TensorSpec(shape=None, dtype=tf.float32)))

    return dataset

def model_fn(features, labels, mode, params):
    num_train_steps = 100
    lr = 0.0001
    k = 5
    weights = tf.Variable(tf.random_normal_initializer()(shape=[k, k], dtype=tf.float32))
    cvals = tf.constant(np.random.uniform(-1, 1), tf.float32)
    reader_module_path = '/data/hldai/data/realm_data/cc_news_pretrained/bert'
    # vals_ragged = tf.ragged.constant(list(features))
    # vals_tensor = vals_ragged.to_tensor()
    # vals_tensor = features + global_vals
    vals_tensor = features['vals']
    # tok_id_seq_batch = features['tok_id_seq_batch'].to_tensor()
    # input_mask = features['input_mask']
    z = tf.matmul(vals_tensor, weights) + cvals
    predictions = z
    loss = tf.reduce_mean(z)
    eval_metric_ops = None

    # rand_vals = tf.constant(np.random.randint(100, 105, (4, 5)), dtype=tf.int32)
    # tok_id_seq_batch = tf.concat((features['tok_id_seq_batch'], rand_vals), axis=1).to_tensor()

    # with tf.device("/cpu:0"):
    #     blocks_np = datautils.load_pickle_data(os.path.join(config.DATA_DIR, 'realm_data/blocks_tok_id_seqs.pkl'))
    #     blocks = tf.ragged.constant(blocks_np)
    #     # blocks = tf.ragged.constant([[3, 4], [1], [2, 3, 7], [4]], dtype=tf.int32, ragged_rank=1)
    #     retrieved_block_ids = tf.constant([0, 2])
    #     retrieved_blocks = tf.gather(blocks, retrieved_block_ids).to_tensor()
    # logging_hook = tf.estimator.LoggingTensorHook({"pred": predictions, 'feat': features}, every_n_iter=1)
    # logging_hook = tf.estimator.LoggingTensorHook(
    #     {"pred": predictions, 'labels': labels, 'feat': features['tok_id_seq_batch'],
    #      'ids': retrieved_block_ids}, every_n_iter=1)
    ls = tf.reduce_sum(labels, axis=1)
    logging_hook = tf.estimator.LoggingTensorHook({
        'z': z, 'ls': ls}, every_n_iter=1)

    train_op = optimization.create_optimizer(
        loss=loss,
        init_lr=lr,
        num_train_steps=num_train_steps,
        num_warmup_steps=min(10000, max(100, int(num_train_steps / 10))),
        use_tpu=False)

    return tf.estimator.EstimatorSpec(
        mode=mode,
        loss=loss,
        train_op=train_op,
        predictions=predictions,
        # training_hooks=[logging_hook],
        evaluation_hooks=[logging_hook],
        eval_metric_ops=eval_metric_ops)

def train():
    params = dict()
    model_dir = '/data/hldai/data/tmp/tmpmodels'
    num_train_steps = 10

    logger = tf.get_logger()
    logger.setLevel('INFO')
    logger.propagate = False

    run_config = tf.estimator.RunConfig(
        model_dir=model_dir,
        log_step_count_steps=5,
        save_checkpoints_steps=5,
        save_checkpoints_secs=None,
        tf_random_seed=1355)
    estimator = tf.estimator.Estimator(
        config=run_config,
        model_fn=model_fn,
        params=params,
        model_dir=model_dir)
    # estimator.train(input_fn)
    # estimator.evaluate(input_fn)

    train_spec = tf.estimator.TrainSpec(
        input_fn=input_fn,
        max_steps=num_train_steps)
    eval_spec = tf.estimator.EvalSpec(
        name="default",
        input_fn=input_fn,
        # exporters=exporters,
        # start_delay_secs=FLAGS.eval_start_delay_secs,
        # throttle_secs=FLAGS.eval_throttle_secs
        )

    # estimator.evaluate(input_fn)
    tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

train()
exit()

# digits = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
# vals = tf.ragged.constant([[2, 3], [1], [], [1, 4, 9], [0]])

# print(tf.concat((digits, vals), axis=1))

# blocks_list = list()
# lens = [3, 1, 5, 2, 5, 3, 4, 2]
# # print(all_vals)
# # all_vals = get_ragged_vals(5)
# for length in lens:
#     vals = list()
#     for _ in range(length):
#         vals.append(random.uniform(-1, 1))
#     blocks_list.append(vals)
blocks_list = [[3, 4], [5, 3, 8], [8]]

def data_gen():
    for vals in blocks_list:
        yield tf.ragged.constant([vals], dtype=tf.float32)

dataset = tf.data.Dataset.from_generator(
    data_gen,
    output_signature=tf.RaggedTensorSpec(ragged_rank=1, dtype=tf.float32))

for v in dataset:
    print(v)
# dataset = dataset.apply(
#     tf.data.experimental.dense_to_ragged_batch(2))
# for v in dataset.batch(4):
#     print(v)
#     # print(v[1].to_tensor())
#     vt = v[1].to_tensor()
#     print(vt)
#     print(tf.squeeze(vt))
# for v in dataset:
#     print(v)

# tf.data.experimental.save(dataset, '/data/hldai/data/tmp/tmp.tfdata', shard_func=lambda x: np.int64(0))
# print('******************* save ************************')

# dataset = tf.data.experimental.load(
#     '/data/hldai/data/tmp/tmp.tfdata',
#     element_spec=tf.RaggedTensorSpec(ragged_rank=1, dtype=tf.float32))
# dataset = dataset.batch(8)
# all_docs = tf.data.experimental.get_single_element(dataset)
# print(all_docs)
# for v in dataset:
#     print(v)

# non_ragged_dataset = tf.data.Dataset.from_tensor_slices([1, 5, 3, 2, 8])
# non_ragged_dataset = non_ragged_dataset.map(tf.range)
# for v in non_ragged_dataset:
#     print(v)
# batched_non_ragged_dataset = non_ragged_dataset.apply(
#     tf.data.experimental.dense_to_ragged_batch(2))
# for element in batched_non_ragged_dataset:
#     print(element)

# vals_tensor = vals_ragged.to_tensor()
# weights = tf.Variable(tf.random_normal_initializer()(shape=[k, k], dtype=tf.float32))
# z = tf.matmul(vals_tensor, weights)
# print(weights)
# print(vals)
# print(vals_ragged)
# print(vals_tensor)
# print(z)


import glob
import argparse
from os import path
import matplotlib.image as pltimg
import cv2
import numpy as np
from utils import rgb2hsv
from env import *

dataset_location = path.expanduser("~/dataset/sky_pixel_swim_test.npz")

if SVM_FORM_DATA:
    img_dir = path.expanduser("~/dataset/swimseg/train/images") + "/*.png"
    mask_dir = path.expanduser("~/dataset/swimseg/train/masks") + "/*.png"
    img_paths = sorted(glob.glob(img_dir))
    mask_paths = sorted(glob.glob(mask_dir))
    data = None
    labels = None
    for img_name, mask_name in zip(img_paths, mask_paths):
         print("Forming data set {} out of 200".format(n))
         img = pltimg.imread(img_name)
         img = cv2.resize(img, dsize = (256,256))
         mask = pltimg.imread(mask_name)
         mask = cv2.resize(mask, dsize = (256,256))
         img = rgb2hsv(img)
         img_int = (img[...,2]*255).astype(np.uint8)
         img_int = cv2.equalizeHist(img_int)
         img[...,2] = img_int

         #pixel classification

         patch_data, mask_data = [], []
         i = 0
         while i < img.shape[0]:
             j = 0
             while j < img.shape[1]:
                 patch = img[i:i+SLIDING_WINDOW_SIZE,j:j+SLIDING_WINDOW_SIZE,:]
                 padded = np.zeros(shape = ( SLIDING_WINDOW_SIZE,SLIDING_WINDOW_SIZE ,3 ) )
                 padded[:patch.shape[0],:patch.shape[1]] = patch
                 padded = np.reshape(padded, (SLIDING_WINDOW_SIZE*SLIDING_WINDOW_SIZE*3))
                 patch_data.append(padded)
                 mask_data.append([np.mean(mask[i:i+SLIDING_WINDOW_SIZE,j:j+SLIDING_WINDOW_SIZE]) > 0.5])
                 j+= 1
             i+= 1

         #sliding window classification
         patch_data = np.array(patch_data)
         mask_data = np.array(mask_data)
         if data is None:
             data = patch_data
         else:
             data = np.vstack((data,patch_data))

         if labels is None:
             labels = mask_data
         else:
             labels = np.vstack((labels,mask_data))

    data = data.astype(np.float32)
    labels = np.squeeze(labels).astype(np.int32)
    print(data.shape, end = ", ")
    print(data.dtype)
    print(labels.shape, end = ", ")
    print(labels.dtype)
    np.savez(dataset_location, x = data, y = labels)

print("Loading data from {} ...".format(dataset_location))
ds = np.load(dataset_location)
data = ds['x']
labels = ds['y']
print("Data loaded. Start SVM optimization...")
# Train the SVM
svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setTermCriteria((cv2.TERM_CRITERIA_MAX_ITER, 100, 1e-6))
svm.train(data, cv2.ml.ROW_SAMPLE, labels)
svm.save('./models/svm_weights_test.xml')
print("SVM training done.")


import scipy.io as sio
import os
import io

import PIL.Image
import cv2
import tensorflow as tf

import contextlib2
import dataset_ultility as dataset_util

num_shards=5
part = "train"

flags = tf.app.flags
flags.DEFINE_string('output_path', '/home/hz/project/eye_closeness_cls/dataset/tfrecords/multi-task/MUCT/'+part,
                     'Path to output TFRecord')
# flags.DEFINE_string('dataset_root', '/data0/hz/dataset_B_FacialImages/test0.2/'+part+'/',
#                      'Root to widerface events image')
flags.DEFINE_string('dataset_root', '/data0/hz/muct_croped',
                     'Root to widerface events image')
flags.DEFINE_string('task_type', 'reg',
                      'Task that the data is labeled for.')
FLAGS = flags.FLAGS

class Example():
  def __init__(self, subdir, file_name, label_list, task_type):
    self.set_image(subdir, file_name)
    if task_type =='cls':
      self.label, self.label_text = label_list['label'], label_list['label_text']
      self.left, self.right = [-1, -1], [-1, -1] # unrelavent
      self.task_type = 0
    elif task_type =='reg':
      self.label, self.label_text = -1, "None" # unrelavent
      self.left, self.right = label_list['left'], label_list['right']
      self.task_type = 1

  def set_image(self, dataset_root, file_name):
    self.file_name = file_name.encode('utf8')

    image_path = os.path.join(dataset_root, file_name)
    print( image_path)
    cv_image = cv2.imread(image_path)
    self.image = cv_image
    self.h = cv_image.shape[0]
    self.w = cv_image.shape[1]

    with tf.gfile.GFile(image_path, 'rb') as fid:
      self.encoded_jpg = fid.read()
    encoded_jpg_io = io.BytesIO(self.encoded_jpg)
    image = PIL.Image.open(encoded_jpg_io)
    if image.format != 'JPEG':
      raise ValueError('Image format not JPEG')

def create_tf_example(example):
  print(example.w,example.h, example.file_name)

  height, width= example.h, example.w # Image width # height
  filename = example.file_name # Filename of the image. Empty if image is not from file
  encoded_image_data = example.encoded_jpg # Encoded image bytes
  image_format = b'jpeg' # b'jpeg' or b'png'

  label = example.label
  label_text = example.label_text
  left = example.left
  right = example.right
  task = example.task_type

  channels = 3
  tf_example = tf.train.Example(features=tf.train.Features(feature={
      'image/encoded':        dataset_util.bytes_feature(encoded_image_data),
      'image/format':         dataset_util.bytes_feature(image_format),
      'image/filename':       dataset_util.bytes_feature(filename),
      'image/shape':          dataset_util.int64_feature([height, width, channels]),
      'label/cls/label':      dataset_util.int64_feature(label),
      'label/cls/label_text': dataset_util.bytes_feature(label_text),
      'label/loc/left_eye':   dataset_util.float_feature(left),
      'label/loc/right_eye':  dataset_util.float_feature(right),
      'label/task_type':      dataset_util.int64_feature(task)
  }))
  # exit()
  return tf_example

def create_tf_record_cls(task_type):
  CEW_LABELS = {
    'OpenFace': {'label':0, 'label_text':'open'},
    'ClosedFace': {'label':1, 'label_text':'closed'},
  }
  dataset_root = FLAGS.dataset_root

  with contextlib2.ExitStack() as tf_record_close_stack:
    output_tfrecords = dataset_util.open_sharded_output_tfrecords(
        tf_record_close_stack, FLAGS.output_path, num_shards)

    index = 0
    for subkey in CEW_LABELS:
      subdir = os.path.join(dataset_root, subkey)
      for file in os.listdir(subdir):
          file_name = file
          label_list = CEW_LABELS[subkey]
          example = Example(subdir, file_name, label_list, task_type)

          tf_example = create_tf_example(example)
          output_shard_index = index % num_shards
          output_tfrecords[output_shard_index].write(tf_example.SerializeToString())
          index += 1
          print (index)

def apply_shift(label_list, shift_list):
  shiftxy=shift_list[:2]
  cropwh=shift_list[2:]
  label_list['left']=[ (label_list['left'][i]-shiftxy[i])/cropwh[i] for i in range(2) ]
  label_list['right']=[ (label_list['right'][i]-shiftxy[i])/cropwh[i] for i in range(2) ]
  # print(label_list)
  return label_list

def create_tf_record_reg(task_type):
  MUCT_LABELS = {
    'left_idx_shift' : 31,
    'right_idx_shift' : 73
  }
  dataset_root = FLAGS.dataset_root

  with contextlib2.ExitStack() as tf_record_close_stack:
    output_tfrecords = dataset_util.open_sharded_output_tfrecords(
        tf_record_close_stack, FLAGS.output_path, num_shards)

    index = 0
    subdir = os.path.join(dataset_root, 'jpg')
    labeldir = os.path.join(dataset_root, 'muct-landmarks', 'muct76-opencv.csv')
    cropdir = os.path.join(dataset_root, 'rect_shift.csv')

    image_crop_shift = {}
    with open(cropdir) as f:
      for line in f:
        line = line.strip().split(',')
        name, xshift, yshift, width, height = line
        image_crop_shift[name] = map(float, [xshift, yshift, width, height])

    image_labels = {}
    with open(labeldir) as f:
      for line in f:
        line = line.strip().split(',')
        if line[0]=='name':
          continue # exclude the first line as header line

        leftx =  float(line[ MUCT_LABELS['left_idx_shift']*2+2 ])
        lefty =  float(line[ MUCT_LABELS['left_idx_shift']*2+2+1 ])
        rightx = float(line[ MUCT_LABELS['right_idx_shift']*2+2 ])
        righty = float(line[ MUCT_LABELS['right_idx_shift']*2+2+1 ])
        if leftx+lefty==0 or rightx+righty==0:
          print('this image has eye occupied: '+line[0])
          exit()
        image_labels[line[0]+'.jpg'] = {'left':[leftx,lefty], 'right':[rightx,righty]}

    for file in os.listdir(subdir):
        file_name = file
        label_list = image_labels[file]
        shift_list = image_crop_shift[file]
        label_list = apply_shift(label_list, shift_list)
        example = Example(subdir, file_name, label_list, task_type)

        tf_example = create_tf_example(example)
        output_shard_index = index % num_shards
        output_tfrecords[output_shard_index].write(tf_example.SerializeToString())
        index += 1
        print (index)

def main(_):
  if FLAGS.task_type =='cls': create_tf_record_cls('cls')
  elif FLAGS.task_type =='reg': create_tf_record_reg('reg')
  else: print('unknow task type!')

if __name__ == '__main__':
  tf.app.run()


import os

import numpy as np

from pymoo.core.problem import Problem
from pymoo.util.remote import Remote

class COCOProblem(Problem):

    def __init__(self, name, n_var=10, pf_from_file=True, **kwargs):
        self.function, self.instance, self.object = get_bbob(name, n_var)
        self.name = name
        self.pf_from_file = pf_from_file

        coco = self.object
        n_var, n_obj, n_ieq_constr = coco.number_of_variables, coco.number_of_objectives, coco.number_of_constraints
        xl, xu = coco.lower_bounds, coco.upper_bounds

        super().__init__(n_var=n_var,
                         n_obj=n_obj,
                         n_ieq_constr=n_ieq_constr,
                         xl=xl,
                         xu=xu,
                         **kwargs)

    def _calc_pareto_set(self, *args, **kwargs):
        if self.n_obj == 1:
            fname = '._bbob_problem_best_parameter.txt'

            self.object._best_parameter(what="print")
            ps = np.loadtxt(fname)
            os.remove(fname)

            return ps

    def _calc_pareto_front(self, *args, **kwargs):
        if self.pf_from_file:
            return Remote.get_instance().load("pymoo", "pf", "bbob.pf", to="json")[str(self.function)][str(self.instance)]
        else:
            ps = self.pareto_set()
            if ps is not None:
                return self.evaluate(ps)

    def _evaluate(self, X, out, *args, **kwargs):
        out["F"] = np.array([self.object(x) for x in X])

    def __getstate__(self):
        d = self.__dict__.copy()
        d["object"] = None
        return d

    def __setstate__(self, d):
        self.__dict__.update(d)
        self.object = get_bbob(self.name, self.n_var)

def get_bbob(name, n_var=10, **kwargs):
    try:
        import cocoex as ex
    except:
        raise Exception("COCO test suite not found. \nInstallation Guide: https://github.com/numbbo/coco")

    args = name.split("-")

    n_instance = int(args[-1])
    n_function = int(args[-2].replace("f", ""))

    assert 1 <= n_function <= 24, f"BBOB has 24 different functions to be chosen. {n_function} is out of range."

    suite_filter_options = f"function_indices: {n_function} " \
                           f"instance_indices: {n_instance} " \
                           f"dimensions: {n_var}"

    problems = ex.Suite("bbob", "", suite_filter_options)
    assert len(problems) == 1, "COCO problem not found."

    coco = problems.next_problem()

    return n_function, n_instance, coco


import base64
import sys
import nacl.secret
import nacl.utils

def encode_additional_parameters(data):

    assert(isinstance(data, bytes))

    assert(nacl.secret.SecretBox.KEY_SIZE == 32)
    key = nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE)
    assert (len(key) == 32)
    box = nacl.secret.SecretBox(key)

    assert(nacl.secret.SecretBox.NONCE_SIZE == 24)
    if sys.version_info[0] == 2:
        # Python 2
        zero_bytes = [chr(0) for _ in range(nacl.secret.SecretBox.NONCE_SIZE)]
        nonce = ''.join(zero_bytes)
    else:
        # Python 3
        nonce = bytes([0] * nacl.secret.SecretBox.NONCE_SIZE)
    assert(len(nonce) == 24)

    encrypted = box.encrypt(data, nonce)
    ctext = encrypted.ciphertext
    assert len(ctext) == len(data) + box.MACBYTES

    payload = key + encrypted.ciphertext
    encoded = base64.b64encode(payload)

    if sys.version_info[0] == 2:
        # Python 2
        encoded_str = encoded
    else:
        # Python 3
        encoded_str = encoded.decode()
    assert(isinstance(encoded_str, str))

    return encoded_str


import sys

import cv2
import numpy as np
from skimage import io

import image_utilities as img_util

def get_image_kmeans(image, k):
    Z = image.reshape((-1,3))
    Z = np.float32(Z)
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
    K = int(k)
    ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
    center = np.uint8(center)
    res = center[label.flatten()]
    res2 = res.reshape((image.shape))
    return res2

def process_image(im):
    im_in = cv2.bitwise_not(im)

    im_blurred = cv2.blur(im_in, (60,60))

    kernel = np.ones((2,2), np.uint8)

    im_closed = cv2.dilate(im_in, kernel, iterations=1)
    im_closed = cv2.erode(im_closed, kernel, iterations=1)

    im_closed = cv2.blur(im_closed, (20,20))
    return im_closed

def flood_fill(im):
    th, im_th = cv2.threshold(im, 220, 255, cv2.THRESH_BINARY_INV)
    im_floodfill = im_th.copy()
    h, w = im_th.shape[:2]
    mask = np.zeros((h+2, w+2), np.uint8)

    # Floodfill from point (0, 0)
    cv2.floodFill(im_floodfill, mask, (0,0), 255);

    # Invert floodfilled image
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)
    im_out = im_th | im_floodfill_inv
    return im_out

def get_petal_shape(im):

    b_im = img_util.brighten_image(im, 2,0)
    kmeans = get_image_kmeans(b_im, 3)
    im_in =  cv2.cvtColor(kmeans,cv2.COLOR_BGR2GRAY)
    im_in = img_util.make_bw(im_in)
    im_closed = process_image(im_in)
    return flood_fill(im_closed)

def get_vein_shape(im):
    im_in = cv2.bitwise_not(im)

    im_blurred = cv2.blur(im_in, (60,60))
    im_blurred = cv2.blur(im_blurred, (60,60))
    # im_blurred = cv2.blur(im_blurred, (60,60))

    kernel = np.ones((2,2), np.uint8)

    im_closed = cv2.dilate(im_blurred, kernel, iterations=1)
    im_closed = cv2.erode(im_closed, kernel, iterations=1)

    im_closed = cv2.blur(im_closed, (20,20))
    # Threshold.
    # Set values equal to or above 220 to 0.
    # Set values below 220 to 255.

    th, im_th = cv2.threshold(im_closed, 220, 255, cv2.THRESH_BINARY_INV)

    # Copy the thresholded image.
    im_floodfill = im_th.copy()

    # Mask used to flood filling.
    # Notice the size needs to be 2 pixels than the image.
    h, w = im_th.shape[:2]
    mask = np.zeros((h+2, w+2), np.uint8)

    # Floodfill from point (0, 0)
    cv2.floodFill(im_floodfill, mask, (0,0), 255);

    # Invert floodfilled image
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)

    # Combine the two images to get the foreground.
    im_out = im_th | im_floodfill_inv
    return im_th


from tests import base

class HogueTestJavascript(base.HogueTest):
	def __init__(self):
		self.title = "Javascript Support"
		self.description = "Checking wether the client supports JavaScript via window.location.href entry"
		base.HogueTest.__init__(self)

	def send_http_response(self,handler):
		self.status="PROGRESS"
		redirurl = "/hogue/do?result="+self.id
		html="""
			<!DOCTYPE html>
			<html lang="en">
			<head>
				<meta charset="utf-8">
				<title>Hogue FTW</title>
			</head>
			<body>
				Hi there.
				<script language="JavaScript">
					window.location.href = '%s';
				</script>
			</body>
		""" % redirurl
		handler.send_response(200)
		handler.send_header('Content-type','text/html')
		handler.end_headers()
		handler.wfile.write(html.encode())


#
# @lc app=leetcode id=892 lang=python3
#
# [892] Surface Area of 3D Shapes
#
# https://leetcode.com/problems/surface-area-of-3d-shapes/description/
#
# algorithms
# Easy (55.73%)
# Total Accepted:    10.6K
# Total Submissions: 19.1K
# Testcase Example:  '[[2]]'
#
# On a N * N grid, we place some 1 * 1 * 1 cubes.
#
# Each value v = grid[i][j] represents a tower of v cubes placed on top of grid
# cell (i, j).
#
# Return the total surface area of the resulting shapes.
#
#
#
#
#
#
#
#
#
#
#
#
#
# Example 1:
#
#
# Input: [[2]]
# Output: 10
#
#
#
# Example 2:
#
#
# Input: [[1,2],[3,4]]
# Output: 34
#
#
#
# Example 3:
#
#
# Input: [[1,0],[0,2]]
# Output: 16
#
#
#
# Example 4:
#
#
# Input: [[1,1,1],[1,0,1],[1,1,1]]
# Output: 32
#
#
#
# Example 5:
#
#
# Input: [[2,2,2],[2,1,2],[2,2,2]]
# Output: 46
#
#
#
#
# Note:
#
#
# 1 <= N <= 50
# 0 <= grid[i][j] <= 50
#
#
#
#
#
#
#
#
class Solution:
    # def surfaceArea(self, grid: List[List[int]]) -> int:
    def top_down(self, grid):
        res = 0
        for row in grid:
            for ele in row:
                if ele != 0:
                    res += 1
        return res
    def left_right(self, grid):
        res = [r[0] for r in grid]
        for r in range(len(grid)):
            for c in range(1, len(grid[0])):
                if grid[r][c] > grid[r][c-1]:
                    res[r] += grid[r][c] - grid[r][c-1]
        return sum(res)
    def right_left(self,grid):
        res = [r[-1] for r in grid]
        for r in range(len(grid)):
            for c in range(len(grid[0])-2, -1, -1):
                if grid[r][c] > grid[r][c+1]:
                    res[r] += grid[r][c] - grid[r][c+1]
        return sum(res)

    def up_bottum(self, grid):
        res = grid[0].copy()
        for r in range(1, len(grid)):
            for c in range(len(grid[0])):
                if grid[r][c] > grid[r-1][c]:
                    res[c] += grid[r][c] - grid[r-1][c]
        return sum(res)
    def bottum_up(self, grid):
        res = grid[-1].copy()
        # print(grid)
        for r in range(len(grid)-2, -1, -1):
            # print('r', r)
            for c in range(len(grid[0])):
                if grid[r][c] > grid[r+1][c]:
                    # print('r=', r, grid[r])
                    # print('r+1=', r+1, grid[r+1])
                    res[c] += grid[r][c] - grid[r+1][c]
                    # print(res)
        return sum(res)
    def surfaceArea(self, grid):
        td = self.top_down(grid)
        lr = self.left_right(grid)
        rl = self.right_left(grid)
        # print(grid)
        ub = self.up_bottum(grid)
        bu = self.bottum_up(grid)
        # print(td)
        # print(lr)
        # print(rl)
        # print(ub)
        # print(bu)
        res = td*2+lr+rl+ub+bu
        # print(res)
        return res

# s = Solution()

# grid = [[2]]
# print(s.surfaceArea(grid) == 10)

# grid = [[1,2],[3,4]]
# print(s.surfaceArea(grid) == 34)

# grid = [[1,0],[0,2]]
# print(s.surfaceArea(grid) == 16)

# grid = [[1,1,1],[1,0,1],[1,1,1]]
# print(s.surfaceArea(grid) == 32)

# grid = [[2,2,2],[2,1,2],[2,2,2]]
# print(s.surfaceArea(grid) == 46)


import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    #class to show a single alien in fleet

    def __init__(self, ai_settings, screen):
        # initialise alien and give starting location
        super(Alien, self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        # load alien image and set the rect coordinates
        self.image = pygame.image.load('alien.png')
        self.rect = self.image.get_rect()

        # start each new alien top left of screen
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        #store alien's location
        self.x = float(self.rect.x)

    def blitme(self):
        #draw alien at current location
        self.screen.blit(self.image, self.rect)

    def check_edges(self):
        # return true if alien at edge of screen
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <=0:
            return True

    def update(self):
        # move alien to the right or left
        self.x += (self.ai_settings.alien_speed_factor * self.ai_settings.fleet_direction)
        self.rect.x = self.x


import sys
sys.setrecursionlimit(10**7)
from collections import deque

n, k = map(int, input().split())

visited = [False] * (max(n, k) + 2)

def bfs(start):
    q = deque([start])
    answer = 0
    length = 1

    while q:
        v = q.popleft()
        visited[v] = True
        if v == k:
            print(answer)
            break
        else:
            if not (v - 1 <= -1):
                if not visited[v - 1]:
                    q.append(v - 1)
            if not (v + 1 >= max(n, k) + 2):
                if not visited[v + 1]:
                    q.append(v + 1)
            if not (v * 2 >= max(n, k) + 2):
                if not visited[v * 2]:
                    q.append(v * 2)

        length -= 1

        if length == 0:
            answer += 1
            length = len(q)

bfs(n)

백준 알고리즘/숨바꼭질.py


import inspect
from dataclasses import field
from datetime import date, datetime, time
from decimal import Decimal
from typing import List, Optional

from google.cloud.bigquery import SchemaField

from bq_schema.schema_converter import schema_to_dataclass
from bq_schema.types.type_mapping import Geography, Timestamp

# pylint: disable=line-too-long, too-few-public-methods
# fmt: off
class RequiredNestedField:
    int_field: int = field(metadata={"description": "This field is an INT field."})

class RequiredSchema:
    string_field: str = field(metadata={"description": "This field is a STRING field."})
    bytes_field: bytes
    int_field: int
    float_field: float
    numeric_field: Decimal
    bool_field: bool
    timestamp_field: Timestamp
    date_field: date
    time_field: time
    datetime_field: datetime
    geography_field: Geography
    required_nested_field: RequiredNestedField = field(metadata={"description": "This field is a STRUCT field."})
# fmt: on
# pylint: enable=line-too-long

def test_required_schema_to_dataclass():
    schema = [
        SchemaField(
            "string_field", "STRING", "REQUIRED", "This field is a STRING field.", ()
        ),
        SchemaField("bytes_field", "BYTES", "REQUIRED", None, ()),
        SchemaField("int_field", "INT64", "REQUIRED", None, ()),
        SchemaField("float_field", "FLOAT64", "REQUIRED", None, ()),
        SchemaField("numeric_field", "NUMERIC", "REQUIRED", None, ()),
        SchemaField("bool_field", "BOOL", "REQUIRED", None, ()),
        SchemaField("timestamp_field", "TIMESTAMP", "REQUIRED", None, ()),
        SchemaField("date_field", "DATE", "REQUIRED", None, ()),
        SchemaField("time_field", "TIME", "REQUIRED", None, ()),
        SchemaField("datetime_field", "DATETIME", "REQUIRED", None, ()),
        SchemaField("geography_field", "GEOGRAPHY", "REQUIRED", None, ()),
        SchemaField(
            "required_nested_field",
            "STRUCT",
            "REQUIRED",
            "This field is a STRUCT field.",
            (
                SchemaField(
                    "int_field", "INT64", "REQUIRED", "This field is an INT field.", ()
                ),
            ),
        ),
    ]
    expected = (
        f"@dataclass\n{inspect.getsource(RequiredNestedField)}\n"
        f"@dataclass\n{inspect.getsource(RequiredSchema)}"
    )
    assert schema_to_dataclass("RequiredSchema", schema).strip() == expected.strip()

# pylint: disable=line-too-long
# fmt: off
class NullableNestedField:
    int_field: Optional[int] = field(metadata={"description": "This field is an INT field."})

class NullableSchema:
    string_field: Optional[str] = field(metadata={"description": "This field is a STRING field."})
    bytes_field: Optional[bytes]
    int_field: Optional[int]
    float_field: Optional[float]
    numeric_field: Optional[Decimal]
    bool_field: Optional[bool]
    timestamp_field: Optional[Timestamp]
    date_field: Optional[date]
    time_field: Optional[time]
    datetime_field: Optional[datetime]
    geography_field: Optional[Geography]
    nullable_nested_field: Optional[NullableNestedField] = field(metadata={"description": "This field is a STRUCT field."})
# fmt: on
# pylint: enable=line-too-long

def test_optional_schema_to_dataclass():
    schema = [
        SchemaField(
            "string_field", "STRING", "NULLABLE", "This field is a STRING field.", ()
        ),
        SchemaField("bytes_field", "BYTES", "NULLABLE", None, ()),
        SchemaField("int_field", "INT64", "NULLABLE", None, ()),
        SchemaField("float_field", "FLOAT64", "NULLABLE", None, ()),
        SchemaField("numeric_field", "NUMERIC", "NULLABLE", None, ()),
        SchemaField("bool_field", "BOOL", "NULLABLE", None, ()),
        SchemaField("timestamp_field", "TIMESTAMP", "NULLABLE", None, ()),
        SchemaField("date_field", "DATE", "NULLABLE", None, ()),
        SchemaField("time_field", "TIME", "NULLABLE", None, ()),
        SchemaField("datetime_field", "DATETIME", "NULLABLE", None, ()),
        SchemaField("geography_field", "GEOGRAPHY", "NULLABLE", None, ()),
        SchemaField(
            "nullable_nested_field",
            "STRUCT",
            "NULLABLE",
            "This field is a STRUCT field.",
            (
                SchemaField(
                    "int_field", "INT64", "NULLABLE", "This field is an INT field.", ()
                ),
            ),
        ),
    ]
    expected = (
        f"@dataclass\n{inspect.getsource(NullableNestedField)}\n"
        f"@dataclass\n{inspect.getsource(NullableSchema)}"
    )
    assert schema_to_dataclass("NullableSchema", schema) == expected.strip()

# pylint: disable=line-too-long
# fmt: off
class RepeatedNestedField:
    int_field: List[int] = field(metadata={"description": "This field is an INT field."})

class RepeatedSchema:
    string_field: List[str] = field(metadata={"description": "This field is a STRING field."})
    bytes_field: List[bytes]
    int_field: List[int]
    float_field: List[float]
    numeric_field: List[Decimal]
    bool_field: List[bool]
    timestamp_field: List[Timestamp]
    date_field: List[date]
    time_field: List[time]
    datetime_field: List[datetime]
    geography_field: List[Geography]
    repeated_nested_field: List[RepeatedNestedField] = field(metadata={"description": "This field is a STRUCT field."})
# fmt: on
# pylint: enable=line-too-long

def test_repeated_schema_to_dataclass():
    schema = [
        SchemaField(
            "string_field", "STRING", "REPEATED", "This field is a STRING field.", ()
        ),
        SchemaField("bytes_field", "BYTES", "REPEATED", None, ()),
        SchemaField("int_field", "INT64", "REPEATED", None, ()),
        SchemaField("float_field", "FLOAT64", "REPEATED", None, ()),
        SchemaField("numeric_field", "NUMERIC", "REPEATED", None, ()),
        SchemaField("bool_field", "BOOL", "REPEATED", None, ()),
        SchemaField("timestamp_field", "TIMESTAMP", "REPEATED", None, ()),
        SchemaField("date_field", "DATE", "REPEATED", None, ()),
        SchemaField("time_field", "TIME", "REPEATED", None, ()),
        SchemaField("datetime_field", "DATETIME", "REPEATED", None, ()),
        SchemaField("geography_field", "GEOGRAPHY", "REPEATED", None, ()),
        SchemaField(
            "repeated_nested_field",
            "STRUCT",
            "REPEATED",
            "This field is a STRUCT field.",
            (
                SchemaField(
                    "int_field", "INT64", "REPEATED", "This field is an INT field.", ()
                ),
            ),
        ),
    ]
    expected = (
        f"@dataclass\n{inspect.getsource(RepeatedNestedField)}\n"
        f"@dataclass\n{inspect.getsource(RepeatedSchema)}"
    )
    assert schema_to_dataclass("RepeatedSchema", schema) == expected.strip()


"""Initialize app."""
from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
login_manager = LoginManager()

def create_app():
    """Construct the core app object."""
    # app = Flask(__name__, instance_relative_config=True)
    app = Flask(__name__)
    # app.config.from_pyfile('config.py')
    app.config['SECRET_KEY'] = 'food_for_all_secret_key'

    # Initialize Plugins
    db.init_app(app)
    login_manager.init_app(app)

    with app.app_context():
        from . import auth, routes

        # Register Blueprints
        app.register_blueprint(routes.main_bp)
        app.register_blueprint(auth.auth_bp)

        # Create Database Models
        db.create_all()

        return app


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

import os
import sys

def main():
    """
    main
    :return: 0
    """
    destination = ".\\dl\\"
    f_in = ".\\link.txt"

    if str(os.path.exists(destination)) == "False":
        os.mkdir(destination)

    if len(sys.argv) >= 2:
        os.system(f"cd {destination} && spotdl {sys.argv[-1]}")
    else:
        if os.stat(f_in).st_size > 0:
            with open(f_in, "r", encoding="utf-8") as f_link:
                for i in f_link:
                    os.system(f"cd {destination} && spotdl {i}")
        else:
            link_in = input("\nLink brano/album/playlist:   ")
            os.system(f"cd {destination} && spotdl {link_in}")
    return 0

if __name__ == "__main__":
    main()


import copy
import re
import yaml

#########################################################################
# state

class ParserState :
  def __init__(self) :
    super().__setattr__('state', {})
    super().__setattr__('stack', [])

  def __setattr__(self, name, value) :
    self.state[name] = value

  def __getattr__(self, name) :
    if name in self.state :
      return self.state[name]
    return None

  def stackDepth(self) :
    return len(self.stack)

  def showState(self) :
    print("---------------------------")
    print(yaml.dump(self.state))
    print("---------------------------")
    print(yaml.dump(self.stack))
    print("---------------------------")

  def pushState(self, keepState=True) :
    self.stack.append(self.state)
    if keepState : super().__setattr__('state', copy.deepcopy(self.state))
    else :         super().__setattr__('state', {})

  def popState(self) :
    if 0 < len(self.stack) : super().__setattr__('state', self.stack.pop())
    else                   : super().__setattr__('state', {})

class Parser :

  state = ParserState()

  finalActions = []

  @classmethod
  def registerFinalAction(cls, aFinalAction) :
    cls.finalActions.append(aFinalAction)

  @classmethod
  def runFinalActions(cls, config) :
    for anAction in cls.finalActions :
      anAction(config)

  #########################################################################
  # macros specific class variables and methods

  macros = {}

  @classmethod
  def registerMacro(cls, macroProbe, macroAction) :
    if not macroProbe.startswith('\\') :
      macroProbe = '\\'+macroProbe
    if macroProbe in cls.macros :
      print(f"You can not register an existing macro {macroProbe}")
      return
    cls.macros[macroProbe] = macroAction

  @classmethod
  def showMacros(cls) :
    print(yaml.dump(cls.macros))

  #########################################################################
  # parser specific class variables and methods

  macroRE = re.compile("\\\\\w+")

  #########################################################################
  # parser specific instance variables and methods

  def __init__(self, contextPath) :
    if contextPath.startswith('\\component') :
      # create a fake Parser to hand to
      # lpic.macros.baseContext.dealWithComponent to get everything
      # started
      print(f"New fake parser on [{contextPath}]")
      self.curLine = contextPath
    else :
      if '.' not in contextPath : contextPath = contextPath + '.tex'
      print(f"New parser on [{contextPath}]")
      self.curLine     = None

    self.contextPath = contextPath
    self.contextFile = None
    self.linesIter   = None
    self.probesIter  = None

  def __del__(self) :
    if self.contextFile is not None and not isinstance(self.contextFile, list) :
      self.contextFile.close()

  def removeComment(aLine) :
    aLine = aLine.strip()
    parts = aLine.split('%')
    newLine = []
    while True :
      if len(parts) < 1 : break
      firstPart = parts.pop(0)
      newLine.append(firstPart)
      if not firstPart.endswith('\\') : break
    return "%".join(newLine)

  def __lineIter__(self) :
    if self.contextFile is None :
      try :
        self.contextFile = open(self.contextPath, 'r')
      except FileNotFoundError :
        print(f"Could not open [{self.contextPath}]")
        self.contextFile = []
    for aLine in self.contextFile :
      self.curLine = aLine.rstrip()
      yield self.curLine
    self.curLine = None
    yield self.curLine

  def nextLine(self) :
    if self.linesIter is None :
      self.linesIter = self.__lineIter__()
    return next(self.linesIter, None)

  def __probeIter__(self) :
    if self.curLine is None : self.nextLine()
    while self.curLine  is not None :
      curLine = Parser.removeComment(self.curLine)
      curProbes = type(self).macroRE.findall(curLine)
      for aProbe in curProbes :
        yield aProbe
      self.nextLine()
    yield None

  def nextProbe(self) :
    if self.probesIter is None :
      self.probesIter = self.__probeIter__()
    return next(self.probesIter, None)

  def runMacros(self) :
    aProbe = self.nextProbe()
    while aProbe :
      print(aProbe)
      if aProbe in type(self).macros :
        index = self.curLine.find(aProbe)
        print(f"Found {aProbe} at {index} in [{self.curLine}]")
        type(self).macros[aProbe](self, index)
      aProbe = self.nextProbe()


# File name: pickup.py
# Author: Michael Chunko
# Python Version: 3.7

# This file contains the class representing items that can be picked up

from entities.entity import Entity
import tcod

class Pickup(Entity):
    def __init__(self, tiles, x=1, y=1, char='-', color=tcod.white, name="item", blocks=False, moves=False,
                 deletes=True):
        Entity.__init__(self, tiles, x, y, char, color, name, blocks, moves)
        self.deletes = deletes

    def use(self, entities):
        """ Performs the use action for the item. """
        message = "You used the {0}. It didn't do much of anything".format(self.name)
        return [{"pickup_used": [message, self]}]

    def delete(self, player):
        """ Remove the item from the player inventory. """
        for i in range(0, player.inventory_size):
            if player.inventory[i] == self:
                player.inventory[i] = None
                break

    def take_turn(self, entities, fov_map, game_map):
        """ Checks if the player is on top of it and, if so, performs the code to obtain the item. """
        result = []

        # The player is on the same tile as the item
        if entities[0].x == self.x and entities[0].y == self.y:
            # Find the index of the first open space in the player inventory
            i = 0
            while i < entities[0].inventory_size and entities[0].inventory[i] is not None:
                i += 1

            if i >= entities[0].inventory_size:
                result = [{"pickup_failed": [self.name]}]
            else:
                result = [{"pickup_success": [self.name, self]}]
                entities[0].inventory[i] = self

        return result


import functools

def job_cmp(a, b):
    # Custom comparison function for sorting jobs
    if a[0] * b[1] > b[0] * a[1]:
        return 1
    elif a[0] * b[1] == b[0] * a[1]:
        return 0
    else:
        return -1

num_tests = int(input("Enter the number of tests: "))  # Prompt for the number of tests

for i in range(num_tests):
    input()  # Ignore blank line
    num_jobs = int(input("Enter the number of jobs: "))  # Prompt for the number of jobs

    jobs = []
    for j in range(num_jobs):
        # Prompt for job characteristics
        T, S = [int(x) for x in input().split()]
        jobs.append((T, S, j + 1))

    jobs = sorted(jobs, key=functools.cmp_to_key(job_cmp), reverse=False)
    if i > 0:
        print()

    # Print the sorted job identifiers
    print(" ".join([str(j[2]) for j in jobs]))

Competitive Programming/15. Shoemaker’s Problem.py


import numpy as np
import torch as T
from policy import PolicyNet
from replay_memory import ReplayMemory

class PolicyGradientAgent():
    def __init__(self, lr, gamma, state_dims, num_actions, env_name,
                 checkpoint_dir):

        self.lr = lr
        self.gamma = gamma
        self.state_dims = state_dims
        self.num_actions = num_actions

        self.policy = PolicyNet(lr=lr, num_actions=num_actions,
                                input_dims=state_dims, fc1_dims=256, fc2_dims=256,
                                 name=env_name+'_policy_gradients',
                                 checkpoint_dir=checkpoint_dir)
        # self.action_logprob_history = T.autograd.Variable(T.Tensor()).to(self.policy.device)
        self.action_logprob_history = []
        self.reward_history = []
        self.loss_history = []

    def get_action(self, state):
        action_probs = self.policy(state)
        action_probs = T.distributions.Categorical(action_probs) #define action_probs as a multinoulli distribution

        action = action_probs.sample()

        action_logprob = action_probs.log_prob(action)

        # if self.action_logprob_history.size()[0] == 0:
        #     self.action_logprob_history = action_logprob
        # else:
        #     T.cat((self.action_logprob_history, action_logprob))
        self.action_logprob_history.append(action_logprob)

        return action.cpu().item()

    def learn(self):
        self.policy.optimizer.zero_grad()
        reward_history = T.tensor(self.reward_history, dtype=T.float32).to(self.policy.device)

        #Calculate Return values
        # R_list = T.zeros_like(reward_history)
        R_list = np.zeros_like(self.reward_history)
        for t in range(len(self.reward_history)):
            R_t = 0
            discount = 1
            for k in range(t, len(self.reward_history)):
                R_t += self.reward_history[k] * discount
                discount = self.gamma * discount
            R_list[t] = R_t

        std = R_list.std() if R_list.std() > 0 else 1 #handles exception where std == 0
        R_list = (R_list - R_list.mean()) / std

        #Calculate loss and backprop
        # loss = T.sum(T.mul(R_list, self.action_logprob_history)).to(self.policy.device)
        # loss *= -1.0
        loss = 0
        for R, action_logprob in zip(R_list, self.action_logprob_history):
            loss += -R * action_logprob

        loss.backward()
        self.policy.optimizer.step()

        # self.action_logprob_history = T.autograd.Variable(T.Tensor()).to(self.policy.device)
        self.action_logprob_history = []
        self.reward_history = []

    def save_model(self):
        self.policy.save()

    def load_model(self):
        self.policy.load()


from PyQt5.QtCore import pyqtSignal, QThread
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
from airtest.cli.parser import cli_setup
from airtest.core.api import *
import tools

class init_devices(QThread):
    trigger = pyqtSignal()
    def __init__(self):
        super(init_devices, self).__init__()
        if not cli_setup():
            auto_setup(__file__, logdir=True, devices=[
            "Android://127.0.0.1:5037/FKC4C16629002059?touch_method=ADBTOUCH",
            ])
        self.poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
        #"mCurrentFocus=Window{5842cb5 u0 com.xiangzi.jukandian/com.xiangzi.jukandian.activity.MainActivity}"
        self.jukandian_package = "com.xiangzi.jukandian"
        self.jukandian_activity = "com.xiangzi.jukandian.activity.MainActivity"
        #"mCurrentFocus=Window{9916f10 u0 com.jm.video/com.jm.video.ui.main.MainActivity}"
        self.shuabao_package = "com.jm.video"
        self.shuabao_activity = "com.jm.video.ui.main.MainActivity"
        tools.start_my_app(self.shuabao_package, self.shuabao_activity)


L1=list(range(65,91))
L2=list(range(97,123))
Str = input('')
k = 3
s=[]
LL=s.append
for x in Str:
    a=ord(x)
    if a in L1:
        LL(chr(L1[(a-91+k)%26]))
    elif a in L2:
        LL(chr(L2[(a-123+k)%26]))
    else:
        LL(x)
print(''.join(s))


class Solution:
    def numFactoredBinaryTrees(self, A: List[int]) -> int:
        A = sorted(A)
        dp, answer, modVal = Counter(), 0, 10**9+7
        factors = defaultdict(set)
        for i in range(len(A)):
            for j in range(i):
                if A[i]%A[j] == 0:
                    factors[A[i]].add(A[j])
        for i in range(len(A)):
            dp[A[i]] = 1
            for factor in factors[A[i]]:
                dp[A[i]] += (dp[factor]*dp[A[i]//factor])
            answer = (answer + dp[A[i]]) %modVal
        return answer%modVal


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Jun 20 16:33:39 2018

@author: z5044541
"""

def longestPalindrome(s):
    lenS = len(s)
    if lenS <= 1: return s
    minStart, maxLen, i = 0, 1, 0
    while i < lenS:
        if lenS - i <= maxLen / 2: break
        j, k = i, i
        print("first_line", j,k,i)
        while k < lenS - 1 and s[k] == s[k + 1]: k += 1
        i = k + 1
        print("second_line", j,k,i)
        while k < lenS - 1 and j and s[k + 1] == s[j - 1]:  k, j = k + 1, j - 1
        if k - j + 1 > maxLen: minStart, maxLen = j, k - j + 1
    return s[minStart: minStart + maxLen]

s = "abcba"
b = longestPalindrome(s)
print(b)


#!/usr/bin/env python
import time
import sys
from requests import get
import dns.resolver
from boto.route53.connection import Route53Connection
from boto.route53.exception import DNSServerError
from boto.route53.record import ResourceRecordSets
import logging
import click

logger = logging.getLogger(__name__)
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

get_change_id = lambda response: response['ChangeInfo']['Id'].split('/')[-1]
get_change_status = lambda response: response['ChangeInfo']['Status']

def resolve_name_ip(name):
    resolver = dns.resolver.Resolver()
    resolver.nameservers = [
        '208.67.222.222',
        '8.8.4.4'
    ]
    answer = resolver.query(name)
    return answer.response.answer[0].items[0].address

@click.command()
@click.option('--hosted-zone', '-z', 'HOSTED_ZONE', type=str, required=True, help='Select AWS hosted zone id')
@click.option('--domain-name', '-n', 'DOMAIN_NAME', type=str, required=True, help='Select the domain to be updated')
def main(HOSTED_ZONE, DOMAIN_NAME):
    # Get your ip using a public service
    try:
        current_ip = get('https://ident.me').text
        # current_ip = get('https://checkip.amazonaws.com').text Another option
    except:
        logger.error('Internet is down')
        sys.exit(1)

    # Avoid to hit the Route53 API if is not necessary.
    # so compare first to a DNS server if the IP changed
    resolved_ip = resolve_name_ip(DOMAIN_NAME)
    if resolved_ip == current_ip:
        logger.debug('DNS response (%s) and public IP (%s) are the same, nothing to do' % (resolved_ip, current_ip))
        return

    conn = Route53Connection()

    try:
        zone = conn.get_hosted_zone(HOSTED_ZONE)
    except DNSServerError:
        logger.error('%s Zone Not Found' % HOSTED_ZONE)
        sys.exit(1)

    response = conn.get_all_rrsets(HOSTED_ZONE, 'A', DOMAIN_NAME, maxitems=1)[0]

    if current_ip not in response.resource_records:
        logger.info('Found new IP: %s' % current_ip)

        # Delete the old record, and create a new one.
        # This code is from route53.py script, the change record command
        changes = ResourceRecordSets(conn, HOSTED_ZONE, '')
        change1 = changes.add_change("DELETE", DOMAIN_NAME, 'A', response.ttl)
        for old_value in response.resource_records:
            change1.add_value(old_value)
        change2 = changes.add_change("CREATE", DOMAIN_NAME, 'A', response.ttl)
        change2.add_value(current_ip)

        try:
            commit = changes.commit()
            logger.debug('%s' % commit)
        except:
            logger.error("Changes can't be made: %s" % commit)
            sys.exit(1)
        else:

            change = conn.get_change(get_change_id(commit['ChangeResourceRecordSetsResponse']))
            logger.debug('%s' % change)

            while get_change_status(change['GetChangeResponse']) == 'PENDING':
                time.sleep(2)
                change = conn.get_change(get_change_id(change['GetChangeResponse']))
                logger.debug('%s' % change)
            if get_change_status(change['GetChangeResponse']) == 'INSYNC':
                logger.info('Change %s A de %s -> %s' % (DOMAIN_NAME, response.resource_records[0], current_ip))
            else:
                logger.warning('Unknow status for the change: %s' % change)
                logger.debug('%s' % change)

if __name__ == '__main__':
    main()


from torchvision.datasets import VOCDetection
import torchvision.transforms as T

from torch.utils.data import DataLoader

from utils.drawer import Drawer

from tqdm import tqdm

from voc_od.nets import BaseNet, DetectionNet, ClassificationNet
import voc_od.config as config

from voc_od.voc_label import VocLabel

import matplotlib.pyplot as plt

import os
from dotenv import load_dotenv

def from_dataset():
	dataset = VOCDetection(
		root=os.getenv('VOC_ROOT'),
		download=os.getenv('VOC_DOWNLOAD') == 'True',
		image_set='trainval',
		transform=T.Compose([
			T.ToTensor(),
			T.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
		]),
	)

	for img, label in dataset:
		drawer = Drawer.from_array_chw(img.numpy())
		for obj in label['annotation']['object']:
			box = obj['bndbox']
			xmin, xmax, ymin, ymax = box['xmin'], box['xmax'], box['ymin'], box['ymax']
			drawer.bounding_box_from_corners(
				int(xmin),
				int(ymin),
				int(xmax),
				int(ymax),
				[1, 1, 1]
			)

		path = os.path.join(os.getenv('OUT_DIR'), 'voc_od_data_sample.png')
		drawer.save(path)
		break

def from_loader():
	# data and loader
	def target_transform(label):
		return (VocLabel
			.from_label(label)
			.to_tensor(config.NUM_CELLS, config.CLASS_TO_INDEX)
		)

	dataset = VOCDetection(
		root=os.getenv('VOC_ROOT'),
		download=os.getenv('VOC_DOWNLOAD') == 'True',
		image_set='trainval',
		transform=T.Compose([
			T.ToTensor(),
			T.Resize((config.INPUT_SIZE, config.INPUT_SIZE)),
			T.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
		]),
		target_transform=target_transform,
	)

	loader = DataLoader(
		dataset,
		1,
		True,
	)

	for img, label in loader:
		img = img[0].numpy()
		label = label[0].numpy()

		drawer = Drawer.from_array_chw(img)

		cell_size = config.INPUT_SIZE / config.NUM_CELLS

		for i in range(label.shape[0]):
			for j in range(label.shape[1]):
				box = label[i, j, config.NUM_CLASSES:]

				if box[0] < 0.5:
					continue

				center_x, center_y, width, height = box[1:]

				center_x = j * cell_size + center_x * cell_size
				center_y = i * cell_size + center_y * cell_size

				width *= cell_size
				height *= cell_size

				print(center_x, center_y, width, height)
				drawer.bounding_box_from_corners(
					int(center_x - width / 2),
					int(center_y - height / 2),
					int(center_x + width / 2),
					int(center_y + height / 2),
					[1, 1, 1]
				)

		path = os.path.join(os.getenv('OUT_DIR'), 'voc_od_data_sample.png')
		drawer.save(path)
		break

if __name__ == '__main__':
	load_dotenv()
	# from_dataset()
	from_loader()


import os
from datetime import date
import pickle
import glob
import logging

from prisma.constants import CACHE_DIR

class Cache:
    def get_short_name(self, query, data_type):
        symbol = query["symbol"]
        region = query["region"]
        return f"{region}-{symbol}-{data_type}"

    def get_full_name(self, query, data_type, date):
        name = self.get_short_name(query, data_type)
        return f"{name}-{date}.pkl"

    def get_filename(self, query, data_type):
        today = date.today()
        full_name = self.get_full_name(query, data_type, today)
        filename = os.path.join(CACHE_DIR, full_name)
        return filename

    def get_older_filename(self, query, data_type):
        full_name = self.get_full_name(query, data_type, "*")
        filename = os.path.join(CACHE_DIR, full_name)
        files = glob.glob(filename)
        if files:
            return sorted(files)[-1]  # take the latest
        return None

    def cache_response(self, data, filename):
        with open(filename, "wb") as file:
            pickle.dump(data, file)

    def load_cahced_response(self, filename):
        with open(filename, "rb") as file:
            return pickle.load(file)

    def clean(self):
        files = glob.glob(os.path.join(CACHE_DIR, "*.pkl"))
        today = date.today()
        for filename in files:
            if not str(today) in filename:
                logging.debug("Removing file %s", filename)
                os.remove(filename)


import pytesseract
import cv2
import pyttsx3

#-- Set up untuk library pytessseract dan pyttsx3
#-- Start
pytesseract.pytesseract.tesseract_cmd = "C:\\Program Files\\Tesseract-OCR\\tesseract"
img = cv2.imread('000.jpg')
engine = pyttsx3.init()
engine.setProperty("rate", 130)  # kecepatan
engine.setProperty("volume", 1.0)  # Volume level (0.0 to 1.0)
voices = engine.getProperty('voices') #change
engine.setProperty('voice', voices[1].id)
url = ""
#-- End

imgH, imgW, _ = img.shape

boxes = pytesseract.image_to_boxes(img)
# print(boxes)

#-- Mengambil satu per satu huruf yang nantinya akan dimasukan ke sebuah variabel
a= ""
for box in boxes.splitlines():
    box = box.split(' ')
    # print(box)
    # print(box)
    x, y, w, h = int(box[1]), int(box[2]), int(box[3]), int(box[4])
    name = box[0]
    cv2.rectangle(img, (x, imgH-y), (w, imgH-h), (100,100,255), 1)
    cv2.putText(img, name, (x, imgH-y+25), cv2.FONT_HERSHEY_PLAIN, 1, (100,100,255), 2)
    a += box[0]

#-- Menampilkan Visual dan Audio teks yang sudah di deteksi
def running():
    cv2.imshow('Netra Assist', img)
    engine.say("expired on" + a)
    engine.runAndWait()
    key = cv2.waitKey(0)


from flask import Flask, render_template, flash, redirect, url_for, send_from_directory
from flask import Markup
from flask_ckeditor import random_filename

from form import LoginForm,UploadForm
import os
app = Flask(__name__)
app.secret_key = 'secret string'
#要在项目根目录下手动创建uploads文件夹，用于保存上传后的文件
app.config['UPLOAD_PATH'] = os.path.join(app.root_path,'uploads')
user = {
	'username': 'Grey Li',
	'bio': 'A boy who loves movies and music.',
}
movies = [
	{'name': 'My Neighbor Totoro', 'year': '1988'},
	{'name': 'Three Colours trilogy', 'year': '1993'},
	{'name': 'Forrest Gump', 'year': '1994'},
	{'name': 'Perfect Blue', 'year': '1997'},
	{'name': 'The Matrix', 'year': '1999'},
	{'name': 'Memento', 'year': '2000'},
	{'name': 'The Bucket list', 'year': '2007'},
	{'name': 'Black Swan', 'year': '2010'},
	{'name': 'Gone Girl', 'year': '2014'},
	{'name': 'CoCo', 'year': '2017'},
]

def baz(n):
    if n == 'baz':
        return True
    return False
app.jinja_env.tests['baz'] = baz

def bar():
	return 'I am bar.'
foo = 'I am foo.'
app.jinja_env.globals['bar'] = bar
app.jinja_env.globals['foo'] = foo

@app.template_filter()
def musical(s):
    return s+Markup(' ♫ ')

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/watchlist')
def watchlist():
    return render_template('watchlist.html',user=user,movies=movies)

@app.route('/flash')
def just_flash():
	flash('I am flash,who is looking for me')
	return 'aaaa'

@app.route('/html')
def pure():
	return render_template('pure.html')

@app.route('/basic',methods=['GET','POST'])
def basic():
	form = LoginForm()
	if form.validate_on_submit():
		username = form.username.data
		flash('Welcome %s' %username)
		return redirect(url_for('index'))
	return render_template('basic.html',form=form)

@app.route('/bootstrap')
def bootstrapForm():
	form = LoginForm()
	return render_template('bootstrap.html',form=form)

@app.route('/upload', methods=['GET','POST'])
def upload():
	form = UploadForm()
	if form.validate_on_submit():
		f = form.photo.data
		#生成随机文件名 我们调用这个函数来获取随机文件名，传入原文 件名作为参数
		filename = random_filename(f.filename)
		#保存文件
		f.save(os.path.join(app.config['UPLOAD_PATH'],filename))
		flash('Upload success')
		#session['filenames'] = [filename]
		#return redirect(url_for('show_images'))
		return redirect(url_for('watchlist'))
	return  render_template('upload.html',form=form)
@app.route('/uploads/<path:filename>')
#传入参数filename
def showfile(filename):
	return send_from_directory(app.config['UPLOAD_PATH'], filename)
@app.errorhandler(404)
def page_not_found(e):
	return render_template('errors/404.html'),404

if __name__ == '__main__':
    app.run()


# 17404. RGB거리 2  2023-01-12

N = int(input())
lights = [tuple(map(int, input().split())) for _ in range(N)]
dp = [[0] * 3 for _ in range(N)]

ans = 1000001
for color in range(3):

    for j in range(3):
        if j == color:
            dp[0][j] = lights[0][j]
        else:
            dp[0][j] = 1000001

    for i in range(1, N):
        dp[i][0] = min(dp[i - 1][1], dp[i - 1][2]) + lights[i][0]
        dp[i][1] = min(dp[i - 1][0], dp[i - 1][2]) + lights[i][1]
        dp[i][2] = min(dp[i - 1][0], dp[i - 1][1]) + lights[i][2]

    for j in range(3):
        if j == color: continue

        ans = min(ans, dp[N - 1][j])

print(ans)


"""
1722. 执行交换操作后的最小汉明距离
给你两个整数数组 source 和 target ，长度都是 n 。还有一个数组 allowedSwaps ，其中每个 allowedSwaps[i] = [ai, bi] 表示你可以交换数组 source 中下标为 ai 和 bi（下标从 0 开始）的两个元素。注意，你可以按 任意 顺序 多次 交换一对特定下标指向的元素。

相同长度的两个数组 source 和 target 间的 汉明距离 是元素不同的下标数量。形式上，其值等于满足 source[i] != target[i] （下标从 0 开始）的下标 i（0 <= i <= n-1）的数量。

在对数组 source 执行 任意 数量的交换操作后，返回 source 和 target 间的 最小汉明距离 。

示例 1：

输入：source = [1,2,3,4], target = [2,1,4,5], allowedSwaps = [[0,1],[2,3]]
输出：1
解释：source 可以按下述方式转换：
- 交换下标 0 和 1 指向的元素：source = [2,1,3,4]
- 交换下标 2 和 3 指向的元素：source = [2,1,4,3]
source 和 target 间的汉明距离是 1 ，二者有 1 处元素不同，在下标 3 。
示例 2：

输入：source = [1,2,3,4], target = [1,3,2,4], allowedSwaps = []
输出：2
解释：不能对 source 执行交换操作。
source 和 target 间的汉明距离是 2 ，二者有 2 处元素不同，在下标 1 和下标 2 。
示例 3：

输入：source = [5,1,2,4,3], target = [1,5,4,2,3], allowedSwaps = [[0,4],[4,2],[1,3],[1,4]]
输出：0

提示：

n == source.length == target.length
1 <= n <= 105
1 <= source[i], target[i] <= 105
0 <= allowedSwaps.length <= 105
allowedSwaps[i].length == 2
0 <= ai, bi <= n - 1
ai != bi

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/minimize-hamming-distance-after-swap-operations
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""
from collections import defaultdict, Counter
from typing import List

class DSU:
    def __init__(self, n):
        self.uf = {i: i for i in range(n)}
        self.rank = {i: 1 for i in range(n)}

    def find(self, x):
        if self.uf[x] != x:
            self.uf[x] = self.find(self.uf[x])
        return self.uf[x]

    def union(self, x, y):
        px, py = self.find(x), self.find(y)
        ans = False
        if px != py:
            if self.rank[px] > self.rank[py]:
                px, py = py, px
            self.rank[py] += self.rank[px]
            self.uf[px] = py
            ans = True
        return ans

class Solution:
    def minimumHammingDistance(self, source: List[int], target: List[int], allowedSwaps: List[List[int]]) -> int:
        n = len(source)
        dsu = DSU(n)
        for a, b in allowedSwaps:
            dsu.union(a, b)
        dic = defaultdict(list)
        for i in range(n):
            dic[dsu.find(i)].append(i)
        ans = 0
        for v in dic.values():
            cnt1, cnt2 = Counter(), Counter()
            for i in v:
                cnt1[source[i]] += 1
                cnt2[target[i]] += 1
            cur = list((cnt1 & cnt2).elements())
            ans += len(cur)
        return n - ans

if __name__ == '__main__':
    source = [1, 2, 3, 4]
    target = [2, 1, 4, 5]
    allowedSwaps = [[0, 1], [2, 3]]
    print(Solution().minimumHammingDistance(source, target, allowedSwaps))

1722. 执行交换操作后的最小汉明距离.py


import sys
import json

def gettime(timeanddate):
  return timeanddate[11:16]

def samelocation(previous, current):
  plat = previous['latitude']
  plng = previous['longitude']
  clat = current['latitude']
  clng = current['longitude']
  if(plat == clat and plng == clng):
    return True
  return False

def mapfunction(data):
  response = []
  data = data['data']
  previousRow = ''
  curpath = []
  curtype = ''
  starttime = ''
  endtime = ''
  startvol = 0
  endvolume = 0
  volumeadded = 0
  volumeused = 0
  if len(data) > 0:
    for row in data:
      if previousRow != '':
        if (samelocation(previousRow, row) and (curtype == 'stop' or curtype == '')):
          curtype = 'stop'
        elif (samelocation(previousRow, row) and curtype == 'moving'):
          curpath.append({'lat': float(row['latitude']), 'lng': float(row['longitude'])})
          response.append({'type': curtype, 'path': curpath, 'starttime': starttime, 'endtime': endtime, 'voa': startvol, 'vol': endvolume, 'va': volumeadded, 'vu': volumeused})
          startvol = float(previousRow['volume_left'])
          volumeadded = 0
          volumeused = 0
          curpath = [{'lat': float(row['latitude']), 'lng': float(row['longitude'])}]
          starttime = gettime(row['created_at'])
          curtype = 'stop'
        elif ((not(samelocation(previousRow, row))) and (curtype == 'moving' or curtype == '')):
          curtype = 'moving'
          curpath.append({'lat': float(row['latitude']), 'lng': float(row['longitude'])})
        elif ((not(samelocation(previousRow, row))) and curtype == 'stop'):
          curpath.append({'lat': float(row['latitude']), 'lng': float(row['longitude'])})
          response.append({'type': curtype, 'path': curpath, 'starttime': starttime, 'endtime': endtime, 'voa': startvol, 'vol': endvolume, 'va': volumeadded, 'vu': volumeused})
          startvol = float(row['volume_left'])
          volumeadded = 0
          volumeused = 0
          curpath = [{'lat': float(row['latitude']), 'lng': float(row['longitude'])}]
          starttime = gettime(row['created_at'])
          curtype = 'moving'
      else:
        starttime = gettime(row['created_at'])
        startvol = float(row['volume_left'])
        curpath.append({'lat': float(row['latitude']), 'lng': float(row['longitude'])})
      volumeadded += float(row['volume_added'])
      volumeused += float(row['volume_used'])
      endvolume = float(row['volume_left'])
      endtime = gettime(row['created_at'])
      previousRow = row
    curpath.append({'lat': float(row['latitude']), 'lng': float(row['longitude'])})
    response.append({'type': curtype, 'path': curpath, 'starttime': starttime, 'endtime': endtime, 'voa': startvol, 'vol': endvolume, 'va': volumeadded, 'vu': volumeused})
    return response
  return []

dataFromNode = sys.argv[1]

dataFromNode = json.loads(dataFromNode)

formattedMapData = mapfunction(dataFromNode)
formattedMapData = json.dumps(formattedMapData)
print(formattedMapData)


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

# Akvo RSR is covered by the GNU Affero General Public License.
# See more details in the license.txt file located at the root folder of the Akvo RSR module.
# For additional details on the GNU license please see < http://www.gnu.org/licenses/agpl.html >.

from decimal import Decimal

from django.contrib.auth import get_permission_codename, get_user_model
from django.core.exceptions import ObjectDoesNotExist
from django.forms.models import ModelForm

from tastypie import fields

from tastypie.authorization import Authorization
from tastypie.constants import ALL, ALL_WITH_RELATIONS
from tastypie.exceptions import NotFound
from tastypie.http import HttpUnauthorized
from tastypie.resources import ModelResource

from akvo import settings

from akvo.api.authentication import ConditionalApiKeyAuthentication
from akvo.api.fields import ConditionalFullToManyField
from akvo.api.serializers import IATISerializer
from akvo.rsr.models import (
    Project, Benchmarkname, Category, Goal, Partnership, BudgetItem, ProjectLocation, Benchmark, Organisation
)
from akvo.utils import RSR_LIMITED_CHANGE

from .resources import ConditionalFullResource, get_extra_thumbnails
from .partnership import FIELD_NAME, FIELD_LONG_NAME

class IATIProjectModelForm(ModelForm):
    class Meta:
        model = Project
        fields = "__all__"

class IATIProjectResource(ModelResource):

    benchmarks =  fields.ToManyField(
        'akvo.api.resources.IATIBenchmarkResource',
        'benchmarks', full=True, related_name='project'
    )
    budget_items = fields.ToManyField(
        'akvo.api.resources.IATIBudgetItemResource',
        'budget_items', full=True, related_name='project'
    )
    categories =  fields.ToManyField(
        'akvo.api.resources.IATICategoryResource',
        'categories', full=True, null=True, related_name='project'
    )
    goals = fields.ToManyField(
        'akvo.api.resources.IATIGoalResource',
        'goals', full=True, related_name='project'
    )
    locations = fields.ToManyField(
        'akvo.api.resources.IATIProjectLocationResource',
        'locations', full=True, related_name='location_target'
    )
    partnerships = fields.ToManyField(
        'akvo.api.resources.IATIPartnershipResource',
        'partnerships', full=True, related_name='project'
    )

    # This field makes the Cordaid import dismally slow, and isn't used for anything else,
    # so rather than trying to fix it by re-writing the OrganisationResource, we set the sync_owner
    # to Cordaid in the post_import.py script
    # This commented code remains as a reminder NOT to add the field as currently defined ;-)
    # sync_owner = fields.ToOneField(
    #     'akvo.api.resources.OrganisationResource',
    #     'sync_owner', full=True, related_name='project'
    # )

    class Meta:
        allowed_methods = ['post', 'put']
        resource_name   = 'iati_activity'
        authorization   = Authorization()
        authentication  = ConditionalApiKeyAuthentication(methods_requiring_key=['POST', 'PUT'])
        serializer      = IATISerializer()
        # validation      = ModelFormValidation(form_class=IATIProjectModelForm)
        queryset        = Project.objects.all()

    def obj_update(self, bundle, skip_errors=False, **kwargs):
        """
        override obj_update to delete related objects
        """
        method = kwargs.pop('method')
        if not bundle.obj or not self.get_bundle_detail_data(bundle):
            try:
                lookup_kwargs = self.lookup_kwargs_with_identifiers(bundle, kwargs)
            except:
                # if there is trouble hydrating the data, fall back to just
                # using kwargs by itself (usually it only contains a "pk" key
                # and this will work fine.
                lookup_kwargs = kwargs

            try:
                bundle.obj = self.obj_get(bundle=bundle, **lookup_kwargs)
            except ObjectDoesNotExist:
                raise NotFound(
                    "A model instance matching the provided arguments could not be found."
                )

        # If the method is PUT, delete all related objects
        # so they can be re-created with potentially new data
        if method == 'PUT':
            Goal.objects.filter(project=bundle.obj).delete()
            BudgetItem.objects.filter(project=bundle.obj).delete()
            ProjectLocation.objects.filter(location_target=bundle.obj).delete()
            # Since all locations for the project are deleted we need to make sure Project.primary_location is set to None
            bundle.obj.primary_location = None
            bundle.obj.save()
            Partnership.objects.filter(project=bundle.obj).delete()
            Benchmark.objects.filter(project=bundle.obj).delete()
            bundle.obj.categories.clear()

        self.authorized_update_detail(self.get_object_list(bundle.request), bundle)
        bundle = self.full_hydrate(bundle)
        return self.save(bundle, skip_errors=skip_errors)

    def put_detail(self, request, **kwargs):
        # inject request method to be used in obj_update()
        kwargs['method'] = request.META['REQUEST_METHOD']
        super(IATIProjectResource, self).put_detail(request, **kwargs)

    def alter_deserialized_detail_data(self, request, data):
        reporting_iati_org_id = data['partnerships'][0]['reporting_org']
        # Cordaid custom code
        if reporting_iati_org_id == getattr(settings, 'CORDAID_IATI_ID', 'NL-KVK-41160054'):
            # Figure out the category for the project from the business unit
            business_unit_categories = {
                "K6020": dict(cat_name="Children & Education", fa="Education"),
                "K6090": dict(cat_name="Domestic", fa="Economic development"),
                "K6030": dict(cat_name="Disaster Recovery", fa="Economic development"),
                "K6070": dict(cat_name="Entrepreneurship", fa="Economic development"),
                "K6110": dict(cat_name="Food Security", fa="Healthcare"),
                "K6100": dict(cat_name="Investments", fa="Economic development"),
                "K6010": dict(cat_name="Healthcare", fa="Healthcare"),
                "K6060": dict(cat_name="Security & Justice", fa="Economic development"),
                "K6080": dict(cat_name="Urban Matters", fa="Economic development"),
                "K6040": dict(cat_name="Women's leadership", fa="Economic development"),
                "K6050": dict(cat_name="Extractives", fa="Economic development"),
            }
            business_unit = business_unit_categories.get(data['partnerships'][0]['business_unit'], None)
            project_category = Category.objects.get(name=business_unit['cat_name'], focus_area__name=business_unit['fa'])
            data['categories'] = ['/api/v1/iati_category/{pk}/'.format(pk=project_category.pk),]

            # prepare the benchmarks, looking up the Benchmarkname and set the Category to project_category
            benchmarks = []
            for benchmark in data['benchmarks']:
                # if we don't find a value drop that benchmark
                if benchmark.get('value'):
                    new_benchmark = dict(value=benchmark['value'])
                    benchmarkname = Benchmarkname.objects.get(name=benchmark['name'])
                    new_benchmark['name'] = benchmarkname.pk
                    new_benchmark['category'] = project_category.pk
                    benchmarks.append(new_benchmark)
            data['benchmarks'] = benchmarks
        if reporting_iati_org_id == getattr(settings, 'RAIN_IATI_ID', 'NL-KVK-34200988'):
            # remove benchmarks, as they currently have no category
            data['benchmarks'] = []

        # hack to set the first location as primary
        if data.get('locations'):
            data['locations'][0]['primary'] = True
            for location in data['locations'][1:]:
                location['primary'] = False

        # remove budget items with value 0
        if data.get('budget_items'):
            data['budget_items'] = [item for item in data['budget_items'] if Decimal(item['amount']) > 0]

        # hack to truncate org names.
        # Tried to do this in the XSLT but substring(text, 1, 25) sometimes returns more than 25 characters :-p
        # TODO: write a general truncator function for all char and text field of a model's deserialized data
        if data.get('partnerships'):
            temp_org = data['partnerships'][0]
            # are the requirements met for creating a business unit partnership?
            if temp_org['business_unit'] and temp_org['reporting_org']:
                data['partnerships'] += [dict(
                    internal_org_id=temp_org['business_unit'],
                    reporting_org=temp_org['reporting_org'],
                    name='Incorrect business unit', #this should never be used, if it is the lookup of existing BUs is borked
                    long_name='Incorrect business unit',
                    partner_type='sponsor',
                    new_organisation_type='21',
                    organisation=None,
                )]
            for partnership in data['partnerships']:
                partnership[FIELD_NAME] = partnership[FIELD_NAME][:25]
                partnership[FIELD_LONG_NAME] = partnership[FIELD_LONG_NAME][:75]
        return data

    def hydrate_date_end_actual(self, bundle):
        date_end_actual = bundle.data.get('date_end_actual')
        if date_end_actual and date_end_actual[-1] == 'Z':
            bundle.data['date_end_actual'] = date_end_actual[:-1]
        return bundle

    def hydrate_date_start_actual(self, bundle):
        date_start_actual = bundle.data.get('date_start_actual')
        if date_start_actual and date_start_actual[-1] == 'Z':
            bundle.data['date_start_actual'] = date_start_actual[:-1]
        return bundle

    def hydrate_date_end_planned(self, bundle):
        date_end_planned = bundle.data.get('date_end_planned')
        if date_end_planned and date_end_planned[-1] == 'Z':
            bundle.data['date_end_planned'] = date_end_planned[:-1]
        if date_end_planned:
            bundle.data['date_complete'] = bundle.data.pop('date_end_planned')
        return bundle

    def hydrate_date_start_planned(self, bundle):
        date_start_planned = bundle.data.get('date_start_planned')
        if date_start_planned and date_start_planned[-1] == 'Z':
            bundle.data['date_start_planned'] = date_start_planned[:-1]
        if date_start_planned:
            bundle.data['date_request_posted'] = bundle.data.pop('date_start_planned')
        return bundle

    # def hydrate_categories(self, bundle):
    #     if bundle.data['categories']:
    #         bundle.data['categories'] = [
    #             reverse('api_dispatch_detail', kwargs={
    #                 'resource_name': 'category',
    #                 'api_name': 'v1',
    #                 'pk': bundle.data['categories'][0]
    #             })
    #         ]
    #     return bundle

    # def hydrate_partnerships(self, bundle):
    #     import pdb
    #     pdb.set_trace()
    #     return bundle

    # def hydrate_current_image(self, bundle):
    #     import requests
    #
    #     from django.core.files import File
    #     from django.core.files.temp import NamedTemporaryFile
    #     return bundle
    #
    #     def save_image_from_url(model, url):
    #         r = requests.get(url)
    #
    #         img_temp = NamedTemporaryFile(delete=True)
    #         img_temp.write(r.content)
    #         img_temp.flush()
    #
    #         img_name = "%s_%s_%s_%s%s" % (
    #             bundle.obj._meta.object_name,
    #             bundle.obj.pk or '',
    #             'current_image',
    #             datetime.now().strftime("%Y-%m-%d_%H.%M.%S"),
    #             os.path.splitext(img_temp.name)[1],
    #         )
    #         Project.current_image.save("image.jpg", File(img_temp), save=True)

class ProjectResource(ConditionalFullResource):
    benchmarks = ConditionalFullToManyField('akvo.api.resources.BenchmarkResource', 'benchmarks',)
    budget_items = ConditionalFullToManyField('akvo.api.resources.BudgetItemResource', 'budget_items')
    categories = ConditionalFullToManyField('akvo.api.resources.CategoryResource', 'categories')
    goals = ConditionalFullToManyField('akvo.api.resources.GoalResource', 'goals')
    keywords = ConditionalFullToManyField('akvo.api.resources.KeywordResource', 'keywords')
    invoices = ConditionalFullToManyField('akvo.api.resources.InvoiceResource', 'invoices')
    links = ConditionalFullToManyField('akvo.api.resources.LinkResource', 'links')
    locations = ConditionalFullToManyField('akvo.api.resources.ProjectLocationResource', 'locations')
    partnerships = ConditionalFullToManyField('akvo.api.resources.PartnershipResource', 'partnerships',)
    primary_location = fields.ToOneField('akvo.api.resources.ProjectLocationResource', 'primary_location', full=True, null=True)
    project_comments = ConditionalFullToManyField('akvo.api.resources.ProjectCommentResource', 'comments')
    project_updates = ConditionalFullToManyField('akvo.api.resources.ProjectUpdateResource', 'project_updates')

    class Meta:
        allowed_methods         = ['get']
        authentication          = ConditionalApiKeyAuthentication(methods_requiring_key=['POST', 'PUT'])
        queryset                = Project.objects.all() #Note: this is modified in get_object_list()
        resource_name           = 'project'
        include_absolute_url    = True

        filtering               = dict(
            # other fields
            id                  = ALL,
            status              = ALL,
            title               = ALL,
            budget              = ALL,
            funds               = ALL,
            funds_needed        = ALL,
            current_image       = ALL,
            # foreign keys
            benchmarks          = ALL_WITH_RELATIONS,
            budget_items        = ALL_WITH_RELATIONS,
            categories          = ALL_WITH_RELATIONS,
            goals               = ALL_WITH_RELATIONS,
            invoices            = ALL_WITH_RELATIONS,
            links               = ALL_WITH_RELATIONS,
            locations           = ALL_WITH_RELATIONS,
            keywords            = ALL_WITH_RELATIONS,
            partnerships        = ALL_WITH_RELATIONS,
            project_comments    = ALL_WITH_RELATIONS,
            project_updates     = ALL_WITH_RELATIONS,
        )

    def get_object_list(self, request):
        """ The Project queryset is filtered depending on the user accessing the API
            All users get Project.objects.published()
            If the user is authenticated via an API key additional projects are added similarly to the access in the
            admin:
                Superusers get access to ALL projects
                Users with "change_project" perm (currently Akvo staff users) also get access to ALL projects
                Users with "rsr_limited_change_project" perm get access to all projects linked to their organisation
                regardless of publishing status
        """
        object_list = super(ProjectResource, self).get_object_list(request)
        # The whole point of ConditionalApiKeyAuthentication is to allow some access even for unauthorised requests,
        # but here we need to figure out if the request contains a name/key pair and if so allow access to unpublished
        # projects. So we call ApiKeyAuthentication.is_authenticated() (using super() which returns True if there is an
        # identified user holding an api key, AND is_authenticated() also sets request.user to the User object which we
        # need to be able to call request.user.has_perm() correctly.
        if super(ConditionalApiKeyAuthentication, self.Meta.authentication).is_authenticated(request) is True:
            opts = Project._meta
            if request.user.has_perm(opts.app_label + '.' + get_permission_codename('change', opts)):
                return object_list
            elif request.user.has_perm(opts.app_label + '.' + get_permission_codename(RSR_LIMITED_CHANGE, opts)):
                object_list = object_list.published() | object_list.of_partners(request.user.organisations.all())
                return object_list.distinct()
        return object_list.published()

    def dehydrate(self, bundle):
        """ add thumbnails inline info for Project.current_image
        """
        bundle = super(ProjectResource, self).dehydrate(bundle)
        if isinstance(bundle.data['created_at'], bool):
            bundle.data['created_at'] = None
        if isinstance(bundle.data['last_modified_at'], bool):
            bundle.data['last_modified_at'] = None
        bundle.data['current_image'] = {
            'original': bundle.data['current_image'],
            'thumbnails': get_extra_thumbnails(bundle.obj.current_image),
        }
        bundle.data['date_request_posted'] = bundle.data.pop('date_start_planned')
        bundle.data['date_complete'] = bundle.data.pop('date_end_planned')
        return bundle


import numpy as np
import glob
import re
import csv

from ssd_data import BaseGTUtility

from thirdparty.get_image_size import get_image_size

class GTUtility(BaseGTUtility):
    """Utility for RoboTT-Net dataset.

    # Arguments
        data_path: Path to ground truth and image data.
    """

    def __init__(self, data_path):
        self.data_path = data_path
        self.image_path = data_path
        self.gt_path = data_path
        self.classes = ['Background', 'Lot 0', 'Lot 90', 'Lot 180', 'Lot -90']
        self.classes_lower = [s.lower() for s in self.classes]
        self.num_classes = len(self.classes)

        self.image_names = []
        self.data = []
        for filename in sorted(glob.glob(data_path+'**/*_location.csv', recursive=True)):
            image_path = re.sub(r'_location.csv$', '.jpg', filename)
            image_name = image_path[len(data_path):]
            boxes = []
            with open(filename, newline='') as f:
                reader = csv.reader(f, delimiter=';')
                header = next(reader)
                box = next(reader, None)
                if box:
                    class_idx = ['0', '90', '180', '-90'].index(box[0]) + 1

                    image_size = get_image_size(image_path)
                    img_width, img_height = image_size

                    xmin = float(box[2]) / img_width
                    ymin = float(box[1]) / img_height
                    xmax = float(box[4]) / img_width
                    ymax = float(box[3]) / img_height

                    box = [xmin, ymin, xmax, ymax, class_idx]
                    boxes.append(box)

            # only images with boxes
            if len(boxes) == 0:
                continue
                boxes = np.empty((0,4+self.num_classes))
            else:
                boxes = np.asarray(boxes)

            self.image_names.append(image_name)
            self.data.append(boxes)


import boto3
import json
import re
import os
import io
from io import BytesIO
from datetime import datetime
import tempfile

# Packages from layers
import cchardet
import pandas as pd

from aux_data_integration import *

REGION = os.getenv("REGION")
INPUT_RAW_BUCKET = os.getenv("INPUT_RAW_BUCKET")
RAW_ZONE_BUCKET = os.getenv("RAW_ZONE_BUCKET")
LANDING_ZONE_BUCKET = os.getenv("LANDING_ZONE_BUCKET")
STAGING_ZONE_BUCKET = os.getenv("STAGING_ZONE_BUCKET")
ERROR_ZONE_BUCKET = os.getenv("ERROR_ZONE_BUCKET")
s3_client = boto3.client("s3")
sns = boto3.client("sns")
dynamodb = boto3.resource("dynamodb", region_name=REGION)
table = dynamodb.Table("inventory_per_district")

def get_topic_arn(topic_name):
    """
    This function retrieves the ARN of a topic with the specified name.
    It retrieves all the topics available in the SNS service and looks
    for the topic with the specified name.
    """
    response = sns.list_topics()
    topics = response["Topics"]
    next_token = response.get("NextToken", None)
    while next_token:
        response = sns.list_topics(NextToken=next_token)
        topics += response["Topics"]
        next_token = response.get("NextToken", None)
    for topic in topics:
        if topic["TopicArn"].split(":")[-1] == topic_name:
            return topic["TopicArn"]
    return None

def write_df_to_s3_parquet(df, output_bucket_name, output_prefix):
    """
    This function writes a dataframe to S3 in parquet format.
    The dataframe is written to a temporary file in the local filesystem,
    and then uploaded to S3.

    Parameters:
        df (pandas.DataFrame): The dataframe to be written to S3.
        output_bucket_name (str): The name of the S3 bucket to which the dataframe will be written.
        output_prefix (str): The name of the output file in S3.

    Returns:
        None
    """

    # Create a temporary file
    with tempfile.NamedTemporaryFile() as temp:

        # Write the dataframe to the temporary file in parquet format
        df.to_parquet(temp.name, index=False, compression='snappy')

        # Move the file pointer to the beginning of the file
        temp.seek(0)

        # Upload the file to S3
        output_prefix = output_prefix + ".parquet"
        s3_client.upload_file(temp.name, output_bucket_name, output_prefix)

def get_validation_rules(prefix):

    document_key = "/".join(re.split("/", prefix)[:-1])
    file_name = prefix.rsplit("/", 1)[-1]

    response = table.get_item(Key={"document_key": document_key})
    district_documents = response.get("Item")

    valid_file = False
    for _, district_data in district_documents["files"].items():
        if re.match(district_data["file_name_regex"], file_name):
            district_key = district_data["district_key"]
            output_base_file_name = district_data["output_base_file_name"]
            valid_file = True
    if valid_file:
        response = table.get_item(Key={"document_key": district_key})
        district_rules = response.get("Item")
        return True, district_rules, output_base_file_name, file_name, document_key
    return False, _, _, _, _

def get_file_extract(input_bucket_name, prefix, file_name, district_rules):
    extension_status = False
    encoding_status = False
    file_extension = district_rules["validation_rules"].get(
        "file_extension")
    if "file_extension" in district_rules["validation_rules"]:
        extension_status = validate_file_extension(
            file_name, file_extension
        )

    if extension_status:
        bytes_min_range = 0
        bytes_delta = 2500
        bytes_max_range = bytes_delta

        # Create a bytes buffer to hold the first two lines of the file
        buffer = io.BytesIO()

        # Download the first two lines of the file into the buffer
        s3_client.download_fileobj(
            Bucket=input_bucket_name, Key=prefix, Fileobj=buffer, Config={"Range": f"bytes={bytes_min_range}-{bytes_max_range}"})
        file_bytes = buffer.getvalue()
        if "encoding" in district_rules["validation_rules"] and extension_status:
            encoding = district_rules["validation_rules"].get("encoding")
            encoding_status = validate_file_encoding(
                file_bytes, encoding)

    if encoding_status:
        record_delimiter = get_record_delimiter(file_extension, encoding)
        max_iterations = 10
        i = 0
        while i < max_iterations:
            buffer.seek(0)
            file_content = buffer.read().decode(encoding)
            if len(file_content.split(record_delimiter)) < 3:
                i += 1
                # Append the next bytes
                bytes_min_range += bytes_delta
                bytes_max_range += bytes_delta
                buffer.seek(0, 2)  # set the pointer to the end of the buffer
                s3_client.download_fileobj(
                    Bucket=input_bucket_name, Key=prefix, Fileobj=buffer, Config={"Range": f"bytes={bytes_min_range}-{bytes_max_range}"})
            else:
                break
        if not file_content:
            raise Exception("The file is empty")
        if buffer.tell() >= 1000000:
            raise Exception("The buffer has reached the maximum size")

        file_extract = file_content.split(record_delimiter)[:2]
        return file_extract
    else:
        return None

def create_dataframe(input_bucket_name, prefix, district_rules):
    columns_details = district_rules["validation_rules"].get("columns_details")
    encoding = district_rules["validation_rules"].get("encoding")
    delimiter = district_rules["validation_rules"].get("delimiter")

    dtypes = {}
    for col in columns_details:
        column_name = col["header"]
        column_type = col["data_type"]
        if column_type == "date":
            dtypes[column_name] = "string"
        else:
            dtypes[column_name] = column_type

    obj = s3_client.get_object(Bucket=input_bucket_name, Key=prefix)
    file_content = obj["Body"].read().decode(encoding)

    df = pd.read_csv(io.BytesIO(bytes(file_content, encoding)),
                     dtype=dtypes, delimiter=delimiter)

    for col in columns_details:
        if col["data_type"] == "date" and "date_format" in col:
            df[col["header"]] = pd.to_datetime(
                df[col["header"]], format=col["date_format"])

    return df

def lambda_handler(event, context):

    input_bucket_name = event["Records"][0]["s3"]["bucket"]["name"]
    prefix = event["Records"][0]["s3"]["object"]["key"]
    if INPUT_RAW_BUCKET == input_bucket_name:
        file_exist = False
        file_extract = None
        file_properties = False

        file_exist, district_rules, output_base_file_name, file_name, document_key = get_validation_rules(
            prefix)

        if file_exist:
            file_extract = get_file_extract(
                input_bucket_name, prefix, file_name, district_rules)

        if file_extract != None:
            print(file_extract)
            if "delimiter" in district_rules["validation_rules"]:
                delimiter = district_rules["validation_rules"].get("delimiter")
                file_extract = normalize_headers(
                    file_extract, delimiter)
                if "columns_count" in district_rules["validation_rules"]:
                    number_of_columns_status = validate_file_number_of_columns(
                        file_extract,
                        district_rules["validation_rules"].get(
                            "columns_count"),
                        delimiter,
                    )
                if "columns_details" in district_rules["validation_rules"]:
                    columns_names_status = validate_file_columns_names(
                        file_extract,
                        district_rules["validation_rules"].get(
                            "columns_details"),
                        delimiter,
                    )
                if number_of_columns_status and columns_names_status:
                    file_properties = True

        if file_properties:
            df = create_dataframe(input_bucket_name, prefix, district_rules)

            if "date_details" in district_rules["validation_rules"]:
                date_details = district_rules["validation_rules"].get(
                    "date_details")

                df, output_file_name = add_date_columns(
                    df, date_details, file_name, output_base_file_name)
            else:
                output_file_name = output_base_file_name

            output_bucket_name = re.sub(
                INPUT_RAW_BUCKET, STAGING_ZONE_BUCKET, input_bucket_name)
            output_prefix = prefix.rsplit(
                "/", 1)[0] + "/" + output_file_name

            print(output_file_name)

            write_df_to_s3_parquet(
                df, output_bucket_name, output_prefix)


n=int(input())
length=len(str(n))
tem=n
sum=0
rem=0
while tem>0:
    rem=tem%10
    sum=sum+int(rem**length)
    tem=tem//10
    length=length-1
if sum==n:
    print("True")
else:
    print("False")