import json
import re
import unicodedata

import sqlalchemy
from sqlalchemy import text

import db
import db.dataset_eval
from db import exceptions
from utils import dataset_validator

def slugify(string):
    """Converts unicode string to lowercase, removes alphanumerics and
    underscores, and converts spaces to hyphens. Also strips leading and
    trailing whitespace.
    """
    string = unicodedata.normalize('NFKD', string).encode('ascii', 'ignore').decode('ascii')
    string = re.sub('[^\w\s-]', '', string).strip().lower()
    return re.sub('[-\s]+', '-', string)

def create_from_dict(dictionary, author_id):
    """Creates a new dataset from a dictionary.

    Returns:
        Tuple with two values: new dataset ID and error. If error occurs first
        will be None and second is an exception. If there are no errors, second
        value will be None.
    """
    dataset_validator.validate(dictionary)

    with db.engine.begin() as connection:
        if "description" not in dictionary or dictionary["description"] is None:
            dictionary["description"] = ""

        result = connection.execute("""INSERT INTO dataset (id, name, description, public, author)
                          VALUES (uuid_generate_v4(), %s, %s, %s, %s) RETURNING id""",
                                    (dictionary["name"], dictionary["description"], dictionary["public"], author_id))
        dataset_id = result.fetchone()[0]

        for cls in dictionary["classes"]:
            if "description" not in cls or cls["description"] is None:
                cls["description"] = ""
            result = connection.execute("""INSERT INTO dataset_class (name, description, dataset)
                              VALUES (%s, %s, %s) RETURNING id""",
                                        (cls["name"], cls["description"], dataset_id))
            cls_id = result.fetchone()[0]

            # Remove duplicate recordings, preserving order
            seen = set()
            cls["recordings"] = [r for r in cls["recordings"] if not (r in seen or seen.add(r))]

            for recording_mbid in cls["recordings"]:
                connection.execute("INSERT INTO dataset_class_member (class, mbid) VALUES (%s, %s)",
                                   (cls_id, recording_mbid))

    return dataset_id

def update_dataset_meta(dataset_id, meta):
    """ Update the metadata (name, description, public) for a dataset.

    Args:
        dataset_id: id of the dataset to update
        meta: dictionary of metadata to update

    Valid keys for `meta` are: `name`, `description`, `public`.
    If one of these keys is not present, the corresponding field
    for the dataset will not be updated. If no keys are present,
    the dataset will not be updated.
    """

    params = {}
    updates = []
    # Check meta values against None because "" and False are valid values
    name = meta.pop("name", None)
    if name is not None:
        updates.append("name = :name")
        params["name"] = name
    desc = meta.pop("description", None)
    if desc is not None:
        updates.append("description = :description")
        params["description"] = desc
    public = meta.pop("public", None)
    if public is not None:
        updates.append("public = :public")
        params["public"] = public

    if meta:
        raise ValueError("Unexpected meta value(s): %s" % ", ".join(meta.keys()))

    setstr = ", ".join(updates)
    query = text("""UPDATE dataset
                       SET %s
                     WHERE id = :id
            """ % setstr)

    # Only do an update if we have items to update
    if params:
        params["id"] = dataset_id
        with db.engine.begin() as connection:
            connection.execute(query, params)

def update(dataset_id, dictionary, author_id):
    # TODO(roman): Make author_id argument optional (keep old author if None).
    dataset_validator.validate(dictionary)

    with db.engine.begin() as connection:
        if "description" not in dictionary or dictionary["description"] is None:
            dictionary["description"] = ""

        connection.execute("""UPDATE dataset
                          SET (name, description, public, author, last_edited) = (%s, %s, %s, %s, now())
                          WHERE id = %s""",
                           (dictionary["name"], dictionary["description"], dictionary["public"], author_id, dataset_id))

        # Replacing old classes with new ones
        connection.execute("""DELETE FROM dataset_class WHERE dataset = %s""", (dataset_id,))

        for cls in dictionary["classes"]:
            if "description" not in cls or cls["description"] is None:
                cls["description"] = ""
            result = connection.execute("""INSERT INTO dataset_class (name, description, dataset)
                              VALUES (%s, %s, %s) RETURNING id""",
                                        (cls["name"], cls["description"], dataset_id))
            cls_id = result.fetchone()[0]

            for recording_mbid in cls["recordings"]:
                connection.execute("INSERT INTO dataset_class_member (class, mbid) VALUES (%s, %s)",
                                   (cls_id, recording_mbid))

def get(id):
    """Get dataset with a specified ID.

    Returns:
        Dictionary with dataset details if it has been found, None
        otherwise.
    """
    with db.engine.connect() as connection:
        result = connection.execute(
            "SELECT id::text, name, description, author, created, public, last_edited "
            "FROM dataset "
            "WHERE id = %s",
            (str(id),)
        )
        if result.rowcount < 1:
            raise exceptions.NoDataFoundException("Can't find dataset with a specified ID.")
        row = dict(result.fetchone())
        row["classes"] = _get_classes(row["id"])
        row["num_recordings"] = sum([len(cl.get("recordings", [])) for cl in row["classes"]])
        return row

def get_public_datasets(status):
    if status == "all":
        statuses = db.dataset_eval.VALID_STATUSES
    elif status in db.dataset_eval.VALID_STATUSES:
        statuses = [status]
    else:
        raise ValueError("Unknown status")

    with db.engine.connect() as connection:
        query = text("""
            SELECT dataset.id::text
                 , dataset.name
                 , dataset.description
                 , "user".musicbrainz_id AS author_name
                 , dataset.created
                 , job.status
            FROM dataset
            JOIN "user"
              ON "user".id = dataset.author
              LEFT JOIN LATERAL (SELECT dataset_eval_jobs.status
                                   FROM dataset_eval_jobs
                                   JOIN dataset_snapshot
                                     ON dataset_snapshot.id = dataset_eval_jobs.snapshot_id
                                  WHERE dataset.id = dataset_snapshot.dataset_id
                               ORDER BY dataset_eval_jobs.updated DESC
                               LIMIT 1)
                               AS JOB ON TRUE
          WHERE dataset.public = 't'
            AND job.status = ANY((:status)::eval_job_status[])
       ORDER BY dataset.created DESC
             """)
        result = connection.execute(query, {"status": statuses})
        return [dict(row) for row in result]

def _get_classes(dataset_id):
    with db.engine.connect() as connection:
        query = text("""SELECT id::text
                             , name
                             , description
                          FROM dataset_class
                         WHERE dataset = :dataset_id
                      ORDER BY id
        """)
        result = connection.execute(query, {"dataset_id": dataset_id})
        rows = result.fetchall()
        classes = []
        for row in rows:
            row = dict(row)
            row["recordings"] = _get_recordings_in_class(row["id"])
            classes.append(row)
        return classes

def _get_recordings_in_class(class_id):
    with db.engine.connect() as connection:
        result = connection.execute("SELECT mbid::text FROM dataset_class_member WHERE class = %s",
                                    (class_id,))
        recordings = []
        for row in result:
            recordings.append(row["mbid"])
        return recordings

def get_by_user_id(user_id, public_only=True):
    """Get datasets created by a specified user.

    Returns:
        List of dictionaries with dataset details.
    """
    with db.engine.connect() as connection:
        where = "WHERE author = %s"
        if public_only:
            where += " AND public = TRUE"
        result = connection.execute("SELECT id, name, description, author, created "
                                    "FROM dataset " + where,
                                    (user_id,))
        datasets = []
        for row in result:
            datasets.append(dict(row))
        return datasets

def delete(id):
    """Delete dataset with a specified ID."""
    with db.engine.begin() as connection:
        connection.execute("DELETE FROM dataset WHERE id = %s", (str(id),))

def create_snapshot(dataset_id):
    """Creates a snapshot of current version of a dataset.

    Snapshots are stored as JSON and have the following structure:
    {
        "name": "..",
        "description": "..",
        "classes": [
            {
                "name": "..",
                "description: "..",
                "recordings": ["..", ...]
            },
            ...
        ]
    }

    Args:
        dataset_id (string/uuid): ID of a dataset.

    Returns:
        ID (UUID) of a snapshot that was created.
    """
    dataset = get(dataset_id)
    if not dataset:
        raise exceptions.NoDataFoundException("Can't find dataset with a specified ID.")
    snapshot = {
        "name": dataset["name"],
        "description": dataset["description"],
        "classes": [{
                        "name": c["name"],
                        "description": c["description"],
                        "recordings": c["recordings"],
                    } for c in dataset["classes"]],
    }
    with db.engine.connect() as connection:
        result = connection.execute(sqlalchemy.text("""
            INSERT INTO dataset_snapshot (id, dataset_id, data)
                 VALUES (uuid_generate_v4(), :dataset_id, :data)
              RETURNING id::text
        """), {
            "dataset_id": dataset_id,
            "data": json.dumps(snapshot),
        })
        return result.fetchone()["id"]

def get_snapshot(id):
    """Get snapshot of a dataset.

    Args:
        id (string/uuid): ID of a snapshot.

    Returns:
        dictionary: {
            "id": <ID of the snapshot>,
            "dataset_id": <ID of the dataset that this snapshot is associated with>,
            "created": <creation time>,
            "data": <actual content of a snapshot (see `create_snapshot` function)>
        }
    """
    with db.engine.connect() as connection:
        result = connection.execute(sqlalchemy.text("""
            SELECT id::text
                 , dataset_id::text
                 , data
                 , created
              FROM dataset_snapshot
             WHERE id = :id
        """), {"id": id})
        row = result.fetchone()
        if not row:
            raise db.exceptions.NoDataFoundException("Can't find dataset snapshot with a specified ID.")
        return dict(row)

def _delete_snapshot(connection, snapshot_id):
    """Delete a snapshot.

    Args:
        connection: an SQLAlchemy connection.
        snapshot_id (string/uuid): ID of a snapshot.
    """
    query = sqlalchemy.text("""
        DELETE FROM dataset_snapshot
              WHERE id = :snapshot_id""")
    connection.execute(query, {"snapshot_id": snapshot_id})

def get_snapshots_for_dataset(dataset_id):
    """Get all snapshots created for a dataset.

    Args:
        dataset_id (string/uuid): ID of a dataset.

    Returns:
        List of snapshots as dictionaries.
    """
    with db.engine.connect() as connection:
        result = connection.execute(sqlalchemy.text("""
            SELECT id::text
                 , dataset_id::text
                 , data
                 , created
              FROM dataset_snapshot
             WHERE dataset_id = :dataset_id
        """), {"dataset_id": dataset_id})
        return [dict(row) for row in result]

