import logging
import threading
import uuid

from django import forms
from django.db import models
from django.utils.text import Truncator, slugify
from modelcluster.fields import ParentalManyToManyField
from modelcluster.models import ClusterableModel
from wagtail.admin.forms import WagtailAdminPageForm
from wagtail.admin.panels import FieldPanel, FieldRowPanel, MultiFieldPanel
from wagtail.api import APIField
from wagtail.models import Page
from wagtail.search import index

from mycarehub.common.models import Organisation, Program
from mycarehub.content.models.snippets import CustomSnippetForm

LOGGER = logging.getLogger(__name__)

class SMSContentItemPageForm(WagtailAdminPageForm):
    def __init__(
        self, data=None, files=None, parent_page=None, subscription=None, *args, **kwargs
    ):  # pragma: no cover
        super().__init__(data, files, parent_page, subscription, *args, **kwargs)
        self.fields["category"].queryset = self.fields["category"].queryset.filter(
            organisation=self.for_user.organisation, programs=parent_page.specific.program_id
        )
        self.fields["tag"].queryset = self.fields["tag"].queryset.filter(
            organisation=self.for_user.organisation, programs=parent_page.specific.program_id
        )

class SMSContentItemCategory(ClusterableModel):
    """Category associated with an SMS."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    code = models.CharField(
        max_length=32,
        unique=True,
        help_text="A code that will be used to uniquely identify a category",
    )
    name = models.CharField(
        max_length=64, help_text="This name will be displayed while creating sms content"
    )
    sequence_key = models.IntegerField(
        help_text="A pre-determined value to be used while sequencing content under this category"
    )
    programs = ParentalManyToManyField(
        Program, help_text="Select a program to assign this category"
    )
    organisation = models.ForeignKey(
        Organisation,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name="%(app_label)s_%(class)s_related",
    )
    base_form_class = CustomSnippetForm

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

    class Meta:
        unique_together = (
            "sequence_key",
            "code",
        )
        verbose_name_plural = "sms content item categories"

    panels = [
        FieldPanel("code"),
        FieldPanel("name"),
        FieldPanel("sequence_key"),
        FieldPanel("programs", widget=forms.CheckboxSelectMultiple),
    ]

    def get_programs(self):
        return "\n".join([p.name for p in self.programs.all()])

class SMSContentItemTag(ClusterableModel):
    """Tag associated with an SMS."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(
        max_length=64, help_text="This name will be displayed when creating sms content"
    )
    code = models.IntegerField(
        help_text="A pre-determined value that will be used to uniquely identify a tag"
    )
    programs = ParentalManyToManyField(Program, help_text="Select a program to assign this tag")
    organisation = models.ForeignKey(
        Organisation,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name="%(app_label)s_%(class)s_related",
    )
    base_form_class = CustomSnippetForm

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

    class Meta:
        verbose_name_plural = "sms content item tags"
        unique_together = (
            "name",
            "code",
        )

    panels = [
        FieldPanel("name"),
        FieldPanel("code"),
        FieldPanel("programs", widget=forms.CheckboxSelectMultiple),
    ]

    def get_programs(self):
        return "\n".join([p.name for p in self.programs.all()])

class SMSContentItem(Page):
    """
    An `SMSContentItem` represents the content that
    is sent to sms subscribers.
    """

    organisation = models.ForeignKey(
        Organisation,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name="%(app_label)s_%(class)s_related",
    )

    program = models.ForeignKey(
        Program,
        on_delete=models.PROTECT,
        null=True,
        blank=True,
        related_name="%(app_label)s_%(class)s_related",
    )

    category = models.ForeignKey(
        SMSContentItemCategory,
        on_delete=models.PROTECT,
        related_name="categories",
        help_text="Category to associate content with",
    )

    tag = models.ForeignKey(
        SMSContentItemTag,
        on_delete=models.PROTECT,
        related_name="tags",
        help_text="Tag to associate content with",
    )
    sequence_number = models.IntegerField(null=True, blank=True)
    sequence = models.CharField(max_length=10, null=True, blank=True)
    body = models.TextField(
        max_length=160, help_text="Write out the body of the content to be sent to subscribers"
    )

    base_form_class = SMSContentItemPageForm

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldRowPanel(
                    [
                        FieldPanel("category", widget=forms.Select),
                        FieldPanel("tag", widget=forms.Select),
                    ]
                ),
            ],
            heading="About",
        ),
        FieldPanel("body"),
    ]

    # these fields determine the content that is indexed for search purposes
    search_fields = Page.search_fields + [
        index.SearchField("category"),
        index.SearchField("body"),
    ]

    # this configuration allows these custom fields to be available over the API
    api_fields = [
        APIField("live"),
        APIField("organisation"),
        APIField("program"),
        APIField("category"),
        APIField("tag"),
        APIField("sequence"),
        APIField("sequence_number"),
        APIField("body"),
    ]

    # limit the parent page types
    parent_page_type = [
        "content.ContentItemIndexPage",
    ]

    subpage_types = []  # type: ignore

    def __str__(self):
        """Human readable model representation."""
        return f"{self.sequence} {self.title}"

    def generate_sequence_number(self):
        """Generate content sequence and sequence numbers."""
        if self.__class__.objects.filter(pk=self.pk, sequence__isnull=False):
            msg = "Sequence has already been set"
            LOGGER.info(msg)
            return

        filters = {
            "organisation": self.organisation,
            "program": self.program,
            "category": self.category,
        }
        seq = (
            self.__class__.objects.filter(**filters)
            .order_by("translation_key")
            .distinct("translation_key")
            .count()
        )
        lock = threading.Lock()

        def increment_seq(lock):
            lock.acquire()
            nonlocal seq
            seq = seq + 1
            lock.release()

        thread = threading.Thread(target=increment_seq, args=(lock,))
        thread.start()
        thread.join()

        self.sequence_number = seq
        self.sequence = f"{self.category.sequence_key}.{self.sequence_number}"

    def save(self, *args, **kwargs):
        """Override save method.

        We replace the title to make it easier for users to
        keep track of their sms's.
        """
        new_title = Truncator(self.body).chars(30)
        slug = slugify(new_title)

        unique_slug = slug
        offset = 1
        while self.__class__.objects.filter(slug=unique_slug).exists():
            msg = "Duplicate slug found, generating unique slug"
            LOGGER.info(msg)

            unique_slug = "{}-{}".format(slug, offset)  # type: ignore
            offset += 1

        self.slug = unique_slug

        self.title = new_title
        super().save(*args, **kwargs)


def get_all_sshkeys(self):
        """
            This function returns a list of SSHKey object.
        """
        data = self.get_data("account/keys/")
        ssh_keys = list()
        for jsoned in data['ssh_keys']:
            ssh_key = SSHKey(**jsoned)
            ssh_key.token = self.token
            ssh_keys.append(ssh_key)
        return ssh_keys


############################################################
# -*- coding: utf-8 -*-
#
#       #   #  #   #   #    #
#      ##  ##  #  ##  #    #
#     # # # #  # # # #    #  #
#    #  ##  #  ##  ##    ######
#   #   #   #  #   #       #
#
# Python-based Tool for interaction with the 10micron mounts
# GUI with PyQT5 for python
#
# written in python3, (c) 2019-2023 by mworion
# Licence APL2.0
#
###########################################################
# standard libraries
import os
from pathlib import Path

# external packages
from PyQt5.QtWidgets import QListView, QApplication
from astropy.io import fits

# local import

class Rename:
    """
    """

    def __init__(self):
        self.selectorsDropDowns = {'rename1': self.ui.rename1,
                                   'rename2': self.ui.rename2,
                                   'rename3': self.ui.rename3,
                                   'rename4': self.ui.rename4,
                                   'rename5': self.ui.rename5,
                                   'rename6': self.ui.rename6,
                                   }
        self.fitsHeaderKeywords = {'None': [''],
                                   'Datetime': ['DATE-OBS'],
                                   'Frame': ['FRAME', 'IMAGETYP'],
                                   'Filter': ['FILTER'],
                                   'Binning': ['XBINNING'],
                                   'Exp Time': ['EXPTIME'],
                                   'CCD Temp': ['CCD-TEMP'],
                                   }
        self.setupGuiTools()
        self.ui.renameStart.clicked.connect(self.renameRunGUI)
        self.ui.renameInputSelect.clicked.connect(self.chooseDir)

    def initConfig(self):
        """
        initConfig read the key out of the configuration dict and stores it to the gui
        elements. if some initialisations have to be proceeded with the loaded persistent
        data, they will be launched as well in this method.

        :return: True for test purpose
        """
        config = self.app.config['mainW']
        defaultDir = self.app.mwGlob['imageDir']
        self.ui.renameDir.setText(config.get('renameDir', defaultDir))
        self.ui.newObjectName.setText(config.get('newObjectName', ''))
        self.ui.includeSubdirs.setChecked(config.get('includeSubdirs', False))
        for name, ui in self.selectorsDropDowns.items():
            ui.setCurrentIndex(config.get(name, 0))

        self.ui.renameProgress.setValue(0)
        return True

    def storeConfig(self):
        """
        storeConfig writes the keys to the configuration dict and stores. if some
        saving has to be proceeded to persistent data, they will be launched as
        well in this method.

        :return: True for test purpose
        """
        config = self.app.config['mainW']
        config['renameDir'] = self.ui.renameDir.text()
        config['newObjectName'] = self.ui.newObjectName.text()
        config['includeSubdirs'] = self.ui.includeSubdirs.isChecked()
        for name, ui in self.selectorsDropDowns.items():
            config[name] = ui.currentIndex()

        return True

    def setupGuiTools(self):
        """
        :return: success for test
        """
        for name, selectorUI in self.selectorsDropDowns.items():
            selectorUI.clear()
            selectorUI.setView(QListView())
            for headerEntry in self.fitsHeaderKeywords:
                selectorUI.addItem(headerEntry)
        return True

    @staticmethod
    def getNumberFiles(pathDir='', search=''):
        """
        getNumberFiles counts the number of files to be valid for the renaming.

        :param pathDir: path to root directory to be scanned
        :param search: search string
        :return: number of files found
        """
        if not pathDir:
            return 0
        if not os.path.isdir(pathDir):
            return 0
        if not search:
            return 0

        number = sum(1 for _ in Path(pathDir).glob(search))
        return number

    @staticmethod
    def convertHeaderEntry(entry='', fitsKey=''):
        """
        convertHeaderEntry takes the fitsHeader entry and reformat it to a
        reasonable string.

        :param entry:
        :param fitsKey:
        :return:
        """
        if not fitsKey:
            return ''
        if not entry:
            return ''

        if fitsKey == 'DATE-OBS':
            chunk = entry.replace(':', '-')
            chunk = chunk.replace('T', '_')
            chunk = chunk.split('.')[0]
        elif fitsKey == 'XBINNING':
            chunk = f'Bin{entry:1.0f}'
        elif fitsKey == 'CCD-TEMP':
            chunk = f'Temp{entry:03.0f}'
        elif fitsKey == 'FRAME':
            chunk = f'{entry}'
        elif fitsKey == 'FILTER':
            chunk = f'{entry}'
        elif fitsKey == 'EXPTIME':
            chunk = f'Exp{entry:1.0f}s'
        else:
            chunk = ''

        return chunk

    def processSelectors(self, fitsHeader=None, selection=''):
        """
        processSelectors takes the selection for a fileName chunk and runs through the
        possible list of valid fits header keys. if there is more than one valid fitsKey,
        it automatically selects only the first on for conversion.

        :param fitsHeader:
        :param selection: str entry from the drop-down selector
        :return: nameChunk: part of the entry
        """
        if fitsHeader is None:
            return ''
        if not selection:
            return ''

        nameChunk = ''
        fitsKeywords = self.fitsHeaderKeywords[selection]
        for fitsKey in fitsKeywords:
            if fitsKey not in fitsHeader:
                continue
            nameChunk = self.convertHeaderEntry(entry=fitsHeader[fitsKey],
                                                fitsKey=fitsKey)
            break
        return nameChunk

    def renameFile(self, fileName=''):
        """
        renameFile opens the given FITS file and retrieves its header. if valid it
        runs through selectors of the drop-down lists and checks all header keys to
        get the new filename build. afterwards it renames the given file.

        :param fileName: fits file to be renamed
        :return: success
        """
        if not fileName:
            return False
        if not os.path.isfile(fileName):
            return False

        fileName = os.path.normpath(fileName)
        with fits.open(name=fileName) as fd:
            fitsHeader = fd[0].header

            # object should be in lower case. if not, it will be set
            newObjectName = self.ui.newObjectName.text().upper()
            if newObjectName:
                newFilename = newObjectName

            else:
                if 'OBJECT' in fitsHeader:
                    newFilename = fitsHeader['OBJECT'].upper()
                else:
                    newFilename = 'UNKNOWN'

            for _, selector in self.selectorsDropDowns.items():
                selection = selector.currentText()
                chunk = self.processSelectors(fitsHeader=fitsHeader,
                                              selection=selection
                                              )
                if chunk:
                    newFilename += f'_{chunk}'

            newFilename += '.fits'
            dirName = os.path.dirname(fileName)
            newFilename = os.path.normpath(f'{dirName}/{newFilename}')
            os.rename(fileName, newFilename)

        return True

    def renameRunGUI(self):
        """
        renameRunGUI retrieves a full list of files to be renamed and renames
        them on by one.

        :return: True for test purpose
        """
        pathDir = self.ui.renameDir.text()
        includeSubdirs = self.ui.includeSubdirs.isChecked()
        if not os.path.isdir(pathDir):
            self.msg.emit(2, 'Tools', 'Rename error',
                          'No valid input directory given')
            return False

        if includeSubdirs:
            search = '**/*.fit*'
        else:
            search = '*.fit*'

        numberFiles = self.getNumberFiles(pathDir, search=search)
        if not numberFiles:
            self.msg.emit(2, 'Tools', 'Rename error',
                          'No files to rename')
            return False

        for i, fileName in enumerate(Path(pathDir).glob(search)):
            self.ui.renameProgress.setValue(int(100 * (i + 1) / numberFiles))
            QApplication.processEvents()
            suc = self.renameFile(fileName=fileName)
            if not suc:
                self.msg.emit(2, 'Tools', 'Rename error',
                              f'{fileName} could not be renamed')

        self.msg.emit(0, 'Tools', 'Rename',
                      f'{numberFiles:d} images were renamed')

        return True

    def chooseDir(self):
        """
        chooseDir selects the input directory and sets the default value for the
        output directory as well

        :return: True for test purpose
        """
        folder = self.ui.renameDir.text()
        pathDir, _, _ = self.openDir(self, 'Choose Input Dir', folder,)
        if pathDir:
            self.ui.renameDir.setText(pathDir)
            self.ui.renameProgress.setValue(0)
        return True


