# Created by rahman at 11:06 2020-02-22 using PyCharm
import tensorflow as tf
tf.random.set_seed(3)

#if tf.test.is_built_with_cuda or tf.__version__ == '2.1.0':
from tensorflow import keras

k_init = tf.keras.initializers.Constant(value=0.1)
b_init = keras.initializers.Constant(value=0)
r_init = keras.initializers.Constant(value=0.1)

from tensorflow.keras import backend as K
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras.layers import Dropout, Dense, Conv1D, MaxPooling1D, Flatten , LSTM, Bidirectional, Reshape

from tensorflow.keras import Sequential, utils, Input, Model

#if tf.__version__ != '2.1.0':
    #import keras.layers.CuDNNLSTM

"""import keras
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.layers import Dropout, Dense, Conv1D, MaxPooling1D, Flatten, Reshape, LSTM
from keras import Sequential, utils, Input, Model"""

from keras.utils.vis_utils import plot_model

import logging
import math

class BinaryDNN:

    def __init__(self, num_layers = 2, layer_params=[[0.5, 0.2], [0.25, 0]], num_epochs=100, batch_size=64, verbose=0):
        """

        :param num_layers: just for a sanity check
        :param layer_params: list of size 2 lists, containing [layer size factor, dropout] for each layer
        :param num_epochs:
        :param batch_size:
        """

        assert(num_layers == len(layer_params))

        self.num_layers = num_layers
        self.layer_params = layer_params
        self.num_epochs = num_epochs
        self.batch_size = batch_size
        self.verbose = verbose

        self.logger = logging.getLogger("DnnClassifier")

    def fit(self, X_train, y_train):

        dim = X_train.shape[1]

        self.model = Sequential()

        for factor, dropout in self.layer_params:

            self.model.add(Dense(int(dim * factor if dim * factor > 1 else 1), input_dim=dim, activation='relu'))
            self.model.add(Dropout(dropout))

        self.model.add(Dense(1, activation='sigmoid'))
        self.model.compile(optimizer='adam', loss='binary_crossentropy',  metrics=['accuracy'])

        if self.verbose!=0:

            self.model.summary()

        #y_keras= utils.to_categorical(y_train, 2)
        es = EarlyStopping(monitor='val_loss', mode='auto', verbose=1, patience=30, restore_best_weights=True)
        self.model.fit(X_train, y_train, epochs = self.num_epochs, batch_size = self.batch_size, verbose=self.verbose, callbacks=[es])

    def predict(self, X_test):

        y_pred = self.model.predict(X_test, verbose=True)

        return (y_pred > 0.5)

class SiameseClassifier:

    def __init__(self, shape, regu, combi, time_dim=0):

        self.time_dim = time_dim
        self.regu =  keras.regularizers.l2(regu)
        self.combi = combi

        #self.l_a and self.l_b will be defined in the child constructors
        if len(shape)==3:

            assert(self.time_dim==1)
            self.num_features = shape[2]
            self.num_timesteps = shape[1]

            self.sample_a = Input(shape=(self.num_timesteps, self.num_features))
            self.sample_b = Input(shape=(self.num_timesteps, self.num_features))

        elif len(shape)==2: #it is an old style vecframe

            self.num_features = shape[1]-2

            self.sample_a = Input(shape=(self.num_features,))
            self.sample_b = Input(shape=(self.num_features,))

    def combine(self, plot=False):

        if self.combi=='l1':

            difference = keras.layers.subtract([self.l_a, self.l_b])
            combined = keras.layers.Lambda(tensorabs)(difference)  # in general: absolute value: abs(<tensor>)

        elif self.combi=='mul':

            combined = keras.layers.multiply([self.l_a, self.l_b])
            #combined = keras.layers.Lambda(tensorabs)(difference)  # in general: absolute value: abs(<tensor>)

        elif self.combi == 'avg':

            combined = keras.layers.average([self.l_a, self.l_b])
            #combined = keras.layers.Lambda(tensorabs)(difference)  # in general: absolute value: abs(<tensor>)

        elif self.combi == 'sql2':

            #combined = keras.layers.average([l_a2, l_b2])
            combined = keras.layers.Lambda(lambda x: (x[0] - x[1]) ** 2 )([self.l_a, self.l_b])

        predictions = Dense(1, activation='sigmoid')(combined)

        self.model = tf.keras.Model(inputs=[self.sample_a, self.sample_b], outputs=predictions)

        self.model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy', tf.keras.metrics.AUC()])

        print(self.model.summary())

        if plot:
            plot_model(self.model, to_file='siam.png', show_shapes=True, show_layer_names=True)

    def fit_predict(self, link, batchsize, epochs, verbose=0):

        self.model.fit([link.vecframe.loc[link.tr_pairs.i].iloc[:, 2:], link.vecframe.loc[link.tr_pairs.j].iloc[:, 2:]],
                           link.tr_pairs.label,
                           batch_size=batchsize, epochs=epochs,
                           validation_data=([link.vecframe.loc[link.te_pairs.i].iloc[:, 2:], link.vecframe.loc[link.te_pairs.j].iloc[:, 2:]],
                           link.te_pairs.label), verbose=verbose)

        y_pred = self.model.predict([link.vecframe.loc[link.te_pairs.i].iloc[:, 2:], link.vecframe.loc[link.te_pairs.j].iloc[:, 2:]],
                                        verbose=verbose)

        from sklearn.metrics import roc_auc_score

        auc = roc_auc_score(link.te_pairs.label, y_pred)

        return auc

    def fit_predict_callback(self, link, batchsize, epochs, patience, verbose=0):

        es = EarlyStopping(monitor='val_loss', mode='auto', verbose=1, patience=patience, restore_best_weights=True)
        #mc = ModelCheckpoint('best_model.h5', monitor='val_acc', mode='max', verbose=1, save_best_only=True)
        print (self.model.layers)

        if self.time_dim: #link.vecframe is actually just a 3d arrary, not dataframe
            self.model.fit([link.vecframe[link.tr_pairs.i][:, :], link.vecframe[link.tr_pairs.j][:, :]],
                           link.tr_pairs.label,
                           batch_size=batchsize, epochs=epochs,
                           validation_data=(
                           [link.vecframe[link.te_pairs.i][:, :], link.vecframe[link.te_pairs.j][:, :]],
                           link.te_pairs.label), verbose=verbose,
                           callbacks=[es]) #, mc
            y_pred = self.model.predict(
                [link.vecframe[link.te_pairs.i][:, :], link.vecframe[link.te_pairs.j][:, :]],
                verbose=verbose)

        else:

            self.model.fit([link.vecframe.loc[link.tr_pairs.i].iloc[:, 2:], link.vecframe.loc[link.tr_pairs.j].iloc[:, 2:]],
                       link.tr_pairs.label,
                       batch_size=batchsize, epochs=epochs,
                       validation_data=(
                       [link.vecframe.loc[link.te_pairs.i].iloc[:, 2:], link.vecframe.loc[link.te_pairs.j].iloc[:, 2:]],
                       link.te_pairs.label), verbose=verbose,
                       callbacks=[es]) #, mc
            y_pred = self.model.predict(
                [link.vecframe.loc[link.te_pairs.i].iloc[:, 2:], link.vecframe.loc[link.te_pairs.j].iloc[:, 2:]],
                verbose=verbose)

        #layer_name = 'attention' its layer 8
        """for layer in self.model.layers[2:]:  # all layer outputs

            print(layer)

            intermediate_layer_model = keras.Model(inputs=self.model.input,
                                               outputs=layer.output)

            test_a = tf.ones((1,12))
            test_b = tf.ones((1,12))
            intermediate_output = intermediate_layer_model.predict([test_a, test_b])

            print (intermediate_output[0])"""

        #saved_model = load_model('best_model.h5')

        from sklearn.metrics import roc_auc_score

        auc = roc_auc_score(link.te_pairs.label, y_pred)

        return auc

class Dense_siameseClassifier(SiameseClassifier):

    def __init__(self, shape, regu, combi, dense_params):

        super().__init__(shape, regu, combi)

        half_num_features = int(math.floor(self.num_features * dense_params[0]) if self.num_features>=2 else 1)
        shared_dense1 = Dense(half_num_features, input_shape=(self.num_features,),
                              activation='relu') #, kernel_initializer=k_init, bias_initializer=b_init

        if self.regu != None:
            shared_dense1.kernel_regularizer = self.regu

        l_a = shared_dense1(self.sample_a)
        l_b = shared_dense1(self.sample_b)

        quater_num_features = int(math.floor(self.num_features * dense_params[1]) if self.num_features>=4 else 1)
        shared_dense2 = Dense(quater_num_features, input_shape=(half_num_features,),
                              activation='relu') #, kernel_initializer=k_init, bias_initializer=b_init

        if self.regu != None:
            shared_dense2.kernel_regularizer = self.regu

        l_a2 = shared_dense2(l_a)
        l_b2 = shared_dense2(l_b)

        self.l_a = l_a2
        self.l_b = l_b2

class LSTMsiameseClassifier(SiameseClassifier):

    def __init__(self, num_timesteps, regu, combi, time_dim, lstm_params, fixed_units=True):
        super().__init__(num_timesteps, regu, combi, time_dim)

        shared_nn = Sequential()

        shared_nn.add(Reshape((num_timesteps, 1), input_shape=(num_timesteps,)))

        if len(lstm_params)==2:

            param_0 = lstm_params[0]

            units = param_0[0]

            shared_nn.add(LSTM(units, return_sequences=True, input_shape=(num_timesteps, 1),\
                               kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init))
            shared_nn.add(Dropout(param_0[1]))

            param_1 = lstm_params[1]
            units = param_1[0]

            shared_nn.add(LSTM(units, kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init))
            shared_nn.add(Dropout(param_1[1]))

        elif len(lstm_params)==1:

            param_0 = lstm_params[0]

            units = param_0[0] if fixed_units else (int(math.floor(num_timesteps * param_0[0])) if num_timesteps >= 4 else 1)

            shared_nn.add(LSTM(units,input_shape=(num_timesteps, 1), \
                               kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init))
            shared_nn.add(Dropout(param_0[1]))

        self.l_a = shared_nn(self.sample_a)
        self.l_b = shared_nn(self.sample_b)