def _delete_snapshots_for_dataset(connection, dataset_id):
    """Delete all snapshots of a dataset.

    Args:
        connection: an SQLAlchemy connection.
        dataset_id (string/uuid): ID of a dataset.
    """
    query = sqlalchemy.text("""
        DELETE FROM dataset_snapshot
              WHERE dataset_id = :dataset_id""")
    connection.execute(query, {"dataset_id": dataset_id})

def _get_classid_for_dataset(connection, dataset_id, class_name):
    query = sqlalchemy.text("""
      SELECT id
        FROM dataset_class
       WHERE name = :name
         AND dataset = :dataset_id""")
    result = connection.execute(query, {"name": class_name, "dataset_id": dataset_id})
    if result.rowcount < 1:
        raise exceptions.NoDataFoundException("No such class exists.")
    clsid = result.fetchone()
    return clsid[0]

def add_recordings(dataset_id, class_name, recordings):
    """Adds new recordings to a class in a dataset.

    If any given recording already exist in this class it is not added again.

    Args:
        dataset_id: the uuid of the dataset
        class_name: The class to add the recordings to
        recordings: List of recordings (MBID strings) to add

    Raises:
        NoDataFoundException if the dataset doesn't exist or if the class doesn't exist in the dataset
    """

    with db.engine.begin() as connection:
        clsid = _get_classid_for_dataset(connection, dataset_id, class_name)
        for mbid in recordings:
            connection.execute(sqlalchemy.text("""
              INSERT INTO dataset_class_member (class, mbid)
                   SELECT :clsid, :mbid
         WHERE NOT EXISTS (SELECT *
                             FROM dataset_class_member d
                            WHERE d.class = :clsid
                              AND d.mbid = :mbid)
                      """),
                               {"clsid": clsid, "mbid": mbid})

def delete_recordings(dataset_id, class_name, recordings):
    """Delete recordings from a dataset class"""

    with db.engine.begin() as connection:
        clsid = _get_classid_for_dataset(connection, dataset_id, class_name)
        for mbid in recordings:
            connection.execute(sqlalchemy.text("""
                DELETE FROM dataset_class_member
                      WHERE class = :class_name
                        AND mbid = :mbid_num
                            """),
                               {"class_name": clsid, "mbid_num": mbid})

def add_class(dataset_id, class_data):
    """Add a class to a dataset

    If the dict argument contains a key "recordings", add these recordings
    to the class as well. See :func:`add_recordings`.
    If the class already exists, do not add it again, but add recordings
    to it if they are given.

    Args:
        dataset_id: the UUID of the dataset to add this class to
        class_data: A dictionary representing the class to add:
              {"name": "Classname", "description": "Class desc",
               "recordings": [list of recording ids (optional)}
    """

    with db.engine.begin() as connection:
        if "description" not in class_data:
            class_data["description"] = ""
        connection.execute(sqlalchemy.text("""
            INSERT INTO dataset_class (name, description, dataset)
                 SELECT :name, :description, :datasetid
       WHERE NOT EXISTS (SELECT *
                           FROM dataset_class d
                          WHERE d.name = :name
                            AND d.dataset = :datasetid)
                    """),
                           {"name": class_data["name"], "description": class_data["description"], "datasetid": dataset_id})
    if "recordings" in class_data:
        add_recordings(dataset_id, class_data["name"], class_data["recordings"])

def delete_class(dataset_id, class_data):
    """Delete a class from a dataset

    Deletes the class members as well since we have ON DELETE CASCADE set in the database

    Args:
        dataset_id: the UUID of the dataset to delete this class from
        class_data: A dictionary representing the class to delete:
              {"name": "Classname"}
    """

    with db.engine.begin() as connection:
        query = sqlalchemy.text("""
            DELETE FROM dataset_class
                  WHERE name = :class_name
                    AND dataset = :dataset_id
                        """)
        connection.execute(query,  {"class_name": class_data["name"], "dataset_id": dataset_id})

def update_class(dataset_id, class_name, class_data):
    """ Update the metadata (name, description) for a class.

    Args:
        dataset_id: id of the dataset to update
        class_name: the name of the class to update
        class_data: dictionary of metadata to update

    Valid keys for `meta` are: `name` (required),
     `new_name` (optional), `description` (optional)
    If one of the optional keys is not present, the corresponding field
    for the class will not be updated. If no keys are present,
    the class will not be updated.
    """

    params = {}
    updates = []
    if "new_name" in class_data:
        updates.append("name = :new_name")
        params["new_name"] = class_data["new_name"]
    if "description" in class_data:
        updates.append("description = :description")
        params["description"] = class_data["description"]
    setstr = ", ".join(updates)
    update_query = text("""UPDATE dataset_class
                               SET %s
                             WHERE id = :id

            """ % setstr)

    if params:
        with db.engine.begin() as connection:
            clsid = _get_classid_for_dataset(connection, dataset_id, class_name)
            params["id"] = clsid

            connection.execute(update_query, params)

def check_recording_in_dataset(dataset_id, mbid):
    """Check whether an MBID is in a given dataset.
    Args:
        dataset_id: ID of a dataset
        mbid: MBID to be checked
    Returns:
        True if an MBID appears anywhere in a dataset, False otherwise
    """
    with db.engine.connect() as connection:
        result = connection.execute(sqlalchemy.text("""
            SELECT dataset_class.id
              FROM dataset_class
              JOIN dataset_class_member
                ON dataset_class_member.class = dataset_class.id
             WHERE dataset_class.dataset = :dataset_id
               AND dataset_class_member.mbid = :mbid
        """), {"dataset_id": dataset_id, "mbid": mbid})

        return result.rowcount > 0


from flask import Flask
from flask_session import Session
from flask_caching import Cache

from app.models import db
from config import Config
from app.routes import register_routes

cache = Cache()

def create_app():
    app = Flask(__name__, instance_relative_config=True)
    app.config.from_object(Config.get_config())

    cache.init_app(app)
    db.init_app(app)
    register_routes(app)
    Session(app)

    return app

if __name__ == '__main__':
    app = create_app()
    app.run()
else:
    gunicorn_app = create_app()


### MYSWaningImmunity
### From CasesDeaths --- ICU and Deaths
### Used in assessing severe outcomes
### SOURCE FILE: 02dec2021 VINTAGE
### Additional columns: dupes, trace (pre-Sep), test (pre-Sep), frontliners
### FOR PUBLIC RELEASE (ANONYMITY CHECKS)

import pandas as pd
import numpy as np
from datetime import date, timedelta
import statsmodels.discrete.discrete_model as sm
import plotly.graph_objects as go
from patsy import dmatrices
import itertools
import time
import telegram_send
import dataframe_image as dfi

time_start = time.time()

### 0 --- Preliminaries
## File paths
path_input = ''
path_wi = '' # RR folder
## File name
file_input = 'CasesDeaths_WaningImmunity_Data_RR.csv'
## Data frames
list_col_dates = ['date_lab', 'date_death',
                  'date1', 'date2'] # taken from CasesDeaths_Data
df = pd.read_csv(path_input + file_input, parse_dates=list_col_dates)
for i in list_col_dates:
    df[i] = df[i].dt.date # %Y-%m-%d format

### I --- Double check
## Check missing
for i in df.columns: print(i + ': ' + str(df.loc[df[i].isna(), i].count()) + ' missing')
print('\n\n')
for i in df.columns: print(i + ': ' + str(df.loc[df[i].isin([np.inf, -np.inf]), i].count()) + ' inf')
## Delete columns never used in analysis (intended for other side projects)
col_notused = ['dead_gap', 'infdead_gap']
for i in col_notused: del df[i]
## Rename duplicate as 'reinf' (these are repeat entries at different dates in the cases line listing, hence assumed to be reinfections)
df = df.rename(columns={'duplicate':'reinf'})
## Fill NA
col_na_str0 = ['date1', 'date2' , 'date_death', 'type1', 'type2']
for i in col_na_str0: df.loc[df[i].isna(), i] = '0'
for i in df.columns: df.loc[df[i].isna(), i] = 0
## Reset index
df = df.reset_index(drop=True)
## Impose data type
dict_df_dtype = {'date1': 'str',
                 'date2': 'str',
                 'date_lab': 'str',
                 'date_death': 'str',
                 'dead': 'int',
                 'symptomatic': 'int',
                 'icu': 'int',
                 'comorb': 'int',
                 'age': 'int',
                 'malaysian': 'int',
                 'male': 'int',
                 'state_id': 'int',
                 'type1': 'str',
                 'type2': 'str',
                 'type_comb': 'str',
                 'vax_partial': 'int',
                 'vax_full': 'int',
                 'test_count': 'float',
                 'trace_count': 'float',
                 'frontliner': 'float',
                 'reinf': 'int'}
df = df.astype(dict_df_dtype)

### II --- Export as parquet (save space)
df.to_parquet(path_input + 'CasesDeaths_WaningImmunity_Data_RR_ForRelease.parquet', compression='brotli')

### End
print('\n----- Ran in ' + "{:.0f}".format(time.time() - time_start) + ' seconds -----')


import boto3
import pandas as pd
import numpy as np
import pickle
import os
import requests
import json
import zipfile
import logging
import time
from time import strftime, gmtime, sleep
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from datetime import datetime
from urllib.parse import urlparse
from sagemaker.s3 import S3Downloader

# How often to check the status
UPDATE_DELAY_SECONDS = 15
HOME_DIRECTORY = os.path.expanduser("~")

def signed_request(method, url, data=None, params=None, headers=None, service=None):
    request = AWSRequest(
        method=method, url=url, data=data, params=params, headers=headers
    )
    session = boto3.Session()
    credentials = session.get_credentials()
    try:
        frozen_creds = credentials.get_frozen_credentials()
    except AttributeError:
        print("Could not find valid IAM credentials in any the following locations:\n")
        print(
            "env, assume-role, assume-role-with-web-identity, sso, shared-credential-file, custom-process, "
            "config-file, ec2-credentials-file, boto-config, container-role, iam-role\n"
        )
        print(
            "Go to https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html for more "
            "details on configuring your IAM credentials."
        )
        return request
    SigV4Auth(frozen_creds, service, boto3.Session().region_name).add_auth(request)
    return requests.request(
        method=method, url=url, headers=dict(request.headers), data=data
    )

def load_configuration():
    with open(f"{HOME_DIRECTORY}/graph_notebook_config.json") as f:
        data = json.load(f)
        host = data["host"]
        port = data["port"]
        if data["auth_mode"] == "IAM":
            iam = True
        else:
            iam = False
    return host, port, iam

