from lib.cuckoo.common.abstracts import Signature

class NetworkDocumentFile(Signature):
    name = "network_document_file"
    description = "A document or script file initiated network communications indicative of a potential exploit or payload download"
    severity = 3
    categories = ["exploit", "downloader"]
    # Migrated by @CybercentreCanada
    authors = ["Kevin Ross", "Will Metcalf", "@CybercentreCanada"]
    minimum = "1.2"
    ttps = ["T1071"]
    mbcs = ["E1105"]
    evented = True

    filter_apinames = set(
        [
            "InternetCrackUrlW",
            "InternetCrackUrlA",
            "URLDownloadToFileW",
            "URLDownloadToCacheFileW",
            "HttpOpenRequestW",
            "WSASend",
            "send",
        ]
    )
    filter_analysistypes = set(["file"])

    def __init__(self, *args, **kwargs):
        Signature.__init__(self, *args, **kwargs)
        self.proc_list = [
            "wordview.exe",
            "winword.exe",
            "excel.exe",
            "powerpnt.exe",
            "outlook.exe",
            "acrord32.exe",
            "acrord64.exe",
            "wscript.exe",
            "mspub.exe",
            "powershell.exe",
        ]

    def on_call(self, _, process):
        pname = process["process_name"].lower()
        if pname in self.proc_list:
            if self.pid:
                self.mark_call()
            return True

class NetworkEXE(Signature):
    name = "network_downloader_exe"
    description = "An executable file was downloaded"
    severity = 2
    categories = ["exploit", "downloader"]
    # Migrated by @CybercentreCanada
    authors = ["Kevin Ross", "Will Metcalf", "@CybercentreCanada"]
    minimum = "1.2"
    ttps = ["T1129"]
    evented = True

    filter_apinames = set(["recv", "InternetReadFile"])

    def __init__(self, *args, **kwargs):
        Signature.__init__(self, *args, **kwargs)
        self.high_risk_proc = [
            "wordview.exe",
            "winword.exe",
            "excel.exe",
            "powerpnt.exe",
            "outlook.exe",
            "acrord32.exe",
            "acrord64.exe",
            "wscript.exe",
            "java.exe",
            "javaw.exe",
            "powershell.exe",
        ]

    def on_call(self, call, process):
        if call["api"] == "recv":
            buf = self.get_argument(call, "buffer")
        elif call["api"] == "InternetReadFile":
            buf = self.get_argument(call, "Buffer")
        else:
            return
        pname = process["process_name"].lower()
        if buf and "MZ" in buf and "This program" in buf:
            if pname in self.high_risk_proc:
                self.severity = 3
            if self.pid:
                self.mark_call()
            return True


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

"""
Compute the mean Apparent Fiber Density (AFD) and mean Radial fODF (radfODF)
maps along a bundle.

This is the "real" fixel-based fODF amplitude along every streamline
of the bundle provided, averaged at every voxel.

Please use a bundle file rather than a whole tractogram.
"""

import argparse
import itertools
import os
import multiprocessing
import shutil

from dipy.io.stateful_tractogram import Space, Origin, StatefulTractogram
from dipy.io.utils import create_nifti_header
import h5py
import nibabel as nib
import numpy as np

from scilpy.io.streamlines import reconstruct_streamlines_from_hdf5
from scilpy.io.utils import (add_overwrite_arg,
                             add_processes_arg,
                             add_sh_basis_args,
                             assert_inputs_exist,
                             assert_outputs_exist,
                             validate_nbr_processes)
from scilpy.tractanalysis.afd_along_streamlines \
    import afd_map_along_streamlines

EPILOG = """
Reference:
    [1] Raffelt, D., Tournier, JD., Rose, S., Ridgway, GR., Henderson, R.,
        Crozier, S., Salvado, O., & Connelly, A. (2012).
        Apparent Fibre Density: a novel measure for the analysis of
        diffusion-weighted magnetic resonance images. NeuroImage,
        59(4), 3976--3994.
"""

def _afd_rd_wrapper(args):
    in_hdf5_filename = args[0]
    key = args[1]
    fodf_img = args[2]
    sh_basis = args[3]
    length_weighting = args[4]

    with h5py.File(in_hdf5_filename, 'r') as in_hdf5_file:
        affine = in_hdf5_file.attrs['affine']
        dimensions = in_hdf5_file.attrs['dimensions']
        voxel_sizes = in_hdf5_file.attrs['voxel_sizes']
        streamlines = reconstruct_streamlines_from_hdf5(in_hdf5_file, key)
        if len(streamlines) == 0:
            return key, 0

    header = create_nifti_header(affine, dimensions, voxel_sizes)
    sft = StatefulTractogram(streamlines, header, Space.VOX,
                             origin=Origin.TRACKVIS)
    afd_mean_map, rd_mean_map = afd_map_along_streamlines(sft, fodf_img,
                                                          sh_basis,
                                                          length_weighting)
    afd_mean = np.average(afd_mean_map[afd_mean_map > 0])

    return key, afd_mean

def _build_arg_parser():
    p = argparse.ArgumentParser(description=__doc__, epilog=EPILOG,
                                formatter_class=argparse.RawTextHelpFormatter)
    p.add_argument('in_hdf5',
                   help='HDF5 filename (.h5) containing decomposed '
                        'connections.')
    p.add_argument('in_fodf',
                   help='Path of the fODF volume in spherical harmonics (SH).')
    p.add_argument('out_hdf5',
                   help='Path of the output HDF5 filenames (.h5).')

    p.add_argument('--length_weighting', action='store_true',
                   help='If set, will weigh the AFD values according to '
                        'segment lengths. [%(default)s]')

    add_processes_arg(p)
    add_sh_basis_args(p)
    add_overwrite_arg(p)
    return p

def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    assert_inputs_exist(parser, [args.in_hdf5, args.in_fodf])
    assert_outputs_exist(parser, args, [args.out_hdf5])

    nbr_cpu = validate_nbr_processes(parser, args)

    # HDF5 will not overwrite the file
    if os.path.isfile(args.out_hdf5):
        os.remove(args.out_hdf5)

    fodf_img = nib.load(args.in_fodf)
    in_hdf5_file = h5py.File(args.in_hdf5, 'r')
    if not (np.allclose(in_hdf5_file.attrs['affine'], fodf_img.affine,
                        atol=1e-03)
            and np.array_equal(in_hdf5_file.attrs['dimensions'],
                               fodf_img.shape[0:3])):
        parser.error('{} does not have a compatible header with {}'.format(
            args.in_hdf5, args.in_fodf))

    keys = list(in_hdf5_file.keys())
    in_hdf5_file.close()

    if nbr_cpu == 1:
        results_list = []
        for key in keys:
            results_list.append(_afd_rd_wrapper([args.in_hdf5, key, fodf_img,
                                                 args.sh_basis,
                                                 args.length_weighting]))

    else:
        pool = multiprocessing.Pool(nbr_cpu)
        results_list = pool.map(_afd_rd_wrapper,
                                zip(itertools.repeat(args.in_hdf5),
                                    keys,
                                    itertools.repeat(fodf_img),
                                    itertools.repeat(args.sh_basis),
                                    itertools.repeat(args.length_weighting)))
        pool.close()
        pool.join()

    shutil.copy(args.in_hdf5, args.out_hdf5)
    with h5py.File(args.out_hdf5, 'a') as out_hdf5_file:
        for key, afd_fixel in results_list:
            group = out_hdf5_file[key]
            if 'afd_fixel' in group:
                del group['afd_fixel']
            group.create_dataset('afd_fixel', data=afd_fixel)

if __name__ == '__main__':
    main()


import sys
import heapq

t = int(sys.stdin.readline())

for _ in range(t):
    k = int(sys.stdin.readline())

    visited = [False] * k
    max_heap = []
    min_heap = []

    for key in range(k):
        process, value = map(str, sys.stdin.readline().split())

        if process == "I":
            heapq.heappush(min_heap, (int(value), key))
            heapq.heappush(max_heap, (-int(value), key))
            visited[key] = True
        else:
            if value == "1":
                while max_heap and not visited[max_heap[0][1]]:
                    heapq.heappop(max_heap)
                if max_heap:
                    visited[max_heap[0][1]] = False
                    heapq.heappop(max_heap)
            else:
                while min_heap and not visited[min_heap[0][1]]:
                    heapq.heappop(min_heap)
                if min_heap:
                    visited[min_heap[0][1]] = False
                    heapq.heappop(min_heap)

    while min_heap and not visited[min_heap[0][1]]:
        heapq.heappop(min_heap)
    while max_heap and not visited[max_heap[0][1]]:
        heapq.heappop(max_heap)

    if not max_heap or not min_heap:
        print("EMPTY")
    else:
        print(-max_heap[0][0], min_heap[0][0])

백준/Gold/7662. 이중 우선순위 큐/이중 우선순위 큐.py

이중 우선순위 큐.py


from tkinter import ttk  # Normal Tkinter.* widgets are not themed!
from ttkthemes import ThemedTk
from tkinter import *
"""
所有主题使用方式
ThemedTk(theme="Adapta")
"""
Themes = [
    'adapta',  # 自适应式主题
    'aquativo',  # ?
    'arc',  #
    'black',
    'blue',
    'breeze',
    'clearlooks',
    'elegance',
    'equilux',
    'itft1',
    'keramik',
    'kroc',
    'plastik',
    'radiance',
    'scid themes',
    'smog',
    'winxpblue',
    'yaru'
]
# Window color
window = ThemedTk(theme=Themes[-1])
window.wm_minsize(500, 500)
window.configure(background='pink')

s = ttk.Style()
# Create style.css used by default for all Frames
s.configure('TFrame', background='green')
# Create style.css for the first frame
s.configure('Frame1.TFrame', background='red')
# Create style.css for the second frame
s.configure('Frame2.TFrame', background='blue')

# …………………………

F1 = ttk.Frame(window, style='Frame1.TFrame', height=100, width=100).pack()

# 标签框是一个简单的容器小部件。它的主要目的是充当复杂窗口布局的间隔物或容器
lfr = ttk.Labelframe(window, text='This is a A').pack(fill=BOTH, expand=True)
ttk.Label(lfr, text='Inside the LabelFrame').pack()
# x
bt = ttk.Button(window, text="Quit", command=window.destroy).pack()
mt = ttk.Menubutton(window, text='Menu').pack()
lt = ttk.Label(window, text='Doc').pack()
ttk.Entry(window).pack()
ttk.Checkbutton(window).pack()
ttk.Combobox(window).pack()
ttk.LabeledScale(window).pack()
ttk.Radiobutton(window).pack()
ttk.Progressbar(window).pack()
ttk.Scrollbar(window).pack()
ttk.Scale(window).pack()
#
ttk.Sizegrip(window).pack()
ttk.Spinbox(window).pack()
#
m1 = ttk.Panedwindow(window)
m1.pack(fill=BOTH, expand=1)
left = ttk.Label(m1, text='one')
m1.add(left)
#
"""插入列"""
tree = ttk.Treeview(window)
tree["columns"]=("one","two","three")
"""插入行"""
tree.insert('', 'end', 'widgets', text='Widget Tour')
tree.insert('', 0, 'gallery', text='Applications')
# Treeview chooses the id:
id = tree.insert('', 'end', text='Tutorial')

