fin = open("city-feature.txt", "r");
ff = [];
feature_num = 109;
for i in range(0,feature_num):
	ff.append(open("feature//" + str(i) + ".txt", "w"));
avg = {};
cnt = {};
var = {};
for i in range(0,feature_num):
	avg[i] = 0.0;
	cnt[i] = 0.0;
	var[i] = 0.0;
max = 0;
for line in fin:
	words = line[0:-1].split("\t");
	avg[int(words[1])] += float(words[2]);
	cnt[int(words[1])] += 1;
	ff[int(words[1])].write(words[0] + " " + words[2] + '\n');
	if (int(words[0]) > max):
		max = int(words[0]);

print(max);

for i in range(0, feature_num):
	avg[i] = avg[i] / cnt[i];
fin = open("city-feature.txt", "r");
for line in fin:
	words = line[0:-1].split("\t");
	a = avg[int(words[1])];
	b = float(words[2]);
	var[int(words[1])] += (b-a) * (b-a);
#	print(var[int(words[1])]);
#print(var);
for i in range(0,feature_num):
	var[i] = var[i] / cnt[i];
s = sorted(var.items(), key = lambda asd:asd[1], reverse = True)
for i in range(0,10):
	print(str(s[i][0]) + "\t" + str(s[i][1]));


# -*- coding: utf-8 -*-
import PyQt5
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtGui import QImage
import cv2, imutils
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset
import sys
import os
import numpy as np
import utils
up_factor = 4

