import configparser
from datetime import datetime
import os
from pyspark.sql import SparkSession
from pyspark.sql.functions import udf, col, monotonically_increasing_id
from pyspark.sql.functions import year, month, dayofmonth, hour, weekofyear, date_format
from pyspark.sql import types as t

# reading in the AWS config information from the dl.cfg file
config = configparser.ConfigParser()
config.read('dl.cfg')

os.environ['AWS_ACCESS_KEY_ID']        =config['AWS']['AWS_ACCESS_KEY_ID']
os.environ['AWS_SECRET_ACCESS_KEY']    =config['AWS']['AWS_SECRET_ACCESS_KEY']

print(os.environ['AWS_ACCESS_KEY_ID'] )
print(os.environ['AWS_SECRET_ACCESS_KEY'] )
#def create_spark_session():
#    spark = SparkSession \
#        .builder \
#        .config("spark.jars.packages", "org.apache.hadoop:hadoop-aws:2.7.0") \
#        .getOrCreate()
#    print("spark session created")
#    return spark

def create_spark_session():
    """
    This creates a Spark session, specifying the hadoop package to use, the S3 buckets and reads in the AWS ID and key as
    environment variables

    Parameters:
    None

    Returns:
    Spark session object
    """
    spark = SparkSession \
    .builder \
    .config("spark.jars.packages", "org.apache.hadoop:hadoop-aws:2.7.0") \
    .config("spark.hadoop.fs.s3a.impl","org.apache.hadoop.fs.s3a.S3AFileSystem") \
    .config("spark.hadoop.fs.s3a.awsAccessKeyId", os.environ['AWS_ACCESS_KEY_ID']) \
    .config("spark.hadoop.fs.s3a.awsSecretAccessKey", os.environ['AWS_SECRET_ACCESS_KEY']) \
    .getOrCreate()
    print("spark session created")
    return spark

def process_song_data(spark, input_data, output_data):
    """
    This reads in song and artist data as csv files from the udacity s3 bucket as a spark dataframe
    and then uses spark_sql to insert select columns into a parquet file format back into the user-generated S3 bucket

    Parameters:
    spark:         A spark session object
    input_data:    A string representing the udacity-generated s3 bucket root
    output_data:   A string representing the user-generated s3 bucket root

    Output:
    No output returned: but two parquet files written to user-generated s3 bucket

    """
    # get filepath to song data file
    song_data = input_data +"song_data/*/*/*/*.json"

    print(song_data)
    # read song data file
    print("reading in song data")
    df = spark.read.json(song_data)

    # extract columns to create songs table
    df.createOrReplaceTempView("songs_table_df")

    songs_table = spark.sql("""
                            SELECT song_id, title, artist_id,year, duration
                            FROM songs_table_df
                            ORDER by song_id
                            """)

    # write songs table to parquet files partitioned by year and artist
    songs_table_path = output_data + "songs_table.parquet"

    print("read to songs table to parquet format")
    songs_table.write.mode("overwrite").partitionBy("year","artist_id").parquet(songs_table_path)

    # extract columns to create artists table
    df.createOrReplaceTempView("artist_table_df")
    artists_table = spark.sql( """
                                SELECT artist_id AS artist_id,
                                artist_name AS name,
                                artist_location AS location,
                                artist_latitude AS latitude,
                                artist_longitute AS longitude
                                FROM artist_table_df
                               """)

    # write artists table to parquet files
    artists_table_path = output_data + "artists_table.parquet"

    print("write to artist table")
    artists_table.write.mode("overwrite").parquet(artist_table_path)

def process_log_data(spark, input_data, output_data):
    """
    This reads in log_data from the udacity-generated s3 bucket, where the data relates to songs played, and this is written to a parquet file.
    It then takes a subset of the log_data, creates time- and date- stamps by using a udf with lambdas, and this is written to a parquet file.
    Song data is then read into a data frame and joined with log data to create a joined table, which is written to a parquet file.

    Parameters:
    spark:         A spark session object
    input_data:    A string representing the udacity-generated s3 bucket root
    output_data:   A string representing the user-generated s3 bucket root

    Returns:
    users_table:   A spark dataframe holding user information
    time_table:    A spark dataframe holding time information
    songplays_table: A spark dataframe holding songplay information
    """

    # get filepath to log data file
    log_data = input_data + "log_data/*.json"

    print("reading in log data")
    # read log data file
    df_log = spark.read.json(log_data)

    # filter by actions for song plays
    df_log = df_log.filter(df.page == 'NextSong')

    # extract columns for users table
    df_log.createOrReplaceTempView("users_table_df")
    users_table = spark.sql("""
                              SELECT DISTINCT userId AS userid,
                              firstName AS first_name,
                              lastName AS last_name,
                              gender,
                              level
                              FROM users_table_df
                              ORDER BY last_name
                              """)

    print("writing to parquet format")
    # write users table to parquet files
    users_table_path = output_data + "users_table.parquet"

    users_table.write.mode("overwrite").parquet(users_table_path)

    # create timestamp column from original timestamp column
    get_timestamp = udf(lambda x: datetime.fromtimestamp((x/1000.0)),TimestampType())
    df_log = df_log.withColumn("timestamp", gettimestamp("ts"))

    # create datetime column from original timestamp column
    get_datetime = udf(lambda x: datetime.fromtimestamp(ts/1000.0).strfrmtime('%Y-%m-%d %H:%M:%S'))
    df_log = df_log.withColumn("datetime",get_datetime("ts"))

    # extract columns to create time table
    df_log.createOrReplaceTempView("time_table_df")

    time_table = spark.sql("""SELECT DISTINCT
                             datetime as start_time,
                             hour(timestamp) as hour,
                             day(timestamp) as day,
                             weekofyear(timestamp) as week,
                             month(timestamp) as month,
                             year(timestamp) as year,
                             dayofweek(timestamp) as weekday
                             FROM time_table_df
                             ORDER BY start_time

                           """)

    # write time table to parquet files partitioned by year and month
    time_table_path = output_data + "time_table.parquet"
    time_table.write.mode("overwrite").partitionBy("year","month").parquet(time_table_path)

    # read in song data to use for songplays table
    song_df = spark.read.json(song_data)

    #join log and song df together
    df_log_song_df_joined = df_log_filtered.join(df_song, (df_log_filtered.artist == df_song.artist_name) & (df_log_filtered.song == df_song.title))

    # extract columns from joined song and log datasets to create songplays table

    df_log_song_df_joined.createOrReplaceTempView("songplays_table_df")

    songplays_table = spark.sql("""
        SELECT  songplay_id AS songplay_id,
                timestamp   AS start_time,
                userId      AS user_id,
                level       AS level,
                song_id     AS song_id,
                artist_id   AS artist_id,
                sessionId   AS session_id,
                location    AS location,
                userAgent   AS user_agent
        FROM songplays_table_DF
        ORDER BY (user_id, session_id)
    """)

    # write songplays table to parquet files partitioned by year and month
    songplays_table_path = output_data + "songplays_table.parquet"

    songplays_table.write.mode("overwrite").partitionBy("year","month").parquet(songplays_table_path)

    return users_table, time_table, songplays_table

def main():
    """
    Main function for the code.
    It creates a spark session, defines the paths of the input and ouput buckets, and call the two functions
    process_song_data and process_log_data
    """
    spark = create_spark_session()
    input_data = "s3a://udacity-dend/"
    output_data = "s3a://udacity-lake/output_data/"

    process_song_data(spark, input_data, output_data)
    process_log_data(spark, input_data, output_data)

if __name__ == "__main__":
    main()


import logging
import json

from discord import Interaction, app_commands, Role
from discord.app_commands import Choice
from discord.ext.commands import Bot, Cog

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

with open("config.json") as cfg_json:
    cfg = json.loads(cfg_json.read())

owner_id = cfg["owner_id"]

async def log_reply(ctx: Interaction, response: str, ephemeral=True):
    log = f"From {ctx.user}: {response}"
    if ctx.guild:
        log = f"From {ctx.user} in {ctx.guild.name}: {response}"
    logger.info(log)
    await ctx.response.send_message(response, ephemeral=ephemeral)

async def is_owner(ctx: Interaction) -> bool:
    if ctx.user.id != owner_id:
        await log_reply(ctx, f"**Error:** Only my owner can use this command")
        return False
    return True

class CommandError(Exception):
    def __init__(self, msg: str):
        self.msg = msg
        super().__init__(msg)

    @classmethod
    async def send_err(cls, ctx: Interaction, msg: str):
        self = cls(msg)
        await log_reply(ctx, self.msg)
        return self

class OwnerCog(Cog):
    """Commands that can only be used by the bot's owner"""

    def __init__(self, bot: Bot):
        self.bot = bot

    @app_commands.command(name="sync")
    @app_commands.check(is_owner)
    async def sync_commands(self, ctx: Interaction):
        """(Owner only) Syncs app command info with Discord"""
        await self.bot.tree.sync()
        await log_reply(ctx, "Synced command tree with Discord")

    emote = app_commands.Group(
        name="emote",
        description=("(Owner only) Modify DGG emote translations"),
    )

    @emote.command(name="add")
    @app_commands.describe(
        dgg_version="The emote as it's used in DGG",
        disc_version="The emote as it's used in Discord",
    )
    @app_commands.check(is_owner)
    async def add_emote(self, ctx: Interaction, dgg_version: str, disc_version: str):
        """(Owner only) Add or modify a DGG emote translation"""
        self.bot.emotes[dgg_version] = disc_version
        self.bot.save_cfg()
        await log_reply(ctx, f"Translating {dgg_version} to {str(disc_version)}")

    @emote.command(name="remove")
    @app_commands.describe(dgg_version="The emote to remove (in DGG format)")
    @app_commands.check(is_owner)
    async def remove_emote(self, ctx: Interaction, dgg_version: str):
        """(Owner only) Remove a DGG emote translation"""
        if dgg_version in self.bot.emotes.keys():
            removed_emote = self.bot.emotes.pop(dgg_version)
            self.bot.save_cfg()
            await log_reply(ctx, f"Removed {removed_emote} from emotes")
        else:
            await log_reply(ctx, f"Couldn't find emote {dgg_version}")

    config = app_commands.Group(
        name="config",
        description=("(Owner only) Modify the bot's config file"),
    )

    @config.command(name="remove")
    @app_commands.choices(
        mode=[
            Choice(name="phrase", value="phrase"),
            Choice(name="relay", value="relay"),
        ]
    )
    @app_commands.check(is_owner)
    async def config_remove(self, ctx: Interaction, mode: str, value: str):
        """Remove a relay or phrase from the config file"""
        if mode == "phrase" and value in self.bot.phrases:
            del self.bot.phrases[value]
            self.bot.save_cfg()
            await log_reply(ctx, f"Removed '{value}' from phrases", ephemeral=False)
        elif mode == "relay" and value in self.bot.relays:
            del self.bot.relays[value]
            self.bot.save_cfg()
            await log_reply(ctx, f"Removed '{value}' from relays", ephemeral=False)
        else:
            await log_reply(ctx, f"Couldn't find '{value}' in {mode}s")

