from __future__ import absolute_import, division, print_function
'''
'''

import iotbx.pdb
import mmtbx.model

from iotbx.file_reader import any_file
from iotbx.data_manager import DataManagerBase
from libtbx import Auto
from libtbx.utils import Sorry

# =============================================================================
class ModelDataManager(DataManagerBase):

  datatype = 'model'

  # ---------------------------------------------------------------------------
  # Models
  def add_model_phil_str(self):
    '''
    Add custom PHIL and storage for type
    '''

    # set up storage
    # self._model_types = dict()  # [filename] = type
    self._model_types = dict()
    self._default_model_type = 'x_ray'
    self._possible_model_types = ['x_ray', 'neutron', 'electron']

    # custom PHIL section
    custom_phil_str = '''
model
  .multiple = True
{
  file = None
    .type = path
    .short_caption = Model file
    .style = file_type:pdb input_file
  type = *%s
    .type = choice(multi=False)
}
''' % ' '.join(self._possible_model_types)

    # custom PHIL scope
    self._custom_model_phil = iotbx.phil.parse(custom_phil_str)

    return custom_phil_str

  def export_model_phil_extract(self):
    '''
    Export custom PHIL extract
    '''
    extract = list()
    filenames = self.get_model_names()
    for filename in filenames:
      item_extract = self._custom_model_phil.extract().model[0]
      item_extract.file = filename
      item_extract.type = self._model_types.get(
        filename, self._default_model_type)
      extract.append(item_extract)
    return extract

  def load_model_phil_extract(self, phil_extract):
    '''
    Load custom PHIL extract
    '''
    extract = phil_extract.data_manager.model
    for item_extract in extract:
      if ((not hasattr(item_extract, 'file')) or
          (not hasattr(item_extract, 'type'))):
        raise Sorry('This PHIL is not properly defined for the "model" datatype.\n There should be a parameter for the filename ("file") and type ("type").\n')

      # process file
      self.process_model_file(item_extract.file)
      self._model_types[item_extract.file] = item_extract.type

  def add_model(self, filename, data):
    return self._add(ModelDataManager.datatype, filename, data)

  def set_default_model_type(self, model_type):
    if (model_type not in self._possible_model_types):
      raise Sorry('Unrecognized model type, "%s," possible choices are %s.' %
                  (model_type, ', '.join(self._possible_model_types)))
    self._default_model_type = model_type

  def get_default_model_type(self):
    return self._default_model_type

  def set_default_model(self, filename):
    return self._set_default(ModelDataManager.datatype, filename)

  def get_model(self, filename=None):
    model = self._get(ModelDataManager.datatype, filename)
    if (self.supports('restraint')):
      restraint_objects = list()
      for filename in self.get_restraint_names():
        restraint_objects.append((filename, self.get_restraint(filename)))
      model.set_restraint_objects(restraint_objects)
    return model

  def set_model_type(self, filename=None, model_type=None):
    if (filename is None):
      filename = self.get_default_model_name()
    if (model_type is None):
      model_type = self._default_model_type
    elif (model_type not in self._possible_model_types):
      raise Sorry('Unrecognized model type, "%s," possible choices are %s.' %
                  (model_type, ', '.join(self._possible_model_types)))
    self._model_types[filename] = model_type

  def get_model_type(self, filename=None):
    if (filename is None):
      filename = self.get_default_model_name()
    return self._model_types.get(filename, self._default_model_type)

  def get_model_names(self, model_type=None):
    all_names = self._get_names(ModelDataManager.datatype)
    names = list()
    if (model_type is None):
      names = all_names
    else:
      for filename in all_names:
        if (model_type == self.get_model_type(filename)):
          names.append(filename)
    return names

  def get_default_model_name(self):
    return self._get_default_name(ModelDataManager.datatype)

  def remove_model(self, filename):
    return self._remove(ModelDataManager.datatype, filename)

  def has_models(self, expected_n=1, exact_count=False, raise_sorry=False):
    return self._has_data(ModelDataManager.datatype, expected_n=expected_n,
                          exact_count=exact_count, raise_sorry=raise_sorry)

  def process_model_file(self, filename, pdb_interpretation_extract=None):
    # unique because any_file does not return a model object
    if (filename not in self.get_model_names()):
      a = any_file(filename)
      if (a.file_type != 'pdb'):
        raise Sorry('%s is not a recognized model file' % filename)
      else:
        model_in = iotbx.pdb.input(a.file_name)
        model = mmtbx.model.manager(
          model_input=model_in,
          pdb_interpretation_params=pdb_interpretation_extract,
          log=self.logger)
        self.add_model(filename, model)

  def process_model_str(self, label, model_str, pdb_interpretation_extract=None):
    model = mmtbx.model.manager(
      model_input=iotbx.pdb.input(source_info=None, lines=model_str),
      pdb_interpretation_params=pdb_interpretation_extract,
      log=self.logger)
    self.add_model(label, model)

  def get_default_output_model_filename(self, extension=Auto):
    '''
    Function for returning the filename with extension. By default ".cif" will
    be used.
    '''
    filename = self.get_default_output_filename()
    if extension is Auto:
      extension = '.cif'
    if not (filename.endswith('.cif') or filename.endswith('.pdb')):
      filename += extension
    return filename

  def write_model_file(self, model_str, filename=Auto, extension=Auto,
                       overwrite=Auto):
    '''
    Function for writing a model to file

    Parameters
    ----------
      model_str: str or mmtbx.model.manager object
        The string to be written or a model object. If a model object is
        provided, the format (PDB or mmCIF) of the original file is kept.
      filename: str or Auto
        The output filename. If set to Auto, a default filename is
        generated based on params.output.prefix, params.output.suffix,
        and params.output.serial
      extension: str or Auto
        The extension to be added. If set to Auto, defaults to .cif
      overwrite: bool or Auto
        Overwrite filename if it exists. If set to Auto, the overwrite
        state of the DataManager is used.

    Returns
    -------
      Nothing
    '''
    if isinstance(model_str, mmtbx.model.manager):
      if model_str.input_format_was_cif():
        extension = '.cif'
        model_str = model_str.model_as_mmcif()
      else:
        extension = '.pdb'
        model_str = model_str.model_as_pdb()
    if filename is Auto:
      filename = self.get_default_output_model_filename(extension=extension)
    elif extension is not Auto:
      filename += extension
    self._write_text(ModelDataManager.datatype, model_str,
                     filename=filename, overwrite=overwrite)

  def update_pdb_interpretation_for_model(
    self, filename, pdb_interpretation_extract):
    '''
    Pass PHIL extract to model class
    model class handles finding and matching of PHIL scopes
    '''
    self.get_model(filename=filename).set_pdb_interpretation_params(
      pdb_interpretation_extract)

