from django.test import TestCase, Client
from mc.models import Server
from unittest.mock import patch
from django.utils import timezone
from datetime import timedelta
# Create your tests here.

class ServerTest(TestCase):
    def setUp(self):
        self.s1 = Server(name='test', description='some_test',directory='/home/work/some_dir')
        self.s1.save()
        self.s2 = Server(name='test2', description='some_test', directory='some_dire', status='ok',
                         last_checked_at=timezone.now() - timedelta(minutes=6))
        self.s2.save()

    def tearDown(self):
        self.s1.delete()

    @patch('mc.models.check_server')
    def testSuccessServer(self, _check):
        _check.return_value = 'ok'
        check_result = self.s1.get_status()
        self.assertEqual('ok', check_result)
        check_result = self.s2.get_status()
        self.assertEqual('ok', check_result)

    @patch('mc.models.check_server')
    def testFailedServer(self, _check):
        _check.return_value = 'not ok'
        check_result = self.s1.get_status()
        self.assertEqual('not ok', check_result)
        check_result = self.s2.get_status()
        self.assertEqual('not ok', check_result)

class StatusViewTest(TestCase):

    def setUp(self):
        self.s1 = Server(name='test', description='some_test', directory='/home/work/some_dir', status='ok',
                         last_checked_at=timezone.now())
        self.s1.save()

    def tearDown(self):
        self.s1.delete()

    def test_status_view(self):
        c = Client()
        r = c.get('/')
        self.assertTemplateUsed(r, 'status.html')
        self.assertContains(r, self.s1.name)

class RestartViewTest(TestCase):

    def setUp(self):
        self.s1 = Server(name='test', description='some_test', directory='/home/work/some_dir', status='ok',
                         last_checked_at=timezone.now())
        self.s1.save()
        self.s2 = Server(name='test', description='some_test', directory='/home/work/some_dir', status='not ok',
                         last_checked_at=timezone.now())
        self.s2.save()

    def tearDown(self):
        self.s1.delete()
        self.s2.delete()

    def test_restart_server(self):
        c = Client()
        r = c.post('/server/{}/start/'.format(self.s1.id))
        # 已经ok的服务器不准重启
        self.assertEqual(400, r.status_code)
        r = c.post('/server/{}/start/'.format(self.s2.id))
        self.assertContains(r, 'ok')


from .client import MongoClient
import logging

client = None

def init_client(io_loop=None, db='mongodb://localhost:27017/torspider'):
    global client
    logging.debug('Initializing client. db: %s', db)
    MongoClient.setup(db=db, io_loop=io_loop)
    client = MongoClient()

async def save_report(report):
    return await client.save_report(report)

__all__ = [MongoClient,]


import streamlit as st
import pandas as pd
import plotly.express as px

# Load data
data = pd.read_csv("vehicles_us.csv", encoding='utf-8')

# Header
st.header("Exploratory Data Analysis")

# Checkbox to toggle between histograms and scatter plots
show_histograms = st.checkbox("Show histograms", True)

# Histogram of mileage
if show_histograms:
    st.subheader("Mileage Distribution")
    fig = px.histogram(data, x="odometer")
    st.plotly_chart(fig)

# Show scatter plot of days listed vs condition
show_days_vs_condition = st.checkbox("Show days listed vs condition scatter plot")
if show_days_vs_condition:
    st.subheader("Days Listed vs Condition")
    fig = px.scatter(data, x="days_listed", y="condition")
    st.plotly_chart(fig)

# Scatter plot of mileage vs. price
st.subheader("Mileage vs. Price")
fig = px.scatter(data, x="odometer", y="price")
st.plotly_chart(fig)


# Basic Lib Import
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.shortcuts import render
from django.views.generic import View

from brand.models import Brand

class BrandListView(View):
    def get(self, request):
        ''' This will reutrn list of brand '''
        brand_list = Brand.objects.all().order_by('-id')
        paginator = Paginator(brand_list, 10)
        page_number = request.GET.get('page')

        try:
            page_object = paginator.page(page_number)
        except PageNotAnInteger:
            # if page is not an integer, deliver the first page
            page_object = paginator.page(1)
        except EmptyPage:
            # if the page is out of range, deliver the last page
            page_object = paginator.page(paginator.num_pages)

        context = {
            'brand': page_object,
        }
        return render(request, 'brand/brand_list.html', context)


from collections import deque
def solution(queue1, queue2):
    answer =  0
    queue1, queue2 = deque(queue1), deque(queue2)
    sum1, sum2 = sum(queue1), sum(queue2)

    # 두 큐의 합이 홀수이면, 두 큐의 합을 같게 만들 수 없다.
    if sum1 + sum2 % 2 == 1:
        return -1

    # 4 * n(큐의 길이)번 insert & pop을 수행하면 처음 큐 상태로 돌아간다.
    for i in range(len(queue1) * 4):
        # sum1이 sum2보다 크면, queue1의 원소를 추출하여 queue2에 삽입힌다.
        if sum1 > sum2:
            sum1 -= queue1[0]
            sum2 += queue1[0]
            queue2.append(queue1.popleft())

        # sum2가 sum1보다 크면, queue2의 원소를 추출하여 queue1에 삽입한다.
        elif sum1 < sum2:
            sum1 += queue2[0]
            sum2 -= queue2[0]
            queue1.append(queue2.popleft())

        # sum1과 sum2가 같은 경우
        else:
            return i

    return -1

코테/두 큐 합 같게 만들기 복습.py

두 큐 합 같게 만들기 복습.py


from kge import Config, Dataset
from kge.model.kge_model import RelationalScorer, KgeModel
from kge.util import similarity, KgeLoss, rat

import torch
from torch import Tensor
from torch.nn import functional as F
from torch import nn
from torch.nn.parameter import Parameter

from pytorch_pretrained_bert.modeling import BertEncoder, BertConfig, BertLayerNorm, BertPreTrainedModel

from functools import partial

from kge.util import sc

class TrmEScorer(RelationalScorer):
    r"""Implementation of the TrmE KGE scorer."""

    def __init__(self, config: Config, dataset: Dataset, configuration_key=None):
        super().__init__(config, dataset, configuration_key)
        self.dim = self.get_option("entity_embedder.dim")
        self.max_context_size = self.get_option("max_context_size")
        self.initializer_range = self.get_option("initializer_range")

        self.cls = Parameter(torch.Tensor(1, self.dim))
        torch.nn.init.normal_(self.cls, std=self.initializer_range)
        self.global_cls = Parameter(torch.Tensor(1, self.dim))
        torch.nn.init.normal_(self.global_cls, std=self.initializer_range)
        self.local_mask = Parameter(torch.Tensor(1, self.dim))
        torch.nn.init.normal_(self.local_mask, std=self.initializer_range)
        self.type_embeds = nn.Embedding(100, self.dim)
        torch.nn.init.normal_(self.type_embeds.weight, std=self.initializer_range)
        self.atomic_type_embeds = nn.Embedding(3, self.dim)
        torch.nn.init.normal_(self.atomic_type_embeds.weight, std=self.initializer_range)

        self.similarity = getattr(similarity, self.get_option("similarity"))(self.dim)
        self.layer_norm = BertLayerNorm(self.dim, eps=1e-12)
        self.atomic_layer_norm = BertLayerNorm(self.dim, eps=1e-12)

        self.transformer_encoder = rat.Encoder(
            lambda: rat.EncoderLayer(
                self.dim,
                rat.MultiHeadedAttentionWithRelations(
                    self.get_option("nhead"),
                    self.dim,
                    self.get_option("attn_dropout")),
                rat.PositionwiseFeedForward(
                    self.dim,
                    self.get_option("ff_dim"),
                    self.get_option("hidden_dropout")),
                num_relation_kinds=0,
                dropout=self.get_option("hidden_dropout")),
            self.get_option("nlayer"),
            self.initializer_range,
            tie_layers=False)

        config = BertConfig(0, hidden_size=self.dim,
                            num_hidden_layers=self.get_option("nlayer") // 2,
                            num_attention_heads=self.get_option("nhead"),
                            intermediate_size=self.get_option("ff_dim"),
                            hidden_act=self.get_option("activation"),
                            hidden_dropout_prob=self.get_option("hidden_dropout"),
                            attention_probs_dropout_prob=self.get_option("attn_dropout"),
                            max_position_embeddings=0,  # no effect
                            type_vocab_size=0,  # no effect
                            initializer_range=self.initializer_range)
        self.atom_encoder = BertEncoder(config)
        self.atom_encoder.config = config
        self.atom_encoder.apply(partial(BertPreTrainedModel.init_bert_weights, self.atom_encoder))

    def _get_encoder_output(self, e_emb, p_emb, ids, gt_ent, gt_rel, output_repr=False):
        n = p_emb.size(0)
        device = p_emb.device

        ctx_list, ctx_size = self.dataset.index('neighbor')
        ctx_ids = ctx_list[ids].to(device).transpose(1, 2)
        ctx_size = ctx_size[ids].to(device)

        # sample neighbors unifromly during training
        if self.training:
            perm_vector = sc.get_randperm_from_lengths(ctx_size, ctx_ids.size(1))
            ctx_ids = torch.gather(ctx_ids, 1, perm_vector.unsqueeze(-1).expand_as(ctx_ids))

        # [bs, length, 2]
        ctx_ids = ctx_ids[:, :self.max_context_size]
        ctx_size[ctx_size > self.max_context_size] = self.max_context_size

        # [bs, max_ctx_size]
        entity_ids = ctx_ids[...,0]
        relation_ids = ctx_ids[...,1]

        # initialize mask by length of context, seq=[CLS, S, N1, N2, ...]
        # 1 is the positions that will be attended to
        ctx_size = ctx_size + 2
        attention_mask = sc.get_mask_from_sequence_lengths(ctx_size, self.max_context_size + 2)

        if self.training and not output_repr:
            # mask out ground truth during training to avoid overfitting
            gt_mask = ((entity_ids != gt_ent.view(n, 1)) | (relation_ids != gt_rel.view(n, 1)))
            ctx_random_mask = (attention_mask
                               .new_ones((n, self.max_context_size))
                               .bernoulli_(1 - self.get_option("ctx_dropout")))
            attention_mask[:,2:] = attention_mask[:, 2:] & ctx_random_mask & gt_mask

        # [bs, max_ctx_size, dim]
        entity_emb = self._entity_embedder().embed(entity_ids)
        relation_emb = self._relation_embedder().embed(relation_ids)

        if self.training and self.get_option("self_dropout") > 0 and self.max_context_size > 0 and not output_repr:
            # sample a proportion of input for masked prediction similar to the MLM in BERT
            self_dropout_sample = sc.get_bernoulli_mask([n], self.get_option("self_dropout"), device)

            # replace with mask tokens
            masked_sample = sc.get_bernoulli_mask([n], self.get_option("mlm_mask"), device) & self_dropout_sample
            e_emb[masked_sample] = self.local_mask.unsqueeze(0)

            # replace with random sampled entities, no back propagation here
            replaced_sample = sc.get_bernoulli_mask([n], self.get_option(
                "mlm_replace"), device) & self_dropout_sample & ~masked_sample
            e_emb[replaced_sample] = self._entity_embedder().embed(torch.randint(self.dataset.num_entities(
            ), replaced_sample.shape, dtype=torch.long, device=device))[replaced_sample].detach()

        src = torch.cat([torch.stack([e_emb, p_emb], dim=1), torch.stack([entity_emb, relation_emb], dim=2)
                         .view(n, 2 * self.max_context_size, self.dim)], dim=1)
        src = src.reshape(n, self.max_context_size + 1, 2, self.dim)

        # only keep un-masked positions to reduce computational cost
        src = src[attention_mask[:, 1:]]

        # add CLS (local) and pos embedding
        pos = self.atomic_type_embeds(torch.arange(0, 3, device=device)).unsqueeze(0).repeat(src.shape[0], 1, 1)
        src = torch.cat([self.cls.expand(src.size(0), 1, self.dim), src], dim=1) + pos

        src = F.dropout(src, p=self.get_option("output_dropout"), training=self.training and not output_repr)
        src = self.atomic_layer_norm(src)

        # [bs, dim]
        out = self.atom_encoder(src,
                                self.convert_mask(src.new_ones(src.size(0), src.size(1), dtype=torch.long)),
                                output_all_encoded_layers=False)[-1][:,0]

        # recover results from output based on mask
        src = out.new_zeros(n, self.max_context_size + 1, self.dim)
        src[attention_mask[:, 1:]] = out

        # when not using graph context, exit here
        if self.max_context_size == 0:
            return src[:, 0], 0

        # begin the processing of graph context with the upper transformer block
        # add CLS (global) and pos embeddings
        src = torch.cat([self.global_cls.expand(n, 1, self.dim), src], dim=1)
        pos = self.type_embeds(torch.arange(0, 3, device=device))
        src[:, 0] = src[:, 0] + pos[0].unsqueeze(0)
        src[:, 1] = src[:, 1] + pos[1].unsqueeze(0)
        src[:, 2:] = src[:, 2:] + pos[2].view(1, 1, -1)

        src = F.dropout(src, p=self.get_option("hidden_dropout"), training=self.training)
        src = self.layer_norm(src)
        out = self.transformer_encoder(src, None, self.convert_mask_rat(attention_mask))

        if output_repr:
            return out, self.convert_mask(attention_mask)

        out = out[-1][:,:2]

        # compute the mlm-like loss if needed
        if self.training and self.get_option("add_mlm_loss") and self.get_option("self_dropout") > 0.0 and self_dropout_sample.sum() > 0:
            all_entity_emb = self._entity_embedder().embed_all()
            all_entity_emb = F.dropout(all_entity_emb, p=self.get_option("output_dropout"), training=self.training)
            source_scores = self.similarity(out[:, 1], all_entity_emb, False).view(n, -1)
            self_pred_loss = F.cross_entropy(
                source_scores[self_dropout_sample], ids[self_dropout_sample], reduction='mean')
            return out[:, 0], self_pred_loss
        else:
            return out[:, 0], 0

    def convert_mask_rat(self, attention_mask):
        attention_mask = attention_mask.unsqueeze(1).repeat(1, attention_mask.size(1), 1)
        return attention_mask

    def convert_mask(self, attention_mask):
        # extend mask to Transformer format
        attention_mask = attention_mask.unsqueeze(1).unsqueeze(2)
        attention_mask = (1.0 - attention_mask.float()) * -10000.0
        return attention_mask

    def _scoring(self, s_emb, p_emb, o_emb, is_pairwise, ids, gt_ent, gt_rel):
        encoder_output, self_pred_loss = self._get_encoder_output(s_emb, p_emb, ids, gt_ent, gt_rel)
        o_emb = F.dropout(o_emb, p=self.get_option("output_dropout"), training=self.training)
        target_scores = self.similarity(encoder_output, o_emb, is_pairwise).view(p_emb.size(0), -1)
        if self.training:
            return target_scores, self_pred_loss
        else:
            return target_scores

    def score_emb(self, s_emb, p_emb, o_emb, combine: str, s, o, gt_ent=None, gt_rel=None):
        # the 'spo' combination is only used in reciprocal model
        # 'spo' prefix stands for triple-wise scoring, suffix "s"/"o" indicates direction
        if combine == 'spoo' or combine == 'sp_' or combine == 'spo':
            out = self._scoring(s_emb, p_emb, o_emb, combine.startswith('spo'), s, gt_ent, gt_rel)
        elif combine == 'spos' or combine == '_po':
            out = self._scoring(o_emb, p_emb, s_emb, combine.startswith('spo'), o, gt_ent, gt_rel)
        else:
            raise Exception("Combine {} is not supported in TrmE's score function".format(combine))
        return out