def hello():
    print("Hello New Python Programmer, welcome ")
hello()

def pack(a,b,c):
    mylist = []
    mylist.append(a)
    mylist.append(b)
    mylist.append(c)
    return mylist
print(pack(1,2,3))

def eat_lunch(lunchbox):
  if len(lunchbox) == 0:
    print("My lunchbox is empty!")
  else:
    for i in range(len(lunchbox)):
      if i == 0:
        print(f"First I eat {lunchbox[0]}")
      else:
        print(f"Next I eat {lunchbox[i]}")

eat_lunch([])
eat_lunch(["chicken","rice","veggies",])


"""
This is an example demonstrating the differences between a class and its instances.
"""

class Dog:
    """
    This is a dog!

    See all the references to self? All of an object's methods have 'self' as the first argument. This is referring
    to the object itself, and by referencing self, you can access the attributes and methods of the object itself.

    E.g. self.name refers to the name of this dog specifically, rather than any other dog, or a variable called name
    that's somewhere else in your code.
    """
    # This is a characteristic that is the same for all Dogs.
    species = "Canis familiaris"

    def __init__(self, name, age, weight, height):
        # These characteristics can be different for each dog.
        # If I were a less terrible person, I would be more specific with these variable names, e.g.
        # by including the expected units that the variable should hold.
        self.name = name
        self.age = age
        self.weight = weight
        self.height = height

    # This is a series of things that all dogs can do. So, they are added into the definition of the Dog class.
    def move(self, distance_meters):
        time_to_move = distance_meters * self.height / self.weight * (self.age / 10)
        return time_to_move

    def bark(self):
        volume = (self.weight / 30) * (self.age / 10)
        # This is a series of conditions--when you have a block like this, with if... elif... else, the code will
        # evaluate each of the conditions until it finds one that passes. When that happens, it skips to the line after
        # the end of the else block.
        # So in this case, if volume > 25, then the code will skip to the bit after the else: statement, where it
        # returns the sound_text that it found.
        if volume > 25:
            sound_text = 'BARK!'
        elif volume > 15:
            sound_text = 'Bark!'
        else:
            sound_text = 'bark'
        return sound_text

    def bite(self):
        # Now, compare that to this situation. In this situation, this isn't an if... else block. So, each if statement
        # will get evaluated (and if they evaluate to True, the stuff inside the if block will be run).
        if self.weight > 150:
            print('OM NOM NOM')
        if self.weight > 200:
            print('NOM NOM')

    def wag_tail(self):
        print("Swish swish")
        return self.name

if __name__ == '__main__':  # This is explained in main.py, won't repeat it here.
    special_dog = Dog('Derpy', 7, 100, 12)
    how_long_to_move = special_dog.move(10)
    print(how_long_to_move)
    special_dog.bark()
    special_dog.bite()
    dog_name = special_dog.wag_tail()
    print(dog_name)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
   File Name：     test
   Description :   测试默认参数可以直接赋值 int 或 dict 等类型
   Author :        ZYZ
   date：          2019/12/11
