import math
import numpy as np
import matplotlib
import torch
from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
from matplotlib.patches import Arc

# https://stackoverflow.com/questions/34017866/arrow-on-a-line-plot-with-matplotlib
def add_arrow(line, position=None, direction='right', size=15, color=None, lw=2, alpha=1.0, text=None, text_offset=(0 , 0)):
    """
    add an arrow to a line.

    line:       Line2D object
    position:   x-position of the arrow. If None, mean of xdata is taken
    direction:  'left' or 'right'
    size:       size of the arrow in fontsize points
    color:      if None, line color is taken.
    """
    if color is None:
        color = line.get_color()

    xdata = line.get_xdata()
    ydata = line.get_ydata()

    if position is None:
        position = xdata.mean()
    # find closest index
    start_ind = np.argmin(np.absolute(xdata - position))
    if direction == 'right':
        end_ind = start_ind + 1
    else:
        end_ind = start_ind - 1

#     if end_ind > 1:
#         end_ind = 0
#     if end_ind < 0:
#         end_ind = 1

    line.axes.annotate('',
        xytext=(xdata[start_ind], ydata[start_ind]),
        xy=(xdata[end_ind], ydata[end_ind]),
        arrowprops=dict(arrowstyle="->", color=color, lw=lw, linestyle='--' if alpha < 1 else '-', alpha=alpha),
        size=size,
    )
    if text is not None:
        line.axes.annotate(text, color=color,
            xytext=(xdata[end_ind] + text_offset[0], ydata[end_ind] + text_offset[1]),
            xy=(xdata[end_ind], ydata[end_ind]),
            size=size,
        )

def sequence_pred(sbs_obj, X, directions=None, n_rows=2, n_cols=5):
    fig, axs = plt.subplots(n_rows, n_cols, figsize=(4*n_cols, 4*n_rows))
    axs = axs.flatten()

    for e, ax in enumerate(axs):
        first_corners = X[e, :2, :]
        sbs_obj.model.eval()
        next_corners = sbs_obj.model(X[e:e+1, :2].to(sbs_obj.device)).squeeze().detach().cpu().numpy()
        pred_corners = np.concatenate([first_corners, next_corners], axis=0)

        for j, corners in enumerate([X[e], pred_corners]):
            for i in range(4):
                coords = corners[i]
                color = 'k'
                ax.scatter(*coords, c=color, s=400)
                if i == 3:
                    start = -1
                else:
                    start = i
                if (not j) or (j and i):
                    ax.plot(*corners[[start, start+1]].T, c='k', lw=2, alpha=.5, linestyle='--' if j else '-')
                ax.text(*(coords - np.array([.04, 0.04])), str(i+1), c='w', fontsize=12)
                if directions is not None:
                    ax.set_title(f'{"Counter-" if not directions[e] else ""}Clockwise')

        ax.set_xlabel(r"$x_0$")
        ax.set_ylabel(r"$x_1$", rotation=0)
        ax.set_xlim([-1.45, 1.45])
        ax.set_ylim([-1.45, 1.45])

    fig.tight_layout()
    return fig

# https://stackoverflow.com/questions/25227100/best-way-to-plot-an-angle-between-two-lines-in-matplotlib
# https://gist.github.com/battlecook/0c0bdb7097ec7c8fa160e342b1bf51ef
def get_angle_plot(line1, line2, offset=1, color=None, origin=(0, 0), len_x_axis = 1, len_y_axis = 1):

    l1xy = line1.get_xydata()

    # Angle between line1 and x-axis
    slope1 = (l1xy[1][1] - l1xy[0][1]) / float(l1xy[1][0] - l1xy[0][0])
    angle1 = abs(math.degrees(math.atan(slope1))) # Taking only the positive angle

    l2xy = line2.get_xydata()

    # Angle between line2 and x-axis
    slope2 = (l2xy[1][1] - l2xy[0][1]) / float(l2xy[1][0] - l2xy[0][0])
    angle2 = abs(math.degrees(math.atan(slope2)))

    theta1 = min(angle1, angle2)
    theta2 = max(angle1, angle2)

    angle = theta2 - theta1

    if color is None:
        color = line1.get_color() # Uses the color of line 1 if color parameter is not passed.

    angle_plot = Arc(origin, len_x_axis*offset, len_y_axis*offset, 0, theta1, theta2, color=color, label = str(angle)+u"\u00b0")
    angle = angle_plot.get_label()[:-1] # Excluding the degree symbol
    angle_text = "%0.2f"%float(angle)+u"\u00b0" # Display angle upto 2 decimal places

    return angle_plot, angle_text

def make_line(ax, point):
    point = np.vstack([[0., 0.], np.array(point.squeeze().tolist())])
    line = ax.plot(*point.T, lw=0)[0]
    return line

def project_cosine(q, k):
    norm_q, norm_k = np.linalg.norm(q), np.linalg.norm(k)
    unit_q = q / norm_q
    unit_k = k / norm_k
    cos_theta = np.dot(unit_q, unit_k)
    unit_proj = cos_theta * unit_k

    fig, axs = plt.subplots(1, 3, figsize=(12, 4))

    ax = axs[0]
    line_q = make_line(ax, q)
    line_k = make_line(ax, k)
    add_arrow(line_q, lw=2, color='r', text=f'||Q||={norm_q:.2f}', size=12)
    add_arrow(line_k, lw=2, color='k', text=f'||K||={norm_k:.2f}', size=12, text_offset=(-.03, .02))
    circle1 = plt.Circle((0, 0), 1., color='k', fill=False, lw=2)
    ax.add_artist(circle1)

    angle_plot, angle_text = get_angle_plot(line_q, line_k, offset=.3, color='k')
    ax.add_patch(angle_plot) # To display the angle arc
    ax.text(.2, .2, angle_text)

    ax = axs[1]
    add_arrow(make_line(ax, q / norm_q), lw=2, color='r', text=r'$||\hat{Q}||=1$', size=12, alpha=.9, text_offset=(.02, .02))
    add_arrow(make_line(ax, k / norm_k), lw=2, color='k', text=r'$||\hat{K}||=1$', size=12, alpha=.9, text_offset=(.02, .02))
    circle2 = plt.Circle((0, 0), 1., color='k', fill=False, lw=2)
    ax.add_artist(circle2)

    angle_plot, angle_text = get_angle_plot(line_q, line_k, offset=.3, color='k')
    ax.add_patch(angle_plot) # To display the angle arc
    ax.text(.2, .2, angle_text)

    ax = axs[2]
    add_arrow(make_line(ax, q / norm_q), lw=2, color='r', text=r'$\hat{Q}$', size=12, alpha=.9, text_offset=(.02, .02))
    add_arrow(make_line(ax, k / norm_k), lw=2, color='k', text=r'$\hat{K}$', size=12, alpha=.9, text_offset=(.02, .02))
    circle3 = plt.Circle((0, 0), 1., color='k', fill=False, lw=2)
    ax.add_artist(circle3)
    add_arrow(make_line(ax, unit_proj), lw=2, color='r',
              text=r'$||\hat{Q}_\hat{K}||=cos\theta=' + f'{cos_theta:.2f}' + '$', size=12, alpha=.9, text_offset=(-.35, -.16))

    angle_plot, angle_text = get_angle_plot(line_q, line_k, offset=.3, color='k')
    ax.add_patch(angle_plot) # To display the angle arc
    ax.text(.2, .2, angle_text)

    ax.plot(*np.stack([q / norm_q, unit_proj]).T, lw=2, linestyle='--', color='gray')

    titles = [r'$Q\ and\ K$',
              r'$Unit\ Norm: \hat{Q}\ and\ \hat{K}$',
              r'$Projection: \hat{Q}_{\hat{K}}$']
    for i, ax in enumerate(axs):
        ax.set_ylim([0, 1.02])
        ax.set_xlim([0, 1.02])
        ax.set_xticklabels([0., .5, 1.0], fontsize=12)
        ax.set_yticks([0, .5, 1.0])
        ax.set_yticklabels([0., .5, 1.0], fontsize=12)
        ax.set_xlabel(r'$x_0$')
        ax.set_ylabel(r'$x_1$')
        ax.set_title(titles[i])

    fig.tight_layout()
    return fig

def project_cosine_scaling(q, k):
    norm_q, norm_k = np.linalg.norm(q), np.linalg.norm(k)
    unit_q = q / norm_q
    unit_k = k / norm_k
    cos_theta = np.dot(unit_q, unit_k)
    unit_proj = cos_theta * unit_k

    fig, axs = plt.subplots(1, 3, figsize=(12, 4))

    ax = axs[0]
    add_arrow(make_line(ax, unit_proj), lw=2, color='r',
              text=r'$cos\theta=' + f'{cos_theta:.2f}' + '$', size=12, alpha=.9, text_offset=(-.13, .03))

    ax = axs[1]
    add_arrow(make_line(ax, q), lw=2, color='r', text=f'||Q||={norm_q:.2f}', size=12)
    add_arrow(make_line(ax, unit_proj * norm_q), lw=2, color='r',
              text=r'$cos\theta\ ||Q||=' + f'{cos_theta*norm_q:.2f}' + '$', size=12, alpha=.9, text_offset=(-.18, .03))

    ax = axs[2]
    add_arrow(make_line(ax, q), lw=2, color='r', text=f'||Q||={norm_q:.2f}', size=12)
    add_arrow(make_line(ax, k), lw=2, color='k', text=f'||K||={norm_k:.2f}', size=12, text_offset=(-.03, .02))
    add_arrow(make_line(ax, unit_proj * norm_q * norm_k), lw=2, color='r',
              text=r'$cos\theta\ ||Q||\ ||K||=' + f'{cos_theta*norm_q*norm_k:.2f}' + '$',
              size=12, alpha=.9, text_offset=(-.23, -.13))

    titles = [r'$Projection: \hat{Q}_{\hat{K}}$',
              r'$Scaling\ by\ ||Q||$',
              r'$Scaling\ by\ ||K||$']
    for i, ax in enumerate(axs):
        ax.set_ylim([0, 1.02])
        ax.set_xlim([0, 1.02])
        ax.set_xticks([0, .5, 1.0])
        ax.set_xticklabels([0., .5, 1.0], fontsize=12)
        ax.set_yticks([0, .5, 1.0])
        ax.set_yticklabels([0., .5, 1.0], fontsize=12)
        ax.set_xlabel(r'$x_0$')
        ax.set_ylabel(r'$x_1$')
        ax.set_title(titles[i])

    fig.tight_layout()
    return fig

def query_and_keys(q, ks, result=None, ax=None):
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    else:
        fig = ax.get_figure()

    norm_q = np.linalg.norm(q)
    line_q = make_line(ax, q)

    line_k = []
    norm_k = []
    cos_k = []
    for k in ks:
        line_k.append(make_line(ax, k))
        norm_k.append(np.linalg.norm(k))
        cos_k.append(np.dot(q, k)/(norm_k[-1]*norm_q))

    add_arrow(line_q, lw=2, color='r', text=f'||Q||={norm_q:.2f}', size=12)
    add_arrow(line_k[0], lw=2, color='k', text=r'$||K_0' + f'||={norm_k[0]:.2f}$' + '\n' + r'$cos\theta_0=' + f'{cos_k[0]:.2f}$', size=12, text_offset=(-.33, .1))
    add_arrow(line_k[1], lw=2, color='k', text=r'$||K_1' + f'||={norm_k[1]:.2f}$' + '\n' + r'$cos\theta_1=' + f'{cos_k[1]:.2f}$', size=12, text_offset=(-.63, -.18))
    add_arrow(line_k[2], lw=2, color='k', text=r'$||K_2' + f'||={norm_k[2]:.2f}$' + '\n' + r'$cos\theta_2=' + f'{cos_k[2]:.2f}$', size=12, text_offset=(.05, .58))
    if result is not None:
