#!/usr/bin/env python
# -*- coding: utf-8 -*-

from kivy.factory import Factory
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button

from electrum_zcash.gui.kivy.i18n import _
from electrum_zcash.logging import Logger
from electrum_zcash.plugin import run_hook

Builder.load_string('''
<PluginLabel@ButtonBehavior+Label>
    text_size: self.size
    halign: 'left'
    valign: 'middle'

<PluginWidget@BoxLayout>
    fullname: ''
    orientation: 'horizontal'
    size_hint: 0.6, None
    height: '48dp'
    CheckBox:
        id: cb
        disabled: False
        active: False
        size_hint: None, 1
        width: '48dp'
        on_active: root.on_cb_active(self.active)
    PluginLabel:
        on_release: cb.active = not cb.active
        text: root.fullname
        disabled: cb.disabled

<SettingsBox@BoxLayout>
    orientation: 'horizontal'
    size_hint: 0.4, None
    height: '48dp'

<PluginHelp@Button>
    help_text: ''
    size_hint: None, None
    size: '48dp', '48dp'
    text: '?'

<PluginsDialog@Popup>
    title: _('Plugins')
    BoxLayout:
        orientation: 'vertical'
        padding: '10dp', '10dp'
        ScrollView:
            GridLayout:
                id: grid
                cols: 3
                spacing: '5dp'
                size_hint: 1, None
                height: self.minimum_height
        Button:
            text: _('Close')
            size_hint: 1, None
            height: '48dp'
            on_release: root.dismiss()
''')

class PluginWidget(BoxLayout):

    def __init__(self, *, app, name, fullname, settings_box):
        super(PluginWidget, self).__init__()
        self.app = app
        self.fullname = fullname
        self.name = name
        self.settings_box = settings_box
        self.active = False

    def update_settings_box(self, plugin):
        settings_widget = None
        if plugin and plugin.requires_settings() and plugin.is_enabled():
            settings_widget = plugin.settings_widget(self.app)
        self.settings_box.update(settings_widget)

    def update(self, from_cb=False):
        plugins = self.app.plugins
        wallet = self.app.wallet
        p = plugins.get(self.name)
        cb = self.ids.cb
        cb.disabled = (not p and not plugins.is_available(self.name, wallet)
                       or p and not p.is_available()
                       or p and not p.can_user_disable())
        self.active = bool(p and p.is_enabled())
        self.update_settings_box(p)
        if cb.active != self.active:
            cb.active = self.active

    def on_cb_active(self, is_checked):
        if self.active != is_checked:
            self.app.plugins.toggle(self.name)
            self.update()
            run_hook('init_kivy', self.app)

class SettingsBox(BoxLayout):

    def update(self, widget):
        self.clear_widgets()
        if widget:
            self.add_widget(widget)

class PluginHelp(Button):

    def __init__(self, *, app, help_text):
        super(PluginHelp, self).__init__()
        self.app = app
        self.help_text = help_text

    def on_release(self):
            width = self.app.root.width * 0.8
            self.app.show_info_bubble(text=self.help_text, width=width,
                                      arrow_pos=None)

class PluginsDialog(Factory.Popup, Logger):

    def __init__(self, app):
        super(PluginsDialog, self).__init__()
        self.app = app
        self.config = app.electrum_config
        self.network = app.network
        plugins = app.plugins
        grid = self.ids.grid
        for i, plugin_dict in enumerate(plugins.descriptions.values()):
            if plugin_dict.get('registers_keystore'):
                continue
            try:
                module_name = plugin_dict['__name__']
                prefix, _separator, name = module_name.rpartition('.')
                settings_box = SettingsBox()
                plugin_widget = PluginWidget(app=app, name=name,
                                             fullname=plugin_dict['fullname'],
                                             settings_box=settings_box)
                grid.add_widget(plugin_widget)
                grid.add_widget(settings_box)

                help_text = plugin_dict['description']
                requires = plugin_dict.get('requires')
                if requires:
                    help_text += '\n\n' + _('Requires') + ':\n'
                    help_text += '\n'.join(map(lambda x: x[1], requires))
                plugin_help = PluginHelp(app=app, help_text=help_text)
                grid.add_widget(plugin_help)
            except Exception as e:
                self.logger.exception(f'cannot display plugin {name}')

    def update(self):
        for widget in self.ids.grid.children:
            if isinstance(widget, PluginWidget):
                widget.update()


import collections

def is_merge(s, p1, p2):
    n, n1, n2 = len(s), len(p1), len(p2)
    if n1 + n2 != n:
        return False
    if not p1:
        return s == p2
    if not p2:
        return s == p1
    c, c1, c2 = collections.Counter(s), collections.Counter(p1), collections.Counter(p2)
    for k in c1:
        if k in c:
            c[k] -= c1[k]
    for k in c2:
        if k in c:
            c[k] -= c2[k]
    if any(c[k] != 0 for k in c):
        return False
    j = 0
    for i in range(n):
        if s[i] == p1[j]:
            j += 1
            if j == n1:
                break
    if j < n1:
        return False
    j = 0
    for i in range(n):
        if s[i] == p2[j]:
            j += 1
            if j == n2:
                break
    if j < n2:
        return False
    return True

print(is_merge("Can we merge it? Yes, we can!", "Ca eme ites, we can", "nw erg? Y!"))


import cv2
import os

def get_all_images(folder_path):
    """
    loads all images from a given directory
    :param folder_path: path to folder containing loaded images, relative to main project folder
                        eg. 'images/lifeLines'
    :return: python list of images in opencv (numpy) format
    """
    images = []
    for filename in os.listdir(folder_path):
        image = cv2.imread(f'{folder_path}/{filename}')
        if image is not None:
            images.append(image)
    return images


#!/bin/python3
from sklearn.linear_model import LinearRegression
import numpy as np
from datasets import DataSet
from sklearn.metrics import mean_squared_error
def to_matrix(data,dim):
	full_train_data = []
	num_examples = len(data['x'])
	for i in range(num_examples):
		row = np.zeros(dim)
		row[train_data['x'][i]] = 1
		full_train_data.append(row)
	return np.array(full_train_data),data['y']

ds = DataSet('./data/','frappe')
train_data = ds.train_data
num_train = len(train_data['y'])
validation_data = ds.validation_data
num_valid = len(validation_data['y'])
test_data = ds.test_data
num_test = len(test_data['y'])
dim = ds.feat_dim
train_x,train_y = to_matrix(train_data,dim)
valid_x,valid_y = to_matrix(validation_data,dim)
test_x,test_y = to_matrix(test_data,dim)
clf = LinearRegression()
clf.fit(train_data,train_y)
train_y_ = clf.predict(train_x)
valid_y_ = clf.predict(valid_x)
test_y_ = clf.predict(test_y_)
train_rmse = mean_squared_error(train_y,train_y_)
valid_rmse = mean_squared_error(valid_y,valid_y_)
test_rmse = mean_squared_error(test_y,test_y_)
print('train rmse:',train_rmse,'validation rmse:',valid_rmse,'test rmse:',test_rmse)


"""
This is a demo of how you can optimize machine learning algorithm results with
only linear programming tools like scipy.optimize
"""

import numpy as np
import pandas as pd
from scipy.optimize import minimize
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split

def mape(y, y_pred, weight=1):
    """Custom metric with bias possibilities. Weight parameter will multiply
    every prediction by it's value thus changing the mape error.

    Arguments:
        y {array} -- ground truth
        y_pred {array} -- prediction made by estimator

    Keyword Arguments:
        weight {int} -- custom bias for y_pred (default: {1})

    Returns:
        [float] -- mape error with added bias (default = 1)
    """
    mape = round(mean_absolute_error(y, y_pred * weight) / np.mean(y), 4)
    return mape

def objective(x):
    """Simple optimization function for sklearn.optimize

    Arguments:
        x {float} -- initial value to start optimization from

    Returns:
        float -- error minimized by sklearn.optimize function
    """
    return mean_absolute_error(y_train, y_pred_train * x)

# Let's load dataset and select only numerical data for simplicity sake
df = pd.read_csv('datasets/weatherHistory.csv')
num = df.select_dtypes(include='float64').columns
df = df[num]

# cut data between target value and features
y = df['Pressure (millibars)']
X = df.loc[:, df.columns != 'Pressure (millibars)']

# this requires no explanation
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.20, random_state=42)

# define model and predict train and test data
model = LinearRegression()
model.fit(X_train, y_train)
y_pred_train = model.predict(X_train)
y_pred_test = model.predict(X_test)

# let's further minimize error by calling minimize on our predictions
x0 = 1.0
sol = minimize(objective, x0, method='Nelder-Mead')
print('\n' + str(sol) + '\n')

# weight is the optimized value that will further reduce error on our prediction
# you have to multiply weight value by y_train to see how good it optimizes
# result. After that test it on test data
weight = sol.x[0]

print('mape on train', mape(y_train, y_pred_train))
print('mape on train scipy optimized', mape(y_train, y_pred_train, weight))
print('mape on test', mape(y_test, y_pred_test))
print('mape on test scipy optimized', mape(y_test, y_pred_test, weight))

# We can see that after optimizing our predictions error went down. This is done
# on toy dataset so reduction is small. Test it on real business problem to see
# better results


import codecs
import re
from datetime import datetime, timedelta

import discord
import requests
import json
import random
import os
from io import BytesIO
import json
from os import listdir
import asyncio

from modules import basics
from modules.utility import get_emoji

