import copy
import torch
import numpy as np
from torch.optim import Adam
from torch.optim.lr_scheduler import CosineAnnealingLR
from torch.nn.functional import smooth_l1_loss
from all import nn
from all.approximation import QNetwork, FixedTarget
from all.agents import Agent, DQN, DQNTestAgent
from all.bodies import DeepmindAtariBody
from all.logging import DummyLogger
from all.memory import ExperienceReplayBuffer
from all.optim import LinearScheduler
from all.policies import GreedyPolicy
from all.presets.builder import PresetBuilder
from all.presets.preset import Preset
from all.presets.atari.models import nature_dqn

default_hyperparameters = {
    # Common settings
    "discount_factor": 0.99,
    # Adam optimizer settings
    "lr": 1e-4,
    "eps": 1.5e-4,
    # Training settings
    "minibatch_size": 32,
    "update_frequency": 4,
    "target_update_frequency": 1000,
    # Replay buffer settings
    "replay_start_size": 80000,
    "replay_buffer_size": 1000000,
    # Explicit exploration
    "initial_exploration": 1.,
    "final_exploration": 0.01,
    "final_exploration_step": 250000,
    "test_exploration": 0.001,
    # Model construction
    "model_constructor": nature_dqn
}

class DQNAtariPreset(Preset):
    """
    Deep Q-Network (DQN) Atari Preset.

    Args:
        env (all.environments.AtariEnvironment): The environment for which to construct the agent.
        name (str): A human-readable name for the preset.
        device (torch.device): The device on which to load the agent.

    Keyword Args:
        discount_factor (float, optional): Discount factor for future rewards.
        lr (float): Learning rate for the Adam optimizer.
        eps (float): Stability parameters for the Adam optimizer.
        minibatch_size (int): Number of experiences to sample in each training update.
        update_frequency (int): Number of timesteps per training update.
        target_update_frequency (int): Number of timesteps between updates the target network.
        replay_start_size (int): Number of experiences in replay buffer when training begins.
        replay_buffer_size (int): Maximum number of experiences to store in the replay buffer.
        initial_exploration (float): Initial probability of choosing a random action,
            decayed over course of training.
        final_exploration (float): Final probability of choosing a random action.
        final_exploration_step (int): The step at which exploration decay is finished
        test_exploration (float): The exploration rate of the test Agent
        model_constructor (function): The function used to construct the neural model.
    """

    def __init__(self, env, name, device, **hyperparameters):
        super().__init__(name, device, hyperparameters)
        hyperparameters = {**default_hyperparameters, **hyperparameters}
        self.model = hyperparameters['model_constructor'](env).to(device)
        self.n_actions = env.action_space.n

    def agent(self, logger=DummyLogger(), train_steps=float('inf')):
        n_updates = (train_steps - self.hyperparameters['replay_start_size']) / self.hyperparameters['update_frequency']

        optimizer = Adam(
            self.model.parameters(),
            lr=self.hyperparameters['lr'],
            eps=self.hyperparameters['eps']
        )

        q = QNetwork(
            self.model,
            optimizer,
            scheduler=CosineAnnealingLR(optimizer, n_updates),
            target=FixedTarget(self.hyperparameters['target_update_frequency']),
            logger=logger
        )

        policy = GreedyPolicy(
            q,
            self.n_actions,
            epsilon=LinearScheduler(
                self.hyperparameters['initial_exploration'],
                self.hyperparameters['final_exploration'],
                self.hyperparameters['replay_start_size'],
                self.hyperparameters['final_exploration_step'] - self.hyperparameters['replay_start_size'],
                name="exploration",
                logger=logger
            )
        )

        replay_buffer = ExperienceReplayBuffer(
            self.hyperparameters['replay_buffer_size'],
            device=self.device
        )

        return DeepmindAtariBody(
            DQN(
                q,
                policy,
                replay_buffer,
                discount_factor=self.hyperparameters['discount_factor'],
                loss=smooth_l1_loss,
                minibatch_size=self.hyperparameters['minibatch_size'],
                replay_start_size=self.hyperparameters['replay_start_size'],
                update_frequency=self.hyperparameters['update_frequency'],
            ),
            lazy_frames=True
        )

    def test_agent(self):
        q = QNetwork(copy.deepcopy(self.model))
        policy = GreedyPolicy(
            q,
            self.n_actions,
            epsilon=self.hyperparameters['test_exploration']
        )
        return DeepmindAtariBody(DQNTestAgent(policy))

dqn = PresetBuilder('dqn', default_hyperparameters, DQNAtariPreset)


import cv2
import numpy as np
from matplotlib import pyplot as plt

orig = cv2.imread("lenna.jpg", cv2.IMREAD_GRAYSCALE)

hist_equal = cv2.equalizeHist(orig)

# numpy does elementwise scalar operation on the image matrix
whitened_img = (orig - np.mean(orig)) / np.std(orig)

fig = plt.figure()

images = [orig, whitened_img, hist_equal]
titles = ["Original", "Whitened", "Histogram equalization"]
pos = 1

# display image and the corresponding historgram
for i in range(len(images)):
    ax = fig.add_subplot(3, 2, pos)
    ax.set_title(titles[i])
    # uncomment to see the output like in cv2.imshow()
    # if (images[i] == whitened_img).all():
    #     ax.imshow(images[i], cmap="gray", vmax=1, vmin=0)
    # else:
    #     ax.imshow(images[i], cmap="gray")
    ax.imshow(images[i], cmap="gray")
    plt.xticks([])
    plt.yticks([])
    pos += 1
    ax = fig.add_subplot(3, 2, pos)
    # round to 2 decimal places
    mean = round(np.mean(images[i]), 2)
    std = round(np.std(images[i]), 2)
    hist_title = "Mean:" + str(mean) + "  Std:" + str(std)
    ax.set_title(hist_title)
    ax.hist(images[i].ravel(), 256, [0, 256])
    pos += 1
    plt.xticks([])
    plt.yticks([])

plt.show()


from datetime import datetime
from pymongo import MongoClient
from typing import Dict, List

from PandlolCollection.Objects.LOLObject import LOLObject
from PandlolCollection.building import BUILDING_LIST

class BaseEvent:
    """
    Фабрика событий матча
    """
    def __init__(self, connection: MongoClient):
        self.connection = connection

    @staticmethod
    def base_record(
            participant_list: Dict,
            timestamp: int,
            event_type: str,
            participant_code: int = 0,
            team_code: int = None
    ) -> Dict:
        """
        Функция записи базовых параметров события
        :param participant_list: Список участников матча
        :param timestamp: Время события
        :param event_type: Тип события
        :param participant_code: Код участника матча
        :param team_code: Код команды, если нет конкретного участника
        :return Количество заполненных полей
        """
        if participant_code > 0:
            record = {
                "match_id": participant_list[participant_code]["match_id"],
                "patch": participant_list[participant_code]["patch"],
                "queue": participant_list[participant_code]["queue"],
                "platform": participant_list[participant_code]["platform"],
                "tier": participant_list[participant_code]["tier"],
                "division": participant_list[participant_code]["division"],
                "team_code": participant_list[participant_code]["team_code"],
                "participant_code": participant_code,
                "puu_id": participant_list[participant_code]["puu_id"],
                "champion_name": participant_list[participant_code]["champion_name"],
                "event_type": event_type,
                "timestamp": round(timestamp / 1000)
            }
        else:
            record = {
                "match_id": participant_list[1]["match_id"],
                "patch": participant_list[1]["patch"],
                "queue": participant_list[1]["queue"],
                "platform": participant_list[1]["platform"],
                "team_code": team_code,
                "event_type": event_type,
                "timestamp": round(timestamp / 1000)
            }

        return record

    def write(self, event_list: List, participant_list: Dict):
        # выберем отдельно пометки убийств
        special_kill_list = []
        for event in event_list:
            if event["type"] == "CHAMPION_SPECIAL_KILL":
                special_kill_list.append(event)

        for event in event_list:
            # Начало и окончание игры
            if event["type"] in ["PAUSE_END", "GAME_END"]:
                record = {
                    "match_id": participant_list[1]["match_id"],
                    "patch": participant_list[1]["patch"],
                    "queue": participant_list[1]["queue"],
                    "platform": participant_list[1]["platform"]
                }
                new_event = EventBeginEnd(connection=self.connection, record=record)
                new_event.write(event, participant_list)

            elif event["type"] == "LEVEL_UP":
                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("participantId", 0)
                )
                new_event = EventLevel(connection=self.connection, record=record)
                new_event.write(event)

            elif event["type"] == "SKILL_LEVEL_UP":
                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("participantId", 0)
                )
                new_event = EventSkill(connection=self.connection, record=record)
                new_event.write(event)

            elif event["type"] in ["ITEM_PURCHASED", "ITEM_DESTROYED", "ITEM_UNDO", "ITEM_SOLD"]:
                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("participantId", 0)
                )
                new_event = EventItem(connection=self.connection, record=record)
                new_event.write(event)

            elif event["type"] == "WARD_PLACED":
                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("creatorId", 0)
                )
                new_event = EventWard(connection=self.connection, record=record)
                new_event.write(event)

            elif event["type"] == "WARD_KILL":
                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("killerId", 0)
                )
                new_event = EventWard(connection=self.connection, record=record)
                new_event.write(event)

            elif event["type"] in ["TURRET_PLATE_DESTROYED", "BUILDING_KILL"]:
                if event.get("teamId", 0) == 100:
                    team_code = 200
                elif event.get("teamId", 0) == 200:
                    team_code = 100
                else:
                    team_code = None

                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("killerId", 0),
                    team_code=team_code
                )
                new_event = EventBuilding(connection=self.connection, record=record)
                new_event.write(event)

                for participant in event.get("assistingParticipantIds", []):
                    event_type = "BUILDING_ASSIST"
                    if event["type"] == "TURRET_PLATE_DESTROYED":
                        event_type = "TURRET_PLATE_ASSIST"

                    record = self.base_record(
                        participant_list,
                        event["timestamp"],
                        event_type=event_type,
                        participant_code=participant,
                        team_code=team_code
                    )
                    new_event = EventBuilding(connection=self.connection, record=record)
                    new_event.write(event)

            elif event["type"] == "ELITE_MONSTER_KILL":
                if event.get("killerId", 0) == 0:
                    team_code = event.get("killerTeamId", 0)
                else:
                    team_code = None

                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    participant_code=event.get("killerId", 0),
                    team_code=team_code
                )
                new_event = EventMonster(connection=self.connection, record=record)
                new_event.write(event)

                for participant in event.get("assistingParticipantIds", []):
                    event_type = "ELITE_MONSTER_ASSIST"

                    record = self.base_record(
                        participant_list,
                        event["timestamp"],
                        event_type=event_type,
                        participant_code=participant
                    )
                    new_event = EventMonster(connection=self.connection, record=record)
                    new_event.write(event)

            elif event["type"] == "DRAGON_SOUL_GIVEN":
                record = self.base_record(
                    participant_list,
                    event["timestamp"],
                    event_type=event["type"],
                    team_code=event.get("teamId")
                )
                new_event = EventDragonSoul(connection=self.connection, record=record)
                new_event.write(event)

            elif event["type"] == "CHAMPION_KILL":
                if event.get("killerId", 0) > 0:
                    # запишем убийство
                    record = self.base_record(
                        participant_list,
                        event["timestamp"],
                        event_type=event["type"],
                        participant_code=event.get("killerId", 0)
                    )
                    kill_event = EventChampion(connection=self.connection, record=record)
                    kill_event.write_kill(event, special_kill_list)

                    # запишем смерть
                    record = self.base_record(
                        participant_list,
                        event["timestamp"],
                        event_type="CHAMPION_DEATH",
                        participant_code=event.get("victimId", 0)
                    )
                    kill_event = EventChampion(connection=self.connection, record=record)
                    kill_event.write_death(event)

                    # запишем содействия
                    for participant in event.get("assistingParticipantIds", []):
                        record = self.base_record(
                            participant_list,
                            event["timestamp"],
                            event_type="CHAMPION_ASSIST",
                            participant_code=participant
                        )
                        assist_event = EventChampion(connection=self.connection, record=record)
                        assist_event.write_assist(event)