class BiLSTMsiameseClassifier(SiameseClassifier):

    def __init__(self, num_timesteps, regu, combi, lstm_params, fixed_units=True):
        super().__init__(num_timesteps, regu, combi)

        shared_nn = Sequential()

        shared_nn.add(Reshape((num_timesteps, 1), input_shape=(num_timesteps,)))

        if len(lstm_params)==2:

            param_0 = lstm_params[0]

            units = param_0[0]

            shared_nn.add(Bidirectional(LSTM(units, return_sequences=True, input_shape=(num_timesteps, 1),\
                               kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init)))
            shared_nn.add(Dropout(param_0[1]))

            param_1 = lstm_params[1]
            units = param_1[0]

            shared_nn.add(Bidirectional(LSTM(units, kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init)))
            shared_nn.add(Dropout(param_1[1]))

        elif len(lstm_params)==1:

            param_0 = lstm_params[0]

            units = param_0[0] if fixed_units else (int(math.floor(num_timesteps * param_0[0])) if num_timesteps >= 4 else 1)

            shared_nn.add(Bidirectional(LSTM(units,input_shape=(num_timesteps, 1), \
                               kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init)))
            shared_nn.add(Dropout(param_0[1]))

        self.l_a = shared_nn(self.sample_a)
        self.l_b = shared_nn(self.sample_b)

"""class Attention(tf.keras.Model):

    def __init__(self, units):
        super(Attention, self).__init__()

        self.W1 = tf.keras.layers.Dense(units)
        self.W2 = tf.keras.layers.Dense(units)
        self.V = tf.keras.layers.Dense(1)

    def call(self, features, hidden):

        hidden_with_time_axis = tf.expand_dims(hidden, 1)
        score = tf.nn.tanh(self.W1(features) + self.W2(hidden_with_time_axis))
        attention_weights = tf.nn.softmax(self.V(score), axis=1)
        context_vector = attention_weights * features
        context_vector = tf.reduce_sum(context_vector, axis=1)
        return context_vector, attention_weights

max_len = 200
rnn_cell_size = 128
vocab_size=250"""

#https://medium.com/@sanjivgautamofficial/lstm-in-keras-56a59264c0b2
#https://www.coursera.org/lecture/nlp-sequence-models/attention-model-lSwVa
#The original idea of attention uses the output of the decoder as h_t, representing "current decoding state".
# If you think of the "many-to-one" problem as a special case of the "many-to-many" problem, h_t becomes the last hidden state of the encoder.
#https://github.com/tensorflow/tensorflow/issues/39332
"""class AttentionBiLSTMClassifier(SiameseClassifier):

    def __init__(self, num_timesteps, regu, combi, lstm_params, fixed_units=True):
        super().__init__(num_timesteps, regu, combi)

        units, dropout = lstm_params[0][0],  lstm_params[0][1]
        shared = []

        for sample in [self.sample_a, self.sample_b]:

            sample = tf.keras.layers.Reshape((num_timesteps, 1), input_shape=(num_timesteps,))(sample)

            lstm, forward_h, forward_c, backward_h, backward_c = tf.keras.layers.Bidirectional \
                (tf.keras.layers.LSTM
                 (units,
                  dropout= dropout,
                  return_sequences=True,
                  return_state=True,
                  recurrent_activation='relu',
                  recurrent_initializer='glorot_uniform'))(sample)

            state_h = tf.keras.layers.Concatenate()([forward_h, backward_h])
            #state_c = tf.keras.layers.Concatenate()([forward_c, backward_c])

            # Query-value attention of shape [batch_size, Tq, filters].
            query_value_attention_seq = tf.keras.layers.Attention()([lstm, state_h])

            query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(
                query_value_attention_seq)

            #output = keras.layers.Dense(1, activation='sigmoid')(context_vector)

            #model = keras.Model(inputs=sequence_input, outputs=output)

            # summarize layers
            #print(model.summary())
            shared.append(query_value_attention)

        self.l_a = shared[0]
        self.l_b = shared[1]
"""

class AttentionBiLSTMClassifier(SiameseClassifier):

    def __init__(self, shape, regu, combi, time_dim, lstm_params, fixed_units=True):
        super().__init__(shape, regu, combi, time_dim)

        units, dropout = lstm_params[0][0],  lstm_params[0][1]

        shared = []

        for sample in [self.sample_a, self.sample_b]:

            sample = tf.keras.layers.Reshape((self.num_timesteps, self.num_features), input_shape=(self.num_timesteps, self.num_features))(sample)

            lstm, forward_h, forward_c, backward_h, backward_c = tf.keras.layers.Bidirectional(LSTM(units,input_shape=(self.num_timesteps, self.num_features), \
                               kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init, return_sequences=True, return_state=True))(sample)

            state_h = tf.keras.layers.Concatenate()([forward_h, backward_h])
            # state_c = tf.keras.layers.Concatenate()([forward_c, backward_c])

            # Query-value attention of shape [batch_size, Tq, filters].
            query_value_attention_seq = tf.keras.layers.Attention()([state_h, lstm])

            query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(
                query_value_attention_seq)

            shared.append(query_value_attention)

        self.l_a = shared[0]
        self.l_b = shared[1]

def GlobalAttention(hidden_states):
    # hidden_states.shape = (batch_size, time_steps, hidden_size)
    hidden_size = int(hidden_states.shape[2])
    # Inside dense layer
    #              hidden_states            dot               W            =>           score_first_part
    # (batch_size, time_steps, hidden_size) dot (hidden_size, hidden_size) => (batch_size, time_steps, hidden_size)
    # W is the trainable weight matrix of attention
    # Luong's multiplicative style score
    score_first_part = Dense(hidden_size, use_bias=False, name='attention_score_vec')(hidden_states)
    #            score_first_part           dot        last_hidden_state     => attention_weights
    # (batch_size, time_steps, hidden_size) dot   (batch_size, hidden_size)  => (batch_size, time_steps)
    h_t = tf.keras.layers.Lambda(lambda x: x[:, -1, :], output_shape=(hidden_size,), name='last_hidden_state')(
        hidden_states)
    score = tf.keras.layers.Dot([score_first_part, h_t], [2, 1], name='attention_score')
    attention_weights = tf.keras.layers.Activation('softmax', name='attention_weight')(score)
    # (batch_size, time_steps, hidden_size) dot (batch_size, time_steps) => (batch_size, hidden_size)
    context_vector = tf.keras.layers.Dot([hidden_states, attention_weights], [1, 1], name='context_vector')
    pre_activation = tf.keras.layers.Concatenate([context_vector, h_t], name='attention_output')
    attention_vector = Dense(128, use_bias=False, activation='tanh',
                             name='attention_vector')(
        pre_activation)
    return attention_vector

class GlobalAttentionBiLSTMClassifier(SiameseClassifier):

    def __init__(self, num_timesteps, regu, combi, lstm_params, fixed_units=True):
        super().__init__(num_timesteps, regu, combi)

        units, dropout = lstm_params[0][0],  lstm_params[0][1]

        shared = []

        for sample in [self.sample_a, self.sample_b]:

            sample = tf.keras.layers.Reshape((num_timesteps, 1), input_shape=(num_timesteps,))(sample)

            lstm_out = tf.keras.layers.Bidirectional(LSTM(units,input_shape=(num_timesteps, 1), \
                               kernel_initializer=k_init, bias_initializer=b_init, recurrent_initializer=r_init, return_sequences=True))(sample)

            # Query-value attention of shape [batch_size, Tq, filters].
            attention = tf.keras.layers.GlobalAttention(lstm_out)

            shared.append(attention)

        self.l_a = shared[0]
        self.l_b = shared[1]

def tensorabs(t):
    return abs(t)

class CNNsiameseClassifier(SiameseClassifier):

    def __init__(self, shape, regu, combi, cnn_params):

        super().__init__(shape, regu, combi)

        (filt1, ker1), (filt2, ker2), pool, num_maxpools = cnn_params

        assert (num_maxpools in [1, 2])

        shared_conv1 = Sequential()

        shared_conv1.add(Reshape((self.num_features, 1), input_shape=(self.num_features,)))

        shared_conv1.add(Conv1D(filters=filt1, kernel_size=ker1, activation='relu', kernel_regularizer=self.regu, padding='same'))

        if num_maxpools==2:

            shared_conv1.add(MaxPooling1D(pool_size=pool))

        shared_conv1.add(Conv1D(filters=filt2, kernel_size=ker2, activation='relu', kernel_regularizer=self.regu, padding='same'))

        shared_conv1.add(MaxPooling1D(pool_size=pool))

        shared_conv1.add(Flatten())

        shared_conv1.add(Dense(100, activation='relu'))

        self.l_a = shared_conv1(self.sample_a)
        self.l_b = shared_conv1(self.sample_b)


#!/usr/bin/env python3

import pysam
import argparse

parser = argparse.ArgumentParser(description= 'Add tags to VCF')
parser.add_argument('invcf', default= '-', nargs= '?', help= 'Input VCF [%(default)s]')
args = parser.parse_args()

invcf = pysam.VariantFile(args.invcf, "r")

invcf.header.formats.add("ALT_AF", "A", "Float", "Alternate allele frequencies")
invcf.header.formats.add("SUM_ALT", "1", "Integer", "Sum of observations from all alternate alleles")
invcf.header.formats.add("SUM_ALT_AF", "1", "Float", "Sum of alternate allele frequencies")

outvcf = pysam.VariantFile('-', 'w', header= invcf.header)

for variant in invcf:
    for sample in variant.samples:
        ad = variant.samples[sample]['AD']
        dp = float(sum(ad))
        alt_af = [x/dp for x in ad[1:]]
        sumalt = sum(ad) - ad[0]
        variant.samples[sample]['ALT_AF'] = alt_af
        variant.samples[sample]['SUM_ALT'] = sumalt
        variant.samples[sample]['SUM_ALT_AF'] = sum(alt_af)
    outvcf.write(variant)
invcf.close()


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

"""
抓取英雄联盟英雄全皮肤
author: gxcuizy
date: 2018-11-13
"""

import requests
import json
from urllib import parse
import os

