"""
Functions for ridge regression used in predict_session_day.py, predict_trial_number.py, and predict_session_number.py.
"""
import numpy as np
from sklearn.linear_model import RidgeCV
from sklearn.preprocessing import StandardScaler
from tqdm import tqdm

import logging

def get_logger(filename):
    logger = logging.getLogger()  # Get a logger instance
    logger.setLevel(logging.INFO)  # Set logging level

    # Create a file handler
    file_handler = logging.FileHandler(filename, mode='w')
    formatter = logging.Formatter('%(asctime)s %(message)s')
    file_handler.setFormatter(formatter)

    # Add the file handler to the logger
    logger.addHandler(file_handler)

    return logger

def fit_ridge_clf(X, y, alphas:list, ncv = 10):
    """
    Fits the ridge classifier to the data.

    Parameters
    ----------
    X : np.ndarray
        Data matrix.
    y : np.ndarray
        Target vector.
    alphas : list
        List of alpha values to try.
    ncv : int
        Number of cross validation folds to use when fitting the classifier.

    Returns
    -------
    clf : sklearn.linear_model.Ridge
        Fitted ridge classifier.
    """

    # create the classifier
    clf = RidgeCV(alphas = alphas, cv = ncv)

    # fit the classifier
    clf.fit(X, y)

    return clf

def tgm_ridge_scores(X, y, stratify, alphas = np.logspace(0, 5, 10), ncv = 10, logger = None):
    """
    Fits the ridge classifier to the data and applies it to all timepoints.

    Parameters
    ----------
    X : np.ndarray
        Data matrix, shape (n_timepoints, n_trials, n_features).
    y : np.ndarray
        Target vector.
    stratify : np.ndarray
        Stratification vector. Default is None. This vector is used to ensure no leakage between training and testing sets by leaving out one stratification group at a time.
    alphas : list
        List of alpha values to try.
    ncv : int
        Number of cross validation folds to use when fitting the classifier.

    Returns
    -------
    predictions : np.ndarray
        Matrix of predictions, shape (n_timepoints, n_timepoints, n_stratification_groups, n_trials).

    true_values : np.ndarray
        Matrix of true values, shape (n_timepoints, n_timepoints, n_stratification_groups, n_trials).
    """
    # get the number of timepoints
    n_timepoints = X.shape[0]

    # get the number of stratification groups
    n_stratification_groups = len(np.unique(stratify))

    # get the largest number of trials in a stratification group
    n_trials = np.max(np.unique(stratify, return_counts=True)[1])

    # create the predictions and true value matrices
    predictions = np.empty((n_timepoints, n_timepoints, n_stratification_groups, n_trials))
    true_values = np.empty((n_timepoints, n_timepoints, n_stratification_groups, n_trials))

    # fill with nans
    predictions[:] = np.nan
    true_values[:] = np.nan

    # shuffle the data
    idx = np.random.permutation(X.shape[1])
    X = X[:, idx, :]
    y = y[idx]
    stratify = stratify[idx]

    # loop over the timepoints
    for i in tqdm(range(n_timepoints)):
        # loop over stratification groups
        for s, strat in enumerate(np.unique(stratify)):
            # get the training and testing data
            X_train = X[i, stratify != strat, :]
            y_train = y[stratify != strat]
            X_test = X[:, stratify == strat, :]
            y_test = y[stratify == strat]

            # standardize the data
            scaler = StandardScaler()
            X_train = scaler.fit_transform(X_train)

            # fit the classifier
            clf = fit_ridge_clf(X_train, y_train, alphas = alphas, ncv = ncv)

            # test the classifier on all timepoint
            for j in range(n_timepoints):
                # get the testing data
                X_test_j = X_test[j, :, :]
                # standardize the data
                X_test_j = scaler.transform(X_test_j)

                # predict the labels
                pred = clf.predict(X_test_j)

                # store the predictions and true values
                predictions[i, j, s, :pred.shape[0]] = pred
                true_values[i, j, s, :pred.shape[0]] = y_test

                # log if all predictions made using model trained on time point i are the same for stratification group s (i.e. no variance in predictions)
                if logger is not None:
                    if np.all(pred == pred[0]):
                        logger.info(f'All predictions for train timepoint {i} and test timepoint {j} (stratgroup {s}) are the same.')

    return predictions, true_values


import os
import torch
import numpy as np
from sklearn.metrics import f1_score, accuracy_score

from feature_extraction import FeatureExtraction

class ExperimentRandom:

    def __init__(self, cfg):

        self.cfg = cfg

        # Data attributes
        pt_path = f"data/{self.cfg['data']}_{self.cfg['pretrained'].replace('/', '_')}.pt"
        if not os.path.exists(pt_path):
            fe = FeatureExtraction(self.cfg)
            fe.extract()

        self.texts, self.features, self.labels, self.train_ind, self.val_ind, self.test_ind, self.num_classes = torch.load(f"data/{self.cfg['data']}_{self.cfg['pretrained'].replace('/', '_')}.pt", map_location="cpu")

        self.len_train = len(self.train_ind)
        self.len_val = len(self.val_ind)
        self.len_test = len(self.test_ind)

    def evaluate(self, y_test, y_pred):
        f1 = f1_score(y_test, y_pred, average="macro")
        acc = accuracy_score(y_test, y_pred)

        print(f"F1 Score: {np.round(f1, 4)}")
        print(f"Accuracy Score: {np.round(acc, 4)}")

    def run(self):
        print(f"Random experiment for data {self.cfg['data']}")
        y_test = self.labels[self.test_ind]

        y_test = y_test.detach().cpu().numpy()

        print("---")

        # Random per class
        print("Random per class")
        y_pred = np.random.randint(0,self.num_classes, size=y_test.shape)
        y_pred = y_pred >= 0.5
        self.evaluate(y_test, y_pred)

        print("---")

        # Random per instance
        print("Random per instance")
        y_pred = np.random.randint(0,self.num_classes, size=y_test.shape[0])
        y_pred = np.eye(self.num_classes)[y_pred, :]
        y_pred = y_pred >= 0.5

        self.evaluate(y_test, y_pred)
        print("------------------")


# cook_book = {
#     'яйчница': [
#         {'ingredient_name': 'яйца', 'quantity': 2, 'measure': 'шт.'},
#         {'ingredient_name': 'помидоры', 'quantity': 100, 'measure': 'гр.'}
#     ],
#     'стейк': [
#         {'ingredient_name': 'говядина', 'quantity': 300, 'measure': 'гр.'},
#         {'ingredient_name': 'специи', 'quantity': 5, 'measure': 'гр.'},
#         {'ingredient_name': 'масло', 'quantity': 10, 'measure': 'мл.'}
#     ],
#     'салат': [
#         {'ingredient_name': 'помидоры', 'quantity': 100, 'measure': 'гр.'},
#         {'ingredient_name': 'огурцы', 'quantity': 100, 'measure': 'гр.'},
#         {'ingredient_name': 'масло', 'quantity': 100, 'measure': 'мл.'},
#         {'ingredient_name': 'лук', 'quantity': 1, 'measure': 'шт.'}
#     ]
# }

def get_shop_list_by_dishes(cook_book, dishes, person_count):
    shop_list = {}
    for dish in dishes:
        for ingredient in cook_book[dish]:
            new_shop_list_item = dict(ingredient)
            new_shop_list_item['quantity'] *= person_count
            if new_shop_list_item['ingredient_name'] not in shop_list:
                shop_list[new_shop_list_item['ingredient_name']] = new_shop_list_item
            else:
                shop_list[new_shop_list_item['ingredient_name']]['quantity'] += new_shop_list_item['quantity']
    return shop_list

def print_shop_list(shop_list):
    for shop_list_item in shop_list.values():
        print('{} {} {}'.format(shop_list_item['ingredient_name'], shop_list_item['quantity'],
                                shop_list_item['measure']))

def get_cook_book(path):
    cook_book = {}
    with open(path, encoding='utf-8') as f:
        while True:
            name = f.readline().strip().lower()
            f.readline()
            if not name:
                break
            cook_book[name] = []
            line = f.readline().strip()
            while line:
                ingredients = line.split(" | ")
                ingredients_dict = {"ingredient_name": ingredients[0],
                                    "quantity": int(ingredients[1]),
                                    "measure": ingredients[2]}
                cook_book[name].append(ingredients_dict)
                line = f.readline().strip()

    return cook_book

def create_shop_list():
    person_count = int(input('Введите количество человек: '))
    dishes = input('Введите блюда в расчете на одного человека (через запятую): ').lower().split(', ')
    cook_book = get_cook_book("cook_book.txt")
    shop_list = get_shop_list_by_dishes(cook_book, dishes, person_count)
    print_shop_list(shop_list)

create_shop_list()


from curie.models import base
from curie.loaders import arxiv, offline
from curie.cleaners import nltk
from curie.embedders.w2v import CW2V

from tqdm import tqdm

class ArxivCurie(base.AbstractModel):

    __name__ = "ArxivCurie"

    def __init__(self):
        super().__init__()
        self._loader = arxiv.ArxivReader()
        self._cleaner = nltk.NLTKCleaner()
        self._embedder = CW2V()

    @property
    def loader(self):
        return self._loader

    @property
    def cleaner(self):
        return self._cleaner

    @property
    def embedder(self):
        return self._embedder

    @property
    def summarizer(self):
        pass

    @property
    def name(self):
        return self.__name__

    def online_training(
        self, query: str, max_results=1000, epochs=5, load_kwargs={}
    ) -> None:
        self._loader.query(query, max_results, **load_kwargs)
        for paper in tqdm(self._loader.retrieve()):
            # extract sentences from paper, and clean
            text = self._cleaner.tokenize_sentence(paper)
            self._embedder.build_vocab(text, update=True)
            self._embedder.train(text, epochs=epochs, total_examples=len(text))

    def offline_training(self, path: str, epochs=3) -> None:
        """
        Function to perform the training routine using downloaded PDFs.
        This function overrides the `Loader` class the model would otherwise
        be using in favor of an `OfflineReader`, that simply loads and parses
        PDFs with `tika`.

        For every paper, we run the text through the cleaning pipeline, then
        pass it to our `Word2Vec` wrapper to train with.

        Parameters
        ----------
        path : str
            [description]
        """
        loader = offline.OfflineReader()
        paths = loader.query(path)
        for paper in tqdm(loader.retrieve(paths)):
            text = self._cleaner.tokenize_sentence(paper)
            self._embedder.build_vocab(text, update=True)
            self._embedder.train(text, epochs=epochs, total_examples=len(text))

    def summarize_pdf(self, path: str) -> str:
        text = self._loader.read_pdf(path)
        text = self._cleaner.tokenize_sentence(text)
        embeddings = self._embedder.sentence_embedding(text)
        return embeddings


import numpy as np
import matplotlib.pyplot as plt
import math

# 考慮rayleigh fading的16QAM調變

snr_db = [0]*11
snr = [0]*len(snr_db)
ber = [0]*len(snr_db)
N = 100000 #執行N次來找錯誤率
for i in range(len(snr)):
    snr_db[i] = 2*i
    snr[i] = np.power(10,snr_db[i]/10)

