#!/usr/bin/env python
"""orwellpivot.py: Create Pivot of AWS Workspaces Data"""

import pandas as pd
import numpy as np
import os
import glob

# owned
__author__ = 'Rich Bocchinfuso'
__copyright__ = 'Copyright 2020, Create Pivot of AWS Workspaces Data'
__credits__ = ['Rich Bocchinfuso']
__license__ = 'MIT'
__version__ = '0.2.0'
__maintainer__ = 'Rich Bocchinfuso'
__email__ = 'rbocchinfuso@gmail.com'
__status__ = 'Dev'

pd.set_option('colheader_justify', 'center')   # FOR TABLE

html_string = '''

  <title>HTML Pandas Dataframe Pivot Report with CSS</title>
  <link rel="stylesheet" type="text/css" href="df_style.css"/>

    {table}

.
'''

# set working directory
os.chdir("./output")

# find all csv files in the folder
# use glob pattern matching -> extension = 'csv'
# save result in list -> all_filenames
extension = 'csv'
all_filenames = [i for i in glob.glob('*.{}'.format(extension))]
# print(all_filenames)

#combine all files in the list
combined_csv = pd.concat([pd.read_csv(f) for f in all_filenames ])

# export to csv
combined_csv.to_csv( "../tmp/tmp_all_data.csv", index=False, encoding='utf-8-sig')

df = pd.read_csv("../tmp/tmp_all_data.csv").astype({"connection_hrs":float})
df.head()
print (df)

df["user_state"] = df["user_state"].astype("category")
df["user_state"].cat.set_categories(["ONLINE","OFFLINE"],inplace=True)

# pivot by date, user, user_state
table = pd.pivot_table(df.round(1),index=["log_datestamp","username"],values=["connection_hrs"], columns=["user_state"],aggfunc=[np.sum],fill_value=0)
print (table)

# render dataframe as html
with open('./reports/orwell_pivot_by_date.html', 'w') as f:
    f.write(html_string.format(table=table.to_html(classes='mystyle')))

# pivot by user, date, user_state
table = pd.pivot_table(df.round(1),index=["username","log_datestamp"],values=["connection_hrs"], columns=["user_state"],aggfunc=[np.sum],fill_value=0)
print (table)

# render dataframe as html
with open('./reports/orwell_pivot_by_user.html', 'w') as f:
    f.write(html_string.format(table=table.to_html(classes='mystyle')))

# pivot by user, date, user_state alternate view
table = pd.pivot_table(df.round(1),index=["username","user_state"],values=["connection_hrs"], columns=["log_datestamp"],aggfunc=[np.sum],fill_value=0)
print (table)

# render dataframe as html
with open('./reports/orwell_pivot_by_user_alt.html', 'w') as f:
    f.write(html_string.format(table=table.to_html(classes='mystyle')))

# pivot by user, date, user_state, hour
table = pd.pivot_table(df.round(1),index=["username","log_datestamp",'user_state'],values=["connection_hrs"], columns=["log_timestamp"],aggfunc=[np.sum],fill_value=0)
print (table)

# render dataframe as html
with open('./reports/orwell_pivot_by_hour.html', 'w') as f:
    f.write(html_string.format(table=table.to_html(classes='mystyle')))


"""

u are a renowned thief who has recently switched from stealing precious metals to stealing cakes because of the insane profit margins. You end up hitting the jackpot, breaking into the world’s largest privately owned stock of cakes—the vault of the Queen of England.

While Queen Elizabeth has a limited number of types of cake , she has an unlimited supply of each type .

Each type of cake has a weight and a value, stored in a tuple with two indices:

An integer representing the weight of the cake in kilograms
An integer representing the monetary value of the cake in British shillings
For example:

# Weighs 7 kilograms and has a value of 160 shillings
(7, 160)

# Weighs 3 kilograms and has a value of 90 shillings
(3, 90)
You brought a duffel bag that can hold limited weight, and you want to make off with the most valuable haul possible.

Write a function get_max_value() that takes a list of cake type tuples and a weight capacity , and returns the maximum monetary value the duffel bag can hold.

For example:

cake_tuples = [(7, 160), (3, 90), (2, 15)]
capacity    = 20

# Returns 555 (6 of the middle type of cake and 1 of the last type of cake)
get_max_value(cake_tuples, capacity)
Weights and values may be any non-negative integer. Yes, it’s weird to think about cakes that weigh nothing or duffel bags that can’t hold anything. But we’re not just super mastermind criminals—we’re also meticulous about keeping our algorithms flexible and comprehensive.
"""
def get_max_value(cake_tuples, max_capacity):
    #index is the capacity and value is the value at that capacity
    max_vals_at_capacity = [0] * (max_capacity + 1)
    for capacity in range(max_capacity + 1):
        current_max = 0
        for weight, value in cake_tuples:
            #edge cases
            if(weight == 0 and value > 0):
                return float('inf')
            if(weight == 0 and value == 0):
                return 0
            #valid cake to include in the bag
            if(weight <= capacity):
                max_val_using_cake = value + max_vals_at_capacity[capacity-weight]
                current_max = max(current_max, max_val_using_cake)
        max_vals_at_capacity[capacity] = current_max
    return max_vals_at_capacity[max_capacity]

import unittest

# Tests

class Test(unittest.TestCase):

    def test_one_cake(self):
        actual = get_max_value([(2, 1)], 9)
        expected = 4
        self.assertEqual(actual, expected)

    def test_two_cakes(self):
        actual = get_max_value([(4, 4), (5, 5)], 9)
        expected = 9
        self.assertEqual(actual, expected)

    def test_only_take_less_valuable_cake(self):
        actual = get_max_value([(4, 4), (5, 5)], 12)
        expected = 12
        self.assertEqual(actual, expected)

    def test_lots_of_cakes(self):
        actual = get_max_value([(2, 3), (3, 6), (5, 1), (6, 1), (7, 1), (8, 1)], 7)
        expected = 12
        self.assertEqual(actual, expected)

    def test_value_to_weight_ratio_is_not_optimal(self):
        actual = get_max_value([(51, 52), (50, 50)], 100)
        expected = 100
        self.assertEqual(actual, expected)

    def test_zero_capacity(self):
        actual = get_max_value([(1, 2)], 0)
        expected = 0
        self.assertEqual(actual, expected)

    def test_cake_with_zero_value_and_weight(self):
        actual = get_max_value([(0, 0), (2, 1)], 7)
        expected = 3
        self.assertEqual(actual, expected)

    def test_cake_with_non_zero_value_and_zero_weight(self):
        actual = get_max_value([(0, 5)], 5)
        expected = float('inf')
        self.assertEqual(actual, expected)

unittest.main(verbosity=2)


from flask import Flask, redirect, url_for, render_template, url_for, request, session, flash
import sqlite3
import json
from collections import defaultdict
import pandas as pd
import numpy as np
from sklearn.neighbors import NearestNeighbors
from werkzeug.utils import secure_filename
from data_uploader import upload_data
import os
import utils
from datetime import date

app = Flask(__name__)
app.secret_key = '1jfEi4fjJ@3iFso9'

@app.route('/')
def index():

    return render_template('index.html')