class GetLolSkin(object):
    """抓取LOL英雄皮肤"""

    def __init__(self):
        """初始化变量"""
        self.hero_url = 'https://lol.qq.com/biz/hero/champion.js'
        self.hero_detail_url = 'http://lol.qq.com/biz/hero/'
        self.skin_folder = 'skin'
        self.skin_url = 'https://ossweb-img.qq.com/images/lol/web201310/skin/big'

    @staticmethod
    def get_html(url):
        """下载html"""
        request = requests.get(url)
        request.encoding = 'gbk'
        if request.status_code == 200:
            return request.text
        else:
            return "{}"

    def get_hero_list(self):
        """获取英雄的完整信息列表"""
        hero_js = self.get_html(self.hero_url)
        # 删除左右的多余信息，得到json数据
        out_left = "if(!LOLherojs)var LOLherojs={};LOLherojs.champion="
        out_right = ';'
        hero_list = hero_js.replace(out_left, '').rstrip(out_right)
        return json.loads(hero_list)

    def get_hero_info(self, hero_id):
        """获取英雄的详细信息"""
        # 获取js详情
        detail_url = parse.urljoin(self.hero_detail_url, hero_id + '.js')
        detail_js = self.get_html(detail_url)
        # 删除左右的多余信息，得到json数据
        out_left = "if(!herojs)var herojs={champion:{}};herojs['champion'][%s]=" % hero_id
        out_right = ';'
        hero_info = detail_js.replace(out_left, '').rstrip(out_right)
        return json.loads(hero_info)

    def download_skin_list(self, skin_list, hero_name):
        """下载皮肤列表"""
        # 循环下载皮肤
        for skin_info in skin_list:
            # 拼接图片名字
            if skin_info['name'] == 'default':
                skin_name = '默认皮肤'
            else:
                if ' ' in skin_info['name']:
                    name_info = skin_info['name'].split(' ')
                    skin_name = name_info[0]
                else:
                    skin_name = skin_info['name']
            hero_skin_name = hero_name + '-' + skin_name + '.jpg'
            self.download_skin(skin_info['id'], hero_skin_name)

    def download_skin(self, skin_id, skin_name):
        """下载皮肤图片"""
        # 下载图片
        img_url = self.skin_url + skin_id + '.jpg'
        request = requests.get(img_url)
        if request.status_code == 200:
            print('downloading……%s' % skin_name)
            img_path = os.path.join(self.skin_folder, skin_name)
            with open(img_path, 'wb') as img:
                img.write(request.content)
        else:
            print('img error!')

    def make_folder(self):
        """初始化，创建图片文件夹"""
        if not os.path.exists(self.skin_folder):
            os.mkdir(self.skin_folder)

    def run(self):
        # 获取英雄列表信息
        hero_json = self.get_hero_list()
        hero_keys = hero_json['keys']
        # 循环遍历英雄
        for hero_id, hero_code in hero_keys.items():
            hero_name = hero_json['data'][hero_code]['name']
            hero_info = self.get_hero_info(hero_id)
            if hero_info:
                skin_list = hero_info['result'][hero_id]['skins']
                # 下载皮肤
                self.download_skin_list(skin_list, hero_name)
            else:
                print('英雄【%s】的皮肤获取有问题……' % hero_name)

# 程序执行入口
if __name__ == '__main__':
    lol = GetLolSkin()
    # 创建图片存储文件
    lol.make_folder()
    # 执行脚本
    lol.run()


# Text analyzing in PDF via GUI
import PyPDF2
import re
import tkinter as tk
from tkinter import filedialog as fd
import openpyxl
from itertools import tee, islice, chain

# To control words combination is trying to be able to find previous, current and next words
def previous_and_next(some_iterable):
    prevs, items, nexts = tee(some_iterable, 3)
    prevs = chain([None], prevs)
    nexts = chain(islice(nexts, 1, None), [None])
    return zip(prevs, items, nexts)

def search(myDict, lookup):
    for key, value in myDict.items():
        if lookup.lower() == value.lower():
            return key

# Integer is finding in text to sort descending
def sort_fn(x):
    y = x.find(":")
    z = x.find(" %")
    return int(x[y + 2:z])  # After : character rest of ist numeric

def SrtFn(x):
    y = x.find(":")
    return int(x[y + 3:-1])   # After : character rest of ist numeric

def remove_values_from_list(main_list, omitted_list):
    return [value for value in main_list if value.strip() not in omitted_list]

def dialog_window():
    entry.delete(0, fd.END)
    global filename
    filename = fd.askopenfilename(title="Select A File", filetypes=(("PDF Files", "*.pdf"), ("All Files", "*.*")))
    entry.insert(0, filename)
    return filename

def run():
    n_page = 0
    Uniqgroup = []
    UniqList = []
    t_Word = []

    # Twits' words are being compared with main category in excel
    wb = openpyxl.load_workbook('Word_Glossory.xlsx')
    sh = wb['Sheet1']
    glos = []

    file = open(filename, 'rb')  # Name of the PDF
    p_count = PyPDF2.PdfFileReader(file).numPages

    while n_page < p_count:
        p_Word = PyPDF2.PdfFileReader(file).getPage(n_page).extractText().split()
        t_Word.extend(p_Word)
        n_page += 1

    for item in t_Word:
        if re.search(r'\(|\)|/|[^a-zA-ZäÄöÖüÜß]', item):
            loc = t_Word.index(item)
            t_Word.remove(item)
            t_Word.insert(loc, re.sub(r'\(+|\)+|/+|[^a-zA-ZäÄöÖüÜß]+', "", item))

    # transform lowercase
    t_Word = [x.lower() for x in t_Word]

    stop_words = ["a", "about", "above", "after", "again", "against", "ain", "all", "am", "an", "and", "any", "are",
                  "aren", "aren't", "as", "at", "be", "because", "been", "before", "being", "below", "between", "both",
                  "but", "by", "can", "couldn", "couldn't", "d", "did", "didn", "didn't", "do", "does", "doesn",
                  "doesn't", "doing", "don", "don't", "down", "during", "each", "few", "for", "from", "further",
                  "had", "hadn", "hadn't", "has", "hasn", "hasn't", "have", "haven", "haven't", "having", "he", "her",
                  "here", "hers", "herself", "him", "himself", "his", "how", "i", "if", "in", "into", "is", "isn",
                  "isn't", "it", "it's", "its", "itself", "just", "ll", "m", "ma", "me", "mightn", "mightn't", "more",
                  "most", "mustn", "mustn't", "my", "myself", "needn", "needn't", "no", "nor", "not", "now", "o", "of",
                  "off", "on", "once", "only", "or", "other", "our", "ours", "ourselves", "out", "over", "own", "re",
                  "s", "same", "shan", "shan't", "she", "she's", "should", "should've", "shouldn", "shouldn't", "so",
                  "some", "such", "t", "than", "that", "that'll", "the", "their", "theirs", "them", "themselves",
                  "then", "there", "these", "they", "this", "those", "through", "to", "too", "under", "until", "up",
                  "ve", "very", "was", "wasn", "wasn't", "we", "were", "weren", "weren't", "what", "when", "where",
                  "which", "while", "who", "whom", "why", "will", "with", "won", "won't", "wouldn", "wouldn't", "y",
                  "you", "you'd", "you'll", "you're", "you've", "your", "yours", "yourself", "yourselves", "could",
                  "he'd", "he'll", "he's", "here's", "how's", "i'd", "i'll", "i'm", "i've", "let's", "ought", "she'd",
                  "she'll", "that's", "there's", "they'd", "they'll", "they're", "they've", "we'd", "we'll", "we're",
                  "we've", "what's", "when's", "where's", "who's", "why's", "would", ""]

    # Remove stopwords from main list
    t_Word = remove_values_from_list(t_Word, stop_words)

    # Excel columns was added in a dictionary to be able to search and to find word category
    group_dict = dict((g_word.value, word.value) for g_word, word in sh['A1':'B' + str(len(sh['B']))])

    # To look words combination previous, current and next words combine with each other
    for prev, current, nxt in previous_and_next(t_Word):
        try:
            if search(group_dict, current):
                glos += [search(group_dict, current)]

            if search(group_dict, prev + ' ' + current):
                glos += [search(group_dict, prev + ' ' + current)]

            if search(group_dict, prev + ' ' + current + ' ' + nxt):
                glos += [search(group_dict, prev + ' ' + current + ' ' + nxt)]

            if not (search(group_dict, current) or search(group_dict, prev + ' ' + current) or search(group_dict, prev + ' ' + current + ' ' + nxt)):
                glos += ["Words not yet grouped"]
        except TypeError:
            continue

    # All occurrence are being counted and being calculated frequency
    for item in glos:
        num = glos.count(item)
        density = item + "\t" * 3 + ": " + str(round((num / len(glos)) * 100)) + ' %' + ' (' + str(num) + ' times)'

        # get rid of from duplicated data
        if density not in Uniqgroup:
            Uniqgroup.append(density)

    # Sort as descending
    checkList = sorted(Uniqgroup, key=sort_fn, reverse=True)

    for item in t_Word:
        num = t_Word.count(item)
        denst = item.lower() + "\t\t : (" + str(num) + ")"

        if denst not in UniqList:   # get rid of from duplicated data
            UniqList.append(denst)

    srtList = sorted(UniqList, key=SrtFn, reverse=True)

    title = " WORDS GROUP" + " " * 22 + "RATE" + "\n" + "-" * 70 + "\n"

    scrollbar = tk.Scrollbar(lower_frame)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    textbox = tk.Text(lower_frame)
    textbox.place(relwidth=0.95, relheight=1)
    textbox["font"] = ("Arial", "10")
    textbox.insert(1.0, title + "\n".join(checkList) + "\n" + "-"*70 + "\n\t\t ALL WORDS \n" + "-"*70 + "\n" + "\n".join(srtList))

    textbox.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=textbox.yview)

# For Window
root = tk.Tk()
root.title("Report")
root.geometry("650x500")

frame = tk.Frame(root, bg='#DDB6C6', bd=5)
frame.place(relx=0.55, rely=0.05, relwidth=0.85, relheight=0.1, anchor='n')

frame_file = tk.Frame(root, bg='#DDB6C6', bd=5)
frame_file.place(relx=0.075, rely=0.05, relwidth=0.1, relheight=0.1, anchor='n')

entry = tk.Entry(frame, font=("Arial", 10))
entry.place(relwidth=0.680, relheight=1)

button = tk.Button(frame, text='Get Result', bd=2.5, fg='#484C7F', command=lambda: run())
button.place(relx=0.7, relheight=1, relwidth=0.3)

lower_frame = tk.Frame(root, bg='#DDB6C6', bd=7.5)
lower_frame.place(relx=0.5, rely=0.175, relwidth=0.95, relheight=0.75, anchor='n')

label_text = tk.Label(lower_frame, text="")
label_text.place(relwidth=1, relheight=1)

# label2 = tk.Label(root, text="URL :")
# label2.place(relx=0.06, rely=0.12)

button_file = tk.Button(frame_file, text="File  :  ", bd=2.5, fg='#484C7F', command=lambda: dialog_window())
button_file.place(relheight=1)

root.mainloop()


#!/bin/python

import sys, rospy, utils
from geometry_msgs.msg import Point
from nav_msgs.srv import GetPlan

