from pico2d import *
import random

class General:
    def __init__(self):
        self.location = random.randint(1,4)
        if self.location == 1:
            self.x, self.y = 900, 800
        elif self.location == 2:
            self.x, self.y = 1000, 750
        elif self.location == 3:
            self.x, self.y = 1100, 700
        elif self.location == 4:
            self.x, self.y = 1200, 650
        self.frame = 0
        self.dieck = False
        self.count = 0
        self.image = load_image('image\\forces\\general.png')
#        self.image_die = load_image('image\\forces\\general_die.png')

    def update(self):
        if self.dieck:
            self.count += 1
            if self.count > 4:
                self.count = 0
                self.dieck = False
        else:
            self.frame = (self.frame + 1) % 6
            self.x -= 10
            self.y -= 5
        if self.x < 0:
            self.location = random.randint(1,4)
            if self.location == 1:
                self.x, self.y = 800, 800
            elif self.location == 2:
                self.x, self.y = 900, 750
            elif self.location == 3:
                self.x, self.y = 1000, 700
            elif self.location == 4:
                self.x, self.y = 1100, 650

    def draw(self):
#        if self.dieck:
#            self.image_die.clip_draw(0,0,137,120,self.x,self.y)
#        else:
            self.image.clip_draw(70 * self.frame, 0, 70, 100, self.x, self.y)

def handle_events():
    global testing
    global team
    events = get_events()
    for event in events:
        if event.type == SDL_QUIT:
            testing = False
        elif event.type == SDL_KEYDOWN :
            if event.key == SDLK_ESCAPE:
                testing = False
            for general in team:
                if event.key == SDLK_q and random.randint(1,4) == general.location:
                    general.dieck = True

open_canvas(1000,800)

team = [General() for i in range(4)]

testing = True

while testing:
    handle_events()

    for general in team:
        general.update()

    clear_canvas()
    for general in team:
        general.draw()
    update_canvas()

    delay(0.05)

close_canvas()


import numpy

iterations = 10000
learning_rate = 0.01
index = 0

theta_0 = 0
theta_1 = 0

x = numpy.array([0,3,4,5])
y = numpy.array([1,3,4,4])

m = len(x)

while index < iterations:
    h_theta = (theta_0 + theta_1 * x)

    temp_theta_0 = theta_0 - (learning_rate / m) * (h_theta - y).sum()
    temp_theta_1 = theta_1 - (learning_rate / m) * ((h_theta - y) * x).sum()

    theta_0 = temp_theta_0
    theta_1 = temp_theta_1

    index += 1

print(theta_0)
print(theta_1)


#!/usr/bin/env python
import numpy as np
from attribute_tree_decoder import create_tree_decoder
from tree_walker import OnehotBuilder
from cmd_args import cmd_args
from mol_util import atom_valence, bond_types, bond_valence, prod, DECISION_DIM, rule_ranges

def batch_make_att_masks(node_list, tree_decoder = None, walker = None, dtype=np.byte):
    if walker is None:
        walker = OnehotBuilder()
    if tree_decoder is None:
        tree_decoder = create_tree_decoder()

    true_binary = np.zeros((len(node_list), cmd_args.max_decode_steps, DECISION_DIM), dtype=dtype)
    rule_masks = np.zeros((len(node_list), cmd_args.max_decode_steps, DECISION_DIM), dtype=dtype)

    for i in range(len(node_list)):
        node = node_list[i]
        tree_decoder.decode(node, walker)

        true_binary[i, np.arange(walker.num_steps), walker.global_rule_used[:walker.num_steps]] = 1
        true_binary[i, np.arange(walker.num_steps, cmd_args.max_decode_steps), -1] = 1

        for j in range(walker.num_steps):
            rule_masks[i, j, walker.mask_list[j]] = 1

        rule_masks[i, np.arange(walker.num_steps, cmd_args.max_decode_steps), -1] = 1.0

    return true_binary, rule_masks


from django.conf.urls import url

from .views import index, enroll, lottery, receiver

urlpatterns = [
    url(r'^$', index, name='index'),
    url(r'^enroll/$', enroll, name='enroll'),
    url(r'^do_lottery/$', lottery, name='lottery'),
    url(r'^receiver/$', receiver, name='receiver'),
]


#!/usr/bin/python3
# Copyright 2019 Northern.tech AS
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        https://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

import pytest
import time
import os.path
import re

from helpers import package_filename, upload_deb_package
from mender_test_containers.helpers import *

class PackageMenderClientChecker():

    expected_update_modules = ["deb", "directory", "rpm", "script", "single-file"]
    expected_inventory_files = ["mender-inventory-bootloader-integration",
                                "mender-inventory-hostinfo",
                                "mender-inventory-network",
                                "mender-inventory-os",
                                "mender-inventory-rootfs-type"]
    expected_indentity_files = ["mender-device-identity"]

    expected_copyright_md5sum = "269720c1a5608250abd54a7818f369f6"

    def check_mender_client_version(self, ssh_connection, mender_version, mender_version_deb):
        result = ssh_connection.run('mender -version')
        if mender_version == "master":
            # For master, mender -version will print the short git hash. We can obtain this
            # from the deb package version, which is something like: "0.0~git20191022.dade697-1"
            m = re.match(r"0.0~git[0-9]+\.([a-z0-9]+)-1", mender_version_deb)
            assert m is not None
            assert m.group(1) in result.stdout
        else:
            assert mender_version in result.stdout

    def check_installed_files(self, ssh_connection, device_type="unknown"):
        ssh_connection.run('test -x /usr/bin/mender')
        ssh_connection.run('test -d /usr/share/mender/modules/v3')
        for module in self.expected_update_modules:
            module_path = os.path.join("/usr/share/mender/modules/v3", module)
            ssh_connection.run('test -x {mod}'.format(mod=module_path))
        ssh_connection.run('test -d /usr/share/mender/modules/v3')
        for inventory in self.expected_inventory_files:
            inventory_path = os.path.join("/usr/share/mender/inventory", inventory)
            ssh_connection.run('test -x {invent}'.format(invent=inventory_path))
        for identity in self.expected_indentity_files:
            identity_path = os.path.join("/usr/share/mender/identity", identity)
            ssh_connection.run('test -x {ident}'.format(ident=identity_path))
        ssh_connection.run('test -d /etc/mender')
        ssh_connection.run('test -f /etc/mender/artifact_info')
        ssh_connection.run('test -f /etc/mender/mender.conf')
        ssh_connection.run('test -f /lib/systemd/system/mender-client.service')
        ssh_connection.run('test -f /etc/systemd/system/multi-user.target.wants/mender-client.service')
        ssh_connection.run('test -f /usr/share/doc/mender-client/examples/demo.crt')

        # Device type
        ssh_connection.run('test -f /var/lib/mender/device_type')
        result = ssh_connection.run('cat /var/lib/mender/device_type')
        assert "device_type={}".format(device_type) in result.stdout

        # Northern.tech copyright file
        ssh_connection.run('test -f /usr/share/doc/mender-client/copyright')
        result = ssh_connection.run('md5sum /usr/share/doc/mender-client/copyright')
        assert result.stdout.split(' ')[0] == self.expected_copyright_md5sum

    def check_systemd_start_full_cycle(self, ssh_connection):
        # Check first that mender process is running
        result = ssh_connection.run('pgrep mender')
        assert result.exited == 0

        # Detect of a full cycle in 4 min timeout (~2 min to generate device keys + 30 secs full cycle)
        start_time = time.time()
        while time.time() - start_time < 4 * 60:
            result = ssh_connection.run('sudo journalctl -u mender-client --no-pager')
            if "State transition: authorize [Sync] -> authorize-wait [Idle]" in result.stdout:
                break
            time.sleep(10)

        # Check correct boot
        assert "Started Mender OTA update service." in result.stdout
        assert "Loaded configuration file" in result.stdout
        assert "No dual rootfs configuration present" in result.stdout

        # Check transition Sync to Idle (one full cycle)
        assert "authorize failed: transient error: authorization request failed" in result.stdout
        assert "State transition: authorize [Sync] -> authorize-wait [Idle]" in result.stdout

    def check_removed_files(self, ssh_connection, purge):
        # Check first that mender process has been stopped
        result = ssh_connection.run('pgrep mender', warn=True)
        assert result.exited == 1

        ssh_connection.run('test ! -f /usr/bin/mender')
        ssh_connection.run('test ! -e /usr/share/mender')
        ssh_connection.run('test ! -f /lib/systemd/system/mender-client.service')
        ssh_connection.run('test ! -f /etc/systemd/system/multi-user.target.wants/mender-client.service')
        ssh_connection.run('test ! -f /usr/share/doc/mender-client/examples/demo.crt')
        ssh_connection.run('test -d /var/lib/mender/')
        if purge:
            ssh_connection.run('test ! -f /etc/mender/mender.conf')
            ssh_connection.run('test ! -f /var/lib/mender/device_type')
            ssh_connection.run('test ! -f /etc/mender/artifact_info')
            ssh_connection.run('test ! -d /etc/mender')
        else:
            ssh_connection.run('test -f /etc/mender/mender.conf')
            ssh_connection.run('test -f /var/lib/mender/device_type')
            ssh_connection.run('test -f /etc/mender/artifact_info')
            ssh_connection.run('test -d /etc/mender')

        result = ssh_connection.run('sudo journalctl -u mender-client --no-pager')
        assert "Stopping Mender OTA update service..." in result.stdout
        assert "Stopped Mender OTA update service." in result.stdout