#         add_arrow(line_q, lw=2, color='r', text=f'||Q||={norm_q:.2f}', size=12)
#         add_arrow(line_k0, lw=2, color='k', text=r'$||K_0' + f'||={norm_k0:.2f}$', size=12, text_offset=(-.2, .1))
#         add_arrow(line_k1, lw=2, color='k', text=r'$||K_1' + f'||={norm_k1:.2f}$', size=12, text_offset=(-.53, -.12))
#         add_arrow(line_k2, lw=2, color='k', text=r'$||K_2' + f'||={norm_k2:.2f}$', size=12, text_offset=(-.08, -.14))
        add_arrow(make_line(ax, result), lw=2, color='g', text=f'Context Vector', size=12, text_offset=(-.26, .1))
    circle1 = plt.Circle((0, 0), 1., color='k', fill=False, lw=2)
    ax.add_artist(circle1)

    ax.set_ylim([-1.02, 1.02])
    ax.set_xlim([-1.02, 1.02])

    ax.set_xticks([-1.0, 0, 1.0])
    ax.set_xticklabels([-1.0, 0, 1.0], fontsize=12)
    ax.set_yticks([-1.0, 0, 1.0])
    ax.set_yticklabels([-1.0, 0, 1.0], fontsize=12)
    ax.set_xlabel(r'$x_0$')
    ax.set_ylabel(r'$x_1$')
    ax.set_title(r'$Query\ and\ Keys$')
    fig.tight_layout()
    return fig

def plot_attention(model, inputs, point_labels=None, source_labels=None, target_labels=None, decoder=False, self_attn=False, n_cols=5, alphas_attr='alphas'):
    textcolors=["white", "black"]
    kw = dict(horizontalalignment="center", verticalalignment="center")
    valfmt = matplotlib.ticker.StrMethodFormatter("{x:.2f}")

    model.eval()
    device = list(model.parameters())[0].device.type
    predicted_seqs = model(inputs.to(device))
    alphas = model
    for attr in alphas_attr.split('.'):
        alphas = getattr(alphas, attr)
    if len(alphas.shape) < 4:
        alphas = alphas.unsqueeze(0)
    alphas = np.array(alphas.tolist())
    n_heads, n_points, target_len, input_len = alphas.shape

    if point_labels is None:
        point_labels = [f'Point #{i}' for i in range(n_points)]

    if source_labels is None:
        source_labels = [f'Input #{i}' for i in range(input_len)]

    if target_labels is None:
        target_labels = [f'Target #{i}' for i in range(target_len)]

    if self_attn:
        if decoder:
            source_labels = source_labels[-1:] + target_labels[:-1]
        else:
            target_labels = source_labels

    if n_heads == 1:
        n_rows = (n_points // n_cols) + int((n_points % n_cols) > 0)
    else:
        n_cols = n_heads
        n_rows = n_points

    fig, axs = plt.subplots(n_rows, n_cols, figsize=(n_cols*3, n_rows*3))

    for i in range(n_points):
        for head in range(n_heads):
            data = alphas[head][i].squeeze()
            if n_heads > 1:
                if n_points > 1:
                    ax = axs[i, head]
                else:
                    ax = axs[head]
            else:
                ax = axs.flat[i]

            im = ax.imshow(data, vmin=0, vmax=1, cmap=plt.cm.gray)
            ax.grid(False)

            #ax.set_xticks(np.arange(data.shape[1]+1)-.5, minor=True)
            #ax.set_yticks(np.arange(data.shape[0]+1)-.5, minor=True)

            ax.set_xticks(np.arange(data.shape[1]))
            ax.set_yticks(np.arange(data.shape[0]))

            ax.set_xticklabels(source_labels)
            if n_heads == 1:
                ax.set_title(point_labels[i], fontsize=14)
            else:
                if i == 0:
                    ax.set_title(f'Attention Head #{head+1}', fontsize=14)
                if head == 0:
                    ax.set_ylabel(point_labels[i], fontsize=14)

            ax.set_yticklabels([])
            if n_heads == 1:
                if not (i % n_cols):
                    ax.set_yticklabels(target_labels)
            else:
                if head == 0:
                    ax.set_yticklabels(target_labels)

            ax.set_xticks(np.arange(data.shape[1]+1)-.5, minor=True)
            ax.set_yticks(np.arange(data.shape[0]+1)-.5, minor=True)

            ax.tick_params(top=True, bottom=False, labeltop=True, labelbottom=False)

            threshold = im.norm(data.max())/2.
            for ip in range(data.shape[0]):
                for jp in range(data.shape[1]):
                    kw.update(color=textcolors[int(im.norm(data[ip, jp]) > threshold)])
                    text = im.axes.text(jp, ip, valfmt(data[ip, jp], None), **kw)

    fig.subplots_adjust(wspace=0.8, hspace=1.0)
    fig.tight_layout()
    return fig

def figure9():
    english = ['the', 'European', 'economic', 'zone']
    french = ['la', 'zone',  'économique', 'européenne']

    source_labels = english
    target_labels = french

    data = np.array([[.8, 0, 0, .2],
                     [0, 0, 0, 1],
                     [0, 0, 1, 0],
                     [0, .8, 0, .2]])

    fig, ax = plt.subplots(1, 1, figsize=(5, 5))
    im = ax.imshow(data, vmin=0, vmax=1, cmap=plt.cm.gray)
    ax.grid(False)

    ax.set_xticks(np.arange(data.shape[1]))
    ax.set_yticks(np.arange(data.shape[0]))

    ax.set_xticklabels(source_labels, rotation=90)

    ax.set_yticklabels([])
    ax.set_yticklabels(target_labels)

    ax.set_xticks(np.arange(data.shape[1]+1)-.5, minor=True)
    ax.set_yticks(np.arange(data.shape[0]+1)-.5, minor=True)

    ax.tick_params(top=True, bottom=False, labeltop=True, labelbottom=False)

    textcolors=["white", "black"]
    kw = dict(horizontalalignment="center", verticalalignment="center")
    valfmt = matplotlib.ticker.StrMethodFormatter("{x:.2f}")

    threshold = im.norm(data.max())/2.
    for ip in range(data.shape[0]):
        for jp in range(data.shape[1]):
            kw.update(color=textcolors[int(im.norm(data[ip, jp]) > threshold)])
            text = im.axes.text(jp, ip, valfmt(data[ip, jp], None), **kw)

    fig.tight_layout()
    return fig

def plot_dial(xs, ys, seq, dim, scale, ax, has_coords=False):
    point = np.array([xs[1, 0], ys[1, 0]])
    point = np.vstack([point*.9, point*1.1])
    line_tick = ax.plot(*point.T, lw=2, c='k')[0]
    line_zero = ax.plot([0.9, 1.1], [0, 0], lw=2, c='k')[0]

    q = np.array([xs[seq, dim], ys[seq, dim]])

    line_q = make_line(ax, q*.95)
    add_arrow(line_q, lw=2, color='r', text='', size=12)
    circle1 = plt.Circle((0, 0), 1., color='k', fill=False, lw=2)
    ax.add_artist(circle1)

    ax.set_ylim([-1.1, 1.1])
    ax.set_xlim([-1.1, 1.1])
    ax.grid(False)
    ax.text(xs[1, 0]+np.sign(xs[1, 0])*.1-.2, ys[1, 0]+(.15 if ys[1,0]>.001 else -.05), scale)
    ax.text(1.2, -.05, '0')
    if has_coords:
        ax.set_xlabel(f'({ys[seq, dim]:.2f}, {xs[seq, dim]:.2f})')
    ax.set_xticks([])
    ax.set_yticks([])

def plot_text(x, y, text, ax, fontsize=24):
    ax.text(x, y, text, fontsize=fontsize)
    ax.grid(False)
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_ylim([-1, 1])
    ax.set_xlim([-1, 1])

def gen_coords(d_model, max_len, exponent=10000):
    position = torch.arange(0, max_len).float().unsqueeze(1)
    angular_speed = torch.exp(torch.arange(0, d_model, 2).float() * (-np.log(exponent) / d_model))
    return np.cos(position * angular_speed), np.sin(position * angular_speed)

def encoding_degrees(dims, seqs, tot):
    fig, axs = plt.subplots(dims+1, tot+1, figsize=(2*(tot+1), 2*(1+dims)))
    axs = np.atleast_2d(axs)
    for dim in range(dims):
        xs, ys = np.cos(np.linspace(0, tot/seqs[dim], tot+1)*2*np.pi).reshape(-1, 1), np.sin(np.linspace(0, tot/seqs[dim], tot+1)*2*np.pi).reshape(-1, 1)
        for seq in range(tot):
            plot_text(-.1, -.5, seq, axs[0, seq+1])
            plot_text(-.5, -.5, 'Position', axs[0, 0])
            if seq == 0:
                plot_text(-.5, -.2, f'Base {seqs[dim]}', axs[dim+1, 0])
                plot_text(-.5, -1.3, f'(sine, cosine)', axs[dim+1, 0], fontsize=16)
            plot_dial(xs, ys, seq=seq, dim=0, scale=f'1/{seqs[dim]}', ax=axs[dim+1, seq+1], has_coords=True)
        seqs *= 2

    fig.tight_layout()
    return fig

def exponential_dials(d_model, max_len):
    xs, ys = gen_coords(d_model, max_len)
    dims = int(d_model/2)
    seqs = max_len
    fig, axs = plt.subplots(dims+1, seqs+1, figsize=(2*(1+seqs), 2*(1+dims)))
    axs = np.atleast_2d(axs)
    for seq in range(seqs):
        plot_text(-.1, -.5, seq, axs[0, seq+1])
        plot_text(-.5, -.5, 'Position', axs[0, 0])
        for dim in range(dims):
            scale = 10**dim
            if seq == 0:
                plot_text(-.5, -.2, f'Dims #{2*dim},#{2*dim+1}', axs[dim+1, 0], fontsize=16)
                plot_text(-.5, -1.35, f'(sine, cosine)', axs[dim+1, 0], fontsize=16)
            plot_dial(xs, ys, seq=seq, dim=dim, scale=scale, ax=axs[dim+1, seq+1], has_coords=True)

    fig.tight_layout()
    return fig

def plot_mesh(values, ax, showvals=False, colorbar=False, ylabel=None):
    max_len, d_model = values.squeeze().shape
    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(12, 4))
    else:
        fig = ax.get_figure()
    im = ax.pcolormesh(values.T, cmap='viridis')
    if ylabel is None:
        ylabel = 'Dimensions'
    ax.set_ylabel(ylabel)
    ax.set_ylim((d_model-.5, 0))
    ax.set_yticks(np.arange(d_model+1, -1, -1)-.5)
    ax.set_yticklabels([''] + list(range(d_model-1, -1, -1)) + [''])
    ax.set_xlabel('Positions')
    ax.set_xlim((0, max_len))
    ax.set_xticks(np.arange(0, max_len+1)-.5)
    ax.set_xticklabels([''] + list(range(0, max_len)))
    if colorbar:
        plt.colorbar(im)

    if showvals:
        textcolors=["white", "black"]
        kw = dict(horizontalalignment="center", verticalalignment="center")
        valfmt = matplotlib.ticker.StrMethodFormatter("{x:.2f}")
        threshold = im.norm(values.max())/2.
        for ip in range(values.shape[0]):
            for jp in range(values.shape[1]):
                kw.update(color=textcolors[int(im.norm(values[ip, jp]) > threshold)])
                text = im.axes.text(jp+.5, ip+.5, valfmt(values[ip, jp], None), **kw)

    fig.tight_layout()
    return fig

def encoding_heatmap(d_model, max_len):
    position = torch.arange(0, max_len).float().unsqueeze(1)
    angular_speed = torch.exp(torch.arange(0, d_model, 2).float() * (-np.log(10000.0) / d_model))

    encoding = torch.zeros(max_len, d_model)
    encoding[:, 0::2] = torch.sin(angular_speed * position)
    encoding[:, 1::2] = torch.cos(angular_speed * position)

    fig, axs = plt.subplots(2, 2, figsize=(14, 8))

    sines = torch.sin(angular_speed * position)
    cosines = torch.cos(angular_speed * position)

    axs = axs.flatten()
    axs[0].plot(sines)
    axs[0].set_title('Sines - Even Dimensions')
    axs[0].legend(["dim %d" % p for p in range(0, 8, 2)], loc='lower left')

    axs[1].plot(cosines)
    axs[1].set_title('Cosines - Odd Dimensions')
    axs[1].legend(["dim %d" % p for p in range(1, 9, 2)], loc='lower left')

    values = np.zeros((max_len, d_model))
    values.fill(np.nan)
    values[:, 0::2] = sines

    fig = plot_mesh(values, axs[2])

    values = np.zeros((max_len, d_model))
    values.fill(np.nan)
    values[:, 1::2] = cosines
    fig = plot_mesh(values, axs[3])

    return fig


#!/usr/bin/env python

import csv

import numpy as np

from mylib.util import cross_val_split
from mylib.linear_model import LogisticRegression

