# Dash & Plotly Modules
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_flexbox_grid as dfx
from dash.dependencies import Input, Output, State
import dash_table
import dash_dangerously_set_inner_html
from dash.exceptions import PreventUpdate
import plotly.express as px
import dash_dangerously_set_inner_html

#Python Generic & Local Modules
import base64
import shap, eli5
from config import *
from ml_utils_xai import *
import pandas as pd

external_stylesheets = [dbc.themes.BOOTSTRAP]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

df = pd.read_csv('Data/Output/test.csv')
app.layout = html.Div([
    dcc.Tabs([
        dcc.Tab(label='Metrics', children=[
            html.Div([html.H2("Performance Metrics: ")], style={'marginLeft': 10, 'marginBottom': 50, 'marginTop': 25}),
            dbc.Row(
                [
                    dbc.Col(html.Div([html.Img(src = encodedImage('ROCAUC.png'), id = 'rocauc_image', height=700, width=720)])),
                    dbc.Col(html.Div([html.Img(src = encodedImage('ClassificationReport.png'), id = 'classificationreport_image', height=700, width=720)])),
                ]
            ),
            dbc.Row(
                [
                    dbc.Col(html.Div([html.Img(src = encodedImage('PrecisionRecallCurve.png'), id = 'precisionrecall_image', height=700, width=720)])),
                    dbc.Col(html.Div([html.Img(src = encodedImage('ConfusionMatrix.png'), id = 'confusion_matrix_image', height=700, width=720)])),
                ]
            )
        ]),

        dcc.Tab(label='Explainable AI - SHAP', children=[
            html.Div([html.H2(" Feature Importance With SHAP: ")], style={'marginLeft': 10, 'marginBottom': 50, 'marginTop': 25}),
            html.Div([html.H4("Please Choose a Death Event Label: ")], style={'marginLeft': 10, 'marginTop': 25}),
            dcc.Dropdown(id = 'shapLabelOption',  options=[
                    {'label':'Benign', 'value': 0},
                    {'label':'Death', 'value':1}
                ]
                , value = 1
                , style={'width':300,'paddingLeft':10 }),

            dbc.Row(
            [
                dbc.Col(html.Div([dcc.Graph(id='shapBarPlot')], style = {'marginTop':55}))
            ]
            ),
        ]),
        dcc.Tab(label='Explainable AI - ELI5', children=[
            html.Div([html.H2(" Explain Datapoint Prediction with ELI5: ")], style={'marginLeft': 10, 'marginBottom': 50, 'marginTop': 25}),

            dbc.Row(
                [
                    dbc.Col([
                            html.Div([html.H4("Test Dataset: ")], style={'marginLeft': 10, 'marginBottom': 50, 'marginTop': 25}),
                            html.Div([
                            dash_table.DataTable(
                                    data=df.to_dict('records'),
                                    columns=[{'id': c, 'name': c} for c in df.columns],
                                    style_table={'height': '400px', 'overflowY': 'auto'}
                                )
                            ], style={'marginLeft': 10, 'marginTop': 150, 'marginTop': 25}),
                            html.Div([html.H4("Enter an index row for analysis: ")], style={'marginTop':10,'marginLeft': 10, 'marginBottom': 15, 'marginTop': 25}),
                            html.Div(dbc.Input(id='rowIndex', type='number', value = 0 , style={'marginLeft': 10,'width':125})),
                            html.Div(dbc.Button('Submit', id='eli5Button', n_clicks=0, style={'marginLeft': 10, 'marginBottom': 50, 'marginTop': 10})),
                            html.Div(id='eli5Table', style = {'marginLeft': 10, 'marginBottom': 50,'marginTop':10})]),
                ],
            ),
        ]),
    ]),

])

@app.callback(Output('shapBarPlot', 'figure'),
              [Input('shapLabelOption','value')])
def shapCallback(shapLabelOption):
    """
    SHAP Global Interpretability Callback - Bar chart.
    Purpose: Visualize feature importance from SHAP package
    Steps:
        1) Convert shap_values into a df
        2) Get the columns of the training dataset
        3) Assign the same column of the training dataset to the shap values dataframe
        4) Copy the train data df and reset the index so that it is compatible with shap value df
        5) Get  the correlation coefficient and append it to a new df (corr_df) - This will be use to plot the bar chart
    """
    # Load SHAP correlation Dataframe
    shapObjectName = 'RandomForestClassifier_SHAP_LABEL_{}'.format(shapLabelOption)
    outputShapCorrelationDataframe = loadObject(shapObjectName, OUTPUT_PATH)

    # Generate Shap figure
    shapFigure = px.bar(outputShapCorrelationDataframe, x="Features", y="Correlation",title="<b>Feature Importance (Postive/Negative) Correlation <br>",
            height=650, width = 1200,color = np.where(outputShapCorrelationDataframe['Correlation']>0,'Positive Correlation','Negative Correlation'))
    return shapFigure

@app.callback(Output('eli5Table', 'children'),
    [Input('eli5Button','n_clicks')],
    [State('rowIndex', 'value')])
def eli5Callback(clicks, rowIndex):
    """
    ELI5 Local Interpretability Callback - Output results table.
    Purpose: Visualize ELI5 explanation table
    """
    modelName = "RandomForestClassifier"
    trainedModel = loadObject(modelName, OUTPUT_PATH)
    testDataset = pd.read_csv(OUTPUT_PATH + 'test.csv')

    #Calls EL5 explain prediction API - Format as HTML
    explainPredictionObject = eli5.explain_prediction(trainedModel, testDataset.iloc[rowIndex], top=10, target_names= {0: ' Benign', 1:' Death'})
    HTMLFormat = eli5.format_as_html(explainPredictionObject, show=('targets','decision_tree','transition_features'))

    #Construct ELI5 table
    tableHeader = [html.Thead(html.Tr([html.Th("Row #"+ str(rowIndex))]), style={"fontSize":14})]
    tableBody = [html.Tbody(dash_dangerously_set_inner_html.DangerouslySetInnerHTML(HTMLFormat), style={"fontSize":14})]
    outputELI5Table = dbc.Table(tableHeader + tableBody, hover=True, responsive=True, striped=True)

    return outputELI5Table
if __name__ == '__main__':
    app.run_server(debug=False)


# from argparse import ArgumentParser
from PIL import Image, ImageFont, ImageDraw
from config import Input_shape, channels, threshold, ignore_thresh, path
from network_function import YOLOv3
from detect_function import predict
from utils.yolo_utils import read_anchors, read_classes, letterbox_image  # , resize_image
from timeit import default_timer as timer  # to calculate FPS
from pathlib import Path
import numpy as np
import tensorflow as tf
import argparse
import colorsys
import random
import sys
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
# from tensorflow.python.client import device_lib
# print(device_lib.list_local_devices())