class TestPackageMenderClientDefaults(PackageMenderClientChecker):
    """Tests instalation, setup, start, removal and purge of mender-client deb package with
    in non-interactive method (i.e. default configuration).
    """

    @pytest.mark.usefixtures("setup_test_container")
    def test_install_configure_start(self, setup_tester_ssh_connection, mender_dist_packages_versions, mender_version):
        result = setup_tester_ssh_connection.run('uname -a')
        assert "raspberrypi" in result.stdout

        upload_deb_package(setup_tester_ssh_connection, mender_dist_packages_versions["mender-client"])

        result = setup_tester_ssh_connection.run('sudo DEBIAN_FRONTEND=noninteractive dpkg -i ' + package_filename(mender_dist_packages_versions["mender-client"]))
        assert "Unpacking mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout
        assert "Setting up mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout

        self.check_mender_client_version(setup_tester_ssh_connection, mender_version, mender_dist_packages_versions["mender-client"])

        self.check_installed_files(setup_tester_ssh_connection)

        # Default setup expects ServerURL hosted.mender.io
        result = setup_tester_ssh_connection.run('cat /etc/mender/mender.conf')
        assert '"ServerURL": "https://hosted.mender.io"' in result.stdout

        self.check_systemd_start_full_cycle(setup_tester_ssh_connection)

    @pytest.mark.usefixtures("setup_test_container")
    def test_remove_stop(self, setup_tester_ssh_connection, mender_dist_packages_versions):
        result = setup_tester_ssh_connection.run('sudo dpkg -r mender-client')
        assert "Removing mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout

        self.check_removed_files(setup_tester_ssh_connection, purge=False)

    @pytest.mark.usefixtures("setup_test_container")
    def test_purge(self, setup_tester_ssh_connection, mender_dist_packages_versions):
        result = setup_tester_ssh_connection.run('sudo dpkg -P mender-client')
        assert "Purging configuration files for mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout

        self.check_removed_files(setup_tester_ssh_connection, purge=True)

class TestPackageMenderClientInteractive(PackageMenderClientChecker):
    """Tests instalation, setup, start, removal and purge of mender-client deb package with
    in interactive method (i.e. user navigates wizard via stdin).
    """

    @pytest.mark.usefixtures("setup_test_container")
    def test_install_configure_start(self, setup_tester_ssh_connection, mender_dist_packages_versions, mender_version):
        result = setup_tester_ssh_connection.run('uname -a')
        assert "raspberrypi" in result.stdout

        upload_deb_package(setup_tester_ssh_connection, mender_dist_packages_versions["mender-client"])

        # Install the package using the following flow in the wizard:
        # Device type (for example raspberrypi3-raspbian): rasbperrytest
        # Confirm devicetype as rasbperrytest? [Y/n] y
        # Are you connecting this device to Hosted Mender? [Y/n] n
        # Do you want to run the client in demo mode? [Y/n] y
        # Set the IP of the Mender Server: [127.0.0.1] 1.2.3.4
        result = setup_tester_ssh_connection.run('sudo dpkg -i ' + package_filename(mender_dist_packages_versions["mender-client"]) + """ <<STDIN
rasbperrytest
y
n
y
1.2.3.4
STDIN""")

        assert "Unpacking mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout
        assert "Setting up mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout

        self.check_mender_client_version(setup_tester_ssh_connection, mender_version, mender_dist_packages_versions["mender-client"])

        self.check_installed_files(setup_tester_ssh_connection, "rasbperrytest")

        # Demo setup expects ServerURL docker.mender.io with IP address in /etc/hosts
        result = setup_tester_ssh_connection.run('cat /etc/mender/mender.conf')
        assert '"ServerURL": "https://docker.mender.io"' in result.stdout
        result = setup_tester_ssh_connection.run('cat /etc/hosts')
        assert re.match(r".*1\.2\.3\.4\s*docker\.mender\.io.*", result.stdout, re.DOTALL) is not None

        self.check_systemd_start_full_cycle(setup_tester_ssh_connection)

    @pytest.mark.usefixtures("setup_test_container")
    def test_remove_stop(self, setup_tester_ssh_connection, mender_dist_packages_versions):
        result = setup_tester_ssh_connection.run('sudo dpkg -r mender-client')
        assert "Removing mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout

        self.check_removed_files(setup_tester_ssh_connection, purge=False)

    @pytest.mark.usefixtures("setup_test_container")
    def test_purge(self, setup_tester_ssh_connection, mender_dist_packages_versions):
        result = setup_tester_ssh_connection.run('sudo dpkg -P mender-client')
        assert "Purging configuration files for mender-client (" + mender_dist_packages_versions["mender-client"] + ")" in result.stdout

        self.check_removed_files(setup_tester_ssh_connection, purge=True)

class TestPackageMenderClientSystemd():

    def test_mender_client_service_starts_after_reboot(self, setup_test_container, setup_tester_ssh_connection, mender_dist_packages_versions):
        conn = setup_tester_ssh_connection
        upload_deb_package(conn, mender_dist_packages_versions["mender-client"])

        conn.run('sudo DEBIAN_FRONTEND=noninteractive dpkg -i ' + package_filename(mender_dist_packages_versions["mender-client"]))

        # Reboot in the background, so that SSH can exit properly
        conn.run('sleep 1 && sudo reboot &')

        # Wait for the reboot to actually start before calling wait_for_container_boot
        time.sleep(10)
        wait_for_container_boot(setup_test_container.container_id)

        # Check first that mender process is running
        result = conn.run('pgrep mender')
        assert result.exited == 0

        result = conn.run('sudo journalctl -u mender-client --no-pager')

        # Check Mender service start after device reboot
        assert "Started Mender OTA update service." in result.stdout
        assert "Loaded configuration file" in result.stdout
        assert "No dual rootfs configuration present" in result.stdout


from abc import ABC, abstractmethod
from typing import Any, Type, TypeVar

from bevy import Bevy
from .query import Query, QueryFilter, QueryResult

TModel = TypeVar("TModel")

class Database(ABC, Bevy):
    @abstractmethod
    async def add(self, model: TModel):
        ...

    @abstractmethod
    async def connect(self):
        ...

    @abstractmethod
    def query(self, model: Type[TModel], query_filter: QueryFilter) -> Query[TModel]:
        ...

    def __getitem__(self, model: Type[TModel]) -> Query[TModel]:
        return Query(model)

    async def delete(self, model: Type[TModel], query_filter: QueryFilter):
        query = self.query(model, query_filter)
        await query.delete()

    async def fetch_all(
        self, model: Type[TModel], query_filter: QueryFilter
    ) -> QueryResult[TModel]:
        query = self.query(model, query_filter)
        return await query.fetch_all()

    async def fetch_one(
        self, model: Type[TModel], query_filter: QueryFilter
    ) -> QueryResult[TModel]:
        query = self.query(model, query_filter)
        return await query.fetch_one()

    async def update(
        self, model: Type[TModel], query_filter: QueryFilter, **changes: Any
    ):
        query = self.query(model, query_filter)
        await query.update(**changes)


import pygame
import numpy as np
import time
from random import randrange

class Wall():
    def __init__(self, rows, cols, screen_width, screen_height):
        width = screen_width // cols
        height = int(screen_height * 0.1)
        self.blocks = []
        self.blocks_exist = []
        for row in range(rows):
            block_row = []
            block_exist_row = []
            for col in range(cols):
                block_x = col * width
                block_y = row * height
                rect = pygame.Rect(block_x, block_y, width, height)
                block_row.append(rect)
                block_exist_row.append(True)
            self.blocks.append(block_row)
            self.blocks_exist.append(block_exist_row)

class Paddle():
    def __init__(self, rows, cols, screen_width, screen_height):
        self.screen_width = screen_width
        self.height = int(screen_height * 0.05)
        self.width = int(screen_width / cols)
        self.x = int(screen_width / 2 - self.width / 2)
        self.y = screen_height - (self.height * 2)
        self.speed = int(screen_width / 60) * 2
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)

    def move(self, action):
        if 2 > action < 0:
            print(f"ERROR IN BREAKOUT ENVIRONMENT: received action {action}")
            exit()
        if action == 1 and self.rect.left > 0:
            self.rect.x -= self.speed
        if action == 2 and self.rect.right < self.screen_width:
            self.rect.x += self.speed

class Ball:
    def __init__(self, start_x, start_y, screen_width, screen_height):
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.radius = int(screen_width * 0.015)
        self.x = start_x - self.radius
        self.y = start_y
        self.rect = pygame.Rect(self.x, self.y, self.radius * 2, self.radius * 2)
        self.speed_x = 4 * 2
        self.speed_y = -4 * 2
        self.speed_max = 5 * 2

    def move(self, blocks, blocks_exist, paddle):
        collision_thresh = 5 * 2

        reward = 0

        for row_id, row in enumerate(blocks):
            for block_id, block in enumerate(row):
                if not blocks_exist[row_id][block_id]:
                    continue
                if self.rect.colliderect(block):
                    # collision from above
                    if abs(self.rect.bottom - block.top) < collision_thresh and self.speed_y > 0:
                        self.speed_y *= -1
                    # collision from bellow
                    if abs(self.rect.top - block.bottom) < collision_thresh and self.speed_y < 0:
                        self.speed_y *= -1
                    # collision from left
                    if abs(self.rect.right - block.left) < collision_thresh and self.speed_x > 0:
                        self.speed_x *= -1
                    # collision from right
                    if abs(self.rect.left - block.right) < collision_thresh and self.speed_x < 0:
                        self.speed_x *= -1
                    blocks_exist[row_id][block_id] = False
                    # del wall.blocks[row_id][block_id]
                    reward += 1

        done_ = True
        for row in blocks_exist:
            for block_exists in row:
                if block_exists:
                    done_ = False
                    break
        if done_:
            reward = 10
        done = done_

        # Check collision on wall
        if self.rect.left < 0 or self.rect.right > self.screen_width:
            self.speed_x *= -1
        if self.rect.top < 0:
            self.speed_y *= -1

        # Check bottom of screen
        if self.rect.bottom > self.screen_height:
            done = True
            reward -= 10

        # Check paddle
        if self.rect.colliderect(paddle):
            if abs(self.rect.bottom - paddle.rect.top) < collision_thresh and self.speed_y > 0:
                self.speed_y *= -1
            else:
                self.speed_x *= -1

        self.rect.x += self.speed_x
        self.rect.y += self.speed_y
        return reward, done, blocks, blocks_exist