def iris():
    np.seterr(over='ignore', invalid='ignore')
    print('在iris.data上验证：')

    m = 150
    dataset = np.zeros((m, 5))

    # load dataset
    with open('./dataset/iris.data.csv', 'r') as fd:
        rows = csv.reader(fd)
        for i, row in enumerate(rows):
            for j in range(4):
                dataset[i][j] = row[j]
            if row[4] == 'Iris-setosa':
                dataset[i][4] = 1
            elif row[4] == 'Iris-versicolor':
                dataset[i][4] = 2
            else:
                dataset[i][4] = 3

    np.random.shuffle(dataset)
    X = dataset[:, :4]
    y = dataset[:, 4]

    rate = [0] * 10
    k = 0
    for train_X, train_y, test_X, test_y in cross_val_split(X, y, k=10):
        print('10折交叉验证，第{}轮'.format(k + 1))
        # train
        cls1_X = train_X[train_y == 1]
        cls2_X = train_X[train_y == 2]
        cls3_X = train_X[train_y == 3]

        setosa_versicolor_model = LogisticRegression()
        versicolor_virginica_model = LogisticRegression()
        virginica_setosa_model = LogisticRegression()

        X1 = np.concatenate((cls1_X, cls2_X))
        X2 = np.concatenate((cls2_X, cls3_X))
        X3 = np.concatenate((cls3_X, cls1_X))

        y1 = np.concatenate((np.ones((len(cls1_X),)), np.zeros((len(cls2_X),))))
        y2 = np.concatenate((np.ones((len(cls2_X),)), np.zeros((len(cls3_X),))))
        y3 = np.concatenate((np.ones((len(cls3_X),)), np.zeros((len(cls1_X),))))

        setosa_versicolor_model.fit(X1, y1)
        versicolor_virginica_model.fit(X2, y2)
        virginica_setosa_model.fit(X3, y3)

        # test
        n = 0
        for i, x in enumerate(test_X):
            vote = [0, 0, 0]

            if setosa_versicolor_model.predict(x):
                vote[0] += 1
            else:
                vote[1] += 1

            if versicolor_virginica_model.predict(x):
                vote[1] += 1
            else:
                vote[2] += 1

            if virginica_setosa_model.predict(x):
                vote[2] += 1
            else:
                vote[0] += 1

            cls = vote.index(max(vote)) + 1
            if cls != test_y[i]:
                n += 1
        rate[k] = n / len(test_y)
        print('错误数量：{}/{}'.format(n, len(test_y)))
        k += 1
    print('10折交叉验证结束，平均错误率：{:.2f}%'.format(sum(rate) * 10))

def wine():
    np.seterr(over='ignore', invalid='ignore')
    print('在wine.data上验证：')

    # load dataset
    dataset = np.loadtxt('./dataset/wine.data.csv', delimiter=",")
    np.random.shuffle(dataset)
    X = dataset[:, 1:]
    y = dataset[:, 0]

    rate = [0] * 10
    k = 0
    for train_X, train_y, test_X, test_y in cross_val_split(X, y, k=10):
        print('10折交叉验证，第{}轮'.format(k + 1))
        # train
        cls1_X = train_X[train_y == 1]
        cls2_X = train_X[train_y == 2]
        cls3_X = train_X[train_y == 3]

        model_1_2 = LogisticRegression()
        model_2_3 = LogisticRegression()
        model_3_1 = LogisticRegression()

        X1 = np.concatenate((cls1_X, cls2_X))
        X2 = np.concatenate((cls2_X, cls3_X))
        X3 = np.concatenate((cls3_X, cls1_X))

        y1 = np.concatenate((np.ones((len(cls1_X),)), np.zeros((len(cls2_X),))))
        y2 = np.concatenate((np.ones((len(cls2_X),)), np.zeros((len(cls3_X),))))
        y3 = np.concatenate((np.ones((len(cls3_X),)), np.zeros((len(cls1_X),))))

        model_1_2.fit(X1, y1)
        model_2_3.fit(X2, y2)
        model_3_1.fit(X3, y3)

        # test
        n = 0
        for i, x in enumerate(test_X):
            vote = [0, 0, 0]

            if model_1_2.predict(x):
                vote[0] += 1
            else:
                vote[1] += 1

            if model_2_3.predict(x):
                vote[1] += 1
            else:
                vote[2] += 1

            if model_3_1.predict(x):
                vote[2] += 1
            else:
                vote[0] += 1

            cls = vote.index(max(vote)) + 1
            if cls != test_y[i]:
                n += 1
        rate[k] = n / len(test_y)
        print('错误数量：{}/{}'.format(n, len(test_y)))
        k += 1
    print('10折交叉验证结束，平均错误率：{:.2f}%'.format(sum(rate) * 10))

def main():
    iris()
    print()
    wine()

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
"""
Author: [Yunting Chiu](https://www.linkedin.com/in/yuntingchiu/)
"""

import cv2
import matplotlib.pyplot as plt
import numpy as np
import time
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler # standardize features by removing the mean and scaling to unit variance.
from sklearn.metrics import confusion_matrix
#from sklearn.metrics import plot_confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.model_selection import GridSearchCV

# Exploratory Data Analysis
##Read the data (`.npz` file)

data_zipped = np.load("np_data_all.npz", allow_pickle=True)

for item in data_zipped.files:
    print(item)
    print(data_zipped[item])

#print(data_zipped[item].shape)
data = data_zipped[item]

"""## Check the length of $X$ and $y$"""

X = []
y = []
for i in data:
  X.append(i[0])
  y.append(i[1])
print("The length of X feature is", len(X[1]))

print("The length should be " + str((6984+7000)))
print("data dimension:",data.shape)

"""## Visualization"""

fake_cnt = 0
real_cnt = 0
for i in data:
  if i[1] == "fake":
    fake_cnt += 1
  else:
    real_cnt += 1

#print(fake_cnt)
#print(real_cnt)
df = [['fake', fake_cnt], ['real', real_cnt]]
df = pd.DataFrame(df, columns=['image_type', 'count'])
#ax = df.plot.bar(x='video_type', y='count', rot=0)
fig = plt.figure()
plt.bar(df['image_type'], df['count'])
plt.xlabel("Image Type")
plt.ylabel("Count")
plt.savefig('10.count_type.png')

"""# Machine Learning Task

"""## Random Forest Classifier"""

start_time = time.time()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42) # 80% for training, 20 for of testing

### Cross vaildation procedure and define a classifier
cv_inner = KFold(n_splits=5, shuffle=True, random_state=100)
rf_clf = RandomForestClassifier(random_state=42, bootstrap=True)

# define search space
# n_estimators: The number of trees in the forest.
space = {}
space['n_estimators'] = [100, 500, 1000, 2000]
space['max_depth'] = [0, 100, 500, 1000, 2000, None]
space['min_samples_leaf'] = [100, 500, 1000]
space['min_samples_split'] = [100, 500, 1000]

# define search
search = GridSearchCV(rf_clf, space, scoring='accuracy', n_jobs=1, cv=cv_inner)
result = search.fit(X_train, y_train)
print(search.best_params_)
best_model = result.best_estimator_
print("Best Model: {}".format(best_model))

# evaluate model on the hold out dataset
y_pred = best_model.predict(X_test)
print("--- %s seconds ---" % (time.time() - start_time))
print("----------Confusion Matrix----------------")
print(confusion_matrix(y_test, y_pred))

### RF Confusion Matrix

#plot_confusion_matrix(svm_clf, X_test, y_test, values_format = '.0f')
#plt.figure(figsize=(12,8))
#plt.show()
conf_matrix = confusion_matrix(y_true = y_test, y_pred = y_pred)

# Print the confusion matrix using Matplotlib

fig, ax = plt.subplots(figsize=(7.5, 7.5))
ax.matshow(conf_matrix, cmap=plt.cm.Blues, alpha=0.3)
for i in range(conf_matrix.shape[0]):
    for j in range(conf_matrix.shape[1]):
        ax.text(x=j, y=i,s=conf_matrix[i, j], va='center', ha='center', size='xx-large')

plt.xlabel('Predictions', fontsize=18)
plt.ylabel('Actuals', fontsize=18)
plt.title('Confusion Matrix', fontsize=18)
plt.show()
plt.savefig('10.confusion_matrix.png')

### RF Accuracy Score

print("----------Accuracy Score----------------")
print(accuracy_score(y_test, y_pred))

print("------------Classification Report----------")
target_names = ['fake', 'real']
print(classification_report(y_test, y_pred, target_names=target_names))

# References
# https://machinelearningmastery.com/nested-cross-validation-for-machine-learning-with-python/
# https://towardsdatascience.com/hyperparameter-tuning-the-random-forest-in-python-using-scikit-learn-28d2aa77dd74


word = input()
n = int(input())
words = []
for i in range(n):
	words.append(input())

vowels = ("а", "у", "о", "ы", "и", "э", "я", "ю", "ё", "е")

def search_vowels(word: str):
	result = []
	for i in range(len(word)):
		if word[i] in vowels:
			result.append(i)
	return result

word_vowels = search_vowels(word)
words_vowels = []
for word in words:
	words_vowels.append(search_vowels(word))

for i in range(n):
	if word_vowels == words_vowels[i]:
		print(words[i])
	else:
		print(f"не подходит {words[i]}")


from heapq import heapify, heappop, heappush

class priority_queue:
  def __init__(self, heap):
    self.heap = heap
    heapify(self.heap)

  def push(self, item):
    heappush(self.heap, item)

  def pop(self):
    return heappop(self.heap)

  def __len__(self):
        return len(self.heap)

inf = 10**6
state = []
distance = []
parent = []

n = int(input())
v = 0

matrix = [[inf]*n for i in range(n)]

for i in range(n):
  e = list(map(int, input().split()))

  if e[1] != 0:
    u = e[0]

    for k, j in enumerate(e[2:], 2):
      if k % 2 == 0:
        v = j
      else:
        matrix[u][v] = j

  state.append(0)
  distance.append(inf)
  parent.append(-1)

distance[0] = 0

pq = priority_queue([(0, 0)])

while pq:
  min, u = pq.pop()

  state[u] = 2

  if distance[u] < min:
    continue

  for v in range(n):
    if state[v] != 2 and matrix[u][v] != inf:
      if distance[u] + matrix[u][v] < distance[v]:
        distance[v] = distance[u] + matrix[u][v]
        parent[v] = u
        state[v] = 1
        pq.push((distance[v], v))

for i in range(n):
  print(i, distance[i])


from django.conf import settings
from django.conf.urls import url
from django.contrib.auth.views import LogoutView as logout, LoginView as login
from django.urls import path
from inc_mgmt import views as v

app_name = 'inc_mgmt'
urlpatterns = [
    url(r'^register/$', v.self_register, name='register'),
    url(r'^login/$', login.as_view(), {'next_page': settings.LOGIN_REDIRECT_URL}, name='login'),
    url(r'^logout/$', logout.as_view(), {'next_page': settings.LOGOUT_REDIRECT_URL}, name='logout'),
    url(r'^register/confirm_account/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', v.confirm_account, name='confirm_account'),
    url(r'^activate_account/list/$', v.activate_user_list, name='activate_user_list'),
    url('ajax/activate_account/', v.activate_user, name='activate_user'),
    path('', v.index, name='index'),
    path('<area_name>/ticket/list/', v.ticket_list, name='ticket_list'),
    path('<area_name>/ticket/list/<fast_status_filter>/', v.ticket_list, name='ticket_list'),
    path('<area_name>/ticket/new/', v.ticket_new, name='ticket_new'),
    path('<area_name>/ticket/<ticket_id>/detail/', v.ticket_detail, name='ticket_detail'),
    path('<area_name>/ticket/<ticket_id>/change/', v.ticket_change, name='ticket_change'),
    path('ajax/update_ticket/', v.ticket_update, name='ticket_update'),
]


#!/usr/bin/python
# coding: utf8

