import os
import glob
import numpy as np

#2020/07/25
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt

import sys
import traceback

from collections import defaultdict
from io import StringIO
from PIL import Image

# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
from object_detection.utils import ops as utils_ops

#<modified date="2020/07/27">
# To avoid the following error:
# AttributeError: module 'tensorflow' has no attribute 'get_default_graph'
# We have changed the following line.
#import tensorflow as tf
import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
#</modified>

from utils import label_map_util
from utils import visualization_utils as vis_util
from vis_utils2 import *

from FiltersParser       import FiltersParser

from CocoModelDownloader import CocoModelDownloader

class TensorflowObjectDetector2:
  #Constructor
  def __init__(self, frozen_graph, labels):
    self.frozen_graph = frozen_graph
    self.labels = labels

    #Load a frozen Tensorflow model into memory.
    self.detection_graph = tf.Graph()
    with self.detection_graph.as_default():
      od_graph_def = tf.compat.v1.GraphDef()
      with tf.compat.v2.io.gfile.GFile(self.frozen_graph, 'rb') as fid:
        serialized_graph = fid.read()
        od_graph_def.ParseFromString(serialized_graph)
        tf.import_graph_def(od_graph_def, name='')

    #Loading label map
    self.category_index = label_map_util.create_category_index_from_labelmap(
              self.labels, use_display_name=True)

    self.NUM_DETECTIONS    = 'num_detections'
    self.DETECTION_CLASSES = 'detection_classes'
    self.DETECTION_BOXES   = 'detection_boxes'
    self.DETECTION_MASKS   = 'detection_masks'
    self.DETECTION_SCORES  = 'detection_scores'

  def load_image_into_numpy_array(self, image):
    (im_width, im_height) = image.size
    return np.array(image.getdata()).reshape(
        (im_height, im_width, 3)).astype(np.uint8)

  #2020/06/20
  # Detect objects in each image in input_image_dir, and save the detected image
  # to output_image_dir.

  def detect_all(self, input_image_dir, output_image_dir, filters=None):

      image_list = []

      if os.path.isdir(input_image_dir):
        image_list.extend(glob.glob(os.path.join(input_image_dir, "*.png")) )
        image_list.extend(glob.glob(os.path.join(input_image_dir, "*.jpg")) )

      print("image_list {}".format(image_list) )

      for image_filename in image_list:
          #image_filename will take images/foo.png
          image_file_path = os.path.abspath(image_filename)

          print("filename {}".format(image_file_path))

          self.detect(image_file_path, output_image_dir, filters)

  ## Object detection for a single image to image_path
  def detect(self, image_path, image_output_dir, filters=None):
    image = Image.open(image_path)

    # the array based representation of the image will be used later in order to prepare the
    # result image with boxes and labels on it.

    image_np = self.load_image_into_numpy_array(image)

    # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
    image_np_expanded = np.expand_dims(image_np, axis=0)

    # Actual detection.
    #output_dict = run_inference_for_single_image(image_np, detection_graph)

    with self.detection_graph.as_default():
      with tf.compat.v1.Session() as sess:

        # Get handles to input and output tensors
        ops = tf.get_default_graph().get_operations()
        all_tensor_names = {output.name for op in ops for output in op.outputs}
        tensor_dict = {}
        for key in [
            self.NUM_DETECTIONS,
            self.DETECTION_CLASSES,
            self.DETECTION_BOXES,
            self.DETECTION_MASKS,
            self.DETECTION_SCORES,
        ]:
          tensor_name = key + ':0'

          if tensor_name in all_tensor_names:
            tensor_dict[key] = tf.get_default_graph().get_tensor_by_name(
                tensor_name)

        if self.DETECTION_MASKS in tensor_dict:
          # The following processing is only for single image
          detection_boxes = tf.squeeze(tensor_dict[self.DETECTION_BOXES], [0])
          detection_masks = tf.squeeze(tensor_dict[self.DETECTION_MASKS], [0])

          # Reframe is required to translate mask from box coordinates to image coordinates and fit the image size.
          real_num_detection = tf.cast(tensor_dict[self.NUM_DETECTIONS][0], tf.int32)

          detection_boxes = tf.slice(detection_boxes, [0, 0], [real_num_detection, -1])

          detection_masks = tf.slice(detection_masks, [0, 0, 0], [real_num_detection, -1, -1])

          detection_masks_reframed = utils_ops.reframe_box_masks_to_image_masks(
              detection_masks, detection_boxes, image_np.shape[0], image_np.shape[1])

          detection_masks_reframed = tf.cast(
              tf.greater(detection_masks_reframed, 0.5), tf.uint8)

          # Follow the convention by adding back the batch dimension
          tensor_dict[self.DETECTION_MASKS] = tf.expand_dims(
              detection_masks_reframed, 0)

        image_tensor = tf.get_default_graph().get_tensor_by_name('image_tensor:0')

        # Run inference
        output_dict = sess.run(tensor_dict,
                               feed_dict={image_tensor: np.expand_dims(image_np, 0)})

        # all outputs are float32 numpy arrays, so convert types as appropriate
        output_dict[self.NUM_DETECTIONS] = int(output_dict[self.NUM_DETECTIONS][0])

        output_dict[self.DETECTION_CLASSES] = output_dict[self.DETECTION_CLASSES][0].astype(np.uint8)

        output_dict[self.DETECTION_BOXES]   = output_dict[self.DETECTION_BOXES][0]

        output_dict[self.DETECTION_SCORES]  = output_dict[self.DETECTION_SCORES][0]

        if self.DETECTION_MASKS in output_dict:
          output_dict[self.DETECTION_MASKS] = output_dict[self.DETECTION_MASKS][0]

    filename_only = self.get_filename_only(image_path)
    output_image_filepath = os.path.join(image_output_dir, filename_only)

    print("filters {}".format(filters))

    if filters is not None:
      parser = FiltersParser(str(filters))
      output_image_filepath = parser.get_ouput_filename(image_path, image_output_dir)
    print(output_image_filepath)

    # Draw detected boxes, classes, scores onto image_np,
    # and save it to the output_image_filepath
    self.visualize(filters, image_np, output_dict, output_image_filepath)

  def visualize(self, filters, image_np, output_dict, output_image_filepath):
    # Visualization of the results of a detection.
    # vis_utils2.py
    (image, detected_objects) = visualize_boxes_and_labels_on_image_array_with_filters(
        filters,
        image_np,
        output_dict[self.DETECTION_BOXES],
        output_dict[self.DETECTION_CLASSES],
        output_dict[self.DETECTION_SCORES],
        self.category_index,
        instance_masks=output_dict.get(self.DETECTION_MASKS),
        use_normalized_coordinates=True,
        line_thickness=4)
    pil_img = Image.fromarray(image_np)

    pil_img.save(output_image_filepath)

    # Save detected_objects data to a detected_objects_path file.
    # [(1, 'car', '90%'), (2, 'person', '8%'),... ]
    detected_objects_path = output_image_filepath + '.txt'

    with open(detected_objects_path, mode='w') as f:
      for item in detected_objects:
         (id, label, score) = item
         line = str(id) + " " + str(label) + ": " + str(score) + "\n"
         f.write(line)

  def get_filename_only(self, input_image_filename):

     rpos  = input_image_filename.rfind("/")
     fname = input_image_filename

     if rpos >0:
         fname = input_image_filename[rpos+1:]
     else:
         rpos = input_image_filename.rfind("\\")
         if rpos >0:
            fname = input_image_filename[rpos+1:]
     return fname

def parse_args(argv):
  input_image_path  = None #"images/img.png"
  output_image_dir  = None
  filters           = None
  frozen_graph_path = None
  label_path        = None
  if len(argv) >= 2:
    input_image_path = argv[1]

  if len(argv) >= 3:
    output_image_dir = argv[2]

  if len(argv) >= 4:
    str_filters = argv[3]
    filtersParser = FiltersParser(str_filters)
    filters = filtersParser.get_filters()

  if len(argv) >= 5:
    frozen_graph_path = argv[4]

  if len(argv) == 6:
    label_path = argv[5]

  if not os.path.exists(input_image_path):
    raise Exception("Not found input_image_path {}".format(input_image_path))

  output_image_dir = os.path.join(os.getcwd(), output_image_dir)
  if not os.path.exists(output_image_dir):
    os.makedirs(output_image_dir)

  return (input_image_path, output_image_dir, filters, frozen_graph_path, label_path)

#
#
#
if __name__ == "__main__":
  use_coco_model = False
  """
  python TensorflowObjectDetector.py input_image_dir output_image_dir filters frozen_graph.pb  label_map.pbtxt
  """
  try:
     input_image_path, output_image_dir, filters, frozen_graph_path, label_path = parse_args(sys.argv)

     if len(sys.argv) == 3 or len(sys.argv) == 4:
       use_coco_model = True

     if use_coco_model==True:
       print("Using CocoModel-----------")
       downloader = CocoModelDownloader()
       downloader.download()
       frozen_graph_path = downloader.get_frozen_graph_path()
       label_path        = downloader.get_label_path()
       print("frozen_graph_path {}".format(frozen_graph_path))
       print("label_path        {}".format(label_path))

     detector = TensorflowObjectDetector2(frozen_graph_path, label_path)

     if os.path.isfile(input_image_path):
       # If input_image_path is a file
       detector.detect(input_image_path, output_image_dir, filters)

     elif os.path.isdir(input_image_path):
       detector.detect_all(input_image_path, output_image_dir, filters)

     else:
        print("Inavlid input_file type {}".format(input_image_path))

  except Exception as ex:
    traceback.print_exc()


# list = [1, 2, 3, 4, 5]

# total = sum(list)

# print("Sum of numbers in list: ", total)

numbers = [1, 2, 3, 4, 5]

total = sum(numbers)

print("Sum of numbers: ", total)


# 단어수를 체크 -> ABCDE .... -> 홀수개인 것이 딱 1개or 0개만 존재해야함.
# 홀수개인것을 제외. 나머지 ABCD .. 순으로 출력 (사전순으로 앞서는 것을 출력하기위해)

alp_dict = {chr(ord('A') + i) : 0 for i in range(26)} # A~ Z까지를 key로 가지는 딕셔너리 생성

chars = input()
middle = ''
res_str = ''

for char in chars:
    alp_dict[char] += 1

