import math
import ROOT
from ROOT import gStyle, gROOT, TStyle

def looks_atlas():

    atlasStyle = TStyle("ATLAS","Atlas style");
    icol=0
    atlasStyle.SetFrameBorderMode(icol)
    atlasStyle.SetFrameFillColor(icol)
    atlasStyle.SetCanvasBorderMode(icol)
    atlasStyle.SetCanvasColor(icol)
    atlasStyle.SetPadBorderMode(icol)
    atlasStyle.SetPadColor(icol)
    atlasStyle.SetStatColor(icol)
    atlasStyle.SetPaperSize(20,26)

    atlasStyle.SetPadTopMargin(0.05)
    atlasStyle.SetPadRightMargin(0.05)
    atlasStyle.SetPadBottomMargin(0.16)
    atlasStyle.SetPadLeftMargin(0.16)

    atlasStyle.SetTitleXOffset(1.4)
    atlasStyle.SetTitleYOffset(1.4)

    font=42
    tsize=0.05
    atlasStyle.SetTextFont(font)

    atlasStyle.SetTextSize(tsize)
    atlasStyle.SetLabelFont(font,'x')
    atlasStyle.SetTitleFont(font,'x')
    atlasStyle.SetLabelFont(font,'y')
    atlasStyle.SetTitleFont(font,'y')
    atlasStyle.SetLabelFont(font,'z')
    atlasStyle.SetTitleFont(font,'z')

    atlasStyle.SetLabelSize(tsize,'x')
    atlasStyle.SetTitleSize(tsize,'x')
    atlasStyle.SetLabelSize(tsize,'y')
    atlasStyle.SetTitleSize(tsize,'y')
    atlasStyle.SetLabelSize(tsize,'z')
    atlasStyle.SetTitleSize(tsize,'z')

    atlasStyle.SetMarkerStyle(20)
    atlasStyle.SetMarkerSize(1.2)
    atlasStyle.SetHistLineWidth(2)
    atlasStyle.SetLineStyleString(2,'[12 12]')

    atlasStyle.SetEndErrorSize(0.)

    atlasStyle.SetOptTitle(0)
    atlasStyle.SetOptStat(0)
    atlasStyle.SetOptFit(0)

    atlasStyle.SetPadTickX(1)
    atlasStyle.SetPadTickY(1)

    atlasStyle.cd()
    gROOT.ForceStyle()

class plot_props:
    def __init__(self,nbins,xmin,xmax):
        self.nbins   = nbins
        self.xmin    = xmin
        self.xmax    = xmax
        self.binsize = (float(xmax) - float(xmin))/float(nbins)

def hist_formatting(chist,ptype):
    chist.SetLineWidth(0)
    chist.SetMarkerStyle(8)
    chist.SetMarkerSize(1)
    chist.GetXaxis().SetLabelOffset(99)
    chist.GetXaxis().SetTitleOffset(99)
    chist.GetYaxis().SetTitleOffset(.9)
    chist.GetYaxis().SetTitleSize(.065)
    chist.GetYaxis().SetLabelSize(.0625)

    if ptype == 'data':
        chist.SetLineWidth(1)
        chist.SetMaximum(chist.GetMaximum()*1.275)

def hist_ratio_formatting(hist):
    hist.SetMarkerStyle(8)
    hist.SetMarkerSize(1)
    hist.SetLineWidth(1)
    hist.SetLineColor(1)
    hist.GetYaxis().SetNdivisions(5)
    hist.GetXaxis().SetLabelSize(0.12)
    hist.GetXaxis().SetTitleSize(0.13)
    hist.GetYaxis().SetLabelSize(0.12)
    hist.GetYaxis().SetTitleSize(0.13)
    hist.GetXaxis().SetTitleOffset(1.4)
    hist.GetYaxis().SetTitleOffset(.45)
    hist.GetYaxis().CenterTitle()
    hist.SetMinimum(0)

def format_legend(legend):
    legend.SetTextFont(42)
    legend.SetTextSize(0.0575)
    legend.SetFillStyle(0)
    legend.SetBorderSize(0)

def pad_margining(pad1,pad2):
    pad1.SetBottomMargin(0.03)
    pad2.SetTopMargin(0.045)
    #pad1.SetLeftMargin(.1)
    #pad2.SetLeftMargin(.1)
    pad1.SetRightMargin(.025)
    pad2.SetRightMargin(.025)
    pad2.SetBottomMargin(0.475)
    pad2.SetFrameFillColor(0)
    pad2.SetFrameBorderMode(0)

legend = ROOT.TLegend(.815,.55,1.025,.92)
format_legend(legend)
leg_data = ROOT.TH1D('leg_data','leg_data',100,1,0)
leg_data.SetLineColorAlpha(ROOT.kBlack,1)
leg_data.SetMarkerStyle(8)
leg_zjets = ROOT.TH1D('leg_zjets','leg_zjets',100,1,0)
leg_zjets.SetLineWidth(2)
leg_zjets.SetLineColorAlpha(ROOT.kBlack,1)
leg_zjets.SetFillColorAlpha(0,1)
leg_diboson = ROOT.TH1D('leg_diboson','leg_diboson',100,1,0)
leg_diboson.SetLineWidth(0)
leg_diboson.SetFillColorAlpha(ROOT.kAzure+2,.7)
leg_diboson.SetLineColorAlpha(ROOT.kAzure+2,.7)
leg_ttbar = ROOT.TH1D('leg_ttbar','leg_ttbar',100,1,0)
leg_ttbar.SetLineWidth(0)
leg_ttbar.SetFillColorAlpha(ROOT.kGreen-2,.7)
leg_ttbar.SetLineColorAlpha(ROOT.kGreen-2,.7)
leg_ttbarV = ROOT.TH1D('leg_ttbarV','leg_ttbarV',100,1,0)
leg_ttbarV.SetLineWidth(0)
leg_ttbarV.SetFillColorAlpha(ROOT.kOrange+1,.7)
leg_ttbarV.SetLineColorAlpha(ROOT.kOrange+1,.7)

legend.AddEntry(leg_data,   'Data',      'p')
legend.AddEntry(leg_zjets,  'Z+jets',    'f')
legend.AddEntry(leg_diboson,'WZ/ZZ',     'f')
legend.AddEntry(leg_ttbar,  't#bar{t}',  'f')
legend.AddEntry(leg_ttbarV, 't#bar{t}V', 'f')

atlaslabel = ROOT.TLatex()
atlaslabel.SetNDC()
atlaslabel.SetTextFont(72)
atlaslabel.SetTextSize(0.065)
atlaslabelText = ROOT.TLatex()
atlaslabelText.SetNDC()
atlaslabelText.SetTextFont(42)
atlaslabelText.SetTextSize(0.065)

line_at_one = ROOT.TF1('line_at_one','1',-1e5,1e5)
line_at_one.SetLineColorAlpha(1,1)
line_at_one.SetLineStyle(7)
line_at_one.SetLineWidth(1)


#----Constantes----#
PREGUNTA_PESO = "cuanto pesas en kg? : "
PREGUNTA_ESTATURA = "cuanto mides en metros? : "
MENSAJE_BIENVENIDA = "Hola como estas? Voy a calcular tu IMC"
MENSAJE_DESPEDIDA = "Tu IMC es ..."
MENSAJE_BAJO_PESO = "Estás pero delgado!!"
MENSAJE_NORMAL = "Estás en forma "
MENSAJE_SOBRE_PESO = "Ten cuidado,estás en sobre peso "
MENSAJE_OBESO = "Cuidado,estás obeso. Tu salud corre riesgo"
#----Entrada código----#
print (MENSAJE_BIENVENIDA)
peso = float (input(PREGUNTA_PESO))
estatura = float (input(PREGUNTA_ESTATURA))
imc = peso/(estatura**2)
isBajoPeso = imc < 18.5
isNormal = imc >= 18.5 and imc < 25
isSobrePeso = imc >= 25 and imc < 30
resultado = ""
if (isBajoPeso) :
    resultado = MENSAJE_BAJO_PESO
elif (isNormal) :
    resultado = MENSAJE_NORMAL
elif (isSobrePeso) :
    resultado = MENSAJE_SOBRE_PESO
else :
    resultado = MENSAJE_OBESO

print (MENSAJE_DESPEDIDA, imc)
print (resultado)


import requests
import json
from data_source.car_schema import car_schema
from bs4 import BeautifulSoup
import pprint
import copy

def get_listings(zipcode=30307, distance=200, max_mileage=100000, max_price=20000, min_year=2014):

    zipcode = str(zipcode)
    distance = str(distance)
    url = "https://www.cargurus.com/Cars/inventorylisting/ajaxFetchSubsetInventoryListing.action"

    payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"zip\"\r\n\r\n"+zipcode+"\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"distance\"\r\n\r\n"+distance+"\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"selectedEntity\"\r\n\r\nd380\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"page\"\r\n\r\n1\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"

    headers = {
        'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
        'cache-control': "no-cache",
    }

    response = requests.request("POST", url, data=payload, headers=headers)

    response = json.loads(response.content)

    listings = response['listings']

    listings = filter_listings(listings, max_mileage, max_price, min_year)
    listings = normalize(listings)

    return listings

def get_phone(listing_id):
    print(f'Getting phone for listing {listing_id}')
    url = "https://www.cargurus.com/Cars/inventorylisting/viewListingDetailAjax.action"
    querystring = {"inventoryListing": listing_id}

    response = requests.request("GET", url, params=querystring)

    details = BeautifulSoup(response.content, 'html.parser')
    phone = details.find(id='dealerPhoneNumber').text
    phone = ''.join(filter(lambda x: x.isdigit(), phone))
    print(f'Got phone number {phone}')
    return phone

def filter_listings(listings, max_mileage=100000, max_price=20000, min_year=2014):
    try:
        listings = [listing for listing in listings if int(listing['carYear']) >= min_year]
        listings = [listing for listing in listings if int(listing['price']) <= max_price]
        listings = [listing for listing in listings if int(listing['price']) > 0]
        listings = [listing for listing in listings if int(listing['mileage']) <= max_mileage]
        listings = [listing for listing in listings if int(listing['mileage']) > 0]
    except KeyError:
        print("KeyError")
    return listings

def normalize(listings):
    for listing in listings:
        try:
            listing['listings'] = dict(car_gurus=copy.deepcopy(listing))
            listing['links'] = dict(car_gurus=f'https://www.cargurus.com/Cars/inventorylisting/viewListingDetailAjax.action?inventoryListing={listing["id"]}')
            listing['year'] = int(listing['carYear'])
            listing['mileage'] = int(listing['mileage'])
            listing['vin'] = listing['vehicleIdentifier']
            listing['damage'] = bool(listing['hasAccidents'] or listing['frameDamaged'])
            listing['owners'] = listing['ownerCount']
        except KeyError as a:
            print(str(KeyError) + str(a))

        for key in list(listing):
            if key not in car_schema:
                del listing[key]

    return listings

def get_phone_for_car(listing):
        listing['phone'] = get_phone(listing['listings']['car_gurus']['id'])
        return listing

if __name__ == "__main__":
    pprint.pprint(get_listings()[0])


from threading import Thread,Lock
import time
num = 0
mutexFlag=mutex.acquire(True)
def work1():
	global num
	for i in range(1000):
		mutex.acquire(True)
		num += 1
		mutex.replease()
	print("线程一%d"%num)
def work2():
	global num
	for i in range(1000):
		mutex.acquire(True)
		num += 1
		mutex.replease()
	print("线程二%d"%num)
t = Thread(target=work1)
t.start()

#延时一会，保证t1线程中的事情做完
time.sleep(1)
t1 = Thread(target=work2)
t1.start()


import torch
import torch.nn as nn
import torch.nn.functional as F

class ConvNet(nn.Module):

	def __init__(self,output_size):
		super(ConvNet,self).__init__()
		self.conv1 = nn.Conv2d(1,6,5)
		self.conv2 = nn.Conv2d(6,16,5)
		self.fc1 = nn.Linear(16*4*4,120)
		self.fc2 = nn.Linear(120,84)
		self.fc3 = nn.Linear(84,output_size)

	def forward(self,input_):
		x = F.relu(self.conv1(input_))
		x = F.max_pool2d(x,(2,2))
		x = F.relu(self.conv2(x))
		x = F.max_pool2d(x,2)
		x = x.view(-1,1,self.getfeaturesize(x))
		x = F.relu(self.fc1(x))
		x = F.relu(self.fc2(x))
		x = F.relu(self.fc3(x))
		o = F.log_softmax(x,dim=2)
		return o
	def getfeaturesize(self,x):
		size = x.size()[1:]
		features = 1
		for s in size:
			features *= s
		return features