class TrmE(KgeModel):
    r"""Implementation of the TrmE KGE model."""

    def __init__(self, config: Config, dataset: Dataset, configuration_key=None):
        super().__init__(
            config, dataset, TrmEScorer, configuration_key=configuration_key
        )
        self.loss = KgeLoss.create(config)

    def forward(self, fn_name, *args, **kwargs):
        # bind entity/relation embedder to scorer to retrieve embeddings
        self._scorer._entity_embedder = self.get_s_embedder
        self._scorer._relation_embedder = self.get_p_embedder

        # call score_sp/score_po during training, score_spo/score_sp_po during inference
        scores = getattr(self, fn_name)(*args, **kwargs)

        # delete references to embedder getter
        del self._scorer._entity_embedder
        del self._scorer._relation_embedder

        if fn_name == 'get_hitter_repr':
            return scores

        if self.training:
            self_loss_w = self.get_option("self_dropout")
            # MLM-like loss is weighted by the proportion of entities sampled
            self_loss_w = self_loss_w / (1 + self_loss_w)
            return self.loss(scores[0], kwargs["gt_ent"]) + self_loss_w * scores[1] * scores[0].size(0)
        else:
            return scores

    def get_hitter_repr(self, s, p):
        s_emb = self.get_s_embedder().embed(s)
        p_emb = self.get_p_embedder().embed(p)
        return self._scorer._get_encoder_output(s_emb, p_emb, s, None, None, output_repr=True)

    def score_spo(self, s: Tensor, p: Tensor, o: Tensor, direction=None) -> Tensor:
        s_emb = self.get_s_embedder().embed(s)
        o_emb = self.get_o_embedder().embed(o)
        if direction:
            if direction == 's':
                p_emb = self.get_p_embedder().embed(p + self.dataset.num_relations())
            else:
                p_emb = self.get_p_embedder().embed(p)
            return self._scorer.score_emb(s_emb, p_emb, o_emb, "spo" + direction, s, o).view(-1)
        else:
            raise Exception(
                "The TrmE model cannot compute "
                "undirected spo scores."
            )

    def score_sp(self, s: Tensor, p: Tensor, o: Tensor = None, gt_ent=None, gt_rel=None) -> Tensor:
        s_emb = self.get_s_embedder().embed(s)
        p_emb = self.get_p_embedder().embed(p)
        if o is None:
            o_emb = self.get_o_embedder().embed_all()
        else:
            o_emb = self.get_o_embedder().embed(o)

        return self._scorer.score_emb(s_emb, p_emb, o_emb, "sp_", s, None, gt_ent, gt_rel)

    def score_po(self, p: Tensor, o: Tensor, s: Tensor = None, gt_ent=None, gt_rel=None) -> Tensor:
        if s is None:
            s_emb = self.get_s_embedder().embed_all()
        else:
            s_emb = self.get_s_embedder().embed(s)
        o_emb = self.get_o_embedder().embed(o)
        p_inv_emb = self.get_p_embedder().embed(p + self.dataset.num_relations())

        return self._scorer.score_emb(s_emb, p_inv_emb, o_emb, "_po", None, o, gt_ent, gt_rel)

    def score_sp_po(self, s: Tensor, p: Tensor, o: Tensor, entity_subset: Tensor = None) -> Tensor:
        s_emb = self.get_s_embedder().embed(s)
        p_emb = self.get_p_embedder().embed(p)
        p_inv_emb = self.get_p_embedder().embed(p + self.dataset.num_relations())
        o_emb = self.get_o_embedder().embed(o)
        if self.get_s_embedder() is self.get_o_embedder():
            if entity_subset is not None:
                all_entities = self.get_s_embedder().embed(entity_subset)
            else:
                all_entities = self.get_s_embedder().embed_all()
            sp_scores = self._scorer.score_emb(
                s_emb, p_emb, all_entities, "sp_", s, None)
            po_scores = self._scorer.score_emb(
                all_entities, p_inv_emb, o_emb, "_po", None, o)
        else:
            assert False
        return torch.cat((sp_scores, po_scores), dim=1)


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

import argparse

def main(args):
    with open(args.input) as f:
        for line in f:
            splitted_line = line.rstrip().split('|||')
            src = splitted_line[0].rstrip().lstrip().split(' ')
            tgt = splitted_line[1].rstrip().lstrip().split(' ')
            if len(src) > 1:
                continue
            print(' '.join(src).replace('\\', '') + '\t' + ' '.join(tgt).replace('\\', ''))

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--input', '-i', help='path to input file')
    args = parser.parse_args()
    main(args)


#24.  Given an unsorted integer array as input,  return the number of perfect squares in it.
import math
def perfectSquare(N):
    flag = False
    M = math.sqrt(N)
    x = round(M)
    if ((M-x)==0):
        flag = True
    return flag

#print(perfectSquare(16))
def filter_perfectSquare(array):
    for i in array:
        if (perfectSquare(i)):
            print (i)

array = [24,16,90,25,75,64]
filter_perfectSquare(array)


class NaZakupy:
    nazwa_produktu=""
    ilosc=0
    jednostka_miary=""
    cena_jed=0

    def __init__(self, nazwa_produktu, ilosc, jednostka_miary, cena_jedn):
        self.nazwa_produktu = nazwa_produktu
        self.ilosc = ilosc
        self.jednostka_miary = jednostka_miary
        self.cena_jedn = cena_jedn

    def wyswietl_produkty(self):
        print("Nazwa: ", self.nazwa_produktu)
        print("Ilosc: ", self.ilosc)
        print("Jednostka: ", self.jednostka_miary)
        print("Cena: ", self.cena_jedn)

    def ile_produktu(self):
        print(self.ilosc, self.jednostka_miary, sep=" ")

    def ile_kosztuje(self):
        return self.ilosc*self.cena_jedn

produkt = NaZakupy("Mąka", 4, "kg", 3.99)
produkt.wyswietl_produkty()
produkt.ile_produktu()
print(produkt.ile_kosztuje())


"""
Functions for the view code
"""
from django.shortcuts import render, redirect, get_object_or_404, reverse
from django.views import generic, View
from django.http import HttpResponseRedirect
from django.contrib import messages
from .models import ArtPrint
from .forms import SubmitPrintForm

class PrintsPage(generic.ListView):
    """
    View prints page.
    """
    model = ArtPrint
    queryset = ArtPrint.objects.filter(status=1).order_by('-created_on')
    template_name = 'prints.html'
    paginate_by = 12

# Function built using instructions from "Hello Django",
# "I think therefore I blog",
# Stackoverflow, a fellow student,
# And a comment on slack - credited in README.
def submit_art_print(request):
    """
    View for print submission page.
    """
    if request.method == 'POST':
        submission_form = SubmitPrintForm(request.POST, request.FILES)
        if submission_form.is_valid():
            submission_form.instance.artist = request.user
            submission_form.save()
            messages.success(
                request, "Faantastic! Please wait while we review it!.")
            return redirect('prints')
        else:
            submission_form = SubmitPrintForm()

    return render(
        request,
        'submit-print.html',
        {
            'submission_form': SubmitPrintForm(),
        },
    )

def edit_art_print(request, slug):
    """
    Edit a submitted artprint
    """
    prints = get_object_or_404(ArtPrint, slug=slug)
    edit_form = SubmitPrintForm(request.POST or None, instance=prints)
    context = {
        'edit_form': edit_form,
        'prints': prints
    }

    if request.method == 'POST':
        edit_form = SubmitPrintForm(
            request.POST, request.FILES, instance=prints)
        if edit_form.is_valid():
            prints = edit_form.save(commit=False)
            prints.artist = request.user
            prints.save()
            return redirect('prints')
    else:
        edit_form = SubmitPrintForm(instance=prints)

    return render(request, 'edit-print.html', context)

