import scrapy
from pyquery import PyQuery as pq
import json
from ..items import HongheItem
import re
import requests

class HhSpider(scrapy.Spider):
    name = 'hh'

    def start_requests(self):
        url = 'http://tuku.hh.cn/list1/15-16'
        yield scrapy.Request(url, callback=self.get_id_one_class)

    def get_id_one_class(self, response):
        html = response.text
        url = 'http://tuku.hh.cn/respository'
        info_url = 'http://tuku.hh.cn/respository/info'
        dics = re.findall(r'"sub_respository":\[(.*?)\]};', html)
        dics_list = dics[0].replace('],"old_photo":[', ',').replace('},{', '}@{').split('@')
        for dic in dics_list:
            item = HongheItem()
            dic = json.loads(dic)
            i_d = dic['id']
            item['one_class'] = dic['name']
            count_data = {
                'i': str(i_d),
                't': '3',
                'callback': 'jQuery111204507538242328981_1618236090086',
            }
            hd = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'}
            h = requests.post(info_url, data=count_data, headers=hd).text
            d_count = json.loads(h.split('(')[1].split(')')[0])
            count = int(d_count['c_n'])
            for i in range(0, count + 20, 20):
                data = {
                    'id': str(i_d),
                    'start': str(i),
                    'cnt': '20',
                    'callback': 'jQuery111205435798931123299_1618229472875'
                }
                yield scrapy.FormRequest(url, formdata=data, meta={'item': item}, callback=self.parse, dont_filter=True)

    def parse(self, response, **kwargs):
        j = response.text
        d_str = json.loads(j.split('(', 1)[1].rsplit(')', 1)[0])
        for d in d_str['data']:
            item = response.meta['item']
            two_href = 'http://tuku.hh.cn/' + d['href']
            item['two_class'] = d['title']
            yield scrapy.Request(two_href, meta={'item': item}, callback=self.detail_parse)

    def detail_parse(self, response):
        html = response.text
        datas_list = re.findall(r'var data=\[(.*)\];', html)
        dict_list = datas_list[0].replace('},{', '}@{').split('@')
        for d in dict_list:
            d_data = json.loads(d)
            item = response.meta['item']
            item['img_name'] = d_data['description']
            item['img_url'] = 'http://tuku.hh.cn/' + d_data['file'].replace('\\', '')
            yield item


import pprint
from typing import Dict
from pydantic import BaseModel, Field
from github import GithubException, BadCredentialsException, UnknownObjectException

class InputSchema(BaseModel):
    owner: str = Field(
        description='Username of the GitHub user. Eg: "johnwick"',
        title='Owner'
    )
    repository: str = Field(
        description='Name of the GitHub repository. Eg: "Awesome-CloudOps-Automation"',
        title='Repository',
    )
    pull_request_number: int = Field(
        description='Pull request number. Eg: 167',
        title='Pull Request Number'
    )

def github_get_pull_request_printer(output):
    if output is None:
        return
    pprint.pprint(output)

def github_get_pull_request(handle, owner:str, repository:str, pull_request_number: int) -> Dict:
    """github_get_pull_request returns details of pull requests for a user

        :type handle: object
        :param handle: Object returned from task.validate(...).

        :type owner: string
        :param owner: Username of the GitHub user. Eg: "johnwick"

        :type repository: string
        :param repository: Name of the GitHub repository. Eg: "Awesome-CloudOps-Automation"

        :type pull_request_number: int
        :param pull_request_number: Pull request number. Eg: 167

        :rtype: Dict of details of pull request for a user
    """
    prs_dict = {}
    pr_number = int(pull_request_number)
    try:
        owner = handle.get_user(owner)
        repo_name = owner.login+'/'+repository
        repo = handle.get_repo(repo_name)
        pr = repo.get_pull(pr_number)
        prs_dict["pull_number"] = pr.number
        prs_dict["pull_title"] = pr.title
        prs_dict["pull_changed_files"] = pr.changed_files
        prs_dict["pull_review_comments"] = pr.review_comments
        prs_dict["pull_commits"] = pr.commits
    except GithubException as e:
        if e.status == 403:
            raise BadCredentialsException("You need admin access") from e
        if e.status == 404:
            raise UnknownObjectException("No such pull number or repository or user found") from e
        raise e.data
    except Exception as e:
        raise e
    return prs_dict


import warnings; warnings.filterwarnings("ignore")
import time
start_time = time.time()

import pandas as pd
import os

from sklearn import pipeline, grid_search
from sklearn.ensemble import RandomForestRegressor
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import FeatureUnion
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics import mean_squared_error, make_scorer

def fmean_squared_error(ground_truth, predictions):
    fmean_squared_error_ = mean_squared_error(ground_truth, predictions)**0.5
    return fmean_squared_error_

class cust_regression_vals(BaseEstimator, TransformerMixin):
    def fit(self, x, y=None):
        return self
    def transform(self, hd_searches):
        d_col_drops=['id','relevance','search_term','product_title','product_description','product_info','attr','brand']
        hd_searches = hd_searches.drop(d_col_drops,axis=1).values
        return hd_searches
class cust_txt_col(BaseEstimator, TransformerMixin):
    def __init__(self, key):
        self.key = key
    def fit(self, x, y=None):
        return self
    def transform(self, data_dict):
        return data_dict[self.key].apply(str)

RMSE  = make_scorer(fmean_squared_error, greater_is_better=False)

df_all = pd.read_csv(os.path.expanduser('~/Desktop/Home Depot/Features/feature_array.csv'))
feature_cols = [col for col in df_all.columns if col not in ['Unnamed: 0']]
df_all = df_all[feature_cols]

df_train = pd.read_csv('~/Desktop/Home Depot/Data/train.csv', encoding="ISO-8859-1")#[:1000]
num_train = df_train.shape[0]

df_train = df_all[:num_train]
df_test = df_all[num_train:]

y_train = df_train['relevance']
id_test = df_test['id']
X_train = df_train[:]
X_test = df_test[:]

if __name__ == '__main__':

    rfr = RandomForestRegressor(n_estimators = 2000, n_jobs = -1, random_state = 2016, verbose = 1)
    tfidf = TfidfVectorizer(ngram_range=(1, 1), stop_words='english')
    tsvd = TruncatedSVD(n_components=10, random_state = 2016)
    clf = pipeline.Pipeline([
            ('union', FeatureUnion(
                        transformer_list = [
                            ('cst',  cust_regression_vals()),
                            ('txt1', pipeline.Pipeline([('s1', cust_txt_col(key='search_term')), ('tfidf1', tfidf), ('tsvd1', tsvd)])),
                            ('txt2', pipeline.Pipeline([('s2', cust_txt_col(key='product_title')), ('tfidf2', tfidf), ('tsvd2', tsvd)])),
                            ('txt3', pipeline.Pipeline([('s3', cust_txt_col(key='product_description')), ('tfidf3', tfidf), ('tsvd3', tsvd)])),
                            ('txt4', pipeline.Pipeline([('s4', cust_txt_col(key='brand')), ('tfidf4', tfidf), ('tsvd4', tsvd)])),
                            ],
                        transformer_weights = {
                            'cst': 1.0,
                            'txt1': 0.5,
                            'txt2': 0.25,
                            'txt3': 0.0,
                            'txt4': 0.5,

                            },
                    n_jobs = -1
                    )),
            ('rfr', rfr)])
    param_grid = {'rfr__max_features': [10], 'rfr__max_depth': [20]}
    model = grid_search.GridSearchCV(estimator = clf, param_grid = param_grid, n_jobs = -1, cv = 2, verbose = 20, scoring=RMSE)
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)

    print("Best parameters found by grid search:")
    print(model.best_params_)
    print("Best CV score:")
    print(model.best_score_)
    print(model.best_score_ + 0.47003199274)

    pd.DataFrame({"id": id_test, "relevance": y_pred}).to_csv(os.path.expanduser('~/Desktop/Home Depot/Output/rf_submission.csv'),index=False)
    print("--- Training & Testing: %s minutes ---" % round(((time.time() - start_time)/60),2))


import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from utils import *

if torch.cuda.is_available():
    device = torch.device('cuda')
else:
    device = torch.device('cpu')
print('Using PyTorch version:', torch.__version__, ' Device:', device)

from LSTM_rewrite import mylstm
hidden_size=128
rnn=mylstm()
criterion = nn.NLLLoss()
learning_rate = 0.05

def train(category_tensor, line_tensor):
    # 初始全零的隐藏向量
    hidden = rnn.init_hidden()
    rnn.zero_grad()
    for i in range(line_tensor.size()[0]):
        # 对于name中的每一个字母
        output,hc= rnn(line_tensor[i],hidden)

    loss = criterion(output, category_tensor)
    loss.backward()

    # Add parameters' gradients to their values, multiplied by learning rate
    for p in rnn.parameters():
        p.data.add_(p.grad.data, alpha=-learning_rate)

    return output, loss.item()

def validate():
    correct = 0
    all = 0
    for key, value in category_lines.items():
        for name in value:
            line_tensor = lineToTensor(name)
            hidden = rnn.init_hidden()
            for i in range(line_tensor.size()[0]):
                output, hidden = rnn(line_tensor[i], hidden)
            # 得到结果向量output
            guess, guess_i = categoryFromOutput(output)
            if guess == key:
                correct += 1
        all += len(value)
    print('Accuract is {}/{}'.format(correct, all))

def evaluate(line_tensor):
    hidden = rnn.init_hidden()
    for i in range(line_tensor.size()[0]):
        output ,hidden= rnn(line_tensor[i],hidden)
    return output

n_iters = 200000
print_every = 5000
plot_every = 1000

current_loss = 0
all_losses = []

