from abc import ABC, abstractmethod
from typing import Iterable, List

import numpy as np
import pandas as pd
import scipy.stats as sps

import ambrosia.tools._lib._bin_ci_aide as helper_dir
import ambrosia.tools.pvalue_tools as pvalue_pkg
from ambrosia import types

from . import EFFECT_COL_NAME, FIRST_TYPE_ERROR_COL_NAME, GROUP_SIZE_COL_NAME, STAT_ERRORS_COL_NAME

RELATIVE_ABSOLUTE_DELTA_ERROR = ValueError("Choose relative or absolute delta, not both")
ROUND_DIGITS: int = 3
ROUND_DIGITS_TABLE: int = 3
ROUND_DIGITS_PERCENT: int = 1

class BinomTwoSampleCI(ABC):
    """
    Implementation of two-sample confidence interval.
    Supported the following types  interval_type:

    X ~ Bin(m, p1)
    Y ~ Bin(n, p2)

    Estimated Delta = p1 - p2
    For more information explore:
    http://stat.wharton.upenn.edu/~lbrown/Papers/2005c%20Confidence%20intervals%20for%
    20the%20two%20sample%20binomial%20distribution%20problem.pdf

    Methods
    -------

        Frequency:
        ----------

        Wald's CI - Using MLE estimation for proportions and
                asymptotic normality

        Yule's CI - Using estimation for Var(p1 - p2), in assumption
                (p1 = p2) and (m ~= n). Could be use for criterion
                H0: p1 = p2   vs   H1: p1 != p2
        Yule's modified CI - analogue for previous one for m != n
        Newcombe's CI - combination of CI for p1 and p2, building CI for difference
        Recentred CI - Using t quantiles

        Bayes:
        ------

        Jeffrey's CI - Using for prior distribution Beta(1/2, 1/2)
        Agresti's CI - Using for prior distribution Beta(1, 1)
        Conjugate Beta - Using for prior Beta(n_success, n_failure)

    """

    __PRECISION: float = 0.0001

    # This class just a container with all confidence intervals.
    # Thats why there is no instantiation.
    @abstractmethod
    def __init__(self):
        pass

    @staticmethod
    def __wald_ci(
        sample_a: int, sample_b: int, a_trials: int, b_trials: int, significance_level: float
    ) -> types.IntervalType:
        """
        Implementation of Wald confidence interval.
        """
        p_a_est = sample_a / a_trials
        p_b_est = sample_b / b_trials
        q_a_est = 1 - p_a_est
        q_b_est = 1 - p_b_est
        delta_estimation = p_b_est - p_a_est

        quantile = sps.norm.ppf(significance_level / 2)
        variation = p_a_est * q_a_est / a_trials + p_b_est * q_b_est / b_trials
        shift = -quantile * np.sqrt(variation)

        return delta_estimation - shift, delta_estimation + shift

    @staticmethod
    def __yule_ci(
        sample_a: int, sample_b: int, a_trials: int, b_trials: int, significance_level: float, modified: bool = False
    ) -> types.IntervalType:
        """
        Implementation of Yule's confidence intervals.
        """

        p_a_est = sample_a / a_trials
        p_b_est = sample_b / b_trials
        delta_estimation = p_b_est - p_a_est

        quantile = sps.norm.ppf(significance_level / 2)

        if modified:
            coef_a = b_trials / a_trials
            coef_b = a_trials / b_trials
            p_hat = (sample_a * coef_a + sample_b * coef_b) / (a_trials + b_trials)
            q_hat = 1 - p_hat
            variation = (1 / a_trials + 1 / b_trials) * p_hat * q_hat
        else:
            p_overline = (sample_a + sample_b) / (a_trials + b_trials)
            q_overline = 1 - p_overline
            variation = (1 / a_trials + 1 / b_trials) * p_overline * q_overline

        shift = -quantile * np.sqrt(variation)
        return delta_estimation - shift, delta_estimation + shift

    @staticmethod
    def __bayes_conjugate_beta(
        sample_a: int,
        sample_b: int,
        a_trials: int,
        b_trials: int,
        n_success: int,
        n_failure: int,
        significance_level: float,
    ) -> types.IntervalType:
        """
        Implementation of bayes confidence intervals with cojugate distribution
        Beta(n_success, n_falure).
        """

        p_tilde_a = (sample_a + n_success) / (n_success + n_failure + a_trials)
        p_tilde_b = (sample_b + n_success) / (n_success + n_failure + b_trials)

        q_tilde_a = 1 - p_tilde_a
        q_tilde_b = 1 - p_tilde_b
        delta_tilde = p_tilde_b - p_tilde_a

        quantile = sps.norm.ppf(significance_level / 2)
        variation = p_tilde_a * q_tilde_a / a_trials + p_tilde_b * q_tilde_b / b_trials
        shift = -quantile * np.sqrt(variation)
        return delta_tilde - shift, delta_tilde + shift

    @staticmethod
    def __square_eq_newcombe(p_est: float, m: int, quantile: float) -> types.IntervalType:  # pylint: disable=C0103
        """
        Helper function for newcombe_ci.
        """

        coef_a = 1 + quantile**2 / m
        coef_b = -(2 * p_est + quantile**2 / m)
        coef_c = p_est**2
        d = coef_b**2 - 4 * coef_a * coef_c  # pylint: disable=C0103
        left = (-coef_b - np.sqrt(d)) / (2 * coef_a)
        right = (-coef_b + np.sqrt(d)) / (2 * coef_a)

        return left, right

    @staticmethod
    def __newcombe_ci(
        sample_a: int,
        sample_b: int,
        a_trials: int,
        b_trials: int,
        significance_level: float = 0.05,
    ) -> types.IntervalType:
        """
        Implementation of Newcombe's confidence intervals.
        """
        p_a_est = sample_a / a_trials
        p_b_est = sample_b / b_trials
        delta_est = p_b_est - p_a_est

        quantile = sps.norm.ppf(significance_level / 2)

        # Calculate intevalls for A and B group
        left_bound_group_a, right_bound_group_a = BinomTwoSampleCI.__square_eq_newcombe(p_a_est, a_trials, quantile)
        left_bound_group_b, right_bound_group_b = BinomTwoSampleCI.__square_eq_newcombe(p_b_est, b_trials, quantile)

        variance_a_left = left_bound_group_a * (1 - left_bound_group_a) / a_trials
        variance_a_right = right_bound_group_a * (1 - right_bound_group_a) / a_trials
        variance_b_left = left_bound_group_b * (1 - left_bound_group_b) / b_trials
        variance_b_right = right_bound_group_b * (1 - right_bound_group_b) / b_trials
        variance_left = variance_a_left + variance_b_right
        variance_right = variance_b_left + variance_a_right
        left_bound = delta_est + quantile * np.sqrt(variance_left)
        right_bound = delta_est - quantile * np.sqrt(variance_right)

        return left_bound, right_bound

    @staticmethod
    def __recentered_ci(
        sample_a: int, sample_b: int, a_trials: int, b_trials: int, significance_level: float
    ) -> types.IntervalType:
        """
        Implementation of recentered confidence intervals.
        """
        p_a_est = sample_a / a_trials
        p_b_est = sample_b / b_trials
        delta_estimation = p_b_est - p_a_est
        p_est = (b_trials * p_a_est + a_trials * p_b_est) / (a_trials + b_trials)
        q_est = 1 - p_est
        quantile = -sps.t.ppf(significance_level / 2, df=a_trials + b_trials - 2)
        coef = 1 + quantile**2 / (a_trials + b_trials)
        center = delta_estimation / coef
        var_est = (1 / a_trials + 1 / b_trials) * p_est * q_est
        shift = quantile * np.sqrt(coef * var_est - delta_estimation**2 / (a_trials + b_trials)) / coef
        return center - shift, center + shift

    @staticmethod
    def calculate_pvalue(
        a_success: int,
        b_success: int,
        a_trials: int,
        b_trials: int,
        interval_type: str = "wald",
        alternative: str = "two-sided",
        n_success_conjugate: int = None,
        n_failure_conjugate: int = None,
    ) -> float:
        """
        Calculate pvalue for confidence interval.
        pvalue(x) = inf_a {a | x \\in S_a }

        Parameters
        ----------
        a_success : int
            Samples from Bin(a_trials, p_a)
        b_success : int
            Sample from Bin(b_trials, p_b)
        a_trials : int
            Parameter for trials amount for group A
        b_trials : int
            Parameter for trials amount for group B
        confidence_level : float
            Pr ( [p1 - p2] in CI ) -> confidence_level, n -> infty
        interval_type : str, default : ``"wald"``
            One from [wald, yule, yule_modif, newcombe, jeffrey, agresti, bayes_beta, recenter]
        alternative : str, default : ``"two-sided"``
            Alternative for static criteria - two-sided, less, greater
            Less means, that mean in first group less, than mean in second group
        n_success : int
            Arguments for conjugate distribution Beta(n_success, n_failure) if interval_type = "bayes_beta"
        n_failure : int
            Arguments for conjugate distribution Beta(n_success, n_failure) if interval_type = "bayes_beta"

        Comment
        -------
        You can pass numpy arrays with same shapes for a_success, b_success and e.t.c

        Returns
        -------
        pvalue : float
            P-value of the interval-induced criterion
        """

        return pvalue_pkg.calculate_pvalue_by_interval(
            BinomTwoSampleCI.confidence_interval,
            0,
            a_success=a_success,
            a_trials=a_trials,
            b_success=b_success,
            b_trials=b_trials,
            n_success_conjugate=n_success_conjugate,
            n_failure_conjugate=n_failure_conjugate,
            interval_type=interval_type,
            alternative=alternative,
        )

    @staticmethod
    def confidence_interval(
        a_success: int,
        b_success: int,
        a_trials: int,
        b_trials: int,
        confidence_level: float,
        interval_type: str = "wald",
        alternative: str = "two-sided",
        n_success_conjugate: int = None,
        n_failure_conjugate: int = None,
    ) -> types.IntervalType:
        """
        Main function building confidence interval.

        Parameters
        ----------
        a_success : int
            Samples from Bin(a_trials, p_a)
        b_success : int
            Sample from Bin(b_trials, p_b)
        a_trials : int
            Parameter for trials amount for group A
        b_trials : int
            Parameter for trials amount for group B
        confidence_level : float
            Pr ( [p1 - p2] in CI ) -> confidence_level, n -> infty
        interval_type : str, default : ``"wald"``
            One from [wald, yule, yule_modif, newcombe, jeffrey, agresti, bayes_beta, recenter]
        alternative : str, default : ``"two-sided"``
            Alternative for static criteria - two-sided, less, greater
            Less means, that mean in first group less, than mean in second group
        n_success : int
            Arguments for conjugate distribution Beta(n_success, n_failure) if interval_type = "bayes_beta"
        n_failure : int
            Arguments for conjugate distribution Beta(n_success, n_failure) if interval_type = "bayes_beta"

        Note
        ----
        You can pass numpy arrays with same shapes for a_success, b_success and e.t.c

        Returns
        -------
        interval : Tuple[float, float]
        """

        valid_types: List[str] = [
            "wald",
            "yule",
            "yule_modif",
            "newcombe",
            "jeffrey",
            "agresti",
            "bayes_beta",
            "recenter",
        ]
        pvalue_pkg.check_alternative(alternative)
        significance_level = pvalue_pkg.corrected_alpha(1 - confidence_level, alternative)
        if interval_type == "wald":
            left_ci, right_ci = BinomTwoSampleCI.__wald_ci(a_success, b_success, a_trials, b_trials, significance_level)
        elif interval_type == "yule":
            left_ci, right_ci = BinomTwoSampleCI.__yule_ci(
                a_success, b_success, a_trials, b_trials, significance_level, modified=False
            )
        elif interval_type == "yule_modif":
            left_ci, right_ci = BinomTwoSampleCI.__yule_ci(
                a_success, b_success, a_trials, b_trials, significance_level, modified=True
            )
        elif interval_type == "newcombe":
            left_ci, right_ci = BinomTwoSampleCI.__newcombe_ci(
                a_success, b_success, a_trials, b_trials, significance_level
            )
        elif interval_type == "recenter":
            left_ci, right_ci = BinomTwoSampleCI.__recentered_ci(
                a_success, b_success, a_trials, b_trials, significance_level
            )
        elif interval_type == "jeffrey":
            left_ci, right_ci = BinomTwoSampleCI.__bayes_conjugate_beta(
                a_success, b_success, a_trials, b_trials, 0.5, 0.5, significance_level
            )
        elif interval_type == "agresti":
            left_ci, right_ci = BinomTwoSampleCI.__bayes_conjugate_beta(
                a_success, b_success, a_trials, b_trials, 1, 1, significance_level
            )
        elif interval_type == "bayes_beta":
            error_beta_params: str = "Pass correct params n_success_conjugate, n_faliure_conjugate"
            args_correctness = (
                (n_success_conjugate is not None)
                and (n_failure_conjugate is not None)
                and (n_success_conjugate > 0)
                and (n_failure_conjugate > 0)
            )
            if not args_correctness:
                raise ValueError(error_beta_params)
            left_ci, right_ci = BinomTwoSampleCI.__bayes_conjugate_beta(
                a_success, b_success, a_trials, b_trials, n_success_conjugate, n_failure_conjugate, significance_level
            )
        else:
            algo_type_error: str = f'Choose one from accepted methods, from - {", ".join(valid_types)}'
            raise ValueError(algo_type_error)
        left_ci, right_ci = pvalue_pkg.choose_from_bounds(
            left_ci, right_ci, alternative, left_bound=np.array([-1]), right_bound=np.array([1])
        )
        return left_ci, right_ci