class PublicCog(Cog):
    """Commands that can be used by anybody"""

    def __init__(self, bot: Bot):
        self.bot = bot

    async def get_relay_channel(self, ctx: Interaction) -> int:
        if not ctx.guild:
            err = "**Error:** This command is only usable in servers"
            raise await CommandError(err).send_err(ctx, err)
        if "dgg-relay-mod" not in (role.name for role in ctx.user.roles):
            err = "**Error:** This command requires the 'dgg-relay-mod' role"
            raise await CommandError(err).send_err(ctx, err)
        relay_channel = None
        for channel in ctx.guild.channels:
            if channel.name == "dgg-relay":
                relay_channel = channel.id
                break
        if not relay_channel:
            err = f"**Error:** No '#dgg-relay' channel found in '{ctx.guild.name}'"
            raise await CommandError(err).send_err(ctx, err)
        return relay_channel

    relay = app_commands.Group(
        name="relay",
        description="Relays DGG messages to servers",
    )

    @relay.command(name="add")
    @app_commands.describe(dgg_username="The DGG user you want to relay messages from")
    async def relay_add(self, ctx: Interaction, dgg_username: str):
        """Add a DGG user whose messages get forwarded to this server (case sensitive!)"""
        relay_channel = await self.get_relay_channel(ctx)
        if dgg_username not in self.bot.relays:
            self.bot.relays[dgg_username] = []
            logger.info(f"Added new relay list '{dgg_username}'")
        if relay_channel not in self.bot.relays[dgg_username]:
            self.bot.relays[dgg_username].append(relay_channel)
            response = (
                f"Messages from '{dgg_username}' will be relayed to '{ctx.guild.name}'"
            )
        else:
            response = f"**Error:** '{dgg_username}' is already being relayed to '{ctx.guild.name}'"
        self.bot.save_cfg()
        await log_reply(ctx, response, ephemeral=False)

    @relay.command(name="remove")
    @app_commands.describe(dgg_username="The DGG user you want to stop relaying")
    async def relay_remove(self, ctx: Interaction, dgg_username: str):
        """Remove a DGG user's relay from this server"""
        relay_channel = await self.get_relay_channel(ctx)
        response = None
        if dgg_username in self.bot.relays.keys():
            if relay_channel in self.bot.relays[dgg_username]:
                self.bot.relays[dgg_username].remove(relay_channel)
                response = f"Removed '{dgg_username}' relay from '{ctx.guild.name}'"
                if not self.bot.relays[dgg_username]:
                    self.bot.relays.pop(dgg_username)
                    logger.info(f"Removed empty relay list for '{dgg_username}'")
                self.bot.save_cfg()
        if not response:
            response = (
                f"**Error:** '{dgg_username}' isn't being relayed to '{ctx.guild.name}'"
                " (try the '/relay list' command)"
            )

        await log_reply(ctx, response, ephemeral=False)

    @relay.command(name="list")
    async def relay_list(self, ctx: Interaction):
        """Lists DGG users currently being relayed to this server."""
        relay_channel = await self.get_relay_channel(ctx)
        relays = []
        for nickname in self.bot.relays:
            for channel in self.bot.relays[nickname]:
                if channel == relay_channel:
                    relays.append(nickname)
        relays = "', '".join(relays)
        response = f"This server gets messages from: '{relays}'"
        if not relays:
            response = "No relays are active for this server."
        await log_reply(ctx, response, ephemeral=False)

    live_notifications = app_commands.Group(
        name="live-notifications",
        description="Configure live notifications for Destiny",
    )

    @live_notifications.command(name="on")
    async def live_notifications_on(self, ctx: Interaction):
        """Enable live notifications for this server"""
        relay_channel = await self.get_relay_channel(ctx)
        if relay_channel not in self.bot.live["channels"].keys():
            self.bot.live["channels"][relay_channel] = {"role": None}
        self.bot.live["channels"][relay_channel]["enabled"] = True
        self.bot.save_cfg()
        response = f"Live notifications enabled for {ctx.guild.name}"
        await log_reply(ctx, response, ephemeral=False)

    @live_notifications.command(name="off")
    async def live_notifications_off(self, ctx: Interaction):
        """Disable live notifications for this server"""
        relay_channel = await self.get_relay_channel(ctx)
        if relay_channel not in self.bot.live["channels"].keys():
            self.bot.live["channels"][relay_channel] = {"role": None}
        self.bot.live["channels"][relay_channel]["enabled"] = False
        self.bot.save_cfg()
        response = f"Live notifications disabled for {ctx.guild.name}"
        await log_reply(ctx, response, ephemeral=False)

    @live_notifications.command(name="role")
    @app_commands.describe(role="The role that will be pinged")
    async def live_notifications_role(self, ctx: Interaction, role: Role):
        """Set a role that gets pinged for live notifications"""
        relay_channel = await self.get_relay_channel(ctx)
        if relay_channel not in self.bot.live["channels"].keys():
            self.bot.live["channels"][relay_channel] = {"enabled": True}
        self.bot.live["channels"][relay_channel]["role"] = role.id
        self.bot.save_cfg()
        response = (
            f'"<@&{role.id}>" will be pinged for live notifications in {ctx.guild.name}'
        )
        await log_reply(ctx, response, ephemeral=False)

    def check_prefs(self, disc_user):
        if disc_user not in self.bot.user_prefs.keys():
            self.bot.user_prefs[disc_user] = {"detect_presence": False, "ignores": []}
            logger.info(f"Added new user '{disc_user}' to preferences list")

    phrase = app_commands.Group(
        name="phrase",
        description="Relays DGG messages to users",
    )

    @phrase.command(name="add")
    @app_commands.describe(
        phrase="The phrase you want forwarded to you (most likely your DGG username)"
    )
    async def phrase_add(self, ctx: Interaction, phrase: str):
        """Add a phrase (usually a username) that will be forwarded
        to you when it's used in DGG (case insensitive)"""
        self.check_prefs(ctx.user.id)
        if phrase not in self.bot.phrases:
            self.bot.phrases[phrase] = []
            logger.info(f"Added new phrase list for '{phrase}'")
        if ctx.user.id not in self.bot.phrases[phrase]:
            self.bot.phrases[phrase].append(ctx.user.id)
            response = f"Forwarding '{phrase}' to {ctx.user}"
        else:
            response = f"**Error:** '{phrase}' is already being forwarded to {ctx.user}"
        self.bot.save_cfg()
        await log_reply(ctx, response)

    @phrase.command(name="remove")
    @app_commands.describe(phrase="The phrase you want to stop being forwarded")
    async def phrase_remove(self, ctx: Interaction, phrase: str):
        """Stop a phrase from being forwarded to you"""
        self.check_prefs(ctx.user.id)
        response = None
        if phrase in self.bot.phrases:
            if ctx.user.id in self.bot.phrases[phrase]:
                self.bot.phrases[phrase].remove(ctx.user.id)
                response = f"No longer forwarding '{phrase}' to {ctx.user}"
                if not self.bot.phrases[phrase]:
                    self.bot.phrases.pop(phrase)
                    logger.info(f"Removed empty phrase list '{phrase}'")
                self.bot.save_cfg()
        if not response:
            response = (
                f"**Error:** '{phrase}' isn't being forwarded to {ctx.user}"
                " (try the '/phrase list' command)"
            )
        await log_reply(ctx, response)

    @phrase.command(name="list")
    async def phrase_list(self, ctx: Interaction):
        """List the phrases currently being forwarded to you"""
        disc_user = ctx.user.id
        user_phrases = []
        for phrase in self.bot.phrases:
            for user_id in self.bot.phrases[phrase]:
                if user_id == disc_user:
                    user_phrases.append(phrase)
        user_phrases = "', '".join(user_phrases)
        response = f"Your phrases: '{user_phrases}'"
        if not user_phrases:
            response = "No phrases are being forwarded to you."
        await log_reply(ctx, response)

    @phrase.command(name="detect-dgg-presence")
    @app_commands.describe(mode="Set to True to detect DGG presence. Default is False.")
    async def detect_dgg_presence(self, ctx: Interaction, mode: bool):
        """Change behavior of the /phrase command by controlling when the bot messages you."""
        self.check_prefs(ctx.user.id)
        self.bot.user_prefs[ctx.user.id]["detect_presence"] = mode
        self.bot.save_cfg()
        word = "enabled" if mode else "disabled"
        response = f"Presence detection {word} for {ctx.user.name}"
        await log_reply(ctx, response)

    ignore = app_commands.Group(
        name="ignore",
        description="Configure your DGG Relay ignore list",
    )

    @ignore.command(name="add")
    @app_commands.describe(dgg_username="The user in DGG you want to ignore")
    async def add_ignore(self, ctx: Interaction, dgg_username: str):
        """Ignore messages from a DGG user"""
        self.check_prefs(ctx.user.id)
        ignores = self.bot.user_prefs[ctx.user.id]["ignores"]
        ignores.append(dgg_username)
        self.bot.user_prefs[ctx.user.id]["ignores"] = list(set(ignores))
        self.bot.save_cfg()
        response = f"'{dgg_username}' added to your ignore list"
        await log_reply(ctx, response)

    @ignore.command(name="remove")
    @app_commands.describe(dgg_username="The user in DGG you want to unignore")
    async def add_ignore(self, ctx: Interaction, dgg_username: str):
        """Remove someone from your ignore list"""
        self.check_prefs(ctx.user.id)
        ignores = self.bot.user_prefs[ctx.user.id]["ignores"]
        if dgg_username not in ignores:
            await log_reply(ctx, f"'{dgg_username}' is not in your ignore list")
            return
        self.bot.user_prefs[ctx.user.id]["ignores"].remove(dgg_username)
        self.bot.save_cfg()
        response = f"'{dgg_username}' removed from your ignore list"
        await log_reply(ctx, response)


import logging
import sys

from loguru import logger
from starlette.config import Config
from starlette.datastructures import Secret

from app.core.logger import InterceptHandler

config = Config(".env")

API_PREFIX = "/api"
VERSION = "0.1.0"
DEBUG: bool = config("DEBUG", cast=bool, default=False)
MAX_CONNECTIONS_COUNT: int = config("MAX_CONNECTIONS_COUNT", cast=int, default=10)
MIN_CONNECTIONS_COUNT: int = config("MIN_CONNECTIONS_COUNT", cast=int, default=10)
HOST: str = config("HOST", cast=str, default="0.0.0.0")
PORT: int = config("PORT", cast=int, default=35100)
SECRET_KEY: Secret = config("SECRET_KEY", cast=Secret, default="")

PROJECT_NAME: str = config("PROJECT_NAME", default="augmentation")

# logging configuration
LOGGING_LEVEL = logging.DEBUG if DEBUG else logging.INFO
logging.basicConfig(
    handlers=[InterceptHandler(level=LOGGING_LEVEL)], level=LOGGING_LEVEL
)
logger.configure(handlers=[{"sink": sys.stderr, "level": LOGGING_LEVEL}])

FASTTEXT_PATH = config("FASTTEXT_PATH", default="./model/cc.vi.300.vec")
PHOBERT_PATH = config("PHOBERT_PATH", default="./model/PhoBERT_base_fairseq")
STOPWORD_PATH = config("STOPWORD_PATH", default="./data/vietnamese-stopwords.txt")
IRRELEVANT_WORD_PATH = config("IRRELEVANT_WORD_PATH", default="./data/irrelevant_words.txt")
EDIT_DISTANCE_PATH = config("EDIT_DISTANCE_PATH", default="./data/edit_distance.txt")
MAX_CACHE_SIZE = config("MAX_CACHE_SIZE", cast=int, default=1000)
PHO_NLP_URL = config("PHO_NLP_URL", default="http://172.29.13.23:20217/")
VN_CORE_PATH = config("VN_CORE_PATH", default="http://172.29.13.23")
VN_CORE_PORT = config("VN_CORE_PORT", cast=int, default=20215)


from flask import Flask, redirect, render_template, request, url_for, session, flash
from datetime import timedelta
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.secret_key = "hello"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.sqlite3' # Things you have to set up before creating a database
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.permanent_session_lifetime = timedelta(minutes=5) # Deciding the session time

db = SQLAlchemy(app) # creating a database

