#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/8/18 19:23
# @Author  : hearecho
# @Site    :
# @File    : get_list.py
# @Software: PyCharm

import requests
from spider.yundownload.utils import headers,tools
import json
import time

def get_list():
    path = input("请输入路径:/*")
    encode_path = tools.encodeURIComponent(path)
    url = 'http://pan.baidu.com/api/list?dir={}' \
          '&num=100&order=time&desc=0&clienttype=0' \
          '&showempty=0&web=1&page=1'.format(encode_path)
    resp = requests.get(url,headers=headers.setheaders())
    print(resp.apparent_encoding)
    resp.encoding = resp.apparent_encoding
    resu_json = resp.json()
    print(json.dumps(resu_json,indent=2))

def get_item(fs_id):
    timestamp = int(time.time())
    fidlist = tools.encodeURIComponent("[{}]".format(fs_id))
    url = "http://pan.baidu.com/api/download?" \
          "sign=IVB6GC7Y665X6pNpiZz293vavj6qLsrdOFQtaJ8z4RNAUXReoQrjZA==" \
          "&timestamp={}" \
          "&fidlist={}".format(timestamp,fidlist)
    resp = requests.get(url,headers=headers.setheaders())
    resu_json = resp.json()
    print(json.dumps(resu_json, indent=2))
    print(url)

if __name__ == '__main__':
    get_list()


import sys
import logging
import datetime
from backend.block import operations
from scripts import witness_service

taskname = "witness schedule"
if __name__ == "__main__":

    try:
        if len(sys.argv) > 1:
            time_str = sys.argv[1]
            utc_date_time = datetime.datetime.strptime(time_str, "%Y-%m-%d")
        else:
            utc_date_time = datetime.datetime.now() - datetime.timedelta(days=1)
        witness_service.witness_services("make_witness_schedule", utc_date_time)
        logging.info('execute crontab [%s] success.', taskname)
    except Exception as e:
        logging.error('execute crontab [%s] error: %s', taskname, e)


# ECBM E4040 Final Project: WSAE-LSTM
# Author: Yifan Liu
# This is a utility function to help you download the dataset and preprocess the data we use for this homework.
# requires several modules: _pickle, tarfile, glob. If you don't have them, search the web on how to install them.
# You are free to change the code as you like.

# import modules
import os
import sys

import numpy as np
import pandas as pd

sys.path.append("../")

from src.models.stacked_auto_encoder import StackedAutoEncoder
from src.models.wavelet import wavelet_transform

# define training period as 24 months, validation as 3 months, and test as 3 months
NUM_TRAIN = 24
NUM_VAL = 3
NUM_TEST = 3

# # define absolute path
FEATURE_DIR = os.path.abspath(os.path.join(os.path.realpath(__file__), "../../../data"))

def min_max_scale(x, x_train):
    """
    Normalize the inputs data to range(0,1) for auto encoder.
    :arg x: inputs to conduct normalization
    :arg x_train: training data for min max calculation
    :return: normalized data
    """
    return (x - x_train.min(axis=0)) / (x_train.max(axis=0) - x_train.min(axis=0))