def get_table_power_on_size_and_conversions(
    interval_type: str = "wald",
    p_a_values: Iterable[float] = (0.5,),
    p_b_values: Iterable[float] = (0.4,),
    sample_sizes: Iterable[int] = (100,),
    amount: int = 10000,
    confidence_level: float = 0.95,
) -> pd.DataFrame:
    """
    Table with power / empirical 1 type error = 1 - coverage, for fixed size and conversions.

    Parameters
    ----------
    interval_type : str, default : ``"wald"``
        interval_type for confidence interval
    p_a_values : Iterable[float], default : ``(0.5,)``
        Conversions for A group
    p_b_values : Itrable[float], default : ``(0.5,)``
        Conversions for B group
    sample_sizes : Iterable[float], default : ``(100,)``
        Sizes for samples
    amount : int, default : ``10000``
        Amount of generated samples for one n(trials amount), to estimate power
    confidence_level : float, default : ``0.95``
        Such value x, that: Pr ( delta in I ) >= x

    Returns
    -------
    table : pd.DataFrame
        Required table with power
    """
    trials = np.array(sample_sizes)
    conversions_cond = np.all((np.array(p_a_values) >= 0) & (np.array(p_a_values) <= 1)) and np.all(
        (np.array(p_b_values) >= 0) & (np.array(p_b_values) <= 1)
    )
    if not conversions_cond:
        raise ValueError("Conversions must be from 0 to 1")
    powers_array: List[np.ndarray] = []
    for p_a in p_a_values:
        for p_b in p_b_values:
            sample_a = sps.binom.rvs(n=trials, p=p_a, size=(amount, len(sample_sizes)))
            sample_b = sps.binom.rvs(n=trials, p=p_b, size=(amount, len(sample_sizes)))
            binom_kwargs = {
                "interval_type": interval_type,
                "a_success": sample_a,
                "b_success": sample_b,
                "a_trials": trials,
                "b_trials": trials,
                "confidence_level": confidence_level,
            }
            conf_interval: types.ManyIntervalType = BinomTwoSampleCI.confidence_interval(**binom_kwargs)
            power: np.ndarray = helper_dir.__helper_calc_empirical_power(conf_interval)
            powers_array.append(power)
    power_matrix = np.vstack(powers_array)
    table = pd.DataFrame(
        power_matrix,
        index=pd.MultiIndex.from_tuples(
            [(round(p_a, 3), round(p_b, 3)) for p_a in p_a_values for p_b in p_b_values], names=[r"$p_a$", r"$p_b$"]
        ),
        columns=sample_sizes,
    )
    table.index.name = "conversions"
    table.columns.name = "sample sizes"
    return table

def get_table_power_on_size_and_delta(
    p_a: float,
    sample_sizes: Iterable[int],
    first_errors: Iterable[float] = (0.05,),
    delta_values: Iterable[float] = None,
    delta_relative_values: Iterable[float] = None,
    interval_type: str = "wald",
    # alternative: str = "two-sided",
    amount: int = 10000,
    as_numeric: bool = False,
) -> pd.DataFrame:
    """
    Table with power / empirical 1 type error = 1 - coverage for fixed size and effect.

    Parameters
    ----------
    p_a : Iterable[float]
        Conversion in A group
    sample_sizes : Iterable[float]
        Sizes for samples
    first_errors : Iterable[float], default : ``(0.05,)``
        First type error values
    delta_values : Iterable[float]
        Absolute delta values: p_b - p_a = delta
    delta_relative_values : Iterable[float]
        Relative delta values: p_b = delta_relative * p_a
    interval_type : str
        interval_type for confidence interval
    alternative : str, default : ``"two-sided"``
        Alternative for static criteria - two-sided, less, greater
        Less means, that mean in first group less, than mean in second group
    amount : int, default : ``10000``
        Amount of generated samples for one n(trials amount), to estimate power
    as_numeric : bool, default: ``False``
        The result of calculations can be obtained as a percentage string
        either as a number, this parameter could used to toggle.
        Works only for relative values of power.

    Returns
    -------
    table : pd.DataFrame
        Required table with power
    """
    trials = np.array(sample_sizes)
    if not (delta_values is None) ^ (delta_relative_values is None):
        raise RELATIVE_ABSOLUTE_DELTA_ERROR
    if delta_values is not None:
        p_b_values: np.ndarray = p_a + np.array(delta_values)
        grid_delta: np.ndarray = delta_values
    else:
        p_b_values: np.ndarray = p_a * np.array(delta_relative_values)
        grid_delta: np.ndarray = [f"{np.round((x - 1) * 100, ROUND_DIGITS_PERCENT)}%" for x in delta_relative_values]
    if not np.all((p_b_values >= 0) & (p_b_values <= 1)):
        raise ValueError(f"Probability of success in group B must be positive, not {p_b_values}")

    values = [(round(a, ROUND_DIGITS), b) for a in first_errors for b in grid_delta]
    table: pd.DataFrame = pd.DataFrame(
        index=pd.MultiIndex.from_tuples(values, names=[FIRST_TYPE_ERROR_COL_NAME, EFFECT_COL_NAME]),
        columns=trials,
    )
    table.columns.name = GROUP_SIZE_COL_NAME
    sample_a = sps.binom.rvs(n=trials, p=p_a, size=(amount, trials.shape[0]))
    for alpha in first_errors:
        for p_b, delta in zip(p_b_values, grid_delta):
            sample_b = sps.binom.rvs(n=trials, p=p_b, size=(amount, trials.shape[0]))
            binom_kwargs = {
                "interval_type": interval_type,
                "a_success": sample_a,
                "b_success": sample_b,
                "a_trials": trials,
                "b_trials": trials,
                "confidence_level": 1 - alpha,
                #    "alternative": alternative,
            }
            conf_interval: types.ManyIntervalType = BinomTwoSampleCI.confidence_interval(**binom_kwargs)
            power: np.ndarray = helper_dir.__helper_calc_empirical_power(conf_interval)
            if as_numeric:
                power = [round(power_val, ROUND_DIGITS_TABLE) for power_val in power]
            else:
                power = [str(round(power_val * 100, ROUND_DIGITS_PERCENT)) + "%" for power_val in power]
            table.loc[(alpha, delta), trials] = power
    return table

def iterate_for_sample_size(
    interval_type: str,
    first_errors: Iterable[float],
    second_errors: Iterable[float],
    p_a: float,
    p_b_values: Iterable[float],
    grid_delta: Iterable[float],
    amount: int,
) -> pd.DataFrame:
    """
    Iterate over params for different sample size
    """
    # values = [(round(a, ROUND_DIGITS), round(b, ROUND_DIGITS)) for a in first_errors for b in second_errors]
    # table: pd.DataFrame = pd.DataFrame(
    #     index=pd.MultiIndex.from_tuples(values, names=[r"$\alpha$", r"$\beta$"]),
    #     columns=grid_delta,
    # )
    multiindex = pd.MultiIndex.from_tuples([(eff,) for eff in grid_delta], names=[EFFECT_COL_NAME])
    multicols = pd.MultiIndex.from_tuples(
        [(f"({alpha}; {beta})",) for alpha in first_errors for beta in second_errors],
        names=[STAT_ERRORS_COL_NAME],
    )
    table: pd.DataFrame = pd.DataFrame(index=multiindex, columns=multicols)
    for alpha in first_errors:
        for beta in second_errors:
            power = 1 - beta
            for p_b, delta in zip(p_b_values, grid_delta):
                trials = helper_dir.__helper_bin_search_for_size(
                    interval_type=interval_type,
                    confidence_level=1 - alpha,
                    p_a=p_a,
                    p_b=p_b,
                    amount=amount,
                    power=power,
                )
                table.loc[delta, f"({alpha}; {beta})"] = trials
    return table

def get_table_sample_size_on_effect(
    interval_type: str = "wald",
    first_errors: Iterable[float] = (0.05,),
    second_errors: Iterable[float] = (0.2,),
    p_a: float = 0.5,
    delta_values: Iterable[float] = None,
    delta_relative_values: Iterable[float] = None,
    amount: int = 10000,
) -> pd.DataFrame:
    """
    Table for sample sizes with given effect and errors.

    Parameters
    ----------
    interval_type : str, default : ``"wald"``
        interval_type for confidence interval
    first_errors : Iterable[float], default : ``(0.05,)``
        First type error values
    second_errors : Iterable[float], default : ``(0.2,)``
        Second type error values
    p_a : Iterable[float]
        Conversion in A group, default : ``0.5``
    delta_values : Iterable[float]
        Absolute delta values: p_b - p_a = delta
    delta_relative_values : Iterable[float]
        Relative delta values: p_b = delta_relative * p_a
    amount : int, default : ``1000``
        Amount of generated samples for one n(trials amount), to estimate power

    Returns
    -------
    table : pd.DataFrame
        Required table with sample sizes
    """

    errors_condition = np.all((np.array(first_errors) >= 0) & (np.array(first_errors) <= 1)) and np.all(
        (np.array(second_errors) >= 0) & (np.array(second_errors) <= 1)
    )
    if not errors_condition:
        raise ValueError("Errors must be from 0 to 1")

    if (delta_values is not None) and (delta_relative_values is not None):
        raise RELATIVE_ABSOLUTE_DELTA_ERROR

    # If delta type not set => set to absolute
    if delta_values is None and delta_relative_values is None:
        delta_values = [p_a / 2]

    if delta_values is not None:
        p_b_values: np.ndarray = p_a + np.array(delta_values)
        grid_delta: np.ndarray = delta_values
    else:
        p_b_values: np.ndarray = p_a * np.array(delta_relative_values)
        grid_delta: np.ndarray = [f"{np.round((x - 1) * 100, ROUND_DIGITS_PERCENT)}%" for x in delta_relative_values]
    if not np.all((p_b_values >= 0) & (p_b_values <= 1)):
        raise ValueError(f"Probability of success in group B must be positive, not {p_b_values}")
    table = iterate_for_sample_size(interval_type, first_errors, second_errors, p_a, p_b_values, grid_delta, amount)
    return table