class users(db.Model):
    _id = db.Column("id", db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    email = db.Column(db.String(100))

    def __init__(self, name, email):
        self.name = name
        self.email = email

@app.route('/')
def home():
    return render_template("Home.html")

@app.route("/login", methods=["POST",'GET'])
def login():
    if request.method == "POST":
        session.permanent = True
        user = request.form['nm']

        session['user'] = user

        # 先以名字進行查詢
        found_user = users.query.filter_by(name=user).first()

        #如果有的話就把user的email加進去session list裡面, 如果沒有的話就加入一筆新資料到資料庫
        if found_user:
            flash(f"Welcome back {user}!")
            session['email'] = found_user.email
        else:
            flash(f"Hello {user}!, Nice to meet you!!")
            usr = users(user ,"")
            db.session.add(usr)
            db.session.commit()

        return redirect(url_for('user_page'))
    else:
        if "user" in session:
            flash("Already Logged in!")
            return redirect(url_for('user_page'))
        return render_template("login.html")

@app.route('/logout')
def logout():
    if 'user' in session:
        user = session['user']
        flash(f"You have been logged out, {user}!", "info")
    session.pop('user', None)
    session.pop('email', None)
    return redirect(url_for('login') )

@app.route('/user', methods=["POST",'GET'])
def user_page():
    email = None
    if 'user' in session:
        user = session['user']

        if request.method == "POST":
            email = request.form['email'] # 使用者輸入的email
            session['email'] = email #也建立一個session
            found_user = users.query.filter_by(name=user).first() # 找到user之後要做的事情
            found_user.email = email # 更新使用者新輸入的email
            db.session.commit() # 每次更新完就要儲存 commit 一次

            flash("Email was saved!!")

        else:
            if "email" in session:
                email = session['email']
            return render_template("user_page.html",content=user, email=email)
    else:
        flash("You are not logged in! ")
        return redirect(url_for('login'))

@app.route("/view")
def view():
    return render_template("view.html", values=users.query.all())

if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        app.run(debug=True)


problems = input()
count_trust = 0
implemented_problems = 0

for i in range(0,int(problems)):
    trust_line = input()
    trust_line = trust_line.split(' ')
    for j in trust_line:
        if j=='1':
            count_trust+=1

    if count_trust >1:
        implemented_problems +=1
    count_trust = 0

print(implemented_problems)


# -*- coding: utf-8 -*-
import numpy as np
import torch
import torch.nn as nn

from lichee import plugin
from lichee import config

@plugin.register_plugin(plugin.PluginType.MODULE_LOSS, 'mse_loss')
class MSELoss:

    @classmethod
    def build(cls, cfg):
        return nn.MSELoss()

@plugin.register_plugin(plugin.PluginType.MODULE_LOSS, 'cross_entropy')
class CrossEntropyLoss:

    @classmethod
    def build(cls, cfg):
        return nn.CrossEntropyLoss()

@plugin.register_plugin(plugin.PluginType.MODULE_LOSS, 'neg_log_likelihood')
class NLLLoss:

    @classmethod
    def build(cls, cfg):
        return nn.NLLLoss()

@plugin.register_plugin(plugin.PluginType.MODULE_LOSS, 'binary_cross_entropy')
class BinaryCrossEntropyLoss:

    @classmethod
    def build(cls, cfg):
        return nn.BCEWithLogitsLoss()

@plugin.register_plugin(plugin.PluginType.MODULE_LOSS, 'binary_focal_loss')
class BinaryFocalLoss(nn.Module):
    """
    This is a implementation of Focal Loss with smooth label cross entropy supported which is proposed in
    'Focal Loss for Dense Object Detection. (https://arxiv.org/abs/1708.02002)'
        Focal_Loss= -1*alpha*(1-pt)*log(pt)
    :param num_class:
    :param alpha: (tensor) 3D or 4D the scalar factor for this criterion
    :param gamma: (float,double) gamma > 0 reduces the relative loss for well-classified examples (p>0.5) putting more
                    focus on hard misclassified example
    :param reduction: `none`|`mean`|`sum`
    :param **kwargs
        balance_index: (int) balance class index, should be specific when alpha is float
    """

    def __init__(self, alpha=[1.0, 1.0], gamma=2, ignore_index=None, reduction='mean'):
        super(BinaryFocalLoss, self).__init__()
        if alpha is None:
            alpha = [0.25, 0.75]
        self.alpha = alpha
        self.gamma = gamma
        self.smooth = 1e-6
        self.ignore_index = ignore_index
        self.reduction = reduction

        assert self.reduction in ['none', 'mean', 'sum']

        if self.alpha is None:
            self.alpha = torch.ones(2)
        elif isinstance(self.alpha, (list, np.ndarray)):
            self.alpha = np.asarray(self.alpha)
            self.alpha = np.reshape(self.alpha, (2))
            assert self.alpha.shape[0] == 2, \
                'the `alpha` shape is not match the number of class'
        elif isinstance(self.alpha, (float, int)):
            self.alpha = np.asarray([self.alpha, 1.0 - self.alpha], dtype=np.float).view(2)

        else:
            raise TypeError('{} not supported'.format(type(self.alpha)))

        self.one_hot_eye = None

    @classmethod
    def set_config_default(cls, cfg):
        d_c = {'loss_alpha': [1.0, 1.0],
               'loss_gamma': 2,
               'loss_ignore_index': None,
               'loss_reduction': 'mean'}
        for key, value in d_c.items():
            if key not in cfg.PARAM:
                cfg.PARAM[key] = value

    @classmethod
    def build(cls, cfg):
        cls.set_config_default(cfg)
        return cls(alpha=cfg.PARAM["loss_alpha"],
                   gamma=cfg.PARAM["loss_gamma"],
                   ignore_index=cfg.PARAM["loss_ignore_index"],
                   reduction=cfg.PARAM["loss_reduction"])

    def forward(self, output, target):
        prob = torch.sigmoid(output)
        prob = torch.clamp(prob, self.smooth, 1.0 - self.smooth)

        if self.one_hot_eye == None:
            self.one_hot_eye = torch.eye(2).cuda(target.device.index)
        target = self.one_hot_eye[target]

        pos_mask = (target == 1).float()
        neg_mask = (target == 0).float()

        pos_loss = -self.alpha[0] * torch.pow(torch.sub(1.0, prob), self.gamma) * torch.log(prob) * pos_mask
        neg_loss = -self.alpha[1] * torch.pow(prob, self.gamma) * \
                   torch.log(torch.sub(1.0, prob)) * neg_mask

        neg_loss = neg_loss.sum()
        pos_loss = pos_loss.sum()
        num_pos = pos_mask.view(pos_mask.size(0), -1).sum()
        num_neg = neg_mask.view(neg_mask.size(0), -1).sum()

        if num_pos == 0:
            loss = neg_loss
        else:
            loss = pos_loss / num_pos + neg_loss / num_neg
        return loss

@plugin.register_plugin(plugin.PluginType.MODULE_LOSS, 'focal_loss')
class FocalLoss(nn.Module):
    """
    This is a implementation of Focal Loss with smooth label cross entropy supported which is proposed in
    'Focal Loss for Dense Object Detection. (https://arxiv.org/abs/1708.02002)'
        Focal_Loss= -1*alpha*(1-pt)*log(pt)
    :param num_class:
    :param alpha: (tensor) 3D or 4D the scalar factor for this criterion
    :param gamma: (float,double) gamma > 0 reduces the relative loss for well-classified examples (p>0.5) putting more
                    focus on hard misclassified example
    :param smooth: (float,double) smooth value when cross entropy
    :param size_average: (bool, optional) By default, the losses are averaged over each loss element in the batch.
    """

    def __init__(self, num_class, alpha=[0.25, 0.75], gamma=2, balance_index=-1, size_average=True):
        super(FocalLoss, self).__init__()
        self.num_class = num_class
        self.alpha = alpha
        self.gamma = gamma
        self.size_average = size_average
        self.eps = 1e-6

        if isinstance(self.alpha, (list, tuple)):
            assert len(self.alpha) == self.num_class
            self.alpha = torch.Tensor(list(self.alpha))
        elif isinstance(self.alpha, (float, int)):
            assert 0 < self.alpha < 1.0, 'alpha should be in `(0,1)`)'
            assert balance_index > -1
            alpha = torch.ones((self.num_class))
            alpha *= 1 - self.alpha
            alpha[balance_index] = self.alpha
            self.alpha = alpha
        elif isinstance(self.alpha, torch.Tensor):
            self.alpha = self.alpha
        else:
            raise TypeError('Not support alpha type, expect `int|float|list|tuple|torch.Tensor`')

    @classmethod
    def set_config_default(cls, cfg):
        d_c = {'loss_alpha': [0.25, 0.75],
               'loss_gamma': 2,
               'loss_balance_index': -1,
               'loss_size_average': True}
        for key, value in d_c.items():
            if key not in cfg.PARAM:
                cfg.PARAM[key] = value

    @classmethod
    def build(cls, cfg):
        cls.set_config_default(cfg)
        return cls(num_class=config.get_cfg().DATASET.CONFIG.NUM_CLASS,
                   alpha=cfg.PARAM["loss_alpha"],
                   gamma=cfg.PARAM["loss_gamma"],
                   balance_index=cfg.PARAM["loss_balance_index"],
                   size_average=cfg.PARAM["loss_size_average"])

    def forward(self, logit, target):

        if logit.dim() > 2:
            # N,C,d1,d2 -> N,C,m (m=d1*d2*...)
            logit = logit.view(logit.size(0), logit.size(1), -1)
            logit = logit.transpose(1, 2).contiguous()  # [N,C,d1*d2..] -> [N,d1*d2..,C]
            logit = logit.view(-1, logit.size(-1))  # [N,d1*d2..,C]-> [N*d1*d2..,C]
        target = target.view(-1, 1)  # [N,d1,d2,...]->[N*d1*d2*...,1]

        # -----------legacy way------------
        #  idx = target.cpu().long()
        # one_hot_key = torch.FloatTensor(target.size(0), self.num_class).zero_()
        # one_hot_key = one_hot_key.scatter_(1, idx, 1)
        # if one_hot_key.device != logit.device:
        #     one_hot_key = one_hot_key.to(logit.device)
        # pt = (one_hot_key * logit).sum(1) + epsilon

        # ----------memory saving way--------
        pt = logit.gather(1, target).view(-1) + self.eps  # avoid apply
        logpt = pt.log()

        if self.alpha.device != logpt.device:
            alpha = self.alpha.to(logpt.device)
            alpha_class = alpha.gather(0, target.view(-1))
            logpt = alpha_class * logpt
        loss = -1 * torch.pow(torch.sub(1.0, pt), self.gamma) * logpt

        if self.size_average:
            loss = loss.mean()
        else:
            loss = loss.sum()
        return loss


import math as ma
import multiprocessing as mp
import time

def first_test(n):
    """ test naïf de primalité
    retourne True si l'entier est premier, et inversement
    n : un entier naturel
    """
    for a in range(2, int(ma.sqrt(n) + 1)):
        if n % a == 0:
            return False
    return True

def pi(x):
    """retourne le nombre de premiers inférieurs à x
    X : un réel
    """
    cpt = 0
    for n in range(1, int(x)):
        if first_test(n):
            cpt += 1
    return cpt

def gen_carmichael(t):
    """retourne tous les nombres de Carmichael inférieurs à x
    t : un réel
    """
    res = []
    for x in range(3, int(t), 2):  # les nombres de Carmichael sont impairs
        valid = False
        for y in range(2, x):
            if ma.gcd(x, y) == 1:
                if pow(y, x-1, x) != 1:
                    valid = False
                    break
            else:
                valid = True
        if valid:
            res.append(x)

    return res

def worker_proc(x):
    valid = False
    for y in range(2, x):
        if ma.gcd(x, y) == 1:
            if pow(y, x - 1, x) != 1:
                return
        else:
            valid = True
    if valid:
        print(x)

def gen_carmichael_mp(t):
    """retourne tous les nombres de Carmichael inférieurs à t
    version multiprocess
    t : un réel
    """
    pool = mp.Pool(processes=mp.cpu_count())
    pool.map(worker_proc, range(3, int(t), 2))

def gen_carmichael_3(k):
    """ genère les nombres de Carmicheal de longueur binaire k à partir de trois diviseurs premiers
    k : un entier
    """
    # t = int(t)
    prime = []
    for n in range(3, 2 ** k, 2):
        if first_test(n):
            prime.append(n)
    res = []
    for i_a, a in enumerate(prime):
        for i_b, b in enumerate(prime[:i_a]):
            ab = a * b
            for c in prime[:i_b]:
                # on  a obtenu 3 premiers, on teste si leur produit est Carmichael
                # worker_proc(a * b * c)
                tst = ab * c - 1
                if tst.bit_length() != k:
                    continue
                if tst % 2 == 0 and tst % (a - 1) == 0 and tst % (b - 1) == 0 and tst % (c - 1) == 0 and a % (b * c) != 0:
                    res.append(tst + 1)
    return sorted(res)

def gen_carmichael_3_all(t):
    """ genère un nombre de Carmicheal inférieur t à partir de trois diviseurs premiers
    version sans contrainte de taille
    """
    t = int(t)
    prime = []
    for n in range(3, t, 2):
        if first_test(n):
            prime.append(n)
    res = []
    for i_a, a in enumerate(prime):
        for i_b, b in enumerate(prime[:i_a]):
            ab = a * b
            for c in prime[:i_b]:
                tst = ab * c - 1
                if tst % 2 == 0 and tst % (a - 1) == 0 and tst % (b - 1) == 0 and tst % (c - 1) == 0 and a % (b * c) != 0:
                    res.append(tst + 1)
    return sorted(res)

def gen_carmichael_2(p):
    """retourne tous les nombre de carmichael de la forme pqr pour un p donné"""
    prime = []
    for n in range(3, 2 * p * (p ** 2 + 1), 2):
        if n == p:
            continue
        if first_test(n):
            prime.append(n)
    res = []
    for i_r, r in enumerate(prime):
        for q in prime[:i_r]:
            tst = p * q * r - 1
            if tst % 2 == 0 and tst % (p - 1) == 0 and tst % (q - 1) == 0 and tst % (r - 1) == 0 and r % (p * q) != 0:
                res.append(tst + 1)
    return sorted(res)

if __name__ == '__main__':
    t = time.time()
    gen_carmichael_mp(10000)
    print("mt : ", str(time.time() - t))
    t = time.time()
    print(gen_carmichael(64000))
    print("naif : ", str(time.time() - t))
    t = time.time()
    print(gen_carmichael_3_all(100))
    print("3 : ", str(time.time() - t))


import firstscript as sense
import random
import time

def get_random_time():
    random_time_frame = random.randrange(7,25)
    return random_time_frame

def get_random():
    numbers = [1,2,3,4,5,6,7,8,9]
    y = get_random_time()
    for i in range(y):
        sense.display_letter(str(random.choice(numbers)))
        time.sleep(.5)
        sense.clear_hat()
    sense.display_letter(str(random.choice(numbers)),[255,0,0])

if __name__ == '__main__':
    get_random()


#!/usr/bin/python

"""
    This is the code to accompany the Lesson 1 (Naive Bayes) mini-project.

    Use a Naive Bayes Classifier to identify emails by their authors

    authors and labels:
    Sara has label 0
    Chris has label 1
"""

import sys

import time
sys.path.append("../tools/")
from email_preprocess import preprocess

#imports
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score

### features_train and features_test are the features for the training
### and testing datasets, respectively
### labels_train and labels_test are the corresponding item labels

#########################################################
    ### your code goes here ###
sample_size_list = [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]
##Loop to change sample Size
for j in sample_size_list:
    features_train, features_test, labels_train, labels_test = preprocess("../tools/word_data_unix.pkl","../tools/email_authors.pkl",j)
    loop = [0,1,2,3,4,5,6,7,8,9]
    print("Test sample Size:",features_train.size)
    ##Loop to change the var_smoothing
    for i in loop:
        num=1/(10)**i
        gnb = GaussianNB(var_smoothing=num)
        time0=time.time()
        pred = gnb.fit(features_train, labels_train).predict(features_test)
        time1=time.time()
        acc=accuracy_score(labels_test,pred)
        print("Test sample_Size: ",j," Accuracy for ",num,": ", acc,"Ellapsed time: ",time1-time0)
        i=i+1
    j=1+1
#########################################################


from typing import List, Tuple
import networkx as nx
import numpy as np
from matplotlib import pyplot as plt
import time
import copy

from node import Node

def get_graph(node: Node) -> Tuple[nx.Graph, List, List]:
    board_size = node.state.shape[0]
    G = nx.grid_2d_graph(board_size, board_size)
    diagonals = []
    for x,y in G:
        x2 = x-1
        y2 = y+1
        if y2 >= board_size or x2 < 0:
            continue
        edge = ((x, y), (x2,y2))
        diagonals.append(edge)
    G.add_edges_from(diagonals)
    pos = {}
    colour_map = []
    theta = -(1/4) * np.pi
    costheta = np.cos(theta)
    sintheta = np.sin(theta)
    rotation_matrix = np.array([
        [costheta, -sintheta],
        [sintheta, costheta]
    ])
    for x,y in G:
        coords = (x,y)
        pos[coords] = np.dot(rotation_matrix, (y,-x))
        if node.state[coords] == 1:
            colour_map.append("red")
        elif node.state[coords] == -1:
            colour_map.append("blue")
        else:
            colour_map.append("grey")

    return G, pos, colour_map

def visualize_hex_node_state(node: Node, done: bool=False) -> None:
    G, pos, colour_map = get_graph(node)
    nx.draw(G, pos=pos,
            node_color=colour_map,
            with_labels=True,
            node_size=600)
    plt.draw()
    plt.pause(0.001)
    if done:
        plt.close()

if __name__ == "__main__":
    plt.figure(figsize=(5,5))
    plt.ion()
    plt.show()
    test_state = np.zeros(shape=(7,7))
    test_state[0, 1] = 1
    test_node = Node(state=test_state)
    visualize_hex_node_state(test_node)
    new_node = copy.copy(test_node)
    new_node.state[0,2] = -1
    visualize_hex_node_state(new_node)


from __future__ import division

from PyQt4 import QtCore, QtGui
from vistrails.core.inspector import PipelineInspector
from vistrails.gui.common_widgets import QToolWindowInterface
from vistrails.gui.pipeline_view import QPipelineView
from vistrails.gui.theme import CurrentTheme

################################################################################
class QAnnotatedPipelineView(QPipelineView, QToolWindowInterface):
    """
    QAnnotatedPipelineView subclass QPipelineView to perform some overlay
    marking on a pipeline view

    """
    def __init__(self, parent=None):
        """ QPipelineView(parent: QWidget) -> QPipelineView
        Initialize the graphics view and its properties

        """
        QPipelineView.__init__(self, parent)
        self.setWindowTitle('Annotated Pipeline')
        self.inspector = PipelineInspector()

    def sizeHint(self):
        """ sizeHint() -> QSize
        Prefer the view not so large

        """
        return QtCore.QSize(256, 256)

    def paintEvent(self, event):
        """ paintEvent(event: QPaintEvent) -> None
        Paint an overlay annotation on spreadsheet cell modules

        """
        QPipelineView.paintEvent(self, event)
        # super(QAnnotatedPipelineView, self).paintEvent(event)
        if self.scene():
            painter = QtGui.QPainter(self.viewport())
            for mId, annotatedId in \
                    self.inspector.annotated_modules.iteritems():
                if mId not in self.scene().modules:
                    # faulty annotated_modules entry
                    continue
                item = self.scene().modules[mId]
                br = item.sceneBoundingRect()
                rect = QtCore.QRect(self.mapFromScene(br.topLeft()),
                                    self.mapFromScene(br.bottomRight()))
                QAnnotatedPipelineView.drawId(painter, rect, annotatedId)
            painter.end()

    def updateAnnotatedIds(self, pipeline):
        """ updateAnnotatedIds(pipeline: Pipeline) -> None
        Re-inspect the pipeline to get annotated ids

        """
        if pipeline and self.scene():
            self.inspector.inspect_ambiguous_modules(pipeline)
            self.scene().fitToAllViews(True)

    @staticmethod
    def drawId(painter, rect, id, align=QtCore.Qt.AlignCenter):
        """ drawId(painter: QPainter, rect: QRect, id: int,
                   align: QtCore.Qt.Align) -> None
        Draw the rounded id number on a rectangular area

        """
        painter.save()
        painter.setRenderHints(QtGui.QPainter.Antialiasing)
        painter.setPen(CurrentTheme.ANNOTATED_ID_BRUSH.color())
        painter.setBrush(CurrentTheme.ANNOTATED_ID_BRUSH)
        font = QtGui.QFont()
        font.setStyleStrategy(QtGui.QFont.ForceOutline)
        font.setBold(True)
        painter.setFont(font)
        fm = QtGui.QFontMetrics(font)
        size = fm.size(QtCore.Qt.TextSingleLine, str(id))
        size = max(size.width(), size.height())

        x = rect.left()
        if align & QtCore.Qt.AlignHCenter:
            x = rect.left() + rect.width()//2-size//2
        if align & QtCore.Qt.AlignRight:
            x = rect.left() + rect.width()-size
        y = rect.top()
        if align & QtCore.Qt.AlignVCenter:
            y = rect.top() + rect.height()//2-size//2
        if align & QtCore.Qt.AlignBottom:
            y = rect.top() + rect.height()-size

        newRect = QtCore.QRect(x, y, size, size)
        painter.drawEllipse(newRect)
        painter.setPen(CurrentTheme.ANNOTATED_ID_PEN)
        painter.drawText(newRect, QtCore.Qt.AlignCenter, str(id))
        painter.restore()


#Import Necessary Packages
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import seaborn as sns
import ruptures as rpt
from statistics import stdev
import pandas as pd

def load_rms(path, sect, ref):
    raw_string = open('../../' + path + '/rmsd_' + sect + '_ref_' + ref + '.txt').readlines()
    #Convert data to fload
    raw = np.zeros(len(raw_string))
    for i in range(len(raw_string)):
        raw[i] = float(raw_string[i])*10
    return raw

def plot_compare(RMSD_mean, RMSD_err, Label, sect, n, ref):
    rmsd_n = RMSD_mean[:,n]
    rmsd_err_n = RMSD_err[:,n]

    section = sect[n]
#    bar_color = ['gray', 'gray', 'pink', 'blue', 'pink', 'red', 'red']

    num = np.linspace(1, len(Label)+1, num = len(Label))
    fig = plt.figure(figsize=(18,10))
    ax1 = fig.add_subplot(111)
    ax1.set_title("RMSD for " + section + ' to ' + ref)
    ax1.set_ylabel(r'RMSD($\AA$)')
    ax1.bar(num, rmsd_n)
    plt.xticks(num, Label, fontsize=14)
    plt.errorbar(num, rmsd_n, yerr= rmsd_err_n, fmt='o', color='black')
    fig.savefig('RMSD_compare_' + section + '_' + ref + '.png')
    plt.close(fig)

def plot_kernel_mut(df, sect_name, sect_file, xmin, xmax):
    ax = sns.kdeplot(data = df, fill=True, alpha=0.5, common_grid = True)
    plt.setp(ax.get_legend().get_texts(), fontsize='12') # for legend text
    plt.xlabel(r'RMSD($\AA$)', fontsize = 14)
    plt.xlim(xmin, xmax)
    plt.xticks(fontsize = 13)
    plt.yticks(fontsize = 13)
    plt.ylabel(r'Normalized Density', fontsize = 14)
    plt.title(str(sect_name) + r' RMSD Relative to WT Closed', fontsize = 15)
    plt.savefig('mutate_RMSD_' + str(sect_file) + '.png')
    plt.close()

def plot_kernel_cmpr_lig(apo_df, AD_df, BBR_df, mut, sect, n):
    df = pd.concat([apo_df, AD_df, BBR_df])

    sns.kdeplot(data = df, fill=True, alpha=0.5, common_norm = True, common_grid = True)
    plt.xlabel(r'RMSD($\AA$)', fontsize = 14)
    plt.ylabel(r'Normalized Density', fontsize = 14)
    plt.title(sect + ' RMSD Compared to WT Closed', fontsize = 15)
    plt.savefig('mutate_RMSD_' + sect + '_' + mut + '.png')
    plt.close()

def rmsd_sect(sect, file_path_close, file_path_close_AD, file_path_close_BBR, ref, n):
    rmsd_1sug = load_rms(file_path_close[0], sect, ref[n])
    rmsd_apo = load_rms(file_path_close[1], sect, ref[n])
    rmsd_L192F = load_rms(file_path_close[2], sect, ref[n])
    rmsd_E276F = load_rms(file_path_close[3], sect, ref[n])
    rmsd_F280Y = load_rms(file_path_close[4], sect, ref[n])
    rmsd_L195F = load_rms(file_path_close[5], sect, ref[n])
    rmsd_F196A = load_rms(file_path_close[6], sect, ref[n])
    rmsd_V287T = load_rms(file_path_close[7], sect, ref[n])

    rmsd_L192F_AD = load_rms(file_path_close_AD[0], sect, ref[n])
    rmsd_L192F_BBR = load_rms(file_path_close_BBR[0], sect, ref[n])
    rmsd_E276F_AD = load_rms(file_path_close_AD[1], sect, ref[n])
    rmsd_E276F_BBR = load_rms(file_path_close_BBR[1], sect, ref[n])
    rmsd_F280Y_AD = load_rms(file_path_close_AD[2], sect, ref[n])
    rmsd_F280Y_BBR = load_rms(file_path_close_BBR[2], sect, ref[n])
    rmsd_L195F_AD = load_rms(file_path_close_AD[3], sect, ref[n])
    rmsd_L195F_BBR = load_rms(file_path_close_BBR[3], sect, ref[n])
    rmsd_F196A_AD = load_rms(file_path_close_AD[4], sect, ref[n])
    rmsd_F196A_BBR = load_rms(file_path_close_BBR[4], sect, ref[n])
    rmsd_V287T_AD = load_rms(file_path_close_AD[4], sect, ref[n])
    rmsd_V287T_BBR = load_rms(file_path_close_BBR[4], sect, ref[n])

    return rmsd_1sug, rmsd_apo, rmsd_L192F, rmsd_E276F, rmsd_F280Y, rmsd_L195F, rmsd_F196A, rmsd_V287T, rmsd_L192F_AD, rmsd_E276F_AD, rmsd_F280Y_AD, rmsd_L195F_AD, rmsd_F196A_AD, rmsd_V287T_AD, rmsd_L192F_BBR, rmsd_E276F_BBR, rmsd_F280Y_BBR, rmsd_L195F_BBR, rmsd_F196A_BBR, rmsd_V287T_BBR

#File paths for all input files
file_path = ['../Apo_dis/analysis', 'L192F/Apo/analysis', 'E276F/Apo/analysis', 'F280Y/Apo/analysis', 'L195F/Apo/analysis', 'F196A/Apo/analysis', 'V287T/Apo/analysis'] #Indices to rank in order of closest activity to WT to Furthest

file_path_close = ['../Apo_1SUG/analysis/1sug', '../Apo_dis/analysis', 'L192F/Apo/analysis', 'E276F/Apo/analysis', 'F280Y/Apo/analysis', 'L195F/Apo/analysis', 'F196A/Apo/analysis', 'V287T/Apo/analysis']
file_path_close_AD = ['L192F/AD/analysis', 'E276F/AD/analysis', 'F280Y/AD/analysis', 'L195F/AD/analysis', 'F196A/AD/analysis', 'V287T/AD/analysis']
file_path_close_BBR = ['L192F/BBR/analysis', 'E276F/BBR/analysis', 'F280Y/BBR/analysis', 'L195F/BBR/analysis', 'F196A/BBR/analysis', 'V287T/BBR/analysis']

sections = ['WPD', 'WPD_a3', 'SBL', 'beg', 'P', 'CYS', 'a3', 'a3_top', 'a4', 'a5', 'a6', 'a6_bot', 'a7', 'Q']
ref = ['open', 'closed', 'self', 'F196A', 'V287T']

#open all files
RMSD_mean = np.zeros((len(file_path), len(sections))) #Mean for reference open
RMSD_err = np.zeros((len(file_path), len(sections))) #SEM for reference open
RMSD_mean_close = np.zeros((len(file_path_close), len(sections))) #Mean for reference closed
RMSD_err_close = np.zeros((len(file_path_close), len(sections))) #SEM for reference closed
RMSD_mean_close_AD = np.zeros((len(file_path_close_AD), len(sections))) #Mean for reference closed
RMSD_err_close_AD = np.zeros((len(file_path_close_AD), len(sections))) #SEM for reference closed
RMSD_mean_close_BBR = np.zeros((len(file_path_close_BBR), len(sections))) #Mean for reference closed
RMSD_err_close_BBR = np.zeros((len(file_path_close_BBR), len(sections))) #SEM for reference closed

#Save all rmsd values for a3_top, a4_top, and a6 helix
rmsd_a3_1sug, rmsd_a3_apo, rmsd_a3_L192F, rmsd_a3_E276F, rmsd_a3_F280Y, rmsd_a3_L195F, rmsd_a3_F196A, rmsd_a3_V287T, rmsd_a3_L192F_AD, rmsd_a3_E276F_AD, rmsd_a3_F280Y_AD, rmsd_a3_L195F_AD, rmsd_a3_F196A_AD, rmsd_a3_V287T_AD, rmsd_a3_L192F_BBR, rmsd_a3_E276F_BBR, rmsd_a3_F280Y_BBR, rmsd_a3_L195F_BBR, rmsd_a3_F196A_BBR, rmsd_a3_V287T_BBR = rmsd_sect('a3', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

rmsd_a3_top_1sug, rmsd_a3_top_apo, rmsd_a3_top_L192F, rmsd_a3_top_E276F, rmsd_a3_top_F280Y, rmsd_a3_top_L195F, rmsd_a3_top_F196A, rmsd_a3_top_V287T, rmsd_a3_top_L192F_AD, rmsd_a3_top_E276F_AD, rmsd_a3_top_F280Y_AD, rmsd_a3_top_L195F_AD, rmsd_a3_top_F196A_AD, rmsd_a3_top_V287T_AD, rmsd_a3_top_L192F_BBR, rmsd_a3_top_E276F_BBR, rmsd_a3_top_F280Y_BBR, rmsd_a3_top_L195F_BBR, rmsd_a3_top_F196A_BBR, rmsd_a3_top_V287T_BBR = rmsd_sect('a3_top', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

rmsd_a4_1sug, rmsd_a4_apo, rmsd_a4_L192F, rmsd_a4_E276F, rmsd_a4_F280Y, rmsd_a4_L195F, rmsd_a4_F196A, rmsd_a4_V287T, rmsd_a4_L192F_AD, rmsd_a4_E276F_AD, rmsd_a4_F280Y_AD, rmsd_a4_L195F_AD, rmsd_a4_F196A_AD, rmsd_a4_V287T_AD, rmsd_a4_L192F_BBR, rmsd_a4_E276F_BBR, rmsd_a4_F280Y_BBR, rmsd_a4_L195F_BBR, rmsd_a4_F196A_BBR, rmsd_a4_V287T_BBR = rmsd_sect('a4', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

rmsd_a6_1sug, rmsd_a6_apo, rmsd_a6_L192F, rmsd_a6_E276F, rmsd_a6_F280Y, rmsd_a6_L195F, rmsd_a6_F196A, rmsd_a6_V287T, rmsd_a6_L192F_AD, rmsd_a6_E276F_AD, rmsd_a6_F280Y_AD, rmsd_a6_L195F_AD, rmsd_a6_F196A_AD, rmsd_a6_V287T_AD, rmsd_a6_L192F_BBR, rmsd_a6_E276F_BBR, rmsd_a6_F280Y_BBR, rmsd_a6_L195F_BBR, rmsd_a6_F196A_BBR, rmsd_a6_V287T_BBR = rmsd_sect('a6', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

rmsd_a6_bot_1sug, rmsd_a6_bot_apo, rmsd_a6_bot_L192F, rmsd_a6_bot_E276F, rmsd_a6_bot_F280Y, rmsd_a6_bot_L195F, rmsd_a6_bot_F196A, rmsd_a6_bot_V287T, rmsd_a6_bot_L192F_AD, rmsd_a6_bot_E276F_AD, rmsd_a6_bot_F280Y_AD, rmsd_a6_bot_L195F_AD, rmsd_a6_bot_F196A_AD, rmsd_a6_bot_V287T_AD, rmsd_a6_bot_L192F_BBR, rmsd_a6_bot_E276F_BBR, rmsd_a6_bot_F280Y_BBR, rmsd_a6_bot_L195F_BBR, rmsd_a6_bot_F196A_BBR, rmsd_a6_bot_V287T_BBR = rmsd_sect('a6_bot', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

rmsd_CYS_1sug, rmsd_CYS_apo, rmsd_CYS_L192F, rmsd_CYS_E276F, rmsd_CYS_F280Y, rmsd_CYS_L195F, rmsd_CYS_F196A, rmsd_CYS_V287T, rmsd_CYS_L192F_AD, rmsd_CYS_E276F_AD, rmsd_CYS_F280Y_AD, rmsd_CYS_L195F_AD, rmsd_CYS_F196A_AD, rmsd_CYS_V287T_AD, rmsd_CYS_L192F_BBR, rmsd_CYS_E276F_BBR, rmsd_CYS_F280Y_BBR, rmsd_CYS_L195F_BBR, rmsd_CYS_F196A_BBR, rmsd_CYS_V287T_BBR = rmsd_sect('CYS', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

rmsd_beg_1sug, rmsd_beg_apo, rmsd_beg_L192F, rmsd_beg_E276F, rmsd_beg_F280Y, rmsd_beg_L195F, rmsd_beg_F196A, rmsd_beg_V287T, rmsd_beg_L192F_AD, rmsd_beg_E276F_AD, rmsd_beg_F280Y_AD, rmsd_beg_L195F_AD, rmsd_beg_F196A_AD, rmsd_beg_V287T_AD, rmsd_beg_L192F_BBR, rmsd_beg_E276F_BBR, rmsd_beg_F280Y_BBR, rmsd_beg_L195F_BBR, rmsd_beg_F196A_BBR, rmsd_beg_V287T_BBR = rmsd_sect('beg', file_path_close, file_path_close_AD, file_path_close_BBR, ref, 1)

for i in range(len(file_path_close)):
    for j in range(len(sections)):
        #Load Data for reference open
        rmsd_Apo = load_rms(file_path_close[i], sections[j], ref[1])

        #Mean and SEM for each trajectory
        RMSD_mean_close[i][j] = np.mean(rmsd_Apo)
        RMSD_err_close[i][j] = stats.sem(rmsd_Apo)

for i in range(len(file_path)):
    #Load Data for reference open
    rmsd = load_rms(file_path[i], sections[j], ref[0])
    #Mean and SEM for each trajectory
    RMSD_mean[i][j] = np.mean(rmsd)
    RMSD_err[i][j] = stats.sem(rmsd)

for i in range(len(file_path_close_AD)):
    #Load Data for reference open
    rmsd_AD = load_rms(file_path_close_AD[i], sections[j], ref[1])
    RMSD_mean_close_AD[i][j] = np.mean(rmsd_AD)
    RMSD_err_close_AD[i][j] = stats.sem(rmsd_AD)

    rmsd_BBR = load_rms(file_path_close_BBR[i], sections[j], ref[1])
    RMSD_mean_close_BBR[i][j] = np.mean(rmsd_BBR)
    RMSD_err_close_BBR[i][j] = stats.sem(rmsd_BBR)

#Name Labels
Label = ['WT', 'L192F', 'E276F', 'F280Y', 'L195F', 'F196A', 'V287T']
Label_close = ['WT Close', 'WT Open', 'L192F', 'E276F', 'F280Y', 'L195F', 'F196A', 'V287T']
Labels_mut = ['L192F', 'E276F', 'F280Y', 'L195F', 'F196A', 'V287T']

#Plot all compared to WT Open
for i in range(len(sections)):
    plot_compare(RMSD_mean, RMSD_err, Label, sections, i, ref[0])
    plot_compare(RMSD_mean_close, RMSD_err_close, Label_close, sections, i, ref[1])

#Determine % difference from WT
RMSD_diff = np.zeros((len(sections), len(Labels_mut)))
for i in range(1, len(Label)):
    n = i-1
    for j in range(len(sections)):
        WT = RMSD_mean[0][j]
        Mut = RMSD_mean[i][j]
        RMSD_diff[j][n] = ((Mut-WT)/((Mut+WT)/2)) * 100

#Plot table comparing residue interactions to WT
ax = plt.figure(figsize=(12, 6), frameon=False) # no visible frame
ax = sns.heatmap(RMSD_diff, annot=False, cmap = 'jet', cbar = True, cbar_kws={'label': 'Percentage Difference from WT'}, vmin = 0, vmax = 150, xticklabels = Labels_mut, yticklabels = sections)
#ax.add_artist(lines.Line2D([0, 20], [7, 7], color = 'black', linestyle= '--', linewidth = 4))
plt.title('Section RMSD Compared to WT')
plt.savefig('mutate_RMSD_Apo.png')
plt.close()

RMSD_mean_mut = np.zeros((len(Label_close), len(sections))) #Mean for reference open
RMSD_err_mut = np.zeros((len(Label_close), len(sections))) #SEM for reference open

#Plot self and two references
for i in [0, 2, 3, 4]:
    for j in range(len(sections)):
        #Load Data
        RMSD_mean_mut[0][j] = RMSD_mean_close[0][j]
        RMSD_err_mut[0][j] = RMSD_err_close[0][j]
        for k in range(1, len(Label_close)):
            rmsd = load_rms(file_path_close[k], sections[j], ref[i])
            RMSD_mean_mut[k][j] = np.mean(rmsd)
            RMSD_err_mut[k][j] = stats.sem(rmsd)
        plot_compare(RMSD_mean_mut, RMSD_err_mut, Label_close, sections, j, ref[i])

#Plot Kernel DEnsity Estimate Plot
#Compare a3_top for L192F, E276F, L195F, V287T
a3_top_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_a3_top_apo})
a3_top_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_a3_top_1sug})
a3_top_L192F_df = pd.DataFrame({'L192F': rmsd_a3_top_L192F})
a3_top_L195F_df = pd.DataFrame({'L195F': rmsd_a3_top_L195F})
a3_top_F280Y_df = pd.DataFrame({'F280Y': rmsd_a3_top_F280Y})
a3_top_E276F_df = pd.DataFrame({'E276F': rmsd_a3_top_E276F})
a3_top_F196A_df = pd.DataFrame({'F196A': rmsd_a3_top_F196A})
a3_top_V287T_df = pd.DataFrame({'V287T': rmsd_a3_top_V287T})
a3_top_L192F_AD_df = pd.DataFrame({'L192F AD': rmsd_a3_top_L192F_AD})
a3_top_L195F_AD_df = pd.DataFrame({'L195F AD': rmsd_a3_top_L195F_AD})
a3_top_F280Y_AD_df = pd.DataFrame({'F280Y AD': rmsd_a3_top_F280Y_AD})
a3_top_E276F_AD_df = pd.DataFrame({'E276F AD': rmsd_a3_top_E276F_AD})
a3_top_F196A_AD_df = pd.DataFrame({'F196A AD': rmsd_a3_top_F196A_AD})
a3_top_V287T_AD_df = pd.DataFrame({'V287T AD': rmsd_a3_top_V287T_AD})
a3_top_L192F_BBR_df = pd.DataFrame({'L192F BBR': rmsd_a3_top_L192F_BBR})
a3_top_L195F_BBR_df = pd.DataFrame({'L195F BBR': rmsd_a3_top_L195F_BBR})
a3_top_F280Y_BBR_df = pd.DataFrame({'F280Y BBR': rmsd_a3_top_F280Y_BBR})
a3_top_E276F_BBR_df = pd.DataFrame({'E276F BBR': rmsd_a3_top_E276F_BBR})
a3_top_F196A_BBR_df = pd.DataFrame({'F196A BBR': rmsd_a3_top_F196A_BBR})
a3_top_V287T_BBR_df = pd.DataFrame({'V287T BBR': rmsd_a3_top_V287T_BBR})

df = pd.concat([a3_top_Apo_open_df, a3_top_Apo_close_df, a3_top_L192F_df, a3_top_E276F_df, a3_top_V287T_df, a3_top_F196A_df, a3_top_F280Y_df, a3_top_L195F_df])
plot_kernel_mut(df, r'Top of $\alpha$3', 'a3_top_all', 0, 2)

df = pd.concat([a3_top_L192F_df, a3_top_E276F_df, a3_top_V287T_df, a3_top_F196A_df, a3_top_F280Y_df, a3_top_L195F_df])
plot_kernel_mut(df, r'Top of $\alpha$3', 'a3_top_mut_all', 0, 2)

df = pd.concat([a3_top_Apo_open_df, a3_top_Apo_close_df, a3_top_V287T_df, a3_top_F280Y_df])
plot_kernel_mut(df, r'Top of $\alpha$3', 'a3_top_extr', 0, 2)

plot_kernel_cmpr_lig(a3_top_L192F_df, a3_top_L192F_AD_df, a3_top_L192F_BBR_df, 'L192F', sections[7], 7)
plot_kernel_cmpr_lig(a3_top_L195F_df, a3_top_L195F_AD_df, a3_top_L195F_BBR_df, 'L195F', sections[7], 7)
plot_kernel_cmpr_lig(a3_top_E276F_df, a3_top_E276F_AD_df, a3_top_E276F_BBR_df, 'E276F', sections[7], 7)
plot_kernel_cmpr_lig(a3_top_V287T_df, a3_top_V287T_AD_df, a3_top_V287T_BBR_df, 'V287T', sections[7], 7)

#Compare a3_top for L192F, E276F, L195F, V287T
a3_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_a3_apo})
a3_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_a3_1sug})
a3_L192F_df = pd.DataFrame({'L192F': rmsd_a3_L192F})
a3_L195F_df = pd.DataFrame({'L195F': rmsd_a3_L195F})
a3_F280Y_df = pd.DataFrame({'F280Y': rmsd_a3_F280Y})
a3_E276F_df = pd.DataFrame({'E276F': rmsd_a3_E276F})
a3_F196A_df = pd.DataFrame({'F196A': rmsd_a3_F196A})
a3_V287T_df = pd.DataFrame({'V287T': rmsd_a3_V287T})
a3_L192F_AD_df = pd.DataFrame({'L192F AD': rmsd_a3_L192F_AD})
a3_L195F_AD_df = pd.DataFrame({'L195F AD': rmsd_a3_L195F_AD})
a3_F280Y_AD_df = pd.DataFrame({'F280Y AD': rmsd_a3_F280Y_AD})
a3_E276F_AD_df = pd.DataFrame({'E276F AD': rmsd_a3_E276F_AD})
a3_F196A_AD_df = pd.DataFrame({'F196A AD': rmsd_a3_F196A_AD})
a3_V287T_AD_df = pd.DataFrame({'V287T AD': rmsd_a3_V287T_AD})
a3_L192F_BBR_df = pd.DataFrame({'L192F BBR': rmsd_a3_L192F_BBR})
a3_L195F_BBR_df = pd.DataFrame({'L195F BBR': rmsd_a3_L195F_BBR})
a3_F280Y_BBR_df = pd.DataFrame({'F280Y BBR': rmsd_a3_F280Y_BBR})
a3_E276F_BBR_df = pd.DataFrame({'E276F BBR': rmsd_a3_E276F_BBR})
a3_F196A_BBR_df = pd.DataFrame({'F196A BBR': rmsd_a3_F196A_BBR})
a3_V287T_BBR_df = pd.DataFrame({'V287T BBR': rmsd_a3_V287T_BBR})