"""

class Test:
    def __init__(
            self,
            document_class=int,
            **kwargs):
        print(type(document_class))

Test()  # <class 'type'>
Test(document_class=20)  # <class 'int'>


import torch.nn as nn
from util import dataloader as loader
from util.dataloader import process_tdpts
import torch.nn.functional as F
from util import config
import torch
from opacus.layers.dp_rnn import DPLSTMCell as LSTMCell

class Model(nn.Module):
    def __init__(self, z_dim=16, t_dim=48, te_dim=32, xe_dim=128, h_dim=128, o_dim=32, device=None):
        super(Model, self).__init__()
        self.z_dim = z_dim
        self.register_buffer('adj', loader.load_edgeadjs())
        self.register_buffer('eprop', loader.load_edgeproperties())
        if config.USE_TGRAPH:
            self.t_emb = nn.Embedding(t_dim * 7, te_dim)
            # self.t_emb = nn.Linear(t_dim * 7, te_dim)
            self.t_emb.weight = nn.Parameter(loader.load_time_emb(), True)  # load pre-trained temporal graph values
            self.tcost_emb = nn.Embedding(self.adj.size(0), te_dim)  # New
        else:
            self.t_emb = nn.Embedding(t_dim, te_dim)
            self.tcost_emb = nn.Embedding(self.adj.size(0), te_dim)  # New

        self.x_emb = nn.Embedding(self.adj.size(0), xe_dim)  # embed edges, 0 for padding

        self.lstms = nn.ModuleList()  # nn.LSTMCell(h_dim, h_dim) for _ in range(LSTMS_NUM)

        bias = True
        self.lstms.append(LSTMCell(z_dim + te_dim + xe_dim + self.eprop.size(1), h_dim, bias))
        for _ in range(1, config.LSTMS_NUM - 1):
            self.lstms.append(LSTMCell(h_dim, h_dim, bias))
        self.lstms.append(LSTMCell(h_dim, o_dim, bias)) if config.L2_NUM == 0 else self.lstms.append(
            LSTMCell(h_dim, h_dim, bias))

        self.linear_afterx = []  # nn.Sequential()
        self.linear_aftert = []
        self.linear_aftert += [nn.Linear(te_dim + te_dim, o_dim), nn.ReLU()]
        if config.L2_NUM != 0:
            self.linear_afterx += [nn.Linear(h_dim, o_dim), nn.ReLU()]
        for _ in range(1, config.L2_NUM):
            self.linear_afterx += [nn.Linear(o_dim, o_dim), nn.ReLU()]
            self.linear_aftert += [nn.Linear(o_dim, o_dim), nn.ReLU()]
        self.linear_afterx = nn.Sequential(*self.linear_afterx)
        self.linear_aftert = nn.Sequential(*self.linear_aftert)
        self.mlp_meta_x = nn.Sequential(nn.Linear(xe_dim + te_dim + self.eprop.size(1), o_dim))
        self.mlp_meta_t = nn.Sequential(nn.Linear(xe_dim + te_dim + self.eprop.size(1), o_dim))
        self.to(device)

    def adj_idx(self, input, output):  # return adj idx
        return (self.adj[input] == output.unsqueeze(-1)).nonzero()[:, -1]  # (B*L, )

    def init_h(self, batch_size, device):
        hs, cs = [], []
        for lstm in self.lstms:
            hs.append(torch.zeros(batch_size, lstm.hidden_size, device=device))
            cs.append(torch.zeros(batch_size, lstm.hidden_size, device=device))
        return hs, cs

    def forward(self, x, dpt):  # B * L, traj sequences
        x, dpt = x.t(), dpt.t()
        L, B = x.size()
        pred_x, pred_t = [], []
        hs, cs = self.init_h(B, x.device)
        for i in range(L):
            hidden, hs, cs = self.step(x[i], dpt[i], hs, cs)
            pred_x.append(F.log_softmax(hidden[0], dim=-1))  # B*adj_dim
            pred_t.append(torch.sigmoid(hidden[1]))

        pred_x = torch.stack(pred_x, 1).view(-1, self.adj.size(1))  # (B*L) * adj_dim
        pred_t = torch.stack(pred_t, 1).view(-1, self.adj.size(1))
        return pred_x, pred_t

    def step(self, xt, dptslot, hs, cs):  # B
        # print(xt.shape)
        B = xt.size(0)
        zt = torch.randn(B, self.z_dim, device=xt.device)
        xt_emb = self.x_emb(xt)  # B * emb_dim
        # print(dptslot.max(), dptslot.min())
        tt_emb = self.t_emb(dptslot)  # B * temb_dim
        xt_eprop = self.eprop[xt]  # B * eprop_dim
        hidden = torch.cat([zt, xt_emb, tt_emb, xt_eprop], dim=-1)
        for i, lstm in enumerate(self.lstms):  # LSTMs
            hs[i], cs[i] = lstm(hidden, (hs[i], cs[i]))
            hidden = hs[i]
        afterx = self.linear_afterx(hidden)
        adjs = self.adj[xt]  # B * adj_dim
        tt_emb = tt_emb.unsqueeze(1).expand(-1, self.adj.size(1), -1)
        aftert = self.linear_aftert(torch.cat([self.tcost_emb(adjs), tt_emb], dim=-1))
        props = self.eprop[adjs]  # .view(B, self.adj_dim, -1)
        mk = torch.cat([self.x_emb(adjs), tt_emb, props], -1)  # B * adj_size * know_emb_len
        softmax_w = self.mlp_meta_x(mk)
        sigmoid_w = self.mlp_meta_t(mk)

        pred_xnext = afterx.view(B, 1, 1, -1).matmul(softmax_w.view(B, self.adj.size(1), -1, 1)).view(B, -1)  # B * adj_dim
        pred_xnext[adjs == self.adj.size(0) + config.ADJ_MASK] = float('-inf')
        pred_tnext = aftert.unsqueeze(2).matmul(sigmoid_w.unsqueeze(-1)).view(B, self.adj.size(1))
        return (pred_xnext, pred_tnext), hs, cs

    def sample(self, x, dpts, ts):  # B * L, parts of sequences
        with torch.no_grad():
            if x is None or len(x) == 0: return torch.LongTensor().to(config.device), torch.FloatTensor().to(config.device)
            # assert x is not None and len(x) > 0
            x, dpts, ts = x.t(), dpts.t(), ts.t()
            given_len, B = x.size()
            samples_x, samples_t = [], []
            hs, cs = self.init_h(B, x.device)
            for i in range(given_len):
                hidden, hs, cs = self.step(x[i], dpts[i], hs, cs)
                if i + 1 < given_len: samples_x.append(x[i + 1]), samples_t.append(ts[i])
            sample_batch_idx = F.softmax(hidden[0], -1).multinomial(1).view(-1)  # .argmax(-1)
            samples_x.append(self.adj[x[-1]][range(B), sample_batch_idx])
            samples_t.append(torch.sigmoid(hidden[1][range(B), sample_batch_idx]))
            dpt = (dpts[-1] + (samples_t[-1] * config.TCOST_MAX).round().long()) % config.T_LOOP
            dpt = process_tdpts(dpt)
            for i in range(given_len, config.TRAJ_FIX_LEN - 1):
                hidden, hs, cs = self.step(samples_x[-1], dpt, hs, cs)
                sample_batch_idx = F.softmax(hidden[0], -1).multinomial(1).view(-1)  # .multinomial(1).view(-1)
                samples_x.append(self.adj[samples_x[-1]][range(B), sample_batch_idx])
                samples_t.append(torch.sigmoid(hidden[1][range(B), sample_batch_idx]))
                dpt = (dpt + (samples_t[-1] * config.TCOST_MAX).round().long()) % config.T_LOOP
                dpt = process_tdpts(dpt)
            samples_x, samples_t = torch.stack(samples_x, 1), torch.stack(samples_t, 1)  # B*L
            return samples_x, samples_t

    def sample_t(self, x, yidx, dpts):
        with torch.no_grad():
            if x is None or len(x) == 0: return torch.FloatTensor().to(config.device)
            x, yidx, dpts_slots = x.t(), yidx.t(), dpts.t()
            L, B = x.size()
            assert L == config.TRAJ_FIX_LEN - 1
            samples_costs = []
            hs, cs = self.init_h(B, x.device)
            for i in range(L):
                hidden, hs, cs = self.step(x[i], dpts_slots[i], hs, cs)
                pred_t = torch.sigmoid(hidden[1][range(B), yidx[i]])
                pred_t[yidx[i] == config.STOP_EDGE] = 0
                samples_costs.append(pred_t)
            return torch.stack(samples_costs, 1)  # B*L


from datetime import datetime, timedelta
from functools import wraps

from hamcrest import assert_that, equal_to, none, is_
from httmock import urlmatch, HTTMock
from mock import patch

from django.conf import settings
from django.http import HttpRequest, HttpResponse
from django.test import TestCase

from stagecraft.apps.datasets.models import OAuthUser
from stagecraft.apps.datasets.tests.support.test_helpers import has_header
from stagecraft.libs.authorization.http import (
    check_permission, authorize, _get_resource_role_permissions
)

def govuk_signon_mock(**kwargs):
    # So that this behaves as expected, when we use
    # it be sure to clean out any existing users.
    # This will prevent loading them from the database
    # instead of using the signon mock.
    OAuthUser.objects.all().delete()

    @urlmatch(netloc=r'.*signon.*')
    def func(url, request):
        if request.headers['Authorization'] == 'Bearer correct-token':
            status_code = 200
            user = {
                "user": {
                    "email": kwargs.get("email", "foobar.lastname@gov.uk"),
                    "name": kwargs.get("name", "Foobar"),
                    "organisation_slug": kwargs.get(
                        "organisation_slug", "cabinet-office"),
                    "permissions": kwargs.get(
                        "permissions", ["signin", "anon"]),
                    "uid": "a-long-uid",
                }
            }

        else:
            status_code = 401
            user = {}

        return {'status_code': status_code, 'content': user}

    return func

def with_govuk_signon(**signon_kwargs):

    def decorator(func):
        @wraps(func)
        def wrapped(*args, **kwargs):
            use_development_users = settings.USE_DEVELOPMENT_USERS
            settings.USE_DEVELOPMENT_USERS = False
            signon_mock = HTTMock(
                govuk_signon_mock(**signon_kwargs))
            try:
                with signon_mock:
                    result = func(*args, **kwargs)
            finally:
                settings.USE_DEVELOPMENT_USERS = use_development_users
            return result
        return wrapped

    return decorator

class CheckPermissionTestCase(TestCase):

    def setUp(self):
        self.use_development_users = settings.USE_DEVELOPMENT_USERS

    def tearDown(self):
        settings.USE_DEVELOPMENT_USERS = self.use_development_users

    def test_use_development_users_gets_from_dictionary(self):
        (user, has_permission) = check_permission(
            'development-oauth-access-token', set(['signin']))
        assert_that(user['name'], equal_to('Some User'))
        assert_that(has_permission, equal_to(True))

    def test_user_with_permission_from_signon_returns_object_and_true(self):
        settings.USE_DEVELOPMENT_USERS = False
        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission(
                'correct-token', set(['signin']))
        assert_that(user['name'], equal_to('Foobar'))
        assert_that(has_permission, equal_to(True))

    @patch('requests.get')
    def test_signon_with_client_id(self, get_patch):
        settings.USE_DEVELOPMENT_USERS = False

        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission(
                'correct-token', set(['signin']))
        get_patch.assert_called_with(
            'http://signon.dev.gov.uk/user.json?client_id=clientid',
            headers={
                'Authorization': 'Bearer correct-token',
            })

    def test_user_without_permission_from_signon_returns_none_and_false(self):
        settings.USE_DEVELOPMENT_USERS = False
        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission(
                'bad-auth', set(['signin']))
        assert_that(user, none())
        assert_that(has_permission, equal_to(False))

    def test_user_with_permission_from_database_returns_object_and_true(self):
        settings.USE_DEVELOPMENT_USERS = False

        OAuthUser.objects.create(access_token='correct-token',
                                 uid='my-uid',
                                 email='joe@example.com',
                                 permissions=['signin'],
                                 expires_at=datetime.now() + timedelta(days=1))

        (user, has_permission) = check_permission(
            'correct-token', set(['signin']))

        assert_that(user['email'], equal_to('joe@example.com'))
        assert_that(has_permission, equal_to(True))

    def test_user_with_returns_object_and_true_when_permissions_is_list(self):
        settings.USE_DEVELOPMENT_USERS = False

        OAuthUser.objects.create(access_token='correct-token',
                                 uid='my-uid',
                                 email='joe@example.com',
                                 permissions=['signin'],
                                 expires_at=datetime.now() + timedelta(days=1))

        (user, has_permission) = check_permission(
            'correct-token', set(['signin', 'bob']))

        assert_that(user['email'], equal_to('joe@example.com'))
        assert_that(has_permission, equal_to(True))

    def test_user_without_permission_from_database_returns_false(self):
        settings.USE_DEVELOPMENT_USERS = False
        OAuthUser.objects.create(access_token='correct-token',
                                 uid='my-uid',
                                 email='joe@example.com',
                                 permissions=['signin'],
                                 expires_at=datetime.now() + timedelta(days=1))

        (user, has_permission) = check_permission(
            'correct-token', set(['admin']))

        assert_that(has_permission, equal_to(False))

    def test_check_permission_returns_object_and_true_when_permissions_list(
            self):
        settings.USE_DEVELOPMENT_USERS = False

        OAuthUser.objects.create(access_token='correct-token',
                                 uid='my-uid',
                                 email='jon@example.com',
                                 permissions=['signin'],
                                 expires_at=datetime.now() + timedelta(days=1))

        (user, has_permission) = check_permission(
            'correct-token', set(['signin', 'bob']))

        assert_that(user['email'], equal_to('jon@example.com'))
        assert_that(has_permission, equal_to(True))

    def test_user_from_database_should_not_be_returned_if_expired(self):
        settings.USE_DEVELOPMENT_USERS = False
        OAuthUser.objects.create(access_token='correct-token-2',
                                 uid='my-uid',
                                 email='joe@example.com',
                                 permissions=['signin'],
                                 expires_at=datetime.now() - timedelta(days=1))

        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission('correct-token-2',
                                                      set(['admin']))

        assert_that(user, none())
        assert_that(has_permission, equal_to(False))
        assert_that(OAuthUser.objects.count(), equal_to(0))

    def test_user_is_written_to_database_after_successful_auth(self):
        settings.USE_DEVELOPMENT_USERS = False

        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission('correct-token',
                                                      set(['signin']))

        assert_that(OAuthUser.objects.count(), equal_to(1))

        (user, has_permission) = check_permission(
            'correct-token', set(['signin']))

        assert_that(has_permission, equal_to(True))

    def test_if_permission_is_none_and_user_then_not_ok(self):
        settings.USE_DEVELOPMENT_USERS = False

        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission('correct-token',
                                                      set())

            assert_that(has_permission, equal_to(False))

    def test_if_permission_is_anon_and_user_then_ok(self):
        settings.USE_DEVELOPMENT_USERS = False

        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission('correct-token',
                                                      set(['anon']))

            assert_that(has_permission, equal_to(True))

    def test_if_permission_is_none_and_no_user_then_fail(self):
        settings.USE_DEVELOPMENT_USERS = False

        with HTTMock(govuk_signon_mock()):
            (user, has_permission) = check_permission('incorrect-token',
                                                      set())

            assert_that(has_permission, equal_to(False))

    def test_anon_user_if_no_token(self):
        settings.USE_DEVELOPMENT_USERS = False

        (user, has_permission) = check_permission(None, set(['anon']), True)

        assert_that(has_permission, equal_to(True))
        assert_that(user.get('name'), equal_to('Anonymous'))

    def test_no_access_without_role(self):
        settings.USE_DEVELOPMENT_USERS = False

        (user, has_permission) = check_permission(None, set(), True)

        assert_that(has_permission, equal_to(False))

    def test_no_user_if_no_token_and_anon_user_not_allowed(self):
        settings.USE_DEVELOPMENT_USERS = False

        (user, has_permission) = check_permission(None, set(), False)

        assert_that(has_permission, equal_to(False))
        assert_that(user, is_(None))

    def test_anon_user_if_permission_requested(self):
        settings.USE_DEVELOPMENT_USERS = False

        (user, has_permission) = check_permission(
            None, set(['permission']), True)

        assert_that(has_permission, equal_to(False))
        assert_that(user.get('name'), equal_to('Anonymous'))

    def test_role_permissions_for_a_resource(self):
        permissions_set = [
            {
                "role": "admin",
                "permissions": {
                    "Dashboard": ["get"],
                    "Transform": ["get"]
                },
            },
            {
                "role": "dashboard-editor",
                "permissions": {
                    "Dashboard": ["get", "post"]
                }
            }
        ]
        permissions = _get_resource_role_permissions(
            'Dashboard', permissions_set)
        assert_that(permissions, equal_to(
            {
                'get': set(['admin', 'dashboard-editor']),
                'post': set(['dashboard-editor']),
                'put': set(),
                'delete': set()
            }
        ))
        permissions = _get_resource_role_permissions(
            'Transform', permissions_set)
        assert_that(permissions, equal_to(
            {
                'get': set(['admin']),
                'post': set(),
                'put': set(),
                'delete': set()
            }
        ))

class AuthorizeTestCase(TestCase):

    def setUp(self):
        self.use_development_users = settings.USE_DEVELOPMENT_USERS

    def tearDown(self):
        settings.USE_DEVELOPMENT_USERS = self.use_development_users

    def test_authorize(self):
        settings.USE_DEVELOPMENT_USERS = False

        request = HttpRequest()
        request.META['HTTP_AUTHORIZATION'] = 'Bearer correct-token'

        with HTTMock(govuk_signon_mock()):
            user, err = authorize(request, set(['signin']))
            assert_that(err, is_(None))
            assert_that(user['uid'], is_('a-long-uid'))

    def test_authorize_no_user(self):
        settings.USE_DEVELOPMENT_USERS = False

        request = HttpRequest()
        request.META['HTTP_AUTHORIZATION'] = 'Bearer incorrect-token'

        with HTTMock(govuk_signon_mock()):
            user, err = authorize(request, set(['signin']))
            assert_that(err.status_code, is_(401))
            assert_that(user, is_(None))

    def test_authorize_bad_permission(self):
        settings.USE_DEVELOPMENT_USERS = False

        request = HttpRequest()
        request.META['HTTP_AUTHORIZATION'] = 'Bearer correct-token'

        with HTTMock(govuk_signon_mock()):
            user, err = authorize(
                request, set(['super-high-level-permission']))
            assert_that(err.status_code, is_(403))
            assert_that(user['uid'], is_('a-long-uid'))


# -*- coding:UTF-8 -*-
#NOTE: This code is using Python 2.7

"""
Ejercicio 1:

Almacenar los datos de una persona
    - Nombre
    - Apellidos
        - Paterno
        - Materno
    - Edad
    - Peso
    - Altura
    - CURP

Validar su CURP, y de ser válido, calcular su IMC (Índice de Masa Corporal
y mostrar la información de la persona
"""
"""
    En esta primera parte, se almacenan los datos en diferentes variables, que serán
    utilizadas conforme sean necesitadas.
"""

#Definición de variables a utilizar
"""
Nombre = ""         #Sólo un nombre
ApellidoP = ""      #Apellido Paterno
ApellidoM = ""      #Apellido Materno
Edad = 0            #Edad del usuario
Peso = 0.0          #Peso en Kilogramos
Estatura = 0.0        #Estatura en Metros
"""

#Solicitud de los datos del Usuario
"""
Nombre = raw_input("Ingrese su nombre (Solo el primer nombre): ")
ApellidoP = raw_input("Ingrese su apellido Paterno: ")
ApellidoM = raw_input("Ingrese su apellido Materno: ")
Edad = int(raw_input("Ingrese su edad: "))
Peso = float(raw_input("Ingrese su peso (Kg): "))
Estatura = float(raw_input("Ingrese su estatura (m): "))

print("Para validar sus datos, ingrese su DNI: ")
DNI = raw_input("DNI: ")
"""

"""
    En esta segunda parte se almacenan los datos en un diccionario
"""

#Definición del diccionario y solicitud de datos del usuario
persona = {}
persona["Nombre"] = raw_input("Ingrese su nombre (Solo el primer nombre): ")
persona["ApellidoP"] = raw_input("Ingrese su apellido Paterno: ")
persona["ApellidoM"] = raw_input("Ingrese su apellido Materno: ")
persona["Edad"] = int(raw_input("Ingrese su edad: "))
persona["Peso"] = float(raw_input("Ingrese su peso (Kg): "))
persona["Estatura"] = float(raw_input("Ingrese su estatura (m): "))
print("Para validar sus datos, ingrese su DNI: ")
persona["DNI"] = raw_input("DNI: ")

#Cálculo del Índice de Masa Corporal
"""
El índice de masa corporal (IMC) se calcula mediante la fórmula:
IMC = Peso/(Estatura^2)
"""
def CalcIMC(p_Peso, p_Est):
    IMC = p_Peso/(p_Est*p_Est)
    print("Tiene un IMC de: "+str(IMC)+".")
    print("Por lo tanto:")
    if IMC < 18:
        print("--Su peso es bajo")
    else:
        if IMC >= 18 and IMC < 25:
            print("--Su peso es normal")
        else:
            print("--Su peso es elevado")
#Fin de la función para calcular IMC

#Función para imprimir datos de usuario dede Diccionario
def printUsr():
    print("------------------------------------------------")
    print("El usuario " + persona["Nombre"] + " " + persona["ApellidoP"] + " " + persona["ApellidoM"])
    print("de " + str(persona["Edad"]) + " años.")
    print("Peso: " + str(persona["Peso"]) + " Kg")
    print("Estatura: " + str(persona["Estatura"]) + " mts")
    CalcIMC(persona["Peso"], persona["Estatura"])
    print("------------------------------------------------")

"""
    Definición de una función para validación de DNI, de acuerdo al algoritmo obtenido mediante
    el siguiente enlace:
    http://www.interior.gob.es/web/servicios-al-ciudadano/dni/calculo-del-digito-de-control-del-nif-nie
"""
def valDNI(p_DNI):
    letrasDNI = ("T","R","W","A","G","M","Y","F","P","D","X","B","N","J","Z","S","Q","V","H","L","C","K","E")
    #Determinar si el DNI es de ciudadano Español o Residente Extranjero
    tempNIF = p_DNI[1:len(p_DNI)]
    NIE = ["X", "Y", "Z"]
    if p_DNI[0] == "X":
        p_DNI = str(0)+tempNIF
    elif p_DNI[0] == "Y":
        p_DNI = str(1) + tempNIF
    elif p_DNI[0] == "Z":
        p_DNI = str(2) + tempNIF
    #Si no hay letra X, Y o Z al inicio, el DNI pertenece a ciudadano Español
    numDNI = int(p_DNI[0:len(p_DNI)-1])
    letraDNI = p_DNI[8]
    calcLetraDNI = numDNI % 23
    if letraDNI == letrasDNI[calcLetraDNI]:
        print("La DNI fue ingresada y validada correctamente")
        print("Mostrando los datos del usuario...")
        printUsr()
    else:
        print("La DNI ingresada contiene un error, intente nuevamente")

valDNI(persona["DNI"])

"""
#Mostrar datos ingresados del usuario (Mediante las variables)
print("------------------------------------------------")
print("El usuario "+Nombre+" "+ApellidoP+" "+ApellidoM)
print("de "+str(Edad)+" años.")
print("Peso: "+str(Peso)+" Kg")
print("Estatura: "+str(Estatura)+" mts")
CalcIMC(Peso,Estatura)
print("------------------------------------------------")
"""


import csv
from src.MEMM import MEMM
from src.prep import prep

prepocessing = prep('../Project2_resources/train.txt')
data = prepocessing.pre_process_memm()
#

memm_classifier = MEMM(data)
memm_classifier.trainMEMM(True)

test_prepocessing = prep('../Project2_resources/test.txt')
test_words = test_prepocessing.pre_process_memm_test()
my_prep_test = prep('../Project2_resources/test.txt')
data_test = my_prep_test.pre_process_hmm_test()

tags = []
actual_list = []
words = []

dict = {'PER': '', 'LOC': '', 'ORG': '', 'MISC': ''}
for x in range(len(test_words)):
    print("handling:", x)
    sentence = test_words[x]
    word_list = map(lambda x: x[1][0], sentence)
    type_list = map(lambda x: x[1][2], sentence)
    position_list = map(lambda x: x[1][2], sentence)
    # print(word_list)
    # print(type_list)
    actual_list += type_list
    words.append(word_list)

    prediction = memm_classifier.viterbi_search(sentence)
    # print(prediction)
    numbers_line = data_test[2][x]
    start_num = numbers_line[0]
    prev_number = numbers_line[0]
    prev_tag = None
    for j in range(len(prediction)):
        tag = prediction[j]
        number = numbers_line[j]
        # print tag, number
        if 'PER' in tag and prev_tag != 'PER':
            if prev_tag != None:
                dict[prev_tag] += start_num + '-' + prev_number + ' '
            start_num = number
            prev_tag = 'PER'
        elif 'LOC' in tag and prev_tag != 'LOC':
            if prev_tag != None:
                dict[prev_tag] += start_num + '-' + prev_number + ' '
            start_num = number
            prev_tag = 'LOC'
        elif 'ORG' in tag and prev_tag != 'ORG':
            if prev_tag != None:
                dict[prev_tag] += start_num + '-' + prev_number + ' '
            start_num = number
            prev_tag = 'ORG'
        elif 'MISC' in tag and prev_tag != 'MISC':
            if prev_tag != None:
                dict[prev_tag] += start_num + '-' + prev_number + ' '
            start_num = number
            prev_tag = 'MISC'
        else:
            if prev_tag != None and tag == 'O':
                dict[prev_tag] += start_num + '-' + prev_number + ' '
                prev_tag = None

        prev_number = number

with open('../output/speech_classification_MEMM_features.csv', mode='w') as test_output:
    speech_writer = csv.writer(test_output, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    speech_writer.writerow(['Type', 'Prediction'])

    speech_writer.writerow(['PER', dict['PER']])
    speech_writer.writerow(['LOC', dict['LOC']])
    speech_writer.writerow(['ORG', dict['ORG']])
    speech_writer.writerow(['MISC', dict['MISC']])


from typing import Iterable
from itertools import pairwise
from more_itertools import triplewise

def number_of_increases(values: Iterable[int]) -> int:
    """
    Given a list of numbers, return the number of consecutive pairs in which a
    number is larger than the one that precedes it.
    """
    return sum(a < b for a, b in pairwise(values))

def triple_sums(values: Iterable[int]) -> Iterable[int]:
    for vals in triplewise(values):
        yield sum(vals)

if __name__ == '__main__':
    content = open('input.txt').read()
    values = [int(line) for line in content.strip().splitlines()]

    print('Part1:')
    n = number_of_increases(values)
    print(n)

    print('Part2:')
    s = triple_sums(values)
    n = number_of_increases(s)
    print(n)


def tip_calculator():
    while True:
        try:
            total_bill = float(input("What was the total bill? $"))
            no_of_people = int(input("How many people to split the bill? "))
            tip = int(input("Want to leave a tip? (choose a percentage, 0 for no tip) %" ))
            ppp = ((total_bill + (total_bill * (tip / 100))) / no_of_people)
            return ppp
        except ValueError:
            print("please make sure you insert numbers only!")

if __name__ == '__main__':
    print ("Welcome to the tip calculator!")
    print(f'Each person needs to pay ${tip_calculator()}')


#+---------------------------------------------------------------------
#+ Python Script that creates CMAQ OCEAN files form MCIP GRICRO2d file
#+ Check the 'CHANGE' comments to define your directories for the run
#+ Author: Camilo Moreno
#+ Email = cama9709@gmail.com
#+---------------------------------------------------------------------
#%%
import numpy as np
import glob
from netCDF4 import Dataset
from datetime import datetime, date, timedelta
from os import listdir, scandir, getcwd

def create_forced_var(ds_cro):
    """Create array where cells that wanted to be forced are equal to 1
    and the rest are equal to 0 for multiple locations.

    Keyword arguments:
    ds_cro -- Dataset of the latlon netCDF file of the grid
    dic_coords -- dictionary of latlon coordinates for lower left and
                  upper right corners of each specified kay-value location
    """
    open_var = ds_cro.variables['LWMASK'][:][:][:][:]
    open_var[open_var > 0] = 2
    open_var[open_var == 0] = 1
    open_var[open_var > 1] = 0

    return open_var

def create_ncfile(save_dir, spc_name, open_var, ds_ocean):
    """Create Final NETCDF file.

    Keyword arguments:
    save_dir -- string of the location for saving the netCDF files
    ds_cro -- Dataset of the latlon netCDF file of the grid
    spc_name -- string of the forced species name
    open_var -- array containing the forced values by location for the species
    ds_ocean -- conc file dataset
    """
    hr = 0
    num_vars = 1
    lays = 1
    ltime = 1
    cols = len(ds_ocean.dimensions['COL'])
    rows = len(ds_ocean.dimensions['ROW'])
    datetimes = len(ds_ocean.dimensions['DATE-TIME'])

    #* Create new netCDF
    new_cmaq_file = f'{save_dir}/ocean_file_2018_NSthAm_CROS.ncf'
    ds_new_cmaq = Dataset(new_cmaq_file, open = True, mode = 'w', format=  "NETCDF3_64BIT")

    #* Create dimenssions
    TSTEP = ds_new_cmaq.createDimension("TSTEP", None)
    DATE_TIME = ds_new_cmaq.createDimension("DATE-TIME", datetimes)
    LAY = ds_new_cmaq.createDimension("LAY", lays)
    VAR = ds_new_cmaq.createDimension("VAR", num_vars)
    ROW = ds_new_cmaq.createDimension("ROW", rows)
    COL = ds_new_cmaq.createDimension("COL", cols)

    ds_new_cmaq.sync()

    #* Creatae attributes
    attrs=["IOAPI_VERSION", "EXEC_ID", "FTYPE", "CDATE", "CTIME", "WDATE", "WTIME",
           "SDATE", "STIME", "TSTEP", "NTHIK", "NCOLS", "NROWS", "GDTYP", "P_ALP",
           "P_BET", "P_GAM", "XCENT", "YCENT", "XORIG", "YORIG", "XCELL", "YCELL",
           "VGTYP", "VGTOP", "VGLVLS", "GDNAM", "HISTORY"]

    for attr in attrs:
        if hasattr(ds_ocean, attr):
            attrVal = getattr(ds_ocean, attr)
            setattr(ds_new_cmaq, attr, attrVal)

    varlist = spc_name + ' '*(16 - len(spc_name))
    cmaq_attrs = {'NLAYS': np.int32(lays),
                  'NVARS': np.int32(num_vars),
                  'UPNAM': "OCEAN_FILE",
                  'VAR-LIST': varlist,
                  'FILEDESC': "Created by Camilo Moreno"
                  }

    for attr in cmaq_attrs:
        ds_new_cmaq.setncattr(attr, cmaq_attrs[attr])

    #* Create variables
    tflag = ds_new_cmaq.createVariable('TFLAG', 'i4', ('TSTEP', 'VAR', 'DATE-TIME'))
    fill_attrs(ds_ocean, tflag, 'TFLAG')

    var_temp = ds_new_cmaq.createVariable(spc_name,"f4",("TSTEP", "LAY", "ROW", "COL"))
    fill_attrs(ds_ocean, var_temp, 'OPEN')

    #* Fill variables
    ds_new_cmaq.variables[spc_name][:, :, :] = open_var
    dattim = np.squeeze(ds_ocean.variables['TFLAG'][:][:])
    tflag[:] = np.zeros([ltime,lays,datetimes])
    tflag[:] = np.reshape(dattim,[ltime,lays,datetimes])

    #* Close new netcdf file
    ds_new_cmaq.close()

    print(f" OCEAN file DONE")

def fill_attrs(ds_ocean, nc_var, var_name):
    """Fill atribute values for variables as appear in conc file.

    Keyword arguments:
    ds_ocean -- conc file dataset
    nc_var -- netCDF variable of the file
    var_name -- variable name
    """
    varattrs=["long_name","units","var_desc"]
    for varattr in varattrs:
        if hasattr(ds_ocean.variables[var_name], varattr):
            varattrVal = getattr(ds_ocean.variables[var_name], varattr)
            setattr(nc_var, varattr, varattrVal)

def get_concfiels(ocean_file):
    """Get all files that begins whith 'CONC' from the given directory.

    Keyword arguments:
    ocean_file -- string of the directory whre conc day files
    """
    all_files = [f for f in glob.glob(f'{ocean_file}/CONC.*')]
    all_files.sort()
    return all_files

# %%
if __name__ == "__main__":
    #CHANGE: save_dir: directory path where the forced files will be saved
    #        latlon_file: path of the latlon netCDF of the run grid
    #        ocean_file: path where CONC files are located
    #        spc_name: cbo5_aero5_aq name of the one species to be forced
    #        dic_coord: dictionary containing a list of latlon coords of lower left
    #                   and upper right corners for each key-value location.
    #                   Format fo dic_coord must be:
    #                   dic_coord = {
    #                               'name_of_location_1': [lower_left_lat_1, lower_left_lon_1, upper_left_lat_1, upper_left_lon_1]
    #                               'name_of_location_2': [lower_left_lat_2, lower_left_lon_2, upper_left_lat_2, upper_left_lon_2]
    #                                 }
    save_dir = '/Volumes/Avispa/OCEAN'
    cro_file = '/Users/camilo/Downloads/ocean/GRIDCRO2D_20180208.nc'
    ocean_file = '/Users/camilo/Downloads/ocean_file_2018_NSthAm_CROS.ncf'
    spc_name = 'OPEN'

    ds_cro = Dataset(cro_file, mode = 'r',  open = True)
    ds_ocean = Dataset(ocean_file, mode = 'r',  open = True)

    open_var = create_forced_var(ds_cro)
    create_ncfile(save_dir, spc_name, open_var, ds_ocean)

    ds_ocean.close()
    ds_cro.close()

# %%


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        sentinel = ListNode()
        sentinel.next = head
        def remove_elm(curr,prev, val):
            if not curr:
                return curr
            if curr.val == val:
                # print('here')
                prev.next = curr.next if curr.next else None
                return remove_elm(curr.next, prev, val)
            else:
                # print('there')
                return remove_elm(curr.next, curr, val)
        remove_elm(sentinel.next, sentinel ,val)
        return sentinel.next


# coding=utf-8
"""
Django settings for tansparency project.

For more information on this file, see
https://docs.djangoproject.com/en/dev/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/dev/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import dj_database_url
from local_settings import *
import dropbox

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

# Application definition
INSTALLED_APPS = (
    # 'admin_tools',
    # 'admin_tools.theming',
    # 'admin_tools.menu',
    # 'admin_tools.dashboard',

    # django-autocomplete-light (2017/03/29)
    'dal',
    'dal_select2',

    # Social OAuth logins (2017/03/10)
    'social_django',

    # Forms usability improvements (2017/03/10)  TODO: fix this date (2017/03/15)
    'widget_tweaks',

    # CPF and CEP form fields (2017/03/10)  TODO: fix this date (2017/03/15)
    'localflavor',

    # Main app, handles internal management (2017/03/10)  TODO: fix this date (2017/03/15)
    'website',

    # Website at https://purubemalves.com.br (2017/03/10)  TODO: fix this date (2017/03/15)
    'home',

    # Applications for students performance tracking (2017/03/10)  TODO: fix this date (2017/03/15)
    'projeto_redacao',
    'controle_de_frequencia',

    # Feedback meta applications (2017/03/10)  TODO: fix this date (2017/03/15)
    'issues',
    'issues.templatetags',

    # Affirmative actions management (2017/03/10)
    'politicas_afirmativas',

    # Students views  (2017/03/15)
    'alunos',

    # Reports views  (2017/03/21)
    'reports',

    # Static content distribution (2017/03/10)
    'storages',

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

MIDDLEWARE_CLASSES = (
    # 'sslify.middleware.SSLifyMiddleware',  # TODO: Decomment this line before pushing (2017/03/14)
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',

    # Social OAuth login handler
    'social_django.middleware.SocialAuthExceptionMiddleware',
)

ROOT_URLCONF = 'transparency.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(PROJECT_ROOT, '../static/templates/'),
            os.path.join(BASE_DIR, '/static/templates/'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            # 'loaders': [
            #     'admin_tools.template_loaders.Loader',
            # ],
            'libraries': {
                # Templete tools for dictionaries (2017/03/15)
                'dict_filters': 'issues.templatetags.dict_filters',
            },
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',

                # Social OAuth login context processors
                'social_django.context_processors.backends',
                'social_django.context_processors.login_redirect',
            ],
        },
    },
]