## A route representation
#
# Gets a list of points, and calculates a circular route (an order by which these points need to be visisted)
# Provides a method to iterate over these points and a counter property that tracks the number of points visited in each round.
class Route:

    MAKE_PLAN_SERVICE_NAME = "move_base_node/make_plan"

    def __init__(self, current_location):
        self.__plan_client = rospy.ServiceProxy(self.MAKE_PLAN_SERVICE_NAME, GetPlan)
        rospy.wait_for_service(self.MAKE_PLAN_SERVICE_NAME)
        self.__points = utils.get_points_list_from_rosparams()
        self.__route = {}
        self.__distances = {}
        self.__current_point = utils.Point(*current_location)
        self.__find_shortest_path()
        self.__points_counter = -1

    @property
    def per_round_points_counter(self):
        return self.__points_counter % len(self.__points)

    ## Uses GetPlan to calculate the real distance between two points.
    def __get_distance(self, first_point, second_point):
        start = utils.create_pose(first_point)
        goal = utils.create_pose(second_point)
        tolerance = 0.5
        responce = self.__plan_client(start=start, goal=goal, tolerance=tolerance)
        points = map(lambda x: x.pose.position, responce.plan.poses)
        return sum([utils.distance(points[i+1], points[i]) for i in xrange(len(points)-1)])

    ## Selects a closest point from a list
    #
    # @return the closest point (from points_list) to current_point and the distance to that point.
    def __nearest_point(self, current_point, points_list):
        distances = map(self.__get_distance, [current_point]*len(points_list), points_list)
        result = min(zip(distances, points_list))
        return tuple(reversed(result))

    ## Finds a route between all points contained in self.__points.
    # Fills self.__route and self.__distances accordingly.
    #
    # Uses Nearest Neighbour algorithm for the route calculation.
    def __find_shortest_path(self):
        points = set(self.__points)
        visited_points = set()
        current_point = self.__current_point
        while not points.issubset(visited_points):
            self.__route[current_point], self.__distances[current_point] = self.__nearest_point(current_point, points - visited_points)
            current_point = self.__route[current_point]
            visited_points.add(current_point)
        self.__route[current_point] = self.__route[self.__current_point]
        self.__distances[current_point] = self.__get_distance(current_point, self.__route[current_point])

    ## Gets the next point in route to go to
    #
    # @return the next point in route and distance to travel to that point.
    def next_in_route(self):
        distance = self.__distances.get(self.__current_point)
        self.__current_point = self.__route.get(self.__current_point)
        self.__points_counter += 1
        return self.__current_point, distance


import sys
import asyncore

from ..game import Game, InvalidMove, coord_in_mini_board

COLORS = {
        'default'    :    '\033[0m',

        'bold'       :    '\033[1m',
        'underline'  :    '\033[4m',
        'blink'      :    '\033[5m',
        'reverse'    :    '\033[7m',
        'concealed'  :    '\033[8m',

        'black'      :    '\033[30m',
        'red'        :    '\033[31m',
        'green'      :    '\033[32m',
        'yellow'     :    '\033[33m',
        'blue'       :    '\033[34m',
        'magenta'    :    '\033[35m',
        'cyan'       :    '\033[36m',
        'white'      :    '\033[37m',

        'on_black'   :    '\033[40m',
        'on_red'     :    '\033[41m',
        'on_green'   :    '\033[42m',
        'on_yellow'  :    '\033[43m',
        'on_blue'    :    '\033[44m',
        'on_magenta' :    '\033[45m',
        'on_cyan'    :    '\033[46m',
        'on_white'   :    '\033[47m' }

class StdinWatcher(asyncore.file_dispatcher):
    def __init__(self, ui):
        super(StdinWatcher, self).__init__(sys.stdin)
        self._ui = ui

    def handle_read(self):
        self._ui.on_keyboard_input(self.recv(1024).decode('utf8'))

class ConsoleUi:
    def __init__(self):
        self._watcher = StdinWatcher(self)
        self._waiting_for_move = False
        self._input_buffer = ''

    def set_handler(self, handler):
        self._handler = handler

    def on_join_match_reply(self, reply, match):
        print('Joined match %s. %i user(s) in.' %
                (match.match_id, len(match.users)))
        print('If you want another user to join the match, tell them to run ')
        print('this command (and to replace NICKNAME with their nickname):')
        print('./inceptoe-client.py %s %i NICKNAME %s' %
                (self._handler._host, self._handler._port, match.match_id))

    def on_new_game(self, obj, game):
        self._char = obj['your_char']
        self.on_make_move(obj, game)

    def on_make_move(self, obj, game):
        self.print_game(game)
        winner = game.board_winner()
        if winner is None and game.current_player == self._char:
            self.play(game)
        elif winner is not None:
            print('%s won.' % winner)
        else:
            print('%s\'s turn.' % game.current_player)

    def print_game(self, game):
        if game.last_move is not None:
            (last_char, last_line, last_column) = game.last_move
            expected_mini_board = coord_in_mini_board(last_line, last_column)
            if game.mini_board_winner(*expected_mini_board) is not None:
                expected_mini_board = (-1, -1)
        else:
            expected_mini_board = (-1, -1)
        print('      1 2 3       4 5 6       7 8 9')
        print('  ' + ('+-----------'*3) + '+')
        letter = ord('A')
        for l1 in range(0, 3):
            mini_boards = []
            for c1 in range(0, 3):
                s = []
                color = ''
                winner = game.mini_board_winner(l1, c1)
                if (l1, c1) == expected_mini_board:
                    color = COLORS['on_blue']
                elif winner == 'X':
                    color = COLORS['on_red']
                elif winner == 'O':
                    color = COLORS['on_green']
                border = color + '  ' + COLORS['default']
                s.append(color + (' '*11) + COLORS['default'])
                s.append(border + '+-+-+-+' + border)
                for l2 in range(l1*3, l1*3+3):
                    s2 = border + '|'
                    for c2 in range(c1*3, c1*3+3):
                        if game.grid[l2][c2] == 'O':
                            s2 += COLORS['on_green']
                        elif game.grid[l2][c2] == 'X':
                            s2 += COLORS['on_red']
                        s2 += game.grid[l2][c2]
                        s2 += COLORS['default']
                        s2 += '|'
                    s2 += border
                    s.append(s2)
                    s.append(border + '+-+-+-+' + border)
                s.append(s[0])
                mini_boards.append(s)
            for (i, line) in zip([0, 0, 1, 0, 1, 0, 1, 0, 0], zip(*mini_boards)):
                if i:
                    prefix = chr(letter)
                    letter += 1
                else:
                    prefix = ' '
                print(prefix + ' |' + ('|'.join(line)) + '|')
            print('  ' + ('+-----------'*3) + '+')

    def play(self, game):
        sys.stdout.write('Move? ')
        sys.stdout.flush()
        self._waiting_for_move = True
        self._game = game

    def on_keyboard_input(self, input_):
        self._input_buffer += input_
        messages = self._input_buffer.split('\n')
        self._input_buffer = messages[-1]
        messages = messages[0:-1]

        for message in filter(bool, messages):
            if self._waiting_for_move:
                if self.make_move(message):
                    self._waiting_for_move = False
                else:
                    self._handler.send_message(message)
            else:
                self._handler.send_message(message)

    def make_move(self, move):
        """Tried to make a move.

        :param move: A string that is either a message or a move
        :returns: True if it is a move, False otherwise (ie. it's a message).
        """
        if len(move) != 2:
            return False
        (line, column) = move
        line = ord(line.lower()) - ord('a')
        if not (0 <= line <= 8):
            return False
        if not column.isdigit() or not (1 <= int(column) <= 9):
            return False
        column = int(column)-1

        try:
            self._game.make_move(line, column, apply_=False)
        except InvalidMove as e:
            print('Invalid move: %s' % e.args[0])
            return False
        else:
            self._handler.make_move(line, column)
            return True

    def on_message(self, obj, t):
        (match_id, from_, message) = t
        if self._waiting_for_move:
            prompt = 'Move? '
            backspaces = '\b'*len(prompt)
        else:
            backspaces = prompt = ''
        sys.stdout.write('%s<%s> %s\n%s' % (backspaces, from_, message, prompt))
        sys.stdout.flush()

    def handle_connection_closed(self):
        print('Server closed connection.')
        exit()


from scipy.linalg import block_diag
from copy import deepcopy, copy
import rospy
import numpy as np

from system.RobotState import RobotState
from utils.Landmark import LandmarkList
from utils.utils import wrap2Pi

class UKF:
    # UKF construct an instance of this class
    #
    # Inputs:
    #   system: system and noise models
    #   init:   initial state mean and covariance

    def __init__(self, system, init):

        self.gfun = system.gfun  # motion model
        self.hfun = system.hfun  # measurement model
        self.M = system.M # motion noise covariance
        self.Q = system.Q # measurement noise covariance

        self.kappa_g = init.kappa_g

        self.state_ = RobotState()
        self.state_.setState(init.mu)
        self.state_.setCovariance(init.Sigma)

    def prediction(self, u):
        # prior belief
        X = self.state_.getState()
        P = self.state_.getCovariance()

        ###############################################################################
        # TODO: Implement the prediction step for UKF                                 #
        # Hint: save your predicted state and cov as X_pred and P_pred                #
        ###############################################################################

        M_t = self.M(u)
        Q_t = self.Q

        mu_a_t__1 = np.concatenate((X.transpose(), np.zeros(3).transpose(), np.zeros(2).transpose())).reshape(-1,1)
        sigma_a_t__1 = block_diag(P, M_t, Q_t)
        self.sigma_point(mu_a_t__1 , sigma_a_t__1, self.kappa_g)

        self.X_dash_x_t = np.zeros_like(self.X[0:3,:])
        for i in range(len(self.X[0])):
            self.X_dash_x_t[:,i] = self.gfun(self.X[0:3,i],u + self.X[3:6,i])

        mew_dash_t = np.zeros_like(self.X_dash_x_t[:,0])
        for j in range(len(self.X[0])):
            mew_dash_t += self.w[j] * self.X_dash_x_t[:,j]

        mew_dash_t[2] = wrap2Pi(mew_dash_t[2])

        sigma_dash_t = np.zeros((3,3))
        for k in range(len(self.X[0])):
            mat = self.X_dash_x_t[:,k] - mew_dash_t
            mat[2] = wrap2Pi(mat[2])
            placeholder = self.w[k] * mat.reshape(3,1) @ mat.reshape(1,3)
            sigma_dash_t += placeholder

        X_pred =  mew_dash_t

        P_pred =  sigma_dash_t + M_t

        ###############################################################################
        #                         END OF YOUR CODE                                    #
        ###############################################################################

        self.state_.setTime(rospy.Time.now())
        self.state_.setState(X_pred)
        self.state_.setCovariance(P_pred)

    def correction(self, z, landmarks):

        X_predict = self.state_.getState()
        P_predict = self.state_.getCovariance()

        landmark1 = landmarks.getLandmark(z[2].astype(int))
        landmark2 = landmarks.getLandmark(z[5].astype(int))

        ###############################################################################
        # TODO: Implement the correction step for EKF                                 #
        # Hint: save your corrected state and cov as X and P                          #
        # Hint: you can use landmark1.getPosition()[0] to get the x position of 1st   #
        #       landmark, and landmark1.getPosition()[1] to get its y position        #
        ###############################################################################

        Z_t = np.zeros((4,len(self.X[0])))

        for i in range(len(self.X[0])):

            Z_t[0:2,i] = self.hfun(landmark1.getPosition()[0], landmark1.getPosition()[1], self.X_dash_x_t[:,i]) + self.X[6:,i]
            Z_t[2:,i] = self.hfun(landmark2.getPosition()[0], landmark2.getPosition()[1], self.X_dash_x_t[:,i]) + self.X[6:,i]

            Z_t[0] = wrap2Pi(Z_t[0])
            Z_t[2] = wrap2Pi(Z_t[2])

        z_t = np.zeros((len(self.w[0] * Z_t[:,0])))
        for i in range(len(self.X[0])):
            z_t += self.w[i] * Z_t[:,i]

        z_t[0] = wrap2Pi(z_t[0])
        z_t[2] = wrap2Pi(z_t[2])

        placeholder_0 = self.w[0] * (Z_t[:,0] - z_t).reshape(4,1) @ (Z_t[:,0] - z_t).reshape(1,4)
        S_t = np.zeros(placeholder_0.shape)
        for i in range(len(self.X[0])):
           S_t += self.w[i] * (Z_t[:,i] - z_t).reshape(4,1) @ (Z_t[:,i] - z_t).reshape(1,4)
        S_t += np.kron(np.eye(2),self.Q[0:2,0:2])

        placeholder_1= self.w[0] * (self.X_dash_x_t[:,0] - X_predict).reshape(3,1) @ (Z_t[:,0] - z_t).reshape(1,4)
        sigma_xz_t = np.zeros(placeholder_1.shape)
        for i in range(len(self.X[0])):
            sigma_xz_t += self.w[i] * (self.X_dash_x_t[:,i] - X_predict).reshape(3,1) @ (Z_t[:,i] - z_t).reshape(1,4)

        K_t = np.dot(sigma_xz_t,np.linalg.inv(S_t))
        z_t_without_hat = np.hstack((z[0:2],z[3:5]))
        delta_t = (z_t_without_hat - z_t).reshape(4,1)

        mew____t = X_predict.reshape(3,1) + (K_t @ delta_t).reshape(3,1)
        mew____t[2] = wrap2Pi(mew____t[2])
        X = mew____t.reshape(3,)

        sigma__t = P_predict - (K_t @ S_t @ np.transpose(K_t))
        P = sigma__t

        ###############################################################################
        #                         END OF YOUR CODE                                    #
        ###############################################################################

        self.state_.setTime(rospy.Time.now())
        self.state_.setState(X)
        self.state_.setCovariance(P)

    def sigma_point(self, mean, cov, kappa):
        self.n = len(mean) # dim of state
        L = np.sqrt(self.n + kappa) * np.linalg.cholesky(cov)
        Y = mean.repeat(len(mean), axis=1)
        self.X = np.hstack((mean, Y+L, Y-L))
        self.w = np.zeros([2 * self.n + 1, 1])
        self.w[0] = kappa / (self.n + kappa)
        self.w[1:] = 1 / (2 * (self.n + kappa))
        self.w = self.w.reshape(-1)

    def getState(self):
        return deepcopy(self.state_)

    def setState(self, state):
        self.state_ = state