class Ui_MainWindow(PyQt5.QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.fix_selection = 'None'
        self.selection = 'RGB Content-Loss'
        self.lowres_img = None
        self.lowres_input = None
        self.tmp = None
        self.filename = None
        self.prediction = None
        self.image = None
        self.model = None
        self.upfactor = 4

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1, 1)

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")

        self.horizontalLayout_6 = QtWidgets.QVBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")

        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setText("")
        self.label.setObjectName("label")
        self.horizontalLayout_3.addWidget(self.label)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.horizontalLayout_3.addLayout(self.horizontalLayout)
        self.gridLayout.addLayout(self.horizontalLayout_3, 0, 0, 1, 1)

        self.gridLayout.addLayout(self.horizontalLayout_6, 1, 1, 1, 1)
        l1 = QtWidgets.QLabel()
        l1.setText("Color adjustment for SRGAN:")
        self.horizontalLayout_6.addWidget(l1)

        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout_2.addWidget(self.pushButton_2)
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.horizontalLayout_2.addWidget(self.pushButton_3)
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout_2.addWidget(self.pushButton)
        self.gridLayout.addLayout(self.horizontalLayout_2, 1, 0, 1, 1)
        self.gridLayout_3.addLayout(self.horizontalLayout_4, 0, 0, 1, 1)
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        self.gridLayout_3.addLayout(self.gridLayout_2, 0, 1, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusBar)

        self.combobox1 = QtWidgets.QComboBox(self.centralwidget)
        self.combobox1.setFixedSize(200,60)
        self.combobox1.move(15, 1)
        self.combobox1.addItem('RGB Content-Loss')
        self.combobox1.addItem('RGB MSE')
        self.combobox1.addItem('YCbCr Content-Loss')
        self.combobox1.addItem('YCbCr MSE')
        self.combobox1.addItem('RGB GAN Perceptual-Loss')
        self.combobox1.addItem('YCbCr GAN Perceptual-Loss')
        self.combobox1.currentTextChanged.connect(self.text_check)

        self.radiobutton = PyQt5.QtWidgets.QRadioButton("RGB correction")
        self.radiobutton.setChecked(False)
        self.radiobutton.selection = "RGB correction"
        self.radiobutton.toggled.connect(self.onClicked)
        self.horizontalLayout_6.addWidget(self.radiobutton)

        self.radiobutton = PyQt5.QtWidgets.QRadioButton("YCbCr correction")
        self.radiobutton.setChecked(False)
        self.radiobutton.selection = "YCbCr correction"
        self.radiobutton.toggled.connect(self.onClicked)
        self.horizontalLayout_6.addWidget(self.radiobutton)

        self.radiobutton = PyQt5.QtWidgets.QRadioButton("None")
        self.radiobutton.setChecked(True)
        self.radiobutton.selection = "None"
        self.radiobutton.toggled.connect(self.onClicked)
        self.horizontalLayout_6.addWidget(self.radiobutton)

        self.retranslateUi(MainWindow)
        self.pushButton_2.clicked.connect(self.loadImage)
        self.pushButton.clicked.connect(self.superres)
        self.pushButton_3.clicked.connect(self.bicubic)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.filename = None  # Will hold the image address location
        self.tmp = None  # Will hold the temporary image for display

    def onClicked(self):
        radioButton = self.sender()
        if radioButton.isChecked():
            print("Radio button on %s" % (radioButton.selection))
        self.fix_selection = radioButton.selection
    def text_check(self, s):
        print("Model loss text changed:", s)
        self.selection = s

    def loadImage(self):

        self.filename = QFileDialog.getOpenFileName(filter="Image (*.*)")[0]
        self.image = tf.keras.preprocessing.image.load_img(self.filename)
        self.image = tf.keras.preprocessing.image.img_to_array(self.image)
        img_array = self.image.astype("float32") / 255.0

        # Create a new figure with a default 111 subplot.
        fig, ax = plt.subplots()
        im = ax.imshow(img_array[::-1], origin="lower")

        plt.title('Ground Truth')
        plt.axis('off')
        # zoom-factor: 2.0, location: upper-left
        axins = zoomed_inset_axes(ax, 2, loc=2)
        axins.imshow(img_array[::-1], origin="lower")

        # Specify the limits.
        x1, x2, y1, y2 = 200, 300, 100, 200
        # Apply the x-limits.
        axins.set_xlim(x1, x2)
        # Apply the y-limits.
        axins.set_ylim(y1, y2)

        plt.yticks(visible=False)
        plt.xticks(visible=False)

        # Make the line.
        mark_inset(ax, axins, loc1=1, loc2=3, fc="none", ec="blue")
        plt.show()

    def superres(self):

        self.filename = QFileDialog.getOpenFileName(filter="Image (*.*)")[0]
        self.image = tf.keras.preprocessing.image.load_img(self.filename)
        highres_img_arr = tf.keras.preprocessing.image.img_to_array(self.image)
        self.lowres_input = utils.get_lowres_image(self.image, self.upfactor)
        name = 'None'
        if self.selection == 'RGB Content-Loss':
            self.model = keras.models.load_model('models/img_models/rgb_crop_CL_50_x4.h5', compile=False)
            channel = 'rgb'

        if self.selection == 'YCbCr Content-Loss':
            self.model = keras.models.load_model('models/img_models/ycbcr_crop_CL_50_x4.h5', compile=False)
            channel = "ycbcr"

        if self.selection == 'YCbCr MSE':
            self.model = keras.models.load_model('models/img_models/ycbcr_crop_MSE_50_x4.h5', compile=False)
            channel = "ycbcr"

        if self.selection == 'RGB MSE':
            self.model = keras.models.load_model('models/img_models/rgb_crop_MSE_50_x4.h5', compile=False)
            channel = "rgb"

        if self.selection == 'RGB GAN Perceptual-Loss':
            self.model = keras.models.load_model('models/img_models/generator_x4.h5', compile=False)
            name = 'RGB GAN Perceptual-Loss'
            channel = "rgb"

        if self.selection == 'YCbCr GAN Perceptual-Loss':
            self.model = keras.models.load_model('models/img_models/generator_ycbcr_x4.h5', compile=False)
            name = 'YCbCr GAN'
            channel = 'ycbcr'
            pass

        self.prediction = utils.upscale_image(self.model, self.lowres_input, channels=channel)

        img_array = tf.keras.preprocessing.image.img_to_array(self.prediction)
        sr_psnr = tf.image.psnr(img_array, highres_img_arr, max_val=255)

        if self.fix_selection == 'YCbCr correction' and self.selection == 'YCbCr GAN Perceptual-Loss':
            self.selection = self.selection + " with added correction"
            img_array = utils.gan_ycbcr_correction(self.prediction, self.image)
            img_array = tf.keras.preprocessing.image.img_to_array(img_array)
            sr_psnr = tf.image.psnr(img_array, highres_img_arr, max_val=255)
            print('ycbcr gan fix function')

        if (self.fix_selection == 'RGB correction') and (self.selection == 'RGB GAN Perceptual-Loss'):
            self.selection = self.selection + " with added correction"
            img_array = utils.gan_rgb_correction(img_array // 1, self.image)
            sr_psnr = tf.image.psnr(img_array, highres_img_arr, max_val=255)
            print('rgb gan fix function')

        img_array = img_array.astype("float32") / 255.0
        # Create a new figure with a default 111 subplot.
        fig, ax = plt.subplots()
        im = ax.imshow(img_array[::-1], origin="lower")

        plt.title('SR with '+ self.selection + ' | PSNR: ' + str(sr_psnr.numpy()))
        plt.axis('off')
        # zoom-factor: 2.0, location: upper-left
        axins = zoomed_inset_axes(ax, 2, loc=2)
        axins.imshow(img_array[::-1], origin="lower")

        # Specify the limits.
        x1, x2, y1, y2 = 200, 300, 100, 200
        # Apply the x-limits.
        axins.set_xlim(x1, x2)
        # Apply the y-limits.
        axins.set_ylim(y1, y2)

        plt.yticks(visible=False)
        plt.xticks(visible=False)

        # Make the line.
        mark_inset(ax, axins, loc1=1, loc2=3, fc="none", ec="blue")

        filename = QFileDialog.getSaveFileName(filter="JPG(*.jpg);;PNG(*.png);;TIFF(*.tiff);;BMP(*.bmp);;JPEG(*.jpeg)")[0]
        plt.savefig(filename+'superrezzed'+'.png')
        plt.show()

    def bicubic(self):
        self.filename = QFileDialog.getOpenFileName(filter="Image (*.*)")[0]
        self.image = tf.keras.preprocessing.image.load_img(self.filename)
        self.lowres_input = utils.get_lowres_image(self.image, self.upfactor)
        w = self.lowres_input.size[0] * up_factor
        h = self.lowres_input.size[1] * up_factor
        self.lowres_img = self.lowres_input.resize((w, h))
        lowres_img_array = tf.keras.preprocessing.image.img_to_array(self.lowres_img)
        highres_img_arr = tf.keras.preprocessing.image.img_to_array(self.image)
        bicubic_psnr = tf.image.psnr(lowres_img_array, highres_img_arr, max_val=255)
        lowres_img_array = lowres_img_array.astype("float32") / 255.0

       # print(bicubic_psnr)
        # Create a new figure with a default 111 subplot.
        fig, ax = plt.subplots()
        im = ax.imshow(lowres_img_array[::-1], origin="lower")
        #print(bicubic_psnr.numpy())
        plt.title('Bicubic PSNR: ' + str(bicubic_psnr.numpy()))
        plt.axis('off')
        # zoom-factor: 2.0, location: upper-left
        axins = zoomed_inset_axes(ax, 2, loc=2)
        axins.imshow(lowres_img_array[::-1], origin="lower")

        # Specify the limits.
        x1, x2, y1, y2 = 200, 300, 100, 200
        # Apply the x-limits.
        axins.set_xlim(x1, x2)
        # Apply the y-limits.
        axins.set_ylim(y1, y2)

        plt.yticks(visible=False)
        plt.xticks(visible=False)

        # Make the line.
        mark_inset(ax, axins, loc1=1, loc2=3, fc="none", ec="blue")

        filename = QFileDialog.getSaveFileName(filter="JPG(*.jpg);;PNG(*.png);;TIFF(*.tiff);;BMP(*.bmp)")[0]
        plt.savefig(filename + 'Bicubic' + '.png')
        plt.show()

    def img_fix(self):
        pass

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Super Resolution Demo"))
        self.pushButton_2.setText(_translate("MainWindow", "Open"))
        self.pushButton.setText(_translate("MainWindow", "SuperRes Image"))
        self.pushButton_3.setText(_translate("MainWindow", "Bicubic Image"))

if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    score_board = []
    for _ in range(int(input())):
        name = input()
        score = float(input())
        score_board.append([name, score])
    score_board.sort(key=lambda x: (x[1],x[0]))
    names = [i[0] for i in score_board]
    scores = [i[1] for i in score_board]
    min_score = min(scores)
    while scores[0] == min_score:
        scores.remove(scores[0])
        names.remove(names[0])
    for x in range(len(scores)):
        if scores[x]== min(scores):
            print(names[x])


from router import Router
import config as c
import os
import importlib

router = Router()

def load_apps():
    app_names =  os.listdir(c.appsDirectory)
    app_names = [ x for x in app_names if x not in ["__init__.py", "__pycache__"]]
    print(app_names)
    for app in app_names:
        module = importlib.import_module(f'{c.appsDirectory}.{app}')
        for key,value in module.router.routes.items():
            route_object = {
                "route":key,
                **value
            }
            router.add_route(route_object)

load_apps()

letter = {'SuperVision': {'UnderSupervision': 0, 'AdditionalInfo': '', 'Reasons': []}, 'TracingNo': 864583, 'Symbol': 'وکبهمن', 'CompanyName': 'مدیریت سرمایه گذاری کوثر بهمن', 'UnderSupervision': 0, 'Title': 'گزارش فعالیت ماهانه دوره ۱ ماهه منتهی به ۱۴۰۰/۱۲/۲۹', 'LetterCode': 'ن-۳۱', 'SentDateTime': '۱۴۰۱/۰۱/۰۲ ۱۶:۰۰:۲۶', 'PublishDateTime': '۱۴۰۱/۰۱/۰۲ ۱۶:۰۰:۲۶', 'HasHtml': True, 'IsEstimate': False, 'Url': '/Reports/Decision.aspx?LetterSerial=gNsjPbspoFfcRTuttDuQ1g%3D%3D&rt=2&let=8&ct=0&ft=-1', 'HasExcel':
True, 'HasPdf': True, 'HasXbrl': False, 'HasAttachment': False, 'AttachmentUrl': '', 'PdfUrl': 'DownloadFile.aspx?hs=gNsjPbspoFfcRTuttDuQ1g%3d%3d&ft=1005&let=8', 'ExcelUrl': 'https://excel.codal.ir/service/Excel/GetAll/gNsjPbspoFfcRTuttDuQ1g%3d%3d/0',
'XbrlUrl': '', 'TedanUrl': 'http://www.tedan.ir'}

router.letter_handler(letter)


import pandas as pd
import umap
import numpy as np
import copy
# from sklearn.manifold import TSNE
from collections import Counter
import joblib

model_dict={}
def get_mapping_pd(ftr_pd,umapT,ftr):
    try: df_umap=ftr_pd[ftr]
    except: df_umap=ftr_pd[list(map(str,ftr))]
    df_umap1=(df_umap.sample(1)).values
    assert (np.round(df_umap1)==df_umap1).all()
    u_da=umapT.transform(df_umap.values)
    # umapped=pd.DataFrame(u_da, columns=[f"u{ii}" for ii in range(len(u_da[0]))])
    # ftr_pd=pd.concat([ftr_pd,umapped],axis=1)
    for ii in range(len(u_da[0])):
        ftr_pd[f'u{ii+1}'] = u_da[:,ii]
    print(ftr_pd.keys())
    return ftr_pd

def get_HH_subclass_label(HH_pd,label_pd,encode_str='encode',label_str='label',HH_str='HH'):
    labels=[]
    for ii, HH in enumerate(HH_pd[HH_str]):
        label_list=label_pd[label_pd[encode_str]==int(HH)][label_str]
        c=Counter(label_list)
        labels.append(c.most_common(1)[0][0])
    HH_pd[f'{label_str}m']=labels
    return None

###############################SPEC_UMAP###############################

def get_umap_pd(ftr_pd, ftr, n_comp):
    umapT = umap.UMAP(n_components=n_comp,min_dist=0.0,n_neighbors=50, random_state=1178)
    try: df_umap=ftr_pd[ftr]
    except: df_umap=ftr_pd[list(map(str,ftr))]
    umap_result = umapT.fit_transform(df_umap.values)
    for ii in range(n_comp):
        ftr_pd[f'u{ii+1}'] = umap_result[:,ii]
    return umapT

def get_spec_mapping(HH_pd,ftr, df_lbl, base,name,umap_comp,HH_cut=20000):
    df_label=copy.deepcopy(df_lbl)
    HH_pdc=HH_pd[:HH_cut]
    print(len(HH_pdc),len(HH_pd),HH_pdc['freq'].sum(), HH_pdc['freq'][0],HH_pdc['freq'].tail())
    umapT=get_umap_pd(HH_pdc, list(range(len(ftr))), umap_comp)
    for ii in ['class','subclass','l5','l8']:
        get_HH_subclass_label(HH_pdc,df_label,encode_str='encode',label_str=ii,HH_str='HH')
    return HH_pdc,umapT

def get_spec_label(HH_pd, df_lbl):
    df_label=copy.deepcopy(df_lbl)
    for ii in ['class','subclass','l5','l8']:
        get_HH_subclass_label(HH_pd,df_label,encode_str='encode',label_str=ii,HH_str='HH')
    return HH_pd

# def get_spec_mapping(HH_pd,ftr, df_lbl, base,name,HH_cut=20000):
#     df_label=copy.deepcopy(df_lbl)
#     # lb,ub=int(HH_pd['freq'][0]*lbr),int(HH_pd['freq'][0])
#     # HH_pdc=HH_pd[HH_pd['freq']>lb]
#     HH_pdc=HH_pd[:HH_cut]
#     print(len(HH_pdc),len(HH_pd),HH_pdc['freq'].sum(), HH_pdc['freq'][0],HH_pdc['freq'].tail())
#     get_HH_label(HH_pdc,df_label,encode_str='encode',label_str='class',HH_str='HH')
#     HH_pdQS,QS_stats=get_QS_stats(HH_pdc,model_dict,name,pd_key='classU',clusters_str=['QSO','STAR','mixed'])
#     umapT=get_umap_pd(HH_pdQS, list(range(len(ftr))));
# #     sns.scatterplot('u1','u2',data=HH_pdQS)
#     get_HH_label(HH_pdQS,df_label,encode_str='encode',label_str='l5',HH_str='HH')
#     HH_pd5=HH_pdQS[HH_pdQS[f'l5U']!='mixed']
#     stat25=(len(HH_pd5),len(HH_pdQS), len(HH_pd5)/len(HH_pdQS))
#     model_dict[name]['s25']=stat25
#     print(stat25)
#     get_HH_label(HH_pdQS,df_label,encode_str='encode',label_str='l8',HH_str='HH')
#     HH_pd8=HH_pdQS[HH_pdQS[f'l8U']!='mixed']
#     stat58=[len(HH_pd8),len(HH_pdQS), len(HH_pd8)/len(HH_pdQS)]
#     model_dict[name]['s58']=stat58
#     print(stat58)
#     model_dict[name]['HH']=[len(HH_pdc),len(HH_pd),HH_pdc['freq'].sum(), HH_cut]
#     return HH_pdQS,umapT, model_dict

# def get_spec_label(HH_pd, df_lbl,name,HH_cut=20000):
#     df_label=copy.deepcopy(df_lbl)
#     # lb,ub=int(HH_pd['freq'][0]*lbr),int(HH_pd['freq'][0])
#     # HH_pdc=HH_pd[HH_pd['freq']>lb]
#     HH_pdc=HH_pd[:HH_cut]
#     print(len(HH_pdc),len(HH_pd),HH_pdc['freq'].sum(), HH_pdc['freq'][0],HH_pdc['freq'].tail())
#     get_HH_label(HH_pdc,df_label,encode_str='encode',label_str='class',HH_str='HH')
#     # HH_pdQS,QS_stats=get_QS_stats(HH_pdc,model_dict,name,pd_key='classU',clusters_str=['QSO','STAR','mixed'])
#     model_dict={name:{}}
#     HH_pdQS=HH_pdc
#     get_HH_label(HH_pdQS,df_label,encode_str='encode',label_str='l5',HH_str='HH')
#     HH_pd5=HH_pdQS[HH_pdQS[f'l5U']!='mixed']
#     stat25=(len(HH_pd5),len(HH_pdQS), len(HH_pd5)/len(HH_pdQS))
#     model_dict[name]['s25']=stat25
#     print(stat25)
#     get_HH_label(HH_pdQS,df_label,encode_str='encode',label_str='l8',HH_str='HH')
#     HH_pd8=HH_pdQS[HH_pdQS[f'l8U']!='mixed']
#     stat58=[len(HH_pd8),len(HH_pdQS), len(HH_pd8)/len(HH_pdQS)]
#     model_dict[name]['s58']=stat58
#     print(stat58)
#     model_dict[name]['HH']=[len(HH_pdc),len(HH_pd),HH_pdc['freq'].sum(), HH_cut]
#     return HH_pdQS, model_dict

# def get_QS_stats(HH_pd,model_dict,name,pd_key='classU',clusters_str=['QSO','STAR','mixed']):
#     HH_pdh=HH_pd[(HH_pd['class']=='STAR')|(HH_pd['class']=='QSO')|(HH_pd['class']=='QSOSTAR')]
#     N_HH=HH_pdh['freq'].sum()
#     HH_pdQS=HH_pdh[(HH_pdh['classU']!='mixed')]
#     N_Q=(HH_pdh[pd_key]==clusters_str[0]).sum()
#     N_S=(HH_pdh[pd_key]==clusters_str[1]).sum()
#     N_M=(HH_pdh[pd_key]==clusters_str[2]).sum()
#     N_QS, N_A=len(HH_pdQS), len(HH_pdh)
#     print('Heaviness:', N_QS, N_A, N_HH)
#     assert (abs(N_QS-N_Q-N_S)<1e-5) and( abs(N_M+N_QS-N_A)<1e-5)
#     e, p_Q, p_S= N_QS/N_A, N_Q/(N_Q+N_M), N_S/(N_S+N_M)
#     print(f'model:{name} e:{np.round(e*100,1)}%, Q purity: {np.round(p_Q*100,1)}%, S purity: {np.round(p_S*100,1)}%')
#     QS_stats=[e,p_Q,p_S,N_HH]
#     model_dict[name]={"QS":QS_stats}
#     return HH_pdQS,QS_stats

# def get_HH_label(HH_pd,label_pd,encode_str='encode',label_str='label',HH_str='HH'):
#     labels=[]
#     ulabels=[]
#     for ii, HH in enumerate(HH_pd[HH_str]):
#         label=label_pd[label_pd[encode_str]==int(HH)][label_str].unique()
#         lblstr="".join(label.astype(str))
#         labels.append(lblstr)
#         if len(label)>1:
#             ulabels.append('mixed')
#         else:
#             ulabels.append(lblstr)
#     HH_pd[label_str]=labels
#     HH_pd[f'{label_str}U']=ulabels
#     return HH_pd

    # f,axs=plt.subplots(1,3,figsize=(20,8))
    # hues=['classU','l5U','l8U']
    # for ii, ax in enumerate(axs.flatten()):
    #     sns.scatterplot('u1','u2',data=HH_pdQS,hue=hues[ii],ax=ax)
    #     if ii==0: ax.set_title(f'{name}, base{base}', fontsize=16)
    #     if ii==1: ax.set_title(f'{ftr}', fontsize=16)


from math import pi, log, sqrt
import pandas as pd
import numpy as np
from math import pi, log, exp
import matplotlib as mpl; mpl.use("Qt5Agg")
import matplotlib.pyplot as plt

plt.rcParams.update({'font.size': 16})

def collectCoeffsSimple(pressure, temperature):

    # pressure in GPa
    # temperature in degK
    # Cottrell et al 2009

    coeffs = {
        'alpha': 0,
          'beta': 0,
          'chi': 0,
          'delta': 0,
          'epsilon': 0
    }

    if 0 <= pressure <= 3:
        coeffs['alpha'] = 1.11
        coeffs['beta'] = -1.18
        coeffs['chi'] = -0.85
        coeffs['delta'] = 1680
        coeffs['epsilon'] = 487

    elif 3 < pressure:
        coeffs['alpha'] = 1.05
        coeffs['beta'] = -1.10
        coeffs['chi'] = -0.84
        coeffs['delta'] = 3588
        coeffs['epsilon'] = -102

    return coeffs

def partition(pressure, temperature, deltaIW):
    nbo_t = 2.6
    coeffs = collectCoeffsSimple(pressure=pressure, temperature=temperature)
    alpha = coeffs['alpha']
    beta = coeffs['beta']
    chi = coeffs['chi']
    delta = coeffs['delta']
    epsilon = coeffs['epsilon']
    logD = alpha + (beta * deltaIW) + (chi * nbo_t) + (delta * (1/temperature)) + (epsilon * (pressure/temperature))
    D = 10**logD
    return D

def adiabat(current_depth, current_temperature, depth_increment, depth, gravity, thermal_expansion, heat_capacity,
            depth_gradient, adiabat_gradient):
    current_depth += depth_increment
    # dT/dh = (alpha * g * T) / c_p
    current_temperature += ((thermal_expansion * gravity * current_temperature) / heat_capacity) * depth_increment
    adiabat_gradient.append(current_temperature)
    depth_gradient.append(current_depth / 1000)
    if current_depth < depth:  # recursion!
        return adiabat(current_depth, current_temperature, depth_increment, depth, gravity, thermal_expansion,
                       heat_capacity, depth_gradient, adiabat_gradient)
    else:
        return depth_gradient, adiabat_gradient

def hydrostatic(current_depth, depth_increment, depth, gravity, density_melt, current_pressure, depth_gradient,
                pressure_gradient):
    current_depth += depth_increment
    # dP/dh = rho * g
    current_pressure += (density_melt * gravity) * depth_increment
    pressure_gradient.append(current_pressure * (10**(-9)))  # gPa
    depth_gradient.append(current_depth / 1000)
    if current_depth < depth:
        return hydrostatic(current_depth, depth_increment, depth, gravity, density_melt, current_pressure, depth_gradient,
                pressure_gradient)
    else:
        return depth_gradient, pressure_gradient

earth_magma_ocean_depth = 520 * 1000
earth_magma_ocean_depth_increment = 260 * 10
earth_surface_gravity = 9.8

vesta_magma_ocean_depth = 262.8 * 1000
vesta_magma_ocean_depth_increment = 400
vesta_surface_gravity = 0.25

silicate_density = 3750
metal_density = 7800
w_diffusivity = 10**-8
thermal_expansivity = 6 * 10**(-5)
heat_capacity = 10**3

earth_z_eq_eta_35_actual = 23.93 / 1000
earth_z_eq_eta_10_actual = 62.97 / 1000

earth_adiabatic_depths, earth_adiabatic = adiabat(
    current_depth=0 / 1000,  # begin at surface
    current_temperature=2000,  # degrees K
    depth_increment=earth_magma_ocean_depth_increment,  # 10 km interval
    depth=earth_magma_ocean_depth,  # to depth of 250 km
    gravity=earth_surface_gravity,  # m/s^2, Vesta
    thermal_expansion=thermal_expansivity,
    heat_capacity=heat_capacity,
    depth_gradient=[0],  # returns this list at index=0
    adiabat_gradient=[2000],  # returns this list at index=1
)

earth_hydrostatic_depths, earth_hydrostat = hydrostatic(
    current_depth=0 / 1000,
    depth_increment=earth_magma_ocean_depth_increment,
    depth=earth_magma_ocean_depth,
    gravity=earth_surface_gravity,
    current_pressure=0,
    density_melt=silicate_density,
    depth_gradient=[0],
    pressure_gradient=[0],
)

vesta_adiabatic_depths, vesta_adiabatic = adiabat(
    current_depth=0 / 1000,  # begin at surface
    current_temperature=2000,  # degrees K
    depth_increment=vesta_magma_ocean_depth_increment,  # 10 km interval
    depth=vesta_magma_ocean_depth,  # to depth of 250 km
    gravity=vesta_surface_gravity,  # m/s^2, Vesta
    thermal_expansion=thermal_expansivity,
    heat_capacity=heat_capacity,
    depth_gradient=[0],  # returns this list at index=0
    adiabat_gradient=[2000],  # returns this list at index=1
)

vesta_hydrostatic_depths, vesta_hydrostat = hydrostatic(
    current_depth=0 / 1000,
    depth_increment=vesta_magma_ocean_depth_increment,
    depth=vesta_magma_ocean_depth,
    gravity=vesta_surface_gravity,
    current_pressure=0,
    density_melt=silicate_density,
    depth_gradient=[0],
    pressure_gradient=[0],
)

cottrell_model_vesta = []
cottrell_model_earth = []
fO2_list = [-0.8, -1.10, -2.25, -2.45]
for i in fO2_list:
    temp_d_vesta = []
    temp_d_earth = []
    for index, t in enumerate(vesta_hydrostatic_depths):
        pressure = vesta_hydrostat[index]
        temperature = vesta_adiabatic[index]
        d = partition(pressure=pressure, temperature=temperature, deltaIW=i)
        temp_d_vesta.append(d)
    for index, t in enumerate(earth_hydrostatic_depths):
        pressure = earth_hydrostat[index]
        temperature = earth_adiabatic[index]
        d = partition(pressure=pressure, temperature=temperature, deltaIW=i)
        temp_d_earth.append(d)
    cottrell_model_vesta.append(temp_d_vesta)
    cottrell_model_earth.append(temp_d_earth)

print(vesta_adiabatic[-1], earth_adiabatic[-1], vesta_hydrostat[-1], earth_hydrostat[-1])

# adiabatic/hydrostatic gradient figure
fig1 = plt.figure()
ax1_0 = fig1.add_subplot(111)
ax1_1 = fig1.add_subplot(211)
ax1_2 = fig1.add_subplot(212)
ax1_1.plot(vesta_adiabatic_depths, vesta_adiabatic, linewidth=2.0, color='black', label='Vesta')
ax1_2.plot(earth_adiabatic_depths, earth_adiabatic, linewidth=2.0, color='black', label='Earth')
# Turn off axis lines and ticks of the big subplot
ax1_0.spines['top'].set_color('none')
ax1_0.spines['bottom'].set_color('none')
ax1_0.spines['left'].set_color('none')
ax1_0.spines['right'].set_color('none')
ax1_0.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off')
ax1_0.xaxis.labelpad = 20
ax1_0.yaxis.labelpad = 20
ax1_0.set_xlabel("Depth (km)")
ax1_0.set_ylabel("Temperature ($\degree$K)")
ax1_0.set_title("Adiabatic Temperature Profile for Vestian and Earth Magma Ocean")
ax1_1.grid()
ax1_2.grid()
ax1_1.legend(loc='upper left')
ax1_2.legend(loc='upper left')
ax1_1.set_xlim(0, max(vesta_adiabatic_depths))
ax1_2.set_xlim(0, max(earth_adiabatic_depths))

fig4 = plt.figure()
ax4_0 = fig4.add_subplot(111)
ax4_1 = fig4.add_subplot(211)
ax4_2 = fig4.add_subplot(212)
ax4_1.plot(vesta_hydrostatic_depths, vesta_hydrostat, linewidth=2.0, color='black', label='Vesta')
ax4_2.plot(earth_hydrostatic_depths, earth_hydrostat, linewidth=2.0, color='black', label='Earth')
# Turn off axis lines and ticks of the big subplot
ax4_0.spines['top'].set_color('none')
ax4_0.spines['bottom'].set_color('none')
ax4_0.spines['left'].set_color('none')
ax4_0.spines['right'].set_color('none')
ax4_0.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off')
ax4_0.xaxis.labelpad = 20
ax4_0.yaxis.labelpad = 20
ax4_0.set_xlabel("Depth (km)")
ax4_0.set_ylabel("Pressure (GPa)")
ax4_0.set_title("Hydrostatic Pressure Profile for Vestian and Earth Magma Ocean")
ax4_1.grid()
ax4_2.grid()
ax4_1.legend(loc='upper left')
ax4_2.legend(loc='upper left')
ax4_1.set_xlim(0, max(vesta_hydrostatic_depths))
ax4_2.set_xlim(0, max(earth_hydrostatic_depths))

# cottrell partition models for Vesta
fig2 = plt.figure()
ax2_0 = fig2.add_subplot(111)
ax2_1 = fig2.add_subplot(211)
ax2_2 = fig2.add_subplot(212)
# Turn off axis lines and ticks of the big subplot
ax2_0.spines['top'].set_color('none')
ax2_0.spines['bottom'].set_color('none')
ax2_0.spines['left'].set_color('none')
ax2_0.spines['right'].set_color('none')
ax2_0.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off')
ax2_0.xaxis.labelpad = 20
ax2_0.yaxis.labelpad = 20
ax2_0.set_xlabel("Depth (km)")
ax2_0.set_ylabel("D")
ax2_0.set_title("Predicted Partition Coefficients for a Vestian Magma Ocean")
ax2_1.plot(vesta_hydrostatic_depths, cottrell_model_vesta[0], color='black')
ax2_1.plot(vesta_hydrostatic_depths, cottrell_model_vesta[1], color='black')
ax2_1.fill_between(vesta_hydrostatic_depths, cottrell_model_vesta[0], cottrell_model_vesta[1], color='red', alpha=0.4,
                   label="Vesta Oxidizing Model")
ax2_1.grid()
ax2_1.legend(loc='upper right')
ax2_2.plot(vesta_hydrostatic_depths, cottrell_model_vesta[2], color='black')
ax2_2.plot(vesta_hydrostatic_depths, cottrell_model_vesta[3], color='black')
ax2_2.fill_between(vesta_hydrostatic_depths, cottrell_model_vesta[2], cottrell_model_vesta[3], color='red', alpha=0.4,
                   label="Vesta Reducing Model")
ax2_2.grid()
ax2_2.legend(loc='upper right')

# cottrell partition models for Earth
fig3 = plt.figure()
ax3_0 = fig3.add_subplot(111)
ax3_1 = fig3.add_subplot(211)
ax3_2 = fig3.add_subplot(212)
# Turn off axis lines and ticks of the big subplot
ax3_0.spines['top'].set_color('none')
ax3_0.spines['bottom'].set_color('none')
ax3_0.spines['left'].set_color('none')
ax3_0.spines['right'].set_color('none')
ax3_0.tick_params(labelcolor='w', top='off', bottom='off', left='off', right='off')
ax3_0.xaxis.labelpad = 20
ax3_0.yaxis.labelpad = 20
ax3_0.set_xlabel("Depth (km)")
ax3_0.set_ylabel("D")
ax3_0.set_title("Predicted Partition Coefficients for an Earth Magma Ocean")
ax3_1.plot(earth_hydrostatic_depths, cottrell_model_earth[0], color='black')
ax3_1.plot(earth_hydrostatic_depths, cottrell_model_earth[1], color='black')
ax3_1.fill_between(earth_hydrostatic_depths, cottrell_model_earth[0], cottrell_model_earth[1], color='red', alpha=0.5,
                   label="Earth Oxidizing Model")
ax3_1.axvline(earth_z_eq_eta_10_actual, linewidth=2.0, linestyle="--", color='black', label="z$_{eq}$ ($\eta$=10$^{-1.0}$)")
ax3_1.axvline(earth_z_eq_eta_35_actual, linewidth=2.0, linestyle="--", color='red', label="z$_{eq}$ ($\eta$=10$^{-3.5}$)")
ax3_2.axvline(earth_z_eq_eta_10_actual, linewidth=2.0, linestyle="--", color='black', label="z$_{eq}$ ($\eta$=10$^{-1.0}$)")
ax3_2.axvline(earth_z_eq_eta_35_actual, linewidth=2.0, linestyle="--", color='red', label="z$_{eq}$ ($\eta$=10$^{-3.5}$)")
ax3_1.grid()
ax3_1.legend(loc='upper right')
ax3_2.plot(earth_hydrostatic_depths, cottrell_model_earth[2], color='black')
ax3_2.plot(earth_hydrostatic_depths, cottrell_model_earth[3], color='black')
ax3_2.fill_between(earth_hydrostatic_depths, cottrell_model_earth[2], cottrell_model_earth[3], color='red', alpha=0.5,
                   label="Earth Reducing Model")
ax3_2.grid()
ax3_2.legend(loc='upper right')

plt.show()


from django.urls import path, include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
    # version: v1
    path('api/v1/users', include('user.v1.urls')),
    path('api/v1/information', include('information.v1.urls')),

    # admin panel
    path('api/admin', include('admin.urls')),
]