@app.route('/write_data/', methods = ['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['file']
        f.save(secure_filename(f.filename))

    result_message = upload_data(f.filename)
    flash(result_message)
    os.remove(f.filename)

    return redirect('/')

@app.route('/investor-report/', methods=['POST'])
def investor_report():

    acct = request.form['acct']

    conn = sqlite3.connect("citi.db")
    query = """SELECT * from interactions_roadshow
                where acct = {}
                order by 'date' """.format(acct)
    df = pd.read_sql_query(query, conn)
    conn.close()

    df = df.loc[df['year'] >= int(request.form['report_start_year']), :]
    df = df.loc[df['year'] <= int(request.form['report_end_year']), :]

    if request.form['report_analyst'] != 'All':
        df = df.loc[df['analyst_name'] == request.form['report_analyst'], :]

    if request.form['report_pm'] != 'All':
        df = df.loc[df['pm'] == request.form['report_pm'], :]

    if df.shape[0] == 0:
        return render_template('report_error.html', acct=acct)

    stats = {}
    stats['unique_corporates'] = df.corporate_id.nunique()
    stats['unique_industries'] = df.company_industry.nunique()
    stats['mgmt'] = str(round(100 * df.management_flag.mean(), 1)) + '%'

    stat_tuples = []
    if 'unique_corporates_check' in request.form:
        stat_tuples.append(('Unique Corporates', df.corporate_id.nunique()))

    if 'unique_industries_check' in request.form:
        stat_tuples.append(('Unique Industries', df.company_industry.nunique()))

    if 'management_check' in request.form:
        stat_tuples.append(('Management Presence', str(round(100*df.management_flag.mean())) + '%'))

    if 'public_check' in request.form:
        stat_tuples.append(('% Public', str(round(100*pd.isnull(df.market_cap).mean())) + '%'))

    if 'market_cap_check' in request.form:
        temp_df = df.loc[~pd.isnull(df.market_cap), :]
        if temp_df.shape[0] == 0:
            stat_tuples.append(('Avg. Market Cap', 'NA'))
        else:
            mc_mean = temp_df.market_cap.mean()
            mean_string = '$' + str(round(mc_mean)) + 'MM'
            if mc_mean > 1000:
                mean_string = '$' + str(round(mc_mean/1000)) + 'B'
            stat_tuples.append(('Avg. Market Cap', mean_string))

    if 'video_conf_check' in request.form:
        stat_tuples.append(('% Video Call', str(round(100*(df.medium=='Video Conference').mean())) + '%'))

    industries_data = []
    #bookmark
    if 'top_industries_check' in request.form:
        temp_df = df.groupby('company_industry').apply(lambda x: pd.Series({'total_interactions':x['corporate_id'].count(),
                                                                            'unique_corporates':x['corporate_id'].nunique()}))
        industries_data = temp_df.sort_values('total_interactions', ascending=False).reset_index().values

    account_name = list(df.account_name)[0]

    #getting interactions by year
    temp_df = df.groupby('year')['date'].count().reset_index().rename(columns={'date':'ct'})
    int_year = []
    for i, r in temp_df.iterrows():
        int_year.append({'year':r['year'], 'value':r['ct']})

    #getting interactions by type
    temp_df = df['meeting_type'].value_counts().to_frame().reset_index()
    temp_df.columns = ['meeting_type', 'ct']
    if (temp_df['ct'] < 0.05*df.shape[0]).sum() > 1:
        temp_df.loc[temp_df['ct'] < 0.05*df.shape[0], 'meeting_type'] = 'Other'
    temp_df = temp_df.groupby('meeting_type')['ct'].sum().reset_index().sort_values('ct', ascending=False)
    pcts = list((temp_df['ct']/df.shape[0]).round(2))
    int_type_positions = utils.get_donut_lines(pcts)
    int_type = {}
    for i, r in temp_df.iterrows():
        int_type[r['meeting_type']] = round(100 * r['ct'] / df.shape[0], 1)

    #getting interactions by market cap
    temp_df = df['market_bucket'].value_counts().to_frame().reset_index()
    temp_df.columns = ['market_bucket', 'ct']
    if (temp_df['ct'] < 0.05*df.shape[0]).sum() > 1:
        temp_df.loc[temp_df['ct'] < 0.05*df.shape[0], 'market_bucket'] = 'Other'
    temp_df = temp_df.groupby('market_bucket')['ct'].sum().reset_index().sort_values('ct', ascending=False)
    pcts = list((temp_df['ct']/df.shape[0]).round(2))
    int_bucket_positions = utils.get_donut_lines(pcts)
    int_bucket = {}
    for i, r in temp_df.iterrows():
        dict_key = r['market_bucket']
        if dict_key == 'Private/unknown':
            dict_key = 'NA'
        int_bucket[dict_key] = round(100 * r['ct'] / df.shape[0], 1)

    #getting interactions by company region
    temp_df = df['company_region'].value_counts().to_frame().reset_index()
    temp_df.columns = ['company_region', 'ct']
    if (temp_df['ct'] < 0.05*df.shape[0]).sum() > 1:
        temp_df.loc[temp_df['ct'] < 0.05*df.shape[0], 'company_region'] = 'Other'
    temp_df = temp_df.groupby('company_region')['ct'].sum().reset_index().sort_values('ct', ascending=False)

    pcts = list((temp_df['ct']/df.shape[0]).round(2))
    int_region_positions = utils.get_donut_lines(pcts)
    int_region = {}
    for i, r in temp_df.iterrows():
        int_region[r['company_region']] = round(100 * r['ct'] / df.shape[0], 1)

    return render_template('report_investor.html',
                            account_name=account_name,
                            stats=stats,
                            int_year=int_year,
                            int_type=int_type,
                            int_type_positions=int_type_positions,
                            int_bucket=int_bucket,
                            int_bucket_positions=int_bucket_positions,
                            int_region=int_region,
                            int_region_positions=int_region_positions,
                            current_date=str(date.today()),
                            stat_tuples=stat_tuples,
                            industries_data=industries_data)

    print(request.form)
    return 'hello'

@app.route('/report-investor/', defaults={'acct': 9601})
@app.route('/report-investor/<acct>')
def report_investor(acct):

    conn = sqlite3.connect("citi.db")
    query = """SELECT * from interactions_roadshow
                where acct = {}
                order by 'date' """.format(acct)
    df = pd.read_sql_query(query, conn)
    conn.close()

    print(df.columns)
    print(df.head())

    stats = {}
    stats['unique_corporates'] = df.corporate_id.nunique()
    stats['unique_industries'] = df.company_industry.nunique()
    stats['mgmt'] = str(round(100 * df.management_flag.mean(), 1)) + '%'

    #getting interactions by year
    temp_df = df.groupby('year')['date'].count().reset_index().rename(columns={'date':'ct'})
    int_year = []
    for i, r in temp_df.iterrows():
        int_year.append({'year':r['year'], 'value':r['ct']})

    #getting interactions by type
    temp_df = df['meeting_type'].value_counts().to_frame().reset_index()
    temp_df.columns = ['meeting_type', 'ct']
    if (temp_df['ct'] < 0.05*df.shape[0]).sum() > 1:
        temp_df.loc[temp_df['ct'] < 0.05*df.shape[0], 'meeting_type'] = 'Other'
    temp_df = temp_df.groupby('meeting_type')['ct'].sum().reset_index().sort_values('ct', ascending=False)
    pcts = list((temp_df['ct']/df.shape[0]).round(2))
    int_type_positions = utils.get_donut_lines(pcts)
    int_type = {}
    for i, r in temp_df.iterrows():
        int_type[r['meeting_type']] = round(100 * r['ct'] / df.shape[0], 1)

    #getting interactions by market cap
    temp_df = df['market_bucket'].value_counts().to_frame().reset_index()
    temp_df.columns = ['market_bucket', 'ct']
    if (temp_df['ct'] < 0.05*df.shape[0]).sum() > 1:
        temp_df.loc[temp_df['ct'] < 0.05*df.shape[0], 'market_bucket'] = 'Other'
    temp_df = temp_df.groupby('market_bucket')['ct'].sum().reset_index().sort_values('ct', ascending=False)
    pcts = list((temp_df['ct']/df.shape[0]).round(2))
    int_bucket_positions = utils.get_donut_lines(pcts)
    int_bucket = {}
    for i, r in temp_df.iterrows():
        dict_key = r['market_bucket']
        if dict_key == 'Private/unknown':
            dict_key = 'NA'
        int_bucket[dict_key] = round(100 * r['ct'] / df.shape[0], 1)

    #getting interactions by company region
    temp_df = df['company_region'].value_counts().to_frame().reset_index()
    temp_df.columns = ['company_region', 'ct']
    if (temp_df['ct'] < 0.05*df.shape[0]).sum() > 1:
        temp_df.loc[temp_df['ct'] < 0.05*df.shape[0], 'company_region'] = 'Other'
    temp_df = temp_df.groupby('company_region')['ct'].sum().reset_index().sort_values('ct', ascending=False)

    pcts = list((temp_df['ct']/df.shape[0]).round(2))
    int_region_positions = utils.get_donut_lines(pcts)
    int_region = {}
    for i, r in temp_df.iterrows():
        int_region[r['company_region']] = round(100 * r['ct'] / df.shape[0], 1)

    return render_template('report_investor.html',
                            stats=stats,
                            int_year=int_year,
                            int_type=int_type,
                            int_type_positions=int_type_positions,
                            int_bucket=int_bucket,
                            int_bucket_positions=int_bucket_positions,
                            int_region=int_region,
                            int_region_positions=int_region_positions)

@app.route('/investors/', defaults={'acct': None})
@app.route('/investors/<acct>')
def investors(acct):

    if acct == None:
        conn = sqlite3.connect("citi.db")
        query = """SELECT * from roadshow_investor
                    order by total_interactions desc limit 1000"""
        investors = pd.read_sql_query(query, conn)
        conn.close()

        top_investors = investors.groupby('acct')['total_interactions'].sum().reset_index()\
                                    .sort_values('total_interactions', ascending=False)\
                                    .reset_index(drop=True)
        top_investors['total_interactions'] = top_investors['total_interactions'].astype(int)
        top_investors = top_investors.head(10).values.tolist()

        cols_to_show = ['acct', 'investor_region', 'year', 'global_access', 'total_interactions',
                        'unique_corporates', 'unique_industries', 'one_on_one_pct',
                        'management_pct', 'vid_call_pct']
        investors = investors[cols_to_show]

        pct_cols = ('one_on_one_pct', 'management_pct', 'vid_call_pct')
        for colname in pct_cols:
            investors[colname] = (investors[colname]*100).round(1)

        html_colnames = ['Acct', 'Region', 'Year', 'Global Access Tier', 'Total Interactions',
                            'Unique Corporates', 'Unique Industries',
                             '1:1 %', 'Mgmt %', 'Video Call %']

        select_values = {}
        select_values['years'] = sorted(list(set(investors['year'])), reverse=True)
        select_values['regions'] = sorted(list(set(investors['investor_region'])))
        select_values['tiers'] = sorted(list(set(investors['global_access'])))

        return render_template('investors.html',
                                data = investors.values.tolist(),
                                colnames = cols_to_show,
                                html_colnames = html_colnames,
                                top_investors = top_investors,
                                select_values = select_values)

    else:
        conn = sqlite3.connect("citi.db")
        query = """SELECT * from interactions_roadshow
                    where acct == {}
                    order by 'date' """.format(acct)
        df = pd.read_sql_query(query, conn)

        cur = conn.cursor()
        query = """SELECT DISTINCT account_name FROM
                roadshow_investor WHERE acct == {}""".format(acct)
        cur.execute(query)
        account_name = cur.fetchall()[0][0]
        conn.close()

        df['management_presence'] = np.where(df['management_flag'] == 1, 'Yes', 'No')
        df['video_flag'] = np.where(df['medium'] == 'Video Conference', 'Yes', 'No')
        df = df.sort_values('date', ascending=False).reset_index(drop=True)

        year_set = sorted(list(set(df['year'])), reverse = True)

        investor_info = {}
        investor_info['acct'] = acct
        investor_info['name'] = account_name

        pm_list = sorted(list(set(df['pm'])))
        analyst_list = sorted(list(set(df['analyst_name'])))

        html_colnames = {'acct':'Account ID', 'sgp':'SGP', 'investor_region':'Investor Region',
                        'equity_tier': 'Equity Tier', 'global_access': 'Global Access',
                        'company_name': 'Corporate Name', 'ric':'RIC',
                        'company_industry':'Industry', 'product_region':'Product Region',
                        'company_region': 'Corporate Region', 'company_country':'Corporate Country',
                        'market_cap':'Market Cap', 'market_bucket':'Market Bucket',
                        'ratings':'Ratings', 'date': 'Date', 'event_type':'Event Type',
                        'meeting_type':'Meeting Type', 'global_region_visited':'Region Visited',
                        'city':'City', 'management_presence':'Management Present',
                        'video_flag': 'Video'}

        return render_template('view_investor.html',
                                year_set = year_set,
                                investor_info = investor_info,
                                data = json.dumps(df.values.tolist()),
                                colnames = list(df.columns),
                                html_colnames = html_colnames,
                                pm_list=pm_list,
                                analyst_list=analyst_list)

@app.route('/investors/<acct>/similar_investors.html')
def similar_investors(acct):
    conn = sqlite3.connect("citi.db")
    query = """SELECT * from roadshow_investor"""
    investors = pd.read_sql_query(query, conn)
    conn.close()

    investors.fillna(0, inplace=True)

    correlation_columns = ['total_interactions', 'unique_corporates', 'unique_industries', 'one_on_one_pct',
                  'group_pct', 'management_pct', 'market_cap_mean', 'market_cap_median', 'large_pct',
                  'private_pct', 'us_pct', 'meeting_pct', 'conf_call_pct', 'vid_call_pct', 'open_ex_pct']
    knn_investor = NearestNeighbors(n_neighbors=3).fit(investors.loc[:, correlation_columns])
    neighbors = knn_investor.kneighbors(return_distance=False)

    acct_index = investors.index[investors['acct'] == acct]
    acct_neighbors = [investors.iloc[n]['acct'] for n in neighbors[acct_index][0]]

    year_set = sorted(list(set(investors['year'])), reverse = True)

    investor_info = {}
    investor_info['acct'] = acct
    investor_info['neighbors'] = acct_neighbors

    return render_template('similar_investors.html',
                            year_set = year_set,
                            investor_info = investor_info,
                            data = json.dumps(investors.values.tolist()),
                            colnames = list(investors.columns))

@app.route('/search')
def search():
    search_term = request.args.get('search')
    c_columns = []
    i_columns = []
    text = "No results found."

    if search_term.strip()=='' or search_term == None:
        return render_template('search.html',
                                searched = text,
                                results = 0,
                                c_results = [],
                                i_results = [],
                                c_columns = c_columns,
                                i_columns = i_columns)

    else:
        conn = sqlite3.connect("citi.db")
        query = """SELECT * FROM corporates
                    WHERE company_name LIKE '%"""+search_term+"""%'
                    ORDER BY company_name limit 100"""
        corporates = pd.read_sql_query(query, conn)

        query = """SELECT distinct acct, account_name, investor_region, global_access FROM roadshow_investor
                    WHERE account_name LIKE '%"""+search_term+"""%'
                    ORDER BY account_name limit 100"""
        investors = pd.read_sql_query(query, conn)
        conn.close()

        grp = ['acct','account_name']
        # i_results = investors.groupby(grp, as_index=False)['investor_region'].apply(', '.join).reset_index()
        aggregation_functions = {'global_access': 'first', 'investor_region': 'last'}
        i_results = investors.groupby(grp, as_index=False).aggregate(aggregation_functions).reindex(columns=investors.columns)

        if len(corporates)+len(i_results)>0:
            text = "Results for: \""+search_term+"\""

        if len(corporates)>0:
            c_columns = ['Name', 'Company Region', 'Company Country', 'Company Industry']
        if len(i_results)>0:
            i_columns = ['Acct.', 'Account Name', 'Region', 'Global Access Tier']

        return render_template('search.html',
                                searched = text,
                                results = len(corporates)+len(i_results),
                                c_results = corporates.values.tolist(),
                                i_results = i_results.values.tolist(),
                                c_columns = c_columns,
                                i_columns = i_columns)

@app.route('/corporates/', defaults={'corporate_id': None})
@app.route('/corporates/<corporate_id>')
def corporates(corporate_id):

    if corporate_id == None:

        conn = sqlite3.connect("citi.db")
        query = """SELECT * from roadshow_company
                    order by total_interactions desc limit 1000"""
        corporates = pd.read_sql_query(query, conn)
        conn.close()

        top_corporates = corporates.groupby('company_name')['total_interactions'].sum().reset_index()\
                                    .sort_values('total_interactions', ascending=False)\
                                    .reset_index(drop=True)
        top_corporates['total_interactions'] = top_corporates['total_interactions'].astype(int)
        top_corporates = top_corporates.head(10).values.tolist()

        corporates['company_type'] = np.where(corporates['private_flag'] == 0, 'Public', 'Private')
        cols_to_show = ['corporate_id', 'company_name', 'company_region', 'company_type', 'year', 'total_interactions',
                        'unique_investors', 'one_on_one_pct', 'management_pct', 'vid_call_pct']
        corporates = corporates[cols_to_show]

        pct_cols = ('one_on_one_pct', 'management_pct', 'vid_call_pct')
        for colname in pct_cols:
            corporates[colname] = (corporates[colname]*100).round(1)

        html_colnames = ['Corporate', 'Region', 'Type', 'Year', 'Interactions',
                            'Unique Investors', '1:1 %', 'Mgmt %', 'Video Call %']

        select_values = {}
        select_values['years'] = sorted(list(set(corporates['year'])), reverse=True)
        select_values['regions'] = sorted(list(set(corporates['company_region'])))

        return render_template('corporates.html',
                                data = corporates.values.tolist(),
                                colnames = cols_to_show,
                                html_colnames = html_colnames,
                                top_corporates = top_corporates,
                                select_values = select_values)

    else:

        conn = sqlite3.connect("citi.db")
        query = """SELECT * FROM interactions_roadshow
                    WHERE corporate_id = {}
                    ORDER BY 'date' asc """.format(corporate_id)
        df = pd.read_sql_query(query, conn)
        conn.close()

        df['management_presence'] = np.where(df['management_flag'] == 1, 'Yes', 'No')
        df['video_flag'] = np.where(df['medium'] == 'Video Conference', 'Yes', 'No')

        #Readable Column Names
        html_colnames = {'acct':'Account ID', 'sgp':'SGP', 'investor_region':'Investor Region',
                        'equity_tier': 'Equity Tier', 'global_access': 'Global Access',
                        'company_name': 'Corporate Name', 'ric':'RIC',
                        'company_industry':'Industry', 'product_region':'Product Region',
                        'company_region': 'Corporate Region', 'company_country':'Corporate Country',
                        'market_cap':'Market Cap', 'market_bucket':'Market Bucket',
                        'ratings':'Ratings', 'date': 'Date', 'event_type':'Event Type',
                        'meeting_type':'Meeting Type', 'global_region_visited':'Region Visited',
                        'city':'City', 'management_presence':'Management Present',
                        'video_flag': 'Video'}

        year_set = sorted(list(set(df['year'])), reverse = True)

        corporate_info = {}
        corporate_info['region'] = df['company_region'][0]
        corporate_info['country'] = df['company_country'][0]
        corporate_info['company_name'] = df['company_name'][0]
        corporate_info['company_industry'] = df['company_industry'][0]
        corporate_info['corporate_id'] = corporate_id

        df = df.sort_values('date', ascending=False).reset_index(drop=True)

        #get investor-level summary
        df_investors = df.groupby(['acct', 'investor_region', 'global_access']).apply(
                        lambda x: pd.Series({'total_interactions': x.count(),
                                            'last_interaction': x['date'].max()})).reset_index()

        return render_template('view_corporate.html',
                                year_set = year_set,
                                corporate_info = corporate_info,
                                data = json.dumps(df.values.tolist()),
                                colnames = list(df.columns),
                                html_colnames = json.dumps(html_colnames),
                                df_investors = df_investors)

@app.route('/corporates/<corporate_id>/similar_corporates.html')
def similar_corporates(corporate_id):
    conn = sqlite3.connect("citi.db")
    query = """SELECT * from roadshow_company"""
    corporates = pd.read_sql_query(query, conn)
    conn.close()

    corporates.fillna(0, inplace=True)

    correlation_columns = ['corporate_id', 'company_name', 'total_interactions', 'unique_investors', 'one_on_one_pct',
                  'group_pct', 'management_pct', 'market_cap_avg', 'platinum_pct',
                  'meeting_pct', 'conf_call_pct', 'vid_call_pct', 'open_ex_pct']
    corporates_correlation = corporates.loc[:, correlation_columns]
    corporates_correlation_grouped = corporates_correlation.groupby(['company_name']).apply(lambda x: pd.Series({'total_interactions': x['total_interactions'].sum(),
                                                                'unique_investors': x['unique_investors'].mean(),
                                                                'one_on_one_pct': x['one_on_one_pct'].mean(),
                                                               'group_pct': x['group_pct'].mean(),
                                                               'management_pct': x['management_pct'].mean(),
                                                               'market_cap_avg': x['market_cap_avg'].mean(),
                                                               'platinum_pct': x['platinum_pct'].mean(),
                                                              'meeting_pct': x['meeting_pct'].mean(),
                                                              'conf_call_pct': x['conf_call_pct'].mean(),
                                                              'vid_call_pct': x['vid_call_pct'].mean(),
                                                             'open_ex_pct': x['open_ex_pct'].mean(),
                                                             'corporate_id': x['corporate_id'][0]
                                                                })).reset_index()

    correlation_columns = ['total_interactions', 'unique_investors', 'one_on_one_pct',
                  'group_pct', 'management_pct', 'market_cap_avg', 'platinum_pct',
                  'meeting_pct', 'conf_call_pct', 'vid_call_pct', 'open_ex_pct']
    knn_corporate = NearestNeighbors(n_neighbors=3).fit(corporates_correlation_grouped.loc[:, correlation_columns])
    neighbors = knn_corporate.kneighbors(return_distance=False)

    acct_index = corporates_correlation_grouped.index[corporates_correlation_grouped['corporate_id'] == float(corporate_id)]
    acct_neighbors = [int(corporates_correlation_grouped.iloc[n]['corporate_id']) for n in neighbors[acct_index][0]]
    acct_neighbors_names = [corporates_correlation_grouped.iloc[n]['company_name'] for n in neighbors[acct_index][0]]

    corporate_info = {}
    corporate_info['company_name'] = corporates_correlation_grouped.iloc[acct_index]['company_name'].to_string().split(' ', 1)[1]
    corporate_info['corporate_id'] = corporate_id
    corporate_info['neighbors'] = acct_neighbors
    corporate_info['neighbor_names'] = acct_neighbors_names

    return render_template('similar_corporates.html', corporate_info = corporate_info)

if __name__ == '__main__':
    app.run(debug = True)


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

""" Helps Check various web elements attributes or compare them with user input
"""

from core.shared.actions import Switch, case, map_funcs, ElementNotFoundError, WebElementDecompositionException, \
    FuncRef, get_regular, compose_table_xpath, choose_table_label, URL_REPR, first, split_name

__author__ = 'MGVasilev'

class Check(object):
    """ Contains checks and related actions
    """
    def __init__(self):
        pass

    @staticmethod
    def check_page(browser, page_url: str, user_data: dict):
        """ Check if current page url corresponds to referred value
        """

        return browser.check_page(user_data[URL_REPR] + page_url)

    @staticmethod
    def check_element(browser, locator: str, argument: str, *args):
        """ Check if DOM element is present on page
        """

        while Switch(argument):
            if case(get_regular(FuncRef.TABLE)):
                return browser.verify_element(compose_table_xpath(locator))
            return browser.verify_element(locator)

    @staticmethod
    def element_contents_check(browser, value: str, argument: str=None, column_name: str=None, position: str=None,
                               xpath: str=None, trans_type: str=None, not_mod: bool=False) -> bool or object:
        """ Check current (parsed web element saved to Driver) content on containing given value
        :param browser: Current Driver() instance
        :param argument: full web element name
        :param value: user input value
        :param column_name: table column name
        :param position: indicates if we are looking for top ("ПЕРВОЙ") or bottom ("ПОСЛЕДНЕЙ") line
        :param xpath: universal element locator at page
        :return: bool or ElementNotFoundError

        Doctest:
        >>> from core.shared.custom_selenium.web_driver import Driver
        >>> browser = Driver(driver="IE")
        >>> browser.go_to("http://sbt-oafs-578:7001/SVFE2/")
        >>> browser.click(".//*[@id='LoginForm:Login']")
        >>> browser.send_key(".//*[@id='LoginForm:Login']", 'admin')
        >>> browser.click(".//*[@id='LoginForm:Password']")
        >>> browser.click(".//*[@id='LoginForm:submit']")
        >>> browser.check_page("http://sbt-oafs-578:7001/SVFE2/pages/blank.jsf")
        >>> browser.go_to("http://sbt-oafs-578:7001/SVFE2/pages/acquirer/terminal/terminal.jsf")
        >>> browser.check_page("http://sbt-oafs-578:7001/SVFE2/pages/acquirer/terminal/terminal.jsf")
        >>> browser.check_text_button(".//*[@id='UserForm:j_id533']", "Найти")
        True
        """

        while Switch(first(split_name(argument))):
            if case(get_regular(FuncRef.TABLE)):
                browser.parse_html_table(compose_table_xpath(xpath), choose_table_label(xpath))
                if column_name is None:
                    return browser.find_table_line(value)
                else:
                    res = map_funcs((browser.find_value_in_column_and_line, browser.find_value_in_column),
                                    column_name, value, position)
                    if not res and not_mod is False:
                        raise WebElementDecompositionException(
                            "Could not find requested info in table: {table}".format(table=value))
                    return True
            elif case(get_regular(FuncRef.FORM)):
                return browser.check_text_in_element(xpath, value)
            elif case(get_regular(FuncRef.FIELD)):
                return browser.check_text(xpath, value)
            elif case(get_regular(FuncRef.ELEMENT)):
                pass
            elif case(get_regular(FuncRef.HEADING)):
                return browser.check_text(xpath, value)
            elif case(get_regular(FuncRef.LINK)):
                return browser.check_text_link(xpath, value)
            elif case(get_regular(FuncRef.BUTTON)):
                return browser.check_text_button(xpath, value)
            elif case(get_regular(FuncRef.DROP_DOWN)):
                return browser.check_text_dropdown(xpath, value)

            raise NotImplementedError("Cannot check contents of {element}.".format(element=argument))


#Complementing a Strand of DNA

def reverseComplement(dna):
    compl = ""
    for i in dna[::-1]:
        if i == 'A':
            compl += 'T'
        elif i == 'T':
            compl += 'A'
        elif i == 'C':
            compl += 'G'
        elif i == 'G':
            compl += 'C'
    return compl

'''
with open('input.txt', 'r') as input:
    dna = input.read()
    print(reverseComplement(dna))
'''


#! /usr/bin/env python3
import itertools
import sys

def get_data(path) -> list[list[str]]:
    with open(path) as f:
        return [line.strip().split('x') for line in f.readlines() if line.strip()]

def part1(packages: list[list[str]]) -> int:
    paper_needed = 0

    for dims in packages:
        l, w, h = [int(x) for x in dims]
        surface_area = 2 * l * w + 2 * w * h + 2 * h * l
        paper_needed += surface_area
        sides = itertools.combinations([l, w, h], 2)
        extra = min([x[0] * x[1] for x in sides])
        paper_needed += extra

    return paper_needed

def part2(packages: list[list[str]]) -> int:
    pass

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('Usage: main.py <filename>')
        sys.exit(1)

    file_name = sys.argv[1]

    print(f'part1 {part1(get_data(file_name))}')
    print()
    print(f'part2 {part2(get_data(file_name))}')


#For the problem I will connect with spark library to do the MapReduce.

'''
Define names
chapter 1: 1_2_1_character
chapter 2: 1_2_2_character
chapter 3: 1_3_1_character
chapter 4: 1_3_2_character
chapter 5: 1_4_1_character
chapter 6: 1_4_2_character
chapter 7: 2_3_1_character
chapter 8: 2_3_2_character
chapter 9: 2_4_1_character
chapter 10:2_4_2_character
chapter 11:3_4_1_character
chapter 12:3_4_2_character

Define Folder name
maptest: Master folder which contain all the files
1: first node, will find how many As in there
2: second node, will find how many Bss in there
3: third node, will find how many Cs in there
4: fourth node, will find how many Ds in there
'''

import timeit
import sys
import os
import numpy as np
import pandas as pd
#import dispy
import shutil
import re
import time
import threading#, Queue
import random
import math
#from multiprocessing import Process,Lock,Pool
import time,datetime
import multiprocessing

def filecreator():
    ####finish created director
    for i in range(users):
        for j in range(users):
            for k in range(2):
                for l in range(users):
                    if i != j and i<j:
                        filename=str(i+1)+"_"+str(j+1)+"_"+str(k+1)+"_"+str(l+1)+".txt"
                        filegen=open(filename,'w')
                        generate = str(random.randint(0,9000))
                        #sys.stdout= open(filename,'w')#create a txt file
                        filegen.write(generate) #store all the numbers which generate earier to the txt  file
                        filegen.close()
#sys.stdout.close()

############### Part 3  ##################
############# Mapping Code  ##############
def Mapping():
    files= os.listdir(folder_path) #get file name under the folder
    results = set() #find folder name
    number_result=set()
    for files_names in files:
        files_name=files_names.split('.')
        file_name=files_name[0].split('_')
        if len(files_names) > 4:
            first = "coded_"+file_name[0]
            third = "coded_"+file_name[1]
            results.add(first)
            results.add(third)
            number_first=file_name[0]
            number_third=file_name[1]
            number_result.add(number_first)
            number_result.add(number_third)
    results=list(results)
    number_result=list(number_result)
    #print(number_result)
    os.chdir(path)#change the director for the folder path
    #print(results)
    for folder_name in results:#delete folders that exists from previous run
        if os.path.exists(path):
            #print(folder_name)
            shutil.rmtree(folder_name)

    for folder_name in results:#create new folders for the number desired
        if os.path.isdir(path):
            os.mkdir(os.path.join(path, folder_name))
            new_path=path+'/'+folder_name
            if os.path.isdir(path):
                os.mkdir(os.path.join(new_path, folder_name))
    counter=0

    for files_names in files:
        files_name=files_names.split('.')
        file_name=files_name[0].split('_')
        if len(files_names) > 4:
            first="coded_"+file_name[0]
            third="coded_"+file_name[1]
            shutil.copy('/Users/xiaoran/dropbox/cache_map/coded_master/'+files_names, '/Users/xiaoran/dropbox/cache_map/'+first)
            shutil.copy('/Users/xiaoran/dropbox/cache_map/coded_master/'+files_names, '/Users/xiaoran/dropbox/cache_map/'+third)
    print(results)
    print(number_result)
#print(type(file_name))

    return (results,file_name)

#second part: shuffe(naive scheme)

def Encoding(val1,val2,val3):
    results=val1
    file_name=val2
    thread_name =val3
        #for thread_name in results:
    thread_path="/Users/xiaoran/dropbox/cache_map/"+thread_name
    location=os.listdir(thread_path)
    print("Helloworld"+thread_path)
    for file_copy in location:
        gau_pause_time=-math.log(random.uniform(0, 1))#gaussian distribution

        result_file_copy=file_copy.split('_')
        if len(result_file_copy) >3:
            print(file_copy)
            first=result_file_copy[0]
            third=result_file_copy[1]
            fifth=result_file_copy[2]
            seventh=result_file_copy[3]
            '''
            first=file_copy[0]
            third=file_copy[2]
            fifth=file_copy[4]
            seventh=file_copy[6]
            '''
            file_location='/Users/xiaoran/dropbox/cache_map/coded_'+seventh
            #print(first, third, fifth, seventh)
            if (seventh != first and seventh!=third and (fifth =="1")): # if equal to 1 then copy file from location equal to the value from first
                shutil.copy('/Users/xiaoran/dropbox/cache_map/coded_'+first+'/'+file_copy, file_location)
            elif (seventh != first and seventh!=third and (fifth =="2")): # if equal to 2 then copy file from location equal to the value from second
                shutil.copy('/Users/xiaoran/dropbox/cache_map/coded_'+third+'/'+file_copy, file_location)
            time.sleep(0.1)
######################
if __name__ == "__main__":
    path ="/Users/xiaoran/dropbox/cache_map"
    folder_path="/Users/xiaoran/dropbox/cache_map/coded_master"
    def moveFileto(sourceDir,  targetDir):
        shutil.copy(sourceDir,  targetDir)

    if os.path.exists(folder_path): #Delete the folder if the folder exist
        shutil.rmtree(folder_path)
    print("How many user you are trying to have?")
    user=input()
    users=int(user)
    counter=int(user)
    userss=str(user)
    print("you are going to have " +user + " users for this simulation" )

#filecreating()#creating files and folder

    #def filecreating():
    files= os.listdir(path) #get file name under the folder
    # define the access rights
    access_rights = 0o755

    try:
        os.mkdir(folder_path, access_rights)
    except OSError:
        print ("Creation of the directory %s failed" % folder_path)
    else:
        print ("Successfully created the directory %s" % folder_path)
    os.chdir(folder_path)#change the director for the folder path
    filecreator()
    user_name, temp2 = Mapping()
    #Encoding(temp1,temp2)
    pool=multiprocessing.Pool(processes = users)
    start =datetime.datetime.now()
    for i in user_name:
        print("Server current running " + i)
        print(datetime.datetime.now())
        pool.apply_async(Encoding, [user_name,temp2,i])
        #pool.apply_async(Decoding(user_name),args=(i,))
    pool.close()
    pool.join()
    print("Done")
    finish=datetime.datetime.now()
    print("For " + userss +" users spent \{}".format(finish-start))


import numpy as np
import scipy.signal

class Modem:
    def __init__(self, fs, bufsz, ans=False):
        self.bit_rate = 300
        self.fi = 0
        self.bits =[]
        self.s = []
        self.sbuffer= np.zeros(fs//self.bit_rate).tolist()
        self.v0i= 0
        self.v0r= 0
        self.v1i= 0
        self.v1r= 0
        self.y = None
        self.v = [0, 0, 0]
        self.fs = fs  # taxa de amostragem
        self.bufsz = bufsz  # quantidade de amostas que devem ser moduladas por vez
        # frequências de modulação (upload)
        self.tx_omega0 = 2*np.pi*(1080 + 100)
        self.tx_omega1 = 2*np.pi*(1080 - 100)
        # frequências de demodulação (download)
        self.rx_omega0 = 2*np.pi*(1750 + 100)
        self.rx_omega1 = 2*np.pi*(1750 - 100)
        # se o modem estiver atendendo uma ligação
        if ans:
            # inverte as frequências
            self.tx_omega0, self.rx_omega0 = self.rx_omega0, self.tx_omega0
            self.tx_omega1, self.rx_omega1 = self.rx_omega1, self.tx_omega1

    # Modulação

    def put_bits(self, bits):
        self.bits.extend(bits)

    def get_samples(self):
    	#MODULADOR
        y = np.zeros(self.bufsz)
        t = 0.0

        if len(self.bits) == 0:
            self.bits.append(1)

        w = (self.tx_omega1 if self.bits[0] else self.tx_omega0)
        self.fi = self.fi-w*t
        for j in range(self.bufsz):
            y[j] = np.sin(w*t+self.fi)
            t = t+1/self.fs

        self.fi = (w*t + self.fi)%(2*np.pi)
        self.bits.pop(0)
        return y
    # Demodulação

    def put_samples(self, data):
        self.s = self.s.copy() + data.tolist()

    def get_bits(self):

        fs= self.fs
        T = 1/fs
        L = fs//self.bit_rate #self.bit_rate = 300
        pi = np.pi
        omega0=self.rx_omega0
        omega1=self.rx_omega1

        #print("Tam = ",tam)

        cutoff_index = len(self.s) - len(self.s)%L

        s = self.sbuffer + self.s

        v0i= self.v0i
        v0r= self.v0r
        v1i= self.v1i
        v1r= self.v1r

        V0i= np.zeros(len(s) - L)
        V0r= np.zeros(len(s) - L)
        V1i= np.zeros(len(s) - L)
        V1r= np.zeros(len(s) - L)

        r=0.99

        #print("len s=", len(s))
        #print("len v0=", len(v0i),len(v0r),len(v1i),len(v1r))

        for n in range(L,len(s)):
            V0r[n-L] = s[n] - r**L * np.cos(omega0*L*T)*s[n-L] + r*np.cos(omega0*T)*v0r - r*np.sin(omega0*T)*v0i
            V0i[n-L] = -r**L*np.sin(omega0*L*T)*s[n-L] + r*np.cos(omega0*T)*v0i + r*np.sin(omega0*T)*v0r
            V1r[n-L] = s[n] - r**L * np.cos(omega1*L*T)*s[n-L] + r*np.cos(omega1*T)*v1r - r*np.sin(omega1*T)*v1i
            V1i[n-L] = -r**L*np.sin(omega1*L*T)*s[n-L] + r*np.cos(omega1*T)*v1i + r*np.sin(omega1*T)*v1r

            v0r = V0r[n-L]
            v0i = V0i[n-L]
            v1r = V1r[n-L]
            v1i = V1i[n-L]

        self.v0i = v0i
        self.v0r = v0r
        self.v1i = v1i
        self.v1r = v1r

        rho = V1r**2+V1i**2+V0r**2+V0i**2   # carrier detection

        c = abs(V1r**2+V1i**2-V0r**2-V0i**2)
        v = self.v.copy()

        y = np.zeros(len(c))

        r = 0.9999
        for n in range(len(c)):
                v[2] = (1-r)*c[n] + 2*r*np.cos(2*pi*300/fs)*v[1] - r**2*v[0]
                y[n] = v[2] - v[0]

                v[0] = v[1]
                v[1] = v[2]

        self.v = v.copy()

        #print(f"help me = {self.y}")
        if self.y != None:
            y = np.concatenate((self.y, y))

        delta = V1r**2+V1i**2-V0r**2-V0i**2

        ponto_amostra = 1500*((y[1:]>0)&(y[:-1]<0))

        bits = []
        for i in range (len(ponto_amostra)):
            if ponto_amostra[i] != 0:
                bits.append(1 if delta[i] > 0.5 else 0)
        #for i in range(L//2 + 46, len(delta), L):
        #   bits.append(1 if delta[i] > 0.5 else 0)

        self.s = []
        self.sbuffer = s[len(s)-L:]
        if len(self.sbuffer) < L:
            self.sbuffer = [0]*(L - len(self.sbuffer)) + self.sbuffer
        self.y = np.array([y[-1]])

        return bits


# coding: utf-8

"""
    Apache NiFi Registry REST API

    The REST API provides an interface to a registry with operations for saving, versioning, reading NiFi flows and components.

    OpenAPI spec version: 1.19.0
    Contact: dev@nifi.apache.org
    Generated by: https://github.com/swagger-api/swagger-codegen.git
"""

from pprint import pformat
from six import iteritems
import re

class DefaultSettings(object):
    """
    NOTE: This class is auto generated by the swagger code generator program.
    Do not edit the class manually.
    """

    """
    Attributes:
      swagger_types (dict): The key is attribute name
                            and the value is attribute type.
      attribute_map (dict): The key is attribute name
                            and the value is json key in definition.
    """
    swagger_types = {
        'yield_duration': 'str',
        'penalty_duration': 'str',
        'bulletin_level': 'str'
    }

    attribute_map = {
        'yield_duration': 'yieldDuration',
        'penalty_duration': 'penaltyDuration',
        'bulletin_level': 'bulletinLevel'
    }

    def __init__(self, yield_duration=None, penalty_duration=None, bulletin_level=None):
        """
        DefaultSettings - a model defined in Swagger
        """

        self._yield_duration = None
        self._penalty_duration = None
        self._bulletin_level = None

        if yield_duration is not None:
          self.yield_duration = yield_duration
        if penalty_duration is not None:
          self.penalty_duration = penalty_duration
        if bulletin_level is not None:
          self.bulletin_level = bulletin_level

    @property
    def yield_duration(self):
        """
        Gets the yield_duration of this DefaultSettings.
        The default yield duration

        :return: The yield_duration of this DefaultSettings.
        :rtype: str
        """
        return self._yield_duration

    @yield_duration.setter
    def yield_duration(self, yield_duration):
        """
        Sets the yield_duration of this DefaultSettings.
        The default yield duration

        :param yield_duration: The yield_duration of this DefaultSettings.
        :type: str
        """

        self._yield_duration = yield_duration

    @property
    def penalty_duration(self):
        """
        Gets the penalty_duration of this DefaultSettings.
        The default penalty duration

        :return: The penalty_duration of this DefaultSettings.
        :rtype: str
        """
        return self._penalty_duration

    @penalty_duration.setter
    def penalty_duration(self, penalty_duration):
        """
        Sets the penalty_duration of this DefaultSettings.
        The default penalty duration

        :param penalty_duration: The penalty_duration of this DefaultSettings.
        :type: str
        """

        self._penalty_duration = penalty_duration

    @property
    def bulletin_level(self):
        """
        Gets the bulletin_level of this DefaultSettings.
        The default bulletin level

        :return: The bulletin_level of this DefaultSettings.
        :rtype: str
        """
        return self._bulletin_level

    @bulletin_level.setter
    def bulletin_level(self, bulletin_level):
        """
        Sets the bulletin_level of this DefaultSettings.
        The default bulletin level

        :param bulletin_level: The bulletin_level of this DefaultSettings.
        :type: str
        """

        self._bulletin_level = bulletin_level

    def to_dict(self):
        """
        Returns the model properties as a dict
        """
        result = {}

        for attr, _ in iteritems(self.swagger_types):
            value = getattr(self, attr)
            if isinstance(value, list):
                result[attr] = list(map(
                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
                    value
                ))
            elif hasattr(value, "to_dict"):
                result[attr] = value.to_dict()
            elif isinstance(value, dict):
                result[attr] = dict(map(
                    lambda item: (item[0], item[1].to_dict())
                    if hasattr(item[1], "to_dict") else item,
                    value.items()
                ))
            else:
                result[attr] = value

        return result

    def to_str(self):
        """
        Returns the string representation of the model
        """
        return pformat(self.to_dict())

    def __repr__(self):
        """
        For `print` and `pprint`
        """
        return self.to_str()

    def __eq__(self, other):
        """
        Returns true if both objects are equal
        """
        if not isinstance(other, DefaultSettings):
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        """
        Returns true if both objects are not equal
        """
        return not self == other


from django.urls import re_path

from .views import LoginView, CallbackView, LogoutView

urlpatterns = [
    re_path(r'^oauth2/login/?$', LoginView.as_view(), name='oauth2_login_view'),
    re_path(r'^oauth2/callback/?$', CallbackView.as_view(), name='oauth2_callback_view'),
    re_path(r'^oauth2/logout/?$', LogoutView.as_view(), name='oauth2_logout_view'),
]


'''
Given a vector A of non-negative integers representing an
elevation map where the width of each bar is 1,
compute how much water it is able to trap after raining.

Input : A = [0, 1, 0, 2]
Output 1

1 unit is trapped on top of the 3rd element.

'''

class Solution:
	# @param A : tuple of integers
	# @return an integer
	def trap(self, A):
		"""
		Time complexity O(N**2)
		Args:
		    A (TYPE): Array of +ve intigers

		Returns:
		    TYPE: integer (water trapped)
		"""
		ans = 0

		N = len(A)

		for i in range(1,N-1):

			left = A[i]

			for j in range(i):
				left = max(left,A[j])
			right = A[i]
			for j in range(i+1,N):
				right = max(right,A[j])

			net_support = min(left,right)
			ans += max(net_support-A[i],0)
		return ans

class Solution:
	## in brute force we are taking max of left and right of ith index so
	## build left max and right max array
	def trap(self,A):
		"""
		Build left max and right max array
		time complexity O(N)
		space complexity O(N)
		Args:
		    A (TYPE): Array of +ve intigers

		Returns:
		    TYPE: ammount of water trapped int
		"""
		n = len(A)
		ans = 0
		lm,rm = [],[]
		for i in range(n):
			lm.append(A[0])
			rm.append(A[n-1])

		for i in range(1,n):
			lm[i] = max(lm[i-1],A[i])
		for i in range(n-2,-1,-1):
			rm[i] = max(rm[i+1],A[i])

		for i in range(1,n-1):
			left_max = lm[i]
			right_max = rm[i]

			net_support = min(left_max,right_max)
			ans += max(net_support-A[i],0)
		return ans
sol = Solution()
A = [0, 1, 0, 2]
# A = [-3,6,2,4,5,5,2,8,-4,3,1]
print(sol.trap(A))

MODULE-4/Arrays 1/Q3. Rain Water Trapped.py


import torch
import math
import torch.nn.functional as F
from torchvision.transforms import Normalize, Compose, ToTensor
from torch.utils.data import DataLoader
from model import CNN
from loss import loss_coteaching
from dataset.cifar import CIFAR10

# Constants
batch_size = 256
input_channel = 3
num_classes = 10
learning_rate = 5e-4
model_str = 'CIFAR10'
n_epoch = 40
epoch_decay_start = 4
noise_type = 'symmetric'
noise_rate = 0.2

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

mean = [0.4914, 0.4822, 0.4465]
std = [0.2470, 0.2435, 0.2616]

# define drop rate schedule
forget_rate = noise_rate

alpha_plan = torch.ones(n_epoch) * learning_rate

for i in range(epoch_decay_start, n_epoch):
    alpha_plan[i] = float(n_epoch - i) / (n_epoch - epoch_decay_start) * learning_rate

def adjust_learning_rate(optimizer, epoch_idx):
    for param_group in optimizer.param_groups:
        param_group['lr'] = alpha_plan[epoch_idx] / (float(math.sqrt(epoch_idx+1)))

@torch.no_grad()
def accuracy(model, data_loader):
    """Computes the accuracy of a model"""
    model.eval()
    total, correct = 0, 0
    for (images, labels, _) in data_loader:
        images = images.to(device)
        labels = labels.to(device)
        ypred = model(images)
        output = F.softmax(ypred, dim=1)
        correct += torch.sum(torch.argmax(output, dim=1) == labels)
        total += labels.shape[0]
    return float(correct / total)

def accuracy_batch(ypred, labels):
    """Computes the accuracy of a model"""
    output = F.softmax(ypred, dim=1)
    correct = torch.sum(torch.argmax(output, dim=1) == labels)
    return float(correct / labels.shape[0])

def train(train_loader, test_loader, epoch_idx, model1, optimizer1, model2, optimizer2):
    """Train the two models using Co-teaching method"""
    print(f'epoch {epoch_idx+1}/{n_epoch}')
    remember_rate = 1 - max(forget_rate, forget_rate * (epoch_idx/epoch_decay_start))
    for batch_idx, (images, labels, _) in enumerate(train_loader):
        num_remember = int(remember_rate * labels.shape[0])
        images = images.to(device)
        labels = labels.to(device)
        logits1 = model1(images)
        logits2 = model2(images)
        loss_1, loss_2 = loss_coteaching(logits1, logits2, labels, num_remember)
        optimizer1.zero_grad()
        loss_1.backward()
        optimizer1.step()
        optimizer2.zero_grad()
        loss_2.backward()
        optimizer2.step()
    accuracy1, accuracy2 = evaluate(test_loader, model1, model2)
    print(f"accuracy of model 1 on test set: {accuracy1*100}\naccuracy of model 2 on test set: {accuracy2*100}")

@torch.no_grad()
def evaluate(test_loader, model1, model2):
    """Evaluate model1, model2"""
    model1.eval()
    total, correct1, correct2 = 0, 0, 0
    for (images, labels, _) in test_loader:
        total += labels.shape[0]
        images = images.to(device)
        labels = labels.to(device)
        ypred1 = model1(images)
        probs1 = F.softmax(ypred1, dim=1)
        correct1 += torch.sum(torch.argmax(probs1, dim=1) == labels)
        ypred2 = model2(images)
        probs2 = F.softmax(ypred2, dim=1)
        correct2 += torch.sum(torch.argmax(probs2, dim=1) == labels)
    return float(correct1 / total), float(correct2 / total)

# Construting TensorDatasets
print('Construting datasets ...')
train_dataset = CIFAR10('data', train=True, download=True, noise_type=noise_type, noise_rate=noise_rate, transform=Compose([
    ToTensor(),
    Normalize(mean=mean, std=std)]))
test_dataset = CIFAR10('data', train=False, download=True, noise_type=noise_type, noise_rate=noise_rate, transform=Compose([
    ToTensor(),
    Normalize(mean=mean, std=std)]))

# Construting DataLoaders
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, pin_memory=True, num_workers=4, persistent_workers=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, pin_memory=True, num_workers=4, persistent_workers=True)

cnn1 = CNN(input_channel=input_channel, n_outputs=num_classes).to(device)
cnn2 = CNN(input_channel=input_channel, n_outputs=num_classes).to(device)

optimizer1 = torch.optim.Adam(cnn1.parameters(), lr=learning_rate)
optimizer2 = torch.optim.Adam(cnn2.parameters(), lr=learning_rate)

# Train modelsn_epoch
n_epoch = min(n_epoch, int(epoch_decay_start/forget_rate))
for epoch_idx in range(n_epoch):
    cnn1.train()
    cnn2.train()
    adjust_learning_rate(optimizer1, epoch_idx)
    adjust_learning_rate(optimizer2, epoch_idx)
    train(train_loader, test_loader, epoch_idx, cnn1, optimizer1, cnn2, optimizer2)


import torch.nn as nn
import torch
import math
from codebase.models.nns.BBBLayer import BBBLayer

class BBBLinear(BBBLayer):
    """
    One feedforward linear layer with BBB (without nonlinearity)
    Adapted from torch.nn.Linear
    with Gaussian mixture as prior
    """
    def __init__(self, in_features, out_features, *args, **kwargs):
        super(BBBLinear, self).__init__(*args, **kwargs)

        self.in_features = in_features
        self.out_features = out_features
        self.weight_mean = nn.Parameter(torch.Tensor(out_features, in_features))
        self.bias_mean = nn.Parameter(torch.Tensor(out_features))
        if self.BBB is True:
            self.weight_logvar = \
                nn.Parameter(torch.Tensor(out_features, in_features))
            self.bias_logvar = nn.Parameter(torch.Tensor(out_features))

        # used for KL
        self.means = [self.weight_mean, self.bias_mean]
        if self.BBB is True:
            self.logvars = [self.weight_logvar, self.bias_logvar]

        self.reset_parameters()

    def reset_parameters(self):
        """
        Parameter initialization
        Using simple uniform distribution
        Consider other methods such as He and Xavier
        """
        stdv_init = 1. / math.sqrt(self.weight_mean.size(1))
        for mean in self.means:
            mean.data.uniform_(-stdv_init, stdv_init)
        if self.BBB is True:
            logvar_init = math.log(stdv_init) * 2
            for logvar in self.logvars:
                logvar.data.fill_(logvar_init)

    def forward(self, inputs):
        if self.BBB:
            # if use BBB and it is training
            self.sample()
            weight = self.sampled_weights[0]
            bias = self.sampled_weights[1]
        else:
            # use only mean for testing or non BBB
            weight = self.weight_mean
            bias = self.bias_mean
        return nn.functional.linear(inputs, weight, bias)


class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Line:
    PRECISION = 4

    def __init__(self, p1, p2):
        if Line.equal(p1.x, p2.x):
            self.slope = float('inf')
            self.intercept = Line.round(p1.x)
        else:
            self.slope = Line.round((p1.y - p2.y) / (p1.x - p2.x))
            self.intercept = Line.round(p1.y - p1.x * self.slope)

    def __eq__(self, line):
        return (self.slope, line.slope) == (self.intercept, line.intercept)

    def __hash__(self):
        return hash((self.slope, self.intercept))

    @staticmethod
    def round(val):
        return round(val, Line.PRECISION)

    @staticmethod
    def equal(a, b):
        return Line.round(a) == Line.round(b)

def search_line(points):
    count = {}
    for i in range(len(points)):
        for j in range(i + 1, len(points)):
            p1 = points[i]
            p2 = points[j]
            line = Line(p1, p2)
            if line not in count:
                count[line] = 0
            count[line] += 1

    max_count = 0
    best_line = None
    for line, c in count.items():
        if c > max_count:
            max_count = c
            best_line = line
    return best_line


n=int(input())
sn=n*n
rev=0
while n>0:
    r=n%10
    rev=rev*10+r
    n=n//10
rn=rev
srn=rn*rn
rev1=0
while srn>0:
    r=srn%10
    rev1=rev1*10+r
    srn=srn//10
print(rev1==sn)


import geopandas
from shapely.geometry import Point
import numpy as np
import pandas as pd
import re

neighborhoods = geopandas.read_file('nynta_17d/nynta.shp')
dataset = pd.read_csv("/Users/pravarsingh/Desktop/Study Material/sem 3/Big Data Analytics/project/NYPD_Complaint_Data_Historic_Cleaned.csv", engine='python',index_col=None, header=None,error_bad_lines=False)
dataset[23] = None

#For handling invalid values
latlong_regex = re.compile(r'(\([^\(\)]+\))')

# Map crimes to neighborhoods
def find_neighborhood(x_coord, y_coord):
    '''
    Takes a pair of X and Y coordinates (using the NAD_1983_StatePlane_New_York_Long_Island coordinate system)
    and returns the corresponding New York City neighborhood.
    '''

    x_coord = re.sub(latlong_regex, r'\1', x_coord)
    y_coord = re.sub(latlong_regex, r'\1', y_coord)
    if np.isnan(x_coord) or np.isnan(y_coord):
        return np.nan

    matches = neighborhoods.geometry.contains(Point(x_coord, y_coord))

    if any(matches):
        return neighborhoods.loc[matches, 'NTAName'].values[0]

    return np.nan

years = range(2006, 2016)

for crime_type in ['felony', 'misdemeanor', 'violation']:
    for year in years:
        # Define filename
        folder = dataloc + '/bk_slice_' + crime_type + '/'
        filename = folder + crime_type + '_{}_desc_year_borough'.format(year)

         # Drop any rows that are missing x or y coordinates
        dataset = dataset[~pd.isnull(dataset[19])]
        dataset = dataset[~pd.isnull(dataset[20])]

        for index, row in dataset.iterrows():
            dataset[23][index] = find_neighborhood(row[19],row[20])
            print(dataset[23][index])

        dataset.to_csv(filename + "_with_hood.out", index=False)

#Usage:
#print(find_neighborhood(1004528,195225))


from datasets import load_dataset
import requests
import time

# Load the dataset
dataset = load_dataset("brianarbuckle/cocktail_recipes", split="train[200:300]") # Only load first 100 recipes

def send_to_api(data):
    api_url = "https://cocktail-rag.beefie.xyz/doc/add"
    print("-----------------------------------------------")
    print(f"Data Length: {len(data)}")
    print(data)
    payload = {"data": data}
    response = requests.post(api_url, json=payload)

    if response.status_code == 200:
        print("Successfully sent data to API.")
    else:
        print("Failed to send data to API.")
    time.sleep(0.5)

# Iterate over the dataset
for item in dataset:
    # Create an array of strings to hold the recipe information
    recipe_details = [
        f"Title: {item['title']}\n",
        f"Keywords: {', '.join(item['ner'])}\n",
        "Ingredients:\n" + "\n".join([f"- {ingredient}" for ingredient in item['ingredients']]) + "\n",
        "Directions:\n" + "\n".join([f"- {direction}" for direction in item['directions']]) + "\n",
        f"Source: {item['source']}\n"
    ]

    # Join all the strings in the array with newline characters
    full_recipe = "\n".join(recipe_details)

    # Send the full recipe string to the API
    send_to_api(full_recipe)


import numpy as np

from tensorflow.python.framework import ops
from tensorflow.python.framework import tensor
from tensorflow.python.framework import tensor_conversion
from tensorflow.python.keras import backend_config
from tensorflow.python.keras.optimizer_v2 import optimizer_v2
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import gen_training_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import state_ops

class RMSprop(optimizer_v2.OptimizerV2):
  r"""Optimizer that implements the RMSprop algorithm.

  The gist of RMSprop is to:

  - Maintain a moving (discounted) average of the square of gradients
  - Divide the gradient by the root of this average

  This implementation of RMSprop uses plain momentum, not Nesterov momentum.

  The centered version additionally maintains a moving average of the
  gradients, and uses that average to estimate the variance.

  Args:
    learning_rate: A `Tensor`, floating point value, or a schedule that is a
      `tf.keras.optimizers.schedules.LearningRateSchedule`, or a callable
      that takes no arguments and returns the actual value to use. The
      learning rate. Defaults to 0.001.
    rho: Discounting factor for the history/coming gradient. Defaults to 0.9.
    momentum: A scalar or a scalar `Tensor`. Defaults to 0.0.
    epsilon: A small constant for numerical stability. This epsilon is
      "epsilon hat" in the Kingma and Ba paper (in the formula just before
      Section 2.1), not the epsilon in Algorithm 1 of the paper. Defaults to
      1e-7.
    centered: Boolean. If `True`, gradients are normalized by the estimated
      variance of the gradient; if False, by the uncentered second moment.
      Setting this to `True` may help with training, but is slightly more
      expensive in terms of computation and memory. Defaults to `False`.
    name: Optional name prefix for the operations created when applying
      gradients. Defaults to `"RMSprop"`.
    **kwargs: Keyword arguments. Allowed to be one of
      `"clipnorm"` or `"clipvalue"`.
      `"clipnorm"` (float) clips gradients by norm; `"clipvalue"` (float) clips
      gradients by value.

  Note that in the dense implementation of this algorithm, variables and their
  corresponding accumulators (momentum, gradient moving average, square
  gradient moving average) will be updated even if the gradient is zero
  (i.e. accumulators will decay, momentum will be applied). The sparse
  implementation (used when the gradient is an `IndexedSlices` object,
  typically because of `tf.gather` or an embedding lookup in the forward pass)
  will not update variable slices or their accumulators unless those slices
  were used in the forward pass (nor is there an "eventual" correction to
  account for these omitted updates). This leads to more efficient updates for
  large embedding lookup tables (where most of the slices are not accessed in
  a particular graph execution), but differs from the published algorithm.

  Usage:

  >>> opt = tf.keras.optimizers.RMSprop(learning_rate=0.1)
  >>> var1 = tf.Variable(10.0)
  >>> loss = lambda: (var1 ** 2) / 2.0    # d(loss) / d(var1) = var1
  >>> step_count = opt.minimize(loss, [var1]).numpy()
  >>> var1.numpy()
  9.683772

  Reference:
    - [Hinton, 2012](
      http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf)
  """

  _HAS_AGGREGATE_GRAD = True

  def __init__(self,
               learning_rate=0.001,
               rho=0.9,
               momentum=0.0,
               epsilon=1e-7,
               centered=False,
               name="RMSprop",
               **kwargs):
    """Construct a new RMSprop optimizer.

    Args:
      learning_rate: A `Tensor`, floating point value, or a schedule that is a
        `tf.keras.optimizers.schedules.LearningRateSchedule`, or a callable
        that takes no arguments and returns the actual value to use. The
        learning rate. Defaults to 0.001.
      rho: Discounting factor for the history/coming gradient. Defaults to 0.9.
      momentum: A scalar or a scalar `Tensor`. Defaults to 0.0.
      epsilon: A small constant for numerical stability. This epsilon is
        "epsilon hat" in the Kingma and Ba paper (in the formula just before
        Section 2.1), not the epsilon in Algorithm 1 of the paper. Defaults to
        1e-7.
      centered: Boolean. If `True`, gradients are normalized by the estimated
        variance of the gradient; if False, by the uncentered second moment.
        Setting this to `True` may help with training, but is slightly more
        expensive in terms of computation and memory. Defaults to `False`.
      name: Optional name prefix for the operations created when applying
        gradients. Defaults to "RMSprop".
      **kwargs: keyword arguments. Allowed to be {`clipnorm`, `clipvalue`, `lr`,
        `decay`}. `clipnorm` is clip gradients by norm; `clipvalue` is clip
        gradients by value, `decay` is included for backward compatibility to
        allow time inverse decay of learning rate. `lr` is included for backward
        compatibility, recommended to use `learning_rate` instead.

    @compatibility(eager)
    When eager execution is enabled, `learning_rate`, `decay`, `momentum`, and
    `epsilon` can each be a callable that takes no arguments and returns the
    actual value to use. This can be useful for changing these values across
    different invocations of optimizer functions.
    @end_compatibility
    """
    super(RMSprop, self).__init__(name, **kwargs)
    self._set_hyper("learning_rate", kwargs.get("lr", learning_rate))
    self._set_hyper("decay", self._initial_decay)
    self._set_hyper("rho", rho)

    self._momentum = False
    if isinstance(
        momentum, tensor.Tensor) or callable(momentum) or momentum > 0:
      self._momentum = True
    if isinstance(momentum, (int, float)) and (momentum < 0 or momentum > 1):
      raise ValueError("`momentum` must be between [0, 1].")
    self._set_hyper("momentum", momentum)

    self.epsilon = epsilon or backend_config.epsilon()
    self.centered = centered

  def _create_slots(self, var_list):
    for var in var_list:
      self.add_slot(var, "rms")
    if self._momentum:
      for var in var_list:
        self.add_slot(var, "momentum")
    if self.centered:
      for var in var_list:
        self.add_slot(var, "mg")

  def _prepare_local(self, var_device, var_dtype, apply_state):
    super(RMSprop, self)._prepare_local(var_device, var_dtype, apply_state)

    rho = array_ops.identity(self._get_hyper("rho", var_dtype))
    apply_state[(var_device, var_dtype)].update(
        dict(
            neg_lr_t=-apply_state[(var_device, var_dtype)]["lr_t"],
            epsilon=tensor_conversion.convert_to_tensor_v2_with_dispatch(
                self.epsilon, var_dtype
            ),
            rho=rho,
            momentum=array_ops.identity(self._get_hyper("momentum", var_dtype)),
            one_minus_rho=1.0 - rho,
        )
    )

  def _resource_apply_dense(self, grad, var, apply_state=None):
    var_device, var_dtype = var.device, var.dtype.base_dtype
    coefficients = ((apply_state or {}).get((var_device, var_dtype))
                    or self._fallback_apply_state(var_device, var_dtype))

    rms = self.get_slot(var, "rms")
    if self._momentum:
      mom = self.get_slot(var, "momentum")
      if self.centered:
        mg = self.get_slot(var, "mg")
        return gen_training_ops.ResourceApplyCenteredRMSProp(
            var=var.handle,
            mg=mg.handle,
            ms=rms.handle,
            mom=mom.handle,
            lr=coefficients["lr_t"],
            rho=coefficients["rho"],
            momentum=coefficients["momentum"],
            epsilon=coefficients["epsilon"],
            grad=grad,
            use_locking=self._use_locking)
      else:
        return gen_training_ops.ResourceApplyRMSProp(
            var=var.handle,
            ms=rms.handle,
            mom=mom.handle,
            lr=coefficients["lr_t"],
            rho=coefficients["rho"],
            momentum=coefficients["momentum"],
            epsilon=coefficients["epsilon"],
            grad=grad,
            use_locking=self._use_locking)
    else:
      rms_t = (coefficients["rho"] * rms +
               coefficients["one_minus_rho"] * math_ops.square(grad))
      rms_t = state_ops.assign(rms, rms_t, use_locking=self._use_locking)
      denom_t = rms_t
      if self.centered:
        mg = self.get_slot(var, "mg")
        mg_t = coefficients["rho"] * mg + coefficients["one_minus_rho"] * grad
        mg_t = state_ops.assign(mg, mg_t, use_locking=self._use_locking)
        denom_t = rms_t - math_ops.square(mg_t)
      var_t = var - coefficients["lr_t"] * grad / (
          math_ops.sqrt(denom_t) + coefficients["epsilon"])
      return state_ops.assign(var, var_t, use_locking=self._use_locking).op

  def _resource_apply_sparse(self, grad, var, indices, apply_state=None):
    var_device, var_dtype = var.device, var.dtype.base_dtype
    coefficients = ((apply_state or {}).get((var_device, var_dtype))
                    or self._fallback_apply_state(var_device, var_dtype))

    rms = self.get_slot(var, "rms")
    if self._momentum:
      mom = self.get_slot(var, "momentum")
      if self.centered:
        mg = self.get_slot(var, "mg")
        return gen_training_ops.ResourceSparseApplyCenteredRMSProp(
            var=var.handle,
            mg=mg.handle,
            ms=rms.handle,
            mom=mom.handle,
            lr=coefficients["lr_t"],
            rho=coefficients["rho"],
            momentum=coefficients["momentum"],
            epsilon=coefficients["epsilon"],
            grad=grad,
            indices=indices,
            use_locking=self._use_locking)
      else:
        return gen_training_ops.ResourceSparseApplyRMSProp(
            var=var.handle,
            ms=rms.handle,
            mom=mom.handle,
            lr=coefficients["lr_t"],
            rho=coefficients["rho"],
            momentum=coefficients["momentum"],
            epsilon=coefficients["epsilon"],
            grad=grad,
            indices=indices,
            use_locking=self._use_locking)
    else:
      rms_scaled_g_values = (grad * grad) * coefficients["one_minus_rho"]
      rms_t = state_ops.assign(rms, rms * coefficients["rho"],
                               use_locking=self._use_locking)
      with ops.control_dependencies([rms_t]):
        rms_t = self._resource_scatter_add(rms, indices, rms_scaled_g_values)
        rms_slice = array_ops.gather(rms_t, indices)
      denom_slice = rms_slice
      if self.centered:
        mg = self.get_slot(var, "mg")
        mg_scaled_g_values = grad * coefficients["one_minus_rho"]
        mg_t = state_ops.assign(mg, mg * coefficients["rho"],
                                use_locking=self._use_locking)
        with ops.control_dependencies([mg_t]):
          mg_t = self._resource_scatter_add(mg, indices, mg_scaled_g_values)
          mg_slice = array_ops.gather(mg_t, indices)
          denom_slice = rms_slice - math_ops.square(mg_slice)
      var_update = self._resource_scatter_add(
          var, indices, coefficients["neg_lr_t"] * grad / (
              math_ops.sqrt(denom_slice) + coefficients["epsilon"]))
      if self.centered:
        return control_flow_ops.group(*[var_update, rms_t, mg_t])
      return control_flow_ops.group(*[var_update, rms_t])

  def set_weights(self, weights):
    params = self.weights
    # Override set_weights for backward compatibility of Keras V1 optimizer
    # since it does not include iteration at head of the weight list. Set
    # iteration to 0.
    if len(params) == len(weights) + 1:
      weights = [np.array(0)] + weights
    super(RMSprop, self).set_weights(weights)

  def get_config(self):
    config = super(RMSprop, self).get_config()
    config.update({
        "learning_rate": self._serialize_hyperparameter("learning_rate"),
        "decay": self._initial_decay,
        "rho": self._serialize_hyperparameter("rho"),
        "momentum": self._serialize_hyperparameter("momentum"),
        "epsilon": self.epsilon,
        "centered": self.centered,
    })
    return config

RMSProp = RMSprop


from zope.event import notify
from zope.interface import implements

from ZODB.transact import transact

from Products.ZenUtils.Ext import DirectRouter, DirectResponse

from Products import Zuul
from Products.Zuul.catalog.events import IndexingEvent
from Products.Zuul.facades import ZuulFacade
from Products.Zuul.interfaces import IFacade
from Products.Zuul.utils import ZuulMessageFactory as _t

class IAWSFacade(IFacade):
    '''
    Python API interface.
    '''

    def add_ec2account(self, accountname, accesskey, secretkey, collector):
        '''
        Schedule the addition of an EC2 account.
        '''

    def setDeviceClassInfo(self, uid, linux=None, windows=None):
        '''
        Set the device classes into which to discovery the guest device
        devices from Linux and Windows instance platform respectively.
        '''

class AWSFacade(ZuulFacade):
    '''
    Python API implementation.
    '''

    implements(IAWSFacade)

    def add_ec2account(self, accountname, accesskey, secretkey, collector):
        deviceRoot = self._dmd.getDmdRoot("Devices")
        device = deviceRoot.findDeviceByIdExact(accountname)
        if device:
            return False, _t("A device named %s already exists." % accountname)

        @transact
        def create_device():
            dc = self._dmd.Devices.getOrganizer('/Devices/AWS/EC2')

            account = dc.createInstance(accountname)
            account.setPerformanceMonitor(collector)

            account.ec2accesskey = accesskey
            account.ec2secretkey = secretkey

            account.index_object()
            notify(IndexingEvent(account))

        # This must be committed before the following model can be
        # scheduled.
        create_device()

        # Schedule a modeling job for the new account.
        account = deviceRoot.findDeviceByIdExact(accountname)
        account.collectDevice(setlog=False, background=True)

        return True

    def setDeviceClassInfo(self, uid, linux=None, windows=None):
        account = self._getObject(uid)

        if not linux:
            linux = None

        if not windows:
            windows = None

        if account.linuxDeviceClass != linux:
            account.linuxDeviceClass = linux

        if account.windowsDeviceClass != windows:
            account.windowsDeviceClass = windows

class AWSRouter(DirectRouter):
    '''
    ExtJS DirectRouter API implementation.
    '''

    def _getFacade(self):
        return Zuul.getFacade('aws', self.context)

    def add_ec2account(self, accountname, accesskey, secretkey, collector):
        success = self._getFacade().add_ec2account(
            accountname, accesskey, secretkey, collector)

        if success:
            return DirectResponse.succeed()
        else:
            return DirectResponse.fail("Failed to add EC2 account")

    def setDeviceClassInfo(self, uid, linux=None, windows=None):
        self._getFacade().setDeviceClassInfo(uid, linux=linux, windows=windows)


# write a program that corrects: Hello-This-is-a-text-file.

'''with open('text.txt','w+') as file:
    file.write("Hello-This-is-a-text-file.")
    file.close()
data=file.readlines()
    for line in data:
        word=line.split()
        print(word)

with open('text.txt','r') as file2:
    word=file2.read()
    for line in word:
        while line== "-":
            line == " "
            new=line
    print(new)'''

file=open("text.txt",'w+')
file.writelines("Hello-This-is-Python-class.")
text=file.readline()
text2= text.replace('-',' ')
print(text2)
file.close()


import asyncio
import copy
import logging
import os
import pickle
from typing import Dict, List, Optional

from torrent_client.algorithms import TorrentManager
from torrent_client.models import generate_peer_id, TorrentInfo, TorrentState
from torrent_client.network import PeerTCPServer
from torrent_client.utils import import_signals

QObject, pyqtSignal = import_signals()

__all__ = ['ControlManager']

state_filename = os.path.expanduser('~/.torrent_gui_state')

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

class ControlManager(QObject):
    if pyqtSignal:
        torrents_suggested = pyqtSignal(list)
        torrent_added = pyqtSignal(TorrentState)
        torrent_changed = pyqtSignal(TorrentState)
        torrent_removed = pyqtSignal(bytes)

    def __init__(self):
        super().__init__()

        self._our_peer_id = generate_peer_id()

        self._torrents = {}          # type: Dict[bytes, TorrentInfo]
        self._torrent_managers = {}  # type: Dict[bytes, TorrentManager]

        self._server = PeerTCPServer(self._our_peer_id, self._torrent_managers)

        self._torrent_manager_executors = {}  # type: Dict[bytes, asyncio.Task]
        self._state_updating_executor = None  # type: Optional[asyncio.Task]

        self.last_torrent_dir = None   # type: Optional[str]
        self.last_download_dir = None  # type: Optional[str]

    def get_torrents(self) -> List[TorrentInfo]:
        return list(self._torrents.values())

    async def start(self):
        await self._server.start()

    def _start_torrent_manager(self, torrent_info: TorrentInfo):
        info_hash = torrent_info.download_info.info_hash

        manager = TorrentManager(torrent_info, self._our_peer_id, self._server.port)
        if pyqtSignal:
            manager.state_changed.connect(lambda: self.torrent_changed.emit(TorrentState(torrent_info)))
        self._torrent_managers[info_hash] = manager
        self._torrent_manager_executors[info_hash] = asyncio.ensure_future(manager.run())

    def add(self, torrent_info: TorrentInfo):
        info_hash = torrent_info.download_info.info_hash
        if info_hash in self._torrents:
            raise ValueError('This torrent is already added')

        if not torrent_info.paused:
            self._start_torrent_manager(torrent_info)
        self._torrents[info_hash] = torrent_info

        if pyqtSignal:
            self.torrent_added.emit(TorrentState(torrent_info))

    def resume(self, info_hash: bytes):
        if info_hash not in self._torrents:
            raise ValueError('Torrent not found')
        torrent_info = self._torrents[info_hash]
        if not torrent_info.paused:
            raise ValueError('The torrent is already running')

        self._start_torrent_manager(torrent_info)

        torrent_info.paused = False

        if pyqtSignal:
            self.torrent_changed.emit(TorrentState(torrent_info))

    async def _stop_torrent_manager(self, info_hash: bytes):
        manager_executor = self._torrent_manager_executors[info_hash]
        manager_executor.cancel()
        try:
            await manager_executor
        except asyncio.CancelledError:
            pass
        del self._torrent_manager_executors[info_hash]

        manager = self._torrent_managers[info_hash]
        del self._torrent_managers[info_hash]
        await manager.stop()

    async def remove(self, info_hash: bytes):
        if info_hash not in self._torrents:
            raise ValueError('Torrent not found')
        torrent_info = self._torrents[info_hash]

        del self._torrents[info_hash]
        if not torrent_info.paused:
            await self._stop_torrent_manager(info_hash)

        if pyqtSignal:
            self.torrent_removed.emit(info_hash)

    async def pause(self, info_hash: bytes):
        if info_hash not in self._torrents:
            raise ValueError('Torrent not found')
        torrent_info = self._torrents[info_hash]
        if torrent_info.paused:
            raise ValueError('The torrent is already paused')

        await self._stop_torrent_manager(info_hash)

        torrent_info.paused = True

        if pyqtSignal:
            self.torrent_changed.emit(TorrentState(torrent_info))

    def _dump_state(self):
        torrent_list = []
        for manager, torrent_info in self._torrents.items():
            torrent_info = copy.copy(torrent_info)
            torrent_info.download_info = copy.copy(torrent_info.download_info)
            torrent_info.download_info.reset_run_state()
            torrent_list.append(torrent_info)

        try:
            with open(state_filename, 'wb') as f:
                pickle.dump((self.last_torrent_dir, self.last_download_dir, torrent_list), f)
            logger.info('state saved (%s torrents)', len(torrent_list))
        except Exception as err:
            logger.warning('Failed to save state: %r', err)

    STATE_UPDATE_INTERVAL = 5 * 60

    async def _execute_state_updates(self):
        while True:
            await asyncio.sleep(ControlManager.STATE_UPDATE_INTERVAL)

            self._dump_state()

    def invoke_state_dumps(self):
        self._state_updating_executor = asyncio.ensure_future(self._execute_state_updates())

    def load_state(self):
        if not os.path.isfile(state_filename):
            return

        with open(state_filename, 'rb') as f:
            self.last_torrent_dir, self.last_download_dir, torrent_list = pickle.load(f)

        for torrent_info in torrent_list:
            self.add(torrent_info)
        logger.info('state recovered (%s torrents)', len(torrent_list))

    async def stop(self):
        await self._server.stop()

        tasks = list(self._torrent_manager_executors.values())
        if self._state_updating_executor is not None:
            tasks.append(self._state_updating_executor)

        for task in tasks:
            task.cancel()
        if tasks:
            await asyncio.wait(tasks)

        if self._torrent_managers:
            await asyncio.wait([manager.stop() for manager in self._torrent_managers.values()])

        if self._state_updating_executor is not None:  # Only if we have loaded starting state
            self._dump_state()


IMM_UHEX = None
IMM_SHEX = "shex"
IMM_UDEC = "udec"
IMM_SDEC = "sdec"
IMM_CHAR = "chr"
IMM_ADDR = "addr"

class InvalidAddrException(Exception):
    "Thrown when dereferencing address which doesn't exist in AddressSpace."
    def __init__(self, addr):
        self.args = (addr, hex(addr))


# CELL 1: Import necessary libraries

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding, LSTM, SpatialDropout1D
import matplotlib.pyplot as plt

# CELL 2: CONFIG
config = {
    "num_words": 150,
    "max_length": 130,
    "embedding_dim": 128,
    "batch_size": 128,
    "epochs": 50,
    "dropout": 0.1,
}

# CELL 3: Read data
df = pd.read_excel('Opcode (1).xlsx')

# CELL 4: Create the Tokenizer and fit on texts
tokenizer = Tokenizer(num_words=config["num_words"], lower=False)
tokenizer.fit_on_texts(df["OPCODE"].values)

# CELL 5: Convert text to sequences
sequences = tokenizer.texts_to_sequences(df["OPCODE"].values)

# CELL 6: Pad sequences
X = pad_sequences(sequences, maxlen=config["max_length"])

# CELL 7: Prepare labels
labels = df['Result'].apply(lambda x: 0 if x == '1 0 0 0' else 1)
y = to_categorical(labels)

# CELL 8: Split data into train, validation, and test
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp)

# CELL 9: Define the LSTM model
lstm_model = Sequential()
lstm_model.add(Embedding(input_dim=config["num_words"], output_dim=config["embedding_dim"], input_length=config["max_length"]))
lstm_model.add(SpatialDropout1D(config["dropout"]))
lstm_model.add(LSTM(64))
lstm_model.add(Dense(2, activation="softmax"))

# Compile the model
lstm_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])