def iterate_for_delta(
    interval_type: str,
    first_errors: Iterable[float],
    second_errors: Iterable[float],
    sample_sizes: Iterable[int],
    p_a: float,
    amount: int,
    delta_type: str,
    as_numeric: bool = False,
) -> pd.DataFrame:
    """
    Helps to find effect for different params.
    """
    multiindex = pd.MultiIndex.from_tuples([(trials,) for trials in sample_sizes], names=[GROUP_SIZE_COL_NAME])
    multicols = pd.MultiIndex.from_tuples(
        [(f"({alpha}; {beta})",) for alpha in first_errors for beta in second_errors],
        names=[STAT_ERRORS_COL_NAME],
    )
    table: pd.DataFrame = pd.DataFrame(index=multiindex, columns=multicols)
    for alpha in first_errors:
        for beta in second_errors:
            power = 1 - beta
            for trials in sample_sizes:
                delta = helper_dir.__helper_bin_search_for_delta(
                    interval_type=interval_type,
                    confidence_level=1 - alpha,
                    p_a=p_a,
                    trials=trials,
                    amount=amount,
                    power=power,
                )
                if delta is not None and delta_type == "relative":
                    if as_numeric:
                        delta = round(abs(delta) / p_a, ROUND_DIGITS_TABLE) + 1
                    else:
                        delta = str(round(abs(delta) / p_a * 100, ROUND_DIGITS_PERCENT)) + "%"
                table.loc[trials, f"({alpha}; {beta})"] = delta
    return table

def get_table_effect_on_sample_size(
    interval_type: str = "wald",
    first_errors: Iterable[float] = (0.05,),
    second_errors: Iterable[float] = (0.2,),
    sample_sizes: Iterable[int] = (100,),
    p_a: float = 0.5,
    amount: int = 10000,
    delta_type: str = "relative",
    as_numeric: bool = False,
) -> pd.DataFrame:
    """
    Table for effects with given sample sizes and erros.
    If there are no effects satisfy first and second errors value will be set to None

    Parameters
    ----------
    interval_type : str, default : ``"wald"``
        interval_type for confidence interval
    first_errors : Iterable[float], default : ``(0.05,)``
        First type error values
    second_errors : Iterable[float], default : ``(0.2,)``
        Second type error values
    p_a : Iterable[float], default : ``0.5``
        Conversion in A group
    amount : int, default : ``10000``
        Amount of generated samples for one n(trials amount), to estimate power
    sample_sizes : Iterable[int], default : ``(100,)``
        Sample sizes for A/B group
    delta_type : str, default : ``"absolute``
        absolute or relative, if relative gives effect in percents: |delta| / p_a
    as_numeric : bool, default: ``False``
        The result of calculations can be obtained as a percentage string
        either as a number, this parameter could used to toggle.
        Works only for relative values of effect.

    Returns
    -------
    table : pd.DataFrame
        Required table with effects
    """
    errors_condition = np.all((np.array(first_errors) >= 0) & (np.array(first_errors) <= 1)) and np.all(
        (np.array(second_errors) >= 0) & (np.array(second_errors) <= 1)
    )
    if not errors_condition:
        error_mesage_errors: str = "Errors must be from 0 to 1"
        raise ValueError(error_mesage_errors)

    delta_types: List[str] = ["absolute", "relative"]
    if delta_type not in delta_types:
        raise ValueError(f"Delta type must be absolute relative, not {delta_type}")
    table: pd.DataFrame = iterate_for_delta(
        interval_type, first_errors, second_errors, sample_sizes, p_a, amount, delta_type, as_numeric
    )
    return table


from elasticsearch import Elasticsearch
from elasticsearch.helpers import scan
from dotenv import load_dotenv
import os
import pandas as pd
from datetime import datetime, timedelta, timezone
from re import search

load_dotenv()

def get_elasticsearchdata():
    indexer_es = Elasticsearch([os.getenv("ELASTIC_URL")],
                               basic_auth=(os.getenv("ELASTIC_USERNAME"), os.getenv("ELASTIC_PASSWORD")),
                               verify_certs=False)
    print("Elasticsearch connection is successful")
    query = {
        "query": {
            "bool": {
                "must": [
                    {
                        "wildcard": {
                            "sitename": "**"
                        }
                    },
                    {
                        "range": {
                            "@timestamp": {
                                "gte": "now-1m"
                            }
                        }
                    }
                ]
            }
        }
    }

    part_of_index = scan(client=indexer_es,
                         query=query,
                         index=('*'),
                         raise_on_error=True,
                         preserve_order=False,
                         clear_scroll=True
                         )

    result = list(part_of_index)

    temp = []
    # We need only '_source', which has all the fields required.
    # This elimantes the elasticsearch metdata like _id, _type, _index.
    for hit in result:
        temp.append(hit['_source'])

    df = pd.DataFrame(temp)

    return df

df = get_elasticsearchdata()
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
pd.set_option('display.max_colwidth', None)
df.columns.values.tolist()

print(df)


from django.test import TestCase
from .models import Invitation

from django.contrib.auth.models import User

class InvitationTests(TestCase):

    @classmethod
    def setUpTestData(cls):
        # Set up non-modified objects used by all test methods
        from_user = User.objects.create(username='jimmy')
        to_user = User.objects.create(username='joe')
        Invitation.objects.create(from_user=from_user,
                                  to_user=to_user,
                                  message='I will crush you!'
                                  )

    def test_to_user(self):
        invitation = Invitation.objects.get(id=1)
        expected_user = f'{invitation.from_user}'
        self.assertEquals(expected_user, 'jimmy')

    def test_from_user(self):
        invitation =Invitation.objects.get(id=1)
        expected_user = f'{invitation.to_user}'
        self.assertEquals(expected_user, 'joe')

    def test_message(self):
        invitation = Invitation.objects.get(id=1)
        expected_message = f'{invitation.message}'
        self.assertEquals(expected_message, 'I will crush you!')


from datetime import datetime

from airflow import DAG
from airflow.providers.databricks.operators.databricks_repos import DatabricksReposCreateOperator

with DAG(
        dag_id='Create_DatabricksRepo',
        schedule_interval='@daily',
        start_date=datetime.now(),
        tags=['example'],
        catchup=False,
) as dag:
    repo_path = "/Repos/sc87291@inetpsa.com/airflow-repo"
    git_url = "https://github.com/lazkamal/dags_2.git"
    create_repo = DatabricksReposCreateOperator(task_id='create_repo', repo_path=repo_path, git_url=git_url, databricks_conn_id='databricks_default')


import sys
from collections import *
from itertools import *
from util import *

def parse(line):
    return line.strip()

a, b = sys.stdin.readlines()

a = int(a)
b = list(map(int, filter(lambda x: x != "x", b.split(","))))

ns = dict()
for bb in b:
    for n in count(1):
        x = n * bb
        if x >= a:
            ns[bb] = x
            break

ma, mb = 0, 999999999

for x, y in ns.items():
    if y < mb:
        mb = y
        ma = x

print((mb - a) * ma )


import os
import sys
import optparse,argparse
import subprocess
import json
import ROOT
from collections import OrderedDict

def prepare_shell(shell_file, command, condor, FarmDir):

  cwd       = os.getcwd()
  with open('%s/%s'%(FarmDir,shell_file), 'w') as shell:
    shell.write('#!/bin/bash\n')
    shell.write('WORKDIR=%s\n'%cwd)
    shell.write('cd %s\n'%cmsswBase)
    shell.write('eval `scram r -sh`\n')
    shell.write('cd ${WORKDIR}\n')
    shell.write(command)
  condor.write('cfgFile=%s\n'%shell_file)
  condor.write('queue 1\n')