class YOLO(object):
    def __init__(self):

        self.anchors_path = path + '/yolo3/model/yolo_anchors.txt'
        self.COCO = False
        self.trainable = False

        args1 = sys.argv[2]
        if args1=='COCO':
            print("-----------COCO-----------")
            self.COCO = True
            self.classes_path = path + '/yolo3/model/coco_classes.txt'
            self.trainable = False
        elif args1=='VOC':
            print("-----------VOC------------")
            self.classes_path = path + '/yolo3/model/voc_classes.txt'
        elif args1=='boat':
            print("-----------boat-----------")
            self.classes_path = path + '/yolo3/model/boat_classes.txt'

        # args = self.argument()
        # if args.COCO:
        #     print("-----------COCO-----------")
        #     self.COCO = True
        #     self.classes_path = self.PATH + '/model/coco_classes.txt'
        #     self.trainable = False
        # elif args.VOC:
        #     print("-----------VOC------------")
        #     self.classes_path = self.PATH + '/model/voc_classes.txt'
        # elif args.boat:
        #     print("-----------boat-----------")
        #     self.classes_path = self.PATH + '/model/boat_classes.txt'

        self.class_names = read_classes(self.classes_path)
        self.anchors = read_anchors(self.anchors_path)
        self.threshold = 0.5# threshold
        self.ignore_thresh = ignore_thresh
        self.INPUT_SIZE = (Input_shape, Input_shape)  # fixed size or (None, None)
        self.is_fixed_size = self.INPUT_SIZE != (None, None)
        # LOADING SESSION...
        self.boxes, self.scores, self.classes, self.sess = self.load()

    @staticmethod
    def argument():
        parser = argparse.ArgumentParser(description='COCO or VOC or boat')
        parser.add_argument('--COCO', action='store_true', help='COCO flag')
        parser.add_argument('--VOC', action='store_true', help='VOC flag')
        parser.add_argument('--boat', action='store_true', help='boat flag')
        args = parser.parse_args()
        return args
    def load(self):
        # Remove nodes from graph or reset entire default graph
        tf.reset_default_graph()

        # Generate colors for drawing bounding boxes.
        hsv_tuples = [(x / len(self.class_names), 1., 1.) for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors))
        random.seed(10101)  # Fixed seed for consistent colors across runs.
        random.shuffle(self.colors)  # Shuffle colors to decorrelate adjacent classes.
        random.seed(None)  # Reset seed to default.

        # Generate output tensor targets for filtered bounding boxes.
        self.x = tf.placeholder(tf.float32, shape=[None, Input_shape, Input_shape, channels])
        self.image_shape = tf.placeholder(tf.float32, shape=[2, ])
        # self.is_training = tf.placeholder(tf.bool)
        # image_shape = np.array([image.size[0], image.size[1]])  # tf.placeholder(tf.float32, shape=[2,])

        # Generate output tensor targets for filtered bounding boxes.
        # scale1, scale2, scale3 = YOLOv3(self.x, len(self.class_names), trainable=self.trainable, is_training=self.is_training).feature_extractor()
        scale1, scale2, scale3 = YOLOv3(self.x, len(self.class_names), trainable=self.trainable).feature_extractor()
        scale_total = [scale1, scale2, scale3]

        # detect
        boxes, scores, classes = predict(scale_total, self.anchors, len(self.class_names), self.image_shape,
                                         score_threshold=self.threshold, iou_threshold=self.ignore_thresh)

        # Add ops to save and restore all the variables
        saver = tf.train.Saver(var_list=None if self.COCO==True else tf.trainable_variables())

        # Allowing GPU memory growth

        config = tf.ConfigProto()
        config.gpu_options.allow_growth = True
        sess = tf.Session(config = config)
        sess.run(tf.global_variables_initializer())
        epoch = input('Entrer a check point at epoch:')
        # For the case of COCO
        epoch = epoch if self.COCO == False else 2000
        checkpoint = path + "/yolo3/save_model/SAVER_MODEL_boat10/model.ckpt-" + str(epoch)
        try:
            aaa = checkpoint + '.meta'
            my_abs_path = Path(aaa).resolve()
        except FileNotFoundError:
            print("Not yet training!")
        else:
            saver.restore(sess, checkpoint)
            print("checkpoint: ", checkpoint)
            print("already training!")

        return boxes, scores, classes, sess

    def detect_image(self, image):
        # Generate colors for drawing bounding boxes.
        hsv_tuples = [(x / len(self.class_names), 1., 1.) for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors))
        random.seed(10101)  # Fixed seed for consistent colors across runs.
        random.shuffle(self.colors)  # Shuffle colors to decorrelate adjacent classes.
        random.seed(None)  # Reset seed to default.

        if self.is_fixed_size:
            assert self.INPUT_SIZE[0] % 32 == 0, 'Multiples of 32 required'
            assert self.INPUT_SIZE[1] % 32 == 0, 'Multiples of 32 required'
            boxed_image, image_shape = letterbox_image(image, tuple(reversed(self.INPUT_SIZE)))
            # boxed_image, image_shape = resize_image(image, tuple(reversed(self.INPUT_SIZE)))
        else:
            new_image_size = (image.width - (image.width % 32), image.height - (image.height % 32))
            boxed_image, image_shape = letterbox_image(image, new_image_size)
            # boxed_image, image_shape = resize_image(image, new_image_size)
        image_data = np.array(boxed_image, dtype='float32')

        print("heights, widths:", image_shape)
        image_data /= 255.
        inputs = np.expand_dims(image_data, 0)  # Add batch dimension. #

        out_boxes, out_scores, out_classes = self.sess.run([self.boxes, self.scores, self.classes],
                                                           feed_dict={self.x: inputs,
                                                                      self.image_shape: image_shape,
                                                                      # self.is_training: False
                                                                      })

        print('Found {} boxes for {}'.format(len(out_boxes), 'img'))

        # Visualisation#################################################################################################
        font = ImageFont.truetype(font=path + '/yolo3/model/font/FiraMono-Medium.otf', size=np.floor(3e-2 * image.size[1] + 0.5).astype(np.int32))
        thickness = (image.size[0] + image.size[1]) // 500  # do day cua BB

        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = self.class_names[c]
            box = out_boxes[i]
            score = out_scores[i]

            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)

            top, left, bottom, right = box  # y_min, x_min, y_max, x_max
            top = max(0, np.floor(top + 0.5).astype(np.int32))
            left = max(0, np.floor(left + 0.5).astype(np.int32))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype(np.int32))
            right = min(image.size[0], np.floor(right + 0.5).astype(np.int32))
            print(label, (left, top), (right, bottom))  # (x_min, y_min), (x_max, y_max)

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            # My kingdom for a good redistributable image drawing library.
            for j in range(thickness):
                draw.rectangle([left + j, top + j, right - j, bottom - j], outline=self.colors[c])
            draw.rectangle([tuple(text_origin), tuple(text_origin + label_size)], fill=self.colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw
        return image

def detect_video(yolo, video_path=None, output_video=None):
    import urllib.request as urllib
    import cv2

    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    fps = 20.0  # display fps frame per second
    accum_time = 0
    curr_fps = 0
    prev_time = timer()
    if video_path=='stream':
        url = 'http://10.18.97.1:8080/shot.jpg'
        out = cv2.VideoWriter(output_video, fourcc, fps, (1280, 720))
        while True:

            # Use urllib to get the image and convert into a cv2 usable format
            imgResp = urllib.urlopen(url)
            imgNp = np.array(bytearray(imgResp.read()), dtype=np.uint8)
            img = cv2.imdecode(imgNp, -1)
            # print(np.shape(img))  # get w, h from here

            image = Image.fromarray(img)
            image = yolo.detect_image(image)
            result = np.asarray(image)

            curr_time = timer()
            exec_time = curr_time - prev_time
            prev_time = curr_time
            accum_time = accum_time + exec_time
            curr_fps = curr_fps + 1
            if accum_time > 1:
                accum_time = accum_time - 1
                fps = "FPS: " + str(curr_fps)
                curr_fps = 0
            cv2.putText(result, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                        fontScale=0.50, color=(255, 0, 0), thickness=2)
            # cv2.namedWindow("result", cv2.WINDOW_NORMAL)
            cv2.imshow("Result", result)
            out.write(result)

            # To give the processor some less stress
            # time.sleep(0.1)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        out.release()
        # Closes all the frames
        cv2.destroyAllWindows()

        yolo.sess.close()
    else:
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            raise IOError("Couldn't open webcam or video")
        # The size of the frames to write
        w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        out = cv2.VideoWriter(output_video, fourcc, fps, (w, h))
        while True:
            ret, frame = cap.read()
            if ret==True:
                image = Image.fromarray(frame)

                image = yolo.detect_image(image)
                result = np.asarray(image)

                curr_time = timer()
                exec_time = curr_time - prev_time
                prev_time = curr_time
                accum_time = accum_time + exec_time
                curr_fps = curr_fps + 1
                if accum_time > 1:
                    accum_time = accum_time - 1
                    fps = "FPS: " + str(curr_fps)
                    curr_fps = 0
                cv2.putText(result, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                            fontScale=0.50, color=(255, 0, 0), thickness=2)
                cv2.namedWindow("Result", cv2.WINDOW_NORMAL)
                cv2.imshow("Result", result)

                out.write(result)

                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
            else:
                break
        cap.release()
        out.release()
        # Closes all the frames
        cv2.destroyAllWindows()

        yolo.sess.close()

def detect_img(yolo, output=''):
    while True:
        img = input('Input image filename:')
        try:
            img = path + '/yolo3' + str(img)
            image = Image.open(img)
        except:
            print('Open Error! Try again!')
            continue
        else:
            r_image = yolo.detect_image(image)
            r_image.save(output)
            r_image.show()

    yolo.sess.close()

if __name__ == '__main__':
    choose = sys.argv[1]
    if choose=='image':
        output = sys.argv[3]
        detect_img(YOLO(), output)
    elif choose=='video':
        video_path = sys.argv[3]
        output = sys.argv[4]
        detect_video(YOLO(), video_path, output)


from collections import defaultdict

class ATM:

    def __init__(self):
        self.notectr = defaultdict(int)

    def deposit(self, banknotesCount: List[int]) -> None:
        for i in range(5):
            self.notectr[[20, 50, 100, 200, 500][i]] += banknotesCount[i]

    def withdraw(self, amount: int) -> List[int]:
        currnotectr = self.notectr.copy()
        for note in [500, 200, 100, 50, 20]:
            notesused = min(amount // note, currnotectr[note])
            amount -= notesused * note
            currnotectr[note] -= notesused
            if amount == 0:
                break
        if amount != 0:
            return [-1]
        used = [self.notectr[note] - currnotectr[note] for note in [20, 50, 100, 200, 500]]
        self.notectr = currnotectr
        return used

# Your ATM object will be instantiated and called as such:
# obj = ATM()
# obj.deposit(banknotesCount)
# param_2 = obj.withdraw(amount)


def get_M(n):
	M = []
	for i in range(n):
		A = list(map(int, input().split()))
		M.append(A)
	print('\n')
	return M

def PRINT(A):
    for i in range(len(A)):
        print(' '.join(map(str, A[i])))
    print('\n')

def move_line(A, i, st, uord):
	if st:
		if uord:
			for k in range(i, len(A) - i - 1):
				A[k][i] = A[k + 1][i]
		else:
			for k in range(len(A) - i - 1, i, -1):
				A[k][i] = A[k - 1][i]
	elif uord:
		for k in range(len(A) - i - 1, i, -1):
			A[i][k] = A[i][k - 1]
	else:
		for k in range(i, len(A) - i - 1):
			A[i][k] = A[i][k + 1]

def chng_crl(A, i):
	for k in range(len(A) - i - 1):
		p = A[i][i]
		move_line(A, i, 1, 1)
		PRINT(A)
		move_line(A, len(A) - i - 1, 0, 0)
		PRINT(A)
		move_line(A, len(A) - i - 1, 1, 0)
		PRINT(A)
		move_line(A, i, 0, 1)
		A[i][i + 1] = p

def Rotate(A):
	i = 1
	while i != n // 2:
		chng_crl(A, i)
		PRINT(A)
		i += 1

n = int(input())
M = get_M(n)
Rotate(M)
PRINT(M)


from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from Tasks.task10.pages.campaign_page import CampaignPage
from Tasks.task10.pages.checkout_page import CheckoutPage
import time

class Application:

    def __init__(self):
        self.driver = webdriver.Chrome(ChromeDriverManager().install())
        #self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(1)
        self.base_url = "http://localhost/litecart"
        self.campaign_tab = CampaignPage(self.driver)
        self.checkout_page = CheckoutPage(self.driver)

    def quit(self):
        self.driver.quit()

    def open_campaign(self):
        self.campaign_tab.open(self.base_url)

    def buy_first_product(self):
        # Condition: items in cart should increase:
        self.init_cart = self.get_items_from_cart()
        self.final_cart = self.init_cart + 1

        # Add it:
        self.campaign_tab.add_item_to_cart()
        self.campaign_tab.close_item()

        # Wait until cart's items is updated:
        self.campaign_tab.wait_for_cart(str(self.final_cart))

    def get_items_from_cart(self):
        # Check current items in the cart:
        return self.campaign_tab.check_items()

    def purge_cart(self):
        self.checkout_page.open()
        self.checkout_page.remove_items()

    def is_cart_empty(self):
        try:
            self.checkout_page.open()
        finally:
            return not self.checkout_page.check_shopping_cart()

    def is_cart_full(self):
        try:
            self.checkout_page.open()
        finally:
            return self.checkout_page.check_shopping_cart()


import os
import arquitecto
import plano
nomb_arq=os.sys.argv[1]
modelo_plano=os.sys.argv[2]
p1=plano.Plano(modelo_plano,5,1200,"A","hd")
a1=arquitecto.Arquitecto(nomb_arq,23,3,p1,"m")
print("arquitecto:"+a1.getNombre())
print("plano:"+p1.getModelo())
a1.setPlano(p1)
print(a1.proyectar())


# This is a sample Python script.

# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
from gooey import Gooey,GooeyParser

def hello(name):
    # Use a breakpoint in the code line below to debug your script.
    return f'Hi, {name}'  # Press Ctrl+F8 to toggle the breakpoint.

# Press the green button in the gutter to run the script.
@Gooey(program_name='Hello app')
def main():
    parser = GooeyParser(description="GUI Hello Program")
    parser.add_argument('name',help="Please enter your real name")
    args = parser.parse_args()
    print(hello(args.name))

if __name__ == '__main__':
    main()

# See PyCharm help at https://www.jetbrains.com/help/pycharm/


from collections import namedtuple
from operator import attrgetter

metro_data = [
    ('Tokyo', 'JP', 36.93, (35.68, 139.69)),
    ('Delhi NCR', 'IN', 21.94, (28.61, 77.21)),
    ('Mexico City', 'MX', 20.14, (19.43, -99.13)),
    ('New York-Newark', 'US', 20.1, (40.81, -74.02)),
    ('Sao Paulo', 'BR', 19.65, (-23.55, -46.64))
]
LatLon = namedtuple('LatLon', 'lat lon')
Metropolis = namedtuple('Metropolis', 'name cc pop coord')
metro_areas = [Metropolis(name, cc, pop, LatLon(lat, lon)) for name, cc, pop, (lat, lon) in metro_data]
print(metro_areas[0].coord.lat)

# attrgetter 创建的函数会根据名称来提取对象的属性
name_let = attrgetter('name', 'coord.lat')
for city in sorted(metro_areas, key=attrgetter('coord.lat')):
    print(name_let(city))


from django.conf import settings as django_settings
from datetime import datetime
from fabric.api import *
import django
import yaml
import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "microsite.settings")
django.setup()

def build_documents():
    books_dir = os.path.join(django_settings.BASE_DIR, 'books')
    books_source_dir = os.path.join(django_settings.BASE_DIR, 'books/source')
    documents_file = open(os.path.join(books_dir, 'books.yml'), 'r')
    data = yaml.load(documents_file)

    # Update the books modified date in books.yml file
    for position, book in data.get('documents').iteritems():
        book["updated_date"] = datetime.fromtimestamp(
            os.path.getmtime(books_source_dir + '/' + book.get("folder_name")))

    with open(os.path.join(books_dir, 'books.yml'), 'w') as f:
        yaml.dump(data, f, default_flow_style=False)

    # Remove the templates(build) directory, if exists
    books_templates_dir = os.path.join(
        django_settings.BASE_DIR, 'books/templates')
    if os.path.exists(books_templates_dir):
        local("rm -rf %s" % books_templates_dir)

    # Build documents(.rst files to HTML files) using Sphinx command.
    local("cd books && make html")


class Atm():
    def __init__(self,card_number,pin_number):
        self.card_number = card_number
        self.pin_number = pin_number

    def cashWithdrawal(self,amount):
        self.amount = amount
        print("You withdrawed " + self.amount)

    def balanceEnquiry(self):
        print("Your current balance is : 10000")

card_num = input("Enter your card number : ")
pin_num = input("Enter the pin of your card : ")
withdraw = input("How much cash you want to withdraw : ")

atmObject = Atm(card_num,pin_num)
atmObject.cashWithdrawal(withdraw)
atmObject.balanceEnquiry()


import pandas as pd
import streamlit as st

# function to preprocess the data file and remove redundant data based on the week of the date provided in file.
@st.cache()
def pre_process(data):
    countyColumns = data[['countyFIPS', 'County Name']]
    week_df = data.drop(['countyFIPS', 'County Name', 'State', 'StateFIPS'], axis=1)
    week_df = week_df.diff(axis=1)
    week_df = week_df.T.reset_index()
    week_df['week'] = week_df['index']
    week_df = week_df.drop(columns='index')
    week_df['week'] = week_df['week'].astype('datetime64[ns]')
# find start and end date of the file containing full weeks only
    start = week_df[week_df['week'].dt.dayofweek == 6].first_valid_index()
    end = week_df[week_df['week'].dt.dayofweek == 5].last_valid_index()
# slice dataframe to only consider full weeks
    week_df = week_df[start:end + 1]
    grouped = week_df.resample('w-sun', label='left', closed='left', on='week').sum()
    table = pd.merge(countyColumns, grouped.T, left_index=True, right_index=True)
    return table

# function to calculate rate for cases per 100000
@st.cache()
def rate(confirmed_data, population):
    df = pd.merge(confirmed_data, population, left_on=['countyFIPS'], right_on=['countyFIPS'])
    df['countyFIPS'] = df['countyFIPS'].apply(lambda x: '0' + x if len(x) == 4 else x)
    county = df[['countyFIPS','County Name']]
    finalTable = df.drop(['countyFIPS','County Name'], axis=1).apply(lambda x:( x / df['population']) * 100000)
    finalTable = finalTable.drop(['population'], axis=1)
    finalTable.columns = pd.to_datetime(finalTable.columns, utc=True).date
    finalTable.columns = finalTable.columns.astype(str)
    columns = finalTable.columns.values.tolist()
    final_df = pd.merge(county, finalTable, left_index=True, right_index=True)
    final_df = final_df.drop(final_df[final_df['countyFIPS'] == '0'].index)
    return final_df, columns


import turtle
import pandas

screen= turtle.Screen()
image= "Day 15+\Day 25 Sporcle\india3.gif"
screen.title("Indian Sporcle")
screen.setup(width=600, height=600)
screen.addshape(image)

turtle.shape(image)

def get_mouse_click_coor(x, y):
    print(x, y)

turtle.onscreenclick(get_mouse_click_coor)

data= pandas.read_csv("Day 15+\Day 25 Sporcle\indian_states.csv")
states= data.state.to_list()
guessed_states= []

while len(guessed_states) < 28:
    answer= screen.textinput(f"{len(guessed_states)}/28 are correct", prompt="What's other state's name?").title()
    if answer == "Exit":
    #     remaining_states=[]
    #     for i in states:
    #         if i not in guessed_states:
    #             remaining_states.append(i)
        remaining_states=[i for i in states if i not in guessed_states]
        states_to_learn= pandas.DataFrame(remaining_states)
        states_to_learn.to_csv("Day 15+\Day 25 Sporcle\states_to_learn")
        break
    if answer in states:
        t= turtle.Turtle()
        state_data= data[data.state == answer]
        guessed_states.append(answer)
        t.hideturtle()
        t.penup()
        t.pencolor("black")
        t.goto(int(state_data.x), int(state_data.y))
        t.write(answer)

# # turtle.mainloop()
# screen.exitonclick()


from imageProjection import *
from featureAssociation import *
import os
if __name__ == "__main__":
    argparser = argparse.ArgumentParser(
        description=__doc__)
    argparser.add_argument(
        '--flag',
        default=0,
        type=int,
        help='0: initial cloud, 1: initial cloud with colors, 2: segmented cloud, 3: ground points, 4: remove ground points')
    argparser.add_argument(
        '--data',
        default=0,
        type=int,
        help='0: initial data, 1: another data')
    args = argparser.parse_args()

    '''
    lidarCount = loadLidarData("lidarTestRaw_count.txt")
    lidarData_ori = loadLidarData("lidarTestRaw.txt")

    rangeMat = np.ones((N_SCAN, Horizon_SCAN)) * (-1)
    groundMat = np.zeros((N_SCAN, Horizon_SCAN))
    labelMat = np.zeros((N_SCAN, Horizon_SCAN))
    lidarData = projectPointCloud(lidarData_ori, ang_res_x, ang_res_y, N_SCAN, Horizon_SCAN, rangeMat)
    groundRemoval(lidarData, N_SCAN, Horizon_SCAN, groundScanInd, groundMat, labelMat, rangeMat)
    startRingIndex, endRingIndex, outlierCloud, segmentedCloudGroundFlag, segmentedCloudColInd, segmentedCloudRange, segmentedCloud = cloudSegmentation(lidarData, N_SCAN, Horizon_SCAN, groundScanInd, ang_res_x, ang_res_y, labelMat, rangeMat, groundMat)

    # dataList_seg = []
    # colorList_seg = []
    # for i in range(len(segmentedCloud)):
    #     if segmentedCloudGroundFlag[i]:
    #         colorList_seg.append(np.array([1,0,0]))
    #     else:
    #         colorList_seg.append(np.array([1,1,1]))
    #     dataList_seg.append(segmentedCloud[i])
    # dataList_seg = np.array(dataList_seg)
    # colorList_seg = np.array(colorList_seg)
    # dataList = removeEmptyData(lidarData)

    vis = False
    if vis:
        if args.flag == 0:
            print("All points: ", np.sum(lidarCount))
            visulizeLiadarData(removeEmptyData(lidarData_ori))

        elif args.flag == 2:
            visulizeLiadarData(dataList_seg, colorList_seg)
        elif args.flag == 3:
            for i in range(N_SCAN):
                for j in range(Horizon_SCAN):
                    if labelMat[i, j] != -2:
                        lidarData[i*Horizon_SCAN+j, 3] = 0
            visulizeLiadarData(removeEmptyData(lidarData))
        elif args.flag == 4:
            for i in range(N_SCAN):
                for j in range(Horizon_SCAN):
                    if labelMat[i, j] == -2:
                        lidarData[i*Horizon_SCAN+j, 3] = 0
            visulizeLiadarData(removeEmptyData(lidarData))
        else:
            dataList_other = []
            colorList_other = []
            for i in range(N_SCAN):
                for j in range(Horizon_SCAN):
                    if labelMat[i, j] == -1:
                        if lidarData[i*Horizon_SCAN + j, 3] == 0:
                            continue
                        dataList_other.append(lidarData[i*Horizon_SCAN + j, :])
                        colorList_other.append(np.array([0,1,0]))
            dataList_other = np.array(dataList_other)
            colorList_other = np.array(colorList_other)
            dataList_other = np.r_[dataList_other, dataList_seg]
            colorList_other = np.r_[colorList_other, colorList_seg]
            # print(dataList_other.shape, colorList_other.shape)
            visulizeLiadarData(dataList_other, colorList_other)

    segmentedCloud = np.array(segmentedCloud)
    cloudCurvature = np.zeros(segmentedCloud.shape[0])
    cloudNeighborPicked = np.zeros(segmentedCloud.shape[0])
    cloudLabel = np.zeros(segmentedCloud.shape[0])
    cloudSmoothness = np.zeros((segmentedCloud.shape[0],2))

    # calculateSmoothness(segmentedCloud, segmentedCloudRange, cloudCurvature, cloudNeighborPicked, cloudLabel, cloudSmoothness)
    # markOccludePoints(segmentedCloud, segmentedCloudRange, segmentedCloudColInd, cloudNeighborPicked)
    '''

    frame = 1
    outputPath = "G:\Carla//CARLA_0.9.13//WindowsNoEditor//PythonAPI//_out//"
    img_files_path = outputPath + "camera//"
    gt_path = outputPath + "gt//"
    lidar_files_path = outputPath + "lidar//"

    lidar_files = os.listdir(lidar_files_path)
    laserCloudCornerLast = []
    laserCloudSurfLast = []
    transformCur = np.zeros(6)
    transformSum = np.zeros(6)
    for data in lidar_files:
        # print(data)
        lidarData_ori = loadLidarData(lidar_files_path+"/"+data)

        rangeMat = np.ones((N_SCAN, Horizon_SCAN)) * (-1)
        groundMat = np.zeros((N_SCAN, Horizon_SCAN))
        labelMat = np.zeros((N_SCAN, Horizon_SCAN))
        lidarData = projectPointCloud(lidarData_ori, ang_res_x, ang_res_y, N_SCAN, Horizon_SCAN, rangeMat)
        groundRemoval(lidarData, N_SCAN, Horizon_SCAN, groundScanInd, groundMat, labelMat, rangeMat)
        startRingIndex, endRingIndex, outlierCloud, segmentedCloudGroundFlag, segmentedCloudColInd, segmentedCloudRange, segmentedCloud = cloudSegmentation(lidarData, N_SCAN, Horizon_SCAN, groundScanInd, ang_res_x, ang_res_y, labelMat, rangeMat, groundMat)

        segmentedCloud = np.array(segmentedCloud)

        feature = featureAccociation(segmentedCloud, segmentedCloudRange, segmentedCloudColInd, N_SCAN, startRingIndex, endRingIndex, segmentedCloudGroundFlag)
        # cloudCurvature = np.zeros(segmentedCloud.shape[0])
        # cloudNeighborPicked = np.zeros(segmentedCloud.shape[0])
        # cloudLabel = np.zeros(segmentedCloud.shape[0])
        # cloudSmoothness = np.zeros((segmentedCloud.shape[0],2))
        feature.calculateSmoothness()
        feature.markOccludePoints()
        cornerPointsSharp, cornerPointsLessSharp, surfPointsFlat, surfPointsLessFlat = feature.extractFeatures()

        cornerPointsSharpColor = np.array([[1,1,1]]*len(cornerPointsSharp))
        cornerPointsLessSharpColor = np.array([[1,1,1]]*len(cornerPointsLessSharp))
        surfPointsFlatColor = np.array([[0,1,0]]*len(surfPointsFlat))
        surfPointsLessFlatColor = np.array([[0,0,1]]*len(surfPointsLessFlat))
        cloud_extracted = np.r_[cornerPointsLessSharp, surfPointsLessFlat]
        color_extracted = np.r_[cornerPointsLessSharpColor, surfPointsLessFlatColor]
        # visulizeLiadarData(cloud_extracted, color_extracted)

        if frame == 1:
            laserCloudCornerLast = cornerPointsLessSharp
            laserCloudSurfLast = surfPointsLessFlat
            print("less Sharp number:", len(cornerPointsLessSharp), " less Surf number:", len(surfPointsLessFlat))
            print("Sharp number:", len(cornerPointsSharp), " Surf number:", len(surfPointsFlat))
            print("Current transform:", transformCur)
            print("Current position:", transformSum)
            frame += 1
            continue
        else:
            feature.updateTransformation(laserCloudCornerLast, laserCloudSurfLast, surfPointsFlat, cornerPointsSharp, transformCur)
            feature.interateTransformation(transformSum, transformCur)
            print("less Sharp number:", len(cornerPointsLessSharp), " less Surf number:", len(surfPointsLessFlat))
            print("Sharp number:", len(cornerPointsSharp), " Surf number:", len(surfPointsFlat))
            print("Current transform:", transformCur)
            print("Current position:", transformSum)
            frame += 1
            laserCloudCornerLast = cornerPointsLessSharp
            laserCloudSurfLast = surfPointsLessFlat


A = [1,34,21,3,5,1,2,11]

for i in range(1,len(A)):
    for j in range(i-1,0,-1):
        if A[j] > A[j+1]:
            A[j],A[j+1] = A[j+1],A[j]
        else:
            break
print(A)

# python function to sort (sorting tuples list and sets)
# python function to reverse list, tuples and sets and sort the same
# python function to get permutations of strings (from collection import itertools)
# matrix multiplication in python


import pygame
import sys

pygame.init()

size= (800,500)
screen= pygame.display.set_mode(size)
clock = pygame.time.Clock()

pygame.mouse.set_visible(0)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    mouse_pos = pygame.mouse.get_pos()
    x = mouse_pos[0]
    y = mouse_pos[1]

    screen.fill("Black")

    pygame.draw.rect(screen, "Red", (x,y, 100,100))

    #60 seran los circulos de la ventana
    pygame.display.flip()
    clock.tick(30) #Creamos puntos aleatorios cada 30 seg


# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from scrapy.http import Request

class SteamSpider(CrawlSpider):
    name = 'steam'
    #allowed_domains = ['https://store.steampowered.com/']
    start_urls = ['https://store.steampowered.com/search/?sort_by=Released_DESC/']

    rules = (
        Rule(
            LinkExtractor(
                restrict_css=[".search_result_row",]
            ),
            callback='parse_item',
            follow=True
        ),

        #Rule(
        #    LinkExtractor(
        #        restrict_css=[".search_pagination_right",]
        #        restrict_xpath=["./a[@class='pagebtn'][last()]",]
        #    ),
        #    follow=True
        #)
    )

    def parse_item(self, response):
        i = {}

        i['title'] = response.css(".details_block").xpath("./text()")[1].extract()

        return i


from collections import namedtuple

error_message = namedtuple('error_message', ('message', 'code',))

WRONG_UUID = error_message(
    'Строка UUID не соответсует стандарту. Допустимы только строки UUID версии 4',
    'wrong_uuid',
)
WRONG_URL_CODE_LEN = error_message(
    'Длинна "url_code" должна быть ровно 7 символов',
    'wrong_url_code_len',
)
WRONG_FULL_URL = error_message(
    'URL не корректно отформатированн',
    'wrong_full_url',
)
UNIQUE_URL_CODE = error_message(
    'Такой "url_code" уже существует. Придумайте другой',
    'unique_url_code',
)


def print_items(my_list):
    print(my_list)

def print_item_amount(my_list):
    print(len(my_list))

def is_item_in_list(my_list):
    item = input("Enter item name to check if in list: ")
    print(item in my_list)

def times_item_in_list(my_list):
    item = input("Enter item name to count amount in list: ")
    print(my_list.count(item))

def remove_item_from_list(my_list):
    item = input("Enter item name to remove form list: ")
    my_list.remove(item)
    print(my_list)

def add_item_to_list(my_list):
    item = input("Enter item name to add to list: ")
    my_list.append(item)
    print(my_list)

def print_illegal_items(my_list):
    illegal_list = list()
    for item in my_list:
        if len(item) < 3 or not item.isalpha():
            illegal_list.append(item)
    print("Illegal items:", illegal_list)

def remove_duplicate_items(my_list):
    # my_list = list(dict.fromkeys(my_list))
    for item in my_list:
        while my_list.count(item) > 1:
            my_list.remove(item)
    print("Items after removing duplicates:", my_list)

menu = """
1. הדפסת רשימת המוצרים
2. הדפסת מספר המוצרים ברשימה
3. הדפסת התשובה לבדיקה "האם המוצר נמצא ברשימה?" (המשתמש יתבקש להקיש שם מוצר)
4. הדפסת התשובה לבדיקה "כמה פעמים מופיע מוצר מסוים?" (המשתמש יתבקש להקיש שם מוצר)
5. מחיקת מוצר מהרשימה (המשתמש יתבקש להקיש שם מוצר, רק מוצר אחד ימחק)
6. הוספת מוצר לרשימה (המשתמש יתבקש להקיש שם מוצר)
7. הדפסת כל המוצרים שאינם חוקיים (מוצר אינו חוקי אם אורכו קטן מ-3 או שהוא כולל תווים שאינם אותיות)
8. הסרת כל הכפילויות הקיימות ברשימה
9. יציאה
"""

actions = [print_items, print_item_amount, is_item_in_list, times_item_in_list,
           remove_item_from_list, add_item_to_list, print_illegal_items, remove_duplicate_items]

groceries = input("Enter grocery string: ")
grocery_list = groceries.split(',')
print(menu)

while True:
    choice = input("Choose 1-9: ")
    if not choice.isdigit():
        print("Not a number")
        continue
    choice = int(choice)
    if not 1 <= choice <= 9:
        print("Not in menu")
        continue
    if choice == 9:
        print("Thanks, come again soon!")
        break
    actions[choice - 1](grocery_list)


from string import ascii_lowercase, ascii_uppercase

def rotVerschuiving(letter: str, shift: int) -> str:

    # check de ingevoerde letter en geef het verschoven nummer terug
    if letter in ascii_uppercase:
        return ascii_uppercase[((ascii_uppercase.index(letter) + shift) % 26)]
    elif letter in ascii_lowercase:
        return ascii_lowercase[((ascii_lowercase.index(letter) + shift) % 26)]
    else:
        return letter

def decode(invoer: str, shift: int) -> str:

    # ga alle letters langs en decodeer ze door de verschuiving.
    uitvoer = ''
    for nummer in invoer:
        uitvoer += uitvoer.join(rotVerschuiving(nummer, shift * -1))

    return uitvoer

# gebruiker voert zijn bericht in en hoeveel letters hij wil verschuiven.
message = input("Bericht: ")
verschuiving = int(input("Shift: "))

# print het gecodeerde bericht
print(decode(message, verschuiving))


#standard library imports
import tkinter as tk
from tkinter import scrolledtext, Menu, ttk, BOTTOM
from tkinter.filedialog import asksaveasfilename, askopenfilename
import re

#local application imports
from Análisis_Sintáctico_LL1.LL1 import LL1
from Análisis_Sintáctico_LL1.syntax_chart import *
from AnalisisSintacticoSLR.SLR import SLR, SLRError
from AnalisisSintacticoCLR.CLR import CLR, CLRError
from Análisis_Léxico.Analizador.AnalizadorLexico import AnalizadorLexico, LexicalError

class CodechemyIDE:
    def __init__(self, grammar, analyzer="SLR"):
        self.window = tk.Tk()
        self.window.title("IDE CODECHEMY")
        #self.grammar = grammar
        self.lexical_analyzer = AnalizadorLexico()
        self.file_path = ''

        self.lightpattern = [
            (r'🝰', 'Dark green'),  # int
            (r'🝯', 'Dark green'),  # bool
            (r'🝮', 'Dark green'),  # char
            (r'♒', 'Dark green'),  # string
            (r'♈', 'Dark green'),  # double
            (r'♋', 'Dark green'),  # float
            (r'♊', 'Dark green'),  # array
            (r'se', 'orange'),  # if
            (r'alie', 'orange'),  # else
            (r'por', 'orange'),  # for
            (r'dum', 'orange'),  # while
            (r'rompi', 'orange'),  # break
            (r'reveni', 'orange'),  # return
            (r'🜂', 'purple'),  # +
            (r'🜄', 'purple'),  # -
            (r'🜁', 'purple'),  # *
            (r'🜃', 'purple'),  # /
            (r'🜅', 'purple'),  # %
            (r'malvera', 'red'),  # false
            (r'vera', 'red'),  # true
            (r'🜓', 'purple'),  # &&
            (r'🝘', 'purple'),  # ||
            (r'🜎', 'purple'),  # ==
            (r'🜔', 'purple'),  # >
            (r'🜕', 'purple'),  # <
            (r'🜖', 'purple'),  # >=
            (r'🜗', 'purple'),  # <=
            (r'🜍', 'purple'),  # !=
            (r'🝱', 'red'),  # !
            (r'☾', 'magenta'),  # (
            (r'☽', 'magenta'),  # )
            (r'🝳', '#151715'),  # declaración (nombreVariable)
            (r'🝑', '#151715'),  # asignación (variable = valor)
            (r'🜌', 'cyan'),  # //
            (r'🜋🜋', 'cyan'),  # /**/
            (r'null', '#151715')  # null
        ]
        self.darkpattern = [
            (r'🝰', '#f58442'),  # int
            (r'🝯', '#f58442'),  # bool
            (r'🝮', '#f58442'),  # char
            (r'♒', '#f58442'),  # string
            (r'♈', '#f58442'),  # double
            (r'♋', '#f58442'),  # float
            (r'♊', '#f58442'),  # array
            (r'se', 'magenta'),  # if
            (r'alie', 'magenta'),  # else
            (r'por', 'magenta'),  # for
            (r'dum', 'magenta'),  # while
            (r'rompi', 'magenta'),  # break
            (r'reveni', 'magenta'),  # return
            (r'🜂', 'yellow'),  # +
            (r'🜄', 'yellow'),  # -
            (r'🜁', 'yellow'),  # *
            (r'🜃', 'yellow'),  # /
            (r'🜅', 'yellow'),  # %
            (r'malvera', 'red'),  # false
            (r'vera', 'red'),  # true
            (r'🜓', 'yellow'),  # &&
            (r'🝘', 'yellow'),  # ||
            (r'🜎', 'yellow'),  # ==
            (r'🜔', 'yellow'),  # >
            (r'🜕', 'yellow'),  # <
            (r'🜖', 'yellow'),  # >=
            (r'🜗', 'yellow'),  # <=
            (r'🜍', 'yellow'),  # !=
            (r'🝱', 'red'),  # !
            (r'☾', 'magenta'),  # (
            (r'☽', 'magenta'),  # )
            (r'🝳', '#03fc4e'),  # declaración (nombreVariable)
            (r'🝑', '#03fc4e'),  # asignación (variable = valor)
            (r'🜌', 'cyan'),  # //
            (r'🜋🜋', 'cyan'),  # /**/
            (r'null', 'yellow')  # null
        ]
        self.patternUsed=self.lightpattern
        if analyzer == "SLR":
            self.syntax_analyzer = SLR(grammar)
            self.syntax_analyzer.buildTable()
        elif analyzer == "CLR":
            self.syntax_analyzer = CLR(grammar)
            self.syntax_analyzer.buildTable()
        elif analyzer == "LL1":
            self.syntax_analyzer = LL1(grammar)
            self.syntax_analyzer.buildTable()

        self.create_menu()
        self.create_editor()
        self.create_output()
        self.create_words_bar()
        self.bind_events()

        # Mostrar la ventana
        self.window.mainloop()

    # function for light mode window
    def light(self):
        self.editor.config(fg="black",bg="white")
        self.window.config(bg="white")
        self.patternUsed=self.lightpattern
        self.output.config(fg="black",bg="white")
        self.highlight_syntax()

    # function for dark mode window
    def dark(self):
        self.editor.config(fg="white", bg="black", insertbackground="white")
        self.window.config(bg="black")
        self.output.config(bg="black", fg="white")
        self.patternUsed=self.darkpattern
        self.highlight_syntax()

    def create_menu(self):
        # Crear y configurar menú
        menu = Menu(self.window)
        self.window.config(menu=menu)

        # Crear submenús y añadirlos al menú principal
        file_menu = Menu(menu, tearoff=0)
        output_menu = Menu(menu, tearoff=0)
        theme_menu = Menu(menu, tearoff=0)
        symbol_menu = Menu(menu, tearoff=0)
        menu.add_cascade(label="File", menu=file_menu)
        menu.add_cascade(label="Output", menu=output_menu)
        menu.add_cascade(label="Theme", menu=theme_menu)
        menu.add_cascade(label="Dictionary", menu=symbol_menu)

        # Configurar file_menu
        file_menu.add_command(label="Open", accelerator="Ctrl+O", command=self.open_file)
        file_menu.add_separator()
        file_menu.add_command(label="Save", accelerator="Ctrl+S", command=self.save_file)
        file_menu.add_command(label="Save as", accelerator="Ctrl+A", command=self.save_as)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", accelerator="Ctrl+Q", command=self.close)

        # Configurar output_menu
        output_menu.add_command(label="Execute", accelerator="F5", command=self.execute_code)
        output_menu.add_separator()
        output_menu.add_command(label="Clean", accelerator="F4", command=self.clean_output)

        # Comando para cambiar theme
        theme_menu.add_command(label="Light", command= self.light)
        theme_menu.add_command(label="Dark", command= self.dark)

        #Comando para insertar simbolos
        #symbol_menu.add_command(label="🝰 int", accelerator="Ctrl-B", command=lambda: self.insert_symbol("🝰"))
        #symbol_menu.add_command(label="🝯 bool", accelerator="Ctrl-D", command=lambda: self.insert_symbol("🝯"))
        #symbol_menu.add_command(label="🝮 char", accelerator="Ctrl-E", command=lambda: self.insert_symbol("🝮"))
        #symbol_menu.add_command(label="♒ string", accelerator="Ctrl-F", command=lambda: self.insert_symbol("♒"))
        #symbol_menu.add_command(label="♈ double", accelerator="Ctrl-G", command=lambda: self.insert_symbol("♈"))
        #symbol_menu.add_command(label="♋ float", accelerator="Ctrl-H", command=lambda: self.insert_symbol("♋"))
        #symbol_menu.add_command(label="♊ array", accelerator="Ctrl-I", command=lambda: self.insert_symbol("♊"))
        symbol_menu.add_command(label="🜂 +", accelerator="Ctrl-J", command=lambda: self.insert_symbol("🜂"))
        symbol_menu.add_command(label="🜄 -", accelerator="Ctrl-K", command=lambda: self.insert_symbol("🜄"))
        symbol_menu.add_command(label="🜁 *", accelerator="Ctrl-L", command=lambda: self.insert_symbol("🜁"))
        symbol_menu.add_command(label="🜃 /", accelerator="Ctrl-M", command=lambda: self.insert_symbol("🜃"))
        symbol_menu.add_command(label="🜅 %", accelerator="Ctrl-N", command=lambda: self.insert_symbol("🜅"))
        symbol_menu.add_command(label="🜓 &&", accelerator="Ctrl-P", command=lambda: self.insert_symbol("🜓"))
        symbol_menu.add_command(label="🝘 ||", accelerator="Ctrl-R", command=lambda: self.insert_symbol("🝘"))
        symbol_menu.add_command(label="🜎 ==", accelerator="Ctrl-T", command=lambda: self.insert_symbol("🜎"))
        symbol_menu.add_command(label="🜔 >", accelerator="Ctrl-U", command=lambda: self.insert_symbol("🜔"))
        symbol_menu.add_command(label="🜕 <", accelerator="Ctrl-W", command=lambda: self.insert_symbol("🜕"))
        symbol_menu.add_command(label="🜖 >=", accelerator="F1", command=lambda: self.insert_symbol("🜖"))
        symbol_menu.add_command(label="🜗 <=", accelerator="F2", command=lambda: self.insert_symbol("🜗"))
        symbol_menu.add_command(label="🜍 !=", accelerator="F3", command=lambda: self.insert_symbol("🜍"))
        symbol_menu.add_command(label="🝱 !", accelerator="F6", command=lambda: self.insert_symbol("🝱"))
        symbol_menu.add_command(label="☾ (", accelerator="F7", command=lambda: self.insert_symbol("☾"))
        symbol_menu.add_command(label="☽ )", accelerator="F8", command=lambda: self.insert_symbol("☽"))
        symbol_menu.add_command(label="🝳 Declaracion", accelerator="F9", command=lambda: self.insert_symbol("🝳"))
        symbol_menu.add_command(label="🝑 Asignacion", accelerator="F10", command=lambda: self.insert_symbol("🝑"))
        symbol_menu.add_command(label="🜌 //", accelerator="F11", command=lambda: self.insert_symbol("🜌"))
        symbol_menu.add_command(label="🜋🜋 /**/", accelerator="F12", command=lambda: self.insert_symbol("🜋🜋"))

        # Insert column break after every 10 commands
        for i in range(1, 10):
            symbol_menu.entryconfigure(i * 5, columnbreak=tk.TRUE)

    def create_editor(self):
        self.editor = scrolledtext.ScrolledText(self.window, width=80, height=20, font=("Courier New", 12))
        self.editor.pack(expand=True, fill=tk.BOTH)
        self.editor.bind("<KeyRelease>", self.highlight_syntax)
        self.editor.bind("<<Modified>>", self.change_word)

    def create_output(self):
        self.output = scrolledtext.ScrolledText(self.window, height=8)
        self.output.pack(expand=True, fill=tk.BOTH)
        self.output.config(state="disabled")

    def create_words_bar(self):
        self.words_bar = ttk.Label(self.window, text="\t\t\t\t\t\tt\t\t\t\t\t\t\t characters: 0 words: 0")
        self.words_bar.pack(side=BOTTOM)

    def bind_events(self):
        self.window.bind("<Control-q>", self.close)
        self.window.bind("<Control-Q>", self.close)
        self.window.bind("<Control-o>", self.open_file)
        self.window.bind("<Control-O>", self.open_file)
        self.window.bind("<Control-s>", self.save_file)
        self.window.bind("<Control-S>", self.save_file)
        self.window.bind("<Control-a>", self.save_as)
        self.window.bind("<Control-A>", self.save_as)
        self.window.bind("<F5>", self.execute_code)
        self.window.bind("<F4>", self.clean_output)
        #self.window.bind("<Control-B>", lambda event: self.insert_symbol("🝰"))
        #self.window.bind("<Control-b>", lambda event: self.insert_symbol("🝰"))
        #self.window.bind("<Control-D>", lambda event: self.insert_symbol("🝯"))
        #self.window.bind("<Control-d>", lambda event: self.insert_symbol("🝯"))
        #self.window.bind("<Control-E>", lambda event: self.insert_symbol("🝮"))
        #self.window.bind("<Control-e>", lambda event: self.insert_symbol("🝮"))
        #self.window.bind("<Control-F>", lambda event: self.insert_symbol("♒"))
        #self.window.bind("<Control-f>", lambda event: self.insert_symbol("♒"))
        #self.window.bind("<Control-G>", lambda event: self.insert_symbol("♈"))
        #self.window.bind("<Control-g>", lambda event: self.insert_symbol("♈"))
        #self.window.bind("<Control-H>", lambda event: self.insert_symbol("♋"))
        #self.window.bind("<Control-h>", lambda event: self.insert_symbol("♋"))
        #self.window.bind("<Control-I>", lambda event: self.insert_symbol("♊"))
        #self.window.bind("<Control-i>", lambda event: self.insert_symbol("♊"))
        self.window.bind("<Control-J>", lambda event: self.insert_symbol("🜂"))
        self.window.bind("<Control-j>", lambda event: self.insert_symbol("🜂"))
        self.window.bind("<Control-K>", lambda event: self.insert_symbol("🜄"))
        self.window.bind("<Control-k>", lambda event: self.insert_symbol("🜄"))
        self.window.bind("<Control-L>", lambda event: self.insert_symbol("🜁"))
        self.window.bind("<Control-l>", lambda event: self.insert_symbol("🜁"))
        self.window.bind("<Control-M>", lambda event: self.insert_symbol("🜃"))
        self.window.bind("<Control-m>", lambda event: self.insert_symbol("🜃"))
        self.window.bind("<Control-N>", lambda event: self.insert_symbol("🜅"))
        self.window.bind("<Control-n>", lambda event: self.insert_symbol("🜅"))
        self.window.bind("<Control-P>", lambda event: self.insert_symbol("🜓"))
        self.window.bind("<Control-p>", lambda event: self.insert_symbol("🜓"))
        self.window.bind("<Control-R>", lambda event: self.insert_symbol("🝘"))
        self.window.bind("<Control-r>", lambda event: self.insert_symbol("🝘"))
        self.window.bind("<Control-T>", lambda event: self.insert_symbol("🜎"))
        self.window.bind("<Control-t>", lambda event: self.insert_symbol("🜎"))
        self.window.bind("<Control-U>", lambda event: self.insert_symbol("🜔"))
        self.window.bind("<Control-u>", lambda event: self.insert_symbol("🜔"))
        self.window.bind("<Control-W>", lambda event: self.insert_symbol("🜕"))
        self.window.bind("<Control-w>", lambda event: self.insert_symbol("🜕"))
        self.window.bind("<F1>", lambda event: self.insert_symbol("🜖"))
        self.window.bind("<F2>", lambda event: self.insert_symbol("🜗"))
        self.window.bind("<F3>", lambda event: self.insert_symbol("🜍"))
        self.window.bind("<F6>", lambda event: self.insert_symbol("🝱"))
        self.window.bind("<F7>", lambda event: self.insert_symbol("☾"))
        self.window.bind("<F8>", lambda event: self.insert_symbol("☽"))
        self.window.bind("<F9>", lambda event: self.insert_symbol("🝳"))
        self.window.bind("<F10>", lambda event: self.insert_symbol("🝑"))
        self.window.bind("<F11>", lambda event: self.insert_symbol("🜌"))
        self.window.bind("<F12>", lambda event: self.insert_symbol("🜋🜋"))

    # Función para pintar en tiempo real las palabras reservadas
    def highlight_syntax(self, event=None):
        #if event.keysym == "space" or event.keysym == "Return":
            text = self.editor.get("1.0", "end-1c")
            self.editor.tag_remove("highlight", "1.0", "end")  # Eliminar todas las etiquetas de resaltado existentes

            for i, (pattern, color) in enumerate(self.patternUsed):
                matches = re.finditer(pattern, text)
                for match in matches:
                    start = f"1.0+{match.start()}c"
                    end = f"1.0+{match.end()}c"
                    tag_name = f"highlight_{i}"  # Etiqueta única para cada patrón
                    self.editor.tag_add(tag_name, start, end)
                    self.editor.tag_config(tag_name, foreground=color)

    # Función para actualizar la cantidad de palabras y caractéres
    def change_word(self, event=None):
        if self.editor.edit_modified():
            word = len(self.editor.get("1.0", "end-1c").split())
            text = self.editor.get("1.0", "end-1c").replace(" ", "")
            text = text.replace("\n","")
            chararcter = len(text)
            self.words_bar.config(text=f"\t\t\t\t\t\tt\t\t\t\t\t\t\t characters: {chararcter} words: {word}")
        self.editor.edit_modified(False)

    # Función para cerrar la ventana
    def close(self, event=None):
        self.window.destroy()

    # Función para abrir archivos
    def open_file(self, event=None):
        open_path = askopenfilename(filetypes=[("CHEMY File", "*.chemy")])
        if open_path != '':
            self.file_path = open_path
            with open(open_path, "r", encoding="utf-8") as file:
                code = file.read()
                self.editor.delete("1.0", "end")
                self.editor.insert("1.0", code)
                self.highlight_syntax()

    # Función para guardar archivos
    def save_file(self, event=None):
        if self.file_path == '':
            save_path = asksaveasfilename(defaultextension=".chemy", filetypes=[("CHEMY File", "*.chemy")])
            self.file_path = save_path
        else:
            save_path = self.file_path
        if save_path != '':
            with open(save_path, "w", encoding="utf-8") as file:
                code = self.editor.get("1.0", "end-1c")
                file.write(code)

    # function para guardar archivos con un nombre específico
    def save_as(self, event=None):
        save_path = asksaveasfilename(defaultextension=".chemy", filetypes=[("CHEMY File", "*.chemy")])
        self.file_path = save_path
        if save_path != '':
            with open(save_path, "w", encoding="utf-8") as file:
                code = self.editor.get("1.0", "end-1c")
                file.write(code)

    # function para compilar el código del IDE
    def execute_code(self, event=None):
        execution = "Compiling..."
        print(execution)
        self.output.config(state="normal")
        #aca agregar el resultado de los análisis
        try:
            tokens = self.lexical_analyzer.analizar(self.editor.get("1.0", "end-1c"))
            self.syntax_analyzer.analyze(tokens)
            print("------------------------")
            print("¡Instrucción válida!")
            print("------------------------")
            execution = execution + "\n¡Instrucción válida!"
        except LexicalError as lexicalError:
            print("------------------------")
            print(lexicalError.mensaje)
            print("------------------------")
            execution = execution + "\n" + lexicalError.mensaje
        except SLRError as syntaxError:
            print("------------  ------------")
            print("Error en analizador sintáctico SLR")
            print(syntaxError.mensaje)
            print("------------------------")
            execution = execution + "\n" + "Error en analizador sintáctico SLR" + "\n" + syntaxError.mensaje
        except CLRError as syntaxError:
            print("------------------------")
            print("Error en analizador sintáctico CLR")
            print(syntaxError.mensaje)
            print("------------------------")
            execution = execution + "\n" + "Error en analizador sintáctico CLR" + "\n" + syntaxError.mensaje

        except LL1Error as syntaxError:
            print("------------------------")
            print("Error en analizador sintáctico LL1")
            print(syntaxError.mensaje)
            print("------------------------")
            execution = execution + "\n" + "Error en analizador sintáctico LL1" + "\n" + syntaxError.mensaje

        self.output.delete("1.0", "end")
        self.output.insert("1.0", execution)
        self.output.config(state="disabled")

    # function para limpiar la salida del IDE
    def clean_output(self, event=None):
        self.output.config(state="normal")
        self.output.delete("1.0", "end")
        self.output.config(state="disabled")

    def insert_symbol(self, symbol):
        # Insert the symbol at the current cursor position in the editor
        cursor_pos = self.editor.index(tk.INSERT)
        self.editor.insert(cursor_pos, symbol)
        self.highlight_syntax()


import pytest
from src.lib.string_util import StringUtil

@pytest.fixture(scope="module", autouse=True)
def stu_object():
    stu = StringUtil()
    yield stu

class TestStringUtil:
    @pytest.mark.parametrize("test_input, expected", [('県外一例目', False), ('県内1例目', True), ('県内2外', True)])
    def test_exclude_outside(self, stu_object, test_input, expected):
        result = stu_object.exclude_outside(test_input)
        assert result == expected

    @pytest.mark.parametrize("test_input, expected_bool, expected_list", [('県内一例目', False, '県内一例目'), ('県内3,4例目', True, ['県内3例目', '県内4例目'])])
    def test_is_duplicate_data(self, stu_object, test_input, expected_bool, expected_list):
        result_bool, result_list = stu_object.is_duplicate_data(test_input)
        assert result_bool == expected_bool
        assert result_list == expected_list

if __name__ == '__main__':
    pytest.main(['-v', __file__])


import sys
input = sys.stdin.readline

n = int(input())
array = [list(map(int, input().split())) for _ in range(n)]

array = sorted(array, key = lambda x : x[0]) # 시작 시간 기준으로 정렬
array = sorted(array, key = lambda x : x[1]) # 종료 시간 기준으로 정렬
# print(array)

count = 1 # 회의실을 최대로 사용할 수 있는 회의 수
last = array[0][1]

for i in range(1, n):
    if last <= array[i][0]: # 현재 회의 종료 시각이 다음 회의 시작 시각보다 작으면
        last = array[i][1] # 회의 종료 시각을 새로운 회의 배정 시각의 종료시각으로 업데이트
        count += 1 # 회의실을 새로 배정해줌

print(count)


import numpy as np
import torch
import torchvision
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset
from torchvision import transforms
import seaborn as sns
import argparse
sns.set_style('white')

parser = argparse.ArgumentParser()
parser.add_argument("--seed", type=int, default=9192)
parser.add_argument("--type", type=str, choices=["EWN", "SWN", "no-WN"], default="EWN")
args = parser.parse_args()

seed = args.seed
np.random.seed(seed)
torch.manual_seed(seed)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

d=784
k=10

transform = transforms.Compose(
    [   transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,)),
    ])

