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

import pytest

from pairing.utils import Pairing

class TestPairing(object):
    def test_pairing(self):
        '''
        If we have an ordered list 1,2,3,4,5,6
        slide pairing is (1, 4), (2, 5), (3, 6)
        '''
        params = [{'id': 1, 'score': 0}, {'id': 2, 'score': 0}]
        #output, _ = pair(players)
        p = Pairing(params)
        assert p.output == [(1, 2), ]

    def test_pair_multiple(self):
        params = [
            {'id': 1, 'score': 0},
            {'id': 2, 'score': 0},
            {'id': 3, 'score': 0},
            {'id': 4, 'score': 0}
        ]
        #output, _ = pair(params)
        p = Pairing(params)
        assert p.output == [(1, 3), (2, 4)]

    def test_pair_odd(self):
        params = [
            {'id': 1, 'score': 0},
            {'id': 2, 'score': 0},
            {'id': 3, 'score': 0},
            {'id': 4, 'score': 0},
            {'id': 5, 'score': 0},
        ]
        #import pdb;pdb.set_trace()
        p = Pairing(params)
        #output, remainder = pair(params)
        assert p.remainder == [{'id': 5, 'score': 0}]
        assert p.output == [(1, 3), (2, 4)]

    def test_grouping(self):
        params = [
            {'id': 1, 'score': 2},
            {'id': 2, 'score': 2},
            {'id': 3, 'score': 1},
            {'id': 4, 'score': 1},
            {'id': 5, 'score': 0},
            {'id': 6, 'score': 0}
        ]
        #import pdb;pdb.set_trace()
        p = Pairing(params)
        #output, remainder = pair(params)
        assert p.output == [(1, 2), (3, 4), (5, 6)]

    def test_grouping_bottom_heavy(self):
        '''Test that higher score will fall-through
           to be paired with lower scores
        '''
        params = [
            {'id': 1, 'score': 2},
            {'id': 2, 'score': 1},
            {'id': 3, 'score': 1},
            {'id': 4, 'score': 1},
        ]
        #import pdb;pdb.set_trace()
        p = Pairing(params)
        #output, remainder = pair(params)
        assert p.output == [(1, 2), (3, 4)]

    def test_grouping_topheavy(self):
        params = [
            {'id': 1, 'score': 2},
            {'id': 2, 'score': 2},
            {'id': 3, 'score': 2},
            {'id': 4, 'score': 1},
        ]
        p = Pairing(params)
        #output, remainder = pair(params)
        assert p.output == [(1, 2), (3, 4)]

    def test_topheavy_remainder(self):
        params = [
            {'id': 1, 'score': 2},
            {'id': 2, 'score': 2},
            {'id': 3, 'score': 2},
            {'id': 4, 'score': 1},
            {'id': 5, 'score': 1},
        ]
        #import pdb;pdb.set_trace()
        p = Pairing(params)
        #output, remainder = pair(params)
        assert p.output == [(1, 2), (3, 4)]
        assert p.remainder == {'id': 5, 'score': 1}

class TestHavePlayed(object):

    @pytest.fixture
    def params(self):
        return [
            {'id': 1, 'score': 2},
            {'id': 2, 'score': 2},
            {'id': 3, 'score': 2},
            {'id': 4, 'score': 1},
            {'id': 5, 'score': 1},
            {'id': 6, 'score': 0},
            {'id': 7, 'score': 0},
            {'id': 8, 'score': 0},
            {'id': 9, 'score': 0}
        ]

    def test_pairing(self, params):
        p = Pairing(params)
        #output, remainder = pair(params)
        assert p.output == [(1, 2), (3, 4), (5, 6), (7, 8)]
        assert p.remainder == {'id': 9, 'score': 0}

    def test_history(self, params):
        history = [(3, 4), (1, 5), (2, 6)]
        #import pdb;pdb.set_trace()
        p = Pairing(params, history=history)
        assert p.output == [(1, 2), (3, 5), (4, 6), (7, 8)]
        assert p.remainder == {'id': 9, 'score': 0}

class TestSorting(object):

    def test_sort_by_score(self):
        '''Test that players are sorted by score'''
        params = [
            {'id': 1, 'score': 0},
            {'id': 2, 'score': 2},
            {'id': 3, 'score': 4},
            {'id': 4, 'score': 1},
            {'id': 5, 'score': 1},
        ]
        p = Pairing(params)
        assert p.output == [(3, 2), (4, 5)]
        assert p.remainder == {'id': 1, 'score': 0}


import firebase_admin
from firebase_admin import credentials
from shopping_cart.main_menu import MainMenu

# inserting the filapath to your Service Account Key while initializing the firebase
# connection allows the db to check your credentials
cred = credentials.Certificate("untracked_files\\ServiceAccountKey.json")
firebase_admin.initialize_app(cred)

def main():
    # initalize main menu object and run loop
    main_menu = MainMenu()
    main_menu.menu_loop()

if __name__ == '__main__':
    main()


#!/usr/bin/env python
import httplib2
import operator
import json
from bs4 import BeautifulSoup
from config import *
import smtplib
import string
import sys

def format_thesis(author, info):
	string = u"\n"
	string += u"What: " + info['title'] + u"\n"
	string += u"Who: " + author + u"\n"
	string += u"When: " + info['date'] + u"\n"
	string += u"Location: " + info['location'] + u"\n"
	string += u"Area: " + info['area'] + u"\n"
	string += u"Level: " + info['level'] + u"\n"
	return string

old_dict = {}
try:
	f = open(config_dump_filename, 'r')
	content = f.read()
	old_dict = json.loads(content)
	f.close()
except:
	# we will simply compare with an empty dictionary of the "old" these
	pass