#!/usr/bin/env python
import argparse
import pprint as pp
import re
import os

gdb_string="""arm-none-eabi-gdb -i=mi  -iex \\\"target remote :{gdb_port}\\\"  -ex \\\"monitor reset\\\" -ex \\\"b main\\\" -ex \\\"continue\\\" -ex \\\"delete 1\\\" {elf}"""

dir_local = """
((nil . (
   (company-clang-arguments . ({company-clang-arguments}))
   (c-eldoc-includes        . "{c-eldoc-include}")
   (gud-gdb-command-name    . "{gud-gdb-command-name}")

)))

"""

defs = ["-D__STATIC_INLINE= "]

def get_args():
    """
    Convert CFLAGS (gcc/clang options) to an emacs-lisp .dir-locals.el file
    for company-clang and c-eldoc
    """

    parser = argparse.ArgumentParser(description="""
Put description of application here
                   """)
    parser.add_argument('--cflags', action='store', dest='cflags',
                        help='gcc/clang option line (quoted)')
    parser.add_argument('--elf', action='store', dest='elf',
                        help='Project final elf file, full path')

    parser.add_argument('--gdb_port', action='store', dest='gdb_port',
                        help='Port used by gdb server')

    parser.add_argument('--elisp', action='store', dest='elisp',
                        help='elisp file to be generated')

    parser.add_argument('--version', action='version', version='%(prog)s 0.1')

    return parser.parse_args()

if __name__ == '__main__':
    args = get_args()
    # print ">" + args.cflags + "<"
    cflags = args.cflags[1:-1]
    # Remove the baskslah introduced in the  Makefile

    # print ">>" + cflags + "<<"
    inc_dirs = re.findall(r"-I\s*\S+", cflags)
    defs += (re.findall(r"-D\s*\S+", cflags))
    # remove -I
    inc_dirs_noinc = [x.replace('-I', '').strip() for x in inc_dirs]
    pp.pprint(defs)
    inc_dirs_abs = [os.path.abspath(x) for x in inc_dirs_noinc]
    inc_dirs_quoted = ["\"-I" + x + "\"" for x in inc_dirs_abs]
    inc_dirs_unquoted = ["-I" + x for x in inc_dirs_abs]
    defs_quoted = ["\"" + x + "\"" for x in defs]
    inc_as_one_string = ' '.join(inc_dirs_unquoted)
    fmt = dict()
    fmt['company-clang-arguments'] = '\n'.join(inc_dirs_quoted+defs_quoted)
    fmt['c-eldoc-include'] = ' '.join(inc_dirs_unquoted + defs)
    gdb_cmd = gdb_string.format(gdb_port=args.gdb_port, elf=args.elf)
    fmt['gud-gdb-command-name'] = gdb_cmd
    txt = dir_local.format(**fmt)
    print(txt)
    with open(args.elisp, 'w') as fh:
        fh.write(txt)
        fh.close()


import keras
from keras.layers import Dense, Activation, Flatten, Conv2D, MaxPooling2D
from keras.models import Sequential
from keras.utils import to_categorical
import numpy as np
import matplotlib.pyplot as plt

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neural_network import MLPClassifier
#from sklearn import datasets, svm, metrics
#from sklearn.datasets import fetch_openml
import matplotlib.pyplot as plt
import ssl
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import LabelEncoder
import pylab as pl
ssl._create_default_https_context = ssl._create_unverified_context
def sort_by_target(mnist):
    reorder_train = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[:60000])]))[:, 1]
    reorder_test = np.array(sorted([(target, i) for i, target in enumerate(mnist.target[60000:])]))[:, 1]
    mnist.data[:60000] = mnist.data[reorder_train]
    mnist.target[:60000] = mnist.target[reorder_train]
    mnist.data[60000:] = mnist.data[reorder_test + 60000]
    mnist.target[60000:] = mnist.target[reorder_test + 60000]

try:
    from sklearn.datasets import fetch_openml
    mnist = fetch_openml('mnist_784', version=1, cache=True)
    mnist.target = mnist.target.astype(np.int8) # fetch_openml() returns targets as strings
    sort_by_target(mnist) # fetch_openml() returns an unsorted dataset
except ImportError:
    from sklearn.datasets import fetch_mldata
    mnist = fetch_mldata('MNIST original')

mnist_data = fetch_openml('mnist_784', version=1)
print ("keyes")
print(mnist_data.keys())

X, y = mnist.data, mnist.target
#X = mnist.data/ 255.
#y = mnist.target
train_X, test_X = X[:60000], X[60000:]
train_Y, test_Y = y[:60000], y[60000:]

#(train_X,train_Y), (test_X,test_Y) = fashion_mnist.load_data()

train_X = train_X.reshape(-1, 28,28, 1)
test_X = test_X.reshape(-1, 28,28, 1)

train_X = train_X.astype('float32')
test_X = test_X.astype('float32')
train_X = train_X / 255
test_X = test_X / 255

train_Y_one_hot = to_categorical(train_Y)
test_Y_one_hot = to_categorical(test_Y)

model = Sequential()

model.add(Conv2D(64, (3,3), input_shape=(28, 28, 1)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())
model.add(Dense(64))

model.add(Dense(10))
model.add(Activation('softmax'))

model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(),metrics=['accuracy'])

model.fit(train_X, train_Y_one_hot, batch_size=64, epochs=5)

test_loss, test_acc = model.evaluate(test_X, test_Y_one_hot)
print('Test loss', test_loss)
print('Test accuracy', test_acc)

predictions = model.predict(test_X)
print(np.argmax(np.round(predictions[0])))
print("confusion matrix")
print(confusion_matrix(validation_generator.classes, y_pred))

plt.imshow(test_X[0].reshape(28, 28), cmap = plt.cm.binary)
plt.show()


#!/usr/bin/env python3
import configparser
import os
from telethon import TelegramClient, types
from colorama import Fore, Back, Style
import sys

# Reading Configs
config = configparser.ConfigParser()
config.read("config.ini")
# Setting configuration values
api_id = config['Telegram']['api_id']
api_hash = config['Telegram']['api_hash']
api_hash = str(api_hash)
bot_username = config['Telegram']['bot_username']

# Creating the bot session
if not os.path.isfile(str(bot_username) + ".session"):
    print(Fore.GREEN + "[+] We are creating the session file for bot, input the bot token (i.e. 4509046619:LMnjdork...)" + Style.RESET_ALL)
bot = TelegramClient(bot_username, api_id, api_hash)

async def main():
    # Get the channel object
    entity = input("Type the scammer channel username (Starts with @, Telegram URL or entity ID): ")
    if entity.isnumeric():
        channel = int(entity)
    # Negative numbers
    elif entity[0] == '-':
        if entity[1:].isnumeric():
            channel = -abs(int(entity))
        else:
            channel = entity
    else:
        channel = entity

    channel = await bot.get_entity(channel)

    # Check if User
    if isinstance(channel, types.User):
        print("\n" + Back.WHITE + Fore.RED + "You can't do this because your input belongs to a user entity, not a channel" + Style.RESET_ALL)
        sys.exit(0)

    print(Fore.RED + "Are you sure?\nLeaving this channel means a lossing of doing other activities over the channel")
    answer = input("Type 'Yes' to proceed, anything to cancel: " + Style.RESET_ALL)
    if answer == 'Yes':
        try:
            await bot.delete_dialog(channel, revoke = True)
            print("\n" + Fore.GREEN + "Completed! Succesfully leaving the channel " + str(entity) + Style.RESET_ALL)
        except Exception as err:
            print(Exception, err)
            print("It might possible you see you're not a member of channel because you already previously left it")
    elif answer == 'yes':
        print(Fore.RED + "Please type Yes next time once you input the channel again" + Style.RESET_ALL)
        await main()
    elif answer == 'y':
        print(Fore.RED + "Please type Yes next time once you input the channel again" + Style.RESET_ALL)
        await main()
    elif answer == 'Y':
        print(Fore.RED + "Please type Yes next time once you input the channel again" + Style.RESET_ALL)
        await main()
    else:
        print("\n" + Back.WHITE + Fore.RED + "[-] Not leaving the channel " + str(entity) + " as you cancelled the operation" + Style.RESET_ALL)

with bot:
    bot.loop.run_until_complete(main())