train_length = 60000
batch_size = 128
trainset = torchvision.datasets.MNIST(root='./data', train=True,
                                      download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,
                                               shuffle=True, num_workers=0)
test_length = 10000
testset = torchvision.datasets.MNIST(root='./data', train=False,
                                     download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,
                                         shuffle=False, num_workers=0)

num_fc_layers = 2
fc_neurons = [1024]
norm_type = args.type
loss_values = ['-10', '-100', '-300']
load = True
load_dir_base = './MNIST_pruning/' + str(seed) + '/'
if norm_type == 'EWN':
    WN = True
    exp_WN = True
    load_dir_base_2 = load_dir_base + 'EWN/'
elif norm_type == 'SWN':
    WN = True
    exp_WN = False
    load_dir_base_2 = load_dir_base + 'SWN/'
else:
    WN = False
    exp_WN = False
    load_dir_base_2 = load_dir_base + 'no-WN/'

act = 'relu'
class TestNet(nn.Module):
    def __init__(self, d, k, num_fc_layers, fc_neurons, act):
        super(TestNet, self).__init__()
        if WN:
            self.w = nn.ParameterList()
            self.s = nn.ParameterList()
        else:
            self.linears = nn.ModuleList()

        for i in range(num_fc_layers):
            if i==0:
                if WN:
                    temp_param = torch.randn(d, fc_neurons[0])
                    self.w.append(nn.Parameter(temp_param/torch.norm(temp_param, dim=0, keepdim=True)))
                    if exp_WN:
                        self.s.append(nn.Parameter(torch.zeros(1, fc_neurons[0])))
                    else:
                        self.s.append(nn.Parameter(torch.ones(1, fc_neurons[0])))
                    self.b = nn.Parameter(torch.zeros(1, fc_neurons[0]))
                else:
                    self.linears.append(nn.Linear(d, fc_neurons[0], bias=True))
            elif i==num_fc_layers-1:
                if WN:
                    self.lin = nn.Linear(fc_neurons[-1], k, bias=False)
                else:
                    self.linears.append(nn.Linear(fc_neurons[-1], k, bias=False))
            else:
                if WN:
                    temp_param = torch.randn(fc_neurons[i-1], fc_neurons[i])
                    self.w.append(nn.Parameter(temp_param/torch.norm(temp_param, dim=0, keepdim=True)))
                    if exp_WN:
                        self.s.append(nn.Parameter(torch.zeros(1, fc_neurons[i])))
                    else:
                        self.s.append(nn.Parameter(torch.ones(1, fc_neurons[i])))
                else:
                    self.linears.append(nn.Linear(fc_neurons[i-1], fc_neurons[i], bias=False))

        if not WN:
            self.linears.apply(self.w_init)
        self.fc_layers = num_fc_layers
        self.act = act

    def forward(self, x):
        x = x.view(x.shape[0],-1)
        for i in range(self.fc_layers):
            if WN:
                if i!=self.fc_layers-1:
                    w1 = self.w[i]
                    if exp_WN:
                        w1 = (torch.exp(self.s[i]) / torch.norm(w1, dim=0, keepdim=True)) * w1
                    else:
                        w1 = (self.s[i] / torch.norm(w1, dim=0, keepdim=True)) * w1

                    if i==0:
                        x = torch.matmul(x, w1) + self.b
                    else:
                        x = torch.matmul(x, w1)
                    if i != self.fc_layers - 1 and self.act != 'linear':
                        if self.act == 'relu':
                            x = F.relu(x)
                        elif self.act == 'hardtanh':
                            x = F.hardtanh(x)
                else:
                    x = self.lin(x)
            else:
                x = self.linears[i](x)
                if i != self.fc_layers - 1 and self.act != 'linear':
                    if self.act == 'relu':
                        x = F.relu(x)
                    elif self.act == 'hardtanh':
                        x = F.hardtanh(x)

        return x

    def w_init(self, m):
        if type(m) == nn.Linear:
            nn.init.kaiming_normal_(m.weight)
            if m.bias is not None:
                m.bias.data.fill_(0.0)

