# ------------------------------------------
# Writtern by Subhashis Suara / QuantumBrute
# ------------------------------------------

from psaw import PushshiftAPI
import praw
import time
import json
import re

# --------------------------------------------------------------------------------

subreddit_name = 'jschlatt' # Mention the subreddit that bot should work on
limitno = 30000 # Set the maximum number of posts to get in the given timeframe
end_epoch=int(time.time()) # Current time
x = int(input("Enter the number of days you want to search for:"))
start_epoch=int(end_epoch - (60*60*24*x)) # Current time - the amount you mention in seconds

#---------------------------------------------------------------------------------

print("Starting Bot...")

reddit = praw.Reddit(client_id= '',
		     client_secret= '',
		     username= '',
		     password= '',
		     user_agent= 'Created by u/QuantumBrute') # Login to reddit API

api = PushshiftAPI() # Variable to use the PushShiftAPI
subreddit = reddit.subreddit(subreddit_name)

print("From: "+ str(start_epoch))
print("Till: "+ str(end_epoch))

result = list(api.search_submissions(after=start_epoch,
                                    before=end_epoch,
                                    subreddit=subreddit_name,
                                    filter=['author', 'id'],
                                    limit=limitno)) # Gets the data with the parameters mentioned from PushShift and makes it into a list

def nominate():
    print("Opening database...")
    with open('UserDatabase.txt', 'r') as infile: # Opens the database
        info = json.load(infile,)

    print("Going through posts & comments for !nominate...")
    print(' ')

    data = []

    for b in range(len(info)): # Copies the database to a list named data to make it easier to modify the elements of the database
        data.append(info[b])

    post_ids = []
    reply_to_nomination = "Nominated for +1 SchlattCoin!" # Reply that bot will post

    for i in range(len(result)):
        post_ids.append(result[i].id) # Gathers the ids of all posts in given time frame

    post_ids_size = len(post_ids)
    template = '2d073f42-677a-11e9-8b58-0e9db0a8f550' # Template ID of custom flair

    for j in range(post_ids_size):
        submission = reddit.submission(post_ids[j])
        submission.comments.replace_more(limit=None)
        author = result[j].author

        for comment in submission.comments.list(): # Goes through comments of post; Note: .list() is used to flatten all hierarchy of comments into a single list
            if comment.author == author or comment.saved: # Checks for post author's comments and other saved comments to avoid re running of commands
                continue
            else:
                keyword = re.search("!nominate", comment.body) # Searches for !nominate in the comment
                if keyword: # Whole process of replying, saving and setting the flairs
                    print(str(comment.author) + " has nominated " + str(author) + "!")
                    print("Awarding SchlattCoin to " + str(author) + "...")
                    comment.save()
                    comment.reply(reply_to_nomination)
                    flag = 0
                    for a in range(len(data)):
                        if author == data[a].get("Name"):
                            print(str(author) + " found in database!")
                            print("Sending reply and setting flair...")
                            print("Updating the changes to database...")
                            print(' ')
                            flag = 1
                            coins = data[a].get("SchlattCoins")
                            coins += 1
                            data[a].update({'SchlattCoins' : coins})
                            flair = next(reddit.subreddit(subreddit_name).flair(author))
                            if flair.get('flair_text') == None:
                                newflair = (str(coins) + " SchlattCoins")
                                subreddit.flair.set(author, newflair)
                            else:
                                flair_split = flair.get('flair_text').split()
                                for c in range(len(flair_split)):
                                    if flair_split[c] == "SchlattCoins" or flair_split[c] == "SchlattCoin":
                                        if flair_split[c] == "SchlattCoin":
                                            flair_split[c] = "SchlattCoins"
                                        c -= 1
                                        flair_split[c] = str(coins)
                                        newflair = ' '.join(flair_split)
                                        if author == "jschlattAlt":
                                            subreddit.flair.set(author, text = newflair, flair_template_id = template)
                                        else:
                                            subreddit.flair.set(author, newflair)
                                        break
                                    else:
                                        newflair = (str(flair.get('flair_text')) + " ( " + str(coins) + " SchlattCoins" + " )")
                                        subreddit.flair.set(author, newflair)
                            break

                    if flag == 0:
                        print(str(author) + " not found in database!")
                        print("Sending reply and setting flair...")
                        print("Adding to database...")
                        print(' ')
                        flair = next(reddit.subreddit(subreddit_name).flair(author))
                        item_to_add = { "Name" : str(author), "SchlattCoins" : 1}
                        data.append(item_to_add)
                        if flair.get('flair_text') == None:
                                newflair = (str(1) + " SchlattCoin")
                                subreddit.flair.set(author, newflair)
                        else:
                            flair_split = flair.get('flair_text').split()
                            for c in range(len(flair_split)):
                                if flair_split[c] == "SchlattCoin":
                                    c -= 1
                                    flair_split[c] = str(1)
                                    newflair = ' '.join(flair_split)
                                    subreddit.flair.set(author, newflair)
                                else:
                                    newflair = (str(flair.get('flair_text')) + " ( " + str(1) + " SchlattCoin" + " )")
                                    subreddit.flair.set(author, newflair)

    with open('UserDatabase.txt', 'w') as outfile: # Overwites the JSON file with updated data
        json.dump(data, outfile, indent=2)
        print("Database updated successfully!")
    print(' ')
    input("Press ENTER to exit...")

def main():
    nominate()

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
from functools import reduce
from operator import mul
def read_input():
    inp = []
    with open('input', 'r') as f:
        for line in f.readlines():
            line = line.strip('\n')
            row = []
            for c in line:
                row.append(c)
            inp.append(row)
    return inp

def count_trees(stepx, stepy):
    treemap = read_input()
    x = 0
    y = 0
    count = 0
    while y < len(treemap):
        if x >= len(treemap[y]):
            x -= len(treemap[y])
        if treemap[y][x] == '#':
            count += 1
        x += stepx
        y += stepy

    return count

def solve1():
    return count_trees(3, 1)

def solve2():
    slopes = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
    counts = [count_trees(*x) for x in slopes]
    return reduce(mul, counts, 1)

if __name__ == "__main__":
    print(solve1())
    print(solve2())


import torch
import torch.nn as nn
from torch.nn import functional as F

import math
from .utils import LinearNorm, FFN
from utils.tools import get_mask_from_lengths

# device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

class BaseAttention(nn.Module):
    def __init__(self, attention_dim):
        super(BaseAttention, self).__init__()
        self.attention_dim = attention_dim

    def forward(self, inputs, memory, memory_lengths, query_lengths):
        """
        :param inputs: query, [batch, q_time, q_dim]
        :param memory: [batch, m_time, m_dim]
        :param memory_lengths: [batch,]
        :param query_lengths: [batch,]
        :return: (tensor1, tensor2)
            tensor1: contexts, [batch, q_time, attention_dim]
            tensor2: alignments, probabilities, [batch, q_time, m_time]
        """
        raise NotImplementedError

    @staticmethod
    def _get_key_mask(batch_size, memory_max_time, query_max_time, memory_lengths, query_lengths, device):
        memory_lengths = (memory_lengths if memory_lengths is not None
                          else torch.ones(batch_size, dtype=torch.int32, device=device) * memory_max_time)
        memeory_mask = get_mask_from_lengths(memory_lengths, memory_max_time)
        memeory_mask = torch.tile(memeory_mask.unsqueeze(1),  # [batch, 1, m_max_time]
                               [1, query_max_time, 1])  # [batch, q_max_time, m_max_time]
        query_lengths = (query_lengths if query_lengths is not None
                         else torch.ones(batch_size, dtype=torch.int32, device=device) * query_max_time)
        query_mask = get_mask_from_lengths(query_lengths, query_max_time)  # [batch, q_max_time]
        query_mask = torch.tile(query_mask.unsqueeze(2),  # [batch, q_max_time, 1]
                             [1, 1, memory_max_time])  # [batch, q_max_time, m_max_time]
        length_mask = torch.logical_and(memeory_mask, query_mask)
        return length_mask