# =============================================================================
# end


from django.conf.urls import url
from .views import *
from django.contrib.auth.views import login, logout

urlpatterns = [
    url(r'^$', Index.as_view(), name='index'),
    url(r'^login/$', login, name='login'),
    url(r'^logout/$', logout, name='logout'),
    url(r'^signup/$', UserCreate.as_view(), name='signup'),
    url(r'^groups/$', GroupList.as_view(), name='groups'),
    url(r'^groups/create$', GroupCreate.as_view(), name='group_create'),
    url(r'^groups/(?P<pk>\d+)/$', GroupDetail.as_view(), name='group_detail'),
    url(r'^groups/(?P<pk>\d+)/delete$', GroupDelete.as_view(), name='group_delete'),
    url(r'^groups/(?P<pk>\d+)/edit$', GroupUpdate.as_view(), name='group_update'),
    url(r'^groups/(?P<pk>\d+)/members/$', MemberAdd.as_view(), name='members'),
    url(r'^groups/(?P<pk>\d+)/memos/create$', MemoCreate.as_view(), name='memo_create'),
    url(r'^groups/(?P<pk>\d+)/memos/(?P<memo_id>\d+)/$', MemoDetail.as_view(), name='memo_detail'),
    url(r'^groups/(?P<pk>\d+)/memos/(?P<memo_id>\d+)/delete$', MemoDelete.as_view(), name='memo_delete'),
    url(r'^groups/(?P<pk>\d+)/memos/(?P<memo_id>\d+)/edit$', MemoUpdate.as_view(), name='memo_update'),
    ]