for alp in alp_dict:
    middle += alp * (alp_dict[alp] % 2)
    res_str += alp * (alp_dict[alp] // 2)

if len(middle) > 1:
    print("I'm Sorry Hansoo")
else :
    print(res_str+middle+res_str[::-1])

백준/Silver/1213. 팰린드롬 만들기/팰린드롬 만들기.py


""" /*
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
*/
"""
import math

number =600851475143
sqrt = math.ceil(math.sqrt(number))#I have to use ceil because I want to have a number without decimals
print("Square root from long number is:",sqrt)
prime_factor = 0
divisor = 2
while(divisor <= sqrt):
    if (number % divisor == 0):#If this condition is true, it is deployed all statements then out directly to the while
        prime_factor = divisor
        number = number // divisor #two of // in order to discard decimals numbers
        print("Multiple of long number: ",number)
    elif (number == 1):
        print("The largest prime_factor is: ", prime_factor)
        break
    else:
        divisor += 1


__author__ = 'Daoyuan'
from BaseSolution import *
class BestTimeToBuyAndSellStock(BaseSolution):
    def __init__(self):
        BaseSolution.__init__(self)
        self.push_test(
            params = ([1,6,3,2,5,6,7,8,9,9,4,3,1,4,5,7,8,5,4,3,5,4,3,2,4],),
            expects = 8
        )

    def solution(self, prices):
        if not prices or prices == [] : return 0
        n = len(prices)
        low = high = prices[0]
        lowp = highp = 0
        ret = 0
        for i in range(1, n):
            if prices[i] > high:
                high = prices[i]
                highp = i
            elif prices[i] < low:
                low = prices[i]
                lowp = i
            if lowp < highp:
                ret = max(ret, high - low)
            else:
                highp = lowp
                high = low
        return ret

    #DP way
    # s[i] denotes the maximum profit at i-th day.
    # then for s[i+1], s[i+1] = max(s[i], price[i+1] - min_so_far)

    def solution(self, prices):
        if not prices or prices == []: return 0
        n = len(prices)
        s = [0] * n
        min_so_far = prices[0]
        ret = 0
        for i in range(1, n):
            s[i] = max(s[i-1], prices[i] - min_so_far)
            min_so_far = min(min_so_far, prices[i])
        return s[n-1]


__author__ = 'Daoyuan'
from BaseSolution import *
import math
class MaximumProductSubarray(BaseSolution):
    def __init__(self):
        BaseSolution.__init__(self)
        self.fuckinglevel = 9
        self.push_test(
            params =([2,3,-2,4],),
            expects = 6
        )
        self.push_test(
            params = ([-2,1,2,3,0,-1,-2,3,4,3,-1,2,3,0,-3],),
            expects = 432
        )
        self.push_test(
            params = ([-2,1,2,3,0,-2,-2,3,4,3,-4,2,3,0,-3],),
            expects = 1728
        )
        self.push_test(
            params = ([-2,1,2,3,0,-2,2,3,4,3,-4,2,3,0,-3],),
            expects = 3456
        )

    # beautiful DP algorithm

    def solution(self, nums):
        big = small = nums[0]
        maxv = minv = nums[0]
        for i in nums[1:]:
            big,small  = max(big * i, small*i, i),min(big * i, small * i ,i)
            maxv, minv = max(big, maxv), min(small, minv)
        return maxv

    def solution(self, nums):
        n = len(nums)
        high = [0] * n
        low = [0] * n
        high[0] = low[0] = nums[0]
        for i in range(1, n):
            if nums[i-1] == 0:
                high[i] = nums[i]
                low[i] = nums[i]
            else:
                high[i] = max( high[i-1]*nums[i], nums[i], low[i-1]*nums[i])
                low[i] = min(high[i-1]*nums[i], nums[i], low[i-1]*nums[i])
        return max(high)


#모델을 저장하고 불러와서 모델의 상태 유지(persist), 모델의 예측 실행

import torch
import torchvision.models as models

model = models.vgg16(pretrained=True)
#state_dict(내부 상태 사전)에 저장 및 save로 저장
torch.save(model.state_dict(), 'model_weight.pth')

#모델 가중치를 불러오기 이해 instance를 생성한 후 load_State_dict사용하여 매개변수 불라옴
model = models.vgg16()
model.load_state_dict(torch.load('model_weight.pth'))
model.eval()
#dropout과 배치 정규화(batch normalization)를 평가모드(evaluation mode)로 설정해야 일관성 있는 결고 ㅏ생성

#모델의 형태 포함하여 저장 및 불러오기
torch.save(model, 'model.pth')

model = torch.load('model.pth')
#pickle 모듈을 사용하여 모델을 직렬화(serialize)하므로
#모델을 불러올 때 실제 클래스 정의(definition)를 적용(rely on)


# From shivam shiaro's repo, with modification to work with stable-dreamfusion
import argparse
import gc
import hashlib
import itertools
import logging
import math
import os
import random
import traceback
import numpy as np

from contextlib import nullcontext
from pathlib import Path
from typing import Optional

import torch
import torch.nn.functional as F
import torch.utils.checkpoint
from PIL import Image
from accelerate import Accelerator
from accelerate.utils import set_seed
from diffusers import AutoencoderKL, DDIMScheduler, DDPMScheduler, EulerAncestralDiscreteScheduler, \
    StableDiffusionPipeline, UNet2DConditionModel
from diffusers.optimization import get_scheduler
from diffusers.utils import logging as dl
from huggingface_hub import HfFolder, whoami
from torch.utils.data import Dataset
from torchvision import transforms
from tqdm.auto import tqdm
from transformers import CLIPTextModel, CLIPTokenizer

from extensions.stable_dreamfusion_extension.dreamfusion import xattention
from extensions.stable_dreamfusion_extension.dreamfusion.dreamfusion import printm #, dumb_safety, save_checkpoint, list_features, is_image

from modules import shared
from stable_dreamfusion.nerf.provider import NeRFDataset
from stable_dreamfusion.nerf.utils import *
from stable_dreamfusion.optimizer import Shampoo

# Custom stuff
try:
    cmd_dreamfusion_models_path = shared.cmd_opts.dreamfusion_models_path
except:
    cmd_dreamfusion_models_path = None

mem_record = {}
torch.backends.cudnn.benchmark = True

logger = logging.getLogger(__name__)
# define a Handler which writes DEBUG messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
logger.addHandler(console)
logger.setLevel(logging.DEBUG)
dl.set_verbosity_error()

def cleanup():
    try:
        if torch.cuda.is_available():
            torch.cuda.empty_cache()
            torch.cuda.ipc_collect()
        gc.collect()
    except:
        pass
    printm("Cleanup completed.")

def parse_args(input_args=None):
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--pretrained_model_name_or_path",
        type=str,
        default=None,
        required=True,
        help="Path to pretrained model or model identifier from huggingface.co/models.",
    )
    parser.add_argument('--text', default=None, help="text prompt")
    parser.add_argument('--negative', default='', type=str, help="negative text prompt")
    parser.add_argument('-O', action='store_true', help="equals --fp16 --cuda_ray --dir_text")
    parser.add_argument('-O2', action='store_true', help="equals --backbone vanilla --dir_text")
    parser.add_argument('--test', action='store_true', help="test mode")
    parser.add_argument('--save_mesh', action='store_true', help="export an obj mesh with texture")
    parser.add_argument('--eval_interval', type=int, default=10, help="evaluate on the valid set every interval epochs")
    parser.add_argument('--workspace', type=str, default='workspace')
    parser.add_argument('--guidance', type=str, default='stable-diffusion', help='choose from [stable-diffusion, clip]')
    parser.add_argument('--seed', type=int, default=0)

    ### training options
    parser.add_argument('--iters', type=int, default=10000, help="training iters")
    parser.add_argument('--lr', type=float, default=1e-3, help="initial learning rate")
    parser.add_argument('--ckpt', type=str, default='latest')
    parser.add_argument('--cuda_ray', action='store_true', help="use CUDA raymarching instead of pytorch")
    parser.add_argument('--max_steps', type=int, default=512, help="max num steps sampled per ray (only valid when using --cuda_ray)")
    parser.add_argument('--num_steps', type=int, default=64, help="num steps sampled per ray (only valid when not using --cuda_ray)")
    parser.add_argument('--upsample_steps', type=int, default=32, help="num steps up-sampled per ray (only valid when not using --cuda_ray)")
    parser.add_argument('--update_extra_interval', type=int, default=16, help="iter interval to update extra status (only valid when using --cuda_ray)")
    parser.add_argument('--max_ray_batch', type=int, default=4096, help="batch size of rays at inference to avoid OOM (only valid when not using --cuda_ray)")
    parser.add_argument('--albedo', action='store_true', help="only use albedo shading to train, overrides --albedo_iters")
    parser.add_argument('--albedo_iters', type=int, default=1000, help="training iters that only use albedo shading")
    parser.add_argument('--uniform_sphere_rate', type=float, default=0.5, help="likelihood of sampling camera location uniformly on the sphere surface area")
    # model options
    parser.add_argument('--bg_radius', type=float, default=1.4, help="if positive, use a background model at sphere(bg_radius)")
    parser.add_argument('--density_thresh', type=float, default=10, help="threshold for density grid to be occupied")
    # network backbone
    parser.add_argument('--fp16', action='store_true', help="use amp mixed precision training")
    parser.add_argument('--backbone', type=str, default='grid', choices=['grid', 'vanilla'], help="nerf backbone")
    parser.add_argument('--sd_version', type=str, default='2.0', choices=['1.5', '2.0'], help="stable diffusion version")
    # rendering resolution in training, decrease this if CUDA OOM.
    parser.add_argument('--w', type=int, default=64, help="render width for NeRF in training")
    parser.add_argument('--h', type=int, default=64, help="render height for NeRF in training")
    parser.add_argument('--jitter_pose', action='store_true', help="add jitters to the randomly sampled camera poses")

    ### dataset options
    parser.add_argument('--bound', type=float, default=1, help="assume the scene is bounded in box(-bound, bound)")
    parser.add_argument('--dt_gamma', type=float, default=0, help="dt_gamma (>=0) for adaptive ray marching. set to 0 to disable, >0 to accelerate rendering (but usually with worse quality)")
    parser.add_argument('--min_near', type=float, default=0.1, help="minimum near distance for camera")
    parser.add_argument('--radius_range', type=float, nargs='*', default=[1.0, 1.5], help="training camera radius range")
    parser.add_argument('--fovy_range', type=float, nargs='*', default=[40, 70], help="training camera fovy range")
    parser.add_argument('--dir_text', action='store_true', help="direction-encode the text prompt, by appending front/side/back/overhead view")
    parser.add_argument('--suppress_face', action='store_true', help="also use negative dir text prompt.")
    parser.add_argument('--angle_overhead', type=float, default=30, help="[0, angle_overhead] is the overhead region")
    parser.add_argument('--angle_front', type=float, default=60, help="[0, angle_front] is the front region, [180, 180+angle_front] the back region, otherwise the side region.")

    parser.add_argument('--lambda_entropy', type=float, default=1e-4, help="loss scale for alpha entropy")
    parser.add_argument('--lambda_opacity', type=float, default=0, help="loss scale for alpha value")
    parser.add_argument('--lambda_orient', type=float, default=1e-2, help="loss scale for orientation")
    parser.add_argument('--lambda_smooth', type=float, default=0, help="loss scale for surface smoothness")

    ### GUI options
    parser.add_argument('--gui', action='store_true', help="start a GUI")
    parser.add_argument('--W', type=int, default=800, help="GUI width")
    parser.add_argument('--H', type=int, default=800, help="GUI height")
    parser.add_argument('--radius', type=float, default=3, help="default GUI camera radius from center")
    parser.add_argument('--fovy', type=float, default=60, help="default GUI camera fovy")
    parser.add_argument('--light_theta', type=float, default=60, help="default GUI light direction in [0, 180], corresponding to elevation [90, -90]")
    parser.add_argument('--light_phi', type=float, default=0, help="default GUI light direction in [0, 360), azimuth")
    parser.add_argument('--max_spp', type=int, default=1, help="GUI rendering max sample per pixel")

    if input_args is not None:
        args = parser.parse_args(input_args)
    else:
        args = parser.parse_args()

    # TODO: distributed training
    # env_local_rank = int(os.environ.get("LOCAL_RANK", -1))
    # if env_local_rank != -1 and env_local_rank != args.local_rank:
    #     args.local_rank = env_local_rank
    return args