def generate_features(raw: pd.DataFrame, sheet_name):
    """
    Generate normalizaed, denoised and encoded features using normalization, wavelet transform and stacked auto-
    encoder.
    :arg raw: data frame contains the data
    :arg sheet_name: sheet name correspond to the raw args
    :return: None
    """

    # treat with messy data
    if sheet_name == 'DJIA index Data':
        raw.WVAD = np.where(raw.WVAD < -1e8, -1e8, raw.WVAD)

    if sheet_name == 'Nifty 50 index Data':
        raw.Ntime = raw.Date

    if sheet_name == 'CSI300 Index Data':
        raw.insert(0, 'Ntime', raw.Time)

    # use month to organize data slice
    month_lst = list(set(raw.Ntime // 100))
    month_lst.sort()

    def get_index(keys):
        ind_lst = []
        for key in keys:
            ind_lst.extend(index_dict[key])
        return ind_lst

    index_dict = dict()
    for month in month_lst:
        index_dict[month] = raw[raw.Ntime // 100 == month].index.to_list()

    save_dir = FEATURE_DIR + f'/interim/{sheet_name}'
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    for i in range(0, len(month_lst) - NUM_TRAIN - NUM_VAL - NUM_TEST + 3, 3):
        train_ind = get_index(month_lst[i:i + NUM_TRAIN])
        val_ind = get_index(month_lst[i + NUM_TRAIN:i + NUM_TRAIN + NUM_VAL])
        test_index = get_index(month_lst[i + NUM_TRAIN + NUM_VAL:i + NUM_TRAIN + NUM_VAL + NUM_TEST])

        save_dir = FEATURE_DIR + f'/interim/{sheet_name}/{month_lst[i + NUM_TRAIN + NUM_VAL]}'
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

        # save the second column 'closing price' as target for training LSTM and RNN

        x_train = raw.iloc[train_ind, 2:].values.astype(np.float32)
        y_train = raw.iloc[train_ind, 2].values.astype(np.float32)
        x_val = raw.iloc[val_ind, 2:].values.astype(np.float32)
        y_val = raw.iloc[val_ind, 2].values.astype(np.float32)
        x_test = raw.iloc[test_index, 2:].values.astype(np.float32)
        y_test = raw.iloc[test_index, 2].values.astype(np.float32)

        # inputs normalization

        x_train_n = min_max_scale(x_train, x_train)
        y_train_n = min_max_scale(y_train, y_train)
        x_val_n = min_max_scale(x_val, x_train)
        y_val_n = min_max_scale(y_val, y_train)
        x_test_n = min_max_scale(x_test, x_train)
        y_test_n = min_max_scale(y_test, y_train)

        # save normalized data to ./data/interim
        np.save(file=save_dir + '/X_train.npy', arr=x_train_n)
        np.save(file=save_dir + '/Y_train.npy', arr=y_train_n)
        np.save(file=save_dir + '/X_val.npy', arr=x_val_n)
        np.save(file=save_dir + '/Y_val.npy', arr=y_val_n)
        np.save(file=save_dir + '/X_test.npy', arr=x_test_n)
        np.save(file=save_dir + '/Y_test.npy', arr=y_test_n)

        # wavelet transformation
        x_train_nw = wavelet_transform(wavelet_transform(x_train_n))
        x_val_nw = wavelet_transform(wavelet_transform(x_val_n))
        x_test_nw = wavelet_transform(wavelet_transform(x_test_n))

        # save smoothed data to ./data/processed/wavelet
        save_dir = FEATURE_DIR + f'/processed/wavelet/{sheet_name}/{month_lst[i + NUM_TRAIN + NUM_VAL]}'
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

        np.save(file=save_dir + '/X_train.npy', arr=x_train_nw)
        np.save(file=save_dir + '/Y_train.npy', arr=y_train_n)
        np.save(file=save_dir + '/X_val.npy', arr=x_val_nw)
        np.save(file=save_dir + '/Y_val.npy', arr=y_val_n)
        np.save(file=save_dir + '/X_test.npy', arr=x_test_nw)
        np.save(file=save_dir + '/Y_test.npy', arr=y_test_n)

        sae = StackedAutoEncoder(layers=4,
                                 original_dim=x_train_n.shape[1],
                                 intermidiate_dim=10)
        sae.train_stacked_ae(inputs=x_train_n,
                             learning_rate=0.01,
                             n_epochs=20)

        x_train_ne = sae.encode(x_train_n)
        x_val_ne = sae.encode(x_val_n)
        x_test_ne = sae.encode(x_test_n)

        save_dir = FEATURE_DIR + f'/processed/sae/{sheet_name}/{month_lst[i + NUM_TRAIN + NUM_VAL]}'
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

        np.save(file=save_dir + '/X_train.npy', arr=x_train_ne)
        np.save(file=save_dir + '/Y_train.npy', arr=y_train_n)
        np.save(file=save_dir + '/X_val.npy', arr=x_val_ne)
        np.save(file=save_dir + '/Y_val.npy', arr=y_val_n)
        np.save(file=save_dir + '/X_test.npy', arr=x_test_ne)
        np.save(file=save_dir + '/Y_test.npy', arr=y_test_n)

        # train stacked autoencoder
        sae = StackedAutoEncoder(layers=4,
                                 original_dim=x_train_nw.shape[1],
                                 intermidiate_dim=10)
        sae.train_stacked_ae(inputs=x_train_nw,
                             learning_rate=0.01,
                             n_epochs=20)

        x_train_nwe = sae.encode(x_train_nw)
        x_val_nwe = sae.encode(x_val_nw)
        x_test_nwe = sae.encode(x_test_nw)

        save_dir = FEATURE_DIR + f'/processed/wsae/{sheet_name}/{month_lst[i + NUM_TRAIN + NUM_VAL]}'
        if not os.path.exists(save_dir):
            os.makedirs(save_dir)

        np.save(file=save_dir + '/X_train.npy', arr=x_train_nwe)
        np.save(file=save_dir + '/Y_train.npy', arr=y_train_n)
        np.save(file=save_dir + '/X_val.npy', arr=x_val_nwe)
        np.save(file=save_dir + '/Y_val.npy', arr=y_val_n)
        np.save(file=save_dir + '/X_test.npy', arr=x_test_nwe)
        np.save(file=save_dir + '/Y_test.npy', arr=y_test_n)
        print(f">>>>{month_lst[i + NUM_TRAIN + NUM_VAL]} finished!<<<<")

    print(">>>> Feature generation complete! <<<<")


#1356번
#https://www.acmicpc.net/problem/1356

N = int(input())
yes = 0

for i in range(1, len(N)):
  left = N[:i]
  right = N[i:]
  L = R = 1
  for j in left:
    L *= int(j)
  for k in right:
    R *= int(k)
  if L == R :
    yes = 1
    print("YES")
    break

if yes == 0:
  print("NO")


# -- python imports --
import numpy as np
from easydict import EasyDict as edict

# -- project imports --
from pyutils import create_named_meshgrid,np_log
from pretty_plots.stat_test_properties.misc import skip_with_endpoints

def create_standard_parameter_grid():
    pgrid = edict()

    start,end,size,base = 1,4,15,10
    D_exp = np.linspace(start,end,size)
    D = np.power([base],D_exp).astype(np.long) # np.linspace(3,128,10)**2
    D_tickmarks = np.linspace(start,end,end-start+1)
    D_tickmarks = skip_with_endpoints(D_tickmarks,1)
    D_ticks = np.power([base],D_tickmarks)
    D_tickmarks_str = ["%d" % x for x in D_tickmarks]

    start,end,size,base = -1,2,5,10
    mu2_exp = np.linspace(start,end,size)
    mu2 = np.power([base],mu2_exp) # [0,1e-6,1e-3,1e-1,1,1e1]
    mu2_tickmarks = np.linspace(start,end,end - start + 1)
    mu2_tickmarks = skip_with_endpoints(mu2_tickmarks,3)
    mu2_ticks = np.power([base],mu2_tickmarks)
    mu2_tickmarks_str = ["%d" % x for x in mu2_tickmarks]

    # start,end,size,base = -5,2,50,10
    start,end,size,base = 0,100,21,10
    #std_exp = np.linspace(start,end,size).astype(np.int)
    #std = np.power([base],std_exp) # [1e-6,1e-3,1e-1,1,1e1]
    std_exp = np.linspace(start,end,end - start + 1)
    std_exp = skip_with_endpoints(std_exp,len(std_exp)//size)
    std = std_exp
    std_tickmarks = np.linspace(start,end,end - start + 1)
    std_tickmarks = skip_with_endpoints(std_tickmarks,50)
    #std_ticks = np.power([base],std_tickmarks)
    std_ticks = std_tickmarks
    std_tickmarks_str = ["%d" % x for x in std_tickmarks]

    start,end = 3,50
    int_spacing = (end - start + 1)
    num = 5
    nframes = [3,10,50]
    #nframes = np.linspace(start,end,num).astype(np.long)
    # nframes = [3,18,34,50]
    #nframes_tickmarks = np.linspace(start,end,num)
    nframes_tickmarks = nframes
    nframes_ticks = np_log(nframes_tickmarks)/ np_log([10])
    nframes_tickmarks_str = ["%d" % x for x in nframes_tickmarks]

    size = [5000]

    params = [D,mu2,std,nframes,size]
    names = ['D','mu2','std','T','size']
    pgrid = create_named_meshgrid(params,names)
    print(f"Mesh grid created of size [{len(pgrid)}]")

    ticks = edict({'D':D_ticks,'mu2':mu2_ticks,
                   'std':std_ticks,'T':nframes_ticks})
    tickmarks = edict({'D':D_tickmarks,'mu2':mu2_tickmarks,
                       'std':std_tickmarks,'T':nframes_tickmarks})
    tickmarks_str = edict({'D':D_tickmarks_str,'mu2':mu2_tickmarks_str,
                           'std':std_tickmarks_str,
                           'T':nframes_tickmarks_str})
    logs = {'D':True,'mu2':True,'std':False,'T':False}
    # log_tickmarks = edict({'D':np_log(D_ticks),
    #                        'mu2':np_log(mu2_ticks),
    #                        'std':np_log(std_ticks)})
    lgrid = edict({'ticks':ticks,'tickmarks':tickmarks,
                   'tickmarks_str':tickmarks_str,'logs':logs})
                   #'log_tickmarks':log_tickmarks})

    return pgrid,lgrid


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

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation

class Parameter:
    def __init__(self, *args, **kwargs):

        if args and isinstance(args[0],Parameter):
            xb = args[0].xb
            xe = args[0].xe
            N = args[0].N
            dt = args[0].dt
            kappa = args[0].kappa

        elif kwargs :
            xb = kwargs['xb']
            xe = kwargs['xe']
            N = kwargs['N']
            dt = kwargs['dt']
            kappa = kwargs['kappa']

        self.xb = xb
        self.xe = xe
        self.N = N
        self.dx = (self.xe-self.xb)/float(self.N)
        self.dt = dt
        self.kappa = kappa
        self.cfl=1

class PDE(Parameter):
    """
    solves: u_t = \kappa \Delta u
    """
    def __init__(self, p ,t0 = 0.0):
        Parameter.__init__(self,p)
        self.kx = np.linspace(0,self.N/2,self.N/2+1)*2*np.pi/(self.xe-self.xb)
        self.kx2 = np.square(self.kx)

        self.x = self.xb + self.dx * np.arange(self.N)
        self.u = np.sin(self.x)
        self.uhat = np.fft.rfft(self.u)
        print(len(self.uhat))
        #self.u = np.piecewise(self.x, [np.abs(self.x-np.pi) < 0.01], [1])
        #self.u = np.sign(np.cos(self.x))
        self.t = t0

        self.scheme = self.heun

        # attributes used for dynamic plotting
        #  self.x_line = None
        #  self.u_line = None

    def time_step(self, Nsteps = 1):
        for i in range(Nsteps):
            self.scheme()
        self.u = np.fft.irfft(self.uhat)
        #print self.t, np.max(-np.fft.irfft(self.kx*1j*self.uhat))
        self.cfl = np.max(self.u)*self.dt/self.dx
        #print "cfl =",self.cfl
        self.t += self.dt * Nsteps

    def rhs(self, uhat):
        # aliasing
        uhat[int(2.*len(self.kx)/3.):len(self.kx)] = 0
        return  uhat - 0.5 * self.kx * 1j * np.fft.rfft(np.fft.irfft(uhat)**2)*self.dt

    def prop(self, delta):
        return np.exp(-self.kappa*self.dt*self.kx2*delta)

    def euler(self):
        self.uhat = self.rhs(self.uhat)*self.prop(1.)

    def heun(self):
        uone = self.rhs(self.uhat)*self.prop(1.)
        self.uhat = 0.5*(self.uhat*self.prop(1.) + self.rhs(uone))

    def shuOsher(self):
        uone =  self.rhs(self.uhat)*self.prop(1.)
        utwo = 3./4.*self.uhat*self.prop(0.5) + 1./4.*self.rhs(uone)*self.prop(-0.5)
        self.uhat = 1./3.*self.uhat*self.prop(1.) + 2./3.*self.rhs(utwo)*self.prop(0.5)

p = Parameter(xb=0,xe=2*np.pi,N=256,dt=0.01,kappa=0.02)

N_steps = 10
t_max = 100
frames = int(t_max / float(N_steps * p.dt))
frames = 500

pde = PDE(p)

def step():
    pde.time_step(N_steps)
    return np.array([pde.x, pde.u])

res = np.array([step() for _ in range(frames)])

######################################################################
# Set up plot
fig = plt.figure()
ax = plt.axes(xlim=(p.xb,p.xe), ylim=(-1.2, 1.2))
u_line, = ax.plot([], [],lw=2,marker='.',markerfacecolor='red', markersize=12)
time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
cfl_text = ax.text(0.02, 0.90, '', transform=ax.transAxes)
#ax.legend(prop=dict(size=14))
ax.set_xlabel('$x$')
ax.set_ylabel('$u$')

######################################################################
# Animate plot
def init():
    u_line.set_data([], [])

    time_text.set_text('')
    cfl_text.set_text('')
    return (u_line, time_text,cfl_text)

def integrate(i):
    #  pde.time_step(N_steps)
    u_line.set_data(res[i,0], res[i,1])

    #  time_text.set_text('time = %.2f' % pde.t)
    #  cfl_text.set_text('cfl = %.2f' % pde.cfl)
    #  return (u_line, time_text,cfl_text)
    return u_line,

anim = animation.FuncAnimation(fig, integrate, init_func=init, frames=frames,
                               interval=100, blit=True,repeat=False)

plt.show()


import matplotlib.pyplot as plt
import numpy as np
from dimensions import ureg
from fu_jet import Fu_Jet

# Film Jet is a type of Fu Jet that is used exclusively for
#   film cooling the wall of the combustion chamber.
# It extends the Fu_Jet class and adds in the property of
#   phase for the film cooling jet. This is a necessary
#   addition since film cooling utilizes liquid and gas
#   for creating a protective layer isolating the walls
#   from the combustion in the center of the chamber.
# Increased attention also needs to be paid to the heat
#   fluxes leaving the combustion area, since that will
#   determine the effectiveness of the film cooling.

# Film cooling jets will always run parallel with the chamber axis

class Film_Jet(Fu_Jet):
    def __init__(self, id_num, package):
        super().__init__(id_num, package)
        self.film_ring_dia_u = package['film_ring_dia_u']
        self.num_film = package['num_film']
        self.film_vel_u = package['film_vel_u']

    def set_origins(self):
        pos_x = (self.film_ring_dia_u / 2) * np.cos(self.id_num * (2 * np.pi / self.num_film))
        pos_y = (self.film_ring_dia_u / 2) * np.sin(self.id_num * (2 * np.pi / self.num_film))
        pos_z = 0 * ureg('meter')

        self.pos_vectors.append(np.array([pos_x.magnitude, pos_y.magnitude, pos_z.magnitude]))

    def set_initial_velocity(self):
        self.vel_vectors.append(np.array([0, 0, self.film_vel_u.magnitude]))


import openai
import pandas as pd
import argparse
import json
from collections import Counter
from tqdm import tqdm
import backoff
from openai.error import APIError, Timeout, APIConnectionError
import jsonlines
import random

@backoff.on_exception(backoff.expo, openai.error.RateLimitError)
def completions_with_backoff(**kwargs):
    return openai.ChatCompletion.create(**kwargs)

KNOWLEDGE_INSTRUCTIONS = {"nq": "Please answer the following questions using the shortest possible response. For example, if the question asks 'What is the capital of France?'', you can simply reply with 'Paris'.",
                          "fever": "Determine whether the following statement is true or false.",
                          "wow": "You have been provided with a chat history between two agents, separated by new lines. Generate a response that is informative and engaging based on the latest message."}

PROMPT_DICT = {
    "multi": (
        "You'll be provided with an instruction, along with evidence and possibly some preceding sentences. "
        "When there are preceding sentences, your focus should be on the sentence that comes after them. "
        "Your job is to determine if the evidence is relevant to the initial instruction and the preceding context, and provides useful information to complete the task described in the instruction. "
        "If the evidence meets this requirement, respond with [Relevant]; otherwise, generate [Irrelevant].\n\n"
        "###\nInstruction: Given four answer options, A, B, C, and D, choose the best answer.\n\n"
        "Input: Earth rotating causes\n"
        "A: the cycling of AM and PM\nB: the creation of volcanic eruptions\nC: the cycling of the tides\nD: the creation of gravity\n\n"
        "Evidence: Rotation causes the day-night cycle which also creates a corresponding cycle of temperature and humidity creates a corresponding cycle of temperature and humidity. Sea level rises and falls twice a day as the earth rotates.\n\n"
        "Rating: [Relevant]\n"
        "Explanation: The evidence explicitly mentions that the rotation causes a day-night cycle, as described in the answer option A.\n\n"
        "###\nInstruction: age to run for us house of representatives\n\n"
        "Evidence: The Constitution sets three qualifications for service in the U.S. Senate: age (at least thirty years of age); U.S. citizenship (at least nine years); and residency in the state a senator represents at the time of election.\n\n"
        "Rating: [Irrelevant]\n"
        "Explanation: The evidence only discusses the ages to run for the US Senate, not for the House of Representatives.\n\n"
        "###\nInstruction: {instruction}\n\n"
        "Evidence: {evidence}\n\n"
        "Rating:"
    ),
    "multi_no_preceding": (
        "You'll be provided with an instruction, along with evidence and possibly some preceding sentences. "
        "When there are preceding sentences, your focus should be on the sentence that comes after them. "
        "Your job is to determine if the evidence is relevant to the initial instruction and the preceding context, and provides useful information to complete the task described in the instruction. "
        "If the evidence meets this requirement, respond with [Relevant]; otherwise, generate [Irrelevant].\n\n"
        "###\nInstruction: Given four answer options, A, B, C, and D, choose the best answer.\n\n"
        "Input: Earth rotating causes\n"
        "A: the cycling of AM and PM\nB: the creation of volcanic eruptions\nC: the cycling of the tides\nD: the creation of gravity\n\n"
        "Evidence: Rotation causes the day-night cycle which also creates a corresponding cycle of temperature and humidity creates a corresponding cycle of temperature and humidity. Sea level rises and falls twice a day as the earth rotates.\n\n"
        "Rating: [Relevant]\n"
        "Explanation: The evidence explicitly mentions that the rotation causes a day-night cycle, as described in the answer option A.\n\n"
        "###\nInstruction: Describe a leader or a politician whom you admire. \n\n"
        "Preceding sentences: Leaders and politicians have the power to shape the course of history and impact the lives of countless individuals. Among the myriad of notable figures, Nelson Mandela stands as an exemplary leader whose indomitable spirit, unwavering commitment to justice, and remarkable ability to unite a divided nation have made him an admired and revered personality on a global scale. "
        "Evidence: Barack Obama was one of the most influential people of the world and the man with a difference. He has served as the President of the United States of America. He was the 44th President of America. He was elected in the year 2009 to the office of the President. He was the first-ever African-American President of America.\n\n"
        "Rating: [Irrelevant]\n"
        "Explanation: While the evidence discuss Barack Obama, who is known as an influential political leader, the preceding sentences describe Nelson Mandela, so this evidence doesn't provide useful information to generate an helpful continuation.\n\n"
        "###\nInstruction: {instruction}\n\n"
        "Evidence: {evidence}\n\n"
        "Rating:"
    ),
}

def load_jsonlines(file):
    with jsonlines.open(file, 'r') as jsonl_f:
        lst = [obj for obj in jsonl_f]
    return lst

def postprocess(results):
    raw_output = results["choices"][0]["message"]["content"]
    print(raw_output)
    if "\nExplanation:" in raw_output:
        explanation = raw_output.split("\nExplanation:")[1]
        if explanation[0] == " ":
            explanation = explanation[1:]
        score_string = raw_output.split("\nExplanation:")[0]
        score = None
        for i in range(1, 6):
            if str(i) in score_string:
                score = int(i)
        if score is None:
            return "", explanation
        else:
            return score, explanation
    else:
        return "", ""

def process_input(example, multi_retrieval=False):
    if multi_retrieval is False:
        return PROMPT_DICT["context"].format_map(example)
    else:
        if "sent_idx" not in example or example["sent_idx"] == 0 or len(example["preceding_sentences"]) == 0:
            return PROMPT_DICT["multi_no_preceding"].format_map(example)
        else:
            return PROMPT_DICT["multi"].format_map(example)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--input_files', type=str, nargs='+')
    parser.add_argument('--output_file_name', type=str)
    parser.add_argument('--multi_retrieval', action="store_true")
    parser.add_argument('--api_key', type=str)
    parser.add_argument('--org_name', type=str)
    parser.add_argument('--model_name', type=str, default="gpt-3.5-turbo")
    parser.add_argument('--n', type=int, default=None)
    args = parser.parse_args()

    with open(args.api_key) as f:
        openai.api_key = f.read()[:-1]
    openai.organization = args.org_name

    examples = []
    for input_file in args.input_files:
        if input_file.endswith(".json"):
            examples += json.load(open(input_file))
        else:
            examples += load_jsonlines(input_file)

    result_list = []
    if args.n is not None and len(examples) > args.n:
        examples = random.sample(examples, k=args.n)

    task_types = Counter([item["dataset_name"]
                         for item in examples if "dataset_name" in item])

    print(Counter(task_types))

    for idx, example in tqdm(enumerate(examples)):
        if "output" not in example and "answers" in example:
            example["output"] = example["answers"][0] if type(
                example["answers"]) is list else example["answers"]
        if "target_output" not in example and "output" in example:
            example["target_output"] = example["output"]
        if "instruction" not in example and "question" in example:
            data_type = example["q_id"].split("_")[0]
            if data_type in KNOWLEDGE_INSTRUCTIONS:
                example["instruction"] = KNOWLEDGE_INSTRUCTIONS[data_type] + \
                    example["question"]
            else:
                example["instruction"] = example["question"]
        if "As a language model, I cannot" in example["output"]:
            continue
        input = process_input(example, multi_retrieval=args.multi_retrieval)
        try:
            results = completions_with_backoff(
                model=args.model_name,
                messages=[
                    {"role": "user",
                        "content": input},
                ],
                request_timeout=60,
                max_tokens=200,
            )
            score, explanation = postprocess(results)
            result_list.append({"input": example, "score": score, "explanation": score,
                               "raw_output": results["choices"][0]["message"]["content"]})
            if idx % 20 == 0:
                print("Input: {}".format(example["instruction"]))
                print("Output: {}".format(example["output"]))
                print("Evidence: {}".format(example["evidence"]))
                print("Score: {0} ({1})".format(score, explanation))

        except (APIError, Timeout, APIConnectionError):
            results = "ERROR: API error outputs"
        if idx % 20 == 0:
            print("saved output at {}".format(args.output_file_name + "_tmp"))
            with open(args.output_file_name + "_tmp", "w") as outfile:
                json.dump(result_list, outfile)

    with open(args.output_file_name, "w") as outfile:
        json.dump(result_list, outfile)

if __name__ == "__main__":
    main()


import numpy as np

class LinUCB(object):
    def __init__(self, name, k, d, lambda_, arm_norm_bound, theta_norm_bound, delta, sigma_noise, color):
        self.name = name
        self.k = k
        self.d = d
        self.lambda_ = lambda_
        self.arm_norm_bound = arm_norm_bound
        self.theta_norm_bound = theta_norm_bound
        self.delta = delta
        self.sigma_noise = sigma_noise
        self.color = color

    def init(self):
        self.matrix = self.lambda_ * np.identity(self.d)
        self.b = np.zeros(self.d)
        self.t = 1
        # print('self.matrix:', self.matrix)
        # print('self.b:', self.b)

    def select_arm(self, arms):
        ucbs = np.zeros(self.k)
        inv_matrix = np.linalg.inv(self.matrix)
        estimated_theta = np.inner(inv_matrix, self.b)

        # beta sqrt
        # print('matrix_norm_temp_one:', matrix_norm_temp_one)
        # print('arm.arm_feature:', arm.arm_feature)
        # print('matrix_norm_temp_two:', matrix_norm_temp_two)
        molecule_term = 1 + self.t * self.arm_norm_bound ** 2 / self.lambda_
        exponent_term = molecule_term / self.delta
        log_term = np.log(exponent_term)
        square_term = self.d * log_term
        sqrt_term = np.sqrt(square_term)
        beta_first_term = self.sigma_noise * sqrt_term
        beta_second_term = np.sqrt(self.lambda_) * self.theta_norm_bound
        beta_sqrt = beta_first_term + beta_second_term
        for (i, arm) in enumerate(arms):
            # estimated reward
            estimated_reward = np.inner(arm.arm_feature, estimated_theta)

            # alpha
            # norm term
            matrix_norm_temp_one = np.dot(arm.arm_feature, inv_matrix)
            matrix_norm_temp_two = np.inner(matrix_norm_temp_one, arm.arm_feature)
            matrix_norm = np.sqrt(matrix_norm_temp_two)

            # alpha
            alpha = beta_sqrt * matrix_norm

            # ucb
            ucb = estimated_reward + alpha
            ucbs[i] = ucb
        # print('ucbs:', ucbs)
        mixer = np.random.random(self.k)
        ucb_indices = list(np.lexsort((mixer, ucbs)))
        ucb_indices_reverse = ucb_indices[::-1]
        choice = ucb_indices_reverse[0]
        # print('choice:', choice)
        return choice

    def update(self, chosen_arm, round_reward):
        arm_feature = chosen_arm.arm_feature
        matrix_addition = np.outer(arm_feature, arm_feature)
        self.matrix += matrix_addition
        b_addition = round_reward * arm_feature
        self.b += b_addition
        self.t += 1


#!/usr/bin/env python3

#
# Usage: see lc0_graph_activations.py --help
#

import chess
import chess.pgn
import chess.uci
import chess.svg
import re
import matplotlib.pyplot as plt
import matplotlib.axes
import pandas as pd
import numpy as np
import os
import math
import argparse
from collections import OrderedDict
import svgutils.transform as sg
from svgutils.compose import *
import sys
#import cairosvg

COLS = 32
ROWS = 8

DIR_VECTORS = {'N': (0, 1), 'NE': (1, 1), 'E': (1, 0), 'SE': (1, -1),
        'S':(0, -1), 'SW':(-1, -1), 'W': (-1, 0), 'NW': (-1, 1)}

KNIGHT_DIR_VECTORS = {'N': (1, 2), 'NE': (2, 1), 'E': (2, -1), 'SE': (1, -2),
        'S':(-1, -2), 'SW':(-2, -1), 'W': (-2, 1), 'NW': (-1, 2)}

LOCMAP = []

for direction in ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']:
    for steps in range(1, 8):
        x, y = DIR_VECTORS[direction]
        x *= steps
        y *= steps
        #print(len(LOCMAP), "normal", direction, x, y)
        LOCMAP.append((x, y))

for direction in ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']:
    x, y = KNIGHT_DIR_VECTORS[direction]
    #print(len(LOCMAP), "knight", direction, x, y)
    LOCMAP.append((x,y))

LOCMAP.extend([(-5,8),(-4,8),(-3,8), (-1,8),(0,8),(1,8), (3,8),(4,8),(5,8)])

def plot(data, layernum, board):
    if len(data) == 80:
        fig, ax = plt.subplots(16, 15, figsize=(15*2,16*2), subplot_kw={'title':"", 'xticks':[], 'yticks':[]}, frameon=False)
        for e, d in enumerate(data):
            if e >= len(LOCMAP): break
            # Data in logfile has side to move going down the board,
            # so flip vertically.
            d = np.flip(d, 0)
            x, y = LOCMAP[e]
            x += 7
            y = -y + 8
            #ax[y, x].imshow(d, norm=matplotlib.colors.SymLogNorm(linthresh=0.03, linscale=0.03, vmin=-50, vmax=50))
            ax[y, x].imshow(d, norm=matplotlib.colors.SymLogNorm(linthresh=0.03, linscale=0.03, vmin=-1, vmax=1))
            #ax[y, x].imshow(d, vmin=0, vmax=1)
            #ax[y, x].imshow(d, norm=matplotlib.colors.Normalize(vmin=0., vmax=1.))
            ax[y, x].get_xaxis().set_visible(False)
            ax[y, x].get_yaxis().set_visible(False)
        #plt.tight_layout(w_pad=0.01, h_pad=0.01)
        filename = "%s/activation_layer_%03d.png" % (args.savedir, layernum)
        plt.savefig(filename, transparent=True)
        plt.close("all")
        print("saved " + filename)
    else:
        fig, ax = plt.subplots(ROWS, COLS, figsize=(32,8), subplot_kw={'title':"", 'xticks':[], 'yticks':[]}, frameon=False)
        for e, d in enumerate(data):
            # Data in logfile has side to move going down the board,
            # so flip vertically.
            d = np.flip(d, 0)
            #ax[e//COLS, e%COLS].imshow(d, norm=matplotlib.colors.SymLogNorm(linthresh=0.03, linscale=0.03, vmin=-50, vmax=50))
            ax[e//COLS, e%COLS].imshow(d, norm=matplotlib.colors.SymLogNorm(linthresh=0.03, linscale=0.03, vmin=-1, vmax=1))
            #ax[e//COLS, e%COLS].imshow(d, vmin=0, vmax=1)
            ax[e//COLS, e%COLS].get_xaxis().set_visible(False)
            ax[e//COLS, e%COLS].get_yaxis().set_visible(False)
        plt.tight_layout(w_pad=0.01, h_pad=0.01)
        filename = "%s/activation_layer_%03d.png" % (args.savedir, layernum)
        plt.savefig(filename, transparent=True)
        plt.close("all")
        print("saved " + filename)

def parse():
    alldata = []
    layernum = 0
    board = chess.Board()
    if not os.path.exists(args.savedir):
        os.makedirs(args.savedir)
    for line in open(args.logfile).readlines():
        m = re.search(">> position startpos", line)
        if m:
            m = re.search(">> (position startpos moves .*)", line)
            if m:
                ucipos = m.group(1)
            else:
                ucipos = "position startpos"
            f = open("%s/activation_game.txt" % (args.savedir), "w")
            for m in ucipos.split()[3:]:
                board.push_uci(m)
            f.write(str(chess.pgn.Game.from_board(board)) + "\n")
            f.write(str(ucipos) + "\n")
            f.write(str(board.fen()) + "\n")
            f.write(str(board) + "\n")
            f.close()
        data = line.split()
        if len(data) == 0 or not data[0].startswith("channel:"): continue
        _,channel_num = data[0].split(":")
        channel_num = int(channel_num)
        if channel_num == 0 and len(alldata) > 0:
            plot(alldata, layernum, board)
            alldata = []
            layernum += 1
        data = [float(x) for x in data[1:]]
        alldata.append(np.array(data).reshape((8,8)))
    plot(alldata, layernum, board)

if __name__ == "__main__":
    usage_str = """
lc0_graph_activations.py lc0log_mypos.txt activations_mypos

This script parses a logfile generated using a special lc0 binary that dumps
activation data of the NN. It outputs a text file of the position, and images
of the activations for every layer of the NN.

To generate a logfile:
* `git clone -b nndebug http://github.com/killerducky/lc0`
* Build lc0
* Run lc0 with Backend=blas, and LogFile=lc0log_mypos.txt
* setposition you want to analyze
  * currently script assumes there is only 1 position!
  * fens won't work right now, only full setposition
* go nodes 1 (it's important the NN only analyzes one position)
* quit lc0
* Now you can run this script on lc0log_mypos.txt

Side to move is always going up in these images.

Output files generated:

activation_game.txt - pgn, uci, fen, and ascii board
activation_layer_000.png - Inputs:
    For 8 plies of hisory, most recent first:
        Our     P, N, B, R, Q, K
        Their   P, N, B, R, Q, K
        Repetition plane
    We can O-O-O
    We can O-O
    They can O-O-O
    They can O-O
    We are Black
    50 move rule counter
    Unused (used to be move count)
    Plane of 1s
activation_layer_001.png - Output of input convolution
activation_layer_002.png - Output of 1st resblock, first half
activation_layer_003.png - Output of 1st resblock, second half
...
activation_layer_040.png - Output of 20th resblock, second half
activation_layer_041.png - Output of 20th resblock, second half
activation_layer_042.png - Output of Policy FC layer (T50 convolutional Policy will have two convolves instead)
(Final Policy move selection not supported yet)
"""

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=usage_str)
    parser.add_argument("logfile", type=str, help="logfile to parse")
    parser.add_argument("savedir", type=str, help="directory to put files")

    args = parser.parse_args()
    print(args.logfile)
    parse()


#고장난 컴퓨터
#문제
#https://level.goorm.io/exam/49095/%EA%B3%A0%EC%9E%A5%EB%82%9C-%EC%BB%B4%ED%93%A8%ED%84%B0/quiz/1

n, delay = map(int,input().split(' '))
times = input().split(' ')

for i in range(n):
    times[i] = int(times[i])

cnt = 1
for i in range(n-1):
    if times[i+1] - times[i] <= delay:
        cnt += 1
    else:
        cnt = 1

print(cnt)


import numpy as np
import random

def train(sortedigs, train_examples, lnorm, howmany = 200, trainsize = 100):
    w = []
    for i in range(howmany):
        w.append(random.random())
    s = 0
    e = 0.1
    swanted = 420
    count = 0
    while(s < swanted):
        count  += 1
        s = 0
        probs = []
        for j in range(trainsize):
            L = 0
            for i in range(howmany):
                prob = predict(w, train_examples[j], sortedigs)
                probs.append(prob)
                if(train_examples[j][-1]):
                    L += prob + 1/trainsize
                else:
                    L += (1 - prob) + 1/trainsize
            L = np.log(L)
            summ = 0
            for i in w:
                summ += i * i
            L = L - lnorm * summ
            s += L
            for i in range(howmany):
                if(train_examples[j][-1]):
                    y = 1
                else:
                    y = 0
                if sortedigs[i][0] in train_examples[j]:
                    x = 1 - 1/trainsize
                else:
                    x = 1/trainsize
                w[i] = w[i] + e * (1 / (x * (y - probs[i] + 1 / trainsize))) * (y - probs[i]) * x - 2 * lnorm * w[i]
        e *= 0.8
        if(count > 10):
            break
    return w

def predict(w, x, sortedigs):
    t = 0
    for i in range(len(w)):
        if(sortedigs[i][0] in x): #word
            t += w[i]
    prob = 1 / (1 + np.exp(-t))
    return prob


import json
import operator
import io

f = open(r'G:\twitter\Twitter\user-tweet-similar.json')
df =json.loads(f.read())
#user_tweet = df['user_tweet']

g = open(r'G:\twitter\Twitter\graph\nodes.json')
dg = json.loads(g.read())
nodes = dg['nodes']
#print(nodes)
d = dict()

fun = operator.itemgetter('id')
l = list()
for u in df:
    #r=str(u).lstrip()
    for su in df[u]:
        #t=str(su).lstrip()
        l.append(dict(source= map(fun,nodes).index(u),target=map(fun,nodes).index(su)))

d['links']=l
with open('link-ut-sim.json','w')as jj:
    json.dump(d,jj)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 30 09:20:49 2018

@author: gjacopo
"""

#%%
from __future__ import print_function

import os, re#analysis:ignore
import warnings
from operator import itemgetter

try:
    import numpy as np#analysis:ignore
except ImportError:
    raise IOError("Package numpy not imported - Requested")

try:
    import pandas as pd
    PDVERS = int(pd.__version__.split('.')[1])
except ImportError:
    PDVERS = 0 # unknown
    raise IOError("Package pandas not imported - Requested")

try:
    import networkx as nx
except ImportError:
    raise IOError("Package networkx not imported - Requested")

try:
    import json
except:
    try:
        import simplejson as json#analysis:ignore
    except:
        warnings.warn("Package simplejson/json not imported")

import metadata

#%%
#==============================================================================
# CHORD FUNCTIONS
#==============================================================================

def __filedirexists(file):
    return os.path.exists(os.path.abspath(os.path.dirname(file)))

def data2adjacency(df):
    df_unique = df.drop_duplicates([metadata.INDICATOR, metadata.DIMENSION])
    # df_test = df_unique.pivot(index='indicator', columns='dimension', values='label')
    df_unique.drop(columns=metadata.LABEL)
    df_cross = pd.crosstab(df_unique[metadata.INDICATOR], df_unique[metadata.DIMENSION])
    df_cross['dumb'] = 0
    df_cross = df_cross.T
    df_cross['dumber'] = 0
    df_cross.loc['dumb','dumber'] = -1
    df_crossT = df_cross
    df_cross = df_crossT.T
    # note that at this stage, indicators and dimensions are reordered
    #a dimensions, indicators = df_cross.index.tolist(), df_cross.columns.tolist()
    indicators, dimensions = df_cross.index.tolist(), df_cross.columns.tolist()
    # df_crossT = df_cross.T

    #idx = indicators + dimensions
    idx = dimensions + indicators
    df_cross = df_cross.reindex(index = idx, columns = idx, fill_value=0)
    df_crossT = df_crossT.reindex(index = idx, columns = idx, fill_value=0)

    return [dimensions, indicators, pd.DataFrame(df_cross.values | df_crossT.values, index = idx, columns = idx)]
    # note: df_cross | df_crossT generates a NotImplementedError error type

def meta2cross(df, cross=None):
    idx = {0: [], 1: []}
    if not cross in ([],None):
        if not isinstance(cross, (list,tuple)) or len(cross)!=2:
            cross = [cross,]
        for i in [0,1]:
            if cross[i] in ([],None):   break
            regexp = '|'.join(cross[i])
            _idx = df.loc[df[metadata.INDICATOR].str.contains(regexp, regex=True)].index.tolist()
            idx[i] = idx[i] + _idx
    if not all([_idx in ([],None) for _idx in idx.values()]):
        index = idx[0] + idx[1]
    else:
        idx[0] = idx[1] = df.index
        index = df.index
    ## two rounds of drop_duplicates to keep only non-unique (DIMENSION,LABEL) pairs
    #df1 = df.drop_duplicates(subset=[metabase.DIMENSION, metabase.LABEL])
    #df2 = df.loc[(df.index).difference(df1.index)]
    #uni_index = df2.drop_duplicates(subset=[metabase.DIMENSION, metabase.LABEL]).index
    ## note also:
    #df_group = df.groupby(by=[metabase.DIMENSION, metabase.LABEL])
    #df_dimlab = df_group.count()
    ## keep only non-unique (DIMENSION,LABEL) pairs
    #df_dimlab = df_dimlab[df_dimlab[metabase.INDICATOR] > 1]

    df_cross = pd.pivot_table(df, index=[metadata.DIMENSION, metadata.LABEL], columns=[metadata.INDICATOR], aggfunc=len, fill_value=0)
    df_cross = df_cross.T.dot(df_cross)
    # # alternative solution
    # df['value'] = 1
    # df1 = pd.pivot_table(df, index=[metabase.DIMENSION, metabase.LABEL], values='value', columns=metabase.INDICATOR, fill_value=0)
    np.fill_diagonal(df_cross.values, 0)

    #s = df_cross.sum(axis=0)
    #index = s[s != 0].index.tolist()
    df_cross.reindex(index = index, columns = index, fill_value=0)

    return [df.ix[pd.Index(idx[0]),metadata.INDICATOR].unique().tolist(),
            df.ix[pd.Index(idx[1]),metadata.INDICATOR].unique().tolist(),
            df_cross]

def adjacency2edges(df, ind0, ind1):
    #g = nx.from_pandas_adjacency(df.loc[ind0].T.loc[ind1].T)
    # adjacency matrix needs to be square
    df_adj = df.copy()
    df_adj.loc[ind0] = 0
    df_adj = df_adj.T
    df_adj.loc[pd.Index(ind1)] = 0
    df_adj = df_adj.T
    g = nx.from_pandas_adjacency(df_adj)
    edges = sorted([(s, t, w['weight']) for (s, t, w) in g.edges(data=True)], key=itemgetter(2), reverse=True)
    df_edges = pd.DataFrame(edges, columns=("source","target","value"))
    return df_edges

def adjacency2json(df_adjacency, **kwargs):
    dimensions, indicators = kwargs.pop('dim',[]), kwargs.pop('ind',[])
    odir, ofmt = kwargs.pop('odir','.'), kwargs.pop('ofmt','json')
    oifn, odfn = kwargs.pop('oifn', metadata.INDICATOR), kwargs.pop('odfn', metadata.DIMENSION)
    oixdfn = kwargs.pop('oixdfn','%sx%s' % (metadata.INDICATOR, metadata.DIMENSION))

    ofn = '%s/%s.%s' % (odir, oixdfn, ofmt)
    if __filedirexists(ofn):
        with open(ofn, 'w') as f:
            #s = str(df_adjacency.values.tolist())
            #f.write('var matrix = %s;' % s.replace('-1','emptyStroke'))
            f.write('var matrix = %s;' % df_adjacency.values.tolist())
    #df_adjacency.to_json('%s/%s.%s' % (odir, oixdfn, ofmt), orient='split')
    #with open('%s/%s.%s' % (odir, oixdfn, ofmt), 'w') as f:
    #    json.dump(df_adjacency.values.tolist())

    ofn = '%s/%s.%s' % (odir, odfn, ofmt)
    if __filedirexists(ofn) and dimensions is not None:
        with open(ofn, 'w') as f:
            # json.dump('var %s = %s;' % (DIMENSION,dimensions), f)
            s = str(dimensions)
            #a: f.write('var Dimension = %s;' % s.replace('dumber',''))
            f.write('var Dimension = %s;' % s.replace('dumb',''))

    ofn = '%s/%s.%s' % (odir, oifn, ofmt)
    if __filedirexists(ofn) and indicators is not None:
        with open(ofn, 'w') as f:
            # json.dump({INDICATOR:indicators}, f)
            s = str(indicators)
            # a: f.write('var Indicator = %s;' % s.replace('dumb',''))
            f.write('var Indicator = %s;' % s.replace('dumber',''))


"""
We have a big list having values fom 1 to n, occurring only once but unordered with an unknown amount of
missing values. The number n will be considered the maximum value of the array.

We have to output the missing numbers sorted by value. Example:
[8, 10, 11, 7, 3, 15, 6, 1, 14, 5, 12]  ---> [2, 4, 9, 13]

The number 1 should be in the input array, if it's not present in the input array, should be included in
the results. See the example below.
[8, 10, 11, 7, 3, 15, 6, 14, 5, 12]  ---> [1, 2, 4, 9, 13]

As this is a hardcore version, the tests are prepared for only algorithms of time complexityO(n) to pass. As the speed of each language are different, we will have different maximum lengths for the input.

Features of the random tests:
1000 <= length of arrays <= 4.000.000
1 <= amount of missing  numbers <= 10
amount of tests: 20

"""

def miss_nums_finder(arr):
    result = []
    n = max(arr)
    arr = arr + [arr[0]]*(n - len(arr))

    for num in arr:
        arr[abs(num)-1] = -1 * abs(arr[abs(num)-1])

    for i in range(0, len(arr)):
        if arr[i] > 0:
            result.append(i+1)

    return result

print(miss_nums_finder([8, 10, 11, 7, 3, 15, 6, 14, 5, 12]))

"""
better solution from codewars

def miss_nums_finder(arr):
    mx = max(arr)
    s  = set(arr)
    return [x for x in range(1,mx) if x not in s]
"""


from django.shortcuts import render
from django.http import HttpResponse
#from rest_framework.decorators import api_view
#from rest_framework.response import Response
from django.views.generic import TemplateView
from django.http import FileResponse

global ready
ready = False

class indexView(TemplateView):
    template_name = 'index.html'

def pageLoaded(res):
    res = HttpResponse("?")
    global ready
    ready = False

    return res

def image(res, id):
    img_url = 'app/img/' + str(id) + '.jpg'
    img = open(img_url, 'rb')
    res = FileResponse(img)

    return res

def machine_ready(res):
    global ready
    print(ready)
    if(ready):
        res = HttpResponse("yes")
    else:
        res = HttpResponse("no!")

    return res

def ready_from_backend(res):
    res = HttpResponse("?")

    global ready
    ready = True
    return res


from monai.data import ImageDataset, decollate_batch, DataLoader
from monai.inferers import sliding_window_inference
from monai.metrics import DiceMetric
from monai.transforms import Activations, EnsureChannelFirst, AsDiscrete, Compose, RandRotate90, RandSpatialCrop, ScaleIntensity, CenterSpatialCrop
import numpy as np
import torch
from torchmetrics.classification import Recall
import utils
import blob_detection as blob

def test(model, val_loader, dataset_name, modalities, net, device, modalities_present_at_training, save_outputs, save_path="/home/sedm2651/", detect_blobs=False):
  cropped_input_size = [128,128,128]
  dice_metric = DiceMetric(include_background=True, reduction="mean", get_not_nans=False)
  post_trans = Compose([Activations(sigmoid=True), AsDiscrete(threshold=0.5)])

  with torch.no_grad():
    recall = Recall('binary').to(device)
    recall_total = 0.

    val_images = None
    val_labels = None
    val_outputs = None
    steps = 0

    dice_metric.reset()

    detected = []
    undetected = []
    det_seg_sizes = []
    undet_seg_sizes = []
    dice_metrics = []
    segment_pixel_vol = []
    gt_pixel_vol = []
    segmented_num_over_thresh = 0
    segmented_are_lesions = 0

    for val_data in val_loader:

      roi_size = (cropped_input_size[0], cropped_input_size[1], cropped_input_size[2])
      sw_batch_size = 1

      if net.net_type == "UNet" or net.net_type == "UNetv2":
        val_data[0] = utils.create_UNET_input(val_data, modalities, dataset_name, net, modalities_present_at_training)
      else:
        val_data[0] = val_data[0][:,modalities,:,:,:]

      val_images, val_labels = val_data[0].to(device), val_data[1].to(device)
      val_outputs = sliding_window_inference(val_images, roi_size, sw_batch_size, model)
      val_outputs = [post_trans(i) for i in decollate_batch(val_outputs)]

      if save_outputs:
        file_save_path = save_path + str(steps) + ".nii.gz"
        utils.save_nifti(val_outputs[0], file_save_path)

      # compute metric for current iteration
      current_dice = dice_metric(y_pred=val_outputs, y=val_labels)
      # dice_metrics.append(float(current_dice.cpu().detach()))
      pixels_segmented = np.count_nonzero(val_outputs[0])
      # print(pixels_segmented)
      gt_segmented = np.count_nonzero(val_labels[0])
      # print("Segmtentation results:")
      # print(current_dice)
      # print(pixels_segmented)
      # print(gt_segmented)
      segment_pixel_vol.append(pixels_segmented)
      gt_pixel_vol.append(gt_segmented)

      if detect_blobs:
        [det, undet, det_seg_size, undet_seg_size] = blob.detect_blobs(val_labels[0], val_outputs[0])
        [out_segmented_are_lesions,out_segmented_num_over_thresh] = blob.count_over_thresh(val_labels[0],val_outputs[0])
        detected = detected + det
        undetected = undetected + undet
        det_seg_sizes = det_seg_sizes + det_seg_size
        undet_seg_sizes = undet_seg_sizes + undet_seg_size
        segmented_are_lesions += out_segmented_are_lesions
        segmented_num_over_thresh += out_segmented_num_over_thresh

      # print(float(current_dice))
      current_recall = float(recall(val_outputs[0],val_labels[0]).cpu().detach())
      recall_total += current_recall
      # print(current_recall)
      steps+=1

    # aggregate the final mean dice result
    metric = dice_metric.aggregate().item()

    print("DICE Metric:")
    print(metric)

    # print("Averge Recall:")
    # print(recall_total/steps)

    print("Num comps in seg over thresh ", segmented_num_over_thresh)
    print("Num comps over thresh are lesions ", segmented_are_lesions)

    if detect_blobs:
      blob.plot_hist(detected, undetected)

    # print("Mean pixels segmented:")
    # print(np.mean(segment_pixel_vol))

    # reset the status for next validation round
    dice_metric.reset()
    return dice_metrics, segment_pixel_vol, gt_pixel_vol, detected, undetected, det_seg_sizes, undet_seg_sizes


import numpy as np
import warnings
import pandas as pd

from ... import utils

from .sampler import register_sampler
from .. import InitialBinaryTable
from ... import _evolvebin

__author__ = "Katelyn Breivik <katie.breivik@gmail.com>"
__credits__ = ("Scott Coughlin <scott.coughlin@ligo.org>, Michael Zevin <michael.j.zevin@gmail.com>, "
               "Tom Wagg <tomjwagg@gmail.com>")
__all__ = ["get_independent_sampler", "Sample"]

def get_independent_sampler(
    final_kstar1,
    final_kstar2,
    primary_model,
    ecc_model,
    porb_model,
    SF_start,
    SF_duration,
    binfrac_model,
    met,
    size=None,
    total_mass=np.inf,
    sampling_target="size",
    trim_extra_samples=False,
    **kwargs
):
    """Generates an initial binary sample according to user specified models

    Parameters
    ----------
    final_kstar1 : `int or list`
        Int or list of final kstar1

    final_kstar2 : `int or list`
        Int or list of final kstar2

    primary_model : `str`
        Model to sample primary mass; choices include: kroupa93, kroupa01, salpeter55, custom
        if 'custom' is selected, must also pass arguemts:
        alphas : `array`
            list of power law indicies
        mcuts : `array`
            breaks in the power laws.
        e.g. alphas=[-1.3,-2.3,-2.3],mcuts=[0.08,0.5,1.0,150.] reproduces standard Kroupa2001 IMF

    ecc_model : `str`
        Model to sample eccentricity; choices include: thermal, uniform, sana12

    porb_model : `str`
        Model to sample orbital period; choices include: log_uniform, sana12, raghavan10, moe19

    qmin : `float`
        kwarg which sets the minimum mass ratio for sampling the secondary
        where the mass ratio distribution is flat in q
        if q > 0, qmin sets the minimum mass ratio
        q = -1, this limits the minimum mass ratio to be set such that
        the pre-MS lifetime of the secondary is not longer than the full
        lifetime of the primary if it were to evolve as a single star

    m_max : `float`
        kwarg which sets the maximum primary and secondary mass for sampling
        NOTE: this value changes the range of the IMF and should *not* be used
            as a means of selecting certain kstar types!

    m1_min : `float`
        kwarg which sets the minimum primary mass for sampling
        NOTE: this value changes the range of the IMF and should *not* be used
            as a means of selecting certain kstar types!

    m2_min : `float`
        kwarg which sets the minimum secondary mass for sampling
        the secondary as uniform in mass_2 between m2_min and mass_1

    msort : `float`
        Stars with M>msort can have different pairing and sampling of companions

    qmin_msort : `float`
        Same as qmin for M>msort

    m2_min_msort : `float`
        Same as m2_min for M>msort

    SF_start : `float`
        Time in the past when star formation initiates in Myr

    SF_duration : `float`
        Duration of constant star formation beginning from SF_Start in Myr

    binfrac_model : `str or float`
        Model for binary fraction; choices include: vanHaaften or a fraction where 1.0 is 100% binaries

    binfrac_model_msort : `str or float`
        Same as binfrac_model for M>msort

    met : `float`
        Sets the metallicity of the binary population where solar metallicity is zsun

    size : `int`
        Size of the population to sample

    total_mass : `float`
        Total mass to use as a target for sampling

    sampling_target : `str`
        Which type of target to use for sampling (either "size" or "total_mass"), by default "size".
        Note that `total_mass` must not be None when `sampling_target=="total_mass"`.

    trim_extra_samples : `str`
        Whether to trim the sampled population so that the total mass sampled is as close as possible to
        `total_mass`. Ignored when `sampling_target==size`.
        Note that given the discrete mass of stars, this could mean your sample is off by 300
        solar masses in the worst case scenario (of a 150+150 binary being sampled). In reality the majority
        of cases track the target total mass to within a solar mass.

    zsun : `float`
        optional kwarg for setting effective radii, default is 0.02

    Returns
    -------
    InitialBinaryTable : `pandas.DataFrame`
        DataFrame in the format of the InitialBinaryTable

    mass_singles : `float`
        Total mass in single stars needed to generate population

    mass_binaries : `float`
        Total mass in binaries needed to generate population

    n_singles : `int`
        Number of single stars needed to generate a population

    n_binaries : `int`
        Number of binaries needed to generate a population
    """
    if sampling_target == "total_mass" and (total_mass is None or total_mass == np.inf):
        raise ValueError("If `sampling_target == 'total mass'` then `total_mass` must be supplied")
    if size is None and (total_mass is None or total_mass == np.inf):
        raise ValueError("Either a sample `size` or `total_mass` must be supplied")
    elif size is None:
        size = int(total_mass)

    if binfrac_model == 0.0 and sampling_target == "size":
        raise ValueError(("If `binfrac_model == 0.0` then `sampling_target` must be 'total_mass'. Otherwise "
                          "you are targetting a population of `size` binaries but will never select any."))

    final_kstar1 = [final_kstar1] if isinstance(final_kstar1, (int, float)) else final_kstar1
    final_kstar2 = [final_kstar2] if isinstance(final_kstar2, (int, float)) else final_kstar2
    primary_min, primary_max, secondary_min, secondary_max = utils.mass_min_max_select(
        final_kstar1, final_kstar2, **kwargs)
    initconditions = Sample()

    # set up multiplier if the mass sampling is inefficient
    multiplier = 1

    # track samples to actually return (after masks)
    mass1_singles = []
    mass1_binary = []
    mass2_binary = []
    binfrac = []

    # track the total mass of singles and binaries sampled
    m_sampled_singles = 0.0
    m_sampled_binaries = 0.0

    # track the total number of stars sampled
    n_singles = 0
    n_binaries = 0

    # if porb_model = `moe19`, the binary fraction is fixed based on the metallicity
    if porb_model == "moe19":
        binfrac_model = utils.get_met_dep_binfrac(met)
        warnings.warn('your supplied binfrac_model has been overwritten to {} match Moe+2019'.format(binfrac_model))

    # define a function that evaluates whether you've reached your sampling target
    target = lambda mass1_binary, size, m_sampled_singles, m_sampled_binaries, total_mass:\
        len(mass1_binary) < size if sampling_target == "size" else m_sampled_singles + m_sampled_binaries < total_mass

    # sample until you've reached your target
    while target(mass1_binary, size, m_sampled_singles, m_sampled_binaries, total_mass):
        # sample primary masses
        mass1, _ = initconditions.sample_primary(primary_model, size=int(size * multiplier), **kwargs)

        # split them into binaries or single stars
        (mass1_binaries, mass_single, binfrac_binaries, binary_index,
        ) = initconditions.binary_select(mass1, binfrac_model=binfrac_model, **kwargs)

        # sample secondary masses for the single stars
        mass2_binaries = initconditions.sample_secondary(mass1_binaries, **kwargs)

        # check if this batch of samples will take us over our sampling target
        if not target(mass1_binary, size,
                      m_sampled_singles + np.sum(mass_single),
                      m_sampled_binaries + np.sum(mass1_binaries) + np.sum(mass2_binaries),
                      total_mass) and trim_extra_samples and sampling_target == "total_mass":
            # get the cumulative total mass of the samples
            total_mass_list = np.copy(mass1)
            total_mass_list[binary_index] += mass2_binaries
            sampled_so_far = m_sampled_singles + m_sampled_binaries
            cumulative_total_mass = sampled_so_far + np.cumsum(total_mass_list)

            # find the boundary for reaching the right total mass
            threshold_index = np.where(cumulative_total_mass > total_mass)[0][0]

            keep_offset = abs(cumulative_total_mass[threshold_index] - total_mass)
            drop_offset = abs(cumulative_total_mass[threshold_index - 1] - total_mass)
            lim = threshold_index - 1 if (keep_offset > drop_offset) else threshold_index

            # work out how many singles vs. binaries to delete
            one_if_binary = np.zeros(len(mass1))
            one_if_binary[binary_index] = 1
            sb_delete = one_if_binary[lim + 1:]
            n_single_delete = (sb_delete == 0).sum()
            n_binary_delete = (sb_delete == 1).sum()

            # delete em!
            if n_single_delete > 0:
                mass_single = mass_single[:-n_single_delete]
            if n_binary_delete > 0:
                mass1_binaries = mass1_binaries[:-n_binary_delete]
                mass2_binaries = mass2_binaries[:-n_binary_delete]
                binfrac_binaries = binfrac_binaries[:-n_binary_delete]

            # ensure we don't loop again after this
            target = lambda mass1_binary, size, m_sampled_singles, m_sampled_binaries, total_mass: False

        # track the mass sampled
        m_sampled_singles += sum(mass_single)
        m_sampled_binaries += sum(mass1_binaries)
        m_sampled_binaries += sum(mass2_binaries)

        # track the total number sampled
        n_singles += len(mass_single)
        n_binaries += len(mass1_binaries)

        # select out the primaries and secondaries that will produce the final kstars
        ind_select = (  (mass1_binaries > primary_min)
                      & (mass1_binaries < primary_max)
                      & (mass2_binaries > secondary_min)
                      & (mass2_binaries < secondary_max))
        mass1_binary.extend(mass1_binaries[ind_select])
        mass2_binary.extend(mass2_binaries[ind_select])
        binfrac.extend(binfrac_binaries[ind_select])

        # select out the single stars that will produce the final kstar
        mass1_singles.extend(mass_single[(mass_single > primary_min) & (mass_single < primary_max)])

        # check to see if we should increase the multiplier factor to sample the population more quickly
        if target(mass1_binary, size / 100, m_sampled_singles, m_sampled_binaries, total_mass / 100):
            # well this sampling rate is clearly not working time to increase
            # the multiplier by an order of magnitude
            multiplier *= 10

    mass1_binary = np.array(mass1_binary)
    mass2_binary = np.array(mass2_binary)
    binfrac = np.asarray(binfrac)
    mass1_singles = np.asarray(mass1_singles)

    zsun = kwargs.pop("zsun", 0.02)

    rad1 = initconditions.set_reff(mass1_binary, metallicity=met, zsun=zsun)
    rad2 = initconditions.set_reff(mass2_binary, metallicity=met, zsun=zsun)

    # sample periods and eccentricities
    # if the porb_model is moe19, the metallicity needs to be supplied
    if porb_model == "moe19":
        porb,aRL_over_a = initconditions.sample_porb(
            mass1_binary, mass2_binary, rad1, rad2, porb_model, met=met, size=mass1_binary.size
        )
    else:
        porb,aRL_over_a = initconditions.sample_porb(
            mass1_binary, mass2_binary, rad1, rad2, porb_model, size=mass1_binary.size
        )
    ecc = initconditions.sample_ecc(aRL_over_a, ecc_model, size=mass1_binary.size)

    tphysf, metallicity = initconditions.sample_SFH(
        SF_start=SF_start, SF_duration=SF_duration, met=met, size=mass1_binary.size
    )
    metallicity[metallicity < 1e-4] = 1e-4
    metallicity[metallicity > 0.03] = 0.03
    kstar1 = initconditions.set_kstar(mass1_binary)
    kstar2 = initconditions.set_kstar(mass2_binary)

    if kwargs.pop("keep_singles", False):
        binary_table = InitialBinaryTable.InitialBinaries(
            mass1_binary,
            mass2_binary,
            porb,
            ecc,
            tphysf,
            kstar1,
            kstar2,
            metallicity,
            binfrac=binfrac,
        )
        tphysf_singles, metallicity_singles = initconditions.sample_SFH(
            SF_start=SF_start, SF_duration=SF_duration, met=met, size=mass1_singles.size
        )
        metallicity_singles[metallicity_singles < 1e-4] = 1e-4
        metallicity_singles[metallicity_singles > 0.03] = 0.03
        kstar1_singles = initconditions.set_kstar(mass1_singles)
        singles_table = InitialBinaryTable.InitialBinaries(
            mass1_singles,                          # mass1
            np.ones_like(mass1_singles) * 0,        # mass2 (all massless remnants)
            np.ones_like(mass1_singles) * -1,       # porb (single not binary)
            np.ones_like(mass1_singles) * -1,       # ecc (single not binary)
            tphysf_singles,                         # tphysf
            kstar1_singles,                         # kstar1
            np.ones_like(mass1_singles) * 15,       # kstar2 (all massless remnants)
            metallicity_singles,                    # metallicity
        )
        binary_table = pd.concat([binary_table, singles_table])
    else:
        binary_table = InitialBinaryTable.InitialBinaries(
            mass1_binary,
            mass2_binary,
            porb,
            ecc,
            tphysf,
            kstar1,
            kstar2,
            metallicity,
            binfrac=binfrac,
        )

    return (
        binary_table,
        m_sampled_singles,
        m_sampled_binaries,
        n_singles,
        n_binaries,
    )

register_sampler(
    "independent",
    InitialBinaryTable,
    get_independent_sampler,
    usage="final_kstar1, final_kstar2, binfrac_model, primary_model, ecc_model, SFH_model, component_age, metallicity, size",
)

class Sample(object):
    # sample primary masses
    def sample_primary(self, primary_model='kroupa01', size=None, **kwargs):
        """Sample the primary mass (always the most massive star) from a user-selected model

            kroupa93 follows Kroupa (1993), normalization comes from
            `Hurley 2002 <https://arxiv.org/abs/astro-ph/0201220>`_
            between 0.08 and 150 Msun
            salpter55 follows
            `Salpeter (1955) <http://adsabs.harvard.edu/abs/1955ApJ...121..161S>`_
            between 0.08 and 150 Msun
            kroupa01 follows Kroupa (2001) <https://arxiv.org/abs/astro-ph/0009005>
            between 0.08 and 100 Msun

            Parameters
            ----------
            primary_model : str, optional
            model for mass distribution; choose from:

            kroupa93 follows Kroupa (1993), normalization comes from
            `Hurley 2002 <https://arxiv.org/abs/astro-ph/0201220>`_
            valid for masses between 0.1 and 100 Msun

            salpter55 follows
            `Salpeter (1955) <http://adsabs.harvard.edu/abs/1955ApJ...121..161S>`_
            valid for masses between 0.1 and 100 Msun

            kroupa01 follows Kroupa (2001), normalization comes from
            `Hurley 2002 <https://arxiv.org/abs/astro-ph/0009005>`_
            valid for masses between 0.1 and 100 Msun

            custom is a generic piecewise power law that takes in the power
            law slopes and break points given in the optional input lists (alphas, mcuts)
            default alphas and mcuts yield an IMF identical to kroupa01

            Default kroupa01

            size : int, optional
            number of initial primary masses to sample
            NOTE: this is set in cosmic-pop call as Nstep

            alphas : array, optional
            absolute values of the power law slopes for primary_model = 'custom'
            Default [-1.3,-2.3,-2.3] (identical to slopes for primary_model = 'kroupa01')

            mcuts : array, optional, units of Msun
            break points separating the power law 'pieces' for primary_model = 'custom'
            Default [0.08,0.5,1.0,150.] (identical to breaks for primary_model = 'kroupa01')

            Optional kwargs are defined in `get_independent_sampler`

            Returns
            -------
            a_0 : array
            Sampled primary masses
            np.sum(a_0) : float
            Total amount of mass sampled
            """

        # Read in m1_min and m_max kwargs, if provided
        m1_min = kwargs["m1_min"] if "m1_min" in kwargs.keys() else 0.08
        m_max = kwargs["m_max"] if "m_max" in kwargs.keys() else 150.0

        # Make sure m1_min value is below 0.5, since otherwise it will not work for Kroupa IMF
        if m1_min > 0.5:
            raise ValueError("m1_min must be greater than 0.5 Msun")

        if primary_model == 'kroupa93':
            alphas, mcuts = [-1.3,-2.2,-2.7], [m1_min,0.5,1.0,m_max]
        # Since COSMIC/BSE can't handle < 0.08Msun, we by default truncate at 0.08 Msun instead of 0.01
        elif primary_model == 'kroupa01':
            alphas, mcuts = [-1.3,-2.3], [m1_min,0.5,m_max]
        elif primary_model == 'salpeter55':
            alphas, mcuts = [-2.35], [m1_min,m_max]
        elif primary_model == 'custom':
            if 'alphas' in kwargs and 'mcuts' in kwargs:
                alphas = kwargs.pop("alphas", [-1.3,-2.3,-2.3])
                mcuts = kwargs.pop("mcuts", [m1_min,0.5,1.0,m_max])
            else:
                raise ValueError("You must supply both alphas and mcuts to use"
                                 " a custom IMF generator")

        Ncumulative, Ntotal, coeff = [], 0., 1.
        for i in range(len(alphas)):
            g = 1. + alphas[i]
            # Compute this piece of the IMF's contribution to Ntotal
            if alphas[i] == -1: Ntotal += coeff * np.log(mcuts[i+1]/mcuts[i])
            else: Ntotal += coeff/g * (mcuts[i+1]**g - mcuts[i]**g)
            Ncumulative.append(Ntotal)
            if i < len(alphas)-1: coeff *= mcuts[i+1]**(-alphas[i+1]+alphas[i])

        cutoffs = np.array(Ncumulative)/Ntotal
        u = np.random.uniform(0.,1.,size)
        idxs = [() for i in range(len(alphas))]

        for i in range(len(alphas)):
            if i == 0: idxs[i], = np.where(u <= cutoffs[0])
            elif i < len(alphas)-1: idxs[i], = np.where((u > cutoffs[i-1]) & (u <= cutoffs[i]))
            else: idxs[i], = np.where(u > cutoffs[i-1])
        for i in range(len(alphas)):
            if alphas[i] == -1.0:
                u[idxs[i]] = 10**np.random.uniform(np.log10(mcuts[i]),
                                                   np.log10(mcuts[i+1]),
                                                   len(idxs[i]))
            else:
                u[idxs[i]] = utils.rndm(a=mcuts[i], b=mcuts[i+1], g=alphas[i], size=len(idxs[i]))

        return u, np.sum(u)

    # sample secondary mass
    def sample_secondary(self, primary_mass, **kwargs):
        """Sample a secondary mass using draws from a uniform mass ratio distribution motivated by
        `Mazeh et al. (1992) <http://adsabs.harvard.edu/abs/1992ApJ...401..265M>`_
        and `Goldberg & Mazeh (1994) <http://adsabs.harvard.edu/abs/1994ApJ...429..362G>`_

        NOTE: the lower lim is set by either qmin or m2_min which are passed as kwargs

        Parameters
        ----------
        primary_mass : `array`
            sets the maximum secondary mass (for a maximum mass ratio of 1)

        Optional kwargs are defined in `get_independent_sampler`

        Returns
        -------
        secondary_mass : array
            sampled secondary masses with array size matching size of
            primary_mass
        """

        qmin = kwargs["qmin"] if "qmin" in kwargs.keys() else 0.0
        m1_min = kwargs["m1_min"] if "m1_min" in kwargs.keys() else 0.08
        m2_min = kwargs["m2_min"] if "m2_min" in kwargs.keys() else None
        if (m2_min is None) & (qmin is None):
            warnings.warn("It is highly recommended that you specify either qmin or m2_min!")
        if (m2_min is not None) and (m2_min > m1_min):
            raise ValueError("The m2_min you specified is above the minimum"
                             " primary mass of the IMF, either lower m2_min or"
                             " raise the lower value of your sampled primaries")

        # --- `msort` kwarg can be set to have different qmin above `msort`
        msort = kwargs["msort"] if "msort" in kwargs.keys() else None
        qmin_msort = kwargs["qmin_msort"] if "qmin_msort" in kwargs.keys() else None
        m2_min_msort = kwargs["m2_min_msort"] if "m2_min_msort" in kwargs.keys() else None
        if (msort is None) and (qmin_msort is not None):
            raise ValueError("If qmin_msort is specified, you must also supply a value for msort")
        if (msort is None) and (m2_min_msort is not None):
            raise ValueError("If m2_min_msort is specified, you must also supply a value for msort")
        if (m2_min_msort is not None) and (m2_min_msort > msort):
            raise ValueError("The m2_min_msort you specified is above the minimum"
                             " primary mass of the high-mass binaries msort")

        if (msort is not None) and (qmin_msort is not None):
            (highmassIdx,) = np.where(primary_mass >= msort)
            (lowmassIdx,) = np.where(primary_mass < msort)
        else:
            (highmassIdx,) = np.where(primary_mass < 0)
            (lowmassIdx,) = np.where(primary_mass >= 0)   # all idxs

        qmin_vals = -1 * np.ones_like(primary_mass)
        # --- qmin for low-mass systems (all systems if msort is not specified)
        if (qmin > 0.0):
            qmin_vals[lowmassIdx] = qmin * np.ones_like(primary_mass[lowmassIdx])
        elif (qmin < 0.0):
            # mass-dependent qmin, assume qmin=0.1 for m_primary<5
            dat = np.array([[5.0, 0.1363522012578616],
                            [6.999999999999993, 0.1363522012578616],
                            [12.599999999999994, 0.11874213836477984],
                            [20.999999999999993, 0.09962264150943395],
                            [29.39999999999999, 0.0820125786163522],
                            [41, 0.06490566037735851],
                            [55, 0.052327044025157254],
                            [70.19999999999999, 0.04301886792452836],
                            [87.4, 0.03622641509433966],
                            [107.40000000000002, 0.030188679245283068],
                            [133.40000000000003, 0.02515723270440262],
                            [156.60000000000002, 0.02163522012578628],
                            [175.40000000000003, 0.01962264150943399],
                            [200.20000000000005, 0.017358490566037776]])
            from scipy.interpolate import interp1d
            qmin_interp = interp1d(dat[:, 0], dat[:, 1])
            qmin_vals[lowmassIdx] = np.ones_like(primary_mass[lowmassIdx]) * 0.1
            ind_5, = np.where(primary_mass[lowmassIdx] > 5.0)
            qmin_vals[lowmassIdx][ind_5] = qmin_interp(primary_mass[lowmassIdx][ind_5])
        else:
            qmin_vals[lowmassIdx] = np.zeros_like(primary_mass[lowmassIdx])
        # --- qmin for high-mass systems, if msort and qmin_msort are specified
        if (msort is not None) and (qmin_msort is not None):
            if (qmin_msort > 0.0):
                qmin_vals[highmassIdx] = qmin_msort * np.ones_like(primary_mass[highmassIdx])
            elif (qmin_msort < 0.0):
                # mass-dependent qmin, assume qmin=0.1 for m_primary<5
                dat = np.array([[5.0, 0.1363522012578616],
                                [6.999999999999993, 0.1363522012578616],
                                [12.599999999999994, 0.11874213836477984],
                                [20.999999999999993, 0.09962264150943395],
                                [29.39999999999999, 0.0820125786163522],
                                [41, 0.06490566037735851],
                                [55, 0.052327044025157254],
                                [70.19999999999999, 0.04301886792452836],
                                [87.4, 0.03622641509433966],
                                [107.40000000000002, 0.030188679245283068],
                                [133.40000000000003, 0.02515723270440262],
                                [156.60000000000002, 0.02163522012578628],
                                [175.40000000000003, 0.01962264150943399],
                                [200.20000000000005, 0.017358490566037776]])
                from scipy.interpolate import interp1d
                qmin_interp = interp1d(dat[:, 0], dat[:, 1])
                qmin_vals[highmassIdx] = np.ones_like(primary_mass[highmassIdx]) * 0.1
                ind_5, = np.where(primary_mass[highmassIdx] > 5.0)
                qmin_vals[highmassIdx][ind_5] = qmin_interp(primary_mass[highmassIdx][ind_5])
            else:
                qmin_vals[highmassIdx] = np.zeros_like(primary_mass[highmassIdx])

        # --- apply m2_min and m2_min_msort, if specified
        if m2_min is not None:
            qmin_vals[lowmassIdx] = np.maximum(qmin_vals[lowmassIdx], m2_min/primary_mass[lowmassIdx])
        if m2_min_msort is not None:
            qmin_vals[highmassIdx] = np.maximum(qmin_vals[highmassIdx], m2_min_msort/primary_mass[highmassIdx])

        # --- now, randomly sample mass ratios and get secondary masses
        secondary_mass = np.random.uniform(qmin_vals, 1) * primary_mass

        return secondary_mass

    def binary_select(self, primary_mass, binfrac_model=0.5, **kwargs):
        """Select which primary masses will have a companion using
        either a binary fraction specified by a float or a
        primary-mass dependent binary fraction following
        `van Haaften et al.(2009) <http://adsabs.harvard.edu/abs/2013A%26A...552A..69V>`_ in appdx

        Parameters
        ----------
            primary_mass : array
                Mass that determines the binary fraction

            binfrac_model : str or float
                vanHaaften - primary mass dependent and ONLY VALID up to 100 Msun
                float - fraction of binaries; 0.5 means 2 in 3 stars are a binary pair while 1
                means every star is in a binary pair

        Optional kwargs are defined in `get_independent_sampler`

        Returns
        -------
            stars_in_binary : array
                primary masses that will have a binary companion

            stars_in_single : array
                primary masses that will be single stars

            binary_fraction : array
                system-specific probability of being in a binary

            binaryIdx : array
                Idx of stars in binary
        """

        # --- `msort` kwarg can be set to have different binary fraction above `msort`
        msort = kwargs["msort"] if "msort" in kwargs.keys() else None
        binfrac_model_msort = kwargs["binfrac_model_msort"] if "binfrac_model_msort" in kwargs.keys() else None
        if (msort is None) and (binfrac_model_msort is not None):
            raise ValueError("If binfrac_model_msort is specified, you must also supply a value for msort")
        if (msort is not None) and (binfrac_model_msort is not None):
            (highmassIdx,) = np.where(primary_mass >= msort)
            (lowmassIdx,) = np.where(primary_mass < msort)
        else:
            (highmassIdx,) = np.where(primary_mass < 0)
            (lowmassIdx,) = np.where(primary_mass >= 0)   # all idxs

        # --- read in binfrac models
        if type(binfrac_model) == str:
            if binfrac_model == "vanHaaften":
                binary_fraction_low = 1 / 2.0 + 1 / \
                    4.0 * np.log10(primary_mass[lowmassIdx])
                binary_choose_low = np.random.uniform(
                    0, 1.0, primary_mass[lowmassIdx].size)

                (singleIdx_low,) = np.where(
                    binary_fraction_low < binary_choose_low)
                (binaryIdx_low,) = np.where(
                    binary_fraction_low >= binary_choose_low)
            else:
                raise ValueError(
                    "You have supplied a non-supported binary fraction model. Please choose vanHaaften or a float"
                )
        elif type(binfrac_model) == float:
            if (binfrac_model <= 1.0) & (binfrac_model >= 0.0):
                binary_fraction_low = binfrac_model * \
                    np.ones(primary_mass[lowmassIdx].size)
                binary_choose_low = np.random.uniform(
                    0, 1.0, primary_mass[lowmassIdx].size)

                (singleIdx_low,) = np.where(
                    binary_choose_low > binary_fraction_low)
                (binaryIdx_low,) = np.where(
                    binary_choose_low <= binary_fraction_low)
            else:
                raise ValueError(
                    "You have supplied a fraction outside of 0-1. Please choose a fraction between 0 and 1."
                )
        else:
            raise ValueError(
                "You have not supplied a model or a fraction. Please choose either vanHaaften or a float"
            )

        # --- if using a different binary fraction for high-mass systems
        if (binfrac_model_msort is not None) and (type(binfrac_model_msort) == str):
            if binfrac_model_msort == "vanHaaften":
                binary_fraction_high = 1 / 2.0 + 1 / \
                    4.0 * np.log10(primary_mass[highmassIdx])
                binary_choose_high = np.random.uniform(
                    0, 1.0, primary_mass[highmassIdx].size)

                (singleIdx_high,) = np.where(
                    binary_fraction_high < binary_choose_high)
                (binaryIdx_high,) = np.where(
                    binary_fraction_high >= binary_choose_high)
            else:
                raise ValueError(
                    "You have supplied a non-supported binary fraction model. Please choose vanHaaften or a float"
                )
        elif (binfrac_model_msort is not None) and (type(binfrac_model_msort) == float):
            if (binfrac_model_msort <= 1.0) & (binfrac_model_msort >= 0.0):
                binary_fraction_high = binfrac_model_msort * \
                    np.ones(primary_mass[highmassIdx].size)
                binary_choose_high = np.random.uniform(
                    0, 1.0, primary_mass[highmassIdx].size)

                (singleIdx_high,) = np.where(
                    binary_choose_high > binary_fraction_high)
                (binaryIdx_high,) = np.where(
                    binary_choose_high <= binary_fraction_high)
            else:
                raise ValueError(
                    "You have supplied a fraction outside of 0-1. Please choose a fraction between 0 and 1."
                )
        elif (binfrac_model_msort is not None):
            raise ValueError(
                "You have not supplied a model or a fraction. Please choose either vanHaaften or a float"
            )

        # --- get pertinent info
        if (binfrac_model_msort is not None):
            stars_in_binary = np.append(
                primary_mass[highmassIdx][binaryIdx_high], primary_mass[lowmassIdx][binaryIdx_low])
            stars_in_single = np.append(
                primary_mass[highmassIdx][singleIdx_high], primary_mass[lowmassIdx][singleIdx_low])
            binary_fraction = np.append(
                binary_fraction_high[binaryIdx_high], binary_fraction_low[binaryIdx_low])
            binaryIdx = np.append(
                highmassIdx[binaryIdx_high], lowmassIdx[binaryIdx_low])
        else:
            stars_in_binary = primary_mass[lowmassIdx][binaryIdx_low]
            stars_in_single = primary_mass[lowmassIdx][singleIdx_low]
            binary_fraction = binary_fraction_low[binaryIdx_low]
            binaryIdx = lowmassIdx[binaryIdx_low]

        return (
            stars_in_binary,
            stars_in_single,
            binary_fraction,
            binaryIdx,
        )

    def sample_porb(self, mass1, mass2, rad1, rad2, porb_model, porb_max=None, size=None, **kwargs):
        """Sample the orbital period according to the user-specified model

        Parameters
        ----------
        mass1 : array
            primary masses
        mass2 : array
            secondary masses
        rad1 : array
            radii of the primaries.
        rad2 : array
            radii of the secondaries
        porb_model : string
            selects which model to sample orbital periods, choices include:
            log_uniform : semi-major axis flat in log space from RRLO < 0.5 up to 1e5 Rsun according to
            `Abt (1983) <http://adsabs.harvard.edu/abs/1983ARA%26A..21..343A>`_
            and consistent with Dominik+2012,2013
            and then converted to orbital period in days using Kepler III
            sana12 : power law orbital period between 0.15 < log(P/day) < 5.5 following
            `Sana+2012 <https://ui.adsabs.harvard.edu/abs/2012Sci...337..444S/abstract>_`
            renzo19 : power law orbital period for m1 > 15Msun binaries from
            `Sana+2012 <https://ui.adsabs.harvard.edu/abs/2012Sci...337..444S/abstract>_`
            following the implementation of
            `Renzo+2019 <https://ui.adsabs.harvard.edu/abs/2019A%26A...624A..66R/abstract>_`
            and flat in log otherwise
            raghavan10 : log normal orbital periods in days with mean_logP = 4.9
            and sigma_logP = 2.3 between 0 < log10(P/day) < 9  following
            `Raghavan+2010 <https://ui.adsabs.harvard.edu/abs/2010ApJS..190....1R/abstract>_`
            moe19 : log normal orbital periods in days with mean_logP = 4.9
            and sigma_logP = 2.3 between 0 < log10(P/day) < 9  following
            `Raghavan+2010 <https://ui.adsabs.harvard.edu/abs/2010ApJS..190....1R/abstract>_`
            but with different close binary fractions following
            `Moe+2019 <https://ui.adsabs.harvard.edu/abs/2019ApJ...875...61M/abstract>_`
        met : float
            metallicity of the population

        Returns
        -------
        porb : array
            orbital period with array size equalling array size
            of mass1 and mass2 in units of days
        aRL_over_a: array
            ratio of radius where RL overflow starts to the sampled seperation
            used to truncate the eccentricitiy distribution
        """

        # First we need to compute where RL overflow starts.  We truncate the lower-bound
        # of the period distribution there
        q = mass2 / mass1
        RL_fac = (0.49 * q ** (2.0 / 3.0)) / (
            0.6 * q ** (2.0 / 3.0) + np.log(1 + q ** 1.0 / 3.0)
        )

        q2 = mass1 / mass2
        RL_fac2 = (0.49 * q2 ** (2.0 / 3.0)) / (
            0.6 * q2 ** (2.0 / 3.0) + np.log(1 + q2 ** 1.0 / 3.0)
        )

        # include the factor for the eccentricity
        RL_max = 2 * rad1 / RL_fac
        (ind_switch,) = np.where(RL_max < 2 * rad2 / RL_fac2)
        if len(ind_switch) >= 1:
            RL_max[ind_switch] = 2 * rad2[ind_switch] / RL_fac2[ind_switch]

        # Can either sample the porb first and truncate the eccentricities at RL overflow
        # or sample the eccentricities first and truncate a(1-e) at RL overflow
        #
        # If we haven't sampled the eccentricities, then the minimum semi-major axis is at
        # RL overflow
        #
        # If we have, then the minimum pericenter is set to RL overflow
        a_min = RL_max

        if porb_model == "log_uniform":
            if porb_max is None:
                a_0 = np.random.uniform(np.log(a_min), np.log(1e5), size)
            else:
                # If in CMC, only sample binaries as wide as the local hard/soft boundary
                a_max = utils.a_from_p(porb_max,mass1,mass2)
                a_max[a_max < a_min] = a_min[a_max < a_min]
                a_0 = np.random.uniform(np.log(a_min), np.log(a_max), size)

            # convert out of log space
            a_0 = np.exp(a_0)
            aRL_over_a = a_min/a_0

            # convert to au
            rsun_au = 0.00465047
            a_0 = a_0 * rsun_au

            # convert to orbital period in years
            yr_day = 365.24
            porb_yr = ((a_0 ** 3.0) / (mass1 + mass2)) ** 0.5
            porb = porb_yr * yr_day
        elif porb_model == "sana12":
            # Same here: if using CMC, set the maximum porb to the smaller of either the
            # hard/soft boundary or 5.5 (from Sana paper)
            if porb_max is None:
                log10_porb_max = 5.5
            else:
                log10_porb_max = np.minimum(5.5,np.log10(porb_max))

            # Use the lower limit from the Sana12 distribution, unless this means the binaries are sampled at RL overflow. If so,
            # change the lower limit to a_min

            log10_porb_min = np.array([0.15]*len(a_min))
            RL_porb = utils.p_from_a(a_min,mass1,mass2)
            log10_RL_porb = np.log10(RL_porb)
            log10_porb_min[log10_porb_min <  log10_RL_porb] = log10_RL_porb[log10_porb_min < log10_RL_porb]

            porb = 10 ** utils.rndm(a=log10_porb_min, b=log10_porb_max, g=-0.55, size=size)
            aRL_over_a = a_min / utils.a_from_p(porb,mass1,mass2)

        elif porb_model == "renzo19":
            # Same here: if using CMC, set the maximum porb to the smaller of either the
            # hard/soft boundary or 5.5 (from Sana paper)
            if porb_max is None:
                log10_porb_max = 5.5

            else:
                log10_porb_max = np.minimum(5.5,np.log10(porb_max))

            # Use the lower limit from the Sana12 distribution, unless this means the binaries are sampled at RL overflow. If so,
            # change the lower limit to a_min
            log10_porb_min = np.array([0.15]*len(a_min))
            RL_porb = utils.p_from_a(a_min,mass1,mass2)
            log10_RL_porb = np.log10(RL_porb)
            log10_porb_min[log10_porb_min <  log10_RL_porb] = log10_RL_porb[log10_porb_min < log10_RL_porb]

            porb = 10 ** (np.random.uniform(log10_porb_min, log10_porb_max, size))
            (ind_massive,) = np.where(mass1 > 15)

            if type(log10_porb_max) != float:
                log10_porb_max = log10_porb_max[ind_massive]
                log10_porb_min = log10_porb_min[ind_massive]

            porb[ind_massive] = 10 ** utils.rndm(
                a=log10_porb_min[ind_massive], b=log10_porb_max, g=-0.55, size=len(ind_massive))
            aRL_over_a = a_min / utils.a_from_p(porb,mass1,mass2)

        elif porb_model == "raghavan10":
            import scipy
            # Same here: if using CMC, set the maximum porb to the smaller of either the
            # hard/soft boundary or 5.5 (from Sana paper)
            if porb_max is None:
                log10_porb_max = 9.0
            else:
                log10_porb_max = np.minimum(5.5, np.log10(porb_max))

            lower = 0
            upper = log10_porb_max
            mu = 4.9
            sigma = 2.3

            porb = 10 ** (scipy.stats.truncnorm.rvs(
                (lower-mu)/sigma,(upper-mu)/sigma, loc=mu, scale=sigma, size=size
                ))

            aRL_over_a = a_min / utils.a_from_p(porb,mass1,mass2)

        elif porb_model == "moe19":
            from scipy.interpolate import interp1d
            from scipy.stats import norm
            from scipy.integrate import trapz
            try:
                met = kwargs.pop('met')
            except:
                raise ValueError(
                    "You have chosen moe19 for the orbital period distribution which is a metallicity-dependent distribution. "
                    "Please specify a metallicity for the population."
                    )
            def get_logP_dist(nsamp, norm_wide, norm_close, mu=4.4, sigma=2.1):
                logP_lo_lim=0
                logP_hi_lim=9
                close_logP=4.0
                wide_logP=6.0
                neval = 500
                prob_wide = norm.pdf(np.linspace(wide_logP, logP_hi_lim, neval), loc=mu, scale=sigma)*norm_wide
                prob_close = norm.pdf(np.linspace(logP_lo_lim, close_logP, neval), loc=mu, scale=sigma)*norm_close
                slope = -(prob_close[-1] - prob_wide[0]) / (wide_logP - close_logP)
                prob_intermediate = slope * (np.linspace(close_logP, wide_logP, neval) - close_logP) + prob_close[-1]
                prob_interp_int = interp1d(np.linspace(close_logP, wide_logP, neval), prob_intermediate)

                log_p_success = []
                n_success = 0
                while n_success < nsamp:
                    logP_samp = np.random.uniform(logP_lo_lim, logP_hi_lim, nsamp*5)
                    logP_prob = np.random.uniform(0, 1, nsamp*5)

                    logP_samp_lo = logP_samp[logP_samp<close_logP]
                    logP_prob_lo = logP_prob[logP_samp<close_logP]
                    log_p_success.extend(logP_samp_lo[np.where(logP_prob_lo < norm.pdf(logP_samp_lo, loc=mu, scale=sigma)*norm_close)])

                    logP_samp_int = logP_samp[(logP_samp>=close_logP) & (logP_samp<wide_logP)]
                    logP_prob_int = logP_prob[(logP_samp>=close_logP) & (logP_samp<wide_logP)]
                    log_p_success.extend(logP_samp_int[np.where(logP_prob_int < prob_interp_int(logP_samp_int))])

                    logP_samp_hi = logP_samp[(logP_samp>=wide_logP)]
                    logP_prob_hi = logP_prob[(logP_samp>=wide_logP)]

                    log_p_success.extend(logP_samp_hi[np.where(logP_prob_hi < norm.pdf(logP_samp_hi, loc=mu, scale=sigma)*norm_wide)])

                    n_success = len(log_p_success)
                log_p_success = np.array(log_p_success)[np.random.randint(0,n_success,nsamp)]
                return log_p_success
            norm_wide, norm_close = utils.get_porb_norm(met)
            logP_dist = get_logP_dist(size, norm_wide, norm_close)
            logP_dist = logP_dist[np.random.randint(0, len(logP_dist), size)]
            porb = 10**logP_dist
            aRL_over_a = a_min / utils.a_from_p(porb,mass1,mass2)

        else:
            raise ValueError(
                "You have supplied a non-supported model; Please choose either log_flat, sana12, renzo19, raghavan10, or moe19"
            )
        return porb, aRL_over_a

    def sample_ecc(self, aRL_over_a, ecc_model="sana12", size=None):
        """Sample the eccentricity according to a user specified model

        Parameters
        ----------
        ecc_model : string
            'thermal' samples from a  thermal eccentricity distribution following
            `Heggie (1975) <http://adsabs.harvard.edu/abs/1975MNRAS.173..729H>`_
            'uniform' samples from a uniform eccentricity distribution
            'sana12' samples from the eccentricity distribution from
            `Sana+2012 <https://ui.adsabs.harvard.edu/abs/2012Sci...337..444S/abstract>_`
            'circular' assumes zero eccentricity for all systems
            DEFAULT = 'sana12'

        aRL_over_a : ratio of the minimum seperation (where RL overflow starts)
            to the sampled semi-major axis.  Use this to truncate the eccentricitiy

        size : int, optional
            number of eccentricities to sample
            this is set in cosmic-pop call as Nstep

        Returns
        -------
        ecc : array
            array of sampled eccentricities with size=size
        """

        # if we sampled the periods first, we need to truncate the eccentricities
        # to avoid RL overflow/collision at pericenter
        e_max = 1.0 - aRL_over_a

        if ecc_model == "thermal":
            a_0 = np.random.uniform(0.0, e_max**2, size)
            ecc = a_0 ** 0.5
            return ecc

        elif ecc_model == "uniform":
            ecc = np.random.uniform(0.0, e_max, size)
            return ecc

        elif ecc_model == "sana12":
            sana_max = np.array([0.9]*len(e_max))
            max_e = np.minimum(e_max, sana_max)
            ecc = utils.rndm(a=0.001, b=max_e, g=-0.45, size=size)

            return ecc

        elif ecc_model == "circular":
            ecc = np.zeros(size)
            return ecc

        else:
            raise ValueError("You have specified an unsupported model. Please choose from thermal, "
                             "uniform, sana12, or circular")

    def sample_SFH(self, SF_start=13700.0, SF_duration=0.0, met=0.02, size=None):
        """Sample an evolution time for each binary based on a user-specified
        time at the start of star formation and the duration of star formation.
        The default is a burst of star formation 13,700 Myr in the past.

        Parameters
        ----------
        SF_start : float
            Time in the past when star formation initiates in Myr
        SF_duration : float
            Duration of constant star formation beginning from SF_Start in Myr
        met : float
            metallicity of the population [Z_sun = 0.02]
            Default: 0.02
        size : int, optional
            number of evolution times to sample
            NOTE: this is set in cosmic-pop call as Nstep

        Returns
        -------
        tphys : array
            array of evolution times of size=size
        metallicity : array
            array of metallicities
        """

        if (SF_start > 0.0) & (SF_duration >= 0.0):
            tphys = np.random.uniform(SF_start - SF_duration, SF_start, size)
            metallicity = np.ones(size) * met
            return tphys, metallicity
        else:
            raise ValueError(
                'SF_start and SF_duration must be positive and SF_start must be greater than 0.0')

    def set_kstar(self, mass):
        """Initialize stellar types according to BSE classification
        kstar=1 if M>=0.7 Msun; kstar=0 if M<0.7 Msun

        Parameters
        ----------
        mass : array
            array of masses

        Returns
        -------
        kstar : array
            array of initial stellar types
        """

        kstar = np.zeros(mass.size)
        low_cutoff = 0.7
        lowIdx = np.where(mass < low_cutoff)[0]
        hiIdx = np.where(mass >= low_cutoff)[0]

        kstar[lowIdx] = 0
        kstar[hiIdx] = 1

        return kstar

    def set_reff(self, mass, metallicity, zsun=0.02):
        """
        Better way to set the radii from BSE, by calling it directly

        takes masses and metallicities, and returns the radii

        Note that the BSE function is hard-coded to go through arrays
        of length 10^5.  If your masses are more than that, you'll
        need to divide it into chunks
        """

        max_array_size = 100000
        total_length = len(mass)
        radii = np.zeros(total_length)

        _evolvebin.metvars.zsun = zsun

        idx = 0
        while total_length > max_array_size:
            ## cycle through the masses max_array_size number at a time
            temp_mass = mass[idx*max_array_size:(idx+1)*max_array_size]

            temp_radii = _evolvebin.compute_r(temp_mass,metallicity,max_array_size)

            ## put these in the radii array
            radii[idx*max_array_size:(idx+1)*max_array_size] = temp_radii

            total_length -= max_array_size
            idx += 1

        length_remaining = total_length

        ## if smaller than 10^5, need to pad out the array
        temp_mass = np.zeros(max_array_size)
        temp_mass[:length_remaining] = mass[-length_remaining:]

        temp_radii = _evolvebin.compute_r(temp_mass,metallicity,length_remaining)

        #finish up the array
        radii[-length_remaining:] = temp_radii[:length_remaining]

        return radii


g = lambda: [*map(int, input().split())]

L, G, R = g()
dic = {}
lamps = [0] * (L + 1)
for _ in range(G):
    name, *l = input().split()
    dic[name] = [*map(int, l)]
for _ in range(R):
    a, d = dic[input()]
    while a <= L:
        lamps[a] ^= 1
        a += d
print(sum(lamps))