import math
import torch
import torch.nn as nn
import torch.nn.functional as F

class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = nn.Conv2d(inplanes, inplanes, 1, stride, bias=False)
        self.bn1 = nn.BatchNorm2d(inplanes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(inplanes, planes, 1, stride, bias=False)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = nn.Sequential(
                    nn.Conv2d(inplanes, planes,
                            kernel_size=1, stride=stride, bias=False),
                            nn.BatchNorm2d(planes))
        self.isdownsample = True if inplanes != planes else False

    def forward(self, x):
        residual = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.isdownsample:
            residual = self.downsample(x)

        out += residual
        out = self.relu(out)

        return out

class Decoder(nn.Module):
    def __init__(self, backbone):
        super(Decoder, self).__init__()
        if backbone == 'resnet':
            channel = [0, 256, 512, 1024, 256]
        else:
            raise NotImplementedError

        self.layer1 = nn.Sequential(nn.Conv2d(channel[1], 256, 1, 1, bias=False),
                                    nn.BatchNorm2d(256),
                                    nn.ReLU())
        self.layer2 = nn.Sequential(nn.Conv2d(channel[2], 256, 1, 1, bias=False),
                                    nn.BatchNorm2d(256),
                                    nn.ReLU())
        self.layer3 = nn.Sequential(nn.Conv2d(channel[3], 256, 1, 1, bias=False),
                                    nn.BatchNorm2d(256),
                                    nn.ReLU())

        plances = [256, 256, 256, 256]
        self.last_conv1 = BasicBlock(256, plances[0])
        self.last_conv2 = BasicBlock(256, plances[1])
        self.last_conv3 = BasicBlock(256, plances[2])
        self.last_conv4 = BasicBlock(256, plances[3])

        self.plances = plances

        self._init_weight()

    def forward(self, layer1_feat, layer2_feat, layer3_feat, layer4_feat):
        x = layer4_feat
        dssdlayer4 = self.last_conv4(x)

        y = self.layer3(layer3_feat)
        if x.size()[2:] != y.size()[2:]:
            x = F.interpolate(x, size=y.size()[2:], mode='bilinear', align_corners=True)
        x = x + y
        dssdlayer3 = self.last_conv3(x)

        y = self.layer2(layer2_feat)
        if x.size()[2:] != y.size()[2:]:
            x = F.interpolate(x, size=y.size()[2:], mode='bilinear', align_corners=True)
        x = x + y
        dssdlayer2 = self.last_conv2(x)

        y = self.layer1(layer1_feat)
        if x.size()[2:] != y.size()[2:]:
            x = F.interpolate(x, size=y.size()[2:], mode='bilinear', align_corners=True)
        x = x + y
        dssdlayer1 = self.last_conv1(x)

        return dssdlayer1, dssdlayer2, dssdlayer3, dssdlayer4

    def _init_weight(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                torch.nn.init.kaiming_normal_(m.weight)
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()

def build_decoder(backbone):
    return Decoder(backbone)

if __name__ == "__main__":
    model = build_decoder('resnet')
    layer4_feat = torch.rand((1, 256, 16, 16))
    layer3_feat = torch.rand((1, 1024, 16, 16))
    layer2_feat = torch.rand((1, 512, 32, 32))
    layer1_feat = torch.rand((1, 256, 64, 64))
    output = model(layer1_feat, layer2_feat, layer3_feat, layer4_feat)
    pass


# pylint: disable=W0102
# pylint: disable=W0212
# pylint: disable=W0221
# pylint: disable=W0231
# pylint: disable=W0640
# pylint: disable=C0103
"""Module for representing UDS corpora."""

import os
import json
import requests

from pkg_resources import resource_filename
from os.path import basename, splitext
from logging import warn
from glob import glob
from random import sample
from functools import lru_cache
from typing import Union, Optional, Any, TextIO
from typing import Dict, List, Set
from io import BytesIO
from zipfile import ZipFile
from rdflib.query import Result
from rdflib.plugins.sparql.sparql import Query
from ..predpatt import PredPattCorpus

from .document import UDSDocument
from .annotation import UDSAnnotation
from .annotation import RawUDSAnnotation
from .annotation import NormalizedUDSAnnotation
from .graph import UDSSentenceGraph
from .metadata import UDSCorpusMetadata
from .metadata import UDSAnnotationMetadata
from .metadata import UDSPropertyMetadata

Location = Union[str, TextIO]

class UDSCorpus(PredPattCorpus):
    """A collection of Universal Decompositional Semantics graphs

    Parameters
    ----------
    sentences
        the predpatt sentence graphs to associate the annotations with
    documents
        the documents associated with the predpatt sentence graphs
    sentence_annotations
        additional annotations to associate with predpatt nodes on
        sentence-level graphs; in most cases, no such annotations
        will be passed, since the standard UDS annotations are
        automatically loaded
    document_annotations
        additional annotations to associate with predpatt nodes on
        document-level graphs
    version
        the version of UDS datasets to use
    split
        the split to load: "train", "dev", or "test"
    annotation_format
        which annotation type to load ("raw" or "normalized")
    """

    UD_URL = 'https://github.com/UniversalDependencies/' +\
             'UD_English-EWT/archive/r1.2.zip'
    ANN_DIR = resource_filename('decomp', 'data/')
    CACHE_DIR = resource_filename('decomp', 'data/')

    def __init__(self,
                 sentences: Optional[PredPattCorpus] = None,
                 documents: Optional[Dict[str, UDSDocument]] = None,
                 sentence_annotations: List[UDSAnnotation] = [],
                 document_annotations: List[UDSAnnotation] = [],
                 version: str = '2.0',
                 split: Optional[str] = None,
                 annotation_format: str = 'normalized'):
        self._validate_arguments(sentences, documents,
                                 version, split, annotation_format)

        self.version = version
        self.annotation_format = annotation_format

        self._metadata = UDSCorpusMetadata()

        # methods inherited from Corpus that reference the self._graphs
        # attribute will operate on sentence-level graphs only
        self._graphs = self._sentences = {}
        self._documents = {}

        self._initialize_paths(version, annotation_format)
        all_built = self._check_build_status()

        if sentences is None and split in self._sentences_paths:
            self._load_split(split)

        elif sentences is None and split is None and all_built:
            for split in ['train', 'dev', 'test']:
                self._load_split(split)

        elif sentences is None:
            # download UD-EWT
            udewt = requests.get(self.UD_URL).content

            if sentence_annotations or document_annotations:
                warn("sentence and document annotations ignored")

            self._process_conll(split, udewt)

        else:
            self._sentences = sentences
            self._documents = documents

            self.add_annotation(sentence_annotations, document_annotations)

    def _validate_arguments(self, sentences, documents,
                            version, split, annotation_format):
        # neither documents nor graphs should be supplied to the constructor
        # without the other
        if sentences is None and documents is not None:
            raise ValueError('UDS documents were provided without sentences. '
                             'Cannot construct corpus.')

        elif sentences is not None and documents is None:
            raise ValueError('UDS sentences were provided without documents. '
                             'Cannot construct corpus.')

        if not (split is None or split in ['train', 'dev', 'test']):
            errmsg = 'split must be "train", "dev", or "test"'
            raise ValueError(errmsg)

        if annotation_format not in ['raw', 'normalized']:
            errmsg = f'Unrecognized annotation format {annotation_format}.'\
                     f'Must be either "raw" or "normalized".'
            raise ValueError(errmsg)

    def _initialize_paths(self, version, annotation_format) -> bool:
        self._sentences_paths = {splitext(basename(p))[0].split('-')[-2]: p
                                 for p
                                 in glob(os.path.join(self.CACHE_DIR,
                                                      version,
                                                      annotation_format,
                                                      'sentence',
                                                      '*.json'))}

        self._documents_paths = {splitext(basename(p))[0].split('-')[-2]: p
                                 for p
                                 in glob(os.path.join(self.CACHE_DIR,
                                                      version,
                                                      annotation_format,
                                                      'document',
                                                      '*.json'))}

        self._sentences_annotation_dir = os.path.join(self.ANN_DIR,
                                                      version,
                                                      annotation_format,
                                                      'sentence',
                                                      'annotations')

        self._documents_annotation_dir = os.path.join(self.ANN_DIR,
                                                      version,
                                                      annotation_format,
                                                      'document',
                                                      'annotations')

        sent_ann_paths = glob(os.path.join(self._sentences_annotation_dir,
                                           '*.json'))
        doc_ann_paths = glob(os.path.join(self._documents_annotation_dir,
                                          '*.json'))

        # out of the box, the annotations are stored as zip files and the
        # JSON they contain must be extracted
        if not sent_ann_paths:
            zipped_sent_paths = os.path.join(self._sentences_annotation_dir,
                                             '*.zip')
            zipped_sentence_annotations = glob(zipped_sent_paths)

            for zipped in zipped_sentence_annotations:
                ZipFile(zipped).extractall(path=self._sentences_annotation_dir)

            sent_ann_paths = glob(os.path.join(self._sentences_annotation_dir,
                                               '*.json'))

        if not doc_ann_paths:
            zipped_doc_paths = os.path.join(self._documents_annotation_dir,
                                            '*.zip')

            zipped_document_annotations = glob(zipped_doc_paths)

            for zipped in zipped_document_annotations:
                ZipFile(zipped).extractall(path=self._documents_annotation_dir)

            doc_ann_paths = glob(os.path.join(self._documents_annotation_dir,
                                              '*.json'))

        self._sentence_annotation_paths = sent_ann_paths
        self._document_annotation_paths = doc_ann_paths

    def _check_build_status(self):
        sentences_built = self._sentences_paths and \
                          all(s in self._sentences_paths
                              for s in ['train', 'dev', 'test'])
        documents_built = self._documents_paths and \
                          all(s in self._documents_paths
                              for s in ['train', 'dev', 'test'])

        return sentences_built and documents_built

    def _load_split(self, split):
        sentence_fpath = self._sentences_paths[split]
        doc_fpath = self._documents_paths[split]
        split = self.__class__.from_json(sentence_fpath, doc_fpath)

        self._metadata += split.metadata

        self._sentences.update(split._sentences)
        self._documents.update(split._documents)

    def _process_conll(self, split, udewt):
        with ZipFile(BytesIO(udewt)) as zf:
            conll_names = [fname for fname in zf.namelist()
                           if splitext(fname)[-1] == '.conllu']
            for fn in conll_names:
                with zf.open(fn) as conll:
                    conll_str = conll.read().decode('utf-8')
                    sname = splitext(basename(fn))[0].split('-')[-1]
                    spl = self.__class__.from_conll(conll_str,
                                                    self._sentence_annotation_paths,
                                                    self._document_annotation_paths,
                                                    annotation_format=self.annotation_format,
                                                    version=self.version,
                                                    name='ewt-'+sname)

                    if sname == split or split is None:
                        # add metadata
                        self._metadata += spl.metadata

                        # prepare sentences
                        sentences_json_name = '-'.join(['uds', 'ewt', 'sentences',
                                                        sname, self.annotation_format]) +\
                                              '.json'
                        sentences_json_path = os.path.join(self.__class__.CACHE_DIR,
                                                           self.version,
                                                           self.annotation_format,
                                                           'sentence',
                                                           sentences_json_name)

                        self._sentences.update(spl._sentences)
                        self._sentences_paths[sname] = sentences_json_path

                        # prepare documents
                        documents_json_name = '-'.join(['uds', 'ewt', 'documents',
                                                        sname, self.annotation_format]) +\
                                              '.json'
                        documents_json_path = os.path.join(self.__class__.CACHE_DIR,
                                                           self.version,
                                                           self.annotation_format,
                                                           'document',
                                                           documents_json_name)

                        self._documents.update(spl._documents)
                        self._documents_paths[sname] = documents_json_path

                        # serialize both
                        spl.to_json(sentences_json_path, documents_json_path)

    @classmethod
    def from_conll(cls,
                   corpus: Location,
                   sentence_annotations: List[Location] = [],
                   document_annotations: List[Location] = [],
                   annotation_format: str = 'normalized',
                   version: str = '2.0',
                   name: str = 'ewt') -> 'UDSCorpus':
        """Load UDS graph corpus from CoNLL (dependencies) and JSON (annotations)

        This method should only be used if the UDS corpus is being
        (re)built. Otherwise, loading the corpus from the JSON shipped
        with this package using UDSCorpus.__init__ or
        UDSCorpus.from_json is suggested.

        Parameters
        ----------
        corpus
            (path to) Universal Dependencies corpus in conllu format
        sentence_annotations
            a list of paths to JSON files or open JSON files containing
            sentence-level annotations
        document_annotations
            a list of paths to JSON files or open JSON files containing
            document-level annotations
        annotation_format
            Whether the annotation is raw or normalized
        version
            the version of UDS datasets to use
        name
            corpus name to be appended to the beginning of graph ids
        """
        if annotation_format == 'raw':
            loader = RawUDSAnnotation.from_json
        elif annotation_format == 'normalized':
            loader = NormalizedUDSAnnotation.from_json
        else:
            raise ValueError('annotation_format must be either'
                             '"raw" or "normalized"')

        predpatt_corpus = PredPattCorpus.from_conll(corpus, name=name)
        predpatt_sentence_graphs = {name: UDSSentenceGraph(g, name)
                                    for name, g in predpatt_corpus.items()}
        predpatt_documents = cls._initialize_documents(predpatt_sentence_graphs)

        # process sentence-level graph annotations
        processed_sentence_annotations = []

        for ann_path in sentence_annotations:
            ann = loader(ann_path)
            processed_sentence_annotations.append(ann)

        # process document-level graph annotations
        processed_document_annotations = []

        for ann_path in document_annotations:
            ann = loader(ann_path)
            processed_document_annotations.append(ann)

        return cls(predpatt_sentence_graphs, predpatt_documents,
                   processed_sentence_annotations,
                   processed_document_annotations,
                   version=version,
                   annotation_format=annotation_format)

    @classmethod
    def _load_ud_ids(cls, sentence_ids_only: bool = False) -> Dict[str, Dict[str, str]]:
        # load in the document and sentence IDs for each sentence-level graph
        ud_ids_path = os.path.join(cls.ANN_DIR, 'ud_ids.json')

        with open(ud_ids_path) as ud_ids_file:
            ud_ids = json.load(ud_ids_file)

            if sentence_ids_only:
                return {k: v['sentence_id'] for k, v in ud_ids.items()}

            else:
                return ud_ids

    @classmethod
    def from_json(cls, sentences_jsonfile: Location,
                  documents_jsonfile: Location) -> 'UDSCorpus':
        """Load annotated UDS graph corpus (including annotations) from JSON

        This is the suggested method for loading the UDS corpus.

        Parameters
        ----------
        sentences_jsonfile
            file containing Universal Decompositional Semantics corpus
            sentence-level graphs in JSON format
        documents_jsonfile
            file containing Universal Decompositional Semantics corpus
            document-level graphs in JSON format
        """
        sentences_ext = splitext(basename(sentences_jsonfile))[-1]
        documents_ext = splitext(basename(documents_jsonfile))[-1]
        sent_ids = cls._load_ud_ids(sentence_ids_only=True)

        # process sentence-level graphs
        if isinstance(sentences_jsonfile, str) and sentences_ext == '.json':
            with open(sentences_jsonfile) as infile:
                sentences_json = json.load(infile)

        elif isinstance(sentences_jsonfile, str):
            sentences_json = json.loads(sentences_jsonfile)

        else:
            sentences_json = json.load(sentences_jsonfile)

        sentences = {name: UDSSentenceGraph.from_dict(g_json, name)
                     for name, g_json in sentences_json['data'].items()}

        # process document-level graphs
        if isinstance(documents_jsonfile, str) and documents_ext == '.json':
            with open(documents_jsonfile) as infile:
                documents_json = json.load(infile)

        elif isinstance(documents_jsonfile, str):
            documents_json = json.loads(documents_jsonfile)

        else:
            documents_json = json.load(documents_jsonfile)

        documents = {name: UDSDocument.from_dict(d_json, sentences,
                                                 sent_ids, name)
                     for name, d_json in documents_json['data'].items()}

        corpus = cls(sentences, documents)

        metadata_dict = {'sentence_metadata': sentences_json['metadata'],
                         'document_metadata': documents_json['metadata']}
        metadata = UDSCorpusMetadata.from_dict(metadata_dict)
        corpus.add_corpus_metadata(metadata)

        return corpus

    def add_corpus_metadata(self, metadata: UDSCorpusMetadata) -> None:
        self._metadata += metadata

    def add_annotation(self, sentence_annotation: UDSAnnotation,
                       document_annotation: UDSAnnotation) -> None:
        """Add annotations to UDS sentence and document graphs

        Parameters
        ----------
        sentence_annotation
            the annotations to add to the sentence graphs in the corpus
        document_annotation
            the annotations to add to the document graphs in the corpus
        """
        for ann in sentence_annotation:
            self.add_sentence_annotation(ann)

        for ann in document_annotation:
            self.add_document_annotation(ann)

    def add_sentence_annotation(self, annotation: UDSAnnotation) -> None:
        """Add annotations to UDS sentence graphs

        Parameters
        ----------
        annotation
            the annotations to add to the graphs in the corpus
        """
        self._metadata.add_sentence_metadata(annotation.metadata)

        for gname, (node_attrs, edge_attrs) in annotation.items():
            if gname in self._sentences:
                self._sentences[gname].add_annotation(node_attrs,
                                                      edge_attrs)

    def add_document_annotation(self, annotation: UDSAnnotation) -> None:
        """Add annotations to UDS documents

        Parameters
        ----------
        annotation
            the annotations to add to the documents in the corpus
        """
        self._metadata.add_document_metadata(annotation.metadata)

        for dname, (node_attrs, edge_attrs) in annotation.items():
            if dname in self._documents:
                self._documents[dname].add_annotation(node_attrs,
                                                      edge_attrs)

    @classmethod
    def _initialize_documents(cls, graphs: Dict[str, 'UDSSentenceGraph']) -> Dict[str, UDSDocument]:

        # Load the UD document and sentence IDs
        ud_ids = cls._load_ud_ids()

        # Add each graph to the appropriate document
        documents = {}
        for name, graph in graphs.items():
            doc_id = ud_ids[name]['document_id']
            sent_id = ud_ids[name]['sentence_id']
            graph.document_id = doc_id
            graph.sentence_id = sent_id

            # Add the graph to an existing document
            if doc_id in documents:
                documents[doc_id].add_sentence_graphs({name: graph}, {name: sent_id})
            # Create a new document
            else:
                genre = doc_id.split('-')[0]
                timestamp = UDSDocument._get_timestamp_from_document_name(doc_id)
                documents[doc_id] =\
                    UDSDocument({name: graph}, {name: sent_id}, doc_id, genre, timestamp)

        return documents

    def to_json(self,
                sentences_outfile: Optional[Location] = None,
                documents_outfile: Optional[Location] = None) -> Optional[str]:
        """Serialize corpus to json

        Parameters
        ----------
        sentences_outfile
            file to serialize sentence-level graphs to
        documents_outfile
            file to serialize document-level graphs to
        """
        metadata_serializable = self._metadata.to_dict()

        # convert graphs to dictionaries
        sentences_serializable = {'metadata': metadata_serializable['sentence_metadata'],
                                  'data': {name: graph.to_dict()
                                           for name, graph
                                           in self._sentences.items()}}

        if sentences_outfile is None:
            return json.dumps(sentences_serializable)

        elif isinstance(sentences_outfile, str):
            with open(sentences_outfile, 'w') as out:
                json.dump(sentences_serializable, out)

        else:
            json.dump(sentences_serializable, sentences_outfile)

        # Serialize documents (Note: we serialize only the *graphs*
        # for each document — not the metadata, which is loaded by
        # other means when calling UDSDocument.from_dict)
        documents_serializable = {'metadata': metadata_serializable['document_metadata'],
                                  'data': {name: doc.document_graph.to_dict()
                                           for name, doc
                                           in self._documents.items()}}

        if documents_outfile is None:
            return json.dumps(documents_serializable)

        elif isinstance(documents_outfile, str):
            with open(documents_outfile, 'w') as out:
                json.dump(documents_serializable, out)

        else:
            json.dump(documents_serializable, documents_outfile)

    @lru_cache(maxsize=128)
    def query(self, query: Union[str, Query],
              query_type: Optional[str] = None,
              cache_query: bool = True,
              cache_rdf: bool = True) -> Union[Result,
                                               Dict[str,
                                                    Dict[str, Any]]]:
        """Query all graphs in the corpus using SPARQL 1.1

        Parameters
        ----------
        query
            a SPARQL 1.1 query
        query_type
            whether this is a 'node' query or 'edge' query. If set to
            None (default), a Results object will be returned. The
            main reason to use this option is to automatically format
            the output of a custom query, since Results objects
            require additional postprocessing.
        cache_query
            whether to cache the query. This should usually be set to
            True. It should generally only be False when querying
            particular nodes or edges--e.g. as in precompiled queries.
        clear_rdf
            whether to delete the RDF constructed for querying
            against. This will slow down future queries but saves a
            lot of memory
        """
        return {gid: graph.query(query, query_type,
                                 cache_query, cache_rdf)
                for gid, graph in self.items()}

    @property
    def documents(self) -> Dict[str, UDSDocument]:
        """The documents in the corpus"""
        return self._documents

    @property
    def documentids(self):
        """The document ID for each document in the corpus"""
        return list(self._documents)

    @property
    def ndocuments(self):
        """The number of IDs in the corpus"""
        return len(self._documents)

    def sample_documents(self, k: int) -> Dict[str, UDSDocument]:
        """Sample k documents without replacement

        Parameters
        ----------
        k
            the number of documents to sample
        """

        return {doc_id: self._documents[doc_id]
                for doc_id
                in sample(self._documents.keys(), k=k)}

    @property
    def metadata(self):
        return self._metadata

    @property
    def sentence_node_subspaces(self) -> Set[str]:
        """The UDS sentence node subspaces in the corpus"""
        raise NotImplementedError

    @property
    def sentence_edge_subspaces(self) -> Set[str]:
        """The UDS sentence edge subspaces in the corpus"""
        raise NotImplementedError

    @property
    def sentence_subspaces(self) -> Set[str]:
        """The UDS sentence subspaces in the corpus"""
        return self.sentence_node_subspaces |\
               self.sentence_edge_subspaces

    @property
    def document_node_subspaces(self) -> Set[str]:
        """The UDS document node subspaces in the corpus"""
        raise NotImplementedError

    @property
    def document_edge_subspaces(self) -> Set[str]:
        """The UDS document edge subspaces in the corpus"""
        return self._document_edge_subspaces

    @property
    def document_subspaces(self) -> Set[str]:
        """The UDS document subspaces in the corpus"""
        return self.document_node_subspaces |\
               self.document_edge_subspaces

    def sentence_properties(self, subspace: Optional[str] = None) -> Set[str]:
        """The properties in a sentence subspace"""
        raise NotImplementedError

    def sentence_property_metadata(self, subspace: str,
                                   prop: str) -> UDSPropertyMetadata:
        """The metadata for a property in a sentence subspace

        Parameters
        ----------
        subspace
            The subspace the property is in
        prop
            The property in the subspace
        """
        raise NotImplementedError

    def document_properties(self, subspace: Optional[str] = None) -> Set[str]:
        """The properties in a document subspace"""
        raise NotImplementedError

    def document_property_metadata(self, subspace: str,
                                   prop: str) -> UDSPropertyMetadata:
        """The metadata for a property in a document subspace

        Parameters
        ----------
        subspace
            The subspace the property is in
        prop
            The property in the subspace
        """
        raise NotImplementedError


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

# In[1]:

import json, urllib
import plotly.graph_objects as go
import pandas as pd
import numpy as np

# In[2]:

asi_measures = pd.read_csv('final-data.csv')
asi_measures.head()

# In[4]:

all_nodes = asi_measures.Category.values.tolist() + asi_measures.ASI.values.tolist()
source_indices = [all_nodes.index(Category) for Category in asi_measures.Category]
target_indices = [all_nodes.index(ASI) for ASI in asi_measures.ASI]

fig = go.Figure(data=[go.Sankey(
    node = dict(
      pad = 20,
      thickness = 20,
      line = dict(color = "black", width = 1.0),
      label =  all_nodes,
    ),

    link = dict(
      source =  source_indices,
      target =  target_indices,
      value =  asi_measures.Count,
))])

fig.update_layout(title_text="Transport mitigation actions in the context of Avoid, Shift and Improve",
                  font_size=10)
fig.show()


from loader import dp, bot
from aiogram.types import ContentType, Message
from pathlib import Path

# kelgan hujjatlar (rasm/video/audio...) downloads/categories papkasiga tushadi
download_path = Path().joinpath("downloads","categories")
download_path.mkdir(parents=True, exist_ok=True)

@dp.message_handler()
async def text_handler(message: Message):
    await message.reply("Siz matn yubordingiz!")

@dp.message_handler(content_types=ContentType.DOCUMENT)
# @dp.message_handler(content_types='document')
async def doc_handler(message: Message):
    await message.document.download(destination=download_path)
    doc_id = message.document.file_id
    await message.reply("Siz hujjat yubordingiz!\n"
                        f"file_id = {doc_id}")

# @dp.message_handler(content_types=ContentType.VIDEO)
@dp.message_handler(content_types='video')
async def video_handler(message: Message):
    await message.video.download(destination=download_path)
    await message.reply("Video qabul qilindi\n"
                    f"file_id = {message.video.file_id}")

@dp.message_handler(content_types='photo')
async def video_handler(message: Message):
    await message.photo[-1].download(destination=download_path)
    await message.reply("Rasm qabul qilindi\n"
                    f"file_id = {message.photo[-1].file_id}")

# Bu yerga yuqoridagi 3 turdan boshqa barcha kontentlar tushadi
@dp.message_handler(content_types=ContentType.ANY)
async def any_handler(message: Message):
    await message.reply(f"{message.content_type} qabul qilindi")


from typing import NamedTuple, Optional, List, Dict, Any, Union
from enum import Enum, auto

import pysam

def _build_filter(rec: pysam.VariantRecord) -> List[Union[str, int]]:
    return [f for f in rec.filter]

def _build_info(rec: pysam.VariantRecord) -> Dict[str, Any]:
    info = dict()
    for key, value in rec.info.items():
        info[key] = value
    return info

def _build_format(rec: pysam.VariantRecord) -> List[str]:
    return [f for f in rec.format]

def _build_samples(rec: pysam.VariantRecord) -> Dict[str, Dict[str, Any]]:
    samples = dict()
    for sample_name in rec.samples:
        sample_dict = dict()
        for key, value in rec.samples[sample_name].items():
            sample_dict[key] = value
        samples[sample_name] = sample_dict
    return samples

class VariantType(Enum):
    """Enumeration with the different types of variations
    """
    SNV = auto()
    DEL = auto()
    INS = auto()
    DUP = auto()
    INV = auto()
    CNV = auto()
    TRA = auto()
    SGL = auto()

class BreakendSVRecord(NamedTuple):
    """NamedTuple with the information of a breakend notated SV record
    """
    prefix: Optional[str]
    """Prefix of the SV record with breakend notation. For example, for :code:`G]17:198982]` the prefix will be :code:`G`"""
    bracket: str
    """Bracket of the SV record with breakend notation. For example, for :code:`G]17:198982]` the bracket will be :code:`]`"""
    contig: str
    """Contig of the SV record with breakend notation. For example, for :code:`G]17:198982]` the contig will be :code:`17`"""
    pos: int
    """Position of the SV record with breakend notation. For example, for :code:`G]17:198982]` the position will be :code:`198982`"""
    suffix: Optional[str]
    """Suffix of the SV record with breakend notation. For example, for :code:`G]17:198982]` the suffix will be :code:`None`"""

class ShorthandSVRecord(NamedTuple):
    """NamedTuple with the information of a shorthand SV record
    """
    type: str
    """One of the following, :code:`'DEL'`, :code:`'INS'`, :code:`'DUP'`, :code:`'INV'` or :code:`'CNV'`"""
    extra: Optional[List[str]]
    """Extra information of the SV. For example, for :code:`<DUP:TANDEM:AA>` the extra will be :code:`['TANDEM', 'AA']`"""

def _str_value(value):
    if isinstance(value, str):
        return value
    elif isinstance(value, float):
        return f'{value:.2f}'
    elif hasattr(value, '__iter__'):
        return ','.join([_str_value(v) for v in value])
    elif value is None:
        return '.'
    else:
        return str(value)

def _convert_info_key_value(key, value):
    if value is None:
        return key
    elif isinstance(value, bool):
        return key if value else None
    else:
        return key+'='+_str_value(value)

def _convert_sample_value(key, value):
    if key == 'GT':
        return '/'.join([_str_value(v) for v in value])
    else:
        return _str_value(value)

class VariantRecord():
    """NamedTuple with the information of a variant record
    """
    contig: str
    """Contig name"""
    pos: int
    """Position of the variant in the contig"""
    end: int
    """End position of the variant in the contig (same as `pos` for TRA and SNV)"""
    length: int
    """Length of the variant"""
    id: Optional[str]
    """Record identifier"""
    ref: str
    """Reference sequence"""
    alt: str
    """Alternative sequence"""
    qual: Optional[float]
    """Quality score for the assertion made in ALT"""
    filter: List[Union[str, int]]
    """Filter status. PASS if this position has passed all filters. Otherwise, it contains the filters that failed"""
    variant_type: VariantType
    """Variant type"""
    alt_sv_breakend: Optional[BreakendSVRecord]
    """Breakend SV info, present only for SVs with breakend notation. For example, :code:`G]17:198982]`"""
    alt_sv_shorthand: Optional[ShorthandSVRecord]
    """Shorthand SV info, present only for SVs with shorthand notation. For example, :code:`<DUP:TANDEM>`"""

    def __init__(self, rec: pysam.VariantRecord, contig: str, pos: int, end: int,
                 length: int, id: Optional[str], ref: str,
                 alt: str, variant_type: VariantType,
                 alt_sv_breakend: Optional[BreakendSVRecord] = None,
                 alt_sv_shorthand: Optional[ShorthandSVRecord] = None):
        self._rec = rec
        self.contig = contig
        self.pos = pos
        self.end = end
        self.length = length
        self.id = id
        self.ref = ref
        self.alt = alt
        self.qual = rec.qual
        self.filter = _build_filter(rec)
        self.variant_type = variant_type
        self.alt_sv_breakend = alt_sv_breakend
        self.alt_sv_shorthand = alt_sv_shorthand

        self._info = None
        self._format = None
        self._samples = None

    @property
    def info(self):
        """Additional information"""
        if self._info is None:
            self._info = _build_info(self._rec)
        return self._info

    @info.setter
    def info(self, value):
        self._info = value

    @property
    def format(self):
        """Specifies data types and order of the genotype information"""
        if self._format is None:
            self._format = _build_format(self._rec)
        return self._format

    @format.setter
    def format(self, value):
        self._format = value

    @property
    def samples(self):
        """Genotype information for each sample"""
        if self._samples is None:
            self._samples = _build_samples(self._rec)
        return self._samples

    @samples.setter
    def samples(self, value):
        self._samples = value

    def _replace(self, **kwargs):
        new_record = VariantRecord(self._rec, self.contig, self.pos, self.end,
                                   self.length, self.id, self.ref, self.alt,
                                   self.variant_type, self.alt_sv_breakend,
                                   self.alt_sv_shorthand)
        for key, value in kwargs.items():
            setattr(new_record, key, value)
        return new_record

    def _info_str(self, rec_str: List[str]) -> str:
        # If info has not been loaded, return the original info string
        if self._info is None and len(rec_str) > 7:
            return rec_str[7]
        info_list = []
        for key, value in self.info.items():
            info_str = _convert_info_key_value(key, value)
            if info_str is None:
                continue
            info_list.append(info_str)
        if self.alt_sv_shorthand:
            info_list.insert(0, 'END='+str(self.end))
        info = ";".join(info_list)
        return info

    def _format_str(self, rec_str: List[str]) -> str:
        # If format has not been loaded, return the original format string
        if self._format is None and len(rec_str) > 8:
            return rec_str[8]
        return ":".join(self.format)

    def _samples_str(self, rec_str: List[str]) -> str:
        # If samples and format have not been loaded, return the original samples string
        if self._samples is None and self._format is None and len(rec_str) > 9:
            return '\t'.join(rec_str[9:])
        samples_list = [":".join([_convert_sample_value(k, self.samples[sample_name][k])
                                 for k in self.format]) for sample_name in self.samples]
        samples = "\t".join(samples_list)
        return samples

    def __str__(self):
        rec_str_split = str(self._rec).split('\t')
        contig = self.contig
        pos = self.pos
        id_ = self.id if self.id else '.'
        ref = self.ref
        alt = self.alt
        qual = _str_value(self.qual)
        filter_ = ";".join(map(str, self.filter)) if self.filter else '.'
        info = self._info_str(rec_str_split)
        format_ = self._format_str(rec_str_split)
        samples = self._samples_str(rec_str_split)
        return f'{contig}\t{pos}\t{id_}\t{ref}\t{alt}\t{qual}\t{filter_}\t{info}\t{format_}\t{samples}'.strip()


#!/usr/bin/python

import json
import re
import os
import sys

# Get data.json from Twitter for
# Followers: https://oauth-playground.glitch.me/?id=usersIdFollowers&params=%28%27user.fields%21%27description%27%29_
# Followings: https://oauth-playground.glitch.me/?id=usersIdFollowing&params=%28%27user.fields%21%27description%27%29_

with open(os.path.join(sys.path[0], "data.json"), "r") as fileData:
    jsonData = json.load(fileData)

    mastodonUrlRegex = re.compile(r'@\w*@\w*\.\w*')
    webUrlRegex = re.compile(r'http(s?)://.*/@\w*')

    for follower in jsonData['data']:
        name = follower['name']
        username = follower['username']
        description = follower['description']

        match1 = mastodonUrlRegex.search(description)
        if match1:
            print("%s (@%s) - %s" % (name, username, match1.group()))

        match2 = webUrlRegex.search(description)
        if match2:
            print("%s (@%s) - %s" % (name, username, match2.group()))


"""Utilities for plotting the results of the experiments."""
import os
import json
import numpy as np
import pandas as pd
import matplotlib
matplotlib.use("pdf")
# Avoid trouble when generating pdf's on a distant server
# matplotlib.use("TkAgg") # Be able to import matplotlib in ipython
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

def plot_cost_acc(params, lim_acc=None, lim_cost=None):
    """Plots the cost value and accuracy for test and train."""
    plt.plot(params["step"], params["cost_test"],
             label="SCE test", color="red")
    plt.plot(params["step"], params["cost_train"],
             label="SCE train", color="red", linestyle="--")
    plt.grid()
    plt.legend(loc="lower left")
    plt.ylabel("SCE", color="red")
    if lim_cost:
        plt.ylim(lim_cost)
    plt.twinx()
    plt.plot(params["step"], 1 - np.array(params["acc_test"]),
             label="miss test", color="blue")
    plt.plot(params["step"], 1 - np.array(params["acc_train"]),
             label="miss train", color="blue", linestyle="--")
    plt.ylabel("misses", color="blue")
    if lim_acc:
        plt.ylim(lim_acc)
    plt.legend(loc="upper right")
    plt.tight_layout()

def plot_norm(params):
    """Plots the regularization."""
    plt.plot(params["step"], params["norm_mat"], label="norm", color="red")
    plt.tight_layout()

# --- Quantile plotting functions ---

def quantile(X, q, axis=0):
    """np.quantile only exists on numpy 1.15 and higher."""
    assert axis == 0
    X = np.array(X)
    return np.sort(X, axis=0)[int(X.shape[0]*q), :]

def param_list_to_quant(key, q, p_list):
    """Returns a quantile."""
    if key.startswith("acc") or key.startswith("top"):
        # We plot the error rates 1-acc.
        return quantile(1-np.array([p[key] for p in p_list]), q)
    return quantile(np.array([p[key] for p in p_list]), q)

def plot_quant(params_list, param_name, label, color,
               linestyle="-", alpha=0.05):
    """Plots quantile intervals with the desired value."""
    p_list = params_list
    params = p_list[0]

    # Plot the result
    plt.fill_between(params["step"],
                     param_list_to_quant(param_name, (1-alpha/2), p_list),
                     param_list_to_quant(param_name, alpha/2, p_list),
                     color=color, alpha=0.25)
    plt.plot(params["step"], param_list_to_quant(param_name, 0.5, p_list),
             label=label, color=color, linestyle=linestyle)

def plot_quant_cost_acc(params_list, alpha, lim_acc=None, lim_cost=None,
                        left_label_remove=False, right_label_remove=False):
    """Plots quantile intervals of the cost value and accuracy."""

    p_list = params_list
    params = p_list[0]

    # Plot the result
    plt.fill_between(params["step"],
                     param_list_to_quant("cost_test", (1-alpha/2), p_list),
                     param_list_to_quant("cost_test", alpha/2, p_list),
                     color="red", alpha=0.25)
    plt.plot(params["step"], param_list_to_quant("cost_test", 0.5, p_list),
             label="SCE test", color="red")
    plt.plot(params["step"], param_list_to_quant("cost_train", 0.5, p_list),
             label="SCE train", color="red", linestyle="--")
    plt.grid()
    plt.legend(loc="lower left")

    if not left_label_remove:
        plt.ylabel("SCE", color="red")
    else:
        plt.gca().yaxis.set_ticklabels([])
    if lim_cost:
        plt.ylim(lim_cost)
    plt.twinx()
    plt.fill_between(params["step"],
                     param_list_to_quant("acc_test", (1-alpha/2), p_list),
                     param_list_to_quant("acc_test", alpha/2, p_list),
                     color="blue", alpha=0.25)
    plt.plot(params["step"],
             np.array(param_list_to_quant("acc_test", 0.5, p_list)),
             label="miss test", color="blue")
    plt.plot(params["step"],
             np.array(param_list_to_quant("acc_train", 0.5, p_list)),
             label="miss train", color="blue", linestyle="--")

    if not right_label_remove:
        plt.ylabel("misses", color="blue")
    else:
        plt.gca().yaxis.set_ticklabels([])
    if lim_acc:
        plt.ylim(lim_acc)
    plt.legend(loc="upper right")
    plt.tight_layout()

def plot_quantiles(root_exp_folder,
                   subfolds=("uniform", "prediction", "stratum"),
                   alpha=0.05, figsize=(3, 3),
                   lim_acc=None, lim_cost=None,
                   camera_ready=True):
    """
        Plot the quantile graphs for a standardized experiment.

        If the experiment data is in a folder named exp, it expects to find
        subfolders subfolds in which there are folders with runs and a
        params.json file that contains the result of the runs. It will generate
        a quantile plot for each of the experiments.
    """
    for type_weight in subfolds:
        cur_dir = "{}/tw_{}/".format(root_exp_folder, type_weight)
        params_list = get_param_list_for_quantiles(root_exp_folder,
                                                   type_weight)

        plt.figure(figsize=figsize)
        right_label_remove = camera_ready and type_weight == "uniform"
        left_label_remove = camera_ready and type_weight == "prediction"
        plot_quant_cost_acc(params_list, alpha=alpha,
                            lim_acc=lim_acc, lim_cost=lim_cost,
                            left_label_remove=left_label_remove,
                            right_label_remove=right_label_remove)
        if not camera_ready:
            plt.title(type_weight)
        plt.savefig("{}/{}.pdf".format(cur_dir, "quantiles"), format="pdf")

def get_param_list_for_quantiles(root_exp_folder, type_weight):
    """Accumulates all of the json files for different runs and reweighting."""
    cur_dir = "{}/tw_{}/".format(root_exp_folder, type_weight)
    cur_runs = os.listdir(cur_dir)
    params_list = list()
    for cur_run in cur_runs:
        cur_file = cur_dir + cur_run + "/params.json"
        if os.path.exists(cur_file):
            params_list.append(json.load(open(cur_file, "rt")))
    return params_list

def plot_quantiles_cost_n_miss(root_exp_folder,
                               subfolds=("uniform", "prediction", "stratum"),
                               sf_style={"uniform": {"color": "blue",
                                                     "label": "Uniform"},
                                         "prediction": {"color": "green",
                                                        "label": "Weighted"},
                                         "stratum": {"color": "green",
                                                     "label": "Stratum"},
                                        },
                               alpha=0.05, figsize=(3, 3), lim_acc=None,
                               lim_cost=None, lim_top=None, camera_ready=True):
    """
        Plot the quantile graphs for a standardized experiment.

        If the experiment data is in a folder named exp, it expects to find
        subfolders subfolds in which there are folders with runs and a
        params.json file that contains the result of the runs. It will generate
        a quantile plot for each of the experiments.
    """
    print("Loading the data...")
    list_params_list = list()
    for type_weight in subfolds:
        list_params_list.append(get_param_list_for_quantiles(
            root_exp_folder, type_weight))

    print("Plotting results...")
    for plotted_val in ("acc", "cost", "topk"):
        plt.figure(figsize=figsize)
        for itw, type_weight in enumerate(subfolds):
            params_list = list_params_list[itw]

            params = params_list[0]

            color = sf_style[type_weight]["color"]

            plot_quant(params_list, "{}_test".format(plotted_val), "",
                       color=color)
            plt.plot(params["step"], param_list_to_quant(
                "{}_train".format(plotted_val), 0.5, params_list),
                     color=color, linestyle="--")
        if plotted_val == "acc" and lim_acc:
            plt.ylim(lim_acc)
            plt.ylabel("Miss rate")
        if plotted_val == "cost" and lim_cost:
            plt.ylim(lim_cost)
            plt.ylabel("SCE")
        if plotted_val == "topk" and lim_top:
            plt.ylim(lim_top)
            plt.ylabel("Top-5 error")
        if not camera_ready:
            plt.title(plotted_val)

        train_lgd = Line2D([0, 0], [1, 1], color="black", linestyle="--")
        test_lgd = Line2D([0, 0], [1, 1], color="black", linestyle="-")
        legend1 = plt.gca().legend([train_lgd, test_lgd], ["Train", "Test"],
                                   loc="upper right")
        legend_lines = [Line2D([0, 0], [1, 1],
                               color=sf_style[k]["color"], linestyle="-")
                        for k in subfolds]
        legend_names = [sf_style[k]["label"] for k in subfolds]
        plt.gca().legend(legend_lines, legend_names, loc="lower left")
        plt.gca().add_artist(legend1)

        plt.grid()
        plt.tight_layout()
        # elif plotted_val == "acc":
        #     plt.title("Miss rate")
        # else:
        #     plt.title("SCE")
        plt.savefig("{}/{}_{}.pdf".format(root_exp_folder, "quant",
                                          plotted_val), format="pdf")
    print("Done !")

def plot_class_probas(params, with_ticklabels=True):
    """Plots the probabilities of each class for the train and test set."""
    n_classes = len(params["p_y_train"])
    width = 0.35
    ind = np.arange(n_classes)
    ax = plt.gcf().subplots()
    rects1 = ax.bar(ind, params["p_y_train"], width, color="blue")
    rects2 = ax.bar(ind + width, params["p_y_test"], width, color="green")

    ax.set_ylabel("Probability")
    ax.set_xlabel("Class")
    ax.set_xticks(ind+width/2)

    if with_ticklabels:
        ax.set_xticklabels(ind)
    else:
        ax.set_xticklabels(["" for _ in ind])

    ax.legend((rects1[0], rects2[0]), ("Train", "Test"))
    plt.grid()
    plt.gcf().tight_layout()

def plot_strata_probas(params, with_ticklabels=True):
    """Plot the probabilities of each strata for train and test."""
    n_stratas = len(params["p_z_train"])
    width = 0.35
    ind = np.arange(n_stratas)
    ax = plt.gcf().subplots()
    rects1 = ax.bar(ind, params["p_z_train"], width, color="blue")
    rects2 = ax.bar(ind + width, params["p_z_test"], width, color="green")

    ax.set_ylabel("Probability")
    ax.set_xlabel("Strata")
    ax.set_xticks(ind+width/2)
    if with_ticklabels:
        ax.set_xticklabels(ind)
    else:
        ax.set_xticklabels(["" for _ in ind])
    ax.legend((rects1[0], rects2[0]), ("Train", "Test"))
    plt.gca().yaxis.grid(True)
    # plt.grid()
    plt.gcf().tight_layout()


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

import os
import sys
import rospy
import numpy as np

import cv2
from sensor_msgs.msg import Image, CompressedImage
from cv_bridge import CvBridge, CvBridgeError

from darknet_ros_msgs.msg import BoundingBoxes, ObjectCount

class Bridge(object):
    """압축된 이미지를 센서 메세지 형태로 변환한다.."""

    def __init__(self):
        # 글로벌 변수 설정
        self.bridge = CvBridge()
        self.bounding_boxes = BoundingBoxes()
        self.image = None

        # 발행 설정
        self.compressed_detection_image_pub = rospy.Publisher("/detection_image/compressed", CompressedImage, queue_size=1)

        # 구독 설정
        compressed_color_image_sub = rospy.Subscriber("camera/color/image_raw/compressed", CompressedImage, self.bridge_color_image)
        bounding_boxes_sub = rospy.Subscriber('darknet_ros/bounding_boxes', BoundingBoxes, self.update_bounding_boxes)

    def bridge_color_image(self, data):
        """
        """

        # 압축 데이터를 CV 배열로 변환
        np_arr = np.fromstring(data.data, np.uint8)
        self.image = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)

        # try:
        #     self.color_image_pub.publish(self.bridge.cv2_to_imgmsg(color_image, "bgr8"))

        # except CvBridgeError as e:
        #     print(e)

    def update_bounding_boxes(self, data):
        bounding_boxes = data

        for i in range(len(self.bounding_boxes.bounding_boxes)):
            try:
                if self.bounding_boxes.bounding_boxes[i].Class == 'person':
                    probability = self.bounding_boxes.bounding_boxes[i].probability
                    xmin = self.bounding_boxes.bounding_boxes[i].xmin
                    ymin = self.bounding_boxes.bounding_boxes[i].ymin
                    xmax = self.bounding_boxes.bounding_boxes[i].xmax
                    ymax = self.bounding_boxes.bounding_boxes[i].ymax
                    _id = i + 1
                    _class = self.bounding_boxes.bounding_boxes[i].Class
            except:
                pass

    # def bridge_detection_image(self, data):
    #     """
    #     """
    #     # try:
    #     detection_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
    #     # except CvBridgeError as e:
    #     #     print(e)

    #     compressed_detection_image = CompressedImage()
    #     compressed_detection_image.header.stamp = rospy.Time.now()
    #     compressed_detection_image.format = "jpeg"
    #     compressed_detection_image.data = cv2.imencode('.jpg', detection_image)[1].tostring()

    #     try:
    #         self.compressed_detection_image_pub.publish(compressed_detection_image)

    #     except CvBridgeError as e:
    #         print(e)

if __name__ == '__main__':
    rospy.init_node('bridge', anonymous=False)
    bridge = Bridge()
    rospy.spin()


from typing import Callable

def format_number(number: int) -> str:
    num = float(f"{number:.3g}")
    magnitude = 0

    format_human: Callable[[float], str] = lambda x: f"{x:f}".rstrip("0").rstrip(".")

    while abs(num) >= 1000:
        magnitude += 1
        num /= 1000.0

    return f"{format_human(num)}{['', 'K', 'M', 'G', 'T', 'P'][magnitude]}"


import itertools
from itertools import izip, cycle
import os
import string
import glob
from moduleBaseClass import ModuleBaseClass

class XorStuff:

    def __init__(self, filepath=None):
        """Constructor : set xored file (optional)

        """
        self.file_type = None
        self.list_types = self.load_files_types('modules/')
        if filepath is not None:
            self.file_content = self.set_file_content(filepath)

    def load_files_types(self, path):
        """Load all modules from modules/ and make them available

        """
        list_types = {}
        files = glob.glob(path + "*")
        for file in files:
            file_name, file_extension = os.path.splitext(file)
            if not file_name.endswith("__init__") and file_extension == ".py":
                module_name = file_name.replace("/", ".")
                mod = __import__(module_name)
                modules = module_name.split('.')
                for module in modules[1:]:
                    mod = getattr(mod, module)
                    if issubclass(mod.Module, ModuleBaseClass):
                        instance = mod.Module()
                        list_types[instance.name] = instance
        return list_types

    def xor(self, data, key, file_type=None):
        """Perform a simple xor with data and key
           file_type is an instance of modules and provide file checking

        """
        result = []
        for data, char_key in izip(data, cycle(key)):
            byte = chr(ord(data) ^ ord(char_key))
            if file_type is not None:
                if not file_type.live_check(byte):
                    return None
            result.append(byte)
        return ''.join(result)

    def set_file_content(self, filepath, length=None):
        """Open xored file and store content
           Optional : can store n bytes only
        """
        bin_file = ''
        with open(filepath, "rb") as f:
            byte = f.read(1)
            index = 0
            while byte != "":
                bin_file = bin_file + byte
                byte = f.read(1)
                if length is not None:
                    if index == length:
                        break
                    index = index + 1
        self.file_content = bin_file

    def get_pass(self, key_length, grep=None):
        """Try to recover key(s) for a given length and yield them
           Optional : can grep bytes in result
        """
        # Padding of header with %s if key length > header length
        if int(key_length) > len(self.file_type.header):
            header_no_formatters = self.file_type.header.replace('%s', '?')
            formatters = '%s' * (int(key_length) - len(header_no_formatters))
            self.file_type.header = "%s%s" % (self.file_type.header,
                                              formatters)

        bf_length = self.file_type.header.count('%s')
        header_length = len(self.file_type.header.replace('%s', '?'))
        bin_header = self.file_content[:header_length]

        charset = ''.join([chr(i) for i in range(128)])
        key_charset = string.ascii_letters + string.digits + string.punctuation

        # generate keys
        for char in itertools.product(charset, repeat=bf_length):
            generated_header = self.file_type.header % char
            output = self.xor(bin_header, generated_header)
            key = output[0: key_length]
            if not [c for c in key if c not in key_charset]:
                raw = self.xor(self.file_content, key, self.file_type)
                if raw is not None:
                    if self.file_type.final_check(raw):
                        if grep is not None:
                            if grep in raw:
                                yield key
                        else:
                            yield key

    def set_file_type(self, file_type):
        """Load correct file type module according to file extension name

        """
        self.file_type = self.list_types[file_type]


from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views import generic
#from django.template import loader  # no longer needed b/c of render shortcut

from .models import Question, Choice

# Create your views here.
class IndexView(generic.ListView):
    """
    """
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        return Question.objects.order_by('-pub_date')[:5]

class DetailView(generic.DetailView):
    """
    This is a generic view. Each generic view needs to know
    what model it will be acting upon. This is provided using
    the model attribute. The detail view expects the primary key
    value captured from the url to be called 'pk' so we changed
    question_id to pk for the generic views.
    """
    model = Question
    template_name = 'polls/detail.html'

class ResultsView(generic.DetailView):
    """
    This is a generic view
    """
    model = Question
    template_name = 'polls/results.html'

def vote(request, question_id):
    """
    This function will increase the number of votes a selected
    question have, if it exists, and then redirect us to the results
    page. If said question fails, we are given a 404 error!

    Reverse will take us to the view specified by arg1 along with the
    variable portion of the url specified by arg2.
    """
    question = get_object_or_404(Question, pk=question_id)
    try:
        # this will obtain the id of the selected choice as a string
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # error message if choice isn't given
        return render(request, 'polls/detail.html', {'question': question, 'error_message': "You didn't select a choice."})
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # redirected to this url - always return a redirect after successfully
        # dealing with POST data - prevents data from being posted twice if the
        # user hits the back button
        return HttpResponseRedirect(reverse('polls:results', args=(question_id,)))

#################################################################################################################3
### Previous versions of functions below!
#################################################################################################################3

#def index(request):
    #"""
    #index will display the latest 5 poll questions in the system, separated by commans,
    #according to the publication date.
    #"""
    #latest_question_list = Question.objects.order_by('-pub_date')[:5]
    #template = loader.get_template('polls/index.html')
    #context = {
        #'latest_question_list': latest_question_list
    #}
    # httpresponse is common, but render is a shortcut!
    #return HttpResponse(template.render(context, request))

#def index(request):
    #"""
    #The simplest view possible in Django
    #"""
    #return HttpResponse("Hello world! You're at the polls index!")

# one way of writing a 404 error
#def detail(request, question_id):
    #"""
    #Returns a simple template response.
    #"""
    #try:
        #question = Question.objects.get(pk=question_id)
    #except Question.DoesNotExist:
        #raise Http404("Question does not exist!")
    #return render(request, 'polls/detail.html', {'question': question})


import os
import zipfile
from abc import ABCMeta
from pathlib import Path
from typing import Optional, Union
from urllib.request import urlretrieve

class BaseDownloader(metaclass=ABCMeta):
    """Base downloader for all Movielens datasets."""

    DOWNLOAD_URL: str
    DEFAULT_PATH: str

    def __init__(self, zip_path: Optional[Union[Path, str]] = None):
        if zip_path is None:
            zip_path = self.DEFAULT_PATH
        else:
            zip_path = zip_path
        self.zip_path = Path(zip_path)
        if not self.zip_path.exists():
            self._retrieve()

    def _retrieve(self) -> None:
        url: str = self.DOWNLOAD_URL
        file_name: str = str(self.zip_path) + ".zip"
        urlretrieve(url, filename=file_name)
        with zipfile.ZipFile(file_name) as zf:
            zf.extractall(self.zip_path.parent)
        os.remove(file_name)


import markovify
import sys
import argparse
import configparser
import twitter

model_depth_default = 2
model_depth = model_depth_default

def main():
	arg_parser = argparse.ArgumentParser(description="Generate text with Markov chains based on a source corpus.")
	subparser = arg_parser.add_subparsers(dest="subparser_name")

	subparser_train = subparser.add_parser("train")
	subparser_train.add_argument("corpus", help="Path to a corpus to train with.")
	subparser_train.add_argument("savepath", help="Path to where to save the model, in JSON format.")

	subparser_tweet = subparser.add_parser("tweet")
	subparser_tweet.add_argument("corpus", help="Path to a corpus.")
	subparser_tweet.add_argument("modelpath", help="Path to a model built with \"train\"")
	subparser_tweet.add_argument("--no-post", help="Do not post to Twitter, write to stdout and exit.", action="store_true")

	args = arg_parser.parse_args()

	config = configparser.ConfigParser()
	config.read("poorlytrained.ini")
	twitter_consumer_key = config["keys"]["consumerkey"]
	twitter_consumer_secret = config["keys"]["consumersecret"]
	twitter_access_token = config["keys"]["accesstoken"]
	twitter_access_token_secret = config["keys"]["accesstokensecret"]

	try:
		model_depth = config["markov"]["modeldepth"]
	except:
		sys.stderr.write("WARNING: Could not read model depth from configuration file. Defaulting to {}.\n".format(model_depth_default))

	if(args.subparser_name == "train"):
		with open(args.corpus) as f:
			text = f.read()

		text_model = markovify.Text(text)

		with open(args.savepath, "w") as f:
			f.write(text_model.chain.to_json())

	elif(args.subparser_name == "tweet"):
		with open(args.corpus) as corpus:
			with open(args.modelpath) as model:
				model_chain = markovify.Chain.from_json(model.read())
				text_model = markovify.Text(corpus.read(), model_depth, model_chain)

		tweet_message = text_model.make_short_sentence(140)
		print(tweet_message)

		if(args.no_post == False): # If --no-post was not specified, go ahead and post.
			tapi = twitter.Api(twitter_consumer_key, twitter_consumer_secret, twitter_access_token, twitter_access_token_secret)
			tapi.PostUpdate(tweet_message)
if __name__ == "__main__":
	main()


"""
enums.py

Contains the different types of objects for the application.
"""
# Import modules and libraries
from enum import Enum

class UserType(Enum):
    """
    Represents the different types of users in the application.
    """
    admin = "admin"
    manager = "manager"
    inspector = "inspector"
    maintenance_worker = "maintenance_worker"
    repair_tech = "repair_tech"
    user = "user" # Default value
    archived = "archived"

class FireClass(Enum):
    """
    Represents the common fire types an extinguisher can put out in the United States.
    """
    A = "A" # Ordinary solid combustibles
    B = "B" # Flammable liquids and gases
    C = "C" # Energized electrical equipment
    D = "D" # Combustible metals
    K = "K" # Oils and fats
    ABC = "ABC" # Multi-purpose dry chemical
    other = "other" # Default value

class TicketType(Enum):
    """
    Represents the type of ticket.
    """
    inspect = "inspect"
    damaged_ext = "damaged_ext"
    repair_ext = "repair_ext"
    damaged_box = "damaged_box"
    repair_box = "repair_box"
    other = "other" # Default value

class TicketState(Enum):
    """
    Represents the state of a ticket.
    """
    open = "open"
    in_progress = "in_progress"
    closed = "closed"
    archived = "archived"


# This is a sample Python script.

# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import sys
import asyncio
import datetime
import time
import collections
import json

# function to execute aws cli 'iam' command
async def getAwsIamData(require_data:str) -> list:
    command = "aws iam "
    command += require_data
    process = await asyncio.create_subprocess_shell(
        command,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)
    return await process.communicate()

# function to get user list
async def getAwsUserList() -> str:
    output, errs = await getAwsIamData("list-users")
    if errs:
        print("Error occurred to get user list")
        return "error"

    return output.decode()

# function to get access key list
async def getAwsAccessKeys(userName) -> str:
    output, errs = await getAwsIamData("list-access-keys --user-name " + userName)
    if errs:
        print("Error occurred to get access key list:", errs)
        return "error"

    return output.decode()

# get access key list per user and arranging them in the dictionary
async def arrangeUserAccessKeyData(user_map, userName:str, current_time:float, valid_time:int):
    # request access key list assigned to {userName}
    keys = json.loads(await getAwsAccessKeys(userName))

    # iterate access keys and check if it is valid.
    for key in keys["AccessKeyMetadata"]:
        if await checkIsValid(key["CreateDate"], current_time, valid_time):
            user_map[key["UserName"]]["UserName"] = key["UserName"]
            user_map[key["UserName"]]["AccessKeyId"] = key["AccessKeyId"]
            user_map[key["UserName"]]["CreateDate"] = key["CreateDate"]

# check if create_time + valid_time is older than current_time
async def checkIsValid(created_time:str, current_time:float, valid_time:int) -> bool:
    date = datetime.datetime.strptime(created_time, '%Y-%m-%dT%H:%M:%S+00:00')
    created_at = time.mktime(date.timetuple())

    # print("diff: ", (current_time - (created_at + valid_time)) // 3600)
    if created_at + valid_time < current_time: # user is not valid
        return True
    else: # user is still valid
        return False

async def detectInvalidUserkey(valid_time:int):

    users = json.loads(await getAwsUserList())
    if users == "error":
        print("Error occurred to get User data")
        return

    # dictionary to save user/key data
    user_data = collections.defaultdict(dict)
    # current time to be base
    current_time = time.time()
    valid_time *= 3600

    tasks = []
    # get access keys per user and arrange them in 'user_data' dictionary
    for user in users["Users"]:
        tasks.append(arrangeUserAccessKeyData(user_data, user["UserName"], current_time, valid_time))
    # running the tasks asynchronously
    await asyncio.gather(*tasks)

    # write result(user_data) on the file
    with open("invalid_access_keys.txt", "w") as fd:
        fd.write(" - Get Invalid User List - At: " + datetime.datetime.fromtimestamp(current_time).strftime("%m/%d/%Y, %H:%M:%S") + "\n\n")
        for key, val in user_data.items():
            fd.write(" " + "{\n")
            for nkey, nval in val.items():
                fd.write(" \t" + nkey + ": " + nval + "\n")
            fd.write(" }\n")

# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    limit = int(sys.argv[1])
    if not limit:
        print("please put validation time to filter access keys.")
    else:
        asyncio.run(detectInvalidUserkey(limit))


#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Fri Oct 21 16:38:00 2016

@author: Neo

Oct 25, 2016: updated by Niu.
"""

import numpy as np
import matplotlib.pyplot as plt

res_dir = '../results/'
dat_fil = ['OVrot.dat', 'GRrot.dat']

#glide for the three special catalog
w3 = np.loadtxt(res_dir + 'SpecialSets.rot', usecols=(1,3,5,7))

Num = np.loadtxt(res_dir + dat_fil[0], usecols=(0,), dtype=int)
W, W_E, WX, WX_E, WY, WY_E, WZ, WZ_E = \
        np.loadtxt(res_dir + dat_fil[0], usecols=list(range(1,9)), unpack=True)
Wg, W_Eg, WXg, WX_Eg, WYg, WY_Eg, WZg, WZ_Eg = \
        np.loadtxt(res_dir + dat_fil[1], usecols=list(range(1,9)), unpack=True)

i = Num
y = np.ones(Num.size)

#############################################################################
#plot, writted a year ago.

#i = range(100,len(Sou)+1)
#y = np.ones(len(i))
#
#fig, ax = plt.subplots(2, 2)
#((ax1, ax2), (ax3, ax4)) = ax
#
#ax1.plot(i, WX, 'b')
##ax1.plot(i, WXg, 'r')
#ax1.set_ylabel('$\omega_x$',fontsize = 25)
#ax1.plot(i, w3[0][1]*y, ':', label = '212 ICRF' )
#ax1.plot(i, w3[1][1]*y, '-.', label = '295 ICRF' )
#ax1.plot(i, w3[2][1]*y, '--', label = '247 MFV' )
#
#ax2.plot(i, WY, 'b')
##ax2.plot(i, WYg, 'r')
#ax2.set_ylabel('$\omega_y$',fontsize = 25)
#ax2.plot(i, w3[0][2]*y, ':', label = '212 ICRF'  )
#ax2.plot(i, w3[1][2]*y, '-.', label = '295 ICRF' )
#ax2.plot(i, w3[2][2]*y, '--', label = '247 MFV' )
#
#ax3.plot(i, WZ, 'b')
##ax3.plot(i, WZg, 'r')
#ax3.set_ylabel('$\omega_z$',fontsize = 25)
#ax3.plot(i, w3[0][3]*y, ':', label = '212 ICRF'  )
#ax3.plot(i, w3[1][3]*y, '-.', label = '295 ICRF' )
#ax3.plot(i, w3[2][3]*y, '--', label = '247 MFV' )
#
#ax4.plot(i, W, 'b')
##ax4.plot(i, Wg, 'r')
#ax4.set_ylabel('$\omega$',fontsize = 25)
#ax4.plot(i, w3[0][0]*y, ':' , label = '212 ICRF' )
#ax4.plot(i, w3[1][0]*y, '-.', label = '295 ICRF' )
#ax4.plot(i, w3[2][0]*y, '--', label = '247 MFV' )
#
#ax1.legend()
#ax2.legend()
#ax3.legend()
#ax4.legend()
#
#ax1.set_xlabel('No. Sources',fontsize = 15)
#ax2.set_xlabel('No. Sources',fontsize = 15)
#ax3.set_xlabel('No. Sources',fontsize = 15)
#ax4.set_xlabel('No. Sources',fontsize = 15)
#
#plt.show()
##plt.savefig('../plot/OARank_rot.eps')
#plt.savefig('../plot/GRank_rot.eps')

##############################################################################
plt.figure()

#set the size of subplots
left,width = 0.10,0.85
bottom,height = 0.1, 0.17
bottom_3 = bottom + height*2 + 0.01
bottom_2 = bottom_3 + height + 0.01
bottom_1 = bottom_2 + height + 0.01

scale4 = [left, bottom,   width, height*2]
scale3 = [left, bottom_3, width, height]
scale2 = [left, bottom_2, width, height]
scale1 = [left, bottom_1, width, height]

ax1 = plt.axes(scale1)
ax2 = plt.axes(scale2, sharex = ax1)
ax3 = plt.axes(scale3, sharex = ax1)
ax4 = plt.axes(scale4)

ax1.plot(i, np.abs(WX) , 'b', linewidth=3)
ax1.plot(i, np.abs(WXg), 'r', linewidth=3)
ax1.set_ylabel('$r_1$',fontsize = 25)
ax1.set_xlim([100, max(i)])
ax1.set_xticks([100,150,200,250,300,350,400,450,500,550])
ax1.set_xticklabels(['','','','','','','','','',''])
ax1.set_ylim([0,15])
ax1.set_yticks(np.arange(0, 15, 5))
ax1.set_yticklabels(['0','5','10'],fontsize = 12)
ax1.plot(i, np.abs(w3[0][1])*y, 'b--', label = '212 ICRF' )
ax1.plot(i, np.abs(w3[1][1])*y, 'g--', label = '295 ICRF')
ax1.plot(i, np.abs(w3[2][1])*y, 'y--', label = '247 MFV' )
ax1.plot(i, np.abs(w3[3][1])*y, 'k--', label = '260 AMS' )

ax2.plot(i, np.abs(WY) , 'b', linewidth=3)
ax2.plot(i, np.abs(WYg), 'r', linewidth=3)
ax2.set_ylabel('$r_2$',fontsize = 25)
ax2.set_ylim([0,20])
ax2.set_yticks([0,5,10,15])
ax2.set_yticklabels(['0','5','10','15'],fontsize = 12)
ax2.plot(i, np.abs(w3[0][2])*y, 'b--', label = '212 ICRF' )
ax2.plot(i, np.abs(w3[1][2])*y, 'g--', label = '295 ICRF')
ax2.plot(i, np.abs(w3[2][2])*y, 'y--', label = '247 MFV' )
ax2.plot(i, np.abs(w3[3][2])*y, 'k--', label = '260 AMS' )

ax3.plot(i, np.abs(WZ) , 'b', linewidth=3)
ax3.plot(i, np.abs(WZg), 'r', linewidth=3)
ax3.set_ylabel('$r_3$',fontsize = 25)
ax3.set_ylim([0, 15])
ax3.set_yticks(np.arange(0, 15, 5))
ax3.set_yticklabels(['0','5','10'],fontsize = 12)
ax3.plot(i, w3[0][3]*y, 'b--', label = '212 ICRF' )
ax3.plot(i, w3[1][3]*y, 'g--', label = '295 ICRF')
ax3.plot(i, w3[2][3]*y, 'y--', label = '247 MFV' )
ax3.plot(i, w3[3][3]*y, 'k--', label = '260 AMS' )

ax4.plot(i, W, 'b', linewidth=3)
ax4.plot(i, Wg, 'r', linewidth=3)
ax4.set_ylabel('$r$', fontsize=25)
ax4.set_ylim([0,20])
ax4.set_yticks(np.arange(0, 20, 5))
ax4.set_yticklabels(['0','5','10','15'],fontsize = 12)
ax4.plot(i, w3[0][0]*y, 'b--' , label = '212 ICRF' )
ax4.plot(i, w3[1][0]*y, 'g--', label = '295 ICRF' )
ax4.plot(i, w3[2][0]*y, 'y--', label = '247 MFV' )
ax4.plot(i, w3[3][0]*y, 'k--', label = '260 AMS' )
ax4.set_xlim([100,max(i)])
ax4.set_xticks([100,150,200,250,300,350,400,450,500,550, max(i)])
ax4.set_xticklabels(['100','','200','','300','','400','','500', ''],fontsize = 15)
ax4.legend(loc=0, fontsize=10)
ax4.set_xlabel('No. Sources', fontsize=15)

plt.show()
plt.savefig('../plot/Rotation_No.eps', dpi=100)
plt.close()

print('Done!')


from enum import Enum
from dynsimf.models.helpers.ConfigValidator import ConfigValidator
from dynsimf.models.components.conditions.Condition import Condition

__author__ = "Mathijs Maijer"
__email__ = "m.f.maijer@gmail.com"

class UpdateType(Enum):
    '''
    An Enum to specify the type of the update
    '''
    STATE = 0
    NETWORK = 1
    EDGE_VALUES = 2

class UpdateConfiguration(object):
    '''
    Configuration for Updates

    :var config: The dictionary containing the key/value pairs of the members of this class,
        if no key/value pair is provided, a default value is used instead
    :vartype config: dict
    :var arguments: A dictionary with arguments for the update function, defaults to empty dict
    :vartype arguments: dict
    :var condition: A condition for nodes that must be met before the update is executed on them
    :vartype condition: Condition or None
    :var get_nodes: A boolean indicating whether the update function should receive a list of sampled nodes as argument,
        defaults to None
    :vartype get-nodes: bool or None
    :var update_type: A value from the `UpdateType` enum, indicating what kind of update is being performed,
        defaults to `UpdateType.STATE`
    :vartype update_type: UpdateType
    '''
    def __init__(self, config=None):
        self.set_config(config)
        self.validate()

    def set_config(self, config):
        '''
        Set the values for the members of the class by reading them from the config or setting their default values

        :param dict config: The configuration dictionary with the key/value pairs for the class members
        '''
        self.config = config if config else {}
        self.arguments = config['arguments'] if 'arguments' in self.config else {}
        self.condition = config['condition'] if 'condition' in self.config else None
        self.get_nodes = config['get_nodes'] if 'get_nodes' in self.config else None
        self.update_type = config['update_type'] if 'update_type' in self.config else UpdateType.STATE

    def validate(self):
        '''
        Validate the update configuration

        :raises ValueError: if the `update_type` member is not of type `UpdateType`
        '''
        ConfigValidator.validate('arguments', self.arguments, dict)
        ConfigValidator.validate('condition', self.condition, Condition, optional=True)
        ConfigValidator.validate('get_nodes', self.get_nodes, bool, optional=True)
        ConfigValidator.validate('update_type', self.update_type, UpdateType)
        if not isinstance(self.update_type, UpdateType):
            raise ValueError('Update type should of enum UpdateType')

class Update(object):
    """
    Update class

    :var fun: The update function that should be executed
    :vartype fun: function
    :var config: UpdateConfiguration object, defaults to a new UpdateConfiguration object
    :vartype config: UpdateConfiguration
    :var arguments: A dictionary with arguments for the update function, defaults to empty dict
    :vartype arguments: dict
    :var condition: A condition for nodes that must be met before the update is executed on them
    :vartype condition: Condition or None
    :var get_nodes: A boolean indicating whether the update function should receive a list of sampled nodes as argument,
        defaults to None
    :vartype get-nodes: bool or None
    :var update_type: A value from the `UpdateType` enum, indicating what kind of update is being performed,
        defaults to `UpdateType.STATE`
    :vartype update_type: UpdateType
    """

    def __init__(self, fun, config=None):
        '''
        Initialise the update by setting the class members to their values defined in the config

        :param function fun: The update function to execute
        :param config: The configuration object containing the values for the class members
        :type config: UpdateConfiguration, optional
        '''
        self.function = fun
        self.config = config if config else UpdateConfiguration()
        self.arguments = self.config.arguments
        self.condition = self.config.condition
        self.get_nodes = self.config.get_nodes
        self.update_type = self.config.update_type

    def execute(self, nodes=None):
        '''
        Execute the update function with or without the sampled nodes from the scheme/condition
        and return the output

        :param nodes: An optional list of nodes that the update function should be applied on.
            The given nodes are filtered by the schemes and conditions
        :type nodes: list, optional
        '''
        if self.get_nodes:
            output = self.function(nodes, **self.arguments)
        else:
            output = self.function(**self.arguments)
        return output


#-*- coding: utf-8 -*-
'''
1. 添加系：adddepartment
2. 添加班级：addclass
3. 删除系：deldepartment
4. 删除班级：delclass
5. 编辑系：editdepartment
6. 编辑班级：editclass
'''

from django.shortcuts import render_to_response
from django.template import RequestContext, Template, Context
from classes.models import Class, Department
from teachers.models import Teacher
from students.models import Student
from django.http import HttpResponse, Http404, HttpResponseRedirect
import datetime
import json
import logging
logger = logging.getLogger('mysite.log')
def adddepartment(request):
        if not 'username' in request.session:
                return HttpResponseRedirect('/Login/')
        deptls = Department.objects.order_by('id')
        classls = Class.objects.order_by('id')
        judgeadd=0
        errors = []
        if request.method == 'POST':
                if not request.POST.get('deptname',''):
                        errors.append('deptname')
                for dept in deptls:
                        if(dept.deptname==request.POST['deptname']):
                                judgeadd=1
                                break;
                if(judgeadd==0):
                        dept = Department(deptname=request.POST['deptname'],teacherid_id= request.session['userid'],createtime=datetime.datetime.now(),edittime=datetime.datetime.now())
                        dept.save()
        deptls = Department.objects.order_by('id')
        departments = Department.objects.order_by('id')
        return HttpResponseRedirect('/students/')

def addclass(request):
        if not 'username' in request.session:
                return HttpResponseRedirect('/Login/')
        deptls = Department.objects.order_by('id')
        classls = Class.objects.order_by('id')
        judgeadd=0
        errors = []
        if request.method == 'POST':
                if not request.POST.get('claname',''):
                        errors.append('claname')
                for clas in classls:
                        if(clas.claname == request.POST['claname']):
                                if(clas.grade == int(request.POST['grade'])):
                                        if(clas.departmentid_id ==int(request.POST['deptid'])):
                                                judgeadd=1
                                                break;
                if(judgeadd==0):
                        cla = Class(claname=request.POST['claname'],departmentid_id=int(request.POST['deptid']),grade=int(request.POST['grade']),teacherid_id= request.session['userid'],createtime=datetime.datetime.now(),edittime=datetime.datetime.now())
                        cla.save()
        deptls = Department.objects.order_by('id')
        classes = Class.objects.order_by('id')
        return HttpResponseRedirect('/students/')

def delclass(request, did):
        global logger
        if not 'username' in request.session:
                return HttpResponseRedirect('/Login/')
        error = ''
        try:
                did = int(did)
                cla = Class.objects.get(id=did)
        except ValueError:
                logger.error("classes")
                raise Http404()

        cla.delete()
        return HttpResponseRedirect('/students/')

def deldepartment(request, did):
        global logger
        if not 'username' in request.session:
                return HttpResponseRedirect('/Login/')
        error = ''
        try:
                did = int(did)
                dept = Department.objects.get(id=did)
        except ValueError:
                logger.error("classes")
                raise Http404()

        dept.delete()
        return HttpResponseRedirect('/students/')

def editdepartment(request, did):
        global logger
        if not 'username' in request.session:
                return HttpResponseRedirect('/Login/')
        errors = []
        deptls = Department.objects.order_by('id')
        classls = Class.objects.order_by('id')
        judgeadd=0
        try:
                did = int(did)
                dept= Department.objects.get(id=did)
        except ValueError:
                logger.error("classes")
                raise Http404()

        if request.method == 'POST':
                if not request.POST.get('deptname',''):
                        errors.append('deptname')
                for deptl in deptls:
                        if(deptl.deptname==request.POST['deptname']):
                                if(dept.deptname!=request.POST['deptname']):
                                        judgeadd=1
                                        break;
                if(judgeadd==0):
                        dept.deptname = request.POST['deptname']
                        dept.edittime=datetime.datetime.now()
                        dept.save()
        deptls = Department.objects.order_by('id')
        departments = Department.objects.order_by('id')
        return HttpResponseRedirect('/students/')

def editclass(request, did):
        global logger
        if not 'username' in request.session:
                return HttpResponseRedirect('/Login/')
        errors = []
        deptls = Department.objects.order_by('id')
        classls = Class.objects.order_by('id')
        judgeadd=0
        try:
                did = int(did)
                clas=Class.objects.get(id=did)
        except ValueError:
                logger.error("classes")
                raise Http404()

        if request.method == 'POST':
                if not request.POST.get('claname',''):
                        errors.append('claname')
                for clasl in classls:
                        if(clasl.claname == request.POST['claname']):
                                if(clasl.grade == int(request.POST['grade'])):
                                        if(clasl.departmentid_id ==int(request.POST['deptid'])):
                                                judgeadd=1
                                                break;
                if(judgeadd==0):
                        clas.claname = request.POST['claname']
                        clas.grade = request.POST['grade']
                        clas.departmentid_id = request.POST['deptid']
                        clas.edittime=datetime.datetime.now()
                        clas.save()
        deptls = Department.objects.order_by('id')
        classes = Class.objects.order_by('id')
        return HttpResponseRedirect('/students/')

def deptnamecheck(request):
        departments = Department.objects.order_by('-id')
        judgedeptname= 0
        if request.method == 'POST':
                deptdeptname=request.POST['deptname']
               # print deptdeptname
                for dept in departments:
                        if (dept.deptname == deptdeptname):
                                judgedeptname=1
                                break
        data={}
        data["judgedeptname"]=judgedeptname
        return HttpResponse(json.dumps(data))

def clanamecheck(request):
        classes = Class.objects.order_by('-id')
        judgeclaname= 0
        if request.method == 'POST':
                cladeptid= int(request.POST['deptid'])
                clagrade = int(request.POST['grade'])
                claclaname = request.POST['claname']
                for cla in classes:
                        if (cla.claname==claclaname):
                                if(cla.grade==clagrade):
                                        #print cla.departmentid_id
                                        #print cladeptid
                                        if(cla.departmentid_id==cladeptid):
                                                judgeclaname=1
                                                break
        data={}
        data["judgeclaname"]=judgeclaname
        return HttpResponse(json.dumps(data))


#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Time: 2020/4/5 21:14
# @Author: qyh

import matplotlib.pyplot as plt
import numpy.random as rdm
import networkx as nx

node_num = 100
probability = 0.01
er_graph = nx.erdos_renyi_graph(node_num, probability)
susceptible = 'S'
infected = 'I'
recovered = 'R'

# Init
def onset(graph):
    for i in graph.nodes.keys():
        graph.nodes[i]['state'] = susceptible

# Set infection rate
def infect_prop(graph, proportion):
    for i in graph.nodes.keys():
        if rdm.random() <= proportion:
            graph.nodes[i]['state'] = infected

# Model building
def build_model(p_infect, p_recover):
    def model(graph, i):
        if graph.nodes[i]['state'] == infected:
            for m in graph.neighbors(i):
                if graph.nodes[m]['state'] == susceptible:
                    if rdm.random() <= p_infect:
                        graph.nodes[m]['state'] = infected
            if rdm.random() <= p_recover:
                graph.nodes[i]['state'] = recovered
    return model

# Single model run
def model_run(graph, model):
    for i in graph.nodes.keys():
        model(graph, i)

# Multiple model cycles
def model_iter(graph, model, iter_num):
    for i in range(iter_num):
        model_run(graph, model)

def draw(graph):
    fig, ax = plt.subplots(figsize=(12, 10))
    ax.set_xticks([])
    ax.set_xticks([])
    pos = nx.spring_layout(graph, k=0.2)
    nx.draw_networkx_edges(graph, pos, alpha=0.5, width=1)
    nx.draw_networkx_nodes(graph, pos, node_size=80)
    plt.show()

def calc_infection_rate(graph):
    onset(graph)
    infect_prop(graph, 0.05)
    model = build_model(0.2, 0.8)
    model_iter(graph, model, 10)
    infect = [v for (v, attr) in graph.nodes(data=True) if attr['state'] == recovered]
    infection_rate = len(infect) / node_num
    print(infection_rate)

if __name__ == '__main__':
    draw(er_graph)
    calc_infection_rate(er_graph)


import os

import pandas as pd
from sklearn.model_selection import KFold, train_test_split

root_path = os.path.dirname(__file__)
asset_path = os.path.join(root_path, '../assets')

# load the full titanic example data
data = pd.read_csv(os.path.join(root_path, '../data/train.csv'))

# train / test split
train_data, test_data = train_test_split(data, test_size=0.2)

# number of data samples for the train and test sets
N_TRAIN_DATA_SAMPLES = 10
N_TEST_DATA_SAMPLES = 2

train_test_configs = [
    {
        'data': train_data,
        'n_samples': N_TRAIN_DATA_SAMPLES,
        'data_samples_root': os.path.join(asset_path, 'train_data_samples'),
        'data_samples_content': [],
    },
    {
        'data': test_data,
        'n_samples': N_TEST_DATA_SAMPLES,
        'data_samples_root': os.path.join(asset_path, 'test_data_samples'),
        'data_samples_content': [],
    },
]

# generate data samples
for conf in train_test_configs:
    kf = KFold(n_splits=conf['n_samples'], shuffle=True)
    splits = kf.split(conf['data'])
    for _, index in splits:
        conf['data_samples_content'].append(conf['data'].iloc[index])

# save data samples
for conf in train_test_configs:
    for i, data_sample in enumerate(conf['data_samples_content']):
        filename = os.path.join(conf['data_samples_root'], f'data_sample_{i}/data_sample_{i}.csv')
        os.makedirs(os.path.dirname(filename))
        with open(filename, 'w') as f:
            data_sample.to_csv(f)