class EventBeginEnd(LOLObject):
    """
    Событие начала - окончания матча
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_begin_end",
            find_field=['match_id'],
            update_field=['end_time', 'duration', 'team_win', 'surr', 'early_surr']
        )

    @property
    def begin_time(self):
        return self._record["begin_time"]

    @begin_time.setter
    def begin_time(self, value):
        self._record["begin_time"] = value

    @property
    def end_time(self):
        return self._record["end_time"]

    @end_time.setter
    def end_time(self, value):
        self._record["end_time"] = value

    @property
    def duration(self) -> int:
        return self._record["duration"]

    @duration.setter
    def duration(self, value: int):
        self._record["duration"] = value

    @property
    def team_win(self) -> int:
        return self._record["team_win"]

    @team_win.setter
    def team_win(self, value: int):
        self._record["team_win"] = value

    @property
    def surr(self) -> bool:
        return self._record["surr"]

    @surr.setter
    def surr(self, value: bool):
        self._record["surr"] = value

    @property
    def early_surr(self) -> bool:
        return self._record["early_surr"]

    @early_surr.setter
    def early_surr(self, value: bool):
        self._record["early_surr"] = value

    def write(self, event: Dict, participant_list: Dict):
        if event["type"] == "PAUSE_END":
            self.begin_time = datetime.fromtimestamp(event.get("realTimestamp", 0) / 1000)
            self.insert()

        if event["type"] == "GAME_END":
            self.end_time = datetime.fromtimestamp(event.get("realTimestamp", 0) / 1000)
            self.duration = round(event["timestamp"] / 1000)
            self.team_win = event.get("winningTeam", 0)

            self.surr = False
            self.early_surr = False

            for participant_code in range(1, 10):
                if participant_list[participant_code]["surr"] and not self.surr:
                    self.surr = True

                if participant_list[participant_code]["early_surr"] and not self.early_surr:
                    self.early_surr = True

            self.update()

class EventLevel(LOLObject):
    """
    Прокачка уровня чемпиона
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_level"
        )

    @property
    def level(self) -> int:
        return self._record["level"]

    @level.setter
    def level(self, value: int):
        self._record["level"] = value

    def write(self, event):
        self.level = event.get("level", 0)
        self.insert()

class EventSkill(LOLObject):
    """
    Прокачка скиллов
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_skill"
        )

    @property
    def skill_code(self) -> int:
        return self._record["skill_code"]

    @skill_code.setter
    def skill_code(self, value: int):
        self._record["skill_code"] = value

    def write(self, event):
        self.skill_code = event.get("skillSlot", 0)
        self.insert()

class EventItem(LOLObject):
    """
    Действие с предметом
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_item"
        )

    @property
    def item_id(self) -> int:
        return self._record["item_id"]

    @item_id.setter
    def item_id(self, value: int):
        self._record["item_id"] = value

    def write(self, event):
        if event["type"] == "ITEM_UNDO":
            self.item_id = event.get("beforeId", 0)
        else:
            self.item_id = event.get("itemId", 0)
        self.insert()

class EventWard(LOLObject):
    """
    Установка или уничтожение варда
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_ward"
        )

    @property
    def ward_type(self) -> str:
        return self._record["ward_type"]

    @ward_type.setter
    def ward_type(self, value: str):
        self._record["ward_type"] = value

    def write(self, event):
        self.ward_type = event.get("wardType")
        self.insert()

class EventBuilding(LOLObject):
    """
    Разрушение объекта
    """
    def __init__(
            self,
            connection: MongoClient,
            record: Dict
    ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_building"
        )

    @property
    def lane(self) -> str:
        return self._record["lane"]

    @lane.setter
    def lane(self, value: str):
        self._record["lane"] = value

    @property
    def building_type(self) -> str:
        return self._record["building_type"]

    @building_type.setter
    def building_type(self, value: str):
        self._record["building_type"] = value

    @property
    def turret_type(self) -> str:
        return self._record["turret_type"]

    @turret_type.setter
    def turret_type(self, value: str):
        self._record["turret_type"] = value

    def write(self, event):
        for building in BUILDING_LIST:
            if building["position"] == event.get("position", {}):
                self.lane = building["lane"]
                self.building_type = building["building_type"]
                self.turret_type = building["turret_type"]

        self.insert()

class EventMonster(LOLObject):
    """
    Убийство монстра
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_monster"
        )

    @property
    def monster_type(self) -> str:
        return self._record["monster_type"]

    @monster_type.setter
    def monster_type(self, value: str):
        self._record["monster_type"] = value

    @property
    def monster_sub_type(self) -> str:
        return self._record["monster_sub_type"]

    @monster_sub_type.setter
    def monster_sub_type(self, value: str):
        self._record["monster_sub_type"] = value

    @property
    def position(self):
        return self._record["position"]

    @position.setter
    def position(self, value: str):
        self._record["position"] = value

    def write(self, event):
        self.monster_type = event.get("monsterType")
        self.monster_sub_type = event.get("monsterSubType")
        self.position = event.get("position", None)
        self.insert()