from django.conf.urls import patterns, url
from fuel_tracker.views import main, vehicle, gas_company, gas_station, fuel_up

# Main URLs
urlpatterns = patterns('main',
    url(r'^$', main.index, name='main.index'),
    url(r'^register/$', main.register, name='main.register'),
    url(r'^login/$', main.user_login, name='main.login'),
    url(r'^logout/$', main.user_logout, name='main.logout'),
)
# Vehicle URLs
urlpatterns += patterns('',
    url(r'^vehicle/$', vehicle.index, name='vehicle.index'),
    url(r'^vehicle/add/$', vehicle.add, name='vehicle.add'),
    url(r'^vehicle/(?P<owner_name>\w+)/(?P<vehicle_nickname>\w+)/$', vehicle.detail, name='vehicle.detail'),
    url(r'^vehicle/(?P<owner_name>\w+)/(?P<vehicle_nickname>\w+)/edit/$', vehicle.edit, name='vehicle.edit'),
)
# Gas Company URLs
urlpatterns += patterns('',
    url(r'^gas_company/$', gas_company.index, name='gas_company.index'),
    url(r'^gas_company/add/$', gas_company.add, name='gas_company.add'),
)
# Gas Station URLs
urlpatterns += patterns('',
    url(r'^gas_station/$', gas_station.index, name='gas_station.index'),
    url(r'^gas_station/add/$', gas_station.add, name='gas_station.add'),
)
# Fuel Up URLs
urlpatterns += patterns('',
    url(r'^fuel_up/$', fuel_up.index, name='fuel_up.index'),
    url(r'^fuel_up/add/$', fuel_up.add, name='fuel_up.add'),
)


# This script calculates and plots the expected genetic distance differences
# between Hamming distance and Jukes-Cantor correction
# author: Jonas Ditz

#!/bin/python

import matplotlib.pyplot as plt
import numpy as np

################################################################

SEQ_LENGTH = 200.0

################################################################

def calculateJC(distances):
  distJC = []
  for dist in distances:
    jc = -3./4. * np.log(1 - 4./3. * (dist/SEQ_LENGTH))
    distJC.append(jc)
  return distJC

def calculateHam(distances):
  distHam = []
  for dist in distances:
    distHam.append(dist/SEQ_LENGTH)
  return distHam

if __name__ == '__main__':
  t = range(150)
  ham = calculateHam(t)
  jc = calculateJC(t)

  plt.plot(t, ham, 'bs', label='observed distance p')
  plt.plot(t, jc, 'g^', label='expected genetic distance d')
  plt.xlabel('number of differences between two sequences')
  plt.ylabel('distance')
  plt.legend(loc='best')
  plt.show()


#Valeurs aberrantes
import pandas
import numpy as np
import matplotlib.pyplot as plt

vols_MC = pandas.read_csv("./Data/vols_MC_cleaned.csv",sep=',',decimal=b',')

def retrait_valeurs_aberrantes(vols_MC):
    #moyenne des retards à l'arrivée
    moy_retard = np.mean(vols_MC['Retard_D'])
    #ecart type à l'arrivée
    ecarttype_retard = np.std(vols_MC['Retard_D'])

    #vols sans valeurs aberrantes
    vols_MC_opt = vols_MC[vols_MC['Retard_D'].apply(lambda x: (x < moy_retard + 20*ecarttype_retard))]

    return vols_MC_opt

#boxplot du retard / type d'avion (retard non moyen) avec valeurs aberrantes
vols_MC.boxplot('Retard_D', by='Type avion réalisé', figsize=(12, 8))
plt.show()

#boxplot du retard / type d'avion (retard non moyen) SANS valeurs aberrantes
vols_opt = retrait_valeurs_aberrantes(vols_MC)
vols_opt.boxplot('Retard_D', by='Type avion réalisé', figsize=(12, 8))
plt.show()


import os
import time

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class DowloadsHandler(FileSystemEventHandler):
    def __init__(self,
                 track_dir,
                 dest_dir):
        super(DowloadsHandler, self).__init__()
        self._folder_to_track = track_dir
        self._folder_destination = dest_dir

    def on_modified(self, event):
        for filename in os.listdir(self._folder_to_track):
            source_file = os.path.join(self._folder_to_track, filename)
            # Чекаем формат файла или директорию
            if os.path.isdir(source_file):
                file_format = 'folders'
            elif os.path.isfile(source_file):
                try:
                    file_format = filename.split('.')[-1]
                except IndexError:
                    file_format = 'unknowns'
            else:
                print('WTF is this?!')
            # Назначаем папку, в которой хранятся файлы данного формата
            destination_dir = os.path.join(self._folder_destination, file_format)
            # Если такой папки нет, то создаем ее
            if not os.path.exists(destination_dir):
                print('Такой штука нет')
                os.mkdir(destination_dir)

            # Определяем куда переместить файл
            destination_file = os.path.join(destination_dir, filename)
            # Перемещаем файлик
            os.rename(source_file, destination_file)

def handle_event(track_dir='/Users/antoncesnov/Downloads/',
                 dest_dir='/Users/antoncesnov/DownloadsMirror/'):
    handler = DowloadsHandler(track_dir=track_dir, dest_dir=dest_dir)
    observer = Observer()
    observer.schedule(handler, track_dir, recursive=True)
    observer.start()

    try:
        while True:
            time.sleep(10)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()


from itertools import count
from itertools import cycle

# итератор, генерирующий целые числа, начиная с указанного
for i in count(105):
    if i > 113:
        break
    print(i)

# итератор, повторяющий элементы некоторого списка, определенного заранее
l = ['spring', 'summer', 'autumn', 'winter']

c = 0
for i in cycle(l):
    if c >= 7:
        break
    print(i)
    c += 1


import os
import argparse

from kalaha.config import __version__, __app_name__

def get_parser():
    parser = argparse.ArgumentParser(
        prog=__app_name__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="Kalaha game",
        epilog="See 'kalaha <command> -h' for more information "
               "on a specific mode."
    )

    parser.add_argument("-V", "--version", action="version", version="v{}".format(__version__),
                        help="print version and exit")
    parser.add_argument("--log-level", default="DEBUG",
                        choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
                        help="set log level")

    subparsers = parser.add_subparsers(
        title="Available modes",
        metavar="",
        dest="mode"
    )

    # building executable
    server_parser = subparsers.add_parser(
        "server",
        aliases=["s"],
        formatter_class=argparse.RawDescriptionHelpFormatter,
        help="Host a game",
        description="Start a server to host a game of Kalaha."
    )

    server_parser.add_argument("-H", "--host", type=str, default="127.0.0.1",
                               help="hostname to bind to")
    server_parser.add_argument("-p", "--port", type=int, default=20202,
                               help="port to listen on")

    server_parser.add_argument("-mS", "--min-stones", type=int, default=0,
                               help="minimum amount of stones per pit")
    server_parser.add_argument("-MS", "--max-stones", type=int, default=100,
                               help="maximum amount of stones per pit")

    server_parser.add_argument("-bS", "--min-board", type=int, default=0,
                               help="minimum amount of pits per player")
    server_parser.add_argument("-BS", "--max-board", type=int, default=100,
                               help="maximum amount of pits per player")

    server_parser.add_argument("-MB", "--max-boards", type=int, default=100,
                               help="maximum amount of available boards")

    server_parser.add_argument("-tT", "--min-timeout", type=int, default=0,
                               help="minimum amount of seconds to wait for a turn")
    server_parser.add_argument("-TT", "--max-timeout", type=int, default=100,
                               help="maximum amount of seconds to wait for a turn")
    server_parser.add_argument("-r", "--remove-boards", action="store_true",
                               help="remove boards on game over")

    client_parser = subparsers.add_parser(
        "client",
        aliases=["c"],
        formatter_class=argparse.RawDescriptionHelpFormatter,
        help="Connect to a server",
        description="Connect to a server to play a game of Kalaha."
    )

    client_parser.add_argument("-H", "--host", type=str, default="127.0.0.1",
                               help="hostname to connect to")
    client_parser.add_argument("-p", "--port", type=int, default=20202,
                               help="port to connect to")
    client_parser.add_argument("--auto-play", "-ap", action="store_true",
                               help="start with auto-player enabled")
    client_parser.add_argument("--minimax-depth", "-md", type=int, default=4,
                               help="minimax depth")
    client_parser.add_argument("--auto-play-delay", "-apd", type=int, default=5,
                               help="delay of auto-play in seconds")
    client_parser.add_argument("--alpha-beta", "-ab", action="store_true",
                               help="enable alpha-beta pruning")
    client_parser.add_argument("--iterative-deepening", "-id", action="store_true",
                               help="enable iterative deepening")
    client_parser.add_argument("--highlight_moves", "-hm", action="store_true",
                               help="highlight pit calculated by auto-player before making move")
    return parser

def parse_args(args: list):
    parser = get_parser()
    args = parser.parse_args(args)

    if args.mode is None:
        parser.print_help()
        return
    else:
        args.host = os.getenv("HOST", args.host)
        args.port = int(os.getenv("PORT", args.port))
        args.log_level = os.getenv("LOG_LEVEL", args.log_level)

    if args.mode == "server":
        args.min_stones = int(os.getenv("MIN_STONES", args.min_stones))
        args.max_stones = int(os.getenv("MAX_STONES", args.max_stones))
        args.min_board = int(os.getenv("MIN_BOARD", args.min_board))
        args.max_board = int(os.getenv("MAX_BOARD", args.max_board))
        args.max_boards = int(os.getenv("MAX_BOARDS", args.max_boards))
        args.min_timeout = int(os.getenv("MIN_TIMEOUT", args.min_timeout))
        args.max_timeout = int(os.getenv("MAX_TIMEOUT", args.max_timeout))
        args.remove_boards = str(os.getenv("REMOVE_BOARDS", args.remove_boards)).lower() in ("true", "1", "t")
    elif args.mode == "client":
        args.minimax_depth = int(os.getenv("MINIMAX_DEPTH", args.minimax_depth))
        args.auto_play = str(os.getenv("AUTO_PLAY", args.auto_play)).lower() in ("true", "1", "t")
        args.auto_play_delay = int(os.getenv("AUTO_PLAY_DELAY", args.auto_play_delay))
        args.alpha_beta = str(os.getenv("ALPHA_BETA", args.alpha_beta)).lower() in ("true", "1", "t")
        args.iterative_deepening = str(os.getenv("ITERATIVE_DEEPENING",
                                                 args.iterative_deepening)).lower() in ("true", "1", "t")
        args.highlight_moves = str(os.getenv("HIGHLIGHT_MOVES", args.highlight_moves)).lower() in ("true", "1", "t")
    return args