for k in range(3):
    if k == 0 or k == 1:
        # 定義16QAM的個星座點
        constellation = [1 + 1j, 1 + 3j, 3 + 1j, 3 + 3j, -1 + 1j, -1 + 3j, -3 + 1j, -3 + 3j, -1 - 1j, -1 - 3j, -3 - 1j, -3 - 3j, 1 - 1j, 1 - 3j, 3 - 1j, 3 - 3j]
        constellation_name = '16QAM'
    elif k == 2:
        # 定義64QAM星座點
        constellation_new = [-7, -5, -3, -1, 1, 3, 5, 7]
        constellation_name = '64QAM'
        constellation = []
        for i in range(len(constellation_new)):
            for j in range(len(constellation_new)):
                constellation += [constellation_new[i] + 1j * constellation_new[j]]

    for i in range(len(snr_db)):

        K = int(np.log2(len(constellation)))  # 代表一個symbol含有K個bit
        # 接下來要算平均一個symbol有多少能量
        # 先將所有可能的星座點能量全部加起來
        energy = 0
        for m in range(len(constellation)):
            energy += abs(constellation[m]) ** 2
        Es = energy / len(constellation)  # 平均一個symbol有Es的能量
        Eb = Es / K  # 平均一個bit有Eb能量
        No = Eb / snr[i]  # 決定No

        if k == 0: # 16 - QAM approximation (rayleigh)
            a = 2 * (1 - 1 / K) / np.log2(K)
            b = 6 * np.log2(K) / (K * K - 1)
            rn = b * snr[i] / 2
            ber[i] = 1 / 2 * a * (1 - np.sqrt(rn / (rn + 1)))
            continue

        error = 0

        for j in range(N):
            b = np.random.random()  # 產生一個 (0,1) uniform 分布的隨機變數，來決定送出去的信號
            for m in range(len(constellation)):
                if b <= (m+1)/len(constellation):
                    symbol = constellation[m]
                    break

            #接下來考慮rayleigh fading
            h = 1/np.sqrt(2)*np.random.randn() + 1j/np.sqrt(2)*np.random.randn()
            receive = symbol*h

            #接下來加上雜訊
            receive = receive + np.sqrt(No/2)*np.random.randn() + 1j*np.sqrt(No/2)*np.random.randn()

            #接收端利用Maximum Likelihood來detect symbol (缺點是對M - QAM調變系統而言，解調速度過慢)
            #receive = receive/h
            #min_distance = 10**9
            #for m in range(len(constellation)):
            #    if abs(constellation[m] - receive) < min_distance:
            #        detection = constellation[m]
            #        min_distance = abs(constellation[m] - receive)

            # 以下則是採用 decision region的方式來對M - QAM系統做symbol detection(解調速度較快)
            receive = receive/h
            detection = 0
            if constellation_name == '16QAM':
                for m in range(2):
                    if m == 0:  # 先detect symbol的實部
                        if (receive.real < -2):
                            detection += -3
                        elif (receive.real >= -2 and receive.real < 0):
                            detection += -1
                        elif (receive.real >= 0 and receive.real < 2):
                            detection += 1
                        else:
                            detection += 3
                    else:  # 再來detect symbol的虛部
                        if (receive.imag < -2):
                            detection += -3j
                        elif (receive.imag >= -2 and receive.imag < 0):
                            detection += -1j
                        elif (receive.imag >= 0 and receive.imag < 2):
                            detection += 1j
                        else:
                            detection += 3j
            elif constellation_name == '64QAM':
                for m in range(2):
                    if m == 0:  # 先detect symbol的實部
                        if (receive.real < -6):
                            detection += -7
                        elif (receive.real >= -6 and receive.real < -4):
                            detection += -5
                        elif (receive.real >= -4 and receive.real < -2):
                            detection += -3
                        elif (receive.real >= -2 and receive.real < 0):
                            detection += -1
                        elif (receive.real >= 0 and receive.real < 2):
                            detection += 1
                        elif (receive.real >= 2 and receive.real < 4):
                            detection += 3
                        elif (receive.real >= 4 and receive.real < 6):
                            detection += 5
                        else:
                            detection += 7
                    else:  # 再來detect symbol的虛部
                        if (receive.imag < -6):
                            detection += -7j
                        elif (receive.imag >= -6 and receive.imag < -4):
                            detection += -5j
                        elif (receive.imag >= -4 and receive.imag < -2):
                            detection += -3j
                        elif (receive.imag >= -2 and receive.imag < 0):
                            detection += -1j
                        elif (receive.imag >= 0 and receive.imag < 2):
                            detection += 1j
                        elif (receive.imag >= 2 and receive.imag < 4):
                            detection += 3j
                        elif (receive.imag >= 4 and receive.imag < 6):
                            detection += 5j
                        else:
                            detection += 7j

            # 紀錄錯幾個bit
            # 我們這次不找錯幾個symbol，因為在SNR很小時，symbol error rate / 4 不等於 ber error rate
            if detection != symbol :
                if constellation_name == '16QAM':
                    if abs(detection.real-symbol.real) == 2 or abs(detection.real-symbol.real) == 6:
                        error += 1
                    elif abs(detection.real-symbol.real) == 4:
                        error += 2
                    if abs(detection.imag-symbol.imag) == 2 or abs(detection.imag-symbol.imag) == 6:
                        error += 1
                    elif abs(detection.imag-symbol.imag) == 4:
                        error += 2
                elif constellation_name == '64QAM':
                    if abs(detection.real-symbol.real) == 2 or abs(detection.real-symbol.real) == 6 or abs(detection.real-symbol.real) == 14:
                        error += 1
                    elif abs(detection.real-symbol.real) == 4 or abs(detection.real-symbol.real) == 8 or abs(detection.real-symbol.real) == 12:
                        error += 2
                    elif abs(detection.real - symbol.real) == 10:
                        error += 3
                    if abs(detection.imag-symbol.imag) == 2 or abs(detection.imag-symbol.imag) == 6 or abs(detection.imag-symbol.imag) == 14:
                        error += 1
                    elif abs(detection.imag-symbol.imag) == 4 or abs(detection.imag-symbol.imag) == 8 or abs(detection.imag-symbol.imag) == 12:
                        error += 2
                    elif abs(detection.imag - symbol.imag) == 10:
                        error += 3

        ber[i] = error / (K*N)

    if k == 0:
        plt.semilogy(snr_db, ber, marker='o', label='{0} (approximation for rayleigh fading)'.format(constellation_name))
    if k == 1 or k == 2:
        plt.semilogy(snr_db, ber, marker='o', label='{0} (simulation for rayleigh fading)'.format(constellation_name))

plt.xlabel('Eb/No , dB')
plt.ylabel('BER')
plt.ylim(10**(-3),1)
plt.legend()
plt.grid(True,which='both')
plt.show()


#정규식
import re  #정규표현식 지원하기 위해 re모듈 사용 /모듈 임포트
           #p =re.compile('정규표현식')을 통해서 정규표현식 컴파일함
p = re.compile("ca.e")  # . : 하나의 문자를 의미 /care,case 됨 , caffe는 안됨
                       # ^ : 문자열 시작 (^de)이면 desk,destination
                      # $ (se$):문자열 끝 ,case,base

m= p.match("case") #case가 정규식의 내용가 match(매칭)이 되어 출력됨
print(m.group())

# m = p.match("caffe")
# print(m.group()) #매치되지 않으면 에러가 발생

if m:
    print(m.group())
else:
    print("매칭되지 않음")


import time

def exercise_006(n_natural):
    """
    The sum of the squares of the first ten natural numbers is,
        1^2 + 2^2 + 3^2 + ... + 10^2 = 385

    The square of the sum of the first ten natural numbers is,
        (1 + 2 + 3 + ... + 10)^2 = 55^2 = 3025

    Hence the difference between the sum of the squares of the first ten
    natural numbers and the square of the sum is 3025 - 385 = 2640. Find the
    difference between the sum of the squares of the first one hundred natural
    numbers and the square of the sum.

    :param n_natural: Number of natural numbers
    :type n_natural: int

    :return: difference between the sum of the squares of the first
    <n_natural> natural numbers and the square of the sum.
    :rtype: int
    """

    cumsum = 0
    sum_square = 0
    for natural in range(1, n_natural+1):
        cumsum += natural
        sum_square += natural ** 2

    difference = cumsum ** 2 - sum_square

    return difference

def exercise_006_best(n_natural):
    cumsum = n_natural * (n_natural + 1) / 2
    sum_square = (2 * n_natural + 1) * (n_natural + 1) * n_natural / 6
    difference = cumsum ** 2 - sum_square
    return difference

if __name__ == '__main__':
    n_natural = 100  # 10
    start_time = time.time()
    print(exercise_006(n_natural))
    end_time = time.time()
    print('{} s'.format(end_time - start_time))

    start_time = time.time()
    print(exercise_006_best(n_natural))
    end_time = time.time()
    print('{} s'.format(end_time - start_time))


"""
Saindo de loops com break

Utilizamos break para sair de loop de maneira projetada.
"""

for num in range(1, 11):
    if num == 6:
        break
    else:
        print(num)
print('Sai do loop')

while True:
    comando = input("Digite 'sair' para sair: ")
    if comando == 'sair':
        break
print('Sai do loop')


import os
import nibabel as nib
import re
import numpy as np
import warnings
# Internal libraries/scripts
from miscnn.data_loading.interfaces.abstract_io import Abstract_IO

#-----------------------------------------------------#
#                 NIfTI I/O Interface                 #
#-----------------------------------------------------#
""" Data I/O Interface for NIfTI files. The Neuroimaging Informatics Technology Initiative file format
    is designed to contain brain images from e.g. magnetic resonance tomography. Nevertheless, it is
    currently broadly used for any 3D medical image data.

Code source heavily modified from the Kidney Tumor Segmentation Challenge 2019 git repository:
https://github.com/neheller/kits19
"""
class NIFTI_interface(Abstract_IO):
    # Class variable initialization
    def __init__(self, channels=1, classes=2, three_dim=True, pattern=None):
        self.data_directory = None
        self.channels = channels
        self.classes = classes
        self.three_dim = three_dim
        self.pattern = pattern

    #---------------------------------------------#
    #                  initialize                 #
    #---------------------------------------------#
    # Initialize the interface and return number of samples
    def initialize(self, input_path):
        # Resolve location where imaging data should be living
        if not os.path.exists(input_path):
            raise IOError(
                "Data path, {}, could not be resolved".format(str(input_path))
            )
        # Cache data directory
        self.data_directory = input_path
        # Identify samples
        sample_list = os.listdir(input_path)
        # IF pattern provided: Remove every file which does not match
        if self.pattern != None and isinstance(self.pattern, str):
            for i in reversed(range(0, len(sample_list))):
                if not re.fullmatch(self.pattern, sample_list[i]):
                    del sample_list[i]
        # Return sample list
        return sample_list

    #---------------------------------------------#
    #                  load_image                 #
    #---------------------------------------------#
    # Read a volume NIFTI file from the data directory
    def load_image(self, index):
        # Make sure that the image file exists in the data set directory
        img_path = os.path.join(self.data_directory, index)
        if not os.path.exists(img_path):
            raise ValueError(
                "Image could not be found \"{}\"".format(img_path)
            )
        # Load volume from NIFTI file
        vol = nib.load(os.path.join(img_path, "imaging.nii.gz"))
        # Transform NIFTI object to numpy array
        vol_data = vol.get_fdata()
        # Identify correct spacing diagonal
        spacing_matrix = vol.affine[:3,:3]
        diagonal_negative = np.diag(spacing_matrix)
        diagonal_positive = np.diag(spacing_matrix[::-1,:])
        if np.count_nonzero(diagonal_negative) != 1:
            spacing = diagonal_negative
        elif np.count_nonzero(diagonal_positive) != 1:
            spacing = diagonal_positive
        else:
            warnings.warn("Affinity matrix of NIfTI volume can not be parsed.")
        # Calculate absolute values for voxel spacing
        spacing = np.absolute(spacing)
        # Delete cached spacing
        # Return dictionary
        return vol_data, {"type":"nifti", "affine":vol.affine, "spacing":spacing}

    #---------------------------------------------#
    #              load_segmentation              #
    #---------------------------------------------#
    # Read a segmentation NIFTI file from the data directory
    def load_segmentation(self, index):
        # Make sure that the segmentation file exists in the data set directory
        seg_path = os.path.join(self.data_directory, index)
        if not os.path.exists(seg_path):
            raise ValueError(
                "Segmentation could not be found \"{}\"".format(seg_path)
            )
        # Load segmentation from NIFTI file
        seg = nib.load(os.path.join(seg_path, "segmentation.nii.gz"))
        # Transform NIFTI object to numpy array
        seg_data = seg.get_fdata()
        # Return segmentation
        return seg_data #should this also store the matrix in case they are not aligned?

    #---------------------------------------------#
    #               load_prediction               #
    #---------------------------------------------#
    # Read a prediction NIFTI file from the MIScnn output directory
    def load_prediction(self, index, output_path):
        # Resolve location where data should be living
        if not os.path.exists(output_path):
            raise IOError(
                "Data path, {}, could not be resolved".format(str(output_path))
            )
        # Parse the provided index to the prediction file name
        pred_file = str(index) + ".nii.gz"
        pred_path = os.path.join(output_path, pred_file)
        # Make sure that prediction file exists under the prediction directory
        if not os.path.exists(pred_path):
            raise ValueError(
                "Prediction could not be found \"{}\"".format(pred_path)
            )
        # Load prediction from NIFTI file
        pred = nib.load(pred_path)
        # Transform NIFTI object to numpy array
        pred_data = pred.get_fdata()
        # Return prediction
        return pred_data #should this also store the matrix in case they are not aligned?

    #---------------------------------------------#
    #               save_prediction               #
    #---------------------------------------------#
    # Write a segmentation prediction into in the NIFTI file format
    def save_prediction(self, sample, output_path):
        # Resolve location where data should be written
        if not os.path.exists(output_path):
            raise IOError(
                "Data path, {}, could not be resolved".format(output_path)
            )
        # Obtain prediction data
        pred = sample.pred_data.astype(np.uint16)
        if "affine" in sample.get_extended_data():
            spacing = sample.get_extended_data()["affine"]
        else : spacing = None
        # Convert numpy array to NIFTI
        nifti = nib.Nifti1Image(pred, spacing)
        # Save segmentation to disk
        pred_file = str(sample.index) + ".nii.gz"
        nib.save(nifti, os.path.join(output_path, pred_file))

    #---------------------------------------------#
    #           check_file_termination            #
    #---------------------------------------------#
    @staticmethod
    def check_file_termination(termination):
        return termination in [".nii.gz"]