# Instructed by "Hello Django"
def delete_art_print(request, slug):
    """
    Delete a submitted artprint
    """
    prints = get_object_or_404(ArtPrint, slug=slug)
    prints.delete()
    return redirect('prints')

class PrintDetails(View):
    """
    Render the individual print
    to the browser.
    """
    def get(self, request, slug, *args, **kwargs):
        """
        Obtain print & check for likes.
        """
        queryset = ArtPrint.objects.filter(status=1)
        prints = get_object_or_404(queryset, slug=slug)
        liked = False
        if prints.likes.filter(id=self.request.user.id).exists():
            liked = True

        return render(
            request,
            'print-details.html',
            {
                'prints': prints,
                'liked': liked,
            }
        )

# Class used from "I think therefore I blog" walkthrough.
class LikeArtPrint(View):
    """
    Allow a user to like an
    art print submission
    """
    def post(self, request, slug):
        """
        Check for user.
        And like/unlike a post
        """
        prints = get_object_or_404(ArtPrint, slug=slug)

        if prints.likes.filter(id=request.user.id).exists():
            prints.likes.remove(request.user)
        else:
            prints.likes.add(request.user)

        return HttpResponseRedirect(reverse('print_detail', args=[slug]))


# blur.py
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
from scipy.sparse import lil_matrix

# read image file
fname = 'chill.jpg'
image = Image.open(fname).convert("L")
arr = np.asarray(image)
arr.setflags(write=1)

# initialize blurring matrix
m = arr.shape[0]
n = arr.shape[1]
dofs = m * n
A = lil_matrix((dofs, dofs))
A.setdiag(np.ones(dofs))
for i in range(1, m - 1):
    for j in range(1,n-1):
        A[n*i+j,n*i+j] = 1./2.
        A[n*i+j,n*(i-1)+j] = 1./16.
        A[n*i+j,n*(i+1)+(j-1)] = 1./16.
        A[n*i+j,n*(i-1)+(j+1)] = 1./16.
        A[n*i+j,n*i+(j-1)] = 1./16.

        A[n*i+j,n*i+(j+1)] = 1./16.
        A[n*i+j,n*(i+1)+j] = 1./16.
        A[n*i+j,n*(i+1)+(j-1)] = 1./16.
        A[n*i+j,n*(i+1)+(j+1)] = 1./16.
A = A.tocsr()

# Blurring function - converts image to a vector, multiplies by
# the blurring matrix, and copies the result back into the image
def blur():
    x = np.zeros(shape=(dofs,1))
    for i in range(0,m):
        for j in range(0,n):
            x[n*i+j] = arr[i,j]

    y = A.dot(x)
    for i in range(0,m):
        for j in range(0,n):
            arr[i,j] = y[n*i+j]

# Execute the blurring function 20 times
for i in range(0,20):
    blur()

# Display the blurred image
plt.imshow(arr,cmap='gray')
plt.show()


# -*- coding:utf-8 -*-
"""
dialogue manager for hierarchical reinforcement learning policy
"""

import copy
import random
from collections import deque
import sys, os
import time

sys.path.append(os.getcwd().replace("src/dialogue_system/dialogue_manager",""))

from src.dialogue_system.state_tracker import StateTracker as StateTracker
from src.dialogue_system import dialogue_configuration
from src.dialogue_system.disease_classifier import dl_classifier
from src.dialogue_system.agent.utils import state_to_representation_last, reduced_state_to_representation_last
import numpy as np
from sklearn import svm
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier

from sklearn.model_selection import GridSearchCV
from sklearn.metrics import f1_score, classification_report, accuracy_score
import pickle
import torch
import torch.nn.functional as F