def main(args, memory_record):
    if args.o:
        args.fp16 = True
        args.dir_text = True
        args.cuda_ray = True
    elif args.o2:
        if args.albedo:
            args.fp16 = True
        args.dir_text = True
        args.backbone = 'vanilla'

    if args.albedo:
        args.albedo_iters = args.iters

    if args.backbone == 'vanilla':
        from stable_dreamfusion.nerf.network import NeRFNetwork
    elif args.backbone == 'grid':
        from stable_dreamfusion.nerf.network_grid import NeRFNetwork
    else:
        raise NotImplementedError(f'--backbone {args.backbone} is not implemented')
    seed_everything(args.seed)
    model = NeRFNetwork(args)
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    if args.test:
        guidance = None # no need to load guidance model at test

        trainer = Trainer('df', args, model, guidance, device=device, workspace=args.workspace, fp16=args.fp16, use_checkpoint=args.ckpt)

        test_loader = NeRFDataset(args, device=device, type='test', H=args.gui_h, W=args.gui_w, size=100).dataloader()
        trainer.test(test_loader)

        if args.save_mesh:
            trainer.save_mesh(resolution=256)
    else:
        train_loader = NeRFDataset(args, device=device, type='train', H=args.h, W=args.w, size=100).dataloader()

        optimizer = lambda model: torch.optim.Adam(model.get_params(args.lr), betas=(0.9, 0.99), eps=1e-15)
        # optimizer = lambda model: Shampoo(model.get_params(opt.lr))

        scheduler = lambda optimizer: optim.lr_scheduler.LambdaLR(optimizer, lambda iter: 0.1 ** min(iter / args.iters, 1))
        # scheduler = lambda optimizer: optim.lr_scheduler.OneCycleLR(optimizer, max_lr=opt.lr, total_steps=opt.iters, pct_start=0.1)

        if args.guidance == 'stable-diffusion':
            from stable_dreamfusion.nerf.sd import StableDiffusion
            guidance = StableDiffusion(device, args.sd_version, args.pretrained_model_name_or_path)
        elif args.guidance == 'clip':
            from stable_dreamfusion.nerf.clip import CLIP
            guidance = CLIP(device)
        else:
            raise NotImplementedError(f'--guidance {args.guidance} is not implemented.')

        trainer = Trainer('df', args, model, guidance, device=device,
                        workspace=args.workspace, optimizer=optimizer,
                        ema_decay=None, fp16=args.fp16, lr_scheduler=scheduler,
                        use_checkpoint=args.ckpt, eval_interval=args.eval_interval,
                        scheduler_update_every_step=True)
        valid_loader = NeRFDataset(args, device=device, type='val', H=args.gui_h, W=args.gui_h, size=5).dataloader()

        max_epoch = np.ceil(args.iters / len(train_loader)).astype(np.int32)
        trainer.train(train_loader, valid_loader, max_epoch)

    return args, mem_record

    # args.tokenizer_name = None
    # global mem_record
    # mem_record = memory_record
    # logging_dir = Path(args.output_dir, "logging")
    # args.max_token_length = int(args.max_token_length)
    # if not args.pad_tokens and args.max_token_length > 75:
    #     logger.debug("Cannot raise token length limit above 75 when pad_tokens=False")

    # # if args.attention == "xformers":
    # #     xattention.replace_unet_cross_attn_to_xformers()
    # # elif args.attention == "flash_attention":
    # #     xattention.replace_unet_cross_attn_to_flash_attention()
    # # else:
    # #     xattention.replace_unet_cross_attn_to_default()

    # # weight_dtype = torch.float32
    # # if args.mixed_precision == "fp16":
    # #     weight_dtype = torch.float16
    # # elif args.mixed_precision == "bf16":
    # #     weight_dtype = torch.bfloat16

    # model = NERFNetwork(args)
    # device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    # if args.test:
    #     guidance = None # no need to load guidance model at test

    #     trainer = Trainer('df', args, model, guidance, device=device, workspace=args.workspace, fp16=args.fp16, use_checkpoint=args.ckpt)

    #     test_loader = NeRFDataset(args, device=device, type='test', H=args.H, W=args.W, size=100).dataloader()
    #     trainer.test(test_loader)

    #     if args.save_mesh:
    #         trainer.save_mesh(resolution=256)

    # else:
    #     print(args)
    #     train_loader = NeRFDataset(args, device=device, type='train', H=args.h, W=args.w, size=100).dataloader()

    #     optimizer = lambda model: torch.optim.Adam(model.get_params(args.lr), betas=(0.9, 0.99), eps=1e-15)
    #     # optimizer = lambda model: Shampoo(model.get_params(opt.lr))

    #     scheduler = lambda optimizer: optim.lr_scheduler.LambdaLR(optimizer, lambda iter: 0.1 ** min(iter / args.iters, 1))
    #     # scheduler = lambda optimizer: optim.lr_scheduler.OneCycleLR(optimizer, max_lr=opt.lr, total_steps=opt.iters, pct_start=0.1)

    #     if args.guidance == 'stable-diffusion':
    #         from stable_dreamfusion.nerf.sd import StableDiffusion
    #         if args.pretrained_model_name_or_path:
    #             guidance = StableDiffusion(device, args.pretrained_model_name_or_path)
    #     elif args.guidance == 'clip':
    #         from stable_dreamfusion.nerf.clip import CLIP
    #         guidance = CLIP(device)
    #     else:
    #         raise NotImplementedError(f'--guidance {args.guidance} is not implemented.')

    #     trainer = Trainer('df', args, model, guidance,
    #                       device=device, workspace=args.workspace,
    #                       optimizer=optimizer, ema_decay=None,
    #                       fp16=args.fp16, lr_scheduler=scheduler,
    #                       use_checkpoint=args.ckpt, eval_interval=args.eval_interval,
    #                       scheduler_update_every_step=True)

    #     valid_loader = NeRFDataset(args, device=device, type='val', H=args.H, W=args.W, size=5).dataloader()

    #     max_epoch = np.ceil(args.iters / len(train_loader)).astype(np.int32)
    #     trainer.train(train_loader, valid_loader, max_epoch)


# -*- coding: utf-8 -*-
"""
Created on Wed Jul 21 2021

@author: Markus Borg
"""

import xml.sax
import pandas as pd
from collections import Counter
from .publication import SSSPublication
from .scholar import SSSScholar