if __name__=='__main__':

  usage = 'usage: %prog [options]'
  parser = argparse.ArgumentParser(description=usage)
  parser.add_argument('-m', '--method', dest='method', help='[data/slim_mc/slim_data/...]',default='all', type=str)
  parser.add_argument('-e', '--era', dest='era', help='[all/2016apv/2016postapv/2017/2018]',default='all',type=str, choices=["all","2016apv","2016postapv","2017","2018"])
  parser.add_argument('-s', '--sampletype', dest='sampletype', help='[all/normal/interference/highmass]',default='normal',type=str, choices=["all","normal","interference","highmass"])
  parser.add_argument("--test", action="store_true")
  args = parser.parse_args()

  Eras_List = ['2016postapv','2016apv','2017','2018']
  Eras = []
  for Era in Eras_List:
    if args.era == 'all' or args.era == Era:
      Eras.append(Era)

  cwd       = os.getcwd()
  os.system('cp %s/../../python/common.py .'%cwd)

  from common import inputFile_path, cmsswBase
  from common import GetTrainingFile, GetDataFile

  FarmDir   = '%s/Farm_BDT'%cmsswBase
  os.system('mkdir -p %s'%FarmDir)

  condor = open('%s/condor.sub'%FarmDir,'w')
  condor.write('output = %s/job_common.out\n'%FarmDir)
  condor.write('error  = %s/job_common.err\n'%FarmDir)
  condor.write('log    = %s/job_common.log\n'%FarmDir)
  condor.write('executable = %s/$(cfgFile)\n'%FarmDir)
  condor.write('requirements = (OpSysAndVer =?= "CentOS7")\n')
  condor.write('+JobFlavour = "tomorrow"\n')
  condor.write('+MaxRuntime = 7200\n')

  cwd = os.getcwd()

  for Era in Eras:

    template = "%s/../../script/slim.h"%cwd
    era_header = "script/slim_%s.h"%Era
    template_fake = "%s/../../script/slim_fake.h"%cwd
    era_header_fake = "script/slim_fake_%s.h"%Era

    os.system('mkdir -p script')
    os.system('cat %s | sed "s/EraToBeReplaced/%s/g" > %s'%(template,Era,era_header))
    os.system('cat %s | sed "s/EraToBeReplaced/%s/g" > %s'%(template_fake,Era,era_header_fake))
    os.system('mkdir -p sample/%s'%Era)

    path = inputFile_path[Era]
    if (args.method == 'slim_mc' or args.method == 'all') and args.sampletype == 'normal':
      print ("Creating configuration for slim_mc")
      python_file = "%s/slim_mc.py"%cwd

      # Training sample
      Training_list = GetTrainingFile(Era, True)
      print ("=="*50)
      print ("Training_list: ", Training_list)

      for iin in Training_list:
        # if not iin == 'TTTo2L.root': continue #Meng confirmed on 7Sep2022
        command = "python %s --era %s --train %d --iin %s"%(python_file, Era, 1, iin)
        shell_file = 'slim_mc_%s_%s.sh'%(iin, Era)
        prepare_shell(shell_file, command, condor, FarmDir)

      # nonTraining sample
      nonTraining_list = GetTrainingFile(Era, False)
      print ("=="*50)
      print ("nonTraining_list: ", nonTraining_list)

      for iin in nonTraining_list:
        command = "python %s --era %s --train %d --iin %s"%(python_file, Era, 0, iin)
        shell_file = 'slim_mc_%s_%s.sh'%(iin,Era)
        prepare_shell(shell_file, command, condor, FarmDir)

      # Signal sample
      # coups=['rtc01','rtc04','rtc08','rtc10','rtu01','rtu04','rtu08','rtu10']
      coups=['rtc04','rtu04']
      cps=['A']
      masses=['200','300','350','400','500','600','700']

      for cp in cps:
        for coup in coups:
          for mass in masses:
            iin = 'ttc_%s_%s.root'%(cp.lower(),coup)
            flag='GenModel_T%sToTTQ_M%s_%s_TuneCP5_13TeV_G2HDM_%s_madgraphMLM_pythia8'%(cp,cp,mass,coup)
            command = "python %s --era %s --train %d --iin %s --flag %s"%(python_file, Era, 1, iin, flag)
            shell_file = 'slim_mc_%s_%s.sh'%(flag,Era)
            prepare_shell(shell_file, command, condor, FarmDir)

    #====================
    #Highmass samples
    #====================

    if (args.method == 'slim_mc' or args.method == 'all') and args.sampletype == 'highmass':
      print ("Creating configuration for highmass samples using slim_mc")
      python_file = "%s/slim_mc.py"%cwd

      print ("=="*50)

      coups=['rtc04','rtu04']
      cps=['A']
      masses=['800','900','1000']

      for cp in cps:
        for coup in coups:
          for mass in masses:
            iin = 'ttc_%s_%s_%s_highmass.root'%(cp.lower(), mass, coup)
            command = "python %s --era %s --train %d --iin %s "%(python_file, Era, 1, iin)
            shell_file = 'slim_mc_%s_%s.sh'%(iin,Era)
            print ("shell_file: ", shell_file)
            prepare_shell(shell_file, command, condor, FarmDir)

    #====================
    #Interference samples
    #====================
    if (args.method == 'slim_mc' or args.method == 'all') and args.sampletype == 'interference' :
      print ("=="*50)
      print ("Creating configuration for interference samples using slim_mc")
      python_file = "%s/slim_mc.py"%cwd

      print ("=="*50)

      coups=['rtc04','rtu04']

      A_masses = ['250','300','350','400','550','700','800','900','1000']
      S_masses = ['200','250','300','350','500','650','750','850','950']

      for coup in coups:
          for index, mass in enumerate(A_masses):
            iin = 'ttc_a_%s_s_%s_%s.root'%(A_masses[index], S_masses[index], coup)
            command = "python %s --era %s --train %d --iin %s "%(python_file, Era, 1, iin)
            shell_file = 'slim_%s_%s.sh'%(iin,Era)
            prepare_shell(shell_file, command, condor, FarmDir)

    #====================
    # Data run
    #====================
    if (args.method == 'slim_data' or args.method == 'all') and args.sampletype == 'normal':
      print ("Creating configuration for slim_data")

      python_file = "%s/slim_data.py"%cwd

      for channel in ['DoubleElectron','DoubleMuon','ElectronMuon']:
        FileList = GetDataFile(Era,channel)
        print ("=="*50)
        print ("FileList: ", FileList)

        for iin in FileList:
          shell_file = 'slim_data_%s_%s_%s.sh'%(iin,Era,channel)
          command = "python %s --era %s --channel %s --iin %s"%(python_file, Era, channel, iin)
          prepare_shell(shell_file, command, condor, FarmDir)

    if (args.method == 'slim_fakelep_mc' or args.method == 'all') and args.sampletype == 'normal':
      print ("Creating configuration for slim_falelep_mc")

      python_file = "%s/slim_fakelep_mc.py"%cwd

      for channel in ['DoubleElectron','DoubleMuon','ElectronMuon']:

        Training_list = GetTrainingFile(Era, True)
        print ("=="*50)
        print ("Training_list: ", Training_list)

        for iin in Training_list:
          if "TTTo1L" in  iin: continue
          command = "python %s --era %s --train %d --iin %s --channel %s"%(python_file, Era, 1, iin, channel)
          shell_file = 'slim_fakelep_mc_%s_%s_%s.sh'%(iin, Era, channel)
          prepare_shell(shell_file, command, condor, FarmDir)

        nonTraining_list = GetTrainingFile(Era, False)
        print ("=="*50)
        print ("nonTraining_list: ", nonTraining_list)

        for iin in nonTraining_list:
          command = "python %s --era %s --train %d --iin %s --channel %s"%(python_file, Era, 0, iin, channel)
          shell_file = 'slim_fakelep_mc_%s_%s_%s.sh'%(iin,Era,channel)
          prepare_shell(shell_file, command, condor, FarmDir)

    if (args.method == 'slim_fakelep_data' or args.method=='all') and args.sampletype == 'normal':
      print ("Creating configuration for slim_fakelep_data")

      python_file = "%s/slim_fakelep_data.py"%cwd
      for channel in ['DoubleElectron','DoubleMuon','ElectronMuon']:
        DataList = GetDataFile(Era, channel)
        print ("=="*50)
        print ("DataList: ", DataList)

        for iin in DataList:
          command  = "python %s --era %s --train %d --iin %s --channel %s"%(python_file, Era, 0, iin, channel)
          shell_file = 'slim_fakelep_data_%s_%s_%s.sh'%(iin, Era, channel)
          prepare_shell(shell_file, command, condor, FarmDir)

  condor.close()
  if not args.test:
    print ("Submitting Jobs on Condor")
    os.system('condor_submit %s/condor.sub'%FarmDir)


import torch
import numpy as np
from utils import set_model_mode
import torch.nn.functional as F

def tester(encoder, classifier, discriminator, source_test_loader, target_test_loader, training_mode):
    print("Model test ...")
    batch_size=32
    encoder.cuda()
    classifier.cuda()
    set_model_mode('eval', [encoder, classifier])

    if training_mode == 'dann':
        discriminator.cuda()
        set_model_mode('eval', [discriminator])
        domain_correct = 0

    source_correct = 0
    target_correct = 0

    for batch_idx, (source_data, target_data) in enumerate(zip(source_test_loader, target_test_loader)):
        count = min(len(source_test_loader), len(target_test_loader))
        p = float(batch_idx) / count
        alpha = 2. / (1. + np.exp(-10 * p)) - 1

        # 1. Source input -> Source Classification
        source_image, source_label = source_data
        source_image, source_label = source_image.cuda(), source_label.cuda()
        # source_image = torch.cat((source_image, source_image, source_image), 1)  # MNIST convert to 3 channel
        source_feature = encoder(source_image)
        source_output = classifier(source_feature)
        # source_output = F.softmax(source_output, dim=0)
        source_pred = source_output.data.max(1, keepdim=True)[1]
        # max tensor index
        source_correct += source_pred.eq(source_label.data.view_as(source_pred)).cpu().sum()

        # 2. Target input -> Target Classification
        target_image, target_label = target_data
        target_image, target_label = target_image.cuda(), target_label.cuda()
        target_feature = encoder(target_image)
        target_output = classifier(target_feature)
       # target_output = F.softmax(target_output, dim=0)
        target_pred = target_output.data.max(1, keepdim=True)[1]
        target_correct += target_pred.eq(target_label.data.view_as(target_pred)).cpu().sum()

        if training_mode == 'dann':
            # Combined input -> Domain Classificaion
            combined_image = torch.cat((source_image, target_image), 0)  # 64 = (S:32 + T:32)
            domain_source_labels = torch.zeros(source_label.shape[0]).type(torch.LongTensor)
            domain_target_labels = torch.ones(target_label.shape[0]).type(torch.LongTensor)
            domain_combined_label = torch.cat((domain_source_labels, domain_target_labels), 0).cuda()
            domain_feature = encoder(combined_image)
            domain_output = discriminator(domain_feature, alpha)
        #    domain_output = F.softmax(domain_output, dim=0)
            domain_pred = domain_output.max(1, keepdim=True)[1]
         #   print('domain_pred:', domain_pred.squeeze())
            domain_correct += domain_pred.eq(domain_combined_label.data.view_as(domain_pred)).cpu().sum()
         #   print('domain label: ', domain_combined_label)

    if training_mode == 'dann':
        print("Test Results on DANN :")
        print('\nSource Accuracy: {}/{} ({:.2f}%)\n'
              'Target Accuracy: {}/{} ({:.2f}%)\n'
              'Domain Accuracy: {}/{} ({:.2f}%)\n'.
            format(
            source_correct, (count*batch_size), 100. * source_correct.item() / (count*batch_size),
            target_correct, (count*batch_size), 100. * target_correct.item() / (count*batch_size),
            domain_correct, (count + count)*batch_size, 100. * domain_correct.item() / ((count + count)*batch_size)
        ))
    else:
        print("Test results on source_only :")
        print('\nSource Accuracy: {}/{} ({:.2f}%)\n'
              'Target Accuracy: {}/{} ({:.2f}%)\n'.format(
            source_correct, (count*batch_size), 100. * source_correct.item() / (count*batch_size),
            target_correct, (count*batch_size), 100. * target_correct.item() / (count*batch_size)))


from django.shortcuts import render,redirect,get_object_or_404
from .models import Recent,Song,Favourite,Playlist
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db.models import Q

# Create your views here.

def indexPaige(request):
    # display recent music

    if not request.user.is_anonymous:
        recent = list(Recent.objects.filter(user=request.user).values('song_id').order_by('-id'))
        recent_id = [each['song_id'] for each in recent][:5]
        recent_songs_unsorted = Song.objects.filter(id__in=recent_id,recent__user=request.user)
        recent_songs = list()

        for id in recent_id:
            recent_songs.append(recent_songs_unsorted.get(id=id))
    else:
        recent = None
        recent_songs = None
    first_time = False

    #last played song

    if not request.user.is_anonymous:
            last_played_list = list(Recent.objects.filter(user=request.user).values('song_id').order_by('-id'))
            if last_played_list:
                last_played_id = last_played_list[0]['song_id']
                last_played_song =Song.objects.get(id=last_played_id)
            else:
                first_time =True
                last_played_song = Song.objects.get(id=2)
    else:
        first_time = True
        last_played_song = Song.objects.get(id=2)

#DISPLAY ALL THE SONGS
    songs = Song.objects.all()

# display songs on the home page
    songs_all = list(Song.objects.all().values('id').order_by('?'))
    slided_ids = [each['id'] for each in songs_all ][:5]
    indexpage_Songs = Song.objects.filter(id__in=slided_ids)

    # display Rap Songs
    songs_Rap = list(Song.objects.filter(genre='Rap').values('id'))
    slided_ids = [each['id'] for each in songs_Rap][:5]
    indexpaige_Rap_songs = Song.objects.filter(id__in=slided_ids)

    # display Gospel Songs
    songs_Gospel = list(Song.objects.filter(genre='Gospel').values('id'))
    slided_ids = [each['id'] for each in songs_Gospel][:5]
    indexpaige_Gospel_songs = Song.objects.filter(id__in=slided_ids)

    # display Rock Songs

    songs_Rock = list(Song.objects.filter(genre='Rock').values('id'))
    slided_ids = [each['id'] for each in songs_Rap][:5]
    indexpaige_Rock_songs = Song.objects.filter(id__in=slided_ids)

    if len(request.GET)>0:
        search_query = request.GET.get('q')
        filtered_songs = songs.filter(Q(name__icontains=search_query)).distinct()
        context ={
            'allsongs':filtered_songs,'last_played':last_played_song,'query_search':True
        }
        return render(request,'music/index.html',context=context)

    context ={
          'all_songs':indexpage_Songs,
          'recent_songs':recent_songs,
          'rap_songs':indexpaige_Rap_songs,
          'gospel_songs':indexpaige_Gospel_songs,
          'rock_songs':indexpaige_Rock_songs,
          'last_palyed':last_played_song,
          'first_time':first_time,
          'query_search':False
    }

    return render(request,'music/index.html',context=context)

def gospel_song(request):
    gospel_songs  = Song.objects.filter(genre='Gospel')

    last_played_list = list(Recent.objects.values('song_id').order_by('-id'))
    if last_played_list:
        last_played_id = last_played_list[0]['song_id']
        last_played_song = Song.objects.get(id=last_played_id)
    else:
        last_played_id_song = Song.objects.get(id=2)

    query = request.GET.get('q')

    if query:
        gospel_songs = Song.objects.filter(Q(name__icontains=query)).distinct()
        context = {
            'gospel_songs':gospel_songs

        }
        return render(request,music/rap_songs.html,context=context)

    context ={ 'gospel_songs':gospel_songs,'last_played':last_played_id_song}

    return render(request,music/rap_songs.html,context=context)