if __name__ == '__main__':
    np.set_printoptions(suppress=True)
    for ind1, curr_loss_val in enumerate(loss_values):
        if load:
            load_dir = load_dir_base_2 + str(curr_loss_val)
            net = TestNet(d, k, num_fc_layers, fc_neurons, act)
            net.to(device)
            net.load_state_dict(torch.load(load_dir + '/weights.pth'))
            last_log_loss = torch.tensor(float(curr_loss_val))

        for ind2 in range(ind1 + 2):
            if ind2==0:
                filename = load_dir + '/weight_layer_norm.txt'
            elif ind2==1:
                filename = load_dir + '/weight_layer_norm_init.txt'
            else:
                filename = load_dir + '/weight_layer_norm_' + str(loss_values[ind2-2]) + '.txt'
            test_acc = []
            cutoffs = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
            for cutoff in cutoffs:
                print(cutoff)
                nums = []
                for j in range(num_fc_layers - 1):
                    nums.append(int(cutoff*fc_neurons[j]/100))
                nums.append(0)
                fin_norms = []
                with open(filename, 'r') as f:
                    for i in range(num_fc_layers):
                        norms = []
                        while True:
                            curr_norm = f.readline()
                            if curr_norm == '\n' or curr_norm == '':
                                break
                            curr_norm = curr_norm.strip('\n')
                            norms.append(float(curr_norm))
                        norms = np.array(norms)
                        fin_norms.append(norms)

                indices = []
                for i in range(num_fc_layers):
                    temp = fin_norms[i]
                    indices.append(np.array(np.sort(np.argsort(temp)[nums[i]:])))

                new_fc_neurons = []
                for i in range(num_fc_layers-1):
                    new_fc_neurons.append(len(indices[i]))

                net2 = TestNet(d, k, num_fc_layers, new_fc_neurons, act)
                net2.to(device)
                state_dict = net2.state_dict()
                curr_index_lin_s = 0
                curr_index_lin_w = 0
                for name, param in net.named_parameters():
                    if WN:
                        if 'b' in name:
                            if len(indices[0])==1:
                                temp = indices[0][0]
                                state_dict['b'].copy_(param[:, temp:temp+1])
                            else:
                                state_dict['b'].copy_(param[:, indices[0]])
                        elif 'lin' in name:
                            state_dict['lin.weight'].copy_(param[:, indices[-2]])
                        elif 's' in name:
                            if len(indices[curr_index_lin_s]) == 1:
                                temp = indices[curr_index_lin_s][0]
                                state_dict['s.' + str(curr_index_lin_s)].copy_(param[:, temp:temp + 1])
                            else:
                                state_dict['s.' + str(curr_index_lin_s)].copy_(param[:, indices[curr_index_lin_s]])
                            curr_index_lin_s += 1
                        else:
                            if len(indices[curr_index_lin_w]) == 1:
                                temp = indices[curr_index_lin_w][0]
                                if curr_index_lin_w == 0:
                                    state_dict['w.' + str(curr_index_lin_w)].copy_(param[:, temp:temp + 1])
                                else:
                                    state_dict['w.' + str(curr_index_lin_w)].copy_(param[indices[curr_index_lin_w - 1], temp:temp + 1])
                            else:
                                if curr_index_lin_w == 0:
                                    temp = param[:, indices[curr_index_lin_w]]
                                    state_dict['w.' + str(curr_index_lin_w)].copy_(temp)
                                else:
                                    temp = param[indices[curr_index_lin_w - 1]]
                                    temp2 = temp[:, indices[curr_index_lin_w]]
                                    state_dict['w.' + str(curr_index_lin_w)].copy_(temp2)
                            curr_index_lin_w += 1
                    else:
                        if 'bias' in name:
                            state_dict['linears.0.bias'].copy_(param[indices[0]])
                        elif len(indices[curr_index_lin_w]) == 1:
                            temp = indices[curr_index_lin_w][0]
                            if curr_index_lin_w == 0:
                                state_dict['linears.' + str(curr_index_lin_w) + '.weight'].copy_(param[temp:temp + 1, :])
                            else:
                                state_dict['linears.' + str(curr_index_lin_w) + '.weight'].copy_(
                                    param[temp:temp + 1, indices[curr_index_lin_w - 1]])
                            curr_index_lin_w += 1
                        else:
                            if curr_index_lin_w == 0:
                                temp = param[indices[curr_index_lin_w]]
                                state_dict['linears.' + str(curr_index_lin_w) + '.weight'].copy_(temp)
                            else:
                                temp = param[indices[curr_index_lin_w]]
                                temp2 = temp[:, indices[curr_index_lin_w - 1]]
                                state_dict['linears.' + str(curr_index_lin_w) + '.weight'].copy_(temp2)
                            curr_index_lin_w += 1
                acc = 0.0
                running_loss = 0.0
                temp_vec = torch.zeros(10, k - 1).type(torch.LongTensor).to(device)
                for j in range(10):
                    temp_index = 0
                    for l in range(k):
                        if l == j:
                            continue
                        else:
                            temp_vec[j][temp_index] = l
                            temp_index += 1

                for i, data in enumerate(trainloader, 0):
                    inputs, labels = data[0].to(device), data[1].to(device)
                    outputs = net2(inputs)
                    temp = outputs.gather(1, labels.unsqueeze(1))
                    outputs2 = temp - outputs
                    temp_vec_2 = temp_vec[labels]
                    s_n = outputs2.gather(1, temp_vec_2)
                    s_n_min = None
                    if torch.min(s_n) > 0:
                        s_n_min = torch.min(s_n)
                    if torch.min(s_n) > 30:
                        loss = torch.mean(torch.exp(torch.logsumexp(-s_n, dim=1, keepdim=True) - last_log_loss))
                    else:
                        loss = torch.mean(torch.log1p(torch.sum(torch.exp(-s_n), dim=1)) * torch.exp(-last_log_loss))

                    class_pred = torch.argmax(outputs, dim=1)
                    acc = acc + torch.sum(class_pred == labels)
                    running_loss = running_loss + loss.item()*inputs.shape[0]

                print('Training acc: ' + str(acc.item() / train_length))

                criterion = torch.nn.functional.cross_entropy
                net2 = net2.eval()
                acc = 0.0
                total_loss = 0.0
                with torch.no_grad():
                    for i, data in enumerate(testloader, 0):
                        inputs, labels = data[0].to(device), data[1].to(device)
                        outputs = net2(inputs)

                        loss = criterion(outputs, labels, reduction='sum')
                        total_loss += loss.item()
                        class_pred = torch.argmax(outputs, dim=1)
                        acc = acc + torch.sum(class_pred == labels)

                print('Test acc: ' + str(acc.item()/test_length))
                test_acc.append(acc.item()/test_length)

            str_test_acc = []
            for i in range(len(test_acc)):
                str_test_acc.append(str(test_acc[i]))
            if WN:
                if exp_WN:
                    mid_name = 'EWN'
                else:
                    mid_name = 'SWN'
            else:
                mid_name = 'no-WN'
            if ind2 == 0:
                end_name = '0'
            elif ind2 == 1:
                end_name = 'init'
            else:
                end_name = str(loss_values[ind2 - 2])
            name = load_dir_base + 'test_acc_prune_' + mid_name + '_diff_' + end_name + '_' + str(curr_loss_val) + '.txt'
            with open(name, 'w') as f:
                f.write('\n'.join(str_test_acc))
            f.close()


