import pandas as pd
import pandas_flavor as pf
from typing import Union, Optional
from functools import partial
import plotly.graph_objects as go

from plotnine import *

from pytimetk.plot.plot_timeseries import plot_timeseries
from pytimetk.utils.plot_helpers import hex_to_rgba, rgba_to_hex, parse_rgba
from pytimetk.utils.checks import check_dataframe_or_groupby, check_date_column, check_anomalize_data
from pytimetk.plot.theme import theme_timetk

@pf.register_dataframe_method
def plot_anomalies(
    data: Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy],
    date_column: str,

    facet_ncol: int = 1,
    facet_nrow: Optional[int] = None,
    facet_scales: str = "free_y",
    facet_dir: str = "h",

    line_color: str = "#2c3e50",
    line_size: Optional[float] = None,
    line_type: str = 'solid',
    line_alpha: float = 1.0,

    anom_color: str = "#E31A1C",
    anom_alpha: float = 1.0,
    anom_size: Optional[float] = None,

    ribbon_fill: str = "#646464",
    ribbon_alpha: float = 0.2,

    y_intercept: Optional[float] = None,
    y_intercept_color: str = "#2c3e50",
    x_intercept: Optional[str] = None,
    x_intercept_color: str = "#2c3e50",

    legend_show: bool = True,

    title: str = "Anomaly Plot",
    x_lab: str = "",
    y_lab: str = "",
    color_lab: str = "Legend",

    x_axis_date_labels: str = "%b %Y",
    base_size: float = 11,
    width: Optional[int] = None,
    height: Optional[int] = None,

    engine: str = 'plotly'
):
    '''
    The `plot_anomalies` function is used to plot anomalies in a time series
    data using either Plotly, Matplotlib, or Plotnine. See `anomalize()` for the
    function to prepare the data for plotting.

    Parameters
    ----------
    data : Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy]
        The input data for the plot. It can be either a pandas DataFrame or a
        pandas DataFrameGroupBy object.
    date_column : str
        The `date_column` parameter is a string that specifies the name of the
        column in the dataframe that contains the dates for the plot.
    facet_ncol : int, optional
        The `facet_ncol` parameter determines the number of columns in the facet
        grid. It specifies how many subplots will be arranged horizontally in
        the plot.
    facet_nrow : int
        The `facet_nrow` parameter determines the number of rows in the facet
        grid. It specifies how many subplots will be arranged vertically in the
        grid.
    facet_scales : str, optional
        The `facet_scales` parameter determines the scaling of the y-axis in the
        facetted plots. It can take the following values:
        - "free_y": The y-axis scale will be free for each facet, but the x-axis
          scale will be fixed for all facets. This is the default value.
        - "free_x": The y-axis scale will be free for each facet, but the x-axis
          scale will be fixed for all facets.
        - "free": The y-axis scale will be free for each facet (subplot). This
          is the default value.

    facet_dir : str, optional
        The `facet_dir` parameter determines the direction in which the facets
        (subplots) are arranged. It can take two possible values:
        - "h": The facets will be arranged horizontally (in rows). This is the
          default value.
        - "v": The facets will be arranged vertically (in columns).
    line_color : str, optional
        The `line_color` parameter is used to specify the color of the lines in
        the time series plot. It accepts a string value representing a color
        code or name. The default value is "#2c3e50", which corresponds to a
        dark blue color.
    line_size : float
        The `line_size` parameter is used to specify the size of the lines in
        the time series plot. It determines the thickness of the lines.
    line_type : str, optional
        The `line_type` parameter is used to specify the type of line to be used
        in the time series plot.
    line_alpha : float
        The `line_alpha` parameter controls the transparency of the lines in the
        time series plot. It accepts a value between 0 and 1, where 0 means
        completely transparent (invisible) and 1 means completely opaque (solid).
    anom_color : str, optional
        The `anom_color` parameter is used to specify the color of the anomalies
        in the plot. It accepts a string value representing a color code or name.
        The default value is `#E31A1C`, which corresponds to a shade of red.
    anom_alpha : float
        The `anom_alpha` parameter controls the transparency (alpha) of the
        anomaly points in the plot. It accepts a float value between 0 and 1,
        where 0 means completely transparent and 1 means completely opaque.
    anom_size : Optional[float]
        The `anom_size` parameter is used to specify the size of the markers
        used to represent anomalies in the plot. It is an optional parameter,
        and if not provided, a default value will be used.
    ribbon_fill : str, optional
        The `ribbon_fill` parameter is used to specify the fill color of the
        ribbon that represents the range of anomalies in the plot. It accepts a
        string value representing a color code or name.
    ribbon_alpha : float
        The parameter `ribbon_alpha` controls the transparency of the ribbon
        fill in the plot. It accepts a float value between 0 and 1, where 0
        means completely transparent and 1 means completely opaque. A higher
        value will make the ribbon fill more visible, while a lower value will
        make it
    y_intercept : float
        The `y_intercept` parameter is used to add a horizontal line to the plot
        at a specific y-value. It can be set to a numeric value to specify the
        y-value of the intercept. If set to `None` (default), no y-intercept
        line will be added to the plot
    y_intercept_color : str, optional
        The `y_intercept_color` parameter is used to specify the color of the
        y-intercept line in the plot. It accepts a string value representing a
        color code or name. The default value is "#2c3e50", which corresponds to
        a dark blue color. You can change this value.
    x_intercept : str
        The `x_intercept` parameter is used to add a vertical line at a specific
        x-axis value on the plot. It is used to highlight a specific point or
        event in the time series data.
        - By default, it is set to `None`, which means no vertical line will be
          added.
        - You can use a date string to specify the x-axis value of the intercept.
          For example, "2020-01-01" would add a vertical line at the beginning
          of the year 2020.
    x_intercept_color : str, optional
        The `x_intercept_color` parameter is used to specify the color of the
        vertical line that represents the x-intercept in the plot. By default,
        it is set to "#2c3e50", which is a dark blue color. You can change this
        value to any valid color code.
    legend_show : bool, optional
        The `legend_show` parameter is a boolean indicating whether or not to
        show the legend in the plot. If set to True, the legend will be
        displayed. The default value is True.
    title : str, optional
        The title of the plot.
    x_lab : str
        The `x_lab` parameter is used to specify the label for the x-axis in the
        plot. It is a string that represents the label text.
    y_lab : str
        The `y_lab` parameter is used to specify the label for the y-axis in the
        plot. It is a string that represents the label for the y-axis.
    color_lab : str, optional
        The `color_lab` parameter is used to specify the label for the legend or
        color scale in the plot. It is used to provide a description of the
        colors used in the plot, typically when a color column is specified.
    x_axis_date_labels : str, optional
        The `x_axis_date_labels` parameter is used to specify the format of the
        date labels on the x-axis of the plot. It accepts a string representing
        the format of the date labels. For  example, "%b %Y" would display the
        month abbreviation and year (e.g., Jan 2020).
    base_size : float, optional
        The `base_size` parameter is used to set the base font size for the plot.
        It determines the size of the text elements such as axis labels, titles,
        and legends.
    width : int
        The `width` parameter is used to specify the width of the plot. It
        determines the horizontal size of the plot in pixels.
    height : int
        The `height` parameter is used to specify the height of the plot in
        pixels. It determines the vertical size of the plot when it is rendered.
    engine : str, optional
        The `engine` parameter specifies the plotting library to use for
        creating the time series plot. It can take one of the following values:

        - "plotly" (interactive): Use the plotly library to create the plot.
           This is the default value.
        - "plotnine" (static): Use the plotnine library to create the plot.
          This is the default value.
        - "matplotlib" (static): Use the matplotlib library to create the plot.

    Returns
    -------
        A plot object, depending on the specified `engine` parameter:
        - If `engine` is set to 'plotnine' or 'matplotlib', the function returns
          a plot object that can be further customized or displayed.
        - If `engine` is set to 'plotly', the function returns a plotly figure
          object.

    See Also
    --------
    `anomalize()`: The `anomalize()` function is used to prepare the data for
                   plotting anomalies in a time series data.

    Examples
    --------
    ```{python}
    # EXAMPLE 1: SINGLE TIME SERIES
    import pytimetk as tk
    import pandas as pd
    import numpy as np

    # Create a date range
    date_rng = pd.date_range(start='2021-01-01', end='2024-01-01', freq='MS')

    # Generate some random data with a few outliers
    np.random.seed(42)
    data = np.random.randn(len(date_rng)) * 10 + 25
    data[3] = 100  # outlier

    # Create a DataFrame
    df = pd.DataFrame(date_rng, columns=['date'])
    df['value'] = data

    # Anomalize the data
    anomalize_df = tk.anomalize(
        df, "date", "value",
        method = "twitter",
        iqr_alpha = 0.10,
        clean_alpha = 0.75,
        clean = "min_max",
    )
    ```

    ``` {python}
    # Visualize the anomaly bands, plotly engine
    (
         anomalize_df
            .plot_anomalies(
                date_column = "date",
                engine = "plotly",
            )
    )
    ```

    ``` {python}
    # Visualize the anomaly bands, plotly engine
    (
         anomalize_df
            .plot_anomalies(
                date_column = "date",
                engine = "plotnine",
            )
    )
    ```

    ``` {python}
    # EXAMPLE 2: MULTIPLE TIME SERIES
    import pytimetk as tk
    import pandas as pd

    df = tk.load_dataset("walmart_sales_weekly", parse_dates=["Date"])[["id", "Date", "Weekly_Sales"]]

    anomalize_df = (
        df
            .groupby('id')
            .anomalize(
                "Date", "Weekly_Sales",
                period = 52,
                trend = 52,
                threads = 1
            )
    )
    ```

    ``` {python}
    # Visualize the anomaly bands, plotly engine
    (
        anomalize_df
            .groupby(["id"])
            .plot_anomalies(
                date_column = "Date",
                facet_ncol = 2,
                width = 800,
                height = 800,
                engine = "plotly",
            )
    )
    ```

    ``` {python}
    # Visualize the anomaly bands, matplotlib engine
    (
        anomalize_df
            .groupby(["id"])
            .plot_anomalies(
                date_column = "Date",
                facet_ncol = 2,
                width = 800,
                height = 800,
                engine = "matplotlib",
            )
    )
    ```

    '''

    # Check data
    check_dataframe_or_groupby(data)
    check_date_column(data, date_column)

    # Check data was anomalized first
    check_anomalize_data(data)

    # Handle line_size
    if line_size is None:
        if engine == 'plotnine':
            line_size = 0.35
        elif engine == 'matplotlib':
            line_size = 0.35
        elif engine == 'plotly':
            line_size = 0.65

    if engine == 'plotly':

        if anom_size is None:
            anom_size = 6.0

        fig = _plot_anomalies_plotly(
            data = data,
            date_column = date_column,

            facet_ncol = facet_ncol,
            facet_nrow = facet_nrow,
            facet_scales = facet_scales,
            facet_dir = facet_dir,

            line_color = line_color,
            line_size = line_size,
            line_type = line_type,
            line_alpha = line_alpha,

            anom_color = anom_color,
            anom_alpha = anom_alpha,
            anom_size = anom_size,

            ribbon_fill = ribbon_fill,
            ribbon_alpha = ribbon_alpha,

            y_intercept = y_intercept,
            y_intercept_color = y_intercept_color,
            x_intercept = x_intercept,
            x_intercept_color = x_intercept_color,

            legend_show = legend_show,

            title = title,
            x_lab = x_lab,
            y_lab = y_lab,
            color_lab = color_lab,

            x_axis_date_labels = x_axis_date_labels,
            base_size = base_size,
            width = width,
            height = height,
        )

    else:

        if anom_size is None:
            anom_size = 1.0

        fig = _plot_anomalies_plotnine(
            data = data,
            date_column = date_column,

            facet_ncol = facet_ncol,
            facet_nrow = facet_nrow,
            facet_scales = facet_scales,
            facet_dir = facet_dir,

            line_color = line_color,
            line_size = line_size,
            line_type = line_type,
            line_alpha = line_alpha,

            anom_color = anom_color,
            anom_alpha = anom_alpha,
            anom_size = anom_size,

            ribbon_fill = ribbon_fill,
            ribbon_alpha = ribbon_alpha,

            y_intercept = y_intercept,
            y_intercept_color = y_intercept_color,
            x_intercept = x_intercept,
            x_intercept_color = x_intercept_color,

            legend_show = legend_show,

            title = title,
            x_lab = x_lab,
            y_lab = y_lab,
            color_lab = color_lab,

            x_axis_date_labels = x_axis_date_labels,
            base_size = base_size,
            width = width,
            height = height,
        )

        if engine == 'matplotlib':
            if width == None:
                width_size = 800 # in pixels for compat with plotly
            else:
                width_size = width

            if height == None:
                height_size = 600 # in pixels for compat with plotly
            else:
                height_size = height
            fig = fig + theme_timetk(height=height_size, width=width_size) # setting default figure size to prevent matplotlib sizing error
            fig = fig.draw()

    return fig