ans_chat = [
        "Hi!",
        "Hello!",
        "Hi there!",
        "Hey!",
        "Howdy!",
        "Hi everybody!",
        "Welcome to Toontown!",
        "What's up?",
        "How are you doing?",
        "Hello?",
        "Bye!",
        "Later!",
        "See ya!",
        "Have a nice day!",
        "Have fun!",
        "Good luck!",
        "I'll be right back.",
        "I'll be back later!",
        "I only have a few minutes.",
        "I need to go.",
        ":-)",
        "Yay!",
        "Hooray!",
        "Cool!",
        "Woo hoo!",
        "Yeah!",
        "Ha ha!",
        "Hee hee!",
        "Wow!",
        "Great!",
        "Whee!",
        "Oh boy!",
        "Whoopee!",
        "Yippee!",
        "Yee hah!",
        "Toontastic!",
        ":-(",
        "Oh no!",
        "Uh oh!",
        "Rats!",
        "Drat!",
        "Ouch!",
        "Oof!",
        "No!!!",
        "Yikes!",
        "Huh?",
        "I need more Laff Points.",
        "You look nice.",
        "You are awesome!",
        "You rock!",
        "You are a genius!",
        "I like your name.",
        "I like your look.",
        "I like your shirt.",
        "I like your skirt.",
        "I like your shorts.",
        "I like this game!",
        "Thanks!",
        "No problem.",
        "You're welcome!",
        "Any time!",
        "No thank you.",
        "Good teamwork!",
        "That was fun!",
        "Please be my friend!",
        "Let's work together!",
        "You guys are great!",
        "Are you new here?",
        "Have you been here before?",
        "Did you win?",
        "I think this is too risky for you.",
        "Would you like some help?",
        "Can you help me?",
        "Oops!",
        "Sorry!",
        "Sorry, I'm busy fighting cogs!",
        "Sorry, I'm busy getting Jellybeans!",
        "Sorry, I'm busy completing a Toontask!",
        "Sorry, I'm busy fishing!",
        "Sorry, I'm busy kart racing!",
        "Sorry, I'm busy gardening!",
        "Sorry, I'm busy golfing!",
        "Sorry, I'm in a building!",
        "Sorry, I'm helping a friend!",
        "Sorry, my Friends List is full.",
        "Sorry, I had to leave unexpectedly.",
        "Sorry, I was delayed.",
        "Sorry, I can't.",
        "I can't get on the elevator now.",
        "I couldn't wait any longer.",
        "I can't understand you.",
        "Use the SpeedChat.",
        "Hey!",
        "Please go away!",
        "Stop that!",
        "That wasn't nice!",
        "Don't be mean!",
        "You stink!",
        "I'm stuck.",
        "Let's go on the trolley!",
        "Let's go back the the playground!",
        "Let's go to Toontown Central!",
        "Let's go to Donald's Dock!",
        "Let's go to Minnie's Melodyland!",
        "Let's go to Daisy Gardens!",
        "Let's go to The Brrrgh!",
        "Let's go to Donald's Dreamland!",
        "Let's go to Goofy Speedway!",
        "Let's go fishing!",
        "Let's go to Chip 'n Dale's Acorn Acres!",
        "Let's go to Chip 'n Dale's Minigolf!",
        "Let's go fight the Cogs!",
        "Lets go take over a Cog building!",
        "Let's go in the elevator!",
        "Let's go to Sellbot HQ!",
        "Let's go fight the VP!",
        "Let's go in the Factory!",
        "Let's go to Cashbot HQ!",
        "Let's go fight the CFO!",
        "Let's go in the Mint!",
        "Let's go to Lawbot HQ!",
        "Let's go fight the Chief Justice!",
        "Let's go in the District Attorney's office!",
        "Let's go to Bossbot HQ!",
        "Let's go fight the CEO!",
        "Let's go in the Cog Golf Course!",
        "Let's go take over a Field Office!",
        "Let's go to my house!",
        "Let's go to your house!",
        "Can you come to my house?",
        "Let's go fishing at my house!",
        "Come check out my garden.",
        "Let's go to a party.",
        "See you at the party!",
        "My party has started!",
        "Come to my party!",
        "Wait!",
        "Wait for me!",
        "Let's wait for my friend.",
        "Wait here.",
        "Wait a minute.",
        "Don't wait for me.",
        "Let's catch the next one.",
        "Let's go!",
        "Can you teleport to me?",
        "Shall we go?",
        "Where should we go?",
        "Which way?",
        "This way.",
        "Follow me.",
        "Let's find other toons.",
        "Meet here.",
        "I think you should choose Toon-up.",
        "I think you should choose Sound.",
        "I think you should choose Drop.",
        "I think you should choose Lure.",
        "I think you should choose Trap.",
        "I need more Merits.",
        "I need more Cogbucks.",
        "I need more Jury Notices.",
        "I need more Stock Options.",
        "I need more Sellbot Suit Parts.",
        "I need more Cashbot Suit Parts.",
        "I need more Lawbot Suit Parts.",
        "I need more Bossbot Suit Parts.",
        "What Toontask are you working on?",
        "Let's work on that.",
        "This isn't what I'm looking for.",
        "This isn't what you need.",
        "I'm going to look for that.",
        "I found what you need.",
        "It isn't on this street.",
        "I haven't found it yet.",
        "Let's use toon-up!",
        "Let's use trap!",
        "Let's use lure!",
        "Let's use sound!",
        "Let's use throw!",
        "Let's use squirt!",
        "Let's use drop!",
        "Nice shot!",
        "Nice gag!",
        "I need more gags.",
        "Missed me!",
        "Bring it on!",
        "Rock and roll!",
        "That's gotta hurt.",
        "Catch!",
        "Special delivery!",
        "Are you still here?",
        "I'm SO scared!",
        "That's going to leave a mark!",
        "Piece of cake!",
        "That was easy!",
        "I need a Toon-Up.",
        "I'm going to use trap.",
        "I'm going to use lure.",
        "I'm going to use drop.",
        "You should pass.",
        "You should use a different gag.",
        "Let's all go for the same cog.",
        "You should choose a different cog.",
        "Go for the weakest cog first.",
        "Go for the strongest cog first.",
        "Save your powerful gags.",
        "Don't use sound on lured cogs.",
        "Hurry!",
        "We can do this!",
        "You did it!",
        "We did it!",
        "Run!",
        "Help!",
        "Phew!",
        "We are in trouble.",
        "I have enough gags.",
        "I need more jellybeans.",
        "Me too.",
        "Hurry up!",
        "One more?",
        "Play again?",
        "Let's play again.",
        "Yes",
        "No",
        "OK",
        ]

ans_time = [
        "BILLION YEARS",
        "century",
        "day",
        "decade",
        "era",
        "fiscal year",
        "fortnight",
        "galactic year",
        "hour",
        "instant",
        "jiffy",
        "long weekend",
        "millennium",
        "minute",
        "month",
        "season",
        "week"
        ]

ans_time_plural = [
    "BILLION YEARS",
    "centuries",
    "days",
    "decades",
    "eras",
    "fiscal years",
    "fortnights",
    "galactic years",
    "hours",
    "instants",
    "jiffies",
    "long weekends",
    "millennia",
    "minutes",
    "months",
    "seasons",
    "weeks"
    ]

ans_xavier = ["Frittata!",
"Nobody has ever survived our initiation process.",
"Really? Is he disabled?",
"Hold. Hold. Hold. Hold. Hold. Hold. Hold. Hold. Hold. Hold. Hold. Hold. Hold.",
"That's why you don't like cereal.",
"Here. 20 bucks. Get out of town. Start a new life.",
"Instead of eating tacos, let's just talk. Oh.",
"I'd like to see this guy pray an abortion.",
"Stay off that knee for a week.",
"This is spreadable bread.",
"Threeito.",
"There's more to life than life.",
"You'd feel so proud of me, mom. I'm not gonna be another Einstein.",
"Bloomin onion on a stick!",
"THEY'RE ALL GONNA LAUGH AT ME",
"Does anyone know how to get to the lake?",
"I'll never sell these arrows.",
"Could use a little coconut.",
"Always tough to kill your dad, but you made the right choice.",
"Fate. Destiny. Fatestiny.",
"I'll take care of that!",
"You're just making me horny!",
"Smells... EXACTLY like my ass.",
"He died during childbirth.",
"You may have just gotten checkmate, but we're playing chinese checkers!",
"I'm gonna name him after me. C'mon, Me.",
"Idiot. He totally missed the board.",
"Let's play a bored game. I'm bored. I win. What's my prize?",
"THINK OF SOME KIDS.SOME KIDS.",
"RIGGINGTON SPORT RIGGER",
"I learned from watching you.",
"Computer! Analysis!",
"OOGA BOOGA CHINAM'N",
"What's the matter? Pussy got your tounge?",
">peak of disappointment",
"I no longer fear your pain fries. (WHOOBOY)",
"Sucker! I would have settled for every other day!",
"I can't remember the memory jogging dance!",
">puke here",
"We're gonna get this little guy laid.",
"I feel like someone is raping me with their eyes.",
"VOW LOCKED IN",
"You don't want it, it's Jap Crap.",
"I could never say no to a virgin.",
"Get me the Hell out of Heaven.",
"Just two more Xaviers left.",
"I fingered myself to death.",
'''"you seem like smart guys" "that's slander"''',
"5-185550-170",
"I swear to Chekhov, I'll cock your clock off.",
"Know when you're defeated. Accept your defecation.",
"Ladies first. (16 HOURS LATER)",
"I assume you're familliar with St. Louis Rules?",
"Well, I think a lot of things, but you're prob'ly gonna cut--",
"Send it where? You decide!",
"But did I whine? No, I turned to the bottle.",
"Flesh colored? How offensive.",
"I'm still holding that raw meat from years ago.",
"This isn't a real Kwanzaa bean.",
"SEXUAL DIARRHEA",
"Dos Ex Machina?",
"Thank you for closing your legs, mommy.",
"This is the 9/11 of noise.",
"I'm going to search far and wide so I can totally tattle to my mom.",
"Chicken bone bread.",
"You seem awfully nervous for a guy who's totally freaked out right now.",
"THE SIX CODE WORDS!",
"You're in the mob?! No wonder I didn't suspect a thing!",
"One grunt for yes. \*grunts twice* Hmm, you want it double bad, huh?",
">building bones",
"Don't worry! Your panties will be bloody soon enough!",
'''Peterson, shut up! New Ryan, say that again! "Peterson, shut up."''',
"WE CAN NO LONGER RELY ON THE SUN'S LIFE-SUSTAINING HEAT!",
"Xavier DOWN UNDA!",
"He's passed on to a better, more euphemistic place.",
"He's coming.. he's coming... INSIDE ME!",
"What do you think I'm back from the dead for, for my health?",
"Do you want some hot coco? Good, and fruity...",
"And if you look to your left, you'll want to look to your right...",
'''"Get away from me! You make me sick!" That's what she said.''',
"Women here have the freedom to do whatever they want! It totally sucks...",
"I even gold polished the Quran! (Can't polish a turd...)",
"SAUSAGE MILK ENERGY BAR",
"I don't feel myself today. That means someone else is feeling me!",
"Okay, I'll see you at church.",
"I've been running for so long, it's like the background is repeating...",
"To be self consumed, sometimes, one must consume one self.",
"Mom spelled backwards is Wow!",
"We can't abort it this far into the pregnancy. The best we can do is torture it a little.",
"Now chow down, or I'll break my vow of nonviolence against your face.",
"Here's the funhouse mirrors for the anorexics.",
"broke-ass pony",
"Dammit! I had money on that game!",
"You were my first, (not counting rape)!",
"This is rubbing against my pole! My princi-pole! Of nonviolence!",
"Trick shot.",
"Cured? Who said there was anything wrong with you?"]

def allyeses():
    l = json.load(open("json/ans_yes.json", encoding="utf-8"))
    for n,x in enumerate(l):
        l[n] = x.split(";")[0]
    return l

def allnos():
    l = json.load(open("json/ans_no.json", encoding="utf-8"))
    for n,x in enumerate(l):
        l[n] = x.split(";")[0]
    return l

def allmaybes():
    return json.load(open("json/ans_maybe.json", encoding="utf-8"))

def eightyes():
    return random.choice(allyeses())

def eightno():
    return random.choice(allnos())