"""
    url(r'^profile/$', Signup.as_view()),
    url(r'^users/(?P<user_id>\d+)/$', Signup.as_view(), name='profile'),

"""


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

#
# Author: Grant Conine
# Date: 2017-09-01
#
# UNC Charlotte MS Math Finance
# MATH 6204 Numerical Methods for Financial Derivatives
# Prof Hwan Lin
#

"""
Created on Sun Sep 17 15:19:12 2017

@author: Grant Conine

UNC Charlotte MS Math Finance
MATH 6204 Numerical Methods for Financial Derivatives
Prof Hwan Lin

This is a set of functions which simulates the motion of a stock process
driven by geometric Brownian motion and graphs the paths taken by these
processes.

This uses Euler discretization to estimate the path of the geometric Brownian
motion.
"""

import numpy as np
import matplotlib.pyplot as plt
import math

def GBM_generate_paths(S0, mu, sigma, T, delta_t, I):
    '''Function to simulate geometric Brownian motion.

    Parameters
    ==========
    S0 = float
        Initial value of stock process
    mu = float
        Drift of stock process
    sigma = float
        Volatility of stock process
    T  = float
        Time horizon
    delta_t = float
        Time step size
    I  = integer
        Number of paths to generate

    Returns
    =======
    x = NumPy array
        simulated paths of stock process
    '''

    M = int(T / delta_t) # number of steps. Must be an integer.
    x = np.zeros((M + 1, I)) # initialize output array
    x[0] = S0
    ran = np.random.standard_normal((M + 1, I)) # prepare random numbers

    for t in xrange(1, M+1):
        W = ran[t] * math.sqrt(delta_t)
        x[t] = x[(t-1)] + mu * x[(t-1)] * delta_t + sigma * x[(t-1)] * W

    return x

def plot_paths(x):
    '''Function to plot paths from GBM_generate_paths() function.'''

    plt.figure(figsize=(27, 15))
    plt.plot(range(len(x)), x[:, :5])
    plt.grid()
    plt.xlabel('time (t)')
    plt.ylabel('S(t)')

np.random.seed(seed = 100)
s = GBM_generate_paths(100, 0.1, 0.2, 1, 0.001, 5)

plot_paths(s)


import sys
sys.stdin = open('input.txt', 'r')
# sys.stdout = open('output.txt', 'w')

n, m, pos = map(int, input().split())

f = [[[0 for i in range(55)] for j in range(55)] for k in range(55)]
c = [[0 for i in range(55)] for j in range(55)]
fact = [0 for i in range(55)]

c[0][0] = 1
fact[0] = 1

for i in range(51):
    c[i][0] = 1
    if (i > 0):
        fact[i] = fact[i - 1] * i
    for j in range(1, 51):
        c[i][j] = c[i - 1][j - 1] + c[i - 1][j]

f[0][0][0] = 1 #f[i][j][k]: i numbers, j useful, k fixed points
for i in range(1, n + 1):
    for j in range(0, i + 1):
        sumAll = fact[i]
        for k in range(1, j + 1):
            f[i][j][k] = f[i - k][j - k][0] * c[j][k]
            sumAll -= f[i][j][k]
            # print(i, j, k, f[i][j][k])
        f[i][j][0] = sumAll

# construct
res = [0 for _ in range(n + 1)]
used = [0 for _ in range(n + 1)]
isUseful = [1 for _ in range(0, n + 1)]
isUseful[0] = 0

if (f[n][n][m] < pos):
    print(-1)
    exit(0)