class NeuralNet(nn.Module):

	def __init__(self,input_size,output_size):
		super(NeuralNet,self).__init__()
		self.l1 = nn.Linear(input_size,128)
		self.l2 = nn.Linear(128,64)
		self.l3 = nn.Linear(64,32)
		self.l4 = nn.Linear(32,output_size)

	def forward(self,input_):
		x = torch.tanh(self.l1(input_))
		x = torch.relu(self.l2(x))
		x = torch.tanh(self.l3(x))
		x = torch.relu(self.l4(x))
		out = F.log_softmax(x,dim=2)
		return out


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

# # * Prerequisites

# In this assignment you will implement the Naive Bayes Classifier. Before starting this assignment, make sure you understand the concepts discussed in the videos in Week 2 about Naive Bayes. You can also find it useful to read Chapter 1 of the textbook.
#
#
# Also, make sure that you are familiar with the `numpy.ndarray` class of python's `numpy` library and that you are able to answer the following questions:
#
# Let's assume `a` is a numpy array.
# * What is an array's shape (e.g., what is the meaning of `a.shape`)?
# * What is numpy's reshaping operation? How much computational over-head would it induce?
# * What is numpy's transpose operation, and how it is different from reshaping? Does it cause computation overhead?
# * What is the meaning of the commands `a.reshape(-1, 1)` and `a.reshape(-1)`?
# * Would happens to the variable `a` after we call `b = a.reshape(-1)`? Does any of the attributes of `a` change?
# * How do assignments in python and numpy work in general?
#     * Does the `b=a` statement use copying by value? Or is it copying by reference?
#     * Would the answer to the previous question change depending on whether `a` is a numpy array or a scalar value?
#
# You can answer all of these questions by
#
#     1. Reading numpy's documentation from https://numpy.org/doc/stable/.
#     2. Making trials using dummy variables.

# # *Assignment Summary

# The UC Irvine machine learning data repository hosts a famous dataset, the Pima Indians dataset, on whether a patient has diabetes originally owned by the National Institute of Diabetes and Digestive and Kidney Diseases and donated by Vincent Sigillito. You can find it at  https://www.kaggle.com/uciml/pima-indians-diabetes-database/data. This data has a set of attributes of patients, and a categorical variable telling whether the patient is diabetic or not. For several attributes in this data set, a value of 0 may indicate a missing value of the variable. It has a total of 768 data-points.
#
# * **Part 1-A)** First, you will build a simple naive Bayes classifier to classify this data set. We will use 20% of the data for evaluation and the other 80% for training.
#
#   You should use a normal distribution to model each of the class-conditional distributions.
#
#   Report the accuracy of the classifier on the 20% evaluation data, where accuracy is the number of correct predictions as a fraction of total predictions.
#
# * **Part 1-B)** Next, you will adjust your code so that, for attributes 3 (Diastolic blood pressure), 4 (Triceps skin fold thickness), 6 (Body mass index), and 8 (Age), it regards a value of 0 as a missing value when estimating the class-conditional distributions, and the posterior.
#
#   Report the accuracy of the classifier on the 20% that was held out for evaluation.
#
# * **Part 1-C)** Last, you will have some experience with SVMLight, an off-the-shelf implementation of Support Vector Machines or SVMs. For now, you don't need to understand much about SVM's, we will explore them in more depth in the following exercises. You will install SVMLight, which you can find at http://svmlight.joachims.org, to train and evaluate an SVM to classify this data.
#
#   You should NOT substitute NA values for zeros for attributes 3, 4, 6, and 8.
#
#   Report the accuracy of the classifier on the held out 20%

# # 0. Data

# ## 0.1 Description

# The UC Irvine's Machine Learning Data Repository Department hosts a Kaggle Competition with famous collection of data on whether a patient has diabetes (the Pima Indians dataset), originally owned by the National Institute of Diabetes and Digestive and Kidney Diseases and donated by Vincent Sigillito.
#
# You can find this data at https://www.kaggle.com/uciml/pima-indians-diabetes-database/data. The Kaggle website offers valuable visualizations of the original data dimensions in its dashboard. It is quite insightful to take the time and make sense of the data using their dashboard before applying any method to the data.

# ## 0.2 Information Summary

# * **Input/Output**: This data has a set of attributes of patients, and a categorical variable telling whether the patient is diabetic or not.
#
# * **Missing Data**: For several attributes in this data set, a value of 0 may indicate a missing value of the variable.
#
# * **Final Goal**: We want to build a classifier that can predict whether a patient has diabetes or not. To do this, we will train multiple kinds of models, and will be handing the missing data with different approaches for each method (i.e., some methods will ignore their existence, while others may do something about the missing data).

# ## 0.3 Loading

# In[1]:

get_ipython().run_line_magic('matplotlib', 'inline')
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from aml_utils import test_case_checker

# In[2]:

df = pd.read_csv('../BasicClassification-lib/diabetes.csv')
df.head()

# ## 0.1 Splitting The Data

# First, we will shuffle the data completely, and forget about the order in the original csv file.
#
# * The training and evaluation dataframes will be named ```train_df``` and ```eval_df```, respectively.
#
# * We will also create the 2-d numpy array `train_features` whose number of rows is the number of training samples, and the number of columns is 8 (i.e., the number of features). We will define `eval_features` in a similar fashion
#
# * We would also create the 1-d numpy arrays `train_labels` and `eval_labels` which contain the training and evaluation labels, respectively.

# In[3]:

# Let's generate the split ourselves.
np_random = np.random.RandomState(seed=12345)
rand_unifs = np_random.uniform(0,1,size=df.shape[0])
division_thresh = np.percentile(rand_unifs, 80)
train_indicator = rand_unifs < division_thresh
eval_indicator = rand_unifs >= division_thresh

# In[4]:

train_df = df[train_indicator].reset_index(drop=True)
train_features = train_df.loc[:, train_df.columns != 'Outcome'].values
train_labels = train_df['Outcome'].values
train_df.head()

# In[5]:

eval_df = df[eval_indicator].reset_index(drop=True)
eval_features = eval_df.loc[:, eval_df.columns != 'Outcome'].values
eval_labels = eval_df['Outcome'].values
eval_df.head()

# In[6]:

train_features.shape, train_labels.shape, eval_features.shape, eval_labels.shape

# ## 0.2 Pre-processing The Data

# Some of the columns exhibit missing values. We will use a Naive Bayes Classifier later that will treat such missing values in a special way.  To be specific, for attribute 3 (Diastolic blood pressure), attribute 4 (Triceps skin fold thickness), attribute 6 (Body mass index), and attribute 8 (Age), we should regard a value of 0 as a missing value.
#
# Therefore, we will be creating the `train_featues_with_nans` and `eval_features_with_nans` numpy arrays to be just like their `train_features` and `eval_features` counter-parts, but with the zero-values in such columns replaced with nans.

# In[7]:

train_df_with_nans = train_df.copy(deep=True)
eval_df_with_nans = eval_df.copy(deep=True)
for col_with_nans in ['BloodPressure', 'SkinThickness', 'BMI', 'Age']:
    train_df_with_nans[col_with_nans] = train_df_with_nans[col_with_nans].replace(0, np.nan)
    eval_df_with_nans[col_with_nans] = eval_df_with_nans[col_with_nans].replace(0, np.nan)
train_features_with_nans = train_df_with_nans.loc[:, train_df_with_nans.columns != 'Outcome'].values
eval_features_with_nans = eval_df_with_nans.loc[:, eval_df_with_nans.columns != 'Outcome'].values

# In[8]:

print('Here are the training rows with at least one missing values.')
print('')
print('You can see that such incomplete data points constitute a substantial part of the data.')
print('')
nan_training_data = train_df_with_nans[train_df_with_nans.isna().any(axis=1)]
nan_training_data

# # 1. Part 1 (Building a simple Naive Bayes Classifier)

# Consider a single sample $(\mathbf{x}, y)$, where the feature vector is denoted with $\mathbf{x}$, and the label is denoted with $y$. We will also denote the $j^{th}$ feature of $\mathbf{x}$ with $x^{(j)}$.
#
# According to the textbook, the Naive Bayes Classifier uses the following decision rule:
#
# "Choose $y$ such that $$\bigg[\log p(y) + \sum_{j} \log p(x^{(j)}|y) \bigg]$$ is the largest"
#
# However, we first need to define the probabilistic models of the prior $p(y)$ and the class-conditional feature distributions $p(x^{(j)}|y)$ using the training data.
#
# * **Modelling the prior $p(y)$**: We fit a Bernoulli distribution to the `Outcome` variable of `train_df`.
# * **Modelling the class-conditional feature distributions $p(x^{(j)}|y)$**: We fit Gaussian distributions, and infer the Gaussian mean and variance parameters from `train_df`.

# # Task 1

# Write a function `log_prior` that takes a numpy array `train_labels` as input, and outputs the following vector as a column numpy array (i.e., with shape $(2,1)$).
#
# $$\log p_y =\begin{bmatrix}\log p(y=0)\\\log p(y=1)\end{bmatrix}$$
#
# Try and avoid the utilization of loops as much as possible. No loops are necessary.
#
# **Hint**: Make sure all the array shapes are what you need and expect. You can reshape any numpy array without any tangible computational over-head.

# In[9]:

def log_prior(train_labels):

    # your code here
    # raise NotImplementedError
    num_of_one = np.sum(train_labels)
    num_of_zero = np.shape(train_labels)[0] - num_of_one

    log_py = np.array([np.log(num_of_zero/np.shape(train_labels)[0]), np.log(num_of_one/np.shape(train_labels)[0])]).reshape(2, 1)

    assert log_py.shape == (2,1)

    return log_py

# In[10]:

# Performing sanity checks on your implementation
some_labels = np.array([0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1])
some_log_py = log_prior(some_labels)
assert np.array_equal(some_log_py.round(3), np.array([[-0.916], [-0.511]]))

# Checking against the pre-computed test database
test_results = test_case_checker(log_prior, task_id=1)
assert test_results['passed'], test_results['message']

# In[11]:

# This cell is left empty as a seperator. You can leave this cell as it is, and you should not delete it.

# In[12]:

log_py = log_prior(train_labels)
log_py

# # Task 2

# Write a function `cc_mean_ignore_missing` that takes the numpy arrays `train_features` and `train_labels` as input, and outputs the following matrix with the shape $(8,2)$, where 8 is the number of features.
#
# $$\mu_y = \begin{bmatrix} \mathbb{E}[x^{(0)}|y=0] & \mathbb{E}[x^{(0)}|y=1]\\
# \mathbb{E}[x^{(1)}|y=0] & \mathbb{E}[x^{(1)}|y=1] \\
# \cdots & \cdots\\
# \mathbb{E}[x^{(7)}|y=0] & \mathbb{E}[x^{(7)}|y=1]\end{bmatrix}$$
#
# Some points regarding this task:
#
# * The `train_features` numpy array has a shape of `(N,8)` where `N` is the number of training data points, and 8 is the number of the features.
#
# * The `train_labels` numpy array has a shape of `(N,)`.
#
# * **You can assume that `train_features` has no missing elements in this task**.
#
# * Try and avoid the utilization of loops as much as possible. No loops are necessary.

# In[16]:

def cc_mean_ignore_missing(train_features, train_labels):
    N, d = train_features.shape
    allZeros = np.where(train_labels == 0)[0]
    allOnes = np.where(train_labels == 1)[0]

    df_features = pd.DataFrame(train_features)

    dfZeros = df_features.loc[allZeros]
    dfOnes = df_features.loc[allOnes]

    firstCol = dfZeros.mean(axis=0).to_numpy().reshape((d, 1))
    secondCol = dfOnes.mean(axis=0).to_numpy().reshape((d, 1))

    mu_y = np.concatenate((firstCol, secondCol), axis=1)
    # your code here
    # raise NotImplementedError

    assert mu_y.shape == (d, 2)
    return mu_y

# In[17]:

# Performing sanity checks on your implementation
some_feats = np.array([[  1. ,  85. ,  66. ,  29. ,   0. ,  26.6,   0.4,  31. ],
                       [  8. , 183. ,  64. ,   0. ,   0. ,  23.3,   0.7,  32. ],
                       [  1. ,  89. ,  66. ,  23. ,  94. ,  28.1,   0.2,  21. ],
                       [  0. , 137. ,  40. ,  35. , 168. ,  43.1,   2.3,  33. ],
                       [  5. , 116. ,  74. ,   0. ,   0. ,  25.6,   0.2,  30. ]])
some_labels = np.array([0, 1, 0, 1, 0])

some_mu_y = cc_mean_ignore_missing(some_feats, some_labels)

assert np.array_equal(some_mu_y.round(2), np.array([[  2.33,   4.  ],
                                                    [ 96.67, 160.  ],
                                                    [ 68.67,  52.  ],
                                                    [ 17.33,  17.5 ],
                                                    [ 31.33,  84.  ],
                                                    [ 26.77,  33.2 ],
                                                    [  0.27,   1.5 ],
                                                    [ 27.33,  32.5 ]]))