# Make a dictionary with three major rivers and the country each
# runs through.  Key is river, Value is country.
# Use a loop to print a sentance about each river including key and
# value.
# Use a loop to print each river and one to print each country.

rivers = {
        'xingu': 'brazil',
        'ob': 'russia',
        'st lawrence': 'canada and united states',
        }

for river, country in rivers.items():
    print(f"The {river.title()} River is in {country.title()}.")

print("-------")

for river in rivers.keys():
    print(river.title())

print("-------")

for country in rivers.values():
    print(country.title())


import bpy
from . c_utils import executeSubtract_A_B
from ... base_types import AnimationNode, VectorizedSocket
from ... data_structures import VirtualDoubleList, DoubleList

class DelayTimeNode(AnimationNode, bpy.types.Node):
    bl_idname = "an_DelayTimeNode"
    bl_label = "Delay Time"
    dynamicLabelType = "HIDDEN_ONLY"

    useListA: VectorizedSocket.newProperty()
    useListB: VectorizedSocket.newProperty()

    def create(self):
        self.newInput(VectorizedSocket("Float", "useListA",
            ("Time", "time"), ("Times", "times")))
        self.newInput(VectorizedSocket("Float", "useListB",
            ("Delay", "delay", dict(value = 10)),
            ("Delays", "delays")))
        self.newOutput(VectorizedSocket("Float",
            ["useListA", "useListB"],
            ("Time", "outTime"), ("Times", "outTimes")))

    def drawLabel(self):
        if self.useListB: return "Delay Time"
        delaySocket = self.inputs["Delay"]
        if delaySocket.isUnlinked:
            value = delaySocket.value
            if value == int(value): return "Delay " + str(int(value)) + " Frames"
            else: return "Delay " + str(round(value, 2)) + " Frames"
        else: return "Delay Time"

    def getExecutionCode(self, required):
        if self.useListA or self.useListB:
            args = ", ".join(socket.identifier for socket in self.inputs)
            return "outTimes = self.executeList({})".format(args)
        else:
            return "outTime = time - delay"

    def executeList(self, time, delay):
        virtualTimes, virtualDelays = VirtualDoubleList.createMultiple((time, 0), (delay, 0))
        amount = VirtualDoubleList.getMaxRealLength(virtualTimes, virtualDelays)

        return executeSubtract_A_B(virtualTimes, virtualDelays, amount)


import os
from os import getenv
from dotenv import load_dotenv

if os.path.exists("local.env"):
    load_dotenv("local.env")

load_dotenv()
admins = {}
SESSION_NAME = getenv("SESSION_NAME", "session")
BOT_TOKEN = getenv("BOT_TOKEN")
BOT_NAME = getenv("BOT_NAME", "Video Stream")
API_ID = int(getenv("API_ID"))
API_HASH = getenv("API_HASH")
OWNER_NAME = getenv("OWNER_NAME", "shubham 712")
ALIVE_NAME = getenv("ALIVE_NAME", "Shubham 712")
BOT_USERNAME = getenv("BOT_USERNAME", "shubham_w_712")
ASSISTANT_NAME = getenv("ASSISTANT_NAME", "shubham_712")
GROUP_SUPPORT = getenv("GROUP_SUPPORT", "Old is Gold")
UPDATES_CHANNEL = getenv("UPDATES_CHANNEL", "Old is Gold")
UPSTREAM_REPO = getenv("UPSTREAM_REPO","https://github.com/shubham1992228/NOBITA_JAAN?organization=shubham1992228&organization=shubham1992228")
SUDO_USERS = list(map(int, getenv("SUDO_USERS").split()))
COMMAND_PREFIXES = list(getenv("COMMAND_PREFIXES", "/ ! .").split())
ALIVE_IMG = getenv("ALIVE_IMG", "https://telegra.ph/file/9ef29940fd5d6d7bc756c.jpg")
DURATION_LIMIT = int(getenv("DURATION_LIMIT", "60"))
IMG_1 = getenv("IMG_1", "https://telegra.ph/file/9ef29940fd5d6d7bc756c.jpg")
IMG_2 = getenv("IMG_2", "https://telegra.ph/file/9ef29940fd5d6d7bc756c.jpg")
IMG_3 = getenv("IMG_3", "https://telegra.ph/file/9ef29940fd5d6d7bc756c.jpg")


#682.BaseballGame.py
# https://leetcode.com/problems/baseball-game/
class Solution:
    def calPoints(self, operations: List[str]) -> int:
        mystack = []
        for i in operations:
            if len(mystack) > 1 and i == '+':
                mystack.append(int(mystack[-1]) + int(mystack[-2]))
            elif mystack and i == 'C':
                mystack.pop()
            elif mystack and i == 'D':
                mystack.append(2*int(mystack[-1]))
            else:
                mystack.append(int(i))
        return sum(mystack)


def solve(n):
    count  = 0
    answer = []
    while n > 0:
        if n % 2 == 1:
            answer.append(count)
        n //= 2
        count += 1
    return answer

while True:
    n=int(input())
    if n == 0:
        break
    print("{ " + (", ".join([ str(3**i) for i in solve(n-1) ]) + " }" if n != 1 else "}"))


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

## @package drama_filter
# Main module.

from code import *

__author__ = 'Gabriela Salvador Thumé <gabithume@gmail.com>'
__copyright__ = 'Copyright (c) 2012 Gabriela Salvador Thumé'
__license__ = 'GPLv3'
__version__ = '0.1'

## \mainpage Project D.R.A.M.A. Filter
#
# \section intro Introduction
#
# This module aims to ...
#
# \section install_sec Installation
#
# To install this module, just download the last version,
# unpack it and import drama_filter package on your Python
# interpreter:
#
#     import drama_filter as df
#
#     df.main()


from six.moves import cPickle as pickle
from random import randint

import numpy as np
import theano as th

class Dataset(object):
    def __init__(self):
        self.train_size = 0
        self.test_size = 0
        self.labels = []
        self.datas = []
        pass
    def load(self, i_=None, is_test_=False, augment_=False):
        if is_test_:
            y_set = self.labels[self.train_size:]
            x_set = self.datas[self.train_size:]
        else:
            y_set = self.labels[:self.train_size]
            x_set = self.datas[:self.train_size]
        if i_ is None:
            i_ = randint(0, len(x_set)-1)
        elif type(i_) is int:
            i_ = [i_]
        if not augment_:
            return x_set[i_], y_set[i_]
        return type(self)._augment_data_batch(x_set[i_]),y_set[i_]

    def _augment_data_batch(v_img_):
        return v_img_

class Cifar10Loader(Dataset):
    def __init__(self):
        self.train_size = 50000
        self.test_size = 10000
        self.labels = np.empty(shape=(60000,), dtype=np.int32)
        self.datas = np.empty(shape=(60000,3,32,32), dtype=np.float32)
        for b in range(5):
            with open('./data/image/cifar10/data_batch_'+str(b+1), 'rb') as f:
                data = pickle.load(f, encoding='bytes')
                self.labels[10000*b:10000*(b+1)] = np.asarray(data[b'labels'], dtype=np.int32)
                self.datas[10000*b:10000*(b+1)]= np.reshape(np.asarray(data[b'data'], dtype=np.float32), (10000,3,32,32))/255.
        with open('./data/image/cifar10/test_batch', 'rb') as f:
            data = pickle.load(f, encoding='bytes')
            self.labels[50000:60000] = np.asarray(data[b'labels'], dtype=np.int32)
            self.datas[50000:60000]= np.reshape(np.asarray(data[b'data'], dtype=np.float32), (10000,3,32,32))/255.

    def _augment_data_batch(v_img_):
        for img in v_img_:
            if randint(0,65535)>32767:
                img[:,:,:] = img[:,:,::-1]
            gamma = np.random.uniform(0.77,1.3, size=(3,1,1))
            img **= gamma
            r,n = divmod(randint(0,31), 8)
            if r==0:
                img[:,:n,:] = 0.
            elif r==1:
                img[:,-n:, :] = 0.
            if r==2:
                img[:,:,:n] = 0.
            elif r==3:
                img[:,:,-n:] = 0.

class MnistLoader(Dataset):
    def __init__(self):
        self.train_size = 60000
        self.test_size = 10000
        self.labels = np.empty(shape=(70000,), dtype=np.int32)
        self.datas = np.empty(shape=(70000,1,28,28), dtype=np.float32)
        with open('./data/image/mnist/mnist-train.pkl', 'rb') as f:
            self.labels[:60000] = np.asarray(pickle.load(f), dtype=np.int32)
            self.datas[:60000] = np.expand_dims(np.asarray([pickle.load(f) for _ in range(60000)], dtype=th.config.floatX), 1)
        with open('./data/image/mnist/mnist-test.pkl', 'rb') as f:
            self.labels[60000:] = np.asarray(pickle.load(f), dtype=np.int32)
            self.datas[60000:] = np.expand_dims(np.asarray([pickle.load(f) for _ in range(10000)], dtype=th.config.floatX), 1)

    def _augment_data_batch(v_img_):
        return v_img_


#!/usr/bin/env python
# coding: UTF-8
#
## @package engine
#
#   Executing a list of instructions
#
#   @author Nathaniel Ramalho
#   @since 11/28/2020
#

from virtual_machine import VirtualMachine
from assembler import Assembler
from time import sleep
from instruction_set import Fill, Sw