class DialogueManager_HRL(object):
    """
    Dialogue manager of this dialogue system.
    """
    def __init__(self, user, agent, parameter):

        self.state_tracker = StateTracker(user=user, agent=agent, parameter=parameter)

        self.parameter = parameter
        self.experience_replay_pool = deque(maxlen=self.parameter.get("experience_replay_pool_size"))
        self.inform_wrong_disease_count = 0
        self.dialogue_output_file = parameter.get("dialogue_file")
        self.save_dialogue = parameter.get("save_dialogue")
        self.action_history = []
        self.master_action_history = []
        self.now_imp_recall = 0
        self.lower_action_history = []
        self.group_id_match = 0
        self.repeated_action_count = 0
        self.reward_for_activate_doctor_amend = 0
        self.slot_set = pickle.load(open(self.parameter.get("slot_set"), 'rb'))
        self.disease_symptom = pickle.load(open(self.parameter.get("disease_symptom"),'rb'))
        if 'disease' in self.slot_set.keys():
            self.slot_set.pop('disease')
        self.id2disease = {}
        self.disease2id = {}
        for disease, v in self.disease_symptom.items():
            self.id2disease[v['index']] = disease
            self.disease2id[disease] = v['index']
        self.disease_replay = {'train': deque(maxlen=50000), 'test': deque(maxlen=500)}
        self.worker_right_inform_num = 0
        self.acc_by_group = {x:[0,0,0] for x in ['12', '13', '14', '19', '1', '4', '5', '6', '7',
        'h12', 'h13', 'h14', 'h19', 'h1', 'h4', 'h5', 'h6', 'h7']}
        # 这里的三维向量分别表示inform的症状正确的个数、group匹配正确的个数、隶属于某个group的个数

        if self.parameter.get("train_mode")==False:
            self.test_by_group = {x:[0,0,0] for x in ['12', '13', '14', '19', '1', '4', '5', '6', '7','h12', 'h13', 'h14', 'h19', 'h1', 'h4', 'h5', 'h6', 'h7']}
            #这里的三维向量分别表示成功次数、group匹配正确的个数、隶属于某个group的个数
            self.disease_record = []
            self.lower_reward_by_group = {x: [] for x in ['12', '13', '14', '19', '1', '4', '5', '6', '7','h12', 'h13', 'h14', 'h19', 'h1', 'h4', 'h5', 'h6', 'h7']}
            # self.master_index_by_group = {x:[] for x in ['12', '13', '14', '19', '1', '4', '5', '6', '7']}
            self.master_index_by_group = []
            self.symptom_by_group = {x: [0,0] for x in ['12', '13', '14', '19', '1', '4', '5', '6', '7','h12', 'h13', 'h14', 'h19', 'h1', 'h4', 'h5', 'h6', 'h7']}

    def next(self, greedy_strategy, save_record, index,mode='train'):
        """
        The next two turn of this dialogue session. The agent will take action first and then followed by user simulator.
        :param save_record: bool, save record?
        :param train_mode: bool, True: the purpose of simulation is to train the model, False: just for simulation and the
                           parameters of the model will not be updated.
        :return: immediate reward for taking this agent action.
        """
        # Agent takes action.
        def delete_item_from_dict(item, value):
            new_item = {}
            for k, v in item.items():
                if v != value: new_item[k] = v
            return new_item
        # end1 = time.time()
        lower_reward = 0
        state = self.state_tracker.get_state()
        group_id = self.state_tracker.user.goal["group_id"]
        self.master_action_space = self.state_tracker.agent.master_action_space
        state_slots = self.make_ml_features(state["current_slots"]["inform_slots"])
        state_cv_rep = self.cv.transform([state_slots]).toarray()
        all_Y, pre_disease = self.model.predict(state_cv_rep)
        disease_conf = F.softmax(all_Y).max(-1)[0].item()
        early_stop = False
        if disease_conf > 0.99:
            early_stop = True
        agent_action, master_action_index, activator_action_index, lower_action_index = self.state_tracker.agent.next(state=state, turn=self.state_tracker.turn,
                                                                                greedy_strategy=greedy_strategy, index=index,
                                                                                disease_tag = self.state_tracker.user.goal)
        # end2 = time.time()
        # print(self.state_tracker.user.goal["disease_tag"])
        if agent_action == -1 :
            lower_action = "ban activate human"
            action_type = 'ban'
        elif len(agent_action["request_slots"]) > 0:
            lower_action = list(agent_action["request_slots"].keys())[0]
            assert len(list(agent_action["request_slots"].keys())) == 1
            action_type = "symptom"
        elif len(agent_action["inform_slots"]) > 0:
            lower_action = list(agent_action["inform_slots"].keys())[0]
            assert len(list(agent_action["inform_slots"].keys()))==1
            action_type = "disease"
            #print("#########")
        else:
            lower_action = "return to master"
            assert agent_action["action"] == 'return'
            action_type = 'return'
            #print("***************************************************************************************")
        # print(state['turn'])
        # print("self.state_tracker.turn",self.state_tracker.turn)
        # print("['turn']",self.state_tracker.get_state()['turn'])
        # if len(self.state_tracker.user.goal['goal']['implicit_inform_slots']) == 0 or len(delete_item_from_dict(self.state_tracker.get_state()["current_slots"]["inform_slots"],dialogue_configuration.I_DO_NOT_KNOW)) == len(self.state_tracker.user.goal['goal']['explicit_inform_slots']) + len(self.state_tracker.user.goal['goal']['implicit_inform_slots']):
        #     self.auto_diagnose =True
        if self.parameter.get("disease_as_action")==False:
            if save_record == True:
                condition = False
            else:
                condition = (state['turn']==self.parameter.get("max_turn")*2 or action_type == 'ban')
            if action_type == "disease" or condition or early_stop:# or lower_action in self.lower_action_history:
                #once the action is repeated or the dialogue reach the max turn, then the classifier will output the predicted disease
                state_rep = self.current_state_representation(state)
                disease = self.state_tracker.user.goal["disease_tag"]
                state_slots = self.make_ml_features(state["current_slots"]["inform_slots"])
                state_cv_rep = self.cv.transform([state_slots]).toarray()
                # print(state_slots)
                # print(state_cv_rep)
                # assert 0
                # state_slots1 = self.make_ml_features(self.state_tracker.user.goal['goal']['explicit_inform_slots'])
                # state_cv_rep_exp = self.cv.transform([state_slots1]).toarray()
                # state_slots2 = self.make_ml_features(self.state_tracker.user.goal['goal']['implicit_inform_slots'])

                # state_cv_rep_all = self.cv.transform([state_slots1+' '+state_slots2]).toarray()

                # master_state_rep = reduced_state_to_representation_last(state=state,
                #                                                 slot_set=self.state_tracker.agent.slot_set,
                #                                                 parameter=self.parameter)

                all_Y, pre_disease = self.model.predict(state_cv_rep)

                if mode == 'train':
                    self.disease_replay['train'].append((state_cv_rep[0], self.disease2id[disease]))
                    # self.disease_replay['train'].append((state_cv_rep_exp[0], self.disease2id[disease]))
                    # self.disease_replay['train'].append((state_cv_rep_all[0], self.disease2id[disease]))
                    # self.disease_replay['train'].append((master_state_rep_hide_imp, self.disease2id[disease]))
                else:
                    self.disease_replay['test'].append((state_cv_rep[0], self.disease2id[disease]))
                lower_action_index = -1
                master_action_index = 2
                agent_action = {'action': 'inform', 'inform_slots': {"disease":self.id2disease[pre_disease[0]]}, 'request_slots': {},"explicit_inform_slots":{}, "implicit_inform_slots":{}}
                #print(agent_action)
                if self.parameter.get("train_mode") == False:
                    self.disease_record.append([disease,self.id2disease[pre_disease[0]]])
        # end3 = time.time()
        if action_type == 'ban':
            self.state_tracker.state["turn"] = self.state_tracker.turn
            self.state_tracker.turn += 1
        else:
            self.state_tracker.state_updater(agent_action=agent_action)
        # print("turn:%2d, state for agent:\n" % (state["turn"]) , json.dumps(state))

        # User takes action.

        user_action, reward, episode_over, dialogue_status = self.state_tracker.user.next(agent_action=agent_action,turn=self.state_tracker.turn)
        # end4 = time.time()
        # print(reward)
        inquire_state = False
        if user_action == -1:
            self.state_tracker.state["turn"] = self.state_tracker.turn
            self.state_tracker.turn += 1
        else:
            if user_action["action"] == "inform":
                inquire_state = True
            self.state_tracker.state_updater(user_action=user_action)
            # if self.state_tracker.turn >40 :
            #     print(user_action["action"])
            #     print(self.state_tracker.turn)
        # print("turn:%2d, update after user :\n" % (state["turn"]), json.dumps(state))
        #print('status', dialogue_status)

        # if self.state_tracker.turn == self.state_tracker.max_turn:
        #     episode_over = True

        if master_action_index < 2:
            self.master_action_history.append(self.master_action_space[activator_action_index])
        #print(self.state_tracker.get_state()["turn"])
        #print(master_action_index)

        if self.parameter.get('agent_id').lower()=='agenthrljoint2' and lower_action in self.lower_action_history:
            lower_reward = self.parameter.get("reward_for_repeated_action")
            print("################################")
        self.reward_for_activate_doctor_amend = 0
        if self.parameter.get("agent_id") == "agenthrljoint2" and self.parameter.get("disease_as_action")==False and action_type != "disease":
            #print(master_action_index)
            #print('lower_action',lower_action)
            reward, lower_reward = self.next_by_hrl_joint2(dialogue_status, lower_action, state, activator_action_index, group_id, episode_over, reward)
            if self.state_tracker.agent.subtask_terminal is True and master_action_index == 1:
                another_state = self.state_tracker.agent.parallel_next(self.state_tracker.user.goal)
                # print(self.state_tracker.agent.master_state["current_slots"]["inform_slots"])
                # print(another_state)
                # print(self.state_tracker.get_state()["current_slots"]["inform_slots"])
                # print("goal", self.state_tracker.user.goal['goal']['implicit_inform_slots'])
                disease = self.state_tracker.user.goal["disease_tag"]
                disease_id = self.disease2id[disease]
                cur_state = copy.deepcopy(self.state_tracker.get_state()["current_slots"]["inform_slots"])
                another_state_rep = self.cv.transform([self.make_ml_features(another_state)]).toarray()
                all_Y1, pre_disease1 = self.model.predict(another_state_rep)
                Y1 = F.softmax(all_Y1, dim = 1).detach().cpu().numpy()[0]
                cur_state_rep = self.cv.transform([self.make_ml_features(cur_state)]).toarray()
                all_Y2, pre_disease2 = self.model.predict(cur_state_rep)
                Y2 = F.softmax(all_Y2, dim = 1).detach().cpu().numpy()[0]
                # print(disease_id)
                # print(Y1)
                # print(Y2)
                if disease_id != pre_disease1[0] and disease_id == pre_disease2[0]:
                    # print('*')
                    self.reward_for_activate_doctor_amend = 10 * 2
                elif disease_id != pre_disease1[0] and disease_id != pre_disease2[0] and Y2[disease_id] > Y1[disease_id]:
                    # print('#')
                    self.reward_for_activate_doctor_amend = 10
                else:
                    # print('@')
                    self.reward_for_activate_doctor_amend = 0

        else:
            #print(agent_action)
            #print('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
            if lower_action in self.action_history:
                reward = self.parameter.get("reward_for_repeated_action")
                print("************************")
                self.repeated_action_count += 1
                episode_over = True
            else:
                self.action_history.append(lower_action)
                # print('lower_action',lower_action)
                # print('self.action_history',self.action_history)
                # lower_action disease
                # self.action_history ['disease']

        if dialogue_status == dialogue_configuration.DIALOGUE_STATUS_INFORM_WRONG_DISEASE:
            self.inform_wrong_disease_count += 1

        # if dialogue_status == dialogue_configuration.DIALOGUE_STATUS_SUCCESS:
        #     print("success:", self.state_tracker.user.state)
        # elif dialogue_status == dialogue_configuration.DIALOGUE_STATUS_NOT_COME_YET:
        #     print("not come:", self.state_tracker.user.state)
        # else:
        #     print("failed:", self.state_tracker.user.state)
        # if len(self.state_tracker.user.state["rest_slots"].keys()) ==0:
        #     print(self.state_tracker.user.goal)
        #     print(dialogue_status,self.state_tracker.user.state)
        #print(reward)
        if len(self.state_tracker.user.goal['goal']['implicit_inform_slots']) == 0:
            self.now_imp_recall = 1
        else:
            self.now_imp_recall = float(float(len(delete_item_from_dict(self.state_tracker.get_state()["current_slots"]["inform_slots"],dialogue_configuration.I_DO_NOT_KNOW)) - len(self.state_tracker.user.goal['goal']['explicit_inform_slots'])) / len(self.state_tracker.user.goal['goal']['implicit_inform_slots']))
        if save_record is True and self.auto_diagnose is False:

            #print(self.action_history)
            if self.parameter.get("initial_symptom") is False or self.state_tracker.get_state()["turn"]==2:
                self.record_training_sample(
                    state=state,
                    agent_action=lower_action_index,
                    next_state=self.state_tracker.get_state(),
                    reward=reward,
                    episode_over=episode_over,
                    lower_reward = lower_reward,
                    master_action_index = master_action_index,
                    activator_action_index = activator_action_index,
                    imp_recall = self.now_imp_recall,
                    state_turn = self.state_tracker.turn - 2
                    )
        # end5 = time.time()
        # Record machine inquire acc
        disease = self.state_tracker.user.goal["disease_tag"]
        disease_id = self.disease2id[disease]
        cur_state = copy.deepcopy(self.state_tracker.get_state()["current_slots"]["inform_slots"])
        cur_state_rep = self.cv.transform([self.make_ml_features(cur_state)]).toarray()
        all_Y2, pre_disease2 = self.model.predict(cur_state_rep)
        if disease_id == pre_disease2[0]:
            return_disease = 1
            # print('1')
        else:
            return_disease = 0
        # Output the dialogue.
        slots_proportion_list = []
        if episode_over == True:
            self.action_history = []
            self.lower_action_history = []
            current_slots = copy.deepcopy(state["current_slots"]["inform_slots"])
            imp_acc = 0
            real_implicit_slots = len(self.state_tracker.user.goal['goal']['implicit_inform_slots'])
            real_explicit_slots = len(self.state_tracker.user.goal['goal']['explicit_inform_slots'])
            for values in current_slots.values():
                if values != dialogue_configuration.I_DO_NOT_KNOW:
                    imp_acc += 1
            num_of_all_slots = len(current_slots)
            slots_proportion_list.append(imp_acc - real_explicit_slots)  #only imp patient have
            slots_proportion_list.append(self.state_tracker.agent.ban_human)   #all ban
            slots_proportion_list.append(real_implicit_slots)    #all imp
            try:
                last_master_action = self.master_action_history[-1]
            except:
                last_master_action = -1
            if self.save_dialogue == True :
                state = self.state_tracker.get_state()
                goal = self.state_tracker.user.get_goal()
                # self.__output_dialogue(state=state, goal=goal, master_history=self.master_action_history)
            if last_master_action == group_id:
                self.group_id_match += 1
            self.master_action_history = []
            # if self.parameter.get("train_mode") == False and self.parameter.get("agent_id").lower()=="agenthrlnew2":
            #     #self.test_by_group[group_id][2] += 1
            #     #if last_master_action == group_id:
            #     #    self.test_by_group[group_id][1] += 1
            #     #    if reward == self.parameter.get("reward_for_success"):
            #     #        self.test_by_group[group_id][0] += 1
            #     if action_type == "disease":
            #         self.test_by_group[last_master_action][2] += 1
            #         if last_master_action == group_id:
            #             self.test_by_group[last_master_action][1] += 1
            #             if reward == self.parameter.get("reward_for_success"):
            #                 self.test_by_group[last_master_action][0] += 1
        # end = time.time()

        # print('程序运行时间为: %s Seconds'%(end-end5))
        # print('程序运行时间为: %s Seconds'%(end5-end4))
        # print('程序运行时间为: %s Seconds'%(end4-end3))
        # print('程序运行时间为: %s Seconds'%(end3-end2))
        # print('程序运行时间为: %s Seconds'%(end2-end1))
        # assert 0
        return reward, episode_over, dialogue_status, slots_proportion_list, inquire_state, return_disease

    def next_by_hrl_joint2(self, dialogue_status, lower_action, state, master_action_index, group_id, episode_over, reward):
        '''
                    self.acc_by_group[group_id][2] += 1
                    if self.master_action_space[master_action_index] == group_id:
                        self.acc_by_group[group_id][1] += 1
                        if self.lower_reward_function(state=state, next_state=self.state_tracker.get_state()) > 0:
                            self.acc_by_group[group_id][0] += 1
                    '''
        alpha = self.parameter.get("weight_for_reward_shaping")
        if dialogue_status == dialogue_configuration.DIALOGUE_STATUS_REACH_MAX_TURN:
            self.repeated_action_count += 1

        # if action_type == "return":
        #    lower_reward = alpha/2 * self.worker_right_inform_num
        # if action_type == "symptom" and self.state_tracker.agent.subtask_terminal:  #reach max turn
        #    lower_reward = -alpha

        lower_reward = alpha * self.lower_reward_function(state=state, next_state=self.state_tracker.get_state())
        if lower_action in self.lower_action_history:  # repeated action
            print(lower_action)
            assert 0
            lower_reward = -alpha
            self.state_tracker.agent.subtask_terminal = True
            # episode_over = True
            # self.repeated_action_count += 1
            reward = self.parameter.get("reward_for_repeated_action")
        # elif self.state_tracker.agent.subtask_terminal is False or lower_reward>0:
        else:
            ## 要么是44，要么是0
            lower_reward = max(0, lower_reward)
            if lower_reward > 0:
                self.state_tracker.agent.subtask_terminal = True
                self.worker_right_inform_num += 1
                #print(alpha,lower_reward)
                lower_reward = alpha
            self.lower_action_history.append(lower_action)
            #print("###############################",self.lower_action_history)
            # if self.parameter.get("train_mode")==False:
            #    self.lower_reward_by_group[self.master_action_space[master_action_index]].append(lower_reward)
        # else:
        #    lower_reward = -alpha
        # if self.lower_reward_function(state=state, next_state=self.state_tracker.get_state())>0:
        #   self.worker_right_inform_num += 1
        # if  dialogue_status == dialogue_configuration.DIALOGUE_STATUS_REACH_MAX_TURN:

        if episode_over == True:
            self.state_tracker.agent.subtask_terminal = True
            self.state_tracker.agent.subtask_turn = 0
            '''
            #reward = alpha/2 * self.worker_right_inform_num - 2
            if dialogue_status != dialogue_configuration.DIALOGUE_STATUS_REACH_MAX_TURN:
                if self.master_action_space[master_action_index] == group_id:
                    reward = 10
                else:
                    reward = -1
            self.worker_right_inform_num = 0
            #self.lower_action_history = []
            '''
        elif self.state_tracker.agent.subtask_terminal:
            # reward = alpha / 2 * self.worker_right_inform_num - 2
            '''
            if self.master_action_space[master_action_index] == group_id:
                reward = 10
            else:
                reward = -1
            '''
            self.worker_right_inform_num = 0
            if self.parameter.get("train_mode") == False:
                self.master_index_by_group.append([group_id, master_action_index])
            # self.lower_action_history = []
            #print(reward,lower_reward)
        return reward, lower_reward

    def initialize(self, dataset, goal_index=None):
        self.state_tracker.initialize()
        self.inform_wrong_disease_count = 0
        user_action = self.state_tracker.user.initialize(dataset=dataset, goal_index=goal_index)
        self.state_tracker.state_updater(user_action=user_action)
        self.state_tracker.agent.initialize()
        self.auto_diagnose = False
        # self.group_id_match = 0
        # print("#"*30 + "\n" + "user goal:\n", json.dumps(self.state_tracker.user.goal))
        # state = self.state_tracker.get_state()
        # print("turn:%2d, initialized state:\n" % (state["turn"]), json.dumps(state))

    def record_training_sample(self, state, agent_action, reward, next_state, episode_over, **kwargs):
        if self.parameter.get("agent_id").lower() in ["agenthrljoint",'agenthrljoint2']:
            lower_reward = kwargs.get("lower_reward")
            master_action_index = kwargs.get("master_action_index")
            activator_action_index = kwargs.get("activator_action_index")
            imp_recall = kwargs.get("imp_recall")
            state_turn = kwargs.get("state_turn")
            self.state_tracker.agent.record_training_sample(state, agent_action, reward, next_state, episode_over, lower_reward, master_action_index, activator_action_index,imp_recall, state_turn, self.reward_for_activate_doctor_amend)
        else:
            self.state_tracker.agent.record_training_sample(state, agent_action, reward, next_state, episode_over)

    def record_prioritized_training_sample(self, state, agent_action, reward, next_state, episode_over, TD_error, **kwargs):
        if self.parameter.get("agent_id").lower() in ["agenthrljoint",'agenthrljoint2']:
            lower_reward = kwargs.get("lower_reward")
            self.state_tracker.agent.record_prioritized_training_sample(state, agent_action, reward, next_state,
                                                                        episode_over, TD_error, lower_reward)
        else:
            self.state_tracker.agent.record_prioritized_training_sample(state, agent_action, reward, next_state, episode_over, TD_error)

    def set_agent(self,agent):
        self.state_tracker.set_agent(agent=agent)

    def train(self):
        self.state_tracker.agent.train_dqn()
        self.state_tracker.agent.update_target_network()

    def __output_dialogue(self,state, goal, master_history):
        history = state["history"]
        file = open(file=self.dialogue_output_file,mode="a+",encoding="utf-8")
        file.write("User goal: " + str(goal)+"\n")
        for turn in history:
            #print(turn)
            try:
                speaker = turn["speaker"]
            except:
                speaker = 'agent'
            action = turn["action"]
            inform_slots = turn["inform_slots"]
            request_slots = turn["request_slots"]
            if speaker == "agent":
                try:
                    master_action = master_history.pop(0)
                    file.write(speaker + ": master+ " + str(master_action) +' +'+ action + "; inform_slots:"
                               + str(inform_slots) + "; request_slots:" + str(request_slots) + "\n")
                except:
                    file.write(speaker + ": master+ " + ' +' + action + "; inform_slots:" + str(inform_slots)
                               + "; request_slots:" + str(request_slots) + "\n")
            else:
                file.write(speaker + ": " + action + "; inform_slots:" + str(inform_slots) + "; request_slots:" + str(request_slots) + "\n")
        file.write("\n\n")
        assert len(master_history) == 0
        file.close()

    def lower_reward_function(self, state, next_state):
        """
        The reward for lower agent
        :param state:
        :param next_state:
        :return:
        """
        def delete_item_from_dict(item, value):
            new_item = {}
            for k, v in item.items():
                if v != value: new_item[k] = v
            return new_item

        # slot number in state.
        slot_dict = copy.deepcopy(state["current_slots"]["inform_slots"])
        slot_dict = delete_item_from_dict(slot_dict, dialogue_configuration.I_DO_NOT_KNOW)

        next_slot_dict = copy.deepcopy(next_state["current_slots"]["inform_slots"])
        next_slot_dict = delete_item_from_dict(next_slot_dict, dialogue_configuration.I_DO_NOT_KNOW)
        gamma = self.parameter.get("gamma")
        return gamma * len(next_slot_dict) - len(slot_dict)
        #return max(0, gamma * len(next_slot_dict) - len(slot_dict))

    def current_state_representation(self, state):
        """
        The state representation for the input of disease classifier.
        :param state: the last dialogue state before fed into disease classifier.
        :return: a vector that has equal length with slot set.
        """
        assert 'disease' not in self.slot_set.keys()
        state_rep = [0]*len(self.slot_set)
        current_slots = copy.deepcopy(state['current_slots'])
        if self.parameter.get('data_type') == 'simulated':
            for slot, value in current_slots['inform_slots'].items():
                if value == True:
                    state_rep[self.slot_set[slot]] = 1
                #elif value == "I don't know.":
                #    state_rep[self.slot_set[slot]] = -1
                #else:
                #    print(value)
                #    raise ValueError("the slot value of inform slot is not among True and I don't know")
            #print(state_rep)
        elif self.parameter.get('data_type') == 'real':
            for slot, value in current_slots['inform_slots'].items():
                if value == True:
                    state_rep[self.slot_set[slot]] = 1
                elif value == False:
                    state_rep[self.slot_set[slot]] = -1
        return state_rep

    def current_state_representation_both(self, state):
        assert 'disease' not in self.slot_set.keys()
        state_rep = np.zeros((len(self.slot_set.keys()), 3))
        current_slots = copy.deepcopy(state['current_slots'])
        #for slot, value in current_slots['inform_slots'].items():
        for slot in self.slot_set:
            if slot in current_slots['inform_slots']:
                if current_slots['inform_slots'][slot] == True:
                    state_rep[self.slot_set[slot],:] = [1,0,0]
                elif current_slots['inform_slots'][slot] == dialogue_configuration.I_DO_NOT_KNOW:
                    state_rep[self.slot_set[slot],:] = [0,1,0]
                else:
                    state_rep[self.slot_set[slot],:] = [0,0,1]
            else:
                state_rep[self.slot_set[slot],:] = [0,0,1]
                #raise ValueError("the slot value of inform slot is not among True and I don't know")
        print(state_rep)
        state_rep1 = state_rep.reshape(1, len(self.slot_set.keys()) * 3)[0]
        return state_rep1

    def make_ml_features(self, state_slots):
        feature = []
        for k,v in state_slots.items():
            if v == True:
                feature.append(k+'-Positive')
            elif v == False:
                feature.append(k+'-Negative')
        return ' '.join(feature)

    def train_ml_classifier(self):
        goal_set = pickle.load(open(self.parameter.get("goal_set"),'rb'))
        disease_y = []
        total_set = random.sample(goal_set['train'], 5000)

        slots_exp = np.zeros((len(total_set), len(self.slot_set)))
        for i, dialogue in enumerate(total_set):
            tag = dialogue['disease_tag']
            # tag_group=disease_symptom1[tag]['symptom']
            disease_y.append(tag)
            goal = dialogue['goal']
            explicit = goal['explicit_inform_slots']
            for exp_slot, value in explicit.items():
                try:
                    slot_id = self.slot_set[exp_slot]
                    if value == True:
                        slots_exp[i, slot_id] = '1'
                except:
                    pass

        self.model = svm.SVC(kernel='linear', C=1)
        self.model.fit(slots_exp, disease_y)

    def build_deep_learning_classifier(self):
        # for index in ['1', '4', '5', '6', '7','12', '13', '14', '19']:
        #     self.dl_model[index] = dl_classifier(input_size=len(self.slot_set), hidden_size=256,
        #                             output_size=len(self.disease_symptom),
        #                             parameter=self.parameter)
        # print(self.dl_model.values())
        # assert 0
        # if self.parameter.get("fix_9_classifier") is True:
        #     self.dl_model['1'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309185708_agenthrljoint2_T22_ss100_lr0.0005_cp20_G1_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.822_r54.252_t41.0_mr0.0_mr2-0.624_e-24.pkl")
        #     self.dl_model['4'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309195246_agenthrljoint2_T22_ss100_lr0.0005_cp20_G4_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.956_r63.096_t41.0_mr0.0_mr2-0.653_e-28.pkl")
        #     self.dl_model['5'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309200038_agenthrljoint2_T22_ss100_lr0.0005_cp20_G5_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.732_r48.312_t41.0_mr0.0_mr2-0.73_e-30.pkl")
        #     self.dl_model['6'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309201124_agenthrljoint2_T22_ss100_lr0.0005_cp20_G6_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.86_r56.76_t41.0_mr0.0_mr2-0.747_e-22.pkl")
        #     self.dl_model['7'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309205257_agenthrljoint2_T22_ss100_lr0.0005_cp20_G7_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.687_r45.342_t41.0_mr0.0_mr2-0.866_e-20.pkl")
        #     self.dl_model['12'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309205854_agenthrljoint2_T22_ss100_lr0.0005_cp20_G12_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.769_r50.754_t41.0_mr0.0_mr2-0.857_e-35.pkl")
        #     self.dl_model['13'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309214328_agenthrljoint2_T22_ss100_lr0.0005_cp20_G13_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.888_r58.608_t41.0_mr0.0_mr2-0.717_e-41.pkl")
        #     self.dl_model['14'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309214337_agenthrljoint2_T22_ss100_lr0.0005_cp20_G14_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.907_r59.862_t41.0_mr0.0_mr2-0.733_e-50.pkl")
        #     self.dl_model['19'].restore_model("/home/zxh/new_for_mr2/src/model/DQN/checkpoint/0309215543_agenthrljoint2_T22_ss100_lr0.0005_cp20_G19_beta-0.0_smt3_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-66_mls0_gamma0.95_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataSynthetic_Dataset_RID0/classifier/model_d10agenthrljoint2_s0.835_r55.11_t41.0_mr0.0_mr2-0.671_e-52.pkl")
        self.model = dl_classifier(input_size=62 , hidden_size=256,
                                    output_size=len(self.disease_symptom),
                                    parameter=self.parameter)
        self.cv = CountVectorizer(tokenizer=tokenizer)
        features = []
        #'哭闹-Positive 脱水-Positive 稀便-Positive 腹泻-Positive'
        for goal in self.state_tracker.user.goal_set['train']:
            state_solts = copy.deepcopy(goal['goal']['explicit_inform_slots'])
            state_solts.update(goal['goal']['implicit_inform_slots'])
            feature = self.make_ml_features(state_solts)
            features.append(feature)
        _x_train = self.cv.fit_transform(features)
        # ex = self.cv.transform(['哭闹-Positive 脱水-Negative 稀便-Positive' ]).toarray()
        # print(len(ex[0]))
        # assert 0
        # self.model_classifier_group = dl_classifier(input_size=len(self.slot_set) * 3, hidden_size=256,
        #                             output_size=9,
        #                             parameter=self.parameter)
        # saved_model = '/home/zxh/HRL_ppo/src/model/DQN/checkpoint/0516214511_agenthrljoint2_DA0.7_RFH-14_ST3_T20_ss200_lr0.0005_wfrs10.0_RFS15_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-44_mls0_gamma1_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_dtft0_ird0_ubc0.985_lbc1e-10_dataDxy_Dataset_RID0/classifier/s0.875_r13.125_t2.587_aah1.856_mr2-1.0_e-87.pkl'
        saved_model = '/home/zxh/HRL_ppo/src/dialogue_system/run/disease_classifier0.894231.pkl'
        self.model.restore_model(saved_model)
        if self.parameter.get("train_mode") == False:
            temp_path = self.parameter.get("saved_model")
            path_list = temp_path.split('/')
            path_list.insert(-1, 'classifier')
            saved_model = '/'.join(path_list)
            # saved_model = '/home/zxh/HRL/src/model/DQN/checkpoint/0502170050_agenthrljoint2_DA0.7_RFH-44_ST3_T20_ss100_lr0.0005_RFS66_RFF0_RFNCY0.0_RFIRS0_RFRA-44_RFRMT-44_mls0_gamma1_gammaW0.9_epsilon0.1_awd0_crs0_hwg0_wc0_var0_sdai0_wfrs44.0_dtft0_ird0_ubc0.985_lbc1e-10_dataMuzhi_Dataset_RID0/classifier/s0.768_r50.662_t16.965_aah0.732_mr2-0.976_e-45.pkl'
            self.model.restore_model(saved_model)
            self.model.eval_mode()
    def train_deep_learning_classifier(self, epochs):
        best_test_acc = self.model.test(test_batch=self.disease_replay['test'])
        print('best_test_acc',best_test_acc)
        loss = {}
        loss["loss"] = 0.0
        test_acc = 0
        best_model = copy.deepcopy(self.model.model)
        for iter in range(epochs):

            try:
                batch = random.sample(self.disease_replay['train'], min(self.parameter.get("batch_size"),len(self.disease_replay['train'])))

                loss = self.model.train(batch=batch)

            except:
                pass
            # print(loss)

            try:
                test_batch = self.disease_replay['test']
                test_acc = self.model.test(test_batch=test_batch)

                if test_acc > best_test_acc:
                    best_test_acc = test_acc
                    print("update__",test_acc)
                    best_model.load_state_dict(self.model.model.state_dict())
                    if test_acc> 0.90:
                        torch.save(self.model.model.state_dict(), 'disease_classifier'+format(test_acc,'5f')+'.pkl')
            except:
                pass
            # print(test_acc)
        # test_batch = random.sample(self.disease_replay['train'], min(500,len(self.disease_replay['train'])))
        # test_acc = self.model.test(test_batch=test_batch)

        self.model.model.load_state_dict(best_model.state_dict())

        # self.disease_replay = {'train': deque(maxlen=50000), 'test': deque(maxlen=1000)}
        print('disease_replay:{},loss:{:.4f}, test_acc:{:.4f}'.format(len(self.disease_replay['train']), loss["loss"], best_test_acc))

    def save_dl_model(self, model_performance, episodes_index, checkpoint_path=None):
        # Saving master agent
        temp_checkpoint_path = os.path.join(checkpoint_path, 'classifier/')
        self.model.save_model(model_performance=model_performance, episodes_index=episodes_index, checkpoint_path=temp_checkpoint_path)

    def exp_transform(self, x):
        exp_sum = 0
        for i in x:
            exp_sum += np.exp(i)
        return [np.exp(i)/exp_sum for i in x]