def shell_sort(_list):
    """
    Сортировка Шелла. Сортируем подгруппы элементов на расстонии d.

    :param _list: Массив для сортировки.
    :type _list: list

    :return: Отсортированый массив.
    :rtype: list

    """
    length = len(_list)
    d = int(length // 2)

    while d > 0:  # Пока есть расстояние
        for i in range(length - d):  # Идем под подгруппе

            j = i
            while j >= 1 and _list[j] > _list[j + d]:  # Внутри подгруппы сортируем элементы.
                _list[j], _list[j + d] = _list[j + d], _list[j]
                j -= 1

        d = int(d // 2)

    return _list

if __name__ == "__main__":
    test_list = [12, 68, 213, 1, 59, 394, 43, 12, 645, 324, 98, 999, 998]
    print(shell_sort(test_list))


def get_preprocess(data):
    n, m = data.shape
    columns = data.columns.tolist()
    nn = 0
    has3 = 0
    previous = -1
    isnull = data.isnull()
    total3 = 0
    f = False
    interactions_modified = []
    temp = []
    for i in range(n):
        ff = True
        for j in range(m):
            if isnull.iloc[i][columns[j]] == True:
                ff = False
                break
        if ff == True:
            id = int(data.iloc[i][columns[0]])
            rec = int(data.iloc[i][columns[2]])
            if id != previous:
                if f == True:
                    interactions_modified.append([previous, temp])
                previous = id
                temp = []
                nn += 1
                f = False
            else:
                temp.append([data.iloc[i][columns[1]], data.iloc[i][columns[2]],
                             data.iloc[i][columns[3]]])
            if (rec == 3):
                total3 += 1
                if f == False:
                    has3 += 1
                    f = True
    print('Total Candidates:', nn)
    print('Candidates with 3:', has3)
    print('Total 3 Recommendations:', total3)
    return interactions_modified


import math
x, y, c = map(float, input().split())

r = min(x, y)
l = 0

while abs(l-r) >= 0.001:
    d = (l+r) / 2
    h1 = math.sqrt(pow(x, 2) - pow(d, 2))
    h2 = math.sqrt(pow(y, 2) - pow(d, 2))
    h = h1 * h2 / (h1 + h2)
    if h <= c:
        r = d
    else:
        l = d
print(round(d, 3))


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

from odoo import api, fields, models

class MergeOpportunity(models.TransientModel):

    _inherit = 'crm.merge.opportunity'

    #owner_type = fields.Selection([('team', '分配给线索团队'), ('user', '分配给负责人')], required=True, string='分配方式', default='user', help="线索可以分配给团队负责,或者分配给指定具体人员负责")

    #owner_team_id = fields.Many2one('crm.team', string='线索团队')

    @api.model
    def default_get(self, fields):
        '''
            自动计算多个线索中的分配关系
        '''

        record_ids = self._context.get('active_ids')
        result = super().default_get(fields)

        if record_ids:
            opps = self.env['crm.lead'].browse(record_ids)
            #owner_type_set = set()
            user_id_set = set()
            team_id_set = set()
            for opp in opps:
                #owner_type_set.add(opp.owner_type)
                if opp.user_id:
                    user_id_set.add(opp.user_id.id)
                if opp.team_id:
                    team_id_set.add(opp.team_id.id)

            #if len(owner_type_set) == 1:
            #    result['owner_type'] = owner_type_set.pop()

            if len(user_id_set) == 1:
                result['user_id'] = user_id_set.pop()

            if len(team_id_set) == 1:
                result['team_id'] = team_id_set.pop()

        return result


import os

root_dir = "./folders"

for dirpath, dirnames, filenames in os.walk(root_dir):
    for filename in filenames:
        filepath = os.path.join(dirpath, filename)

        if "-01" in filename or "-02" in filename or "-03" in filename:

            new_filename = filename.replace(
                "-01", "").replace("-02", "").replace("-03", "")
            new_filepath = os.path.join(dirpath, new_filename)

            os.rename(filepath, new_filepath)


import datetime
import textwrap
from pathlib import Path

from slap import __version__
from slap.application import Application, Command, argument, option
from slap.plugins import ApplicationPlugin
from slap.util.external.licenses import get_spdx_license_details, wrap_license_text
from slap.util.vcs import get_git_author

TEMPLATES = {
    "poetry": {
        "pyproject.toml": """
            [build-system]
            requires = ["poetry-core"]
            build-backend = "poetry.core.masonry.api"

            [tool.poetry]
            name = "{name}"
            version = "0.1.0"
            description = ""
            authors = ["{author_name} <{author_email}>"]
            license = "{license}"
            readme = "readme.md"
            packages = [{{ include = "{path}", from = "src" }}]
            classifiers = []
            keywords = []

            [tool.poetry.urls]
            # "Bug Tracker" = ""
            # Documentation = ""
            # Homepage = ""
            # Repository = ""

            [tool.poetry.dependencies]
            python = "^3.6"

            [tool.poetry.dev-dependencies]
            black = "*"
            flake8 = "*"
            isort = "*"
            mypy = "*"
            pytest = "*"

            [tool.slap]
            typed = true

            [tool.slap.test]
            check = "slap check"
            mypy = "dmypy run src/"
            pytest = "pytest tests/ -vv"
            black = "black --check src/ tests/"
            isort = "isort --check-only src/ tests/"
            flake8 = "flake8 src/ tests/"

            [tool.slap.run]
            fmt = "black src/ tests/ && isort src/ tests/"

            [tool.mypy]
            python_version = "3.6"
            explicit_package_bases = true
            mypy_path = ["src"]
            namespace_packages = true
            pretty = true
            show_error_codes = true
            show_error_context = true
            strict = true
            warn_no_return = true
            warn_redundant_casts = true
            warn_unreachable = true
            warn_unused_ignores = true

            [tool.isort]
            profile = "black"
            line_length = 120
            combine_as_imports = true

            [tool.black]
            line-length = 120
        """,
        "LICENSE": "",
        "readme.md": """
            # {name}

        """,
        ".flake8": """
            [flake8]
            max-line-length = 120
        """,
        ".gitignore": """
            /.vscode
            /dist
            /build
            .venv/
            *.egg-info/
            __pycache__/
            poetry.lock
        """,
        "src/{path}/__init__.py": """
            __version__ = "0.1.0"
        """,
        "tests/test_import.py": """
            def test_import():
                exec("from {dotted_name} import *")
    """,
        "src/{path}/py.typed": "",
    },
    "github": {
        ".github/workflows/python-package.yml": """
            name: Python application

            on:
              push: {{ branches: [ develop ], tags: [ "*" ] }}
              pull_request: {{ branches: [ develop ] }}

            jobs:
              test:
                runs-on: ubuntu-latest
                strategy:
                  fail-fast: false
                  matrix:
                    python-version: [ "3.6", "3.7", "3.8", "3.9", "3.10", "3.x" ]
                steps:
                - uses: actions/checkout@v2
                - uses: python-slap/slap.cli@gha/install/v1
                - uses: actions/setup-python@v2
                  with: {{ python-version: "${{{{ matrix.python-version }}}}" }}
                - run: slap install -vv --no-venv-check
                - run: slap test

              update-changelog:
                runs-on: ubuntu-latest
                if: github.event_name == 'pull_request'
                steps:
                  - uses: actions/checkout@v2
                  - uses: python-slap/slap.cli@gha/changelog/update/v1
    """,
    },
}

class InitCommandPlugin(ApplicationPlugin, Command):
    """Bootstrap some files for a Python project.

    Currently available templates:

    1. <info>poetry</info>
    """

    app: Application

    name = "init"
    arguments = [
        argument(
            "directory",
            description="The directory in which to create the generated files. If not specified, a new directory with "
            "the name specified via the <opt>--name</opt> option is created.",
            optional=True,
        )
    ]
    options = [
        option(
            "--name",
            description="The name of the Python package.",
            flag=False,
        ),
        option(
            "--license",
            description="The package license.",
            flag=False,
            default="MIT",
        ),
        option(
            "--template",
            "-t",
            description="The template to use.",
            flag=False,
            default="poetry",
        ),
        option(
            "--overwrite",
            "-f",
            description="Overwrite files.",
        ),
        option(
            "--dry",
            "-d",
            description="Dont actually write files.",
        ),
        option(
            "--as-markdown",
            description="Render the content as Markdown (uses by the Slap docs)",
        ),
    ]

    def load_configuration(self, app: Application) -> None:
        return None

    def activate(self, app: Application, config: None) -> None:
        self.app = app
        app.cleo.add(self)

    def handle(self) -> int:
        from nr.util.optional import Optional

        template = self.option("template")
        if template not in TEMPLATES:
            self.line_error(f'error: template "{template}" does not exist', "error")
            return 1

        author = get_git_author()
        name = self.option("name")
        directory = (
            Optional(self.argument("directory"))
            .map(Path)
            .map(lambda v: v or (name.replace(".", "-") if name else None))
            .or_else_get(Path.cwd)
        )

        scope = {
            "license": self.option("license"),
            "year": datetime.date.today().year,
            "author_name": author.name if author and author.name else "Unknown",
            "author_email": author.email if author and author.email else "me@unknown.org",
        }
        if self.option("name"):
            scope.update(
                {
                    "name": self.option("name"),
                    "dotted_name": self.option("name").replace("-", "_"),
                    "path": self.option("name").replace(".", "/").replace("-", "_"),
                    "package": self.option("name").replace(".", "_").replace("-", "_"),
                }
            )
        for filename, content in TEMPLATES[template].items():
            if filename == "LICENSE":
                content = get_spdx_license_details(self.option("license")).license_text
                content = wrap_license_text(content).replace("<year>", str(scope["year"]))
                content = wrap_license_text(content).replace("<copyright holders>", scope["author_name"])
            else:
                filename = filename.format(**scope)
                content = textwrap.dedent(content.format(**scope)).strip()
                if content:
                    content += "\n"

            path = directory / filename

            if self.option("as-markdown"):
                print(f'```{path.suffix[1:]} title="{path}"')
                print(content, "    ")
                print(f"```\n\n")
                continue

            if path.exists() and not self.option("overwrite"):
                self.line(f"skip <info>{path}</info> (already exists)")
                continue

            if not self.option("dry") and not self.option("as-markdown"):
                path.parent.mkdir(parents=True, exist_ok=True)
                path.write_text(content)

            self.line(f"write <info>{path}</info>")

        return 0


def inspect_target(fuzzer):
    fuzz_targets = []

    built_in_msg_types = ros_utils.get_all_message_types()
    subscriptions = ros_utils.get_subscriptions(fuzzer.node_ptr)

    if fuzzer.config.px4_sitl:
        if fuzzer.config.use_mavlink:
            topic_name = "/dummy_mavlink_topic"
            msg_type_class = ros_utils.get_msg_class_from_name(
                "px4_msgs", "ManualControlSetpoint"
            )
        else:
            topic_name = "/TrajectorySetpoint_PubSubTopic"
            msg_type_class = ros_utils.get_msg_class_from_name(
                "px4_msgs", "TrajectorySetpoint"
            )

        fuzz_targets.append([topic_name, msg_type_class, "drone"])
        return fuzz_targets

    elif fuzzer.config.tb3_sitl:
        topic_name = "/cmd_vel"
        msg_type_class = ros_utils.get_msg_class_from_name(
            "geometry_msgs", "Twist"
        )
        fuzz_targets.append(
            [topic_name, msg_type_class, "/turtlebot3_diff_drive"]
        )

        return fuzz_targets

    elif fuzzer.config.tb3_hitl:
        topic_name = "/cmd_vel"
        msg_type_class = ros_utils.get_msg_class_from_name(
            "geometry_msgs", "Twist"
        )
        fuzz_targets.append([topic_name, msg_type_class, "/turtlebot3_node"])

        return fuzz_targets

    elif fuzzer.config.test_rosidl:
        topic_name = "/metatopic" # fake topic (topic tbd by mutator)
        msg_type_class = ros_utils.get_msg_class_from_name(
            "std_msgs", "Empty"
        )
        fuzz_targets.append([topic_name, msg_type_class, "/rosidl_node"])

        return fuzz_targets

    elif fuzzer.config.test_moveit:
        # use below if testing without commander harness
        topic_name = "/motion_plan_request"
        msg_type_class = ros_utils.get_msg_class_from_name(
            "moveit_msgs", "MotionPlanRequest"
        )
        # for now, use commander harness for convenience
        topic_name = "/metatopic"
        msg_type_class = ros_utils.get_msg_class_from_name(
            "geometry_msgs", "Pose"
        )

        fuzz_targets.append([topic_name, msg_type_class, "/moveit_node"])

        return fuzz_targets

    for subscriber_node in subscriptions:
        print()
        print("[+] processing", subscriber_node)

        if subscriber_node.replace("/", "").startswith("_"):
            print("[-] skip internal node")
            continue

        for ti, topic in enumerate(subscriptions[subscriber_node]):
            topic_name = topic[0]
            msg_type_full = topic[1]

            print("[{}] {} {}".format(ti, topic_name, msg_type_full))

            if len(msg_type_full) > 1:
                print("[check] MULTIPLE MESSAGE TYPES!")

            msg_type = msg_type_full[0]
            msg_pkg = msg_type.split("/")[0]
            msg_name = msg_type.split("/")[-1]

            if msg_name == "ParameterEvent":
                print("[-] skip ParameterEvents")
                continue

            if msg_pkg in built_in_msg_types.keys():
                msg_type_class = ros_utils.get_msg_class_from_name(
                    msg_pkg, msg_name
                )
            else:
                msg_type_class = ros_utils.find_custom_msg(msg_type)

            if msg_type_class is None:
                print("[-] couldn't find msg class")
                continue

            print()
            print("Found fuzzing topic", topic_name, "of type", msg_type_class)
            print("- target node:", subscriber_node)
            fuzz_targets.append([topic_name, msg_type_class, subscriber_node])

    return fuzz_targets

def inspect_secure_target(fuzzer):
    fuzz_targets = []

    built_in_msg_types = ros_utils.get_all_message_types()
    subscriptions = ros_utils.get_secure_subscriptions(fuzzer.node_ptr)

    for subscriber_node in subscriptions:
        print()
        print("[+] processing", subscriber_node)

        if subscriber_node.replace("/", "").startswith("_"):
            print("[-] skip internal node")
            continue

        for ti, topic in enumerate(subscriptions[subscriber_node]):
            topic_name = topic[0]
            msg_type_full = topic[1]

            print("[{}] {} {}".format(ti, topic_name, msg_type_full))

            if len(msg_type_full) > 1:
                print("[check] MULTIPLE MESSAGE TYPES!")

            msg_type = msg_type_full[0]
            msg_pkg = msg_type.split("/")[0]
            msg_name = msg_type.split("/")[-1]

            if msg_name == "ParameterEvent":
                print("[-] skip ParameterEvents")
                continue

            if msg_pkg in built_in_msg_types.keys():
                msg_type_class = ros_utils.get_msg_class_from_name(
                    msg_pkg, msg_name
                )
            else:
                msg_type_class = ros_utils.find_custom_msg(msg_type)

            if msg_type_class is None:
                print("[-] couldn't find msg class")
                continue

            print()
            print("Found fuzzing topic", topic_name, "of type", msg_type_class)
            print("- target node:", subscriber_node)
            fuzz_targets.append([topic_name, msg_type_class, subscriber_node])

    fuzzer.kill_target()
    return fuzz_targets

def inspect_service(fuzzer):
    services = ros_utils.get_services(fuzzer.node_ptr)
    built_in_svc_types = ros_utils.get_all_service_types()

    target_services = []
    for tested_node in services:
        print()
        print("[+] processing {}'s services".format(tested_node))
        for si, srv in enumerate(services[tested_node]):
            srv_name = srv[0]
            srv_type_full = srv[1]
            print("[{}] {} {}".format(si, srv_name, srv_type_full))

            if len(srv_type_full) > 1:
                print("[check] MULTIPLE SERVICE TYPES!")

            if "parameter" in srv_name:
                print("[-] skip param servers")
                continue

            srv_type_full = srv_type_full[0]
            ss = srv_type_full.split("/")
            if len(ss) == 2:
                ss = [ss[0], "srv", ss[1]]
            srv_pkg = ss[0]
            srv_type = ss[-1]
            if srv_pkg == "action_msgs":
                print("[-] skip action messages")
                continue

            if ss[1] != "srv":
                print("[-] skip non-svc services")
                continue

            if srv_pkg not in built_in_svc_types.keys():
                print("service package not found")
                continue

            srv_module_name = ".".join(ss[:-1])
            try:
                module = importlib.import_module(srv_module_name)
                srv_module = getattr(module, srv_type)
                if not srv_pkg or not srv_module:
                    raise ValueError()
            except ValueError:
                raise RuntimeError("service type is invalid")

            target_services.append([srv_name, srv_module, srv_type_full])

    return target_services


import numpy as np
from lightfm.datasets import fetch_movielens
from lightfm import LightFM

data = fetch_movielens(min_rating = 4.0)

print(repr(data['train']))
print(repr(data['test']))

#model with loss func.
model = LightFM(loss = 'warp')

model.fit(data['train'],epochs = 30,num_threads = 2)

def sample_rec(model, data, user_ids):

    n_users,n_items = data['train'].shape
    for i in user_ids:

        known_pos = data['item_labels'][data['train'].tocsr()[i].indices]
        scores = model.predict(i,np.arange(n_items))
        top_items = data['item_labels'][np.argsort(-scores)]

        #printing
        print("User  %s"% i)
        print(" Known positives:")
        for j in known_pos[:3]:     ##top 3
            print("     %s" % j)
        print(" Recommended:")
        for j in top_items[:3]:
            print("     %s" % j)

sample_rec(model,data,[3,45,250])


import concurrent
from concurrent import futures
import grpc
import json
import booking_pb2
import booking_pb2_grpc

class BookingServicer(booking_pb2_grpc.BookingServicer):
    def __init__(self):
        with open('{}/databases/bookings.json'.format("."), "r") as jsf:
            self.db = json.load(jsf)["bookings"]

    def GetAllBookings(self,request,context):
        for booking in self.db:
            yield booking_pb2.BookingMessage(date=booking['dates'],userid=booking['userid'])

    def GetBookingByUserId(self, request, context):
        for booking in self.db:
            if str(booking["userid"]) == str(request.id):
                print("hello")
                return booking_pb2.BookingMessage(
                    userid=booking["userid"],
                    date=[booking_pb2.Date(date=b.date,movies=b.movies) for b in booking]
                )
        return booking_pb2.BookingMessage(
            userid="",
            date=""
        )

    def CreateBooking(self, request, context):
        self.db.append({
            "userid":request.userid,
            "date":request.date
        })

def serve():
  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
  booking_pb2_grpc.add_BookingServicer_to_server(BookingServicer(),
                                                      server)
  server.add_insecure_port('[::]:' + "3005")
  server.start()
  server.wait_for_termination()

if __name__ == '__main__':
  serve()


#1 wala issue
import json
import pprint
import collections
import operator
import pandas as pd
import csv
import math
from collections import defaultdict
import networkx as nx

csv_file = open('article-ids.csv')
csv_reader = csv.reader(csv_file,delimiter = ',')
aid = {}

for row in csv_reader:
    if row[0] == "Article_Name":
        continue
    aid[row[0]] = row[1]

csv_file = open('category-ids.csv')
csv_reader = csv.reader(csv_file,delimiter = ',')
cid = {}
cid2 = {}

for row in csv_reader:
    if row[0] == "Category_Name":
        continue
    cid[row[0]] = row[1]
    cid2[row[1]] = row[0]

csv_file = open('article-categories.csv')
csv_reader = csv.reader(csv_file,delimiter = ',')
acid = {}
for row in csv_reader:
    if row[0] == "Article ID":
        continue
    lis = row[1].split(" ")
    acid[row[0]] = lis

G = nx.DiGraph()
csv_file = open('edges.csv')
csv_reader = csv.reader(csv_file,delimiter = ',')

for row in csv_reader:
    if row[0] == "From_ArticleID":
        continue
    x = (row[0],row[1])
    G.add_edge(*x)

sample = open('temp4','r')
lines = sample.readlines()

catnp = {}
catnt = {}
catsp = {}
catst = {}
catnp = defaultdict(lambda:0,catnp)
catnt = defaultdict(lambda:0,catnt)
catsp = defaultdict(lambda:0,catsp)
catst = defaultdict(lambda:0,catst)

for line in lines:
    done = []
    done2 = []
    a = line[:-1]
    lis = a.split(";")
    stack = []
    for key in lis:
        if key == '<' :
            stack.pop()
        else:
            stack.append(aid[key])
    f = stack[0]
    l = stack[-1]
    if f != l:
        try:
            short = nx.shortest_path(G,f,l)
        except:
            continue

        for key in stack:
            if key in acid:
                for cats in acid[key]:
                    a = cid2[cats]
                    n = a.count('.') +1
                    for i in range(1,n):
                        k = ".".join(a.split(".", i)[:i])
                        cat = cid[k]
                        if cat not in done:
                            catnp[cat] = catnp[cat] + 1
                            done.append(cat)
                        catnt[cat] = catnt[cat] + 1
                    if cats not in done:
                        catnp[cats] = catnp[cats] + 1
                        done.append(cats)
                    catnt[cats] = catnt[cats] + 1

        for key in short:
            if key in acid:
                for cats in acid[key]:
                    a = cid2[cats]
                    n = a.count('.') +1
                    for i in range(1,n):
                        k = ".".join(a.split(".", i)[:i])
                        cat = cid[k]
                        if cat not in done2:
                            catsp[cat] = catsp[cat] + 1
                            done2.append(cat)
                        catst[cat] = catst[cat] + 1
                    if cats not in done2:
                        catsp[cats] = catsp[cats] + 1
                        done2.append(cats)
                    catst[cats] = catst[cats] + 1

sd = open('category-subtree-paths.csv','w')
print('Category_ID,Number_of_human_paths_traversed,Number_of_human_times_traversed,Number_of_shortest_paths_traversed,Number_of_shortest_times_traversed',file=sd)

for i in range(1,147):
    key = "C" + "{:04n}".format(i)
    if key in catsp.keys():
        print(key,catnp[key],catnt[key],catsp[key],catst[key],sep=",",file =sd)
    else:
        print(key,0,0,0,0,sep=",",file =sd)


def calculate(map):

    changed=False

    for i in range(len(map)-1):
        for j in range(len(map[i])):
            if map[i][j]=="-" and map[i+1][j+1]!="-" and map[i+1][j]!="-":
                map[i][j]= map[i+1][j]+map[i+1][j+1]
                changed=True

    for i in range(len(map)-1,0,-1):
        for j in range(len(map[i])-1):
            if map[i][j]=="-" and map[i][j+1]!="-" and map[i-1][j]!="-":
                map[i][j]= map[i-1][j]-map[i][j+1]
                changed=True

        for j in range(1,len(map[i])):
            if map[i][j]=="-" and map[i-1][j-1]!="-" and map[i][j-1]!="-":
                map[i][j]= map[i-1][j-1]-map[i][j-1]
                changed=True

    if changed:
        calculate(map)

    return
lines=[]

with open("pyramid.in","r") as file:
    for line in file:
        lines.append(line.strip().split())

counter=0
map=[]
testcase=1
text=""
for i in range(len(lines)):
    if lines[i][0]=="-1":
        break
    if i == counter:
        height= int(lines[i][0])
        counter+=height+1
        for j in range(i+1,counter):
            map.append(lines[j])

        for k in range(len(map)):
            for z in range(len(map[k])):
                try:
                    map[k][z]=int(map[k][z])
                except:
                    a=5

        if testcase==20:
            print(map)

        calculate(map)

        if map[0][0]!="-":
            print(testcase,". ",map[0][0])
            text+=str(testcase)+": "+str(map[0][0])
        else:
            print(testcase,". not solvable")
            text+=str(testcase)+": Not solvable"

        text+="\n"
        testcase+=1

        map=[]

with open("pyramid.answer","w")as file:
    file.write(text)


import bs4
import urllib.request
import smtplib
import time
prices_list=[]
def check_price():

    url = 'https://www.amazon.in/dp/B082MDMW3X/ref=s9_acsd_al_bw_c2_x_0_i?pf_rd_m=A1K21FY43GMZF8&pf_rd_s=merchandised-search-5&pf_rd_r=CF9JY0WX1GAAPBD3S9KW&pf_rd_t=101&pf_rd_p=8398f427-fbf5-4310-a31e-29a4be7a59bc&pf_rd_i=26297682031'
    sauce = urllib.request.urlopen(url).read()
    soup = bs4.BeautifulSoup(sauce,"html.parser")
    price = soup.find(id="priceblock_dealprice").get_text()
    p1 = float(price.replace(",","").replace("₹",""))
    print(price)
    print(p1)
    prices_list.append(p1)
    return p1
check_price()

def send_email(message):
    s=smtplib.SMTP('smtp.gmail.com',587)
    s.starttls()
    s.login("anshtestiing123@gmail.com","anshpratap013@")
    s.sendmail("anshtestiing123@gmail.com","anshpratap013@gmail.com",message)
    s.quit()

send_email("Hi Ansh")
def price_decrease_check(prices_list):
    if prices_list[-1]<prices_list[-2]:
        return True
    else:
        return False
count = 1
while True:

    current_price = check_price()
    if count>1:
        flag = price_decrease_check(prices_list)
        if flag>1:
            decrease = prices_list[-1]-prices_list[-2]
            message = "The price has decreased please check the item and it has decreased by {decrese} rupees"
            send_email(message)
    time.sleep(1)
    count+=1


"""
Definition of the GridOsc trading logic, which constitutes the basic components of swing trading.
"""

from math import ceil, floor
from constants import *
from strategy import INIT, REQ, SPLIT
from strategy import calc_order_params, update_position_avg_price_2way

class GridOsc:
    """
    Oscillatory trading on a pre-defined price grid. Support trailing buy/sell.
    """

    def __init__(self,
                 logger,
                 tag,
                 contract,
                 low_bound,
                 n_grids,
                 grid_height,
                 low_ext,
                 high_ext,
                 trail_amt,
                 qty_base_long,
                 qty_base_short,
                 qty_offset_long,
                 qty_offset_short,
                 last_order_price,
                 k_init,
                 qty_base_scaling=True,
                 position_qty_cap_min=-2**64,
                 position_qty_cap_max=2**64,
                 order_qty_cap_long=2**64,
                 order_qty_cap_short=2**64):
        """
        :param tag: str. Name tag of the zone.
        :param contract: Contract object.
        :param low_bound: float. Initial lower price bound of the zone.
        :param n_grids: int. Initial number of grids.
        :param grid_height: float. Price grid height.
        :param low_ext: bool. If lower bound can be extended.
        :param high_ext: bool. If higher bound can be extended.
        :param trail_amt: float. Price trailing amount to trigger an order.
        :param qty_base_long: int. Base order quantity A for one-grid swing long.
        :param qty_base_short: int. Base order quantity A for one-grid swing short.
        :param qty_offset_long: int. Base offset order quantity for the long side.
        :param qty_offset_short: int. Base offset order quantity for the short side.
        :param k_init: int. Initial value of offset order quantity scale k.
        :param qty_base_scaling: bool. If scale base order qty based on price swing range.
        :param last_order_price: float. Price of last successfully submitted order.
        :param position_qty_cap_min: int. Minimal position qty (-inf, inf) to keep.
        :param position_qty_cap_max: int. Maximal position qty (-inf, inf) to keep.
        :param order_qty_cap_long: int. Maximal order qty for long [0, inf).
        :param order_qty_cap_short: int. Maximal order qty for short [0, inf).
        """
        self.logger = logger

        # tag, contract
        self.tag = tag
        self.contract = contract

        # Grids planning
        self.n_grids = n_grids
        self.ph = grid_height
        self.bounds = [low_bound, round(low_bound + n_grids * self.ph, contract.decimal)]
        self.ext = (low_ext, high_ext)

        # Trailing and oscillatory parameters
        self.pt = trail_amt
        self.qa = [qty_base_long, qty_base_short]
        self.qn = [qty_offset_long, qty_offset_short]
        self.order_qty_scaling = qty_base_scaling
        self.position_qty_caps = [position_qty_cap_min, position_qty_cap_max]
        self.order_qty_caps = [order_qty_cap_long, order_qty_cap_short]

        # Oscillator states
        self.state = INIT
        self.last_order_price = last_order_price
        self.peak = [last_order_price, last_order_price]  # price valley and ridge for long and short
        self._position_qty = 0  # Position quantity. >0: long, <0: short.
        self._cma_price = 0.0  # Cumulative moving average price.
        self._k = k_init  # initial value of the volume offset scale k
        self._k_profit = 0.0  # Accumulated profit since the last change of k value
        self._k_profit_th = (self.bounds[1] - self.bounds[0]) * (
            self.n_grids * min(self.qa) + self._k * min(self.qn)) * self.contract.unit

    def __repr__(self):
        return ("{}: n_grids={} bounds={} ext={} qa={} qn={} state={} last_order_price={} peak={} "
                "position_qty={} cma_price={} k={} k_profit={} k_profit_th={}").format(
                    self.tag, self.n_grids, self.bounds, self.ext, self.qa, self.qn, self.state, self.last_order_price,
                    self.peak, self._position_qty, self._cma_price, self._k, self._k_profit, self._k_profit_th)

    def _r(self, price):
        return round(price, self.contract.decimal)

    def _update_last_order_price(self, last_order_price):
        self.last_order_price = last_order_price
        self.peak = [last_order_price, last_order_price]

    def _zone_expand(self, price):
        for direction in (0, 1):
            d = 1 - 2 * direction
            if self.ext[direction] and d * (price - self.bounds[direction]) < 0:
                n_grids_ext = int(ceil(d * (self.bounds[direction] - price) / self.ph))
                self.n_grids += n_grids_ext
                self.bounds[direction] = self._r(self.bounds[direction] - d * n_grids_ext * self.ph)
                self._k_profit_th = (self.bounds[1] - self.bounds[0]) * (
                    self.n_grids * min(self.qa) + self._k * min(self.qn)) * self.contract.unit
                break

    def on_tick_update(self, price):
        # Update peak prices
        self.peak[0] = min(self.peak[0], price)
        self.peak[1] = max(self.peak[1], price)

        # Expand zone if necessary
        if any(self.ext):
            self._zone_expand(price)

    def on_tick_trade(self, trade_price, position_long, position_short):
        """
        Trading rules and states update when receiving market data.
        :params trade_price: Latest price used to determine trading conditions.
        :params position_long: Current available long position quantity to sell.
        :params position_short: Current available short position quantity to sell.
        """
        # Check state
        order_params_list = []
        if self.state in (REQ, SPLIT):
            return order_params_list, position_long, position_short

        # Check if order conditions are met in either long or short direction.
        # 1. peak to last trade price > h0;  2. trailing > pt;  3. last price and last order price in different grids.
        position_qty = position_long - position_short
        pos_qty_caps = (self.position_qty_caps[1] - position_qty, position_qty - self.position_qty_caps[0])
        for direction in (0, 1):
            peak = self.peak[direction]
            d = 1 - 2 * direction
            if self._r(d * (self.last_order_price - trade_price)) >= self.ph \
                    and self._r(d * (trade_price - peak)) >= self.pt:
                scale = int(floor(d * (self.last_order_price - trade_price) / self.ph))
                if not self.order_qty_scaling:
                    scale = min(1, scale)
                order_qty = int(scale > 0) * (scale * self.qa[direction] + self._k * self.qn[direction])
                self.logger.debug("{}: {} last_order_price={} peak={} trade_price={} scale={} k={} order_qty={}".format(
                    self.tag, ('long', 'short')[direction], self.last_order_price, peak, trade_price, scale, self._k,
                    order_qty))
                order_qty = min(order_qty, pos_qty_caps[direction])
                self.logger.debug("{}: {} pos={}({},{}) pos_cap_{}={} qty_cap={} updated order_qty={}".format(
                    self.tag, ('long', 'short')[direction], position_qty, position_long, position_short,
                    ('max', 'min')[direction], (self.position_qty_caps[1], self.position_qty_caps[0])[direction],
                    pos_qty_caps[direction], order_qty))
                order_qty = min(order_qty, self.order_qty_caps[direction])
                self.logger.debug("{}: {} order_qty_cap={} updated order_qty={}".format(
                    self.tag, ('long', 'short')[direction], self.order_qty_caps[direction], order_qty))
                if order_qty > 0:  # Make order parameters list only if order qty > 0.
                    order_params_list, position_long, position_short, is_order_split = calc_order_params(
                        (BUY, SELL)[direction],
                        DIRECTION_LONG,
                        trade_price,
                        order_qty,
                        order_tag=self.tag,
                        position_available=position_long,
                        position_available_reverse=position_short)
                    # State transition to REQ to wait for order submission
                    self.state = SPLIT if is_order_split else REQ
                    break
        return order_params_list, position_long, position_short

    def on_buy_sell_fail(self):
        if self.state == SPLIT:
            self.state = REQ
        elif self.state == REQ:
            self.state = INIT

    def on_buy_sell_success(self, order_price):
        if self.state == SPLIT:
            self.state = REQ
        elif self.state == REQ:
            self.state = INIT
        self._update_last_order_price(order_price)

    def on_trade_update(self, trade_action, trade_direction, trade_price, trade_qty):
        self.logger.debug("{}: trade update Begin: position_qty={} cma_price={} k={} k_profit={} k_profit_th={}".format(
            self.tag, self._position_qty, self._cma_price, self._k, self._k_profit, self._k_profit_th))
        self._cma_price, self._position_qty, realized_gain = update_position_avg_price_2way(
            self._cma_price, self._position_qty, trade_action, trade_direction, trade_price, trade_qty)
        self._k_profit += realized_gain * self.contract.unit
        if self._k_profit > self._k_profit_th:
            self._k += 1
            self._k_profit = 0.0
            self._k_profit_th += (self.bounds[1] - self.bounds[0]) * min(self.qn) * self.contract.unit
        self.logger.debug(
            "{}: trade update End: unscaled_gain={} position_qty={} cma_price={} k={} k_profit={} k_profit_th={}".
            format(self.tag, realized_gain, self._position_qty, self._cma_price, self._k, self._k_profit,
                   self._k_profit_th))


import requests
import os
import sys

from physics import calculate

LINE_URL = 'https://api.line.me/v2/bot/message/reply'
token = os.environ.get('LINE_TOKEN')

VALID_VARIABLES = ['v', 'u', 'a', 't', 's']

class User:
    def __init__(self, userId):
        self.userId = userId
        self.reset()

    def reset(self):
        self.unknown_variable = None
        self.missing_variable = None
        self.variables_to_ask = VALID_VARIABLES.copy()

        # for calculation
        self.variables = {}

    def ask_for_unknown(self, replyToken):
        self.reply(replyToken, 'กรุณาใส่ตัวแปรที่ท่านต้องการหา', VALID_VARIABLES)

    def ask_for_missing(self, replyToken):
        self.reply(replyToken, 'กรุณาใส่ตัวแปรที่ไม่มีอยู่ในโจทย์', self.variables_to_ask)

    def converse(self, replyToken, text):
        if self.unknown_variable is None:
            if text in VALID_VARIABLES:
                self.unknown_variable = text
                self.variables_to_ask.remove(self.unknown_variable)
            else:
                self.ask_for_unknown(replyToken)
                return

        if self.missing_variable is None:
            if text in self.variables_to_ask:
                self.missing_variable = text
                self.variables_to_ask.remove(self.missing_variable)
            else:
                self.ask_for_missing(replyToken)
                return

        if len(self.variables_to_ask) != 0:
            variable = self.variables_to_ask[0]
            if text.isnumeric():
                value = float(text)
                self.variables_to_ask.remove(variable)
                self.variables[variable] = value

                if len(self.variables_to_ask) != 0:
                    self.reply(replyToken, self.variables_to_ask[0] + ' = ?')
                    return
            else:
                self.reply(replyToken, variable + ' = ?')
                return

        try:
            answer = calculate(self.unknown_variable, self.missing_variable, self.variables)
            reply = 'คำตอบของท่านคือ ' + self.unknown_variable + ' = ' + answer + '\n'
            link = 'https://fequalsma.herokuapp.com/graph?a={a}&u={u}&t={t}'.format(**self.variables)
            reply += link
            self.reply(replyToken, reply)
        except Exception as e:
            self.reply(replyToken, 'Something went wrong!')
        self.reset()

    def create_quickReply_item(self, option):
        return {\
            'type': 'action',\
            'action': {\
                'type': 'message',\
                'label': option,\
                'text': option\
            }\
        }

    def reply(self, replyToken, text, options=[]):
        body = {}
        body['replyToken'] = replyToken
        body['messages'] = [{ 'type': 'text', 'text': text }]

        if len(options) != 0:
            quickReply = { 'items': [] }

            for option in options:
                quickReply['items'].append(self.create_quickReply_item(option))

            body['messages'][0]['quickReply'] = quickReply

        headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + token }
        req = requests.post(LINE_URL, json=body, headers=headers)


from __future__ import division
from __future__ import print_function
import tensorflow as tf

from tensorflow.keras.layers import Lambda, Dense, TimeDistributed, Input
from tensorflow.keras.models import Model
from tensorflow.keras.preprocessing import image
import tensorflow.keras.backend as K

from vgg16 import VGG16
from RoiPooling import RoiPooling
from get_regions import rmac_regions, get_size_vgg_feat_map

import scipy.io
import numpy as np
import utils

from dataset import generate_data
import time
import pandas as pd
import re
import os

from PIL import Image

flags = tf.compat.v1.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('data', 'mnist', 'dataset')
flags.DEFINE_float('start', 0.0, 'starting file')
flags.DEFINE_float('end',  1.0, 'end_file')
flags.DEFINE_string('prefix', '/rds/general/user/emuller/home/emily/phd/', 'when using RDS')

start = np.float(FLAGS.start)
end = np.float(FLAGS.end)

def addition(x):
    sum = K.sum(x, axis=1)
    return sum

def weighting(input):
    x = input[0]
    w = input[1]
    w = K.repeat_elements(w, 512, axis=-1)
    out = x * w
    return out

def rmac(input_shape, num_rois):

    # Load VGG16
    model = tf.keras.applications.vgg16.VGG16(include_top = False, input_shape=input_shape)
    #img_input = Input(shape=input_shape)
    vgg16_model = tf.keras.models.Model(inputs=model.input, outputs=model.output)
    #vgg16_model = VGG16(utils.DATA_DIR + utils.WEIGHTS_FILE, input_shape)

    # Regions as input
    in_roi = Input(shape=(num_rois, 4), name='input_roi')

    # ROI pooling
    x = RoiPooling([1], num_rois)([vgg16_model.layers[-1].output, in_roi])

    # Normalization
    x = Lambda(lambda x: K.l2_normalize(x, axis=2), name='norm1')(x)

    # PCA
    x = TimeDistributed(Dense(512, name='pca',
                              kernel_initializer='identity',
                              bias_initializer='zeros'))(x)

    # Normalization
    x = Lambda(lambda x: K.l2_normalize(x, axis=2), name='pca_norm')(x)

    # Addition
    rmac = Lambda(addition, output_shape=(512,), name='rmac')(x)

    # # Normalization
    rmac_norm = Lambda(lambda x: K.l2_normalize(x, axis=1), name='rmac_norm')(rmac)

    # Define model
    model = Model([vgg16_model.input, in_roi], rmac_norm)
    print (model.summary())
    # Load PCA weights
    mat = scipy.io.loadmat(FLAGS.prefix + '003_image_matching/keras_rmac-master/' + utils.DATA_DIR + utils.PCA_FILE)
    b = np.squeeze(mat['bias'], axis=1)
    w = np.transpose(mat['weights'])
    model.layers[-4].set_weights([w, b])

    return model

def preprocess(img):
    (left, upper, right, lower) = (137, 132, 505, 500)
    # Here the image "im" is cropped and assigned to new variable im_crop
    img_crop = img.crop((left, upper, right, lower))
    img_crop = img_crop.resize((640,640),Image.BICUBIC)
    return img_crop
# if __name__ == "__main__":

    # # Load sample image
    # # file = utils.DATA_DIR + 'sample.jpg'
    # img = image.load_img(file)

#     # Resize
    # scale = utils.IMG_SIZE / max(img.size)
    # new_size = (int(np.ceil(scale * img.size[0])), int(np.ceil(scale * img.size[1])))
    # print('Original size: %s, Resized image: %s' %(str(img.size), str(new_size)))

    # img = img.resize(new_size)

    # # Mean substraction
    # x = image.img_to_array(img)
    # x = np.expand_dims(x, axis=0)
#     x = utils.preprocess_image(x)

#     # Load RMAC model
#     Wmap, Hmap = get_size_vgg_feat_map(x.shape[3], x.shape[2])
#     regions = rmac_regions(Wmap, Hmap, 3)
#     print('Loading RMAC model...')
#     model = rmac((x.shape[1], x.shape[2], x.shape[3]), len(regions))

#     # Compute RMAC vector
#     print('Extracting RMAC from image...')
#     RMAC = model.predict([x, np.expand_dims(regions, axis=0)])
#     print('RMAC size: %s' % RMAC.shape[1])
#     print('Done!')
path = FLAGS.data
files = os.listdir(path)
n = len(files)
corrupts = []

start_time = time.time()
if __name__ == "__main__":

    # Load sample image
    #dataset = FLAGS.data

    img_dim = 640
    K.set_image_data_format('channels_last')
    #ds, ds_test, img_dim_, files = generate_data(dataset, img_dim, 1, subset=(None, None), shuffle=False)
    K.set_image_data_format('channels_first')
    encoded_images = {}
    counter = 0
    for i in range(int(np.floor(n*start)), int(np.ceil(n*end))):
    #for img in ds:
        try:
            # for running with PIL
            img = Image.open(path + '/' + files[i])
            img = preprocess(img)
            name = files[i][:-4]
            img = np.array(img)
            img = np.expand_dims(img, axis=0)
            img = tf.transpose(img, [0, 3, 1, 2]).numpy()
            img = img.astype('float32')
            x = utils.preprocess_image(img)

            # Load RMAC model
            if counter == 0:
                Wmap, Hmap = get_size_vgg_feat_map(x.shape[3], x.shape[2])
                regions = rmac_regions(Wmap, Hmap, 3)
                model = rmac((x.shape[1], x.shape[2], x.shape[3]), len(regions))
            else:
                pass

            # Compute RMAC vector
            RMAC = model.predict([x, np.expand_dims(regions, axis=0)])

            encoded_images[name] = [RMAC]
        except:
            corrupts.append(files[i])
        counter += 1
        if counter % 10000 == 0:
            encoded = pd.DataFrame(encoded_images).T
            encoded.to_csv(FLAGS.prefix + '003_image_matching/keras_rmac-master/census2021outputs/census2011_zoom_rmac_feature_vector_zoom_%s.csv' % str(FLAGS.end))
            print('Completed image %s in %s seconds!' % (str(counter) + '_' + name, str(time.time() - start_time) ))
            print ('There are %s corrupt files' %len(corrupts))

encoded = pd.DataFrame(encoded_images).T
encoded.to_csv(FLAGS.prefix + '003_image_matching/keras_rmac-master/census2021outputs/census2011_zoom_rmac_feature_vector_zoom_%s.csv' % str(FLAGS.end))
print (corrupts)


from unittest.mock import Mock, patch

import botocore.session
from botocore.exceptions import ParamValidationError
from moto import (  # pylint: disable=import-error
    mock_ec2,
    mock_kinesis,
    mock_kms,
    mock_lambda,
    mock_s3,
    mock_sqs,
)

from opentelemetry.instrumentation.botocore import BotocoreInstrumentor
from opentelemetry.sdk.resources import Resource
from opentelemetry.test.test_base import TestBase

def assert_span_http_status_code(span, code):
    """Assert on the span"s "http.status_code" tag"""
    tag = span.attributes["http.status_code"]
    assert tag == code, "%r != %r" % (tag, code)

class TestBotocoreInstrumentor(TestBase):
    """Botocore integration testsuite"""

    def setUp(self):
        super().setUp()
        BotocoreInstrumentor().instrument()

        self.session = botocore.session.get_session()
        self.session.set_credentials(
            access_key="access-key", secret_key="secret-key"
        )

    def tearDown(self):
        super().tearDown()
        BotocoreInstrumentor().uninstrument()

    @mock_ec2
    def test_traced_client(self):
        ec2 = self.session.create_client("ec2", region_name="us-west-2")

        ec2.describe_instances()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 1)
        self.assertEqual(span.attributes["aws.agent"], "botocore")
        self.assertEqual(span.attributes["aws.region"], "us-west-2")
        self.assertEqual(span.attributes["aws.operation"], "DescribeInstances")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(
                attributes={
                    "endpoint": "ec2",
                    "operation": "describeinstances",
                }
            ),
        )
        self.assertEqual(span.name, "ec2.command")

    @mock_ec2
    def test_not_recording(self):
        mock_tracer = Mock()
        mock_span = Mock()
        mock_span.is_recording.return_value = False
        mock_tracer.start_span.return_value = mock_span
        mock_tracer.use_span.return_value.__enter__ = mock_span
        mock_tracer.use_span.return_value.__exit__ = True
        with patch("opentelemetry.trace.get_tracer") as tracer:
            tracer.return_value = mock_tracer
            ec2 = self.session.create_client("ec2", region_name="us-west-2")
            ec2.describe_instances()
            self.assertFalse(mock_span.is_recording())
            self.assertTrue(mock_span.is_recording.called)
            self.assertFalse(mock_span.set_attribute.called)
            self.assertFalse(mock_span.set_status.called)

    @mock_ec2
    def test_traced_client_analytics(self):
        ec2 = self.session.create_client("ec2", region_name="us-west-2")
        ec2.describe_instances()

        spans = self.memory_exporter.get_finished_spans()
        assert spans

    @mock_s3
    def test_s3_client(self):
        s3 = self.session.create_client("s3", region_name="us-west-2")

        s3.list_buckets()
        s3.list_buckets()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 2)
        self.assertEqual(span.attributes["aws.operation"], "ListBuckets")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(
                attributes={"endpoint": "s3", "operation": "listbuckets"}
            ),
        )

        # testing for span error
        self.memory_exporter.get_finished_spans()
        with self.assertRaises(ParamValidationError):
            s3.list_objects(bucket="mybucket")
        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[2]
        self.assertEqual(
            span.resource,
            Resource(
                attributes={"endpoint": "s3", "operation": "listobjects"}
            ),
        )

    # Comment test for issue 1088
    @mock_s3
    def test_s3_put(self):
        params = dict(Key="foo", Bucket="mybucket", Body=b"bar")
        s3 = self.session.create_client("s3", region_name="us-west-2")
        location = {"LocationConstraint": "us-west-2"}
        s3.create_bucket(Bucket="mybucket", CreateBucketConfiguration=location)
        s3.put_object(**params)

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 2)
        self.assertEqual(span.attributes["aws.operation"], "CreateBucket")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(
                attributes={"endpoint": "s3", "operation": "createbucket"}
            ),
        )
        self.assertEqual(spans[1].attributes["aws.operation"], "PutObject")
        self.assertEqual(
            spans[1].resource,
            Resource(attributes={"endpoint": "s3", "operation": "putobject"}),
        )
        self.assertEqual(spans[1].attributes["params.Key"], str(params["Key"]))
        self.assertEqual(
            spans[1].attributes["params.Bucket"], str(params["Bucket"])
        )
        self.assertTrue("params.Body" not in spans[1].attributes.keys())

    @mock_sqs
    def test_sqs_client(self):
        sqs = self.session.create_client("sqs", region_name="us-east-1")

        sqs.list_queues()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 1)
        self.assertEqual(span.attributes["aws.region"], "us-east-1")
        self.assertEqual(span.attributes["aws.operation"], "ListQueues")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(
                attributes={"endpoint": "sqs", "operation": "listqueues"}
            ),
        )

    @mock_kinesis
    def test_kinesis_client(self):
        kinesis = self.session.create_client(
            "kinesis", region_name="us-east-1"
        )

        kinesis.list_streams()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 1)
        self.assertEqual(span.attributes["aws.region"], "us-east-1")
        self.assertEqual(span.attributes["aws.operation"], "ListStreams")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(
                attributes={"endpoint": "kinesis", "operation": "liststreams"}
            ),
        )

    @mock_kinesis
    def test_unpatch(self):
        kinesis = self.session.create_client(
            "kinesis", region_name="us-east-1"
        )

        BotocoreInstrumentor().uninstrument()

        kinesis.list_streams()
        spans = self.memory_exporter.get_finished_spans()
        assert not spans, spans

    @mock_sqs
    def test_double_patch(self):
        sqs = self.session.create_client("sqs", region_name="us-east-1")

        BotocoreInstrumentor().instrument()
        BotocoreInstrumentor().instrument()

        sqs.list_queues()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        self.assertEqual(len(spans), 1)

    @mock_lambda
    def test_lambda_client(self):
        lamb = self.session.create_client("lambda", region_name="us-east-1")

        lamb.list_functions()

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 1)
        self.assertEqual(span.attributes["aws.region"], "us-east-1")
        self.assertEqual(span.attributes["aws.operation"], "ListFunctions")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(
                attributes={"endpoint": "lambda", "operation": "listfunctions"}
            ),
        )

    @mock_kms
    def test_kms_client(self):
        kms = self.session.create_client("kms", region_name="us-east-1")

        kms.list_keys(Limit=21)

        spans = self.memory_exporter.get_finished_spans()
        assert spans
        span = spans[0]
        self.assertEqual(len(spans), 1)
        self.assertEqual(span.attributes["aws.region"], "us-east-1")
        self.assertEqual(span.attributes["aws.operation"], "ListKeys")
        assert_span_http_status_code(span, 200)
        self.assertEqual(
            span.resource,
            Resource(attributes={"endpoint": "kms", "operation": "listkeys"}),
        )

        # checking for protection on sts against security leak
        self.assertTrue("params" not in span.attributes.keys())