# begin to train
start = time.time()
for iter in range(1, n_iters + 1):
    category, line, category_tensor, line_tensor = randomTrainingExample()
    output, loss = train(category_tensor, line_tensor)
    current_loss += loss

    # Print iter number, loss, name and guess
    if iter % print_every == 0:
        guess, guess_i = categoryFromOutput(output)
        correct = '✓' if guess == category else '✗ (%s)' % category
        print('%d %d%% (%s) %.4f %s / %s %s' % (iter, iter / n_iters * 100, timeSince(start), loss, line, guess, correct))

    # Add current loss avg to list of losses
    if iter % plot_every == 0:
        all_losses.append(current_loss / plot_every)
        current_loss = 0
# begin to test
validate()

plt.figure()
plt.plot(all_losses)
plt.savefig('./loss.png')
plt.clf()

# 准备混淆矩阵
confusion = torch.zeros(n_categories, n_categories)
n_confusion = 10000
for i in range(n_confusion):
    category, line, category_tensor, line_tensor = randomTrainingExample()
    output = evaluate(line_tensor)
    guess, guess_i = categoryFromOutput(output)
    category_i = all_categories.index(category)
    confusion[category_i][guess_i] += 1

# Normalize by dividing every row by its sum
for i in range(n_categories):
    confusion[i] = confusion[i] / confusion[i].sum()

# Set up plot
fig = plt.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(confusion.numpy())
fig.colorbar(cax)
# Set up axes

ax.set_xticklabels([''] + all_categories, rotation=90)
ax.set_yticklabels([''] + all_categories)

# Force label at every tick
ax.xaxis.set_major_locator(ticker.MultipleLocator(1))
ax.yaxis.set_major_locator(ticker.MultipleLocator(1))
plt.savefig('./matrix.png')
plt.clf()


from pprint import pprint

names = [

    ['first', 'First'],
    ['Second', 'second'],
    ['Tree', 'tree', 'treeee'],
]

numbers = [2, 22, 444,55,666]

import itertools

# print(list(ite1rtools.product(*names)))
# print(list(itertools.combinations([names[0][0], names[1][0], names[2][0]], 3)))

def generate():

    final = []

    for line1 in names[0]:
        for line2 in names[1]:
            for line3 in names[2]:
                for line4 in numbers:

                    for i in range(1, 4):
                        # print(i, line1, line2, line3, line4)

                        mutant = list(itertools.permutations([line1, line2, line3], i))

                        final = final + mutant

                        for m in mutant:

                            final.append(m + tuple([str(line4)]))

    return list(set(final))

if __name__ == "__main__":

    final = generate()

    pprint(final)

    print(len(final))

    with open('passwords.txt', 'w') as f:
        for item in final:
            comb_str = ''.join(list(item))
            if len(comb_str)<8:
                # print('skip small', comb_str)
                continue
            f.write("%s\n" % comb_str)


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('cmdb', '0005_server_productname'),
    ]

    operations = [
        migrations.AddField(
            model_name='server',
            name='manufacturer',
            field=models.CharField(max_length=20, null=True, verbose_name='\u5382\u5546', blank=True),
        ),
    ]


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

import pygame
def main():
	pygame.init()#初始化pygame,为使用硬件做准备
	screen = pygame.display.set_mode([640,480])#相当于生成画布，像素点原点在左上角，右向0-640为x轴，下向0-480为y轴
	running = True
	while running:
		screen.fill([255,255,255]) #设置填充颜色，三个数字分别代表红、绿、蓝色分量 0-255，都是255——白色
		pygame.draw.circle(screen,[255,0,0],[100,100],10,0)#1.color2.圆心在x、y轴的位置3.半径4.是圆环(数字代表圆环粗细)还是圆(0)
		pygame.draw.rect(screen,[0,255,255],[280,400,80,5],0)#1.color2.[左上角顶点坐标，宽度W，高度H]3.0-实心长方形，其他数字代表长方形边框的粗细

		# pygame.draw.circle(screen,[100,100,200],[320,240],50,5)
		# pygame.draw.circle(screen,[0,0,250],[320,240],30,0)
		# pygame.draw.rect(screen,[50,150,50],[270,400,100,30],5)
		# pygame.draw.rect(screen,[200,50,50],[290,405,60,20],0)

		pygame.display.flip()#把填充的东西全部运行在screen上
		for event in pygame.event.get():
			if event.type == pygame.QUIT:#点右上角叉叉关闭的话
				running = False
	pygame.quit()

if __name__ == '__main__':
	main()


from django.urls import path
from .views import RegisterView, UserView  # , LogoutView, login_view#user,
from rest_framework_simplejwt import views as jwt_viwes

app_name = 'accounts'

urlpatterns = [
    # with simple jwt auth
    path('api/login/', jwt_viwes.TokenObtainPairView.as_view(), name='login'),
    path('api/token/refresh/', jwt_viwes.TokenRefreshView.as_view()),

    # path('api/v2/user/', user, name='user'),
    path('api/register/', RegisterView.as_view()),
    # path('api/login/', LoginView.as_view()),
    path('api/user/', UserView.as_view(), name='user'),
    # path('api/logout/', LogoutView.as_view()),
    # path('api/v2/login/', login_view, name='login'),
]


import discord
import os
import json
from discord.ext import commands, tasks
from discord_components import DiscordComponents, ComponentsBot, Button, component, interaction

intents = discord.Intents.default()
intents.typing = True
intents.presences = True
intents.members = True

client = ComponentsBot(command_prefix = '$', intents=intents)
client.remove_command('help')

##########################################################################
#generalrole = discord.utils.get(ctx.guild.roles, id=661454256251076613)
#logchannel = discord.utils.get(client.get_all_channels(), id = 753619980548833401)

#SERVER INFO
ownerid = 605217750847062049
botownerid = 631441731350691850
robloxaccountid = "2735986134"

category_list = {
    "help" : 896390484908470292,
    "mm" : 896374909897420831,
    "complete": 896375184834064404
}
##########################################################################

#USEFUL FUNCTIONS
##########################################################################
#Auction-Related
def joinlist(thislist):
    x = ""
    for i in thislist:
        x += i
    return x

def formatmoney(money):
    strmoney = str(money)
    storagelist = []

    lengthofmoney = len(strmoney)

    if lengthofmoney < 4:
        return strmoney
    else:
        mok = lengthofmoney//3
        namoji = lengthofmoney%3

        for i in strmoney:
            storagelist.append(i)

        bait = 0

        if bait == 0 and mok == 1:
            storagelist.insert(namoji, ",") #first comma insert
        elif namoji == 0:
            jumpdistance = 3
            mok = mok - 2
            while bait <= mok:
                storagelist.insert(jumpdistance, ",")
                jumpdistance += 4
                bait += 1
        else:
            bait = 1
            newmok = 0
            while bait <= mok:
                if bait == 1:
                    storagelist.insert(namoji, ",")
                    bait += 1
                else:
                    if newmok == 0:
                        newmok = namoji + 4
                    else:
                        newmok += 4
                    storagelist.insert(newmok, ",")
                    bait += 1

        complete = joinlist(storagelist)
        return complete

def checkowner(enterownerid):
    if enterownerid == ownerid or enterownerid == botownerid:
        return True
    else:
        return False

def checkifauctionexists(auctionid):
    supportbridge = "database/auction/ongoing/"
    bidid = str(auctionid)

    if os.path.isfile(supportbridge+f"{bidid}.json"):
        return True
    else:
        return False

##########################################################################
@client.event
async def on_ready():
    game = discord.Game(name = "판매 돕는 중")
    await client.change_presence(activity = game)

    print("Ready to Run")

@client.event
async def on_button_click(interaction):
    if interaction.responded:
        return
    getcustomid = interaction.custom_id
    guild = interaction.guild
    user = interaction.user

    userid = str(user.id)

    groupcategory = discord.utils.get(guild.categories, id=910395160163127296)
    limitedcategory = discord.utils.get(guild.categories, id=896374909897420831)
    ingamecategory = discord.utils.get(guild.categories, id=910400736892960808)

    if getcustomid == "grouprelated":
        try:
            findchannel = discord.utils.get(client.get_all_channels(), name = str(f"g-{userid}"), category = groupcategory)
            await interaction.send(f"이미 진행중인 채널이 존재합니다, {findchannel.mention}")
        except:
            madechannel = await guild.create_text_channel(str(f"g-{userid}"), category=groupcategory)
            await madechannel.set_permissions(user, read_messages=True, send_messages=True)
            await interaction.send(f"{madechannel.mention} 채널이 생성되었습니다")
            await madechannel.send("@everyone\n거래 대상의 유저를 알려주시면 서버 주인이 해당 사람을 채널에 초대할 것입니다. 만약 서버에 없다면 빨리 초대해주세요.")
    elif getcustomid == "limitedrelated":
        try:
            findchannel = discord.utils.get(client.get_all_channels(), name = str(f"l-{userid}"), category = limitedcategory)
            await interaction.send(f"이미 진행중인 채널이 존재합니다, {findchannel.mention}")
        except:
            madechannel = await guild.create_text_channel(str(f"l-{userid}"), category=limitedcategory)
            await madechannel.set_permissions(user, read_messages=True, send_messages=True)
            await interaction.send(f"{madechannel.mention} 채널이 생성되었습니다")
            await madechannel.send("@everyone\n거래 대상의 유저를 알려주시면 서버 주인이 해당 사람을 채널에 초대할 것입니다. 만약 서버에 없다면 빨리 초대해주세요.")
    elif getcustomid == "ingamerelated":
        try:
            findchannel = discord.utils.get(client.get_all_channels(), name = str(f"in-{userid}"), category = ingamecategory)
            await interaction.send(f"이미 진행중인 채널이 존재합니다, {findchannel.mention}")
        except:
            madechannel = await guild.create_text_channel(str(f"in-{userid}"), category=ingamecategory)
            await madechannel.set_permissions(user, read_messages=True, send_messages=True)
            await interaction.send(f"{madechannel.mention} 채널이 생성되었습니다")
            await madechannel.send("@everyone\n거래 대상의 유저를 알려주시면 서버 주인이 해당 사람을 채널에 초대할 것입니다. 만약 서버에 없다면 빨리 초대해주세요.")
    else:
        pass