class Game():
    def __init__(self):
        pygame.init()

        self.done = False

        self.screen_width = 600  # todo change later
        self.screen_height = 600  # todo change later
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
        pygame.display.set_caption("Breakout")

        self.bg = (234, 218, 184)
        self.block_color = (242, 85, 96)
        self.paddle_color = (142, 135, 123)
        self.paddle_outline = (100, 100, 100)

        self.rows = 6
        self.cols = 6

        self.n_actions = 3
        self.n_states_disc = 10 * 10 * 2 * 2 * 10

    def reset(self):
        # initialize wall, ball, paddle
        self.wall = Wall(self.rows, self.cols, self.screen_width, self.screen_height)
        self.paddle = Paddle(self.rows, self.cols, self.screen_width, self.screen_height)
        self.ball = Ball(randrange(20, 560),
                         randrange(380, 520), self.screen_width,
                         self.screen_height)  # 380
        # return state
        return self.get_current_state()

    def get_current_state(self):
        # for image: return self.screen
        ball_x = self.ball.rect.x
        ball_y = self.ball.rect.y
        abs_speed = abs(self.ball.speed_x)
        ball_speed_x = self.ball.speed_x / abs_speed
        ball_speed_y = self.ball.speed_y / abs_speed
        paddle_x = self.paddle.rect.x + self.paddle.width / 2
        return self.discretize_state([ball_x, ball_y, ball_speed_x, ball_speed_y, paddle_x])

    def step(self, action):
        # move paddle
        self.paddle.move(action)

        # move ball and potentially break the bricks
        reward, done, blocks, blocks_exist = self.ball.move(self.wall.blocks, self.wall.blocks_exist, self.paddle)
        self.wall.blocks_exist = blocks_exist
        self.wall.blocks = blocks

        state = self.get_current_state()

        # Feedback
        ball_x = self.ball.rect.x
        feedback = 1 if self.paddle.rect.x <= ball_x < self.paddle.rect.x + self.paddle.width else -1

        return state, reward, done, feedback

    def draw(self):
        self.screen.fill(self.bg)
        self.draw_wall()
        self.draw_paddle()
        self.draw_ball()
        pygame.display.update()

    def draw_wall(self):
        for row_id, row in enumerate(self.wall.blocks):
            for b_id, block in enumerate(row):
                if not self.wall.blocks_exist[row_id][b_id]:
                    continue
                pygame.draw.rect(self.screen, self.block_color, block)
                pygame.draw.rect(self.screen, self.bg, (block), 2)

    def draw_paddle(self):
        pygame.draw.rect(self.screen, self.paddle_color, self.paddle.rect)
        pygame.draw.rect(self.screen, self.paddle_outline, self.paddle.rect, 2)

    def draw_ball(self):
        pygame.draw.circle(self.screen, self.paddle_color,
                           (self.ball.rect.x + self.ball.radius, self.ball.rect.y + self.ball.radius), self.ball.radius)
        pygame.draw.circle(self.screen, self.paddle_outline,
                           (self.ball.rect.x + self.ball.radius, self.ball.rect.y + self.ball.radius), self.ball.radius,
                           2)

    def discretize_state(self, state):
        ball_x = 9 if state[0] >= 600 else int(state[0] / 60)
        ball_y = 9 if state[1] >= 600 else int(state[1] / 60)
        ball_speed_x = 0 if state[2] == -1 else 1
        ball_speed_y = 0 if state[3] == -1 else 1
        paddle_x = 9 if state[4] >= 600 else int(state[4] / 60)
        return [ball_x, ball_y, ball_speed_x, ball_speed_y, paddle_x]

"""
# Example
env = Game()
for episode in range(10):
    state = env.reset()

    for step in range(100):
        # action = np.random.choice([0, 1, 2])
        action = 2
        new_state, reward, done, feedback = env.step(action)

        env.draw()
        time.sleep(0.1)
        print(new_state, ",", reward, ",", done)

        if done == True:
            break
"""


import colorgram
from PIL import Image
from django.db import models
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from accounts.models import Area, Prefecture

# Create your models here

class IndexCategory(models.Model):
    clothes_index = models.ForeignKey("ClothesIndex", on_delete=models.CASCADE)
    category = models.ForeignKey("Category", on_delete=models.CASCADE)
    needs_outers = models.BooleanField(_("needs_outers"), default=False)

    class Meta:
        verbose_name = _("index category")
        verbose_name_plural = _("index categories")

class ParentCategory(models.Model):
    name = models.CharField(_("parent category name"), max_length=255)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _("parent category")
        verbose_name_plural = _("parent categories")

class Category(models.Model):
    name = models.CharField(_("category name"), max_length=255)
    parent = models.ForeignKey(
        "ParentCategory",
        verbose_name="parent category",
        on_delete=models.PROTECT,
        related_name="child",
    )

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _("category")
        verbose_name_plural = _("categories")

class Clothes(models.Model):
    name = models.CharField(_("name"), max_length=255, blank=True)
    note = models.TextField(_("note"), blank=True)
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="clothes"
    )
    parent_category = models.ForeignKey(
        ParentCategory,
        verbose_name="parent category",
        related_name="parent_category",
        on_delete=models.PROTECT,
    )
    category = models.ForeignKey(
        Category,
        verbose_name="category",
        related_name="clothes",
        on_delete=models.PROTECT,
    )
    picture = models.ImageField(upload_to="clothes_pic/", blank=True, null=True)
    created_at = models.DateTimeField(_("date created"), default=timezone.now)
    publish = models.BooleanField(_("publish"), default=False)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = _("clothes")
        verbose_name_plural = _("clothes")

    def crop_picture(self, x, y, width, height):
        image = Image.open(self.picture)
        cropped_image = image.crop((x, y, width + x, height + y))
        resized_image = cropped_image.resize((200, 200), Image.ANTIALIAS)
        resized_image.save(self.picture.path)

    def show_img(self):
        if not self.picture:
            return f"/static/img/icon/clothes/{self.category}.jpg"
        return self.picture.url

    def extract_color(self):
        clothes_picture = self.picture
        if clothes_picture:
            clothes_colors = self.colors.all()
            # Check if colors an user has are extracted
            # or selected by the user.
            if clothes_colors:
                all_are_different = all(
                    [
                        clothes_colors[0].code != clothes_colors[0].original,
                        clothes_colors[1].code != clothes_colors[1].original,
                        clothes_colors[2].code != clothes_colors[2].original,
                    ]
                )
            # Extract 3 colors from an image an user will upload.
            extracted_colors = colorgram.extract(clothes_picture, 3)
            # colorgram.extract returns Color objects, which let you access
            # RGB, HSL, and what proportion of the image was that color.
            for i in range(3):
                rgb = extracted_colors[i].rgb  # e.g. Rgb(r=217, g=216, b=233)
                # RGB and HSL are named tuples, so values can be accessed as properties.
                code = f"rgb({rgb[0]},{rgb[1]},{rgb[2]})"
                # You can get a proportion of a color
                # as color.proportion  # e.g. 0.34
                if clothes_colors:
                    # Change only extracted colors if an user selects colors
                    if are_all_difference:
                        clothes_colors[i].original = code
                    # Change both colors if an user doesn't select
                    else:
                        clothes_colors[i].code = code
                        clothes_colors[i].original = code

                else:
                    ClothesColor.objects.create(clothes=self, code=code, original=code)

class ClothesColor(models.Model):
    clothes = models.ForeignKey(
        Clothes, on_delete=models.CASCADE, related_name="colors"
    )
    code = models.CharField(_("code"), max_length=64, null=True)
    original = models.CharField(_("original"), max_length=64, null=True)

    def __str__(self):
        return self.code

class Outfit(models.Model):
    name = models.CharField(_("name"), max_length=255, blank=True)
    note = models.TextField(_("note"), blank=True)
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="outfits"
    )
    outerwear = models.ForeignKey(
        Clothes,
        verbose_name="outerwear",
        related_name="outerwear",
        on_delete=models.PROTECT,
        blank=True,
        null=True,
    )
    top = models.ForeignKey(
        Clothes, verbose_name="top", related_name="top", on_delete=models.PROTECT,
    )
    extra_top = models.ForeignKey(
        Clothes,
        verbose_name="extra top",
        related_name="extra_top",
        on_delete=models.PROTECT,
        blank=True,
        null=True,
    )
    bottom = models.ForeignKey(
        Clothes, verbose_name="bottom", related_name="bottom", on_delete=models.PROTECT,
    )
    created_at = models.DateTimeField(_("date created"), default=timezone.now)
    publish = models.BooleanField(_("publish"), default=False)

    def __str__(self):
        return self.name

    def set_name(self):
        if not self.name:
            count_outfit = self.owner.outfits.count()
            self.name = f"Outfit {count_outfit + 1}"
            self.save()

class ClothesIndex(models.Model):
    value = models.PositiveIntegerField(_("value"))
    description = models.TextField(_("description"), blank=True)
    categories = models.ManyToManyField("Category", through="IndexCategory", blank=True)

    def __str__(self):
        return f"value: {self.value}"

    class Meta:
        verbose_name = _("clothes index")
        verbose_name_plural = _("clothes indexes")

class WeatherElement(models.Model):
    name = models.CharField(max_length=255)
    icon = models.CharField(max_length=255, blank=True, null=True)

    def __str__(self):
        return self.name

class Forecast(models.Model):
    area = models.ForeignKey(
        Area, verbose_name="area", related_name="forecast", on_delete=models.PROTECT
    )
    prefecture = models.ForeignKey(
        Prefecture,
        verbose_name="prefecture",
        related_name="forecast",
        on_delete=models.PROTECT,
    )
    clothes_index = models.ForeignKey(
        ClothesIndex,
        verbose_name="clothes index",
        related_name="forecast",
        on_delete=models.PROTECT,
    )
    first_weather = models.ForeignKey(
        "WeatherElement", on_delete=models.PROTECT, related_name="first"
    )
    weather_change = models.ForeignKey(
        "WeatherElement", on_delete=models.PROTECT, related_name="change", null=True
    )
    second_weather = models.ForeignKey(
        "WeatherElement", on_delete=models.PROTECT, related_name="second", null=True
    )
    highest_temp = models.IntegerField(_("highest tempreture"))
    lowest_temp = models.IntegerField(_("lowest tempreture"))
    rain_chance = models.IntegerField(_("rain chance"))
    created_at = models.DateTimeField(_("date created"))

    def __str__(self):
        return f"{self.prefecture} - {self.created_at}"


#!/usr/bin/python3

import time
import serial
import os
import sys
import threading
import socket
import base64