import copy
import json
import time
import typing

import random
import ansi
from non_blocking_input import nbprepare, nbclose
import atexit
import sys, os

nb = nbprepare()
atexit.register(nbclose)

l_snake = []
dangerous_grids = set()

bw = 2

_size: typing.Optional[typing.Tuple] = None
_display_size: typing.Optional[typing.Tuple] = None
def get_size() -> typing.Tuple:
    global _size
    if _size is None:
        change_size()
    return _size

_debug = False
_debug_buffer = []
_MAX_DEBUG_BUFFER = 2
def debug(*args, **kwargs):
    global _debug_buffer
    if _debug:
        _debug_buffer.append((kwargs.get('split', ' ').join(str(i) for i in args), time.time()))
        if len(_debug_buffer) > _MAX_DEBUG_BUFFER:
            _debug_buffer.pop(0)
        if kwargs.get('flush', False):
            display()

def get_display_size() -> typing.Tuple:
    change_size()
    return _display_size

minimal_h, minimal_w = 30, 70

def change_size(h=None, w=None):
    global _size, _display_size
    if h is None or w is None:
        terminal_size = os.get_terminal_size()
        if h is None:
            h = int(terminal_size.lines)
        if w is None:
            w = int(terminal_size.columns)
    # if h < minimal_h or w < minimal_w:
    #     if h < minimal_h:
    #         h = minimal_h
    #     if w < minimal_w:
    #         w = minimal_w
    #     sys.stdout.write(f"\x1b[8;{h};{w}t")
    #     sys.stdout.flush()

    _display_size = (h, w)
    _size = (25, 60)