urlpatterns += staticfiles_urlpatterns()


import numpy as np
import sys
import pickle
import tensorflow as tf
from utils import greedy, ep_greedy

def clipped_error(x):
    # Huber loss
    try:
      return tf.select(tf.abs(x) < 1.0, 0.5 * tf.square(x), tf.abs(x) - 0.5)
    except:
      return tf.where(tf.abs(x) < 1.0, 0.5 * tf.square(x), tf.abs(x) - 0.5)

class nn_model:
    def __init__(self, shape, a_list, name, lrate, load = False):
        self.lrate = lrate
        self._name = name
        self._path = 'trained_agents/'
        self.shape = shape
        self.a_list = a_list
        self.w = {}
        self.w_t = {}
        self.assign_op = {}
        self._graph = tf.Graph()
        config = tf.ConfigProto(device_count = {'GPU': 0})
        self._sess = tf.Session(graph=self._graph,config=config)
        try:
            self._build()
        except Exception as e:
            print('Model Initialization Fails! Because {}'.format(e))
        else:
            print('Model Generated!')
        if load == True:
            try:
                self.saver.restore(self._sess, self._path + name)
            except:
                print('Restoring Variables Fails!')
            else:
                print('Model Restored!')
        else:
            self._sess.run(self.init_op)
            print('Model Initialized!')

    def get_loss(self, states, actions, targets):
        if hasattr(self, 'loss'):
            feed_dict = {
                'states:0':states.reshape(list(np.shape(states)) + [1]),
                'actions:0':[self.a_list.index(a) for a in actions],
                'targets:0':targets,
            }
            return self._sess.run(self.loss, feed_dict=feed_dict)
        else:
            print('loss has not been calculated.')

    def __del__(self):
        self._sess.close()

    def _build(self):
        with self._graph.as_default():
            global_step = tf.Variable(0, trainable=False, name='global')
            s = tf.placeholder(dtype=tf.float32, shape=[None] + self.shape + [1], name='states')
            a = tf.placeholder(dtype=tf.uint8, shape=[None], name='actions')
            y = tf.placeholder(dtype=tf.float32, shape=[None], name='targets')
            onehot = tf.one_hot(a, depth=len(self.a_list))
            output_dim = len(self.a_list)
            with tf.variable_scope('train'):
                # conv layer 1
                self.w['l1c1w'] = l1c1w = tf.Variable(
                    tf.truncated_normal([2, 1, 1, 10]) / 100)
                self.w['l1c1b'] = l1c1b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv1 = tf.nn.conv2d(s, l1c1w, [1,1,1,1], 'SAME')
                l1c1 = tf.nn.relu(conv1 + l1c1b)
                self.w['l1c2w'] = l1c2w = tf.Variable(
                    tf.truncated_normal([1, 2, 1, 10]) / 100)
                self.w['l1c2b'] = l1c2b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv2 = tf.nn.conv2d(s, l1c2w, [1,1,1,1], 'SAME')
                l1c2 = tf.nn.relu(conv2 + l1c2b)
                # conv layer 2
                self.w['l2c1w'] = l2c1w = tf.Variable(
                    tf.truncated_normal([1, 2, 10, 10]) / 100)
                self.w['l2c1b'] = l2c1b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv3 = tf.nn.conv2d(l1c1, l2c1w, [1,1,1,1], 'VALID')
                l2c1 = tf.nn.relu(conv3 + l2c1b)
                self.w['l2c2w'] = l2c2w = tf.Variable(
                    tf.truncated_normal([2, 1, 10, 10]) / 100)
                self.w['l2c2b'] = l2c2b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv4 = tf.nn.conv2d(l1c2, l2c2w, [1,1,1,1], 'VALID')
                l2c2 = tf.nn.relu(conv4 + l2c2b)
                # fully connected layer
                L3 = tf.concat([tf.reshape(l2c1, [-1, 120]),
                    tf.reshape(l2c2, [-1, 120])], 1)
                self.w['l3w'] = l3w = tf.Variable(
                    tf.truncated_normal([240, 100]) / 100
                )
                self.w['l3b'] = l3b = tf.Variable(
                    tf.constant(0.01, shape=[100]))
                L4 = tf.nn.relu(tf.matmul(L3,l3w) + l3b)
                self.w['l4w'] = l4w = tf.Variable(
                    tf.truncated_normal([100, output_dim]) / 100
                )
                self.w['l4b'] = l4b = tf.Variable(
                    tf.constant(0.01, shape=[output_dim]))
                self.pred = tf.matmul(L4, l4w) + l4b
                q_act = tf.reduce_sum(self.pred * onehot, reduction_indices=1)
                self.loss = tf.reduce_mean(
                    (q_act  - y)**2) \
                    # + self.lambda_ * (tf.norm(l1w) + tf.norm(l4w))
            with tf.variable_scope('target'):
                # conv layer 1
                self.w_t['l1c1w'] = l1c1w = tf.Variable(
                    tf.truncated_normal([2, 1, 1, 10]) / 100)
                self.w_t['l1c1b'] = l1c1b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv1 = tf.nn.conv2d(s, l1c1w, [1,1,1,1], 'SAME')
                l1c1 = tf.nn.relu(conv1 + l1c1b)
                self.w_t['l1c2w'] = l1c2w = tf.Variable(
                    tf.truncated_normal([1, 2, 1, 10]) / 100)
                self.w_t['l1c2b'] = l1c2b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv2 = tf.nn.conv2d(s, l1c2w, [1,1,1,1], 'SAME')
                l1c2 = tf.nn.relu(conv2 + l1c2b)
                # conv layer 2
                self.w_t['l2c1w'] = l2c1w = tf.Variable(
                    tf.truncated_normal([1, 2, 10, 10]) / 100)
                self.w_t['l2c1b'] = l2c1b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv3 = tf.nn.conv2d(l1c1, l2c1w, [1,1,1,1], 'VALID')
                l2c1 = tf.nn.relu(conv3 + l2c1b)
                self.w_t['l2c2w'] = l2c2w = tf.Variable(
                    tf.truncated_normal([2, 1, 10, 10]) / 100)
                self.w_t['l2c2b'] = l2c2b = tf.Variable(
                    tf.constant(0.01, shape=[10]))
                conv4 = tf.nn.conv2d(l1c2, l2c2w, [1,1,1,1], 'VALID')
                l2c2 = tf.nn.relu(conv4 + l2c2b)
                # fully connected layer
                L3 = tf.concat([tf.reshape(l2c1, [-1, 120]),
                    tf.reshape(l2c2, [-1, 120])], 1)
                self.w_t['l3w'] = l3w = tf.Variable(
                    tf.truncated_normal([240, 100]) / 100
                )
                self.w_t['l3b'] = l3b = tf.Variable(
                    tf.constant(0.01, shape=[100]))
                L4 = tf.nn.relu(tf.matmul(L3,l3w) + l3b)
                self.w_t['l4w'] = l4w = tf.Variable(
                    tf.truncated_normal([100, output_dim]) / 100
                )
                self.w_t['l4b'] = l4b = tf.Variable(
                    tf.constant(0.01, shape=[output_dim]))
                self.pred_t = tf.matmul(L4, l4w) + l4b

            with tf.variable_scope('optimize'):
                optimizer = tf.train.AdamOptimizer(learning_rate=
                    self.lrate)
                # Clip gradient
                # gvs = optimizer.compute_gradients(self.loss, self.w)
                # capped_gvs = [(tf.clip_by_value(grad, -10., 10.), var) for grad, var in gvs]
                # self.train_op = optimizer.apply_gradients(capped_gvs)

                # optimizer = tf.train.GradientDescentOptimizer(
                #     learning_rate=self.lrate
                # )

                # optimizer = tf.train.RMSPropOptimizer(learning_rate = self.lrate)
                self.train_op = optimizer.minimize(loss=self.loss,
                    global_step=global_step)
                self.init_op = tf.global_variables_initializer()
            with tf.variable_scope('assign'):
                for key in self.w.keys():
                    self.assign_op[key] = tf.assign(self.w_t[key], self.w[key])
            self.saver = tf.train.Saver()
        self._graph.finalize()

    def fit(self, states, actions, targets):
        with self._graph.as_default():
            feed_dict = {
                'states:0':states.reshape(list(np.shape(states)) + [1]),
                'actions:0':[self.a_list.index(a) for a in actions],
                'targets:0':targets,
            }
            self._sess.run(self.train_op, feed_dict)

    def update(self):
        for key in self.w.keys():
            self._sess.run(self.assign_op[key])

    # evaluate the trained network
    def Q(self, state):
        feed_dict = {
            'states:0': np.array(state).reshape([1] + list(np.shape(state)) + [1]),
        }
        return self._sess.run(self.pred, feed_dict)[0]

    # evaluate the target network
    def Qhat(self, state):
        feed_dict = {
            'states:0': np.array(state).reshape([1] + list(np.shape(state)) + [1]),
        }
        return self._sess.run(self.pred_t, feed_dict)[0]

    def save(self):
        self.saver.save(self._sess, self._path + self._name)

