#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/9/19 下午6:34
# @Author  : Lynn
# @Site    :
# @File    : analysis.py
# @Software: PyCharm
import numpy as np
import imutils
import cv2
from PIL import Image
import time
import math
import pattern
from tools import *

############################################################################################
# 轮廓上的所有点
cnt_point = []
# 图形的顶点
vertex = []

no_shape = {
    '0': [],
    '1': [],
    '2': [],
    '3': [],
    '4': [],
    '5': [],
    '6': []
}

############################################################################################
# 初始化 vertex, cnt_point
def initial_cntpoint_and_vertex():
    for i in range(0, 7):
        cnt_point.append([])
        # vertex对每个图形存储对应顶点编号，如vertex[0][0]=(x,y)
        # vertex[0]第0个图形，vertex[0][0]第0个图形的第0个顶点
        vertex.append([])

############################################################################################
#形状分析
class Analysis:
    def __init__(self):
        self.shapes = {'triangle': 0, 'square': 0, 'polygons': 0, 'circles': 0,'parallelogram':0}
    def draw_text_info(self, image):
        c1 = self.shapes['triangle']
        c2 = self.shapes['square']
        c3 = self.shapes['polygons']
        c4 = self.shapes['circles']
        c5=self.shapes['parallelogram']
        cv2.putText(image, "triangle: "+str(c1), (10, 20), cv2.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
        cv2.putText(image, "square: " + str(c2), (10, 40), cv2.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
        cv2.putText(image, "parallelogram: " + str(c5), (10, 60), cv2.FONT_HERSHEY_PLAIN, 1.2, (255, 0, 0), 1)
        return  image
    # load the image, convert it to grayscale, blur it slightly,
    # and threshold it
    def analy(self, image):
        k=0
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        dict = getColorList()
        num = 0
        for d in dict:
            if d != 'gray' and d != 'white' and d != 'black':
                num += 1
                if num == 1:
                    thresh = cv2.inRange(hsv, dict[d][0], dict[d][1])
                if len(dict[d])==4:
                    mask1=cv2.inRange(hsv, dict[d][0], dict[d][1])
                    mask2=cv2.inRange(hsv, dict[d][2], dict[d][3])
                    mask = cv2.addWeighted(mask1, 1, mask2, 1, 0)
                else:
                    mask = cv2.inRange(hsv, dict[d][0], dict[d][1])
                #cv2.imshow(d,mask)
                #cv2.waitKey(0)
                thresh = cv2.addWeighted(thresh, 1, mask, 1, 0)
        #
        cv2.imshow('thresh inital', thresh)
        blurred = cv2.GaussianBlur(thresh, (5, 5), 0)
        #show the GaussianBlur picture
        cv2.imshow('GaussianBlur', blurred)
        ret, thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)
        #test for threshold
        cv2.imshow('threshold', thresh)
        cv2.waitKey(0)
        #生成kernel:
        # array([[1, 1, 1, 1, 1],
        #        [1, 1, 1, 1, 1],
        #        [1, 1, 1, 1, 1],
        #        [1, 1, 1, 1, 1],
        #        [1, 1, 1, 1, 1]], dtype=uint8)
        # kernel = np.ones(5,5)
        kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
        #进行闭运算，形成封闭图形
        closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
        #腐蚀图像
        closed = cv2.erode(closed, None, iterations=4)
        #膨胀图像
        thresh = cv2.dilate(closed, None, iterations=4)
        # findContours：基于二值图像寻找物体的轮廓
        #       image:      二值图像
        #       mode:       定义轮廓检索模式
        #       method:     定义轮廓近似方法
        #       return:     contours：hierarchy
        cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                                cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if imutils.is_cv2() else cnts[1]
        #print(len(cnts))
        # loop over the contours
        for c in cnts:
            #print(c)
            # 轮廓逼近
            epsilon = 0.05 * cv2.arcLength(c, True) # 计算轮廓周长
            approx = cv2.approxPolyDP(c, epsilon, True)
            # 分析几何形状
            corners = len(approx)
            shape_type = ""
            # 图形顶点
            for i in range(0, len(approx)):
                p = Point()
                p.x = approx[i][0][0]
                p.y = approx[i][0][1]
                vertex[k].append(p)
                cv2.circle(image, (approx[i][0][0], approx[i][0][1]), 2, (255, 0, 0), 2)
            if corners == 3:
                count = self.shapes['triangle']
                count = count + 1
                self.shapes['triangle'] = count
                shape_type = "triangle"
                # 编号
                # ul为三角形的直角顶点
                u1 = max_distance(vertex[k][0], vertex[k][1], vertex[k][2])
                # 前两个存斜边顶点，第三个存直角顶点,直角点存y小的
                if u1 != vertex[k][2]:
                    if vertex[k][0] == u1:
                        vertex[k][0] = vertex[k][2]
                    else:
                        vertex[k][1] = vertex[k][2]
                    vertex[k][2] = u1
                if (vertex[k][0].y > vertex[k][1].y):
                    t = vertex[k][1]
                    vertex[k][1] = vertex[k][0]
                    vertex[k][0] = t
            if corners == 4:
                # 用红色表示有旋转角度的矩形框架
                rect = cv2.minAreaRect(approx)
                w=rect[1][0]
                h=rect[1][1]
                ar=w/float(h)
                print(ar)
                box = cv2.boxPoints(rect)
                box = np.int0(box)
                cv2.drawContours(image, [box], 0, (0, 0, 255), 2)
                if ar>=0.70 and ar<=2.00:
                    count = self.shapes['square']
                    count = count + 1
                    self.shapes['square'] = count
                    shape_type = "square"
                    # 正方形编号
                    min = Xmin(vertex[k])
                else:
                    count=self.shapes['parallelogram']
                    count=count+1
                    self.shapes['parallelogram']=count
                    shape_type="parallelogram"
                    """
                    for i in range(0,4):
                        print(str(vertex[k][i].x) + "," + str(vertex[k][i].y))
                        print(str(box[i][0]) + "," + str(box[i][1]))
                        """
                    # 对平行四边形进行编号（与box重合的点为0）
                    break_flag = False
                    while break_flag == False:
                        for i in range(0, 4):
                            while break_flag == False:
                                for j in range(0, 4):
                                    if abs(vertex[k][i].x - box[j][0]) <= 10 and abs(
                                            vertex[k][i].y - box[j][1]) <= 10:
                                        min = i
                                        #print(min)
                                        break_flag = True
                if min != 0:
                    Reverse(vertex[k], min, 3)
                    Reverse(vertex[k], 0, min - 1)
                    Reverse(vertex[k], 0, 3)
            if corners >= 10:
                count = self.shapes['circles']
                count = count + 1
                self.shapes['circles'] = count
                shape_type = "circles"
            if 4 < corners < 10:
                count = self.shapes['polygons']
                count = count + 1
                self.shapes['polygons'] = count
                shape_type = "polygons"
            M = cv2.moments(c)
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
            im = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
            #根据螺丝的半径，圆心重新确定识别的点（cx-R,cy-R)
            color=Color(cX-5,cY-5,im)
            #color=Color(vertex[k][0].x,vertex[k][0].y,im)
            # draw the contour and center of the shape on the image
            cv2.drawContours(image, [c], -1, (0, 255, 0), 1)
            cv2.putText(image, str(color)+" "+shape_type, (cX - 20, cY - 20),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
            cv2.circle(image, (cX,cY), 2, (255, 0, 0), 2)
            no_shape[str(k)].append(shape_type)
            no_shape[str(k)].append(color)
            no_shape[str(k)].append((cX, cY))
            for i in range(0,len(vertex[k])):
                cv2.putText(image,str(i),(vertex[k][i].x,vertex[k][i].y),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
            k+=1
        cv2.imshow("Analysis Result", self.draw_text_info(image))
        cv2.imwrite("image/pattern.jpg",image)
        cv2.waitKey(0)


from flask import render_template, flash, redirect, url_for
from app import app
from app.forms import LoginForm

@app.route('/')
@app.route('/index')
def index():
    user = {'username': 'javi'}
    posts = [
        {
            'author': {'username': 'javi'},
            'body': 'Open source is the future!'
        },
        {
            'author': {'username': 'ana'},
            'body': 'AstroBot is awesome!'
        }
    ]
    return render_template('index.html', title='Home', user=user, posts=posts)

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    # will return true when user clicks on submit and all fields are validated ok
    if form.validate_on_submit():
        flash(f'Login requested for user {form.username.data}, remember_me={form.remember_me.data}')
        # name of the view function
        return redirect(url_for('index'))
    return render_template('login.html', title="Sign In", form=form)


from flask import Flask,render_template,url_for,request
app = Flask(__name__)

@app.route('/Login',methods=['GET','POST'])
def hello():
    type_of_request = request.method
    return render_template('Hello.html', request_method = type_of_request)

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

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


from prettytable import PrettyTable, DOUBLE_BORDER
from util import clear

from data import words
from art import logo
import random

CORRECT_WORD = random.choice(words).upper()
print("Clue: " + CORRECT_WORD)

table = PrettyTable()
table.set_style(DOUBLE_BORDER)
TABLE_HEADER = ["⚔", "W", "Ö", "R", "D", "L", "E"]

table.field_names = TABLE_HEADER
clear()
print(logo)
print("Clue: " + CORRECT_WORD)
print(table)

MAX_ATTEMPTS = 6
WORD_LENGTH = 6
attempt = 1

def is_valid_word(word, length):
    return len(word) == length and word.isalpha()

def user_guess():
    while True:
        guess = input("Enter a word: ").strip().upper()
        if is_valid_word(guess, WORD_LENGTH):
            return guess
        else:
            print(f"Invalid word! Make sure the word is {WORD_LENGTH} letters long")

def format(word, CORRECT_WORD, attempt):
    formatted_answer = []
    attempt_number = [f"{attempt}."]
    formatted_answer.extend(attempt_number)

    word_list = [char for char in word]

    for char in range(len(word_list)):
        if word_list[char] == CORRECT_WORD[char]:
            word_list[char] = f"[{word_list[char]}]"
        elif word_list[char] in CORRECT_WORD:
            word_list[char] = f"({word_list[char]})"

    formatted_answer.extend(word_list)

    return formatted_answer

def update_table(formatted_answer):
    table.add_row(formatted_answer)

def update_board():
    clear()
    print(logo)
    print(table)

while attempt <= MAX_ATTEMPTS:
    answer = user_guess()
    formatted_answer = format(answer, CORRECT_WORD, attempt)
    update_table(formatted_answer)
    update_board()

    if answer != CORRECT_WORD and attempt == MAX_ATTEMPTS:
        print(f"You lost! The correct word was: {CORRECT_WORD}")
        break
    elif answer == CORRECT_WORD:
        print("You won")
        break
    else:
        print("Wrong. Try again.")

    attempt += 1

# x Randomly select a 6 letter word, this is the correct word
# x Attempts = 6
#   (Nice to have: Choose attempts)

# x Ask for word from user
# x Word should only contains letters, exactly 'len' letters in length
# x if word break rules, ask for new word

# Print playboard


import os
import os.path
import shutil
import sys
import tempfile
from pathlib import Path, PureWindowsPath

import click
from loguru import logger

from livemaker import LMArchive, LMCompressType
from livemaker.exceptions import LiveMakerException

from .cli import __version__, _version

@click.command()
@click.version_option(version=__version__, message=_version)
@click.argument("archive_file", required=True, type=click.Path(exists=True, dir_okay=False))
@click.argument("patched_lsb", required=True, type=click.Path(exists=True, dir_okay=True))
@click.option("--split", is_flag=True, default=False, help="Generate a split data archive.")
@click.option("--no-backup", is_flag=True, default=False, help="Do not generate backup of original archive file(s).")
@click.option(
    "-f", "--force", is_flag=True, default=False, help="Overwrite any existing files instead of erroring out."
)
@click.option("-r", "--recursive", is_flag=True, default=False, help="Patch multiple files into the archive.")
def lmpatch(archive_file, patched_lsb, split, no_backup, force, recursive):
    """Patch a LiveMaker game.

    If patched_lsb is a file, any existing version of patched_lsb will be replaced in the specified
    LiveMaker archive. If a file with the same name as patched_lsb does
    not already exist, this will do nothing.

    If patched_lsb is a directory, every file existing in this directory and in the old archive will
    be replaced in the specified LiveMaker archive.
    The -r/--recursive option is required for directory mode.

    If file extension for archive_file is ".ext", or if archive_file is not
    an excutable and the --split option is specified,
    a split archive will be generated.

    A backup copy of the old archive file(s) will also be created unless the
    --no-backup option is specified.

    """
    logger.add("patch.log", level="INFO", encoding="utf-8")

    archive_path = Path(archive_file).resolve()
    archive_dir = archive_path.parent
    archive_name = archive_path.name

    try:
        orig_lm = LMArchive(archive_path)
    except LiveMakerException as e:
        logger.error(e)
        return

    if orig_lm.is_exe:
        fd, tmp_exe = tempfile.mkstemp()
        fp = os.fdopen(fd, "wb")
        fp.write(orig_lm.read_exe())
        fp.close()
    else:
        if orig_lm.is_split:
            split = True
        tmp_exe = None

    if not no_backup:
        backup_paths = {archive_path: Path(f"{archive_path}.bak")}
        if orig_lm.is_split:
            for p in orig_lm._split_files:
                backup_paths[Path(p)] = Path(f"{p}.bak")
        for p in backup_paths.values():
            if p.exists():
                if force:
                    print(f"{p} will be overwritten")
                else:
                    sys.exit(f"{p} already exists")

    if Path(patched_lsb).is_dir():
        if not recursive:
            sys.exit(f"Cannot patch directory ({patched_lsb}) without -r/--recursive mode")
    else:
        if recursive:
            sys.exit(f"Cannot patch file ({patched_lsb}) within -r/--recursive mode")

    try:
        tmpdir = tempfile.mkdtemp()
        tmpdir_path = Path(tmpdir)
        logger.info(f"Using temp directory {tmpdir_path}")
        print("Generating new archive contents...")
        with LMArchive(
            name=tmpdir_path.joinpath(archive_name), mode="w", version=orig_lm.version, exe=tmp_exe, split=split
        ) as new_lm:

            def bar_show(item):
                width, _ = shutil.get_terminal_size()
                width //= 4
                name = item.name if item is not None else ""
                if len(name) > width:
                    name = "".join(["...", name[-width:]])
                return name

            # patch
            with click.progressbar(orig_lm.infolist(), item_show_func=bar_show) as bar:
                for info in bar:
                    # replace existing with patch version
                    #
                    # TODO: support writing encrypted files
                    if info.compress_type == LMCompressType.ENCRYPTED:
                        compress_type = LMCompressType.NONE
                    elif info.compress_type == LMCompressType.ENCRYPTED_ZLIB:
                        compress_type = LMCompressType.ZLIB
                    else:
                        compress_type = info.compress_type

                    if recursive:
                        lsb_path = Path(patched_lsb).joinpath(info.path)
                        if not lsb_path.exists():
                            lsb_path = None
                    else:
                        lsb_path = Path(patched_lsb)
                        if info.path != PureWindowsPath(lsb_path):
                            lsb_path = None

                    if lsb_path:
                        new_lm.write(lsb_path, compress_type=compress_type, unk1=info.unk1, arcname=info.path)
                        logger.info(f"patched {info.path}")
                    else:
                        # copy original version
                        data = orig_lm.read(info, decompress=False)
                        new_lm.writebytes(info, data)
                        logger.info(f"copied {info.path}")

        orig_lm.close()

        # copy temp dir contents to output path then remove the temp dir
        # this operation needs to be a copy instead of rename (move)
        # in case windows system temp directory is on a different
        # logical drive than the output path
        print("Writing new archive files...")
        for root, dirs, files in os.walk(tmpdir_path):
            for name in files:
                tmp_p = Path(root).joinpath(name)
                orig_p = archive_dir.joinpath(name)
                if orig_p.exists() and not no_backup:
                    orig_p.rename(backup_paths[orig_p])
                shutil.copy(tmp_p, archive_dir)
    except Exception as e:
        logger.error(e)

        raise e
    finally:
        if tmp_exe is not None:
            Path(tmp_exe).unlink()

        print("Cleaning up temporary files...")
        if tmpdir_path:
            for root, dirs, files in os.walk(tmpdir_path):
                for name in files:
                    p = Path(root).joinpath(name)
                    p.unlink()
            tmpdir_path.rmdir()

if __name__ == "__main__":
    lmpatch()


import torch
from torch import nn

from models.modules import MLP, TransformerEncoder
from models.OrVNet_FFiNet import OrVNetModel

from .FFiNet_model import FFiLayer
from .modules import MLP, BoltzmannLayer, ReadoutPhase

class Interaction(nn.Module):
    def __init__(self, in_dim, dim, heads, dropout, num_layers):
        super().__init__()
        self.dim = dim
        self.in_dim = in_dim
        self.num_layers = num_layers
        self.repr_token = nn.Parameter(torch.FloatTensor(1, in_dim))
        self.encoders = nn.ModuleList([TransformerEncoder(in_dim, dim, heads, dropout) if i == 0 else TransformerEncoder(dim, dim, heads, dropout) for i in range(num_layers)])

    def forward(self, x1, x2):
        in_set = torch.stack([self.repr_token.expand(x1.size(0), self.in_dim), x1, x2], dim=1)
        for i, encoder in enumerate(self.encoders):
            if i == 0:
                output = encoder(in_set)
            else:
                output = encoder(output)
        return output[:, 0, :]

class OrVMixNetModel(nn.Module):
    def __init__(self, config):
        super().__init__()

        self.input_dim = config.model.input_dim
        self.hidden_dim = config.model.hidden_dim
        self.num_layers = config.model.num_layers
        self.num_heads = config.model.num_heads
        self.dropout = config.model.dropout
        self.num_energies = config.model.num_energies
        self.return_repr = config.model.return_repr
        self.pretrained_path = config.train.pretrained_path

        self.message_passing = nn.ModuleList()
        for i in range(self.num_layers):
            self.message_passing.append(
                FFiLayer(
                    self.input_dim if i == 0 else self.hidden_dim,
                    self.hidden_dim // self.num_heads,
                    self.num_heads,
                    dropout=self.dropout
                ))

        self.readout = ReadoutPhase(self.hidden_dim)

        self.pred_boltzmann = BoltzmannLayer(self.hidden_dim*2+2, self.num_energies)
        self.pred_surmount_prob = nn.Sigmoid()
        self.pred_extra = MLP(self.num_energies, 128, 1, 2, 0.1, nn.ELU())

        self.inter_module = Interaction(2*self.hidden_dim, 128, 8, 0.1, 3)

        # pretrain
        if self.pretrained_path != 'None':
            self.mol_repr_model = OrVNetModel(config)
            self.mol_repr_model.eval()
            print(self.mol_repr_model.load_state_dict(torch.load(config.train.pretrained_path)))
            for name, param in self.mol_repr_model.named_parameters():
                param.requires_grad = False

    def forward_pure(self, data):
        if self.pretrained_path != 'None':
            _, mol_repr, ln_visc = self.mol_repr_model(data)
        else:
            x, edge_index = data.x, data.edge_index
            triple_index, quadra_index, pos, edge_attr= data.triple_index, data.quadra_index, data.pos, data.edge_attr
            for layer in self.message_passing:
                x = layer((x, edge_index, triple_index, quadra_index, pos, edge_attr))

            mol_repr = self.readout(x, data.batch)

        return mol_repr

    def forward(self, data1, data2):
        mol_repr1 = self.forward_pure(data1)
        mol_repr2 = self.forward_pure(data2)

        x = data1.molar_ratio.reshape(-1, 1).float()

        inter_repr = self.inter_module(mol_repr1, mol_repr2)
        inter_repr = torch.cat([inter_repr, x, 1-x], dim=1)
        energy_distribution = self.pred_boltzmann(inter_repr, data1.temps)
        delta_visc = self.pred_extra(energy_distribution).squeeze(-1)

        return delta_visc


import os
import re

import click as click
import requests

from bs4 import BeautifulSoup
from tqdm import tqdm

class IsoStandards:
    def __init__(self):
        self.BASE_URL = 'https://standards.iso.org'
        self.PATH = '../downloads/'

        self.s = requests.session()
        # jesus christ
        self.pattern = re.compile(r'(iso)[^/]*/(\d+)/(-\d+)/([^/]+)')

    def check_url(self, iso_url: str) -> bool:
        if not iso_url.startswith(self.BASE_URL):
            return False

        return True

    def raw_get_html(self, link: str) -> None or bytes:
        try:
            r = self.s.get(link, stream=True)

            if r.status_code == 200 and r.headers['Content-Type'].lower() is not None:
                return r.content

            return None

        except requests.RequestException as e:
            print('Error during requests to {0} : {1}'.format(link, str(e)))
            return None

    def download_file(self, file_url: str, base_url: str, show_progress: bool = False):
        """
        Downloads a single file to self.PATH using requests and tqdm
        :param file_url: The file_url which gets downloaded
        :param base_url: The base_url of the downloaded folder, so it will calulate the relative path from both
        :param show_progress: True for enabling a progress bar with tqdm
        :return:
        """
        # remove the base_url from the file_url to get the actual relative path
        file_path = os.path.join(self.PATH, file_url.replace(base_url, ''))
        if os.path.exists(file_path):
            print(f'Already downloaded {file_path}')
            return

        # extract the folder_path from the file_path and create those folders
        folder_path = os.path.dirname(file_path)
        os.makedirs(folder_path, exist_ok=True)

        print(f'Downloading {file_path}')
        # stream the file with error handling
        try:
            r = self.s.get(file_url, stream=True)
            if r.status_code != 200 or r.headers['Content-Type'].lower() is None:
                return

        except requests.RequestException as e:
            print('Error during requests to {0} : {1}'.format(file_url, str(e)))
            return None

        try:
            total = int(r.headers['content-length'])
        except KeyError:
            return

        with open(file_path, 'wb') as f:
            # just use the tdqm progress bar
            if show_progress:
                with tqdm(total=total, unit='B', unit_scale=True, unit_divisor=1024, miniters=1) as bar:
                    for chunk in r.iter_content(chunk_size=1024):
                        # filter out keep-alive new chunks
                        if chunk:
                            f.write(chunk)
                            bar.update(len(chunk))
            else:
                for chunk in r.iter_content(chunk_size=1024):
                    # filter out keep-alive new chunks
                    if chunk:
                        f.write(chunk)

    def load_folder(self, folder_url: str, base_url: str):
        """
        Recursive function which will load all folders from a parent folder

        :param folder_url: The actual URL of the folder
        :param base_url: The base URL of the main folder
        :return:
        """
        raw_html = self.raw_get_html(folder_url)
        soup = BeautifulSoup(raw_html, 'html.parser')

        # get the table and all table rows
        table = soup.find('tbody')
        table_rows = table.find_all('tr')

        # iterate over all table rows (files and folders)
        for row in table_rows:
            # get the data_type which is either fa-file or fa-folder
            data_type = row.find('td').get('data-sort')
            # save the relative path
            children_url = row.find('a').get('href')
            # convert it to an absolute path
            actual_url = self.BASE_URL + children_url

            if 'folder' in data_type:
                # recursively open the new-found folder
                self.load_folder(actual_url, base_url)
            elif 'file' in data_type:
                # download the file if it's not a folder
                self.download_file(actual_url, base_url)
            else:
                print('Unknown file type, skipping')

    def main(self, iso_url: str):
        if not self.check_url(iso_url):
            print(f'Enter a valid ISO Standards URL starting with: {self.BASE_URL}')
            exit()

        # remove the base url and perform an iso standard beautifier
        iso_name = iso_url.replace(self.BASE_URL, "")[1:]
        try:
            iso_name = ' '.join(x for x in re.findall(self.pattern, iso_name)[0]).upper()
        except IndexError:
            print('Could not beautify the URL, continuing anyway')

        # save the new path in self.PATH
        self.PATH = os.path.join(self.PATH, iso_name)

        print(f'Found ISO Standard: {iso_name}')
        self.load_folder(iso_url, base_url=iso_url)
        print('Download finished!')

@click.command(
    name='ISO-Standards-Downloader',
    short_help='A python module to download ISO Standards from https://standards.iso.org/iso-iec',
    context_settings=dict(
        help_option_names=['-?', '-h', '--help']
    ))
@click.argument(
    'iso_url',
    type=str
)
def run(iso_url: str):
    """
    ISO_URL: Enter the URL from the ISO Standard you want to download: https://standards.iso.org/iso-iec

    \f
    :param iso_url: URL from https://standards.iso.org/iso-iec
    :return: Nothing
    """
    try:
        iso_standards = IsoStandards()
        iso_standards.main(iso_url)
    except KeyboardInterrupt:
        print('\n\t^C pressed - abort')
        exit()

if __name__ == '__main__':
    run()


from heapq import nlargest

from rich import print

def get_puzzle_input():
    puzzle_input = []
    with open("input.txt") as input_txt:
        for line in input_txt:
            puzzle_input.append([int(c) for c in line.strip()])
    return puzzle_input

def solve_part_1(heightmap):
    #print(heightmap)
    risk_level = 0
    for i in range(len(heightmap)):
        row = heightmap[i]
        for j in range(len(heightmap[0])):
            height = heightmap[i][j]
            if i > 0 and heightmap[i-1][j] <= height:
                continue
            if i < len(heightmap)-1 and heightmap[i+1][j] <= height:
                continue
            if j > 0 and heightmap[i][j-1] <= height:
                continue
            if j < len(row)-1 and row[j+1] <= height:
                continue

            #print(i,j,height)
            risk_level += height + 1

    return risk_level

def solve_part_2(heightmap):
    basin_sizes = []
    basin_membership = set()
    for i in range(len(heightmap)):
        for j in range(len(heightmap[0])):
            #print("-", i,j)
            candidates = [(i,j)]
            basin_size = 0
            while len(candidates) > 0:
                candidate = candidates.pop()
                ci, cj = candidate
                #print(candidate)
                if ci < 0 or ci >= len(heightmap):
                    #print("ibounds")
                    continue
                if cj < 0 or cj >= len(heightmap[0]):
                    #print("jbounds")
                    continue
                if heightmap[ci][cj] >= 9:
                    #print("height")
                    continue
                if candidate in basin_membership:
                    #print("spoken for")
                    continue

                #print("check")
                basin_size += 1
                basin_membership.add(candidate)
                candidates.append((ci+1,cj))
                candidates.append((ci-1,cj))
                candidates.append((ci,cj+1))
                candidates.append((ci,cj-1))

            if basin_size > 0:
                basin_sizes.append(basin_size)

    #print(basin_sizes)
    largest = list(nlargest(3, basin_sizes))
    #print(largest)

    return largest[0] * largest[1] * largest[2]

if __name__ == "__main__":
    puzzle_input = get_puzzle_input()

    answer_1 = solve_part_1(puzzle_input)
    print(f"Part 1: {answer_1}")

    answer_2 = solve_part_2(puzzle_input)
    print(f"Part 2: {answer_2}")


#-*- coding: UTF-8 -*-
from django.shortcuts import render_to_response,render,get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib import auth
from django.contrib import messages
from django.template.context import RequestContext
from django.contrib.auth.decorators import login_required

from django.forms.formsets import formset_factory
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

from model.models import *

from django.contrib.auth import get_user_model
User = get_user_model()
# Create your views here.
@login_required
def frontend_uav_job_list(request):
    nowuser = request.user
    uav_id = request.GET.get("uav","")
    try:
        if uav_id != "":
            uav = UAV.objects.get(id=uav_id)
            if uav.user_id != nowuser.id:#检查这个编号的无人机是否属于当前用户
                messages.warning(request, '错误，您没有权限')
                return HttpResponseRedirect("/myuav/")#不是则返回
            jobdetail = UAV_Job_Detail.objects.filter(uav_id=uav_id)
            job_list = []
            for i in jobdetail:
                job = Job.objects.get(id = i.job_id)
                if job == 2:
                    continue
                job_list.append(job)
            return render_to_response('frontend_uav_job_list.html',{
                'self':nowuser,
                'uav':uav,
                'job_list':job_list,
                },
                context_instance=RequestContext(request))
    except:
        messages.warning(request, '错误，您没有权限')
    return HttpResponseRedirect("/myuav/")


import pygame
import sys
from all_resources import background, start_menu, victory, score_text, hog_logo, hp, end_menu, dementor, owls, clans, death_eater, again_btn, quit_btn, game_icon
from all_resources import hit_sound, hit_enemy_sound, click, victory_sound, end_menu_sound, shoot_sound
from all_resources import load_font
from helpers.Explosion import Explosion
from helpers.Enemy import Enemy
from helpers.Player import Player
from helpers.Bullet import Bullet
from helpers.Button import Button
from helpers.MaxScoreCounter import MaxScoreCounter
from helpers.MainTheme import MainTheme
from vars import WIDTH, HEIGHT, FPS, MAX_SCORE

# Создаем игру и окно
pygame.init()
pygame.display.set_caption("Порри Гаттер против всех")
pygame.display.set_icon(game_icon)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
max_score_counter = MaxScoreCounter()
main_theme = MainTheme()

def create_dementor():
    dementor_tmp = Enemy([dementor], [6, 8], [-4, 4])
    all_sprites.add(dementor_tmp)
    dementors_group.add(dementor_tmp)

def create_owl():
    owl_tmp = Enemy(owls, [2, 4])
    all_sprites.add(owl_tmp)
    owls_group.add(owl_tmp)

def create_clans():
    clans_tmp = Enemy(clans, [3, 5])
    all_sprites.add(clans_tmp)
    clans_group.add(clans_tmp)

def create_death_eater():
    death_eater_tmp = Enemy([death_eater], [5, 7], [-2, 2])
    all_sprites.add(death_eater_tmp)
    death_eaters_group.add(death_eater_tmp)

def new_enemy():
    create_dementor()
    create_owl()
    create_clans()
    create_death_eater()

# универсальная функция для вывода любого текста на экран
def draw_text(surf, text, size, x, y):
    font = load_font(size)
    text_surface = font.render(text, True, "yellow")
    text_rect = text_surface.get_rect()
    text_rect.midtop = (x, y)
    surf.blit(text_surface, text_rect)

# функция вывода стартового меню
def show_go_screen():
    screen.blit(start_menu, start_menu.get_rect()) # загрузка картинки
    draw_text(screen, f'Лучший счёт: {max_score_counter.getMaxScore()}', 35, 250, HEIGHT / 1.5)
    pygame.display.flip()
    waiting = True
    while waiting:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: # выход из игры
                quit_game()
            if event.type == pygame.KEYDOWN: # если нажалась любая клавиша - игра началась
                click.play()
                waiting = False

# функция выхода из игры
def quit_game():
    global waiting, running

    waiting = False
    running = False
    pygame.quit()
    sys.exit()

# функция вывода меню выигрыша или проигрыша
def show_out_screen(isVictory):
    global score, waiting, max_score_counter

    max_score_counter.updateMaxScore(min(score, MAX_SCORE))
    main_theme.stop()
    hit_sound.stop()
    hit_enemy_sound.stop()
    shoot_sound.stop()

    if isVictory:
        screen.blit(victory, victory.get_rect())
        victory_sound.play()
    else:
        screen.blit(end_menu, end_menu.get_rect())
        draw_text(screen, str(score), 60, WIDTH / 1.45, HEIGHT / 2.3)
        end_menu_sound.play()

    group = pygame.sprite.Group()
    again_btn_obj = Button(again_btn, again_btn.get_rect(center=(WIDTH / 3 - 50, HEIGHT / 1.35)), set_up_playground)
    quit_btn_obj = Button(quit_btn, quit_btn.get_rect(center=(WIDTH / 1.5 + 50, HEIGHT / 1.35)), quit_game)
    group.add(again_btn_obj, quit_btn_obj)

    group.draw(screen)
    pygame.display.flip()
    waiting = True
    while waiting:
        clock.tick(FPS)
        event_list = pygame.event.get()
        for event in event_list:

            if event.type == pygame.QUIT:
                quit_game()

        group.update(event_list)

# функция обработки столкновения игрока с противником
def handle_harry_collision_with_enemy(enemy, damage):
    hits = pygame.sprite.spritecollide(player, enemy, True)
    for hit in hits:
        player.hp -= damage
        hit_sound.play()
        expl = Explosion(hit.rect.center)
        all_sprites.add(expl)

# функция обработки попадания игрока по противнику
def handle_attacks_collision_with_enemy(enemys, score_number, create_enemy_func):
    global score
    hits = pygame.sprite.groupcollide(enemys, bullets, True, True)
    for hit in hits:
        hit_enemy_sound.play()
        expl = Explosion(hit.rect.center)
        all_sprites.add(expl)
        score += score_number
        create_enemy_func()

# функция подготовки игрового поля
def set_up_playground():
    global game_over, running, waiting, all_sprites, bullets, player, death_eaters_group, dementors_group, owls_group, clans_group, score
    game_over = True
    running = True
    waiting = False
    all_sprites = pygame.sprite.Group()
    bullets = pygame.sprite.Group()
    player = Player()
    all_sprites.add(player)
    all_sprites.add(bullets)
    death_eaters_group = pygame.sprite.Group()
    dementors_group = pygame.sprite.Group()
    owls_group = pygame.sprite.Group()
    clans_group = pygame.sprite.Group()
    score = 0
    main_theme.play()

    for i in range(6):
        new_enemy()

set_up_playground()
show_go_screen()
while running:
    # Держим цикл на правильной скорости
    clock.tick(FPS)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                bullet = Bullet(player.rect.right, player.rect.centery)
                all_sprites.add(bullet)
                bullets.add(bullet)
                shoot_sound.play()

    # Обновление
    all_sprites.update()

    # Столкновения персонажа с противниками
    handle_harry_collision_with_enemy(dementors_group, 20)
    handle_harry_collision_with_enemy(owls_group, 10)
    handle_harry_collision_with_enemy(clans_group, 10)
    handle_harry_collision_with_enemy(death_eaters_group, 40)

    # Персонаж попал в противника
    handle_attacks_collision_with_enemy(dementors_group, 20, create_dementor)
    handle_attacks_collision_with_enemy(clans_group, 10, create_clans)
    handle_attacks_collision_with_enemy(owls_group, 20, create_owl)
    handle_attacks_collision_with_enemy(death_eaters_group, 30, create_death_eater)

    if score >= MAX_SCORE:
        show_out_screen(True)

    if player.hp <= 0:
        show_out_screen(False)

    # Рендеринг
    screen.blit(background, background.get_rect())
    screen.blit(score_text, score_text.get_rect(center=(WIDTH - 700, 50)))
    screen.blit(hog_logo, hog_logo.get_rect(center=(WIDTH - 825, 50)))
    screen.blit(hp, hp.get_rect(center=(WIDTH - 180, 50)))
    all_sprites.draw(screen)
    draw_text(screen, str(score), 48, WIDTH - 550, 27)
    draw_text(screen, str(player.hp), 48, WIDTH - 80, 27)
    draw_text(screen, f'ЦЕЛЬ:{MAX_SCORE}', 48, 180, HEIGHT - 75)

    pygame.display.flip()

quit_game()


import numpy as np
import scipy
import scipy.optimize

class FourierFit(object):
    def __init__(self, P=2, ndims=2, maxiters=100, tol=1.0E-6):
        super(FourierFit, self).__init__()

        self.P = P
        self.maxiters = maxiters
        self.ndims = ndims
        self.tol = tol
        self.pp = []
        self.t0 = None
        self.w0 = None

    def calc_string(self,w,t,x_meas):
        tlen = len(t)
        t = np.linspace(0.0,1.0,tlen)
        x_est = x_meas[0,:] + (x_meas[-1,:] - x_meas[0,:])*t[:,np.newaxis]
        for i in xrange(self.ndims):
            for j in xrange(self.P):
                x_est[:,i] += w[i,j]*np.sin((j+1)*np.pi*t)
        return x_est

    def _optimize_dist(self,tk,x_meas,w,k):
        x_target = x_meas[k,:]
        x_est = x_meas[0,:] + (x_meas[-1,:] - x_meas[0,:])*tk
        for i in xrange(self.ndims):
            for j in xrange(self.P):
                x_est[i] += w[i,j]*np.sin((j+1)*np.pi*tk)

        err = x_target - x_est
        return err

    def _optimize_w(self,w,x_meas,t,k,weight):
        x_target = x_meas[:,k]
        x_est = x_meas[0,k] + (x_meas[-1,k] - x_meas[0,k])*t

        for j in xrange(self.P):
            x_est += w[j]*np.sin((j+1)*np.pi*t)

        err = weight*(x_target - x_est)
        return err

    def optimize(self,data,weight,w0,t0):
        ncenters = data.shape[0]
        self.w0 = w0
        self.t0 = t0
        if weight is None:
            weight = np.ones_like(t0)

        for iiter in xrange(self.maxiters):
            self.pp.append(self.calc_string(self.w0,self.t0,data))
            if iiter > 0:
                err = np.sum((self.pp[-1] - self.pp[-2])**2)/ncenters
                print('{} -- {}'.format(iiter,err))
                if err < self.tol:
                    break
            else:
                print(iiter)
            # Optimize tk
            for ci in xrange(ncenters):
                self.t0[ci] = scipy.optimize.leastsq(self._optimize_dist, self.t0[ci], args=(data,self.w0,ci))[0]

            # Optimize wij
            for k in xrange(self.ndims):
                self.w0[k,:] = scipy.optimize.leastsq(self._optimize_w,self.w0[k,:],args=(data,self.t0,k,weight))[0]


import matplotlib.pyplot as plt
import numpy as np
import hiprmc
from operator import mul
from skimage.draw import polygon, circle
from PIL import Image

def test_simulated():

    #####################################################
    ########## Begin Test Images ########################
    #####################################################

    N = 50  # size of image (NxN)
    initial_image = np.zeros((N, N))
    iterations = 2000

    # This bit creates a disc to try and model via RMC
    # for i in range(0, N):
    #     for j in range(0, N):
    #         r = np.sqrt((i - int(N / 2)) ** 2 + (j - int(N / 2)) ** 2)
    #         if 10 <= r <= 11:
    #             initial_image[i, j] = 1
    #         else:
    #             initial_image[i, j] = 0

    # # This creates a circle to model via RMC
    rr, cc = circle(int(N/2), int(N/2), int(N/8))
    initial_image[rr, cc] = 1

    # This creates a square
    #initial_image[int(2*N/6):int(4*N/6), int(1*N/6):int(2*N/6)] = 1

    #f_image = initial_image

    num_particles = np.count_nonzero(initial_image == 1)
    load = num_particles/initial_image.size

    i_image = hiprmc.abs2(hiprmc.fourier_transform(initial_image))

    T = 1000.0  # i_image.shape[0]  # temperature is on the same order as the image

    simulated_image = hiprmc.rmc(i_image, T, iterations, load, movie=True)

    f = plt.figure(3)
    f.add_subplot(2, 2, 1)
    plt.imshow(initial_image, cmap='Greys', origin="lower")
    plt.axis('off')
    plt.title("original image")
    f.add_subplot(1, 5, 2)
    plt.axis('off')
    f.add_subplot(2, 2, 2)
    plt.imshow(np.log10(i_image), origin="lower", cmap='hsv')
    # plt.imshow(cmap='Greys', origin='lower', alpha=0.5)
    plt.axis('off')
    plt.title("Initial Intensity Plot")
    f.add_subplot(2, 2, 3)
    plt.imshow(simulated_image, cmap="Greys", origin="lower")
    plt.title("Model")
    plt.axis('off')
    f.add_subplot(2, 2, 4)
    plt.imshow(np.log10(hiprmc.abs2(hiprmc.fourier_transform(simulated_image))), origin='lower', cmap='hsv')
    plt.axis('off')
    plt.title("Model Intensity Plot")
    plt.show()

    ######################################################
    ########### End Test Images ##########################
    ######################################################

def test_real():

    ######################################################
    ######### Uncomment for Uploading Real Data ##########
    ######################################################

    #Image upload
    image = np.load('cool_40p0C_ILC1_insitu_40pt0C_2m.edf.npy')
    print(image.shape)
    f_mask = np.load('shuai_data_mask.edf.npy')
    N = image.shape[0]
    image[image==np.nan]=0

    #set load of particles
    load = 0.10

    #random particles
    initial_particles = np.random.choice([0, 1], size=(N,N), p=[1.0-load, load])

    ######################################################
    ########### End Real Data Upload #####################
    ######################################################

    T = 40 # i_image.shape[0]  # temperature is on the same order as the image

    simulated_image = hiprmc.rmc(image, num_particles, N, T, iterations, movie=True)

    f = plt.figure(3)
    f.add_subplot(2, 2, 1)
    plt.imshow(image, cmap='Greys', origin="lower")
    plt.axis('off')
    plt.title("original image")
    f.add_subplot(1, 5, 2)
    plt.axis('off')
    #f.add_subplot(2, 2, 2)
    #original_intensity = np.log10(hiprmc.abs2(hiprmc.fourier_transform(i_image)))
    #plt.imshow(original_intensity, origin="lower", cmap='hsv')
    # plt.imshow(cmap='Greys', origin='lower', alpha=0.5)
    #plt.axis('off')
    #plt.title("Initial Intensity Plot")
    f.add_subplot(2, 2, 3)
    plt.imshow(simulated_image, cmap="Greys", origin="lower")
    plt.title("Model")
    plt.axis('off')
    f.add_subplot(2, 2, 4)
    plt.imshow(np.log10(hiprmc.abs2(hiprmc.fourier_transform(simulated_image))), origin='lower', cmap='hsv')
    plt.axis('off')
    plt.title("Model Intensity Plot")
    plt.show()

if __name__ == '__main__':
    test_simulated()


from tkinter import Tk, Label, Entry, Button
import json
from Driver.invokeChrome import DriverBot
from time import sleep
from Controllers.criarConta import criar_conta

#importar thread
from threading import Thread

def salvar_dados():
    # Obter os valores dos campos de entrada
    api_proxy = api_proxy_entry.get()
    link_reset_api = link_reset_api_entry.get()
    senha_contas = senha_contas_entry.get()

    # Cria um objeto com os dados
    dados = {
        "API_PROXY": api_proxy,
        "Link Reset API": link_reset_api,
        "Senha para contas": senha_contas
    }

    # Salva os dados em um arquivo json
    try:
        with open("BancoDeDados/dados.json", "w") as arquivo:
            json.dump(dados, arquivo)
        message_label.config(text="Dados salvos com sucesso!")
    except Exception as e:
        message_label.config(text=f"Erro ao salvar os dados: {str(e)}")

def carregar_dados():
    try:
        with open("BancoDeDados/dados.json", "r") as arquivo:
            dados = json.load(arquivo)
            return dados
    except:
        return None

dados_carregados = carregar_dados()

def iniciar_criacao():
    # Lógica para iniciar a criação usando os dados fornecidos
    api_proxy = api_proxy_entry.get()
    link_reset_api = link_reset_api_entry.get()
    senha_contas = senha_contas_entry.get()

    # Criar uma thread para executar o criar_conta
    thread = Thread(target=criar_conta, args=(senha_contas,))
    thread.start()

def tela_logado():
    global message_label, api_proxy_entry, link_reset_api_entry, senha_contas_entry
    # Criar a janela principal
    root = Tk()
    root.title("Usuário Logado")

    width = 300
    height = 220
    root.geometry(f"{width}x{height}")

    # Label e Entry para API_PROXY
    api_proxy_label = Label(root, text="API_PROXY")
    api_proxy_label.pack()
    api_proxy_entry = Entry(root)
    api_proxy_entry.pack()

    # Label e Entry para Link Reset API
    link_reset_api_label = Label(root, text="Link Reset API")
    link_reset_api_label.pack()
    link_reset_api_entry = Entry(root)
    link_reset_api_entry.pack()

    # Label e Entry para marcadorPasta
    senha_contas_label = Label(root, text="Qual pasta deseja abrir?")
    senha_contas_label.pack()
    senha_contas_entry = Entry(root)
    senha_contas_entry.pack()

    # Botão para salvar os dados
    salvar_button = Button(root, text="Salvar", command=salvar_dados)
    salvar_button.pack()

    # Botão para iniciar a criação
    iniciar_button = Button(root, text="Abrir Perfil", command=iniciar_criacao)
    iniciar_button.pack()

    # Label para exibir mensagens
    message_label = Label(root, text="")
    message_label.pack()

    # Verificar se os dados foram carregados com sucesso
    if dados_carregados is not None:
        api_proxy = dados_carregados.get("API_PROXY")
        link_reset_api = dados_carregados.get("Link Reset API")
        senha_contas = dados_carregados.get("Senha para contas")

        # Inserir os valores nos campos de entrada
        api_proxy_entry.insert(0, api_proxy)
        link_reset_api_entry.insert(0, link_reset_api)
        senha_contas_entry.insert(0, senha_contas)

    # Iniciar o loop do Tkinter

    root.mainloop()


from django.conf.urls import url
from . import views

app_name="image"

urlpatterns = [
    url('list-images/', views.list_images, name="list_images"),
    url('upload-image/', views.upload_image, name='upload_image'),
    url('del-image/', views.del_image, name='del_image'),
    url('images/', views.falls_images, name="falls_images"),
]


'''
Example of API usage on how to work with this library
Tests almost everything.
'''
from sclrecommender.mask import MaskGenerator
from sclrecommender.mask import RandomMaskGenerator
from sclrecommender.mask import LegalMoveMaskGenerator

from sclrecommender.matrix import RatingMatrix
from sclrecommender.matrix import PositiveNegativeMatrix
from sclrecommender.matrix import OneClassMatrix

from sclrecommender.analyzer import MatrixAnalyzer

from sclrecommender.transform import MatrixTransform

from sclrecommender.parser import ExampleParser
from sclrecommender.parser import MovieLensParser100k

# from sclrecommender.bandit.runner import BanditRunner
from banditRunner2541 import BanditRunner2541

#from sclrecommender.bandit.model import UncertaintyModel
from uncertaintyModel import UncertaintyModel
#from nnmf import NNMF # Distribution SVI NNMF
#from nnmf_vanilla import NNMFVanilla # NNMFVanilla with point estimates

from pmf import PMF

from banditChoiceBoltzmann import BanditChoiceBoltzmann
from banditChoiceUCBEmpirical import BanditChoiceUCBEmpirical
from banditChoiceExploit import BanditChoiceExploit
from banditChoiceThompsonSampling import BanditChoiceThompsonSampling
from banditChoiceEntropy import BanditChoiceEntropy
from banditChoiceEgreedy import BanditChoiceEgreedy

from sclrecommender.bandit.choice import RandomChoice # A random choice
from sclrecommender.bandit.choice import OptimalChoice # The optimal choice
from sclrecommender.bandit.choice import WorstChoice # The worst choice

from utils import preprocess_data, prepare_test_users

from sclrecommender.evaluator import Evaluator
# Reconstruction Evaluators
from sclrecommender.evaluator import ReconstructionEvaluator
from sclrecommender.evaluator import RootMeanSquareError
from sclrecommender.evaluator import PositiveNegativeEvaluator
from sclrecommender.evaluator import F1ScoreEvaluator

# Ranking Evaluators
from sclrecommender.evaluator import RankingEvaluator
from sclrecommender.evaluator import RecallAtK
from sclrecommender.evaluator import PrecisionAtK
from sclrecommender.evaluator import MeanAveragePrecisionAtK
# TODO: NDCG, used by 2017 paper by Pierre

# Bandit Evaluators
from sclrecommender.evaluator import RegretOptimalEvaluator
from sclrecommender.evaluator import RegretInstantaneousEvaluator

import copy
import numpy as np
import random
import matplotlib.pyplot as plt
import sys

'''
def pprint(obj):
    # For debugging, print statements with numpy variable names and shape
    def namestr(obj):
        namespace = globals()
        return [name for name in namespace if namespace[name] is obj]
    # Assumes obj is a numpy array, matrix
    try:
        print(namestr(obj), obj.shape)
    except:
        try:
            print(namestr(obj), ",", len(obj))
        except:
            print(namestr(obj))
    print(obj)
'''
def pprint(obj):
    print(obj)

def runAll(nnmf, ucb, ratingMatrix, trainMatrix, testMatrix, testUsers, modelName, fileLocation):
    positiveThreshold = 3.0 # Threshold to set prediction to positive labels
    labelTruth = PositiveNegativeMatrix(ratingMatrix, positiveThreshold)

    positiveNegativeMatrix = labelTruth.getPositiveNegativeMatrix()

    pprint(trainMatrix)
    pprint(testMatrix)
    pprint(positiveNegativeMatrix)

    # Step 5: RecommenderAlgorithm
    # Option 5.1: ReconstructionMatrix: Outputs a reconstruction of actual matrix, known as recommenderMatrix

    reconstructionMatrix = ratingMatrix.copy() # TODO: Calculate reconstruction matrix
    reconstructionPrediction = PositiveNegativeMatrix(reconstructionMatrix, positiveThreshold)
    positiveNegativePredictionMatrix = reconstructionPrediction.getPositiveNegativeMatrix()

    pprint(reconstructionMatrix)
    pprint(positiveNegativePredictionMatrix)

    # Option 5.2: RankingMatrix: Outputs a matrix of ranking for each user or item
    # Bandit Specific, get Legal Move that can be trained on
    legalTrainMask = LegalMoveMaskGenerator(trainMatrix).getMaskCopy()
    legalTestMask = LegalMoveMaskGenerator(testMatrix).getMaskCopy()

    pprint(legalTrainMask)
    pprint(legalTestMask)

    banditRunner = BanditRunner2541(ratingMatrix.copy(), legalTrainMask.copy(), legalTestMask.copy(), testUsers, modelName, fileLocation)
    banditRunner.setUncertaintyModel(nnmf)
    banditRunner.setBanditChoice(ucb)

    rankingMatrix = banditRunner.generateRanking()
    orderChoices = banditRunner.getOrderChoices()

    pprint(rankingMatrix)
    pprint(orderChoices)

    # Step 6: Evaluator

    # Option 6.1 Reconstruction Matrix evaluators
    accuracy = ReconstructionEvaluator(ratingMatrix, reconstructionMatrix).evaluate()
    rmse = RootMeanSquareError(ratingMatrix, reconstructionMatrix).evaluate()
    f1ScoreEvaluator = F1ScoreEvaluator(ratingMatrix, reconstructionMatrix)
    f1Score = f1ScoreEvaluator.evaluate()
    recall = f1ScoreEvaluator.getRecall()
    precision= f1ScoreEvaluator.getPrecision()

    pprint(accuracy)
    pprint(rmse)
    pprint(f1Score)
    pprint(recall)
    pprint(precision)

    # Option 6.2  Ranking Matrix evaluators
    # Option 6.2.1 Confusion Matrix evaluators
    # Evaluate the ranking matrix that was given
    k = 10 # number of items for each user is 20, so should be less than 20 so recall not guaranteed to be 1

    #-----------------------------------------------------------------------
    print("TEMP SHRINK TO tempMaxNumUser!")
    print(ratingMatrix.shape)
    ratingMatrix = ratingMatrix[:tempMaxNumUser]
    # Choices were made from any position, so can't reduce rating matrix size by tempMaxNumItem
    # ratingMatrix = ratingMatrix[:, :tempMaxNumItem]
    print(ratingMatrix.shape)
    print(legalTestMask.shape)
    legalTestMask = legalTestMask[:tempMaxNumUser]
    # legalTestMask = legalTestMask[:, :tempMaxNumItem]
    print(legalTestMask.shape)
    print(rankingMatrix.shape)
    rankingMatrix = rankingMatrix[:tempMaxNumUser]
    # rankingMatrix = rankingMatrix[:, :tempMaxNumItem]
    print(rankingMatrix.shape)
    #-------------------------------------------------------------------------------------------------------
    meanPrecisionAtK = PrecisionAtK(ratingMatrix, rankingMatrix, positiveThreshold, k).evaluate()
    meanRecallAtK = RecallAtK(ratingMatrix, rankingMatrix, positiveThreshold, k).evaluate()
    meanAveragePrecisionAtK = MeanAveragePrecisionAtK(ratingMatrix, rankingMatrix, positiveThreshold, k).evaluate()
    print("Model: " + str(modelName))
    print("\nMeanRecallAtK")
    print(meanRecallAtK) # meanRecallAtK
    print("MeanPrecisionAtK")
    print(meanPrecisionAtK) # meanPrecisionAtK
    print("MeanAveragePrecisionAtK")
    print(meanAveragePrecisionAtK)

    # Option 6.2.2  Bandit evaluators
    discountFactor = 0.99
    regretBasedOnOptimalRegret = RegretOptimalEvaluator(ratingMatrix, rankingMatrix, discountFactor).evaluate()
    nonZeroMask = np.ones(ratingMatrix.shape)
    nonZeroMask[np.where(ratingMatrix == 0.0)] = 0.0
    instantaneousRegret = RegretInstantaneousEvaluator(ratingMatrix, rankingMatrix, discountFactor, nonZeroMask.copy() ,orderChoices)
    regretBasedOnInstantaneousRegret = instantaneousRegret.evaluate()
    cumulativeInstantaneousRegret =  instantaneousRegret.getCumulativeInstantaneousRegret()
    print("RegretBasedOnOptimalRegret")
    pprint(regretBasedOnOptimalRegret)
    print("RegretBasedOnInstantaneousRegret")
    pprint(regretBasedOnInstantaneousRegret)
    print("CumulativeInstantaneousRegret")
    pprint(cumulativeInstantaneousRegret)

    instantRegretPerUser = []
    cumulativeRegretPerUser = []
    for userIndex in range(tempMaxNumUser):
        regretBasedOnInstantaneousRegret = instantaneousRegret.evaluate(userIndex)
        cumulativeInstantaneousRegret =  instantaneousRegret.getCumulativeInstantaneousRegret()

        instantRegretPerUser.append(regretBasedOnInstantaneousRegret)
        cumulativeRegretPerUser.append(cumulativeInstantaneousRegret)
    meanInstantRegret = np.mean(np.array(instantRegretPerUser))
    print("MeanInstantRegret")
    print(meanInstantRegret)
    # cumRegretUser = np.array(cumulativeRegretPerUser)
    cumRegretUser = np.array([np.array(xi) for xi in cumulativeRegretPerUser])

    print("CumulativeInstantRegretPerUser")
    print(cumRegretUser.shape)
    print(cumRegretUser)
    meanCumRegretUser = np.mean(cumRegretUser, axis = 0)
    print("MeanCumulativeInstantRegretPerUser")
    print(meanCumRegretUser.shape)
    print(meanCumRegretUser)
    print("Ranking matrix for numUser users and numItems items")
    print(rankingMatrix[:, :tempMaxNumItem])

    #-----------------------------------------------------------------
    matrixAnalyzer.summarize()
    xs = []
    ys = []
    for i in range(cumRegretUser.shape[0]):
        x = list(range(len(cumRegretUser[i])))
        y = cumRegretUser[i].copy()
        xs.append(x)
        ys.append(y)
    #-----------------------------------------------------------------
    return xs, ys

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

if __name__ == '__main__':
    # seedNum =  int(random.random() * 1000)
    # print("SEEDNUM IS", seedNum)
    seedNum = 196
    np.random.seed(seedNum)
    random.seed(seedNum)

    # Anything with pprint(numpyVariable) means it is a numpy matrix
    # Step 1: Get data based on dataset specific parser
    # dataDirectory = "sclrecommender/data/movielens/ml-100k"
    dataDirectory ="ml-100k"
    mlp = MovieLensParser100k(dataDirectory)
    numUser = 50
    numItem = 50
    exParser = ExampleParser("")
    ratingMatrix = exParser.getRatingMatrix(numUser, numItem)
    ratingMatrix[0][0] = 1.0
    ratingMatrix = mlp.getRatingMatrixCopy()

    R = ratingMatrix.copy()

    # To run on entire rating matrix
    ratingMatrix = mlp.getRatingMatrixCopy()
    # Remove the users that are too hot
    ratingMatrix = MatrixTransform(ratingMatrix).coldUsers(830)
    # Sort by users that are hot
    ratingMatrix = MatrixTransform(ratingMatrix).hotUsers()

    # TODO: Work with R
    tempMaxNumUser = 20 # TODO TEMPORARY, FOLLOWS NUMBER IN BANDIT RUNNER
    tempMaxNumItem = 50 # for printing ranking matrix
    print("Test Users")
    R = preprocess_data(R)
    test_users = prepare_test_users(R)
    print(test_users)

    fileLocation = "/home/soon/Desktop/runs/all/"
    # '''
    fileLocation = "/home/soon/Desktop/runs/dense/"
    # Dense
    ratingMatrix = R.copy()
    for curr in range(test_users.shape[0]):
        # Swap them
        userIndex = test_users[curr]
        temp = ratingMatrix[curr].copy()
        temp2 = ratingMatrix[userIndex].copy()
        ratingMatrix[curr] = temp2.copy()
        ratingMatrix[userIndex] = temp.copy()
    # '''

    testUsers = np.array([i for i in range(tempMaxNumUser)])

    # TODO: PICK FOR DENSE AND ALL
    # Create the folder
    bashCommand = "mkdir -p " + fileLocation
    import subprocess
    process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE)
    output, error = process.communicate()

    # Step 2: Generate both Rating Matrix and Label Matrix for evaluation
    rmTruth = RatingMatrix(ratingMatrix)
    # Step 3 Analyze the rating matrix
    matrixAnalyzer = MatrixAnalyzer(ratingMatrix)
    matrixAnalyzer.summarize()

    # Step 4: Split rating matrix to train and test
    trainSplit = 0.70 # Assuming 200 items, 70 percent, will allow > 50 items to be explored in test

    # Step 4.1: Choose splitting procedure

    # Option 4.1.1: Random Split
    randomMaskTrain, randomMaskTest = RandomMaskGenerator(rmTruth.getRatingMatrix(), trainSplit).getMasksCopy()

    #TODO: Option 4.1.2: Split based on time
    #TODO: Option 4.1.3: Split based on cold users
    #TODO: Option 4.1.4: Split based on cold items

    # Step 4.2: Apply mask
    rmTrain = copy.deepcopy(rmTruth)
    rmTest = copy.deepcopy(rmTruth)
    rmTrain.applyMask(randomMaskTrain)
    rmTest.applyMask(randomMaskTest)

    trainMatrix = rmTrain.getRatingMatrix()
    testMatrix = rmTest.getRatingMatrix()

    xLabel = 'Exploration Number'
    yLabel = 'Cumulative Instantaneous Regret'
    #----------------------------------------
    um = UncertaintyModel(ratingMatrix.copy())
    optimalChoice = OptimalChoice()
    modelString7 = "Optimal"
    x7s, y7s = runAll(um, optimalChoice, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString7, fileLocation)
    currI = 0
    for x7, y7 in zip(x7s, y7s):
        plt.plot(x7, y7, label=modelString7 + str(currI))
        currI += 1
    x7 = x7s[0]
    y7 = np.mean(y7s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString7)
    plt.savefig(fileLocation + "optimalChoices.png")
    plt.clf()
    plt.plot(x7, y7, label=modelString7 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString7)
    plt.savefig(fileLocation + "optimalChoicesMean.png")
    np.save(fileLocation + "x7.npy", x7)
    np.save(fileLocation + "y7s.npy", y7s)
    plt.clf()
    #----------------------------------------
    um = UncertaintyModel(ratingMatrix.copy())
    worstChoice = WorstChoice()
    modelString8 = "Worst"
    x8s, y8s = runAll(um, worstChoice, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString8, fileLocation)
    currI = 0
    for x8, y8 in zip(x8s, y8s):
        plt.plot(x8, y8, label=modelString8 + str(currI))
        currI += 1
    x8 = x8s[0]
    y8 = np.mean(y8s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString8)
    plt.savefig(fileLocation + "worstChoices.png")
    plt.clf()
    plt.plot(x8, y8, label=modelString8 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString8)
    plt.savefig(fileLocation + "worstChoicesMean.png")
    np.save(fileLocation + "x8.npy", x8)
    np.save(fileLocation + "y8s.npy", y8s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    bBoltz = BanditChoiceBoltzmann()
    modelString1 = "PMF_Boltzmann"
    x1s, y1s = runAll(pmf, bBoltz, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString1, fileLocation)
    currI = 0
    for x1, y1 in zip(x1s, y1s):
        plt.plot(x1, y1, label=modelString1 + str(currI))
        currI += 1
    x1 = x1s[0]
    y1 = np.mean(y1s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString1)
    plt.savefig(fileLocation + modelString1 + ".png")
    plt.clf()
    plt.plot(x1, y1, label=modelString1 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString1)
    plt.savefig(fileLocation + modelString1 + "Mean.png")
    np.save(fileLocation + "x1.npy", x1)
    np.save(fileLocation + "y1s.npy", y1s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    bExploit = BanditChoiceExploit()
    modelString2 = "PMF_Exploit"
    x2s, y2s = runAll(pmf, bExploit, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(),testUsers, modelString2, fileLocation)
    currI = 0
    for x2, y2 in zip(x2s, y2s):
        plt.plot(x2, y2, label=modelString2 + str(currI))
        currI += 1
    x2 = x2s[0]
    y2 = np.mean(y2s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString2)
    plt.savefig(fileLocation + modelString2 + ".png")
    plt.clf()
    plt.plot(x2, y2, label=modelString2 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString2)
    plt.savefig(fileLocation + modelString2 + "Mean.png")
    np.save(fileLocation + "x2.npy", x2)
    np.save(fileLocation + "y2s.npy", y2s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    bUcbEmpirical = BanditChoiceUCBEmpirical()
    modelString3 = "PMF_UCB"
    x3s, y3s = runAll(pmf, bUcbEmpirical, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(),testUsers, modelString3, fileLocation)
    currI = 0
    for x3, y3 in zip(x3s, y3s):
        plt.plot(x3, y3, label=modelString3 + str(currI))
        currI += 1
    x3 = x3s[0]
    y3 = np.mean(y3s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString3)
    plt.savefig(fileLocation + modelString3 + ".png")
    plt.clf()
    plt.plot(x3, y3, label=modelString3 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString3)
    plt.savefig(fileLocation + modelString3 + "Mean.png")
    np.save(fileLocation + "x3.npy", x3)
    np.save(fileLocation + "y3s.npy", y3s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    bThompson = BanditChoiceThompsonSampling()
    modelString4 = "PMF_Thompson_Sampling"
    x4s, y4s = runAll(pmf, bThompson, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString4, fileLocation)
    currI = 0
    for x4, y4 in zip(x4s, y4s):
        plt.plot(x4, y4, label=modelString4 + str(currI))
        currI += 1
    x4 = x4s[0]
    y4 = np.mean(y4s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString4)
    plt.savefig(fileLocation + modelString4 + ".png")
    plt.clf()
    plt.plot(x4, y4, label=modelString4 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString4)
    plt.savefig(fileLocation + modelString4 + "Mean.png")
    np.save(fileLocation + "x4.npy", x4)
    np.save(fileLocation + "y4s.npy", y4s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    bEntropy = BanditChoiceEntropy()
    modelString5 = "PMF_Entropy"
    x5s, y5s = runAll(pmf, bEntropy, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString5, fileLocation)
    currI = 0
    for x5, y5 in zip(x5s, y5s):
        plt.plot(x5, y5, label=modelString5 + str(currI))
        currI += 1
    x5 = x5s[0]
    y5 = np.mean(y5s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString5)
    plt.savefig(fileLocation + modelString5 + ".png")
    plt.clf()
    plt.plot(x5, y5, label=modelString5 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString5)
    plt.savefig(fileLocation + modelString5 + "Mean.png")
    np.save(fileLocation + "x5.npy", x5)
    np.save(fileLocation + "y5s.npy", y5s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    bEgreedy= BanditChoiceEgreedy()
    modelString6 = "PMF_eGreedy"
    x6s, y6s = runAll(pmf, bEgreedy, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString6, fileLocation)
    currI = 0
    for x6, y6 in zip(x6s, y6s):
        plt.plot(x6, y6, label=modelString6 + str(currI))
        currI += 1
    x6 = x6s[0]
    y6 = np.mean(y6s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString6)
    plt.savefig(fileLocation + modelString6 + ".png")
    plt.clf()
    plt.plot(x6, y6, label=modelString6 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString6)
    plt.savefig(fileLocation + modelString6 + "Mean.png")
    np.save(fileLocation + "x6.npy", x6)
    np.save(fileLocation + "y6s.npy", y6s)
    plt.clf()
    #----------------------------------------
    pmf = PMF(ratingMatrix.copy())
    rc = RandomChoice()
    modelString9 = "PMF_Random"
    x9s, y9s = runAll(pmf, rc, ratingMatrix.copy(), trainMatrix.copy(), testMatrix.copy(), testUsers, modelString9, fileLocation)
    currI = 0
    for x9, y9 in zip(x9s, y9s):
        plt.plot(x9, y9, label=modelString9 + str(currI))
        currI += 1
    x9 = x9s[0]
    y9 = np.mean(y9s, axis = 0)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString9)
    plt.savefig(fileLocation + "randomChoices.png")
    plt.clf()
    plt.plot(x9, y9, label=modelString9 + str(currI))
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString9)
    plt.savefig(fileLocation + "randomChoicesMean.png")
    np.save(fileLocation + "x9.npy", x9)
    np.save(fileLocation + "y9s.npy", y9s)
    plt.clf()
    #----------------------------------------
    modelString = "All Models"
    plt.plot(x1, y1, label=modelString1)
    plt.plot(x2, y2, label=modelString2)
    plt.plot(x3, y3, label=modelString3)
    plt.plot(x4, y4, label=modelString4)
    plt.plot(x5, y5, label=modelString5)
    plt.plot(x6, y6, label=modelString6)
    plt.plot(x7, y7, label=modelString7)
    plt.plot(x8, y8, label=modelString8)
    plt.plot(x9, y9, label=modelString9)
    plt.legend(loc = 'upper left')
    plt.xlabel(xLabel)
    plt.ylabel(yLabel)
    plt.title(modelString)
    plt.savefig(fileLocation + "AllInOne.png")
    plt.clf()
    print("DONE TESTING")


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# 1 * 32 * 32输入
# 卷积（5 * 5）：6 * 28 * 28
# 池化（2 * 2）：6 * 14 * 14
# 卷积（5 * 5）：16 * 10 * 10
# 池化（2 * 2）：16 * 5 * 5
# 全连接（120层）：
# 全连接（84层）：
# 全连接（10层）：

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        x = F.max_pool2d(F.relu(self.conv2(x)), (2, 2))
        # 将数据从[n * c * w * h]转换为[n * m]维，作为下一步全连接的输入
        # x = x.view(-1, self.num_flat_features(x))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

    def num_flat_features(self, x):
    # 将数据从[n * c * w * h]转换为[n * m]维，作为下一步全连接的输入
        size = x.size()[1: ] #除batch size外的大小
        print('size = ', size)
        num_features = 1
        for s in size:
            print(s)
            num_features = num_features * s
        return num_features

net = Net()
print(net)
#params = list(net.parameters())
#print(params)
input = torch.randn(1, 1, 32, 32)
target = torch.randn(1, 10)
print(target)
criterion = nn.MSELoss()

# 优化函数
optimizer = optim.SGD(net.parameters(), lr = 0.01)
optimizer.zero_grad()
output = net(input)
print(output)
loss = criterion(output, target)
loss.backward()
optimizer.step()
print(output)


from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views

urlpatterns = [
    # django admin
    url(r'^django-admin/', admin.site.urls),
    # login / logout
    url(r'^login$', views.LoginView.as_view(template_name='login.html'), name='login'),
    url(r'^logout$', views.LogoutView.as_view(next_page='/'), name='logout'),
    # permissions managment
    url(r'^', include('permissions.urls')),
    # account managment
    url(r'^', include('accounts.urls')),
    # tracker
    url(r'^', include('tracker.urls')),
]


import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from mmdet.core import bbox_overlaps
from ..registry import LOSSES
import numpy as np
import DOTA_devkit.polyiou as polyiou
from mmdet.core.bbox.transforms_rbbox import RotBox2Polys_torch, poly2bbox_torch, mask2poly, Tuplelist2Polylist
from .utils import weighted_loss
from shapely.geometry import Polygon,MultiPoint
#from poly_nms_gpu.poly_overlaps import poly_overlaps

import random
import string

def randomString(stringLength=8):

    letters = string.ascii_lowercase

    return ''.join(random.choice(letters) for i in range(stringLength))

def polygon_iou(list1, list2):
    """
    Intersection over union between two shapely polygons.
    """
    polygon_points1 = np.array(list1).reshape(4, 2)
    poly1 = Polygon(polygon_points1).convex_hull
    polygon_points2 = np.array(list2).reshape(4, 2)
    poly2 = Polygon(polygon_points2).convex_hull
    union_poly = np.concatenate((polygon_points1, polygon_points2))
    if not poly1.intersects(poly2):  # this test is fast and can accelerate calculation
        iou = 0
    else:
        try:
            inter_area = poly1.intersection(poly2).area
            union_area = poly1.area + poly2.area - inter_area
            # union_area = MultiPoint(union_poly).convex_hull.area
            if union_area == 0:
                return 1
            iou = float(inter_area) / union_area
        except shapely.geos.TopologicalError:
            print('shapely.geos.TopologicalError occured, iou set to 0')
            iou = 0
    return iou

@weighted_loss
def skew_iou_loss(pred_box,gt_box,eps=1e-6):
    # first calculate the hbb overlaps, for overlaps > 0, calculate the obb overlaps
    # from 5 pt representation to 8pt polygon
    gt_poly = RotBox2Polys_torch(gt_box)
    pred_poly = RotBox2Polys_torch(pred_box)

    # polygon to hbb
    h_bboxes= poly2bbox_torch(gt_poly)
    h_query_bboxes = poly2bbox_torch(pred_poly)
    # hious
    ious = bbox_overlaps(h_query_bboxes, h_bboxes)
    import pdb
    # pdb.set_trace()
    inds = (ious>0).int().nonzero()
    iou =  torch.tensor(0).float()
    #print(inds.shape, ious.shape,flush=True)
    for index in range(inds.shape[0]):
        box_index = inds[index][1]
        query_box_index = inds[index][0]

        box = gt_poly[box_index]
        query_box = pred_poly[query_box_index]
        #union_poly = torch.cat([box,query_box],0)

        overlap = polygon_iou(query_box.detach().cpu().numpy(),box.detach().cpu().numpy())
        #overlap = polyiou.iou_poly(polyiou.VectorDouble(query_box.cpu().numpy().astype(np.float),polyiou.VectorDouble(box.cpu().numpy().astype(np.float))))
        '''
        query = query_box.clone().detach().cpu().numpy()
        ox = box.clone().detach().cpu().numpy()
        plt.scatter(query[::2],query[1::2])
        plt.scatter(ox[::2],ox[1::2])
        plt.title(str(overlap))
        plt.savefig('./tests/NEW_skew_iou_%s'%(randomString(6)))
        plt.clf()
        '''
        if overlap < eps:
            overlap = eps
        iou += -torch.tensor(overlap).log()

#    ious  = ious.clamp(min=eps)
#    loss = -ious.log()
#    loss = -np.log(iou)
    loss = torch.tensor(iou).cuda()
    return loss

#def iou_loss(pred, target, eps=1e-6):
    """IoU loss.

    Computing the IoU loss between a set of predicted bboxes and target bboxes.
    The loss is calculated as negative log of IoU.

    Args:
        pred (Tensor): Predicted bboxes of format (x1, y1, x2, y2),
            shape (n, 4).
        target (Tensor): Corresponding gt bboxes, shape (n, 4).
        eps (float): Eps to avoid log(0).

    Return:
        Tensor: Loss tensor.
    """
#    ious = bbox_overlaps(pred, target, is_aligned=True).clamp(min=eps)
#    loss = -ious.log()
#    return loss

@LOSSES.register_module
class skew_IoULoss(nn.Module):

    def __init__(self, eps=1e-6, reduction='mean', loss_weight=1.0):
        super(skew_IoULoss, self).__init__()
        self.eps = eps
        self.reduction = reduction
        self.loss_weight = loss_weight

    def forward(self,
                pred,
                target,
                weight=None,
                avg_factor=None,
                reduction_override=None,
                **kwargs):
#        if weight is not None and not torch.any(weight > 0):
#            print(pred.shape, weight.shape,"????????????", flush=True)
#            return (weight * pred).sum()  # 0
        assert reduction_override in (None, 'none', 'mean', 'sum')
        reduction = (
            reduction_override if reduction_override else self.reduction)
        loss = self.loss_weight * skew_iou_loss(
            pred,
            target,
            weight,
            eps=self.eps,
            reduction=reduction,
            avg_factor=avg_factor,
            **kwargs)
        return loss

if __name__ == "__main__":
    gt_bbox = np.array([[1,2,3,5,0],[6,6,4,4,np.pi/2]])
    pred = np.array([[2,1,5,3,0],[6,6,4,4,0]])
    print(skew_iou_loss(gt_bbox,pred))


import sys
import os

from rdkit.Chem import Descriptors
from rdkit.Chem import rdMolDescriptors
from rdkit.Chem import RDConfig
from rdkit.Chem import Lipinski
from rdkit.Chem import rdmolops
from rdkit.Chem import Crippen

from .. import Mol
from ..convert import from_smarts
from .._version import is_lower_than_current_rdkit_version

def _sasscorer(mol: Mol):
    sys.path.append(os.path.join(RDConfig.RDContribDir, "SA_Score"))
    try:
        import sascorer  # type:ignore
    except ImportError:
        raise ImportError(
            "Could not import sascorer. If you installed rdkit-pypi with `pip`, please uninstall it and reinstall rdkit with `conda` or `mamba`."
        )

    return sascorer.calculateScore(mol)

_AROMATIC_QUERY = from_smarts("a")

mw = rdMolDescriptors.CalcExactMolWt
fsp3 = rdMolDescriptors.CalcFractionCSP3
tpsa = rdMolDescriptors.CalcTPSA
qed = Descriptors.qed
clogp = Descriptors.MolLogP  # type: ignore
sas = _sasscorer
formal_charge = rdmolops.GetFormalCharge
refractivity = Crippen.MolMR

n_hba = rdMolDescriptors.CalcNumHBA
n_hbd = rdMolDescriptors.CalcNumHBD
n_lipinski_hba = rdMolDescriptors.CalcNumLipinskiHBA
n_lipinski_hbd = rdMolDescriptors.CalcNumLipinskiHBD
n_rings = rdMolDescriptors.CalcNumRings
n_hetero_atoms = rdMolDescriptors.CalcNumHeteroatoms

if is_lower_than_current_rdkit_version("2021.09"):
    n_heavy_atoms = Descriptors.HeavyAtomCount  # type: ignore
else:
    n_heavy_atoms = rdMolDescriptors.CalcNumHeavyAtoms

n_rotatable_bonds = rdMolDescriptors.CalcNumRotatableBonds
n_radical_electrons = Descriptors.NumRadicalElectrons
n_NHOH = Lipinski.NHOHCount
n_NO = Lipinski.NOCount
n_spiro_atoms = rdMolDescriptors.CalcNumSpiroAtoms

n_aliphatic_carbocycles = rdMolDescriptors.CalcNumAliphaticCarbocycles
n_aliphatic_heterocyles = rdMolDescriptors.CalcNumAliphaticHeterocycles
n_aliphatic_rings = rdMolDescriptors.CalcNumAliphaticRings

n_aromatic_carbocycles = rdMolDescriptors.CalcNumAromaticCarbocycles
n_aromatic_heterocyles = rdMolDescriptors.CalcNumAromaticHeterocycles
n_aromatic_rings = rdMolDescriptors.CalcNumAromaticRings

n_saturated_carbocycles = rdMolDescriptors.CalcNumSaturatedCarbocycles
n_saturated_heterocyles = rdMolDescriptors.CalcNumSaturatedHeterocycles
n_saturated_rings = rdMolDescriptors.CalcNumSaturatedRings

def n_rigid_bonds(mol: Mol) -> int:
    """Compute the number of rigid bonds in a molecule.

    Rigid bonds are bonds that are not single and not in rings.

    Args:
        mol: A molecule.

    Returns:
        n_rigid_bonds: number of rigid bonds in the molecule
    """
    non_rigid_bonds_count = from_smarts("*-&!@*")
    n_rigid_bonds = mol.GetNumBonds() - len(mol.GetSubstructMatches(non_rigid_bonds_count))
    return n_rigid_bonds

def n_aromatic_atoms(mol: Mol) -> int:
    """Calculate the number of aromatic atoms."""
    matches = mol.GetSubstructMatches(_AROMATIC_QUERY)
    return len(matches)

def n_aromatic_atoms_proportion(mol: Mol) -> int:
    """Calculate the aromatic proportion: # aromatic atoms/#atoms total.

    Args:
        mol: A molecule.

    Only heavy atoms are considered.
    """
    return n_aromatic_atoms(mol) / mol.GetNumHeavyAtoms()

def n_stereo_centers(mol: Mol) -> int:
    """Compute the number of stereocenters in a molecule.

    Args:
        mol: A molecule.

    Returns:
        n_stero_center: number of stereocenters in the molecule
    """
    n = 0
    try:
        rdmolops.FindPotentialStereo(mol, cleanIt=False)
        n = rdMolDescriptors.CalcNumAtomStereoCenters(mol)
    except Exception:
        pass
    return n

def n_stereo_centers_unspecified(mol: Mol) -> int:
    """Compute the number of unspecified stereocenters in a molecule.

    Args:
        mol: A molecule.

    Returns:
        n_stereo_centers_unspecified: number of unspecified stereocenters in the molecule
    """
    n = 0
    try:
        rdmolops.FindPotentialStereo(mol, cleanIt=False)
        n = rdMolDescriptors.CalcNumUnspecifiedAtomStereoCenters(mol)
    except Exception:
        pass
    return n

def n_charged_atoms(mol: Mol) -> int:
    """Compute the number of charged atoms in a molecule.

    Args:
        mol: A molecule.

    Returns:
        n_charged_atoms: number of charged atoms in the molecule
    """
    return sum([at.GetFormalCharge() != 0 for at in mol.GetAtoms()])


import boto3, botocore

from b2flow.python.tools.config import get, logger

class Driver:
    def __init__(self, bucket_name: str = get('B2FLOW__PYTHON__TOOLS__BUCKET'),
                 endpoint_url: str = get('B2FLOW__PYTHON__TOOLS__HOSTNAME')):

        self.bucket_name = bucket_name
        session = boto3.session.Session(aws_access_key_id='identity', aws_secret_access_key='credential')
        config = boto3.session.Config(s3={'addressing_style': 'path'})
        self.client = session.client('s3', endpoint_url=endpoint_url, config=config)
        self.resource = session.resource('s3', endpoint_url=endpoint_url, config=config)

        try:
            self.client.create_bucket(Bucket=bucket_name)
        except botocore.exceptions.ClientError:
            pass

    def write(self, body: bytes, filepath: str):
        self.client.put_object(Bucket=self.bucket_name, Body=body, Key=filepath)
        logger.info("write", self.bucket_name, filepath, f"{len(body)}bytes")

    def read(self, filepath: str):
        obj = self.client.get_object(Bucket=self.bucket_name, Key=filepath)
        body = obj['Body'].read()
        logger.info("read", self.bucket_name, filepath, f"{len(body)}bytes")
        return body

    def list(self, prefix: str = ""):
        objects = self.client.list_objects(Bucket=self.bucket_name, Prefix=prefix).get("Contents") or []
        logger.info("list", self.bucket_name, prefix, f"{len(objects)} objects")
        return objects


#!/usr/bin/env python3

import struct

class Error(Exception):
    pass

def _jtlvi_assert(assertion, text=None):
    if assertion:
        return
    if text:
        raise Error(text)
    else:
        raise Error()

def bsd_checksum(input):
    checksum = 0
    for ch in input:
        checksum = (checksum >> 1) + ((checksum & 1) << 15)
        checksum += ch
        checksum &= 0xffff
    return checksum

def dumps(
    input, sort=True, trailer=True,
    padded_length=0, padding_bytes=b'\x00',
):
    """Encode an interable into a JTLVI message.

    :param input:
        Input to encode.  May be a list of key/value tuples, or a
        dict-like iterable (dict, OrderedDict, etc).  Keys must be
        integers between 0 and 65534 (inclusive), and values must be
        bytes-like objects (bytes or bytearray).

    :param sort:
        If True, items are sorted by key before being encoded.

    :param trailer:
        If True, last-element sentinel 65535 is added as a final
        element.  Even if False, it may be set to True if needed (such
        as when adding padding).

    :param padded_length:
        If non-zero, the message will be padded to a minimum length.  If
        the encoded message is already greater than or equal to this
        length, no padding is added.

    :param padding_bytes:
        A bytes object of one or more bytes to be used as a repeating
        sequence when padding.

    :return:
        Returns a bytes object containing the encoded JTLVI message.
    """
    _jtlvi_assert(
        hasattr(input, '__iter__'),
        'Input must be a dict, or list of tuples',
    )
    if hasattr(input, 'items'):
        input_items = input.items()
    else:
        input_items = input
    if sort:
        input_items = sorted(input_items)

    # Magic number 0xd40e and temporarily-zeroed checksum
    output = bytearray(b'\xd4\x0e\x00\x00')

    for (t, v) in input_items:
        # T must be a postive non-zero integer
        _jtlvi_assert(
            type(t) == int,
            'Tag {} must be an integer'.format(t),
        )
        # T=65535 is reserved for explicit EOM
        _jtlvi_assert(
            0 <= t <= 65534,
            'Tag {} must be between 0 and 65534, inclusive'.format(t),
        )
        # V must be bytearray or bytes
        _jtlvi_assert(
            type(v) in (bytearray, bytes),
            'Value for tag {} must be bytes or bytearray object, not {}'.format(t, type(v))
        )

        # Pack T (16-bit big-endian)
        output += struct.pack('!H', t)
        # Pack L (16-bit big-endian)
        output += struct.pack('!H', len(v))
        # Append V
        output += v

    # Add optional padding, a trailer is required if so
    if (padded_length > 0) and (len(output) < padded_length):
        trailer = True
    if trailer:
        output += b'\xff\xff\x00\x00'
    if len(output) < padded_length:
        pad_target = padded_length - len(output)
        padding = padding_bytes * int(pad_target / len(padding_bytes) + 1)
        output += padding[0:pad_target]

    # Calculate and inject the checksum
    output[2:4] = struct.pack('!H', bsd_checksum(output))

    return bytes(output)

def dump(input, fp, **kwargs):
    fp.write(dumps(input, **kwargs))

def loads(input):
    """Decode a JTLVI message to a list of key/value tuples.

    Any errors encountered during decoding will be raised as a
    jtlvi.Error() exception.

    :param input:
        Input to decode.  Must be a bytes object containing a valid
        JTLVI message.

    :return:
        Returns a list of key/value tuples.
    """
    input_len = len(input)
    output = []

    # Check correct magic number
    _jtlvi_assert(
        input[0:2] == b'\xd4\x0e',
        'Unknown magic number {}'.format(input[0:2]),
    )
    # Check input is a valid length (at least 4 bytes)
    _jtlvi_assert(
        input_len >= 4,
        'Incorrect input length {}'.format(input_len),
    )
    # Verify the checksum
    input_checksum = struct.unpack('!H', input[2:4])[0]
    input_zeroed = b'\xd4\x0e\x00\x00' + input[4:]
    calculated_checksum = bsd_checksum(input_zeroed)
    _jtlvi_assert(
        calculated_checksum == input_checksum,
        'Incorrect checksum (calculated {}, saw {})'.format(calculated_checksum, input_checksum),
    )

    # Begin looping through TLVs
    pos = 4
    while input_len > pos:
        # TLV must be at least 4 bytes (2 byte T, 2 byte L, 0+ byte V)
        _jtlvi_assert(
            input_len >= (pos + 4),
            'Position {}: Attempted to read T+L past EOM'.format(pos),
        )
        t = struct.unpack('!H', input[pos:pos+2])[0]
        # T=65535 is reserved for explicit EOM; stop processing if seen
        if t == 65535:
            break
        l = struct.unpack('!H', input[pos+2:pos+4])[0]
        # Make sure L does not read past EOM
        _jtlvi_assert(
            input_len >= (pos + 4 + l),
            'Position {}: Attempted to read T+L+V past EOM'.format(pos),
        )
        v = input[pos+4:pos+4+l]
        output.append((t, v))
        pos += 4 + l

    return output

def load(fp, **kwargs):
    return loads(fp.read(), **kwargs)

if __name__ == '__main__':
    import argparse
    import sys
    import pickle

    parser = argparse.ArgumentParser(
        description='jtlvi',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    parser.add_argument(
        'action', choices=['pickle-to-jtlvi', 'jtlvi-to-pickle'],
        help='action to perform',
    )
    args = parser.parse_args()

    if args.action == 'pickle-to-jtlvi':
        dump(pickle.load(sys.stdin.buffer), sys.stdout.buffer)
    elif args.action == 'jtlvi-to-pickle':
        pickle.dump(load(sys.stdin.buffer), sys.stdout.buffer)


from django.shortcuts import render
from models import *
from  reg_proc.models  import *
from testapp.models  import *
from django.views.decorators.csrf import csrf_exempt
from forms import *
from django.http import HttpResponse
import json,random,string

# Create your views here.

@csrf_exempt
def fetch_deal(request):
	if request.method=='POST':
		form=fetch(request.POST)
		if form.is_valid():
			mobile=form.cleaned_data['mobile']
			token=form.cleaned_data['token']
			try:
				p=signup_db.objects.get(mobile=mobile,token=token)
				k=1
			except:
				k=0
			j={}
			if  k:
				p=0
				n={}
				r=[]
				dbobject=deals.objects.all().order_by('weightage')
				for i  in dbobject:
					n['deal_validity']=str(dbobject[p].deal_validity)
					n['deal_category']=dbobject[p].deal_category
					n['deal_type']=dbobject[p].deal_type
					n['store_name']=dbobject[p].store_name
					n['store_location']=dbobject[p].store_location
					n['store_address']=dbobject[p].store_address
					ph=str(dbobject[p].store_phone)
					phl=list(ph)
					if phl[0]=='*':
						phl[0]='0'
					ph=''.join(phl)
					n['store_phone']=ph
					n['store_latitude']=dbobject[p].store_latitude
					n['store_longitude']=dbobject[p].store_longitude
					n['deal_heading']=dbobject[p].deal_heading
					s=str(dbobject[p].deal_description)
					ls=list(s)
					k=0
					for i in ls:
						if i=='*':
							ls[k]='\n'
						k=k+1

					n['deal_description']=''.join(ls)
					s=str(dbobject[p].deal_activate)
					ls=list(s)
					k=0
					for i in ls:
						if i=='*':
							ls[k]='\n'
						k=k+1

					n['deal_activate']=''.join(ls)
					n['weightage']=dbobject[p].weightage
					n['deal_id']=dbobject[p].deal_id
					n['image']=dbobject[p].image
					n['activated']=dbobject[p].activate

					try:
						dbobject1=vouchers_db.objects.get(deal_id=dbobject[p].deal_id,mobile=mobile)
						n['voucher_id']=str(dbobject1.voucher_id)
						act=1
					except:
						act=0

					n['activatedre']=act

					r.append(n)
					n={}
					p=p+1
				j['result']=1
				j['deals']=r
				return HttpResponse(json.dumps(j),content_type='application/json')
			else:
				j['result']=0
				return HttpResponse(json.dumps(j),content_type='application/json')

#@csrf_exempt
#def image_fetch(request):
#	if request.method=='POST':
#		path=request.POST.get('path','')
#		image=open('%s'%path,'rb')
#		response = HttpResponse(content=image)
#		response['Content-Type'] = 'image'
#		response['Content-Disposition'] = 'attachment; filename="%s.png"' \
#                                 % 'test'
#		return response

@csrf_exempt
def voucher(request):
	if request.method=='POST':
		form=voucher_form(request.POST)
		if form.is_valid():
			mobile=form.cleaned_data['mobile']
			token=form.cleaned_data['token']
			deal_id=form.cleaned_data['deal_id']
			try:
				p=signup_db.objects.get(mobile=mobile,token=token)
				k=1
			except:
				k=0
			n={}
			if k:
				test=vouchers_db.objects.filter(mobile=mobile,deal_id=deal_id)
				if test:
					voucher_id=test[0].voucher_id
				else:
					voucher_id=''.join(random.choice(string.uppercase+string.digits) for i in range(6))
					dbobject1=deals.objects.get(deal_id=deal_id)

					dbobject1.save()
					dbobject=vouchers_db(mobile=mobile,deal_id=deal_id,voucher_id=voucher_id,activate=1)
					dbobject.save()
				n['result']=1
				n['voucher_id']=voucher_id
				return HttpResponse(json.dumps(n),content_type='application/json')
			else:
				n['result']=0
				return HttpResponse(json.dumps(n),content_type='application/json')


import json

from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt

from .models import CustomUser, Image, Notification, Result

def index(request):
    """index."""
    return HttpResponse("Hello, world. You're at the polls index.")

def create_image(request):
    """Create image."""
    return None

def get_recommended_images(request):
    """Get recommended images."""
    images = Image.objects.filter(is_recommended=True)
    results = [{
        'id': image.pk,
        'url': image.url,
    } for image in images]
    return JsonResponse({'results': results})

def get_public_images(request):
    """Get public images."""
    images = Image.objects.filter(is_public=True, is_banned=False)
    results = [{
        'id': image.pk,
        'user_id': image.user.pk,
        'url': image.url,
    } for image in images]
    return JsonResponse({'results': results})

@csrf_exempt
def get_images(request, user_id):
    """Get images."""
    if request.method == 'GET':
        try:
            images = Image.objects.filter(user_id=user_id, is_deleted=False).order_by('-created_datetime')[:100]
            results = [{
                'id': image.pk,
                'user_id': image.user.pk,
                'url': image.url,
                'original_uri': image.original_uri,
                'created_datetime': image.created_datetime,
                'modified_datetime': image.modified_datetime,
            } for image in images]
            return JsonResponse({'results': results})
        except ValueError:
            return JsonResponse({'results': []})

    elif request.method == 'POST':
        data = json.loads(request.body.decode("utf-8"))
        image = Image.objects.create_analytics(
            url=data.get('url'),
            original_uri=data.get('original_uri'),
        )

        user, _ = CustomUser.objects.get_or_create(id=user_id, username=user_id)
        image.user = user
        image.save()
        image.analyze(save=True)
        image.sync_firebase()
        results = [{
            'id': image.pk,
            'user_id': image.user.pk,
            'url': image.url,
            'original_uri': image.original_uri,
        }]
        return JsonResponse({'results': results})

@csrf_exempt
def get_image(request, user_id, image_id):
    """Get image."""
    if request.method == 'GET':
        try:
            images = Image.objects.filter(user_id=user_id, id=image_id, is_deleted=False)
            results = [{
                'id': image.pk,
                'user_id': image.user.pk,
                'url': image.url,
                'original_uri': image.original_uri,
                'tags': list(image.tags.order_by('-score').values_list('name', flat=True)),
            } for image in images]
            return JsonResponse({'results': results})
        except ValueError:
            return JsonResponse({'results': []})
    elif request.method == 'DELETE':
        try:
            image = Image.objects.get(user_id=user_id, id=image_id, is_deleted=False)
            image.is_deleted = True
            image.save()
            return JsonResponse({'results': 'success'})
        except ValueError:
            return JsonResponse({'results': 'failure'})

@csrf_exempt
def get_notifications(request, user_id):
    """Get notifications."""
    if request.method == 'GET':
        try:
            notifications = Notification.objects \
                .filter(user_id=user_id, is_deleted=False) \
                .order_by('-created_datetime')[:100]
            results = [{
            } for notification in notifications]
            return JsonResponse({'results': results})
        except ValueError:
            return JsonResponse({'results': {}})

@csrf_exempt
def results_endpoint(request, user_id, image_id):
    """Get results."""
    if request.method == 'GET':
        try:
            image = Image.objects.get(user_id=user_id, is_deleted=False, id=image_id)
            return JsonResponse({'results': image.get_results()})
        except ValueError:
            return JsonResponse({'results': {}})

    elif request.method == 'POST':
        try:
            image = Image.objects.get(user_id=user_id, is_deleted=False, id=image_id)

            data = json.loads(request.body.decode("utf-8"))
            if data.get('payload'):
                Result.objects.create(
                    image_id=image_id,
                    category=Result.HUMAN,
                    name=data.get('payload', {}).get('type'),
                    feature=Result.CODE,
                    user_id=user_id,
                    payload=json.dumps(data.get('payload')),
                )
                image.sync_firebase()

            return JsonResponse({'results': image.get_results()})
        except ValueError:
            return JsonResponse({'results': {}})

        results = [{
            'id': image.pk,
            'user_id': image.user.pk,
            'url': image.url,
            'original_uri': image.original_uri,
        }]
        return JsonResponse({'results': results})