def get_host():
    host, port, iam = load_configuration()
    return host

def get_training_job_name(prefix: str):
    return f"{prefix}-{int(time.time())}"

def check_ml_enabled():
    host, port, use_iam = load_configuration()
    response = signed_request(
        "GET", url=f"https://{host}:{port}/ml/modeltraining", service="neptune-db"
    )
    if response.status_code != 200:
        print(
            """This Neptune cluster \033[1mis not\033[0m configured to use Neptune ML.
Please configure the cluster according to the Amazpnm Neptune ML documentation before proceeding."""
        )
    else:
        print("This Neptune cluster is configured to use Neptune ML")

def get_neptune_ml_job_output_location(job_name: str, job_type: str):
    assert job_type in [
        "dataprocessing",
        "modeltraining",
        "modeltransform",
    ], "Invalid neptune ml job type"

    host, port, use_iam = load_configuration()

    response = signed_request(
        "GET",
        service="neptune-db",
        url=f"https://{host}:{port}/ml/{job_type}/{job_name}",
        headers={"content-type": "application/json"},
    )
    result = json.loads(response.content.decode("utf-8"))
    if result["status"] != "Completed":
        logging.error(
            "Neptune ML {} job: {} is not completed".format(job_type, job_name)
        )
        return
    return result["processingJob"]["outputLocation"]

def get_modeltraining_job_output_location(training_job_name: str):
    assert (
        training_job_name is not None
    ), "Neptune ML training job name id should be passed, if training job s3 output is missing"
    return get_neptune_ml_job_output_location(training_job_name, "modeltraining")

def get_embeddings(
    training_job_name: str, download_location: str = "./model-artifacts"
):
    training_job_s3_output = get_modeltraining_job_output_location(training_job_name)
    if not training_job_s3_output:
        return

    download_location = os.path.join(download_location, training_job_name)
    os.makedirs(download_location, exist_ok=True)
    # download embeddings and mapping info

    S3Downloader.download(
        os.path.join(training_job_s3_output, "embeddings/"),
        os.path.join(download_location, "embeddings/"),
    )

    entity_emb = np.load(os.path.join(download_location, "embeddings", "entity.npy"))

    return entity_emb

def get_mapping(training_job_name: str, download_location: str = "./model-artifacts"):
    training_job_s3_output = get_modeltraining_job_output_location(training_job_name)
    if not training_job_s3_output:
        return

    download_location = os.path.join(download_location, training_job_name)
    os.makedirs(download_location, exist_ok=True)
    # download embeddings and mapping info

    S3Downloader.download(training_job_s3_output, download_location)


import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

import os

class DenseLayer(object):
    def __init__(self, n_in, m_out, name, f=tf.nn.relu):
        W = tf.Variable(tf.random_normal(shape=(n_in, m_out)) * 2 / np.sqrt(n_in), name=name + "_W")
        b = tf.Variable(np.zeros(m_out).astype(np.float32), name=name + "_b")
        self.f = f

        self.W = W
        self.b = b
        self.params = [self.W, self.b]
        self.name = name

    def forward(self, X):
        a = tf.matmul(X, self.W) + self.b

        return self.f(a)

def plot_grid(samples):
    fig = plt.figure(figsize=(4,4))
    gs = gridspec.GridSpec(4,4)
    i = 0

    for sample in samples:
        if i > 15:
            break
        ax = plt.subplot(gs[i])
        plt.axis('off')
        i += 1

        ax.set_aspect('equal')

        plt.imshow(sample.reshape(28, 28), cmap='gray' )

    return fig

class GAN(object):
    def __init__(self, n_latent, d_sizes, g_sizes, index):

        self.index = index
        img_size = 28
        self.img_size = img_size
        self.d_sizes = d_sizes
        self.g_sizes = g_sizes
        self.g_layers = []
        self.d_layers = []

        self.n_latent = n_latent

        self.g_vars = []
        self.d_vars = []

        n_in = img_size**2

        self.g_sizes.append(img_size**2)
        self.d_sizes.append(1)
        mnist = input_data.read_data_sets('../data/MNIST_data', one_hot=True)
        self.X = mnist.train.images
        count = 0

        for d_size in self.d_sizes:
            name = "discriminator_" + str(count)
            if d_size != self.d_sizes[-1]:
                layer = DenseLayer(n_in, d_size, name)
            else:
                layer = DenseLayer(n_in, d_size, name, lambda x:x)

            self.d_layers.append(layer)
            self.d_vars.append(layer.params)
            count += 1
            n_in = d_size

        n_in = n_latent
        count = 0
        for g_size in self.g_sizes:
            name = "generator_" + str(count)

            if g_size != self.g_sizes[-1]:
                layer = DenseLayer(n_in, g_size, name)
            else:
                layer = DenseLayer(n_in, g_size, name, tf.nn.sigmoid)

            self.g_layers.append(layer)
            self.g_vars.append(layer.params)
            count += 1
            n_in = g_size

    def sample_generator(self, noise):
        # E = tf.placeholder(tf.float32, shape=(examples, self.n_latent))
        sample = noise
        for layer in self.g_layers:
            sample = layer.forward(sample)

        return sample

    def forward_discriminator(self, X):
        out = X
        for layer in self.d_layers:
            out = layer.forward(out)

        return out

    def fit(self):

        E = tf.placeholder(dtype = tf.float32, shape=(None, self.n_latent))
        Z = tf.placeholder(dtype=tf.float32, shape=(None, self.img_size**2))

        sampled_images = self.sample_generator(E)
        logits = self.forward_discriminator(Z)
        logits_sampled = self.forward_discriminator(sampled_images)
        sampled_images_test = self.sample_generator(E)

        d_cost_real = tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=tf.ones_like(logits))
        d_cost_fake = tf.nn.sigmoid_cross_entropy_with_logits(logits=logits_sampled, labels=tf.zeros_like(logits_sampled))

        g_cost = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits_sampled, labels=tf.ones_like(logits_sampled)))
        d_cost = tf.reduce_mean(d_cost_fake) + tf.reduce_mean(d_cost_real)

        d_train_op = tf.train.AdamOptimizer().minimize(d_cost, var_list=self.d_vars)
        g_train_op = tf.train.AdamOptimizer().minimize(g_cost, var_list=self.g_vars)

        self.init_op = tf.global_variables_initializer()
        self.sess = tf.InteractiveSession()
        self.sess.run(self.init_op)

        d_costs = []
        g_costs = []
        batch_sz = 16
        epochs = 1000

        n_batches = len(self.X) // batch_sz

        if not os.path.exists('../samples' + str(self.index) +'/'):
            os.makedirs('../samples' + str(self.index) +'/')

        k = 0
        for i in range(epochs):
            print("epoch:", i)
            np.random.shuffle(self.X)
            for j in range(n_batches):
                batch = self.X[j * batch_sz:(j + 1) * batch_sz]
                W = np.random.uniform(-1, 1, size=(batch_sz, self.n_latent))
                _, d_cost_value = self.sess.run((d_train_op, d_cost), feed_dict={Z: batch, E: W})
                _, g_cost_value = self.sess.run((g_train_op, g_cost), feed_dict={E: W})
                d_costs.append(d_cost_value)
                g_costs.append(g_cost_value)

                if j % 100 == 0:
                    print("epoch " + str(i) + " iter " + str(j) + " d cost: " + str(d_costs[-1]) + " g cost: " + str(g_costs[-1]))
                    Z_out_test = self.sess.run(tf.nn.sigmoid(sampled_images_test),
                                               feed_dict={E: W})

                    fig = plot_grid(Z_out_test)
                    plt.savefig('../samples' + str(self.index) +'/' + str(k)+ '.png')
                    k += 1
                    plt.close(fig)

g = GAN(50, [150], [300], 1)
g.fit()

g2 = GAN(30, [150, 500], [150, 500], 2)
g2.fit()


#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
It is possible to show that the square root of two can be expressed as an infinite continued fraction.

√ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213...

By expanding this for the first four iterations, we get:

1 + 1/2 = 3/2 = 1.5
 1 + 1/(2 + 1/2) = 7/5 = 1.4
 1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
 1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...

The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985,
is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.

In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator?

observations:
a[n] = 1 + 1 / (1 + a[n-1])
a0 = 1

a[n-1] = frn / frd
fr[n] =  (frn + 2 * frd) / (frd + frn)