df = pd.concat([a3_Apo_open_df, a3_Apo_close_df, a3_L192F_df, a3_E276F_df, a3_V287T_df, a3_F196A_df, a3_F280Y_df, a3_L195F_df])
plot_kernel_mut(df, r'$\alpha$3', 'a3_all', 0, 2)

df = pd.concat([a3_L192F_df, a3_E276F_df, a3_V287T_df, a3_F196A_df, a3_F280Y_df, a3_L195F_df])
plot_kernel_mut(df, r'$\alpha$3', 'a3_mut_all', 0, 2)

df = pd.concat([a3_Apo_open_df, a3_Apo_close_df, a3_V287T_df, a3_F280Y_df])
plot_kernel_mut(df, r'$\alpha$3', 'a3_mut_extr', 0, 2)

plot_kernel_cmpr_lig(a3_L192F_df, a3_L192F_AD_df, a3_L192F_BBR_df, 'L192F', sections[6], 6)
plot_kernel_cmpr_lig(a3_L195F_df, a3_L195F_AD_df, a3_L195F_BBR_df, 'L195F', sections[6], 6)
plot_kernel_cmpr_lig(a3_E276F_df, a3_E276F_AD_df, a3_E276F_BBR_df, 'E276F', sections[6], 6)
plot_kernel_cmpr_lig(a3_V287T_df, a3_V287T_AD_df, a3_V287T_BBR_df, 'V287T', sections[6], 6)