http = httplib2.Http()
urls = ['http://www.ida.liu.se/edu/ugrad/thesis/presentations.shtml', 'http://www.isy.liu.se/edu/pres/']
theses_dict = {}
for url in urls:
	try:
		resp, content = http.request(url)
	except:
		sys.exit(1)

	main_div =  BeautifulSoup(content).find('div', { 'id' : 'maincontent' })
	table = main_div.find('table')
	tr = table.findAll('tr')
	for i in range(0, len(tr) , 2):
		header = tr[i].find('td').find('b').renderContents().decode('utf-8')
		date, area = header.split(' - ') # first element is date, second element is area
		info = tr[i + 1].find('td')
		title = info.find('b').renderContents().strip().decode('utf-8')
		author, level, info = info.find('font').renderContents().replace('
', '').replace('
', '').split('
')
		author = author.strip().decode('utf-8')
		level = level.strip().decode('utf-8')
		info = info.strip().decode('utf-8')
		clock, location = info.split(', ')
		entry = { u'date' : date + u', ' + clock, u'location' : location, u'title' : title, u'level' : level, u'area' : area }
		theses_dict.update({ author : entry })

new_theses = [thesis for thesis in theses_dict if thesis not in old_dict]
something_removed = any([True for thesis in old_dict if thesis not in theses_dict])

mail_str = ""
if (len(new_theses) != 0):
	mail_str = "New theses added:\n"
	# done alphabetically
	for x in sorted(new_theses):
		mail_str += format_thesis(x, theses_dict[x])

# we have produced output, thus we shall mail the user and update our dump file
if (mail_str != ""):
	body = string.join((
			u"From: %s" % config_email_from,
			u"To: %s" % config_email_to,
			u"Subject: %s" % config_email_subject ,
			u"",
			mail_str
			), u"\r\n")
	server = smtplib.SMTP(config_email_host)
	server.sendmail(config_email_from, [config_email_to], body.encode('utf-8'))
	server.quit()

if (mail_str != "") or something_removed:
	f = open(config_dump_filename, 'w')
	f.write(json.dumps(theses_dict))
	f.close()


""""Given a Matrix of ones and zeros, write a function (solution) that returns the size of the largest contiguous block of zeros.

For example, for the input:

matrix = [
   [0, 0, 0, 0, 1, 1, 1],
   [0, 0, 0, 0, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 0, 0, 1, 1],
   [1, 1, 1, 1, 0, 1, 1],
]
The largest contiguous block is the one in the top left corner, which contains 9 zeros (solution = 9)

Tip: two elements are not within the same blocks if they are only connected diagonally.

[execution time limit] 4 seconds (py3)

[input] array.array.integer matrix

The input matrix is an array of arrays, where the values are either 1 or 0.

[output] integer

The size of the largest contiguous block of zeros"""

def solution(grid):
    def dfs(r, c):

        # base case:

        if not (0 <= r < h) or not (0 <= c < w):
            # Stop due to being out of boundary
            return 0

        if grid[r][c] != 0:
            # Stop due to being out of current island
            return 0

            # general cases:

            # mark current grid to -1 as visited
        grid[r][c] = -1

        # update area of current island
        return 1 + dfs(r - 1, c) + dfs(r + 1, c) + dfs(r, c - 1) + dfs(r, c + 1)

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

    h, w = len(grid), len(grid[0])

    max_island_area = 0

    # Search all possible islands in DFS
    for r in range(h):
        for c in range(w):

            if grid[r][c] == 0:
                cur_island_area = dfs(r, c)

                max_island_area = max(max_island_area, cur_island_area)

    return max_island_area


import math
n = int(input())

def gcd(a,b):
    if b == 0:
        return a
    else:
        return gcd(b,a%b)
for _ in range(n):
    a,b = map(int,input().split())
    g = gcd(a,b)
    print(
        math.trunc(g*(a/g)*(b/g))
    )


from __future__ import annotations
import os
from pathlib import Path
from typing import (
    Any,
    Dict,
    Iterable,
    Literal,
    Sequence,
    Tuple,
    Union,
)

from xarray import DataArray
from datatree import DataTree
from numpy.typing import NDArray

import dask.array as da
from fibsem_tools.io.util import (
    AccessMode,
    ArrayLike,
    Attrs,
    GroupLike,
    PathLike,
    split_by_suffix,
)

import fibsem_tools.io.mrc
import fibsem_tools.io.dat
import fibsem_tools.io.xr
import fibsem_tools.io.h5
import fibsem_tools.io.zarr
import fibsem_tools.io.tif

_formats = (".dat", ".mrc", ".tif", ".tiff")
_container_extensions = (".zarr", ".n5", ".h5")
_suffixes = (*_formats, *_container_extensions)

def access(
    path: PathLike,
    mode: AccessMode,
    **kwargs: Any,
) -> ArrayLike | GroupLike:
    """

    Access a variety of hierarchical array storage formats.

    Parameters
    ----------
    path: A path reference to array data or an array container.
        If `path` is a string, it is assumed to be a path, then the appropriate access
        function will be selected based on the extension of the path, and the file will
        be accessed. To access a Zarr or N5 containers, the path to the root container
        must end with .zarr or .n5

        For reading .zarr or n5 containers, this function dispatches to `zarr.open`

        For reading .dat files (Janelia-native binary image format), this function uses
        routines found in `fibsem_tools.io.dat`

        If `path` is a collection of strings, it is assumed that each element of the
        collection represents a path, and this function will return the result of
        calling itself on each element of the collection.

    mode: string
        The access mode for the file. e.g. 'r' for read-only access, 'w' for writable
        access.

    **kwargs: any
        Additional kwargs are passed to the format-specific access function.

    Returns
    -------
    An array-like object or a group-like object
    """

    path_outer, path_inner, suffix = split_by_suffix(path, _suffixes)
    is_container = suffix in _container_extensions

    if suffix == ".zarr":
        accessor = fibsem_tools.io.zarr.access_zarr
    elif suffix == ".n5":
        accessor = fibsem_tools.io.zarr.access_n5
    elif suffix == ".h5":
        accessor = fibsem_tools.io.h5.access_h5
    elif suffix in (".tif", ".tiff"):
        accessor = fibsem_tools.io.tif.access
    elif suffix == ".mrc":
        accessor = fibsem_tools.io.mrc.access
    elif suffix == ".dat":
        accessor = fibsem_tools.io.dat.access
    else:
        raise ValueError(
            f"""
                Cannot access file with extension {suffix}. Try one of
                {_suffixes}
                """
        )

    if is_container:
        return accessor(path_outer, path_inner, mode=mode, **kwargs)
    else:
        return accessor(path_outer, mode=mode, **kwargs)

def read(path: PathLike, **kwargs) -> ArrayLike | GroupLike:
    """

    Read-only access for data (arrays and groups) from a variety of hierarchical array
    storage formats.

    Parameters
    ----------
    path: A path or collection of paths to image files.
        If `path` is a string, it is assumed to be a path, then the appropriate access
        function will be selected based on the extension of the path, and the file will
        be accessed. To access a Zarr or N5 containers, the path to the root container
        must end with .zarr or .n5

        For reading .zarr or n5 containers, this function dispatches to `zarr.open`

        For reading .dat files (Janelia-native binary image format), this function uses
        routines found in `fibsem_tools.io.fibsem`

        If `path` is a collection of strings, it is assumed that each element of the
        collection represents a path, and this function will return the result of
        calling itself on each element of the collection.

    Additional kwargs are passed to the format-specific access function.

    Returns
    -------
    An array-like object or a group-like object
    zarr.hierarchy.Group

    """
    return access(path, mode="r", **kwargs)

def read_dask(
    path: PathLike,
    chunks: Union[Literal["auto"], Tuple[int, ...]] = "auto",
    **kwargs: Any,
) -> da.Array:
    """
    Create a dask array from a uri
    """
    _, _, suffix = split_by_suffix(path, _suffixes)
    if suffix in (".zarr", ".n5"):
        dasker = fibsem_tools.io.zarr.to_dask
    elif suffix == ".mrc":
        dasker = fibsem_tools.io.mrc.to_dask
    elif suffix == ".dat":
        dasker = fibsem_tools.io.dat.to_dask
    else:
        raise ValueError(
            f"""
                Cannot access file with extension {suffix} as a dask array. Extensions
                with dask support are (".zarr", ".n5", ".mrc", and ".dat")
                """
        )
    return dasker(read(path, **kwargs), chunks)

def read_xarray(
    path: PathLike,
    chunks: Union[Literal["auto"], Tuple[int, ...]] = "auto",
    coords: Any = "auto",
    use_dask: bool = True,
    attrs: Dict[str, Any] | None = None,
    name: str | None = None,
    **kwargs: Any,
) -> DataArray | DataTree:
    _, _, suffix = split_by_suffix(path, _suffixes)
    element = read(path, **kwargs)
    if suffix in (".zarr", ".n5"):
        return fibsem_tools.io.zarr.to_xarray(
            element,
            chunks=chunks,
            coords=coords,
            use_dask=use_dask,
            attrs=attrs,
            name=name,
        )
    elif suffix == ".mrc":
        # todo: support datatree semantics for mrc files, maybe by considering a folder
        # group?
        return fibsem_tools.io.mrc.to_xarray(
            element,
            chunks=chunks,
            coords=coords,
            use_dask=use_dask,
            attrs=attrs,
            name=name,
        )
    else:
        raise ValueError(
            f"""
        Xarray data structures are only supported for data saved as zarr, n5, and mrc.
        Got {type(element)}, which is not supported.
        """
        )

def create_group(
    group_url: PathLike,
    arrays: Iterable[NDArray[Any]],
    array_paths: Iterable[str],
    chunks: Sequence[int],
    group_attrs: Attrs = {},
    array_attrs: Sequence[Attrs] | None = None,
    group_mode: AccessMode = "w-",
    array_mode: AccessMode = "w-",
    **array_kwargs: Any,
) -> GroupLike:
    _arrays = tuple(a for a in arrays)
    _array_paths = tuple(p for p in array_paths)

    bad_paths = []
    for path in _array_paths:
        if len(Path(path).parts) > 1:
            bad_paths.append(path)

    if len(bad_paths):
        raise ValueError(
            f"""
            Array paths cannot be nested. The following paths violate this rule:
            {bad_paths}
            """
        )

    group = access(group_url, mode=group_mode, attrs=group_attrs)
    a_urls = [os.path.join(group_url, name) for name in _array_paths]

    if array_attrs is None:
        _array_attrs: Tuple[Attrs, ...] = ({},) * len(_arrays)
    else:
        _array_attrs = array_attrs

    for idx, vals in enumerate(zip(_arrays, a_urls, _array_attrs)):
        array, path, attrs = vals
        access(
            path=path,
            mode=array_mode,
            shape=array.shape,
            dtype=array.dtype,
            chunks=chunks[idx],
            attrs=attrs,
            **array_kwargs,
        )

    return group


import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

w = 0.1
b = 0.3

# x_data = np.random.rand(100).astype(np.float32)
x_data = np.linspace(-1, 1, num=100).astype(np.float32)
y_data = w * x_data + b

# "tf.zeros([1])" is same as "tf.zeros(1)"
est_w = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
est_b = tf.Variable(tf.zeros([1]))
est_y = est_w * x_data + est_b

# "reduce" means "reduce of tensor_rank."
loss = tf.reduce_mean(tf.square(est_y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)

# All of tensorflow-variables must be initialized.
init = tf.global_variables_initializer()

# "with" syntax can automatically close.
# sess = tf.Session()
# sess.run(init)
# (something disposal)
# sess.close()
with tf.Session() as sess:
    sess.run(init)
    for step in range(100):
        sess.run(train)
        # if step % 20 == 0:
        print(step, sess.run(est_w), sess.run(est_b))
        plt.scatter(step, sess.run(loss), c='black', s=10)

plt.show()


VERSION_YEAR = 2019
VERSION_MONTH = 8
VERSION_DAY = 3
VERSION_REV = 0

whos_in = None
twitter = None
users = {}
twilio_client = None
ARGS = {}
smmry_api_key = None
pubg_api_key = None
pubg_api = None

# Variable hold trumps last tweet id
last_id = 0
trump_chance_roll_rdy = False

# Runtime stats
duels_conducted = 0
items_awarded = 0
trump_tweets_seen = 0
missed_trumps = 0
first = True

# Shot_duel acceptance and active
accepted = False
shot_duel_running = False
vict_name = ""

# News handles to pull from
news_handles = ['mashable', 'cnnbrk', 'whitehouse', 'cnn', 'nytimes',
                'foxnews', 'reuters', 'npr', 'usatoday', 'cbsnews',
                'abc', 'washingtonpost', 'msnbc', 'ap', 'aphealthscience',
                'lifehacker', 'cnnnewsroom', 'theonion']

# Delays for Newsfeed and Check_trump, These are in minutes
# remember that news_del is fuzzed + (0-10)
trump_del = 25
news_del = 55

# Location of db.json and tokens.config
data_dir = "/data"

# Create/Load Local Database
db_file = '{}/db.json'.format(data_dir)
db = {}

# Global toggle for news feed
NEWS_FEED_ON = False
NEWS_FEED_CREATED = False

async def trigger_social(ctx):
    """Triggers a social """
    for m in ctx.bot.get_all_members():
        if m.display_name != 'brochat-bot' and m.status == 'online':
            add_drink(m.display_name)
    glass = ":tumbler_glass:"
    await ctx.bot.say("Ah shit that's three in a row! ITS A SOCIAL! SHOTS! "
                      "SHOTS! SHOTS!\n{}{}{}".format(glass, glass, glass))

def add_drink(user):
    """
    Adds a drink for the user.
    :param user: users display name
    :return:
    """

    if user not in users:
        users[user] = {}

    if "drinks_owed" in users[user]:
        users[user]['drinks_owed'] += 1
    else:
        users[user]['drinks_owed'] = 1

    return users[user]['drinks_owed']


# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import h5py
import random
import glob
from sklearn.model_selection import StratifiedKFold
import os
from ushuffle import Shuffler, shuffle
import pdb

"""
sequence to matrix
"""

class GeneRateOneHotMatrix():

    def __init__(self):

        self.OriSeq = None
        self.Seqlabel = None
        self.SeqMatrix = None
        self.TrainX = None
        self.TestX = None
        self.TrainY = None
        self.TestY = None
        self.TrainID = None
        self.TestID = None
        self.Trainlist = []
        self.Testlist = []
        self.seq_pos_matrix_out = None

    def mkdir(self, path):
        """
        :param path:
        :return:
        """
        isExists = os.path.exists(path)
        if not isExists:
            os.makedirs(path)
            return (True)
        else:
            return False

    def seq_to_matrix(self,seq, seq_matrix, seq_order):
        '''
        change target 3D tensor according to sequence and order
        :param seq: Input single root sequence
        :param seq_matrix: Input initialized matrix
        :param seq_order: This is the first sequence
        :return:
        '''
        for i in range(len(seq)):
            if ((seq[i] == 'A') | (seq[i] == 'a')):
                seq_matrix[seq_order, i, 0] = 1
            if ((seq[i] == 'C') | (seq[i] == 'c')):
                seq_matrix[seq_order, i, 1] = 1
            if ((seq[i] == 'G') | (seq[i] == 'g')):
                seq_matrix[seq_order, i, 2] = 1
            if ((seq[i] == 'T') | (seq[i] == 't')):
                seq_matrix[seq_order, i, 3] = 1
        return seq_matrix

    def genarate_matrix_for_train(self, seq_shape, seq_series):
        """
        generate a large matrix composed of sequences.
        :param shape: (seq number, sequence_length, 4)
        :param seq_series: A file in dataframe format composed of seq
        :return:seq
        """
        seq_matrix = np.zeros(seq_shape)
        for i in range(seq_series.shape[0]):
            seq_tem = seq_series[i]
            seq_matrix = self.seq_to_matrix(seq_tem, seq_matrix, i)
        return seq_matrix

    def cross_validation(self, number_of_folds, total_number, random_seeds=233):
        """
        This function is used to generate the index of n-fold cross validation
        :param number_of_folds:
        :param total_number:
        :param random_seeds:
        :return:
        """
        x = np.zeros((total_number,), dtype=np.int)
        split_iterator = StratifiedKFold(n_splits=number_of_folds, random_state=random_seeds, shuffle=True)
        split_train_index_and_test_index_list = [
            (train_index, test_index)
            for train_index, test_index in split_iterator.split(x, x)
            ]
        return (split_train_index_and_test_index_list)

    def split_dataset(self, split_index_list, fold, data_x, data_y, data_id=None):
        """
        Return training set and test set as needed
        :param split_index_list:Index of each fold returned by cross_validation
        :param fold:
        :param data_id:
        :param data_x:X
        :param data_y:Y
        :return:
        """
        id_train = data_id[split_index_list[fold][0].tolist()]
        x_train = data_x[split_index_list[fold][0].tolist()]
        y_train = data_y[split_index_list[fold][0].tolist()]
        id_test = data_id[split_index_list[fold][1].tolist()]
        x_test = data_x[split_index_list[fold][1].tolist()]
        y_test = data_y[split_index_list[fold][1].tolist()]
        return [x_train, y_train, id_train, x_test, y_test, id_test]

    def StoreTrainSet(self, rootPath):
        """
        Store multi-fold  data
        :param rootPath:
        :param ValNum: Generate valNum different validation data sets
        :param RandomSeeds:
        :param allData:
        :return:
        """
        self.mkdir(rootPath)
        training_path = rootPath + "/training_set.hdf5"
        test_path = rootPath + "/test_set.hdf5"

        f_train = h5py.File(training_path)
        f_test = h5py.File(test_path)

        f_train.create_dataset("sequences", data=self.TrainX)
        f_train.create_dataset("labs", data=self.TrainY)
        f_train.create_dataset("seq_idx", data=self.TrainID)
        f_train.close()
        f_test.create_dataset("sequences", data=self.TestX)
        f_test.create_dataset("labs", data=self.TestY)
        f_test.create_dataset("seq_idx", data=self.TestID)
        f_test.close()

    def k_mer_shuffle(self,seq_shape, seq_series, k=2):
        """
        Return a shuffled negative matrix
        :param seq_series:sequence list
        :param seq_shape:
        :param k:kshuffle
        :return:
        """
        seq_shuffle_matrix = np.zeros(seq_shape)

        for i in range(seq_shape[0]):
            seq = seq_series[i]
            shuffler = Shuffler(seq, k)
            seqres = shuffler.shuffle()
            seq_shuffle_matrix = self.seq_to_matrix(seqres, seq_shuffle_matrix, i)

        return seq_shuffle_matrix

    def runSeveral(self, SeqPath, OutputDir, SaveData=False):
        """
        Call this function to directly generate data, seq format requirements, odd-numbered lines are names,
        even-numbered lines are corresponding sequences
        :return:
        """
        allFileFaList = glob.glob(SeqPath)
        for allFileFa in allFileFaList:
            AllTem = allFileFa.split("/")[-1].split(".")[0]
            output_dir = OutputDir + AllTem + "/"
            SeqLen = 0
            ChipSeqlFileFa = pd.read_csv(allFileFa, sep='\t', header=None, index_col=None)
            seq_positive_series = np.asarray(ChipSeqlFileFa[1::2]).reshape(np.asarray(ChipSeqlFileFa[1::2]).shape[0], )
            seq_positive_shape = seq_positive_series.shape[0]
            for i in range(seq_positive_shape):
                SeqLen = max(SeqLen, len(seq_positive_series[i]))
            seq_positive_name = np.asarray(ChipSeqlFileFa[::2]).reshape(seq_positive_shape, )

            self.seq_pos_matrix_out = self.genarate_matrix_for_train((seq_positive_shape, SeqLen, 4),
                                                           seq_positive_series)
            seq_pos_label_out = np.ones(seq_positive_shape, )

            seq_negative_name = seq_positive_name
            seq_neg_matrix_out = self.k_mer_shuffle((seq_positive_shape, SeqLen, 4), seq_positive_series)
            seq_neg_label_out = np.zeros(seq_positive_shape, )

            seq = np.concatenate((self.seq_pos_matrix_out, seq_neg_matrix_out), axis=0)
            label = np.concatenate((seq_pos_label_out, seq_neg_label_out), axis=0)
            id_tem = np.concatenate((seq_positive_name, seq_negative_name), axis=0)
            index_shuffle = range(seq_positive_shape + seq_positive_shape)
            random.shuffle(index_shuffle)
            seq_matrix_out = seq[index_shuffle, :, :]
            label_out = label[index_shuffle]
            id_out = id_tem[index_shuffle].astype("string_")
            outData = [seq_matrix_out, label_out, id_out]
            self.GeneRateTrain(allData=outData, ValNum=10, RandomSeeds=233)
            if SaveData:
                self.StoreTrainSet(rootPath=output_dir)

    def GeneRateTrain(self, allData, ValNum=10, RandomSeeds=233):
        """

        """
        dataNum = allData[1].shape[0]
        split_train_index_and_test_index_list = self.cross_validation(number_of_folds=ValNum, total_number=dataNum,
                                                                 random_seeds=RandomSeeds)
        i = 0
        outDataTem = self.split_dataset(split_train_index_and_test_index_list, fold=i, data_x=allData[0], data_y=allData[1],
                                   data_id=allData[2])

        self.TrainX = outDataTem[0]
        self.TestX = outDataTem[3]
        self.TrainY = outDataTem[1]
        self.TestY = outDataTem[4]
        self.TrainID = outDataTem[2]
        self.TestID = outDataTem[5]

    def runSimple(self, SeqPath, OutputDir, SaveData=False):
        """
        Call this function to directly generate data, here is a separate data set, including Training and test
        seq format requirements, odd-numbered lines are names, even-numbered lines are corresponding sequences
        :return:
        """
        SeqLen = 0
        ChipSeqlFileFa = pd.read_csv(SeqPath, sep='\t', header=None, index_col=None)
        self.OriSeq = np.asarray(ChipSeqlFileFa[1::2]).reshape(np.asarray(ChipSeqlFileFa[1::2]).shape[0], )
        seq_positive_shape = self.OriSeq.shape[0]
        for i in range(seq_positive_shape):
            SeqLen = max(SeqLen, len(self.OriSeq[i]))
        seq_positive_name = np.asarray(ChipSeqlFileFa[::2]).reshape(seq_positive_shape, )

        self.seq_pos_matrix_out = self.genarate_matrix_for_train((seq_positive_shape, SeqLen, 4),
                                                       self.OriSeq)
        seq_pos_label_out = np.ones(seq_positive_shape, )

        seq_negative_name = seq_positive_name
        seq_neg_matrix_out = self.k_mer_shuffle((seq_positive_shape, SeqLen, 4), self.OriSeq)
        seq_neg_label_out = np.zeros(seq_positive_shape, )

        seq = np.concatenate((self.seq_pos_matrix_out, seq_neg_matrix_out), axis=0)
        label = np.concatenate((seq_pos_label_out, seq_neg_label_out), axis=0)
        id_tem = np.concatenate((seq_positive_name, seq_negative_name), axis=0)
        index_shuffle = range(seq_positive_shape + seq_positive_shape)
        random.shuffle(index_shuffle)
        self.SeqMatrix = seq[index_shuffle, :, :]
        self.Seqlabel = label[index_shuffle]
        id_out = id_tem[index_shuffle].astype("string_")
        outData = [self.SeqMatrix, self.Seqlabel, id_out]
        self.GeneRateTrain(allData=outData, ValNum=10, RandomSeeds=233)
        if SaveData:
            self.StoreTrainSet(rootPath=OutputDir)

if __name__ == '__main__':
    base = {0:"A",1:"C",2:"G",3:"T"}
    allFileFaList = glob.glob("./chip-seqFa/*fa")
    OutputDir = "./chip-seqFa/TrainingData/"
    GeneRateOneHotMatrixTest = GeneRateOneHotMatrix()

    GeneRateOneHotMatrixTest.runSeveral("./chip-seqFa/*fa", OutputDir, SaveData=True)

    GeneRateOneHotMatrixTest.runSimple(allFileFaList[0], OutputDir, SaveData=True)


#!/usr/bin/python3
import os
import subprocess
import sys
import time

image = sys.argv[1]

def clean():
    os.system("docker rm -f test &> /dev/null");

def success():
    clean()
    sys.exit(0)

def fail(message):
    print(message)
    clean()
    sys.exit(1)

clean()
os.system("docker run -d -p 80:80 --name test " + image + "");

# Check if php is working
result = subprocess.getstatusoutput("docker exec test php -r 'echo \"Hello World!\";'")
if result[1] != "Hello World!":
    fail("PHP CLI do not work")

# Check if Apache is working
time_limit = 10
while True:
    os.system("docker exec test bash -c 'echo \"<?php echo \\\"Hello World!\\\"; \" > /var/www/html/index.php'");
    result = subprocess.getstatusoutput("curl -sS 127.0.0.1:80")

    if result[1].strip() != "Hello World!":
        break

    if time_limit == 0:
        fail("Apache do not work")

    time_limit -= 1
    time.sleep(1)

success()


# -*- coding: utf-8 -*-
import os

# Scrapy settings for review_crawler project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.html

BOT_NAME = 'review_crawler'

SPIDER_MODULES = ['review_crawler.spiders']
NEWSPIDER_MODULE = 'review_crawler.spiders'

DNS_TIMEOUT = 20
DOWNLOAD_TIMEOUT = 25

# most common user agents from:
# https://techblog.willshouse.com/2012/01/03/most-common-user-agents/
USER_AGENT_CHOICES = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/74.0.3729.169 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/79.0.3945.130 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/80.0.3987.122 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/80.0.3987.132 Safari/537.36',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) '
    'Version/13.0.5 Safari/605.1.15',
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
    'Chrome/80.0.3987.116 Safari/537.36',
]

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# generate proxy file with: python proxy_generator.py > proxies
ROTATING_PROXY_LIST_PATH = os.path.realpath(os.path.join(os.getcwd(), 'proxies'))

CSV_PATH_PRODUCTS = os.path.realpath(os.path.join(os.getcwd(), 'products.csv'))
CSV_PATH_REVIEWS = os.path.realpath(os.path.join(os.getcwd(), 'reviews.csv'))

# Configure maximum concurrent requests performed by Scrapy (default: 16)
# CONCURRENT_REQUESTS = 32

# Disable cookies (enabled by default)
COOKIES_ENABLED = False
HTTPCACHE_ENABLED = True  # should be true in debug only\

AUTOTHROTTLE_ENABLED = True
AUTOTHROTTLE_START_DELAY = 2
AUTOTHROTTLE_TARGET_CONCURRENCY = 3
AUTOTHROTTLE_DEBUG = True
CONCURRENT_REQUESTS = 3
DOWNLOAD_DELAY = 4
# CONCURRENT_REQUESTS_PER_IP = 16

# Disable Telnet Console (enabled by default)
TELNETCONSOLE_ENABLED = False

# Override the default request headers:
# DEFAULT_REQUEST_HEADERS = {
#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
#   'Accept-Language': 'en',
# }

# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
# SPIDER_MIDDLEWARES = {
#    'review_crawler.middlewares.ReviewCrawlerSpiderMiddleware': 543,
# }

ROTATING_PROXY_PAGE_RETRY_TIMES = 150

# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
    'rotating_proxies.middlewares.RotatingProxyMiddleware': 610,
    'review_crawler.middlewares.RotateUserAgentMiddleware': 110,
    'rotating_proxies.middlewares.BanDetectionMiddleware': 620,
    'review_crawler.middlewares.ReviewCrawlerDownloaderMiddleware': 543,
}