class memory(list):
    def __init__(self,length):
        self.length = length
        super().__init__()
    def add(self,x):
        if len(self) < self.length:
            super().append(x)
        elif len(self) == self.length:
            super().pop(0)
            super().append(x)
    def sample(self,size):
        output = np.random.choice(self,size)
        return output

class dqn_agent:
    '''
        The agent can play the game and train it self using DQN.
    '''
    def __init__(self, params, load = False):
        self._path = 'trained_agents/'
        if load:
            self.load(**params)
        else:
            self.new(**params)
        self.Q = self.model.Q
        self.Qhat = self.model.Qhat
        self.ep = lambda x: self.ep_start - min(self.ep_rate *
            (max(x - self.learn_starts, 0)), self.ep_start - self.ep_end)
        self.game_para = {'size': 4, 'odd_2': 0.9}

    def new(self, name, N, shape, ep_start, ep_end, ep_rate, batch_size,
        a_list, C, lrate, gamma = 1, learn_starts = 5):
        self.name = name
        self.shape = shape
        self.ep_start = ep_start
        self.ep_end = ep_end
        self.ep_rate = ep_rate
        self.batch_size = batch_size
        self.a_list = a_list
        self.C = C
        self.lrate = lrate
        self.gamma = gamma
        self.learn_starts = learn_starts

        self.D = memory(N)
        self.nA = len(a_list)
        self.model = nn_model(shape, a_list, name, lrate) # implement two networks in one model with an update method.
        self.iter = 0
        self.episode = 0

    def load(self, name):
        with open(self._path + name + '-params','rb') as f:
            params = pickle.load(f)
            self.name = name
            self.shape = params['shape']
            self.ep_start = params['ep_start']
            self.ep_end = params['ep_end']
            self.ep_rate = params['ep_rate']
            self.batch_size = params['batch_size']
            self.a_list = params['a_list']
            self.C = params['C']
            self.lrate = params['lrate']
            self.gamma = params['gamma']
            self.learn_starts = params['learn_starts']

            self.nA = params['nA']
            self.iter = params['iter']
            self.episode = params['episode']
        with open(self._path + name + '-memory','rb') as f:
            self.D = pickle.load(f)
        self.model = nn_model(self.shape, self.a_list, name, self.lrate, load=True)

    def save(self):
        with open(self._path + self.name + '-memory','wb') as f:
            pickle.dump(self.D, f)
        with open(self._path + self.name + '-params', 'wb') as f:
            params = {
                'shape': self.shape,
                'ep_start': self.ep_start,
                'ep_end': self.ep_end,
                'ep_rate': self.ep_rate,
                'batch_size': self.batch_size,
                'a_list': self.a_list,
                'C': self.C,
                'lrate': self.lrate,
                'gamma': self.gamma,
                'learn_starts': self.learn_starts,
                'nA': self.nA,
                'iter': self.iter,
                'episode': self.episode,
            }
            pickle.dump(params, f)
        self.model.save()

    def perceive(self, observation):
        self.iter += 1
        if observation['done']:
            self.episode += 1
        self.D.add(observation)

    def train_action(self, state):
        return self.a_list[ep_greedy(self.Q, state, self.ep(self.episode))]

    def play_action(self, state):
        return self.a_list[greedy(self.Q, state)]

    def train(self):
        if self.episode < self.learn_starts:
            return 0
        batch = self.D.sample(self.batch_size)
        y = np.empty(self.batch_size)
        s_batch = []
        a_batch = []
        for idx in range(self.batch_size):
            if batch[idx]['done']:
                y[idx] = batch[idx]['r']
            else:
                y[idx] = batch[idx]['r'] + \
                    self.gamma * max(self.Qhat(batch[idx]['ss']))
            s_batch += [batch[idx]['s']]
            a_batch += [batch[idx]['a']]
        self.model.fit(np.array(s_batch), np.array(a_batch), y)
        if self.iter % 100 == 0:
            loss = self.model.get_loss(np.array(s_batch), np.array(a_batch), y)
            print('episode: {}, loss: {:<.4}  '.format(
                        self.episode, loss))
        if self.iter % self.C == self.C - 1:
            self.model.update()