#Compare a4 for L192F, E276F, L195F, V287T
a4_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_a4_apo})
a4_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_a4_1sug})
a4_L192F_df = pd.DataFrame({'L192F': rmsd_a4_L192F})
a4_L195F_df = pd.DataFrame({'L195F': rmsd_a4_L195F})
a4_F280Y_df = pd.DataFrame({'F280Y': rmsd_a4_F280Y})
a4_E276F_df = pd.DataFrame({'E276F': rmsd_a4_E276F})
a4_F196A_df = pd.DataFrame({'F196A': rmsd_a4_F196A})
a4_V287T_df = pd.DataFrame({'V287T': rmsd_a4_V287T})
a4_L192F_AD_df = pd.DataFrame({'L192F AD': rmsd_a4_L192F_AD})
a4_L195F_AD_df = pd.DataFrame({'L195F AD': rmsd_a4_L195F_AD})
a4_F280Y_AD_df = pd.DataFrame({'F280Y AD': rmsd_a4_F280Y_AD})
a4_E276F_AD_df = pd.DataFrame({'E276F AD': rmsd_a4_E276F_AD})
a4_F196A_AD_df = pd.DataFrame({'F196A AD': rmsd_a4_F196A_AD})
a4_V287T_AD_df = pd.DataFrame({'V287T AD': rmsd_a4_V287T_AD})
a4_L192F_BBR_df = pd.DataFrame({'L192F BBR': rmsd_a4_L192F_BBR})
a4_L195F_BBR_df = pd.DataFrame({'L195F BBR': rmsd_a4_L195F_BBR})
a4_F280Y_BBR_df = pd.DataFrame({'F280Y BBR': rmsd_a4_F280Y_BBR})
a4_E276F_BBR_df = pd.DataFrame({'E276F BBR': rmsd_a4_E276F_BBR})
a4_F196A_BBR_df = pd.DataFrame({'F196A BBR': rmsd_a4_F196A_BBR})
a4_V287T_BBR_df = pd.DataFrame({'V287T BBR': rmsd_a4_V287T_BBR})