# Checking against the pre-computed test database
test_results = test_case_checker(cc_mean_ignore_missing, task_id=2)
assert test_results['passed'], test_results['message']

# In[18]:

# This cell is left empty as a seperator. You can leave this cell as it is, and you should not delete it.

# In[19]:

mu_y = cc_mean_ignore_missing(train_features, train_labels)
mu_y

# # Task 3

# Write a function `cc_std_ignore_missing` that takes the numpy arrays `train_features` and `train_labels` as input, and outputs the following matrix with the shape $(8,2)$, where 8 is the number of features.
#
# $$\sigma_y = \begin{bmatrix} \text{std}[x^{(0)}|y=0] & \text{std}[x^{(0)}|y=1]\\
# \text{std}[x^{(1)}|y=0] & \text{std}[x^{(1)}|y=1] \\
# \cdots & \cdots\\
# \text{std}[x^{(7)}|y=0] & \text{std}[x^{(7)}|y=1]\end{bmatrix}$$
#
# Some points regarding this task:
#
# * The `train_features` numpy array has a shape of `(N,8)` where `N` is the number of training data points, and 8 is the number of the features.
#
# * The `train_labels` numpy array has a shape of `(N,)`.
#
# * **You can assume that `train_features` has no missing elements in this task**.
#
# * Try and avoid the utilization of loops as much as possible. No loops are necessary.

# In[20]:

def cc_std_ignore_missing(train_features, train_labels):
    N, d = train_features.shape

    allZeros = np.where(train_labels == 0)[0]
    allOnes = np.where(train_labels == 1)[0]

    df_features = pd.DataFrame(train_features)

    dfZeros = df_features.loc[allZeros]
    dfOnes = df_features.loc[allOnes]

    firstCol = dfZeros.std(axis=0, ddof=0).to_numpy().reshape((d, 1))
    secondCol = dfOnes.std(axis=0, ddof=0).to_numpy().reshape((d, 1))

    sigma_y = np.concatenate((firstCol, secondCol), axis=1)

    # your code here
    # raise NotImplementedError

    assert sigma_y.shape == (d, 2)

    return sigma_y

# In[21]:

# Performing sanity checks on your implementation
some_feats = np.array([[  1. ,  85. ,  66. ,  29. ,   0. ,  26.6,   0.4,  31. ],
                       [  8. , 183. ,  64. ,   0. ,   0. ,  23.3,   0.7,  32. ],
                       [  1. ,  89. ,  66. ,  23. ,  94. ,  28.1,   0.2,  21. ],
                       [  0. , 137. ,  40. ,  35. , 168. ,  43.1,   2.3,  33. ],
                       [  5. , 116. ,  74. ,   0. ,   0. ,  25.6,   0.2,  30. ]])
some_labels = np.array([0, 1, 0, 1, 0])

some_std_y = cc_std_ignore_missing(some_feats, some_labels)

assert np.array_equal(some_std_y.round(3), np.array([[ 1.886,  4.   ],
                                                     [13.768, 23.   ],
                                                     [ 3.771, 12.   ],
                                                     [12.499, 17.5  ],
                                                     [44.312, 84.   ],
                                                     [ 1.027,  9.9  ],
                                                     [ 0.094,  0.8  ],
                                                     [ 4.497,  0.5  ]]))

# Checking against the pre-computed test database
test_results = test_case_checker(cc_std_ignore_missing, task_id=3)
assert test_results['passed'], test_results['message']

# In[22]:

# This cell is left empty as a seperator. You can leave this cell as it is, and you should not delete it.

# In[23]:

sigma_y = cc_std_ignore_missing(train_features, train_labels)
sigma_y

# # Task 4

# Write a function `log_prob` that takes the numpy arrays `train_features`, $\mu_y$, $\sigma_y$, and  $\log p_y$ as input, and outputs the following matrix with the shape $(N, 2)$
#
# $$\log p_{x,y} = \begin{bmatrix} \bigg[\log p(y=0) + \sum_{j=0}^{7} \log p(x_1^{(j)}|y=0) \bigg] & \bigg[\log p(y=1) + \sum_{j=0}^{7} \log p(x_1^{(j)}|y=1) \bigg] \\
# \bigg[\log p(y=0) + \sum_{j=0}^{7} \log p(x_2^{(j)}|y=0) \bigg] & \bigg[\log p(y=1) + \sum_{j=0}^{7} \log p(x_2^{(j)}|y=1) \bigg] \\
# \cdots & \cdots \\
# \bigg[\log p(y=0) + \sum_{j=0}^{7} \log p(x_N^{(j)}|y=0) \bigg] & \bigg[\log p(y=1) + \sum_{j=0}^{7} \log p(x_N^{(j)}|y=1) \bigg] \\
# \end{bmatrix}$$
#
# where
# * $N$ is the number of training data points.
# * $x_i$ is the $i^{th}$ training data point.
#
# Try and avoid the utilization of loops as much as possible. No loops are necessary.

# **Hint**: Remember that we are modelling $p(x_i^{(j)}|y)$ with a Gaussian whose parameters are defined inside $\mu_y$ and $\sigma_y$. Write the Gaussian PDF expression and take its natural log **on paper**, then implement it.
#
# **Important Note**: Do not use third-party and non-standard implementations for computing $\log p(x_i^{(j)}|y)$. Using functions that find the Gaussian PDF, and then taking their log is **numerically unstable**; the Gaussian PDF values can easily become extremely small numbers that cannot be represented using floating point standards and thus would be stored as zero. Taking the log of a zero value will throw an error. On the other hand, it is unnecessary to compute and store $p(x_i^{(j)}|y)$ in order to find $\log p(x_i^{(j)}|y)$; you can write $\log p(x_i^{(j)}|y)$ as a direct function of $\mu_y$, $\sigma_y$ and the features. This latter approach is numerically stable, and can be applied when the PDF values are much smaller than could be stored using the common standards.

# In[24]:

def log_prob(train_features, mu_y, sigma_y, log_py):
    N, d = train_features.shape
    mu0 = mu_y[:, 0]
    sigma0 = sigma_y[:, 0]

    mu1 = mu_y[:, 1]
    sigma1 = sigma_y[:, 1]

    firstCol = np.sum(np.log(1/(sigma0.reshape(1, d)*np.sqrt(2*np.pi)))-(1/2)*((train_features-mu0.reshape(1, d))/sigma0.reshape(1, d))**2, axis=1)+log_py[0]
    secondCol = np.sum(np.log(1/(sigma1.reshape(1, d)*np.sqrt(2*np.pi)))-(1/2)*((train_features-mu1.reshape(1, d))/sigma1.reshape(1, d))**2, axis=1)+log_py[1]

    log_p_x_y = np.concatenate((firstCol.reshape(N, 1), secondCol.reshape(N,1)), axis=1)
    # your code here
    # raise NotImplementedError

    assert log_p_x_y.shape == (N,2)
    return log_p_x_y

# In[25]:

# Performing sanity checks on your implementation
some_feats = np.array([[  1. ,  85. ,  66. ,  29. ,   0. ,  26.6,   0.4,  31. ],
                       [  8. , 183. ,  64. ,   0. ,   0. ,  23.3,   0.7,  32. ],
                       [  1. ,  89. ,  66. ,  23. ,  94. ,  28.1,   0.2,  21. ],
                       [  0. , 137. ,  40. ,  35. , 168. ,  43.1,   2.3,  33. ],
                       [  5. , 116. ,  74. ,   0. ,   0. ,  25.6,   0.2,  30. ]])
some_labels = np.array([0, 1, 0, 1, 0])

some_mu_y = cc_mean_ignore_missing(some_feats, some_labels)
some_std_y = cc_std_ignore_missing(some_feats, some_labels)
some_log_py = log_prior(some_labels)

some_log_p_x_y = log_prob(some_feats, some_mu_y, some_std_y, some_log_py)

assert np.array_equal(some_log_p_x_y.round(3), np.array([[ -20.822,  -36.606],
                                                         [ -60.879,  -27.944],
                                                         [ -21.774, -295.68 ],
                                                         [-417.359,  -27.944],
                                                         [ -23.2  ,  -42.6  ]]))

# Checking against the pre-computed test database
test_results = test_case_checker(log_prob, task_id=4)
assert test_results['passed'], test_results['message']

# In[26]:

# This cell is left empty as a seperator. You can leave this cell as it is, and you should not delete it.

# In[27]:

log_p_x_y = log_prob(train_features, mu_y, sigma_y, log_py)
log_p_x_y

# ## 1.1. Writing the Simple Naive Bayes Classifier

# In[28]:

class NBClassifier():
    def __init__(self, train_features, train_labels):
        self.train_features = train_features
        self.train_labels = train_labels
        self.log_py = log_prior(train_labels)
        self.mu_y = self.get_cc_means()
        self.sigma_y = self.get_cc_std()

    def get_cc_means(self):
        mu_y = cc_mean_ignore_missing(self.train_features, self.train_labels)
        return mu_y

    def get_cc_std(self):
        sigma_y = cc_std_ignore_missing(self.train_features, self.train_labels)
        return sigma_y

    def predict(self, features):
        log_p_x_y = log_prob(features, self.mu_y, self.sigma_y, self.log_py)
        return log_p_x_y.argmax(axis=1)

# In[29]:

diabetes_classifier = NBClassifier(train_features, train_labels)
train_pred = diabetes_classifier.predict(train_features)
eval_pred = diabetes_classifier.predict(eval_features)

# In[30]:

train_acc = (train_pred==train_labels).mean()
eval_acc = (eval_pred==eval_labels).mean()
print(f'The training data accuracy of your trained model is {train_acc}')
print(f'The evaluation data accuracy of your trained model is {eval_acc}')

# ## 1.2 Running an off-the-shelf implementation of Naive-Bayes For Comparison

# In[31]:

from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB().fit(train_features, train_labels)
train_pred_sk = gnb.predict(train_features)
eval_pred_sk = gnb.predict(eval_features)
print(f'The training data accuracy of your trained model is {(train_pred_sk == train_labels).mean()}')
print(f'The evaluation data accuracy of your trained model is {(eval_pred_sk == eval_labels).mean()}')

# # Part 2 (Building a Naive Bayes Classifier Considering Missing Entries)

# In this part, we will modify some of the parameter inference functions of the Naive Bayes classifier to make it able to ignore the NaN entries when inferring the Gaussian mean and stds.

# # Task 5

# Write a function `cc_mean_consider_missing` that
# * has exactly the same input and output types as the `cc_mean_ignore_missing` function,
# * and has similar functionality to `cc_mean_ignore_missing` except that it can handle and ignore the NaN entries when computing the class conditional means.
#
# You can borrow most of the code from your `cc_mean_ignore_missing` implementation, but you should make it compatible with the existence of NaN values in the features.
#
# Try and avoid the utilization of loops as much as possible. No loops are necessary.

# * **Hint**: You may find the `np.nanmean` function useful.

# In[32]:

def cc_mean_consider_missing(train_features_with_nans, train_labels):
    N, d = train_features_with_nans.shape
    allZeros = np.where(train_labels == 0)[0]
    allOnes = np.where(train_labels == 1)[0]

    # Convert the 2-d numpy array to DataFrame
    df_features = pd.DataFrame(train_features_with_nans)

    dfZeros = df_features.loc[allZeros]
    dfOnes = df_features.loc[allOnes]

    firstCol = np.nanmean(dfZeros, axis=0).reshape((d, 1))
    secondCol = np.nanmean(dfOnes, axis=0).reshape((d, 1))

    mu_y = np.concatenate((firstCol, secondCol), axis=1)
    # your code here
    #raise NotImplementedError

    assert not np.isnan(mu_y).any()
    assert mu_y.shape == (d, 2)
    return mu_y

# In[33]:

# Performing sanity checks on your implementation
some_feats = np.array([[  1. ,  85. ,  66. ,  29. ,   0. ,  26.6,   0.4,  31. ],
                       [  8. , 183. ,  64. ,   0. ,   0. ,  23.3,   0.7,  32. ],
                       [  1. ,  89. ,  66. ,  23. ,  94. ,  28.1,   0.2,  21. ],
                       [  0. , 137. ,  40. ,  35. , 168. ,  43.1,   2.3,  33. ],
                       [  5. , 116. ,  74. ,   0. ,   0. ,  25.6,   0.2,  30. ]])
some_labels = np.array([0, 1, 0, 1, 0])

for i,j in [(0,0), (1,1), (2,3), (3,4), (4, 2)]:
    some_feats[i,j] = np.nan

some_mu_y = cc_mean_consider_missing(some_feats, some_labels)

assert np.array_equal(some_mu_y.round(2), np.array([[  3.  ,   4.  ],
                                                    [ 96.67, 137.  ],
                                                    [ 66.  ,  52.  ],
                                                    [ 14.5 ,  17.5 ],
                                                    [ 31.33,   0.  ],
                                                    [ 26.77,  33.2 ],
                                                    [  0.27,   1.5 ],
                                                    [ 27.33,  32.5 ]]))