# CELL 10: Train the LSTM model
lstm_history = lstm_model.fit(X_train, y_train, epochs=config["epochs"], batch_size=config["batch_size"], validation_data=(X_val, y_val))

# Get the history for training and validation metrics
train_loss = lstm_history.history['loss']
train_acc = lstm_history.history['acc']
val_loss = lstm_history.history['val_loss']
val_acc = lstm_history.history['val_acc']

# Evaluate the model on the test set
test_loss, test_acc = lstm_model.evaluate(X_test, y_test)

# Print the results
print("LSTM Model Train Loss:", train_loss[-1])
print("LSTM Model Train Accuracy:", train_acc[-1])
print("LSTM Model Validation Loss:", val_loss[-1])
print("LSTM Model Validation Accuracy:", val_acc[-1])
print("LSTM Model Test Loss:", test_loss)
print("LSTM Model Test Accuracy:", test_acc)

# Draw
plt.figure(figsize=(12, 4))

# Draw training & validation accuracy values
plt.subplot(1, 2, 1)
plt.plot(train_acc, label='Train')
plt.plot(val_acc, label='Validation')
plt.title('LSTM Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()

plt.tight_layout()
plt.savefig('lstm_train_val_plot.png')
plt.show()

import numpy as np

# test_data
test_data = pd.read_excel('Opcode (1).xlsx', usecols=['Address', 'OPCODE', 'Result'])

# Tokenize the OPCODE
sequences = tokenizer.texts_to_sequences(test_data["OPCODE"].values)
X_test = pad_sequences(sequences, maxlen=config["max_length"])

# Convert the categories to binary labels
y_test = test_data['Result'].apply(lambda x: 0 if x == '1 0 0 0' else 1)

# Convert to categorical
y_test = to_categorical(y_test)

# Evaluate the model
test_loss, test_acc = lstm_model.evaluate(X_test, y_test)

print('LSTM Model Test Loss: {}'.format(test_loss))
print('LSTM Model Test Accuracy: {}'.format(test_acc))

# Get predictions
y_pred = lstm_model.predict(X_test)
y_pred_classes = np.argmax(y_pred, axis=1)

# Convert y_test back from one-hot encoding
y_test_classes = np.argmax(y_test, axis=1)

# Generate confusion matrix and classification report
from sklearn.metrics import confusion_matrix, classification_report
cm = confusion_matrix(y_test_classes, y_pred_classes)

print("LSTM Model Confusion Matrix:")
print(cm)

print("LSTM Model Classification Report:")
print(classification_report(y_test_classes, y_pred_classes, target_names=['non vulnerable', 'vulnerable']))

# LSTM modal and train

from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

test_data = pd.read_excel('Opcode (1).xlsx', usecols=['Address', 'OPCODE', 'Result'])

test_data = test_data.sample(frac=0.2, random_state=42)

n = test_data[test_data.Result == '1 0 0 0']
s = test_data[test_data.Result == '0 1 0 0']
p = test_data[test_data.Result == '0 0 1 0']
g = test_data[test_data.Result == '0 0 0 1']

catarr = [n, s, p, g]
cat_names = ['non vulnerable', 'suicidial', 'prodigal', 'greedy']

for i, test_cat in enumerate(catarr):
    try:
        print("\nTesting for:", cat_names[i])

        # Process OPCODE data
        tokenizer = Tokenizer(num_words=config["num_words"], lower=False)
        tokenizer.fit_on_texts(test_cat["OPCODE"].values)
        sequences = tokenizer.texts_to_sequences(test_cat["OPCODE"].values)
        x_test_class = np.array(pad_sequences(sequences, maxlen=config["max_length"]))

        # For non vulnerable class, labels are all zeros. For other classes, labels are all ones.
        y_test_class = np.zeros(len(test_cat)) if i == 0 else np.ones(len(test_cat))

        # Evaluate the model
        y_pred = lstm_model.predict(x_test_class)
        y_pred_class = np.round(y_pred[:, 1]).astype(int)

        # Generate confusion matrix
        cm = confusion_matrix(y_test_class, y_pred_class)

        print(f"Test Accuracy: {accuracy_score(y_test_class, y_pred_class)}")
        print("Confusion Matrix: ")
        print(cm)
        print("Classification Report: ")
        print(classification_report(y_test_class, y_pred_class))

    except Exception as e:
        print(f"An error occurred while processing the {cat_names[i]} class. Error: {str(e)}")

# CELL 14: Test the model for each class separately

vulnerability_classes = ['non vulnerable', 'suicidial', 'prodigal', 'greedy']
class_indices = {0: 'non vulnerable', 1: 'suicidial', 2: 'prodigal', 3: 'greedy'}

# Convert y_test back from one-hot encoding
y_test_classes = np.argmax(y_test, axis=1)

for i, vulnerability in enumerate(vulnerability_classes):
    # Get the indices for each class
    indices = np.where(y_test_classes == i)

    # Separate the test data for this class
    x_test_class = X_test[indices]
    y_test_class = y_test[indices]

    # Check if the class has any entries in the test set
    if x_test_class.shape[0] > 0:
        # Evaluate the model on this class
        test_loss, test_acc = lstm_model.evaluate(x_test_class, y_test_class, verbose=0)

        # Get predictions
        y_pred = lstm_model.predict(x_test_class)
        y_pred_classes = np.argmax(y_pred, axis=1)

        # Generate confusion matrix
        from sklearn.metrics import confusion_matrix, classification_report
        cm = confusion_matrix(np.argmax(y_test_class, axis=1), y_pred_classes)

        print(f"\nFor {vulnerability} class:")
        print(f"Test Loss: {test_loss}")
        print(f"Test Accuracy: {test_acc}")
        print("Confusion Matrix: ")
        print(cm)
        print("Classification Report: ")
        print(classification_report(np.argmax(y_test_class, axis=1), y_pred_classes))
    else:
        print(f"No entries in the test set for {vulnerability} class.")