from geodata import *
import pandas as pd
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('index_path', help='Путь к перечню объектов (.txt, .xls, .xlsx)')
parser.add_argument('final_dir', help='Путь для сохранения данных')
parser.add_argument('-d', default=None, dest='dout', help='Путь для сохранения сцен с метаданными')
parser.add_argument('-r', default=None, dest='rdir', help='Путь к папке с растровыми файлами, пересечение с которыми тоже выкачивать безотносительно имени')
args = parser.parse_args()
dout = args.dout
rdir = args.rdir
index_path = args.index_path
final_dir = args.final_dir

def ExtractKanId(line):
    if re.search('^KV.+L2$', line):
        return line
    else:
        for type in ['.MS', '.PAN', '.PMS']:
            if type in line:
                return line.split(type)[0]+type+'.L2'

def KanCallSQL(kan_id, type=False):
    if re.search('IM4-.+-.+', kan_id):
        if type:
            date = kan_id.split('-')[2]
            kan_date = '%s-%s-%s' % (date[:4], date[4:6], date[6:])
            return '''"source='kanopus' and date(datetime)='%s' and type='%s'"''' % (kan_date, type.lower())
        else:
            print('KANOPUS TYPE NOT DEFINED, CANNOT DOWNLOAD DATA: %s' % kan_id)
    else:
        return '''"source='kanopus' and hashless_id='%s'"''' % kan_id

def DownloadKanopusFromS3(pout, type=None, geom_path = None):
    command = r'''gu_db_query -w "source='kanopus' and type='ms'" -d %s''' % pout
    if geom_path is not None:
        command += ' -v %s' % geom_path
    print(command)
    os.system(command)

class FolderDirs(dict):

    def __init__(self, folder, miss_tmpt=None):
        for name in os.listdir(folder):
            path = fullpath(folder, name)
            if os.path.isdir(path):
                if miss_tmpt:
                    if re.search(miss_tmpt, name):
                        continue
                self[name] = path

suredir(final_dir)

if index_path.endswith('txt'):
    with open(index_path) as txt:
        lines = txt.read().split('\n')
elif index_path.endswith('xls'):
    lines = []
    for xls_line in xls_to_dict(index_path):
        id_source = xls_line.get('ID')
        if id_source:
            lines.append(id_source)
elif index_path.endswith('xlsx'):
    lines = []
    for id_source in pd.read_excel(index_path).get('ID'):
        if id_source:
            lines.append(id_source)

for line in lines:
    id = ExtractKanId(line)
    path0 = tempname()
    raster_fin = fullpath(final_dir,id,'tif')
    if os.path.exists(raster_fin):
        print('FILE EXISTS: %s' % id)
        continue
    command = r'''gu_db_query -w "source='kanopus' and hashless_id='%s'" -d %s''' % (id, path0)
    os.system(command)
    dirs = FolderDirs(path0)
    if dirs:
        for folder in dirs:
            imgid = ExtractKanId(folder)
            raster = folder_paths(dirs[folder],1,'tif')[0]
            raster_fin = fullpath(final_dir,imgid,'tif')
            copyfile(raster, raster_fin)
            if dout is not None:
                copydir(dirs[folder], dout)
            print('WRITTEN: %s\n' % id)
    else:
        print('EMPTY DIRS: %s\n' % id)
    destroydir(path0)

if rdir and dout:
    rfiles = folder_paths(rdir,1,'tif')
    scroll(rfiles)
    for rfile in rfiles:
        rmask = tempname('json')
        RasterLimits(gdal.Open(rfile), reference=None, vector_path=rmask)
        if os.path.exists(rmask):
            f = r'%s\!_new' % (dout)
            suredir(f)
            DownloadKanopusFromS3(f, geom_path = rmask)
            print('UPLOADED: %s' % rfile)
        delete(rmask)