class EventDragonSoul(LOLObject):
    """
    Получение души дракона
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_dragon_soul",
            find_field=["match_id"]
        )

    @property
    def soul_type(self) -> str:
        return self._record["soul_type"]

    @soul_type.setter
    def soul_type(self, value: str):
        self._record["soul_type"] = value

    def write(self, event):
        self.soul_type = event.get("name")
        res = self.read_one()
        if res["status"] == 'OK':
            if res['result'] is None:
                self.insert()

class EventChampion(LOLObject):
    """
    Убийство чемпиона
    """
    def __init__(self,
                 connection: MongoClient,
                 record: Dict
                 ):
        super().__init__(
            connection=connection,
            record=record,
            table_name="event_champion"
        )

    @property
    def participant_event(self) -> int:
        return self._record["participant_event"]

    @participant_event.setter
    def participant_event(self, value: int):
        self._record["participant_event"] = value

    @property
    def gold_bounty(self) -> int:
        return self._record["gold_bounty"]

    @gold_bounty.setter
    def gold_bounty(self, value: int):
        self._record["gold_bounty"] = value

    @property
    def kill_streak(self) -> int:
        return self._record["kill_streak"]

    @kill_streak.setter
    def kill_streak(self, value: int):
        self._record["kill_streak"] = value

    @property
    def position(self):
        return self._record["position"]

    @position.setter
    def position(self, value):
        self._record["position"] = value

    @property
    def first_blood(self) -> bool:
        return self._record["first_blood"]

    @first_blood.setter
    def first_blood(self, value: bool):
        self._record["first_blood"] = value

    @property
    def ace(self) -> bool:
        return self._record["ace"]

    @ace.setter
    def ace(self, value: bool):
        self._record["ace"] = value

    @property
    def multikill(self) -> int:
        return self._record["multikill"]

    @multikill.setter
    def multikill(self, value: int):
        self._record["multikill"] = value

    def write_kill(self, event, special_event_list):
        self.participant_event = event.get("victimId")
        self.gold_bounty = event.get("bounty", 0)
        self.kill_streak = event.get("killStreakLength", 0)
        self.position = event.get("position", None)

        for kill in special_event_list:
            if kill["timestamp"] == event["timestamp"] and kill["killerId"] == event["killerId"]:
                if kill["killType"] == "KILL_FIRST_BLOOD":
                    self.first_blood = True
                if kill["killType"] == "KILL_MULTI":
                    self.multikill = kill["multiKillLength"]
                if kill["killType"] == "KILL_ACE":
                    self.ace = True
        self.insert()

    def write_death(self, event):
        self.participant_event = event.get("killerId", 0)
        self.position = event.get("position", None)
        self.insert()

    def write_assist(self, event):
        self.participant_event = event.get("victimId", 0)
        self.position = event.get("position", None)
        self.insert()


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

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('app', '0003_auto_20150317_0917'),
    ]

    operations = [
        migrations.CreateModel(
            name='Recipe',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('pub_date', models.DateTimeField(auto_now_add=True, verbose_name=b'Date Published')),
                ('title', models.CharField(max_length=200)),
                ('instructions', models.TextField()),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='RecipeIngredient',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('ingredient', models.CharField(max_length=255)),
                ('recipe', models.ForeignKey(related_name='ingredients', to='app.Recipe')),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.AlterIndexTogether(
            name='customer',
            index_together=None,
        ),
        migrations.RemoveField(
            model_name='customer',
            name='country',
        ),
        migrations.DeleteModel(
            name='Customer',
        ),
        migrations.AlterIndexTogether(
            name='recipient',
            index_together=None,
        ),
        migrations.RemoveField(
            model_name='recipient',
            name='country',
        ),
        migrations.DeleteModel(
            name='CountryCodes',
        ),
        migrations.DeleteModel(
            name='Recipient',
        ),
    ]


"""empty message

Revision ID: e731b2aa2436
Revises: f0e77116e401
Create Date: 2022-03-30 22:20:34.244379

"""
import geoalchemy2  # noqa
from alembic import op
import sqlalchemy as sa  # noqa

# revision identifiers, used by Alembic.
revision = "e731b2aa2436"
down_revision = "f0e77116e401"
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column(
        "activity",
        sa.Column("activity_unique_id", sa.String(), nullable=True),
        schema="vision_sources",
    )
    op.create_unique_constraint(
        None, "activity", ["activity_id"], schema="vision_sources"
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_constraint(
        None, "activity", schema="vision_sources", type_="unique"
    )
    op.drop_column("activity", "activity_unique_id", schema="vision_sources")
    # ### end Alembic commands ###


import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing

def z_1():
    a = int(input('Введите число: '))
    b = a
    c = 0 + abs(a ** 2)

    while b != 0:
        a = int(input('Введите следующее число: '))
        b = b + a
        print('Сумма ваших чисел: %d' % b)
        c = 0 + abs(a) ** 2
        if b == 0:
            break
    print('Квадрат всех считанных чисел: ', c)

def z_2():
    list, n = [], int(input('Введите число: '))
    for i in range(n):
        count = 0
        if n == 1:
            print(n)
            break
        while count < i + 1:
            list.append(i + 1)
            count += 1
            if len(list) == n:
                print(*list)
                break

def z_3():
    columns = int(input('Введите количество столбцов матрицы: '))
    rows = int(input('Введите количество строк матрицы: '))
    RC = columns * rows

    A = np.arange(RC).reshape(rows, columns)
    B = []

    for i in range(rows):
        for j in range(columns):
            B.append(A[i, j])

    print('Исходная матрица\n', A)
    print('Результат\n', B)

def z_4():
    A = [1, 2, 3, 4, 2, 1, 3, 4, 5, 6, 5, 4, 3, 2]
    B = ['a', 'b', 'c', 'c', 'c', 'b', 'a', 'c', 'a', 'a', 'b', 'c', 'b', 'a']
    T1 = {}

    for i in range(len(A)):
        if i > 3:
            C = T1.get(B[i]) + A[i]
            T1.update([(B[i], C)])
        else:
            T1.update([(B[i], A[i])])
    print(T1)

def z_5_11():
    data = fetch_california_housing(as_frame=True)
    print("---TYPE---\n", type(data))
    print("---KEYS---\n", data.keys())
    print("---DATA---\n", data.data)
    print("---CONCAT---\n", pd.concat([data["data"], data['target']], axis=1))
    print("---INFO---")
    data["data"].info()
    print("---ISNA.SUM---\n", data.data.isna().sum())
    print("---LOC---\n", data.data.loc[(data.data.HouseAge > 50) & (data.data.Population > 2500)])
    print("---MEDINC.MAX---\n", data.data.MedInc.max)
    print("---MEDINC.MIN---\n", data.data.MedInc.min)
    print("---APPLY---\n", data.data.apply(np.mean, axis=0))

if __name__ == '__main__':
    z = int(input('Выберите задание: '))
    if z == 1:
        z_1()
    elif z == 2:
        z_2()
    elif z == 3:
        z_3()
    elif z == 4:
        z_4()
    elif z == 5 or z == 6 or z == 7 or z == 8 or z == 9 or z == 10 or z==11:
        z_5_11()


import itertools
import random

from mimesis import Address
from mimesis import Development

from ..util import OrgTree
from .base import BaseGenerator

class OrgTreeGenerator(BaseGenerator):
    def __init__(self) -> None:
        super().__init__()
        self.address_gen = Address("da")
        self.development_gen = Development()

    def generate(self, size: int) -> OrgTree:
        print("Generating organisation tree")

        return {
            "Borgmesterens Afdeling": {
                "Budget og Planlægning": {},
                "HR og organisation": {},
                "Erhverv": {},
                "Byudvikling": {},
                "IT-Support": {},
            },
            "Teknik og Miljø": {
                "Kloakering": self.generate_cantina(),
                "Park og vej": self.generate_cantina(),
                "Renovation": self.generate_cantina(),
                "Belysning": self.generate_cantina(),
                "IT-Support": self.generate_cantina(),
            },
            "Skole og Børn": {
                "Social Indsats": {
                    "Skoler og børnehaver": self.gen_schools_and_childcare(
                        num_schools=size * 6,
                        num_childcare=size * 4,
                    ),
                },
                "IT-Support": self.generate_cantina(),
            },
            "Social og sundhed": {},
        }

    def gen_schools_and_childcare(
        self, num_schools: int, num_childcare: int
    ) -> OrgTree:
        def gen_city() -> str:
            # The number of cities in the mimesis library is way too small, so we need
            # to append a random postal code to ensure that we don't overwrite the same
            # name in the output org tree dictionary over and over, limiting the size.
            return f"{self.address_gen.postal_code()} - {self.address_gen.city()}"

        def generate_school() -> tuple[str, OrgTree]:
            name = f"{gen_city()} skole"
            school: dict[str, dict] = {}
            if random.random() > 0.5:
                school["Administration"] = {}
            school["Teknisk Support"] = {
                f"Teknisk support for {self.development_gen.os()}": {}
                for _ in range(int(random.gammavariate(alpha=2, beta=1)))
            }
            return name, school

        def generate_childcare() -> tuple[str, OrgTree]:
            name = f"{gen_city()} børnehave"
            return name, {}

        schools = (generate_school() for _ in range(num_schools))
        childcares = (generate_childcare() for _ in range(num_childcare))
        return dict(itertools.chain(schools, childcares))

    @staticmethod
    def generate_cantina() -> OrgTree:
        if random.random() > 0.5:
            return {"Kantine": {}}
        return {}


import os
import csv
import re

from collections import defaultdict

def a1_to_rowcol(a1):
    m = re.compile(r"([A-Za-z]+)([1-9]\d*)").match(a1)
    if m:
        column_label = m.group(1).upper()
        ridx = int(m.group(2))
        cidx = 0
        for i, c in enumerate(reversed(column_label)):
            cidx += (ord(c) - 64) * (26 ** i)
        return ridx, cidx
    return None

def render_html(headers, rows, messages):
    html = '

'
    for h in headers:
        html += f"\n{h}	"
    html += "\n

"
    row_idx = 1
    for row in rows:
        html += "
"
        row_idx += 1
        col_idx = 0
        for h in headers:
            col_idx += 1
            itm = row[h]
            msg = messages.get(col_idx, {}).get(row_idx, None)
            if not msg:
                html += f"\n{itm}	"
                continue

            rule_id = msg.get("rule ID", "")
            rule_text = msg.get("rule", "")
            rule_message = msg.get("message", "")
            suggest = msg.get("suggestion", "")
            level = msg.get("level", "error").lower()

            if level == "error":
                td_class = "table-danger"
            elif level == "warn":
                td_class = "table-warning"
            else:
                td_class = "table-info"

            full_msg = ""
            if rule_id and rule_text:
                full_msg += f"{rule_id}: {rule_text}"
            elif rule_id:
                full_msg += rule_id
            elif rule_text:
                full_msg += rule_text

            if rule_message and full_msg != "":
                full_msg += f"
{rule_message}"
            elif rule_message:
                full_msg += rule_message

            if suggest and full_msg != "":
                full_msg += f"
Suggestion: '{suggest}'"
            elif suggest:
                full_msg += f"Suggestion: '{suggest}'"

            if full_msg:
                html += f'\n{itm}	'
            else:
                html += f'\n{itm}	'
        html += "\n
"
    html += "\n

"
    return html

def tsv2html(path, messages):
    table_name = os.path.splitext(path)[0]
    table_messages = defaultdict(dict)
    for row in messages:
        table = row["table"]
        loc = row["cell"]
        row_idx, col_idx = a1_to_rowcol(loc)
        if col_idx not in table_messages:
            table_messages[col_idx] = dict()
        table_messages[col_idx].update(
            {
                row_idx: {
                    "level": row.get("level", "error"),
                    "rule ID": row.get("rule ID"),
                    "rule": row.get("rule"),
                    "message": row.get("message"),
                    "suggestion": row.get("suggestion"),
                }
            }
        )
    rows = []
    with open(path, "r") as f:
        reader = csv.DictReader(f, delimiter="\t")
        headers = reader.fieldnames
        for row in reader:
            rows.append(row)
    return render_html(headers, rows, table_messages)


# project/server/user/views.py

from flask import Blueprint, abort, render_template

from project.server.models import Person

user_blueprint = Blueprint("user", __name__)

@user_blueprint.route("/rec<rec_id>", methods=["GET"])
def ledger(rec_id=None):
    # Home page is a 404
    if rec_id is None:
        abort(404)

    rec_id = "rec" + rec_id
    player = Person.query.filter_by(at_id=rec_id).first()

    # No matching player is a 404
    if not player:
        abort(404)

    ledger = player.ledger()
    ledger.reverse()
    balance = player.balance()

    return render_template(
        "user/ledger.html",
        player=player.name,
        balance=balance,
        ledger=ledger,
    )


"""
  TwrBinTraceReader format:   unix_ts(uint32), obj_id(uint64), key-size(uint16), value-size(uint32), client(uint16),
  op(uint16 1:get, 2:gets, 3:set, 5:add, 6: replace, 7: append, 8: prepend, 9: cas, 10: delete, 11:incr, 12:decr),
  namespace(uint64), ttl(uint32)
  trace_long_format_struct_str = "<IQHIHHQI"

  TwrShortBinReader format:
    real_time, obj_id, key and value size (first 12 bits key size, last 20 bits value size), op and ttl (first 8 bit op, last 24 bit ttl, ttl_max=8000000)
    trace_short_format_struct_str = "<IQII"

  Jason <peter.waynechina@gmail.com>
