import pandas as pd
import numpy as np
import logging
from utils import dataframe_cleanup, get_orig_col_names, get_variation_count

# CONSTANT VALUES
## These values are manually selected after some analysis
## for provided measuremnet data.
# === FETS-IV ===
NUM_DP_PER_TEMP_FET_03V3 = 25
NUM_DP_PER_TEMP_FET_06V0_NVT = 12
NUM_DP_PER_TEMP_FET_06V0 = 20
NUM_COLS_MEAS_VBS = 7
NUM_COLS_MEAS_VGS = 8

def parse_dp_id_vgs_vbs(sub_df, dev_name):
    """
    Function to parse measurement data for Ids Vs Vgs with Vbs sweep to be used in simulation.

    Parameters
    ----------
    sub_df : pd.DataFrame
        DataFrame that holds sub measurement information per each variation.
    dev_name : str
        Device we want to extract data for.
    Returns
    ----------
    df_id_vgs_vbs : pd.DataFrame
        DataFrame that holds all measurement points for Id Vs Vds with Vbs sweep
    """

    ## Id Vs Vgs [Vbs sweep]
    df_id_vgs_vbs = sub_df.iloc[:, :NUM_COLS_MEAS_VBS]
    vds_df_id_vgs_vbs = float(df_id_vgs_vbs.columns[0].split("/")[0].split("=")[1])
    df_id_vgs_vbs.drop(columns=df_id_vgs_vbs.columns[0], inplace=True)

    # Get vgs sweep values
    vgs_col_name = "vgs " if "nfet" in dev_name else "-vgs "
    # Get Vgs step value
    vgs_step_val = abs(df_id_vgs_vbs[vgs_col_name][1] - df_id_vgs_vbs[vgs_col_name][0])

    # Stacking all vbs sweeps in one column
    df_id_vgs_vbs = (
        df_id_vgs_vbs.set_index([vgs_col_name])
        .stack()
        .reset_index(name="id")
        .rename(columns={"level_1": "vbs"})
        .rename(columns={vgs_col_name: "vgs"})
    )

    # Multiplying vgs by -1 for pfet devices to match provided data
    df_id_vgs_vbs["vgs"] = df_id_vgs_vbs["vgs"].apply(lambda x: x * -1) if "pfet" in dev_name else df_id_vgs_vbs["vgs"]

    # Get min/max values of vgs sweep
    vgs_min_val = df_id_vgs_vbs["vgs"].min()
    vgs_max_val = df_id_vgs_vbs["vgs"].max()

    # Adding columns for all voltage sweeps and output
    df_id_vgs_vbs["vbs"] = df_id_vgs_vbs["vbs"].apply(lambda x: x.split("=")[1])
    df_id_vgs_vbs["vbs"] = df_id_vgs_vbs["vbs"].astype(float)
    df_id_vgs_vbs["vds"] = vds_df_id_vgs_vbs
    df_id_vgs_vbs["rds"] = np.nan
    df_id_vgs_vbs["const_var"] = "vds"
    df_id_vgs_vbs["const_var_val"] = vds_df_id_vgs_vbs
    df_id_vgs_vbs["out_col"] = "id"

    # Get vgs sweep values
    vbs_min_val = df_id_vgs_vbs["vbs"].min()
    vbs_max_val = df_id_vgs_vbs["vbs"].max()
    vbs_step_val = abs(df_id_vgs_vbs["vbs"][1] - df_id_vgs_vbs["vbs"][0])

    # Adding sweeps used per each variation
    df_id_vgs_vbs[
        "sweeps"
    ] = f"vgs {vgs_min_val} {vgs_max_val} {vgs_step_val} vbs {vbs_min_val} {vbs_max_val} {vbs_step_val}"

    return df_id_vgs_vbs

def parse_dp_id_vds_vgs(sub_df, dev_name):
    """
    Function to parse measurement data for Ids Vs Vds with Vgs sweep to be used in simulation.

    Parameters
    ----------
    sub_df : pd.DataFrame
        DataFrame that holds sub measurement information per each variation.
    dev_name : str
        Device we want to extract data for.

    Returns
    ----------
    df_id_vds_vgs : pd.DataFrame
        DataFrame that holds all measurement points for Id Vs Vds with Vgs sweep
    """

    ## Id Vs Vds [Vgs sweep]
    df_id_vds_vgs = sub_df.iloc[
        :, NUM_COLS_MEAS_VBS : NUM_COLS_MEAS_VBS + NUM_COLS_MEAS_VGS
    ]
    vbs_df_id_vds_vgs = float(df_id_vds_vgs.columns[0].split("/")[0].split("=")[1])
    df_id_vds_vgs.drop(columns=df_id_vds_vgs.columns[0], inplace=True)

    # Get vds sweep values
    vgs_col_name = "vds (V)" if "nfet" in dev_name else "-vds (V)"

    # Get vds step vaule used in sweep
    vds_step_val = abs(df_id_vds_vgs[vgs_col_name][1] - df_id_vds_vgs[vgs_col_name][0])

    # Stacking all vgs sweeps in one column
    df_id_vds_vgs = (
        df_id_vds_vgs.set_index([vgs_col_name])
        .stack()
        .reset_index(name="id")
        .rename(columns={"level_1": "vgs"})
        .rename(columns={vgs_col_name: "vds"})
    )

    # Multiplying vds by -1 for pfet devices to match provided data
    df_id_vds_vgs["vds"] = df_id_vds_vgs["vds"].apply(lambda x: x * -1) if "pfet" in dev_name else df_id_vds_vgs["vds"]

    # Get vds min/max values used in sweep
    vds_min_val = df_id_vds_vgs["vds"].min()
    vds_max_val = df_id_vds_vgs["vds"].max()

    # Adding columns for all voltage sweeps and output
    df_id_vds_vgs["vgs"] = df_id_vds_vgs["vgs"].apply(lambda x: x.split("=")[1])
    df_id_vds_vgs["vgs"] = df_id_vds_vgs["vgs"].astype(float)
    df_id_vds_vgs["vbs"] = vbs_df_id_vds_vgs
    df_id_vds_vgs["rds"] = np.nan
    df_id_vds_vgs["const_var"] = "vbs"
    df_id_vds_vgs["const_var_val"] = vbs_df_id_vds_vgs
    df_id_vds_vgs["out_col"] = "id"

    # Get vgs sweep values
    vgs_min_val = df_id_vds_vgs["vgs"].min()
    vgs_max_val = df_id_vds_vgs["vgs"].max()
    vgs_step_val = abs(df_id_vds_vgs["vgs"][1] - df_id_vds_vgs["vgs"][0])

    # Adding sweeps used per each variation
    df_id_vds_vgs[
        "sweeps"
    ] = f"vds {vds_min_val} {vds_max_val} {vds_step_val} vgs {vgs_min_val} {vgs_max_val} {vgs_step_val}"

    return df_id_vds_vgs

def parse_dp_rds_vds_vgs(sub_df, dev_name):
    """
    Function to parse measurement data for Rds Vs Vds with Vgs sweep to be used in simulation.

    Parameters
    ----------
    sub_df : pd.DataFrame
        DataFrame that holds sub measurement information per each variation.
    dev_name : str
        Device we want to extract data for.
    Returns
    ----------
    df_rds_vds_vgs : pd.DataFrame
        DataFrame that holds all measurement points for Rds Vs Vds with Vgs sweep
    """

    ## Rds Vs Vds [Vgs sweep]
    df_rds_vds_vgs = sub_df.iloc[:, -NUM_COLS_MEAS_VGS:]

    vbs_df_rds_vds_vgs = float(df_rds_vds_vgs.columns[0].split("/")[0].split("=")[1])
    df_rds_vds_vgs.drop(columns=df_rds_vds_vgs.columns[0], inplace=True)

    # Get vds sweep values
    vgs_col_name = "vds (V).1" if "nfet" in dev_name else "-vds (V).1"

    vds_step_val = abs(df_rds_vds_vgs[vgs_col_name][1] - df_rds_vds_vgs[vgs_col_name][0])

    # Stacking all vgs sweeps in one column
    df_rds_vds_vgs = (
        df_rds_vds_vgs.set_index([vgs_col_name])
        .stack()
        .reset_index(name="rds")
        .rename(columns={"level_1": "vgs"})
        .rename(columns={vgs_col_name: "vds"})
    )

    # Multiplying vds by -1 for pfet devices to match provided data
    df_rds_vds_vgs["vds"] = df_rds_vds_vgs["vds"].apply(lambda x: x * -1) if "pfet" in dev_name else df_rds_vds_vgs["vds"]

    # Get min/max values for vds sweeps
    vds_min_val = df_rds_vds_vgs["vds"].min()
    vds_max_val = df_rds_vds_vgs["vds"].max()

    # Adding columns for all voltage sweeps and output
    df_rds_vds_vgs["vgs"] = df_rds_vds_vgs["vgs"].apply(
        lambda x: ".".join(x.split("=")[1].split(".")[:-1])
    )
    df_rds_vds_vgs["vgs"] = df_rds_vds_vgs["vgs"].astype(float)
    df_rds_vds_vgs["vbs"] = vbs_df_rds_vds_vgs
    df_rds_vds_vgs["id"] = np.nan
    df_rds_vds_vgs["const_var"] = "vbs"
    df_rds_vds_vgs["const_var_val"] = vbs_df_rds_vds_vgs
    df_rds_vds_vgs["out_col"] = "rds"

    # Get vgs sweep values
    vgs_min_val = df_rds_vds_vgs["vgs"].min()
    vgs_max_val = df_rds_vds_vgs["vgs"].max()
    vgs_step_val = abs(df_rds_vds_vgs["vgs"][1] - df_rds_vds_vgs["vgs"][0])

    df_rds_vds_vgs[
        "sweeps"
    ] = f"vds {vds_min_val} {vds_max_val} {vds_step_val} vgs {vgs_min_val} {vgs_max_val} {vgs_step_val}"

    return df_rds_vds_vgs