# Checking against the pre-computed test database
test_results = test_case_checker(cc_mean_consider_missing, task_id=5)
assert test_results['passed'], test_results['message']

# In[34]:

# This cell is left empty as a seperator. You can leave this cell as it is, and you should not delete it.

# In[35]:

mu_y = cc_mean_consider_missing(train_features_with_nans, train_labels)
mu_y

# # Task 6

# Write a function `cc_std_consider_missing` that
# * has exactly the same input and output types as the `cc_std_ignore_missing` function,
# * and has similar functionality to `cc_std_ignore_missing` except that it can handle and ignore the NaN entries when computing the class conditional means.
#
# You can borrow most of the code from your `cc_std_ignore_missing` implementation, but you should make it compatible with the existence of NaN values in the features.
#
# Try and avoid the utilization of loops as much as possible. No loops are necessary.

# * **Hint**: You may find the `np.nanstd` function useful.

# In[36]:

def cc_std_consider_missing(train_features_with_nans, train_labels):
    N, d = train_features_with_nans.shape
    allZeros = np.where(train_labels == 0)[0]
    allOnes = np.where(train_labels == 1)[0]

    # Convert the 2-d numpy array to DataFrame
    df_features = pd.DataFrame(train_features_with_nans)

    dfZeros = df_features.loc[allZeros]
    dfOnes = df_features.loc[allOnes]

    firstCol = np.nanstd(dfZeros, axis=0, ddof=0).reshape((d, 1))
    secondCol = np.nanstd(dfOnes, axis=0, ddof=0).reshape((d, 1))

    sigma_y = np.concatenate((firstCol, secondCol), axis=1)
    # your code here
    #raise NotImplementedError

    assert not np.isnan(sigma_y).any()
    assert sigma_y.shape == (d, 2)
    return sigma_y

# In[37]:

# Performing sanity checks on your implementation
some_feats = np.array([[  1. ,  85. ,  66. ,  29. ,   0. ,  26.6,   0.4,  31. ],
                       [  8. , 183. ,  64. ,   0. ,   0. ,  23.3,   0.7,  32. ],
                       [  1. ,  89. ,  66. ,  23. ,  94. ,  28.1,   0.2,  21. ],
                       [  0. , 137. ,  40. ,  35. , 168. ,  43.1,   2.3,  33. ],
                       [  5. , 116. ,  74. ,   0. ,   0. ,  25.6,   0.2,  30. ]])
some_labels = np.array([0, 1, 0, 1, 0])

for i,j in [(0,0), (1,1), (2,3), (3,4), (4, 2)]:
    some_feats[i,j] = np.nan

some_std_y = cc_std_consider_missing(some_feats, some_labels)

assert np.array_equal(some_std_y.round(2), np.array([[ 2.  ,  4.  ],
                                                     [13.77,  0.  ],
                                                     [ 0.  , 12.  ],
                                                     [14.5 , 17.5 ],
                                                     [44.31,  0.  ],
                                                     [ 1.03,  9.9 ],
                                                     [ 0.09,  0.8 ],
                                                     [ 4.5 ,  0.5 ]]))

# Checking against the pre-computed test database
test_results = test_case_checker(cc_std_consider_missing, task_id=6)
assert test_results['passed'], test_results['message']

# In[38]:

# This cell is left empty as a seperator. You can leave this cell as it is, and you should not delete it.

# In[39]:

sigma_y = cc_std_consider_missing(train_features_with_nans, train_labels)
sigma_y

# ## 2.1. Writing the Naive Bayes Classifier With Missing Data Handling

# In[40]:

class NBClassifierWithMissing(NBClassifier):
    def get_cc_means(self):
        mu_y = cc_mean_consider_missing(self.train_features, self.train_labels)
        return mu_y

    def get_cc_std(self):
        sigma_y = cc_std_consider_missing(self.train_features, self.train_labels)
        return sigma_y

    def predict(self, features):
        preds = []
        for feature in features:
            is_num = np.logical_not(np.isnan(feature))
            mu_y_not_nan = self.mu_y[is_num,:]
            std_y_not_nan = self.sigma_y[is_num,:]
            feats_not_nan = feature[is_num].reshape(1,-1)
            log_p_x_y = log_prob(feats_not_nan, mu_y_not_nan, std_y_not_nan, self.log_py)
            preds.append(log_p_x_y.argmax(axis=1).item())

        return np.array(preds)

# In[41]:

diabetes_classifier_nans = NBClassifierWithMissing(train_features_with_nans, train_labels)
train_pred = diabetes_classifier_nans.predict(train_features_with_nans)
eval_pred = diabetes_classifier_nans.predict(eval_features_with_nans)

# In[42]:

train_acc = (train_pred==train_labels).mean()
eval_acc = (eval_pred==eval_labels).mean()
print(f'The training data accuracy of your trained model is {train_acc}')
print(f'The evaluation data accuracy of your trained model is {eval_acc}')

# # 3. Running SVMlight

# In this section, we are going to investigate the support vector machine classification method. We will become familiar with this classification method in week 3. However, in this section, we are just going to observe how this method performs to set the stage for the third week.
#
# `SVMlight` (http://svmlight.joachims.org/) is a famous implementation of the SVM classifier.
#
# `SVMLight` can be called from a shell terminal, and there is no nice wrapper for it in python3. Therefore:
# 1. We have to export the training data to a special format called `svmlight/libsvm`. This can be done using scikit-learn.
# 2. We have to run the `svm_learn` program to learn the model and then store it.
# 3. We have to import the model back to python.

# ## 3.1 Exporting the training data to libsvm format

# In[43]:

from sklearn.datasets import dump_svmlight_file
dump_svmlight_file(train_features, 2*train_labels-1, 'training_feats.data',
                   zero_based=False, comment=None, query_id=None, multilabel=False)

# ## 3.2 Training `SVMlight`

# In[44]:

get_ipython().system('chmod +x ../BasicClassification-lib/svmlight/svm_learn')
from subprocess import Popen, PIPE
process = Popen(["../BasicClassification-lib/svmlight/svm_learn", "./training_feats.data", "svm_model.txt"], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
print(stdout.decode("utf-8"))

# ## 3.3 Importing the SVM Model

# In[45]:

from svm2weight import get_svmlight_weights
svm_weights, thresh = get_svmlight_weights('svm_model.txt', printOutput=False)

def svmlight_classifier(train_features):
    return (train_features @ svm_weights - thresh).reshape(-1) >= 0.

# In[46]:

train_pred = svmlight_classifier(train_features)
eval_pred = svmlight_classifier(eval_features)

# In[47]:

train_acc = (train_pred==train_labels).mean()
eval_acc = (eval_pred==eval_labels).mean()
print(f'The training data accuracy of your trained model is {train_acc}')
print(f'The evaluation data accuracy of your trained model is {eval_acc}')

# In[48]:

# Cleaning up after our work is done
get_ipython().system('rm -rf svm_model.txt training_feats.data')

# In[ ]:

# In[ ]:


import logging

from ops.charm import CharmBase
from ops.main import main
from ops.model import ActiveStatus, MaintenanceStatus

from charms.data_platform_libs.v0.s3 import CredentialRequestedEvent, S3Provider

logger = logging.getLogger(__name__)

class S3Charm(CharmBase):
    """S3 charm that accepts connections from application charms."""

    def __init__(self, *args):
        super().__init__(*args)

        # Default charm events.
        self.framework.observe(self.on.start, self._on_start)

        # Charm events defined in the s3 provides charm library.
        self.s3_provider = S3Provider(self, relation_name="s3-credentials")
        self.framework.observe(
            self.s3_provider.on.credentials_requested, self._on_credential_requested
        )

    def _on_start(self, _) -> None:
        """Only sets an waiting status."""
        # self.unit.status = WaitingStatus("Waiting for relation")
        self.unit.status = ActiveStatus("HERE")

    def _on_credential_requested(self, event: CredentialRequestedEvent):
        self.unit.status = MaintenanceStatus("Creating credentials")
        # retrieve bucket name from the requirer side
        bucket = event.bucket

        relation_id = event.relation.id

        connection_info = {
            "access-key": "test-access-key",
            "secret-key": "test-secret-key",
            "bucket": f"{bucket}",
            "path": "/path/",
            "endpoint": "s3.amazonaws.com",
            "region": "us",
            "s3-uri-style": "",
            "storage-class": "cinder",
            "tls-ca-chain": [],
            "s3-api-version": "1.0",
            "attributes": ["a1", "a2", "a3"],
        }
        # set connection info in the databag relation
        self.s3_provider.update_connection_info(relation_id, connection_info)

        self.unit.status = ActiveStatus()

if __name__ == "__main__":
    main(S3Charm)


import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt
import math

np.random.seed(3)

# Constants
learning_rate = 0.0001
num_iters = 4000
bias = False

# Calculate the sigmoid / logistic function
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 0-1 accuracy model
def accuracy(y_true, y_pred):
    accuracy = np.sum(y_true == y_pred) / len(y_true)
    return accuracy

# Dataset generation
#   p: number of features
#   m: norm of the parameter vector
#   theta: parameter vector for generation
#   n: number of samples in training set
#   t: number of samples in testing set
#   Generate an n x p array of floats from 0 to 1, and dot with theta to find z
#   Probabilities result from applying sigmoid to the z array
p = 100
m = 30
theta = np.random.random(size=(p, 1)) * 4 - 2
theta = theta * m / np.linalg.norm(theta)

print(f'Norm of parameter vector: {np.linalg.norm(theta)}')
n = 25000
t = 500
X = np.random.rand(n+t, p)
z = np.dot(X, theta)
prob = sigmoid(z)

# Generate labels by sampling from Bernoulli(prob)
y = np.random.binomial(1, prob.flatten())

# Generate labels deterministically
## y = np.where(prob.flatten() >= 0.5, 1, 0)

# Split data into training and testing data
xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=t/(n+t), random_state=0)

# Train the model
iter_list = []
rms_list = []

# plot as n increases the RMSE
for iter in range(100, 25000, 100):
    regressor = LogisticRegression()
    regressor.fit(xtrain[:iter], ytrain[:iter])
    print(f'Trained weights with n={iter} has norm {np.linalg.norm(regressor.coef_)} with accuracy {accuracy(ytest, regressor.predict(xtest))}')

    ## Formula 1
    MSE = np.linalg.norm(np.subtract(theta,regressor.coef_.T)) / np.linalg.norm(theta)

    ## Formula 2
    # MSE = np.linalg.norm(np.subtract(theta / np.linalg.norm(theta),regressor.coef_.T / np.linalg.norm(regressor.coef_.T)))

    RMSE = MSE / math.sqrt(p)
    print(f'RMSE: {RMSE}')

    iter_list.append(iter)
    rms_list.append(RMSE)

plt.plot(iter_list, rms_list)
plt.xlabel("Number of iteration")
plt.ylabel("RMSE")
plt.show()


import locale
from bs4 import BeautifulSoup
from requests import Response
import polars as pl
from datetime import datetime, date, time, timedelta
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
import numpy as np
import streamlit as st
from time import sleep
import streamlit as st

MONTH_MAPPING = {
    "Ene": "01",
    "Feb": "02",
    "Mar": "03",
    "Abr": "04",
    "May": "05",
    "Jun": "06",
    "Jul": "07",
    "Ago": "08",
    "Sep": "09",
    "Oct": "10",
    "Nov": "11",
    "Dic": "12",
}
INTERNAL_DATE_STR_FORMAT = "%d/%m/%Y"
INTERNAL_TIME_STR_FORMAT = "%H:%M:%S"

CONTRARIES = {"N": "S", "S": "N", "E": "O", "O": "E"}

# def get_wind_status(wind_direction, wave_direction):
#     if is_offshore(wind_direction, wave_direction):
#         return "Offshore"
#     elif is_crossoff(wind_direction, wave_direction):
#         return "Cross-off"
#     else:
#         return "Onshore"

# margen de 20 grados en N,S,E,O
def angle_to_direction(angle):
    angle %= 360
    if 0 <= angle < 10 or angle >= 350:
        return "North"
    elif 10 <= angle < 80:
        return "NorthEast"
    elif 80 <= angle < 100:
        return "East"
    elif 100 <= angle < 170:
        return "SouthEast"
    elif 170 <= angle < 190:
        return "South"
    elif 190 <= angle < 260:
        return "SouthWest"
    elif 260 <= angle < 280:
        return "West"
    elif 280 <= angle < 350:
        return "NorthWest"

    # if 0 <= angle < 22.5 or angle >= 337.5:
    #     return "North"
    # elif 22.5 <= angle < 67.5:
    #     return "NorthEast"
    # elif 67.5 <= angle < 112.5:
    #     return "East"
    # elif 112.5 <= angle < 157.5:
    #     return "SouthEast"
    # elif 157.5 <= angle < 202.5:
    #     return "South"
    # elif 202.5 <= angle < 247.5:
    #     return "SouthWest"
    # elif 247.5 <= angle < 292.5:
    #     return "West"
    # elif 292.5 <= angle < 337.5:
    #     return "NorthWest"