def rock_song(request):
    rock_songs  = Song.objects.filter(genre='Rock')

    last_played_list = list(Recent.objects.values('song_id').order_by('-id'))
    if last_played_list:
        last_played_id = last_played_list[0]['song_id']
        last_played_song = Song.objects.get(id=last_played_id)
    else:
        last_played_id_song = Song.objects.get(id=2)

    query = request.GET.get('q')

    if query:
        rap_songs = Song.objects.filter(Q(name__icontains=query)).distinct()
        context = {
            'rock_songs':rock_songs

        }
        return render(request,music/rap_songs.html,context=context)

    context ={ 'rock_songs':rock_songs,'last_played':last_played_id_song}

    return render(request,music/rap_songs.html,context=context)

def rap_song(request):
    rap_songs  = Song.objects.filter(genre='Rap')

    last_played_list = list(Recent.objects.values('song_id').order_by('-id'))
    if last_played_list:
        last_played_id = last_played_list[0]['song_id']
        last_played_song = Song.objects.get(id=last_played_id)
    else:
        last_played_id_song = Song.objects.get(id=2)

    query = request.GET.get('q')

    if query:
        rap_songs = Song.objects.filter(Q(name__icontains=query)).distinct()
        context = {
            'rap_songs':rap_songs

        }
        return render(request,music/rap_songs.html,context=context)

    context ={ 'rap_songs':rap_songs,'last_played':last_played_id_song}

    return render(request,music/rap_songs.html,context=context)

@login_required(login_url='login')
def play_song(request,song_id):
    songs = Song.objects.filter(id=song_id).first()

    #add this data to the recent dataabase
    if list(Recent.objects.filter(song=songs,user=request.user).values()):
        data = Recent.objects.filter(song=songs,user=request.user)
        data.delete()
    data = Recent(song=songs,user=request.user)
    data.save()
    return redirect('all_songs')

@login_required(login_url='login')
def play_song_index(request,song_id):
    songs = Song.objects.filter(id=song_id).first()

    if list(Recent.objects.filter(song=songs,user=request.user).values()):
        data = Recent.objects.filter(song=songs,user=request.user)
        data.delete()
    data = Recent(song=songs,user=request.user)
    data.save()
    return redirect('index')

@login_required(login_url='login')
def play_recent_song(request,song_id):
    songs = Song.objects.filter(id=song_id).first()

    #add this data to the recent dataabase
    if list(Recent.objects.filter(song=songs,user=request.user).values()):
        data = Recent.objects.filter(song=songs,user=request.user)
        data.delete()
    data = Recent(song=songs,user=request.user)
    data.save()
    return redirect('recent')

def all_songs(request):
    songs = Song.objects.all()

    first_time = False

    if not request.user.is_anonymous:
        last_played_list = list(Recent.objects.filter(user=request.user).values('song_id').order_by(['-id']))
        if last_played_list:
            last_played_id =  last_played_list[0]['song_id']
            last_played_song = Song.objects.get(id=last_played_id)
    else:
        first_time= True
        last_played_song = Song.objects.get(id='2')

        ######## APPLYING THE SEARCH FILTERS
        qs_singers = Song.objects.values_list('singer').all()
        s_list =[s.split(',') for singer in qs_singers for s in singers]
        all_singers = sorted(list(set([s.strip() for singer in  s_list for s in singer])))

        qs_genres = Song.objects.values_list('genre').all()
        all_genres = sorted(list(set([l.strip() for genr in qs_genres for g in genr])))

        if len(request.GET)>0:
            search_query = request.GET.get('q')
            search_singer = request.GET.get('singers') or ""
            search_genre = request.GET.get('genres') or ''
            filtered_Songs =songs.filter(Q(name__icontains=search_query)).filter(Q(genre__icontains=search_genre)).filter(Q(singer__icontains=search_singer)).distinct()

            context = {
                'songs':filtered_Songs,
                'last_played':last_played_song,
                'all_singers':all_singers,
                'all_genres': all_genres,
                'query_search':True,
            }

            return render(request, 'music/all_songs.html',context)

        context = {
            'songs':filtered_Songs,
            'last_played':last_played_song,
            'first_time':first_time,
            'all_singers':all_singers,
            'all_genres': all_genres,
            'query_search':False,
        }
        return render(request, 'music/all_songs.html',context)

def recent(request):

    ### last played songs
    last_played_list =  list(Recent.objects.values('song_id').order_by('-id'))

    if last_played_list:
        last_played_id = last_played_list[0]['song_id']
        last_played_song = Song.objects.get(id=last_played_id)
    else:
        last_played_song = Song.objects.get(id=2)

        ### Display the recent songs
    recent = list(Recent.objects.filter(user=request.user).values('song_id').order_by(-id))
    if recent and not request.user.is_anonymous:
        recent_id = [each['song_id'] for each in recent]
        recent_songs_unsorted = Song.objects.filter(id__in=recent_id,recent__user=request.user)
        recent_songs = list()

        for id in recent_id:
            recent_songs.append(recent_songs_unsorted.get(id=id))
    else:
        recent_songs= None

    if len(request.GET)>0:
        search_query = request.GET.get('q')
        filtered_songs = recent_songs_unsorted.filter(Q(name__icontains=search_query)).distinct()
        context = {
            'recent_songs':filtered_songs,'lastplayed':last_played_song, 'query_search':True

        }
        return render(request, 'music/recent.html',context)

    context = {
            'recent_songs':filtered_songs,'lastplayed':last_played_song, 'query_search':False

    }

    return render(request, 'music/recent.html',context)

@login_required(login_url='login')
def detail(request,song_id):
    song = Song.objects.filter(id=song_id).first()

    ## add data to the recent database

    if list(Recent.objects.filter(song=songs,user=request.user).values()):
        data = Recent.objects.filter(song=songs,user=request.user)
        data.delete()
    data = Recent(song=songs,user=request.user)
    data.save()

    # last played song
    last_played_list = list(Recent.objects.values('song_id').order_by('-id'))
    if last_play_list:
        last_played_id = last_played_list[0]['song_id']
        last_played_song = Song.objects.get(id=last_played_id)
    else:
        last_played_song = Song.objects.get(id=2)

    playlists = Playlist.objects.filter(user=request.user).values('playlist_name').distinct()
    is_favourite = Favourite.objects.filter(user=request.user).filter(song=song_id).values('is_fav')

    if request.method =='POST':
        if 'playlist' in request.POST:
            playlist_name =  request.POST['playlist']
            q = Playlist(user=request.user,song=songs,playlist_name=playlist_name)
            q.save()
            messages.success(request,'Song added to playlist')
        elif 'add-fav' in request.POST:
            is_fav = True
            query = Favourite(user=request.user,song=songs,is_fav=is_fav)
            query.save()
            messages.success(request,'Added to favourite')
            return rediect('detail',song_id=song_id)
        elif 'rm-fav' in request.POST:
            is_fav = True
            query = Favourite.objects.filter(user=request.user,song=songs,is_fav=is_fav)
            query.delete()
            messages.success(request,'Removed from favourites')
            return redirec('detail',song_id=song_id)
    context ={ 'songs':songs,'playlists':playlists,'is_favourite':is_favourite, 'last_played_song':last_played_song}

    return render(request,'music/detail.html',context=context)

def mymusic(request):
    return render(request,'music/mymusic.html')

def playlist(request):
    playlists =Playlists.objects.filter(user=request.user).values('playlist_name').distinct
    context = {
        'playlists':playlists
    }
    return render(request,'music/playlist.html',context=context)

def playlist_songs(request,playlist_name):
    songs = Song.objects.filter(playlist__playlist_name=playlist_name,song__id = song_id,user=request.user).distinct()

    if request.method == "POST":
        song_id = list(request.POST.keys())[1]
        favourite_song = Favourite.objects.filter(user=request.user,song__id = song_id,is_fav=True)
        playlist_song.delete()
        messages.success(request,"Song Removed from playlist")

        context ={
            'playlist_name':playlist_name,
            'songs':songs
        }
    return render(request,'music/playlist_song.html',context=content)

def favourite(request):
    songs = Song.objects.filter(favourite_user=request.user,favourite__is_fav=True).distinct()

    if request.method == "POST":
        song_id = list(request.POST.keys())[1]
        favourite_song = Favourite.objects.filter(user=request.user,song__id = song_id,is_fav=True)
        favourite_song.delete()
        messages.success(request,"Removed from favourite")
    context ={
        'songs':songs

    }
    return render(request,'music/favourite.html',context=context)


#!/usr/bin/python3

def roman_to_int(roman_string):

    if roman_string is None or type(roman_string) != str:
        return 0

    roman_dict = {
        'I': 1, 'V': 5,
        'X': 10, 'L': 50,
        'C': 100, 'D': 500, 'M': 1000}

    num = 0
    r_digt = 0
    prev = 0
    count = 0
    for N in reversed(roman_string):
        r_digt = roman_dict[N]
        if r_digt >= prev:
            num += r_digt
        elif r_digt < prev:
            num -= r_digt
        prev = r_digt

    return num


energy = int(input())
count_wins = 0
game_lost = False

command = input()
while command != "End of battle":
    distance = int(command)
    if energy >= distance:
        energy -= distance
        count_wins += 1
    else:
        game_lost = True
        break

    if count_wins % 3 == 0:
        energy += count_wins
    command = input()

if game_lost:
    print(f'Not enough energy! Game ends with {count_wins} won battles and {energy} energy')
else:
    print(f'Won battles: {count_wins}. Energy left: {energy}')

06_old_mid_exams/03. Mid Exam Retake/01. Counter-Strike.py


def_class_len = 50

def radec2pixvec_dist(cen, pixv, nside):
    import healpy as hp
    from astropy.coordinates import SkyCoord
    from astropy import units as u

    sc_cen = SkyCoord(ra=cen[0]*u.degree, dec=cen[1]*u.degree, frame='icrs')
    l, b = hp.pix2ang(nside=nside, ipix=pixv, nest=True, lonlat=True)
    sc_vec = SkyCoord(l=l*u.degree, b=b*u.degree, frame='galactic')
    return sc_cen.separation(sc_vec).degree

def get_planck_by_pix(ipix, planck_nside=2048,
                      dirname='/home/rt2122/Data/Planck/normalized/'):
    import numpy as np
    import os

    files = sorted(next(os.walk(dirname))[-1])
    res = []
    for i_f, file in enumerate(files):
        i_s = np.load(os.path.join(dirname, file))
        res.append(i_s[ipix])
    return np.stack(res, axis=1)

def radec2line_class(coords, radius=7.5/60, class_len=50, planck_nside=2048):
    import numpy as np
    import healpy as hp
    from DS_healpix_fragmentation import radec2vec

    vec = radec2vec(*coords)
    closest_pix = hp.query_disc(nside=planck_nside, vec=vec, radius=np.radians(radius))
    dists = radec2pixvec_dist(coords, closest_pix, nside=planck_nside)
    #sort pix by dist
    arr = list(np.stack([closest_pix, dists]).T)
    arr = sorted(arr, key=lambda x:x[1])

    closest_pix = np.array(arr, dtype=np.int64)[:class_len,0]
    res = get_planck_by_pix(closest_pix)
    return res

def gen_data_for_class(tp_coef, n, cats, pix2, dirname='/home/rt2122/Data/clusters/',
                      fp_file='/home/rt2122/Data/class/fp_coords/fp_pz_pnz_act.csv',
                      radius=7.5/60, class_len=50):
    import os
    import numpy as np
    import pandas as pd
    from DS_healpix_fragmentation import radec2pix

    df_cat = pd.concat([pd.read_csv(os.path.join(dirname, cat + '.csv'))
                        for cat in cats], ignore_index=True)
    df_cat['pix2'] = radec2pix(df_cat['RA'], df_cat['DEC'], 2)
    df_cat = df_cat[np.in1d(df_cat['pix2'], pix2)]
    df_cat.index = np.arange(len(df_cat))

    n_tp = int(tp_coef * n)
    n_fp = n - n_tp

    tp_df = df_cat.sample(n=n_tp)[['RA', 'DEC']]
    fp_df = pd.read_csv(fp_file)
    fp_df['pix2'] = radec2pix(fp_df['RA'], fp_df['DEC'], 2)
    fp_df = fp_df[np.in1d(fp_df['pix2'], pix2)].sample(n=n_fp)[['RA', 'DEC']]
    tp_df['y'] = True
    fp_df['y'] = False
    df = pd.concat([tp_df, fp_df], ignore_index=True)

    X = np.stack([radec2line_class([df['RA'].iloc[i], df['DEC'].iloc[i]],
                                radius=radius, class_len=class_len).flatten()
               for i in range(len(df))])

    y = np.array(df['y'])
    return X, y

