import curses
import math
import re

from pyful import look
from pyful import util

from pyful.widget.base import Widget

class ListBox(Widget):
    scroll_type = "HalfScroll"
    zoom = 0
    keymap = None

    def __init__(self, title=None):
        Widget.__init__(self, title)
        self.list = []
        self.title = title
        self.cursor = 0
        self.scrolltop = 0
        self.lb = 0
        self.maxrow = 1

    def zoombox(self, amount):
        if amount == 0:
            self.zoom = 0
        else:
            self.zoom += amount
        self.refresh()

    def refresh(self):
        y, x = self.stdscr.getmaxyx()
        odd = y % 2
        base_y = y//2 + odd
        height = base_y + self.zoom
        if height > y-2:
            height = y - 2
            self.zoom = height - base_y
        elif height < 3:
            height = 3
            self.zoom = height - base_y
        self.panel.resize(height, x, y-height-2, 0)
        self.panel.attr = look.colors["ListBoxWindow"]

    def show(self, entries, pos=None):
        if pos is None:
            pos = self.lb
        self.cursor = pos
        self.scrolltop = 0
        self.list = entries
        self.panel.show()

    def hide(self):
        self.cursor = 0
        self.scrolltop = 0
        self.list = []
        self.panel.hide()

    def mvscroll(self, amount):
        if not self.panel.win:
            return
        y, x = self.panel.win.getmaxyx()
        height = (y-2)*self.maxrow
        amount *= self.maxrow
        bottom = self.scrolltop+height
        if amount > 0:
            if bottom >= len(self.list):
                return
            self.scrolltop += amount
            if self.cursor < self.scrolltop:
                self.cursor += amount
        else:
            if self.scrolltop == 0:
                return
            self.scrolltop += amount
            bottom += amount
            if self.cursor >= bottom:
                self.cursor += amount

    def mvcursor(self, amount):
        self.cursor += amount
        if self.cursor < self.lb:
            self.cursor = len(self.list) - 1
        elif self.cursor >= len(self.list):
            self.cursor = 0

    def cursordown(self):
        self.mvcursor(self.maxrow)

    def cursorup(self):
        self.mvcursor(-self.maxrow)

    def setcursor(self, dist):
        if self.lb <= dist < len(self.list):
            self.cursor = dist

    def settop(self):
        self.cursor = 0

    def setbottom(self):
        self.cursor = len(self.list) - 1

    def pagedown(self):
        if not self.panel.win:
            return
        height = (self.panel.win.getmaxyx()[0]-2) * self.maxrow
        if self.scrolltop+height >= len(self.list):
            return
        self.scrolltop += height
        self.cursor += height

    def pageup(self):
        if self.scrolltop == 0 or not self.panel.win:
            return
        height = (self.panel.win.getmaxyx()[0]-2) * self.maxrow
        self.scrolltop -= height
        self.cursor -= height

    def cursor_entry(self):
        if 0 <= self.cursor < len(self.list):
            return self.list[self.cursor]
        else:
            return Entry("")

    def input(self, key):
        if key in self.keymap:
            self.keymap[key]()

    def _fix_position(self, size, height, listcount):
        if self.cursor >= size:
            self.cursor = 0
        elif self.cursor < self.lb:
            self.cursor = size - 1

        if self.cursor < self.scrolltop or \
                self.cursor >= self.scrolltop+listcount:
            if self.scroll_type == "HalfScroll":
                self.scrolltop = (self.cursor//self.maxrow*self.maxrow
                                  - height//2*self.maxrow)
            elif self.scroll_type == "PageScroll":
                self.scrolltop = self.cursor//listcount * listcount
            elif self.scroll_type == "ContinuousScroll":
                if self.cursor >= self.scrolltop+listcount:
                    self.scrolltop = (self.cursor//self.maxrow*self.maxrow
                                      + self.maxrow - listcount)
                else:
                    self.scrolltop = self.cursor//self.maxrow*self.maxrow
            else:
                self.scrolltop = self.cursor - height//2*self.maxrow

        if self.scrolltop < 0 or size < height:
            self.scrolltop = 0
        elif self.scrolltop >= size:
            self.scrolltop = size//height * height

    def _draw_titlebar(self, win, size, listcount):
        if not self.title:
            return
        if self.cursor < 0:
            cpage = 1
        else:
            cpage = self.cursor//listcount + 1
        maxpage = int(math.ceil(float(size)/float(listcount)))
        win.addstr(0, 2, "{0}({1}) [{2}/{3}]".format
                   (self.title, size, cpage, maxpage),
                   look.colors["ListBoxTitle"])

    def _draw_scrollbar(self, win, size, height, listcount, x_offset):
        if size <= listcount:
            return
        line = 1 + int(float(self.scrolltop) / float(size-listcount) * height)
        if line >= height:
            line = height
        for i in range(1, height+1):
            if i == line:
                win.addstr(i, x_offset, "=")
            elif i == 1 or i == height:
                win.addstr(i, x_offset, "+")
            else:
                win.addstr(i, x_offset, "|")

    def draw(self):
        if not self.list:
            return
        self.panel.create_window()
        win = self.panel.win
        size = len(self.list)
        y, x = win.getmaxyx()
        height = y - 2
        width = x - 4
        listwidth = width // self.maxrow
        listcount = height * self.maxrow

        self._fix_position(size, height, listcount)

        win.erase()
        win.border(*self.borders)
        self._draw_titlebar(win, size, listcount)
        self._draw_scrollbar(win, size, height, listcount, x-2)

        line = row = 0
        for i in range(self.scrolltop, size):
            if row >= self.maxrow:
                row = 0
                line += 1
                if line >= height:
                    break
            win.move(line+1, row*listwidth+2)
            entry = self.list[i]
            if self.cursor == i:
                entry.attr += curses.A_REVERSE
                entry.addstr(win, listwidth)
                entry.attr -= curses.A_REVERSE
            else:
                entry.addstr(win, listwidth)
            row += 1
        win.noutrefresh()

class Entry(object):
    __slots__ = ["text", "histr", "attr", "hiattr"]

    def __init__(self, text, histr=None, attr=0, hiattr=None):
        if hiattr is None:
            hiattr = look.colors["CandidateHighlight"]
        self.text = text
        self.histr = histr
        self.attr = attr
        self.hiattr = hiattr

    def addstr(self, win, width):
        text = util.mbs_ljust(self.text, width)
        self.addtext(win, text)

    def addtext(self, win, text):
        if self.histr:
            r = re.compile(r"({0})".format(re.escape(self.histr)))
            for s in r.split(text):
                if r.match(s):
                    win.addstr(s, self.attr | self.hiattr)
                else:
                    win.addstr(s, self.attr)
        else:
            win.addstr(text, self.attr)


#
# @lc app=leetcode id=204 lang=python3
#
# [204] Count Primes
#

# @lc code=start
class Solution:
    def countPrimes(self, n: int) -> int:
        is_prime = [True] * n
        for i in range(2, int(n ** 0.5) + 1):
            if is_prime[i]:
                for j in range(i * i, n, i):
                    is_prime[j] = False
        return len([x for x in range(2, n, 1) if is_prime[x]])

# @lc code=end


import metview as mv

# get data
use_mars = False
if use_mars:
    # retrieve data from MARS
    ret_core = {
        "date": 20200822,
        "time": 0,
        "area": [40, -93, 51, -84],
        "grid": [0.5, 0.5],
    }

    # forecast fields on all the model levels (bottom=ML-137, top=ML-1)
    # Note= log surface pressure (lnsp) is defined on ML-1!
    fs_ml = mv.retrieve(
        **ret_core,
        type="fc",
        levtype="ml",
        levelist=[1, "TO", 137],
        step=12,
        param=["t", "q", "lnsp"]
    )

    # surface geopotential is available in
    # the analysis only! It is available on ML-1!
    zs = mv.retrieve(**ret_core, type="an", levtype="ml", levelist=1, param="z")
else:
    # read data from GRIB file
    filename = "xs_ml_orog.grib"
    if mv.exist(filename):
        fs_ml = mv.read(filename)
    else:
        fs_ml = mv.gallery.load_dataset(filename)
    zs = mv.read(data=fs_ml, param="z")

# extract ml data
t = mv.read(data=fs_ml, param="t")
q = mv.read(data=fs_ml, param="q")
lnsp = mv.read(data=fs_ml, param="lnsp")

# compute geopotential on model levels
z = mv.mvl_geopotential_on_ml(t, q, lnsp, zs)

# define cross section line
line = [50.21, -91.82, 40.82, -84.71]

# define bottom level (m)
bottom_level = 0

# extract a set of levels needed for the cross section
# and converts temperature from K to C and z to m
t = mv.read(data=t, levelist=[137, "TO", 100]) - 273.16
z = mv.read(data=z, levelist=[137, "TO", 100]) / 9.81

# compute cross section in height (above sea level) for t
# (using z, paramId=129)
xs_t = mv.mcross_sect(
    data=mv.merge(t, z),
    line=line,
    vertical_coordinates="user",
    vertical_coordinate_param=129,
    vertical_coordinate_extrapolate="on",
)

# generate orography area curve
orog_curve = mv.xs_build_orog(xs_t, zs / 9.81, bottom_level, "charcoal")

# define contour shading for temperature
cont = mv.mcont(
    legend="on",
    contour_line_colour="charcoal",
    contour_highlight="off",
    contour_level_selection_type="interval",
    contour_max_level=23.5,
    contour_min_level=16.5,
    contour_interval=0.5,
    contour_shade="on",
    contour_shade_method="area_fill",
    contour_shade_max_level_colour="red",
    contour_shade_min_level_colour="green",
    contour_shade_colour_direction="clockwise",
)

# define vertical axis
vertical_axis = mv.maxis(
    axis_orientation="vertical",
    axis_title_text="Height ASL (m)",
    axis_tick_label_height=0.4,
)

# define cross section in height above sea level  (m)
xs_view = mv.mxsectview(
    line=line, top_level=1000, bottom_level=bottom_level, vertical_axis=vertical_axis
)

# define legend
legend = mv.mlegend(legend_text_font_size=0.35)

# define title
title = mv.mtext(text_font_size=0.4)

# define the output plot file
mv.setoutput(mv.pdf_output(output_name="cross_section_height_ml_orog"))

# generate plot
mv.plot(xs_view, xs_t, cont, orog_curve, legend, title)


'''
题目描述:
随着新能源车的普及，网易越来越多的同事开电动车上下班通勒。网易大厦停车场里可以提供使
用的电桩数量是S, 1 <= S <= 100, 现在有N台电动车等待充电，1 <= N <= 999，第i台电动车所需
要的充电时间为t, 1 <= i <= N, S、N、t均为正整数。

输入为2行，第-行N s,分别为N台电动车和S个电桩，以空格分隔，第二行为每台电动牛允电
所需的时长ti，以空格分隔，如:

Input:
3 2
2 1 3
Output:
3
'''
from bisect import bisect_left

n, s = map(int, input().split())
times = map(int, input().split())
times = sorted(times)[::-1]
values = [0] * s

for t in times:
    tmp = values[0] + t
    ind = bisect_left(values, tmp)
    values.insert(ind, tmp)
    values = values[1:]

print(values[-1])


from rest_framework.exceptions import AuthenticationFailed
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super(CustomTokenObtainPairSerializer, self).validate(attrs)
        request = self.context.get("request")

        if (
            request.region
            and self.user.region
            and request.region.id != self.user.region.id
        ):
            raise AuthenticationFailed()

        return data


import sqlite3
from Project import db
from Project.models import Session

def create_connection(db_file):
    """ create a database connection to a SQLite database """
    try:
        conn = sqlite3.connect(db_file)
        print(sqlite3.version)
        db.create_all()
    except :
        print('error')
    finally:
        conn.close()
    return db_file+".sqlite3"


import scientificamerican
from itertools import zip_longest
from tkinter import *
from time import strftime

bg = "#000000"
fg = "#FFFFFF"

root = Tk()
root.configure(bg=bg)
root.title("Dashboard")
root.attributes('-fullscreen', True)

news_frame = LabelFrame(root, text=" Physics ", font=('helvetica', 20), padx=10, pady=10)
news_frame.configure(bg=bg, fg=fg)
news_frame.grid(row=0, column=0, padx=50, pady=50)

article_headings = scientificamerican.get_headings()
article_dates = scientificamerican.get_dates()
article_summaries = scientificamerican.get_summaries()

count=0
for heading,date,summary in zip_longest(article_headings, article_dates, article_summaries, fillvalue=None):
    heading_label = Label(news_frame, padx=5, pady=10, text=heading, bg=bg, fg=fg, font=('helvetica', 16))
    date_label = Label(news_frame, padx=5, pady=10, text=date, bg=bg, fg=fg, font=('helvetica', 12))
    heading_label.grid(row=count, column=0, sticky='w')
    date_label.grid(row=count, column=1, sticky='e')
    count += 1

def time_func():
    time = strftime(" %H : %M : %S ")
    clock_lbl.config(text = time)
    clock_lbl.after(1000, time_func)

clock_lbl = Label(root, font=('helvetica', 40, 'bold'), bg=bg, fg=fg, padx=30, pady=80)
clock_lbl.grid(row=0, column=2, sticky='ne')

time_func()

root.mainloop()


#write a program that sorts words in alfphabetical order

def wordSorter(str):
    #divide the words into an array where each element of it is a word
    sortedStr = [word.lower() for word in str.split()]

    #array.sort, then print it
    sortedStr.sort()
    for word in sortedStr:
        yield word

for word in wordSorter("hello my name is Alessandro Inguscio and I am trying to sort this sentence"):
    print(word)


import time
from datetime import date
from Maps import Maps
from GameActions import GameActions
from Telegram import Telegram
from Events import Events
from QualityControl import QualityControl

nResets = input("Quantos resets você gostaria de dar? [padrão é 999] ")
esperar = input("Deseja esperar até a madrugada? y/N  [padrão é N] ")
time.sleep(3)
if (not nResets):
    nResets = 999

if (not esperar):
    esperar = False
else:
    if (str(esperar) == 'y'):
        esperar = True

gameActions = GameActions()
maps = Maps()
telegram = Telegram()
events = Events()
qualityControl = QualityControl()

qualityControl.iniciandoBot()
startDay = int(date.today().strftime("%d"))
reportString = "/////////////////////////////////////////////////\n"
i = events.getResetsDoDia()
currentNReset = i
while i <= int(nResets):
    if (not qualityControl.isMadrugada(esperar)):
        i = int(nResets) + 1
        continue
    # reseta o dia para saber a quantidade de resets diário
    currentDay = int(date.today().strftime("%d"))
    if (startDay != currentDay):
        startDay = currentDay
        #i = 1
    startTime = time.time()
    events.escreverLog('####################')
    events.escreverLog(str(i) + ' resets')
    gameActions.resetar(i)
    maps.lorenciaNew()
    report = qualityControl.resetStepTwo()
    if (i % 2 == 0):
        gameActions.reparar()
    checkReset = qualityControl.checkReset(report, i, startTime, reportString, nResets)
    reportString = checkReset[0]
    currentNReset = i
    i = checkReset[1]
events.rodarComando('/move atlans')
reportString += "Bot finalizado!!! Número de resets: " + str(currentNReset) + "\n"
while (not telegram.sendMessage(reportString)):
    time.sleep(5)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed May 10 12:03:35 2023

@author: isaac
"""
import os
# os.chdir('Documents/Doctorado_CIC/Internship/Sylvain/Stability-project/Stability_project_Code/')
os.chdir('/export03/data/Santiago/Stability_project_Code')

import pandas as pd
import numpy as np
import copy
import seaborn as sns
import tensorflow as tf
import pickle
import math
from tensorflow import keras
from tqdm import tqdm
from matplotlib.pyplot import plot, figure
from Fun4CamCanJason import *
from FunClassifier4CamCanJason import *
from fooof import FOOOF
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso, LinearRegression
from sklearn.ensemble import RandomForestRegressor
from TAR import TestAlgorithmsRegression
from RegressionsResultPlot import RegPlot

#%% Hyperparameters

#fooof
inBetween=[1,40]

#PSD
freqs=np.arange(0,150,.5)
alfaBetaFreqs=[0,50]
columns= [i for i, x in enumerate((freqs>=alfaBetaFreqs[0]) & (freqs<alfaBetaFreqs[1])) if x]
columnsfooof= [i for i, x in enumerate((freqs>=inBetween[0]) & (freqs<inBetween[1])) if x]
freqsCropped=freqs[columns]
freqsFooof=freqs[columnsfooof]
#columns is used to select the region of the PSD we are interested in

#%% Directories
current_path = os.getcwd()
parentPath=os.path.abspath(os.path.join(current_path,os.pardir))
path2Data=parentPath+'/Stability-project_db/CAMCAN_Jason_PrePro/'
path2Anatomical=parentPath+'/Stability-project_db/Anatomical_Features/'
path2PreventAD=parentPath+'/Stability-project_db/PreventAD_PSD/'
PreventADFile=os.listdir(path2PreventAD)
AnatFile=os.listdir(path2Anatomical)
mainDir=np.sort(os.listdir(path2Data))
emptyRoomDir=np.sort(os.listdir(path2Data+mainDir[0]+'/'))
restStateDir=np.sort(os.listdir(path2Data+mainDir[2]+'/'))
taskDir=np.sort(os.listdir(path2Data+mainDir[3]+'/'))

#%% Read demografics

demographics=pd.read_csv(path2Data+mainDir[1])
lineAge,ECatell=PltDistDemographics(demographics)
Catell=demographics['Catell_score'].to_numpy()
Age=demographics['age'].to_numpy()
Acer=demographics['additional_acer'].to_numpy()
Targets=['Catell','Age','Acer']

#%% Plot dist cortical thickness
CorticalThickness=pd.read_csv(path2Anatomical+AnatFile[0],header=None)
CorticalThickness_std=PltDistAnat(CorticalThickness,demographics) #Plot the map using R

#%% average Resting state using all time windows
for e,file in enumerate(tqdm(restStateDir)):
    matrix=myReshape(pd.read_csv(path2Data+mainDir[2]+'/'+file,header=None).to_numpy())[np.newaxis, :]
    if e == 0:
        # print (e)
        restStateAll=matrix
        FirstWindow=matrix
        continue
    restStateAll=np.concatenate((restStateAll,matrix))
emptyRoom=pd.read_csv(path2Data+mainDir[0]+'/'+emptyRoomDir[0],header=None).to_numpy()
emptyRoom = myReshape(emptyRoom) #reshape into [Subjects,PSD,ROI]
emptyRoomCropped = emptyRoom[:,columns,:]
restStateOriginal=RestoreShape(np.mean(restStateAll,axis=0))
restState = myReshape(restStateOriginal) #reshape into [Subjects,PSD,ROI]
restStateNoOffset=np.empty(restState.shape)
Sub,PSD,ROI=restState.shape
for sub in range(Sub):
    for roi in range(ROI):
        # offset=np.mean(restState[sub,:,roi])
        offset=restState[sub,0,roi]
        restStateNoOffset[sub,:,roi]=restState[sub,:,roi]-offset
        # restStateNoOffset[sub,:,roi]+=abs(np.min(restStateNoOffset[sub,:,roi]))+.01
restStateCropped = restState[:,columns,:] # Select the band-width of interest
restStateCroppedNoOffset = restStateNoOffset[:,columns,:] # Select the band-width of interest
restStateFooof=restState[:,columnsfooof,:]
FirstWindow = np.squeeze(FirstWindow,axis=0)[:,columns,:]

#%% Read and reformat PreventAD PSD File.
plt.close('all')
#Read
Age_pAD=pd.read_csv(path2PreventAD+PreventADFile[1],header=None).to_numpy()[:,1]
AbTau_pAD=pd.read_csv(path2PreventAD+PreventADFile[2],header=None).to_numpy()[:,1:]
cogCrossSec=pd.read_csv(path2PreventAD+PreventADFile[3],header=None).to_numpy()[:,1:]
pAD_PSD=pd.read_csv(path2PreventAD+PreventADFile[0],header=None).to_numpy()[:,:-1]
pAD_PSD=reformat_AD(pAD_PSD)
pAD_PSD=myReshape(pAD_PSD,num_subjects=pAD_PSD.shape[0])

#Remove
Subjects2remove=[19, 22, 23, 51, 59, 69]
pAD_PSD=np.delete(pAD_PSD, Subjects2remove,axis=0)
Age_pAD=np.delete(Age_pAD,Subjects2remove)
AbTau_pAD=np.delete(AbTau_pAD,Subjects2remove,axis=0)
cogCrossSec=np.delete(cogCrossSec,Subjects2remove,axis=0)

psdPlot(freqs[4:80],pAD_PSD[:,4:80,:])
psdPlot(freqs[4:80],restState[:,4:80,:])
psdPlot(freqs[4:80],Relativize(pAD_PSD)[:,4:80,:])
psdPlot(freqs[4:80],Relativize(restState)[:,4:80,:])
plt.show()

#%% NNMF instead of PCA
nPca=100
# pca_df,pro2use,prop_varianza_acum=myPCA (np.log(restStateOriginal),True, nPca)
W = NNMatFac(restStateOriginal.to_numpy(),nPca)

#%%
#  FOOOF

periodic, aperiodic, whiten, parameters, freqsInBetween=fooof(restStateFooof, freqsFooof, inBetween)
mywhiten=myWhiten(restState[:,columns[2:],:],freqs[columns[2:]],parameters)
#%% Plot global mean PSD per Subject of just one ROI
psdAgeRangePlot_JustOneROI(freqs,restState[:,:,1],Age,'',False)
psdAgeRangePlot_JustOneROI(freqs,restStateNoOffset[:,:,1],Age,'w/o Offset',False)
psdAgeRangePlot_JustOneROI(freqs[columns[2:]],mywhiten[:,:,1],Age,'- Whiten',True)

#%% Plot global mean PSD per Subject
psdAgeRangePlot(freqs,restState,Age,'',True)
psdAgeRangePlot(freqs,restStateNoOffset,Age,'w/o Offset',False)
psdAgeRangePlot(freqs[columns[2:]],mywhiten,Age,' - Whiten',True)

#%% PSD mean per ROI after FOOOF
psdPlot(freqsInBetween, periodic)
psdPlot(freqsInBetween, aperiodic)
psdPlot(freqsInBetween, whiten)

#%% Plot mean rho based on the amount of time provided to the system as input
# Uncoment if you want to overwrite the picke files to plot the regresions
# TestAlgorithmsRegression(restStateDir,path2Data,mainDir,columns,)
# REMEMBER THAT THE exec() DOESNT WORK INSIDE FUNCTIONS! CHAGE THE CODE BEFORE USING IT AGAIN (not warking as a function)

#plot the results
from RegressionsResultPlot import RegPlot

df=RegPlot(current_path) #TODO Necesitas Hacer el goodness of fit
# MeanCorrMatrix(restStateCropped,current_path)
#%% Test Lasso with different "Data"
Data2Test=[restStateOriginal.to_numpy(),
           np.log(restStateOriginal.to_numpy()),
           restStateCropped,
           np.log(restStateCropped),
           periodic,
           aperiodic,
           whiten]
DataName=['Original','Log(Original)','LowPass[<50]','Log(LowPass[<50])','Rhythmic','Arhythmic','Whiten']
Test=[Age,Catell,Acer]
TheDf=pd.DataFrame(columns=['Corr','Data','Test'])
TestName=['Age','Catell','Acer']
for testName,test in zip(TestName,Test):
    for dataName,data2use in zip(tqdm(DataName),Data2Test):
        Data=RestoreShape(data2use)
        Data,labels=RemoveNan(Data, test)
        for i in range(100):
            x_train, x_test, y_train,y_test=Split(Data,labels,.2)
            # DataScaled=Scale(Data)
            # x_train, x_test, y_train,y_test=Split(DataScaled,labels,.2)
            model = Lasso(alpha=.2)
            model.fit(x_train, y_train)
            pred_Lasso=model.predict(x_test)
            lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
            TheDf.loc[len(TheDf)]=[lassoPred,dataName,testName]
        # plt.xlim([0,100])
        # plt.ylim([0,100])
        # plt.xlabel('True Score')
        # plt.ylabel('Predicted Score')
        # plt.annotate('r_sq='+str(round(LassoPred*100,4)), [20,80], fontsize=12)
        # plt.title('Lasso Regression on Age')

sns.set(font_scale=1)
sns.boxplot(TheDf,x='Test',y='Corr',hue='Data',palette="rocket_r").set(title='Lasso performance based on Dataset Processing')#gist_earth_r, mako_r, rocket_r
plt.xticks(rotation=15, ha='right')
#%% Search for the importance of the features

meanCorr=0
Data=RestoreShape(np.log(restStateCropped))
Data,labels=RemoveNan(Data, Age)
Data,_=RemoveNan(Data, Catell)
labels,Catell_noNan=RemoveNan(labels, Catell)
ExpectedCatell=np.zeros(len(labels))
for i,l in enumerate(labels):
    ExpectedCatell[i]=ECatell[np.where(lineAge==l)[0]]
itr=100
errorMatrix=np.empty((len(Data),itr))
errorMatrix.fill(np.nan)
predMatrix=np.empty((len(Data),itr))
predMatrix.fill(np.nan)
for i in tqdm(range(itr)):
    x_train, x_test, y_train,y_test,idx_train,idx_test=Split(Data,labels,.2)
    # DataScaled=Scale(Data)
    # x_train, x_test, y_train,y_test=Split(DataScaled,labels,.2)
    model = Lasso(alpha=.2)
    # model = LinearRegression()
    model.fit(x_train, y_train)
    pred_Lasso=model.predict(x_test)
    lassoPred=scipy.stats.pearsonr(y_test,pred_Lasso)[0]
    error = np.subtract(y_test,pred_Lasso)
    for idx,e,p in zip(idx_test,error,pred_Lasso):
        errorMatrix[idx,i]=e
        predMatrix[idx,i]=p
    meanCorr+=lassoPred
    # MAE.append(mae)
meanCorr/=itr
meanError=np.nanmean(errorMatrix,axis=1)
meanPred=np.round(np.nanmean(predMatrix,axis=1),2)

from Fun4CamCanJason import *
PlotErrorvsAge(meanPred,meanError,labels,Age,Catell_noNan,ExpectedCatell)

meanROICorr=0
MeanDiffAllbutOne=[]
for i in tqdm(range(68)):
    Data=np.delete(np.log(restStateCropped),i,axis=2)
    Data=RestoreShape(Data)
    Data,labels=RemoveNan(Data, Age)
    for _ in range(itr):
        x_train, x_test, y_train,y_test,_,_=Split(Data,labels,.2)
        model = Lasso(alpha=.2)
        model.fit(x_train, y_train)
        pred_Lasso=model.predict(x_test)
        lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
        meanROICorr+=lassoPred
    meanROICorr/=itr
    MeanDiffAllbutOne.append(meanCorr-meanROICorr)

MeanDiffJustOne=[]
AllROICorr=[]
for i in tqdm(range(68)):
    ROICorr=[]
    Data=np.log(restStateCropped[:,:,i])
    # Data=RestoreShape(Data)
    Data,labels=RemoveNan(Data, Age)
    for _ in range(itr):
        x_train, x_test, y_train,y_test,_,_=Split(Data,labels,.2)
        model = Lasso(alpha=.2)
        model.fit(x_train, y_train)
        pred_Lasso=model.predict(x_test)
        lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
        ROICorr.append(lassoPred)
    AllROICorr.append(ROICorr)
    meanROICorr=np.mean(ROICorr)
    MeanDiffJustOne.append(meanCorr-meanROICorr)

MeanDiffJustOne2=(1-np.array(MeanDiffJustOne))*meanCorr
MeanDiffAllbutOne2=1-np.array(MeanDiffAllbutOne) *meanCorr

MeanDiffJustOneER=[] #EmptyRoom
AllROICorrER=[]
for i in tqdm(range(68)):
    ROICorr=[]
    Data=np.log(restStateCropped[:,:,i])
    DataEmpty=np.log(emptyRoomCropped[:,:,i])
    # Data=RestoreShape(Data)
    Data,labels=RemoveNan(Data, Age)
    DataEmpty,labels=RemoveNan(DataEmpty, Age)
    for _ in range(itr):
        seed=np.random.randint(1000,size=1)[0]
        x_train,_, y_train,_,_,_=Split(Data,labels,.2,seed=seed)
        _, x_test, _,y_test,_,_=Split(DataEmpty,labels,.2,seed=seed)
        model = Lasso(alpha=.2)
        model.fit(x_train, y_train)
        pred_Lasso=model.predict(x_test)
        lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
        ROICorr.append(lassoPred)
    AllROICorrER.append(ROICorr)
    meanROICorr=np.mean(ROICorr)
    MeanDiffJustOneER.append(meanCorr-meanROICorr)

MeanDiffJustOneER2=(1-np.array(MeanDiffJustOneER))*meanCorr

#Correlation between empty room map and ROI map

CorrJO_Empty=[] #JustOne
for JO,ER in zip(AllROICorr,AllROICorrER):
    CorrJO_Empty.append(scipy.stats.pearsonr(JO,ER)[0])
CorrJO_Empty=np.array(CorrJO_Empty)
#%%
with open(current_path+'/Pickle/meanCorr_allFeatures.pickle', 'wb') as f:
    pickle.dump(meanCorr, f)

with open(current_path+'/Pickle/MeanDiff_AllbutOne.pickle', 'wb') as f:
    pickle.dump(MeanDiffAllbutOne, f)

with open(current_path+'/Pickle/MeanDiff_JustOne.pickle', 'wb') as f:
    pickle.dump(MeanDiffJustOne2, f)

#%% Train on all windows, test just on first window
FirstWindowCorr=0
DataTrain=RestoreShape(np.log(restStateCropped))
DataTrain,labels=RemoveNan(DataTrain, Age)
DataTest=RestoreShape(np.log(FirstWindow))
DataTest,labels=RemoveNan(DataTest, Age)
itr=100
for i in tqdm(range(itr)):
    x_train, _, y_train,_=Split(DataTrain,labels,.2,seed=i)
    _, x_test, _,y_test=Split(DataTest,labels,.2,seed=i)

    # DataScaled=Scale(Data)
    # x_train, x_test, y_train,y_test=Split(DataScaled,labels,.2)
    model = Lasso(alpha=.2)
    model.fit(x_train, y_train)
    pred_Lasso=model.predict(x_test)
    lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
    FirstWindowCorr+=lassoPred
FirstWindowCorr/=itr

#%% Training based on frequency bins

corrPerBin=[]
itr=50
CleanData,labels=RemoveNan(restStateCroppedNoOffset, Age)
Sub,PSD,ROI=CleanData.shape
for PSDbin in tqdm(np.arange(2,CleanData.shape[1])):
    corr=[]
    Data=RestoreShape(np.log(CleanData[:,PSDbin,:]))
    for i in range(itr):
        x_train, x_test, y_train, y_test, idx_train, idx_test=Split(Data,labels,.3)
        # DataScaled=Scale(Data)
        # x_train, x_test, y_train,y_test=Split(DataScaled,labels,.2)
        model = Lasso(alpha=.2)
        model.fit(x_train, y_train)
        pred_Lasso=model.predict(x_test)
        lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
        corr.append(lassoPred)
    corrPerBin.append(corr)
corrPerBin=np.array(corrPerBin)
fig,ax=plt.subplots()
GlobalMeanPSD=np.mean(np.mean(restStateCropped,axis=2),axis=0)
ax.plot(GlobalMeanPSD[2:]/max(GlobalMeanPSD[2:]), 'k', linewidth=2)
plt.legend(['Global Mean PSD'])
corrPerBinDf=pd.DataFrame(corrPerBin.T,columns=freqs[2:PSD])
sns.set(font_scale=1)
sns.boxplot(corrPerBinDf, ax=ax).set(title='Lasso performance per frequency bin - Age')#gist_earth_r, mako_r, rocket_r
plt.xticks(rotation=90, ha='right')

#%% Training based on frequency bins
LassoPerBin(restStateCropped,freqs,Age,'',randomize=False)
LassoPerBin(restStateCroppedNoOffset,freqs,Age,'w/o Offset',randomize=False)
LassoPerBinfooof(mywhiten,freqs[columns[2:]],Age,' Whiten',randomize=False)
LassoPerBin(restStateCropped,freqs,Age,'Random Permutations',randomize=True)

#%% Training based on frequency windows: 5 Hz w/ .5 Hz steps

corrPerBin=[]
itr=100
CleanData,labels=RemoveNan(restStateCropped, Age)
windowSize=int(5*(1/.5)) #5Hz windows * freq bin size in Hz/s = 10 datapoints,
step= int(.5*(1/.5)) #.5Hz step * freq bin size in Hz/s = 1 datapoint step
for PSDwinStart in tqdm(np.arange(0,CleanData.shape[1]-windowSize,step)):
    corr=[]
    Data=RestoreShape(np.log(CleanData[:,PSDwinStart:PSDwinStart+windowSize,:]))
    for i in range(itr):
        x_train, x_test, y_train, y_test, idx_train, idx_test=Split(Data,labels,.2)
        # DataScaled=Scale(Data)
        # x_train, x_test, y_train,y_test=Split(DataScaled,labels,.2)
        model = Lasso(alpha=.2)
        model.fit(x_train, y_train)
        pred_Lasso=model.predict(x_test)
        lassoPred=scipy.stats.pearsonr(pred_Lasso,y_test)[0]
        corr.append(lassoPred)
    corrPerBin.append(corr)
corrPerBin=np.array(corrPerBin)
fig,ax=plt.subplots()
GlobalMeanPSD=np.mean(np.mean(restStateCropped,axis=2),axis=0)
ax.plot(GlobalMeanPSD[int(windowSize/2):len(columns)-int(windowSize/2)]/max(GlobalMeanPSD[int(windowSize/2):len(columns)-int(windowSize/2)]), 'k', linewidth=2)
# ax.plot(GlobalMeanPSD[int(windowSize/2):100-int(windowSize/2)]/max(GlobalMeanPSD[2:]), 'k', linewidth=2)
plt.legend(['Global Mean PSD'])
corrPerBinDf=pd.DataFrame(corrPerBin.T,columns=freqs[int(windowSize/2):len(columns)-int(windowSize/2)])
sns.set(font_scale=1)
sns.boxplot(corrPerBinDf, ax=ax).set(title='Lasso performance per frequency window [ 5 Hz w/ .5 Hz steps]  - Age')#gist_earth_r, mako_r, rocket_r
plt.xticks(rotation=90, ha='right')

#%% Overfitting curve
fig,ax=plt.subplots(1,2,figsize=(17, 9))
DataAll=RestoreShape(np.log(restStateCropped))
DataAll,labels=RemoveNan(DataAll, Age)
DataFirstWindow=RestoreShape(np.log(FirstWindow))
DataFirstWindow,labels=RemoveNan(DataFirstWindow, Age)
DataEmptyRoom=RestoreShape(np.log(emptyRoomCropped))
DataEmptyRoom,labels=RemoveNan(DataEmptyRoom, Age)
predMatrixAllEmpty=LassoTrainTestRatio(DataAll,DataEmptyRoom,labels,ax[1],'gist_gray','300 sec')
predMatrixFirstWindowEmpty=LassoTrainTestRatio(DataFirstWindow,DataEmptyRoom,labels,ax[0],'gist_gray','30 sec')
predMatrixAll=LassoTrainTestRatio(DataAll,DataAll,labels,ax[1],'magma','300 sec')
predMatrixFirstWindow=LassoTrainTestRatio(DataFirstWindow,DataFirstWindow,labels,ax[0],'mako','30 sec')
# predMatrixFirstWindow=LassoTrainTestRatio(DataEmptyRoom,labels,ax,'gist_gray','30 sec')
plt.suptitle('Lasso performance under different Tests/Train ratios - Age')

#%% Training Percentage per Recorging Time
meanMatrix=LassoTestTrainRatiosPerWindow(restStateAll,emptyRoomCropped,FirstWindow,columns,Age)
colors=linear_gradient('#2100ff', '#ff0000', len(meanMatrix))
for i,mean in enumerate(meanMatrix):
    if i == 0:
        label='Empty room'
    else:
        label='Time = '+str(int(30*i))+" [s]"
    plt.plot(testTrainRatio,mean,color=colors['hex'][i],linewidth=5,alpha=.5,label=label)
plt.legend(fontsize=15)
plt.title('Lasso performance under different Tests/Train ratios and Recording times - Age',fontsize=17)
plt.xlabel('Train percentage',fontsize=15)
plt.ylabel('Pearson Correlation',fontsize=15)
plt.yticks(fontsize=15)
plt.xticks(fontsize=15)

#%% Lasso Trained on CAMCAN and tested on Prevent AD

LassoCAMCANvspAD(restStateCropped, pAD_PSD[:,columns,:],
                 np.concatenate((Age,Age_pAD)),AbTau_pAD,cogCrossSec,Norm=None)

#%% Dictionary For ggseg

# ROI={'bankssts_left':0,
# 'bankssts_right':1,
# 'caudalanteriorcingulate_left':0,
# 'caudalanteriorcingulate_right':1,
# 'caudalmiddlefrontal_left':0,
# 'caudalmiddlefrontal_right':1,
# 'cuneus_left':0,
# 'cuneus_right':1,
# 'entorhinal_left':0,
# 'entorhinal_right':1,
# 'frontalpole_left':0,
# 'frontalpole_right':1,
# 'fusiform_left':0,
# 'fusiform_right':1,
# 'inferiorparietal_left':0,
# 'inferiorparietal_right':1,
# 'inferiortemporal_left':0,
# 'inferiortemporal_right':1,
# 'insula_left':0,
# 'insula_right':1,
# 'isthmuscingulate_left':0,
# 'isthmuscingulate_right':1,
# 'lateraloccipital_left':0,
# 'lateraloccipital_right':1,
# 'lateralorbitofrontal_left':0,
# 'lateralorbitofrontal_right':1,
# 'lingual_left':0,
# 'lingual_right':1,
# 'medialorbitofrontal_left':0,
# 'medialorbitofrontal_right':1,
# 'middletemporal_left':0,
# 'middletemporal_right':1,
# 'paracentral_left':0,
# 'paracentral_right':1,
# 'parahippocampal_left':0,
# 'parahippocampal_right':1,
# 'parsopercularis_left':0,
# 'parsopercularis_right':1,
# 'parsorbitalis_left':0,
# 'parsorbitalis_right':1,
# 'parstriangularis_left':0,
# 'parstriangularis_right':1,
# 'pericalcarine_left':0,
# 'pericalcarine_right':1,
# 'postcentral_left':0,
# 'postcentral_right':1,
# 'posteriorcingulate_left':0,
# 'posteriorcingulate_right':1,
# 'precentral_left':0,
# 'precentral_right':1,
# 'precuneus_left':0,
# 'precuneus_right':1,
# 'rostralanteriorcingulate_left':0,
# 'rostralanteriorcingulate_right':1,
# 'rostralmiddlefrontal_left':0,
# 'rostralmiddlefrontal_right':1,
# 'superiorfrontal_left':0,
# 'superiorfrontal_right':1,
# 'superiorparietal_left':1,
# 'superiorparietal_right':1,
# 'superiortemporal_left':0,
# 'superiortemporal_right':1,
# 'supramarginal_left':0,
# 'supramarginal_right':1,
# 'temporalpole_left':0,
# 'temporalpole_right':1,
# 'transversetemporal_left':0,
# 'transversetemporal_right':1
# }

# keysList = list(ROI.keys())
# for i,key in enumerate(ROI):
#     ROI[key]=MeanDiffJustOne2[i]
# import ggseg
# ggseg.plot_dk(ROI, background='k', edgecolor='w', cmap='jet',
#               bordercolor='gray', ylabel='Age Predictibility (mm)', title='ROI Importance')
#%% Modify Dictionary based on Results

#%% Print Figure of the brain
#
#%% PCA statistics
# Data=whitened #change this in order to test diferent psd (original, per, aper, whitened, etc )
# Sub,PSD,ROI=Data.shape
# nPca=25
# PCA=np.zeros((Sub,nPca+2,ROI))
# Var=[]
# Pro=[]
# for roi in  tqdm(range(ROI)):
#     df=pd.DataFrame(Data[:,:,roi])
#     proyecciones,pro2use,prop_varianza_acum=ACP (df,False,False,25)
#     Var.append(prop_varianza_acum)
#     PCA[:,:nPca,roi]=pro2use
#     for sub in range (Sub):
#         PCA[sub,nPca,roi]=parameters[0][sub][0]
#         PCA[sub,nPca+1,roi]=parameters[0][sub][1]
# Var=pd.DataFrame(Var)
# sns.boxplot(Var)
# plt.ylim((0,1))

# myPCA statistics
# figure()
# Data=whitened #change this in order to test diferent psd (original, per, aper, whitened, etc )
# Sub,PSD,ROI=Data.shape
# nPca=25
# PCA=np.zeros((Sub,nPca+2,ROI))
# Var=[]
# Pro=[]
# for roi in  tqdm(range(ROI)):
#     df=pd.DataFrame(Data[:,:,roi])
#     pca_df,pro2use,prop_varianza_acum=myPCA(df,False,nPca)
#     Var.append(prop_varianza_acum)
#     PCA[:,:nPca,roi]=pro2use
#     for sub in range (Sub):
#         PCA[sub,nPca,roi]=parameters[0][sub][0]
#         PCA[sub,nPca+1,roi]=parameters[0][sub][1]
# Var=pd.DataFrame(Var)
# sns.boxplot(Var)
# plt.ylim((0,1))


import urllib2, re

_url_ = 'https://www.whatismyip.com/'
_reg_pattern_ = 'Country:	([A-Z]*)	'

def returnCountyCode() :
    match = re.findall(_reg_pattern_,_GEO_getUrl(_url_))
    try :
        return match[0]
    except :
        return ""

def _GEO_getUrl(url, cookieJar=None,post=None, timeout=20, headers=None):

    cookie_handler = urllib2.HTTPCookieProcessor(cookieJar)
    opener = urllib2.build_opener(cookie_handler, urllib2.HTTPBasicAuthHandler(), urllib2.HTTPHandler())
    #opener = urllib2.install_opener(opener)
    req = urllib2.Request(url)
    req.add_header('User-Agent','Kodi/14.0 (Macintosh; Intel Mac OS X 10_10_3) App_Bitness/64 Version/14.0-Git:2014-12-23-ad747d9-dirty')
    if headers:
        for h,hv in headers:
            req.add_header(h,hv)

    response = opener.open(req,post,timeout=timeout)
    link=response.read()
    response.close()
    return link;


from datetime import datetime
import image_utils

start_import = datetime.now()
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import ListProperty, StringProperty, Clock
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.event import EventDispatcher
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.widget import Widget
from kivy.uix.camera import Camera
from kivy.uix.image import Image
from kivy.properties import ObjectProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.network.urlrequest import UrlRequest
from kivy.core.text import LabelBase
from kivy.core.window import Window
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.properties import NumericProperty
from kivy.graphics import *
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.button import Button
from kivy.uix.modalview import ModalView

print(f"Kivy Imports: {datetime.now() - start_import}")
start_import = datetime.now()
# PEP 8 Crying rn

import os.path
from os import path
import configparser
import requests
import os
import glob
import StepPyStep
from Mathpix import mathpix
import imagesize
import json
import urllib
import cProfile
import certifi
import glob
from functools import partial
from theme import themeConfig
import imghdr

import shutil
import cv2
from plyer import filechooser as native_file_chooser

print(f"StepPyStep Imports: {datetime.now() - start_import}")

Builder.load_file("main.kv")

# global filepath for each run

# declare screens
class SolutionStep(Button):
    pass

class HomeScreen(Screen):

    def capture(self):
        directory_file = open("curdir.tmp", 'w')
        # Creates a folder for the solution and stores it's relative name in self.filepath
        filepath = StepPyStep.create_zip().create_directory(App.get_running_app().user_data_dir)
        # print("Filepath: ", filepath)
        directory_file.write(filepath)
        directory_file.close()

        try:
            camera = self.ids["proxy"]
            image_path = os.path.join(App.get_running_app().user_data_dir, "Solutions", filepath, "image.png")

            camera.export_to_png(image_path)
            image_utils.crop_transparent(image_path, image_path)
            print("captured successfully")
            self.on_image_get()
        except KeyError:
            self.image_input_error()
        except Exception as e:
            print("Camera capture exception: " + str(e))

        # link = solution().step_by_step(f"Solutions/{self.filepath}/image{self.count}.png", f"Solutions/{self.filepath}/solution.txt")[0]
        # print(link)

        # self.manager.transition.direction = 'right'
        # self.manager.current = 'mathpixDisplay'

        # link = solution().check(f"Solutions/{self.filepath}/image{self.count}.png", f"Solutions/{self.filepath}/solution.txt")
        # if link != None:
        #     print(link)

    def image_input_error(self):
        error = ImageErrorPopup()
        error.open()

    def on_resize(self):
        try:
            self.window_width_relative = (Window.width / 1080)
            self.window_height_relative = (Window.height / 1920)
            self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)
            self.image_container.height = min(self.image_size[1] * self.relative_size, Window.height - (
                    (120 + 60 + 150 + 30 + 30 + 145) * self.relative_size) - self.title_label.height)
            self.display_latex_image.size_hint = (None, None)
            self.display_latex_image.height = max(self.image_container.height, self.image_size[1] * self.relative_size)
            self.display_latex_image.width = max(Window.width - 240 * self.relative_size,
                                                 self.image_size[0] * self.relative_size)
            self.capture_popup.height = self.image_container.height + (
                    (60 + 150 + 30 + 30 + 145) * self.relative_size) + self.title_label.height
        except AttributeError:
            pass

    def open_image(self):
        print("open")
        try:
            open_image_path = native_file_chooser.open_file(title="Choose an image: ", filters=[(
                "Image Files(*.jpg, *.jpeg, *.png, *.tiff, *.pjp, *.jfif, *.gif, *.svg, *.raw)",
                "*.jpg", "*.jpeg",
                "*.png", "*.tiff",
                "*.pjp", "*.jfif",
                "*.gif", "*.svg",
                "*.raw"), (
                "All Files(*.*)", "*.*")])[0]
            print(open_image_path)
            destination_filepath = StepPyStep.create_zip().create_directory(App.get_running_app().user_data_dir)
            print("Filepath: ", destination_filepath)
            directory_file = open("curdir.tmp", 'w')
            directory_file.write(destination_filepath)
            directory_file.close()
            shutil.copy2(open_image_path,
                         os.path.join(App.get_running_app().user_data_dir, "Solutions", destination_filepath,
                                      "image.png"))
            try:
                self.on_image_get()
            except KeyError:
                self.image_input_error()

        except TypeError:
            pass

    def on_image_get(self):

        dir_file = open("curdir.tmp", "r")
        self.solve_file_path = dir_file.read()
        dir_file.close()
        latex = solution().call_mathpix(self.solve_file_path)
        latex_file = open(
            os.path.join(App.get_running_app().user_data_dir, "Solutions", self.solve_file_path, "latex.txt"), 'w+')
        print(latex)
        latex_file.write(latex["latex_simplified"])
        self.open_capture_popup()

    def open_capture_popup(self):
        render_path = os.path.join(App.get_running_app().user_data_dir, "Renders", self.solve_file_path,
                                   "capture_render.png")
        self.capture_popup = CapturePopup()

        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        self.image_container = self.capture_popup.ids["image_scroll_view"]
        self.title_label = self.capture_popup.ids["title_label"]
        max_latex_height = Window.height - ((150 + 30 + 30 + 145) * self.relative_size)
        self.image_size = imagesize.get(render_path)
        self.display_latex_image = Image()
        self.display_latex_image.source = render_path
        self.display_latex_image.allow_stretch = True
        self.display_latex_image.color = App.get_running_app().theme.color_neutral
        self.image_container.add_widget(self.display_latex_image)

        self.image_container.height = min(self.image_size[1] * self.relative_size, Window.height - (
                (120 + 60 + 150 + 30 + 30 + 145) * self.relative_size) - self.title_label.height)
        self.display_latex_image.size_hint = (None, None)
        self.display_latex_image.height = max(self.image_container.height, self.image_size[1] * self.relative_size)
        self.display_latex_image.width = max(Window.width - 240 * self.relative_size,
                                             self.image_size[0] * self.relative_size)
        self.title_label.texture_update()
        self.capture_popup.height = self.image_container.height + (
                (60 + 150 + 30 + 30 + 145) * self.relative_size) + self.title_label.height
        self.capture_popup.open()

class CapturePopup(ModalView):

    def solve(self):
        dir_file = open("curdir.tmp", "r")
        self.solve_file_path = dir_file.read()
        dir_file.close()
        latex_file = open(
            os.path.join(App.get_running_app().user_data_dir, "Solutions", self.solve_file_path, "latex.txt"))
        solved_solution = solution().step_by_step(latex_file.read(),
                                                  os.path.join(App.get_running_app().user_data_dir, "Solutions",
                                                               self.solve_file_path, "solution.txt"),
                                                  self.solve_file_path)
        self.dismiss()
        App.get_running_app().sm.transition.direction = 'left'
        App.get_running_app().sm.current = 'solveequ'

    def retake(self):
        # Cleans up on the event of a retake
        dir_file = open("curdir.tmp", "r")
        solve_file_path = dir_file.read()
        dir_file.close()
        shutil.rmtree(os.path.join(App.get_running_app().user_data_dir, "Solutions", solve_file_path))
        shutil.rmtree(os.path.join(App.get_running_app().user_data_dir, "Renders", solve_file_path))
        self.dismiss()

    def check(self):
        dir_file = open("curdir.tmp", "r")
        solve_file_path = dir_file.read()
        dir_file.close()
        latex_file = open(os.path.join(App.get_running_app().user_data_dir, "Solutions", solve_file_path, "latex.txt"))
        latex = latex_file.read()
        solution().check(latex, solve_file_path)
        self.dismiss()
        App.get_running_app().sm.transition.direction = 'left'
        App.get_running_app().sm.current = 'check'

class ImageErrorPopup(ModalView):

    def retake(self):
        # Cleans up on the event of a retake
        dir_file = open("curdir.tmp", "r")
        solve_file_path = dir_file.read()
        dir_file.close()
        shutil.rmtree(os.path.join(App.get_running_app().user_data_dir, "Solutions", solve_file_path))
        shutil.rmtree(os.path.join(App.get_running_app().user_data_dir, "Renders", solve_file_path))
        self.dismiss()

class FileOpenPopup(ModalView):
    pass

class CorrectionLabel(Label):
    pass

class CheckWorkScreen(Screen):

    def back(self):
        try:
            App.get_running_app().screen_history.pop()
        except IndexError:
            pass
        try:
            return App.get_running_app().screen_history[len(App.get_running_app().screen_history) - 1]
        except IndexError:
            return "home"

    def on_enter(self, *args):
        self.setup_checked_solution()
        self.bind(size=self.on_resize)

    def setup_checked_solution(self):

        dir_file = open("curdir.tmp", "r")
        self.solve_file_path = dir_file.read()
        dir_file.close()
        self.check = configparser.ConfigParser()
        self.check.read(
            os.path.join(App.get_running_app().user_data_dir, "Solutions", self.solve_file_path, "check.txt"))

        os.mkdir(os.path.join(App.get_running_app().user_data_dir, "Renders", self.solve_file_path, "checksteps"))
        working_directory = os.path.join(App.get_running_app().user_data_dir, "Renders", self.solve_file_path,
                                         "checksteps")
        self.check_steps = self.check.sections()
        step_number = 0
        for section in self.check_steps:
            if "STEP" in section:
                # Prepares by rendering the math

                image_utils.render_text(self.check[section]["step"].replace("|", ""),
                                        os.path.join(working_directory, f"step{step_number}.png"))
            else:
                correction_number = section.replace("CORRECTION", "")
                # Prepares by rendering the math

                image_utils.render_text(self.check[section]["operation"].replace("|", ""),
                                        os.path.join(working_directory, f"step{step_number}.png"))
            step_number +=1

        self.build()

    def build(self):
        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        self.check_step_widgets = []
        self.comment_labels = [0, 0, 0]
        check_steps_layout = self.ids['check_steps_layout']

        solution_title_label = self.ids['check_title_label']
        solution_title_label.text = self.solve_file_path

        cumulative_height = 0

        for s in range(len(self.check_steps)):

            # Creates widget object
            self.check_step_widgets.append(
                SolutionStep(x=30 * self.relative_size, width=Window.width - 60 * self.relative_size))

            # Links KV objects
            latex_image = self.check_step_widgets[s].ids['latex_image']
            latex_image_scrollview = self.check_step_widgets[s].ids["latex_image_scroll"]
            instructions_label = self.check_step_widgets[s].ids["instructions_label"]

            # Is it a step or correction?

            # Yes, is a step
            if "STEP" in self.check_steps[s]:
                padding_height = 60
                # Step is correct
                if self.check[self.check_steps[s]]["iscorrect"] == "True":
                    self.check_step_widgets[s].background_color = App.get_running_app().theme.color_neutral_muted
                # Step is incorrect
                else:
                    self.comment_labels[0] = CorrectionLabel(text="Here's what you did wrong:")
                    self.comment_labels[0].width = check_steps_layout.width
                    self.comment_labels[0].text = "Here's what you did wrong:"
                    check_steps_layout.add_widget(self.comment_labels[0])
                    self.comment_labels[0].texture_update()

                    self.check_step_widgets[s].background_color = App.get_running_app().theme.color_wrong
            # No, is a correction
            else:
                if self.check_steps[s] == "CORRECTION0":
                    self.comment_labels[1] = CorrectionLabel()
                    self.comment_labels[1].width = check_steps_layout.width
                    self.comment_labels[1].text = "Solution:"
                    check_steps_layout.add_widget(self.comment_labels[1])
                    self.comment_labels[1].texture_update()

                padding_height = 90
                self.check_step_widgets[s].background_color = App.get_running_app().theme.color_right
                instructions_label.text = self.check[self.check_steps[s]]["instruction"].replace("text: ", "")

            latex_image.color = App.get_running_app().theme.color_neutral
            instructions_label.color = App.get_running_app().theme.color_neutral

            latex_image.source = os.path.join(App.get_running_app().user_data_dir, "Renders", self.solve_file_path,
                                              "checksteps", f"step{s}.png")

            latex_image_size = imagesize.get(latex_image.source)

            latex_image.texture_update()
            instructions_label.texture_update()
            print(instructions_label.height)
            latex_image.height = 75 * (latex_image_size[1] / 75) * self.relative_size
            latex_image.width = max(latex_image_scrollview.width,
                                    latex_image.height * (latex_image_size[0] / latex_image_size[1]))
            self.check_step_widgets[s].height = latex_image.height + instructions_label.height + padding_height * self.relative_size
            check_steps_layout.add_widget(self.check_step_widgets[s])

        try:
            if self.check[self.check_steps[len(self.check_steps) - 1]]["iscorrect"] == "True":
                self.check_step_widgets[len(self.check_step_widgets) - 1].background_color = App.get_running_app().theme.color_right
                self.comment_labels[2] = CorrectionLabel()
                self.comment_labels[2].width = check_steps_layout.width
                self.comment_labels[2].text = "All correct!"
                check_steps_layout.add_widget(self.comment_labels[2])
                self.comment_labels[2].texture_update()
                cumulative_height += self.comment_labels[2].height + 40 * self.relative_size
        except KeyError:
            pass

        for s in range(len(self.check_step_widgets)):
            cumulative_height += self.check_step_widgets[s].height
            cumulative_height += 40 * self.relative_size
        check_steps_layout.height = cumulative_height

    def on_leave(self):
        self.ids['check_steps_layout'].clear_widgets()

    def on_resize(self, instance, value):

        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        check_steps_layout = self.ids['check_steps_layout']

        cumulative_height = 0

        for comment in range(3):
            try:
                self.comment_labels[comment].width = check_steps_layout.width
                self.comment_labels[comment].texture_update()
                cumulative_height += self.comment_labels[2].height + 40 * self.relative_size
            except AttributeError:
                pass

        for s in range(len(self.check_steps)):

            # Links KV objects
            latex_image = self.check_step_widgets[s].ids['latex_image']
            latex_image_scrollview = self.check_step_widgets[s].ids["latex_image_scroll"]
            instructions_label = self.check_step_widgets[s].ids["instructions_label"]

            # Is it a step or correction?

            # Yes, is a step
            if "STEP" in self.check_steps[s]:
                padding_height = 60
            # No, is a correction
            else:
                padding_height = 90

            latex_image_size = imagesize.get(latex_image.source)

            latex_image.texture_update()
            instructions_label.texture_update()
            latex_image.height = 75 * (latex_image_size[1] / 75) * self.relative_size
            latex_image.width = max(latex_image_scrollview.width,
                                    latex_image.height * (latex_image_size[0] / latex_image_size[1]))
            self.check_step_widgets[s].height = latex_image.height + instructions_label.height + padding_height * self.relative_size
            self.check_step_widgets[s].width = Window.width - 60 * self.relative_size

        for s in range(len(self.check_step_widgets)):
            cumulative_height += self.check_step_widgets[s].height
            cumulative_height += 40 * self.relative_size
        check_steps_layout.height = cumulative_height

class SolveEquScreen(Screen):

    def back(self):
        try:
            App.get_running_app().screen_history.pop()
        except IndexError:
            pass
        try:
            return App.get_running_app().screen_history[len(App.get_running_app().screen_history) - 1]
        except IndexError:
            return "home"

    def on_enter(self):
        dir_file = open("curdir.tmp", "r")
        self.solve_file_path = dir_file.read()
        dir_file.close()
        self.create_build_objects()
        self.bind(size=self.on_resize)

    def on_leave(self):
        self.ids['solution_steps_layout'].clear_widgets()

    def create_build_objects(self):
        self.solution = configparser.ConfigParser()
        solution_file = os.path.join(App.get_running_app().user_data_dir, "Solutions", self.solve_file_path,
                                     "solution.txt")
        self.solution.read(solution_file)
        self.solution_steps = self.solution.sections()
        print(f"create_build: {self.solution_steps}")
        self.build()

    def build(self):

        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        self.solution_step_widgets = []
        solution_step_layout = self.ids['solution_steps_layout']

        solution_title_label = self.ids['solution_title_label']
        solution_title_label.text = self.solve_file_path

        for s in range(len(self.solution_steps)):
            self.solution_step_widgets.append(
                SolutionStep(x=30 * self.relative_size, width=Window.width - 60 * self.relative_size))
            self.solution_step_widgets[s].background_color = App.get_running_app().theme.color_neutral_muted
            latex_image = self.solution_step_widgets[s].ids['latex_image']
            latex_image_scrollview = self.solution_step_widgets[s].ids["latex_image_scroll"]
            if s == len(self.solution_steps) - 1:
                self.solution_step_widgets[s].background_color = App.get_running_app().theme.color_right
            else:
                self.solution_step_widgets[s].background_color = App.get_running_app().theme.color_neutral_muted
            instructions_label = self.solution_step_widgets[s].ids["instructions_label"]
            latex_image.color = App.get_running_app().theme.color_neutral
            instructions_label.color = App.get_running_app().theme.color_neutral
            latex_image.source = os.path.join(App.get_running_app().user_data_dir, "Renders", self.solve_file_path,
                                              "steppysteps", f"step{s}.png")
            latex_image_size = imagesize.get(latex_image.source)
            instructions_label.text = self.solution[self.solution_steps[s]]['instruction'].replace("text: ", "")
            if instructions_label.text == "":
                padding_height = 60
            else:
                padding_height = 90
            latex_image.texture_update()
            instructions_label.texture_update()
            latex_image.height = 75 * (latex_image_size[1] / 75) * self.relative_size
            latex_image.width = max(latex_image_scrollview.width,
                                    latex_image.height * (latex_image_size[0] / latex_image_size[1]))
            self.solution_step_widgets[
                s].height = latex_image.height + instructions_label.height + padding_height * self.relative_size
            solution_step_layout.add_widget(self.solution_step_widgets[s])

        cumulative_height = 0
        for s in range(len(self.solution_step_widgets)):
            cumulative_height += self.solution_step_widgets[s].height
            cumulative_height += 40 * self.relative_size
        solution_step_layout.height = cumulative_height

    def on_resize(self, instance, value):

        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        solution_step_layout = self.ids['solution_steps_layout']

        for s in range(len(self.solution_steps)):
            latex_image = self.solution_step_widgets[s].ids['latex_image']
            latex_image_scrollview = self.solution_step_widgets[s].ids["latex_image_scroll"]
            instructions_label = self.solution_step_widgets[s].ids['instructions_label']

            instructions_label.font_size = 60 * self.relative_size

            latex_image_size = imagesize.get(latex_image.source)
            latex_image.height = 75 * (latex_image_size[1] / 75) * self.relative_size
            latex_image.width = max(latex_image_scrollview.width - 5,
                                    latex_image.height * (latex_image_size[0] / latex_image_size[1]))
            if instructions_label.text == "":
                padding_height = 60
            else:
                padding_height = 90
            latex_image.texture_update()
            instructions_label.texture_update()
            self.solution_step_widgets[s].height = latex_image.height + instructions_label.height + padding_height * self.relative_size
            self.solution_step_widgets[s].width = Window.width - 60 * self.relative_size
            latex_image.width = max(Window.width - 120 * self.relative_size,
                                    latex_image.height * (latex_image_size[0] / latex_image_size[1]))
        cumulative_height = 0
        for s in range(len(self.solution_step_widgets)):
            cumulative_height += self.solution_step_widgets[s].height
            cumulative_height += 40 * self.relative_size
        solution_step_layout.height = cumulative_height

class FileScreen(Screen):

    def on_enter(self):
        App.get_running_app().screen_history.append("files")
        self.build()
        self.bind(size=self.on_resize)
        self.popup = FileOpenPopup()

    def on_leave(self):
        file_chooser = self.ids["file_chooser"]
        file_chooser.clear_widgets()

    def back(self):
        try:
            App.get_running_app().screen_history.pop()
        except IndexError:
            pass
        try:
            return App.get_running_app().screen_history[len(App.get_running_app().screen_history) - 1]
        except IndexError:
            return "home"

    def open(self):
        # if file is selected
        try:
            # Get full filepath of selected
            selected_file = self.file_labels[len(self.file_labels) - self.selected_file_index - 1].text
            selected_file_path = os.path.join(App.get_running_app().user_data_dir, "Solutions", selected_file)
            self.selected_file_path = selected_file_path
            # print(self.selected_file_path)

            # Set popup title text
            self.popup.ids["filename_label"].text = selected_file

            # Compute maximum image height and maximum popup size based on window size
            max_image_height_raw = (120 + 120 + 150 + 30 + 30 + 145)
            max_image_height = Window.height - max_image_height_raw * self.relative_size
            max_image_width = self.popup.width - 120 * self.relative_size
            image_size = imagesize.get(os.path.join(self.selected_file_path, "image.png"))

            # Fit image
            if image_size[0] / image_size[1] < max_image_width / max_image_height:
                image_height = max_image_height
            else:
                image_height = (Window.size - 240 * self.relative_size) * image_size[1] / image_size[0]

            # Popup height to image and window
            self.popup.height = image_height + (max_image_height_raw - 120) * self.relative_size
            selected_file_image_params = {
                "source": os.path.join(self.selected_file_path, "image.png"),
                "size_hint": (None, None),
            }

            # Create image and build
            self.selected_file_image = Image(**selected_file_image_params)
            self.popup_layout = self.popup.ids["popup_layout"]
            self.popup_layout.add_widget(self.selected_file_image)
            self.selected_file_image.size = image_size[0] / image_size[1] * image_height, image_height
            self.popup.bind(on_dismiss=self.clean_up_popup)
            self.popup.open()

        # if nothing is selected
        except:
            pass

        # Update so elements are in correct position
        try:
            max_image_height_raw = (120 + 120 + 150 + 30 + 30 + 145)
            max_image_height = Window.height - max_image_height_raw * self.relative_size
            max_image_width = self.popup.width - 120 * self.relative_size
            image_size = imagesize.get(os.path.join(self.selected_file_path, "image.png"))
            if image_size[0] / image_size[1] < max_image_width / max_image_height:
                image_height = max_image_height
            else:
                image_height = (Window.size[0] - 240 * self.relative_size) * image_size[1] / image_size[0]
            self.popup.height = image_height + (max_image_height_raw - 120) * self.relative_size
            self.selected_file_image.x = self.popup.x + (self.popup.width / 2) - (self.selected_file_image.width / 2)
            self.selected_file_image.y = self.popup.y + (320 * self.relative_size)
            self.selected_file_image.size = image_size[0] / image_size[1] * image_height, image_height
        except AttributeError:
            pass

    def clean_up_popup(self, instance):
        self.popup_layout.remove_widget(self.selected_file_image)
        print(self.selected_file_image)

    def delete(self):
        selected_file = self.file_labels[len(self.file_labels) - self.selected_file_index - 1].text
        print(selected_file)
        selected_file_path = os.path.join(App.get_running_app().user_data_dir, "Solutions", selected_file)
        shutil.rmtree(selected_file_path)
        file_chooser = self.ids["file_chooser"]
        file_chooser.clear_widgets()
        self.build()

    def on_selected(self, instance, value):
        # change color when selected, using only one texture
        if value == "down":
            instance.background_color = App.get_running_app().theme.color_right
            self.selected_file_index = self.file_buttons.index(instance)
        else:
            instance.background_color = App.get_running_app().theme.color_neutral_muted
            self.selected_file_index = None

    def on_resize(self, obj, value):
        # Define new window dimensions
        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        # Define new scrollview layout height
        file_chooser = self.ids["file_chooser"]
        self.chooser_height = ((len(self.files) * 240) * (
                (self.window_width_relative + self.window_height_relative) / 2)) + (
                                      (40 * (len(self.files) - 1)) * (
                                      (self.window_width_relative + self.window_height_relative) / 2))
        file_chooser.height = self.chooser_height

        # Update height of file entries, namely labels and their font
        for current_entry in range(len(self.file_buttons)):

            # Update size and position of labels
            self.file_labels[current_entry]._label.refresh()
            self.file_labels[current_entry].pos = self.file_labels[current_entry]._label.texture.size[
                                                      0] / 2 + 230 * self.relative_size, current_entry * (
                                                          280 * self.relative_size) + 120 * self.relative_size
            self.file_labels[
                current_entry].text_size = 790 * self.window_width_relative - 32 * self.relative_size, 60 * self.relative_size
            self.file_labels[current_entry].font_size = 60 * (
                    (self.window_width_relative + self.window_height_relative) / 2)

            # Update size and position of images
            if self.file_images[current_entry].source == self.default_file_image:
                self.file_image_size = 100
            else:
                self.file_image_size = 200
            self.file_images[current_entry].pos = (
                (15 * self.window_width_relative) + (100 * self.relative_size) - self.file_images[
                    current_entry].width / 2,
                current_entry * (
                        280 * self.relative_size) + (120 * self.relative_size) - self.file_images[
                    current_entry].height / 2)
            self.file_image_params["height"] = self.file_image_size * self.relative_size
            self.file_image_params["width"] = self.file_image_size * self.relative_size
            icon_width, icon_height = imagesize.get(self.file_images[current_entry].source)
            if icon_width > icon_height:
                self.file_image_params["height"] *= icon_height / icon_width
            else:
                self.file_image_params["width"] *= icon_width / icon_height
            self.file_images[current_entry].height = self.file_image_params["height"]
            self.file_images[current_entry].width = self.file_image_params["width"]
            # Update popup image compute image size
            try:
                max_image_height_raw = (120 + 120 + 150 + 30 + 30 + 145)
                max_image_height = Window.height - max_image_height_raw * self.relative_size
                max_image_width = self.popup.width - 120 * self.relative_size
                image_size = imagesize.get(os.path.join(self.selected_file_path, "image.png"))
                if image_size[0] / image_size[1] < max_image_width / max_image_height:
                    image_height = max_image_height
                else:
                    image_height = (Window.size[0] - 240 * self.relative_size) * image_size[1] / image_size[0]
                self.popup.height = image_height + (max_image_height_raw - 120) * self.relative_size
                self.selected_file_image.x = self.popup.x + (self.popup.width / 2) - (
                        self.selected_file_image.width / 2)
                self.selected_file_image.y = self.popup.y + (320 * self.relative_size)
                self.selected_file_image.size = image_size[0] / image_size[1] * image_height, image_height
            except AttributeError:
                pass

    def build(self):
        # Find files
        self.data_path = os.path.join(App.get_running_app().user_data_dir, "Solutions")
        self.files = glob.glob(os.path.join(self.data_path, "*/"))

        # Sort by recent
        self.files.sort(key=os.path.getmtime)

        file_chooser = self.ids["file_chooser"]

        # Define window dimensions
        self.window_width_relative = (Window.width / 1080)
        self.window_height_relative = (Window.height / 1920)
        self.relative_size = ((self.window_width_relative + self.window_height_relative) / 2)

        self.chooser_height = ((len(self.files) * 240) * self.relative_size) + (
                (40 * (len(self.files) - 1)) * self.relative_size)
        file_chooser.height = self.chooser_height

        # Parameters for button and label for file entry
        self.default_file_image = os.path.join("themes", App.get_running_app().theme.theme_folder, "icons",
                                               "file_empty.png")
        self.file_image_size = 100
        self.file_image_params = {
            "source": self.default_file_image,
            "height": self.file_image_size * self.relative_size,
            "width": self.file_image_size * self.relative_size,
            "pos": (0, 0),
            "allow_stretch": True,
        }
        self.file_entry_params = {
            "text": "",
            "group": "files",
            "background_normal": os.path.join("themes", App.get_running_app().theme.theme_folder, "boxes", "empty.png"),
            "background_down": os.path.join("themes", App.get_running_app().theme.theme_folder, "boxes", "empty.png"),
            "background_color": App.get_running_app().theme.color_neutral_muted,
            "border": [20] * 4,
        }
        self.label_entry_params = {
            "text": "world",
            "shorten": True,
            "shorten_from": "right",
            "text_size": (700 * self.window_width_relative, 60 * self.relative_size),
            "font_name": "main",
            "font_size": 60 * self.relative_size,
            "pos": (0, 0),
        }

        self.file_buttons = []
        self.file_labels = []
        self.file_images = []

        # Create file list from parameters
        for file in self.files:
            try:
                source_image = os.path.join(file, "image.png")
                self.file_image_size = 200
                icon_width, icon_height = imagesize.get(source_image)
                if imghdr.what(source_image) != "png":
                    source_image = self.default_file_image
                    icon_width, icon_height = imagesize.get(source_image)
                    self.file_image_size = 100
            except FileNotFoundError:
                source_image = self.default_file_image
                icon_width, icon_height = imagesize.get(source_image)
                self.file_image_size = 100

            self.file_image_params["source"] = source_image
            self.file_image_params["height"] = self.file_image_size * self.relative_size
            self.file_image_params["width"] = self.file_image_size * self.relative_size
            if icon_width > icon_height:
                self.file_image_params["height"] *= icon_height / icon_width
            else:
                self.file_image_params["width"] *= icon_width / icon_height
            # Create labels for file
            self.label_entry_params["text"] = file.replace(self.data_path, "").replace("/", "")
            self.file_buttons.append(ToggleButton(**self.file_entry_params))

            current_entry = len(self.file_buttons) - 1
            # Position relative
            self.file_image_params["pos"] = (
                (15 * self.window_width_relative) + (100 * self.relative_size) - self.file_image_params["width"] / 2,
                current_entry * (
                        280 * self.relative_size) + (120 * self.relative_size) - self.file_image_params["height"] / 2)
            self.file_images.append(Image(**self.file_image_params))

            self.file_labels.append(Label(**self.label_entry_params))

            self.file_labels[current_entry].size = self.file_labels[current_entry].texture_size
            self.file_labels[current_entry]._label.refresh()
            self.file_labels[current_entry].pos = self.file_labels[current_entry]._label.texture.size[
                                                      0] / 2 + 230 * self.relative_size, current_entry * (
                                                          280 * self.relative_size) + 120 * self.relative_size
            self.file_buttons[current_entry].add_widget(self.file_labels[current_entry])
            self.file_buttons[current_entry].add_widget(self.file_images[current_entry])
            if self.file_images[current_entry].source == self.default_file_image:
                self.file_images[current_entry].color = App.get_running_app().theme.color_neutral_muted
            file_chooser.add_widget(self.file_buttons[current_entry])

            self.file_buttons[current_entry].bind(state=self.on_selected)

class SettingsScreen(Screen):
    pass

class FocusMath(App):

    def __init__(self):
        App.__init__(self)
        try:
            os.mkdir(os.path.join(self.user_data_dir, "Solutions"))
        except FileExistsError:
            pass
        self.theme = themeConfig()
        self.theme.read_theme()
        self.screen_history = ["home"]
        os.environ['SSL_CERT_FILE'] = certifi.where()

    def clean_saved_images(self):
        files = glob.glob(os.path.join(App.get_running_app().user_data_dir, "Solutions", "*/"))
        for file in files:
            try:
                image = os.path.join(file, "image.png")
                print(image)
                if imghdr.what(image) == "png":
                    image_utils.crop_transparent(image, image)
                else:
                    os.remove(image)
            except FileNotFoundError:
                pass

    def build(self):
        start_load = datetime.now()
        self.sm = ScreenManager()
        self.sm.add_widget(HomeScreen(name='home'))
        self.sm.add_widget(FileScreen(name='files'))
        self.sm.add_widget(SolveEquScreen(name='solveequ'))
        self.sm.add_widget(CheckWorkScreen(name='check'))
        self.sm.add_widget(SettingsScreen(name='settings'))
        print(f"GUI Load: {datetime.now() - start_load}")
        return self.sm

    def on_start(self):
        self.profile = cProfile.Profile()
        self.profile.enable()
        LabelBase.register(name="main", fn_regular=App.get_running_app().theme.font_info)

    def on_stop(self):
        self.profile.disable()
        self.profile.dump_stats('debug.prof')

class solution(object):
    def __init__(self):
        try:
            os.mkdir(os.path.join(App.get_running_app().user_data_dir, "Solutions", "Outputs"))
        except Exception:
            pass

    def call_mathpix(self, filepath):
        # Creates render directories
        try:
            os.mkdir(os.path.join(App.get_running_app().user_data_dir, "Renders"))
        except Exception as e:
            print(e)
        try:
            os.mkdir(os.path.join(App.get_running_app().user_data_dir, "Renders", filepath))
            os.mkdir(os.path.join(App.get_running_app().user_data_dir, "Renders", filepath, "steps"))
        except Exception as e:
            print(e)

        # Checks if an internet connection exists.
        try:
            urllib.request.urlopen('https://www.google.com', timeout=3)
        except Exception as e:
            return f"[ERROR]{e} Sorry! We encountered an issue. Check your internet connection and try again!"

        try:
            source_filepath = os.path.join(App.get_running_app().user_data_dir, "Solutions", filepath, "image.png")
        # Handles a failure to get a reply from mathpix
        except ConnectionAbortedError:
            # return "\\text[ERROR<ConnectionAbortedError> This could be because of \n[http_unauthorized], [http_max_requests] \nCheck https://mathpix.github.io/docs/#errors]"
            pass

        # if 'latex_simplified' not in r:
        #     r['latex_simplified'] = "OCR_ERROR"
        self.ocr_latex = mathpix.latex(
            {'src': mathpix.image_uri(f'{source_filepath}'), 'formats': ['latex_simplified']})
        print(self.ocr_latex)
        print(self.ocr_latex['latex_simplified'])
        print(filepath)
        image_utils.render_text(
            self.ocr_latex['latex_simplified'],
            os.path.join(App.get_running_app().user_data_dir, "Renders", filepath, "capture_render.png"),
            os.path.join(App.get_running_app().user_data_dir, "Renders", filepath, "steps", "steps_render.png")
        )
        return self.ocr_latex

    def step_by_step(self, input_latex, writepath, input_filepath):

        try:
            os.mkdir(os.path.join(App.get_running_app().user_data_dir, "Renders", input_filepath, "steppysteps"))
        except Exception as e:
            print(e)
        input_latex = StepPyStep.parse_tex().replaceBackSlash(input_latex)

        # What the OCR detected in the image.
        engine = StepPyStep.solve_equation()
        self.solution_link = engine.wolfram_alpha(input_latex, image=False)
        print(self.solution_link)
        temp = []
        solution_list = []
        for i in range(len(self.solution_link)):
            temp.append(self.solution_link[i])
            if i % 2 == 1:
                solution_list.append(temp)
                print(f"temp: {temp}")
                temp = []
        print(solution_list)
        with open(f"{writepath}", "w+", encoding='utf-8') as steps_file:
            print(solution_list)
            write_steps = configparser.ConfigParser()
            for i in range(len(solution_list)):
                write_steps[f"STEP{i}"] = {
                    "instruction": solution_list[i][0],
                    "operation": solution_list[i][1]
                }
            write_steps.write(steps_file)
        for i in range(len(solution_list)):
            filename = f"step{i}.png"
            render_text = solution_list[i][1].replace('|', '')
            print(f"Rendering {render_text}")
            image_utils.render_text(render_text,
                                    os.path.join(App.get_running_app().user_data_dir, "Renders", input_filepath,
                                                 "steppysteps", filename), delete_intermediate=True)
        print(solution_list)
        return solution_list

    def check(self, input_latex, writepath):
        tex = input_latex
        tex = str(tex)
        engine = StepPyStep.solve_equation()
        # error here
        latex_list = StepPyStep.parse_tex().split_array(input_latex)
        print(latex_list)
        if not isinstance(latex_list, list):
            return "NOT_MULTILINE"
        for i in range(len(latex_list)):
            latex_list[i] = latex_list[i].replace("{", "(")
            latex_list[i] = latex_list[i].replace("}", ")")
            latex_list[i] = latex_list[i].replace("^", "**")
            latex_list[i] = StepPyStep.parse_tex().replaceBackSlash(latex_list[i])
        a = engine.get_answer(latex_list[0])
        results = []
        dirFile = open("curdir.tmp", "r")
        solveFilePath = dirFile.read()
        dirFile.close()
        with open(os.path.join(App.get_running_app().user_data_dir, "Solutions", solveFilePath, "check.txt"), "w+",
                  encoding='utf-8') as check_file:

            for i in range(len(latex_list)):
                write_steps = configparser.ConfigParser()
                print(f"latex_list[{i}]: {latex_list[i]}")

                truth = StepPyStep.check_equation().check_eq(latex_list[i], a, precision=5, step=i,
                                                             writepath=os.path.join(App.get_running_app().user_data_dir,
                                                                                "Solutions", solveFilePath))

                truth = truth.replace("**", "^")
                results.append(truth)
                if ("False" in truth):
                    print(truth)
                    if (i == 0):
                        print(f"latex_list[i]: {latex_list[i]}")
                        result = StepPyStep.solve_equation().wolfram_alpha(latex_list[i], writepath)

                        print(f"result: {result}")
                        results.append(result)
                    else:
                        print(f"latex_list[i-1]: {latex_list[i - 1]}")
                        result = StepPyStep.solve_equation().wolfram_alpha(latex_list[i - 1], writepath)
                        print(f"result: {result}")
                        results.append(result)
                    print(f"STEP{i}")
                    truth = truth.replace("(False)", "")
                    write_steps[f"STEP{i}"] = {
                        "step": truth,
                        "isCorrect": False
                    }
                    temp = []
                    correction_list = []
                    for i in range(len(result)):
                        temp.append(result[i])
                        if i % 2 == 1:
                            correction_list.append(temp)
                            temp = []
                    for correction in correction_list:
                        write_steps[f"CORRECTION{correction_list.index(correction)}"] = {
                            "instruction": correction[0],
                            "operation": correction[1]
                        }
                    write_steps.write(check_file)
                    return results
                else:
                    write_steps[f"STEP{i}"] = {
                        "step": truth,
                        "isCorrect": True
                    }
                    write_steps.write(check_file)

        results.append("All correct!")
        return results

if __name__ == '__main__':
    FocusMath().run()


from django.conf.urls import url

from onadata.apps.eventlog.views import ProjectLogListView, TaskListView, OtherTaskListViewSet,  MyTaskListViewSet, SiteLogListView, SiteLog, ProjectLog, CeleryTaskProgressView, MyCeleryTaskProgress, NotificationListView, NotificationCountnSeen, NotificationViewSet, NotificationDetailView, MessageListView
from onadata.apps.fieldsight.mixins import group_required

@group_required("hello")
def notifications(args):
    pass

urlpatterns = [
    url(r'^notification/$', NotificationListView.as_view(), name='notification-list'),
    url(r'^api/notification/$', NotificationViewSet.as_view({'get': 'list'}), name="api-not"),
    url(r'^api/notification/count/$', NotificationCountnSeen.as_view(), name="api-not-count"),
    url(r'^message/$', MessageListView.as_view(), name='message-list'),
    url(r'^notification/(?P<pk>[0-9]+)/$', NotificationDetailView.as_view(), name='notification-detail'),
    url(r'^message/(?P<pk>[0-9]+)/$', notifications, name='message-detail'),
    url(r'^task_state$', CeleryTaskProgressView.as_view(), name="task_state"),

    url(r'^mytasks_progress$', MyCeleryTaskProgress.as_view(), name="mytasks_progress"),
    url(r'^api/project_logs/(?P<pk>[0-9]+)/$', ProjectLog.as_view({'get': 'list'}), name="api_project_logs"),
    url(r'^api/site_logs/(?P<pk>[0-9]+)/$', SiteLog.as_view({'get': 'list'}), name="api_site_logs"),

    url(r'^project_logs/(?P<pk>[0-9]+)/$', ProjectLogListView.as_view(), name="project_logs"),
    url(r'^site_logs/(?P<pk>[0-9]+)/$', SiteLogListView.as_view(), name="site_logs"),
    url(r'^api/mytasks/$', MyTaskListViewSet.as_view({'get': 'list'}), name="my_task_list"),
    url(r'^api/othertasks/$', OtherTaskListViewSet.as_view({'get': 'list'}), name="other_task_list"),
    url(r'^tasks/$', TaskListView.as_view(), name="task_list"),
    ]


"""Scrieţi un program care citeşte de la tastatură elementele mulţimilor A şi B şi afişează pe ecran:
a) intersecţia mulţimilor A şi B;
b) reuniunea mulţimilor A şi B;
c) diferenţa mulţimilor A şi B.
Mulţimile A şi B sunt formate din numere întregi."""
A=set()
B=set()
for i in range(0,999999):
    x=eval(input("Dati un numar:"))
    if type(x)!=int:
        break
    else:
        A.add(x)
for i in range(0,99999):
    y=eval(input("Dati un numar:"))
    if type(y)==int:
        B.add(y)
    else:
        break
print(A)
print(B)
print("a)Intersectia multimilor A si B este",A.intersection(B))
print("b)Reuniunea multimilor A si B este",A.union(B))
print("c)Diferenta multimilor A si B este",A.difference(B),"\n","Iar diferenta multimilor B si A este",B.difference(A))


from flask import redirect,session,request,render_template,flash
from flask_app import app
from flask_app.models.companion import Companion
from flask_app.models.breed import Breed
from flask_app.models.profession import Profession
from flask_app.models.user import User
from flask_app.models.weapon import Weapon

#Directs the user to the create companion page
@app.route('/create-companion')
def make_companion():
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":session['user_id']
    }
    return render_template('create_character.html')

#Directs the user to the update companion page
@app.route('/update-companion/<int:id>')
def update_companion(id):
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":id
    }
    user_data = {
        "id":session['user_id']
    }
    session['edit_companion_id'] = id
    return render_template('update_character.html',
                            edit=Companion.get_one(data),
                            companion=Companion.get_one(data),
                            user=User.get_by_id(user_data))

#Process the user's request to create a new companion
@app.route('/create/companion', methods=['POST'])
def create_companion():
    if 'user_id' not in session:
        return redirect('/logout')
    if not Companion.validate_create(request.form):
        return redirect('/create-companion')
    data = {
        "name": request.form["name"],
        "breed": request.form["breed"],
        "profession": request.form["profession"],
        "weapon": request.form["weapon"],
        "ability1": request.form["ability1"],
        "ability2": request.form["ability2"],
        "ability3": request.form["ability3"],
        "picture": request.form["picture"],
        "story": request.form["story"],
        "health": Breed.get_stats(request.form).health + Profession.get_stats(request.form).health,
        "strength": Breed.get_stats(request.form).strength + Profession.get_stats(request.form).strength + Weapon.get_stats(request.form).strength,
        "defense": Breed.get_stats(request.form).defense + Profession.get_stats(request.form).defense + Weapon.get_stats(request.form).defense,
        "luck": Breed.get_stats(request.form).luck + Profession.get_stats(request.form).luck + Weapon.get_stats(request.form).luck,
        "user_id": session["user_id"]
    }
    Companion.create(data)
    return redirect('/dashboard')

#Process the user's request to update their companion
# (breed, profession, and weapon cannot be updated)
@app.route('/edit/companion', methods=['POST'])
def editCompanion():
    if 'user_id' not in session:
        return redirect('/logout')
    if 'edit_companion_id' not in session:
        return redirect('/dashboard')
    edit_companion_id = session['edit_companion_id']
    if not Companion.validate_update(request.form):
        return redirect(f'/update-companion/{edit_companion_id}')
    data = {
        "name": request.form["name"],
        "ability1": request.form["ability1"],
        "ability2": request.form["ability2"],
        "ability3": request.form["ability3"],
        "picture": request.form["picture"],
        "story": request.form["story"],
        "id": request.form['id']
    }
    Companion.update_info(data)
    return redirect('/dashboard')

#Process the user's request to "retire" their companion
@app.route('/delete/companion/<int:id>')
def retire_companion(id):
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":id
    }
    Companion.delete(data)
    return redirect('/dashboard')

#leaderboard
@app.route('/leaderboard')
def leader_board():
    if 'user_id' not in session:
        return redirect('/logout')
    data ={
        'id': session['user_id']
    }
    scores = Companion.leaderboard()
    print("*****scores = ", type(scores))
    print("******scores = ", scores)
    for one_score in scores:
        print("*******one_score = ", one_score)
    print("**********one_score type = ", type(one_score))
    print("**********one_score = ", one_score)
    return render_template('leaderboard.html', scores = scores)

#Directs the user to a details page of one of their companions
@app.route('/companion/<int:id>')
def one_companion(id):
    if 'user_id' not in session:
        return redirect('/logout')
    data = {
        "id":id
    }
    user_data = {
        "id":session['user_id']
    }
    return render_template('character_page.html',
                        user=User.get_by_id(user_data),
                        companion = Companion.get_one(data))


# input
import time
arr = input()

# my sol
start_time = time.time()
length = int(len(arr) / 2)  # f.b: length // 2
head, tail = arr[:length], arr[length:]

sum_head = sum([int(num) for num in head])
sum_tail = sum([int(num) for num in tail])

if sum_head == sum_tail:
    print('LUCKY')
else:
    print('READY')

end_time = time.time()
print('time: ', end_time - start_time)

이것이 취업을 위한 코딩테스트다 with 파이썬/Implementation/럭키 스트레이트.py


# 간단한 소인수분해
# 소인수분해: 주어진 합성수를 소인수들의 곱으로 나타내는 과정
# 소인수 : 자연수의 인수 중 소수
# 소수 : 1보다 큰 자연수 중에서 1과 그 수 자신만을 약수로 가지는 수
# 소인수분해 하는 법 : 소인수로 몫이 소수가 될 때까지 나눗셈을 한다 # 모든 소인수와 마지막 몫을 곱한다
# 약수 구하기

T = int(input())
lst = [2, 3, 5, 7, 11] # 숫자 N을 구성하는 정해진 소수값 저장할 리스트

for tc in range(1, T + 1):
    res = [] # 횟수 저장할 빈 리스트 초기화
    N = int(input())
    for i in lst:  # 숫자 N을 구성하는 정해진 소수값을 기준으로 반복
        cnt = 0  # 횟수 저장할 변수 초기화
        while N % i == 0: # 숫자 N을 i로 나눈 나머지가 0이 될 때까지
            N = N // i # N을 i로 나눔
            cnt += 1 # N이 i로 나눠질 때마다 cnt변수를 1씩 증가(횟수 세기)
        res.append(cnt) # i 반복 끝날때마다 cnt 변수를 res 리스트에 추가
    print('#{} {}'.format(tc, ' '.join(map(str, res)))) # res 리스트의 요소를 map함수를 사용해서 문자열로 변환하여 join 메서드로 공백으로 나누어 출력


from django.shortcuts import render

# Create your views here.
from rest_framework import generics, status, mixins
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

from measure.models import Measures
from .serializers import MeasuresSerializer
import datetime as dt
from attack_information.models import Attackinformation
from django.db.models import Count, Sum, Q, F, Avg

class MeasureRecordCreate(generics.CreateAPIView):

    serializer_class = MeasuresSerializer
    permission_classes = [AllowAny]

    http_method_names = ['post']

    def post(self, request, *args, **kwargs):

        vulnerability_without_measure = request.data['vulnerability_without_measure']
        reduced_vulnerability = request.data['reduced_vulnerability']
        reduced_l1_rate = request.data['reduced_l1_rate']
        reduced_l2_rate = request.data['reduced_l2_rate']
        incident_category = request.data['incident_category']
        initial_cost = request.data['initial_cost']
        annual_upgrade = request.data['annual_upgrade']
        annual_maintenance = request.data['annual_maintenance']
        time_period = request.data['time_period']
        discount_rate = request.data['discount_rate']
        organization_id = request.data['organization_id']

        total_cost = float(initial_cost) + float(annual_upgrade) + float(annual_maintenance)

        last_year = dt.date.today().year - 1

        queryset = Attackinformation.objects.values('attack_id__start_time_stamp__year') \
            .filter(Q(attack_id__start_time_stamp__year=last_year), Q(organization_id=organization_id),
                    Q(incident_category=incident_category)) \
            .annotate(total_l1=Sum(F('l1')), total_l2=Sum(F('l2')), total_l3=Sum(F('l3')))

        l1 = 0
        l2 = 0
        l3 = 0
        RC = 0
        R0 = 0
        NPV = 0
        ROSI = 0

        if queryset :

            if queryset[0]['total_l1'] is not None:

                l1 = float(queryset[0]['total_l1'])

            if queryset[0]['total_l2'] is not None:
                l2 = float(queryset[0]['total_l2'])

            if queryset[0]['total_l3'] is not None:
                l3 = float(queryset[0]['total_l3'])

            RC = (float(vulnerability_without_measure) * float(reduced_vulnerability) * (l1 * float(reduced_l1_rate) + l2 * float(reduced_l2_rate) + l3))
            R0 = l1+l2+l3

            ROSI = (R0 - RC - total_cost) / total_cost

            time_period = int(time_period)

            for i in range(1, time_period+1):

                NPV = NPV + ((R0 - RC - float(annual_upgrade) - float(annual_maintenance)) / (1 + float(discount_rate))**i)
                # NPV = NPV - 1

            NPV = NPV - float(initial_cost)

        serializer = MeasuresSerializer(data={'user_id': request.data['user_id'],
                                              'organization_id': request.data['organization_id'],
                                              'measure_type_id': request.data['measure_type_id'],
                                              'measure_description': request.data['measure_description'],
                                              'rosi': ROSI, 'npv': NPV, 'time_period': time_period,
                                              'initial_cost': initial_cost, 'annual_upgrade': annual_upgrade,
                                              'annual_maintenance': annual_maintenance, 'total_cost': total_cost,
                                              'reduced_vulnerability': reduced_vulnerability,
                                              'incident_category': request.data['incident_category'],
                                              'vulnerability_without_measure': vulnerability_without_measure,
                                              'reduced_l1_rate': reduced_l1_rate, 'reduced_l2_rate': reduced_l2_rate,
                                              'discount_rate': discount_rate})
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            print(serializer.data)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class MeasureRecordList(APIView):
    serializer_class = MeasuresSerializer
    permission_classes = [AllowAny]

    http_method_names = ['get']
    queryset = Measures.objects.all()

    def get(self, request, userid, incident_category, *args, **kwargs):
        try:
            queryset = Measures.objects.filter(Q(incident_category=incident_category), Q(user_id=userid)) \
                            .order_by('-rosi')
            serializer = MeasuresSerializer(queryset, many=True)
            return Response(serializer.data)
        except Measures.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

class MeasureRecordListByUser(APIView):
    serializer_class = MeasuresSerializer
    permission_classes = [AllowAny]

    http_method_names = ['get']
    queryset = Measures.objects.all()

    def get(self, request, userid, *args, **kwargs):
        try:
            queryset = Measures.objects.filter(Q(user_id=userid))
            serializer = MeasuresSerializer(queryset, many=True)
            return Response(serializer.data)
        except Measures.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)


from regrippy import BasePlugin, PluginResult

class Plugin(BasePlugin):
    """Searches for Sysinternal EulaAccepted keys"""

    __REGHIVE__ = "NTUSER.DAT"

    def run(self):
        key = self.open_key(r"Software\Sysinternals")
        if not key:
            return

        for subkey in key.subkeys():
            eula = None
            for v in subkey.values():
                if v.name() == "EulaAccepted":
                    eula = v
                    break

            res = PluginResult(key=subkey, value=eula)
            yield res

    def display_human(self, result):
        print(result.key_name, "\t", result.value_data)