for i in range(1, n + 1):
    sumSmaller = 0
    lastSum = 0
    for val in range(1, n + 1):
        lastSum = sumSmaller
        if (used[val]):
            continue

        useful = sum(isUseful)

        if (isUseful[i]):
            if (val == i):
                sumSmaller += f[n - i][useful - 1][m - 1]
            elif (isUseful[val]):
                sumSmaller += f[n - i][useful - 2][m]
            else:
                sumSmaller += f[n - i][useful - 1][m]
        else:
            if (isUseful[val] == 1):
                sumSmaller += f[n - i][useful - 1][m]
            else:
                sumSmaller += f[n - i][useful][m]

        if (sumSmaller >= pos):
            pos -= lastSum
            res[i] = val
            isUseful[i] = isUseful[val] = 0
            used[val] = 1
            if (i == val):
                m -= 1

            # print(res[i], pos, sumSmaller, m)
            break

for i in range(1, n + 1):
    print(res[i], end = ' ')


class Twocheckout(dict):
    def __init__(self, dict_):
        super(Twocheckout, self).__init__(dict_)
        for key in self:
            item = self[key]
            if isinstance(item, list):
                for id, it in enumerate(item):
                    if isinstance(it, dict):
                        item[id] = self.__class__(it)
            elif isinstance(item, dict):
                self[key] = self.__class__(item)

    def __getattr__(self, key):
        return self[key]


import numpy as np
from pandas import DataFrame
# from tensorflow.keras.preprocessing.sequence import pad_sequences
import csv
import os

import six #ALI : added to remove tensorflow dependency

class ECGDataIterator:

    def __init__(self, f, subsample=1):
        self.ifd = open(f, "rb")
        self._ss = subsample
        self._offset = 2048

    def __next__(self):
        chIb = self.ifd.read(2)
        if chIb == b'':
            self.ifd.close()
            raise StopIteration
        chI = int.from_bytes(chIb, byteorder="little") - self._offset
        chIII = int.from_bytes(self.ifd.read(2), byteorder="little") - self._offset
        # move pointer 4 bytes times subsampling to next data
        if self._ss > 1:
            self.ifd.seek(4*(self._ss-1), 1)

        return chI, chIII

    def __iter__(self):
        return self

def extract_data(file_list, sample_rate=125, subsample=1, duration=42):
    fs = sample_rate // subsample
    num_samples = duration * fs
    length = len(file_list)
    x = np.empty((length, num_samples, 2))
    # y = np.empty(length) # original code
    y = np.empty((length, 2)) #y is 2 dimensional, to make y ouptut shape as a one_hot vector
    for i, f in enumerate(file_list):
        data = DataFrame(ECGDataIterator(f, subsample)).to_numpy().T
        data = pad_sequences(data, maxlen=num_samples, padding='pre', truncating='pre')
        x[i, :] = data.T
        # y[i] = 0 if 'sinus' in f else 1 #original code

        #ALI:  SINUS_RYTHM one_hot vector with argmax = 0 [1,0] return np.eye(2)[1]  # AF one_hot vector with argmax = 1 [0,1]
        y[i] = np.eye(2)[0] if 'sinus' in f else np.eye(2)[1]
    return x, y

def extract_ecg_file_list(datafolder, csvfile):
    file_list = list()
    with open(os.path.join(datafolder, csvfile)) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        for row in csv_reader:
            file_list.append(os.path.join(datafolder, row[0]))
    return file_list