# decrypt the ciphertext

CIPHERFILE = "ciphertext"

enc_flag = open(CIPHERFILE, 'r').readline()

parts = [
        enc_flag[:enc_flag.index('{')],
        '{',
        enc_flag[enc_flag.index('{')+1:enc_flag.index('}')],
        '}'
        ]
enc = parts[2]

# just a nice way of printing out the flag
assemble = lambda x: "".join([parts[0], parts[1], x, parts[3]])

import string

ALPHABET = string.ascii_lowercase
OFFSET = ord('a')

# making sure the encrypted flag is within the alphabet
assert all([e in ALPHABET for e in enc])

# shift by distance
def shiftd(p, dist, ALPHA=ALPHABET, OFF=OFFSET):
    # shifting the letters to the start of the alphabet
    a = ord(p) - OFF # plaintext

    # returning the shifted character
    return ALPHA[(a + dist) % len(ALPHA)]

# shift by character
def shiftc(p, k, ALPHA=ALPHABET, OFF=OFFSET):
    # shifting the letters to the start of the alphabet
    a = ord(p) - OFF # plaintext
    b = ord(k) - OFF # key

    # returning the shifted character
    return ALPHA[(a + b) % len(ALPHA)]

# string shift
def sshift(s, mod, ALPHA=ALPHABET, OFF=OFFSET):
    move = None
    if isinstance(mod, int):
        move = shiftd
    elif isinstance(mod, str):
        move = shiftc
    else:
        return -1

    # applying the shift
    return "".join(
            list(
                map(lambda x: move(x, mod, ALPHA=ALPHA, OFF=OFF), s)))

# trying to brute force the cipher
for i in range(len(ALPHABET)):
    r = sshift(enc, i)
    print("shift by %2d -> %s" % (i, assemble(r)))


# Jonathan Burgess
# First made: 2/1/2022
# Last update: 2/8/2022
# This program is to calculate the displacement in a global from an origin in a local frame.

import math as m                                            # library math needed for sin and cos functions

theta = float(0)                                            # initialize variables as floats
xdis = float(0)
ydis = float(0)

x = float(input("Initial Global X Displacement: "))         # input the local frame x origin
y = float(input("Initial Global Y Displacement: "))         # input the local frame y origin

more = "Y"

while more == "y" or more == "Y":                           # while loop is for multiple displacements
    theta = float(input("Heading angle in degrees: "))      # input the heading angle relative to global x axis
    theta = theta*m.pi/180                                  # convert degree to radian
    xdis = float(input("Local X displacement: "))           # input the x displacement
    ydis = float(input("Local Y displacement: "))           # input the y displacement
    x += m.cos(theta)*xdis - m.sin(theta)*ydis              # calculate the new x position in global frame
    y += m.sin(theta)*xdis + m.cos(theta)*ydis              # calculate the new y position in global frame
    print("Current Global X Coordinate:", x)                # print new x coordinate
    print("Current Global Y Coordinate:", y)                # print new y coordinate
    more = input("Continue? (Y/N)")                         # ask to continue movement

print("\nFinal global coordinates are:")                    # print final x and y global coordinates
print("(", x, ",", y, ")")


#!/usr/bin/env python
import os
import time

import numpy as np
from astropy.io import fits

from aoide import voronoi

import argparse

def main():

    print("\n=======================   Aoide | Step 3   ====================\n")
    print("AoideVoronoi.py: Voronoi Tesselation based on Stellar Continuum Signal\n")

    args = parse_args()

    input_cube = os.path.abspath(args.input_cube)
    name = args.name
    continuum_signal_band = args.band_continuum
    target_sn = args.sn
    max_area = args.max_area

    working_directory = os.path.dirname(os.path.abspath(input_cube))
    voronoi_directory = working_directory + "/voronoi/"

    if not os.path.exists(voronoi_directory):
        os.makedirs(voronoi_directory)
        print("Voronoi Products Directory {} not found. Creating it.".format(
            voronoi_directory))
    else:
        print("Voronoi products will be saved to {}".format(voronoi_directory))

    # Change to Voronoi directory
    os.chdir(voronoi_directory)
    print("Working directory set to {}".format(voronoi_directory))

    # Work on input cube
    hdu = fits.open(input_cube)
    data = hdu[0].data
    select = np.isnan(data)
    data[select] = 0
    error = np.sqrt(hdu[1].data)
    error[select] = 1e9
    hdr = hdu[0].header
    wave = np.arange(hdr['NAXIS3']) * 1.25 + hdr['CRVAL3']
    hdu.close()
    select_wave = (wave > continuum_signal_band[0]) & (
        wave < continuum_signal_band[1])
    mean_img = np.mean(data[select_wave, :, :], 0)
    err_img = np.std(data[select_wave, :, :], 0)

    # Create CONTINUUM SIGNAL and NOISE samples on which to iterate
    hdu = fits.PrimaryHDU(mean_img)
    hdu.writeto('signal_cont.fits', overwrite=True)

    hdu = fits.PrimaryHDU(err_img)
    hdu.writeto('noise_cont.fits', overwrite=True)

    voronoi.binning_fits('signal_cont.fits', voronoi_directory + 'noise_cont.fits',
                         target_sn, name, max_area=max_area, gersho=True, plot=False)

    bin_cube('{}.voronoi.pixel.dat'.format(name),
             input_cube, '{}.voronoi_rss.fits'.format(name))

    return voronoi_directory

def bin_cube(voronoi_pixel, input_cube, output_rss):
    hdu = fits.open(input_cube)
    data = hdu[0].data
    select = np.isnan(data)
    data[select] = 0
    error = np.sqrt(hdu[1].data)
    error[select] = 1e9
    hdr = hdu[0].header
    wave = np.arange(hdr['NAXIS3']) * 1.25 + hdr['CRVAL3']
    hdu.close()

    ascii_in = open(voronoi_pixel, 'r')
    lines = ascii_in.readlines()
    x = np.arange(len(lines) - 1, dtype=np.int16)
    y = np.arange(len(lines) - 1, dtype=np.int16)
    binNr = np.arange(len(lines) - 1, dtype=np.int16)
    for i in range(1, len(lines)):
        line = lines[i].split()
        x[i - 1] = int(line[0])
        y[i - 1] = int(line[1])
        binNr[i - 1] = int(line[2])

    rss_data = np.zeros((max(binNr), len(wave)), dtype=np.float32)
    rss_error = np.zeros((max(binNr), len(wave)), dtype=np.float32)

    for l in range(max(binNr)):
        select_bin = binNr == (l + 1)
        x_bin = x[select_bin] - 1
        y_bin = y[select_bin] - 1
        for j in range(len(x_bin)):
            rss_data[l, :] += data[:, y_bin[j], x_bin[j]]
            rss_error[l, :] += error[:, y_bin[j], x_bin[j]]**2
        rss_error[l, :] = np.sqrt(rss_error[l, :])
    rss_error[np.isnan(rss_error)] = 1e9
    rss_out = fits.HDUList([fits.PrimaryHDU(rss_data), fits.ImageHDU(
        rss_error, name='ERROR'), fits.ImageHDU(np.zeros(rss_data.shape, dtype=np.uint16), name='MASK')])
    rss_out[0].header = hdr
    rss_out[0].header['CDELT1'] = 1.25
    rss_out[0].header['CRVAL1'] = hdr['CRVAL3']
    rss_out[0].header['CRPIX1'] = 1
    rss_out.writeto(output_rss, overwrite=True, output_verify='fix')

def parse_args():

    parser = argparse.ArgumentParser(
        description="Voronoi bin a clean MUSE datacube based on S/N in the stellar continuum.")

    parser.add_argument('input_cube', metavar='CUBE_IN', type=str, nargs='?',
                        help='Input FITS MUSE cube to bin.')

    parser.add_argument('-n', '--name', metavar='GALAXY_NAME', default='NAME_OF_GALAXY', type=str,
                        nargs='?', help='Name of your galaxy.')

    parser.add_argument('-b', '--band_continuum', nargs='?', default=(6427, 6632),
                        help='Wavelength range, in Angstroms, of a line-free region of stellar continuum signal. Express as a tuple, e.g. (6427, 6632).')

    parser.add_argument('-s', '--sn', type=int, nargs='?',
                        default=50, help='Signal-to-noise ratio used for Voronoi threshold. Default is 50.')

    parser.add_argument('-m', '--max_area', type=int, nargs='?',
                        default=1000, help='Maximum area, in pixels, for any given Voronoi bin. ')

    args = parser.parse_args()

    return args

if __name__ == '__main__':

    start_time = time.time()
    voronoi_directory = main()
    runtime = round((time.time() - start_time), 3)
    print("\n=================    Aoide | Step 3 Finished   ================\n")
    print("Finished in {} minutes.".format(round(runtime / 60, 3)))
    print("Use the Voronoi-binned cube as part of your Paradise STELLAR fitting.")
    print("You'll find these products in {}.".format(voronoi_directory))