# Monkey patch the method to pandas groupby objects
pd.core.groupby.generic.DataFrameGroupBy.plot_anomalies = plot_anomalies

def _plot_anomalies_plotly(
    data: Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy],
    date_column: str,

    facet_ncol: int = 1,
    facet_nrow: Optional[int] = None,
    facet_scales: str = "free_y",
    facet_dir: str = "h",

    line_color: str = "#2c3e50",
    line_size: float = None,
    line_type: str = 'solid',
    line_alpha: float = 1.0,

    anom_color: str = "#E31A1C",
    anom_alpha: float = 1.0,
    anom_size: Optional[float] = None,

    ribbon_fill: str = "#646464",
    ribbon_alpha: float = 0.2,

    y_intercept: Optional[float] = None,
    y_intercept_color: str = "#2c3e50",
    x_intercept: Optional[str] = None,
    x_intercept_color: str = "#2c3e50",

    legend_show: bool = True,

    title: str = "Anomaly Plot",
    x_lab: str = "",
    y_lab: str = "",
    color_lab: str = "Legend",

    x_axis_date_labels: str = "%b %Y",
    base_size: float = 11,
    width: Optional[int] = None,
    height: Optional[int] = None,

):

    # Plot Setup
    ribbon_color_rgba = hex_to_rgba(ribbon_fill, ribbon_alpha)
    ribbon_color_rgba_list = parse_rgba(ribbon_color_rgba)
    ribbon_color_hex = rgba_to_hex(*ribbon_color_rgba_list)

    preload_plot_timeseries = partial(
        plot_timeseries,

        date_column = date_column,
        value_column = "_val",
        color_column = "_var",

        color_palette = [
            line_color,
            ribbon_color_hex,
            ribbon_color_hex
        ],

        facet_ncol = facet_ncol,
        facet_nrow = facet_nrow,
        facet_scales = facet_scales,
        facet_dir = facet_dir,

        line_size = line_size,
        line_type = line_type,
        line_alpha = line_alpha,

        y_intercept = y_intercept,
        y_intercept_color = y_intercept_color,
        x_intercept = x_intercept,
        x_intercept_color = x_intercept_color,

        smooth = False,

        legend_show = legend_show,

        title = title,
        x_lab = x_lab,
        y_lab = y_lab,
        color_lab = color_lab,

        x_axis_date_labels = x_axis_date_labels,

        base_size = base_size,

        width = width,
        height = height,
    )

    # 1.0 Create Main Plot

    is_grouped = False
    if isinstance(data, pd.core.groupby.generic.DataFrameGroupBy):
        group_names = data.grouper.names
        data = data.obj.copy()
        is_grouped = True
    else:
        data = data.copy()
        data["_grp"] = "Time Series"
        group_names = ["_grp"]

    data[group_names] = data[group_names].astype(str)

    data_prepared = (
        data[[*group_names, date_column, "observed", "recomposed_l1", "recomposed_l2"]]
            .melt(
                id_vars = [*group_names, date_column],
                value_name='_val',
                var_name = '_var',
            )
            .groupby(group_names)
    )

    fig = preload_plot_timeseries(data_prepared)

    # 2.0 Add Ribbon

    # Create lists to store the indices of the traces
    indices_l1 = [i for i, trace in enumerate(fig.data) if trace.name == 'recomposed_l1']
    indices_l2 = [i for i, trace in enumerate(fig.data) if trace.name == 'recomposed_l2']

    # Transparent color for the line (line will be invisible)
    transparent_rgba = 'rgba(0,0,0,0)'

    # Iterate through the pairs of indices and update the fig.data list
    for i_l1, i_l2 in zip(indices_l1, indices_l2):
        # Ensure 'recomposed_l1' comes before 'recomposed_l2' in fig.data
        if i_l1 > i_l2:
            i_l1, i_l2 = i_l2, i_l1  # Swap the indices
            fig.data[i_l1], fig.data[i_l2] = fig.data[i_l2], fig.data[i_l1]  # Swap the traces

        # Update the 'recomposed_l1' and 'recomposed_l2' traces to have transparent lines
        fig.data[i_l1].update(line=dict(color=transparent_rgba))
        fig.data[i_l2].update(line=dict(color=transparent_rgba), fill='tonexty', fillcolor=ribbon_color_rgba)  # Adjust fill color as needed

    # 3.0 Add Anomaly Dots

    # Assuming fig.data contains your trace data and you know the number of subplots
    num_subplots = len(fig.layout.annotations)  # Assuming each subplot has one annotation

    def generate_triples(n):
        result = []
        for i in range(1, 3*n+1, 3):
            result.append([i, i+1, i+2])
        return result

    tripples = generate_triples(num_subplots)

    for tripple in tripples:

        observed_data = None
        recomposed_l2_data = None
        recomposed_l1_data = None

        for i in tripple:
            i-=1

            # Extract data for each subplot

            if fig.data[i].name == 'observed':
                observed_data = fig.data[i]
            elif fig.data[i].name == 'recomposed_l1':
                recomposed_l1_data = fig.data[i]
                fig.data[i].legendgroup = "bands"
                fig.data[i].showlegend = False
            elif fig.data[i].name == 'recomposed_l2':
                recomposed_l2_data = fig.data[i]
                fig.data[i].legendgroup = "bands"
                fig.data[i].showlegend = False

        # Ensure we have the data
        if observed_data and recomposed_l2_data and recomposed_l1_data:
            # Identify points where condition is met
            x_values = []
            y_values = []
            for x, y, y_l2, y_l1 in zip(observed_data.x, observed_data.y, recomposed_l2_data.y, recomposed_l1_data.y):
                if y > y_l2 or y < y_l1:
                    x_values.append(x)
                    y_values.append(y)

            # Add scatter plot with identified points to the correct subplot
            fig.add_trace(
                go.Scatter(
                    x=x_values,
                    y=y_values,
                    mode='markers',
                    marker=dict(
                        color=anom_color,
                        size=anom_size,
                        opacity=anom_alpha,
                    ),
                    name='anomalies',
                    legendgroup='anomalies',
                    xaxis=observed_data.xaxis,
                    yaxis=observed_data.yaxis
                )
            )

    # Remove duplicate legends in each legend group
    seen_legendgroups = set()
    for trace in fig.data:
        legendgroup = trace.legendgroup
        if legendgroup in seen_legendgroups:
            trace.showlegend = False
        else:
            seen_legendgroups.add(legendgroup)

    # Cleanup annotations if ungrouped
    if not is_grouped:
        fig['layout']['annotations'] = []

    # Apply Styling
    fig.update_annotations(font_size=base_size*0.8)
    fig.update_traces(hoverlabel=dict(font_size=base_size*0.8))

    return fig

def _plot_anomalies_plotnine(
    data: Union[pd.DataFrame, pd.core.groupby.generic.DataFrameGroupBy],
    date_column: str,

    facet_ncol: int = 1,
    facet_nrow: Optional[int] = None,
    facet_scales: str = "free_y",
    facet_dir: str = "h",

    line_color: str = "#2c3e50",
    line_size: float = None,
    line_type: str = 'solid',
    line_alpha: float = 1.0,

    anom_color: str = "#E31A1C",
    anom_alpha: float = 1.0,
    anom_size: Optional[float] = None,

    ribbon_fill: str = "#646464",
    ribbon_alpha: float = 0.2,

    y_intercept: Optional[float] = None,
    y_intercept_color: str = "#2c3e50",
    x_intercept: Optional[str] = None,
    x_intercept_color: str = "#2c3e50",

    legend_show: bool = True,

    title: str = "Anomaly Plot",
    x_lab: str = "",
    y_lab: str = "",
    color_lab: str = "Legend",

    x_axis_date_labels: str = "%b %Y",
    base_size: float = 11,
    width: Optional[int] = None,
    height: Optional[int] = None,

):

    if isinstance(data, pd.core.groupby.generic.DataFrameGroupBy):

        group_names = data.grouper.names

        data = data.obj.copy()

        if not isinstance(group_names, list):
            group_names = [group_names]

        data[group_names] = data[group_names].astype(str)

        data["_group_names"] =  data[group_names].agg(" | ".join, axis=1)

    else:
        group_names = None
        data = data.copy()

    # 1.0 Canvas
    if group_names is not None:
        g = ggplot(
                data = data,
                mapping = aes(
                    x = date_column,
                    y = "observed",
                    group = "_group_names",
                )
            )

    else:
        g = ggplot(
            data = data,
            mapping = aes(
                x = date_column,
                y = "observed",
            )
        )

    # 2.0 Add facets
    if group_names is not None:
       g = g + facet_wrap(
            "_group_names",
            ncol = facet_ncol,
            nrow = facet_nrow,
            scales = facet_scales,
            dir = facet_dir,
            shrink = True
        )

    # 3.0 Add Ribbons
    g = g + geom_ribbon(
        mapping = aes(
            ymin = "recomposed_l1",
            ymax = "recomposed_l2",
        ),
        alpha = ribbon_alpha,
        fill  = ribbon_fill,
    )

    # 4.0 Add Lines
    g = g + \
        geom_line(
            color    = line_color,
            size     = line_size,
            linetype = line_type,
            alpha    = line_alpha
        )

    # 5.0 Add Anomalies
    if anom_size is None:
        anom_size = 2.0

    g = g + \
        geom_point(
            mapping = aes(
                x = date_column,
                y = "observed",
            ),
            color = anom_color,
            size = anom_size,
            alpha = anom_alpha,
            data = data.query("observed > recomposed_l2 | observed < recomposed_l1"),
        )

    # Add a Y-Intercept if desired
    if y_intercept is not None:
        g = g \
            + geom_hline(
                yintercept = y_intercept,
                color = y_intercept_color
        )

    # Add a X-Intercept if desired
    if x_intercept is not None:
        g = g \
            + geom_vline(
                xintercept = x_intercept,
                color = x_intercept_color
        )

    # Add theme & labs
    g = g + labs(x = x_lab, y = y_lab, title = title, color = color_lab)

    # Add scale to X
    g = g + scale_x_datetime(date_labels = x_axis_date_labels)

    # Add theme
    g = g + \
        theme_timetk(base_size=base_size, width = width, height = height)

    if not legend_show:
        g = g + theme(legend_position='none')

    return g