gcd(frn, frd) -- not necessary, how to prove it?
'''
import time
import math
DEBUG = True

N=1000

def gcd(a, b):
    while b != 0:
        (a, b) = (b, a % b)
    return a

def main():
    S = 0
    frn = 1
    frd = 1
    n0 = 0
    for n in range(N):
      (frn, frd) = (frn+frd*2, frd+frn)

      g = gcd (frn, frd)
      if g > 1:
        d(['reduce fraction %i / %i' % (frn,frd)])
        frn = frn // g
        frd = frd // g
      if len(str(frn)) > len(str(frd)):
        S = S + 1
        d([n,n-n0,frn, frd])
        n0 = n
    print(['result', S])

def d(args):
    global DEBUG
    if DEBUG:
      print(args)

if  __name__ =='__main__':
  tStart = time.time()
  main()
  print(['time[ms]',int((time.time() - tStart)*1000)])


from __future__ import annotations

# pygame
import pygame
from pygame import Surface
from pygame.freetype import SysFont
# numpy
import numpy as np
from numpy_typing import NDArray
# project
from game_map import MapCell
from data_manager import Texture
from sprite import Sprite
from colour import ColourType
from health_bar import HealthBar
from utility import scale_by_height
# standard
from typing import TYPE_CHECKING
import math

if TYPE_CHECKING:
    from game import RaycastingGame

class GameRenderer:
    RAY_DISTANCE_BOUND: float = 0.01
    FONT_SCALE_RATIO: float = 0.05
    FONT_NAME: str = ""
    HIT_EFFECT_TIME: int = 1000
    HIT_EFFECT_MAX_OPACITY = 150
    WEAPON_PARABOLA_EXPONENT = 2
    WEAPON_PARABOLA_COEFFICIENT = 0.1
    WEAPON_Y_OFFSET: float = -WEAPON_PARABOLA_COEFFICIENT**WEAPON_PARABOLA_EXPONENT
    CROSSHAIR_NAME: str = "crosshair"
    CROSSHAIR_SCALE: float = 0.05

    def __init__(self, game: RaycastingGame, sky_texture: Texture):
        self.game: RaycastingGame = game
        self.texture_map: dict[MapCell, list[Texture]] = {
            MapCell.WALL: self.game.data.textures["mossy_cobblestone"].columns
        }
        self.z_buffer: [NDArray[float]] = np.empty((0, ))
        self.floor_colour: ColourType = (75, 105, 47)
        self.sky_texture: Texture = sky_texture
        self.scaled_sky: Texture = sky_texture
        self.light_surface: Surface = Surface((0, 0))
        self.light_surface.set_alpha(100)
        self.hit_surface: Surface = Surface((0, 0))
        self._hit_start_time: int = np.iinfo(int).min
        self.font: SysFont = SysFont(GameRenderer.FONT_NAME, 0)
        self.health_bar: HealthBar = HealthBar(self.game.data)
        self.crosshair_texture: Texture = game.data.textures[GameRenderer.CROSSHAIR_NAME].texture

    def resize(self, size):
        self.z_buffer = np.empty((size[0], ))

        # resize light surface
        old_colour = (0, 0, 0) if self.light_surface.get_width() == 0 or self.light_surface.get_height() == 0 else self.light_surface.get_at((0, 0))
        old_alpha = self.light_surface.get_alpha()
        self.light_surface = Surface(size)
        self.light_surface.fill(old_colour)
        self.light_surface.set_alpha(old_alpha)

        old_alpha = self.light_surface.get_alpha()
        self.hit_surface = Surface(size)
        self.hit_surface.set_alpha(old_alpha)
        self.hit_surface.fill((255, 0, 0))

        # scale sky texture
        texture_height = size[1] // 2
        texture_width = texture_height * self.sky_texture.get_width() // self.sky_texture.get_height()
        if texture_width < size[0]:  # width is too small
            texture_width = size[0]
            texture_height = texture_width * self.sky_texture.get_height() // self.sky_texture.get_width()

        self.scaled_sky = pygame.transform.scale(self.sky_texture, (texture_width, texture_height))

        # font
        self.font: SysFont = SysFont(GameRenderer.FONT_NAME, int(size[1] * GameRenderer.FONT_SCALE_RATIO))

        # health bar
        self.health_bar.resize(size)

    def draw_walls(self, surface: Surface):
        for x in range(surface.get_width()):
            # how far x is along the screen between -0.5 and 0.5
            camera_x = x / surface.get_width() - 0.5
            # raycast
            info = self.game.raycast(self.game.player.position, self.game.player.forward + self.game.player.camera_plane * camera_x)

            # store hit distance into z-buffer
            self.z_buffer[x] = info.perp_wall_dist

            if info.hit:
                # determine line height, clamping to surface height if the wall distance is very low to avoid running
                # out of memory when scaling the texture
                line_height = surface.get_height() if info.perp_wall_dist <= GameRenderer.RAY_DISTANCE_BOUND else int(surface.get_height() / info.perp_wall_dist)

                # find the point at which the wall was hit
                wall_x = info.collision[1] if info.ns_wall else info.collision[0]
                wall_x -= np.floor(wall_x)

                # get the wall's texture columns from the texture map
                texture = self.texture_map[self.game.map[info.map_position[1], info.map_position[0]]]

                # find the index of the texture column the ray hit
                texture_x = int(wall_x * len(texture))

                centre_offset_y = (surface.get_height() - line_height) / 2

                scaled_texture = pygame.transform.scale(texture[texture_x], (1, line_height))

                # blit scaled texture column to screen
                surface.blit(scaled_texture, (x, centre_offset_y))

    def draw_sprites(self, surface: Surface):
        def square_distance(sprite: Sprite):
            relative_position = sprite.position - self.game.player.position
            return relative_position[0] * relative_position[0] + relative_position[1] * relative_position[1]

        sorted_sprites = sorted(self.game.sprites, key=square_distance, reverse=True)

        # determine surface centres on each axis
        screen_centre_x = surface.get_width() / 2
        screen_centre_y = surface.get_height() / 2

        for sprite in sorted_sprites:
            # find position of sprite with player as the origin
            relative_position = sprite.position - self.game.player.position
            # rotate sprite to camera space
            transformed = np.matmul(self.game.player.inv_camera_matrix, relative_position)

            for texture_data in sprite.textures:
                if texture_data is None:
                    continue

                texture = texture_data.texture
                # determine sprite dimensions based on distance
                sprite_height = min(surface.get_height() * texture.get_height(), abs(int(surface.get_height() / transformed[1] * sprite.scale)))
                sprite_width = int(sprite_height * texture.get_width() / texture.get_height())

                # determine centre of sprite on screen
                screen_x = screen_centre_x * (1 + transformed[0] / transformed[1] * 2) - sprite_width / 2
                screen_y = screen_centre_y - sprite_height / 2 + surface.get_height() * -sprite.height_offset / transformed[1]

                if texture_data.simple_clip:
                    flipped_texture = pygame.transform.flip(texture, texture_data.flip_x, False) if texture_data.flip_x else texture
                    surface.blit(pygame.transform.scale(flipped_texture, (sprite_width, sprite_height)), (screen_x, screen_y))
                else:
                    # scale texture columns to the correct size
                    scaled_texture_columns = list(map(lambda x: pygame.transform.scale(x, (1, sprite_height)), texture_data.columns))

                    for x in range(sprite_width):
                        column_screen_x = int(screen_x + x)
                        # if:
                        # 1. the distance to the sprite is not negative (i.e. it is in front of the camera)
                        # 2. the texture column is on screen
                        # 3. the texture column is in front of all walls
                        if transformed[1] > 0 and \
                                0 <= column_screen_x < self.z_buffer.shape[0] and \
                                transformed[1] < self.z_buffer[column_screen_x]:
                            index = int(x / sprite_width * texture.get_width())
                            if texture_data.flip_x:
                                index = -index
                            surface.blit(scaled_texture_columns[index], (column_screen_x, screen_y))

    def draw_floor(self, surface: Surface):
        surface.fill(self.floor_colour, (0, surface.get_height() // 2, surface.get_width(), surface.get_height()))

    def draw_sky(self, surface: Surface):
        sky_region = math.atan2(self.game.player.forward[1], self.game.player.forward[0]) / math.pi / 2
        if sky_region < 0:
            sky_region = 1 + sky_region

        half_surface_height = surface.get_height() // 2

        source = pygame.Rect(int(self.scaled_sky.get_width() * sky_region), 0, surface.get_width(), half_surface_height)

        surface.blit(self.scaled_sky, (0, 0), source)

        if source.right > self.scaled_sky.get_width():
            dest = (self.scaled_sky.get_width() - source.left, 0)
            surface.blit(self.scaled_sky, dest, pygame.Rect(0, 0, source.left, half_surface_height))

    def postprocess(self, surface: Surface):
        surface.blit(self.light_surface, (0, 0))

        time = pygame.time.get_ticks()
        hit_effect_interval = time - self._hit_start_time
        if hit_effect_interval < self.HIT_EFFECT_TIME:
            effect_factor = hit_effect_interval / self.HIT_EFFECT_TIME

            self.hit_surface.set_alpha(GameRenderer.HIT_EFFECT_MAX_OPACITY - int(effect_factor * GameRenderer.HIT_EFFECT_MAX_OPACITY))

            surface.blit(self.hit_surface, (0, 0))

    def draw_weapon(self, surface: Surface):
        player = self.game.player
        texture = player.weapon.get_texture().texture
        height = surface.get_height() * self.game.player.weapon.get_window_scale()
        width = height * texture.get_width() / texture.get_height()
        scaled_texture = pygame.transform.scale(texture, (int(width), int(height)))

        screen_x = (surface.get_width() - scaled_texture.get_width()) // 2
        screen_y = surface.get_height() - scaled_texture.get_height()

        screen_x += player.footstep_progress * surface.get_width() // 10
        screen_y -= ((player.footstep_progress * GameRenderer.WEAPON_PARABOLA_COEFFICIENT)**GameRenderer.WEAPON_PARABOLA_EXPONENT + GameRenderer.WEAPON_Y_OFFSET) * surface.get_height()

        surface.blit(scaled_texture, (screen_x, screen_y))

    def draw_hud(self, surface: Surface):
        self.health_bar.draw(surface, (self.font.size, self.font.size), self.game.player)
        self.font.render_to(surface, (0, surface.get_height() - self.font.size), "Wave " + str(self.game.enemy_manager.wave))
        scaled_crosshair = scale_by_height(self.crosshair_texture, int(surface.get_height() * GameRenderer.CROSSHAIR_SCALE))
        surface.blit(scaled_crosshair, ((surface.get_width() - scaled_crosshair.get_width()) // 2, (surface.get_height() - scaled_crosshair.get_height()) // 2))

    def draw(self, surface: Surface):
        self.draw_floor(surface)
        self.draw_sky(surface)
        self.draw_walls(surface)
        self.draw_sprites(surface)
        self.postprocess(surface)
        self.draw_weapon(surface)
        self.draw_hud(surface)

    def run_hit_effect(self):
        self._hit_start_time = pygame.time.get_ticks()


''' 완전탐색