# copied from tensorflow source code, to remove tensorflow dependency
def pad_sequences(sequences, maxlen=None, dtype='int32',
                  padding='pre', truncating='pre', value=0.):
    if not hasattr(sequences, '__len__'):
        raise ValueError('`sequences` must be iterable.')
    num_samples = len(sequences)

    lengths = []
    sample_shape = ()
    flag = True

    # take the sample shape from the first non empty sequence
    # checking for consistency in the main loop below.

    for x in sequences:
        try:
            lengths.append(len(x))
            if flag and len(x):
                sample_shape = np.asarray(x).shape[1:]
                flag = False
        except TypeError:
            raise ValueError('`sequences` must be a list of iterables. '
                             'Found non-iterable: ' + str(x))

    if maxlen is None:
        maxlen = np.max(lengths)

    is_dtype_str = np.issubdtype(dtype, np.str_) or np.issubdtype(dtype, np.unicode_)
    if isinstance(value, six.string_types) and dtype != object and not is_dtype_str:
        raise ValueError("`dtype` {} is not compatible with `value`'s type: {}\n"
                         "You should set `dtype=object` for variable length strings."
                         .format(dtype, type(value)))

    x = np.full((num_samples, maxlen) + sample_shape, value, dtype=dtype)
    for idx, s in enumerate(sequences):
        if not len(s):
            continue  # empty list/array was found
        if truncating == 'pre':
            trunc = s[-maxlen:]
        elif truncating == 'post':
            trunc = s[:maxlen]
        else:
            raise ValueError('Truncating type "%s" '
                             'not understood' % truncating)

        # check `trunc` has expected shape
        trunc = np.asarray(trunc, dtype=dtype)
        if trunc.shape[1:] != sample_shape:
            raise ValueError('Shape of sample %s of sequence at position %s '
                             'is different from expected shape %s' %
                             (trunc.shape[1:], idx, sample_shape))

        if padding == 'post':
            x[idx, :len(trunc)] = trunc
        elif padding == 'pre':
            x[idx, -len(trunc):] = trunc
        else:
            raise ValueError('Padding type "%s" not understood' % padding)
    return x


import socket, json

########ESTE PROGRAMA RODA A EXECUÇÃO DO DNS SERVER; DEVE SER O PRIMEIRO A SER EXECUTADO
######OBSERVAÇÕES:
###### a variável "serverHost" deve conter o ip da máquina que está rodando o código

serverHost = '172.22.67.194' #cin lua
serverPort1 = 12000

dados = []                                              ###dados salva o domínio e o respectivo endereço do servidor

def addDadosJSON(nome, addr):
        doc = {
                "nome": nome,
                "addr": addr
        }

        dados.append(doc)

##serverCom faz a comunicação DNS/SERVIDOR
def serverCom():
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind((serverHost, serverPort1))

        while True:
                data, addr = sock.recvfrom(1024)
                print(f'Recebendo dados do SERVIDOR: {addr}')
                addDadosJSON(data.decode(), addr[0])
                #print(dados)
                print('Encerrando conexão com SERVIDOR...')
                sock.close()
                break
        return addr

##  clientCom faz a comunicação dns/cliente
def clienteCom():
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind((serverHost, serverPort1))

        while True:
                data, addr = sock.recvfrom(1024)
                print(f'Cliente  {addr[0]} solicitando: {data.decode()}')
                dominio = searchDomain(data.decode())
                #print(dominio)
                sock.sendto(bytes(dominio, "utf-8"), addr)
                if dominio != "Dominio não encontrado":
                        sock.close()
                        print('Encerrando conexão com cliente...')
                        break

## searchDomain procura pelo dominio solicitado pelo cliente
def searchDomain(domain):
        #print(f'aqui eh dominio: {domain}')
        for x in dados:
                if x["nome"] == domain:
                        return x["addr"]
        return "Dominio não encontrado"

##MAIN
def main():
        print('Iniciando execução do DNS...')

        enderServer = serverCom()
        print('---Nova conexão ---')
        clienteCom()
        print('Encerrando DNS...')

if __name__ == "__main__":
    main()


import hashlib as hl

import json

from block import Block
from transaction import Transaction

from utility.verification import Verification
from utility.hash_util import hashBlock
from wallet import Wallet

#gagne 10 coin par block miné
miningReward = 10