"""
File: asteroids.py
Original Author: Br. Burton
Designed to be completed by Dhener Trinidad

This program implements the asteroids game.

My changes:
Added Background
Added sound for fire and hit
asteroid bounce to each other
limit the speed of the ship and make the direction where it is traveling the same with the angle or orientation.
If ship died. it will show a new Game Over view for game over and the time-lapse to finish the game + score penalty.
If all asteroids were destroyed, a new Game over view for congratulations and the time-lapse will appear
Added ship life and display mini ship on the top right corner that represents the ship
Score: the lower the better, penalty points will be added when you hit an asteroid
The Game() was also change from arcade.Window to arcade.View to make the change screen possible
main functions was added
############################################################################
week10 update:
bullet was corrected to have a life of 60 frames by counting the travel time via self.travel
For the ship to move easier, removed the bounce for ship and now only implement it with the asteroid
As part of the assesment guidline when asteroid and ship collide, it should break the asteroid
The ship now moving correctly and at a fix slower rate when the key is released
draw method in base class for flyingobjects and ship are no longer abstract, (changed this in week 11)
draw method were removed in subclasses because of the changes and added attributes/member variables instead
Week11:
To satisfy the assesment requirement for draw method,
    I have added the draw method back to each flying object
    and make a it an abstract method in flyingbase class again.
Added life for ship and it will blink when it by the asteroid
Removed the try/except for loading images, I finally found a fix in my issue with vs code
Penalty was added when an asteroid hit the ship, it varies base on asteroid size,

############################################################################
About the bounce:
    The bounce will make the game more realistic in a way that the asteroid have a chance to collide and bounce,
    Bounce might go to a totally opposite direction or just slide, or just move a little depending on the impact and angle

About Scoring and endgame:
    The ship will live until all the asteroids are gone.
    The score will depend on how long the player clears all the asteroids.
    The lower the score, the better.
    The game will end once all the asteroids were gone and the congratulatory message with the score will show at the center
############################################################################

"""
import arcade
import math
import random
from abc import ABC, abstractmethod
import time

# These are Global constants to use throughout the game
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

BULLET_RADIUS = 30
BULLET_SPEED = 10
BULLET_LIFE = 60

SHIP_TURN_AMOUNT = 3
SHIP_THRUST_AMOUNT = 0.25
SHIP_RADIUS = 30

INITIAL_ROCK_COUNT = 5

BIG_ROCK_SPIN = 1
BIG_ROCK_SPEED = 1.5
BIG_ROCK_RADIUS = 15

MEDIUM_ROCK_SPIN = -2
MEDIUM_ROCK_RADIUS = 5

SMALL_ROCK_SPIN = 5
SMALL_ROCK_RADIUS = 2

class Point:
    """
    This will provide the location of the object
    """
    def __init__(self):
        self.x = 0.00
        self.y = 0.00

class Velocity:
    """
    This helps in the movement of the object
    """
    def __init__(self):
        self.dx = 0
        self.dy = 0

class FlyingObject(ABC):
    """
    This will be the base class for flying objects
    """
    def __init__(self):
        self.center = Point()
        self.velocity = Velocity()
        self.alive = True #check if the object is still alive
        self.radius = 0.0
        self.angle = 0 #facing

        self.img = "images/bgu.jpg"
        self.texture = arcade.load_texture(self.img)
        self.width = self.texture.width
        self.height = self.texture.height
        self.alpha = 0

    @abstractmethod
    def draw(self):
        arcade.draw_texture_rectangle(self.center.x, self.center.y, self.width,
                self.height, self.texture, self.angle, self.alpha)

    def advance(self):

        """
        This will help in the movement of the object
        """
        self.center.x += self.velocity.dx #initial position += new possition
        self.center.y += self.velocity.dy #initial position += new possition

    def is_off_screen(self,width,height):
        """
        This will check if the object is off screen, sample, if an object goes off the right edge of the screen,
        it should appear on the left edge.
        """
        if self.center.x > width:
            self.center.x = 0
        elif self.center.x < 0:
            self.center.x = width
        elif self.center.y > height:
            self.center.y = 0
        elif self.center.y < 0:
            self.center.y = height

class Ship(FlyingObject):
    """
    This will have the ship functions and basic attributes
    """
    def __init__(self):
        super().__init__()
        self.angle = 0.00
        self.radius = SHIP_RADIUS
        self.center.x = SCREEN_WIDTH // 2
        self.center.y = SCREEN_HEIGHT //2
        self.life = 5

    def draw(self):
        self.img = "images/playerShip1_orange.png"
        self.texture = arcade.load_texture(self.img)
        self.width = self.texture.width
        self.height = self.texture.height
        super().draw()

    def advance(self):
        super().advance()
        #this will make the help looks blinking when hit by the asteroid, collission will set the alpha to 1
        if self.alpha <= 5:
            self.alpha += 1
            if self.alpha >= 5:
                self.alpha = 255

class Bullet(FlyingObject):
    def __init__(self):
        super().__init__()
        self.radius = BULLET_RADIUS
        self.travel = 0
        self.angle = self.angle + 90

    def draw(self):
        self.img = "images/laserBlue01.png"
        self.texture = arcade.load_texture(self.img)
        self.width = self.texture.width
        self.height = self.texture.height
        self.alpha = 255
        super().draw()

    def advance(self):
        super().advance()
        #travel represents the frame, it will die in 60 frames
        self.travel += 1
        if self.travel == BULLET_LIFE:
            self.alive = False

    def fire(self, ship):
        """
        This will give the movement for our bullet and angel for its direction
        """
        #get the position of the ship and angle
        self.center.x = ship.center.x
        self.center.y = ship.center.y
        self.angle += ship.angle
        #speed and angle of bullet when fired
        self.velocity.dx = math.cos(math.radians(ship.angle - 270)) * BULLET_SPEED
        self.velocity.dy = math.sin(math.radians(ship.angle - 270)) * BULLET_SPEED
        self.velocity.dx += ship.velocity.dx
        self.velocity.dy += ship.velocity.dy

class Asteroids(FlyingObject, ABC):
    def __init__(self):
        """
        Base class for asteroids
        """
        super().__init__()
        self.rotation = 0.00 #spin
        self.penalty = 0 #this will be added to the score when the asteroid hit the ship

    def advance(self):
        """
        This will help in the movement of the object
        """
        self.angle += self.rotation #spin
        self.center.x += self.velocity.dx #initial position += new possition
        self.center.y += self.velocity.dy #initial position += new possition

    @abstractmethod
    def hit(self):
        """

        """
        return

    def bounce_horizontal(self):
        """
        The asteroid will bounce when they hit each other
        """
        self.velocity.dx *= -1 #inverse the movement of the ball

    def bounce_vertical(self):
        """
        The asteroid will bounce when they hit each other
        """
        self.velocity.dy *= -1 #inverse the movement of the ball

class Largeasteroids(Asteroids):
    def __init__(self):
        super().__init__()
        #position
        self.center.x = random.uniform(0,SCREEN_HEIGHT)
        self.center.y = random.uniform(SCREEN_HEIGHT,SCREEN_WIDTH)
        #speed
        self.velocity.dx = random.uniform(-BIG_ROCK_SPEED,BIG_ROCK_SPEED)
        self.velocity.dy = random.uniform(-BIG_ROCK_SPEED,BIG_ROCK_SPEED)
        self.rotation = BIG_ROCK_SPIN
        self.radius = BIG_ROCK_RADIUS
        self.penalty = 10

    def draw(self):
        self.img = "images/meteorGrey_big1.png"
        self.texture = arcade.load_texture(self.img)
        self.width = self.texture.width
        self.height = self.texture.height
        self.alpha = 255
        super().draw()

    def hit(self):
        """
        split the asteroid
        """
        #create new asteroid from the current posstion of this asteroid
        particles = [Mediumasteroids(self.center), Mediumasteroids(self.center), Smallasteroids(self.center)]

        #get the speed of this asteroid and pass it to the new asteriods and give them direction + speed
        particles[0].velocity.dx = self.velocity.dx
        particles[0].velocity.dy = self.velocity.dy + 2 #go up

        particles[1].velocity.dx = self.velocity.dx
        particles[1].velocity.dy = self.velocity.dy + 2 * -1 #go down

        particles[2].velocity.dx = self.velocity.dx + 5 #to the right
        particles[2].velocity.dy = self.velocity.dy

        return particles

class Mediumasteroids(Asteroids):
    def __init__(self,asteroid_center):
        super().__init__()
        self.rotation = MEDIUM_ROCK_SPIN
        self.radius = MEDIUM_ROCK_RADIUS
        self.center.x = asteroid_center.x
        self.center.y = asteroid_center.y
        self.penalty = 6

    def draw(self):
        self.img = "images/meteorGrey_med1.png"
        self.texture = arcade.load_texture(self.img)
        self.width = self.texture.width
        self.height = self.texture.height
        self.alpha = 255
        super().draw()

    def hit(self):
        """
        split the asteroid
        """
        #create new asteroid from the current posstion of this asteroid
        particles = [Smallasteroids(self.center), Smallasteroids(self.center)]

        #get the speed of this asteroid and pass it to the new asteriods and give then direction + speed
        particles[0].velocity.dx = self.velocity.dx + 1.5
        particles[0].velocity.dy = self.velocity.dy + 1.5

        particles[1].velocity.dx = self.velocity.dx + 1.5 * -1
        particles[1].velocity.dy = self.velocity.dy + 1.5 * -1

        return particles

class Smallasteroids(Asteroids):
    def __init__(self,asteroid_center):
        super().__init__()
        self.rotation = SMALL_ROCK_SPIN
        self.radius = SMALL_ROCK_RADIUS
        self.center.x = asteroid_center.x
        self.center.y = asteroid_center.y
        self.penalty = 3

    def draw(self):
        self.img = "images/meteorGrey_small1.png"
        self.texture = arcade.load_texture(self.img)
        self.width = self.texture.width
        self.height = self.texture.height
        self.alpha = 255
        super().draw()

    def hit(self):
        """
        split the asteroid
        """
        #no new asteroid will be created
        particles = []
        return particles