df = pd.concat([a4_Apo_open_df, a4_Apo_close_df, a4_L192F_df, a4_E276F_df, a4_V287T_df, a4_F196A_df, a4_F280Y_df, a4_L195F_df])
plot_kernel_mut(df, r'$\alpha$4', 'a4_all', 0, 1.5)

df = pd.concat([a4_L192F_df, a4_E276F_df, a4_V287T_df, a4_F196A_df, a4_F280Y_df, a4_L195F_df])
plot_kernel_mut(df, r'$\alpha$4', 'a4_mut_all',0, 1.5)

df = pd.concat([a4_Apo_open_df, a4_Apo_close_df, a4_V287T_df, a4_F196A_df, a4_F280Y_df])
plot_kernel_mut(df, r'$\alpha$4', 'a4', 0, 1.5)

plot_kernel_cmpr_lig(a4_F196A_df, a4_F196A_AD_df, a4_F196A_BBR_df, 'F196A', sections[8], 8)
plot_kernel_cmpr_lig(a4_F280Y_df, a4_F280Y_AD_df, a4_F280Y_BBR_df, 'F280Y', sections[8], 8)

#a4_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_a4_apo_rapo})
#a4_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_a4_1sug_rapo})
#a4_F196A_df = pd.DataFrame({'F196A': rmsd_a4_F196A_rapo})
#a4_F196A_AD_df = pd.DataFrame({'F196A AD': rmsd_a4_F196A_AD_rapo})
#a4_F196A_BBR_df = pd.DataFrame({'F196A BBR': rmsd_a4_F196A_BBR_rapo})

#df = pd.concat([a4_Apo_open_df, a4_Apo_close_df, a4_F196A_df, a4_F196A_AD_df, a4_F196A_BBR_df])

#ax = plt.figure(figsize=(12, 6), frameon=False) # no visible frame
#sns.kdeplot(data = df, fill=True, alpha=0.5, common_norm = True, common_grid = True)
#plt.xlabel(r'RMSD($\AA$)')
#plt.ylabel(r'Normalized Density')
#plt.title(r'$\alpha$-4 RMSD Compared to Apo F196A')
#plt.savefig('mutate_RMSD_a4_ref_F196A.png')
#plt.close()

#a6 comparison
a6_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_a6_apo})
a6_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_a6_1sug})
a6_L192F_df = pd.DataFrame({'L192F': rmsd_a6_L192F})
a6_L195F_df = pd.DataFrame({'L195F': rmsd_a6_L195F})
a6_F280Y_df = pd.DataFrame({'F280Y': rmsd_a6_F280Y})
a6_E276F_df = pd.DataFrame({'E276F': rmsd_a6_E276F})
a6_F196A_df = pd.DataFrame({'F196A': rmsd_a6_F196A})
a6_V287T_df = pd.DataFrame({'V287T': rmsd_a6_V287T})
a6_L192F_AD_df = pd.DataFrame({'L192F AD': rmsd_a6_L192F_AD})
a6_L195F_AD_df = pd.DataFrame({'L195F AD': rmsd_a6_L195F_AD})
a6_F280Y_AD_df = pd.DataFrame({'F280Y AD': rmsd_a6_F280Y_AD})
a6_E276F_AD_df = pd.DataFrame({'E276F AD': rmsd_a6_E276F_AD})
a6_F196A_AD_df = pd.DataFrame({'F196A AD': rmsd_a6_F196A_AD})
a6_V287T_AD_df = pd.DataFrame({'V287T AD': rmsd_a6_V287T_AD})
a6_L192F_BBR_df = pd.DataFrame({'L192F BBR': rmsd_a6_L192F_BBR})
a6_L195F_BBR_df = pd.DataFrame({'L195F BBR': rmsd_a6_L195F_BBR})
a6_F280Y_BBR_df = pd.DataFrame({'F280Y BBR': rmsd_a6_F280Y_BBR})
a6_E276F_BBR_df = pd.DataFrame({'E276F BBR': rmsd_a6_E276F_BBR})
a6_F196A_BBR_df = pd.DataFrame({'F196A BBR': rmsd_a6_F196A_BBR})
a6_V287T_BBR_df = pd.DataFrame({'V287T BBR': rmsd_a6_V287T_BBR})

df = pd.concat([a6_Apo_open_df, a6_Apo_close_df, a6_L192F_df, a6_E276F_df, a6_V287T_df, a6_F196A_df, a6_F280Y_df, a6_L195F_df])
plot_kernel_mut(df, r'$\alpha$6', 'a6_all', 0, 2)

df = pd.concat([a6_L192F_df, a6_E276F_df, a6_V287T_df, a6_F196A_df, a6_F280Y_df, a6_L195F_df])
plot_kernel_mut(df, r'$\alpha$6', 'a6_mut_all', 0, 2)

plot_kernel_cmpr_lig(a6_L192F_df, a6_L192F_AD_df, a6_L192F_BBR_df, 'L192F', sections[11], 11)
plot_kernel_cmpr_lig(a6_L195F_df, a6_L195F_AD_df, a6_L195F_BBR_df, 'L195F', sections[11], 11)
plot_kernel_cmpr_lig(a6_E276F_df, a6_E276F_AD_df, a6_E276F_BBR_df, 'E276F', sections[11], 11)
plot_kernel_cmpr_lig(a6_V287T_df, a6_V287T_AD_df, a6_V287T_BBR_df, 'V287T', sections[11], 11)

#Just CYS215
cys_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_CYS_apo})
cys_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_CYS_1sug})
cys_L192F_df = pd.DataFrame({'L192F': rmsd_CYS_L192F})
cys_L195F_df = pd.DataFrame({'L195F': rmsd_CYS_L195F})
cys_F280Y_df = pd.DataFrame({'F280Y': rmsd_CYS_F280Y})
cys_E276F_df = pd.DataFrame({'E276F': rmsd_CYS_E276F})
cys_F196A_df = pd.DataFrame({'F196A': rmsd_CYS_F196A})
cys_V287T_df = pd.DataFrame({'V287T': rmsd_CYS_V287T})

df = pd.concat([cys_Apo_open_df, cys_Apo_close_df, cys_L192F_df, cys_E276F_df, cys_V287T_df, cys_F196A_df, cys_F280Y_df, cys_L195F_df])
plot_kernel_mut(df, 'CYS215', 'cys_all', 0, 1)

df = pd.concat([cys_L192F_df, cys_E276F_df, cys_V287T_df, cys_F196A_df, cys_F280Y_df, cys_L195F_df])
plot_kernel_mut(df, 'CYS215', 'cys_mut_all', 0, 1)

rmsd_cys = [rmsd_CYS_1sug, rmsd_CYS_apo, rmsd_CYS_F196A]
ax = plt.figure(figsize=(12, 6), frameon=False) # no visible frame
sns.kdeplot(data = rmsd_cys, fill=True, alpha=0.5)
plt.title('CYS215 RMSD Compared to WT Closed')
plt.savefig('mutate_RMSD_cys_F196A.png')
plt.close()

#BEG loop (L1)
beg_Apo_open_df = pd.DataFrame({'Apo Open':rmsd_beg_apo})
beg_Apo_close_df = pd.DataFrame({'Apo Closed': rmsd_beg_1sug})
beg_L192F_df = pd.DataFrame({'L192F': rmsd_beg_L192F})
beg_L195F_df = pd.DataFrame({'L195F': rmsd_beg_L195F})
beg_F280Y_df = pd.DataFrame({'F280Y': rmsd_beg_F280Y})
beg_E276F_df = pd.DataFrame({'E276F': rmsd_beg_E276F})
beg_F196A_df = pd.DataFrame({'F196A': rmsd_beg_F196A})
beg_V287T_df = pd.DataFrame({'V287T': rmsd_beg_V287T})

df = pd.concat([beg_Apo_open_df, beg_Apo_close_df, beg_L192F_df, beg_E276F_df, beg_V287T_df, beg_F196A_df, beg_F280Y_df, beg_L195F_df])
plot_kernel_mut(df, 'L1', 'beg_all', 0, 4)

df = pd.concat([beg_L192F_df, beg_E276F_df, beg_V287T_df, beg_F196A_df, beg_F280Y_df, beg_L195F_df])
plot_kernel_mut(df, 'L1', 'beg_mut_all', 0, 4)

#Determine p-values for each of the sections of focus
file_p = open('p_values_mut.txt', 'w')
p = np.zeros((5, 7))
st, p[0,0] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_L192F, equal_var = False) #Welch's t-test
st, p[0,1] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_E276F, equal_var = False) #Welch's t-test
st, p[0,2] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_F280Y, equal_var = False) #Welch's t-test
st, p[0,3] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_L195F, equal_var = False) #Welch's t-test
st, p[0,4] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_F196A, equal_var = False) #Welch's t-test
st, p[0,5] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_V287T, equal_var = False) #Welch's t-test
st, p[0,6] = stats.ttest_ind(rmsd_a3_top_apo, rmsd_a3_top_1sug, equal_var = False) #Welch's t-test

st, p[1,0] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_L192F, equal_var = False) #Welch's t-test
st, p[1,1] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_E276F, equal_var = False) #Welch's t-test
st, p[1,2] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_F280Y, equal_var = False) #Welch's t-test
st, p[1,3] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_L195F, equal_var = False) #Welch's t-test
st, p[1,4] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_F196A, equal_var = False) #Welch's t-test
st, p[1,5] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_V287T, equal_var = False) #Welch's t-test
st, p[1,6] = stats.ttest_ind(rmsd_a3_apo, rmsd_a3_1sug, equal_var = False) #Welch's t-test

st, p[1,0] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_L192F, equal_var = False) #Welch's t-test
st, p[1,1] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_E276F, equal_var = False) #Welch's t-test
st, p[1,2] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_F280Y, equal_var = False) #Welch's t-test
st, p[1,3] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_L195F, equal_var = False) #Welch's t-test
st, p[1,4] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_F196A, equal_var = False) #Welch's t-test
st, p[1,5] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_V287T, equal_var = False) #Welch's t-test
st, p[1,6] = stats.ttest_ind(rmsd_a4_apo, rmsd_a4_1sug, equal_var = False) #Welch's t-test

st, p[2,0] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_L192F, equal_var = False) #Welch's t-test
st, p[2,1] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_E276F, equal_var = False) #Welch's t-test
st, p[2,2] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_F280Y, equal_var = False) #Welch's t-test
st, p[2,3] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_L195F, equal_var = False) #Welch's t-test
st, p[2,4] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_F196A, equal_var = False) #Welch's t-test
st, p[2,5] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_V287T, equal_var = False) #Welch's t-test
st, p[2,6] = stats.ttest_ind(rmsd_a6_bot_apo, rmsd_a6_bot_1sug, equal_var = False) #Welch's t-test

st, p[3,0] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_L192F, equal_var = False) #Welch's t-test
st, p[3,1] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_E276F, equal_var = False) #Welch's t-test
st, p[3,2] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_F280Y, equal_var = False) #Welch's t-test
st, p[3,3] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_L195F, equal_var = False) #Welch's t-test
st, p[3,4] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_F196A, equal_var = False) #Welch's t-test
st, p[3,5] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_V287T, equal_var = False) #Welch's t-test
st, p[3,6] = stats.ttest_ind(rmsd_CYS_apo, rmsd_CYS_1sug, equal_var = False) #Welch's t-test

sections_mini = ['a3_top', 'a3', 'a4', 'a6_bot']
Labels_mut = ['L192F', 'E276F', 'F280Y', 'L195F', 'F196A', 'V287T', 'Apo Closed']
file_p.write('P values of RMSD with Apo closed reference structure Relative to Apo Open \n')
for i in range(len(sections_mini)):
    file_p.write(str(sections_mini[i]) + '\n')
    for j in range(len(Labels_mut)):
        file_p.write(Labels_mut[j] + ': ' + str(p[i,j]) + '\n')