def generate_fets_sweeps(all_dfs, dev_name):
    """
    Function to generate full data frame of measured data with all variations.

    Parameters
    ----------
    all_dfs : pd.DataFrame
        DataFrame that holds all the measurement data after extraction.
    dev_name : str
        Device we want to extract data for.
    Returns
    -------
        None
    """

    # Generate csv file contains simulation sweeps
    ## Re-arranging columns of sweep data file
    sweeps_df_cols = [
        "W (um)",
        "L (um)",
        "corner",
        "temp",
        "const_var",
        "const_var_val",
        "sweeps",
        "out_col",
    ]
    sweeps_df = all_dfs.reindex(columns=sweeps_df_cols)
    sweeps_df.drop_duplicates(inplace=True)

    # Splitting sweeps depends one selected measured output
    sweeps_df_id = sweeps_df[sweeps_df['out_col'] == 'id']
    sweeps_df_rds = sweeps_df[sweeps_df['out_col'] == 'rds']
    # Drop out_col columns as it will be redundant
    sweeps_df_id = sweeps_df_id.drop('out_col', axis=1)
    sweeps_df_rds = sweeps_df_rds.drop('out_col', axis=1)
    # Saving sweep data files to csv
    sweeps_df_id.to_csv(f"{dev_name}_sweeps_id.csv", index=False)
    sweeps_df_rds.to_csv(f"{dev_name}_sweeps_rds.csv", index=False)
    logging.info(f"Sweep csv file for {dev_name}: {sweeps_df}")
    logging.info(f"Number of sweep points for {dev_name}: {len(sweeps_df)}")
    logging.info(f"Sweep csv file for {dev_name} at : {sweeps_df}_sweeps.csv")

def parse_fet_iv_sweeps(sub_df, dev_name):
    """
    Function to parse measurement data to be used in simulation.

    Parameters
    ----------
    sub_df : pd.DataFrame
        DataFrame that holds sub measurement information per each variation.
    dev_name : str
        Device we want to extract data for.
    Returns
    -------
    df_dp_sweeps : pd.DataFrame
        DataFrame that holds all extracted points for all sweeps.
    """

    ## Id Vs Vgs [Vbs sweep]
    df_id_vgs_vbs = parse_dp_id_vgs_vbs(sub_df, dev_name)

    ## Id Vs Vds [Vgs sweep]
    df_id_vds_vgs = parse_dp_id_vds_vgs(sub_df, dev_name)

    ## Rds Vs Vds [Vgs sweep]
    df_rds_vds_vgs = parse_dp_rds_vds_vgs(sub_df, dev_name)

    df_dp_sweeps = pd.concat([df_id_vgs_vbs, df_id_vds_vgs, df_rds_vds_vgs])

    return df_dp_sweeps

def generate_fets_iv_variations(df, dp_df, dev_name, variations_count):
    """
    Function to generate full data frame of measured data with all variations.

    Parameters
    ----------
    df : pd.DataFrame
        DataFrame that holds all the measurement information for selected fet.
    dp_df : pd.DataFrame
        DataFrame that holds all data points for all varaitions.
    dev_name : str
        Device we want to extract data for.
    variations_count : float
        Number of variations per each selected device
    Returns
    -------
        None
    """

    # Get number of columns that holds measurement data for each variation
    # Get columns names that holds data for each variation
    num_data_col_per_dp, orig_col_names = get_orig_col_names(df, variations_count)

    # Generating all data points per each variation and combining all data in one DF
    all_dfs = []
    for i in range(0, len(df.columns), num_data_col_per_dp):
        sub_df = df[df.columns[i : i + num_data_col_per_dp]].copy()
        sub_df.columns = orig_col_names
        parsed_df = parse_fet_iv_sweeps(sub_df, dev_name)
        for c in dp_df.columns:
            parsed_df[c] = dp_df.loc[len(all_dfs), c]
        all_dfs.append(parsed_df)

    all_dfs = pd.concat(all_dfs)
    all_dfs.drop_duplicates(inplace=True)
    all_dfs.rename(columns={"corners": "corner"}, inplace=True)

    # Generate data file that holds all sweep values per each variation to be used in simulation
    generate_fets_sweeps(all_dfs, dev_name)

    # Generate final data file that holds all data points to be used in comparision
    ## Re-arranging columns of final data file
    all_dfs_cols = [
        "W (um)",
        "L (um)",
        "corner",
        "temp",
        "vds",
        "vgs",
        "vbs",
        "id",
        "rds",
    ]
    all_dfs = all_dfs.reindex(columns=all_dfs_cols)

    logging.info(f"Length of all data points {len(all_dfs)}")

    # Making sure that we don't have any nan values except in measured output [Id or Rds]
    for c in all_dfs.columns:
        logging.info(f"col: {c} has nan: {all_dfs[c].isna().any()}")

    return all_dfs

def fet_iv_meas_extraction(df: pd.DataFrame, dev_name: str):
    """
    Function to extract measurement data for Fets.

    Parameters
    ----------
    df : pd.DataFrame
        DataFrame that holds all the measurement information for selected fet.
    dev_name : str
        Device we want to extract data for.
    Returns
    -------
        None
    """

    # Drop any unwanted columns
    id_cols = [c for c in df.columns if "Id (A)" in c]
    rd_cols = [c for c in df.columns if "Rds" in c]
    unwanted_cols = ["Unnamed: 2", "Ids"] + id_cols + rd_cols

    # Cleanup dataframe from unwanted columns we don't use
    df = dataframe_cleanup(df, unwanted_cols)

    # Get num of variations for fets depending on length values in data
    variations_count = get_variation_count(df, "L (um)")

    # For Fets 03v3, There are 75 variations = 25*3 [For each temp] and all variations are extracted at tt corner
    ## For Fets 06v0, There are 60 variations = 20*3 [For each temp] and all variations are extracted at tt corner
    ## For Fets 06v0_nvt, There are 36 variations = 12*3 [For each temp] and all variations are extracted at tt corner
    ## Please note that the temp variation wasn't included in dataset so we will have to add that new column
    if "03v3" in dev_name:
        NUM_DP_PER_TEMP = NUM_DP_PER_TEMP_FET_03V3
    elif "06v0_nvt" in dev_name:
        NUM_DP_PER_TEMP = NUM_DP_PER_TEMP_FET_06V0_NVT
    else:
        NUM_DP_PER_TEMP = NUM_DP_PER_TEMP_FET_06V0

    all_temp = (
        [25] * NUM_DP_PER_TEMP + [-40] * NUM_DP_PER_TEMP + [125] * NUM_DP_PER_TEMP
    )

    # Define new data frame that holds all variations
    dp_cols = ["W (um)", "L (um)", "corners"]
    dp_df = df[dp_cols].iloc[:variations_count].copy()
    dp_df["temp"] = all_temp
    df.drop(columns=dp_cols, inplace=True)

    # Generate the full dataframe that holds all meas data in a clean format
    all_dfs = generate_fets_iv_variations(df, dp_df, dev_name, variations_count)

    # Writing final dataframe that holds all clean data
    all_dfs.drop_duplicates(inplace=True)

    # Splitting final df depends on measured output
    all_dfs_id = all_dfs.loc[all_dfs['id'].notnull()]
    all_dfs_rds = all_dfs.loc[all_dfs['rds'].notnull()]
    # Drop rds/id columns as it will be redundant
    all_dfs_id = all_dfs_id.drop('rds', axis=1)
    all_dfs_rds = all_dfs_rds.drop('id', axis=1)
    # Saving full extracted measured data to csv
    all_dfs_id.to_csv(f"{dev_name}_meas_id.csv", index=False)
    all_dfs_rds.to_csv(f"{dev_name}_meas_rds.csv", index=False)
    logging.info(f"Full extracted measurement data for {dev_name}:\n {all_dfs}")
    logging.info(
        f"Full extracted measurement data for {dev_name} at: {dev_name}_meas.csv"
    )


import pytz
from fcm_django.models import FCMDevice

import api.apis as api_app
from cobalt.settings import GLOBAL_ORG, TIME_ZONE
from notifications.models import RealtimeNotification
from notifications.views.core import send_cobalt_bulk_notifications

TZ = pytz.timezone(TIME_ZONE)

def fcm_token_get_user_v1(fcm_token):
    """Helper function to validate an FCM token

    Args:
        fcm_token: str. FCM token usually passed from mobile client. Not trusted.

    Returns:
        user(User): either a valid user associated with this token or False
        return_error_code (int or None): if user is invalid this will be the return code
        return_error_msg_structure (struct or None): if user is invalid this will be the return structure (StatusResponseV1)

    """

    # Test for empty string
    if fcm_token == "":
        return (
            False,
            403,
            {
                "status": api_app.APIStatus.ACCESS_DENIED,
                "message": "Token is invalid",
            },
        )

    fcm_token_object = FCMDevice.objects.filter(registration_id=fcm_token).first()

    if fcm_token_object:
        return fcm_token_object.user, None, None

    return (
        False,
        403,
        {
            "status": api_app.APIStatus.ACCESS_DENIED,
            "message": "Token is invalid",
        },
    )

def notifications_api_file_upload_v1(request, file, sender_identification=None):
    """API call to upload a file and send SMS messages"""

    from api.apis import APIStatus

    data = []
    invalid_lines = []
    lines_in_file = 0

    for line in file.readlines():
        lines_in_file += 1
        line = line.decode("utf-8").strip()
        try:
            number, msg = line.split("\t")
            number = int(number)
            if isinstance(number, int):
                if len(msg.strip()) > 0:
                    data.append((number, msg.replace("<NL>", "\n")))
                else:
                    invalid_lines.append(
                        f"Line {lines_in_file}. No message found. : {line}"
                    )
            else:
                invalid_lines.append(
                    f"Line {lines_in_file}. No {GLOBAL_ORG} number found. : {line}"
                )
        except Exception as exc:
            if "too many values to unpack" in exc.__str__():
                invalid_lines.append(
                    f"Line {lines_in_file}. Too many tab characters in row. : {line}"
                )
            elif "not enough values to unpack" in exc.__str__():
                invalid_lines.append(
                    f"Line {lines_in_file}. No tab character found in row. : {line}"
                )
            elif "invalid literal for int" in exc.__str__():
                invalid_lines.append(
                    f"Line {lines_in_file}. Invalid {GLOBAL_ORG} number. : {line}"
                )
            else:
                invalid_lines.append(f"Line {lines_in_file}. Invalid row {exc}: {line}")

    (
        sent_users,
        unregistered_users,
        uncontactable_users,
    ) = send_cobalt_bulk_notifications(
        msg_list=data,
        admin=request.auth,
        description=file.name,
        invalid_lines=invalid_lines,
        total_file_rows=lines_in_file,
        sender_identification=sender_identification,
    )

    # If we sent anything, we were successful
    status = APIStatus.SUCCESS if len(sent_users) > 0 else APIStatus.FAILURE

    return {
        "status": status,
        "sender": request.auth.__str__(),
        "filename": file.name,
        "counts": {
            "total_lines_in_file": lines_in_file,
            "valid_lines_in_file": len(data),
            "invalid_lines_in_file": lines_in_file - len(data),
            "registered_users_in_file": len(data) - len(unregistered_users),
            "registered_contactable_users_in_file": len(data)
            - len(unregistered_users)
            - len(uncontactable_users),
            "sent": len(sent_users),
        },
        "errors": {
            "invalid_lines": invalid_lines,
            "unregistered_users": unregistered_users,
            "uncontactable_users": uncontactable_users,
            "sent_users": sent_users,
        },
    }