"""

import os, sys
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../"))
import struct
import collections
from core.req import Req
from core.traceReader import TraceReader

class TwrBinTraceReader(TraceReader):
  def __init__(self, trace_path, *args, **kwargs):
    TraceReader.__init__(self, trace_path, "binary", real_time_field=1, obj_id_field=2, key_size_field=3, value_size_field=4,
      op_field=6, ttl_field=8, **kwargs)
    self.struct = struct.Struct("<IQHIHHQI")
    self.struct_size = self.struct.size
    self.client_field = 5
    self.namespace_field = 7
    self.per_struct_size_overhead = 60
    # self.op_mapping = ("get", "gets", "set", "NA", "add", "replace", "append", "prepend", "cas", "delete", "incr", "decr")
    self.op_mapping = ("get", "gets", "set", "add", "cas", "replace", "append", "prepend", "delete", "incr", "decr")

  def read_one_req(self):
    TraceReader.read_one_req(self)
    bin_data = self.trace_file.read(self.struct_size)
    if not bin_data:
      return None
    item = self.struct.unpack(bin_data)
    key_size = int(item[self.key_size_field-1])
    value_size = int(item[self.value_size_field-1])
    obj_size = key_size + value_size
    if value_size == 0:
      obj_size = 0
    op = self.op_mapping[int(item[self.op_field-1])-1]
    ttl = int(item[self.ttl_field-1])
    if isinstance(self.req, tuple):
      req = Req(logical_time=self.n_read_req, real_time=int(item[self.real_time_field-1]),
                obj_id=int(item[self.obj_id_field-1]), op = op, ttl=ttl, key_size=key_size, value_size=value_size,
                obj_size=obj_size, req_size=obj_size, cnt=1)
      self.req = req
    else:
      self.req.logical_time, self.req.real_time = self.n_read_req, int(item[self.real_time_field-1])
      self.req.obj_id, self.req.op, self.req.ttl, self.req.cnt = int(item[self.obj_id_field-1]), op, ttl, 1
      self.req.key_size, self.req.value_size, self.req.obj_size, self.req.req_size = key_size, value_size, obj_size, obj_size
    return self.req

  def __len__(self):
    self.n_req = os.path.getsize(self.trace_path)//self.struct.size
    assert self.n_req * self.struct.size == os.path.getsize(self.trace_path), "trace file size is not mulitple of req struct size"
    return self.n_req

# this is only for /disk/traces/allJobOneTaskLong/ on pm1, a one-week temporal sampled data
class TwrShortBinTraceReaderOld(TraceReader):
  def __init__(self, trace_path, *args, **kwargs):
    TraceReader.__init__(self, trace_path, "binary", real_time_field=1, obj_id_field=2, obj_size_field=3)
    self.struct = struct.Struct("<IQII")
    self.struct_size = self.struct.size
    self.per_struct_size_overhead = 60
    self.op_mapping = ("get", "gets", "set", "add", "cas", "replace", "append", "prepend", "delete", "incr", "decr")
    self.op_ttl_field = 4

  def read_one_req(self):
    TraceReader.read_one_req(self)
    try:
    # if 1:
      bin_data = self.trace_file.read(self.struct_size)
      if not bin_data:
        return None
      item = self.struct.unpack(bin_data)
      real_time = int(item[self.real_time_field-1])
      obj_id = int(item[self.obj_id_field-1])
      obj_size = int(item[self.obj_size_field-1])
      op_ttl = int(item[self.op_ttl_field-1])
      op = op_ttl & (0x0100-1)
      ttl = op_ttl >> 8
      if op -1 > 10:
        print("op {}".format(op-1))
      op = self.op_mapping[op-1]

      req = Req(logical_time=self.n_read_req, real_time=real_time,
                obj_id=obj_id, op = op, ttl=ttl,
                obj_size=obj_size, req_size=obj_size)
    except Exception as e:
      print("TwrShortBinTraceReader err: {}".format(e))
      self.n_read_req -= 1
      return self.read_one_req()
    return req

class TwrShortBinTraceReader(TraceReader):
  def __init__(self, trace_path, *args, **kwargs):
    TraceReader.__init__(self, trace_path, "binary", real_time_field=1, obj_id_field=2, **kwargs)
    self.struct = struct.Struct("<IQII")
    self.struct_size = self.struct.size
    self.per_struct_size_overhead = 60
    self.op_mapping = ("get", "gets", "set", "add", "cas", "replace", "append", "prepend", "delete", "incr", "decr")
    self.kv_size_field = 3
    self.op_ttl_field = 4

  def read_one_req(self):
    # while True:
    TraceReader.read_one_req(self)
    bin_data = self.trace_file.read(self.struct_size)
    if not bin_data:
      return None
    item = self.struct.unpack(bin_data)
    real_time = int(item[self.real_time_field-1])
    obj_id = int(item[self.obj_id_field-1])
    # key and value size (first 12 bits is key size, last 20 bits is value size)
    kv_size = int(item[self.kv_size_field-1])
    key_size, value_size = (kv_size >> 22) & (0x00000400-1), kv_size & (0x00400000 - 1)
    obj_size = key_size + value_size
    if value_size == 0:
      obj_size = 0

    # op and ttl (first 8 bit op, last 24 bit ttl, ttl_max=8000000)
    op_ttl = int(item[self.op_ttl_field-1])
    op = (op_ttl >> 24) & (0x00000100-1)
    ttl = op_ttl & (0x01000000-1)
    op = self.op_mapping[op-1]

    if isinstance(self.req, tuple):
      req = Req(logical_time=self.n_read_req, real_time=real_time,
                obj_id=obj_id, op = op, ttl=ttl, key_size=key_size, value_size=value_size,
                obj_size=obj_size, req_size=obj_size, cnt=1)
      self.req = req
    else:
      self.req.logical_time, self.req.real_time = self.n_read_req, real_time
      self.req.obj_id, self.req.op, self.req.ttl, self.req.cnt = obj_id, op, ttl, 1
      self.req.key_size, self.req.value_size, self.req.obj_size, self.req.req_size = key_size, value_size, obj_size, obj_size
    return self.req

if __name__ == "__main__":
  from collections import defaultdict
  reader = TwrShortBinTraceReader("/Users/junchengy/Downloads/log-twemcache.cmd.bin")
  obj_cnt_dict = defaultdict(int)
  ttl_cnt_dict = defaultdict(int)
  for n, req in enumerate(reader):
    if n < 8:
      print(req)
    obj_cnt_dict[req.obj_id] += req.cnt
    ttl_cnt_dict[req.ttl] += 1
  print(sorted(obj_cnt_dict.items(), key=lambda x:-x[1])[:20])
  print(ttl_cnt_dict)


#!/usr/bin/env python

import json
import urllib.request
import re
from pyalpm import vercmp
from functools import cmp_to_key

github_repo = "yairm210/Unciv"
from_pattern = r'(.*)-patch(\d+)'
to_pattern = r'\1.\2'
prefix = ''

def custom_preproc(vers):
  # Sometimes, vers contains a `-XXX` suffix
  # that is not covered by `from_pattern`.
  if "-" in vers:
    vers = vers.replace('-', '.')
  if len(vers.split('.')) == 3:
    return vers + '.REL'
  else:
    return vers

def remove_prefix(s, prefix):
  if s.startswith(prefix):
    return s[len(prefix):]
  else:
    return s

# Check github tags
# Replace by regex before sorting. This is not currently supported by nvchecker
req = urllib.request.Request('https://api.github.com/repos/{}/tags'.format(github_repo))
body = None
with urllib.request.urlopen(req) as res:
  body = json.load(res)

versions = [ custom_preproc(remove_prefix(re.sub(from_pattern, to_pattern, it['name']), prefix)) for it in body ]
versions.sort(key=cmp_to_key(vercmp))

print(versions[-1])


#!/usr/bin/env python
'''
Shows the full image in which the pedestrian with pedestrianID
is contained.
This is mainly just to get a quick feel for how to use the annotations.
'''

from __future__ import print_function

import os
import sqlite3
from PIL import Image
import numpy as np
from matplotlib import pyplot as plt
from argparse import ArgumentParser

def main(args):
    try:
        dbFile = os.path.join(args.parse_path, 'annotations.sqlite3')
        db = sqlite3.connect(dbFile)
        dbc = db.cursor()
    except sqlite3.Error as e:
        raise Exception(e)

    query = '''SELECT directory, filename
                FROM Pedestrian p
                      JOIN Image i ON i.imageID = p.imageID
                      JOIN Sequence s ON s.sequenceID = i.sequenceID
                WHERE p.pedestrianID = {}
            '''
    result = dbc.execute(query.format(args.pid)).fetchone()

    imgfn = os.path.join(args.parse_path, 'sequences', result[0], result[1])
    print('image file: ', imgfn)
    try:
        img = np.array(Image.open(imgfn).convert('RGB'))
    except IOError as e:
        print('could not load image file')
        sys.exit(1)
    plt.imshow(img)
    plt.show()

if __name__ == '__main__':
    parser = ArgumentParser(description=__doc__)
    parser.add_argument('--verbose', '-v', action='store_true')
    parser.add_argument('--parse_path',
                        default=os.getenv('PARSE_PATH',
                                          '/work/sudowe/datasets/parse/'))
    parser.add_argument('pid', type=int,
                        help='show image containing the pedestrian with PID')
    args = parser.parse_args()
    main(args)


import psutil
import plotly.plotly as py
import plotly.graph_objs as go
import time

if __name__ == "__main__":
    arr = []
    times = [0]
    t = 0
    while t < 15:
        t += 1
        x = psutil.cpu_percent(interval=1, percpu=True)
        arr.append(x)
        print(x)
        times.append(t)
        time.sleep(1)

    data = []

    for i in range(len(arr[0])):
        t = go.Scatter(
            x=times,
            y=[z[i] for z in arr],
            mode='lines',
            name='Core ' + str(i + 1),
            connectgaps=True
        )
        data.append(t)

    layout = dict(title="CPU Usage Per Core",
                  xaxis=dict(title="Elapsed Time (seconds)"),
                  yaxis=dict(title="CPU Usage")
                  )

    fig = go.Layout(
    )

    fig = go.Figure(data=data, layout=layout)
    py.iplot(fig, filename='cpu_usage')


import os

import pytest

import dask.array as da
from dask.utils_test import inc
from dask.highlevelgraph import HighLevelGraph

def test_visualize(tmpdir):
    pytest.importorskip('graphviz')
    fn = str(tmpdir)
    a = da.ones(10, chunks=(5,))
    b = a + 1
    c = a + 2
    d = b + c
    d.dask.visualize(fn)
    assert os.path.exists(fn)

def test_basic():
    a = {'x': 1}
    b = {'y': (inc, 'x')}
    layers = {'a': a, 'b': b}
    dependencies = {'a': set(), 'b': {'a'}}
    hg = HighLevelGraph(layers, dependencies)

    assert dict(hg) == {'x': 1, 'y': (inc, 'x')}


from django.http import JsonResponse
from django.http.response import Http404

from .decoder import Decoder
from .encoder import Encoder
from .utils import process_sentence_param

encoder = Encoder()
decoder = Decoder()

def encode(request):
    """WeirdText encoding method.
    Args:
        request: User request with sentence
        to encode.
    Returns:
        Json response with encoded text.
    """
    if request.method == "GET":
        raw_sentence = request.GET.get("data", "")
        sentence = process_sentence_param(raw_sentence)
        return JsonResponse({"encoded": encoder.encode(sentence)})
    return Http404

def decode(request):
    """WeirdText decoding method.
    Args:
        request: User request with text
        to decode.
    Returns:
        Json response with decoded text.
    """
    if request.method == "GET":
        raw_sentence = request.GET.get("data", "")
        sentence = process_sentence_param(raw_sentence)
        return JsonResponse({"decoded": decoder.decode(sentence)})
    return Http404


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import (roc_auc_score, precision_score, recall_score, accuracy_score, plot_confusion_matrix,
                             roc_curve, f1_score, mean_absolute_error, mean_squared_error, r2_score, )

# some mappings to clarify the dataset
MAPPINGS = dict()

def create_attribute_mapping(attribute):
    attr_values = attribute.unique()
    mapping = dict(zip(attr_values, range(len(attr_values))))
    MAPPINGS[attribute.name] = mapping
    return mapping

class MetricLogger:

    def __init__(self):
        self.df = pd.DataFrame(
            {'metric': pd.Series([], dtype='str'),
             'alg': pd.Series([], dtype='str'),
             'value': pd.Series([], dtype='float')})

    def add(self, metric, alg, value):
        """
        Добавление значения
        """
        # Удаление значения если оно уже было ранее добавлено
        self.df.drop(self.df[(self.df['metric'] == metric) & (self.df['alg'] == alg)].index, inplace=True)
        # Добавление нового значения
        temp = [{'metric': metric, 'alg': alg, 'value': value}]
        self.df = self.df.append(temp, ignore_index=True)

    def get_data_for_metric(self, metric, ascending=True):
        """
        Формирование данных с фильтром по метрике
        """
        temp_data = self.df[self.df['metric'] == metric]
        temp_data_2 = temp_data.sort_values(by='value', ascending=ascending)
        return temp_data_2['alg'].values, temp_data_2['value'].values

    def plot(self, str_header, metric, ascending=True, figsize=(5, 5)):
        """
        Вывод графика
        """
        array_labels, array_metric = self.get_data_for_metric(metric, ascending)
        fig, ax1 = plt.subplots(figsize=figsize)
        pos = np.arange(len(array_metric))
        rects = ax1.barh(pos, array_metric,
                         align='center',
                         height=0.5,
                         tick_label=array_labels)
        ax1.set_title(str_header)
        for a, b in zip(pos, array_metric):
            plt.text(0.5, a - 0.05, str(round(b, 3)), color='white')
        plt.show()

METRIC_LOGGER = MetricLogger()

# Отрисовка ROC-кривой
# def draw_roc_curve(y_true, y_score, pos_label=1, average='micro'):
#     fpr, tpr, thresholds = roc_curve(y_true, y_score,
#                                      pos_label=pos_label)
#     roc_auc_value = roc_auc_score(y_true, y_score, average=average)
#     plt.figure()
#     lw = 2
#     plt.plot(fpr, tpr, color='darkorange',
#              lw=lw, label='ROC curve (area = %0.2f)' % roc_auc_value)
#     plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
#     plt.xlim([0.0, 1.0])
#     plt.ylim([0.0, 1.05])
#     plt.xlabel('False Positive Rate')
#     plt.ylabel('True Positive Rate')
#     plt.title('Receiver operating characteristic')
#     plt.legend(loc="lower right")
#     plt.show()

# def classification_train_model(x_train, y_train, x_test, y_test, model_name, model, clasMetricLogger):
#     model.fit(x_train, y_train)
#     Y_pred = model.predict(x_test)
#     precision = precision_score(y_test.values, Y_pred)
#     recall = recall_score(y_test.values, Y_pred)
#     f1 = f1_score(y_test.values, Y_pred)
#     roc_auc = roc_auc_score(y_test.values, Y_pred)
#
#     clasMetricLogger.add('precision', model_name, precision)
#     clasMetricLogger.add('recall', model_name, recall)
#     clasMetricLogger.add('f1', model_name, f1)
#     clasMetricLogger.add('roc_auc', model_name, roc_auc)
#
#     print('*****************************************************')
#     print(model)
#     print('*****************************************************')
#     draw_roc_curve(y_test.values, Y_pred)
#
#     plot_confusion_matrix(model, x_test, y_test.values,
#                           display_labels=['0', '1'],
#                           cmap=plt.cm.Blues, normalize='true')
#     plt.show()

def regression_train_model(x_train, y_train, x_test, y_test, model_name, model, metric_logger):
    model.fit(x_train, y_train)
    Y_pred = model.predict(x_test)

    mae = mean_absolute_error(y_test, Y_pred)
    mse = mean_squared_error(y_test, Y_pred)
    r2 = r2_score(y_test, Y_pred)

    metric_logger.add('MAE', model_name, mae)
    metric_logger.add('MSE', model_name, mse)
    metric_logger.add('R2', model_name, r2)

    print('*****************************************************')
    print(model)
    print()
    print('MAE={}, MSE={}, R2={}'.format(
        round(mae, 3), round(mse, 3), round(r2, 3)))
    print('*****************************************************')


"""
  This module contains objects to define and integrate full material models.

  In our context a material model is a ODE that defines the stress rate and
  an associated set of internal variables.  Mathematically, we can define
  this as two ODEs:

  .. math::

    \\dot{\\sigma} = f(\\sigma, h, T, \\dot{\\varepsilon}, t)

    \\dot{h} = g(\\sigma, h, T, \\dot{\\varepsilon}, t)

  where :math:`\\sigma` is the uniaxial stress, :math:`h` is some
  arbitrary set of internal variables, :math:`T` is the temperature,
  :math:`\\dot{\\varepsilon}` is the strain rate, and :math:`t` is the time.
  Note then that we mathematically define models as strain controlled: the input
  is the strain rate and the output is the stress rate.  Currently there is
  only one implemented full material model: :py:class:`pyoptmat.models.InelasticModel`,
  which is a standard viscoplastic formulation.  However other types of
  models, including rate-independent plasticity, could be defined with
  the same basic form.

  The model itself just defines a system of ODEs.  To solve for stress or
  strain as a function of the experimental conditions we need to integrate
  this model using the methods in :py:mod:`pyoptmat.ode`.  We could do this
  in two ways, in strain control where we provide the strains and temperatures
  as a function of time and integrate for the stress or provide the
  stresses and temperatures as a function of time and integrate for the
  strains.  The :py:class:`pyoptmat.models.ModelIntegrator` provides both
  options, where each experiment can either be strain or stress controlled.

  The basic process of setting up a material model capable of simulating
  experimental tests is to define the model form mathematically, using a
  Model class and wrap that Model with an Integrator to provide actual
  time series of stress or strain.  As the integrator class uses the
  methods in :py:mod:`pyoptmat.ode` to actually do the integration, the
  results (and subsequent mathematical operations on the results) can be
  differentiated using either PyTorch backpropogation AD or the adjoint
  method.