# -*- coding: utf-8 -*-
class Singleton(type):
    """ This is a Singleton metaclass. All classes affected by this metaclass
    have the property that only one instance is created for each set of arguments
    passed to the class constructor."""

    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(cls, bases, dict)
        cls._instanceDict = {}

    def __call__(cls, *args, **kwargs):
        argdict = {'args': args}
        argdict.update(kwargs)
        argset = frozenset(argdict)
        if argset not in cls._instanceDict:
            cls._instanceDict[argset] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instanceDict[argset]


import requests
import json
import os

def buscar_pokemon(nombre):
    url = f"https://pokeapi.co/api/v2/pokemon/{nombre.lower()}"
    response = requests.get(url)

    if response.status_code == 404:
        print("El Pokémon no fue encontrado.")
        return None

    data = response.json()
    imagen = data["sprites"]["front_default"]
    peso = data["weight"]
    altura = data["height"]
    movimientos = [movimiento["move"]["name"] for movimiento in data["moves"]]
    habilidades = [habilidad["ability"]["name"] for habilidad in data["abilities"]]
    tipos = [tipo["type"]["name"] for tipo in data["types"]]

    pokemon = {
        "nombre": nombre,
        "imagen": imagen,
        "peso": peso,
        "altura": altura,
        "movimientos": movimientos,
        "habilidades": habilidades,
        "tipos": tipos
    }

    return pokemon