@client.command()
async def sendembed(ctx):
    if ctx.author.id == 631441731350691850:
        embed1 = discord.Embed(
            title = f"티켓을 여는 법",
            description = f"아래 카테고리 중 본인의 거래에 적합한 카테고리를 골라 버튼을 눌러주시면 티켓을 열 수 있습니다.\n\n**티켓을 열기 전에 꼭 읽으세요!**\n거래를 하는 사람과 거래를 바로 할 수 있도록 확실하게 해주세요. 만일 소유자의 시간을 끌게 된다면 이후에 블랙리스트될 수 있습니다.",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed1.set_footer(text=f"NastyCore, The Next Innovation")
        #get channel with id 896374268659634207
        channel = client.get_channel(896374268659634207)
        await channel.send(embed=embed1)

        embed2 = discord.Embed(
            title = f"로블록스 그룹 관련",
            description = f"그룹 관련(페이아웃, 그룹 소유권)..에 해당된다면 반응해주세요",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed2.set_footer(text=f"NastyCore, The Next Innovation")
        embed2.set_thumbnail(url="https://static.wikia.nocookie.net/roblox/images/a/a3/Intern.png/revision/latest/top-crop/width/360/height/360?cb=20190103234928")

        await channel.send(
            embed=embed2,
            components = [
                Button(label = "⚡ 중개 요청(그룹)", style=1 ,custom_id = "grouprelated")
            ]
        )

        embed3 = discord.Embed(
            title = f"리미티드 관련",
            description = f"리미티드 관련(판매)..에 해당된다면 반응해주세요",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed3.set_footer(text=f"NastyCore, The Next Innovation")
        embed3.set_thumbnail(url="https://cdn.discordapp.com/attachments/896368284545454132/910395071021584444/Png.png")

        await channel.send(
            embed=embed3,
            components = [
                Button(label = "⚡ 중개 요청(리미티드)", style=1 ,custom_id = "limitedrelated")
            ]
        )

        embed4 = discord.Embed(
            title = f"인게임 아이템 관련",
            description = f"인게임 관련(게임 아이템)..에 해당된다면 반응해주세요",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed4.set_footer(text=f"NastyCore, The Next Innovation")
        embed4.set_thumbnail(url="https://static.wikia.nocookie.net/murder-mystery-2/images/e/ee/Seer.png/revision/latest/top-crop/width/360/height/450?cb=20210204082208")

        await channel.send(
            embed=embed4,
            components = [
                Button(label = "⚡ 중개 요청(리미티드)", style=1 ,custom_id = "ingamerelated")
            ]
        )

@client.command(aliases=["중개종료"])
async def endmm(ctx):
    if checkowner(ctx.author.id):
        thiscategory = ctx.channel.category
        categoryidlist = [910395160163127296, 896374909897420831, 910400736892960808]

        donecategory = discord.utils.get(ctx.guild.categories, id=896375184834064404)

        if thiscategory.id in categoryidlist:
            await ctx.channel.edit(category = donecategory, sync_permissions = True)

            channelname = ctx.channel.name
            userid = int(channelname.split("-")[1])

            user = client.get_user(userid)
            try:
                await user.send("만족하셨다면 후기 채널에 후기 남겨주세요!")
            except:
                pass

        else:
            await ctx.send("여기는 중개 채널이 아닌디..")
    else:
        embed = discord.Embed(
            title = f"에러 | 주인 전용 명령어",
            description = f"중개종료 명령어는 주인만 사용 가능한 명령어입니다.",
            color = discord.Color.from_rgb(255, 0, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["경매생성"])
async def postauction(ctx, auctionchannel:discord.TextChannel = None, startingprice = None, *, itemtosell = None):

    jsonpath = "database/auction/ongoing/"

    if checkowner(ctx.author.id):
        if auctionchannel == None or startingprice == None or itemtosell == None:
            embed = discord.Embed(
                title = f"에러 | 양식 오류",
                description = f"`$경매생성 #채널 시작가격 판매하는물건`",
                color = discord.Color.from_rgb(255, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)
        else:
            convertedprice = formatmoney(int(startingprice))
            targetchannel = discord.utils.get(client.get_all_channels(), id = auctionchannel.id)

            with open(jsonpath+"newauction.json", encoding='UTF8') as f:
                jsondata = json.load(f)
                f.close()

            currentid = jsondata["auctionid"]
            currentid += 1
            jsondata["auctionid"] = currentid

            with open(jsonpath+"newauction.json", "w", encoding='UTF8') as f:
                json.dump(jsondata, f, indent=2)
                f.close()

            jsondata["itemname"] = itemtosell
            jsondata["startingprice"] = startingprice
            jsondata["best_bet"]["userid"] = ctx.author.id
            jsondata["best_bet"]["price"] = startingprice
            jsondata["auctionchannel"] = auctionchannel.id

            with open(jsonpath+f"{currentid}.json", "w", encoding='UTF8') as f:
                json.dump(jsondata, f, indent=2)
                f.close()

            await targetchannel.send("@everyone")
            embed = discord.Embed(
                title = f"새로운 경매 | **{itemtosell}**",
                description = f"새로운 경매가 나왔습니다\n```아이템: {itemtosell}\n시작가격: {convertedprice}\n경매아이디: {currentid}```\n경매참여: `$경매참여 경매아이디 가격`\n경매정보: `$경매정보 경매아이디`",
                color = discord.Color.from_rgb(0, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await targetchannel.send(embed=embed)

    else:
            embed = discord.Embed(
                title = f"에러 | 주인 전용 명령어",
                description = f"경매생성 명령어는 주인만 사용 가능한 명령어입니다.",
                color = discord.Color.from_rgb(255, 0, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)

@client.command(aliases=["경매차단"])
async def blacklistauction(ctx, target:discord.Member = None):
    if target != None:
        if checkowner(ctx.author.id):
            path = "database/auction/blacklist/blacklist.json"

            with open(path) as f:
                r = json.load(f)
                f.close()

            if target.id in r:
                r.remove(target.id)

                embed = discord.Embed(
                    title = f"블랙리스트 해제",
                    description = f"{target.mention}님은 다시 경매 명령어를 사용할 수 있습니다.",
                    color = discord.Color.from_rgb(0, 255, 0)
                )
                embed.set_footer(text=f"NastyCore, The Next Innovation")
                await ctx.send(embed=embed)
            else:
                r.append(target.id)

                embed = discord.Embed(
                    title = f"블랙리스트 추가",
                    description = f"{target.mention}님은 이제 경매 명령어를 사용할 수 없습니다.",
                    color = discord.Color.from_rgb(0, 255, 0)
                )
                embed.set_footer(text=f"NastyCore, The Next Innovation")
                await ctx.send(embed=embed)

            with open(path, "w") as f:
                json.dump(r, f, indent=2)
                f.close()
        else:
            embed = discord.Embed(
                title = f"에러 | 주인 전용 명령어",
                description = f"경매생성 명령어는 주인만 사용 가능한 명령어입니다.",
                color = discord.Color.from_rgb(255, 0, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)
    else:
        embed = discord.Embed(
            title = f"에러 | 양식오류",
            description = f"`$경매차단 @유저멘션`",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["최고가설정"])
async def sethighest(ctx, auctionid=None, target:discord.Member=None, price=None):
    if checkowner(ctx.author.id):
        if auctionid != None and target != None and price != None:
            decidedpath = f"database/auction/ongoing/{auctionid}.json"

            with open(decidedpath, encoding='UTF8') as f:
                r = json.load(f)
                f.close()

            historylist = r["history"]
            highestbid = r["best_bet"]

            if checkifauctionexists(int(auctionid)):
                highestbid["userid"] = target.id
                highestbid["price"] = int(price)

                await ctx.send("ok")

                with open(decidedpath, "w") as f:
                    json.dump(r, f, indent=2)
                    f.close()

            else:
                embed = discord.Embed(
                    title = f"에러 | 찾지못함",
                    description = f"해당 입찰아이디를 찾지 못했습니다",
                    color = discord.Color.from_rgb(255, 255, 0)
                )
                embed.set_footer(text=f"NastyCore, The Next Innovation")
                await ctx.send(embed=embed)

        else:
            embed = discord.Embed(
                title = f"에러 | 양식오류",
                description = f"`$최고가설정 경매아이디 @유저 가격`",
                color = discord.Color.from_rgb(255, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)

    else:
        embed = discord.Embed(
            title = f"에러 | 주인 전용 명령어",
            description = f"경매생성 명령어는 주인만 사용 가능한 명령어입니다.",
            color = discord.Color.from_rgb(255, 0, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["경매종료"])
async def endauction(ctx, auctionid=None):
    if checkowner(ctx.author.id):
        if auctionid != None:
            if checkifauctionexists(auctionid):
                path = f"database/auction/ongoing/{auctionid}.json"

                with open(path) as f:
                    r = json.load(f)
                    f.close()

                itemname = r["itemname"]
                startingprice = r["startingprice"]
                auctionid = auctionid
                auctionchannel = r["auctionchannel"]

                best_bet_dict = r["best_bet"]
                history_list = r["history"]
                winner_dict = r["winner"]

                #winner info
                winner_id = best_bet_dict["userid"]
                winner_price = best_bet_dict["price"]
                winner_id = best_bet_dict["bidid"]

                targetchannel = discord.utils.get(client.get_all_channels(), id = auctionchannel)

                altuserid = r["best_bet"]["userid"]
                targetuser = await client.fetch_user(int(altuserid))

                targetuserdisplayname = targetuser.display_name

                startingprice = formatmoney(startingprice)
                finalprice = formatmoney(winner_price)

                #transfer to winner_dict
                winner_dict["userid"] = winner_id
                winner_dict["price"] = winner_price
                winner_dict["bidid"] = winner_id

                await targetchannel.send("@everyone")
                embed = discord.Embed(
                    title = f"경매 종료 | **{targetuserdisplayname}**🎉",
                    description = f"경매 정보:\n```판매 제품: {itemname}\n시작가격: {startingprice}\n낙찰가: {finalprice}\n입찰참여총횟수: {len(history_list)-1}```\n우승을 축하드립니다:\n```유저: {targetuser}\n유저아이디: {altuserid}```",
                    color = discord.Color.from_rgb(0, 255, 0)
                )
                embed.set_footer(text=f"NastyCore, The Next Innovation")
                await targetchannel.send(embed=embed)

                os.remove(path)

            else:
                embed = discord.Embed(
                    title = f"에러 | 존재하지 않는 경매 아이디",
                    description = f"해당 경매 아이디는 존재하지 않습니다",
                    color = discord.Color.from_rgb(255, 255, 0)
                )
                embed.set_footer(text=f"NastyCore, The Next Innovation")
                await ctx.send(embed=embed)
        else:
            embed = discord.Embed(
                title = f"에러 | 양식오류",
                description = f"$경매종료 경매아이디",
                color = discord.Color.from_rgb(255, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)
    else:
        embed = discord.Embed(
            title = f"에러 | 주인 전용 명령어",
            description = f"경매생성 명령어는 주인만 사용 가능한 명령어입니다.",
            color = discord.Color.from_rgb(255, 0, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["계정"])
async def account(ctx):
    await ctx.message.delete()
    if checkowner(ctx.author.id):
        await ctx.send(f"계정링크:\nhttps://www.roblox.com/users/{robloxaccountid}/profile")
    else:
        embed = discord.Embed(
            title = f"에러 | 주인 전용 명령어",
            description = f"경매생성 명령어는 주인만 사용 가능한 명령어입니다.",
            color = discord.Color.from_rgb(255, 0, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["계정아이디"])
async def changeaccount(ctx, accountid = None):
    if checkowner(ctx.author.id):
        if accountid != None:
            robloxaccountid = str(accountid)
        else:
            embed = discord.Embed(
                title = f"에러 | 양식오류",
                description = f"$계정아이디 계정아이디",
                color = discord.Color.from_rgb(255, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)
    else:
        embed = discord.Embed(
            title = f"에러 | 주인 전용 명령어",
            description = f"유저추가 명령어는 주인만 사용 가능한 명령어입니다.",
            color = discord.Color.from_rgb(255, 0, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["유저추가"])
async def adduser(ctx, userid = None):
    await ctx.message.delete()
    if checkowner(ctx.author.id):
        if userid != None:
            targetchannel = ctx.channel

            user = await client.fetch_user(int(userid))

            await targetchannel.set_permissions(user, read_messages=True, send_messages=True)

            await ctx.send("해당 유저를 채널에 추가했습니다")

        else:
            embed = discord.Embed(
                title = f"에러 | 양식오류",
                description = f"$유저추가 디스코드아이디",
                color = discord.Color.from_rgb(255, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)
    else:
        embed = discord.Embed(
            title = f"에러 | 주인 전용 명령어",
            description = f"유저추가 명령어는 주인만 사용 가능한 명령어입니다.",
            color = discord.Color.from_rgb(255, 0, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["경매정보"])
async def auctioninfo(ctx, auctionid=None):
    if auctionid != None:
        if checkifauctionexists(auctionid):
            path = f"database/auction/ongoing/{auctionid}.json"

            with open(path) as f:
                r = json.load(f)
                f.close()

            itemname = r["itemname"]
            startingprice = r["startingprice"]
            bestpriceid = r["best_bet"]["userid"]
            bestpriceprice = r["best_bet"]["price"]

            startingprice = formatmoney(startingprice)
            bestpriceprice = formatmoney(bestpriceprice)

            targetuser = await client.fetch_user(int(bestpriceid))

            embed = discord.Embed(
                title = f"경매 정보",
                description = f"판매 제품: {itemname}\n시작가: {startingprice}\n\n현재최고가: {targetuser}, {bestpriceprice}",
                color = discord.Color.from_rgb(0, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)

        else:
            embed = discord.Embed(
                title = f"에러 | 존재하지 않는 경매 아이디",
                description = f"해당 경매 아이디는 존재하지 않습니다",
                color = discord.Color.from_rgb(255, 255, 0)
            )
            embed.set_footer(text=f"NastyCore, The Next Innovation")
            await ctx.send(embed=embed)
    else:
        embed = discord.Embed(
            title = f"에러 | 양식오류",
            description = f"`$경매정보 경매아이디`",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

@client.command(aliases=["경매참여"])
async def enterauction(ctx, auctionid=None, price=None):
    if auctionid != None and price != None:

        with open("database/auction/blacklist/blacklist.json") as f:
            jsondata = json.load(f)
            f.close()

        if ctx.author.id not in jsondata:
            if checkifauctionexists(auctionid):
                price = int(price)
                formatprice = formatmoney(price)
                path = f"database/auction/ongoing/{auctionid}.json"

                with open(path) as f:
                    r = json.load(f)
                    f.close()

                bestpriceprice = r["best_bet"]["price"]

                history_list = r["history"]
                currentbidid = r["bidid"]
                targetchannel = r["auctionchannel"]
                targetchannel = discord.utils.get(client.get_all_channels(), id = int(targetchannel))

                newbidid = currentbidid + 1

                r["bidid"] = newbidid

                bestformatprice = formatmoney(bestpriceprice)

                if int(bestpriceprice) >= int(price):
                    embed = discord.Embed(
                        title = f"에러 | 최고가보다 낮음",
                        description = f"현재 최고가({bestformatprice})보다 높게 설정해 주세요.",
                        color = discord.Color.from_rgb(255, 255, 0)
                    )
                    embed.set_footer(text=f"NastyCore, The Next Innovation")
                    await ctx.send(embed=embed)
                else:
                    format_dict = {
                        "userid": ctx.author.id,
                        "price": int(price),
                        "bidid": newbidid
                    }

                    history_list.append(format_dict)

                    r["best_bet"]["price"] = int(price)
                    r["best_bet"]["userid"] = ctx.author.id
                    r["best_bet"]["bidid"] = currentbidid

                    with open(path, "w") as f:
                        json.dump(r, f, indent=2)
                        f.close()

                    embed = discord.Embed(
                        title = f"새로운 경매 최고가",
                        description = f"{ctx.author.mention}님: {formatprice}\n입찰아이디: {newbidid}",
                        color = discord.Color.from_rgb(0, 255, 0)
                    )
                    embed.set_footer(text=f"NastyCore, The Next Innovation")
                    await targetchannel.send(embed=embed)

                    await ctx.send("ㅇㅋ")

            else:
                embed = discord.Embed(
                    title = f"에러 | 존재하지 않는 경매 아이디",
                    description = f"해당 경매 아이디는 존재하지 않습니다",
                    color = discord.Color.from_rgb(255, 255, 0)
                )
                embed.set_footer(text=f"NastyCore, The Next Innovation")
                await ctx.send(embed=embed)
    else:
        embed = discord.Embed(
            title = f"에러 | 양식오류",
            description = f"`$경매참여 경매아이디 가격`",
            color = discord.Color.from_rgb(255, 255, 0)
        )
        embed.set_footer(text=f"NastyCore, The Next Innovation")
        await ctx.send(embed=embed)

client.run("ODk2MzY4NTk1ODA0NzgyNjQy.YWGGTg.7AUnthC-deNyobLAGf8FjPRwoSk")


##########################################################################################
#                           PLC CONNECTION WITH SNAP 7                                   #
##########################################################################################

# import libraries
import snap7
from snap7 import util

# define IP, RACK & SLOT of PLC
IP = '192.168.0.1'
RACK = 0
SLOT = 1

# connect to PLC
plc = snap7.client.Client()
plc.connect(IP, RACK, SLOT)
plc.get_connected()

# reads the db number 1 starting from the byte 0 until byte 4 (real type).
db = plc.db_read(1, 0, 4)
t = util.get_real(db, 0)
print(t)

# reads the db number 1 starting from the byte 4 until byte 6 (int type).
db = plc.db_read(1, 4, 2)
t = util.get_int(db, 0)
print(t)

# reads the db number 1 starting from the byte 6 until byte 8 (int type).
db = plc.db_read(1, 6, 2)
t = util.get_int(db, 0)
print(t)

# reads the db number 1 starting from the byte 10 until byte 11 (bool type).
db = plc.db_read(1, 10, 1)
# read byte_index 0 and bit_index 0
t = util.get_bool(db, 0, 0)
print(t)

# writes the db number 2 a boolean status in bytearray
buffer = bytearray([0b00000001])
wt = plc.db_write(2, 0, buffer)
print(t)

#Bruno Oliveira

#--Refences
# https://python-snap7.readthedocs.io/en/latest/API/client.html


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django_markdown.models

class Migration(migrations.Migration):

    dependencies = [
        ('blog', '0003_auto_20170711_1514'),
    ]

    operations = [
        migrations.CreateModel(
            name='MyModel',
            fields=[
                ('id', models.AutoField(primary_key=True, verbose_name='ID', serialize=False, auto_created=True)),
                ('content', django_markdown.models.MarkdownField()),
            ],
        ),
    ]


import time
from datetime import datetime
import threading
import requests
from dotenv.main import load_dotenv
import os
import argparse

parser=argparse.ArgumentParser()

parser.add_argument("-p", "--path", help="Log file path to monitor.", required=True)
parser.add_argument("-mt", "--max_time", help="Max time in seconds to wait before send a message.", required=True)
parser.add_argument("-ph","--phrase", help="Phrase to monitor.", required=True)
args = parser.parse_args()

log_name = args.path
max_time = int(args.max_time)
phrase_to_monitor = args.phrase

load_dotenv()

def follow(thefile):
    thefile.seek(0,2) # Go to the end of the file
    while True:
        line = thefile.readline()
        if not line:
            time.sleep(0.1) # Sleep briefly
            continue
        yield line

logfile = open(log_name)
loglines = follow(logfile)

last_time_last_log = datetime.now()

def analyze_time(last_time_last_log):
    while True:
        delta = datetime.now() - last_time_last_log
        sec = delta.total_seconds()

        if sec > max_time:
            send_to_telegram(f'Se dejo de obtener logs con la frase {phrase_to_monitor} que se esta monitoreando.')
            break
        global stop_thread
        if stop_thread:
            break

def send_to_telegram(message):

    apiToken = os.environ['apiToken']
    chatID = os.environ['chatID']
    apiURL = f'https://api.telegram.org/bot{apiToken}/sendMessage'

    try:
        response = requests.post(apiURL, json={'chat_id': chatID, 'text': message})
    except Exception as e:
        pass

stop_thread = False
for line in loglines:
    last_time_last_log = datetime.now()
    if not phrase_to_monitor.lower() in line.lower():
        stop_thread = False
        x = threading.Thread(target=analyze_time, args=(last_time_last_log,))
        x.start()
    else:
        stop_thread = True


from rouge import Rouge as R
from prettytable import PrettyTable

class Rouge:
    def __init__(self, evaluated_sentences, reference_sentences):
        rouge = R()
        eval_sents = None
        ref_sents = None
        if type(evaluated_sentences) is list:
            eval_sents = ' '.join(evaluated_sentences)
        else:
            eval_sents = evaluated_sentences
        if type(reference_sentences) is list:
            ref_sents = ' '.join(reference_sentences)
        else:
            ref_sents = reference_sentences
        self._score = rouge.get_scores(eval_sents, ref_sents)[0]

    def get_rouge(self):
        return self._score

    def get_rouge_1(self):
        return self._score["rouge-1"]

    def get_rouge_2(self):
        return self._score["rouge-2"]

    def get_rouge_l(self):
        return self._score["rouge-l"]

    @staticmethod
    def cal_avg_rouge(rouges):
        """
        :param rouges: list
            List of dict.
        :return: dict
        """
        avg_rouge = rouges[0]
        n = len(rouges)
        if n > 1:
            for rouge in rouges[1:]:
                for k in rouge:
                    avg_rouge[k]["f"] += rouge[k]["f"]
                    avg_rouge[k]["p"] += rouge[k]["p"]
                    avg_rouge[k]["r"] += rouge[k]["r"]
            for v in avg_rouge.values():
                v["f"] /= n
                v["p"] /= n
                v["r"] /= n

        return avg_rouge

    @staticmethod
    def print(labels, rouges):
        if type(labels) is not list:
            labels = [labels]
        if type(rouges) is not list:
            rouges = [rouges]
        for k in rouges[0]:
            print(k)
            t = PrettyTable(['Summarizer', 'F1-score', 'Precision', 'Recall'])
            for i, v in enumerate(labels):
                t.add_row([v] + list(rouges[i][k].values()))
            print(t)


from datetime import datetime as dt
import pandas as pd
from contextlib import contextmanager
import requests as re
from bs4 import BeautifulSoup
import time
from pathlib import Path

@contextmanager
def nested_break():
    '''
    Custom exception to break out of nested loops.
    '''
    class NestedBreakException(Exception):
        pass
    try:
        yield NestedBreakException
    except NestedBreakException:
        pass

def report_exchange(url, last_update):
    '''
    Exchange Rate crawler.
    url: any exchange page on finance.naver.com
    last_update: data will be crawled up to this date. Has to be datetime.date object.
    '''
    page = 1
    dataset = []

    cols = [
        '날짜', '매매기준율', '전일대비', '현찰 사실 때', '현찰 파실 때',
        '송금 보내실 때', '송금 받으실 때', 'T/C 사실 때', '외화수표 파실 때'
    ]

    with nested_break() as escape:
        while True:
            response = re.get(url+f'&page={page}')
            print(f'Processing page {page}')
            page += 1
            response_soup = BeautifulSoup(response.content, 'html.parser')
            tbody = response_soup.find('tbody')
            rows = tbody.find_all('tr')
            if len(rows) == 0:
                # if there is no data, then that's probably the end of data
                break

            for tr in rows:
                status = tr.attrs['class'][0]
                row = tr.find_all('td')
                row_parse = {}
                for i, (data, col) in enumerate(zip(row, cols)):
                    if i == 0:
                        date = data.text.replace('.', '-').strip()
                        date_dt = pd.to_datetime(date)
                        if date_dt == last_update:
                            raise escape
                        row_parse[col] = date
                    elif i == 2:
                        if status == 'down':
                            row_parse[col] = float('-' + data.text.replace(',', '').strip())
                        else:
                            row_parse[col] = float(data.text.replace(',', '').strip())
                    else:
                        row_parse[col] = float(data.text.replace(',', '').strip())
                dataset.append(row_parse)

    return dataset

USDKRW = 'https://finance.naver.com/marketindex/exchangeDailyQuote.nhn?marketindexCd=FX_USDKRW'

data_file = Path('exchange_rate.csv')

if data_file.is_file():
    print(f'{data_file} was found. Proceeding to UPDATE.')
    exchange_rate_df = pd.read_csv('exchange_rate.csv')
    exchange_rate_df['날짜'] = pd.to_datetime(exchange_rate_df['날짜'])
    last_update = exchange_rate_df['날짜'].max()
    #last_update = pd.to_datetime('2020-10-23')
    update_data = report_exchange(USDKRW, last_update)
    update_size = len(update_data)
    if update_size > 0:
        print(f'{update_size} number of updates available')
        update_data_df = pd.DataFrame(update_data)
        update_data_df['날짜'] = pd.to_datetime(update_data_df['날짜'])
        updated_df = pd.concat([exchange_rate_df, update_data_df], ignore_index=True)
        updated_df.drop_duplicates(subset=['날짜'], inplace=True)
        updated_df.sort_values(['날짜'], ascending=False, inplace=True)
        print('data updated. Now saving.')
        updated_df.to_csv('exchange_rate.csv', index=False)
    else:
        print('No Update Available')
else:
    print(f'{data_file} was NOT found. Proceeding to crawl ALL data.')
    last_update = None
    exchange_rate_data = report_exchange(USDKRW, last_update)
    exchange_rate_df = pd.DataFrame(exchange_rate_data)
    exchange_rate_df['날짜'] = pd.to_datetime(exchange_rate_df['날짜'])
    exchange_rate_df.sort_values(['날짜'], ascending=False, inplace=True)
    exchange_rate_df.to_csv('exchange_rate.csv', index=False)


from django.urls import path
from .views import (
    home,
    single_product,
    product_info_2,
    product_info,
    blog,
    about_us,
    wishlist,
    contact,
    shoppingcart,
    posts,
    delete,
    update,
    delete_wishlist,
    user_profile,
    user_edit_page,
    checkout
)

urlpatterns = [
    path('', home, name='home'),
    path('<int:pk>/', single_product, name='single_product'),
    path('shopleftcolumn/', product_info , name='shopleftcolumn'),
    path('shopcolumn/', product_info_2 , name='shopcolumn2'),
    path('blog/', blog , name='blog'),
    path('about/', about_us , name='about_us'),
    path('wishlist/', wishlist , name='wishlist'),
    path('contact/', contact , name='contact'),
    path('shoppingcart/', shoppingcart , name='shoppingcart'),
    path('update/<int:pk>/', update, name='update'),
    path('delete/<int:pk>/', delete, name='delete'),
    path('delete_wishlist/<int:pk>/', delete_wishlist, name='delete_wishlist'),
    path('userprofile/', user_profile, name='userprofile'),
    path('userinfoedit/<int:pk>/', user_edit_page, name='userinfoedit'),
    path('checkout', checkout, name='checkout'),

    path('posts/', posts , name='posts'),

]


import os
import codecs
import six
import numpy as np

# pylint: disable=no-member

def load_data_numpy(input_dir, prefix):
    train_data = np.load(
        os.path.join(input_dir, prefix + "train.npy"),
        encoding="latin1",
        allow_pickle=True,
    ).tolist()
    dev_data = np.load(
        os.path.join(input_dir, prefix + "valid.npy"),
        encoding="latin1",
        allow_pickle=True,
    ).tolist()
    test_data = np.load(
        os.path.join(input_dir, prefix + "test.npy"),
        encoding="latin1",
        allow_pickle=True,
    ).tolist()
    print("train data size:{}".format(len(train_data)))
    return train_data, dev_data, test_data

def seq2seq_pad_concat_convert(xy_batch, eos_id=2, bos_id=1):
    """
    Args:
        xy_batch (list of tuple of two numpy.ndarray-s or cupy.ndarray-s):
            xy_batch[i][0] is an array
            of token ids of i-th input sentence in a minibatch.
            xy_batch[i][1] is an array
            of token ids of i-th target sentence in a minibatch.
            The shape of each array is `(sentence length, )`.
        eos_id: The index of end-of-sentence special token in the
            dictionary.

    Returns:
        Tuple of Converted array.
            (input_sent_batch_array, target_sent_batch_input_array,
            target_sent_batch_output_array).
            The shape of each array is `(batchsize, max_sentence_length)`.
            All sentences are padded with 0 to reach max_sentence_length.
    """

    x_seqs, y_seqs = zip(*xy_batch)
    x_block = _concat_examples(x_seqs, padding=0)
    y_block = _concat_examples(y_seqs, padding=0)

    # Add EOS
    x_block = np.pad(x_block, ((0, 0), (0, 1)), "constant", constant_values=0)
    for i_batch, seq in enumerate(x_seqs):
        x_block[i_batch, len(seq)] = eos_id

    y_out_block = np.pad(
        y_block, ((0, 0), (0, 1)), "constant", constant_values=0
    )
    for i_batch, seq in enumerate(y_seqs):
        y_out_block[i_batch, len(seq)] = eos_id

    # Add BOS in target language
    y_in_block = np.pad(
        y_block, ((0, 0), (1, 0)), "constant", constant_values=bos_id
    )
    return x_block, y_in_block, y_out_block

def source_pad_concat_convert(x_seqs, eos_id=2, bos_id=1):
    """
    This function is used when testing the model without target input.
    """
    x_block = _concat_examples(x_seqs, padding=0)

    # add EOS
    x_block = np.pad(x_block, ((0, 0), (0, 1)), "constant", constant_values=0)
    for i_batch, seq in enumerate(x_seqs):
        x_block[i_batch, len(seq)] = eos_id
    return x_block

def _concat_examples(arrays, padding=0):
    if len(arrays) == 0:
        raise ValueError("batch is empty")

    first_elem = arrays[0]
    assert isinstance(first_elem, np.ndarray)

    shape = np.array(arrays[0].shape, dtype=int)
    for array in arrays[1:]:
        if np.any(shape != array.shape):
            np.maximum(shape, array.shape, shape)
    shape = tuple(np.insert(shape, 0, len(arrays)))

    result = np.full(shape, padding, dtype=arrays[0].dtype)
    for i in six.moves.range(len(arrays)):
        src = arrays[i]
        slices = tuple(slice(dim) for dim in src.shape)
        result[(i,) + slices] = src
    return result

def write_words(words_list, filename):
    with codecs.open(filename, "w+", "utf-8") as myfile:
        for words in words_list:
            myfile.write(" ".join(words) + "\n")


from __future__ import unicode_literals
from jsonfield import JSONField
import pytz

from django.db import models
from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible

from health_monitor import utils

@python_2_unicode_compatible
class Health(models.Model):
    uid = models.IntegerField(primary_key=True, db_index=True)
    state = JSONField(default={}, blank=True, null=True)
    severity = JSONField(default={}, blank=True, null=True)
    history = JSONField(default={}, blank=True, null=True)

    def __str__(self):
        return str(self.uid)

    def _calculate_severity(self, group):
        """Return a severity calculation.

        The severity is the highest score in state dict of a group.

        Arguments:
        g -- group
        """
        test_scores = [1, ]
        for t in self.state[group].keys():
            if self.state[group][t]['score']:
                test_scores.append(self.state[group][t]['score'])

        return max(test_scores)

    @classmethod
    def get_or_create(cls, *args, **kwargs):
        try:
            return cls.objects.get(**kwargs)
        except Exception:
            return cls.objects.create(**kwargs)

    def update_score(self, test, score):
        """Update the health state, health severity, and health history.

        These are updated based on the test name and score.

        Arguments:
        test  -- test
        score -- score
        """

        # update state and severity
        for group in HealthTest._get_groups(test):
            if test in HealthTest._get_tests(group):
                if group not in self.state.keys():
                    self.state[group] = {}
                self.state[group] = utils.init_score_dict(
                    self.state[group], test)
                self.state[group][test] = utils.update_score_dict(
                    self.state[group][test], score)
                self.severity = utils.init_score_dict(self.severity, group)
                self.severity[group] = utils.update_score_dict(
                    self.severity[group], self._calculate_severity(group))

        # update history
        if test not in self.history.keys():
            self.history[test] = [score]
        else:
            self.history[test] = utils.push_pop_deque(
                score, self.history[test])

        self.save()

    def delete_test(self, test):
        """Delete a test from all groups.

        Deleting a test results in recalculations of all health states per
        group and the health severity.
        """
        for group in self.state.keys():
            if test in self.state[group].keys():
                del(self.state[group][test])
                self.severity[group] = utils.update_score_dict(
                    self.severity[group], self._calculate_severity(group))
        self.save()

    def delete_group(self, group):
        """Delete group from health state and severity."""
        del(self.state[group])
        del(self.severity[group])
        self.save()

    def delete_group_test(self, group, test):
        """Delete test entry from specified group's health state.

        This also results in an updated severity.
        """
        if test in self.state[group].keys():
            del(self.state[group][test])
            self.severity[group] = utils.update_score_dict(
                self.severity[group], self._calculate_severity(group))
        self.save()

    def get_latest_scores(self, test, repetition):
        """Get latest x scores from HealthTest historical records.

        Where x is the number of repetitions.
        """
        test_model = HealthTest._get_model(test)
        return [
            x.get_score() for x in test_model.objects.filter(
                uid=self.uid).order_by('-time')[:repetition]
        ]

    def get_history(self, test, repetition):
        """Return the cached x test scores or retrieve from historical records.

        Where x is the number of repetitions.
        """
        try:
            if not len(self.history[test]) >= repetition:
                raise Exception
        except Exception:
            self.history[test] = self.get_latest_scores(test, repetition)
            self.save()
        return self.history[test][0:repetition]

    class Meta(object):
        abstract = True

class HealthAlarm(object):
    @classmethod
    def _get_associated_healths(cls, group, test):
        """Return a subset of healths

        That contain the nested group and test key.
        """
        healths = []
        for health in cls.health_model.objects.all():
            if group in health.state.keys():
                if test in health.state[group].keys():
                    healths.append(health)

        return healths

    @classmethod
    def calculate_alarms(
        cls, group, test, score, aggregate_percent=0, repetition=1,
        repetition_percent=100, **kwargs
    ):
        """Return a list of asset uids based off of filtering criteria.

        Arguments:
        group              -- group name
        test               -- test name
        score              -- minimum score to tigger an alarm
        aggregate_percent  -- minimum percentage of test failures to trigger an
            alarm
        repetition         -- minimum number of test failures in a row to
            trigger an alarm
        repetition_percent -- minimum percentage of failures within repetition
            to trigger an alarm
        """
        healths = cls._get_associated_healths(group, test)

        # step 1: filter failing assets by score, if repetition_percent is less
        # than 100%, all healths must be checked
        if repetition_percent == 100:
            failing_healths_by_score = [
                x for x in healths if x.state[group][test]['score'] >= score]
        else:
            failing_healths_by_score = healths

        # step 2: filter failing assets by repetition criteria
        failing_healths = []
        for health in failing_healths_by_score:
            score_history = health.get_history(test, repetition)
            failing_count = len([x for x in score_history if x >= score])
            if 100 * failing_count / len(score_history) >= repetition_percent:
                failing_healths.append(health)

        # step 3: return empty array if percentage of failing assets is below
        # aggregate_percent
        if (len(failing_healths) / len(healths)) < (aggregate_percent / 100):
            return []
        else:
            return [x.uid for x in failing_healths]

class HealthTest(models.Model):
    uid = models.IntegerField(db_index=True)
    time = models.DateTimeField()

    test = None
    groups = []
    health_model = Health

    def __str__(self):
        return str(self.uid)

    @classmethod
    def create(cls, uid, **kwargs):
        health_test = cls(uid=uid, time=timezone.now(), **kwargs)
        health_test.save()

        h = cls.health_model.get_or_create(uid=uid)
        h.update_score(test=cls.test, score=cls.calculate_score(**kwargs))

        return health_test

    @classmethod
    def calculate_score(cls, **kwargs):
        """Returns the score.

        This is calculated from derived class' score() method and inputted
        kwargs.
        """
        score = cls.score(**kwargs)
        if type(score) != int:
            raise TypeError('score method should return an integer')
        elif score < 0:
            raise ValueError('score method should return a positive integer')
        else:
            return score

    def get_score(self):
        """Returns the score.

        This is calculated using self.calculate_score() and instance attributes
        (db columns).
        """
        kwargs = {
            x.name: getattr(self, x.name) for x in type(self)._meta.fields}
        return type(self).calculate_score(**kwargs)

    @classmethod
    def get_history(
        cls, uids=None,
        start_time=timezone.datetime.min.replace(tzinfo=pytz.UTC),
        end_time=timezone.datetime.max.replace(tzinfo=pytz.UTC)
    ):
        """Returns historical test results.

        Arguments:
        uids       -- a list of uids
        start_time -- a datetime object
        end_time   -- a datetime object
        """
        if uids:
            return cls.objects.filter(
                uid__in=uids, **{'time__range': (start_time, end_time)})
        else:
            return cls.objects.filter(
                **{'time__range': (start_time, end_time)})

    @staticmethod
    def _get_tests(group=None):
        """Return list of test names associated with a group."""
        if not group:
            return [t.test for t in HealthTest.__subclasses__()]
        return [
            t.test for t in HealthTest.__subclasses__() if group in t.groups]

    @classmethod
    def _get_groups(cls, test=None):
        """Return a list of group names.

        These are associated with a test or all groups if no test is passed.
        """
        if not test:
            return utils.merge_to_uniques(
                [x.groups for x in cls.__subclasses__()])
        for t in HealthTest.__subclasses__():
            if test == t.test:
                return t.groups
        return []

    @staticmethod
    def _get_model(test):
        """Return the model associated with a test."""
        for t in HealthTest.__subclasses__():
            if test == t.test:
                return t
        raise TypeError('test {} does not exist'.format(test))

    class Meta(object):
        abstract = True


# -*- test-case-name: foolscap.test.test_banana -*-

from __future__ import print_function
from twisted.internet import defer
from twisted.python import log
from foolscap.slicers.list import ListSlicer
from foolscap.slicers.tuple import TupleUnslicer
from foolscap.slicer import BaseUnslicer
from foolscap.tokens import Violation
from foolscap.constraint import OpenerConstraint, Any, IConstraint
from foolscap.util import AsyncAND

class SetSlicer(ListSlicer):
    opentype = ("set",)
    trackReferences = True
    slices = set

    def sliceBody(self, streamable, banana):
        for i in self.obj:
            yield i

class FrozenSetSlicer(SetSlicer):
    opentype = ("immutable-set",)
    trackReferences = False
    slices = frozenset

class _Placeholder:
    pass

class SetUnslicer(BaseUnslicer):
    # this is a lot like a list, but sufficiently different to make it not
    # worth subclassing
    opentype = ("set",)

    debug = False
    maxLength = None
    itemConstraint = None

    def setConstraint(self, constraint):
        if isinstance(constraint, Any):
            return
        assert isinstance(constraint, SetConstraint)
        self.maxLength = constraint.maxLength
        self.itemConstraint = constraint.constraint

    def start(self, count):
        #self.opener = foo # could replace it if we wanted to
        self.set = set()
        self.count = count
        if self.debug:
            log.msg("%s[%d].start with %s" % (self, self.count, self.set))
        self.protocol.setObject(count, self.set)
        self._ready_deferreds = []

    def checkToken(self, typebyte, size):
        if self.maxLength != None and len(self.set) >= self.maxLength:
            # list is full, no more tokens accepted
            # this is hit if the max+1 item is a primitive type
            raise Violation("the set is full")
        if self.itemConstraint:
            self.itemConstraint.checkToken(typebyte, size)

    def doOpen(self, opentype):
        # decide whether the given object type is acceptable here. Raise a
        # Violation exception if not, otherwise give it to our opener (which
        # will normally be the RootUnslicer). Apply a constraint to the new
        # unslicer.
        if self.maxLength != None and len(self.set) >= self.maxLength:
            # this is hit if the max+1 item is a non-primitive type
            raise Violation("the set is full")
        if self.itemConstraint:
            self.itemConstraint.checkOpentype(opentype)
        unslicer = self.open(opentype)
        if unslicer:
            if self.itemConstraint:
                unslicer.setConstraint(self.itemConstraint)
        return unslicer

    def update(self, obj, placeholder):
        # obj has already passed typechecking
        if self.debug:
            log.msg("%s[%d].update: [%s]=%s" % (self, self.count,
                                                placeholder, obj))
        self.set.remove(placeholder)
        self.set.add(obj)
        return obj

    def receiveChild(self, obj, ready_deferred=None):
        if ready_deferred:
            self._ready_deferreds.append(ready_deferred)
        if self.debug:
            log.msg("%s[%d].receiveChild(%s)" % (self, self.count, obj))
        # obj could be a primitive type, a Deferred, or a complex type like
        # those returned from an InstanceUnslicer. However, the individual
        # object has already been through the schema validation process. The
        # only remaining question is whether the larger schema will accept
        # it.
        if self.maxLength != None and len(self.set) >= self.maxLength:
            # this is redundant
            # (if it were a non-primitive one, it would be caught in doOpen)
            # (if it were a primitive one, it would be caught in checkToken)
            raise Violation("the set is full")
        if isinstance(obj, defer.Deferred):
            if self.debug:
                log.msg(" adding my update[%d] to %s" % (len(self.set), obj))
            # note: the placeholder isn't strictly necessary, but it will
            # help debugging to see a _Placeholder sitting in the set when it
            # shouldn't rather than seeing a set that is smaller than it
            # ought to be. If a remote method ever sees a _Placeholder, then
            # something inside Foolscap has broken.
            placeholder = _Placeholder()
            obj.addCallback(self.update, placeholder)
            obj.addErrback(self.printErr)
            self.set.add(placeholder)
        else:
            self.set.add(obj)

    def printErr(self, why):
        print("ERR!")
        print(why.getBriefTraceback())
        log.err(why)

    def receiveClose(self):
        ready_deferred = None
        if self._ready_deferreds:
            ready_deferred = AsyncAND(self._ready_deferreds)
        return self.set, ready_deferred

class FrozenSetUnslicer(TupleUnslicer):
    opentype = ("immutable-set",)

    def receiveClose(self):
        obj_or_deferred, ready_deferred = TupleUnslicer.receiveClose(self)
        if isinstance(obj_or_deferred, defer.Deferred):
            def _convert(the_tuple):
                return frozenset(the_tuple)
            obj_or_deferred.addCallback(_convert)
        else:
            obj_or_deferred = frozenset(obj_or_deferred)
        return obj_or_deferred, ready_deferred

class SetConstraint(OpenerConstraint):
    """The object must be a Set of some sort, with a given maximum size. To
    accept sets of any size, use maxLength=None. All member objects must obey
    the given constraint. By default this will accept both mutable and
    immutable sets, if you want to require a particular type, set mutable= to
    either True or False.
    """

    # TODO: if mutable!=None, we won't throw out the wrong set type soon
    # enough. We need to override checkOpenType to accomplish this.
    opentypes = [("set",), ("immutable-set",)]
    name = "SetConstraint"

    def __init__(self, constraint, maxLength=None, mutable=None):
        self.constraint = IConstraint(constraint)
        self.maxLength = maxLength
        self.mutable = mutable

    def checkObject(self, obj, inbound):
        if not isinstance(obj, (set, frozenset)):
            raise Violation("not a set")
        if (self.mutable == True and
            not isinstance(obj, set)):
            raise Violation("obj is a set, but not a mutable one")
        if (self.mutable == False and
            not isinstance(obj, frozenset)):
            raise Violation("obj is a set, but not an immutable one")
        if self.maxLength is not None and len(obj) > self.maxLength:
            raise Violation("set is too large")
        if self.constraint:
            for o in obj:
                self.constraint.checkObject(o, inbound)


from setuptools import setup, find_packages

from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup(name='brain-pred-toolbox',
      version='2.3.2',
      long_description=long_description,
      long_description_content_type='text/markdown',
      description='The Brain Predictability toolbox (BPt) is a ' +
      'Python based machine learning library designed to work with ' +
      'a range of neuroimaging data. Warning: Not actively maintained ' +
      'as of 11/30/22.',
      url='http://github.com/sahahn/BPt',
      author='Sage Hahn',
      author_email='sahahn@euvm.edu',
      license='MIT',
      packages=find_packages(),
      python_requires=">=3.8",
      install_requires=[
          'scikit-learn>=1.1.0,<1.1.4',
          'numpy>=1.21,<1.24',
          'scipy>=1.2,<2.0',
          'pandas>=1.1.5,<1.6',
          'matplotlib>=3.2.2,<3.7',
          'seaborn>=0.9,<0.13',
          'scikit-image>=0.16',
          'tqdm>=4.51',
          'nevergrad>=0.5.0,<0.6',
          'Ipython',
          'joblib>=1,<2',
          'loky',
          'threadpoolctl>=3'
      ],
      extras_require={
          'extra': ['lightgbm>=3.3.0',
                    'nilearn>=0.9',
                    'python-docx',
                    'mvlearn',
                    'imblearn',
                    'xgboost>=1.4',
                    'bp-neurotools'],
       },
      test_suite='pytest',
      tests_require=['pytest', 'coverage'],
      zip_safe=False)


#!/usr/bin/env python
# −*− coding: UTF−8 −*−
from __future__ import division

import numpy.testing as npt
import pytest

import numpy as np

from bspline.knots import Knots, get_basis_knots

@pytest.fixture
def knots():
    return Knots(np.array([0.,0,1,1]), degree=2)

def test_intervals(knots):
    intervals = list(knots.intervals())
    assert len(intervals) == knots.nb_curves

def test_left_knot(knots):
    assert knots.left_knot(.2) == 1
    assert knots.left_knot(.8) == 1

def test_info():
    knots = Knots([0,0,.5,1,1], degree=2)
    assert knots.degree == 2
    assert knots.nb_curves == 2
    assert len(knots.knot_range()) == knots.nb_curves

def test_intervals():
    knots = np.array([0,0,.5,1,1])
    K = Knots(knots, degree=3)
    intervals = list(K.intervals())
    assert len(intervals) == K.nb_curves

@pytest.fixture
def long_knots():
    values = np.array([1.,2.,3.,4.,5.,6.,7.])
    knots = Knots(values, degree=3)
    return knots

def test_get_item(long_knots):
    values = long_knots.knots
    for i,v in enumerate(values):
        assert long_knots[i] == values[i]

def test_left_knot(long_knots):
    knots = long_knots
    assert knots.left_knot(3.8) == 2
    assert knots.left_knot(3.2) == 2
    assert knots.left_knot(4.8) == 3
    assert knots.left_knot(4.0) == 3
    assert knots.left_knot(4.0-1e-14) == 3
    with pytest.raises(ValueError):
        knots.left_knot(2.5)
    with pytest.raises(ValueError):
        knots.left_knot(5.5)

def test_knot_range(long_knots):
    knots = long_knots
    k = Knots(np.arange(10))
    assert len(k.knot_range()) == 0

def test_abscissae(rng=None):
    rng = np.random.default_rng(rng)
    pts = rng.random([7,2])
    knots = [0,0,0,2,3,4,5,5,5]
    K = Knots(knots, degree=3)
    computed = K.abscissae()
    expected = np.array([0, 2/3, 5/3, 3, 4, 14/3, 5]) # values from Sederberg §6.14
    npt.assert_allclose(computed, expected)

def test_nonuniform():
    a,b,c = 0., 2.5, 8
    ck = get_basis_knots([a,b,c]).get_basis()
    npt.assert_allclose(ck(a)[1], 0)
    npt.assert_allclose(ck(b)[1], 1.)
    npt.assert_allclose(ck(c)[1], 0.)

def test_constant_abscissae():
    k = get_basis_knots(np.arange(2))
    k.abscissae()

def test_sum_to_one():
    """
    Check that the basis functions sum up to one.
    """
    w = [ 0, 0, 0, 1/3, 2/3, 1, 1, 1]
    wk = Knots(w, degree=3)
    basis = [wk.get_basis(i) for i in range(6)]
    vals = []
    for b in basis:
        vals_b = []
        for s in b:
            l,r = s.interval
            ts = np.linspace(l,r)
            vals_b.append(s(ts))
        vals.append(vals_b)
    avals = np.array(vals)
    npt.assert_allclose(np.sum(avals[:,:,:,1], axis=0), 1.)


from __future__ import absolute_import
from __future__ import print_function
from __future__ import division

from six.moves import xrange

from tensorforce.core import Agent
from tensorforce.core.memories import ReplayMemory

class MemoryAgent(Agent):

    default_config = dict(
        batch_size=32,
        memory_capacity=1000000,
        update_frequency=4,
        first_update=10000,
        repeat_update=1
    )

    def __init__(self, config):
        config.default(MemoryAgent.default_config)
        super(MemoryAgent, self).__init__(config)

        self.batch_size = config.batch_size
        self.memory = ReplayMemory(capacity=config.memory_capacity, states_config=config.states, actions_config=config.actions)
        self.update_frequency = config.update_frequency
        self.first_update = config.first_update
        self.repeat_update = config.repeat_update

    def observe(self, state, action, reward, terminal):
        if self.unique_state:
            state = dict(state=state)
        if self.unique_action:
            action = dict(action=action)

        self.memory.add_experience(state=state, action=action, reward=reward, terminal=terminal, internal=self.internals)

        if self.timestep >= self.first_update and self.timestep % self.update_frequency == 0:
            for _ in xrange(self.repeat_update):
                batch = self.memory.get_batch(batch_size=self.batch_size)
                self.model.update(batch=batch)


# Keithley_2230.py driver for Keithley 2230 power supply
#
# Sam Hile <samhile@gmail.com>
# Daniel Widmann <>
# Gabriele de Boo <ggdeboo@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

from instrument import Instrument
import visa
import types
import logging
import numpy
import re

import qt

def bool_to_str(val):
    '''
    Function to convert boolean to 'ON' or 'OFF'
    '''
    if val == True:
        return "ON"
    else:
        return "OFF"

class Keithley_2230(Instrument):
    '''
    This is the driver for the Keithley 2230 Multimeter

    Usage:
    Initialize with
    <name> = instruments.create('<name>', 'Keithley_2230',
        address='<GBIP address>',
        reset=<bool>)
    '''

    def __init__(self, name, address, reset=False):
        '''
        Initializes the Keithley_2230, and communicates with the wrapper.

        Input:
            name (string)           : name of the instrument
            address (string)        : GPIB address
            reset (bool)            : resets to default values
        Output:
            None
        '''
        # Initialize wrapper functions
        logging.info('Initializing instrument Keithley_2230')
        Instrument.__init__(self, name, tags=['physical', 'measure'])

        # Add some global constants
        self._address = address
        self._visainstrument = visa.instrument(self._address)

        # Add parameters to wrapper
        self.add_parameter('voltage',
            flags=Instrument.FLAG_GETSET,
            units='V', minval=0, maxval=30, type=types.FloatType,
            channels=(1,2,3))
        self.add_parameter('voltage_reading',
            flags=Instrument.FLAG_GET,
            units='V', minval=0, maxval=30, type=types.FloatType,
            channels=(1,2,3))
        self.add_parameter('current',
            flags=Instrument.FLAG_GETSET,
            units='A', minval=0, maxval=5, type=types.FloatType,
            channels=(1,2,3))
        self.add_parameter('current_reading',
            flags=Instrument.FLAG_GET,
            units='A', minval=0, maxval=5, type=types.FloatType,
            channels=(1,2,3))
        self.add_parameter('active',
            flags=Instrument.FLAG_GETSET,
            type=types.BooleanType, channels=(1,2,3))
#        self.add_parameter('remote_status',
#            flags=Instrument.FLAG_GETSET,
#            type=types.BooleanType)
        # Add functions to wrapper

        self.set_parameter_bounds('voltage3', 0, 6)
        self.set_parameter_bounds('current1', 0, 1.5)
        self.set_parameter_bounds('current2', 0, 1.5)

        self.add_function('reset')
        self.add_function('get_all')
        self.add_function('set_remote')

        if reset:
            self.reset()
        else:
            pass#self.get_all()

# --------------------------------------
#           functions
# --------------------------------------

    def reset(self):
        '''
        Resets instrument to default values

        Input:
            None

        Output:
            None
        '''
        logging.debug('Resetting instrument')
        self._visainstrument.write('*RST')
        self.get_all()

    def get_all(self):
        '''
        Reads all relevant parameters from instrument

        Input:
            None

        Output:
            None
        '''
        logging.info('Get all relevant data from device')
        self.get_active1()
        self.get_active2()
        self.get_active3()
        self.get_voltage1()
        self.get_voltage2()
        self.get_voltage3()
        self.get_voltage_reading1()
        self.get_voltage_reading2()
        self.get_voltage_reading3()
        self.get_current_reading1()
        self.get_current_reading2()
        self.get_current_reading3()

########

    def do_get_voltage(self,channel):
        '''
        Get voltage for a specified channel
            in: ch - channel number
            out: voltage [Volts]
        '''
        logging.debug('Getting voltage from instrument')
        self._visainstrument.write('INST:SEL CH%d' % channel)
        return self._visainstrument.ask('SOUR:VOLTAGE?')

    def do_get_voltage_reading(self,channel):
        '''
        Get voltage for a specified channel
            in: ch - channel number
            out: voltage [Volts]
        '''
        logging.debug('Getting voltage from instrument')
        return self._visainstrument.ask('MEAS:VOLT? CH%d' % channel)

    def do_set_voltage(self,v,channel):
        '''
        Get voltage for a specified channel
            in: ch - channel number
                v - voltage [Volts]
            out: none
        '''
        logging.debug('Sending voltage to instrument')
        self._visainstrument.write('INST:SEL CH%d' % channel)
        self._visainstrument.write('SOUR:VOLT %.3fV' % v)
#        self._visainstrument.write('SOUR:APP CH%d,%fV' % (channel,v))
        return

    def do_get_current(self, channel):
        '''
        Get current for a specified channel
            in: ch - channel number
            out: current [A]
        '''
        logging.debug(__name__ + ': Getting current from instrument')
        self._visainstrument.write('INST:SEL CH%d' % channel)
        return self._visainstrument.ask('SOUR:CURR?')

    def do_set_current(self, I, channel):
        '''
        Set current for a specified channel
            in: ch - channel number
            out: current [A]
        '''
        logging.debug(__name__ + ': Setting current to %.3f' % I)
        self._visainstrument.write('INST:SEL CH%d' % channel)
        self._visainstrument.write('SOUR:CURR %.3fA' % I)
        return

    def do_get_current_reading(self, channel):
        '''
        Get current reading for a specified channel
            in: ch - channel number
            out:
        '''
        logging.debug(__name__ + ': Getting current from instrument')
        return self._visainstrument.ask('MEAS:CURR? CH%d' % channel)

    def do_get_active(self,channel):
        '''
        Get voltage for a specified channel
            in: ch - channel number
            out: active_status [Boolean]
        '''
        logging.debug('Getting active status from instrument')
        self._visainstrument.write('INST:SEL CH%d' % channel)
        answer = self._visainstrument.ask('CHAN:OUTP?')
        if answer == '1':
            return True
        elif answer =='0':
            return False
        else:
            logging.warning(__name__ + ': responded with unexpected answer: %s' % answer)

    def do_set_active(self,a,channel):
        '''
        Get voltage for a specified channel
            in: ch - channel number
                a - active_status [Boolean]
            out: none
        '''
        logging.debug('Sending active status to instrument')
        self._visainstrument.write('INST:SEL CH%d' % channel)
        self._visainstrument.write('CHAN:OUTP %s' % bool_to_str(a))
        return

    def set_remote(self):
        self._visainstrument.write('SYST:REM')


from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _

from applications.enums import AdditionalInfoUserReason

def validate_additional_info_user_reasons(
    input_reasons_list, allow_empty_list=True
) -> None:
    """
    Validate input_reasons_list as a list of unique values from AdditionalInfoUserReason.
    The list may be empty only if allow_empty_list is True.

    :raises ValidationError: If input_reasons_list is not a list of unique values from
                             AdditionalInfoUserReason, or if allow_empty_list is False
                             and input_reasons_list is an empty list.
    """
    if not isinstance(input_reasons_list, list):
        raise ValidationError(
            _("additional_info_user_reasons must be a list, was %(type)s")
            % {"type": type(input_reasons_list)}
        )

    if input_reasons_list == [] and not allow_empty_list:
        raise ValidationError(
            "additional_info_user_reasons must be non-empty, was empty"
        )

    valid_reasons_set = set(AdditionalInfoUserReason.values)

    try:
        input_reasons_set = set(input_reasons_list)
    except TypeError:
        raise ValidationError(
            _("Invalid type input values for additional_info_user_reasons")
        )

    if not input_reasons_set.issubset(valid_reasons_set):
        raise ValidationError(
            _(
                "additional_info_user_reasons must contain only values from "
                "AdditionalInfoUserReason, contained invalid values %(invalid_values)s"
            )
            % {"invalid_values": sorted(input_reasons_set - valid_reasons_set)}
        )

    if len(input_reasons_list) != len(input_reasons_set):
        raise ValidationError(
            "additional_info_user_reasons must contain unique values, contained duplicates"
        )