def is_offshore(wind_direction, wave_direction):
    offshore_mapping = {
        "N": "S",
        "E": "O",
        "NO": "SE",
        "SO": "NE",
        "ONO": "ESE",
        "ONE": "ENO",
        "ONS": "E",
        "OES": "",
        "ESE": "",
        "ESS": "",
        "NOO": "",
        "NOE": "",
        "NOS": "",
        "NEO": "",
        "NEE": "",
        "NES": "",
        "SOO": "",
        "SOE": "",
        "SON": "",
        "SEO": "",
        "SEE": "",
        "SEN": "",
        "OON": "",
        "OOE": "",
        "OOS": "",
        "OEN": "",
        "OEE": "",
        "OES": "",
    }

    return wind_direction == offshore_mapping.get(wave_direction, [])

def is_crossoff(wind_direction, wave_direction):
    cross_offshore_mapping = {
        "N": ["SE", "SO"],
        "S": ["NE", "NO"],
        "E": ["NO", "SO"],
        "O": ["NE", "SE"],
        "NE": ["SE", "NO", "S", "O"],
        "NO": ["SO", "NE", "S", "E"],
        "SE": ["SO", "NE", "N", "O"],
        "SO": ["NO", "SE", "N", "E"],
    }
    return wind_direction in cross_offshore_mapping.get(wave_direction, [])

def export_to_html(filename, response: Response):
    soup = BeautifulSoup(response.text, "html.parser")
    with open(filename, "w") as file:
        file.write(soup.prettify())

def import_html(filename):
    with open(filename, "r") as file:
        return file.read()

def combine_df(df1, df2):
    # df = pl.concat([df1, df2], axis=0, ignore_index=True)
    df = pl.concat([df1, df2])
    return df

def convert_datestr_format(datestr):
    # Define the mapping of month names to their numeric representations

    day = int(datestr.split(" ")[-1].strip())
    month_name = datestr.split(" ")[-2].strip()
    month = MONTH_MAPPING[month_name]
    current_year = datetime.now().year

    date_obj = datetime(current_year, int(month), day)

    return date_obj.strftime("%d/%m/%Y")

def open_browser():
    my_user_agent = (
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
    )

    options = webdriver.ChromeOptions()
    options.add_argument("--lang=es")
    options.add_argument("--headless")
    options.add_argument(f"--user-agent={my_user_agent}")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--disable-gpu")
    # options.add_argument("--disable-features=NetworkService")
    options.add_argument("--window-size=1920x1080")
    # options.add_argument("--disable-features=VizDisplayCompositor")
    options.page_load_strategy = "eager"
    browser = webdriver.Chrome(options=options)
    return browser

def render_html(url, tag_to_wait=None, timeout=10):
    try:
        browser = open_browser()
        browser.get(url)
        if tag_to_wait:
            element = WebDriverWait(browser, timeout).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, tag_to_wait))
            )
            assert element
        html_content = browser.page_source
        return html_content
    except Exception as e:
        raise e
    finally:
        browser.close()
        browser.quit()

def rename_key(dictionary, old_key, new_key):
    if old_key in dictionary:
        dictionary[new_key] = dictionary.pop(old_key)

    return dictionary

def handle_wind(df: pl.DataFrame) -> pl.DataFrame:
    wind_speed = df["wind_speed"].cast(pl.Float32)

    WIND_STATUS_HIGH_10 = (df["wind_status"] == "Offshore") | (
        df["wind_status"] == "Cross-off"
    )

    WIND_STATUS_LESS_10 = (df["wind_status"] != "Offshore") & (
        df["wind_status"] != "Cross-off"
    )
    WIND_SPEED_LESS_10 = wind_speed <= 10

    wind_ok = (WIND_STATUS_LESS_10 & WIND_SPEED_LESS_10) | (WIND_STATUS_HIGH_10)

    default = "Viento No Favorable"

    df = df.with_columns(
        pl.when(wind_ok)
        .then("Viento Favorable")
        .otherwise(default)
        .alias("wind_approval")
    )
    return df

def get_date_name_column(df: pl.DataFrame) -> pl.DataFrame:
    today = datetime.now().date()
    tomorrow = today + timedelta(days=1)
    day_after_tomorrow = today + timedelta(days=2)
    yesterday = today - timedelta(days=1)

    df = df.with_columns(
        pl.when((df["datetime"].dt.date()) == today)
        .then("Hoy")
        .when((df["datetime"].dt.date()) == tomorrow)
        .then("Mañana")
        .when((df["datetime"].dt.date()) == day_after_tomorrow)
        .then("Pasado")
        .when((df["datetime"].dt.date()) == yesterday)
        .then("Ayer")
        .otherwise("Otro día")
        .alias("date_name")
    )

    return df

def get_day_name(days_to_add: float) -> str:
    today = date.today()
    day = today + timedelta(days=days_to_add)
    day_name_number = day.strftime("%m-%d, %A")

    return day_name_number

def final_forecast_format(df: pl.DataFrame):
    if not df.is_empty():
        df.sort(by=["datetime", "spot_name"], descending=[False, False])
        datetimes = df["datetime"].cast(pl.Time)
        _6_AM = time(hour=6, minute=0, second=0, microsecond=0)
        _19_PM = time(hour=19, minute=0, second=0, microsecond=0)
        mask = (datetimes >= _6_AM) & (datetimes <= _19_PM)
        df = df.filter(mask)

        df = get_date_name_column(df)

        common_columns = [
            "date_name",
            "datetime",
            "spot_name",
            "wind_status",
            "wave_height",
            "wave_period",
            "wind_direction",
            "wave_direction",
            "wind_speed",
            "wind_approval",
        ]
        columns_to_check = ["swell_height", "energy"]

        for column in columns_to_check:
            try:
                df[column]
                if column == "energy":
                    common_columns.insert(common_columns.index("wave_height"), column)
                else:
                    common_columns.append(column)
            except Exception:
                pass

        df = df[common_columns]
    return df

def final_tides_format(df: pl.DataFrame) -> pl.DataFrame:
    pass
    return df

def degrees_to_direction(degrees):
    directions = ["N", "NE", "E", "SE", "S", "SW", "W", "NW"]
    index = round(degrees / 45) % 8
    return directions[index]

def classify_wind_speed(speed_knots):
    if speed_knots < 1:
        return "Calm"
    elif speed_knots <= 3:
        return "Light Air"
    elif speed_knots <= 7:
        return "Light Breeze"
    elif speed_knots <= 12:
        return "Gentle Breeze"
    elif speed_knots <= 18:
        return "Moderate Breeze"
    elif speed_knots <= 24:
        return "Fresh Breeze"
    elif speed_knots <= 31:
        return "Strong Breeze"
    elif speed_knots <= 38:
        return "High Wind, Moderate Gale, Near Gale"
    elif speed_knots <= 46:
        return "Gale, Fresh Gale"
    elif speed_knots <= 54:
        return "Strong Gale"
    elif speed_knots <= 63:
        return "Storm, Whole Gale"
    elif speed_knots <= 72:
        return "Violent Storm"
    else:
        return "Hurricane"

def feet_to_meters(feet):
    meters = feet * 0.3048
    return meters

def datetime_to_str(dt: datetime, dt_format: str) -> str:
    return dt.strftime(dt_format)

def timestamp_to_datetime(timestamp_date: int) -> datetime:
    return datetime.utcfromtimestamp(timestamp_date)

def add_offset_to_datetime(dt: datetime, utc_offset: int) -> datetime:
    return dt + timedelta(hours=utc_offset)

def timestamp_to_datetimestr(timestamp_date: int, utc_offset: int) -> str:
    datetime_dt = timestamp_to_datetime(timestamp_date)
    datestr = datetime_to_str(
        add_offset_to_datetime(datetime_dt, utc_offset), INTERNAL_DATE_STR_FORMAT
    )
    timestr = datetime_to_str(
        add_offset_to_datetime(datetime_dt, utc_offset), INTERNAL_TIME_STR_FORMAT
    )
    return datestr, timestr

def datestr_to_datetime(dtstr, format) -> datetime:
    locale.setlocale(locale.LC_TIME, "es_ES.UTF-8")
    return datetime.strptime(dtstr, format)

def get_datename(dt: str):
    dt_dt = datestr_to_datetime(dt, INTERNAL_DATE_STR_FORMAT).date()

    today = datetime.now().date()
    tomorrow = today + timedelta(days=1)
    day_after_tomorrow = today + timedelta(days=2)

    if dt_dt == today:
        return "Today"
    elif dt_dt == tomorrow:
        return "Tomorrow"
    elif dt_dt == day_after_tomorrow:
        return "Day After Tomorrow"
    else:
        return "Another Day"

def kmh_to_knots(kmh):
    return kmh / 1.852

def mps_to_knots(mps):
    return mps * 1.94384

def convert_all_values_of_dict_to_min_length(data):
    min_len = obtain_minimum_len_of_dict_values(data)
    new_data = {}
    for key, value in data.items():
        new_data[key] = value[:min_len]
    return new_data

def obtain_minimum_len_of_dict_values(data: dict):
    data_value_lens = []
    for _, value in data.items():
        data_value_lens.append(len(value))
    return min(data_value_lens)

def generate_dates(times: list) -> list:
    dates = []
    date = datetime.now().date()
    for index, time in enumerate(times):
        if index - 1 >= 0 and datestr_to_datetime(time, "%H:%M") < datestr_to_datetime(
            times[index - 1], "%H:%M"
        ):
            date += timedelta(days=1)
        date_str = datetime.strftime(date, "%d/%m/%Y")
        dates.append(date_str)
    return dates

# def check_conditions(wind_direction, wave_direction):
#     # Define the contraries
#     contraries = {"N": "S", "S": "N", "E": "O", "O": "E"}
#     return contraries

def are_contraries(dir1, dir2):
    return CONTRARIES.get(dir1) == dir2

def get_maximum_len_str(wind_direction, wave_direction):
    if len(wind_direction) > len(wave_direction):
        return wind_direction
    else:
        return wave_direction

def get_minimum_len_str(wind_direction, wave_direction):
    if len(wind_direction) > len(wave_direction):
        return wave_direction
    else:
        return wind_direction

def count_contraries(wind_direction, wave_direction):
    counter = 0
    if len(wind_direction) == len(wave_direction):
        for i in range(len(wind_direction)):
            if are_contraries(wind_direction[i], wave_direction[i]):
                counter += 1
    else:
        max_len_str = get_maximum_len_str(wind_direction, wave_direction)
        min_len_str = get_minimum_len_str(wind_direction, wave_direction)
        for mili in min_len_str:
            for mali in max_len_str:
                if are_contraries(mili, mali):
                    counter += 1
                if counter >= len(min_len_str):
                    break
    return counter

def get_wind_status(wind_direction, wave_direction):
    wd_len = len(wind_direction)
    wv_len = len(wave_direction)
    len_contraries = count_contraries(wind_direction, wave_direction)
    if wd_len == wv_len and wd_len == len_contraries:
        return "Offshore"
    elif len_contraries >= 1:
        return "Cross-off"
    return "Onshore"


from lab_python_fp.gen_random import gen_random

class Unique(object):
    def __init__(self, items, **kwargs):
        self.ignore_case = kwargs.get('ignore_case', False)
        self.set = set()
        self.iter = iter(items)

    def __next__(self):
        for current in self.iter:
            if self.ignore_case == False:
                if current not in self.set:
                    self.set.add(current)
                    return current
            else:
                if current.lower() not in self.set:
                    self.set.add(current)
                    return current
        raise StopIteration

    def __iter__(self):
        return self

class Unique(object):
    def __init__(self, items, **kwargs):
        self.ignore_case = kwargs.get("ignore_case", False)
        self.iter = iter(items)
        self.used = set()

    def __next__(self):
        for current in self.iter:
            if isinstance(current, str):
                if (current.lower() if self.ignore_case else current) not in self.used:
                    self.used.add(current.lower())
                    return current
            else:
                if current not in self.used:
                    self.used.add(current)
                    return current
        raise StopIteration

    def __iter__(self):
        return self

def main():

    u = Unique([2, 1, 2, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 4, 5, 4])
    for i in u:
        print(i, end=" ")
    print()
    u = Unique(["A", "a", "B", "b", "b", "B", "A", "C"])
    for i in u:
        print(i, end=" ")
    print()
    u = Unique(["A", "a", "B", "b", "b", "B", "A", "C"], ignore_case=True)
    for i in u:
        print(i, end=" ")
    print()