class Engine:
    def __init__(self, context):
        self.execution_queue = []
        self.virtual_machine = None
        self.clock = 0.5
        self.status = StatusReady()
        self.context = context

    ##
    # Performs actions necessary to execute a program from
    #  text and executes the program
    #
    def run(self, text):
        if self.status.is_running:
            self.status = StatusReady()

        if not text:
            self.context.log_on_console('O código fonte está em branco.')
            self.context.log_on_console('Fim da execução.')
            self.context.change_back_pc_bg()
            self.context.console_space()
            self.context.enable_execution_button()
            return

        # Translation
        try:
            self.translate(text)
        except ValueError as err:
            self.context.log_on_console(err)
            self.context.log_on_console('Fim da Execução.')
            self.context.enable_execution_button()
            self.context.change_back_pc_bg()
            return

        # Execution
        self.create_virtual_machine()
        self.virtual_machine.reset_pc()

        self.status = StatusRunning()

        while self.status.is_running:
            pc = self.virtual_machine.get_pc()
            if not self.is_valid_pc(pc):
                self.context.log_on_console('Falha na execução.')
                self.context.log_on_console('    O endereço de memória acessado '
                                            'não contém uma instrução válida.')
                self.context.log_on_console('    (Dica: sempre termine seu '
                                            'código com halt)')
                self.virtual_machine.reset_pc()

                self.status = StatusReady()
                self.context.enable_execution_button()
                self.context.log_on_console('Fim da Execução.')
                self.context.change_back_pc_bg()
                return

            try:
                sleep(self.clock)

                instruction = self.execution_queue[pc]

                if isinstance(instruction, int):
                    raise ValueError(f'Erro de execução: "{instruction}" não é uma '
                                     f'instrução válida.\n(endereço de memória: {pc})')
                else:
                    inst_representation = self.execution_queue[pc].get_hexa_representation(self.virtual_machine)
                    self.virtual_machine.instruction_register = inst_representation
                    success = instruction.execute(self.virtual_machine)

                if success:
                    self.virtual_machine.increment_pc()
                    if isinstance(instruction, Sw):
                        self.update_execution_queue()
                        self.context.update_memory_table()
                        self.context.update_ui_pc()
                else:
                    self.status = StatusReady()
                    self.context.log_on_console('Fim da execução.')
                    self.context.change_back_pc_bg()
                    self.context.console_space()
                    self.context.enable_execution_button()
            except (ValueError, TypeError) as err:
                self.context.log_on_console(err)

                self.context.log_on_console('Fim da Execução.')
                self.context.console_space()
                self.context.change_back_pc_bg()

                self.virtual_machine.reset_pc()
                self.status = StatusReady()
                self.context.enable_execution_button()

    ##
    # Performs a series of actions to start the step execution.
    #
    def run_in_steps(self, text):
        if not text:
            self.context.log_on_console('O código fonte está em branco.')
            self.context.log_on_console('Fim da execução em etapas.')
            self.context.change_back_pc_bg()
            self.context.console_space()
            return

        if self.status.is_running:
            self.status = StatusReady()

        try:
            self.translate(text)
        except ValueError as err:
            self.context.log_on_console(err)
            self.context.log_on_console('Fim da Execução.')
            self.context.enable_execution_button()
            self.context.change_back_pc_bg()
            return

        self.create_virtual_machine()
        self.virtual_machine.reset_pc()
        self.virtual_machine.instruction_register = 0

        self.status = StatusWaiting()
        self.context.log_on_console('O sistema iniciou o processo de Execução em Etapas.')
        self.context.change_pc_bg()
        self.context.action_avancar.setDisabled(False)

    ##
    # Execute the next instruction of the execution queue when
    # in step execution mode
    #
    def step_foward(self):
        pc = self.virtual_machine.get_pc()
        if not self.is_valid_pc(pc):
            self.context.log_on_console('Falha na execução.')
            self.context.log_on_console('    O endereço de memória acessado não contém uma instrução válida.')
            self.context.log_on_console('    (Dica: Sempre termine seu código com "halt")')
            self.virtual_machine.reset_pc()
            self.status = StatusWaiting()
            self.context.action_avancar.setDisabled(True)
            self.context.log_on_console('Fim da execução.')
            self.context.change_back_pc_bg()
            self.context.console_space()
            return

        if not self.status.is_step_execution:
            self.context.log_on_console(
                'O sistema não está em modo de Execução em Etapas.')

            self.context.log_on_console('Fim da Execução.')
            self.context.enable_execution_button()
            self.context.change_back_pc_bg()

            return

        try:
            instruction = self.execution_queue[pc]

            if isinstance(instruction, int):
                raise ValueError(f'Erro de execução: "{instruction}" não é uma '
                                 f'instrução válida.\n(endereço de memória: {pc})')
            else:
                inst_representation = self.execution_queue[pc].get_hexa_representation(self.virtual_machine)
                self.virtual_machine.instruction_register = inst_representation
                success = instruction.execute(self.virtual_machine)

            if success:
                self.virtual_machine.increment_pc()
                if isinstance(instruction, Sw):
                    self.update_execution_queue()
                    self.context.update_memory_table()
                    self.context.update_ui_pc()
            else:
                self.context.action_avancar.setDisabled(True)
                self.context.log_on_console('Fim da Execução em Etapas.')
                self.context.change_back_pc_bg()
                self.context.console_space()
                self.status = StatusReady()
                self.context.enable_execution_button()
        except (ValueError, TypeError) as err:
            self.context.log_on_console(err)
            self.context.log_on_console('Fim da Execução.')
            self.context.change_back_pc_bg()
            self.virtual_machine.reset_pc()
            self.context.action_avancar.setDisabled(True)
            self.status = StatusWaiting()

        pc = self.virtual_machine.get_pc()

        if not self.is_valid_pc(pc):
            self.status = StatusReady()

    ##
    # Performs a series of actions to translate a text
    # into source code. It also invokes other methods to
    # load the translated data into the virtual machine.
    # reraises exceptions that may occur in the methods
    # called during its execution
    #
    # @param text texto de entrada do usuário
    def translate(self, text):
        if not text:
            self.context.log_on_console('Sem itens para traduzir.')
            self.context.console_space()
            return

        self.create_virtual_machine()
        try:
            self.populate_execution_queue(text)
            self.update_vm_labels()
            self.update_vm_main_memory()
        except ValueError as err:
            raise ValueError(err)
        self.context.log_on_console('Sucesso na tradução!')

    ##
    # Populates the execution queue with the instruction
    # list translated by the assembler.
    #
    def populate_execution_queue(self, text):
        assembler = Assembler()
        try:
            self.execution_queue = assembler.assemble(text)
        except ValueError as err:
            raise ValueError(err)

    ##
    #   Updates execution_queue based on virual_machine.main_memory
    #
    #   @see VirtualMachine
    def update_execution_queue(self):
        memory = self.virtual_machine.main_memory

        # TODO: Maybe this test is unnecessary
        if self.virtual_machine.BLOCKED_ADDRESS_KEY in memory.keys():
            memory.pop(self.virtual_machine.BLOCKED_ADDRESS_KEY)

        for i, k in enumerate(memory.keys()):
            if i >= len(self.execution_queue):
                self.execution_queue.append(memory[k])
            else:
                inst = self.execution_queue[i]
                if isinstance(inst, int):
                    value = inst
                else:
                    value = inst.get_hexa_representation(self.virtual_machine)
                    value = int(value, 16)
                if value != self.virtual_machine.main_memory[k]:
                    self.execution_queue[i] = memory[k]

        self.virtual_machine.block_memory(len(self.execution_queue) - 1)

    ##
    # Updates the data in the main memory of the virtual machine
    #
    def update_vm_main_memory(self):
        self.virtual_machine.clear_main_memory()

        try:
            for i, inst in enumerate(self.execution_queue):
                if isinstance(inst, Fill):
                    representation = inst.get_value()
                    if representation in self.virtual_machine.labels.keys():
                        representation = self.virtual_machine.get_label_value(representation)
                else:
                    hex_representation = inst.get_hexa_representation(self.virtual_machine)
                    representation = int(hex_representation, 16)
                self.virtual_machine.set_main_memory_value(representation, i)
            # TODO: (2021-sw) BLOQUEIO DA MEMÓRIA - TALVEZ REMOVER O TESTE EM UPDATE_EXECUTION_QUEUE
            self.virtual_machine.block_memory(len(self.execution_queue) - 1)
        except ValueError as err:
            raise ValueError(f'Atualização da memória principal: {err}')
        self.context.update_memory_table()

    ##
    # Updates the list of virtual machine labels
    #
    def update_vm_labels(self):
        self.create_virtual_machine()
        try:
            self.virtual_machine.clear_labels()
            for i, inst in enumerate(self.execution_queue):
                if inst.label is not None:
                    self.virtual_machine.add_label(inst.label, i)
                inst.set_address(i)
        except ValueError as err:
            raise ValueError(err)

    ##
    # Checks your past value can represent a valid register
    #
    # @param a value to check if can represent a register
    #
    def is_valid_pc(self, pc):
        if pc in list(range(len(self.execution_queue))):
            return True

        return False

    ##
    # Creates a virtual machine if not exists
    #
    def create_virtual_machine(self):
        if self.virtual_machine is None:
            self.virtual_machine = VirtualMachine(self.context)

    def set_clock(self, value):
        self.clock = value

    ##
    # Returns data tha represents a Engine class instance
    #
    # @retun A string that represents the object
    #
    def __repr__(self):
        msg = '\n-= ENGINE =-\n'
        msg += f'· Status: {self.status}\n'
        msg += f'· Clock: {self.clock}\n'
        msg += '· Execution Queue: \n'
        msg += '\t' + str(self.execution_queue) + '\n'
        msg += '· Virtual Machine:\n'
        msg += str(self.virtual_machine) + '\n'
        msg += '-= FIM =-:\n'

        return msg

# States
##
# EngineStatus is an abstract class
# to model all sistem status classes
#
class EngineStatus:
    NAME = 'Superclass'

    def __init__(self):
        self.is_running = False
        self.is_step_execution = False

    def __repr__(self):
        return self.NAME

##
# Classes whose instance represents the running engine
#
class StatusRunning(EngineStatus):
    NAME = 'Running'

    def __init__(self):
        super().__init__()
        self.is_running = True

##
# Class whose instance represents the waiting state.
# This state occurs when the engine is running a step execution.
#
class StatusWaiting(EngineStatus):
    NAME = 'Waiting'

    def __init__(self):
        super().__init__()
        self.is_running = True
        self.is_step_execution = True

##
# Class whose instance represents the engine in
# its normal state ready to receive commands.
#
class StatusReady(EngineStatus):
    NAME = 'Ready'

    def __init__(self):
        super().__init__()


import zmq

def start_server():
    context=zmq.Context()
    socket = context.socket(zmq.REP)
    socket.bind("tcp://*:5556")

    while True:
        message=socket.recv_string()
        print("%s" % message)
        socket.send_string("18429 サーバからクライアントに送るメッセージ：絶好調やで")

    socket.close()
    context.destroy()

if __name__ == "__main__":
    start_server()


from itertools import product

from urllib.parse import uses_relative
from wsgiref.util import request_uri
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from django.http import Http404
from .serializer import OrderAddressSerializer,OrderSerializer,OrderAdminserializer,OrdernumberSerializer
from .models import Address, Order,Ordernumber
from rest_framework.decorators import api_view
from rest_framework import status
from django.http import JsonResponse
from cart.models import Cart

import random
import string
import datetime
import itertools

# Create your views here.

class OrderAddress(APIView):

        def get(self,request):
            print("this is get")
            data=Address.objects.all()
            print("pro")
            seriail=OrderAddressSerializer(data,many=True)
            return Response(seriail.data,status=status.HTTP_200_OK)

        def post(self,request):
            serializer = OrderAddressSerializer(data=request.data)
            if serializer.is_valid():
                serializer.save()
                print("saved ayyeee")
                return Response(serializer.data, status=status.HTTP_201_CREATED , )

            print("",serializer.errors)

            return Response(serializer.errors,status=status.HTTP_502_BAD_GATEWAY)

class ordernumber_generation(APIView):
    def get(self,request):
        print("this is otp")
        yr                  = int(datetime.date.today().strftime('%Y'))
        dt                  = int(datetime.date.today().strftime('%d'))
        mt                  = int(datetime.date.today().strftime('%m'))
        d                   = datetime.date(yr,mt,dt)
        current_date        = d.strftime("%Y%m%d")
        orderno = Ordernumber()

        orderno.save()
        orderno.order_no       = current_date + str(orderno.id)
        orderno.save()
        print(orderno)

        return Response({"num":orderno.order_no})

class Orderplaced(APIView):
    def post (self,request):
        print("order palced ")

        userid=request.data["username"]
        ordernum=request.data["order_number"]
        orderid = Ordernumber.objects.get(order_no=ordernum)
        Idorder=orderid.id

        request.data['order_number']=Idorder

        items=Cart.objects.filter(username=userid)
        order=Order()

        for i in items:
           print(i.product_id_id)
           request.data["product"]=i.product_id_id
           request.data["product_stock"]=i.product_stock
           print("this is product assigned")
           print (request.data,"this is request.data")
           seril=OrderSerializer(data=request.data)
           if seril.is_valid(raise_exception=True):
               seril.save()
               print("this is porduct")
           else :
               return Response ("this is not a valid data")

        print("for loop is completed")
        return Response ({"status":"true"})

    def get(self,request):
            print("this is get")
            data=Order.objects.all()
            print("pro")
            seriail=OrderAdminserializer(data,many=True,context={'request': request})
            return Response(seriail.data,status=status.HTTP_200_OK)
    def patch(self,request):
        print("this is patch ")
        orderid=request.data["orderid"]
        productid=request.data["productid"]
        orderstatus=request.data["status"]
        item=Order.objects.get(order_number=orderid,product=productid)

        item.status=orderstatus
        item.save()
        serial = OrderSerializer(data=item)
        print(serial)
        return Response (" saved ")