def tokenizer(x):
    return x.split()


import pygame
from random import randint
import random
import time
import pprint
import networks
import json
import numpy as np
import os
import torch
import torch.nn as nn
import copy

class SnakeGame:

	def __init__(self,w,h,fps=30):
		self.width = w
		self.height = h

		self.food = (randint(0,self.width - 1),randint(0,self.height - 1))
		self.snake = [[0,0]]

		self.colors = {"FOOD" : (255,20,20),"SNAKE" : (20,255,20)}

		self.frame_time = 1 / fps

		self.snapshot_vector = [[0 for x in range(self.height)] for i in range(self.width)]

		self.direction = (1,0)

		self.data = []

	def play_game(self,window_x,window_y,training_match=True,model=None):

		if not window_x == window_y:
			print(f"invalid game_size {window_x},{window_y}.\nDimensions must be equal")
			return

		square_width 	= window_x / self.width
		square_height 	= window_y / self.height

		#Display setup
		pygame.init()
		self.window = pygame.display.set_mode((window_x,window_y))
		pygame.display.set_caption("AI Training!")

		self.output_vector = [0,0,0,1]
		game_running = True

		while game_running:
			self.window.fill((0,0,0))
			pygame.event.pump()
			t_start = time.time()
			keys = pygame.key.get_pressed()

			#print(keys[pygame.K_w])
			f_time = t_start - time.time()

			#Draw snake and food
			if training_match:
				self.update_movement()
				self.create_input_vector()

			else:
				assert model is not None

				y_feed = torch.tensor(self.game_to_model(self.create_input_vector()),dtype=torch.float)
				model_out = model.forward(y_feed)

				w,s,a,d = model_out.cpu().detach().numpy()
				print([w,a,s,d])
				keys= pygame.key.get_pressed()
				if True in [keys[pygame.K_w],keys[pygame.K_a],keys[pygame.K_s],keys[pygame.K_d]]:
					print("overriding ML")
					self.update_movement(player_input=True)
				else:
					self.update_movement(player_input=False,w=w,s=s,a=a,d=d)

			for coord in self.snake:
				x,y = coord[0] * square_width,coord[1] * square_height
				new_rect = pygame.draw.rect(self.window,self.colors["SNAKE"],pygame.Rect(x,y,square_width,square_height))
			x,y = self.food[0] * square_width,self.food[1] * square_height
			food_rect = pygame.draw.rect(self.window,self.colors["FOOD"],pygame.Rect(x,y,square_width,square_height))
			pygame.display.update()

			#Movement
			next_x = self.snake[0][0] + self.direction[0]
			next_y = self.snake[0][1] + self.direction[1]
			if next_x >= self.width or next_y >= self.height or next_x < 0 or next_y < 0:
				game_running = False
			next_head = (next_x , next_y)

			if next_head in self.snake:
				print("you lose!")
				game_running = False

			if next_head == self.food:
				self.food = (randint(0,self.width - 1),randint(0,self.height - 1))
				self.snake = [next_head] + self.snake
			else:
				self.snake = [next_head] + self.snake[:-1]

			if keys[pygame.K_p]:
				print(f"input vect: {self.vector}")
				print(f"\n\noutput vect:{self.output_vector}")
			#Keep constant frametime
			self.data.append({"x":self.input_vector,"y":self.output_vector})
			if self.frame_time > f_time:
				time.sleep(self.frame_time - f_time)

		self.save_data()

	def save_data(self):
		x = []
		y = []
		for item in self.data[:-1]:
			x_item = np.ndarray.flatten(np.array(item["x"]))
			y_item = np.array(item["y"])

			x.append(x_item)
			y.append(y_item)

		x_item_final = np.ndarray.flatten(np.array(self.data[-1]["x"]))
		y_item_final = list(map(lambda x : x * -1,self.data[-1]["y"]))

		x.append(x_item_final)
		y.append(y_item_final)

		x = np.array(x)
		y = np.array(y)

		if not os.path.isdir("experiences"):
			os.mkdir("experiences")

		i = 0
		fname = f"exp_x_{i}.npy"
		while os.path.exists(os.path.join("experiences",fname)):
			i += 1
			fname = f"exp_x_{i}.npy"
		np.save(os.path.join("experiences",fname),x)
		np.save(os.path.join("experiences",f"exp_y_{i}.npy"),y)

	def game_to_model(self,x):
		return np.ndarray.flatten(np.array(x))

	def create_input_vector(self):
		self.input_vector = [[0 for x in range(self.height)] for y in range(self.width)]
		self.input_vector[self.snake[0][1]][self.snake[0][0]] = 1
		for piece in self.snake[1:]:
			self.input_vector[piece[1]][piece[0]] = -1
		food_placement = [[0 for x in range(self.height)] for y in range(self.width)]
		food_placement[self.food[1]][self.food[0]] = 1
		self.input_vector += food_placement
		return self.input_vector

	def update_movement(self,player_input=False,w=0,s=0,a=0,d=0):

		if player_input:
			pygame.event.pump()
			keys = pygame.key.get_pressed()
			w,s,a,d = (0,0,0,0)

			if keys[pygame.K_w]:
				w = 1
			elif keys[pygame.K_s]:
				s = 1
			elif keys[pygame.K_a]:
				a = 1
			elif keys[pygame.K_d]:
				d = 1
			else:
				return
			self.output_vector = [w,s,a,d]

		self.movement_choices = {
			(0,-1) 	: w,
			(0,1) 	: s,
			(-1,0) 	: a,
			(1,0)	: d}

		self.direction = max(self.movement_choices,key=self.movement_choices.get)

	def train_on_game(self,model,visible=True,epsilon=.05):
		window_x, window_y = (600,600)
		experiences = []
		rewards = {"die":-1,"food":1,"live":.05,"idle":-.5}

		#setup
		assert model is not None
		square_width 	= window_x / self.width
		square_height 	= window_y / self.height
		pygame.init()
		game_running = True
		output_vector = [0,0,0,1]
		eaten_since = 0
		#Game display
		if visible:
			self.window = pygame.display.set_mode((window_x,window_y))
			pygame.display.set_caption("AI Training!")

		#Game Loop
		while game_running:
			input_vector = self.get_state_vector()

			#Find next update_movement
			if random.random() < epsilon:
				x = random.randint(-1,1)
				y = random.randint(-1,1)
				while abs(x) == abs(y):
					x = random.randint(-1,1)
					y = random.randint(-1,1)
				self.direction = (x,y)
			else:
				movement_values = model.forward(input_vector)
				w,s,a,d = movement_values.cpu().detach().numpy()
				self.update_movement(w=w,s=s,a=a,d=d)

			#Game display
			if visible:
				self.window.fill((0,0,0))
				#print(f"model predicts: {[w,a,s,d]}")

			#Game Display
			if visible:
				for coord in self.snake:
					x,y = coord[0] * square_width,coord[1] * square_height
					new_rect = pygame.draw.rect(self.window,self.colors["SNAKE"],pygame.Rect(x,y,square_width,square_height))
				x,y = self.food[0] * square_width,self.food[1] * square_height
				food_rect = pygame.draw.rect(self.window,self.colors["FOOD"],pygame.Rect(x,y,square_width,square_height))
				pygame.display.update()

			#Game Logic
			next_x = self.snake[0][0] + self.direction[0]
			next_y = self.snake[0][1] + self.direction[1]
			next_head = (next_x , next_y)

			#Check lose
			if next_x >= self.width or next_y >= self.height or next_x < 0 or next_y < 0 or next_head in self.snake:
				game_running = False
				reward = rewards['die']
				experiences.append({'s':input_vector,'r':reward,'a':self.direction,'s`':'terminal'})
				return experiences

			#Check eat food
			eaten_since += 1
			if next_head == self.food:
				eaten_since = 0
				self.food = (randint(0,self.width - 1),randint(0,self.height - 1))
				self.snake = [next_head] + self.snake
				reward = rewards['food']
			else:
				self.snake = [next_head] + self.snake[:-1]
				reward = rewards['live']

			#Add to experiences
			experiences.append({'s':input_vector,'r':reward,'a':self.direction,'s`': self.get_state_vector()})

			if eaten_since > 2000:
				game_running = False
				reward = rewards['idle']
				experiences.append({'s':input_vector,'r':reward,'a':self.direction,'s`':'terminal'})
				return experiences
		return experiences

	def get_state_vector(self):
		#Build x by y vector for snake
		input_vector = [[0 for x in range(self.height)] for y in range(self.width)]

		#Head of snake == 1
		input_vector[self.snake[0][1]][self.snake[0][0]] = 1

		#Rest of snake == -1
		for piece in self.snake[1:]:
			input_vector[piece[1]][piece[0]] = -1

		#Build x by y vector for food placement
		food_placement = [[0 for x in range(self.height)] for y in range(self.width)]
		food_placement[self.food[1]][self.food[0]] = 1
		input_vector += food_placement

		#Translate to numpy and flatten
		np_array = np.ndarray.flatten(np.array(input_vector))
		#Translate to tensor
		return torch.tensor(np_array,dtype=torch.float)