__author__ = 'qiong'

# key is a string
# return an integer
def hash(key):
    return sum([ord(c) for c in key])

class ListNode:
    def __init__(self, key, val):
        self.key = key
        self.val = val
        self.next = None

    # self node is the head of linkedlist and node to append to end
    def append(self, node):
        temp = self.next
        while temp:
            temp = temp.next
        temp.next = node

class HashMap:
    def __init__(self, n):
        if n<=0: raise ValueError
        self.capacity = n
        self.size = 0
        self.array = [None for i in range(n)]

    def get(self, key):
        idx = hash(key)%self.capacity
        for k, v in self.array[idx]:
            if k==key:
                return v
        return None

    def set(self, key, value):
        idx = hash(key)%self.capacity
        node = ListNode(key, value)
        if self.array[idx]==None:
            self.array[idx] = node
        else:
            # if node with the same key exists, update it
            temp = self.array[idx]
            while temp:
                if temp.key==key:
                    temp.value = value
                    break
                temp = temp.next
                self.size += 1
            temp.next = node

            if self.size>2*self.capacity:
                self.rehash(2*self.capacity)

    def delete(self, key):
        idx = hash(key)%self.capacity
        head = self.array[idx]
        self.remove(head, key)
        if self.size<self.capacity/2:
            self.rehash(self.capacity/2)

    def remove(self, head, key):
        if head:
            if head.key==key:
                self.head = self.head.next
            else:
                temp = head
                while temp.next:
                    if temp.next.key==key:
                        temp.next = temp.next.next
        return head

    def rehash(self, dest_capacity):
        result = [None for i in range(dest_capacity)]
        for node in self.array:
            temp = node
            while temp:
                idx = hash(temp.key)%dest_capacity
                if result[idx]==None:
                    result[idx]= node
                else:
                    result[idx].append(temp)

                temp = temp.next
        self.array = result


from random import randint

class Dice(object):
    def __init__(self, num=1, sides=6):
        self.num = num
        self.sides = sides
        self.values = []
        for _ in range(self.num):
            self.values.append(randint(1,self.sides))
        self.roll()

    def roll(self):
        for i in range(self.num):
            self.values[i] = randint(1, self.sides)


import visa

import argparse
import logging

from device import Device

logging.getLogger().setLevel(logging.INFO)

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--driver', default='', help="Set VISA driver ('@py' to use pyVISA-py)")
    parser.add_argument('--list', action='store_true', help="list resources and exit")
    args = parser.parse_args()

    # Detect resources
    rm = visa.ResourceManager(args.driver)
    resources = rm.list_resources()

    # List resources
    if args.list:
        for i, resource in enumerate(resources):
            print("{}: {}".format(i, resource))
        return 0

    # Create some devices
    devices = [
        Device("GPIB1::15::INSTR"),
        Device("GPIB1::16::INSTR"),
    ]

    # Perform some commands with instruments
    for device in devices:
        logging.info("********")
        if device.resource not in resources:
            logging.warning("%s not found", device)
        else:
            # Conenct with instrument
            device.connect(rm)
            logging.info("connected: %s", device.valid())
            # Get beeper state from device
            result = device.get_beeper()
            logging.info(result)
            # Get IDN from device
            result = device.get_idn()
            logging.info(result)
            # Query for IDN
            result = device.query("*IDN?")
            logging.info(result)
            # Write/read for IDN
            result = device.write("*IDN?")
            logging.info(result)
            result = device.read()
            logging.info(result)
            # Set beeper state to ON
            result = device.write(":SYSTem:BEEPer:STATe ON")
            logging.info(result)

    return 0

if __name__ == '__main__':
    main()


import re
from typing import List

from autoglossary.tokenizer import Tokenizer

class GlossaryLink:
    def __init__(self, start, end, glossary_item_id) -> None:
        self.start = start
        self.end = end
        self.span_info = f"""data-glossary-item-id="{glossary_item_id}">"""
        self.open_span = f"""<span class="abbr" {self.span_info}"""
        self.close_span = """"""

class GlossaryLinkInserter:
    def __init__(self, tokenizer: Tokenizer) -> None:
        self.tokenizer = tokenizer

    def html_insertion(self, html: str, glossary: dict) -> str:
        link_list = self._find_glossary(html, glossary)
        for link in link_list[::-1]:
            if not self._check_existing_span(self.tokens, link):
                self.tokens.insert(link.end, link.close_span)
                self.tokens.insert(link.start, link.open_span)
        return "".join(self.tokens)

    def _check_existing_span(self, tokens: List[str], link: GlossaryLink) -> bool:
        left_len = len(self.tokenizer.tokenize(link.span_info))
        right_len = len(self.tokenizer.tokenize(link.close_span))
        if ''.join(tokens[link.start - left_len:link.start])[-len(link.span_info):] == link.span_info \
            and ''.join(tokens[link.end:link.end + right_len])[:len(link.close_span)] == link.close_span:
            return True
        return False

    def _find_glossary(self, html: str, glossary: dict):
        self.tokens = self.tokenizer.tokenize(html)
        lemmatized_tokens = self.tokenizer.lemmatize(self.tokens)

        link_list = []
        i = 0
        while i < len(lemmatized_tokens):
            start, end = 0, 0
            if re.match(r"[\w]+", lemmatized_tokens[i]):
                for termin in glossary:
                    for j, termin_part in enumerate(termin):
                        while not re.match(r"[\w]+", lemmatized_tokens[i]):
                            i += 1

                        if lemmatized_tokens[i] == termin_part:
                            if start == 0:
                                start = i
                            i += 1
                        else:
                            break
                        if j == len(termin) - 1:
                            end = i
                            i -= 1
                            link_list.append(
                                GlossaryLink(start=start, end=end, glossary_item_id=glossary[termin])
                            )
            i += 1
        return link_list


from django.urls import path, include
from rest_framework.routers import DefaultRouter

from . import views

router = DefaultRouter()
router.register("article", views.ArticleViewSet, basename="viewset-article")
router.register("generic", views.ArticleGenericViewSet, basename="viewset-generic")

urlpatterns = [
    path("viewset/", include(router.urls)),
    path("article", views.ArticleListView.as_view(), name="article-list"),
    path("article/<int:pk>", views.ArticleDetailView.as_view(), name="article-detail"),
]


"""
На вход автоматически подаются две строки frac1 и frac2 вида a/b - дробь с числителем и знаменателем.
Напишите программу, которая должна возвращать сумму и произведение дробей.
Для проверки своего кода используйте модуль fractions.
"""

from fractions import Fraction

frac1 = "1/2"
frac2 = "1/3"

def sum_and_product(frac1, frac2):
    # Разделение строк на числитель и знаменатель
    numer1, denom1 = map(int, frac1.split('/'))
    numer2, denom2 = map(int, frac2.split('/'))

    # Вычисление суммы дробей
    sum_numer = numer1 * denom2 + numer2 * denom1
    sum_denom = denom1 * denom2

    # Вычисление произведения дробей
    prod_numer = numer1 * numer2
    prod_denom = denom1 * denom2

    # Приведение дробей к несократимому виду
    gcd_sum = gcd(sum_numer, sum_denom)
    sum_numer //= gcd_sum
    sum_denom //= gcd_sum
    gcd_prod = gcd(prod_numer, prod_denom)
    prod_numer //= gcd_prod
    prod_denom //= gcd_prod

    # Возвращение результатов в виде строк
    print(f"Сумма дробей: {sum_numer}/{sum_denom}")
    print(f"Произведение дробей: {prod_numer}/{prod_denom}")
    # return f"Сумма дробей: {sum_numer}/{sum_denom}\n", \
    #     f"Произведение дробей: {prod_numer}/{prod_denom}"

# Нахождение наибольшего общего делителя
def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

sum_and_product(frac1, frac2)

# Проверка кода
print("Сумма дробей:", Fraction(frac1) + Fraction(frac2))
print("Произведение дробей:", Fraction(frac1) * Fraction(frac2))


import torch
import numpy as np
import torch.nn as nn
import cv2
# from torchvision import transforms
import albumentations
import time

import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from geometry_msgs.msg import Twist
from cv_bridge import CvBridge

from road_segmentation import unet

transform = albumentations.Compose([
    albumentations.Resize(224, 224, always_apply=True),
    albumentations.Normalize(
            mean=[0.45734706, 0.43338275, 0.40058118],
            std=[0.23965294, 0.23532275, 0.2398498],
            always_apply=True)
])

# mean=[0.45734706, 0.43338275, 0.40058118]
# std=[0.23965294, 0.23532275, 0.2398498]

# pytransform = transforms.Compose([
#     transforms.Resize(224),
#     transforms.Normalize(mean=mean, std=std),
#     transforms.ToTensor(),
# ])