import numpy as np
from statsmodels import robust
import pickle
import logging
from sklearn.preprocessing import StandardScaler, MinMaxScaler, MaxAbsScaler, RobustScaler, QuantileTransformer, Normalizer
from obspy.signal.filter import highpass
from scipy.signal import savgol_filter
from keras.models import load_model

N = 128
CONFIDENCE_THRESHOLD = 0.95

'''
The following move states are used:
IDLE (with move_state as 1)
DETERMINING_DANCE_MOVE (with move_state as 2)

The machine begins in IDLE state. When idle dance move is received, it moves to DETERMINING_DANCE_MOVE state.
When dance move is successfully determined and sent to the server, it moves back to IDLE state.
'''

# Begin with IDLE state
move_state = 1

ENC_LIST = [
    ('IDLE', 0),
    ('wipers', 1),
    ('number7', 2),
    ('chicken', 3),
    ('sidestep', 4),
    ('turnclap', 5),
    # ('numbersix', 6),
    # ('salute', 7),
    # ('mermaid', 8),
    # ('swing', 9),
    # ('cowboy', 10),
    # ('logout', 11)
]

ENC_DICT = {
    0: 'IDLE',
    1: 'wipers',
    2: 'number7',
    3: 'chicken',
    4: 'sidestep',
    5: 'turnclap',
    # 6: 'numbersix',
    # 7: 'salute',
    # 8: 'mermaid',
    # 9: 'swing',
    # 10: 'cowboy',
    # 11: 'logout'
}

CLASSLIST = [ pair[0] for pair in ENC_LIST ]

# Obtain best class from a given list of class probabilities for every prediction
def onehot2str(onehot):
       enc_dict = dict([(i[1],i[0]) for i in ENC_LIST])
       idx_list = np.argmax(onehot, axis=1).tolist()
       result_str = []
       for i in idx_list:
               result_str.append(enc_dict[i])
       return np.asarray(result_str)

# Convert a class to its corresponding one hot vector
def str2onehot(Y):
   enc_dict = dict(ENC_LIST)
   new_Y = []
   for y in Y:
       vec = np.zeros((1,len(ENC_LIST)),dtype='float64')
       vec[ 0, enc_dict[y] ] = 1.
       new_Y.append(vec)
   del Y
   new_Y = np.vstack(new_Y)
   return new_Y

# Load model from pickle/hdf5 file
model = load_model(os.path.join('nn_models', 'nn_model.hdf5'))
# model = pickle.load(open('classifier_models\\model_RandomForestClassifier200.pkl', 'rb'))
# Load scalers
min_max_scaler = pickle.load(open(os.path.join('scaler', 'min_max_scaler.pkl'), 'rb'))
standard_scaler = pickle.load(open(os.path.join('scaler', 'standard_scaler.pkl'), 'rb'))

# for every segment of data (128 sets per segment with 0% overlap for now), extract the feature vector
def extract_feature_vector(X):
    # preprocess data
    X = savgol_filter(X, 3, 2)
    X = highpass(X, 3, 50)
    X = min_max_scaler.transform(X)
    # extract time domain features
    X_mean = np.mean(X, axis=0)
    X_var = np.var(X, axis=0)
    X_max = np.max(X, axis=0)
    X_min = np.min(X, axis=0)
    X_off = np.subtract(X_max, X_min)
    X_mad = robust.mad(X, axis=0)
    # extract frequency domain features - unused for now
    X_psd = []
    X_peakF = []
    # obtain feature vector by appending all vectors above as one d-dimension feature vector
    X = np.append(X_mean, [X_var, X_max, X_min, X_off, X_mad])
    return standard_scaler.transform([X])

def predict_dance_move(segment):
    X = extract_feature_vector(segment)
    Y = model.predict(X)
    # return model.predict(X).tolist()[0]
    return onehot2str(Y)[0], max(Y[0])

def readLineCR(port):
    rv = ""
    while True:
        ch = port.read().decode()
        rv += ch
        if ch == '\r':
            return rv

def testReadLineCR(port):
    read_flag = 1
    rv = ""
    while (read_flag == 1):
        ch = port.read()
        rv += ch
        if ch == '\r':
            data = rv
            read_flag = 0

# dataArray = [] # N objects in array, per 20ms
handshake_flag = False
data_flag = False
print("test")
port=serial.Serial("/dev/serial0", baudrate=115200, timeout=3.0)
print("set up")
# port.reset_input_buffer()
# port.reset_output_buffer()
while (handshake_flag == False):
    port.write('H'.encode())
    print("H sent")
    response = port.read()
    if (response.decode() == 'A'):
        print("A received, sending N")
        port.write('N'.encode())
        handshake_flag= True
        port.read()

# port.reset_input_buffer()
# port.reset_output_buffer()
print("connected")

while (data_flag == False):

    print("ENTERING")

    movementData = []
    otherData = []
    for i in range(N): # extract from 0->N-1 = N sets of readings
        data = readLineCR(port).split(',')
        data = [ float(val.strip()) for val in data ]
        movementData.append(data[:10]) # extract acc1[3], acc2[3] and gyro[3] values
        otherData.append(data[10:]) # extract voltage, current, power and cumulativepower

    # Add ML Logic
    # Precondition 1: dataArray has values for acc1[3], acc2[3], gyro[3], voltage[1], current[1], power[1] and energy[1] in that order
    # Precondition 2: dataArray has N sets of readings, where N is the segment size, hence it has dimensions N*13
    danceMove, predictionConfidence = predict_dance_move(movementData)
    if move_state == 2 and not danceMove == "IDLE" and predictionConfidence >= CONFIDENCE_THRESHOLD:
        voltage, current, power, energy = tuple(map(tuple, np.mean(otherData, axis=0)))
        output = "#" + danceMove + "|" + str(round(voltage, 2)) + "|" + str(round(current, 2)) + "|" + str(round(power, 2)) + "|" + str(round(energy, 2)) + "|"
        if danceMove == "logout":
            output = danceMove # with logout command, no other values are sent
        # TODO @ Ng Jin: Add code to send output to server below

        # Add code to send output to server above
        move_state = 1
    elif move_state == 1 and danceMove == "IDLE":
        move_state = 2

    print("Print array: ")
    output = "1.0,2.0,3.0,4.0,5.0"
    output = output.replace(',', '|')
    print(output)
    action, voltage, current, power, cumulativepower = output.split('|')
    print("action: " + action + '\n' + "voltage: " + voltage + '\n' + "current: " + current + '\n' +
          "power: " + power + '\n' + "cumulativepower: " + cumulativepower + '\n')

    data_flag = True


import subprocess
import os
from tkinter import Tk, Text, Button, END, re, font, W, Entry, Label, Frame, filedialog, messagebox
import fileRepresentation as ventana_fileRepresentation

class Interfaz:
    def __init__(self):
        self.window = Tk()
        # Inicializar la ventana con un título
        self.window.title('File Fast System')
        self.window.geometry('854x680')
        self.createAndPositionButtons()
        self.entries = self.createAndPositionEntries()
        self.createAndPositionLabels()
        self.path = ''
        self.txt = Text(self.window, height = 23, width = 50, state='disabled')

        self.txt.grid(row=5, column=1, sticky=W, pady=(30,5), padx=4)

        self.window.mainloop()

    def createAndPositionButtons(self):
        createDiretory = Button(self.window, text='Crear directorio',
                                width=15, height=1, font=('mincho', 11), command=self.createDirectory)
        createFile = Button(self.window, text='Crear Archivo',
                            width=15, height=1, font=('mincho', 11), command=self.createFile)
        deleteFile = Button(self.window, text='Eliminar Archivo',
                            width=15, height=1, font=('mincho', 11), command=self.deleteFile)
        execFfs = Button(self.window, text='Crear archivos/directorios',
                         width=25, height=1, font=('mincho', 11), command=self.execFFS)
        loadFile = Button(self.window, text='Cargar archivo',
                          width=15, height=1, font=('mincho', 11), command=self.onOpen)
        buttons = [createDiretory, createFile, deleteFile]

        for i, val in enumerate(buttons):
            val.grid(row=i + 1, column=0, sticky=W, pady=4, padx=(12,4))
        execFfs.grid(row=6, column=1, pady=4)
        loadFile.grid(row=7, column=2, pady=4)

    def createDirectory(self):
        if self.entries[0].get() != '':
            self.txt.configure(state='normal')
            self.txt.insert(END, 'dir '+ self.entries[0].get()+ '\n')
            self.txt.configure(state='disabled')
            self.entries[0].delete(0, END)

    def createFile(self):
        if self.entries[1].get() != '' and self.entries[3].get().isdigit():
            self.txt.configure(state='normal')
            self.txt.insert(END, 'file ' + self.entries[1].get() + ' '+ self.entries[3].get()  +'\n')
            self.txt.configure(state='disabled')
        else:
            self.onError()
        self.entries[1].delete(0, END)
        self.entries[3].delete(0, END)

    def deleteFile(self):
        if self.entries[2].get() != '':
            self.txt.configure(state='normal')
            self.txt.insert(END, 'delete ' + self.entries[2].get()+ '\n')
            self.txt.configure(state='disabled')
            self.entries[2].delete(0, END)

    def createAndPositionEntries(self):
        entries = []
        for i in range(0,3):
            entries.append(Entry(self.window, font=('mincho', 14)))
            entries[i].grid(row=i + 1, column=1, pady=4, padx=4)
        size = Entry(self.window, font=('mincho', 14))
        entries.append(size)
        size.grid(row=2, column=2, pady=4, padx=4)
        return entries

    def createAndPositionLabels(self):
        action = Label(self.window, text = 'Acción', font=('mincho', 12))
        name = Label(self.window, text = 'Nombre', font=('mincho', 12))
        size = Label(self.window, text = 'Tamaño', font=('mincho', 12))
        infoLabel = Label(self.window, text = 'En caso de tener el txt listo, puede cargar el archivo')
        labels = [action, name, size]
        for i, val in enumerate(labels):
            val.grid(row=0, column=i, pady=4, padx=4)
        infoLabel.grid(row=7, column=1, pady=4, padx=4)

    def onOpen(self):
        ftypes = [('Todos los archivos', '*')]
        dlg = filedialog.Open(self.window, filetypes = ftypes)
        path = dlg.show()

        if path != '':
            text = self.readFile(path)
            self.txt.configure(state='normal')
            self.txt.insert(END, text)
            self.txt.configure(state='disabled')
            self.unableEntries()
            self.path = path

    def unableEntries(self):
        for i in range(len(self.entries)):
            self.entries[i].configure(state='disabled')

    def readFile(self, filename):

        with open(filename, 'r') as f:
            text = f.read()

        return text

    def execFFS(self):
        self.writeFile()
        data = subprocess.Popen('./src/ffs.py -f ' + self.path + ' -c', shell=True, stdout=subprocess.PIPE).stdout.readlines()
        self.window.destroy()
        ventana_fileRepresentation.Interfaz(data, self.path)

    def onError(self):
        messagebox.showerror('Error', 'El tamaño no está permitido, ingrese un número natural')

    def writeFile(self):
        if self.path == '':
            path = './assets/input_user_file'
            f = open(path, 'w+')
            f.write(self.txt.get('1.0', END))
            f.close()
            self.path = path