def eightmaybe():
    return random.choice(allmaybes())

def allhippos(bot):
    the_e_list = []
    the_e_name_list = []
    for e in bot.emojis:
        if "hippo" in e.name.lower() and e.name not in the_e_name_list and not e.name[-1].isnumeric():
            the_e_list.append(e)
            the_e_name_list.append(e.name)
    return the_e_list

def eighthippo(bot):
    return random.choice(allhippos(bot))

def allchannels(guild):
    l = []
    for x in guild.text_channels:
        l.append(x.mention)
    return l

def eightchannel(guild):
    l = allchannels(guild)
    if len(l) == 0:
        return "Somehow there's no text channels yet this command is happening"
    return random.choice(l)

def allcustomemojis(bot):
    l = []
    print(len(bot.emojis))
    for e in bot.emojis:
        if not(e.name.startswith("bn_") or e.name.startswith("owo") or e.name.startswith("dd_") or e.name.startswith("tbc") or e.name.startswith("dickdick") or e.name.startswith("SMILE") or e.name.startswith("dick2") or e.name.startswith("dick3") or e.name.startswith("dick4") or e.name.startswith("dick5") or e.name.startswith("cus_") or e.name.startswith("rot") or e.name.startswith("cera") or e.name.startswith("LR") or "hippo" in e.name or e.guild.id=="306149758320508928"):
            l.append(str(e))
    return l

def eightcustomemoji(bot):
    return random.choice(allcustomemojis(bot))

def allchats():
    return ans_chat

def eightchat():
    return random.choice(allchats())

def alltimes(plural):
    if plural:
        return ans_time_plural
    return ans_time

def eighttime(plural):
    return random.choice(alltimes(plural))

def eightcolor():
    return "#"+str(hex(random.randint(0,0xffffff)))[2:].ljust(6,"0")

def allxaviers():
    return ans_xavier

def eightxavier():
    return random.choice(allxaviers())

def alllinesfromsonic06():
    return json.load(open("json/sonic_06.json", encoding="utf-8"))

def eightlinefromsonic0():
    return random.choice(alllinesfromsonic06())

def allaudies():
    l=[]
    for x in listdir("audio/audies"):
        l.append(x.replace(".mp3",""))
    return l

def eightaudie():
    return random.choice(allaudies())

def allanimals():
    return json.load(open("json/animals.json"))

def eightanimal():
    return random.choice(allanimals())

def allads():
    from xml.dom.minidom import parseString

    html_string = """
    <!DOCTYPE html>
    <title>title</title>
test

    """

    # extract the text value of the document's
 tag:
    doc = parseString(html_string)
    paragraph = doc.getElementsByTagName("div")[0]
    content = paragraph.firstChild.data
    print(content)

def allconfirms():
    return ['🙄', '😱', '😒', '😚', '😔', '😨', '😟', '😜', '😤', '🤢', '😅', '☺', '😕', '<:whatthefuck:358083695544107019>', '\U0001f97a', '😎', '😬', '😘', '😍', '😋', '\U0001f970', '😡', '\U0001f971', '😶', '😌', '\U0001f973', '\U0001f92c', '🤣', '🙃', '😂', '\U0001f92a', '😭', '\U0001f929', '😳', '😠', '😉', '🤕', '😴', '😀', '🤔', '😖', '\U0001f92b', '\U0001f92e', '🤤', '😏', '🤧', '😲', '😊', '😞', '😣', '\U0001f92f', '😩', '😵', '\U0001f928', '🤗', '\U0001f974', '😆']

def eightconfirm():
    return random.choice(allconfirms())

def repuser(bot, user):
    # from modules import basics
    return shownames(bot, user)
    # return "{} {}".format(basics.useremoji(bot, user), shownames(bot,user))

def bar(bot,size,decimal,kind="slice"):
    edict = {}

    if kind=="slice":
        variants=4
        for x in bot.get_guild(556497061072076820).emojis:
            edict[int(x.name[1])] = str(x).replace(x.name,"_")
    elif kind=="circle":
        variants=49
        for x in bot.get_guild(331163970629271553).emojis:
            try:
                edict[int(x.name)] = f"<{'a' if x.animated else ''}:_:{x.id}>"
            except:
                pass
    elif kind=="mini":
        variants=49
        for x in bot.get_guild(364995623528824832).emojis:
            try:
                edict[int(x.name.replace("_",""))] = f"<{'a' if x.animated else ''}:_:{x.id}>"
            except:
                pass
    elif kind=="unicode":
        variants=4
        for n,x in enumerate(list("○◔◑◕●")):
            edict[n] = x

    s=""
    decimal = round(decimal*variants*size)
    for x in range(size):
        if decimal>=variants:
            s+=edict[variants]
            decimal -=variants
        else:
            s+=edict[decimal]
            decimal = 0

    return s

def shownames(bot,member):
    if member.display_name == member.name or basics.truename(bot,member) == member.display_name:
        name = basics.truename(bot,member)
    else:
        name = member.display_name
    return f"{basics.useremoji(bot,member)} {name.replace('@','@')}"
    # if member.display_name == member.name or basics.truename(bot,member) == member.display_name:
    #     return basics.truename(bot,member)
    # else:
    #     s = fonts(basics.truename(bot,member), "small")
    #
    #     dispname = str(member.display_name)
    #     dispname = dispname.replace("@everyone", "@everyone")
    #     return "{}{}".format(dispname, s)