그리디 문제라 해서 그리디로 풀었다가 멘탈 터짐.. 첨부터 완전탐색으로 풀껄... 그리디인지 바로 판별 안되는 것 부터 내 실력임을 반성해야함..
완전 탐색의 경우 2^N이라 2 ^ 20 탐색이라 시간 초과일줄 알았는데  "B" * 20 으로 해본 결과 1048575 => 대략 10 ^ 5 밖에 나오지 않음.
완전 탐색이 팩토리얼이 아닌 2^N인 경우 대략 20에서 25 사이 정도는 쓸만하다. 라고 할 수 있겠다.
'''

def move(n, pos, dx):
    return (pos + dx + n) % n

def distance(n, pos, dx, s):
    cnt = 1
    idx = move(n, pos, dx)
    while s[idx] == 0 and cnt < n:
        idx = move(n, idx, dx)
        cnt += 1
    if cnt >= n:
        return -1, None
    return cnt, idx

def convert_string_to_number(s):
    ans = []
    for ch in s:
        ans.append(ord(ch) - ord("A"))
    return ans

def solve(n, pos, s):
    score = min(s[pos], 26 - s[pos])
    s[pos] = 0
    # print(f"solve: n:{n}, pos:{pos}, s:{s}, score: {score}")

    left_dist, left_idx = distance(n, pos, -1, s)
    right_dist, right_idx = distance(n, pos, 1, s)
    if left_dist == -1:
        return score

    score += min(
        solve(n, left_idx, s[:]) + left_dist, solve(n, right_idx, s[:]) + right_dist
    )
    return score

def solution(name):
    pos = 0
    n = len(name)
    s = convert_string_to_number(name)
    return solve(n, pos, s)

# print(solution("BBBBBBBBBBBBBBBBBBBB"))


import torch
from math import sqrt
from torch import nn

D_MODEL = 512

def manual_SDPA(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor) -> torch.Tensor:
    """
    Args:
        q (tensor): The queries, of dimension (*, d_k, D_MODEL).
        k (tensor): The keys, of dimension (*, d_k, D_MODEL).
        v (tensor): The values, of dimension (*, d_v, D_MODEL).
    """
    q_mul_k = torch.matmul(q, k.transpose(-2, -1))
    scaled = torch.div(q_mul_k, sqrt(k.shape[-1]))
    e_powered = torch.exp(scaled)
    softmaxed = torch.div(e_powered, torch.sum(e_powered).unsqueeze(-1))
    return torch.matmul(softmaxed, v)

class manual_MHA(nn.Module):
    def __init__(self, num_heads: int):
        """
        Args:
            num_heads (int): Number of heads to concatenate together at end.
        """
        super().__init__()
        self.num_heads = num_heads
        assert D_MODEL % num_heads == 0, \
            f"D_MODEL / num_heads must divide evenly, not {D_MODEL} / {num_heads}!"
        self.d_k = int(D_MODEL / num_heads)
        self.d_v = int(D_MODEL / num_heads)
        self.q_lin_projs = nn.Parameter(torch.randn(num_heads,
                                                    D_MODEL,
                                                    self.d_k))
        self.k_lin_projs = nn.Parameter(torch.randn(num_heads,
                                                    D_MODEL,
                                                    self.d_k))
        self.v_lin_projs = nn.Parameter(torch.randn(num_heads,
                                                    D_MODEL,
                                                    self.d_v))
        self.concat_lin_proj = nn.Parameter(torch.randn(num_heads * self.d_v,
                                                        D_MODEL))

    def forward(self, embeded_seq: torch.Tensor) -> torch.Tensor:
        """
        Args:
            embeded_seq (tensor): A matrix of the embeded sequence, of
                dimension (seq_len, D_MODEL).
        """
        # Create matrix with a copy of the input sequence for each head
        expanded_seq = embeded_seq.expand(self.num_heads, -1, -1)

        # Results have dimensions of (num_heads, seq_len, d_k or d_v)
        qs = torch.matmul(expanded_seq, self.q_lin_projs)
        ks = torch.matmul(expanded_seq, self.k_lin_projs)
        vs = torch.matmul(expanded_seq, self.v_lin_projs)

        print(f"qs: {qs.shape}")
        print(f"ks: {ks.shape}")
        print(f"vs: {vs.shape}")

        # Calculate attentions
        head_attns = manual_SDPA(qs, ks, vs)

        print(f"head_attns: {head_attns.shape}")

        # Concat head outputs to dimensions of (seq_len, self.num_heads * self.d_v)
        concat_heads = torch.cat([head_attn.squeeze(dim=0) for head_attn in torch.split(head_attns, 1, dim=0)], dim=1)

        return torch.matmul(concat_heads, self.concat_lin_proj)

class manual_encoder(nn.Module):
    def __init__(self, d_model: int):
        """
        Args:
            d_model (int): Dimension of embeddings and tensors passed between
                internal blocks of the encoder and decoder.
        """
        super().__init__()

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        pass

class manual_decoder(nn.Module):
    def __init__(self, ):
        """
        Args:

        """

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        pass

if __name__ == "__main__":
    sdpa = manual_SDPA()


# 1. 토달기(#1897)
import sys
sys.stdin = open('input.txt')
input = sys.stdin.readline

N, start = input().rstrip().split()

dictionary = []
for _ in range(int(N)):
    dictionary.append(input().rstrip())
dictionary.sort(key=lambda x: len(x)) # 단어들 길이 오름차순 정렬

result = start # 선생님이 말한 단어를 result 초깃값으로 설정
memo = { start: 1 } # 단어들 저장해둘 dict
for text in dictionary: # 짧은 단어들부터 for문 돌기
    n = len(text)
    for k in range(0, n): # 단어의 첫인덱스부터 끝-1인덱스까지 돌면서
        newText = text[0:k] + text[k+1:n] # k번째 자리 없는 단어 만들기
        if newText in memo: # 그 단어가 이전에 만들었던 단어중에 있으면
            memo[text] = 1 # 현재 단어도 dict에 추가
            if len(text) > len(result): # result보다 더 긴 단어면 result 갱신
                result = text
print(result)


from binarytree import BinaryTree
from cs260.data_structures.ch_three_hw.stack import Stack
import operator
import re

'''
Exercise 1: Extend the build_parse_tree function to handle mathematical expressions that do
not have spaces between every character.
>> Function 'tokenize() acomplishes this

Exercise 2: Modify the build_parse_tree and evaluate functions to handle boolean statements
(and, or, and not). Remember that “not” is a unary operator, so this will complicate your
code somewhat.