"""

import torch
from torch import nn

from pyoptmat import utility, ode, damage, solvers

class InelasticModel(nn.Module):
    """
    This object provides the standard strain-based rate form of a constitutive model

    .. math::

      \\dot{\\sigma} = E \\left(\\dot{\\varepsilon} - \\dot{\\varepsilon}_{in} \\right)

    Args:
      E:                        Material Young's modulus
      flowrule:                 :py:class:`pyoptmat.flowrules.FlowRule` defining the inelastic
                                strain rate
    """

    def __init__(self, E, flowrule, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.E = E
        self.flowrule = flowrule

    @property
    def nhist(self):
        """
        Number of internal variables
        """
        return 1 + self.flowrule.nhist

    def forward(self, t, y, erate, T):
        """
        Return the rate equations for the strain-based version of the model

        Args:
          t:              (nbatch,) times
          y:              (nbatch,1+nhist) [stress, history]
          erate:          (nbatch,) strain rates
          T:              (nbatch,) temperatures

        Returns:
          y_dot:          (nbatch,1+nhist) state rate
          d_y_dot_d_y:    (nbatch,1+nhist,1+nhist) Jacobian wrt the state
          d_y_dot_d_erate:(nbatch,1+nhist) Jacobian wrt the strain rate
          d_y_dot_d_T:    (nbatch,1+nhist) derivative wrt temperature (unused)
        """
        stress = y[..., 0].clone()
        h = y[..., 1:].clone()

        frate, dfrate = self.flowrule.flow_rate(stress, h, t, T, erate)
        hrate, dhrate = self.flowrule.history_rate(stress, h, t, T, erate)

        # Stacked rate of evolution vector
        result = torch.cat(
            [(self.E(T) * (erate - frate)).unsqueeze(-1), hrate],
            dim=-1,
        )

        # Form the large blocked matrix of d(y_dot)/d(y)
        row1 = torch.cat(
            [
                (-self.E(T) * dfrate).unsqueeze(-1).unsqueeze(-1),
                (
                    -self.E(T)[..., None, None]
                    * self.flowrule.dflow_dhist(stress, h, t, T, erate)
                ),
            ],
            dim=-1,
        )

        row2 = torch.cat(
            [self.flowrule.dhist_dstress(stress, h, t, T, erate).unsqueeze(-1), dhrate],
            dim=-1,
        )
        dresult = torch.cat([row1, row2], dim=-2)

        # Form the stacked derivative of the state rate with respect to the strain rate
        drate = torch.cat(
            [
                (
                    self.E(T)
                    * (1.0 - self.flowrule.dflow_derate(stress, h, t, T, erate))
                ).unsqueeze(-1),
                self.flowrule.dhist_derate(stress, h, t, T, erate),
            ],
            dim=-1,
        )

        # Logically we should return the derivative wrt T, but right now
        # we're not going to use it
        Trate = torch.zeros_like(y)

        return result, dresult, drate, Trate

class DamagedInelasticModel(nn.Module):
    """
    This object provides the standard strain-based rate form of a constitutive model

    .. math::

      \\dot{\\sigma} = E \\left(\\dot{\\varepsilon} - (1-d) \\dot{\\varepsilon}_{in} \\right)

    Args:
      E:                        Material Young's modulus
      flowrule:                 :py:class:`pyoptmat.flowrules.FlowRule` defining the inelastic
                                strain rate
      dmodel (optional):        :py:class:`pyoptmat.damage.DamageModel` defining the damage variable
                                  evolution rate, defaults to :py:class:`pyoptmat.damage.NoDamage`
    """

    def __init__(self, E, flowrule, *args, dmodel=damage.NoDamage(), **kwargs):
        super().__init__(*args, **kwargs)
        self.E = E
        self.flowrule = flowrule
        self.dmodel = dmodel

    @property
    def nhist(self):
        """
        Number of internal variables
        """
        return 2 + self.flowrule.nhist

    def forward(self, t, y, erate, T):
        """
        Return the rate equations for the strain-based version of the model

        Args:
          t:              (nbatch,) times
          y:              (nbatch,1+nhist+1) [stress, history, damage]
          erate:          (nbatch,) strain rates
          T:              (nbatch,) temperatures

        Returns:
          y_dot:          (nbatch,1+nhist+1) state rate
          d_y_dot_d_y:    (nbatch,1+nhist+1,1+nhist+1) Jacobian wrt the state
          d_y_dot_d_erate:(nbatch,1+nhist+1) Jacobian wrt the strain rate
          d_y_dot_d_T:    (nbatch,1+nhist+1) derivative wrt temperature (unused)
        """
        stress = y[..., 0].clone()
        h = y[..., 1 : 1 + self.flowrule.nhist].clone()
        d = y[..., -1].clone()

        frate, dfrate = self.flowrule.flow_rate(stress / (1 - d), h, t, T, erate)
        hrate, dhrate = self.flowrule.history_rate(stress / (1 - d), h, t, T, erate)
        drate, ddrate = self.dmodel.damage_rate(stress / (1 - d), d, t, T, erate)

        # Stacked rate of evolution vector
        result = torch.cat(
            [
                ((1 - d) * self.E(T) * (erate - frate)).unsqueeze(-1),
                hrate,
                drate.unsqueeze(-1),
            ],
            dim=-1,
        )

        # Form the large blocked matrix of d(y_dot)/d(y)
        row1 = torch.cat(
            [
                (-self.E(T) * dfrate).unsqueeze(-1).unsqueeze(-1),
                (
                    -self.E(T)[..., None, None]
                    * self.flowrule.dflow_dhist(stress / (1 - d), h, t, T, erate)
                    * (1 - d)[..., None, None]
                ),
                (-self.E(T) * (erate - frate) - self.E(T) * dfrate * stress / (1 - d))
                .unsqueeze(-1)
                .unsqueeze(-1),
            ],
            dim=-1,
        )
        row2 = torch.cat(
            [
                (
                    self.flowrule.dhist_dstress(stress / (1 - d), h, t, T, erate)
                    / (1 - d)[..., None]
                ).unsqueeze(-1),
                dhrate,
                (
                    self.flowrule.dhist_dstress(stress / (1 - d), h, t, T, erate)
                    * stress[..., None]
                    / (1 - d[..., None]) ** 2
                ).unsqueeze(-1),
            ],
            dim=-1,
        )
        row3 = torch.cat(
            [
                (
                    self.dmodel.d_damage_rate_d_s(stress / (1 - d), d, t, T, erate)
                    / (1 - d)
                )[..., None, None],
                torch.zeros_like(h).unsqueeze(-2),
                ddrate[..., None, None],
            ],
            dim=-1,
        )
        dresult = torch.cat([row1, row2, row3], dim=-2)

        # Form the stacked derivative of the state rate with respect to the strain rate
        drate = torch.cat(
            [
                (
                    self.E(T)
                    * (1 - d)
                    * (
                        1.0
                        - self.flowrule.dflow_derate(stress / (1 - d), h, t, T, erate)
                    )
                ).unsqueeze(-1),
                self.flowrule.dhist_derate(stress / (1 - d), h, t, T, erate),
                self.dmodel.d_damage_rate_d_e(
                    stress / (1 - d), d, t, T, erate
                ).unsqueeze(-1),
            ],
            dim=-1,
        )

        # Logically we should return the derivative wrt T, but right now
        # we're not going to use it
        Trate = torch.zeros_like(y)

        return result, dresult, drate, Trate

class ModelIntegrator(nn.Module):
    """
    This class provides infrastructure for integrating constitutive models in
    either strain or stress control.

    Args:
      model:                        base strain-controlled model
      method (optional):            integrate method used to solve the equations, defaults
                                    to `"backward-euler"`
      use_adjoint (optional):       if `True` use the adjoint approach to
      **kwargs:                     passed on to the odeint method

    """

    def __init__(self, model, *args, use_adjoint=True, **kwargs):
        super().__init__(*args)
        self.model = model
        self.use_adjoint = use_adjoint
        self.kwargs_for_integration = kwargs

        if self.use_adjoint:
            self.imethod = ode.odeint_adjoint
        else:
            self.imethod = ode.odeint

    def solve_both(self, times, temperatures, idata, control):
        """
        Solve for either strain or stress control at once

        Args:
          times:          input times, (ntime,nexp)
          temperatures:   input temperatures (ntime,nexp)
          idata:          input data (ntime,nexp)
          control:        signal for stress/strain control (nexp,)
        """
        rates = torch.cat(
            (
                torch.zeros(1, idata.shape[1], device=idata.device),
                (idata[1:] - idata[:-1]) / (times[1:] - times[:-1]),
            )
        )
        # Likely if this happens dt = 0
        rates[torch.isnan(rates)] = 0

        rate_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(times, rates)
        base_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(times, idata)
        temperature_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(
            times, temperatures
        )

        init = torch.zeros(times.shape[1], self.model.nhist, device=idata.device)

        bmodel = BothBasedModel(
            self.model,
            rate_interpolator,
            base_interpolator,
            temperature_interpolator,
            control,
        )

        return self.imethod(bmodel, init, times, **self.kwargs_for_integration)

    def solve_strain(self, times, strains, temperatures):
        """
        Basic model definition: take time and strain rate and return stress

        Args:
          times:          input times, shape (ntime)
          strains:        input strains, shape (ntime, nbatch)
          temperatures:   input temperatures, shape (ntime, nbatch)

        Returns:
          y:          stacked [stress, history, damage] vector of shape
                      `(ntime,nbatch,1+nhist+1)`
        """
        strain_rates = torch.cat(
            (
                torch.zeros(1, strains.shape[1], device=strains.device),
                (strains[1:] - strains[:-1]) / (times[1:] - times[:-1]),
            )
        )
        # Likely if this happens dt = 0
        strain_rates[torch.isnan(strain_rates)] = 0

        erate_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(
            times, strain_rates
        )
        temperature_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(
            times, temperatures
        )

        init = torch.zeros(times.shape[1], self.model.nhist, device=strains.device)

        emodel = StrainBasedModel(
            self.model, erate_interpolator, temperature_interpolator
        )

        return self.imethod(emodel, init, times, **self.kwargs_for_integration)

    def solve_stress(self, times, stresses, temperatures):
        """
        Inverse model definition: take time and stress rate and return strain

        Args:
          times:          input times, shape (ntime,)
          stresses:       input stresses, shape (ntime, nbatch)
          temperatures:   input temperatures, shape (ntime, nbatch)

        Returns:
          y:              stack [strain, history, damage] vector
                          of shape `(ntime,nbatch,2+nhist)`
        """
        stress_rates = torch.cat(
            (
                torch.zeros(1, stresses.shape[1], device=stresses.device),
                (stresses[1:] - stresses[:-1]) / (times[1:] - times[:-1]),
            )
        )
        # Likely if this happens dt = 0
        stress_rates[torch.isnan(stress_rates)] = 0

        stress_rate_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(
            times, stress_rates
        )
        stress_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(
            times, stresses
        )
        temperature_interpolator = utility.ArbitraryBatchTimeSeriesInterpolator(
            times, temperatures
        )

        init = torch.zeros(times.shape[1], self.model.nhist, device=stresses.device)

        smodel = StressBasedModel(
            self.model,
            stress_rate_interpolator,
            stress_interpolator,
            temperature_interpolator,
        )

        return self.imethod(smodel, init, times, **self.kwargs_for_integration)

    def forward(self, t, y):
        """
        Evaluate both strain and stress control and paste into the right
        locations.

        Args:
            t:  input times
            y:  input state
        """
        raise NotImplementedError("forward method is pure virtual in base class")

class BothBasedModel(nn.Module):
    """
    Provides both the strain rate and stress rate form at once, for better vectorization

    Args:
      model:    base InelasticModel
      rate_fn:  controlled quantity rate interpolator
      base_fn:  controlled quantity base interpolator
      T_fn:     temperature interpolator
      indices:  split into strain and stress control
    """

    def __init__(self, model, rate_fn, base_fn, T_fn, control, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.model = model
        self.rate_fn = rate_fn
        self.base_fn = base_fn
        self.T_fn = T_fn
        self.control = control

        self.emodel = StrainBasedModel(self.model, self.rate_fn, self.T_fn)
        self.smodel = StressBasedModel(
            self.model, self.rate_fn, self.base_fn, self.T_fn
        )

    def forward(self, t, y):
        """
        Evaluate both strain and stress control and paste into the right
        locations.

        Args:
            t:  input times
            y:  input state
        """
        strain_rates, strain_jacs = self.emodel(t, y)
        stress_rates, stress_jacs = self.smodel(t, y)

        actual_rates = torch.zeros_like(strain_rates)

        e_control = self.control == 0
        s_control = self.control == 1

        actual_rates[..., e_control, :] = strain_rates[..., e_control, :]
        actual_rates[..., s_control, :] = stress_rates[..., s_control, :]

        actual_jacs = torch.zeros_like(strain_jacs)
        actual_jacs[..., e_control, :, :] = strain_jacs[..., e_control, :, :]
        actual_jacs[..., s_control, :, :] = stress_jacs[..., s_control, :, :]

        return actual_rates, actual_jacs

class StrainBasedModel(nn.Module):
    """
    Provides the strain rate form

    Args:
      model:        base InelasticModel
      erate_fn:     erate(t)
      T_fn:         T(t)
    """

    def __init__(self, model, erate_fn, T_fn, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.model = model
        self.erate_fn = erate_fn
        self.T_fn = T_fn

    def forward(self, t, y):
        """
        Strain rate as a function of t and state

        Args:
            t:  input times
            y:  input state
        """
        return self.model(t, y, self.erate_fn(t), self.T_fn(t))[
            :2
        ]  # Don't need the extras

class StressBasedModel(nn.Module):
    """
    Provides the stress rate form

    Args:
      model:        base InelasticModel
      srate_fn:     srate(t)
      T_fn:         T(t)
    """

    def __init__(self, model, srate_fn, stress_fn, T_fn, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.model = model
        self.srate_fn = srate_fn
        self.stress_fn = stress_fn
        self.T_fn = T_fn

    def forward(self, t, y):
        """
        Stress rate as a function of t and state

        Args:
            t:  input times
            y:  input state
        """
        csr = self.srate_fn(t)
        cs = self.stress_fn(t)
        cT = self.T_fn(t)

        erate_guess = torch.zeros_like(y[..., 0])[..., None]

        def RJ(erate):
            yp = y.clone()
            yp[..., 0] = cs
            ydot, _, Je, _ = self.model(t, yp, erate[..., 0], cT)

            R = ydot[..., 0] - csr
            J = Je[..., 0]

            return R[..., None], J[..., None, None]

        erate, _ = solvers.newton_raphson(RJ, erate_guess)
        yp = y.clone()
        yp[..., 0] = cs
        ydot, J, Je, _ = self.model(t, yp, erate[..., 0], cT)

        # Rescale the jacobian
        J[..., 0, :] = -J[..., 0, :] / Je[..., 0][..., None]
        J[..., :, 0] = 0

        # Insert the strain rate
        ydot[..., 0] = erate[..., 0]

        return ydot, J


import os
import psutil
import trawl_agent.common.api_handler
import time
import re

class HostStats():
    def get_parts(self):
        fsignore = ['iso9660', 'cdrom']
        partitions = []
        mounts = psutil.disk_partitions(all=False)
        for mount in mounts:
            if mount.fstype not in fsignore:
                partitions.append(mount.mountpoint)

        return partitions

    def net_stats(self):

        parts = [
            r'(^|\s+)',
            r'(?P<device>\w+)\:\s+',
            r'(?P<rbytes>\d+)\s+',
            r'(?P<rpackets>\d+)\s+',
            r'(?P<rerrs>\d+)\s+',
            r'(?P<rdrop>\d+)\s+',
            r'(?P<rfifo>\d+)\s+',
            r'(?P<rframe>\d+)\s+',
            r'(?P<rcompressed>\d+)\s+',
            r'(?P<rmulticast>\d+)\s+',
            r'(?P<sbytes>\d+)\s+',
            r'(?P<spackets>\d+)\s+',
            r'(?P<serrs>\d+)\s+',
            r'(?P<sdrop>\d+)\s+',
            r'(?P<sfifo>\d+)\s+',
            r'(?P<scolls>\d+)\s+',
            r'(?P<scarrier>\d+)\s+',
            r'(?P<scompress>\d+)',
        ]
        pattern = re.compile(''.join(parts))

        net = {}
        f = open('/proc/net/dev', 'r')
        lines = f.readlines()
        for line in lines:
            m = pattern.match(line) if True else None
            if m is not None:
                    net[m.group('device')] = m.groupdict()

        devs = net.keys()
        net_total = {}
        for dev in devs:
           net_total[dev] =  ( int(net[dev]['rbytes']) + int(net[dev]['sbytes']) )

        return net_total

    def disk_space_stats(self, stat):
        partitions = self.get_parts()
        disk_usage = {}
        for part in partitions:
            p = psutil.disk_usage(part)
            if stat == 'used':
                disk_usage[part] = p.used
            else:
                disk_usage[part] = p.total

        return disk_usage

    def cpu_stats(self):
        la = os.getloadavg()
        stats = {}
        stats['la1'], stats['la5'], stats['la15'] = la[0], la[1], la[2]
        cpu_pct_stats = psutil.cpu_times_percent(interval=1)
        stats['cpu_iowait'], stats['cpu_sys'], stats['cpu_usr'], stats['cpu_idle'], stats['cpu_steal'] = cpu_pct_stats.iowait, cpu_pct_stats.system, cpu_pct_stats.user, cpu_pct_stats.idle, cpu_pct_stats.steal
        stats['cpu_count'] = psutil.cpu_count()

        return stats

    def mem_stats(self):
        vram = psutil.virtual_memory()
        stats = {'vm_total': vram[0], 'vm_avail': vram[1], 'vm_used': vram[3], 'vm_buffers': vram[7], 'vm_cache': vram[8]}

        return stats

    def swap_stats(self):
        swap = psutil.swap_memory()
        stats = {'swap_total': swap[0], 'swap_free': swap[2], 'swap_used': swap[1], 'swap_pct': swap[3]}

        return stats

    def collect(self):
        stats = {}
        stats['log_type'] = 'sysstats'
        up = trawlers.trawl_agent.common.api_handler.UploadHostStats()
        run1 = {}
        while True:
            try:
                ns = self.net_stats()
                ms = self.mem_stats()
                cs = self.cpu_stats()
                du = self.disk_space_stats('used')
                dt = self.disk_space_stats('total')
                if len(run1.keys()) == 0:
                    run1 = ns
                else:
                    nets = {}
                    for key in ns.keys():
                        nets[key] = ( ns[key] - run1[key] ) / 300

                    stats['NET'] = nets
                    stats['MEM'] = ms
                    stats['CPU'] = cs
                    stats['DISK_TOTAL'] = dt
                    stats['DISK_USED'] = du
                    up.upload_stats(stats)
                    run1 = ns
                    time.sleep(300)
            except:
                raise


from . import CommBench, setup_model, update_once, print_experimental_env

import argparse
import socket

from logging import DEBUG
from logging import getLogger
from logging import StreamHandler

logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)

try:
    import chainer
    import chainermn
    import mpi4py.MPI

except:
    logger.exception("rank=%d, host=%s", mpi4py.MPI.COMM_WORLD.rank,
                     socket.gethostname())
    import traceback
    traceback.print_exc()
    raise

possible_comm_names = ['flat', 'hierarchical', 'two_dimensional',
                       'naive', 'pure_nccl', 'pure_nccl_fp16']
default_com_names = ['pure_nccl', 'pure_nccl_fp16']

def main():
    parser = argparse.ArgumentParser('Communicator Benchmark 1:'
                                     ' allreduce_grad latency stats')
    parser.add_argument('--model', default='resnet50', help="Type of model",
                        choices=['resnet50', 'resnet101', 'resnet152'])
    parser.add_argument('--communicator_names', '--comm', type=str,
                        help="Communicator names")
    parser.add_argument('--use_gpu', '-g', help='Use GPU',
                        action='store_true', default=True)
    parser.add_argument('--label_num', help='Number of labels',
                        type=int, default=1000)
    parser.add_argument('--n_trials', '-n', help='Number of trials',
                        type=int, default=100)
    parser.add_argument('--interval', help='interval in sec',
                        type=int, default=0)
    parser.add_argument('--verbose', '-v', action='store_true',
                        help="Verbose mode to see each latency")
    args = parser.parse_args()

    model = setup_model(args.model, args.label_num)
    communicator_names = args.communicator_names
    use_gpu = args.use_gpu
    model_name = args.model
    n_trials = args.n_trials

    if args.communicator_names is None:
        communicator_names = default_com_names
    else:
        communicator_names = communicator_names.split(',')
    for name in communicator_names:
        assert name in possible_comm_names

    comm = chainermn.create_communicator()

    if use_gpu:
        chainer.cuda.get_device(comm.intra_rank).use()
        model.to_gpu()
    update_once(model)
    print_experimental_env(comm, model, model_name, n_trials, logger)

    if comm.rank == 0:
        logger.info("Communicator names: {}".format(communicator_names))

        logger.info('-----------------------------------------------')
        logger.info('Communicator     Mean    Median  Min     Max     Std')

    for communicator_name in communicator_names:
        bench = CommBench(communicator_name, n_trials,
                          args.interval, args.verbose)
        bench.benchmark(model)
        bench.pp_result()

if __name__ == '__main__':
    try:
        main()
    except:
        logger.exception("rank=%d, host=%s", mpi4py.MPI.COMM_WORLD.rank,
                         socket.gethostname())
        import traceback
        traceback.print_exc()


from flask import Flask, redirect, url_for, request, jsonify, json, Response
from twilio.rest import Client

from Persona import Persona

app = Flask(__name__)

segment_persona_map = {
        "segment_0": "Persona 0", "segment_1": "Persona 1", "segment_2": "Persona 2", "segment_3": "Persona 3"
    }
account_sid = '<twilio account_sid>'
auth_token = '<twilio auth_token>'
whatsapp_sender = 'whatsapp:<twilio number>'

@app.route('/')
def hello_world():
    return 'Welcome to Persona Based Store Service!'

@app.route('/api/v1/sendMessage', methods=['POST'])
def send_message():
    json_string = json.dumps(request.get_json())
    json_dict = json.loads(json_string)

    phone_number = 'whatsapp:' + json_dict['phoneNumber']
    location = json_dict['location']
    persona_name = json_dict['personaName']
    result_summary = 'Your persona is ' + persona_name + ' . Please head to ' + location + ' to enjoy the collection '
    'curate according to your taste. Happy shopping!'

    client = Client(account_sid, auth_token)

    message = client.messages.create(
        from_=whatsapp_sender,
        body=result_summary,
        to=phone_number
    )

    return Response(message.sid, status=200, mimetype='application/json')

@app.route('/api/v1/categories/<gender>')
def get_categories(gender):
    # hardcoding the gender for the time being since our data is only for female category
    gender = 'female';
    print('Categories for %s' % gender)
    js = open('static/json/categories.json').read()
    resp = Response(js, status=200, mimetype='application/json')
    return resp

@app.route('/api/v1/personas/<gender>')
def get_personas(gender):
    # hardcoding the gender for the time being since our data is only for female category
    file_name = 'personas_' + gender+'.json'
    print('Personas for %s' % gender)
    js = open('static/json/' + file_name).read()
    resp = Response(js, status=200, mimetype='application/json')
    return resp

@app.route('/api/v1/personas/computed', methods=['POST'])
def predict_persona():
    json_string = json.dumps(request.get_json())
    json_dict = json.loads(json_string)
    print(json_dict["gender"])
    gender_value = json_dict["gender"]
    selected_attributes = json_dict["selectedAttributes"]
    selected_attributes_category = selected_attributes["name"]
    selected_attributes_array = selected_attributes["attributes"]

    param_dict = {}

    for x in selected_attributes_array:
        print ('name %s' % x["name"])
        print ('value %s' % x["value"])
        if len(x["value"]) != 0:
            param_dict['Attribute_' + (x["name"].lower()).replace(' ','_')] = x["value"][0]

    print(gender_value + " " + selected_attributes_category)

    return Response(calculate_persona(param_dict, selected_attributes_category), status=200, mimetype='application/json')

def calculate_persona(param_dict, selected_attributes_category):
    obj = Persona()

    if selected_attributes_category == 'Dresses for Women':
        obj.load_model('computation/segment_params.txt', 'computation/segment_predictions.csv')
    elif selected_attributes_category == 'Denims for Women':
        obj.load_model('computation/segment_params_denim.txt', 'computation/segment_predictions_denim.csv')

    file_name = 'personas_female.json'
    js = open('static/json/' + file_name).read()
    personas_list = json.loads(js)

    results_list = personas_list

    if len(param_dict) != 0:
        predicted_persona = obj.predict_persona(param_dict)
        print('Predicted Persona %s' % predicted_persona)
        persona = predicted_persona.pop()
        persona_name = segment_persona_map[persona]
        print ('Computed Persona: %s' % persona_name)

        index_of_space = persona_name.index(' ')
        persona_id = int(persona_name[index_of_space+1:])
        results_list = personas_list[persona_id:persona_id+1]

    return json.dumps(results_list)

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