if __name__ == "__main__":
    ffs = Interfaz()


from django.shortcuts import render
import json
from django.core import serializers
from django.http import HttpResponse
from frontend.models import Suggestion, Facultie, Course
from django.views.decorators.csrf import csrf_exempt

# Create your views here.
@csrf_exempt
def index(request):
    return render(request, 'faculty/index.html')
@csrf_exempt
def review(request):
    datas = list(Suggestion.objects.values('category', 'score'))
    score = [['Category', 'Weightage']]
    categories = list(set(Suggestion.objects.values_list('category', flat=True)))
    for category in categories:
        sum = 0
        count = 0
        for data in datas:
            if category == data['category']:
                sum = sum + int(data['score'])
                count = count + 1
        total  = (sum / count)
        score.append([category, total])
    return HttpResponse(json.dumps(score), content_type='application/json')


# Copyright 2019 clbo@kea.dk
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

# Basic Filter exercises
# Fill in the code for the functions below. main() is already set up
# to call the functions with a few different inputs,
# printing 'OK' when each function is correct.
# The starter code for each function includes a 'return'
# which is just a placeholder for your code.

# A. Get 'a' words
# Give a list of words, return a tuple of words containing the letter 'a'
# Use the filter function to solve this task.
def get_a_words(words):

    x = tuple(filter(lambda x: "a" in x, words))

    return x

# C. Filter un-even number
# Give a list of numbers, return a list of the un-even numbers
# from the original list. Use the filter function to solve this task.
def filter_uneven_numbers(num):

    y = list(filter(lambda y: y % 2, num))

    return y

# Simple provided test() function used in main() to print
# what each function returns vs. what it's supposed to return.
def test(got, expected):
    if got == expected:
        prefix = ' OK '
    else:
        prefix = '  X '
    print(f'{prefix} got: {got} expected: {expected}')

# Calls the above functions with interesting inputs.
def main():

    print('get_a_words')
    test(get_a_words(['aba', 'dd', 'the', 'abcda']), ('aba', 'abcda'))
    test(get_a_words(['aba', 'xyz', 'aa', 'x', 'bbb']), ('aba', 'aa'))
    test(get_a_words(['', 'x', 'xy', 'xyx', 'xx']), ())
    test(get_a_words(['aaa', 'be', 'abc', 'hello']), ('aaa', 'abc'))

    print('filter_uneven_numbers')
    test(filter_uneven_numbers([1, 2, 3, 4, 5, 6, 7]), [1, 3, 5, 7])
    test(filter_uneven_numbers([17, 121, 44, 55, 61]), [17, 121, 55, 61])
    test(filter_uneven_numbers([111, 108, 54, 27, 81]), [111, 27, 81])

if __name__ == "__main__":
    main()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from django.conf import settings

class Migration(migrations.Migration):

    dependencies = [
        ('contant', '0001_initial'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Playlist',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(max_length=60)),
                ('specification', models.TextField(null=True)),
                ('rating', models.FloatField(default=0)),
            ],
            options={
                'db_table': 'playlists',
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='PlaylistComposition',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('composition', models.ForeignKey(related_name='composition', to='contant.Compositions')),
                ('playlist', models.ForeignKey(related_name='playlist', to='playlist.Playlist')),
            ],
            options={
                'db_table': 'playlist_composition',
            },
            bases=(models.Model,),
        ),
        migrations.AddField(
            model_name='playlist',
            name='compositions',
            field=models.ManyToManyField(to='contant.Compositions', through='playlist.PlaylistComposition'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='playlist',
            name='user_id',
            field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
            preserve_default=True,
        ),
    ]


import torch
import os
#! /usr/bin/env python

import tensorflow as tf
import numpy as np
import os
import time
import datetime
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from corpus import *
from models_CapsE import CapsE

np.random.seed(1234)
tf.set_random_seed(1234)

from models import SpKBGATModified, SpKBGATConvOnly
from torch.autograd import Variable
import numpy as np
from utils import save_model, load_object, load_model, save_object
import random
import time
from config import Config

args = Config()
args.load_config()
device = "cuda" if args.cuda else "cpu"

with tf.Graph().as_default():
    session_conf = tf.ConfigProto(allow_soft_placement=args.allow_soft_placement, log_device_placement=args.log_device_placement)
    session_conf.gpu_options.allow_growth = True
    sess = tf.Session(config=session_conf)
    with sess.as_default():
        global_step = tf.Variable(0, name="global_step", trainable=False)
        capse = CapsE(sequence_length=x_valid.shape[1],
                            initialization=initialization,
                            embedding_size=args.embedding_dim,
                            filter_size=args.filter_size,
                            num_filters=args.num_filters,
                            vocab_size=len(words_indexes),
                            iter_routing=args.iter_routing,
                            batch_size=2*args.batch_size,
                            num_outputs_secondCaps=args.num_outputs_secondCaps,
                            vec_len_secondCaps=args.vec_len_secondCaps,
                            useConstantInit=args.useConstantInit
                            )

        # Define Training procedure
        #optimizer = tf.contrib.opt.NadamOptimizer(1e-3)
        optimizer = tf.train.AdamOptimizer(learning_rate=args.learning_rate)
        #optimizer = tf.train.RMSPropOptimizer(learning_rate=args.learning_rate)
        #optimizer = tf.train.GradientDescentOptimizer(learning_rate=args.learning_rate)
        grads_and_vars = optimizer.compute_gradients(capse.total_loss)
        train_op = optimizer.apply_gradients(grads_and_vars, global_step=global_step)

        out_dir = os.path.abspath(os.path.join(args.run_folder, "runs_CapsE", args.model_name))
        print("Writing to {}\n".format(out_dir))

        checkpoint_dir = os.path.abspath(os.path.join(out_dir, "checkpoints"))
        checkpoint_prefix = os.path.join(checkpoint_dir, "model")
        if not os.path.exists(checkpoint_dir):
            os.makedirs(checkpoint_dir)
        # Initialize all variables
        sess.run(tf.global_variables_initializer())

        def train_step(x_batch, y_batch):
            """
            A single training step
            """
            feed_dict = {
                capse.input_x: x_batch,
                capse.input_y: y_batch
            }
            _, step, loss = sess.run([train_op, global_step, capse.total_loss], feed_dict)
            return loss

        num_batches_per_epoch = int((data_size - 1) / args.batch_size) + 1
        for epoch in range(args.num_epochs):
            for batch_num in range(num_batches_per_epoch):
                x_batch, y_batch = train_batch()
                loss = train_step(x_batch, y_batch)
                current_step = tf.train.global_step(sess, global_step)
                #print(loss)
            if epoch > 0:
                if epoch % args.savedEpochs == 0:
                    path = capse.saver.save(sess, checkpoint_prefix, global_step=epoch)
                    print("Saved model checkpoint to {}\n".format(path))


from bisect import bisect_left
from itertools import accumulate

n, m = map(int, input().split())
a = list(map(int, input().split()))
a.sort()

b = [0] + a
b.sort(reverse=True)
b = [0] +b
b = list(accumulate(b))

def isok(sum_):
    n_pattern = 0
    for i in range(n):
        n_pattern += n - bisect_left(a, sum_ - a[i])
        if n_pattern >= m:
            return True

    return False

ok = min(a)*2
ng = max(a)*2 +1

while ng - ok > 1:
    mid = (ok+ng)//2
    if isok(mid):
        ok = mid
    else:
        ng = mid

sum_ng = ng
sum_ok = ok

m_counter_ng = 0

ans = 0
for i in range(n):
    id_ng = bisect_left(a, sum_ng - a[i])
    ans += b[n-id_ng]
    ans += a[i]*(n - id_ng)
    m_counter_ng += n - id_ng

ans += sum_ok * (m - m_counter_ng)

print(ans)


from flask import Blueprint, render_template, abort, request, current_app
from flask_login import login_required

from simpledu.models import Live

live = Blueprint('live', __name__, url_prefix='/live')

@live.route('/')
@login_required
def index():
    page = request.args.get('page', default=1, type=int)
    pagination = Live.get_page(page=page, per_page=current_app.config['INDEX_PER_PAGE'])
    return render_template('live/index.html', pagination=pagination)

@live.route('/<int:id>')
@login_required
def detail(id):
    live = Live.query.get_or_404(id)
    return render_template('live/live.html', live=live)


from .rman_ui_base import _RManPanelHeader,ShaderPanel,ShaderNodePanel, CollectionPanel
from ..rfb_utils.shadergraph_utils import is_renderman_nodetree, gather_nodes
from ..rfb_utils.draw_utils import panel_node_draw,draw_nodes_properties_ui,draw_node_properties_recursive
from ..rfb_utils.draw_utils import show_node_sticky_params, show_node_match_params
from ..rfb_utils.prefs_utils import get_pref
from ..rman_cycles_convert import do_cycles_convert
from .. import rfb_icons
from ..rman_render import RmanRender
import bpy
from bpy.types import Panel