class ScholarMiner(xml.sax.ContentHandler):

    def __init__(self, filename_prefix, input_sss_scholars, input_sss_affiliations):
        self.filename_prefix = filename_prefix
        self.input_sss_scholars = input_sss_scholars
        self.input_sss_affiliations = input_sss_affiliations

        # data structures containing the results
        self.sss_scholars = []

        # keep track of all coauthors as they might suggest missing SSS scholars
        self.global_SSS_coauthors = Counter()

        # some information to keep track of while parsing scholars
        self.current_scholar = None
        self.current_scholar_name = ""
        self.current_scholar_running_nbr = -1
        self.current_scholar_affiliation = ""
        self.current_scholar_url = ""

        # some information to keep track of while parsing publications
        self.parsing_publication = False
        self.tmp_author_pid = ""
        self.current_pub_title = -1
        self.current_pub_journal = -1
        self.current_pub_booktitle = -1
        self.current_pub_year = -1
        self.current_pub_authors = []
        self.current_pub_informal = False

        # to tackle escaped characters
        self.current_string_done = False
        self.current_string = ""

    def parse_scholars(self):
        nbr_scholars = len(self.input_sss_scholars)
        if nbr_scholars > 0:
            i = 0 # for the progress bar
            print(str(nbr_scholars) + " scholars to parse from DBLP...")
            self.print_progress_bar(i, nbr_scholars)
            parser = xml.sax.make_parser()
            parser.setContentHandler(self)
            for scholar in self.input_sss_scholars:
                i += 1
                self.current_scholar_name = scholar.name
                self.current_scholar_running_nbr = scholar.running_number
                self.current_scholar_affiliation = scholar.affiliation
                self.current_scholar_url = scholar.url
                # SAX parse the URL
                parser.parse(scholar.url)
                self.print_progress_bar(i, nbr_scholars)

            # Calculating statistics and removing scholars with no first-authored SCI publications
            print("Calculating statistics...")
            tmp_scholars = []
            counter = 0
            for scholar in self.sss_scholars:
                scholar.calc_stats()
                if scholar.nbr_first_sci > 0:
                    tmp_scholars.append(scholar)
                else:
                    curr = next((x for x in self.input_sss_affiliations if scholar.affiliation == x.name), None)
                    curr.nbr_scholars -= 1
                    counter = counter + 1
                    print("Removed scholar with no first-authored SCI publications: " + scholar.name)
            self.sss_scholars = tmp_scholars
            if counter > 0:
                print("Done! " + str(counter) + " scholars removed.")
            else:
                print("Done! No scholars were removed.")

    def clear_current_scholar(self):
        self.current_scholar = None

    def clear_current_pub(self):
        self.current_pub_title = -1
        self.current_pub_journal = -1
        self.current_pub_booktitle = -1
        self.current_pub_year = -1
        self.current_pub_authors = []
        self.current_pub_informal = False

    def write_results(self):
        print("Writing results to file")

        tmp = open(self.filename_prefix + "1_miner.txt","w+")
        for scholar in self.sss_scholars:
            tmp.write(scholar.name + "\n")
            tmp.write(scholar.sci_publications_to_string())
        tmp.close()

        tmp = open(self.filename_prefix + "1_miner.csv","w+")
        for scholar in self.sss_scholars:
            tmp.write(scholar.to_csv_line() + "\n")
        tmp.close()

        # Write concatenated titles per author and affiliation
        self.write_author_and_affiliation_titles()

        # Write co-authors to csv-file
        (pd.DataFrame.from_dict(data=self.global_SSS_coauthors, orient='index').to_csv(self.filename_prefix + "1_coauthors.csv", sep=';', header=False))

        # Write co-authors who are not already among the included SSS scholars
        diff = Counter()
        for candidate in self.global_SSS_coauthors:
            if self.scholar_exists(candidate):
                del diff[candidate]
            else:
                diff[candidate] = self.global_SSS_coauthors[candidate]

        (pd.DataFrame.from_dict(data=diff, orient='index').to_csv(self.filename_prefix + "1_candidates.csv", sep=';', header=False))

    def write_author_and_affiliation_titles(self):
        """
        Write all titles from all first authors to csv
        """

        titles_per_author = open(self.filename_prefix + "1_titles_per_author.csv", "w+")
        titles_per_affiliation = open(self.filename_prefix + "1_titles_per_affiliation.csv", "w+")
        affiliation_titles = self.get_dict_of_affiliations()

        for scholar in self.sss_scholars:
            tmp = scholar.name + "; "
            for p in scholar.get_first_author_titles():
                affiliation_titles[scholar.affiliation] += p + " "
                tmp += p + " "
            titles_per_author.write(tmp + "\n")

        for affiliation, titles in affiliation_titles.items():
            titles_per_affiliation.write(affiliation + ";" + titles + "\n")
        titles_per_author.close()
        titles_per_affiliation.close()

    def get_scholars(self):
        return self.sss_scholars

    def get_coauthors(self):
        return self.global_SSS_coauthors

    def scholar_exists(self, name):
        exists = False
        for scholar in self.sss_scholars:
           if scholar.name == name:
               exists = True
        return exists

    # SAX parsing

    def startElement(self, tag, attributes):
        self.CurrentData = tag
        self.current_string_done = False
        self.current_string = ""
        # Opening person
        if tag == "dblpperson":
            author_name = attributes["name"]
            author_id = attributes["pid"]
            dblp_entries = int(attributes["n"])
            self.current_scholar = SSSScholar(self.current_scholar_name, self.current_scholar_running_nbr, author_id, self.current_scholar_url, self.current_scholar_affiliation, dblp_entries)
        # Opening journal paper
        elif tag == "article":
            self.parsing_publication = True
            self.clear_current_pub()
            # filter arXiv preprints
            attribute_list = attributes.getNames()
            if "publtype" in attribute_list and attributes["publtype"] == "informal":
                self.current_pub_informal = True  # skipping arXiv preprints
        # Opening conference/workshop paper
        elif tag == "inproceedings":
            self.parsing_publication = True
            self.clear_current_pub()
        # Opening co-author of a publication
        elif tag == "author" and self.parsing_publication:
            # store the author's PID until we end the element
            self.tmp_author_pid = attributes["pid"]

    def endElement(self, tag):
        #print("# Closing: " + tag)
        self.current_string_done = True
        #print("String ready: " + str(self.current_string))
        # Closing person
        if tag == "dblpperson":
            self.sss_scholars.append(self.current_scholar)
        # Closing journal paper
        elif tag == "article" and not self.current_pub_informal:
            # Remove titles containing any of the substrings indicating editorial work
            real_article = True
            title_to_check = self.current_pub_title.lower()
            if title_to_check.find("special issue") >= 0 or title_to_check.find("special section") >= 0 or \
                    title_to_check.find("editorial") >= 0 or title_to_check.find("commentaries on") >= 0 or \
                    title_to_check.find("introduction to section") >= 0 or title_to_check.find(
                "editor's introduction") >= 0 or \
                    title_to_check.find("in this issue") >= 0 or title_to_check.find("foreword to the") >= 0 or \
                    title_to_check.find("erratum") >= 0 or title_to_check.find("corrigendum") >= 0 or \
                    title_to_check.find("correction to") >= 0 or \
                    title_to_check.find("open science initiative of the empirical software engineering journal") >= 0 or \
                    title_to_check.find("preface.") >= 0 or title_to_check.find("splc") >= 0 or \
                    title_to_check.find("ftscs") >= 0 or title_to_check.find("keynote") >= 0:
                #print("Skipping editorial work and corrections: " + self.current_pub_title)
                real_article = False

            # Remove titles published in ACM SIGSOFT Softw. Eng. Notes
            if self.current_pub_journal == "ACM SIGSOFT Softw. Eng. Notes":
                real_article = False

            if real_article:
                current_publication = SSSPublication(self.current_pub_title, self.current_pub_journal, self.current_pub_booktitle, self.current_pub_year, self.current_pub_authors)
                self.current_scholar.add_publication(current_publication)
            self.parsing_publication = False
        # Closing conference/workshop paper
        elif tag == "inproceedings":
            current_publication = SSSPublication(self.current_pub_title, self.current_pub_journal,
                                                 self.current_pub_booktitle, self.current_pub_year,
                                                 self.current_pub_authors)
            self.current_scholar.add_publication(current_publication)
            self.parsing_publication = False
        # Closing author
        elif tag == "author" and self.parsing_publication:
            self.current_pub_authors.append((self.author, self.tmp_author_pid))
        # Closing title
        elif tag == "title":
            self.current_pub_title = self.title
        # Closing journal
        elif tag == "journal":
            self.current_pub_journal = self.journal
        elif tag == "booktitle":
            self.current_pub_booktitle = self.booktitle
        # Closing year
        elif tag == "year":
            self.current_pub_year = self.year
        # Closing coauthor
        elif tag == "na":
            self.global_SSS_coauthors[self.na] += 1 # add/increment this author to the Counter
        self.CurrentData = ""

    # Overwrite the characters method to get the content of an XML element
    def characters(self, content):
        # Single chars need to be turned into strings to support concatenation
        if isinstance(self.current_string, bytes):
            self.current_string = self.current_string.decode()

        # remove any unreasonable characters, e.g., set theory
        tmp = content.encode('utf-8', 'ignore')
        if self.current_string == "": # add to new string
            self.current_string = tmp.decode()
        else: # concatenate to remembered string
            self.current_string = self.current_string + tmp.decode()

        if self.CurrentData == "author":
            self.author = self.current_string
        elif self.CurrentData == "title":
            self.title = self.current_string
        elif self.CurrentData == "journal":
            self.journal = self.current_string
        elif self.CurrentData == "booktitle":
            self.booktitle = self.current_string
        elif self.CurrentData == "year":
            self.year = self.current_string
        elif self.CurrentData == "na":
            self.na = self.current_string

    # Print progress bar for scholar processing
    def print_progress_bar(self, iteration, total):
        """
        Call in a loop to create terminal progress bar
        @params:
            iteration   : current iteration
            total       : total iterations
        """
        length = 50 # character length of bar (Int)
        decimals = 1 # number of decimals in percent complete
        fill = '█' # bar fill character (Str)
        percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
        filled_length = int(length * iteration // total)
        bar = fill * filled_length + '-' * (length - filled_length)

        print('\r%s |%s| %s%% %s' % ("Progress:", bar, percent, "Complete "), end = '\r')
        # Print New Line on Complete
        if iteration == total:
            print()

    def get_dict_of_affiliations(self):
        ''' Return a dict with affiliations as keys. All values are empty strings. '''
        affiliations = {}
        for scholar in self.sss_scholars:
            if scholar.affiliation not in affiliations:
                affiliations[scholar.affiliation] = ""
        return affiliations


# source: https://leetcode.com/problems/trapping-rain-water/

class Solution(object):
    def trap(self, heights):
        """
        :type height: List[int]
        :rtype: int
        """
        n = len(heights)
        if n < 3:
            return 0
        highest_idx = 0
        for i in range(n):
            if heights[i] > heights[highest_idx]:
                highest_idx = i
        # from let to right
        total = 0
        l_h = 0
        for i in range(highest_idx):
            if heights[i] > l_h:
                l_h = heights[i]
            total += l_h - heights[i]
        # from right to left
        r_h = 0
        for i in range(n-1, highest_idx, -1):
            if heights[i] > r_h:
                r_h = heights[i]
            total += r_h - heights[i]
        return total


# get_hash login we will implement the same in hash_table class

# def get_hash(key):
#     h = 0
#     for char in key:
#         h += ord(char)
#     return h % 100

class HashTable:
    def __init__(self):
        self.MAX_SIZE = 100
        self.arr = [[] for i in range(self.MAX_SIZE)]

    def get_hash(self, key):
        chars = 0
        for char in key:
            chars += ord(char)
        return chars % self.MAX_SIZE

    # instead of this h.add('march 6', 130) we can use h['march 6'] = 130 by replacing add with __setitem__
    # what we are doing is operator overriding
    # replace 'def add(self, key):' this with 'def __setitem__(self, key)'
    def __setitem__(self, key, val):
        hash_data = self.get_hash(key)
        found = False
        for idx, element in enumerate(self.arr[hash_data]):
            if len(element) == 2 and element[0] == key:
                self.arr[hash_data][idx] = (key, val)
                found = True
                break
        if not found:
            self.arr[hash_data].append((key, val))

    # instead of this h.add('march 6', 130) we can use h['march 6'] = 130 by replacing add with __setitem__
    # what we are doing is operator overriding
    # replace 'def get(self, key):' this with 'def __getitem__(self, key)'
    def __getitem__(self, key):
        hash_data = self.get_hash(key)
        for element in self.arr[hash_data]:
            if element[0] == key:
                return element[1]

    def __delitem__(self, key):
        hash_data = self.get_hash(key)
        for index, element in enumerate(self.arr[hash_data]):
            if element[0] == key:
                del self.arr[hash_data][index]

if __name__ == '__main__':
    h = HashTable()
    h.get_hash('march 6')
    # h.add('march 6', 130)
    # print(h.get('march 6'))
    h['march 6'] = 130
    h['march 6'] = 50
    h['march 7'] = 140
    h['march 8'] = 150
    h['march 17'] = 200
    print(h.arr, end="\n")
    print(h['march 6'])
    print(h['march 17'])
    del h['march 17']
    print(h.arr)

DataStructures/3 - HashMap/hasmap implimention with collision handling-chaining.py


import multiprocessing
import os.path as path
import cv2
import lgsvl
import time
from logger import create_logger

from lane_detector import LaneDetector

class ControllerProcess(multiprocessing.Process):
    def __init__(self, log_q, queue, event_handler, sim_event_handler):
        super().__init__()
        self.log = create_logger(log_q, controller=True)
        self.queue = queue
        self.eventH = event_handler
        self.eventH_sim = sim_event_handler
        self.log.info("Initialized the controller")

        self.controller = LaneDetector(self.log)

    def run(self):
        old_controls = None
        self.log.info("Starting the controller process...")
        initial_controls = self.controller.init()
        self.queue.put(initial_controls)
        self.log.debug("Put initial controls to the queue")
        while True:
            self.log.debug("Setting the simulation event. Requesting sensor data and/or sending data.")
            self.eventH_sim.set()
            self.log.debug("Waiting for an event from the simulator")
            while not self.eventH.is_set():
                self.eventH.wait()
            self.log.debug("Received an event from the simulator")
            self.eventH.clear()
            sensors = self.queue.get()
            controls = self.controller.execute(sensors, old_controls)
            old_controls = controls
            self.queue.put(controls)


__copyright__ = "Copyright 2017 Birkbeck, University of London"
__author__ = "Martin Paul Eve & Andy Byers"
__license__ = "AGPL v3"
__maintainer__ = "Birkbeck Centre for Technology and Publishing"

import re

from django import forms
from django.utils.translation import gettext, gettext_lazy as _

from submission import models
from core import models as core_models
from identifiers import models as ident_models
from review.logic import render_choices
from utils.forms import KeywordModelForm, JanewayTranslationModelForm
from utils import setting_handler

class PublisherNoteForm(forms.ModelForm):

    class Meta:
        model = models.PublisherNote
        fields = ('text',)

class ArticleStart(forms.ModelForm):

    class Meta:
        model = models.Article
        fields = ('publication_fees', 'submission_requirements', 'copyright_notice', 'comments_editor',
                  'competing_interests')

    def __init__(self, *args, **kwargs):
        journal = kwargs.pop('journal', False)
        super(ArticleStart, self).__init__(*args, **kwargs)

        self.fields['competing_interests'].label = ''
        self.fields['comments_editor'].label = ''

        if not journal.submissionconfiguration.publication_fees:
            self.fields.pop('publication_fees')
        else:
            self.fields['publication_fees'].required = True

        if not journal.submissionconfiguration.submission_check:
            self.fields.pop('submission_requirements')
        else:
            self.fields['submission_requirements'].required = True

        if not journal.submissionconfiguration.copyright_notice:
            self.fields.pop('copyright_notice')
        else:
            self.fields['copyright_notice'].required = True
            copyright_label = setting_handler.get_setting(
                'general',
                'copyright_submission_label',
                journal,
            ).processed_value
            self.fields['copyright_notice'].label = copyright_label

        if not journal.submissionconfiguration.competing_interests:
            self.fields.pop('competing_interests')

        if not journal.submissionconfiguration.comments_to_the_editor:
            self.fields.pop('comments_editor')

class ArticleInfo(KeywordModelForm, JanewayTranslationModelForm):
    FILTER_PUBLIC_FIELDS = False

    class Meta:
        model = models.Article
        fields = ('title', 'subtitle', 'abstract', 'non_specialist_summary',
                  'language', 'section', 'license', 'primary_issue',
                  'article_number', 'is_remote', 'remote_url', 'peer_reviewed',
                  'first_page', 'last_page', 'page_numbers', 'total_pages',
                  'competing_interests', 'custom_how_to_cite', 'rights')
        widgets = {
            'title': forms.TextInput(attrs={'placeholder': _('Title')}),
            'subtitle': forms.TextInput(attrs={'placeholder': _('Subtitle')}),
            'abstract': forms.Textarea(
                attrs={
                    'placeholder': _('Enter your article\'s abstract here')
                }
            ),
        }

    def __init__(self, *args, **kwargs):
        """
        Initialises the ArticleInfo form.
        :param kwargs:  elements: queryest of Field objects.
                        submission_sumary: boolean, detmines if this field
                        is on or off.
                        journal: Journal object.
                        pop_disabled_fields: boolean, if False we do not pop
                        fields that are disabled by SubmissionConfiguration
                        or overwrite their saving.
        """
        elements = kwargs.pop('additional_fields', None)
        submission_summary = kwargs.pop('submission_summary', None)
        journal = kwargs.pop('journal', None)
        self.pop_disabled_fields = kwargs.pop('pop_disabled_fields', True)

        super(ArticleInfo, self).__init__(*args, **kwargs)
        if 'instance' in kwargs:
            article = kwargs['instance']
            section_queryset = models.Section.objects.filter(
                journal=article.journal,
            )
            license_queryset = models.Licence.objects.filter(
                journal=article.journal,
            )
            if self.FILTER_PUBLIC_FIELDS:
                section_queryset = section_queryset.filter(
                    public_submissions=self.FILTER_PUBLIC_FIELDS,
                )
                license_queryset = license_queryset.filter(
                    available_for_submission=self.FILTER_PUBLIC_FIELDS,
                )
            self.fields['section'].queryset = section_queryset
            self.fields['license'].queryset = license_queryset

            self.fields['section'].required = True
            self.fields['license'].required = True
            self.fields['primary_issue'].queryset = article.issues.all()

            abstracts_required = article.journal.get_setting(
                'general',
                'abstract_required',
            )

            if abstracts_required:
                self.fields['abstract'].required = True

            if submission_summary:
                self.fields['non_specialist_summary'].required = True

            # Pop fields based on journal.submissionconfiguration
            if journal and self.pop_disabled_fields:
                if not journal.submissionconfiguration.subtitle:
                    self.fields.pop('subtitle')

                if not journal.submissionconfiguration.abstract:
                    self.fields.pop('abstract')

                if not journal.submissionconfiguration.language:
                    self.fields.pop('language')

                if not journal.submissionconfiguration.license:
                    self.fields.pop('license')

                if not journal.submissionconfiguration.keywords:
                    self.fields.pop('keywords')

                if not journal.submissionconfiguration.section:
                    self.fields.pop('section')

            # Add additional fields
            if elements:
                for element in elements:
                    if element.kind == 'text':
                        self.fields[element.name] = forms.CharField(
                            widget=forms.TextInput(attrs={'div_class': element.width}),
                            required=element.required)
                    elif element.kind == 'textarea':
                        self.fields[element.name] = forms.CharField(widget=forms.Textarea,
                                                                    required=element.required)
                    elif element.kind == 'date':
                        self.fields[element.name] = forms.CharField(
                            widget=forms.DateInput(attrs={'class': 'datepicker', 'div_class': element.width}),
                            required=element.required)

                    elif element.kind == 'select':
                        choices = render_choices(element.choices)
                        self.fields[element.name] = forms.ChoiceField(
                            widget=forms.Select(attrs={'div_class': element.width}), choices=choices,
                            required=element.required)

                    elif element.kind == 'email':
                        self.fields[element.name] = forms.EmailField(
                            widget=forms.TextInput(attrs={'div_class': element.width}),
                            required=element.required)
                    elif element.kind == 'check':
                        self.fields[element.name] = forms.BooleanField(
                            widget=forms.CheckboxInput(attrs={'is_checkbox': True}),
                            required=element.required)

                    self.fields[element.name].help_text = element.help_text
                    self.fields[element.name].label = element.name

                    if article:
                        try:
                            check_for_answer = models.FieldAnswer.objects.get(field=element, article=article)
                            self.fields[element.name].initial = check_for_answer.answer
                        except models.FieldAnswer.DoesNotExist:
                            pass

    def save(self, commit=True, request=None):
        article = super(ArticleInfo, self).save(commit=False)

        if request:
            additional_fields = models.Field.objects.filter(journal=request.journal)

            for field in additional_fields:
                answer = request.POST.get(field.name, None)
                if answer:
                    try:
                        field_answer = models.FieldAnswer.objects.get(article=article, field=field)
                        field_answer.answer = answer
                        field_answer.save()
                    except models.FieldAnswer.DoesNotExist:
                        field_answer = models.FieldAnswer.objects.create(article=article, field=field, answer=answer)

            if self.pop_disabled_fields:
                request.journal.submissionconfiguration.handle_defaults(article)

        if commit:
            article.save()

        return article

class ArticleInfoSubmit(ArticleInfo):
    # Filter licenses and sections to publicly available only
    FILTER_PUBLIC_FIELDS = True

class EditorArticleInfoSubmit(ArticleInfo):
    # Used when an editor is making a submission.
    FILTER_PUBLIC_FIELDS = False

class AuthorForm(forms.ModelForm):

    class Meta:
        model = core_models.Account
        exclude = (
            'date_joined',
            'activation_code'
            'date_confirmed'
            'confirmation_code'
            'reset_code'
            'reset_code_validated'
            'roles'
            'interest'
            'is_active'
            'is_staff'
            'is_admin'
            'password',
            'username',
            'roles',
        )

        widgets = {
            'first_name': forms.TextInput(attrs={'placeholder': 'First name'}),
            'middle_name': forms.TextInput(attrs={'placeholder': 'Middle name'}),
            'last_name': forms.TextInput(attrs={'placeholder': 'Last name'}),
            'biography': forms.Textarea(
                attrs={'placeholder': 'Enter biography here'}),
            'institution': forms.TextInput(attrs={'placeholder': 'Institution'}),
            'department': forms.TextInput(attrs={'placeholder': 'Department'}),
            'twitter': forms.TextInput(attrs={'placeholder': 'Twitter handle'}),
            'linkedin': forms.TextInput(attrs={'placeholder': 'LinkedIn profile'}),
            'impactstory': forms.TextInput(attrs={'placeholder': 'ImpactStory profile'}),
            'orcid': forms.TextInput(attrs={'placeholder': 'ORCID ID'}),
            'email': forms.TextInput(attrs={'placeholder': 'Email address'}),
        }

    def __init__(self, *args, **kwargs):
        super(AuthorForm, self).__init__(*args, **kwargs)
        self.fields['password'].required = False
        self.fields['first_name'].required = True
        self.fields['last_name'].required = True

    def clean_orcid(self):
        orcid_string = self.cleaned_data.get('orcid')
        print(orcid_string)
        try:
            return utility_clean_orcid(orcid_string)
        except ValueError:
            self.add_error(
                'orcid',
                'An ORCID must be in the pattern https://orcid.org/0000-0000-0000-0000 or'
                ' 0000-0000-0000-0000',
            )
        return orcid_string

class FileDetails(forms.ModelForm):

    class Meta:
        model = core_models.File
        fields = (
            'label',
            'description',
        )

    def __init__(self, *args, **kwargs):
        super(FileDetails, self).__init__(*args, **kwargs)
        self.fields['label'].required = True
        self.fields['label'].inital = 'Manuscript'

class EditFrozenAuthor(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        instance = kwargs.pop("instance", None)
        if instance:
            if instance.author:
                self.fields["frozen_email"].help_text += gettext(
                    "Currently linked to %s, leave blank to use this address"
                    "" % instance.author.email,
                )
                if instance.author.orcid:
                    self.fields["frozen_orcid"].help_text += gettext(
                        "If left blank, the account ORCiD will be used (%s)"
                        "" % instance.author.orcid,
                    )
            del self.fields["is_corporate"]
            if instance.is_corporate:
                del self.fields["name_prefix"]
                del self.fields["first_name"]
                del self.fields["middle_name"]
                del self.fields["last_name"]
                del self.fields["name_suffix"]

    class Meta:
        model = models.FrozenAuthor
        fields = (
            'name_prefix',
            'first_name',
            'middle_name',
            'last_name',
            'name_suffix',
            'institution',
            'department',
            'frozen_biography',
            'country',
            'is_corporate',
            'frozen_email',
            'frozen_orcid',
            'display_email',
        )

    def save(self, commit=True, *args, **kwargs):
        obj = super().save(*args, **kwargs)
        if commit is True and obj.frozen_email:
            try:
                # Associate with account if one exists
                account = core_models.Account.objects.get(
                    username=obj.frozen_email.lower())
                obj.author = account
                obj.frozen_email = None
            except core_models.Account.DoesNotExist:
                pass
            obj.save()
        return obj

    def clean_frozen_orcid(self):
        orcid_string = self.cleaned_data.get('frozen_orcid')
        try:
            return utility_clean_orcid(orcid_string)
        except ValueError:
            self.add_error(
                'frozen_orcid',
                'An ORCID must be in the pattern https://orcid.org/0000-0000-0000-0000 or'
                ' 0000-0000-0000-0000',
            )
        return orcid_string

class IdentifierForm(forms.ModelForm):

    class Meta:
        model = ident_models.Identifier
        fields = (
            'id_type',
            'identifier',
            'enabled',
        )

class FieldForm(forms.ModelForm):

    class Meta:
        model = models.Field
        exclude = (
            'journal',
            'press',
        )

class LicenseForm(forms.ModelForm):

    class Meta:
        model = models.Licence
        exclude = (
            'journal',
            'press',
        )

class ConfiguratorForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(ConfiguratorForm, self).__init__(*args, **kwargs)
        self.fields['default_section'].queryset = models.Section.objects.filter(
            journal=self.instance.journal,
        )
        self.fields[
            'default_license'].queryset = models.Licence.objects.filter(
            journal=self.instance.journal,
        )

    def clean(self):
        cleaned_data = super().clean()

        license = cleaned_data.get('license', False)
        section = cleaned_data.get('section', False)
        language = cleaned_data.get('language', False)

        default_license = cleaned_data.get('default_license', None)
        default_section = cleaned_data.get('default_section', None)
        default_language = cleaned_data.get('default_language', None)

        if not license and not default_license:
            self.add_error(
                'default_license',
                'If license is unset you must select a default license.',
            )

        if not section and not default_section:
            self.add_error(
                'default_section',
                'If section is unset you must select a default section.',
            )

        if not language and not default_language:
            self.add_error(
                'default_language',
                'If language is unset you must select a default language.'
            )

    class Meta:
        model = models.SubmissionConfiguration
        exclude = (
            'journal',
        )

class ProjectedIssueForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(ProjectedIssueForm, self).__init__(*args, **kwargs)
        self.fields['projected_issue'].queryset = self.instance.journal.issue_set.all()

    class Meta:
        model = models.Article
        fields = ('projected_issue',)

class FunderForm(forms.ModelForm):

    class Meta:
        model = models.Funder
        fields = ('name', 'fundref_id', 'funding_id')

    def __init__(self, *args, **kwargs):
        self.article = kwargs.pop('article', None)
        super().__init__(*args, **kwargs)

    def save(self, commit=True, *args, **kwargs):
        funder = super().save(commit=commit, *args, **kwargs)
        if self.article:
            self.article.funders.add(funder)
            self.article.save()
        return funder

def utility_clean_orcid(orcid):
    """
    Utility function that cleans an ORCID ID.
    """
    if orcid:
        orcid_regex = re.compile('([0]{4})-([0-9]{4})-([0-9]{4})-([0-9]{3})([0-9X]{1})')
        result = orcid_regex.search(orcid)

        if result:
            return result.group(0)
        else:
            raise ValueError('ORCID is not valid.')

    # ORCID is None.
    return orcid


import torch
import clip
from models.stylegan2 import Generator, GeneratorMappingWrapper

class GradientManager(object):
    def __init__(self, opts):
        self.train_encoder = opts.train_encoder
        self.train_full_generator = opts.train_full_generator

    def requires_grad_generator_wrapper(self, model: GeneratorMappingWrapper, flag=True):
        self.requires_grad_generator(model.generator)

        for p in model.pre_mapping.parameters():
            p.requires_grad = flag

    def requires_grad_generator(self, model: Generator, flag=True):
        if not flag:
            for p in model.parameters():
                p.requires_grad = flag
        if flag:
            if self.train_full_generator:
                for p in model.parameters():
                    p.requires_grad = flag
            else:
                for p in model.style.parameters():
                    p.requires_grad = flag

    def __requires_grad(self, model: torch.nn.Module, flag=True):
        for p in model.parameters():
            p.requires_grad = flag

    def requires_grad(self, model: torch.nn.Module, flag=True):
        if type(model) == Generator:
            self.requires_grad_generator(model, flag)
        if type(model) == GeneratorMappingWrapper:
            self.requires_grad_generator_wrapper(model, flag)
        if (type(model) == clip.model.CLIP) and self.train_encoder:
            self.__requires_grad(model, flag)
            self.__requires_grad(model.visual, flag)
        else:
            self.__requires_grad(model, flag)


from ..dbConfig import dbConnect, dbDisconnect

class LocationHistory:
	# Constructor
	def __init__(self, id = None):
		# Connect to database
		connection = dbConnect()
		db = connection.cursor()

		# If the id is provided, fill the object with details from database
		hasResult = False
		if id is not None:
			# Select location history from database and populate instance variables
			result = db.execute("""SELECT id, NRIC, location_visited, time_in,
										  time_out
								   FROM location_history
								   WHERE id = (?)""", (id,)).fetchone()

			# Populate private instance variables with value or None
			if result is not None:
				hasResult = True
				self.__id = result[0]
				self.__NRIC = result[1]
				self.__locationVisited = result[2]
				self.__time_in = result[3]
				self.__time_out = result[4]

		# If no result
		if not hasResult:
				self.__id = None
				self.__NRIC = None
				self.__locationVisited = None
				self.__time_in = None
				self.__time_out = None

		# Disconnect from database
		dbDisconnect(connection)

	# Accessor Method
	def getID(self):
		return self.__id

	def getNRIC(self):
		return self.__NRIC

	def getTimeIn(self):
		return self.__time_in

	def getTimeOut(self):
		return self.__time_out

	# Other Method
	def getPastLocationHistory(self, NRIC, noOfDays):
		"""
		Return None if there is no result, or
		Return a 2d array containing all results
		"""
		# Connect to database
		connection = dbConnect()
		db = connection.cursor()

		#Format statement for SQL
		date = "-{} days".format(noOfDays)

		# Select location history within past __ of days based on NRIC
		result = db.execute("""SELECT id, NRIC, location_visited, time_in,
									  time_out
							   FROM location_history
							   WHERE NRIC = (?) AND
							   		 date(time_in) >= strftime('%Y-%m-%d', date(date('now','localtime')), (?))
							   ORDER BY time_in DESC""",
							(NRIC, date)).fetchall()

		# Disconnect from database
		dbDisconnect(connection)

		return result

	def getLocationHistoryOn(self, NRIC, noOfDaysAgo):
		"""
		Return None if there is no result, or
		Return an array containing all locationID
		"""
		# Connect to database
		connection = dbConnect()
		db = connection.cursor()

		#Format statement for SQL
		date = "-{} days".format(noOfDaysAgo)

		latestDate = None
		if noOfDaysAgo > 0:
			latestDate = "-{} days".format(noOfDaysAgo - 1)
		else:
			latestDate = "+{} days".format(noOfDaysAgo + 1)

		# Select location history within past __ of days based on NRIC
		results = db.execute("""SELECT id, NRIC, location_visited, time_in,
									  time_out
							   FROM location_history
							   WHERE NRIC = (?) AND
							   		 date(time_in) >= strftime('%Y-%m-%d', date(date('now','localtime')), (?)) AND
									 date(time_in) < strftime('%Y-%m-%d', date(date('now','localtime')), (?))
							   ORDER BY time_in DESC""",
							(NRIC, date, latestDate)).fetchall()

		# Disconnect from database
		dbDisconnect(connection)

		# Get all infected people's locationID
		locationList = []
		for result in results:
			locationList.append(result[2])

		# Return the list of locationID
		return locationList

	def getLocationCheckInDetails(self, locationID, noOfDaysAgo, NRICList):
		"""
		Return 2d array containing details
		[][0] - id
		[][1] - NRIC
		[][2] - location_visited
		[][3] - time_in
		[][4] - time_out
		"""
		# Connect to database
		connection = dbConnect()
		db = connection.cursor()

		#Format statement for SQL
		date = "-{} days".format(noOfDaysAgo)

		latestDate = None
		if noOfDaysAgo > 0:
			latestDate = "-{} days".format(noOfDaysAgo - 1)
		else:
			latestDate = "+{} days".format(noOfDaysAgo + 1)

		query = """SELECT id, NRIC, location_visited, time_in, time_out
					FROM location_history
					WHERE
						date(time_in) >= strftime('%Y-%m-%d', date(date('now','localtime')), (?)) AND
						date(time_in) < strftime('%Y-%m-%d', date(date('now','localtime')), (?)) AND
						location_visited = (?) AND
						NRIC IN ({seq})
					ORDER BY time_in DESC""".format(seq=','.join(['?']*len(NRICList)))

		# Prepare query arguments
		queryArgs = [date, latestDate, locationID]
		for item in NRICList:
			queryArgs.append(item)

		# Select location history within past __ of days based on NRIC
		results = db.execute(query, queryArgs).fetchall()

		# Disconnect from database
		dbDisconnect(connection)

		# Return the list of locationID
		return results


import matplotlib.pylab as plt
import cv2 as cv

Imgs = []

def print_add(img) -> None:
    Imgs.append(img)

def print_imgs(name: str) -> None:
    time = 1
    for img in Imgs:
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
        plt.subplot(3, 3, time)
        plt.imshow(img)
        plt.axis('off')
        plt.title(name + str(time))
        time = time + 1
    plt.show()

def cv_read(paths: list) -> list:
    imgs = []
    for path in paths:
        imgs.append(cv.imread(path))
    return imgs


##################################################################################
# Cross-modal Guided Visual Representation Learning for Social Image Retrieval   #
#                                                                                #
#                                                                                #
# Description: This .py is used for training and test the CGVR                   #
#                                                                                #
# Note: This code is used for ICCV2023 review purposes                           #
##################################################################################

from utils import getMAP
import torch
from model.models import build_CGVR_net
from torch import optim
from tqdm import tqdm
from torch.optim import lr_scheduler
import time
import os
import logging
import numpy as np
from dataset.dataloader import get_train_loaders, get_base_loaders, get_query_loaders, deserialize_vocab
import random
import argparse
from losses import ContrastiveLoss

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--dataname', default='nuswide', help='nuswide or mirflickr25k')
    parser.add_argument('--img_size', default=224, type=int, help='image size. default(224)')
    parser.add_argument('--device', default='cuda:0')
    parser.add_argument('--Epochs', default=60, type=int, help="Number of epoch.")
    parser.add_argument('--lr', default=0.0001, help="Learning rate.")
    parser.add_argument('--workers', default=8, type=int, metavar='N',
                        help='number of data loading workers (default: 8)')
    parser.add_argument('--batch_size', default=64, type=int,
                        metavar='N', help='mini-batch size')
    parser.add_argument('--pretrained', default=True)
    parser.add_argument('--word_dim', default=300, type=int, help="dim of word")
    parser.add_argument('--dropout', default=0.1, type=float,
                        help="Dropout applied in the transformer")
    parser.add_argument('--resume', type=bool, default=False)
    parser.add_argument('--writelog', type=bool, default=False)

    # CGVR

    parser.add_argument('--d_model', default=2048, type=int,
                        help="num_channels of the resnet feature (512 for resnet18 and resnet34, 2048 for resnet50 and resnet101)")
    parser.add_argument('--CGVR_backbone', default='resnet50', type=str,
                        help="Name of the convolutional backbone to use")
    parser.add_argument('--enc_layers', default=0, type=int,
                        help="Number of encoding layers in the transformer")
    parser.add_argument('--dec_layers', default=2, type=int,
                        help="Number of decoding layers in the transformer")
    parser.add_argument('--kg_layers', default=2, type=int,
                        help="Number of kg_attention layers in the transformer")

    parser.add_argument('--position_embedding', default='sine', type=str, choices=('sine'),
                        help="Type of positional embedding to use on top of the image features")
    parser.add_argument('--nheads', default=8, type=int,
                        help="Number of attention heads inside the transformer's attentions")
    parser.add_argument('--CGVR_nbits', default=64, type=int, help="CGVR output length")
    parser.add_argument('--use_KG', default=True)
    parser.add_argument('--margin_scaler', default=0.15 , type=float)
    parser.add_argument('--ignoring_rate', default=0.01, type=float) #0.01 DEFAULE

    args = parser.parse_args()
    setup_seed(41)
    device = torch.device(args.device if torch.cuda.is_available() else 'cpu')

    logging = write_log(args)
    print(device)
    logging.info("Backbone: {}".format(args.CGVR_backbone))
    logging.info("Start training on {}...".format(args.dataname))
    logging.info("batch_size: {}".format(args.batch_size))
    logging.info("learning_rate: {}".format(args.lr))
    logging.info("nbits: {}".format(args.CGVR_nbits))

    data_path = "data/{}".format(args.dataname)
    query_caps = 'query/query.txt'
    base_caps = 'base/base.txt'
    train_caps = 'train/train.txt'

    vocab_path = os.path.join('dataset/vocab/{}_vocab.json'.format(args.dataname))
    vocab = deserialize_vocab(vocab_path)
    rel_matrix = np.load('dataset/concepnet/{}_rel50.npy'.format(args.dataname))
    rel_matrix = torch.from_numpy(rel_matrix)
    save_path = 'checkpoints/CGVR/{}/crn_resnet101_{}bits_{}_{}.pth'.format(args.dataname, args.CGVR_nbits, args.lr, args.dataname)
    groundTruthSimilarityMatrix = np.load("data/{}/GroundTruthSimilarityMatrix.npy".format(args.dataname))
    word_vectors = np.load("dataset/wordembedding/{}ConceptNetEmbedding.npy".format(args.dataname))
    word_vectors = torch.from_numpy(word_vectors).to(torch.double)

    train_loader = get_train_loaders(base_path=data_path, data_path=train_caps, vocab=vocab, batch_size=args.batch_size,
                                     workers=args.workers)
    query_loader = get_query_loaders(base_path=data_path, data_path=query_caps, vocab=vocab, batch_size=args.batch_size,
                                     workers=args.workers)
    base_loader = get_base_loaders(base_path=data_path, data_path=base_caps, vocab=vocab, batch_size=args.batch_size,
                                   workers=args.workers)
    print(len(train_loader), len(query_loader), len(base_loader))

    CGVR_net = build_CGVR_net(word_vectors, rel_matrix, args)
    CGVR_net = CGVR_net.to(device)
    backbone_params = CGVR_net.backbone.parameters()
    backbone_params_list = list(map(id, CGVR_net.backbone.parameters()))
    customers_params = filter(lambda p: id(p) not in backbone_params_list, CGVR_net.parameters())
    optimizer = optim.SGD([{'params': customers_params},
                           {'params': backbone_params, 'lr': args.lr * 0.1}],
                          lr=args.lr, weight_decay=0.01, momentum=0.9)
    lr_sche = lr_scheduler.StepLR(optimizer, step_size=15, gamma=0.1, last_epoch=-1)

    certerion = ContrastiveLoss(args)
    best_mAP = 0

    if args.resume:
        print('loading latest model parameters...')
        logging.info('loading latest model parameters...')
        model_state_dict = torch.load(save_path, map_location=device)
        CGVR_net.load_state_dict(model_state_dict)

    # training CGVR
    for epoch in range(args.Epochs):
        print('----------------------------Training----------------------------')
        print('Epoch: {}, lr: {:.6f}'.format(epoch + 1, optimizer.param_groups[0]["lr"]))
        logging.info('----------------------------Training----------------------------')
        logging.info('Epoch: {}, lr: {:.6f}'.format(epoch + 1, optimizer.param_groups[0]["lr"]))
        avg_loss = train(train_loader, CGVR_net, certerion, optimizer, epoch, device, query_loader, base_loader, groundTruthSimilarityMatrix, save_path)
        lr_sche.step()
        print("AVGLoss: {:.4f}".format(avg_loss))
        logging.info("AVGLoss: {:.4f}".format(avg_loss))
        if (epoch + 1) % 1 == 0:
            print('----------------------------Verifying----------------------------')
            logging.info('----------------------------Verifying----------------------------')
            MAP, precisions, recalls = validate(query_loader, base_loader, groundTruthSimilarityMatrix, CGVR_net, device)
            if best_mAP < MAP:
                best_mAP = MAP
                torch.save(CGVR_net.state_dict(), save_path)
                print('Teacher Model Changed!')
            else:
                print('Teacher Model Not Changed!')

            print('Teacher Model : cur_mAP = {:.4f}, best_mAP = {:.4f} \n'.format(MAP, best_mAP))
    '''
    print('----------------------------Verifying----------------------------')
    logging.info('----------------------------Verifying----------------------------')
    MAP, precisions, recalls = validate(query_loader, base_loader, groundTruthSimilarityMatrix, CRN_net, device)
    torch.save(CGVR_net.state_dict(), save_path)

    print('CGVR Model : mAP = {:.4f} \n'.format(MAP))
    logging.info('CRN Model : mAP = {:.4f}\n'.format(MAP))
    '''
    logging.info("End training on {}...".format(args.dataname))
    logging.info("nbits: {}".format(args.CRN_nbits))

def getHashes(outputs):
    return (torch.sgn(outputs - 0.5) + 1) * 0.5

def train(train_loader, CGVR_net, criterion, optimizer, epoch, device, query_loader, base_loader, groundTruthSimilarityMatrix, save_path):
    loss_sum = 0
    batch_start = time.time()
    CGVR_net.train()
    best_mAP = 0
    for i, (imgs, targets, ids, lengths) in enumerate(train_loader):
        imgs = imgs.to(device)
        targets = targets.to(device)
        outputs_h1, outputs_h2, caps_embed, s_v, sim_mat, s_v2 = CGVR_net(imgs, targets, lengths)
        loss = criterion(outputs_h1, outputs_h2, caps_embed, sim_mat, epoch, s_v, s_v2)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        loss_sum += loss.item()
        if (i + 1) % 10 == 0:
            batch_end = time.time()
            print('batch_{}, loss: {:.4f}, Time: {:.2f}'.format(i + 1, loss.item(), batch_end - batch_start))
            logging.info('batch_{}, loss: {:.4f}, Time: {:.2f}'.format(i + 1, loss.item(), batch_end - batch_start))
            batch_start = time.time()

    avg_loss = loss_sum / len(train_loader)
    return avg_loss

def validate(query_loader, base_loader, groundTruthSimilarityMatrix, CGVR_net, device):
    queryHashes, baseHashes = [], []
    CGVR_net.eval()
    with torch.no_grad():
        start = time.time()
        for i, (imgs, targets, ids, lengths) in enumerate(tqdm(query_loader, "queryHashBuilding")):
            imgs = imgs.to(device)
            outputs_h1 = CGVR_net(imgs)
            queryHashes.append(getHashes(outputs_h1))
        queryHashes = torch.cat(queryHashes, dim=0)
        end = time.time()
        print("Q_Hash's shape: {}, Time:{:.2f}".format(queryHashes.shape, end - start))
        logging.info("Q_Hash's shape: {}, Time:{:.2f}".format(queryHashes.shape, end - start))
        for i, (imgs, targets, ids, lengths) in enumerate(tqdm(base_loader, "baseHashBuilding")):
            imgs = imgs.to(device)
            outputs_h1 = CGVR_net(imgs)
            baseHashes.append(getHashes(outputs_h1))
        baseHashes = torch.cat(baseHashes, dim=0)
        end = time.time()
        print("B_Hash's shape: {}, Time:{:.2f}".format(baseHashes.shape, end - start))
        logging.info("B_Hash's shape: {}, Time:{:.2f}".format(baseHashes.shape, end - start))
        MAP, precisions, recalls = getMAP(queryHashes, baseHashes, groundTruthSimilarityMatrix, top=5000)
    return MAP, precisions, recalls

def setup_seed(seed):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.deterministic = True

def write_log(args):
    filepath = 'checkpoints/CGVR/{}/log/CGVR_resnet_{}bits_{}_{}.txt'\
        .format(args.dataname, str(args.CGVR_nbits), str(args.lr), args.dataname)
    logging.basicConfig(
        filename=filepath,
        level=logging.INFO,
    )
    return logging

if __name__ == '__main__':
    main()


class Solution:
    def strangePrinter(self, s: str) -> int:
        n = len(s)

        @cache
        def dp(l: int, r: int) -> int:
            if l == r:
                return 0
            if r - l == 1:
                return 1
            res = 100
            toRemove = 1 if s[l] == s[r - 1] else 0
            for i in range(l + 1, r):
                res = min(res, dp(l, i) + dp(i, r) - toRemove)
            return res

        return dp(0, n)


import google.auth.transport.requests
import google.oauth2.id_token
import os
import requests
import json
from google.cloud import pubsub_v1

def report_failure(failure: dict) -> dict:
 #   url: str = os.environ.get(
 #       'ERROR_HANDLER_URL',
 #       'https://us-central1-aou-curation-omop-dev.cloudfunctions.net/fhir_to_fhirstore_error_handler'
 #   )

#    req = make_authorized_request(
#        method='POST',
#        url=url,
#        json=failure,
#    ).prepare()

#    sess = requests.Session()
#    response = sess.send(req)
#    print(f'Error handler responded with {response.status_code}')

    response = publish(failure)

    return failure

def make_authorized_request(url: str, json: dict, method: str = 'GET'):
    """
    make_authorized_get_request makes a GET request to the specified HTTP endpoint
    in service_url (must be a complete URL) by authenticating with the
    ID token obtained from the google-auth client library.
    """

    auth_req = google.auth.transport.requests.Request()
    id_token = google.oauth2.id_token.fetch_id_token(auth_req, url)

    headers: dict = {'Authorization': f'Bearer {id_token}'}

    return requests.Request(method=method, url=url, json=json, headers=headers)

# Publishes a message to a Cloud Pub/Sub topic.
def publish(request):

    # Instantiates a Pub/Sub client
    publisher = pubsub_v1.PublisherClient()

    # References an existing topic
    project_id = 'aou-curation-omop-dev'
    topic_name = 'site-fhir-data-error-handler'
    topic_path = publisher.topic_path(project_id, topic_name)

    message_json = json.dumps({
        'data': {'message': request},
    })
    message_bytes = message_json.encode('utf-8')

    # Publishes a message
    try:
        publish_future = publisher.publish(topic_path, data=message_bytes)
        publish_future.result()  # Verify the publish succeeded
        return 'Message published.'
    except Exception as e:
        print(e)
        return (e, 500)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu May 31 16:30:15 2018

@author: anastasis
"""

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb  5 17:53:24 2018

@author: anastasis
"""
def create_artist(timestep = 15, df="pois_toclusters.csv", only_start = 'No'):
    import pandas as pd
    from datetime import timedelta, datetime
    import numpy as np
    if ".csv" in df:
        my_df_ex1 = pd.read_csv(df)
    else:
        my_df_ex1 = df
    metrics = pd.read_excel('metrs.xls', header= None, names = ['artist', 'metr', 'rep'])

    start = my_df_ex1['Date'].iloc[0]+' 00:00:00'
    start = datetime.strptime(start, '%Y-%m-%d %H:%M:%S')
    end = my_df_ex1['Date'].iloc[0]+' 23:59:59'
    end = datetime.strptime(end, '%Y-%m-%d %H:%M:%S')

    periods = []
    periods_to_numbers = []
    #list of each period in from-to view
    periods_from_to = []
    #same as periods_to_numbers but instead of numbers we got from-to
    each_period = []

    def check_user(Timestamp):
        for i in range(len(periods)):
            if (Timestamp >= periods[i] and Timestamp < periods[i+1]):
                periods_to_numbers.append(i)
                each_period.append(periods_from_to[i])
                break

    #def period(time):
    while start < end:
        start1 = start
        start = start + timedelta(minutes=timestep)
        periods.append(start1.strftime('%H:%M:%S'))
        periods_from_to.append(start1.strftime('%H:%M:%S')+' to '+start.strftime('%H:%M:%S'))

    periods.append('23:59:59')

    for timestamp in my_df_ex1['Time']:
        check_user(timestamp)

    #ta 3 pou vgainoun ap e3w einai komple
    my_df_ex1['Period'] = each_period
#    trelakiko = trelakiko.copy()
    each_period = list(zip(my_df_ex1.Date, my_df_ex1.Period))
    my_df_ex1['Period'] = each_period
    my_df_ex1.set_index('Period', inplace = True)

#Μεχρι αυτο το σημειο απλα εφτιαξα τα time periods και τιποτα περισσοτερο. Απο δω και περα γινεται
#η αντιστοιχιση καλλιτερχνων-περιοδων-μετρικων κοκ.

#(1) φτιαχνω λιστα με τα stages και βρισκω σε ποια χρονικη περιοδο ξεκιναει ο καθε καλλιτεχνης. Οποτε εχω ενα dict στο οποιο σαν
#    keys ειναι τα stages και μεσα περιεχονται ολα τα periods και τα periods που ΞΕΚΙΝΑΕΙ ο καθε καλλιτεχνης.

    b = list(my_df_ex1.groupby('Buhne').groups.keys())

    stages = {}

    for letters in b:
        stages.update({letters: my_df_ex1[my_df_ex1['Buhne'] == letters]})

    a = my_df_ex1.groupby(['Date']).size().index.tolist()
#    a.extend(('2018-07-20', '2018-07-21', '2018-07-22'))
    import itertools
    periods_from_to = list((itertools.product(a, periods_from_to)))

    def assign_to_per(art_clust):
        trelakiko = pd.DataFrame(index = periods_from_to, columns = ['Artist_1'])
        for periods in periods_from_to:
            try:
                trelakiko.at[[periods], 'Artist_1'] = art_clust.loc[[periods]]['Artist'][0]
#            except AttributeError:
#                trelakiko.set_value([periods], 'Artist_1', art_clust.loc[[periods]]['Artist'][0])
            except KeyError:
                pass
        return trelakiko

    trelakiko = {}

    for letters in b:
        trelakiko.update({letters: assign_to_per(stages[letters])})

#(2) Εδω φιλαρω τη λιστα με τη συνολικη διαρκεια που παιζει ο καθε καλλιτεχνης. Συγκεκριμενα θελουμε σε καθε
#    περιπτωση να υπαρχει ενα time period κενο μεταξυ 2 διαφορετικων καλλιτεχνω στο ιδιο stage. Επισης ολα τα live
#    τελειωνουν στις 12 το βραδυ (00:00:00).
    if only_start == 'No':
        def copy_artists_periods(buhne):
            for artists in buhne['Artist_1'][buhne['Artist_1'].isnull() == False]:
                ind = buhne.index
                i = ind.get_loc(buhne.index[buhne['Artist_1'] == artists].get_values()[0])
                k = '00:00:00' in buhne.iloc[i].name
                l = 0
                while (i < len(buhne)-2 and (buhne.iloc[i+1].isnull()[0]) == True and k == False and l<105//timestep):
                    buhne.iloc[i+1]['Artist_1'] = buhne.iloc[i]['Artist_1']
                    i += 1
                    l += 1
                    k = '23:30:00' in buhne.iloc[i].name[1]
            return buhne

        final_list = {}
        for letters in b:
            final_list.update({letters: copy_artists_periods(trelakiko[letters])})
    else:
        final_list = trelakiko
#(3) Εδω με εναν αξιοσημειωτο τροπο βγαλμενο απο ταινια αντιστοιχιζω τα stages με τα clusters στα οποια βρισκονται.
#    Για καποιο λογο δεν μπορουσα να σκεφτω πιο απλο τροπο να κανω το mapping.

    artists = pd.DataFrame(index = periods_from_to, columns = b)
    for keys in final_list:
        artists[keys] = final_list[keys].values

    clusters = {}

    for letters in b:
        clusters.update({letters: my_df_ex1['Cluster'][my_df_ex1['Buhne'] == letters].unique()[0]})

#(4) Εδω γινεται το rename των στηλων συμφωνα με το mapping που εφτιαξα παραπανω
    artists = artists.rename(columns=clusters)

#(5) Προσθετω στις μετρικες το τι γινεται στην περιπτωση του NaN, δηλαδη σε τι αντιστοιχιζεται η κατασταση NaN.
    metrics = metrics.append(pd.DataFrame([[np.NaN, -5, 'NO_SHOW']], columns = ['artist', 'metr', 'rep']))

#(6) Βαζω σαν index τους artists ετσι ωστε να μπορω να κανω το mapping.
    metrics.set_index('artist', inplace=True)

#(7) Κανω την αντιστοιχιση artists ---> metrics
    artists = artists.applymap(lambda x: metrics.loc[x]['metr'])

#(7) Κάνω combine ολες τις στηλες που εχουν το ιδιο ονομα και τις βαζω σε εναν scaler έτσι ώστε να εχω σαν 0 τις
#    περιοδους που δεν υπάρχει live και να μπορω να προσθεσω τις μετρικές των live για τις ιδιες περιοδους στο ιδιο κλαστερ.
#    Τωρα ολες οι τιμες ειναι θετικες οποτε μπορουν να προστεθουν. Πλεον οταν σ ενα κλαστερ υπαρχει ΕΝΑ live σε μια χρονικη
#    περιοδο (ενω σε αλλες υπαρχουν 2 πχ) θα προστεθει η μετρικη του καλλιτεχνη με το 0 (δλδ οχι 2ρο live) οποτε και θα
#    παρουμε σα συνολικο αποτελεσμα την μετρικη του ενος καλλιτεχνη.
#
#    ΕΤΣΙ ΒΕΒΑΙΑ ΜΠΟΥΣΤΑΡΟΝΤΑΙ ΚΑΤΑ ΠΟΛΥ ΟΙ ΜΕΤΡΙΚΕΣ ΣΕ ΜΙΑ ΠΕΡΙΟΔΟ ΠΟΥ ΠΑΙΖΟΥΝ 2 ΚΑΛΛΙΤΕΧΝΕΣ ΤΑΥΤΟΧΡΟΝΑ ΣΤΟ ΙΔΙΟ ΚΛΑΣΤΕΡ!!!!

    from sklearn.preprocessing import MinMaxScaler
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaler.fit(artists.values)

    artists[list(artists.columns.unique())] = scaler.fit_transform(artists[list(artists.columns.unique())])
    artists = artists.groupby(artists.columns, axis=1).max()
    if only_start=='end':
        artists.iloc[:,:] = np.roll(artists.iloc[:,:],-1,0)
    return artists


import argparse

import torch
from diffusers import StableDiffusionPipeline
from PIL import Image
from text_to_image.models import decode_img_latents
from text_to_image.models import get_text_embeddings
from text_to_image.models import produce_latents
from torch.amp.autocast_mode import autocast

def generate(
    args: argparse.Namespace,
) -> Image.Image:
    """Generate image from text prompt.

    Args:
        args (argparse.Namespace): Parsed command line arguments.

    Returns:
        Image.Image - A Pillow Image object.
    """
    if isinstance(args.prompts, str):
        args.prompts = [args.prompts]

    pipe = StableDiffusionPipeline.from_pretrained(
        args.pretrained_image_model, revision='fp16',
        cache_dir=args.cache_dir,
        torch_dtype=torch.float16,
        use_auth_token=True,
    )
    pipe = pipe.to(args.device)

    with autocast(args.device):
        image: Image.Image = pipe(
            args.prompts,
            num_inference_steps=args.steps,
        )['sample'][0]

    return image

def generate_images(
    args: argparse.Namespace,
) -> list[Image.Image]:
    """Generate image(s) from text prompt(s).

    Args:
        args (argparse.Namespace): Parsed command line arguments.

    Returns:
        list[Image.Image]: Image or list of generated PIL images.
    """
    kwargs = vars(args)

    # Prompts -> text embeddings.
    text_embeddings = get_text_embeddings(args.prompts, **kwargs)

    # Text embeddings -> image latents.
    latents = produce_latents(
        text_embeddings,
        num_inference_steps=args.steps,
        **kwargs,
    )

    # Image latents -> Images.
    imgs = decode_img_latents(latents, **kwargs)

    return imgs


import tarfile
import tempfile
import json
import shutil
import numpy as np
import torch
import torch.nn as nn

from ..utils import binary_to_array

class BaseNet(nn.Module):

    def __init__(self):
        super(BaseNet, self).__init__()

    @property
    def device(self):
        try:
            out = next(self.parameters()).device
            return (out if isinstance(out, torch.device)
                    else torch.device('cpu'))
        except Exception:
            return torch.device('cpu')

    def predict(self, x):
        localizations, classifications, localizations_default = self.forward(x)
        localizations_default = localizations_default.to(self.device)
        return self.detector(localizations, classifications, localizations_default)

    def save(self, filename, net_parameters):
        with tarfile.open(filename, "w") as tar:
            temporary_directory = tempfile.mkdtemp()
            name = "{}/net_params.json".format(temporary_directory)
            json.dump(net_parameters, open(name, "w"))
            tar.add(name, arcname="net_params.json")
            name = "{}/state.torch".format(temporary_directory)
            torch.save(self.state_dict(), name)
            tar.add(name, arcname="state.torch")
            shutil.rmtree(temporary_directory)
        return filename

    @classmethod
    def load(cls, filename, use_device=torch.device('cpu')):
        with tarfile.open(filename, "r") as tar:
            net_parameters = json.loads(
                tar.extractfile("net_params.json").read().decode("utf-8"))
            path = tempfile.mkdtemp()
            tar.extract("state.torch", path=path)
            net = cls(**net_parameters)
            net.load_state_dict(
                torch.load(
                    path + "/state.torch",
                    map_location=use_device,
                )
            )
        return net, net_parameters

    def predict_dataset(self,
                        inference_dataset,
                        threshold,
                        overlap_factor=0.5,
                        batch_size=128,
                        ):
        """
        Predicts events in inference_dataset.
        """

        # Set network to eval mode
        self.eval()

        # Set network prediction parameters
        self.detector.classification_threshold = threshold
        window_size = inference_dataset.window_size
        window = inference_dataset.window
        overlap = window * overlap_factor

        # List of dicts, to save predictions of each class per record
        predictions = {}
        for record in inference_dataset.records:
            predictions[record] = []
            result = np.zeros((self.number_of_classes - 1,
                               inference_dataset.signals[record]["size"]))
            for signals, times in inference_dataset.get_record_batch(
                    record,
                    batch_size=int(batch_size),
                    stride=overlap):
                x = signals.to(self.device)
                batch_predictions = self.predict(x)

                for events, time in zip(batch_predictions, times):
                    for event in events:
                        start = int(round(event[0] * window_size + time[0]))
                        stop = int(round(event[1] * window_size + time[0]))
                        result[event[2], start:stop] = 1

            predicted_events = [binary_to_array(k) for k in result]
            assert len(predicted_events) == self.number_of_classes - 1
            for event_num in range(self.number_of_classes - 1):
                predictions[record].append(predicted_events[event_num])

        return predictions

    @property
    def nelement(self):
        cpt = 0
        for p in self.parameters():
            cpt += p.nelement()
        return cpt

def get_overlerapping_default_events(window_size, default_event_sizes, factor_overlap=2):
    window_size = window_size
    default_event_sizes = default_event_sizes
    factor_overlap = factor_overlap
    default_events = []
    for default_event_size in default_event_sizes:
        overlap = default_event_size / factor_overlap
        number_of_default_events = int(window_size / overlap)
        default_events.extend(
            [(overlap * (0.5 + i) / window_size, default_event_size / window_size)
             for i in range(number_of_default_events)]
        )
    return torch.Tensor(default_events)