DATABASE = {
    'drivername': 'postgres',
    'host': '',
    'port': '5432',
    'username': 'bogo',
    'password': '',
    'database': 'review_crawler'
}

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'review_crawler.pipelines.ReviewCrawlerPipeline': 300,
   'review_crawler.pipelines.WriteToCsv': 301,
   'review_crawler.pipelines.PostgresPipeline': 302,
}

# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
# EXTENSIONS = {
#    'scrapy.extensions.telnet.TelnetConsole': None,
# }

# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
# HTTPCACHE_ENABLED = True
# HTTPCACHE_EXPIRATION_SECS = 0
# HTTPCACHE_DIR = 'httpcache'
# HTTPCACHE_IGNORE_HTTP_CODES = []
# HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'


"""
Funciones basicas del Framework
"""

import os
import pathlib

import pytest

from utils import driver_config
from utils.driver_config import get_driver_instance, quit_driver, init_driver

def pytest_addoption(parser):
    parser.addoption('--env', action='store', default='test', help='select environments')
    parser.addoption('--role', action='store', default='', help='"ci" to used role based auth')

    parser.addoption('--browser', action='store', default='none',
                     help="supported browser: chrome, firefox, appium, browserstack")
    parser.addoption('--headless', action='store', default='none', help='true/false to use or not headless mode')
    parser.addoption('--maximized', action='store', default='none', help='true/false to maximize browser')
    parser.addoption('--device_name', action='store', default='none',
                     help='device name to execute using mobile emulation in Chrome')

    parser.addoption('--bs_browser', action='store', default='none', help='browser name to use on BrowserStack')
    parser.addoption('--bs_browser_version', action='store', default='none', help='browser version to use on BS')
    parser.addoption('--bs_os', action='store', default='none', help='OS to run test on BS')

    parser.addoption('--device', action='store', default='none', help='device name to use on BS for mobile browser')
    parser.addoption('--browserName', action='store', default='none', help='use android or ios to run tests on BS')

    parser.addoption('--os_version', action='store', default='none', help='for desktop or mobile execution on BS')