class MATERIAL_PT_renderman_preview(ShaderPanel, Panel):
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_options = {'DEFAULT_CLOSED'}
    bl_context = "material"
    bl_label = "Preview"

    @classmethod
    def poll(cls, context):
        if context.scene.render.engine != "PRMAN_RENDER":
            return
        mat = getattr(context, 'material', None)
        if not mat:
            return False
        rr = RmanRender.get_rman_render()
        if rr.rman_interactive_running:
            return False
        return get_pref('rman_do_preview_renders', False)

    def draw(self, context):
        layout = self.layout
        mat = context.material
        row = layout.row()

        if mat:
            row.template_preview(context.material, show_buttons=1)

        layout.separator()
        split = layout.split()

        col = split.column(align=True)
        col.label(text="Viewport Color:")
        col.prop(mat, "diffuse_color", text="")

        col = split.column(align=True)
        col.label(text="Viewport Specular:")
        col.prop(mat, "specular_color", text="")
        #FIXME col.prop(mat, "specular_hardness", text="Hardness")

class MATERIAL_PT_renderman_material_refresh(ShaderPanel, Panel):
    bl_context = "material"
    bl_label = "Refresh"

    @classmethod
    def poll(cls, context):
        mat = getattr(context, 'material', None)
        if not mat:
            return False
        rr = RmanRender.get_rman_render()
        if not rr.rman_is_live_rendering:
            return False
        if rr.rman_swatch_render_running:
            return False
        return True

    def draw(self, context):
        mat = context.material
        layout = self.layout
        rr = RmanRender.get_rman_render()
        if rr.rman_is_live_rendering:
            layout.context_pointer_set("material", mat)
            layout.operator("node.rman_force_material_refresh", text='Force Refresh')

class DATA_PT_renderman_light_refresh(ShaderPanel, Panel):
    bl_context = "data"
    bl_label = "Refresh"

    @classmethod
    def poll(cls, context):
        light = getattr(context, 'light', None)
        if not light:
            return False
        rr = RmanRender.get_rman_render()
        if not rr.rman_is_live_rendering:
            return False
        if rr.rman_swatch_render_running:
            return False
        return True

    def draw(self, context):
        layout = self.layout
        light = getattr(context, 'light', None)
        if not light:
            return False
        rr = RmanRender.get_rman_render()
        if light.renderman.renderman_light_role == 'RMAN_LIGHT':
            layout.context_pointer_set("light", context.active_object)
            layout.operator("node.rman_force_light_refresh", text='Force Refresh')
        else:
            layout.context_pointer_set("light_filter", context.active_object)
            layout.operator("node.rman_force_lightfilter_refresh", text='Force Refresh')

class MATERIAL_PT_renderman_shader_surface(ShaderPanel, Panel):
    bl_context = "material"
    bl_label = "Bxdf"
    shader_type = 'Bxdf'

    def draw(self, context):
        mat = context.material
        layout = self.layout
        if context.material.renderman and context.material.node_tree:
            nt = context.material.node_tree
            rman_output_node = is_renderman_nodetree(mat)

            if rman_output_node:
                if rman_output_node.solo_node_name != '':
                    solo_node = nt.nodes.get(rman_output_node.solo_node_name, None)
                    if solo_node:

                        split = layout.split(factor=0.25)
                        split.context_pointer_set("nodetree", nt)
                        split.context_pointer_set("node", rman_output_node)
                        rman_icon = rfb_icons.get_icon('rman_solo_on')
                        split.label(text=rman_output_node.solo_node_name , icon_value=rman_icon.icon_id)

                        split = split.split(factor=0.95)
                        split.menu('NODE_MT_renderman_node_solo_output_menu', text='Select Output')
                        op = split.operator('node.rman_set_node_solo', text='', icon='FILE_REFRESH')
                        op.refresh_solo = True
                        layout.separator()

                        layout.separator()
                        draw_node_properties_recursive(layout, context, nt, solo_node, level=0)
                        return

                # Filter Toggle
                split = layout.split(factor=0.05)
                col = split.column()
                filter_icon = 'FILTER'
                filter_parameters = getattr(rman_output_node, 'bxdf_filter_parameters', False)
                filter_method = getattr(rman_output_node, 'bxdf_filter_method', 'NONE')
                col.context_pointer_set('node', rman_output_node)
                pressed = filter_parameters
                op = col.operator('node.rman_toggle_filter_params', depress=pressed, icon=filter_icon, text='')
                op.prop_name = 'bxdf_filter_parameters'

                if filter_parameters:
                    col = split.column()
                    col.prop(rman_output_node, 'bxdf_filter_method', text='')

                    if filter_method == 'MATCH':
                        col = split.column()
                        col.prop(rman_output_node, 'bxdf_match_expression', text='')
                        col = split.column()
                        col.prop(rman_output_node, 'bxdf_match_on', text='')
                    else:
                        col = split.column()
                        col = split.column()

                layout.separator()
                input_name = 'bxdf_in'
                if not rman_output_node.inputs[input_name].is_linked:
                    panel_node_draw(layout, context, mat,
                                    'RendermanOutputNode', 'Bxdf')
                elif not filter_parameters or filter_method == 'NONE':
                    panel_node_draw(layout, context, mat,
                                    'RendermanOutputNode', 'Bxdf')
                elif filter_method == 'STICKY':
                    bxdf_node = rman_output_node.inputs[input_name].links[0].from_node
                    nodes = gather_nodes(bxdf_node)
                    for node in nodes:
                        prop_names = getattr(node, 'prop_names', list())
                        show_node_sticky_params(layout, node, prop_names, context, nt, rman_output_node)
                elif filter_method == 'MATCH':
                    expr = rman_output_node.bxdf_match_expression
                    if expr == '':
                        return
                    bxdf_node = rman_output_node.inputs[input_name].links[0].from_node
                    nodes = gather_nodes(bxdf_node)
                    for node in nodes:
                        prop_names = getattr(node, 'prop_names', list())
                        show_node_match_params(layout, node, expr, rman_output_node.bxdf_match_on,
                                            prop_names, context, nt)
                else:
                    panel_node_draw(layout, context, mat,
                                    'RendermanOutputNode', 'Bxdf')

            else:
                if not panel_node_draw(layout, context, mat, 'ShaderNodeOutputMaterial', 'Surface'):
                    layout.prop(mat, "diffuse_color")
            layout.separator()

        else:
            # if no nodetree we use pxrdisney
            mat = context.material
            rm = mat.renderman

            row = layout.row()
            row.prop(mat, "diffuse_color")

            layout.separator()
        if mat and not is_renderman_nodetree(mat):
            rm = mat.renderman
            row = layout.row()
            #row.prop(rm, "copy_color_params")

            row = layout.row(align=True)
            col = row.column()
            rman_icon = rfb_icons.get_icon('rman_graph')
            col.operator(
                'material.rman_add_rman_nodetree', icon_value=rman_icon.icon_id).idtype = "material"
            if do_cycles_convert():
                col = row.column()
                op = col.operator('material.rman_convert_cycles_shader').idtype = "material"
                if not mat.grease_pencil:
                    layout.operator('material.rman_convert_all_cycles_shaders')

class MATERIAL_PT_renderman_shader_light(ShaderPanel, Panel):
    bl_context = "material"
    bl_label = "Light Emission"
    shader_type = 'Light'
    COMPAT_ENGINES = {'PRMAN_RENDER'}

    @classmethod
    def poll(cls, context):
        mat = getattr(context, 'material', None)
        if not mat:
            return False
        if not mat.node_tree:
            return False
        output = is_renderman_nodetree(mat)
        if not output:
            return False
        if not output.inputs[1].is_linked:
            return False

        from_node = output.inputs[1].links[0].from_node
        return from_node.bl_label == 'PxrMeshLight'

    def draw(self, context):
        if context.material.node_tree:
            nt = context.material.node_tree
            mat = context.material
            rman_output_node = is_renderman_nodetree(mat)
            if not rman_output_node:
                return
            layout = self.layout

            # Filter Toggle
            split = layout.split(factor=0.05)
            col = split.column()
            filter_icon = 'FILTER'
            filter_parameters = getattr(rman_output_node, 'light_filter_parameters', False)
            filter_method = getattr(rman_output_node, 'light_filter_method', 'NONE')
            col.context_pointer_set('node', rman_output_node)
            pressed = filter_parameters
            op = col.operator('node.rman_toggle_filter_params', depress=pressed, icon=filter_icon, text='')
            op.prop_name = 'light_filter_parameters'

            if filter_parameters:
                col = split.column()
                col.prop(rman_output_node, 'light_filter_method', text='')

                if filter_method == 'MATCH':
                    col = split.column()
                    col.prop(rman_output_node, 'light_match_expression', text='')
                    col = split.column()
                    col.prop(rman_output_node, 'light_match_on', text='')
                else:
                    col = split.column()
                    col = split.column()

            input_name = 'light_in'
            if not rman_output_node.inputs[input_name].is_linked:
                draw_nodes_properties_ui(
                    layout, context, nt, input_name=input_name)
            elif not filter_parameters or filter_method == 'NONE':
                draw_nodes_properties_ui(
                    layout, context, nt, input_name=input_name)
            elif filter_method == 'STICKY':
                light_node = rman_output_node.inputs[input_name].links[0].from_node
                nodes = gather_nodes(light_node)
                for node in nodes:
                    prop_names = getattr(node, 'prop_names', list())
                    show_node_sticky_params(layout, node, prop_names, context, nt, rman_output_node)
            elif filter_method == 'MATCH':
                expr = rman_output_node.light_match_expression
                if expr == '':
                    return
                light_node = rman_output_node.inputs[input_name].links[0].from_node
                nodes = gather_nodes(light_node)
                for node in nodes:
                    prop_names = getattr(node, 'prop_names', list())
                    show_node_match_params(layout, node, expr, rman_output_node.disp_match_on,
                                        prop_names, context, nt)
            else:
                draw_nodes_properties_ui(
                    layout, context, nt, input_name=input_name)