# Social & Internal logins (2017/03/10)
AUTHENTICATION_BACKENDS = (
    # 'social_core.backends.github.GithubOAuth2',
    # 'social_core.backends.twitter.TwitterOAuth',
    'social_core.backends.facebook.FacebookOAuth2',

    'django.contrib.auth.backends.ModelBackend',
)

# Login information for the Alunos application (2017/03/15)
LOGIN_URL = 'login'
LOGOUT_URL = 'alunos/logout'
LOGIN_REDIRECT_URL = '/alunos'

# Django's main web application address
WSGI_APPLICATION = 'transparency.wsgi.application'

# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/dev/topics/i18n/

LANGUAGE_CODE = 'pt-BR'

TIME_ZONE = 'America/Sao_Paulo'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Update database configuration with $DATABASE_URL.
db_from_env = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(db_from_env)

# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/dev/howto/static-files/

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
ENCRYPT_URL = '/.well-known/'
# noinspection PyUnresolvedReferences
ENCRYPT_ROOT = os.path.join(STATIC_ROOT, '.well-known')

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = (
    os.path.join(PROJECT_ROOT, '../static'),
)

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

# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

# Dropbox storage settings (2017/03/15)
dbx = dropbox.Dropbox(DROPBOX_OAUTH2_TOKEN)

SECURE_SSL_REDIRECT = False
ADMIN_SITE_HEADER = "Pré-Universitário Comunitário Rubem Alves"
ADMIN_INDEX_TITLE = "Administração do Projeto"


import time
from types import MappingProxyType
from collections import namedtuple
import math

VdmInfo = namedtuple('VdmInfo', 'index data_type dimension')