class Game(arcade.View):
    """
    This class handles all the game callbacks and interaction

    This class will then call the appropriate functions of
    each of the above classes.

    You are welcome to modify anything in this class.
    """

    def __init__(self):
        """
        Sets up the initial conditions of the game
        :param width: Screen width
        :param height: Screen height
        """
        super().__init__()
        arcade.set_background_color(arcade.color.SMOKY_BLACK)

        self.held_keys = set()

        # TODO: declare anything here you need the game class to track
        self.ship = Ship()
        self.score = 0
        self.bullets = []
        self.asteroids = []
        self.background = arcade.load_texture("images/bgu.jpg")
        #create asteroids
        for i in range(5):
            asteroid = Largeasteroids()
            self.asteroids.append(asteroid)

        # my add on: Load sounds. Sounds from kenney.nl
        self.fire_sound = arcade.sound.load_sound(":resources:sounds/laser1.wav")
        self.hit_sound = arcade.sound.load_sound(":resources:sounds/explosion1.wav")

    def on_draw(self):
        """
        Called automatically by the arcade framework.
        Handles the responsibility of drawing all elements.
        """

        # clear the screen to begin drawing
        arcade.start_render()
        arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)

        # TODO: draw each object
        #draw bullets
        for bullet in self.bullets:
            bullet.draw()

        #draw asteroids
        for asteroid in self.asteroids:
            asteroid.draw()

        #do this when ship is alive
        if self.ship.alive:
            #draw the ship
            self.ship.draw()
            #draw the score
            self.draw_score()
            #draw the mini ships representing the ship life
            self.draw_ship_life()

        #if the ship has no more lives it will die
        if self.ship.life <= 0:
            self.ship.alive = False

        #if all the asteroids were cleared show congratulations if the ship died show game over
        if len(self.asteroids) == 0 or self.ship.alive == False:
            view = GameOver() #create and instance of gameover class
            view.score = self.score #copy the score to the gameoverclass
            view.asteroids = self.asteroids #copy the asteroids to the gameoverclass
            self.window.show_view(view) #show the gameoverview
            self.ship.alive = False #hide the ship

    def update(self, delta_time):
        """
        Update each object in the game.
        :param delta_time: tells us how much time has actually elapsed
        """
        self.check_keys()
        self.check_collisions()

        # TODO: Tell everything to advance or move forward one step in time
        self.ship.advance()
        self.ship.is_off_screen(SCREEN_WIDTH, SCREEN_HEIGHT)
        #move the bullets
        for bullet in self.bullets:
            bullet.advance()
            bullet.is_off_screen(SCREEN_WIDTH,SCREEN_HEIGHT)

        #move the asterois
        for asteroid in self.asteroids:
            asteroid.advance()
            asteroid.is_off_screen(SCREEN_WIDTH,SCREEN_HEIGHT)

        #add score while the ship alive
        if self.ship.alive:
            self.score += delta_time

        # TODO: Check for collisions
    def check_collisions(self):
        """
        Checks to see if bullets have hit asteroids.
        Updates scores and removes dead items.
        :return:
        """

        # NOTE: This assumes you named your asteroids list "asteroids"
        #on progress this should bounce the asteroid when it hit ship and other asteroid
        #ship and asteroid
        for asteroid in self.asteroids:

            # Make sure they are both alive before checking for a collision
            if self.ship.alive and asteroid.alive:
                    too_close = self.ship.radius + asteroid.radius

                    if (abs(self.ship.center.x - asteroid.center.x) < too_close and
                                abs(self.ship.center.y - asteroid.center.y) < too_close):

                            asteroid.alive = False
                            self.ship.life -= 1
                            self.ship.alpha = 1
                            self.score += asteroid.penalty #add the penalty score
                            self.asteroids += asteroid.hit() #add the new asteroids to current list
                            arcade.play_sound(self.hit_sound) #play the sound

        #asteroid to asteroid
        for asteroid1 in self.asteroids:
            for asteroid in self.asteroids:
            # Make sure they are both alive before checking for a collision
            #This will make the asteroid bounce when they hit eachother
                if asteroid1.alive and asteroid.alive:
                        too_close = asteroid1.radius + asteroid.radius

                        if (abs(asteroid1.center.x - asteroid.center.x) < too_close and
                                    abs(asteroid1.center.y - asteroid.center.y) < too_close):

                            if asteroid.center.x > asteroid1.center.x and asteroid.velocity.dx > asteroid1.velocity.dx:
                                asteroid.bounce_horizontal()

                            if asteroid.center.x < asteroid1.center.x and asteroid.velocity.dx < asteroid1.velocity.dx:
                                asteroid.bounce_horizontal()

                            if asteroid.center.y > asteroid1.center.y and asteroid.velocity.dy > asteroid1.velocity.dy:
                                asteroid.bounce_horizontal()

                            if asteroid.center.y < asteroid1.center.y and asteroid.velocity.dy < asteroid1.velocity.dy:
                                asteroid.bounce_horizontal()

        #bullets and asteroid
        for bullet in self.bullets:
            for asteroid in self.asteroids:

                # Make sure they are both alive before checking for a collision
                if bullet.alive and asteroid.alive:
                    too_close = bullet.radius + asteroid.radius

                    if (abs(bullet.center.x - asteroid.center.x) < too_close and
                                abs(bullet.center.y - asteroid.center.y) < too_close):
                        # its a hit!
                        bullet.alive = False #kill the bullet
                        asteroid.alive = False #kill the asteroid
                        self.asteroids += asteroid.hit() #add the new asteroids to current list
                        arcade.play_sound(self.hit_sound) #play sound

                        # We will wait to remove the dead objects until after we
                        # finish going through the list

        # Now, check for anything that is dead, and remove it
        self.cleanup_zombies()

    def cleanup_zombies(self):
        """
        Removes any dead bullets or asteroids from the list.
        :return:
        """
        #clean up bullets
        for bullet in self.bullets:
            if not bullet.alive:
                self.bullets.remove(bullet)

        #clean up asteroids
        for asteroid in self.asteroids:
            if not asteroid.alive:
                self.asteroids.remove(asteroid)

    def check_keys(self):
        """
        This function checks for keys that are being held down.
        You will need to put your own method calls in here.
        """
        if arcade.key.LEFT in self.held_keys:
            self.ship.angle += SHIP_TURN_AMOUNT

        if arcade.key.RIGHT in self.held_keys:
            self.ship.angle -= SHIP_TURN_AMOUNT

        if arcade.key.UP in self.held_keys:
            #move the ship
            self.ship.velocity.dx += math.cos(math.radians(self.ship.angle + 90)) * SHIP_THRUST_AMOUNT
            self.ship.velocity.dy += math.sin(math.radians(self.ship.angle + 90)) * SHIP_THRUST_AMOUNT

            #limit the speed of the ship
            if self.ship.velocity.dx > 10:
                self.ship.velocity.dx = 10

            if self.ship.velocity.dx < -10:
                self.ship.velocity.dx = -10

            if self.ship.velocity.dy > 10:
                self.ship.velocity.dy = 10

            if self.ship.velocity.dy < -10:
                self.ship.velocity.dy = -10

        if arcade.key.DOWN in self.held_keys:
            #move the ship
            self.ship.velocity.dx -= math.cos(math.radians(self.ship.angle + 90)) * SHIP_THRUST_AMOUNT
            self.ship.velocity.dy -= math.sin(math.radians(self.ship.angle + 90)) * SHIP_THRUST_AMOUNT

            #limit the speed of the ship
            if self.ship.velocity.dx > 10:
                self.ship.velocity.dx = 10

            if self.ship.velocity.dx < -10:
                self.ship.velocity.dx = -10

            if self.ship.velocity.dy > 10:
                self.ship.velocity.dy = 10

            if self.ship.velocity.dy < -10:
                self.ship.velocity.dy = -10

        # Machine gun mode...
        #if arcade.key.SPACE in self.held_keys:
        #    pass

    def on_key_press(self, key: int, modifiers: int):
        """
        Puts the current key in the set of keys that are being held.
        You will need to add things here to handle firing the bullet.
        """
        if self.ship.alive:
            self.held_keys.add(key)

            if key == arcade.key.SPACE:
                # TODO: Fire the bullet here!
                # Fire!
                ship = self.ship

                #get the instance of bullet then align it with the ship's location and angle
                bullet = Bullet()
                bullet.fire(ship)
                #my addtional sound
                arcade.play_sound(self.fire_sound) #playsound
                self.bullets.append(bullet) #add the new bullet to the list

    def on_key_release(self, key: int, modifiers: int):
        """
        Removes the current key from the set of held keys.
        """
        if key in self.held_keys:
            self.held_keys.remove(key)
            #slow down the ship but will still  looks like floating
            self.ship.velocity.dx = math.cos(math.radians(self.ship.angle + 90)) * SHIP_THRUST_AMOUNT
            self.ship.velocity.dy = math.sin(math.radians(self.ship.angle + 90)) * SHIP_THRUST_AMOUNT

    def draw_score(self):
        """
        Puts the current score on the screen
        """
        score_text = f"Time Lapse: {self.score}"
        start_x = 10
        start_y = SCREEN_HEIGHT - 20
        arcade.draw_text(score_text, start_x=start_x, start_y=start_y, font_size=12, color=arcade.color.WHITE_SMOKE)

    def draw_ship_life(self):
        """
        Draw the mini ships that represent the lives of the ship
        """
        x = 10 #position it to the left
        y = SCREEN_HEIGHT - 30 #position this to the top - 30
        for i in range(self.ship.life):
            img = "images/playerShip1_orange.png"
            texture = arcade.load_texture(img)
            width = texture.width // 4 #reduce the size
            height = texture.height // 4 #reduce the size
            angle = 0
            alpha = 255
            arcade.draw_texture_rectangle(x, y, width,
                    height, texture, angle, alpha)
            x += width #add the new mini ship beside the last ship created

class GameOver(arcade.View):
    """ View to show when game is over """
    def __init__(self):

        super().__init__()

        # Reset the viewport, necessary if we have a scrolling game and we need
        # to reset the viewport back to the start so we can see what we draw.
        arcade.set_viewport(0, SCREEN_WIDTH - 1, 0, SCREEN_HEIGHT - 1)

        arcade.set_background_color(arcade.color.SMOKY_BLACK)
        self.asteroids = []

        self.score = 0.00

    def on_draw(self):
        """ Draw this view """
        arcade.start_render()
        if len(self.asteroids) > 0:
            self.draw_game_over()
        else:
            self.draw_congratulations()

    def on_mouse_press(self, _x, _y, _button, _modifiers):
        """ If the user presses the mouse button, re-start the game. """
        game_view = Game()
        self.window.show_view(game_view)

    def draw_congratulations(self):
        """
        Print the message "Congratulations" and show the score(time lapse)
        """
        self.background = arcade.load_texture("images/congrats.png")
        arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
        lapse = f"Time Lapse: {self.score:.2f}"
        start_x = SCREEN_WIDTH // 2
        start_y = SCREEN_HEIGHT // 2
        arcade.draw_text(lapse, start_x=start_x, start_y=start_y, font_size= 20, color=arcade.color.WHITE, anchor_x="center")

    def draw_game_over(self):
        """
        Print the message "Game over" and show the score(time lapse)
        """
        self.background = arcade.load_texture("images/game_over.png")
        arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
        lapse = f"Time Lapse: {self.score:.2f}"
        start_x = SCREEN_WIDTH // 2
        start_y = SCREEN_HEIGHT // 2
        arcade.draw_text(lapse, start_x=start_x, start_y=start_y, font_size= 20, color=arcade.color.WHITE, anchor_x="center")

def main():
    """
    This will initiate the game
    """

    # Creates the game and starts it going
    window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT)
    start_view = Game()
    window.show_view(start_view)
    arcade.run()

if __name__ == "__main__":
    main()