if __name__ == "__main__":
    print(list(Unique([1, 1, 1, 1, 1, 2, 2, 2, 2, 2])))
    print(list(Unique(gen_random(10, 1, 3))))
    print(list(Unique(['a', 'A', 'b', 'B', 'a', 'b'])))
    print(list(Unique(['a', 'A', 'b', 'B', 'a', 'A', 'b', 'B'], ignore_case=True)))


from collections import namedtuple

from django import template

register = template.Library()

Unit = namedtuple("Unit", ["name", "plural", "seconds"])

second = Unit("sec", "secs", 1)
units = [
    Unit("day", "days", 24 * 60 * 60),
    Unit("hr", "hrs", 60 * 60),
    Unit("min", "mins", 60),
]

def _duration_unit(value, unit):
    unit_name = unit.name if value == 1 else unit.plural
    return f"{value:g} {unit_name}"

def _pretty_durations(value):
    remainder = value
    for unit in units:
        quotient, remainder = divmod(remainder, unit.seconds)
        if quotient:
            quotient = int(quotient)
            yield _duration_unit(quotient, unit)
    if remainder:
        yield _duration_unit(remainder, second)

@register.filter
def sectodur(value):
    """Returns human-readable duration from seconds.
    """
    if value <= 0:
        return "-"
    return " ".join(unit for unit in _pretty_durations(value))


import random as r
import decimal as d
# Задайте список из нескольких чисел. Напишите программу, которая найдёт сумму элементов списка,
# стоящих на нечётной позиции. # Пример:
# - [2, 3, 5, 9, 3] -> на нечётных индексы элементы 3 и 9, ответ: 12
print('\nЗадача 1. Найти сумму элементов списка с нечетными индексами')
l_1 = int(input('введите размер списка:'))
list_1 = []
sum_1 = 0
for i in range(l_1):
    list_1.append(r.randint(0, 9))
    if i % 2 != 0:
        sum_1 += list_1[i]
print(f'для списка {list_1} сумма элементов с нечетными индексами: {sum_1}')

# Напишите программу, которая найдёт произведение пар чисел списка. Парой считаем первый и последний элемент,
# второй и предпоследний и т.д.
# Пример:
# - [2, 3, 4, 5, 6] => [12, 15, 16];
# - [2, 3, 5, 6] => [12, 15]
print('\nЗадача 2. Найти произведение пар чисел списка')
l_2 = int(input('введите размер списка:'))
list_2 = [r.randint(1, 9) for i in range(l_2)]
half_list = l_2//2 if l_2 % 2 == 0 else l_2//2 +1
l_product = [list_2[i] * list_2[l_2-i-1] for i in range(half_list)]
print(f'для списка {list_2} список произведений пар чисел списка: {l_product}')

# Задайте список из вещественных чисел. Напишите программу, которая найдёт разницу
# между максимальным и минимальным значением дробной части элементов.
# Пример:
# - [1.1, 1.2, 3.1, 10.01] => 0.19
print('\nЗадача 3. Найти  разницу между максимальным и минимальным значением дробной части элементов списка')
l_3 = int(input('введите размер списка:'))
list_int = [round(r.random() * r.randint(1, 100), 2) for i in range(l_3)]
dec_list = [list_int[i] % 1 for i in range(l_3)]
diff = max(dec_list)-min(dec_list)
print(f'{list_int} =>  {round(diff, 2)}')

# Напишите программу, которая будет преобразовывать десятичное число в двоичное (без встроенных функций).
# Пример:
# - 45 -> 101101
# - 3 -> 11
# - 2 -> 10
print('\nЗадача 4. Преобразовать десятичное число в двоичное')

def bin_number(i):
    bin_list = []
    while i > 0:
        dig = i % 2
        bin_list.insert(0, dig)
        i = i//2
    return "".join([str(x) for x in bin_list])

int_number = int(input("Введите целое число: "))
print(f'{int_number} -> {bin_number(int_number)}')

# # Задайте число. Составьте список чисел Фибоначчи, в том числе для отрицательных индексов.
# # Пример:#
# # для k = 8 список будет выглядеть так: [-21 ,13, -8, 5, −3, 2, −1, 1, 0, 1, 1, 2, 3, 5, 8, 13, 21]
print('\nЗадача 5. задать натуральное число k, получить список Фибоначчи от f(-k) до f(k)')

def fibonacci(n):
    if n in {0, 1}:
        return n
    elif n == -1:
        return 1
    elif n == -2:
        return -1
    elif n > 0:
        return fibonacci(n - 1) + fibonacci(n - 2)
    else:
        return fibonacci(n + 2) - fibonacci(n + 1)

k = int(input("Введите целое число: "))
f_list = [fibonacci(i) for i in range(-k, k+1)]
print(f'для k = {k} список будет выглядеть так: {f_list}')


import streamlit as st
import numpy as np
import pandas as pd
import altair as alt
import itertools
import statsmodels
import pickle
import statsmodels.api as sm
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tools.eval_measures import rmse
from statsmodels.tsa.stattools import adfuller
from pandas.plotting import autocorrelation_plot
from matplotlib import pyplot
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.arima_model import ARMAResults
from statsmodels.tsa.stattools import acf
import fbprophet
from scipy.stats import boxcox
from scipy.special import inv_boxcox
from datetime import timedelta
import plotly.graph_objects as go

def regression2():
    cases_malaysia = pd.read_csv("Dataset/cases_malaysia.csv")
    cases_malaysia['date'] = pd.to_datetime(cases_malaysia['date'])
    cases_malaysia.fillna(value = 0, inplace = True)
    filter = ['cluster_import','cluster_religious','cluster_community','cluster_highRisk','cluster_education','cluster_detentionCentre','cluster_workplace']
    cases_malaysia[filter] = cases_malaysia[filter].astype(int)
    df_cases_reg2 = cases_malaysia[['date','cases_new']]
    df_cases_reg2 = df_cases_reg2[df_cases_reg2['date'] > '2020-12-31']
    df_cases_reg2['date'] = pd.to_datetime(df_cases_reg2['date'])
    df_cases_reg2 = df_cases_reg2.set_index('date')

    selectModel = st.selectbox("Select a model to view", ['Autoregressive integrated moving average(ARIMA)','FBProphet'])

    if selectModel == 'Autoregressive integrated moving average(ARIMA)':
        st.markdown('------Autoregressive integrated moving average(ARIMA)------')
        df_arima_reg2 = df_cases_reg2.copy()
        train_arima_reg2 = df_arima_reg2[:293]
        test_arima_reg2 = df_arima_reg2[293:]
        #load arima model
        model_arima_reg2 = pickle.load(open('Model/arima_cases', 'rb'))
        # Forecast
        fc, conf = model_arima_reg2.predict(5, return_conf_int=True)  # 95% conf

        # Make as pandas series
        fc_series = pd.Series(fc, index=test_arima_reg2.index)
        lower_series = pd.Series(conf[:, 0], index=test_arima_reg2.index)
        upper_series = pd.Series(conf[:, 1], index=test_arima_reg2.index)

        st.markdown('********Out-of-Time cross-validation********')
        st.markdown('In Out-of-Time cross-validation, few steps back in time and forecast into the future to as many steps you took back. Then you compare the forecast against the actuals.')
        # Plot for Model Validation
        plt.figure(figsize=(12,5), dpi=100)
        plt.plot(train_arima_reg2, label='training')
        plt.plot(test_arima_reg2, label='actual')
        plt.plot(fc_series, label='forecast')
        plt.fill_between(lower_series.index, lower_series, upper_series,
                        color='k', alpha=.15)
        plt.title('Forecast vs Actuals')
        plt.xlabel('Date')
        plt.ylabel('COVID-19 Cases')
        plt.legend(loc='upper left', fontsize=10)
        st.pyplot(plt)
        plt.clf()

        #Model Evaluation Metrics
        def forecast_accuracy(forecast, actual):
            mape = np.mean(np.abs(forecast - actual)/np.abs(actual))  # MAPE
            me = np.mean(forecast - actual)             # ME
            mae = np.mean(np.abs(forecast - actual))    # MAE
            mpe = np.mean((forecast - actual)/actual)   # MPE
            rmse = np.mean((forecast - actual)**2)**.5  # RMSE
            corr = np.corrcoef(forecast, actual)[0,1]   # corr
            mins = np.amin(np.hstack([forecast[:,None],
                                    actual[:,None]]), axis=1)
            maxs = np.amax(np.hstack([forecast[:,None],
                                    actual[:,None]]), axis=1)
            minmax = 1 - np.mean(mins/maxs)             # minmax
            acf1 = acf(fc-test_arima_reg2['cases_new'])[1]   # ACF1
            return (mape,me,mae,mpe,rmse,corr,minmax,acf1)

        (mape,me,mae,mpe,rmse,corr,minmax,acf1) = forecast_accuracy(fc, test_arima_reg2['cases_new'].values)

        ##Printing Table
        st.text("")
        st.markdown('********ARIMA Evaluation Metrics Score********')
        st.markdown('Evaluation Metrics: \n- Mean Absolute Percentage Error (MAPE)\n- Mean Error (ME)\n- Mean Absolute Error (MAE)\n- Mean Percentage Error (MPE)\n- Root Mean Squared Error (RMSE)\n- Lag 1 Autocorrelation of Error (ACF1)\n- Correlation between the Actual and the Forecast (corr)\n- Min-Max Error (minmax)')
        table1 = go.Figure(data=[go.Table(
        columnwidth=[1, 4],
        header=dict(values=['Metrics', 'Value'],
                    fill=dict(color=['paleturquoise']),
                    align='center',height=30),
        cells=dict(values=[['MAPE','ME','MAE','MPE','RMSE','corr','minmax','ACF1'],
                        [str(mape),str(me), str(mae), str(mpe), str(rmse), str(corr), str(minmax), str(acf1)]],
                fill=dict(color=['lightcyan']),
                align='center',height=30))
        ])
        table1 = table1.update_layout(width=400,height=200, margin=dict(l=0,r=10,t=5,b=0))
        st.write(table1)
        st.text("")
        st.markdown('********Forecasting for the Total Number of COVID-19 Cases Drop below 1000 Cases per day********')
        #Forecasting the date
        time_steps = 1
        while True:
            forecast_arr = model_arima_reg2.predict(n_periods=time_steps)
            forecast_arr_length = len(forecast_arr)
            forecast = forecast_arr[forecast_arr_length - 1]
            if(forecast < 1000):
                break
            time_steps += 1

        #Forecast
        n_periods = time_steps
        fc, confint = model_arima_reg2.predict(n_periods=n_periods, return_conf_int=True)
        index_of_fc = np.arange(len(train_arima_reg2.values), len(train_arima_reg2.values)+n_periods)

        # make series for plotting purpose
        fc_series = pd.Series(fc, index=index_of_fc)
        lower_series = pd.Series(confint[:, 0], index=index_of_fc)
        upper_series = pd.Series(confint[:, 1], index=index_of_fc)

        # Plot
        plt.figure(figsize=(12,5), dpi=100)
        plt.plot( train_arima_reg2.values)
        plt.plot(fc_series, color='darkgreen',label='Forecast')
        plt.fill_between(lower_series.index,
                        lower_series,
                        upper_series,
                        color='k', alpha=.15)
        plt.legend(loc='upper left', fontsize=15)
        plt.ylabel('COVID-19 Cases')
        plt.title("Forecast for the Total Number of COVID-19 Cases Drop below 1000 Cases per day")
        plt.axhline(y=1000, color='r', linestyle='--',label='1000')
        label_list = [
            (310, 'Cases drop below 1000 starting on 2021-11-07', 'r'),

        ]
        ax = plt.gca()
        for date_point, label, clr in label_list:
            plt.axvline(x=date_point, color=clr,linestyle='--')
            plt.text(date_point, ax.get_ylim()[1]-4, label,
                    horizontalalignment='center',
                    verticalalignment='center',
                    color=clr,
                    bbox=dict(facecolor='white', alpha=0.9))
        st.pyplot(plt)
        st.markdown('The total number of COVID-19 cases will drop below 1000 cases per day on 2021-11-07.')
        st.text("")

    else:
        st.markdown('------FBProphet------')
        df_prophet_reg2 = cases_malaysia[['date','cases_new']]
        #filter for year 2021
        df_prophet_reg2 = df_prophet_reg2[df_prophet_reg2['date'] > '2020-12-31']
        # prepare expected column names
        df_prophet_reg2.columns = ['ds', 'y']
        df_prophet_reg2['ds']= pd.to_datetime(df_prophet_reg2['ds'])
        #create train and test dataset
        train_regq2_2 = df_prophet_reg2[:293].copy()
        test_regq2_2 = df_prophet_reg2[293:].copy()
        #load prophet model
        model_prophet_reg2 = pickle.load(open('Model/prophet_cases', 'rb'))
        #Test performance
        test_future_dates = model_prophet_reg2.make_future_dataframe(periods=5)
        test_forecast = model_prophet_reg2.predict(test_future_dates)
        test_yhat_q2 = test_forecast['yhat']
        test_yhat_q2 = test_yhat_q2[293:]

        def forecast_accuracy2(forecast, actual):
            mape = np.mean(np.abs(forecast - actual)/np.abs(actual))  # MAPE
            me = np.mean(forecast - actual)             # ME
            mae = np.mean(np.abs(forecast - actual))    # MAE
            mpe = np.mean((forecast - actual)/actual)   # MPE
            rmse = np.mean((forecast - actual)**2)**.5  # RMSE
            corr = np.corrcoef(forecast, actual)[0,1]   # corr
            mins = np.amin(np.hstack([forecast[:,None],
                                    actual[:,None]]), axis=1)
            maxs = np.amax(np.hstack([forecast[:,None],
                                    actual[:,None]]), axis=1)
            minmax = 1 - np.mean(mins/maxs)             # minmax
            acf1 = acf(test_yhat_q2-test_regq2_2['y'].values)[1]   # ACF1
            return (mape,me,mae,mpe,rmse,corr,minmax,acf1)

        (mape2,me2,mae2,mpe2,rmse2,corr2,minmax2,acf1) = forecast_accuracy2(test_yhat_q2, test_regq2_2['y'].values)

        ##Printing Table
        st.text("")
        st.markdown('********FBProphet Evaluation Metrics Score********')
        st.markdown('Evaluation Metrics: \n- Mean Absolute Percentage Error (MAPE)\n- Mean Error (ME)\n- Mean Absolute Error (MAE)\n- Mean Percentage Error (MPE)\n- Root Mean Squared Error (RMSE)\n- Lag 1 Autocorrelation of Error (ACF1)\n- Correlation between the Actual and the Forecast (corr)\n- Min-Max Error (minmax)')
        table2 = go.Figure(data=[go.Table(
        columnwidth=[1, 4],
        header=dict(values=['Metrics', 'Value'],
                    fill=dict(color=['paleturquoise']),
                    align='center',height=30),
        cells=dict(values=[['MAPE','ME','MAE','MPE','RMSE','corr','minmax','ACF1'],
                        [str(mape2),str(me2), str(mae2), str(mpe2), str(rmse2), str(corr2), str(minmax2), str(acf1)]],
                fill=dict(color=['lightcyan']),
                align='center',height=30))
        ])
        table2 = table2.update_layout(width=400,height=200, margin=dict(l=0,r=10,t=5,b=0))
        st.write(table2)
        st.text("")
        st.markdown('********Forecasting for the Total Number of COVID-19 Cases Drop below 1000 Cases per day********')

        future_dates = model_prophet_reg2.make_future_dataframe(periods=365)
        forecast = model_prophet_reg2.predict(future_dates)
        model_prophet_reg2.plot(forecast)
        plt.ylim(0,30000)
        plt.title("Forecast for the Total Number of COVID-19 Cases Drop below 1000 Cases per day")
        plt.xlabel('Date')
        plt.ylabel('COVID-19 Cases')
        plt.axhline(y=1000, color='r', linestyle='--',label='1000')
        label_list = [
            (pd.to_datetime("2021-11-14"), 'Cases drop below 1000 starting on 2021-11-14', 'r'),

        ]
        ax = plt.gca()
        for date_point, label, clr in label_list:
            plt.axvline(x=date_point, color=clr,linestyle='--')
            plt.text(date_point, ax.get_ylim()[1]-4, label,
                    horizontalalignment='center',
                    verticalalignment='center',
                    color=clr,
                    bbox=dict(facecolor='white', alpha=0.9))
        plt.legend()
        st.pyplot(plt)

        st.markdown('The total number of COVID-19 cases drop below 1000 cases per day on 2021-11-14')