class Vdm:
    """
    call Vdm.init_vdm_mapping() once before any vdm operation
    # VDM Config pages: 20h, 21h, 22h, 23h
    # VDM Real Value pages: 24h, 25h, 26h, 27h
    """
    DATA_TYPE_U16 = 1
    DATA_TYPE_S16 = 2
    DATA_TYPE_F16 = 3

    CONFIG_CODE_MAPPING = MappingProxyType({
        # config_code: [data_type, key, dimension]
        9:   [DATA_TYPE_F16, "Media Pre-FEC Minimum", 1],
        11:  [DATA_TYPE_F16, "Media Pre-FEC Maximum", 1],
        13:  [DATA_TYPE_F16, "Media Pre-FEC Average", 1],
        15:  [DATA_TYPE_F16, "Media Pre-FEC Current", 1],
        17:  [DATA_TYPE_F16, "Media Post-FEC Minimum", 1],
        19:  [DATA_TYPE_F16, "Media Post-FEC Maximum", 1],
        21:  [DATA_TYPE_F16, "Media Post-FEC Average", 1],
        23:  [DATA_TYPE_F16, "Media Post-FEC Current", 1],

        10:  [DATA_TYPE_F16, "Host Pre-FEC Minimum", 1],
        12:  [DATA_TYPE_F16, "Host Pre-FEC Maximum", 1],
        14:  [DATA_TYPE_F16, "Host Pre-FEC Average", 1],
        16:  [DATA_TYPE_F16, "Host Pre-FEC Current", 1],
        18:  [DATA_TYPE_F16, "Host Post-FEC Minimum", 1],
        20:  [DATA_TYPE_F16, "Host Post-FEC Maximum", 1],
        22:  [DATA_TYPE_F16, "Host Post-FEC Average", 1],
        24:  [DATA_TYPE_F16, "Host Post-FEC Current", 1],

        134: [DATA_TYPE_S16, "CD", 1],
        136: [DATA_TYPE_U16, "DGD", 0.01],
        138: [DATA_TYPE_U16, "PDL", 0.1],
        141: [DATA_TYPE_S16, "CFO", 1],
        142: [DATA_TYPE_U16, "EVM", 100/65535],
        139: [DATA_TYPE_U16, "OSNR", 0.1],
        140: [DATA_TYPE_U16, "ESNR", 0.1],
        147: [DATA_TYPE_U16, "MER", 0.1],

        4:   [DATA_TYPE_S16, "Laser Temp", 1/256],
        143: [DATA_TYPE_S16, "Tx Power", 0.01],
        144: [DATA_TYPE_S16, "Rx Total Power", 0.01],
        145: [DATA_TYPE_S16, "Rx Signal Power", 0.01],
        128: [DATA_TYPE_U16, "BIAS_XI", 100/65535],
        129: [DATA_TYPE_U16, "BIAS_XQ", 100/65535],
        132: [DATA_TYPE_U16, "BIAS_XP", 100/65535],
        130: [DATA_TYPE_U16, "BIAS_YI", 100/65535],
        131: [DATA_TYPE_U16, "BIAS_YQ", 100/65535],
        133: [DATA_TYPE_U16, "BIAS_YP", 100/65535],
        2:   [DATA_TYPE_S16, "TEC_CUR", 100/32767]
    })

    def __init__(self, trx):
        self.__trx = trx
        self.__vdm_mapping = None

    def __getitem__(self, key):
        return self.__get_vdm(key)

    def init_vdm_mapping(self):
        config_pages = [0x20, 0x21, 0x22, 0x23]
        vdm_mapping = {}
        for idx_page, page in enumerate(config_pages):
            self.__trx.select_bank_page(0, page)
            b_full_page = self.__trx[128:255]
            config_codes = [int.from_bytes(b_full_page[2*i+1: 2*i+2], 'big') for i in range(64)]
            for idx_config, i_code in enumerate(config_codes):
                if i_code in self.CONFIG_CODE_MAPPING:
                    d_type, key, dim = self.CONFIG_CODE_MAPPING[i_code]
                    vdm_mapping[key] = VdmInfo(
                        index=idx_config+idx_page*64+1,
                        data_type=d_type,
                        dimension=dim
                    )
        self.__vdm_mapping = vdm_mapping

    @property
    def mapping(self):
        if self.__vdm_mapping is None:
            raise ValueError('Please call init_vdm_mapping before any vdm operation.')
        else:
            return self.__vdm_mapping

    @property
    def keys(self):
        return self.mapping.keys()

    @property
    def FreezeRequest(self):
        flag = self.__trx[0, 0x2F, 144][7]
        freeze = bool(flag)
        return freeze

    @FreezeRequest.setter
    def FreezeRequest(self, freezed):
        if not freezed in (True, False):
            raise ValueError('Parameter freezed should be bool.')
        self.__trx[0, 0x2F, 144][7] = int(freezed)

    @property
    def FreezeDone(self):
        flag = self.__trx[0, 0x2F, 145][7]
        done = bool(flag)
        return done

    @property
    def UnfreezeDone(self):
        flag = self.__trx[0, 0x2F, 145][6]
        done = bool(flag)
        return done

    def freezeUntilDone(self):
        self.FreezeRequest = True
        while not self.FreezeDone:
            time.sleep(0.05)

    def unfreezeUntilDone(self):
        self.FreezeRequest = False
        while not self.UnfreezeDone:
            time.sleep(0.05)

    def __parse_data(self, raw, data_type, dimension):
        if data_type == self.DATA_TYPE_U16:
            val = raw.to_unsigned()
        elif data_type == self.DATA_TYPE_S16:
            val = raw.to_signed()
        elif data_type == self.DATA_TYPE_F16:
            u_int_val = raw.to_unsigned()
            val = (u_int_val & 0x7FF) * 10**((u_int_val >> 11) - 24)
        else:
            raise ValueError('Invalid data_type: {:!r}'.format(data_type))
        if val != 1:
            val *= dimension
        return val

    def __calc_page_reg_from_vdm_index(self, index):
        page = math.ceil(index/64) + 0x24 - 1
        reg_addr = ((index-1) % 64) * 2 + 128
        return page, reg_addr

    def __get_vdm(self, key):
        if key not in self.keys:
            raise KeyError('Invalid key for VDM: {key}. Not configured in VDM Configuration pages.'.format(key=key))
        vdm_info = self.mapping[key]
        index, data_type, dimension = vdm_info
        page, reg_addr = self.__calc_page_reg_from_vdm_index(index)
        raw = self.__trx[0, page, reg_addr: reg_addr+1]
        val = self.__parse_data(raw, data_type, dimension)
        return val


def IsProcess64Bit(processId: int) -> bool:
    """
    Return True if process is 64 bit.
    Return False if process is 32 bit.
    Return None if unknown, maybe caused by having no acess right to the process.
    """
    try:
        func = ctypes.windll.ntdll.ZwWow64ReadVirtualMemory64  #only 64 bit OS has this function
    except Exception as ex:
        return False
    try:
        IsWow64Process = ctypes.windll.kernel32.IsWow64Process
        IsWow64Process.argtypes = (ctypes.c_void_p, ctypes.POINTER(ctypes.c_int))
    except Exception as ex:
        return False
    hProcess = ctypes.windll.kernel32.OpenProcess(0x1000, 0, processId)  #PROCESS_QUERY_INFORMATION=0x0400,PROCESS_QUERY_LIMITED_INFORMATION=0x1000
    if hProcess:
        is64Bit = ctypes.c_int32()
        if IsWow64Process(hProcess, ctypes.byref(is64Bit)):
            ctypes.windll.kernel32.CloseHandle(ctypes.c_void_p(hProcess))
            return False if is64Bit.value else True
        else:
            ctypes.windll.kernel32.CloseHandle(ctypes.c_void_p(hProcess))


import time
from delfin.drivers.netapp.netapp_fas import netapp_constants
from delfin.common import constants

ALERT_SEVERITY_MAP = {
    'Unknown': constants.Severity.NOT_SPECIFIED,
    'Other': constants.Severity.NOT_SPECIFIED,
    'Information': constants.Severity.INFORMATIONAL,
    'Degraded': constants.Severity.WARNING,
    'Minor': constants.Severity.MINOR,
    'Major': constants.Severity.MAJOR,
    'Critical': constants.Severity.CRITICAL,
    'Fatal': constants.Severity.FATAL,
}

class AlertHandler(object):
    @staticmethod
    def handle_detail(system_info, storage_map, split):
        detail_arr = system_info.split('\n')
        for detail in detail_arr:
            if detail is not None and detail != '':
                strinfo = detail.split(split + " ")
                key = strinfo[0].replace(' ', '')
                value = ''
                if len(strinfo) > 1:
                    value = strinfo[1]
                storage_map[key] = value

    @staticmethod
    def list_events(self, event_info, query_para, alert_list):
        event_arr = event_info.split(netapp_constants.ALTER_SPLIT_STR)
        event_map = {}
        for event_str in event_arr[1:]:
            self.handle_detail(event_str, event_map, split=':')
            occur_time = int(time.mktime(time.strptime(
                event_map['Time'],
                netapp_constants.EVENT_TIME_TYPE)))
            if query_para is None or \
                    (query_para['begin_time']
                     <= occur_time
                     <= query_para['end_time']):
                alert_model = {
                    'alert_id': event_map['Sequence#'],
                    'alert_name': event_map['MessageName'],
                    'severity': event_map['Severity'],
                    'category': constants.Category.EVENT,
                    'type': constants.EventType.EQUIPMENT_ALARM,
                    'occur_time': occur_time,
                    'description': event_map['Event'],
                    'sequence_number': event_map['Sequence#'],
                    'resource_type': constants.DEFAULT_RESOURCE_TYPE,
                    'location': event_map['Source']
                }
                alert_list.append(alert_model)

    @staticmethod
    def list_alerts(self, alert_info, query_para, alert_list):
        alert_arr = alert_info.split(netapp_constants.ALTER_SPLIT_STR)
        alert_map = {}
        for alert_str in alert_arr[1:]:
            self.handle_detail(alert_str, alert_map, split=':')
            occur_time = int(time.mktime(time.strptime(
                alert_map['IndicationTime'],
                netapp_constants.ALTER_TIME_TYPE)))
            if query_para is None or \
                    (query_para['begin_time']
                     <= occur_time
                     <= query_para['end_time']):
                alert_model = {
                    'alert_id': alert_map['AlertID'],
                    'alert_name': alert_map['ProbableCause'],
                    'severity':
                        ALERT_SEVERITY_MAP[alert_map['PerceivedSeverity']],
                    'category': constants.Category.FAULT,
                    'type': constants.EventType.EQUIPMENT_ALARM,
                    'occur_time': occur_time,
                    'description': alert_map['Description'],
                    'sequence_number': alert_map['AlertID'],
                    'resource_type': constants.DEFAULT_RESOURCE_TYPE,
                    'location': alert_map['AlertingResourceName']
                }
                alert_list.append(alert_model)


# 3. Создать текстовый файл (не программно),
# построчно записать фамилии сотрудников и величину их окладов.
# Определить, кто из сотрудников имеет оклад менее 20 тыс.,
# вывести фамилии этих сотрудников. Выполнить подсчет средней величины дохода сотрудников.

with open('salary.txt', 'r', encoding='utf-8') as my_file:
    sal = []
    poor = []
    my_list = my_file.read().split('\n')
    for i in my_list:
        i = i.split()
        if int(i[1]) < 20000:
            poor.append(i[0])
        sal.append(i[1])
print(f'Оклад меньше 20.000 {poor}, средний оклад {sum(map(int, sal)) / len(sal)}')

# правильный вариант решения (после разбора на уроке)

with open('text_3.txt', 'r', encoding='utf-8') as f:
    employees_dict = {line.split()[0]: float(line.split()[1]) for line in f}
    print(f'average salary = {round(sum(employees_dict.values()) / len(employees_dict), 3)}\n'
          f'employees with salary less than 20k {[e[0] for e in employees_dict.items() if e[1] < 20000]}')


'''
9. Write a program which implements master-worker mode:
    1 host must create N worker processes by itself
    2 when worker is created, he writes his rank in the console
    3 each worker sends his rank to host
    4 host shows the messages received in the console
    For this program you need to write two scripts - host.py and worker.py, each will implement its own logic.
'''

'''
9. Напишите программу, которая реализует режим master-worker:
    1 хост должен сам создать N рабочих процессов
    2 когда работник создан, он записывает свой ранг в консоль
    3 каждый работник отправляет свой ранг хозяину
    4 хост показывает сообщения, полученные в консоли
    Для этой программы вам нужно написать два скрипта - host.py и worker.py , каждый будет реализовывать свою собственную логику.
'''

import logging as log
from mpi4py import MPI as mpi

comm = mpi.Comm.Get_parent()
rank = comm.Get_rank()
host = 0

# 2 when worker is created, he writes his rank in the console
log.error("Host created {} worker!".format(rank))
#print("Host created {} worker!".format(rank))

# 3 each worker sends his rank to host
comm.send(rank, dest=host)

comm.Disconnect()


from django.conf.urls import patterns, include, url
from techstack_app.views import *

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'techstack.views.home', name='home'),
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin', include(admin.site.urls)),
    url(r'^companies', companies_page),
    url(r'^search', search_controller),
    url(r'^new', add_company_page),
    url(r'^company/(\d+)$', company_page),
    url(r'^tagcloud', tagcloud_page),
    url(r'^parse', parse_blogs),
    url(r'', home_page),
)


def maxPerformance(n, speed, efficiency, k):
    _speed = [x for x, _ in sorted(zip(speed, efficiency), key=lambda p:p[1])]
    efficiency.sort()
    print(_speed)
    print(efficiency)
    from functools import lru_cache
    @lru_cache
    def util(index, total_speed, min_eff, count):
        if index >= n:
            return total_speed * min_eff
        if count == k:
            return total_speed * min_eff
        r1 = util(index + 1, total_speed + _speed[index], min(min_eff, efficiency[index]), count + 1)
        r2 = util(index + 1, total_speed, min_eff, count)
        return max(r1, r2)
    return util(0, 0, float('inf'), 0)

def maxPerformanceOp(n, speed, efficiency, k):
    from heapq import heappop, heappush
    engineers = list(zip(efficiency, speed))
    engineers.sort(reverse=True)
    min_heap = []
    speedSum = 0
    ans = 0
    for e, s in engineers:
        speedSum += s
        heappush(min_heap, s)
        if len(min_heap) > k:
            speedSum -= heappop(min_heap)
        ans = max(ans, speedSum*e)
    return ans % 1_000_000_007

n = 6
speed =  [2,10,3,1,5,8]
efficiency = [5,4,3,9,7,2]
k =4
result = maxPerformanceOp(n, speed, efficiency, k)
print(result)