# Inserted underneath an existing node:
tree.insert('widgets', 'end', text='Canvas')
tree.insert(id, 'end', text='Tree')
tree.pack(side=TOP , fill=X)
#

# ttk.OptionMenu(window).pack()
options = [1,2,3,4]
value = StringVar()
value.set(options[1])

dropdown = ttk.OptionMenu(window, value, *options).pack()
# 选项卡标签
note = ttk.Notebook(window)
F2 = ttk.Frame(window, style='Frame2.TFrame')
note.add(F2, text='Tab-1')
note.pack(expand=True, fill=BOTH)

window.mainloop()


import time

from utils import open_file

day = 1
year = 2015

TESTSTRING = ''')())())'''
STRING = ''''''

def run1():
    string = open_file(day, year)
    floor = string.count('(') - string.count(')')
    return floor

def run2():
    string = open_file(day, year)
    floor = 0
    for i, s in enumerate(string):
        if s == '(':
            floor += 1
        elif s == ')':
            floor -= 1

        if floor < 0:
            return i + 1

if __name__ == "__main__":
    a = time.time()
    f = run1()
    g = run2()
    print(time.time() - a)
    print(f"Part 1", f)
    print(f"Part 2", g)


import torch
import torch.nn as nn
from left_vertex import DownConvolution
from right_vertex import UpConvolution
from last_convolution import LastConvolution
from simple_convolution import SimpleConvolution
from image_cropper import crop_img

class UNet(nn.Module):
	def __init__(self,input_channels,num_classes):
		super(UNet,self).__init__()
		self.simpleConv = SimpleConvolution(input_channels, 64)
		self.downConvBlock1 = DownConvolution(64,128)
		self.downConvBlock2 = DownConvolution(128,256)
		self.downConvBlock3 = DownConvolution(256,512)
		self.midMaxpool = nn.MaxPool2d(2,2)
		self.bridge = UpConvolution(512,1024)
		self.upConvBlock1 = UpConvolution(1024,512)
		self.upConvBlock2 = UpConvolution(512,256)
		self.upConvBlock3 = UpConvolution(256,128)
		self.lastConv = LastConvolution(128,64,num_classes)

	def forward(self,x):
		x_1 = self.simpleConv(x)
		x_2 = self.downConvBlock1(x_1)
		x_3 = self.downConvBlock2(x_2)
		x_4 = self.downConvBlock3(x_3)
		x_5 = self.midMaxpool(x_4)
		x_6 = self.bridge(x_5)
		crop_x_4 = crop_img(x_4,x_6)
		concat_x_4_6 = torch.cat((crop_x_4,x_6),1)
		x_7 = self.upConvBlock1(concat_x_4_6)
		crop_x_3 = crop_img(x_3,x_7)
		concat_x_3_7 = torch.cat((crop_x_3,x_7),1)
		x_8 = self.upConvBlock2(concat_x_3_7)
		crop_x_2 = crop_img(x_2,x_8)
		concat_x_2_8 = torch.cat((crop_x_2,x_8),1)
		x_9 = self.upConvBlock3(concat_x_2_8)
		crop_x_1 = crop_img(x_1,x_9)
		concat_x_1_9 = torch.cat((crop_x_1,x_9),1)
		out = self.lastConv(concat_x_1_9)
		return out

if __name__ == '__main__':
	unet = UNet(3,2)
	inp = torch.rand(4,3,572,572)
	out = unet(inp)
	print(out.size())