_old_size_buffer = None
def display_size_changed():
    global _old_size_buffer
    display_size = get_display_size()
    if _old_size_buffer != display_size:
        _old_size_buffer = display_size
        return True
    return False

def reset_dangerous_grids():
    dangerous_grids.clear()

def clear_snake():
    l_snake.clear()
    reset_dangerous_grids()

def push_snake(x, y):  # return False if (x, y) dangerous
    l_snake.append((x, y))
    if (x, y) in dangerous_grids:
        return False
    dangerous_grids.add((x, y))
    return True

def pop_snake():  # return popped element
    x, y = l_snake.pop(0)
    dangerous_grids.remove((x, y))
    return x, y

food_position = None

def generate_food():
    global food_position
    h, w = get_size()
    if len(dangerous_grids) < h * w * 4 // 5:
        while True:
            x, y = random.randint(0, h - 1), random.randint(0, w - 1)
            if not (x, y) in dangerous_grids:
                break
    else:
        safe_grids = []
        for x in range(h):
            for y in range(w):
                if (x, y) not in dangerous_grids:
                    safe_grids.append((x, y))
        if len(safe_grids) == 0:
            return None
        k = random.randint(0, len(safe_grids))
        x, y = k
    food_position = (x, y)
    debug(f'FOOD POSITION ({x}, {y})')
    return food_position