class MultiHeadScaledProductAttention(BaseAttention):
    def __init__(self, attention_dim, input_dim, memory_dim, num_head, temperature=1.0):
        assert attention_dim % num_head == 0
        super(MultiHeadScaledProductAttention, self).__init__(
            attention_dim=attention_dim)
        self.query_layer = LinearNorm(
            input_dim, attention_dim, use_bias=False)
        self.key_layer = LinearNorm(
            memory_dim, attention_dim, use_bias=False)
        self.value_layer = LinearNorm(
            memory_dim, attention_dim, use_bias=False)
        self.num_head = num_head
        self.temperature = temperature

    def _split_head(self, inputs):
        """
        :param inputs: [batch, time, dim]
        :return: [batch, num_head, time, dim // head]
        """
        batch, max_time, dim = inputs.shape
        reshaped = inputs.reshape(batch, max_time, self.num_head,
                               dim // self.num_head)
        # [batch, time, num_head, dim // head]
        transposed = reshaped.permute(0, 2, 1, 3)
        # [batch, num_head, time, dim // head]
        return transposed

    def _merge_head(self, inputs):
        """
        :param inputs: [batch, num_head, time, dim]
        :return: [batch, time, attention_dim]
        """
        batch, _, time, head_dim = inputs.shape
        transposed = inputs.permute(0, 2, 1, 3)
        # [batch, time, num_head, dim]
        reshaped = transposed.reshape(batch, time, self.num_head * head_dim)
        return reshaped

    def _get_key_mask(self, batch_size, memory_max_time, query_max_time,
                      memory_lengths, query_lengths, device):
        memory_lengths = (memory_lengths if memory_lengths is not None
                          else torch.ones(batch_size, dtype=torch.int32, device=device) * memory_max_time)
        memory_mask = get_mask_from_lengths(memory_lengths, memory_max_time)  # [batch, m_max_time]
        memory_mask = torch.tile(memory_mask.unsqueeze(1),  # [batch, 1, m_max_time]
                              [1, query_max_time, 1])  # [batch, q_max_time, m_max_time]
        query_lengths = (query_lengths if query_lengths is not None
                         else torch.ones(batch_size, dtype=torch.int32, device=device) * query_max_time)
        query_mask = get_mask_from_lengths(query_lengths, query_max_time)  # [batch, q_max_time]
        query_mask = torch.tile(query_mask.unsqueeze(2),  # [batch, q_max_time, 1]
                             [1, 1, memory_max_time])  # [batch, q_max_time, m_max_time]
        length_mask = torch.logical_and(memory_mask, query_mask)
        length_mask = torch.tile(length_mask.unsqueeze(1),
                              [1, self.num_head, 1, 1])
        # [batch, num_head, q_max_time, m_max_time]
        return length_mask

    @staticmethod
    def _get_causal_mask(logits):
        causal_mask = torch.tril(torch.ones(logits.shape, dtype=torch.bool, device=logits.device))
        return causal_mask

    def forward(self, inputs, memory, memory_lengths=None, query_lengths=None, causality=None):
        queries = self.query_layer(inputs)  # [batch, Tq, D]
        keys = self.key_layer(memory)  # [batch, Tk, D]
        values = self.value_layer(memory)  # [batch, Tk, Dv]
        headed_queries = self._split_head(queries)  # [batch, num_head, Tq, head_dim]
        headed_keys = self._split_head(keys)  # [batch, num_head, Tk, head_dim]
        headed_values = self._split_head(values)  # [batch, num_head, Tk, head_dim]
        logits = torch.matmul(headed_queries,
                                  headed_keys.transpose(-2, -1))  # [batch, num_head, Tq, Tk]
        logits = logits / math.sqrt(
            float(self.attention_dim // self.num_head))  # scale
        logits = logits / self.temperature  # temperature
        # apply mask
        batch_size = memory.shape[0]
        memory_max_time = memory.shape[1]
        query_max_time = inputs.shape[1]
        length_mask = self._get_key_mask(
            batch_size, memory_max_time, query_max_time, memory_lengths, query_lengths, inputs.device)
        if causality:
            causal_mask = self._get_causal_mask(logits)
            length_mask = torch.logical_and(length_mask, causal_mask)
        # [batch, num_head, q_max_time, m_max_time]
        paddings = torch.ones_like(logits, dtype=torch.float32) * (-2. ** 32 + 1)
        logits = torch.where(length_mask, logits, paddings)
        alignments = torch.softmax(logits, dim=3)  # [batch, num_head, Tq, Tk]
        contexts = torch.matmul(alignments, headed_values)
        # [batch, num_head, Tq, head_dim]
        contexts = self._merge_head(contexts)  # [batch, Tq, attention_dim]
        return contexts, alignments

class SelfAttentionBlock(nn.Module):
    def __init__(self, input_dim, attention_dim, attention_heads, attention_temperature,
                 ffn_hidden):
        super(SelfAttentionBlock, self).__init__()
        self.input_dim = input_dim
        self.attention_dim = attention_dim
        self.attention = MultiHeadScaledProductAttention(attention_dim=attention_dim,
                                                         input_dim=input_dim,
                                                         memory_dim=input_dim,
                                                         num_head=attention_heads,
                                                         temperature=attention_temperature)
        self.att_proj = LinearNorm(attention_dim + input_dim, input_dim)
        self.layer_norm = nn.LayerNorm(input_dim)
        self.ffn = FFN(in_features=input_dim, hidden1=ffn_hidden, hidden2=input_dim)

    def forward(self, inputs, memory, query_lengths, memory_lengths, causality=None):
        att_outs, alignments = self.attention(inputs=inputs, memory=memory,
                                              query_lengths=query_lengths,
                                              memory_lengths=memory_lengths,
                                              causality=causality)
        contexts = torch.cat([inputs, att_outs], dim=-1)
        att_outs = self.att_proj(contexts)
        att_outs = self.layer_norm(inputs + att_outs)
        ffn_outs = self.ffn(att_outs)
        return ffn_outs, alignments

class CrossAttentionBlock(nn.Module):
    def __init__(self, input_dim, memory_dim, attention_dim, attention_heads, attention_temperature,
                 ffn_hidden, name=None):
        super(CrossAttentionBlock, self).__init__()
        self.name = name
        self.input_dim = input_dim
        self.attention_dim = attention_dim
        self.self_attention = MultiHeadScaledProductAttention(
            attention_dim=attention_dim, input_dim=input_dim, memory_dim=input_dim, num_head=attention_heads,
            temperature=attention_temperature)
        self.att_proj1 = LinearNorm(attention_dim + input_dim, input_dim)
        self.layer_norm1 = nn.LayerNorm(input_dim)
        self.cross_attention = MultiHeadScaledProductAttention(
            attention_dim=attention_dim, input_dim=input_dim, memory_dim=memory_dim, num_head=attention_heads,
            temperature=attention_temperature)
        self.att_proj2 = LinearNorm(attention_dim * 2, attention_dim)
        self.layer_norm2 = nn.LayerNorm(attention_dim)
        self.ffn = FFN(in_features=attention_dim, hidden1=ffn_hidden, hidden2=attention_dim)

    def forward(self, inputs, memory, query_lengths, memory_lengths):
        self_att_outs, self_ali = self.self_attention(
            inputs=inputs, memory=inputs, query_lengths=query_lengths,
            memory_lengths=query_lengths, causality=True)
        contexts = torch.cat([inputs, self_att_outs], dim=-1)
        self_att_outs = self.att_proj1(contexts)
        self_att_outs = self.layer_norm1(self_att_outs + inputs)
        att_outs, cross_ali = self.cross_attention(
            inputs=self_att_outs, memory=memory, query_lengths=query_lengths,
            memory_lengths=memory_lengths, causality=False)
        contexts = torch.cat([self_att_outs, att_outs], dim=-1)
        att_outs = self.att_proj2(contexts)
        att_outs = self.layer_norm2(att_outs + self_att_outs)
        ffn_outs = self.ffn(att_outs)
        return ffn_outs, cross_ali


from itertools import combinations as comb, product
from collections import deque

def check_one(polje, i, j):
    q = deque([(i,j)])
    while len(q) > 0:
        ci,cj = q.popleft()
        if polje[ci][cj] == '.': continue
        for di in [-1,0,1]:
            for dj in [-1,0,1]:
                if di == dj == 0: continue
                if 0 <= ci+di < len(polje) and 0 <= cj+dj < len(polje[0]) and \
                            str(polje[ci+di][cj+dj]) not in '.*' and polje[ci][cj] == 0:
                    q.append((ci+di, cj+dj))
        polje[ci][cj] = '.'
    return all(set(i) <= set(".*") for i in polje)

def count(polje, i, j):
    if polje[i][j] == '*':return'*'
    c = 0
    for di in [-1,0,1]:
        for dj in [-1,0,1]:
            if di == dj == 0: continue
            c += 0 <= i+di < len(polje) and 0 <= j+dj < len(polje[0]) and polje[i+di][j+dj] == '*'
    return c

def small(h,w,m):

    for c in comb(product(range(h),range(w)),m):
        polje = [['.' for i in range(w)] for j in range(h)]
        for i,j in c:
            polje[i][j] = '*'

        for i in range(h):
            for j in range(w):
                polje[i][j] = count(polje,i,j)

        first = True
        for i in range(h):
            for j in range(w):
                if polje[i][j] == 0 and first:
                    if check_one(polje, i, j):
                        polje[i][j] = 'c'
                        return polje
                    first = False

        if m == h*w-1:
            for i in range(h):
                for j in range(w):
                    if polje[i][j] != '*':
                        polje[i][j] = 'c'
            return polje

for tt in range(int(input())):
    h,w,m = map(int, input().split())
#      print (h,w,m)
    print ("Case #{}:".format(tt+1))
    polje = small(h,w,m)
#      print(polje)
    if polje is not None:
        print('\n'.join(''.join(i) for i in polje))
    else:
        print("Impossible")


#Script creado por:
#Alberto Villar Bautista

from concurrent.futures import thread
from time import sleep
from typing import List
from wakeonlan import send_magic_packet
from ping3 import ping
import os
import subprocess
import datetime

class pc:
    def __init__(self, ip, mac):
        self.ip = ip
        self.mac = mac

class pcversions:
    def __init__(self, hostname, v1,v2):
        self.hostname = hostname
        self.v1 = v1
        self.v2 = v2

ordenadores = [];
versiones =[];

archivo = open(r"C:\Users\Administrator\Desktop\Script Fusion\aula3.txt");
lineas = archivo.readlines();
archivo.close();

for i in lineas:
    info = i.split(';');
    info[1] = info[1].strip('\n');
    ordenadores.append(pc(info[0], info[1]));

#codigo para ver si coge bien el archivo
for pc in ordenadores:
    print(pc.ip + " - Paquete enviado.");
    send_magic_packet(pc.mac);

rsp = False

sleep(120)

ping(ordenadores[0].ip)

if ping:
  print("PCs Encendidos");

hostnames = [];
for pc in ordenadores:
    if pc.ip == "10.20.3.1":
        hostnames.append("A310")
        versiones.append(pcversions("A310","1","1"))

    else:
        hostnames.append("A3" + pc.ip[-2:])
        versiones.append(pcversions("A3" + pc.ip[-2:],"1","1"))

print(hostnames)

for pc in versiones:
    v1 = subprocess.check_output('winrs -r:'+ pc.hostname + r'-u:FUNDACIOCIM\Administrador -p:procan0 type C:\Program Files\Autodesk\webdeploy\production\5504d85ae982f0b7c130e43cd174ede20d73f523\fusion_version.txt')
    v1 = str(v1)
    v1 = v1[2:len(v1)-1]

    pc.v1 = v1

for pc in hostnames:
    print("Actualizando: " + pc)
    os.system('winrs -r:' + pc + r' -u:EDU\administrator -p:procana choco upgrade autodesk-fusion360 --ignore-checksums -y')

for pc in versiones:
    v2 = subprocess.check_output('winrs -r:' + pc.hostname + r'-u:FUNDACIOCIM\Administrador -p:procan0 type C:\Program Files\Autodesk\webdeploy\production\5504d85ae982f0b7c130e43cd174ede20d73f523\fusion_version.txt')
    v2 = str(v2)
    v2 = v2[2:len(v2)-1]

    pc.v2 = v2

today = datetime.datetime.now()

today = "%s/%s/%s : %s:%s" %(today.day, today.month, today.year, today.hour, today.minute)

logs = open(today + "-logs.txt","w+")

for pc in versiones:
    linea = pc.hostname + "Version antes de actualizar: " + pc.v1 + " | Version despues de actualizar: " + pc.v2
    logs.write(linea + "\n")

for pc in hostnames:
    os.system('winrs -r:' + pc + r' -u:EDU\administrator -p:procana shutdown -s')


import torch

from pathlib import Path
from typing import Union

from .model import load_pretrained_model
from .tokenizer import SMILESTokenizer

class Fingerprinter:
    def __init__(
        self,
        weights_path: Path = "model/encoder-weights.ckpt",
        tokenizer_path: Path = "model/smiles-tokenizer.json",
        n_samples: int = 32
        ):

        self.tokenizer = SMILESTokenizer(tokenizer_path)
        self.model = load_pretrained_model(weights_path)
        self.n_samples = n_samples

    def __call__(self, smiles_string: str) -> Union[None, torch.tensor]:
        tokens = self.tokenizer.tokenize(smiles_string, n_samples=self.n_samples)

        if tokens is None:
            return None

        with torch.no_grad():
            fingerprints = self.model(tokens)

        fingerprints = fingerprints.mean(axis=0)
        return fingerprints


from django.db import models
import uuid

class AutoMetadataMixin(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    modified_at = models.DateTimeField(auto_now=True, null=True, blank=True)

    class Meta:
        abstract = True

class BaseOrder(AutoMetadataMixin):
    order_id = models.UUIDField(primary_key=True, verbose_name='order_id', default=uuid.uuid4)
    # order_id = models.CharField(primary_key=True, max_length=255, verbose_name='order_id')
    name = models.CharField(max_length=255, verbose_name='name')
    customer_id = models.CharField(max_length=255, verbose_name='customer-id')

    class Meta:
        abstract = True

    def __str__(self):
        return self.name


import matplotlib.pyplot as plt, pytz,os, glob
from dateutil.parser import parse
import numpy as np, pickle, datetime
import pymc3 as pm
import pandas as pd
import theano

# plt.ion()

os.chdir(r"\\vmware-host\Shared Folders\Shared Folders\Desktop\ArXivSpider_data")

# loading the data
obj=[]
for i in glob.glob('ArXiv_*.pkl'):
    with open(i, 'rb') as f:
        obj.append(pickle.load(f))

def time_diff(t):
#This function defines the time difference between submission time and cutoff time

    if t>datetime.datetime(2017,1,1): h=14
    else: h=16

    if (t.isoweekday() == 1 and t.hour < h):  # Monday before 16
        t_cutoff=datetime.datetime(t.year, t.month, t.day, h)-datetime.timedelta(3)
    elif 1 <= t.isoweekday() <= 5 and t.hour >= h:  # Monday to Friday after 16.00
        t_cutoff = datetime.datetime(t.year, t.month, t.day, h)
    elif 1 < t.isoweekday() <= 5 and t.hour < h:  # Tuesday to Friday, before 16.00
        t_cutoff = datetime.datetime(t.year, t.month, t.day, h) - datetime.timedelta(1)
    elif 5 < t.isoweekday():  # Saturday and Sunday
        t_cutoff=datetime.datetime(t.year, t.month, t.day, h)-datetime.timedelta(t.isoweekday()-5)

    return (t-t_cutoff).total_seconds(),t_cutoff.toordinal() # time difference between submission time and cutoff time and proleptic Gregorian ordinal of the date

#fetching citation and submission day
dt=[];cit=[]; to=[]
for feed in obj:
    for entry in feed.entries:
        t=parse(entry['published']).astimezone(pytz.timezone("US/Eastern")).replace(tzinfo=None)
        _t,_to=time_diff(t)
        dt.append(_t)
        to.append(_to)
        cit.append(entry['ADS']['Citations'])
dt=np.array(dt); cit=np.array(cit); to=np.array(to)
ii,=np.where(cit >=0); cit=cit[ii]; dt=dt[ii]; to=to[ii]; ii_cp=ii

n, bins, patches = plt.hist(dt, 200, facecolor='green',alpha=0.75) #makeing an histogram
plt.xlabel('Time from submission cutoff (seconds)')
plt.ylabel('Number of submissions')
plt.ylim(.1,1500)

idt=np.zeros_like(dt,dtype=int); grp=np.zeros_like(dt,dtype=int); idt_inv=np.zeros_like(dt,dtype=int)
ll=np.zeros(len(np.unique(to)),dtype=int); cit_av=np.zeros_like(ll,dtype=int)
for j,i in enumerate(sorted(np.unique(to),reverse=True)): #grouping citation per day
    ii,=np.where(to == i)
    idt[ii]=dt[ii].argsort() #submission rank, that is 1 i the submission nearest to the cutoff time, and so on
    idt_inv[ii]=idt[ii][::-1] #inverse submission rank
    ll[j]=len(ii); cit_av[j]=np.mean(cit[ii[idt[ii]][:10]])
    grp[ii] = j #group of citations submitted the same calendar day

# plt.cla()

## Kernel density estimation via Guassian kernel
ii,=np.where((idt<=5) & (cit<150)  & (cit>=2)); ii2,=np.where((idt>=10) & (idt<=20) & (cit<150)  & (cit>=2)); ii3,=np.where((idt_inv<=9) & (cit<150) & (cit>=2));
from scipy.stats.kde import gaussian_kde
x = np.linspace(0,150,20)
plt.clf()
plt.yscale('log')
lab=['1-5','5-10','last 5']
kde=gaussian_kde(cit[ii]); kde.set_bandwidth(bw_method=kde.factor *1.5 )
plt.plot(x,kde(x),label=lab[0])
kde=gaussian_kde(cit[ii2]); kde.set_bandwidth(bw_method=kde.factor *1.5 )
plt.plot(x,kde(x),label=lab[1])
kde=gaussian_kde(cit[ii3]); kde.set_bandwidth(bw_method=kde.factor *1.5 )
plt.plot(x,kde(x),label=lab[2])
plt.legend()
plt.xlabel('Submission rank')
plt.ylabel('Kernel density estimation')

#### relation between citations and submission time via hyrarchical Bayesian model

data=pd.DataFrame(np.c_[grp,grp],columns=['citations','citations_code'])
data['rank']=np.log10(idt+1)
data['log_citations']=np.log10(cit+1)
data.sort_values(by=['citations_code', 'rank'],inplace=True)
data.index=sorted(data.index)

data['log_citations'] = data['log_citations'].astype(theano.config.floatX)
citations_names = data.citations.unique()
citations_idx = data.citations_code.values

n_citations = len(data.citations.unique())

data[['citations', 'log_citations', 'rank']].head()

with pm.Model() as unpooled_model:

    # Independent parameters for each citations
    a = pm.Normal('a', 0, sd=100, shape=n_citations)
    b = pm.Normal('b', 0, sd=100, shape=n_citations)

    # Model error
    eps = pm.HalfCauchy('eps', 5)
    citations_est = a[citations_idx] + b[citations_idx]*data["rank"].values

    # Data likelihood
    y = pm.Normal('y', citations_est, sd=eps, observed=data.log_citations)

with unpooled_model:
    unpooled_trace = pm.sample(1000)

with pm.Model() as hierarchical_model:
    # Hyperpriors for group nodes
    mu_a = pm.Normal('mu_a', mu=0., sd=100**2)
    sigma_a = pm.HalfCauchy('sigma_a', 5)
    mu_b = pm.Normal('mu_b', mu=0., sd=100**2)
    sigma_b = pm.HalfCauchy('sigma_b', 5)

    a = pm.StudentT('a', mu=mu_a, lam=sigma_a, nu=1,shape=n_citations) #intercept
    b = pm.StudentT('b', mu=mu_b, lam=sigma_b,nu=1, shape=n_citations) #slope

    # Model error
    eps = pm.HalfCauchy('eps', 5)

    citations_est = a[citations_idx] + b[citations_idx] * data["floor"].values

    # Data likelihood
    citations_like = pm.Normal('citations_like', mu=citations_est, sd=eps, observed=data.log_citations)

# Inference
with hierarchical_model:
    hierarchical_trace = pm.sample(draws=2000, n_init=1000)

pm.traceplot(hierarchical_trace);

selection = [4, 7,12,19]
fig, axis = plt.subplots(2,2, figsize=(12, 6), sharey=True, sharex=True)
axis = axis.ravel()
for i, c in enumerate(selection):
    c_data = data.ix[data.citations == c]
    c_data = c_data.reset_index(drop = True)
    c_index = np.where(citations_names==c)[0][0]
    z = list(c_data['citations_code'])[0]

    xvals = np.linspace(0, 2.5)
    for a_val, b_val in zip(unpooled_trace['a'][1000:, c_index], unpooled_trace['b'][1000:, c_index]):
        axis[i].plot(xvals, a_val + b_val * xvals, 'b', alpha=.1)
    axis[i].plot(xvals, unpooled_trace['a'][1000:, c_index].mean() + unpooled_trace['b'][1000:, c_index].mean() * xvals,
                 'b', alpha=1, lw=2., label='individual')
    for a_val, b_val in zip(hierarchical_trace['a'][1000:][z], hierarchical_trace['b'][1000:][z]):
        axis[i].plot(xvals, a_val + b_val * xvals, 'g', alpha=.1)
    axis[i].plot(xvals, hierarchical_trace['a'][1000:][z].mean() + hierarchical_trace['b'][1000:][z].mean() * xvals,
                 'g', alpha=1, lw=2., label='hierarchical')
    axis[i].scatter(c_data.floor, c_data.log_citations,
                    alpha=1, color='k', marker='.', s=80, label='original data')
    axis[i].set_title(c)

hier_a = hierarchical_trace['a'][500:].mean(axis=0)
hier_b = hierarchical_trace['b'][500:].mean(axis=0)
indv_a = [unpooled_trace['a'][500:, np.where(citations_names==c)[0][0]].mean() for c in citations_names]
indv_b = [unpooled_trace['b'][500:, np.where(citations_names==c)[0][0]].mean() for c in citations_names]

fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111, xlabel='Intercept', ylabel='Floor Measure',
                     title='Hierarchical vs. Non-hierarchical Bayes',
                     xlim=(.5, 2.5), ylim=(-1.3, 1.3))

ax.scatter(indv_a, indv_b, s=26, alpha=0.4, label = 'non-hierarchical')
ax.scatter(hier_a,hier_b, c='red', s=26, alpha=0.4, label = 'hierarchical')
for i in range(len(indv_b)):
    ax.arrow(indv_a[i], indv_b[i], hier_a[i] - indv_a[i], hier_b[i] - indv_b[i],
             fc="k", ec="k", length_includes_head=True, alpha=0.4, head_width=.04)
ax.legend();

ll=np.array([sum(grp ==i) for i in np.unique(grp)])
plt.plot(ll,hier_b,'k.')

weekday=np.array([datetime.datetime.fromordinal(i).isoweekday() for i in np.unique(to)])

months=np.array([datetime.datetime.fromordinal(i).month for i in np.unique(to)])
cit_hier_month=np.array([(hier_a[np.where(months ==i)[0]]+hier_b[np.where(months ==i)[0]]*np.log10(5+1)).mean()  for i in np.unique(months)])
weekdays=np.array([datetime.datetime.fromordinal(i).isoweekday() for i in to])
# cit_week=[np.mean(cit[np.where((weekdays ==i) & (cit>=0) & (cit<=60))[0]]) for i in range(1,6)]
# plt.plot(range(1,6),cit_week,'k.')

slope=np.array([np.mean(hier_b[np.where(weekday ==i)[0]]) for i in range(1,6)])
norm=np.array([np.mean(hier_a[np.where(weekday ==i)[0]]) for i in range(1,6)])
cit_hier=np.array([(hier_a[np.where(weekday ==i)[0]]+hier_b[np.where(weekday ==i)[0]]*np.log10(5+1)).mean()  for i in range(1,6)])
plt.plot(range(1,6),cit_hier,'k.')
plt.plot(range(1,6),slope,'k.')
plt.plot(range(1,6),norm,'k.')

slope=np.array([np.mean(hier_b[np.where(months ==i)[0]]) for i in range(1,13)])
norm=np.array([np.mean(hier_a[np.where(months ==i)[0]]) for i in range(1,13)])
cit_hier=np.array([(hier_a[np.where(months ==i)[0]]+hier_b[np.where(months ==i)[0]]*np.log10(5+1)).mean()  for i in range(1,13)])
plt.plot(range(1,13),cit_hier,'k.')

import pymc3 as pm
import theano
# ii=idt.argsort()
# ii,=np.where((grp==10) & (cit>=1) & (cit<=60))
x=np.log10(idt+1); y=np.log10(cit+1); x=x/max(x)
# ii,=np.where((cit>=2) & (cit<=60)); x=x[ii]; y=y[ii]
data = dict(x=x, y=y)
# data=data.ix[:20]
# data = dict(x=data['rank'].values,y=data['log_citations'].values)

with pm.Model() as model:
    pm.glm.glm('y ~ x', data)
    start = pm.find_MAP()
    step = pm.NUTS(scaling=start)
    trace = pm.sample(100, step, progressbar=True)

from theano.scan_module.scan_perform_ext import *

plt.subplot(111, xlabel='x', ylabel='y',
            title='Posterior predictive regression lines')
plt.plot(x,y, 'x', label='data')
pm.glm.plot_posterior_predictive(trace, samples=100,
                                 label='posterior predictive regression lines')

plt.legend(loc=0);

plt.hist(trace['x'])
plt.hist(trace['x'][30:])
trace['x'][30:].mean()

with pm.Model() as model_robust:
    family = pm.glm.families.StudentT()
    pm.glm.glm('y ~ x', data, family=family)
    start = pm.find_MAP()
    step = pm.NUTS(scaling=start)
    trace_robust = pm.sample(200, step, progressbar=False)

plt.figure(figsize=(5, 5))
plt.plot(x,y, 'x', label='data')
pm.glm.plot_posterior_predictive(trace_robust,
                                 label='posterior predictive regression lines')
plt.legend();

plt.hist(trace_robust['x'])
plt.hist(trace_robust['x'][30:])
trace_robust['x'][60:].mean()

#### relation between citations and submission time via hyrarchical Bayesian model

##  NLP of scientific papers

titles=[];abstracts=[]
for feed in obj:
    for entry in feed.entries:
        titles.append(entry['title'])
        abstracts.append(entry['summary'])
ii=ii_cp
abstracts=np.array(abstracts)

from sklearn.feature_extraction.text import TfidfVectorizer
import spacy
en_nlp = spacy.load('en')  # load spacy's English language models

# create a custom tokenizer using the SpaCy document processing pipeline, but with custom tokenizer
def custom_tokenizer(document):
    doc_spacy = en_nlp(document,entity=False, parse=False)
    return [token.lemma_ for token in doc_spacy]

import string
#text_train defines a list of abstracts
text_train=np.array([
    ' '.join([word for word in entry['summary'].split() if not any(x in word for x in ['$', '\\','\n','-','+']) and word.isalpha()]) #parsing the abstract
        .encode("ascii", "ignore") #removing non-ascii characters
        .lower().translate(None, string.punctuation)  #strip punctuation from a string in Python
    for feed in obj for entry in feed.entries])  # loop in entries and feeds
[ii] #ii,=np.where(cit >=0)

#title_train defines a list of titles
title_train=np.array([' '.join([word for word in entry['title'].split() if not any(x in word for x in ['$', '\\','\n','-','+']) and word.isalpha()]).encode("ascii", "ignore").lower().translate(None, string.punctuation) for feed in obj for entry in feed.entries])[ii]

vectorizer = TfidfVectorizer(stop_words="english", ngram_range=(1, 1), token_pattern=r'\b\w+\b', smooth_idf=False, tokenizer=custom_tokenizer).fit(text_train)  #tf_idf vectorizer with the custom tokenizer
X_train = vectorizer.fit_transform(text_train) #tf_idf matrix
feature_names = vectorizer.get_feature_names() #feature names
vectorizer2 = TfidfVectorizer(stop_words="english", ngram_range=(2, 2), token_pattern=r'\b\w+\b', smooth_idf=False, tokenizer=custom_tokenizer).fit(text_train)  #tf_idf vectorizer with the custom tokenizer
X_train2 = vectorizer2.fit_transform(text_train)
feature_names2 = vectorizer2.get_feature_names()

y_train=np.log(cit[:5000]+1)

from sklearn.linear_model import Lasso
from sklearn.model_selection import GridSearchCV
param_grid = {'alpha': [1e-5,5e-5,1e-4,5e-4,1e-3]}
grid = GridSearchCV(Lasso(), param_grid, cv=5)
grid.fit(X_train, y_train)
print("Best cross-validation score: {:.2f}".format(grid.best_score_))
print("Best parameters: ", grid.best_params_)
feature_names = vectorizer.get_feature_names()
print("First 50 features:\n{}".format(feature_names[:50]))

from sklearn.feature_selection import SelectFromModel
select = SelectFromModel(Lasso(alpha=1e-3),threshold=0.05).fit(X_train, y_train)
mo=Lasso(alpha=1e-4).fit(X_train, y_train); mo.score(X_train, y_train)
X_train_l1 = select.transform(X_train)
mask = select.get_support()
X_test_l1 = select.transform(X_train)
score = Lasso(alpha=1e-4).fit(X_train_l1, y_train).score(X_train_l1, y_train)
mo=Lasso(alpha=1e-4).fit(X_train_l1, y_train)
mo.coef_

max_value = X_train.max(axis=0).toarray().ravel()
sorted_by_tfidf = max_value.argsort()
# get feature names
feature_names = np.array(vectorizer.get_feature_names())
print("Features with highest tfidf: \n{}".format(feature_names[sorted_by_tfidf[-100:]]))

from sklearn.feature_selection import SelectPercentile
select = SelectPercentile(percentile=20)
select.fit(X_train, y_train)
# transform training set
X_train_selected = select.transform(X_train)
# select2=SelectPercentile(percentile=20)
# X_train_selected2 = select2.fit(X_train2,y_train).transform(X_train2)
print("X_train.shape: {}".format(X_train.shape))
print("X_train_selected.shape: {}".format(X_train_selected.shape))

mask = select.get_support()
print(mask)
# visualize the mask -- black is True, white is False
plt.matshow(mask.reshape(1, -1), cmap='gray_r')
plt.xlabel("Sample index")

aa=np.where(X_train_selected.sum(0) >50)[1]
feat=np.array(feature_names)[mask][aa]
import nltk
pos_tagged_tokens = [nltk.pos_tag([t]) for t in feat]
pos_tagged_tokens = [token for sent in pos_tagged_tokens for token in sent]

current_entity_chunk=[]
for (token, pos) in pos_tagged_tokens:
        if pos.startswith('JJ'):
            current_entity_chunk.append(token)

np.array(feature_names)[mask][np.where(X_train_selected.sum(0) >50)[1]]
# np.array(feature_names2)[select2.get_support()][np.where(X_train_selected2.sum(0) >50)[1]]

ii2=(X_train[:,feature_names == 'issue'] >0).toarray().flatten() + (X_train[:,feature_names == 'disagreement'] >0).toarray().flatten()+ (X_train[:,feature_names == 'tension'] >0).toarray().flatten() + (X_train[:,feature_names == 'contrast'] >0).toarray().flatten() #+ (X_train[:,feature_names == 'disprove'] >0).toarray().flatten()
_=plt.hist(cit[ii2], 30, facecolor='red',alpha=0.75,normed=1)
ii2=(X_train[:,feature_names == 'agreement'] >0).toarray().flatten() + (X_train[:,feature_names == 'confirm'] >0).toarray().flatten() +(X_train[:,feature_names == 'validate'] >0).toarray().flatten()
_=plt.hist(cit[ii2], 30, facecolor='yellow',alpha=0.75,normed=1)
plt.yscale('log');plt.xscale('log')

from scipy.stats.kde import gaussian_kde
x = np.linspace(0,200,20)
plt.clf()
plt.yscale('log');plt.xscale('log')
feature_names=np.array(feature_names)
linestyles = ['-','-','-','-','--', '--','--',':',':']
for k,i in enumerate(['unprecedented','exceptionally','significantly','strongly','speculate','suggest','indicate','contrast','agreement']):
    plt.plot(x,gaussian_kde(cit[(X_train[:,feature_names == i] >0).toarray().flatten()])(x),linestyles[k],label=i)
# for i in ['good agreement']:
#     plt.plot(x, gaussian_kde(cit[(X_train2[:, feature_names2 == i] > 0).toarray().flatten()])(x), label=i)
plt.ylim([1e-5,0.08])
plt.legend(loc="best")
plt.xlabel('Citation'); plt.ylabel('KDE')

feature_names2=np.array(feature_names2)
for i in ['good agreement','previous work','provide good','result indicate','strongly indicate','strong indication', '-PRON- demonstrate','-PRON- prove']:
    plt.plot(x,gaussian_kde(cit[(X_train2[:,feature_names2 == i] >0).toarray().flatten()
                            ])(x),label=i)
plt.ylim([1e-4,3e-2])
plt.legend(loc="best")
plt.yscale('log');plt.xscale('log')

x = np.linspace(0,800,60)
ii2=(X_train[:,feature_names == 'issue'] >0).toarray().flatten() + (X_train[:,feature_names == 'disagreement'] >0).toarray().flatten()+ (X_train[:,feature_names == 'tension'] >0).toarray().flatten() + (X_train[:,feature_names == 'contrast'] >0).toarray().flatten() + (X_train[:,feature_names == 'disprove'] >0).toarray().flatten()
kde=gaussian_kde(cit[ii2]); kde.set_bandwidth(bw_method=kde.factor *5 )
plt.plot(x,kde(x),label=':)')
ii2=(X_train[:,feature_names == 'agree'] >0).toarray().flatten() + (X_train[:,feature_names == 'confirm'] >0).toarray().flatten() +(X_train[:,feature_names == 'validate'] >0).toarray().flatten()
kde=gaussian_kde(cit[ii2]); kde.set_bandwidth(bw_method=kde.factor * 10)
plt.plot(x,kde(x),label=':(')
plt.yscale('log');plt.xscale('log')
plt.ylim([1e-6,0.05]); plt.xlim(10,800)
plt.legend(loc="best")

#Analysis of citation index

publ=[];tdiff=[]
for feed in obj:
    for entry in feed.entries:
        comment=entry['arxiv_comment'].lower() if entry.has_key('arxiv_comment') else ''
        if comment:
            if any(x in comment for x in ['accept', 'press', 'publish']):
                if 'v1' in entry['id']:
                    _publ = 2 ; _tdiff=0
                else:
                    _publ=1
                    _tdiff= (parse(entry['updated'])-parse(entry['published'])).total_seconds()/(24*3600.*30)
        else:
            _publ=-1; _tdiff=-1

        publ.append(_publ)
        tdiff.append(_tdiff)

ii=ii_cp;publ=np.array(publ)[ii]
plt.xscale('log');plt.yscale('log')
kde=gaussian_kde(cit[np.where(publ==2)[0]]); kde.set_bandwidth(bw_method=kde.factor *3 )
plt.plot(x,kde(x),label='In press at v1')
kde=gaussian_kde(cit[np.where(publ==1)[0]]); kde.set_bandwidth(bw_method=kde.factor *3 )
plt.plot(x,kde(x),label='Submitted at v1')
plt.legend(loc="best")
plt.ylabel('KDE'); plt.xlabel('Citations')

# number of authors vs. citaton
num_authors=[]
for feed in obj:
    for entry in feed.entries:
        num_authors.append(len(entry['authors']) if entry.has_key('authors') else 0)
ii=ii_cp
num_authors=np.array(num_authors)[ii]
plt.plot(num_authors,cit,'k.')
plt.yscale('log')

#self promoted SF vs. visibility bias VB
x = np.linspace(0,200,20)
kde=gaussian_kde(cit[np.where((idt<=8)  & (cit>=1) & (cit<=400) & (dt<600))]); kde.set_bandwidth(bw_method=kde.factor *3 )
plt.plot(x,kde(x),label='SP')
kde=gaussian_kde(cit[np.where((idt<=8)  & (cit>=1) & (cit<=400) & (dt>=600))]); kde.set_bandwidth(bw_method=kde.factor *3 )
plt.plot(x,kde(x),label='VB')
kde=gaussian_kde(cit[np.where((idt>=20)  & (cit<=400) & (cit>=1))]); kde.set_bandwidth(bw_method=kde.factor *3 )
plt.plot(x,kde(x),label='others')
plt.yscale('log');plt.xscale('log')
plt.legend(loc="best")

import re
journals=[]
for feed in obj:
    for entry in feed.entries:
        _journal=re.findall(r'([a-zA-Z&]{2,})',entry['ADS']['Bibliographic Code'])[0] \
            if entry['ADS']['Bibliographic Code'] and type(entry['ADS']['Bibliographic Code'])!=list else ''
        if _journal =='ApJ' and re.findall(r'(ApJ\S{4,}L)',entry['ADS']['Bibliographic Code']): _journal='ApJL'
        journals.append(_journal)
ii=ii_cp
journals=np.array(journals)[ii]

imp_factor=[4.952,5.909,5.487,11.257,5.185,38.138,34.661]  #refer to 2015
for k,i in enumerate(['MNRAS','ApJ','ApJL','ApJS','A&A','Natur','Sci']):
    kde = gaussian_kde(cit[(journals == i) & (cit>=20)])
    width=1 if i in ['Natur','Sci'] else 1.8
    if i in ['ApJ', 'ApJL','MNRAS']: width = 4
    kde.set_bandwidth(bw_method=kde.factor * width)
    plt.plot(x,kde(x),label=i+' '+str(imp_factor[k]))
# plt.ylim([1e-5,6e-2])
plt.legend(loc="best")
plt.yscale('log');plt.xscale('log')

import urllib2
html = urllib2.urlopen('http://adsabs.harvard.edu/abs_doc/refereed.html').read()  # ADS Bibliographic Codes: Refereed Publications
biblio_code=[i.strip() for i in re.findall('onClick=.*>(.*)<',html)]; biblio_code.append('ApJL')
journals=[re.sub(r'[\d.]+','',''.join(\
    re.findall(r'([a-zA-Z&]{2,})|\d+(ApJ[.\d]+L)',entry['ADS']['Bibliographic Code'])[0])) \
              if entry['ADS']['Bibliographic Code'] and type(entry['ADS']['Bibliographic Code'])!=list \
              else '' \
          for feed in obj for entry in feed.entries]
biblio_code=tuple(set(journals).intersection(biblio_code))

# Impact_factor
# https://en.wikipedia.org/wiki/Impact_factor#cite_note-IFintro-1
import pandas as pd, re
df0= pd.DataFrame(index=np.arange(1980,2019),columns=np.unique(journals)) #the total number of articles published in a journal in a specific month
df= df0.copy() # the number of citations received in a specific month by articles published in a journal
# _t_pub0=datetime.datetime(2013,1,1)
for feed in obj:
    for entry in feed.entries:
        # if entry['ADS']['Citations'] <100: continue
        _journal=re.findall(r'([a-zA-Z&]{2,})',entry['ADS']['Bibliographic Code'])[0] \
            if entry['ADS']['Bibliographic Code'] and type(entry['ADS']['Bibliographic Code'])!=list else ''
        if _journal == 'ApJ' and re.findall(r'(ApJ\S{4,}L)', entry['ADS']['Bibliographic Code']): _journal = 'ApJL'
        try:
            # _t_pub0=datetime.datetime.strptime(entry['ADS']['Publication Date'].replace('00/','01/'), '%m/%Y').year
            _t_pub0=int(entry['ADS']['Publication Date'].split('/')[1])
        except:
            continue
        df0[_journal].ix[_t_pub0+1:_t_pub0 + 2] = df0[_journal].ix[_t_pub0+1:_t_pub0 + 2].fillna(0) + 1

        for _t in entry['ADS']['Citations list']:
            __journal= re.findall(r'([a-zA-Z&]{2,})', _t[0])[0] \
            if entry['ADS']['Bibliographic Code'] else ''
            if __journal == 'ApJ' and re.findall(r'(ApJ\S{4,}L)', entry['ADS']['Bibliographic Code']): __journal = 'ApJL'
            try:
                # _t_pub=datetime.datetime.strptime(_t[2].replace('00/','01/'), '%m/%Y').year
                _t_pub = int(_t[2].split('/')[1])
            except:
                continue
            if __journal in biblio_code:
                if _t_pub-_t_pub0==0:
                    df[_journal].ix[_t_pub0+1:_t_pub0+2]=df[_journal].ix[_t_pub0+1:_t_pub0+2].fillna(0) + 1
                elif _t_pub-_t_pub0==1:
                    df[_journal].ix[_t_pub0 + 2] = df[_journal].ix[_t_pub0 + 2]+ 1 if pd.notnull(df[_journal].ix[_t_pub0+2]) else 1

df_cp=df.copy();df0_cp=df0.copy()
df0=df0.loc[df.notnull().any(axis=1)]
df=df.loc[df.notnull().any(axis=1)]
# df0.loc['2001-01-01':'2016-12-31',:] = df0.loc[_t_pub0].values/(48.)

i=['MNRAS','ApJ','ApJL','ApJS','A&A','Natur','Sci']
pd.DataFrame(df[i]/df0[i]).plot()

pd.DataFrame(df[i].rolling(window=24,min_periods=12).sum()/df0[i].rolling(window=24,min_periods=12).sum().values,index=df0.index.shift(0)).plot()

pd.DataFrame((df[i].rolling(window=24,min_periods=12).sum()/df0[i].rolling(window=24,min_periods=12).sum()).values,index=df0.index.shift(24,freq='M'),columns=i).plot()

# df0.where(df >=40,np.nan,inplace=True); df.where(df >=100,np.nan,inplace=True)
# df0=df0_cp.copy(); df=df_cp.copy()

def get_journal(journal):
    _journal=re.findall(r'([a-zA-Z&]{2,})', journal)[0] \
        if journal and type(journal) != list else ''
    if _journal == 'ApJ' and re.findall(r'(ApJ\S{4,}L)', journal): _journal = 'ApJL'
    return _journal

import pandas as pd, re
jou=['MNRAS','ApJ','ApJL','ApJS','A&A','Natur','Sci']
df=pd.Panel(items =[0,1], major_axis = np.arange(2014,2017), minor_axis = jou) #https://stackoverflow.com/questions/23431900/fill-pandas-panel-object-with-data
for feed in obj:
    for entry in feed.entries:
        # if entry['ADS']['Citations'] <100: continue
        _journal=get_journal(entry['ADS']['Bibliographic Code'])
        try:
            _t_pub0=int(entry['ADS']['Publication Date'].split('/')[1])
            if _journal not in df[0].keys() or _t_pub0 not in [2013,2014,2015]: continue
        except:
            continue
        df[0][_journal].ix[_t_pub0+1:_t_pub0+2]=df[0][_journal].ix[_t_pub0+1:_t_pub0+2].fillna(0)+1

        for _t in entry['ADS']['Citations list']:
            __journal=get_journal(_t[0])
            try:
                _t_pub = int(_t[2].split('/')[1])
            except:
                continue
            if __journal in biblio_code and _t_pub in [2015,2016] and 1<=_t_pub-_t_pub0<=2:
                df[1][_journal].ix[_t_pub]=df[1][_journal].ix[_t_pub]+1 if pd.notnull(df[1][_journal].ix[_t_pub]) else 1

df_cp=df.copy()
(df[1]/df[0]).ix[2015:2016].plot(kind='bar',rot=0)

(df[1]/df[0]).ix[2015] / [4.952,5.909,5.487,11.257,5.185,38.138,34.661]

bins=np.array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30,40,50,60,70,80,100,130,160,200,250])
bins_center=(bins[:-1] + bins[1:]) / 2.; bins_center=np.append(bins_center,250)
df3=pd.DataFrame(index=bins_center, columns = jou) #KDE IF 2015
for feed in obj:
    for entry in feed.entries:
        _journal=get_journal(entry['ADS']['Bibliographic Code'])
        try:
            _t_pub0=int(entry['ADS']['Publication Date'].split('/')[1])
            if _journal not in df[0].keys() or _t_pub0 not in [2013,2014]: continue
        except:
            continue

        cit_thresh=0
        for _t in entry['ADS']['Citations list']:
            __journal=get_journal(_t[0])
            try:
                _t_pub = int(_t[2].split('/')[1])
            except:
                continue
            if __journal in biblio_code and _t_pub == 2015: cit_thresh+=1
        cit_thresh=bins_center[np.digitize(cit_thresh, bins=bins)-1]
        df3[_journal].ix[cit_thresh]=df3[_journal].ix[cit_thresh]+1 if pd.notnull(df3[_journal].ix[cit_thresh]) else 1

df3.rolling(window=10,center=True,min_periods=1).mean().div(df3.sum(0)).plot(logy=True,logx=True)
plt.xlim([1,250])


from fastapi import FastAPI

from api.endpoints import api
from api.endpoints import api

app = FastAPI()

app.include_router(api.router)

info = [
    {
        "route"    : "/api/predict",
        "method"   : "POST",
        "params"   : "One wine",
        "response" : "Predict the quality of the wine input"
    },
    {
        "route"    : "/api/predict",
        "method"   : "GET",
        "params"   : None,
        "response" : "Try to get the 'perfect wine'"
    },
    {
        "route"    : "/api/model",
        "method"   : "GET",
        "params"   : None,
        "response" : "Serialize the last created model"
    },
    {
        "route"    : "/api/model/description",
        "method"   : "GET",
        "params"   : None,
        "response" : "Bring information about the last created model"
    },
    {
        "route"    : "/api/model",
        "method"   : "PUT",
        "params"   : "One wine",
        "response" : "Add a wine to the model"
    },
    {
        "route"    : "/api/model/retrain",
        "method"   : "POST",
        "params"   : None,
        "response" : "Train the model again"
    }
]

@app.get("/")
async def root():
    """
        Guide to use APIs on the welcome page
    """
    return {"Title": "Welcome on the wine quality prediction API!! Here you can see some information about it",
            "First, here are the different available APIs": info,
            "Then, let's use the docs to call APIs": "http://127.0.0.1:8000/docs",
            "It's your turn!": "Now you can use our API!"}


from torch.utils.data import Dataset
from PIL import Image
from tqdm import tqdm
from glob import glob

import os
import shutil

import pandas as pd
import numpy as np

data_split = {
    0: 'train',
    1: 'val',
    2: 'test'
}

class CelebADataset(Dataset):
    def __init__(
            self,
            root,
            raw_data_path,
            split='train',
            transform=None,
            target_transform=None,
            attr_name='Blond_Hair',
            confounder_names="Male",
            return_confounder=False,
    ) -> None:
        self.split = split
        self.transform = transform
        self.target_transform = target_transform
        self.return_confounder = return_confounder
        self.return_masked = False
        self.data_path = []
        self.masked_data_path = []
        self.labels = []
        self.confounders = {}
        img_data_dir = os.path.join(
            root, 'images', split)
        if not (os.path.isdir(img_data_dir) and len(os.listdir(img_data_dir)) > 0):
            print(
                f"\n\nstart creating and saving {split} dataset of CelebA\n\n")
            attrs_df = pd.read_csv(os.path.join(
                raw_data_path, 'list_attr_celeba.csv'))
            image_ids = attrs_df['image_id'].values
            attrs_df = attrs_df.drop(labels='image_id', axis='columns')
            attr_names = attrs_df.columns.copy()
            attrs_df = attrs_df.values
            attrs_df[attrs_df == -1] = 0
            target_idx = attr_names.get_loc(attr_name)
            labels = attrs_df[:, target_idx]
            confounder_idx = attr_names.get_loc(confounder_names)
            confounders = attrs_df[:, confounder_idx]
            partition_df = pd.read_csv(os.path.join(
                raw_data_path, 'list_eval_partition.csv'))
            partitions = partition_df['partition']
            os.makedirs(img_data_dir, exist_ok=True)
            for label in np.unique(labels):
                os.makedirs(os.path.join(
                    img_data_dir, str(label)), exist_ok=True)
            for image_id, label, confounder, partition in tqdm(zip(image_ids, labels, confounders, partitions), total=len(image_ids)):
                if data_split[partition] == split:
                    shutil.copy(os.path.join(raw_data_path, 'img_align_celeba', image_id), os.path.join(
                        img_data_dir, str(label), image_id))
                    self.data_path.append(os.path.join(
                        img_data_dir, str(label), image_id))
                    self.labels.append(label)
                    self.confounders[image_id] = confounder
            print(
                f"\n\nfinished creating and saving {split} dataset of CelebA\n\n")
            return
        attrs_df = pd.read_csv(os.path.join(
            raw_data_path, 'list_attr_celeba.csv'))
        image_ids = attrs_df['image_id'].values
        attrs_df = attrs_df.drop(labels='image_id', axis='columns')
        attr_names = attrs_df.columns.copy()
        attrs_df = attrs_df.values
        attrs_df[attrs_df == -1] = 0
        confounder_idx = attr_names.get_loc(confounder_names)
        confounders = attrs_df[:, confounder_idx]
        partition_df = pd.read_csv(os.path.join(
            raw_data_path, 'list_eval_partition.csv'))
        partitions = partition_df['partition']
        for image_id, confounder, partition in tqdm(zip(image_ids, confounders, partitions), total=len(image_ids)):
            if data_split[partition] == split:
                self.confounders[image_id] = int(confounder)

        self.update_data(img_data_dir)

    def update_data(self, data_file_directory, masked_data_file_path=None):
        self.data_path = []
        self.masked_data_path = []
        self.labels = []
        data_classes = sorted(os.listdir(data_file_directory))
        print("-"*10, f"indexing {self.split} data", "-"*10)
        for data_class in tqdm(data_classes):
            try:
                label = int(data_class)
            except:
                continue
            class_image_file_paths = glob(
                os.path.join(data_file_directory, data_class, '*'))
            self.data_path += class_image_file_paths
            if masked_data_file_path is not None:
                self.return_masked = True
                masked_class_image_file_paths = sorted(glob(
                    os.path.join(masked_data_file_path, data_class, '*')))
                self.masked_data_path += masked_class_image_file_paths
            self.labels += [label] * len(class_image_file_paths)

    def __len__(self):
        return len(self.data_path)

    def __getitem__(self, index: int):
        """
        Args:
            index (int): Index

        Returns:
            tuple: (image, img_file_path, label) where label is index of the label class.
        """
        img_file_path, label = self.data_path[index], self.labels[index]
        img = Image.open(img_file_path)
        if self.transform is not None:
            img = self.transform(img)
        if self.target_transform is not None:
            label = self.target_transform(label)
        if self.return_masked:
            masked_img_file_path = self.masked_data_path[index]
            masked_img = Image.open(masked_img_file_path)
            if self.transform is not None:
                masked_img = self.transform(masked_img)
            if self.return_confounder:
                return img, img_file_path, label, masked_img, self.confounders[img_file_path.split('/')[-1]]
            return img, img_file_path, label, masked_img
        if self.return_confounder:
            return img, img_file_path, label, self.confounders[img_file_path.split('/')[-1]]
        return img, img_file_path, label


from flask import Flask
from flask import request
import json

app = Flask(__name__)

# Accepts json data with two ints x,y -- returns sum in json format
@app.route("/test", methods=['POST'])
def jsonPOST():
	content = request.get_json()
	sum_ = content['x'] + content['y']
	ret = json.dumps({'sum': sum_})
	return ret

if __name__ == "__main__":
	app.run()


import discord

from utils.server_configuration import ServerConfiguration

class OnMessageEventInfo:
    def __init__(self, ctx: discord.Message, client: discord.Client, database, bot_config, server_config: ServerConfiguration, module):
        self.message = ctx
        self.client = client
        self.database = database
        self.bot_config = bot_config
        self.server_config = server_config
        self.module = module


from django.db import models
import django.contrib.auth.models as auth
from .helpers import RandomFileName
from uuid import uuid4

class Merchandise(models.Model):
    name = models.CharField(default="", max_length=255)
    price = models.DecimalField(max_digits=6, decimal_places=2)  # цена, 999999 макс
    pic = models.ImageField(upload_to="images", blank=True, null=True)

    def __str__(self):
        return self.name

# Нужно больше параметров

class Lottery(models.Model):
    name = models.CharField(default="", max_length=255)
    total_count = models.PositiveIntegerField(default=100, null=False)
    now_count = models.PositiveIntegerField(default=0)
    merchandise = models.ForeignKey(Merchandise, on_delete=models.PROTECT)
    users = models.ManyToManyField("User", through = 'UserScore')
    random_int = models.UUIDField(default=uuid4, editable=False, unique=True)

    def __str__(self):
        return self.name

    def check_end(self):
        if self.now_count >= self.total_count:
            return True

    def add_count(self, coins):
        if self.check_end(): return 0
        if (int(coins)+self.now_count) > self.total_count:
            coins_for_return = int(coins)+self.now_count-self.total_count
            coins -= coins_for_return
        else:
            coins_for_return = 0
        self.now_count += int(coins)
        self.check_end()
        return coins_for_return

class User(auth.AbstractUser):
    cash = models.PositiveIntegerField(default=0)
    active_lottery = models.ManyToManyField(Lottery, through='UserScore')
    avatar = models.ImageField(upload_to=RandomFileName("avatar"), blank=True, null=True, default='default/avatar.png')

    def __str__(self):
        return self.username

    def check_coins(self, coins):
        if self.cash < int(coins) or self.cash == 0:
            return False
        else:
            return True

class UserScore(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(value='Deleted'))
    lottery = models.ForeignKey(Lottery, on_delete=models.SET(value='Deleted'))
    score = models.IntegerField(default=0, null=True)

    class Meta:
        unique_together = ('user', 'lottery')

def add_user_into_lottery(user, lottery, coins):
    if not user.check_coins(coins) or coins == 0:
        return False # some exception here
    else:
        current_lottery= Lottery.objects.get(random_int=lottery)
        if current_lottery.check_end():
            return False
        user.cash -= int(coins)
        try:
           nw=UserScore.objects.get(user=user, lottery=current_lottery)
        except UserScore.DoesNotExist:
            nw = UserScore(user=user, lottery=current_lottery, score=coins)
        else:
            nw.score += coins
        return_coins = current_lottery.add_count(coins)
        if return_coins > 0:
            user.cash += return_coins
        user.save()
        nw.save()
        current_lottery.save()

# Create your models here.


import logging
import sys
from dataclasses import dataclass, field
import faiss
from sentence_transformers import SentenceTransformer
from transformers import HfArgumentParser
from data_utils import DatasetReader

@dataclass
class QuestionAnsweringModuleArgs:
    model: str = field(
        default="./output",
        metadata={"help": "The name or path to the model"},
    )
    input_path: str = field(
        default="data.jsonl",
        metadata={"help": "Input data file"},
    )
    simple_qa: bool = field(
        default=False,
        metadata={"help": "Use question to question module"},
    )
    fp16: bool = field(
        default=True,
        metadata={"help": "Use 16 bit precision"},
    )

class Question2QuestionModule:

    def __init__(self, args: QuestionAnsweringModuleArgs):
        self.args = args
        self.model = SentenceTransformer(self.args.model)
        self.model.eval()
        if self.args.fp16: self.model.half()
        self.data = self._load_data()
        self.index = self._create_index()

    def _load_data(self):
        reader = DatasetReader(self.args.input_path, eval_size=0)
        return [pair for pair in reader.get_question_answer_pairs(first_answer_only=True)]

    def _create_index(self):
        logging.info("Initializing faiss index")
        texts = [q for q, a in self.data]
        embeddings = self.model.encode(texts, normalize_embeddings=True, show_progress_bar=True)
        dim = embeddings.shape[1]
        res = faiss.IndexFlatIP(dim)
        res.add(embeddings)
        return res

    def generate_answer(self, question: str):
        q_emb = self.model.encode([question], normalize_embeddings=True, show_progress_bar=False)
        sim, indices = self.index.search(q_emb, 1)
        indices = indices.tolist()
        idx = indices[0][0]
        q, a = self.data[idx]
        return a

class Question2AnswerModule:

    def __init__(self, args: QuestionAnsweringModuleArgs):
        self.args = args
        self.model = SentenceTransformer(self.args.model)
        self.model.eval()
        if self.args.fp16: self.model.half()
        self.answers = self._load_answers()
        self.index = self._create_index()

    def _load_answers(self):
        reader = DatasetReader(self.args.input_path, eval_size=0)
        return [sent for sent in reader.get_answers()]

    def _create_index(self):
        logging.info("Initializing faiss index")
        embeddings = self.model.encode(self.answers, normalize_embeddings=True, show_progress_bar=True)
        dim = embeddings.shape[1]
        res = faiss.IndexFlatIP(dim)
        res.add(embeddings)
        return res

    def generate_answer(self, question: str):
        q_emb = self.model.encode([question], normalize_embeddings=True, show_progress_bar=False)
        sim, indices = self.index.search(q_emb, 1)
        indices = indices.tolist()
        idx = indices[0][0]
        return self.answers[idx]

if __name__ == '__main__':
    logging.basicConfig(format='%(asctime)s : %(message)s', level=logging.DEBUG)
    logging.root.setLevel(logging.DEBUG)
    parser = HfArgumentParser([QuestionAnsweringModuleArgs])
    args = parser.parse_args_into_dataclasses()[0]
    qa = Question2QuestionModule(args) if args.simple_qa else Question2AnswerModule(args)
    print("Dzień dobry, zapraszam do zadawania pytań")
    for question in sys.stdin:
        if question.strip() == "exit":
            print("Dziękuję za skorzystanie z usług wirtualnego asystenta")
            exit(0)
        answer = qa.generate_answer(question.strip())
        print(f"A: {answer}")


import shutil
import tempfile

from deals.forms import TaskCreateForm
from deals.models import Task
from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import Client, TestCase, override_settings
from django.urls import reverse

# Создаем временную папку для медиа-файлов;
# на момент теста медиа папка будет переопределена
TEMP_MEDIA_ROOT = tempfile.mkdtemp(dir=settings.BASE_DIR)

# Для сохранения media-файлов в тестах будет использоватьсяgs
# временная папка TEMP_MEDIA_ROOT, а потом мы ее удалим
@override_settings(MEDIA_ROOT=TEMP_MEDIA_ROOT)
class TaskCreateFormTests(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        # Создаем запись в базе данных для проверки сушествующего slug
        Task.objects.create(
            title='Тестовый заголовок',
            text='Тестовый текст',
            slug='first'
        )
        # Создаем форму, если нужна проверка атрибутов
        cls.form = TaskCreateForm()

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        # Модуль shutil - библиотека Python с прекрасными инструментами
        # для управления файлами и директориями:
        # создание, удаление, копирование, перемещение, изменение папок и файлов
        # Метод shutil.rmtree удаляет директорию и всё её содержимое
        shutil.rmtree(TEMP_MEDIA_ROOT, ignore_errors=True)

    def setUp(self):
        # Создаем неавторизованный клиент
        self.guest_client = Client()

    def test_create_task(self):
        """Валидная форма создает запись в Task."""
        # Подсчитаем количество записей в Task
        tasks_count = Task.objects.count()
        # Подготавливаем данные для передачи в форму
        small_gif = (
            b'\x47\x49\x46\x38\x39\x61\x01\x00'
            b'\x01\x00\x00\x00\x00\x21\xf9\x04'
            b'\x01\x0a\x00\x01\x00\x2c\x00\x00'
            b'\x00\x00\x01\x00\x01\x00\x00\x02'
            b'\x02\x4c\x01\x00\x3b'
        )
        uploaded = SimpleUploadedFile(
            name='small.gif',
            content=small_gif,
            content_type='image/gif'
        )
        form_data = {
            'title': 'Тестовый заголовок',
            'text': 'Тестовый текст',
            'image': uploaded,
        }
        response = self.guest_client.post(
            reverse('deals:home'),
            data=form_data,
            follow=True
        )
        # Проверяем, сработал ли редирект
        self.assertRedirects(response, reverse('deals:task_added'))
        # Проверяем, увеличилось ли число постов
        self.assertEqual(Task.objects.count(), tasks_count+1)
        # Проверяем, что создалась запись с нашим слагом
        self.assertTrue(
            Task.objects.filter(
                slug='testovyij-zagolovok',
                text='Тестовый текст',
                image='tasks/small.gif'
                ).exists()
        )

    def test_cant_create_existing_slug(self):
        # Подсчитаем количество записей в Task
        tasks_count = Task.objects.count()
        form_data = {
            'title': 'Заголовок из формы',
            'text': 'Текст из формы',
            'slug': 'first',  # отправим в форму slug, который уже есть в БД
        }
        # Отправляем POST-запрос
        response = self.guest_client.post(
            reverse('deals:home'),
            data=form_data,
            follow=True
        )
        # Убедимся, что запись в базе данных не создалась:
        # сравним количество записей в Task до и после отправки формы
        self.assertEqual(Task.objects.count(), tasks_count)
        # Проверим, что форма вернула ошибку с ожидаемым текстом:
        # из объекта responce берём словарь 'form',
        # указываем ожидаемую ошибку для поля 'slug' этого словаря
        self.assertFormError(
            response,
            'form',
            'slug',
            'Адрес "first" уже существует, придумайте уникальное значение'
        )
        # Проверим, что ничего не упало и страница отдаёт код 200
        self.assertEqual(response.status_code, 200)

    # Если не тестировали содержимое лейблов в models
    # или переопределили их при создании формы - тестируем так:
    def test_title_label(self):
        title_label = TaskCreateFormTests.form.fields['title'].label
        self.assertEqual(title_label, 'Заголовок')

    def test_title_help_text(self):
        title_help_text = TaskCreateFormTests.form.fields['title'].help_text
        self.assertEqual(title_help_text, 'Дайте короткое название задаче')


#!/usr/bin/env python

import sys
import numpy as np
import matplotlib.pyplot as pl
from scipy import signal, optimize

def gaincal(fs,psd,vdc,vchop):
	df = fs[1]-fs[0]
	fmin = 28.
	fmax = 32.
	ok = (fmin < fs) & (fs < fmax)
	w = np.sqrt(df*np.sum(psd[ok]))
	rb = 0.851e6
	rh = 0.073
	p0 = (vdc/rb)**2 * rh
	pmax = ((vdc+vchop/2.)/rb)**2 * rh
	pmin = ((vdc-vchop/2.)/rb)**2 * rh
	ppp = pmax - pmin
	prms = ppp / (2.*np.sqrt(2.))
	gain = w/prms
	psd /= gain**2
	return psd,gain,p0

setfn = sys.argv[1]
gains = []
for line in open(setfn):
	resultsfn,vdc,vchop,pread = line.split()
	vdc = float(vdc)
	vchop = float(vchop)
	pread = float(pread)

	NFFT = 1024
	results = np.loadtxt(resultsfn)

	results[:,0]*=1e6
	results -= np.mean(results,axis=0)

	sample_rate = 1e6/1024.

	ares = []
	anocal = []
	for i in range(1):
		fs,psd = signal.welch(results[:,i],nperseg=NFFT,fs=sample_rate)
		anocal.append(np.sqrt(psd))
		psd,gain,pdc = gaincal(fs,psd,vdc,vchop)
		results[:,i] /= gain
		asd = np.sqrt(psd)*1e18
		ares.append(asd)

	gains.append(gain)

#names = 'f0 Qr A B'.split()
	names = 'f0 Qr A B Qe_re Qe_im D'.split()

	pl.figure(1)
	for i in range(1):
		pl.plot(fs,ares[i],label='heat=%.2fpW pread=%ddB'%(pdc*1e12,pread))
	pl.figure(2)
	for i in range(1):
		pl.plot(fs,anocal[i],label='heat=%.2fpW pread=%ddB'%(pdc*1e12,pread))

pl.figure(1)
pl.gca().set_xscale('log')
pl.gca().set_yscale('log')
pl.xlabel('Frequency (Hz)')
pl.ylabel('NEP (aW/rtHz)')
pl.legend(loc='upper left')
pl.grid()
pl.savefig('chirp_nep1.png')

pl.figure(2)
pl.gca().set_xscale('log')
pl.gca().set_yscale('log')
pl.xlabel('Frequency (Hz)')
pl.ylabel('NEF (Hz/rtHz)')
pl.legend(loc='upper left')
pl.grid()
pl.savefig('chirp_nef1.png')

gains = np.array(gains)*1e-18
pl.figure()
pl.plot(gains,marker='o')
pl.xlabel('Test #')
pl.ylabel('Responsivity (MHz/pW)')
pl.ylim(0,1.3*np.max(gains))
pl.ylim(ymax=1.3*np.max(gains))
pl.grid()
pl.savefig('chirp_responsivity1.png')

pl.show()


import argparse
from pathlib import Path
import sys

from .analyzer import analyze
from .shared import GROUP, STUDENT, PROBLEM, ATTEMPT

ALLOWED_COMPONENTS = [STUDENT, GROUP, PROBLEM, ATTEMPT]
COMPONENT_DELIMITER = '/'
DEFAULT_PATH = STUDENT
COMPONENT_DESCRIPTION = f'{", ".join(map(repr, ALLOWED_COMPONENTS))}'f' separated with {repr(COMPONENT_DELIMITER)}'

DEFAULT_MIN_NGRAM = 1
DEFAULT_MAX_NGRAM = 20

DEFAULT_CLIQUE_INDIVIDUAL = 5
DEFAULT_CLIQUE_GROUP = 2

DEFAULT_MIN_RATIO = 0.2

STUDENT_MATCH_DELIMITER = '-' * 20 + '\n\n' + '-' * 20
STUDENT_SUBMISSION_DELIMITER = '-' * 5
SUBMISSION_MATCH_DELIMITER = '+'

def parse_path(path: str) -> tuple[str, ...]:
    components = path.split(COMPONENT_DELIMITER)
    if not all(component in ALLOWED_COMPONENTS for component in components):
        raise argparse.ArgumentTypeError(f'Expected {COMPONENT_DESCRIPTION}, got {repr(path)}')
    if STUDENT not in components:
        raise argparse.ArgumentTypeError(f'Expected {repr(STUDENT)} among the path components, got {repr(path)}')
    return tuple(components)

def parse_positive_integer(value: str) -> int:
    try:
        size = int(value)
    except ValueError:
        size = None
    if size is None or size <= 0:
        raise argparse.ArgumentTypeError(f'Expected positive integer, got {repr(value)}')
    return size

def parse_ratio(value: str) -> float:
    try:
        ratio = float(value)
    except ValueError:
        ratio = None
    if ratio is None or not 0.0 <= ratio <= 1.0:
        raise argparse.ArgumentTypeError(f'Expected a number between 0.0 and 1.0, got {repr(value)}')
    return ratio

def numeral(n: int, word: str, plural_suffix: str = 's') -> str:
    return f'{n} {word}{"" if n == 1 else plural_suffix}'

def log(*args, **kwargs) -> None:
    print(*args, file=sys.stderr, **kwargs)

def run() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument('root', type=Path, help='directory with submissions')
    parser.add_argument('--path', type=parse_path, nargs='?', default=DEFAULT_PATH,
                        help=f'template for the path to individual submissions: {COMPONENT_DESCRIPTION}')
    parser.add_argument('--min-ngram', type=parse_positive_integer, nargs='?', default=DEFAULT_MIN_NGRAM,
                        help='minimum size of ngrams to analyze')
    parser.add_argument('--max-ngram', type=parse_positive_integer, nargs='?', default=DEFAULT_MAX_NGRAM,
                        help='maximum size of ngrams to analyze')
    parser.add_argument('--min-ratio', type=parse_ratio, nargs='?', default=DEFAULT_MIN_RATIO,
                        help='minimum ratio of the number of shared tokens'
                             ' to the number of tokens in the longer of the two submissions')
    parser.add_argument('--max-clique', type=parse_positive_integer, nargs='?', default=None,
                        help=f'if an ngram occurs in submissions of more than so many students (or in submissions'
                             f' of students from more than so many groups), it is excluded from analysis')
    arguments = parser.parse_args()
    root: Path = arguments.root
    if not root.exists():
        parser.error(f'{root} does not exist')
    if not root.is_dir():
        parser.error(f'{root} is not a directory')
    path: tuple[str, ...] = arguments.path
    has_groups = GROUP in path
    min_ngram: int = arguments.min_ngram
    max_ngram: int = arguments.max_ngram
    if min_ngram > max_ngram:
        parser.error(f'Min ngram size exceeds max ngram size: {min_ngram} > {max_ngram}')
    min_ratio: float = arguments.min_ratio
    max_clique: int = (arguments.max_clique if arguments.max_clique is not None
                       else (DEFAULT_CLIQUE_GROUP if has_groups else DEFAULT_CLIQUE_INDIVIDUAL))
    if max_clique == 1 and not has_groups:
        parser.error('Max clique size must be greater than 1 if students are not assigned groups')
    log(f'Running with '
        f'path={COMPONENT_DELIMITER.join(path)}, '
        f'min-ngram={min_ngram}, '
        f'max-ngram={max_ngram}, '
        f'min-ratio={min_ratio}, '
        f'max-clique={max_clique}')
    analysis = analyze(root, path, min_ngram, max_ngram, min_ratio, max_clique, log)
    print(', '.join(filter(None, [
        numeral(analysis.submission_count, 'submission'),
        numeral(analysis.problem_count, 'problem'),
        numeral(analysis.student_count, 'student'),
        numeral(analysis.group_count, 'group') if has_groups else None,
    ])) + ' discovered')
    print(numeral(len(analysis.student_matches), 'student-to-student match', 'es') + ' found')
    for student_match in analysis.student_matches:
        print(STUDENT_MATCH_DELIMITER)
        print(student_match.a)
        print(student_match.b)
        print(numeral(student_match.common_tokens, 'common token'))
        for index, submission_match in enumerate(student_match.submission_matches):
            print(STUDENT_SUBMISSION_DELIMITER if index == 0 else SUBMISSION_MATCH_DELIMITER)
            print(submission_match.a)
            print(submission_match.b)
            print(numeral(submission_match.common_tokens, 'common token')
                  + ' / ' + numeral(len(submission_match.longest_ngram), 'token') + ' in the longest match:')
            print(' '.join(submission_match.longest_ngram))
    log('Analysis complete')


import paddle
import warnings
from typing import Optional

def one_hot(labels: paddle.Tensor, num_classes: int, dtype: Optional[paddle.dtype]=None, eps: float=1e-06
    ) ->paddle.Tensor:
    """Convert an integer label x-D tensor to a one-hot (x+1)-D tensor.
    Args:
        labels: tensor with labels of shape :math:`(N, *)`, where N is batch size.
          Each value is an integer representing correct classification.
        num_classes: number of classes in labels.
        dtype: the desired data type of returned tensor.
    Returns:
        the labels in one hot tensor of shape :math:`(N, C, *)`,
    Examples:
         labels = paddle.LongTensor([[[0, 1], [2, 0]]])
         one_hot(labels, num_classes=3)
        tensor([[[[1.0000e+00, 1.0000e-06],
                  [1.0000e-06, 1.0000e+00]],
        <BLANKLINE>
                 [[1.0000e-06, 1.0000e+00],
                  [1.0000e-06, 1.0000e-06]],
        <BLANKLINE>
                 [[1.0000e-06, 1.0000e-06],
                  [1.0000e+00, 1.0000e-06]]]])
    """
    if not isinstance(labels, paddle.Tensor):
        raise TypeError(
            f'Input labels type is not a paddle.Tensor. Got {type(labels)}')
    if not labels.dtype == paddle.int64:
        raise ValueError(
            f'labels must be of the same dtype paddle.int64. Got: {labels.dtype}'
            )
    if num_classes < 1:
        raise ValueError(
            'The number of classes must be bigger than one. Got: {}'.format
            (num_classes))
    shape = labels.shape
    one_hot = paddle.zeros(shape=[shape[0], num_classes]+ shape[1:],
        dtype=dtype)
    return paddle.put_along_axis(one_hot, indices=labels.unsqueeze(axis=1), values=1.0, axis=1)  + eps

def focal_loss(input: paddle.Tensor, target: paddle.Tensor, alpha: float,
    gamma: float=2.0, reduction: str='none', eps: Optional[float]=None
    ) ->paddle.Tensor:
    """Criterion that computes Focal loss.
    According to :cite:`lin2018focal`, the Focal loss is computed as follows:
    .. math::
        \\text{FL}(p_t) = -\\alpha_t (1 - p_t)^{\\gamma} \\, \\text{log}(p_t)
    Where:
       - :math:`p_t` is the model's estimated probability for each class.
    Args:
        input: logits tensor with shape :math:`(N, C, *)` where C = number of classes.
        target: labels tensor with shape :math:`(N, *)` where each value is :math:`0 ≤ targets[i] ≤ C−1`.
        alpha: Weighting factor :math:`\\alpha \\in [0, 1]`.
        gamma: Focusing parameter :math:`\\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        eps: Deprecated: scalar to enforce numerical stabiliy. This is no longer used.
    Return:
        the computed loss.
    Example:
         N = 5  # num_classes
         input = paddle.randn(1, N, 3, 5, requires_grad=True)
         target = paddle.empty(1, 3, 5, dtype=paddle.long).random_(N)
         output = focal_loss(input, target, alpha=0.5, gamma=2.0, reduction='mean')
         output.backward()
    """
    if eps is not None:
        warnings.warn(
            '`focal_loss` has been reworked for improved numerical stability and the `eps` argument is no longer necessary'
            , DeprecationWarning, stacklevel=2)
    if not isinstance(input, paddle.Tensor):
        raise TypeError(f'Input type is not a paddle.Tensor. Got {type(input)}')
    if not len(input.shape) >= 2:
        raise ValueError(
            f'Invalid input shape, we expect BxCx*. Got: {input.shape}')
    if input.shape[0] != target.shape[0]:
        raise ValueError(
            f'Expected input batch_size ({input.shape[0]}) to match target batch_size ({target.shape[0]}).'
            )
    n = input.shape[0]
    out_size = [n,] + input.shape[2:]
    if target.shape[1:] != input.shape[2:]:
        raise ValueError(f'Expected target size {out_size}, got {target.shape}'
            )
    input_soft = paddle.nn.functional.softmax(x=input, axis=1)
    log_input_soft = paddle.nn.functional.log_softmax(x=
        input, axis=1)
    target_one_hot = one_hot(target, num_classes=input.shape
        [1], dtype=input.dtype)
    weight = paddle.pow(x=-input_soft + 1.0, y=gamma)
    focal = -alpha * weight * log_input_soft
    # loss_tmp = paddle.einsum('bc...,bc...->b...', (target_one_hot, focal))
    loss_tmp = paddle.sum(target_one_hot * focal, axis=1)
    if reduction == 'none':
        loss = loss_tmp
    elif reduction == 'mean':
        loss = paddle.mean(x=loss_tmp)
    elif reduction == 'sum':
        loss = paddle.sum(x=loss_tmp)
    else:
        raise NotImplementedError(f'Invalid reduction mode: {reduction}')
    return loss

class FocalLoss(paddle.nn.Layer):
    """Criterion that computes Focal loss.
    According to :cite:`lin2018focal`, the Focal loss is computed as follows:
    .. math::
        \\text{FL}(p_t) = -\\alpha_t (1 - p_t)^{\\gamma} \\, \\text{log}(p_t)
    Where:
       - :math:`p_t` is the model's estimated probability for each class.
    Args:
        alpha: Weighting factor :math:`\\alpha \\in [0, 1]`.
        gamma: Focusing parameter :math:`\\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        eps: Deprecated: scalar to enforce numerical stability. This is no longer
          used.
    Shape:
        - Input: :math:`(N, C, *)` where C = number of classes.
        - Target: :math:`(N, *)` where each value is
          :math:`0 ≤ targets[i] ≤ C−1`.
    Example:
         N = 5  # num_classes
         kwargs = {"alpha": 0.5, "gamma": 2.0, "reduction": 'mean'}
         criterion = FocalLoss(**kwargs)
         input = paddle.randn(1, N, 3, 5, requires_grad=True)
         target = paddle.empty(1, 3, 5, dtype=paddle.long).random_(N)
         output = criterion(input, target)
         output.backward()
    """

    def __init__(self, alpha: float, gamma: float=2.0, reduction: str=
        'none', eps: Optional[float]=None) ->None:
        super().__init__()
        self.alpha: float = alpha
        self.gamma: float = gamma
        self.reduction: str = reduction
        self.eps: Optional[float] = eps

    def forward(self, input: paddle.Tensor, target: paddle.Tensor
        ) ->paddle.Tensor:
        return focal_loss(input, target, self.alpha, self.gamma, self.
            reduction, self.eps)

def binary_focal_loss_with_logits(input: paddle.Tensor, target: paddle.
    Tensor, alpha: float=0.25, gamma: float=2.0, reduction: str='none', eps:
    Optional[float]=None) ->paddle.Tensor:
    """Function that computes Binary Focal loss.
    .. math::
        \\text{FL}(p_t) = -\\alpha_t (1 - p_t)^{\\gamma} \\, \\text{log}(p_t)
    where:
       - :math:`p_t` is the model's estimated probability for each class.
    Args:
        input: input data tensor of arbitrary shape.
        target: the target tensor with shape matching input.
        alpha: Weighting factor for the rare class :math:`\\alpha \\in [0, 1]`.
        gamma: Focusing parameter :math:`\\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
        eps: Deprecated: scalar for numerically stability when dividing. This is no longer used.
    Returns:
        the computed loss.
    Examples:
         kwargs = {"alpha": 0.25, "gamma": 2.0, "reduction": 'mean'}
         logits = paddle.tensor([[[6.325]],[[5.26]],[[87.49]]])
         labels = paddle.tensor([[[1.]],[[1.]],[[0.]]])
         binary_focal_loss_with_logits(logits, labels, **kwargs)
        tensor(21.8725)
    """
    if eps is not None:
        warnings.warn(
            '`binary_focal_loss_with_logits` has been reworked for improved numerical stability and the `eps` argument is no longer necessary'
            , DeprecationWarning, stacklevel=2)
    if not isinstance(input, paddle.Tensor):
        raise TypeError(f'Input type is not a paddle.Tensor. Got {type(input)}')
    if not len(input.shape) >= 2:
        raise ValueError(
            f'Invalid input shape, we expect BxCx*. Got: {input.shape}')
    if input.shape[0] != target.shape[0]:
        raise ValueError(
            f'Expected input batch_size ({input.shape[0]}) to match target batch_size ({target.shape[0]}).'
            )
    probs_pos = paddle.nn.functional.sigmoid(x=input)
    probs_neg = paddle.nn.functional.sigmoid(x=-input)
    loss_tmp = -alpha * paddle.pow(x=probs_neg, y=gamma
        ) * target * paddle.nn.functional.logsigmoid(x=input) - (1 - alpha
        ) * paddle.pow(x=probs_pos, y=gamma) * (1.0 - target
        ) * paddle.nn.functional.logsigmoid(x=-input)
    if reduction == 'none':
        loss = loss_tmp
    elif reduction == 'mean':
        loss = paddle.mean(x=loss_tmp)
    elif reduction == 'sum':
        loss = paddle.sum(x=loss_tmp)
    else:
        raise NotImplementedError(f'Invalid reduction mode: {reduction}')
    return loss

class BinaryFocalLossWithLogits(paddle.nn.Layer):
    """Criterion that computes Focal loss.
    According to :cite:`lin2018focal`, the Focal loss is computed as follows:
    .. math::
        \\text{FL}(p_t) = -\\alpha_t (1 - p_t)^{\\gamma} \\, \\text{log}(p_t)
    where:
       - :math:`p_t` is the model's estimated probability for each class.
    Args:
        alpha): Weighting factor for the rare class :math:`\\alpha \\in [0, 1]`.
        gamma: Focusing parameter :math:`\\gamma >= 0`.
        reduction: Specifies the reduction to apply to the
          output: ``'none'`` | ``'mean'`` | ``'sum'``. ``'none'``: no reduction
          will be applied, ``'mean'``: the sum of the output will be divided by
          the number of elements in the output, ``'sum'``: the output will be
          summed.
    Shape:
        - Input: :math:`(N, *)`.
        - Target: :math:`(N, *)`.
    Examples:
         kwargs = {"alpha": 0.25, "gamma": 2.0, "reduction": 'mean'}
         loss = BinaryFocalLossWithLogits(**kwargs)
         input = paddle.randn(1, 3, 5, requires_grad=True)
         target = paddle.empty(1, 3, 5, dtype=paddle.long).random_(2)
         output = loss(input, target)
         output.backward()
    """

    def __init__(self, alpha: float, gamma: float=2.0, reduction: str='none'
        ) ->None:
        super().__init__()
        self.alpha: float = alpha
        self.gamma: float = gamma
        self.reduction: str = reduction

    def forward(self, input: paddle.Tensor, target: paddle.Tensor
        ) ->paddle.Tensor:
        return binary_focal_loss_with_logits(input, target, self.alpha,
            self.gamma, self.reduction)


import sys
sys.path.append("..")

from parse import input_as_string, input_as_lines, input_as_ints

line = input_as_lines('test.txt')
nums = [int(n) for n in line[0].split(',')]
nums = [[n,1] for n in nums]
nums.sort()
fuel = 0
m = 1

kv = {}
for ii in range(len(nums)):
	if nums[ii][0] in kv:
		kv[nums[ii][1]] += 1
	else:
		kv[nums[ii][1]] = nums[ii][1]

maxx = 0

for e in kv:
	maxx = max(maxx, e)

print( len(nums) - maxx)


import multiprocessing
from multiprocessing.managers import BaseManager, NamespaceProxy

class Counter(object):
    def __init__(self):
        self.value = 0

    def update(self, value):
        self.value += value

def update(counter_proxy, thread_id):
    counter_proxy.update(1)

class CounterManager(BaseManager):
    pass

class CounterProxy(NamespaceProxy):
    _exposed_ = ('__getattribute__', '__setattr__', '__delattr__', 'update')

    def update(self, value):
        callmethod = object.__getattribute__(self, '_callmethod')
        return callmethod(self.update.__name__, (value,))

CounterManager.register('Counter', Counter, CounterProxy)

def main():
    manager = CounterManager()
    manager.start()

    counter = manager.Counter()
    pool = multiprocessing.Pool(multiprocessing.cpu_count())
    for i in range(10):
        pool.apply(func=update, args=(counter, i))
    pool.close()
    pool.join()

    print('Should be 10 but is %s.' % counter.value)

if __name__ == '__main__':
    main()


import shutil
import os
import datetime
import sys
import time

x = 1

mod = input('Mod to play: \n >>')
#if

if mod == 'vc' or 'VC':
	dest = 'C:\\Users\\coust\\Documents\\Mount&Blade Warband Savegames - Backup\\VC'
	source = 'C:\\Users\\coust\\Documents\\Mount&Blade Warband Savegames\\Viking Conquest\\'
elif mod == 'pop' or 'POP':
	source = 'C:\\Users\\coust\\Documents\\Mount&Blade Warband Savegames\\Prophesy of Pendor V3.9.2\\'
	dest = 'C:\\Users\\coust\\Documents\\Mount&Blade Warband Savegames - Backup\\PoP'

while x:
    timestamp = datetime.datetime.now()
    for adi_dir, dirs, files in os.walk(source):
        for file in files:
            time   .sleep(60*5)
            source_path = source + file
            file_creation_time = os.path.getmtime(source_path)
            dest_path = dest + file + timestamp.strftime('-%Y%m%dT%H%M%S')
            if not os.path.exists(dest):
                try:
                    os.makedirs(os.path.dirname(dest))
                except:  # Guard against race condition
                    print('Directory could not be made')
            shutil.copyfile(source_path, dest_path)
            nowtime = datetime.datetime.now()
            print('[{}]: Save Backed-up'.format(nowtime))


import gin
import numpy as np
import tensorflow as tf
from tensorflow.keras import layers
import tensorflow_probability as tfp
tfd = tfp.distributions

class MetaDense(layers.Dense):
    def build(self,*args,**kwargs):
        assert self.built == False

        super().build(*args,**kwargs)
        self.input_spec = [self.input_spec,
                           layers.InputSpec(self.kernel.dtype,self.kernel.get_shape()),
                           layers.InputSpec(self.bias.dtype,self.bias.get_shape())]

    #@tf.function
    def call(self,inputs):
        assert self.built == True

        if isinstance(inputs,tuple):
            x,w,b = inputs

            tf.assert_equal(tf.shape(w),tf.shape(self.kernel))
            tf.assert_equal(tf.shape(b),tf.shape(self.bias))

            outputs = tf.matmul(x, w)
            if self.use_bias:
                outputs = tf.nn.bias_add(outputs, b)
            if self.activation is not None:
                return self.activation(outputs)  # pylint: disable=not-callable
            return outputs
        else:
            return super().call(inputs)

@gin.configurable(module=__name__)
class DenseNet(layers.Layer):
    def __init__(self,in_dim,out_dim,num_layers,dim,activation='relu'):
        super().__init__()
        self.layers = [
            MetaDense(dim,activation=activation)
            for _ in range(num_layers)
        ] + [MetaDense(out_dim)]

        #build network
        self.layers[0].build(in_dim)
        for l in self.layers[1:]: l.build(dim)

    @property
    def params_list(self):
        return [l.weights for l in self.layers]

    def call(self, inputs):
        assert False, "You don't need to call this function"

    #@tf.function
    def call_with_params(self, x, params_list, raw=False):
        assert len(params_list) == len(self.layers), f'{len(params_list)} != {len(self.layers)}'
        o = x
        for l,params in zip(self.layers,params_list):
            o = l((o,*params))
        return o

@gin.configurable(module=__name__)
class DenseNetProbPred(layers.Layer):
    def __init__(self,in_dim,out_dim,num_layers,dim,activation='relu',anp_style_sigma=False):
        super().__init__()
        self.layers = [
            MetaDense(dim,activation=activation)
            for _ in range(num_layers)
        ] + [MetaDense(out_dim*2)]

        #build network
        self.layers[0].build(in_dim)
        for l in self.layers[1:]: l.build(dim)

        self.anp_style_sigma = anp_style_sigma

    @property
    def params_list(self):
        return [l.weights for l in self.layers]

    def call(self, inputs):
        assert False, "You don't need to call this function"

    def call_with_params(self, x, params_list, raw=False):
        assert len(params_list) == len(self.layers), f'{len(params_list)} != {len(self.layers)}'
        o = x
        for l,params in zip(self.layers,params_list):
            o = l((o,*params))

        if raw:
            return o
        else:
            return self.make_dist(o)

    def make_dist(self, o):
        mu_y,sigma_y = tf.split(o,2,axis=-1) #[B,d_y],[B,d_y]

        if self.anp_style_sigma:
            sigma_y = 0.1 + 0.9 * tf.nn.softplus(sigma_y)
        else:
            sigma_y = tf.nn.softplus(tf.maximum(-15.,sigma_y))

        y_dist = tfd.MultivariateNormalDiag(mu_y,scale_diag=sigma_y)
        y_hat = y_dist.sample()

        return y_hat, y_dist


#! /usr/bin/env python
import matplotlib.pyplot as plt
from gmapsplot import GMapsPlot

center = (52.382882, -1.565237) # this will be the x,y origin
gmaps = GMapsPlot(api_key="GOOGLE_MAP_KEY", center=center, zoom=18, scale=1, size_meter=(200, 200))
gmaps.download()
fig, ax = gmaps.plot()
ax.scatter([-56, -36, 10, 30, 90], [-42, -30, 10, 30, 90], s=20)
plt.show()


from typing import Callable
from typing import Dict
from typing import Optional

class SerializerConfig:
    """
    Serializer configuration options.

    Some options are not applicable for both xml or json documents.

    :param encoding: Text encoding
    :param xml_version: XML Version number (1.0|1.1)
    :param xml_declaration: Generate XML declaration
    :param pretty_print: Enable pretty output
    :param pretty_print_indent: Indentation string for each indent level
    :param ignore_default_attributes: Ignore optional attributes with
        default values
    :param schema_location: xsi:schemaLocation attribute value
    :param no_namespace_schema_location: xsi:noNamespaceSchemaLocation
        attribute value
    :param globalns: Dictionary containing global variables to extend or
        overwrite for typing
    """

    __slots__ = (
        "encoding",
        "xml_version",
        "xml_declaration",
        "pretty_print",
        "pretty_print_indent",
        "ignore_default_attributes",
        "schema_location",
        "no_namespace_schema_location",
        "globalns",
    )

    def __init__(
        self,
        encoding: str = "UTF-8",
        xml_version: str = "1.0",
        xml_declaration: bool = True,
        pretty_print: bool = False,
        pretty_print_indent: Optional[str] = None,
        ignore_default_attributes: bool = False,
        schema_location: Optional[str] = None,
        no_namespace_schema_location: Optional[str] = None,
        globalns: Optional[Dict[str, Callable]] = None,
    ):
        self.encoding = encoding
        self.xml_version = xml_version
        self.xml_declaration = xml_declaration
        self.pretty_print = pretty_print
        self.pretty_print_indent = pretty_print_indent
        self.ignore_default_attributes = ignore_default_attributes
        self.schema_location = schema_location
        self.no_namespace_schema_location = no_namespace_schema_location
        self.globalns = globalns


import json
import textwrap
from collections import OrderedDict

from django import forms
from django.core.exceptions import ValidationError
from django.http import HttpRequest
from django.template.loader import get_template
from django.utils.translation import ugettext_lazy as _
from i18nfield.fields import I18nFormField, I18nTextarea
from i18nfield.strings import LazyI18nString

from pretix.base.models import OrderPayment
from pretix.base.payment import BasePaymentProvider

class Etherpay(BasePaymentProvider):
    identifier = 'etherpay'
    verbose_name = _('Etherpay')

    @property
    def settings_form_fields(self):
        return OrderedDict(list(super().settings_form_fields.items()) + [
            ('network_type', forms.ChoiceField(
                label=_('Ethereum network'),
                widget=forms.RadioSelect,
                choices=(
                    ('mainnet', _('Mainnet')),
                    ('ropsten', _('Ropsten (Testing only)')),
                    ('local', _('Local 7545 (Testing only)')),
                ),
                initial='mainnet',
                required=True
            )),
            ('contract_address', forms.CharField(
                label=_('Contract address'),
                widget=forms.TextInput,
                required=True
            )),
            ('contract_abi', forms.CharField(
                label=_('Contract ABI'),
                widget=forms.Textarea,
                required=True
            ))
        ])

    def payment_form_render(self, request) -> str:
        template = get_template('pretixplugins/etherpay/checkout_payment_form.html')
        ctx = {
            'request': request,
            'event': self.event,
            'settings': self.settings
        }
        return template.render(ctx)

    def checkout_prepare(self, request, total):
        return True

    def payment_prepare(self, request: HttpRequest, payment: OrderPayment):
        return True

    def payment_is_valid_session(self, request):
        return True

    def checkout_confirm_render(self, request):
        return self.payment_form_render(request)

    def payment_pending_render(self, request: HttpRequest, payment: OrderPayment):
        template = get_template('pretixplugins/etherpay/pending.html')
        ctx = {
            'event': self.event,
            'code': payment.order.full_code,
            'order': payment.order,
            'amount': payment.amount,
            'settings': self.settings
        }
        return template.render(ctx)

    def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
        template = get_template('pretixplugins/etherpay/control.html')
        ctx = {
            'request': request,
            'event': self.event,
            'code': payment.order.full_code,
            'payment_info': payment.info_data,
            'order': payment.order
        }
        return template.render(ctx)


from airflow import DAG
from airflow.decorators import task, dag

from datetime import datetime
import pandas as pd

@task
def extract():

    people = {
        'Firstnames': ['James','Corolla','Mark','Eddy'],
        'Lastnames': ['Wick','Leto','Smith','Etwan']
    }

    df = pd.DataFrame(people, columns = ['Firstnames', 'Lastnames'])
    #return df
    return people

@task
def process(value):
    print(f"Processing: {value}")

@dag(schedule_interval='@daily', start_date=datetime(2021, 1, 1), catchup=False)
def my_dag():

    value = extract()
    process(value)

dag = my_dag()