p = np.zeros((5, 12))
st, p[0,0] = stats.ttest_ind(rmsd_a3_top_L192F, rmsd_a3_top_L192F_AD, equal_var = False) #Welch's t-test
st, p[0,1] = stats.ttest_ind(rmsd_a3_top_E276F, rmsd_a3_top_E276F_AD, equal_var = False) #Welch's t-test
st, p[0,2] = stats.ttest_ind(rmsd_a3_top_F280Y, rmsd_a3_top_F280Y_AD, equal_var = False) #Welch's t-test
st, p[0,3] = stats.ttest_ind(rmsd_a3_top_L195F, rmsd_a3_top_L195F_AD, equal_var = False) #Welch's t-test
st, p[0,4] = stats.ttest_ind(rmsd_a3_top_F196A, rmsd_a3_top_F196A_AD, equal_var = False) #Welch's t-test
st, p[0,5] = stats.ttest_ind(rmsd_a3_top_V287T, rmsd_a3_top_V287T_AD, equal_var = False) #Welch's t-test
st, p[0,6] = stats.ttest_ind(rmsd_a3_top_L192F, rmsd_a3_top_L192F_BBR, equal_var = False) #Welch's t-test
st, p[0,7] = stats.ttest_ind(rmsd_a3_top_E276F, rmsd_a3_top_E276F_BBR, equal_var = False) #Welch's t-test
st, p[0,8] = stats.ttest_ind(rmsd_a3_top_F280Y, rmsd_a3_top_F280Y_BBR, equal_var = False) #Welch's t-test
st, p[0,9] = stats.ttest_ind(rmsd_a3_top_L195F, rmsd_a3_top_L195F_BBR, equal_var = False) #Welch's t-test
st, p[0,10] = stats.ttest_ind(rmsd_a3_top_F196A, rmsd_a3_top_F196A_BBR, equal_var = False) #Welch's t-test
st, p[0,11] = stats.ttest_ind(rmsd_a3_top_V287T, rmsd_a3_top_V287T_BBR, equal_var = False) #Welch's t-test

st, p[1,0] = stats.ttest_ind(rmsd_a3_L192F, rmsd_a3_L192F_AD, equal_var = False) #Welch's t-test
st, p[1,1] = stats.ttest_ind(rmsd_a3_E276F, rmsd_a3_E276F_AD, equal_var = False) #Welch's t-test
st, p[1,2] = stats.ttest_ind(rmsd_a3_F280Y, rmsd_a3_F280Y_AD, equal_var = False) #Welch's t-test
st, p[1,3] = stats.ttest_ind(rmsd_a3_L195F, rmsd_a3_L195F_AD, equal_var = False) #Welch's t-test
st, p[1,4] = stats.ttest_ind(rmsd_a3_F196A, rmsd_a3_F196A_AD, equal_var = False) #Welch's t-test
st, p[1,5] = stats.ttest_ind(rmsd_a3_V287T, rmsd_a3_V287T_AD, equal_var = False) #Welch's t-test
st, p[1,6] = stats.ttest_ind(rmsd_a3_L192F, rmsd_a3_L192F_BBR, equal_var = False) #Welch's t-test
st, p[1,7] = stats.ttest_ind(rmsd_a3_E276F, rmsd_a3_E276F_BBR, equal_var = False) #Welch's t-test
st, p[1,8] = stats.ttest_ind(rmsd_a3_F280Y, rmsd_a3_F280Y_BBR, equal_var = False) #Welch's t-test
st, p[1,9] = stats.ttest_ind(rmsd_a3_L195F, rmsd_a3_L195F_BBR, equal_var = False) #Welch's t-test
st, p[1,10] = stats.ttest_ind(rmsd_a3_F196A, rmsd_a3_F196A_BBR, equal_var = False) #Welch's t-test
st, p[1,11] = stats.ttest_ind(rmsd_a3_V287T, rmsd_a3_V287T_BBR, equal_var = False) #Welch's t-test

st, p[2,0] = stats.ttest_ind(rmsd_a4_L192F, rmsd_a4_L192F_AD, equal_var = False) #Welch's t-test
st, p[2,1] = stats.ttest_ind(rmsd_a4_E276F, rmsd_a4_E276F_AD, equal_var = False) #Welch's t-test
st, p[2,2] = stats.ttest_ind(rmsd_a4_F280Y, rmsd_a4_F280Y_AD, equal_var = False) #Welch's t-test
st, p[2,3] = stats.ttest_ind(rmsd_a4_L195F, rmsd_a4_L195F_AD, equal_var = False) #Welch's t-test
st, p[2,4] = stats.ttest_ind(rmsd_a4_F196A, rmsd_a4_F196A_AD, equal_var = False) #Welch's t-test
st, p[2,5] = stats.ttest_ind(rmsd_a4_V287T, rmsd_a4_V287T_AD, equal_var = False) #Welch's t-test
st, p[2,6] = stats.ttest_ind(rmsd_a4_L192F, rmsd_a4_L192F_BBR, equal_var = False) #Welch's t-test
st, p[2,7] = stats.ttest_ind(rmsd_a4_E276F, rmsd_a4_E276F_BBR, equal_var = False) #Welch's t-test
st, p[2,8] = stats.ttest_ind(rmsd_a4_F280Y, rmsd_a4_F280Y_BBR, equal_var = False) #Welch's t-test
st, p[2,9] = stats.ttest_ind(rmsd_a4_L195F, rmsd_a4_L195F_BBR, equal_var = False) #Welch's t-test
st, p[2,10] = stats.ttest_ind(rmsd_a4_F196A, rmsd_a4_F196A_BBR, equal_var = False) #Welch's t-test
st, p[2,11] = stats.ttest_ind(rmsd_a4_V287T, rmsd_a4_V287T_BBR, equal_var = False) #Welch's t-test

sections_mini = ['a3_top', 'a3', 'a4']
Labels_mut = ['L192F', 'E276F', 'F280Y', 'L195F', 'F196A', 'V287T']
file_p.write('P values of RMSD with Apo closed reference structure Relative to Apo Mut \n')
for i in range(len(sections_mini)):
    file_p.write(str(sections_mini[i]) + '\n')
    for j in range(len(Labels_mut)):
        n = j+6
        file_p.write(Labels_mut[j] + ' AD: ' + str(p[i,j]) + '\n')
        file_p.write(Labels_mut[j] + ' BBR: ' + str(p[i,n]) + '\n')


from datetime import datetime
import csv

def logReceivedGossip(file,gossipID,spreader,audience,awardedSP,targetCitizensSP,receivingAudienceKnownRumours,citizen_list,rumourTarget,sentiment):
	now = datetime.now()
	date_time = now.strftime("%m/%d/%Y %H:%M:%S:%f")

	# get total rumour count
	for key in citizen_list: kt = sum(len(x['knownRumours']) for x in citizen_list.values() if x)

	#'time,key,id,spreader,audience,sp,originalsp,audienceKnownRumours,totalRumours,'
	with open(file, 'a', newline='') as csvfile:
		writer = csv.writer(csvfile)
		writer.writerow([str(date_time),str(gossipID),spreader,audience,str(awardedSP),str(targetCitizensSP),str(len(receivingAudienceKnownRumours)),rumourTarget,sentiment,kt])

def logUpdateMessage(message,file,action='a'):
	f = open(file, action)
	f.write(message)
	f.close()


import json

fs = open("G:\python\Analysis"+"\\"+'score.json', encoding='utf-8')
ft = open("G:\python\Analysis"+"\\"+'template.json', encoding='utf-8')

res1 = fs.read()
data = json.loads(res1)
res2 = ft.read()
template = json.loads(res2)

scoreKey = []
templateKey = template.keys()
goal = {}

for key in data:
    user_id = str(key)
    cases = data[key]['cases']
    cid = []
    res = []

    for case in cases:
        if case["score"] == 100:
            cid.append(case['case_id'])

    for i in templateKey:
        if i in cid:
            res.append(1)
        else:
            res.append(0)

    goal[user_id] = res

json_str = json.dumps(goal, indent=4, ensure_ascii=False)

with open("G:\python\Analysis"+"\\"+"flag.json", 'w', encoding='utf-8') as json_file:
    json_file.write(json_str)


import Node

def readFile(filePath, heuristic=None):
    if heuristic is None:
        heuristic = {}
    with open("./data/" + filePath, 'r') as f:
        data = f.read().splitlines()

    initialState, goalState = None, [None]

    graph = dict()
    count = 0

    for line in data:
        if line == '' or line == '#':
            continue
        elif count == 0:
            initialState = line
            count += 1
            continue
        elif count == 1:
            goalState = line.split()
            count += 1
            continue
        else:
            transitions(line, graph)

    graph = initializeGraph(graph, heuristic)
    return graph, initialState, goalState

def readHeuristic(filePath):
    with open("./data/" + filePath, 'r') as f:
        data = f.read().splitlines()
        heuristic = dict()
        for line in data:
            city, heuristicValue = line.split(" ")
            city = city[:-1]
            heuristic[city] = int(heuristicValue)
    return heuristic

def transitions(line, graph):
    city = line.split()[0][:-1]
    neighbours = [tuple(neighbour.split(',')) for neighbour in line.split()[1:]]
    node = Node.Node(city, {})
    graph[city] = (node, neighbours)

def initializeGraph(graph, heuristic):
    for x, (node, edges) in graph.items():
        for edge in edges:
            neighbor_name, weight = edge
            node.edges[graph[neighbor_name][0]] = int(weight)
            if heuristic:
                node.heuristic = heuristic[node.city]

    return {k: v[0] for k, v in graph.items()}

def setNodes(initialState, goalState, graph):
    initialNode, goalNodes = None, []

    if initialState in graph:
        initialNode = graph[initialState]

    for states in goalState:
        if states in graph:
            goalNodes.append(graph[states])

    return initialNode, goalNodes

def calculateTotalCost(copy):
    totalCost = 0
    parent1 = copy.parent
    while copy.parent:
        parent1 = copy.parent
        for key, value in parent1.edges.items():
            if key.city == copy.city:
                totalCost += value
        copy = copy.parent
    return totalCost

Introduction to Artificial Intelligence/laboratory_exercise_1/utils.py


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

import requests

class MetrikaAPI(object):
    def __init__(self, counter_id, token, host='https://api-metrika.yandex.ru'):
        self.counter_id = counter_id
        self.token = token
        self.host = host

    def _get_url(self, url='/stat/v1/data', params=None, data=None, method='GET'):
        req = requests.request(
            method=method,
            url=self.host + url,
            params=params,
            data=data,
            headers={'Authorization': 'OAuth ' + self.token},
        )
        try:
            req.raise_for_status()
        except requests.exceptions.HTTPError:
            print(req.content)
            raise
        except Exception:
            print("Unexpected exception")
            raise

        return req

    def get_sources_visits(self):
        req = self._get_url(params=dict(
            metrics='ym:s:visits',
            id=self.counter_id,
        ))
        return req.json()

    def get_sources_users(self):
        req = self._get_url(params=dict(
            metrics='ym:s:users',
            id=self.counter_id,
        ))
        return req.json()

    def get_sources_pageviews(self):
        req = self._get_url(params=dict(
            metrics='ym:s:pageviews',
            id=self.counter_id,
        ))
        return req.json()

def main():
    d = MetrikaAPI(44138734, 'тут мог бы быть токен')
    vis = d.get_sources_visits()
    us = d.get_sources_users()
    view = d.get_sources_pageviews()
    print('Всего визитов: {}'.format(vis['data'][0]['metrics']))
    print('Всего посетителей: {}'.format(us['data'][0]['metrics']))
    print('Всего просмотров: {}'.format(view['data'][0]['metrics']))

if __name__ == '__main__':
    main()


from __future__ import annotations

import re
from dataclasses import asdict, dataclass
from typing import Optional, Sized, TypeVar

import torch
import torchinfo
from accelerate.utils.random import set_seed
from torch.utils.data import DataLoader

from simpletrainer.utils.common import pretty_repr

T = TypeVar('T')
set_seed = set_seed

@dataclass
class DataInfo:
    batch_size: int
    batch_size_per_device: int
    num_sampels: Optional[int]
    num_batches_per_epoch: Optional[int]

    def __repr__(self) -> str:
        return pretty_repr(asdict(self), self.__class__.__name__)

def get_batch_size_from_dataloader(dataloader: DataLoader) -> int:
    if dataloader.batch_size is None:
        try:
            return dataloader.batch_sampler.batch_size  # type: ignore
        except AttributeError:
            raise ValueError(
                'Can not get batch size from dataloader, does not support `BatchSampler` with varying batch size yet.'
            )
    else:
        return dataloader.batch_size

def get_num_samples_from_dataloader(dataloader: DataLoader) -> Optional[int]:
    if isinstance(dataloader.dataset, Sized):
        return len(dataloader.dataset)
    elif isinstance(dataloader.sampler, Sized):
        return len(dataloader.sampler)
    else:
        sampler = getattr(dataloader.batch_sampler, 'sampler')
        if isinstance(sampler, Sized):
            return len(sampler)
        else:
            return

def get_data_info(dataloader: DataLoader, world_size: int = 1) -> DataInfo:
    num_samples = get_num_samples_from_dataloader(dataloader)

    try:
        num_batches_per_epoch = len(dataloader)
    except:
        num_batches_per_epoch = None

    batch_size_per_device = get_batch_size_from_dataloader(dataloader)
    batch_size = batch_size_per_device * world_size

    return DataInfo(
        batch_size=batch_size,
        batch_size_per_device=batch_size_per_device,
        num_sampels=num_samples,
        num_batches_per_epoch=num_batches_per_epoch,
    )

def get_model_info(
    model: torch.nn.Module,
    input_data: Optional[torchinfo.torchinfo.INPUT_DATA_TYPE] = None,
    device: Optional[torch.device] = None,
) -> torchinfo.ModelStatistics:
    try:
        model_statistics = torchinfo.summary(model, input_data=input_data, verbose=0, device=device)
    except Exception:
        model_statistics = torchinfo.summary(model, verbose=0, device=device)
    return model_statistics

def get_parameter_id_group_map(
    optimizer: torch.optim.Optimizer,
) -> dict[int, str]:
    parameter_id_group_map = {}
    for group, params in enumerate(optimizer.param_groups):
        for param in params['params']:
            parameter_id_group_map[id(param)] = str(group)
    return parameter_id_group_map

def get_params_with_pattern(model: torch.nn.Module, pattern: re.Pattern):
    params = []
    for name, param in model.named_parameters():
        if pattern.search(name):
            params.append(param)
    return params