def _notifications_api_common_messages_for_user_v1(messages):
    """Common code to handle returning messages"""

    if not messages:
        return 404, {"status": api_app.APIStatus.FAILURE, "message": "No data found"}

    # return messages as list
    return_messages = []

    # mark messages as read now
    for message in messages:
        created_datetime = message.created_time.astimezone(TZ).strftime(
            "%a %d-%b-%Y %-I:%M"
        )
        # Make am/pm lowercase
        created_datetime += message.created_time.astimezone(TZ).strftime("%p").lower()
        item = api_app.UnreadMessageV1(
            id=message.id, message=message.msg, created_datetime=created_datetime
        )
        return_messages.append(item)
        message.has_been_read = True
        message.save()

    return 200, {
        "status": api_app.APIStatus.SUCCESS,
        "un_read_messages": return_messages,
    }

def notifications_api_unread_messages_for_user_v1(fcm_token):
    """Send any unread notifications (FCM) for a user"""

    user, error_code, error_struct = fcm_token_get_user_v1(fcm_token)

    if not user:
        return error_code, error_struct

    messages = (
        RealtimeNotification.objects.filter(has_been_read=False)
        .filter(member=user)
        .order_by("-pk")
    )

    return _notifications_api_common_messages_for_user_v1(messages)

def notifications_api_latest_messages_for_user_v1(fcm_token):
    """Send latest notifications (FCM) for a user regardless if read or not"""

    user, error_code, error_struct = fcm_token_get_user_v1(fcm_token)

    if not user:
        return error_code, error_struct

    messages = RealtimeNotification.objects.filter(member=user).order_by("-pk")[:50]

    return _notifications_api_common_messages_for_user_v1(messages)

def notifications_delete_message_for_user_v1(data):
    """Delete a single message"""

    user, error_code, error_struct = fcm_token_get_user_v1(data.fcm_token)

    if not user:
        return error_code, error_struct

    # Get message
    msg = RealtimeNotification.objects.filter(pk=data.message_id).first()

    if not msg:
        return 404, {
            "status": api_app.APIStatus.FAILURE,
            "message": "No match found",
        }

    if msg.member != user:
        return 403, {
            "status": api_app.APIStatus.ACCESS_DENIED,
            "message": "Message does not belong to this user",
        }

    # TODO: Add a status and keep the message but exclude from other queries
    msg.delete()

    return 200, {
        "status": api_app.APIStatus.SUCCESS,
        "message": "Message deleted",
    }

def notifications_delete_all_messages_for_user_v1(data):
    """Delete all messages for a user"""

    user, error_code, error_struct = fcm_token_get_user_v1(data.fcm_token)

    if not user:
        return error_code, error_struct

    # Get messages
    msgs = RealtimeNotification.objects.filter(member=user)

    if not msgs:
        return 404, {
            "status": api_app.APIStatus.FAILURE,
            "message": "No matches found",
        }

    # TODO: Add a status and keep the messages but exclude from other queries
    msgs.delete()

    return 200, {
        "status": api_app.APIStatus.SUCCESS,
        "message": "Message(s) deleted",
    }


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

# functionality: perform HOG/SVM testing over a specified dataset and compute the
# resulting prediction/clasification error over that same dataset, using
# pre-saved the SVM model trained on HOG feature descriptors

# This version: (c) 2018 Toby Breckon, Dept. Computer Science, Durham University, UK
# License: MIT License

# Minor portions: based on fork from https://github.com/nextgensparx/PyBOW

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

import numpy as np
import cv2
import params
import sys
import os
sys.path.append(os.path.abspath("./"))
import utils

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

def main():

    # load up the SVM stored from prior training

    try:
        svm = cv2.ml.SVM_load(params.HOG_SVM_PATH_SAVED)
    except:
        print("Missing files  SVM")
        print("-- have you performed training to produce this file ?")
        exit()

    # load ** testing ** data sets in the same class order as training
    # (here we perform patch sampling only from the centre of the +ve
    # class and only a single sample is taken
    # hence [0,0] sample sizes and [False,True] centre weighting flags)

    print("Loading test data as a batch ...")

    paths = [params.DATA_testing_path_neg, params.DATA_testing_path_pos]
    use_centre_weighting = [False, True]
    class_names = params.DATA_CLASS_NAMES
    imgs_data = utils.load_images(
        paths, class_names, [0, 0], use_centre_weighting)

    print("Computing HOG descriptors...")  # for each testing image
    start = cv2.getTickCount()
    [img_data.compute_hog_descriptor() for img_data in imgs_data]
    utils.print_duration(start)

    # get the example/sample HOG descriptors and class labels

    samples, class_labels = utils.get_hog_descriptors(
        imgs_data), utils.get_class_labels(imgs_data)

    # perform batch SVM classification over the whole set

    print("Performing batch SVM classification over all data  ...")

    results = svm.predict(samples)
    output = results[1].ravel()

    # compute and report the error over the whole set

    error = ((np.absolute(class_labels.ravel() - output).sum()) /
             float(output.shape[0]))
    print("Successfully trained SVM with {}% testing set error".format(
        round(error * 100, 2)))
    print("-- meaining the SVM got {}% of the testing examples correct!".format(round((1.0 - error) * 100, 2)))

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

if __name__ == "__main__":
    main()

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


from django.conf import settings
from django.contrib.sites.models import Site
from django.core.mail import EmailMultiAlternatives
from django.template.loader import get_template

def send_notification(template_name, subject, receivers, **kwargs):
    domain = Site.objects.get_current()
    context = kwargs.get('context', {})
    context.update({
        'domain': domain,
    })
    template = get_template(template_name)
    message = template.render(context)
    msg = EmailMultiAlternatives(subject, from_email=settings.EMAIL_HOST_USER, to=receivers)
    msg.attach_alternative(message, "text/html")
    msg.send()


import networkx as nx
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt

################################################################################################################
'''Function that creates a network with edge and node attributes for a given year'''

def make_year_network(year):
    # enter year in YYYY string format

    node_attr = pd.read_csv('../data/Attributes.csv')
    # print(water_rights.WDID.to_list())
    path = 'network_csv_files/priorityWdid/v2_network_'
    data = pd.read_csv(path + year + '.csv')

    G = nx.from_pandas_edgelist(df=data, source='priorityWdid', target='analysisWdid', edge_attr = 'sumWtdCount',
                                create_using=nx.DiGraph())
    # add latitude for each node
    lat_dict = node_attr[['wdid', 'latitude']].set_index('wdid')['latitude'].to_dict()
    nx.set_node_attributes(G, name = 'latitude', values = lat_dict)

    # add longitude for each node
    long_dict = node_attr[['wdid', 'longitude']].set_index('wdid')['longitude'].to_dict()
    nx.set_node_attributes(G, name = 'longitude', values = long_dict)

    # add net absolute for each node
    vol_dict = node_attr[['wdid', 'sum_netAbs']].set_index('wdid')['sum_netAbs'].to_dict()
    nx.set_node_attributes(G, name='netAbs', values=vol_dict)

    # add label for each node
    label_dict = node_attr[['wdid', 'structureName']].set_index('wdid')['structureName'].to_dict()
    nx.set_node_attributes(G, name='name', values=label_dict)

    return G

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

'''Plot network graph'''

def plot_network_graph(G, year):
    # creates gridspec plot for a given network G
    fig = plt.figure(figsize=(18, 12))
    gspec = GridSpec(nrows=6, ncols=9)
    fig.suptitle(year, fontsize=24, fontweight='bold')
    plt.rcParams.update({'font.size': 12})

    # map extent
    extent = [-109.125, -105.625, 38.875, 40.50]
    # background map tiles
    tiles = cimgt.Stamen('terrain-background')
    # MosartWM gridcells
    xlist = np.linspace(-109.125, -105.625, 29)
    ylist = np.linspace(38.875, 40.50, 17)
    X, Y = np.meshgrid(xlist, ylist)
    Xgrid = np.arange(128, 156)
    Ygrid = np.arange(112, 128)
    Z = np.ones([len(Ygrid), len(Xgrid)])
    # Basin shape
    shape_feature = ShapelyFeature(Reader('../data/Water_Districts.shp').geometries(),
                                   ccrs.PlateCarree(), edgecolor='black', facecolor='None')
    # Stream lines
    flow_feature = ShapelyFeature(Reader('../data/UCRBstreams.shp').geometries(),
                                  ccrs.PlateCarree(), edgecolor='royalblue', facecolor='None', alpha=0.5, zorder=1)

    # 1. SUBPLOT OF NETWORK MAP
    # the first subplot will span 6 rows and 4 columns, top left
    crs = ccrs.PlateCarree()
    ax0 = fig.add_subplot(gspec[:, :], projection=crs)

    # Set map extent
    ax0.set_extent([-109.125, -105.625, 38.875, 40.50])
    # Draw background tiles
    ax0.add_image(tiles, 9)
    # Draw basin
    ax0.add_feature(shape_feature, facecolor='#a1a384', alpha=0.5)
    # Draw streams
    ax0.add_feature(flow_feature, alpha=0.7, linewidth=1.5, zorder=1)
    # Draw grid
    # ax0.pcolor(X, Y, Z, facecolor='none', edgecolor='grey', alpha=0.1, linewidth=0.5, transform=ccrs.PlateCarree())

    # Get latitude and longitude attributes for each node
    latitude = nx.get_node_attributes(G, 'latitude')
    longitude = nx.get_node_attributes(G, 'longitude')
    ds = [longitude, latitude]
    pos = {}
    for k in latitude.iterkeys():
        pos[k] = tuple(d[k] for d in ds)
    print(pos)

    Gcc = G

    # Color nodes by out degree
    degs = Gcc.out_degree() # Dict with Node ID, Degree
    nod = Gcc.nodes()
    color = np.asarray([degs[n] for n in nod])
    # print(sorted(color, reverse=True))

    # Size nodes by net absolute volume log-scaled and set size of nodes with out_degree = 0 to 0
    net_abs = nx.get_node_attributes(Gcc, 'netAbs')
    sizes = [np.log10(net_abs[i])*40 if net_abs[i] > 0 and Gcc.out_degree(i) > 0 else 0 for i in Gcc.nodes]

    # Size edge widths by sumWtdCount
    count = nx.get_edge_attributes(Gcc, 'sumWtdCount').values()
    print(count)
    count = [c/200 + 0.01 for c in count]

    # Add labels only for important users (nodes with out_degree > 20)

    labels = {i: name for i, name in list(nx.get_node_attributes(Gcc, 'name').items()) if degs[i] >= 1}

    # Add nodes with out_degree = 0 colored in white
    sizes2 = [0 if (Gcc.out_degree(node)) > 0 else np.log10(net_abs[node])*20 for node in nod]
    nx.draw_networkx_nodes(Gcc, ax = ax0, pos=pos,node_color='white',node_size=sizes2, zorder=40, alpha=0.6)

    # Draw network
    nx.draw_networkx(Gcc, ax = ax0, pos=pos, edge_color='black', alpha=0.9, arrows=True,
                     with_labels=True, node_color = color, cmap=plt.cm.plasma, vmin=1, vmax=2000,
                     node_size=sizes, labels=labels, width = count, font_size=14, font_weight='bold', zorder=50)
    sm = plt.cm.ScalarMappable(cmap=plt.cm.plasma, norm=plt.Normalize(vmin=1, vmax=2000))
    sm._A = []
    cb = plt.colorbar(sm, ax=ax0, orientation='horizontal')
    cb.set_label(label='Out Degree', size=16)

    plt.tight_layout(pad=5)
    plt.savefig( 'by_seniority/' + year  + '.png', dpi=300)

    return

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