def guardar_pokemon(pokemon):
    carpeta_pokedex = "pokedex"
    if not os.path.exists(carpeta_pokedex):
        os.makedirs(carpeta_pokedex)

    nombre_archivo = f"{carpeta_pokedex}/{pokemon['nombre']}.json"
    with open(nombre_archivo, "w") as archivo:
        json.dump(pokemon, archivo, indent=4)
    print(f"La información del Pokémon se ha guardado en {nombre_archivo}.")

def mostrar_info_pokemon(pokemon):
    print("Nombre:", pokemon["nombre"])
    print("Imagen:", pokemon["imagen"])
    print("Peso:", pokemon["peso"])
    print("Altura:", pokemon["altura"])
    print("Movimientos:", ", ".join(pokemon["movimientos"]))
    print("Habilidades:", ", ".join(pokemon["habilidades"]))
    print("Tipos:", ", ".join(pokemon["tipos"]))

# Ciclo principal del programa
while True:
    # Obtener el nombre del Pokémon desde el usuario
    nombre_pokemon = input("Ingrese el nombre de un Pokémon (o 'q' para salir): ")

    # Verificar si se quiere salir del programa
    if nombre_pokemon.lower() == "q":
        break

    # Buscar el Pokémon en la Pokédex
    pokemon = buscar_pokemon(nombre_pokemon)

    if pokemon:
        mostrar_info_pokemon(pokemon)
        guardar_pokemon(pokemon)