def pytest_configure(config):
    os.environ["env"] = config.getoption('env')
    os.environ["role"] = config.getoption('role')

    os.environ["browser"] = config.getoption('browser')
    os.environ["headless"] = config.getoption('headless')
    os.environ["maximized"] = config.getoption('maximized')
    os.environ["device_name"] = config.getoption('device_name')

    os.environ["bs_browser"] = config.getoption('bs_browser')
    os.environ["bs_browser_version"] = config.getoption('bs_browser_version')
    os.environ["bs_os"] = config.getoption('bs_os')

    os.environ["device"] = config.getoption('device')
    os.environ["browserName"] = config.getoption('browserName')

    os.environ["os_version"] = config.getoption('os_version')

    driver_config.set_driver_type()

@pytest.fixture
def driver():
    # Init driver
    init_driver()
    # Get current driver instance
    yield get_driver_instance()
    # For cleanup, quit the driver
    quit_driver()

@pytest.mark.hookwrapper
def pytest_runtest_makereport(item):
    """
    Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails.
    :param item:
    """
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, 'extra', [])

    if report.when == 'call' or report.when == "setup":
        xfail = hasattr(report, 'wasxfail')
        if (report.skipped and xfail) or (report.failed and not xfail):
            method_name = report.nodeid.split('/')
            method_name = method_name[len(method_name) - 1].replace("::", "_") + ".png"
            file_path = str(pathlib.Path(__file__).parent) + '/report/images/' + method_name
            _capture_screenshot(file_path)
            file_name = 'images/' + method_name
            if file_path:
                html = f'

'
                extra.append(pytest_html.extras.html(html))
        report.extra = extra

def _capture_screenshot(name):
    try:
        get_driver_instance().get_screenshot_as_file(name)
    except:
        pass

def pytest_runtest_setup(item):
    if "incremental" in item.keywords:
        previousfailed = getattr(item.parent, "_previousfailed", None)
        if previousfailed is not None:
            pytest.xfail("previous test failed ({})".format(previousfailed.name))


import urllib.request
from bs4 import BeautifulSoup
import time
from newspaper import Article
import nltk
import sqlite3
from sqlite3 import Error
import re
import pandas as pd
from urllib.request import build_opener, HTTPCookieProcessor

#it is used to search words
def find_word(soup1):
    search=['surge','acquisitions','IPO','coronavirus','covid-19']
    for i in search:
        result=re.findall('\\b'+i+'\\b',soup1.text,flags=re.IGNORECASE)
        if len(result)>0:
            print(f"{i} found in news")
            return;

# it is used to establish a sqllite connection
def sql_connection():
    try:
        con=sqlite3.connect('mydatabase10.db') # it is used to connect to  a data base i.e mydatabase.db file
        # this file is created on disk . if we want to create the db on ram then we have to use connect(:memory)
        print("connection is established...")
        return con
    except Error:
        print("Error!")

# it is used to create a table
def sql_create_table(con,tname):
    try:
        mcur=con.cursor() # it gives the cursor object that is used to execute the sqlite statemsnts
        mcur.execute(f"CREATE TABLE {tname}(title text PRIMARY KEY,summary text,publishdate text)")
        con.commit()
        # in order to drop the table just write DROP TABLE tablename inside execute.
    except Error:
        print("Error!")

# it used to insert data into the table
def sql_insert(con,entities,tname):
    try:
        mcur=con.cursor() # it gives the cursor object that is used to execute the sqlite statemsnts
        mcur.execute(f"INSERT INTO {tname}(title,summary,publishdate)VALUES(?,?,?)",entities)
        con.commit()
    except Error:
        print("Error!")

# it used to extract data from the table and display it also checks for exact word
def sql_select(con,tname):
    try:
        df=pd.read_sql_query(f"select * from {tname} limit 5;",con)
        print(df)
    except Error:
        print("Error!")

count=1 # number of news to be taken from the page. I have taken 2 news.
nltk.download('punkt')
rcon=sql_connection()
sql_create_table(rcon,"main_news")
sql_create_table(rcon,"sub_news")

url='https://news.google.com/' #url of the web page

page=urllib.request.Request(url,headers={'User-Agent':'Mozilla/5.0'})
pdata=urllib.request.urlopen(page).read()

soup=BeautifulSoup(pdata,'lxml')

main=soup.find("main",{"class":"HKt8rc CGNRMc"})
main_news=main.find_all("h3",{"class":"ipQwMb ekueJc gEATFF RD0gLb"})
sub_news=main.find_all("h4",{"class":"ipQwMb ekueJc gEATFF RD0gLb"})

murl='https://news.google.com'

print("<<............................................Main News Collecting...................................................>>")
for j in main_news:
    if count<=5:
        i=j.find("a",href=True)
        l=i['href'].split('.')
        lnk=murl+l[1]
        try:
            page1=urllib.request.Request(lnk,headers={'User-Agent':'Mozilla/5.0'})
            pdata1=urllib.request.urlopen(page1).read()
            soup1=BeautifulSoup(pdata1,'lxml')
            find_word(soup1)

            myarticle=Article(lnk,language='en')
            time.sleep(3)
            myarticle.download()
            myarticle.parse()
            myarticle.nlp()

            entities=(myarticle.title,myarticle.summary,myarticle.publish_date)
            sql_insert(rcon,entities,"main_news")
        except Exception as e:
            print("")

        count=count+1
        time.sleep(5)

print("<<............................................Sub News Collecting...................................................>>")
for j in sub_news:
    if count>1:
        i=j.find("a",href=True)
        l=i['href'].split('.')
        lnk=murl+l[1]
        try:
            page1=urllib.request.Request(lnk,headers={'User-Agent':'Mozilla/5.0'})
            pdata1=urllib.request.urlopen(page1).read()
            soup1=BeautifulSoup(pdata1,'lxml')
            find_word(soup1)

            myarticle=Article(lnk,language='en')
            time.sleep(3)
            myarticle.download()
            myarticle.parse()
            myarticle.nlp()

            entities=(myarticle.title,myarticle.summary,myarticle.publish_date)
            sql_insert(rcon,entities,"sub_news")
        except Exception as e:
            print("")

        count=count-1
        time.sleep(10)

sql_select(rcon,"main_news")
sql_select(rcon,"sub_news")


__author__ = "V.A. Sole - ESRF"
__contact__ = "sole@esrf.fr"
__license__ = "MIT"
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
import sys
import time
import numpy
import logging
from PyMca5.PyMcaGui import PyMcaQt as qt
from PyMca5.PyMcaGui.misc import CalculationThread

try:
    from . import PCAWindow
    PCA = True
    MDP = PCAWindow.MDP
except ImportError:
    PCA = False
    MDP = False

_logger = logging.getLogger(__name__)

class PCADialog(qt.QDialog):
    def __init__(self, parent=None, rgbwidget=None, selection=False):
        qt.QDialog.__init__(self, parent)
        self.setWindowTitle("PCA calculation dialog")
        self.mainLayout = qt.QVBoxLayout(self)
        self.calculateButton = qt.QPushButton(self)
        self.calculateButton.setAutoDefault(False)
        self.calculateButton.setText("Perform PCA")
        self.showLastButton = qt.QPushButton(self)
        self.showLastButton.setAutoDefault(False)
        self.showLastButton.setText("Last Results")
        self.mainLayout.addWidget(self.calculateButton)
        self.mainLayout.addWidget(self.showLastButton)
        self._data = None
        self.pcaWindow = PCAWindow.PCAWindow(parent=None,
                                             rgbwidget=rgbwidget,
                                             #selection=True,
                                             selection=selection,
                                             colormap=True,
                                             #imageicons=True,
                                             imageicons=selection,
                                             standalonesave=True)
        self.pcaWindow.setDefaultColormap(0, logflag=False)
        self.pcaParametersDialog = PCAWindow.PCAParametersDialog(self)
        self.pcaParametersDialog.nPC.setMaximum(11)
        self.pcaParametersDialog.nPC.setValue(10)
        self.pcaParametersDialog.hide()
        self.pcaParametersDialogInitialized = False
        self.pcaWindow.hide()

        #connections
        self.calculateButton.clicked.connect(self._calculateSlot)
        self.showLastButton.clicked.connect(self._showLastSlot)

    def sizeHint(self):
        return qt.QSize(int(4 * qt.QDialog.sizeHint(self).width()),
                        qt.QDialog.sizeHint(self).height())

    def _calculateSlot(self):
        if self._data is None:
            msg = qt.QMessageBox(self)
            msg.setWindowTitle("No data")
            msg.setIcon(qt.QMessageBox.Information)
            msg.setText("No data to perform calculation")
            msg.exec()
            return

        if not self.pcaParametersDialogInitialized:
            self.pcaParametersDialog.nPC.setMaximum(self._spectrumLength)
            self.pcaParametersDialog.nPC.setValue(
                min(10, self._spectrumLength))
            ddict = {'options': self._binningOptions,
                     'binning': 1,
                     'method': 0}
            self.pcaParametersDialog.setParameters(ddict)
            self.pcaParametersDialogInitialized = True
        ret = self.pcaParametersDialog.exec()
        if ret:
            t0 = time.time()
            pcaParameters = self.pcaParametersDialog.getParameters()
            self.pcaParametersDialog.close()
            function = pcaParameters['function']
            binning = pcaParameters['binning']
            npc = pcaParameters['npc']
            mask = pcaParameters.get('mask', None)
            kw = pcaParameters.get('kw', {})
            data = self._data
            old_shape = self._data.shape
            if mask is not None:
                if mask.sum() < npc:
                    msg = qt.QMessageBox(self)
                    msg.setWindowTitle("Not enough data")
                    msg.setIcon(qt.QMessageBox.Information)
                    msg.setText("Number of components too high")
                    msg.exec()
                    return
            if _logger.getEffectiveLevel() == logging.DEBUG:
                images, eigenvalues, eigenvectors = function(data,
                                                             npc,
                                                             binning=binning,
                                                             mask=mask,
                                                             **kw)
            else:
                try:
                    threadResult = self._submitThread(function,
                                                         data,
                                                         npc,
                                                         binning=binning,
                                                         mask=mask,
                                                         **kw)
                    if type(threadResult) == type((1,)):
                        if len(threadResult):
                            if hasattr(threadResult[0], "startswith"):
                                if threadResult[0].startswith("Exception"):
                                    raise Exception(threadResult[1],
                                                threadResult[2])
                    images, eigenvalues, eigenvectors = threadResult
                except Exception:
                    if isinstance(data, numpy.ndarray):
                        self._data.shape = old_shape
                    msg = qt.QMessageBox(self)
                    msg.setIcon(qt.QMessageBox.Critical)
                    msg.setText("%s" % sys.exc_info()[1])
                    msg.exec()
                    return
            if isinstance(self._data, numpy.ndarray):
                self._data.shape = old_shape
            _logger.debug("PCA Elapsed = %s", time.time() - t0)
            methodlabel = pcaParameters.get('methodlabel', "")
            imagenames = None
            vectornames = None
            if " ICA " in methodlabel:
                nimages = images.shape[0]
                imagenames = []
                vectornames = []
                itmp = int(nimages / 2)
                for i in range(itmp):
                    imagenames.append("ICAimage %02d" % i)
                    vectornames.append("ICAvector %02d" % i)
                for i in range(itmp):
                    imagenames.append("Eigenimage %02d" % i)
                    vectornames.append("Eigenvector %02d" % i)
            self.pcaWindow.setPCAData(images,
                                      eigenvalues,
                                      eigenvectors,
                                      imagenames=imagenames,
                                      vectornames=vectornames)
            self.pcaWindow.show()
            self.pcaWindow.raise_()

    def _showLastSlot(self):
        self.pcaWindow.show()
        self.pcaWindow.raise_()

    def setData(self, data=None, spectrumindex=-1):
        if type(data) == type([]):
            #assume is an image list
            if data[0].dtype not in [numpy.float32, numpy.float64]:
                dtype = numpy.float64
            else:
                dtype = data[0].dtype
            self._spectrumLength = len(data)
            self._shape = data[0].shape
            n = 1
            for shape in self._shape:
                n *= shape
            self._binningOptions = [1]
            if len(self._shape) == 1:
                self._data = numpy.zeros((self._shape[0],
                                          self._spectrumLength), dtype)
                for i in range(self._spectrumLength):
                    self._data[:, i] = data[i][:]
            elif len(self._shape) == 2:
                self._data = numpy.zeros((self._shape[0],
                                          self._shape[1],
                                          self._spectrumLength), dtype)
                for i in range(self._spectrumLength):
                    self._data[:, :, i] = data[i][:, :]
        else:
            self._shape = data.shape
            self._data = data
            self._spectrumLength = self._shape[spectrumindex]
            self._binningOptions = [1]
            for number in [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19]:
                if (self._spectrumLength % number) == 0:
                    self._binningOptions.append(number)
        if self.pcaParametersDialog is not None:
            value = self.pcaParametersDialog.nPC.value()
            self.pcaParametersDialog.nPC.setMaximum(self._spectrumLength)
            self.pcaParametersDialog.nPC.setValue(min(value,
                                                      self._spectrumLength))

    def setSpectrum(self, x, y, legend=None):
        return self.pcaParametersDialog.setSpectrum(x, y, legend=legend)

    def _submitThread(self, function, *var, **kw):
        message = "Please Wait: PCA Going On"
        thread = CalculationThread.CalculationThread(
                                      calculation_method=function,
                                      calculation_vars = var,
                                      calculation_kw = kw,
                                      expand_vars=True,
                                      expand_kw=True)
        thread.start()
        CalculationThread.waitingMessageDialog(thread,
                                              message=message,
                                              parent=self,
                                              modal=True,
                                              update_callback=None,
                                              frameless=True)
        threadResult = thread.getResult()
        self.raise_()
        return threadResult