import math
import numpy as nup

#INPUTS
#CHORD   local blade chord
#BETA    local blade angle  (radians)
#rr       local radius
#BLDS    number of blades
#RAD     tip radius  (for Prandtl's factor)
#VEL     forward flight speed
#OMG     rotational speed  (radians/time)
#VSO     speed of sound
#MCRIT

PI = nup.pi
euler = nup.e
EPS = 1.0E-6
MSQMAX = 0.9

rr = 0.1
VEL = 10
rpm = 2300
OMG = rpm*2*PI/60
BLDS = 4
RAD = 0.3
BETA = math.radians(30)
VSO = 340
CHORD = 0.05

CL0 = 0.56
DCLDA = 5.58
CLMIN = -0.3
CLMAX = 1.37
MCRIT = 0.7

U0A = 0.
U0T = 0.
UA     = VEL   + U0A
UT     = OMG*rr - U0T

WZ = (UA**2 + UT**2)**0.5

PSI2 = BETA + CL0/DCLDA
PSI = math.atan(UA/UT)
PSI = max(PSI, PSI2)

while True:
    COSP = math.cos(PSI)
    SINP = math.sin(PSI)

    WA     = 0.5*UA     + 0.5*WZ    *SINP
    WA_PSI =              0.5*WZ    *COSP
    WT     = 0.5*UT     + 0.5*WZ    *COSP
    WT_PSI =            - 0.5*WZ    *SINP

    if (WA == 0.0):
        F     = 1.0
        F_PSI = 0
        ADW     = 0
        ADW_PSI = 0

    else:
        TSR = WT/WA * RAD/rr
        TSR_PSI = (WT_PSI * RAD/rr - TSR*WA_PSI)/WA
        FARG     = 0.5*BLDS*(1.0-rr/RAD)*TSR
        FARG_TSR = 0.5*BLDS*(1.0-rr/RAD)
        FARG = min( FARG , 20.0 )
        FEXP = euler**(-FARG)
        FEXP_TSR = -FEXP*FARG_TSR
        F = (2.0/PI) * math.acos(FEXP)
        F_TSR = -(2.0/PI) / ((1.0 - FEXP**2)**0.5) * FEXP_TSR
        F_PSI = F_TSR*TSR_PSI
        ADW     =  1.0    /TSR
        ADW_PSI = -TSR_PSI/TSR**2

    VA     = WA     - UA
    VA_PSI = WA_PSI
    VT     = UT     - WT
    VT_PSI =        - WT_PSI

    QBI = 4.0/BLDS
    PIR = ((PI*rr)**2 + (QBI*RAD*ADW)**2)**0.5
    PIR_ADW = (QBI*RAD)**2*ADW/PIR
    PIR_PSI = PIR_ADW*ADW_PSI

    GAM     = QBI* F*VT                *PIR
    GAM_PSI = QBI*(F*VT_PSI + F_PSI*VT)*PIR + QBI*F*VT*PIR_PSI

    WSQ = WA**2 + WT**2
    W = (WSQ)**0.5
    W_PSI = (WA*WA_PSI + WT*WT_PSI)/W

    A = BETA - math.atan(WA/WT)
    A_PSI = (-WT*WA_PSI + WA*WT_PSI)/WSQ

    MSQ = WSQ / VSO**2
    MSQ_PSI = 2.0*W*W_PSI / VSO**2

    if (MSQ > MSQMAX):
        MSQ = MSQMAX
        MSQ_PSI = 0.

    PG = 1.0 / (1.0 - MSQ)**0.5
    PG_MSQ = 0.5*PG / (1.0 - MSQ)
    PG_PSI = PG_MSQ*MSQ_PSI

    CL     = (DCLDA*A + CL0)*PG
    CL_PSI =  DCLDA*A_PSI   *PG + (DCLDA*A + CL0)*PG_PSI

    STALL = False
    if (CL > CLMAX):
        STALL = True
        ACL0 = CL0/DCLDA
        CL   =  CLMAX*math.cos(A-ACL0)
        CL_A = -CLMAX*math.sin(A-ACL0)
        CL_PSI = CL_A*A_PSI

    elif (CL < CLMIN):
        STALL = True
        ACL0 = CL0/DCLDA
        CL   =  CLMIN*math.cos(A-ACL0)
        CL_A = -CLMIN*math.sin(A-ACL0)
        CL_PSI = CL_A*A_PSI

    RES     = GAM     - 0.5*CHORD* CL*W
    RES_PSI = GAM_PSI - 0.5*CHORD*(CL*W_PSI + CL_PSI*W)

    DPSI = -RES/RES_PSI
    DPSI = max(-0.1, min(0.1, DPSI))

    if(abs(DPSI) < EPS):
        LCONV = True
        break

    PSI = PSI + DPSI

print(f"Res, a, CL = {RES} {A} {CL}")


import time

door = 16616892
card = 14505727

def find_loop_size(to_find):
    value = 1
    loop_size = 0
    while 1:
        loop_size += 1
        value = value * 7
        value = value % 20201227
        if value == to_find:
            return loop_size

def find_key(loops, subject_number):
    value = 1
    for loop_size in range(loops):
        value = value * subject_number
        value = value % 20201227
    return value

start = time.time()
print("part one {}".format(find_key(find_loop_size(door), card)))
print("time taken {}".format(time.time() - start))


#%%
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import copy
from collections import deque
from pandas.core.frame import DataFrame
from sklearn import metrics
import scipy.stats as st
from collections import defaultdict
import math
from scipy.interpolate import interp1d
from scipy.interpolate import PchipInterpolator
#%%
def df_get_pdf(df,X,Y,X_len,delta=None,CDF_Monotonic=True):
    def feature_cdf(df,X,Y,ascending=True):
        def zero():
            return 0
        # df sort
        arr_len = df.shape[0]
        feat_N = df[Y].unique()

        # Y_arrary
        Y_arr = np.array(df[Y])
        PY_arr = np.zeros((arr_len,feat_N.shape[0]),dtype=float)
        columns = ["%s_cdf(%s=%s)" %("As" if ascending==True else "Ds",Y,v) for i,v in enumerate(feat_N)]

        tmp_N = defaultdict(zero)
        for ind_,val_ in enumerate(Y_arr):
            for fi_,fv_ in enumerate(feat_N):
                if val_ == fv_:
                    tmp_N[fv_] += 1
                    PY_arr[ind_,fi_] = tmp_N[fv_]
                else:
                    PY_arr[ind_,fi_] = tmp_N[fv_]

        for fi_,fv_ in enumerate(feat_N):
            PY_arr[:,fi_] = PY_arr[:,fi_] / tmp_N[fv_]

        df_cdf = pd.concat([df[X],
                            pd.DataFrame(PY_arr,columns=columns)],axis=1)\
                    .groupby(by=[X]).max()
        return df_cdf.sort_index()

    def get_interfunc(df,Y):
        X_Y = np.zeros((df.shape[0] + 2,2))
        X_Y[1:-1,0] = df.index
        X_Y[1:-1,1] = df[Y]
        X_Y[0] = 2 * X_Y[1] - X_Y[2]
        X_Y[-1] = 2 * X_Y[-2] - X_Y[-3]
        X_Y[0,1] = 0
        X_Y[-1,1] = 1

        if CDF_Monotonic == True:
            func_ = PchipInterpolator(X_Y[:,0], X_Y[:,1])
        else:
            func_ = interp1d(X_Y[:,0], X_Y[:,1], kind = 'quadratic')
        return func_, X_Y[-2,0] - X_Y[-3,0]

    df_sort = df.sort_values(by=[X]).reset_index(drop=True)
    feat_X = df_sort[X].to_numpy()  #格式轉換

    interval_n = math.ceil((feat_X.max()-feat_X.min())/X_len)
    feat_Xmin = feat_X.min()
    for i in range(interval_n,-1,-1):
        feat_X[(feat_Xmin + (i)*X_len <= feat_X) &\
               (feat_X < feat_Xmin + (i+1)*X_len) ] = feat_Xmin + (i+1)*X_len

    feat_cdf = feature_cdf(df_sort, X=X, Y=Y)
    cols = feat_cdf.columns

    if delta == None:
        delta = X_len/2

    X_delta1 = feat_X - X_len/2 + delta
    X_delta2 = feat_X - X_len/2 - delta
    for col in cols:
        XY_func,delta_tmp = get_interfunc(feat_cdf,col)
        Y_delta1 = XY_func(X_delta1)
        Y_delta2 = XY_func(X_delta2)
        df_sort['pdf' + col[6:]] = (Y_delta2 - Y_delta1 ) /(X_delta2 - X_delta1)

    df_sort[X] = feat_X - X_len/2

    return df_sort

#%%
if __name__ == "__main__":
    #data prepare
    mu, sigma = 10, 5
    s1 = st.norm(mu, sigma).rvs(100000)
    s2 = st.norm(mu-4, sigma+4).rvs(100000)

    df_1 = pd.DataFrame(s1,columns=["feat"]  )
    df_1['Y'] = 0

    df_2 = pd.DataFrame(s2,columns=["feat"]  )
    df_2['Y'] = 1
    df = pd.concat([df_1,df_2],axis=0).reset_index(drop=True)

#%%
X_len = 1
delta = .5
X = 'feat'
Y = 'Y'
bins = math.ceil((df[X].max()-df[X].min())/X_len)-2

# df_get_pdf
df_pdf = df_get_pdf(df, X=X, Y=Y, X_len=X_len, delta=delta,CDF_Monotonic=True)
df_pdf['pdf_diff'] = df_pdf['pdf(Y=1)'] - df_pdf['pdf(Y=0)']
df[X].min()
plt.figure(figsize=(15,10),dpi=100,linewidth = 2)
plt.hist(df.loc[df[Y]==0,X],bins=bins,density=True)
plt.hist(df.loc[df[Y]==1,X],bins=bins,density=True)
plt.plot(df_pdf[X],df_pdf['pdf(Y=1)'],'o-',color = 'r', label="pdf(Y=1)")
plt.plot(df_pdf[X],df_pdf['pdf(Y=0)'],'o-',color = 'g', label="pdf(Y=0)")
#plt.plot(df_pdf['feat'],df_pdf['pdf_diff'],'-',color = 'b', label="pdf_diff")

plt.xticks(fontsize=20)
plt.yticks(fontsize=20)

# 標示x,y軸(labelpad代表與圖片的距離)
plt.xlabel("feat", fontsize=30, labelpad = 15)
plt.ylabel("pdf", fontsize=30, labelpad = 20)

# 顯示出線條標記位置
plt.legend(loc = "best", fontsize=20)
plt.show()


import joblib
import numpy as np

if __name__ == '__main__':
    print('loading models...')
    sub_cat = joblib.load('sub_model.pkl')
    sub_categories = joblib.load('sub_slugs.pkl')

    while(True):
        text = input("input (or ctrl+c to stop):")

        a = sub_cat.predict_proba([text])
        z = int(np.argmax(a, axis=1))
        r = sub_categories[z],max(a[0])
        print(r)


import sys
input = sys.stdin.readline

def init(start, end, node):
    if start == end:
        tree[node] = arr[start]
        return tree[node]
    mid = (start + end) // 2
    tree[node] = init(start, mid, node * 2) + init(mid + 1, end, node * 2 + 1)
    return tree[node]

def sum(start, end, node, left, right):
    if left > end or right < start:
        return 0
    if left <= start and end <= right:
        return tree[node]
    mid = (start + end) // 2
    return sum(start, mid, node * 2, left, right) + sum(mid + 1, end, node * 2 + 1, left, right)

def update(start, end, node, index, dif):
    if index < start or index > end:
        return
    tree[node] += dif
    if start == end:
        return
    mid = (start + end) // 2
    update(start, mid, node * 2, index, dif)
    update(mid + 1, end, node * 2 + 1, index, dif)