"""project URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app.views import home, cadastro, create, vizualizar, editar, alterar, deletar

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home, name='home'),
    path('cadastro/', cadastro, name='cadastro'),
    path('create/', create, name='create'),
    path('vizualizar/<int:pk>/', vizualizar, name='vizualizar'),
    path('editar/<int:pk>/', editar, name='editar'),
    path('alterar/<int:pk>/', alterar, name='alterar'),
    path('deletar/<int:pk>/', deletar, name='deletar'),
]


#!/usr/bin/env python
import liqui_client

domain = "api.liqui.io"

attrs = ('high', 'low', 'avg', 'vol', 'vol_cur', 'last',
         'buy', 'sell', 'updated')

print("Tickers:")
connection = liqui_client.BTCEConnection(domain)

info = liqui_client.APIInfo(connection)
for pair in info.pair_names:
    ticker = liqui_client.getTicker(pair, connection)
    print(pair)
    for a in attrs:
        print("\t%s %s" % (a, getattr(ticker, a)))


"""
Based on the original memory.py from keras-rl (https://github.com/keras-rl/keras-rl).
Extended to handle an ensemble of agents with separate neural networks, which are trained on separate replay memories.
"""

from rl.memory import Memory, RingBuffer, zeroed_observation
import numpy as np
import warnings
from collections import namedtuple

# This is to be understood as a transition: Given `state0`, performing `action`
# yields `reward` and results in `state1`, which might be `terminal`.
Experience = namedtuple('Experience', 'state0, action, reward, state1, terminal1')

class BootstrappingMemory(Memory):
    """
    Replay memory for ensemble, with separate memories for different ensemble members.

    The replay memory consists of a circular buffer that stores experiences.
    To limit memory usage, only one replay memory is maintained, and the separate replay memories of each
    ensemble member are created by referencing different subsets of the joint replay memory.

    Args:
        nb_nets (int): Number of ensemble members.
        limit(int): Replay memory size.
        adding_prob (float): Probability of adding an experience to the replay memory of each ensemble member.
        **kwargs: contains:
            window_length (int): Number of states in the network input.
    """
    def __init__(self, nb_nets, limit, adding_prob=0.5, **kwargs):
        super(BootstrappingMemory, self).__init__(**kwargs)
        self.nb_nets = nb_nets
        self.adding_prob = adding_prob
        self.limit = limit
        self.index_refs = [[] for i in range(self.nb_nets)]

        # Do not use deque to implement the memory. This data structure may seem convenient but
        # it is way too slow on random access. Instead, we use our own ring buffer implementation.
        self.actions = RingBuffer(limit)
        self.rewards = RingBuffer(limit)
        self.terminals = RingBuffer(limit)
        self.observations = RingBuffer(limit)

    def sample(self, net, batch_size):
        """
        Returns a randomized batch of experiences for an ensemble member
        Args:
            net (int): Index of ensemble member
            batch_size (int): Size of the batch

        Returns:
            A list of random experiences
        """
        # It is not possible to tell whether the first state in the memory is terminal, because it
        # would require access to the "terminal" flag associated to the previous state. As a result
        # we will never return this first state (only using `self.terminals[0]` to know whether the
        # second state is terminal).
        # In addition we need enough entries to fill the desired window length.
        assert self.nb_entries >= self.window_length + 2, 'not enough entries in the memory'

        # Sample random indexes for the specified ensemble member
        batch_idxs = self.sample_batch_idxs(net, batch_size)

        assert np.min(batch_idxs) >= self.window_length + 1
        assert np.max(batch_idxs) < self.nb_entries
        assert len(batch_idxs) == batch_size

        # Create experiences
        experiences = []
        for idx in batch_idxs:
            terminal0 = self.terminals[idx - 2]
            while terminal0:
                # Skip this transition because the environment was reset here. Select a new, random
                # transition and use this instead. This may cause the batch to contain the same
                # transition twice.
                # idx = sample_batch_indexes(self.window_length + 1, self.nb_entries, size=1)[0]
                idx = self.sample_batch_idxs(net, 1)[0]
                terminal0 = self.terminals[idx - 2]
            assert self.window_length + 1 <= idx < self.nb_entries

            # This code is slightly complicated by the fact that subsequent observations might be
            # from different episodes. We ensure that an experience never spans multiple episodes.
            # This is probably not that important in practice but it seems cleaner.
            state0 = [self.observations[idx - 1]]
            for offset in range(0, self.window_length - 1):
                current_idx = idx - 2 - offset
                assert current_idx >= 1
                current_terminal = self.terminals[current_idx - 1]
                if current_terminal and not self.ignore_episode_boundaries:
                    # The previously handled observation was terminal, don't add the current one.
                    # Otherwise we would leak into a different episode.
                    break
                state0.insert(0, self.observations[current_idx])
            while len(state0) < self.window_length:
                state0.insert(0, zeroed_observation(state0[0]))
            action = self.actions[idx - 1]
            reward = self.rewards[idx - 1]
            terminal1 = self.terminals[idx - 1]

            # Okay, now we need to create the follow-up state. This is state0 shifted on timestep
            # to the right. Again, we need to be careful to not include an observation from the next
            # episode if the last state is terminal.
            state1 = [np.copy(x) for x in state0[1:]]
            state1.append(self.observations[idx])

            assert len(state0) == self.window_length
            assert len(state1) == len(state0)
            experiences.append(Experience(state0=state0, action=action, reward=reward,
                                          state1=state1, terminal1=terminal1))
        assert len(experiences) == batch_size
        return experiences

    def sample_batch_idxs(self, net, batch_size):
        """
        Sample random replay memory indexes from the list of replay memory indexes of the specified ensemble member.

        Args:
            net (int): Index of ensemble member
            batch_size (int): Size of the batch

        Returns:
            A list of replay memory indexes.
        """
        memory_size = len(self.index_refs[net])
        assert memory_size > self.window_length + 1
        if batch_size > memory_size:
            warnings.warn("Less samples in memory than batch size.")
        ref_idxs = np.random.randint(0, memory_size, batch_size)
        batch_idxs = [self.index_refs[net][idx] for idx in ref_idxs]
        assert len(batch_idxs) == batch_size
        return batch_idxs

    def append(self, observation, action, reward, terminal, training=True):
        """Append an observation to the replay memory.

        With probability self.adding_prob, the index of the added experience will be added to the index list of each
        ensemble replay memory.

        Args:
            observation (dict): Observation returned by environment
            action (int): Action taken to obtain this observation
            reward (float): Reward obtained by taking this action
            terminal (boolean): Is the state terminal
            training (boolean): True during training episodes, false during testing episodes.
        """
        super(BootstrappingMemory, self).append(observation, action, reward, terminal, training=training)

        if training:
            if self.nb_entries < self.limit:   # One more entry will be added after this loop
                # There should be enough experiences before the chosen sample to fill the window length + 1
                if self.nb_entries > self.window_length + 1:
                    for i in range(self.nb_nets):
                        if np.random.rand() < self.adding_prob:
                            self.index_refs[i].append(self.nb_entries)

        # This needs to be understood as follows: in `observation`, take `action`, obtain `reward`
        # and weather the next state is `terminal` or not.
        if training:
            self.observations.append(observation)
            self.actions.append(action)
            self.rewards.append(reward)
            self.terminals.append(terminal)

    @property
    def nb_entries(self):
        """Return number of observations

        Returns:
            Number of observations
        """
        return len(self.observations)

    def get_config(self):
        """Return configurations of SequentialMemory

        Returns:
            Dict of config
        """
        config = super(BootstrappingMemory, self).get_config()
        config['limit'] = self.limit
        return config


import pandas as pd

data = pd.read_csv("nato_phonetic_alphabet.csv")
new_dict = {row.letter: row.code for (index, row) in data.iterrows()}

def phonetic_generator():
    user_input = input("Please insert your name: ").upper()
    try:
        output_list = [new_dict[letter] for letter in user_input]
    except KeyError:
        print("Sorry! only letters are allowed")
        phonetic_generator()
    else:
        print(output_list)

phonetic_generator()


from globals import *

__all__ = ['special_hit', 'cough_up', 'orc_gold', 'check_orc', 'check_xeroc',
           'hiding_xeroc', 'm_confuse', 'flame_broil']

def special_hit(monster):
    k = monster.ichar
    if k == 'A':
        rust(monster)
    elif k == 'F':
        g.being_held = 1
    elif k == 'I':
        freeze(monster)
    elif k == 'L':
        steal_gold(monster)
    elif k == 'N':
        steal_item(monster)
    elif k == 'R':
        sting(monster)
    elif k == 'V':
        drain_life()
    elif k == 'W':
        drain_level()

def rust(monster):
    if not rogue.armor or get_armor_class(rogue.armor) <= 1 or rogue.armor.which_kind == LEATHER:
        return
    if rogue.armor.is_protected:
        if not monster.identified:
            message("the rust vanishes instantly", 0)
            monster.identified = 1
    else:
        rogue.armor.damage_enchantment -= 1
        message("your armor weakens", 0)
        print_stats()

def freeze(monster):
    if rand_percent(12): return

    freeze_percent = 99
    freeze_percent -= rogue.strength_current + rogue.strength_current / 2
    freeze_percent -= rogue.exp * 4
    freeze_percent -= get_armor_class(rogue.armor) * 5
    freeze_percent -= rogue.hp_max / 3

    if freeze_percent > 10:
        monster.identified = 1
        message("you are frozen", 1)

        n = get_rand(5, 9)
        for i in range(n):
            move_monsters()
        if rand_percent(freeze_percent):
            for i in range(50):
                move_monsters()
            killed_by(None, HYPOTHERMIA)
        message("you can move again", 1)
        monster.identified = 0

def steal_gold(monster):
    if rand_percent(15): return

    if rogue.gold > 50:
        amount = get_rand(8, 15) if rogue.gold > 1000 else get_rand(2, 5)
        amount = rogue.gold / amount
    else:
        amount = rogue.gold / 2
    amount += (get_rand(0, 2) - 1) * (rogue.exp + g.current_level)

    if amount <= 0 and rogue.gold > 0:
        amount = rogue.gold

    if amount > 0:
        rogue.gold -= amount
        message("your purse feels lighter", 0)
        print_stats()

    disappear(monster)

def steal_item(monster):
    if rand_percent(15): return

    has_something = 0
    obj = rogue.pack.next_object
    while obj:
        if obj != rogue.armor and obj != rogue.weapon:
            has_something = 1
            break
        obj = obj.next_object
    if has_something:
        n = get_rand(0, MAX_PACK_COUNT)
        obj = rogue.pack.next_object

        for i in range(n + 1):
            obj = obj.next_object
            while not obj or obj == rogue.armor or obj == rogue.weapon:
                if not obj:
                    obj = rogue.pack.next_object
                else:
                    obj = obj.next_object
        message("she stole " + get_description(obj), 0)

        if obj.what_is == AMULET:
            g.has_amulet = 0
        vanish(obj, 0)
    disappear(monster)

def disappear(monster):
    row = monster.row
    col = monster.col

    remove_mask(row, col, MONSTER)
    if can_see(row, col):
        mvaddch(row, col, get_room_char(screen[row][col], row, col))
    remove_from_pack(monster, g.level_monsters)

def cough_up(monster):
    if g.current_level < g.max_level: return

    if monster.ichar == 'L':
        obj = get_an_object()
        obj.what_is = GOLD
        obj.quantity = get_rand(9, 599)
    else:
        if rand_percent(monster.which_kind):
            obj = get_rand_object()
        else:
            return

    row = monster.row
    col = monster.col

    for n in range(6):
        for i in range(-n, n + 1):
            if try_to_cough(row + n, col + i, obj):
                return
            if try_to_cough(row - n, col + i, obj):
                return
        for i in range(-n, n + 1):
            if try_to_cough(row + i, col - n, obj):
                return
            if try_to_cough(row + i, col + n, obj):
                return

def try_to_cough(row, col, obj):
    if row < MIN_ROW or row > LINES - 2 or col < 0 or col > COLS - 1:
        return 0
    if not screen[row][col] & IS_OBJECT and not screen[row][col] & MONSTER and screen[row][col] & (TUNNEL | FLOOR | DOOR):
        put_object_at(obj, row, col)
        mvaddch(row, col, get_room_char(screen[row][col], row, col))
        refresh()
        return 1
    return 0

def orc_gold(monster):
    if monster.identified:
        return 0
    rn = get_room_number(monster.row, monster.col)
    if rn < 0:
        return 0
    r = rooms[rn]
    for i in range(r.top_row + 1, r.bottom_row):
        for j in range(r.left_col + 1, r.right_col):
            if screen[i][j] & GOLD and not screen[i][j] & MONSTER:
                monster.m_flags |= CAN_GO
                s = monster_can_go(monster, i, j)
                monster.m_flags &= ~CAN_GO
                if s:
                    move_monster_to(monster, i, j)
                    monster.m_flags |= IS_ASLEEP
                    monster.m_flags &= ~WAKENS
                    monster.identified = 1
                    return 1
                monster.identified = 1
                monster.m_flags |= CAN_GO
                mv_monster(monster, i, j)
                monster.m_flags &= ~CAN_GO
                monster.identified = 0
                return 1
    return 0

def check_orc(monster):
    if monster.ichar == 'O':
        monster.identified = 1

def check_xeroc(monster):
    if monster.ichar == 'X' and monster.identified:
        wake_up(monster)
        monster.identified = 0
        mvaddch(monster.row, monster.col, get_room_char(screen[monster.row][monster.col], monster.row, monster.col))
        check_message()
        message("wait, that's a %s!" % monster_name(monster), 1)
        return 1
    return 0

def hiding_xeroc(row, col):
    if g.current_level < XEROC1 or g.current_level > XEROC2 or not screen[row][col] & MONSTER:
        return 0

    monster = object_at(g.level_monsters, row, col)
    return monster.ichar == 'X' and monster.identified

def sting(monster):
    if rogue.strength_current < 5: return

    sting_chance = 35
    ac = get_armor_class(rogue.armor)
    sting_chance += 6 * (6 - ac)

    if rogue.exp > 8:
        sting_chance -= 6 * (rogue.exp - 8)

    sting_chance = max(min(sting_chance, 100), 1)

    if rand_percent(sting_chance):
        message("the %s's bite has weakened you" % monster_name(monster), 0)
        rogue.strength_current -= 1
        print_stats()

def drain_level():
    if not rand_percent(20) or rogue.exp < 8:
        return

    rogue.exp_points = level_points[rogue.exp - 2] - get_rand(10, 50)
    rogue.exp -= 2
    add_exp(1)

def drain_life():
    if not rand_percent(25) or rogue.hp_max <= 30 or rogue.hp_current < 10:
        return
    message("you feel weaker", 0)
    rogue.hp_max -= 1
    rogue.hp_current -= 1
    if rand_percent(50):
        if rogue.strength_current >= 5:
            rogue.strength_current -= 1
            if rand_percent(50):
                rogue.strength_max -= 1
    print_stats()

def m_confuse(monster):
    if monster.identified:
        return 0
    if not can_see(monster.row, monster.col):
        return 0
    if rand_percent(45):
        monster.identified = 1
        return 0
    if rand_percent(55):
        monster.identified = 1
        message("the gaze of the %s has confused you" % monster_name(monster), 1)
        confuse()
        return 1
    return 0

def flame_broil(monster):
    if rand_percent(50):
        return 0
    row, col = monster.row, monster.col
    if not can_see(row, col):
        return 0
    if not rogue_is_around(row, col):
        row, col = get_closer(row, col, rogue.row, rogue.col)
        standout()
        while True:
            mvaddch(row, col, '*')
            refresh()
            row, col = get_closer(row, col, rogue.row, rogue.col)
            if row == rogue.row and col == rogue.col: break
        standend()

        row, col = get_closer(monster.row, monster.col, rogue.row, rogue.col)
        while True:
            mvaddch(row, col, get_room_char(screen[row][col], row, col))
            refresh()
            row, col = get_closer(row, col, rogue.row, rogue.col)
            if row == rogue.row and col == rogue.col: break
    monster_hit(monster, "flame")
    return 1

def get_closer(row, col, trow, tcol):
    if row < trow:
        row += 1
    elif row > trow:
        row -= 1
    if col < tcol:
        col += 1
    elif col > tcol:
        col -= 1
    return row, col


import os
from scipy.spatial.distance import euclidean
from baseClasses.PreProcessingStep import *

class CenterFace(PreProcessingStep):

    def findBiggerValue(self,points):
        biggerValues = -float('inf')
        idxBigger = -1
        for p in range(len(points)):
            if (points[p][2] > biggerValues):
                biggerValues = points[p][2]
                idxBigger = p

        return idxBigger

    def doPreProcessing(self,template):
        bigger = self.findBiggerValue(template.image)
        template.image = bigger - template.image
        if (os.path.exists(template.rawRepr[0:-4]+'_centered.obj')):
            os.remove(template.rawRepr[0:-4]+'_centered.obj')
        return template


from __future__ import annotations

from credentials import gpt_api_key

from typing import Any, Dict, List, Optional

from pydantic import Extra

from langchain.base_language import BaseLanguageModel
from langchain.callbacks.manager import (
    AsyncCallbackManagerForChainRun,
    CallbackManagerForChainRun,
)
from langchain.chains.base import Chain
from langchain.prompts.base import BasePromptTemplate
from langchain.callbacks.stdout import StdOutCallbackHandler
from langchain.chat_models.openai import ChatOpenAI
from langchain.prompts.prompt import PromptTemplate

class MyCustomChain(Chain):
    """
    An example of a custom chain.
    """

    prompt: BasePromptTemplate
    """Prompt object to use."""
    llm: BaseLanguageModel
    output_key: str = "text"  #: :meta private:

    class Config:
        """Configuration for this pydantic object."""

        extra = Extra.forbid
        arbitrary_types_allowed = True

    @property
    def input_keys(self) -> List[str]:
        """Will be whatever keys the prompt expects.

        :meta private:
        """
        return self.prompt.input_variables

    @property
    def output_keys(self) -> List[str]:
        """Will always return text key.

        :meta private:
        """
        return [self.output_key]

    def _call(
        self,
        inputs: Dict[str, Any],
        run_manager: Optional[CallbackManagerForChainRun] = None,
    ) -> Dict[str, str]:
        # Your custom chain logic goes here
        # This is just an example that mimics LLMChain
        prompt_value = self.prompt.format_prompt(**inputs)

        # Whenever you call a language model, or another chain, you should pass
        # a callback manager to it. This allows the inner run to be tracked by
        # any callbacks that are registered on the outer run.
        # You can always obtain a callback manager for this by calling
        # `run_manager.get_child()` as shown below.
        response = self.llm.generate_prompt(
            [prompt_value], callbacks=run_manager.get_child() if run_manager else None
        )

        # If you want to log something about this run, you can do so by calling
        # methods on the `run_manager`, as shown below. This will trigger any
        # callbacks that are registered for that event.
        if run_manager:
            run_manager.on_text("Log something about this run")

        return {self.output_key: response.generations[0][0].text}

    async def _acall(
        self,
        inputs: Dict[str, Any],
        run_manager: Optional[AsyncCallbackManagerForChainRun] = None,
    ) -> Dict[str, str]:
        # Your custom chain logic goes here
        # This is just an example that mimics LLMChain
        prompt_value = self.prompt.format_prompt(**inputs)

        # Whenever you call a language model, or another chain, you should pass
        # a callback manager to it. This allows the inner run to be tracked by
        # any callbacks that are registered on the outer run.
        # You can always obtain a callback manager for this by calling
        # `run_manager.get_child()` as shown below.
        response = await self.llm.agenerate_prompt(
            [prompt_value], callbacks=run_manager.get_child() if run_manager else None
        )

        # If you want to log something about this run, you can do so by calling
        # methods on the `run_manager`, as shown below. This will trigger any
        # callbacks that are registered for that event.
        if run_manager:
            await run_manager.on_text("Log something about this run")

        return {self.output_key: response.generations[0][0].text}

    @property
    def _chain_type(self) -> str:
        return "my_custom_chain"

if __name__ == "__main__":
    chain = MyCustomChain(
        prompt=PromptTemplate.from_template(
            """
You are an agent designed to extract key information about cricket, from a question.
Most, if not all questions will be based on cricket statistics.

These are the key bits of information you should extract:
Names: The name(s) of the players in the question. This might be the first name and/or last name.
Format:  - T20I can be referred to as Twenty20 or Twenty twenty but return T20I if those are the case
         - ODI can be referred to as one-dayers, 50-over cricket or one-day but return ODI
         - White ball refers to ODI and T20I, therefore you return "T20I and ODI".
         - Test is only other format in cricket, if spotted return Test
         - Red ball refers to Test matches, therefore return "Test".
Teams: The team(s) in the question
Statistic: The statistic the question is involving, examples include:
                - Batting average
                - Batting strike rate
                - Bowling strike rate
                - Bowling average
                - Wickets
                - Economy
                - Runs
                - Balls
                - Boundaries
                - 4s
                - 6s
                - No balls
                - Wides
                - Maidens

After extracting the key info, understand how to calculate what is being asked IF A CALCULATION IS NEEDED.

Here are some useful definitions that will help you understand how to calculate statistics:
        - STAT: HOW TO CALCULATE IT
        - Batting average: runs divided by (number of times they have gotten out)
        - Bowling average: runs conceded / wickets taken
        - Bowling strike rate: balls / wickets
        - Batting strike rate: (runs / balls) * 100
        - An over has 6 balls. Therefore if a bowler has bowled 4.2 overs, they have bowled 4 complete overs and 2 more balls amounting in 26 balls.
        - Boundaries: 4s and 6s

Given the input question, return the information in this fashion if the question contains any of the below:
Name|Format|Teams|Statistic|Calculation Required

Example 1: "What is Virat Kohli's average in T20Is?"
You return:
Virat Kohli|T20I||Batting or bowling average|[runs / number of times they have gotten out OR runs / wickets]
You return "runs / number of times they gotten out OR runs / wickets" because you do not know which average the question is asking about.
Therefore, you must return both types of average definitions you know. However, if a type of average has been specified, return just that one.
Apply the same logic to strike rate.

Example 2: "List the white ball games for Australia where Smith has had a strike rate over 150."
You return:
Smith|T20I and ODI|Australia|Strike rate|[(runs / balls) * 100 OR balls / wickets]

Example 3: "Which Test matches have had a bowler get 8 or more wickets in an innings?"
You return:
|Test||Wickets|---

Example 4: "What was Dale Steyn's bowling average in Test matches in 2010?"
You return:
Dale Steyn|Test||Bowling average|[runs / wickets]

Example 5: "What was Rohit Sharma's batting average in red ball matches in 2014?"
You return:
Rohit Sharma|Test||Batting average|[runs / number of times they have gotten out]

Begin!
Question: {input}
"""
        ),
        llm=ChatOpenAI(
            temperature=0,
            openai_api_key=gpt_api_key,
            model="gpt-3.5-turbo",
        ),
    )

    print(
        chain.run(
            {"input": "List the bowlers that have gotten 100 runs and a wicket?"},
            callbacks=[StdOutCallbackHandler()],
        )
    )


from config import default_detection_configs
from backbone import EfficientNet, Conv_BN
from loss import *
from keras.layers import Input, Conv2D, MaxPooling2D, Lambda, Softmax, ReLU, add, SeparableConv2D, BatchNormalization, Activation
from keras.models import Model
from keras.optimizers import adam
import tensorflow as tf
import keras.backend as K
import numpy as np
import os

def EfficientDet(lr=3e-4, decay=5e-6):

    config = default_detection_configs()

    # image input
    input_shape = config['input_shape']
    inpt = Input(input_shape)

    # y_true input
    n_points = config['num_points']
    n_classes = config['num_classes']
    h ,w = inpt._keras_shape[1:3]
    y_true = [Input(shape=(h//2**l, w//2**l, n_points*(2+n_classes))) for l in range(config['min_out_level'], config['max_out_level']+1)]

    # backbone
    x = build_backbone(inpt, config)       # dict{3:8x, 4:16x, 5: 32x}

    # feature network
    x = build_feature_network(x, config)        # list[P3", P4", P5", P6", P7"]

    # heads
    cls_outputs, kp_outputs = build_class_and_box_outputs(x, config)       # [8xhead3, 128xhead7]

    # model
    scales = [2**l for l in range(config['min_out_level'], config['max_out_level']+1)]
    model_loss = Lambda(kp_loss, arguments={'n_classes': n_classes, 'n_points': n_points, 'scales': scales})  \
                        ([*cls_outputs, *kp_outputs, *y_true])
    model = Model([inpt, *y_true], model_loss)

    model.compile(adam(lr, decay),
                  loss=lambda y_true, y_pred: y_pred,
                  metrics=None)

    return model

def build_backbone(x, config):
    eff_back = EfficientNet(config['input_shape'], config['width_coefficient'], config['depth_coefficient'], config['dropout_rate'])
    if config['pretrained'] and os.path.exists(config['pretrained']):
        eff_back.load_weights(config['pretrained'])
    features = eff_back(x)         # [x4, x8, x16, x32]
    # return level3-level5 features (8x-32x)
    return {3:features[1], 4:features[2], 5:features[3]}

def build_feature_network(x, config):
    feats = []
    for level in range(config['min_level'], config['max_level']+1):   # [C3,C7]
        if level in x.keys():
            feats.append(x[level])
        else:
            # Adds a coarser level by downsampling the last feature map
            target_h = (feats[-1]._keras_shape[1] - 1)//2 + 1
            target_w = (feats[-1]._keras_shape[2] - 1)//2 + 1
            target_c = config['fpn_num_filters']
            feats.append(resample_feature_map(feats[-1], target_h, target_w, target_c))

    for i in range(config['fpn_cell_repeats']):
        feats = build_bifpn(feats, config)

    # return level3-level7 fpn features (8x-128x)
    return feats

def build_class_and_box_outputs(x, config):
    class_outputs = []
    box_outputs = []
    for level in range(config['min_out_level'], config['max_out_level']+1):
        class_outputs.append(class_net(x[level-config['min_level']],
                                       n_classes=config['num_classes'],
                                       n_points=config['num_points'],
                                       n_filters=config['conv_filters'],
                                       act_type=config['activation_type'],
                                       repeats=config['box_class_repeats'],
                                       survival_prob=config['survival_prob']))
        box_outputs.append(box_net(x[level-config['min_level']],
                                   n_points=config['num_points'],
                                   n_filters=config['conv_filters'],
                                   act_type=config['activation_type'],
                                   repeats=config['box_class_repeats'],
                                   survival_prob=config['survival_prob']))
    return class_outputs, box_outputs

def class_net(x, n_classes, n_points, n_filters, act_type,
              repeats=3, separable_conv=True, survival_prob=None):
    # conv-bn-swish + id
    for i in range(repeats):
        inpt = x
        if separable_conv:
            x = SeparableConv2D(n_filters, kernel_size=3, strides=1, padding='same',
                                depthwise_initializer=tf.initializers.variance_scaling(),
                                pointwise_initializer=tf.initializers.variance_scaling(),
                                bias_initializer=tf.zeros_initializer())(x)
        else:
            x = Conv2D(n_filters, kernel_size=3, strides=1, padding='same',
                       kernel_initializer=tf.random_normal_initializer(stddev=0.01),
                       bias_initializer=tf.zeros_initializer())(x)
        x = BatchNormalization()(x)
        x = Activation(act_type)(x)
        if i>0 and survival_prob:
            x = Lambda(drop_connect, arguments={'survival_prob': survival_prob, 'is_training': True})(x)
        x = add([x, inpt])

    # head
    x = Conv2D(n_classes*n_points, kernel_size=3, strides=1, padding='same',
               bias_initializer=tf.constant_initializer(-np.log((1 - 0.01) / 0.01)))(x)

    return x

def box_net(x, n_points, n_filters, act_type,
            repeats=3, separable_conv=True, survival_prob=None):
    # conv-bn-swish + id
    for i in range(repeats):
        inpt = x
        if separable_conv:
            x = SeparableConv2D(n_filters, kernel_size=3, strides=1, padding='same',
                                depthwise_initializer=tf.initializers.variance_scaling(),
                                pointwise_initializer=tf.initializers.variance_scaling(),
                                bias_initializer=tf.zeros_initializer())(x)
        else:
            x = Conv2D(n_filters, kernel_size=3, strides=1, padding='same',
                       kernel_initializer=tf.random_normal_initializer(stddev=0.01),
                       bias_initializer=tf.zeros_initializer())(x)
        x = BatchNormalization()(x)
        x = Activation(act_type)(x)
        if i>0 and survival_prob:
            x = Lambda(drop_connect, arguments={'survival_prob': survival_prob, 'is_training': True})(x)
        x = add([x, inpt])

    # head
    x = Conv2D(2*n_points, kernel_size=3, strides=1, padding='same',
               bias_initializer=tf.zeros_initializer())(x)

    return x

def drop_connect(x, survival_prob, is_training=False):
    # Unlike conventional way that multiply survival_prob at test time, here we
    # divide survival_prob at training time, such that no addition compute is
    # needed at test time.
    if not is_training:
        return x

    # Compute tensor.
    batch_size = tf.shape(x)[0]
    random_tensor = tf.random.uniform([batch_size, 1, 1, 1], dtype=x.dtype)
    binary_tensor = tf.floor(random_tensor)
    x = tf.div(x, survival_prob) * binary_tensor
    return x

def build_bifpn(feats, config):
    # Node id starts from the input features and monotonically increase whenever
    # a new node is added. Here is an example for level P3 - P7:
    #     P7 (4)              P7" (12)
    #     P6 (3)    P6' (5)   P6" (11)
    #     P5 (2)    P5' (6)   P5" (10)
    #     P4 (1)    P4' (7)   P4" (9)
    #     P3 (0)              P3" (8)
    fpn_nodes = [{'feat_level': 6, 'inputs_offsets': [3, 4]},  # for P6'
                 {'feat_level': 5, 'inputs_offsets': [2, 5]},  # for P5'
                 {'feat_level': 4, 'inputs_offsets': [1, 6]},  # for P4'
                 {'feat_level': 3, 'inputs_offsets': [0, 7]},  # for P3"
                 {'feat_level': 4, 'inputs_offsets': [1, 7, 8]},  # for P4"
                 {'feat_level': 5, 'inputs_offsets': [2, 6, 9]},  # for P5"
                 {'feat_level': 6, 'inputs_offsets': [3, 5, 10]},  # for P6"
                 {'feat_level': 7, 'inputs_offsets': [4, 11]}]  # for P7"

    for i, fpn_node in enumerate(fpn_nodes):
        new_node_h, new_node_w = feats[fpn_node['feat_level']-config['min_level']]._keras_shape[1:3]
        nodes_in = []
        for idx, inputs_offset in enumerate(fpn_node['inputs_offsets']):
            input_node = feats[inputs_offset]
            input_node = resample_feature_map(input_node, new_node_h, new_node_w, config['fpn_num_filters'])
            nodes_in.append(input_node)
        new_node = Lambda(fuse_features, arguments={'weight_method': 'fast'})(nodes_in)
        new_node = Conv_BN(new_node, config['fpn_num_filters'], activation=None)
        feats.append(new_node)

    fpn_feats = feats[-5:]

    return fpn_feats         # [P3", P4", P5", P6", P7"]

def fuse_features(nodes_in, weight_method='fast'):
    if weight_method=='softmax':
        weights = [tf.Variable(1.) for i in nodes_in]
        normed_weights = tf.unstack(K.softmax(tf.stack(weights)))
        new_node = add([nodes_in[i] * normed_weights[i] for i in range(len(nodes_in))])
    elif weight_method=='fast':
        weights = [ReLU()(tf.Variable(1.)) for i in nodes_in]
        normed_weights = tf.unstack((tf.stack(weights)/(K.sum(weights)+K.epsilon())))
        new_node = add([nodes_in[i] * normed_weights[i] for i in range(len(nodes_in))])
    else:  # normal sum
        new_node = add(nodes_in)
    return new_node

def resample_feature_map(x, target_h, target_w, target_c):
    # 1x1 conv if channel not match, conv-bn-swish
    x = Conv_BN(x, target_c, kernel_size=1, strides=1)
    # resize
    h, w = x._keras_shape[1:3]
    if h > target_h and w > target_w:
        h_stride = int((h - 1)//target_h + 1)
        w_stride = int((w - 1)//target_w + 1)
        x = MaxPooling2D(pool_size=(h_stride+1, w_stride+1), strides=(h_stride,w_stride), padding='same')(x)
    elif h <= target_h and w <= target_w:
        x = Lambda(tf.image.resize_nearest_neighbor, arguments={'size': [target_h, target_w]})(x)
    else:
        print("Incompatible target feature map size")
    return x

if __name__ == '__main__':

    model = EfficientDet()
    model.summary()


from enum import unique
from django.db import models
from users.models import NewUser

# Create your models here.
# class Speciality(models.Model):
#     letter = models.CharField(max_length=10, unique=True)
#     describe = models.TextField(blank=True)

# class Level(models.Model):
#     num = models.IntegerField(unique=True)
#     describe = models.TextField(blank=True)

# class Classe(models.Model):
#     level = models.ForeignKey(Level, on_delete=models.CASCADE)
#     speciality = models.ForeignKey(Speciality, on_delete=models.CASCADE, related_name='spec_class')

class Classe(models.Model):
    SPECIALITIES = [
        ('C', 'Mathematique'),
        ('D', 'Science'),
        ('TI', 'Informatique'),
        ('ALL', 'Allemand'),
        ('ESP', 'Espagnol'),
        ('N', 'None'),
    ]
    LEVELS = [
        ('6', '6 eime'),
        ('5', '5 eime'),
        ('4', '4 eime'),
        ('3', '3 eime'),
        ('2', 'seconde'),
        ('1', 'premiere'),
        ('0', 'terminale'),
    ]
    level = models.CharField(
        max_length=2,
        choices=LEVELS,
        null=True,
        blank=True
        # Level, on_delete=models.CASCADE
    )
    speciality = models.CharField(
        # Speciality, on_delete=models.CASCADE, related_name='spec_class'
        max_length=7,
        choices=SPECIALITIES,
        null=True,
        blank=True
    )

class ClassRoom(models.Model):
    user = models.ForeignKey(NewUser, on_delete=models.CASCADE, related_name="classroom_user")
    classe = models.ForeignKey(Classe, on_delete=models.CASCADE, related_name="classroom_classe")

class Matter(models.Model):
    MATTERS = [
        ('math', 'Mathematique'),
        ('phy', 'Physique'),
        ('chim', 'Chimie'),
        ('hist', 'Histoire'),
        ('svt', 'Science'),
        ('geo', 'Geographie'),
        ('eng', 'Anglais'),
        ('fr', 'Francais'),
        ('ecm', 'ECM'),
        ('stud', 'student'),
        ('eps', 'sport'),
        ('inf', 'Informatique'),
    ]
    classe = models.ForeignKey(Classe, on_delete=models.CASCADE, related_name='class_matter')
    credit = models.IntegerField()
    matter = models.CharField(
        max_length=7,
        choices=MATTERS,
        null=True,
        blank=True
        # Departement, on_delete=models.CASCADE, related_name='dep_user', blank=True, null=True
        )

class Program(models.Model):
    matter = models.ForeignKey(Matter, on_delete=models.CASCADE, related_name='matter_program')
    title = models.CharField(max_length=255, unique=True)
    describe = models.TextField()
    limit_day = models.DateField()
    course_day = models.DateField()
    begin_time = models.TimeField()
    duration = models.IntegerField()
    status = models.BooleanField(default=False, blank=True)

class Lecon(models.Model):
    program = models.ForeignKey(Program, unique=True, on_delete=models.CASCADE, related_name="program_lecon")
    content = models.TextField()

class Question(models.Model):
    lesson = models.ForeignKey(Lecon, on_delete=models.CASCADE, related_name="lecon_question")
    content = models.CharField(max_length=10000)

class Reponse(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name="question_response")
    content = models.CharField(max_length=1000)
    verify = models.BooleanField()

class TestResults(models.Model):
    lesson = models.ForeignKey(Lecon, on_delete=models.CASCADE, related_name="note_test")
    note = models.FloatField()
    student = models.ForeignKey(NewUser, on_delete=models.CASCADE, related_name="note_user")


import streamlit as st

st.title('BMI Calculator')

weight = st.slider('Choose weight - kg', 20, 200, value=75)

weight

height = st.slider('Choose height - cm', 100, 240, value=170)

height

height_meters = height / 100

bmi = weight / (height_meters ** 2)

st.write('BMI is')

bmi


opçao = 0
resp = ' '
while opçao != 5:
    num = float(input('Informe um número inteiro: '))
    num2 = float(input('Informe outro número: '))
    print("""
    [1] Somar dois números
    [2] Diferença entre dois números
    [3] Multiplicar dois números
    [4] Dividir  dois números
    [5] Sair
    """)
    opçao = int(input('O que deseja fazer? '))
    if opçao == 1:
        print(f'A soma dos números {num} e {num2} é igual a {num + num2}')
    elif opçao == 2:
        print(f'A diferença dos números {num} e {num2} é igual a {num - num2}')
    elif opçao == 3:
        print(f'A multiplicação dos números {num} e {num2} é igual a {num * num2}')
    elif opçao == 4:
        print(f'A divisão dos números {num} e {num2} é igual a {num / num2}')
    elif opçao == 5:
        print('Finalizando....')
        break
    else:
        print('Opção inválida! Escolha um valor entre 1 e 5: ')


# 하루에 3개를 넘지 않는 글자를 기억할 수 있다

# non-empty string s를 기록하길 원한다
# s가 뭐냐면 구성되어있다 소문자로 가장 작은 숫자 of days

# 얼마나 많은 날짜 안에 할 수 있는가

# P는 empty sting 으로 초기화, 오직 sting의 마지막에 글자를 추가 할 수 있다

# ex_) lollipops -> 2일
# 첫날 l, o, i 를 기억하여 lolli를 만든다
# 둘째날 p, o, s 를 만들어 pops를 만들고
# 둘째날까지 기억한 모든 글자를 활용하여 lollipops 단어를 완성 할 수 있다 -> 최소 날자 2일

import sys
from collections import deque

t = int(sys.stdin.readline().rstrip())

def one_day_process(s_deque: deque, end_flag: bool) -> (deque, bool):
    memory: list = []

    while True:
        # If deque is empty, return
        try:
            if len(memory) < 3:
                current = s_deque.popleft()
                if not memory.__contains__(current):
                    memory.append(current)

            if memory.__contains__(s_deque[0]):
                s_deque.popleft()
            elif len(memory) == 3:
                # test code start
                print("deque: ", s_deque)
                print("memory: ", memory)
                # test code end

                return s_deque, end_flag

        except IndexError:
            end_flag = True
            return s_deque, end_flag

def exec_case():
    s_list: list = list(sys.stdin.readline().rstrip())
    s_deque = deque(s_list)

    days_cnt: int = 0

    end_flag: bool = False

    while True:
        days_cnt += 1

        # One day process
        (return_deque, return_flag) = one_day_process(s_deque, end_flag)

        s_deque = return_deque
        end_flag = return_flag

        if end_flag:
            print(days_cnt)
            return

for _ in range(t):
    exec_case()


#! /usr/bin/python3

display_arr=[0,0,0,0,0,0,0,0,0,0,0]

class motion():                         #This file is responsible for converting axis readings into speed signals

    def motorSpeed(self, axis, max_speed,buttons):

        self.forward = axis[0]          #asigning axis readings to their functionalities
        self.rotate = axis[1]
        self.slide = axis[2]
        self.pitch = axis[3]
        self.up = axis[4]
        self.max_speed = max_speed
                                        #calculating the speed of each motor depending on axis readings and max speed provided
        self.FR = (self.forward - self.rotate + self.slide) * self.max_speed
        self.FL = (-self.forward - self.rotate + self.slide) * self.max_speed
        self.TF = (self.pitch - self.up) * self.max_speed
        self.TB = (self.pitch + self.up) * self.max_speed
        self.BR = (-self.forward + self.rotate + self.slide) * self.max_speed
        self.BL = (self.forward + self.rotate + self.slide) * self.max_speed

        self.speeds=[self.FR,self.FL,self.TF,self.TB,self.BR,self.BL]

                                        #calculating scale and limiting the speed to be written to thrusters
        x=[abs(max(self.speeds)),abs(min(self.speeds))]
        if(max(x)>self.max_speed):
            scale = self.max_speed / max(x)
            for i in range(len(self.speeds)):
               self.speeds[i]=round(self.speeds[i]*scale)
        else:
            for i in range(len(self.speeds)):
                self.speeds[i]=round(self.speeds[i])
        #print(self.speeds)
        self.output = self.encoder()    #calling function that encodes those speed signals
                                        #adding '#' for checking whether the information is being recieved correctly
        self.output="#" + self.output + str(buttons)+ "#"

        return self.output
                                        #This function encodes the speeds to be sent
    def encoder(self):
        self.Chrspeeds=[]
        for i in range(len(self.speeds)):
                                        #shifting by '200' to eliminate negative values then dividing by 2
            self.speeds[i] = (self.speeds[i] + 200)
            self.speeds[i] = round(self.speeds[i] / 2)
                                        #appending each value to an array after converting the number to its corresponding ascii character
            self.Chrspeeds.append(chr(self.speeds[i]))

        #print(self.Chrspeeds)
        self.spd = ''.join(self.Chrspeeds)

        return self.spd

    def decoder(self,msg):              #the decoder function reverses the operations performed in the encoder part
        global display_arr
        self.speeds2=[x for x in msg]
        #Check if the squence is sent correct
        #if(len(self.speeds) == '' )
        print(msg)
        if (self.speeds2[0]=="#" and self.speeds2[8]=="#"): #checking whether the message is received correctly
            #del self.speeds2[0]
            #self.speeds2.pop()

            speeds_arr=[ord(x) for x in msg[1:7]]
            speeds_arr=[((x*2)-200)for x in speeds_arr[0:6]] #values to be passed to the gui to display speeds of thrusters
            #print(speeds_arr)                               #printing in terminal just to check

            states=bin(ord(msg[7])-50)[2:].zfill(5)          #decoding light/gripper states values
            ls=[int(x) for x in states]
            display_arr=speeds_arr+ls
            print(display_arr)
        else:
            pass

        return(display_arr)

        #This did not work so we switched to the two lines upove
            #for i in range(len(self.speeds)):

            #    self.speeds2[i] = int(ord(self.speeds2[i]))
            #    self.speeds2[i] = self.speeds2[i] * 2
            #    self.speeds2[i] = self.speeds2[i] - 200

        #print(bin(ord(self.speeds2[7])-50))


# in the name of God
import math

from utils.prime import is_prime

def check(num):
    x = int(math.sqrt(num // 2))  # x is the bound for square number
    for i in range(1, x + 1):
        if is_prime(num - 2 * i * i):
            return True
    return False

for i in range(3, 10000000, 2):
    if not is_prime(i) and not check(i):
        print(i)
        break


# class for a simple implementation of the KNN algorithm
## Author: Devin Gluesing

import numpy
import random
import time
import os

class KNN():
    def __init__(self, test_file, train_file):
        self.testing_set = numpy.loadtxt(test_file)
        self.training_set = numpy.loadtxt(train_file)

        self.tp = 0 #True Positive
        self.fp = 0 #False Positive
        self.tn = 0 #True Negative
        self.fn = 0 #False Negative

        self.predictions = []
        self.actual = []

    def GeneratePredictions(self, k):
        for test_row in self.testing_set:
            prediction = self.MakePrediction(self.training_set, test_row, k)
            self.predictions.append(prediction)
            self.actual.append(test_row[-1])

    def GatherStats(self):
        for i in range(len(self.predictions)-1):
            currPrediction = self.predictions[i]
            currActual = self.actual[i]
            if  currPrediction == 1 and currActual == 1:
                self.tp += 1
            elif currPrediction == 1 and currActual == -1:
                self.fp += 1
            elif currPrediction == -1 and currActual == -1:
                self.tn += 1
            elif currPrediction == -1 and currActual == 1:
                self.fn +=1
            else:
                print("[-] done fucked up")

    def GenerateTestResults(self, label):
        accuracy = str(self.Accuracy())
        sensitivity = str(self.Sensitivity())
        specificity = str(self.Specificity())
        precision = str(self.Precision())
        info =  "Results for {0}:\n".format(label)
        info += "Accuracy: {0}\n".format(accuracy)
        info += "Sensitivity: {0}\n".format(sensitivity)
        info += "Specificity: {0}\n".format(specificity)
        info += "Precision: {0}\n\n".format(precision)
        return info

    def ClearMemory(self):
        self.predictions = []
        self.actual = []
        self.tp = 0
        self.fp = 0
        self.tn = 0
        self.fn = 0

    def CalculateDistance(self, x, y):
        distance = 0.0
        for i in range(len(x)-1):
            # print(x[i], y[i])
            distance += (x[i] - y[i])**2
        return (distance**(1/2))

    def GetNeighbors(self, training_set, test_row, k):
        distances = []
        for train_row in training_set:
            distance =  self.CalculateDistance(test_row, train_row)
            distances.append((train_row, distance))
        distances.sort(key=lambda tup: tup[1])
        # distances.sort()
        # print(distances)
        neighbors = []
        for i in range(k):
            neighbors.append(distances[i][0])
            # neighbors.append(distances[i])
        return neighbors

    def MakePrediction(self, training_set, test_row, k):
        neighbors =  self.GetNeighbors(training_set, test_row, k)
        output_vals = []
        for row in neighbors:
            output_vals.append(row[-1])
        prediction = max(set(output_vals), key=output_vals.count)
        return prediction

    # functions written to be easily readable
    def Accuracy(self):
        top = self.tp + self.tn
        bottom = self.tp + self.fp + self.tn + self.fn
        return (top / bottom)

    def Sensitivity(self):
        bottom = self.tp + self.fn
        return (self.tp / bottom)

    def Specificity(self):
        bottom = self.fp + self.tn
        return (self.tn / bottom)

    def Precision(self):
        bottom = self.tp + self.fp
        return (self.tp / bottom)


try:
	from zcrmsdk.src.com.zoho.crm.api.exception import SDKException
	from zcrmsdk.src.com.zoho.crm.api.util import APIResponse, CommonAPIHandler, Constants
	from zcrmsdk.src.com.zoho.crm.api.header import Header
	from zcrmsdk.src.com.zoho.crm.api.header_map import HeaderMap
except Exception:
	from ..exception import SDKException
	from ..util import APIResponse, CommonAPIHandler, Constants
	from ..header import Header
	from ..header_map import HeaderMap

class BulkWriteOperations(object):
	def __init__(self):
		"""Creates an instance of BulkWriteOperations"""
		pass

	def upload_file(self, request, header_instance=None):
		"""
		The method to upload file

		Parameters:
			request (FileBodyWrapper) : An instance of FileBodyWrapper
			header_instance (HeaderMap) : An instance of HeaderMap

		Returns:
			APIResponse: An instance of APIResponse

		Raises:
			SDKException
		"""

		try:
			from zcrmsdk.src.com.zoho.crm.api.bulk_write.file_body_wrapper import FileBodyWrapper
		except Exception:
			from .file_body_wrapper import FileBodyWrapper

		if request is not None and not isinstance(request, FileBodyWrapper):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: request EXPECTED TYPE: FileBodyWrapper', None, None)

		if header_instance is not None and not isinstance(header_instance, HeaderMap):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: header_instance EXPECTED TYPE: HeaderMap', None, None)

		handler_instance = CommonAPIHandler()
		api_path = ''
		api_path = api_path + 'https://content.zohoapis.com/crm/v2/upload'
		handler_instance.set_api_path(api_path)
		handler_instance.set_http_method(Constants.REQUEST_METHOD_POST)
		handler_instance.set_category_method(Constants.REQUEST_CATEGORY_CREATE)
		handler_instance.set_content_type('multipart/form-data')
		handler_instance.set_request(request)
		handler_instance.set_mandatory_checker(True)
		handler_instance.set_header(header_instance)
		try:
			from zcrmsdk.src.com.zoho.crm.api.bulk_write.action_response import ActionResponse
		except Exception:
			from .action_response import ActionResponse
		return handler_instance.api_call(ActionResponse.__module__, 'application/json')

	def create_bulk_write_job(self, request):
		"""
		The method to create bulk write job

		Parameters:
			request (RequestWrapper) : An instance of RequestWrapper

		Returns:
			APIResponse: An instance of APIResponse

		Raises:
			SDKException
		"""

		try:
			from zcrmsdk.src.com.zoho.crm.api.bulk_write.request_wrapper import RequestWrapper
		except Exception:
			from .request_wrapper import RequestWrapper

		if request is not None and not isinstance(request, RequestWrapper):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: request EXPECTED TYPE: RequestWrapper', None, None)

		handler_instance = CommonAPIHandler()
		api_path = ''
		api_path = api_path + '/crm/bulk/v2/write'
		handler_instance.set_api_path(api_path)
		handler_instance.set_http_method(Constants.REQUEST_METHOD_POST)
		handler_instance.set_category_method(Constants.REQUEST_CATEGORY_CREATE)
		handler_instance.set_content_type('application/json')
		handler_instance.set_request(request)
		handler_instance.set_mandatory_checker(True)
		try:
			from zcrmsdk.src.com.zoho.crm.api.bulk_write.action_response import ActionResponse
		except Exception:
			from .action_response import ActionResponse
		return handler_instance.api_call(ActionResponse.__module__, 'application/json')

	def get_bulk_write_job_details(self, job_id):
		"""
		The method to get bulk write job details

		Parameters:
			job_id (int) : An int representing the job_id

		Returns:
			APIResponse: An instance of APIResponse

		Raises:
			SDKException
		"""

		if not isinstance(job_id, int):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: job_id EXPECTED TYPE: int', None, None)

		handler_instance = CommonAPIHandler()
		api_path = ''
		api_path = api_path + '/crm/bulk/v2/write/'
		api_path = api_path + str(job_id)
		handler_instance.set_api_path(api_path)
		handler_instance.set_http_method(Constants.REQUEST_METHOD_GET)
		handler_instance.set_category_method(Constants.REQUEST_CATEGORY_READ)
		try:
			from zcrmsdk.src.com.zoho.crm.api.bulk_write.response_wrapper import ResponseWrapper
		except Exception:
			from .response_wrapper import ResponseWrapper
		return handler_instance.api_call(ResponseWrapper.__module__, 'application/json')

	def download_bulk_write_result(self, download_url):
		"""
		The method to download bulk write result

		Parameters:
			download_url (string) : A string representing the download_url

		Returns:
			APIResponse: An instance of APIResponse

		Raises:
			SDKException
		"""

		if not isinstance(download_url, str):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: download_url EXPECTED TYPE: str', None, None)

		handler_instance = CommonAPIHandler()
		api_path = ''
		api_path = api_path + '/'
		api_path = api_path + str(download_url)
		handler_instance.set_api_path(api_path)
		handler_instance.set_http_method(Constants.REQUEST_METHOD_GET)
		handler_instance.set_category_method(Constants.REQUEST_CATEGORY_READ)
		try:
			from zcrmsdk.src.com.zoho.crm.api.bulk_write.response_handler import ResponseHandler
		except Exception:
			from .response_handler import ResponseHandler
		return handler_instance.api_call(ResponseHandler.__module__, 'application/octet-stream')

class UploadFileHeader(object):
	feature = Header('feature', 'com.zoho.crm.api.BulkWrite.UploadFileHeader')
	x_crm_org = Header('X-CRM-ORG', 'com.zoho.crm.api.BulkWrite.UploadFileHeader')


import sklearn
from sklearn.linear_model import SGDRegressor, SGDClassifier
from sklearn.neural_network import MLPRegressor, MLPClassifier
from sklearn.naive_bayes import MultinomialNB, GaussianNB
from sklearn.neighbors import KNeighborsRegressor, KNeighborsClassifier
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from sklearn.cluster import KMeans
from .mixed_nb import MixedNB
import logging
import numpy as np
import titus.prettypfa

def sklearn_to_pfa(estimator, types, featurizer=None):
    """
    Convert scikit-learn estimator to PFA format.
    :param estimator: Scikit-learn estimator, must be supported
    :param types: List of tuples (name, type)
    """
    types = _fix_types_compatibility(types)

    featurizer = featurizer or _construct_featurizer(types)

    if isinstance(estimator, SGDRegressor):
        return _pfa_sgdregressor(estimator, types, featurizer)
    elif isinstance(estimator, SGDClassifier):
        return _pfa_sgdclassifier(estimator, types, featurizer)
    elif isinstance(estimator, MLPRegressor):
        return _pfa_mlpregressor(estimator, types, featurizer)
    elif isinstance(estimator, MLPClassifier):
        return _pfa_mlpclassifier(estimator, types, featurizer)
    elif isinstance(estimator, MultinomialNB):
        return _pfa_multinomialnb(estimator, types, featurizer)
    elif isinstance(estimator, GaussianNB):
        return _pfa_gaussiannb(estimator, types, featurizer)
    elif isinstance(estimator, MixedNB):
        return _pfa_mixednb(estimator, types, featurizer)
    elif isinstance(estimator, KMeans):
        return _pfa_kmeans(estimator, types, featurizer)
    elif isinstance(estimator, KNeighborsRegressor):
        return _pfa_kneighborsregressor(estimator, types, featurizer)
    elif isinstance(estimator, KNeighborsClassifier):
        return _pfa_kneighborsclassifier(estimator, types, featurizer)
    elif isinstance(estimator, GradientBoostingRegressor):
        return _pfa_gradientboostingregressor(estimator, types, featurizer)
    elif isinstance(estimator, GradientBoostingClassifier):
        return _pfa_gradientboostingclassifier(estimator, types, featurizer)
    else:
        raise NotImplementedError('Estimator {} is not yet supported'.format(estimator.__class__.__name__))

def _pfa_sgdregressor(estimator, types, featurizer):
    """
    Example output:
        input: record(Data,
            feature0: double,
            feature1: double,
        )
        output: double
        action:
            -2.525797382870301 + 31.7004451488 * input.feature0 + 42.5005713274 * input.feature1
    """
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Regression = record(Regression, const: double, coeff: array(double));
    Input = {input_record}
input: Input
output: double
cells:
    // query(Query) = {{}};
    model(Regression) = {{const: 0.0, coeff: []}};
fcns:
    {functions}
action:
    var x = {featurizer};
    model.reg.linear(x, model)
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    pfa['cells']['model']['init'] = {'const': estimator.intercept_[0], 'coeff': list(estimator.coef_)}

    return pfa

def _pfa_sgdclassifier(estimator, types, featurizer):
    """
    Example output:
        types:
            Query = record(Query,
                           sql: string,
                           variable: string,
                           covariables: array(string));
            Input = record(Input,
                a: double,
                b: double
            );
            Regression = record(Regression, const: double, coeff: array(double));
        input: Input
        output: string
        cells:
            query(Query) = {sql: SELECT, variable: dep, covariables: [a, b, c]};
            model(array(Regression)) = [
                {const: 3, coeff: [1, 2]},
                {const: 3, coeff: [1, 4]}
            ];
            classes(array(string)) = [a, b, c];
        fcns:
            featurize = fcn(x: Input -> array(double))
                new(array(double),
                    x.a,
                    x.b
                )
        action:
            // TODO: define this as a function when functions start working with titus python 3
            var x = new(array(double),
                input.a,
                input.b
            );
            var scores = a.map(model, fcn(r: Regression -> double) model.reg.linear(x, r));
            classes[a.argmax(scores)]
    """
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Regression = record(Regression, const: double, coeff: array(double));
    Input = {input_record}
input: Input
output: string
cells:
    // query(Query) = {{}};
    model(array(Regression)) = [];
    classes(array(string)) = [];
fcns:
    {functions}
action:
    var x = {featurizer};
    var scores = a.map(model, fcn(r: Regression -> double) model.reg.linear(x, r));
    classes[a.argmax(scores)]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    pfa['cells']['classes']['init'] = list(estimator.classes_)
    pfa['cells']['model']['init'] = [
        {
            'const': const,
            'coeff': list(coeff)
        } for const, coeff in zip(estimator.intercept_, estimator.coef_)
    ]

    return pfa

def _pfa_mlpregressor(estimator, types, featurizer):
    """
    See https://github.com/opendatagroup/hadrian/wiki/Basic-neural-network
    """
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Layer = record(Layer,
                   weights: array(array(double)),
                   bias: array(double));
    Input = {input_record}
input: Input
output: double
cells:
    neuralnet(array(Layer)) = [];
fcns:
{functions}
action:
    var x = {featurizer};
    var activation = model.neural.simpleLayers(x, neuralnet, fcn(x: double -> double) m.link.relu(x));
    activation[0]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    # NOTE: `model.neural.simpleLayers` accepts transposed matrices
    pfa['cells']['neuralnet']['init'] = [
        {
            'bias': bias.tolist(),
            'weights': weights.T.tolist()
        } for bias, weights in zip(estimator.intercepts_, estimator.coefs_)
    ]

    return pfa

def _pfa_mlpclassifier(estimator, types, featurizer):
    """
    See https://github.com/opendatagroup/hadrian/wiki/Basic-neural-network
    """
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Layer = record(Layer,
                   weights: array(array(double)),
                   bias: array(double));
    Input = {input_record}
input: Input
output: string
cells:
    neuralnet(array(Layer)) = [];
    classes(array(string)) = [];
fcns:
{functions}
action:
    var x = {featurizer};
    var activations = model.neural.simpleLayers(x, neuralnet, fcn(x: double -> double) m.link.relu(x));
    classes[a.argmax(activations)]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    pfa['cells']['classes']['init'] = list(estimator.classes_)
    # NOTE: `model.neural.simpleLayers` accepts transposed matrices
    pfa['cells']['neuralnet']['init'] = [
        {
            'bias': bias.tolist(),
            'weights': weights.T.tolist()
        } for bias, weights in zip(estimator.intercepts_, estimator.coefs_)
    ]

    return pfa

def _pfa_multinomialnb(estimator, types, featurizer):
    """
    See https://github.com/opendatagroup/hadrian/wiki/Basic-naive-bayes
    NOTE: in our use case we use mostly one-hot encoded variables, so using BernoulliNB might make
        more sense
    """
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Distribution = record(Distribution,
                        logLikelihoods: array(double),
                        logPrior: double);
    Input = {input_record}
input: Input
output: string
cells:
    model(array(Distribution)) = [];
    classes(array(string)) = [];
fcns:
{functions}
action:
    var x = {featurizer};

    var classLL = a.map(model, fcn(dist: Distribution -> double) {{
        model.naive.multinomial(x, dist.logLikelihoods) + dist.logPrior
    }});
    var norm = a.logsumexp(classLL);
    var probs = a.map(classLL, fcn(x: double -> double) m.exp(x - norm));
    classes[a.argmax(probs)]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    logprior = np.maximum(estimator.class_log_prior_, -1e10)
    pfa['cells']['classes']['init'] = list(estimator.classes_)
    pfa['cells']['model']['init'] = [
        {
            'logLikelihoods': ll.tolist(),
            'logPrior': log_prior.tolist()
        } for log_prior, ll in zip(logprior, np.exp(estimator.feature_log_prob_))
    ]

    return pfa

def _pfa_gaussiannb(estimator, types, featurizer):
    """
    See https://github.com/opendatagroup/hadrian/wiki/Basic-naive-bayes
    """
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Distribution = record(Distribution,
                          stats: array(record(M, mean: double, variance: double)),
                          logPrior: double);
    Input = {input_record}
input: Input
output: string
cells:
    model(array(Distribution)) = [];
    classes(array(string)) = [];
fcns:
{functions}
action:
    var x = {featurizer};

    var classLL = a.map(model, fcn(dist: Distribution -> double) {{
      model.naive.gaussian(x, dist.stats) + dist.logPrior
    }});

    var norm = a.logsumexp(classLL);
    var probs = a.map(classLL, fcn(x: double -> double) m.exp(x - norm));
    classes[a.argmax(probs)]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    prior = np.maximum(estimator.class_prior_, 1e-10)
    pfa['cells']['classes']['init'] = list(estimator.classes_)
    pfa['cells']['model']['init'] = [
        {
            'stats': [{
                'mean': m,
                'variance': s
            } for m, s in zip(means, sigmas)],
            'logPrior': np.log(prior).tolist()
        } for prior, means, sigmas in zip(prior, estimator.theta_, estimator.sigma_)
    ]

    return pfa

def _pfa_mixednb(estimator, types, featurizer):
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    GaussianDistribution = record(GaussianDistribution,
                                  stats: array(record(M, mean: double, variance: double)));
    MultinomialDistribution = record(MultinomialDistribution,
                                     logLikelihoods: array(double));
    Input = {input_record}
input: Input
output: string
cells:
    gaussModel(array(GaussianDistribution)) = [];
    multinomialModel(array(MultinomialDistribution)) = [];
    classes(array(string)) = [];
    logPrior(array(double)) = [];
fcns:
{functions}
action:
    var x = {featurizer};

    var gaussFeatures = if( a.len(gaussModel) > 0 ) a.len(gaussModel[0,"stats"]) else 0;

    var gaussianLL = a.map(gaussModel, fcn(dist: GaussianDistribution -> double) {{
        model.naive.gaussian(a.subseq(x, 0, gaussFeatures), dist.stats)
    }});

    var multinomialLL = a.map(multinomialModel, fcn(dist: MultinomialDistribution -> double) {{
        model.naive.multinomial(a.subseq(x, gaussFeatures, a.len(x)), dist.logLikelihoods)
    }});

    var classLL = logPrior;
    if (a.len(gaussianLL) > 0)
        classLL = la.add(classLL, gaussianLL);
    if (a.len(multinomialLL) > 0)
        classLL = la.add(classLL, multinomialLL);

    var norm = a.logsumexp(classLL);
    var probs = a.map(classLL, fcn(x: double -> double) m.exp(x - norm));
    classes[a.argmax(probs)]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    pfa['cells']['classes']['init'] = list(estimator.classes_)
    # avoid null values from log prior
    logprior = np.maximum(estimator.class_log_prior_, -1e10)
    pfa['cells']['logPrior']['init'] = logprior.tolist()

    # assumes that continuous features go before nominal ones
    if hasattr(estimator.gauss_nb, 'theta_'):
        pfa['cells']['gaussModel']['init'] = [
            {
                'stats': [{
                    'mean': m,
                    'variance': s
                } for m, s in zip(means, sigmas)]
            } for means, sigmas in zip(estimator.gauss_nb.theta_, estimator.gauss_nb.sigma_)
        ]
    if hasattr(estimator.multi_nb, 'feature_log_prob_'):
        pfa['cells']['multinomialModel']['init'] = [
            {
                'logLikelihoods': ll.tolist()
            } for ll in np.exp(estimator.multi_nb.feature_log_prob_)
        ]

    return pfa

def _pfa_kmeans(estimator, types, featurizer):
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Cluster = record(Cluster, center: array(double), id: int);
    Input = {input_record}
input: Input
output: int
cells:
    clusters(array(Cluster)) = [];
fcns:
{functions}
action:
    var x = {featurizer};
    var cluster = model.cluster.closest(x, clusters, metric.simpleEuclidean);
    cluster.id
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    pfa['cells']['clusters']['init'] = [
        {
            'center': c.tolist(),
            'id': i
        } for i, c in enumerate(estimator.cluster_centers_)
    ]
    return pfa

def _pfa_kneighborsregressor(estimator, types, featurizer):
    """See https://github.com/opendatagroup/hadrian/wiki/Basic-nearest-neighbors"""
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Point = record(Point,
                   x: array(double),
                   y: double);
    Codebook = array(Point);
    Input = {input_record}
input: Input
output: double
cells:
    codebook(Codebook) = [];
    nNeighbors(int) = 5;
fcns:
{functions}
action:
    var x = {featurizer};
    var neighbors = model.neighbor.nearestK(nNeighbors, x, codebook, fcn(x: array(double), p: Point -> double) {{
        metric.simpleEuclidean(x, p.x)
    }});
    a.mean(a.map(neighbors, fcn(p: Point -> double) p.y))
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    pfa['cells']['codebook']['init'] = [
        {
            'x': x.tolist(),
            'y': y
        } for x, y in zip(estimator._fit_X, estimator._y)
    ]
    pfa['cells']['nNeighbors']['init'] = estimator.n_neighbors

    return pfa

def _pfa_kneighborsclassifier(estimator, types, featurizer):
    """See https://github.com/opendatagroup/hadrian/wiki/Basic-nearest-neighbors"""
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    Point = record(Point,
                   x: array(double),
                   y: string);
    Codebook = array(Point);
    Input = {input_record}
input: Input
output: string
cells:
    codebook(Codebook) = [];
    nNeighbors(int) = 5;
fcns:
{functions}
action:
    var x = {featurizer};
    var neighbors = model.neighbor.nearestK(nNeighbors, x, codebook, fcn(x: array(double), p: Point -> double) {{
        metric.simpleEuclidean(x, p.x)
    }});
    a.mode(a.map(neighbors, fcn(p: Point -> string) p.y))
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    logging.info(pretty_pfa)
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    y_labels = [estimator.classes_[e] for e in estimator._y]
    pfa['cells']['codebook']['init'] = [
        {
            'x': x.tolist(),
            'y': y
        } for x, y in zip(estimator._fit_X, y_labels)
    ]
    pfa['cells']['nNeighbors']['init'] = estimator.n_neighbors

    return pfa

def make_tree(tree, node_id=0):
    if tree.children_left[node_id] == sklearn.tree._tree.TREE_LEAF:
        leaf_value = float(tree.value[node_id][0, 0])

        # special case for empty tree with just root
        if node_id == 0:
            return {'TreeNode': {
                'feature': 0,
                'operator': '<=',
                'value': 0.,
                'pass': {'double': leaf_value},
                'fail': {'double': leaf_value}
            }}
        else:
            return {'double': leaf_value}

    return {'TreeNode': {
        'feature': int(tree.feature[node_id]),
        'operator': '<=',
        'value': float(tree.threshold[node_id]),
        'pass': make_tree(tree, tree.children_left[node_id]),
        'fail': make_tree(tree, tree.children_right[node_id])
    }}

def _pfa_gradientboostingregressor(estimator, types, featurizer):
    """See https://github.com/opendatagroup/hadrian/wiki/Basic-decision-tree"""
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    TreeNode = record(TreeNode,
                    feature: int,
                    operator: string,
                    value: double,
                    pass: union(double, TreeNode),
                    fail: union(double, TreeNode));
    Row = record(Row, values: array(double));
    Input = {input_record}
input: Input
output: double
cells:
    // empty tree to satisfy type constraint; will be filled in later
    trees(array(TreeNode)) = [];
    // model intercept to which tree predictions are added
    intercept(double) = 0.0;
    learningRate(double) = 0.0;
fcns:
{functions}
action:
    var x = {featurizer};
    var row = new(Row, values: x);

    var scores = a.map(trees, fcn(tree: TreeNode -> double) {{
      model.tree.simpleWalk(row, tree, fcn(d: Row, t: TreeNode -> boolean) {{
        d.values[t.feature] <= t.value
      }})
    }});

    intercept + learningRate * a.sum(scores)
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    tree_dicts = []
    for tree in estimator.estimators_[:, 0]:
        tree_dicts.append(make_tree(tree.tree_)['TreeNode'])
    pfa["cells"]["trees"]["init"] = tree_dicts
    pfa['cells']['intercept']['init'] = estimator.init_.mean
    pfa['cells']['learningRate']['init'] = estimator.learning_rate

    return pfa

def _pfa_gradientboostingclassifier(estimator, types, featurizer):
    """See https://github.com/opendatagroup/hadrian/wiki/Basic-decision-tree"""
    input_record = _input_record(types)

    # construct template
    pretty_pfa = """
types:
    Query = record(Query,
                   sql: string,
                   variable: string,
                   covariables: array(string));
    TreeNode = record(TreeNode,
                    feature: int,
                    operator: string,
                    value: double,
                    pass: union(double, TreeNode),
                    fail: union(double, TreeNode));
    Row = record(Row, values: array(double));
    Input = {input_record}
input: Input
output: string
cells:
    classes(array(string)) = [];
    // set of trees for each class
    classesTrees(array(array(TreeNode))) = [];
    // model priors to which tree predictions are added
    priors(array(double)) = [];
    learningRate(double) = 0.0;
fcns:
{functions}
action:
    var x = {featurizer};
    var row = new(Row, values: x);

    // trees activations
    var activations = a.map(classesTrees, fcn(trees: array(TreeNode) -> double) {{
        var scores = a.map(trees, fcn(tree: TreeNode -> double) {{
          model.tree.simpleWalk(row, tree, fcn(d: Row, t: TreeNode -> boolean) {{
            d.values[t.feature] <= t.value
          }})
        }});
        learningRate * a.sum(scores)
    }});

    // add priors
    activations = la.add(priors, activations);

    // probabilities
    var norm = a.logsumexp(activations);
    var probs = a.map(activations, fcn(x: double -> double) m.exp(x - norm));

    classes[a.argmax(probs)]
    """.format(
        input_record=input_record, featurizer=featurizer, functions=_functions()
    ).strip()

    # compile
    pfa = titus.prettypfa.jsonNode(pretty_pfa)

    # add model from scikit-learn
    tree_dicts = [[make_tree(tree.tree_)['TreeNode'] for tree in trees] for trees in estimator.estimators_.T]
    pfa["cells"]["classesTrees"]["init"] = tree_dicts
    pfa['cells']['classes']['init'] = list(estimator.classes_)
    pfa['cells']['priors']['init'] = list(estimator.init_.priors)
    pfa['cells']['learningRate']['init'] = estimator.learning_rate

    return pfa

def _construct_featurizer(types):
    inputs = []
    for name, typ in types:
        if typ == 'int':
            inputs.append('cast.double(input.{})'.format(name))
        else:
            inputs.append('input.{}'.format(name))

    return """
new(array(double),
    {inputs}
    )
    """.format(inputs=',\n'.join(inputs)).strip()

def _input_record(types):
    s = 'record(Input'
    for name, typ in types:
        s += ',\n    {}: {}'.format(name, typ)
    return s + '\n);'

def _fix_types_compatibility(types):
    new_types = []
    for name, typ in types:
        if typ == 'real':
            typ = 'double'
        elif typ == 'integer':
            typ = 'int'
        elif typ in ('polynominal', 'binominal'):
            typ = 'string'
        new_types.append((name, typ))
    return new_types

def _functions():
    return """
    arr = fcn(x: double -> array(double))
        new(array(double), x);

    C = fcn(x: string, categories: array(string) -> array(double))
        a.map(categories, fcn(cat: string -> double) if(cat == x) 1 else 0);

    standardize = fcn(x: double, mu: double, sigma: double -> double)
        (x - mu) / sigma;
""".strip()


"""
? Задание: Вывести в консоль улитку с заданной длинной и высотой
"""
import math

elem = "[]"
size = 1

# Проверка ввода размерности матрицы
while size < 9 or size > 100:
    print("Размер улитки должен быть >= 9 и <= 100")
    size = int(input("Укажите размер улитки? "))

spiral_nums = math.floor(math.sqrt(size))

# Создание матрицы
matrix = [[0 for i in range(size)] for j in range(size)]

# Вывод матрицы
def print_matrix(matrix, elem):
    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            if matrix[i][j] == 0:
                print(f"\033[1;30;40m{elem}\033[0m", end="")
            else:
                print(f"\033[1;30;47m{elem}\033[0m", end="")
        print ()

# Заполнение матрицы
def fill_matrix(matrix, str_num_1, str_num_2, col_num_1, col_num_2):
    # верхняя линия
    for j in range(col_num_1, col_num_2):
        matrix[str_num_1][j] = 1

    # нижняя линия
    for j in range(col_num_1, col_num_2):
        matrix[str_num_2][j] = 1

    # правая линия
    for i in range(str_num_1, str_num_2):
        matrix[i][col_num_2-1] = 1

    # левая линия
    for i in range(str_num_1+2, str_num_2):
        matrix[i][col_num_1] = 1

    # закрасить соединяющий блок
    matrix[str_num_1+2][col_num_1+1] = 1

# Вызов функций
step = 0
for i in range(spiral_nums):
    fill_matrix(matrix, str_num_1=step, str_num_2=size-1-step, col_num_1=step, col_num_2=size-step)
    step += 2

#Заполнение матрицы происходит с шагом 2
# fill_matrix(matrix, str_num_1=0, str_num_2=size-1, col_num_1=0, col_num_2=size)
# fill_matrix(matrix, str_num_1=2, str_num_2=size-3, col_num_1=2, col_num_2=size-2)

# Вывод получившейся матрицы
print_matrix(matrix, elem)