from typing import List

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        MAX_BUCKETS_SIZE = 1000

        begin, end = float("+inf"), float("-inf")
        for num in nums:
            if num > 0:
                begin = min(begin, num)
                end = max(end, num)

        # Gap at the beginning, 1 is the only possible answer
        if begin > 1:
            return 1

        while begin < end - 1:
            # Fit all elements into at most MAX_BUCKETS_SIZE buckets
            buckets_count = min((end - begin), MAX_BUCKETS_SIZE) + 1
            bucket_size = (end - begin) // (buckets_count - 1)
            buckets = [0] * buckets_count

            # Update counts of elements in each bucket
            for num in nums:
                if begin <= num <= end:
                    buckets[(num - begin) // bucket_size] += 1

            # Find the first bucket that has less than bucket_size elements
            for bucket, count in enumerate(buckets):
                if count < bucket_size:
                    # Update begin and end with this bucket to continue search
                    # for the missing element here
                    begin = begin + bucket * bucket_size
                    end = begin + bucket_size

                    # This is an element we're looking for, since we have 0
                    # elements in the bucket of size 1
                    if bucket_size == 1:
                        return begin

                    break

            # Bucket size is 1 and no gaps found
            if bucket_size == 1:
                break

        # No gaps found, return the element next to the last element
        return end + 1


# from math import pi,sin,cos
try :
  from OpenGL.GLUT import *
  from OpenGL.GL import *
  from OpenGL.GLU import *
except:
  print ("Error: PyOpenGL not installed properly !!")
  sys.exit()

from models import *

def car(size,rot_roue=0,dir_roue=0,rot_grue=0,slices=10,stacks=5):
    base_cylindre = size*0.05
    height_cylindre= size*0.25
    theta = rot_grue

    glPushMatrix()
    glTranslatef(0,0,-height_cylindre/2)  #pour avoir la voiture au milieu du repère

    #carrosserie
    glColor3f(0.5,0.2,0.6)
    glPushMatrix()
    glRotatef(180,0,1,0)
    create_disk(0,base_cylindre,slices,stacks)
    glPopMatrix()
    create_cylinder(base_cylindre,base_cylindre,height_cylindre,slices,stacks)
    glPushMatrix()
    glTranslatef(0,0,height_cylindre)
    create_cone(size*0.07,2*base_cylindre,slices,stacks)
    glPopMatrix()

    glPushMatrix()
    glTranslatef(base_cylindre,-base_cylindre*0.2,height_cylindre-size*0.05)
    glRotatef(90,0,1,0)

    #essieu avant
    glPushMatrix()
    glRotatef(rot_roue,0,0,1)
    glRotatef(dir_roue,0,1,0)
    create_roue(size*0.5)
    glTranslatef(0,0,-2*base_cylindre)
    create_roue(size*0.5)
    glPopMatrix()

    #essieu arriere
    glPushMatrix()
    glTranslatef(height_cylindre-size*0.1,0,0)
    glRotatef(rot_roue,0,0,1)
    create_roue(size*0.5)
    glTranslatef(0,0,-2*base_cylindre)
    create_roue(size*0.5)
    glPopMatrix()

    glPopMatrix()
    grue(size, theta)
    glPopMatrix()

    glPopMatrix()

def create_roue(size):
    sizeroue = size*0.6
    create_boulons(size)
    create_jante(sizeroue*0.1)
    glColor3f(0.0,0.0,0.0)
    glutSolidTorus(sizeroue*0.025,sizeroue*0.1,int(sizeroue*100),int(sizeroue*100))

def create_boulons(size):
    boulons = 4
    angle = 360./boulons

    # glColor3f(0.2,0.6,0.0)
    glColor3f(0.4,0.2,0.0)
    for i in range(boulons):
      glPushMatrix()
      glRotate(angle*i,0,0,1)
      glPushMatrix()
      glRotatef(180,0,1,0)
      glTranslatef(0.05*(size/2),0,size*0.005)
      create_disk(0,size*0.01)
      glPopMatrix()
      glPushMatrix()
      glTranslatef(0.05*(size/2),0,size*0.005)
      create_disk(0,size*0.01)
      glPopMatrix()
      glPopMatrix()

    #print("create_boulons")

def create_jante(size):
    glPushMatrix()
    glColor3f(0,0.7,0.2)
    create_disk(0,size)
    glRotatef(180,0,1,0)
    glTranslatef(0,0,size*0.05)
    create_disk(0,size)
    glPopMatrix()

def grue(size,theta,slices=10,stacks=5):

  base_cylindre = size*0.025
  height_cylindre= size*0.25/2 #cylindre carrosserie
  size_sphere = size*0.03
  glPushMatrix()
  glColor3f(0.2,0.5,0.7)
  glTranslatef(0,size*0.05,height_cylindre/2)
  create_cylinder(base_cylindre,base_cylindre,height_cylindre,slices,stacks)
  glPushMatrix()

  glRotatef(theta,0,0,1)

  # #articulation 3
  # glPushMatrix()
  # glTranslatef(0,height_cylindre*2+size_sphere,height_cylindre/2)
  # articulation(size_sphere,base_cylindre,height_cylindre,-90)
  # glPopMatrix()

  #articulation 2
  glPushMatrix()
  glTranslatef(0,height_cylindre+size_sphere+base_cylindre,height_cylindre/2)
  articulation(size_sphere,base_cylindre,height_cylindre,-90+theta)
  glPopMatrix()

  #articulation 1
  glPushMatrix()
  glTranslatef(0,base_cylindre*2,height_cylindre/2)
  articulation(size_sphere,base_cylindre,height_cylindre,-90)
  glPopMatrix()

  glPopMatrix()

  glPopMatrix()

def articulation(size,base_cylindre,height_cylindre,rotate=-90):
  glPushMatrix()
  glColor3f(0.9,0.5,0)
  glPushMatrix()
  glRotatef(rotate,1,0,0)
  create_cylinder(base_cylindre*0.8,base_cylindre*0.8,height_cylindre)
  glColor3f(0.1,0.9,0)
  glPopMatrix()
  create_sphere(size)

  glPopMatrix()


from tkinter import *
fields = 'Chords to Practice', 'Scales to Practice', 'PDF Destination'

def fetch(entries):
	toPrint = ""
	for entry in entries:
		toPrint += entry[1].get()
		toPrint += " 0000 "
	print(toPrint)

def makeform(root, fields):
   entries = []
   for field in fields:
      row = Frame(root)
      lab = Label(row, width=15, text=field, anchor='w')
      ent = Entry(row)
      row.pack(side=TOP, fill=X, padx=5, pady=5)
      lab.pack(side=LEFT)
      ent.pack(side=RIGHT, expand=YES, fill=X)
      entries.append((field, ent))
   return entries

if __name__ == '__main__':
   root = Tk()
   ents = makeform(root, fields)
   root.bind('<Return>', (lambda event, e=ents: fetch(e)))
   b1 = Button(root, text='Create PDF',
          command=(lambda e=ents: fetch(e)))
   b1.pack(side=LEFT, padx=5, pady=5)
   b2 = Button(root, text='Quit', command=root.quit)
   b3 = Button(root, text= 'Help', command = root.quit)
   b2.pack(side=LEFT, padx=5, pady=5)
   b3.pack(side=LEFT, padx = 5, pady = 5)
   root.mainloop()


#!/bin/python3

def quick_sort(ar, n):
    # Performs a quick sort using divide and conquer

    # Base case, array is already sorted if n is 1
    if n <= 1:
        return ar

    # Get the pivot element
    pivot = ar[0]

    # Sort the ar using the pivot element
    left, right = [], []
    for i in ar:
        if i < pivot:
            left.append(i)
        elif i > pivot:
            right.append(i)

    # Perform quick sort on the sub arrays
    left = quick_sort(left, len(left))
    right = quick_sort(right, len(right))

    # Combine the sorted arr
    sorted_ar = left + [pivot] + right
    [print(i, end=' ') for i in sorted_ar]
    print()
    return sorted_ar

# Get the size of array
n = int(input())
# Get the array
ar = list(map(int, input().split()))

quick_sort(ar, n)


""" class views for 2FA management """
from datetime import datetime, timedelta
import pyotp
import qrcode
import qrcode.image.svg

from django.contrib.auth import login
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponseBadRequest
from django.template.response import TemplateResponse
from django.shortcuts import redirect
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.debug import sensitive_post_parameters

from bookwyrm import forms, models
from bookwyrm.settings import DOMAIN, TWO_FACTOR_LOGIN_MAX_SECONDS
from bookwyrm.views.helpers import set_language

# pylint: disable= no-self-use
@method_decorator(login_required, name="dispatch")
class Edit2FA(View):
    """change 2FA settings as logged in user"""

    def get(self, request):
        """Two Factor auth page"""
        data = {"form": forms.ConfirmPasswordForm()}
        return TemplateResponse(request, "preferences/2fa.html", data)

    @method_decorator(sensitive_post_parameters("password"))
    def post(self, request):
        """check the user's password"""
        form = forms.ConfirmPasswordForm(request.POST, instance=request.user)
        if not form.is_valid():
            data = {"form": form}
            return TemplateResponse(request, "preferences/2fa.html", data)
        data = self.create_qr_code(request.user)
        qr_form = forms.Confirm2FAForm()
        data = {
            "password_confirmed": True,
            "qrcode": data[0],
            "code": data[1],
            "form": qr_form,
        }
        return TemplateResponse(request, "preferences/2fa.html", data)

    def create_qr_code(self, user):
        """generate and save a qr code for 2FA"""
        otp_secret = pyotp.random_base32()
        # save the secret to the user record - we'll need it to check codes in future
        user.otp_secret = otp_secret
        user.save(broadcast=False, update_fields=["otp_secret"])
        # now we create the qr code
        provisioning_url = pyotp.totp.TOTP(otp_secret).provisioning_uri(
            name=user.localname, issuer_name=DOMAIN
        )
        qr_code = qrcode.QRCode(image_factory=qrcode.image.svg.SvgPathImage)
        qr_code.add_data(provisioning_url)
        qr_code.make(fit=True)
        img = qr_code.make_image(attrib={"fill": "black"})
        return [
            str(img.to_string(), "utf-8"),
            otp_secret,
        ]  # to_string() returns a byte string

@method_decorator(login_required, name="dispatch")
class Confirm2FA(View):
    """confirm user's 2FA settings"""

    def post(self, request):
        """confirm the 2FA works before requiring it"""
        form = forms.Confirm2FAForm(request.POST, instance=request.user)

        if not form.is_valid():
            data = {
                "password_confirmed": True,
                "qrcode": Edit2FA.create_qr_code(self, request.user),
                "form": form,
            }
            return TemplateResponse(request, "preferences/2fa.html", data)

        # set the user's 2FA setting on
        request.user.two_factor_auth = True
        request.user.save(broadcast=False, update_fields=["two_factor_auth"])
        data = {"form": form, "success": True}
        return TemplateResponse(request, "preferences/2fa.html", data)

@method_decorator(login_required, name="dispatch")
class Disable2FA(View):
    """Turn off 2FA on this user account"""

    def get(self, request):
        """Confirmation page to turn off 2FA"""
        return TemplateResponse(request, "preferences/disable-2fa.html")

    def post(self, request):
        """Turn off 2FA on this user account"""
        request.user.two_factor_auth = False
        request.user.save(broadcast=False, update_fields=["two_factor_auth"])
        data = {"form": forms.ConfirmPasswordForm(), "success": True}
        return TemplateResponse(request, "preferences/2fa.html", data)

class LoginWith2FA(View):
    """Check 2FA code matches before allowing login"""

    def get(self, request):
        """Display 2FA form"""
        data = {"form": forms.Confirm2FAForm()}
        return TemplateResponse(request, "two_factor_auth/two_factor_login.html", data)

    def post(self, request):
        """Check 2FA code and allow/disallow login"""
        try:
            user = models.User.objects.get(username=request.session.get("2fa_user"))
        except ObjectDoesNotExist:
            request.session["2fa_auth_time"] = 0
            return HttpResponseBadRequest("Invalid user")

        session_time = (
            int(request.session["2fa_auth_time"])
            if request.session["2fa_auth_time"]
            else 0
        )
        elapsed_time = datetime.now() - datetime.fromtimestamp(session_time)
        form = forms.Confirm2FAForm(request.POST, instance=user)
        # don't allow the login credentials to last too long before completing login
        if elapsed_time > timedelta(seconds=TWO_FACTOR_LOGIN_MAX_SECONDS):
            request.session["2fa_user"] = None
            request.session["2fa_auth_time"] = 0
            return redirect("/")
        if not form.is_valid():
            data = {"form": form, "2fa_user": user}
            return TemplateResponse(
                request, "two_factor_auth/two_factor_login.html", data
            )

        # is this a reactivate? let's go for it
        if not user.is_active and user.allow_reactivation:
            user.reactivate()
        # log the user in - we are bypassing standard login
        login(request, user)
        user.update_active_date()
        return set_language(user, redirect("/"))

@method_decorator(login_required, name="dispatch")
class GenerateBackupCodes(View):
    """Generate and display backup 2FA codes"""

    def get(self, request):
        """Generate and display backup 2FA codes"""
        data = {"backup_codes": self.generate_backup_codes(request.user)}
        return TemplateResponse(request, "preferences/2fa.html", data)

    def generate_backup_codes(self, user):
        """generate fresh backup codes for 2FA"""

        # create fresh hotp secrets and count
        hotp_secret = pyotp.random_base32()
        user.hotp_count = 0
        # save the secret to the user record
        user.hotp_secret = hotp_secret
        user.save(broadcast=False, update_fields=["hotp_count", "hotp_secret"])

        # generate codes
        hotp = pyotp.HOTP(hotp_secret)
        counter = 0
        codes = []
        while counter < 10:
            codes.append(hotp.at(counter))
            counter = counter + 1

        return codes

class Prompt2FA(View):
    """Alert user to the existence of 2FA"""

    def get(self, request):
        """Alert user to the existence of 2FA"""
        return TemplateResponse(request, "two_factor_auth/two_factor_prompt.html")


from django.db import transaction
from rest_framework import serializers

from core.models import User
from goals.models import GoalCategory, Goal, GoalComment, Board, BoardParticipant
from core.serializers import UserSerializer

class GoalCategoryCreateSerializer(serializers.ModelSerializer):
    """Сериализатор для создания категории цели."""
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = GoalCategory
        read_only_fields = ("id", "created", "updated", "user")
        fields = "__all__"

    def create(self, validated_data):
        """Создаем категорию цели и назначаем ее текущему пользователю."""
        user = validated_data.pop("user")
        category = GoalCategory.objects.create(user=user, **validated_data)
        return category

    def validate(self, attrs):
        """Проверка: текущий пользователь должен быть владельцем доски."""
        user = self.context['request'].user
        is_owner = BoardParticipant.objects.filter(
            user=user,
            board=attrs['board'],
            role=BoardParticipant.Role.owner
        ).exists()

        if not is_owner:
            raise serializers.ValidationError("You are not owner of this board")
        return attrs

class GoalCreateSerializer(serializers.ModelSerializer):
    """Сериализатор для создания целей."""
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Goal
        read_only_fields = ("id", "created", "updated", "user")
        fields = "__all__"

    def validate_category(self, value):
        """Валидация: проверка что пользователь является владельцем или автором доски."""
        if value.is_deleted:
            raise serializers.ValidationError("not allowed in deleted category")
        if not BoardParticipant.objects.filter(
                user=self.context["request"].user,
                board=value.board,
                role__in=[BoardParticipant.Role.owner, BoardParticipant.Role.writer]
        ).exists():
            raise serializers.ValidationError("not owner or writer of board")
        return value

class GoalCategorySerializer(serializers.ModelSerializer):
    """Сериализатор для представления категории цели."""
    user = UserSerializer(read_only=True)
    board = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = GoalCategory
        fields = "__all__"
        read_only_fields = ("id", "created", "updated", "user")

class GoalSerializer(serializers.ModelSerializer):
    """Сериализатор для представления цели."""
    user = UserSerializer(read_only=True)

    class Meta:
        model = Goal
        fields = "__all__"
        read_only_fields = ("id", "created", "updated", "user", 'title', 'description')

class GoalCommentCreateSerializer(serializers.ModelSerializer):
    """Сериализатор для создания комментариев к цели."""
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = GoalComment
        read_only_fields = ("id", "created", "updated", "user")
        fields = "__all__"

class GoalCommentSerializer(serializers.ModelSerializer):
    """Сериализатор для представления комментария к цели."""
    user = UserSerializer(read_only=True)

    class Meta:
        model = GoalComment
        fields = "__all__"
        read_only_fields = ("id", "created", "updated", "user")

class BoardCreateSerializer(serializers.ModelSerializer):
    """Сериализатор для создания доски."""
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Board
        read_only_fields = ("id", "created", "updated")
        fields = "__all__"

    def create(self, validated_data):
        """Создаем доску и добавляем текущего пользователя в качестве владельца."""
        user = validated_data.pop("user")
        board = Board.objects.create(**validated_data)
        board.participants.create(user=user, role=BoardParticipant.Role.owner)
        return board

class BoardParticipantSerializer(serializers.ModelSerializer):
    """Сериализатор для представления участника доски."""
    role = serializers.ChoiceField(
        required=True, choices=BoardParticipant.Role.choices
    )
    user = serializers.SlugRelatedField(
        slug_field="username", queryset=User.objects.all()
    )

    class Meta:
        model = BoardParticipant
        fields = "__all__"
        read_only_fields = ("id", "created", "updated", "board")

class BoardSerializer(serializers.ModelSerializer):
    """Сериализатор для представления доски."""
    participants = BoardParticipantSerializer(many=True)
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Board
        fields = "__all__"
        read_only_fields = ("id", "created", "updated")

    def update(self, instance, validated_data):
        """Обновляем информацию доски и участников."""
        owner = validated_data.pop("user")
        new_participants = validated_data.pop("participants")
        new_by_id = {part["user"].id: part for part in new_participants}

        old_participants = instance.participants.exclude(user=owner)
        print("Old participants before processing: ", old_participants)
        with transaction.atomic():
            for old_participant in old_participants:
                if old_participant.user_id not in new_by_id:
                    old_participant.delete()
                else:
                    if (
                            old_participant.role
                            != new_by_id[old_participant.user_id]["role"]
                    ):
                        old_participant.role = new_by_id[old_participant.user_id][
                            "role"
                        ]
                        old_participant.save()
                    new_by_id.pop(old_participant.user_id)
            for new_part in new_by_id.values():
                BoardParticipant.objects.create(
                    board=instance, user=new_part["user"], role=new_part["role"]
                )

            instance.title = validated_data["title"]
            instance.save()

        return instance

class BoardListSerializer(serializers.ModelSerializer):
    """Сериализатор для представления списка досок."""
    class Meta:
        model = Board
        fields = "__all__"
        # fields = ['id', 'created', 'updated', 'title', 'is_deleted']


import jax
import jax.numpy as jnp

from functools import wraps
from jax import vmap
from typing import Callable, Optional, Union

from piscis.utils import smooth_sum_pool

def smoothf1_loss(
        deltas_pred: jax.Array,
        labels_pred: jax.Array,
        deltas: jax.Array,
        labels: jax.Array,
        dilation_iterations: int,
        max_distance: float,
        epsilon: float = 1e-7
) -> jax.Array:

    """Compute the SmoothF1 loss.

    Parameters
    ----------
    deltas_pred : jax.Array
        Predicted subpixel displacements.
    labels_pred : jax.Array
        Predicted binary labels.
    deltas : jax.Array
        Ground truth subpixel displacements.
    labels : jax.Array
        Ground truth binary labels.
    dilation_iterations : int
        Number of iterations used to dilate ground truth labels.
    max_distance : float
        Maximum distance for matching predicted and ground truth subpixel displacements.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.

    Returns
    -------
    smoothf1 : jax.Array
        SmoothF1 loss.
    """

    # Use labels as the support for deltas_pred.
    deltas_pred = labels * deltas_pred

    # Squeeze the channel dimension in labels arrays.
    labels_pred = labels_pred[:, :, 0]
    labels = labels[:, :, 0]

    # Apply deltas_pred to labels_pred.
    kernel_size = (2 * dilation_iterations + 1, ) * 2
    pooled_labels = smooth_sum_pool(deltas_pred, labels_pred, 0.5, kernel_size)
    distances = jnp.linalg.norm(deltas_pred - deltas, axis=-1)
    matches = jnp.maximum(1 - distances / max_distance, 0.0)

    # Estimate the number of true positives, false positives, and false negatives.
    tp = jnp.sum(pooled_labels * matches)
    fp = jnp.sum(pooled_labels) - tp
    fn = jnp.sum(labels) - tp

    # Compute the SmoothF1 loss.
    smoothf1 = -2 * tp / (2 * tp + fp + fn + epsilon)

    return smoothf1

def dice_loss(
        y_pred: jax.Array,
        y: jax.Array,
        epsilon: float = 1e-7
) -> jax.Array:

    """Compute the Dice loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted binary labels.
    y : jax.Array
        Ground truth binary labels.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.

    Returns
    -------
    dl : jax.Array
        Dice loss.
    """

    intersection = jnp.sum(y_pred * y)
    dl = - (2.0 * intersection) / (jnp.sum(y_pred) + jnp.sum(y) + epsilon)

    return dl

def masked_l2_loss(
        y_pred: jax.Array,
        y: jax.Array,
        mask: jax.Array
) -> jax.Array:

    """Compute the L2 loss over masked pixels.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted values.
    y : jax.Array
        Ground truth values.
    mask : jax.Array
        Binary mask where 1 indicates pixels to compute the L2 loss and 0 indicates pixels to ignore.

    Returns
    -------
    rmse : jax.Array
        Masked root-mean-square error.
    """

    l2 = jnp.sum(jnp.linalg.norm(y_pred - y, axis=-1) * mask) / jnp.sum(mask)

    return l2

def mse_loss(
        y_pred: jax.Array,
        y: jax.Array,
) -> jax.Array:

    """Compute the mean squared error.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted values.
    y : jax.Array
        Ground truth values.

    Returns
    -------
    mse : jax.Array
        Mean squared error.
    """

    mse = (y - y_pred) ** 2
    mse = reduce_loss(mse, 'mean')

    return mse

def bce_loss(
        y_pred: jax.Array,
        y: jax.Array,
        pos_weight: Union[float, jax.Array] = 1.0,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the binary cross entropy loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted binary labels.
    y : jax.Array
        Ground truth binary labels.
    pos_weight : Union[float, jax.Array], optional
        Weight for positive class. Default is 1.0.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bce : jax.Array
        Binary cross entropy loss.
    """

    bce = -(pos_weight * jnp.log(y_pred + epsilon) * y + jnp.log((1 - y_pred) + epsilon) * (1 - y))
    bce = reduce_loss(bce, reduction)

    return bce

def bce_with_logits_loss(
        y_pred: jax.Array,
        y: jax.Array,
        pos_weight: Union[float, jax.Array] = 1.0,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the binary cross entropy loss with logits.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    pos_weight : Union[float, jax.Array], optional
        Weight for positive class. Default is 1.0.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bce : jax.Array
        Binary cross entropy loss.
    """

    neg_abs = -jnp.abs(y_pred)
    bce = jnp.maximum(y_pred, 0) - y_pred * y + jnp.log(1 + jnp.exp(neg_abs))
    bce = jnp.where(y, pos_weight * bce, bce)
    bce = reduce_loss(bce, reduction)

    return bce

def weighted_bce_loss(
        y_pred: jax.Array,
        y: jax.Array,
        alpha: float = 1.0,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the weighted binary cross entropy loss.

    y_pred : jax.Array
        Predicted binary labels.
    y : jax.Array
        Ground truth binary labels.
    alpha : float, optional
        Exponent factor applied to the inverse class weight. Default is 1.0.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bce : jax.Array
        Weighted binary cross entropy loss.
    """

    pos_weight = _inverse_class_weight(y, alpha=alpha, epsilon=epsilon)
    bce = bce_loss(y_pred, y, pos_weight=pos_weight, epsilon=epsilon, reduction=reduction)

    return bce

def weighted_bce_with_logits_loss(
        y_pred: jax.Array,
        y: jax.Array,
        alpha: float = 1.0,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the weighted binary cross entropy loss with logits.

    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    alpha : float, optional
        Exponent factor applied to the inverse class weight. Default is 1.0.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bce : jax.Array
        Weighted binary cross entropy loss.
    """

    pos_weight = _inverse_class_weight(y, alpha=alpha, epsilon=epsilon)
    bce = bce_with_logits_loss(y_pred, y, pos_weight=pos_weight, reduction=reduction)

    return bce

def cb_bce_loss(
        y_pred: jax.Array,
        y: jax.Array,
        beta: float = 0.999,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the class-balanced binary cross entropy loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted binary labels.
    y : jax.Array
        Ground truth binary labels.
    beta : float, optional
        Hyperparameter for computing the effective number of samples. Default is 0.999.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bce : jax.Array
        Class-balanced binary cross entropy loss.

    References
    ----------
    .. [1] Cui, Yin, et al. "Class-balanced loss based on effective number of samples." Proceedings of the IEEE/CVF
           conference on computer vision and pattern recognition. 2019.
    """

    pos_weight = _class_balanced_weight(y, beta=beta)
    bce = bce_loss(y_pred, y, pos_weight=pos_weight, epsilon=epsilon, reduction=reduction)

    return bce

def cb_bce_with_logit_loss(
        y_pred: jax.Array,
        y: jax.Array,
        beta: float = 0.999,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the class-balanced binary cross entropy loss with logits.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    beta : float, optional
        Hyperparameter for computing the effective number of samples. Default is 0.999.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bce : jax.Array
        Class-balanced binary cross entropy loss.

    References
    ----------
    .. [1] Cui, Yin, et al. "Class-balanced loss based on effective number of samples." Proceedings of the IEEE/CVF
           conference on computer vision and pattern recognition. 2019.
    """

    pos_weight = _class_balanced_weight(y, beta=beta)
    bce = bce_with_logits_loss(y_pred, y, pos_weight=pos_weight, reduction=reduction)

    return bce

def la_loss(
        y_pred: jax.Array,
        y: jax.Array,
        tau: float = 1.0,
        reduction: Optional[str] = 'mean'
):

    """Compute the logit-adjusted loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    tau : float, optional
        Hyperparameter for computing the logit adjustment. Default is 1.0.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    la : jax.Array
        Logit-adjusted loss.

    References
    ----------
    .. [1] Menon, Aditya Krishna, et al. "Long-tail learning via logit adjustment." arXiv preprint arXiv:2007.07314
           (2020).
    """

    y_pred = _logit_adjustment(y_pred, y, tau=tau)
    la = bce_with_logits_loss(y_pred, y, reduction=reduction)

    return la

def vs_loss(
        y_pred: jax.Array,
        y: jax.Array,
        tau: float = 1.0,
        gamma: float = 0.25,
        reduction: Optional[str] = 'mean'
):

    """Compute the vector-scaling loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    tau : float, optional
        Hyperparameter for computing the additive logit adjustment. Default is 1.0.
    gamma : float, optional
        Hyperparameter for computing the multiplicative logit adjustment. Default is 0.25.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    vs : jax.Array
        Vector-scaling loss.

    References
    ----------
    .. [1] Kini, Ganesh Ramachandra, et al. "Label-imbalanced and group-sensitive classification under
           overparameterization." Advances in Neural Information Processing Systems 34 (2021): 18970-18983.
    """

    y_pred = _vector_scaling(y_pred, y, tau=tau, gamma=gamma)
    vs = bce_with_logits_loss(y_pred, y, reduction=reduction)

    return vs

def binary_focal_loss(
        y_pred: jax.Array,
        y: jax.Array,
        gamma: float = 2,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the binary focal loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted binary labels.
    y : jax.Array
        Ground truth binary labels.
    gamma : float, optional
        Hyperparameter for computing the binary focal loss. Default is 2.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    bf : jax.Array
        Binary focal loss.

    References
    ----------
    .. [1] Lin, Tsung-Yi, et al. "Focal loss for dense object detection." Proceedings of the IEEE international
           conference on computer vision. 2017.
    """

    bf = -((1 - y_pred) ** gamma * jnp.log(y_pred + epsilon) * y +
           y_pred ** gamma * jnp.log((1 - y_pred) + epsilon) * (1 - y))
    bf = reduce_loss(bf, reduction=reduction)

    return bf

def ce_loss(
        y_pred: jax.Array,
        y: jax.Array,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the cross entropy loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted labels.
    y : jax.Array
        Ground truth labels.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    ce : jax.Array
        Cross entropy loss.
    """

    ce = -(jnp.log(y_pred + epsilon) * y)
    ce = reduce_loss(ce, reduction=reduction)

    return ce

def focal_loss(
        y_pred: jax.Array,
        y: jax.Array,
        gamma: float = 2,
        epsilon: float = 1e-7,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Compute the focal loss.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted labels.
    y : jax.Array
        Ground truth labels.
    gamma : float, optional
        Hyperparameter for computing the focal loss. Default is 2.
    epsilon : float, optional
        Small constant for numerical stability. Default is 1e-7.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    f : jax.Array
        Focal loss.

    References
    ----------
    .. [1] Lin, Tsung-Yi, et al. "Focal loss for dense object detection." Proceedings of the IEEE international
           conference on computer vision. 2017.
    """

    f = -((1 - y_pred) ** gamma * jnp.log(y_pred + epsilon) * y)
    f = reduce_loss(f, reduction=reduction)

    return f

def _inverse_class_weight(
        y: jax.Array,
        alpha: float,
        epsilon: float
) -> jax.Array:

    """Compute the inverse class weight.

    Parameters
    ----------
    y : jax.Array
        Ground truth binary labels.
    alpha : float
        Exponent of the inverse class weight.
    epsilon : float
        Small constant for numerical stability.

    Returns
    -------
    pos_weight : jax.Array
        Inverse class weight.
    """

    pos_weight = (jnp.sum(~y) / (jnp.sum(y) + epsilon)) ** alpha

    return pos_weight

def _class_balanced_weight(
        y: jax.Array,
        beta: float
) -> jax.Array:

    """Compute the class-balanced weight.

    Parameters
    ----------
    y : jax.Array
        Ground truth binary labels.
    beta : float
        Hyperparameter for computing the effective number of samples.

    Returns
    -------
    pos_weight : jax.Array
        Class-balanced weight.

    References
    ----------
    .. [1] Cui, Yin, et al. "Class-balanced loss based on effective number of samples." Proceedings of the IEEE/CVF
           conference on computer vision and pattern recognition. 2019.
    """

    pos_weight = (1 - beta ** jnp.sum(~y)) / (1 - beta ** jnp.sum(y))

    return pos_weight

def _logit_adjustment(
        y_pred: jax.Array,
        y: jax.Array,
        tau: float
) -> jax.Array:

    """Apply logit adjustment to the predicted logits.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    tau : float
        Hyperparameter for computing the logit adjustment.

    Returns
    -------
    y_pred : jax.Array
        Adjusted logits.

    References
    ----------
    .. [1] Menon, Aditya Krishna, et al. "Long-tail learning via logit adjustment." arXiv preprint arXiv:2007.07314
           (2020).
    """

    # Compute class sizes.
    num_pos = jnp.sum(y)
    num_neg = jnp.sum(~y)
    num_tot = num_pos + num_neg

    # Compute logit adjustments.
    iota_pos = tau * jnp.log(num_pos / num_tot)
    iota_neg = tau * jnp.log(num_neg / num_tot)

    # Apply logit adjustments.
    y_pred = jnp.where(y, y_pred + iota_pos, y_pred + iota_neg)

    return y_pred

def _vector_scaling(
        y_pred: jax.Array,
        y: jax.Array,
        tau: float,
        gamma: float
) -> jax.Array:

    """Apply vector scaling to the predicted logits.

    Parameters
    ----------
    y_pred : jax.Array
        Predicted logits.
    y : jax.Array
        Ground truth binary labels.
    tau : float
        Hyperparameter for computing the additive logit adjustment.
    gamma : float
        Hyperparameter for computing the multiplicative logit adjustment.

    Returns
    -------
    y_pred : jax.Array
        Adjusted logits.

    References
    ----------
    .. [1] Kini, Ganesh Ramachandra, et al. "Label-imbalanced and group-sensitive classification under
           overparameterization." Advances in Neural Information Processing Systems 34 (2021): 18970-18983.
    """

    # Compute class sizes.
    num_pos = jnp.sum(y)
    num_neg = jnp.sum(~y)
    num_tot = num_pos + num_neg
    num_max = jnp.maximum(num_pos, num_neg)

    # Compute additive logit adjustments.
    iota_pos = tau * jnp.log(num_pos / num_tot)
    iota_neg = tau * jnp.log(num_neg / num_tot)

    # Compute multiplicative logit adjustments.
    delta_pos = (num_pos / num_max) ** gamma
    delta_neg = (num_neg / num_max) ** gamma

    # Apply vector scaling.
    y_pred = jnp.where(y, delta_pos * y_pred + iota_pos, delta_neg * y_pred + iota_neg)

    return y_pred

def wrap_loss_fn(
        loss_fn: Callable,
        axis: int = 0,
        reduction: Optional[str] = 'mean'
) -> Callable:
    """Wrap a loss function for vectorization and loss reduction.

    Parameters
    ----------
    loss_fn : Callable
        Loss function.
    axis : int, optional
        Axis to vectorize over. Default is 0.
    reduction : Optional[str], optional
        Loss reduction method. Default is 'mean'.

    Returns
    -------
    wrapped_loss_fn : Callable
        Wrapped loss function.
    """

    @wraps(loss_fn)
    def wrapped_loss_fn(*args):

        # Build in_axes dynamically from the arguments.
        in_axes = tuple(axis if isinstance(arg, jax.Array) else None for arg in args)

        # Vectorize the loss function.
        loss = vmap(loss_fn, in_axes=in_axes)(*args)

        # Reduce the loss.
        loss = reduce_loss(loss, reduction=reduction)

        return loss

    return wrapped_loss_fn

def reduce_loss(
        loss: jax.Array,
        reduction: Optional[str] = 'mean'
) -> jax.Array:

    """Reduce the loss.

    Parameters
    ----------
    loss : jax.Array
        Loss array to be reduced.
    reduction : Optional[str], optional
        Loss reduction method. Supported methods are 'mean' and 'sum'. Default is 'mean'.

    Returns
    -------
    loss : jax.Array
        Reduced loss.

    Raises
    ------
    ValueError
        If the `reduction` method is not supported.
    """

    if reduction == 'mean':
        loss = jnp.mean(loss)
    elif reduction == 'sum':
        loss = jnp.sum(loss)
    else:
        raise ValueError("Reduction method is not supported.")

    return loss


from src.entities import Entity
import pygame

class Npc(Entity):

    def __init__(self, name, nb_points, dialog):
        super().__init__(name, 0, 0)
        self.nb_points = nb_points
        self.dialog = dialog
        self.points = []
        self.name = name
        self.speed = 1
        self.current_point = 0

    def move(self):
        current_point = self.current_point
        target_point = self.current_point + 1

        if target_point >= self.nb_points:
            target_point = 0

        current_rect = self.points[current_point]
        target_rect = self.points[target_point]

        if current_rect.y < target_rect.y and abs(current_rect.x - target_rect.x) < 3:
            self.move_down()
        elif current_rect.y > target_rect.y and abs(current_rect.x - target_rect.x) < 3:
            self.move_up()
        elif current_rect.x < target_rect.x and abs(current_rect.y - target_rect.y) < 3:
            self.move_right()
        elif current_rect.x > target_rect.x and abs(current_rect.y - target_rect.y) < 3:
            self.move_left()

        if self.rect.colliderect(target_rect):
            self.current_point = target_point

    def teleport_spawn(self):
        location = self.points[self.current_point]
        self.position[0] = location.x
        self.position[1] = location.y
        self.save_location()

    def load_points(self, tmx_data):
        for num in range(1, self.nb_points+1):
            point = tmx_data.get_object_by_name(f"{self.name}_path{num}")
            rect = pygame.Rect(point.x, point.y, point.width, point.height)
            self.points.append(rect)


import lmctl.project.handlers.interface as handlers_api
import lmctl.project.testing as project_testing

class TestProcessError(Exception):
    pass

class TestProcess:

    def __init__(self, pkg_content, options, journal, env_sessions):
        self.pkg_content = pkg_content
        self.journal = journal
        self.options = options
        self.env_sessions = env_sessions

    def execute(self):
        return TestWorker(self.pkg_content, self.options, self.journal, self.env_sessions).work()

class TestWorker:

    def __init__(self, pkg_content, options, journal, env_sessions):
        self.pkg_content = pkg_content
        self.journal = journal
        self.options = options
        self.env_sessions = env_sessions

    def work(self):
        child_test_reports = self.__test_child_content()
        test_report = self.__test_content()
        return project_testing.PkgTestReport(self.pkg_content.meta.name, self.pkg_content.meta.full_name, test_report, child_test_reports)

    def __filter_selected_tests(self):
        return self.options.selected_tests

    def __test_content(self):
        self.journal.section('Execute Tests')
        try:
            test_report = self.pkg_content.handler.execute_tests(self.journal, self.env_sessions, self.__filter_selected_tests())
            return test_report
        except handlers_api.ContentHandlerError as e:
            raise TestProcessError(str(e)) from e

    def __test_child_content(self):
        child_reports = []
        subcontents = self.pkg_content.subcontents
        for subcontent in subcontents:
            self.journal.subproject(subcontent.meta.name)
            test_report = TestWorker(subcontent, self.options, self.journal, self.env_sessions).work()
            child_reports.append(test_report)
            self.journal.subproject_end(subcontent.meta.name)
        return child_reports


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

import os
import datetime

from django.conf import settings
from django.db import models
from django.db.models import Sum, Count
from django.db.models.signals import pre_save, post_save, post_delete
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from django.template.defaultfilters import filesizeformat
from django.core.urlresolvers import reverse

from .constants import *
from .markup import render_markup
from .exceptions import *
from app_settings import *

#from .model_fields import RestrictedFileField, RestrictedImageField

def forum_profile_for(user):
    instance, created = Profile.objects.get_or_create(user=user)
    return instance

# --- Custom managers
class ActiveManager(models.Manager):
    def active(self):
        return super(ActiveManager, self).filter(is_active=True)

# --- Abstract classes
class DatedModel(models.Model):
    creation_time = models.DateTimeField(auto_now_add=True)
    modification_time = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class ActiveModel(models.Model):
    is_active = models.BooleanField(verbose_name='Is active?', default=True)
    objects = ActiveManager()

    class Meta:
        abstract = True

class MessageModel(models.Model):
    """
    Used for models that should have a formatted message attached.
    """
    message = models.TextField(blank=True, null=True)
    message_format = models.IntegerField(
        choices=MARKUP_CHOICES,
        default=MARKUP)
    html = models.TextField(editable=False, blank=True, null=True)

    class Meta:
        abstract = True

# --- End abstract classes

class Profile(DatedModel, ActiveModel, MessageModel):
    """
    Forum user profile
    """
    user = models.OneToOneField(User, related_name="forum_profile", primary_key=True)
    nickname = models.SlugField(max_length=50, unique=True, null=False)
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES, default=GENDER_UNDEFINED)
    avatar = models.ImageField(
        verbose_name=_('Avatar image'),
        help_text=_('Up to %s') % filesizeformat(AVATAR_MAX_SIZE),
        upload_to='uploads/forum/profiles/avatar/', blank=True, null=True)
    flag = models.IntegerField(default=0, help_text=_('System wise attribute'))

    reputation = models.PositiveIntegerField(default=0)
    threads_counter = models.PositiveIntegerField(default=0)
    replies_counter = models.PositiveIntegerField(default=0)

    class Meta:
        db_table = 'forum_profile'
        verbose_name = 'Profile'
        verbose_name_plural = 'Profiles'
        ordering = ['-creation_time']

    def __unicode__(self):
        return unicode(self.nickname or self.user)

    @models.permalink
    def get_absolute_url(self):
        return 'forum:profile', [self.nickname]

    def set_flag(self, flag):
        self.flag = self.flag | flag

    def get_avatar_url(self):
        if self.avatar:
            return self.avatar.url
        return settings.STATIC_URL + "img/forum/avatar/dull_face.png"

    def update_threads_counter(self):
        self.threads_counter = self.threads.count()

    def update_replies_counter(self):
        self.replies_counter = self.replies.count()

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):

        # TODO: request nickname on registering
        if not self.nickname:
            self.nickname = self.user.username

        return super(Profile, self).save(force_insert, force_update, using, update_fields)

class Category(DatedModel, ActiveModel):
    """
    Used to sort the forum
    """
    name = models.CharField(max_length=50)
    slug = models.SlugField(max_length=50, unique=True, primary_key=True)

    class Meta:
        db_table = 'forum_category'
        verbose_name = 'Category'
        verbose_name_plural = 'Categories'
        ordering = ['slug']

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return 'forum:category', [self.slug]

class Forum(DatedModel, ActiveModel):
    category = models.ForeignKey(
        Category, help_text='Set to show forum in the index page',
        related_name='forum_set', blank=True, null=True)
    parent = models.ForeignKey('self', related_name='children', blank=True, null=True, default=None)
    name = models.CharField(verbose_name=_("Forum name"), max_length=100)
    description = models.CharField(
        verbose_name=_("Description"),
        max_length=255, blank=True, null=True)
    moderation = models.ManyToManyField(
        'Profile', related_name="moderation",
        blank=True, null=True)
    last_thread = models.OneToOneField(
        'Thread', related_name="as_last_thread_for",
        blank=True, null=True, editable=False)

    threads_counter = models.PositiveIntegerField(_("Threads counter"), default=0, editable=False)
    replies_counter = models.PositiveIntegerField(_("Replies counter"), default=0, editable=False)

    class Meta:
        db_table = 'forum'
        verbose_name = 'Forum'
        verbose_name_plural = 'Forums'
        ordering = ['-creation_time']

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return 'forum:expose', [self.id]

    def parent_tree(self):
        parent_list = []
        parent = self.parent

        while parent is not None:
            parent_list.append(parent)
            parent = parent.parent

        return parent_list

    def latest_thread(self):
        try:
            return self.threads.active().latest('creation_time')
        except Thread.DoesNotExist:
            return None

    def check_permission(self, request):
        if self.access_filter == PERMISSION_LOGGED and not request.user.is_authenticated():
            raise LoginRequiredException()

    def update_threads_counter(self):
        self.threads_counter = self.threads.count()

    def update_replies_counter(self):
        agg = self.threads.aggregate(Sum('replies_counter'))
        self.replies_counter = agg['replies_counter__sum']

class Thread(DatedModel, ActiveModel):
    _order_by = ('title', 'author', 'replies_counter', 'view_counter')

    author = models.ForeignKey(Profile, related_name='threads')
    forum = models.ForeignKey(Forum, related_name='threads')
    status = models.IntegerField(
        choices=THREAD_STATUS_CH,
        default=THREAD_STATUS_OPEN)
    title = models.CharField(verbose_name=_('Title'), max_length=255)
    image = models.ImageField(
        verbose_name=_('Head image'), help_text='Shown at the threads top',
        #validators=[max_upload_size(MAX_THREAD_IMAGE_SIZE)],
        upload_to='uploads/forum/threads/image/',
        blank=True, null=True)
    attachment = models.FileField(
        verbose_name=_('Attachment'), help_text='Associate a file with this threads',
        #validators=[max_upload_size(MAX_THREAD_ATTACH_SIZE), virus_check],
        upload_to='uploads/forum/threads/attachment/',
        blank=True, null=True)

    views_counter = models.PositiveIntegerField(
        _("Views counter"), default=0, editable=False)
    replies_counter = models.PositiveIntegerField(
        _("Replies counter"), default=0, editable=False)
    authors_counter = models.PositiveIntegerField(
        _("Authors counter"), default=0, editable=False)

    class Meta:
        db_table = 'forum_thread'
        verbose_name = ugettext('Thread')
        verbose_name_plural = ugettext('Threads')
        ordering = ['-creation_time']

    def __unicode__(self):
        return self.title

    @models.permalink
    def get_absolute_url(self):
        return 'forum:thread', (self.forum_id, self.id), {}

    def get_attachment_basename(self):
        return os.path.basename(self.attachment.name)

    def update_views(self, request):
        """
        Updates the threads visit counter
        """
        ip_address = request.META['REMOTE_ADDR']
        return Views.objects.get_or_create(
            thread=self, ip_address=ip_address,
            date=datetime.date.today())

    def update_views_counter(self):
        self.views_counter = self.views.count()

    def update_replies_counter(self):
        self.replies_counter = self.replies.active().count()

    def update_authors_counter(self):
        agg = self.replies.active().aggregate(Count('author'))
        self.authors_counter = agg['author__count']

class Reply(DatedModel, ActiveModel, MessageModel):
    author = models.ForeignKey(Profile, related_name='replies')
    forum = models.ForeignKey(Forum, related_name='replies')
    thread = models.ForeignKey(Thread, related_name='replies')
    avg_rating = models.PositiveIntegerField(_('Average rating'), default=0)

    class Meta:
        db_table = 'forum_reply'
        verbose_name = ugettext('Reply')
        verbose_name_plural = ugettext('Replies')
        ordering = ['creation_time']

    def get_absolute_url(self):
        replies = self.thread.replies.active()
        page = int(list(replies).index(self) / PAGINATE_THREADS_BY) + 1
        return "%s?page=%d" % (reverse('forum:thread', args=[self.forum.id, self.thread.id]), page)

    def update_reputation(self):
        agg = self.rating.aggregate(Sum('value'))
        self.reputation = agg['value__sum']

class Views(models.Model):
    date = models.DateField(auto_now_add=True)
    thread = models.ForeignKey(Thread, related_name='views')
    ip_address = models.IPAddressField()

    class Meta:
        db_table = 'forum_views'
        verbose_name = ugettext('View')
        verbose_name_plural = ugettext('Views')
        ordering = ('-date', '-thread')
        unique_together = ('thread', 'ip_address', 'date')

    def __unicode__(self):
        return "%s" % self.ip_address

class Rating(DatedModel):
    """
    Stores a pontuation given from an user for a reply. This is used
    to calculate the total reputation of the user
    """
    reply = models.ForeignKey(Reply, related_name='rating')
    author = models.ForeignKey(Profile, related_name='ratings')
    value = models.IntegerField(choices=RATING_CHOICES)

    class Meta:
        db_table = 'forum_rating'
        verbose_name = 'Rating'
        verbose_name_plural = 'Ratings'

    def __unicode__(self):
        return self.get_value_display()

class AbuseReport(DatedModel):
    """
    An logged user can report a reply for abuse.
    """
    reply = models.ForeignKey(Reply, related_name='reports')
    author = models.ForeignKey('Profile', related_name='abuse_reports')
    reason = models.IntegerField(choices=REASON_CH)
    observation = models.TextField(_('Any observations?'), blank=True, help_text=_('Use plain text'))

    class Meta:
        db_table = 'forum_abuse_report'
        verbose_name = ugettext('Abuse report')
        verbose_name_plural = ugettext('Abuse reports')

    def __unicode__(self):
        return len(self.observation) > 30 and (self.observation[:30] + '...') or self.get_reason_display()

class Subscription(DatedModel, ActiveModel):
    """
    Represents a subscription of an user to a threads. That means a user
    is interested in the subscribed threads and wish to follow updates on it.
    """
    profile = models.ForeignKey('Profile', related_name="forum_subscribes")
    thread = models.ForeignKey(Thread, related_name="subscriptions")

    class Meta:
        db_table = 'forum_subscription'
        verbose_name = ugettext('Subscription')
        verbose_name_plural = ugettext('subscriptions')
        unique_together = ('profile', 'thread')

    def __unicode__(self):
        return _("Subscription to threads %s") % self.thread

class MessageBox(DatedModel):
    profile = models.OneToOneField(Profile, related_name='message_box')
    box_size = models.PositiveIntegerField(default=20)

    class Meta:
        db_table = 'forum_message_box'
        verbose_name = _('Message box')
        verbose_name_plural = _('Message boxes')

class Message(DatedModel, ActiveModel, MessageModel):
    """
    Represents a private message sent from an user to another.
    """
    was_read = models.BooleanField(verbose_name=_('Was read?'), default=False)
    was_read_at = models.DateTimeField(editable=False, blank=True, null=True)
    author = models.ForeignKey(Profile, verbose_name=_('Author'), related_name='sent_messages')
    to = models.ForeignKey(Profile, verbose_name=_('Recipient'), related_name='messages')
    title = models.CharField(max_length=100)

    class Meta:
        db_table = 'forum_message'
        verbose_name = ugettext('Message')
        verbose_name_plural = ugettext('Messages')
        ordering = ['creation_time']

    @models.permalink
    def get_absolute_url(self):
        return 'forum:messages', [self.id]

    def __unicode__(self):
        return self.title

    def read(self, commit=False):
        self.was_read = True
        self.was_read_at = datetime.datetime.now()

        if commit:
            self.save()

def on_new_profile(sender, instance, **kw):
    if kw.get('created'):
        MessageBox.objects.create(profile=instance)

post_save.connect(on_new_profile, sender=Profile,
                  dispatch_uid='forum_post_save_on_new_profile')

def on_new_views(sender, instance, **kw):
    """
    Updates the view counter for a threads
    """
    if kw.get('created', True):
        instance.thread.update_views_counter()
        instance.thread.save()

post_save.connect(on_new_views, sender=Views,
                  dispatch_uid='forum_post_save_on_new_views')

def on_new_thread(sender, instance, **kw):
    """
    Updates the threads_counter for the forum and threads author
    """
    # works for create and delete
    if kw.get('created', True) is True:
        instance.forum.update_threads_counter()
        instance.forum.save()

        instance.author.update_threads_counter()
        instance.author.save()

post_save.connect(on_new_thread, sender=Thread,
                  dispatch_uid='forum_thread_post_save_update_threads_counter')
post_delete.connect(on_new_thread, sender=Thread,
                    dispatch_uid='forum_thread_post_delete_update_threads_counter')

def on_new_rating(sender, instance, **kw):
    """
    Updates rating counter of the reply.
    """
    # works for create and delete
    if kw.get('created', True) is True:
        instance.reply.update_reputation()
        instance.reply.save()

post_save.connect(on_new_rating, sender=Rating,
                  dispatch_uid='forum_post_save_on_new_rating')
post_delete.connect(on_new_rating, sender=Rating,
                    dispatch_uid='forum_post_delete_on_new_rating')

def on_new_reply(sender, instance, **kw):
    """
    Actually this method name is misleading. The counters that are
    updated are, actually, the counters of the threads this reply is
    related to.
    """
    if kw.get('created', True) is True:
        instance.thread.update_authors_counter()
        instance.thread.update_replies_counter()
        instance.thread.save()

        # update reply counter for the author
        instance.author.update_replies_counter()
        instance.author.save()

        # sum all attributes replies_counter of all threads and updates forum
        instance.thread.forum.update_replies_counter()
        instance.thread.forum.save()

post_save.connect(on_new_reply, sender=Reply,
                  dispatch_uid='forum_post_save_on_new_reply')
post_delete.connect(on_new_reply, sender=Reply,
                    dispatch_uid='forum_post_delete_on_new_reply')

def update_html(sender, instance, *args, **kw):
    """
    pre_save event
    Renders the html for a reply and stores it in an attribute for
    performance
    """
    instance.html = render_markup(instance.message_format, instance.message)

pre_save.connect(update_html, sender=Profile,
                 dispatch_uid='forum_pre_save_update_profile_html')
pre_save.connect(update_html, sender=Reply,
                 dispatch_uid='forum_pre_save_update_reply_html')
pre_save.connect(update_html, sender=Message,
                 dispatch_uid='forum_pre_save_update_message_html')


#!/usr/bin/env python
# coding: utf-8

# In[1]:

import pickle
import pandas as pd
from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier, BaggingClassifier, StackingClassifier, VotingClassifier
from sklearn.model_selection import train_test_split
import xgboost as xgb

# # Load dataset

# In[2]:

X = pd.read_feather('dataset/train.feather')
y = X.iloc[:, -1]
X = X.iloc[:, :-1]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, random_state=42, test_size=0.25, stratify=y)

# # Train and test Machine Learning models

# In[3]:

clf1 = ExtraTreesClassifier(n_jobs=-1, n_estimators=1000, criterion='entropy')
clf2 = RandomForestClassifier(
    n_jobs=-1, n_estimators=1000, criterion='entropy')

param = {'max_depth': 0}
clf3 = xgb.XGBClassifier(param, 1000, objective='multi:softmax')

# In[4]:

print("training ExtraTreesClassifier")
clf1.fit(X_train, y_train)
print("training RandomForestClassifier")
clf2.fit(X_train, y_train)
print("training XGBoost")
clf3.fit(X_train, y_train)

# In[ ]:

print(clf1.score(X_test, y_test), clf2.score(
    X_test, y_test), clf3.score(X_test, y_test))

# In[ ]:

# Save trained model

with open('models/ExtraTrees.pickle', 'wb') as handle:
    pickle.dump(clf1, handle)

with open('models/RandomForest.pickle', 'wb') as handle:
    pickle.dump(clf2, handle)

with open('models/XGBoost.pickle', 'wb') as handle:
    pickle.dump(clf3, handle)

# In[ ]:

# test saved model

with open('models/ExtraTrees.pickle', 'rb') as handle:
    clf_et = pickle.load(handle)

with open('models/RandomForest.pickle', 'rb') as handle:
    clf_rf = pickle.load(handle)

with open('models/XGBoost.pickle', 'rb') as handle:
    clf_xgb = pickle.load(handle)

print(clf_et.score(X_test, y_test), clf_rf.score(
    X_test, y_test), clf_xgb.score(X_test, y_test))


import argparse
import os
import random
import numpy as np

import torch
import torch.nn.parallel
import torch.backends.cudnn as cudnn
import torch.optim
import torch.utils.data
import torchvision.transforms as transforms

from torch.utils.tensorboard import SummaryWriter

from utils.train import validate, train1st, train2nd, adjust_learning_rate, save_checkpoint
import utils.datasets as datasets
from utils.ClassAwareSampler import ClassAwareSampler

import models

parser = argparse.ArgumentParser(description='Imbalanced Learning')
#Data
parser.add_argument('--data', default='./datasets/imagenetlt/', type=str,
                    help='path to dataset')
parser.add_argument('--dataset', default='imagenetlt', type=str,
                    help='dataset name')

#Network
parser.add_argument('--arch', default='ResNet10Feature', type=str,
                    help='CNN architecture (default: ResNet10Feature)')
parser.add_argument('--rot-alpha', default=45, type=float,
                    help='random rotation angle [degree] (default: 45)')

parser.add_argument('--first-model-file', default=None, type=str,
                    help='path to the 1st-trained model file')

parser.add_argument('--logit-adjust', action='store_true',
                    help='adjust logits based on class probabilities')

#Optimization
parser.add_argument('--lr', default=0.2, type=float)
parser.add_argument('--epochs', default=180, type=int)  # 30
parser.add_argument('--batch-size', default=256, type=int)
parser.add_argument('--weight-decay', default=0.0001, type=float)
parser.add_argument('--momentum', default=0.9, type=float)

#Utility
parser.add_argument('--seed', default=None, type=int,
                    help='seed for initializing training. ')
parser.add_argument('-j', '--workers', default=12, type=int, metavar='N',
                    help='number of data loading workers (default: 12)')
parser.add_argument('--out-dir', default='./results', type=str,
                    help='path to output directory (default: ./)')
parser.add_argument('--save-all-checkpoints', dest='save_all_checkpoints', action='store_true',
                    help='save all the checkpoints')

def main():
    # performance stats
    stats = {'train_err1': [], 'train_err5': [], 'train_loss': [],
            'test_err1': [],  'test_err5': [],  'test_loss': []}

    # parameters
    args = parser.parse_args()

    num_classes = {'imagenetlt':1000, 'inat2018':8142, 'placeslt':365}[args.dataset]

    # output directory
    os.makedirs(args.out_dir, exist_ok=True)

    if args.seed is not None:
        random.seed(args.seed)
        torch.manual_seed(args.seed)

    # 1st training or not?
    Do2ndTrain = args.first_model_file is not None and os.path.isfile(args.first_model_file)

    # create model
    print("=> creating model '{}'".format(args.arch))
    model_feat = models.__dict__[args.arch]()
    if Do2ndTrain:
        print("=> loading 1st-trained model '{}'".format(args.first_model_file))
        checkpoint = torch.load(args.first_model_file, map_location=torch.device('cpu'))
        model_feat.load_state_dict(checkpoint['feat_state_dict'])
        for _, param in model_feat.named_parameters():
            param.requires_grad = False

        model_fc = torch.nn.Linear(model_feat.get_dim(), num_classes, bias=False)
    else:
        model_fc = models.StatRotLinear(model_feat.get_dim(), num_classes, bias=False, alpha=args.rot_alpha)
    print(model_feat)

    criterion = torch.nn.CrossEntropyLoss()

    writer = SummaryWriter(log_dir=os.path.join(args.out_dir, 'logs'))
    writer.close()

    # DataParallel will divide and allocate batch_size to all available GPUs
    model_feat = torch.nn.DataParallel(model_feat)
    model_feat.cuda()
    model_fc.cuda()
    criterion.cuda()

    # Data augmentation
    train_transform = transforms.Compose([
                        transforms.RandomResizedCrop(224),
                        transforms.RandomHorizontalFlip(),
                        transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4),
                        transforms.ToTensor(),
                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
                    ])
    test_transform = transforms.Compose([
                        transforms.Resize(256),
                        transforms.CenterCrop(224),
                        transforms.ToTensor(),
                        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
                    ])

    # Data loading code
    train_dataset = datasets.ListDataset(args.data, './datasets/{}/train.txt'.format(args.dataset), transform=train_transform)
    val_dataset = datasets.ListDataset(args.data, './datasets/{}/val.txt'.format(args.dataset), transform=test_transform)

    # Data Sampling
    if not Do2ndTrain: # 1st training
        train_loader = torch.utils.data.DataLoader(
            train_dataset, batch_size=args.batch_size, shuffle=True,
            num_workers=args.workers, pin_memory=True, sampler=None)
    else: # 2nd training
        train_loader = torch.utils.data.DataLoader(
            train_dataset, batch_size=args.batch_size, shuffle=False,
            num_workers=args.workers, pin_memory=True, sampler=ClassAwareSampler(train_dataset,num_samples_cls=4))

    val_loader = torch.utils.data.DataLoader(
        val_dataset, batch_size=args.batch_size, shuffle=False,
        num_workers=args.workers, pin_memory=True)

    # Optimizer
    lrs = ( 0.5*args.lr*np.cos(np.pi*np.arange(args.epochs)/args.epochs) + 0.5*args.lr ).tolist()
    model_params = [param for param in model_fc.parameters() if param.requires_grad]
    if not Do2ndTrain:
        model_params += [param for param in model_feat.parameters() if param.requires_grad]
    optimizer = torch.optim.SGD(model_params, lr=lrs[0], weight_decay=args.weight_decay, momentum=args.momentum)

    cudnn.benchmark = True

    # Do Train
    if args.logit_adjust:
        model_logit = models.LogitAdjust([train_dataset.targets.count(c) for c in range(num_classes)]).cuda()
        model_whole = torch.nn.Sequential(model_feat, model_fc, model_logit)
    else:
        model_whole = torch.nn.Sequential(model_feat, model_fc)
    for epoch in range(args.epochs):
        lr = adjust_learning_rate(optimizer, epoch, lrs)

        # train for one epoch
        if not Do2ndTrain: # 1st training
            trnerr1, trnerr5, trnloss = train1st(train_loader, model_whole, criterion, optimizer, epoch)
        else: # 2nd training
            trnerr1, trnerr5, trnloss = train2nd(train_loader, model_whole, criterion, optimizer, epoch)

        # evaluate on validation set
        valerr1, valerr5, valloss = validate(val_loader, model_whole, criterion)

        # statistics
        stats['train_err1'].append(trnerr1)
        stats['train_err5'].append(trnerr5)
        stats['train_loss'].append(trnloss)
        stats['test_err1'].append(valerr1)
        stats['test_err5'].append(valerr5)
        stats['test_loss'].append(valloss)

        # remember best err@1
        is_best = valerr1 <= min(stats['test_err1'])

        # show and save results
        writer.add_scalar('LearningRate', lr, epoch)
        writer.add_scalar('Loss/train', trnloss, epoch)
        writer.add_scalar('Loss/test', valloss, epoch)
        writer.add_scalar('Error_1/train', trnerr1, epoch)
        writer.add_scalar('Error_1/test', valerr1, epoch)
        writer.add_scalar('Error_5/train', trnerr5, epoch)
        writer.add_scalar('Error_5/test', valerr5, epoch)
        save_checkpoint({
            'epoch': epoch + 1,
            'arch': args.arch,
            'feat_state_dict': model_feat.module.state_dict(),
            'fc_state_dict': model_fc.state_dict(),
            'stats': stats,
            'optimizer' : optimizer.state_dict(),
        }, is_best, not args.save_all_checkpoints, filename=os.path.join(args.out_dir, 'checkpoint-epoch{:d}.pth.tar'.format(epoch+1)))

    # show the final results
    minind = stats['test_err1'].index(min(stats['test_err1']))
    print('\n *BEST* Err@1 {:.3f} Err@5 {:.3f}'.format(stats['test_err1'][minind], stats['test_err5'][minind]))
    writer.add_hparams({'dataset':args.dataset, 'arch':args.arch, 'bsize':args.batch_size},
                        {'best/err_1':stats['test_err1'][minind], 'best/err_5':stats['test_err5'][minind], 'best/epoch':minind})
    writer.close()

if __name__ == '__main__':
    main()


def solution(money):
    # 집이 하나인 경우 그 집을 터는게 최댓값
    # 집이 두개인 경우 두 집 중 money가 큰 집을 터는게 최댓값

    # 첫번째 집을 털고, 마지막 집을 털지 않는 경우
    dp1 = [0] * len(money)
    dp1[0] = money[0]
    dp1[1] = max(money[0], money[1])

    # 첫번째 집을 털지 않고, 마지막 집을 터는 경우
    dp2 = [0] * len(money)
    dp2[0] = 0
    dp2[1] = money[1]

    for i in range(2, len(money) -1):
        dp1[i] = max(dp1[i-1], dp1[i-2] + money[i])
        dp2[i] = max(dp2[i-1], dp2[i-2] + money[i])

    dp2[len(money)-1] = max(dp2[len(money)-2], dp2[len(money)-3] + money[len(money)-1])

    return max(max(dp1), max(dp2))

DP/프로그래머스 도둑질.py

프로그래머스 도둑질.py


#!/usr/bin/env python3
import rospy
from geometry_msgs.msg import PoseWithCovarianceStamped
from fiducial_msgs.msg import FiducialTransformArray
from fiducial_msgs.msg import FiducialTransform
import random

import numpy as np
import matplotlib.pyplot as plt

import time

def message_creation(i):
    message=FiducialTransform()
    j=int(4*random.random()+1)
    for a in range(j):
        message.fiducial_id=i
        message.transform.translation.x=9*(random.random())+1
        message.transform.translation.y=9*(random.random())+1
        message.transform.translation.x=9*(random.random())+1
        message.transform.rotation.w= 9*(random.random())+1
        message.transform.rotation.z= 9*(random.random())+1
        message.transform.rotation.y= 9*(random.random())+1
        message.transform.rotation.x= 9*(random.random())+1

    messageArray=FiducialTransformArray()
    messageArray.transforms.append(message)

    return messageArray
def main():
    start=time.time()
    aruco_id=[0,1,2,3,4,5]
    rospy.init_node('aruco_simulator', anonymous=True)
    loop_rate = rospy.Rate(0.5)
    pub_fiducial = rospy.Publisher('/fiducial_transforms', FiducialTransformArray,queue_size=10)
    i=random.choice(aruco_id)
    while not rospy.is_shutdown():
        i=random.choice(aruco_id)
        message=message_creation(i)
        pub_fiducial.publish(message)
        loop_rate.sleep()

if __name__ == "__main__":
    main()


from __future__ import print_function
import pygame
from pygame.locals import *
pygame.init()
from time import sleep

def fin():
	pygame.quit()
	quit()
def afficher_texte(message, x, y):
	font = pygame.font.SysFont("Arial Black", 34)
	texte = font.render(message, 1, (255,255,255))
	largeur, hauteur = font.size(message)
	fenetre.blit(texte, (x-largeur/2, y-hauteur/2))
def afficher_image_centre(img, x, y):
	w, h = pygame.Surface.get_size(img)
	fenetre.blit(img, (x-w/2, y-h/2))

def afficher_classes():
	partie_x = dimension_fenetre[0]/(2*len(classes))
	for i, classe in enumerate(classes):
		afficher_image_centre(classe, (2*i+1)*partie_x, hauteur_icone)

def souris_sur_image():
	x, y = pygame.mouse.get_pos()
	partie_x = dimension_fenetre[0]/(2*len(classes))
	liste_souris_sur_image = [False for i in range(len(classes))]
	for i in range(len(classes)):
		x1 = (2*i+1)*partie_x - dimension_icone[0]/2
		x2 = x1 + dimension_icone[0]
		y1 = hauteur_icone - dimension_icone[1]/2
		y2 = y1 + dimension_icone[1]
		# pygame.draw.rect(fenetre, (255, 0, 0), (x1, y1, dimension_icone[0], dimension_icone[1]), 1)
		if x1 <= x <= x2:
			if y1 <= y <= y2:
				liste_souris_sur_image[i] = True
	return liste_souris_sur_image

def animation():
	liste = souris_sur_image()
	print(liste)
	for i, img in enumerate(liste):
		if img==True:
			classes[i] = pygame.transform.scale(classes[i], (dimension_icone_zoom))
		else:
			classes[i] = pygame.transform.scale(classes[i], (dimension_icone))

#Ouverture de la fenêtre Pygame
dimension_fenetre = (1500, 850)
fenetre = pygame.display.set_mode(dimension_fenetre, pygame.FULLSCREEN)

#Chargement
fond = pygame.image.load("ressources/noir.png").convert_alpha()

dimension_icone = (320, 180)
dimension_icone_zoom = (480, 270)

#Chargement des classes
sniper = pygame.image.load("ressources/sniper.jpg").convert()
sniper2 = pygame.image.load("ressources/sniper2.jpg").convert()
commando1 = pygame.image.load("ressources/commando.jpg").convert()

classes = [commando1, sniper, sniper2, commando1]

hauteur_icone = 250

while True:
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			fin()
		if event.type == pygame.KEYDOWN:
			if event.key == pygame.K_ESCAPE:
				fin()
	fenetre.blit(fond, (0,0))
	afficher_texte("CHOOSE YOUR CLASS", dimension_fenetre[0]/2, 50)
	afficher_classes()
	animation()
	pygame.display.flip()
	sleep(0.02)


s=input()
t=s.split()
pre=-1
ans=True
for i in range(len(t)):
    try:
        cur=int(t[i])
        if (cur>pre) :
            pre=cur
        else:
            ans=False
            break
    except ValueError:
        continue
print(ans)


import random
def primary():
  #print("Keep it logically awesome.")

  f = open("quotes.txt")
  while True:
    quotes = f.readline()
    if not quotes:
      break
    print(quotes)
  f.close()

  #last = 13
  #rnd = random.randint(0, last)
  print(quotes)

if __name__== "__main__":
  primary()


class Solution:
    def isValid(self, s: str) -> bool:
        stack, ch = [], ''
        for ch in list(s):
            if ch in ['(', '{', '[']:
                stack.append(ch)
            else:
                if len(stack) == 0:
                    return False
                chp = stack.pop()
                if ch == ')' and chp == '(' or ch == ']' and chp == '[' or ch == '}' and chp == '{':
                    continue
                return False
        if len(stack) == 0:
            return True
        return False


import pickle
import math
from typing import Iterable, List, Callable
import numpy as np

A_OFFSET = 65

def euclid_distance(p1: Iterable, p2: Iterable):
    return math.sqrt(sum([(c1 - c2)**2 for c1, c2 in zip(p1, p2)]))

def split_percentages(data):
    median = np.zeros(len(data))
    perc_25 = np.zeros(len(data))
    perc_75 = np.zeros(len(data))
    for i in range(0, len(median)):
        median[i] = np.median(data[i])
        perc_25[i] = np.percentile(data[i], 25)
        perc_75[i] = np.percentile(data[i], 75)
    return median, perc_25, perc_75

def max_index_with_cond(ls: List, cond: Callable[[any], bool]) -> int:
    """
    ls must have at least one element matching cond
    """
    index = -1
    while cond(ls[index + 1]):
        index += 1
    return index

def min_index_with_cond(ls: List, cond: Callable[[any], bool]) -> int:
    """
    ls must have at least one element matching cond
    """
    index = 0
    while not cond(ls[index]):
        index += 1
    return index

def save_pickle(obj, path):
    with open(path, 'wb') as f:
        pickle.dump(obj, f)

def load_pickle(path):
    with open(path, 'rb') as f:
        obj = pickle.load(f)
    return obj


import os
import cv2
# root_path = '/root/ntire/Data/video_compress_track2/train_expand_199_2/gt/'

# root_path = '/root/ntire/Data/video_compress_track2/test_youtube/images/train_raw/'
root_path = '/root/ntire/Data/video_compress_track3/images/test/'
foldernames = os.listdir(root_path)
foldernames.sort()
print(foldernames[:5])
txt_name = 'meta_info_Compress_test.txt'
txt_file = os.path.join('/root/ntire/Data/video_compress_track3/', txt_name)
with open(txt_file, 'w') as f:
    for foldername in foldernames:
        print(foldername)
        floder_path = os.path.join(root_path, foldername)
        filenames = os.listdir(floder_path)
        filenames.sort()
        file_path = os.path.join(floder_path, filenames[0])
        image = cv2.imread(file_path)
        height, width, channel = image.shape[:]
        print(height, width, channel)
        for filename in filenames:
            frame = filename.split('.')[0]
            f.write(
                f'{int(foldername):03d}/{int(frame):03d}.png ({height}, {width}, {channel})\n'
            )

# print(f'Generate annotation files {file_name}...')
# txt_file = osp.join(root_path, file_name)
# mmcv.utils.mkdir_or_exist(osp.dirname(txt_file))
# xls_file = osp.join(root_path, xls_name)
# workbook = xlrd.open_workbook(xls_file)  # 文件路径
# worksheet = workbook.sheet_by_index(0)

# nrows = worksheet.nrows  #获取该表总行数
# print(nrows)  # 200

# ncols = worksheet.ncols  #获取该表总列数
# print(ncols)  # 5
# with open(txt_file, 'w') as f:
#     for i in range(1, nrows):
#         frames = int(worksheet.cell_value(i, 3))
#         print(i, frames)
#         for j in range(1, frames + 1):
#             f.write(f'{i:03d}/{j:03d}.png (536, 960, 3)\n')


from chess import *
from chess.piece import King, Rook, Pawn, Bishop
from chess.board import Board
from nose.tools import assert_equals, assert_raises
import chess.outcomes

def test_copy():
  """Test piece copying."""
  king1 = King(WHITE, 0, 0)
  king2 = king1.copy()
  assert king1 is not king2
  assert king1.x == king2.x
  assert king1.y == king2.y
  assert king1.char == king2.char

def test_check_small():
  board = Board()
  king = King(BLACK, 0, 0)
  rook = Rook(WHITE, 2, 2)
  board._pieces = {king, rook}
  assert not board.checked(BLACK)
  board.move(rook, 2, 0)
  assert board.checked(BLACK)

def test_check_medium():
  board = Board()
  king = King(BLACK, 0, 0)
  rook = Rook(WHITE, 2, 2)
  pawn = Pawn(WHITE, 7, 3)
  bishop = Bishop(WHITE, 1, 3)
  enemy_king = King(WHITE, 6, 6)
  board._pieces = {king, rook, pawn, bishop, enemy_king}
  assert not board.checked(BLACK)
  board.move(rook, 2, 0)
  assert board.checked(BLACK)
  assert not board.checked(WHITE)

def test_copy():
  board = Board()
  king = King(BLACK, 0, 0)
  rook = Rook(WHITE, 2, 2)
  board._pieces = {king, rook}
  clone = board.copy()
  assert len(clone._pieces) == len(board._pieces)
  for piece in clone._pieces:
    assert piece not in board._pieces

def test_moves_tiny():
  board = Board()
  king = King(BLACK, 0, 0)
  r = Rook(WHITE, 4, 0)
  board._pieces = {king, r}
  assert_equals(board.moves_open(BLACK), True)

def test_checkmate():
  g = Game(WHITE, "pw", "adam1")
  bk = King(BLACK, 0, 0)
  wr1 = Rook(WHITE, 4, 0)
  wr2 = Rook(WHITE, 4, 4)
  wk = King(WHITE, 7, 7)
  g.board._pieces = {bk, wr1, wr2, wk}
  assert_equals(g.board.moves_open(BLACK), True)
  g.move(Move(4, 4, 4, 1, WHITE, g.board))
  assert_equals(g.winner, "w")
  with assert_raises(ActionNotAllowedException):
    g.move(Move(0, 0, 0, 1, BLACK, g.board))

def test_no_checkmate():
  g = Game(WHITE, "pw", "adam1")
  bk = King(BLACK, 0, 0)
  wk = King(WHITE, 7, 7)
  g.board._pieces = {bk, wk}
  assert g.winner == ""
  g.move(Move(7, 7, 7, 6, WHITE, g.board))
  assert g.winner == ""
  g.move(Move(0, 0, 0, 1, BLACK, g.board))
  assert g.winner == ""

def test_no_stalemate():
  g = Game(WHITE, "pw")
  g.board._pieces = {
    piece.King(WHITE, 4, 6),
    piece.King(BLACK, 7, 1),
    piece.Rook(WHITE, 0, 2),
    piece.Rook(WHITE, 6, 7),
  }
  assert g.winner == ""
  assert not g.board.checked(WHITE)
  assert not g.board.checked(BLACK)
  g.board.turn = BLACK
  g.move(Move(7, 1, 7, 0, BLACK, g.board))
  assert g.board.moves_open(WHITE)
  assert g.board.moves_open(BLACK)

def test_stalemate():
  g = Game(WHITE, "pw", "adam1")
  bk = King(BLACK, 0, 0)
  wr1 = Rook(WHITE, 1, 7)
  wr2 = Rook(WHITE, 7, 2)
  g.board._pieces = {bk, wr1, wr2}
  g.move(Move(7, 2, 7, 1, WHITE, g.board))
  assert_equals(g.winner, "s")


from m5stack import *
from m5ui import *
from uiflow import *
import unit
import json
import network
import machine

def blink(color):
    colorcode = { 'black': 0x000000, 'red': 0xFF0000, 'green': 0x00FF00, 'yellow': 0xFFFF00, 'white':0x808080 }
    rgb.setColorAll(colorcode[color])
    print(color)
    wait_ms(250)
    rgb.setColorAll(colorcode['black'])

def wificheck():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    while not wlan.isconnected():
        blink('red')
        wifi = cfgRead('wifi')
        print('connecting to network...',wifi)
        wlan.connect(wifi['ssid'], wifi['password'])
        wait(4)

    print('network config:', wlan.ifconfig())
    blink('white')

# check if the device woke from a deep sleep
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
    print('woke from a deep sleep')
else:
    print('NOT woke from a deep sleep')

wificheck()

blink('green')

print('going to deepsleep')
machine.deepsleep(10000)


import numpy as np
import random
import math
import copy

playing = 1 #First player
RL_player = 1 #Person player
IA_player = 2 #IA player

# Main Board call
def create_board():
	''' Create a flipped ARRAY board'''
	board = np.zeros((6,7))
	return board
board = create_board()

# --- Basic functions ---
def next_player(player): #Prochain joueur =>
	''' Returns the next player'''
	return RL_player if player == IA_player else IA_player

def print_board(board): #Affiche le tableau
	''' Prints the board UNFLIPPED'''
	print(np.flip(board, 0))

def co(board, x,y): #Essayes ces coordonnées !
	''' Tries coordinates and return if existing'''
	try: return board[y][x]
	except: pass

# --- Advanced functions ---
def check_winner(board, player): #Y-a-t'il (déjà) un gagant ?
	''' Check if there is a winner [+MINIMAX]'''
	for row in range(0,6):
		for column in range(0,7):
			if (co(board, column, row) == co(board, column+1, row) == co(board, column+2, row) == co(board, column+3, row) == player) or (co(board, column, row) == co(board, column, row+1) == co(board, column, row+2) == co(board, column, row+3) == player) or (co(board, column, row) == co(board, column+1, row+1) == co(board, column+2, row+2) == co(board, column+3, row+3) == player) or (co(board, column, row) == co(board, column+1, row-1) == co(board, column+2, row-2) == co(board, column+3, row-3) == player):
				return True
	return False

def drop_piece(board, x, player): #Envoyez une pièce svp!
	''' Drop a piece in a correct place'''
	if x in get_valid_locations(board):
		board[get_next_open_row(board, x)][x] = player
	else: raise Exception("Colonne pleine ou incorrecte")

# --- IA : MINIMAX & Alpha-Beta ---
def board_is_full(board): #Le tableau est-il plein ?
	''' Returns a bool saying if the board is full or not [MINIMAX]'''
	return True if len(get_valid_locations(board)) == 0 else False

def get_valid_locations(board): #Quelles colonnes sont-elles jouables ? [MINIMAX ONLY]
	''' Returns a list of playable columns (x) [MINIMAX]'''
	valid_locations = []
	for col in range(7):
		if board[5][col] == 0:
			valid_locations.append(col)
	return valid_locations

def get_next_open_row(board, col): #Quelle ligne vide est la plus basse sur une certaine colonne ? [MINIMAX ONLY]
	''' Return open row for (x) column [+MINIMAX]'''
	for r in range(7):
		if board[r][col] == 0:
			return r

def is_terminal_node(board): #Est-ce une feuille d'une branche du minimax ?
	''' Return the winning_move of player 1 || winning_move of player 2 || IS no playable columns True ? [MINIMAX]'''
	return winning_move(board, RL_player) or winning_move(board, IA_player) or len(get_valid_locations(board)) == 0

def winning_move(board, piece):
	# Check horizontal locations for win
	for col in range(7-3):
		for row in range(6):
			if board[row][col] == piece and board[row][col+1] == piece and board[row][col+2] == piece and board[row][col+3] == piece:
				return True

	# Check vertical locations for win
	for col in range(7):
		for row in range(6-3):
			if board[row][col] == piece and board[row+1][col] == piece and board[row+2][col] == piece and board[row+3][col] == piece:
				return True

	# Check positively sloped diaganols
	for col in range(7-3):
		for row in range(6-3):
			if board[row][col] == piece and board[row+1][col+1] == piece and board[row+2][col+2] == piece and board[row+3][col+3] == piece:
				return True

	# Check negatively sloped diaganols
	for col in range(7-3):
		for row in range(3, 6):
			if board[row][col] == piece and board[row-1][col+1] == piece and board[row-2][col+2] == piece and board[row-3][col+3] == piece:
				return True

def evaluate_window(window, player): #Combien de points vaux une fenetre (4x4) ?
	''' Gives a score to a 4 sized window from the board [MINIMAX]'''
	score = 0
	if player == IA_player:
		opponent_player = RL_player
	else: opponent_player = IA_player

	if window.count(player) == 4: score += 100
	elif window.count(player) == 3 and window.count(0) == 1: score += 5
	elif window.count(player) == 2 and window.count(0) == 2: score += 2

	if window.count(opponent_player) == 3 and window.count(0) == 1: score -= 4

	return score

def score_position(board, player): #Combien de points vaux le JEU entier (7*6) ?
	''' Gives a score to the CURRENT board [MINIMAX]'''
	score = 0

	## Score center column
	center_array = [int(i) for i in list(board[:, 7//2])] #PB
	center_count = center_array.count(player)
	score += center_count * 3

	## Score Horizontal
	for row in range(0,6):
		row_array = [int(i) for i in list(board[row,:])] #PB
		for col in range(0,7-3):
			window = row_array[col:col+4]
			score += evaluate_window(window, player)

	## Score Vertical
	for col in range(0,7):
		col_array = [int(i) for i in list(board[:,col])] #PB
		for row in range(0,6-3):
			window = col_array[row:row+4]
			score += evaluate_window(window, player)

	## Score posiive sloped diagonal
	for row in range(0,6-3):
		for col in range(0,7-3):
			window = [board[row+i][col+i] for i in range(4)]
			score += evaluate_window(window, player)

	for row in range(0,6-3):
		for col in range(0,7-3):
			window = [board[row+3-i][col+i] for i in range(4)]
			score += evaluate_window(window, player)

	return score

def minimax(board, depth, alpha, beta, maximizingPlayer): #Quel est le meilleur coup et combien de points vaut-il ?
	''' Minimax algorithm pruned with alpha-beta // returns the best move (column) for a certain depth and the score corresponding'''
	valid_locations = get_valid_locations(board)
	is_terminal = is_terminal_node(board)
	if depth == 0 or is_terminal:
		if is_terminal:
			if winning_move(board, 2):
				return (None, 100000000000000)
			elif winning_move(board, 1):
				return (None, -10000000000000)
			else: # Game is over, no more valid moves
				return (None, 0)
		else: # Depth is zero
			return (None, score_position(board, 2))
	if maximizingPlayer:
		value = -math.inf
		column = random.choice(valid_locations)
		for col in valid_locations:
			row = get_next_open_row(board, col)
			b_copy = board.copy()
			b_copy[row][col] = IA_player
			new_score = minimax(b_copy, depth-1, alpha, beta, False)[1]
			if new_score > value:
				value = new_score
				column = col
			alpha = max(alpha, value)
			if alpha >= beta:
				break
		return column, value

	else: # Minimizing player
		value = math.inf
		column = random.choice(valid_locations)
		for col in valid_locations:
			row = get_next_open_row(board, col)
			b_copy = board.copy()
			b_copy[row][col] = RL_player
			new_score = minimax(b_copy, depth-1, alpha, beta, True)[1]
			if new_score < value:
				value = new_score
				column = col
			beta = min(beta, value)
			if alpha >= beta:
				break
		return column, value

def initialising():
	import Puissance4

# --- Playing functions ---
def player_play(board, x):
	import Puissance4
	global playing
	drop_piece(board, x, RL_player)
	if check_winner(board, RL_player):
		#print('Bravo ! Tu as gagné !')
		Puissance4.end_game('Won', 'Win')
		del Puissance4.liste_jettons[:]
		board = create_board()
		Puissance4.title_screen()
		running = False
	playing = IA_player

	#print_board(board)
	#print("Tour de l'IA.")

def ia_play(board, difficulty, alpha = -math.inf, beta = math.inf, maximizingPlayer = True):
	import Puissance4
	global playing
	col, minimax_score = minimax(board, difficulty, alpha, beta, maximizingPlayer)
	if col in get_valid_locations(board):
		Puissance4.afficher_jetton(Puissance4.IA[2], 580+(col*109), col)
		drop_piece(board, col, IA_player)
		if check_winner(board, IA_player):
			#print('Domage ! Tu as perdu.')
			Puissance4.end_game('Lost', 'Lost')
			del Puissance4.liste_jettons[:]
			board = create_board()
			Puissance4.title_screen()
			running = False
	  #print_board(board)
	  #print("Tour du Joueur 1.")
	playing = RL_player


from setuptools import setup, find_packages

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()
setup(
    name='kasearch',
    version='0.0.19',
    description='KA-Search: Rapid and exhaustive sequence identity search of known antibodies',
    license='BSD 3-clause license',
    maintainer='Tobias Hegelund Olsen; Brennan Abanades kenyon',
    long_description=long_description,
    long_description_content_type='text/markdown',
    include_package_data=True,
    packages=find_packages(include=('kasearch', 'kasearch.*')),
    package_data={
        '': ['*.txt']
    },
    install_requires=[
        'pandas',
        'joblib',
        'requests',
        'numpy',
        'jax',
        'jaxlib'
    ],
)


from Stack import Stack
import constants, operator, exceptions

class Board:
    def __init__(self):
        self.board = []

        # create the board and references
        for col in constants.COLUMNS:
            n = []

            for row in constants.ROWS:
                n += [self.Node(col, row)]

            self.board += [n]

        # establish all knight moves
        vertDif = [2, 1, -1, -2, -2, -1, 1, 2]
        horzDif = [1, 2, 2, 1, -1, -2, -2, -1]

        for row in range(0, 8):
            for col in range(0, 8):
                for i in range(0, 8):
                    tempRow = row + vertDif[i]
                    tempCol = col + horzDif[i]

                    if tempRow in range(0, 8) and tempCol in range(0, 8):
                        self.board[row][col].add_connection(self.board[tempRow][tempCol])

        # sort all connections from each square based on possible moves from those connections
        for row in range(0, 8):
            for col in range(0, 8):
                self.board[row][col].connections = sorted(self.board[row][col].connections, key=operator.methodcaller('get_possible_moves'))

    def __get_node(self, column, row):
        """Returns the specified board square"""

        if column not in constants.COLUMNS:
            raise exceptions.InvalidColumnError(column)
        if row not in constants.ROWS:
            raise exceptions.InvalidRowError(row)

        return self.board[constants.COLUMNS.index(column)][constants.ROWS.index(row)]

    def knights_tour(self, column, row):
        """performs a knight's tour of a 8x8 chess board from the given starting location
           returns a list containing the 64 moves required"""

        currNode = self.__get_node(column, row)
        currNode.visit()

        # update all connections' degrees and sort their connections by degree in ascending order
        for node in currNode.connections:
            node.connections = sorted(node.connections, key=operator.methodcaller('get_possible_moves'))

        stack = Stack()
        stack.push([currNode, 0]) # first element represents current square, second element which connection number it took

        while True:
            # knight's tour is complete
            if stack.size() == 64:
                moveList = []

                for i in range(0, stack.size()):
                    moveList += [str(stack.items[i][0])]

                return moveList

            stackElement = stack.peek()
            stackNode = stackElement[0]
            stackNum = stackElement[1]

            # there is a valid move from this square
            if stackNode.get_possible_moves() != 0 and stackNum < len(stackNode.connections):
                while stackNode.connections[stackNum].visited:
                    stackNum += 1

                # update stack if the stackNum was changed
                if stackNum != stackElement[1]:
                    stack.pop()
                    stack.push([stackNode, stackNum])

                nextNode = stackNode.connections[stackNum]
                nextNode.visit()

                for node in nextNode.connections:
                    node.connections = sorted(node.connections, key=operator.methodcaller('get_possible_moves'))

                # add this square to the path and assume the first connection from this square is valid
                stack.push([nextNode, 0])

            # there is no valid move from this square
            else:
                # this path isn't valid, so "undo" it
                stackNode = stack.pop()[0]
                stackNode.unvisit()

                # update all connections' degrees and sort their connections by degree in ascending order
                for node in stackNode.connections:
                    node.connections = sorted(node.connections, key=operator.methodcaller('get_possible_moves'))

    class Node:
        """Represents a square on the chess board"""

        def __init__(self, column, row):
            # columns are letters A-H, rows are numbers 1-8

            if column not in constants.COLUMNS:
                raise exceptions.InvalidColumnError(column)
            if row not in constants.ROWS:
                raise exceptions.InvalidRowError(row)

            self.col = column
            self.row = row
            self.visited = False
            self.connections = []

        def visit(self):
            """visits the current square, throws an error if already visited"""

            if not self.visited:
                self.visited = True
            else:
                raise exceptions.VisitError("Already visited")

        def un_visit(self):
            """unvisits the current square, throws an error if not been visited"""

            if self.visited:
                self.visited = False
            else:
                raise exceptions.VisitError("Has not been visited")

        def get_possible_moves(self):
            """Returns the number of possible knight moves from this square"""
            count = 0

            for node in self.connections:
                if not node.visited:
                    count += 1

            return count

        def add_connection(self, node):
            self.connections += [node]

        def __str__(self):
            return self.col + self.row

if __name__ == '__main__':
    raise exceptions.ModuleError()