class Userorder(APIView):

    def post(self, request):

        username= request.data["username"]
        data = Order.objects.filter(username=username)
        useritems = OrderAdminserializer(data, many=True,context={'request':request})
        return Response (useritems.data)

class ordernumberlist(APIView):

    def post(self, request):
        print ("ordre number function")

        username = request.data["username"]
        data = Order.objects.filter(username=username)
        print(type(data))
        print (data)
        useritems = OrdernumberSerializer(
            data, many=True,)

        return Response(useritems.data)

        # return Response ({"data":"saved"})

#  {"status":"item_shipped","orderid":"2022032169","productid":"29"}
#instance.email = validated_data.get('email', instance.email)

# # {"userid":"31","address":3,"payment_method":"COD","order_number":2022201}

        # return Response ({"data":"notsaved"})

# class Ordermanage(APIView):
#{"userid":31}

#  {"full_name":"zayan malik","mobile":"7012682523","state":"kerala","city":"kalladikode","district":"palakkad","address_line1":"puthenparambil"}


# Conways game of life - Python

# Any live cell with fewer than two live neighbours dies, as if by underpopulation.
# Any live cell with two or three live neighbours lives on to the next generation.
# Any live cell with more than three live neighbours dies, as if by overpopulation.
# Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
# These rules, which compare the behavior of the automaton to real life, can be condensed into the following:

# Any live cell with two or three live neighbours survives.
# Any dead cell with three live neighbours becomes a live cell.
# All other live cells die in the next generation. Similarly, all other dead cells stay dead.

import time
import pygame
import numpy

# I want to define color constants as I will be using them frequently throughout
color_bg = (255, 246, 213)
color_grid = (249, 237, 187)
color_die_next = (185, 157, 136)
color_alive_next = (93, 50, 43)

# Update will contain game logic and drawing process
# with_progress=False allows me to update the screen without moving to the next generation, if true executes the next
# generation
def update(screen, cells, size, with_progress=False):
    # empty numpy array creates the shape of the already existing cells and creates an empy array and within this
    # updated array apply changes
    updated_cells = numpy.zeros((cells.shape[0], cells.shape[1]))
    # This takes each cell and lets me iterate over each cell by row and column going throuhg each and ecery one
    for row, col in numpy.ndindex(cells.shape):
        # Apply game rules here: calculate number of alive neighbouring cells, check all cells surrounding current
        # alive cell if any others are alive
        # Calculate from top left cell to bottom right cell any 1 cells, sdubstract the 1 cell that is alive
        alive = numpy.sum(cells[row - 1:row + 2, col - 1:col + 2]) - cells[row, col]
        # Sets cells to background color if not alive = 0 else sets to alive next color
        color = color_bg if cells[row, col] == 0 else color_alive_next

        if cells[row, col] == 1:
            # Any live cell with fewer than two live neighbours dies, as if by underpopulation.
            # Any live cell with more than three live neighbours dies, as if by overpopulation.
            if alive < 2 or alive > 3:
                if with_progress:
                    color = color_die_next
            # Any live cell with two or three live neighbours lives on to the next generation.
            elif 2 <= alive <= 3:
                updated_cells[row, col] = 1
                if with_progress:
                    color = color_alive_next
        else:
            if alive == 3:
                updated_cells[row, col] = 1
                if with_progress:
                    color = color_alive_next
        pygame.draw.rect(screen, color, (col * size, row * size, size - 1, size - 1))

    return updated_cells