class RoadSegmentationNode(Node):
    def __init__(self):
        super().__init__('road_segmentation')
        self.segmentation_publisher_ = self.create_publisher(Image, '/segmentation/road', 2)
        self.image_subscriber = self.create_subscription(Image, '/video/front_camera', self.image_callback, 2)
        self.segmentation_timer = self.create_timer(.1, self.segmentation_callback)

        self.drive_commands_publisher = self.create_publisher(Twist, '/nav/cmd_vel', 2)
        self.drive_commands_timer = self.create_timer(.2, self.drive_commands_callback)

        self.bridge = CvBridge()
        self.image = np.zeros([320, 240, 3], dtype=np.uint8)

        self.Unet = unet.UNet(in_chans=3, depth=3, layers=1, skip_connection=True)
        self.Unet.load_state_dict(torch.load('/workspaces/isaac_ros-dev/src/road_segmentation/models/checkpoints/unet.pkl'))
        self.sigmoid = nn.Sigmoid()
        self.Unet.eval()
        self.center_line = 112.
        self.detected_center = 112.
        self.center_line_threshold = 16.

        if torch.cuda.is_available():
            self.device = torch.device('cuda:0')
        else:
            self.device = torch.device('cpu')
        print('using device:', self.device)

        self.Unet.to(self.device)

    def image_callback(self, msg):
        self.image = self.bridge.imgmsg_to_cv2(msg)

    def segmentation_callback(self):
        with torch.no_grad():
            try:
                # Do inference
                orig_frame = self.image.copy()
                orig_frame = cv2.resize(orig_frame, (224,224), interpolation = cv2.INTER_AREA)
                frame = cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB)
                frame = transform(image=frame)['image']
                frame = np.transpose(frame, (2, 0, 1))
                frame = torch.tensor(frame, dtype=torch.float32)
                frame = frame.unsqueeze(0).to(self.device)
                infer = self.Unet(frame).squeeze()
                infer = self.sigmoid(infer)

                infer = infer.detach().cpu().numpy()
                infer = np.where(infer >= .5, 0, 255).astype(np.uint8)
                # Generate intermediate image; use morphological closing to keep parts together
                inter = cv2.morphologyEx(infer, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))

                # Find largest contour in intermediate image
                cnts, _ = cv2.findContours(inter, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
                cnt = max(cnts, key=cv2.contourArea)

                # Create mask for detected road segment
                out = np.zeros(infer.shape, np.uint8)
                cv2.drawContours(out, [cnt], -1, 255, cv2.FILLED)
                out = cv2.bitwise_and(inter, out)
                out = cv2.cvtColor(out, cv2.COLOR_GRAY2BGR)

                # Find min and max detected road pixels in the y-axis, used for finding detected center of road
                detected_idxs = np.nonzero(out)
                y_idxs = detected_idxs[1]
                y_min = np.min(y_idxs)
                y_max = np.max(y_idxs)
                self.detected_center = (y_max + y_min) / 2

                # Combine images to visualization
                added_image = cv2.addWeighted(orig_frame,0.5,out,0.5,0)
                # Color "true centerline"
                added_image[:, int(self.center_line)] = [255,0,0]

                # Color detected centerline based on threshold, red if outside, green if inside threshold
                if abs(self.center_line - self.detected_center) > self.center_line_threshold:
                    added_image[:,self.detected_center.astype(int)] = [0,0,255]
                else:
                    added_image[:,self.detected_center.astype(int)] = [0,255,0]

                # publish image
                ros_image = self.bridge.cv2_to_imgmsg(added_image)
                self.segmentation_publisher_.publish(ros_image)

            except Exception as e:
                print(e)

    def drive_commands_callback(self):
        drive_twist = Twist()
        if abs(self.center_line - self.detected_center) > self.center_line_threshold:
            if self.center_line - self.detected_center > 0:
                # Steer right
                drive_twist.angular.z = .5
                drive_twist.linear.x = .25
            if self.center_line - self.detected_center < 0:
                # Steer left
                drive_twist.angular.z = -.5
                drive_twist.linear.x = .25
            self.drive_commands_publisher.publish(drive_twist)
        else:
            drive_twist.angular.z = 0.
            drive_twist.linear.x = .25
            self.drive_commands_publisher.publish(drive_twist)

def main(args=None):
    rclpy.init(args=args)
    road_segmentation_node = RoadSegmentationNode()
    rclpy.spin(road_segmentation_node)
    road_segmentation_node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()


import logging
import random

import netaddr
from sqlalchemy import orm
from sqlalchemy.orm import exc

from quantum.api.v2 import router as api_router
from quantum.common import exceptions as q_exc
from quantum.db import api as db
from quantum.db import models_v2
from quantum import quantum_plugin_base_v2

LOG = logging.getLogger(__name__)

class QuantumDbPluginV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
    """ A class that implements the v2 Quantum plugin interface
        using SQLAlchemy models.  Whenever a non-read call happens
        the plugin will call an event handler class method (e.g.,
        network_created()).  The result is that this class can be
        sub-classed by other classes that add custom behaviors on
        certain events.
    """

    def __init__(self):
        # NOTE(jkoelker) This is an incomlete implementation. Subclasses
        #                must override __init__ and setup the database
        #                and not call into this class's __init__.
        #                This connection is setup as memory for the tests.
        sql_connection = 'sqlite:///:memory:'
        db.configure_db({'sql_connection': sql_connection,
                         'base': models_v2.model_base.BASEV2})

    def _get_tenant_id_for_create(self, context, resource):
        if context.is_admin and 'tenant_id' in resource:
            tenant_id = resource['tenant_id']
        elif ('tenant_id' in resource and
              resource['tenant_id'] != context.tenant_id):
            reason = _('Cannot create resource for another tenant')
            raise q_exc.AdminRequired(reason=reason)
        else:
            tenant_id = context.tenant_id
        return tenant_id

    def _model_query(self, context, model):
        query = context.session.query(model)

        # NOTE(jkoelker) non-admin queries are scoped to their tenant_id
        if not context.is_admin and hasattr(model.tenant_id):
            query = query.filter(tenant_id=context.tenant_id)

        return query

    def _get_by_id(self, context, model, id, joins=(), verbose=None):
        query = self._model_query(context, model)
        if verbose:
            if verbose and isinstance(verbose, list):
                options = [orm.joinedload(join) for join in joins
                           if join in verbose]
            else:
                options = [orm.joinedload(join) for join in joins]
            query = query.options(*options)
        return query.filter_by(id=id).one()

    def _get_network(self, context, id, verbose=None):
        try:
            network = self._get_by_id(context, models_v2.Network, id,
                                      joins=('subnets',), verbose=verbose)
        except exc.NoResultFound:
            raise q_exc.NetworkNotFound(net_id=id)
        except exc.MultipleResultsFound:
            LOG.error('Multiple networks match for %s' % id)
            raise q_exc.NetworkNotFound(net_id=id)
        return network

    def _get_subnet(self, context, id, verbose=None):
        try:
            subnet = self._get_by_id(context, models_v2.Subnet, id,
                                     verbose=verbose)
        except exc.NoResultFound:
            raise q_exc.SubnetNotFound(subnet_id=id)
        except exc.MultipleResultsFound:
            LOG.error('Multiple subnets match for %s' % id)
            raise q_exc.SubnetNotFound(subnet_id=id)
        return subnet

    def _get_port(self, context, id, verbose=None):
        try:
            port = self._get_by_id(context, models_v2.Port, id,
                                   verbose=verbose)
        except exc.NoResultFound:
            # NOTE(jkoelker) The PortNotFound exceptions requires net_id
            #                kwarg in order to set the message correctly
            raise q_exc.PortNotFound(port_id=id, net_id=None)
        except exc.MultipleResultsFound:
            LOG.error('Multiple ports match for %s' % id)
            raise q_exc.PortNotFound(port_id=id)
        return port

    def _fields(self, resource, fields):
        if fields:
            return dict(((key, item) for key, item in resource.iteritems()
                         if key in fields))
        return resource

    def _get_collection(self, context, model, dict_func, filters=None,
                        fields=None, verbose=None):
        collection = self._model_query(context, model)
        if filters:
            for key, value in filters.iteritems():
                column = getattr(model, key, None)
                if column:
                    collection = collection.filter(column.in_(value))
        return [dict_func(c, fields) for c in collection.all()]

    @staticmethod
    def _generate_mac(context, network_id):
        # TODO(garyk) read from configuration file (CONF)
        max_retries = 16
        for i in range(max_retries):
            # TODO(garyk) read base mac from configuration file (CONF)
            mac = [0xfa, 0x16, 0x3e, random.randint(0x00, 0x7f),
                   random.randint(0x00, 0xff), random.randint(0x00, 0xff)]
            mac_address = ':'.join(map(lambda x: "%02x" % x, mac))
            if QuantumDbPluginV2._check_unique_mac(context, network_id,
                                                   mac_address):
                LOG.debug("Generated mac for network %s is %s",
                          network_id, mac_address)
                return mac_address
            else:
                LOG.debug("Generated mac %s exists. Remaining attempts %s.",
                          mac_address, max_retries - (i + 1))
        LOG.error("Unable to generate mac address after %s attempts",
                  max_retries)
        raise q_exc.MacAddressGenerationFailure(net_id=network_id)

    @staticmethod
    def _check_unique_mac(context, network_id, mac_address):
        mac_qry = context.session.query(models_v2.Port)
        try:
            mac_qry.filter_by(network_id=network_id,
                              mac_address=mac_address).one()
        except exc.NoResultFound:
            return True
        return False

    def _make_network_dict(self, network, fields=None):
        res = {'id': network['id'],
               'name': network['name'],
               'tenant_id': network['tenant_id'],
               'admin_state_up': network['admin_state_up'],
               'status': network['status'],
               'subnets': [subnet['id']
                           for subnet in network['subnets']]}

        return self._fields(res, fields)

    def _make_subnet_dict(self, subnet, fields=None):
        res = {'id': subnet['id'],
               'network_id': subnet['network_id'],
               'ip_version': subnet['ip_version'],
               'cidr': subnet['cidr'],
               'gateway_ip': subnet['gateway_ip']}
        return self._fields(res, fields)

    def _make_port_dict(self, port, fields=None):
        res = {"id": port["id"],
               "network_id": port["network_id"],
               'tenant_id': port['tenant_id'],
               "mac_address": port["mac_address"],
               "admin_state_up": port["admin_state_up"],
               "status": port["status"],
               "fixed_ips": [ip["address"] for ip in port["fixed_ips"]],
               "device_id": port["device_id"]}
        return self._fields(res, fields)

    def create_network(self, context, network):
        n = network['network']

        # NOTE(jkoelker) Get the tenant_id outside of the session to avoid
        #                unneeded db action if the operation raises
        tenant_id = self._get_tenant_id_for_create(context, n)
        with context.session.begin():
            network = models_v2.Network(tenant_id=tenant_id,
                                        name=n['name'],
                                        admin_state_up=n['admin_state_up'],
                                        status="ACTIVE")
            context.session.add(network)
        return self._make_network_dict(network)

    def update_network(self, context, id, network):
        n = network['network']
        with context.session.begin():
            network = self._get_network(context, id)
            network.update(n)
        return self._make_network_dict(network)

    def delete_network(self, context, id):
        with context.session.begin():
            network = self._get_network(context, id)

            filter = {'network_id': [id]}
            ports = self.get_ports(context, filters=filter)
            if ports:
                raise q_exc.NetworkInUse(net_id=id)

            subnets_qry = context.session.query(models_v2.Subnet)
            subnets_qry.filter_by(network_id=id).delete()
            context.session.delete(network)

    def get_network(self, context, id, fields=None, verbose=None):
        network = self._get_network(context, id, verbose=verbose)
        return self._make_network_dict(network, fields)

    def get_networks(self, context, filters=None, fields=None, verbose=None):
        return self._get_collection(context, models_v2.Network,
                                    self._make_network_dict,
                                    filters=filters, fields=fields,
                                    verbose=verbose)

    def create_subnet(self, context, subnet):
        s = subnet['subnet']

        if s['gateway_ip'] == api_router.ATTR_NOT_SPECIFIED:
            net = netaddr.IPNetwork(s['cidr'])
            s['gateway_ip'] = str(netaddr.IPAddress(net.first + 1))

        with context.session.begin():
            network = self._get_network(context, s["network_id"])
            subnet = models_v2.Subnet(network_id=s['network_id'],
                                      ip_version=s['ip_version'],
                                      cidr=s['cidr'],
                                      gateway_ip=s['gateway_ip'])

            context.session.add(subnet)
        return self._make_subnet_dict(subnet)

    def update_subnet(self, context, id, subnet):
        s = subnet['subnet']
        with context.session.begin():
            subnet = self._get_subnet(context, id)
            subnet.update(s)
        return self._make_subnet_dict(subnet)

    def delete_subnet(self, context, id):
        with context.session.begin():
            subnet = self._get_subnet(context, id)

            allocations_qry = context.session.query(models_v2.IPAllocation)
            allocations_qry.filter_by(subnet_id=id).delete()

            context.session.delete(subnet)

    def get_subnet(self, context, id, fields=None, verbose=None):
        subnet = self._get_subnet(context, id, verbose=verbose)
        return self._make_subnet_dict(subnet, fields)

    def get_subnets(self, context, filters=None, fields=None, verbose=None):
        return self._get_collection(context, models_v2.Subnet,
                                    self._make_subnet_dict,
                                    filters=filters, fields=fields,
                                    verbose=verbose)

    def create_port(self, context, port):
        p = port['port']
        # NOTE(jkoelker) Get the tenant_id outside of the session to avoid
        #                unneeded db action if the operation raises
        tenant_id = self._get_tenant_id_for_create(context, p)

        with context.session.begin():
            network = self._get_network(context, p["network_id"])

            # Ensure that a MAC address is defined and it is unique on the
            # network
            if p['mac_address'] == api_router.ATTR_NOT_SPECIFIED:
                p['mac_address'] = QuantumDbPluginV2._generate_mac(
                    context, p["network_id"])
            else:
                # Ensure that the mac on the network is unique
                if not QuantumDbPluginV2._check_unique_mac(context,
                                                           p["network_id"],
                                                           p['mac_address']):
                    raise q_exc.MacAddressInUse(net_id=p["network_id"],
                                                mac=p['mac_address'])

            port = models_v2.Port(tenant_id=tenant_id,
                                  network_id=p['network_id'],
                                  mac_address=p['mac_address'],
                                  admin_state_up=p['admin_state_up'],
                                  status="ACTIVE",
                                  device_id=p['device_id'])
            context.session.add(port)

            # TODO(anyone) ip allocation
            #for subnet in network["subnets"]:
            #    pass

        return self._make_port_dict(port)

    def update_port(self, context, id, port):
        p = port['port']
        with context.session.begin():
            port = self._get_port(context, id)
            port.update(p)
        return self._make_port_dict(port)

    def delete_port(self, context, id):
        with context.session.begin():
            port = self._get_port(context, id)

            allocations_qry = context.session.query(models_v2.IPAllocation)
            allocations_qry.filter_by(port_id=id).delete()

            context.session.delete(port)

    def get_port(self, context, id, fields=None, verbose=None):
        port = self._get_port(context, id, verbose=verbose)
        return self._make_port_dict(port, fields)

    def get_ports(self, context, filters=None, fields=None, verbose=None):
        return self._get_collection(context, models_v2.Port,
                                    self._make_port_dict,
                                    filters=filters, fields=fields,
                                    verbose=verbose)


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

"""Generating/updating project related files"""

import hashlib
import re
import os
import binascii
import datetime
import time
import hashlib

files = [
    'tournament.py',
    'tournament.sql',
    'tournament_test.py',
    'tournament_test_multi_tournaments.py',
    'README.md-template'
]

md5 = hashlib.md5()

file_index = []
for file_name in files:
    md5.update(open(file_name).read())
    file_index.append("`" + file_name + " (md5: " + binascii.hexlify(md5.digest()) + ")`")

genrated = datetime.datetime.now().isoformat()

readme_template = open("README.md-template").read()
readme = readme_template.format(
    files="* " + ("\n* ").join(file_index),
    genrated=genrated
)

readme_file = open("README.md","w+")
readme_file.write(readme)
readme_file.close()


from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.staticfiles.storage import staticfiles_storage
from django.views.generic import RedirectView, TemplateView

from rest_framework import routers

from games.views import IndexPage, SearchGameViewSet

router = routers.DefaultRouter()
router.register(r'search_game', SearchGameViewSet)

urlpatterns = [
    url(r'^$', IndexPage.as_view(), name='index'),
    url(r'^', include('games.urls', namespace='games')),
    url(r'^a441a4cc8871.html$',
        TemplateView.as_view(template_name='yandex.html')),
    url(r'^api/', include(router.urls, namespace='api')),
    url(r'^news/', include('news.urls', namespace='news')),
    url(r'^about/', include('pages.urls', namespace='pages')),
    url(r'^robots.txt$',
        TemplateView.as_view(template_name='robots.txt',
                             content_type='text/plain')),
    url(r'^favicon.ico$',
        RedirectView.as_view(url=staticfiles_storage.url('favicon.ico'),
                             permanent=True)),
    url(r'^admin/', include(admin.site.urls)),
]

if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [
        url(r'^__debug__/', include(debug_toolbar.urls)),
    ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)


from flask import Flask, render_template
import random
import datetime
import requests

app = Flask(__name__)

@app.route("/")
def home():
    random_number = random.randint(1, 10)
    current_year = datetime.datetime.now().year
    return render_template(
        "index.html", random_number=random_number, current_year=current_year
    )

@app.route("/guess/<name>")
def guess(name):
    name = name.capitalize()
    res = requests.get(url="https://api.genderize.io", params={"name": name})
    data = res.json()
    print(data)
    gender = data["gender"]
    res = requests.get(url="https://api.agify.io", params={"name": name})
    data = res.json()
    age = data["age"]
    return render_template("guess.html", name=name, gender=gender, age=age)

@app.route("/blog")
def get_blog():
    blog_url = "https://api.npoint.io/8ca3f3b91e6448ef25f1"
    response = requests.get(blog_url)
    all_posts = response.json()
    return render_template("blog.html", posts=all_posts)

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


import unittest

import numpy as np
from lsst.ts.wep.deblend.nelderMeadModify import feval, nelderMeadModify

class TestNelderMeadModify(unittest.TestCase):
    """Test the nelderMeadModify function."""

    def setUp(self):
        self.func = lambda x, y, c: abs(x**2 + y**2 - c)

    def testFunc(self):
        vars = (1, 2, 1)
        self.assertEqual(feval(self.func, vars), 4)

        xopt = nelderMeadModify(
            self.func,
            np.array([2.1]),
            args=(
                2,
                8,
            ),
        )
        self.assertEqual(xopt[0], 2)

if __name__ == "__main__":
    # Do the unit test
    unittest.main()


# Title: This is a solution to the n-Queens problem using backtracking
# Author: Pradeep Yadav
# Date: 03/01/2018
# Problem Statement: The N Queen is the problem of placing N chess queens on
# an N×N chessboard so that no two queens attack each other.

def isValid(board, row, col):
    # Function to check if a certain position is valid, given a particular
    # board configuration
    # Input: board: Current board configuration
    # row: row index to be checked
    # column: column index to be checked
    # Output: True, if current position does not have any conflict with other
    # queens.

    for rowIndex in range(len(board)):
        for colIndex in range(len(board)):
            if abs(rowIndex-row) == abs(colIndex-col):   # Diagonal test
                if board[rowIndex][colIndex] == 1:
                    return False
            elif colIndex == col:                        # Column test
                if board[rowIndex][colIndex] == 1:
                    return False
            elif rowIndex == row:                        # Row test
                if board[rowIndex][colIndex] == 1:
                    return False
    return True

def PrintBoard(board):
    # Function to print a given board configuration
    # Input: board: A given board configuration( board will contain False when
    # the board does not have a solution)
    # Output: Print out board configuration

    if board == False:
        print("No Solution Exist")
    else:
        for row in board:
            print(row)

def PlaceQueen(board, row):
    # Function to place a queen in a given row
    # Input: board: Current board configuration
    # row: Row in which queen needs to be placed
    # Output: returns board configuration in case a solution exists otherwise
    # return False

    if row == len(board):                # If all the queens are alredy placed
        return True
    else:
        flag = False
        for col in range(len(board)):
            if isValid(board, row, col): # check if the board position is valid
                board[row][col] = 1
                flag = PlaceQueen(board, row + 1) # recursive call for next row
                if flag == False:           # if attempt to place queen failed
                    board[row][col] = 0     # try next column
                    continue
                else:
                    # If all the queens are successfully placed on the board
                    # return board configuration
                    return board

        # Return false if unable to place queen
        return False

def nQueens(noQueens):
    # Function to initialize the board and start the placement of queens
    # Input: noQueens: Number of queens
    # Output: Board configuration in case of success otherwise False

    board = [[0]*noQueens for _ in range(noQueens)]
    return PlaceQueen(board,0)

def main():
    noQueens = int(input("Enter Number of Queens: "))
    boardSolution = nQueens(noQueens)
    PrintBoard(boardSolution)                # Printing out board configuration

if __name__ == "__main__":
    main()


import torch
import torch.nn.functional as F
from torch.optim.lr_scheduler import _LRScheduler

def adjust_learning_rate(
    optimizer, epoch, args, state, batch=None, nBatch=None
):
    if args.lr_schedule == "cos":
        raise NotImplementedError()
    elif args.lr_schedule == "step":
        if epoch in args.schedule:
            state["lr"] *= args.gamma
            for param_group in optimizer.param_groups:
                param_group["lr"] *= args.gamma
    else:
        raise ValueError()

class WarmUpLR(_LRScheduler):
    """warmup_training learning rate scheduler

    Args:
        optimizer: optimzier(e.g. SGD)
        total_iters: totoal_iters of warmup phase
    """

    def __init__(self, optimizer, total_iters, last_epoch=-1, start_lr=0.1):
        self.total_iters = total_iters
        self.start_lr = start_lr
        super().__init__(optimizer, last_epoch)

    def get_lr(self):
        """we will use the first m batches, and set the learning
        rate to base_lr * m / total_iters
        """
        ret = [
            (
                self.start_lr
                + (base_lr - self.start_lr)
                * self.last_epoch
                / (self.total_iters + 1e-8)
                if base_lr > self.start_lr
                else base_lr
            )
            for base_lr in self.base_lrs
        ]
        return ret

def label_smoothing_cross_entropy(
    pred, target, classes, dim, reduction="batchmean", smoothing=0.1
):
    """Implement a cross_entropy with label smoothing.

    adopted from https://github.com/OpenNMT/OpenNMT-py/blob/e8622eb5c6117269bb3accd8eb6f66282b5e67d9/onmt/utils/loss.py#L186
    and https://github.com/pytorch/pytorch/issues/7455
    """
    confidence = 1.0 - smoothing
    pred = pred.log_softmax(dim=dim)
    with torch.no_grad():
        true_dist = torch.zeros_like(pred)
        true_dist.fill_(smoothing / (classes - 1))
        true_dist.scatter_(1, target.data.unsqueeze(1), confidence)
    return F.kl_div(pred, true_dist, reduction=reduction)


from unittest import TestCase
import numpy as np
import matplotlib
from collections import OrderedDict
from CompartmentalSystems.ArrayDict import ArrayDict
import CompartmentalSystems.helpers_reservoir as hr

class TestArrayDict(TestCase):

    def test___getattribute__(self):
        ref_x = np.array([0, 1, 2, 3])
        ref_t = np.array([0, 1, 2, 3])
        ad = ArrayDict(
            {
                "t": ref_t,
                "x": ref_x
            }
        )
        self.assertTrue(np.allclose(ad.x, ref_x))

        self.assertTrue(np.allclose(ad['x'], ref_x))

    def test__fields(self):
        ref_x = np.array([0, 1, 2, 3])
        ref_t = np.array([0, 1, 2, 3])
        ad = ArrayDict(
            {
                "t": ref_t,
                "x": ref_x
            }
        )
        self.assertTrue(ad._fields == ad.keys())

    def test___add__(self):
        ref_x = np.array([0, 1, 2, 3])
        ref_t = np.array([0, 1, 2, 3])
        ad = ArrayDict(
            {
                "t": ref_t,
                "x": ref_x
            }
        )
        res = ad + ad
        self.assertTrue(np.all(res.x == ref_x + ref_x))
        self.assertTrue(np.all(res.t == ref_t + ref_t))

    def test___truediv__(self):
        ref_x = np.array([0, 1, 2, 3])
        ref_t = np.array([0, 1, 2, 3])
        ad = ArrayDict(
            {
                "t": ref_t,
                "x": ref_x
            }
        )
        res = ad / 2
        self.assertTrue(np.all(res.x == ref_x/2))
        self.assertTrue(np.all(res.t == ref_t/2))

    def test_averaged_values(self):
        ref_x = np.array([0, 1, 2, 3])
        ref_t = np.array([0, 1, 2, 3])
        ad = ArrayDict(
            {
                "t": ref_t,
                "x": ref_x
            }
        )
        res = ad.averaged_values([(0,2),(2,4)])
        self.assertTrue(np.all(res.x == np.array([0.5,2.5])))


"""
 @Author : cmingwhu
 @Datetime : 2019/06/06
 @File : BiLSTM_CRF.py
 @Contact : fccchengm@{zzu.edu.cn}
"""
import os
import pickle
import codecs
import numpy as np
import random

tag2label = {"O": 0,
             "B-PER": 1, "I-PER": 2,
             "B-LOC": 3, "I-LOC": 4,
             "B-ORG": 5, "I-ORG": 6
             }
# Conll2003_ner tags, BIO
tag2label_Conll2003 = {"O": 0,
                       "B-PER": 1, "I-PER": 2,
                       "B-LOC": 3, "I-LOC": 4,
                       "B-ORG": 5, "I-ORG": 6,
                       "B-MISC": 7, "I-MISC": 8,
                       "NUL": 9
                       }

# CCKS2017 tags, BIO
tag2label_CCKS17 = {"O": 0,
                  "B-SIGNS": 1, "I-SIGNS": 2,
                  "B-CHECK": 3, "I-CHECK": 4,
                  "B-DISEASE": 5, "I-DISEASE": 6,
                  "B-TREATMENT": 7, "I-TREATMENT": 8,
                  "B-BODY": 9, "I-BODY": 10
                    }

# CCKS2018 tags, BIO
tag2label_CCKS18 = {"O": 0,
                  "B-ANATOMICSITE": 1, "I-ANATOMICSITE": 2,
                  "B-SYMPTOMDES": 3, "I-SYMPTOMDES": 4,
                  "B-INDEPSYMPTOM": 5, "I-INDEPSYMPTOM": 6,
                  "B-DRUGS": 7, "I-DRUGS": 8,
                  "B-OPERATION": 9, "I-OPERATION": 10
                    }

# 默认数据集 MSRA tags, BIO
tag2label_msra = {"O": 0,
                  "B-PER": 1, "I-PER": 2,
                  "B-LOC": 3, "I-LOC": 4,
                  "B-ORG": 5, "I-ORG": 6
                  }

# 人民日报数据集
tag2label_chinadaily = {"O": 0,
                        "B-PERSON": 1, "I-PERSON": 2,
                        "B-LOC": 3, "I-LOC": 4,
                        "B-ORG": 5, "I-ORG": 6,
                        "B-GPE": 7, "I-GPE": 8,
                        "B-MISC": 9, "I-MISC": 10
                        }
# WeiboNER
tag2label_weibo_ner = {"O": 0,
                       "B-PER.NAM": 1, "I-PER.NAM": 2,
                       "B-LOC.NAM": 3, "I-LOC.NAM": 4,
                       "B-ORG.NAM": 5, "I-ORG.NAM": 6,
                       "B-GPE.NAM": 7, "I-GPE.NAM": 8,
                       "B-PER.NOM": 9, "I-PER.NOM": 10,
                       "B-LOC.NOM": 11, "I-LOC.NOM": 12,
                       "B-ORG.NOM": 13, "I-ORG.NOM": 14
                       }

# Resume_NER
tag2label_resume_ner = {"O": 0,
                        "B-NAME": 1, "M-NAME": 2, "E-NAME": 3, "S-NAME": 4,
                        "B-RACE": 5, "M-RACE": 6, "E-RACE": 7, "S-RACE": 8,
                        "B-CONT": 9, "M-CONT": 10, "E-CONT": 11, "S-CONT": 12,
                        "B-LOC": 13, "M-LOC": 14, "E-LOC": 15, "S-LOC": 16,
                        "B-PRO": 17, "M-PRO": 18, "E-PRO": 19, "S-PRO": 20,
                        "B-EDU": 21, "M-EDU": 22, "E-EDU": 23, "S-EDU": 24,
                        "B-TITLE": 25, "M-TITLE": 26, "E-TITLE": 27, "S-TITLE": 28,
                        "B-ORG": 29, "M-ORG": 30, "E-ORG": 32, "S-ORG": 33,
                        }

tag2label_mapping = {
    'MSRA': tag2label_msra,
    '人民日报': tag2label_chinadaily,
    'WeiboNER': tag2label_weibo_ner,
    'ResumeNER': tag2label_resume_ner,
    'CCKS17': tag2label_CCKS17,
    'CCKS18': tag2label_CCKS18,
    'Conll2003_NER':tag2label_Conll2003
}

def build_pretrained_words_embeddings(pretrained_emb_path, embeddings_path, word2id, embedding_dim):
    """
    load pretrained words embeddings
    :param pretrained_emb_path:
    :param embeddings_path:
    :param word2id:
    :param embedding_dim:
    :return:
    """
    pre_emb = {}
    for line in codecs.open(pretrained_emb_path, 'r', 'utf-8'):
        line = line.strip().split()
        if len(line) == embedding_dim + 1:
            pre_emb[line[0]] = [float(x) for x in line[1:]]
    word_ids = sorted(word2id.items(), key=lambda x: x[1])
    characters = [c[0] for c in word_ids]
    embeddings = list()
    for i, ch in enumerate(characters):
        if ch in pre_emb:
            embeddings.append(pre_emb[ch])
        else:
            embeddings.append(np.random.uniform(-0.25, 0.25, embedding_dim).tolist())
    embeddings = np.asarray(embeddings, dtype=np.float32)
    np.save(embeddings_path, embeddings)

def read_corpus(corpus_path):
    """
    read corpus and return the list of samples
    :param corpus_path:
    :return: data= (char,label)
    eg: 中 B-ORG
        国 O
    """
    data = []
    with open(corpus_path, encoding='utf-8') as fr:
        lines = fr.readlines()
    sent_, tag_ = [], []
    for line in lines:
        if line != '\n':
            [char, label] = line.strip().split()
            sent_.append(char)
            tag_.append(label)
        else:
            data.append((sent_, tag_))
            sent_, tag_ = [], []

    return data

def read_sentences(path, encoding="utf8"):
    """
    read sentences and labels from dataset
    :param path:
    :param encoding:
    :return:
    """
    with open(path) as fp:
        sentence = []
        sentences = []
        label = []
        labels = []
        for line in fp.readlines()[2:]:
            if line == '\n':
                sentences.append(sentence)
                labels.append(label)
                sentence = []
                label = []
            else:
                sentence.append(line.split()[0])
                label.append(line.split()[-1])
    return (sentences, labels)

def vocab_build(vocab_path, corpus_path,test_path, min_count=1, CE_Flag = '0'):
    """
    Chinese create vocabulary, word to id, word2id={[word, [word_id, word_freq]]}
    :param vocab_path:
    :param corpus_path:
    :param min_count:
    :return:
    """
    dataa = read_corpus(corpus_path)
    test_data = read_corpus(test_path)
    data = dataa+ test_data
    word2id = {}
    for sent_, tag_ in data:
        for word in sent_:
            if CE_Flag is '1':
                if word.isdigit():
                    word = '<NUM>'
                elif ('\u0041' <= word <= '\u005a') or ('\u0061' <= word <= '\u007a'):
                    word = '<ENG>'
                if word not in word2id:
                    word2id[word] = [len(word2id) + 1, 1]
                else:
                    word2id[word][1] += 1
            else:
                if word.isdigit():
                    word = '<NUM>'
                if word not in word2id:
                    word2id[word] = [len(word2id) + 1, 1]
                else:
                    word2id[word][1] += 1
    # delete words for word_freq <1
    low_freq_words = []
    for word, [word_id, word_freq] in word2id.items():
        if CE_Flag is '1':
            if word_freq < min_count and word != '<NUM>' and word != '<ENG>':
                low_freq_words.append(word)
        else:
            if word_freq < min_count and word != '<NUM>':
                low_freq_words.append(word)
    for word in low_freq_words:
        del word2id[word]

    new_id = 1
    for word in word2id.keys():
        word2id[word] = new_id
        new_id += 1
    word2id['<UNK>'] = new_id
    word2id['<PAD>'] = 0

    print(len(word2id))
    with open(vocab_path, 'wb') as fw:
        pickle.dump(word2id, fw)

def sentence2id(sent, word2id):
    """
    Based on transform sentence to id
    :param sent:
    :param word2id:
    :return: sentence2id
    """
    sentence_id = []
    for word in sent:
        if word.isdigit():
            word = '<NUM>'
        elif ('\u0041' <= word <= '\u005a') or ('\u0061' <= word <= '\u007a'):
            word = '<ENG>'
        if word not in word2id:
            word = '<UNK>'
        sentence_id.append(word2id[word])
    return sentence_id

def sentence2id_E(sent, word2id):
    """
    Based on transform sentence to id
    :param sent:
    :param word2id:
    :return: sentence2id
    """
    sentence_id = []
    for word in sent:
        if word.isdigit():
            word = '<NUM>'
        if word not in word2id:
            word = '<UNK>'
        sentence_id.append(word2id[word])
    return sentence_id

def read_dictionary(vocab_path):
    """
    read dictionary plk
    :param vocab_path:
    :return:
    """
    vocab_path = os.path.join(vocab_path)
    with open(vocab_path, 'rb') as fr:
        word2id = pickle.load(fr)
    print('vocab_size:', len(word2id))
    return word2id

def random_embedding(vocab, embedding_dim):
    """

    :param vocab:
    :param embedding_dim:
    :return:
    """
    embedding_mat = np.random.uniform(-0.25, 0.25, (len(vocab), embedding_dim))
    embedding_mat = np.float32(embedding_mat)
    return embedding_mat

def char_embedding_matrix(sentences, dim):
    """
    randomly initial char embedding
    :param sentences:
    :param d:
    :return:
    """
    chars = []
    chars_embedding = []
    char_id = {}
    for sentence in sentences:
        for word in sentence:
            for char in word:
                chars.append(char)
    chars = set(chars)
    #   add a null symbol for char padding to CNN to represent character-level---------------
    char_id['NUL'] = 0
    #   add a unknown symbol in case the test dataset appear the chars which are not appeared in training dataset
    char_id['<UNK>'] = len(chars) + 1
    chars_embedding.append(np.random.uniform(-np.sqrt(3.0 / 30), np.sqrt(3.0 / 30), (dim, 1)))
    for i, char in enumerate(chars):
        char_id[char] = i + 1
        chars_embedding.append(np.random.uniform(-np.sqrt(3.0 / 30), np.sqrt(3.0 / 30), (dim, 1)))
    chars_embedding.append(np.random.uniform(-np.sqrt(3.0 / 30), np.sqrt(3.0 / 30), (dim, 1)))
    chars_embedding = np.reshape(chars_embedding, [-1, dim])
    chars_embedding = chars_embedding.astype(np.float32)
    return (char_id, chars, chars_embedding)

def char2id(sent_, chars_vocab, max_word):
    """
    convert chars in batch sentences to ids
    :param char_id:
    :param vocabulary:
    :param X:
    :param max_sentence:
    :param max_word:
    :return:
    """
    X2id = []
    for word in sent_:
        char_index = []
        for char in word:
            if char.isdigit():
                char = '<NUM>'
            if char not in chars_vocab:
                char = '<UNK>'
            char_index.append(chars_vocab[char])
        char_index_ = char_index[:max_word] + [0] * max(max_word - len(char_index), 0)
        X2id.append(char_index_)
    return X2id

def build_label_ids(labels):
    """

    :param labels:
    :return:
    """
    label = []
    label_id = {}
    for sentence in labels:
        for word in sentence:
            label.append(word)
    label = set(label)
    #    label_num = len(label)
    label_id['NUL'] = 0
    for i, label in enumerate(label):
        label_id[label] = i + 1
    id_label = {v: k for k, v in label_id.items()}
    label_num = len(label_id.values())

    return (label_id, id_label, label_num)

def pad_sequences(sequences, pad_mark=0):
    """
    Filling sequences
    :param sequences:
    :param pad_mark:
    :return:
    """
    max_len = max(map(lambda x: len(x), sequences))
    seq_list, seq_len_list = [], []
    for seq in sequences:
        seq = list(seq)
        seq_ = seq[:max_len] + [pad_mark] * max(max_len - len(seq), 0)
        seq_list.append(seq_)
        seq_len_list.append(min(len(seq), max_len))
    return seq_list, seq_len_list

def pad_sequences_(sequences, words, max_word, pad_mark=0):
    """
    Filling sequences
    :param sequences:
    :param pad_mark:
    :return:
    """
    max_len = max(map(lambda x: len(x), sequences))
    seq_list,word_list, seq_len_list = [], [], []
    for seq in sequences:
        seq = list(seq)
        seq_ = seq[:max_len] + [pad_mark] * max(max_len - len(seq), 0)
        seq_list.append(seq_)
        seq_len_list.append(min(len(seq), max_len))
    tep = np.zeros(max_word,dtype=int).tolist()
    for cha in words:
        char_ind = []
        for cha1 in cha:
            char_ind.append(cha1)
        for l in range(max_len-len(char_ind)):
           char_ind.append(tep)
        word_list.append(char_ind)

    return seq_list, word_list, seq_len_list

def batch_yield(data, batch_size, vocab, tag2label, shuffle=False):
    """

    :param data:
    :param batch_size:
    :param vocab:
    :param tag2label:
    :param shuffle:
    :return:
    """
    if shuffle:
        random.shuffle(data)

    seqs, labels = [], []
    for (sent_, tag_) in data:
        sent_ = sentence2id(sent_, vocab)
        label_ = [tag2label[tag] for tag in tag_]

        if len(seqs) == batch_size:
            yield seqs, labels
            seqs, labels = [], []

        seqs.append(sent_)
        labels.append(label_)

    if len(seqs) != 0:
        yield seqs, labels

def batch_yield_(data, batch_size, vocab, chars_vocab, max_word, tag2label, shuffle=False):
    """

    :param data:
    :param batch_size:
    :param vocab:
    :param tag2label:
    :param shuffle:
    :return:
    """
    if shuffle:
        random.shuffle(data)

    seqs, words, labels = [], [], []
    for (sent_, tag_) in data:
        word_ = char2id(sent_, chars_vocab, max_word)
        sent_ = sentence2id_E(sent_, vocab)
        label_ = [tag2label[tag] for tag in tag_]

        if len(seqs) == batch_size:
            yield seqs, words, labels
            seqs, words, labels = [], [], []

        seqs.append(sent_)
        words.append(word_)
        labels.append(label_)

    if len(seqs) != 0:
        yield seqs, words, labels

if __name__ == '__main__':

    if not os.path.exists(os.path.join('data_path', 'CCKS17', 'word2id.pkl')):
        vocab_build(os.path.join('data_path', 'CCKS17', 'word2id.pkl'),
                    os.path.join('data_path', 'CCKS17',  'train_data.txt'))

    word2id = read_dictionary(os.path.join('data_path', 'CCKS17', 'word2id.pkl'))

    build_pretrained_words_embeddings('./data_path/sgns.wiki.char', './data_path/CCKS17/vectors.npy', word2id, 300)


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

import os
import time
import threading
import random
import gevent
import uuid
import sha
import logging
import functools
import contextlib

from sqlalchemy import event
from sqlalchemy import create_engine as sqlalchemy_create_engine
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
from sqlalchemy.orm import Session, scoped_session, sessionmaker
from sqlalchemy.exc import SQLAlchemyError

from .skt.env import is_in_dev
from .log import get_sql_logger
from .conf import settings
from .ctx import g

db_ctx = threading.local()
logger = logging.getLogger(__name__)

def scope_func():
    if not hasattr(db_ctx, 'session_stack'):
        db_ctx.session_stack = 0
    return (threading.current_thread().ident, db_ctx.session_stack)

@contextlib.contextmanager
def session_stack():
    if not hasattr(db_ctx, 'session_stack'):
        db_ctx.session_stack = 0

    try:
        db_ctx.session_stack += 1
        yield
    finally:
        db_ctx.session_stack -= 1

def close_connections(engines, transations):
    if engines and transations:
        for engine in engines:
            for parent in transations:
                conn = parent._connections.get(engine)
                if conn:
                    conn = conn[0]
                    conn.invalidate()

class RoutingSession(Session):
    _name = None

    def __init__(self, engines, *args, **kwds):
        super(RoutingSession, self).__init__(*args, **kwds)
        self.engines = engines
        self.slave_engines = [e for role, e in engines.items()
                              if role != 'master']
        assert self.slave_engines, ValueError("DB slave configs is wrong!")
        self._id = self.gen_id()
        get_sql_logger().ctx.current_session_id = self._id

    def get_bind(self, mapper=None, clause=None):
        if self._name:
            return self.engines[self._name]
        elif self._flushing:
            return self.engines['master']
        else:
            return random.choice(self.slave_engines)

    def using_bind(self, name):
        self._name = name
        return self

    def rollback(self):
        with gevent.Timeout(5):
            super(RoutingSession, self).rollback()

    def close(self):
        current_transations = tuple()
        if self.transaction is not None:
            current_transations = self.transaction._iterate_parents()
        try:
            with gevent.Timeout(5):
                super(RoutingSession, self).close()
        # pylint: disable=E0712
        except gevent.Timeout:
            # pylint: enable=E0712
            close_connections(self.engines.itervalues(), current_transations)
            raise

    def gen_id(self):
        pid = os.getpid()
        tid = threading.current_thread().ident
        clock = time.time() * 1000
        address = id(self)
        hash_key = self.hash_key
        return sha.new('{0}\0{1}\0{2}\0{3}\0{4}'.format(
            pid, tid, clock, address, hash_key)).hexdigest()[:20]

def patch_engine(engine):
    pool = engine.pool
    pool._origin_recyle = pool._recycle
    del pool._recycle
    setattr(pool.__class__, '_recycle', RecycleField())
    return engine

def make_session(engines, force_scope=False, info=None):
    if is_in_dev() or force_scope:
        scopefunc = scope_func
    else:
        scopefunc = None

    session = scoped_session(
        sessionmaker(
            class_=RoutingSession,
            expire_on_commit=False,
            engines=engines,
            info=info or {"name": uuid.uuid4().hex},
        ),
        scopefunc=scopefunc
    )
    return session

def create_engine(*args, **kwds):
    engine = patch_engine(sqlalchemy_create_engine(*args, **kwds))
    get_sql_logger().register(engine)
    event.listen(engine, 'before_cursor_execute', sql_commenter, retval=True)
    return engine

def gen_commit_deco(DBSession, raise_exc, error_code):
    def decorated(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            session = DBSession()
            try:
                ret = func(*args, **kwargs)
                session.flush()
                if not session.identity_map.values():
                    logger.warning("Session may have been closed")
                session.commit()
            except SQLAlchemyError as e:
                session.rollback()
                raise_exc(error_code, repr(e))
            finally:
                session.close()
            return ret
        return wrapper
    return decorated

def sql_commenter(conn, cursor, statement, params, context, executemany):
    if hasattr(g, 'call_meta_data') and 'request_id' in g.call_meta_data:
        request_id = g.get_call_meta('request_id')
        rpc_id = g.get_call_meta('seq')
        role = conn._execution_options.get('role', 'unknown')
        statement = "/* E:rid=%s&rpcid=%s&role=%s:E */ %s" % (
            request_id,
            rpc_id,
            role,
            statement
        )
    return statement, params

class ModelMeta(DeclarativeMeta):
    def __new__(self, name, bases, attrs):
        cls = DeclarativeMeta.__new__(self, name, bases, attrs)

        from .cache import CacheMixinBase
        for base in bases:
            if issubclass(base, CacheMixinBase) and hasattr(cls, "_hook"):
                cls._hook.add(cls)
                break
        return cls

def model_base():
    return declarative_base(metaclass=ModelMeta)

class RecycleField(object):
    def __get__(self, instance, klass):
        if instance is not None:
            return int(random.uniform(0.75, 1) * instance._origin_recyle)
        raise AttributeError

class DBManager(object):
    def __init__(self):
        self.session_map = {}

    def create_sessions(self):
        for db, db_configs in settings.DB_SETTINGS.iteritems():
            self.add_session(db, db_configs)

    def get_session(self, name):
        try:
            return self.session_map[name]
        except KeyError:
            raise KeyError(
                '`%s` session not created, check `DB_SETTINGS`' % name)

    def add_session(self, name, config):
        if name in self.session_map:
            raise ValueError("Duplicate session name {},"
                             "please check your config".format(name))
        session = self._make_session(name, config)
        self.session_map[name] = session
        return session

    @classmethod
    def _make_session(cls, db, config):
        urls = config['urls']
        pool_size = config.get('pool_size', settings.DB_POOL_SIZE)
        max_overflow = config.get(
            'max_overflow', settings.DB_MAX_OVERFLOW)
        pool_recycle = config.get(
            'pool_recycle', settings.DB_POOL_RECYCLE)
        engines = {
            role: cls.create_engine(
                dsn, pool_size=pool_size, max_overflow=max_overflow,
                pool_recycle=pool_recycle, execution_options={'role': role})
            for role, dsn in urls.iteritems()
        }
        return make_session(engines, info={"name": db})

    def close_sessions(self, should_close_connection=False):
        dbsessions = self.session_map
        for dbsession in dbsessions.itervalues():
            if should_close_connection:
                session = dbsession()
                if session.transaction is not None:
                    close_connections(session.engines.itervalues(),
                                      session.transaction._iterate_parents())
            try:
                dbsession.remove()
            except:
                logger.exception("Error closing session")

    @classmethod
    def create_engine(cls, *args, **kwds):
        engine = patch_engine(sqlalchemy_create_engine(*args, **kwds))
        get_sql_logger().register(engine)
        event.listen(engine, 'before_cursor_execute', sql_commenter,
                     retval=True)
        return engine

db_manager = DBManager()
db_manager.create_sessions()


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

# In[1]:

print('import modules ...')
import xarray as xr
import numpy  as np
import pandas as pd
from datetime import datetime
import calendar
import copy
import argparse

print('end import modules ...')

def get_argument():
    # define argument
    parser = argparse.ArgumentParser()
    parser.add_argument("--years", metavar='start year YYYY', help="start year", type=int, nargs=1, required=True)
    parser.add_argument("--yeare", metavar='end year YYYY', help="end year", type=int, nargs=1, required=True)
    parser.add_argument("--fileext", metavar='file extension', help="file extension 20602100-19792019 or 21602200-19792019", \
                                     type=str, nargs=1, required=True)
    return parser.parse_args()

args = get_argument()

# data dir path
cdir='./'

# list of file variables to process and the corresponding infile variables
#fvarlst_ano=['SNOW' ,'Q_1_5M','LW_TOTAL_DOWNWARD_SURFACE','P_SURF','SW_TOTAL_DOWNWARD_SURFACE','TOTAL_PRECIP','T_AIR_1_5M','U_10M','V_10M']
#cvarlst_ano=['dsnow','dq'    ,'dilr'                     ,'dp'    ,'dfield203'                ,'dprecip'     ,'dtemp'     ,'du'   ,   'dv']
#
#fvarlst_JRA=['prsn', 'huss'  ,'rlds'                     ,'psl'   ,'rsds'                     ,'tprecip'     ,'tas'       ,'uas'  ,'vas'  ]
#cvarlst_JRA=['prsn', 'huss'  ,'rlds'                     ,'psl'   ,'rsds'                     ,'tprecip'     ,'tas'       ,'uas'  ,'vas'  ]

fvarlst_ano=['T_AIR_1_5M']
cvarlst_ano=['dtemp'     ]

fvarlst_JRA=['tas']
cvarlst_JRA=['tas']

# input file name extension
cfin_ext=args.fileext[0]

yJRAs=args.years[0]
yJRAe=args.yeare[0]

# ## Add HadCM3 anomaly data to JRA data

# In[3]:

for ivar,fvar in enumerate(fvarlst_ano[0:1]):
    cvar_ano=cvarlst_ano[ivar]
    cvar_JRA=cvarlst_JRA[ivar]

    for year in range(yJRAs,yJRAe+1):
        year_out=year
        print('YEAR = ',year)
        print(datetime.now())
        # load data anomaly
        print('    load HadCM3 data ...')
        cfin_ano='./A1B_{}_3h_ano_{}_on_JRA_grid.NC'.format(fvar,cfin_ext)
        print('        file : {}'.format(cfin_ano))
        ds_ano = xr.open_dataset('./DATA_out/'+cfin_ano)

        # load JRA data
        print('    load JRA data '+str(year)+' ...')
        cfin_JRA='drowned_{}_JRA55_y{}.nc'.format(cvar_JRA,year)
        print('        file : {}'.format(cfin_JRA))
        ds_JRA = xr.open_dataset('./DATA_in/JRA/'+cfin_JRA)

        # if leap year repeat last frame 8 times (ie one day)
        if calendar.isleap(year):
            print('    year {} is a leap year, repeat last frame over 1 day ...'.format(year))
            ds_tmp=ds_ano.isel(time=slice(-1,None,1))
            ds_tmp['time']=ds_tmp['time']+pd.Timedelta(hours=3)
            ds_leap=copy.deepcopy(ds_tmp)
            for ih in range(7):
                ds_tmp['time']=ds_tmp['time']+pd.Timedelta(hours=3)
                ds_leap = xr.concat([ds_leap,ds_tmp],dim='time')

            ds_ano=xr.concat([ds_ano,ds_leap],dim='time')

        # add dataset
        print('    add anomaly to JRA data ...')
        ds_out = copy.deepcopy(ds_JRA)
        ds_out[cvar_JRA].values = ds_JRA[cvar_JRA].values + ds_ano[cvar_ano].values

        # correct attributes
        print('    update global attributes ...')
        ds_out.attrs['Description']='JRA data plus A1B HadCM3 {} anomaly ({}) creating by {}'.format(cfin_ext, cfin_ano, 'Add_A1B_HadCM3_anomaly_to_JRA_data.py')
        ds_out.attrs['Contact']='P. Mathiot (IGE)'
        ds_out.attrs['Creation date'] = '{}'.format(datetime.now())

        # write dataset
        cfout='drowned_{}_JRA55_perturbed_A1B_HadCM3_{}_anomaly_y{:d}.nc'.format(cvar_JRA,cfin_ext,year_out)
        print('    write output file ...')
        print('        file : ',cfout)
        ds_out.to_netcdf('DATA_out/JRA55_perturb/'+cfout)
        print()
        print()

print('DONE')


import datetime
from typing import List
from dataclasses import dataclass

@dataclass
class Order:
    order_id: int
    country: str
    order_at: datetime.datetime
    description: str
    element: List[str]

if __name__ == "__main__":
    order1 = Order(
        1,
        "USA",
        datetime.datetime.now(),
        "its a proper order",
        ["10 wines", "3 whisky"]
    )

    print(f"this is proper {order1}")

    order2 = Order(
        2.2,
        "USA",
        datetime.datetime.now(),
        "its a NOT proper order",
        ["10 wines", "3 whisky"]
    )

    print(f"this orderId is float : {order2}")

    order3 = Order(
        [3],
        "USA",
        datetime.datetime.now(),
        "its a NOT proper order",
        ["10 wines", "3 whisky"]
    )

    print(f"this orderId is list : {order3}")

    #dataclass is not helping when runtime


from random import randint
a = 0
while True:
    computer = randint(1, 49)
    # 抽出六組號碼
    if a == 0:
        num_1 = computer
        a += 1
        continue
    elif a == 1:
        num_2 = computer
        a += 1
        continue
    elif a == 2:
        num_3 = computer
        a += 1
        continue
    elif a == 3:
        num_4 = computer
        a += 1
        continue
    elif a == 4:
        num_5 = computer
        a += 1
        continue
    elif a == 5:
        num_6 = computer
        a += 1
        continue
        # 所有號碼都不重複
    elif (num_1 != num_2 and num_1 != num_3 and num_1 != num_4 and num_1 != num_5
          and num_1 != num_6 and num_2 != num_3 and num_2 != num_4
          and num_2 != num_5 and num_2 != num_6 and num_3 != num_4
          and num_3 != num_5 and num_3 != num_6 and num_4 != num_5
          and num_4 != num_6 and num_5 != num_6):
        break
        # 判斷號碼是否有重複
    elif (num_1 == num_2 or num_1 == num_3 or num_1 == num_4 or num_1 == num_5
          or num_1 == num_6 or num_2 == num_3 or num_2 == num_4
          or num_2 == num_5 or num_2 == num_6 or num_3 == num_4
          or num_3 == num_5 or num_3 == num_6 or num_4 == num_5
          or num_4 == num_6 or num_5 == num_6):
        num = sorted([num_1, num_2, num_3, num_4, num_5, num_6])  # sorted函数可对list进行排序
        print("號碼遇到重複:", num, )
        a = 0
        continue
print("發財號碼為:", [num_1, num_2, num_3, num_4, num_5, num_6])
num = sorted([num_1, num_2, num_3, num_4, num_5, num_6])   # sorted函数可对list进行排序
print("由小到大排列為:", num,)


from tkinter import *
import tkinter as tk

#   'criar janela'

root = tk.Tk()
root.grid_rowconfigure(0, weight=1)
root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=1)
root.grid_columnconfigure(2, weight=1)
root.grid_columnconfigure(3, weight=1)
root.grid_columnconfigure(4, weight=1)
root.grid_columnconfigure(5, weight=1)
root.grid_columnconfigure(6, weight=1)
root.grid_columnconfigure(7, weight=1)
root.grid_columnconfigure(8, weight=1)
root.grid_columnconfigure(9, weight=1)

#   'funçao'

var =StringVar()
def caps(*args):
    var.set(var.get().title())
var.trace("w", caps)

#   'configuraçoes janela'

root.configure(bg='black')
root.title('Cadastro')
frame1 = LabelFrame(root,text='Dados Pessoais:',bg='black',font=(30),foreground="white")
frame1.grid(row=0, column=0, sticky=NSEW)
frame2 = LabelFrame(root,text='Endereço:',bg='black',font=(30),foreground="white")
frame2.grid(row=1, column=0,sticky=NSEW)
frame3 = LabelFrame(root,text='',bg='black',font=(30),foreground="white")
frame3.grid(row=2, column=0,sticky=NSEW)

#   'Frame1'

lb1 = Label(frame1, text='Nome:',font='Bahnschrift',background='black',foreground="white").grid(row=0, column=0,sticky=EW)
in1 = Entry(frame1, font='Bahnschrift',textvariable=var).grid(row=0, column=1,sticky=EW,columnspan=5)

lb2 = Label(frame1, text='CPF:',font='Bahnschrift',background='black',foreground="white").grid(row=1, column=0,sticky=EW)
in2 = Entry(frame1, font='Bahnschrift').grid(row=1, column=1,sticky=EW)

lb3 = Label(frame1, text='Telefone:',font='Bahnschrift',background='black',foreground="white").grid(row=1, column=2,sticky=EW)
in3 = Entry(frame1, font='Bahnschrift').grid(row=1, column=3,sticky=EW)

lb4 = Label(frame1, text='Data Nasc:',font='Bahnschrift',background='black',foreground="white").grid(row=1, column=4,sticky=EW)
in4 = Entry(frame1, font='Bahnschrift').grid(row=1, column=5,sticky=EW)

#   'Frame2'

lb5 = Label(frame2, text='Rua:',font='Bahnschrift',background='black',foreground="white").grid(row=0, column=0,sticky=EW)
in5 = Entry(frame2, font='Bahnschrift').grid(row=0, column=1,sticky=EW,columnspan=7,ipadx=100)

lb6 = Label(frame2, text='N°:',font='Bahnschrift',background='black',foreground="white").grid(row=0, column=4,sticky=EW)
in6 = Entry(frame2, font='Bahnschrift').grid(row=0, column=5,sticky=EW)

lb7 = Label(frame2, text='Bairro:',font='Bahnschrift',background='black',foreground="white").grid(row=1, column=0,sticky=EW)
in7 = Entry(frame2, font='Bahnschrift').grid(row=1, column=1,sticky=EW)

lb8 = Label(frame2, text='Cidade',font='Bahnschrift',background='black',foreground="white").grid(row=1, column=2,sticky=EW)
in8 = Entry(frame2, font='Bahnschrift').grid(row=1, column=3,sticky=EW)

lb9 = Label(frame2, text='UF:',font='Bahnschrift',background='black',foreground="white").grid(row=1, column=4,sticky=EW)
in9 = Entry(frame2, font='Bahnschrift').grid(row=1, column=5,sticky=EW)

#   'Frame3'

Button(frame3,text='Gravar Dados',background='black',foreground="white").grid(sticky=EW)

Button(frame3,text='Listar Dados',background='black',foreground="white").grid(sticky=EW)

#   'Run'

root.mainloop()


import os
import sqlite3

conn = sqlite3.connect(os.environ["DATABASE_OF_IPS"].replace("\\","/"))
cursor = conn.cursor()

# Create the table
cursor.execute("CREATE TABLE IF NOT EXISTS ipinfo (ip TEXT PRIMARY KEY, dns_name TEXT)")

# Commit the changes
conn.commit()

# Close the connection
conn.close()

print("database loaded")


rows, cols = [int(el) for el in input().split()]

def init_matrix():

    matrix = []
    for _ in range(rows):
        row = [x for x in input().split()]
        matrix.append(row)
    return matrix

def chek_elements_equal(row, col, matr):
    curent_element = matr[row][col]
    next_element_same_row = matr[row][col]
    element_botom = matr[row][col]
    element_botom_right = matr[row + 1][col + 1]
    if curent_element == next_element_same_row and element_botom == element_botom_right:
        return True
    return False

matrix = init_matrix()

counter = 0
for row_index in range(rows-1):
    for col_index in range(cols-1):
        if chek_elements_equal(row_index, col_index, matrix):
            counter +=1

print(counter)

08.Exercise Multidimensional Lists/02. 2x2 Squares in Matrix.py