users = pd.read_csv('../data/CDSS_WaterRights.csv')
print(users.columns)

N = 200

# select top 200 users by decree (net absolute)
users_decree = users.sort_values('Net Absolute')
users_decree = users_decree.head(n=N)['WDID'].tolist()
print(users_decree[:10])

# select top 200 users by seniority
users_seniority = users.sort_values('Priority Admin No')
users_seniority = users_seniority.head(n=N)['WDID'].tolist()
print(users_seniority[:10])

years = [str(yr) for yr in range(2000,2019)]
print(years)

for year in years:
    print(year)
    G = make_year_network(year)
    Gcc = G.subgraph(users_seniority)
    plot_network_graph(Gcc, year)
    print(Gcc.number_of_nodes())


import logging
import sys
from datetime import datetime, date
from logging.handlers import RotatingFileHandler

from PySide6.QtCore import Qt
from PySide6.QtSql import QSqlDatabase, QSqlQueryModel
from PySide6.QtWidgets import QComboBox
from sqlalchemy import create_engine as ce
from sqlalchemy.orm import Session

from logic import configure_file_handler
from logic.config import properties
from logic.model import create_tables, Person, InventoryItem, Base, LendingHistory

db = ce("sqlite:///pyIM.db")

rfh: RotatingFileHandler = configure_file_handler("database")

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(rfh)

logger.info("Logger initialised")

def init_database():
    print("Connecting to database {}".format(db))
    db.connect()

    print("Initializing database")
    create_tables(db)

    print("Connect database to PySide")
    database = QSqlDatabase.addDatabase("QSQLITE")
    database.setDatabaseName("pyIM.db")

    if not database.open():
        print("Unable to open database")
        sys.exit(1)

def find_by_id(identifier: int, entities):
    s = properties.open_session()
    result = s.query(entities).filter_by(id=identifier).first()
    s.close()
    return result

def load_persons(persons):
    with Session(db) as session:
        for p in persons:
            person = Person(
                id=p["id"] + 1,
                firstname=p["firstName"],
                lastname=p["lastName"],
                email=p["email"]
            )
            session.add(person)
        session.commit()

def load_inventory(inventory):
    with Session(db) as session:
        for i in inventory:
            inventory_item = InventoryItem(
                id=i["id"] + 1,
                name=i["name"],
                available=i["available"],
                lending_date=convert_date(i["lendingDate"]),
                lender_id=i["lender"],
                info=i["info"],
                category=i["category"],
                mot_required=i["motRequired"],
                next_mot=convert_date(i["nextMot"])
            )
            session.add(inventory_item)
        session.commit()

def convert_date(date_str: str):
    date_pattern = "%Y-%m-%d"
    if len(date_str) > 0:
        return datetime.strptime(date_str, date_pattern)
    else:
        return None

def configure_query_model(box: QComboBox, query: str):
    model = QSqlQueryModel(box)
    model.setQuery(query)
    model.setHeaderData(0, Qt.Horizontal, "Name")
    box.setModel(model)
    box.setEditable(True)

def persist_item(item: Base):
    s = properties.open_session()
    s.add(item)
    s.commit()
    logger.info("Added new item to database: %s", item)

def delete_item(item: Base):
    s = properties.open_session()
    s.delete(item)
    s.commit()
    logger.info("Removed entry from database: %s", item)

def update_inventory(value_dict: dict):
    s = properties.open_session()
    item_id = value_dict["item_id"]
    item: InventoryItem = s.query(InventoryItem).filter_by(id=item_id).first()
    item.name = value_dict["name"]
    item.category = value_dict["category"]
    item.info = value_dict["info"]
    item.mot_required = value_dict["mot_required"]
    item.next_mot = value_dict["next_mot"]
    item.available = value_dict["available"]

    lender_id = value_dict["lender"]
    item.lender_id = lender_id
    if lender_id:
        check_and_lend(s, lender_id, item)
    s.commit()

def check_and_lend(s: Session, lender_id: int, item: InventoryItem):
    history_record = s.query(LendingHistory).filter(
        LendingHistory.lender_id == lender_id,
        LendingHistory.item_id == item.id,
        LendingHistory.return_date == None
    ).first()
    if not history_record:
        today = date.today()
        history_record = LendingHistory(lending_date=today, item_id=item.id, lender_id=lender_id)
        s.add(history_record)
        item.lending_date = today
        item.available = False

def check_and_return(item_id: int):
    s = properties.open_session()
    history_record = s.query(LendingHistory).filter(
        LendingHistory.item_id == item_id,
        LendingHistory.return_date == None
    ).first()
    if history_record:
        history_record.return_date = date.today()
        item = s.query(InventoryItem).filter(InventoryItem.id == item_id).first()
        item.lending_date = None
        item.lender_id = None
        item.available = True
    s.commit()

def update_person(value_dict: dict):
    s = properties.open_session()
    person: Person = s.query(Person).filter_by(id=value_dict["item_id"]).first()
    person.firstname = value_dict["firstname"]
    person.lastname = value_dict["lastname"]
    person.email = value_dict["email"]
    s.commit()


import unittest
from sdk_test_case import SdkTestCase
from test_project import create_test_project

import flywheel
from flywheel import util