N, M, K = map(int, input().split())
arr = [int(input()) for _ in range(N)]
tree = [0] * (N * 4)
init(0, N - 1, 1)
for _ in range(M + K):
    a, b, c = map(int, input().split())
    if a == 1:
        update(0, N - 1, 1, b - 1, c - arr[b - 1])
        arr[b - 1] = c
    if a == 2:
        print(sum(0, N - 1, 1, b - 1, c - 1))

백준/단계별로 풀기/SegmentTree/1. 구간 합 구하기_2042.py


import os, pyowm, subprocess, tweepy
#This contains the API keys
from credentials import *

class ExternalConnection(object):
    __instance = None
    @staticmethod
    def getInstance():
        if ExternalConnection.__instance == None:
            ExternalConnection()
        return ExternalConnection.__instance
    def __init__(self):
        if ExternalConnection.__instance !=None:
            raise Exception ("This class is a singleton")
        else:
            ExternalConnection.__instance = self
            self.api = ""
            self.TweetAPIConnect()
            self.pyOWMConnect()
    def TweetAPIConnect(self):
        auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
        auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)
        self.api = tweepy.API(auth)
        print("\nSuccessfully connected to Twitter API.\n")
        #needs a disconnect
    def pyOWMConnect(self):
        #initialize OWM object with API key
        self.owm = pyowm.OWM(OWM_KEY)
        print("\nSuccessfully connected to PYOWM API.")
    def pingTest(self):
        #this will ping infinitely on linux without the -c parameter
        hostname = "twitter.com"
        with open(os.devnull, 'w') as DEVNULL:
            try:
                subprocess.check_call(
                    ['ping', hostname],
                    stdout=DEVNULL,  # suppress output
                    stderr=DEVNULL
                )
                isUp = True
            except subprocess.CalledProcessError:
                isUp = False
        return isUp
    def WANtest(self):
        #run pingTest up to maxTries. return result of pingTest
        WANup = False
        tryCount = 1
        maxTries = 10
        waitTime = 5
        while(WANup == False and tryCount <= maxTries):
            if(self.pingTest()):
                #test connectivity
                WANup = True
                if(tryCount > 1):
                    print("\nWAN was down, but was restored.")
                return WANup
            else:
                print("\nWAN down. Try " + str(tryCount) + " failed. Waiting " + str(waitTime) + " seconds to retry.")
                time.sleep(waitTime)
                tryCount +=1
                if(tryCount > maxTries):
                    print("\nMax tries attempted.")
                    return WANup
    def returnTwitterConnection(self):
        return self.api
    def returnOWMConnection(self):
        return self.owm


'''Escribir un programa que pida al usuario su peso (en kg) y estatura (en metros)
calcule el índice de masa corporal y lo almacene en una variable.
Luego, debe mostrar por pantalla la frase: “Tu índice de masa corporal es:{imc}”
No olvide validar'''

imc = 0

while imc == 0: #Ciclo while general
    try:
        peso = int(input("Ingrese su peso en Kg: "))
    except: #Try-Except para el peso
        print("Solo debe ingresar numeros enteros")
    else:
        if peso <= 0: #Validación del peso
            print("Usted es un pitufo, o no existe")
        else:
            while True: #Ciclo while para la altura y el calculo del IMC
                try:
                    altura = float(input("Ingrese su altura en metros: "))
                    if 0.0 < altura < 3.0:
                        imc = peso / (altura)**2 #Calculo del IMC
                        break
                    else:
                        print("La altura debe ser menor a 3 metros y mayor a 0")
                except: #Try-Except para la altura
                    print("Ingrese numeros reales")

print(f"Su indice de masa corporal es {imc:.1f}") #print final, redondea el valor de imc con :.1f


from typing import Iterator

import requests
from base import LotSpaces, Scraper

class NJITScraper(Scraper):
    """Scrape NJIT json.

    https://mobile.njit.edu/parking/
    """

    HOME_URL = "https://mobile.njit.edu/parking/"
    API_URL = "http://mobile.njit.edu/parking/data.php"
    TIMEOUT = 5

    name = "njit"

    def fetch_spaces(self) -> Iterator[LotSpaces]:
        session = requests.Session()
        session.get(self.HOME_URL, headers={"User-Agent": "open-parking-spaces"})
        response = session.post(
            self.API_URL, timeout=self.TIMEOUT, headers={"Referer": self.HOME_URL}
        )
        response.raise_for_status()
        data = response.json()
        for row in data["decks"].values():
            yield LotSpaces(
                lot=row["SiteName"],
                spaces=int(row["Available"]),
                capacity=int(row["Total"]),
                address=row["Address"],
            )


#!/usr/bin/python3

import datetime
import stat
import os
from pathlib import Path
import secrets
import logging
import ipaddress

from cryptography import x509
from cryptography.hazmat.primitives import serialization as crypto_serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend as crypto_default_backend
from cryptography.x509.oid import NameOID
import nacl
from nacl import secret
import hashlib
import base64

from gi.repository import GLib, GObject

import util
import prefs

day = datetime.timedelta(1, 0, 0)
EXPIRE_TIME = 30 * day

DEFAULT_GROUP_CODE = "Warpinator"
KEYFILE_GROUP_NAME = "warpinator"
KEYFILE_CODE_KEY = "code"
KEYFILE_UUID_KEY = "connect_id"
CONFIG_FILE_NAME = ".group"

CONFIG_FOLDER = os.path.join(GLib.get_user_config_dir(), "warpinator")

singleton = None

def get_singleton():
    global singleton

    if singleton == None:
        singleton = AuthManager()

    return singleton

class AuthManager(GObject.Object):
    __gsignals__ = {
        'group-code-changed': (GObject.SignalFlags.RUN_LAST, None, ())
    }

    def __init__(self):
        GObject.Object.__init__(self)
        self.hostname = util.get_hostname()
        self.ident = ""
        self.ip_info = None
        self.port = None
        self.code = ""

        self.private_key = None
        self.server_cert = None

        self.remote_certs = {}

        os.makedirs(CONFIG_FOLDER, exist_ok=True)
        self.path = Path(os.path.join(CONFIG_FOLDER, CONFIG_FILE_NAME))

    def update(self, ip_info, port):
        self.ip_info = ip_info;
        self.port = port

        self._load_keyfile()

        self._read_ident()
        self._read_group_code()

        self._make_key_cert_pair()

    def get_ident(self):
        return self.ident

    def get_group_code(self):
        return self.code;

    def update_group_code(self, code):
        if code == self.code:
            return

        self.keyfile.set_string(KEYFILE_GROUP_NAME, KEYFILE_CODE_KEY, code)
        self._save_keyfile()

        self.emit("group-code-changed")

    def get_server_creds(self):
        return (self.server_private_key, self.server_pub_key)

    def get_cached_cert(self, hostname, ip_info):
        try:
            return self.remote_certs["%s.%s" % (hostname, ip_info.ip4_address)]
        except KeyError:
            return None

    def process_remote_cert(self, hostname, ip_info, server_data):
        if server_data == None:
            return False
        decoded = base64.decodebytes(server_data)

        hasher = hashlib.sha256()
        hasher.update(bytes(self.code, "utf-8"))
        key = hasher.digest()
        decoder = secret.SecretBox(key)

        try:
            cert = decoder.decrypt(decoded)
        except nacl.exceptions.CryptoError as e:
            print(e)
            cert = None

        if cert:
            self.remote_certs["%s.%s" % (hostname, ip_info.ip4_address)] = cert
            return True
        else:
            return False

    def get_encoded_local_cert(self):
        hasher = hashlib.sha256()
        hasher.update(bytes(self.code, "utf-8"))
        key = hasher.digest()

        encoder = secret.SecretBox(key)

        encrypted = encoder.encrypt(self.server_pub_key)
        encoded = base64.encodebytes(encrypted)
        return encoded

# Internals
    def _load_keyfile(self):
        self.keyfile = GLib.KeyFile()

        try:
            self.keyfile.load_from_file(self.path.as_posix(), GLib.KeyFileFlags.NONE)
        except GLib.Error as e:
            if e.code == GLib.FileError.NOENT:
                logging.debug("Auth: No group code file, making one.")
                self.path.touch()
            else:
                logging.debug("Auth: Could not load existing keyfile (%s): %s" %(CONFIG_FOLDER, e.message))
                self.path.unlink()
                self.path.touch()

    def _save_keyfile(self):
        keyfile_bytes = bytes(self.keyfile.to_data()[0], "utf-8")

        try:
            self.path.unlink()
        except OSError:
            pass

        flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
        mode = stat.S_IRUSR | stat.S_IWUSR
        umask = 0o777 ^ mode  # Prevents always downgrading umask to 0.

        umask_original = os.umask(umask)

        try:
            fdesc = os.open(self.path, flags, mode)
        finally:
            os.umask(umask_original)

        with os.fdopen(fdesc, 'wb') as f:
            f.write(keyfile_bytes)

    def _read_ident(self):
        gen_new = False

        try:
            self.ident = self.keyfile.get_string(KEYFILE_GROUP_NAME, KEYFILE_UUID_KEY)
        except GLib.Error as e:
            if e.code not in (GLib.KeyFileError.KEY_NOT_FOUND, GLib.KeyFileError.GROUP_NOT_FOUND):
                logging.critical("Could not read uuid (ident) from settings file: %s" % e.message)

            gen_new = True

        if len(self.ident.split("-")) == 5:
            gen_new = True

        if gen_new:
            # Max 'instance' length is 63.
            # https://datatracker.ietf.org/doc/html/rfc6763#section-7.2
            self.ident = "%s-%s" % (self.hostname.upper()[:42], secrets.token_hex(10).upper())
            self.keyfile.set_string(KEYFILE_GROUP_NAME, KEYFILE_UUID_KEY, self.ident)
            self._save_keyfile()

    def _read_group_code(self):
        reset = False
        code = None

        try:
            code = self.keyfile.get_string(KEYFILE_GROUP_NAME, KEYFILE_CODE_KEY)
        except GLib.Error as e:
            if e.code not in (GLib.KeyFileError.KEY_NOT_FOUND, GLib.KeyFileError.GROUP_NOT_FOUND):
                logging.warn("Could not read group code from settings file (%s): %s" % (CONFIG_FOLDER, e.message))

        if code == None or code == "":
            self.code = DEFAULT_GROUP_CODE
            self._save_keyfile()
            return

        if len(code) < 8:
            logging.warn("Group Code is short, consider something longer than 8 characters.")

        self.code = code

    def _make_key_cert_pair(self):
        logging.debug("Auth: Creating server credentials")

        private_key = rsa.generate_private_key(
            backend=crypto_default_backend(),
            public_exponent=65537,
            key_size=2048
        )

        public_key = private_key.public_key()

        builder = x509.CertificateBuilder()
        builder = builder.subject_name(x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, self.hostname),
        ]))
        builder = builder.issuer_name(x509.Name([
            x509.NameAttribute(NameOID.COMMON_NAME, self.hostname),
        ]))
        builder = builder.not_valid_before(datetime.datetime.today() - day)
        builder = builder.not_valid_after(datetime.datetime.today() + EXPIRE_TIME)
        builder = builder.serial_number(x509.random_serial_number())
        builder = builder.public_key(public_key)

        alt_names = []

        if self.ip_info.ip4_address != None:
            alt_names.append(x509.IPAddress(ipaddress.IPv4Address(self.ip_info.ip4_address)))

        builder = builder.add_extension(x509.SubjectAlternativeName(alt_names), critical=True)

        certificate = builder.sign(
            private_key=private_key, algorithm=hashes.SHA256(),
            backend=crypto_default_backend()
        )

        ser_private_key = private_key.private_bytes(
            crypto_serialization.Encoding.PEM,
            crypto_serialization.PrivateFormat.PKCS8,
            crypto_serialization.NoEncryption())

        ser_public_key = certificate.public_bytes(
            crypto_serialization.Encoding.PEM
        )

        self.server_pub_key = ser_public_key
        self.server_private_key = ser_private_key