def detected_cat2class(cat_df, clf, label='class', radius=7.5/60, class_len=50, nn_mode=False):
    import numpy as np
    import pandas as pd
    from DS_healpix_fragmentation import radec2pix

    X = np.stack([radec2line_class([cat_df['RA'].iloc[i], cat_df['DEC'].iloc[i]],
                                radius=radius, class_len=class_len).flatten()
               for i in range(len(cat_df))])
    if nn_mode:
        ans = clf.predict(X)
        cat_df[label] = ans
    else:
        ans = clf.predict_proba(X)
        cat_df[label] = ans[:, 1]
    return cat_df


import sys, os
path = os.path.dirname(os.path.abspath(__file__))
sys.path.append(path)

import pickle
import numpy as np
import matplotlib.pyplot as plt
from statistics import mean,stdev
from midi_utils import midi_to_csv, csv_to_notes, notes_to_midi

#Print some useful stats to screen
def printStats(pop,gen):
    print('Generation:',gen)
    avgval=0
    maxval=pop[0].fit
    sigma=pop[0].sigma
    for ind in pop:
        avgval+=ind.fit
        if ind.fit > maxval:
            maxval=ind.fit
            sigma=ind.sigma
        #print(ind)

    print('Max fitness',maxval)
    print('Sigma',sigma)
    print('Avg fitness',avgval/len(pop))
    print('')

def generate_prob_vector(length):
    return normalize(np.random.rand(length))

def normalize(x):
     return x / x.sum(0)

def save_model(model, filename):
    with open(filename, 'wb') as f:
        pickle.dump(model, f)

def extract_notes(filename, save = False):
    midi_filename = filename

    csv_midi = midi_to_csv(midi_filename)
    print("csv_midi.shape: ", csv_midi.shape, '\n')

    notes = csv_to_notes(csv_midi)
    print("notes.shape", notes.shape, '\n')

    if save:
        new_mini_name = 'ten_notes.mid'
        ten_notes = np.zeros(notes.shape, dtype='int') + 10
        ten_notes = np.array(ten_notes, dtype='str')

        midi_file = notes_to_midi(midi_filename, ten_notes, new_mini_name)

    return csv_midi, notes

#Basic class for computing, managing, plotting EV3 run stats
class EV_Stats:
    def __init__(self):
        self.bestIndividual = None
        self.bestFit=[]
        self.meanFit=[]
        self.stddevFit=[]
        self.mutationStrength = []

    def accumulate(self, pop):
        #find state with max fitness
        max_fit = pop[0].fit
        max_fit_individ = pop[0]
        mut_strength = pop[0].sigma

        for p in pop:
            if p.fit > max_fit:
                 max_fit = p.fit
                 max_fit_individ = p
                 mut_strength = p.sigma

        self.bestIndividual = max_fit_individ
        self.bestFit.append(max_fit)
        self.mutationStrength.append(mut_strength)

        #compute mean and stddev
        fits = [p.fit for p in pop]
        self.meanFit.append(mean(fits))
        self.stddevFit.append(stdev(fits))

    def print(self, gen=None):
        #if gen not specified, print latest
        if gen is None: gen = len(self.bestFit)-1
        print('Generation:',gen)
        print('Best fitness     : {:6.3f}'.format(self.bestFit[gen]))
        print('Mean fitness     : {:6.3f}'.format(self.meanFit[gen]))
        print('Stddev fitness   : {:6.3f}'.format(self.stddevFit[gen]))
        print('Mutation Strength: {}'.format(str(self.mutationStrength[gen])))

    def plot(self):
        #plot stats to screen & file using matplotlib
        gens = range(len(self.bestFit))

        plt.figure()
        #create stacked plots (4x1)
        plt.subplots_adjust(hspace=0.5)
        plt.subplot(411)
        plt.plot(gens,self.bestFit)
        plt.ylabel('Max Fit')
        plt.title('EV Run Statistics')
        plt.subplot(412)
        plt.plot(gens,self.meanFit)
        plt.ylabel('Mean Fit')
        plt.subplot(413)
        plt.plot(gens,self.stddevFit)
        plt.ylabel('Stddev Fit')
        plt.subplot(414)
        plt.plot(gens,self.mutationStrength)
        plt.ylabel('Mutation Strength')

        #write plots to .png file, then display to screen
        plt.savefig('output/statistics.png')
        plt.show()

    def __str__(self):
        s=''
        s+='bestFits  : ' + str(self.bestFit) + '\n'
        #s+='bestStates: ' + str(self.bestState) + '\n'
        s+='meanFits  : ' + str(self.meanFit) + '\n'
        s+='stddevFits: ' + str(self.stddevFit) + '\n'
        s+=':mutationStrength ' + str(self.mutationStrength)
        return s


def solve(num:list,k:int):
    Max = num.count(1)
    for i in range(len(num)-k+1):
        newNum = list(num)
        for j in range(0,k):
            newNum[i+j] = 1 - newNum[i+j]
        Max = max(Max,newNum.count(1))
    return Max

n = eval(input())
num = list(map(int,input().split(' ')))
Max = num.count(1)
for i in range(n,0,-1):
    Max = max(Max,solve(num,i))
print(Max)


'''
import numpy as np

data_directory = '/home/reyhaneh/VGG/data/'
num_cls = 10
rgb_mean = [0,0,0]
batch_size = None
epoch = None
CHECKPOINT_DIR = '/home/reyhaneh/VGG/checkpoint/'
'''

import os.path  as osp
import numpy    as np
from easydict import EasyDict as edict

__C = edict()
cfg = __C
#__C.DATA_SETS_TYPE='cifar-10'
#__C.DATA_SETS_TYPE='DIV2K_train_HR'
__C.DATA_SETS_TYPE='data3'

# Root directory of project
__C.ROOT_DIR = osp.abspath(osp.join(osp.dirname(__file__), '..'))
__C.DATA_SETS_DIR=osp.join(__C.ROOT_DIR, 'data3/')

__C.CHECKPOINT_DIR=osp.join(__C.ROOT_DIR,'checkpoint')
__C.LOG_DIR=osp.join(__C.ROOT_DIR,'log')

#__C.num_class = 10
__C.num_out = 120
__C.image_size = [32,32,1]
__C.img_channels = 1
__C.degree = 7
__C.rgb_mean = [0.0,0.0,0.0]

# if timer is needed.
__C.TRAINING_TIMER = True
__C.TRACKING_TIMER = True
__C.DATAPY_TIMER = False

__C.USE_CLIDAR_TO_TOP = True

def _merge_a_into_b(a, b):
    """Merge config dictionary a into config dictionary b, clobbering the
    options in b whenever they are also specified in a.
    """
    if type(a) is not edict:
        return

    for k, v in a.iteritems():
        # a must specify keys that are in b
        if not b.has_key(k):
            raise KeyError('{} is not a valid config key'.format(k))

        # the types must match, too
        old_type = type(b[k])
        if old_type is not type(v):
            if isinstance(b[k], np.ndarray):
                v = np.array(v, dtype=b[k].dtype)
            else:
                raise ValueError(('Type mismatch ({} vs. {}) '
                                'for config key: {}').format(type(b[k]),
                                                            type(v), k))

        # recursively merge dicts
        if type(v) is edict:
            try:
                _merge_a_into_b(a[k], b[k])
            except:
                print('Error under config key: {}'.format(k))
                raise
        else:
            b[k] = v

def cfg_from_list(cfg_list):
    """Set config keys via list (e.g., from command line)."""
    from ast import literal_eval
    assert len(cfg_list) % 2 == 0
    for k, v in zip(cfg_list[0::2], cfg_list[1::2]):
        key_list = k.split('.')
        d = __C
        for subkey in key_list[:-1]:
            assert d.has_key(subkey)
            d = d[subkey]
        subkey = key_list[-1]
        assert d.has_key(subkey)
        try:
            value = literal_eval(v)
        except:
            # handle the case when v is a string literal
            value = v
        assert type(value) == type(d[subkey]), \
            'type {} does not match original type {}'.format(
            type(value), type(d[subkey]))
        d[subkey] = value

if __name__ == '__main__':
    print('__C.ROOT_DIR = '+__C.ROOT_DIR)


# -*- coding: utf-8 -*-
"""
Capstone Project: TCS (Graph)
Task: Scraping
Source: https://comptox.epa.gov/dashboard/
"""
import pandas as pd
import requests
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from webdriver_manager.chrome import ChromeDriverManager

def loadCosingData(path):
    """load the data from cosing_clean.

      Args:
          path (string): The path of cosing data

      Returns:
          res: A data frame of cosing chemical name.
    """
    cosing = pd.read_excel(path)
    cosing_name = cosing['Chemical Name'].copy()
    cosing_name = cosing_name.apply(lambda x: x.lower())
    return cosing_name.to_frame()

def loadChemData(path):
    """load the data from comptox and do cleaning (remove na and convert to lower case).

      Args:
          path (string): The path of chemical dictionary data

      Returns:
          res: A cleaned data frame.
    """
    chem_dict = pd.read_csv(path)
    chem_dict = chem_dict.dropna(subset=['preferred_name', 'curation_level'])
    chem_dict_uni = chem_dict.drop_duplicates(subset=['preferred_name'])
    chem_dict_uni['preferred_name'] = chem_dict_uni['preferred_name'].apply(lambda x: str(x).lower())
    return chem_dict, chem_dict_uni

def findID_CompTox(str, chem_dict):
  """Find the corresponding DTXSID for each chemical that has a match.

    Args:
        str (string): The chemical name of this ingredient in cosing clean data
        chem_dict (dataframe): A dataframe containing the chemicals listed in CompTox website.

    Returns:
        res: A string value reporting the corresponding DTXSID.
  """
  if chem_dict['preferred_name'].str.fullmatch(str).sum() > 0:
      return chem_dict[chem_dict['preferred_name']==str]['DTXSID'].iloc[0]
  else:
      return ''

def findFunc(id, func_dict):
    """Find the corresponding functional uses for each chemical that has a match.

      Args:
          id (string): The DTXSID of this ingredient in cosing clean data
          func_dict (dataframe): A dataframe containing the chemicals listed in CompTox website.

      Returns:
          res: A string value reporting the corresponding functional uses, concatnated with comma.
    """
    if id == '':
        return ''
    sample_match = chem_dict[chem_dict['DTXSID']== id]
    sample_match_func = sample_match.join(func_dict[['chemical_id', 'report_funcuse']].set_index('chemical_id'),
                                          how = 'inner', on = 'chemical_id')
    sample_func = sample_match_func.drop_duplicates(subset=['report_funcuse'])
    prop = ''
    for i in sample_func['report_funcuse']:
        prop = prop + str(i) + ','
    prop = prop[:-1]
    return prop

def findSynonyms(id, chem_dict):
    """Find the corresponding synonyms for each chemical that has a match.

      Args:
          id (string): The DTXSID of this ingredient in cosing clean data
          chem_dict (dataframe): A dataframe containing the chemicals listed in CompTox website.

      Returns:
          res: A string value reporting the corresponding synonyms, concatnated with comma.
    """
    sample_synonyms = chem_dict[chem_dict['DTXSID']== id]
    sample_synms = sample_synonyms.drop_duplicates(subset=['raw_chem_name'])
    synms = ''
    for i in sample_synms['raw_chem_name']:
        synms = synms + str(i) + ','
    synms = synms[:-1]
    return synms