# Main functionality
def main():
    # Initialise pygame
    pygame.init()
    # Create a screen
    screen = pygame.display.set_mode((1920, 1080))
    cells = numpy.zeros((108, 192))
    # Fills screen with grid color unless a cell is dead in which case it applies the background color to that cell
    screen.fill((color_grid))
    update(screen, cells, 10)
    pygame.display.flip()
    pygame.display.update()

    # Game loop
    running = False

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            elif event.type == pygame.KEYDOWN:
                # Toggle running with spacebar
                if event.key == pygame.K_SPACE:
                    running = not running
                    update(screen, cells, 10)
                    pygame.display.update()
            if pygame.mouse.get_pressed()[0]:
                pos = pygame.mouse.get_pos()
                cells[pos[1] // 10, pos[0] // 10] = 1
                pygame.display.update()
                screen.fill(color_grid)

            if running:
                cells = update(screen, cells, 10, with_progress=True)
                pygame.display.update()

            time.sleep(0.001)

if __name__ == '__main__':
    main()


#Mongo
from mongoengine import *
from utils import StatsGenerator, Tools, FileGenerator
import models
import csv
import utils
import os
import codecs

#Connect to mongo `export MONGOLAB_URI=$MONGOLAB_URI`
connect('db', host=os.environ.get('MONGOLAB_URI'))

csvfile = open('korea_Raw4.csv', 'rU')
reader = csv.DictReader(csvfile, dialect=csv.excel)
Form = utils.Form()

stats = StatsGenerator()

models.Company.objects(Q(country='Korea')).delete()
models.Company.objects(Q(country='kr')).delete()
models.Stats.objects(Q(country='kr')).delete()
models.Agency.objects(Q(country='kr')).delete()

# Issues:
#  * Company description is missing.  what should we show instead?
#  * Company category column has several categories, we can only show one.  Please pick one category for each company. Right now we're just showing the first listed category.

# MAX_ROWS = 10000 # CHANGE ME WHEN YOU RUN FOR REAL!!!!

output=[]
for rownum, row in enumerate(reader):
    #arguments={}
    #for i in header:
    #    arguments[i]=each[i]
    company = Form.create_new_company(arguments={
        'country': 'Korea', # this will be stored as 'kr'
        'companyName': row['company_name'].decode('utf8', errors='ignore'),
        'state': row['state'].decode('utf8', errors='ignore')
    })
    company.url = row['url'].decode('utf8', errors='ignore')
    company.yearFounded = row['year_founded'].decode('utf8', errors='ignore')
    company.city = row['city'].decode('utf8', errors='ignore')
    company.zipCode = row['zip_code'].decode('utf8', errors='ignore').zfill(5)
    company.companyCategory = row['company_category'].decode('utf8', errors='ignore')
    company.companyType = row['company_type'].decode('utf8', errors='ignore')
    company.fte = row['full_time_employees'].decode('utf8', errors='ignore')
    company.revenueSource = row['revenue_source'].decode('utf8', errors='ignore').split(', ')
    company.businessModels = row['business_model'].decode('utf8', errors='ignore')
    company.socialImpact = row['social_impact'].decode('utf8', errors='ignore').split(', ')
    company.description = row['description'].decode('utf8', errors='ignore')
    company.prettyName = Tools.prettify(company['companyName'])
    company.filters = []

    if company.companyType.lower() == 'nonprofit':
        company.companyType = 'Non-profit'

    if company.fte == '10-Jan':
        company.fte = '1 - 10'
    elif company.fte == 'Nov-50':
        company.fte = '11 - 50'

    company.companyCategory = company.companyCategory.split(',')[0]

    agency_names = row['agencies'].decode('utf8', errors='ignore').split(', ')
    agencies = []
    for agency_name in agency_names:
        if agency_name == '':
            continue
        else:
            agency_name = agency_name.strip()
        agency = models.Agency.objects(Q(country='kr') & Q(name=agency_name)).first()
        if not agency:
            agency = models.Agency(name=agency_name,
                prettyName=Tools.prettify(agency_name),
                abbrev="",
                url="",
                source="",
                subagencies=[],
                datasets=[],
                usedBy=[],
                notes="",
                dataType='Federal', # only federal agencies are shown in the filter list
                country='kr')
            agency.save()
        agencies.append(agency)

    company.display = True
    company.save()

    for agency in agencies:
        Form.add_agency_to_company(company, agency)

    # if rownum > MAX_ROWS:
    #     break

    #print u'saved: {}'.format(company.companyName)
# print output

stats.create_new_stats('kr')
stats.refresh_stats('kr')
Tools().re_do_filters('kr')
FileGenerator().generate_company_csv('kr')
FileGenerator().generate_company_all_csv('kr')
FileGenerator().generate_agency_csv('kr')
FileGenerator().generate_chord_chart_files('kr','en')


n = int(input())
data = []
for i in range(n):
    data.append(list(map(int, input().split())))
def binary_search(left, right):
    if right - left <= 1:
        return right
    middle = (right + left)//2
    if is_can(middle):
        return binary_search(left,middle)
    else:
        return binary_search(middle,right)
def is_can(limit):
    data.sort(key=lambda x: (limit - x[0] + x[1]) / x[1])
    for i in range(n):
        if data[i][0] + data[i][1] * i > limit:
            return False
    return True
print(binary_search(0,10**15))

python/AtCoder Beginner Contest 023/射撃王.py


def main():
    # first = [9, 6, 8, 3, 6, 4, 1, 8, 5, 1]
    # second = [9, 9, 9, 5, 7, 8, 8, 10, 8, 2]
    # values = [17, 29, 3, 20, 11, 8, 3, 23, 5, 15]
    # query = [6, 1, 8, 9, 6, 4, 3]
    # n = 10
    # solution(n, first, second, values, query)
    first = [8, 1, 2, 2, 5, 1, 3, 6, 6]
    second = [8, 2, 4, 5, 7, 3, 6, 8, 9]
    values = [2, 4, 8, 5, 6, 7, 7, 11, 4]
    query = [1, 2, 3, 6, 5]
    n = 9
    print(solution(n, first, second, values, query))
    # for i in range(0, 10):
    #     print(i, prime_check(i))

def prime_check(val):
    if val == 4:
        return False

    for i in range(2, val//2):
        if val % i == 0:
            return False
    return True

def solution(n, first, second, values, query):
    tree = {}
    node = {}

    for i in range(len(first)):
        if first[i] == second[i]:
            continue
        if first[i] in tree:
            tree[first[i]].add(second[i])
            if second[i] in tree:
                tree[second[i]].add(first[i])
            else:
                tree[second[i]] = {first[i]}
        else:
            tree[first[i]] = {second[i]}
            if second[i] in tree:
                tree[second[i]].add(first[i])
            else:
                tree[second[i]] = {first[i]}

    for i in range(len(values)):
        node[i+1] = values[i]

    prime_tree = recursive(tree, node, 1, set(), {})

    # for i in sorted(tree.keys()):
    #     print(i, prime_tree[i])

    for i in range(len(query)):
        if query[i] in prime_tree:
            query[i] = prime_tree[query[i]]
        else:
            query[i] = 0
    return query

def recursive(tree, node, curr, looked, prime_tree):
    if_leaf = 0
    looked.add(curr)
    for i in tree[curr]:
        if i in looked:
            if_leaf += 1

    if if_leaf == len(tree[curr]):
        if prime_check(node[curr]):
            prime_tree[curr] = 1
        else:
            prime_tree[curr] = 0

        return prime_tree
    else:
        prime_count = 0
        for i in tree[curr]:
            if i not in looked:
                prime_tree = recursive(tree, node, i, looked, prime_tree)
                prime_count += prime_tree[i]
        if prime_check(node[curr]):
            prime_count += 1

        prime_tree[curr] = prime_count

        return prime_tree

if __name__ == "__main__":
    main()


import tty
import select
import sys
import termios
import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist

key_binds = {
    "i": (1.0, 0.0, 0.0, 0.0),
    "k": (0.0, 0.0, 0.0, 0.0),
    "m": (-1.0, 0.0, 0.0, 0.0),
    "j": (0.5, 0.0, 0.0, 1.0),
    "l": (0.5, 0.0, 0.0, -1.0),
    "u": (0.0, 0.0, 0.0, 1.0),
    "o": (0.0, 0.0, 0.0, -1.0)
}

class TeleopPublisher(Node):
    """
    Publisher for cmd_vel topic
    """
    def __init__(self):
        super().__init__("teleop")
        self.pub = self.create_publisher(Twist, 'cmd_vel', 10)
        self.msg = Twist()

def getKey(settings):
    """
    Get the current key pressed
    """
    tty.setraw(sys.stdin.fileno())
    select.select([sys.stdin], [], [], 0)
    key = sys.stdin.read(1)
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
    return key

def main(args=None):
    """
    Allow control of the robot using keys
    i, k, m, j, l, u, o
    """
    rclpy.init(args=args)
    tp = TeleopPublisher()
    settings = termios.tcgetattr(sys.stdin)
    key = None
    while key != '\x03':
        key = getKey(settings)
        if key in key_binds.keys():
            tp.msg.linear.x = key_binds[key][0]
            tp.msg.linear.y = key_binds[key][1]
            tp.msg.linear.z = key_binds[key][2]
            tp.msg.angular.z = key_binds[key][3]
        tp.pub.publish(tp.msg)
    rclpy.shutdown()

if __name__ == "__main__":
    main()


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def buildTree(self, preorder, inorder) -> TreeNode:
        pre = 0
        idx_map = {value: index for index, value in enumerate(inorder)}

        def helper(left, right):
            nonlocal pre
            if left > right:
                return None
            root_val = preorder[pre]
            root = TreeNode(root_val)
            pre += 1
            root.left = helper(left, idx_map[root_val]-1)
            root.right = helper(idx_map[root_val]+1, right)
            return root
        return helper(0, len(preorder)-1)


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

# In[2]:

import findspark,os
findspark.init()

# In[3]:

from pyspark.sql import SparkSession
from pyspark.sql.functions import input_file_name
spark=SparkSession.builder.appName('Read_Write_Json_Spark').getOrCreate()

# In[4]:

def getFilePath(File):
    cwd=os.getcwd()
    filepath=os.path.join(cwd,'data',File)
    return filepath

# In[5]:

df=spark.read.format('json').option('inferSchema',True).load(getFilePath('*-summary.json'))

# In[10]:

df1=df.withColumn('FILE_NAME',input_file_name()).coalesce(1)

# In[11]:

df1.write.format('json').mode('overwrite').option('path',getFilePath('JsonResult')).save()


class Solution:
    def searchRange(self, nums, target: int):
        lower_bound = self.findTarget(nums, target, True)
        if lower_bound == -1:
            return [-1,-1]
        upper_bound = self.findTarget(nums, target, False)
        return [lower_bound, upper_bound]

    def findTarget(self, nums, target, isFirst):

        start = 0
        end = len(nums)-1
        while(start <= end):
            mid = (start+end)//2
            if nums[mid] == target:
                if isFirst:
                    #check if we have the same number on the left
                    if mid == start or nums[mid-1] < target:
                        return mid
                    else:
                        end = mid-1
                else:
                    if mid==end or nums[mid+1] > target:
                        return mid
                    else:
                        start = mid+1
            elif nums[mid] > target:
                end = mid-1
            else:
                start = mid+1
        return -1

if __name__ == '__main__':
    soln = Solution()
    print(soln.searchRange([5,7,7,8,8,10], 8))
    print(soln.searchRange([8], 8))
    print(soln.searchRange([5,7,7,8,8,20],10))
    print(soln.searchRange([],0))


from collections import deque

class Solution:
    def makeGood(self, s: str) -> str:
        s, stack, is_good = deque(s), [], False

        while not is_good:
            is_good = True

            while s:
                curr = s.popleft()
                if stack and stack[-1] == curr.swapcase():
                    is_good = False
                    stack.pop()
                else:
                    stack.append(curr)

        return ''.join(stack)


# -*- coding: utf-8 -*-
import os
import glob

class Murindex:

	def __init__(self, muranalyzer, filepath='output'):
		self.m = muranalyzer
		self.outpath = filepath+os.sep+self.m.owner.replace(":", "-")

	#high level function to be called for html generation.
	def run(self):
		arbolist = self.generateArbolist()
		print("Generate index pages:")
		self.html_generateIndexes(arbolist, 1)

		self.html_writeRootIndex(arbolist, self.outpath)

	#Generate a recursive structure list for the path. structure: ((current folder), [(N+1 folder struct), (N+1 folder struct), ...]
	def generateArbolist(self, curPath=None):
		if curPath is None:
			curPath = self.outpath

		return(
			(
				curPath.replace(self.outpath, ""),
				[self.generateArbolist(curPath + os.sep + dirname) for dirname in get_immediate_subdirectories(curPath)]
			)
		)

	#This will generate an index.html for all folders of the arboList
	def html_generateIndexes(self, arboList, rank):
		print('  '*rank + self.outpath + arboList[0])

		html_generateIndex(self.outpath + arboList[0])
		for folder in arboList[1]:
			self.html_generateIndexes(folder, rank+1)

	#write an index html with the list of all svg files recusively. Folders with svg inside will be a link to the folder/index.htm
	def html_writeRootIndex(self, arboList, filepath):
		string = ""
		string += self.html_getRootList(arboList)
		string += ''

		index = open(os.path.join(filepath, 'index.htm'), 'w')
		index.write(string)
		index.close()

	#Get the html list of files (for writeRootIndex function)
	def html_getRootList(self, arboList, result=""):
		result+="
"
		svgs = getFiles(self.outpath + arboList[0], 'svg')
		htms = getFiles(self.outpath + arboList[0], 'htm')
		if svgs or htms: # there are files
			result+= "
{1}
".format(arboList[0][1::], os.path.basename(arboList[0]))
			result += "
"

			for svg in svgs:
				result +="
{0}
\n".format(os.path.basename(svg).replace(".svg", ""))
			for htm in htms:
				filename = os.path.basename(htm)
				if filename != 'index.htm':
					result +="
{1}
".format(arboList[0][1::], filename.replace(".htm", ""))

			result += "
"
		else: # no files here
			result+= "
{0}
".format(os.path.basename(arboList[0]))

		if arboList[1]: #subfolders
			for folder in arboList[1]:
				result = self.html_getRootList(folder, result=result)

		result+="
"
		return result

### OUTPUT HTML GENERATION
def get_immediate_subdirectories(a_dir):
	return [name for name in os.listdir(a_dir)
			if os.path.isdir(os.path.join(a_dir, name))]

#Generate an index.html with all svg and htm files contained in this folder
def html_generateIndex(folderPath):
	svgs = getFiles(folderPath, 'svg')
	if svgs:
		index = open(os.path.join(folderPath, 'index.htm'), 'w')
		index.write('
')
		for svg in svgs:
			index.write("
<embed type='image/svg+xml' src='{0}' />

\n".format(os.path.basename(svg)))

		index.write('
')
		index.close()

#Get all svg files inside the specified folder
def getFiles(folderPath, extension):
	if os.path.exists(folderPath) :
		return [file for file in glob.glob( os.path.join(folderPath, '*.{0}'.format(extension)))]
	else:
		return(None)


# https://leetcode.com/problems/house-robber-ii/
from typing import List

class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        nums1 = nums[:]

        if n > 3:
            nums1[2] += nums1[0]

        for i in range(3, n - 1):
            nums1[i] += max(nums1[i - 2], nums1[i - 3])

        max1 = max(nums1)
        nums2 = nums[:]

        if n > 3:
            nums2[3] += nums[1]

        for i in range(4, n):
            nums2[i] += max(nums2[i - 2], nums2[i - 3])

        max2 = max(nums2)

        return max(max1, max2)

tests = (
    ([2, 3, 2], 3),
    ([1, 2, 3, 1], 4),
    ([1, 2, 3], 3)
)

solution = Solution()

def check(inp, out):
    res = solution.rob(inp)
    assert res == out

for inp, out in tests:
    check(inp, out)


# Definition for singly-linked list.
class ListNode:
  def __init__(self, x):
    self.val = x
    self.next = None

class Solution:
  def deleteDuplicates(self, head):
    """
    :type head: ListNode
    :rtype: ListNode
    """
    if not head:
      return head
    dummy = ListNode(0)
    dummy.next = head
    slow = dummy
    fast = head
    while fast:
      while fast.next and fast.val == fast.next.val:
        fast = fast.next
      if slow.next == fast:
        slow = slow.next
      else:
        slow.next = fast.next
      fast = fast.next
    return dummy.next

head = ListNode(1)
head.next = ListNode(1)
head.next.next = ListNode(2)
head.next.next.next = ListNode(2)
s = Solution()
print(s.deleteDuplicates(head).val)

Leetcode/82. Remove Duplicates from Sorted List II.py


import os, sys, subprocess
from mpypack import cli as mpypack_cli

PYTHON_EXE = sys.executable
POPEN_BASE_ARGS = [PYTHON_EXE, "-m", "mpypack.cli"]

ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
# BUILD_SOURCE_DIR = os.path.join(ROOT_PATH, "mgui")
# BUILD_TARGET_DIR = os.path.join(ROOT_PATH, "dist", "mgui")
BOARD_TARGET_DIR = "/lib/mgui"

MPYPACK_CONFIG_FILE = os.path.join(ROOT_PATH, mpypack_cli.DEFAULT_CONFIG_FILE)
mpypack_cli.conf.read(MPYPACK_CONFIG_FILE)

def build():
    cmd = list(POPEN_BASE_ARGS)
    cmd.append('build')
    print('building...')
    subprocess.run(cmd)

def flash():
    fe = mpypack_cli.get_file_explorer()
    with fe:
        fe.mkdirs(mpypack_cli.get_config(mpypack_cli.CONFIG_OPTION_REMOTE, BOARD_TARGET_DIR))
    cmd = list(POPEN_BASE_ARGS)
    cmd.append('sync')
    print('flashing...')
    subprocess.run(cmd)

def test():
    flash()
    fe = mpypack_cli.get_file_explorer()
    with fe:
        with open('testmcu.py', 'rb') as f:
            fe.upload('/test.py', f.read())
    cmd = list(POPEN_BASE_ARGS)
    cmd.append('repl')
    print('[REPL MODE]')
    subprocess.run(cmd)

if __name__ == "__main__":
    build()
    if len(sys.argv) > 1:
        if sys.argv[1] == "flash":
            flash()
        if sys.argv[1] == "test":
            test()


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

#
#
#

# In[1]:

import pandas as pd
import numpy as np
import matplotlib.pylab as plt
import sklearn
from sklearn.datasets import load_boston
import ipywidgets as widgets
import numpy as np
from matplotlib import cm

# # Estructura de un problema general de machine learning:
# Los modelos de aprendizaje estadístico que pueden ser industriazados,   puede ser [esquematizado](https://proceedings.neurips.cc/paper/2015/file/86df7dcfd896fcaf2674f757a2463eba-Paper.pdf) según se muestra en la siguiente imagen:
#
# ![MLOPs](https://github.com/hernansalinas/Curso_aprendizaje_estadistico/blob/main/Sesiones/imagenes/Sesion_04_MLOP_General.png?raw=true)
#
#
# ![MLOPs](https://github.com/hernansalinas/Curso_aprendizaje_estadistico/blob/main/Sesiones/imagenes/Sesion_04_MLOPS.png?raw=true)
#
#
#
# A partir de ahora, nos concentraremos en entender los modelos de que ocurren dentro de la caja negra, y como encajan dentro de una estructura general de los modelos de machine learning ML.
#
# De forma general un modelo de [ML](https://www.coursera.org/learn/machine-learning)   puede ser visualizado de la siguiente manera :
#
# ![SupervisedModel](https://github.com/hernansalinas/Curso_aprendizaje_estadistico/blob/main/Sesiones/imagenes/Sesion_04_GeneralTraining.png?raw=true)
#
#
# [Machine Learning Engineering for Production (MLOps), Course 1](https://www.coursera.org/specializations/machine-learning-engineering-for-production-mlops)
#
#
#
# ## ¿Cual es el mejor enfoque para optimizar un problema?
#
# [Non-Free-Lunch-Theorem](https://ieeexplore.ieee.org/document/585893):
# Por cada par de algoritmos hay tantos problemas en el que el primer algoritmo es mejor que el segundo como problemas en el que el segundo es mejor que el primero, como consecuencia no existe un unico algoritmo inteligente para optimizar un problema, siempre es recomendable emplear un cierto conocimiento especifico de un problema.
#
#
#
# ##  Estructura general de los problemas ML:
# 1. Construir hipotesis.
# 2. Elegir parametros
# 3. Elegir la funcion de coste.
# 4. Minimizar los datos
# 5. Validar y entrenar.
#
#
#
# ## Aprendizaje Supervisado :
#
# - Datos etiquetados
# - Retroalimentación directa
# - Predicción de resultados.
#
#
#
#
#
#
#
#
#

# En general, el modelo puede ser optmizado como sigue:
#
# Dado un conjunto de caracteristicas $X_1, X_2,X_3, ...X_n$ podemos encontrar un valor $Y$, que puede ser optimado dado el siguiente modelo#
#
# $Y = f(X) + \epsilon$
#
#
#
#

# # Regresión lineal: Para un resumen del metodo ir al final de esta sesión. Resumen del metodo
#
# Supongamos que tenemos un sistema en el que existe un predicor con  **m** valores de entrenamiento,  asi:   $ (x^{(1)}, y^{(1)} ) , (x^{(2)}, y^{(2)}) ... (x^{(m)}, y^{(m)})$
#
#
# |Training|Y         | X_1      |
# |--------|----------|----------|
# |1       |$Y^{1}$   | $X_1^{1}$|
# |2       |$Y^{2}$   | $X_1^{2}$|
# |.       |.         | .        |
# |.|.         | .        |
# |.|.         | .        |
# |m|$Y^{m}$ | $X_1^{m}$  |
#
#
#
# Podemos definir un modelo lineal  como : $h(X) = \theta_0 + \theta_1 X$ con $(\theta_0 , \theta_1)$ parámetros. Nuestro objetivo es encontrar el conjunto de puntos  $(\theta_0 , \theta_1)$ que se encuentan más "cercano" a $Y$ para cada $X$.
#
# Para la optimización, vamos a definir la función de coste **$J(\theta_1,\theta_2 )$** para las muestras de entrenamiento como aquella que garantiza la distancia euclidiana respecto a la hipotesis planteada, así:
#
# \begin{equation}
# J(\theta_1, \theta_2)=\frac{1}{2m} \sum_{i=0}^m ( h_{\theta} (x^{(i)})-y^{(i)})^2
# \end{equation}
#
# Para encontrar los valores  $(\theta_0 , \theta_1)$ se necesita  minimizar la función de coste, que permite obtener los valores más cercanos,  esta minimización podrá ser realizada a través de diferentes metodos el más conocido es el gradiente descendente.
#
# ![](https://github.com/hernansalinas/Curso_aprendizaje_estadistico/blob/main/Sesiones/imagenes/fig00.png?raw=true=50x)
#
#
#

# ### Ejemplo :
# Supongamos que tenemos lo siguientes valores, asocaidas a un determinado sistema:
#
# |Entrenamiento|Y| X_1 |
# |-|-|-|
# |0|0|0|
# |1|1|1|
# |2|2|2|
# |3|3|3|
# |4|4|4|
# |m|5|5|
#
#

# In[2]:

x = np.linspace(0, 10)
y = np.linspace(0, 10)
names_cols = ["X1","Y"]

df = pd.DataFrame({"X1":x,"Y":y})
plt.figure()
plt.plot(df.X1,df.Y,"bo")
plt.xlabel("X",fontsize=14)
plt.ylabel("Y",fontsize=14)
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)
plt.show()

# Supongamos un modelo lineal para realizar la predicción, así nuestro modelo estará basado en la siguiente hipotesis de trabajo:
#
# $h(X) =\theta_0 + \theta_1 X$
#
#
# Reemplando el modelo anterior en la función de coste, tenemos que:
#
#
#
# \begin{equation}
# J(\theta_1, \theta_2)=\frac{1}{2m} \sum_{i=0}^m ( (\theta_0 + \theta_1 X)- y^{(i)})^2
# \end{equation}
#
#

# Definamos nuestro modelo y la función de coste:

# In[3]:

def H(X, θ0, θ1):
  """
  Parameter:
    theta_0 = input parameter
    theta_1 = input parameter
    X = Caracteristicas
  Return
    H value with model
  """
  return θ0 + θ1*X

def cost(X, Y, θ0, θ1):

    #m = len(Y)
    j = (H(X, θ0, θ1) - Y)**2
    J = j.mean()
    return J/(2)

# Para $\theta_0 = 0 $ y diferentes valores de $\theta_1  $, determinemos la funcion de coste y las rectas que modelan nuestro sistema, así, tenemos que:
#
#

# In[4]:

theta1 = np.linspace(-10, 12)
J = np.zeros(len(theta1))

for i,t1 in enumerate(theta1):
    J[i] = cost(df.X1.values, df.Y.values, 0, t1)
    i =i + 1

# In[5]:

@widgets.interact
def graph_values(theta_eval = np.array([-10, -5, -1, 0, 1, 5, 10])):
    plt.figure(figsize=(14, 6))
    plt.subplot(121)
    plt.plot(df.X1,df.Y,"bo")
    plt.plot(df.X1, H(df.X1, 0, theta_eval )  ,"r-", label = f"θ0 = 0, θ1 = {theta_eval}")
    plt.xticks(fontsize = 14)
    plt.yticks(fontsize = 14)
    plt.xlim( 0, 10)
    plt.ylim(-10, 10)
    plt.xlabel("X", fontsize=14)
    plt.ylabel("Y", fontsize=14)
    plt.legend()

    plt.subplot(122)
    plt.plot(theta1, J)
    plt.plot(theta_eval, cost(df.X1, df.Y,0, theta_eval), "or",label = f"θ0 = 0, θ1 = {theta_eval}")
    plt.xlabel("$\\theta_1$", fontsize=14)
    plt.ylabel("$J(\\theta_0 = 0, \\theta_1)$", fontsize=14)
    plt.xticks(fontsize = 14)
    plt.yticks(fontsize = 14)
    plt.xlim( -10, 12)
    plt.ylim( 0 , 2000)
    plt.legend()
    plt.show()

# In[6]:

# Construir la superficie para theta0, theta_1

# In[7]:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import numpy as np

# In[8]:

# Construyendo el grid()
N1 = 100
N2 = 100
theta0 = np.linspace(-0.5, 0.5, N1)
theta1 = np.linspace(-2.0, 3.0, N2)
t0, t1 = np.meshgrid(theta0, theta1) #Empleando un meshgrid

J = np.zeros((N1, N2)) #Evaluando los valores de la funcion de coste para el meshgrid considerado
for i,t_0 in enumerate(theta0):
  for j,t_1 in enumerate(theta1):
    J[i,j] = cost( df.X1, df.Y, t_0, t_1)
#J=J/np.max(J)

# In[9]:

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(t0, t1, J,  rstride=1, cstride=1, alpha=0.5)
ax.contour(t0, t1, J, 20, lw=3, cmap="autumn_r", linestyles="solid", offset=-1)
ax.contour(t0, t1, J, 20, lw=3, colors="k", linestyles="solid")
ax.set_xlabel("$\\theta_0$")
ax.set_ylabel("$\\theta_1$")
ax.set_zlabel("J")
#ax.set_zlim(0, 30)
plt.show()

# # Otra forma de verlo

# In[10]:

X = np.linspace(0, 1, 100)
y = 0.2 + 0.2*X + 0.02*np.random.random(100)

# Datos sinteticos para entender mejor la regresion lineal

# In[11]:

plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
#plt.ylim(100, 1000)
#plt.xlim(0, 3000)
plt.show()

# \begin{equation}
# h(X) =\theta_0 + \theta_1 X
# \end{equation}
#
# \begin{equation}
# J(\theta_1, \theta_2)=\frac{1}{2m} \sum_{i=0}^m ( (\theta_0 + \theta_1 X)- y^{(i)})^2
# \end{equation}
#

# In[12]:

@widgets.interact
def graph_values(theta_eval = np.linspace(0, 0.5, 10)):
  plt.figure(figsize=(14, 6))
  plt.subplot(121)
  plt.plot(X,y,"bo")
  plt.plot(X, H(X, 0.2, theta_eval )  ,"r-", label = f"θ0 = 200, θ1 = {theta_eval}")
  plt.xticks(fontsize = 14)
  plt.yticks(fontsize = 14)
  #plt.xlim( 0, 10)
  #plt.ylim(-10, 10)
  plt.xlabel("X", fontsize=14)
  plt.ylabel("Y", fontsize=14)
  plt.legend()

# In[13]:

# Construyendo el grid()
N1 = 400
N2 = 400
theta0 = np.linspace(-1, 1, N1)  #Intercepto
theta1 = np.linspace(-0.8, 0.8, N2)   #pendiente
t0, t1 = np.meshgrid(theta0, theta1) #Empleando un meshgrid

J = np.zeros((N1, N2)) #Evaluando los valores de la funcion de coste para el meshgrid considerado

for i,t_0 in enumerate(theta0):
  for j,t_1 in enumerate(theta1):
    J[i,j] = cost( X, y, t_0, t_1)

# In[14]:

fig = plt.figure()
ax = fig.add_subplot(211, projection="3d")
ax.plot_surface(t0,t1,J,  rstride=1, cstride=1)
#ax.contour(t0, t1, J, 50,   linestyles="solid")
ax.set_xlabel("$\\theta_0$")
ax.set_ylabel("$\\theta_1$")
ax.set_zlabel("J")
#ax.set_zlim(0, 30)
plt.show()

# In[15]:

fig = plt.figure()
ax = fig.add_subplot(111)
ax.contour(t0, t1,J, 200,   linestyles="solid")
ax.set_xlabel("$\\theta_0$")
ax.set_ylabel("$\\theta_1$")
#ax.set_xlim(-0,700)
#ax.set_ylim(-0.6,0.6)
plt.show()

# En sintesis, lo que se busca es el minimo de la hypersuperficie asociada a la función de coste. Veamoslo con una superficie diferente:
#
#

# In[16]:

x1=np.linspace(-10,10,100 )
X1,X2 = np.meshgrid(x1,x1)
Y = X1**2 + X2**2

fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(X1, X2, Y,  cmap="autumn_r",rstride=1, cstride=1, alpha=0.5)
ax.contour(X1, X2, Y, 20, lw=3,  linestyles="solid", offset=-1)
#ax.contour(t0, t1, J, 20, lw=3, colors="k", linestyles="solid")
ax.set_xlabel("$\\theta_0$")
ax.set_ylabel("$\\theta_1$")
ax.set_zlabel("J")
#ax.set_zlim(0, 30)
plt.show()

# # Gradiente Descendente

# Sea $f(\omega) = (\omega-1)^2$ , con $\omega \in \mathbb{R} $. El minimo de esta función esta determinado por#
# \begin{equation}
# \frac{\mathrm{d}f}{\mathrm{d}\omega} = 0
# \end{equation}
#
# \begin{equation}
# \omega = 1
# \end{equation}
#
#
# Para determinar el minimo,  a través del gradiente descendente puede ser aplicada el siguiente algoritmo:
# 1. Proponer un número aleatorios inicial $\omega_i$
# 2. Para descender al mínimo de la función, encontremos un  valor para el cual
# el deriva de la función descenciende, asi:
# \begin{equation}
# \omega_{i+1} = \omega_{i} - \alpha \frac{\mathrm{d}f(\omega_i)}{\mathrm{d}\omega}
# \end{equation}
#
# donde, $\alpha$ es conocido como la tasa de aprendizaje del algoritmo.
#
# 3. Evaluar $f(\omega_{i+1})$
#
# 4. Iterar hasta encontrar el minimo de la función
#
#
# En el caso de la funcion propuesta, asumiendo un valor de $\alpha=1$, tenemos que:
#
# 1. Supongamos que $\omega_{0} = 2$, luego :
# 2. $\omega_{0+1} = 2 - 1 f'(\omega_{0}) =  = 0$
# 3. $f(0) = 1$
# 4. $\omega_{1+1} = 0 - 1 f'(\omega_{1}) = 0-1(2(0-1)) =  2$
#
# El valor del $\omega$  despues de un par de iteraciones, no es el esperado, por que no minimiza la función, se debe proponer un tasa de aprendizaje  **$\alpha$** de tal forma que permita descender suavemente para encontrar el minimo.
#

# In[17]:

f = lambda omega: (omega**2 - 1)
fp = lambda omega: 2*(omega - 1)

def gradD(omega_,alpha, fp):
  """
  Gradiente descendente
  """
  return omega_ - alpha*fp(omega_)

# In[18]:

# Determinacion del gradiente descendente
omegai = 2
alpha = 0.7
OM = []
def gradient_iteration(alpha, omegai):
  OM = []
  for i in range(0,20):
    omega = gradD(omegai, alpha , fp)
    omegai = omega
    OM.append(omegai)
    if( abs(fp(omegai))< 1E-4):
      print(f"El valor minimo es {omegai:.4f} despues de {i} iteraciones")
      break
#    print(f"omega = {omegai:.4f}\t f(omega) = {f(omegai):.4f}\t fp(omega) = {f(omegai):.4f}")

  return OM

# In[19]:

@widgets.interact
def graph_descent(OM = gradient_iteration(alpha = 0.1, omegai = 2)):
  omega = np.linspace(-10, 10, 100)
  fig = plt.figure(figsize=(10,4))
  ax = fig.add_subplot(121)
  ax.plot(omega, f(omega))
  ax.plot(OM, f(OM),"ro-", label=f" fp(omega)={f(OM):.4f}")
  plt.legend()

#
# Cuando se tiene más dimensiones, el gradiente descendente puede ser escrito como sigue:  Sea $ J(\theta_1, \theta_2) $ una función continua, nuestro objetivo es encontrar el mínimo de la función, a través del gradiente descendente, sea $\vec{\Theta} = (\theta_0, \theta_1)$
#
#
# \begin{equation}
# \Delta \vec{\Theta} =  - \alpha \nabla J(\theta_0, \theta_1)
# \end{equation}
#
# en componentes:
#
# \begin{equation}
# \Delta \theta_{0} =  - \alpha \frac{\partial J}{\partial \theta_0}
# \end{equation}
#
# \begin{equation}
# \Delta \theta_{1} =  - \alpha \frac{\partial J}{\partial \theta_1}
# \end{equation}
#
#
# La componente j-esima será:
# \begin{equation}
# \theta_{j} := \theta_{j} - \alpha \frac{\partial J}{\partial \theta_j}
# \end{equation}
#
#
#
#
#

# ¿Cómo puede encontrar el minimo el gradiente descente en 2D?. Intuición gráfica
#

# In[20]:

#Ref=https://stackoverflow.com/questions/35445424/surface-and-3d-contour-in-matplotlib
#Change the color
#Ref:https://matplotlib.org/stable/tutorials/colors/colormaps.html

X, Y = np.mgrid[-1:1:30j, -1:1:30j]
Z = np.sin(np.pi*X) * np.sin(np.pi*(Y))

fig = plt.figure(figsize=(14, 6))
ax = fig.add_subplot(121, projection="3d")
c=ax.plot_surface(X, Y, Z, cmap=cm.viridis)
ax.contour(X, Y, Z, 20, lw=3, cmap=cm.viridis, linestyles="solid", offset=-1)
#fig.colorbar(c)
#ax.contour(X, Y, Z, 10, lw=3, cmap=cm.coolwarm, colors="k", linestyles="solid")

ax2 = fig.add_subplot(122)
ax2.contour(X, Y, Z, 30, lw = 3, linestyles="-", offset=-1)
c=ax2.contourf(X, Y, Z, 30, lw=3,c="white")
fig.colorbar(c,)

#ax2.contour(X, Y, Z, 10, lw=3, colors="k", linestyles="solid")
plt.show()

# Tarea 4.1
# [Ejemplo guia: dotcsv](https://www.youtube.com/watch?v=-_A_AAxqzCg)
#
# Encontrar el minimo de la siguiente función a través del metodo del gradiente descendente https://en.wikipedia.org/wiki/Gradient_descent:
#
# \begin{equation}
# F(x,y) = \sin \left( \frac{1}{2}x^2-\frac{1}{4}y^2 +3\right) \cos (2x+1-e^y)
# \end{equation}
#
# 1. Para ello realice una gráfica de la función en 3D, y un mapa de contourno de la función.
# 2. Determine el valor mínimo de la funcion con el metodo del gradiente descendente.
#

# In[21]:

x=np.linspace(-1.5, 2.0, 200)
y=np.linspace(-1.5, 2.0, 200)
X, Y=np.meshgrid(x, y)
F = lambda x, y: (np.sin(0.5*x**2-0.25*y**2+3))*(np.cos(2*x+1-np.exp(y)))
Z = F(X,Y)

# In[22]:

fig = plt.figure(figsize=(14, 6))
ax = fig.add_subplot(121, projection="3d")
ax.plot_surface(X, Y, Z, cmap=cm.viridis, rstride=1, cstride=1, alpha=1)
ax.contour(X, Y, Z, 40, lw=3, cmap=cm.viridis, linestyles="solid", offset=-1)
ax.set_xlabel("$\\theta_0$")
ax.set_ylabel("$\\theta_1$")
ax.set_zlabel("J")
#ax.set_zlim(0, 30)

ax2 = fig.add_subplot(122)
ax2.contour(X, Y, Z, 30, lw=3, cmap=cm.viridis, linestyles="solid", offset=-1)
c=ax2.contourf(X, Y, Z, 30, lw=3,cmap=cm.viridis)
fig.colorbar(c,)

plt.show()

# # Gradiente descendente para la función de coste
#
# Proponiendo un modelo lineal, tenemos que:
# \begin{equation}
# h(X) = (\theta_0 + \theta_1 X)
# \end{equation}
#
#
#
# \begin{equation}
# J(\theta_1, \theta_2)=\frac{1}{2m} \sum_{i=1}^m ( h_{\theta} (X^{(i)})-y^{(i)})^2
# \end{equation}
#
# Asumiento una metrica  euclidiana, tenemos que:
#
# \begin{equation}
# J(\theta_1, \theta_2)=\frac{1}{2m} \sum_{i=1}^m ( (\theta_0 + \theta_1 X)- y^{(i)})^2
# \end{equation}
#
# Las derivadas de la funcion de cote vienen dadas por :
#
# \begin{equation}
# \frac{\partial J}{\partial \theta_0} = \frac{1}{m}\sum_{i=1}^{m}(h(X^{(i)})-y^{(i)})
# \end{equation}
#
# \begin{equation}
# \frac{\partial J}{\partial \theta_1} = \frac{1}{m}\sum_{i=1}^{m}(h(X^{(i)})-y^{(i)})X^{(i)}
# \end{equation}
#
#
# El gradiente descente viene dado por :
#
# \begin{equation}
# \theta_0 := \theta_0 - \alpha \frac{\partial J}{\partial \theta_0}
# \end{equation}
#
# \begin{equation}
# \theta_1 := \theta_1 - \alpha \frac{\partial J}{\partial \theta_1}
# \end{equation}
#
#

# # Modelo de *machine learning*: Solución general
#
# Un modelo general para solucionar un problema de machining learning puede ser estructurado como sigue:
#
#
# 1. Eliger el modelo a emplear:
# \begin{equation}
# h(X,\Theta)
# \end{equation}
#
# - En el caso de una regresion lineal tenemos que $h(X,\Theta=(\theta_0, \theta_1))$:
#
#     \begin{equation}
#     h(X) = (\theta_0 + \theta_1 X)
#     \end{equation}
#
#
# 2. Eligir la funcion de coste :
# -  Metrica Ecuclidiana:
# \begin{equation}
# J(\Theta)=\frac{1}{2m} \sum_{i=1}^m ( h_{\theta} (X^{(i)})-y^{(i)})^2
# \end{equation}
# - [Lista de funciones de coste que pueden ser empleadas](https://jmlb.github.io/flashcards/2018/04/21/list_cost_functions_fo_neuralnets/)
#
#
# 3. Aplicar el gradiente descendente iterativamente, hasta encontrar el minimo:
#
# \begin{equation}
# \Delta \vec{\Theta} =  - \alpha \nabla J(\Theta)
# \end{equation}
#
#
#
# - En el caso de una regresion lineal tenemos que $h(X,\Theta=(\theta_0, \theta_1))$:
#
#
# \begin{equation}
# \theta_0 := \theta_0 - \alpha \frac{\partial J}{\partial \theta_0}
# \end{equation}
#
# \begin{equation}
# \theta_1 := \theta_1 - \alpha \frac{\partial J}{\partial \theta_1}
# \end{equation}

# # Tarea 4.2:
#
# De igual forma que con los sistemas metricos, la funcion de coste puede ser generalizada para otro tipo de metricas, de forma análoga a lo que ocurre con la distancia entre dos puntos. Sabemos que la metrica euclidiana puede ser escrita como:
#
# \begin{equation}
# d = \left[ \sum_{i=1}^{D}  (x_i-x_i')^2 \right]^{1/2}  (1)
# \end{equation}
#
# donde D es la dimension del espacio, así :
#
# - Para una dimensión tenemos que D = 1:
#
# \begin{equation}
# d = |x_i-x_i'|
# \end{equation}
#
# - Para una dimensión tenemos que D = 2:
# \begin{equation}
# d = \left[ (x_1-x_1')^2 + (x_2-x_2')^2 \right]^{1/2}
# \end{equation}
#
# - Para una dimensión tenemos que D = 3:
# \begin{equation}
# d = \left[ (x_1-x_1')^2 + (x_2-x_2')^2 + (x_3-x_3')^2 \right]^{1/2}
# \end{equation}
#
#
# La metrica anterior puede ser generalizada como sigue,
#
# \begin{equation}
# d = \left[ \sum_{i=1}^{D}  (x_i-x_i')^p \right]^{1/p}
# \end{equation}
#
# Para n=2 tenemos que la metrica  de la ecuación (1).
#
#
#
# Análogo a lo anterior, la funcion de coste puede emplear cualquiera de las metricas descritas dependiendo de la dimension o caracteristicas asociadas al sistema de estudio, para datos de una sola caracteristica la función de coste puede ser escrita como sigue:
#
# \begin{equation}
# J(\theta_1, \theta_2)=\frac{1}{pm} \sum_{i=1}^m ( h_{\theta} (X^{(i)})-y^{(i)})^p
# \end{equation}
#
#
#
#
#
# Empleando los siguientes datos determine:
#
# ```
# X = np.linspace(0, 1, 100)
# y = 0.2 + 0.2*X + 0.02*np.random.random(100)
# ```
#
# Determine los valores mínimos de $\theta_0$, $\theta_1$ para los siguientes casos:
#
#
#  1. Emplea la metrica ecuclidiana con p = 2 compare su resultado con los valores empleando la libreria sklearn:[Linear Regresion](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html)
#
#  2. Emple p = 1, p = 3. ¿Como varian los resultaodos en este caso?
#  3. Construya las curvas de aprendizaje  para función del número  de datos para las situaciones descritas, ¿qué peude concluir?


#  get_toy_owner
# Your mission

# Create a route that returns the owner of a given toy.

# The route will be of the form /toys/xxx/owner.
# The route will return the message "I don't know who my owner is\n".

# And, again, if the parameter is the string "unknown",
# the route will return a 404 error.

# $> curl "http://127.0.0.1:5000/toys/actionman/owner"
# I don't know who my owner is
# $> curl "http://127.0.0.1:5000/toys/unknown/owner"
# <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
# <title>404 Not Found</title>
#
Not Found

#
The requested URL was not found on the server.
# If you entered the URL manually please check your spelling and try again.

# $> curl "http://127.0.0.1:5000/toys/doll/owner"
# I don't know who my owner is
# $>

from flask import Flask, abort

app = Flask(__name__)

# Flask decorator above a function:
# -> basic route

@app.route("/toys/<toy_id>/owner")
def index_2(toy_id):
    if toy_id == "unknown":
        abort(404)
    else:
        return "I don't know who my owner is\n"

app.run(debug=True)