class SessionsTestCases(SdkTestCase):
    def setUp(self):
        self.group_id, self.project_id = create_test_project()

    def tearDown(self):
        self.fw.delete_project(self.project_id)
        self.fw.delete_group(self.group_id)

    def test_sessions(self):
        fw = self.fw

        session_name = self.rand_string()
        session = flywheel.Session(
            label=session_name,
            project=self.project_id,
            info = { 'some-key': 37 },
            subject = flywheel.Subject(
                code = self.rand_string_lower(),
                firstname = self.rand_string(),
                lastname = self.rand_string(),
                sex = 'other',
                age = util.years_to_seconds(56),
                info = { 'some-subject-key': 37 }
            )
        )

        # Add
        session_id = fw.add_session(session)
        self.assertNotEmpty(session_id)

        # Get
        r_session = fw.get_session(session_id)
        self.assertEqual(r_session.id, session_id)
        self.assertEqual(r_session.label, session_name)
        self.assertIn('some-key', r_session.info)
        self.assertEqual(r_session.info['some-key'], 37)
        self.assertTimestampBeforeNow(r_session.created)
        self.assertGreaterEqual(r_session.modified, r_session.created)
        self.assertIsNotNone(r_session.subject)
        self.assertEqual(r_session.subject.firstname, session.subject.firstname)
        self.assertEqual(r_session.age_years, 56)

        # Generic Get is equivalent
        self.assertEqual(fw.get(session_id).to_dict(), r_session.to_dict())

        # Get All
        sessions = fw.get_all_sessions()
        self.assertNotEmpty(sessions)

        self.sanitize_for_collection(r_session)
        self.assertIn(r_session, sessions)

        # Get from parent
        sessions = fw.get_project_sessions(self.project_id)
        self.assertIn(r_session, sessions)

        # Modify
        new_name = self.rand_string()
        session_mod = flywheel.Session(label=new_name)
        fw.modify_session(session_id, session_mod)

        changed_session = fw.get_session(session_id)
        self.assertEqual(changed_session.label, new_name)
        self.assertEqual(changed_session.created, r_session.created)
        self.assertGreater(changed_session.modified, r_session.modified)

        # Notes, Tags
        message = 'This is a note'
        fw.add_session_note(session_id, message)

        tag = 'example-tag'
        fw.add_session_tag(session_id, tag)

        # Replace Info
        fw.replace_session_info(session_id, { 'foo': 3, 'bar': 'qaz' })

        # Set Info
        fw.set_session_info(session_id, { 'foo': 42, 'hello': 'world' })

        # Check
        r_session = fw.get_session(session_id)

        self.assertEqual(len(r_session.notes), 1)
        self.assertEqual(r_session.notes[0].text, message)

        self.assertEqual(len(r_session.tags), 1)
        self.assertEqual(r_session.tags[0], tag)

        self.assertEqual(r_session.info['foo'], 42)
        self.assertEqual(r_session.info['bar'], 'qaz')
        self.assertEqual(r_session.info['hello'], 'world')

        # Delete info fields
        fw.delete_session_info_fields(session_id, ['foo', 'bar'])

        r_session = fw.get_session(session_id)
        self.assertNotIn('foo', r_session.info)
        self.assertNotIn('bar', r_session.info)
        self.assertEqual(r_session.info['hello'], 'world')

        # Delete
        fw.delete_session(session_id)

        sessions = fw.get_all_sessions()
        self.sanitize_for_collection(r_session)
        self.assertNotIn(r_session, sessions)

    def test_session_files(self):
        fw = self.fw

        session = flywheel.Session(label=self.rand_string(), project=self.project_id)
        session_id = fw.add_session(session)

        # Upload a file
        poem = 'The best lack all conviction, while the worst'
        fw.upload_file_to_session(session_id, flywheel.FileSpec('yeats.txt', poem))

        # Check that the file was added to the session
        r_session = fw.get_session(session_id)
        self.assertEqual(len(r_session.files), 1)
        self.assertEqual(r_session.files[0].name, 'yeats.txt')
        self.assertEqual(r_session.files[0].size, 45)
        self.assertEqual(r_session.files[0].mimetype, 'text/plain')

        # Download the file and check content
        self.assertDownloadFileTextEquals(fw.download_file_from_session_as_data, session_id, 'yeats.txt', poem)

        # Test unauthorized download with ticket for the file
        self.assertDownloadFileTextEqualsWithTicket(fw.get_session_download_url, session_id, 'yeats.txt', poem)

        # Test file attributes
        self.assertEqual(r_session.files[0].modality, None)
        self.assertEmpty(r_session.files[0].classification)
        self.assertEqual(r_session.files[0].type, 'text')

        resp = fw.modify_session_file(session_id, 'yeats.txt', flywheel.FileEntry(
            modality='modality',
            type='type'
        ))

        # Check that no jobs were triggered, and attrs were modified
        self.assertEqual(resp.jobs_spawned, 0)

        r_session = fw.get_session(session_id)
        self.assertEqual(r_session.files[0].modality, "modality")
        self.assertEmpty(r_session.files[0].classification)
        self.assertEqual(r_session.files[0].type, 'type')

        # Test classifications
        resp = fw.replace_session_file_classification(session_id, 'yeats.txt', {
            'Custom': ['measurement1', 'measurement2'],
        })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_session = fw.get_session(session_id)
        self.assertEqual(r_session.files[0].classification, {
            'Custom': ['measurement1', 'measurement2']
        });

        resp = fw.modify_session_file_classification(session_id, 'yeats.txt', {
            'add': {
                'Custom': ['HelloWorld'],
            },
            'delete': {
                'Custom': ['measurement2']
            }
        })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_session = fw.get_session(session_id)
        self.assertEqual(r_session.files[0].classification, {
            'Custom': ['measurement1', 'HelloWorld'],
        });

        # Test file info
        self.assertEmpty(r_session.files[0].info)
        fw.replace_session_file_info(session_id, 'yeats.txt', {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4
        })

        fw.set_session_file_info(session_id, 'yeats.txt', {
            'c': 5
        })

        r_session = fw.get_session(session_id)
        self.assertEqual(r_session.files[0].info['a'], 1)
        self.assertEqual(r_session.files[0].info['b'], 2)
        self.assertEqual(r_session.files[0].info['c'], 5)
        self.assertEqual(r_session.files[0].info['d'], 4)

        fw.delete_session_file_info_fields(session_id, 'yeats.txt', ['c', 'd'])
        r_session = fw.get_session(session_id)
        self.assertEqual(r_session.files[0].info['a'], 1)
        self.assertEqual(r_session.files[0].info['b'], 2)
        self.assertNotIn('c', r_session.files[0].info)
        self.assertNotIn('d', r_session.files[0].info)

        fw.replace_session_file_info(session_id, 'yeats.txt', {})
        r_session = fw.get_session(session_id)
        self.assertEmpty(r_session.files[0].info)

        # Delete file
        fw.delete_session_file(session_id, 'yeats.txt')
        r_session = fw.get_session(session_id)
        self.assertEmpty(r_session.files)

        # Delete session
        fw.delete_session(session_id)

    def test_session_errors(self):
        fw = self.fw

        # Try to create session without project id
        try:
            session = flywheel.Session(label=self.rand_string())
            session_id = fw.add_session(session)
            self.fail('Expected ApiException creating invalid session!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 400)

        # Try to get a session that doesn't exist
        try:
            fw.get_session('DOES_NOT_EXIST')
            self.fail('Expected ApiException retrieving invalid session!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 404)

    def test_session_analysis(self):
        fw = self.fw

        session = flywheel.Session(project=self.project_id, label=self.rand_string())

        # Add
        session_id = fw.add_session(session)
        self.assertNotEmpty(session_id)

        poem = 'When a vast image out of Spiritus Mundi'
        fw.upload_file_to_session(session_id, flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(
            id=session_id,
            type='session',
            name='yeats.txt'
        )

        analysis = flywheel.AnalysisInput(label=self.rand_string(), description=self.rand_string(), inputs=[file_ref])

        # Add
        analysis_id = fw.add_session_analysis(session_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the session
        analyses = fw.get_session_analyses(session_id)
        self.assertEqual(len(analyses), 1)

        r_analysis = analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')

    def sanitize_for_collection(self, session, info_exists=True):
        # workaround: all-container endpoints skip some fields, single-container does not. this sets up the equality check
        session.age = None
        session.info = {}
        session.info_exists = info_exists
        session.analyses = None

        session.subject.age = None
        session.subject.sex = None
        session.subject.firstname = None
        session.subject.lastname = None
        session.subject.info = {}
        session.subject.info_exists = info_exists

def create_test_session(return_subject=False):
    group_id, project_id = create_test_project()
    subject = {
        'code': SdkTestCase.rand_string_lower(),
        'firstname': SdkTestCase.rand_string(),
        'lastname': SdkTestCase.rand_string(),
        'sex': 'other'
    }

    if return_subject:
        subject['project'] = project_id
        subject_id = SdkTestCase.fw.add_subject(subject)
        session_id = SdkTestCase.fw.add_session({
            'project': project_id,
            'label': SdkTestCase.rand_string(),
            'subject': {
                '_id': subject_id
            }
        })
        return group_id, project_id, subject_id, session_id

    return group_id, project_id, SdkTestCase.fw.add_session({
        'project': project_id,
        'label': SdkTestCase.rand_string(),
        'subject': subject,
        'age': 57
    })


# -*- coding: utf-8 -*-

from myformatter import MyFormatter
import pandas as pd
from males import get_males
from females import get_females
from heightstandperc import get_standards
from getheight import get_heights
from datetime import date
import os

def main():
    standard = get_standards()
    height = get_heights()
    heightsfemale = get_females(standard,height)
    heightsmale = get_males(standard,height)

    last_row = len(heightsfemale) + 1
    last_rowm = len(heightsmale) + 1
    with pd.ExcelWriter("HeightMonitoring{:%d-%b}.xlsx".format(date.today())) as writer:
        workbook = writer.book
        danger_format = workbook.add_format({'border': 1, 'bg_color': '#ff3333'})
        clear_format = workbook.add_format({'border': 1, 'bg_color': '#00ff00'})
        date_format = workbook.add_format({'num_format': 'dd-mmm-yyyy','border': 1})
        bold = workbook.add_format({'bold': True, 'font_color': 'black'})
        bold.set_align("top")
        red = workbook.add_format({'bold': True, 'font_color': '#ff0000'})
        red.set_align('vcenter')
        red.set_text_wrap()
        green = workbook.add_format({'bold': True, 'font_color': '#248f24'})
        green.set_align('vcenter')
        green.set_text_wrap()
        wrap = workbook.add_format({'bold': False, 'font_color': 'black'})
        wrap.set_align('vcenter')
        wrap.set_text_wrap()

        heightsfemale.to_excel(writer, sheet_name="Females")

        worksheet = writer.sheets["Females"]

        # If Height Needed to be in 3rd percentile > Projected Height at final visit
        formula_danger = f'=L2>N2'
        formula_clear = f'=G2>L2'

        worksheet.conditional_format(f'A2:A{last_row}', {'type': 'formula',
                                                        'criteria': formula_danger,
                                                        'format': danger_format})
        worksheet.conditional_format(f'A2:A{last_row}', {'type': 'formula',
                                                    'criteria': formula_clear,
                                                    'format': clear_format})
        worksheet.conditional_format(f'G2:G{last_row}', {'type': 'formula',
                                                    'criteria': formula_clear,
                                                    'format': clear_format})
        worksheet.conditional_format(f'G2:G{last_row}', {'type': 'formula',
                                                    'criteria': formula_danger,
                                                    'format': danger_format})
        worksheet.conditional_format(f'F2:F{last_row}', {'type': 'no_errors','format': date_format})
        worksheet.conditional_format(f'H2:H{last_row}', {'type': 'no_errors','format': date_format})
        formatter = MyFormatter(heightsfemale,workbook,worksheet)
        formatter.spacing()
        formatter.color_columns(color="#b3e0ff")
        formatter.add_borders()
        worksheet.freeze_panes(1,1)
        # Males
        heightsmale.to_excel(writer, sheet_name="Males")

        worksheet = writer.sheets["Males"]
        worksheet.conditional_format(f'A2:A{last_row}', {'type': 'formula',
                                                        'criteria': formula_danger,
                                                        'format': danger_format})
        worksheet.conditional_format(f'A2:A{last_row}', {'type': 'formula',
                                                    'criteria': formula_clear,
                                                    'format': clear_format})
        worksheet.conditional_format(f'G2:G{last_row}', {'type': 'formula',
                                                    'criteria': formula_clear,
                                                    'format': clear_format})
        worksheet.conditional_format(f'G2:G{last_row}', {'type': 'formula',
                                                    'criteria': formula_danger,
                                                    'format': danger_format})
        worksheet.conditional_format(f'F2:F{last_rowm}', {'type': 'no_errors','format': date_format})
        worksheet.conditional_format(f'H2:H{last_rowm}', {'type': 'no_errors','format': date_format})
        formatter = MyFormatter(heightsmale,workbook,worksheet)
        formatter.spacing()
        formatter.color_columns(color="#b3e0ff")
        formatter.add_borders()
        worksheet.freeze_panes(1,1)

        pd.DataFrame().to_excel(writer,sheet_name="Definitions", index = False)
        worksheet=writer.sheets["Definitions"]
        worksheet.set_column(0, 0, 20)
        worksheet.set_column(1, 1, 35)
        worksheet.write(0, 0, 'HNAT:',bold)
        worksheet.write(0, 1, 'Final Week 52 Height needed for a patient to be in the 3rd Percentile.\nCalculated as BaselineWeight + 3rd Percentile Growth Rate for that specific age and sex cohort.',wrap)
        worksheet.write(1,0,"WeeklyGrowthRate:",bold)
        worksheet.write(1,1,"Most Recent Visit Height - Baseline Height/Time between those visits in weeks",wrap)
        worksheet.write(2,0,"ProjectedGrowth:",bold)
        worksheet.write(2,1,"(WeeklyGrowthRate * Number of weeks from most recent vist date to EstimatedWk52Date)\n + Most recent CurrentHeight",wrap)
        worksheet.write(4,1,"Patients Highlighted in Red are not not expected to be above the 3rd percentile based on current GR",red)
        worksheet.write(6,1,"Any CurrentHeight highlighted in Greeen is already above the 3rd percentile",green)
        worksheet.write(8,1,"Percentile Standards are taken from the Table of Yearly growth velocity by age and gender(abstracted  from Tanner and  Davis. J Pediatr. 1985;107(3):317-329)",wrap)
    os.system("start EXCEL.EXE HeightMonitoring{:%d-%b}.xlsx".format(date.today()))

if __name__ == "__main__":
    main()


#!/usr/bin/env python
"""Plotting singular vectors of random matrices."""

import numpy as np
from matplotlib import pyplot as plt

MAXITER, M, N = 1_000_000, 2, 2
matrices = np.random.randn(MAXITER, M, N)
us = np.full((MAXITER, M), fill_value=float("nan"))
vs = np.full((MAXITER, N), fill_value=float("nan"))

for k, A in enumerate(matrices):
    U, S, Vh = np.linalg.svd(A)
    u, s, v = U[:, 0], S[0], Vh[0, :]
    us[k] = u
    vs[k] = v

angle_u = np.arctan2(*us.T[::-1])  # takes y as first arg
angle_v = np.arctan2(*vs.T[::-1])  # takes y as first arg

fig, ax = plt.subplots(figsize=(2.5, 2.5), dpi=300, constrained_layout=True)
ax.plot(angle_u, angle_v, ".", ms=2, markeredgecolor="none", alpha=0.2)
ax.set_xlabel("angle u")
ax.set_ylabel("angle v")
ax.set_aspect("equal", adjustable="box")
ax.set_xticks([-np.pi, 0, np.pi], ["-π", "0", "+π"])
ax.set_yticks([-np.pi, 0, np.pi], ["-π", "0", "+π"])
fig.savefig("hexagons.png", dpi=300)


from openpyxl import load_workbook
import requests
import re
from lxml import etree
def get_quxian(excel):
    wb = load_workbook(excel)
    for i in wb['SQL Results']['F']:
        if i.value != '区县名称':
            yield i.value
def baidu_ss(arg):
    url1 = 'https://www.baidu.com/s?wd='+str(arg)+'人口'
    url2 = 'https://www.baidu.com/s?wd='+str(arg)+'面积'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'Host': 'baike.baidu.com',
        'Accept-Encoding': 'gzip, deflate, br'
    }
    response = requests.get(url1,headers=headers)
    response.encoding = 'utf-8'
    html = response.text
    html = etree.HTML(html)
    renkou = html.xpath('//div[@class="op_exactqa_s_area c-span18 c-span-last"]/div[@class="op_exactqa_s_answer"]/text()')

    # a2 = ''.join(a).replace('\n','')
    # mianji = re.findall('(\d+.\d+)平方千米|(\d+)平方公里',a2)
    # renkou = re.findall('(\d+.\d+)万.*?（\d+年常住人口）|(\d+)万.*?（\d+年常住人口）|(\d+.\d+)万.*?（\d+年）|(\d+)万.*?（\d+年）|(\d+)万人|(\d+.\d+)万人',a2)
    response2 = requests.get(url2,headers=headers)
    response2.encoding = 'utf-8'
    html = response2.text
    html = etree.HTML(html)
    mianji = html.xpath('//div[@class="op_exactqa_s_area c-span18 c-span-last"]/div[@class="op_exactqa_s_answer"]/text()')
    print(url1)
    renkou = ''.join(renkou).replace('\n','').replace(' ','').replace('\t','').replace(' ','')
    mianji = ''.join(mianji).replace('\n','').replace(' ','').replace('\t','').replace(' ','')
    print(renkou,mianji)
    return mianji,renkou
def write_excel(mianji,renkou):
    with open('test4.xlsx','a',encoding='utf-8') as f:
        f.write(mianji+'\t'+renkou+'\n')
def main():
    for i in get_quxian('基准价覆盖城市行政区详情.xlsx'):
        mianji,renkou = baidu_ss(i)
        write_excel(str(mianji),str(renkou))
if __name__ == '__main__':
    main()


import argparse
from collections import defaultdict
import numpy as np
import os.path

parser = argparse.ArgumentParser()
parser.add_argument("--babi_dir", default=None, type=str, help="bAbI tasks directory.")
parser.add_argument("--tasks", default=[5, 6], type=int, nargs='+', help="Which tasks to include.")

START_TOKEN = '<START>'

def entropy(vocab: dict, word_count):
    e = 0
    for word, freq in vocab.items():
        e -= freq / word_count * np.log2(freq / word_count)
    return e

def bigram_entropy(bigram_vocab: dict, vocab: dict, bigram_count, start_count):
    e = 0
    for (context_word, word), freq in bigram_vocab.items():
        if context_word == START_TOKEN:
            context_freq = start_count
        else:
            context_freq = vocab[context_word]
        e -= freq / bigram_count * np.log2(freq / context_freq)
    return e

def update(vocab: dict, words: list):
    for word in words:
        vocab[word] += 1

def bigram_update(bigram_vocab: dict, words: list):
    for bigram in zip([START_TOKEN] + words, words):
        bigram_vocab[bigram] += 1

def main(args):
    assert os.path.isdir(args.babi_dir), "Invalid path to bAbI directory."
    test_files = ['dialog-babi-task1-API-calls-trn.txt',
                  'dialog-babi-task2-API-refine-trn.txt',
                  'dialog-babi-task3-options-trn.txt',
                  'dialog-babi-task4-phone-address-trn.txt',
                  'dialog-babi-task5-full-dialogs-trn.txt',
                  'dialog-babi-task6-dstc2-trn.txt']
    paths = [os.path.join(args.babi_dir, test_file) for test_file in test_files]

    data = {}

    for task in args.tasks:
        path = paths[task - 1]

        dialogues = 0
        turns_total = 0
        words_user_total = 0
        words_bot_total = 0
        bigrams_user_total = 0
        bigrams_bot_total = 0
        bot_start_count_total = 0
        vocab_user = defaultdict(int)
        vocab_bot = defaultdict(int)
        bigram_vocab_user = defaultdict(int)
        bigram_vocab_bot = defaultdict(int)
        turn_counts = []
        user_word_counts = []
        bot_word_counts = []
        wpt_user_counter = []
        wpt_bot_counter = []
        words_user = 0
        words_bot = 0

        with open(path, "r") as task_file:
            for line in task_file:
                if not line.strip():
                    turn_counts.append(turns)
                    wpt_user_counter.append(words_user)
                    wpt_bot_counter.append(words_bot)
                    words_user = 0
                    words_bot = 0
                    continue
                if '\t' not in line: continue

                user, bot = line.split('\t')
                ID, *user = user.split()
                ID = int(ID)
                bot = bot.split()

                if ID == 1:
                    dialogues += 1
                    turns = 0

                if user == [] or user[0] == '<SILENCE>':
                    user = []
                else:
                    turns += 1
                    wpt_user_counter.append(words_user)
                    wpt_bot_counter.append(words_bot)
                    words_user = 0
                    words_bot = 0

                bot_start_count_total += 1

                words_user += len(user)
                words_bot += len(bot)
                words_user_total += len(user)
                words_bot_total += len(bot)
                bigrams_user_total += len(user) - 1
                bigrams_bot_total += len(bot) - 1

                update(vocab_user, user)
                update(vocab_bot, bot)
                bigram_update(bigram_vocab_user, user)
                bigram_update(bigram_vocab_bot, bot)

        user_entropy = entropy(vocab_user, words_user_total)
        bot_entropy = entropy(vocab_bot, words_bot_total)

        user_bigram_entropy = bigram_entropy(bigram_vocab_user, vocab_user, bigrams_user_total, sum(turn_counts))
        bot_bigram_entropy = bigram_entropy(bigram_vocab_bot, vocab_bot, bigrams_bot_total, bot_start_count_total)

        user_vocab_size = len(vocab_user.keys())
        print(vocab_user.keys())
        bot_vocab_size = len(vocab_bot.keys())

        data[task] = [dialogues,
                      sum(turn_counts),
                      np.mean(turn_counts),
                      np.std(turn_counts),
                      user_entropy,
                      user_bigram_entropy,
                      words_user_total,
                      user_vocab_size,
                      np.mean(wpt_user_counter),
                      np.std(wpt_user_counter),
                      bot_entropy,
                      bot_bigram_entropy,
                      bot_vocab_size,
                      words_bot_total,
                      np.mean(wpt_bot_counter),
                      np.std(wpt_bot_counter)]

    labels = ['Total Dialogues',
              'Total Truns',
              'Mean Dialogue Length in Turns',
              'Std of Dialogue Length in Turns',
              'User Entropy',
              'User Bigram Entropy',
              'User Words',
              'User Vocabulary Size',
              'User Mean Turn Length in Words',
              'User Std of Turn Length in Words',
              'System Entropy',
              'System Bigram Entropy',
              'System Vocabulary Size',
              'System Words',
              'System Mean Turn Length in Words',
              'System Std of Turn Length in Words']

    print('||', end='')
    for task in args.tasks:
        print(f'Task {task}|', end='')
    print()
    print('|---|' + '---|' * len(args.tasks))
    for idx, label in enumerate(labels):
        print(f'|{label}|', end='')
        for task in args.tasks:
            val = data[task][idx]
            if isinstance(val, int):
                print(val, end='|')
            else:
                print(f'{val:.2f}', end='|')
        print()

if __name__ == "__main__":
    args = parser.parse_args([] if "__file__" not in globals() else None)

    main(args)


from PIL import Image
import img2pdf
import os
from glob import glob

# 各画像を格納したフォルダの直下に、画像があるようにすること
# PDFのファイル名はフォルダ名になる

# 画像を格納したフォルダの親フォルダ
path = "C:\\_Python\\PDFeditor\\img"
# 画像の拡張子 *pngはダメらいしい？未検証
ext = ".jpg"

path += "\\**\\"

for p in [i for i in glob(path)]:
    search_path = p + "*" + ext
    folder_name = os.path.basename(p.rstrip(os.sep))
    print(folder_name)
    for i in glob(search_path):
        with Image.open(i) as src:
            data = src.getdata()
            mode = src.mode
            size = src.size
        with Image.new(mode, size) as dst:
            dst.putdata(data)
            dst.save(i)
    if len([i for i in glob(search_path)]) == 0:
        continue
    else:
        with open(folder_name + ".pdf", "wb") as files:
            files.write(img2pdf.convert([i for i in glob(search_path)]))


'''test_model.py shows how to write a standalone script to test various django subroutines.
'''

'''Over here is some boiler plat django to make sure the script executes properly. Don't worry
about it too much. Pretty much pattern match when you need to do this.;
'''
import sys, os, logging
sys.path.append('../ormintro')
os.environ['DJANGO_SETTINGS_MODULE'] = 'ormintro.settings'

import django
django.setup()

#sets up logging, all logs go to the console
root = logging.getLogger()
root.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)

'''Now we will import our code
'''
from library.models import *

#addBook('9781497438095','Romeo and Juliet','William Shakespeare', 1597)
#addInventory('9781497438095',5)

#addBook('9780446310789','To Kill a Mockingbird','Harper Lee', 1962)

#addInventory('9781497438095',5)
#addInventory('9780446310789',3)

#checkout('9780446310789')
#checkout('9780446310789')
#checkout('9781497438095')

checkin(1)


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

### Learning TensorFlow with Laurence Moroney, Google Brain on Coursera
#/Users/trannguyen/TranData/WORK/BioinformaticsSpecialization_Tran_2019/
#MachineLearning/TensorFlow_LanguageProcessing/

# Download data
# !wget --no-check-certificate \
#     https://storage.googleapis.com/laurencemoroney-blog.appspot.com/sarcasm.json \
#     -O data/sarcasm.json

import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
import json

def reading_file(filename):
    with open(filename, "r") as f:
        filedata = json.load(f)

    sentences = []
    labels = []
    urls = []

    for item in filedata:
        sentences.append(item['headline'])
        labels.append(item['is_sarcastic'])
        urls.append(item['article_link'])

    return sentences, labels, urls

def text_processing(sentences):

    #tokenizer = Tokenizer(oov_token="<OOV>", num_words = 100,
    #            filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n')
    # num_words: the maximum number of words to keep, based on word frequency.
    # Only the most common num_words-1 words will be kept.
    # if want to keep -, for example "twenty-one": delete - in the filters

    tokenizer = Tokenizer(oov_token="<OOV>")
    # specify a token to use for unknown words as OOV
    tokenizer.fit_on_texts(sentences)
    word_index = tokenizer.word_index
    sequences = tokenizer.texts_to_sequences(sentences)
    padded = pad_sequences(sequences, padding = 'post')
    #default of pad_sequences:
    #They’ll get padded to the length of the longest sequence
    #by adding zeros to the beginning of shorter ones
    print(padded[0])
    print(padded.shape)

########################################################################
# The main() function
def main():

    #print(tf.__version__)
    filename = 'data/sarcasm.json'
    sentences, labels, urls = reading_file(filename)
    text_processing(sentences)

#######################################################################
# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
  main()


#!python3
# encoding=UTF-8
"""

"""
import pathlib
from my_python import lib

NL = '\n'

class MyBox:
    def __init__(self):
        """
        >>> mb = MyBox()
        """
        self.__vbox_path = lib.path_for_command('vboxmanage')

    def list_vms(self):
        """
        >>> for line in MyBox().list_vms().split(NL):
        ...     print(line.strip())
        "centos_default_1646280262092_51162" {18748b24-afea-4945-a02c-6ee9c70f9ddf}
        "centos8" {ca6d485f-33d1-4f66-8df3-a3be3b1970ff}
        <BLANKLINE>
        """
        return lib.invoke_subprocess([self.__vbox_path, 'list', 'vms'])

    def list_runningvms(self, long=False):
        """
        >>> for line in MyBox().list_runningvms().split(NL):
        ...     print(line.strip())
        "centos8" {ca6d485f-33d1-4f66-8df3-a3be3b1970ff}
        <BLANKLINE>

        >>> for line in MyBox().list_runningvms(long=True).split(NL):
        ...     print(line.strip())
        Name:                        centos8
        Groups:                      /
        Guest OS:                    Red Hat (64-bit)
        UUID:                        ca6d485f-33d1-4f66-8df3-a3be3b1970ff
        Config file:                 /Users/mfm/VirtualBox VMs/centos8/centos8.vbox
        Snapshot folder:             /Users/mfm/VirtualBox VMs/centos8/Snapshots
        Log folder:                  /Users/mfm/VirtualBox VMs/centos8/Logs
        Hardware UUID:               ca6d485f-33d1-4f66-8df3-a3be3b1970ff
        Memory size:                 2048MB
        Page Fusion:                 disabled
        VRAM size:                   32MB
        CPU exec cap:                100%
        HPET:                        disabled
        CPUProfile:                  host
        Chipset:                     piix3
        Firmware:                    BIOS
        Number of CPUs:              2
        PAE:                         enabled
        Long Mode:                   enabled
        Triple Fault Reset:          disabled
        APIC:                        enabled
        X2APIC:                      enabled
        Nested VT-x/AMD-V:           disabled
        CPUID Portability Level:     0
        CPUID overrides:             None
        Boot menu mode:              message and menu
        Boot Device 1:               HardDisk
        Boot Device 2:               DVD
        Boot Device 3:               Not Assigned
        Boot Device 4:               Not Assigned
        ACPI:                        enabled
        IOAPIC:                      enabled
        BIOS APIC mode:              APIC
        Time offset:                 0ms
        RTC:                         UTC
        Hardware Virtualization:     enabled
        Nested Paging:               enabled
        Large Pages:                 disabled
        VT-x VPID:                   enabled
        VT-x Unrestricted Exec.:     enabled
        Paravirt. Provider:          Default
        Effective Paravirt. Prov.:   KVM
        State:                       running (since 2022-04-02T22:10:09.870000000)
        Graphics Controller:         VBoxVGA
        Monitor count:               1
        3D Acceleration:             disabled
        2D Video Acceleration:       disabled
        Teleporter Enabled:          disabled
        Teleporter Port:             0
        Teleporter Address:
        Teleporter Password:
        Tracing Enabled:             disabled
        Allow Tracing to Access VM:  disabled
        Tracing Configuration:
        Autostart Enabled:           disabled
        Autostart Delay:             0
        Default Frontend:
        VM process priority:         default
        Storage Controller Name (0):            IDE Controller
        Storage Controller Type (0):            PIIX4
        Storage Controller Instance Number (0): 0
        Storage Controller Max Port Count (0):  2
        Storage Controller Port Count (0):      2
        Storage Controller Bootable (0):        on
        IDE Controller (0, 0): /Users/mfm/VirtualBox VMs/centos8/Snapshots/{5657ee45-6b16-4138-bbdc-f4e51053d3e7}.vmdk (UUID: 5657ee45-6b16-4138-bbdc-f4e51053d3e7)
        NIC 1:                       MAC: 080027D0B9AE, Attachment: NAT, Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
        NIC 1 Settings:  MTU: 0, Socket (send: 64, receive: 64), TCP Window (send:64, receive: 64)
        NIC 1 Rule(0):   name = ssh, protocol = tcp, host ip = 127.0.0.1, host port = 2222, guest ip = , guest port = 22
        NIC 2:                       MAC: 080027DE5034, Attachment: Internal Network 'intnet', Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
        NIC 3:                       disabled
        NIC 4:                       disabled
        NIC 5:                       disabled
        NIC 6:                       disabled
        NIC 7:                       disabled
        NIC 8:                       disabled
        Pointing Device:             PS/2 Mouse
        Keyboard Device:             PS/2 Keyboard
        UART 1:                      disabled
        UART 2:                      disabled
        UART 3:                      disabled
        UART 4:                      disabled
        LPT 1:                       disabled
        LPT 2:                       disabled
        Audio:                       disabled
        Audio playback:              disabled
        Audio capture:               disabled
        Clipboard Mode:              Bidirectional
        Drag and drop Mode:          disabled
        Session name:                GUI/Qt
        VRDE:                        enabled (Address 127.0.0.1, Ports 11615, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
        Video redirection:           disabled
        VRDE property               : TCP/Ports  = "11615"
        VRDE property               : TCP/Address = "127.0.0.1"
        VRDE property               : VideoChannel/Enabled = <not set>
        VRDE property               : VideoChannel/Quality = <not set>
        VRDE property               : VideoChannel/DownscaleProtection = <not set>
        VRDE property               : Client/DisableDisplay = <not set>
        VRDE property               : Client/DisableInput = <not set>
        VRDE property               : Client/DisableAudio = <not set>
        VRDE property               : Client/DisableUSB = <not set>
        VRDE property               : Client/DisableClipboard = <not set>
        VRDE property               : Client/DisableUpstreamAudio = <not set>
        VRDE property               : Client/DisableRDPDR = <not set>
        VRDE property               : H3DRedirect/Enabled = <not set>
        VRDE property               : Security/Method = <not set>
        VRDE property               : Security/ServerCertificate = <not set>
        VRDE property               : Security/ServerPrivateKey = <not set>
        VRDE property               : Security/CACertificate = <not set>
        VRDE property               : Audio/RateCorrectionMode = <not set>
        VRDE property               : Audio/LogPath = <not set>
        OHCI USB:                    disabled
        EHCI USB:                    disabled
        xHCI USB:                    disabled
        <BLANKLINE>
        USB Device Filters:
        <BLANKLINE>
        <none>
        <BLANKLINE>
        Bandwidth groups:  <none>
        <BLANKLINE>
        Shared folders:<none>
        <BLANKLINE>
        Capturing:                   not active
        Capture audio:               not active
        Capture screens:             0
        Capture file:                /Users/mfm/VirtualBox VMs/centos8/centos8.webm
        Capture dimensions:          1024x768
        Capture rate:                512kbps
        Capture FPS:                 25kbps
        Capture options:
        <BLANKLINE>
        Guest:
        <BLANKLINE>
        Configured memory balloon size: 0MB
        <BLANKLINE>
        Snapshots:
        <BLANKLINE>
        Name: vagrant up (UUID: 58bae67f-86a0-4b9d-8704-e633ce0e90bc)
        Description:
        220302233336 5937 mfm@Mikes-MacBook-Pro.local:/Users/mfm/vagrant/centos8 <<< vagrant up
        Bringing machine 'default' up with 'virtualbox' provider...
        ==> default: Importing base box 'generic/centos8'...
        ==> default: Matching MAC address for NAT networking...
        ==> default: Setting the name of the VM: centos8
        ==> default: Clearing any previously set network interfaces...
        ==> default: Preparing network interfaces based on configuration...
        default: Adapter 1: nat
        default: Adapter 2: intnet
        ==> default: Forwarding ports...
        default: 22 (guest) => 2222 (host) (adapter 1)
        ==> default: Running 'pre-boot' VM customizations...
        ==> default: Booting VM...
        ==> default: Waiting for machine to boot. This may take a few minutes...
        default: SSH address: 127.0.0.1:2222
        default: SSH username: vagrant
        default: SSH auth method: private key
        default:
        default: Vagrant insecure key detected. Vagrant will automatically replace
        default: this with a newly generated keypair for better security.
        default:
        default: Inserting generated public key within guest...
        default: Removing insecure key from the guest if it's present...
        default: Key inserted! Disconnecting and reconnecting using new SSH key...
        ==> default: Machine booted and ready!
        ==> default: Checking for guest additions in VM...
        ==> default: Setting hostname...
        ==> default: Configuring and enabling network interfaces...
        Name: Converting from CentOS Linux 8 to CentOS Stream 8 (UUID: 4f084f2b-3a27-4496-b33d-2a339f449853)
        Description:
        dnf --disablerepo '*' --enablerepo extras swap centos-linux-repos centos-stream-repos
        dnf distro-sync
        Name: install docker (UUID: 484dbd16-396f-4c09-9444-bdf8ab7c943e) *
        Description:
        #see https://docs.docker.com/engine/install/centos/
        curl -fsSL https://get.docker.com -o get-docker.sh
        DRY_RUN=1 sh ./get-docker.sh
        sudo sh get-docker.sh
        <BLANKLINE>
        <BLANKLINE>
        """
        args = [self.__vbox_path, 'list', 'runningvms']
        if long:
            args.insert(-1, '-l')
        return lib.invoke_subprocess(args)

    def list_ostypes(self):
        """
        >>> for line in MyBox().list_ostypes().split(NL):
        ...     print(line.strip())
        ID:          Other
        Description: Other/Unknown
        Family ID:   Other
        Family Desc: Other
        64 bit:      false
        <BLANKLINE>
        ID:          Other_64
        Description: Other/Unknown (64-bit)
        Family ID:   Other
        Family Desc: Other
        64 bit:      true
        <BLANKLINE>
        ID:          Windows31
        Description: Windows 3.1
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows95
        Description: Windows 95
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows98
        Description: Windows 98
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsMe
        Description: Windows ME
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsNT3x
        Description: Windows NT 3.x
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsNT4
        Description: Windows NT 4
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows2000
        Description: Windows 2000
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsXP
        Description: Windows XP (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsXP_64
        Description: Windows XP (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows2003
        Description: Windows 2003 (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows2003_64
        Description: Windows 2003 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          WindowsVista
        Description: Windows Vista (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsVista_64
        Description: Windows Vista (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows2008
        Description: Windows 2008 (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows2008_64
        Description: Windows 2008 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows7
        Description: Windows 7 (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows7_64
        Description: Windows 7 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows8
        Description: Windows 8 (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows8_64
        Description: Windows 8 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows81
        Description: Windows 8.1 (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows81_64
        Description: Windows 8.1 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows2012_64
        Description: Windows 2012 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows10
        Description: Windows 10 (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          Windows10_64
        Description: Windows 10 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows2016_64
        Description: Windows 2016 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows2019_64
        Description: Windows 2019 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Windows11_64
        Description: Windows 11 (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          WindowsNT
        Description: Other Windows (32-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      false
        <BLANKLINE>
        ID:          WindowsNT_64
        Description: Other Windows (64-bit)
        Family ID:   Windows
        Family Desc: Microsoft Windows
        64 bit:      true
        <BLANKLINE>
        ID:          Linux22
        Description: Linux 2.2
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Linux24
        Description: Linux 2.4 (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Linux24_64
        Description: Linux 2.4 (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Linux26
        Description: Linux 2.6 / 3.x / 4.x (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Linux26_64
        Description: Linux 2.6 / 3.x / 4.x (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          ArchLinux
        Description: Arch Linux (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          ArchLinux_64
        Description: Arch Linux (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Debian
        Description: Debian (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Debian_64
        Description: Debian (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Fedora
        Description: Fedora (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Fedora_64
        Description: Fedora (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Gentoo
        Description: Gentoo (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Gentoo_64
        Description: Gentoo (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Mandriva
        Description: Mandriva (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Mandriva_64
        Description: Mandriva (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Oracle
        Description: Oracle (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Oracle_64
        Description: Oracle (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          RedHat
        Description: Red Hat (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          RedHat_64
        Description: Red Hat (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          OpenSUSE
        Description: openSUSE (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          OpenSUSE_64
        Description: openSUSE (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Turbolinux
        Description: Turbolinux (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Turbolinux_64
        Description: Turbolinux (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Ubuntu
        Description: Ubuntu (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Ubuntu_64
        Description: Ubuntu (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Xandros
        Description: Xandros (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Xandros_64
        Description: Xandros (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Linux
        Description: Other Linux (32-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      false
        <BLANKLINE>
        ID:          Linux_64
        Description: Other Linux (64-bit)
        Family ID:   Linux
        Family Desc: Linux
        64 bit:      true
        <BLANKLINE>
        ID:          Solaris
        Description: Oracle Solaris 10 5/09 and earlier (32-bit)
        Family ID:   Solaris
        Family Desc: Solaris
        64 bit:      false
        <BLANKLINE>
        ID:          Solaris_64
        Description: Oracle Solaris 10 5/09 and earlier (64-bit)
        Family ID:   Solaris
        Family Desc: Solaris
        64 bit:      true
        <BLANKLINE>
        ID:          OpenSolaris
        Description: Oracle Solaris 10 10/09 and later (32-bit)
        Family ID:   Solaris
        Family Desc: Solaris
        64 bit:      false
        <BLANKLINE>
        ID:          OpenSolaris_64
        Description: Oracle Solaris 10 10/09 and later (64-bit)
        Family ID:   Solaris
        Family Desc: Solaris
        64 bit:      true
        <BLANKLINE>
        ID:          Solaris11_64
        Description: Oracle Solaris 11 (64-bit)
        Family ID:   Solaris
        Family Desc: Solaris
        64 bit:      true
        <BLANKLINE>
        ID:          FreeBSD
        Description: FreeBSD (32-bit)
        Family ID:   BSD
        Family Desc: BSD
        64 bit:      false
        <BLANKLINE>
        ID:          FreeBSD_64
        Description: FreeBSD (64-bit)
        Family ID:   BSD
        Family Desc: BSD
        64 bit:      true
        <BLANKLINE>
        ID:          OpenBSD
        Description: OpenBSD (32-bit)
        Family ID:   BSD
        Family Desc: BSD
        64 bit:      false
        <BLANKLINE>
        ID:          OpenBSD_64
        Description: OpenBSD (64-bit)
        Family ID:   BSD
        Family Desc: BSD
        64 bit:      true
        <BLANKLINE>
        ID:          NetBSD
        Description: NetBSD (32-bit)
        Family ID:   BSD
        Family Desc: BSD
        64 bit:      false
        <BLANKLINE>
        ID:          NetBSD_64
        Description: NetBSD (64-bit)
        Family ID:   BSD
        Family Desc: BSD
        64 bit:      true
        <BLANKLINE>
        ID:          OS21x
        Description: OS/2 1.x
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          OS2Warp3
        Description: OS/2 Warp 3
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          OS2Warp4
        Description: OS/2 Warp 4
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          OS2Warp45
        Description: OS/2 Warp 4.5
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          OS2eCS
        Description: eComStation
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          OS2ArcaOS
        Description: ArcaOS
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          OS2
        Description: Other OS/2
        Family ID:   OS2
        Family Desc: IBM OS/2
        64 bit:      false
        <BLANKLINE>
        ID:          MacOS
        Description: Mac OS X (32-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      false
        <BLANKLINE>
        ID:          MacOS_64
        Description: Mac OS X (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS106
        Description: Mac OS X 10.6 Snow Leopard (32-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      false
        <BLANKLINE>
        ID:          MacOS106_64
        Description: Mac OS X 10.6 Snow Leopard (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS107_64
        Description: Mac OS X 10.7 Lion (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS108_64
        Description: Mac OS X 10.8 Mountain Lion (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS109_64
        Description: Mac OS X 10.9 Mavericks (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS1010_64
        Description: Mac OS X 10.10 Yosemite (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS1011_64
        Description: Mac OS X 10.11 El Capitan (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS1012_64
        Description: macOS 10.12 Sierra (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          MacOS1013_64
        Description: macOS 10.13 High Sierra (64-bit)
        Family ID:   MacOS
        Family Desc: Mac OS X
        64 bit:      true
        <BLANKLINE>
        ID:          DOS
        Description: DOS
        Family ID:   Other
        Family Desc: Other
        64 bit:      false
        <BLANKLINE>
        ID:          Netware
        Description: Netware
        Family ID:   Other
        Family Desc: Other
        64 bit:      false
        <BLANKLINE>
        ID:          L4
        Description: L4
        Family ID:   Other
        Family Desc: Other
        64 bit:      false
        <BLANKLINE>
        ID:          QNX
        Description: QNX
        Family ID:   Other
        Family Desc: Other
        64 bit:      false
        <BLANKLINE>
        ID:          JRockitVE
        Description: JRockitVE
        Family ID:   Other
        Family Desc: Other
        64 bit:      false
        <BLANKLINE>
        ID:          VBoxBS_64
        Description: VirtualBox Bootsector Test (64-bit)
        Family ID:   Other
        Family Desc: Other
        64 bit:      true
        <BLANKLINE>
        <BLANKLINE>
        """
        return lib.invoke_subprocess([self.__vbox_path, 'list', 'ostypes'])

    def createvm(self,
                 name,
                 basefolder=pathlib.Path(pathlib.Path(__file__).parent, '../my_vbox/vbii'),
                 ostype="Ubuntu_64",
                 register=True):
        """
        >>> for line in MyBox().createvm('U20044').split(NL):
        ...     if line.startswith('UUID: '):
        ...         uuid = line[len('UUID: '):].strip()  # this is the key for modifyvm
        ...         continue  # this will always change, so do not print in doctest
        ...     print(line.strip())
        Virtual machine 'U20044' is created and registered.
        Settings file: '/Users/mfm/my_python/my_vbox/vbii/U20044/U20044.vbox'
        <BLANKLINE>
        """
        word_list = [ self.__vbox_path, 'createvm', '--name', name]
        if basefolder is not None:
            word_list.extend(['--basefolder', basefolder])
        if ostype is not None:
            word_list.extend(['--ostype', ostype])
        if register:
            word_list.append('--register')
        return lib.invoke_subprocess(word_list)


from setuptools import setup, find_packages

version = "0.1.0a9"

with open("requirements.txt") as f:
    required_packages = f.read().splitlines()

setup(
    name="mentpy",
    version=version,
    author="Luis Mantilla",
    author_email="luismantilla99@outlook.com",
    description="A Python library for simulating MBQC circuits",
    long_description=open("README.md").read(),
    long_description_content_type="text/markdown",
    url="https://github.com/BestQuark/mentpy",
    packages=find_packages(),
    install_requires=required_packages,
)