def findDensityAndSolubility(id):

  den = 'Not found'
  sol = 'Not found'
  if isinstance(id, str):
      url = 'https://comptox.epa.gov/dashboard/chemical/properties/' + id
      driver = webdriver.Chrome(ChromeDriverManager().install())
      driver.get(url)
      html = driver.page_source

      soup = BeautifulSoup(html, "html.parser")
      content = [s.text.strip() for s in soup.find_all(class_ = "ag-cell-value")]
  else:
      return '', ''

  if 'Density' in content:
      den = content[content.index('Density') + 4]
  if 'Water Solubility' in content:
      sol = content[content.index('Water Solubility') + 4]

  return den, sol

if __name__ == '__main__':

    cosing = loadCosingData("cosing_clean.xlsx")
    chem_dict, chem_dict_uni = loadChemData('chemical_dictionary_20201216.csv')
    func_dict = pd.read_csv('functional_use_dictionary_20201216.csv')
    cosing['ID'] = cosing['Chemical Name'].apply(lambda x: findID_CompTox(x, chem_dict_uni))
    cosing['Functionalities'] = cosing['ID'].apply(lambda x: findFunc(x, func_dict))
    cosing['Synonyms'] = cosing['ID'].apply(lambda x: findSynonyms(x, chem_dict))
    cosing['Density'], cosing['Solubility'] = zip(*cosing['ID'].apply(lambda x: findDensityAndSolubility(x)))
    print(cosing.head())


from flask import Flask, render_template, request, redirect, session# added request
app = Flask(__name__)
app.secret_key = 'keep it secret, keep it safe' # set a secret key for security purposes
# our index route will handle rendering our form
@app.route('/')
def index():
    if 'counter' in session:
        session['counter'] = session['counter'] + 1
    else:
        session['counter']=1
    if 'real_counter' in session:
        session['real_counter'] = session['real_counter'] + 1
    else:
        session['real_counter']=1

    return render_template("index.html")

@app.route('/destroy_session')
def destroy_session():
    session.clear()
    return redirect('/')

@app.route('/counter2')
def counter_add_2():
    session['counter']+=1
    return redirect('/')

@app.route('/increment')
def increment():
    session['counter'] = session['counter']+session['incrementor']-1
    return redirect('/')

@app.route('/counter_increment', methods=["POST"])
def increment_counter():
    session['incrementor']=int(request.form["increment"])
    return redirect('/')

@app.route('/reset_counter')
def reset_counter():
    session['counter']=0
    return redirect('/')
# session.pop('key_name')

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


nums = []
for x in range(4):
    tem = input().split(',')
    tem2 = []
    for n in tem:
        tem2.append(int(n))
    nums.append(tem2)
cnt = 0
for x in nums[0]:
    for y in nums[1]:
        for z in nums[2]:
            for u in nums[3]:
                if x + y + z + u == 0:
                    cnt = cnt + 1
print(cnt)


#import numpy as np

name = "Daniel"
surname = "Berreth"
age = 28
print("My name is %s %s and I am %d years old." %(name, surname, age))

if age < 30:
    print("%s %s is younger than 30 years old." %(name, surname))

count = 0
while count < 3:
    print ("It is Loop No.%d atm." %count)
    count += 1

for x in range(0, int(age/10)):
    print("%s %s already had his round birthday No.%d." %(name, surname, x+1))

#height = [1.87,  1.87, 1.82, 1.91, 1.90, 1.85]
#weight = [81.65, 97.52, 95.25, 92.98, 86.18, 88.45]

#np_height = np.array(height)
#np_weight = np.array(weight)
#bmi_list = np_weight / np_height**2
#print(bmi_list)


from flask import Flask, render_template, request
from utils import Utils

app = Flask(__name__)

@app.route('/')
def index():
    """ Главная страница, где осуществляется поиск конкретного предмета; вывод расписания"""
    today = Utils.print_subjects(Utils.weekdays())[0]
    tomorrow = Utils.print_subjects(Utils.weekdays())[1]
    return render_template('index.html', today=today, tomorrow=tomorrow)

@app.errorhandler(404)
def not_found_error(error):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    return render_template('500.html'), 500

@app.route('/subject/', methods=["POST"])
def subject():
    """ Страница предмета, где осуществляется вывод всех занятий по предмету"""
    days = Utils.find_weekday_by_subject(request.form['name_of_subject'])
    if len(days) >= 1:
        return render_template('subject.html', subject=request.form['name_of_subject'], days=days)
    else:
        return render_template('none.html', subject=request.form['name_of_subject'])

if __name__ == "__main__":
    app.run(debug=False)


from kge.util.io import load_checkpoint
import argparse
import os

import torch
import numpy as np
from scipy.stats import pearsonr

from model.KGEInfluence import KGEInfluence

def dump(obj):
    for attr in dir(obj):
        if hasattr(obj, attr):
            print("obj.%s = %s" % (attr, getattr(obj, attr)))

parser = argparse.ArgumentParser()
parser.add_argument("--dataset",
                    type=str,
                    default="FB15k-237",
                    nargs="?",
                    help="Which dataset to use: FB15k-237 or WN18RR.")
parser.add_argument("--num_iterations",
                    type=int,
                    default=500,
                    nargs="?",
                    help="Number of iterations.")
parser.add_argument("--batch_size",
                    type=int,
                    default=128,
                    nargs="?",
                    help="Batch size.")
parser.add_argument("--nneg",
                    type=int,
                    default=50,
                    nargs="?",
                    help="Number of negative samples.")
parser.add_argument('--avextol',
                    type=float,
                    default=1e-03,
                    help='threshold for optimization in influence function')
parser.add_argument('--damping',
                    type=float,
                    default=1e-01,
                    help='damping term in influence function')
parser.add_argument("--lr",
                    type=float,
                    default=50,
                    nargs="?",
                    help="Learning rate.")
parser.add_argument("--dim",
                    type=int,
                    default=40,
                    nargs="?",
                    help="Embedding dimensionality.")
parser.add_argument("--no-wandb",
                    action='store_true',
                    default=False,
                    help="Log wandb.")
parser.add_argument("--compare", action='store_true', help=".")
parser.add_argument('--disable-cuda', action='store_true', help='Disable CUDA')

args = parser.parse_args()

if not args.disable_cuda and torch.cuda.is_available():
    device = torch.device('cuda')
else:
    device = torch.device('cpu')

# fix seeds
torch.backends.cudnn.deterministic = True
seed = 40
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available:
    torch.cuda.manual_seed_all(seed)

# track experiments with wandb
if args.no_wandb:
    os.environ['WANDB_MODE'] = 'dryrun'

# load pretrained model
checkpoint = load_checkpoint('cp/toy.pt')
# checkpoint = load_checkpoint('cp/toy_distmult.pt')
model = KGEInfluence.create_from(checkpoint, device).to(device)
model.train()
print(model)

# load data and create dataloader
train_triples = model.dataset.load_triples('train')
test_triples = model.dataset.load_triples('test')
# we need indices to get corresponding embeddings gradients
model.test_indices = test_triples

# TODO: args Parameters for dataloader
params = {'batch_size': 32, 'shuffle': False, 'num_workers': 6}
params_test = {'batch_size': 1, 'shuffle': False, 'num_workers': 6}

train_loader = torch.utils.data.DataLoader(train_triples, **params)
single_train_loader = torch.utils.data.DataLoader(train_triples, **params_test)
test_loader = torch.utils.data.DataLoader(test_triples[0:6], **params_test)

# print(model.dataset)

# attrs = vars(model.dataset)
# print(', '.join("%s: %s" % item for item in attrs.items()))

for i in range(model.dataset._triples['train'].shape[0]):
    if i == 0:
        print(model.dataset._triples['train'][1:, :].shape)
    elif i+1 == model.dataset._triples['train'].shape[0]:
        print(model.dataset._triples['train'][:i, :].shape)
        print("LAST")
    else:
        print(
            torch.cat([
                model.dataset._triples['train'][0:i],
                model.dataset._triples['train'][i + 1:]
            ]).shape)

print(model.dataset._triples['train'].shape)

# kge start kge_configs/train_config.yaml -f retrains/test2 --random_seed.default 1 --random_seed.python 2 --random_seed.torch 3 --random_seed.numpy 4 --random_seed.numba 5


import pandas as pd
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
# from model.model import HousePriceModel, TransformerRegressor
from model.model_v3 import HousePriceModel, TransformerRegressor
from model.model_v2 import HousePriceModel_CNN
from dataloader import  HousePriceTestDataset, min_max_denormalize, z_score_denormalize
import platform

def inference():
    # Load Data
    data_path = 'data/final_updated_public_dataset.csv'  # Update with the path of your data file
    data = pd.read_csv(data_path)
    # normalize_columns = {'橫坐標': 'min-max', '縱坐標': 'min-max'}
    normalize_columns = {
    '行政區編號': 'one-hot-encoding', #area_code
    '使用分區':'one-hot-encoding', #building_class
    '主要用途':'one-hot-encoding', #building_usage
    '主要建材':'one-hot-encoding', #building_material
    '建物型態':'one-hot-encoding', #building_style
    '土地面積': 'min-max',
    '移轉層次': 'min-max',
    '總樓層數': 'min-max',
    '屋齡': 'min-max',
    '建物面積': 'min-max',
    '車位面積': 'min-max',
    '車位個數': 'min-max',
    '橫坐標': 'min-max', #z-score
    '縱坐標': 'min-max',
    '主建物面積': 'min-max',
    '陽台面積': 'min-max',
    '附屬建物面積': 'min-max',
    }

    if platform.system() == "Linux":
        gpu = True
    elif platform.system() == "Darwin":
        gpu = False

    dataset = HousePriceTestDataset(data, normalize_columns)
    data_loader = DataLoader(dataset, batch_size=len(dataset), shuffle=False)

    # Load Model
    model_path = 'model_cnn.pth'  # Update with the path of your trained model file
    input_dim = 12 #len(normalize_columns.keys())-1
    model = HousePriceModel(input_dim)
    # model = TransformerRegressor(input_dim, 4, 6)
    # model = HousePriceModel_CNN(input_dim)
    if gpu:
        model = model.cuda()
    else:
        model = model
    model.load_state_dict(torch.load(model_path))
    model.eval()

    # Inference
    with torch.no_grad():
        for batch in data_loader:
            if gpu:
                data = batch['features']
                for i in range(len(data)):
                    data[i] = data[i].cuda()
            else:
                data = batch['features']

            predictions = model(data).cpu().numpy().flatten()

    # Create a DataFrame to hold the IDs and predicted prices
    ids = [f"PU-{i}" for i in range(1, len(predictions) + 1)]  # Adjust ID format as needed
    predicted_prices_df = pd.DataFrame({"ID": ids, "predicted_price": predictions})
    predicted_prices_df = min_max_denormalize(predicted_prices_df, ["predicted_price"],scaler_path="pkl/單價_min_max_normalize_data.pkl")
    # predicted_prices_df = z_score_denormalize(predicted_prices_df, ["predicted_price"],scaler_path="pkl/單價_z_score_normalize_data.pkl")

    # Save to CSV
    output_csv_path = 'predicted_prices.csv'  # Update with the desired output path
    predicted_prices_df.to_csv(output_csv_path, index=False)
    print(f"Predictions saved to {output_csv_path}")

if __name__ == "__main__":
    inference()


from math import sqrt

def is_prime(a):
    flag = True
    for k in range(2, int(sqrt(a))):
        if a % k == 0:
            flag = False
    return flag