#IMPORTING LIBRARIES
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# READING DATA FROM TRAIN DATASET
data_1 = pd.read_csv('iosdml1_train.csv')
x_train = data_1.iloc[:, :2].values
y_train = data_1.iloc[:, -1].values
# READING DATA FROM TEST DATASET
data_2 = pd.read_csv('iosdml1_test.csv')
x_test = data_1.iloc[:, :2].values
y_test = data_1.iloc[:, -1].values
# FEATURE SCALING
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
x_train = sc.fit_transform(x_train)
x_test = sc.transform(x_test)
# KNN
from sklearn.neighbors import KNeighborsClassifier
klf = KNeighborsClassifier(n_neighbors=25)
klf.fit(x_train, y_train)
# TESTING A SAMPLE
print(klf.predict(sc.transform([[8.480100064,58.5780145]])))
# ACCURACY OF MODEL
y_pred = klf.predict(x_test)
from sklearn.metrics import confusion_matrix, accuracy_score
print(confusion_matrix(y_test, y_pred))
print(accuracy_score(y_test, y_pred))


import cv2
import numpy as np
import torch

class BaseTransform(object):
    def __init__(self, resize, rgb_means, swap=(2, 0, 1)):
        self.means = rgb_means
        self.resize = resize
        self.swap = swap

    def __call__(self, img):

        interp_methods = [cv2.INTER_LINEAR, cv2.INTER_CUBIC, cv2.INTER_AREA, cv2.INTER_NEAREST, cv2.INTER_LANCZOS4]
        interp_method = interp_methods[0]
        img = cv2.resize(np.array(img), (self.resize,
                                         self.resize),interpolation = interp_method).astype(np.float32)
        img -= self.means
        img = img.transpose(self.swap)
        return torch.from_numpy(img)