if __name__ == "__main__":
    _logger.setLevel(logging.DEBUG)
    import os
    from PyMca5.PyMcaIO import EdfFile
    app = qt.QApplication([])
    app.lastWindowClosed.connect(app.quit)
    d = PCADialog()
    if len(sys.argv) < 2:
        fileList = [r"D:\DATA\ICA\mix1.edf",
                    r"D:\DATA\ICA\mix2.edf",
                    r"D:\DATA\ICA\mix3.edf"]
    else:
        fileList = []
        for i in range(1, len(sys.argv)):
            fileList.append(sys.argv[i])
    imageList = []
    for fname in fileList:
        print(fname)
        if not os.path.exists(fname):
            print("File name %s does not exists" % fname)
            break
        edf = EdfFile.EdfFile(fname)
        data = edf.GetData(0)
        edf = None
        imageList.append(data)
    if len(imageList):
        d.setData(imageList)
    d.show()
    app.exec()


import logging
import os
import json
import discord
from discord.utils import find
from discord.ext import commands

# logger stuff yeah
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.INFO)
LOGGER_HANDLER = logging.FileHandler(
    filename="logs/{}.log".format(__name__), encoding='utf-8', mode='w')
LOGGER_HANDLER.setFormatter(logging.Formatter(
    '%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
LOGGER.addHandler(LOGGER_HANDLER)

thingy = os.path.dirname(os.path.abspath(__file__))
nagisa = os.path.join(thingy, "../config/taiga.json")

with open(nagisa) as file:
    data = json.load(file)
    role_name = data["stream_role"]

# really messy

class OnStream:
    def __init__(self, bot):
        self.bot = bot

    async def on_member_update(self, before, after):
        guild = after.guild
        channel = guild.default_channel
        role = find(lambda m: m.name == role_name, guild.roles)
        mention = after.mention
        if role is None:
            try:
                await guild.create_role(name=role_name,
                                        hoist=True,
                                        colour=discord.Colour.purple())
                role = find(lambda m: m.name == role_name, guild.roles)
            except:
                pass
        try:
            if after.game.type == 1:
                em = discord.Embed(title="Stream Notification",
                                   description="{} is now streaming!".format(
                                       mention),
                                   colour=discord.Colour.purple())
                em.add_field(name="URL:", value=after.game.url)
        except:
            pass

        if after.game is not None:
            game_type = after.game.type
        else:
            game_type = 0

        if before.game is not None:
            before_game_type = before.game.type
        else:
            before_game_type = 0

        if game_type == 1 and role not in after.roles and before_game_type != 1:
            try:
                await channel.send(embed=em)
                await after.add_roles(role)
            except discord.Forbidden as exc:
                error = "{} has thrown an exception:\n{}".format(__name__, exc)
                msg = "Probably not enough permissions."
                LOGGER.error(error)
                LOGGER.error(msg)
                print(error)
                print(msg)
        elif game_type != 1 and role in after.roles and before_game_type == 1:
            await after.remove_roles(role)
            em2 = discord.Embed(title="Stream Notification",
                                description="{} is no longer streaming.".format(
                                    mention),
                                colour=discord.Colour.purple())
            await channel.send(embed=em2)

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


# find_and_replace
# Write a function called nd_and_replace, which takes in a file name, a word to search for, and a replacement word. Replaces all instances
# of the word in the file with the replacement word.

from pathlib import Path
data_folder = Path(
    "c:/Users/sixgg/Documents/GitHub/Python/Self-Learning/File IO/exercise/find_and_replace/")
filename = "story.txt"
file=data_folder / filename

def find_and_replace(og_file, old_word, new_word, file=file):
    with open(file, "r+") as f:  # opening file
        text = f.read()
        new_text = text.replace(old_word, new_word)
        f.seek(0)
        f.write(new_text)
        f.truncate()

find_and_replace('story.txt', 'Alice', 'Jose')


import sys

# 載入正負情緒字典檔
def load_dict_data(positive_dict_file, negative_dict_file):
    print("load data")
    p = []
    n = []
    with open(positive_dict_file, encoding="utf-8-sig") as f:
        for line in f:
            p.append(line.strip())
    with open(negative_dict_file, encoding="utf-8-sig") as f:
        for line in f:
            n.append(line.strip())
    return p, n

# 計算詞頻
def count_words(p, n, data_string):
    p_count = {}
    n_count = {}
    for w in p:
        p_count[w] = data_string.count(w)
    for w in n:
        n_count[w] = data_string.count(w)
    return p_count, n_count

# 輸出結果至Excel檔
def output_results(p_count, n_count):
    with open("positive_count.csv", "w", encoding="utf-8-sig") as f:
        for k, v in p_count.items():
            f.write(f"{k},{v}\n")
    with open("negative_count.csv", "w", encoding="utf-8-sig") as f:
        for k, v in n_count.items():
            f.write(f"{k},{v}\n")

# 執行程式
if __name__ == "__main__":
    text_file = sys.argv[1]
    positive_dict_file = sys.argv[2]
    negative_dict_file = sys.argv[3]

    p, n = load_dict_data(positive_dict_file, negative_dict_file)
    data_string = open(text_file, encoding="utf-8-sig").read()
    p_count, n_count = count_words(p, n, data_string)
    output_results(p_count, n_count)


n=15
b=n
print(b)
s=0
while b>0:
    digit=b%10
    s=s+digit*digit*digit
    b=int(b/10)
if n==s:
    print(n,'is armstrong')
else:
    print(n,'is not armstrong')


# coding: utf-8
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from torch.autograd import Function, Variable

class EmbLoss_v1(nn.Module):
    def __init__(self, feature_dim=4, loss_weight=1.0):
        super(EmbLoss_v1, self).__init__()
        self.feature_dim = feature_dim
        self.loss_weight = loss_weight
        self.delta_v = 0.5
        self.delta_d = 1.5
        self.weights = (1.0, 1.0)

    def forward_single(self, emb, instance, kernel, training_mask, bboxes):
        training_mask = (training_mask > 0.5).long()
        kernel = (kernel > 0.5).long()
        instance = instance * training_mask
        instance_kernel = (instance * kernel).view(-1)
        instance = instance.view(-1)
        emb = emb.view(self.feature_dim, -1)

        unique_labels, unique_ids = torch.unique(instance_kernel, sorted=True, return_inverse=True)
        num_instance = unique_labels.size(0)
        if num_instance <= 1:
            return 0

        emb_mean = emb.new_zeros((self.feature_dim, num_instance), dtype=torch.float32)
        for i, lb in enumerate(unique_labels):
            if lb == 0:
                continue
            ind_k = instance_kernel == lb
            emb_mean[:, i] = torch.mean(emb[:, ind_k], dim=1)

        l_agg = emb.new_zeros(num_instance, dtype=torch.float32)  # bug
        for i, lb in enumerate(unique_labels):
            if lb == 0:
                continue
            ind = instance == lb
            emb_ = emb[:, ind]
            dist = (emb_ - emb_mean[:, i:i + 1]).norm(p=2, dim=0)
            dist = F.relu(dist - self.delta_v) ** 2
            l_agg[i] = torch.mean(torch.log(dist + 1.0))
        l_agg = torch.mean(l_agg[1:])

        if num_instance > 2:
            emb_interleave = emb_mean.permute(1, 0).repeat(num_instance, 1)
            emb_band = emb_mean.permute(1, 0).repeat(1, num_instance).view(-1, self.feature_dim)
            # print(seg_band)

            mask = (1 - torch.eye(num_instance, dtype=torch.int8)).view(-1, 1).repeat(1, self.feature_dim)
            mask = mask.view(num_instance, num_instance, -1)
            mask[0, :, :] = 0
            mask[:, 0, :] = 0
            mask = mask.view(num_instance * num_instance, -1)
            # print(mask)

            dist = emb_interleave - emb_band
            dist = dist[mask > 0].view(-1, self.feature_dim).norm(p=2, dim=1)
            dist = F.relu(2 * self.delta_d - dist) ** 2
            l_dis = torch.mean(torch.log(dist + 1.0))
        else:
            l_dis = 0

        l_agg = self.weights[0] * l_agg
        l_dis = self.weights[1] * l_dis
        l_reg = torch.mean(torch.log(torch.norm(emb_mean, 2, 0) + 1.0)) * 0.001
        loss = l_agg + l_dis + l_reg
        return loss

    def forward(self, emb, instance, kernel, training_mask, bboxes, reduce=True):
        loss_batch = emb.new_zeros((emb.size(0)), dtype=torch.float32)

        for i in range(loss_batch.size(0)):
            loss_batch[i] = self.forward_single(emb[i], instance[i], kernel[i], training_mask[i], bboxes[i])

        loss_batch = self.loss_weight * loss_batch

        if reduce:
            loss_batch = torch.mean(loss_batch)

        return loss_batch


from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import uic
from pathlib import Path

from data.user_input.project.printMessageInput import PrintMessageInput

window_title1 = "ERROR"
window_title2 = "WARNING"

class AcousticElementTypeInput(QDialog):
    def __init__(self, project, opv, *args, **kwargs):
        super().__init__(*args, **kwargs)

        uic.loadUi(Path('data/user_input/ui_files/Model/Setup/Acoustic/acousticElementTypeInput.ui'), self)

        icons_path = str(Path('data/icons/pulse.png'))
        self.icon = QIcon(icons_path)
        self.setWindowIcon(self.icon)

        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setWindowModality(Qt.WindowModal)

        self.opv = opv
        self.opv.setInputObject(self)
        self.lines_id = self.opv.getListPickedLines()

        self.project = project
        self.preprocessor = project.preprocessor
        self.before_run = project.get_pre_solution_model_checks()

        self.dict_tag_to_entity = project.preprocessor.dict_tag_to_entity
        self.comboBox_index = 0
        self.element_type = 'undamped'
        self.complete = False
        self.update_cross_section = False
        self.pipe_to_beam = False
        self.beam_to_pipe = False

        self.checkBox_flow_effects = self.findChild(QCheckBox, 'checkBox_flow_effects')
        self.checkBox_flow_effects.toggled.connect(self.checkBoxEvent_flow_effects)
        self.flow_effects = self.checkBox_flow_effects.isChecked()

        self.label_vol_flow = self.findChild(QLabel, 'label_vol_flow')
        self.lineEdit_vol_flow = self.findChild(QLineEdit, 'lineEdit_vol_flow')
        self.label_ms_unit = self.findChild(QLabel, 'label_ms_unit')

        self.lineEdit_selected_ID = self.findChild(QLineEdit, 'lineEdit_selected_ID')
        self.lineEdit_selected_group = self.findChild(QLineEdit, 'lineEdit_selected_group')
        self.lineEdit_selected_group.setDisabled(True)

        self.lineEdit_proportional_damping = self.findChild(QLineEdit, 'lineEdit_proportional_damping')

        self.comboBox = self.findChild(QComboBox, 'comboBox')
        self.comboBox.currentIndexChanged.connect(self.selectionChange)
        self.comboBox_index = self.comboBox.currentIndex()

        # index: 0 - Undamped
        # index: 1 - Proportional
        # index: 2 - Wide-duct
        # index: 3 - LRF fluid equivalent
        # index: 4 - LRF full

        self.radioButton_all = self.findChild(QRadioButton, 'radioButton_all')
        self.radioButton_selected_lines = self.findChild(QRadioButton, 'radioButton_selection')
        self.radioButton_all.toggled.connect(self.radioButtonEvent)
        self.radioButton_selected_lines.toggled.connect(self.radioButtonEvent)
        self.flagAll = self.radioButton_all.isChecked()
        self.flagSelection = self.radioButton_selected_lines.isChecked()

        self.treeWidget_element_type = self.findChild(QTreeWidget, 'treeWidget_element_type')
        self.treeWidget_element_type.setColumnWidth(0, 150)
        self.treeWidget_element_type.itemClicked.connect(self.on_click_item_line)

        self.tabWidget_general = self.findChild(QTabWidget, 'tabWidget_general')
        self.tabWidget_element_type = self.findChild(QTabWidget, 'tabWidget_element_type')
        # self.tabWidget_element_type.currentChanged.connect(self.tabWidget_etype)
        # self.tabWidget_element_type.setTabEnabled(1, False)

        self.tab_element_type = self.tabWidget_element_type.findChild(QWidget, "tab_element_type")
        self.tab_damping = self.tabWidget_element_type.findChild(QWidget, "tab_damping")

        # self.tabWidget_general.currentChanged.connect(self.tabEvent_)
        # self.currentTab_ = self.tabWidget_general.currentIndex()

        # self.pushButton_remove = self.findChild(QPushButton, 'pushButton_remove')
        # self.pushButton_remove.clicked.connect(self.group_remove)
        # self.pushButton_reset = self.findChild(QPushButton, 'pushButton_reset')
        # self.pushButton_reset.clicked.connect(self.reset_all)

        self.pushButton_get_information = self.findChild(QPushButton, 'pushButton_get_information')
        self.pushButton_get_information.clicked.connect(self.get_information)
        self.pushButton_confirm = self.findChild(QPushButton, 'pushButton_confirm')
        self.pushButton_confirm.clicked.connect(self.confirm_element_type_attribution)
        # self.pushButton_get_information.setDisabled(True)
        # self.pushButton_remove.setDisabled(True)

        self.update()
        self.selectionChange()

        self.load_element_type_info()
        self.exec()

    def write_ids(self, list_ids):
        text = ""
        for _id in list_ids:
            text += "{}, ".format(_id)
        self.lineEdit_selected_ID.setText(text)

    def update(self):
        self.lines_id  = self.opv.getListPickedLines()

        if self.lines_id != []:
            self.write_ids(self.lines_id)
            self.lineEdit_selected_ID.setDisabled(False)
            self.radioButton_selected_lines.setChecked(True)
        else:
            self.lineEdit_selected_ID.setText("All lines")
            self.lineEdit_selected_ID.setDisabled(True)
            self.radioButton_all.setChecked(True)

    def radioButtonEvent(self):
        self.flagAll = self.radioButton_all.isChecked()
        self.flagSelection = self.radioButton_selected_lines.isChecked()
        self.lines_id  = self.opv.getListPickedLines()
        if self.flagSelection:
            self.lineEdit_selected_ID.setDisabled(False)
            if self.lines_id != []:
                self.write_ids(self.lines_id)
            else:
                self.lineEdit_selected_ID.setText("")
        elif self.flagAll:
            self.lineEdit_selected_ID.setText("All lines")
            self.lineEdit_selected_ID.setDisabled(True)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
            self.confirm_element_type_attribution()
        elif event.key() == Qt.Key_Escape:
            self.close()

    def selectionChange(self):
        self.comboBox_index = self.comboBox.currentIndex()
        self.tabWidget_element_type.removeTab(1)

        if self.flow_effects:
            if self.comboBox_index == 0:
                self.element_type = 'undamped mean flow'
            elif self.comboBox_index == 1:
                self.element_type = 'peters'
            elif self.comboBox_index == 2:
                self.element_type = 'howe'
        else:
            if self.comboBox_index == 0:
                self.element_type = 'undamped'
            elif self.comboBox_index == 1:
                self.element_type = 'proportional'
                self.tabWidget_element_type.addTab(self.tab_damping, "Damping")
                self.tabWidget_element_type.setCurrentIndex(1)
                # self.tabWidget_element_type.setTabEnabled(1, True)
                # self.tabWidget_element_type.setCurrentWidget(self.tab_damping)
            elif self.comboBox_index == 2:
                self.element_type = 'wide-duct'
            elif self.comboBox_index == 3:
                self.element_type = 'LRF fluid equivalent'
            elif self.comboBox_index == 4:
                self.element_type = 'LRF full'

    def checkBoxEvent_flow_effects(self):
        self.flow_effects = self.checkBox_flow_effects.isChecked()
        self.label_vol_flow.setDisabled(not self.flow_effects)
        self.lineEdit_vol_flow.setDisabled(not self.flow_effects)
        self.label_ms_unit.setDisabled(not self.flow_effects)
        self.comboBox.clear()

        if self.flow_effects:
            list_items = ["Undamped mean flow", "Peters", "Howe"]
        else:
            list_items = ["Undamped", "Proportional", "Wide-duct", "LRF fluid equivalent", "LRF full"]

        self.comboBox.addItems(list_items)

    def check_input_parameters(self, input_string, label, _float=True):
        title = "INPUT ERROR"
        value_string = input_string
        if value_string != "":
            try:
                if _float:
                    value = float(value_string)
                else:
                    value = int(value_string)
                if value < 0:
                    message = "You cannot input a negative value to the {}.".format(label)
                    PrintMessageInput([title, message, window_title1])
                    return True
                else:
                    self.value = value

            except Exception:
                message = "You have typed an invalid value to the {}.".format(label)
                PrintMessageInput([title, message, window_title1])
                return True
        else:
            title = "Empty entry to the " + label
            message = "Please, input a valid " + label + " value to continue."
            PrintMessageInput([title, message, window_title1])
            self.tabWidget_element_type.setCurrentWidget(self.tab_damping)
            self.value = None
            return True
        return False

    def confirm_element_type_attribution(self):

        if self.comboBox_index == 1 and not self.flow_effects:
            if self.check_input_parameters(self.lineEdit_proportional_damping.text(), "proportional damping"):
                return
            proportional_damping = self.value
        else:
            proportional_damping = None

        if self.flow_effects:
            if self.check_input_parameters(self.lineEdit_vol_flow.text(), "Volume flow rate"):
                return
            vol_flow = self.value
        else:
            vol_flow = None

        if self.flagSelection:
            lineEdit = self.lineEdit_selected_ID.text()
            self.stop, self.typed_lines = self.before_run.check_input_LineID(lineEdit)
            if self.stop:
                return True
            lines = self.typed_lines
            if len(self.typed_lines) <= 20:
                print(f"[Set Acoustic Element Type] - {self.element_type} assigned to {self.typed_lines} lines")
            else:
                print(f"[Set Acoustic Element Type] - {self.element_type} assigned in {len(self.typed_lines)} lines")
        elif self.flagAll:
            lines = self.project.preprocessor.all_lines
            print(f"[Set Acoustic Element Type] - {self.element_type} assigned in all the entities")

        self.project.set_acoustic_element_type_by_lines(lines, self.element_type, proportional_damping = proportional_damping, vol_flow = vol_flow)
        self.complete = True
        self.close()

    def on_click_item_line(self, item):
        self.lineEdit_selected_group.setText(item.text(0))

    def load_element_type_info(self):
        self.treeWidget_element_type.clear()
        header = self.treeWidget_element_type.headerItem()
        header.setText(0, "Element type")
        header.setText(1, "Volume flow rate")
        header.setText(2, "Lines")
        header.setTextAlignment(0, Qt.AlignCenter)
        header.setTextAlignment(1, Qt.AlignCenter)
        header.setTextAlignment(2, Qt.AlignCenter)
        for key, lines in self.project.preprocessor.dict_acoustic_element_type_to_lines.items():
            vol_flow = [self.dict_tag_to_entity[line].vol_flow for line in lines]
            if None in vol_flow:
                new = QTreeWidgetItem([str(key), str('---'), str(lines)])
            else:
                new = QTreeWidgetItem([str(key), str(vol_flow), str(lines)])
            new.setTextAlignment(0, Qt.AlignCenter)
            new.setTextAlignment(1, Qt.AlignCenter)
            new.setTextAlignment(2, Qt.AlignCenter)
            self.treeWidget_element_type.addTopLevelItem(new)

    def get_information(self):
        try:
            if self.lineEdit_selected_group.text() != "":
                key = self.lineEdit_selected_group.text()
                GetInformationOfGroup(self.project, key)
            else:
                title = "UNSELECTED GROUP OF LINES"
                message = "Please, select a group in the list to get the information."
                PrintMessageInput([title, message, window_title2])
        except Exception as e:
            title = "ERROR WHILE GETTING INFORMATION OF SELECTED GROUP"
            message = str(e)
            PrintMessageInput([title, message, window_title1])

class GetInformationOfGroup(QDialog):
    def __init__(self, project, key, *args, **kwargs):
        super().__init__(*args, **kwargs)

        uic.loadUi(Path('data/user_input/ui_files/Model/Info/getGroupInformationInput.ui'), self)

        icons_path = str(Path('data/icons/pulse.png'))
        self.icon = QIcon(icons_path)
        self.setWindowIcon(self.icon)

        self.setWindowFlags(Qt.WindowStaysOnTopHint)
        self.setWindowModality(Qt.WindowModal)

        self.project = project
        self.dict_tag_to_entity = project.preprocessor.dict_tag_to_entity
        self.key = key

        self.treeWidget_group_info = self.findChild(QTreeWidget, 'treeWidget_group_info')
        header = self.treeWidget_group_info.headerItem()
        header.setText(0, "Line")
        header.setText(1, "Element type")
        header.setTextAlignment(0, Qt.AlignCenter)
        header.setTextAlignment(1, Qt.AlignCenter)

        if self.key == 'proportional':
            header.setText(2, "Proportional damping")
            header.setTextAlignment(2, Qt.AlignCenter)
            self.treeWidget_group_info.setColumnWidth(0, 90)
            self.treeWidget_group_info.setColumnWidth(1, 130)
            self.treeWidget_group_info.setColumnWidth(2, 150)
        elif self.key in ["undamped mean flow", "peters", "howe"]:
            header.setText(2, "Volume mean flow")
            header.setTextAlignment(2, Qt.AlignCenter)
            self.treeWidget_group_info.setColumnWidth(0, 90)
            self.treeWidget_group_info.setColumnWidth(1, 130)
            self.treeWidget_group_info.setColumnWidth(2, 150)
        else:
            self.treeWidget_group_info.setColumnWidth(0, 100)
            self.treeWidget_group_info.setColumnWidth(1, 140)

        self.pushButton_close = self.findChild(QPushButton, 'pushButton_close')
        self.pushButton_close.clicked.connect(self.force_to_close)
        self.load_group_info()
        self.exec()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.close()

    def load_group_info(self):
        self.treeWidget_group_info.clear()
        values = self.project.preprocessor.dict_acoustic_element_type_to_lines[self.key]
        for line in values:
            if self.key == 'proportional':
                damping = self.dict_tag_to_entity[line].proportional_damping
                new = QTreeWidgetItem([str(line), self.key, str(damping)])
                new.setTextAlignment(2, Qt.AlignCenter)
            elif self.key in ["undamped mean flow", "peters", "howe"]:
                vol_flow = self.dict_tag_to_entity[line].vol_flow
                new = QTreeWidgetItem([str(line), self.key, str(vol_flow)])
                new.setTextAlignment(2, Qt.AlignCenter)
            else:
                new = QTreeWidgetItem([str(line), self.key])
            new.setTextAlignment(0, Qt.AlignCenter)
            new.setTextAlignment(1, Qt.AlignCenter)
            self.treeWidget_group_info.addTopLevelItem(new)

    def force_to_close(self):
        self.close()


from exercise5_2 import *

# Set learning rate (try experimenting with this)
alpha = 0.001

# Set theta to intial value of None
theta_digits = None

# We go through the entire training set a number of times
# Each of these iterations is called an epoch
n_epochs = 50

accuracies_train = []
accuracies_test = []
log_likelihoods_train = []
log_likelihoods_test = []

for epoch in range(n_epochs):
    theta_digits = train_theta(x_train_digits, y_train_digits, n_epochs=1, theta=theta_digits, alpha=alpha)
    # calculate accuracy
    accuracy_train = -1
    accuracy_test = -1
    # START ANSWER
    predictions_train = predict_binary(x_train_digits, theta_digits)
    accuracy_train = compute_accuracy(predictions_train, y_train_digits)

    predictions_test = predict_binary(x_test_digits, theta_digits)
    accuracy_test = compute_accuracy(predictions_test, y_test_digits)

    # END ANSWER
    accuracies_train.append(accuracy_train)
    accuracies_test.append(accuracy_test)

    # calculate log likelihood
    ll_train = 0
    ll_test = 0
    # START ANSWER
    ll_train = log_likelihood(hypothesis(x_train_digits, theta_digits), y_train_digits)
    ll_test = log_likelihood(hypothesis(x_test_digits, theta_digits), y_test_digits)

    # END ANSWER
    log_likelihoods_train.append(ll_train)
    log_likelihoods_test.append(ll_test)

# plt.plot(np.arange(len(accuracies_train)), accuracies_train, label='train')
# plt.plot(np.arange(len(accuracies_test)), accuracies_test, label='test')
# plt.title('accurracy')
# plt.xlabel('epoch')
# plt.ylabel('accurracy')
# plt.legend(loc=3)
# plt.show()

# plt.plot(np.arange(len(log_likelihoods_train)), log_likelihoods_train, label='train')
# plt.plot(np.arange(len(log_likelihoods_test)), log_likelihoods_test, label='test')
# plt.title('log likelihood')
# plt.xlabel('epoch')
# plt.ylabel('log likelihood')
# plt.legend(loc=3)
# plt.show()


n = int(input())
stack = []
size = 0
count = 0
ans = ''

while(n):
    m = int(input())
    if m > count:
        while m > count:
            size+=1
            count+=1
            ans += '+'
            stack.append(count)
        stack.pop()
        size-=1
        ans += '-'
    elif size > 0 and m <= stack[size-1]:
        while size > 0 and m <= stack[size-1]:
            size-=1
            ans += '-'
            stack.pop()
    elif m < count:
        print('NO')
        break
    n-=1
    if n == 0:
        for i in ans:
            print(i)


import math

def get_slope(p=None, ang=None):
    if p != None:
        (x1, y1), (x2, y2) = p

        if x2 - x1 != 0:
            return (y2 - y1) / (x2 - x1)
        else:
            return 'infinity'

    elif ang != None:
        if ang not in [90, -90]:
            return math.tan(ang)
        else:
            return 'infinity'

def get_gFieldMag(M, r, G=6.67408E-11):
    return G * M / r**2

def get_gForceMag(m, M, r, G=6.67408E-11):
    return m * get_gFieldMag(M, r, G)

class Vector:
    def __init__(self, euclid_coor=None, polar_coor=None):
        if euclid_coor != None:
            (x1, y1), (x2, y2) = euclid_coor

            self.type = 'euclid'

            self.tail = (x1, y1)
            self.head = (x2, y2)

            self.dx = lambda: self.head[0] - self.tail[0]
            self.dy = lambda: self.head[1] - self.tail[1]

            self.mag = lambda: math.dist((self.tail[0], self.tail[1]), (self.head[0], self.head[1]))
            self.slope = lambda: get_slope(p=((self.tail[0], self.tail[1]), (self.head[0], self.head[1])))
            self.ang = lambda: math.degrees(math.atan2((self.head[1] - self.tail[1]), (self.head[0] - self.tail[0])))

            self.x2 = lambda: self.head[0]
            self.y2 = lambda: self.head[1]

        elif polar_coor != None:
            p1, _mag, _ang = polar_coor

            self.type = 'polar'

            self.tail = p1
            self.mag = _mag
            self.ang = _ang

            self.slope = lambda: get_slope(ang=self.ang)

            self.dx = lambda: math.cos(math.radians(self.ang)) * self.mag
            self.dy = lambda: math.sin(math.radians(self.ang)) * self.mag

            self.head = lambda: (self.tail[0] + self.dx(), self.tail[1] + self.dy())

            self.x2 = lambda: self.head()[0]
            self.y2 = lambda: self.head()[1]

        self.x1 = lambda: self.tail[0]
        self.y1 = lambda: self.tail[1]

    def __add__(self, other):
        f = other

        if self.type == other.type:
            if self.type == 'euclid':
                f.changePos('tail', self.head)
                return Vector(euclid_coor=(self.tail, f.head))

            elif self.type == 'polar':
                f.changePos('tail', self.head())

                mag = math.dist(self.tail, f.head())
                ang = math.degrees(math.atan2((self.head()[1] - self.tail[1]), (self.head()[0] - self.tail[0])))
                return Vector(polar_coor=(self.tail, mag, ang))

        else:
            raise TypeError('Cannot add vectors of different types')

    def __sub__(self, other):
        if self.type == other.type:
            return self + other.get_negative()
        else:
            raise TypeError('Cannot subtract vectors of different types')

    def get_negative(self):
        if self.type == 'euclid':
            return Vector(euclid_coor=(self.head, self.tail))
        elif self.type == 'polar':
            return Vector(polar_coor=(self.head(), self.mag, 180 + self.ang))

    def get_compX(self, _type=None):
        if _type is None:
            _type = self.type

        if _type == 'euclid':
            return Vector(euclid_coor=(self.tail, (self.x2(), self.y1())))

        elif _type == 'polar':
            if 90 < self.ang < 270:
                ang = 180
            else:
                ang = 0

            return Vector(polar_coor=(self.tail, self.dx(), ang))

    def get_compY(self, _type=None):
        if _type is None:
            _type = self.type

        if _type == 'euclid':
            return Vector(euclid_coor=((self.x2(), self.y1()), self.head))

        elif _type == 'polar':
            if 0 <= self.ang < 180:
                ang = 90
            else:
                ang = 270

            return Vector(polar_coor=((self.x2(), self.y1()), self.dy(), 90))

    def changePos(self, ele, newCoor):
        if self.type == 'euclid':
            if ele == 'tail':
                dx = self.dx()
                dy = self.dy()

                self.tail = newCoor
                self.head = (self.tail[0] + dx, self.tail[1] + dy)
            elif ele == 'head':
                dx = self.dx()
                dy = self.dy()

                self.head = newCoor
                self.tail = (self.head[0] - dx, self.head[1] - dx)

        elif self.type == 'polar':
            if ele == 'tail':
                self.tail = newCoor
            elif ele == 'head':
                self.tail = (
                    self.tail[0] + (newCoor[0] - self.head()[0]), self.tail[1] + (newCoor[1] - self.head()[1]))

    def get_inverse(self):
        if self.type == 'euclid':
            return Vector(polar_coor=(self.tail, self.mag(), self.ang()))
        elif self.type == 'polar':
            return Vector(euclid_coor=(self.tail, self.head()))

def addVectors(vectors, _type):
    try:
        maxLim = len(vectors)
    except:
        raise TypeError('Please provide an iterable for the \'vectors\' parameter')

    if maxLim != 0:
        for i in range(maxLim):
            if i == 0:
                total = vectors[0]
            else:
                    total += vectors[i]
    else:
        if  _type == 'euclid':
            total = Vector(euclid_coor=((0, 0), (0, 0)))
        elif  _type == 'polar':
            total = Vector(polar_coor=((0, 0), 0, 0))

    return total

class Body:
    def __init__(self, m, r, _color, _x, _y, _velX, _velY, _forces, _image=None):
        self.mass = m
        self.radius = r
        self.color = _color

        self.x = _x
        self.y = _y

        self.applyForces(_forces)
        self.netForce = lambda: addVectors(self.forces, _type='polar')

        self.accX = lambda _type: self.netForce().get_compX(_type).mag / self.mass
        self.velX = lambda _type, dt: _velX + self.accX(_type) * dt

        self.accY = lambda _type: self.netForce().get_compY(_type).mag / self.mass
        self.velY = lambda _type, dt: _velY + self.accY(_type) * dt

        if _image is not None:
            self.image = _image

    def applyForces(self, _forces):
        if hasattr(_forces, '__iter__'):
            self.forces = _forces
        else:
            raise TypeError('Please provide an iterable containing the given forces for the \'_forces\' parameter')

    def get_gForce(self, others, _type):
        gForces = []

        for other in others:
            tail = (self.x, self.y)
            pos2 = (other.x, other.y)
            dist = math.dist(tail, pos2)
            mag = get_gForceMag(self.mass, other.mass, dist)
            ang = math.degrees(math.atan(get_slope((tail, pos2))))

            gForces.append(Vector(polar_coor=(tail, mag, ang)))

        return addVectors(gForces, _type='polar')

    def move(self, coors, dt, _type='polar', _forces=None):
        if _forces is not None:
            self.forces = _forces

        if 'x' in coors:
            self.x += self.velX(_type, dt)
        if 'y' in coors:
            self.y += self.velY(_type, dt)


import argparse
import math
import random
import statistics
import time
from collections import (
    defaultdict,
)
from pathlib import (
    Path,
)

import gym
import numpy as np
import pandas as pd
import plotly.express as px
from gym import (
    wrappers,
)
from tensorflow.keras.models import (
    load_model,
    save_model,
)
from tensorflow.keras.utils import (
    plot_model,
)
from tqdm import (
    tqdm,
)

from bc.bc_model import *
from bc.driving_data import *
from common.consts import *
from common.driving_utils import *
from common.utils import (
    load_pkl,
    print_step,
    save_pkl,
)

def run():
    run_bc_model(
        "checkpoints/decent_bc",
        1,
        False,
    )

def check():
    model = load_model(
        "checkpoints/bc"
    )
    (
        imgs,
        features,
        labels,
    ) = (
        load_bc_data()
    )
    n = len(
        imgs
    )
    for _ in range(
        10
    ):
        i = random.randrange(
            0,
            n,
        )
        fig = px.imshow(
            imgs[
                i
            ],
            title=f"{INDEX2STRING[int(labels[i])]}",
        )
        fig.write_image(
            f"imgs/model_validation/{i}.png"
        )
        # fig.show()

def resume():
    model = load_model(
        "checkpoints/bc"
    )
    (
        imgs,
        features,
        labels,
    ) = (
        load_bc_data()
    )
    train_model(
        model,
        imgs,
        features,
        labels,
        40,
    )

# ======= Train =========

def train():
    model = (
        get_bc_model()
    )
    plot_model(
        model,
        "imgs/model.png",
    )
    (
        imgs,
        features,
        labels,
    ) = (
        load_bc_data()
    )
    train_model(
        model,
        imgs,
        features,
        labels,
        40,
    )

# ======= Evaluate =========

def evaluate():
    (
        x,
        y,
    ) = (
        load_bc_data()
    )
    m = load_model(
        "checkpoints/bc/"
    )
    m.evaluate(
        x,
        y,
    )
    pred = m.predict(
        x
    )
    pred = np.argmax(
        pred,
        axis=1,
    )
    print(
        sum(
            y
            == pred
        )
        / len(
            y
        )
    )

# ======= Generate Data =======

def generate():
    human_generate_data(
        False
    )

def gather():
    gather_data_balanced()

def human():
    human_race()

CHOICES = [
    "run",
    "check",
    "resume",
    "train",
    "evaluate",
    "generate",
    "gather",
    "human",
]
CHOICE2FUNC = {
    "run": run,
    "check": check,
    "resume": resume,
    "train": train,
    "evaluate": evaluate,
    "generate": generate,
    "gather": gather,
    "human": human,
}

if (
    __name__
    == "__main__"
):
    parser = (
        argparse.ArgumentParser()
    )
    parser.add_argument(
        "action",
        type=str,
        choices=CHOICES,
    )
    args = (
        parser.parse_args()
    )
    CHOICE2FUNC[
        args.action
    ]()

# TODO simplify data by setting the speed automatically
# TODO get rl agent working!

# env = gym.make("CarRacing-v0")
# env.reset()
# print(env.action_space)

"""
Car Racing
Actions: [steer, gas, break] (floats)
          steer (left) -1  0 1 (right)
          gas
          break
Observations:
    92x92x3 image
    greens: (102, 204, 102), (104, 229, 104)
    grey: (102-107, 102-107, 102-107)
"""


import numpy as np
from skimage.metrics import peak_signal_noise_ratio, structural_similarity
from .meter import AvgMeter
from .func import normalize_zero_to_one
import torch

def check_sanity(im1, im2):
    assert type(im1) == type(im2), "Mismatched type for the two images."
    assert im1.shape == im2.shape, "Mismatched shape for the two images."

def check_batch_sanity(im1, im2):
    check_sanity(im1, im2)
    assert im1.ndim == 4 # ! What if it's more than 4 dimension?
    assert isinstance(im1, torch.Tensor), "Input batch should be a tensor."

def slice_psnr(gt, pred, maxval= None): # This is only for a single pair of images (gt, pred), especially in ndarray format. For a batch? Not for now, see the below.
    check_sanity(gt, pred)
    if type(pred) is torch.Tensor:
        gt, pred = gt.detach().cpu().numpy(), pred.detach().cpu().numpy()
    maxval = gt.max() if maxval is None else maxval
    return peak_signal_noise_ratio(gt, pred, data_range=maxval)

def slice_ssim(gt, pred, maxval = None): # the in-built function has been already applied channel-wise, now we need focus on the batch-size, even it's just 1.
    check_sanity(gt, pred)
    if type(pred) is torch.Tensor:
        gt, pred = gt.detach().cpu().numpy(), pred.detach().cpu().numpy()
    color = True if pred.shape[1] == 3 else False
    maxval = gt.max() if maxval is None else maxval
    return structural_similarity(gt, pred, data_range=maxval, multichannel=color)

def batch_psnr(gt, pred, maxval=None): # (N, 1, H, W) / (N, H, W, 1) ---> (H, W) Suitable only for gray images of ndim=4 (Tensor)
    check_batch_sanity(gt, pred)
    gt, pred = gt.detach().cpu().numpy(), pred.detach().cpu().numpy()
    batch_size = gt.shape[0]
    psnr = 0.0
    for i in range(batch_size):
        max_val = gt[i].max() if maxval is None else maxval
        psnr += peak_signal_noise_ratio(gt[i].squeeze(), pred[i].squeeze(), data_range=max_val)
    return psnr / batch_size

def batch_ssim(gt, pred, maxval=None):
    color_flag = False
    check_batch_sanity(gt, pred)
    gt = gt.permute(0, 2, 3, 1)
    pred = pred.permute(0, 2, 3, 1)
    color_flag = True if pred.shape[-1] == 3 else False
    gt, pred = gt.detach().cpu().numpy(), pred.detach().cpu().numpy()
    batch_size = gt.shape[0]
    ssim = 0.0
    for i in range(batch_size):
        max_val = gt[i].max() if maxval is None else maxval
        ssim += structural_similarity(gt[i].squeeze(), pred[i].squeeze(), data_range=max_val, multichannel=color_flag)
    return ssim / batch_size

class Metrics:
    def __init__(self, batch_flag=True):
        self.psnr_meter = AvgMeter()
        self.ssim_meter = AvgMeter()
        if batch_flag:
            self.metric_funcs= {'PSNR':batch_psnr, 'SSIM':batch_ssim}
        else:
            self.metric_funcs= {'PSNR':slice_psnr, 'SSIM':slice_ssim}
        self.stats = {metric: None for metric in self.metric_funcs}

    def push(self, target, recons):
        for metric, func in self.metric_funcs.items():
            self.stats[metric]= func(target, recons)
        self.psnr_meter.update(self.stats['PSNR'])
        self.ssim_meter.update(self.stats['SSIM'])
    def reset(self):
        self.psnr_meter.reset()
        self.ssim_meter.reset()
        self.stats = {metric: None for metric in self.metric_funcs}

"""
def ssim(prediction, target):
    import cv2
    C1 = (0.01 * 255)**2
    C2 = (0.03 * 255)**2
    img1 = prediction.astype(np.float64)
    img2 = target.astype(np.float64)
    kernel = cv2.getGaussianKernel(11, 1.5)
    window = np.outer(kernel, kernel.transpose())
    mu1 = cv2.filter2D(img1, -1, window)[5:-5, 5:-5]  # valid
    mu2 = cv2.filter2D(img2, -1, window)[5:-5, 5:-5]
    mu1_sq = mu1**2
    mu2_sq = mu2**2
    mu1_mu2 = mu1 * mu2
    sigma1_sq = cv2.filter2D(img1**2, -1, window)[5:-5, 5:-5] - mu1_sq
    sigma2_sq = cv2.filter2D(img2**2, -1, window)[5:-5, 5:-5] - mu2_sq
    sigma12 = cv2.filter2D(img1 * img2, -1, window)[5:-5, 5:-5] - mu1_mu2
    ssim_map = ((2 * mu1_mu2 + C1) *
                (2 * sigma12 + C2)) / ((mu1_sq + mu2_sq + C1) *
                                       (sigma1_sq + sigma2_sq + C2))
    return ssim_map.mean()

def calculate_ssim(target, ref):
    '''
    calculate SSIM
    the same outputs as MATLAB's
    img1, img2: [0, 255]
    '''
    img1 = np.array(target, dtype=np.float64)
    img2 = np.array(ref, dtype=np.float64)
    if not img1.shape == img2.shape:
        raise ValueError('Input images must have the same dimensions.')
    if img1.ndim == 2:
        return ssim(img1, img2)
    elif img1.ndim == 3:
        if img1.shape[2] == 3:
            ssims = []
            for i in range(3):
                ssims.append(ssim(img1[:, :, i], img2[:, :, i]))
            return np.array(ssims).mean()
        elif img1.shape[2] == 1:
            return ssim(np.squeeze(img1), np.squeeze(img2))
    else:
        raise ValueError('Wrong input image dimensions.')

def psnr(target, ref):
    img1 = np.array(target, dtype=np.float32)
    img2 = np.array(ref, dtype=np.float32)
    diff = img1 - img2
    psnr = 10.0 * np.log10(255.0 * 255.0 / np.mean(np.square(diff)))
    return psnr

def calculate_psnr(target, ref):
    img1 = np.array(target, dtype=np.float64)
    img2 = np.array(ref, dtype=np.float64)
    if not img1.shape == img2.shape:
        raise ValueError('Input images must have the same dimensions.')
    if img1.ndim == 2:
        return psnr(img1, img2)
    elif img1.ndim == 3:
        if img1.shape[2] == 3:
            psnrs = []
            for i in range(3):
                psnrs.append(psnr(img1[...,i], img2[..., i]))
            return np.array(psnrs).mean()
        elif img1.shape[2] == 1:
            return psnr(img1.squeeze(), img2.squeeze())
    else:
        raise ValueError('Wrong input image dimensions.')
"""

if __name__ == '__main__':
    import PIL.Image as Image
    target = Image.open("./asylum/metrics/101085_gray.png")
    noisy = Image.open("./asylum/metrics/101085_noisy.png")
    target_np = np.array(target)
    noisy_np = np.array(noisy)
    print('-' * 10)
    print(f"Shape: target: {target_np.shape}; noisy: {noisy_np.shape}")
    print(f"Max: target: {target_np.max()}; noisy: {noisy_np.max()}")
    print(f"Min: target: {target_np.min()}; noisy: {noisy_np.min()}")

    # print(f"PSNR: {calculate_psnr(target_np, noisy_np)}")
    # print(f"SSIM: {calculate_ssim(target_np, noisy_np)}")

    metric_slice = Metrics(batch_flag=False)
    metric_slice.push(target_np, noisy_np)
    print(metric_slice.psnr_meter.avg)
    print(metric_slice.ssim_meter.avg)

    target_np = np.expand_dims(target_np, 0)
    noisy_np = np.expand_dims(noisy_np, 0)
    target_np = np.expand_dims(target_np, -1)
    noisy_np = np.expand_dims(noisy_np, -1)

    print('-'*10)
    print(f"Shape: target: {target_np.shape}; noisy: {noisy_np.shape}")
    print(f"Max: target: {target_np.max()}; noisy: {noisy_np.max()}")
    print(f"Min: target: {target_np.min()}; noisy: {noisy_np.min()}")

    metrics_batch = Metrics(batch_flag=True)
    metrics_batch.push(target_np, noisy_np)
    print(metrics_batch.psnr_meter.avg)
    print(metrics_batch.ssim_meter.avg)

    # target_np = normalize_zero_to_one(target_np)
    # noisy_np = normalize_zero_to_one(noisy_np)

    # print(f"Shape: target: {target_np.shape}; noisy: {noisy_np.shape}")
    # print(f"Max: target: {target_np.max()}; noisy: {noisy_np.max()}")
    # print(f"Min: targ:et: {target_np.min()}; noisy: {noisy_np.min()}")

    # # print(f"PSNR: {calculate_psnr(target_np, noisy_np)}")
    # # print(f"SSIM: {calculate_ssim(target_np, noisy_np)}")

    # metrics_batch = Metrics()
    # metrics_batch.push(target_np, noisy_np)
    # print(metrics_batch.psnr_meter.avg)
    # print(metrics_batch.ssim_meter.avg)
    # print('----------------------------------------')

    # target_np = np.clip(target_np * 255, 0, 255)
    # noisy_np = np.clip(noisy_np * 255, 0, 255)

    # print(f"Shape: target: {target_np.shape}; noisy: {noisy_np.shape}")
    # print(f"Max: target: {target_np.max()}; noisy: {noisy_np.max()}")
    # print(f"Min: target: {target_np.min()}; noisy: {noisy_np.min()}")

    # # print(f"PSNR: {calculate_psnr(target_np, noisy_np)}")
    # # print(f"SSIM: {calculate_ssim(target_np, noisy_np)}")

    # # target_np = np.expand_dims(target_np, -1)
    # # noisy_np = np.expand_dims(noisy_np, -1)

    # metrics_batch = Metrics()
    # metrics_batch.push(target_np, noisy_np)
    # print(metrics_batch.psnr_meter.avg)
    # print(metrics_batch.ssim_meter.avg)