n = int(input())
for i in range(0, n):
    m = int(input())
    j = 2
    factor = []
    while j <= m:
        if is_prime(j) and m % j == 0:
            factor.append(j)
            m = m // j
        else:
            j += 1
    if len(factor) == 3 and len(factor) == len(set(factor)):
        print(1)
    else:
        print(0)


from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardButton, InlineKeyboardMarkup
from database import getUserLang

# ************************************* 1 *************************************

russianButton = InlineKeyboardButton(callback_data="Русский", text="🇷🇺 Русский")
kazakhButton = InlineKeyboardButton(callback_data="Қазақша", text="🇰🇿 Қазақша")

choice_lang = InlineKeyboardMarkup(row_width=2, resize_keyboard=True)

choice_lang.add(kazakhButton)
choice_lang.add(russianButton)

# ************************************* 2 *************************************

async def mainKeyboard(userID) -> ReplyKeyboardMarkup:
    userLang = await getUserLang(userID)

    kb = ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text="📧 Обращение")],
            [KeyboardButton(text="💬 Консультация")],
            [KeyboardButton(text="⚙ Настройки" if userLang == "Русский" else "⚙ Параметрлер")]
        ], resize_keyboard=True
    )

    return kb

# ************************************* 3 *************************************

async def changeKeyboardFunc(userID) -> InlineKeyboardMarkup:
    userLang = await getUserLang(userID)

    kb = InlineKeyboardMarkup(
        inline_keyboard=[
            [InlineKeyboardButton("⌨ Изменить язык" if userLang == "Русский" else "⌨ Тілді өзгерту",
                                  callback_data="changeLang")]
        ]
    )

    return kb

# ************************************* 4 *************************************

async def setAppealKeyboard(userID) -> ReplyKeyboardMarkup:
    userLang = await getUserLang(userID)

    kb = ReplyKeyboardMarkup(
        keyboard=[
            [KeyboardButton(text="👩⚕ Психолог")],
            [KeyboardButton(text="👨💼 ЗДВР" if userLang == "Русский" else "👨💼 ДТЖЖО")],
            [KeyboardButton(text="◀ Назад" if userLang == "Русский" else "◀ Артқа")]
        ], resize_keyboard=True
    )

    return kb

# ************************************* 5 *************************************
async def causeKeyboard(userID) -> ReplyKeyboardMarkup:
    userLang = await getUserLang(userID)

    causeRuArray = ["Поведенческое расстройство", "Буллинг", "Нет желания учиться", "Нет друзей",
                    "Конфликт с одноклассниками", "Снижение мотивации"]

    causeKzArray = ["Мінез-құлықтың бұзылуы", "Қорқыту", "Оқуға деген құштарлықтың болмауы", "Достары жоқ",
                    "Сыныптастармен жанжал", "Мотивацияның төмендеуі"]

    kb = ReplyKeyboardMarkup(resize_keyboard=True)

    causeArray = causeRuArray if userLang == "Русский" else causeKzArray

    # Добавление кнопок в клавиатуру
    for i in causeArray:
        kb.add(KeyboardButton(text=i))

    kb.add("◀ Haзaд" if userLang == "Русский" else "◀ Apтқa")

    return kb

# ************************************* 6 *************************************

async def skipKeyboard(userID):
    userLang = await getUserLang(userID)
    kb = ReplyKeyboardMarkup(resize_keyboard=True)

    kb.add("▶ Пропустить" if userLang == "Русский" else "▶ Өткізіп жіберу")

    return kb

# ************************************* 7 *************************************

async def dayOfTheWeekKeyboard(userID) -> ReplyKeyboardMarkup:
    userLang = await getUserLang(userID)

    dayOfTheWeekArrayRu = ["Понедельник",
                           "Вторник",
                           "Среда",
                           "Четверг",
                           "Пятница",
                           ]

    dayOfTheWeekArrayKz = [
                            "Дүйсенбі",
                            "Сейсенбі",
                            "Сәрсенбі",
                            "Бейсенбі",
                            "Жұма"
                        ]

    kb = ReplyKeyboardMarkup(resize_keyboard=True)

    causeArray = dayOfTheWeekArrayRu if userLang == "Русский" else dayOfTheWeekArrayKz

    for i in causeArray:
        kb.add(KeyboardButton(text=i))

    kb.add(KeyboardButton(text="◀ Назад" if userLang == "Русский" else "◀ Артқа"))

    return kb

async def timeConsultationKeyboard(userID):

    userLang = await getUserLang(userID)

    time = [
        "9:00",
        "9:30",
        "10:00",
        "10:30",
        "11:00",
        "11:30",
        "12:00",
        "12:30",
        "14:30",
        "15:00",
        "15:30",
        "16:00",
        "16:30",
        "17:00",
        "17:30"
    ]

    kb = ReplyKeyboardMarkup(resize_keyboard=True)

    for i in time:
        kb.add(KeyboardButton(text=i))

    kb.add(KeyboardButton(text="◀ Назад" if userLang == "Русский" else "◀ Артқа"))

    return kb


import numpy as np
import sympy
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from pylab import figure, axes, pie, title, show

print('Graphik1')
print('Steigung','Y-Achsenabschnitt')
x, y = np.loadtxt('tab2.txt', unpack=True,delimiter=',')
T=np.sqrt(y)

plt.plot(x, y, "kx", label="Messwerte")
plt.errorbar(x, y, yerr=T, fmt="none", capsize=5, capthick=2, ms=9, markerfacecolor="red")

c, v = np.loadtxt('tab2.txt', unpack=True,delimiter=',')
def f(c,a,b):
    return a*c+b
popt, pcov = curve_fit(f, c, v)
print(popt)
print(np.diag(pcov))
print(np.sqrt(np.diag(pcov)))
c_new = np.linspace(x[1], x[-1], 500)

plt.figure(1)
#plt.plot(x,y,'x')
plt.plot(c_new,f(c_new,*popt),'-', label='Lineare Regression')
plt.xlabel('Spannung U / V')
plt.ylabel('N/t $/$ 1/min')
plt.grid()
plt.legend()

plt.savefig('Graphik1.pdf')
print ('Fertig')


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

import pygame
import os
from Entity import Entity

class Player(Entity):
    def __init__(self):
        super(Entity, self).__init__()
        self.xvel = 0
        self.yvel = 0
        self.onGround = False
        self.image = pygame.image.load(os.path.join('', 'player.png'))
        self.rect = pygame.Rect(128, 128, 32, 32)

    def update(self, up, down, left, right, running, platform):
        if up:
            self.yvel -= 7
        if down:
            self.yvel = 7
        if running:
            self.xvel = 12
        if left:
            self.xvel = -8
        if right:
            self.xvel = 8

        if not (up or down):
            self.yvel = 0
        if not (left or right):
            self.xvel = 0

        self.rect.left += self.xvel

        self.collide(self.xvel, 0, platform)

        self.rect.top += self.yvel

        self.onGround = False

        self.collide(0, self.yvel, platform)

    def collide(self, xvel, yvel, platform):
        for p in platform:
            if pygame.sprite.collide_rect(self, p):
                if xvel > 0:
                    self.rect.right = p.rect.left
                    print("collide right")
                if xvel < 0:
                    self.rect.left = p.rect.right
                    print("collide left")
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    # self.onGround = True
                    self.yvel = 0
                if yvel < 0:
                    self.rect.top = p.rect.bottom
                    self.yvel = 0


from api.utilities import splitDict
from middle.consumers.consumers import Consumers

class Proc9002ConsultarPontos(Consumers):
    async def get_consultar_pontos(request_) -> dict:
        """
         name: get_consultar_pontos
        :param request_: request
        :return: dict
        """

        params_: dict = {}
        context_: dict = {}
        return_: dict = {}
        try:

            params_["periodo"] = str(request_["parameters"].get("periodo", " "))
            str(request_["parameters"].get("dataNascimento", " ")).replace('/','-')
            params_["tipo"] = int(request_["parameters"].get("tipo", " "))
            params_["numeroCnh"] = str(request_["parameters"].get("numeroCnh", " "))
            params_["dataNascimento"] = str(request_["parameters"].get("dataNascimento", " ")).replace('/','-')
            params_["cpf"] = str(request_["parameters"].get("cpf", " "))

        except Exception as e:
            print("Erro na criação dos parâmetros na PROC", e)

        context_ = await Consumers.serv_consultar_pontos(params_, request_["service"])

        if context_ == {}:
            return {
                "text": "api_nok",
                "context":{}
            }
        else:
            try:
                context_tratado_: dict = {}
                context_tratado_ = splitDict("proc9002_", context_)
                try:
                    cod_ = int(context_tratado_['proc9002_codigo'])
                    if cod_ == 0:
                        return_= {
                            'text': 'api_ok',
                            'context': context_tratado_
                        }
                    else:
                        return_ = {
                            'text': 'api_nok',
                            'context':""
                        }
                except Exception as e:
                    print("Falha na extração do codigo", e)
                    context_tratado_= "proc9002"
            except Exception as e:
                print("Falha na atualização da matrix", e)
                return_ = {
                    'text': 'api_nok',
                    'context': context_tratado_
                }
        return return_


print("""**************************
HESAP MAKİNESİ
**************************
""")

a= float(input("Birinci Sayı: "))
b= input("İşlem: ")
c= float(input("İkinci Sayı: "))

if b=="+" :
    d = a+c

elif b=="-":
    d = a-c

elif b=="/":
    d = a/c

elif b=="*" or b=="x":
    d = a*c

else:
    print("Geçersiz İşlem..")

a = ((d%1) == 0)
if a :
    d = int(d)

print("İşlem Sonucu: {}".format(d))


"""Memory replay utilities."""

import random
from dataclasses import dataclass, astuple

import tensorflow as tf

from typing import Any, Iterable, Optional

@dataclass
class Transition:
    state: tf.Tensor
    action: int
    reward: float
    is_terminal: bool
    next_state: Optional[tf.Tensor]

@dataclass
class Batch:
    states: tf.Tensor
    actions: tf.Tensor
    rewards: tf.Tensor
    is_terminal: tf.Tensor
    next_states: tf.Tensor

class ReplayMemory:

    def __init__(self, capacity: int):
        self.capacity = capacity
        self._items = []
        self._idx = 0

    def store(self, transition: Transition) -> None:

        item = astuple(transition)

        if len(self) < self.capacity:
            self._items.append(item)
        else:
            self._items[self._idx] = item

        self._idx = (self._idx + 1) % self.capacity

    def sample(self, batch_size: int) -> Batch:
        """Sample a batch of transitions, uniformly at random"""

        assert len(self._items) >= batch_size, (
            f'Cannot sample batch of size {batch_size} from buffer with'
            f' {len(self)} elements.'
        )

        # Sample a new batch without replacement
        sampled = random.sample(self._items, batch_size)

        # Transpose List[Transition] -> List[State], List[Action], etc.
        states, actions, rewards, is_terminal, next_states = zip(*sampled)

        batch = Batch(states, actions, rewards, is_terminal,
            [s for s in next_states if s is not None]
        )

        batch = Batch(
            states = tf.stack(states),
            actions = tf.convert_to_tensor(actions),
            rewards = tf.convert_to_tensor(rewards),
            is_terminal = tf.convert_to_tensor(is_terminal),
            next_states = tf.stack([s for s in next_states if s is not None])
        )

        return batch

    def __len__(self) -> int:
        return len(self._items)

    def __iter__(self) -> Iterable[Any]:
        return iter(self._items)

    def __str__(self) -> str:
        return str(self._items)

class Sampler:

    def __init__(self, policy, env) -> None:
        self._policy = policy
        self._env = env

        self._state = self._env.reset()

    def step(self) -> Transition:
        """Samples the next transition"""

        action = self._policy(self._state)
        next_state, reward, done, _ = self._env.step(action)

        transition = Transition(
            state=self._state,
            action=action,
            reward=reward,
            is_terminal=done,
            next_state=next_state if not done else None
        )

        self._state = self._env.reset() if done else next_state
        return transition