class Trainer:

	def __init__(self,memory_size,visible=True,loading=True,PATH="E:\code\Scratch\models",fps=200):
		self.memory_size = memory_size
		self.experiences = []

		self.target_model 	= networks.FullyConnectedNetwork(800,4,5e-6)
		self.learning_model = networks.FullyConnectedNetwork(800,4,5e-6)
		if loading:
			self.target_model.load_state_dict(torch.load(os.path.join(PATH,"t_model")))
			self.learning_model.load_state_dict(torch.load(os.path.join(PATH,"l_model")))
			print("sucessfully loaded models")
			#self.target_model.eval()
			#self.learning_model.eval()
		self.visible = visible
		self.indices = [(0,-1),(0,1),(-1,0),(1,0)]
		self.gamma = .3
		self.PATH = PATH
		self.loss = nn.MSELoss()
		self.optimizer = torch.optim.Adam(self.learning_model.parameters())
		self.fps = fps
	def train(self,episodes=1000,replay_every=100,sample_size=5000,batch_size=8):

		for e_i in range(episodes):
			#Play a game and collect the experiences
			game = SnakeGame(20,20,fps=100)
			self.experiences += game.train_on_game(self.learning_model,visible=self.visible)

			#If training on this episode
			if e_i % replay_every == 0 and not e_i == 0:
				training_set = [self.experiences[random.randint(0,len(self.experiences)-1)] for _ in range(sample_size)]
				print(f"EPISODE {e_i}/{episodes} ----------------------------------")
				self.train_on_experiences(training_set,batch_size=batch_size)
				self.transfer_models()
				self.experiences = []
		torch.save(self.target_model.state_dict(),os.path.join(self.PATH,"t_model"))
		torch.save(self.learning_model.state_dict(),os.path.join(self.PATH,"l_model"))

	def train_on_experiences(self,big_set,epochs=1,batch_size=8):

		for epoch_i in range(epochs):
			batches = [[big_set[i * n] for n in range(batch_size)] for i in range(int(len(big_set)/batch_size))]
			print(f"\tepoch {epoch_i}")
			experiences = torch.from_numpy(np.array([exp['s'].cpu().detach().numpy() for exp in big_set]))

			c_loss = 0
			for batch,exp_set in enumerate(batches):
				indices = [exp['a'] for exp in exp_set]
				vals = self.learning_model(experiences)
				vals_target_adjusted = torch.clone(vals)

				for item,i in enumerate(indices):
					if exp_set[item]['s`'] == 'terminal':
						target = exp_set[item]['r']
					else:
						next_state_val = max(self.target_model(exp_set[item]['s`']))
						target = exp_set[item]['r'] + self.gamma * next_state_val
					vals_target_adjusted[item,i] = target

				self.learning_model.optimizer.zero_grad()
				loss = self.learning_model.loss(vals,vals_target_adjusted)
				c_loss += loss
				#Perform grad descent
				loss.backward()
				self.learning_model.optimizer.step()

				print(f"\tBatch {batch}/{len(batches)}:\t loss={c_loss/(batch+1):.8f}",end="\r")
			print("")

	def transfer_models(self):
		torch.save(self.learning_model.state_dict(),os.path.join(self.PATH,"l_model"))
		self.target_model.load_state_dict(torch.load(os.path.join(self.PATH,"l_model")))