class MATERIAL_PT_renderman_shader_displacement(ShaderPanel, Panel):
    bl_context = "material"
    bl_label = "Displacement"
    shader_type = 'Displacement'
    COMPAT_ENGINES = {'PRMAN_RENDER'}

    def draw(self, context):
        if context.material.node_tree:
            nt = context.material.node_tree
            mat = context.material
            rman_output_node = is_renderman_nodetree(mat)
            if not rman_output_node:
                return
            layout = self.layout

            # Filter Toggle
            split = layout.split(factor=0.05)
            col = split.column()
            filter_icon = 'FILTER'
            filter_parameters = getattr(rman_output_node, 'disp_filter_parameters', False)
            filter_method = getattr(rman_output_node, 'disp_filter_method', 'NONE')
            col.context_pointer_set('node', rman_output_node)
            pressed = filter_parameters
            op = col.operator('node.rman_toggle_filter_params', depress=pressed, icon=filter_icon, text='')
            op.prop_name = 'disp_filter_parameters'

            if filter_parameters:
                col = split.column()
                col.prop(rman_output_node, 'disp_filter_method', text='')

                if filter_method == 'MATCH':
                    col = split.column()
                    col.prop(rman_output_node, 'disp_match_expression', text='')
                    col = split.column()
                    col.prop(rman_output_node, 'disp_match_on', text='')
                else:
                    col = split.column()
                    col = split.column()

            input_name = 'displace_in'
            if not rman_output_node.inputs[input_name].is_linked:
                draw_nodes_properties_ui(
                    layout, context, nt, input_name=input_name)
            elif not filter_parameters or filter_method == 'NONE':
                draw_nodes_properties_ui(
                    layout, context, nt, input_name=input_name)
            elif filter_method == 'STICKY':
                disp_node = rman_output_node.inputs[input_name].links[0].from_node
                nodes = gather_nodes(disp_node)
                for node in nodes:
                    prop_names = getattr(node, 'prop_names', list())
                    show_node_sticky_params(layout, node, prop_names, context, nt, rman_output_node)
            elif filter_method == 'MATCH':
                expr = rman_output_node.disp_match_expression
                if expr == '':
                    return
                disp_node = rman_output_node.inputs[input_name].links[0].from_node
                nodes = gather_nodes(disp_node)
                for node in nodes:
                    prop_names = getattr(node, 'prop_names', list())
                    show_node_match_params(layout, node, expr, rman_output_node.disp_match_on,
                                        prop_names, context, nt)
            else:
                draw_nodes_properties_ui(
                    layout, context, nt, input_name=input_name)

class DATA_PT_renderman_light(ShaderPanel, Panel):
    bl_context = "data"
    bl_label = "Light"
    shader_type = 'light'

    def draw(self, context):
        layout = self.layout

        light = context.light
        if not light.renderman.use_renderman_node:
            layout.prop(light, "type", expand=True)
            layout.prop(light, "color")
            layout.prop(light, "energy")
            if light.type == 'POINT':
                layout.prop(light, "shadow_soft_size")
            layout.label(text='')
            layout.operator('material.rman_add_rman_nodetree').idtype = 'light'
            return
        else:
            row = layout.row()
            col = row.column()
            light_shader = light.renderman.get_light_node_name()
            if light.renderman.renderman_light_role == 'RMAN_LIGHT':
                rman_light_icon = rfb_icons.get_light_icon(light_shader)
            else:
                rman_light_icon = rfb_icons.get_lightfilter_icon(light_shader)
            col.label(text="%s" % light_shader, icon_value=rman_light_icon.icon_id)

class PRMAN_PT_context_material(_RManPanelHeader, Panel):
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_label = ""
    bl_context = "material"
    bl_options = {'HIDE_HEADER'}
    COMPAT_ENGINES = {'PRMAN_RENDER'}

    @classmethod
    def poll(cls, context):
        if context.active_object and context.active_object.type == 'GPENCIL':
            return False
        else:
            return (context.material or context.object) and _RManPanelHeader.poll(context)

    def draw(self, context):
        layout = self.layout

        mat = context.material
        ob = context.object
        slot = context.material_slot
        space = context.space_data

        if ob:
            is_sortable = len(ob.material_slots) > 1
            rows = 1
            if (is_sortable):
                rows = 4

            row = layout.row()

            row.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=rows)

            col = row.column(align=True)
            col.operator("object.material_slot_add", icon='ADD', text="")
            col.operator("object.material_slot_remove", icon='REMOVE', text="")

            col.menu("MATERIAL_MT_context_menu", icon='DOWNARROW_HLT', text="")

            if is_sortable:
                col.separator()

                col.operator("object.material_slot_move", icon='TRIA_UP', text="").direction = 'UP'
                col.operator("object.material_slot_move", icon='TRIA_DOWN', text="").direction = 'DOWN'

            if ob.mode == 'EDIT':
                row = layout.row(align=True)
                row.operator("object.material_slot_assign", text="Assign")
                row.operator("object.material_slot_select", text="Select")
                row.operator("object.material_slot_deselect", text="Deselect")

        split = layout.split(factor=0.65)

        if ob:
            split.template_ID(ob, "active_material", new="material.new")
            row = split.row()

            if slot:
                row.prop(slot, "link", text="")
            else:
                row.label()
        elif mat:
            split.template_ID(space, "pin_id")
            split.separator()

class DATA_PT_renderman_node_shader_light(ShaderNodePanel, Panel):
    bl_label = "Light Parameters"
    bl_context = 'data'

    @classmethod
    def poll(cls, context):
        rd = context.scene.render
        return rd.engine == 'PRMAN_RENDER' and hasattr(context, "light") \
            and context.light is not None and hasattr(context.light, 'renderman') \
            and context.light.renderman.renderman_light_role != 'RMAN_LIGHTFILTER'

    def draw(self, context):
        layout = self.layout
        light = context.light
        layout.prop(light.renderman, 'light_primary_visibility')
        if light.node_tree:
            nt = light.node_tree
            draw_nodes_properties_ui(
                self.layout, context, nt, input_name='light_in')

class DATA_PT_renderman_node_shader_lightfilter(ShaderNodePanel, Panel):
    bl_label = "Light Filter Parameters"
    bl_context = 'data'

    @classmethod
    def poll(cls, context):
        rd = context.scene.render
        return rd.engine == 'PRMAN_RENDER' and hasattr(context, "light") \
            and context.light is not None and hasattr(context.light, 'renderman') \
            and context.light.renderman.renderman_light_role == 'RMAN_LIGHTFILTER'

    def draw(self, context):
        layout = self.layout
        light = context.light

        if light.node_tree:
            nt = light.node_tree
            draw_nodes_properties_ui(
                self.layout, context, nt, input_name='lightfilter_in')

class RENDERMAN_UL_LightFilters(CollectionPanel):
    def draw_item(self, layout, context, item):
        layout.prop(item, 'linked_filter_ob')

        lightfilter = item.linked_filter_ob
        if lightfilter:
            if context.scene.objects.get(lightfilter.name) == None:
                # This is pure yuck. We shouldn't be modifying the scene
                # during a draw routine. However, we can still be referencing
                # an object that's already been removed.
                bpy.data.objects.remove(lightfilter)
                return

            if lightfilter.data.node_tree:
                col = layout.column()
                rr = RmanRender.get_rman_render()
                if rr.rman_is_live_rendering:
                    col.context_pointer_set("light_filter", lightfilter)
                    col.operator("node.rman_force_lightfilter_refresh", text='Force Refresh')

                nt = lightfilter.data.node_tree
                draw_nodes_properties_ui(
                    self.layout, context, nt, input_name='lightfilter_in')
        else:
            layout.label(text='No light filter linked')

    def draw(self, context):
        layout = self.layout
        light = context.light

        self._draw_collection(context, layout, light.renderman, "",
                              "collection.add_remove", "light", "light_filters",
                              "light_filters_index")

class DATA_PT_renderman_node_filters_light(RENDERMAN_UL_LightFilters, Panel):
    bl_label = "Light Filters"
    bl_context = 'data'

    @classmethod
    def poll(cls, context):
        rd = context.scene.render
        return rd.engine == 'PRMAN_RENDER' and hasattr(context, "light") \
            and context.light is not None and hasattr(context.light, 'renderman') \
            and context.light.renderman.renderman_light_role != 'RMAN_LIGHTFILTER'

class RENDERMAN_UL_Porta_Lights(CollectionPanel):
    def draw_item(self, layout, context, item):
        #layout.prop(item, 'linked_portal_ob')

        portal = item.linked_portal_ob
        if portal:
            if context.scene.objects.get(portal.name) == None:
                # This is pure yuck. We shouldn't be modifying the scene
                # during a draw routine. However, we can still be referencing
                # an object that's already been removed.
                bpy.data.objects.remove(portal)
                return

            if portal.data.node_tree:
                nt = portal.data.node_tree
                draw_nodes_properties_ui(
                    self.layout, context, nt, input_name='lightfilter_in')
        else:
            layout.label(text='No portal light linked')

    def draw(self, context):
        layout = self.layout
        light = context.light

        self._draw_collection(context, layout, light.renderman, "",
                              "", "light", "portal_lights",
                              "portal_lights_index")

class DATA_PT_renderman_node_portal_light(RENDERMAN_UL_Porta_Lights, Panel):
    bl_label = "Portal Lights"
    bl_context = 'data'

    @classmethod
    def poll(cls, context):
        rd = context.scene.render
        return rd.engine == 'PRMAN_RENDER' and hasattr(context, "light") \
            and context.light is not None and hasattr(context.light, 'renderman') \
            and context.light.renderman.renderman_light_role == 'RMAN_LIGHT' \
            and context.light.renderman.get_light_node_name() == 'PxrDomeLight'

class DATA_PT_renderman_node_dome_light(ShaderNodePanel, Panel):
    bl_label = "Dome Lights"
    bl_context = 'data'

    @classmethod
    def poll(cls, context):
        rd = context.scene.render
        return rd.engine == 'PRMAN_RENDER' and hasattr(context, "light") \
            and context.light is not None and hasattr(context.light, 'renderman') \
            and context.light.renderman.renderman_light_role == 'RMAN_LIGHT' \
            and context.light.renderman.get_light_node_name() == 'PxrPortalLight'

    def draw(self, context):
        layout = self.layout
        light = context.light
        rm = light.renderman

        layout.prop(rm, 'dome_light_portal')