import tensorflow as tf
from keras.optimizer_v2 import optimizer_v2
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.ops import state_ops
class AccAdam(optimizer_v2.OptimizerV2):
  def __init__(self,
               accumulation_steps=1,
               learning_rate=0.001,
               beta_1=0.9,
               beta_2=0.999,
               epsilon=1e-7,
               name='AccAdam',
               **kwargs):
    super(AccAdam, self).__init__(name, **kwargs)
    self._set_hyper('accumulation_steps', accumulation_steps)
    self._set_hyper('learning_rate', kwargs.get('lr', learning_rate))
    self._set_hyper('decay', self._initial_decay)
    self._set_hyper('beta_1', beta_1)
    self._set_hyper('beta_2', beta_2)
    self._set_hyper('epsilon', epsilon)

  def _create_slots(self, var_list):
    for var in var_list: self.add_slot(var, 'm')
    for var in var_list: self.add_slot(var, 'v')
    for var in var_list: self.add_slot(var, 'g')

  def _prepare_local(self, var_device, var_dtype, apply_state):
    super(AccAdam, self)._prepare_local(var_device, var_dtype, apply_state)

    accumulation_steps = self._get_hyper('accumulation_steps', self.iterations.dtype)

    update_cond = tf.equal((self.iterations + 1) % accumulation_steps, 0)
    sub_step = self.iterations % accumulation_steps + 1
    local_step = math_ops.cast(self.iterations // accumulation_steps + 1, var_dtype)

    learning_rate = array_ops.identity(self._get_hyper('learning_rate', var_dtype))
    epsilon = array_ops.identity(self._get_hyper('epsilon', var_dtype))
    beta_1_t = array_ops.identity(self._get_hyper('beta_1', var_dtype))
    beta_2_t = array_ops.identity(self._get_hyper('beta_2', var_dtype))

    beta_1_power = math_ops.pow(beta_1_t, local_step)
    beta_2_power = math_ops.pow(beta_2_t, local_step)
    lr = learning_rate * math_ops.sqrt(1-beta_2_power)/(1-beta_1_power)

    apply_state[(var_device, var_dtype)].update(
        dict(
            lr=lr,
            update_cond=update_cond,
            sub_step=sub_step,
            epsilon=epsilon,
            beta_1_t=beta_1_t,
            beta_1_power=beta_1_power,
            one_minus_beta_1_t=1 - beta_1_t,
            beta_2_t=beta_2_t,
            beta_2_power=beta_2_power,
            one_minus_beta_2_t=1 - beta_2_t))

  def _resource_apply_dense(self, grad, var, apply_state=None):
    var_device, var_dtype = var.device, var.dtype.base_dtype
    coefficients = ((apply_state or {}).get((var_device, var_dtype))
                    or self._fallback_apply_state(var_device, var_dtype))

    accumulation_steps = self._get_hyper('accumulation_steps', self.iterations.dtype)
    update_cond = coefficients['update_cond']
    sub_step = coefficients['sub_step']
    eps = coefficients['epsilon']

    m = self.get_slot(var, 'm')
    v = self.get_slot(var, 'v')
    g = self.get_slot(var, 'g')

    grad = grad / math_ops.cast(accumulation_steps, var_dtype)
    g_t = tf.where(tf.equal(sub_step,1), grad, g + (grad-g)/math_ops.cast(sub_step, var_dtype))
    m_t = tf.where(update_cond, m * coefficients['beta_1_t'] + g_t * coefficients['one_minus_beta_1_t'], m)
    v_t = tf.where(update_cond, v * coefficients['beta_2_t'] + (g_t * g_t) * coefficients['one_minus_beta_2_t'], v)
    var_t = tf.where(update_cond, coefficients['lr'] * m_t/(math_ops.sqrt(v_t) + eps), tf.zeros_like(grad))

    var_update = state_ops.assign_sub(var, var_t, use_locking=self._use_locking)
    m_update = state_ops.assign(m, m_t, use_locking=self._use_locking)
    v_update = state_ops.assign(v, v_t, use_locking=self._use_locking)
    g_update = state_ops.assign(g, g_t, use_locking=self._use_locking)
    return control_flow_ops.group(*[var_update, m_update, v_update, g_update])

  def get_config(self):
    config = super(AccAdam, self).get_config()
    config.update({
        'accumulation_steps': self._serialize_hyperparameter('accumulation_steps'),
        'learning_rate': self._serialize_hyperparameter('learning_rate'),
        'decay': self._serialize_hyperparameter('decay'),
        'beta_1': self._serialize_hyperparameter('beta_1'),
        'beta_2': self._serialize_hyperparameter('beta_2'),
        'epsilon':self._serialize_hyperparameter('epsilon'),
    })
    return config


#!/usr/bin/env python
from create_nrPDB_GO_annot import read_fasta
from biotoolbox.structure_file_reader import build_structure_container_for_pdb
from biotoolbox.contact_map_builder import DistanceMapBuilder
from Bio.PDB import PDBList

import numpy as np
import argparse
import time

def make_distance_maps(pdbfile, chain=None, sequence=None):
    pdb_handle = open(pdbfile, 'r')
    structure_container = build_structure_container_for_pdb(pdb_handle.read(), chain).with_seqres(sequence)

    mapper = DistanceMapBuilder(atom="CA", glycine_hack=-1)
    ca = mapper.generate_map_for_pdb(structure_container)
    cb = mapper.set_atom("CB").generate_map_for_pdb(structure_container)
    pdb_handle.close()

    return ca.chains, cb.chains

import csv
from collections import defaultdict

def load_GO_annot(filename):
    onts = ['molecular_function', 'biological_process', 'cellular_component']
    prot2annot = {}
    goterms = {ont: [] for ont in onts}
    gonames = {ont: [] for ont in onts}
    with open(filename, mode='r') as tsvfile:
        reader = csv.reader(tsvfile, delimiter='\t')

        for ont in onts:
            next(reader, None)
            goterms[ont] = next(reader)
            next(reader, None)
            gonames[ont] = next(reader)

        next(reader, None)
        for row in reader:
            prot, prot_goterms = row[0], row[1:]
            prot2annot[prot] = {ont: [] for ont in onts}
            for i in range(3):
                prot2annot[prot][onts[i]] = [goterm for goterm in prot_goterms[i].split(',') if goterm != '']
    return prot2annot, goterms, gonames

def retrieve_pdb(pdb, chain, chain_seqres, pdir):
    pdb_list = PDBList()
    pdb_list.retrieve_pdb_file(pdb, pdir=pdir)
    ca, cb = make_distance_maps(pdir + '/' + pdb+'.cif', chain=chain, sequence=chain_seqres)
    return ca[chain]['contact-map'], cb[chain]['contact-map']

def load_list(fname):
    pdb_chain_list = set()
    fRead = open(fname, 'r')
    for line in fRead:
        pdb_chain_list.add(line.strip())
    fRead.close()
    return pdb_chain_list

def write_annot_npz(prot, prot2seq, out_dir):
    pdb, chain = prot.split('-')
    print('pdb=', pdb, 'chain=', chain)
    try:
        A_ca, A_cb = retrieve_pdb(pdb.lower(), chain, prot2seq[prot], pdir=out_dir + 'tmp_PDB_files_dir')
        np.savez_compressed(out_dir + '/' + prot,
                            C_alpha=A_ca,
                            C_beta=A_cb,
                            seqres=prot2seq[prot],
                            )
    except Exception as e:
        print(e)

if __name__ == '__main__':
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-annot', type=str, default='./data/nrPDB-GO_annot.tsv', help="Input file (*.tsv) with preprocessed annotations.")
    parser.add_argument('-seqres', type=str, default='./data/pdb_seqres.txt.gz', help="PDB chain seqres fasta.")
    parser.add_argument('-num_threads', type=int, default=20, help="Number of threads (CPUs) to use in the computation.")
    parser.add_argument('-bc', type=str, default='./data/clusters-by-entity-95.txt', help="Clusters of PDB chains computed by Blastclust.")
    parser.add_argument('-out_dir', type=str, default='./data/annot_pdb_chains_npz/', help="Output directory with distance maps saved in *.npz format.")
    args = parser.parse_args()

    prot2goterms, _, _ = load_GO_annot(args.annot)
    print ("### number of annotated proteins: %d" % (len(prot2goterms)))

    prot2seq = read_fasta(args.seqres)
    print ("### number of proteins with seqres sequences: %d" % (len(prot2seq)))

    import glob
    npz_pdb_chains = glob.glob(args.out_dir + '*.npz')
    npz_pdb_chains = [chain.split('/')[-1].split('.')[0] for chain in npz_pdb_chains]

    to_be_processed = list(prot2goterms.keys())
    to_be_processed = list(set(to_be_processed).difference(npz_pdb_chains))
    print ("Number of pdbs to be processed=", len(to_be_processed))
    print (to_be_processed)

    nprocs = args.num_threads
    out_dir = args.out_dir
    import multiprocessing
    nprocs = min(nprocs, multiprocessing.cpu_count())

    if nprocs > 4:
        pool = multiprocessing.Pool(processes=nprocs)
        pool.starmap(write_annot_npz, zip(to_be_processed, [prot2seq]*len(to_be_processed), [out_dir]*len(to_be_processed)))
    else:
        for prot in to_be_processed:
            write_annot_npz(prot, prot2seq, out_dir)


import socket
from datetime import datetime
import threading
import time
import random
import busio
import digitalio
import board
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn

#SERVER details=======================
SERVER_IP = '192.168.1.196'
SERVER_PORT = 5005
#20 is sufficiently large for our format
BUFF_SIZE = 20
#Flag for turning sending on/off
send_flag = True
#Stores time of last sample (sent with status)
lastsample = None
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#=======================

#Global rate to be sampled by the thread method
rate = 10
#Global channels to be sampled by the thread method
chan = None
chan1 = None

#======================
def main():
    global chan, chan1, rate,s,send_flag

    btn_num = 25

    #Server connection
    s.connect((SERVER_IP, SERVER_PORT))

    #HARDWARE============================================================
    # create the spi bus
    spi = busio.SPI(clock=board.SCLK, MISO=board.MISO, MOSI=board.MOSI)

    # create the cs (chip select)
    cs = digitalio.DigitalInOut(board.D5)

    #create button instance as an digital input
    btn = digitalio.DigitalInOut(board.D25)
    btn.direction = digitalio.Direction.INPUT
    btn.pull = digitalio.Pull.UP

    #Create the mcp object
    mcp = MCP.MCP3008(spi, cs)

    # create an analog input channel on pin 2 - Light sensor
    chan = AnalogIn(mcp, MCP.P2)

    # create an analog input channe on pin 1 - Temperature sensor
    chan1 = AnalogIn(mcp, MCP.P1)

    #THREADING===========================================================
    #Start thread with dedicated method, no args
    thread = threading.Thread(target=sample_thread)
    thread.daemon = True
    thread.start()

    #RECEIVING==============================================================
    while True:
        #Wait to receive server responses
        server_msg = s.recv(BUFF_SIZE)
        #Decode responses to text
        server_msg = server_msg.decode('utf-8')
        #Retreive command character
        cmd = server_msg[0]

        if(cmd == "O"):
            #O - turn sending/sensor on
            send_flag = True
        elif(cmd == "F"):
            #F - turn sending/sensor off
            send_flag = False
        elif(cmd == "K"):
            #K - call method to return current status
            sendstatus()
        elif(cmd == "X"):
            #X - server closing -> client closes
            print("Client exiting...")
            quit()
    #====================================================================

def sample_thread():
    #Thread method to sample values and send data over TCP repetitively
    while(True):
        lgt = chan.value
        tmp = round(chan1.voltage*100)
        #Send sampled values if flag enabled (sensor 'on')
        if(send_flag):
            senddata(lgt,tmp)

        #Wait for 10s
        time.sleep(rate)

#SENDING=================================================================
#Send state of send_flag variable (sensor status) and time of last sample
def sendstatus():
    #T - message code of 'STATUS' message
    char = "T"
    #Default value if no previous sample
    if lastsample == None: message = str(send_flag) + "#XX:XX:XX"
    else: message = str(send_flag) + "#" + lastsample
    length = len(message)
    message = char + " " + str(length) + " " + message
    #Message format: <cmd> <length> <flag>#<time>
    s.send(str.encode(message))

def senddata(lgt,tmp):
    global lastsample
    #S - message code of 'SENSOR' data message
    char = "S"
    message = str(lgt) + "#" + str(tmp)
    length = len(message)
    message = char + " " + str(length) + " " + message
    #Message format: <cmd> <length> <light>#<temp>
    s.send(str.encode(message))

    #Note time as the new latest sample
    lastsample = str(datetime.now().time())[0:8]
#==================================================================

if __name__ == '__main__':
    main()


import requests
import json
import time
import os
import shutil
import random

from utils import read_file, walk_dir, log_notify

class WallSetter:
    def __init__(self, api_key):
        self.api_key = api_key
        self.files = []
        self.image_dict = {}
        self.max_retries = 5
        self.curr_retries = 1
        self.output_file = os.path.join(os.path.dirname(__file__), "../download.txt")
        self.paths = [
            "../../../../../mnt/Files/Important Files/Wallpapers/2020-6-10/",
            "../../../../../mnt/Files/Important Files/Wallpapers/Anime Wallpapers/My Walls",
            "../../../../../home/genuine/.config/wallhaven_pics/",
        ]

    def request(self, request_url: str, retry=False):
        if retry:
            self.curr_retries += 1
            if self.curr_retries > self.max_retries:
                print("Max retries reached")
                return

        r = requests.get(request_url)

        if r.status_code == 429:
            print("Rate limit reached. Sleeping for 1 minute")
            time.sleep(60)

            print("Retrying")
            self.request(request_url, retry=True)

        elif r.status_code == 200:
            data = json.loads(r.content)
            image_urls = [value.get("path") for value in data.get("data")]

            print(f"Total images: {len(image_urls)}")

            for image in image_urls:
                image_id = image.split("/")[-1]
                if image_id not in self.files:
                    self.image_dict[image_id] = image

        else:
            print("Request failed with status code: " + r.status_code)

    def generate_wallpaper_index(self, paths: list[str]):
        file_list = []

        for path in paths:
            files = walk_dir(path)
            file_list.extend(files)

        return list(set(file_list))

    def generate_wallhaven_index(self, pages: int):
        self.files = self.generate_wallpaper_index(self.paths)

        for i in range(1, pages + 1):
            print("Scanning page: " + str(i))

            request_url = f"https://wallhaven.cc/api/v1/search?q=@rootkit&categories=010&purity=111&atleast=1920x1080&sorting=views&order=desc&ratios=landscape&ai_art_filter=1&page={i}&apikey={self.api_key}"
            self.request(request_url)

        self.write_index(self.output_file)

    def write_index(self, filename):
        with open(filename, mode="w") as file:
            for id, value in self.image_dict.items():
                if id not in self.files:
                    file.write(f"{id}:{value}\n")

    def get_random_wallpaper(self) -> str:
        images = read_file(self.output_file)

        while True:
            counter = 0
            idx = random.randint(0, len(images))
            image = images[idx]
            image_id = image.split(":", 1)[0]
            if image_id not in self.files:
                return image
            else:
                counter += 1
                log_notify("Skipping wallpaper" + image_id)

                if counter > 100:
                    log_notify("Many files in downloads.txt are already downloaded")
                    break

        return "Invalid"

    def download_and_save_wallpaper(self, image: str):
        image_id, url = image.split(":", 1)

        self.files = self.generate_wallpaper_index(self.paths)

        home = os.path.expanduser("~")
        file = f"{home}/.config/wallhaven_pics/{image_id}"

        if image_id not in self.files:
            self.request_wallpaper(url, file, image_id)
        else:
            log_notify(f"Skipping download of" + image_id)

        return file

    def request_wallpaper(self, url: str, path: str, image_id: str):
        max_tries = 5

        for i in range(0, max_tries):
            print("Downloading image:" + image_id)

            r = requests.get(
                f"{url}?apikey={self.api_key}",
                stream=True,
                headers={
                    "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36"
                },
            )

            if r.status_code == 200:
                with open(path, "wb+") as f:
                    r.raw.decode_content = True
                    shutil.copyfileobj(r.raw, f)

                    return
            elif r.status_code == 429:
                print("Rate limit reached. Sleeping for 1 minute")
                time.sleep(60)

                print("Retrying")
            else:
                print(f"Failed request with code: {r.status_code}")
                return

        print("Max retries reached. Skipping wallpaper")

    def set_wallpaper(self, file: str):
        os.system(f"wal -i {file} && qtile cmd-obj -o cmd -f reload_config")

    def bulk_image_download(self):
        home = os.path.expanduser("~")
        download_path = f"{home}/.config/wallhaven_pics/"

        for image_id, url in self.image_dict.items():
            if image_id not in self.files:
                self.request_wallpaper(url, f"{download_path}{image_id}", image_id)


import numpy as np
from pylops.LinearOperator import aslinearoperator
from pylops.basicoperators import SecondDerivative

def Laplacian(dims, dirs=(0, 1), weights=(1, 1), sampling=(1, 1),
              edge=False, dtype='float64'):
    r"""Laplacian.

    Apply second-order centered Laplacian operator to a multi-dimensional
    array (at least 2 dimensions are required)

    Parameters
    ----------
    dims : :obj:`tuple`
        Number of samples for each dimension.
    dirs : :obj:`tuple`, optional
        Directions along which laplacian is applied.
    weights : :obj:`tuple`, optional
        Weight to apply to each direction (real laplacian operator if
        ``weights=[1,1]``)
    sampling : :obj:`tuple`, optional
        Sampling steps for each direction
    edge : :obj:`bool`, optional
        Use reduced order derivative at edges (``True``) or
        ignore them (``False``)
    dtype : :obj:`str`, optional
        Type of elements in input array.

    Returns
    -------
    l2op : :obj:`pylops.LinearOperator`
        Laplacian linear operator

    Notes
    -----
    The Laplacian operator applies a second derivative along two directions of
    a multi-dimensional array.

    For simplicity, given a two dimensional array, the Laplacian is:

    .. math::
        y[i, j] = (x[i+1, j] + x[i-1, j] + x[i, j-1] +x[i, j+1] - 4x[i, j])
                  / (dx*dy)

    """
    l2op = weights[0]*SecondDerivative(np.prod(dims), dims=dims, dir=dirs[0],
                                       sampling=sampling[0],
                                       edge=edge, dtype=dtype)
    l2op += weights[1]*SecondDerivative(np.prod(dims), dims=dims, dir=dirs[1],
                                        sampling=sampling[1],
                                        edge=edge, dtype=dtype)
    return aslinearoperator(l2op)


from flask import Flask, request

app = Flask(__name__)

@app.route("/", methods=['GET','POST'])
def index():
    return "Welcome to the flask world!"

#Enviar um post ou get na http://url/shutdown faz o sistema dar shutdown e desligar o flask
@app.route("/shutdown", methods=['GET','POST'])
def shutdown_server():
    print("Shutdown context hit with POST!")
    shutdown = request.environ.get('werkzeug.server.shutdown')
    if shutdown is None:
        raise RuntimeError('The function is unavailable!')
    else:
        shutdown()
        return "The server is shutting down!"

def main():
    app.run(port = 8081, host = '127.0.0.1', threaded = True)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        #shutdown_server()
        print('Server is shutdown!')
    except Exception as e:
        #shutdown_server()
        print('Exception error: Server is shutdown!')


import os
import pandas as pd
import spacy
from sklearn.feature_extraction.text import CountVectorizer
import datetime
import numpy as np

from processing import get_annee_scolaire

if __name__ == "__main__":

    #print("files", os.listdir("data_processed"))

    ##########################
    # Chargement des données
    ##########################

    path_g = os.path.join("data_processed", "greves.pk")
    g = pd.read_pickle(path_g)
    g["ind"] = g.ind.map(lambda x: 1 if x == "GREVE" else 0)
    g = g[["taux_grevistes", "nos", "ind", "greves_manquantes"]]

    path_m = os.path.join("data_processed", "menus.pk")
    m = pd.read_pickle(path_m)

    path_fe = os.path.join("data_processed", "frequentation_effectif.pk")
    fe = pd.read_pickle(path_fe)

    path_ferie = os.path.join("data_processed", "feries.pk")
    feries = pd.read_pickle(path_ferie)

    path_vacs = os.path.join("data_processed", "vacances.pk")
    vacances = pd.read_pickle(path_vacs)

    path_epidemies = os.path.join("data_processed", "epidemies.pk")
    epidemies = pd.read_pickle(path_epidemies)

    path_religions = os.path.join("data_processed", "religions.pk")
    religions = pd.read_pickle(path_religions)

    ##########################
    # Join sur les dates des différentes BDD
    ##########################

    df = fe.groupby("date")[["prevision", "reel", "effectif"]].sum().join(g).join(m).join(feries).join(vacances).join(epidemies).join(religions)

    ##########################
    # Remplacement des valeurs manquantes
    ##########################

    for col in df.isnull().sum()[df.isnull().sum()>0].index.drop("menu"):
        df[col] = df[col].fillna(0)
    df["menu"] = df["menu"].map(lambda x: x if type(x) == list else [])

    ####################################
    # Ajout des jours, mois semaines, année scolaire, repas noel
    ####################################
    dic_jour = {0: "Lundi", 1: "Mardi", 2: "Mercredi", 3: "Jeudi", 4: "Vendredi", 5: "Samedi", 6: "Dimanche"}
    dic_mois = {1: "Janvier", 2: "Fevrier", 3: "Mars", 4: "Avril", 5: "Mai", 6: "Juin", 7: "Juillet", 8: "Aout",
                9: "Septembre", 10: "Octobre", 11: "Novembre", 12: "Decembre"}

    df["jour"] = df.index.weekday
    df["jour"] = df["jour"].apply(lambda x: dic_jour[x])
    df["semaine"] = df.index.week
    df["mois"] = df.index.month
    df["mois"] = df["mois"].apply(lambda x: dic_mois[x])
    df["annee_scolaire"] = df.index.to_series().map(get_annee_scolaire)

    date_repas_noel = ["2012-12-20", "2013-12-19", "2014-12-18", "2015-12-17", "2016-12-15",
                       "2017-12-21", "2018-12-20"]
    l_noel = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in date_repas_noel]

    df_noel = pd.DataFrame(l_noel, columns=["date"])
    df_noel["repas_noel"] = 1
    df = df.join(df_noel.set_index("date"))
    df["repas_noel"] = df["repas_noel"].fillna(0)

    ####################################
    # Ajout du gaspillage
    ####################################

    assert df.isnull().sum().sum() == 0

    df["gaspillage_volume"] = df["prevision"] - df["reel"]
    df["gaspillage_pourcentage"] = 100 * (df["prevision"] - df["reel"]) / df["prevision"]

    ####################################
    # Ajout des variables liées au menu
    ####################################

    nlp = spacy.load("fr_core_news_sm")
    corpus = df['menu'].apply(lambda x: "".join([i + " " for i in x]))
    corpus = corpus.dropna()

    # stop_word
    liste = ['04', '10', '17', '18225', '2015', '2016', '220gr', '268', '29', '500', '500g', '5kg', '850''500', '500g',
             '5kg', '850', 'ab', 'an', 'au', 'aux', 'avec', 'baut', 'bbc', 'de', 'des', 'du', 'en', 'et', 'gr', 'kg',
             'la', 'le', 'les', 'ou', 'par', 's17', 'sa', 'sans', 'ses', 'son']

    # Create CountVectorizer object
    vectorizer = CountVectorizer(strip_accents='ascii', stop_words=liste, lowercase=True, ngram_range=(1, 1))

    # Generate matrix of word vectors
    bow_matrix = vectorizer.fit_transform(corpus)

    # Convert bow_matrix into a DataFrame
    bow_df = pd.DataFrame(bow_matrix.toarray())

    # Map the column names to vocabulary
    bow_df.columns = vectorizer.get_feature_names()
    bow_df.index = df.index

    # feature porc
    l_porc = ["carbonara", "carbonata", "cassoulet", "chipo", "chipolatas", "choucroute",
              "cordon", "croziflette", "francfort", "jambon", "knacks", "lardons", "porc", "rosette",
              "saucisse", "saucisses", "tartiflette"]

    df["porc"] = sum([bow_df[alim] for alim in l_porc])
    df['porc'] = df['porc'] > 0
    df['porc'] = df['porc'].astype('int')

    # feature viande
    l_viande = ["roti", "agneau", "blanquette", "boeuf", "boudin", "boulettes",
                "bourguignon", "bourguignonne", "canard", "carne", "chapon", "colombo",
                "couscous", "dinde", "escalope", "farci", "foie", "kebab", "lapin", "merguez",
                "mouton", "napolitaines", "nuggets", "paupiette", "pintade",
                "poulet", "steak", "stogonoff", "strogonoff", "tagine", "tajine",
                "veau", "viande", "volaile", "volaille", "carbonara", "carbonata", "cassoulet", "chipo", "chipolatas",
                "choucroute",  "cordon", "croziflette", "francfort", "jambon", "knacks", "lardons", "porc", "rosette",
                "saucisse", "saucisses", "tartiflette", "parmentier"]

    df["viande"] = sum([bow_df[alim] for alim in l_viande])
    df['viande'] = df['viande'] > 0
    df['viande'] = df['viande'].astype('int')

    df = df.reset_index().rename(columns = {"index":"date"})

    l_index = ["2018-01-22", "2017-10-09", "2017-05-09", "2016-10-18", "2016-04-25", "2015-05-26", "2014-11-24",
             "2014-05-26", "2014-03-31", "2014-01-20", "2012-01-16", "2012-01-30", "2012-07-02", "2012-10-01",
             "2011-01-17", "2011-01-31", "2011-09-13", "2015-06-22", "2015-01-19", "2014-06-30", "2012-06-18",
             "2011-06-20"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "viande"] = 1

    # traitement particulier des lasagnes napolitaines pour éviter les confusions avec les lasagnes de poisson
    l_index = ["2016-02-22", "2016-02-04", "2015-11-23", "2015-11-17", "2015-10-05",
             "2015-05-04", "2015-01-26", "2014-12-15", "2013-09-23", "2012-10-09", "2012-05-21", "2012-02-27",
             "2011-11-03", "2011-09-05", "2011-05-09", "2012-12-10", "2013-12-02", "2014-05-12", "2016-05-09"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "viande"] = 1

    # traitement particulier de certains termes qui peuvent être utilisés pour du poisson ou de la viande sautés, chili, pot au feu, bolognaise, courgette farcie,ravioli
    l_index = ["2016-01-28", "2016-03-17", "2016-03-07", "2015-09-15", "2012-12-06", "2012-05-03", "2012-02-09",
             "2011-11-03",
             "2011-09-13", "2011-06-07", "2011-04-04", "2014-06-12", "2012-11-12", "2015-06-22"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "viande"] = 1

    # traitement particulier pour parmentier végétale, steack de soja
    l_index = ["2019-11-25", "2014-06-20"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "viande"] = 0

    # feature poisson
    l_poisson = ["poissons", "sardines", "perray", "thon", "calamar", "lieu", "colin", "crabe", "crevette", "crustace",
                 "dorade", "maquereau", "poisson", "rillette", "sardine", "saumon"]

    df["poisson"] = sum([bow_df[alim] for alim in l_poisson])
    df['poisson'] = df['poisson'] > 0
    df['poisson'] = df['poisson'].astype('int')
    df['poisson'][(df['viande'] == 1) & (df['poisson'] == 1)] = np.zeros(
        len(df['poisson'][(df['viande'] == 1) & (df['poisson'] == 1)]))

    # traitement particulier parmentier poisson #nuggets de poisson,steack de soja et sale au thon, carbo de saumon
    l_index = ["2019-05-17", "2019-05-17", "2019-02-01", "2018-11-23", "2018-10-19", "2018-09-14", "2018-06-05",
             "2018-03-27", "2018-01-16", "2017-12-01", "2017-09-22", "2017-05-05", "2016-05-03", "2016-02-26",
             "2016-01-15", "2015-11-20", "2015-09-22", "2015-09-08", "2015-06-05", "2014-09-08", "2014-03-25",
             "2014-02-18", "2014-01-24", "2013-12-10", "2013-11-29", "2013-10-01", "2012-12-14", "2012-10-19",
             "2012-09-21", "2012-03-16", "2012-01-20", "2011-09-09", "2011-03-18", "2019-03-08"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "viande"] = 0
        df.loc[df[df["date"] == i].index, "poisson"] = 1

    # traitement particulier paella de la mer, filet
    l_index = ['2011-01-10', '2012-01-09', '2011-01-07', "2012-01-06"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "poisson"] = 1

    # 2 menus : végé et viande, on considère que c'est un menu végé
    l_index = ["2015-11-13", "2015-09-11"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "poisson"] = 0
        df.loc[df[df["date"] == i].index, "viande"] = 0

    # 2 menus : poisson et viande, on considère que c'est un menu poisson
    l_index = ["2015-11-20", "2015-10-16", "2015-10-02", "2015-09-25", "2015-09-18", "2015-09-04", "2015-06-25",
             "2015-06-11"]
    index = [datetime.datetime.strptime(x, '%Y-%m-%d') for x in l_index]

    for i in index:
        df.loc[df[df["date"] == i].index, "poisson"] = 1
        df.loc[df[df["date"] == i].index, "viande"] = 0

    # menu inconnu, mais probablement avec viande d'après le modèle
    df.loc[df[df["date"] == datetime.datetime.strptime("2015-10-15", "%Y-%m-%d")].index, "viande"] = 1

    # feature bio
    df['bio'] = bow_df["bio"]

    # set date as index
    df = df.set_index("date")

    ###############################################################
    # Ajout des 4 premiers et 4 derniers jours de l'année scolaire (grosse incertitude)
    #############################################################

    ind = []
    temp = []
    subset = df.copy()

    #print("subset", subset["annee_scolaire"].unique()[1:])

    for i in range(1, 5):

        for annee in subset["annee_scolaire"].unique()[1:]:
            temp.append(min(subset[(subset.index.year == min(subset[subset["annee_scolaire"] == annee].index.year)) & (
                        subset["annee_scolaire"] == annee)].index))
            df.loc[temp, "4_premiers_jours"] = 1
            ind.append(temp)

            subset.drop(temp, inplace=True)
            temp = []

    for i in range(1, 5):

        for annee in subset["annee_scolaire"].unique()[:-1]:
            temp.append(max(subset[(subset.index.year == max(subset[subset["annee_scolaire"] == annee].index.year)) & (
                        subset["annee_scolaire"] == annee)].index))
            df.loc[temp, "4_derniers_jours"] = 1
            ind.append(temp)

            subset.drop(temp, inplace=True)
            temp = []
    df["4_derniers_jours"].fillna(0, inplace=True)
    df["4_premiers_jours"].fillna(0, inplace=True)

    ####################################
    # Tests (longueur et valeurs manquantes)
    ####################################

    assert len(df) == 1188

    df.to_pickle("data_processed/global.pk")
    df.to_excel("data_processed/global.xlsx")