def get_module_learning_rate_summary(module: torch.nn.Module, optimizer: torch.optim.Optimizer):
    lr_dict: dict[str, float] = {}
    names = {param: name for name, param in module.named_parameters()}
    for group in optimizer.param_groups:
        if 'lr' not in group:
            continue
        lr = group['lr']
        for param in group['params']:
            if param.requires_grad:
                lr_dict[names[param]] = lr
            else:
                lr_dict[names[param]] = 0.0
    return lr_dict

def get_module_parameter_summary(model: torch.nn.Module):
    parameter_mean: dict[str, float] = {}
    parameter_std: dict[str, float] = {}

    for name, param in model.named_parameters():
        if param.data.numel() > 0:
            parameter_mean[name] = float(param.data.mean().item())
        if param.data.numel() > 1:
            parameter_std[name] = float(param.data.std().item())
    return parameter_mean, parameter_std

def get_module_gradient_summary(model: torch.nn.Module):
    gradient_mean: dict[str, float] = {}
    gradient_std: dict[str, float] = {}

    for name, param in model.named_parameters():
        if param.grad is not None:
            if param.grad.is_sparse:
                grad_data = param.grad.data._values()
            else:
                grad_data = param.grad.data

            # skip empty gradients
            if torch.prod(torch.tensor(grad_data.shape)).item() > 0:
                gradient_mean[name] = float(grad_data.mean().item())
                if grad_data.numel() > 1:
                    gradient_std[name] = float(grad_data.std().item())
    return gradient_mean, gradient_std


# Implement the first move model for the Lego robot.
# 02_a_filter_motor
# Claus Brenner, 31 OCT 2012
from math import sin, cos, pi
from pylab import *
from lego_robot import *

# This function takes the old (x, y, heading) pose and the motor ticks
# (ticks_left, ticks_right) and returns the new (x, y, heading).
def filter_step(old_pose, motor_ticks, ticks_to_mm, robot_width):
    l = ticks_to_mm * motor_ticks[0]
    r = ticks_to_mm * motor_ticks[1]
    # Find out if there is a turn at all.
    if motor_ticks[0] == motor_ticks[1]:
        # No turn. Just drive straight.
        theta = old_pose[2];
        x = old_pose[0] + (l * cos(theta));
        y = old_pose[1] + (l * sin(theta));

    else:
        # Turn. Compute alpha, R, etc.
        alpha = (r - l)/robot_width;
        R = l/alpha;
        cx = old_pose[0] - (R + robot_width/2)*sin(old_pose[2]);
        cy = old_pose[1] + (R + robot_width/2)*cos(old_pose[2]);
        theta = (old_pose[2] + alpha)%(2*pi)
        x = cx + (R + robot_width/2)*sin(theta);
        y = cy - (R + robot_width/2)*cos(theta);

    return (x, y, theta)

if __name__ == '__main__':
    # Empirically derived conversion from ticks to mm.
    ticks_to_mm = 0.349

    # Measured width of the robot (wheel gauge), in mm.
    robot_width = 150.0

    # Read data.
    logfile = LegoLogfile()
    logfile.read("robot4_motors.txt")

    # Start at origin (0,0), looking along x axis (alpha = 0).
    pose = (0.0, 0.0, 0.0)

    # Loop over all motor tick records generate filtered position list.
    filtered = []
    for ticks in logfile.motor_ticks:
        pose = filter_step(pose, ticks, ticks_to_mm, robot_width)
        filtered.append(pose)

    # Draw result.
    for pose in filtered:
        print(pose)
        plot([p[0] for p in filtered], [p[1] for p in filtered], 'bo')
    show()


"""Display image captured from image sensor"""
import numpy as np
import cv2
import socket
import tkinter
import pandas as pd
import datetime
import time
import os

class ImageGUI(object):
    def __init__(self):
        #self.buffer_size = 128 * 128 * 3  # picture size
        self.buffer_size = (16384 * 2 + 2048 * 2)  # picture size
        self.img_buf_index = 0
        self.img_buf_size  = 3
        self.img_buf = np.array([[[0] * 128] * 128] * self.img_buf_size)
        self.array_buf = np.array([[0]*(128*128)]*3)
        self.array_out_buf   = np.array([[0]*(4*8*64)]*2)
        self.array_out_shape = np.array([[[0] * 64] * 32] * 2)
        self.array_pod_out = np.array([[0] * 64] * 32)

        # udp must send bytes object
        self.enquire_command    = bytes([int('0x55', 16), 1])  # 0x55, 0x01
        self.start_command      = bytes([int('0x55', 16), 2])
        self.stop_command       = bytes([int('0x55', 16), 3])
        self.stop_reply         = bytes([int('0xaa', 16), int('0xf3', 16)])

        # 创建主窗口,用于容纳其它组件
        self.root = tkinter.Tk()
        # 给主窗口设置标题内容
        self.root.title("University of Macau AMSV Image Sensor Control")
        self.root.geometry('500x300')

        # 创建一个输入框,并设置尺寸
        self.input_ip = tkinter.Entry(self.root,width=50)

        # 创建一个回显列表
        self.display_info = tkinter.Listbox(self.root, width=50)

        # 创建按钮
        #self.result_button = tkinter.Button(self.root, command = self.find_position, text = "查询")
        self.connect_button     = tkinter.Button(self.root, command = self.connect_fun, text = "Connect")
        self.image_start_button = tkinter.Button(self.root, command = self.trans_start, text = "Start")
        self.image_stop_button  = tkinter.Button(self.root, command = self.image_save_stop, text = "Save")

    # 完成布局
    def gui_arrang(self):
        self.input_ip.pack()
        self.connect_button.place(x=100,y=220,height=50,width=100)
        self.image_start_button.place(x=200,y=220,height=50,width=100)
        self.image_stop_button.place(x=300,y=220,height=50,width=100)
        self.display_info.pack()

    def connect_fun(self, print_en = 1):
        self.ip_addr = self.input_ip.get()
        self.udp_server_ip_addr = self.ip_addr  # target IP address
        self.udp_port = 7                       # port
        self.soc=socket.socket()
        self.soc.connect((self.udp_server_ip_addr, self.udp_port))

        if(print_en == 1):
            self.display_info.insert(0,"Connect successfully")
            self.soc.close()

    def trans_start(self):  # This function will be executed when 'Start' button is clicked
        ## 为回显列表赋值
        #self.display_info.insert(0,input_str)
        #end=self.soc.send(self.start_command) # send 'start' command
        while True:
            t1_init = time.perf_counter()
            self.connect_fun(0)
            #for mean_cnt in range(10):

            #buf_index = 0
            #print('Tcp send')
            self.soc.send(self.start_command) # send 'start' command
            int_dat = []
            cmd_dat = []
            cmd_rec = []

            ############## receive data and cmd ###############
            #print('Tcp receive')
            cmd_rec = self.soc.recv(self.buffer_size)
            for i in cmd_rec[:]:  # transform bytes into int
                cmd_dat.append(int(i))

            if (int(cmd_dat[0]) == int('0x55', 16)) and (int(cmd_dat[1]) == int('0', 16)):
                int_dat = cmd_dat[2:]
                total_len = len(int_dat)
                #print('Tcp receive num:', total_len)
                while total_len < (16384 * 2 + 2048 * 2):
                    #if total_len > 36000:
                    #    break
                    tcp_dat = self.soc.recv(self.buffer_size) # receive data again
                    for i in tcp_dat[:]:  # transform bytes into int
                        int_dat.append(int(i))
                    total_len = len(int_dat)
                    #print('Tcp receive num:', total_len)

                #if total_len < (16384 * 2 + 2048 * 2):
                #    print('TCP data lost! Receive Num:', total_len)
                #    self.soc.close()
                #    self.connect_fun()
                #    continue

                self.array_buf[0][:] = np.array(int_dat[0:16384]) # 曝光前 Pod 数据
                self.array_buf[1][:] = np.array(int_dat[16384:32768])
                array_out_temp1 = np.array(int_dat[32768: (32768 + 2048)])
                array_out_temp2 = np.array(int_dat[(32768 + 2048) : (32768 + 4096)])  # 曝光后 Pod 数据

                # change the 8bit array_out_buf data into 64 bit
                array_shape_temp1  = array_out_temp1.reshape((32, 64), order = 'F')
                array_shape_temp2  = array_out_temp2.reshape((32, 64), order = 'F')
                self.array_out_shape[0]  = array_shape_temp1    # FPGA输出的 OUTR OUTL OUTU OUTD 数据
                # self.array_out_shape[1]  = array_shape_temp2    # Chip输出的 OUTR OUTL OUTU OUTD 数据
                self.array_pod_out  = array_shape_temp2         # Chip输出的 OUT 对应的Pod数据

                self.array_buf[2] = self.array_buf[0] - self.array_buf[1]

                self.img_buf[0] = self.tcp_data2mat(self.array_buf[2]) # reform bytes data into picture structure

                img = np.mat(self.img_buf[0].astype(np.uint8)) # transform img_data into uint8 matrix
                x, y = img.shape[0:2]
                img_test1 = cv2.resize(img, (int(y * 6), int(x * 6)))  # picture reshape (scaling)

                #print('Open-CV show picture')
                cv2.imshow('frame', img_test1)
                if cv2.waitKey(1) & 0xFF == ord('c'):
                    #self.buf_img = img
                    #self.buf_tcp_dat = before_array
                    return 0
            else:
                print('Frame lost! ERROR_code:' + str(cmd_dat[:2]))
                continue

            self.soc.close()
            frame_rate = 1/(time.perf_counter() - t1_init)
            print('Frame Rate:%5.3f' % frame_rate, '/s')

    def tcp_data2mat(self, int_dat):

        #temp = np.array(int_dat)
        #self.img_buf_index = (self.img_buf_index + 1) % self.img_buf_size

        t1 = int_dat.reshape(-1, 16)
        t2 = int_dat.reshape(-1, 16).T
        t3 = t2[0][:].reshape(64,4,2,2)

        pic = np.array([[0]*128]*128) # generate a 128x128 zero array
        for i in range(16):
            for j in range(64):
                for k in range(4):
                    pic[2*j  ][8*i+2*k  ] = t2[i][0+4*k+16*j]
                    pic[2*j  ][8*i+2*k+1] = t2[i][1+4*k+16*j]
                    pic[2*j+1][8*i+2*k+1] = t2[i][2+4*k+16*j]
                    pic[2*j+1][8*i+2*k  ] = t2[i][3+4*k+16*j]

        return pic

    def image_save_stop(self):
        # stop transfer
        self.connect_fun(0)
        end=self.soc.send(self.stop_command)
        image_dat = self.soc.recv(10)

        # create folder
        folder_name = "./Pic_data/" + time.strftime("%Y%m%d%H%M%S")
        dir_exist = os.path.isdir(folder_name)
        if not dir_exist:
            os.makedirs(folder_name)
        #time_info = time.strftime("%Y%m%d%H%M%S")

        # save data
        save = pd.DataFrame(self.img_buf[0])
        save.to_csv(folder_name + '/img_data.csv')
        save = pd.DataFrame(self.array_buf[0])
        save.to_csv(folder_name + '/before_exposure.csv')
        save = pd.DataFrame(self.array_buf[1])
        save.to_csv(folder_name + '/after_exposure.csv')
        save = pd.DataFrame(self.array_buf[2])
        save.to_csv(folder_name + '/sub_data.csv')

        #save = pd.DataFrame(self.array_out_buf[0])
        #save.to_csv(folder_name + '/out_chip_data.csv')
        save = pd.DataFrame(self.array_out_shape[0])
        save.to_csv(folder_name + '/out_fpga_data.csv')

        #save = pd.DataFrame(self.array_out_shape[1])
        #save.to_csv(folder_name + '/out_chip_data.csv')
        save = pd.DataFrame(self.array_pod_out)
        save.to_csv(folder_name + '/out_pod_data.csv')

        #save = pd.DataFrame(self.array_out_buf[1])
        #save.to_csv(folder_name + '/out_fpga_data.csv')

        if(image_dat == self.stop_reply):
            self.display_info.insert(0,'Stop and Save successfully!')

    def image_show(self):
        # Image show
        cap = cv2.VideoCapture(0)
        cap.open(0)
        while True:
            ret, frame = cap.read()
            if not ret:
                print("Can't receive frame (stream end?). Exiting ...")
                break
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            cv2.imshow('frame', gray)
            if cv2.waitKey(1) == ord('q'):
                break
        cap.release()
        cv2.destroyAllWindows()

def main():
    # 初始化对象
    FL = ImageGUI()
    # 进行布局
    FL.gui_arrang()
    # 主程序执行
    tkinter.mainloop()
    pass

if __name__ == "__main__":
    main()

########### UDP client Transfer #########
#from socket import *
#HOST = '192.168.1.10'
#PORT = 8080
#BUFSIZ = 1024
#ADDRESS = (HOST, PORT)
#udpClientSocket = socket(AF_INET, SOCK_DGRAM)
#
#while True:
#    data  = bytes([int('0xFE', 16), 0,2,0,1])
#    if not data:
#        break
#
#    # 发送数据
#    udpClientSocket.sendto(data, ADDRESS)
#    # 接收数据
#    data, ADDR = udpClientSocket.recvfrom(BUFSIZ)
#    if not data:
#        break
#    print("服务器端响应：", data)
#
#udpClientSocket.close()

######## TCP Client Transfer #########
#client_sock = socket.socket()
#client_sock.connect(('192.168.1.10', 7))
## 发送个连接信息
#stop_command = bytes([int('0x55', 16), 3])  # udp must send bytes object
#client_sock.send(stop_command)
#while 1:
#    recv_dat = client_sock.recv(1024)
#    print(recv_dat)
#    # 有关输入的
#    aa = input("echo >>:")
#    if aa == 'exit':
#        break
#    while not aa:
#        aa = input("echo >>:")
#     # 重点就是上下两句
#    client_sock.send(aa.encode('utf-8'))
#client_sock.close()