class DATA_PT_renderman_node_shader_light_viewport(ShaderNodePanel, Panel):
    bl_label = "Viewport"
    bl_context = 'data'

    @classmethod
    def poll(cls, context):
        rd = context.scene.render
        return rd.engine == 'PRMAN_RENDER' and hasattr(context, "light") \
            and context.light is not None and hasattr(context.light, 'renderman') \
            and context.light.renderman.renderman_light_role != 'RMAN_LIGHTFILTER' \
            and context.light.renderman.get_light_node_name() in ['PxrRectLight', 'PxrCylinderLight', 'PxrSphereLight', 'PxrDiskLight']

    def draw(self, context):
        layout = self.layout
        light = context.light
        node = light.renderman.get_light_node()
        if getattr(node, 'coneAngle', 90.0) >= 90.0:
            layout.enabled = False
        layout.prop(light.renderman, 'rman_coneAngleDepth')
        layout.prop(light.renderman, 'rman_coneAngleOpacity')
class MATERIAL_PT_renderman_shader_light_filters(RENDERMAN_UL_LightFilters, Panel):
    bl_context = "material"
    bl_label = "Light Filters"
    bl_parent_id = 'MATERIAL_PT_renderman_shader_light'

    def draw(self, context):
        layout = self.layout
        mat = context.material

        self._draw_collection(context, layout, mat.renderman_light, "",
                              "renderman.add_meshlight_lightfilter", "material", "light_filters",
                              "light_filters_index")

classes = [
    MATERIAL_PT_renderman_preview,
    MATERIAL_PT_renderman_material_refresh,
    DATA_PT_renderman_light_refresh,
    MATERIAL_PT_renderman_shader_surface,
    MATERIAL_PT_renderman_shader_light,
    MATERIAL_PT_renderman_shader_displacement,
    DATA_PT_renderman_light,
    DATA_PT_renderman_node_shader_light,
    DATA_PT_renderman_node_shader_lightfilter,
    DATA_PT_renderman_node_filters_light,
    DATA_PT_renderman_node_portal_light,
    DATA_PT_renderman_node_dome_light,
    DATA_PT_renderman_node_shader_light_viewport,
    PRMAN_PT_context_material,
    MATERIAL_PT_renderman_shader_light_filters
]

def register():
    from ..rfb_utils import register_utils

    register_utils.rman_register_classes(classes)

def unregister():
    from ..rfb_utils import register_utils

    register_utils.rman_unregister_classes(classes)


'''
Created on 30 dic. 2019

@author: javier
'''
from CRIO.Clustering import createClusters
from CRIO.Grouping import createGroups
from CRIO.Regionalization import createRegions
from CRIO.Modelo.Sample import Sample
from CRIO.Modelo.SampleContainer import SampleContainer

class Classifier(object):
    '''
    Esta clase se ocupa de determinar si una muestra pertenece a una de dos clases
    '''
    def __init__(self, c0,c1,t0,t1,d,k):
        '''
        Un Classifier se compone de
        '''
        self.regions = []
        self.__dimension = d
        self.__num_groups = k
        self.__class1 = c1
        self.__class0 = c0
        self.__tag0 = t0
        self.__tag1 = t1
        self.__displace_sample = createDisplaceSample(SampleContainer(self.__class0.getSamples().union(self.__class1.getSamples()),d), self.__dimension)

    def train(self,createClustersMethod=createClusters):

        print("desplazando muestras...")
        displaced_class0 = displace(self.__class0, self.__displace_sample)
        displaced_class1 = displace(self.__class1, self.__displace_sample)

        print("clustering...")
        clusters0 = createClustersMethod(displaced_class0,displaced_class1)
        clusters1 = createClustersMethod(displaced_class1,displaced_class0)
        print("cluster0")
        displayClusterContainer(clusters0)
        print(map(lambda c: c.getSize(), clusters0.getClusters()))
        print("cluster1")
        displayClusterContainer(clusters1)
        print(map(lambda c: c.getSize(), clusters1.getClusters()))

        print("grouping...")
        (groups,clusters) = createGroups(clusters0,clusters1,self.__num_groups)
        print("regionalizing...")
        regions = createRegions(groups, clusters)
        self.regions = regions

    def classify(self, sample):
        sample = sampleSum(sample, self.__displace_sample, self.__dimension)
        for r in self.regions:
            if r.contains(sample):
                return self.__tag1
        return self.__tag0

    def export(self, route,d):
        f = open(route,"w")
        THREE_ITEMS_FORMAT = "%s,%s,%s\n"
        for r in self.regions:
            hiperplanes = r.getHyperplanes()
            for h in hiperplanes:
                data = map(lambda index: h.getCoefficient(index), range(0,d))
                data.append(h.getIntercept())
                f.write(THREE_ITEMS_FORMAT % tuple(data))
        f.close()

    def exportRegion(self,route,d,region):
        f = open(route,"w")
        THREE_ITEMS_FORMAT = "%s,%s,%s\n"

        for h in region.getHyperplanes():
            data = map(lambda index: h.getCoefficient(index), range(0,d))
            data.append(h.getIntercept())
            f.write(THREE_ITEMS_FORMAT % tuple(data))
        f.close()

    def getDisplaceSample(self):
        return self.__displace_sample

    """Ariel: mover esto a otro lado"""
    def __rowConfuseMatrix(self, clasifier, sample, color):
        r1, r2 = 0, 0
        for i in sample:
            if(clasifier.classify(Sample(i)).__eq__(color)):  r1+=1
            else: r2+=1
        return r1, r2

    def generateConfuseMatrix(self, clasifier, sampleC0, sampleC1, t0, t1):
        TP, FP = self.__rowConfuseMatrix(clasifier, sampleC0, t0)
        TN, FN = self.__rowConfuseMatrix(clasifier, sampleC1, t1)
        return float(TP), float(FP), float(TN), float(FN)
    """----------------------------------------------------------------------"""

def displayClusterContainer(c):
    print("_Clusters")
    for cls in c.getClusters():
        print(map(lambda s: s.getData(), cls.getSamples()))

def createDisplaceSample(samples,d):

    def minValuesSample(a,b):
        s = []
        for f in range(0,d):
            if a.getFeature(f) > b.getFeature(f):
                s.append(b.getFeature(f))
            else:
                s.append(a.getFeature(f))
        return tuple(s)

    minValues = reduce(lambda a,b: Sample(minValuesSample(a, b)), samples.getSamples())
    return Sample(tuple(map(lambda n: abs(minValues.getFeature(n)), range(d))))

def sampleSum(s1,s2,d):
        return Sample(tuple(map(lambda i:s1.getFeature(i) + s2.getFeature(i) , range(d))))
def displace(samples, scrollSample):
    d = samples.getDimension()
    return SampleContainer(map(lambda spl: sampleSum(spl,scrollSample,d) , samples.getSamples()),d)


import pickle
import sys

def fn():
    global first_name
    first_name = input('First Name: ')
    while first_name == '':
        print('Please enter a first name.')
        first_name = input('First Name: ')

def ln():
    global last_name
    last_name = input('Last Name: ')
    while last_name == '':
        print('Please enter a last name.')
        last_name = input('Last Name: ')

def gender_func():
    global gender
    gender = input('Gender: (M or F): ')
    gender_list = ['M','F','m','f']
    while gender not in gender_list:
        print('Please enter a valid gender.')
        gender = input('Gender: (M or F): ')
    else:
        if gender == gender_list[2]:
            gender = 'M'
        elif gender == gender_list[3]:
            gender = 'F'

def age_func():
    try:
        global age
        age = input('Age: (19 to 40): ')
        num_age = int(age)
        while num_age < 19 or num_age > 40 or age == '':
            print('Please enter an age from 19 to 40.')
            age = input('Age: (19 to 40): ')
    except ValueError:
        print('Please enter a number.')
        age_func()

##def m_bday():
##
##                                            global month_bday
##                                            month_bday = input('Month of Birth: (01 to 12) ')
##                                            num_month_bday = int(month_bday)
##                                            long_months = ['01','03','05','07','08','10','12']
##                                            short_months = ['04','06','09','11']
##                                            febuary = '02'
##                                            while num_month_bday > 1 or num_month_bday < 12:
##                                                    if month_bday in long_months:
##                                                            global limit
##                                                            limit = '31'
##                                                    elif month_bday in short_months:
##                                                            limit = '30'
##                                                    elif month_bday == febuary:
##                                                            limit ='28'
##                                            num_month_bday = int(month_bday)
##                                            while num_month_bday < 1 or num_month_bday > 12:
##                                                print('Please enter a valid month.')
##                                                month_bday = input('Month of Birth: (1 to 12) ')
##                                                num_month_bday = int(month_bday)
##
##def d_bday():
##                                                    global day_bday
##                                                    day_bday = input('Day of Birth: (1 to '+limit+') ')
##                                                    num_day_bday = int(day_bday)
##                                                    while  num_day_bday < 1 or num_day_bday > int(limit):
##                                                        print('Please enter a valid day of birth.')
##                                                        day_bday = input('Day of Birth: (1 to '+limit+') ')
##                                                        num_day_bday = int(day_bday)
##
def class_func():
    global char_class
    char_class_list = ['Fighter', 'Wizard','Rogue', 'Explorer', 'Scholar']
    char_class = input('Class: (Fighter, Wizard, Rogue, Explorer, Scholar) ')
    while char_class not in char_class_list:
        print('Please enter a valid class.')
        char_class = input('Class: (Fighter, Wizard, Rogue, Explorer, Scholar) ')
def confirm():
    print('')
    print('Your character: ')
    print('Name: '+first_name+' '+last_name+'')
    print('Gender: '+gender+'')
    print('Age: '+age+'')
    ##print('Birthday: '+month_bday+'/'+day_bday+'')

    confirm_character_creation = input('Is this character ok? (1.Yes or 2. No) ')
    if confirm_character_creation == '2':
        wrong = input('What''s wrong? (1.First Name, 2.Last Name, 3.Gender, 4.Age, 5.Nothing) ')
        if wrong == '1':
            fn()
            confirm()
        elif wrong == '2':
            ln()
            confirm()
        elif  wrong == '3':
            gender_func()
            confirm()
        elif wrong == '4':
            age_func()
            confirm()
        elif wrong == '5':
            confirm()
        while wrong not in ['1','2','3','4','5']:
            print('Please enter a valid answer.')

    if confirm_character_creation == '1':
        character = [first_name, last_name, gender, age]
        save = open('savefile.pkl','wb')
        pickle.dump(character, save)
        save.close()