GOLD = 'Annotations'
TRAIN = '/train'
DEV = '/dev'

def load_gold(g_name):
    with open(g_name, 'r') as file:
        return {line.split()[0]: line.split()[1:3] for line in file}

def eval_pred_with_gold(preds, golds):
    good = bad = 0.0
    for pred, gold in zip(preds, golds):
        good += 1 if pred == gold else 0
        bad += 1 if pred != gold else 0
    print("precision: " + str(100 * (good / (good + bad))))


# Helper functions for working with KFAS output

import numpy as np
import pandas as pd
from statsmodels.tools.tools import Bunch

def parse(path, ssm):
    # Dimensions
    n = ssm.nobs
    p = ssm.k_endog
    m = ssm.k_states
    r = ssm.k_posdef

    p2 = p**2
    m2 = m**2
    mp = m * p
    r2 = r**2

    # Extract the different pieces of output from KFAS
    kfas = pd.read_csv(path)
    components = [('r', m), ('r0', m), ('r1', m),
                  ('N', m2), ('N0', m2), ('N1', m2), ('N2', m2),
                  ('m', p), ('v', p), ('F', p), ('Finf', p),
                  ('K', mp), ('Kinf', mp), ('a', m), ('P', m2),
                  ('Pinf', m2), ('att', m), ('Ptt', m2),
                  ('alphahat', m), ('V', m2), ('muhat', p),
                  ('V_mu', p2), ('etahat', r), ('V_eta', r2), ('epshat', p),
                  ('V_eps', p), ('llf', 1)]
    dta = {}
    ix = 0
    for key, length in components:
        dta[key] = kfas.iloc[:, ix:ix + length].fillna(0)
        dta[key].name = None
        ix += length

    # Reformat the KFAS output to compare with statsmodels output
    res = Bunch()
    d = len(kfas['Pinf_1'].dropna())

    # forecasts
    res['forecasts'] = dta['m'].values[:n].T
    res['forecasts_error'] = dta['v'].values[:n].T
    res['forecasts_error_cov'] = np.c_[
        [np.diag(x) for y, x in dta['F'].iloc[:n].iterrows()]].T
    res['forecasts_error_diffuse_cov'] = np.c_[
        [np.diag(x) for y, x in dta['Finf'].iloc[:n].iterrows()]].T

    res['kalman_gain'] = dta['K'].values[:n].reshape(n, m, p, order='F').T
    res['Kinf'] = dta['Kinf'].values[:n].reshape(n, m, p, order='F')

    # filtered
    res['filtered_state'] = dta['att'].values[:n].T
    res['filtered_state_cov'] = dta['Ptt'].values[:n].reshape(
        n, m, m, order='F').T
    # predicted
    res['predicted_state'] = dta['a'].values.T
    res['predicted_state_cov'] = dta['P'].values.reshape(
        n + 1, m, m, order='F').T
    res['predicted_diffuse_state_cov'] = dta['Pinf'].values.reshape(
        n + 1, m, m, order='F').T
    # loglike
    # Note: KFAS only gives the total loglikelihood
    res['llf_obs'] = dta['llf'].values[0, 0]

    # smoothed
    res['smoothed_state'] = dta['alphahat'].values[:n].T
    res['smoothed_state_cov'] = dta['V'].values[:n].reshape(
        n, m, m, order='F').T

    res['smoothed_measurement_disturbance'] = dta['epshat'].values[:n].T
    res['smoothed_measurement_disturbance_cov'] = np.c_[
        [np.diag(x) for y, x in dta['V_eps'].iloc[:n].iterrows()]].T
    res['smoothed_state_disturbance'] = dta['etahat'].values[:n].T
    res['smoothed_state_disturbance_cov'] = dta['V_eta'].values[:n].reshape(
        n, r, r, order='F').T

    # scaled smoothed estimator
    # Note: we store both r and r0 together as "scaled smoothed estimator"
    # while "scaled smoothed diffuse estimator" corresponds to r1
    res['scaled_smoothed_estimator'] = np.c_[dta['r0'][:d].T,
                                             dta['r'][d:].T][..., 1:]
    res['scaled_smoothed_diffuse_estimator'] = dta['r1'].values.T

    N0 = dta['N0'].values[:d].reshape(d, m, m, order='F')
    N = dta['N'].values[d:].reshape(n + 1 - d, m, m, order='F')
    res['scaled_smoothed_estimator_cov'] = np.c_[N0.T, N.T][..., 1:]
    # Have to do a more precise transpose for these since they may not be
    # symmetric
    res['scaled_smoothed_diffuse1_estimator_cov'] = dta['N1'].values.reshape(
        n + 1, m, m, order='F').transpose(1, 2, 0)
    res['scaled_smoothed_diffuse2_estimator_cov'] = dta['N2'].values.reshape(
        n + 1, m, m, order='F').transpose(1, 2, 0)

    # Save the results object for the tests
    return res