from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import QLabel, QPushButton, QFrame, QWidget, QVBoxLayout, QHBoxLayout
from PyQt5.QtGui import *
from modules.codeeditor import CodeEditor

def add(self):
	# Creacion del tab
	tab = QFrame(self.ui.pages)
	tab.setObjectName(u"file_"+str(self.tab_number))
	tab.setMinimumHeight(45)
	tab.setMaximumHeight(45)
	tab.setFrameShape(QFrame.StyledPanel)
	tab.setFrameShadow(QFrame.Raised)
	tab.setToolTip("Nuevo archivo *")
	tab.mousePressEvent = lambda x: self.change_actual(None, tab)

	file_layout = QHBoxLayout(tab)
	file_layout.setSpacing(0)
	file_layout.setObjectName(u"file_layout_"+str(self.tab_number))
	file_layout.setContentsMargins(4, 0, 5, 0)

	title = QLabel("Nuevo archivo *", tab)
	title.setObjectName(u"title_"+str(self.tab_number))

	btn_close = QPushButton(tab)
	btn_close.setObjectName(u"btn_close_"+str(self.tab_number))
	btn_close.setMinimumSize(QSize(28, 28))
	btn_close.setMaximumSize(QSize(28, 28))
	btn_close.setCursor(QCursor(Qt.PointingHandCursor))
	btn_close.clicked.connect(lambda: remove(self))

	file_layout.addWidget(title)
	file_layout.addWidget(btn_close)
	self.ui.Layout_pages.addWidget(tab)

	self.stacked_tabs.append(tab)

	# Creacion del text box
	widget = QWidget()
	widget.setObjectName(u"page_"+str(self.tab_number))
	# creacion del layout
	widget_layout = QVBoxLayout(widget)
	widget_layout.setSpacing(0)
	widget_layout.setObjectName(u"widget_layout_"+str(self.tab_number))
	widget_layout.setContentsMargins(0, 0, 0, 0)
	# Creacion del textbox
	textbox = CodeEditor(widget)
	textbox.setObjectName(u"document_"+str(self.tab_number))
	textbox.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)

	widget_layout.addWidget(textbox)

	self.ui.stackedWidget.addWidget(widget)

	self.tab_number += 1

def remove(self):
	#verificar si el archivo se ha guardado

	# obtengo el indice del tab a eliminar
	number_actual = self.sender().objectName().split("_")[-1]

	# Elimino el tab
	tab = self.ui.top.findChild(QFrame, "file_"+number_actual)
	tab.deleteLater()
	#elimino la pagina textbox
	page = self.ui.stackedWidget.findChild(QWidget, "page_"+number_actual)
	page.deleteLater()
	# remuevo el tab del stack
	self.stacked_tabs.remove(tab)

	# si mi stack se quedo sin tab debe cerrar la ventana
	if len(self.stacked_tabs) == 0:
		self.close()
		return

	# verifico si el ultimo tab seleccionado es el mismo al que se desea eliminar
	number_before = self.before_select.objectName().split("_")[-1]
	# si es asi, entonces elimino la referencia al tab
	if number_actual == number_before:
		# Cambiar el tab seleccionado
		self.change_actual(None, self.stacked_tabs[0])
		self.before_select = self.stacked_tabs[0]


class Solution(object):
    def kthSmallest(self, mat, k):
        """
        :type mat: List[List[int]]
        :type k: int
        :rtype: int
        """
        m, n = len(mat), len(mat[0])
        smallest = sum(mat[i][0] for i in range(m))
        hq = [[smallest] + [0] * m ]
        seen = set(tuple([0] * m))

        while k - 1:
            k -= 1
            prev = heapq.heappop(hq)

            for i in range(m):
                if prev[i + 1] == n - 1: continue
                total, idx = prev[0], prev[1:]

                total -= mat[i][idx[i]]
                idx[i] += 1
                total += mat[i][idx[i]]

                if tuple(idx) not in seen:
                    seen.add(tuple(idx))
                    heapq.heappush(hq, [total] + idx)

        return heapq.heappop(hq)[0]


file = open('연락처.txt','rt')
line_list = file.readlines()
count = 0
idx = 0
for line in line_list:
    arr = line.split(",")
    tel = arr[2]
    if tel[:3].count('751') == 1:
        tel = tel.replace('751','010')
        count += 1
        arr[2] = tel
        line_list[idx] = ",".join(arr)
    idx += 1
file.close()
file = open('연락처.txt','wt')
for line in line_list:
    file.write(line)
file.close()
print('총 {}건의 751 데이터를 찾았습니다.'.format(count))
print('모든 데이터를 수정했습니다.')


import ply.lex as lex

# List of token names.   This is always required
reserved = {
    'if': 'IF',
    'then': 'THEN',
    'else': 'ELSE',
    'while': 'WHILE',
    "switch": "SWITCH",
    'bool': "BOOL",
    'char': "CHAR",
    'byte': "BYTE",
    'short': "SHORT",
    'int': "INT",
    'long': "LONG",
    'double': "DOUBLE",
    'float': "FLOAT",
    'main': "MAIN",
    'class': "CLASS",
    'pub': "PUBLIC",
    'pri': "PRIVATE",
    'pro ': "PROTECTED",
    'static': "STATIC"
}

# (?i) - case insensitive

tokens = [
             'NUMBER',
             'PLUS',
             'MINUS',
             'TIMES',
             'DIVIDE',
             'ID',
             'COMMENT',
             'NEWLINE'
         ] + list(reserved.values())

# Regular expression rules for simple tokens

t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'

literals = [';', '=', '(', ')', '{', '}', ',']

# A regular expression rule with some action code
def t_NUMBER(t):
    r'\d+'
    t.value = int(t.value)
    return t

# Define a rule so we can track line numbers
def t_NEWLINE(t):
    r'\n+'
    t.lexer.lineno += len(t.value)

# A string containing ignored characters (spaces and tabs)
t_ignore = ' \t'

# Error handling rule
def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

def t_ID(t):
    r'[a-zA-Z_][a-zA-Z_0-9]*'
    t.type = reserved.get(t.value, 'ID')  # Check for reserved words
    return t

def t_COMMENT(t):
    r'\//.*'
    pass

# Build the lexer
lexer = lex.lex()

# Test it out
data = '''
3 + 4 * 10
  + -20 *2
  if
  //
'''

# Give the lexer some input
lexer.input(data)

# # Tokenize
# for tok in lexer:
#     print(tok.type, tok.value, tok.lineno, tok.lexpos)


from django.shortcuts import render, get_object_or_404, redirect
from recipes.models import Recipe
from recipes.forms import RecipeForm

# SHOW_RECIPE
def show_recipe(request, id):
    recipe = get_object_or_404(Recipe, id=id)
    context = {
        "recipe_object": recipe,
    }
    return render(request, "recipes/detail.html", context)

# RECIPE_LIST
def recipe_list(request):
    recipes = Recipe.objects.all()
    context = {
        "recipe_list": recipes,
    }
    return render(request, "recipes/list.html", context)

# CREATE_RECIPE
def create_recipe(request):
    if request.method == "POST":
        form = RecipeForm(request.POST)

        if form.is_valid():
            form.save()
            return redirect("recipe_list")
    else:
        form = RecipeForm()

    context = {
        "form": form,
    }

    return render(request, "recipes/create.html", context)

# EDIT_RECIPE
def edit_recipe(request, id):
    recipe = get_object_or_404(Recipe, id=id)

    if request.method == "POST":
        form = RecipeForm(request.POST, instance=recipe)
        if form.is_valid():
            form.save()

            return redirect("show_recipe", id=id)

    else:
        form = RecipeForm(instance=recipe)

    context = {
        "recipe_object": recipe,
        "form": form,
    }
    return render(request, "recipes/edit.html", context)