import uuid
from botocore import stub, exceptions
import pytest
from fixtures import apigateway_event, context, lambda_module # pylint: disable=import-error
from helpers import mock_table # pylint: disable=import-error,no-name-in-module

lambda_module = pytest.fixture(scope="module", params=[{
    "function_dir": "on_connect",
    "module_name": "main",
    "environ": {
        "ENVIRONMENT": "test",
        "EVENT_RULE_NAME": "EVENT_BUS_NAME|EVENT_RULE_NAME",
        "LISTENER_TABLE_NAME": "TABLE_NAME",
        "POWERTOOLS_TRACE_DISABLED": "true"
    }
}])(lambda_module)
context = pytest.fixture(context)

def test_store_id(lambda_module):
    """
    Test store_id()
    """

    connection_id = str(uuid.uuid4())
    table = mock_table(
        lambda_module.table, "put_item", ["id"],
        items={
            "id": connection_id,
            "ttl": stub.ANY
        }
    )

    lambda_module.store_id(connection_id)

    table.assert_no_pending_responses()
    table.deactivate()

def test_enable_rule(lambda_module):
    """
    Test enable_rule()
    """

    eventbridge = stub.Stubber(lambda_module.eventbridge)
    eventbridge.add_response("enable_rule", {}, {
        "Name": "EVENT_RULE_NAME",
        "EventBusName": "EVENT_BUS_NAME"
    })
    eventbridge.add_response(
        "describe_rule",
        {
            "Name": "EVENT_RULE_NAME",
            "State": "ENABLED",
            "EventBusName": "EVENT_BUS_NAME"
        },
        {"Name": "EVENT_RULE_NAME", "EventBusName": "EVENT_BUS_NAME"},
    )
    eventbridge.activate()

    lambda_module.enable_rule()

    eventbridge.assert_no_pending_responses()

    eventbridge.deactivate()

def test_handler(monkeypatch, lambda_module, context, apigateway_event):
    """
    Test handler()
    """

    connection_id = str(uuid.uuid4())

    event = apigateway_event()
    event["requestContext"] = {"connectionId": connection_id}

    calls = {
        "store_id": 0,
        "enable_rule": 0
    }

    def store_id(connection_id_req: str):
        calls["store_id"] += 1
        assert connection_id_req == connection_id
    monkeypatch.setattr(lambda_module, "store_id", store_id)

    def enable_rule():
        calls["enable_rule"] += 1
    monkeypatch.setattr(lambda_module, "enable_rule", enable_rule)

    result = lambda_module.handler(event, context)

    assert result["statusCode"] == 200
    assert calls["store_id"] == 1
    assert calls["enable_rule"] == 1

def test_handler_no_id(monkeypatch, lambda_module, context, apigateway_event):
    """
    Test handler()
    """

    connection_id = str(uuid.uuid4())

    event = apigateway_event()

    calls = {
        "store_id": 0,
        "enable_rule": 0
    }

    def store_id(connection_id_req: str):
        calls["store_id"] += 1
        assert connection_id_req == connection_id
    monkeypatch.setattr(lambda_module, "store_id", store_id)

    def enable_rule():
        calls["enable_rule"] += 1
    monkeypatch.setattr(lambda_module, "enable_rule", enable_rule)

    result = lambda_module.handler(event, context)

    assert result["statusCode"] == 400
    assert calls["store_id"] == 0
    assert calls["enable_rule"] == 0


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

import sys

from base import Solution

class Api(Solution):

    def algorithm_func(self, haystack: str, needle: str) -> int:
        try:
            return haystack.index(needle)
        except:
            print("Unexpected error:", sys.exc_info()[0])
            return -1

def main():
    x = Api()

    x.test(
        {'haystack': '1234567893450', 'needle': '345'},
        {'ret_val': 2},
        '无重复'
    )

    x.test(
        {'haystack': '123434134343434134341', 'needle': '34341'},
        {'ret_val': 2},
        '有重复'
    )

    x.test(
        {'haystack': 'asfeqewqfewqfewqffds', 'needle': '34341'},
        {'ret_val': -1},
        '不存在'
    )

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
import argparse
import lzma
import pickle
import os
import sys
import urllib.request

import numpy as np
from sklearn.neural_network import MLPClassifier
import sklearn.datasets
import sklearn.model_selection
import sklearn.linear_model
import sklearn.pipeline
import sklearn.preprocessing

class Dictionary:
    def __init__(self,
                 name="fiction-dictionary.txt",
                 url="https://ufal.mff.cuni.cz/~straka/courses/npfl129/2122/datasets/"):
        if not os.path.exists(name):
            print("Downloading dataset {}...".format(name), file=sys.stderr)
            urllib.request.urlretrieve(url + name, filename=name)
            urllib.request.urlretrieve(url + name.replace(".txt", ".LICENSE"), filename=name.replace(".txt", ".LICENSE"))

        # Load the dictionary to `variants`
        self.variants = {}
        with open(name, "r", encoding="utf-8-sig") as dictionary_file:
            for line in dictionary_file:
                nodia_word, *variants = line.rstrip("\n").split()
                self.variants[nodia_word] = variants

class Dataset:
    LETTERS_NODIA = "acdeeinorstuuyz"
    LETTERS_DIA = "áčďéěíňóřšťúůýž"

    # A translation table usable with `str.translate` to rewrite characters with dia to the ones without them.
    DIA_TO_NODIA = str.maketrans(LETTERS_DIA + LETTERS_DIA.upper(), LETTERS_NODIA + LETTERS_NODIA.upper())

    def __init__(self,
                 name="fiction-train.txt",
                 url="https://ufal.mff.cuni.cz/~straka/courses/npfl129/2122/datasets/"):
        if not os.path.exists(name):
            print("Downloading dataset {}...".format(name), file=sys.stderr)
            urllib.request.urlretrieve(url + name, filename=name)
            urllib.request.urlretrieve(url + name.replace(".txt", ".LICENSE"),
                                       filename=name.replace(".txt", ".LICENSE"))

        # Load the dataset and split it into `data` and `target`.
        with open(name, "r", encoding="utf-8-sig") as dataset_file:
            self.target = dataset_file.read()
        self.data = self.target.translate(self.DIA_TO_NODIA)

def accuracy(gold: str, system: str) -> float:
    assert isinstance(gold, str) and isinstance(system, str), "The gold and system outputs must be strings"

    gold, system = gold.split(), system.split()
    assert len(gold) == len(system), "The gold and system outputs must have same number of words: {} vs {}.".format(len(gold), len(system))

    words, correct = 0, 0
    for gold_token, system_token in zip(gold, system):
        words += 1
        correct += gold_token == system_token

    return correct / words

def dictionarized(input, dict):
    splitted = input.split()
    dictedOutput = ""
    for word in splitted:
        noDiaWord = makeNoDia(word)
        if noDiaWord in dict.variants.keys():
            variants = dict.variants[noDiaWord]
            dictedOutput += chooseClosestVariant(variants,word) + " "
        else:
            dictedOutput +=  word + " "
    return dictedOutput[:-1]

def chooseClosestVariant(variants,word):
    distances = np.zeros(len(variants))
    for i in range(len(variants)):
        distances[i] = getDistance(variants[i],word)

    closest = np.where(distances == distances.min())

    return variants[closest[0][0]]

def getDistance(variant,word):
    differentLetters=0
    for i in range(len(word)):
        if(word[i]!=variant[i]):
            differentLetters+=1
    return differentLetters

def makeNoDia(word):
    LETTERS_NODIA = "acdeeinorstuuyz"
    LETTERS_DIA = "áčďéěíňóřšťúůýž"
    newWord=""
    for i in range(len(word)):
        upper = False
        lowered = word[i].lower()
        if(word[i].isupper()):
            upper = True
        else:
            upper = False

        if lowered in LETTERS_DIA:
            index = LETTERS_DIA.index(word[i])
            if(upper):
                newWord+=(LETTERS_NODIA[index].upper())
            else:
                newWord+=(LETTERS_NODIA[index])
        else:
            if(upper):
                newWord+=(word[i].upper())
            else:
                newWord+=(word[i])
    return newWord

def doOneHot(window):
    pocetPismenek = 122
    out = np.zeros(len(window) * pocetPismenek)
    for i in range(len(window)):
        out[i * pocetPismenek + ord(window[i]) - 1] = 1
    return out