Exercise 7: Clean up the print_exp function so that it does not include an ‘extra’ set of parentheses
around each number.
'''

def build_parse_tree(fpexp):
    """Builds parse tree, requires fully parenthesized equation
    Arguments:
        fpexp {String} -- Fully parenthesized equation
    Returns:
        eTree {BinaryTree} -- Binary tree build out from Fully parenthesized equation
    """
    fplist = tokenize(fpexp)
    if not checkbalance(fplist):
        raise Exception('Unbalanced parenthesis')
    pStack = Stack()
    eTree = BinaryTree('')
    pStack.push(eTree)
    currentTree = eTree

    for i in fplist:
        #open parenthesis
        if i == '(':
            currentTree.insertLeft('')
            pStack.push(currentTree)
            currentTree = currentTree.getLeftChild()
        #unary operator
        elif i == 'not':
            parent = pStack.pop()
            currentTree = parent
            currentTree.setRootVal(i)
            pStack.push(currentTree)
            currentTree = currentTree.getLeftChild()
        #binary operator
        elif i in ['+', '-', '*','**','//', '/','<','<=','==','!=','>','>=','and','or']:
            currentTree.setRootVal(i)
            currentTree.insertRight('')
            pStack.push(currentTree)
            currentTree = currentTree.getRightChild()
        #close parenthesis
        elif i == ')':
            currentTree = pStack.pop()
        #number or boolean val
        elif i not in ['+', '-', '*', '/', ')']:
            try:
                if(i == 'True' or i == 'False'):
                    currentTree.setRootVal(i)
                else:
                    currentTree.setRootVal(int(i))
                parent = pStack.pop()
                currentTree = parent

            except ValueError:
                raise ValueError(f"token {i} is not a valid integer")

    return eTree

def tokenize(exp):
    """Takes in a string expression and tokenizes
    Arguments:
        exp {String} -- string expression
    Return:
        {List} - list of expression
    """
    x = re.split(r'(\d+|\*+|\band|or|<=|==|>=|!=|not\b|\/+|[^A-Za-z0-9])', exp)
    return [i for i in x if i.strip()]

def checkbalance(tokenlist):
    """Checks if there are balances parenthesis
    Arguments:
        tokenlist {List}
    Reuturns:
        {Boolean}
    """
    return tokenlist.count('(') == tokenlist.count(')')

def postordereval(tree):
    """Evaluates parse tree
    Arguments:
        tree {BinaryTree} -- binary tree built out as parse tree
    """
    opers = get_opers()
    if tree:
        left = postordereval(tree.getLeftChild())
        right = postordereval(tree.getRightChild())
        #two operands
        if left != None and right != None:
            return opers[tree.getRootVal()](left,right)
        #one operand
        elif left != None and right == None:
            return opers[tree.getRootVal()](left)
        else:
            return tree.getRootVal()

def get_opers():
    return {
    '+':operator.add,
    '-':operator.sub,
    '*':operator.mul,
    '**':operator.pow,
    '/':operator.truediv,
    '//': operator.floordiv,
    '<':operator.lt,
    '<=':operator.le,
    '>':operator.gt,
    '>=':operator.ge,
    '==':operator.eq,
    '!=':operator.ne,
    'and': lambda op1,op2: op1 and op2,
    'or': lambda op1,op2: op1 or op2,
    'not': lambda op1: not op1
    }

def printexp(tree):
    """Builds fully parenthesized string from full parse tree
    Arguments:
        tree {BinaryTree}
    Returns:
        {String}
    """
    sVal = ""
    if tree:
        sVal = '(' + printexp(tree.getLeftChild()) if tree.leftChild else ' ' + printexp(tree.getLeftChild())
        sVal = sVal + str(tree.getRootVal())
        sVal = sVal + printexp(tree.getRightChild())+')' if tree.rightChild else sVal + printexp(tree.getRightChild()) + ' '
    return sVal

pt = build_parse_tree('((8 * 5) + (4 * 4))')
print(printexp(pt))
x = postordereval(pt)
print(x)


#Name: Lee Yi Hao

import unittest
import boto3
import sys
sys.path.append('../')
from uuid import uuid4
from moto import mock_dynamodb2

MATERIAL1 = {
    "mat_name": "Paper Feeder Chapter 1",
    "mat_type": "doc",
    "url" : "www.s3bucket.com"
}

MATERIAL2 = {
    "mat_name": "Paper Feeder Chapter 2",
    "mat_type": "doc",
    "url" : "www.s3bucket.com"
}

SECTION1 = {
    "section_id": "0a08ff5c-d72a-4207-b1de-9bbe99efa7fd",
    "section_name": "Paper Feeder",
    "course_id": "IS111",
    "class_id": 1,
    "section_number":1,
    "materials": [MATERIAL1],
    "quiz": "e565b935-2adc-43b2-9d1c-c8fc29eee91a"
}

SECTION2 = {
    "section_id": "0a08ff5c-d72a-4207-b1de-9bbe99easdsd",
    "section_name": "Ink",
    "course_id": "IS111",
    "class_id": 1,
    "section_number":2,
    "materials": [],
    "quiz": None
}

SECTION3 = {
    "section_id": "0a08ff5c-d72a-4207-b1de-9bbe99eaaadsd",
    "section_name": "Ink2",
    "course_id": "IS110",
    "class_id": 1,
    "section_number":1,
    "materials": [],
    "quiz": None
}

class TestMaterial(unittest.TestCase):
    def setUp(self):
        from modules.section_manager import Material
        self.test_material = Material(MATERIAL1)

    def tearDown(self):
        self.test_material = None

    def test_json(self):
        self.assertTrue(isinstance(self.test_material.json(), dict), "Material JSON is not a dictionary")
        self.assertEqual(MATERIAL1, self.test_material.json(), "Material JSON does not match")
        self.assertNotEqual(MATERIAL2, self.test_material.json(), "Material JSON matched when it should not")

class TestSection(unittest.TestCase):
    def setUp(self):
        from modules.section_manager import Section
        self.test_section = Section(SECTION1)

    def tearDown(self):
        self.test_section = None

    def test_json(self):
        self.assertTrue(isinstance(self.test_section.json(), dict), "Section JSON is not a dictionary object")
        self.assertEqual(SECTION1, self.test_section.json(), "Section JSON does not match")
        self.assertNotEqual(SECTION2, self.test_section.json(), "Section JSON matched when it should not")

    def test_add_quiz(self):
        to_add = uuid4()
        self.test_section.add_quiz(to_add)
        self.assertEqual(to_add, self.test_section.get_quiz(), "Quiz does not match after adding")

    def test_add_material(self):
        from modules.section_manager import Material
        self.test_section.add_material(Material(MATERIAL2))
        self.assertEqual([MATERIAL1, MATERIAL2], [mat.json() for mat in self.test_section.get_materials()], "Material list does not match after adding material")

        with self.assertRaises(ValueError, msg="Failed to raise exception when adding a non-material object") as context:
            self.test_section.add_material(MATERIAL2)

        self.assertTrue("Object added is not a Material Object" == str(context.exception))

    def test_remove_material(self):
        with self.assertRaises(IndexError, msg="Failed to raise exception when index out of range") as context:
            self.test_section.remove_material(1)

        self.assertTrue("pop index out of range" == str(context.exception))
        self.test_section.remove_material(0)
        self.assertEqual([], self.test_section.get_materials())

@mock_dynamodb2
class TestSectionDAO(unittest.TestCase):
    def setUp(self):
        from modules import create_tables
        from modules.section_manager import SectionDAO
        self.dynamodb = boto3.resource('dynamodb', region_name = 'ap-southeast-1')
        results = create_tables.create_section_table(self.dynamodb)
        self.table=self.dynamodb.Table('Section')
        self.table.put_item(Item = SECTION1)
        self.table.put_item(Item = SECTION2)
        self.dao = SectionDAO()

    def tearDown(self):
        self.dao = None
        self.table.delete()
        self.table = None
        self.dynamodb= None

    def test_insert_section_w_dict(self):
        from modules.section_manager import Section
        insertDefault = self.dao.insert_section_w_dict({"section_name": 'abdce', 'course_id':'abcde', 'class_id':1})
        self.assertTrue(isinstance(insertDefault, Section))
        self.assertEqual(1, insertDefault.get_section_number(), "Inserted section w dictionary number wrong")

        insertTest = self.dao.insert_section_w_dict(SECTION3)

        self.assertEqual(SECTION3, insertTest.json(), "SectionDAO dictionary insert values do not match")

        with self.assertRaises(ValueError, msg ="Failed to prevent duplicate insert") as context:
            self.dao.insert_section_w_dict(SECTION1)

        self.assertTrue("Section already exists" == str(context.exception))

    def test_retrieve_all_from_class(self):
        section_list = self.dao.retrieve_all_from_class("IS111", 1)
        self.assertEqual([SECTION1, SECTION2], [section.json() for section in section_list], msg="Retrieved sections from class does not match")

        section_list2 = self.dao.retrieve_all_from_class("IS110",2)
        self.assertEqual([], [section.json() for section in section_list2], msg="Retrieved sections when it should not retrieve anything")

    def test_retrieve_one(self):
        self.assertEqual(SECTION1, self.dao.retrieve_one(SECTION1['section_id']).json(), "SectionDAO retrieve existing one test failure")
        self.assertEqual(None, self.dao.retrieve_one("abcdea"), "SectionDAO retrieve not existing one test failure")

    def test_update_section(self):
        from modules.section_manager import Section, Material
        sectionObj = Section(SECTION2)
        sectionObj.add_material(Material(MATERIAL1))
        sectionObj.add_quiz(str(uuid4()))
        self.dao.update_section(sectionObj)
        toCheck = self.table.get_item(Key={'section_id': sectionObj.get_section_id(), 'class_id': sectionObj.get_class_id()})['Item']
        self.assertEqual(sectionObj.json(), toCheck, "SectionDAO update test failure")

if __name__ == "__main__":
    unittest.main()


import sys

input = lambda: sys.stdin.readline().rstrip()

def print(*args, sep=' ', end='\n'):
    sys.stdout.write(sep.join(map(str, args)))
    sys.stdout.write(end)

def solution():
    def f(x: float) -> float:
        ans = 0
        for i in range(n + 1):
            ans += a[i] * x ** i
        return ans

    cx, cy, cd = [float(num) for num in input().split()]
    n = int(input())
    a = [float(num) for num in input().split()]
    a.reverse()
    x = float(input())
    left = x
    right = x + 3 * cd
    for i in range(100):
        mid = left + (right - left) / 2
        if (mid - cx) ** 2 + (f(mid) - cy) ** 2 > cd ** 2:
            right = mid
        else:
            left = mid
    print(mid)

def main():
    t = 1
    while t:
        solution()
        t -= 1

if __name__ == '__main__':
    main()


def binarySearch(alist, item):
    first=0
    last=len(alist)-1
    found = False

    while first<=last and not found:
        midpoint=(first+last)//2
        if alist[midpoint]==item:
            found =True
        else:
            if item<alist[midpoint]:
                last=midpoint-1
            else:
                first=midpoint+1
    return found
print("Enter the number to search")
num=int(input())
alist=[0, 1, 2, 8, 13, 17, 19, 32, 42,]
z=(binarySearch(alist,num))
if z==True:
    print("Number is present in the list")
else:
    print("Number is not present in the list")


# -*- coding: UTF-8 -*-
"""
:Script:   .py
:Author:   Dan.Patterson@carleton.ca
:Modified: 2017-xx-xx
:Purpose:  tools for working with numpy arrays
:Useage:
:
:References:
:
:---------------------------------------------------------------------:
"""
def pad_date(fld):
    """input a date field, strip off the time and format"""
    if fld is not None:
        lst = [int(i) for i in (str(fld).split(" ")[0]).split("-")]
        return "{}-{:02.0f}-{:02.0f}".format(*lst)
    else:
        return None

# ----------------------------------------------------------------------
# __main__ .... code section
if __name__ == "__main__":
    """ A simple test """
    from datetime import datetime
    n = str(datetime.now())
    print(pad_date(n))


from contextvars import ContextVar
from typing import Any, Optional

from sanic.log import logger
from sqlalchemy.ext.asyncio.engine import AsyncEngine, create_async_engine
from sqlalchemy.ext.asyncio.session import AsyncSession
from sqlalchemy.orm import relationship, selectinload
from sqlalchemy.orm.exc import UnmappedClassError
from sqlalchemy.orm.mapper import class_mapper
from sqlalchemy.sql.expression import select

from heliotrope.abc.database import AbstractGalleryinfoDatabase
from heliotrope.database.orm.base import mapper_registry
from heliotrope.database.orm.table import *
from heliotrope.domain import *

_base_model_session_ctx: ContextVar[AsyncSession] = ContextVar("session")

class _SessionManager:
    def __init__(self, engine: AsyncEngine) -> None:
        self.engine = engine

    async def __aenter__(self) -> "_SessionManager":
        self.session = AsyncSession(self.engine, expire_on_commit=False)
        self.session_ctx_token = _base_model_session_ctx.set(self.session)
        return self

    async def __aexit__(self, *args: Any) -> None:
        if hasattr(self, "session_ctx_token"):
            _base_model_session_ctx.reset(self.session_ctx_token)
            await self.session.close()

class ORM(AbstractGalleryinfoDatabase):
    def __init__(self, engine: AsyncEngine) -> None:
        self.engine = engine

    @staticmethod
    def mapping() -> None:
        mapper_registry.map_imperatively(
            Galleryinfo,
            galleryinfo_table,
            properties={
                "files": relationship(File),
                "tags": relationship(Tag),
                "artists": relationship(Artist),
                "characters": relationship(Character),
                "groups": relationship(Group),
                "parodys": relationship(Parody),
                "scene_indexes": relationship(SceneIndex),
                "languages": relationship(Language),
                "related": relationship(Related),
            },
        )
        mapper_registry.map_imperatively(Tag, tag_table)
        mapper_registry.map_imperatively(File, file_table)
        mapper_registry.map_imperatively(Artist, artist_table)
        mapper_registry.map_imperatively(Character, character_table)
        mapper_registry.map_imperatively(Group, group_table)
        mapper_registry.map_imperatively(Parody, parody_table)
        mapper_registry.map_imperatively(SceneIndex, scene_index_table)
        mapper_registry.map_imperatively(Related, related_table)
        mapper_registry.map_imperatively(Language, language_table)
        return None

    @classmethod
    async def setup(cls, db_url: str) -> "ORM":
        logger.debug(f"Setting up {cls.__name__}")
        # Because it is mapped manually, an error occurs if it is already mapped.
        # 수동으로 매핑하기때문에 이미 매핑돼있을경우 오류가 발생합니다.
        try:
            class_mapper(Galleryinfo)
        except UnmappedClassError:
            cls.mapping()
        engine = create_async_engine(db_url)
        async with engine.begin() as connection:
            await connection.run_sync(
                mapper_registry.metadata.create_all, checkfirst=True
            )
        return cls(engine)

    async def add_galleryinfo(self, galleryinfo: Galleryinfo) -> None:
        async with _SessionManager(self.engine) as manager:
            async with manager.session.begin():
                manager.session.add(galleryinfo)

        return None

    async def get_galleryinfo(self, id: int) -> Optional[Galleryinfo]:
        if -2147483648 < id > 2147483647:
            return None
        async with _SessionManager(self.engine) as manager:
            async with manager.session.begin():
                r = await manager.session.get(
                    Galleryinfo,
                    id,
                    [
                        selectinload(Galleryinfo.files),
                        selectinload(Galleryinfo.tags),
                        selectinload(Galleryinfo.artists),
                        selectinload(Galleryinfo.characters),
                        selectinload(Galleryinfo.groups),
                        selectinload(Galleryinfo.parodys),
                        selectinload(Galleryinfo.scene_indexes),
                        selectinload(Galleryinfo.languages),
                        selectinload(Galleryinfo.related),
                    ],
                )
                if r:
                    return r

        return None

    async def get_all_index(self) -> list[int]:
        async with _SessionManager(self.engine) as manager:
            async with manager.session.begin():
                result = await manager.session.execute(select(Galleryinfo.id))
                return [int(id) for id, in result.all()]


n = int(input())

for i in range(n):
    car_number = input().split('-')
    first_number = 0
    k = 2
    for j in car_number[0]:
        number = ord(j)-ord('A')
        first_number += number * (26**k)
        k -= 1
    if abs(first_number-int(car_number[1]))>100:
        print("not nice")
    else:
        print("nice")


import argparse
args = argparse.ArgumentParser()
args.add_argument("--config_path", help="Path to Config File", default="configs/train_habitat.yaml")
args = args.parse_args()

from configs import get_cfg_defaults

from trainer import Trainer

if __name__ == "__main__":

    cfg = get_cfg_defaults()

    if args.config_path[-4:] == 'yaml':
        cfg.merge_from_file(args.config_path)
    else:
        print("No valid config specified, using default")

    cfg.freeze()
    print(cfg)

    # Train stage 1
    # Assume that it has been trained, and it SAVES all the depth outputs in a

    train = Trainer(cfg)
    train.train()


"""
Given a string, what is the minimum number of adjacent swaps required to convert a string into a palindrome. If not possible, return -1.

Time  : O(N^2)
Space : O(N), where N = len(s)
"""

class Solution:
    def canPermutePalindrome(self, s: str) -> bool:
        freqCount = {}
        for char in s:   #character count in string
            if char in freqCount:
                freqCount[char] += 1
            else:
                freqCount[char] = 1
        countOdd = 0
        for key, val in freqCount.items():
            if val % 2 != 0:    # if a character count is odd then increement countOdd
                countOdd += 1
        N = len(s)
        if N % 2 == 0:
            return countOdd == 0  # if length is even and no character count is odd then return True
        else:
            return countOdd == 1

    def min_swaps(self,s):  #using two pointers
        if not self.canPermutePalindrome(s):
            return -1
        s = list(s)  #since string is immutable converting to list
        front,back = 0, len(s)-1   #two pointers
        minSwap = 0
        while front < back:  # --> two cases will check
            if s[front] == s[back]:  # CASE 1: if front and back char are equal
                front += 1
                back -= 1
            else:  # CASE 2: front != back

                # finding the rightmost character that matches the front char --> we will two cases here
                mid = back
                while s[mid] != s[front] and mid > front:
                    mid -= 1

                if mid == front:  # case 1: if char not found--> swap once with right neighbor and continue the while loop
                    s[mid], s[mid+1] = s[mid+1], s[mid]
                    minSwap += 1
                    continue

                for i in range(mid,back):  #case 2: if char found --> SWAP WITH RIGHT NEIGHBOR UNTIL IT ENDS UP AT THE BACK
                    #print(i)
                    s[i], s[i+1] = s[i+1], s[i]
                    minSwap += 1

                front += 1
                back -=1

        return minSwap

obj = Solution()
s = 'mamad'
s = 'ntiin'
print(obj.min_swaps(s))

Arrays/Minimum Adj swaps to palindrome.py


import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    #Class to manage bullets fired from ship
    def __init__(self,ai_settings,screen,ship):
        #Creating bullets object at ships position
        super(Bullet,self).__init__()
        self.screen=screen

        #Create bullet at rect(0,0) and then set correct position.
        self.rect  =  pygame.Rect(0,0,
          ai_settings.bullet_width, ai_settings.bullet_height)
        self.rect.centerx  =  ship.rect.centerx
        self.rect.top  =  ship.rect.top

        #Store Bullets position as decimal value
        self.y  =  float(self.rect.y)

        self.color  =  ai_settings.bullet_color
        self.speed_factor  =  ai_settings.bullet_speed_factor

    def update(self):
        #Moving bullet up the screen
        #Updating Decimal position of bullet
        self.y -= self.speed_factor
        #Update the rect  position
        self.rect.y=self.y

    def draw_bullet(self):
        #Drawing bullet to the screen
        pygame.draw.rect(self.screen, self.color, self.rect)


from django.contrib import admin
from django.urls import path,include
from . import views

urlpatterns = [
    path('',views.Registration_User),
    path('Home',views.Home,name = 'Home'),
    path('pdf',views.pdf,name = 'pdf'),
    path('download',views.download,name = 'download'),
    path('Apply_Test/',views.Apply_Test,name = 'Apply_Test/'),
    path('Apply_Vaccine/',views.Apply_Vaccine,name = 'Apply_Vaccine/'),
    path('user_status/',views.user_status,name = 'user_status/'),
]


#!/usr/bin/python

from __future__ import print_function
import time
import optparse
import sys
import subprocess
import os
import socket
import itertools
try:
	from netaddr import IPNetwork
except:
	print("\033[1m\033[91m[!]\033[0m Error: netaddr package not found. 'pip install netaddr' to use CIDR notation")

def main():

	## Define functions

	def print_err(desc):
		print("\033[1m\033[91m[!]\033[0m Error: %s" % desc)
		print("Use '-h' option for help menu")
		sys.exit()

	def check_requirements():
		try:
			FNULL = open(os.devnull, 'w')
			subprocess.call(["fping", "-v"], stdout=FNULL, stderr=subprocess.STDOUT)
		except OSError as e:
			if e.errno == os.errno.ENOENT:
				print_err("fping is not installed. Please install fping and run again. Exiting...")
			else:
				raise
				sys.exit()

	def is_int(rawvar):
		try:
			int(rawvar)
			return True
		except ValueError:
			return False

	def validate_ip(ip):
		a = ip.split('.')
		if len(a) != 4:
			return False
		for x in a:
			if not x.isdigit():
				return False
			i = int(x)
			if i < 0 or i > 255:
				return False
		return True

	def createiplist_cidr(ipstring):
		iplist = []
		try:
			for ip in IPNetwork(ipstring):
				iplist.append(ip)
		except:
			print_err("invalid CIDR notation")
		return iplist

	def createiplist_dash(input_string):
		iplist = []
		try:
			octets = input_string.split('.')
			chunks = [map(int, octet.split('-')) for octet in octets]
			ranges = [range(c[0], c[1] + 1) if len(c) == 2 else c for c in chunks]

			for address in itertools.product(*ranges):
				iplist.append('.'.join(map(str, address)))
		except:
			print_err("invalid dash notation")
		return iplist

	def createiplist_range(begip, endip):
		ip_list = []

		try:
			start = list(map(int, begip.split(".")))
			end = list(map(int, endip.split(".")))

			if begip == endip:
				if start[3] == 0:
					end[3] = 255

			if end[0] > start[0] or (end[0] == start[0] and end[1] > start[1]) or (end[0] == start[0] and end[1] == start[1] and end[2] > start[2]) or (end[0] == start[0] and end[1] == start[1] and end[2] == start[2] and end[3] >= start[3]):
				temp = start

				ip_list.append(begip)
				while temp != end:
					start[3] += 1
					for i in (3, 2, 1):
						if temp[i] == 256:
							temp[i] = 0
							temp[i-1] += 1
					ip_list.append(".".join(map(str, temp)))

				return ip_list
			else:
				print_err("The second IP must be greater than or equal to the first IP.")
		except:
			print_err("invalid range notation")

	def are_you_sure(numOfHosts):
		valid = {"yes": True, "y": True, "ye": True,
			"no": False, "n": False}

		while True:
			sys.stdout.write("Ping %s hosts? [Y/n] " % numOfHosts)
			choice = raw_input().lower()
			if choice == '':
				return valid["yes"]
			elif choice in valid:
				return valid[choice]
			else:
				sys.stdout.write("Please respond with 'yes' or 'no' "
						"(or 'y' or 'n').\n")

	def resolve(ip):
		try:
			hostname = socket.gethostbyaddr(ip)[0]
			return hostname
		except:
			return ''

	## Get Options

	parser = optparse.OptionParser()

	parser.add_option('-d', '--debug',
			dest="debug",
			default=False,
			action="store_true",
			help='display all pings, failed and successful',
			)
	parser.add_option('-l', '--list',
			dest="ip_file",
			default='',
			help='define a text file of one IP per line to ping',
			)
	parser.add_option('-n', '--hostnames',
			dest="hostnames",
			default=False,
			action="store_true",
			help='Attempt to resolve hostnames for successful pings',
			)
	parser.add_option('-r', '--reverse',
			dest="reverse",
			default=False,
			action="store_true",
			help='display failed pings instead of successful pings',
			)
	parser.add_option('-t', '--timeout',
			dest="timeout",
			default=200,
			help='define a ping timeout in miliseconds (default is 200)',
			)
	parser.add_option('-v', '--verbose',
			dest="verbose",
			default=False,
			action="store_true",
			help='include fping statistics for each ping',
			)
	parser.set_usage("""Usage: pingsweep [options] ip_range

Examples:
  pingsweep 10.0.0.0/24
  pingsweep 10.0.0.0-255
  pingsweep 10.0.0.0 10.0.0.255
		""")

	options, remainder = parser.parse_args()

	## Initialize variables

	verbose = options.verbose
	reverse = options.reverse
	timeout = options.timeout
	if not is_int(timeout):
		print_err("Invalid timeout '%s' - must be an integer" % timeout)
	elif int(timeout) < 50:
		print_err("Invalid timeout '%s' - minimum timeout is 50" % timeout)
	hostnames = options.hostnames
	debug = options.debug
	ip_file = options.ip_file
	begip = "none"
	endip = "none"
	ip_list = []

	## Handle extra arguments (only accepts exactly one or two extra arguments as IP addresses)

	if len(remainder) == 0:
		if ip_file == '':
			print_err("Please define IP range to ping")
		else:
			try:
				with open(ip_file, 'r') as f:
					for line in f:
						line = line.rstrip()
						if not line == "":
							if validate_ip(line):
								ip_list.append(line)
							else:
								print_err("Invalid IP list file format -- IP list file must have one valid IPv4 address per line with no leading or trailing spaces.")
			except:
				print_err("invalid file '%s'" % (ip_file))
	elif len(remainder) == 1:

		ipstring = remainder[0]
		if "/" in ipstring:
			ip_list = createiplist_cidr(ipstring)
		elif "-" in ipstring:
			ip_list = createiplist_dash(ipstring)
		else:
			print_err("invalid IP format")

	elif len(remainder) == 2:

		begip = remainder[0]
		endip = remainder[1]
		ip_list = createiplist_range(begip, endip)

	else:
		print_err("Invalid number of arguments")

	## If hosts list exceeds 256, prompt for confirmation

	if len(ip_list) > 256:
		if not are_you_sure(len(ip_list)):
			sys.exit()

	## Print selected options before starting the scan

	print("Starting ping sweep on %s through %s...\n" % (ip_list[0], ip_list[-1]))

	if verbose:
		print("\033[1m\033[34m[+]\033[0m Verbose option set\n")

	if timeout != 200:
		print("\033[1m\033[34m[+]\033[0m Timeout set to %s milliseconds\n" % (timeout))

	if reverse:
		print("\033[1m\033[34m[+]\033[0m Reverse option set - displaying failed pings\n")

	if hostnames:
		print("\033[1m\033[34m[+]\033[0m Hostnames option set - resolving hosts\n")

	if debug:
		print("\033[1m\033[34m[+]\033[0m Debug option set - displaying all pings\n")

	## Check if fping is installed

	check_requirements()

	## Begin scanning IP addresses by executing fping command on each IP

	print("Scan start: %s\n......" % (time.ctime()))
	success = 0
	for ip in ip_list:
		bash_string = "fping -a -c1 -t%s %s" % (timeout, ip)
		try:
			proc = subprocess.Popen(bash_string.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
			output = proc.communicate()[0].split("\n")[0]
			if debug:
				if "1/1/0" in output:
					success += 1
				print(output)
			else:
				if reverse:
					if "1/0/100" in output:
						if verbose:
							print(output)
						else:
							print(output.split(" ",1)[0])
					else:
						success += 1
				else:
					if "1/1/0" in output:
						success += 1
						if hostnames:
							hostname = resolve(ip)
							if verbose:
								print(output, hostname)
							else:
								print(output.split(" ",1)[0], hostname)
						else:
							if verbose:
								print(output)
							else:
								print(output.split(" ",1)[0])
		except:
			print("\n\033[1m\033[91m[!]\033[0m Exiting...")
			print("Scan stopped at IP %s on %s" % (ip, time.ctime()))
			sys.exit()

	print("......\nSuccessful pings: \033[1m\033[92m%s/%s\033[0m (%s%s)" % (success, len(ip_list), (success * 100 / len(ip_list)), '%'))
	print("Scan finished at: %s" % (time.ctime()))

if __name__ == '__main__':
	main()


import numpy as np
import cv2 as cv
img = cv.imread('coins.jpg', 0)
img = cv.medianBlur(img, 5)
cimg = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
#  get circles of 20-100 pixels in diameter
circles = cv.HoughCircles(
    img, cv.HOUGH_GRADIENT, 1, 65, param1=50, param2=60, minRadius=120, maxRadius=200)

circles = np.uint16(np.around(circles))
for i in circles[0, :]:
    # draw the outer circle
    cv.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
    # draw the center of the circle
    cv.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)
cv.imshow('detected circles', cimg)
cv.waitKey(0)
cv.destroyAllWindows()

#  read the following images from the same folder
#  2, 5,50c, 50old, 10, 1

coin2 = cv.imread('2.png', 0)
coin5 = cv.imread('5.png', 0)
coin50c = cv.imread('50c.png', 0)
coin50old = cv.imread('50old.png', 0)
coin10 = cv.imread('10.png', 0)
coin1 = cv.imread('1.png', 0)

# #  using SIFT to find the most similar coin in the iamge and mark it with is name

sift = cv.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(img, None)
kp2, des2 = sift.detectAndCompute(coin2, None)
kp3, des3 = sift.detectAndCompute(coin5, None)
kp4, des4 = sift.detectAndCompute(coin50c, None)
kp5, des5 = sift.detectAndCompute(coin50old, None)
kp6, des6 = sift.detectAndCompute(coin10, None)
kp7, des7 = sift.detectAndCompute(coin1, None)

#  using FLANN to match the coins
FLANN_INDEX_KDTREE = 5
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=10)
search_params = dict(checks=60)
flann = cv.FlannBasedMatcher(index_params, search_params)
matches2 = flann.knnMatch(des1, des2, k=2)
matches5 = flann.knnMatch(des1, des3, k=2)
matches50c = flann.knnMatch(des1, des4, k=2)
matches50old = flann.knnMatch(des1, des5, k=2)
matches10 = flann.knnMatch(des1, des6, k=2)
matches1 = flann.knnMatch(des1, des7, k=2)

#  store the good matches as per Lowe's ratio test.
good2 = []
good5 = []
good50c = []
good50old = []
good10 = []
good1 = []
for m, n in matches2:
    if m.distance < 0.7 * n.distance:
        good2.append(m)
for m, n in matches5:
    if m.distance < 0.7 * n.distance:
        good5.append(m)
for m, n in matches50c:
    if m.distance < 0.7 * n.distance:
        good50c.append(m)
for m, n in matches50old:
    if m.distance < 0.7 * n.distance:
        good50old.append(m)
for m, n in matches10:
    if m.distance < 0.7 * n.distance:
        good10.append(m)
for m, n in matches1:
    if m.distance < 0.7 * n.distance:
        good1.append(m)

 #  draw the matches  only if the number of matches is greater than 10

img3 = cv.drawMatches(img, kp1, coin2, kp2, good2, None, flags=2)
img4 = cv.drawMatches(img, kp1, coin5, kp3, good5, None, flags=2)
img5 = cv.drawMatches(img, kp1, coin50c, kp4, good50c, None, flags=2)
img6 = cv.drawMatches(img, kp1, coin50old, kp5, good50old, None, flags=2)
img7 = cv.drawMatches(img, kp1, coin10, kp6, good10, None, flags=2)
img8 = cv.drawMatches(img, kp1, coin1, kp7, good1, None, flags=2)

#  show the images
cv.imshow('2', img3)
cv.imshow('5', img4)
cv.imshow('50c', img5)
cv.imshow('50old', img6)
cv.imshow('10', img7)
cv.imshow('1', img8)
cv.waitKey(0)
cv.destroyAllWindows()


import os
import sys
sys.path.insert(0, os.getcwd())

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "price_comparison_site.settings")

import django
django.setup()

from search import two

from django.shortcuts import render
from search.models import Product

import numpy as np
import pandas as pd
from django_pandas.io import read_frame

from transformers import TFBertForMaskedLM
from transformers import AutoTokenizer

from collections import Counter

# Create your views here.
def index(request):
    return render(request, 'search/index.html')

def search(request):
    return render(request, 'search/main.html')

def result(request, q):
    request.q_value = q
    print(request.session.get('query'))
    print(q)
    if request.session.get('query') != q:
        request.session['scraped'] = False
    if request.session.get('scraped') != True:
        Product.objects.all().delete()
        two.coupang(q)
        request.session['scraped'] = True
        request.session['query'] = q
    context = {
        'q': q,
        'page': 1,
        'result': Product.objects.all()[:20],
        'length': len(Product.objects.all()),
    }
    return render(request, 'search/result.html', context)

def result2(request, q, page):
    request.q_value = q
    print(request.session.get('query'))
    print(q)
    if request.session.get('query') != q:
        request.session['scraped'] = False
    if request.session.get('scraped') != True:
        Product.objects.all().delete()
        two.coupang(q)
        request.session['scraped'] = True
        request.session['query'] = q
    try:
        if page > len(Product.objects.all()) / 20:
            raise SyntaxError('')
        context = {
            'q': q,
            'page': page,
            'result': Product.objects.all()[(20*(page-1)):((20*(page-1))+20)],
            'length': len(Product.objects.all()),
        }
    except:
        context = {
            'q': q,
            'page': int(len(Product.objects.all())/20)+1,
            'result': Product.objects.all()[len(Product.objects.all())-20:len(Product.objects.all())],
            'length': len(Product.objects.all()),
        }
    finally:
        return render(request, 'search/result.html', context)

def result3(request, q):
    request.q_value = q

    qs = Product.objects.all()
    df = read_frame(qs)

    try:
        minstar = request.GET.get('minstar')
        if minstar is None:
            minstar = 0
        else:
            minstar = float(minstar)
    except:
        minstar = 0
    finally:
        pass

    try:
        minprice = request.GET.get('minprice')
        if minprice is None:
            minprice = 0
        else:
            minprice = int(minprice)
    except:
        minprice = 0
    finally:
        pass

    try:
        maxprice = request.GET.get('maxprice')
        if maxprice is None:
            maxprice = 2147483647
        else:
            maxprice = int(maxprice)
    except:
        maxprice = 2147483647
    finally:
        pass

    df2 = df.loc[(pd.to_numeric(df['price']) >= int(minprice)) & (pd.to_numeric(df['price']) <= int(maxprice)) & (pd.to_numeric(df['star']) >= float(minstar))]

    detail = request.GET.get('detail')
    if detail:
        model = TFBertForMaskedLM.from_pretrained('klue/bert-base', from_pt=True)
        tokenizer = AutoTokenizer.from_pretrained("klue/bert-base")
        token1 = Counter(tokenizer(detail)['input_ids'])
        similarity = []
        for idx in df2.index:
            token2 = Counter(tokenizer(df2.loc[idx,'product_name'])['input_ids'])
            intersection = sum((token1 & token2).values())
            union = sum((token1 | token2).values())
            similarity.append(intersection / union if union > 0 else 0.0)
        df2['sim'] = similarity
        df2 = df2.sort_values(by='sim',ascending=False)

        print(df2[:20].to_dict(orient='index'))

    context = {
        'q': q,
        'page': 1,
        'result': df2[:20].to_dict(orient='records'),
        'length': len(df2),
    }
    return render(request, 'search/detail.html', context)


import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    """Emulates and creates an alien ship"""

    def __init__(self, screen, settings):
        """Initialize the alien and set its starting position"""
        super().__init__()
        self.screen = screen
        self.settings = settings

        # Loads the alien image, scales it, then set its rect attribute
        self.image = pygame.image.load('images/alien_ship_grey.png')
        self.image = pygame.transform.scale(self.image, (int(self.settings.width/25), int(self.settings.width/25)))
        self.rect = self.image.get_rect()

        # Start alien ship at top left of screen
        self.rect.x = self.settings.width/10
        self.rect.y = self.settings.height/10

        self.x = float(self.rect.x)

    def check_edges(self):
        """Return True if alien is at edge of screen"""
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True

    def update(self):
        """Updates position of alien"""
        self.x += self.settings.alien_speed_factor * self.settings.fleet_direction
        self.rect.x = self.x

    def blitme(self):
        """Draws the alien sprite"""
        self.screen.blit(self.image, self.rect)