head_direction = (0, 1)
def set_head_direction(x, y):
    global head_direction
    head_direction = (x, y)

_direction_queue = []
def change_head_direction(x, y):
    global _direction_queue
    if len(_direction_queue):
        hd = _direction_queue[-1]
    else:
        hd = head_direction
    if x == -hd[0] and y == -hd[1]:
        return False
    if x == hd[0] and y == hd[1]:
        return False
    _direction_queue.append((x, y))
    return True

def apply_change_direction():
    if len(_direction_queue):
        x, y = _direction_queue.pop(0)
        set_head_direction(x, y)

score = 0
_highscore = None
def get_highscore():
    global _highscore
    if _highscore is None:
        try:
            with open("xw.dat", 'rb') as f:
                x = list(f.read(4))
                _highscore = ((x[3]*256+x[2])*256+x[1])*256+x[0]
        except FileNotFoundError:
            _highscore = 0
    return _highscore

def set_highscore(score, force=False):
    global _highscore
    if force or get_highscore() < score:
        _highscore = score
        p0 = score % 256
        p1 = score // 256 % 256
        p2 = score // (256 * 256) % 256
        p3 = score // (256 * 256 * 256)
        fbytes = bytes([p0, p1, p2, p3])
        with open("xw.dat", 'wb') as f:
            f.write(fbytes)
        return True
    return False

def set_score(new_score):
    global score
    score = new_score
    set_highscore(score)

def clear_highscore():
    set_highscore(0, True)