def fonts(s, kind):
    fonts = json.load(open("json/fonts.json", encoding='utf-8'))
    if kind in fonts:
        characters = fonts[kind]["characters"]
    else:
        for k,i in fonts.items():
            if kind in i["aliases"]:
                characters = i["characters"]
                break
        else:
            raise Exception(f"{kind} isn't a valid font.")
    ret = ""
    for x in list(s):
        if x in characters:
            ret += characters[x]
        else:
            ret += x
    return ret

    return
    font = []
    finalstring = ""
    f = codecs.open('json/fonts.txt', encoding='utf-8')
    for line in f:
        font.append(line)
    for l in list(s):
        if kind == "aes":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[0][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1]) + 1]
            else:
                finalstring += l[:1]
        elif kind == "small":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[1][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
        elif kind == "fancy":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[2][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
        elif kind == "circles":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[3][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
        elif kind == "jank":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[4][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
        elif kind == "old":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[5][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
        elif kind == "lines":
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[6][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
        elif kind == "squares":
            if l[:1].lower() in "opab":
                finalstring += "\\"
            if l[
               :1] in """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""":
                finalstring += font[7][
                    """`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:"|ZXCVBNM<>? \\""".index(
                        l[:1])]
            else:
                finalstring += l[:1]
    return finalstring

def highest(l):
    h=l[0]
    for x in l[1:]:
        if x>h:
            x=h
    return h

def lowest(l):
    h=l[0]
    for x in l[1:]:
        if x<h:
            x=h
    return h

async def lit(m, binary=False,ach=False):
    mps = 0
    users = set()
    async for msg in m.channel.history(limit=120000, oldest_first=False, before=m):
        mps +=1
        uh = datetime.utcnow() - timedelta(minutes=2)
        users.add(msg.author)
        if msg.created_at <= uh: break
    if mps == 1:
        mps = 0
    else:
        mps = (mps - 1) / 120
    if binary:
        return mps >= 1 / 4
    if ach:
        return {"mps": mps, "binary": mps >= 1 / 4, "users": users}
    return mps

def pluralstr(string, num):
    if int(num) == num:
        num = int(num)
    if num == 1:
        return str(num) + " " + string
    else:
        return str(num) + " " + string + "s"

def andstr(l,*,an="and"):
    if len(l) == 0:
        return ""
    elif len(l) == 1:
        return l[0]
    elif len(l) == 2:
        return f"{l[0]} {an} {l[1]}"
    else:
        s = ""
        for x in l[:-1]:
            s += f"{x}, "
        return f"{s}{an} {l[-1]}"

def sms(bot, s):
    if s.startswith("/shrug"):
        s = s.replace("/shrug","",1) + " ¯\_(ツ)_/¯"
    elif s.startswith("/tableflip"):
        s = s.replace("/tableflip","",1) + " (╯°□°）╯︵ ┻━┻"
    elif s.startswith("/unflip"):
        s = s.replace("/unflip","",1) + " ┬─┬ ノ( ゜-゜ノ)"

    for e in re.findall(r"",s):
        actualemoji = get_emoji(bot,e)
        if actualemoji != None:
            s = s.replace(e,f"[ {actualemoji.name} : {actualemoji.url} ]")

    return s

def echo(s):
    match = re.match(r"[\s\S]*?([^ ]+)$",s)
    if not match:
        return ""
    else:
        return f'**{match.group(0)}** {match.group(1)} {fonts(match.group(1),"small")} {"ॱ"*len(match.group(1))}'

def covid(bot, country, section, includedate=False):
    if bot.covidstats["confirmed"]["last_updated"].split("T")[0] != str(datetime.utcnow().date()):
        response = requests.get("https://coronavirus-tracker-api.herokuapp.com/all")
        bot.covidstats =  json.loads(response.text)
        basics.save(bot, "covidstats")
        print("Updated covid.")
    j = bot.covidstats[section]
    n = 0
    found = False
    if country:
        for x in j["locations"]:
            if country.lower() in [x["country"].lower(), x["country_code"].lower(), x["province"].lower()]:
                found = True
                n += max(x["history"].values())
    if includedate:
        return n if found else None, j["last_updated"].replace("T", " ").split(".")[0]
    else:
        return n if found else None


from django.shortcuts import render,redirect
from django.http import HttpResponse
from .models import UsersModal,Mobiles,Laptops,HeadSet,Camera,Powerbank,Refrigerator,Kettle,Television,WashingMachine
from http.cookies import SimpleCookie
from math import floor,ceil
from GRS.randkey import make_ratings
from django.core.paginator import Paginator

def GRSappHome(request):
    user = request.COOKIES.get('username')
    mobiles = Mobiles.objects.all()
    paginator1 = Paginator(mobiles,6)
    page1 = request.GET.get('page1')
    mobiles = paginator1.get_page(page1)

    laptops = Laptops.objects.all()
    paginator2 = Paginator(laptops,4)
    page2 = request.GET.get('page2')
    laptops = paginator2.get_page(page2)

    headsets = HeadSet.objects.all()
    paginator3 = Paginator(headsets,6)
    page3 = request.GET.get('page3')
    headsets = paginator3.get_page(page3)

    cameras = Camera.objects.all()
    paginator4 = Paginator(cameras,4)
    page4 = request.GET.get('page4')
    cameras = paginator4.get_page(page4)

    powerbanks = Powerbank.objects.all()
    paginator5 = Paginator(powerbanks,6)
    page5 = request.GET.get('page5')
    powerbanks = paginator5.get_page(page5)

    fridges = Refrigerator.objects.all()
    paginator6 = Paginator(fridges,6)
    page6 = request.GET.get('page6')
    fridges = paginator6.get_page(page6)

    kettles = Kettle.objects.all()
    paginator7 = Paginator(kettles,4)
    page7 = request.GET.get('page7')
    kettles = paginator7.get_page(page7)

    tvs = Television.objects.all()
    paginator8 = Paginator(tvs,8)
    page8 = request.GET.get('page8')
    tvs = paginator8.get_page(page8)

    wms = WashingMachine.objects.all()
    paginator9 = Paginator(wms,8)
    page9 = request.GET.get('page9')
    wms = paginator9.get_page(page9)

    params = {'user':user,'mobiles':mobiles,'laptops':laptops,'headsets':headsets,'cameras':cameras,'powerbanks':powerbanks,'fridges':fridges,'kettles':kettles,'tvs':tvs,'wms':wms}

    return render(request,'GRSapp/GRSHome.html',params)

def loaditem(request,slug):
    if slug=="Mobiles":
        return redirect('loadmobiles')
    else:
        return HttpResponse("Page Not Found")

def loadmobiles(request):
    user = request.COOKIES.get('username')
    mobiles = Mobiles.objects.all()
    mobiles = make_ratings(mobiles)

    params = {"user":user,"mobiles":mobiles}

    return render(request,'GRSapp/loadMobiles.html',params)


from datetime import datetime, timedelta
from server import db

class Sensor(db.Model):
    """Sensor model, DB table."""
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(16), unique=True, nullable=False)
    description = db.Column(db.Text, nullable=True)
    created_at = db.Column(db.DateTime, nullable=False)

    def __init__(self, name, description=None, created_at=None):
        self.name = name
        self.description = description
        if not created_at:
            created_at = datetime.utcnow()
        self.created_at = created_at

    def __repr__(self):
        return '<Sensor id={} name={} created_at={}>'.format(
            self.id, self.name, self.created_at
        )

    @property
    def serialize(self):
        """Simplify object -> JSON conversion."""
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'created_at': self.created_at.isoformat()
        }

class Reading(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    value = db.Column(db.Float, nullable=False)
    timestamp = db.Column(db.DateTime, nullable=False)

    sensor_id = db.Column(db.Integer, db.ForeignKey('sensor.id'), nullable=False)
    sensor = db.relationship('Sensor',
        backref=db.backref('readings', lazy='dynamic', cascade='all, delete-orphan')
    )

    def __init__(self, sensor_name, value, timestamp=None):
        sensor = Sensor.query.filter_by(name=sensor_name).first()
        if sensor is None:
            sensor = Sensor(sensor_name)
            db.session.add(sensor)
            db.session.commit()

        self.sensor = sensor
        self.value = value
        if not timestamp:
            timestamp = datetime.utcnow()
        self.timestamp = timestamp

    def __repr__(self):
        return '<Data sensor={} value={} timestamp={}>'.format(
            self.sensor_id, self.value, self.timestamp
        )

    @property
    def serialize(self):
        """Simplify object -> JSON conversion."""
        return {
            'id': self.id,
            'value': self.value,
            'timestamp': self.timestamp.isoformat(),
            'sensor': self.sensor_id
        }


import wx
from game_master import *

class Main_Frame(wx.Frame):

    def __init__(self):
        self.gui_turn = 0
        self.vs = self.for_ch
        self.selection = ('model','random')

        self.for_convert = [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0),
                            (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1),
                            (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (5, 2), (6, 2), (7, 2),
                            (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (5, 3), (6, 3), (7, 3),
                            (0, 4), (1, 4), (2, 4), (3, 4), (4, 4), (5, 4), (6, 4), (7, 4),
                            (0, 5), (1, 5), (2, 5), (3, 5), (4, 5), (5, 5), (6, 5), (7, 5),
                            (0, 6), (1, 6), (2, 6), (3, 6), (4, 6), (5, 6), (6, 6), (7, 6),
                            (0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7)]

        wx.Frame.__init__(self, None, wx.ID_ANY, 'Reversi', size=(728, 700))
        icon = wx.Icon('img/icon.ico', wx.BITMAP_TYPE_ICO)
        wx.Frame.SetIcon(self, icon)
        self.main_Panel = wx.Panel(self)
        self.board_Panel = wx.Panel(self.main_Panel, pos=(0, 0), size=(560, 560))
        self.control_Panel = wx.Panel(self.main_Panel, pos=(560, 0), size=(560, 700))
        self.control_Panel.SetBackgroundColour('#7fbfff')
        self.status_Panel = wx.Panel(self.main_Panel, pos=(0, 560), size=(560, 140))
        self.status_Panel.SetBackgroundColour('#8484ff')
        self.othello = game_master()
        self.board_make()
        self.make_status()
        self.make_control()

        main_layout = wx.GridBagSizer()
        main_layout.Add(self.board_Panel, (0, 0), (1, 1))
        main_layout.Add(self.control_Panel, (0, 1), (2, 1))
        main_layout.Add(self.status_Panel, (1, 0), (1, 1))
        main_layout.AddGrowableRow(0)
        main_layout.AddGrowableRow(1)
        main_layout.AddGrowableCol(0)
        main_layout.AddGrowableCol(1)
        self.main_Panel.SetSizer(main_layout)

        self.board_color_update()

    def board_make(self):
        button_0 = wx.Button(self.board_Panel, wx.ID_ANY, '0', size=(70, 70))
        button_1 = wx.Button(self.board_Panel, wx.ID_ANY, '1', size=(70, 70))
        button_2 = wx.Button(self.board_Panel, wx.ID_ANY, '2', size=(70, 70))
        button_3 = wx.Button(self.board_Panel, wx.ID_ANY, '3', size=(70, 70))
        button_4 = wx.Button(self.board_Panel, wx.ID_ANY, '4', size=(70, 70))
        button_5 = wx.Button(self.board_Panel, wx.ID_ANY, '5', size=(70, 70))
        button_6 = wx.Button(self.board_Panel, wx.ID_ANY, '6', size=(70, 70))
        button_7 = wx.Button(self.board_Panel, wx.ID_ANY, '7', size=(70, 70))
        button_8 = wx.Button(self.board_Panel, wx.ID_ANY, '8', size=(70, 70))
        button_9 = wx.Button(self.board_Panel, wx.ID_ANY, '9', size=(70, 70))
        button_10 = wx.Button(self.board_Panel, wx.ID_ANY, '10', size=(70, 70))
        button_11 = wx.Button(self.board_Panel, wx.ID_ANY, '11', size=(70, 70))
        button_12 = wx.Button(self.board_Panel, wx.ID_ANY, '12', size=(70, 70))
        button_13 = wx.Button(self.board_Panel, wx.ID_ANY, '13', size=(70, 70))
        button_14 = wx.Button(self.board_Panel, wx.ID_ANY, '14', size=(70, 70))
        button_15 = wx.Button(self.board_Panel, wx.ID_ANY, '15', size=(70, 70))
        button_16 = wx.Button(self.board_Panel, wx.ID_ANY, '16', size=(70, 70))
        button_17 = wx.Button(self.board_Panel, wx.ID_ANY, '17', size=(70, 70))
        button_18 = wx.Button(self.board_Panel, wx.ID_ANY, '18', size=(70, 70))
        button_19 = wx.Button(self.board_Panel, wx.ID_ANY, '19', size=(70, 70))
        button_20 = wx.Button(self.board_Panel, wx.ID_ANY, '20', size=(70, 70))
        button_21 = wx.Button(self.board_Panel, wx.ID_ANY, '21', size=(70, 70))
        button_22 = wx.Button(self.board_Panel, wx.ID_ANY, '22', size=(70, 70))
        button_23 = wx.Button(self.board_Panel, wx.ID_ANY, '23', size=(70, 70))
        button_24 = wx.Button(self.board_Panel, wx.ID_ANY, '24', size=(70, 70))
        button_25 = wx.Button(self.board_Panel, wx.ID_ANY, '25', size=(70, 70))
        button_26 = wx.Button(self.board_Panel, wx.ID_ANY, '26', size=(70, 70))
        button_27 = wx.Button(self.board_Panel, wx.ID_ANY, '27', size=(70, 70))
        button_28 = wx.Button(self.board_Panel, wx.ID_ANY, '28', size=(70, 70))
        button_29 = wx.Button(self.board_Panel, wx.ID_ANY, '29', size=(70, 70))
        button_30 = wx.Button(self.board_Panel, wx.ID_ANY, '30', size=(70, 70))
        button_31 = wx.Button(self.board_Panel, wx.ID_ANY, '31', size=(70, 70))
        button_32 = wx.Button(self.board_Panel, wx.ID_ANY, '32', size=(70, 70))
        button_33 = wx.Button(self.board_Panel, wx.ID_ANY, '33', size=(70, 70))
        button_34 = wx.Button(self.board_Panel, wx.ID_ANY, '34', size=(70, 70))
        button_35 = wx.Button(self.board_Panel, wx.ID_ANY, '35', size=(70, 70))
        button_36 = wx.Button(self.board_Panel, wx.ID_ANY, '36', size=(70, 70))
        button_37 = wx.Button(self.board_Panel, wx.ID_ANY, '37', size=(70, 70))
        button_38 = wx.Button(self.board_Panel, wx.ID_ANY, '38', size=(70, 70))
        button_39 = wx.Button(self.board_Panel, wx.ID_ANY, '39', size=(70, 70))
        button_40 = wx.Button(self.board_Panel, wx.ID_ANY, '40', size=(70, 70))
        button_41 = wx.Button(self.board_Panel, wx.ID_ANY, '41', size=(70, 70))
        button_42 = wx.Button(self.board_Panel, wx.ID_ANY, '42', size=(70, 70))
        button_43 = wx.Button(self.board_Panel, wx.ID_ANY, '43', size=(70, 70))
        button_44 = wx.Button(self.board_Panel, wx.ID_ANY, '44', size=(70, 70))
        button_45 = wx.Button(self.board_Panel, wx.ID_ANY, '45', size=(70, 70))
        button_46 = wx.Button(self.board_Panel, wx.ID_ANY, '46', size=(70, 70))
        button_47 = wx.Button(self.board_Panel, wx.ID_ANY, '47', size=(70, 70))
        button_48 = wx.Button(self.board_Panel, wx.ID_ANY, '48', size=(70, 70))
        button_49 = wx.Button(self.board_Panel, wx.ID_ANY, '49', size=(70, 70))
        button_50 = wx.Button(self.board_Panel, wx.ID_ANY, '50', size=(70, 70))
        button_51 = wx.Button(self.board_Panel, wx.ID_ANY, '51', size=(70, 70))
        button_52 = wx.Button(self.board_Panel, wx.ID_ANY, '52', size=(70, 70))
        button_53 = wx.Button(self.board_Panel, wx.ID_ANY, '53', size=(70, 70))
        button_54 = wx.Button(self.board_Panel, wx.ID_ANY, '54', size=(70, 70))
        button_55 = wx.Button(self.board_Panel, wx.ID_ANY, '55', size=(70, 70))
        button_56 = wx.Button(self.board_Panel, wx.ID_ANY, '56', size=(70, 70))
        button_57 = wx.Button(self.board_Panel, wx.ID_ANY, '57', size=(70, 70))
        button_58 = wx.Button(self.board_Panel, wx.ID_ANY, '58', size=(70, 70))
        button_59 = wx.Button(self.board_Panel, wx.ID_ANY, '59', size=(70, 70))
        button_60 = wx.Button(self.board_Panel, wx.ID_ANY, '60', size=(70, 70))
        button_61 = wx.Button(self.board_Panel, wx.ID_ANY, '61', size=(70, 70))
        button_62 = wx.Button(self.board_Panel, wx.ID_ANY, '62', size=(70, 70))
        button_63 = wx.Button(self.board_Panel, wx.ID_ANY, '63', size=(70, 70))
        self.board_name = [button_0, button_1, button_2, button_3, button_4, button_5, button_6, button_7,
                           button_8, button_9, button_10, button_11, button_12, button_13, button_14,button_15,
                           button_16, button_17, button_18, button_19, button_20,button_21, button_22, button_23,
                           button_24, button_25, button_26, button_27, button_28, button_29, button_30, button_31,
                           button_32, button_33, button_34, button_35, button_36, button_37, button_38, button_39,
                           button_40, button_41, button_42, button_43,button_44, button_45, button_46, button_47,
                           button_48, button_49, button_50, button_51, button_52, button_53, button_54, button_55,
                           button_56, button_57, button_58, button_59, button_60, button_61, button_62, button_63,
                           ]
        dict_reg = 0
        layout_board = wx.FlexGridSizer(8, 8, 0, 0)
        for button_name in self.board_name:
            button_name.SetBackgroundColour('#228b22')
            button_name.SetForegroundColour('#bc8f8f')
            button_name.Bind(wx.EVT_BUTTON, self.vs)
            button_name.Disable()
            layout_board.Add(button_name)
            dict_reg += 1
        self.board_Panel.SetSizer(layout_board)

    def make_control(self):
        control_layout = wx.BoxSizer(wx.VERTICAL)
        text1 = wx.StaticText(self.control_Panel, wx.ID_ANY, '戦う相手', size=(150, 30))
        text1.SetFont(wx.Font(20, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
        self.button_start = wx.Button(self.control_Panel, wx.ID_ANY, 'START', size=(150, 70))
        self.button_start.SetBackgroundColour('#ffe4b5')
        self.button_start.Bind(wx.EVT_BUTTON, self.click_start)
        self.selectin_box = wx.ComboBox(self.control_Panel, wx.ID_ANY, '選択してください',
                                   choices=self.selection, style=wx.CB_READONLY, size=(150, 30))
        self.selectin_box.SetFont(wx.Font(20, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
        self.selectin_box.SetSelection(0)
        self.WINNER = wx.StaticText(self.control_Panel, wx.ID_ANY, '', size=(150, 70), style=wx.TE_CENTER)
        self.WINNER.SetBackgroundColour('#20b2aa')
        self.WINNER.SetFont(wx.Font(28, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
        control_layout.Add(text1)
        control_layout.Add(self.selectin_box)
        control_layout.Add(self.button_start)
        control_layout.Add(self.WINNER)
        self.control_Panel.SetSizer(control_layout)

    def click_start(self, a):
        self.button_start.Disable()
        self.button_enable(BLACK)
        select_p = self.selectin_box.GetStringSelection()
        if select_p == 'model':
            px, py = ch_multi_player(self.othello.can_put_list(BLACK), [self.othello.board], 'LOSER')
            self.othello.put_stone(px, py, BLACK)
            self.board_color_update()
            self.button_enable(WHITE)
            self.gui_turn += 1

        elif select_p == 'random':
            px, py = random_action(self.othello.can_put_list(BLACK), 0, 0)
            self.othello.put_stone(px, py, BLACK)
            self.board_color_update()
            self.button_enable(WHITE)
            self.gui_turn += 1

        else:
            sys.exit()

    def make_status(self):
        layout_status = wx.BoxSizer(wx.HORIZONTAL)
        status_font = wx.Font(50, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        color_b = wx.StaticText(self.status_Panel, wx.ID_ANY, 'BLACK ')
        color_w = wx.StaticText(self.status_Panel, wx.ID_ANY, 'WHITE ')
        self.sc_b = wx.StaticText(self.status_Panel, wx.ID_ANY, '0')
        self.sc_w = wx.StaticText(self.status_Panel, wx.ID_ANY, '0')
        color_b.SetFont(status_font)
        self.sc_b.SetFont(status_font)
        self.sc_w.SetFont(status_font)
        color_w.SetFont(status_font)
        self.sc_w.SetForegroundColour('WHITE')
        color_w.SetForegroundColour('WHITE')

        layout_status.Add(color_b, proportion=1)
        layout_status.Add(self.sc_b, proportion=1)
        layout_status.Add(color_w, proportion=1)
        layout_status.Add(self.sc_w, proportion=1)
        self.status_Panel.SetSizer(layout_status)

    def board_color_update(self):
        self.count_b = 0
        self.count_w = 0
        for bx in range(BOARD_SIZE):
            for by in range(BOARD_SIZE):
                if self.othello.board[by][bx] == 0:
                    button_idx = bx + by * 8
                    self.board_name[button_idx].SetBackgroundColour('#228b22')
                elif self.othello.board[by][bx] == 1:
                    button_idx = bx + by * 8
                    self.board_name[button_idx].SetBackgroundColour('#000000')
                    self.count_b += 1
                else:
                    button_idx = bx + by * 8
                    self.board_name[button_idx].SetBackgroundColour('#ffffff')
                    self.count_w += 1
        self.sc_b.SetLabel(str(self.count_b))
        self.sc_w.SetLabel(str(self.count_w))

    def click_action(self, a, g_p):
        b = a.GetId()
        b_idx = 0
        for button_put in self.board_name:
            c = button_put.GetId()
            if b == c:
                self.put_button(b_idx, g_p)
            else:
                b_idx += 1

    def for_human(self, a):
        g_p = self.turn_check()
        self.click_action(a, g_p)
        if g_p == BLACK:
            self.button_enable(WHITE)
        else:
            self.button_enable(BLACK)
        self.end_check()
        self.gui_turn += 1

    def end_check(self):
        kop = 0
        if self.othello.can_put_list(BLACK) == []:
            kop += 50
        if self.othello.can_put_list(WHITE) == []:
            kop += 50
        if kop == 100:
            judge, sb, sw = self.othello.end()
            self.WINNER.SetLabel(judge)

    def for_random(self, a):
        self.end_check()
        self.click_action(a, WHITE)
        self.board_color_update()
        self.end_check()
        while(True):
            if not self.othello.can_put_list(BLACK) == []:
                px, py = random_action(self.othello.can_put_list(BLACK), 0, 0)
                self.othello.put_stone(px, py, BLACK)
                self.board_color_update()
                self.gui_turn += 1
                self.end_check()
                if not self.othello.can_put_list(WHITE) == []:
                    self.button_enable(WHITE)
                    break
                else:
                    continue
            else:
                self.button_enable(WHITE)
                break
        self.gui_turn += 1

    def for_ch(self, a):
        self.end_check()
        self.click_action(a, WHITE)
        self.board_color_update()
        self.end_check()
        while (True):
            if not self.othello.can_put_list(BLACK) == []:
                px, py = ch_multi_player(self.othello.can_put_list(BLACK), [self.othello.board], 'LOSER')
                self.othello.put_stone(px, py, BLACK)
                self.board_color_update()
                self.gui_turn += 1
                self.end_check()
                if not self.othello.can_put_list(WHITE) == []:
                    self.button_enable(WHITE)
                    break
                else:
                    continue
            else:
                self.button_enable(WHITE)
                break
        self.gui_turn += 1

    def button_enable(self, player):
        for button_name in self.board_name:
            button_name.Disable()
        for bxy in self.othello.can_put_list(player):
            bx, by = bxy
            button_idx = bx + by * 8
            self.board_name[button_idx].Enable()

    def turn_check(self):
        print(self.gui_turn)
        if self.gui_turn == 0:
            print('f b')
            print(self.gui_turn)
            return BLACK
        elif self.gui_turn % 2 == 0:
            if not self.othello.can_put_list(BLACK) == []:
                print('b')
                return BLACK
            else:
                print('pass w')
                self.gui_turn += 1
                return WHITE
        else:
            if not self.othello.can_put_list(WHITE) == []:
                print('w')
                return WHITE
            else:
                print('pass b')
                self.gui_turn += 1
                return BLACK

    def put_button(self, b_idx, g_p):
        px, py = self.for_convert[b_idx]
        self.othello.put_stone(px, py, g_p)
        self.board_color_update()

reversi = wx.App()
Main_Frame = Main_Frame()
Main_Frame.Show()
reversi.MainLoop()


import pandas as pd
from optparse import OptionParser
import os

def run_apriori(transaction, min_support, min_confidence):
    support_list = []
    candidate_item_set_list = get_1_item_set(transaction)
    support = {tuple([int(item)]): 0 for item in candidate_item_set_list}
    for t in transaction:
        items = set(t.split(','))
        for item in items:
            support[tuple([int(item)])] += 1
    length = 1
    while True:
        print('Length:{}\n# of candidate item set: {}'.format(length, len(candidate_item_set_list)))
        length += 1
        support = {k: v for k, v in support.items() if v >= min_support}
        support_list.append([(k, v) for k, v in support.items()])
        candidate_item_set_list = generate_candidate_item_set([x for x in support.keys()], length)
        if len(candidate_item_set_list) == 0:
            break
        transaction = [x for x in transaction if len(x.split(',')) >= length]
        # transaction = transaction[transaction.apply(lambda x: len(x.split(',')) >= length, axis=1)]
        support = {tuple(sorted(item)): 0 for item in candidate_item_set_list}
        for t in transaction:
            items = set(int(x) for x in t.split(','))
            for k, v in support.items():
                if set(k).issubset(items):
                    support[k] += 1
    return support_list, get_confidence(support_list, min_confidence)

def get_confidence(support_list, confidence):
    """
    Return the confidence rules. confidence(pre->post)=support(pre+post)/support(pre)
    :param support_list: [((item_list), support)]
    :param confidence: minimum confidence
    :return: rules: [((pre, post), confidence)]
    """
    result = []
    for item_list in support_list[1:][::-1]:
        for support_item in item_list:
            rules = generate_rules(support_item)
            for pre, post in rules:
                pre_length = len(pre) - 1
                pre_support = [x for x in filter(lambda x: x[0] == pre, support_list[pre_length])][0][1]
                support_item_list_support = [x for x in filter(
                    lambda x: x[0] == support_item[0], support_list[len(support_item[0]) - 1])][0][1]
                this_confidence = float(support_item_list_support) / pre_support
                if this_confidence >= confidence:
                    result.append(tuple([tuple([pre, post]), this_confidence]))
    return result

def generate_rules(items):
    """
    Guarantee that len(pre)+len(post)=len(items)
    :param items: list of frequent items
    :return: [(pre, post)]
    """
    result = []
    support_item = items[0]
    import itertools
    for length in range(1, len(support_item)):
        pre_list = itertools.combinations(support_item, length)
        for pre_item in pre_list:
            post_item = tuple(set(support_item) - set(pre_item))
            result.append((tuple(sorted(pre_item)), tuple(sorted(post_item))))
    return result

def generate_candidate_item_set(item_list, length):
    """
    Generate candidate item list whose length is specified
    :param item_list: a list of frequent item set
    :param length: each frequent-item-set's length
    :return: candidate item set
    """
    result = []
    for index1 in range(len(item_list) - 1):
        for index2 in range(index1 + 1, len(item_list)):
            union = set(item_list[index1]).union(set(item_list[index2]))
            if len(union) == length:
                result.append(tuple(union))
    return result

def get_1_item_set(transaction):
    result = set()
    for t in transaction:
        items = t.split(',')
        for item in items:
            result.add(item)
    return list(result)

def filter_purchase_record(user_behavior_record):
    purchase = user_behavior_record[user_behavior_record['action_type'].isin([2])]
    selected = ['user_id', 'item_id', 'time_stamp']
    purchase = purchase.filter(items=selected)
    print('Finish filtering purchase records, size: {} lines of record.'.format(len(purchase)))
    return purchase.sort_values(by=['time_stamp'])

def construct_transaction(user_behavior_file, truncate_log_size, transaction_file='data_set/transaction.csv'):
    if transaction_file and os.path.exists(transaction_file):
        transaction = pd.read_csv(transaction_file)
    else:
        user_behavior_record = construct_user_behavior_list(user_behavior_file, truncate_log_size)
        purchase_record = filter_purchase_record(user_behavior_record)
        groups = purchase_record.groupby(['time_stamp', 'user_id'])  # transaction = same user buys items in same day
        columns = ['items']
        transaction = pd.DataFrame(columns=columns)
        for t in groups:
            items = t[1]
            transaction = transaction.append(
                {
                    'items': ','.join(items['item_id'].astype('str').values)
                }, ignore_index=True)
        transaction.to_csv('data_set/transaction.csv', index=False)
        print('Finish constructing transaction record, size: {} lines of record'.format(len(transaction)))
    transaction = transaction[:1024 * 16].values
    transaction = [x[0] for x in transaction]
    return transaction

def construct_user_behavior_list(user_behavior_file, truncate_log_size):
    result = pd.read_csv(user_behavior_file)
    print('Finish reading user behavior file, size: {} lines of record.'.format(len(result)))
    result.sample(frac=1)
    result = result[:truncate_log_size]
    print('Finish shuffling and truncating user behavior record, size: {} lines of record.'.format(len(result)))
    return result

def generate_result_string(support_list, rules):
    result = ['------------------ FREQUENT ITEM SET ------------------']
    for i in range(0, len(support_list)):
        length = i + 1
        result.append('Item set length: {}'.format(length))
        for item, support in support_list[i]:
            result.append('\titem: {}, sup: {}'.format(item, support))
    result.append("\n------------------------ RULES ------------------------")
    for rule_item in rules:
        rule, confidence = rule_item
        pre, post = rule
        result.append("rule: {} ==> {}, confidence: {}".format(pre, post, confidence))
    return '\n'.join(result)

def write_to_file(result, destination='result/apriori_result.txt'):
    if not os.path.exists('result'):
        os.makedirs('result')
    with open(destination, 'w') as f:
        f.write(result)

def dispose():
    df = pd.read_csv('data_set/transaction.csv')
    columns = ['items']
    t = pd.DataFrame(columns=columns)
    for index, row in df.iterrows():
        t = t.append(
            {
                'items': row['items']
            }, ignore_index=True)
    t.to_csv('data_set/transaction_disposed.csv', index=False)

def main():
    opt_parser = OptionParser()
    opt_parser.add_option('-f', '--input_file',
                          dest='input',
                          help='user behavior record csv',
                          default='data_set/user_log_format1.csv')
    opt_parser.add_option('-s', '--min_support',
                          dest='min_support',
                          help='minimum support value',
                          default=3,
                          type='int')
    opt_parser.add_option('-c', '--min_confidence',
                          dest='min_confidence',
                          help='minimum confidence value',
                          default=0.6,
                          type='float')
    opt_parser.add_option('-t', '--truncate_log_size',
                          dest='truncate_log_size',
                          help='truncate log size',
                          default=1024 * 1024 * 16,
                          type='int')
    (options, args) = opt_parser.parse_args()

    # user_behavior = construct_user_behavior_list(options.input, options.truncate_log_size)
    transaction_record = construct_transaction(options.input, options.truncate_log_size)
    support_item_list, confidence_rules = run_apriori(transaction_record, options.min_support, options.min_confidence)
    result_string = generate_result_string(support_item_list, confidence_rules)
    print(result_string)
    write_to_file(result_string)

if __name__ == '__main__':
    main()


# Copyright 2020 Lorna Authors. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
import torch
import torch.nn as nn

from .utils import BasicBlock
from .utils import Bottleneck
from .utils import conv1x1
from .utils import get_model_params
from .utils import load_pretrained_weights
from .utils import resnet_params

class ResNet(nn.Module):

    def __init__(self, layers=None, global_params=None):
        super(ResNet, self).__init__()
        assert isinstance(layers, tuple), "blocks_args should be a tuple"
        assert len(layers) > 0, "layers must be greater than 0"

        if global_params.norm_layer is None:
            norm_layer = nn.BatchNorm2d
        self._norm_layer = norm_layer

        self.inplanes = 64
        self.dilation = 1
        if global_params.replace_stride_with_dilation is None:
            # each element in the tuple indicates if we should replace
            # the 2x2 stride with a dilated convolution instead
            replace_stride_with_dilation = [False, False, False]
        if len(replace_stride_with_dilation) != 3:
            raise ValueError("replace_stride_with_dilation should be None "
                             "or a 3-element tuple, got {}".format(replace_stride_with_dilation))
        self.groups = global_params.groups
        self.base_width = global_params.width_per_group
        self.conv1 = nn.Conv2d(3, self.inplanes, kernel_size=7, stride=2, padding=3,
                               bias=False)
        self.bn1 = norm_layer(self.inplanes)
        self.relu = nn.ReLU(inplace=True)
        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
        self.layer1 = self._make_layer(global_params.block, 64, layers[0])
        self.layer2 = self._make_layer(global_params.block, 128, layers[1], stride=2,
                                       dilate=replace_stride_with_dilation[0])
        self.layer3 = self._make_layer(global_params.block, 256, layers[2], stride=2,
                                       dilate=replace_stride_with_dilation[1])
        self.layer4 = self._make_layer(global_params.block, 512, layers[3], stride=2,
                                       dilate=replace_stride_with_dilation[2])
        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
        self.fc = nn.Linear(512 * global_params.block.expansion, global_params.num_classes)

        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
            elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)

        # Zero-initialize the last BN in each residual branch,
        # so that the residual branch starts with zeros, and each residual block behaves like an identity.
        # This improves the model by 0.2~0.3% according to https://arxiv.org/abs/1706.02677
        if global_params.zero_init_residual:
            for m in self.modules():
                if isinstance(m, Bottleneck):
                    nn.init.constant_(m.bn3.weight, 0)
                elif isinstance(m, BasicBlock):
                    nn.init.constant_(m.bn2.weight, 0)

    def _make_layer(self, block, planes, blocks, stride=1, dilate=False):
        norm_layer = self._norm_layer
        downsample = None
        previous_dilation = self.dilation
        if dilate:
            self.dilation *= stride
            stride = 1
        if stride != 1 or self.inplanes != planes * block.expansion:
            downsample = nn.Sequential(
                conv1x1(self.inplanes, planes * block.expansion, stride),
                norm_layer(planes * block.expansion),
            )

        layers = [block(self.inplanes, planes, stride, downsample, self.groups,
                        self.base_width, previous_dilation, norm_layer)]
        self.inplanes = planes * block.expansion
        for _ in range(1, blocks):
            layers.append(block(self.inplanes, planes, groups=self.groups,
                                base_width=self.base_width, dilation=self.dilation,
                                norm_layer=norm_layer))

        return nn.Sequential(*layers)

    def extract_features(self, inputs):
        """ Returns output of the final convolution layer """
        x = self.conv1(inputs)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        return x

    def forward(self, inputs):
        x = self.conv1(inputs)
        x = self.bn1(x)
        x = self.relu(x)
        x = self.maxpool(x)

        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)

        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.fc(x)

        return x

    @classmethod
    def from_name(cls, model_name, override_params=None):
        cls._check_model_name_is_valid(model_name)
        layers, global_params = get_model_params(model_name, override_params)
        return cls(layers, global_params)

    @classmethod
    def from_pretrained(cls, model_name, num_classes=1000):
        model = cls.from_name(model_name, override_params={"num_classes": num_classes})
        load_pretrained_weights(model, model_name, load_fc=(num_classes == 1000))
        return model

    @classmethod
    def get_image_size(cls, model_name):
        cls._check_model_name_is_valid(model_name)
        _, res = resnet_params(model_name)
        return res

    @classmethod
    def _check_model_name_is_valid(cls, model_name):
        """ Validates model name. None that pretrained weights are only available for
        the first four models (resnet_pytorch{i} for i in 18,34,50,101,152) at the moment. """
        num_models = [18, 34, 50, 101, 152]
        valid_models = ["resnet" + str(i) for i in num_models]
        if model_name not in valid_models:
            raise ValueError("model_name should be one of: " + ", ".join(valid_models))


import asyncio
import collections
import datetime
import time

import discord
from discord.embeds import EmptyEmbed
from discord.ext import commands
from discord.raw_models import RawMessageDeleteEvent, RawMessageUpdateEvent
from peewee import IntegrityError

from Util import GearbotLogging, Configuration, Utils, Archive, Emoji, Translator
from database.DatabaseConnector import LoggedMessage, LoggedAttachment

class ModLog:

    def __init__(self, bot):
        self.bot:commands.Bot = bot
        self.bot.loop.create_task(self.prep())
        self.bot.loop.create_task(cache_task(self))
        self.running = True

    def __unload(self):
        self.running = False

    async def buildCache(self, guild:discord.Guild, limit = 500, startup=False):
        GearbotLogging.info(f"Populating modlog with missed messages during downtime for {guild.name} ({guild.id}).")
        newCount = 0
        editCount = 0
        count = 0
        for channel in guild.text_channels:
            if channel.permissions_for(guild.get_member(self.bot.user.id)).read_messages:
                logged_messages = LoggedMessage.select().where(LoggedMessage.channel == channel.id).order_by(
                    LoggedMessage.messageid.desc()).limit(limit*1.5)
                messages = dict()
                for message in logged_messages:
                    messages[message.messageid] = message
                async for message in channel.history(limit=limit, reverse=False, before=self.cache_message if startup else None):
                    if not self.running:
                        GearbotLogging.info("Cog unloaded while still building cache, aborting.")
                        return
                    if message.author == self.bot.user:
                        continue
                    if message.id not in messages.keys():
                        try:
                            LoggedMessage.create(messageid=message.id, author=message.author.id,
                                                                  content=message.content, timestamp = message.created_at.timestamp(), channel=channel.id, server=channel.guild.id)
                            for a in message.attachments:
                                LoggedAttachment.create(id=a.id, url=a.url, isImage=(a.width is not None or a.width is 0), messageid=message.id)
                            newCount = newCount + 1
                        except IntegrityError:
                            # somehow we didn't fetch enough messages, did someone set off a nuke in the channel?
                            logged = LoggedMessage.get(messageid=message.id)
                            if logged.content != message.content:
                                logged.content = message.content
                                logged.save()
                                editCount = editCount + 1
                    else:
                        logged = messages[message.id]
                        if logged.content != message.content:
                            logged.content = message.content
                            logged.save()
                            editCount = editCount + 1
                    count = count + 1
                    if count % 25 is 0:
                        await asyncio.sleep(0)
        GearbotLogging.info(f"Discovered {newCount} new messages and {editCount} edited in {guild.name} (checked {count})")

    async def prep(self):
        self.cache_message = await GearbotLogging.logToBotlog(f"{Emoji.get_chat_emoji('REFRESH')} Validating modlog cache")
        self.to_cache = []
        for guild in self.bot.guilds:
            if Configuration.getConfigVar(guild.id, "MINOR_LOGS") is not 0:
                self.to_cache.append(guild)
        for i in range(min(3, len(self.bot.guilds))):
            self.bot.loop.create_task(self.startup_cache())
        self.cache_start = time.perf_counter()

    async def startup_cache(self):
        while self.to_cache is not None:
            if len(self.to_cache) > 0:
                guild = self.to_cache.pop()
                await self.buildCache(guild, startup=True)
                await asyncio.sleep(0)
            else:
                self.to_cache = None
                await self.cache_message.edit(content=f"{Emoji.get_chat_emoji('YES')} Modlog cache validation completed in {round(time.perf_counter() - self.cache_start, 2)}s")

    async def on_message(self, message: discord.Message):
        if not hasattr(message.channel, "guild") or message.channel.guild is None:
            return
        if Configuration.getConfigVar(message.guild.id, "MINOR_LOGS") is 0 or message.author == self.bot.user:
            return
        for a in message.attachments:
            LoggedAttachment.create(id=a.id, url=a.url, isImage=(a.width is not None or a.width is 0), messageid=message.id)
        LoggedMessage.create(messageid=message.id, author=message.author.id, content=message.content, timestamp=message.created_at.timestamp(), channel=message.channel.id, server=message.guild.id)

    async def on_raw_message_delete(self, data:RawMessageDeleteEvent):
        message = LoggedMessage.get_or_none(messageid=data.message_id)
        if message is not None:
            channel: discord.TextChannel = self.bot.get_channel(data.channel_id)
            user: discord.User = self.bot.get_user(message.author)
            hasUser = user is not None
            if hasUser and user.id in Configuration.getConfigVar(channel.guild.id, "IGNORED_USERS"):
                return
            channelid = Configuration.getConfigVar(channel.guild.id, "MINOR_LOGS")
            if channelid is not 0:
                logChannel:discord.TextChannel = self.bot.get_channel(channelid)
                attachments = LoggedAttachment.select().where(LoggedAttachment.messageid == data.message_id)
                if logChannel is not None:
                    embed = discord.Embed(timestamp=datetime.datetime.utcfromtimestamp(time.time()),
                                          description=message.content)
                    embed.set_author(name=user.name if hasUser else message.author, icon_url=user.avatar_url if hasUser else EmptyEmbed)
                    embed.set_footer(text=f"Sent in #{channel.name}")
                    if len(attachments) > 0:
                        embed.add_field(name=Translator.translate('attachment_link', logChannel.guild), value="\n".join(attachment.url for attachment in attachments))
                    name = Utils.clean_user(user) if hasUser else str(message.author)
                    await logChannel.send(f":wastebasket: {Translator.translate('message_removed', channel.guild.id, name=name, user_id=user.id if hasUser else 'WEBHOOK', channel=channel.mention)}", embed=embed)

    async def on_raw_message_edit(self, event:RawMessageUpdateEvent):
        if event.data["channel_id"] == Configuration.getMasterConfigVar("BOT_LOG_CHANNEL"):
            return
        message = LoggedMessage.get_or_none(messageid=event.message_id)
        if message is not None and "content" in event.data:
            channel: discord.TextChannel = self.bot.get_channel(int(event.data["channel_id"]))
            user: discord.User = self.bot.get_user(message.author)
            hasUser = user is not None
            channelid = Configuration.getConfigVar(channel.guild.id, "MINOR_LOGS")
            if channelid is not 0:
                logChannel: discord.TextChannel = self.bot.get_channel(channelid)
                if logChannel is not None:
                    if message.content == event.data["content"]:
                        #prob just pinned
                        return
                    if message.content is None or message.content == "":
                        message.content = f"<{Translator.translate('no_content', channel.guild.id)}>"
                    embed = discord.Embed(timestamp=datetime.datetime.utcfromtimestamp(time.time()))
                    embed.set_author(name=user.name if hasUser else message.author,
                                     icon_url=user.avatar_url if hasUser else EmptyEmbed)
                    embed.set_footer(text=Translator.translate('sent_in', channel.guild.id, channel= f"#{channel.name}"))
                    embed.add_field(name=Translator.translate('before', channel.guild.id), value=Utils.trim_message(message.content, 1024), inline=False)
                    embed.add_field(name=Translator.translate('after', channel.guild.id), value=Utils.trim_message(event.data["content"], 1024), inline=False)
                    if not (hasUser and user.id in Configuration.getConfigVar(channel.guild.id, "IGNORED_USERS")):
                        await logChannel.send(f":pencil: {Translator.translate('edit_logging', channel.guild.id, user=Utils.clean_user(user), user_id=user.id, channel=channel.mention)}",
                        embed=embed)
                    message.content = event.data["content"]
                    message.save()

    async def on_member_join(self, member:discord.Member):
        channelid = Configuration.getConfigVar(member.guild.id, "JOIN_LOGS")
        if channelid is not 0:
            logChannel:discord.TextChannel = self.bot.get_channel(channelid)
            if logChannel is not None and logChannel.permissions_for(member.guild.me).send_messages:
                dif = (datetime.datetime.utcnow() - member.created_at)
                minutes, seconds = divmod(dif.days * 86400 + dif.seconds, 60)
                hours, minutes = divmod(minutes, 60)
                age = (Translator.translate('days', member.guild.id, days=dif.days)) if dif.days > 0 else Translator.translate('hours', member.guild.id, hours=hours, minutes=minutes)
                await logChannel.send(f"{Emoji.get_chat_emoji('JOIN')} {Translator.translate('join_logging', member.guild.id, user=Utils.clean_user(member), user_id=member.id, age=age)}")

    async def on_member_remove(self, member:discord.Member):
        exits = self.bot.data["forced_exits"]
        if member.id in exits:
            exits.remove(member.id)
            return
        channelid = Configuration.getConfigVar(member.guild.id, "JOIN_LOGS")
        if channelid is not 0:
            logChannel: discord.TextChannel = self.bot.get_channel(channelid)
            if logChannel is not None and logChannel.permissions_for(member.guild.me).send_messages:
                await logChannel.send(f"{Emoji.get_chat_emoji ('LEAVE')} {Translator.translate('leave_logging', member.guild.id, user=Utils.clean_user(member), user_id=member.id)}")

    async def on_member_ban(self, guild, user):
        if user.id in self.bot.data["forced_exits"]:
            return
        channelid = Configuration.getConfigVar(guild.id, "MOD_LOGS")
        if channelid is not 0:
            logChannel: discord.TextChannel = self.bot.get_channel(channelid)
            if logChannel is not None:
                await logChannel.send(f":rotating_light: {user.name}#{user.discriminator} (`{user.id}`) has been banned from the server.")
                self.bot.data["forced_exits"].append(user.id)

    async def on_member_unban(self, guild, user):
        if user.id in self.bot.data["unbans"]:
            return
        channelid = Configuration.getConfigVar(guild.id, "MOD_LOGS")
        if channelid is not 0:
            logChannel: discord.TextChannel = self.bot.get_channel(channelid)
            if logChannel is not None:
                await logChannel.send(
                    f":rotating_light: {user.name}#{user.discriminator} (`{user.id}`) has been unbanned from the server.")

    async def on_member_update(self, before, after):
        channelid = Configuration.getConfigVar(after.guild.id, "MINOR_LOGS")
        if channelid is not 0:
            logChannel: discord.TextChannel = self.bot.get_channel(channelid)
            if logChannel is not None:
                if (before.nick != after.nick and
                    after.nick != before.nick):
                    after_clean_name = Utils.clean(after.name)
                    after_clean_display_name = Utils.clean(after.display_name)
                    before_clean_display_name = Utils.clean(before.display_name)
                    await logChannel.send(
                        f'{Emoji.get_chat_emoji("NICKTAG")} {after_clean_name}#{after.discriminator} (`{after.id}`) has changed nickname from **`\u200b{before_clean_display_name}`** to **`\u200b{after_clean_display_name}`**.'
                    )
                elif (before.name != after.name and
                    after.name != before.name):
                    after_clean_name = Utils.clean(after.name)
                    before_clean_name = Utils.clean(before.name)
                    await logChannel.send(
                        f'{Emoji.get_chat_emoji("NAMETAG")} {after_clean_name}#{after.discriminator} (`{after.id}`) has changed username from **`\u200b{before_clean_name}#{after.discriminator}`** to **`\u200b{after_clean_name}#{after.discriminator}`**.'
                    )

    async def on_raw_bulk_message_delete(self, event: discord.RawBulkMessageDeleteEvent):
        channel_id = Configuration.getConfigVar(event.guild_id, "MINOR_LOGS")
        if channel_id is not 0:
            message_list = dict()
            for mid in event.message_ids:
                message = LoggedMessage.get_or_none(LoggedMessage.messageid == mid)
                if message is not None:
                    message_list[mid] = message
            if len(message_list) > 0:
                await Archive.archive_purge(self.bot, event.guild_id, collections.OrderedDict(sorted(message_list.items())))

async def cache_task(modlog:ModLog):
    GearbotLogging.info("Started modlog background task.")
    while modlog.running:
        if len(modlog.bot.to_cache) > 0:
            ctx = modlog.bot.to_cache.pop(0)
            await modlog.buildCache(ctx.guild)
            await ctx.send("Caching complete.")
        await asyncio.sleep(1)
    GearbotLogging.info("modlog background task terminated.")

def setup(bot):
    bot.add_cog(ModLog(bot))


import json
from itertools import combinations

def create_combinations(variable_list, a_variable):
    combination = combinations(variable_list, a_variable)
    return combination

def print_combinations(list_combinations):
    yuppie = list(list_combinations)
    for variable in yuppie:
        write_to_csv_file_with_new_line(',', variable)

def write_to_csv_file_with_new_line(delimiter, string_value):
    file_print.write(delimiter.join(string_value))
    file_print.write("\n")

def run_example(json_directory, output_location):
    json_raw_data = open(json_directory).read()
    json_data_formed = json.loads(json_raw_data)
    global file_print
    file_print = open(output_location, 'w+')
    hello = create_combinations(json_data_formed, 4)
    print_combinations(hello)

    file_print.close()


"""
Author: Gabriel Fernandez
GitHub: github (dot) com / gabriel80808
Date: June 6, 2018

Algorithms to be implemented
"""
import numpy as np
import tensorflow as tf
from dynamics import NNDynamicsModel
import controllers
import utils

class ModelBasedMPC:
    """Model-Based Model Predictive Control
    Algorithm: “Neural Network Dynamics for Model-Based Deep Reinforcement Learning
    with Model-Free Fine-Tuning”, Anusha Nagabandi, Gregory Kahn, Ronald S. Fearing,
    Sergey Levine. https://arxiv.org/abs/1708.02596
    """
    def __init__(self,
                 environment='Hex',
                 controller='MPC',  # Place holder for object not string
                 function_approx='feed_forward',  # Place holder for object not string
                 exp_name='mb_mpc',
                 seed=1,
                 render=True,
                 learning_rate=1e-3,
                 onpol_iters=3,  # On-policy iteration roll-outs
                 dyn_iters=60,  # Iterations for dynamics model
                 batch_size=512,
                 random_paths=10,  # Paths represents generated dynamical trajectories
                 onpol_paths=10,
                 simulated_paths=200,  # 1000
                 ep_len=200,  # 1000 simulation episode length
                 mpc_horizon=20  # 15
                 ):
        # Major Components
        self.env_name = environment
        self.con = controller
        self.func_ap = function_approx

        # Experiment meta-params
        self.exp_name = exp_name
        self.seed = seed
        self.render = render

        # Training args
        self.learning_rate = learning_rate
        self.onpol_iters = onpol_iters
        self.dyn_iters = dyn_iters
        self.batch_size = batch_size

        # Data collection
        self.random_paths = random_paths
        self.onpol_paths = onpol_paths
        self.simulated_paths = simulated_paths
        self.ep_len = ep_len
        self.mpc_horizon = mpc_horizon

        # Check/create if directory exists
        self.log_dir = utils.data_dir(self.env_name, self.exp_name)

        # Set random seed for experiments
        np.random.seed(self.seed)
        tf.set_random_seed(self.seed)

        # Get environment and cost function
        self.env = utils.get_env(self.env_name)
        self.cost_fn = utils.get_cost_fn(self.env_name)

    def set_param(self, names_value_dict):
        for name, value in names_value_dict:
            setattr(self, name, value)
        return None

    def train(self):
        """Train Model-Based MPC"""
        data = utils.run_sim(self.env,  # Generate random data to train dynamics model
                             controller=controllers.Random(self.env),
                             num_paths=self.random_paths,
                             horizon=self.ep_len,
                             render=False,
                             verbose=True,
                             section="Generating Data for Dynamics with Random Controller")

        # Build dynamics model and MPC controllers.
        sess = tf.Session()

        """Need to add function appx"""
        dyn_model = NNDynamicsModel(env=self.env,
                                    func_name=self.func_ap,
                                    normalization=utils.compute_normalization(data),
                                    batch_size=self.batch_size,
                                    iterations=self.dyn_iters,
                                    learning_rate=self.learning_rate,
                                    sess=sess)

        mpc_controller = controllers.MPC(env=self.env,
                                         dyn_model=dyn_model,
                                         horizon=self.mpc_horizon,
                                         cost_fn=self.cost_fn,
                                         num_simulated_paths=self.simulated_paths)
        # Build tf session
        sess.__enter__()
        tf.global_variables_initializer().run()

        # Iterate: Run policy, aggregate, & refit dynamics
        for itr in range(self.onpol_iters):
            dyn_model.fit(data)
            print('On Policy Iteration: ', itr)
            paths = utils.run_sim(self.env,
                                  mpc_controller,
                                  self.onpol_paths,
                                  horizon=self.ep_len,
                                  render=True,
                                  verbose=True,
                                  section="MPC Trajectories")
            data = np.concatenate((data, paths))

            returns = [np.sum(path["reward"]) for path in paths]
            costs = [utils.path_cost(self.cost_fn, path) for path in paths]
            utils.log_stats(self.log_dir, itr, {"Costs": costs, "Returns": returns})

        return returns, costs


import numpy as np
import pandas as pd   # pandas 是基于NumPy 的一种工具，该工具是为了解决数据分析任务而创建的
import matplotlib.pyplot as plt

# 计算代价函数
# X:输入变量 y：输出变量 theta：预测函数的两个系数值（h(x)=theta(1)+theta(2)*x）
def compute_cost(X,y,theta):
    m=len(X)
    inner=np.power(((X.dot(theta.T))-y),2)
    return sum(inner)/(2*m)

# 梯度下降算法
# alpha：学习率 epoch：迭代次数
def gradientDescent(X, y, theta, alpha, epoch=1000):
    temp = np.array(np.zeros(theta.shape))
    parameters = int(theta.flatten().shape[0])  # 参数theta的数量
    cost = np.zeros(epoch)  # 初始化一个ndarray，包含每次迭代后的cost
    m = X.shape[0]  # 样本数量

    # 利用向量化同步计算theta的值
    for i in range(epoch):
        temp = theta - (alpha / m) * (X.dot(theta.T) - y).T.dot(X)  # 得出一个theta行向量
        theta = temp
        cost[i] = compute_cost(X, y, theta)
    return theta, cost

if __name__=='__main__':
    path = 'ex1data1.txt'
    # names添加列名，header用指定的行来作为标题，若原来无标题则设为none
    data = pd.read_csv(path, names=['Population', 'Profit'])

    # 在训练集中插入一列1，方便计算
    data.insert(0, 'Ones', 1)
    # 设置训练集X和目标变量y的值
    cols = data.shape[1]
    X = data.iloc[:, 0:cols - 1]  # 输入变量X为前cols-1列
    y = data.iloc[:, cols - 1:cols]  # 输出变量y为最后一列
    X = np.array(X.values)
    y = np.array(y.values)
    theta = np.array([0, 0]).reshape(1, 2)

    alpha = 0.01
    epoch = 2000

    final_theta, cost = gradientDescent(X, y, theta, alpha, epoch)

    population = np.linspace(data.Population.min(), data.Population.max(), 100)
    profit = final_theta[0, 0] + (final_theta[0, 1] * population)

    fig, ax = plt.subplots(figsize=(8, 6))
    ax.plot(population, profit, 'r', label='Prediction')
    ax.scatter(data['Population'], data['Profit'], label='Training data')
    ax.legend(loc=4)
    ax.set_xlabel('Population')
    ax.set_ylabel('Profit')
    ax.set_title('Predicting Profit by Population Size')
    plt.show()

    fig, ax = plt.subplots(figsize=(8, 6))
    ax.plot(np.arange(epoch), cost, 'r')
    ax.set_xlabel('Iteration')
    ax.set_ylabel('Cost')
    ax.set_title('Error vs. Traning Epoch')
    plt.show()


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

import math
import copy
from scrapy import Request
from bs4 import BeautifulSoup
from scrapy.spiders import CrawlSpider
from models.club import StructureStartUrl
from item.club_topic_comment_items import ClubTopicCommentScrapyItem

class AutoHomeTopicCommentSpider(CrawlSpider):
    name = "club_topic_comment"
    offset = 0
    club_index = 0
    page_index = 1
    # club_id_list = StructureStartUrl().get_topic_id(offset)
    club_id_list = [5411619]

    base_url = "https://forum.app.autohome.com.cn/forum_v7.9.5/forum/club/topiccontent-a2-pm2-v8.8.0-t%s-o0-p%s-s20-c1-nt0-fs0-sp0-al0-cw360-i0-ct1.json"
    start_urls = [base_url % (club_id_list[club_index], page_index)]

    def parse(self, response):
        item = ClubTopicCommentScrapyItem()
        yield Request(url=response.url, callback=self.parse_club_topic_comment_items,
                      meta={"item": copy.deepcopy(item)})

    def parse_club_topic_comment_items(self, response):
        i = 0
        item = response.meta['item']
        soup = BeautifulSoup(response.body.decode())
        node_list = response.xpath("//*[@class=\"post-flow\"]/li")
        soup_node_list = soup.find_all('div', {'class': 'user-content'})
        for node in node_list:
            item["topic_id"] = self.club_id_list[self.club_index]
            try:
                item["user"] = node.xpath(".//span[@class=\"name\"]/a/text()").extract()[0]
            except Exception as e:
                item["user"] = ""
            try:
                item["content"] = soup_node_list[i].get_text().strip("\n")
            except Exception as e:
                item["content"] = ""
            try:
                item["publish_time"] = node.xpath('.//*[@class="time"]/text()').extract()[0]
            except Exception as e:
                item["publish_time"] = ""
            try:
                item["id"] = node.xpath('.//span[@class="flowLevel"]/span/text()').extract()[0]
            except Exception as e:
                item["id"] = ""
            if item["id"] != "":
                yield item
                i += 1

        self.page_index += 1
        if 0 < len(soup_node_list) <= 20:
            url = self.base_url % (self.club_id_list[self.club_index], self.page_index)
            yield Request(url=url, callback=self.parse_club_topic_comment_items, meta={"item": copy.deepcopy(item)})
        else:
            self.club_index += 1
            if self.club_index < len(self.club_id_list):
                self.page_index = 1
                url = self.base_url % (self.club_id_list[self.club_index], self.page_index)
                yield Request(url=url, callback=self.parse_club_topic_comment_items, meta={"item": copy.deepcopy(item)})
            else:
                self.offset += 1000
                self.club_id_list = StructureStartUrl().get_topic_id(self.offset)
                if 1000 >= len(self.club_id_list) > 0:
                    self.club_index = 0
                    self.page_index = 1
                    url = self.base_url % (self.club_id_list[self.club_index], self.page_index)
                    yield Request(url=url, callback=self.parse_club_topic_comment_items,
                                  meta={"item": copy.deepcopy(item)})