class Blockchain:
    def __init__(self, hostingNodeId):
        genesisBlock = Block(0, '', [], 100, 0)
        self.__chain = [genesisBlock]
        self.__openTransactions = []
        self.loadData()
        self.hostingNode = hostingNodeId

    @property
    def getChain(self):
        return self.__chain[:]

    def getOpenTransactions(self):
        return self.__openTransactions[:]

    def loadData(self):
        try:
            with open('blockchain.txt', mode='r') as f:
                fileContent = f.readlines()
                updateBlockchain = []
                blockchain = json.loads(fileContent[0][:-1])
                for block in blockchain:
                    convertTx = [Transaction(tx['sender'], tx['recipient'], tx['signature'], tx['amount']) for tx in block['transactions']]
                    updateBlock = Block(block['index'],block['previousHash'], convertTx, block['proof'], block['timestamp'])

                    updateBlockchain.append(updateBlock)
                    self.__chain = updateBlockchain
                openTransactions = json.loads(fileContent[1])
                updateTransactions = []
                for tx in openTransactions:
                    updateTransaction = Transaction(tx['sender'],tx['recipient'], tx['signature'], tx['amount'])
                    updateTransactions.append(updateTransaction)
                self.__openTransactions = updateTransactions
        except (IOError, IndexError):
            pass

    def saveData(self):
        try:
            with open('blockchain.txt', mode='w') as f:
                saveableChain = [block.__dict__ for block in [Block(nBlock.index,nBlock.previousHash, [tx.__dict__ for tx in nBlock.transactions], nBlock.proof,nBlock.timestamp) for nBlock in self.__chain]]
                f.write(json.dumps(saveableChain))
                f.write('\n')
                saveableTx = [tx.__dict__ for tx in self.__openTransactions]
                f.write(json.dumps(saveableTx))
        except IOError:
            print('saving failed!')

    def proofOfWork(self):
        lastBlock = self.__chain[-1]
        lastHash = hashBlock(lastBlock)
        proof = 0
        while not Verification.vProof(self.__openTransactions, lastHash, proof):
            proof += 1
        return proof

    def getBalance(self):

        if self.hostingNode == None:
            return None
        participant = self.hostingNode
        txSender = [[tx.amount for tx in block.transactions if tx.sender == participant] for block in self.__chain]
        openTxSender = [tx.amount for tx in self.__openTransactions if tx.sender == participant]

        txSender.append(openTxSender)
        amountSent = 0
        for tx in txSender:
            if len(tx) > 0:
                amountSent += sum(tx) #tx[0] prend seulement la premiere valeur du tableau alors on fait sum
            # else:
            #     amountSent + 0
        textRecipient = [[tx.amount for tx in block.transactions if tx.recipient == participant] for block in self.__chain]
        amountReceived = 0
        for tx in textRecipient:
            if len(tx) > 0:
                amountReceived += sum(tx) #tx[0] prend seulement la premiere valeur du tableau alors on fait sum
        return amountReceived - amountSent

    #La fonction qui permet obtenir le dernier block
    def getLastBlochainValue(self):
        if len(self.__chain) < 1:
            return None
        return self.__chain[-1]

    #La fonction qui permet d ajouter une transaction
    def addTransaction(self, recipient, sender, signature,amount=1.0):

        if self.hostingNode == None:
            return False
        #L'objet transaction avec l'envoyeur le montant et le receveur
        transaction = Transaction(sender, recipient, signature, amount)
        # Sil a assez de coin continue
        if Verification.verifyTransaction(transaction, self.getBalance):
            self.__openTransactions.append(transaction)
            self.saveData()
            return True
        return False

    def mineBlock(self):
        if self.hostingNode == None:
            return None

        lastBlock = self.__chain[-1]
        hashedBlock = hashBlock(lastBlock)
        proof = self.proofOfWork()

    #A chaque fois que quelqun mine il gagne 10 (miningReward)
        rewardTransaction = Transaction('MINING', self.hostingNode, '',miningReward)
        copiedTransactions = self.__openTransactions[:]
        for tx in copiedTransactions:
            if not Wallet.vSignatureTransaction(tx):
                return None
        copiedTransactions.append(rewardTransaction)
        block = Block(len(self.__chain), hashedBlock, copiedTransactions, proof)

        self.__chain.append(block)
        self.__openTransactions = []
        self.saveData()
        return block