# from pokecenter import Pokecenter
# from pokestore import Pokestore
# from trainer import Trainer
# from pokemon import Pokemon
import numpy as np

class Map(object):

    def __init__(self):
        self.generateGrassMap()

    """CREATE MAP FILE FILLED WITH GRASS"""
    def generateGrassMap(self):
        f = open("newMap.txt", "a")
        for a in range(0,42):
            for b in range(0,41):
                f.write("G")
                f.write(" ")
            f.write("G")
            f.write("\n")
        f.close()

map = Map()


import sys
import math
input=sys.stdin.readline

def isPrime(n):
    if n<2:
        return False
    for i in range(2,int(math.sqrt(n))+1):
        if n%i==0:
            return False
    return True
def dfs(num):
    if len(str(num))==n: # 자릿수가 n이라면 출력
        print(num)
    else:
        for i in range(10):
            t=10*num+i
            if isPrime(t):
                dfs(t)
n=int(input())
# 어차피 소수인 한자릿수는 2,3,5,7밖에 없음
dfs(2)
dfs(3)
dfs(5)
dfs(7)

백준/Gold/2023. 신기한 소수/신기한 소수.py


import preprocessing
import util as utils
import pandas as pd
import numpy as np

def test_join_label():
    # Arrange
    config = utils.load_config()

    mock_data = {
        "categori" : [
            "BAIK", "TIDAK SEHAT", "TIDAK SEHAT", "SEDANG", "BAIK", "SEDANG"]}
    mock_data = pd.DataFrame(mock_data)
    expected_data = {
        "categori" : [
            "BAIK", "TIDAK BAIK", "TIDAK BAIK", "TIDAK BAIK", "BAIK", "TIDAK BAIK"]}
    expected_data = pd.DataFrame(expected_data)

    # Act
    processed_data = preprocessing.join_label_categori(mock_data, config)

    # Assert
    assert processed_data.equals(expected_data)

def test_nan_detector():
    # Arrange
    mock_data = {"pm10" : [23, -1, 50, 53, -1, 20]}
    mock_data = pd.DataFrame(mock_data)
    expected_data = {"pm10" : [23, np.nan, 50, 53, np.nan, 20]}
    expected_data = pd.DataFrame(expected_data)

    # Act
    processed_data = preprocessing.nan_detector(mock_data)

    # Assert
    assert processed_data.equals(expected_data)

def test_ohe_transform():
    # Arrange
    config = utils.load_config()
    ohe_object = utils.pickle_load(config["ohe_stasiun_path"])
    mock_data = {
        "stasiun" : [
            "DKI1 (Bunderan HI)", "DKI2 (Kelapa Gading)",
            "DKI3 (Jagakarsa)", "DKI4 (Lubang Buaya)",
            "DKI5 (Kebon Jeruk) Jakarta Barat"]}
    mock_data = pd.DataFrame(mock_data)
    expected_data = {
        "DKI1 (Bunderan HI)" : [1, 0, 0, 0, 0], "DKI2 (Kelapa Gading)" : [0, 1, 0, 0, 0], "DKI3 (Jagakarsa)" : [0, 0, 1, 0, 0], "DKI4 (Lubang Buaya)" : [0, 0, 0, 1, 0], "DKI5 (Kebon Jeruk) Jakarta Barat" : [0, 0, 0, 0, 1]}
    expected_data = pd.DataFrame(expected_data)
    expected_data = expected_data.astype(float)

    # Act
    processed_data = preprocessing.ohe_transform(mock_data, "stasiun", ohe_object)

    # Assert
    assert processed_data.equals(expected_data)

def test_le_transform():
    # Arrange
    config = utils.load_config()
    mock_data = {"categori" : ["BAIK", "TIDAK BAIK", "TIDAK BAIK", "TIDAK BAIK", "BAIK", "TIDAK BAIK"]}
    mock_data = pd.DataFrame(mock_data)
    expected_data = {"categori" : [0, 1, 1, 1, 0, 1]}
    expected_data = pd.DataFrame(expected_data)
    expected_data = expected_data.astype(int)

    # Act
    processed_data = preprocessing.le_transform(mock_data["categori"], config)
    processed_data = pd.DataFrame({"categori" : processed_data})

    # Assert
    assert processed_data.equals(expected_data)


"""
5.2 Операторы break, continue и else

Подвиг 7. Вводится натуральное число n. Вывести первое найденное натуральное число
(то есть, перебирать числа, начиная с 1), квадрат которого больше значения n.
Реализовать программу с использованием цикла while.

Sample Input: 10
Sample Output: 4
"""

num = int(input()) # Пользовательский ввод информации
count = 1 # Счетчик

while True:
    if num < count**2: # Если число меньше квадрата счетчика
        print(count) # Выводим результат и прерываем работу цикла
        break
    else: # Иначе увеличиваем счетчик на 1
        count += 1