if __name__ == "__main__":

	import sys
	if sys.argv[1] in ['-p',"--play"]:
		s = SnakeGame(20,20,fps=15)
		s.play_game(600,600,training_match=True)
		exit()

	elif sys.argv[1] in ['-r','--reinforce']:
		try:
			trainer = Trainer(100000,visible=sys.argv[2] in ["T",'t'],loading=sys.argv[3] in ["t","T"],PATH="models")
			trainer.train(episodes=int(sys.argv[4]),replay_every=int(sys.argv[5]),sample_size=int(sys.argv[6]),batch_size=int(sys.argv[7]))
		except ValueError as i:
			print(i)
			print(f"usage: --reinforce visible[t/f] loading[t/f] episodes[n] replay_every[n] sample_size[n]")
	else:
		exp = {}
		x_exp = {}
		y_exp = {}

		for f in os.listdir("experiences"):
			type = f[4]
			number = f[6:].split(".")[0]

			if not number in exp:
				exp[number] = {"x" :None,"y":None}

			if type == "x":
				exp[number]["x"] = np.load(os.path.join("experiences",f))
			else:
				exp[number]["y"] = np.load(os.path.join("experiences",f))

		final_boss_list = {"x":np.empty((0,800)),"y":np.empty((0,4))}
		for num in exp:
			try:
				final_boss_list["x"] = np.append(final_boss_list['x'], exp[num]["x"],axis=0)
				final_boss_list["y"] = np.append(final_boss_list['y'], exp[num]["y"],axis=0)
			except ValueError:
				print(f"{num} did not play happy\n\n")

		x_data = torch.from_numpy(final_boss_list["x"]).float()
		y_data = torch.from_numpy(final_boss_list["y"]).float()

		model = networks.FullyConnectedNetwork(800,4,1e-7)

		print(f"training model on {x_data.shape} datapoints")
		model.train(x_data,y_data,verbose=True,epochs=int(sys.argv[2]),show_steps=25,batch_size=int(sys.argv[3]),show_graph=sys.argv[4] in ["T",'t'])

		game = SnakeGame(20,20,fps=4)

		game.play_game(600,600,training_match=False,model=model)


import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np

def get_colormap(cmap_name, lims):
    if cmap_name in ('light symmetric', 'dark symmetric', 'symmetric'):
        n_points = 256
        if cmap_name in ('light symmetric', 'symmetric'):
            org_cmap = plt.get_cmap('RdBu_r')
            neg_cmap = get_part_of_cmap(org_cmap, 0.0, 0.5, n_points)
            pos_cmap = get_part_of_cmap(org_cmap, 0.5, 1.0, n_points)
        elif cmap_name == 'dark symmetric':
            neg_color_vals = {
                'red': ((0.0, 0.6, 0.6),
                        (0.6, 0.0, 0.0),
                        (1.0, 0.0, 0.0)),
                'green': ((0.0, 1.0, 1.0),
                          (0.4, 0.8, 0.8),
                          (1.0, 0.0, 0.0)),
                'blue': ((0.0, 1.0, 1.0),
                         (0.8, 0.8, 0.8),
                         (1.0, 0.0, 0.0)),
            }
            neg_cmap = mcolors.LinearSegmentedColormap('', neg_color_vals)
            pos_cmap = plt.get_cmap('afmhot')
        max_abs = np.max(np.abs(lims))
        min_val = lims[0]
        max_val = lims[1]
        z_range = max_val - min_val
        if min_val < 0 < max_val:
            # Negative
            neg_fraction = abs(min_val) / z_range
            n_neg_points = int(neg_fraction * n_points)
            neg_low = 1.0 - abs(min_val)/max_abs
            neg_vals = np.linspace(neg_low, 1.0, n_neg_points)
            neg_colors = neg_cmap(neg_vals)
            # Positive
            pos_fraction = abs(max_val) / z_range
            n_pos_points = int(pos_fraction * n_points)
            pos_high = abs(max_val) / max_abs
            pos_vals = np.linspace(0.0, pos_high, n_pos_points)
            pos_colors = pos_cmap(pos_vals)
            # Combine negative and positive.
            colors = np.vstack((neg_colors, pos_colors))
            cmap = mcolors.LinearSegmentedColormap.from_list('', colors)
        elif 0 <= min_val <= max_val:
            cmap = pos_cmap
        elif min_val <= max_val <= 0:
            cmap = neg_cmap
    else:
        cmap = plt.get_cmap(cmap_name)
    return cmap

def get_part_of_cmap(cmap, low, high, n_points):
    """
    cmap : Colormap instance
        Note that cmap can NOT be a string.
    """
    new_cmap_vals = cmap(np.linspace(low, high, n_points))
    new_cmap = mcolors.LinearSegmentedColormap.from_list('', new_cmap_vals)
    return new_cmap


import nltk
from nltk.stem import WordNetLemmatizer
import networkx as nx
from collections import Counter, defaultdict
import re
from nltk.corpus import stopwords
CAMELCASE = r'([.*?]?(\-)(?=[A-Z]|$|-)|[A-Z][a-z]*)'

def get_tags_d(resource_dict):
    '''given a single resource_dict of types
    return a dict of tags with tag as key
    and a list of corresponding url and ns and occurence
    e.g: Jacques_Tati
    '''

    wnl = WordNetLemmatizer()
    tags = []
    tags_d = {}
    for k,v in resource_dict.items():
        tags = re.findall(CAMELCASE, k)
        print(k,tags)
        # for n in re.findall(CAMELCASE, k):
        #     print(n)
        #     sing = wnl.lemmatize(n.lower())
        #     if sing not in stopwords.words('english'):
        #         print(k, sing, v["resources"])
                # try:
                #     tags_d[sing]["predicates"].append(k)
                # except:
                #     tags_d[sing] = {"predicates": k}

'''
        #         if sing not in tags_d.keys():
        #         # try:
        #             tags_d[sing] = {"predicates": [k],
        #                              "urls": tag_urls,
        #                              "ns": tag_ns,
        #                               "count":1,
        #                               "resources": [v["resources"]]
        #                             }
        #
        #         else:
        #         # except KeyError:
        #             tags_d[sing]["predicates"].append(k)
        #             tags_d[sing]["urls"].extend(tag_urls)
        #             tags_d[sing]["ns"].extend(tag_ns)
        #             tags_d[sing]["count"] += 1
        #             tags_d[sing]["resources"].extend(v["resources"])
'''
        # return tags_d

def get_tags_freq(types):
    '''extract tags from types_d return Counter'''
    from nltk.stem import WordNetLemmatizer
    wnl = WordNetLemmatizer()
    from nltk.corpus import stopwords
    tags = []
    for k in types.keys():
        for n in re.findall('[A-Z][^A-Z]*', k):
            sing = wnl.lemmatize(n.lower())
            if sing not in stopwords.words('english'):
                tags.append(sing)
    return Counter(tags)

def filter_frequent_tags(types, offset=5):
    '''filter the most frequent tags from types_d'''
    return get_tags(types).most_common(offset)

def filter_by_tags(tags, types, offset):
    '''by giving tags, types and offset return list
    of the most common tags
    '''
    predicates = []
    for n in tags:
        for k in types.keys():
            if n[0] in k.lower():
                #print(n[0],"=>", types[k])
                predicates.append([types[k], n[1],n[0]])
    return predicates

def get_similar_tags(tagsA, tagsB, offset=3):
    '''get tags that are shared between 2 lists of tags with offset'''
    similar_prop = []
    for n in list(set(tagsA) & set(tagsB)):
        if tagsA[n] > 1 and tagsB[n] > 1:
            similar_prop.append([n, tagsA[n], tagsB[n]])
    return sorted(similar_prop, key=lambda x: int(x[2]), reverse=True)[:offset]

def get_commons_tags(g, resources):
    '''get commons tags of a graph between the resources'''
    return [k for k,v in nx.degree(g).items() if v>=len(resources) and k not in resources]