def main(args: argparse.Namespace):
    if args.predict is None:
        # We are training a model.
        np.random.seed(args.seed)
        train = Dataset()

        oneHotted = []
        targetMatrix = []
        windowSize = 5
        for i in range(windowSize, len(train.data) - windowSize):
            if(train.data[i] in train.LETTERS_NODIA):
                OneWindow = doOneHot(train.data[i - windowSize:i + windowSize])
                oneHotted.append(OneWindow)
                targetMatrix.append(train.target[i])
        model = MLPClassifier(hidden_layer_sizes=(300, 150), batch_size='auto', learning_rate='constant', max_iter=10, verbose=True).fit(oneHotted, targetMatrix)

        # Serialize the model.
        with lzma.open(args.model_path, "wb") as model_file:
            pickle.dump(model, model_file)

    else:
        test = Dataset(args.predict)

        with lzma.open(args.model_path, "rb") as model_file:
            model = pickle.load(model_file)

        windowSize = 5
        output=""
        for i in range(windowSize,len(test.data)-windowSize):
            if(test.data[i] in test.LETTERS_NODIA):
                OneWindow = doOneHot(test.data[i - windowSize:i + windowSize])
                res =model.predict([OneWindow])
                output+= res[0]
            else:
                output += test.data[i]

        print(accuracy(test.target,test.data[0:windowSize] + output + test.data[-windowSize:] ))
        FinalOutput=test.data[0:windowSize] + output + test.data[-windowSize:]

        initDictionary = Dictionary()

        return dictionarized(FinalOutput,initDictionary)
        #return dictionarized("Praskání Měla Melá jg jablko",initDictionary)


import numpy as np
import glob
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import pickle

mtx=pickle.load(open("mtx.p", "rb"))
dist=pickle.load(open("dist.p", "rb"))

def undistort_image(img, mtx=mtx, dist=dist):
	undist = cv2.undistort(img, mtx, dist, None, mtx)
	return undist

def binary_image_creation(image, already_undistorted, s_thresh=(170,255), sx_thresh=(20,100)):
	if already_undistorted == False:
		undist = undistort_image(image)
		print("Lens distortion removed from image")
	else:
		undist = image
	img = np.copy(undist)

	#Convert to HLS colour space and isolate the L and S channels
	hls = cv2.cvtColor(img, cv2.COLOR_RGB2HLS)
	l_channel = hls[:,:,1]
	s_channel = hls[:,:,2]
	print("Image converted form RGB to HLS colour space")

	#Gradient thresholding is done on L channel
	sobelx = cv2.Sobel(l_channel, cv2.CV_64F, 1, 0) #Take hte derivative in x (better for detecting vertical structures e.g. lane lines)
	abs_sobelx = np.absolute(sobelx) #Absolute x derivative accentuates lines away from horizontal
	scaled_sobel = np.uint8(255*abs_sobelx/np.max(abs_sobelx))

	#Threshold x gradient and map onto a copy of image that will be presented in one layer of final mask
	sxbinary = np.zeros_like(scaled_sobel)
	sxbinary[(scaled_sobel >= sx_thresh[0]) & (scaled_sobel <= sx_thresh[1])] = 1
	print("Gradient thresholding complete")

	#Threshold color channel is done on S channel and map onto a copy of image that will be presented in one layer of final mask
	s_binary = np.zeros_like(s_channel)
	s_binary[(s_channel >= s_thresh[0]) & (s_channel <= s_thresh[1])] = 1
	print("Colour thresholding complete")

	#Stack the different masks into different channels of an RGB image. This is just for visual effect.
	color_binary = np.dstack(( np.zeros_like(sxbinary), sxbinary, s_binary)) *255
	print("Thresholding results displayed in color_binary. Green shows gradient thresholding and blue shows colour thresholding.")

	#Stack the different masks into the same channel. This grayscale image is what we actually use
	overall_binary = cv2.cvtColor(color_binary, cv2.COLOR_RGB2GRAY)
	overall_binary[ overall_binary > 0] =255
	print("Grayscale mask created. Activated pixels show potential regions identified using EITHER gradient OR colour thresholding")

	return overall_binary, color_binary

image = cv2.imread('./test_images/test1.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
print("test1 image loaded from disc")
thresh_gray, thresh_colour = binary_image_creation(image, already_undistorted = False)

#Plot original camera image (distorted) next to the calibrated (undistorted) image
f, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize = (24, 9))
f.tight_layout()
ax1.imshow(image)
ax1.set_title('Original Image', fontsize = 50)
ax2.imshow(thresh_colour)
ax2.set_title('Thresholding', fontsize = 50)
ax3.imshow(thresh_gray, cmap='gray')
ax3.set_title('Lane Detection', fontsize = 50)
plt.subplots_adjust(left=0., right = 1, top=0.9, bottom=0.)
plt.savefig('test1_thresh.png')
plt.close()
print('You can observe the lane detection in test1_thresh.png')


from VASSAL.counters import Decorator, Embellishment, BasicPiece

# 1 (activateCommand)	            'Activate',	     'Activate',
# 2 (activateModifiers)	            '128',	         '128',
# 3 (activateKey)	                'A',	         'A',
# 4 (upCommand)	                    '',	             'fooIncR',
# 5 (upModifiers)	                '128',	         '128',
# 6 (upKey)	                        '',	             '',
# 7 (downCommand)	                '',	             'fooDecD',
# 8 (downModifiers)	                '128',	         '128',
# 9 (downKey)	                    '',	             '',
# 10 (resetCommand)	                '',	             'fooResetF',
# 11 (resetKey)	                    '',	             '70,130',
# 12 (resetLevel.getFormat())	    '1',	         '1',
# 13 (drawUnderneathWhenSelected)   'false',         'false',
# 14 (xOff)	                        '0',	         '0',
# 15 (yOff)	                        '0',		     '0',
# 16 (imageName)	                '',	  	         '',
# 17 (commonName)    	            '',	 	         '',
# 18 (loopLevels)	                'true',		     'false',
# 19 (name)	                        'foo name',	     '',
# 20 (rndKey)   // rnd 	            '',	 	         '',
# 21 (rndText)  // rnd 	            '',	 	         '',
# 22 (followProperty)	            'true',		     'false',
# 23 (propertyName)	                '{fooValue}',	 '',
# 24 (firstLevelValue)	            '1',	         '1',
# 25 (version)	  	                '1',		     '1',
# 26 (alwaysActive)	 	            'true',	         'true',
# 27 (activateKeyStroke)            '65,130',	     '65,130',
# 28 (increaseKeyStroke)            '',	         	 '82,130',
# 29 (decreaseKeyStroke)            '',	         	 '68,130',
# 30 (description)	                'foo desc',    	 '',
# 31 (scale);	 	                '1.0'	       	 '1.0'

class Layer:
    _layer_class = Embellishment().getClass()
    _NAME             = 19
    _FOLLOW_PROP_BOOL = 22
    _FOLLOW_PROP_EXPR = 23
    _FIRST_LEVEL_VAL  = 24

    def __init__(self, emb):
        self._array = [str(x) for x in emb.myGetType().split(';')]
        self._emb = emb

    def __setitem__(self, key, value):
        self._array[key] = value

    def set_follow_expression(self, expr):
        self.__setitem__(key=Layer._FOLLOW_PROP_EXPR, value=expr)
        self.__setitem__(key=Layer._FOLLOW_PROP_BOOL, value="true")
        self.__setitem__(key=Layer._FIRST_LEVEL_VAL , value="1")

    def set_name(self, name):
        self.__setitem__(key=Layer._NAME, value=name)

    @staticmethod
    def rename_piece_layer(piece, old_layer_name, new_layer_name):
        emb = Layer.find_layer(piece, old_layer_name)
        if emb:
            layer = Layer(emb)
            layer.set_name(new_layer_name)
            layer.set_layer()
            return layer
        else:
            return None

    @staticmethod
    def find_layer(piece, layer_name):
        while not isinstance(piece, BasicPiece):
            layer = Decorator.getDecorator(piece, Layer._layer_class)
            if layer.getLayerName() == layer_name:
                return layer
            piece = layer.getInner()
        return None

    @staticmethod
    def layer_to_array(layer):
        return list(layer.getType().split(';'))

    def set_layer(self):
        type_str = ';'.join(self._array)
        self._emb.mySetType(type_str)

    def set_piece_layer_from_layer(self, piece, layer_name):
        type_str = ';'.join(self._array)
        layer = Layer.find_layer(piece, layer_name)
        if layer:
            layer.mySetType(type_str)


# Enter your code here. Read input from STDIN. Print output to STDOUT
from collections import deque
T = int(input())

block_size = []
block_contents = []

for t in range(T):
    t_size = int(input())
    t_content = list(map(int,input().split()))
    block_size.append(t_size)
    block_contents.append(t_content)

def solver(size,content):
    content = deque(content)
    compare = sorted(content,reverse=True)
    tmp = 0
    box = [max(content[0],content[size-1])]
    if content[0] >= content[size-1]:
        content.popleft()
    else:
        content.pop()

    for i in range(size-2):
        new_size = len(content)
        tmp = max(content[0],content[new_size-1])
        if tmp > box[-1]:
            flg = False
            break

        if content[0] >= content[new_size-1]:
            content.popleft()
        else:
            content.pop()

        box.append(tmp)
    box.append(content[0])

    flg = False
    if box == compare:
        flg = True

    return flg

for j in range(T):
    if solver(block_size[j],block_contents[j]):
        print("Yes")
    else:
        print("No")


import pygame
import os
import math
from game.game import Game
from color_settings import *
from settings import WIN_WIDTH, WIN_HEIGHT, FPS,singleton_vol_controller, singleton_map_controller,game_status,test_transparency
from opt_menu.opt_menu import OptMenu
from exit_win.exit_win import ExitWin
from dir_path import *

MOUSE = pygame.transform.scale(pygame.image.load(os.path.join(IMG_DIR, "mouse.png")), (20, 20))

pygame.init()
pygame.mixer.init()

class StartMenu:
    def __init__(self):
        # win
        self.menu_win = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
        # background
        self.bg = pygame.transform.scale(pygame.image.load(os.path.join(IMG_DIR, "start_menu3.png")), (WIN_WIDTH, WIN_HEIGHT))
        # button
        self.start_btn = Buttons(430, 355, 170, 50)  # x, y, width, height
        self.opt_btn=Buttons(430, 425, 170, 50)
        self.buttons = [self.start_btn,
                        self.opt_btn]
        # btn img
        # self.opt_btn_img=pygame.transform.scale(pygame.image.load(os.path.join("images", "options.png")), (338,100))

        # music and sound
        self.sound = pygame.mixer.Sound(os.path.join(SOUND_DIR,"sound.mp3"))

    def play_music(self):
        pygame.mixer.music.stop()
        pygame.mixer.music.load(os.path.join(SOUND_DIR,"menu.mp3"))
        pygame.mixer.music.set_volume(singleton_vol_controller.music_volume)
        pygame.mixer.music.play(-1)
        self.sound.set_volume(singleton_vol_controller.sound_volume)

    def menu_run(self):
        clock = pygame.time.Clock()
        pygame.display.set_caption("Arrivederci")
        self.play_music()
        while game_status["run"] :
            game_status["go_start_menu"]= False
            clock.tick(FPS)
            self.menu_win.blit(self.bg, (0, 0))

            surface = pygame.Surface((WIN_WIDTH, WIN_HEIGHT), pygame.SRCALPHA)
            for btn in self.buttons:
                pygame.draw.rect(surface,(255,255,255,test_transparency),btn.rect)
            self.menu_win.blit(surface, (0, 0))

            x, y = pygame.mouse.get_pos()
            pygame.mouse.set_visible(False)
            self.menu_win.blit(MOUSE, (x, y))
            for event in pygame.event.get():
                # quit
                if event.type == pygame.QUIT:
                    exitWin=ExitWin()
                    exitWin.run()

                if event.type == pygame.MOUSEBUTTONDOWN:
                    # check if hit start btn
                    if self.start_btn.clicked(x, y):
                        self.sound.play()

                        i=True
                        while i:
                            game = Game()
                            game.run()
                            if game_status["restart"]:
                                game_status["restart"]= False
                                i=True
                            else:
                                i=False

                        singleton_map_controller.change_map()

                        self.play_music()

                    if self.opt_btn.clicked(x, y):
                        self.sound.play()
                        opt_menu=OptMenu()
                        opt_menu.run()
                        self.sound.set_volume(singleton_vol_controller.sound_volume)
                        singleton_map_controller.change_map()

                    """(Q1.1) music on/off according to the button"""
                    # (hint) pygame.mixer.music.pause/unpause

            # while cursor is moving (not click)
            """(Q1.2) create button frame and draw"""
            # (hint) use a for loop to go through all the buttons, create the frame, and draw it.
            pygame.display.update()
        pygame.quit()

class Buttons:
    def __init__(self, x:int, y:int, width:int, height:int):
        self.rect = pygame.Rect(x, y, width, height)
        self.frame = None

    def clicked(self, x: int, y: int) -> bool:
        if self.rect.collidepoint(x, y):
            return True
        return False

    def create_frame(self, x: int, y: int):
        """if cursor position is on the button, create button frame"""
        if self.clicked(x, y):
            x, y, w, h = self.rect
            self.frame = pygame.Rect(x - 5, y - 5, w + 10, h + 10)
        else:
            self.frame = None

    def draw_frame(self, win: pygame.Surface):
        if self.frame is not None:
            pygame.draw.rect(win, WHITE, self.frame, 10)