def init_game_data():
    h, w = get_size()
    clear_snake()
    push_snake(h // 2, w // 2 - 2)
    push_snake(h // 2, w // 2 - 1)
    push_snake(h // 2, w // 2 + 0)
    push_snake(h // 2, w // 2 + 1)
    set_head_direction(0, 1)
    generate_food()
    set_score(0)

def move():  # return false if pumped into barrier
    x, y = l_snake[-1]
    h, w = get_size()
    apply_change_direction()
    new_x, new_y = (x + head_direction[0]) % h, (y + head_direction[1]) % w
    if (new_x, new_y) == food_position:  # cannot pump into barrier
        set_score(score + 1)
        push_snake(new_x, new_y)
        generate_food()
        return True
    else:
        pop_snake()
        return push_snake(new_x, new_y)

UNSTARTED, PREPARING, PLAYING, PAUSED, KILLED, END, QUIT = 0, 6, 1, 2, 3, 4, 5
game_status = UNSTARTED

_old_display_dict = {}
def show_message(display, message, position='mid', align=None):
    h, w = get_display_size()
    # positions = position.split('-')
    lines = message.split('\n')
    hh = len(lines)
    if isinstance(position, str):
        if position == 'mid':
            if align is None:
                align = 'mid'
            h0 = (h-hh) // 2
            w0 = w // 2
        elif position == 'top-right':
            if align is None:
                align = 'right'
            h0 = 0
            w0 = w
        elif position == 'bottom-left':
            if align is None:
                align = 'left'
            h0 = h - hh
            w0 = 0
        else:
            raise NotImplementedError("Unsupported message position!")
        for i, line in enumerate(lines):
            ll = len(line)
            for j, x in enumerate(line):
                if align == 'mid':
                    w1 = (w - ll) // 2
                elif align == 'right':
                    w1 = w0 - ll
                else:
                    w1 = w0
                display[(h0 + i, w1 + j)] = x

def show_grid(display, grids=None, position='mid'):
    h, w = get_size()
    h0, w0 = get_display_size()
    dh, dw = (h0 - h) // 2, (w0 - w) // 2
    for (x, y), v in grids.items():
        display[(x + dh, y + dw)] = v

def cls_str():
    return '\033[2J'
def clear_screen(display):
    display[(-1, -1)] = (cls_str(), )

def has_cls(display):
    return display.get((-1, -1), None) == (cls_str(), )

def draw_frame(display):
    h, w = get_size()
    h0, w0 = get_display_size()
    dh, dw = (h0 - h) // 2, (w0 - w) // 2
    for i in range(dh, dh + h):
        display[(i, dw - 1)] = display[(i, dw + w)] = '|'
    for i in range(dw, dw + w):
        display[(dh - 1, i)] = display[(dh + h, i)] = '-'
    display[(dh - 1, dw - 1)] = display[(dh + h, dw - 1)] = display[(dh - 1, dw + w)] = display[(dh + h, dw + w)] = '+'

def get_new_display(game_status):
    new_display = {}
    if display_size_changed():
        clear_screen(new_display)
    if game_status == UNSTARTED:
        welcome_message = 'WELCOME TO GLUTTONOUS SNAKE!\n\nPRESS s TO START GAME.\n\n w - UP   \n a - LEFT \n s - ' \
                          'DOWN \n d - RIGHT\n\nPRESS q TO QUIT. '
        show_message(new_display, welcome_message)
    elif game_status == PLAYING:
        show_message(new_display, f'SCORE  {score:5d}\nHIGH  {get_highscore():5d}', 'top-right')
        show_grid(new_display, {i: '#' for i in dangerous_grids})
        if len(l_snake):
            show_grid(new_display, {l_snake[-1]: '@'})
        if food_position is not None:
            show_grid(new_display, {food_position: '$'})
    elif game_status == PAUSED:
        show_message(new_display, '\n\n\nGLUTTONOUS SNAKE\n\nPAUSED\n\nPRESS p TO RESUME.\nPRESS q TO QUIT.\n\n\n\n'
                                  ' w - UP   \n a - LEFT \n s - '
                                  'DOWN \n d - RIGHT')
    elif game_status == KILLED:
        show_message(new_display, f'SCORE  {score:5d}\nHIGH  {get_highscore():5d}', 'top-right')
        show_grid(new_display, {i: '#' for i in dangerous_grids})
        show_grid(new_display, {l_snake[-1]: ansi.AnsiColor(color8='red').wrap(b'\xf0\x9f\x98\x85'.decode('utf-8'))})
        if food_position is not None:
            show_grid(new_display, {food_position: '$'})
    elif game_status == END:
        show_message(new_display, f'GAME OVER.\nYOUR SCORE: {score:5d}\nHIGH SCORE: {get_highscore():5d}\nPRESS s TO RESTART.')
    elif game_status == QUIT:
        show_message(new_display, "ARE YOU SURE TO QUIT THE GAME?\ny      n")
    draw_frame(new_display)
    return new_display

def show_debug(display):
    global _debug, _debug_buffer
    if _debug and _debug_buffer:
        show_message(display, '\n'.join(i for i, _ in _debug_buffer), 'bottom-left')

def display(cls=False):
    global _old_display_dict
    new_display = get_new_display(game_status)
    if cls:
        clear_screen(new_display)
    show_debug(new_display)
    h, w = get_display_size()
    different_grids = {}
    if has_cls(new_display):
        _old_display_dict.clear()
        sys.stdout.write(cls_str())
    for k, v in new_display.items():
        if isinstance(v, str) and (k not in _old_display_dict or _old_display_dict[k] != v) and h > k[0] >= 0 and w > k[1] >= 0:
            different_grids[k] = v
        elif isinstance(v, tuple) and (h > k[0] >= 0 and w > k[1] >= 0):
            different_grids[k] = v[0]
    for k, v in _old_display_dict.items():
        if k not in new_display:
            different_grids[k] = '\x1b[m '  # restore this grid!
    # display
    contents = [(i, j, v) for (i, j), v in different_grids.items()]
    contents.sort()
    lx, ly = -100, -100
    continuous_parts = ''
    display_buf = ''
    # cls
    for i, (x, y, v) in enumerate(contents):
        flag = False
        if lx == x and ly == y - 1:
            # continuous
            continuous_parts += v
            flag = True
        else:
            display_buf += (continuous_parts) + (f'\033[{x+1};{y+1}H')
            continuous_parts = v
        if i == len(contents) - 1:
            display_buf += (continuous_parts)

        lx, ly = x, y
    _old_display_dict = new_display
    if contents:
        sys.stdout.write(display_buf)
        # debug("Display len:", len(display_buf), "Contents:", len(contents))
        # with open('e.json', 'a') as f:
        #     json.dump(contents, f)
        sys.stdout.flush()
        # time.sleep(1)

def change_game_status(new_status):
    global game_status
    game_status = new_status
    display()

_time = 0
def update_time():
    global _time
    _time = time.time()
def restore_game():
    global game_status
    change_game_status(PLAYING)
    update_time()

def pause_game():
    global game_status
    change_game_status(PAUSED)
    update_time()

def pause_restore():
    if game_status == PAUSED:
        restore_game()
    elif game_status == PLAYING:
        pause_game()
    return game_status

_timer_limit = 0.1
_killed_time_limit = 2
def game_step():
    if game_status == PLAYING:
        if time.time() - _time >= _timer_limit:
            x = move()
            if not x:
                change_game_status(KILLED)
            display()
            update_time()
        return
    if game_status == KILLED:
        if time.time() - _time >= _killed_time_limit:
            change_game_status(END)
            display()
        return
    display()

def loop_on(function, *args, end_condition=None, **kwargs):
    while True:
        rv = function(*args, **kwargs)
        if callable(end_condition) and end_condition(rv):
            return rv

def quit_game():
    global game_status
    old = game_status
    change_game_status(QUIT)
    nb.set_endkeys(['y', '\n'])
    display()
    answer = loop_on(get_input, check_answer, end_condition=lambda x: x in {True, False})
    if answer:
        print('\033[2J')
        exit(0)
    nb.set_endkeys([])
    change_game_status(old)
    display()

def start_game():
    change_game_status(PREPARING)
    display()
    init_game_data()
    restore_game()
    display()

def check_answer(ch):
    if ch == 'y':
        return True
    elif ch == 'n':
        return False
    return None

def check_playing_command(ch):
    if ch == 's':
        return change_head_direction(1, 0)
    elif ch == 'a':
        return change_head_direction(0, -1)
    elif ch == 'w':
        return change_head_direction(-1, 0)
    elif ch == 'd':
        return change_head_direction(0, 1)
    elif ch == 'p':
        return pause_restore()
    elif ch == 'q':
        return quit_game()
    return None

def check_paused_command(ch):
    if ch == 'p':
        return pause_restore()
    elif ch == 'q':
        return quit_game()
    return None

def check_unstarted_command(ch):
    if ch == 's':
        return start_game()
    elif ch == 'q':
        return quit_game()
    return None

def check(ch):
    if game_status == UNSTARTED:
        return check_unstarted_command(ch)
    elif game_status == PREPARING:
        return None
    elif game_status == PLAYING:
        return check_playing_command(ch)
    elif game_status == PAUSED:
        return check_paused_command(ch)
    elif game_status == END:
        return check_unstarted_command(ch)
    elif game_status == QUIT:
        return check_answer(ch)
    return None

def get_input(check_function):
    if nb.kbhit():
        ch = nb.getch()
        debug('GOT ', ch, flush=True)
        return check_function(ch)
    return None

def main_loop_function():
    get_input(check)
    game_step()

if __name__ == '__main__':
    print('\033[?25l')
    display(cls=True)
    loop_on(main_loop_function)

def exitfunction():
    nbclose()
    print("\033[?25h")
    exit(0)


"""
 Print elements of a linked list on console
 head input could be None as well for empty list
 Node is defined as
"""
'''
 class Node:

   def __init__(self, data=None, next_node=None):
       self.data = data
       self.next = next_node
class LinkedList:
    def __init__(self, head, length):
        self.head = head
        self.length = length
'''

def print_list(head):

    current = head
    if( current.next == None and current.data ):
        print(self.current.data)
        return

    elif(current.next == None and current.data == None):
        return

    while(current.next != None):
        print(current.data)
        current = current.next

    print(current.data)
    return


import numpy as np
import math

import torch
import torch.nn as nn
import torchvision.transforms as transforms

class OhemCELoss(nn.Module):
    """
    算法本质：
    Ohem本质：核心思路是取所有损失大于阈值的像素点参与计算，但是最少也要保证取n_min个

    """
    def __init__(self, thresh, lb_ignore=255):
        super(OhemCELoss, self).__init__()
        # self.thresh = 0.3567     -ln(0.7) = 0.3567
        # CELoss = -log(Pt)
        self.thresh = -torch.log(torch.tensor(thresh, requires_grad=False, dtype=torch.float))
        # self.lb_ignore = 255
        self.lb_ignore = lb_ignore
        self.criteria = nn.CrossEntropyLoss(ignore_index=lb_ignore, reduction='none')

    def forward(self, logits, labels):
        # logits: [2,11,1088,896]  batch,classNum,height,width
        # labels: [2,1088,896]  batch,height,width

        # 1、计算n_min（最少算多少个像素点）
        # n_min的大小：一个batch的n张h*w的label图的所有的像素点的十六分之一
        n_min = labels[labels != self.lb_ignore].numel() // 16

        # 2、交叉熵预测得到loss之后，打平成一维的
        loss = self.criteria(logits, labels).view(-1)

        # 3、所有loss中大于阈值的，这边叫做loss hard，这些点才参与损失计算
        # 注意，这里是优化了pytorch中 Ohem 排序的，不然排序太耗时间了
        loss_hard = loss[loss > self.thresh]

        # 4、如果总数小于了n_min，那么肯定要保证有n_min个
        if loss_hard.numel() < n_min:
            loss_hard, _ = loss.topk(n_min)

        # 5、如果参与的像素点的个数大于了n_min个，那么这些点都参与计算
        loss_hard_mean = torch.mean(loss_hard)

        # 6、返回损失的均值
        return loss_hard_mean


#for a given input - Check a number is an armstrong or not
#armstrong number is sum of the power each digit to the number of digits is equal to original number
#For ex - if the number is 123 , we check 1*1*1 + 2*2*2 + 3*3*3 is same as 123.
#36 is not equal to 123. 123 is not Armstrong
#407 is a good example - 4*4*4 + 0*0*0 + 7*7*7 = 64 + 0 + 343 = 407

myNum = int(input("Enter a number : "))
#if(myNum > 999):
#  print("Please enter a 3 digit number only")
#else:
checkNum = myNum
# check the digits of the number
lenNum = len(str(myNum)) #Since, we are entering 3 digit number, it is always 3
sumNum = 0
#Loop thru each digit
while myNum != 0:
	remainingNum = lenNum % 10
	sumNum = sumNum+(remainingNum**lenNum)
	myNum = myNum//10
if checkNum == sumNum:
	print("The given number is armstrong number")
else:
	print("The given number is not armstrong number")


# -*- coding: utf-8 -*-
"""
Created on Fri Feb 17 11:39:58 2017

@author: luzhangqin
"""

import numpy as np
from sklearn.cluster import KMeans
#计算两个输入集合的每对之间的距离。
from scipy.spatial.distance import cdist
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt

font = FontProperties(fname = r'/usr/share/fonts/truetype/arphic/ukai.ttc', size = 10)

#输出间隔的下限。 所有生成的值将大于或等于低。 默认值为0。
#t或ints的元组，可选输出形状。
#如果给定形状是例如（m，n，k），则绘制m * n * k个样本。
#默认值为None，在这种情况下返回单个值。
cluster1 = np.random.uniform(0.5, 1.5, (2, 10))
cluster2 = np.random.uniform(3.5, 4.5, (2, 10))
#取一个数组序列，并水平堆叠，形成一个数组。
#转置
X = np.hstack((cluster1, cluster2)).T
plt.figure()
plt.axis([0, 5, 0, 5])
plt.grid(True)
plt.plot(X[:, 0], X[:, 1], 'k.')
plt.show()
#取一个数组序列，并将它们垂直堆叠以构成一个数组。
#X = np.vstack((cluster1, cluster2)).T

K = range(1, 10)
meandistortions = []
for k in K:
    kmeans = KMeans(n_clusters = k)
    kmeans.fit(X)
    #kmeans.cluster_centers_ 集群中心的坐标
    #axis如果这是一个int的元组，则选择多个轴的最小值，而不是单个轴或所有轴，如前所述。
    meandistortions.append(sum(np.min(cdist(X, kmeans.cluster_centers_,
                                            'euclidean'), axis = 1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('平均畸变程度', fontproperties = font )
plt.title('肘部法则', fontproperties = font )


# An implementation of a linear SVM that uses gradient descent for training
import numpy as np
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler
from datetime import datetime
from util import get_clouds

# Define the Linear SVM using a class
class LinearSVM:
    def __init__(self, C = 1.0):
        self.C = C

    def _objective(self, margins):
        return 0.5 * self.w.dot(self.w) + self.C * np.maximum(0, 1 - margins).sum()

    def fit(self, X, Y, lr = 1e-5, n_iters=400):
        N, D = X.shape
        self.N = N
        self.w = np.random.randn(D)
        self.b = 0

        # Gradient descent
        losses = []
        for _ in range(n_iters):
            margins = Y * self._decision_function(X)
            loss = self._objective(margins)
            losses.append(loss)

            idx = np.where(margins < 1)[0]
            grad_w = self.w - self.C * Y[idx].dot(X[idx])
            self.w -= lr*grad_w
            grad_b = -self.C * Y[idx].sum()
            self.b -= lr * grad_b

        self.support_ = np.where((Y * self._decision_function(X)) <= 1)[0]
        print("num SVs:", len(self.support_))

        print("w:", self.w)
        print("b:", self.b)

        plt.plot(losses)
        plt.title("Loss per iteration")
        plt.show()

    def _decision_function(self, X):
        return X.dot(self.w) + self.b

    def predict(self, X):
        return np.sign(self._decision_function(X))

    def score(self, X, Y):
        P = self.predict(X)
        return np.mean(Y == P)

def plot_decision_boundary(model, X, Y, resolution=100, colors=('b', 'k', 'r')):
    np.warnings.filterwarnings('ignore')
    fig, ax = plt.subplots()

    # Generate a coordinate grid of shape [resolution x resolution]
    # Evaluate the model over the entire space
    x_range = np.linspace(X[:,0].min(), X[:,0].max(), resolution)
    y_range = np.linspace(X[:,1].min(), X[:,1].max(), resolution)
    grid = [[model._decision_function(np.array([[xr, yr]])) for yr in y_range] for xr in x_range]
    grid = np.array(grid).reshape(len(x_range), len(y_range))

    # Plot decision contours using grid and make a scatter plot of training data
    ax.contour(x_range, y_range, grid.T, (-1, 0, 1), linewidths=(1,1,1), linestyles = ('--', '-', '--'), colors=colors)
    ax.scatter(X[:,0], X[:,1], c=Y, lw=0, alpha=0.3, cmap='seismic')

    # Plot support vectors (non-zero alphas) as circled points (linewidth > 0)
    mask = model.support_
    ax.scatter(X[:,0][mask], X[:,1][mask], c=Y[mask], cmap='seismic')

    # Debug
    ax.scatter([0], [0], c='black', marker='x')
    plt.show()

def clouds():
    X, Y = get_clouds()
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size = 0.33)
    return X_train, X_test, Y_train, Y_test, 1e-3, 200

def medical():
    data = load_breast_cancer()
    X, Y = data.data, data.target
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33)
    return X_train, X_test, Y_train, Y_test, 1e-3, 200

if __name__ == '__main__':
    X_train, X_test, Y_train, Y_test, lr, n_iters = clouds()
    print("Possible labels:", set(Y_train))

    # Make sure the targets are (-1, +1)
    Y_train[Y_train == 0] = -1
    Y_test[Y_test == 0] = -1

    # Scale the data
    scaler = StandardScaler()
    X_train = scaler.fit_transform(X_train)
    X_test = scaler.transform(X_test)

    model = LinearSVM(C=1.0)

    t0 = datetime.now()
    model.fit(X_train, Y_train, lr=lr, n_iters=n_iters)
    print("Train duration:", datetime.now() - t0)
    t0 = datetime.now()
    print("Train score:", model.score(X_train, Y_train), "Duration:", datetime.now() -t0)
    t0 = datetime.now()
    print("Test score:", model.score(X_test, Y_test), "Duration:", datetime.now() - t0)

    if X_train.shape[1] == 2:
        plot_decision_boundary(model, X_train, Y_train)


import numpy as np
import matplotlib.pyplot as plt

X= [20,30,47,78,765,89,4]
y = [33,5,72,366,5,4,66]

plt.plot(X,y)
plt.xlabel('X - axis')
plt.ylabel('Y - axis')
plt.title('Example')
plt.legend('temp')

plt.show()