import csv

from django.core.management.base import BaseCommand
from oscar.apps.catalogue.models import ProductAttributeValue
from marine_parts.apps.catalogue.models import Product, ProductCategory

def copy_categories(original_part_upc, new_part):
    """
    Clone original part categories and assign them to new part.
    """
    categories = ProductCategory.objects.filter(
        product__upc=original_part_upc
    )

    for category in categories:
        try:
            # Assign None to pk and save will create a new instance.
            category.pk = None
            category.product = new_part
            category.save()
        except Exception as e:
            print(e)

def copy_attributes(original_part_upc, new_part, manufacturer=""):
    """
    Clone original part attributes and assign them to new part.
    """
    attribute_values = ProductAttributeValue.objects.filter(
        product__upc=original_part_upc
    )

    for attribute_value in attribute_values:
        # Assign None to pk and save will create a new instance.
        attribute_value.pk = None
        attribute_value.product = new_part

        if attribute_value.attribute.name == "Manufacturer":
            attribute_value.value = manufacturer
        if attribute_value.attribute.name == "Origin":
            attribute_value.value = "Aftermarket"

        attribute_value.save()

def search_original_part(original_part_number):
    """
    Looks for original part in database.
    """
    try:
        return Product.objects.get(upc=original_part_number)
    except Exception:
        return None

def clone_original_part(data, manufacturer):
    """
    Data is an array with UPC, OEM and OE#.
    """
    original_part = None
    try:
        original_part = search_original_part(data[2])
        original_part_upc = original_part.upc

        if original_part is not None:
            # Clonning product.
            # Assign None to pk and save will create a new instance.
            original_part.pk = None
            original_part.upc = data[0]
            # Now in original part is the copy.
            original_part.save()

            # Clonning categories and attributes.
            copy_categories(original_part_upc, original_part)
            copy_attributes(original_part_upc, original_part, manufacturer)

            return True
        return False
    except Exception as e:
        # print(e)
        return False

def load_products(file, manufacturer):
    """
    Load manufacturer product from a csv file.
    With format UPC, OEM, OE#.
    """
    count = 0
    with open(file, 'rb') as csvfile:
        products = csv.reader(csvfile, delimiter=',', quotechar='"')
        for row in products:
            # Clone original part, if it exists.
            if clone_original_part(row, manufacturer):
                count += 1
                if (count % 100) == 0:
                    print("Added 100 products... and continuing....")
    return count

class Command(BaseCommand):
    help = 'Load csv files (generic_upc, oem, oe#): python manage.py manufacturer_name file'

    def add_arguments(self, parser):
        parser.add_argument('manufacturer', nargs='+', type=str)
        parser.add_argument('file', nargs='+', type=str)

    def handle(self, *args, **options):
        count = load_products(
            options['file'][0],
            options['manufacturer'][0]
        )

        print("Added: %d new products." % (count))


#ERRO NA CONDIÇÃO DA VARIÁVEL IDADE_MAIS_VELHA
cont = 3
soma_idade = 0
m_menores_20 = 0
for c in range(1, cont+1):
    nome = str(input("NOME DA {}ª PESSOA: ".format(c)))
    idade = int(input("IDADE DA {}ª PESSOA: ".format(c)))
    sexo = str(input("SEXO DA {}ª PESSOA[M/F]: ".format(c)))
    soma_idade = soma_idade + idade
    if c ==1:
        idade_mais_velha = idade
    else:
        if idade > idade_mais_velha and sexo == "M":
            idade_mais_velha = idade
            h_mais_velho = nome
        if sexo == "F" and idade < 20:
            m_menores_20 = m_menores_20 + 1
media_idade = soma_idade / 3
print("A MÉDIA DE IDADE DO GRUPO É:{}".format(media_idade))
print("HOMEM MAIS VELHO SE CHAMA {} E TEM {} ANOS.".format(h_mais_velho, idade_mais_velha))
print("{} MULHERES TEM MENOS DE 20 ANOS.".format(m_menores_20))


from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from keyboards.inline.callback_data import task

def create_panel(task_id):
    panel = InlineKeyboardMarkup()
    panel.add(InlineKeyboardButton(text='Начать', callback_data=task.new(type='todo',
                                                                         attribute='start',
                                                                         info=str(task_id))))

    return panel

inline_new_task = create_panel


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Nov 22 14:55:47 2019
anthony2owaru@gmail.com
Scrapes tabular data from United States Geological Survey (https://waterdata.usgs.gov)
More info: https://help.waterdata.usgs.gov/faq/about-tab-delimited-output
"""

# library modules
import requests
from datetime import datetime
import pandas as pd
import os

"""
**STEP 1**
Pull text from url, feel free to change this URL!"""

url="https://waterdata.usgs.gov/nwis/dv?cb_00065=on&format=rdb&site_no=02247222&referred_module=sw&period=&begin_date=1950-01-01&end_date=2019-11-21"
doc=requests.get(url).text
print("\t \t******First 15 lines of page requested: below:****** \n",doc.split("\n")[0:15],"\n END OF PREVIEW, parsing doc now…")

"""
**STEP 2**
Clean the comments section by stripping up to last hashtag
"""
doc = doc[doc.rfind("# ")+1:]

"""
**STEP 3**
Split cells by \t from rows split from doc by \n
"""
cells=[row.split("\t") for row in doc.split("\n") if len(row.split("\t")) == 5]

"""
**STEP 4**
Construct dict that stores column names and indices
"""
column_indices = dict((column_name, cells[0].index(column_name)) for column_name in cells[0])

"""
**STEP 5**
Create output_object which is dict constructed from column_indices and list comprehensions.
The list comps loop through each row splitting them into columns by index from the column_indices dict
We turn that into a dataframe and then export to csv.
"""
output_object = dict((key,[row[value] for row in cells[1:]]) for key,value in column_indices.items())
print("Document parsed, exporting…")
output_df = pd.DataFrame(output_object)
output_df.to_csv(str(os.getcwd())+"/"+str(datetime.now())+"_site_no_"+output_object["site_no"][0]+".csv")
print("csv exported to ",str(os.getcwd()))


import json
f = open('./py-tgt-train.json')
# data=json.load(f)

import jsonlines

# 有相同的标题的为止
ok=0
# now=1
match_count=0
not_match_count=0
match_file_path='./match-pytgt-train.json'
notmatch_file_path='./notmatch-pytgt-train.json'

linedex=1
with open(match_file_path,mode="w",encoding="utf-8") as mfw:
    with open(notmatch_file_path,mode="w",encoding="utf-8") as nmfw:
        for line in f.readlines():
            i=json.loads(line)
            title=i['title']
            title1=title.replace(" ","").strip()#夏新数据末尾\n删去
            topone=i['top_three_simple'][0]['title'].lower()#全部转换为小写，因为夏新的就是小写
            topone1=topone.replace(" ","").replace("'","").replace("\"","").replace("``","").replace("@","")
            #去除特殊符号，夏新的问题中应该也去除了特殊符号
            # 产生json格式记录
            line_dict={}
            line_dict["title"] = title
            line_dict["top_three_simple"]=i['top_three_simple']
            line_dict['linedex']=linedex
            line_json = json.dumps(line_dict)
            linedex+=1
            if title1==topone1:
                # 匹配的情况下的记录写入文件
                mfw.write(line_json + '\n')
                match_count+=1
                # print('ok')
                ok=1
            else:
                nmfw.write(line_json + '\n')
                not_match_count+=1
                print("___________________________")
                print(title)
                print(topone)
                # print("-----------------------------")
        print('match count:',match_count)
        print('not match count:',not_match_count)

        nmfw.close()
    mfw.close()


"""Set module shortcuts and globals"""

import logging

from pydicom.uid import UID

from ._version import __version__

_version = __version__.split(".")[:3]

# UID prefix provided by https://www.medicalconnections.co.uk/Free_UID
# Encoded as UI, maximum 64 characters
PYNETDICOM_UID_PREFIX = "1.2.826.0.1.3680043.9.3811."
"""``1.2.826.0.1.3680043.9.3811.``

The UID root used by *pynetdicom*.
"""

# Encoded as SH, maximum 16 characters
PYNETDICOM_IMPLEMENTATION_VERSION: str = f"PYNETDICOM_{''.join(_version)}"
"""The (0002,0013) *Implementation Version Name* used by *pynetdicom*"""
assert 1 <= len(PYNETDICOM_IMPLEMENTATION_VERSION) <= 16

PYNETDICOM_IMPLEMENTATION_UID: UID = UID(f"{PYNETDICOM_UID_PREFIX}{'.'.join(_version)}")
"""The (0002,0012) *Implementation Class UID* used by *pynetdicom*"""
assert PYNETDICOM_IMPLEMENTATION_UID.is_valid

# Convenience imports
# ruff: noqa: E402,F401
from pynetdicom import events as evt
from pynetdicom.ae import ApplicationEntity as AE
from pynetdicom.association import Association
from pynetdicom._globals import (
    ALL_TRANSFER_SYNTAXES,
    DEFAULT_TRANSFER_SYNTAXES,
)
from pynetdicom.presentation import (
    build_context,
    build_role,
    AllStoragePresentationContexts,
    ApplicationEventLoggingPresentationContexts,
    BasicWorklistManagementPresentationContexts,
    ColorPalettePresentationContexts,
    DefinedProcedureProtocolPresentationContexts,
    DisplaySystemPresentationContexts,
    HangingProtocolPresentationContexts,
    ImplantTemplatePresentationContexts,
    InstanceAvailabilityPresentationContexts,
    MediaCreationManagementPresentationContexts,
    MediaStoragePresentationContexts,
    ModalityPerformedPresentationContexts,
    NonPatientObjectPresentationContexts,
    PrintManagementPresentationContexts,
    ProcedureStepPresentationContexts,
    ProtocolApprovalPresentationContexts,
    QueryRetrievePresentationContexts,
    RelevantPatientInformationPresentationContexts,
    RTMachineVerificationPresentationContexts,
    StoragePresentationContexts,
    StorageCommitmentPresentationContexts,
    SubstanceAdministrationPresentationContexts,
    UnifiedProcedurePresentationContexts,
    VerificationPresentationContexts,
)
from pynetdicom.sop_class import register_uid

# Setup default logging
logging.getLogger("pynetdicom").addHandler(logging.NullHandler())

def debug_logger() -> None:
    """Setup the logging for debugging."""
    logger = logging.getLogger("pynetdicom")
    # Ensure only have one StreamHandler
    logger.handlers = []
    handler = logging.StreamHandler()
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(levelname).1s: %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)


def find():
    queue = deque([(0,0)])
    melt = []
    while queue:
        y, x = queue.popleft()
        for dy, dx in move:
            ny, nx = y + dy, x + dx
            if 0 <= ny < N and 0 <= nx < M and not visited[ny][nx]:
                visited[ny][nx] = 1
                if cheeze[ny][nx] == 0:
                    queue.append((ny,nx))
                else :
                    melt.append((ny,nx))
    for y, x in melt:
        cheeze[y][x] = 0
    return len(melt)

import sys
from collections import deque
N, M = map(int, sys.stdin.readline().split())
cheeze = [list(map(int, sys.stdin.readline().split())) for _ in range(N)]
move = [[0,1],[0,-1],[1,0],[-1,0]]
cnt = sum(sum(i) for i in cheeze)
result = 1

while True: # 반복하며 녹여보자
    visited = [[0] *M for _ in range(N)]
    now = find()
    cnt -= now
    if cnt == 0 : # 0이 되면, now는 직전의 값
        print(result)
        print(now)
        break
    result += 1